@teselia/password 1.0.0 → 1.0.1
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/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/dist/tes-password.iife.js +1 -1
- package/dist/tes-password.iife.js.map +1 -1
- package/dist/tes-password.js +16 -31
- package/dist/tes-password.js.map +1 -1
- package/package.json +6 -6
package/dist/tes-password.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Fragment as e, computed as t, createCommentVNode as n, createElementBlock as r, createElementVNode as i, defineComponent as a, defineCustomElement as o, mergeDefaults as s, normalizeClass as c, onBeforeUnmount as l, onMounted as u, openBlock as d, reactive as f, ref as p, renderList as m, toDisplayString as h, unref as g, useAttrs as _, useHost as ee, useTemplateRef as te, watch as v, watchEffect as y, withModifiers as b } from "vue";
|
|
2
|
-
|
|
2
|
+
// ../shared/src/use-announcer.ts
|
|
3
3
|
var x = 500, S = 100;
|
|
4
4
|
function C() {
|
|
5
5
|
let e = p(""), t;
|
|
@@ -23,16 +23,14 @@ function C() {
|
|
|
23
23
|
clear: n
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
//#region ../shared/src/use-custom-states.ts
|
|
26
|
+
// ../shared/src/use-custom-states.ts
|
|
28
27
|
function ne(e, t) {
|
|
29
28
|
y(() => {
|
|
30
29
|
let n = e.states;
|
|
31
30
|
if (n) for (let [e, r] of Object.entries(t())) r ? n.add(e) : n.delete(e);
|
|
32
31
|
});
|
|
33
32
|
}
|
|
34
|
-
|
|
35
|
-
//#region src/composables/use-caps-lock.ts
|
|
33
|
+
// src/composables/use-caps-lock.ts
|
|
36
34
|
function re({ props: e, announceNow: t }) {
|
|
37
35
|
let n = p(!1);
|
|
38
36
|
function r(r) {
|
|
@@ -48,8 +46,7 @@ function re({ props: e, announceNow: t }) {
|
|
|
48
46
|
forgetCapsLock: i
|
|
49
47
|
};
|
|
50
48
|
}
|
|
51
|
-
|
|
52
|
-
//#region src/core/purpose.ts
|
|
49
|
+
// src/core/purpose.ts
|
|
53
50
|
var w = {
|
|
54
51
|
current: "current-password",
|
|
55
52
|
new: "new-password"
|
|
@@ -122,8 +119,7 @@ function R(e) {
|
|
|
122
119
|
"allowed: lower, upper, digit, special;"
|
|
123
120
|
].filter(Boolean).join(" ");
|
|
124
121
|
}
|
|
125
|
-
|
|
126
|
-
//#region src/composables/use-field-options.ts
|
|
122
|
+
// src/composables/use-field-options.ts
|
|
127
123
|
function ie(e) {
|
|
128
124
|
let n = t(() => E(e.purpose)), r = t(() => n.value === "new" ? N({
|
|
129
125
|
minlength: e.minlength,
|
|
@@ -137,8 +133,7 @@ function ie(e) {
|
|
|
137
133
|
rulesForPasswordManagers: t(() => r.value ? R(r.value) : void 0)
|
|
138
134
|
};
|
|
139
135
|
}
|
|
140
|
-
|
|
141
|
-
//#region src/composables/use-public-events.ts
|
|
136
|
+
// src/composables/use-public-events.ts
|
|
142
137
|
function ae(e) {
|
|
143
138
|
function t(t) {
|
|
144
139
|
let n = {
|
|
@@ -156,8 +151,7 @@ function ae(e) {
|
|
|
156
151
|
dispatchChange: () => t("change")
|
|
157
152
|
};
|
|
158
153
|
}
|
|
159
|
-
|
|
160
|
-
//#region src/core/changes.ts
|
|
154
|
+
// src/core/changes.ts
|
|
161
155
|
function z(e, t) {
|
|
162
156
|
let n = new Map(e.map((e) => [e.requirement, e.met])), r = t.filter((e) => n.get(e.requirement) !== e.met);
|
|
163
157
|
return r.length === 0 ? null : {
|
|
@@ -166,8 +160,7 @@ function z(e, t) {
|
|
|
166
160
|
allMet: t.every((e) => e.met)
|
|
167
161
|
};
|
|
168
162
|
}
|
|
169
|
-
|
|
170
|
-
//#region src/composables/use-requirements.ts
|
|
163
|
+
// src/composables/use-requirements.ts
|
|
171
164
|
function oe({ host: e, props: n, ruleOptions: r, announceOnceTypingPauses: i }) {
|
|
172
165
|
let a = t(() => r.value ? F(e.state.value, r.value) : []), o = t(() => a.value.map((e) => ({
|
|
173
166
|
...e,
|
|
@@ -199,8 +192,7 @@ function oe({ host: e, props: n, ruleOptions: r, announceOnceTypingPauses: i })
|
|
|
199
192
|
reportUserChange: d
|
|
200
193
|
};
|
|
201
194
|
}
|
|
202
|
-
|
|
203
|
-
//#region src/composables/use-reveal.ts
|
|
195
|
+
// src/composables/use-reveal.ts
|
|
204
196
|
function se({ host: e, props: n, input: r, announceNow: i }) {
|
|
205
197
|
let a = t(() => e.state.revealed), o = t(() => a.value ? "text" : "password"), s = t(() => a.value ? n.textHideLabel : n.textShowLabel);
|
|
206
198
|
function c() {
|
|
@@ -223,8 +215,7 @@ function se({ host: e, props: n, input: r, announceNow: i }) {
|
|
|
223
215
|
toggleByUser: c
|
|
224
216
|
};
|
|
225
217
|
}
|
|
226
|
-
|
|
227
|
-
//#region src/core/validation.ts
|
|
218
|
+
// src/core/validation.ts
|
|
228
219
|
function B({ value: e, required: t, ruleOptions: n, customError: r }, i) {
|
|
229
220
|
return r ? {
|
|
230
221
|
flag: "customError",
|
|
@@ -240,8 +231,7 @@ function B({ value: e, required: t, ruleOptions: n, customError: r }, i) {
|
|
|
240
231
|
message: i.unmet
|
|
241
232
|
} : null;
|
|
242
233
|
}
|
|
243
|
-
|
|
244
|
-
//#region src/composables/use-validation.ts
|
|
234
|
+
// src/composables/use-validation.ts
|
|
245
235
|
function ce({ host: e, props: n, input: r, ruleOptions: i }) {
|
|
246
236
|
let { state: a } = e, o = t(() => B({
|
|
247
237
|
value: a.value,
|
|
@@ -272,8 +262,7 @@ function ce({ host: e, props: n, input: r, ruleOptions: i }) {
|
|
|
272
262
|
revealErrorsIfEdited: f
|
|
273
263
|
};
|
|
274
264
|
}
|
|
275
|
-
|
|
276
|
-
//#region src/composables/use-value-sync.ts
|
|
265
|
+
// src/composables/use-value-sync.ts
|
|
277
266
|
function V({ host: e, input: t }) {
|
|
278
267
|
function n() {
|
|
279
268
|
t.value && (e.state.value = t.value.value);
|
|
@@ -285,14 +274,12 @@ function V({ host: e, input: t }) {
|
|
|
285
274
|
n(), window.addEventListener("reset", r, !0);
|
|
286
275
|
}), l(() => window.removeEventListener("reset", r, !0)), { syncFromInput: n };
|
|
287
276
|
}
|
|
288
|
-
|
|
289
|
-
//#region src/core/ids.ts
|
|
277
|
+
// src/core/ids.ts
|
|
290
278
|
var H = 0;
|
|
291
279
|
function U(e) {
|
|
292
280
|
return H += 1, `${e}-${H}`;
|
|
293
281
|
}
|
|
294
|
-
|
|
295
|
-
//#region src/props.ts
|
|
282
|
+
// src/props.ts
|
|
296
283
|
var W = {
|
|
297
284
|
required: !1,
|
|
298
285
|
disabled: !1,
|
|
@@ -598,7 +585,7 @@ var W = {
|
|
|
598
585
|
let e = this.input;
|
|
599
586
|
e && this.pendingValue !== null && (e.value = this.pendingValue, this.state.value = this.pendingValue, this.pendingValue = null);
|
|
600
587
|
}
|
|
601
|
-
}, J = ":where(tes-password){--_text:var(--tes-color-text,
|
|
588
|
+
}, J = ":where(tes-password){--_text:var(--tes-color-text,light-dark(#1f2328,#e8eaee));--_muted:var(--tes-color-muted,light-dark(#59636e,#a3adba));--_bg:var(--tes-color-bg,light-dark(#fff,#16181d));--_border:var(--tes-color-border,light-dark(#7d8590,#7f8a99));--_accent:var(--tes-color-accent,light-dark(#0b5fcc,#7aa7ff));--_on-accent:var(--tes-color-on-accent,light-dark(#fff,#0d1117));--_hover:var(--tes-color-hover,light-dark(#eef3fb,#232a36));--_focus:var(--tes-color-focus,light-dark(#0b5fcc,#7aa7ff));--_error:var(--tes-color-error,light-dark(#c4232b,#ff8a80));--_success:var(--tes-color-success,light-dark(#1f7a3a,#4cc26a));--_radius:var(--tes-radius,.375rem);--_space:var(--tes-space,.5rem);--_control-height:2.75rem;color:var(--_text);font-family:var(--tes-font-family);font-size:var(--tes-font-size);display:inline-block}:where(tes-password[hidden]){display:none}:where(.tes-password__field){gap:calc(var(--_space) / 2);grid-template-columns:minmax(0,1fr);display:grid}:where(.tes-password__label){font-weight:500}:where(.tes-password__control){box-sizing:border-box;block-size:var(--_control-height);border:1px solid var(--_border);border-radius:var(--_radius);background:var(--_bg);display:flex}:where(.tes-password__control--invalid){border:2px solid var(--_error)}:where(.tes-password__control:has(.tes-password__input:focus-visible)){outline:2px solid var(--_focus);outline-offset:2px}:where(.tes-password__input){box-sizing:border-box;border-radius:var(--_radius);min-inline-size:0;color:var(--_text);font:inherit;background:0 0;border:0;outline:none;flex:1;margin:0;padding-inline:.75rem;font-size:max(1em,16px)}:where(.tes-password__toggle){border-radius:var(--_radius);min-inline-size:2.75rem;color:var(--_accent);font:inherit;cursor:pointer;background:0 0;border:0;flex:none;place-items:center;margin:0;padding-inline:.75rem;font-weight:500;display:grid}:where(.tes-password__control:has(.tes-password__input:disabled)){background:color-mix(in srgb, var(--_muted) 12%, var(--_bg))}:where(.tes-password__input:disabled){color:var(--_muted);cursor:not-allowed}:where(.tes-password__input:disabled~.tes-password__toggle){display:none}:where(.tes-password__toggle-text){grid-area:1/1}:where(.tes-password__toggle-text--inactive){visibility:hidden}:where(.tes-password__toggle:hover){background:var(--_hover)}:where(.tes-password__toggle:focus-visible){outline:2px solid var(--_focus);outline-offset:-2px}:where(.tes-password__hint){color:var(--_muted);margin:0;padding-block-start:.25rem;font-size:.875em}:where(.tes-password__caps-lock){margin:0;padding-block-start:.25rem;font-size:.875em;font-weight:500}:where(.tes-password__requirements){color:var(--_muted);padding-block-start:.25rem;font-size:.875em}:where(.tes-password__requirements-title){margin:0}:where(.tes-password__requirements-list){gap:.125rem;margin:.25rem 0 0;padding:0;list-style:none;display:grid}:where(.tes-password__requirement){align-items:center;gap:.375rem;margin:0;display:flex}:where(.tes-password__requirement--met){color:var(--_text)}:where(.tes-password__icon){fill:none;stroke:currentColor;stroke-width:1.5px;stroke-linecap:round;stroke-linejoin:round;flex:none;block-size:1em;inline-size:1em}:where(.tes-password__icon--met){stroke:var(--_success);stroke-width:2px}:where(.tes-password__error){color:var(--_error);margin:0;font-size:.875em;font-weight:500}:where(.tes-password__error:empty){display:none}:where(.tes-password__visually-hidden){clip-path:inset(50%);white-space:nowrap;border:0;block-size:1px;inline-size:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}@media (forced-colors:active){:where(.tes-password__control:has(.tes-password__input:focus-visible)),:where(.tes-password__toggle:focus-visible){outline-color:highlight}:where(.tes-password__input:disabled){color:graytext}}", Y = ":where(tes-password";
|
|
602
589
|
function X(e) {
|
|
603
590
|
return J.replaceAll(Y, `:where(${e}`);
|
|
604
591
|
}
|
|
@@ -607,8 +594,7 @@ function Z(e) {
|
|
|
607
594
|
let t = new CSSStyleSheet();
|
|
608
595
|
t.replaceSync(X(e)), document.adoptedStyleSheets = [...document.adoptedStyleSheets, t];
|
|
609
596
|
}
|
|
610
|
-
|
|
611
|
-
//#region src/index.ts
|
|
597
|
+
// src/index.ts
|
|
612
598
|
var Q = "tes-password";
|
|
613
599
|
function $(e = Q) {
|
|
614
600
|
if (typeof customElements > "u" || customElements.get(e)) return;
|
|
@@ -616,7 +602,6 @@ function $(e = Q) {
|
|
|
616
602
|
customElements.define(e, e === "tes-password" ? q : t), Z(e);
|
|
617
603
|
}
|
|
618
604
|
$();
|
|
619
|
-
//#endregion
|
|
620
605
|
export { Q as TAG_NAME, q as TesPasswordElement, $ as define };
|
|
621
606
|
|
|
622
607
|
//# sourceMappingURL=tes-password.js.map
|
package/dist/tes-password.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tes-password.js","names":["_openBlock","_createElementBlock","_createElementVNode","_unref","_toDisplayString","_normalizeClass","_withModifiers","_createCommentVNode","_Fragment","_renderList","_sfc_main","TesPasswordComponent","css","TYPING_PAUSE_MS","EMPTY_REGION_GAP_MS","useAnnouncer","announcement","ref","pending","clear","announceNow","message","announceOnceTypingPauses","onBeforeUnmount","useCustomStates","customStates","internals","name","active","states","useCapsLock","capsLockOn","readCapsLock","on","event","props","forgetCapsLock","AUTOCOMPLETE","isPurpose","value","resolvePurpose","autocompleteFor","explicit","purpose","CHARACTER_CLASSES","CLASS_PATTERNS","APPLE_CLASS_NAMES","positiveInteger","number","isCharacterClass","resolveRuleOptions","minLength","raw","maxLength","names","characterLength","checkRequirements","options","requirementsMet","check","isTooLong","passwordRules","useFieldOptions","computed","ruleOptions","usePublicEvents","dispatch","detail","host","requirementChanges","wasMet","previous","changed","current","useRequirements","checks","items","ruleText","announcedChecks","userChangePending","requirement","describeChanges","changes","reportUserChange","watch","useReveal","revealed","inputType","toggleLabel","toggleByUser","hide","hideForOwnForm","input","onMounted","validatePassword","customError","required","texts","useValidation","error","state","visibleError","markEdited","revealErrors","revealErrorsIfEdited","forgetErrorsForOwnForm","watchEffect","useValueSync","syncFromInput","syncAfterOwnFormReset","instanceCount","nextInstanceId","prefix","TES_PASSWORD_DEFAULTS","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","VueTesPassword","defineCustomElement","defineComponent","__props","attrs","useAttrs","useHost","useTemplateRef","inputId","requirementsId","capsLockId","hintId","errorId","defaultValue","describedBy","ids","requirementItems","handleUserInput","dispatchInput","disabled","item","leaveField","openBlock","createElementBlock","createElementVNode","unref","toDisplayString","normalizeClass","autocomplete","rulesForPasswordManagers","withModifiers","_cache","args","dispatchChange","createCommentVNode","Fragment","renderList","TesPasswordElement","reactive","initialProps","tes_password_default","HOST_SELECTOR","stylesFor","tagName","adoptStyles","sheet","TAG_NAME","define","registryAllowsOneTagPerConstructor"],"sources":["../../shared/src/use-announcer.ts","../../shared/src/use-custom-states.ts","../src/composables/use-caps-lock.ts","../src/core/purpose.ts","../src/core/rules.ts","../src/composables/use-field-options.ts","../src/composables/use-public-events.ts","../src/core/changes.ts","../src/composables/use-requirements.ts","../src/composables/use-reveal.ts","../src/core/validation.ts","../src/composables/use-validation.ts","../src/composables/use-value-sync.ts","../src/core/ids.ts","../src/props.ts","../src/TesPassword.vue","../src/TesPassword.vue","../src/element.ts","../src/tes-password.css?inline","../src/styles.ts","../src/index.ts"],"sourcesContent":["import { type Ref, onBeforeUnmount, ref } from 'vue'\n\nconst TYPING_PAUSE_MS = 500\n// Chromium batches accessibility updates per frame, so emptying and refilling the region in one task\n// is a no-op for a repeated message. The gap makes the empty state reach the accessibility tree.\nconst EMPTY_REGION_GAP_MS = 100\n\nexport interface Announcer {\n announcement: Ref<string>\n announceNow: (message: string) => void\n announceOnceTypingPauses: (message: () => string) => void\n clear: () => void\n}\n\nexport function useAnnouncer(): Announcer {\n const announcement = ref('')\n let pending: ReturnType<typeof setTimeout> | undefined\n\n function clear(): void {\n clearTimeout(pending)\n announcement.value = ''\n }\n\n function announceNow(message: string): void {\n clear()\n pending = setTimeout(() => {\n announcement.value = message\n }, EMPTY_REGION_GAP_MS)\n }\n\n function announceOnceTypingPauses(message: () => string): void {\n clear()\n pending = setTimeout(() => {\n announcement.value = message()\n }, TYPING_PAUSE_MS)\n }\n\n onBeforeUnmount(() => clearTimeout(pending))\n\n return { announcement, announceNow, announceOnceTypingPauses, clear }\n}\n","import { watchEffect } from 'vue'\n\nexport function useCustomStates<State extends string>(\n internals: ElementInternals,\n states: () => Record<State, boolean>,\n): void {\n watchEffect(() => {\n const customStates = internals.states\n if (!customStates) return\n\n for (const [name, active] of Object.entries<boolean>(states())) {\n if (active) customStates.add(name)\n else customStates.delete(name)\n }\n })\n}\n","import { ref } from 'vue'\nimport type { ResolvedTesPasswordProps } from '../props'\n\ninterface CapsLockOptions {\n props: ResolvedTesPasswordProps\n announceNow: (message: string) => void\n}\n\nexport function useCapsLock({ props, announceNow }: CapsLockOptions) {\n const capsLockOn = ref(false)\n\n function readCapsLock(event: KeyboardEvent | PointerEvent): void {\n const on = event.getModifierState('CapsLock')\n if (on && !capsLockOn.value) announceNow(props.textCapsLock)\n capsLockOn.value = on\n }\n\n function forgetCapsLock(): void {\n capsLockOn.value = false\n }\n\n return { capsLockOn, readCapsLock, forgetCapsLock }\n}\n","export type Purpose = 'current' | 'new'\n\nconst AUTOCOMPLETE: Record<Purpose, string> = {\n current: 'current-password',\n new: 'new-password',\n}\n\nexport function isPurpose(value: unknown): value is Purpose {\n return value === 'current' || value === 'new'\n}\n\nexport function resolvePurpose(value: unknown): Purpose {\n return isPurpose(value) ? value : 'current'\n}\n\nexport function autocompleteFor(purpose: Purpose, explicit: string | undefined): string {\n return explicit?.trim() ? explicit : AUTOCOMPLETE[purpose]\n}\n","export type CharacterClass = 'lowercase' | 'uppercase' | 'digit' | 'symbol'\nexport type Requirement = 'length' | CharacterClass\n\nexport interface RuleOptions {\n minLength: number\n maxLength: number | null\n classes: CharacterClass[]\n unknown: string[]\n}\n\nexport interface RequirementCheck {\n requirement: Requirement\n met: boolean\n}\n\nexport const DEFAULT_MIN_LENGTH = 8\n\nconst CHARACTER_CLASSES: readonly CharacterClass[] = ['lowercase', 'uppercase', 'digit', 'symbol']\n\nconst CLASS_PATTERNS: Record<CharacterClass, RegExp> = {\n lowercase: /\\p{Ll}/u,\n uppercase: /[\\p{Lu}\\p{Lt}]/u,\n digit: /\\p{Nd}/u,\n symbol: /[^\\p{L}\\p{N}\\s]/u,\n}\n\nconst APPLE_CLASS_NAMES: Record<CharacterClass, string> = {\n lowercase: 'lower',\n uppercase: 'upper',\n digit: 'digit',\n symbol: 'special',\n}\n\nfunction positiveInteger(value: unknown): number | null {\n if (value === null || value === undefined || value === '') return null\n const number = Number(value)\n return Number.isInteger(number) && number > 0 ? number : null\n}\n\nfunction isCharacterClass(name: string): name is CharacterClass {\n return (CHARACTER_CLASSES as readonly string[]).includes(name)\n}\n\nexport function resolveRuleOptions(raw: { minlength?: unknown; maxlength?: unknown; requirements?: unknown }): RuleOptions {\n const minLength = positiveInteger(raw.minlength) ?? DEFAULT_MIN_LENGTH\n const maxLength = positiveInteger(raw.maxlength)\n const names = String(raw.requirements ?? '')\n .toLowerCase()\n .split(/[\\s,]+/)\n .filter(Boolean)\n\n return {\n minLength,\n maxLength: maxLength !== null && maxLength >= minLength ? maxLength : null,\n classes: CHARACTER_CLASSES.filter((name) => names.includes(name)),\n unknown: [...new Set(names.filter((name) => !isCharacterClass(name)))],\n }\n}\n\nexport function characterLength(value: string): number {\n return [...value].length\n}\n\nexport function checkRequirements(value: string, options: RuleOptions): RequirementCheck[] {\n return [\n { requirement: 'length', met: characterLength(value) >= options.minLength },\n ...options.classes.map((name) => ({ requirement: name, met: CLASS_PATTERNS[name].test(value) })),\n ]\n}\n\nexport function requirementsMet(value: string, options: RuleOptions): boolean {\n return checkRequirements(value, options).every((check) => check.met)\n}\n\nexport function isTooLong(value: string, options: RuleOptions): boolean {\n return options.maxLength !== null && characterLength(value) > options.maxLength\n}\n\nexport function passwordRules(options: RuleOptions): string {\n const rules = [\n `minlength: ${options.minLength};`,\n options.maxLength !== null && `maxlength: ${options.maxLength};`,\n ...options.classes.map((name) => `required: ${APPLE_CLASS_NAMES[name]};`),\n 'allowed: lower, upper, digit, special;',\n ]\n return rules.filter(Boolean).join(' ')\n}\n","import { computed, watchEffect } from 'vue'\nimport { autocompleteFor, isPurpose, resolvePurpose } from '../core/purpose'\nimport { passwordRules, resolveRuleOptions } from '../core/rules'\nimport type { TesPasswordProps } from '../props'\n\nexport function useFieldOptions(props: Readonly<TesPasswordProps>) {\n const purpose = computed(() => resolvePurpose(props.purpose))\n\n const ruleOptions = computed(() =>\n purpose.value === 'new'\n ? resolveRuleOptions({ minlength: props.minlength, maxlength: props.maxlength, requirements: props.requirements })\n : null,\n )\n\n const autocomplete = computed(() => autocompleteFor(purpose.value, props.autocomplete))\n const rulesForPasswordManagers = computed(() => (ruleOptions.value ? passwordRules(ruleOptions.value) : undefined))\n\n if (import.meta.env.DEV) {\n watchEffect(() => {\n if (props.purpose !== undefined && !isPurpose(props.purpose)) {\n console.warn(`[tes-password] \\`purpose\\` must be \"current\" or \"new\". Using \"current\".`)\n }\n const unknown = ruleOptions.value?.unknown ?? []\n if (unknown.length > 0) {\n console.warn(`[tes-password] Unknown requirements ignored: ${unknown.join(', ')}.`)\n }\n const hasRules = props.minlength !== undefined || props.maxlength !== undefined || Boolean(props.requirements)\n if (purpose.value === 'current' && hasRules) {\n console.warn('[tes-password] `minlength`, `maxlength` and `requirements` only apply with `purpose=\"new\"`.')\n }\n })\n }\n\n return { purpose, ruleOptions, autocomplete, rulesForPasswordManagers }\n}\n","import type { TesPasswordElement } from '../element'\n\nexport function usePublicEvents(host: TesPasswordElement) {\n function dispatch(name: 'input' | 'change'): void {\n const detail = { value: host.value, requirementsMet: host.requirementsMet }\n host.dispatchEvent(new CustomEvent(name, { bubbles: true, composed: true, detail }))\n }\n\n return {\n dispatchInput: () => dispatch('input'),\n dispatchChange: () => dispatch('change'),\n }\n}\n","import type { Requirement, RequirementCheck } from './rules'\n\nexport interface RequirementChanges {\n met: Requirement[]\n unmet: Requirement[]\n allMet: boolean\n}\n\nexport function requirementChanges(previous: RequirementCheck[], current: RequirementCheck[]): RequirementChanges | null {\n const wasMet = new Map(previous.map((check) => [check.requirement, check.met]))\n const changed = current.filter((check) => wasMet.get(check.requirement) !== check.met)\n if (changed.length === 0) return null\n\n return {\n met: changed.filter((check) => check.met).map((check) => check.requirement),\n unmet: changed.filter((check) => !check.met).map((check) => check.requirement),\n allMet: current.every((check) => check.met),\n }\n}\n","import { type ComputedRef, computed, watch } from 'vue'\nimport { type RequirementChanges, requirementChanges } from '../core/changes'\nimport { type Requirement, type RequirementCheck, type RuleOptions, checkRequirements } from '../core/rules'\nimport type { TesPasswordElement } from '../element'\nimport type { ResolvedTesPasswordProps } from '../props'\n\ninterface RequirementsOptions {\n host: TesPasswordElement\n props: ResolvedTesPasswordProps\n ruleOptions: ComputedRef<RuleOptions | null>\n announceOnceTypingPauses: (message: () => string) => void\n}\n\nexport interface RequirementItem {\n requirement: Requirement\n met: boolean\n text: string\n}\n\nexport function useRequirements({ host, props, ruleOptions, announceOnceTypingPauses }: RequirementsOptions) {\n const checks = computed<RequirementCheck[]>(() =>\n ruleOptions.value ? checkRequirements(host.state.value, ruleOptions.value) : [],\n )\n\n const items = computed<RequirementItem[]>(() =>\n checks.value.map((check) => ({ ...check, text: ruleText(check.requirement) })),\n )\n\n let announcedChecks = checks.value\n let userChangePending = false\n\n function ruleText(requirement: Requirement): string {\n const texts: Record<Requirement, string> = {\n length: props.textRuleLength.replaceAll('{minlength}', String(ruleOptions.value?.minLength ?? '')),\n lowercase: props.textRuleLowercase,\n uppercase: props.textRuleUppercase,\n digit: props.textRuleDigit,\n symbol: props.textRuleSymbol,\n }\n return texts[requirement]\n }\n\n function describeChanges(changes: RequirementChanges): string {\n if (changes.allMet) return props.textAllMet\n return checks.value\n .filter((check) => changes.met.includes(check.requirement) || changes.unmet.includes(check.requirement))\n .map((check) => `${ruleText(check.requirement)}, ${check.met ? props.textRuleMet : props.textRuleUnmet}`)\n .join('. ')\n }\n\n function reportUserChange(): void {\n if (!ruleOptions.value) return\n userChangePending = true\n announceOnceTypingPauses(() => {\n userChangePending = false\n const changes = requirementChanges(announcedChecks, checks.value)\n announcedChecks = checks.value\n return changes ? describeChanges(changes) : ''\n })\n }\n\n watch(checks, (current) => {\n if (!userChangePending) announcedChecks = current\n })\n\n return { requirementItems: items, reportUserChange }\n}\n","import { type Ref, computed, onBeforeUnmount, onMounted } from 'vue'\nimport type { TesPasswordElement } from '../element'\nimport type { ResolvedTesPasswordProps } from '../props'\n\ninterface RevealOptions {\n host: TesPasswordElement\n props: ResolvedTesPasswordProps\n input: Readonly<Ref<HTMLInputElement | null>>\n announceNow: (message: string) => void\n}\n\nexport function useReveal({ host, props, input, announceNow }: RevealOptions) {\n\n const revealed = computed(() => host.state.revealed)\n const inputType = computed(() => (revealed.value ? 'text' : 'password'))\n const toggleLabel = computed(() => (revealed.value ? props.textHideLabel : props.textShowLabel))\n\n function toggleByUser(): void {\n host.revealed = !host.revealed\n announceNow(host.revealed ? props.textShown : props.textHidden)\n }\n\n function hide(): void {\n host.revealed = false\n }\n\n function hideForOwnForm(event: Event): void {\n if (event.target === input.value?.form) hide()\n }\n\n onMounted(() => {\n window.addEventListener('submit', hideForOwnForm, true)\n window.addEventListener('reset', hideForOwnForm, true)\n window.addEventListener('pagehide', hide)\n })\n\n onBeforeUnmount(() => {\n window.removeEventListener('submit', hideForOwnForm, true)\n window.removeEventListener('reset', hideForOwnForm, true)\n window.removeEventListener('pagehide', hide)\n })\n\n return { revealed, inputType, toggleLabel, toggleByUser }\n}\n","import { type RuleOptions, isTooLong, requirementsMet } from './rules'\n\nexport interface PasswordValidationInput {\n value: string\n required: boolean\n ruleOptions: RuleOptions | null\n customError: string\n}\n\nexport interface PasswordValidationTexts {\n required: string\n unmet: string\n tooLong: string\n}\n\nexport interface PasswordValidationError {\n flag: 'customError' | 'valueMissing' | 'tooLong' | 'unmet'\n message: string\n}\n\nexport function validatePassword(\n { value, required, ruleOptions, customError }: PasswordValidationInput,\n texts: PasswordValidationTexts,\n): PasswordValidationError | null {\n if (customError) return { flag: 'customError', message: customError }\n if (value === '') return required ? { flag: 'valueMissing', message: texts.required } : null\n if (!ruleOptions) return null\n if (isTooLong(value, ruleOptions)) {\n return { flag: 'tooLong', message: texts.tooLong.replaceAll('{maxlength}', String(ruleOptions.maxLength)) }\n }\n if (!requirementsMet(value, ruleOptions)) return { flag: 'unmet', message: texts.unmet }\n return null\n}\n","import { type ComputedRef, type Ref, computed, onBeforeUnmount, onMounted, watchEffect } from 'vue'\nimport type { RuleOptions } from '../core/rules'\nimport { validatePassword } from '../core/validation'\nimport type { TesPasswordElement } from '../element'\nimport type { ResolvedTesPasswordProps } from '../props'\n\ninterface ValidationOptions {\n host: TesPasswordElement\n props: ResolvedTesPasswordProps\n input: Readonly<Ref<HTMLInputElement | null>>\n ruleOptions: ComputedRef<RuleOptions | null>\n}\n\nexport function useValidation({ host, props, input, ruleOptions }: ValidationOptions) {\n const { state } = host\n\n const error = computed(() =>\n validatePassword(\n { value: state.value, required: props.required, ruleOptions: ruleOptions.value, customError: state.customError },\n { required: props.textRequired, unmet: props.textUnmet, tooLong: props.textTooLong },\n ),\n )\n\n const visibleError = computed(() => (state.errorsVisible ? error.value : null))\n\n function markEdited(): void {\n state.edited = true\n state.customError = ''\n }\n\n function revealErrors(): void {\n state.errorsVisible = true\n }\n\n function revealErrorsIfEdited(): void {\n if (state.edited) revealErrors()\n }\n\n function forgetErrorsForOwnForm(event: Event): void {\n if (event.target !== input.value?.form) return\n state.edited = false\n state.errorsVisible = false\n state.customError = ''\n }\n\n watchEffect(() => input.value?.setCustomValidity(error.value?.message ?? ''), { flush: 'sync' })\n\n onMounted(() => window.addEventListener('reset', forgetErrorsForOwnForm, true))\n onBeforeUnmount(() => window.removeEventListener('reset', forgetErrorsForOwnForm, true))\n\n return { visibleError, markEdited, revealErrors, revealErrorsIfEdited }\n}\n","import { type Ref, onBeforeUnmount, onMounted } from 'vue'\nimport type { TesPasswordElement } from '../element'\n\ninterface ValueSyncOptions {\n host: TesPasswordElement\n input: Readonly<Ref<HTMLInputElement | null>>\n}\n\nexport function useValueSync({ host, input }: ValueSyncOptions) {\n function syncFromInput(): void {\n if (input.value) host.state.value = input.value.value\n }\n\n function syncAfterOwnFormReset(event: Event): void {\n if (event.target === input.value?.form) setTimeout(syncFromInput)\n }\n\n onMounted(() => {\n syncFromInput()\n window.addEventListener('reset', syncAfterOwnFormReset, true)\n })\n\n onBeforeUnmount(() => window.removeEventListener('reset', syncAfterOwnFormReset, true))\n\n return { syncFromInput }\n}\n","let instanceCount = 0\n\nexport function nextInstanceId(prefix: string): string {\n instanceCount += 1\n return `${prefix}-${instanceCount}`\n}\n","import type { Purpose } from './core/purpose'\n\nexport interface TesPasswordProps {\n label?: string\n name?: string\n hint?: string\n required?: boolean\n disabled?: boolean\n readonly?: boolean\n purpose?: Purpose\n minlength?: number\n maxlength?: number\n requirements?: string\n autocomplete?: string\n textShow?: string\n textHide?: string\n textShowLabel?: string\n textHideLabel?: string\n textShown?: string\n textHidden?: string\n textRequirements?: string\n textRuleLength?: string\n textRuleLowercase?: string\n textRuleUppercase?: string\n textRuleDigit?: string\n textRuleSymbol?: string\n textRuleMet?: string\n textRuleUnmet?: string\n textAllMet?: string\n textCapsLock?: string\n textRequired?: string\n textUnmet?: string\n textTooLong?: string\n}\n\nexport const TES_PASSWORD_DEFAULTS = {\n required: false,\n disabled: false,\n readonly: false,\n textShow: 'Show',\n textHide: 'Hide',\n textShowLabel: 'Show password',\n textHideLabel: 'Hide password',\n textShown: 'Your password is shown',\n textHidden: 'Your password is hidden',\n textRequirements: 'Your password must have:',\n textRuleLength: 'At least {minlength} characters',\n textRuleLowercase: 'A lowercase letter',\n textRuleUppercase: 'An uppercase letter',\n textRuleDigit: 'A number',\n textRuleSymbol: 'A symbol, like ! or #',\n textRuleMet: 'done',\n textRuleUnmet: 'not yet',\n textAllMet: 'All requirements met',\n textCapsLock: 'Caps Lock is on',\n textRequired: 'Enter a password',\n textUnmet: 'Your password does not meet all the requirements',\n textTooLong: 'Use {maxlength} characters or fewer',\n}\n\nexport type ResolvedTesPasswordProps = Readonly<TesPasswordProps & typeof TES_PASSWORD_DEFAULTS>\n","<template>\n <div class=\"tes-password__field\">\n <label :for=\"inputId\" class=\"tes-password__label\">{{ label }}</label>\n <div class=\"tes-password__control\" :class=\"{ 'tes-password__control--invalid': visibleError }\">\n <input\n :id=\"inputId\"\n ref=\"input\"\n class=\"tes-password__input\"\n :type=\"inputType\"\n :name=\"name\"\n :value.attr=\"defaultValue\"\n :autocomplete=\"autocomplete\"\n :passwordrules=\"rulesForPasswordManagers\"\n :aria-describedby=\"describedBy\"\n :aria-invalid=\"visibleError ? 'true' : undefined\"\n :required=\"required\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n spellcheck=\"false\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n @input.stop=\"handleUserInput\"\n @change.stop=\"dispatchChange\"\n @keydown=\"readCapsLock\"\n @keyup=\"readCapsLock\"\n @pointerdown=\"readCapsLock\"\n @blur=\"leaveField\"\n @invalid=\"revealErrors\"\n />\n <button type=\"button\" class=\"tes-password__toggle\" :aria-label=\"toggleLabel\" @click=\"toggleByUser\">\n <span class=\"tes-password__toggle-text\" :class=\"{ 'tes-password__toggle-text--inactive': revealed }\">{{\n textShow\n }}</span>\n <span class=\"tes-password__toggle-text\" :class=\"{ 'tes-password__toggle-text--inactive': !revealed }\">{{\n textHide\n }}</span>\n </button>\n </div>\n <p v-if=\"hint\" :id=\"hintId\" class=\"tes-password__hint\">{{ hint }}</p>\n <p v-if=\"capsLockOn\" :id=\"capsLockId\" class=\"tes-password__caps-lock\">{{ textCapsLock }}</p>\n <div v-if=\"requirementItems.length\" :id=\"requirementsId\" class=\"tes-password__requirements\">\n <p class=\"tes-password__requirements-title\">{{ textRequirements }}</p>\n <ul class=\"tes-password__requirements-list\">\n <li\n v-for=\"item in requirementItems\"\n :key=\"item.requirement\"\n class=\"tes-password__requirement\"\n :class=\"{ 'tes-password__requirement--met': item.met }\"\n >\n <svg\n v-if=\"item.met\"\n class=\"tes-password__icon tes-password__icon--met\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M3.5 8.5l3 3 6-7\" />\n </svg>\n <svg\n v-else\n class=\"tes-password__icon tes-password__icon--unmet\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle cx=\"8\" cy=\"8\" r=\"5\" />\n </svg>\n <span>{{ item.text }}</span\n ><span class=\"tes-password__visually-hidden\">, {{ item.met ? textRuleMet : textRuleUnmet }}</span>\n </li>\n </ul>\n </div>\n <p :id=\"errorId\" class=\"tes-password__error\" aria-live=\"polite\">{{ visibleError?.message }}</p>\n <div role=\"status\" class=\"tes-password__visually-hidden\">{{ announcement }}</div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useAnnouncer, useCustomStates } from '@teselia/shared'\nimport { computed, useAttrs, useHost, useTemplateRef, watch } from 'vue'\nimport { useCapsLock } from './composables/use-caps-lock'\nimport { useFieldOptions } from './composables/use-field-options'\nimport { usePublicEvents } from './composables/use-public-events'\nimport { useRequirements } from './composables/use-requirements'\nimport { useReveal } from './composables/use-reveal'\nimport { useValidation } from './composables/use-validation'\nimport { useValueSync } from './composables/use-value-sync'\nimport { nextInstanceId } from './core/ids'\nimport type { TesPasswordElement } from './element'\nimport { TES_PASSWORD_DEFAULTS, type TesPasswordProps } from './props'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<TesPasswordProps>(), TES_PASSWORD_DEFAULTS)\nconst attrs = useAttrs()\nconst host = useHost() as TesPasswordElement\nconst input = useTemplateRef<HTMLInputElement>('input')\n\nconst inputId = nextInstanceId('tes-password')\nconst requirementsId = `${inputId}-requirements`\nconst capsLockId = `${inputId}-caps-lock`\nconst hintId = `${inputId}-hint`\nconst errorId = `${inputId}-error`\nconst defaultValue = computed(() => (typeof attrs.value === 'string' ? attrs.value : undefined))\n\nconst { announcement, announceNow, announceOnceTypingPauses } = useAnnouncer()\nconst { ruleOptions, autocomplete, rulesForPasswordManagers } = useFieldOptions(props)\nconst { revealed, inputType, toggleLabel, toggleByUser } = useReveal({ host, props, input, announceNow })\nconst { syncFromInput } = useValueSync({ host, input })\nconst { requirementItems, reportUserChange } = useRequirements({\n host,\n props,\n ruleOptions,\n announceOnceTypingPauses,\n})\n\nconst { capsLockOn, readCapsLock, forgetCapsLock } = useCapsLock({ props, announceNow })\n\nconst { visibleError, markEdited, revealErrors, revealErrorsIfEdited } = useValidation({\n host,\n props,\n input,\n ruleOptions,\n})\n\nconst describedBy = computed(() => {\n const ids = [\n props.hint && hintId,\n requirementItems.value.length > 0 && requirementsId,\n capsLockOn.value && capsLockId,\n visibleError.value && errorId,\n ].filter(Boolean)\n return ids.length > 0 ? ids.join(' ') : undefined\n})\n\nconst { dispatchInput, dispatchChange } = usePublicEvents(host)\n\nfunction handleUserInput(): void {\n markEdited()\n syncFromInput()\n reportUserChange()\n dispatchInput()\n}\n\nwatch(\n () => props.disabled,\n (disabled) => {\n if (disabled) host.revealed = false\n },\n)\n\nuseCustomStates(host.internals, () => ({\n invalid: visibleError.value !== null,\n empty: host.state.value === '',\n revealed: revealed.value,\n 'requirements-met': requirementItems.value.length > 0 && requirementItems.value.every((item) => item.met),\n 'caps-lock': capsLockOn.value,\n}))\n\nfunction leaveField(): void {\n forgetCapsLock()\n revealErrorsIfEdited()\n}\n\nif (import.meta.env.DEV && !props.label) {\n console.warn('[tes-password] The `label` attribute is required for an accessible name.')\n}\n</script>\n","<template>\n <div class=\"tes-password__field\">\n <label :for=\"inputId\" class=\"tes-password__label\">{{ label }}</label>\n <div class=\"tes-password__control\" :class=\"{ 'tes-password__control--invalid': visibleError }\">\n <input\n :id=\"inputId\"\n ref=\"input\"\n class=\"tes-password__input\"\n :type=\"inputType\"\n :name=\"name\"\n :value.attr=\"defaultValue\"\n :autocomplete=\"autocomplete\"\n :passwordrules=\"rulesForPasswordManagers\"\n :aria-describedby=\"describedBy\"\n :aria-invalid=\"visibleError ? 'true' : undefined\"\n :required=\"required\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n spellcheck=\"false\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n @input.stop=\"handleUserInput\"\n @change.stop=\"dispatchChange\"\n @keydown=\"readCapsLock\"\n @keyup=\"readCapsLock\"\n @pointerdown=\"readCapsLock\"\n @blur=\"leaveField\"\n @invalid=\"revealErrors\"\n />\n <button type=\"button\" class=\"tes-password__toggle\" :aria-label=\"toggleLabel\" @click=\"toggleByUser\">\n <span class=\"tes-password__toggle-text\" :class=\"{ 'tes-password__toggle-text--inactive': revealed }\">{{\n textShow\n }}</span>\n <span class=\"tes-password__toggle-text\" :class=\"{ 'tes-password__toggle-text--inactive': !revealed }\">{{\n textHide\n }}</span>\n </button>\n </div>\n <p v-if=\"hint\" :id=\"hintId\" class=\"tes-password__hint\">{{ hint }}</p>\n <p v-if=\"capsLockOn\" :id=\"capsLockId\" class=\"tes-password__caps-lock\">{{ textCapsLock }}</p>\n <div v-if=\"requirementItems.length\" :id=\"requirementsId\" class=\"tes-password__requirements\">\n <p class=\"tes-password__requirements-title\">{{ textRequirements }}</p>\n <ul class=\"tes-password__requirements-list\">\n <li\n v-for=\"item in requirementItems\"\n :key=\"item.requirement\"\n class=\"tes-password__requirement\"\n :class=\"{ 'tes-password__requirement--met': item.met }\"\n >\n <svg\n v-if=\"item.met\"\n class=\"tes-password__icon tes-password__icon--met\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M3.5 8.5l3 3 6-7\" />\n </svg>\n <svg\n v-else\n class=\"tes-password__icon tes-password__icon--unmet\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle cx=\"8\" cy=\"8\" r=\"5\" />\n </svg>\n <span>{{ item.text }}</span\n ><span class=\"tes-password__visually-hidden\">, {{ item.met ? textRuleMet : textRuleUnmet }}</span>\n </li>\n </ul>\n </div>\n <p :id=\"errorId\" class=\"tes-password__error\" aria-live=\"polite\">{{ visibleError?.message }}</p>\n <div role=\"status\" class=\"tes-password__visually-hidden\">{{ announcement }}</div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useAnnouncer, useCustomStates } from '@teselia/shared'\nimport { computed, useAttrs, useHost, useTemplateRef, watch } from 'vue'\nimport { useCapsLock } from './composables/use-caps-lock'\nimport { useFieldOptions } from './composables/use-field-options'\nimport { usePublicEvents } from './composables/use-public-events'\nimport { useRequirements } from './composables/use-requirements'\nimport { useReveal } from './composables/use-reveal'\nimport { useValidation } from './composables/use-validation'\nimport { useValueSync } from './composables/use-value-sync'\nimport { nextInstanceId } from './core/ids'\nimport type { TesPasswordElement } from './element'\nimport { TES_PASSWORD_DEFAULTS, type TesPasswordProps } from './props'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<TesPasswordProps>(), TES_PASSWORD_DEFAULTS)\nconst attrs = useAttrs()\nconst host = useHost() as TesPasswordElement\nconst input = useTemplateRef<HTMLInputElement>('input')\n\nconst inputId = nextInstanceId('tes-password')\nconst requirementsId = `${inputId}-requirements`\nconst capsLockId = `${inputId}-caps-lock`\nconst hintId = `${inputId}-hint`\nconst errorId = `${inputId}-error`\nconst defaultValue = computed(() => (typeof attrs.value === 'string' ? attrs.value : undefined))\n\nconst { announcement, announceNow, announceOnceTypingPauses } = useAnnouncer()\nconst { ruleOptions, autocomplete, rulesForPasswordManagers } = useFieldOptions(props)\nconst { revealed, inputType, toggleLabel, toggleByUser } = useReveal({ host, props, input, announceNow })\nconst { syncFromInput } = useValueSync({ host, input })\nconst { requirementItems, reportUserChange } = useRequirements({\n host,\n props,\n ruleOptions,\n announceOnceTypingPauses,\n})\n\nconst { capsLockOn, readCapsLock, forgetCapsLock } = useCapsLock({ props, announceNow })\n\nconst { visibleError, markEdited, revealErrors, revealErrorsIfEdited } = useValidation({\n host,\n props,\n input,\n ruleOptions,\n})\n\nconst describedBy = computed(() => {\n const ids = [\n props.hint && hintId,\n requirementItems.value.length > 0 && requirementsId,\n capsLockOn.value && capsLockId,\n visibleError.value && errorId,\n ].filter(Boolean)\n return ids.length > 0 ? ids.join(' ') : undefined\n})\n\nconst { dispatchInput, dispatchChange } = usePublicEvents(host)\n\nfunction handleUserInput(): void {\n markEdited()\n syncFromInput()\n reportUserChange()\n dispatchInput()\n}\n\nwatch(\n () => props.disabled,\n (disabled) => {\n if (disabled) host.revealed = false\n },\n)\n\nuseCustomStates(host.internals, () => ({\n invalid: visibleError.value !== null,\n empty: host.state.value === '',\n revealed: revealed.value,\n 'requirements-met': requirementItems.value.length > 0 && requirementItems.value.every((item) => item.met),\n 'caps-lock': capsLockOn.value,\n}))\n\nfunction leaveField(): void {\n forgetCapsLock()\n revealErrorsIfEdited()\n}\n\nif (import.meta.env.DEV && !props.label) {\n console.warn('[tes-password] The `label` attribute is required for an accessible name.')\n}\n</script>\n","import { defineCustomElement, reactive } from 'vue'\nimport TesPasswordComponent from './TesPassword.vue'\nimport { resolvePurpose } from './core/purpose'\nimport { requirementsMet, resolveRuleOptions } from './core/rules'\n\nexport interface TesPasswordState {\n revealed: boolean\n value: string\n edited: boolean\n errorsVisible: boolean\n customError: string\n}\n\nconst VueTesPassword = defineCustomElement(TesPasswordComponent, { shadowRoot: false })\n\nexport class TesPasswordElement extends VueTesPassword {\n readonly state: TesPasswordState = reactive({\n revealed: false,\n value: '',\n edited: false,\n errorsVisible: false,\n customError: '',\n })\n\n readonly internals: ElementInternals\n\n private pendingValue: string | null = null\n\n constructor(initialProps?: Record<string, unknown>) {\n super(initialProps)\n this.internals = this.attachInternals()\n }\n\n get revealed(): boolean {\n return this.state.revealed\n }\n\n set revealed(revealed: boolean) {\n if (revealed === this.state.revealed) return\n this.state.revealed = revealed\n this.syncInputType()\n this.dispatchEvent(new CustomEvent('revealchange', { bubbles: true, composed: true, detail: { revealed } }))\n }\n\n get value(): string {\n return this.input?.value ?? this.pendingValue ?? this.defaultValue\n }\n\n set value(value: string) {\n const input = this.input\n if (input) input.value = value\n else this.pendingValue = value\n this.state.value = value\n }\n\n get requirementsMet(): boolean {\n if (resolvePurpose(this.getAttribute('purpose')) !== 'new') return true\n const options = resolveRuleOptions({\n minlength: this.getAttribute('minlength'),\n maxlength: this.getAttribute('maxlength'),\n requirements: this.getAttribute('requirements'),\n })\n return requirementsMet(this.state.value, options)\n }\n\n get defaultValue(): string {\n return this.getAttribute('value') ?? ''\n }\n\n set defaultValue(value: string) {\n this.setAttribute('value', value)\n }\n\n get minLength(): number {\n return resolveRuleOptions({ minlength: this.getAttribute('minlength') }).minLength\n }\n\n set minLength(value: number) {\n this.setAttribute('minlength', String(value))\n }\n\n get maxLength(): number {\n return resolveRuleOptions({ minlength: 1, maxlength: this.getAttribute('maxlength') }).maxLength ?? -1\n }\n\n set maxLength(value: number) {\n this.setAttribute('maxlength', String(value))\n }\n\n get readOnly(): boolean {\n return this.hasAttribute('readonly')\n }\n\n set readOnly(value: boolean) {\n this.toggleAttribute('readonly', value)\n }\n\n get form(): HTMLFormElement | null {\n return this.input?.form ?? null\n }\n\n get validity(): ValidityState {\n return (this.input ?? document.createElement('input')).validity\n }\n\n get validationMessage(): string {\n return this.input?.validationMessage ?? ''\n }\n\n get willValidate(): boolean {\n return this.input?.willValidate ?? false\n }\n\n setCustomValidity(message: string): void {\n this.state.customError = message\n if (message) this.state.errorsVisible = true\n }\n\n checkValidity(): boolean {\n return this.input?.checkValidity() ?? true\n }\n\n reportValidity(): boolean {\n return this.input?.reportValidity() ?? true\n }\n\n override connectedCallback(): void {\n super.connectedCallback()\n this.applyPendingValue()\n }\n\n override focus(options?: FocusOptions): void {\n this.input?.focus(options)\n }\n\n private get input(): HTMLInputElement | null {\n return this.querySelector<HTMLInputElement>('.tes-password__input')\n }\n\n private syncInputType(): void {\n const input = this.input\n if (input) input.type = this.state.revealed ? 'text' : 'password'\n }\n\n private applyPendingValue(): void {\n const input = this.input\n if (!input || this.pendingValue === null) return\n input.value = this.pendingValue\n this.state.value = this.pendingValue\n this.pendingValue = null\n }\n}\n",":where(tes-password) {\n --_text: var(--tes-color-text, light-dark(#1f2328, #e8eaee));\n --_muted: var(--tes-color-muted, light-dark(#59636e, #a3adba));\n --_bg: var(--tes-color-bg, light-dark(#ffffff, #16181d));\n --_border: var(--tes-color-border, light-dark(#7d8590, #7f8a99));\n --_accent: var(--tes-color-accent, light-dark(#0b5fcc, #7aa7ff));\n --_on-accent: var(--tes-color-on-accent, light-dark(#ffffff, #0d1117));\n --_hover: var(--tes-color-hover, light-dark(#eef3fb, #232a36));\n --_focus: var(--tes-color-focus, light-dark(#0b5fcc, #7aa7ff));\n --_error: var(--tes-color-error, light-dark(#c4232b, #ff8a80));\n --_success: var(--tes-color-success, light-dark(#1f7a3a, #4cc26a));\n --_radius: var(--tes-radius, 0.375rem);\n --_space: var(--tes-space, 0.5rem);\n --_control-height: 2.75rem;\n\n display: inline-block;\n color: var(--_text);\n font-family: var(--tes-font-family);\n font-size: var(--tes-font-size);\n}\n\n:where(tes-password[hidden]) {\n display: none;\n}\n\n:where(.tes-password__field) {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: calc(var(--_space) / 2);\n}\n\n:where(.tes-password__label) {\n font-weight: 500;\n}\n\n:where(.tes-password__control) {\n box-sizing: border-box;\n display: flex;\n block-size: var(--_control-height);\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n background: var(--_bg);\n}\n\n:where(.tes-password__control--invalid) {\n border: 2px solid var(--_error);\n}\n\n:where(.tes-password__control:has(.tes-password__input:focus-visible)) {\n outline: 2px solid var(--_focus);\n outline-offset: 2px;\n}\n\n:where(.tes-password__input) {\n box-sizing: border-box;\n flex: 1;\n min-inline-size: 0;\n margin: 0;\n padding-inline: 0.75rem;\n border: 0;\n border-radius: var(--_radius);\n outline: none;\n background: transparent;\n color: var(--_text);\n font: inherit;\n font-size: max(1em, 16px);\n}\n\n:where(.tes-password__toggle) {\n display: grid;\n place-items: center;\n flex: none;\n min-inline-size: 2.75rem;\n margin: 0;\n padding-inline: 0.75rem;\n border: 0;\n border-radius: var(--_radius);\n background: transparent;\n color: var(--_accent);\n font: inherit;\n font-weight: 500;\n cursor: pointer;\n}\n\n:where(.tes-password__control:has(.tes-password__input:disabled)) {\n background: color-mix(in srgb, var(--_muted) 12%, var(--_bg));\n}\n\n:where(.tes-password__input:disabled) {\n color: var(--_muted);\n cursor: not-allowed;\n}\n\n:where(.tes-password__input:disabled ~ .tes-password__toggle) {\n display: none;\n}\n\n:where(.tes-password__toggle-text) {\n grid-area: 1 / 1;\n}\n\n:where(.tes-password__toggle-text--inactive) {\n visibility: hidden;\n}\n\n:where(.tes-password__toggle:hover) {\n background: var(--_hover);\n}\n\n:where(.tes-password__toggle:focus-visible) {\n outline: 2px solid var(--_focus);\n outline-offset: -2px;\n}\n\n:where(.tes-password__hint) {\n margin: 0;\n padding-block-start: 0.25rem;\n color: var(--_muted);\n font-size: 0.875em;\n}\n\n:where(.tes-password__caps-lock) {\n margin: 0;\n padding-block-start: 0.25rem;\n font-size: 0.875em;\n font-weight: 500;\n}\n\n:where(.tes-password__requirements) {\n padding-block-start: 0.25rem;\n color: var(--_muted);\n font-size: 0.875em;\n}\n\n:where(.tes-password__requirements-title) {\n margin: 0;\n}\n\n:where(.tes-password__requirements-list) {\n display: grid;\n gap: 0.125rem;\n margin: 0.25rem 0 0;\n padding: 0;\n list-style: none;\n}\n\n:where(.tes-password__requirement) {\n display: flex;\n gap: 0.375rem;\n align-items: center;\n margin: 0;\n}\n\n:where(.tes-password__requirement--met) {\n color: var(--_text);\n}\n\n:where(.tes-password__icon) {\n flex: none;\n inline-size: 1em;\n block-size: 1em;\n fill: none;\n stroke: currentColor;\n stroke-width: 1.5;\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n\n:where(.tes-password__icon--met) {\n stroke: var(--_success);\n stroke-width: 2;\n}\n\n:where(.tes-password__error) {\n margin: 0;\n color: var(--_error);\n font-size: 0.875em;\n font-weight: 500;\n}\n\n:where(.tes-password__error:empty) {\n display: none;\n}\n\n:where(.tes-password__visually-hidden) {\n position: absolute;\n inline-size: 1px;\n block-size: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n}\n\n@media (forced-colors: active) {\n :where(.tes-password__control:has(.tes-password__input:focus-visible)),\n :where(.tes-password__toggle:focus-visible) {\n outline-color: Highlight;\n }\n\n :where(.tes-password__input:disabled) {\n color: GrayText;\n }\n}\n","import css from './tes-password.css?inline'\n\nconst HOST_SELECTOR = ':where(tes-password'\n\nexport function stylesFor(tagName: string): string {\n return css.replaceAll(HOST_SELECTOR, `:where(${tagName}`)\n}\n\nexport function adoptStyles(tagName: string): void {\n if (typeof document === 'undefined' || typeof CSSStyleSheet === 'undefined') return\n\n const sheet = new CSSStyleSheet()\n sheet.replaceSync(stylesFor(tagName))\n document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]\n}\n","import { TesPasswordElement } from './element'\nimport { adoptStyles } from './styles'\n\nexport { TesPasswordElement }\n\nexport const TAG_NAME = 'tes-password'\n\nexport function define(tagName: string = TAG_NAME): void {\n if (typeof customElements === 'undefined' || customElements.get(tagName)) return\n\n const registryAllowsOneTagPerConstructor = class extends TesPasswordElement {}\n customElements.define(\n tagName,\n tagName === TAG_NAME ? TesPasswordElement : registryAllowsOneTagPerConstructor,\n )\n adoptStyles(tagName)\n}\n\ndefine()\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tes-password': TesPasswordElement\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tes-password.js","names":["_openBlock","_createElementBlock","_createElementVNode","_unref","_toDisplayString","_normalizeClass","_withModifiers","_createCommentVNode","_Fragment","_renderList","_sfc_main","TesPasswordComponent","css","TYPING_PAUSE_MS","EMPTY_REGION_GAP_MS","useAnnouncer","announcement","ref","pending","clear","announceNow","message","announceOnceTypingPauses","onBeforeUnmount","useCustomStates","customStates","internals","name","active","states","useCapsLock","capsLockOn","readCapsLock","on","event","props","forgetCapsLock","AUTOCOMPLETE","isPurpose","value","resolvePurpose","autocompleteFor","explicit","purpose","CHARACTER_CLASSES","CLASS_PATTERNS","APPLE_CLASS_NAMES","positiveInteger","number","isCharacterClass","resolveRuleOptions","minLength","raw","maxLength","names","characterLength","checkRequirements","options","requirementsMet","check","isTooLong","passwordRules","useFieldOptions","computed","ruleOptions","usePublicEvents","dispatch","detail","host","requirementChanges","wasMet","previous","changed","current","useRequirements","checks","items","ruleText","announcedChecks","userChangePending","requirement","describeChanges","changes","reportUserChange","watch","useReveal","revealed","inputType","toggleLabel","toggleByUser","hide","hideForOwnForm","input","onMounted","validatePassword","customError","required","texts","useValidation","error","state","visibleError","markEdited","revealErrors","revealErrorsIfEdited","forgetErrorsForOwnForm","watchEffect","useValueSync","syncFromInput","syncAfterOwnFormReset","instanceCount","nextInstanceId","prefix","TES_PASSWORD_DEFAULTS","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","VueTesPassword","defineCustomElement","defineComponent","__props","attrs","useAttrs","useHost","useTemplateRef","inputId","requirementsId","capsLockId","hintId","errorId","defaultValue","describedBy","ids","requirementItems","handleUserInput","dispatchInput","disabled","item","leaveField","openBlock","createElementBlock","createElementVNode","unref","toDisplayString","normalizeClass","autocomplete","rulesForPasswordManagers","withModifiers","_cache","args","dispatchChange","createCommentVNode","Fragment","renderList","TesPasswordElement","reactive","initialProps","tes_password_default","HOST_SELECTOR","stylesFor","tagName","adoptStyles","sheet","TAG_NAME","define","registryAllowsOneTagPerConstructor"],"sources":["../../shared/src/use-announcer.ts","../../shared/src/use-custom-states.ts","../src/composables/use-caps-lock.ts","../src/core/purpose.ts","../src/core/rules.ts","../src/composables/use-field-options.ts","../src/composables/use-public-events.ts","../src/core/changes.ts","../src/composables/use-requirements.ts","../src/composables/use-reveal.ts","../src/core/validation.ts","../src/composables/use-validation.ts","../src/composables/use-value-sync.ts","../src/core/ids.ts","../src/props.ts","../src/TesPassword.vue","../src/TesPassword.vue","../src/element.ts","../src/tes-password.css?inline","../src/styles.ts","../src/index.ts"],"sourcesContent":["import { type Ref, onBeforeUnmount, ref } from 'vue'\n\nconst TYPING_PAUSE_MS = 500\n// Chromium batches accessibility updates per frame, so emptying and refilling the region in one task\n// is a no-op for a repeated message. The gap makes the empty state reach the accessibility tree.\nconst EMPTY_REGION_GAP_MS = 100\n\nexport interface Announcer {\n announcement: Ref<string>\n announceNow: (message: string) => void\n announceOnceTypingPauses: (message: () => string) => void\n clear: () => void\n}\n\nexport function useAnnouncer(): Announcer {\n const announcement = ref('')\n let pending: ReturnType<typeof setTimeout> | undefined\n\n function clear(): void {\n clearTimeout(pending)\n announcement.value = ''\n }\n\n function announceNow(message: string): void {\n clear()\n pending = setTimeout(() => {\n announcement.value = message\n }, EMPTY_REGION_GAP_MS)\n }\n\n function announceOnceTypingPauses(message: () => string): void {\n clear()\n pending = setTimeout(() => {\n announcement.value = message()\n }, TYPING_PAUSE_MS)\n }\n\n onBeforeUnmount(() => clearTimeout(pending))\n\n return { announcement, announceNow, announceOnceTypingPauses, clear }\n}\n","import { watchEffect } from 'vue'\n\nexport function useCustomStates<State extends string>(\n internals: ElementInternals,\n states: () => Record<State, boolean>,\n): void {\n watchEffect(() => {\n const customStates = internals.states\n if (!customStates) return\n\n for (const [name, active] of Object.entries<boolean>(states())) {\n if (active) customStates.add(name)\n else customStates.delete(name)\n }\n })\n}\n","import { ref } from 'vue'\nimport type { ResolvedTesPasswordProps } from '../props'\n\ninterface CapsLockOptions {\n props: ResolvedTesPasswordProps\n announceNow: (message: string) => void\n}\n\nexport function useCapsLock({ props, announceNow }: CapsLockOptions) {\n const capsLockOn = ref(false)\n\n function readCapsLock(event: KeyboardEvent | PointerEvent): void {\n const on = event.getModifierState('CapsLock')\n if (on && !capsLockOn.value) announceNow(props.textCapsLock)\n capsLockOn.value = on\n }\n\n function forgetCapsLock(): void {\n capsLockOn.value = false\n }\n\n return { capsLockOn, readCapsLock, forgetCapsLock }\n}\n","export type Purpose = 'current' | 'new'\n\nconst AUTOCOMPLETE: Record<Purpose, string> = {\n current: 'current-password',\n new: 'new-password',\n}\n\nexport function isPurpose(value: unknown): value is Purpose {\n return value === 'current' || value === 'new'\n}\n\nexport function resolvePurpose(value: unknown): Purpose {\n return isPurpose(value) ? value : 'current'\n}\n\nexport function autocompleteFor(purpose: Purpose, explicit: string | undefined): string {\n return explicit?.trim() ? explicit : AUTOCOMPLETE[purpose]\n}\n","export type CharacterClass = 'lowercase' | 'uppercase' | 'digit' | 'symbol'\nexport type Requirement = 'length' | CharacterClass\n\nexport interface RuleOptions {\n minLength: number\n maxLength: number | null\n classes: CharacterClass[]\n unknown: string[]\n}\n\nexport interface RequirementCheck {\n requirement: Requirement\n met: boolean\n}\n\nexport const DEFAULT_MIN_LENGTH = 8\n\nconst CHARACTER_CLASSES: readonly CharacterClass[] = ['lowercase', 'uppercase', 'digit', 'symbol']\n\nconst CLASS_PATTERNS: Record<CharacterClass, RegExp> = {\n lowercase: /\\p{Ll}/u,\n uppercase: /[\\p{Lu}\\p{Lt}]/u,\n digit: /\\p{Nd}/u,\n symbol: /[^\\p{L}\\p{N}\\s]/u,\n}\n\nconst APPLE_CLASS_NAMES: Record<CharacterClass, string> = {\n lowercase: 'lower',\n uppercase: 'upper',\n digit: 'digit',\n symbol: 'special',\n}\n\nfunction positiveInteger(value: unknown): number | null {\n if (value === null || value === undefined || value === '') return null\n const number = Number(value)\n return Number.isInteger(number) && number > 0 ? number : null\n}\n\nfunction isCharacterClass(name: string): name is CharacterClass {\n return (CHARACTER_CLASSES as readonly string[]).includes(name)\n}\n\nexport function resolveRuleOptions(raw: { minlength?: unknown; maxlength?: unknown; requirements?: unknown }): RuleOptions {\n const minLength = positiveInteger(raw.minlength) ?? DEFAULT_MIN_LENGTH\n const maxLength = positiveInteger(raw.maxlength)\n const names = String(raw.requirements ?? '')\n .toLowerCase()\n .split(/[\\s,]+/)\n .filter(Boolean)\n\n return {\n minLength,\n maxLength: maxLength !== null && maxLength >= minLength ? maxLength : null,\n classes: CHARACTER_CLASSES.filter((name) => names.includes(name)),\n unknown: [...new Set(names.filter((name) => !isCharacterClass(name)))],\n }\n}\n\nexport function characterLength(value: string): number {\n return [...value].length\n}\n\nexport function checkRequirements(value: string, options: RuleOptions): RequirementCheck[] {\n return [\n { requirement: 'length', met: characterLength(value) >= options.minLength },\n ...options.classes.map((name) => ({ requirement: name, met: CLASS_PATTERNS[name].test(value) })),\n ]\n}\n\nexport function requirementsMet(value: string, options: RuleOptions): boolean {\n return checkRequirements(value, options).every((check) => check.met)\n}\n\nexport function isTooLong(value: string, options: RuleOptions): boolean {\n return options.maxLength !== null && characterLength(value) > options.maxLength\n}\n\nexport function passwordRules(options: RuleOptions): string {\n const rules = [\n `minlength: ${options.minLength};`,\n options.maxLength !== null && `maxlength: ${options.maxLength};`,\n ...options.classes.map((name) => `required: ${APPLE_CLASS_NAMES[name]};`),\n 'allowed: lower, upper, digit, special;',\n ]\n return rules.filter(Boolean).join(' ')\n}\n","import { computed, watchEffect } from 'vue'\nimport { autocompleteFor, isPurpose, resolvePurpose } from '../core/purpose'\nimport { passwordRules, resolveRuleOptions } from '../core/rules'\nimport type { TesPasswordProps } from '../props'\n\nexport function useFieldOptions(props: Readonly<TesPasswordProps>) {\n const purpose = computed(() => resolvePurpose(props.purpose))\n\n const ruleOptions = computed(() =>\n purpose.value === 'new'\n ? resolveRuleOptions({ minlength: props.minlength, maxlength: props.maxlength, requirements: props.requirements })\n : null,\n )\n\n const autocomplete = computed(() => autocompleteFor(purpose.value, props.autocomplete))\n const rulesForPasswordManagers = computed(() => (ruleOptions.value ? passwordRules(ruleOptions.value) : undefined))\n\n if (import.meta.env.DEV) {\n watchEffect(() => {\n if (props.purpose !== undefined && !isPurpose(props.purpose)) {\n console.warn(`[tes-password] \\`purpose\\` must be \"current\" or \"new\". Using \"current\".`)\n }\n const unknown = ruleOptions.value?.unknown ?? []\n if (unknown.length > 0) {\n console.warn(`[tes-password] Unknown requirements ignored: ${unknown.join(', ')}.`)\n }\n const hasRules = props.minlength !== undefined || props.maxlength !== undefined || Boolean(props.requirements)\n if (purpose.value === 'current' && hasRules) {\n console.warn('[tes-password] `minlength`, `maxlength` and `requirements` only apply with `purpose=\"new\"`.')\n }\n })\n }\n\n return { purpose, ruleOptions, autocomplete, rulesForPasswordManagers }\n}\n","import type { TesPasswordElement } from '../element'\n\nexport function usePublicEvents(host: TesPasswordElement) {\n function dispatch(name: 'input' | 'change'): void {\n const detail = { value: host.value, requirementsMet: host.requirementsMet }\n host.dispatchEvent(new CustomEvent(name, { bubbles: true, composed: true, detail }))\n }\n\n return {\n dispatchInput: () => dispatch('input'),\n dispatchChange: () => dispatch('change'),\n }\n}\n","import type { Requirement, RequirementCheck } from './rules'\n\nexport interface RequirementChanges {\n met: Requirement[]\n unmet: Requirement[]\n allMet: boolean\n}\n\nexport function requirementChanges(previous: RequirementCheck[], current: RequirementCheck[]): RequirementChanges | null {\n const wasMet = new Map(previous.map((check) => [check.requirement, check.met]))\n const changed = current.filter((check) => wasMet.get(check.requirement) !== check.met)\n if (changed.length === 0) return null\n\n return {\n met: changed.filter((check) => check.met).map((check) => check.requirement),\n unmet: changed.filter((check) => !check.met).map((check) => check.requirement),\n allMet: current.every((check) => check.met),\n }\n}\n","import { type ComputedRef, computed, watch } from 'vue'\nimport { type RequirementChanges, requirementChanges } from '../core/changes'\nimport { type Requirement, type RequirementCheck, type RuleOptions, checkRequirements } from '../core/rules'\nimport type { TesPasswordElement } from '../element'\nimport type { ResolvedTesPasswordProps } from '../props'\n\ninterface RequirementsOptions {\n host: TesPasswordElement\n props: ResolvedTesPasswordProps\n ruleOptions: ComputedRef<RuleOptions | null>\n announceOnceTypingPauses: (message: () => string) => void\n}\n\nexport interface RequirementItem {\n requirement: Requirement\n met: boolean\n text: string\n}\n\nexport function useRequirements({ host, props, ruleOptions, announceOnceTypingPauses }: RequirementsOptions) {\n const checks = computed<RequirementCheck[]>(() =>\n ruleOptions.value ? checkRequirements(host.state.value, ruleOptions.value) : [],\n )\n\n const items = computed<RequirementItem[]>(() =>\n checks.value.map((check) => ({ ...check, text: ruleText(check.requirement) })),\n )\n\n let announcedChecks = checks.value\n let userChangePending = false\n\n function ruleText(requirement: Requirement): string {\n const texts: Record<Requirement, string> = {\n length: props.textRuleLength.replaceAll('{minlength}', String(ruleOptions.value?.minLength ?? '')),\n lowercase: props.textRuleLowercase,\n uppercase: props.textRuleUppercase,\n digit: props.textRuleDigit,\n symbol: props.textRuleSymbol,\n }\n return texts[requirement]\n }\n\n function describeChanges(changes: RequirementChanges): string {\n if (changes.allMet) return props.textAllMet\n return checks.value\n .filter((check) => changes.met.includes(check.requirement) || changes.unmet.includes(check.requirement))\n .map((check) => `${ruleText(check.requirement)}, ${check.met ? props.textRuleMet : props.textRuleUnmet}`)\n .join('. ')\n }\n\n function reportUserChange(): void {\n if (!ruleOptions.value) return\n userChangePending = true\n announceOnceTypingPauses(() => {\n userChangePending = false\n const changes = requirementChanges(announcedChecks, checks.value)\n announcedChecks = checks.value\n return changes ? describeChanges(changes) : ''\n })\n }\n\n watch(checks, (current) => {\n if (!userChangePending) announcedChecks = current\n })\n\n return { requirementItems: items, reportUserChange }\n}\n","import { type Ref, computed, onBeforeUnmount, onMounted } from 'vue'\nimport type { TesPasswordElement } from '../element'\nimport type { ResolvedTesPasswordProps } from '../props'\n\ninterface RevealOptions {\n host: TesPasswordElement\n props: ResolvedTesPasswordProps\n input: Readonly<Ref<HTMLInputElement | null>>\n announceNow: (message: string) => void\n}\n\nexport function useReveal({ host, props, input, announceNow }: RevealOptions) {\n\n const revealed = computed(() => host.state.revealed)\n const inputType = computed(() => (revealed.value ? 'text' : 'password'))\n const toggleLabel = computed(() => (revealed.value ? props.textHideLabel : props.textShowLabel))\n\n function toggleByUser(): void {\n host.revealed = !host.revealed\n announceNow(host.revealed ? props.textShown : props.textHidden)\n }\n\n function hide(): void {\n host.revealed = false\n }\n\n function hideForOwnForm(event: Event): void {\n if (event.target === input.value?.form) hide()\n }\n\n onMounted(() => {\n window.addEventListener('submit', hideForOwnForm, true)\n window.addEventListener('reset', hideForOwnForm, true)\n window.addEventListener('pagehide', hide)\n })\n\n onBeforeUnmount(() => {\n window.removeEventListener('submit', hideForOwnForm, true)\n window.removeEventListener('reset', hideForOwnForm, true)\n window.removeEventListener('pagehide', hide)\n })\n\n return { revealed, inputType, toggleLabel, toggleByUser }\n}\n","import { type RuleOptions, isTooLong, requirementsMet } from './rules'\n\nexport interface PasswordValidationInput {\n value: string\n required: boolean\n ruleOptions: RuleOptions | null\n customError: string\n}\n\nexport interface PasswordValidationTexts {\n required: string\n unmet: string\n tooLong: string\n}\n\nexport interface PasswordValidationError {\n flag: 'customError' | 'valueMissing' | 'tooLong' | 'unmet'\n message: string\n}\n\nexport function validatePassword(\n { value, required, ruleOptions, customError }: PasswordValidationInput,\n texts: PasswordValidationTexts,\n): PasswordValidationError | null {\n if (customError) return { flag: 'customError', message: customError }\n if (value === '') return required ? { flag: 'valueMissing', message: texts.required } : null\n if (!ruleOptions) return null\n if (isTooLong(value, ruleOptions)) {\n return { flag: 'tooLong', message: texts.tooLong.replaceAll('{maxlength}', String(ruleOptions.maxLength)) }\n }\n if (!requirementsMet(value, ruleOptions)) return { flag: 'unmet', message: texts.unmet }\n return null\n}\n","import { type ComputedRef, type Ref, computed, onBeforeUnmount, onMounted, watchEffect } from 'vue'\nimport type { RuleOptions } from '../core/rules'\nimport { validatePassword } from '../core/validation'\nimport type { TesPasswordElement } from '../element'\nimport type { ResolvedTesPasswordProps } from '../props'\n\ninterface ValidationOptions {\n host: TesPasswordElement\n props: ResolvedTesPasswordProps\n input: Readonly<Ref<HTMLInputElement | null>>\n ruleOptions: ComputedRef<RuleOptions | null>\n}\n\nexport function useValidation({ host, props, input, ruleOptions }: ValidationOptions) {\n const { state } = host\n\n const error = computed(() =>\n validatePassword(\n { value: state.value, required: props.required, ruleOptions: ruleOptions.value, customError: state.customError },\n { required: props.textRequired, unmet: props.textUnmet, tooLong: props.textTooLong },\n ),\n )\n\n const visibleError = computed(() => (state.errorsVisible ? error.value : null))\n\n function markEdited(): void {\n state.edited = true\n state.customError = ''\n }\n\n function revealErrors(): void {\n state.errorsVisible = true\n }\n\n function revealErrorsIfEdited(): void {\n if (state.edited) revealErrors()\n }\n\n function forgetErrorsForOwnForm(event: Event): void {\n if (event.target !== input.value?.form) return\n state.edited = false\n state.errorsVisible = false\n state.customError = ''\n }\n\n watchEffect(() => input.value?.setCustomValidity(error.value?.message ?? ''), { flush: 'sync' })\n\n onMounted(() => window.addEventListener('reset', forgetErrorsForOwnForm, true))\n onBeforeUnmount(() => window.removeEventListener('reset', forgetErrorsForOwnForm, true))\n\n return { visibleError, markEdited, revealErrors, revealErrorsIfEdited }\n}\n","import { type Ref, onBeforeUnmount, onMounted } from 'vue'\nimport type { TesPasswordElement } from '../element'\n\ninterface ValueSyncOptions {\n host: TesPasswordElement\n input: Readonly<Ref<HTMLInputElement | null>>\n}\n\nexport function useValueSync({ host, input }: ValueSyncOptions) {\n function syncFromInput(): void {\n if (input.value) host.state.value = input.value.value\n }\n\n function syncAfterOwnFormReset(event: Event): void {\n if (event.target === input.value?.form) setTimeout(syncFromInput)\n }\n\n onMounted(() => {\n syncFromInput()\n window.addEventListener('reset', syncAfterOwnFormReset, true)\n })\n\n onBeforeUnmount(() => window.removeEventListener('reset', syncAfterOwnFormReset, true))\n\n return { syncFromInput }\n}\n","let instanceCount = 0\n\nexport function nextInstanceId(prefix: string): string {\n instanceCount += 1\n return `${prefix}-${instanceCount}`\n}\n","import type { Purpose } from './core/purpose'\n\nexport interface TesPasswordProps {\n label?: string\n name?: string\n hint?: string\n required?: boolean\n disabled?: boolean\n readonly?: boolean\n purpose?: Purpose\n minlength?: number\n maxlength?: number\n requirements?: string\n autocomplete?: string\n textShow?: string\n textHide?: string\n textShowLabel?: string\n textHideLabel?: string\n textShown?: string\n textHidden?: string\n textRequirements?: string\n textRuleLength?: string\n textRuleLowercase?: string\n textRuleUppercase?: string\n textRuleDigit?: string\n textRuleSymbol?: string\n textRuleMet?: string\n textRuleUnmet?: string\n textAllMet?: string\n textCapsLock?: string\n textRequired?: string\n textUnmet?: string\n textTooLong?: string\n}\n\nexport const TES_PASSWORD_DEFAULTS = {\n required: false,\n disabled: false,\n readonly: false,\n textShow: 'Show',\n textHide: 'Hide',\n textShowLabel: 'Show password',\n textHideLabel: 'Hide password',\n textShown: 'Your password is shown',\n textHidden: 'Your password is hidden',\n textRequirements: 'Your password must have:',\n textRuleLength: 'At least {minlength} characters',\n textRuleLowercase: 'A lowercase letter',\n textRuleUppercase: 'An uppercase letter',\n textRuleDigit: 'A number',\n textRuleSymbol: 'A symbol, like ! or #',\n textRuleMet: 'done',\n textRuleUnmet: 'not yet',\n textAllMet: 'All requirements met',\n textCapsLock: 'Caps Lock is on',\n textRequired: 'Enter a password',\n textUnmet: 'Your password does not meet all the requirements',\n textTooLong: 'Use {maxlength} characters or fewer',\n}\n\nexport type ResolvedTesPasswordProps = Readonly<TesPasswordProps & typeof TES_PASSWORD_DEFAULTS>\n","<template>\n <div class=\"tes-password__field\">\n <label :for=\"inputId\" class=\"tes-password__label\">{{ label }}</label>\n <div class=\"tes-password__control\" :class=\"{ 'tes-password__control--invalid': visibleError }\">\n <input\n :id=\"inputId\"\n ref=\"input\"\n class=\"tes-password__input\"\n :type=\"inputType\"\n :name=\"name\"\n :value.attr=\"defaultValue\"\n :autocomplete=\"autocomplete\"\n :passwordrules=\"rulesForPasswordManagers\"\n :aria-describedby=\"describedBy\"\n :aria-invalid=\"visibleError ? 'true' : undefined\"\n :required=\"required\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n spellcheck=\"false\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n @input.stop=\"handleUserInput\"\n @change.stop=\"dispatchChange\"\n @keydown=\"readCapsLock\"\n @keyup=\"readCapsLock\"\n @pointerdown=\"readCapsLock\"\n @blur=\"leaveField\"\n @invalid=\"revealErrors\"\n />\n <button type=\"button\" class=\"tes-password__toggle\" :aria-label=\"toggleLabel\" @click=\"toggleByUser\">\n <span class=\"tes-password__toggle-text\" :class=\"{ 'tes-password__toggle-text--inactive': revealed }\">{{\n textShow\n }}</span>\n <span class=\"tes-password__toggle-text\" :class=\"{ 'tes-password__toggle-text--inactive': !revealed }\">{{\n textHide\n }}</span>\n </button>\n </div>\n <p v-if=\"hint\" :id=\"hintId\" class=\"tes-password__hint\">{{ hint }}</p>\n <p v-if=\"capsLockOn\" :id=\"capsLockId\" class=\"tes-password__caps-lock\">{{ textCapsLock }}</p>\n <div v-if=\"requirementItems.length\" :id=\"requirementsId\" class=\"tes-password__requirements\">\n <p class=\"tes-password__requirements-title\">{{ textRequirements }}</p>\n <ul class=\"tes-password__requirements-list\">\n <li\n v-for=\"item in requirementItems\"\n :key=\"item.requirement\"\n class=\"tes-password__requirement\"\n :class=\"{ 'tes-password__requirement--met': item.met }\"\n >\n <svg\n v-if=\"item.met\"\n class=\"tes-password__icon tes-password__icon--met\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M3.5 8.5l3 3 6-7\" />\n </svg>\n <svg\n v-else\n class=\"tes-password__icon tes-password__icon--unmet\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle cx=\"8\" cy=\"8\" r=\"5\" />\n </svg>\n <span>{{ item.text }}</span\n ><span class=\"tes-password__visually-hidden\">, {{ item.met ? textRuleMet : textRuleUnmet }}</span>\n </li>\n </ul>\n </div>\n <p :id=\"errorId\" class=\"tes-password__error\" aria-live=\"polite\">{{ visibleError?.message }}</p>\n <div role=\"status\" class=\"tes-password__visually-hidden\">{{ announcement }}</div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useAnnouncer, useCustomStates } from '@teselia/shared'\nimport { computed, useAttrs, useHost, useTemplateRef, watch } from 'vue'\nimport { useCapsLock } from './composables/use-caps-lock'\nimport { useFieldOptions } from './composables/use-field-options'\nimport { usePublicEvents } from './composables/use-public-events'\nimport { useRequirements } from './composables/use-requirements'\nimport { useReveal } from './composables/use-reveal'\nimport { useValidation } from './composables/use-validation'\nimport { useValueSync } from './composables/use-value-sync'\nimport { nextInstanceId } from './core/ids'\nimport type { TesPasswordElement } from './element'\nimport { TES_PASSWORD_DEFAULTS, type TesPasswordProps } from './props'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<TesPasswordProps>(), TES_PASSWORD_DEFAULTS)\nconst attrs = useAttrs()\nconst host = useHost() as TesPasswordElement\nconst input = useTemplateRef<HTMLInputElement>('input')\n\nconst inputId = nextInstanceId('tes-password')\nconst requirementsId = `${inputId}-requirements`\nconst capsLockId = `${inputId}-caps-lock`\nconst hintId = `${inputId}-hint`\nconst errorId = `${inputId}-error`\nconst defaultValue = computed(() => (typeof attrs.value === 'string' ? attrs.value : undefined))\n\nconst { announcement, announceNow, announceOnceTypingPauses } = useAnnouncer()\nconst { ruleOptions, autocomplete, rulesForPasswordManagers } = useFieldOptions(props)\nconst { revealed, inputType, toggleLabel, toggleByUser } = useReveal({ host, props, input, announceNow })\nconst { syncFromInput } = useValueSync({ host, input })\nconst { requirementItems, reportUserChange } = useRequirements({\n host,\n props,\n ruleOptions,\n announceOnceTypingPauses,\n})\n\nconst { capsLockOn, readCapsLock, forgetCapsLock } = useCapsLock({ props, announceNow })\n\nconst { visibleError, markEdited, revealErrors, revealErrorsIfEdited } = useValidation({\n host,\n props,\n input,\n ruleOptions,\n})\n\nconst describedBy = computed(() => {\n const ids = [\n props.hint && hintId,\n requirementItems.value.length > 0 && requirementsId,\n capsLockOn.value && capsLockId,\n visibleError.value && errorId,\n ].filter(Boolean)\n return ids.length > 0 ? ids.join(' ') : undefined\n})\n\nconst { dispatchInput, dispatchChange } = usePublicEvents(host)\n\nfunction handleUserInput(): void {\n markEdited()\n syncFromInput()\n reportUserChange()\n dispatchInput()\n}\n\nwatch(\n () => props.disabled,\n (disabled) => {\n if (disabled) host.revealed = false\n },\n)\n\nuseCustomStates(host.internals, () => ({\n invalid: visibleError.value !== null,\n empty: host.state.value === '',\n revealed: revealed.value,\n 'requirements-met': requirementItems.value.length > 0 && requirementItems.value.every((item) => item.met),\n 'caps-lock': capsLockOn.value,\n}))\n\nfunction leaveField(): void {\n forgetCapsLock()\n revealErrorsIfEdited()\n}\n\nif (import.meta.env.DEV && !props.label) {\n console.warn('[tes-password] The `label` attribute is required for an accessible name.')\n}\n</script>\n","<template>\n <div class=\"tes-password__field\">\n <label :for=\"inputId\" class=\"tes-password__label\">{{ label }}</label>\n <div class=\"tes-password__control\" :class=\"{ 'tes-password__control--invalid': visibleError }\">\n <input\n :id=\"inputId\"\n ref=\"input\"\n class=\"tes-password__input\"\n :type=\"inputType\"\n :name=\"name\"\n :value.attr=\"defaultValue\"\n :autocomplete=\"autocomplete\"\n :passwordrules=\"rulesForPasswordManagers\"\n :aria-describedby=\"describedBy\"\n :aria-invalid=\"visibleError ? 'true' : undefined\"\n :required=\"required\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n spellcheck=\"false\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n @input.stop=\"handleUserInput\"\n @change.stop=\"dispatchChange\"\n @keydown=\"readCapsLock\"\n @keyup=\"readCapsLock\"\n @pointerdown=\"readCapsLock\"\n @blur=\"leaveField\"\n @invalid=\"revealErrors\"\n />\n <button type=\"button\" class=\"tes-password__toggle\" :aria-label=\"toggleLabel\" @click=\"toggleByUser\">\n <span class=\"tes-password__toggle-text\" :class=\"{ 'tes-password__toggle-text--inactive': revealed }\">{{\n textShow\n }}</span>\n <span class=\"tes-password__toggle-text\" :class=\"{ 'tes-password__toggle-text--inactive': !revealed }\">{{\n textHide\n }}</span>\n </button>\n </div>\n <p v-if=\"hint\" :id=\"hintId\" class=\"tes-password__hint\">{{ hint }}</p>\n <p v-if=\"capsLockOn\" :id=\"capsLockId\" class=\"tes-password__caps-lock\">{{ textCapsLock }}</p>\n <div v-if=\"requirementItems.length\" :id=\"requirementsId\" class=\"tes-password__requirements\">\n <p class=\"tes-password__requirements-title\">{{ textRequirements }}</p>\n <ul class=\"tes-password__requirements-list\">\n <li\n v-for=\"item in requirementItems\"\n :key=\"item.requirement\"\n class=\"tes-password__requirement\"\n :class=\"{ 'tes-password__requirement--met': item.met }\"\n >\n <svg\n v-if=\"item.met\"\n class=\"tes-password__icon tes-password__icon--met\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M3.5 8.5l3 3 6-7\" />\n </svg>\n <svg\n v-else\n class=\"tes-password__icon tes-password__icon--unmet\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle cx=\"8\" cy=\"8\" r=\"5\" />\n </svg>\n <span>{{ item.text }}</span\n ><span class=\"tes-password__visually-hidden\">, {{ item.met ? textRuleMet : textRuleUnmet }}</span>\n </li>\n </ul>\n </div>\n <p :id=\"errorId\" class=\"tes-password__error\" aria-live=\"polite\">{{ visibleError?.message }}</p>\n <div role=\"status\" class=\"tes-password__visually-hidden\">{{ announcement }}</div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useAnnouncer, useCustomStates } from '@teselia/shared'\nimport { computed, useAttrs, useHost, useTemplateRef, watch } from 'vue'\nimport { useCapsLock } from './composables/use-caps-lock'\nimport { useFieldOptions } from './composables/use-field-options'\nimport { usePublicEvents } from './composables/use-public-events'\nimport { useRequirements } from './composables/use-requirements'\nimport { useReveal } from './composables/use-reveal'\nimport { useValidation } from './composables/use-validation'\nimport { useValueSync } from './composables/use-value-sync'\nimport { nextInstanceId } from './core/ids'\nimport type { TesPasswordElement } from './element'\nimport { TES_PASSWORD_DEFAULTS, type TesPasswordProps } from './props'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<TesPasswordProps>(), TES_PASSWORD_DEFAULTS)\nconst attrs = useAttrs()\nconst host = useHost() as TesPasswordElement\nconst input = useTemplateRef<HTMLInputElement>('input')\n\nconst inputId = nextInstanceId('tes-password')\nconst requirementsId = `${inputId}-requirements`\nconst capsLockId = `${inputId}-caps-lock`\nconst hintId = `${inputId}-hint`\nconst errorId = `${inputId}-error`\nconst defaultValue = computed(() => (typeof attrs.value === 'string' ? attrs.value : undefined))\n\nconst { announcement, announceNow, announceOnceTypingPauses } = useAnnouncer()\nconst { ruleOptions, autocomplete, rulesForPasswordManagers } = useFieldOptions(props)\nconst { revealed, inputType, toggleLabel, toggleByUser } = useReveal({ host, props, input, announceNow })\nconst { syncFromInput } = useValueSync({ host, input })\nconst { requirementItems, reportUserChange } = useRequirements({\n host,\n props,\n ruleOptions,\n announceOnceTypingPauses,\n})\n\nconst { capsLockOn, readCapsLock, forgetCapsLock } = useCapsLock({ props, announceNow })\n\nconst { visibleError, markEdited, revealErrors, revealErrorsIfEdited } = useValidation({\n host,\n props,\n input,\n ruleOptions,\n})\n\nconst describedBy = computed(() => {\n const ids = [\n props.hint && hintId,\n requirementItems.value.length > 0 && requirementsId,\n capsLockOn.value && capsLockId,\n visibleError.value && errorId,\n ].filter(Boolean)\n return ids.length > 0 ? ids.join(' ') : undefined\n})\n\nconst { dispatchInput, dispatchChange } = usePublicEvents(host)\n\nfunction handleUserInput(): void {\n markEdited()\n syncFromInput()\n reportUserChange()\n dispatchInput()\n}\n\nwatch(\n () => props.disabled,\n (disabled) => {\n if (disabled) host.revealed = false\n },\n)\n\nuseCustomStates(host.internals, () => ({\n invalid: visibleError.value !== null,\n empty: host.state.value === '',\n revealed: revealed.value,\n 'requirements-met': requirementItems.value.length > 0 && requirementItems.value.every((item) => item.met),\n 'caps-lock': capsLockOn.value,\n}))\n\nfunction leaveField(): void {\n forgetCapsLock()\n revealErrorsIfEdited()\n}\n\nif (import.meta.env.DEV && !props.label) {\n console.warn('[tes-password] The `label` attribute is required for an accessible name.')\n}\n</script>\n","import { defineCustomElement, reactive } from 'vue'\nimport TesPasswordComponent from './TesPassword.vue'\nimport { resolvePurpose } from './core/purpose'\nimport { requirementsMet, resolveRuleOptions } from './core/rules'\n\nexport interface TesPasswordState {\n revealed: boolean\n value: string\n edited: boolean\n errorsVisible: boolean\n customError: string\n}\n\nconst VueTesPassword = defineCustomElement(TesPasswordComponent, { shadowRoot: false })\n\nexport class TesPasswordElement extends VueTesPassword {\n readonly state: TesPasswordState = reactive({\n revealed: false,\n value: '',\n edited: false,\n errorsVisible: false,\n customError: '',\n })\n\n readonly internals: ElementInternals\n\n private pendingValue: string | null = null\n\n constructor(initialProps?: Record<string, unknown>) {\n super(initialProps)\n this.internals = this.attachInternals()\n }\n\n get revealed(): boolean {\n return this.state.revealed\n }\n\n set revealed(revealed: boolean) {\n if (revealed === this.state.revealed) return\n this.state.revealed = revealed\n this.syncInputType()\n this.dispatchEvent(new CustomEvent('revealchange', { bubbles: true, composed: true, detail: { revealed } }))\n }\n\n get value(): string {\n return this.input?.value ?? this.pendingValue ?? this.defaultValue\n }\n\n set value(value: string) {\n const input = this.input\n if (input) input.value = value\n else this.pendingValue = value\n this.state.value = value\n }\n\n get requirementsMet(): boolean {\n if (resolvePurpose(this.getAttribute('purpose')) !== 'new') return true\n const options = resolveRuleOptions({\n minlength: this.getAttribute('minlength'),\n maxlength: this.getAttribute('maxlength'),\n requirements: this.getAttribute('requirements'),\n })\n return requirementsMet(this.state.value, options)\n }\n\n get defaultValue(): string {\n return this.getAttribute('value') ?? ''\n }\n\n set defaultValue(value: string) {\n this.setAttribute('value', value)\n }\n\n get minLength(): number {\n return resolveRuleOptions({ minlength: this.getAttribute('minlength') }).minLength\n }\n\n set minLength(value: number) {\n this.setAttribute('minlength', String(value))\n }\n\n get maxLength(): number {\n return resolveRuleOptions({ minlength: 1, maxlength: this.getAttribute('maxlength') }).maxLength ?? -1\n }\n\n set maxLength(value: number) {\n this.setAttribute('maxlength', String(value))\n }\n\n get readOnly(): boolean {\n return this.hasAttribute('readonly')\n }\n\n set readOnly(value: boolean) {\n this.toggleAttribute('readonly', value)\n }\n\n get form(): HTMLFormElement | null {\n return this.input?.form ?? null\n }\n\n get validity(): ValidityState {\n return (this.input ?? document.createElement('input')).validity\n }\n\n get validationMessage(): string {\n return this.input?.validationMessage ?? ''\n }\n\n get willValidate(): boolean {\n return this.input?.willValidate ?? false\n }\n\n setCustomValidity(message: string): void {\n this.state.customError = message\n if (message) this.state.errorsVisible = true\n }\n\n checkValidity(): boolean {\n return this.input?.checkValidity() ?? true\n }\n\n reportValidity(): boolean {\n return this.input?.reportValidity() ?? true\n }\n\n override connectedCallback(): void {\n super.connectedCallback()\n this.applyPendingValue()\n }\n\n override focus(options?: FocusOptions): void {\n this.input?.focus(options)\n }\n\n private get input(): HTMLInputElement | null {\n return this.querySelector<HTMLInputElement>('.tes-password__input')\n }\n\n private syncInputType(): void {\n const input = this.input\n if (input) input.type = this.state.revealed ? 'text' : 'password'\n }\n\n private applyPendingValue(): void {\n const input = this.input\n if (!input || this.pendingValue === null) return\n input.value = this.pendingValue\n this.state.value = this.pendingValue\n this.pendingValue = null\n }\n}\n",":where(tes-password) {\n --_text: var(--tes-color-text, light-dark(#1f2328, #e8eaee));\n --_muted: var(--tes-color-muted, light-dark(#59636e, #a3adba));\n --_bg: var(--tes-color-bg, light-dark(#ffffff, #16181d));\n --_border: var(--tes-color-border, light-dark(#7d8590, #7f8a99));\n --_accent: var(--tes-color-accent, light-dark(#0b5fcc, #7aa7ff));\n --_on-accent: var(--tes-color-on-accent, light-dark(#ffffff, #0d1117));\n --_hover: var(--tes-color-hover, light-dark(#eef3fb, #232a36));\n --_focus: var(--tes-color-focus, light-dark(#0b5fcc, #7aa7ff));\n --_error: var(--tes-color-error, light-dark(#c4232b, #ff8a80));\n --_success: var(--tes-color-success, light-dark(#1f7a3a, #4cc26a));\n --_radius: var(--tes-radius, 0.375rem);\n --_space: var(--tes-space, 0.5rem);\n --_control-height: 2.75rem;\n\n display: inline-block;\n color: var(--_text);\n font-family: var(--tes-font-family);\n font-size: var(--tes-font-size);\n}\n\n:where(tes-password[hidden]) {\n display: none;\n}\n\n:where(.tes-password__field) {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: calc(var(--_space) / 2);\n}\n\n:where(.tes-password__label) {\n font-weight: 500;\n}\n\n:where(.tes-password__control) {\n box-sizing: border-box;\n display: flex;\n block-size: var(--_control-height);\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n background: var(--_bg);\n}\n\n:where(.tes-password__control--invalid) {\n border: 2px solid var(--_error);\n}\n\n:where(.tes-password__control:has(.tes-password__input:focus-visible)) {\n outline: 2px solid var(--_focus);\n outline-offset: 2px;\n}\n\n:where(.tes-password__input) {\n box-sizing: border-box;\n flex: 1;\n min-inline-size: 0;\n margin: 0;\n padding-inline: 0.75rem;\n border: 0;\n border-radius: var(--_radius);\n outline: none;\n background: transparent;\n color: var(--_text);\n font: inherit;\n font-size: max(1em, 16px);\n}\n\n:where(.tes-password__toggle) {\n display: grid;\n place-items: center;\n flex: none;\n min-inline-size: 2.75rem;\n margin: 0;\n padding-inline: 0.75rem;\n border: 0;\n border-radius: var(--_radius);\n background: transparent;\n color: var(--_accent);\n font: inherit;\n font-weight: 500;\n cursor: pointer;\n}\n\n:where(.tes-password__control:has(.tes-password__input:disabled)) {\n background: color-mix(in srgb, var(--_muted) 12%, var(--_bg));\n}\n\n:where(.tes-password__input:disabled) {\n color: var(--_muted);\n cursor: not-allowed;\n}\n\n:where(.tes-password__input:disabled ~ .tes-password__toggle) {\n display: none;\n}\n\n:where(.tes-password__toggle-text) {\n grid-area: 1 / 1;\n}\n\n:where(.tes-password__toggle-text--inactive) {\n visibility: hidden;\n}\n\n:where(.tes-password__toggle:hover) {\n background: var(--_hover);\n}\n\n:where(.tes-password__toggle:focus-visible) {\n outline: 2px solid var(--_focus);\n outline-offset: -2px;\n}\n\n:where(.tes-password__hint) {\n margin: 0;\n padding-block-start: 0.25rem;\n color: var(--_muted);\n font-size: 0.875em;\n}\n\n:where(.tes-password__caps-lock) {\n margin: 0;\n padding-block-start: 0.25rem;\n font-size: 0.875em;\n font-weight: 500;\n}\n\n:where(.tes-password__requirements) {\n padding-block-start: 0.25rem;\n color: var(--_muted);\n font-size: 0.875em;\n}\n\n:where(.tes-password__requirements-title) {\n margin: 0;\n}\n\n:where(.tes-password__requirements-list) {\n display: grid;\n gap: 0.125rem;\n margin: 0.25rem 0 0;\n padding: 0;\n list-style: none;\n}\n\n:where(.tes-password__requirement) {\n display: flex;\n gap: 0.375rem;\n align-items: center;\n margin: 0;\n}\n\n:where(.tes-password__requirement--met) {\n color: var(--_text);\n}\n\n:where(.tes-password__icon) {\n flex: none;\n inline-size: 1em;\n block-size: 1em;\n fill: none;\n stroke: currentColor;\n stroke-width: 1.5;\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n\n:where(.tes-password__icon--met) {\n stroke: var(--_success);\n stroke-width: 2;\n}\n\n:where(.tes-password__error) {\n margin: 0;\n color: var(--_error);\n font-size: 0.875em;\n font-weight: 500;\n}\n\n:where(.tes-password__error:empty) {\n display: none;\n}\n\n:where(.tes-password__visually-hidden) {\n position: absolute;\n inline-size: 1px;\n block-size: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n}\n\n@media (forced-colors: active) {\n :where(.tes-password__control:has(.tes-password__input:focus-visible)),\n :where(.tes-password__toggle:focus-visible) {\n outline-color: Highlight;\n }\n\n :where(.tes-password__input:disabled) {\n color: GrayText;\n }\n}\n","import css from './tes-password.css?inline'\n\nconst HOST_SELECTOR = ':where(tes-password'\n\nexport function stylesFor(tagName: string): string {\n return css.replaceAll(HOST_SELECTOR, `:where(${tagName}`)\n}\n\nexport function adoptStyles(tagName: string): void {\n if (typeof document === 'undefined' || typeof CSSStyleSheet === 'undefined') return\n\n const sheet = new CSSStyleSheet()\n sheet.replaceSync(stylesFor(tagName))\n document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]\n}\n","import { TesPasswordElement } from './element'\nimport { adoptStyles } from './styles'\n\nexport { TesPasswordElement }\n\nexport const TAG_NAME = 'tes-password'\n\nexport function define(tagName: string = TAG_NAME): void {\n if (typeof customElements === 'undefined' || customElements.get(tagName)) return\n\n const registryAllowsOneTagPerConstructor = class extends TesPasswordElement {}\n customElements.define(\n tagName,\n tagName === TAG_NAME ? TesPasswordElement : registryAllowsOneTagPerConstructor,\n )\n adoptStyles(tagName)\n}\n\ndefine()\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tes-password': TesPasswordElement\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teselia/password",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Accessible password input with a show/hide button and live requirements, shipped as a framework-agnostic Web Component. Works with password managers. WCAG 2.2 AA by default.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"password",
|
|
@@ -47,17 +47,17 @@
|
|
|
47
47
|
"vue": "^3.5.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@vitejs/plugin-vue": "^6.0.
|
|
51
|
-
"vite": "^8.3.
|
|
52
|
-
"vue": "^3.5.
|
|
53
|
-
"vue-tsc": "^3.3.
|
|
50
|
+
"@vitejs/plugin-vue": "^6.0.10",
|
|
51
|
+
"vite": "^8.3.6",
|
|
52
|
+
"vue": "^3.5.45",
|
|
53
|
+
"vue-tsc": "^3.3.14",
|
|
54
54
|
"@teselia/shared": "0.0.0"
|
|
55
55
|
},
|
|
56
56
|
"publishConfig": {
|
|
57
57
|
"access": "public"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
|
60
|
-
"build": "vite build && vite build --mode iife && vue-tsc -p tsconfig.build.json && node ../../scripts/check-public-types.mjs",
|
|
60
|
+
"build": "vite build && vite build --mode iife && vue-tsc -p tsconfig.build.json && node ../../scripts/check-public-types.mjs && node ../../scripts/check-built-css.mjs",
|
|
61
61
|
"typecheck": "vue-tsc --noEmit"
|
|
62
62
|
}
|
|
63
63
|
}
|