@retray-dev/ui-kit 10.2.0 → 12.2.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.
Files changed (220) hide show
  1. package/COMPONENTS.md +384 -40
  2. package/README.md +14 -5
  3. package/dist/Accordion.d.mts +6 -0
  4. package/dist/Accordion.d.ts +6 -0
  5. package/dist/Accordion.js +16 -0
  6. package/dist/Accordion.mjs +2 -2
  7. package/dist/AlertBanner.js +2 -0
  8. package/dist/AlertBanner.mjs +2 -2
  9. package/dist/AppHeader.js +2 -0
  10. package/dist/AppHeader.mjs +3 -3
  11. package/dist/Avatar.js +2 -0
  12. package/dist/Avatar.mjs +2 -2
  13. package/dist/Badge.js +2 -0
  14. package/dist/Badge.mjs +2 -2
  15. package/dist/Button.js +17 -17
  16. package/dist/Button.mjs +2 -2
  17. package/dist/Card.js +2 -0
  18. package/dist/Card.mjs +2 -2
  19. package/dist/CategoryStrip.js +2 -0
  20. package/dist/CategoryStrip.mjs +2 -2
  21. package/dist/Checkbox.js +2 -0
  22. package/dist/Checkbox.mjs +2 -2
  23. package/dist/Chip.js +2 -0
  24. package/dist/Chip.mjs +2 -2
  25. package/dist/ConfirmDialog.d.mts +1 -6
  26. package/dist/ConfirmDialog.d.ts +1 -6
  27. package/dist/ConfirmDialog.js +53 -41
  28. package/dist/ConfirmDialog.mjs +3 -3
  29. package/dist/CurrencyDisplay.js +2 -0
  30. package/dist/CurrencyDisplay.mjs +2 -2
  31. package/dist/CurrencyInput.d.mts +3 -8
  32. package/dist/CurrencyInput.d.ts +3 -8
  33. package/dist/CurrencyInput.js +5 -1
  34. package/dist/CurrencyInput.mjs +3 -3
  35. package/dist/DetailRow.js +2 -0
  36. package/dist/DetailRow.mjs +2 -2
  37. package/dist/EmptyState.js +17 -17
  38. package/dist/EmptyState.mjs +3 -3
  39. package/dist/ErrorBoundary.js +2 -0
  40. package/dist/ErrorBoundary.mjs +2 -2
  41. package/dist/Form.js +2 -0
  42. package/dist/Form.mjs +2 -2
  43. package/dist/IconButton.js +2 -0
  44. package/dist/IconButton.mjs +2 -2
  45. package/dist/IconPicker.js +677 -248
  46. package/dist/IconPicker.mjs +3 -2
  47. package/dist/ImageUpload.d.mts +3 -1
  48. package/dist/ImageUpload.d.ts +3 -1
  49. package/dist/ImageUpload.js +10 -3
  50. package/dist/ImageUpload.mjs +3 -3
  51. package/dist/ImageViewer.js +2 -0
  52. package/dist/ImageViewer.mjs +4 -4
  53. package/dist/Input.js +2 -0
  54. package/dist/Input.mjs +2 -2
  55. package/dist/LabelValue.js +2 -0
  56. package/dist/LabelValue.mjs +2 -2
  57. package/dist/ListGroup.js +2 -0
  58. package/dist/ListGroup.mjs +2 -2
  59. package/dist/ListItem.d.mts +7 -7
  60. package/dist/ListItem.d.ts +7 -7
  61. package/dist/ListItem.js +14 -7
  62. package/dist/ListItem.mjs +2 -2
  63. package/dist/MediaCard.js +2 -0
  64. package/dist/MediaCard.mjs +2 -2
  65. package/dist/MenuGroup.js +2 -0
  66. package/dist/MenuGroup.mjs +2 -2
  67. package/dist/MenuItem.js +2 -0
  68. package/dist/MenuItem.mjs +2 -2
  69. package/dist/MonthPicker.js +2 -0
  70. package/dist/MonthPicker.mjs +2 -2
  71. package/dist/NumberStepper.js +2 -0
  72. package/dist/NumberStepper.mjs +2 -2
  73. package/dist/PagerDots.js +2 -0
  74. package/dist/PagerDots.mjs +2 -2
  75. package/dist/Pressable.d.mts +15 -7
  76. package/dist/Pressable.d.ts +15 -7
  77. package/dist/Pressable.js +7 -3
  78. package/dist/Pressable.mjs +1 -1
  79. package/dist/PricingCard.js +17 -17
  80. package/dist/PricingCard.mjs +4 -4
  81. package/dist/Progress.js +2 -0
  82. package/dist/Progress.mjs +2 -2
  83. package/dist/RadioGroup.js +2 -0
  84. package/dist/RadioGroup.mjs +2 -2
  85. package/dist/RetrayProvider.d.mts +1 -1
  86. package/dist/RetrayProvider.d.ts +1 -1
  87. package/dist/RetrayProvider.js +2 -0
  88. package/dist/RetrayProvider.mjs +3 -3
  89. package/dist/Select.js +2 -0
  90. package/dist/Select.mjs +2 -2
  91. package/dist/SelectableCard.d.mts +27 -0
  92. package/dist/SelectableCard.d.ts +27 -0
  93. package/dist/SelectableCard.js +511 -0
  94. package/dist/SelectableCard.mjs +8 -0
  95. package/dist/SelectableGrid.js +2 -0
  96. package/dist/SelectableGrid.mjs +2 -2
  97. package/dist/Separator.js +2 -0
  98. package/dist/Separator.mjs +2 -2
  99. package/dist/Sheet.d.mts +4 -46
  100. package/dist/Sheet.d.ts +4 -46
  101. package/dist/Sheet.js +55 -115
  102. package/dist/Sheet.mjs +2 -3
  103. package/dist/SheetSelect.js +2 -0
  104. package/dist/SheetSelect.mjs +2 -2
  105. package/dist/Skeleton.d.mts +3 -1
  106. package/dist/Skeleton.d.ts +3 -1
  107. package/dist/Skeleton.js +5 -2
  108. package/dist/Skeleton.mjs +2 -2
  109. package/dist/Slider.js +2 -0
  110. package/dist/Slider.mjs +2 -2
  111. package/dist/Spinner.js +2 -0
  112. package/dist/Spinner.mjs +2 -2
  113. package/dist/Stats.d.mts +33 -0
  114. package/dist/Stats.d.ts +33 -0
  115. package/dist/Stats.js +453 -0
  116. package/dist/Stats.mjs +9 -0
  117. package/dist/Switch.js +2 -0
  118. package/dist/Switch.mjs +2 -2
  119. package/dist/TabBar.js +2 -0
  120. package/dist/TabBar.mjs +2 -2
  121. package/dist/Tabs.js +2 -0
  122. package/dist/Tabs.mjs +2 -2
  123. package/dist/Text.d.mts +3 -1
  124. package/dist/Text.d.ts +3 -1
  125. package/dist/Text.js +5 -3
  126. package/dist/Text.mjs +2 -2
  127. package/dist/Textarea.js +2 -0
  128. package/dist/Textarea.mjs +2 -2
  129. package/dist/Toast.js +2 -0
  130. package/dist/Toast.mjs +2 -2
  131. package/dist/Toggle.js +2 -0
  132. package/dist/Toggle.mjs +2 -2
  133. package/dist/{chunk-U2XJFYED.mjs → chunk-2BA3JMKK.mjs} +1 -1
  134. package/dist/{chunk-NMU5FMQJ.mjs → chunk-2HFD4IHU.mjs} +4 -2
  135. package/dist/{chunk-S2R7UVOE.mjs → chunk-2LG326TT.mjs} +1 -1
  136. package/dist/chunk-2P2CB235.mjs +236 -0
  137. package/dist/{chunk-6L4G6PBT.mjs → chunk-3XCFYSX4.mjs} +1 -1
  138. package/dist/{chunk-HTHGSXFG.mjs → chunk-4J2PXL36.mjs} +16 -18
  139. package/dist/{chunk-BEMIQXXU.mjs → chunk-4OORJ2DY.mjs} +1 -1
  140. package/dist/chunk-4XOB5TTD.mjs +166 -0
  141. package/dist/{chunk-FCSSQK3L.mjs → chunk-57V2LXCK.mjs} +1 -1
  142. package/dist/{chunk-6Q64UFIA.mjs → chunk-7AFZWSCI.mjs} +1 -1
  143. package/dist/{chunk-IX3NYLYQ.mjs → chunk-7ELGZ66G.mjs} +1 -1
  144. package/dist/{chunk-GD6KXMG5.mjs → chunk-AENAVIKT.mjs} +1 -1
  145. package/dist/{chunk-ID72TK46.mjs → chunk-BXF4AMHY.mjs} +1 -1
  146. package/dist/{chunk-SOA2Z4RB.mjs → chunk-C43HRKXH.mjs} +1 -1
  147. package/dist/{chunk-TZDGAP5N.mjs → chunk-CF27NBXO.mjs} +11 -6
  148. package/dist/{chunk-SXLKNTA4.mjs → chunk-DF7JA72E.mjs} +1 -1
  149. package/dist/{chunk-AJRVDP2H.mjs → chunk-E5UKLSJZ.mjs} +3 -3
  150. package/dist/{chunk-MBMXYJJV.mjs → chunk-E7NEHHXV.mjs} +7 -3
  151. package/dist/{chunk-VKID2D2I.mjs → chunk-EDLCGYIO.mjs} +13 -8
  152. package/dist/{chunk-BUMAMSTZ.mjs → chunk-ELGEOM7I.mjs} +1 -1
  153. package/dist/{chunk-DYT7BG5I.mjs → chunk-F3YTWO3T.mjs} +1 -1
  154. package/dist/{chunk-VF2ATYN3.mjs → chunk-GH67YXG6.mjs} +1 -1
  155. package/dist/{chunk-WJLKJMKR.mjs → chunk-GUTDFUNF.mjs} +4 -4
  156. package/dist/{chunk-6SECQ2ZF.mjs → chunk-HC4VVCWY.mjs} +2 -2
  157. package/dist/{chunk-A3A6KNQN.mjs → chunk-HEDQPK4I.mjs} +1 -1
  158. package/dist/{chunk-GQYFLP3D.mjs → chunk-IVSRW4HS.mjs} +1 -1
  159. package/dist/{chunk-KOO4WITD.mjs → chunk-KSUWPU2F.mjs} +1 -1
  160. package/dist/{chunk-WBOOUHSS.mjs → chunk-LIS6I5UP.mjs} +1 -1
  161. package/dist/{chunk-X4G6APW6.mjs → chunk-LNPKGWBG.mjs} +1 -1
  162. package/dist/{chunk-T2KCAHOS.mjs → chunk-LOBLCFMN.mjs} +1 -1
  163. package/dist/{chunk-ELXBDILQ.mjs → chunk-LPV4NJJK.mjs} +2 -2
  164. package/dist/{chunk-Y2NS74WS.mjs → chunk-M3C7XM2M.mjs} +53 -99
  165. package/dist/{chunk-BRKYVJVV.mjs → chunk-MEPSKGBO.mjs} +1 -1
  166. package/dist/{chunk-TBNZHU6C.mjs → chunk-MVMGPZN6.mjs} +2 -2
  167. package/dist/{chunk-YJ7I257J.mjs → chunk-NHDI3VQB.mjs} +15 -1
  168. package/dist/{chunk-Z6SFHN6T.mjs → chunk-NJG7DHVF.mjs} +1 -1
  169. package/dist/{chunk-RYZC432S.mjs → chunk-NLZY4TXU.mjs} +1 -1
  170. package/dist/{chunk-ZZ2R6KZ3.mjs → chunk-OLVJFKXS.mjs} +1 -1
  171. package/dist/{chunk-AJ7ZDNBT.mjs → chunk-QDAZGZUF.mjs} +4 -3
  172. package/dist/{chunk-JT7HKXRB.mjs → chunk-QOLWA2PW.mjs} +1 -1
  173. package/dist/{chunk-WYEUNUTP.mjs → chunk-QXDGGOLC.mjs} +38 -25
  174. package/dist/{chunk-JMOZEC77.mjs → chunk-RJNLAH76.mjs} +1 -1
  175. package/dist/{chunk-WF2XDFRK.mjs → chunk-RMRS44MQ.mjs} +1 -1
  176. package/dist/chunk-SAWUXP3A.mjs +1114 -0
  177. package/dist/{chunk-OB4JUQ3O.mjs → chunk-TS7DGUIR.mjs} +1 -1
  178. package/dist/{chunk-AV4EMIRH.mjs → chunk-UBUXUMER.mjs} +1 -1
  179. package/dist/{chunk-IRRY3CRZ.mjs → chunk-ULGNQPNE.mjs} +1 -1
  180. package/dist/{chunk-7LWRKMF5.mjs → chunk-UNNRUJTM.mjs} +1 -1
  181. package/dist/{chunk-TB6SD2FT.mjs → chunk-UQ4742ET.mjs} +1 -1
  182. package/dist/{chunk-MX6HRKMI.mjs → chunk-VJBUCITV.mjs} +1 -1
  183. package/dist/{chunk-2UYENBLV.mjs → chunk-YMYIEVZP.mjs} +1 -1
  184. package/dist/{chunk-SOYNZDVY.mjs → chunk-YTXRIXNZ.mjs} +8 -1
  185. package/dist/{chunk-YFZ3ELX5.mjs → chunk-ZIMY2QUM.mjs} +2 -2
  186. package/dist/{chunk-Z4VHZ7B5.mjs → chunk-ZR6HSEAB.mjs} +1 -1
  187. package/dist/fonts.d.mts +1 -7
  188. package/dist/fonts.d.ts +1 -7
  189. package/dist/fonts.js +0 -2
  190. package/dist/fonts.mjs +1 -2
  191. package/dist/{index-wt-orHUi.d.ts → index-CY34hxPN.d.mts} +1 -0
  192. package/dist/{index-wt-orHUi.d.mts → index-CY34hxPN.d.ts} +1 -0
  193. package/dist/index.d.mts +7 -3
  194. package/dist/index.d.ts +7 -3
  195. package/dist/index.js +1517 -761
  196. package/dist/index.mjs +54 -52
  197. package/package.json +3 -3
  198. package/src/components/Accordion/Accordion.tsx +20 -0
  199. package/src/components/Button/Button.tsx +29 -26
  200. package/src/components/ConfirmDialog/ConfirmDialog.tsx +47 -31
  201. package/src/components/CurrencyInput/CurrencyInput.tsx +4 -7
  202. package/src/components/IconPicker/IconPicker.tsx +124 -112
  203. package/src/components/ImageUpload/ImageUpload.tsx +10 -3
  204. package/src/components/ListItem/ListItem.tsx +43 -28
  205. package/src/components/Pressable/Pressable.tsx +20 -8
  206. package/src/components/SelectableCard/SelectableCard.tsx +304 -0
  207. package/src/components/SelectableCard/index.ts +1 -0
  208. package/src/components/Sheet/Sheet.tsx +72 -173
  209. package/src/components/Skeleton/Skeleton.tsx +5 -2
  210. package/src/components/Stats/Stats.tsx +254 -0
  211. package/src/components/Stats/index.ts +2 -0
  212. package/src/components/Text/Text.tsx +4 -2
  213. package/src/fonts.ts +0 -7
  214. package/src/index.ts +5 -0
  215. package/src/theme/colorUtils.ts +9 -0
  216. package/src/theme/colors.ts +7 -0
  217. package/src/theme/types.ts +4 -1
  218. package/src/utils/curatedIcons.ts +698 -135
  219. package/src/utils/fontGuard.ts +2 -1
  220. package/dist/chunk-53Z3NYGE.mjs +0 -742
