@nori-ui/core 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -0
  3. package/dist/chunk-6NDARMPP.js +389 -0
  4. package/dist/chunk-6NDARMPP.js.map +1 -0
  5. package/dist/chunk-7QVYU63E.js +6 -0
  6. package/dist/chunk-7QVYU63E.js.map +1 -0
  7. package/dist/chunk-BRCCWMGJ.js +3 -0
  8. package/dist/chunk-BRCCWMGJ.js.map +1 -0
  9. package/dist/chunk-FXKIWONG.js +80 -0
  10. package/dist/chunk-FXKIWONG.js.map +1 -0
  11. package/dist/chunk-JGH6Z5LM.js +213 -0
  12. package/dist/chunk-JGH6Z5LM.js.map +1 -0
  13. package/dist/chunk-NDEDMCHT.js +40 -0
  14. package/dist/chunk-NDEDMCHT.js.map +1 -0
  15. package/dist/chunk-RX7UULY3.js +19 -0
  16. package/dist/chunk-RX7UULY3.js.map +1 -0
  17. package/dist/chunk-SSTXLK5I.js +66 -0
  18. package/dist/chunk-SSTXLK5I.js.map +1 -0
  19. package/dist/chunk-XGM2K4TT.js +31 -0
  20. package/dist/chunk-XGM2K4TT.js.map +1 -0
  21. package/dist/client.cjs +861 -0
  22. package/dist/client.cjs.map +1 -0
  23. package/dist/client.d.cts +157 -0
  24. package/dist/client.d.ts +157 -0
  25. package/dist/client.js +50 -0
  26. package/dist/client.js.map +1 -0
  27. package/dist/i18n/index.cjs +70 -0
  28. package/dist/i18n/index.cjs.map +1 -0
  29. package/dist/i18n/index.d.cts +60 -0
  30. package/dist/i18n/index.d.ts +60 -0
  31. package/dist/i18n/index.js +4 -0
  32. package/dist/i18n/index.js.map +1 -0
  33. package/dist/icons/index.cjs +56 -0
  34. package/dist/icons/index.cjs.map +1 -0
  35. package/dist/icons/index.d.cts +38 -0
  36. package/dist/icons/index.d.ts +38 -0
  37. package/dist/icons/index.js +5 -0
  38. package/dist/icons/index.js.map +1 -0
  39. package/dist/index.cjs +820 -0
  40. package/dist/index.cjs.map +1 -0
  41. package/dist/index.d.cts +187 -0
  42. package/dist/index.d.ts +187 -0
  43. package/dist/index.js +11 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/slot/index.cjs +85 -0
  46. package/dist/slot/index.cjs.map +1 -0
  47. package/dist/slot/index.d.cts +13 -0
  48. package/dist/slot/index.d.ts +13 -0
  49. package/dist/slot/index.js +4 -0
  50. package/dist/slot/index.js.map +1 -0
  51. package/dist/stories/story-registry.cjs +612 -0
  52. package/dist/stories/story-registry.cjs.map +1 -0
  53. package/dist/stories/story-registry.d.cts +13 -0
  54. package/dist/stories/story-registry.d.ts +13 -0
  55. package/dist/stories/story-registry.js +105 -0
  56. package/dist/stories/story-registry.js.map +1 -0
  57. package/dist/theme/index.cjs +216 -0
  58. package/dist/theme/index.cjs.map +1 -0
  59. package/dist/theme/index.d.cts +1 -0
  60. package/dist/theme/index.d.ts +1 -0
  61. package/dist/theme/index.js +4 -0
  62. package/dist/theme/index.js.map +1 -0
  63. package/dist/utils/cn.cjs +34 -0
  64. package/dist/utils/cn.cjs.map +1 -0
  65. package/dist/utils/cn.d.cts +4 -0
  66. package/dist/utils/cn.d.ts +4 -0
  67. package/dist/utils/cn.js +4 -0
  68. package/dist/utils/cn.js.map +1 -0
  69. package/package.json +122 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,820 @@
