@12min/ds 1.0.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.
@@ -3,11 +3,17 @@ import {
3
3
  darkTheme,
4
4
  lightTheme,
5
5
  ratingScaleTokens
6
- } from "./chunk-CC3QVZS2.mjs";
6
+ } from "./chunk-ZKPOS2PD.mjs";
7
7
  import {
8
+ borderWidth,
8
9
  colors,
10
+ grid,
11
+ opacity,
12
+ radius,
13
+ shadow,
14
+ spacing,
9
15
  typography
10
- } from "./chunk-NK4IHR7O.mjs";
16
+ } from "./chunk-ZK7NW4WW.mjs";
11
17
 
12
18
  // src/context/ThemeProvider.tsx
13
19
  import { createContext, useContext, useMemo } from "react";
@@ -33,25 +39,32 @@ import { Pressable, Text, StyleSheet } from "react-native";
33
39
  // src/components/Button/Button.styles.ts
34
40
  var buttonTokens = {
35
41
  sizes: {
36
- sm: { height: 36, paddingHorizontal: 14, fontSize: 14 },
37
- md: { height: 48, paddingHorizontal: 16, fontSize: 16 },
38
- lg: { height: 56, paddingHorizontal: 24, fontSize: 18 }
42
+ sm: { height: 32, paddingHorizontal: 12 },
43
+ md: { height: 40, paddingHorizontal: 16 },
44
+ lg: { height: 48, paddingHorizontal: 24 }
39
45
  },
40
- borderRadius: 9999
46
+ borderRadius: radius.full
41
47
  };
42
48
 
43
49
  // src/components/Button/Button.native.tsx
44
50
  import { jsx as jsx2 } from "react/jsx-runtime";