package/dist/Toggle.js CHANGED
@@ -164,6 +164,7 @@ function deriveColors(t, scheme) {
164
164
  const foregroundMuted = mixWithBackground(t.foreground, bg, 0.62);
165
165
  const surface = dark ? lighten(bg, -0.06) : darken(bg, 0.04);
166
166
  const surfaceStrong = dark ? lighten(bg, -0.12) : darken(bg, 0.08);
167
+ const skeleton = dark ? lighten(bg, -0.1) : darken(bg, 0.1);
167
168
  const destructiveTint = dark ? withAlphaOnDark(t.destructive, 0.15, bg) : withAlphaOnWhite(t.destructive, 0.08);
168
169
  const destructiveBorder = dark ? withAlphaOnDark(t.destructive, 0.45, bg) : withAlphaOnWhite(t.destructive, 0.3);
169
170
  const successTint = dark ? withAlphaOnDark(t.success, 0.15, bg) : withAlphaOnWhite(t.success, 0.08);
@@ -176,6 +177,7 @@ function deriveColors(t, scheme) {
176
177
  foregroundMuted,
177
178
  surface,
178
179
  surfaceStrong,
180
+ skeleton,
179
181
  destructiveTint,
180
182
  destructiveBorder,
181
183
  successTint,
package/dist/Toggle.mjs CHANGED
@@ -1,8 +1,8 @@
1
- export { Toggle } from './chunk-7LWRKMF5.mjs';
1
+ export { Toggle } from './chunk-UNNRUJTM.mjs';
2
2
  import './chunk-3DKJ2GIC.mjs';
3
3
  import './chunk-EJ7ZPXOH.mjs';
4
4
  import './chunk-DVK4G2GT.mjs';
5
5
  import './chunk-KA7LTET3.mjs';
6
- import './chunk-SOYNZDVY.mjs';
6
+ import './chunk-YTXRIXNZ.mjs';
7
7
  import './chunk-2CE3TQVY.mjs';
8
8
  import './chunk-Y6FXYEAI.mjs';
@@ -1,6 +1,6 @@
1
1
  import { TIMINGS, EASINGS } from './chunk-DVK4G2GT.mjs';
2
2
  import { renderIcon } from './chunk-KA7LTET3.mjs';
3
- import { useTheme } from './chunk-SOYNZDVY.mjs';
3
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
4
4
  import { vs, ms, s } from './chunk-2CE3TQVY.mjs';
5
5
  import React, { useState, useEffect } from 'react';
6
6
  import { Platform, StyleSheet, View, Text, TextInput } from 'react-native';
@@ -1,4 +1,4 @@
1
- import { Input } from './chunk-SXLKNTA4.mjs';
1
+ import { Input } from './chunk-DF7JA72E.mjs';
2
2
  import { ms, vs } from './chunk-2CE3TQVY.mjs';
3
3
  import React from 'react';
4
4
 
@@ -21,7 +21,8 @@ function CurrencyInput({
21
21
  editable,
22
22
  containerStyle,
23
23
  style,
24
- sheetMode
24
+ sheetMode,
25
+ ...props
25
26
  }) {
26
27
  const handleChange = (text) => {
27
28
  const withoutPrefix = prefix && text.startsWith(prefix) ? text.slice(prefix.length) : text;
@@ -42,6 +43,7 @@ function CurrencyInput({
42
43
  return /* @__PURE__ */ React.createElement(
43
44
  Input,
44
45
  {
46
+ ...props,
45
47
  value: displayValue,
46
48
  onChangeText: handleChange,
47
49
  keyboardType: "numeric",
@@ -1,5 +1,5 @@
1
1
  import { renderIcon } from './chunk-KA7LTET3.mjs';
2
- import { useTheme } from './chunk-SOYNZDVY.mjs';
2
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
3
3
  import { mvs, ms, s } from './chunk-2CE3TQVY.mjs';
4
4
  import React from 'react';
5
5
  import { StyleSheet, View, Text } from 'react-native';
@@ -0,0 +1,236 @@
1
+ import { impactLight } from './chunk-EJ7ZPXOH.mjs';
2
+ import { COLOR_TRANSITION, SPRING_ELASTIC, OPACITY_TRANSITION } from './chunk-DVK4G2GT.mjs';
3
+ import { RADIUS } from './chunk-QY3X2UYR.mjs';
4
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
5
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
6
+ import { mvs, ms, vs, s } from './chunk-2CE3TQVY.mjs';
7
+ import React, { createContext, useContext } from 'react';
8
+ import { StyleSheet, View, Pressable, Text } from 'react-native';
9
+ import { EaseView } from 'react-native-ease';
10
+
11
+ var SelectableCardContext = createContext(null);
12
+ function SelectableCardGroup({
13
+ type,
14
+ value,
15
+ onValueChange,
16
+ variant = "elevated",
17
+ gap = s(8),
18
+ style,
19
+ children
20
+ }) {
21
+ return /* @__PURE__ */ React.createElement(SelectableCardContext.Provider, { value: { type, value, onValueChange, variant } }, /* @__PURE__ */ React.createElement(View, { style: [styles.group, { gap }, style] }, children));
22
+ }
23
+ function SelectableCard({
24
+ value,
25
+ title,
26
+ description,
27
+ iconName,
28
+ icon,
29
+ disabled = false,
30
+ style
31
+ }) {
32
+ const ctx = useContext(SelectableCardContext);
33
+ if (!ctx) {
34
+ throw new Error("SelectableCard must be used inside <SelectableCard.Group>");
35
+ }
36
+ const { colors } = useTheme();
37
+ const { type, value: selectedValue, onValueChange, variant } = ctx;
38
+ const isSelected = type === "radio" ? selectedValue === value : Array.isArray(selectedValue) && selectedValue.includes(value);
39
+ const handlePress = () => {
40
+ if (disabled) return;
41
+ impactLight();
42
+ if (type === "radio") {
43
+ onValueChange(value);
44
+ } else {
45
+ const arr = Array.isArray(selectedValue) ? selectedValue : [];
46
+ if (arr.includes(value)) {
47
+ onValueChange(arr.filter((v) => v !== value));
48
+ } else {
49
+ onValueChange([...arr, value]);
50
+ }
51
+ }
52
+ };
53
+ const variantStyle = (() => {
54
+ const borderWidth = 2;
55
+ const base = {
56
+ elevated: {
57
+ backgroundColor: colors.card,
58
+ borderWidth,
59
+ borderColor: "transparent"
60
+ // reserve space for selected border
61
+ },
62
+ outlined: {
63
+ backgroundColor: colors.card,
64
+ borderWidth,
65
+ borderColor: colors.border
66
+ },
67
+ filled: {
68
+ backgroundColor: colors.surfaceStrong,
69
+ borderWidth,
70
+ borderColor: colors.border
71
+ }
72
+ }[variant];
73
+ if (isSelected && !disabled) {
74
+ return {
75
+ ...base,
76
+ borderColor: colors.primary,
77
+ shadowColor: "transparent",
78
+ shadowOpacity: 0,
79
+ shadowRadius: 0,
80
+ elevation: 0
81
+ };
82
+ }
83
+ if (disabled) {
84
+ return {
85
+ ...base,
86
+ shadowColor: "transparent",
87
+ shadowOpacity: 0,
88
+ shadowRadius: 0,
89
+ elevation: 0,
90
+ borderColor: colors.border
91
+ };
92
+ }
93
+ return base;
94
+ })();
95
+ const resolvedIcon = iconName ? renderIcon(iconName, ms(22), disabled ? colors.foregroundMuted : colors.foregroundMuted) : icon;
96
+ const resolvedIconElement = resolvedIcon ? /* @__PURE__ */ React.createElement(View, { style: [styles.iconWrapper, disabled && { opacity: 0.45 }] }, resolvedIcon) : null;
97
+ const selectorAccessibilityRole = type === "radio" ? "radio" : "checkbox";
98
+ return /* @__PURE__ */ React.createElement(
99
+ Pressable,
100
+ {
101
+ onPress: handlePress,
102
+ disabled,
103
+ accessibilityRole: "button",
104
+ accessibilityLabel: `${title}${description ? `, ${description}` : ""}`,
105
+ accessibilityState: { selected: isSelected, disabled },
106
+ style: [
107
+ styles.card,
108
+ variantStyle,
109
+ isSelected && !disabled && styles.cardSelected,
110
+ style
111
+ ]
112
+ },
113
+ /* @__PURE__ */ React.createElement(View, { style: styles.row }, /* @__PURE__ */ React.createElement(View, { style: styles.selectorContainer, accessibilityRole: selectorAccessibilityRole, accessibilityState: { selected: isSelected, disabled } }, type === "radio" ? /* @__PURE__ */ React.createElement(
114
+ EaseView,
115
+ {
116
+ style: styles.radioCircle,
117
+ animate: { borderColor: !disabled && isSelected ? colors.primary : colors.border },
118
+ transition: COLOR_TRANSITION
119
+ },
120
+ /* @__PURE__ */ React.createElement(
121
+ EaseView,
122
+ {
123
+ animate: {
124
+ scale: !disabled && isSelected ? 1 : 0,
125
+ opacity: !disabled && isSelected ? 1 : 0
126
+ },
127
+ transition: SPRING_ELASTIC
128
+ },
129
+ /* @__PURE__ */ React.createElement(View, { style: [styles.radioDot, { backgroundColor: colors.primary }] })
130
+ )
131
+ ) : /* @__PURE__ */ React.createElement(
132
+ EaseView,
133
+ {
134
+ style: styles.checkboxBox,
135
+ animate: {
136
+ borderColor: !disabled && isSelected ? colors.primary : colors.border,
137
+ backgroundColor: !disabled && isSelected ? colors.primary : "transparent"
138
+ },
139
+ transition: COLOR_TRANSITION
140
+ },
141
+ /* @__PURE__ */ React.createElement(
142
+ EaseView,
143
+ {
144
+ animate: { opacity: !disabled && isSelected ? 1 : 0 },
145
+ transition: OPACITY_TRANSITION
146
+ },
147
+ /* @__PURE__ */ React.createElement(View, { style: [styles.checkmark, { borderColor: colors.primaryForeground }] })
148
+ )
149
+ )), resolvedIconElement, /* @__PURE__ */ React.createElement(View, { style: styles.textArea }, /* @__PURE__ */ React.createElement(
150
+ Text,
151
+ {
152
+ style: [styles.title, { color: disabled ? colors.foregroundMuted : colors.foreground }],
153
+ allowFontScaling: true,
154
+ numberOfLines: 2
155
+ },
156
+ title
157
+ ), description ? /* @__PURE__ */ React.createElement(
158
+ Text,
159
+ {
160
+ style: [styles.description, { color: disabled ? colors.foregroundMuted : colors.foregroundSubtle }],
161
+ allowFontScaling: true,
162
+ numberOfLines: 4
163
+ },
164
+ description
165
+ ) : null))
166
+ );
167
+ }
168
+ var styles = StyleSheet.create({
169
+ group: {
170
+ width: "100%"
171
+ },
172
+ card: {
173
+ borderRadius: RADIUS.md,
174
+ borderWidth: 1
175
+ },
176
+ cardSelected: {
177
+ backgroundColor: void 0
178
+ // overridden by variantStyle
179
+ },
180
+ row: {
181
+ flexDirection: "row",
182
+ alignItems: "flex-start",
183
+ padding: s(16),
184
+ gap: s(12)
185
+ },
186
+ selectorContainer: {
187
+ paddingTop: vs(1)
188
+ },
189
+ radioCircle: {
190
+ width: s(24),
191
+ height: s(24),
192
+ borderRadius: s(12),
193
+ borderWidth: 2,
194
+ alignItems: "center",
195
+ justifyContent: "center"
196
+ },
197
+ radioDot: {
198
+ width: s(10),
199
+ height: s(10),
200
+ borderRadius: s(5)
201
+ },
202
+ checkboxBox: {
203
+ width: s(24),
204
+ height: s(24),
205
+ borderRadius: ms(4),
206
+ borderWidth: 2,
207
+ alignItems: "center",
208
+ justifyContent: "center"
209
+ },
210
+ checkmark: {
211
+ width: s(12),
212
+ height: vs(7),
213
+ borderLeftWidth: 2,
214
+ borderBottomWidth: 2,
215
+ transform: [{ rotate: "-45deg" }, { translateY: -1 }]
216
+ },
217
+ iconWrapper: {
218
+ paddingTop: vs(1)
219
+ },
220
+ textArea: {
221
+ flex: 1,
222
+ gap: vs(4)
223
+ },
224
+ title: {
225
+ fontFamily: "Sohne-SemiBold",
226
+ fontSize: ms(16),
227
+ lineHeight: mvs(22)
228
+ },
229
+ description: {
230
+ fontFamily: "Sohne-Regular",
231
+ fontSize: ms(13),
232
+ lineHeight: mvs(18)
233
+ }
234
+ });
235
+
236
+ export { SelectableCard, SelectableCardGroup };
@@ -3,7 +3,7 @@ import { selectionAsync } from './chunk-EJ7ZPXOH.mjs';
3
3
  import { PRESS_SCALE, COLOR_TRANSITION } from './chunk-DVK4G2GT.mjs';
4
4
  import { RADIUS } from './chunk-QY3X2UYR.mjs';
5
5
  import { renderIcon } from './chunk-KA7LTET3.mjs';
6
- import { useTheme } from './chunk-SOYNZDVY.mjs';
6
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
7
7
  import { ms, s, vs } from './chunk-2CE3TQVY.mjs';
8
8
  import React, { useCallback } from 'react';
9
9
  import { TouchableOpacity, View, Text, StyleSheet, ScrollView } from 'react-native';
@@ -2,7 +2,7 @@ import { PressableButton } from './chunk-3DKJ2GIC.mjs';
2
2
  import { impactMedium } from './chunk-EJ7ZPXOH.mjs';
3
3
  import { TYPOGRAPHY, RADIUS } from './chunk-QY3X2UYR.mjs';
4
4
  import { renderIcon } from './chunk-KA7LTET3.mjs';
5
- import { useTheme } from './chunk-SOYNZDVY.mjs';
5
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
6
6
  import { vs, s, mvs, ms } from './chunk-2CE3TQVY.mjs';
7
7
  import React from 'react';
8
8
  import { StyleSheet, View, ActivityIndicator, Text } from 'react-native';
@@ -41,24 +41,26 @@ function ButtonBase({
41
41
  impactMedium();
42
42
  onPress?.();
43
43
  };
44
- const containerVariantStyle = {
44
+ const containerVariantStyle = isDisabled ? {
45
+ primary: { backgroundColor: colors.surface },
46
+ secondary: { backgroundColor: "transparent", borderWidth: 1.5, borderColor: colors.border },
47
+ text: { backgroundColor: "transparent" },
48
+ destructive: { backgroundColor: colors.surface }
49
+ }[variant] : {
45
50
  primary: { backgroundColor: colors.primary },
46
51
  secondary: { backgroundColor: "transparent", borderWidth: 1.5, borderColor: colors.primary },
47
52
  text: { backgroundColor: "transparent" },
48
53
  destructive: { backgroundColor: colors.destructive }
49
54
  }[variant];
50
- const labelVariantStyle = {
51
- primary: { color: colors.primaryForeground },
52
- secondary: { color: colors.primary },
53
- // AUDIT FIX: was colors.foreground — visually indistinguishable from plain text,
54
- // no affordance that it's a CTA. Now uses accentResolved so text-only buttons
55
- // carry the brand voltage. Falls back to primary when no accent is defined.
56
- text: { color: colors.accentResolved },
57
- destructive: { color: colors.destructiveForeground }
55
+ const labelColor = isDisabled ? colors.foregroundMuted : {
56
+ primary: colors.primaryForeground,
57
+ secondary: colors.primary,
58
+ text: colors.accentResolved,
59
+ destructive: colors.destructiveForeground
58
60
  }[variant];
59
- const textColor = iconColor ?? labelVariantStyle.color;
61
+ const textColor = iconColor ?? labelColor;
60
62
  const effectiveIcon = iconName ? renderIcon(iconName, iconSizeMap[size], textColor) : typeof icon === "function" ? icon({ label, size, variant, color: textColor }) : icon;
61
- const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary" ? colors.primaryForeground : colors.accentResolved;
63
+ const spinnerColor = isDisabled ? colors.foregroundMuted : variant === "destructive" ? colors.destructiveForeground : variant === "primary" ? colors.primaryForeground : colors.accentResolved;
62
64
  const styleArray = Array.isArray(style) ? style : style ? [style] : [];
63
65
  const flatStyle = StyleSheet.flatten(styleArray);
64
66
  const { flex, ...restStyle } = flatStyle || {};
@@ -70,7 +72,6 @@ function ButtonBase({
70
72
  containerVariantStyle,
71
73
  containerSizeStyles[size],
72
74
  fullWidth && styles.fullWidth,
73
- isDisabled && styles.disabled,
74
75
  restStyle
75
76
  ],
76
77
  enabled: !isDisabled,
@@ -86,7 +87,7 @@ function ButtonBase({
86
87
  loading ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ActivityIndicator, { size: "small", color: spinnerColor, style: { marginRight: s(6) } }), /* @__PURE__ */ React.createElement(
87
88
  Text,
88
89
  {
89
- style: [styles.label, labelVariantStyle, labelSizeStyles[size], styles.labelLoading],
90
+ style: [styles.label, { color: labelColor }, labelSizeStyles[size], styles.labelLoading],
90
91
  allowFontScaling: true,
91
92
  numberOfLines: 1
92
93
  },
@@ -94,7 +95,7 @@ function ButtonBase({
94
95
  )) : /* @__PURE__ */ React.createElement(React.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React.createElement(React.Fragment, null, effectiveIcon), /* @__PURE__ */ React.createElement(
95
96
  Text,
96
97
  {
97
- style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
98
+ style: [styles.label, { color: labelColor }, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
98
99
  allowFontScaling: true,
99
100
  numberOfLines: 1
100
101
  },
@@ -113,9 +114,6 @@ var styles = StyleSheet.create({
113
114
  fullWidth: {
114
115
  width: "100%"
115
116
  },
116
- disabled: {
117
- opacity: 0.45
118
- },
119
117
  label: {
120
118
  fontFamily: "Sohne-Medium",
121
119
  flexShrink: 1
@@ -1,6 +1,6 @@
1
1
  import { RADIUS } from './chunk-QY3X2UYR.mjs';
2
2
  import { renderIcon } from './chunk-KA7LTET3.mjs';
3
- import { useTheme } from './chunk-SOYNZDVY.mjs';
3
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
4
4
  import { s, vs, ms } from './chunk-2CE3TQVY.mjs';
5
5
  import React from 'react';
6
6
  import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';
@@ -0,0 +1,166 @@
1
+ import { PressableCard } from './chunk-3DKJ2GIC.mjs';
2
+ import { impactLight } from './chunk-EJ7ZPXOH.mjs';
3
+ import { RADIUS } from './chunk-QY3X2UYR.mjs';
4
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
5
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
6
+ import { s, vs, mvs, ms } from './chunk-2CE3TQVY.mjs';
7
+ import React, { useState, useCallback } from 'react';
8
+ import { StyleSheet, View, Text } from 'react-native';
9
+
10
+ var COMPACT_THRESHOLD = s(150);
11
+ function StatsComponent({
12
+ value,
13
+ label,
14
+ description,
15
+ icon,
16
+ iconName,
17
+ iconColor,
18
+ variant = "elevated",
19
+ size = "default",
20
+ onPress,
21
+ style,
22
+ accessibilityLabel
23
+ }) {
24
+ const { colors } = useTheme();
25
+ const [containerWidth, setContainerWidth] = useState(0);
26
+ const handleLayout = useCallback((e) => {
27
+ const w = e.nativeEvent.layout.width;
28
+ if (w > 0 && w !== containerWidth) {
29
+ setContainerWidth(w);
30
+ }
31
+ }, [containerWidth]);
32
+ const handlePress = () => {
33
+ if (!onPress) return;
34
+ impactLight();
35
+ onPress();
36
+ };
37
+ const isCompact = containerWidth > 0 && containerWidth < COMPACT_THRESHOLD && !!(icon ?? iconName);
38
+ const sizeStyles = size === "compact" ? {
39
+ valueFontFamily: "Sohne-SemiBold",
40
+ valueFontSize: ms(16),
41
+ valueLineHeight: mvs(20),
42
+ labelFontSize: ms(11),
43
+ labelLineHeight: mvs(14),
44
+ descriptionFontSize: ms(10),
45
+ descriptionLineHeight: mvs(14),
46
+ iconSize: ms(18),
47
+ padding: s(12)
48
+ } : {
49
+ valueFontFamily: "Sohne-Bold",
50
+ valueFontSize: ms(21),
51
+ valueLineHeight: mvs(25),
52
+ labelFontSize: ms(13),
53
+ labelLineHeight: mvs(18),
54
+ descriptionFontSize: ms(12),
55
+ descriptionLineHeight: mvs(16),
56
+ iconSize: ms(20),
57
+ padding: s(16)
58
+ };
59
+ const variantStyle = {
60
+ elevated: {
61
+ backgroundColor: colors.card,
62
+ borderWidth: 0,
63
+ shadowColor: "#000",
64
+ shadowOffset: { width: 0, height: 4 },
65
+ shadowOpacity: 0.09,
66
+ shadowRadius: 14,
67
+ elevation: 4
68
+ },
69
+ outlined: {
70
+ backgroundColor: colors.card,
71
+ borderColor: colors.border,
72
+ shadowOpacity: 0,
73
+ elevation: 0
74
+ },
75
+ filled: {
76
+ backgroundColor: colors.surfaceStrong,
77
+ borderColor: colors.border,
78
+ shadowOpacity: 0,
79
+ elevation: 0
80
+ }
81
+ }[variant];
82
+ const iconColorResolved = iconColor ?? colors.primary;
83
+ const resolvedIcon = iconName ? renderIcon(iconName, sizeStyles.iconSize, iconColorResolved) : icon;
84
+ const iconElement = resolvedIcon ? /* @__PURE__ */ React.createElement(View, { style: styles.iconWrapper }, resolvedIcon) : null;
85
+ const valueElement = /* @__PURE__ */ React.createElement(Text, { style: [styles.value, { color: colors.foreground, fontFamily: sizeStyles.valueFontFamily, fontSize: sizeStyles.valueFontSize, lineHeight: sizeStyles.valueLineHeight }], allowFontScaling: true }, value);
86
+ const cardContent = /* @__PURE__ */ React.createElement(View, { style: [styles.card, variantStyle, { padding: sizeStyles.padding }, style], onLayout: handleLayout }, isCompact ? /* @__PURE__ */ React.createElement(React.Fragment, null, iconElement, /* @__PURE__ */ React.createElement(View, { style: styles.compactValue }, valueElement), /* @__PURE__ */ React.createElement(Text, { style: [styles.label, { color: colors.foregroundSubtle, fontSize: sizeStyles.labelFontSize, lineHeight: sizeStyles.labelLineHeight }], allowFontScaling: true }, label), description ? /* @__PURE__ */ React.createElement(Text, { style: [styles.description, { color: colors.foregroundMuted, fontSize: sizeStyles.descriptionFontSize, lineHeight: sizeStyles.descriptionLineHeight }], allowFontScaling: true }, description) : null) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(View, { style: styles.valueRow }, iconElement, valueElement), /* @__PURE__ */ React.createElement(Text, { style: [styles.label, { color: colors.foregroundSubtle, fontSize: sizeStyles.labelFontSize, lineHeight: sizeStyles.labelLineHeight }], allowFontScaling: true }, label), description ? /* @__PURE__ */ React.createElement(Text, { style: [styles.description, { color: colors.foregroundMuted, fontSize: sizeStyles.descriptionFontSize, lineHeight: sizeStyles.descriptionLineHeight }], allowFontScaling: true }, description) : null));
87
+ if (onPress) {
88
+ return /* @__PURE__ */ React.createElement(
89
+ PressableCard,
90
+ {
91
+ onPress: handlePress,
92
+ rippleColor: "transparent",
93
+ touchSoundDisabled: true,
94
+ activateOnHover: true,
95
+ accessibilityRole: "button",
96
+ accessibilityLabel
97
+ },
98
+ cardContent
99
+ );
100
+ }
101
+ return cardContent;
102
+ }
103
+ function StatsGroup({ children, gap = s(12), style }) {
104
+ return /* @__PURE__ */ React.createElement(View, { style: [styles.group, { gap }, style] }, React.Children.map(children, (child) => {
105
+ if (!React.isValidElement(child)) return child;
106
+ const childStyle = child.props.style;
107
+ const mergedStyle = childStyle ? [childStyle, { alignSelf: "stretch" }] : [{ alignSelf: "stretch" }];
108
+ return /* @__PURE__ */ React.createElement(View, { style: styles.groupItem }, React.cloneElement(
109
+ child,
110
+ { style: mergedStyle }
111
+ ));
112
+ }));
113
+ }
114
+ var Stats = Object.assign(React.memo(StatsComponent), { Group: StatsGroup });
115
+ var styles = StyleSheet.create({
116
+ card: {
117
+ borderRadius: RADIUS.md,
118
+ borderWidth: 1,
119
+ padding: s(16),
120
+ alignSelf: "flex-start",
121
+ alignItems: "center",
122
+ justifyContent: "center"
123
+ },
124
+ valueRow: {
125
+ flexDirection: "row",
126
+ alignItems: "center",
127
+ justifyContent: "center",
128
+ gap: s(8)
129
+ },
130
+ iconWrapper: {
131
+ alignItems: "center",
132
+ justifyContent: "center"
133
+ },
134
+ compactValue: {
135
+ marginTop: vs(8)
136
+ },
137
+ value: {
138
+ fontFamily: "Sohne-Bold",
139
+ fontSize: ms(28),
140
+ lineHeight: mvs(32),
141
+ textAlign: "center"
142
+ },
143
+ label: {
144
+ fontFamily: "Sohne-Regular",
145
+ fontSize: ms(13),
146
+ lineHeight: mvs(18),
147
+ marginTop: vs(8),
148
+ textAlign: "center"
149
+ },
150
+ description: {
151
+ fontFamily: "Sohne-Regular",
152
+ fontSize: ms(12),
153
+ lineHeight: mvs(16),
154
+ marginTop: vs(4),
155
+ textAlign: "center"
156
+ },
157
+ group: {
158
+ flexDirection: "row",
159
+ width: "100%"
160
+ },
161
+ groupItem: {
162
+ flex: 1
163
+ }
164
+ });
165
+
166
+ export { Stats };
@@ -1,5 +1,5 @@
1
1
  import { renderIcon } from './chunk-KA7LTET3.mjs';
2
- import { useTheme } from './chunk-SOYNZDVY.mjs';
2
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
3
3
  import { mvs, ms, s } from './chunk-2CE3TQVY.mjs';
4
4
  import React from 'react';
5
5
  import { StyleSheet, View, Text } from 'react-native';
@@ -1,4 +1,4 @@
1
- import { useTheme } from './chunk-SOYNZDVY.mjs';
1
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
2
2
  import { vs, s } from './chunk-2CE3TQVY.mjs';
3
3
  import React from 'react';
4
4
  import { StyleSheet, View, Text } from 'react-native';
@@ -3,7 +3,7 @@ import { impactLight } from './chunk-EJ7ZPXOH.mjs';
3
3
  import { SPRINGS, PRESS_SCALE } from './chunk-DVK4G2GT.mjs';
4
4
  import { RADIUS, SHADOWS } from './chunk-QY3X2UYR.mjs';
5
5
  import { renderIcon } from './chunk-KA7LTET3.mjs';
6
- import { useTheme } from './chunk-SOYNZDVY.mjs';
6
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
7
7
  import { mvs, ms, vs, s } from './chunk-2CE3TQVY.mjs';
8
8
  import React from 'react';
9
9
  import { StyleSheet, View, Platform, Image, TouchableOpacity, Text } from 'react-native';
@@ -1,5 +1,5 @@
1
1
  import { selectionAsync } from './chunk-EJ7ZPXOH.mjs';
2
- import { useTheme } from './chunk-SOYNZDVY.mjs';
2
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
3
3
  import { s, mvs, ms } from './chunk-2CE3TQVY.mjs';
4
4
  import React from 'react';
5
5
  import { StyleSheet, View, TouchableOpacity, Text } from 'react-native';
@@ -1,7 +1,7 @@
1
1
  import { PressableCard } from './chunk-3DKJ2GIC.mjs';
2
2
  import { impactLight } from './chunk-EJ7ZPXOH.mjs';
3
3
  import { RADIUS } from './chunk-QY3X2UYR.mjs';
4
- import { useTheme } from './chunk-SOYNZDVY.mjs';
4
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
5
5
  import { vs, s, mvs, ms } from './chunk-2CE3TQVY.mjs';
6
6
  import React from 'react';
7
7
  import { StyleSheet, View, Text } from 'react-native';
@@ -1,5 +1,5 @@
1
1
  import { RADIUS } from './chunk-QY3X2UYR.mjs';
2
- import { useTheme } from './chunk-SOYNZDVY.mjs';
2
+ import { useTheme } from './chunk-YTXRIXNZ.mjs';
3
3
  import { vs, s } from './chunk-2CE3TQVY.mjs';
4
4
  import React from 'react';
5
5
  import { StyleSheet, View, Text } from 'react-native';