@@ -9,19 +9,44 @@ struct ZXCVBNIndicator: View {
99 var body : some View {
1010 let emptyColor = UIColor . progressDefault
1111 let filledColor : UIColor = state. score < MAXSCORE ? UIColor . progressDanger : UIColor . progressSuccess
12- let text = state. score < MAXSCORE ? ( state. suggestions ?? [ ] ) . joined ( separator: " , " ) : LocalizationManager . stytch_zxcvbn_feedback_success
1312 VStack ( alignment: . leading) {
1413 HStack ( alignment: . center) {
1514 ForEach ( 0 ... MAXSCORE, id: \. self) { index in
1615 let color = state. score >= index ? filledColor : emptyColor
1716 Rectangle ( ) . fill ( Color ( color) ) . frame ( height: 4 )
1817 }
1918 }
20- Text ( text)
21- . fixedSize ( horizontal: false , vertical: true )
22- . font ( Font ( UIFont . IBMPlexSansRegular ( size: 16 ) ) )
23- . multilineTextAlignment ( . leading)
24- . foregroundColor ( Color ( filledColor) )
19+ if state. score < MAXSCORE {
20+ if let warning = state. warning, !warning. isEmpty {
21+ HStack ( alignment: . center, spacing: 4 ) {
22+ Image ( " crossIcon " , bundle: . module) . frame ( width: 16 , height: 16 , alignment: . center)
23+ Text ( warning. mapToLocalizedString ( ) )
24+ . fixedSize ( horizontal: false , vertical: true )
25+ . font ( Font ( UIFont . IBMPlexSansRegular ( size: 16 ) ) )
26+ . multilineTextAlignment ( . leading)
27+ . foregroundColor ( Color ( filledColor) )
28+ }
29+ }
30+ ForEach ( state. suggestions ?? [ ] , id: \. self) { suggestion in
31+ HStack ( alignment: . firstTextBaseline, spacing: 4 ) {
32+ Text ( " • " )
33+ . frame ( width: 16 , height: 16 , alignment: . center)
34+ . font ( Font ( UIFont . IBMPlexSansRegular ( size: 16 ) ) )
35+ . foregroundColor ( Color ( UIColor . secondaryText) )
36+ Text ( suggestion. mapToLocalizedString ( ) )
37+ . fixedSize ( horizontal: false , vertical: true )
38+ . font ( Font ( UIFont . IBMPlexSansRegular ( size: 16 ) ) )
39+ . multilineTextAlignment ( . leading)
40+ . foregroundColor ( Color ( UIColor . secondaryText) )
41+ }
42+ }
43+ } else {
44+ Text ( LocalizationManager . stytch_zxcvbn_feedback_success)
45+ . fixedSize ( horizontal: false , vertical: true )
46+ . font ( Font ( UIFont . IBMPlexSansRegular ( size: 16 ) ) )
47+ . multilineTextAlignment ( . leading)
48+ . foregroundColor ( Color ( filledColor) )
49+ }
2550 }
2651 }
2752
@@ -40,4 +65,86 @@ final class ZXCVBNState: ObservableObject {
4065 @Published var score : Int = 0
4166 @Published var suggestions : [ String ] ?
4267 @Published var warning : String ?
68+
69+ init ( score: Int = 0 , suggestions: [ String ] ? = nil , warning: String ? = nil ) {
70+ self . score = score
71+ self . suggestions = suggestions
72+ self . warning = warning
73+ }
74+ }
75+
76+ // swiftlint:disable cyclomatic_complexity function_body_length
77+ private extension String {
78+ func mapToLocalizedString( ) -> String {
79+ switch self {
80+ case " Use a few words, avoid common phrases. " :
81+ LocalizationManager . stytch_zxcvbn_suggestion_1
82+ case " No need for symbols, digits, or uppercase letters. " :
83+ LocalizationManager . stytch_zxcvbn_suggestion_2
84+ case " Add another word or two. Uncommon words are better. " :
85+ LocalizationManager . stytch_zxcvbn_suggestion_3
86+ case " Use a longer keyboard pattern with more turns. " :
87+ LocalizationManager . stytch_zxcvbn_suggestion_4
88+ case " Avoid repeated words and characters. " :
89+ LocalizationManager . stytch_zxcvbn_suggestion_5
90+ case " Avoid sequences. " :
91+ LocalizationManager . stytch_zxcvbn_suggestion_6
92+ case " Avoid recent years. " :
93+ LocalizationManager . stytch_zxcvbn_suggestion_7
94+ case " Avoid years that are associated with you. " :
95+ LocalizationManager . stytch_zxcvbn_suggestion_8
96+ case " Avoid dates and years that are associated with you. " :
97+ LocalizationManager . stytch_zxcvbn_suggestion_9
98+ case " Capitalization doesn \' t help very much. " :
99+ LocalizationManager . stytch_zxcvbn_suggestion_10
100+ case " All-uppercase is almost as easy to guess as all-lowercase. " :
101+ LocalizationManager . stytch_zxcvbn_suggestion_11
102+ case " Reversed words aren \' t much harder to guess. " :
103+ LocalizationManager . stytch_zxcvbn_suggestion_12
104+ case " Predictable substitutions like \' @ \' instead of \' a \' don \' t help very much. " :
105+ LocalizationManager . stytch_zxcvbn_suggestion_13
106+ case " Short keyboard patterns are easy to guess. " :
107+ LocalizationManager . stytch_zxcvbn_suggestion_14
108+ case " Straight rows of keys are easy to guess. " :
109+ LocalizationManager . stytch_zxcvbn_suggestion_15
110+ case " Repeats like \" abcabcabc \" are only slightly harder to guess than \" abc \" . " :
111+ LocalizationManager . stytch_zxcvbn_suggestion_16
112+ case " Repeats like \" aaa \" are easy to guess. " :
113+ LocalizationManager . stytch_zxcvbn_suggestion_17
114+ case " Sequences like \" abc \" or \" 6543 \" are easy to guess. " :
115+ LocalizationManager . stytch_zxcvbn_suggestion_18
116+ case " Recent years are easy to guess. " :
117+ LocalizationManager . stytch_zxcvbn_suggestion_19
118+ case " Dates are often easy to guess. " :
119+ LocalizationManager . stytch_zxcvbn_suggestion_20
120+ case " This is a top-10 common password. " :
121+ LocalizationManager . stytch_zxcvbn_suggestion_21
122+ case " This is a top-100 common password. " :
123+ LocalizationManager . stytch_zxcvbn_suggestion_22
124+ case " This is a very common password. " :
125+ LocalizationManager . stytch_zxcvbn_suggestion_23
126+ case " This is similar to a commonly used password. " :
127+ LocalizationManager . stytch_zxcvbn_suggestion_24
128+ case " A word by itself is easy to guess. " :
129+ LocalizationManager . stytch_zxcvbn_suggestion_25
130+ case " Names and surnames by themselves are easy to guess. " :
131+ LocalizationManager . stytch_zxcvbn_suggestion_26
132+ case " Common names and surnames are easy to guess. " :
133+ LocalizationManager . stytch_zxcvbn_suggestion_27
134+ default :
135+ self
136+ }
137+ }
138+ }
139+
140+ #Preview {
141+ let state : ZXCVBNState = . init(
142+ score: 2 ,
143+ suggestions: [
144+ " Predictable substitutions like \' @ \' instead of \' a \' don \' t help very much. " ,
145+ " Common names and surnames are easy to guess. " ,
146+ ] ,
147+ warning: " Common names and surnames are easy to guess. "
148+ )
149+ ZXCVBNIndicator ( state: state)
43150}
0 commit comments