namps-native 1.0.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/index.js ADDED
@@ -0,0 +1,655 @@
1
+ 'use strict';
2
+
3
+ var React2 = require('react');
4
+ var reactNative = require('react-native');
5
+ var Svg = require('react-native-svg');
6
+ var Animated2 = require('react-native-reanimated');
7
+
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
+
10
+ var React2__default = /*#__PURE__*/_interopDefault(React2);
11
+ var Svg__default = /*#__PURE__*/_interopDefault(Svg);
12
+ var Animated2__default = /*#__PURE__*/_interopDefault(Animated2);
13
+
14
+ var __defProp = Object.defineProperty;
15
+ var __export = (target, all) => {
16
+ for (var name in all)
17
+ __defProp(target, name, { get: all[name], enumerable: true });
18
+ };
19
+
20
+ // src/theme/tokens.ts
21
+ var tokens_exports = {};
22
+ __export(tokens_exports, {
23
+ fontFamily: () => fontFamily,
24
+ fontSize: () => fontSize,
25
+ fontWeight: () => fontWeight,
26
+ lineHeight: () => lineHeight,
27
+ motion: () => motion,
28
+ palette: () => palette,
29
+ radius: () => radius,
30
+ sizing: () => sizing,
31
+ space: () => space
32
+ });
33
+ var palette = {
34
+ // Warm paper neutrals
35
+ sand50: "#FBFAF6",
36
+ sand100: "#F3F0E8",
37
+ sand200: "#EAE6DB",
38
+ sand300: "#E5E0D4",
39
+ sand400: "#D4CDBD",
40
+ sand500: "#9C9482",
41
+ sand600: "#6B6555",
42
+ sand700: "#413C33",
43
+ sand800: "#211E18",
44
+ sand900: "#191712",
45
+ ink: "#201E1A",
46
+ paperWhite: "#FFFFFF",
47
+ // Clay accent
48
+ clay400: "#D6805C",
49
+ clay500: "#C15F3C",
50
+ clay600: "#A64E2E",
51
+ clay100: "#F1E1D8",
52
+ // Semantic hues
53
+ green500: "#47795B",
54
+ green400: "#6EA687",
55
+ amber500: "#9E6E1B",
56
+ amber400: "#CDA052",
57
+ red500: "#B0463B",
58
+ red400: "#D67E71",
59
+ blue500: "#3F6591",
60
+ blue400: "#7FA4CF"
61
+ };
62
+ var space = {
63
+ 0: 0,
64
+ 1: 4,
65
+ 2: 8,
66
+ 3: 12,
67
+ 4: 16,
68
+ 5: 20,
69
+ 6: 24,
70
+ 8: 32,
71
+ 10: 40,
72
+ 12: 64
73
+ };
74
+ var radius = {
75
+ none: 0,
76
+ sm: 6,
77
+ md: 10,
78
+ lg: 14,
79
+ xl: 20,
80
+ full: 999
81
+ };
82
+ var fontSize = {
83
+ xs: 12,
84
+ sm: 13,
85
+ base: 15,
86
+ md: 16,
87
+ lg: 18,
88
+ xl: 22,
89
+ "2xl": 28,
90
+ "3xl": 34,
91
+ display: 46
92
+ };
93
+ var lineHeight = {
94
+ tight: 1.15,
95
+ snug: 1.35,
96
+ normal: 1.5,
97
+ relaxed: 1.6
98
+ };
99
+ var fontWeight = {
100
+ regular: "400",
101
+ medium: "500",
102
+ semibold: "600",
103
+ bold: "700"
104
+ };
105
+ var fontFamily = {
106
+ display: "Newsreader",
107
+ body: "Geist",
108
+ mono: "JetBrainsMono"
109
+ };
110
+ var motion = {
111
+ duration: { fast: 120, base: 220, slow: 340 },
112
+ /** Reanimated: `Easing.bezier(...motion.easing.standard)`. */
113
+ easing: {
114
+ standard: [0.2, 0, 0, 1],
115
+ decelerate: [0, 0, 0, 1],
116
+ accelerate: [0.4, 0, 1, 1]
117
+ }
118
+ };
119
+ var sizing = {
120
+ sm: { height: 34, paddingX: space[3], fontSize: fontSize.sm, radius: radius.sm, icon: 16 },
121
+ md: { height: 44, paddingX: space[5], fontSize: fontSize.base, radius: radius.md, icon: 18 },
122
+ lg: { height: 54, paddingX: space[6], fontSize: fontSize.md, radius: radius.lg, icon: 20 }
123
+ };
124
+
125
+ // src/theme/themes.ts
126
+ var shared = { space, radius, fontSize, lineHeight, fontWeight, fontFamily, motion, sizing };
127
+ var lightTheme = {
128
+ name: "light",
129
+ ...shared,
130
+ colors: {
131
+ bg: palette.sand100,
132
+ surface: palette.sand50,
133
+ elevated: palette.paperWhite,
134
+ sunken: palette.sand200,
135
+ border: palette.sand300,
136
+ borderStrong: palette.sand400,
137
+ text: palette.ink,
138
+ textMuted: palette.sand600,
139
+ textSubtle: palette.sand500,
140
+ accent: palette.clay500,
141
+ accentHover: palette.clay600,
142
+ accentSoft: palette.clay100,
143
+ onAccent: palette.paperWhite,
144
+ success: palette.green500,
145
+ successSoft: "#E1ECE4",
146
+ warning: palette.amber500,
147
+ warningSoft: "#F3E8D2",
148
+ danger: palette.red500,
149
+ dangerSoft: "#F3DED9",
150
+ info: palette.blue500,
151
+ infoSoft: "#DDE7F1"
152
+ },
153
+ shadow: {
154
+ sm: { shadowColor: "#2B2214", shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.06, shadowRadius: 2, elevation: 1 },
155
+ md: { shadowColor: "#2B2214", shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.08, shadowRadius: 14, elevation: 4 },
156
+ lg: { shadowColor: "#2B2214", shadowOffset: { width: 0, height: 18 }, shadowOpacity: 0.14, shadowRadius: 48, elevation: 12 }
157
+ }
158
+ };
159
+ var darkTheme = {
160
+ name: "dark",
161
+ ...shared,
162
+ colors: {
163
+ bg: palette.sand900,
164
+ surface: palette.sand800,
165
+ elevated: "#2A261F",
166
+ sunken: "#131109",
167
+ border: "#332F27",
168
+ borderStrong: "#443F35",
169
+ text: "#EDE8DC",
170
+ textMuted: "#A69E8D",
171
+ textSubtle: "#726B5C",
172
+ accent: palette.clay400,
173
+ accentHover: "#E4936F",
174
+ accentSoft: "#3A2A21",
175
+ onAccent: "#1B140F",
176
+ success: palette.green400,
177
+ successSoft: "#20302A",
178
+ warning: palette.amber400,
179
+ warningSoft: "#332916",
180
+ danger: palette.red400,
181
+ dangerSoft: "#3A231E",
182
+ info: palette.blue400,
183
+ infoSoft: "#1F2A38"
184
+ },
185
+ shadow: {
186
+ sm: { shadowColor: "#000", shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.4, shadowRadius: 2, elevation: 1 },
187
+ md: { shadowColor: "#000", shadowOffset: { width: 0, height: 6 }, shadowOpacity: 0.45, shadowRadius: 18, elevation: 6 },
188
+ lg: { shadowColor: "#000", shadowOffset: { width: 0, height: 22 }, shadowOpacity: 0.6, shadowRadius: 55, elevation: 16 }
189
+ }
190
+ };
191
+ function createTheme(base2, overrides = {}) {
192
+ return deepMerge(base2, overrides);
193
+ }
194
+ function deepMerge(base2, override) {
195
+ const out = Array.isArray(base2) ? [...base2] : { ...base2 };
196
+ for (const key in override) {
197
+ const v = override[key];
198
+ if (v && typeof v === "object" && !Array.isArray(v)) out[key] = deepMerge(base2[key], v);
199
+ else if (v !== void 0) out[key] = v;
200
+ }
201
+ return out;
202
+ }
203
+
204
+ // src/theme/ThemeProvider.tsx
205
+ var ThemeContext = React2.createContext(null);
206
+ function ThemeProvider({
207
+ children,
208
+ light = lightTheme,
209
+ dark = darkTheme,
210
+ defaultPreference = "system"
211
+ }) {
212
+ const system = reactNative.useColorScheme();
213
+ const [preference, setPreference] = React2.useState(defaultPreference);
214
+ const scheme = preference === "system" ? system === "dark" ? "dark" : "light" : preference;
215
+ const toggle = React2.useCallback(
216
+ () => setPreference((p) => {
217
+ const current = p === "system" ? system === "dark" ? "dark" : "light" : p;
218
+ return current === "dark" ? "light" : "dark";
219
+ }),
220
+ [system]
221
+ );
222
+ const value = React2.useMemo(
223
+ () => ({ theme: scheme === "dark" ? dark : light, scheme, preference, setPreference, toggle }),
224
+ [scheme, preference, light, dark, toggle]
225
+ );
226
+ return /* @__PURE__ */ React2__default.default.createElement(ThemeContext.Provider, { value }, children);
227
+ }
228
+ function useThemeContext() {
229
+ const ctx = React2.useContext(ThemeContext);
230
+ if (!ctx) throw new Error("Clay: components must be rendered inside <ThemeProvider>.");
231
+ return ctx;
232
+ }
233
+
234
+ // src/theme/useTheme.ts
235
+ function useTheme() {
236
+ return useThemeContext().theme;
237
+ }
238
+ function useColorSchemeControl() {
239
+ const { scheme, preference, setPreference, toggle } = useThemeContext();
240
+ return { scheme, preference, setPreference, toggle };
241
+ }
242
+ function useControllableState(params) {
243
+ const { value, defaultValue, onChange } = params;
244
+ const isControlled = value !== void 0;
245
+ const [internal, setInternal] = React2.useState(defaultValue);
246
+ const onChangeRef = React2.useRef(onChange);
247
+ onChangeRef.current = onChange;
248
+ const resolved = isControlled ? value : internal;
249
+ const setValue = React2.useCallback(
250
+ (next) => {
251
+ if (!isControlled) setInternal(next);
252
+ onChangeRef.current?.(next);
253
+ },
254
+ [isControlled]
255
+ );
256
+ return [resolved, setValue];
257
+ }
258
+ function useDisclosure(defaultOpen = false) {
259
+ const [isOpen, setOpen] = React2.useState(defaultOpen);
260
+ const open = React2.useCallback(() => setOpen(true), []);
261
+ const close = React2.useCallback(() => setOpen(false), []);
262
+ const toggle = React2.useCallback(() => setOpen((v) => !v), []);
263
+ return { isOpen, open, close, toggle };
264
+ }
265
+
266
+ // src/utils/color.ts
267
+ function shade(hex, amount) {
268
+ const { r, g, b } = hexToRgb(hex);
269
+ const t = amount < 0 ? 0 : 255;
270
+ const p = Math.abs(amount);
271
+ const mix = (c) => Math.round((t - c) * p + c);
272
+ return rgbToHex(mix(r), mix(g), mix(b));
273
+ }
274
+ function withAlpha(hex, alpha) {
275
+ const { r, g, b } = hexToRgb(hex);
276
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
277
+ }
278
+ function hexToRgb(hex) {
279
+ const h = hex.replace("#", "");
280
+ const full = h.length === 3 ? h.split("").map((c) => c + c).join("") : h;
281
+ return {
282
+ r: parseInt(full.slice(0, 2), 16),
283
+ g: parseInt(full.slice(2, 4), 16),
284
+ b: parseInt(full.slice(4, 6), 16)
285
+ };
286
+ }
287
+ function rgbToHex(r, g, b) {
288
+ return "#" + [r, g, b].map((c) => c.toString(16).padStart(2, "0")).join("");
289
+ }
290
+ var base = (size = 22) => ({ width: size, height: size, viewBox: "0 0 24 24", fill: "none" });
291
+ var stroke = (color = "currentColor") => ({ stroke: color, strokeWidth: 1.7, strokeLinecap: "round", strokeLinejoin: "round" });
292
+ var SearchIcon = ({ size, color }) => /* @__PURE__ */ React2__default.default.createElement(Svg__default.default, { ...base(size) }, /* @__PURE__ */ React2__default.default.createElement(Svg.Circle, { cx: 11, cy: 11, r: 6.5, ...stroke(color) }), /* @__PURE__ */ React2__default.default.createElement(Svg.Path, { d: "m20 20-3.6-3.6", ...stroke(color) }));
293
+ var PlusIcon = ({ size, color }) => /* @__PURE__ */ React2__default.default.createElement(Svg__default.default, { ...base(size) }, /* @__PURE__ */ React2__default.default.createElement(Svg.Path, { d: "M12 5v14M5 12h14", ...stroke(color) }));
294
+ var CheckIcon = ({ size, color }) => /* @__PURE__ */ React2__default.default.createElement(Svg__default.default, { ...base(size) }, /* @__PURE__ */ React2__default.default.createElement(Svg.Path, { d: "m5 12.5 4.5 4.5L19 7", ...stroke(color), strokeWidth: 2 }));
295
+ var ChevronRightIcon = ({ size, color }) => /* @__PURE__ */ React2__default.default.createElement(Svg__default.default, { ...base(size) }, /* @__PURE__ */ React2__default.default.createElement(Svg.Path, { d: "m9 6 6 6-6 6", ...stroke(color) }));
296
+ var CloseIcon = ({ size, color }) => /* @__PURE__ */ React2__default.default.createElement(Svg__default.default, { ...base(size) }, /* @__PURE__ */ React2__default.default.createElement(Svg.Path, { d: "m6 6 12 12M18 6 6 18", ...stroke(color), strokeWidth: 1.8 }));
297
+ var BellIcon = ({ size, color }) => /* @__PURE__ */ React2__default.default.createElement(Svg__default.default, { ...base(size) }, /* @__PURE__ */ React2__default.default.createElement(Svg.Path, { d: "M18 8.5a6 6 0 1 0-12 0c0 5-2 6.5-2 6.5h16s-2-1.5-2-6.5", ...stroke(color) }), /* @__PURE__ */ React2__default.default.createElement(Svg.Path, { d: "M10.5 19a1.8 1.8 0 0 0 3 0", ...stroke(color) }));
298
+ var AView = Animated2__default.default.createAnimatedComponent(reactNative.View);
299
+ function Button({
300
+ children,
301
+ variant = "primary",
302
+ size = "md",
303
+ loading = false,
304
+ disabled = false,
305
+ fullWidth = false,
306
+ leftIcon,
307
+ rightIcon,
308
+ onPress,
309
+ style,
310
+ accessibilityLabel,
311
+ accessibilityHint,
312
+ testID
313
+ }) {
314
+ const theme = useTheme();
315
+ const dim = theme.sizing[size];
316
+ const pressed = Animated2.useSharedValue(0);
317
+ const isDisabled = disabled || loading;
318
+ const palette2 = getVariant(variant, theme);
319
+ const animatedStyle = Animated2.useAnimatedStyle(() => ({
320
+ opacity: Animated2.withTiming(pressed.value ? 0.9 : 1, { duration: theme.motion.duration.fast }),
321
+ transform: [{ scale: Animated2.withTiming(pressed.value ? 0.98 : 1, { duration: theme.motion.duration.fast }) }]
322
+ }));
323
+ return /* @__PURE__ */ React2__default.default.createElement(
324
+ reactNative.Pressable,
325
+ {
326
+ onPress,
327
+ onPressIn: () => pressed.value = 1,
328
+ onPressOut: () => pressed.value = 0,
329
+ disabled: isDisabled,
330
+ accessibilityRole: "button",
331
+ accessibilityState: { disabled: isDisabled, busy: loading },
332
+ accessibilityLabel,
333
+ accessibilityHint,
334
+ testID,
335
+ style: fullWidth ? { alignSelf: "stretch" } : void 0
336
+ },
337
+ /* @__PURE__ */ React2__default.default.createElement(
338
+ AView,
339
+ {
340
+ style: [
341
+ {
342
+ height: dim.height,
343
+ paddingHorizontal: dim.paddingX,
344
+ borderRadius: dim.radius,
345
+ backgroundColor: palette2.bg,
346
+ borderWidth: palette2.borderWidth,
347
+ borderColor: palette2.border,
348
+ flexDirection: "row",
349
+ alignItems: "center",
350
+ justifyContent: "center",
351
+ gap: theme.space[2],
352
+ opacity: isDisabled ? 0.55 : 1
353
+ },
354
+ animatedStyle,
355
+ style
356
+ ]
357
+ },
358
+ loading ? /* @__PURE__ */ React2__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: palette2.fg }) : /* @__PURE__ */ React2__default.default.createElement(React2__default.default.Fragment, null, leftIcon, children != null && /* @__PURE__ */ React2__default.default.createElement(reactNative.Text, { style: { color: palette2.fg, fontSize: dim.fontSize, fontFamily: theme.fontFamily.body, fontWeight: theme.fontWeight.semibold } }, children), rightIcon)
359
+ )
360
+ );
361
+ }
362
+ function getVariant(variant, theme, _disabled) {
363
+ const c = theme.colors;
364
+ switch (variant) {
365
+ case "secondary":
366
+ return { bg: c.elevated, fg: c.text, border: c.borderStrong, borderWidth: 1 };
367
+ case "soft":
368
+ return { bg: c.accentSoft, fg: c.accent, border: "transparent", borderWidth: 0 };
369
+ case "ghost":
370
+ return { bg: "transparent", fg: c.text, border: "transparent", borderWidth: 0 };
371
+ case "danger":
372
+ return { bg: c.danger, fg: "#fff", border: "transparent", borderWidth: 0 };
373
+ case "primary":
374
+ default:
375
+ return { bg: c.accent, fg: c.onAccent, border: "transparent", borderWidth: 0 };
376
+ }
377
+ }
378
+ function IconButton({
379
+ icon,
380
+ variant = "ghost",
381
+ size = "md",
382
+ round = false,
383
+ disabled = false,
384
+ onPress,
385
+ style,
386
+ accessibilityLabel,
387
+ accessibilityHint,
388
+ testID
389
+ }) {
390
+ const theme = useTheme();
391
+ const dim = theme.sizing[size];
392
+ const c = theme.colors;
393
+ const bg = variant === "primary" ? c.accent : variant === "danger" ? c.danger : variant === "soft" ? c.accentSoft : variant === "secondary" ? c.elevated : "transparent";
394
+ const border = variant === "secondary" ? c.borderStrong : "transparent";
395
+ return /* @__PURE__ */ React2__default.default.createElement(
396
+ reactNative.Pressable,
397
+ {
398
+ onPress,
399
+ disabled,
400
+ accessibilityRole: "button",
401
+ accessibilityLabel,
402
+ accessibilityHint,
403
+ accessibilityState: { disabled },
404
+ testID,
405
+ style: ({ pressed }) => [
406
+ {
407
+ width: dim.height,
408
+ height: dim.height,
409
+ borderRadius: round ? theme.radius.full : dim.radius,
410
+ backgroundColor: bg,
411
+ borderWidth: variant === "secondary" ? 1 : 0,
412
+ borderColor: border,
413
+ alignItems: "center",
414
+ justifyContent: "center",
415
+ opacity: disabled ? 0.5 : pressed ? 0.85 : 1
416
+ },
417
+ style
418
+ ]
419
+ },
420
+ /* @__PURE__ */ React2__default.default.createElement(reactNative.View, null, icon)
421
+ );
422
+ }
423
+ function Text2({ children, variant = "body", tone = "default", weight, align, style, ...rest }) {
424
+ const theme = useTheme();
425
+ const v = {
426
+ body: { fontSize: theme.fontSize.base, lineHeight: theme.fontSize.base * theme.lineHeight.relaxed, family: theme.fontFamily.body },
427
+ bodyLg: { fontSize: theme.fontSize.lg, lineHeight: theme.fontSize.lg * theme.lineHeight.relaxed, family: theme.fontFamily.body },
428
+ label: { fontSize: theme.fontSize.sm, lineHeight: theme.fontSize.sm * theme.lineHeight.snug, family: theme.fontFamily.body },
429
+ caption: { fontSize: theme.fontSize.xs, lineHeight: theme.fontSize.xs * theme.lineHeight.snug, family: theme.fontFamily.body },
430
+ mono: { fontSize: theme.fontSize.sm, lineHeight: theme.fontSize.sm * theme.lineHeight.normal, family: theme.fontFamily.mono }
431
+ }[variant];
432
+ const color = {
433
+ default: theme.colors.text,
434
+ muted: theme.colors.textMuted,
435
+ subtle: theme.colors.textSubtle,
436
+ accent: theme.colors.accent,
437
+ danger: theme.colors.danger,
438
+ success: theme.colors.success,
439
+ onAccent: theme.colors.onAccent
440
+ }[tone];
441
+ return /* @__PURE__ */ React2__default.default.createElement(
442
+ reactNative.Text,
443
+ {
444
+ style: [{ color, fontSize: v.fontSize, lineHeight: v.lineHeight, fontFamily: v.family, fontWeight: weight ? theme.fontWeight[weight] : theme.fontWeight.regular, textAlign: align }, style],
445
+ ...rest
446
+ },
447
+ children
448
+ );
449
+ }
450
+ function Heading({ children, level = 2, align, tone = "default", numberOfLines, style }) {
451
+ const theme = useTheme();
452
+ const map = {
453
+ 1: { fontSize: theme.fontSize["3xl"], weight: theme.fontWeight.medium },
454
+ 2: { fontSize: theme.fontSize["2xl"], weight: theme.fontWeight.medium },
455
+ 3: { fontSize: theme.fontSize.xl, weight: theme.fontWeight.medium },
456
+ 4: { fontSize: theme.fontSize.lg, weight: theme.fontWeight.semibold }
457
+ }[level];
458
+ const color = tone === "accent" ? theme.colors.accent : tone === "onAccent" ? theme.colors.onAccent : theme.colors.text;
459
+ return /* @__PURE__ */ React2__default.default.createElement(
460
+ reactNative.Text,
461
+ {
462
+ accessibilityRole: "header",
463
+ numberOfLines,
464
+ style: [{ color, fontSize: map.fontSize, lineHeight: map.fontSize * theme.lineHeight.tight, fontFamily: theme.fontFamily.display, fontWeight: map.weight, letterSpacing: -0.4, textAlign: align }, style]
465
+ },
466
+ children
467
+ );
468
+ }
469
+ function Card({ variant = "outlined", padding = 4, onPress, style, children, testID }) {
470
+ const theme = useTheme();
471
+ const c = theme.colors;
472
+ const surface = {
473
+ outlined: { backgroundColor: c.surface, borderWidth: 1, borderColor: c.border, shadow: void 0 },
474
+ elevated: { backgroundColor: c.elevated, borderWidth: 0, borderColor: "transparent", shadow: theme.shadow.sm },
475
+ filled: { backgroundColor: c.sunken, borderWidth: 1, borderColor: c.border, shadow: void 0 }
476
+ }[variant];
477
+ const boxStyle = [
478
+ {
479
+ borderRadius: theme.radius.lg,
480
+ padding: theme.space[padding],
481
+ backgroundColor: surface.backgroundColor,
482
+ borderWidth: surface.borderWidth,
483
+ borderColor: surface.borderColor
484
+ },
485
+ surface.shadow,
486
+ style
487
+ ];
488
+ if (onPress) {
489
+ return /* @__PURE__ */ React2__default.default.createElement(reactNative.Pressable, { onPress, testID, accessibilityRole: "button", style: ({ pressed }) => [...boxStyle, { opacity: pressed ? 0.94 : 1 }] }, children);
490
+ }
491
+ return /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { testID, style: boxStyle }, children);
492
+ }
493
+ function Input({
494
+ label,
495
+ helperText,
496
+ error,
497
+ size = "md",
498
+ leftAdornment,
499
+ rightAdornment,
500
+ disabled,
501
+ value,
502
+ onChangeText,
503
+ placeholder,
504
+ style,
505
+ testID,
506
+ onFocus,
507
+ onBlur,
508
+ ...rest
509
+ }) {
510
+ const theme = useTheme();
511
+ const c = theme.colors;
512
+ const dim = theme.sizing[size];
513
+ const [focused, setFocused] = React2.useState(false);
514
+ const hasError = !!error;
515
+ const borderColor = hasError ? c.danger : focused ? c.accent : c.borderStrong;
516
+ return /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style }, label && /* @__PURE__ */ React2__default.default.createElement(Text2, { variant: "label", weight: "medium", tone: hasError ? "danger" : "default", style: { marginBottom: theme.space[2] } }, label), /* @__PURE__ */ React2__default.default.createElement(
517
+ reactNative.View,
518
+ {
519
+ style: {
520
+ minHeight: dim.height,
521
+ flexDirection: "row",
522
+ alignItems: "center",
523
+ gap: theme.space[2],
524
+ paddingHorizontal: theme.space[3] + 2,
525
+ borderRadius: dim.radius,
526
+ borderWidth: 1,
527
+ borderColor,
528
+ backgroundColor: disabled ? c.sunken : c.elevated
529
+ }
530
+ },
531
+ leftAdornment,
532
+ /* @__PURE__ */ React2__default.default.createElement(
533
+ reactNative.TextInput,
534
+ {
535
+ value,
536
+ onChangeText,
537
+ placeholder,
538
+ placeholderTextColor: c.textSubtle,
539
+ editable: !disabled,
540
+ onFocus: (e) => {
541
+ setFocused(true);
542
+ onFocus?.(e);
543
+ },
544
+ onBlur: (e) => {
545
+ setFocused(false);
546
+ onBlur?.(e);
547
+ },
548
+ testID,
549
+ style: { flex: 1, color: disabled ? c.textSubtle : c.text, fontSize: dim.fontSize, fontFamily: theme.fontFamily.body, paddingVertical: theme.space[2] },
550
+ ...rest
551
+ }
552
+ ),
553
+ rightAdornment
554
+ ), (error || helperText) && /* @__PURE__ */ React2__default.default.createElement(Text2, { variant: "caption", tone: hasError ? "danger" : "subtle", style: { marginTop: theme.space[1] + 2 } }, error || helperText));
555
+ }
556
+ function Switch({ value, defaultValue = false, onValueChange, disabled, accessibilityLabel, testID }) {
557
+ const theme = useTheme();
558
+ const [on, setOn] = useControllableState({ value, defaultValue, onChange: onValueChange });
559
+ const progress = Animated2.useDerivedValue(() => Animated2.withTiming(on ? 1 : 0, { duration: theme.motion.duration.fast }), [on]);
560
+ const trackStyle = Animated2.useAnimatedStyle(() => ({
561
+ backgroundColor: Animated2.interpolateColor(progress.value, [0, 1], [theme.colors.borderStrong, theme.colors.accent])
562
+ }));
563
+ const thumbStyle = Animated2.useAnimatedStyle(() => ({ transform: [{ translateX: 18 * progress.value }] }));
564
+ return /* @__PURE__ */ React2__default.default.createElement(
565
+ reactNative.Pressable,
566
+ {
567
+ onPress: () => setOn(!on),
568
+ disabled,
569
+ accessibilityRole: "switch",
570
+ accessibilityState: { checked: on, disabled },
571
+ accessibilityLabel,
572
+ testID,
573
+ hitSlop: 10,
574
+ style: { opacity: disabled ? 0.5 : 1 }
575
+ },
576
+ /* @__PURE__ */ React2__default.default.createElement(Animated2__default.default.View, { style: [{ width: 44, height: 26, borderRadius: theme.radius.full, padding: 3, justifyContent: "center" }, trackStyle] }, /* @__PURE__ */ React2__default.default.createElement(Animated2__default.default.View, { style: [{ width: 20, height: 20, borderRadius: theme.radius.full, backgroundColor: "#fff" }, theme.shadow.sm, thumbStyle] }))
577
+ );
578
+ }
579
+ function Checkbox({ value, defaultValue = false, onValueChange, label, disabled, accessibilityLabel, testID }) {
580
+ const theme = useTheme();
581
+ const [checked, setChecked] = useControllableState({ value, defaultValue, onChange: onValueChange });
582
+ const c = theme.colors;
583
+ return /* @__PURE__ */ React2__default.default.createElement(
584
+ reactNative.Pressable,
585
+ {
586
+ onPress: () => setChecked(!checked),
587
+ disabled,
588
+ accessibilityRole: "checkbox",
589
+ accessibilityState: { checked, disabled },
590
+ accessibilityLabel: accessibilityLabel ?? label,
591
+ testID,
592
+ hitSlop: 8,
593
+ style: { flexDirection: "row", alignItems: "center", gap: theme.space[3], opacity: disabled ? 0.5 : 1 }
594
+ },
595
+ /* @__PURE__ */ React2__default.default.createElement(
596
+ reactNative.View,
597
+ {
598
+ style: {
599
+ width: 22,
600
+ height: 22,
601
+ borderRadius: 7,
602
+ alignItems: "center",
603
+ justifyContent: "center",
604
+ backgroundColor: checked ? c.accent : "transparent",
605
+ borderWidth: checked ? 0 : 1.8,
606
+ borderColor: c.borderStrong
607
+ }
608
+ },
609
+ checked && /* @__PURE__ */ React2__default.default.createElement(CheckIcon, { size: 14, color: "#fff" })
610
+ ),
611
+ label && /* @__PURE__ */ React2__default.default.createElement(Text2, { variant: "body" }, label)
612
+ );
613
+ }
614
+ function Badge({ children, status = "neutral", dot = false, style, testID }) {
615
+ const theme = useTheme();
616
+ const c = theme.colors;
617
+ const map = {
618
+ info: { bg: c.infoSoft, fg: c.info },
619
+ success: { bg: c.successSoft, fg: c.success },
620
+ warning: { bg: c.warningSoft, fg: c.warning },
621
+ danger: { bg: c.dangerSoft, fg: c.danger },
622
+ neutral: { bg: c.sunken, fg: c.textMuted }
623
+ };
624
+ const tone = map[status];
625
+ return /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { testID, style: [{ flexDirection: "row", alignItems: "center", gap: theme.space[1] + 2, height: 24, paddingHorizontal: theme.space[2] + 2, borderRadius: theme.radius.full, backgroundColor: tone.bg }, style] }, dot && /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: { width: 6, height: 6, borderRadius: 3, backgroundColor: tone.fg } }), /* @__PURE__ */ React2__default.default.createElement(Text2, { variant: "caption", weight: "semibold", style: { color: tone.fg } }, children));
626
+ }
627
+
628
+ exports.Badge = Badge;
629
+ exports.BellIcon = BellIcon;
630
+ exports.Button = Button;
631
+ exports.Card = Card;
632
+ exports.CheckIcon = CheckIcon;
633
+ exports.Checkbox = Checkbox;
634
+ exports.ChevronRightIcon = ChevronRightIcon;
635
+ exports.CloseIcon = CloseIcon;
636
+ exports.Heading = Heading;
637
+ exports.IconButton = IconButton;
638
+ exports.Input = Input;
639
+ exports.PlusIcon = PlusIcon;
640
+ exports.SearchIcon = SearchIcon;
641
+ exports.Switch = Switch;
642
+ exports.Text = Text2;
643
+ exports.ThemeProvider = ThemeProvider;
644
+ exports.createTheme = createTheme;
645
+ exports.darkTheme = darkTheme;
646
+ exports.lightTheme = lightTheme;
647
+ exports.shade = shade;
648
+ exports.tokens = tokens_exports;
649
+ exports.useColorSchemeControl = useColorSchemeControl;
650
+ exports.useControllableState = useControllableState;
651
+ exports.useDisclosure = useDisclosure;
652
+ exports.useTheme = useTheme;
653
+ exports.withAlpha = withAlpha;
654
+ //# sourceMappingURL=index.js.map
655
+ //# sourceMappingURL=index.js.map