@@ -3,49 +3,55 @@ import {renderer} from "@b9g/crank/dom";
33// Adapted from https://backbonenotbad.hyperclay.com/
44// https://gist.github.com/panphora/8f4d620ae92e8b28dcb4f20152185749
55function * PasswordStrength ( ) {
6- const requirements = [
7- { label : ' 8+ characters' , check : ( pwd ) => pwd . length >= 8 } ,
8- { label : ' 12+ characters' , check : ( pwd ) => pwd . length >= 12 } ,
9- { label : ' Lowercase letter' , check : ( pwd ) => / [ a - z ] / . test ( pwd ) } ,
10- { label : ' Uppercase letter' , check : ( pwd ) => / [ A - Z ] / . test ( pwd ) } ,
11- { label : ' Number' , check : ( pwd ) => / \d / . test ( pwd ) } ,
12- { label : ' Special character' , check : ( pwd ) => / [ ^ a - z A - Z 0 - 9 ] / . test ( pwd ) } ,
13- ] ;
6+ const requirements = [
7+ { label : " 8+ characters" , check : ( pwd ) => pwd . length >= 8 } ,
8+ { label : " 12+ characters" , check : ( pwd ) => pwd . length >= 12 } ,
9+ { label : " Lowercase letter" , check : ( pwd ) => / [ a - z ] / . test ( pwd ) } ,
10+ { label : " Uppercase letter" , check : ( pwd ) => / [ A - Z ] / . test ( pwd ) } ,
11+ { label : " Number" , check : ( pwd ) => / \d / . test ( pwd ) } ,
12+ { label : " Special character" , check : ( pwd ) => / [ ^ a - z A - Z 0 - 9 ] / . test ( pwd ) } ,
13+ ] ;
1414
15- let password = '' ;
15+ let password = "" ;
1616
17- for ( { } of this ) {
18- yield (
19- < div class = "w-80 p-6 bg-white rounded-xl shadow-lg space-y-4" >
20- < input
21- type = "password"
22- value = { password }
23- oninput = { ( e ) => this . refresh ( ( ) => password = e . target . value ) }
24- placeholder = "Enter password"
25- class = "w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2"
26- />
27- < div class = "space-y-2" >
28- { requirements . map ( ( req , idx ) => {
29- const isMet = req . check ( password ) ;
30- return (
31- < div key = { idx } class = "flex items-center gap-2" >
32- < div class = { `w-5 h-5 rounded-full flex items-center justify-center text-xs font-bold ${ isMet ? 'bg-green-500 text-white' : 'bg-gray-200 text-gray-400' } ` } >
33- { isMet ? '✓' : '' }
34- </ div >
35- < span class = { `text-sm ${ isMet ? 'text-green-600 font-medium' : 'text-gray-500' } ` } >
36- { req . label }
37- </ span >
38- </ div >
39- ) ;
40- } ) }
41- </ div >
42- </ div >
43- ) ;
44- }
17+ for ( { } of this ) {
18+ yield (
19+ < div class = "w-80 p-6 bg-white rounded-xl shadow-lg space-y-4" >
20+ < input
21+ type = "password"
22+ value = { password }
23+ oninput = { ( e ) => this . refresh ( ( ) => ( password = e . target . value ) ) }
24+ placeholder = "Enter password"
25+ class = "w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2"
26+ />
27+ < div class = "space-y-2" >
28+ { requirements . map ( ( req , idx ) => {
29+ const isMet = req . check ( password ) ;
30+ return (
31+ < div key = { idx } class = "flex items-center gap-2" >
32+ < div
33+ class = { `w-5 h-5 rounded-full flex items-center justify-center text-xs font-bold ${ isMet ? "bg-green-500 text-white" : "bg-gray-200 text-gray-400" } ` }
34+ >
35+ { isMet ? "✓" : "" }
36+ </ div >
37+ < span
38+ class = { `text-sm ${ isMet ? "text-green-600 font-medium" : "text-gray-500" } ` }
39+ >
40+ { req . label }
41+ </ span >
42+ </ div >
43+ ) ;
44+ } ) }
45+ </ div >
46+ </ div >
47+ ) ;
48+ }
4549}
4650
47- const script = document . createElement ( ' script' ) ;
48- script . src = ' https://cdn.tailwindcss.com' ;
51+ const script = document . createElement ( " script" ) ;
52+ script . src = " https://cdn.tailwindcss.com" ;
4953document . head . appendChild ( script ) ;
50- await new Promise ( ( resolve ) => script . addEventListener ( "load" , ( ) => resolve ( ) , { once : true } ) ) ;
54+ await new Promise ( ( resolve ) =>
55+ script . addEventListener ( "load" , ( ) => resolve ( ) , { once : true } ) ,
56+ ) ;
5157renderer . render ( < PasswordStrength /> , document . body ) ;
0 commit comments