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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Samuel Prigent
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # shadcn-password-strength
2
+
3
+ A customizable password strength indicator component for React with multi-language support
4
+
5
+ [![npm version](https://img.shields.io/npm/v/shadcn-password-strength.svg)](https://www.npmjs.com/package/shadcn-password-strength)
6
+ [![license](https://img.shields.io/npm/l/shadcn-password-strength.svg)](https://github.com/SamuelPrigent/shadcn-password-strength/blob/main/LICENSE)
7
+
8
+ ## Features
9
+
10
+ - **13 languages** supported: English, French, Spanish, German, Portuguese, Italian, Dutch, Polish, Swedish, Ukrainian, Chinese, Japanese, Korean
11
+ - **Flexible display**: Show 0-5 validation rules, or bar-only mode
12
+ - **Configurable strength levels**: 3, 4, or 5 bars
13
+ - **Email pattern detection**: Prevents users from using parts of their email in passwords
14
+ - **Forbidden words**: Block specific words from being used
15
+ - **shadcn/ui integration**: Uses your own Input/Label components for consistent styling
16
+ - **Dark mode** support out of the box
17
+ - **Fully typed** with TypeScript
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ # 1. Install shadcn/ui components (if not already installed)
23
+ npx shadcn@latest add input label
24
+
25
+ # 2. Install the package
26
+ npm install pass-strength-indicator
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ```tsx
32
+ import { useState } from "react";
33
+ import { PasswordStrength } from "pass-strength-indicator";
34
+ import { Input } from "@/components/ui/input";
35
+ import { Label } from "@/components/ui/label";
36
+
37
+ export function PasswordForm() {
38
+ const [password, setPassword] = useState("");
39
+
40
+ return (
41
+ <PasswordStrength
42
+ value={password}
43
+ onChange={setPassword}
44
+ InputComponent={Input}
45
+ LabelComponent={Label}
46
+ />
47
+ );
48
+ }
49
+ ```
50
+
51
+ ## Examples
52
+
53
+ ### Bar Only Mode
54
+
55
+ Set `maxRules={0}` to hide validation rules and show only the strength bar:
56
+
57
+ ```tsx
58
+ <PasswordStrength
59
+ value={password}
60
+ onChange={setPassword}
61
+ maxRules={0}
62
+ InputComponent={Input}
63
+ LabelComponent={Label}
64
+ />
65
+ ```
66
+
67
+ ### Multi-language Support
68
+
69
+ Available locales: `en`, `fr`, `es`, `de`, `pt`, `it`, `nl`, `pl`, `sv`, `uk`, `zh`, `ja`, `ko`
70
+
71
+ ```tsx
72
+ <PasswordStrength
73
+ value={password}
74
+ onChange={setPassword}
75
+ locale="de"
76
+ InputComponent={Input}
77
+ LabelComponent={Label}
78
+ />
79
+ ```
80
+
81
+ ### Email Pattern Detection
82
+
83
+ Prevents users from including any 4+ consecutive characters from their email:
84
+
85
+ ```tsx
86
+ <PasswordStrength
87
+ value={password}
88
+ onChange={setPassword}
89
+ email="johndoe@example.com"
90
+ InputComponent={Input}
91
+ LabelComponent={Label}
92
+ />
93
+ ```
94
+
95
+ ### Custom Number of Bars
96
+
97
+ Choose between 3, 4, or 5 strength bars:
98
+
99
+ ```tsx
100
+ <PasswordStrength
101
+ value={password}
102
+ onChange={setPassword}
103
+ barsNumber={3}
104
+ InputComponent={Input}
105
+ LabelComponent={Label}
106
+ />
107
+ ```
108
+
109
+ ### Full Configuration
110
+
111
+ ```tsx
112
+ <PasswordStrength
113
+ value={password}
114
+ onChange={setPassword}
115
+ locale="fr"
116
+ barsNumber={5}
117
+ maxRules={3}
118
+ email="user@example.com"
119
+ forbiddenWords={["password", "company"]}
120
+ InputComponent={Input}
121
+ LabelComponent={Label}
122
+ />
123
+ ```
124
+
125
+ ## Props
126
+
127
+ ### Required
128
+
129
+ | Prop | Type | Description |
130
+ | ---------- | ------------------------- | --------------- |
131
+ | `value` | `string` | Password value |
132
+ | `onChange` | `(value: string) => void` | Change callback |
133
+
134
+ ### Shadcn Components
135
+
136
+ | Prop | Type | Description |
137
+ | ---------------- | ----------- | ------------------------------- |
138
+ | `InputComponent` | `Component` | Your Input from @/components/ui |
139
+ | `LabelComponent` | `Component` | Your Label from @/components/ui |
140
+
141
+ ### Package Customization
142
+
143
+ | Prop | Type | Default | Description |
144
+ | ------------- | ----------------------------- | ------- | ------------------------------------------------------------- |
145
+ | `locale` | `"en" \| "fr" \| ... \| "ko"` | `"en"` | Language (en, fr, es, de, pt, it, nl, pl, sv, uk, zh, ja, ko) |
146
+ | `barsNumber` | `3 \| 4 \| 5` | `5` | Number of strength indicator bars |
147
+ | `maxRules` | `number` | `2` | Max validation rules shown (0 = bar only) |
148
+ | `placeholder` | `string` | - | Input placeholder text |
149
+ | `label` | `string` | - | Input label text |
150
+
151
+ ### Validation
152
+
153
+ | Prop | Type | Description |
154
+ | ---------------- | ---------- | ----------------------------------------------- |
155
+ | `email` | `string` | Detects 4+ consecutive chars from email |
156
+ | `forbiddenWords` | `string[]` | Words that cannot be in the password (-2 score) |
157
+
158
+ ### Visibility Toggle
159
+
160
+ | Prop | Type | Default | Description |
161
+ | ---------------------- | --------- | ------- | ------------------------------------------- |
162
+ | `showToggleVisibility` | `boolean` | `true` | Show/hide password visibility toggle button |
163
+ | `toggleTabIndex` | `number` | `-1` | Tab index for the visibility toggle button |
164
+
165
+ ### Styling
166
+
167
+ | Prop | Type | Description |
168
+ | ---------------- | -------- | ------------------------------------------- |
169
+ | `className` | `string` | Additional class name for the container |
170
+ | `barClassName` | `string` | Additional class name for the strength bars |
171
+ | `inputClassName` | `string` | Additional class name for the input field |
172
+
173
+ ## Password Rules
174
+
175
+ The component validates passwords against these rules:
176
+
177
+ 1. **Minimum length**: At least 12 characters
178
+ 2. **Uppercase**: At least one uppercase letter
179
+ 3. **Lowercase**: At least one lowercase letter
180
+ 4. **Number**: At least one digit
181
+ 5. **Special character**: At least one special character
182
+ 6. **No email pattern** (optional): No 4+ consecutive characters from email
183
+ 7. **No forbidden words** (optional): None of the specified forbidden words
184
+
185
+ ## Documentation
186
+
187
+ For full documentation and live examples, visit the [documentation site](https://shadcn-password-strength.vercel.app).
188
+
189
+ ## License
190
+
191
+ MIT
@@ -0,0 +1,94 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type Locale = "en" | "fr" | "es" | "de" | "pt" | "it" | "nl" | "pl" | "sv" | "uk" | "zh" | "ja" | "ko";
4
+ type StrengthLevel = "veryWeak" | "weak" | "soso" | "good" | "strong";
5
+ interface PasswordRule {
6
+ id: string;
7
+ test: (password: string, options?: RuleOptions) => boolean;
8
+ }
9
+ interface RuleOptions {
10
+ email?: string;
11
+ forbiddenWords?: string[];
12
+ }
13
+ interface PasswordStrengthResult {
14
+ score: number;
15
+ level: StrengthLevel;
16
+ passedRules: string[];
17
+ failedRules: string[];
18
+ percentage: number;
19
+ }
20
+ interface PasswordStrengthProps {
21
+ /** Current password value */
22
+ value: string;
23
+ /** Language for labels and messages */
24
+ locale?: Locale;
25
+ /** Number of strength bars (3, 4, or 5) */
26
+ barsNumber?: 3 | 4 | 5;
27
+ /** Maximum number of rules to display (0 = no rules, just bar) */
28
+ maxRules?: number;
29
+ /** Email to check password doesn't contain it */
30
+ email?: string;
31
+ /** Additional words that should not be in the password */
32
+ forbiddenWords?: string[];
33
+ /** Additional class name for the container */
34
+ className?: string;
35
+ /** Additional class name for the strength bars */
36
+ barClassName?: string;
37
+ /** Visual bar mode variant */
38
+ barMode?: "default" | "rounded";
39
+ }
40
+
41
+ declare function PasswordStrength({ value, locale, barsNumber, maxRules, email, forbiddenWords, className, barClassName, barMode, }: PasswordStrengthProps): react_jsx_runtime.JSX.Element;
42
+
43
+ /**
44
+ * Maps a strength level to the number of active bars
45
+ */
46
+ declare function levelToActiveBars(level: StrengthLevel, totalBars: 3 | 4 | 5): number;
47
+ interface UsePasswordStrengthOptions {
48
+ barsNumber?: 3 | 4 | 5;
49
+ email?: string;
50
+ forbiddenWords?: string[];
51
+ }
52
+ declare function usePasswordStrength(password: string, options?: UsePasswordStrengthOptions): PasswordStrengthResult;
53
+
54
+ interface Translation {
55
+ levels: Record<StrengthLevel, string>;
56
+ passwordMustInclude: string;
57
+ passwordStrength: string;
58
+ rules: {
59
+ minLength: string;
60
+ uppercase: string;
61
+ lowercase: string;
62
+ number: string;
63
+ special: string;
64
+ noEmail: string;
65
+ noForbiddenWords: string;
66
+ };
67
+ placeholder: string;
68
+ label: string;
69
+ }
70
+
71
+ /**
72
+ * Charge une traduction de manière asynchrone (lazy loading)
73
+ * Retourne la traduction en cache si déjà chargée
74
+ */
75
+ declare function loadTranslation(locale: string): Promise<Translation>;
76
+ /**
77
+ * Obtient une traduction de manière synchrone (depuis le cache ou fallback)
78
+ * Utilisé pour le rendu initial avant que la traduction async soit chargée
79
+ */
80
+ declare function getTranslationSync(locale: string): Translation;
81
+ /**
82
+ * Précharge une traduction (utile pour optimiser le chargement)
83
+ */
84
+ declare function preloadTranslation(locale: string): void;
85
+
86
+ declare const defaultRules: PasswordRule[];
87
+ declare const optionalRules: PasswordRule[];
88
+ declare function evaluatePassword(password: string, options?: RuleOptions): {
89
+ passedRules: string[];
90
+ failedRules: string[];
91
+ score: number;
92
+ };
93
+
94
+ export { type Locale, type PasswordRule, PasswordStrength, type PasswordStrengthProps, type PasswordStrengthResult, type RuleOptions, type StrengthLevel, type Translation, PasswordStrength as default, defaultRules, evaluatePassword, getTranslationSync, levelToActiveBars, loadTranslation, optionalRules, preloadTranslation, usePasswordStrength };
@@ -0,0 +1,94 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type Locale = "en" | "fr" | "es" | "de" | "pt" | "it" | "nl" | "pl" | "sv" | "uk" | "zh" | "ja" | "ko";
4
+ type StrengthLevel = "veryWeak" | "weak" | "soso" | "good" | "strong";
5
+ interface PasswordRule {
6
+ id: string;
7
+ test: (password: string, options?: RuleOptions) => boolean;
8
+ }
9
+ interface RuleOptions {
10
+ email?: string;
11
+ forbiddenWords?: string[];
12
+ }
13
+ interface PasswordStrengthResult {
14
+ score: number;
15
+ level: StrengthLevel;
16
+ passedRules: string[];
17
+ failedRules: string[];
18
+ percentage: number;
19
+ }
20
+ interface PasswordStrengthProps {
21
+ /** Current password value */
22
+ value: string;
23
+ /** Language for labels and messages */
24
+ locale?: Locale;
25
+ /** Number of strength bars (3, 4, or 5) */
26
+ barsNumber?: 3 | 4 | 5;
27
+ /** Maximum number of rules to display (0 = no rules, just bar) */
28
+ maxRules?: number;
29
+ /** Email to check password doesn't contain it */
30
+ email?: string;
31
+ /** Additional words that should not be in the password */
32
+ forbiddenWords?: string[];
33
+ /** Additional class name for the container */
34
+ className?: string;
35
+ /** Additional class name for the strength bars */
36
+ barClassName?: string;
37
+ /** Visual bar mode variant */
38
+ barMode?: "default" | "rounded";
39
+ }
40
+
41
+ declare function PasswordStrength({ value, locale, barsNumber, maxRules, email, forbiddenWords, className, barClassName, barMode, }: PasswordStrengthProps): react_jsx_runtime.JSX.Element;
42
+
43
+ /**
44
+ * Maps a strength level to the number of active bars
45
+ */
46
+ declare function levelToActiveBars(level: StrengthLevel, totalBars: 3 | 4 | 5): number;
47
+ interface UsePasswordStrengthOptions {
48
+ barsNumber?: 3 | 4 | 5;
49
+ email?: string;
50
+ forbiddenWords?: string[];
51
+ }
52
+ declare function usePasswordStrength(password: string, options?: UsePasswordStrengthOptions): PasswordStrengthResult;
53
+
54
+ interface Translation {
55
+ levels: Record<StrengthLevel, string>;
56
+ passwordMustInclude: string;
57
+ passwordStrength: string;
58
+ rules: {
59
+ minLength: string;
60
+ uppercase: string;
61
+ lowercase: string;
62
+ number: string;
63
+ special: string;
64
+ noEmail: string;
65
+ noForbiddenWords: string;
66
+ };
67
+ placeholder: string;
68
+ label: string;
69
+ }
70
+
71
+ /**
72
+ * Charge une traduction de manière asynchrone (lazy loading)
73
+ * Retourne la traduction en cache si déjà chargée
74
+ */
75
+ declare function loadTranslation(locale: string): Promise<Translation>;
76
+ /**
77
+ * Obtient une traduction de manière synchrone (depuis le cache ou fallback)
78
+ * Utilisé pour le rendu initial avant que la traduction async soit chargée
79
+ */
80
+ declare function getTranslationSync(locale: string): Translation;
81
+ /**
82
+ * Précharge une traduction (utile pour optimiser le chargement)
83
+ */
84
+ declare function preloadTranslation(locale: string): void;
85
+
86
+ declare const defaultRules: PasswordRule[];
87
+ declare const optionalRules: PasswordRule[];
88
+ declare function evaluatePassword(password: string, options?: RuleOptions): {
89
+ passedRules: string[];
90
+ failedRules: string[];
91
+ score: number;
92
+ };
93
+
94
+ export { type Locale, type PasswordRule, PasswordStrength, type PasswordStrengthProps, type PasswordStrengthResult, type RuleOptions, type StrengthLevel, type Translation, PasswordStrength as default, defaultRules, evaluatePassword, getTranslationSync, levelToActiveBars, loadTranslation, optionalRules, preloadTranslation, usePasswordStrength };