@alfadocs/ui-kit-debug 0.7.3 → 0.8.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/_chunks/use-password-requirements-DgEYdN4H.js +446 -0
- package/dist/_chunks/use-password-requirements-DgEYdN4H.js.map +1 -0
- package/dist/agent-catalog.json +1 -1
- package/dist/components/password-input/index.d.ts +3 -1
- package/dist/components/password-input/index.d.ts.map +1 -1
- package/dist/components/password-input/index.js +3 -2
- package/dist/components/password-input/password-input.d.ts +31 -0
- package/dist/components/password-input/password-input.d.ts.map +1 -1
- package/dist/components/password-input/use-password-requirements.d.ts +39 -0
- package/dist/components/password-input/use-password-requirements.d.ts.map +1 -0
- package/dist/i18n/config.js +32 -2
- package/dist/i18n/config.js.map +1 -1
- package/dist/i18n/resources.d.ts +30 -0
- package/dist/i18n/resources.d.ts.map +1 -1
- package/dist/index.js +389 -388
- package/dist/locales/de.json +10 -0
- package/dist/locales/en.json +10 -0
- package/dist/locales/it.json +10 -0
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/password-input-C4LmjIH1.js +0 -301
- package/dist/_chunks/password-input-C4LmjIH1.js.map +0 -1
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import { jsxs as g, jsx as a } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as ts, useRef as as, useState as C, useEffect as is, useCallback as u, useMemo as V } from "react";
|
|
3
|
+
import { c as L } from "./index-D2ZczOXr.js";
|
|
4
|
+
import { useTranslation as W } from "react-i18next";
|
|
5
|
+
import { T as rs } from "./text-input-DZwt9L8H.js";
|
|
6
|
+
import { u as ns } from "./form-field-context-B3APVHKx.js";
|
|
7
|
+
import { c as os } from "./compose-refs-C0k0tdqF.js";
|
|
8
|
+
import { u as ds } from "./registry-C9nwlNyL.js";
|
|
9
|
+
import { E as ls } from "./eye-off-xEXDAh5z.js";
|
|
10
|
+
import { c as cs } from "./createLucideIcon-CrFbzy84.js";
|
|
11
|
+
import { C as us } from "./check-DPdL_Sm7.js";
|
|
12
|
+
import { C as ps } from "./circle-BkqTgYmt.js";
|
|
13
|
+
import { T as ms } from "./triangle-alert-CBPUIzQo.js";
|
|
14
|
+
/**
|
|
15
|
+
* @license lucide-react v1.8.0 - ISC
|
|
16
|
+
*
|
|
17
|
+
* This source code is licensed under the ISC license.
|
|
18
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
19
|
+
*/
|
|
20
|
+
const fs = [
|
|
21
|
+
[
|
|
22
|
+
"path",
|
|
23
|
+
{
|
|
24
|
+
d: "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",
|
|
25
|
+
key: "1nclc0"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
|
|
29
|
+
], gs = cs("eye", fs), hs = {
|
|
30
|
+
id: "password-input",
|
|
31
|
+
capabilities: ["edit_inline"],
|
|
32
|
+
state: {
|
|
33
|
+
value: {
|
|
34
|
+
type: "string",
|
|
35
|
+
descriptionKey: "ui.agent.passwordInput.state.value",
|
|
36
|
+
description: "Current password value. Never log or persist this off-device.",
|
|
37
|
+
read: (e) => e.getValue()
|
|
38
|
+
},
|
|
39
|
+
isEmpty: {
|
|
40
|
+
type: "boolean",
|
|
41
|
+
descriptionKey: "ui.agent.passwordInput.state.isEmpty",
|
|
42
|
+
description: "Whether the input has no value.",
|
|
43
|
+
read: (e) => e.getValue() === ""
|
|
44
|
+
},
|
|
45
|
+
isRevealed: {
|
|
46
|
+
type: "boolean",
|
|
47
|
+
descriptionKey: "ui.agent.passwordInput.state.isRevealed",
|
|
48
|
+
description: "Whether the password is currently shown in plain text.",
|
|
49
|
+
read: (e) => e.isRevealed()
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
actions: {
|
|
53
|
+
set_value: {
|
|
54
|
+
safety: "write",
|
|
55
|
+
argsType: "{ value: string }",
|
|
56
|
+
descriptionKey: "ui.agent.passwordInput.actions.setValue",
|
|
57
|
+
description: "Replace the password value.",
|
|
58
|
+
invoke: (e, r) => {
|
|
59
|
+
e.setValue(r.value);
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
clear: {
|
|
63
|
+
safety: "destructive",
|
|
64
|
+
descriptionKey: "ui.agent.passwordInput.actions.clear",
|
|
65
|
+
description: "Empty the input. Loses any typed value.",
|
|
66
|
+
invoke: (e) => {
|
|
67
|
+
e.clear();
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
focus: {
|
|
71
|
+
safety: "read",
|
|
72
|
+
descriptionKey: "ui.agent.passwordInput.actions.focus",
|
|
73
|
+
description: "Move keyboard focus to the input.",
|
|
74
|
+
invoke: (e) => {
|
|
75
|
+
e.focus();
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
toggle_visibility: {
|
|
79
|
+
safety: "read",
|
|
80
|
+
descriptionKey: "ui.agent.passwordInput.actions.toggleVisibility",
|
|
81
|
+
description: "Toggle between masked and plain-text display.",
|
|
82
|
+
invoke: (e) => {
|
|
83
|
+
e.toggleVisibility();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
domHooks: {
|
|
88
|
+
root: {
|
|
89
|
+
attr: "data-component",
|
|
90
|
+
value: "password-input",
|
|
91
|
+
description: "Marks the PasswordInput wrapper."
|
|
92
|
+
},
|
|
93
|
+
instanceId: {
|
|
94
|
+
attr: "data-component-id",
|
|
95
|
+
sourceProp: "id",
|
|
96
|
+
description: "Sourced from the id prop."
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}, ws = {
|
|
100
|
+
sm: "ds:size-4",
|
|
101
|
+
md: "ds:size-[18px]",
|
|
102
|
+
lg: "ds:size-5"
|
|
103
|
+
}, bs = L(
|
|
104
|
+
[
|
|
105
|
+
"ds:absolute ds:inset-y-0 ds:end-0 ds:ps-2 ds:pe-3",
|
|
106
|
+
"ds:inline-flex ds:items-center ds:justify-center",
|
|
107
|
+
"ds:text-muted-foreground ds:hover:text-foreground",
|
|
108
|
+
"ds:bg-transparent ds:border-0 ds:cursor-pointer",
|
|
109
|
+
"ds:rounded-[var(--radius-sm)]",
|
|
110
|
+
"ds:min-w-[var(--min-target-size)]",
|
|
111
|
+
"ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none",
|
|
112
|
+
"ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid",
|
|
113
|
+
"ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]",
|
|
114
|
+
"ds:forced-colors:focus-visible:outline-[CanvasText]",
|
|
115
|
+
"ds:disabled:cursor-not-allowed ds:disabled:opacity-50"
|
|
116
|
+
].join(" ")
|
|
117
|
+
), vs = L(
|
|
118
|
+
"ds:h-1 ds:w-full ds:overflow-hidden ds:rounded-[var(--radius-full)] ds:bg-muted"
|
|
119
|
+
), ys = L(
|
|
120
|
+
[
|
|
121
|
+
"ds:h-full ds:rounded-[var(--radius-full)]",
|
|
122
|
+
"ds:transition-all ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none"
|
|
123
|
+
].join(" "),
|
|
124
|
+
{
|
|
125
|
+
variants: {
|
|
126
|
+
level: {
|
|
127
|
+
0: "ds:w-1/4 ds:bg-destructive",
|
|
128
|
+
1: "ds:w-1/2 ds:bg-warning",
|
|
129
|
+
2: "ds:w-3/4 ds:bg-success",
|
|
130
|
+
3: "ds:w-full ds:bg-success"
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
defaultVariants: { level: 0 }
|
|
134
|
+
}
|
|
135
|
+
), xs = {
|
|
136
|
+
0: "weak",
|
|
137
|
+
1: "fair",
|
|
138
|
+
2: "good",
|
|
139
|
+
3: "strong"
|
|
140
|
+
}, ks = L(
|
|
141
|
+
"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-meta",
|
|
142
|
+
{
|
|
143
|
+
variants: {
|
|
144
|
+
met: {
|
|
145
|
+
true: "ds:text-success",
|
|
146
|
+
false: "ds:text-muted-foreground"
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
defaultVariants: { met: !1 }
|
|
150
|
+
}
|
|
151
|
+
), Ns = ts(
|
|
152
|
+
({
|
|
153
|
+
onRevealChange: e,
|
|
154
|
+
showStrength: r = !1,
|
|
155
|
+
strength: n,
|
|
156
|
+
requirements: l,
|
|
157
|
+
deriveStrength: p = !1,
|
|
158
|
+
autoComplete: w,
|
|
159
|
+
size: h = "md",
|
|
160
|
+
disabled: d,
|
|
161
|
+
name: i,
|
|
162
|
+
id: I,
|
|
163
|
+
onKeyDown: b,
|
|
164
|
+
onKeyUp: v,
|
|
165
|
+
onBlur: y,
|
|
166
|
+
onInput: x,
|
|
167
|
+
defaultValue: T,
|
|
168
|
+
value: m,
|
|
169
|
+
className: $,
|
|
170
|
+
...B
|
|
171
|
+
}, G) => {
|
|
172
|
+
const { t: f } = W(), M = ns().disabled || d, k = as(null), J = os(G, k), [c, j] = C(!1), [Q, A] = C(!1), [_, H] = C(() => typeof m == "string" ? m : typeof T == "string" ? T : "");
|
|
173
|
+
is(() => {
|
|
174
|
+
typeof m == "string" && H(m);
|
|
175
|
+
}, [m]);
|
|
176
|
+
const X = u(
|
|
177
|
+
(s) => {
|
|
178
|
+
H(s.currentTarget.value), x == null || x(s);
|
|
179
|
+
},
|
|
180
|
+
[x]
|
|
181
|
+
), z = u((s) => {
|
|
182
|
+
var R;
|
|
183
|
+
const t = k.current;
|
|
184
|
+
if (!t) return;
|
|
185
|
+
const P = Object.getPrototypeOf(t), S = (R = Object.getOwnPropertyDescriptor(P, "value")) == null ? void 0 : R.set;
|
|
186
|
+
S == null || S.call(t, s), t.dispatchEvent(new Event("input", { bubbles: !0 })), t.dispatchEvent(new Event("change", { bubbles: !0 }));
|
|
187
|
+
}, []), Y = u(() => {
|
|
188
|
+
j((s) => {
|
|
189
|
+
const t = !s;
|
|
190
|
+
return e == null || e(t), t;
|
|
191
|
+
});
|
|
192
|
+
}, [e]), N = u((s) => {
|
|
193
|
+
typeof s.getModifierState == "function" && A(s.getModifierState("CapsLock"));
|
|
194
|
+
}, []), Z = u(
|
|
195
|
+
(s) => {
|
|
196
|
+
N(s), b == null || b(s);
|
|
197
|
+
},
|
|
198
|
+
[N, b]
|
|
199
|
+
), D = u(
|
|
200
|
+
(s) => {
|
|
201
|
+
N(s), v == null || v(s);
|
|
202
|
+
},
|
|
203
|
+
[N, v]
|
|
204
|
+
), q = u(
|
|
205
|
+
(s) => {
|
|
206
|
+
A(!1), y == null || y(s);
|
|
207
|
+
},
|
|
208
|
+
[y]
|
|
209
|
+
), U = V(
|
|
210
|
+
() => ({
|
|
211
|
+
getValue: () => {
|
|
212
|
+
var s;
|
|
213
|
+
return ((s = k.current) == null ? void 0 : s.value) ?? "";
|
|
214
|
+
},
|
|
215
|
+
setValue: (s) => z(s),
|
|
216
|
+
clear: () => z(""),
|
|
217
|
+
focus: () => {
|
|
218
|
+
var s;
|
|
219
|
+
return (s = k.current) == null ? void 0 : s.focus();
|
|
220
|
+
},
|
|
221
|
+
isRevealed: () => c,
|
|
222
|
+
toggleVisibility: () => {
|
|
223
|
+
j((s) => {
|
|
224
|
+
const t = !s;
|
|
225
|
+
return e == null || e(t), t;
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}),
|
|
229
|
+
[e, c, z]
|
|
230
|
+
);
|
|
231
|
+
ds(hs, U, I);
|
|
232
|
+
const F = ws[h], ss = f(
|
|
233
|
+
c ? "ui.inputs.password.toggleHide" : "ui.inputs.password.toggleShow",
|
|
234
|
+
c ? "Hide password" : "Show password"
|
|
235
|
+
), o = V(
|
|
236
|
+
() => (l == null ? void 0 : l.map((s) => ({
|
|
237
|
+
...s,
|
|
238
|
+
met: s.test(_)
|
|
239
|
+
}))) ?? null,
|
|
240
|
+
[l, _]
|
|
241
|
+
), es = V(() => {
|
|
242
|
+
if (!p || !(o != null && o.length)) return 0;
|
|
243
|
+
const s = o.filter((P) => P.met).length, t = o.length;
|
|
244
|
+
return Math.min(3, Math.floor(s / t * 4));
|
|
245
|
+
}, [p, o]), E = n !== void 0 ? n : p ? es : 0, O = xs[E], K = f(
|
|
246
|
+
`ui.inputs.password.strength.${O}`,
|
|
247
|
+
O.charAt(0).toUpperCase() + O.slice(1)
|
|
248
|
+
);
|
|
249
|
+
return /* @__PURE__ */ g(
|
|
250
|
+
"div",
|
|
251
|
+
{
|
|
252
|
+
"data-component": "password-input",
|
|
253
|
+
"data-component-id": I,
|
|
254
|
+
className: "ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]",
|
|
255
|
+
children: [
|
|
256
|
+
/* @__PURE__ */ g("div", { className: "ds:relative", children: [
|
|
257
|
+
/* @__PURE__ */ a(
|
|
258
|
+
rs,
|
|
259
|
+
{
|
|
260
|
+
ref: J,
|
|
261
|
+
id: I,
|
|
262
|
+
type: c ? "text" : "password",
|
|
263
|
+
autoComplete: w ?? "current-password",
|
|
264
|
+
name: i ?? "password",
|
|
265
|
+
spellCheck: !1,
|
|
266
|
+
autoCapitalize: "none",
|
|
267
|
+
autoCorrect: "off",
|
|
268
|
+
size: h,
|
|
269
|
+
disabled: M,
|
|
270
|
+
onKeyDown: Z,
|
|
271
|
+
onKeyUp: D,
|
|
272
|
+
onBlur: q,
|
|
273
|
+
onInput: X,
|
|
274
|
+
value: m,
|
|
275
|
+
defaultValue: T,
|
|
276
|
+
endAdornment: /* @__PURE__ */ a("span", { "aria-hidden": "true", className: "ds:block ds:size-4" }),
|
|
277
|
+
className: $,
|
|
278
|
+
...B
|
|
279
|
+
}
|
|
280
|
+
),
|
|
281
|
+
/* @__PURE__ */ a(
|
|
282
|
+
"button",
|
|
283
|
+
{
|
|
284
|
+
type: "button",
|
|
285
|
+
"aria-pressed": c,
|
|
286
|
+
"aria-label": ss,
|
|
287
|
+
disabled: M,
|
|
288
|
+
onClick: Y,
|
|
289
|
+
className: bs(),
|
|
290
|
+
children: c ? /* @__PURE__ */ a(ls, { "aria-hidden": "true", className: F }) : /* @__PURE__ */ a(gs, { "aria-hidden": "true", className: F })
|
|
291
|
+
}
|
|
292
|
+
)
|
|
293
|
+
] }),
|
|
294
|
+
o && o.length > 0 ? (
|
|
295
|
+
// `role="list"` / `role="listitem"` are set explicitly even
|
|
296
|
+
// though they're the implicit roles on <ul>/<li> — Safari
|
|
297
|
+
// VoiceOver strips the implicit list role when CSS sets
|
|
298
|
+
// `list-style: none` (which `ds:list-none` does), so the
|
|
299
|
+
// redundancy is load-bearing for AT, not a lint nit.
|
|
300
|
+
//
|
|
301
|
+
// aria-live="polite" announces transitions as the per-row
|
|
302
|
+
// `.ds:sr-only` state suffix flips between "met" / "not yet
|
|
303
|
+
// met". aria-live observes text-content mutations, not
|
|
304
|
+
// attribute or class changes, so the data-state attribute
|
|
305
|
+
// alone wouldn't trigger an announcement — the sr-only span
|
|
306
|
+
// is the load-bearing piece for AT users.
|
|
307
|
+
// eslint-disable-next-line jsx-a11y/no-redundant-roles
|
|
308
|
+
/* @__PURE__ */ a(
|
|
309
|
+
"ul",
|
|
310
|
+
{
|
|
311
|
+
role: "list",
|
|
312
|
+
"aria-live": "polite",
|
|
313
|
+
"data-component": "password-requirements",
|
|
314
|
+
className: "ds:list-none ds:m-0 ds:p-0 ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]",
|
|
315
|
+
children: o.map((s) => (
|
|
316
|
+
// eslint-disable-next-line jsx-a11y/no-redundant-roles
|
|
317
|
+
/* @__PURE__ */ g(
|
|
318
|
+
"li",
|
|
319
|
+
{
|
|
320
|
+
role: "listitem",
|
|
321
|
+
"data-state": s.met ? "met" : "unmet",
|
|
322
|
+
className: ks({ met: s.met }),
|
|
323
|
+
children: [
|
|
324
|
+
s.met ? /* @__PURE__ */ a(
|
|
325
|
+
us,
|
|
326
|
+
{
|
|
327
|
+
"aria-hidden": "true",
|
|
328
|
+
className: "ds:size-3.5 ds:text-success ds:shrink-0"
|
|
329
|
+
}
|
|
330
|
+
) : /* @__PURE__ */ a(
|
|
331
|
+
ps,
|
|
332
|
+
{
|
|
333
|
+
"aria-hidden": "true",
|
|
334
|
+
className: "ds:size-3.5 ds:shrink-0"
|
|
335
|
+
}
|
|
336
|
+
),
|
|
337
|
+
/* @__PURE__ */ a("span", { children: s.label }),
|
|
338
|
+
/* @__PURE__ */ g("span", { className: "ds:sr-only", children: [
|
|
339
|
+
" — ",
|
|
340
|
+
s.met ? f("ui.inputs.password.requirements.met", "met") : f(
|
|
341
|
+
"ui.inputs.password.requirements.unmet",
|
|
342
|
+
"not yet met"
|
|
343
|
+
)
|
|
344
|
+
] })
|
|
345
|
+
]
|
|
346
|
+
},
|
|
347
|
+
s.id
|
|
348
|
+
)
|
|
349
|
+
))
|
|
350
|
+
}
|
|
351
|
+
)
|
|
352
|
+
) : null,
|
|
353
|
+
Q ? /* @__PURE__ */ g(
|
|
354
|
+
"span",
|
|
355
|
+
{
|
|
356
|
+
role: "status",
|
|
357
|
+
"aria-live": "polite",
|
|
358
|
+
className: "ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-meta ds:text-warning",
|
|
359
|
+
children: [
|
|
360
|
+
/* @__PURE__ */ a(ms, { "aria-hidden": "true", className: "ds:size-3.5" }),
|
|
361
|
+
f("ui.inputs.password.capsLock", "Caps Lock is on")
|
|
362
|
+
]
|
|
363
|
+
}
|
|
364
|
+
) : null,
|
|
365
|
+
r ? /* @__PURE__ */ g("div", { className: "ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]", children: [
|
|
366
|
+
/* @__PURE__ */ a(
|
|
367
|
+
"div",
|
|
368
|
+
{
|
|
369
|
+
role: "progressbar",
|
|
370
|
+
"aria-valuenow": E,
|
|
371
|
+
"aria-valuemin": 0,
|
|
372
|
+
"aria-valuemax": 3,
|
|
373
|
+
"aria-label": f(
|
|
374
|
+
"ui.inputs.password.strengthLabel",
|
|
375
|
+
"Password strength"
|
|
376
|
+
),
|
|
377
|
+
"aria-valuetext": K,
|
|
378
|
+
className: vs(),
|
|
379
|
+
children: /* @__PURE__ */ a(
|
|
380
|
+
"div",
|
|
381
|
+
{
|
|
382
|
+
className: ys({ level: E })
|
|
383
|
+
}
|
|
384
|
+
)
|
|
385
|
+
}
|
|
386
|
+
),
|
|
387
|
+
/* @__PURE__ */ a(
|
|
388
|
+
"span",
|
|
389
|
+
{
|
|
390
|
+
"aria-hidden": "true",
|
|
391
|
+
className: "type-meta ds:text-muted-foreground",
|
|
392
|
+
children: K
|
|
393
|
+
}
|
|
394
|
+
)
|
|
395
|
+
] }) : null
|
|
396
|
+
]
|
|
397
|
+
}
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
);
|
|
401
|
+
Ns.displayName = "PasswordInput";
|
|
402
|
+
function Hs(e = {}) {
|
|
403
|
+
const { t: r } = W(), { minLength: n, uppercase: l, lowercase: p, digit: w, symbol: h } = e;
|
|
404
|
+
return V(() => {
|
|
405
|
+
const d = [];
|
|
406
|
+
return typeof n == "number" && n > 0 && d.push({
|
|
407
|
+
id: "length",
|
|
408
|
+
label: r("ui.inputs.password.requirements.length", {
|
|
409
|
+
count: n,
|
|
410
|
+
defaultValue: `At least ${n} characters`
|
|
411
|
+
}),
|
|
412
|
+
test: (i) => i.length >= n
|
|
413
|
+
}), l && d.push({
|
|
414
|
+
id: "uppercase",
|
|
415
|
+
label: r(
|
|
416
|
+
"ui.inputs.password.requirements.uppercase",
|
|
417
|
+
"One uppercase letter"
|
|
418
|
+
),
|
|
419
|
+
test: (i) => new RegExp("\\p{Lu}", "u").test(i)
|
|
420
|
+
}), p && d.push({
|
|
421
|
+
id: "lowercase",
|
|
422
|
+
label: r(
|
|
423
|
+
"ui.inputs.password.requirements.lowercase",
|
|
424
|
+
"One lowercase letter"
|
|
425
|
+
),
|
|
426
|
+
test: (i) => new RegExp("\\p{Ll}", "u").test(i)
|
|
427
|
+
}), w && d.push({
|
|
428
|
+
id: "digit",
|
|
429
|
+
label: r("ui.inputs.password.requirements.digit", "One number"),
|
|
430
|
+
test: (i) => new RegExp("\\p{Nd}", "u").test(i)
|
|
431
|
+
}), h && d.push({
|
|
432
|
+
id: "symbol",
|
|
433
|
+
label: r("ui.inputs.password.requirements.symbol", "One symbol"),
|
|
434
|
+
// Anything that isn't a letter, number, or whitespace counts.
|
|
435
|
+
// `\p{L}` + `\p{N}` keep this Unicode-aware so non-Latin
|
|
436
|
+
// alphabets (Arabic, Chinese, …) aren't mis-classified as
|
|
437
|
+
// symbols.
|
|
438
|
+
test: (i) => /[^\p{L}\p{N}\s]/u.test(i)
|
|
439
|
+
}), d;
|
|
440
|
+
}, [r, n, l, p, w, h]);
|
|
441
|
+
}
|
|
442
|
+
export {
|
|
443
|
+
Ns as P,
|
|
444
|
+
Hs as u
|
|
445
|
+
};
|
|
446
|
+
//# sourceMappingURL=use-password-requirements-DgEYdN4H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-password-requirements-DgEYdN4H.js","sources":["../../node_modules/lucide-react/dist/esm/icons/eye.js","../../src/components/password-input/password-input.agent.ts","../../src/components/password-input/password-input.tsx","../../src/components/password-input/use-password-requirements.ts"],"sourcesContent":["/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\",\n key: \"1nclc0\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n];\nconst Eye = createLucideIcon(\"eye\", __iconNode);\n\nexport { __iconNode, Eye as default };\n//# sourceMappingURL=eye.js.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — PasswordInput. */\n/* */\n/* See `src/docs/26-agent-readiness.mdx` for the contract. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { PasswordInputHandle } from './password-input';\n\nexport const passwordInputAgent: AgentAdapter<PasswordInputHandle> = {\n id: 'password-input',\n capabilities: ['edit_inline'],\n state: {\n value: {\n type: 'string',\n descriptionKey: 'ui.agent.passwordInput.state.value',\n description:\n 'Current password value. Never log or persist this off-device.',\n read: (handle) => handle.getValue(),\n },\n isEmpty: {\n type: 'boolean',\n descriptionKey: 'ui.agent.passwordInput.state.isEmpty',\n description: 'Whether the input has no value.',\n read: (handle) => handle.getValue() === '',\n },\n isRevealed: {\n type: 'boolean',\n descriptionKey: 'ui.agent.passwordInput.state.isRevealed',\n description: 'Whether the password is currently shown in plain text.',\n read: (handle) => handle.isRevealed(),\n },\n },\n actions: {\n set_value: {\n safety: 'write',\n argsType: '{ value: string }',\n descriptionKey: 'ui.agent.passwordInput.actions.setValue',\n description: 'Replace the password value.',\n invoke: (handle, args: { value: string }) => {\n handle.setValue(args.value);\n },\n },\n clear: {\n safety: 'destructive',\n descriptionKey: 'ui.agent.passwordInput.actions.clear',\n description: 'Empty the input. Loses any typed value.',\n invoke: (handle) => {\n handle.clear();\n },\n },\n focus: {\n safety: 'read',\n descriptionKey: 'ui.agent.passwordInput.actions.focus',\n description: 'Move keyboard focus to the input.',\n invoke: (handle) => {\n handle.focus();\n },\n },\n toggle_visibility: {\n safety: 'read',\n descriptionKey: 'ui.agent.passwordInput.actions.toggleVisibility',\n description: 'Toggle between masked and plain-text display.',\n invoke: (handle) => {\n handle.toggleVisibility();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'password-input',\n description: 'Marks the PasswordInput wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type FocusEvent,\n type FormEvent,\n type KeyboardEvent,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { AlertTriangle, Check, Circle, Eye, EyeOff } from 'lucide-react';\nimport { TextInput, type TextInputProps } from '../text-input';\nimport { useFormField } from '../form-field/form-field-context';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { useAgentRegistration } from '../../agent';\nimport { passwordInputAgent } from './password-input.agent';\n\n/** Agent-readiness curated handle for PasswordInput. */\nexport interface PasswordInputHandle {\n getValue: () => string;\n setValue: (value: string) => void;\n clear: () => void;\n focus: () => void;\n isRevealed: () => boolean;\n toggleVisibility: () => void;\n}\n\ntype Strength = 0 | 1 | 2 | 3;\n\ntype SizeKey = NonNullable<TextInputProps['size']>;\n\nconst iconSizeClassBySize: Record<SizeKey, string> = {\n sm: 'ds:size-4',\n md: 'ds:size-[18px]',\n lg: 'ds:size-5',\n};\n\nconst toggleVariants = cva(\n [\n 'ds:absolute ds:inset-y-0 ds:end-0 ds:ps-2 ds:pe-3',\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:text-muted-foreground ds:hover:text-foreground',\n 'ds:bg-transparent ds:border-0 ds:cursor-pointer',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:min-w-[var(--min-target-size)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:disabled:cursor-not-allowed ds:disabled:opacity-50',\n ].join(' '),\n);\n\nconst strengthTrackVariants = cva(\n 'ds:h-1 ds:w-full ds:overflow-hidden ds:rounded-[var(--radius-full)] ds:bg-muted',\n);\n\nconst strengthBarVariants = cva(\n [\n 'ds:h-full ds:rounded-[var(--radius-full)]',\n 'ds:transition-all ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n level: {\n 0: 'ds:w-1/4 ds:bg-destructive',\n 1: 'ds:w-1/2 ds:bg-warning',\n 2: 'ds:w-3/4 ds:bg-success',\n 3: 'ds:w-full ds:bg-success',\n },\n },\n defaultVariants: { level: 0 },\n },\n);\n\nconst strengthLabelByLevel: Record<\n Strength,\n 'weak' | 'fair' | 'good' | 'strong'\n> = {\n 0: 'weak',\n 1: 'fair',\n 2: 'good',\n 3: 'strong',\n};\n\nconst requirementRowVariants = cva(\n 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-meta',\n {\n variants: {\n met: {\n true: 'ds:text-success',\n false: 'ds:text-muted-foreground',\n },\n },\n defaultVariants: { met: false },\n },\n);\n\n/**\n * One row in the live requirements checklist. Consumers either build\n * these inline or pull a pre-built set from `usePasswordRequirements`.\n */\nexport interface PasswordRequirement {\n /** Stable id — keyed render + a11y. */\n id: string;\n /** Already-translated label. The consumer owns the wording. */\n label: string;\n /** Predicate against the current value. Pure, runs on every keystroke. */\n test: (value: string) => boolean;\n}\n\nexport interface PasswordInputProps\n extends\n Omit<TextInputProps, 'type' | 'endAdornment' | 'startAdornment'>,\n VariantProps<typeof strengthBarVariants> {\n /** Callback when reveal state changes (for analytics). */\n onRevealChange?: (revealed: boolean) => void;\n /** Show the strength meter below the input. */\n showStrength?: boolean;\n /** Strength score: 0 = weak, 1 = fair, 2 = good, 3 = strong. */\n strength?: Strength;\n /**\n * Live requirements checklist rendered between the input and the\n * strength meter / caps-lock notice. Each row's predicate runs on\n * every keystroke and the row's `data-state` flips between `\"met\"`\n * and `\"unmet\"`. Backed by `aria-live=\"polite\"` so screen readers\n * announce each transition as a visually-hidden suffix span flips\n * between localised \"met\" / \"not yet met\" copy.\n *\n * Tip: hoist or `useMemo` the array — inlining it in JSX makes the\n * predicate-results memo bust every render. The kit's\n * `usePasswordRequirements` helper already does this.\n */\n requirements?: ReadonlyArray<PasswordRequirement>;\n /**\n * When `true` AND `strength` is not provided, derive a 0–3 score\n * from the proportion of `requirements` satisfied. Lets consumers\n * get the strength bar \"for free\" once they declare requirements.\n */\n deriveStrength?: boolean;\n /**\n * Autocomplete hint. Defaults to 'current-password'.\n * Use 'new-password' for registration/change-password forms.\n */\n autoComplete?: 'current-password' | 'new-password' | (string & {});\n}\n\nexport const PasswordInput = forwardRef<HTMLInputElement, PasswordInputProps>(\n (\n {\n onRevealChange,\n showStrength = false,\n strength,\n requirements,\n deriveStrength = false,\n autoComplete,\n size = 'md',\n disabled,\n name,\n id,\n onKeyDown,\n onKeyUp,\n onBlur,\n onInput,\n defaultValue,\n value,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const ctx = useFormField();\n const effectiveDisabled = ctx.disabled || disabled;\n\n const innerInputRef = useRef<HTMLInputElement | null>(null);\n const composedRef = composeRefs(ref, innerInputRef);\n\n const [revealed, setRevealed] = useState(false);\n const [capsLock, setCapsLock] = useState(false);\n\n // Track the current value internally so the requirements checklist\n // can re-evaluate predicates without forcing consumers to lift the\n // input into a controlled state. The seed is whichever of\n // `value` / `defaultValue` was passed; the `input` listener then\n // keeps it in sync on every keystroke (covers both controlled and\n // uncontrolled callers — for controlled callers we resync to the\n // incoming `value` prop in the effect below).\n const [internalValue, setInternalValue] = useState<string>(() => {\n if (typeof value === 'string') return value;\n if (typeof defaultValue === 'string') return defaultValue;\n return '';\n });\n\n useEffect(() => {\n if (typeof value === 'string') setInternalValue(value);\n }, [value]);\n\n const handleInput = useCallback(\n (event: FormEvent<HTMLInputElement>) => {\n setInternalValue(event.currentTarget.value);\n onInput?.(event);\n },\n [onInput],\n );\n\n const writeValueToInput = useCallback((next: string) => {\n const node = innerInputRef.current;\n if (!node) return;\n const prototype = Object.getPrototypeOf(node) as HTMLInputElement;\n const setter = Object.getOwnPropertyDescriptor(prototype, 'value')?.set;\n setter?.call(node, next);\n node.dispatchEvent(new Event('input', { bubbles: true }));\n node.dispatchEvent(new Event('change', { bubbles: true }));\n }, []);\n\n const handleToggle = useCallback(() => {\n setRevealed((prev) => {\n const next = !prev;\n onRevealChange?.(next);\n return next;\n });\n }, [onRevealChange]);\n\n const detectCaps = useCallback((event: KeyboardEvent<HTMLInputElement>) => {\n if (typeof event.getModifierState === 'function') {\n setCapsLock(event.getModifierState('CapsLock'));\n }\n }, []);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLInputElement>) => {\n detectCaps(event);\n onKeyDown?.(event);\n },\n [detectCaps, onKeyDown],\n );\n\n const handleKeyUp = useCallback(\n (event: KeyboardEvent<HTMLInputElement>) => {\n detectCaps(event);\n onKeyUp?.(event);\n },\n [detectCaps, onKeyUp],\n );\n\n const handleBlur = useCallback(\n (event: FocusEvent<HTMLInputElement>) => {\n setCapsLock(false);\n onBlur?.(event);\n },\n [onBlur],\n );\n\n const agentHandle = useMemo<PasswordInputHandle>(\n () => ({\n getValue: () => innerInputRef.current?.value ?? '',\n setValue: (next) => writeValueToInput(next),\n clear: () => writeValueToInput(''),\n focus: () => innerInputRef.current?.focus(),\n isRevealed: () => revealed,\n toggleVisibility: () => {\n setRevealed((prev) => {\n const next = !prev;\n onRevealChange?.(next);\n return next;\n });\n },\n }),\n [onRevealChange, revealed, writeValueToInput],\n );\n useAgentRegistration(passwordInputAgent, agentHandle, id);\n\n const iconSizeClass = iconSizeClassBySize[size];\n const toggleLabel = t(\n revealed\n ? 'ui.inputs.password.toggleHide'\n : 'ui.inputs.password.toggleShow',\n revealed ? 'Hide password' : 'Show password',\n );\n\n // Evaluate each requirement against the current value. Cheap by\n // construction — predicates are pure regex/length checks supplied\n // by the consumer; the kit doesn't memoise per-row because the\n // map is O(n) over a handful of rules and React would re-render\n // the row anyway when its `data-state` flips.\n const requirementResults = useMemo(\n () =>\n requirements?.map((req) => ({\n ...req,\n met: req.test(internalValue),\n })) ?? null,\n [requirements, internalValue],\n );\n\n // Derive a 0–3 score from the satisfied proportion when the\n // consumer hasn't supplied an explicit `strength`. Formula:\n // `floor((satisfied / total) * 4)`, clamped to 3 so a fully-met\n // checklist matches the explicit \"strong\" level. With zero\n // requirements we fall back to 0 — meaningless on its own but\n // never displayed since `showStrength` is what controls the bar.\n const derivedStrength: Strength = useMemo(() => {\n if (!deriveStrength || !requirementResults?.length) return 0;\n const satisfied = requirementResults.filter((r) => r.met).length;\n const total = requirementResults.length;\n return Math.min(3, Math.floor((satisfied / total) * 4)) as Strength;\n }, [deriveStrength, requirementResults]);\n\n const effectiveStrength: Strength =\n strength !== undefined ? strength : deriveStrength ? derivedStrength : 0;\n const strengthKey = strengthLabelByLevel[effectiveStrength];\n const strengthText = t(\n `ui.inputs.password.strength.${strengthKey}`,\n strengthKey.charAt(0).toUpperCase() + strengthKey.slice(1),\n );\n\n return (\n <div\n data-component=\"password-input\"\n data-component-id={id}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n <div className=\"ds:relative\">\n <TextInput\n ref={composedRef}\n id={id}\n type={revealed ? 'text' : 'password'}\n autoComplete={autoComplete ?? 'current-password'}\n name={name ?? 'password'}\n spellCheck={false}\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n size={size}\n disabled={effectiveDisabled}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n onBlur={handleBlur}\n onInput={handleInput}\n value={value}\n defaultValue={defaultValue}\n endAdornment={\n <span aria-hidden=\"true\" className=\"ds:block ds:size-4\" />\n }\n className={className}\n {...rest}\n />\n <button\n type=\"button\"\n aria-pressed={revealed}\n aria-label={toggleLabel}\n disabled={effectiveDisabled}\n onClick={handleToggle}\n className={toggleVariants()}\n >\n {revealed ? (\n <EyeOff aria-hidden=\"true\" className={iconSizeClass} />\n ) : (\n <Eye aria-hidden=\"true\" className={iconSizeClass} />\n )}\n </button>\n </div>\n\n {requirementResults && requirementResults.length > 0 ? (\n // `role=\"list\"` / `role=\"listitem\"` are set explicitly even\n // though they're the implicit roles on <ul>/<li> — Safari\n // VoiceOver strips the implicit list role when CSS sets\n // `list-style: none` (which `ds:list-none` does), so the\n // redundancy is load-bearing for AT, not a lint nit.\n //\n // aria-live=\"polite\" announces transitions as the per-row\n // `.ds:sr-only` state suffix flips between \"met\" / \"not yet\n // met\". aria-live observes text-content mutations, not\n // attribute or class changes, so the data-state attribute\n // alone wouldn't trigger an announcement — the sr-only span\n // is the load-bearing piece for AT users.\n // eslint-disable-next-line jsx-a11y/no-redundant-roles\n <ul\n role=\"list\"\n aria-live=\"polite\"\n data-component=\"password-requirements\"\n className=\"ds:list-none ds:m-0 ds:p-0 ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\"\n >\n {requirementResults.map((req) => (\n // eslint-disable-next-line jsx-a11y/no-redundant-roles\n <li\n key={req.id}\n role=\"listitem\"\n data-state={req.met ? 'met' : 'unmet'}\n className={requirementRowVariants({ met: req.met })}\n >\n {req.met ? (\n <Check\n aria-hidden=\"true\"\n className=\"ds:size-3.5 ds:text-success ds:shrink-0\"\n />\n ) : (\n <Circle\n aria-hidden=\"true\"\n className=\"ds:size-3.5 ds:shrink-0\"\n />\n )}\n <span>{req.label}</span>\n <span className=\"ds:sr-only\">\n {' — '}\n {req.met\n ? t('ui.inputs.password.requirements.met', 'met')\n : t(\n 'ui.inputs.password.requirements.unmet',\n 'not yet met',\n )}\n </span>\n </li>\n ))}\n </ul>\n ) : null}\n\n {capsLock ? (\n <span\n role=\"status\"\n aria-live=\"polite\"\n className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-meta ds:text-warning\"\n >\n <AlertTriangle aria-hidden=\"true\" className=\"ds:size-3.5\" />\n {t('ui.inputs.password.capsLock', 'Caps Lock is on')}\n </span>\n ) : null}\n\n {showStrength ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <div\n role=\"progressbar\"\n aria-valuenow={effectiveStrength}\n aria-valuemin={0}\n aria-valuemax={3}\n aria-label={t(\n 'ui.inputs.password.strengthLabel',\n 'Password strength',\n )}\n aria-valuetext={strengthText}\n className={strengthTrackVariants()}\n >\n <div\n className={strengthBarVariants({ level: effectiveStrength })}\n />\n </div>\n <span\n aria-hidden=\"true\"\n className=\"type-meta ds:text-muted-foreground\"\n >\n {strengthText}\n </span>\n </div>\n ) : null}\n </div>\n );\n },\n);\n\nPasswordInput.displayName = 'PasswordInput';\n","import { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport type { PasswordRequirement } from './password-input';\n\nexport interface UsePasswordRequirementsOptions {\n /**\n * Minimum password length. When set, adds a \"length\" requirement.\n * Pass `12` (or whatever the server-side regex enforces) so the\n * inline checklist tells users the same rule they'll bounce off\n * server-side. When omitted, no length row is rendered.\n */\n minLength?: number;\n /** Adds an \"uppercase letter\" requirement when true. */\n uppercase?: boolean;\n /** Adds a \"lowercase letter\" requirement when true. */\n lowercase?: boolean;\n /** Adds a \"digit\" requirement when true. */\n digit?: boolean;\n /** Adds a \"symbol\" requirement when true. Matches anything outside `[A-Za-z0-9\\s]`. */\n symbol?: boolean;\n}\n\n/**\n * Builds the common set of password requirements with i18n-resolved\n * labels. Designed for the AlfaDocs platform's patient-registration\n * server-side regex (`/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{12,}$/`) but\n * generic enough for any consumer.\n *\n * Each opt-in flag adds one row to the returned array, in a stable\n * visual order (length → uppercase → lowercase → digit → symbol).\n * Predicates are pure and run on every keystroke.\n *\n * @example\n * const requirements = usePasswordRequirements({\n * minLength: 12,\n * uppercase: true,\n * lowercase: true,\n * digit: true,\n * });\n * <PasswordInput requirements={requirements} deriveStrength />\n */\nexport function usePasswordRequirements(\n opts: UsePasswordRequirementsOptions = {},\n): PasswordRequirement[] {\n const { t } = useTranslation();\n const { minLength, uppercase, lowercase, digit, symbol } = opts;\n\n return useMemo(() => {\n const list: PasswordRequirement[] = [];\n\n if (typeof minLength === 'number' && minLength > 0) {\n list.push({\n id: 'length',\n label: t('ui.inputs.password.requirements.length', {\n count: minLength,\n defaultValue: `At least ${minLength} characters`,\n }),\n test: (v) => v.length >= minLength,\n });\n }\n\n if (uppercase) {\n list.push({\n id: 'uppercase',\n label: t(\n 'ui.inputs.password.requirements.uppercase',\n 'One uppercase letter',\n ),\n test: (v) => /\\p{Lu}/u.test(v),\n });\n }\n\n if (lowercase) {\n list.push({\n id: 'lowercase',\n label: t(\n 'ui.inputs.password.requirements.lowercase',\n 'One lowercase letter',\n ),\n test: (v) => /\\p{Ll}/u.test(v),\n });\n }\n\n if (digit) {\n list.push({\n id: 'digit',\n label: t('ui.inputs.password.requirements.digit', 'One number'),\n test: (v) => /\\p{Nd}/u.test(v),\n });\n }\n\n if (symbol) {\n list.push({\n id: 'symbol',\n label: t('ui.inputs.password.requirements.symbol', 'One symbol'),\n // Anything that isn't a letter, number, or whitespace counts.\n // `\\p{L}` + `\\p{N}` keep this Unicode-aware so non-Latin\n // alphabets (Arabic, Chinese, …) aren't mis-classified as\n // symbols.\n test: (v) => /[^\\p{L}\\p{N}\\s]/u.test(v),\n });\n }\n\n return list;\n }, [t, minLength, uppercase, lowercase, digit, symbol]);\n}\n"],"names":["__iconNode","Eye","createLucideIcon","passwordInputAgent","handle","args","iconSizeClassBySize","toggleVariants","cva","strengthTrackVariants","strengthBarVariants","strengthLabelByLevel","requirementRowVariants","PasswordInput","forwardRef","onRevealChange","showStrength","strength","requirements","deriveStrength","autoComplete","size","disabled","name","id","onKeyDown","onKeyUp","onBlur","onInput","defaultValue","value","className","rest","ref","t","useTranslation","effectiveDisabled","useFormField","innerInputRef","useRef","composedRef","composeRefs","revealed","setRevealed","useState","capsLock","setCapsLock","internalValue","setInternalValue","useEffect","handleInput","useCallback","event","writeValueToInput","next","node","prototype","setter","_a","handleToggle","prev","detectCaps","handleKeyDown","handleKeyUp","handleBlur","agentHandle","useMemo","useAgentRegistration","iconSizeClass","toggleLabel","requirementResults","req","derivedStrength","satisfied","r","total","effectiveStrength","strengthKey","strengthText","jsxs","jsx","TextInput","EyeOff","Check","Circle","AlertTriangle","usePasswordRequirements","opts","minLength","uppercase","lowercase","digit","symbol","list","v"],"mappings":"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","x_google_ignoreList":[0]}
|
package/dist/agent-catalog.json
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { PasswordInput } from './password-input';
|
|
2
|
-
export type { PasswordInputProps } from './password-input';
|
|
2
|
+
export type { PasswordInputProps, PasswordRequirement } from './password-input';
|
|
3
|
+
export { usePasswordRequirements } from './use-password-requirements';
|
|
4
|
+
export type { UsePasswordRequirementsOptions } from './use-password-requirements';
|
|
3
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/password-input/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/password-input/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,YAAY,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { P as
|
|
1
|
+
import { P as r, u as a } from "../../_chunks/use-password-requirements-DgEYdN4H.js";
|
|
2
2
|
export {
|
|
3
|
-
|
|
3
|
+
r as PasswordInput,
|
|
4
|
+
a as usePasswordRequirements
|
|
4
5
|
};
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -13,6 +13,18 @@ type Strength = 0 | 1 | 2 | 3;
|
|
|
13
13
|
declare const strengthBarVariants: (props?: ({
|
|
14
14
|
level?: 0 | 2 | 1 | 3 | null | undefined;
|
|
15
15
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
16
|
+
/**
|
|
17
|
+
* One row in the live requirements checklist. Consumers either build
|
|
18
|
+
* these inline or pull a pre-built set from `usePasswordRequirements`.
|
|
19
|
+
*/
|
|
20
|
+
export interface PasswordRequirement {
|
|
21
|
+
/** Stable id — keyed render + a11y. */
|
|
22
|
+
id: string;
|
|
23
|
+
/** Already-translated label. The consumer owns the wording. */
|
|
24
|
+
label: string;
|
|
25
|
+
/** Predicate against the current value. Pure, runs on every keystroke. */
|
|
26
|
+
test: (value: string) => boolean;
|
|
27
|
+
}
|
|
16
28
|
export interface PasswordInputProps extends Omit<TextInputProps, 'type' | 'endAdornment' | 'startAdornment'>, VariantProps<typeof strengthBarVariants> {
|
|
17
29
|
/** Callback when reveal state changes (for analytics). */
|
|
18
30
|
onRevealChange?: (revealed: boolean) => void;
|
|
@@ -20,6 +32,25 @@ export interface PasswordInputProps extends Omit<TextInputProps, 'type' | 'endAd
|
|
|
20
32
|
showStrength?: boolean;
|
|
21
33
|
/** Strength score: 0 = weak, 1 = fair, 2 = good, 3 = strong. */
|
|
22
34
|
strength?: Strength;
|
|
35
|
+
/**
|
|
36
|
+
* Live requirements checklist rendered between the input and the
|
|
37
|
+
* strength meter / caps-lock notice. Each row's predicate runs on
|
|
38
|
+
* every keystroke and the row's `data-state` flips between `"met"`
|
|
39
|
+
* and `"unmet"`. Backed by `aria-live="polite"` so screen readers
|
|
40
|
+
* announce each transition as a visually-hidden suffix span flips
|
|
41
|
+
* between localised "met" / "not yet met" copy.
|
|
42
|
+
*
|
|
43
|
+
* Tip: hoist or `useMemo` the array — inlining it in JSX makes the
|
|
44
|
+
* predicate-results memo bust every render. The kit's
|
|
45
|
+
* `usePasswordRequirements` helper already does this.
|
|
46
|
+
*/
|
|
47
|
+
requirements?: ReadonlyArray<PasswordRequirement>;
|
|
48
|
+
/**
|
|
49
|
+
* When `true` AND `strength` is not provided, derive a 0–3 score
|
|
50
|
+
* from the proportion of `requirements` satisfied. Lets consumers
|
|
51
|
+
* get the strength bar "for free" once they declare requirements.
|
|
52
|
+
*/
|
|
53
|
+
deriveStrength?: boolean;
|
|
23
54
|
/**
|
|
24
55
|
* Autocomplete hint. Defaults to 'current-password'.
|
|
25
56
|
* Use 'new-password' for registration/change-password forms.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password-input.d.ts","sourceRoot":"","sources":["../../../src/components/password-input/password-input.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"password-input.d.ts","sourceRoot":"","sources":["../../../src/components/password-input/password-input.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAM/D,wDAAwD;AACxD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,KAAK,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AA8B9B,QAAA,MAAM,mBAAmB;;8EAgBxB,CAAC;AAyBF;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,kBACf,SACE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,cAAc,GAAG,gBAAgB,CAAC,EAChE,YAAY,CAAC,OAAO,mBAAmB,CAAC;IAC1C,0DAA0D;IAC1D,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,+CAA+C;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAClD;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,kBAAkB,GAAG,cAAc,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;CACpE;AAED,eAAO,MAAM,aAAa,iHAqTzB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { PasswordRequirement } from './password-input';
|
|
2
|
+
export interface UsePasswordRequirementsOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Minimum password length. When set, adds a "length" requirement.
|
|
5
|
+
* Pass `12` (or whatever the server-side regex enforces) so the
|
|
6
|
+
* inline checklist tells users the same rule they'll bounce off
|
|
7
|
+
* server-side. When omitted, no length row is rendered.
|
|
8
|
+
*/
|
|
9
|
+
minLength?: number;
|
|
10
|
+
/** Adds an "uppercase letter" requirement when true. */
|
|
11
|
+
uppercase?: boolean;
|
|
12
|
+
/** Adds a "lowercase letter" requirement when true. */
|
|
13
|
+
lowercase?: boolean;
|
|
14
|
+
/** Adds a "digit" requirement when true. */
|
|
15
|
+
digit?: boolean;
|
|
16
|
+
/** Adds a "symbol" requirement when true. Matches anything outside `[A-Za-z0-9\s]`. */
|
|
17
|
+
symbol?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Builds the common set of password requirements with i18n-resolved
|
|
21
|
+
* labels. Designed for the AlfaDocs platform's patient-registration
|
|
22
|
+
* server-side regex (`/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{12,}$/`) but
|
|
23
|
+
* generic enough for any consumer.
|
|
24
|
+
*
|
|
25
|
+
* Each opt-in flag adds one row to the returned array, in a stable
|
|
26
|
+
* visual order (length → uppercase → lowercase → digit → symbol).
|
|
27
|
+
* Predicates are pure and run on every keystroke.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* const requirements = usePasswordRequirements({
|
|
31
|
+
* minLength: 12,
|
|
32
|
+
* uppercase: true,
|
|
33
|
+
* lowercase: true,
|
|
34
|
+
* digit: true,
|
|
35
|
+
* });
|
|
36
|
+
* <PasswordInput requirements={requirements} deriveStrength />
|
|
37
|
+
*/
|
|
38
|
+
export declare function usePasswordRequirements(opts?: UsePasswordRequirementsOptions): PasswordRequirement[];
|
|
39
|
+
//# sourceMappingURL=use-password-requirements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-password-requirements.d.ts","sourceRoot":"","sources":["../../../src/components/password-input/use-password-requirements.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,MAAM,WAAW,8BAA8B;IAC7C;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uFAAuF;IACvF,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,GAAE,8BAAmC,GACxC,mBAAmB,EAAE,CA8DvB"}
|