pass-strength-indicator 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,839 @@
1
+ import { useMemo, useState, useEffect } from 'react';
2
+ import { clsx } from 'clsx';
3
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
4
+
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __esm = (fn, res) => function __init() {
8
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
9
+ };
10
+ var __export = (target, all) => {
11
+ for (var name in all)
12
+ __defProp(target, name, { get: all[name], enumerable: true });
13
+ };
14
+
15
+ // src/lib/translations/en.ts
16
+ var en_exports = {};
17
+ __export(en_exports, {
18
+ en: () => en
19
+ });
20
+ var en;
21
+ var init_en = __esm({
22
+ "src/lib/translations/en.ts"() {
23
+ en = {
24
+ levels: {
25
+ veryWeak: "Very Weak",
26
+ weak: "Weak",
27
+ soso: "Mid",
28
+ good: "Good",
29
+ strong: "Strong"
30
+ },
31
+ passwordMustInclude: "Your Password must include",
32
+ passwordStrength: "Password Strength",
33
+ rules: {
34
+ minLength: "At least 12 characters",
35
+ uppercase: "At least one uppercase letter",
36
+ lowercase: "At least one lowercase letter",
37
+ number: "At least one number",
38
+ special: "At least one special character",
39
+ noEmail: "Must not contain your email",
40
+ noForbiddenWords: "Must not contain forbidden words"
41
+ },
42
+ placeholder: "Enter your password",
43
+ label: "Password"
44
+ };
45
+ }
46
+ });
47
+
48
+ // src/lib/translations/fr.ts
49
+ var fr_exports = {};
50
+ __export(fr_exports, {
51
+ fr: () => fr
52
+ });
53
+ var fr;
54
+ var init_fr = __esm({
55
+ "src/lib/translations/fr.ts"() {
56
+ fr = {
57
+ levels: {
58
+ veryWeak: "Tr\xE8s faible",
59
+ weak: "Faible",
60
+ soso: "Moyen",
61
+ good: "Bon",
62
+ strong: "Fort"
63
+ },
64
+ passwordMustInclude: "Votre mot de passe doit inclure",
65
+ passwordStrength: "S\xE9curit\xE9 du mot de passe",
66
+ rules: {
67
+ minLength: "Au moins 12 caract\xE8res",
68
+ uppercase: "Au moins une lettre majuscule",
69
+ lowercase: "Au moins une lettre minuscule",
70
+ number: "Au moins un chiffre",
71
+ special: "Au moins un caract\xE8re sp\xE9cial",
72
+ noEmail: "Ne doit pas contenir votre email",
73
+ noForbiddenWords: "Ne doit pas contenir de mots interdits"
74
+ },
75
+ placeholder: "Entrez votre mot de passe",
76
+ label: "Mot de passe"
77
+ };
78
+ }
79
+ });
80
+
81
+ // src/lib/translations/es.ts
82
+ var es_exports = {};
83
+ __export(es_exports, {
84
+ es: () => es
85
+ });
86
+ var es;
87
+ var init_es = __esm({
88
+ "src/lib/translations/es.ts"() {
89
+ es = {
90
+ levels: {
91
+ veryWeak: "Muy d\xE9bil",
92
+ weak: "D\xE9bil",
93
+ soso: "Regular",
94
+ good: "Buena",
95
+ strong: "Fuerte"
96
+ },
97
+ passwordMustInclude: "Tu contrase\xF1a debe incluir",
98
+ passwordStrength: "Seguridad de la contrase\xF1a",
99
+ rules: {
100
+ minLength: "Al menos 12 caracteres",
101
+ uppercase: "Al menos una letra may\xFAscula",
102
+ lowercase: "Al menos una letra min\xFAscula",
103
+ number: "Al menos un n\xFAmero",
104
+ special: "Al menos un car\xE1cter especial",
105
+ noEmail: "No debe contener tu email",
106
+ noForbiddenWords: "No debe contener palabras prohibidas"
107
+ },
108
+ placeholder: "Ingresa tu contrase\xF1a",
109
+ label: "Contrase\xF1a"
110
+ };
111
+ }
112
+ });
113
+
114
+ // src/lib/translations/de.ts
115
+ var de_exports = {};
116
+ __export(de_exports, {
117
+ de: () => de
118
+ });
119
+ var de;
120
+ var init_de = __esm({
121
+ "src/lib/translations/de.ts"() {
122
+ de = {
123
+ levels: {
124
+ veryWeak: "Sehr schwach",
125
+ weak: "Schwach",
126
+ soso: "Mittel",
127
+ good: "Gut",
128
+ strong: "Stark"
129
+ },
130
+ passwordMustInclude: "Ihr Passwort muss enthalten",
131
+ passwordStrength: "Passwortst\xE4rke",
132
+ rules: {
133
+ minLength: "Mindestens 12 Zeichen",
134
+ uppercase: "Mindestens einen Gro\xDFbuchstaben",
135
+ lowercase: "Mindestens einen Kleinbuchstaben",
136
+ number: "Mindestens eine Zahl",
137
+ special: "Mindestens ein Sonderzeichen",
138
+ noEmail: "Darf Ihre E-Mail nicht enthalten",
139
+ noForbiddenWords: "Darf keine verbotenen W\xF6rter enthalten"
140
+ },
141
+ placeholder: "Geben Sie Ihr Passwort ein",
142
+ label: "Passwort"
143
+ };
144
+ }
145
+ });
146
+
147
+ // src/lib/translations/pt.ts
148
+ var pt_exports = {};
149
+ __export(pt_exports, {
150
+ pt: () => pt
151
+ });
152
+ var pt;
153
+ var init_pt = __esm({
154
+ "src/lib/translations/pt.ts"() {
155
+ pt = {
156
+ levels: {
157
+ veryWeak: "Muito fraca",
158
+ weak: "Fraca",
159
+ soso: "M\xE9dia",
160
+ good: "Boa",
161
+ strong: "Forte"
162
+ },
163
+ passwordMustInclude: "Sua senha deve incluir",
164
+ passwordStrength: "For\xE7a da senha",
165
+ rules: {
166
+ minLength: "Pelo menos 12 caracteres",
167
+ uppercase: "Pelo menos uma letra mai\xFAscula",
168
+ lowercase: "Pelo menos uma letra min\xFAscula",
169
+ number: "Pelo menos um n\xFAmero",
170
+ special: "Pelo menos um caractere especial",
171
+ noEmail: "N\xE3o deve conter seu email",
172
+ noForbiddenWords: "N\xE3o deve conter palavras proibidas"
173
+ },
174
+ placeholder: "Digite sua senha",
175
+ label: "Senha"
176
+ };
177
+ }
178
+ });
179
+
180
+ // src/lib/translations/it.ts
181
+ var it_exports = {};
182
+ __export(it_exports, {
183
+ it: () => it
184
+ });
185
+ var it;
186
+ var init_it = __esm({
187
+ "src/lib/translations/it.ts"() {
188
+ it = {
189
+ levels: {
190
+ veryWeak: "Molto debole",
191
+ weak: "Debole",
192
+ soso: "Media",
193
+ good: "Buona",
194
+ strong: "Forte"
195
+ },
196
+ passwordMustInclude: "La tua password deve includere",
197
+ passwordStrength: "Sicurezza della password",
198
+ rules: {
199
+ minLength: "Almeno 12 caratteri",
200
+ uppercase: "Almeno una lettera maiuscola",
201
+ lowercase: "Almeno una lettera minuscola",
202
+ number: "Almeno un numero",
203
+ special: "Almeno un carattere speciale",
204
+ noEmail: "Non deve contenere la tua email",
205
+ noForbiddenWords: "Non deve contenere parole vietate"
206
+ },
207
+ placeholder: "Inserisci la tua password",
208
+ label: "Password"
209
+ };
210
+ }
211
+ });
212
+
213
+ // src/lib/translations/nl.ts
214
+ var nl_exports = {};
215
+ __export(nl_exports, {
216
+ nl: () => nl
217
+ });
218
+ var nl;
219
+ var init_nl = __esm({
220
+ "src/lib/translations/nl.ts"() {
221
+ nl = {
222
+ levels: {
223
+ veryWeak: "Zeer zwak",
224
+ weak: "Zwak",
225
+ soso: "Gemiddeld",
226
+ good: "Goed",
227
+ strong: "Sterk"
228
+ },
229
+ passwordMustInclude: "Uw wachtwoord moet bevatten",
230
+ passwordStrength: "Wachtwoordsterkte",
231
+ rules: {
232
+ minLength: "Minimaal 12 tekens",
233
+ uppercase: "Minimaal \xE9\xE9n hoofdletter",
234
+ lowercase: "Minimaal \xE9\xE9n kleine letter",
235
+ number: "Minimaal \xE9\xE9n cijfer",
236
+ special: "Minimaal \xE9\xE9n speciaal teken",
237
+ noEmail: "Mag uw e-mail niet bevatten",
238
+ noForbiddenWords: "Mag geen verboden woorden bevatten"
239
+ },
240
+ placeholder: "Voer uw wachtwoord in",
241
+ label: "Wachtwoord"
242
+ };
243
+ }
244
+ });
245
+
246
+ // src/lib/translations/pl.ts
247
+ var pl_exports = {};
248
+ __export(pl_exports, {
249
+ pl: () => pl
250
+ });
251
+ var pl;
252
+ var init_pl = __esm({
253
+ "src/lib/translations/pl.ts"() {
254
+ pl = {
255
+ levels: {
256
+ veryWeak: "Bardzo s\u0142abe",
257
+ weak: "S\u0142abe",
258
+ soso: "\u015Arednie",
259
+ good: "Dobre",
260
+ strong: "Silne"
261
+ },
262
+ passwordMustInclude: "Twoje has\u0142o musi zawiera\u0107",
263
+ passwordStrength: "Si\u0142a has\u0142a",
264
+ rules: {
265
+ minLength: "Co najmniej 12 znak\xF3w",
266
+ uppercase: "Co najmniej jedn\u0105 wielk\u0105 liter\u0119",
267
+ lowercase: "Co najmniej jedn\u0105 ma\u0142\u0105 liter\u0119",
268
+ number: "Co najmniej jedn\u0105 cyfr\u0119",
269
+ special: "Co najmniej jeden znak specjalny",
270
+ noEmail: "Nie mo\u017Ce zawiera\u0107 Twojego emaila",
271
+ noForbiddenWords: "Nie mo\u017Ce zawiera\u0107 zabronionych s\u0142\xF3w"
272
+ },
273
+ placeholder: "Wprowad\u017A has\u0142o",
274
+ label: "Has\u0142o"
275
+ };
276
+ }
277
+ });
278
+
279
+ // src/lib/translations/sv.ts
280
+ var sv_exports = {};
281
+ __export(sv_exports, {
282
+ sv: () => sv
283
+ });
284
+ var sv;
285
+ var init_sv = __esm({
286
+ "src/lib/translations/sv.ts"() {
287
+ sv = {
288
+ levels: {
289
+ veryWeak: "Mycket svagt",
290
+ weak: "Svagt",
291
+ soso: "Medel",
292
+ good: "Bra",
293
+ strong: "Starkt"
294
+ },
295
+ passwordMustInclude: "Ditt l\xF6senord m\xE5ste inneh\xE5lla",
296
+ passwordStrength: "L\xF6senordsstyrka",
297
+ rules: {
298
+ minLength: "Minst 12 tecken",
299
+ uppercase: "Minst en stor bokstav",
300
+ lowercase: "Minst en liten bokstav",
301
+ number: "Minst en siffra",
302
+ special: "Minst ett specialtecken",
303
+ noEmail: "F\xE5r inte inneh\xE5lla din e-post",
304
+ noForbiddenWords: "F\xE5r inte inneh\xE5lla f\xF6rbjudna ord"
305
+ },
306
+ placeholder: "Ange ditt l\xF6senord",
307
+ label: "L\xF6senord"
308
+ };
309
+ }
310
+ });
311
+
312
+ // src/lib/translations/uk.ts
313
+ var uk_exports = {};
314
+ __export(uk_exports, {
315
+ uk: () => uk
316
+ });
317
+ var uk;
318
+ var init_uk = __esm({
319
+ "src/lib/translations/uk.ts"() {
320
+ uk = {
321
+ levels: {
322
+ veryWeak: "\u0414\u0443\u0436\u0435 \u0441\u043B\u0430\u0431\u043A\u0438\u0439",
323
+ weak: "\u0421\u043B\u0430\u0431\u043A\u0438\u0439",
324
+ soso: "\u0421\u0435\u0440\u0435\u0434\u043D\u0456\u0439",
325
+ good: "\u0414\u043E\u0431\u0440\u0438\u0439",
326
+ strong: "\u0421\u0438\u043B\u044C\u043D\u0438\u0439"
327
+ },
328
+ passwordMustInclude: "\u0412\u0430\u0448 \u043F\u0430\u0440\u043E\u043B\u044C \u043F\u043E\u0432\u0438\u043D\u0435\u043D \u043C\u0456\u0441\u0442\u0438\u0442\u0438",
329
+ passwordStrength: "\u041D\u0430\u0434\u0456\u0439\u043D\u0456\u0441\u0442\u044C \u043F\u0430\u0440\u043E\u043B\u044F",
330
+ rules: {
331
+ minLength: "\u041C\u0456\u043D\u0456\u043C\u0443\u043C 12 \u0441\u0438\u043C\u0432\u043E\u043B\u0456\u0432",
332
+ uppercase: "\u041F\u0440\u0438\u043D\u0430\u0439\u043C\u043D\u0456 \u043E\u0434\u043D\u0443 \u0432\u0435\u043B\u0438\u043A\u0443 \u043B\u0456\u0442\u0435\u0440\u0443",
333
+ lowercase: "\u041F\u0440\u0438\u043D\u0430\u0439\u043C\u043D\u0456 \u043E\u0434\u043D\u0443 \u043C\u0430\u043B\u0443 \u043B\u0456\u0442\u0435\u0440\u0443",
334
+ number: "\u041F\u0440\u0438\u043D\u0430\u0439\u043C\u043D\u0456 \u043E\u0434\u043D\u0443 \u0446\u0438\u0444\u0440\u0443",
335
+ special: "\u041F\u0440\u0438\u043D\u0430\u0439\u043C\u043D\u0456 \u043E\u0434\u0438\u043D \u0441\u043F\u0435\u0446\u0456\u0430\u043B\u044C\u043D\u0438\u0439 \u0441\u0438\u043C\u0432\u043E\u043B",
336
+ noEmail: "\u041D\u0435 \u043F\u043E\u0432\u0438\u043D\u0435\u043D \u043C\u0456\u0441\u0442\u0438\u0442\u0438 \u0432\u0430\u0448\u0443 \u0435\u043B\u0435\u043A\u0442\u0440\u043E\u043D\u043D\u0443 \u043F\u043E\u0448\u0442\u0443",
337
+ noForbiddenWords: "\u041D\u0435 \u043F\u043E\u0432\u0438\u043D\u0435\u043D \u043C\u0456\u0441\u0442\u0438\u0442\u0438 \u0437\u0430\u0431\u043E\u0440\u043E\u043D\u0435\u043D\u0456 \u0441\u043B\u043E\u0432\u0430"
338
+ },
339
+ placeholder: "\u0412\u0432\u0435\u0434\u0456\u0442\u044C \u043F\u0430\u0440\u043E\u043B\u044C",
340
+ label: "\u041F\u0430\u0440\u043E\u043B\u044C"
341
+ };
342
+ }
343
+ });
344
+
345
+ // src/lib/translations/zh.ts
346
+ var zh_exports = {};
347
+ __export(zh_exports, {
348
+ zh: () => zh
349
+ });
350
+ var zh;
351
+ var init_zh = __esm({
352
+ "src/lib/translations/zh.ts"() {
353
+ zh = {
354
+ levels: {
355
+ veryWeak: "\u975E\u5E38\u5F31",
356
+ weak: "\u5F31",
357
+ soso: "\u4E2D\u7B49",
358
+ good: "\u826F\u597D",
359
+ strong: "\u5F3A"
360
+ },
361
+ passwordMustInclude: "\u60A8\u7684\u5BC6\u7801\u5FC5\u987B\u5305\u542B",
362
+ passwordStrength: "\u5BC6\u7801\u5F3A\u5EA6",
363
+ rules: {
364
+ minLength: "\u81F3\u5C1112\u4E2A\u5B57\u7B26",
365
+ uppercase: "\u81F3\u5C11\u4E00\u4E2A\u5927\u5199\u5B57\u6BCD",
366
+ lowercase: "\u81F3\u5C11\u4E00\u4E2A\u5C0F\u5199\u5B57\u6BCD",
367
+ number: "\u81F3\u5C11\u4E00\u4E2A\u6570\u5B57",
368
+ special: "\u81F3\u5C11\u4E00\u4E2A\u7279\u6B8A\u5B57\u7B26",
369
+ noEmail: "\u4E0D\u80FD\u5305\u542B\u60A8\u7684\u90AE\u7BB1",
370
+ noForbiddenWords: "\u4E0D\u80FD\u5305\u542B\u7981\u7528\u8BCD"
371
+ },
372
+ placeholder: "\u8BF7\u8F93\u5165\u5BC6\u7801",
373
+ label: "\u5BC6\u7801"
374
+ };
375
+ }
376
+ });
377
+
378
+ // src/lib/translations/ja.ts
379
+ var ja_exports = {};
380
+ __export(ja_exports, {
381
+ ja: () => ja
382
+ });
383
+ var ja;
384
+ var init_ja = __esm({
385
+ "src/lib/translations/ja.ts"() {
386
+ ja = {
387
+ levels: {
388
+ veryWeak: "\u975E\u5E38\u306B\u5F31\u3044",
389
+ weak: "\u5F31\u3044",
390
+ soso: "\u666E\u901A",
391
+ good: "\u826F\u3044",
392
+ strong: "\u5F37\u3044"
393
+ },
394
+ passwordMustInclude: "\u30D1\u30B9\u30EF\u30FC\u30C9\u306B\u306F\u4EE5\u4E0B\u304C\u5FC5\u8981\u3067\u3059",
395
+ passwordStrength: "\u30D1\u30B9\u30EF\u30FC\u30C9\u5F37\u5EA6",
396
+ rules: {
397
+ minLength: "12\u6587\u5B57\u4EE5\u4E0A",
398
+ uppercase: "\u5927\u6587\u5B57\u30921\u3064\u4EE5\u4E0A",
399
+ lowercase: "\u5C0F\u6587\u5B57\u30921\u3064\u4EE5\u4E0A",
400
+ number: "\u6570\u5B57\u30921\u3064\u4EE5\u4E0A",
401
+ special: "\u7279\u6B8A\u6587\u5B57\u30921\u3064\u4EE5\u4E0A",
402
+ noEmail: "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u542B\u3081\u306A\u3044",
403
+ noForbiddenWords: "\u7981\u6B62\u8A9E\u3092\u542B\u3081\u306A\u3044"
404
+ },
405
+ placeholder: "\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u5165\u529B",
406
+ label: "\u30D1\u30B9\u30EF\u30FC\u30C9"
407
+ };
408
+ }
409
+ });
410
+
411
+ // src/lib/translations/ko.ts
412
+ var ko_exports = {};
413
+ __export(ko_exports, {
414
+ ko: () => ko
415
+ });
416
+ var ko;
417
+ var init_ko = __esm({
418
+ "src/lib/translations/ko.ts"() {
419
+ ko = {
420
+ levels: {
421
+ veryWeak: "\uB9E4\uC6B0 \uC57D\uD568",
422
+ weak: "\uC57D\uD568",
423
+ soso: "\uBCF4\uD1B5",
424
+ good: "\uC88B\uC74C",
425
+ strong: "\uAC15\uD568"
426
+ },
427
+ passwordMustInclude: "\uBE44\uBC00\uBC88\uD638\uB294 \uB2E4\uC74C\uC744 \uD3EC\uD568\uD574\uC57C \uD569\uB2C8\uB2E4",
428
+ passwordStrength: "\uBE44\uBC00\uBC88\uD638 \uAC15\uB3C4",
429
+ rules: {
430
+ minLength: "\uCD5C\uC18C 12\uC790",
431
+ uppercase: "\uB300\uBB38\uC790 1\uAC1C \uC774\uC0C1",
432
+ lowercase: "\uC18C\uBB38\uC790 1\uAC1C \uC774\uC0C1",
433
+ number: "\uC22B\uC790 1\uAC1C \uC774\uC0C1",
434
+ special: "\uD2B9\uC218\uBB38\uC790 1\uAC1C \uC774\uC0C1",
435
+ noEmail: "\uC774\uBA54\uC77C \uD3EC\uD568 \uBD88\uAC00",
436
+ noForbiddenWords: "\uAE08\uC9C0\uC5B4 \uD3EC\uD568 \uBD88\uAC00"
437
+ },
438
+ placeholder: "\uBE44\uBC00\uBC88\uD638 \uC785\uB825",
439
+ label: "\uBE44\uBC00\uBC88\uD638"
440
+ };
441
+ }
442
+ });
443
+
444
+ // src/lib/rules.ts
445
+ var defaultRules = [
446
+ {
447
+ id: "minLength",
448
+ test: (password) => password.length >= 12
449
+ },
450
+ {
451
+ id: "uppercase",
452
+ test: (password) => /[A-Z]/.test(password)
453
+ },
454
+ {
455
+ id: "lowercase",
456
+ test: (password) => /[a-z]/.test(password)
457
+ },
458
+ {
459
+ id: "number",
460
+ test: (password) => /[0-9]/.test(password)
461
+ },
462
+ {
463
+ id: "special",
464
+ test: (password) => /[!@#$%^&*(),.?":{}|<>_\-+=\[\]\\\/`~;']/.test(password)
465
+ }
466
+ ];
467
+ var optionalRules = [
468
+ {
469
+ id: "noEmail",
470
+ test: (password, options) => {
471
+ if (!(options == null ? void 0 : options.email)) return true;
472
+ const emailParts = options.email.toLowerCase().split("@");
473
+ const username = emailParts[0];
474
+ if (!username || username.length < 4) return true;
475
+ const lowerPassword = password.toLowerCase();
476
+ const minLength = 4;
477
+ for (let len = minLength; len <= username.length; len++) {
478
+ for (let i = 0; i <= username.length - len; i++) {
479
+ const substring = username.slice(i, i + len);
480
+ if (lowerPassword.includes(substring)) {
481
+ return false;
482
+ }
483
+ }
484
+ }
485
+ return true;
486
+ }
487
+ },
488
+ {
489
+ id: "noForbiddenWords",
490
+ test: (password, options) => {
491
+ if (!(options == null ? void 0 : options.forbiddenWords) || options.forbiddenWords.length === 0) return true;
492
+ const lowerPassword = password.toLowerCase();
493
+ return !options.forbiddenWords.some(
494
+ (word) => lowerPassword.includes(word.toLowerCase())
495
+ );
496
+ }
497
+ }
498
+ ];
499
+ function evaluatePassword(password, options) {
500
+ var _a;
501
+ const passedRules = [];
502
+ const failedRules = [];
503
+ for (const rule of defaultRules) {
504
+ if (rule.test(password, options)) {
505
+ passedRules.push(rule.id);
506
+ } else {
507
+ failedRules.push(rule.id);
508
+ }
509
+ }
510
+ for (const rule of optionalRules) {
511
+ if (rule.id === "noEmail" && (options == null ? void 0 : options.email)) {
512
+ if (rule.test(password, options)) {
513
+ passedRules.push(rule.id);
514
+ } else {
515
+ failedRules.push(rule.id);
516
+ }
517
+ }
518
+ if (rule.id === "noForbiddenWords" && ((_a = options == null ? void 0 : options.forbiddenWords) == null ? void 0 : _a.length)) {
519
+ if (rule.test(password, options)) {
520
+ passedRules.push(rule.id);
521
+ } else {
522
+ failedRules.push(rule.id);
523
+ }
524
+ }
525
+ }
526
+ const totalRules = passedRules.length + failedRules.length;
527
+ let score = totalRules > 0 ? Math.round(passedRules.length / totalRules * 5) : 0;
528
+ if (failedRules.includes("noEmail")) {
529
+ score = Math.max(0, score - 2);
530
+ }
531
+ if (failedRules.includes("noForbiddenWords")) {
532
+ score = Math.max(0, score - 2);
533
+ }
534
+ return { passedRules, failedRules, score };
535
+ }
536
+
537
+ // src/lib/usePasswordStrength.ts
538
+ function scoreToLevel(score, levels) {
539
+ if (levels === 5) {
540
+ if (score === 0) return "veryWeak";
541
+ if (score === 1) return "veryWeak";
542
+ if (score === 2) return "weak";
543
+ if (score === 3) return "soso";
544
+ if (score === 4) return "good";
545
+ return "strong";
546
+ }
547
+ if (levels === 4) {
548
+ if (score <= 1) return "weak";
549
+ if (score === 2) return "soso";
550
+ if (score === 3 || score === 4) return "good";
551
+ return "strong";
552
+ }
553
+ if (score <= 2) return "weak";
554
+ if (score <= 4) return "soso";
555
+ return "strong";
556
+ }
557
+ function levelToActiveBars(level, totalBars) {
558
+ const mapping = {
559
+ veryWeak: { 3: 0, 4: 0, 5: 1 },
560
+ weak: { 3: 1, 4: 1, 5: 2 },
561
+ soso: { 3: 2, 4: 2, 5: 3 },
562
+ good: { 3: 2, 4: 3, 5: 4 },
563
+ strong: { 3: 3, 4: 4, 5: 5 }
564
+ };
565
+ return mapping[level][totalBars];
566
+ }
567
+ function usePasswordStrength(password, options = {}) {
568
+ const { barsNumber = 5, email, forbiddenWords } = options;
569
+ return useMemo(() => {
570
+ if (!password) {
571
+ return {
572
+ score: 0,
573
+ level: "veryWeak",
574
+ passedRules: [],
575
+ failedRules: ["minLength", "uppercase", "lowercase", "number", "special"],
576
+ percentage: 0
577
+ };
578
+ }
579
+ const ruleOptions = { email, forbiddenWords };
580
+ const { passedRules, failedRules, score } = evaluatePassword(password, ruleOptions);
581
+ const level = scoreToLevel(score, barsNumber);
582
+ const percentage = Math.round(score / 5 * 100);
583
+ return {
584
+ score,
585
+ level,
586
+ passedRules,
587
+ failedRules,
588
+ percentage
589
+ };
590
+ }, [password, barsNumber, email, forbiddenWords]);
591
+ }
592
+
593
+ // src/lib/translations/index.ts
594
+ init_en();
595
+ var translationCache = /* @__PURE__ */ new Map();
596
+ async function loadTranslation(locale) {
597
+ if (translationCache.has(locale)) {
598
+ return translationCache.get(locale);
599
+ }
600
+ try {
601
+ let translation;
602
+ switch (locale) {
603
+ case "en":
604
+ translation = (await Promise.resolve().then(() => (init_en(), en_exports))).en;
605
+ break;
606
+ case "fr":
607
+ translation = (await Promise.resolve().then(() => (init_fr(), fr_exports))).fr;
608
+ break;
609
+ case "es":
610
+ translation = (await Promise.resolve().then(() => (init_es(), es_exports))).es;
611
+ break;
612
+ case "de":
613
+ translation = (await Promise.resolve().then(() => (init_de(), de_exports))).de;
614
+ break;
615
+ case "pt":
616
+ translation = (await Promise.resolve().then(() => (init_pt(), pt_exports))).pt;
617
+ break;
618
+ case "it":
619
+ translation = (await Promise.resolve().then(() => (init_it(), it_exports))).it;
620
+ break;
621
+ case "nl":
622
+ translation = (await Promise.resolve().then(() => (init_nl(), nl_exports))).nl;
623
+ break;
624
+ case "pl":
625
+ translation = (await Promise.resolve().then(() => (init_pl(), pl_exports))).pl;
626
+ break;
627
+ case "sv":
628
+ translation = (await Promise.resolve().then(() => (init_sv(), sv_exports))).sv;
629
+ break;
630
+ case "uk":
631
+ translation = (await Promise.resolve().then(() => (init_uk(), uk_exports))).uk;
632
+ break;
633
+ case "zh":
634
+ translation = (await Promise.resolve().then(() => (init_zh(), zh_exports))).zh;
635
+ break;
636
+ case "ja":
637
+ translation = (await Promise.resolve().then(() => (init_ja(), ja_exports))).ja;
638
+ break;
639
+ case "ko":
640
+ translation = (await Promise.resolve().then(() => (init_ko(), ko_exports))).ko;
641
+ break;
642
+ default:
643
+ translation = en;
644
+ }
645
+ translationCache.set(locale, translation);
646
+ return translation;
647
+ } catch (e) {
648
+ return en;
649
+ }
650
+ }
651
+ function getTranslationSync(locale) {
652
+ var _a;
653
+ return (_a = translationCache.get(locale)) != null ? _a : en;
654
+ }
655
+ function preloadTranslation(locale) {
656
+ loadTranslation(locale);
657
+ }
658
+ function CheckIcon({ className }) {
659
+ return /* @__PURE__ */ jsx(
660
+ "svg",
661
+ {
662
+ xmlns: "http://www.w3.org/2000/svg",
663
+ viewBox: "0 0 20 20",
664
+ fill: "currentColor",
665
+ className: clsx("w-4 h-4", className),
666
+ children: /* @__PURE__ */ jsx(
667
+ "path",
668
+ {
669
+ fillRule: "evenodd",
670
+ d: "M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z",
671
+ clipRule: "evenodd"
672
+ }
673
+ )
674
+ }
675
+ );
676
+ }
677
+ function XIcon({ className }) {
678
+ return /* @__PURE__ */ jsx(
679
+ "svg",
680
+ {
681
+ xmlns: "http://www.w3.org/2000/svg",
682
+ viewBox: "0 0 20 20",
683
+ fill: "currentColor",
684
+ className: clsx("w-4 h-4", className),
685
+ children: /* @__PURE__ */ jsx("path", { d: "M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" })
686
+ }
687
+ );
688
+ }
689
+ var levelColors = {
690
+ veryWeak: {
691
+ bar: "bg-gray-300 dark:bg-gray-600",
692
+ text: "text-gray-500 dark:text-gray-400"
693
+ },
694
+ weak: {
695
+ bar: "bg-red-500",
696
+ text: "text-red-500"
697
+ },
698
+ soso: {
699
+ bar: "bg-orange-400",
700
+ text: "text-orange-400"
701
+ },
702
+ good: {
703
+ bar: "bg-lime-500",
704
+ text: "text-lime-500"
705
+ },
706
+ strong: {
707
+ bar: "bg-green-500",
708
+ text: "text-green-500"
709
+ }
710
+ };
711
+ function PasswordStrength({
712
+ value,
713
+ locale = "en",
714
+ barsNumber = 5,
715
+ maxRules = 2,
716
+ email,
717
+ forbiddenWords,
718
+ className,
719
+ barClassName,
720
+ barMode = "default"
721
+ }) {
722
+ const [translation, setTranslation] = useState(
723
+ () => getTranslationSync(locale)
724
+ );
725
+ useEffect(() => {
726
+ loadTranslation(locale).then(setTranslation);
727
+ }, [locale]);
728
+ const { level, passedRules, failedRules, percentage } = usePasswordStrength(
729
+ value,
730
+ {
731
+ barsNumber,
732
+ email,
733
+ forbiddenWords
734
+ }
735
+ );
736
+ const colors = levelColors[level];
737
+ const activeBars = levelToActiveBars(level, barsNumber);
738
+ const displayRules = useMemo(
739
+ () => [
740
+ ...failedRules.slice(0, maxRules),
741
+ ...passedRules.slice(0, Math.max(0, maxRules - failedRules.length))
742
+ ].slice(0, maxRules),
743
+ [failedRules, passedRules, maxRules]
744
+ );
745
+ const hasValue = value && value.length > 0;
746
+ const rulesContent = maxRules > 0 && displayRules.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
747
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: translation.passwordMustInclude }),
748
+ /* @__PURE__ */ jsx("ul", { className: "space-y-1", children: displayRules.map((ruleId) => {
749
+ const isPassed = passedRules.includes(ruleId);
750
+ const ruleLabel = translation.rules[ruleId];
751
+ return /* @__PURE__ */ jsxs(
752
+ "li",
753
+ {
754
+ className: clsx(
755
+ "flex items-center gap-[10px] text-sm transition-colors",
756
+ isPassed ? "text-green-600 dark:text-green-400" : "text-gray-600 dark:text-gray-400"
757
+ ),
758
+ children: [
759
+ isPassed ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-blue-500 shrink-0" }) : /* @__PURE__ */ jsx(XIcon, { className: "text-gray-400 shrink-0" }),
760
+ /* @__PURE__ */ jsx("span", { className: "text-black dark:text-white", children: ruleLabel })
761
+ ]
762
+ },
763
+ ruleId
764
+ );
765
+ }) })
766
+ ] });
767
+ if (barMode === "rounded") {
768
+ return /* @__PURE__ */ jsx("div", { className: clsx("w-full space-y-2", className), children: hasValue && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
769
+ rulesContent && /* @__PURE__ */ jsx("div", { className: "space-y-2", children: rulesContent }),
770
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
771
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
772
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600 dark:text-gray-400 font-medium", children: translation.passwordStrength }),
773
+ /* @__PURE__ */ jsx("span", { className: clsx("font-medium", colors.text), children: translation.levels[level] })
774
+ ] }),
775
+ /* @__PURE__ */ jsx(
776
+ "div",
777
+ {
778
+ className: clsx(
779
+ "h-1 w-full rounded-full bg-gray-200 dark:bg-gray-700",
780
+ barClassName
781
+ ),
782
+ children: /* @__PURE__ */ jsx(
783
+ "div",
784
+ {
785
+ className: clsx(
786
+ "h-1 rounded-full transition-all duration-300",
787
+ colors.bar
788
+ ),
789
+ style: { width: `${percentage}%` }
790
+ }
791
+ )
792
+ }
793
+ )
794
+ ] })
795
+ ] }) });
796
+ }
797
+ return /* @__PURE__ */ jsx("div", { className: clsx("w-full space-y-2", className), children: hasValue && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
798
+ maxRules > 0 && displayRules.length > 0 && /* @__PURE__ */ jsxs("div", { className: "p-3 rounded-lg bg-[#f9f9f9] dark:bg-[#eeeeee0f] space-y-2 mt-[17px]", children: [
799
+ rulesContent,
800
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1.5 pt-[6px] pb-2 border-gray-200 dark:border-gray-700", children: [
801
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
802
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600 dark:text-gray-400 font-medium", children: translation.passwordStrength }),
803
+ /* @__PURE__ */ jsx("span", { className: clsx("font-medium", colors.text), children: translation.levels[level] })
804
+ ] }),
805
+ /* @__PURE__ */ jsx("div", { className: clsx("flex gap-1", barClassName), children: Array.from({ length: barsNumber }).map((_, index) => /* @__PURE__ */ jsx(
806
+ "div",
807
+ {
808
+ className: clsx(
809
+ "h-[3.5px] mt-[6px] flex-1 rounded-full transition-all duration-300",
810
+ index < activeBars ? colors.bar : "bg-gray-200 dark:bg-gray-700"
811
+ )
812
+ },
813
+ index
814
+ )) })
815
+ ] })
816
+ ] }),
817
+ maxRules === 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
818
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
819
+ /* @__PURE__ */ jsx("span", { className: "text-gray-600 dark:text-gray-400 font-medium", children: translation.passwordStrength }),
820
+ /* @__PURE__ */ jsx("span", { className: clsx("font-medium", colors.text), children: translation.levels[level] })
821
+ ] }),
822
+ /* @__PURE__ */ jsx("div", { className: clsx("flex gap-1", barClassName), children: Array.from({ length: barsNumber }).map((_, index) => /* @__PURE__ */ jsx(
823
+ "div",
824
+ {
825
+ className: clsx(
826
+ "h-[3.5px] flex-1 mt-0.5 rounded-full transition-all duration-300",
827
+ index < activeBars ? colors.bar : "bg-gray-200 dark:bg-gray-700"
828
+ )
829
+ },
830
+ index
831
+ )) })
832
+ ] })
833
+ ] }) });
834
+ }
835
+ var PasswordStrength_default = PasswordStrength;
836
+
837
+ export { PasswordStrength, PasswordStrength_default as default, defaultRules, evaluatePassword, getTranslationSync, levelToActiveBars, loadTranslation, optionalRules, preloadTranslation, usePasswordStrength };
838
+ //# sourceMappingURL=index.mjs.map
839
+ //# sourceMappingURL=index.mjs.map