@12min/ds 0.1.0 → 3.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.
@@ -1,13 +1,750 @@
1
1
  import {
2
+ DEFAULT_OPTIONS,
2
3
  darkTheme,
3
- lightTheme
4
- } from "./chunk-QIJRSFZB.mjs";
4
+ lightTheme,
5
+ ratingScaleTokens
6
+ } from "./chunk-ZKPOS2PD.mjs";
5
7
  import {
6
- colors
7
- } from "./chunk-E2C4G6H4.mjs";
8
+ borderWidth,
9
+ colors,
10
+ grid,
11
+ opacity,
12
+ radius,
13
+ shadow,
14
+ spacing,
15
+ typography
16
+ } from "./chunk-ZK7NW4WW.mjs";
17
+
18
+ // src/context/ThemeProvider.tsx
19
+ import { createContext, useContext, useMemo } from "react";
20
+ import { jsx } from "react/jsx-runtime";
21
+ var DSThemeContext = createContext({ theme: lightTheme, colorScheme: "light" });
22
+ function DSThemeProvider({
23
+ colorScheme = "light",
24
+ children
25
+ }) {
26
+ const value = useMemo(
27
+ () => ({ theme: colorScheme === "dark" ? darkTheme : lightTheme, colorScheme }),
28
+ [colorScheme]
29
+ );
30
+ return /* @__PURE__ */ jsx(DSThemeContext.Provider, { value, children });
31
+ }
32
+ function useTheme() {
33
+ return useContext(DSThemeContext);
34
+ }
35
+
36
+ // src/components/Button/Button.native.tsx
37
+ import { Pressable, Text, StyleSheet } from "react-native";
38
+
39
+ // src/components/Button/Button.styles.ts
40
+ var buttonTokens = {
41
+ sizes: {
42
+ sm: { height: 32, paddingHorizontal: 12 },
43
+ md: { height: 40, paddingHorizontal: 16 },
44
+ lg: { height: 48, paddingHorizontal: 24 }
45
+ },
46
+ borderRadius: radius.full
47
+ };
48
+
49
+ // src/components/Button/Button.native.tsx
50
+ import { jsx as jsx2 } from "react/jsx-runtime";
51
+ var textStyleBySize = {
52
+ sm: typography.buttonSmall,
53
+ md: typography.buttonDefault,
54
+ lg: typography.buttonLarge
55
+ };
56
+ function Button({ variant = "primary", size = "lg", disabled = false, children, onPress }) {
57
+ const { theme } = useTheme();
58
+ const { sizes: sizes2, borderRadius } = buttonTokens;
59
+ const sizeStyle = sizes2[size];
60
+ const textStyle = textStyleBySize[size];
61
+ const bgColor = disabled ? variant === "ghost" ? "transparent" : theme.bg.disabled : variant === "primary" ? theme.bg.primary : variant === "secondary" ? theme.bg.primarySubtle : "transparent";
62
+ const textColor = disabled ? theme.text.disabled : variant === "primary" ? theme.text.inverse : variant === "secondary" ? theme.text.primary : theme.text.brand;
63
+ return /* @__PURE__ */ jsx2(
64
+ Pressable,
65
+ {
66
+ onPress: disabled ? void 0 : onPress,
67
+ disabled,
68
+ style: ({ pressed }) => [
69
+ styles.base,
70
+ {
71
+ height: sizeStyle.height,
72
+ paddingHorizontal: sizeStyle.paddingHorizontal,
73
+ borderRadius,
74
+ backgroundColor: bgColor,
75
+ opacity: !disabled && pressed ? 1 - opacity.pressed : 1
76
+ }
77
+ ],
78
+ accessibilityRole: "button",
79
+ accessibilityState: { disabled },
80
+ children: /* @__PURE__ */ jsx2(Text, { style: [textStyle, { color: textColor }], children })
81
+ }
82
+ );
83
+ }
84
+ var styles = StyleSheet.create({
85
+ base: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 8 }
86
+ });
87
+
88
+ // src/components/ButtonIcon/ButtonIcon.native.tsx
89
+ import { Pressable as Pressable2, StyleSheet as StyleSheet2 } from "react-native";
90
+ import { jsx as jsx3 } from "react/jsx-runtime";
91
+ var sizeBySize = {
92
+ sm: 40,
93
+ md: 48,
94
+ lg: 64
95
+ };
96
+ function ButtonIcon({ icon, accessibilityLabel, variant = "primary", size = "md", disabled = false, onPress }) {
97
+ const { theme, colorScheme } = useTheme();
98
+ const dimension = sizeBySize[size];
99
+ const bgColor = disabled ? variant === "ghost" ? "transparent" : theme.bg.disabled : variant === "primary" ? theme.bg.primary : variant === "secondary" ? theme.bg.primarySubtle : variant === "overlay" ? colorScheme === "dark" ? colors.overlayWhite[8] : colors.overlayBlack[8] : "transparent";
100
+ return /* @__PURE__ */ jsx3(
101
+ Pressable2,
102
+ {
103
+ onPress: disabled ? void 0 : onPress,
104
+ disabled,
105
+ style: ({ pressed }) => [
106
+ styles2.base,
107
+ {
108
+ width: dimension,
109
+ height: dimension,
110
+ borderRadius: radius.full,
111
+ backgroundColor: bgColor,
112
+ opacity: !disabled && pressed ? 1 - opacity.pressed : 1
113
+ }
114
+ ],
115
+ accessibilityRole: "button",
116
+ accessibilityLabel,
117
+ accessibilityState: { disabled },
118
+ children: icon
119
+ }
120
+ );
121
+ }
122
+ var styles2 = StyleSheet2.create({
123
+ base: { alignItems: "center", justifyContent: "center" }
124
+ });
125
+
126
+ // src/components/DismissButton/DismissButton.native.tsx
127
+ import { Pressable as Pressable3, View, StyleSheet as StyleSheet3 } from "react-native";
128
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
129
+ var containerSize = { xs: 20, sm: 32, md: 40 };
130
+ var glyphSize = { xs: 12, sm: 16, md: 20 };
131
+ function DismissButton({ accessibilityLabel = "Fechar", variant = "subtle", size = "sm", disabled = false, onPress }) {
132
+ const { theme, colorScheme } = useTheme();
133
+ const dimension = containerSize[size];
134
+ const glyph2 = glyphSize[size];
135
+ const bgColor = disabled ? variant === "ghost" ? "transparent" : theme.bg.disabled : variant === "subtle" ? colorScheme === "dark" ? colors.overlayWhite[8] : colors.overlayBlack[8] : "transparent";
136
+ const glyphColor = disabled ? theme.text.disabled : theme.icon.primary;
137
+ return /* @__PURE__ */ jsx4(
138
+ Pressable3,
139
+ {
140
+ onPress: disabled ? void 0 : onPress,
141
+ disabled,
142
+ style: ({ pressed }) => [
143
+ styles3.base,
144
+ {
145
+ width: dimension,
146
+ height: dimension,
147
+ borderRadius: radius.full,
148
+ backgroundColor: bgColor,
149
+ opacity: !disabled && pressed ? 1 - opacity.pressed : 1
150
+ }
151
+ ],
152
+ accessibilityRole: "button",
153
+ accessibilityLabel,
154
+ accessibilityState: { disabled },
155
+ children: /* @__PURE__ */ jsxs(View, { style: { width: glyph2, height: glyph2, alignItems: "center", justifyContent: "center" }, children: [
156
+ /* @__PURE__ */ jsx4(View, { style: [styles3.line, { width: glyph2, backgroundColor: glyphColor, transform: [{ rotate: "45deg" }] }] }),
157
+ /* @__PURE__ */ jsx4(View, { style: [styles3.line, { width: glyph2, backgroundColor: glyphColor, transform: [{ rotate: "-45deg" }] }] })
158
+ ] })
159
+ }
160
+ );
161
+ }
162
+ var styles3 = StyleSheet3.create({
163
+ base: { alignItems: "center", justifyContent: "center" },
164
+ line: { position: "absolute", height: 2, borderRadius: 1 }
165
+ });
166
+
167
+ // src/components/Chip/Chip.native.tsx
168
+ import { Pressable as Pressable4, Text as Text2, StyleSheet as StyleSheet4 } from "react-native";
169
+
170
+ // src/components/Chip/Chip.styles.ts
171
+ var chipSizes = {
172
+ sm: { height: 32, paddingHorizontal: 12 },
173
+ md: { height: 44, paddingHorizontal: 16 }
174
+ };
175
+ var chipRadius = radius.chip;
176
+
177
+ // src/components/Chip/Chip.native.tsx
178
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
179
+ function Chip({ children, checked = false, disabled = false, size = "md", leading, trailing, onPress, style }) {
180
+ const { theme } = useTheme();
181
+ const { height, paddingHorizontal } = chipSizes[size];
182
+ const bg = disabled ? theme.bg.disabled : checked ? theme.interactive.selected : "transparent";
183
+ const borderColor = disabled ? theme.border.disabled : checked ? theme.interactive.selected : theme.border.default;
184
+ const textColor = disabled ? theme.text.disabled : checked ? theme.text.inverse : theme.text.primary;
185
+ const baseText = size === "sm" ? typography.caption : typography.bodyDefault;
186
+ const textStyle = { ...baseText, fontWeight: checked ? "600" : baseText.fontWeight };
187
+ return /* @__PURE__ */ jsxs2(
188
+ Pressable4,
189
+ {
190
+ onPress: disabled ? void 0 : onPress,
191
+ disabled,
192
+ style: ({ pressed }) => [
193
+ styles4.base,
194
+ {
195
+ height,
196
+ paddingHorizontal,
197
+ borderRadius: chipRadius,
198
+ backgroundColor: bg,
199
+ borderColor,
200
+ borderWidth: borderWidth.default,
201
+ opacity: !disabled && pressed ? 1 - opacity.pressed : 1
202
+ },
203
+ style
204
+ ],
205
+ accessibilityRole: "button",
206
+ accessibilityState: { selected: checked, disabled },
207
+ children: [
208
+ leading,
209
+ /* @__PURE__ */ jsx5(Text2, { style: [textStyle, { color: textColor }], children }),
210
+ trailing
211
+ ]
212
+ }
213
+ );
214
+ }
215
+ var styles4 = StyleSheet4.create({
216
+ base: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 8, borderStyle: "solid" }
217
+ });
218
+
219
+ // src/components/Alert/Alert.native.tsx
220
+ import { Pressable as Pressable5, View as View2, Text as Text3, StyleSheet as StyleSheet5 } from "react-native";
221
+ import { Fragment, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
222
+ var glyph = { success: "\u2713", info: "i", warning: "!", error: "\u2715" };
223
+ function Alert({ variant = "info", size = "default", layout = "stacked", title, description, onDismiss }) {
224
+ const { theme } = useTheme();
225
+ const bg = { success: theme.bg.successSubtle, info: theme.bg.infoSubtle, warning: theme.bg.warningSubtle, error: theme.bg.errorSubtle }[variant];
226
+ const iconColor = { success: theme.icon.success, info: theme.icon.info, warning: theme.icon.warning, error: theme.icon.error }[variant];
227
+ const borderColor = theme.border.subtle;
228
+ const padding = size === "compact" ? 12 : 20;
229
+ const outerGap = size === "compact" ? 8 : 12;
230
+ const iconEl = /* @__PURE__ */ jsx6(View2, { style: [styles5.icon, { borderColor: iconColor }], children: /* @__PURE__ */ jsx6(Text3, { style: { color: iconColor, fontSize: 13, fontWeight: "700", lineHeight: 16 }, children: glyph[variant] }) });
231
+ const bodyEl = description ? /* @__PURE__ */ jsx6(Text3, { style: [typography.bodyDefault, { color: theme.text.secondary, flex: layout === "inline" ? 1 : void 0 }], children: description }) : null;
232
+ const closeEl = onDismiss ? /* @__PURE__ */ jsx6(Pressable5, { onPress: onDismiss, accessibilityRole: "button", accessibilityLabel: "Fechar", style: styles5.close, children: /* @__PURE__ */ jsx6(Text3, { style: { color: theme.text.primary, fontSize: 16, lineHeight: 20 }, children: "\u2715" }) }) : null;
233
+ return /* @__PURE__ */ jsxs3(
234
+ View2,
235
+ {
236
+ style: [styles5.container, { backgroundColor: bg, borderColor, padding, gap: outerGap }],
237
+ accessibilityRole: variant === "error" ? "alert" : void 0,
238
+ accessibilityLiveRegion: variant === "error" ? "assertive" : "polite",
239
+ children: [
240
+ layout === "inline" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
241
+ iconEl,
242
+ bodyEl
243
+ ] }) : /* @__PURE__ */ jsxs3(View2, { style: styles5.content, children: [
244
+ /* @__PURE__ */ jsxs3(View2, { style: styles5.header, children: [
245
+ iconEl,
246
+ title ? /* @__PURE__ */ jsx6(Text3, { style: [typography.h3, styles5.title, { color: theme.text.primary }], children: title }) : null
247
+ ] }),
248
+ bodyEl
249
+ ] }),
250
+ closeEl
251
+ ]
252
+ }
253
+ );
254
+ }
255
+ var styles5 = StyleSheet5.create({
256
+ container: {
257
+ width: "100%",
258
+ flexDirection: "row",
259
+ alignItems: "flex-start",
260
+ borderWidth: borderWidth.default,
261
+ borderStyle: "solid",
262
+ borderTopLeftRadius: 24,
263
+ borderTopRightRadius: 24,
264
+ borderBottomRightRadius: 24,
265
+ borderBottomLeftRadius: 0
266
+ },
267
+ content: { flex: 1, flexDirection: "column", gap: 8 },
268
+ header: { flexDirection: "row", alignItems: "center", gap: 12 },
269
+ title: { flex: 1 },
270
+ icon: { width: 24, height: 24, borderRadius: 12, borderWidth: 2, alignItems: "center", justifyContent: "center" },
271
+ close: {}
272
+ });
273
+
274
+ // src/components/ProgressBar/ProgressBar.native.tsx
275
+ import { View as View3, StyleSheet as StyleSheet6 } from "react-native";
276
+
277
+ // src/components/ProgressBar/ProgressBar.styles.ts
278
+ var progressBarTokens = {
279
+ height: 8,
280
+ borderRadius: radius.full,
281
+ fillBorderRadius: radius.full
282
+ };
283
+
284
+ // src/components/ProgressBar/ProgressBar.native.tsx
285
+ import { jsx as jsx7 } from "react/jsx-runtime";
286
+ function ProgressBar({ value }) {
287
+ const { theme } = useTheme();
288
+ const { height, borderRadius, fillBorderRadius } = progressBarTokens;
289
+ const pct = Math.min(100, Math.max(0, value));
290
+ const trackColor = theme.bg.surfaceHover;
291
+ return /* @__PURE__ */ jsx7(
292
+ View3,
293
+ {
294
+ style: [styles6.track, { height, borderRadius, backgroundColor: trackColor }],
295
+ accessibilityRole: "progressbar",
296
+ accessibilityValue: { min: 0, max: 100, now: pct },
297
+ children: /* @__PURE__ */ jsx7(View3, { style: { height, width: `${pct}%`, borderRadius: fillBorderRadius, backgroundColor: theme.bg.primary } })
298
+ }
299
+ );
300
+ }
301
+ var styles6 = StyleSheet6.create({
302
+ track: { width: "100%", overflow: "hidden" }
303
+ });
304
+
305
+ // src/components/Input/Input.native.tsx
306
+ import { useState } from "react";
307
+ import { View as View4, TextInput, StyleSheet as StyleSheet7 } from "react-native";
308
+
309
+ // src/components/Input/Input.styles.ts
310
+ var inputTokens = {
311
+ height: 48,
312
+ padding: 12,
313
+ gap: 8,
314
+ borderRadius: radius.input
315
+ };
316
+
317
+ // src/components/Input/Input.native.tsx
318
+ import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
319
+ function Input({ value, placeholder = "exemplo@email.com", state = "default", leadingIcon, trailingIcon, onChangeText, onFocus, onBlur, style }) {
320
+ const { theme } = useTheme();
321
+ const { height, padding, gap, borderRadius } = inputTokens;
322
+ const [isFocused, setIsFocused] = useState(false);
323
+ const isDisabled = state === "disabled";
324
+ const isError = state === "error";
325
+ const isFilled = state === "filled";
326
+ const bg = isDisabled ? theme.bg.disabled : theme.bg.surface;
327
+ const borderColor = isDisabled ? theme.border.disabled : isError ? theme.border.error : isFocused ? theme.border.focus : theme.border.default;
328
+ const inputBorderWidth = isFocused ? borderWidth.heavy : borderWidth.default;
329
+ const textColor = isDisabled ? theme.text.disabled : isError ? theme.text.error : isFilled || isFocused ? theme.text.primary : theme.text.secondary;
330
+ return /* @__PURE__ */ jsxs4(View4, { style: [styles7.container, { height, padding, gap, borderRadius, backgroundColor: bg, borderColor, borderWidth: inputBorderWidth }, style], children: [
331
+ leadingIcon,
332
+ /* @__PURE__ */ jsx8(
333
+ TextInput,
334
+ {
335
+ value,
336
+ placeholder,
337
+ placeholderTextColor: textColor,
338
+ editable: !isDisabled,
339
+ onChangeText,
340
+ onFocus: () => {
341
+ setIsFocused(true);
342
+ onFocus?.();
343
+ },
344
+ onBlur: () => {
345
+ setIsFocused(false);
346
+ onBlur?.();
347
+ },
348
+ style: [typography.bodyDefault, styles7.input, { color: textColor }]
349
+ }
350
+ ),
351
+ trailingIcon
352
+ ] });
353
+ }
354
+ var styles7 = StyleSheet7.create({
355
+ container: { flexDirection: "row", alignItems: "center", borderStyle: "solid" },
356
+ input: { flex: 1, padding: 0 }
357
+ });
358
+
359
+ // src/components/InputField/InputField.native.tsx
360
+ import { View as View5, Text as Text4 } from "react-native";
361
+ import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
362
+ function InputField({
363
+ label,
364
+ required,
365
+ helperText,
366
+ error,
367
+ value,
368
+ placeholder,
369
+ disabled,
370
+ leadingIcon,
371
+ trailingIcon,
372
+ onChangeText,
373
+ onFocus,
374
+ onBlur
375
+ }) {
376
+ const { theme } = useTheme();
377
+ const state = disabled ? "disabled" : error ? "error" : "default";
378
+ return /* @__PURE__ */ jsxs5(View5, { style: { gap: 8, width: "100%" }, children: [
379
+ label && /* @__PURE__ */ jsxs5(Text4, { style: [typography.labelDefault, { color: theme.text.primary }], children: [
380
+ label,
381
+ required && /* @__PURE__ */ jsx9(Text4, { style: { color: theme.text.error }, children: " *" })
382
+ ] }),
383
+ /* @__PURE__ */ jsx9(
384
+ Input,
385
+ {
386
+ state,
387
+ value,
388
+ placeholder,
389
+ leadingIcon,
390
+ trailingIcon,
391
+ onChangeText,
392
+ onFocus,
393
+ onBlur
394
+ }
395
+ ),
396
+ helperText && /* @__PURE__ */ jsx9(Text4, { style: [typography.caption, { color: error ? theme.text.error : theme.text.secondary }], children: helperText })
397
+ ] });
398
+ }
399
+
400
+ // src/components/Checkbox/Checkbox.native.tsx
401
+ import { Pressable as Pressable6, View as View6, StyleSheet as StyleSheet8 } from "react-native";
402
+
403
+ // src/components/Checkbox/Checkbox.styles.ts
404
+ var checkboxSizes = {
405
+ xs: { box: 16, radius: 4 },
406
+ sm: { box: 20, radius: 5 },
407
+ md: { box: 24, radius: 6 }
408
+ };
409
+
410
+ // src/components/Checkbox/Checkbox.native.tsx
411
+ import { jsx as jsx10 } from "react/jsx-runtime";
412
+ function Checkbox({ checked = false, onChange, disabled = false, size = "sm" }) {
413
+ const { theme } = useTheme();
414
+ const { box, radius: radius2 } = checkboxSizes[size];
415
+ const boxBg = checked ? disabled ? theme.bg.disabled : theme.interactive.selected : "transparent";
416
+ const boxBorder = checked ? boxBg : disabled ? theme.text.disabled : theme.icon.secondary;
417
+ const checkColor = disabled ? theme.text.disabled : colors.white;
418
+ return /* @__PURE__ */ jsx10(
419
+ Pressable6,
420
+ {
421
+ onPress: disabled ? void 0 : () => onChange?.(!checked),
422
+ disabled,
423
+ style: ({ pressed }) => [
424
+ styles8.wrapper,
425
+ // state layer: interactive/selected at ~12% (8-digit hex alpha).
426
+ { backgroundColor: !disabled && pressed ? `${theme.interactive.selected}1F` : "transparent" }
427
+ ],
428
+ accessibilityRole: "checkbox",
429
+ accessibilityState: { checked, disabled },
430
+ children: /* @__PURE__ */ jsx10(
431
+ View6,
432
+ {
433
+ style: [
434
+ styles8.box,
435
+ {
436
+ width: box,
437
+ height: box,
438
+ borderRadius: radius2,
439
+ backgroundColor: boxBg,
440
+ borderColor: boxBorder,
441
+ borderWidth: checked ? 0 : borderWidth.heavy
442
+ }
443
+ ],
444
+ children: checked && /* @__PURE__ */ jsx10(
445
+ View6,
446
+ {
447
+ style: {
448
+ width: box * 0.5,
449
+ height: box * 0.4,
450
+ borderLeftWidth: 1.5,
451
+ borderBottomWidth: 1.5,
452
+ borderColor: checkColor,
453
+ transform: [{ rotate: "-45deg" }, { translateY: -box * 0.1 }]
454
+ }
455
+ }
456
+ )
457
+ }
458
+ )
459
+ }
460
+ );
461
+ }
462
+ var styles8 = StyleSheet8.create({
463
+ wrapper: { padding: 4, borderRadius: 9999, alignItems: "center", justifyContent: "center" },
464
+ box: { alignItems: "center", justifyContent: "center" }
465
+ });
466
+
467
+ // src/components/ToggleSwitch/ToggleSwitch.native.tsx
468
+ import { useEffect, useRef } from "react";
469
+ import { Pressable as Pressable7, Animated } from "react-native";
470
+ import { jsx as jsx11 } from "react/jsx-runtime";
471
+ var sizes = {
472
+ xs: { w: 32, h: 20, knob: 16 },
473
+ sm: { w: 40, h: 24, knob: 20 },
474
+ md: { w: 52, h: 32, knob: 28 }
475
+ };
476
+ function ToggleSwitch({ value = false, onChange, disabled = false, size = "sm", accessibilityLabel }) {
477
+ const { theme } = useTheme();
478
+ const { w, h, knob } = sizes[size];
479
+ const travel = w - knob - 4;
480
+ const anim = useRef(new Animated.Value(value ? 1 : 0)).current;
481
+ useEffect(() => {
482
+ Animated.timing(anim, { toValue: value ? 1 : 0, duration: 150, useNativeDriver: true }).start();
483
+ }, [value, anim]);
484
+ const translateX = anim.interpolate({ inputRange: [0, 1], outputRange: [0, travel] });
485
+ const trackColor = disabled ? theme.bg.disabled : value ? theme.interactive.selected : theme.bg.disabled;
486
+ const knobColor = disabled ? theme.text.disabled : theme.text.inverse;
487
+ return /* @__PURE__ */ jsx11(
488
+ Pressable7,
489
+ {
490
+ onPress: disabled ? void 0 : () => onChange?.(!value),
491
+ disabled,
492
+ style: { width: w, height: h, borderRadius: radius.full, backgroundColor: trackColor, padding: 2, justifyContent: "center" },
493
+ accessibilityRole: "switch",
494
+ accessibilityState: { checked: value, disabled },
495
+ accessibilityLabel,
496
+ children: /* @__PURE__ */ jsx11(
497
+ Animated.View,
498
+ {
499
+ style: { width: knob, height: knob, borderRadius: radius.full, backgroundColor: knobColor, transform: [{ translateX }] }
500
+ }
501
+ )
502
+ }
503
+ );
504
+ }
505
+
506
+ // src/components/RadioGroup/RadioGroup.native.tsx
507
+ import { View as View7 } from "react-native";
508
+ import { jsx as jsx12 } from "react/jsx-runtime";
509
+ function RadioGroup({ children, label, style }) {
510
+ return /* @__PURE__ */ jsx12(View7, { accessibilityRole: "radiogroup", accessibilityLabel: label, style: [{ gap: 8 }, style], children });
511
+ }
512
+
513
+ // src/components/ChoiceCard/ChoiceCard.native.tsx
514
+ import { Pressable as Pressable8, View as View8, Text as Text5, StyleSheet as StyleSheet9 } from "react-native";
515
+ import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
516
+ function Trailing({ type, selected, disabled }) {
517
+ const { theme } = useTheme();
518
+ const offColor = disabled ? theme.text.disabled : theme.icon.secondary;
519
+ const onColor = theme.interactive.selected;
520
+ if (type === "action") {
521
+ return /* @__PURE__ */ jsx13(View8, { style: [styles9.caret, { borderColor: disabled ? theme.text.disabled : theme.icon.secondary }] });
522
+ }
523
+ if (type === "checkbox") {
524
+ return /* @__PURE__ */ jsx13(View8, { style: [styles9.indicator, styles9.checkbox, { borderColor: selected ? onColor : offColor, backgroundColor: selected ? onColor : "transparent" }], children: selected && /* @__PURE__ */ jsx13(View8, { style: [styles9.check, { borderColor: colors.white }] }) });
525
+ }
526
+ return /* @__PURE__ */ jsx13(View8, { style: [styles9.indicator, styles9.radio, { borderColor: selected ? onColor : offColor }], children: selected && /* @__PURE__ */ jsx13(View8, { style: [styles9.dot, { backgroundColor: onColor }] }) });
527
+ }
528
+ function ChoiceCard({ type = "radio", label, description, selected = false, disabled = false, leading, showTrailing = true, onPress }) {
529
+ const { theme } = useTheme();
530
+ const isSelected = type === "action" ? false : selected;
531
+ const baseBg = disabled ? theme.bg.surface : isSelected ? theme.bg.primarySubtle : theme.bg.surface;
532
+ const pressedBg = isSelected ? theme.bg.primarySubtlePressed : theme.bg.surfacePressed;
533
+ const borderColor = disabled ? theme.border.disabled : isSelected ? theme.border.strong : theme.border.default;
534
+ const textColor = disabled ? theme.text.disabled : theme.text.primary;
535
+ const descColor = disabled ? theme.text.disabled : theme.text.secondary;
536
+ return /* @__PURE__ */ jsxs6(
537
+ Pressable8,
538
+ {
539
+ onPress: disabled ? void 0 : onPress,
540
+ disabled,
541
+ accessibilityRole: type === "radio" ? "radio" : type === "checkbox" ? "checkbox" : "button",
542
+ accessibilityState: { selected: isSelected, checked: isSelected, disabled },
543
+ style: ({ pressed }) => [
544
+ styles9.card,
545
+ {
546
+ backgroundColor: !disabled && pressed ? pressedBg : baseBg,
547
+ borderColor,
548
+ borderWidth: isSelected ? borderWidth.heavy : borderWidth.default
549
+ }
550
+ ],
551
+ children: [
552
+ leading && /* @__PURE__ */ jsx13(View8, { style: styles9.leading, children: leading }),
553
+ /* @__PURE__ */ jsxs6(View8, { style: styles9.text, children: [
554
+ /* @__PURE__ */ jsx13(Text5, { style: [description ? typography.labelDefault : typography.bodyDefault, { color: textColor }], children: label }),
555
+ description ? /* @__PURE__ */ jsx13(Text5, { style: [typography.bodyDefault, { color: descColor }], children: description }) : null
556
+ ] }),
557
+ showTrailing && /* @__PURE__ */ jsx13(Trailing, { type, selected: isSelected, disabled })
558
+ ]
559
+ }
560
+ );
561
+ }
562
+ var styles9 = StyleSheet9.create({
563
+ card: { width: "100%", flexDirection: "row", alignItems: "center", gap: 12, padding: 16, borderRadius: 20, borderStyle: "solid" },
564
+ leading: { width: 24, height: 24, alignItems: "center", justifyContent: "center" },
565
+ text: { flex: 1, flexDirection: "column", gap: 4 },
566
+ indicator: { width: 24, height: 24, alignItems: "center", justifyContent: "center", borderWidth: 2 },
567
+ checkbox: { borderRadius: 6 },
568
+ radio: { borderRadius: 12 },
569
+ dot: { width: 12, height: 12, borderRadius: 6 },
570
+ check: { width: 12, height: 8, borderLeftWidth: 2, borderBottomWidth: 2, transform: [{ rotate: "-45deg" }, { translateY: -1 }] },
571
+ caret: { width: 10, height: 10, borderTopWidth: 2, borderRightWidth: 2, transform: [{ rotate: "45deg" }] }
572
+ });
573
+
574
+ // src/components/ListItem/ListItem.native.tsx
575
+ import { Pressable as Pressable9, View as View9, Text as Text6, StyleSheet as StyleSheet10 } from "react-native";
576
+ import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
577
+ function TrailingVisual({ trailing, selected, disabled }) {
578
+ const { theme } = useTheme();
579
+ const offColor = disabled ? theme.text.disabled : theme.icon.secondary;
580
+ const onColor = theme.interactive.selected;
581
+ if (trailing === "action") {
582
+ return /* @__PURE__ */ jsx14(View9, { style: [styles10.caret, { borderColor: disabled ? theme.text.disabled : theme.icon.secondary }] });
583
+ }
584
+ if (trailing === "checkbox") {
585
+ return /* @__PURE__ */ jsx14(View9, { style: [styles10.indicator, styles10.checkbox, { borderColor: selected ? onColor : offColor, backgroundColor: selected ? onColor : "transparent" }], children: selected && /* @__PURE__ */ jsx14(View9, { style: [styles10.check, { borderColor: colors.white }] }) });
586
+ }
587
+ return /* @__PURE__ */ jsx14(View9, { style: [styles10.indicator, styles10.radio, { borderColor: selected ? onColor : offColor }], children: selected && /* @__PURE__ */ jsx14(View9, { style: [styles10.dot, { backgroundColor: onColor }] }) });
588
+ }
589
+ function ListItem({ trailing = "none", label, description, selected = false, disabled = false, leading, switchValue = false, onSwitchChange, onPress }) {
590
+ const { theme } = useTheme();
591
+ const isSelected = trailing === "radio" || trailing === "checkbox" ? selected : false;
592
+ const textColor = disabled ? theme.text.disabled : theme.text.primary;
593
+ const descColor = disabled ? theme.text.disabled : theme.text.secondary;
594
+ const selectedBg = theme.bg.primarySubtle;
595
+ const selectedPressedBg = theme.bg.primarySubtlePressed;
596
+ const neutralPressedBg = theme.bg.surfacePressed;
597
+ const rowStyle = (pressed) => [
598
+ styles10.row,
599
+ { padding: description ? 16 : 10 },
600
+ isSelected ? { backgroundColor: !disabled && pressed ? selectedPressedBg : selectedBg } : { backgroundColor: !disabled && pressed ? neutralPressedBg : "transparent" }
601
+ ];
602
+ const content = /* @__PURE__ */ jsxs7(Fragment2, { children: [
603
+ leading && /* @__PURE__ */ jsx14(View9, { style: styles10.leading, children: leading }),
604
+ /* @__PURE__ */ jsxs7(View9, { style: styles10.text, children: [
605
+ /* @__PURE__ */ jsx14(Text6, { style: [description ? typography.labelDefault : typography.bodyDefault, { color: textColor }], children: label }),
606
+ description ? /* @__PURE__ */ jsx14(Text6, { style: [typography.bodyDefault, { color: descColor }], children: description }) : null
607
+ ] }),
608
+ trailing === "switch" ? /* @__PURE__ */ jsx14(ToggleSwitch, { size: "sm", value: switchValue, onChange: onSwitchChange, disabled, accessibilityLabel: label }) : trailing !== "none" ? /* @__PURE__ */ jsx14(TrailingVisual, { trailing, selected: isSelected, disabled }) : null
609
+ ] });
610
+ if (trailing === "switch" || trailing === "none") {
611
+ return /* @__PURE__ */ jsx14(View9, { style: rowStyle(false), children: content });
612
+ }
613
+ return /* @__PURE__ */ jsx14(
614
+ Pressable9,
615
+ {
616
+ onPress: disabled ? void 0 : onPress,
617
+ disabled,
618
+ accessibilityRole: trailing === "radio" ? "radio" : trailing === "checkbox" ? "checkbox" : "button",
619
+ accessibilityState: { selected: isSelected, checked: isSelected, disabled },
620
+ style: ({ pressed }) => rowStyle(pressed),
621
+ children: content
622
+ }
623
+ );
624
+ }
625
+ var styles10 = StyleSheet10.create({
626
+ row: { width: "100%", flexDirection: "row", alignItems: "center", gap: 12 },
627
+ leading: { width: 24, height: 24, alignItems: "center", justifyContent: "center" },
628
+ text: { flex: 1, flexDirection: "column", gap: 4 },
629
+ indicator: { width: 24, height: 24, alignItems: "center", justifyContent: "center", borderWidth: 2 },
630
+ checkbox: { borderRadius: 6 },
631
+ radio: { borderRadius: 12 },
632
+ dot: { width: 12, height: 12, borderRadius: 6 },
633
+ check: { width: 12, height: 8, borderLeftWidth: 2, borderBottomWidth: 2, transform: [{ rotate: "-45deg" }, { translateY: -1 }] },
634
+ caret: { width: 10, height: 10, borderTopWidth: 2, borderRightWidth: 2, transform: [{ rotate: "45deg" }] }
635
+ });
636
+
637
+ // src/components/Stepper/Stepper.native.tsx
638
+ import { View as View10 } from "react-native";
639
+
640
+ // src/components/Stepper/Stepper.styles.ts
641
+ var stepperTokens = {
642
+ segmentHeight: 4,
643
+ segmentRadius: radius.full,
644
+ gap: 4
645
+ };
646
+
647
+ // src/components/Stepper/Stepper.native.tsx
648
+ import { jsx as jsx15 } from "react/jsx-runtime";
649
+ function Stepper({ totalSteps, currentStep, style }) {
650
+ const { theme } = useTheme();
651
+ const { segmentHeight, segmentRadius, gap } = stepperTokens;
652
+ return /* @__PURE__ */ jsx15(
653
+ View10,
654
+ {
655
+ style: [{ flexDirection: "row", alignItems: "flex-start", width: "100%", gap }, style],
656
+ accessibilityRole: "progressbar",
657
+ accessibilityValue: { min: 1, max: totalSteps, now: currentStep },
658
+ accessibilityLabel: `Etapa ${currentStep} de ${totalSteps}`,
659
+ children: Array.from({ length: totalSteps }, (_, i) => {
660
+ const color = i < currentStep - 1 ? theme.bg.primary : i === currentStep - 1 ? theme.bg.primarySubtle : theme.bg.disabled;
661
+ return /* @__PURE__ */ jsx15(View10, { style: { flex: 1, height: segmentHeight, borderRadius: segmentRadius, backgroundColor: color } }, i);
662
+ })
663
+ }
664
+ );
665
+ }
666
+
667
+ // src/components/RatingScale/RatingScale.native.tsx
668
+ import { Pressable as Pressable10, View as View11, Text as Text7, StyleSheet as StyleSheet11 } from "react-native";
669
+ import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
670
+ function RatingScale({ value = null, onChange, options = DEFAULT_OPTIONS, disabled = false, style }) {
671
+ const { theme } = useTheme();
672
+ const { circleSize, circleRadius, emojiFontSize, emojiLineHeight, itemGap } = ratingScaleTokens;
673
+ return /* @__PURE__ */ jsx16(View11, { style: [styles11.container, style], children: options.map((option, index) => {
674
+ const itemValue = index + 1;
675
+ const selected = value === itemValue;
676
+ const circleBg = disabled ? theme.bg.disabled : selected ? theme.bg.primarySubtle : theme.bg.surface;
677
+ const circleBorderColor = disabled ? theme.border.disabled : selected ? theme.border.strong : theme.border.default;
678
+ const labelColor = disabled ? theme.text.disabled : theme.text.primary;
679
+ return /* @__PURE__ */ jsxs8(
680
+ Pressable10,
681
+ {
682
+ onPress: disabled ? void 0 : () => onChange?.(itemValue),
683
+ disabled,
684
+ style: [styles11.item, { gap: itemGap }],
685
+ accessibilityRole: "radio",
686
+ accessibilityState: { selected, disabled },
687
+ children: [
688
+ /* @__PURE__ */ jsx16(
689
+ View11,
690
+ {
691
+ style: [
692
+ styles11.circle,
693
+ {
694
+ width: circleSize,
695
+ height: circleSize,
696
+ borderRadius: circleRadius,
697
+ backgroundColor: circleBg,
698
+ borderWidth: selected ? borderWidth.heavy : borderWidth.default,
699
+ borderColor: circleBorderColor
700
+ }
701
+ ],
702
+ children: /* @__PURE__ */ jsx16(Text7, { style: [styles11.emoji, { fontSize: emojiFontSize, lineHeight: emojiLineHeight, opacity: disabled ? 0.4 : 1 }], children: option.emoji })
703
+ }
704
+ ),
705
+ /* @__PURE__ */ jsx16(Text7, { style: [typography.caption, styles11.label, { color: labelColor }], children: option.label }),
706
+ /* @__PURE__ */ jsx16(Text7, { style: [styles11.number, { color: theme.text.disabled }], children: itemValue })
707
+ ]
708
+ },
709
+ itemValue
710
+ );
711
+ }) });
712
+ }
713
+ var styles11 = StyleSheet11.create({
714
+ container: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 8, padding: 16 },
715
+ item: { flex: 1, alignItems: "center" },
716
+ circle: { alignItems: "center", justifyContent: "center", overflow: "hidden" },
717
+ emoji: { textAlign: "center" },
718
+ label: { textAlign: "center" },
719
+ number: { textAlign: "center", fontFamily: "Inter", fontSize: 10, fontWeight: "600", letterSpacing: 0.8 }
720
+ });
8
721
  export {
722
+ Alert,
723
+ Button,
724
+ ButtonIcon,
725
+ Checkbox,
726
+ Chip,
727
+ ChoiceCard,
728
+ DSThemeProvider,
729
+ DismissButton,
730
+ Input,
731
+ InputField,
732
+ ListItem,
733
+ ProgressBar,
734
+ RadioGroup,
735
+ RatingScale,
736
+ Stepper,
737
+ ToggleSwitch,
738
+ borderWidth,
9
739
  colors,
10
740
  darkTheme,
11
- lightTheme
741
+ grid,
742
+ lightTheme,
743
+ opacity,
744
+ radius,
745
+ shadow,
746
+ spacing,
747
+ typography,
748
+ useTheme
12
749
  };
13
750
  //# sourceMappingURL=index.native.mjs.map