jaci-ui 0.2.0 → 0.4.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 (172) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +95 -0
  3. package/dist/components/button-group/button-group.cjs +22 -0
  4. package/dist/components/button-group/button-group.cjs.map +1 -0
  5. package/dist/components/button-group/button-group.d.cts +12 -0
  6. package/dist/components/button-group/button-group.d.ts +12 -0
  7. package/dist/components/button-group/button-group.js +21 -0
  8. package/dist/components/button-group/button-group.js.map +1 -0
  9. package/dist/components/button-group/index.d.cts +2 -0
  10. package/dist/components/button-group/index.d.ts +2 -0
  11. package/dist/components/calendar/calendar.cjs +377 -0
  12. package/dist/components/calendar/calendar.cjs.map +1 -0
  13. package/dist/components/calendar/calendar.d.cts +56 -0
  14. package/dist/components/calendar/calendar.d.ts +56 -0
  15. package/dist/components/calendar/calendar.js +368 -0
  16. package/dist/components/calendar/calendar.js.map +1 -0
  17. package/dist/components/calendar/index.d.cts +2 -0
  18. package/dist/components/calendar/index.d.ts +2 -0
  19. package/dist/components/combobox/combobox.cjs +13 -1
  20. package/dist/components/combobox/combobox.cjs.map +1 -1
  21. package/dist/components/combobox/combobox.d.cts +7 -2
  22. package/dist/components/combobox/combobox.d.ts +7 -2
  23. package/dist/components/combobox/combobox.js +13 -2
  24. package/dist/components/combobox/combobox.js.map +1 -1
  25. package/dist/components/combobox/index.d.cts +2 -2
  26. package/dist/components/combobox/index.d.ts +2 -2
  27. package/dist/components/controls/input.cjs +26 -5
  28. package/dist/components/controls/input.cjs.map +1 -1
  29. package/dist/components/controls/input.d.cts +5 -2
  30. package/dist/components/controls/input.d.ts +5 -2
  31. package/dist/components/controls/input.js +28 -7
  32. package/dist/components/controls/input.js.map +1 -1
  33. package/dist/components/controls/textarea.cjs +26 -5
  34. package/dist/components/controls/textarea.cjs.map +1 -1
  35. package/dist/components/controls/textarea.d.cts +5 -2
  36. package/dist/components/controls/textarea.d.ts +5 -2
  37. package/dist/components/controls/textarea.js +28 -7
  38. package/dist/components/controls/textarea.js.map +1 -1
  39. package/dist/components/date-picker/date-picker.cjs +9 -9
  40. package/dist/components/date-picker/date-picker.cjs.map +1 -1
  41. package/dist/components/date-picker/date-picker.d.cts +3 -1
  42. package/dist/components/date-picker/date-picker.d.ts +3 -1
  43. package/dist/components/date-picker/date-picker.js +9 -9
  44. package/dist/components/date-picker/date-picker.js.map +1 -1
  45. package/dist/components/date-range-picker/date-range-picker.cjs +589 -0
  46. package/dist/components/date-range-picker/date-range-picker.cjs.map +1 -0
  47. package/dist/components/date-range-picker/date-range-picker.d.cts +134 -0
  48. package/dist/components/date-range-picker/date-range-picker.d.ts +134 -0
  49. package/dist/components/date-range-picker/date-range-picker.js +568 -0
  50. package/dist/components/date-range-picker/date-range-picker.js.map +1 -0
  51. package/dist/components/date-range-picker/index.d.cts +2 -0
  52. package/dist/components/date-range-picker/index.d.ts +2 -0
  53. package/dist/components/empty-state/empty-state.cjs +62 -0
  54. package/dist/components/empty-state/empty-state.cjs.map +1 -0
  55. package/dist/components/empty-state/empty-state.d.cts +18 -0
  56. package/dist/components/empty-state/empty-state.d.ts +18 -0
  57. package/dist/components/empty-state/empty-state.js +57 -0
  58. package/dist/components/empty-state/empty-state.js.map +1 -0
  59. package/dist/components/empty-state/index.d.cts +2 -0
  60. package/dist/components/empty-state/index.d.ts +2 -0
  61. package/dist/components/field/field.cjs +106 -11
  62. package/dist/components/field/field.cjs.map +1 -1
  63. package/dist/components/field/field.d.cts +22 -4
  64. package/dist/components/field/field.d.ts +22 -4
  65. package/dist/components/field/field.js +107 -13
  66. package/dist/components/field/field.js.map +1 -1
  67. package/dist/components/field/index.d.cts +2 -2
  68. package/dist/components/field/index.d.ts +2 -2
  69. package/dist/components/icon-button/icon-button.cjs +40 -0
  70. package/dist/components/icon-button/icon-button.cjs.map +1 -0
  71. package/dist/components/icon-button/icon-button.d.cts +12 -0
  72. package/dist/components/icon-button/icon-button.d.ts +12 -0
  73. package/dist/components/icon-button/icon-button.js +40 -0
  74. package/dist/components/icon-button/icon-button.js.map +1 -0
  75. package/dist/components/icon-button/index.d.cts +2 -0
  76. package/dist/components/icon-button/index.d.ts +2 -0
  77. package/dist/components/input-group/index.d.cts +2 -0
  78. package/dist/components/input-group/index.d.ts +2 -0
  79. package/dist/components/input-group/input-group.cjs +32 -0
  80. package/dist/components/input-group/input-group.cjs.map +1 -0
  81. package/dist/components/input-group/input-group.d.cts +15 -0
  82. package/dist/components/input-group/input-group.d.ts +15 -0
  83. package/dist/components/input-group/input-group.js +30 -0
  84. package/dist/components/input-group/input-group.js.map +1 -0
  85. package/dist/components/pin-input/index.d.cts +2 -0
  86. package/dist/components/pin-input/index.d.ts +2 -0
  87. package/dist/components/pin-input/pin-input.cjs +266 -0
  88. package/dist/components/pin-input/pin-input.cjs.map +1 -0
  89. package/dist/components/pin-input/pin-input.d.cts +46 -0
  90. package/dist/components/pin-input/pin-input.d.ts +46 -0
  91. package/dist/components/pin-input/pin-input.js +258 -0
  92. package/dist/components/pin-input/pin-input.js.map +1 -0
  93. package/dist/components/select/index.d.cts +2 -2
  94. package/dist/components/select/index.d.ts +2 -2
  95. package/dist/components/select/select.cjs +80 -3
  96. package/dist/components/select/select.cjs.map +1 -1
  97. package/dist/components/select/select.d.cts +18 -3
  98. package/dist/components/select/select.d.ts +18 -3
  99. package/dist/components/select/select.js +78 -5
  100. package/dist/components/select/select.js.map +1 -1
  101. package/dist/components/tags-input/tags-input.cjs +83 -5
  102. package/dist/components/tags-input/tags-input.cjs.map +1 -1
  103. package/dist/components/tags-input/tags-input.d.cts +3 -0
  104. package/dist/components/tags-input/tags-input.d.ts +3 -0
  105. package/dist/components/tags-input/tags-input.js +83 -5
  106. package/dist/components/tags-input/tags-input.js.map +1 -1
  107. package/dist/components/upload/index.d.cts +2 -2
  108. package/dist/components/upload/index.d.ts +2 -2
  109. package/dist/components/upload/upload.cjs +90 -10
  110. package/dist/components/upload/upload.cjs.map +1 -1
  111. package/dist/components/upload/upload.d.cts +25 -2
  112. package/dist/components/upload/upload.d.ts +25 -2
  113. package/dist/components/upload/upload.js +89 -11
  114. package/dist/components/upload/upload.js.map +1 -1
  115. package/dist/index.cjs +70 -0
  116. package/dist/index.d.cts +21 -5
  117. package/dist/index.d.ts +21 -5
  118. package/dist/index.js +13 -5
  119. package/dist/styled-system/recipes/button-group.cjs +30 -0
  120. package/dist/styled-system/recipes/button-group.cjs.map +1 -0
  121. package/dist/styled-system/recipes/button-group.js +30 -0
  122. package/dist/styled-system/recipes/button-group.js.map +1 -0
  123. package/dist/styled-system/recipes/calendar.cjs +43 -0
  124. package/dist/styled-system/recipes/calendar.cjs.map +1 -0
  125. package/dist/styled-system/recipes/calendar.js +43 -0
  126. package/dist/styled-system/recipes/calendar.js.map +1 -0
  127. package/dist/styled-system/recipes/combobox.cjs +1 -0
  128. package/dist/styled-system/recipes/combobox.cjs.map +1 -1
  129. package/dist/styled-system/recipes/combobox.js +1 -0
  130. package/dist/styled-system/recipes/combobox.js.map +1 -1
  131. package/dist/styled-system/recipes/date-range-picker.cjs +52 -0
  132. package/dist/styled-system/recipes/date-range-picker.cjs.map +1 -0
  133. package/dist/styled-system/recipes/date-range-picker.js +52 -0
  134. package/dist/styled-system/recipes/date-range-picker.js.map +1 -0
  135. package/dist/styled-system/recipes/empty-state.cjs +36 -0
  136. package/dist/styled-system/recipes/empty-state.cjs.map +1 -0
  137. package/dist/styled-system/recipes/empty-state.js +36 -0
  138. package/dist/styled-system/recipes/empty-state.js.map +1 -0
  139. package/dist/styled-system/recipes/icon-button.cjs +40 -0
  140. package/dist/styled-system/recipes/icon-button.cjs.map +1 -0
  141. package/dist/styled-system/recipes/icon-button.js +40 -0
  142. package/dist/styled-system/recipes/icon-button.js.map +1 -0
  143. package/dist/styled-system/recipes/input-group.cjs +30 -0
  144. package/dist/styled-system/recipes/input-group.cjs.map +1 -0
  145. package/dist/styled-system/recipes/input-group.js +30 -0
  146. package/dist/styled-system/recipes/input-group.js.map +1 -0
  147. package/dist/styled-system/recipes/pin-input.cjs +39 -0
  148. package/dist/styled-system/recipes/pin-input.cjs.map +1 -0
  149. package/dist/styled-system/recipes/pin-input.js +39 -0
  150. package/dist/styled-system/recipes/pin-input.js.map +1 -0
  151. package/dist/styled-system/recipes/select.cjs +5 -1
  152. package/dist/styled-system/recipes/select.cjs.map +1 -1
  153. package/dist/styled-system/recipes/select.js +5 -1
  154. package/dist/styled-system/recipes/select.js.map +1 -1
  155. package/dist/styled-system/recipes/upload.cjs +2 -0
  156. package/dist/styled-system/recipes/upload.cjs.map +1 -1
  157. package/dist/styled-system/recipes/upload.js +2 -0
  158. package/dist/styled-system/recipes/upload.js.map +1 -1
  159. package/dist/styles/theme.cjs +15 -0
  160. package/dist/styles/theme.cjs.map +1 -1
  161. package/dist/styles/theme.js +15 -0
  162. package/dist/styles/theme.js.map +1 -1
  163. package/dist/styles.css +901 -46
  164. package/dist/theme/index.d.cts +2 -0
  165. package/dist/theme/index.d.ts +2 -0
  166. package/dist/theme/theme-provider.cjs +86 -0
  167. package/dist/theme/theme-provider.cjs.map +1 -0
  168. package/dist/theme/theme-provider.d.cts +66 -0
  169. package/dist/theme/theme-provider.d.ts +66 -0
  170. package/dist/theme/theme-provider.js +85 -0
  171. package/dist/theme/theme-provider.js.map +1 -0
  172. package/package.json +3 -2
