@radix-ui/react-one-time-password-field 0.1.0-rc.1744661316162

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,612 @@
1
+ "use strict";
2
+ "use client";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/index.ts
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ HiddenInput: () => HiddenInput,
35
+ Input: () => Input,
36
+ OneTimePasswordField: () => OneTimePasswordField,
37
+ OneTimePasswordFieldHiddenInput: () => OneTimePasswordFieldHiddenInput,
38
+ OneTimePasswordFieldInput: () => OneTimePasswordFieldInput,
39
+ Root: () => Root2
40
+ });
41
+ module.exports = __toCommonJS(index_exports);
42
+
43
+ // src/one-time-password-field.tsx
44
+ var import_react_primitive = require("@radix-ui/react-primitive");
45
+ var import_react_compose_refs = require("@radix-ui/react-compose-refs");
46
+ var import_react_use_controllable_state = require("@radix-ui/react-use-controllable-state");
47
+ var import_primitive = require("@radix-ui/primitive");
48
+ var import_react_collection = require("@radix-ui/react-collection");
49
+ var RovingFocusGroup = __toESM(require("@radix-ui/react-roving-focus"));
50
+ var import_react_roving_focus = require("@radix-ui/react-roving-focus");
51
+ var import_react_use_is_hydrated = require("@radix-ui/react-use-is-hydrated");
52
+ var React = __toESM(require("react"));
53
+ var import_react_dom = require("react-dom");
54
+ var import_react_context = require("@radix-ui/react-context");
55
+ var import_react_direction = require("@radix-ui/react-direction");
56
+ var import_number = require("@radix-ui/number");
57
+ var import_react_use_effect_event = require("@radix-ui/react-use-effect-event");
58
+ var import_jsx_runtime = require("react/jsx-runtime");
59
+ var INPUT_VALIDATION_MAP = {
60
+ numeric: {
61
+ type: "numeric",
62
+ regexp: /[^\d]/g,
63
+ pattern: "\\d{1}",
64
+ inputMode: "numeric"
65
+ },
66
+ alpha: {
67
+ type: "alpha",
68
+ regexp: /[^a-zA-Z]/g,
69
+ pattern: "[a-zA-Z]{1}",
70
+ inputMode: "text"
71
+ },
72
+ alphanumeric: {
73
+ type: "alphanumeric",
74
+ regexp: /[^a-zA-Z0-9]/g,
75
+ pattern: "[a-zA-Z0-9]{1}",
76
+ inputMode: "text"
77
+ }
78
+ };
79
+ var ONE_TIME_PASSWORD_FIELD_NAME = "OneTimePasswordField";
80
+ var [Collection, useCollection, createCollectionScope] = (0, import_react_collection.unstable_createCollection)(
81
+ ONE_TIME_PASSWORD_FIELD_NAME
82
+ );
83
+ var [createOneTimePasswordFieldContext] = (0, import_react_context.createContextScope)(ONE_TIME_PASSWORD_FIELD_NAME, [
84
+ createCollectionScope,
85
+ import_react_roving_focus.createRovingFocusGroupScope
86
+ ]);
87
+ var useRovingFocusGroupScope = (0, import_react_roving_focus.createRovingFocusGroupScope)();
88
+ var [OneTimePasswordFieldContext, useOneTimePasswordFieldContext] = createOneTimePasswordFieldContext(ONE_TIME_PASSWORD_FIELD_NAME);
89
+ var OneTimePasswordFieldCollectionProvider = ({
90
+ __scopeOneTimePasswordField,
91
+ children
92
+ }) => {
93
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.Provider, { scope: __scopeOneTimePasswordField, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.Slot, { scope: __scopeOneTimePasswordField, children }) });
94
+ };
95
+ var OneTimePasswordFieldImpl = React.forwardRef(
96
+ function OneTimePasswordFieldImpl2({
97
+ __scopeOneTimePasswordField,
98
+ id,
99
+ defaultValue,
100
+ value: valueProp,
101
+ onValueChange,
102
+ autoSubmit,
103
+ children,
104
+ onPaste,
105
+ onAutoSubmit,
106
+ disabled = false,
107
+ readOnly = false,
108
+ autoComplete = "one-time-code",
109
+ autoFocus = false,
110
+ form,
111
+ name,
112
+ placeholder,
113
+ required = false,
114
+ type = "password",
115
+ // TODO: Change default to vertical when inputs use vertical writing mode
116
+ orientation = "horizontal",
117
+ dir,
118
+ validationType = "numeric",
119
+ ...domProps
120
+ }, forwardedRef) {
121
+ const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeOneTimePasswordField);
122
+ const direction = (0, import_react_direction.useDirection)(dir);
123
+ const collection = useCollection(__scopeOneTimePasswordField);
124
+ const validation = validationType in INPUT_VALIDATION_MAP ? INPUT_VALIDATION_MAP[validationType] : void 0;
125
+ const controlledValue = React.useMemo(() => {
126
+ return valueProp != null ? sanitizeValue(valueProp, validation?.regexp) : void 0;
127
+ }, [valueProp, validation?.regexp]);
128
+ const [value, setValue] = (0, import_react_use_controllable_state.useControllableState)({
129
+ caller: "OneTimePasswordField",
130
+ prop: controlledValue,
131
+ defaultProp: defaultValue != null ? sanitizeValue(defaultValue, validation?.regexp) : [],
132
+ onChange: (value2) => onValueChange?.(value2.filter(Boolean).join(""))
133
+ });
134
+ const dispatch = (0, import_react_use_effect_event.useEffectEvent)((action) => {
135
+ switch (action.type) {
136
+ case "SET_CHAR": {
137
+ const { index, char } = action;
138
+ const currentTarget = collection.at(index)?.element;
139
+ if (value[index] === char) {
140
+ const next = currentTarget && collection.from(currentTarget, 1)?.element;
141
+ focusInput(next);
142
+ return;
143
+ }
144
+ if (char === "") {
145
+ return;
146
+ }
147
+ if (validation) {
148
+ const regexp = new RegExp(validation.regexp);
149
+ const clean = char.replace(regexp, "");
150
+ if (clean !== char) {
151
+ return;
152
+ }
153
+ }
154
+ if (value.length >= collection.size) {
155
+ const newValue2 = [...value];
156
+ newValue2[index] = char;
157
+ (0, import_react_dom.flushSync)(() => setValue(newValue2));
158
+ const next = currentTarget && collection.from(currentTarget, 1)?.element;
159
+ focusInput(next);
160
+ return;
161
+ }
162
+ const newValue = [
163
+ //
164
+ ...value.slice(0, index),
165
+ char,
166
+ ...value.slice(index)
167
+ ];
168
+ const lastElement = collection.at(-1)?.element;
169
+ (0, import_react_dom.flushSync)(() => setValue(newValue));
170
+ if (currentTarget !== lastElement) {
171
+ const next = currentTarget && collection.from(currentTarget, 1)?.element;
172
+ focusInput(next);
173
+ } else {
174
+ currentTarget?.select();
175
+ }
176
+ return;
177
+ }
178
+ case "CLEAR_CHAR": {
179
+ const { index, reason } = action;
180
+ if (!value[index]) {
181
+ return;
182
+ }
183
+ const newValue = value.filter((_, i) => i !== index);
184
+ const currentTarget = collection.at(index)?.element;
185
+ const previous = currentTarget && collection.from(currentTarget, -1)?.element;
186
+ (0, import_react_dom.flushSync)(() => setValue(newValue));
187
+ if (reason === "Backspace") {
188
+ focusInput(previous);
189
+ } else if (reason === "Delete" || reason === "Cut") {
190
+ focusInput(currentTarget);
191
+ }
192
+ return;
193
+ }
194
+ case "CLEAR": {
195
+ if (value.length === 0) {
196
+ return;
197
+ }
198
+ if (action.reason === "Backspace" || action.reason === "Delete") {
199
+ (0, import_react_dom.flushSync)(() => setValue([]));
200
+ focusInput(collection.at(0)?.element);
201
+ } else {
202
+ setValue([]);
203
+ }
204
+ return;
205
+ }
206
+ case "PASTE": {
207
+ const { value: pastedValue } = action;
208
+ const value2 = sanitizeValue(pastedValue, validation?.regexp);
209
+ if (!value2) {
210
+ return;
211
+ }
212
+ (0, import_react_dom.flushSync)(() => setValue(value2));
213
+ focusInput(collection.at(value2.length - 1)?.element);
214
+ return;
215
+ }
216
+ }
217
+ });
218
+ const validationTypeRef = React.useRef(validation);
219
+ React.useEffect(() => {
220
+ if (!validation) {
221
+ return;
222
+ }
223
+ if (validationTypeRef.current?.type !== validation.type) {
224
+ validationTypeRef.current = validation;
225
+ setValue(sanitizeValue(value, validation.regexp));
226
+ }
227
+ }, [setValue, validation, value]);
228
+ const hiddenInputRef = React.useRef(null);
229
+ const userActionRef = React.useRef(null);
230
+ const rootRef = React.useRef(null);
231
+ const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, rootRef);
232
+ const firstInput = collection.at(0)?.element;
233
+ const locateForm = React.useCallback(() => {
234
+ let formElement;
235
+ if (form) {
236
+ const associatedElement = (rootRef.current?.ownerDocument ?? document).getElementById(form);
237
+ if (isFormElement(associatedElement)) {
238
+ formElement = associatedElement;
239
+ }
240
+ } else if (hiddenInputRef.current) {
241
+ formElement = hiddenInputRef.current.form;
242
+ } else if (firstInput) {
243
+ formElement = firstInput.form;
244
+ }
245
+ return formElement ?? null;
246
+ }, [form, firstInput]);
247
+ const attemptSubmit = React.useCallback(() => {
248
+ const formElement = locateForm();
249
+ formElement?.requestSubmit();
250
+ }, [locateForm]);
251
+ React.useEffect(() => {
252
+ const form2 = locateForm();
253
+ if (form2) {
254
+ const reset = () => dispatch({ type: "CLEAR", reason: "Reset" });
255
+ form2.addEventListener("reset", reset);
256
+ return () => form2.removeEventListener("reset", reset);
257
+ }
258
+ }, [dispatch, locateForm]);
259
+ const currentValue = value.join("");
260
+ const valueRef = React.useRef(currentValue);
261
+ const length = collection.size;
262
+ React.useEffect(() => {
263
+ const previousValue = valueRef.current;
264
+ valueRef.current = currentValue;
265
+ if (previousValue === currentValue) {
266
+ return;
267
+ }
268
+ if (autoSubmit && value.every((char) => char !== "") && value.length === length) {
269
+ onAutoSubmit?.(value.join(""));
270
+ attemptSubmit();
271
+ }
272
+ }, [attemptSubmit, autoSubmit, currentValue, length, onAutoSubmit, value]);
273
+ const preHydrationIndexTracker = React.useRef(0);
274
+ const isHydrated = (0, import_react_use_is_hydrated.useIsHydrated)();
275
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
276
+ OneTimePasswordFieldContext,
277
+ {
278
+ scope: __scopeOneTimePasswordField,
279
+ value,
280
+ attemptSubmit,
281
+ disabled,
282
+ readOnly,
283
+ autoComplete,
284
+ autoFocus,
285
+ form,
286
+ name,
287
+ placeholder,
288
+ required,
289
+ type,
290
+ hiddenInputRef,
291
+ userActionRef,
292
+ dispatch,
293
+ validationType,
294
+ orientation,
295
+ preHydrationIndexTracker,
296
+ isHydrated,
297
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
298
+ RovingFocusGroup.Root,
299
+ {
300
+ asChild: true,
301
+ ...rovingFocusGroupScope,
302
+ orientation,
303
+ dir: direction,
304
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
305
+ import_react_primitive.Primitive.div,
306
+ {
307
+ ...domProps,
308
+ role: "group",
309
+ ref: composedRefs,
310
+ onPaste: (0, import_primitive.composeEventHandlers)(
311
+ onPaste,
312
+ (event) => {
313
+ event.preventDefault();
314
+ const pastedValue = event.clipboardData.getData("Text");
315
+ const value2 = sanitizeValue(pastedValue, validation?.regexp);
316
+ if (!value2) {
317
+ return;
318
+ }
319
+ dispatch({ type: "PASTE", value: pastedValue });
320
+ }
321
+ ),
322
+ children
323
+ }
324
+ )
325
+ }
326
+ )
327
+ }
328
+ );
329
+ }
330
+ );
331
+ var OneTimePasswordField = React.forwardRef(
332
+ function OneTimePasswordField2(props, ref) {
333
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OneTimePasswordFieldCollectionProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OneTimePasswordFieldImpl, { ...props, ref }) });
334
+ }
335
+ );
336
+ var OneTimePasswordFieldHiddenInput = React.forwardRef(function OneTimePasswordFieldHiddenInput2({ __scopeOneTimePasswordField, ...props }, forwardedRef) {
337
+ const { value, hiddenInputRef } = useOneTimePasswordFieldContext(
338
+ "OneTimePasswordFieldHiddenInput",
339
+ __scopeOneTimePasswordField
340
+ );
341
+ const ref = (0, import_react_compose_refs.useComposedRefs)(hiddenInputRef, forwardedRef);
342
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
343
+ "input",
344
+ {
345
+ ref,
346
+ ...props,
347
+ type: "hidden",
348
+ readOnly: true,
349
+ value: value.join("").trim(),
350
+ autoComplete: "off",
351
+ autoFocus: false,
352
+ autoCapitalize: "off",
353
+ autoCorrect: "off",
354
+ autoSave: "off",
355
+ spellCheck: false
356
+ }
357
+ );
358
+ });
359
+ var OneTimePasswordFieldInput = React.forwardRef(function OneTimePasswordFieldInput2({ __scopeOneTimePasswordField, ...props }, forwardedRef) {
360
+ const {
361
+ value: _value,
362
+ defaultValue: _defaultValue,
363
+ disabled: _disabled,
364
+ readOnly: _readOnly,
365
+ autoComplete: _autoComplete,
366
+ autoFocus: _autoFocus,
367
+ form: _form,
368
+ name: _name,
369
+ placeholder: _placeholder,
370
+ required: _required,
371
+ type: _type,
372
+ ...domProps
373
+ } = props;
374
+ const context = useOneTimePasswordFieldContext(
375
+ "OneTimePasswordFieldInput",
376
+ __scopeOneTimePasswordField
377
+ );
378
+ const { dispatch, userActionRef, validationType, preHydrationIndexTracker, isHydrated } = context;
379
+ const collection = useCollection(__scopeOneTimePasswordField);
380
+ const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeOneTimePasswordField);
381
+ const inputRef = React.useRef(null);
382
+ const [element, setElement] = React.useState(null);
383
+ let index;
384
+ if (!isHydrated) {
385
+ index = preHydrationIndexTracker.current;
386
+ preHydrationIndexTracker.current++;
387
+ } else {
388
+ index = element ? collection.indexOf(element) : -1;
389
+ }
390
+ const composedInputRef = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, inputRef, setElement);
391
+ const char = context.value[index] ?? "";
392
+ const keyboardActionTimeoutRef = React.useRef(null);
393
+ React.useEffect(() => {
394
+ return () => {
395
+ window.clearTimeout(keyboardActionTimeoutRef.current);
396
+ };
397
+ }, []);
398
+ const totalValue = context.value.join("").trim();
399
+ const lastSelectableIndex = (0, import_number.clamp)(totalValue.length, [0, collection.size - 1]);
400
+ const isFocusable = index <= lastSelectableIndex;
401
+ const validation = validationType in INPUT_VALIDATION_MAP ? INPUT_VALIDATION_MAP[validationType] : void 0;
402
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.ItemSlot, { scope: __scopeOneTimePasswordField, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
403
+ RovingFocusGroup.Item,
404
+ {
405
+ ...rovingFocusGroupScope,
406
+ asChild: true,
407
+ focusable: !context.disabled && isFocusable,
408
+ active: index === lastSelectableIndex,
409
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
410
+ import_react_primitive.Primitive.input,
411
+ {
412
+ ref: composedInputRef,
413
+ type: "text",
414
+ "aria-label": `Character ${index + 1} of ${collection.size}`,
415
+ autoComplete: index === 0 ? context.autoComplete : "off",
416
+ inputMode: validation?.inputMode,
417
+ maxLength: 1,
418
+ pattern: validation?.pattern,
419
+ readOnly: context.readOnly,
420
+ value: char,
421
+ "data-radix-otp-input": "",
422
+ "data-radix-index": index,
423
+ ...domProps,
424
+ onFocus: (0, import_primitive.composeEventHandlers)(props.onFocus, (event) => {
425
+ event.currentTarget.select();
426
+ }),
427
+ onCut: (0, import_primitive.composeEventHandlers)(props.onCut, (event) => {
428
+ const currentValue = event.currentTarget.value;
429
+ if (currentValue !== "") {
430
+ userActionRef.current = {
431
+ type: "cut"
432
+ };
433
+ keyboardActionTimeoutRef.current = window.setTimeout(() => {
434
+ userActionRef.current = null;
435
+ }, 10);
436
+ }
437
+ }),
438
+ onChange: (0, import_primitive.composeEventHandlers)(props.onChange, (event) => {
439
+ const action = userActionRef.current;
440
+ userActionRef.current = null;
441
+ if (action) {
442
+ switch (action.type) {
443
+ case "cut":
444
+ dispatch({ type: "CLEAR_CHAR", index, reason: "Cut" });
445
+ return;
446
+ case "keydown": {
447
+ if (action.key === "Char") {
448
+ return;
449
+ }
450
+ const isClearing = action.key === "Backspace" && (action.metaKey || action.ctrlKey);
451
+ if (isClearing) {
452
+ dispatch({ type: "CLEAR", reason: "Backspace" });
453
+ } else {
454
+ dispatch({ type: "CLEAR_CHAR", index, reason: action.key });
455
+ }
456
+ return;
457
+ }
458
+ default:
459
+ return;
460
+ }
461
+ }
462
+ if (event.target.validity.valid) {
463
+ if (event.target.value === "") {
464
+ let reason = "Backspace";
465
+ if (isInputEvent(event.nativeEvent)) {
466
+ const inputType = event.nativeEvent.inputType;
467
+ if (inputType === "deleteContentBackward") {
468
+ reason = "Backspace";
469
+ } else if (inputType === "deleteByCut") {
470
+ reason = "Cut";
471
+ }
472
+ }
473
+ dispatch({ type: "CLEAR_CHAR", index, reason });
474
+ } else {
475
+ dispatch({ type: "SET_CHAR", char: event.target.value, index, event });
476
+ }
477
+ } else {
478
+ const element2 = event.target;
479
+ requestAnimationFrame(() => {
480
+ if (element2.ownerDocument.activeElement === element2) {
481
+ element2.select();
482
+ }
483
+ });
484
+ }
485
+ }),
486
+ onKeyDown: (0, import_primitive.composeEventHandlers)(props.onKeyDown, (event) => {
487
+ switch (event.key) {
488
+ case "Delete":
489
+ case "Backspace": {
490
+ const currentValue = event.currentTarget.value;
491
+ if (currentValue === "") {
492
+ if (event.key === "Delete") return;
493
+ const isClearing = event.metaKey || event.ctrlKey;
494
+ if (isClearing) {
495
+ dispatch({ type: "CLEAR", reason: "Backspace" });
496
+ } else {
497
+ const element2 = event.currentTarget;
498
+ requestAnimationFrame(() => {
499
+ focusInput(collection.from(element2, -1)?.element);
500
+ });
501
+ }
502
+ } else {
503
+ userActionRef.current = {
504
+ type: "keydown",
505
+ key: event.key,
506
+ metaKey: event.metaKey,
507
+ ctrlKey: event.ctrlKey
508
+ };
509
+ keyboardActionTimeoutRef.current = window.setTimeout(() => {
510
+ userActionRef.current = null;
511
+ }, 10);
512
+ }
513
+ return;
514
+ }
515
+ case "Enter": {
516
+ event.preventDefault();
517
+ context.attemptSubmit();
518
+ return;
519
+ }
520
+ case "ArrowDown":
521
+ case "ArrowUp": {
522
+ if (context.orientation === "horizontal") {
523
+ event.preventDefault();
524
+ }
525
+ return;
526
+ }
527
+ // TODO: Handle left/right arrow keys in vertical writing mode
528
+ default: {
529
+ if (event.currentTarget.value === event.key) {
530
+ const element2 = event.currentTarget;
531
+ event.preventDefault();
532
+ focusInput(collection.from(element2, 1)?.element);
533
+ return;
534
+ } else if (
535
+ // input already has a value, but...
536
+ event.currentTarget.value && // the value is not selected
537
+ !(event.currentTarget.selectionStart === 0 && event.currentTarget.selectionEnd != null && event.currentTarget.selectionEnd > 0)
538
+ ) {
539
+ const attemptedValue = event.key;
540
+ if (event.key.length > 1 || event.key === " ") {
541
+ return;
542
+ } else {
543
+ const nextInput = collection.from(event.currentTarget, 1)?.element;
544
+ const lastInput = collection.at(-1)?.element;
545
+ if (nextInput !== lastInput && event.currentTarget !== lastInput) {
546
+ if (event.currentTarget.selectionStart === 0) {
547
+ dispatch({ type: "SET_CHAR", char: attemptedValue, index, event });
548
+ } else {
549
+ dispatch({
550
+ type: "SET_CHAR",
551
+ char: attemptedValue,
552
+ index: index + 1,
553
+ event
554
+ });
555
+ }
556
+ userActionRef.current = {
557
+ type: "keydown",
558
+ key: "Char",
559
+ metaKey: event.metaKey,
560
+ ctrlKey: event.ctrlKey
561
+ };
562
+ keyboardActionTimeoutRef.current = window.setTimeout(() => {
563
+ userActionRef.current = null;
564
+ }, 10);
565
+ }
566
+ }
567
+ }
568
+ }
569
+ }
570
+ }),
571
+ onPointerDown: (0, import_primitive.composeEventHandlers)(props.onPointerDown, (event) => {
572
+ if (index > lastSelectableIndex) {
573
+ event.preventDefault();
574
+ const element2 = collection.at(lastSelectableIndex)?.element;
575
+ focusInput(element2);
576
+ }
577
+ })
578
+ }
579
+ )
580
+ }
581
+ ) });
582
+ });
583
+ var Root2 = OneTimePasswordField;
584
+ var Input = OneTimePasswordFieldInput;
585
+ var HiddenInput = OneTimePasswordFieldHiddenInput;
586
+ function isFormElement(element) {
587
+ return element?.tagName === "FORM";
588
+ }
589
+ function sanitizeValue(value, regexp) {
590
+ if (Array.isArray(value)) {
591
+ value = value.join("");
592
+ }
593
+ if (regexp) {
594
+ regexp = new RegExp(regexp);
595
+ return value.replace(regexp, "").split("").filter(Boolean);
596
+ }
597
+ return value.split("").filter(Boolean);
598
+ }
599
+ function focusInput(element) {
600
+ if (!element) return;
601
+ if (element.ownerDocument.activeElement === element) {
602
+ window.requestAnimationFrame(() => {
603
+ element.select?.();
604
+ });
605
+ } else {
606
+ element.focus();
607
+ }
608
+ }
609
+ function isInputEvent(event) {
610
+ return event.type === "input";
611
+ }
612
+ //# sourceMappingURL=index.js.map