1
+ 'use strict';
2
+
3
+ var reactNative = require('react-native');
4
+ var jsxRuntime = require('nativewind/jsx-runtime');
5
+ var react = require('react');
6
+
7
+ var __defProp = Object.defineProperty;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
+
10
+ // src/utils/cn.ts
11
+ function cn(...inputs) {
12
+ const out = [];
13
+ for (const input of inputs) append(out, input);
14
+ return out.join(" ");
15
+ }
16
+ __name(cn, "cn");
17
+ function append(out, input) {
18
+ if (!input) return;
19
+ if (typeof input === "string") {
20
+ if (input.length > 0) out.push(input);
21
+ return;
22
+ }
23
+ if (typeof input === "number") return;
24
+ if (Array.isArray(input)) {
25
+ for (const inner of input) append(out, inner);
26
+ return;
27
+ }
28
+ if (typeof input === "object") {
29
+ for (const key of Object.keys(input)) {
30
+ if (input[key]) out.push(key);
31
+ }
32
+ }
33
+ }
34
+ __name(append, "append");
35
+ function Box({ className, children, ...rest }) {
36
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { ...rest, className: cn(className), children });
37
+ }
38
+ __name(Box, "Box");
39
+
40
+ // src/slot/compose-refs.ts
41
+ function composeRefs(...refs) {
42
+ return (node) => {
43
+ for (const ref of refs) {
44
+ if (ref == null) continue;
45
+ if (typeof ref === "function") {
46
+ ref(node);
47
+ } else {
48
+ ref.current = node;
49
+ }
50
+ }
51
+ };
52
+ }
53
+ __name(composeRefs, "composeRefs");
54
+ var Slot = react.forwardRef(/* @__PURE__ */ __name(function Slot2(props, forwardedRef) {
55
+ const { children, ...slotProps } = props;
56
+ if (!react.isValidElement(children)) {
57
+ return null;
58
+ }
59
+ const child = react.Children.only(children);
60
+ const merged = mergeProps(slotProps, child.props);
61
+ const childRef = child.ref;
62
+ if (forwardedRef || childRef) {
63
+ merged.ref = composeRefs(forwardedRef, childRef);
64
+ }
65
+ return react.cloneElement(child, merged);
66
+ }, "Slot"));
67
+ Slot.displayName = "Slot";
68
+ function mergeProps(outer, inner) {
69
+ const merged = { ...outer };
70
+ for (const key of Object.keys(inner)) {
71
+ const outerValue = outer[key];
72
+ const innerValue = inner[key];
73
+ if (key === "className" || key === "class") {
74
+ merged[key] = joinClass(outerValue, innerValue);
75
+ continue;
76
+ }
77
+ if (key === "style") {
78
+ merged[key] = {
79
+ ...outerValue,
80
+ ...innerValue
81
+ };
82
+ continue;
83
+ }
84
+ if (isEventHandler(key, outerValue, innerValue)) {
85
+ merged[key] = composeHandlers(outerValue, innerValue);
86
+ continue;
87
+ }
88
+ merged[key] = innerValue;
89
+ }
90
+ return merged;
91
+ }
92
+ __name(mergeProps, "mergeProps");
93
+ function joinClass(outer, inner) {
94
+ const a = typeof outer === "string" ? outer : "";
95
+ const b = typeof inner === "string" ? inner : "";
96
+ const joined = [a, b].filter(Boolean).join(" ");
97
+ return joined.length > 0 ? joined : void 0;
98
+ }
99
+ __name(joinClass, "joinClass");
100
+ function isEventHandler(key, outer, inner) {
101
+ if (!key.startsWith("on") || key.length < 3) return false;
102
+ if (key[2] !== key[2]?.toUpperCase()) return false;
103
+ return typeof outer === "function" && typeof inner === "function";
104
+ }
105
+ __name(isEventHandler, "isEventHandler");
106
+ function composeHandlers(outer, inner) {
107
+ return (...args) => {
108
+ outer(...args);
109
+ inner(...args);
110
+ };
111
+ }
112
+ __name(composeHandlers, "composeHandlers");
113
+ var SIZE_MAP = {
114
+ sm: 12,
115
+ md: 16,
116
+ lg: 24,
117
+ xl: 32
118
+ };
119
+ function Spinner({ label = "Loading", size = "md", testID, color, style, ...rest }) {
120
+ const px = typeof size === "number" ? size : SIZE_MAP[size];
121
+ return /* @__PURE__ */ jsxRuntime.jsx(
122
+ reactNative.ActivityIndicator,
123
+ {
124
+ ...rest,
125
+ ...testID !== void 0 ? { testID } : {},
126
+ accessibilityRole: "progressbar",
127
+ accessibilityLabel: label,
128
+ ...color !== void 0 ? { color } : {},
129
+ size: px,
130
+ style: [{ width: px, height: px }, style]
131
+ }
132
+ );
133
+ }
134
+ __name(Spinner, "Spinner");
135
+ var VARIANT_CLASSES = {
136
+ primary: "bg-semantic-interactive-primary hover:bg-semantic-interactive-primaryHover active:bg-semantic-interactive-primaryPressed",
137
+ secondary: "bg-neutral-100 hover:bg-neutral-200 active:bg-neutral-300",
138
+ ghost: "bg-transparent hover:bg-neutral-100 active:bg-neutral-200",
139
+ destructive: "bg-semantic-interactive-destructive hover:opacity-90 active:opacity-80"
140
+ };
141
+ var SIZE_CLASSES = {
142
+ sm: "h-8 px-3 text-sm",
143
+ md: "h-10 px-4 text-md",
144
+ lg: "h-12 px-5 text-lg"
145
+ };
146
+ var ICON_SIZE = { sm: 14, md: 16, lg: 20 };
147
+ var BASE_CLASSES = "inline-flex flex-row items-center justify-center gap-2 rounded-md select-none";
148
+ var Button = react.forwardRef(/* @__PURE__ */ __name(function Button2({
149
+ children,
150
+ variant = "primary",
151
+ size = "md",
152
+ disabled,
153
+ loading,
154
+ leadingIcon: LeadingIcon,
155
+ trailingIcon: TrailingIcon,
156
+ asChild,
157
+ className,
158
+ onPress,
159
+ testID,
160
+ ...rest
161
+ }, forwardedRef) {
162
+ const isInoperative = Boolean(disabled) || Boolean(loading);
163
+ const classes = cn(
164
+ BASE_CLASSES,
165
+ VARIANT_CLASSES[variant],
166
+ SIZE_CLASSES[size],
167
+ isInoperative ? "opacity-60" : void 0,
168
+ className
169
+ );
170
+ const handlePress = /* @__PURE__ */ __name((ev) => {
171
+ if (isInoperative) return;
172
+ onPress?.(ev);
173
+ }, "handlePress");
174
+ if (asChild) {
175
+ const slotProps = {
176
+ ref: forwardedRef,
177
+ className: classes,
178
+ onClick: handlePress,
179
+ ...rest
180
+ };
181
+ if (isInoperative) slotProps["aria-disabled"] = true;
182
+ if (loading) slotProps["aria-busy"] = true;
183
+ if (testID !== void 0) slotProps["data-testid"] = testID;
184
+ return /* @__PURE__ */ jsxRuntime.jsx(Slot, { ...slotProps, children });
185
+ }
186
+ const pressableExtra = {};
187
+ if (isInoperative) pressableExtra["aria-disabled"] = true;
188
+ if (loading) pressableExtra["aria-busy"] = true;
189
+ return /* @__PURE__ */ jsxRuntime.jsxs(
190
+ reactNative.Pressable,
191
+ {
192
+ ref: forwardedRef,
193
+ ...testID !== void 0 ? { testID } : {},
194
+ role: "button",
195
+ accessibilityRole: "button",
196
+ accessibilityState: { disabled: isInoperative, busy: Boolean(loading) },
197
+ disabled: isInoperative,
198
+ onPress: handlePress,
199
+ className: classes,
200
+ ...pressableExtra,
201
+ ...rest,
202
+ children: [
203
+ loading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: ICON_SIZE[size], label: "Loading" }) : LeadingIcon ? /* @__PURE__ */ jsxRuntime.jsx(LeadingIcon, { size: ICON_SIZE[size] }) : null,
204
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { className: cn("font-medium", SIZE_CLASSES[size].includes("text-") ? void 0 : "text-md"), children }),
205
+ TrailingIcon ? /* @__PURE__ */ jsxRuntime.jsx(TrailingIcon, { size: ICON_SIZE[size] }) : null
206
+ ]
207
+ }
208
+ );
209
+ }, "Button"));
210
+ Button.displayName = "Button";
211
+ var make = /* @__PURE__ */ __name((path) => /* @__PURE__ */ __name(function PlaceholderIcon({ size = 20, color = "currentColor" }) {
212
+ return /* @__PURE__ */ jsxRuntime.jsx(
213
+ "svg",
214
+ {
215
+ width: size,
216
+ height: size,
217
+ viewBox: "0 0 24 24",
218
+ fill: "none",
219
+ stroke: color,
220
+ strokeWidth: "2",
221
+ strokeLinecap: "round",
222
+ strokeLinejoin: "round",
223
+ "aria-hidden": "true",
224
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: path })
225
+ }
226
+ );
227
+ }, "PlaceholderIcon"), "make");
228
+ var defaultSemanticIcons = {
229
+ checkmark: make("M20 6 9 17l-5-5"),
230
+ close: make("M18 6 6 18 M6 6l12 12"),
231
+ eye: make("M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6z"),
232
+ eyeOff: make("M17.94 17.94A10 10 0 0 1 2 12s3.5-7 10-7c2 0 3.8.6 5.4 1.5 M1 1l22 22"),
233
+ chevronDown: make("m6 9 6 6 6-6"),
234
+ chevronUp: make("m18 15-6-6-6 6"),
235
+ alertTriangle: make(
236
+ "M12 9v4 M12 17h.01 M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"
237
+ ),
238
+ info: make(
239
+ "M12 8h.01 M11 12h1v4h1 M12 22C6.48 22 2 17.52 2 12 2 6.48 6.48 2 12 2c5.52 0 10 4.48 10 10 0 5.52-4.48 10-10 10z"
240
+ ),
241
+ check: make("M20 6 9 17l-5-5"),
242
+ x: make("M18 6 6 18 M6 6l12 12")
243
+ };
244
+ var SemanticIconsContext = react.createContext(defaultSemanticIcons);
245
+ SemanticIconsContext.displayName = "SemanticIconsContext";
246
+
247
+ // src/icons/use-semantic-icon.ts
248
+ function useSemanticIcon(name) {
249
+ const icons = react.useContext(SemanticIconsContext);
250
+ return icons[name];
251
+ }
252
+ __name(useSemanticIcon, "useSemanticIcon");
253
+ function Checkbox({
254
+ checked,
255
+ defaultChecked = false,
256
+ indeterminate,
257
+ disabled,
258
+ onChange,
259
+ label,
260
+ className,
261
+ testID,
262
+ asChild,
263
+ children
264
+ }) {
265
+ const [inner, setInner] = react.useState(defaultChecked);
266
+ const isControlled = checked !== void 0;
267
+ const value = isControlled ? Boolean(checked) : inner;
268
+ const ariaChecked = indeterminate ? "mixed" : value ? "true" : "false";
269
+ const toggle = react.useCallback(() => {
270
+ if (disabled) return;
271
+ const next = !value;
272
+ if (!isControlled) setInner(next);
273
+ onChange?.(next);
274
+ }, [disabled, value, isControlled, onChange]);
275
+ const Check = useSemanticIcon("checkmark");
276
+ const commonProps = {
277
+ role: "checkbox",
278
+ "aria-checked": ariaChecked,
279
+ accessibilityRole: "checkbox",
280
+ accessibilityState: { checked: value, disabled: Boolean(disabled) },
281
+ testID
282
+ };
283
+ if (disabled) commonProps["aria-disabled"] = true;
284
+ if (label !== void 0) {
285
+ commonProps["aria-label"] = label;
286
+ commonProps.accessibilityLabel = label;
287
+ }
288
+ if (asChild) {
289
+ const slotProps = {
290
+ role: "checkbox",
291
+ "aria-checked": ariaChecked,
292
+ onClick: toggle
293
+ };
294
+ if (disabled) slotProps["aria-disabled"] = true;
295
+ if (label !== void 0) slotProps["aria-label"] = label;
296
+ if (testID !== void 0) slotProps["data-testid"] = testID;
297
+ if (className !== void 0) slotProps.className = className;
298
+ return /* @__PURE__ */ jsxRuntime.jsx(Slot, { ...slotProps, children });
299
+ }
300
+ const boxClasses = cn("w-5 h-5 rounded-sm border border-semantic-border-strong items-center justify-center");
301
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { className: cn("flex-row items-center gap-2", disabled ? "opacity-60" : void 0, className), children: [
302
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: toggle, ...commonProps, className: boxClasses, children: (value || indeterminate) && !disabled ? /* @__PURE__ */ jsxRuntime.jsx(Check, { size: 14, color: "currentColor" }) : null }),
303
+ children ?? (label !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { children: label }) : null)
304
+ ] });
305
+ }
306
+ __name(Checkbox, "Checkbox");
307
+ var ALIGN_CLASS = {
308
+ start: "items-start",
309
+ center: "items-center",
310
+ end: "items-end",
311
+ stretch: "items-stretch",
312
+ baseline: "items-baseline"
313
+ };
314
+ var JUSTIFY_CLASS = {
315
+ start: "justify-start",
316
+ center: "justify-center",
317
+ end: "justify-end",
318
+ between: "justify-between",
319
+ around: "justify-around",
320
+ evenly: "justify-evenly"
321
+ };
322
+ function HStack({ gap, align, justify, className, children, ...rest }) {
323
+ return /* @__PURE__ */ jsxRuntime.jsx(
324
+ reactNative.View,
325
+ {
326
+ ...rest,
327
+ className: cn(
328
+ "flex-row",
329
+ gap !== void 0 && gap !== 0 ? `gap-${gap}` : void 0,
330
+ align !== void 0 ? ALIGN_CLASS[align] : void 0,
331
+ justify !== void 0 ? JUSTIFY_CLASS[justify] : void 0,
332
+ className
333
+ ),
334
+ children
335
+ }
336
+ );
337
+ }
338
+ __name(HStack, "HStack");
339
+ function Switch({
340
+ checked,
341
+ defaultChecked = false,
342
+ disabled,
343
+ onChange,
344
+ label,
345
+ className,
346
+ testID,
347
+ asChild,
348
+ children
349
+ }) {
350
+ const [inner, setInner] = react.useState(defaultChecked);
351
+ const isControlled = checked !== void 0;
352
+ const value = isControlled ? Boolean(checked) : inner;
353
+ const toggle = react.useCallback(() => {
354
+ if (disabled) return;
355
+ const next = !value;
356
+ if (!isControlled) setInner(next);
357
+ onChange?.(next);
358
+ }, [disabled, value, isControlled, onChange]);
359
+ const ariaChecked = value ? "true" : "false";
360
+ const commonProps = {
361
+ role: "switch",
362
+ "aria-checked": ariaChecked,
363
+ accessibilityRole: "switch",
364
+ accessibilityState: { checked: value, disabled: Boolean(disabled) },
365
+ testID
366
+ };
367
+ if (disabled) commonProps["aria-disabled"] = true;
368
+ if (label !== void 0) {
369
+ commonProps["aria-label"] = label;
370
+ commonProps.accessibilityLabel = label;
371
+ }
372
+ if (asChild) {
373
+ const slotProps = {
374
+ role: "switch",
375
+ "aria-checked": ariaChecked,
376
+ onClick: toggle
377
+ };
378
+ if (disabled) slotProps["aria-disabled"] = true;
379
+ if (label !== void 0) slotProps["aria-label"] = label;
380
+ if (testID !== void 0) slotProps["data-testid"] = testID;
381
+ if (className !== void 0) slotProps.className = className;
382
+ return /* @__PURE__ */ jsxRuntime.jsx(Slot, { ...slotProps, children });
383
+ }
384
+ const trackClasses = cn(
385
+ "w-10 h-6 rounded-full justify-center px-0.5 transition-colors",
386
+ value ? "bg-semantic-interactive-primary" : "bg-neutral-300",
387
+ disabled ? "opacity-60" : void 0
388
+ );
389
+ const thumbClasses = cn("w-5 h-5 rounded-full bg-white shadow-sm", value ? "self-end" : "self-start");
390
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { className: cn("flex-row items-center gap-2", className), children: [
391
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: toggle, ...commonProps, className: trackClasses, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: thumbClasses }) }),
392
+ label ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { className: "text-md text-semantic-text-default", children: label }) : null,
393
+ children
394
+ ] });
395
+ }
396
+ __name(Switch, "Switch");
397
+ var VARIANT_CLASSES2 = {
398
+ "body-xs": "text-xs leading-normal",
399
+ "body-sm": "text-sm leading-normal",
400
+ "body-md": "text-md leading-normal",
401
+ "body-lg": "text-lg leading-relaxed",
402
+ "heading-1": "text-4xl leading-tight font-bold",
403
+ "heading-2": "text-3xl leading-tight font-semibold",
404
+ "heading-3": "text-2xl leading-tight font-semibold"
405
+ };
406
+ var HEADING_VARIANTS = /* @__PURE__ */ new Set(["heading-1", "heading-2", "heading-3"]);
407
+ function Text({ variant = "body-md", className, testID, children, ...rest }) {
408
+ const isHeading = HEADING_VARIANTS.has(variant);
409
+ const role = isHeading ? "header" : rest.accessibilityRole;
410
+ return /* @__PURE__ */ jsxRuntime.jsx(
411
+ reactNative.Text,
412
+ {
413
+ testID,
414
+ ...rest,
415
+ ...role !== void 0 ? { accessibilityRole: role } : {},
416
+ className: cn(VARIANT_CLASSES2[variant], className),
417
+ children
418
+ }
419
+ );
420
+ }
421
+ __name(Text, "Text");
422
+ function TextInput({
423
+ label,
424
+ helperText,
425
+ error,
426
+ disabled,
427
+ leading,
428
+ trailing,
429
+ containerClassName,
430
+ className,
431
+ testID,
432
+ onChangeText,
433
+ multiline,
434
+ numberOfLines,
435
+ ...rest
436
+ }) {
437
+ const reactId = react.useId();
438
+ const inputId = testID ?? `nori-ui-input-${reactId}`;
439
+ const describeId = `${inputId}-describe`;
440
+ const hasError = Boolean(error);
441
+ const describedBy = error || helperText ? describeId : void 0;
442
+ const inputExtras = {};
443
+ if (testID !== void 0) inputExtras.testID = testID;
444
+ if (label !== void 0) inputExtras.accessibilityLabel = label;
445
+ if (hasError) inputExtras["aria-invalid"] = true;
446
+ if (describedBy !== void 0) inputExtras["aria-describedby"] = describedBy;
447
+ if (multiline !== void 0) inputExtras.multiline = multiline;
448
+ if (numberOfLines !== void 0) inputExtras.numberOfLines = numberOfLines;
449
+ if (onChangeText !== void 0) inputExtras.onChangeText = onChangeText;
450
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { className: cn("flex flex-col gap-1", containerClassName), children: [
451
+ label !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: inputId, className: "text-sm font-medium text-semantic-text-default", children: label }) : null,
452
+ /* @__PURE__ */ jsxRuntime.jsxs(
453
+ reactNative.View,
454
+ {
455
+ className: cn(
456
+ "flex-row items-center rounded-md border px-3",
457
+ hasError ? "border-semantic-interactive-destructive" : "border-semantic-border-default",
458
+ disabled ? "opacity-60" : void 0
459
+ ),
460
+ children: [
461
+ leading ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: "mr-2", children: leading }) : null,
462
+ /* @__PURE__ */ jsxRuntime.jsx(
463
+ reactNative.TextInput,
464
+ {
465
+ nativeID: inputId,
466
+ editable: !disabled,
467
+ className: cn("flex-1 py-2 text-md text-semantic-text-default outline-none", className),
468
+ ...inputExtras,
469
+ ...rest
470
+ }
471
+ ),
472
+ trailing ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: "ml-2", children: trailing }) : null
473
+ ]
474
+ }
475
+ ),
476
+ error ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { nativeID: describeId, className: "text-sm text-semantic-interactive-destructive", children: error }) : helperText ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { nativeID: describeId, className: "text-sm text-semantic-text-muted", children: helperText }) : null
477
+ ] });
478
+ }
479
+ __name(TextInput, "TextInput");
480
+ function TextArea({ numberOfLines = 4, ...rest }) {
481
+ return /* @__PURE__ */ jsxRuntime.jsx(TextInput, { multiline: true, numberOfLines, ...rest });
482
+ }
483
+ __name(TextArea, "TextArea");
484
+ var ALIGN_CLASS2 = {
485
+ start: "items-start",
486
+ center: "items-center",
487
+ end: "items-end",
488
+ stretch: "items-stretch",
489
+ baseline: "items-baseline"
490
+ };
491
+ var JUSTIFY_CLASS2 = {
492
+ start: "justify-start",
493
+ center: "justify-center",
494
+ end: "justify-end",
495
+ between: "justify-between",
496
+ around: "justify-around",
497
+ evenly: "justify-evenly"
498
+ };
499
+ function VStack({ gap, align, justify, className, children, ...rest }) {
500
+ return /* @__PURE__ */ jsxRuntime.jsx(
501
+ reactNative.View,
502
+ {
503
+ ...rest,
504
+ className: cn(
505
+ "flex-col",
506
+ gap !== void 0 && gap !== 0 ? `gap-${gap}` : void 0,
507
+ align !== void 0 ? ALIGN_CLASS2[align] : void 0,
508
+ justify !== void 0 ? JUSTIFY_CLASS2[justify] : void 0,
509
+ className
510
+ ),
511
+ children
512
+ }
513
+ );
514
+ }
515
+ __name(VStack, "VStack");
516
+
517
+ // src/i18n/default-dictionary.ts
518
+ var defaultDictionary = {
519
+ // generic / shared
520
+ "common.cancel": "Cancel",
521
+ "common.confirm": "Confirm",
522
+ "common.close": "Close",
523
+ "common.back": "Back",
524
+ "common.loading": "Loading",
525
+ "common.error": "Something went wrong",
526
+ "common.retry": "Try again",
527
+ // button
528
+ "button.loadingLabel": "Loading",
529
+ // input
530
+ "input.clear": "Clear",
531
+ "input.passwordShow": "Show password",
532
+ "input.passwordHide": "Hide password",
533
+ // checkbox / switch
534
+ "checkbox.checked": "Checked",
535
+ "checkbox.unchecked": "Unchecked",
536
+ "switch.on": "On",
537
+ "switch.off": "Off"
538
+ };
539
+
540
+ // src/i18n/resolve.ts
541
+ function resolveI18n(input, defaults) {
542
+ if (typeof input === "function") {
543
+ return (keyOrKeys, options) => input(keyOrKeys, options);
544
+ }
545
+ const dict = input ?? {};
546
+ return (keyOrKeys, options) => {
547
+ const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];
548
+ for (const rawKey of keys) {
549
+ const key = pluralize(rawKey, options?.count);
550
+ const template = dict[key] ?? defaults[key];
551
+ if (template !== void 0) {
552
+ return interpolate(template, options);
553
+ }
554
+ }
555
+ const lastKey = keys[keys.length - 1];
556
+ if (options?.defaultValue !== void 0) {
557
+ return interpolate(options.defaultValue, options);
558
+ }
559
+ return lastKey ?? "";
560
+ };
561
+ }
562
+ __name(resolveI18n, "resolveI18n");
563
+ function pluralize(key, count) {
564
+ if (count === void 0) return key;
565
+ if (count === 1) return `${key}_one`;
566
+ return `${key}_other`;
567
+ }
568
+ __name(pluralize, "pluralize");
569
+ function interpolate(template, options) {
570
+ if (!options) return template;
571
+ return template.replace(/\{\{\s*([A-Za-z0-9_.-]+)\s*\}\}/g, (_match, name) => {
572
+ const value = options[name];
573
+ return value === void 0 || value === null ? "" : String(value);
574
+ });
575
+ }
576
+ __name(interpolate, "interpolate");
577
+ var SIZE_MAP2 = {
578
+ sm: 16,
579
+ md: 20,
580
+ lg: 24,
581
+ xl: 32
582
+ };
583
+ function Icon({ as: IconComponent, size = "md", color }) {
584
+ const numericSize = typeof size === "number" ? size : SIZE_MAP2[size];
585
+ const colorProps = color === void 0 ? {} : { color };
586
+ return /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { size: numericSize, ...colorProps });
587
+ }
588
+ __name(Icon, "Icon");
589
+
590
+ // ../tokens/build/theme.ts
591
+ var theme = {
592
+ color: {
593
+ danger: "#ef4444",
594
+ info: "#3b82f6",
595
+ neutral: {
596
+ "100": "#f4f4f5",
597
+ "200": "#e4e4e7",
598
+ "300": "#d4d4d8",
599
+ "400": "#a1a1aa",
600
+ "50": "#fafafa",
601
+ "500": "#71717a",
602
+ "600": "#52525b",
603
+ "700": "#3f3f46",
604
+ "800": "#27272a",
605
+ "900": "#18181b"
606
+ },
607
+ primary: {
608
+ "100": "#dbeafe",
609
+ "200": "#bfdbfe",
610
+ "300": "#93c5fd",
611
+ "400": "#60a5fa",
612
+ "50": "#f0f7ff",
613
+ "500": "#3b82f6",
614
+ "600": "#2563eb",
615
+ "700": "#1d4ed8",
616
+ "800": "#1e40af",
617
+ "900": "#1e3a8a"
618
+ },
619
+ success: "#22c55e",
620
+ warning: "#f59e0b"
621
+ },
622
+ fontSize: {
623
+ "2xl": "24px",
624
+ "3xl": "30px",
625
+ "4xl": "36px",
626
+ lg: "18px",
627
+ md: "16px",
628
+ sm: "14px",
629
+ xl: "20px",
630
+ xs: "12px"
631
+ },
632
+ fontWeight: {
633
+ bold: "700",
634
+ medium: "500",
635
+ regular: "400",
636
+ semibold: "600"
637
+ },
638
+ lineHeight: {
639
+ normal: "1.4",
640
+ relaxed: "1.6",
641
+ tight: "1.2"
642
+ },
643
+ radius: {
644
+ "2xl": "16px",
645
+ full: "9999px",
646
+ lg: "8px",
647
+ md: "6px",
648
+ none: "0px",
649
+ sm: "4px",
650
+ xl: "12px"
651
+ },
652
+ semantic: {
653
+ background: {
654
+ default: "#fafafa",
655
+ elevated: "#ffffff",
656
+ subtle: "#f4f4f5"
657
+ },
658
+ border: {
659
+ default: "#e4e4e7",
660
+ strong: "#d4d4d8"
661
+ },
662
+ interactive: {
663
+ destructive: "#ef4444",
664
+ primary: "#2563eb",
665
+ primaryHover: "#1d4ed8",
666
+ primaryPressed: "#1e40af"
667
+ },
668
+ text: {
669
+ default: "#18181b",
670
+ inverted: "#fafafa",
671
+ muted: "#52525b"
672
+ }
673
+ },
674
+ shadow: {
675
+ lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)",
676
+ md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)",
677
+ sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)"
678
+ },
679
+ spacing: {
680
+ "0": "0px",
681
+ "1": "4px",
682
+ "10": "40px",
683
+ "12": "48px",
684
+ "16": "64px",
685
+ "2": "8px",
686
+ "20": "80px",
687
+ "24": "96px",
688
+ "3": "12px",
689
+ "4": "16px",
690
+ "5": "20px",
691
+ "6": "24px",
692
+ "8": "32px"
693
+ }
694
+ };
695
+ var themeDark = {
696
+ color: {
697
+ danger: "#ef4444",
698
+ info: "#3b82f6",
699
+ neutral: {
700
+ "100": "#f4f4f5",
701
+ "200": "#e4e4e7",
702
+ "300": "#d4d4d8",
703
+ "400": "#a1a1aa",
704
+ "50": "#fafafa",
705
+ "500": "#71717a",
706
+ "600": "#52525b",
707
+ "700": "#3f3f46",
708
+ "800": "#27272a",
709
+ "900": "#18181b"
710
+ },
711
+ primary: {
712
+ "100": "#dbeafe",
713
+ "200": "#bfdbfe",
714
+ "300": "#93c5fd",
715
+ "400": "#60a5fa",
716
+ "50": "#f0f7ff",
717
+ "500": "#3b82f6",
718
+ "600": "#2563eb",
719
+ "700": "#1d4ed8",
720
+ "800": "#1e40af",
721
+ "900": "#1e3a8a"
722
+ },
723
+ success: "#22c55e",
724
+ warning: "#f59e0b"
725
+ },
726
+ fontSize: {
727
+ "2xl": "24px",
728
+ "3xl": "30px",
729
+ "4xl": "36px",
730
+ lg: "18px",
731
+ md: "16px",
732
+ sm: "14px",
733
+ xl: "20px",
734
+ xs: "12px"
735
+ },
736
+ fontWeight: {
737
+ bold: "700",
738
+ medium: "500",
739
+ regular: "400",
740
+ semibold: "600"
741
+ },
742
+ lineHeight: {
743
+ normal: "1.4",
744
+ relaxed: "1.6",
745
+ tight: "1.2"
746
+ },
747
+ radius: {
748
+ "2xl": "16px",
749
+ full: "9999px",
750
+ lg: "8px",
751
+ md: "6px",
752
+ none: "0px",
753
+ sm: "4px",
754
+ xl: "12px"
755
+ },
756
+ semantic: {
757
+ background: {
758
+ default: "#18181b",
759
+ elevated: "#3f3f46",
760
+ subtle: "#27272a"
761
+ },
762
+ border: {
763
+ default: "#3f3f46",
764
+ strong: "#52525b"
765
+ },
766
+ interactive: {
767
+ destructive: "#ef4444",
768
+ primary: "#60a5fa",
769
+ primaryHover: "#93c5fd",
770
+ primaryPressed: "#bfdbfe"
771
+ },
772
+ text: {
773
+ default: "#fafafa",
774
+ inverted: "#18181b",
775
+ muted: "#a1a1aa"
776
+ }
777
+ },
778
+ shadow: {
779
+ lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)",
780
+ md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)",
781
+ sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)"
782
+ },
783
+ spacing: {
784
+ "0": "0px",
785
+ "1": "4px",
786
+ "10": "40px",
787
+ "12": "48px",
788
+ "16": "64px",
789
+ "2": "8px",
790
+ "20": "80px",
791
+ "24": "96px",
792
+ "3": "12px",
793
+ "4": "16px",
794
+ "5": "20px",
795
+ "6": "24px",
796
+ "8": "32px"
797
+ }
798
+ };
799
+
800
+ exports.Box = Box;
801
+ exports.Button = Button;
802
+ exports.Checkbox = Checkbox;
803
+ exports.HStack = HStack;
804
+ exports.Icon = Icon;
805
+ exports.Slot = Slot;
806
+ exports.Spinner = Spinner;
807
+ exports.Switch = Switch;
808
+ exports.Text = Text;
809
+ exports.TextArea = TextArea;
810
+ exports.TextInput = TextInput;
811
+ exports.VStack = VStack;
812
+ exports.cn = cn;
813
+ exports.composeRefs = composeRefs;
814
+ exports.defaultDictionary = defaultDictionary;
815
+ exports.defaultSemanticIcons = defaultSemanticIcons;
816
+ exports.resolveI18n = resolveI18n;
817
+ exports.theme = theme;
818
+ exports.themeDark = themeDark;
819
+ //# sourceMappingURL=index.cjs.map
820
+ //# sourceMappingURL=index.cjs.map