digitojs 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/LICENSE +21 -0
  3. package/README.md +753 -0
  4. package/dist/adapters/alpine.d.ts +71 -0
  5. package/dist/adapters/alpine.d.ts.map +1 -0
  6. package/dist/adapters/alpine.js +560 -0
  7. package/dist/adapters/alpine.js.map +1 -0
  8. package/dist/adapters/react.d.ts +223 -0
  9. package/dist/adapters/react.d.ts.map +1 -0
  10. package/dist/adapters/react.js +337 -0
  11. package/dist/adapters/react.js.map +1 -0
  12. package/dist/adapters/svelte.d.ts +139 -0
  13. package/dist/adapters/svelte.d.ts.map +1 -0
  14. package/dist/adapters/svelte.js +295 -0
  15. package/dist/adapters/svelte.js.map +1 -0
  16. package/dist/adapters/vanilla.d.ts +110 -0
  17. package/dist/adapters/vanilla.d.ts.map +1 -0
  18. package/dist/adapters/vanilla.js +650 -0
  19. package/dist/adapters/vanilla.js.map +1 -0
  20. package/dist/adapters/vue.d.ts +163 -0
  21. package/dist/adapters/vue.d.ts.map +1 -0
  22. package/dist/adapters/vue.js +298 -0
  23. package/dist/adapters/vue.js.map +1 -0
  24. package/dist/adapters/web-component.d.ts +192 -0
  25. package/dist/adapters/web-component.d.ts.map +1 -0
  26. package/dist/adapters/web-component.js +832 -0
  27. package/dist/adapters/web-component.js.map +1 -0
  28. package/dist/core/feedback.d.ts +26 -0
  29. package/dist/core/feedback.d.ts.map +1 -0
  30. package/dist/core/feedback.js +47 -0
  31. package/dist/core/feedback.js.map +1 -0
  32. package/dist/core/filter.d.ts +24 -0
  33. package/dist/core/filter.d.ts.map +1 -0
  34. package/dist/core/filter.js +47 -0
  35. package/dist/core/filter.js.map +1 -0
  36. package/dist/core/index.d.ts +16 -0
  37. package/dist/core/index.d.ts.map +1 -0
  38. package/dist/core/index.js +15 -0
  39. package/dist/core/index.js.map +1 -0
  40. package/dist/core/machine.d.ts +67 -0
  41. package/dist/core/machine.d.ts.map +1 -0
  42. package/dist/core/machine.js +328 -0
  43. package/dist/core/machine.js.map +1 -0
  44. package/dist/core/timer.d.ts +24 -0
  45. package/dist/core/timer.d.ts.map +1 -0
  46. package/dist/core/timer.js +67 -0
  47. package/dist/core/timer.js.map +1 -0
  48. package/dist/core/types.d.ts +162 -0
  49. package/dist/core/types.d.ts.map +1 -0
  50. package/dist/core/types.js +10 -0
  51. package/dist/core/types.js.map +1 -0
  52. package/dist/digito-wc.min.js +254 -0
  53. package/dist/digito-wc.min.js.map +7 -0
  54. package/dist/digito.min.js +91 -0
  55. package/dist/digito.min.js.map +7 -0
  56. package/dist/index.d.ts +18 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +25 -0
  59. package/dist/index.js.map +1 -0
  60. package/package.json +109 -0
  61. package/src/adapters/alpine.ts +666 -0
  62. package/src/adapters/react.tsx +603 -0
  63. package/src/adapters/svelte.ts +444 -0
  64. package/src/adapters/vanilla.ts +810 -0
  65. package/src/adapters/vue.ts +462 -0
  66. package/src/adapters/web-component.ts +858 -0
  67. package/src/core/feedback.ts +44 -0
  68. package/src/core/filter.ts +48 -0
  69. package/src/core/index.ts +16 -0
  70. package/src/core/machine.ts +373 -0
  71. package/src/core/timer.ts +75 -0
  72. package/src/core/types.ts +167 -0
  73. package/src/index.ts +51 -0