@@ -0,0 +1,266 @@
1
+ "use client";
2
+ const require_cx = require("../../styled-system/css/cx.cjs");
3
+ const require_pin_input = require("../../styled-system/recipes/pin-input.cjs");
4
+ let react = require("react");
5
+ let react_jsx_runtime = require("react/jsx-runtime");
6
+ //#region src/components/pin-input/pin-input.tsx
7
+ const PinInputContext = (0, react.createContext)(null);
8
+ function digitKey(index) {
9
+ return `digit-${index}`;
10
+ }
11
+ function usePinInputContext() {
12
+ const context = (0, react.useContext)(PinInputContext);
13
+ if (!context) throw new Error("PinInput parts must be rendered inside PinInput.Root.");
14
+ return context;
15
+ }
16
+ const PinInputRoot = (0, react.forwardRef)(function PinInputRoot({ autoFocus = false, children, className, defaultValue = "", disabled = false, id: providedId, invalid = false, length, name, onValueChange, onComplete, otp = false, type = "text", value: controlledValue, ...props }, ref) {
17
+ const generatedId = (0, react.useId)();
18
+ const id = providedId ?? generatedId;
19
+ const styles = require_pin_input.pinInput();
20
+ const safeLength = Math.max(1, Math.floor(length));
21
+ const [uncontrolledValue, setUncontrolledValue] = (0, react.useState)(() => defaultValue.slice(0, safeLength));
22
+ const value = (controlledValue ?? uncontrolledValue).slice(0, safeLength);
23
+ const inputRefs = (0, react.useRef)([]);
24
+ const composingRef = (0, react.useRef)(false);
25
+ const updateValue = (0, react.useCallback)((next) => {
26
+ const normalized = next.slice(0, safeLength);
27
+ if (controlledValue === void 0) setUncontrolledValue(normalized);
28
+ onValueChange?.(normalized);
29
+ if (normalized.length === safeLength) onComplete?.(normalized);
30
+ }, [
31
+ controlledValue,
32
+ onComplete,
33
+ onValueChange,
34
+ safeLength
35
+ ]);
36
+ const normalize = (0, react.useCallback)((next) => {
37
+ const characters = Array.from(next);
38
+ return (otp ? characters.filter((character) => /[0-9]/u.test(character)) : characters).join("").slice(0, safeLength);
39
+ }, [otp, safeLength]);
40
+ const focusIndex = (0, react.useCallback)((index) => {
41
+ inputRefs.current[Math.max(0, Math.min(safeLength - 1, index))]?.focus();
42
+ }, [safeLength]);
43
+ const onInput = (0, react.useCallback)((index, nextCharacter) => {
44
+ if (composingRef.current) return;
45
+ const characters = Array.from(value);
46
+ const next = normalize(nextCharacter).slice(-1);
47
+ characters[index] = next;
48
+ const nextValue = characters.join("").slice(0, safeLength);
49
+ updateValue(nextValue);
50
+ if (next) focusIndex(index + 1);
51
+ }, [
52
+ focusIndex,
53
+ normalize,
54
+ safeLength,
55
+ updateValue,
56
+ value
57
+ ]);
58
+ const onCompositionStart = (0, react.useCallback)(() => {
59
+ composingRef.current = true;
60
+ }, []);
61
+ const onCompositionEnd = (0, react.useCallback)((index, event) => {
62
+ composingRef.current = false;
63
+ onInput(index, event.currentTarget.value);
64
+ }, [onInput]);
65
+ const onPaste = (0, react.useCallback)((index, event) => {
66
+ event.preventDefault();
67
+ const pasted = normalize(event.clipboardData.getData("text"));
68
+ if (!pasted) return;
69
+ const characters = Array.from(value);
70
+ Array.from(pasted).forEach((character, offset) => {
71
+ if (index + offset < safeLength) characters[index + offset] = character;
72
+ });
73
+ const nextValue = characters.join("").slice(0, safeLength);
74
+ updateValue(nextValue);
75
+ focusIndex(Math.min(safeLength - 1, index + pasted.length));
76
+ }, [
77
+ focusIndex,
78
+ normalize,
79
+ safeLength,
80
+ updateValue,
81
+ value
82
+ ]);
83
+ const context = {
84
+ disabled,
85
+ id,
86
+ invalid,
87
+ inputRefs,
88
+ length: safeLength,
89
+ onInput,
90
+ onCompositionEnd,
91
+ onCompositionStart,
92
+ onKeyDown: (0, react.useCallback)((index, event) => {
93
+ if (event.key === "Backspace" && !event.currentTarget.value && index > 0) {
94
+ event.preventDefault();
95
+ const characters = Array.from(value);
96
+ characters[index - 1] = "";
97
+ updateValue(characters.join(""));
98
+ focusIndex(index - 1);
99
+ } else if (event.key === "ArrowLeft") {
100
+ event.preventDefault();
101
+ focusIndex(index - 1);
102
+ } else if (event.key === "ArrowRight") {
103
+ event.preventDefault();
104
+ focusIndex(index + 1);
105
+ } else if (event.key === "Home") {
106
+ event.preventDefault();
107
+ focusIndex(0);
108
+ } else if (event.key === "End") {
109
+ event.preventDefault();
110
+ focusIndex(safeLength - 1);
111
+ }
112
+ }, [
113
+ focusIndex,
114
+ safeLength,
115
+ updateValue,
116
+ value
117
+ ]),
118
+ onPaste,
119
+ otp,
120
+ styles,
121
+ type,
122
+ value
123
+ };
124
+ (0, react.useEffect)(() => {
125
+ if (autoFocus) inputRefs.current[0]?.focus();
126
+ }, [autoFocus]);
127
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
128
+ ...props,
129
+ className: require_cx.cx(styles.root, className),
130
+ "data-disabled": disabled || void 0,
131
+ "data-invalid": invalid || void 0,
132
+ "data-jaci-component": "pin-input",
133
+ "data-slot": "pin-input",
134
+ id,
135
+ ref,
136
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PinInputContext.Provider, {
137
+ value: context,
138
+ children
139
+ }), name ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
140
+ "aria-hidden": "true",
141
+ className: styles.hiddenInput,
142
+ disabled,
143
+ name,
144
+ tabIndex: -1,
145
+ value,
146
+ readOnly: true
147
+ }) : null]
148
+ });
149
+ });
150
+ const PinInputLabel = (0, react.forwardRef)(function PinInputLabel({ className, ...props }, ref) {
151
+ const { id, styles } = usePinInputContext();
152
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
153
+ ...props,
154
+ className: require_cx.cx(styles.label, className),
155
+ "data-slot": "pin-input-label",
156
+ htmlFor: props.htmlFor ?? `${id}-0`,
157
+ ref
158
+ });
159
+ });
160
+ const PinInputControl = (0, react.forwardRef)(function PinInputControl({ className, ...props }, ref) {
161
+ const { styles } = usePinInputContext();
162
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
163
+ ...props,
164
+ className: require_cx.cx(styles.control, className),
165
+ "data-slot": "pin-input-control",
166
+ ref
167
+ });
168
+ });
169
+ const PinInputInputs = (0, react.forwardRef)(function PinInputInputs({ className, ...props }, ref) {
170
+ const { length, styles } = usePinInputContext();
171
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
172
+ ...props,
173
+ className: require_cx.cx(styles.inputs, className),
174
+ "data-slot": "pin-input-inputs",
175
+ ref,
176
+ children: Array.from({ length }, (_, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PinInputInput, { index }, digitKey(index)))
177
+ });
178
+ });
179
+ const PinInputInput = (0, react.forwardRef)(function PinInputInput({ className, index, id, onCompositionEnd: onInputCompositionEnd, onCompositionStart: onInputCompositionStart, ...props }, ref) {
180
+ const { disabled, id: rootId, inputRefs, invalid, length, onInput, onCompositionEnd, onCompositionStart, onKeyDown, onPaste, otp, styles, type, value } = usePinInputContext();
181
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
182
+ ...props,
183
+ "aria-label": props["aria-label"] ?? `Digit ${index + 1} of ${length}`,
184
+ "aria-invalid": invalid || void 0,
185
+ autoComplete: otp ? "one-time-code" : props.autoComplete,
186
+ className: require_cx.cx(styles.input, className),
187
+ "data-slot": "pin-input-input",
188
+ disabled: disabled || props.disabled,
189
+ id: id ?? `${rootId}-${index}`,
190
+ inputMode: otp ? "numeric" : props.inputMode,
191
+ maxLength: 1,
192
+ onChange: (event) => onInput(index, event.currentTarget.value),
193
+ onCompositionEnd: (event) => {
194
+ onCompositionEnd(index, event);
195
+ onInputCompositionEnd?.(event);
196
+ },
197
+ onCompositionStart: (event) => {
198
+ onCompositionStart();
199
+ onInputCompositionStart?.(event);
200
+ },
201
+ onKeyDown: (event) => onKeyDown(index, event),
202
+ onPaste: (event) => onPaste(index, event),
203
+ ref: (node) => {
204
+ inputRefs.current[index] = node;
205
+ if (typeof ref === "function") ref(node);
206
+ else if (ref) ref.current = node;
207
+ },
208
+ type,
209
+ value: Array.from(value)[index] ?? ""
210
+ });
211
+ });
212
+ const PinInputDescription = (0, react.forwardRef)(function PinInputDescription({ className, ...props }, ref) {
213
+ const { styles } = usePinInputContext();
214
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
215
+ ...props,
216
+ className: require_cx.cx(styles.description, className),
217
+ "data-slot": "pin-input-description",
218
+ ref
219
+ });
220
+ });
221
+ const PinInputError = (0, react.forwardRef)(function PinInputError({ className, ...props }, ref) {
222
+ const { styles } = usePinInputContext();
223
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
224
+ ...props,
225
+ className: require_cx.cx(styles.error, className),
226
+ "data-slot": "pin-input-error",
227
+ role: "alert",
228
+ ref
229
+ });
230
+ });
231
+ const PinInputHiddenInput = (0, react.forwardRef)(function PinInputHiddenInput(props, ref) {
232
+ const { disabled, styles, value } = usePinInputContext();
233
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
234
+ ...props,
235
+ "aria-hidden": "true",
236
+ className: styles.hiddenInput,
237
+ disabled: disabled || props.disabled,
238
+ readOnly: true,
239
+ ref,
240
+ tabIndex: -1,
241
+ type: "hidden",
242
+ value
243
+ });
244
+ });
245
+ const PinInput = {
246
+ Root: PinInputRoot,
247
+ Label: PinInputLabel,
248
+ Control: PinInputControl,
249
+ Inputs: PinInputInputs,
250
+ Input: PinInputInput,
251
+ Description: PinInputDescription,
252
+ Error: PinInputError,
253
+ HiddenInput: PinInputHiddenInput
254
+ };
255
+ //#endregion
256
+ exports.PinInput = PinInput;
257
+ exports.PinInputControl = PinInputControl;
258
+ exports.PinInputDescription = PinInputDescription;
259
+ exports.PinInputError = PinInputError;
260
+ exports.PinInputHiddenInput = PinInputHiddenInput;
261
+ exports.PinInputInput = PinInputInput;
262
+ exports.PinInputInputs = PinInputInputs;
263
+ exports.PinInputLabel = PinInputLabel;
264
+ exports.PinInputRoot = PinInputRoot;
265
+
266
+ //# sourceMappingURL=pin-input.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pin-input.cjs","names":["pinInput","cx"],"sources":["../../../src/components/pin-input/pin-input.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport type {\n ClipboardEvent,\n CompositionEvent,\n ComponentPropsWithoutRef,\n KeyboardEvent,\n MutableRefObject,\n ReactNode,\n} from \"react\";\n\nimport { cx } from \"../../styled-system/css\";\nimport { pinInput } from \"../../styled-system/recipes\";\n\ninterface PinInputContextValue {\n disabled: boolean;\n id: string;\n invalid: boolean;\n inputRefs: MutableRefObject<Array<HTMLInputElement | null>>;\n length: number;\n onInput: (index: number, value: string) => void;\n onCompositionEnd: (index: number, event: CompositionEvent<HTMLInputElement>) => void;\n onCompositionStart: () => void;\n onKeyDown: (index: number, event: KeyboardEvent<HTMLInputElement>) => void;\n onPaste: (index: number, event: ClipboardEvent<HTMLInputElement>) => void;\n otp: boolean;\n styles: ReturnType<typeof pinInput>;\n type: \"text\" | \"password\";\n value: string;\n}\n\nconst PinInputContext = createContext<PinInputContextValue | null>(null);\n\nfunction digitKey(index: number) {\n return `digit-${index}`;\n}\n\nfunction usePinInputContext() {\n const context = useContext(PinInputContext);\n if (!context) throw new Error(\"PinInput parts must be rendered inside PinInput.Root.\");\n return context;\n}\n\nexport interface PinInputRootProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\" | \"defaultValue\"> {\n length: number;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n onComplete?: (value: string) => void;\n type?: \"text\" | \"password\";\n otp?: boolean;\n autoFocus?: boolean;\n disabled?: boolean;\n invalid?: boolean;\n name?: string;\n children?: ReactNode;\n}\n\nexport const PinInputRoot = forwardRef<HTMLDivElement, PinInputRootProps>(function PinInputRoot(\n {\n autoFocus = false,\n children,\n className,\n defaultValue = \"\",\n disabled = false,\n id: providedId,\n invalid = false,\n length,\n name,\n onValueChange,\n onComplete,\n otp = false,\n type = \"text\",\n value: controlledValue,\n ...props\n },\n ref,\n) {\n const generatedId = useId();\n const id = providedId ?? generatedId;\n const styles = pinInput();\n const safeLength = Math.max(1, Math.floor(length));\n const [uncontrolledValue, setUncontrolledValue] = useState(() =>\n defaultValue.slice(0, safeLength),\n );\n const value = (controlledValue ?? uncontrolledValue).slice(0, safeLength);\n const inputRefs = useRef<Array<HTMLInputElement | null>>([]);\n const composingRef = useRef(false);\n const updateValue = useCallback(\n (next: string) => {\n const normalized = next.slice(0, safeLength);\n if (controlledValue === undefined) setUncontrolledValue(normalized);\n onValueChange?.(normalized);\n if (normalized.length === safeLength) onComplete?.(normalized);\n },\n [controlledValue, onComplete, onValueChange, safeLength],\n );\n const normalize = useCallback(\n (next: string) => {\n const characters = Array.from(next);\n return (otp ? characters.filter((character) => /[0-9]/u.test(character)) : characters)\n .join(\"\")\n .slice(0, safeLength);\n },\n [otp, safeLength],\n );\n const focusIndex = useCallback(\n (index: number) => {\n inputRefs.current[Math.max(0, Math.min(safeLength - 1, index))]?.focus();\n },\n [safeLength],\n );\n const onInput = useCallback(\n (index: number, nextCharacter: string) => {\n if (composingRef.current) return;\n const characters = Array.from(value);\n const next = normalize(nextCharacter).slice(-1);\n characters[index] = next;\n const nextValue = characters.join(\"\").slice(0, safeLength);\n updateValue(nextValue);\n if (next) focusIndex(index + 1);\n },\n [focusIndex, normalize, safeLength, updateValue, value],\n );\n const onCompositionStart = useCallback(() => {\n composingRef.current = true;\n }, []);\n const onCompositionEnd = useCallback(\n (index: number, event: CompositionEvent<HTMLInputElement>) => {\n composingRef.current = false;\n onInput(index, event.currentTarget.value);\n },\n [onInput],\n );\n const onPaste = useCallback(\n (index: number, event: ClipboardEvent<HTMLInputElement>) => {\n event.preventDefault();\n const pasted = normalize(event.clipboardData.getData(\"text\"));\n if (!pasted) return;\n const characters = Array.from(value);\n Array.from(pasted).forEach((character, offset) => {\n if (index + offset < safeLength) characters[index + offset] = character;\n });\n const nextValue = characters.join(\"\").slice(0, safeLength);\n updateValue(nextValue);\n focusIndex(Math.min(safeLength - 1, index + pasted.length));\n },\n [focusIndex, normalize, safeLength, updateValue, value],\n );\n const onKeyDown = useCallback(\n (index: number, event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Backspace\" && !event.currentTarget.value && index > 0) {\n event.preventDefault();\n const characters = Array.from(value);\n characters[index - 1] = \"\";\n updateValue(characters.join(\"\"));\n focusIndex(index - 1);\n } else if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n focusIndex(index - 1);\n } else if (event.key === \"ArrowRight\") {\n event.preventDefault();\n focusIndex(index + 1);\n } else if (event.key === \"Home\") {\n event.preventDefault();\n focusIndex(0);\n } else if (event.key === \"End\") {\n event.preventDefault();\n focusIndex(safeLength - 1);\n }\n },\n [focusIndex, safeLength, updateValue, value],\n );\n const context: PinInputContextValue = {\n disabled,\n id,\n invalid,\n inputRefs,\n length: safeLength,\n onInput,\n onCompositionEnd,\n onCompositionStart,\n onKeyDown,\n onPaste,\n otp,\n styles,\n type,\n value,\n };\n\n useEffect(() => {\n if (autoFocus) inputRefs.current[0]?.focus();\n }, [autoFocus]);\n\n return (\n <div\n {...props}\n className={cx(styles.root, className)}\n data-disabled={disabled || undefined}\n data-invalid={invalid || undefined}\n data-jaci-component=\"pin-input\"\n data-slot=\"pin-input\"\n id={id}\n ref={ref}\n >\n <PinInputContext.Provider value={context}>{children}</PinInputContext.Provider>\n {name ? (\n <input\n aria-hidden=\"true\"\n className={styles.hiddenInput}\n disabled={disabled}\n name={name}\n tabIndex={-1}\n value={value}\n readOnly\n />\n ) : null}\n </div>\n );\n});\n\nexport type PinInputLabelProps = ComponentPropsWithoutRef<\"label\">;\nexport const PinInputLabel = forwardRef<HTMLLabelElement, PinInputLabelProps>(\n function PinInputLabel({ className, ...props }, ref) {\n const { id, styles } = usePinInputContext();\n return (\n // biome-ignore lint/a11y/noLabelWithoutControl: the generated Inputs slot supplies the control.\n <label\n {...props}\n className={cx(styles.label, className)}\n data-slot=\"pin-input-label\"\n htmlFor={props.htmlFor ?? `${id}-0`}\n ref={ref}\n />\n );\n },\n);\n\nexport type PinInputControlProps = ComponentPropsWithoutRef<\"div\">;\nexport const PinInputControl = forwardRef<HTMLDivElement, PinInputControlProps>(\n function PinInputControl({ className, ...props }, ref) {\n const { styles } = usePinInputContext();\n return (\n <div\n {...props}\n className={cx(styles.control, className)}\n data-slot=\"pin-input-control\"\n ref={ref}\n />\n );\n },\n);\n\nexport type PinInputInputsProps = ComponentPropsWithoutRef<\"div\">;\nexport const PinInputInputs = forwardRef<HTMLDivElement, PinInputInputsProps>(\n function PinInputInputs({ className, ...props }, ref) {\n const { length, styles } = usePinInputContext();\n return (\n <div\n {...props}\n className={cx(styles.inputs, className)}\n data-slot=\"pin-input-inputs\"\n ref={ref}\n >\n {Array.from({ length }, (_, index) => (\n <PinInputInput index={index} key={digitKey(index)} />\n ))}\n </div>\n );\n },\n);\n\nexport interface PinInputInputProps\n extends Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"defaultValue\" | \"onChange\" | \"onKeyDown\" | \"onPaste\" | \"type\" | \"value\"\n > {\n index: number;\n}\nexport const PinInputInput = forwardRef<HTMLInputElement, PinInputInputProps>(\n function PinInputInput(\n {\n className,\n index,\n id,\n onCompositionEnd: onInputCompositionEnd,\n onCompositionStart: onInputCompositionStart,\n ...props\n },\n ref,\n ) {\n const {\n disabled,\n id: rootId,\n inputRefs,\n invalid,\n length,\n onInput,\n onCompositionEnd,\n onCompositionStart,\n onKeyDown,\n onPaste,\n otp,\n styles,\n type,\n value,\n } = usePinInputContext();\n return (\n <input\n {...props}\n aria-label={props[\"aria-label\"] ?? `Digit ${index + 1} of ${length}`}\n aria-invalid={invalid || undefined}\n autoComplete={otp ? \"one-time-code\" : props.autoComplete}\n className={cx(styles.input, className)}\n data-slot=\"pin-input-input\"\n disabled={disabled || props.disabled}\n id={id ?? `${rootId}-${index}`}\n inputMode={otp ? \"numeric\" : props.inputMode}\n maxLength={1}\n onChange={(event) => onInput(index, event.currentTarget.value)}\n onCompositionEnd={(event) => {\n onCompositionEnd(index, event);\n onInputCompositionEnd?.(event);\n }}\n onCompositionStart={(event) => {\n onCompositionStart();\n onInputCompositionStart?.(event);\n }}\n onKeyDown={(event) => onKeyDown(index, event)}\n onPaste={(event) => onPaste(index, event)}\n ref={(node) => {\n inputRefs.current[index] = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n }}\n type={type}\n value={Array.from(value)[index] ?? \"\"}\n />\n );\n },\n);\n\nexport type PinInputDescriptionProps = ComponentPropsWithoutRef<\"p\">;\nexport const PinInputDescription = forwardRef<HTMLParagraphElement, PinInputDescriptionProps>(\n function PinInputDescription({ className, ...props }, ref) {\n const { styles } = usePinInputContext();\n return (\n <p\n {...props}\n className={cx(styles.description, className)}\n data-slot=\"pin-input-description\"\n ref={ref}\n />\n );\n },\n);\nexport type PinInputErrorProps = ComponentPropsWithoutRef<\"p\">;\nexport const PinInputError = forwardRef<HTMLParagraphElement, PinInputErrorProps>(\n function PinInputError({ className, ...props }, ref) {\n const { styles } = usePinInputContext();\n return (\n <p\n {...props}\n className={cx(styles.error, className)}\n data-slot=\"pin-input-error\"\n role=\"alert\"\n ref={ref}\n />\n );\n },\n);\nexport type PinInputHiddenInputProps = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"name\" | \"type\" | \"value\"\n>;\nexport const PinInputHiddenInput = forwardRef<HTMLInputElement, PinInputHiddenInputProps>(\n function PinInputHiddenInput(props, ref) {\n const { disabled, styles, value } = usePinInputContext();\n return (\n <input\n {...props}\n aria-hidden=\"true\"\n className={styles.hiddenInput}\n disabled={disabled || props.disabled}\n readOnly\n ref={ref}\n tabIndex={-1}\n type=\"hidden\"\n value={value}\n />\n );\n },\n);\n\nexport const PinInput = {\n Root: PinInputRoot,\n Label: PinInputLabel,\n Control: PinInputControl,\n Inputs: PinInputInputs,\n Input: PinInputInput,\n Description: PinInputDescription,\n Error: PinInputError,\n HiddenInput: PinInputHiddenInput,\n};\n"],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { ComponentPropsWithoutRef, ReactNode } from "react";
2
+ //#region src/components/pin-input/pin-input.d.ts
3
+ interface PinInputRootProps extends Omit<ComponentPropsWithoutRef<"div">, "children" | "defaultValue"> {
4
+ length: number;
5
+ value?: string;
6
+ defaultValue?: string;
7
+ onValueChange?: (value: string) => void;
8
+ onComplete?: (value: string) => void;
9
+ type?: "text" | "password";
10
+ otp?: boolean;
11
+ autoFocus?: boolean;
12
+ disabled?: boolean;
13
+ invalid?: boolean;
14
+ name?: string;
15
+ children?: ReactNode;
16
+ }
17
+ declare const PinInputRoot: import("react").ForwardRefExoticComponent<PinInputRootProps & import("react").RefAttributes<HTMLDivElement>>;
18
+ type PinInputLabelProps = ComponentPropsWithoutRef<"label">;
19
+ declare const PinInputLabel: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "ref"> & import("react").RefAttributes<HTMLLabelElement>>;
20
+ type PinInputControlProps = ComponentPropsWithoutRef<"div">;
21
+ declare const PinInputControl: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
22
+ type PinInputInputsProps = ComponentPropsWithoutRef<"div">;
23
+ declare const PinInputInputs: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
24
+ interface PinInputInputProps extends Omit<ComponentPropsWithoutRef<"input">, "defaultValue" | "onChange" | "onKeyDown" | "onPaste" | "type" | "value"> {
25
+ index: number;
26
+ }
27
+ declare const PinInputInput: import("react").ForwardRefExoticComponent<PinInputInputProps & import("react").RefAttributes<HTMLInputElement>>;
28
+ type PinInputDescriptionProps = ComponentPropsWithoutRef<"p">;
29
+ declare const PinInputDescription: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
30
+ type PinInputErrorProps = ComponentPropsWithoutRef<"p">;
31
+ declare const PinInputError: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
32
+ type PinInputHiddenInputProps = Omit<ComponentPropsWithoutRef<"input">, "name" | "type" | "value">;
33
+ declare const PinInputHiddenInput: import("react").ForwardRefExoticComponent<PinInputHiddenInputProps & import("react").RefAttributes<HTMLInputElement>>;
34
+ declare const PinInput: {
35
+ Root: import("react").ForwardRefExoticComponent<PinInputRootProps & import("react").RefAttributes<HTMLDivElement>>;
36
+ Label: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "ref"> & import("react").RefAttributes<HTMLLabelElement>>;
37
+ Control: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
38
+ Inputs: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
39
+ Input: import("react").ForwardRefExoticComponent<PinInputInputProps & import("react").RefAttributes<HTMLInputElement>>;
40
+ Description: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
41
+ Error: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
42
+ HiddenInput: import("react").ForwardRefExoticComponent<PinInputHiddenInputProps & import("react").RefAttributes<HTMLInputElement>>;
43
+ };
44
+ //#endregion
45
+ export { PinInput, PinInputControl, PinInputControlProps, PinInputDescription, PinInputDescriptionProps, PinInputError, PinInputErrorProps, PinInputHiddenInput, PinInputHiddenInputProps, PinInputInput, PinInputInputProps, PinInputInputs, PinInputInputsProps, PinInputLabel, PinInputLabelProps, PinInputRoot, PinInputRootProps };
46
+ //# sourceMappingURL=pin-input.d.cts.map
@@ -0,0 +1,46 @@
1
+ import { ComponentPropsWithoutRef, ReactNode } from "react";
2
+ //#region src/components/pin-input/pin-input.d.ts
3
+ interface PinInputRootProps extends Omit<ComponentPropsWithoutRef<"div">, "children" | "defaultValue"> {
4
+ length: number;
5
+ value?: string;
6
+ defaultValue?: string;
7
+ onValueChange?: (value: string) => void;
8
+ onComplete?: (value: string) => void;
9
+ type?: "text" | "password";
10
+ otp?: boolean;
11
+ autoFocus?: boolean;
12
+ disabled?: boolean;
13
+ invalid?: boolean;
14
+ name?: string;
15
+ children?: ReactNode;
16
+ }
17
+ declare const PinInputRoot: import("react").ForwardRefExoticComponent<PinInputRootProps & import("react").RefAttributes<HTMLDivElement>>;
18
+ type PinInputLabelProps = ComponentPropsWithoutRef<"label">;
19
+ declare const PinInputLabel: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "ref"> & import("react").RefAttributes<HTMLLabelElement>>;
20
+ type PinInputControlProps = ComponentPropsWithoutRef<"div">;
21
+ declare const PinInputControl: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
22
+ type PinInputInputsProps = ComponentPropsWithoutRef<"div">;
23
+ declare const PinInputInputs: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
24
+ interface PinInputInputProps extends Omit<ComponentPropsWithoutRef<"input">, "defaultValue" | "onChange" | "onKeyDown" | "onPaste" | "type" | "value"> {
25
+ index: number;
26
+ }
27
+ declare const PinInputInput: import("react").ForwardRefExoticComponent<PinInputInputProps & import("react").RefAttributes<HTMLInputElement>>;
28
+ type PinInputDescriptionProps = ComponentPropsWithoutRef<"p">;
29
+ declare const PinInputDescription: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
30
+ type PinInputErrorProps = ComponentPropsWithoutRef<"p">;
31
+ declare const PinInputError: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
32
+ type PinInputHiddenInputProps = Omit<ComponentPropsWithoutRef<"input">, "name" | "type" | "value">;
33
+ declare const PinInputHiddenInput: import("react").ForwardRefExoticComponent<PinInputHiddenInputProps & import("react").RefAttributes<HTMLInputElement>>;
34
+ declare const PinInput: {
35
+ Root: import("react").ForwardRefExoticComponent<PinInputRootProps & import("react").RefAttributes<HTMLDivElement>>;
36
+ Label: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "ref"> & import("react").RefAttributes<HTMLLabelElement>>;
37
+ Control: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
38
+ Inputs: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
39
+ Input: import("react").ForwardRefExoticComponent<PinInputInputProps & import("react").RefAttributes<HTMLInputElement>>;
40
+ Description: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
41
+ Error: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
42
+ HiddenInput: import("react").ForwardRefExoticComponent<PinInputHiddenInputProps & import("react").RefAttributes<HTMLInputElement>>;
43
+ };
44
+ //#endregion
45
+ export { PinInput, PinInputControl, PinInputControlProps, PinInputDescription, PinInputDescriptionProps, PinInputError, PinInputErrorProps, PinInputHiddenInput, PinInputHiddenInputProps, PinInputInput, PinInputInputProps, PinInputInputs, PinInputInputsProps, PinInputLabel, PinInputLabelProps, PinInputRoot, PinInputRootProps };
46
+ //# sourceMappingURL=pin-input.d.ts.map
@@ -0,0 +1,258 @@
1
+ "use client";
2
+ import { cx } from "../../styled-system/css/cx.js";
3
+ import { pinInput } from "../../styled-system/recipes/pin-input.js";
4
+ import { createContext, forwardRef, useCallback, useContext, useEffect, useId, useRef, useState } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/components/pin-input/pin-input.tsx
7
+ const PinInputContext = createContext(null);
8
+ function digitKey(index) {
9
+ return `digit-${index}`;
10
+ }
11
+ function usePinInputContext() {
12
+ const context = useContext(PinInputContext);
13
+ if (!context) throw new Error("PinInput parts must be rendered inside PinInput.Root.");
14
+ return context;
15
+ }
16
+ const PinInputRoot = forwardRef(function PinInputRoot({ autoFocus = false, children, className, defaultValue = "", disabled = false, id: providedId, invalid = false, length, name, onValueChange, onComplete, otp = false, type = "text", value: controlledValue, ...props }, ref) {
17
+ const generatedId = useId();
18
+ const id = providedId ?? generatedId;
19
+ const styles = pinInput();
20
+ const safeLength = Math.max(1, Math.floor(length));
21
+ const [uncontrolledValue, setUncontrolledValue] = useState(() => defaultValue.slice(0, safeLength));
22
+ const value = (controlledValue ?? uncontrolledValue).slice(0, safeLength);
23
+ const inputRefs = useRef([]);
24
+ const composingRef = useRef(false);
25
+ const updateValue = useCallback((next) => {
26
+ const normalized = next.slice(0, safeLength);
27
+ if (controlledValue === void 0) setUncontrolledValue(normalized);
28
+ onValueChange?.(normalized);
29
+ if (normalized.length === safeLength) onComplete?.(normalized);
30
+ }, [
31
+ controlledValue,
32
+ onComplete,
33
+ onValueChange,
34
+ safeLength
35
+ ]);
36
+ const normalize = useCallback((next) => {
37
+ const characters = Array.from(next);
38
+ return (otp ? characters.filter((character) => /[0-9]/u.test(character)) : characters).join("").slice(0, safeLength);
39
+ }, [otp, safeLength]);
40
+ const focusIndex = useCallback((index) => {
41
+ inputRefs.current[Math.max(0, Math.min(safeLength - 1, index))]?.focus();
42
+ }, [safeLength]);
43
+ const onInput = useCallback((index, nextCharacter) => {
44
+ if (composingRef.current) return;
45
+ const characters = Array.from(value);
46
+ const next = normalize(nextCharacter).slice(-1);
47
+ characters[index] = next;
48
+ const nextValue = characters.join("").slice(0, safeLength);
49
+ updateValue(nextValue);
50
+ if (next) focusIndex(index + 1);
51
+ }, [
52
+ focusIndex,
53
+ normalize,
54
+ safeLength,
55
+ updateValue,
56
+ value
57
+ ]);
58
+ const onCompositionStart = useCallback(() => {
59
+ composingRef.current = true;
60
+ }, []);
61
+ const onCompositionEnd = useCallback((index, event) => {
62
+ composingRef.current = false;
63
+ onInput(index, event.currentTarget.value);
64
+ }, [onInput]);
65
+ const onPaste = useCallback((index, event) => {
66
+ event.preventDefault();
67
+ const pasted = normalize(event.clipboardData.getData("text"));
68
+ if (!pasted) return;
69
+ const characters = Array.from(value);
70
+ Array.from(pasted).forEach((character, offset) => {
71
+ if (index + offset < safeLength) characters[index + offset] = character;
72
+ });
73
+ const nextValue = characters.join("").slice(0, safeLength);
74
+ updateValue(nextValue);
75
+ focusIndex(Math.min(safeLength - 1, index + pasted.length));
76
+ }, [
77
+ focusIndex,
78
+ normalize,
79
+ safeLength,
80
+ updateValue,
81
+ value
82
+ ]);
83
+ const context = {
84
+ disabled,
85
+ id,
86
+ invalid,
87
+ inputRefs,
88
+ length: safeLength,
89
+ onInput,
90
+ onCompositionEnd,
91
+ onCompositionStart,
92
+ onKeyDown: useCallback((index, event) => {
93
+ if (event.key === "Backspace" && !event.currentTarget.value && index > 0) {
94
+ event.preventDefault();
95
+ const characters = Array.from(value);
96
+ characters[index - 1] = "";
97
+ updateValue(characters.join(""));
98
+ focusIndex(index - 1);
99
+ } else if (event.key === "ArrowLeft") {
100
+ event.preventDefault();
101
+ focusIndex(index - 1);
102
+ } else if (event.key === "ArrowRight") {
103
+ event.preventDefault();
104
+ focusIndex(index + 1);
105
+ } else if (event.key === "Home") {
106
+ event.preventDefault();
107
+ focusIndex(0);
108
+ } else if (event.key === "End") {
109
+ event.preventDefault();
110
+ focusIndex(safeLength - 1);
111
+ }
112
+ }, [
113
+ focusIndex,
114
+ safeLength,
115
+ updateValue,
116
+ value
117
+ ]),
118
+ onPaste,
119
+ otp,
120
+ styles,
121
+ type,
122
+ value
123
+ };
124
+ useEffect(() => {
125
+ if (autoFocus) inputRefs.current[0]?.focus();
126
+ }, [autoFocus]);
127
+ return /* @__PURE__ */ jsxs("div", {
128
+ ...props,
129
+ className: cx(styles.root, className),
130
+ "data-disabled": disabled || void 0,
131
+ "data-invalid": invalid || void 0,
132
+ "data-jaci-component": "pin-input",
133
+ "data-slot": "pin-input",
134
+ id,
135
+ ref,
136
+ children: [/* @__PURE__ */ jsx(PinInputContext.Provider, {
137
+ value: context,
138
+ children
139
+ }), name ? /* @__PURE__ */ jsx("input", {
140
+ "aria-hidden": "true",
141
+ className: styles.hiddenInput,
142
+ disabled,
143
+ name,
144
+ tabIndex: -1,
145
+ value,
146
+ readOnly: true
147
+ }) : null]
148
+ });
149
+ });
150
+ const PinInputLabel = forwardRef(function PinInputLabel({ className, ...props }, ref) {
151
+ const { id, styles } = usePinInputContext();
152
+ return /* @__PURE__ */ jsx("label", {
153
+ ...props,
154
+ className: cx(styles.label, className),
155
+ "data-slot": "pin-input-label",
156
+ htmlFor: props.htmlFor ?? `${id}-0`,
157
+ ref
158
+ });
159
+ });
160
+ const PinInputControl = forwardRef(function PinInputControl({ className, ...props }, ref) {
161
+ const { styles } = usePinInputContext();
162
+ return /* @__PURE__ */ jsx("div", {
163
+ ...props,
164
+ className: cx(styles.control, className),
165
+ "data-slot": "pin-input-control",
166
+ ref
167
+ });
168
+ });
169
+ const PinInputInputs = forwardRef(function PinInputInputs({ className, ...props }, ref) {
170
+ const { length, styles } = usePinInputContext();
171
+ return /* @__PURE__ */ jsx("div", {
172
+ ...props,
173
+ className: cx(styles.inputs, className),
174
+ "data-slot": "pin-input-inputs",
175
+ ref,
176
+ children: Array.from({ length }, (_, index) => /* @__PURE__ */ jsx(PinInputInput, { index }, digitKey(index)))
177
+ });
178
+ });
179
+ const PinInputInput = forwardRef(function PinInputInput({ className, index, id, onCompositionEnd: onInputCompositionEnd, onCompositionStart: onInputCompositionStart, ...props }, ref) {
180
+ const { disabled, id: rootId, inputRefs, invalid, length, onInput, onCompositionEnd, onCompositionStart, onKeyDown, onPaste, otp, styles, type, value } = usePinInputContext();
181
+ return /* @__PURE__ */ jsx("input", {
182
+ ...props,
183
+ "aria-label": props["aria-label"] ?? `Digit ${index + 1} of ${length}`,
184
+ "aria-invalid": invalid || void 0,
185
+ autoComplete: otp ? "one-time-code" : props.autoComplete,
186
+ className: cx(styles.input, className),
187
+ "data-slot": "pin-input-input",
188
+ disabled: disabled || props.disabled,
189
+ id: id ?? `${rootId}-${index}`,
190
+ inputMode: otp ? "numeric" : props.inputMode,
191
+ maxLength: 1,
192
+ onChange: (event) => onInput(index, event.currentTarget.value),
193
+ onCompositionEnd: (event) => {
194
+ onCompositionEnd(index, event);
195
+ onInputCompositionEnd?.(event);
196
+ },
197
+ onCompositionStart: (event) => {
198
+ onCompositionStart();
199
+ onInputCompositionStart?.(event);
200
+ },
201
+ onKeyDown: (event) => onKeyDown(index, event),
202
+ onPaste: (event) => onPaste(index, event),
203
+ ref: (node) => {
204
+ inputRefs.current[index] = node;
205
+ if (typeof ref === "function") ref(node);
206
+ else if (ref) ref.current = node;
207
+ },
208
+ type,
209
+ value: Array.from(value)[index] ?? ""
210
+ });
211
+ });
212
+ const PinInputDescription = forwardRef(function PinInputDescription({ className, ...props }, ref) {
213
+ const { styles } = usePinInputContext();
214
+ return /* @__PURE__ */ jsx("p", {
215
+ ...props,
216
+ className: cx(styles.description, className),
217
+ "data-slot": "pin-input-description",
218
+ ref
219
+ });
220
+ });
221
+ const PinInputError = forwardRef(function PinInputError({ className, ...props }, ref) {
222
+ const { styles } = usePinInputContext();
223
+ return /* @__PURE__ */ jsx("p", {
224
+ ...props,
225
+ className: cx(styles.error, className),
226
+ "data-slot": "pin-input-error",
227
+ role: "alert",
228
+ ref
229
+ });
230
+ });
231
+ const PinInputHiddenInput = forwardRef(function PinInputHiddenInput(props, ref) {
232
+ const { disabled, styles, value } = usePinInputContext();
233
+ return /* @__PURE__ */ jsx("input", {
234
+ ...props,
235
+ "aria-hidden": "true",
236
+ className: styles.hiddenInput,
237
+ disabled: disabled || props.disabled,
238
+ readOnly: true,
239
+ ref,
240
+ tabIndex: -1,
241
+ type: "hidden",
242
+ value
243
+ });
244
+ });
245
+ const PinInput = {
246
+ Root: PinInputRoot,
247
+ Label: PinInputLabel,
248
+ Control: PinInputControl,
249
+ Inputs: PinInputInputs,
250
+ Input: PinInputInput,
251
+ Description: PinInputDescription,
252
+ Error: PinInputError,
253
+ HiddenInput: PinInputHiddenInput
254
+ };
255
+ //#endregion
256
+ export { PinInput, PinInputControl, PinInputDescription, PinInputError, PinInputHiddenInput, PinInputInput, PinInputInputs, PinInputLabel, PinInputRoot };
257
+
258
+ //# sourceMappingURL=pin-input.js.map