45
- function Button({ variant = "primary", size = "md", disabled = false, children, onPress }) {
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 }) {
46
57
  const { theme } = useTheme();
47
- const { sizes, borderRadius } = buttonTokens;
48
- const sizeStyle = sizes[size];
49
- const bgColor = disabled ? theme.surfaceDisabled : variant === "primary" ? theme.primary : variant === "secondary" ? theme.surface : "transparent";
50
- const textColor = variant === "primary" ? theme.textInverse : variant === "secondary" ? theme.onBackground : theme.primary;
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;
51
63
  return /* @__PURE__ */ jsx2(
52
64
  Pressable,
53
65
  {
54
66
  onPress: disabled ? void 0 : onPress,
67
+ disabled,
55
68
  style: ({ pressed }) => [
56
69
  styles.base,
57
70
  {
@@ -59,146 +72,264 @@ function Button({ variant = "primary", size = "md", disabled = false, children,
59
72
  paddingHorizontal: sizeStyle.paddingHorizontal,
60
73
  borderRadius,
61
74
  backgroundColor: bgColor,
62
- opacity: disabled ? 0.5 : pressed ? 0.85 : 1
75
+ opacity: !disabled && pressed ? 1 - opacity.pressed : 1
63
76
  }
64
77
  ],
65
78
  accessibilityRole: "button",
66
79
  accessibilityState: { disabled },
67
- children: /* @__PURE__ */ jsx2(Text, { style: [styles.label, { fontSize: sizeStyle.fontSize, color: textColor }], children })
80
+ children: /* @__PURE__ */ jsx2(Text, { style: [textStyle, { color: textColor }], children })
68
81
  }
69
82
  );
70
83
  }
71
84
  var styles = StyleSheet.create({
72
- base: { flexDirection: "row", alignItems: "center", justifyContent: "center" },
73
- label: { fontWeight: "600" }
85
+ base: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 8 }
74
86
  });
75
87
 
76
- // src/components/Chip/Chip.native.tsx
77
- import { Pressable as Pressable2, Text as Text2, StyleSheet as StyleSheet2 } from "react-native";
78
-
79
- // src/components/Chip/Chip.styles.ts
80
- var chipTokens = {
81
- size: { height: 48, paddingHorizontal: 16, fontSize: 14 },
82
- borderRadius: 56
83
- };
84
-
85
- // src/components/Chip/Chip.native.tsx
88
+ // src/components/ButtonIcon/ButtonIcon.native.tsx
89
+ import { Pressable as Pressable2, StyleSheet as StyleSheet2 } from "react-native";
86
90
  import { jsx as jsx3 } from "react/jsx-runtime";
87
- function Chip({ children, checked = false, onPress, style }) {
88
- const { theme } = useTheme();
89
- const { size, borderRadius } = chipTokens;
90
- const bg = checked ? theme.primary : theme.surface;
91
- const textColor = checked ? theme.textInverse : theme.onBackground;
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";
92
100
  return /* @__PURE__ */ jsx3(
93
101
  Pressable2,
94
102
  {
95
- onPress,
103
+ onPress: disabled ? void 0 : onPress,
104
+ disabled,
96
105
  style: ({ pressed }) => [
97
106
  styles2.base,
98
- { height: size.height, paddingHorizontal: size.paddingHorizontal, borderRadius, backgroundColor: bg, opacity: pressed ? 0.85 : 1 },
99
- style
107
+ {
108
+ width: dimension,
109
+ height: dimension,
110
+ borderRadius: radius.full,
111
+ backgroundColor: bgColor,
112
+ opacity: !disabled && pressed ? 1 - opacity.pressed : 1
113
+ }
100
114
  ],
101
115
  accessibilityRole: "button",
102
- children: /* @__PURE__ */ jsx3(Text2, { style: { fontSize: size.fontSize, color: textColor, fontWeight: checked ? "600" : "500" }, children })
116
+ accessibilityLabel,
117
+ accessibilityState: { disabled },
118
+ children: icon
103
119
  }
104
120
  );
105
121
  }
106
122
  var styles2 = StyleSheet2.create({
107
- base: { flexDirection: "row", alignItems: "center", justifyContent: "center" }
123
+ base: { alignItems: "center", justifyContent: "center" }
108
124
  });
109
125
 
110
- // src/components/Alert/Alert.native.tsx
111
- import { View, Text as Text3, StyleSheet as StyleSheet3 } from "react-native";
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";
112
169
 
113
- // src/components/Alert/Alert.styles.ts
114
- var alertTokens = {
115
- padding: 20,
116
- borderRadius: 32
170
+ // src/components/Chip/Chip.styles.ts
171
+ var chipSizes = {
172
+ sm: { height: 32, paddingHorizontal: 12 },
173
+ md: { height: 44, paddingHorizontal: 16 }
117
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
+ });
118
218
 
119
219
  // src/components/Alert/Alert.native.tsx
120
- import { jsx as jsx4, jsxs } from "react/jsx-runtime";
121
- function Alert({ variant = "info", title, description }) {
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 }) {
122
224
  const { theme } = useTheme();
123
- const { padding, borderRadius } = alertTokens;
124
- const bg = variant === "success" ? theme.successBg : theme.surface;
125
- return /* @__PURE__ */ jsxs(View, { style: [styles3.container, { backgroundColor: bg, padding, borderColor: theme.border }], children: [
126
- /* @__PURE__ */ jsx4(Text3, { style: [styles3.title, { color: theme.onBackground }], children: title }),
127
- description && /* @__PURE__ */ jsx4(Text3, { style: [styles3.description, { color: theme.muted }], children: description })
128
- ] });
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
+ );
129
254
  }