@@ -0,0 +1,139 @@
1
+ /**
2
+ * digito/svelte
3
+ * ─────────────────────────────────────────────────────────────────────────────
4
+ * Svelte adapter — useOTP store + action (single hidden-input architecture)
5
+ *
6
+ * @author Olawale Balo — Product Designer + Design Engineer
7
+ * @license MIT
8
+ */
9
+ import { writable, derived } from 'svelte/store';
10
+ import { type DigitoOptions } from '../core/index.js';
11
+ /**
12
+ * Extended options for the Svelte useOTP composable.
13
+ * Adds controlled-input, separator, and disabled support on top of DigitoOptions.
14
+ */
15
+ export type SvelteOTPOptions = DigitoOptions & {
16
+ /**
17
+ * Controlled value — drives the slot state from outside the composable.
18
+ * Pass a string of up to length characters to pre-fill or sync the field.
19
+ */
20
+ value?: string;
21
+ /**
22
+ * Fires exactly ONCE per user interaction with the current joined code string.
23
+ * Receives partial values too — not just when the code is complete.
24
+ */
25
+ onChange?: (code: string) => void;
26
+ /**
27
+ * Insert a purely visual separator after this slot index (0-based).
28
+ * Accepts a single position or an array for multiple separators.
29
+ * aria-hidden, never part of the value, no effect on the state machine.
30
+ * Default: 0 (no separator).
31
+ * @example separatorAfter: 3 -> [*][*][*] — [*][*][*]
32
+ * @example separatorAfter: [2, 4] -> [*][*] — [*][*] — [*][*]
33
+ */
34
+ separatorAfter?: number | number[];
35
+ /**
36
+ * The character or string to render as the separator.
37
+ * Default: '—'
38
+ */
39
+ separator?: string;
40
+ /**
41
+ * When `true`, slot templates should display a mask glyph instead of the real
42
+ * character. The hidden input switches to `type="password"` via the action.
43
+ *
44
+ * `getCode()` and `onComplete` always return real characters.
45
+ * Use for PIN entry or any sensitive input flow.
46
+ *
47
+ * Default: `false`.
48
+ */
49
+ masked?: boolean;
50
+ /**
51
+ * The glyph displayed in filled slots when `masked` is `true`.
52
+ * Returned as a `writable` store so Svelte templates can subscribe to it.
53
+ *
54
+ * Default: `'●'` (U+25CF BLACK CIRCLE).
55
+ * @example maskChar: '*'
56
+ */
57
+ maskChar?: string;
58
+ };
59
+ export type UseOTPResult = {
60
+ /** Subscribe to the full state store. */
61
+ subscribe: ReturnType<typeof writable>['subscribe'];
62
+ /** Derived — joined code string. */
63
+ value: ReturnType<typeof derived>;
64
+ /** Derived — completion boolean. */
65
+ isComplete: ReturnType<typeof derived>;
66
+ /** Derived — error boolean. */
67
+ hasError: ReturnType<typeof derived>;
68
+ /** Derived — active slot index. */
69
+ activeSlot: ReturnType<typeof derived>;
70
+ /** Remaining timer seconds store. */
71
+ timerSeconds: ReturnType<typeof writable>;
72
+ /** Whether the field is currently disabled. */
73
+ isDisabled: ReturnType<typeof writable>;
74
+ /** The separator slot index store. -1 = no separator. */
75
+ separatorAfter: ReturnType<typeof writable>;
76
+ /** The separator character store. */
77
+ separator: ReturnType<typeof writable>;
78
+ /** Whether masked mode is active. When true, templates should render `maskChar` instead of char. */
79
+ masked: ReturnType<typeof writable>;
80
+ /**
81
+ * The configured mask glyph store. Use in templates instead of a hard-coded `●`:
82
+ * `{$otp.masked && char ? $otp.maskChar : char}`
83
+ */
84
+ maskChar: ReturnType<typeof writable>;
85
+ /** The placeholder character for empty slots. Empty string when not set. */
86
+ placeholder: string;
87
+ /** Svelte action to bind to the single hidden input. */
88
+ action: (node: HTMLInputElement) => {
89
+ destroy: () => void;
90
+ };
91
+ /** Returns the current joined code string. */
92
+ getCode: () => string;
93
+ /** Clear all slots, restart timer, return focus to input. */
94
+ reset: () => void;
95
+ /** Apply or clear the error state. */
96
+ setError: (isError: boolean) => void;
97
+ /** Enable or disable the field at runtime. */
98
+ setDisabled: (value: boolean) => void;
99
+ /** Programmatically move focus to a slot index. */
100
+ focus: (slotIndex: number) => void;
101
+ /**
102
+ * Programmatically set the field value without triggering `onComplete`.
103
+ * Pass `undefined` to no-op. Filters the incoming string through the current
104
+ * `type`/`pattern` before distribution, identical to controlled-value sync.
105
+ */
106
+ setValue: (v: string | undefined) => void;
107
+ };
108
+ /**
109
+ * Svelte composable for OTP input — single hidden-input architecture.
110
+ *
111
+ * @example
112
+ * ```svelte
113
+ * <script>
114
+ * import { useOTP } from 'digito/svelte'
115
+ * const otp = useOTP({ length: 6, onComplete: (code) => verify(code) })
116
+ * $: state = $otp
117
+ * </script>
118
+ *
119
+ * <div style="position:relative; display:inline-flex; gap:8px; align-items:center">
120
+ * <input
121
+ * use:otp.action
122
+ * style="position:absolute;inset:0;opacity:0;z-index:1;cursor:text"
123
+ * />
124
+ * {#each state.slotValues as char, i}
125
+ * {#if $otp.separatorAfter > 0 && i === $otp.separatorAfter}
126
+ * <span aria-hidden="true">{$otp.separator}</span>
127
+ * {/if}
128
+ * <div class="slot"
129
+ * class:is-active={i === state.activeSlot}
130
+ * class:is-filled={!!char}
131
+ * class:is-error={state.hasError}
132
+ * class:is-disabled={$otp.isDisabled}
133
+ * >{char}</div>
134
+ * {/each}
135
+ * </div>
136
+ * ```
137
+ */
138
+ export declare function useOTP(options?: SvelteOTPOptions): UseOTPResult;
139
+ //# sourceMappingURL=svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svelte.d.ts","sourceRoot":"","sources":["../../src/adapters/svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAO,MAAM,cAAc,CAAA;AAErD,OAAO,EAIL,KAAK,aAAa,EAGnB,MAAM,kBAAkB,CAAA;AAOzB;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG;IAC7C;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAClC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,yCAAyC;IACzC,SAAS,EAAO,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAA;IACxD,oCAAoC;IACpC,KAAK,EAAW,UAAU,CAAC,OAAO,OAAO,CAAC,CAAA;IAC1C,oCAAoC;IACpC,UAAU,EAAM,UAAU,CAAC,OAAO,OAAO,CAAC,CAAA;IAC1C,+BAA+B;IAC/B,QAAQ,EAAQ,UAAU,CAAC,OAAO,OAAO,CAAC,CAAA;IAC1C,mCAAmC;IACnC,UAAU,EAAM,UAAU,CAAC,OAAO,OAAO,CAAC,CAAA;IAC1C,qCAAqC;IACrC,YAAY,EAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAA;IAC3C,+CAA+C;IAC/C,UAAU,EAAM,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAA;IAC3C,yDAAyD;IACzD,cAAc,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAA;IAC3C,qCAAqC;IACrC,SAAS,EAAO,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAA;IAC3C,oGAAoG;IACpG,MAAM,EAAU,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAA;IAC3C;;;OAGG;IACH,QAAQ,EAAQ,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAA;IAC3C,4EAA4E;IAC5E,WAAW,EAAK,MAAM,CAAA;IACtB,wDAAwD;IACxD,MAAM,EAAU,CAAC,IAAI,EAAE,gBAAgB,KAAK;QAAE,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,CAAA;IACnE,8CAA8C;IAC9C,OAAO,EAAS,MAAM,MAAM,CAAA;IAC5B,6DAA6D;IAC7D,KAAK,EAAW,MAAM,IAAI,CAAA;IAC1B,sCAAsC;IACtC,QAAQ,EAAQ,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IAC1C,8CAA8C;IAC9C,WAAW,EAAK,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IACxC,mDAAmD;IACnD,KAAK,EAAW,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C;;;;OAIG;IACH,QAAQ,EAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAA;CAChD,CAAA;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,MAAM,CAAC,OAAO,GAAE,gBAAqB,GAAG,YAAY,CA8RnE"}
@@ -0,0 +1,295 @@
1
+ /**
2
+ * digito/svelte
3
+ * ─────────────────────────────────────────────────────────────────────────────
4
+ * Svelte adapter — useOTP store + action (single hidden-input architecture)
5
+ *
6
+ * @author Olawale Balo — Product Designer + Design Engineer
7
+ * @license MIT
8
+ */
9
+ import { writable, derived, get } from 'svelte/store';
10
+ import { createDigito, createTimer, filterString, } from '../core/index.js';
11
+ // ─────────────────────────────────────────────────────────────────────────────
12
+ // COMPOSABLE
13
+ // ─────────────────────────────────────────────────────────────────────────────
14
+ /**
15
+ * Svelte composable for OTP input — single hidden-input architecture.
16
+ *
17
+ * @example
18
+ * ```svelte
19
+ * <script>
20
+ * import { useOTP } from 'digito/svelte'
21
+ * const otp = useOTP({ length: 6, onComplete: (code) => verify(code) })
22
+ * $: state = $otp
23
+ * </script>
24
+ *
25
+ * <div style="position:relative; display:inline-flex; gap:8px; align-items:center">
26
+ * <input
27
+ * use:otp.action
28
+ * style="position:absolute;inset:0;opacity:0;z-index:1;cursor:text"
29
+ * />
30
+ * {#each state.slotValues as char, i}
31
+ * {#if $otp.separatorAfter > 0 && i === $otp.separatorAfter}
32
+ * <span aria-hidden="true">{$otp.separator}</span>
33
+ * {/if}
34
+ * <div class="slot"
35
+ * class:is-active={i === state.activeSlot}
36
+ * class:is-filled={!!char}
37
+ * class:is-error={state.hasError}
38
+ * class:is-disabled={$otp.isDisabled}
39
+ * >{char}</div>
40
+ * {/each}
41
+ * </div>
42
+ * ```
43
+ */
44
+ export function useOTP(options = {}) {
45
+ const { length = 6, type = 'numeric', timer: timerSecs = 0, disabled: initialDisabled = false, onComplete, onExpire, onResend, haptic = true, sound = false, pattern, pasteTransformer, onInvalidChar, value: controlledValue, onChange: onChangeProp, onFocus: onFocusProp, onBlur: onBlurProp, separatorAfter: separatorAfterOpt = 0, separator: separatorOpt = '—', masked: maskedOpt = false, maskChar: maskCharOpt = '\u25CF', autoFocus: autoFocusOpt = true, name: nameOpt, placeholder: placeholderOpt = '', selectOnFocus: selectOnFocusOpt = false, blurOnComplete: blurOnCompleteOpt = false, } = options;
46
+ // ── Core instance ──────────────────────────────────────────────────────────
47
+ const digito = createDigito({ length, type, pattern, pasteTransformer, onInvalidChar, onComplete, onExpire, onResend, haptic, sound });
48
+ // ── Stores ─────────────────────────────────────────────────────────────────
49
+ const store = writable(digito.state);
50
+ const timerStore = writable(timerSecs);
51
+ const isDisabledStore = writable(initialDisabled);
52
+ const separatorAfterStore = writable(separatorAfterOpt);
53
+ const separatorStore = writable(separatorOpt);
54
+ const maskedStore = writable(maskedOpt);
55
+ const maskCharStore = writable(maskCharOpt);
56
+ let inputEl = null;
57
+ // ── sync() ─────────────────────────────────────────────────────────────────
58
+ function sync(suppressOnChange = false) {
59
+ const s = digito.state;
60
+ store.set({ ...s });
61
+ if (!suppressOnChange) {
62
+ onChangeProp?.(s.slotValues.join(''));
63
+ }
64
+ }
65
+ // ── Controlled value sync ──────────────────────────────────────────────────
66
+ function setValue(incoming) {
67
+ if (incoming === undefined)
68
+ return;
69
+ const filtered = filterString(incoming.slice(0, length), type, pattern);
70
+ const current = digito.state.slotValues.join('');
71
+ if (filtered === current)
72
+ return;
73
+ digito.resetState();
74
+ for (let i = 0; i < filtered.length; i++) {
75
+ digito.inputChar(i, filtered[i]);
76
+ }
77
+ // Prevent a programmatic fill from triggering onComplete as if the user
78
+ // had typed the code. cancelPendingComplete cancels the 10ms deferred
79
+ // callback scheduled by the final inputChar above.
80
+ digito.cancelPendingComplete();
81
+ sync(true);
82
+ if (inputEl) {
83
+ inputEl.value = filtered;
84
+ inputEl.setSelectionRange(filtered.length, filtered.length);
85
+ }
86
+ onChangeProp?.(filtered);
87
+ }
88
+ if (controlledValue !== undefined) {
89
+ setValue(controlledValue);
90
+ }
91
+ // ── Timer ──────────────────────────────────────────────────────────────────
92
+ let timerControls = null;
93
+ if (timerSecs > 0) {
94
+ timerControls = createTimer({
95
+ totalSeconds: timerSecs,
96
+ onTick: (r) => timerStore.set(r),
97
+ onExpire: () => { timerStore.set(0); onExpire?.(); },
98
+ });
99
+ }
100
+ // ── Svelte Action ──────────────────────────────────────────────────────────
101
+ function action(node) {
102
+ inputEl = node;
103
+ node.type = maskedOpt ? 'password' : 'text';
104
+ node.inputMode = type === 'numeric' ? 'numeric' : 'text';
105
+ node.autocomplete = 'one-time-code';
106
+ node.maxLength = length;
107
+ node.disabled = get(isDisabledStore);
108
+ node.spellcheck = false;
109
+ if (nameOpt)
110
+ node.name = nameOpt;
111
+ node.setAttribute('aria-label', `Enter your ${length}-${type === 'numeric' ? 'digit' : 'character'} code`);
112
+ node.setAttribute('autocorrect', 'off');
113
+ node.setAttribute('autocapitalize', 'off');
114
+ const unsubDisabled = isDisabledStore.subscribe((v) => { node.disabled = v; });
115
+ function onKeydown(e) {
116
+ if (get(isDisabledStore))
117
+ return;
118
+ const pos = node.selectionStart ?? 0;
119
+ if (e.key === 'Backspace') {
120
+ e.preventDefault();
121
+ digito.deleteChar(pos);
122
+ sync();
123
+ const next = digito.state.activeSlot;
124
+ requestAnimationFrame(() => node.setSelectionRange(next, next));
125
+ }
126
+ else if (e.key === 'ArrowLeft') {
127
+ e.preventDefault();
128
+ digito.moveFocusLeft(pos);
129
+ sync();
130
+ const next = digito.state.activeSlot;
131
+ requestAnimationFrame(() => node.setSelectionRange(next, next));
132
+ }
133
+ else if (e.key === 'ArrowRight') {
134
+ e.preventDefault();
135
+ digito.moveFocusRight(pos);
136
+ sync();
137
+ const next = digito.state.activeSlot;
138
+ requestAnimationFrame(() => node.setSelectionRange(next, next));
139
+ }
140
+ else if (e.key === 'Tab') {
141
+ if (e.shiftKey) {
142
+ if (pos === 0)
143
+ return;
144
+ e.preventDefault();
145
+ digito.moveFocusLeft(pos);
146
+ }
147
+ else {
148
+ if (!digito.state.slotValues[pos])
149
+ return;
150
+ if (pos >= length - 1)
151
+ return;
152
+ e.preventDefault();
153
+ digito.moveFocusRight(pos);
154
+ }
155
+ sync();
156
+ const next = digito.state.activeSlot;
157
+ requestAnimationFrame(() => node.setSelectionRange(next, next));
158
+ }
159
+ }
160
+ function onChange(e) {
161
+ if (get(isDisabledStore))
162
+ return;
163
+ const raw = e.target.value;
164
+ if (!raw) {
165
+ digito.resetState();
166
+ node.value = '';
167
+ node.setSelectionRange(0, 0);
168
+ sync();
169
+ return;
170
+ }
171
+ const valid = filterString(raw, type, pattern).slice(0, length);
172
+ digito.resetState();
173
+ for (let i = 0; i < valid.length; i++)
174
+ digito.inputChar(i, valid[i]);
175
+ const next = Math.min(valid.length, length - 1);
176
+ node.value = valid;
177
+ node.setSelectionRange(next, next);
178
+ digito.moveFocusTo(next);
179
+ sync();
180
+ if (blurOnCompleteOpt && digito.state.isComplete) {
181
+ requestAnimationFrame(() => node.blur());
182
+ }
183
+ }
184
+ function onPaste(e) {
185
+ if (get(isDisabledStore))
186
+ return;
187
+ e.preventDefault();
188
+ const text = e.clipboardData?.getData('text') ?? '';
189
+ const pos = node.selectionStart ?? 0;
190
+ digito.pasteString(pos, text);
191
+ const { slotValues, activeSlot } = digito.state;
192
+ node.value = slotValues.join('');
193
+ node.setSelectionRange(activeSlot, activeSlot);
194
+ sync();
195
+ if (blurOnCompleteOpt && digito.state.isComplete) {
196
+ requestAnimationFrame(() => node.blur());
197
+ }
198
+ }
199
+ function onFocus() {
200
+ onFocusProp?.();
201
+ const pos = digito.state.activeSlot;
202
+ requestAnimationFrame(() => {
203
+ const char = digito.state.slotValues[pos];
204
+ if (selectOnFocusOpt && char) {
205
+ node.setSelectionRange(pos, pos + 1);
206
+ }
207
+ else {
208
+ node.setSelectionRange(pos, pos);
209
+ }
210
+ });
211
+ }
212
+ function onBlur() {
213
+ onBlurProp?.();
214
+ }
215
+ node.addEventListener('keydown', onKeydown);
216
+ node.addEventListener('input', onChange);
217
+ node.addEventListener('paste', onPaste);
218
+ node.addEventListener('focus', onFocus);
219
+ node.addEventListener('blur', onBlur);
220
+ if (autoFocusOpt && !get(isDisabledStore)) {
221
+ requestAnimationFrame(() => node.focus());
222
+ }
223
+ // Start timer now that the component is mounted and the input element is
224
+ // available — matching Vue's onMounted pattern.
225
+ timerControls?.start();
226
+ return {
227
+ destroy() {
228
+ node.removeEventListener('keydown', onKeydown);
229
+ node.removeEventListener('input', onChange);
230
+ node.removeEventListener('paste', onPaste);
231
+ node.removeEventListener('focus', onFocus);
232
+ node.removeEventListener('blur', onBlur);
233
+ unsubDisabled();
234
+ timerControls?.stop();
235
+ inputEl = null;
236
+ },
237
+ };
238
+ }
239
+ // ── Public API ─────────────────────────────────────────────────────────────
240
+ function reset() {
241
+ digito.resetState();
242
+ if (inputEl) {
243
+ inputEl.value = '';
244
+ inputEl.focus();
245
+ inputEl.setSelectionRange(0, 0);
246
+ }
247
+ timerStore.set(timerSecs);
248
+ timerControls?.restart();
249
+ sync();
250
+ }
251
+ function setError(isError) {
252
+ digito.setError(isError);
253
+ sync(true);
254
+ }
255
+ function setDisabled(value) {
256
+ isDisabledStore.set(value);
257
+ digito.setDisabled(value);
258
+ }
259
+ function focus(slotIndex) {
260
+ digito.moveFocusTo(slotIndex);
261
+ inputEl?.focus();
262
+ requestAnimationFrame(() => inputEl?.setSelectionRange(slotIndex, slotIndex));
263
+ sync(true);
264
+ }
265
+ function getCode() {
266
+ return digito.getCode();
267
+ }
268
+ // Derived stores
269
+ const value = derived(store, ($s) => $s.slotValues.join(''));
270
+ const isComplete = derived(store, ($s) => $s.isComplete);
271
+ const hasError = derived(store, ($s) => $s.hasError);
272
+ const activeSlot = derived(store, ($s) => $s.activeSlot);
273
+ return {
274
+ subscribe: store.subscribe,
275
+ value,
276
+ isComplete,
277
+ hasError,
278
+ activeSlot,
279
+ timerSeconds: timerStore,
280
+ isDisabled: isDisabledStore,
281
+ separatorAfter: separatorAfterStore,
282
+ separator: separatorStore,
283
+ masked: maskedStore,
284
+ maskChar: maskCharStore,
285
+ placeholder: placeholderOpt,
286
+ action,
287
+ getCode,
288
+ reset,
289
+ setError,
290
+ setDisabled,
291
+ setValue,
292
+ focus,
293
+ };
294
+ }
295
+ //# sourceMappingURL=svelte.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svelte.js","sourceRoot":"","sources":["../../src/adapters/svelte.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * digito/vanilla
3
+ * ─────────────────────────────────────────────────────────────────────────────
4
+ * DOM adapter using the single-hidden-input architecture.
5
+ *
6
+ * Architecture:
7
+ * One real <input> sits invisibly behind the visual slot divs.
8
+ * It captures ALL keyboard input, paste, and native SMS autofill.
9
+ * The visual slot <div>s are pure mirrors — they display characters
10
+ * from the hidden input's value, show a fake caret on the active slot,
11
+ * and forward click events to focus the real input.
12
+ *
13
+ * Why this is better than multiple inputs:
14
+ * - autocomplete="one-time-code" works as native single-input autofill
15
+ * - iOS SMS autofill works without any hacks
16
+ * - Screen readers see one real input — perfect a11y
17
+ * - No focus-juggling between inputs on every keystroke
18
+ * - Password managers can't confuse the slots for separate fields
19
+ *
20
+ * Web OTP API:
21
+ * When supported (Android Chrome), navigator.credentials.get is called
22
+ * automatically to intercept the SMS OTP code without any user interaction.
23
+ * The AbortController is wired to destroy() so the request is cancelled
24
+ * on cleanup. Falls back gracefully in all other environments.
25
+ *
26
+ * Two timer modes:
27
+ * Built-in UI — omit onTick. Digito renders "Code expires in [0:60]"
28
+ * and "Didn't receive the code? Resend" automatically.
29
+ * Custom UI — pass onTick. Digito fires the callback and skips its timer.
30
+ *
31
+ * @author Olawale Balo — Product Designer + Design Engineer
32
+ * @license MIT
33
+ */
34
+ import { type DigitoOptions } from '../core/index.js';
35
+ export { createTimer } from '../core/index.js';
36
+ /** The control surface returned by initDigito for each mounted wrapper. */
37
+ export type DigitoInstance = {
38
+ /** Clear all slots, restart timer, focus the hidden input. */
39
+ reset: () => void;
40
+ /** Reset + fire onResend callback. */
41
+ resend: () => void;
42
+ /** Apply or clear the error state on all visual slots. */
43
+ setError: (isError: boolean) => void;
44
+ /** Apply or clear the success state on all visual slots. */
45
+ setSuccess: (isSuccess: boolean) => void;
46
+ /**
47
+ * Enable or disable the input. When disabled, all keypresses and pastes are
48
+ * silently ignored and the hidden input is set to disabled. Use during async
49
+ * verification to prevent the user from modifying the code mid-request.
50
+ */
51
+ setDisabled: (isDisabled: boolean) => void;
52
+ /** Returns the current joined code string. */
53
+ getCode: () => string;
54
+ /** Programmatically move focus to a slot index (focuses the hidden input). */
55
+ focus: (slotIndex: number) => void;
56
+ /** Remove all event listeners and stop the timer. */
57
+ destroy: () => void;
58
+ };
59
+ /**
60
+ * Vanilla-only options that extend the core DigitoOptions.
61
+ * These are not part of the shared adapter API.
62
+ */
63
+ export type VanillaOnlyOptions = Partial<DigitoOptions> & {
64
+ /**
65
+ * Insert a purely visual separator after this slot index (0-based).
66
+ * The separator is aria-hidden, never enters the value, and has no effect on state.
67
+ * Accepts a single position or an array for multiple separators.
68
+ * Default: 0 (no separator).
69
+ * @example separatorAfter: 3 -> [ ][ ][ ] — [ ][ ][ ] (6-slot field)
70
+ * @example separatorAfter: [2, 4] -> [ ][ ] — [ ][ ] — [ ][ ]
71
+ */
72
+ separatorAfter?: number | number[];
73
+ /**
74
+ * The character or string to render as the separator.
75
+ * Default: '—'
76
+ */
77
+ separator?: string;
78
+ /**
79
+ * When `true`, each filled slot displays a mask glyph instead of the real
80
+ * character. The hidden input switches to `type="password"` so the OS keyboard
81
+ * and browser autocomplete treat it as a sensitive field.
82
+ *
83
+ * `getCode()` and `onComplete` always return the real characters — masking is
84
+ * purely visual. Use for PIN entry or any flow where the value should not be
85
+ * visible to shoulder-surfers.
86
+ *
87
+ * Default: `false`.
88
+ */
89
+ masked?: boolean;
90
+ /**
91
+ * The glyph displayed in filled slots when `masked` is `true`.
92
+ * Allows substituting the default bullet with any character of your choice
93
+ * (e.g. `'*'`, `'•'`, `'x'`).
94
+ *
95
+ * Readable via the `data-mask-char` HTML attribute:
96
+ * `<div class="digito-wrapper" data-mask-char="*">`.
97
+ *
98
+ * Default: `'●'` (U+25CF BLACK CIRCLE).
99
+ */
100
+ maskChar?: string;
101
+ };
102
+ /**
103
+ * Mount digito on one or more wrapper elements.
104
+ *
105
+ * @param target CSS selector or HTMLElement. Default: '.digito-wrapper'
106
+ * @param options Runtime options — supplement or override data attributes.
107
+ * @returns Array of DigitoInstance objects, one per wrapper found.
108
+ */
109
+ export declare function initDigito(target?: string | HTMLElement, options?: VanillaOnlyOptions): DigitoInstance[];
110
+ //# sourceMappingURL=vanilla.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vanilla.d.ts","sourceRoot":"","sources":["../../src/adapters/vanilla.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAM9C,2EAA2E;AAC3E,MAAM,MAAM,cAAc,GAAG;IAC3B,8DAA8D;IAC9D,KAAK,EAAS,MAAM,IAAI,CAAA;IACxB,sCAAsC;IACtC,MAAM,EAAQ,MAAM,IAAI,CAAA;IACxB,0DAA0D;IAC1D,QAAQ,EAAM,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IACxC,4DAA4D;IAC5D,UAAU,EAAI,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAA;IAC1C;;;;OAIG;IACH,WAAW,EAAG,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAA;IAC3C,8CAA8C;IAC9C,OAAO,EAAO,MAAM,MAAM,CAAA;IAC1B,8EAA8E;IAC9E,KAAK,EAAS,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IACzC,qDAAqD;IACrD,OAAO,EAAO,MAAM,IAAI,CAAA;CACzB,CAAA;AAoED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG;IACxD;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAClC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,MAAM,GAAG,MAAM,GAAG,WAA+B,EACjD,OAAO,GAAE,kBAAuB,GAC/B,cAAc,EAAE,CAQlB"}