@nori-ui/core 1.6.0 → 1.8.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/dist/{chunk-7UKRN73P.js → chunk-2XJCLPNH.js} +3 -3
- package/dist/{chunk-7UKRN73P.js.map → chunk-2XJCLPNH.js.map} +1 -1
- package/dist/{chunk-5PSC5HT4.js → chunk-3B345SQU.js} +5 -5
- package/dist/{chunk-5PSC5HT4.js.map → chunk-3B345SQU.js.map} +1 -1
- package/dist/{chunk-JSAG5YO7.js → chunk-3IIIHZHT.js} +3 -3
- package/dist/{chunk-JSAG5YO7.js.map → chunk-3IIIHZHT.js.map} +1 -1
- package/dist/{chunk-DDGMLLS3.js → chunk-3W3XYULK.js} +3 -3
- package/dist/{chunk-DDGMLLS3.js.map → chunk-3W3XYULK.js.map} +1 -1
- package/dist/{chunk-WYPGQVDV.js → chunk-5YHT252H.js} +3 -3
- package/dist/{chunk-WYPGQVDV.js.map → chunk-5YHT252H.js.map} +1 -1
- package/dist/{chunk-ZMSIYLSI.js → chunk-7FSFJA33.js} +3 -3
- package/dist/{chunk-ZMSIYLSI.js.map → chunk-7FSFJA33.js.map} +1 -1
- package/dist/chunk-BOMPFNM4.js +165 -0
- package/dist/chunk-BOMPFNM4.js.map +1 -0
- package/dist/chunk-BVLOX4A3.js +256 -0
- package/dist/chunk-BVLOX4A3.js.map +1 -0
- package/dist/{chunk-YZ27OS2R.js → chunk-C32XGHWO.js} +3 -3
- package/dist/{chunk-YZ27OS2R.js.map → chunk-C32XGHWO.js.map} +1 -1
- package/dist/{chunk-UJWCEGQY.js → chunk-C5HQPXRI.js} +3 -3
- package/dist/{chunk-UJWCEGQY.js.map → chunk-C5HQPXRI.js.map} +1 -1
- package/dist/{chunk-XALU6LOT.js → chunk-EN4CLDGZ.js} +3 -3
- package/dist/{chunk-XALU6LOT.js.map → chunk-EN4CLDGZ.js.map} +1 -1
- package/dist/{chunk-6AD6KCVB.js → chunk-F5UKI7XD.js} +3 -3
- package/dist/{chunk-6AD6KCVB.js.map → chunk-F5UKI7XD.js.map} +1 -1
- package/dist/chunk-GTAXVTLF.js +43 -0
- package/dist/chunk-GTAXVTLF.js.map +1 -0
- package/dist/{chunk-NNFJKRXZ.js → chunk-H2LHWJ52.js} +3 -3
- package/dist/{chunk-NNFJKRXZ.js.map → chunk-H2LHWJ52.js.map} +1 -1
- package/dist/{chunk-PZS4A4VQ.js → chunk-HXCETKCC.js} +3 -3
- package/dist/{chunk-PZS4A4VQ.js.map → chunk-HXCETKCC.js.map} +1 -1
- package/dist/chunk-IGBXSBF7.js +71 -0
- package/dist/chunk-IGBXSBF7.js.map +1 -0
- package/dist/{chunk-JXLEMBDB.js → chunk-IIVTPN62.js} +3 -3
- package/dist/{chunk-JXLEMBDB.js.map → chunk-IIVTPN62.js.map} +1 -1
- package/dist/{chunk-PNP7L4TA.js → chunk-ISCJST4P.js} +3 -3
- package/dist/{chunk-PNP7L4TA.js.map → chunk-ISCJST4P.js.map} +1 -1
- package/dist/{chunk-TLS54G6Y.js → chunk-IWM2XDXH.js} +3 -3
- package/dist/{chunk-TLS54G6Y.js.map → chunk-IWM2XDXH.js.map} +1 -1
- package/dist/chunk-J5LK2XHE.js +118 -0
- package/dist/chunk-J5LK2XHE.js.map +1 -0
- package/dist/chunk-KFFGDET3.js +27 -0
- package/dist/chunk-KFFGDET3.js.map +1 -0
- package/dist/{chunk-MRJWPRCX.js → chunk-L6VYDM7S.js} +3 -3
- package/dist/{chunk-MRJWPRCX.js.map → chunk-L6VYDM7S.js.map} +1 -1
- package/dist/chunk-M4BI63P6.js +188 -0
- package/dist/chunk-M4BI63P6.js.map +1 -0
- package/dist/{chunk-RUWD35UI.js → chunk-MK57AOTI.js} +4 -4
- package/dist/{chunk-RUWD35UI.js.map → chunk-MK57AOTI.js.map} +1 -1
- package/dist/{chunk-3BDDPFCI.js → chunk-MOAIQHR7.js} +3 -3
- package/dist/{chunk-3BDDPFCI.js.map → chunk-MOAIQHR7.js.map} +1 -1
- package/dist/{chunk-5XEGZFG5.js → chunk-MYBBBLYE.js} +3 -3
- package/dist/{chunk-5XEGZFG5.js.map → chunk-MYBBBLYE.js.map} +1 -1
- package/dist/{chunk-WP2Z2ATO.js → chunk-O6M3F7BZ.js} +5 -5
- package/dist/{chunk-WP2Z2ATO.js.map → chunk-O6M3F7BZ.js.map} +1 -1
- package/dist/{chunk-FEPTH5RV.js → chunk-OELY6K44.js} +3 -3
- package/dist/{chunk-FEPTH5RV.js.map → chunk-OELY6K44.js.map} +1 -1
- package/dist/{chunk-BZLT6R62.js → chunk-OIHX5B4R.js} +3 -3
- package/dist/{chunk-BZLT6R62.js.map → chunk-OIHX5B4R.js.map} +1 -1
- package/dist/{chunk-QJVS2VXS.js → chunk-PGYEIXCO.js} +4 -4
- package/dist/{chunk-QJVS2VXS.js.map → chunk-PGYEIXCO.js.map} +1 -1
- package/dist/{chunk-UZD77M3J.js → chunk-PJTCO76H.js} +3 -3
- package/dist/{chunk-UZD77M3J.js.map → chunk-PJTCO76H.js.map} +1 -1
- package/dist/{chunk-4PUPKWEP.js → chunk-PJXVLE24.js} +4 -4
- package/dist/{chunk-4PUPKWEP.js.map → chunk-PJXVLE24.js.map} +1 -1
- package/dist/{chunk-WGT345SV.js → chunk-PLQPBMG2.js} +3 -3
- package/dist/{chunk-WGT345SV.js.map → chunk-PLQPBMG2.js.map} +1 -1
- package/dist/{chunk-OMU4R4Y5.js → chunk-PQW5LKAI.js} +3 -3
- package/dist/{chunk-OMU4R4Y5.js.map → chunk-PQW5LKAI.js.map} +1 -1
- package/dist/{chunk-Y5TJ7CAX.js → chunk-RI4Y2C5U.js} +3 -3
- package/dist/{chunk-Y5TJ7CAX.js.map → chunk-RI4Y2C5U.js.map} +1 -1
- package/dist/{chunk-3OIWAS2P.js → chunk-SF6WPUC5.js} +3 -3
- package/dist/{chunk-3OIWAS2P.js.map → chunk-SF6WPUC5.js.map} +1 -1
- package/dist/{chunk-MKSDYRWQ.js → chunk-STX5UKYT.js} +3 -3
- package/dist/{chunk-MKSDYRWQ.js.map → chunk-STX5UKYT.js.map} +1 -1
- package/dist/{chunk-2RL6WCFC.js → chunk-TSWPHJIU.js} +4 -4
- package/dist/{chunk-2RL6WCFC.js.map → chunk-TSWPHJIU.js.map} +1 -1
- package/dist/{chunk-SFNDR6DI.js → chunk-U2ZKY2CP.js} +3 -3
- package/dist/{chunk-SFNDR6DI.js.map → chunk-U2ZKY2CP.js.map} +1 -1
- package/dist/{chunk-PABG3IJ6.js → chunk-UKDDK42K.js} +3 -3
- package/dist/{chunk-PABG3IJ6.js.map → chunk-UKDDK42K.js.map} +1 -1
- package/dist/{chunk-VYRJ7OE5.js → chunk-USFXANEU.js} +3 -3
- package/dist/{chunk-VYRJ7OE5.js.map → chunk-USFXANEU.js.map} +1 -1
- package/dist/{chunk-CCUXO2HN.js → chunk-V5QSMDZL.js} +3 -3
- package/dist/{chunk-CCUXO2HN.js.map → chunk-V5QSMDZL.js.map} +1 -1
- package/dist/{chunk-NF7XG2FG.js → chunk-V75O7QQO.js} +3 -3
- package/dist/{chunk-NF7XG2FG.js.map → chunk-V75O7QQO.js.map} +1 -1
- package/dist/chunk-VFUV6XJR.js +257 -0
- package/dist/chunk-VFUV6XJR.js.map +1 -0
- package/dist/{chunk-NRYWNOG5.js → chunk-VL2WNGPF.js} +3 -3
- package/dist/{chunk-NRYWNOG5.js.map → chunk-VL2WNGPF.js.map} +1 -1
- package/dist/{chunk-JQQ3FBN7.js → chunk-VLZANXRZ.js} +3 -3
- package/dist/{chunk-JQQ3FBN7.js.map → chunk-VLZANXRZ.js.map} +1 -1
- package/dist/{chunk-2HMQDJ22.js → chunk-VOF3S5I4.js} +3 -3
- package/dist/{chunk-2HMQDJ22.js.map → chunk-VOF3S5I4.js.map} +1 -1
- package/dist/chunk-XQNVWHMN.js +60 -0
- package/dist/chunk-XQNVWHMN.js.map +1 -0
- package/dist/{chunk-JZ774T7U.js → chunk-ZGFXKYA5.js} +3 -3
- package/dist/{chunk-JZ774T7U.js.map → chunk-ZGFXKYA5.js.map} +1 -1
- package/dist/client.cjs +1106 -7
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +9 -0
- package/dist/client.d.ts +9 -0
- package/dist/client.js +56 -47
- package/dist/client.js.map +1 -1
- package/dist/components/Accordion/index.js +2 -2
- package/dist/components/Alert/index.js +2 -2
- package/dist/components/AlertDialog/index.js +2 -2
- package/dist/components/AspectRatio/index.cjs +67 -0
- package/dist/components/AspectRatio/index.cjs.map +1 -0
- package/dist/components/AspectRatio/index.d.cts +30 -0
- package/dist/components/AspectRatio/index.d.ts +30 -0
- package/dist/components/AspectRatio/index.js +5 -0
- package/dist/components/AspectRatio/index.js.map +1 -0
- package/dist/components/Avatar/index.js +2 -2
- package/dist/components/Badge/index.js +2 -2
- package/dist/components/Box/index.js +4 -4
- package/dist/components/Breadcrumb/index.js +3 -3
- package/dist/components/Button/index.js +2 -2
- package/dist/components/ButtonGroup/index.cjs +83 -0
- package/dist/components/ButtonGroup/index.cjs.map +1 -0
- package/dist/components/ButtonGroup/index.d.cts +45 -0
- package/dist/components/ButtonGroup/index.d.ts +45 -0
- package/dist/components/ButtonGroup/index.js +5 -0
- package/dist/components/ButtonGroup/index.js.map +1 -0
- package/dist/components/Calendar/index.js +3 -3
- package/dist/components/Card/index.js +2 -2
- package/dist/components/Carousel/index.cjs +297 -0
- package/dist/components/Carousel/index.cjs.map +1 -0
- package/dist/components/Carousel/index.d.cts +67 -0
- package/dist/components/Carousel/index.d.ts +67 -0
- package/dist/components/Carousel/index.js +5 -0
- package/dist/components/Carousel/index.js.map +1 -0
- package/dist/components/Checkbox/index.js +2 -2
- package/dist/components/Collapsible/index.cjs +512 -0
- package/dist/components/Collapsible/index.cjs.map +1 -0
- package/dist/components/Collapsible/index.d.cts +50 -0
- package/dist/components/Collapsible/index.d.ts +50 -0
- package/dist/components/Collapsible/index.js +7 -0
- package/dist/components/Collapsible/index.js.map +1 -0
- package/dist/components/Combobox/index.js +3 -3
- package/dist/components/ContextMenu/index.js +4 -4
- package/dist/components/DataTable/index.js +3 -3
- package/dist/components/DatePicker/index.js +5 -5
- package/dist/components/Dialog/index.js +2 -2
- package/dist/components/DropdownMenu/index.js +3 -3
- package/dist/components/Empty/index.cjs +385 -0
- package/dist/components/Empty/index.cjs.map +1 -0
- package/dist/components/Empty/index.d.cts +32 -0
- package/dist/components/Empty/index.d.ts +32 -0
- package/dist/components/Empty/index.js +7 -0
- package/dist/components/Empty/index.js.map +1 -0
- package/dist/components/FloatButton/index.js +3 -3
- package/dist/components/HStack/index.js +4 -4
- package/dist/components/HoverCard/index.cjs +894 -0
- package/dist/components/HoverCard/index.cjs.map +1 -0
- package/dist/components/HoverCard/index.d.cts +66 -0
- package/dist/components/HoverCard/index.d.ts +66 -0
- package/dist/components/HoverCard/index.js +9 -0
- package/dist/components/HoverCard/index.js.map +1 -0
- package/dist/components/InputGroup/index.js +2 -2
- package/dist/components/InputOTP/index.cjs +580 -0
- package/dist/components/InputOTP/index.cjs.map +1 -0
- package/dist/components/InputOTP/index.d.cts +49 -0
- package/dist/components/InputOTP/index.d.ts +49 -0
- package/dist/components/InputOTP/index.js +7 -0
- package/dist/components/InputOTP/index.js.map +1 -0
- package/dist/components/Item/index.cjs +443 -0
- package/dist/components/Item/index.cjs.map +1 -0
- package/dist/components/Item/index.d.cts +40 -0
- package/dist/components/Item/index.d.ts +40 -0
- package/dist/components/Item/index.js +7 -0
- package/dist/components/Item/index.js.map +1 -0
- package/dist/components/Kbd/index.cjs +396 -0
- package/dist/components/Kbd/index.cjs.map +1 -0
- package/dist/components/Kbd/index.d.cts +22 -0
- package/dist/components/Kbd/index.d.ts +22 -0
- package/dist/components/Kbd/index.js +7 -0
- package/dist/components/Kbd/index.js.map +1 -0
- package/dist/components/Pagination/index.js +4 -4
- package/dist/components/Popover/index.js +2 -2
- package/dist/components/Progress/index.js +2 -2
- package/dist/components/Radio/index.js +2 -2
- package/dist/components/SegmentedControl/index.js +2 -2
- package/dist/components/Select/index.js +2 -2
- package/dist/components/Separator/index.js +2 -2
- package/dist/components/Sheet/index.js +2 -2
- package/dist/components/Skeleton/index.js +2 -2
- package/dist/components/Slider/index.js +2 -2
- package/dist/components/Switch/index.js +2 -2
- package/dist/components/Table/index.js +2 -2
- package/dist/components/Tabs/index.js +2 -2
- package/dist/components/Text/index.js +2 -2
- package/dist/components/TextArea/index.js +3 -3
- package/dist/components/TextInput/index.js +2 -2
- package/dist/components/Toggle/index.js +2 -2
- package/dist/components/Tooltip/index.js +2 -2
- package/dist/components/VStack/index.js +4 -4
- package/dist/index.cjs +1106 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +54 -45
- package/package.json +1 -1
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { px } from './chunk-5A2QOOVN.js';
|
|
2
|
+
import { useThemeColors } from './chunk-R5JMDDCB.js';
|
|
3
|
+
import { cn } from './chunk-CHXHRJNZ.js';
|
|
4
|
+
import { __name } from './chunk-WCQVDF3K.js';
|
|
5
|
+
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
6
|
+
import { StyleSheet, Platform, View, TextInput } from 'react-native';
|
|
7
|
+
import { jsxs, jsx } from 'nativewind/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
function isAllowed(char, pattern) {
|
|
10
|
+
if (pattern === "numeric") {
|
|
11
|
+
return /^\d$/.test(char);
|
|
12
|
+
}
|
|
13
|
+
return /^[a-zA-Z0-9]$/.test(char);
|
|
14
|
+
}
|
|
15
|
+
__name(isAllowed, "isAllowed");
|
|
16
|
+
function filterValue(value, pattern, length) {
|
|
17
|
+
return value.split("").filter((c) => isAllowed(c, pattern)).slice(0, length).join("");
|
|
18
|
+
}
|
|
19
|
+
__name(filterValue, "filterValue");
|
|
20
|
+
var InputOTP = /* @__PURE__ */ __name(({
|
|
21
|
+
value = "",
|
|
22
|
+
onChange,
|
|
23
|
+
onComplete,
|
|
24
|
+
length = 6,
|
|
25
|
+
placeholder = "\xB7",
|
|
26
|
+
pattern = "numeric",
|
|
27
|
+
disabled = false,
|
|
28
|
+
autoFocus = false,
|
|
29
|
+
id,
|
|
30
|
+
name,
|
|
31
|
+
"aria-label": ariaLabel = "One-time code",
|
|
32
|
+
"aria-labelledby": ariaLabelledBy,
|
|
33
|
+
"aria-describedby": ariaDescribedBy,
|
|
34
|
+
"aria-invalid": ariaInvalid,
|
|
35
|
+
className,
|
|
36
|
+
testID
|
|
37
|
+
}) => {
|
|
38
|
+
const colors = useThemeColors();
|
|
39
|
+
const [cells, setCells] = useState(() => {
|
|
40
|
+
const filtered = filterValue(value, pattern, length);
|
|
41
|
+
return Array.from({ length }, (_, i) => filtered[i] ?? "");
|
|
42
|
+
});
|
|
43
|
+
const prevValue = useRef(value);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (value !== prevValue.current) {
|
|
46
|
+
prevValue.current = value;
|
|
47
|
+
const filtered = filterValue(value, pattern, length);
|
|
48
|
+
setCells(Array.from({ length }, (_, i) => filtered[i] ?? ""));
|
|
49
|
+
}
|
|
50
|
+
}, [value, pattern, length]);
|
|
51
|
+
const inputRefs = useRef([]);
|
|
52
|
+
const focusCell = useCallback(
|
|
53
|
+
(idx) => {
|
|
54
|
+
if (idx >= 0 && idx < length) {
|
|
55
|
+
inputRefs.current[idx]?.focus();
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
[length]
|
|
59
|
+
);
|
|
60
|
+
const updateCells = useCallback(
|
|
61
|
+
(next) => {
|
|
62
|
+
setCells(next);
|
|
63
|
+
const joined = next.join("");
|
|
64
|
+
onChange?.(joined);
|
|
65
|
+
if (joined.length === length && !next.includes("")) {
|
|
66
|
+
onComplete?.(joined);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
[onChange, onComplete, length]
|
|
70
|
+
);
|
|
71
|
+
const onContainerPaste = useCallback(
|
|
72
|
+
(e) => {
|
|
73
|
+
e.preventDefault();
|
|
74
|
+
const text = e.clipboardData.getData("text/plain") ?? "";
|
|
75
|
+
const filtered = filterValue(text, pattern, length);
|
|
76
|
+
const next = Array.from({ length }, (_, i) => filtered[i] ?? "");
|
|
77
|
+
updateCells(next);
|
|
78
|
+
const nextEmpty = next.indexOf("");
|
|
79
|
+
focusCell(nextEmpty === -1 ? length - 1 : nextEmpty);
|
|
80
|
+
},
|
|
81
|
+
[pattern, length, updateCells, focusCell]
|
|
82
|
+
);
|
|
83
|
+
const handleChangeText = useCallback(
|
|
84
|
+
(text, idx) => {
|
|
85
|
+
if (text.length > 1) {
|
|
86
|
+
const filtered = filterValue(text, pattern, length);
|
|
87
|
+
const next2 = Array.from({ length }, (_, i) => filtered[i] ?? "");
|
|
88
|
+
updateCells(next2);
|
|
89
|
+
const nextEmpty = next2.indexOf("");
|
|
90
|
+
focusCell(nextEmpty === -1 ? length - 1 : nextEmpty);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const char = text.slice(-1);
|
|
94
|
+
if (char && !isAllowed(char, pattern)) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const next = [...cells];
|
|
98
|
+
next[idx] = char;
|
|
99
|
+
updateCells(next);
|
|
100
|
+
if (char) {
|
|
101
|
+
focusCell(idx + 1);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
[cells, pattern, length, updateCells, focusCell]
|
|
105
|
+
);
|
|
106
|
+
const handleWebKeyDown = useCallback(
|
|
107
|
+
(e, idx) => {
|
|
108
|
+
if (e.key === "Backspace") {
|
|
109
|
+
if (cells[idx] !== "") {
|
|
110
|
+
const next = [...cells];
|
|
111
|
+
next[idx] = "";
|
|
112
|
+
updateCells(next);
|
|
113
|
+
} else {
|
|
114
|
+
focusCell(idx - 1);
|
|
115
|
+
}
|
|
116
|
+
e.preventDefault();
|
|
117
|
+
} else if (e.key === "ArrowLeft") {
|
|
118
|
+
focusCell(idx - 1);
|
|
119
|
+
e.preventDefault();
|
|
120
|
+
} else if (e.key === "ArrowRight") {
|
|
121
|
+
focusCell(idx + 1);
|
|
122
|
+
e.preventDefault();
|
|
123
|
+
} else if (e.key.length === 1 && isAllowed(e.key, pattern)) {
|
|
124
|
+
const next = [...cells];
|
|
125
|
+
next[idx] = e.key;
|
|
126
|
+
updateCells(next);
|
|
127
|
+
focusCell(idx + 1);
|
|
128
|
+
e.preventDefault();
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
[cells, pattern, focusCell, updateCells]
|
|
132
|
+
);
|
|
133
|
+
const handleNativeKeyPress = useCallback(
|
|
134
|
+
(e, idx) => {
|
|
135
|
+
if (e.nativeEvent.key === "Backspace") {
|
|
136
|
+
if (cells[idx] !== "") {
|
|
137
|
+
const next = [...cells];
|
|
138
|
+
next[idx] = "";
|
|
139
|
+
updateCells(next);
|
|
140
|
+
} else {
|
|
141
|
+
focusCell(idx - 1);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
[cells, focusCell, updateCells]
|
|
146
|
+
);
|
|
147
|
+
const cellStyle = [
|
|
148
|
+
styles.cell,
|
|
149
|
+
{
|
|
150
|
+
width: px(48),
|
|
151
|
+
height: px(56),
|
|
152
|
+
borderRadius: px(colors.radius.md),
|
|
153
|
+
borderColor: colors.semantic.border.default,
|
|
154
|
+
backgroundColor: colors.semantic.background.elevated,
|
|
155
|
+
color: colors.semantic.text.default,
|
|
156
|
+
fontSize: px(colors.fontSize.xl),
|
|
157
|
+
fontFamily: colors.fontFamily.body
|
|
158
|
+
},
|
|
159
|
+
disabled ? styles.disabled : null,
|
|
160
|
+
ariaInvalid === true || ariaInvalid === "true" ? { borderColor: colors.color.danger } : null
|
|
161
|
+
];
|
|
162
|
+
const isWeb = Platform.OS === "web";
|
|
163
|
+
const containerProps = isWeb ? {
|
|
164
|
+
onPaste: onContainerPaste,
|
|
165
|
+
role: "group",
|
|
166
|
+
"aria-label": ariaLabel,
|
|
167
|
+
"aria-labelledby": ariaLabelledBy,
|
|
168
|
+
"aria-describedby": ariaDescribedBy
|
|
169
|
+
} : {};
|
|
170
|
+
return /* @__PURE__ */ jsxs(
|
|
171
|
+
View,
|
|
172
|
+
{
|
|
173
|
+
testID,
|
|
174
|
+
...isWeb ? {} : { accessible: true, accessibilityLabel: ariaLabel },
|
|
175
|
+
...containerProps,
|
|
176
|
+
className: cn("flex-row items-center gap-2", className),
|
|
177
|
+
style: styles.container,
|
|
178
|
+
children: [
|
|
179
|
+
Array.from({ length }, (_, idx) => {
|
|
180
|
+
const cellValue = cells[idx] ?? "";
|
|
181
|
+
const cellRef = /* @__PURE__ */ __name((el) => {
|
|
182
|
+
inputRefs.current[idx] = el;
|
|
183
|
+
}, "cellRef");
|
|
184
|
+
const webProps = isWeb ? {
|
|
185
|
+
onKeyDown: /* @__PURE__ */ __name((e) => handleWebKeyDown(e, idx), "onKeyDown"),
|
|
186
|
+
// id only on the first cell
|
|
187
|
+
...idx === 0 && id ? { id, nativeID: id } : {},
|
|
188
|
+
...idx === 0 && name ? { name } : {},
|
|
189
|
+
...idx === 0 && ariaLabelledBy ? { "aria-labelledby": ariaLabelledBy } : {},
|
|
190
|
+
...idx === 0 && ariaDescribedBy ? { "aria-describedby": ariaDescribedBy } : {},
|
|
191
|
+
...idx === 0 && ariaInvalid !== void 0 ? { "aria-invalid": ariaInvalid } : {},
|
|
192
|
+
inputMode: pattern === "numeric" ? "numeric" : "text"
|
|
193
|
+
} : {};
|
|
194
|
+
const nativeOnlyProps = isWeb ? {} : {
|
|
195
|
+
keyboardType: pattern === "numeric" ? "number-pad" : "default",
|
|
196
|
+
textAlign: "center",
|
|
197
|
+
selectTextOnFocus: true,
|
|
198
|
+
onKeyPress: /* @__PURE__ */ __name((e) => handleNativeKeyPress(e, idx), "onKeyPress")
|
|
199
|
+
};
|
|
200
|
+
return /* @__PURE__ */ jsx(
|
|
201
|
+
TextInput,
|
|
202
|
+
{
|
|
203
|
+
ref: cellRef,
|
|
204
|
+
value: cellValue,
|
|
205
|
+
placeholder: placeholder,
|
|
206
|
+
maxLength: 1,
|
|
207
|
+
editable: !disabled,
|
|
208
|
+
autoFocus: autoFocus && idx === 0,
|
|
209
|
+
testID: testID ? `${testID}-cell-${idx}` : void 0,
|
|
210
|
+
onChangeText: (text) => handleChangeText(text, idx),
|
|
211
|
+
accessibilityLabel: `Digit ${idx + 1} of ${length}`,
|
|
212
|
+
...nativeOnlyProps,
|
|
213
|
+
...webProps,
|
|
214
|
+
style: cellStyle
|
|
215
|
+
},
|
|
216
|
+
idx
|
|
217
|
+
);
|
|
218
|
+
}),
|
|
219
|
+
isWeb && name ? /* @__PURE__ */ jsx(
|
|
220
|
+
TextInput,
|
|
221
|
+
{
|
|
222
|
+
style: styles.hidden,
|
|
223
|
+
value: cells.join(""),
|
|
224
|
+
"aria-hidden": true,
|
|
225
|
+
tabIndex: -1,
|
|
226
|
+
...{ name }
|
|
227
|
+
}
|
|
228
|
+
) : null
|
|
229
|
+
]
|
|
230
|
+
}
|
|
231
|
+
);
|
|
232
|
+
}, "InputOTP");
|
|
233
|
+
var styles = StyleSheet.create({
|
|
234
|
+
container: {
|
|
235
|
+
flexDirection: "row",
|
|
236
|
+
alignItems: "center",
|
|
237
|
+
gap: 8
|
|
238
|
+
},
|
|
239
|
+
cell: {
|
|
240
|
+
borderWidth: 1,
|
|
241
|
+
textAlign: "center"
|
|
242
|
+
},
|
|
243
|
+
disabled: {
|
|
244
|
+
opacity: 0.6
|
|
245
|
+
},
|
|
246
|
+
hidden: {
|
|
247
|
+
position: "absolute",
|
|
248
|
+
width: 0,
|
|
249
|
+
height: 0,
|
|
250
|
+
opacity: 0
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
export { InputOTP };
|
|
255
|
+
//# sourceMappingURL=chunk-BVLOX4A3.js.map
|
|
256
|
+
//# sourceMappingURL=chunk-BVLOX4A3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/InputOTP/InputOTP.tsx"],"names":["next","RNTextInput"],"mappings":"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","file":"chunk-BVLOX4A3.js","sourcesContent":["'use client';\n\nimport { type ClipboardEvent, type KeyboardEvent, useCallback, useEffect, useRef, useState } from 'react';\nimport {\n type NativeSyntheticEvent,\n Platform,\n TextInput as RNTextInput,\n StyleSheet,\n type TextInputKeyPressEventData,\n View,\n} from 'react-native';\nimport { px } from '../../theme/px';\nimport { useThemeColors } from '../../theme/use-theme-colors';\nimport { cn } from '../../utils/cn';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type InputOTPPattern = 'numeric' | 'alphanumeric';\n\nexport type InputOTPProps = {\n /** Current value (string of digits/chars, length ≤ `length`). */\n value?: string;\n /** Called with the full value string on any change. */\n onChange?: (value: string) => void;\n /** Called once the code reaches `length` characters. */\n onComplete?: (value: string) => void;\n /** Number of OTP cells. @defaultValue 6 */\n length?: number;\n /** Placeholder shown in empty cells. @defaultValue '·' */\n placeholder?: string;\n /** Input character set validation. @defaultValue 'numeric' */\n pattern?: InputOTPPattern;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /** Auto-focus the first cell on mount. */\n autoFocus?: boolean;\n /** a11y / form id forwarded to the first cell. */\n id?: string;\n /** Form field name forwarded to hidden input (web). */\n name?: string;\n /** aria-label override. @defaultValue 'One-time code' */\n 'aria-label'?: string;\n /** aria-labelledby for Field.Control wiring. */\n 'aria-labelledby'?: string;\n /** aria-describedby for Field.Control wiring. */\n 'aria-describedby'?: string;\n /** aria-invalid for Field.Control wiring. */\n 'aria-invalid'?: boolean | 'true' | 'false';\n className?: string;\n testID?: string;\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isAllowed(char: string, pattern: InputOTPPattern): boolean {\n if (pattern === 'numeric') {\n return /^\\d$/.test(char);\n }\n return /^[a-zA-Z0-9]$/.test(char);\n}\n\nfunction filterValue(value: string, pattern: InputOTPPattern, length: number): string {\n return value\n .split('')\n .filter((c) => isAllowed(c, pattern))\n .slice(0, length)\n .join('');\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Segmented one-time-code input with auto-advance, backspace backtrack,\n * and paste-to-fill. Works cross-platform (web + native) via RN TextInput refs.\n *\n * Field.Control-compatible: pass `id`, `aria-labelledby`, `aria-describedby`,\n * `aria-invalid`, and `disabled` down from Field.Control to wire a11y.\n *\n * ```tsx\n * <InputOTP value={code} onChange={setCode} onComplete={submit} length={6} />\n * ```\n */\nexport const InputOTP = ({\n value = '',\n onChange,\n onComplete,\n length = 6,\n placeholder = '·',\n pattern = 'numeric',\n disabled = false,\n autoFocus = false,\n id,\n name,\n 'aria-label': ariaLabel = 'One-time code',\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n className,\n testID,\n}: InputOTPProps) => {\n const colors = useThemeColors();\n\n // Internal representation as array of single chars\n const [cells, setCells] = useState<string[]>(() => {\n const filtered = filterValue(value, pattern, length);\n return Array.from({ length }, (_, i) => filtered[i] ?? '');\n });\n\n // Sync controlled value into cells\n const prevValue = useRef(value);\n useEffect(() => {\n if (value !== prevValue.current) {\n prevValue.current = value;\n const filtered = filterValue(value, pattern, length);\n setCells(Array.from({ length }, (_, i) => filtered[i] ?? ''));\n }\n }, [value, pattern, length]);\n\n const inputRefs = useRef<Array<RNTextInput | null>>([]);\n\n const focusCell = useCallback(\n (idx: number) => {\n if (idx >= 0 && idx < length) {\n inputRefs.current[idx]?.focus();\n }\n },\n [length]\n );\n\n const updateCells = useCallback(\n (next: string[]) => {\n setCells(next);\n const joined = next.join('');\n onChange?.(joined);\n if (joined.length === length && !next.includes('')) {\n onComplete?.(joined);\n }\n },\n [onChange, onComplete, length]\n );\n\n // -------------------------------------------------------------------------\n // Web: handle paste on the container div\n // -------------------------------------------------------------------------\n const onContainerPaste = useCallback(\n (e: ClipboardEvent<HTMLDivElement>) => {\n e.preventDefault();\n const text = e.clipboardData.getData('text/plain') ?? '';\n const filtered = filterValue(text, pattern, length);\n const next = Array.from({ length }, (_, i) => filtered[i] ?? '');\n updateCells(next);\n // Focus the next empty cell or the last\n const nextEmpty = next.indexOf('');\n focusCell(nextEmpty === -1 ? length - 1 : nextEmpty);\n },\n [pattern, length, updateCells, focusCell]\n );\n\n // -------------------------------------------------------------------------\n // Native: detect paste by checking if onChangeText receives >1 char\n // -------------------------------------------------------------------------\n const handleChangeText = useCallback(\n (text: string, idx: number) => {\n // Native paste might deliver all chars at once\n if (text.length > 1) {\n const filtered = filterValue(text, pattern, length);\n const next = Array.from({ length }, (_, i) => filtered[i] ?? '');\n updateCells(next);\n const nextEmpty = next.indexOf('');\n focusCell(nextEmpty === -1 ? length - 1 : nextEmpty);\n return;\n }\n const char = text.slice(-1); // last char in case of replacement\n if (char && !isAllowed(char, pattern)) {\n return;\n }\n const next = [...cells];\n next[idx] = char;\n updateCells(next);\n if (char) {\n focusCell(idx + 1);\n }\n },\n [cells, pattern, length, updateCells, focusCell]\n );\n\n // -------------------------------------------------------------------------\n // Web: onKeyDown per cell (for backspace + web-only arrow navigation)\n // -------------------------------------------------------------------------\n const handleWebKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>, idx: number) => {\n if (e.key === 'Backspace') {\n if (cells[idx] !== '') {\n const next = [...cells];\n next[idx] = '';\n updateCells(next);\n } else {\n focusCell(idx - 1);\n }\n e.preventDefault();\n } else if (e.key === 'ArrowLeft') {\n focusCell(idx - 1);\n e.preventDefault();\n } else if (e.key === 'ArrowRight') {\n focusCell(idx + 1);\n e.preventDefault();\n } else if (e.key.length === 1 && isAllowed(e.key, pattern)) {\n // Let onChangeText handle it, but clear the cell first so\n // single-char inputs don't accumulate\n const next = [...cells];\n next[idx] = e.key;\n updateCells(next);\n focusCell(idx + 1);\n e.preventDefault();\n }\n },\n [cells, pattern, focusCell, updateCells]\n );\n\n // -------------------------------------------------------------------------\n // Native: onKeyPress for backspace\n // -------------------------------------------------------------------------\n const handleNativeKeyPress = useCallback(\n (e: NativeSyntheticEvent<TextInputKeyPressEventData>, idx: number) => {\n if (e.nativeEvent.key === 'Backspace') {\n if (cells[idx] !== '') {\n const next = [...cells];\n next[idx] = '';\n updateCells(next);\n } else {\n focusCell(idx - 1);\n }\n }\n },\n [cells, focusCell, updateCells]\n );\n\n // -------------------------------------------------------------------------\n // Styles\n // -------------------------------------------------------------------------\n const cellStyle = [\n styles.cell,\n {\n width: px(48),\n height: px(56),\n borderRadius: px(colors.radius.md),\n borderColor: colors.semantic.border.default,\n backgroundColor: colors.semantic.background.elevated,\n color: colors.semantic.text.default,\n fontSize: px(colors.fontSize.xl),\n fontFamily: colors.fontFamily.body,\n },\n disabled ? styles.disabled : null,\n ariaInvalid === true || ariaInvalid === 'true' ? { borderColor: colors.color.danger } : null,\n ];\n\n const isWeb = Platform.OS === 'web';\n\n // -------------------------------------------------------------------------\n // Render\n // -------------------------------------------------------------------------\n const containerProps = isWeb\n ? {\n onPaste: onContainerPaste,\n role: 'group' as const,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n }\n : {};\n\n return (\n <View\n testID={testID}\n {...(isWeb ? {} : { accessible: true, accessibilityLabel: ariaLabel })}\n {...(containerProps as object)}\n className={cn('flex-row items-center gap-2', className)}\n style={styles.container}\n >\n {Array.from({ length }, (_, idx) => {\n const cellValue = cells[idx] ?? '';\n const isFocused = false; // managed by native focus system\n\n const cellRef = (el: RNTextInput | null) => {\n inputRefs.current[idx] = el;\n };\n\n // Web cell uses a standard HTML input via RN TextInput\n const webProps = isWeb\n ? {\n onKeyDown: (e: unknown) => handleWebKeyDown(e as KeyboardEvent<HTMLInputElement>, idx),\n // id only on the first cell\n ...(idx === 0 && id ? { id, nativeID: id } : {}),\n ...(idx === 0 && name ? { name } : {}),\n ...(idx === 0 && ariaLabelledBy ? { 'aria-labelledby': ariaLabelledBy } : {}),\n ...(idx === 0 && ariaDescribedBy ? { 'aria-describedby': ariaDescribedBy } : {}),\n ...(idx === 0 && ariaInvalid !== undefined ? { 'aria-invalid': ariaInvalid } : {}),\n inputMode: pattern === 'numeric' ? ('numeric' as const) : ('text' as const),\n }\n : {};\n\n // On web, omit native-only props that don't map to DOM attributes\n const nativeOnlyProps = isWeb\n ? {}\n : {\n keyboardType: pattern === 'numeric' ? ('number-pad' as const) : ('default' as const),\n textAlign: 'center' as const,\n selectTextOnFocus: true,\n onKeyPress: (e: NativeSyntheticEvent<TextInputKeyPressEventData>) =>\n handleNativeKeyPress(e, idx),\n };\n\n return (\n <RNTextInput\n // biome-ignore lint/suspicious/noArrayIndexKey: OTP cell index IS its stable slot identity\n key={idx}\n ref={cellRef}\n value={cellValue}\n placeholder={isFocused ? '' : placeholder}\n maxLength={1}\n editable={!disabled}\n autoFocus={autoFocus && idx === 0}\n testID={testID ? `${testID}-cell-${idx}` : undefined}\n onChangeText={(text) => handleChangeText(text, idx)}\n accessibilityLabel={`Digit ${idx + 1} of ${length}`}\n {...nativeOnlyProps}\n {...(webProps as object)}\n style={cellStyle}\n />\n );\n })}\n\n {/* Hidden input for form submission on web */}\n {isWeb && name ? (\n <RNTextInput\n style={styles.hidden}\n value={cells.join('')}\n aria-hidden\n tabIndex={-1}\n {...({ name } as object)}\n />\n ) : null}\n </View>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Styles\n// ---------------------------------------------------------------------------\n\nconst styles = StyleSheet.create({\n container: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n },\n cell: {\n borderWidth: 1,\n textAlign: 'center',\n },\n disabled: {\n opacity: 0.6,\n },\n hidden: {\n position: 'absolute',\n width: 0,\n height: 0,\n opacity: 0,\n },\n});\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Table } from './chunk-
|
|
1
|
+
import { Table } from './chunk-5YHT252H.js';
|
|
2
2
|
import { usePagination } from './chunk-73CUV7MW.js';
|
|
3
3
|
import { __name } from './chunk-WCQVDF3K.js';
|
|
4
4
|
import { useState, useMemo } from 'react';
|
|
@@ -198,5 +198,5 @@ function PaginationControls({
|
|
|
198
198
|
__name(PaginationControls, "PaginationControls");
|
|
199
199
|
|
|
200
200
|
export { DataTable };
|
|
201
|
-
//# sourceMappingURL=chunk-
|
|
202
|
-
//# sourceMappingURL=chunk-
|
|
201
|
+
//# sourceMappingURL=chunk-C32XGHWO.js.map
|
|
202
|
+
//# sourceMappingURL=chunk-C32XGHWO.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/DataTable/DataTable.tsx"],"names":["RNText"],"mappings":"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","file":"chunk-YZ27OS2R.js","sourcesContent":["'use client';\n\n/**\n * DataTable — convenience wrapper around Table that renders rows from a\n * `columns` + `data` array, with in-memory sort and client-side pagination.\n *\n * Deferred to v2:\n * - Server-side data (custom `onSort` / `onPaginate` callbacks)\n * - Filtering, row selection, expanding rows\n * - Column resizing, sticky headers\n * - Variable-width columns on native (v1 uses equal flex)\n */\n\nimport { type ReactNode, useMemo, useState } from 'react';\nimport { Pressable, Text as RNText, View } from 'react-native';\nimport { usePagination } from '../Pagination/use-pagination';\nimport { Table } from '../Table/Table';\nimport type { TableAlign } from '../Table/Table.shared';\n\n// ─── Column definition ────────────────────────────────────────────────────────\n\nexport type SortDirection = 'asc' | 'desc';\n\nexport type SortState = {\n id: string;\n direction: SortDirection;\n};\n\nexport type Column<T> = {\n /** Unique column identifier. Used as the sort key. */\n id: string;\n /** Content rendered in the header cell. */\n header: ReactNode;\n /** Render function for a data row. Receives the full row value. */\n cell: (row: T) => ReactNode;\n /** Enable click-to-sort on this column. @defaultValue false */\n sortable?: boolean;\n /** Horizontal alignment of cell content. @defaultValue 'left' */\n align?: TableAlign;\n};\n\n// ─── Props ────────────────────────────────────────────────────────────────────\n\nexport type DataTableProps<T extends object> = {\n /** Row data array. */\n data: T[];\n /** Column definitions. */\n columns: Column<T>[];\n /**\n * Number of rows per page.\n * @defaultValue 10\n */\n pageSize?: number;\n /**\n * Initial sort state. Must reference a `sortable` column id.\n */\n defaultSort?: SortState;\n /**\n * Called when a row is pressed (native) or clicked (web).\n */\n onRowPress?: (row: T) => void;\n /** Content shown when `data` is empty. @defaultValue \"No data\" */\n emptyState?: ReactNode;\n /** Alternating row background tinting. */\n striped?: boolean;\n /** Reduce cell padding. */\n compact?: boolean;\n /** Draw borders around cells. */\n bordered?: boolean;\n className?: string;\n testID?: string;\n};\n\n// ─── Sort helpers ─────────────────────────────────────────────────────────────\n\nfunction sortData<T extends object>(data: T[], sort: SortState | null): T[] {\n if (!sort) {\n return data;\n }\n const key = sort.id as keyof T;\n return [...data].sort((a, b) => {\n const av = a[key];\n const bv = b[key];\n if (av == null && bv == null) {\n return 0;\n }\n if (av == null) {\n return 1;\n }\n if (bv == null) {\n return -1;\n }\n const cmp = av < bv ? -1 : av > bv ? 1 : 0;\n return sort.direction === 'asc' ? cmp : -cmp;\n });\n}\n\n// ─── Sort indicator ───────────────────────────────────────────────────────────\n\nfunction SortIndicator({ direction }: { direction?: SortDirection }) {\n if (direction === undefined) {\n return <span style={{ marginLeft: 4, opacity: 0.3 }}>⇅</span>;\n }\n return <span style={{ marginLeft: 4 }}>{direction === 'asc' ? '↑' : '↓'}</span>;\n}\n\n// ─── DataTable ────────────────────────────────────────────────────────────────\n\nexport function DataTable<T extends object>({\n data,\n columns,\n pageSize = 10,\n defaultSort,\n onRowPress,\n emptyState,\n striped,\n compact,\n bordered,\n testID,\n className,\n}: DataTableProps<T>) {\n const [sort, setSort] = useState<SortState | null>(defaultSort ?? null);\n\n const sorted = useMemo(() => sortData(data, sort), [data, sort]);\n\n const pageCount = Math.max(1, Math.ceil(sorted.length / pageSize));\n const { page, goToPage, canPrev, canNext } = usePagination({ pageCount, defaultPage: 1 });\n\n const pageSlice = useMemo(() => {\n const start = (page - 1) * pageSize;\n return sorted.slice(start, start + pageSize);\n }, [sorted, page, pageSize]);\n\n const handleSort = (colId: string) => {\n setSort((prev) => {\n if (prev?.id !== colId) {\n goToPage(1);\n return { id: colId, direction: 'asc' };\n }\n if (prev.direction === 'asc') {\n return { id: colId, direction: 'desc' };\n }\n goToPage(1);\n return null;\n });\n };\n\n // Build table props without spreading undefined into exactOptionalPropertyTypes\n const tableProps: {\n striped?: boolean;\n compact?: boolean;\n bordered?: boolean;\n testID?: string;\n className?: string;\n } = {};\n if (striped !== undefined) {\n tableProps.striped = striped;\n }\n if (compact !== undefined) {\n tableProps.compact = compact;\n }\n if (bordered !== undefined) {\n tableProps.bordered = bordered;\n }\n if (testID !== undefined) {\n tableProps.testID = testID;\n }\n if (className !== undefined) {\n tableProps.className = className;\n }\n\n return (\n <View style={{ width: '100%' }}>\n <Table {...tableProps}>\n <Table.Header>\n <Table.Row>\n {columns.map((col) => {\n const align = col.align;\n return (\n <Table.HeaderCell key={col.id} {...(align !== undefined ? { align } : {})}>\n {col.sortable ? (\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel={`Sort by ${col.id}`}\n aria-label={`Sort by ${col.id}`}\n onPress={() => handleSort(col.id)}\n style={{ flexDirection: 'row', alignItems: 'center' }}\n >\n {typeof col.header === 'string' ? (\n <RNText>{col.header}</RNText>\n ) : (\n col.header\n )}\n <SortIndicator\n {...(sort?.id === col.id ? { direction: sort.direction } : {})}\n />\n </Pressable>\n ) : (\n col.header\n )}\n </Table.HeaderCell>\n );\n })}\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {pageSlice.length === 0 ? (\n <Table.Row>\n <Table.Cell colSpan={columns.length}>\n <EmptyState>{emptyState ?? 'No data'}</EmptyState>\n </Table.Cell>\n </Table.Row>\n ) : (\n pageSlice.map((row, i) => (\n <Table.Row\n // biome-ignore lint/suspicious/noArrayIndexKey: rows have no guaranteed stable id in v1; v2 will add keyExtractor\n key={i}\n {...(onRowPress !== undefined ? { onPress: () => onRowPress(row) } : {})}\n >\n {columns.map((col) => {\n const colAlign = col.align;\n return (\n <Table.Cell\n key={col.id}\n {...(colAlign !== undefined ? { align: colAlign } : {})}\n >\n {col.cell(row)}\n </Table.Cell>\n );\n })}\n </Table.Row>\n ))\n )}\n </Table.Body>\n </Table>\n\n {/* Pagination controls — only shown when there is more than one page */}\n {pageCount > 1 && (\n <PaginationControls\n page={page}\n pageCount={pageCount}\n canPrev={canPrev}\n canNext={canNext}\n goToPage={goToPage}\n />\n )}\n </View>\n );\n}\n\n// ─── Internal sub-components ──────────────────────────────────────────────────\n\nfunction EmptyState({ children }: { children: ReactNode }) {\n return (\n <View style={{ paddingVertical: 32, alignItems: 'center' }}>\n {typeof children === 'string' ? (\n <RNText style={{ color: '#888', fontSize: 14 }}>{children}</RNText>\n ) : (\n children\n )}\n </View>\n );\n}\n\nfunction PaginationControls({\n page,\n pageCount,\n canPrev,\n canNext,\n goToPage,\n}: {\n page: number;\n pageCount: number;\n canPrev: boolean;\n canNext: boolean;\n goToPage: (p: number) => void;\n}) {\n return (\n <View\n style={{\n flexDirection: 'row',\n justifyContent: 'flex-end',\n alignItems: 'center',\n paddingVertical: 8,\n gap: 8,\n }}\n >\n <Pressable\n onPress={canPrev ? () => goToPage(page - 1) : undefined}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Previous page\"\n aria-label=\"Previous page\"\n aria-disabled={!canPrev}\n style={{ opacity: canPrev ? 1 : 0.4, paddingHorizontal: 8 }}\n >\n <RNText style={{ fontSize: 14 }}>‹ Prev</RNText>\n </Pressable>\n <RNText style={{ fontSize: 14 }} aria-live=\"polite\">\n {page} / {pageCount}\n </RNText>\n <Pressable\n onPress={canNext ? () => goToPage(page + 1) : undefined}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Next page\"\n aria-label=\"Next page\"\n aria-disabled={!canNext}\n style={{ opacity: canNext ? 1 : 0.4, paddingHorizontal: 8 }}\n >\n <RNText style={{ fontSize: 14 }}>Next ›</RNText>\n </Pressable>\n </View>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/DataTable/DataTable.tsx"],"names":["RNText"],"mappings":";;;;;;;AA2EA,SAAS,QAAA,CAA2B,MAAW,IAAA,EAA6B;AACxE,EAAA,IAAI,CAAC,IAAA,EAAM;AACP,IAAA,OAAO,IAAA;AAAA,EACX;AACA,EAAA,MAAM,MAAM,IAAA,CAAK,EAAA;AACjB,EAAA,OAAO,CAAC,GAAG,IAAI,EAAE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM;AAC5B,IAAA,MAAM,EAAA,GAAK,EAAE,GAAG,CAAA;AAChB,IAAA,MAAM,EAAA,GAAK,EAAE,GAAG,CAAA;AAChB,IAAA,IAAI,EAAA,IAAM,IAAA,IAAQ,EAAA,IAAM,IAAA,EAAM;AAC1B,MAAA,OAAO,CAAA;AAAA,IACX;AACA,IAAA,IAAI,MAAM,IAAA,EAAM;AACZ,MAAA,OAAO,CAAA;AAAA,IACX;AACA,IAAA,IAAI,MAAM,IAAA,EAAM;AACZ,MAAA,OAAO,EAAA;AAAA,IACX;AACA,IAAA,MAAM,MAAM,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,KAAK,CAAA,GAAI,CAAA;AACzC,IAAA,OAAO,IAAA,CAAK,SAAA,KAAc,KAAA,GAAQ,GAAA,GAAM,CAAC,GAAA;AAAA,EAC7C,CAAC,CAAA;AACL;AApBS,MAAA,CAAA,QAAA,EAAA,UAAA,CAAA;AAwBT,SAAS,aAAA,CAAc,EAAE,SAAA,EAAU,EAAkC;AACjE,EAAA,IAAI,cAAc,MAAA,EAAW;AACzB,IAAA,uBAAO,GAAA,CAAC,UAAK,KAAA,EAAO,EAAE,YAAY,CAAA,EAAG,OAAA,EAAS,GAAA,EAAI,EAAG,QAAA,EAAA,QAAA,EAAC,CAAA;AAAA,EAC1D;AACA,EAAA,uBAAO,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,UAAA,EAAY,GAAE,EAAI,QAAA,EAAA,SAAA,KAAc,KAAA,GAAQ,QAAA,GAAM,QAAA,EAAI,CAAA;AAC5E;AALS,MAAA,CAAA,aAAA,EAAA,eAAA,CAAA;AASF,SAAS,SAAA,CAA4B;AAAA,EACxC,IAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA,GAAW,EAAA;AAAA,EACX,WAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA;AACJ,CAAA,EAAsB;AAClB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,QAAA,CAA2B,eAAe,IAAI,CAAA;AAEtE,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,MAAM,QAAA,CAAS,IAAA,EAAM,IAAI,CAAA,EAAG,CAAC,IAAA,EAAM,IAAI,CAAC,CAAA;AAE/D,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,IAAA,CAAK,MAAA,CAAO,MAAA,GAAS,QAAQ,CAAC,CAAA;AACjE,EAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,OAAA,EAAS,OAAA,EAAQ,GAAI,aAAA,CAAc,EAAE,SAAA,EAAW,WAAA,EAAa,CAAA,EAAG,CAAA;AAExF,EAAA,MAAM,SAAA,GAAY,QAAQ,MAAM;AAC5B,IAAA,MAAM,KAAA,GAAA,CAAS,OAAO,CAAA,IAAK,QAAA;AAC3B,IAAA,OAAO,MAAA,CAAO,KAAA,CAAM,KAAA,EAAO,KAAA,GAAQ,QAAQ,CAAA;AAAA,EAC/C,CAAA,EAAG,CAAC,MAAA,EAAQ,IAAA,EAAM,QAAQ,CAAC,CAAA;AAE3B,EAAA,MAAM,UAAA,2BAAc,KAAA,KAAkB;AAClC,IAAA,OAAA,CAAQ,CAAC,IAAA,KAAS;AACd,MAAA,IAAI,IAAA,EAAM,OAAO,KAAA,EAAO;AACpB,QAAA,QAAA,CAAS,CAAC,CAAA;AACV,QAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,SAAA,EAAW,KAAA,EAAM;AAAA,MACzC;AACA,MAAA,IAAI,IAAA,CAAK,cAAc,KAAA,EAAO;AAC1B,QAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,SAAA,EAAW,MAAA,EAAO;AAAA,MAC1C;AACA,MAAA,QAAA,CAAS,CAAC,CAAA;AACV,MAAA,OAAO,IAAA;AAAA,IACX,CAAC,CAAA;AAAA,EACL,CAAA,EAZmB,YAAA,CAAA;AAenB,EAAA,MAAM,aAMF,EAAC;AACL,EAAA,IAAI,YAAY,MAAA,EAAW;AACvB,IAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AAAA,EACzB;AACA,EAAA,IAAI,YAAY,MAAA,EAAW;AACvB,IAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AAAA,EACzB;AACA,EAAA,IAAI,aAAa,MAAA,EAAW;AACxB,IAAA,UAAA,CAAW,QAAA,GAAW,QAAA;AAAA,EAC1B;AACA,EAAA,IAAI,WAAW,MAAA,EAAW;AACtB,IAAA,UAAA,CAAW,MAAA,GAAS,MAAA;AAAA,EACxB;AACA,EAAA,IAAI,cAAc,MAAA,EAAW;AACzB,IAAA,UAAA,CAAW,SAAA,GAAY,SAAA;AAAA,EAC3B;AAEA,EAAA,4BACK,IAAA,EAAA,EAAK,KAAA,EAAO,EAAE,KAAA,EAAO,QAAO,EACzB,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAO,GAAG,UAAA,EACP,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,KAAA,CAAM,MAAA,EAAN,EACG,QAAA,kBAAA,GAAA,CAAC,KAAA,CAAM,KAAN,EACI,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAA,KAAQ;AAClB,QAAA,MAAM,QAAQ,GAAA,CAAI,KAAA;AAClB,QAAA,uBACI,GAAA,CAAC,KAAA,CAAM,UAAA,EAAN,EAA+B,GAAI,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAM,GAAI,EAAC,EAClE,cAAI,QAAA,mBACD,IAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACG,iBAAA,EAAkB,QAAA;AAAA,YAClB,kBAAA,EAAoB,CAAA,QAAA,EAAW,GAAA,CAAI,EAAE,CAAA,CAAA;AAAA,YACrC,YAAA,EAAY,CAAA,QAAA,EAAW,GAAA,CAAI,EAAE,CAAA,CAAA;AAAA,YAC7B,OAAA,EAAS,MAAM,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA;AAAA,YAChC,KAAA,EAAO,EAAE,aAAA,EAAe,KAAA,EAAO,YAAY,QAAA,EAAS;AAAA,YAEnD,QAAA,EAAA;AAAA,cAAA,OAAO,GAAA,CAAI,WAAW,QAAA,mBACnB,GAAA,CAACA,QAAQ,QAAA,EAAA,GAAA,CAAI,MAAA,EAAO,IAEpB,GAAA,CAAI,MAAA;AAAA,8BAER,GAAA;AAAA,gBAAC,aAAA;AAAA,gBAAA;AAAA,kBACI,GAAI,IAAA,EAAM,EAAA,KAAO,GAAA,CAAI,EAAA,GAAK,EAAE,SAAA,EAAW,IAAA,CAAK,SAAA,EAAU,GAAI;AAAC;AAAA;AAChE;AAAA;AAAA,SACJ,GAEA,GAAA,CAAI,MAAA,EAAA,EAnBW,GAAA,CAAI,EAqB3B,CAAA;AAAA,MAER,CAAC,GACL,CAAA,EACJ,CAAA;AAAA,sBACA,GAAA,CAAC,KAAA,CAAM,IAAA,EAAN,EACI,QAAA,EAAA,SAAA,CAAU,MAAA,KAAW,CAAA,mBAClB,GAAA,CAAC,KAAA,CAAM,GAAA,EAAN,EACG,QAAA,kBAAA,GAAA,CAAC,KAAA,CAAM,IAAA,EAAN,EAAW,OAAA,EAAS,OAAA,CAAQ,MAAA,EACzB,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAY,QAAA,EAAA,UAAA,IAAc,SAAA,EAAU,CAAA,EACzC,CAAA,EACJ,CAAA,GAEA,SAAA,CAAU,GAAA,CAAI,CAAC,KAAK,CAAA,qBAChB,GAAA;AAAA,QAAC,KAAA,CAAM,GAAA;AAAA,QAAN;AAAA,UAGI,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,OAAA,kBAAS,MAAA,CAAA,MAAM,UAAA,CAAW,GAAG,CAAA,EAApB,SAAA,CAAA,EAAsB,GAAI,EAAC;AAAA,UAErE,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAA,KAAQ;AAClB,YAAA,MAAM,WAAW,GAAA,CAAI,KAAA;AACrB,YAAA,uBACI,GAAA;AAAA,cAAC,KAAA,CAAM,IAAA;AAAA,cAAN;AAAA,gBAEI,GAAI,QAAA,KAAa,MAAA,GAAY,EAAE,KAAA,EAAO,QAAA,KAAa,EAAC;AAAA,gBAEpD,QAAA,EAAA,GAAA,CAAI,KAAK,GAAG;AAAA,eAAA;AAAA,cAHR,GAAA,CAAI;AAAA,aAIb;AAAA,UAER,CAAC;AAAA,SAAA;AAAA,QAbI;AAAA,OAeZ,CAAA,EAET;AAAA,KAAA,EACJ,CAAA;AAAA,IAGC,YAAY,CAAA,oBACT,GAAA;AAAA,MAAC,kBAAA;AAAA,MAAA;AAAA,QACG,IAAA;AAAA,QACA,SAAA;AAAA,QACA,OAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA;AAAA;AACJ,GAAA,EAER,CAAA;AAER;AA5IgB,MAAA,CAAA,SAAA,EAAA,WAAA,CAAA;AAgJhB,SAAS,UAAA,CAAW,EAAE,QAAA,EAAS,EAA4B;AACvD,EAAA,uBACI,GAAA,CAAC,QAAK,KAAA,EAAO,EAAE,iBAAiB,EAAA,EAAI,UAAA,EAAY,QAAA,EAAS,EACpD,QAAA,EAAA,OAAO,QAAA,KAAa,2BACjB,GAAA,CAACA,IAAA,EAAA,EAAO,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,UAAU,EAAA,EAAG,EAAI,QAAA,EAAS,CAAA,GAE1D,QAAA,EAER,CAAA;AAER;AAVS,MAAA,CAAA,UAAA,EAAA,YAAA,CAAA;AAYT,SAAS,kBAAA,CAAmB;AAAA,EACxB,IAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA;AACJ,CAAA,EAMG;AACC,EAAA,uBACI,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACG,KAAA,EAAO;AAAA,QACH,aAAA,EAAe,KAAA;AAAA,QACf,cAAA,EAAgB,UAAA;AAAA,QAChB,UAAA,EAAY,QAAA;AAAA,QACZ,eAAA,EAAiB,CAAA;AAAA,QACjB,GAAA,EAAK;AAAA,OACT;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACG,SAAS,OAAA,GAAU,MAAM,QAAA,CAAS,IAAA,GAAO,CAAC,CAAA,GAAI,MAAA;AAAA,YAC9C,iBAAA,EAAkB,QAAA;AAAA,YAClB,kBAAA,EAAmB,eAAA;AAAA,YACnB,YAAA,EAAW,eAAA;AAAA,YACX,iBAAe,CAAC,OAAA;AAAA,YAChB,OAAO,EAAE,OAAA,EAAS,UAAU,CAAA,GAAI,GAAA,EAAK,mBAAmB,CAAA,EAAE;AAAA,YAE1D,8BAACA,IAAA,EAAA,EAAO,KAAA,EAAO,EAAE,QAAA,EAAU,EAAA,IAAM,QAAA,EAAA,aAAA,EAAM;AAAA;AAAA,SAC3C;AAAA,wBACA,IAAA,CAACA,QAAO,KAAA,EAAO,EAAE,UAAU,EAAA,EAAG,EAAG,aAAU,QAAA,EACtC,QAAA,EAAA;AAAA,UAAA,IAAA;AAAA,UAAK,KAAA;AAAA,UAAI;AAAA,SAAA,EACd,CAAA;AAAA,wBACA,GAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACG,SAAS,OAAA,GAAU,MAAM,QAAA,CAAS,IAAA,GAAO,CAAC,CAAA,GAAI,MAAA;AAAA,YAC9C,iBAAA,EAAkB,QAAA;AAAA,YAClB,kBAAA,EAAmB,WAAA;AAAA,YACnB,YAAA,EAAW,WAAA;AAAA,YACX,iBAAe,CAAC,OAAA;AAAA,YAChB,OAAO,EAAE,OAAA,EAAS,UAAU,CAAA,GAAI,GAAA,EAAK,mBAAmB,CAAA,EAAE;AAAA,YAE1D,8BAACA,IAAA,EAAA,EAAO,KAAA,EAAO,EAAE,QAAA,EAAU,EAAA,IAAM,QAAA,EAAA,aAAA,EAAM;AAAA;AAAA;AAC3C;AAAA;AAAA,GACJ;AAER;AAhDS,MAAA,CAAA,kBAAA,EAAA,oBAAA,CAAA","file":"chunk-C32XGHWO.js","sourcesContent":["'use client';\n\n/**\n * DataTable — convenience wrapper around Table that renders rows from a\n * `columns` + `data` array, with in-memory sort and client-side pagination.\n *\n * Deferred to v2:\n * - Server-side data (custom `onSort` / `onPaginate` callbacks)\n * - Filtering, row selection, expanding rows\n * - Column resizing, sticky headers\n * - Variable-width columns on native (v1 uses equal flex)\n */\n\nimport { type ReactNode, useMemo, useState } from 'react';\nimport { Pressable, Text as RNText, View } from 'react-native';\nimport { usePagination } from '../Pagination/use-pagination';\nimport { Table } from '../Table/Table';\nimport type { TableAlign } from '../Table/Table.shared';\n\n// ─── Column definition ────────────────────────────────────────────────────────\n\nexport type SortDirection = 'asc' | 'desc';\n\nexport type SortState = {\n id: string;\n direction: SortDirection;\n};\n\nexport type Column<T> = {\n /** Unique column identifier. Used as the sort key. */\n id: string;\n /** Content rendered in the header cell. */\n header: ReactNode;\n /** Render function for a data row. Receives the full row value. */\n cell: (row: T) => ReactNode;\n /** Enable click-to-sort on this column. @defaultValue false */\n sortable?: boolean;\n /** Horizontal alignment of cell content. @defaultValue 'left' */\n align?: TableAlign;\n};\n\n// ─── Props ────────────────────────────────────────────────────────────────────\n\nexport type DataTableProps<T extends object> = {\n /** Row data array. */\n data: T[];\n /** Column definitions. */\n columns: Column<T>[];\n /**\n * Number of rows per page.\n * @defaultValue 10\n */\n pageSize?: number;\n /**\n * Initial sort state. Must reference a `sortable` column id.\n */\n defaultSort?: SortState;\n /**\n * Called when a row is pressed (native) or clicked (web).\n */\n onRowPress?: (row: T) => void;\n /** Content shown when `data` is empty. @defaultValue \"No data\" */\n emptyState?: ReactNode;\n /** Alternating row background tinting. */\n striped?: boolean;\n /** Reduce cell padding. */\n compact?: boolean;\n /** Draw borders around cells. */\n bordered?: boolean;\n className?: string;\n testID?: string;\n};\n\n// ─── Sort helpers ─────────────────────────────────────────────────────────────\n\nfunction sortData<T extends object>(data: T[], sort: SortState | null): T[] {\n if (!sort) {\n return data;\n }\n const key = sort.id as keyof T;\n return [...data].sort((a, b) => {\n const av = a[key];\n const bv = b[key];\n if (av == null && bv == null) {\n return 0;\n }\n if (av == null) {\n return 1;\n }\n if (bv == null) {\n return -1;\n }\n const cmp = av < bv ? -1 : av > bv ? 1 : 0;\n return sort.direction === 'asc' ? cmp : -cmp;\n });\n}\n\n// ─── Sort indicator ───────────────────────────────────────────────────────────\n\nfunction SortIndicator({ direction }: { direction?: SortDirection }) {\n if (direction === undefined) {\n return <span style={{ marginLeft: 4, opacity: 0.3 }}>⇅</span>;\n }\n return <span style={{ marginLeft: 4 }}>{direction === 'asc' ? '↑' : '↓'}</span>;\n}\n\n// ─── DataTable ────────────────────────────────────────────────────────────────\n\nexport function DataTable<T extends object>({\n data,\n columns,\n pageSize = 10,\n defaultSort,\n onRowPress,\n emptyState,\n striped,\n compact,\n bordered,\n testID,\n className,\n}: DataTableProps<T>) {\n const [sort, setSort] = useState<SortState | null>(defaultSort ?? null);\n\n const sorted = useMemo(() => sortData(data, sort), [data, sort]);\n\n const pageCount = Math.max(1, Math.ceil(sorted.length / pageSize));\n const { page, goToPage, canPrev, canNext } = usePagination({ pageCount, defaultPage: 1 });\n\n const pageSlice = useMemo(() => {\n const start = (page - 1) * pageSize;\n return sorted.slice(start, start + pageSize);\n }, [sorted, page, pageSize]);\n\n const handleSort = (colId: string) => {\n setSort((prev) => {\n if (prev?.id !== colId) {\n goToPage(1);\n return { id: colId, direction: 'asc' };\n }\n if (prev.direction === 'asc') {\n return { id: colId, direction: 'desc' };\n }\n goToPage(1);\n return null;\n });\n };\n\n // Build table props without spreading undefined into exactOptionalPropertyTypes\n const tableProps: {\n striped?: boolean;\n compact?: boolean;\n bordered?: boolean;\n testID?: string;\n className?: string;\n } = {};\n if (striped !== undefined) {\n tableProps.striped = striped;\n }\n if (compact !== undefined) {\n tableProps.compact = compact;\n }\n if (bordered !== undefined) {\n tableProps.bordered = bordered;\n }\n if (testID !== undefined) {\n tableProps.testID = testID;\n }\n if (className !== undefined) {\n tableProps.className = className;\n }\n\n return (\n <View style={{ width: '100%' }}>\n <Table {...tableProps}>\n <Table.Header>\n <Table.Row>\n {columns.map((col) => {\n const align = col.align;\n return (\n <Table.HeaderCell key={col.id} {...(align !== undefined ? { align } : {})}>\n {col.sortable ? (\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel={`Sort by ${col.id}`}\n aria-label={`Sort by ${col.id}`}\n onPress={() => handleSort(col.id)}\n style={{ flexDirection: 'row', alignItems: 'center' }}\n >\n {typeof col.header === 'string' ? (\n <RNText>{col.header}</RNText>\n ) : (\n col.header\n )}\n <SortIndicator\n {...(sort?.id === col.id ? { direction: sort.direction } : {})}\n />\n </Pressable>\n ) : (\n col.header\n )}\n </Table.HeaderCell>\n );\n })}\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {pageSlice.length === 0 ? (\n <Table.Row>\n <Table.Cell colSpan={columns.length}>\n <EmptyState>{emptyState ?? 'No data'}</EmptyState>\n </Table.Cell>\n </Table.Row>\n ) : (\n pageSlice.map((row, i) => (\n <Table.Row\n // biome-ignore lint/suspicious/noArrayIndexKey: rows have no guaranteed stable id in v1; v2 will add keyExtractor\n key={i}\n {...(onRowPress !== undefined ? { onPress: () => onRowPress(row) } : {})}\n >\n {columns.map((col) => {\n const colAlign = col.align;\n return (\n <Table.Cell\n key={col.id}\n {...(colAlign !== undefined ? { align: colAlign } : {})}\n >\n {col.cell(row)}\n </Table.Cell>\n );\n })}\n </Table.Row>\n ))\n )}\n </Table.Body>\n </Table>\n\n {/* Pagination controls — only shown when there is more than one page */}\n {pageCount > 1 && (\n <PaginationControls\n page={page}\n pageCount={pageCount}\n canPrev={canPrev}\n canNext={canNext}\n goToPage={goToPage}\n />\n )}\n </View>\n );\n}\n\n// ─── Internal sub-components ──────────────────────────────────────────────────\n\nfunction EmptyState({ children }: { children: ReactNode }) {\n return (\n <View style={{ paddingVertical: 32, alignItems: 'center' }}>\n {typeof children === 'string' ? (\n <RNText style={{ color: '#888', fontSize: 14 }}>{children}</RNText>\n ) : (\n children\n )}\n </View>\n );\n}\n\nfunction PaginationControls({\n page,\n pageCount,\n canPrev,\n canNext,\n goToPage,\n}: {\n page: number;\n pageCount: number;\n canPrev: boolean;\n canNext: boolean;\n goToPage: (p: number) => void;\n}) {\n return (\n <View\n style={{\n flexDirection: 'row',\n justifyContent: 'flex-end',\n alignItems: 'center',\n paddingVertical: 8,\n gap: 8,\n }}\n >\n <Pressable\n onPress={canPrev ? () => goToPage(page - 1) : undefined}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Previous page\"\n aria-label=\"Previous page\"\n aria-disabled={!canPrev}\n style={{ opacity: canPrev ? 1 : 0.4, paddingHorizontal: 8 }}\n >\n <RNText style={{ fontSize: 14 }}>‹ Prev</RNText>\n </Pressable>\n <RNText style={{ fontSize: 14 }} aria-live=\"polite\">\n {page} / {pageCount}\n </RNText>\n <Pressable\n onPress={canNext ? () => goToPage(page + 1) : undefined}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Next page\"\n aria-label=\"Next page\"\n aria-disabled={!canNext}\n style={{ opacity: canNext ? 1 : 0.4, paddingHorizontal: 8 }}\n >\n <RNText style={{ fontSize: 14 }}>Next ›</RNText>\n </Pressable>\n </View>\n );\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { px } from './chunk-5A2QOOVN.js';
|
|
2
|
-
import { cn } from './chunk-CHXHRJNZ.js';
|
|
3
2
|
import { useThemeColors } from './chunk-R5JMDDCB.js';
|
|
3
|
+
import { cn } from './chunk-CHXHRJNZ.js';
|
|
4
4
|
import { __name } from './chunk-WCQVDF3K.js';
|
|
5
5
|
import { createContext, useId, useState, useRef, useCallback, Children, useMemo, useContext, isValidElement } from 'react';
|
|
6
6
|
import { Text, View, TextInput, Platform, Pressable } from 'react-native';
|
|
@@ -310,5 +310,5 @@ var InputGroup = Object.assign(InputGroupRoot, {
|
|
|
310
310
|
});
|
|
311
311
|
|
|
312
312
|
export { InputGroup };
|
|
313
|
-
//# sourceMappingURL=chunk-
|
|
314
|
-
//# sourceMappingURL=chunk-
|
|
313
|
+
//# sourceMappingURL=chunk-C5HQPXRI.js.map
|
|
314
|
+
//# sourceMappingURL=chunk-C5HQPXRI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/InputGroup/InputGroup.tsx"],"names":["RNText","RNTextInput"],"mappings":"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","file":"chunk-UJWCEGQY.js","sourcesContent":["'use client';\n\nimport {\n Children,\n createContext,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { TextInput as RNTextInputType, TextStyle, ViewStyle } from 'react-native';\nimport { Platform, Pressable, Text as RNText, TextInput as RNTextInput, View } from 'react-native';\nimport { px } from '../../theme/px';\nimport { useThemeColors } from '../../theme/use-theme-colors';\nimport { cn } from '../../utils/cn';\nimport type { TextInputProps } from '../TextInput/TextInput';\n\n// ─── Internal context ─────────────────────────────────────────────────────\n//\n// Lets the addons + input share focus, error, and disabled state so the\n// WHOLE group's border lights up on focus and dimming cascades visually\n// without consumers having to duplicate props on every child.\ntype InputGroupContextValue = {\n inputId: string;\n describeId: string;\n setFocused: (next: boolean) => void;\n hasError: boolean;\n disabled: boolean;\n inputRef: React.MutableRefObject<RNTextInputType | null>;\n focusInput: () => void;\n};\n\nconst InputGroupContext = createContext<InputGroupContextValue | null>(null);\n\nconst useInputGroupContext = (label: string): InputGroupContextValue => {\n const ctx = useContext(InputGroupContext);\n if (!ctx) {\n throw new Error(`<${label}> must be rendered inside an <InputGroup>.`);\n }\n return ctx;\n};\n\n// Marker symbols on the child component functions so we can split children\n// into [prefix, input, suffix] without forcing consumers to pass `position`\n// props or use named slots. Whatever sits before the InputGroupInput is a\n// prefix; whatever sits after is a suffix.\nconst ADDON_TYPE = Symbol.for('nori-ui.InputGroupAddon');\nconst INPUT_TYPE = Symbol.for('nori-ui.InputGroupInput');\n\nconst isAddon = (child: unknown): child is ReactElement =>\n isValidElement(child) && (child.type as { __noriType?: symbol })?.__noriType === ADDON_TYPE;\n\nconst isInput = (child: unknown): child is ReactElement<InputGroupInputProps> =>\n isValidElement(child) && (child.type as { __noriType?: symbol })?.__noriType === INPUT_TYPE;\n\n// ─── Container ────────────────────────────────────────────────────────────\n\n// Layout-only bases; theme-driven dimensions are merged inside the\n// component below.\nconst CONTAINER_LAYOUT_BASE: ViewStyle = { flexDirection: 'column' };\nconst FIELD_LAYOUT_BASE: ViewStyle = {\n flexDirection: 'row',\n alignItems: 'stretch',\n borderWidth: 1,\n overflow: 'hidden',\n};\n\nexport type InputGroupProps = {\n children: ReactNode;\n /** Mark the entire group as disabled — cascades visually to addons + input. */\n disabled?: boolean;\n /** Mark the entire group as errored — cascades visually to addons + input. */\n error?: boolean;\n className?: string;\n containerClassName?: string;\n testID?: string;\n};\n\n/**\n * Wrapper that visually fuses prefix and/or suffix addons with a TextInput\n * into a SINGLE rounded field — one border around the whole compound, not\n * three separate boxes. Inspired by Chakra's InputGroup and shadcn's input\n * addon pattern.\n *\n * @example\n * <InputGroup>\n * <InputGroupAddon>@</InputGroupAddon>\n * <InputGroupInput placeholder=\"username\" />\n * </InputGroup>\n *\n * @example with both prefix and suffix\n * <InputGroup>\n * <InputGroupAddon>https://</InputGroupAddon>\n * <InputGroupInput defaultValue=\"example\" />\n * <InputGroupAddon>.com</InputGroupAddon>\n * </InputGroup>\n */\nconst InputGroupRoot = ({\n children,\n disabled = false,\n error: groupErrorProp = false,\n className,\n containerClassName,\n testID,\n}: InputGroupProps) => {\n const colors = useThemeColors();\n const reactId = useId();\n const inputId = `nori-ui-input-${reactId}`;\n const describeId = `${inputId}-describe`;\n const [focused, setFocused] = useState(false);\n const inputRef = useRef<RNTextInputType | null>(null);\n\n // Stable identity (does not depend on render-cycle state) so the\n // useMemo below can leave it out of the dep array without lint noise.\n const focusInput = useCallback(() => {\n inputRef.current?.focus();\n }, []);\n\n // Walk children once, split into [prefix, input, suffix]. Anything that\n // isn't a recognised marker gets dropped — the API guarantees a single\n // integrated bar, not arbitrary slots.\n const childArray = Children.toArray(children);\n const inputIndex = childArray.findIndex(isInput);\n const inputElement = inputIndex >= 0 ? (childArray[inputIndex] as ReactElement<InputGroupInputProps>) : null;\n const prefixNodes = inputIndex >= 0 ? childArray.slice(0, inputIndex).filter(isAddon) : [];\n const suffixNodes = inputIndex >= 0 ? childArray.slice(inputIndex + 1).filter(isAddon) : [];\n\n // Lift label / helperText / error from the input element so the parent\n // can render them OUTSIDE the bordered field row (a normal field layout\n // wraps the box with label above and helper/error below).\n const inputProps = inputElement?.props ?? ({} as InputGroupInputProps);\n const label = inputProps.label;\n const helperText = inputProps.helperText;\n const inputError = inputProps.error;\n\n const hasError = Boolean(groupErrorProp) || Boolean(inputError);\n\n const ctx = useMemo<InputGroupContextValue>(\n () => ({\n inputId,\n describeId,\n setFocused,\n hasError,\n disabled,\n inputRef,\n focusInput,\n }),\n [inputId, describeId, hasError, disabled, focusInput]\n );\n\n const borderColor = hasError\n ? colors.color.danger\n : focused\n ? colors.semantic.interactive.primary\n : colors.semantic.border.default;\n\n const fieldStyle = [\n FIELD_LAYOUT_BASE,\n {\n borderRadius: px(colors.radius.md),\n backgroundColor: colors.semantic.background.elevated,\n borderColor,\n },\n disabled ? { opacity: 0.6 } : null,\n ];\n\n const labelStyle: TextStyle = {\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize.sm),\n fontWeight: colors.fontWeight.medium as '500',\n color: colors.semantic.text.default,\n };\n const helperStyle: TextStyle = {\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize.sm),\n color: colors.semantic.text.muted,\n };\n const errorStyle: TextStyle = {\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize.sm),\n color: colors.color.danger,\n };\n const containerStyle: ViewStyle = { ...CONTAINER_LAYOUT_BASE, gap: px(colors.spacing['1']) };\n\n return (\n <View\n {...(testID !== undefined ? { testID } : {})}\n className={cn('flex flex-col gap-1', containerClassName)}\n style={containerStyle}\n >\n {label !== undefined ? (\n // On web we render a real <label htmlFor> so clicking the\n // label focuses the input the standard a11y way (and so\n // jsdom-based tests can assert the label↔input\n // association via the `for` attribute).\n //\n // On native, raw <label> is not a valid host component\n // and RN crashes with \"View config getter callback for\n // component `label` must be a function\". The native\n // path renders an RNText instead — the underlying\n // RNTextInput still carries accessibilityLabel for\n // screen readers, so the visible text + the a11y name\n // remain in sync. Same web-only `<label>` story as\n // TextInput's earlier iteration; this branch is the\n // explicit native-safe fallback.\n Platform.OS === 'web' ? (\n <label\n htmlFor={inputId}\n className=\"text-sm font-medium text-semantic-text-default\"\n style={labelStyle as object}\n >\n {label}\n </label>\n ) : (\n <RNText\n nativeID={`${inputId}-label`}\n accessibilityRole=\"text\"\n className=\"text-sm font-medium text-semantic-text-default\"\n style={labelStyle}\n >\n {label}\n </RNText>\n )\n ) : null}\n <InputGroupContext.Provider value={ctx}>\n <View\n className={cn(\n 'flex-row items-stretch overflow-hidden rounded-md border focus-within:border-semantic-interactive-primary',\n hasError ? 'border-semantic-interactive-destructive' : 'border-semantic-border-default',\n disabled ? 'opacity-60' : undefined,\n className\n )}\n style={fieldStyle}\n >\n {prefixNodes.map((node, i) => {\n const key = (node as ReactElement & { key?: string | null }).key ?? `prefix-${i}`;\n return (\n <AddonSlot key={key} side=\"left\">\n {node}\n </AddonSlot>\n );\n })}\n {inputElement}\n {suffixNodes.map((node, i) => {\n const key = (node as ReactElement & { key?: string | null }).key ?? `suffix-${i}`;\n return (\n <AddonSlot key={key} side=\"right\">\n {node}\n </AddonSlot>\n );\n })}\n </View>\n </InputGroupContext.Provider>\n {inputError ? (\n <RNText\n nativeID={describeId}\n className=\"text-sm text-semantic-interactive-destructive\"\n style={errorStyle}\n >\n {inputError}\n </RNText>\n ) : helperText ? (\n <RNText nativeID={describeId} className=\"text-sm text-semantic-text-muted\" style={helperStyle}>\n {helperText}\n </RNText>\n ) : null}\n </View>\n );\n};\n\n// ─── Addon slot ───────────────────────────────────────────────────────────\n//\n// Internal wrapper that paints the muted background, draws the 1px vertical\n// separator on the input-facing side, and forwards a click to the input so\n// the addon reads as decorator, not as something interactive.\nconst AddonSlot = ({ children, side }: { children: ReactNode; side: 'left' | 'right' }) => {\n const colors = useThemeColors();\n const ctx = useContext(InputGroupContext);\n const dim = ctx?.disabled ? 0.85 : 1;\n\n const baseStyle: ViewStyle = {\n backgroundColor: colors.semantic.background.subtle,\n paddingHorizontal: px(colors.spacing['3']),\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n opacity: dim,\n };\n\n const separatorStyle: ViewStyle =\n side === 'left'\n ? { borderRightWidth: 1, borderRightColor: colors.semantic.border.default }\n : { borderLeftWidth: 1, borderLeftColor: colors.semantic.border.default };\n\n const handlePress = () => {\n ctx?.focusInput();\n };\n\n return (\n <Pressable\n // Pressing the addon focuses the input — addons are decorators,\n // never tab stops. RN's `accessibilityRole` doesn't accept \"presentation\"\n // (web-only), so we set the WAI-ARIA role via the web prop instead.\n onPress={handlePress}\n role=\"none\"\n // RN web maps `focusable={false}` to `tabIndex={-1}`.\n focusable={false}\n style={[baseStyle, separatorStyle]}\n className={cn(\n 'flex-row items-center justify-center px-3 bg-semantic-background-subtle',\n side === 'right' ? 'border-l border-semantic-border-default' : 'border-r border-semantic-border-default'\n )}\n >\n {children}\n </Pressable>\n );\n};\n\n// ─── Addon (public) ───────────────────────────────────────────────────────\n\nexport type InputGroupAddonProps = {\n children: ReactNode;\n className?: string;\n testID?: string;\n};\n\n/**\n * Decorator slot inside an `<InputGroup>`. Renders a muted, non-interactive\n * box that visually fuses with the input. Place before `<InputGroupInput>`\n * for a prefix, after for a suffix. Accepts strings or `ReactNode` (icons).\n */\nexport const InputGroupAddon = ({ children, className, testID }: InputGroupAddonProps) => {\n const colors = useThemeColors();\n const textStyle: TextStyle = {\n color: colors.semantic.text.muted,\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize.sm),\n };\n\n // Wrap raw strings/numbers so consumers can pass `\"@\"` or `<MailIcon />`\n // and both render correctly without callers tripping over RN's \"text\n // outside of <Text>\" warning.\n if (typeof children === 'string' || typeof children === 'number') {\n return (\n <RNText\n {...(testID !== undefined ? { testID } : {})}\n className={cn('text-sm text-semantic-text-muted', className)}\n style={textStyle}\n >\n {children}\n </RNText>\n );\n }\n\n return (\n <View {...(testID !== undefined ? { testID } : {})} {...(className !== undefined ? { className } : {})}>\n {children}\n </View>\n );\n};\n\n// Brand the function so the parent can locate it via Children.toArray walk.\n(InputGroupAddon as unknown as { __noriType: symbol }).__noriType = ADDON_TYPE;\n\n// ─── Input (public) ───────────────────────────────────────────────────────\n\n// Layout-only base; theme-driven dimensions are merged inside InputGroupInput.\nconst INPUT_LAYOUT_BASE: TextStyle = {\n flex: 1,\n // RN web honours `outlineStyle: 'none'` to suppress the default browser\n // focus ring — the group's own focus-within border replaces it.\n outlineStyle: 'none' as unknown as TextStyle['outlineStyle'],\n};\n\nexport type InputGroupInputProps = TextInputProps & {\n /** Label rendered above the bordered field row by the parent InputGroup. */\n label?: string;\n /** Helper text rendered below the bordered field row by the parent InputGroup. */\n helperText?: string;\n /** Error message rendered below the bordered field row by the parent InputGroup. */\n error?: string;\n};\n\n/**\n * The text field inside an `<InputGroup>`. Extends the full `TextInput` API\n * (label, helperText, error, disabled, etc.) so consumers don't lose any\n * functionality when reaching for the integrated layout.\n *\n * Implementation note: this renders a bare RN `TextInput` because the\n * surrounding `<InputGroup>` already paints the border + label + helper —\n * those bits are lifted to the parent so they render OUTSIDE the bordered\n * field row, the way a normal field's label/helper sits above/below the box.\n */\nexport const InputGroupInput = ({\n label: _label,\n helperText: _helperText,\n error,\n disabled,\n onChangeText,\n onFocus,\n onBlur,\n multiline,\n numberOfLines,\n leading: _leading,\n trailing: _trailing,\n containerClassName: _containerClassName,\n className,\n testID,\n ...rest\n}: InputGroupInputProps) => {\n const colors = useThemeColors();\n const ctx = useInputGroupContext('InputGroupInput');\n const inputId = ctx.inputId;\n const describeId = ctx.describeId;\n const isDisabled = disabled || ctx.disabled;\n const hasError = Boolean(error) || ctx.hasError;\n\n const inputExtras: Record<string, unknown> = {};\n if (testID !== undefined) {\n inputExtras.testID = testID;\n }\n if (_label !== undefined) {\n inputExtras.accessibilityLabel = _label;\n }\n if (hasError) {\n inputExtras['aria-invalid'] = true;\n }\n if (error || _helperText) {\n inputExtras['aria-describedby'] = describeId;\n }\n if (multiline !== undefined) {\n inputExtras.multiline = multiline;\n }\n if (numberOfLines !== undefined) {\n inputExtras.numberOfLines = numberOfLines;\n }\n if (onChangeText !== undefined) {\n inputExtras.onChangeText = onChangeText;\n }\n\n const inputStyle: TextStyle = {\n ...INPUT_LAYOUT_BASE,\n paddingVertical: px(colors.spacing['2']),\n paddingHorizontal: px(colors.spacing['3']),\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize.md),\n color: colors.semantic.text.default,\n };\n\n return (\n <RNTextInput\n ref={(node) => {\n ctx.inputRef.current = node;\n }}\n nativeID={inputId}\n editable={!isDisabled}\n className={cn('flex-1 py-2 px-3 text-md text-semantic-text-default outline-none bg-transparent', className)}\n placeholderTextColor={colors.semantic.text.muted}\n onFocus={(e) => {\n ctx.setFocused(true);\n onFocus?.(e);\n }}\n onBlur={(e) => {\n ctx.setFocused(false);\n onBlur?.(e);\n }}\n {...inputExtras}\n {...rest}\n style={[inputStyle, rest.style]}\n />\n );\n};\n\n(InputGroupInput as unknown as { __noriType: symbol }).__noriType = INPUT_TYPE;\n\n/**\n * Public `InputGroup` value — the root function plus its `.Addon` and `.Input`\n * static members. `Object.assign` produces a value whose inferred type carries\n * the static properties, so `.d.ts` consumers can write `<InputGroup.Addon>`\n * without a separate import.\n */\nexport const InputGroup = Object.assign(InputGroupRoot, {\n Addon: InputGroupAddon,\n Input: InputGroupInput,\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/InputGroup/InputGroup.tsx"],"names":["RNText","RNTextInput"],"mappings":";;;;;;;;AAqCA,IAAM,iBAAA,GAAoB,cAA6C,IAAI,CAAA;AAE3E,IAAM,oBAAA,2BAAwB,KAAA,KAA0C;AACpE,EAAA,MAAM,GAAA,GAAM,WAAW,iBAAiB,CAAA;AACxC,EAAA,IAAI,CAAC,GAAA,EAAK;AACN,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,CAAA,EAAI,KAAK,CAAA,0CAAA,CAA4C,CAAA;AAAA,EACzE;AACA,EAAA,OAAO,GAAA;AACX,CAAA,EAN6B,sBAAA,CAAA;AAY7B,IAAM,UAAA,mBAAa,MAAA,CAAO,GAAA,CAAI,yBAAyB,CAAA;AACvD,IAAM,UAAA,mBAAa,MAAA,CAAO,GAAA,CAAI,yBAAyB,CAAA;AAEvD,IAAM,OAAA,2BAAW,KAAA,KACb,cAAA,CAAe,KAAK,CAAA,IAAM,KAAA,CAAM,IAAA,EAAkC,UAAA,KAAe,UAAA,EADrE,SAAA,CAAA;AAGhB,IAAM,OAAA,2BAAW,KAAA,KACb,cAAA,CAAe,KAAK,CAAA,IAAM,KAAA,CAAM,IAAA,EAAkC,UAAA,KAAe,UAAA,EADrE,SAAA,CAAA;AAOhB,IAAM,qBAAA,GAAmC,EAAE,aAAA,EAAe,QAAA,EAAS;AACnE,IAAM,iBAAA,GAA+B;AAAA,EACjC,aAAA,EAAe,KAAA;AAAA,EACf,UAAA,EAAY,SAAA;AAAA,EACZ,WAAA,EAAa,CAAA;AAAA,EACb,QAAA,EAAU;AACd,CAAA;AAgCA,IAAM,iCAAiB,MAAA,CAAA,CAAC;AAAA,EACpB,QAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,OAAO,cAAA,GAAiB,KAAA;AAAA,EACxB,SAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACJ,CAAA,KAAuB;AACnB,EAAA,MAAM,SAAS,cAAA,EAAe;AAC9B,EAAA,MAAM,UAAU,KAAA,EAAM;AACtB,EAAA,MAAM,OAAA,GAAU,iBAAiB,OAAO,CAAA,CAAA;AACxC,EAAA,MAAM,UAAA,GAAa,GAAG,OAAO,CAAA,SAAA,CAAA;AAC7B,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,QAAA,GAAW,OAA+B,IAAI,CAAA;AAIpD,EAAA,MAAM,UAAA,GAAa,YAAY,MAAM;AACjC,IAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AAAA,EAC5B,CAAA,EAAG,EAAE,CAAA;AAKL,EAAA,MAAM,UAAA,GAAa,QAAA,CAAS,OAAA,CAAQ,QAAQ,CAAA;AAC5C,EAAA,MAAM,UAAA,GAAa,UAAA,CAAW,SAAA,CAAU,OAAO,CAAA;AAC/C,EAAA,MAAM,YAAA,GAAe,UAAA,IAAc,CAAA,GAAK,UAAA,CAAW,UAAU,CAAA,GAA2C,IAAA;AACxG,EAAA,MAAM,WAAA,GAAc,UAAA,IAAc,CAAA,GAAI,UAAA,CAAW,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,GAAI,EAAC;AACzF,EAAA,MAAM,WAAA,GAAc,UAAA,IAAc,CAAA,GAAI,UAAA,CAAW,KAAA,CAAM,UAAA,GAAa,CAAC,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,GAAI,EAAC;AAK1F,EAAA,MAAM,UAAA,GAAa,YAAA,EAAc,KAAA,IAAU,EAAC;AAC5C,EAAA,MAAM,QAAQ,UAAA,CAAW,KAAA;AACzB,EAAA,MAAM,aAAa,UAAA,CAAW,UAAA;AAC9B,EAAA,MAAM,aAAa,UAAA,CAAW,KAAA;AAE9B,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,cAAc,CAAA,IAAK,QAAQ,UAAU,CAAA;AAE9D,EAAA,MAAM,GAAA,GAAM,OAAA;AAAA,IACR,OAAO;AAAA,MACH,OAAA;AAAA,MACA,UAAA;AAAA,MACA,UAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACJ,CAAA;AAAA,IACA,CAAC,OAAA,EAAS,UAAA,EAAY,QAAA,EAAU,UAAU,UAAU;AAAA,GACxD;AAEA,EAAA,MAAM,WAAA,GAAc,QAAA,GACd,MAAA,CAAO,KAAA,CAAM,MAAA,GACb,OAAA,GACE,MAAA,CAAO,QAAA,CAAS,WAAA,CAAY,OAAA,GAC5B,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,OAAA;AAE/B,EAAA,MAAM,UAAA,GAAa;AAAA,IACf,iBAAA;AAAA,IACA;AAAA,MACI,YAAA,EAAc,EAAA,CAAG,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA;AAAA,MACjC,eAAA,EAAiB,MAAA,CAAO,QAAA,CAAS,UAAA,CAAW,QAAA;AAAA,MAC5C;AAAA,KACJ;AAAA,IACA,QAAA,GAAW,EAAE,OAAA,EAAS,GAAA,EAAI,GAAI;AAAA,GAClC;AAEA,EAAA,MAAM,UAAA,GAAwB;AAAA,IAC1B,UAAA,EAAY,OAAO,UAAA,CAAW,IAAA;AAAA,IAC9B,QAAA,EAAU,EAAA,CAAG,MAAA,CAAO,QAAA,CAAS,EAAE,CAAA;AAAA,IAC/B,UAAA,EAAY,OAAO,UAAA,CAAW,MAAA;AAAA,IAC9B,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK;AAAA,GAChC;AACA,EAAA,MAAM,WAAA,GAAyB;AAAA,IAC3B,UAAA,EAAY,OAAO,UAAA,CAAW,IAAA;AAAA,IAC9B,QAAA,EAAU,EAAA,CAAG,MAAA,CAAO,QAAA,CAAS,EAAE,CAAA;AAAA,IAC/B,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK;AAAA,GAChC;AACA,EAAA,MAAM,UAAA,GAAwB;AAAA,IAC1B,UAAA,EAAY,OAAO,UAAA,CAAW,IAAA;AAAA,IAC9B,QAAA,EAAU,EAAA,CAAG,MAAA,CAAO,QAAA,CAAS,EAAE,CAAA;AAAA,IAC/B,KAAA,EAAO,OAAO,KAAA,CAAM;AAAA,GACxB;AACA,EAAA,MAAM,cAAA,GAA4B,EAAE,GAAG,qBAAA,EAAuB,GAAA,EAAK,GAAG,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAC,CAAA,EAAE;AAE3F,EAAA,uBACI,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACI,GAAI,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,KAAW,EAAC;AAAA,MAC1C,SAAA,EAAW,EAAA,CAAG,qBAAA,EAAuB,kBAAkB,CAAA;AAAA,MACvD,KAAA,EAAO,cAAA;AAAA,MAEN,QAAA,EAAA;AAAA,QAAA,KAAA,KAAU,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAeP,QAAA,CAAS,OAAO,KAAA,mBACZ,GAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACG,OAAA,EAAS,OAAA;AAAA,cACT,SAAA,EAAU,gDAAA;AAAA,cACV,KAAA,EAAO,UAAA;AAAA,cAEN,QAAA,EAAA;AAAA;AAAA,WACL,mBAEA,GAAA;AAAA,YAACA,IAAA;AAAA,YAAA;AAAA,cACG,QAAA,EAAU,GAAG,OAAO,CAAA,MAAA,CAAA;AAAA,cACpB,iBAAA,EAAkB,MAAA;AAAA,cAClB,SAAA,EAAU,gDAAA;AAAA,cACV,KAAA,EAAO,UAAA;AAAA,cAEN,QAAA,EAAA;AAAA;AAAA;AACL,YAEJ,IAAA;AAAA,wBACJ,GAAA,CAAC,iBAAA,CAAkB,QAAA,EAAlB,EAA2B,OAAO,GAAA,EAC/B,QAAA,kBAAA,IAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACG,SAAA,EAAW,EAAA;AAAA,cACP,2GAAA;AAAA,cACA,WAAW,yCAAA,GAA4C,gCAAA;AAAA,cACvD,WAAW,YAAA,GAAe,MAAA;AAAA,cAC1B;AAAA,aACJ;AAAA,YACA,KAAA,EAAO,UAAA;AAAA,YAEN,QAAA,EAAA;AAAA,cAAA,WAAA,CAAY,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,KAAM;AAC1B,gBAAA,MAAM,GAAA,GAAO,IAAA,CAAgD,GAAA,IAAO,CAAA,OAAA,EAAU,CAAC,CAAA,CAAA;AAC/E,gBAAA,uBACI,GAAA,CAAC,SAAA,EAAA,EAAoB,IAAA,EAAK,MAAA,EACrB,kBADW,GAEhB,CAAA;AAAA,cAER,CAAC,CAAA;AAAA,cACA,YAAA;AAAA,cACA,WAAA,CAAY,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,KAAM;AAC1B,gBAAA,MAAM,GAAA,GAAO,IAAA,CAAgD,GAAA,IAAO,CAAA,OAAA,EAAU,CAAC,CAAA,CAAA;AAC/E,gBAAA,uBACI,GAAA,CAAC,SAAA,EAAA,EAAoB,IAAA,EAAK,OAAA,EACrB,kBADW,GAEhB,CAAA;AAAA,cAER,CAAC;AAAA;AAAA;AAAA,SACL,EACJ,CAAA;AAAA,QACC,UAAA,mBACG,GAAA;AAAA,UAACA,IAAA;AAAA,UAAA;AAAA,YACG,QAAA,EAAU,UAAA;AAAA,YACV,SAAA,EAAU,+CAAA;AAAA,YACV,KAAA,EAAO,UAAA;AAAA,YAEN,QAAA,EAAA;AAAA;AAAA,SACL,GACA,UAAA,mBACA,GAAA,CAACA,IAAA,EAAA,EAAO,QAAA,EAAU,UAAA,EAAY,SAAA,EAAU,kCAAA,EAAmC,KAAA,EAAO,WAAA,EAC7E,QAAA,EAAA,UAAA,EACL,CAAA,GACA;AAAA;AAAA;AAAA,GACR;AAER,CAAA,EA3KuB,gBAAA,CAAA;AAkLvB,IAAM,SAAA,mBAAY,MAAA,CAAA,CAAC,EAAE,QAAA,EAAU,MAAK,KAAuD;AACvF,EAAA,MAAM,SAAS,cAAA,EAAe;AAC9B,EAAA,MAAM,GAAA,GAAM,WAAW,iBAAiB,CAAA;AACxC,EAAA,MAAM,GAAA,GAAM,GAAA,EAAK,QAAA,GAAW,IAAA,GAAO,CAAA;AAEnC,EAAA,MAAM,SAAA,GAAuB;AAAA,IACzB,eAAA,EAAiB,MAAA,CAAO,QAAA,CAAS,UAAA,CAAW,MAAA;AAAA,IAC5C,iBAAA,EAAmB,EAAA,CAAG,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAC,CAAA;AAAA,IACzC,aAAA,EAAe,KAAA;AAAA,IACf,UAAA,EAAY,QAAA;AAAA,IACZ,cAAA,EAAgB,QAAA;AAAA,IAChB,OAAA,EAAS;AAAA,GACb;AAEA,EAAA,MAAM,iBACF,IAAA,KAAS,MAAA,GACH,EAAE,gBAAA,EAAkB,CAAA,EAAG,kBAAkB,MAAA,CAAO,QAAA,CAAS,OAAO,OAAA,EAAQ,GACxE,EAAE,eAAA,EAAiB,CAAA,EAAG,iBAAiB,MAAA,CAAO,QAAA,CAAS,OAAO,OAAA,EAAQ;AAEhF,EAAA,MAAM,8BAAc,MAAA,CAAA,MAAM;AACtB,IAAA,GAAA,EAAK,UAAA,EAAW;AAAA,EACpB,CAAA,EAFoB,aAAA,CAAA;AAIpB,EAAA,uBACI,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MAIG,OAAA,EAAS,WAAA;AAAA,MACT,IAAA,EAAK,MAAA;AAAA,MAEL,SAAA,EAAW,KAAA;AAAA,MACX,KAAA,EAAO,CAAC,SAAA,EAAW,cAAc,CAAA;AAAA,MACjC,SAAA,EAAW,EAAA;AAAA,QACP,yEAAA;AAAA,QACA,IAAA,KAAS,UAAU,yCAAA,GAA4C;AAAA,OACnE;AAAA,MAEC;AAAA;AAAA,GACL;AAER,CAAA,EAzCkB,WAAA,CAAA;AAwDX,IAAM,kCAAkB,MAAA,CAAA,CAAC,EAAE,QAAA,EAAU,SAAA,EAAW,QAAO,KAA4B;AACtF,EAAA,MAAM,SAAS,cAAA,EAAe;AAC9B,EAAA,MAAM,SAAA,GAAuB;AAAA,IACzB,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,KAAA;AAAA,IAC5B,UAAA,EAAY,OAAO,UAAA,CAAW,IAAA;AAAA,IAC9B,QAAA,EAAU,EAAA,CAAG,MAAA,CAAO,QAAA,CAAS,EAAE;AAAA,GACnC;AAKA,EAAA,IAAI,OAAO,QAAA,KAAa,QAAA,IAAY,OAAO,aAAa,QAAA,EAAU;AAC9D,IAAA,uBACI,GAAA;AAAA,MAACA,IAAA;AAAA,MAAA;AAAA,QACI,GAAI,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,KAAW,EAAC;AAAA,QAC1C,SAAA,EAAW,EAAA,CAAG,kCAAA,EAAoC,SAAS,CAAA;AAAA,QAC3D,KAAA,EAAO,SAAA;AAAA,QAEN;AAAA;AAAA,KACL;AAAA,EAER;AAEA,EAAA,2BACK,IAAA,EAAA,EAAM,GAAI,WAAW,MAAA,GAAY,EAAE,QAAO,GAAI,EAAC,EAAK,GAAI,cAAc,MAAA,GAAY,EAAE,WAAU,GAAI,IAC9F,QAAA,EACL,CAAA;AAER,CAAA,EA5B+B,iBAAA,CAAA;AA+B9B,eAAA,CAAsD,UAAA,GAAa,UAAA;AAKpE,IAAM,iBAAA,GAA+B;AAAA,EACjC,IAAA,EAAM,CAAA;AAAA;AAAA;AAAA,EAGN,YAAA,EAAc;AAClB,CAAA;AAqBO,IAAM,kCAAkB,MAAA,CAAA,CAAC;AAAA,EAC5B,KAAA,EAAO,MAAA;AAAA,EACP,UAAA,EAAY,WAAA;AAAA,EACZ,KAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA,EACA,OAAA,EAAS,QAAA;AAAA,EACT,QAAA,EAAU,SAAA;AAAA,EACV,kBAAA,EAAoB,mBAAA;AAAA,EACpB,SAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAG;AACP,CAAA,KAA4B;AACxB,EAAA,MAAM,SAAS,cAAA,EAAe;AAC9B,EAAA,MAAM,GAAA,GAAM,qBAAqB,iBAAiB,CAAA;AAClD,EAAA,MAAM,UAAU,GAAA,CAAI,OAAA;AACpB,EAAA,MAAM,aAAa,GAAA,CAAI,UAAA;AACvB,EAAA,MAAM,UAAA,GAAa,YAAY,GAAA,CAAI,QAAA;AACnC,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAK,CAAA,IAAK,GAAA,CAAI,QAAA;AAEvC,EAAA,MAAM,cAAuC,EAAC;AAC9C,EAAA,IAAI,WAAW,MAAA,EAAW;AACtB,IAAA,WAAA,CAAY,MAAA,GAAS,MAAA;AAAA,EACzB;AACA,EAAA,IAAI,WAAW,MAAA,EAAW;AACtB,IAAA,WAAA,CAAY,kBAAA,GAAqB,MAAA;AAAA,EACrC;AACA,EAAA,IAAI,QAAA,EAAU;AACV,IAAA,WAAA,CAAY,cAAc,CAAA,GAAI,IAAA;AAAA,EAClC;AACA,EAAA,IAAI,SAAS,WAAA,EAAa;AACtB,IAAA,WAAA,CAAY,kBAAkB,CAAA,GAAI,UAAA;AAAA,EACtC;AACA,EAAA,IAAI,cAAc,MAAA,EAAW;AACzB,IAAA,WAAA,CAAY,SAAA,GAAY,SAAA;AAAA,EAC5B;AACA,EAAA,IAAI,kBAAkB,MAAA,EAAW;AAC7B,IAAA,WAAA,CAAY,aAAA,GAAgB,aAAA;AAAA,EAChC;AACA,EAAA,IAAI,iBAAiB,MAAA,EAAW;AAC5B,IAAA,WAAA,CAAY,YAAA,GAAe,YAAA;AAAA,EAC/B;AAEA,EAAA,MAAM,UAAA,GAAwB;AAAA,IAC1B,GAAG,iBAAA;AAAA,IACH,eAAA,EAAiB,EAAA,CAAG,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAC,CAAA;AAAA,IACvC,iBAAA,EAAmB,EAAA,CAAG,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAC,CAAA;AAAA,IACzC,UAAA,EAAY,OAAO,UAAA,CAAW,IAAA;AAAA,IAC9B,QAAA,EAAU,EAAA,CAAG,MAAA,CAAO,QAAA,CAAS,EAAE,CAAA;AAAA,IAC/B,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK;AAAA,GAChC;AAEA,EAAA,uBACI,GAAA;AAAA,IAACC,SAAA;AAAA,IAAA;AAAA,MACG,GAAA,EAAK,CAAC,IAAA,KAAS;AACX,QAAA,GAAA,CAAI,SAAS,OAAA,GAAU,IAAA;AAAA,MAC3B,CAAA;AAAA,MACA,QAAA,EAAU,OAAA;AAAA,MACV,UAAU,CAAC,UAAA;AAAA,MACX,SAAA,EAAW,EAAA,CAAG,iFAAA,EAAmF,SAAS,CAAA;AAAA,MAC1G,oBAAA,EAAsB,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,KAAA;AAAA,MAC3C,OAAA,EAAS,CAAC,CAAA,KAAM;AACZ,QAAA,GAAA,CAAI,WAAW,IAAI,CAAA;AACnB,QAAA,OAAA,GAAU,CAAC,CAAA;AAAA,MACf,CAAA;AAAA,MACA,MAAA,EAAQ,CAAC,CAAA,KAAM;AACX,QAAA,GAAA,CAAI,WAAW,KAAK,CAAA;AACpB,QAAA,MAAA,GAAS,CAAC,CAAA;AAAA,MACd,CAAA;AAAA,MACC,GAAG,WAAA;AAAA,MACH,GAAG,IAAA;AAAA,MACJ,KAAA,EAAO,CAAC,UAAA,EAAY,IAAA,CAAK,KAAK;AAAA;AAAA,GAClC;AAER,CAAA,EA9E+B,iBAAA,CAAA;AAgF9B,eAAA,CAAsD,UAAA,GAAa,UAAA;AAQ7D,IAAM,UAAA,GAAa,MAAA,CAAO,MAAA,CAAO,cAAA,EAAgB;AAAA,EACpD,KAAA,EAAO,eAAA;AAAA,EACP,KAAA,EAAO;AACX,CAAC","file":"chunk-C5HQPXRI.js","sourcesContent":["'use client';\n\nimport {\n Children,\n createContext,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { TextInput as RNTextInputType, TextStyle, ViewStyle } from 'react-native';\nimport { Platform, Pressable, Text as RNText, TextInput as RNTextInput, View } from 'react-native';\nimport { px } from '../../theme/px';\nimport { useThemeColors } from '../../theme/use-theme-colors';\nimport { cn } from '../../utils/cn';\nimport type { TextInputProps } from '../TextInput/TextInput';\n\n// ─── Internal context ─────────────────────────────────────────────────────\n//\n// Lets the addons + input share focus, error, and disabled state so the\n// WHOLE group's border lights up on focus and dimming cascades visually\n// without consumers having to duplicate props on every child.\ntype InputGroupContextValue = {\n inputId: string;\n describeId: string;\n setFocused: (next: boolean) => void;\n hasError: boolean;\n disabled: boolean;\n inputRef: React.MutableRefObject<RNTextInputType | null>;\n focusInput: () => void;\n};\n\nconst InputGroupContext = createContext<InputGroupContextValue | null>(null);\n\nconst useInputGroupContext = (label: string): InputGroupContextValue => {\n const ctx = useContext(InputGroupContext);\n if (!ctx) {\n throw new Error(`<${label}> must be rendered inside an <InputGroup>.`);\n }\n return ctx;\n};\n\n// Marker symbols on the child component functions so we can split children\n// into [prefix, input, suffix] without forcing consumers to pass `position`\n// props or use named slots. Whatever sits before the InputGroupInput is a\n// prefix; whatever sits after is a suffix.\nconst ADDON_TYPE = Symbol.for('nori-ui.InputGroupAddon');\nconst INPUT_TYPE = Symbol.for('nori-ui.InputGroupInput');\n\nconst isAddon = (child: unknown): child is ReactElement =>\n isValidElement(child) && (child.type as { __noriType?: symbol })?.__noriType === ADDON_TYPE;\n\nconst isInput = (child: unknown): child is ReactElement<InputGroupInputProps> =>\n isValidElement(child) && (child.type as { __noriType?: symbol })?.__noriType === INPUT_TYPE;\n\n// ─── Container ────────────────────────────────────────────────────────────\n\n// Layout-only bases; theme-driven dimensions are merged inside the\n// component below.\nconst CONTAINER_LAYOUT_BASE: ViewStyle = { flexDirection: 'column' };\nconst FIELD_LAYOUT_BASE: ViewStyle = {\n flexDirection: 'row',\n alignItems: 'stretch',\n borderWidth: 1,\n overflow: 'hidden',\n};\n\nexport type InputGroupProps = {\n children: ReactNode;\n /** Mark the entire group as disabled — cascades visually to addons + input. */\n disabled?: boolean;\n /** Mark the entire group as errored — cascades visually to addons + input. */\n error?: boolean;\n className?: string;\n containerClassName?: string;\n testID?: string;\n};\n\n/**\n * Wrapper that visually fuses prefix and/or suffix addons with a TextInput\n * into a SINGLE rounded field — one border around the whole compound, not\n * three separate boxes. Inspired by Chakra's InputGroup and shadcn's input\n * addon pattern.\n *\n * @example\n * <InputGroup>\n * <InputGroupAddon>@</InputGroupAddon>\n * <InputGroupInput placeholder=\"username\" />\n * </InputGroup>\n *\n * @example with both prefix and suffix\n * <InputGroup>\n * <InputGroupAddon>https://</InputGroupAddon>\n * <InputGroupInput defaultValue=\"example\" />\n * <InputGroupAddon>.com</InputGroupAddon>\n * </InputGroup>\n */\nconst InputGroupRoot = ({\n children,\n disabled = false,\n error: groupErrorProp = false,\n className,\n containerClassName,\n testID,\n}: InputGroupProps) => {\n const colors = useThemeColors();\n const reactId = useId();\n const inputId = `nori-ui-input-${reactId}`;\n const describeId = `${inputId}-describe`;\n const [focused, setFocused] = useState(false);\n const inputRef = useRef<RNTextInputType | null>(null);\n\n // Stable identity (does not depend on render-cycle state) so the\n // useMemo below can leave it out of the dep array without lint noise.\n const focusInput = useCallback(() => {\n inputRef.current?.focus();\n }, []);\n\n // Walk children once, split into [prefix, input, suffix]. Anything that\n // isn't a recognised marker gets dropped — the API guarantees a single\n // integrated bar, not arbitrary slots.\n const childArray = Children.toArray(children);\n const inputIndex = childArray.findIndex(isInput);\n const inputElement = inputIndex >= 0 ? (childArray[inputIndex] as ReactElement<InputGroupInputProps>) : null;\n const prefixNodes = inputIndex >= 0 ? childArray.slice(0, inputIndex).filter(isAddon) : [];\n const suffixNodes = inputIndex >= 0 ? childArray.slice(inputIndex + 1).filter(isAddon) : [];\n\n // Lift label / helperText / error from the input element so the parent\n // can render them OUTSIDE the bordered field row (a normal field layout\n // wraps the box with label above and helper/error below).\n const inputProps = inputElement?.props ?? ({} as InputGroupInputProps);\n const label = inputProps.label;\n const helperText = inputProps.helperText;\n const inputError = inputProps.error;\n\n const hasError = Boolean(groupErrorProp) || Boolean(inputError);\n\n const ctx = useMemo<InputGroupContextValue>(\n () => ({\n inputId,\n describeId,\n setFocused,\n hasError,\n disabled,\n inputRef,\n focusInput,\n }),\n [inputId, describeId, hasError, disabled, focusInput]\n );\n\n const borderColor = hasError\n ? colors.color.danger\n : focused\n ? colors.semantic.interactive.primary\n : colors.semantic.border.default;\n\n const fieldStyle = [\n FIELD_LAYOUT_BASE,\n {\n borderRadius: px(colors.radius.md),\n backgroundColor: colors.semantic.background.elevated,\n borderColor,\n },\n disabled ? { opacity: 0.6 } : null,\n ];\n\n const labelStyle: TextStyle = {\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize.sm),\n fontWeight: colors.fontWeight.medium as '500',\n color: colors.semantic.text.default,\n };\n const helperStyle: TextStyle = {\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize.sm),\n color: colors.semantic.text.muted,\n };\n const errorStyle: TextStyle = {\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize.sm),\n color: colors.color.danger,\n };\n const containerStyle: ViewStyle = { ...CONTAINER_LAYOUT_BASE, gap: px(colors.spacing['1']) };\n\n return (\n <View\n {...(testID !== undefined ? { testID } : {})}\n className={cn('flex flex-col gap-1', containerClassName)}\n style={containerStyle}\n >\n {label !== undefined ? (\n // On web we render a real <label htmlFor> so clicking the\n // label focuses the input the standard a11y way (and so\n // jsdom-based tests can assert the label↔input\n // association via the `for` attribute).\n //\n // On native, raw <label> is not a valid host component\n // and RN crashes with \"View config getter callback for\n // component `label` must be a function\". The native\n // path renders an RNText instead — the underlying\n // RNTextInput still carries accessibilityLabel for\n // screen readers, so the visible text + the a11y name\n // remain in sync. Same web-only `<label>` story as\n // TextInput's earlier iteration; this branch is the\n // explicit native-safe fallback.\n Platform.OS === 'web' ? (\n <label\n htmlFor={inputId}\n className=\"text-sm font-medium text-semantic-text-default\"\n style={labelStyle as object}\n >\n {label}\n </label>\n ) : (\n <RNText\n nativeID={`${inputId}-label`}\n accessibilityRole=\"text\"\n className=\"text-sm font-medium text-semantic-text-default\"\n style={labelStyle}\n >\n {label}\n </RNText>\n )\n ) : null}\n <InputGroupContext.Provider value={ctx}>\n <View\n className={cn(\n 'flex-row items-stretch overflow-hidden rounded-md border focus-within:border-semantic-interactive-primary',\n hasError ? 'border-semantic-interactive-destructive' : 'border-semantic-border-default',\n disabled ? 'opacity-60' : undefined,\n className\n )}\n style={fieldStyle}\n >\n {prefixNodes.map((node, i) => {\n const key = (node as ReactElement & { key?: string | null }).key ?? `prefix-${i}`;\n return (\n <AddonSlot key={key} side=\"left\">\n {node}\n </AddonSlot>\n );\n })}\n {inputElement}\n {suffixNodes.map((node, i) => {\n const key = (node as ReactElement & { key?: string | null }).key ?? `suffix-${i}`;\n return (\n <AddonSlot key={key} side=\"right\">\n {node}\n </AddonSlot>\n );\n })}\n </View>\n </InputGroupContext.Provider>\n {inputError ? (\n <RNText\n nativeID={describeId}\n className=\"text-sm text-semantic-interactive-destructive\"\n style={errorStyle}\n >\n {inputError}\n </RNText>\n ) : helperText ? (\n <RNText nativeID={describeId} className=\"text-sm text-semantic-text-muted\" style={helperStyle}>\n {helperText}\n </RNText>\n ) : null}\n </View>\n );\n};\n\n// ─── Addon slot ───────────────────────────────────────────────────────────\n//\n// Internal wrapper that paints the muted background, draws the 1px vertical\n// separator on the input-facing side, and forwards a click to the input so\n// the addon reads as decorator, not as something interactive.\nconst AddonSlot = ({ children, side }: { children: ReactNode; side: 'left' | 'right' }) => {\n const colors = useThemeColors();\n const ctx = useContext(InputGroupContext);\n const dim = ctx?.disabled ? 0.85 : 1;\n\n const baseStyle: ViewStyle = {\n backgroundColor: colors.semantic.background.subtle,\n paddingHorizontal: px(colors.spacing['3']),\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n opacity: dim,\n };\n\n const separatorStyle: ViewStyle =\n side === 'left'\n ? { borderRightWidth: 1, borderRightColor: colors.semantic.border.default }\n : { borderLeftWidth: 1, borderLeftColor: colors.semantic.border.default };\n\n const handlePress = () => {\n ctx?.focusInput();\n };\n\n return (\n <Pressable\n // Pressing the addon focuses the input — addons are decorators,\n // never tab stops. RN's `accessibilityRole` doesn't accept \"presentation\"\n // (web-only), so we set the WAI-ARIA role via the web prop instead.\n onPress={handlePress}\n role=\"none\"\n // RN web maps `focusable={false}` to `tabIndex={-1}`.\n focusable={false}\n style={[baseStyle, separatorStyle]}\n className={cn(\n 'flex-row items-center justify-center px-3 bg-semantic-background-subtle',\n side === 'right' ? 'border-l border-semantic-border-default' : 'border-r border-semantic-border-default'\n )}\n >\n {children}\n </Pressable>\n );\n};\n\n// ─── Addon (public) ───────────────────────────────────────────────────────\n\nexport type InputGroupAddonProps = {\n children: ReactNode;\n className?: string;\n testID?: string;\n};\n\n/**\n * Decorator slot inside an `<InputGroup>`. Renders a muted, non-interactive\n * box that visually fuses with the input. Place before `<InputGroupInput>`\n * for a prefix, after for a suffix. Accepts strings or `ReactNode` (icons).\n */\nexport const InputGroupAddon = ({ children, className, testID }: InputGroupAddonProps) => {\n const colors = useThemeColors();\n const textStyle: TextStyle = {\n color: colors.semantic.text.muted,\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize.sm),\n };\n\n // Wrap raw strings/numbers so consumers can pass `\"@\"` or `<MailIcon />`\n // and both render correctly without callers tripping over RN's \"text\n // outside of <Text>\" warning.\n if (typeof children === 'string' || typeof children === 'number') {\n return (\n <RNText\n {...(testID !== undefined ? { testID } : {})}\n className={cn('text-sm text-semantic-text-muted', className)}\n style={textStyle}\n >\n {children}\n </RNText>\n );\n }\n\n return (\n <View {...(testID !== undefined ? { testID } : {})} {...(className !== undefined ? { className } : {})}>\n {children}\n </View>\n );\n};\n\n// Brand the function so the parent can locate it via Children.toArray walk.\n(InputGroupAddon as unknown as { __noriType: symbol }).__noriType = ADDON_TYPE;\n\n// ─── Input (public) ───────────────────────────────────────────────────────\n\n// Layout-only base; theme-driven dimensions are merged inside InputGroupInput.\nconst INPUT_LAYOUT_BASE: TextStyle = {\n flex: 1,\n // RN web honours `outlineStyle: 'none'` to suppress the default browser\n // focus ring — the group's own focus-within border replaces it.\n outlineStyle: 'none' as unknown as TextStyle['outlineStyle'],\n};\n\nexport type InputGroupInputProps = TextInputProps & {\n /** Label rendered above the bordered field row by the parent InputGroup. */\n label?: string;\n /** Helper text rendered below the bordered field row by the parent InputGroup. */\n helperText?: string;\n /** Error message rendered below the bordered field row by the parent InputGroup. */\n error?: string;\n};\n\n/**\n * The text field inside an `<InputGroup>`. Extends the full `TextInput` API\n * (label, helperText, error, disabled, etc.) so consumers don't lose any\n * functionality when reaching for the integrated layout.\n *\n * Implementation note: this renders a bare RN `TextInput` because the\n * surrounding `<InputGroup>` already paints the border + label + helper —\n * those bits are lifted to the parent so they render OUTSIDE the bordered\n * field row, the way a normal field's label/helper sits above/below the box.\n */\nexport const InputGroupInput = ({\n label: _label,\n helperText: _helperText,\n error,\n disabled,\n onChangeText,\n onFocus,\n onBlur,\n multiline,\n numberOfLines,\n leading: _leading,\n trailing: _trailing,\n containerClassName: _containerClassName,\n className,\n testID,\n ...rest\n}: InputGroupInputProps) => {\n const colors = useThemeColors();\n const ctx = useInputGroupContext('InputGroupInput');\n const inputId = ctx.inputId;\n const describeId = ctx.describeId;\n const isDisabled = disabled || ctx.disabled;\n const hasError = Boolean(error) || ctx.hasError;\n\n const inputExtras: Record<string, unknown> = {};\n if (testID !== undefined) {\n inputExtras.testID = testID;\n }\n if (_label !== undefined) {\n inputExtras.accessibilityLabel = _label;\n }\n if (hasError) {\n inputExtras['aria-invalid'] = true;\n }\n if (error || _helperText) {\n inputExtras['aria-describedby'] = describeId;\n }\n if (multiline !== undefined) {\n inputExtras.multiline = multiline;\n }\n if (numberOfLines !== undefined) {\n inputExtras.numberOfLines = numberOfLines;\n }\n if (onChangeText !== undefined) {\n inputExtras.onChangeText = onChangeText;\n }\n\n const inputStyle: TextStyle = {\n ...INPUT_LAYOUT_BASE,\n paddingVertical: px(colors.spacing['2']),\n paddingHorizontal: px(colors.spacing['3']),\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize.md),\n color: colors.semantic.text.default,\n };\n\n return (\n <RNTextInput\n ref={(node) => {\n ctx.inputRef.current = node;\n }}\n nativeID={inputId}\n editable={!isDisabled}\n className={cn('flex-1 py-2 px-3 text-md text-semantic-text-default outline-none bg-transparent', className)}\n placeholderTextColor={colors.semantic.text.muted}\n onFocus={(e) => {\n ctx.setFocused(true);\n onFocus?.(e);\n }}\n onBlur={(e) => {\n ctx.setFocused(false);\n onBlur?.(e);\n }}\n {...inputExtras}\n {...rest}\n style={[inputStyle, rest.style]}\n />\n );\n};\n\n(InputGroupInput as unknown as { __noriType: symbol }).__noriType = INPUT_TYPE;\n\n/**\n * Public `InputGroup` value — the root function plus its `.Addon` and `.Input`\n * static members. `Object.assign` produces a value whose inferred type carries\n * the static properties, so `.d.ts` consumers can write `<InputGroup.Addon>`\n * without a separate import.\n */\nexport const InputGroup = Object.assign(InputGroupRoot, {\n Addon: InputGroupAddon,\n Input: InputGroupInput,\n});\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { px } from './chunk-5A2QOOVN.js';
|
|
2
|
-
import { cn } from './chunk-CHXHRJNZ.js';
|
|
3
2
|
import { useThemeColors } from './chunk-R5JMDDCB.js';
|
|
3
|
+
import { cn } from './chunk-CHXHRJNZ.js';
|
|
4
4
|
import { __name } from './chunk-WCQVDF3K.js';
|
|
5
5
|
import { createContext, useId, useState, useRef, useCallback, useMemo, useEffect, useContext } from 'react';
|
|
6
6
|
import { View, Pressable, Text } from 'react-native';
|
|
@@ -302,5 +302,5 @@ var Tabs = Object.assign(TabsRoot, {
|
|
|
302
302
|
});
|
|
303
303
|
|
|
304
304
|
export { Tabs };
|
|
305
|
-
//# sourceMappingURL=chunk-
|
|
306
|
-
//# sourceMappingURL=chunk-
|
|
305
|
+
//# sourceMappingURL=chunk-EN4CLDGZ.js.map
|
|
306
|
+
//# sourceMappingURL=chunk-EN4CLDGZ.js.map
|