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 +21 -0
- package/README.md +191 -0
- package/dist/index.d.mts +94 -0
- package/dist/index.d.ts +94 -0
- package/dist/index.js +852 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +839 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +95 -0
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
|
+
[](https://www.npmjs.com/package/shadcn-password-strength)
|
|
6
|
+
[](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
|
package/dist/index.d.mts
ADDED
|
@@ -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 };
|
package/dist/index.d.ts
ADDED
|
@@ -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 };
|