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