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.
- package/CHANGELOG.md +12 -0
- package/README.md +95 -0
- package/dist/components/button-group/button-group.cjs +22 -0
- package/dist/components/button-group/button-group.cjs.map +1 -0
- package/dist/components/button-group/button-group.d.cts +12 -0
- package/dist/components/button-group/button-group.d.ts +12 -0
- package/dist/components/button-group/button-group.js +21 -0
- package/dist/components/button-group/button-group.js.map +1 -0
- package/dist/components/button-group/index.d.cts +2 -0
- package/dist/components/button-group/index.d.ts +2 -0
- package/dist/components/calendar/calendar.cjs +377 -0
- package/dist/components/calendar/calendar.cjs.map +1 -0
- package/dist/components/calendar/calendar.d.cts +56 -0
- package/dist/components/calendar/calendar.d.ts +56 -0
- package/dist/components/calendar/calendar.js +368 -0
- package/dist/components/calendar/calendar.js.map +1 -0
- package/dist/components/calendar/index.d.cts +2 -0
- package/dist/components/calendar/index.d.ts +2 -0
- package/dist/components/combobox/combobox.cjs +13 -1
- package/dist/components/combobox/combobox.cjs.map +1 -1
- package/dist/components/combobox/combobox.d.cts +7 -2
- package/dist/components/combobox/combobox.d.ts +7 -2
- package/dist/components/combobox/combobox.js +13 -2
- package/dist/components/combobox/combobox.js.map +1 -1
- package/dist/components/combobox/index.d.cts +2 -2
- package/dist/components/combobox/index.d.ts +2 -2
- package/dist/components/controls/input.cjs +26 -5
- package/dist/components/controls/input.cjs.map +1 -1
- package/dist/components/controls/input.d.cts +5 -2
- package/dist/components/controls/input.d.ts +5 -2
- package/dist/components/controls/input.js +28 -7
- package/dist/components/controls/input.js.map +1 -1
- package/dist/components/controls/textarea.cjs +26 -5
- package/dist/components/controls/textarea.cjs.map +1 -1
- package/dist/components/controls/textarea.d.cts +5 -2
- package/dist/components/controls/textarea.d.ts +5 -2
- package/dist/components/controls/textarea.js +28 -7
- package/dist/components/controls/textarea.js.map +1 -1
- package/dist/components/date-picker/date-picker.cjs +9 -9
- package/dist/components/date-picker/date-picker.cjs.map +1 -1
- package/dist/components/date-picker/date-picker.d.cts +3 -1
- package/dist/components/date-picker/date-picker.d.ts +3 -1
- package/dist/components/date-picker/date-picker.js +9 -9
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.cjs +589 -0
- package/dist/components/date-range-picker/date-range-picker.cjs.map +1 -0
- package/dist/components/date-range-picker/date-range-picker.d.cts +134 -0
- package/dist/components/date-range-picker/date-range-picker.d.ts +134 -0
- package/dist/components/date-range-picker/date-range-picker.js +568 -0
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -0
- package/dist/components/date-range-picker/index.d.cts +2 -0
- package/dist/components/date-range-picker/index.d.ts +2 -0
- package/dist/components/empty-state/empty-state.cjs +62 -0
- package/dist/components/empty-state/empty-state.cjs.map +1 -0
- package/dist/components/empty-state/empty-state.d.cts +18 -0
- package/dist/components/empty-state/empty-state.d.ts +18 -0
- package/dist/components/empty-state/empty-state.js +57 -0
- package/dist/components/empty-state/empty-state.js.map +1 -0
- package/dist/components/empty-state/index.d.cts +2 -0
- package/dist/components/empty-state/index.d.ts +2 -0
- package/dist/components/field/field.cjs +106 -11
- package/dist/components/field/field.cjs.map +1 -1
- package/dist/components/field/field.d.cts +22 -4
- package/dist/components/field/field.d.ts +22 -4
- package/dist/components/field/field.js +107 -13
- package/dist/components/field/field.js.map +1 -1
- package/dist/components/field/index.d.cts +2 -2
- package/dist/components/field/index.d.ts +2 -2
- package/dist/components/icon-button/icon-button.cjs +40 -0
- package/dist/components/icon-button/icon-button.cjs.map +1 -0
- package/dist/components/icon-button/icon-button.d.cts +12 -0
- package/dist/components/icon-button/icon-button.d.ts +12 -0
- package/dist/components/icon-button/icon-button.js +40 -0
- package/dist/components/icon-button/icon-button.js.map +1 -0
- package/dist/components/icon-button/index.d.cts +2 -0
- package/dist/components/icon-button/index.d.ts +2 -0
- package/dist/components/input-group/index.d.cts +2 -0
- package/dist/components/input-group/index.d.ts +2 -0
- package/dist/components/input-group/input-group.cjs +32 -0
- package/dist/components/input-group/input-group.cjs.map +1 -0
- package/dist/components/input-group/input-group.d.cts +15 -0
- package/dist/components/input-group/input-group.d.ts +15 -0
- package/dist/components/input-group/input-group.js +30 -0
- package/dist/components/input-group/input-group.js.map +1 -0
- package/dist/components/pin-input/index.d.cts +2 -0
- package/dist/components/pin-input/index.d.ts +2 -0
- package/dist/components/pin-input/pin-input.cjs +266 -0
- package/dist/components/pin-input/pin-input.cjs.map +1 -0
- package/dist/components/pin-input/pin-input.d.cts +46 -0
- package/dist/components/pin-input/pin-input.d.ts +46 -0
- package/dist/components/pin-input/pin-input.js +258 -0
- package/dist/components/pin-input/pin-input.js.map +1 -0
- package/dist/components/select/index.d.cts +2 -2
- package/dist/components/select/index.d.ts +2 -2
- package/dist/components/select/select.cjs +80 -3
- package/dist/components/select/select.cjs.map +1 -1
- package/dist/components/select/select.d.cts +18 -3
- package/dist/components/select/select.d.ts +18 -3
- package/dist/components/select/select.js +78 -5
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/tags-input/tags-input.cjs +83 -5
- package/dist/components/tags-input/tags-input.cjs.map +1 -1
- package/dist/components/tags-input/tags-input.d.cts +3 -0
- package/dist/components/tags-input/tags-input.d.ts +3 -0
- package/dist/components/tags-input/tags-input.js +83 -5
- package/dist/components/tags-input/tags-input.js.map +1 -1
- package/dist/components/upload/index.d.cts +2 -2
- package/dist/components/upload/index.d.ts +2 -2
- package/dist/components/upload/upload.cjs +90 -10
- package/dist/components/upload/upload.cjs.map +1 -1
- package/dist/components/upload/upload.d.cts +25 -2
- package/dist/components/upload/upload.d.ts +25 -2
- package/dist/components/upload/upload.js +89 -11
- package/dist/components/upload/upload.js.map +1 -1
- package/dist/index.cjs +70 -0
- package/dist/index.d.cts +21 -5
- package/dist/index.d.ts +21 -5
- package/dist/index.js +13 -5
- package/dist/styled-system/recipes/button-group.cjs +30 -0
- package/dist/styled-system/recipes/button-group.cjs.map +1 -0
- package/dist/styled-system/recipes/button-group.js +30 -0
- package/dist/styled-system/recipes/button-group.js.map +1 -0
- package/dist/styled-system/recipes/calendar.cjs +43 -0
- package/dist/styled-system/recipes/calendar.cjs.map +1 -0
- package/dist/styled-system/recipes/calendar.js +43 -0
- package/dist/styled-system/recipes/calendar.js.map +1 -0
- package/dist/styled-system/recipes/combobox.cjs +1 -0
- package/dist/styled-system/recipes/combobox.cjs.map +1 -1
- package/dist/styled-system/recipes/combobox.js +1 -0
- package/dist/styled-system/recipes/combobox.js.map +1 -1
- package/dist/styled-system/recipes/date-range-picker.cjs +52 -0
- package/dist/styled-system/recipes/date-range-picker.cjs.map +1 -0
- package/dist/styled-system/recipes/date-range-picker.js +52 -0
- package/dist/styled-system/recipes/date-range-picker.js.map +1 -0
- package/dist/styled-system/recipes/empty-state.cjs +36 -0
- package/dist/styled-system/recipes/empty-state.cjs.map +1 -0
- package/dist/styled-system/recipes/empty-state.js +36 -0
- package/dist/styled-system/recipes/empty-state.js.map +1 -0
- package/dist/styled-system/recipes/icon-button.cjs +40 -0
- package/dist/styled-system/recipes/icon-button.cjs.map +1 -0
- package/dist/styled-system/recipes/icon-button.js +40 -0
- package/dist/styled-system/recipes/icon-button.js.map +1 -0
- package/dist/styled-system/recipes/input-group.cjs +30 -0
- package/dist/styled-system/recipes/input-group.cjs.map +1 -0
- package/dist/styled-system/recipes/input-group.js +30 -0
- package/dist/styled-system/recipes/input-group.js.map +1 -0
- package/dist/styled-system/recipes/pin-input.cjs +39 -0
- package/dist/styled-system/recipes/pin-input.cjs.map +1 -0
- package/dist/styled-system/recipes/pin-input.js +39 -0
- package/dist/styled-system/recipes/pin-input.js.map +1 -0
- package/dist/styled-system/recipes/select.cjs +5 -1
- package/dist/styled-system/recipes/select.cjs.map +1 -1
- package/dist/styled-system/recipes/select.js +5 -1
- package/dist/styled-system/recipes/select.js.map +1 -1
- package/dist/styled-system/recipes/upload.cjs +2 -0
- package/dist/styled-system/recipes/upload.cjs.map +1 -1
- package/dist/styled-system/recipes/upload.js +2 -0
- package/dist/styled-system/recipes/upload.js.map +1 -1
- package/dist/styles/theme.cjs +15 -0
- package/dist/styles/theme.cjs.map +1 -1
- package/dist/styles/theme.js +15 -0
- package/dist/styles/theme.js.map +1 -1
- package/dist/styles.css +901 -46
- package/dist/theme/index.d.cts +2 -0
- package/dist/theme/index.d.ts +2 -0
- package/dist/theme/theme-provider.cjs +86 -0
- package/dist/theme/theme-provider.cjs.map +1 -0
- package/dist/theme/theme-provider.d.cts +66 -0
- package/dist/theme/theme-provider.d.ts +66 -0
- package/dist/theme/theme-provider.js +85 -0
- package/dist/theme/theme-provider.js.map +1 -0
- 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
|