130
- var styles3 = StyleSheet3.create({
255
+ var styles5 = StyleSheet5.create({
131
256
  container: {
132
257
  width: "100%",
133
- borderWidth: 1,
134
- borderTopLeftRadius: 32,
135
- borderTopRightRadius: 32,
136
- borderBottomRightRadius: 32,
258
+ flexDirection: "row",
259
+ alignItems: "flex-start",
260
+ borderWidth: borderWidth.default,
261
+ borderStyle: "solid",
262
+ borderTopLeftRadius: 24,
263
+ borderTopRightRadius: 24,
264
+ borderBottomRightRadius: 24,
137
265
  borderBottomLeftRadius: 0
138
266
  },
139
- title: { fontWeight: "600", fontSize: 16, lineHeight: 22 },
140
- description: { fontWeight: "500", fontSize: 14, lineHeight: 21, marginTop: 12 }
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: {}
141
272
  });
142
273
 
143
274
  // src/components/ProgressBar/ProgressBar.native.tsx
144
- import { View as View2, StyleSheet as StyleSheet4 } from "react-native";
275
+ import { View as View3, StyleSheet as StyleSheet6 } from "react-native";
145
276
 
146
277
  // src/components/ProgressBar/ProgressBar.styles.ts
147
278
  var progressBarTokens = {
148
279
  height: 8,
149
- borderRadius: 999,
150
- fillBorderRadius: 24
280
+ borderRadius: radius.full,
281
+ fillBorderRadius: radius.full
151
282
  };
152
283
 
153
284
  // src/components/ProgressBar/ProgressBar.native.tsx
154
- import { jsx as jsx5 } from "react/jsx-runtime";
285
+ import { jsx as jsx7 } from "react/jsx-runtime";
155
286
  function ProgressBar({ value }) {
156
287
  const { theme } = useTheme();
157
288
  const { height, borderRadius, fillBorderRadius } = progressBarTokens;
158
289
  const pct = Math.min(100, Math.max(0, value));
159
- return /* @__PURE__ */ jsx5(
160
- View2,
290
+ const trackColor = theme.bg.surfaceHover;
291
+ return /* @__PURE__ */ jsx7(
292
+ View3,
161
293
  {
162
- style: [styles4.track, { height, borderRadius, backgroundColor: theme.border }],
294
+ style: [styles6.track, { height, borderRadius, backgroundColor: trackColor }],
163
295
  accessibilityRole: "progressbar",
164
296
  accessibilityValue: { min: 0, max: 100, now: pct },
165
- children: /* @__PURE__ */ jsx5(View2, { style: { height, width: `${pct}%`, borderRadius: fillBorderRadius, backgroundColor: theme.primary } })
297
+ children: /* @__PURE__ */ jsx7(View3, { style: { height, width: `${pct}%`, borderRadius: fillBorderRadius, backgroundColor: theme.bg.primary } })
166
298
  }
167
299
  );
168
300
  }
169
- var styles4 = StyleSheet4.create({
301
+ var styles6 = StyleSheet6.create({
170
302
  track: { width: "100%", overflow: "hidden" }
171
303
  });
172
304
 
173
305
  // src/components/Input/Input.native.tsx
174
306
  import { useState } from "react";
175
- import { View as View3, TextInput, StyleSheet as StyleSheet5 } from "react-native";
307
+ import { View as View4, TextInput, StyleSheet as StyleSheet7 } from "react-native";
176
308
 
177
309
  // src/components/Input/Input.styles.ts
178
310
  var inputTokens = {
179
311
  height: 48,
180
312
  padding: 12,
181
313
  gap: 8,
182
- borderRadius: 12,
183
- fontSize: 14
314
+ borderRadius: radius.input
184
315
  };
185
316
 
186
317
  // src/components/Input/Input.native.tsx
187
- import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
188
- function Input({ value, placeholder = "exemplo@email.com", state = "default", leadingIcon, onChangeText, onFocus, onBlur, style }) {
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 }) {
189
320
  const { theme } = useTheme();
190
- const { height, padding, gap, borderRadius, fontSize } = inputTokens;
321
+ const { height, padding, gap, borderRadius } = inputTokens;
191
322
  const [isFocused, setIsFocused] = useState(false);
192
323
  const isDisabled = state === "disabled";
193
324
  const isError = state === "error";
194
325
  const isFilled = state === "filled";
195
- const bg = isDisabled ? theme.background : theme.surface;
196
- const borderColor = isDisabled ? theme.muted : isError ? theme.error : isFocused ? theme.primary : theme.border;
197
- const borderWidth = isFocused ? 2 : 1;
198
- const textColor = isDisabled ? theme.muted : isError ? theme.error : isFilled || isFocused ? theme.onBackground : theme.muted;
199
- return /* @__PURE__ */ jsxs2(View3, { style: [styles5.container, { height, padding, gap, borderRadius, backgroundColor: bg, borderColor, borderWidth }, style], children: [
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: [
200
331
  leadingIcon,
201
- /* @__PURE__ */ jsx6(
332
+ /* @__PURE__ */ jsx8(
202
333
  TextInput,
203
334
  {
204
335
  value,
@@ -214,322 +345,405 @@ function Input({ value, placeholder = "exemplo@email.com", state = "default", le
214
345
  setIsFocused(false);
215
346
  onBlur?.();
216
347
  },
217
- style: [styles5.input, { fontSize, color: textColor }]
348
+ style: [typography.bodyDefault, styles7.input, { color: textColor }]
218
349
  }
219
- )
350
+ ),
351
+ trailingIcon
220
352
  ] });
221
353
  }
222
- var styles5 = StyleSheet5.create({
354
+ var styles7 = StyleSheet7.create({
223
355
  container: { flexDirection: "row", alignItems: "center", borderStyle: "solid" },
224
- input: { flex: 1, fontWeight: "500", padding: 0 }
356
+ input: { flex: 1, padding: 0 }
225
357
  });
226
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
+
227
400
  // src/components/Checkbox/Checkbox.native.tsx
228
- import { Pressable as Pressable3, View as View4, StyleSheet as StyleSheet6 } from "react-native";
401
+ import { Pressable as Pressable6, View as View6, StyleSheet as StyleSheet8 } from "react-native";
229
402
 
230
403
  // src/components/Checkbox/Checkbox.styles.ts
231
- var checkboxTokens = {
232
- size: 20,
233
- borderRadius: 6
404
+ var checkboxSizes = {
405
+ xs: { box: 16, radius: 4 },
406
+ sm: { box: 20, radius: 5 },
407
+ md: { box: 24, radius: 6 }
234
408
  };
235
409
 
236
410
  // src/components/Checkbox/Checkbox.native.tsx
237
- import { jsx as jsx7 } from "react/jsx-runtime";
238
- function Checkbox({ checked = false, onChange, disabled = false }) {
411
+ import { jsx as jsx10 } from "react/jsx-runtime";
412
+ function Checkbox({ checked = false, onChange, disabled = false, size = "sm" }) {
239
413
  const { theme } = useTheme();
240
- const { size, borderRadius } = checkboxTokens;
241
- return /* @__PURE__ */ jsx7(
242
- Pressable3,
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,
243
420
  {
244
421
  onPress: disabled ? void 0 : () => onChange?.(!checked),
422
+ disabled,
245
423
  style: ({ pressed }) => [
246
- styles6.base,
247
- {
248
- width: size,
249
- height: size,
250
- borderRadius,
251
- backgroundColor: checked ? theme.primary : "transparent",
252
- borderWidth: checked ? 0 : 1,
253
- borderColor: theme.primary,
254
- opacity: disabled ? 0.5 : pressed ? 0.85 : 1
255
- }
424
+ styles8.wrapper,
425
+ // state layer: interactive/selected at ~12% (8-digit hex alpha).
426
+ { backgroundColor: !disabled && pressed ? `${theme.interactive.selected}1F` : "transparent" }
256
427
  ],
257
428
  accessibilityRole: "checkbox",
258
429
  accessibilityState: { checked, disabled },
259
- children: checked && /* @__PURE__ */ jsx7(View4, { style: styles6.checkmark, children: /* @__PURE__ */ jsx7(View4, { style: [styles6.checkLine, { borderColor: theme.textInverse }] }) })
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
+ )
260
459
  }
261
460
  );
262
461
  }
263
- var styles6 = StyleSheet6.create({
264
- base: { alignItems: "center", justifyContent: "center" },
265
- checkmark: { width: 10, height: 8, alignItems: "center", justifyContent: "center" },
266
- checkLine: { width: 10, height: 8, borderLeftWidth: 1.5, borderBottomWidth: 1.5, transform: [{ rotate: "-45deg" }, { translateY: -2 }] }
462
+ var styles8 = StyleSheet8.create({
463
+ wrapper: { padding: 4, borderRadius: 9999, alignItems: "center", justifyContent: "center" },
464
+ box: { alignItems: "center", justifyContent: "center" }
267
465
  });
268
466
 
269
- // src/components/RadioItem/RadioItem.native.tsx
270
- import { Pressable as Pressable4, View as View5, Text as Text4, StyleSheet as StyleSheet7 } from "react-native";
271
-
272
- // src/components/RadioItem/RadioItem.styles.ts
273
- var radioItemTokens = {
274
- height: 48,
275
- padding: 16,
276
- gap: 12,
277
- borderRadius: 16,
278
- radioSize: 20,
279
- fontSize: 14
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 }
280
475
  };
281
-
282
- // src/components/RadioItem/RadioItem.native.tsx
283
- import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
284
- function RadioItem({ label, description, selected = false, icon, onPress, style }) {
476
+ function ToggleSwitch({ value = false, onChange, disabled = false, size = "sm", accessibilityLabel }) {
285
477
  const { theme } = useTheme();
286
- const { height, padding, gap, borderRadius, radioSize, fontSize } = radioItemTokens;
287
- const bg = selected ? theme.primary : theme.surface;
288
- const textColor = selected ? theme.textInverse : theme.onBackground;
289
- const descColor = selected ? theme.textInverse : theme.textSecondary;
290
- const descOpacity = selected ? 0.8 : 1;
291
- const radioBorderColor = selected ? theme.textInverse : theme.onBackground;
292
- return /* @__PURE__ */ jsxs3(
293
- Pressable4,
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,
294
489
  {
295
- onPress,
296
- style: ({ pressed }) => [
297
- styles7.container,
298
- { height, paddingHorizontal: padding, gap, borderRadius, backgroundColor: bg, opacity: pressed ? 0.9 : 1 },
299
- style
300
- ],
301
- accessibilityRole: "radio",
302
- accessibilityState: { selected },
303
- children: [
304
- /* @__PURE__ */ jsxs3(View5, { style: styles7.left, children: [
305
- icon && /* @__PURE__ */ jsx8(View5, { style: styles7.icon, children: icon }),
306
- /* @__PURE__ */ jsxs3(View5, { style: styles7.textContainer, children: [
307
- /* @__PURE__ */ jsx8(Text4, { style: [styles7.label, { fontSize, color: textColor, fontWeight: selected ? "700" : "500" }], children: label }),
308
- description && /* @__PURE__ */ jsx8(Text4, { style: [styles7.description, { color: descColor, opacity: descOpacity }], children: description })
309
- ] })
310
- ] }),
311
- /* @__PURE__ */ jsx8(View5, { style: [styles7.radio, { width: radioSize, height: radioSize, borderRadius: radioSize / 2, borderColor: radioBorderColor }] })
312
- ]
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
+ )
313
502
  }
314
503
  );
315
504
  }
316
- var styles7 = StyleSheet7.create({
317
- container: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" },
318
- left: { flexDirection: "row", alignItems: "center", gap: 12 },
319
- icon: { width: 20, height: 20 },
320
- textContainer: { flexDirection: "column", gap: 2 },
321
- label: { lineHeight: 21 },
322
- description: { fontSize: 12, fontWeight: "400", lineHeight: 18, letterSpacing: 0.024 },
323
- radio: { borderWidth: 1 }
324
- });
325
505
 
326
506
  // src/components/RadioGroup/RadioGroup.native.tsx
327
- import { View as View6 } from "react-native";
328
- import { jsx as jsx9 } from "react/jsx-runtime";
507
+ import { View as View7 } from "react-native";
508
+ import { jsx as jsx12 } from "react/jsx-runtime";
329
509
  function RadioGroup({ children, label, style }) {
330
- return /* @__PURE__ */ jsx9(View6, { accessibilityRole: "radiogroup", accessibilityLabel: label, style: [{ gap: 8 }, style], children });
510
+ return /* @__PURE__ */ jsx12(View7, { accessibilityRole: "radiogroup", accessibilityLabel: label, style: [{ gap: 8 }, style], children });
331
511
  }
332
512
 
333
- // src/components/ActionItem/ActionItem.native.tsx
334
- import { Pressable as Pressable5, View as View7, Text as Text5, StyleSheet as StyleSheet8 } from "react-native";
335
-
336
- // src/components/ActionItem/ActionItem.styles.ts
337
- var actionItemTokens = {
338
- height: 56,
339
- padding: 16,
340
- gap: 20,
341
- innerGap: 16,
342
- borderRadius: 16,
343
- fontSize: 14
344
- };
345
-
346
- // src/components/ActionItem/ActionItem.native.tsx
347
- import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
348
- function ActionItem({ label, description, selected = false, icon, onPress, style }) {
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 }) {
349
517
  const { theme } = useTheme();
350
- const { height, padding, gap, innerGap, borderRadius, fontSize } = actionItemTokens;
351
- const bg = selected ? theme.border : theme.surface;
352
- return /* @__PURE__ */ jsxs4(
353
- Pressable5,
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,
354
538
  {
355
- onPress,
539
+ onPress: disabled ? void 0 : onPress,
540
+ disabled,
541
+ accessibilityRole: type === "radio" ? "radio" : type === "checkbox" ? "checkbox" : "button",
542
+ accessibilityState: { selected: isSelected, checked: isSelected, disabled },
356
543
  style: ({ pressed }) => [
357
- styles8.container,
544
+ styles9.card,
358
545
  {
359
- height,
360
- paddingHorizontal: padding,
361
- gap,
362
- borderRadius,
363
- backgroundColor: bg,
364
- borderWidth: selected ? 2 : 0,
365
- borderColor: selected ? theme.primary : "transparent",
366
- opacity: pressed ? 0.9 : 1
367
- },
368
- style
546
+ backgroundColor: !disabled && pressed ? pressedBg : baseBg,
547
+ borderColor,
548
+ borderWidth: isSelected ? borderWidth.heavy : borderWidth.default
549
+ }
369
550
  ],
370
- accessibilityRole: "button",
371
551
  children: [
372
- /* @__PURE__ */ jsxs4(View7, { style: [styles8.content, { gap: innerGap }], children: [
373
- icon && /* @__PURE__ */ jsx10(View7, { style: styles8.icon, children: icon }),
374
- /* @__PURE__ */ jsxs4(View7, { style: styles8.textContainer, children: [
375
- /* @__PURE__ */ jsx10(Text5, { style: [styles8.label, { fontSize, color: theme.onBackground }], numberOfLines: 1, children: label }),
376
- description && /* @__PURE__ */ jsx10(Text5, { style: [styles8.description, { color: theme.textSecondary }], numberOfLines: 1, children: description })
377
- ] })
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
378
556
  ] }),
379
- /* @__PURE__ */ jsx10(View7, { style: styles8.chevron, children: /* @__PURE__ */ jsx10(Text5, { style: [styles8.chevronText, { color: theme.onBackground }], children: "\u203A" }) })
557
+ showTrailing && /* @__PURE__ */ jsx13(Trailing, { type, selected: isSelected, disabled })
380
558
  ]
381
559
  }
382
560
  );
383
561
  }
384
- var styles8 = StyleSheet8.create({
385
- container: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" },
386
- content: { flex: 1, flexDirection: "row", alignItems: "center", minWidth: 0 },
387
- icon: { width: 24, height: 24, overflow: "hidden", flexShrink: 0 },
388
- textContainer: { flex: 1, flexDirection: "column", gap: 4, minWidth: 0 },
389
- label: { fontWeight: "500", lineHeight: 21 },
390
- description: { fontSize: 12, fontWeight: "400", lineHeight: 18, letterSpacing: 0.024 },
391
- chevron: { width: 24, height: 24, alignItems: "center", justifyContent: "center", flexShrink: 0 },
392
- chevronText: { fontSize: 20 }
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" }] }
393
635
  });
394
636
 
395
637
  // src/components/Stepper/Stepper.native.tsx
396
- import { View as View8, Text as Text6, StyleSheet as StyleSheet9 } from "react-native";
638
+ import { View as View10 } from "react-native";
397
639
 
398
640
  // src/components/Stepper/Stepper.styles.ts
399
641
  var stepperTokens = {
400
- trackHeight: 4,
401
- trackRadius: 8,
402
- dotSize: 4,
403
- labelFontSize: 10,
642
+ segmentHeight: 4,
643
+ segmentRadius: radius.full,
404
644
  gap: 4
405
645
  };
406
646
 
407
647
  // src/components/Stepper/Stepper.native.tsx
408
- import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
409
- function Stepper({ steps, currentStep, style }) {
648
+ import { jsx as jsx15 } from "react/jsx-runtime";
649
+ function Stepper({ totalSteps, currentStep, style }) {
410
650
  const { theme } = useTheme();
411
- const { trackHeight, trackRadius, dotSize, labelFontSize, gap } = stepperTokens;
412
- const getState = (i) => i < currentStep ? "completed" : i === currentStep ? "active" : "upcoming";
413
- return /* @__PURE__ */ jsx11(View8, { style: [styles9.container, { gap }, style], children: steps.map((step, i) => {
414
- const state = getState(i);
415
- const isLast = i === steps.length - 1;
416
- const trackBg = state === "completed" ? theme.primary : theme.border;
417
- const dotBg = state === "completed" ? theme.primary : theme.border;
418
- return /* @__PURE__ */ jsxs5(View8, { style: { flexDirection: "row", alignItems: "flex-end", flex: 1 }, children: [
419
- /* @__PURE__ */ jsxs5(View8, { style: styles9.stepItem, children: [
420
- /* @__PURE__ */ jsx11(View8, { style: styles9.labelRow, children: /* @__PURE__ */ jsx11(
421
- Text6,
422
- {
423
- style: [styles9.label, { fontSize: labelFontSize, color: theme.onBackground, opacity: state === "active" ? 1 : 0 }],
424
- numberOfLines: 1,
425
- children: step.label
426
- }
427
- ) }),
428
- /* @__PURE__ */ jsx11(View8, { style: [styles9.track, { height: trackHeight, borderRadius: trackRadius, backgroundColor: trackBg }], children: state === "active" && /* @__PURE__ */ jsx11(
429
- View8,
430
- {
431
- style: [styles9.trackFill, { height: trackHeight, borderRadius: trackRadius, backgroundColor: theme.onBackground, right: 12 }]
432
- }
433
- ) })
434
- ] }),
435
- !isLast && /* @__PURE__ */ jsx11(View8, { style: [styles9.dot, { width: dotSize, height: dotSize, borderRadius: dotSize / 2, backgroundColor: dotBg }] })
436
- ] }, step.label);
437
- }) });
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
+ );
438
665
  }
439
- var styles9 = StyleSheet9.create({
440
- container: { width: "100%", flexDirection: "row", alignItems: "flex-end" },
441
- stepItem: { flex: 1, flexDirection: "column", gap: 4 },
442
- labelRow: { height: 12, justifyContent: "flex-end" },
443
- label: { fontWeight: "600", letterSpacing: 0.8, textTransform: "uppercase" },
444
- track: { overflow: "hidden", position: "relative" },
445
- trackFill: { position: "absolute", left: 0 },
446
- dot: { alignSelf: "flex-end" }
447
- });
448
666
 
449
667
  // src/components/RatingScale/RatingScale.native.tsx
450
- import { Pressable as Pressable6, View as View9, Text as Text7, StyleSheet as StyleSheet10 } from "react-native";
451
- import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
452
- function RatingScale({ value = null, onChange, options = DEFAULT_OPTIONS, style }) {
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 }) {
453
671
  const { theme } = useTheme();
454
- const { itemWidth, circleSize, circlePadding, circleRadius, emojiFontSize, emojiLineHeight, labelFontSize, numberFontSize, labelNumberGap } = ratingScaleTokens;
455
- return /* @__PURE__ */ jsx12(View9, { style: [styles10.container, style], children: options.map((option, index) => {
672
+ const { circleSize, circleRadius, emojiFontSize, emojiLineHeight, itemGap } = ratingScaleTokens;
673
+ return /* @__PURE__ */ jsx16(View11, { style: [styles11.container, style], children: options.map((option, index) => {
456
674
  const itemValue = index + 1;
457
675
  const selected = value === itemValue;
458
- return /* @__PURE__ */ jsxs6(
459
- Pressable6,
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,
460
681
  {
461
- onPress: () => onChange?.(itemValue),
462
- style: styles10.item,
463
- accessibilityRole: "button",
464
- accessibilityState: { selected },
682
+ onPress: disabled ? void 0 : () => onChange?.(itemValue),
683
+ disabled,
684
+ style: [styles11.item, { gap: itemGap }],
685
+ accessibilityRole: "radio",
686
+ accessibilityState: { selected, disabled },
465
687
  children: [
466
- /* @__PURE__ */ jsx12(
467
- View9,
688
+ /* @__PURE__ */ jsx16(
689
+ View11,
468
690
  {
469
691
  style: [
470
- styles10.circle,
692
+ styles11.circle,
471
693
  {
472
694
  width: circleSize,
473
695
  height: circleSize,
474
696
  borderRadius: circleRadius,
475
- padding: circlePadding,
476
- backgroundColor: selected ? theme.primary : theme.surface,
477
- borderWidth: selected ? 0 : 1,
478
- borderColor: theme.border
697
+ backgroundColor: circleBg,
698
+ borderWidth: selected ? borderWidth.heavy : borderWidth.default,
699
+ borderColor: circleBorderColor
479
700
  }
480
701
  ],
481
- children: /* @__PURE__ */ jsx12(Text7, { style: [styles10.emoji, { fontSize: emojiFontSize, lineHeight: emojiLineHeight }], children: option.emoji })
702
+ children: /* @__PURE__ */ jsx16(Text7, { style: [styles11.emoji, { fontSize: emojiFontSize, lineHeight: emojiLineHeight, opacity: disabled ? 0.4 : 1 }], children: option.emoji })
482
703
  }
483
704
  ),
484
- /* @__PURE__ */ jsxs6(View9, { style: [styles10.labelContainer, { gap: labelNumberGap }], children: [
485
- /* @__PURE__ */ jsx12(
486
- Text7,
487
- {
488
- style: [
489
- styles10.label,
490
- {
491
- fontSize: labelFontSize,
492
- color: selected ? theme.primary : theme.onBackground,
493
- fontWeight: selected ? "700" : "500",
494
- width: itemWidth
495
- }
496
- ],
497
- children: option.label
498
- }
499
- ),
500
- /* @__PURE__ */ jsx12(Text7, { style: [styles10.number, { fontSize: numberFontSize, color: theme.textTertiary }], children: itemValue })
501
- ] })
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 })
502
707
  ]
503
708
  },
504
709
  itemValue
505
710
  );
506
711
  }) });
507
712
  }
508
- var styles10 = StyleSheet10.create({
509
- container: { flexDirection: "row", justifyContent: "space-between" },
510
- item: { alignItems: "center", gap: 8 },
713
+ var styles11 = StyleSheet11.create({
714
+ container: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 8, padding: 16 },
715
+ item: { flex: 1, alignItems: "center" },
511
716
  circle: { alignItems: "center", justifyContent: "center", overflow: "hidden" },
512
717
  emoji: { textAlign: "center" },
513
- labelContainer: { alignItems: "center" },
514
- label: { textAlign: "center", lineHeight: 16 },
515
- number: { fontWeight: "600", letterSpacing: 0.8, textAlign: "center", lineHeight: 10 }
718
+ label: { textAlign: "center" },
719
+ number: { textAlign: "center", fontFamily: "Inter", fontSize: 10, fontWeight: "600", letterSpacing: 0.8 }
516
720
  });
517
721
  export {
518
- ActionItem,
519
722
  Alert,
520
723
  Button,
724
+ ButtonIcon,
521
725
  Checkbox,
522
726
  Chip,
727
+ ChoiceCard,
523
728
  DSThemeProvider,
729
+ DismissButton,
524
730
  Input,
731
+ InputField,
732
+ ListItem,
525
733
  ProgressBar,
526
734
  RadioGroup,
527
- RadioItem,
528
735
  RatingScale,
529
736
  Stepper,
737
+ ToggleSwitch,
738
+ borderWidth,
530
739
  colors,
531
740
  darkTheme,
741
+ grid,
532
742
  lightTheme,
743
+ opacity,
744
+ radius,
745
+ shadow,
746
+ spacing,
533
747
  typography,
534
748
  useTheme
535
749
  };