@retray-dev/ui-kit 10.1.0 → 12.1.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 (192) hide show
  1. package/COMPONENTS.md +419 -38
  2. package/README.md +14 -5
  3. package/dist/Accordion.js +1 -1
  4. package/dist/Accordion.mjs +3 -3
  5. package/dist/AlertBanner.js +1 -1
  6. package/dist/AlertBanner.mjs +3 -3
  7. package/dist/AppHeader.js +1 -1
  8. package/dist/AppHeader.mjs +4 -4
  9. package/dist/Avatar.mjs +2 -2
  10. package/dist/Badge.js +1 -1
  11. package/dist/Badge.mjs +3 -3
  12. package/dist/Button.js +1 -1
  13. package/dist/Button.mjs +3 -3
  14. package/dist/Card.mjs +2 -2
  15. package/dist/CategoryStrip.js +1 -1
  16. package/dist/CategoryStrip.mjs +3 -3
  17. package/dist/Checkbox.mjs +2 -2
  18. package/dist/Chip.js +1 -1
  19. package/dist/Chip.mjs +3 -3
  20. package/dist/ConfirmDialog.d.mts +1 -6
  21. package/dist/ConfirmDialog.d.ts +1 -6
  22. package/dist/ConfirmDialog.js +30 -24
  23. package/dist/ConfirmDialog.mjs +4 -4
  24. package/dist/CurrencyDisplay.mjs +2 -2
  25. package/dist/CurrencyInput.d.mts +3 -8
  26. package/dist/CurrencyInput.d.ts +3 -8
  27. package/dist/CurrencyInput.js +4 -2
  28. package/dist/CurrencyInput.mjs +4 -4
  29. package/dist/DetailRow.d.mts +1 -1
  30. package/dist/DetailRow.d.ts +1 -1
  31. package/dist/DetailRow.js +1 -1
  32. package/dist/DetailRow.mjs +3 -3
  33. package/dist/EmptyState.js +1 -1
  34. package/dist/EmptyState.mjs +4 -4
  35. package/dist/ErrorBoundary.js +1 -1
  36. package/dist/ErrorBoundary.mjs +3 -3
  37. package/dist/Form.mjs +2 -2
  38. package/dist/IconButton.js +1 -1
  39. package/dist/IconButton.mjs +3 -3
  40. package/dist/IconPicker.d.mts +17 -0
  41. package/dist/IconPicker.d.ts +17 -0
  42. package/dist/IconPicker.js +1424 -0
  43. package/dist/IconPicker.mjs +8 -0
  44. package/dist/ImageUpload.d.mts +3 -1
  45. package/dist/ImageUpload.d.ts +3 -1
  46. package/dist/ImageUpload.js +28 -10
  47. package/dist/ImageUpload.mjs +3 -3
  48. package/dist/ImageViewer.js +1 -1
  49. package/dist/ImageViewer.mjs +5 -5
  50. package/dist/Input.js +1 -1
  51. package/dist/Input.mjs +3 -3
  52. package/dist/LabelValue.js +1 -1
  53. package/dist/LabelValue.mjs +3 -3
  54. package/dist/ListGroup.mjs +2 -2
  55. package/dist/ListItem.d.mts +7 -7
  56. package/dist/ListItem.d.ts +7 -7
  57. package/dist/ListItem.js +13 -8
  58. package/dist/ListItem.mjs +3 -3
  59. package/dist/MediaCard.js +1 -1
  60. package/dist/MediaCard.mjs +3 -3
  61. package/dist/MenuGroup.mjs +2 -2
  62. package/dist/MenuItem.js +1 -1
  63. package/dist/MenuItem.mjs +3 -3
  64. package/dist/MonthPicker.mjs +2 -2
  65. package/dist/NumberStepper.d.mts +19 -0
  66. package/dist/NumberStepper.d.ts +19 -0
  67. package/dist/NumberStepper.js +410 -0
  68. package/dist/NumberStepper.mjs +9 -0
  69. package/dist/PagerDots.js +1 -1
  70. package/dist/PagerDots.mjs +3 -3
  71. package/dist/Pressable.d.mts +15 -7
  72. package/dist/Pressable.d.ts +15 -7
  73. package/dist/Pressable.js +7 -3
  74. package/dist/Pressable.mjs +1 -1
  75. package/dist/PricingCard.js +1 -1
  76. package/dist/PricingCard.mjs +5 -5
  77. package/dist/Progress.mjs +2 -2
  78. package/dist/RadioGroup.mjs +2 -2
  79. package/dist/RetrayProvider.mjs +3 -3
  80. package/dist/Select.mjs +2 -2
  81. package/dist/SelectableGrid.js +1 -1
  82. package/dist/SelectableGrid.mjs +3 -3
  83. package/dist/Separator.mjs +2 -2
  84. package/dist/Sheet.d.mts +4 -46
  85. package/dist/Sheet.d.ts +4 -46
  86. package/dist/Sheet.js +46 -114
  87. package/dist/Sheet.mjs +2 -3
  88. package/dist/SheetSelect.js +1 -1
  89. package/dist/SheetSelect.mjs +3 -3
  90. package/dist/Skeleton.mjs +2 -2
  91. package/dist/Slider.mjs +2 -2
  92. package/dist/Spinner.mjs +2 -2
  93. package/dist/Stats.d.mts +30 -0
  94. package/dist/Stats.d.ts +30 -0
  95. package/dist/Stats.js +429 -0
  96. package/dist/Stats.mjs +9 -0
  97. package/dist/Switch.mjs +2 -2
  98. package/dist/TabBar.js +1 -1
  99. package/dist/TabBar.mjs +3 -3
  100. package/dist/Tabs.mjs +2 -2
  101. package/dist/Text.d.mts +3 -1
  102. package/dist/Text.d.ts +3 -1
  103. package/dist/Text.js +3 -3
  104. package/dist/Text.mjs +2 -2
  105. package/dist/Textarea.js +1 -1
  106. package/dist/Textarea.mjs +3 -3
  107. package/dist/Toast.mjs +2 -2
  108. package/dist/Toggle.js +1 -1
  109. package/dist/Toggle.mjs +3 -3
  110. package/dist/{chunk-DJ7RN37L.mjs → chunk-265G6A46.mjs} +2 -2
  111. package/dist/{chunk-WOEYDUJZ.mjs → chunk-2A2LEFZG.mjs} +2 -2
  112. package/dist/{chunk-ID72TK46.mjs → chunk-2CBQKU7H.mjs} +1 -1
  113. package/dist/{chunk-OB4JUQ3O.mjs → chunk-2I2AYECM.mjs} +1 -1
  114. package/dist/{chunk-WJLKJMKR.mjs → chunk-357YO24D.mjs} +4 -4
  115. package/dist/{chunk-GQYFLP3D.mjs → chunk-3GEYJ7I5.mjs} +1 -1
  116. package/dist/{chunk-AV4EMIRH.mjs → chunk-3N2M3WZL.mjs} +1 -1
  117. package/dist/{chunk-TERDKCLE.mjs → chunk-3UYAZ7I4.mjs} +2 -2
  118. package/dist/{chunk-JMOZEC77.mjs → chunk-4WFMPFZB.mjs} +1 -1
  119. package/dist/chunk-5OLNXP3S.mjs +144 -0
  120. package/dist/{chunk-6OAZJ577.mjs → chunk-7HSILTC4.mjs} +3 -3
  121. package/dist/{chunk-IRRY3CRZ.mjs → chunk-AKM4EPOT.mjs} +1 -1
  122. package/dist/{chunk-VGTDN7SW.mjs → chunk-AQEVCEXV.mjs} +2 -2
  123. package/dist/{chunk-WBOOUHSS.mjs → chunk-BCWEHE34.mjs} +1 -1
  124. package/dist/{chunk-AJ7ZDNBT.mjs → chunk-BOVUP27T.mjs} +1 -1
  125. package/dist/{chunk-BRKYVJVV.mjs → chunk-BQZE3HAW.mjs} +1 -1
  126. package/dist/{chunk-MLF3EZFW.mjs → chunk-D3Y2T42P.mjs} +2 -2
  127. package/dist/{chunk-3U4SSNWP.mjs → chunk-DF6DU42P.mjs} +2 -2
  128. package/dist/{chunk-ZJKGQMYH.mjs → chunk-DI7CBDL6.mjs} +2 -2
  129. package/dist/{chunk-2TFTAWVJ.mjs → chunk-DOGIPOF5.mjs} +2 -2
  130. package/dist/{chunk-MBMXYJJV.mjs → chunk-E7NEHHXV.mjs} +7 -3
  131. package/dist/{chunk-MX6HRKMI.mjs → chunk-EFLFRAHD.mjs} +1 -1
  132. package/dist/{chunk-SOYNZDVY.mjs → chunk-EMUWGDWC.mjs} +6 -1
  133. package/dist/{chunk-4I7D47FH.mjs → chunk-F4V6XLP4.mjs} +4 -4
  134. package/dist/{chunk-UREA2GYY.mjs → chunk-FA2KMTH5.mjs} +2 -2
  135. package/dist/{chunk-Y2NS74WS.mjs → chunk-FFTYLPSB.mjs} +46 -98
  136. package/dist/{chunk-OHBNABL5.mjs → chunk-FUVYSVGR.mjs} +14 -9
  137. package/dist/{chunk-KIHCWCWL.mjs → chunk-FVTVCJAH.mjs} +2 -2
  138. package/dist/{chunk-Y4GL2MHX.mjs → chunk-GK4VRMNE.mjs} +30 -12
  139. package/dist/{chunk-6Q64UFIA.mjs → chunk-HJ46DTJE.mjs} +1 -1
  140. package/dist/{chunk-WF2XDFRK.mjs → chunk-HLMPMUK2.mjs} +1 -1
  141. package/dist/{chunk-GD6KXMG5.mjs → chunk-I4V5XZPS.mjs} +1 -1
  142. package/dist/{chunk-AZJF2BLK.mjs → chunk-ISY26JQJ.mjs} +2 -2
  143. package/dist/{chunk-X4G6APW6.mjs → chunk-J6Q2YJEV.mjs} +1 -1
  144. package/dist/{chunk-KZL5VTYK.mjs → chunk-JCZQOY4O.mjs} +31 -24
  145. package/dist/{chunk-CZCQZHG6.mjs → chunk-JNVAIDLK.mjs} +2 -2
  146. package/dist/{chunk-SOA2Z4RB.mjs → chunk-JULSIZDM.mjs} +1 -1
  147. package/dist/{chunk-T7XZ7H7Y.mjs → chunk-KA7LTET3.mjs} +17 -3
  148. package/dist/chunk-KHYX4IOM.mjs +1114 -0
  149. package/dist/{chunk-LXJIIOYQ.mjs → chunk-LRM4AVYY.mjs} +2 -2
  150. package/dist/{chunk-VQ57HWPL.mjs → chunk-MYZ2EDYU.mjs} +2 -2
  151. package/dist/chunk-N4ZPVCJH.mjs +126 -0
  152. package/dist/{chunk-NA7PARID.mjs → chunk-NXI4YDZ2.mjs} +2 -2
  153. package/dist/{chunk-4K625MVM.mjs → chunk-OULVKTWL.mjs} +2 -2
  154. package/dist/{chunk-A4MDAP7G.mjs → chunk-P64WHW4A.mjs} +2 -2
  155. package/dist/{chunk-URI2WBIV.mjs → chunk-P73V2EKS.mjs} +2 -2
  156. package/dist/{chunk-ZUR7AU5R.mjs → chunk-PGERH3P7.mjs} +2 -2
  157. package/dist/{chunk-2UYENBLV.mjs → chunk-QSFV2P7O.mjs} +1 -1
  158. package/dist/{chunk-JT7HKXRB.mjs → chunk-S3KJCPEJ.mjs} +1 -1
  159. package/dist/{chunk-6MKGPAR2.mjs → chunk-V6NFJXKO.mjs} +2 -2
  160. package/dist/{chunk-A3A6KNQN.mjs → chunk-WOEWGSTU.mjs} +1 -1
  161. package/dist/{chunk-JUXSWN54.mjs → chunk-X26S5EVZ.mjs} +4 -2
  162. package/dist/{chunk-YFZ3ELX5.mjs → chunk-XBAGGKLW.mjs} +2 -2
  163. package/dist/{chunk-JB67UOB5.mjs → chunk-ZHMSAYLT.mjs} +2 -2
  164. package/dist/fonts.d.mts +1 -7
  165. package/dist/fonts.d.ts +1 -7
  166. package/dist/fonts.js +0 -2
  167. package/dist/fonts.mjs +1 -2
  168. package/dist/index.d.mts +7 -1
  169. package/dist/index.d.ts +7 -1
  170. package/dist/index.js +1831 -475
  171. package/dist/index.mjs +54 -51
  172. package/package.json +3 -3
  173. package/src/components/ConfirmDialog/ConfirmDialog.tsx +39 -30
  174. package/src/components/CurrencyInput/CurrencyInput.tsx +4 -7
  175. package/src/components/DetailRow/DetailRow.tsx +1 -1
  176. package/src/components/IconPicker/IconPicker.tsx +395 -0
  177. package/src/components/IconPicker/index.ts +1 -0
  178. package/src/components/ImageUpload/ImageUpload.tsx +34 -12
  179. package/src/components/ListItem/ListItem.tsx +43 -28
  180. package/src/components/NumberStepper/NumberStepper.tsx +147 -0
  181. package/src/components/NumberStepper/index.ts +1 -0
  182. package/src/components/Pressable/Pressable.tsx +20 -8
  183. package/src/components/Sheet/Sheet.tsx +64 -172
  184. package/src/components/Stats/Stats.tsx +226 -0
  185. package/src/components/Stats/index.ts +2 -0
  186. package/src/components/Text/Text.tsx +4 -2
  187. package/src/fonts.ts +0 -7
  188. package/src/index.ts +7 -1
  189. package/src/theme/colorUtils.ts +9 -0
  190. package/src/utils/curatedIcons.ts +849 -0
  191. package/src/utils/fontGuard.ts +2 -1
  192. package/src/utils/icons.ts +20 -2
@@ -0,0 +1,1424 @@
1
+ 'use strict';
2
+
3
+ var React4 = require('react');
4
+ var reactNative = require('react-native');
5
+ var reactNativeGestureHandler = require('react-native-gesture-handler');
6
+ var bottomSheet = require('@gorhom/bottom-sheet');
7
+ var reactNativeSafeAreaContext = require('react-native-safe-area-context');
8
+ var AntDesign = require('@expo/vector-icons/AntDesign');
9
+ var Entypo = require('@expo/vector-icons/Entypo');
10
+ var Feather = require('@expo/vector-icons/Feather');
11
+ var FontAwesome5 = require('@expo/vector-icons/FontAwesome5');
12
+ var MaterialIcons = require('@expo/vector-icons/MaterialIcons');
13
+ var Ionicons = require('@expo/vector-icons/Ionicons');
14
+ var reactNativeSizeMatters = require('react-native-size-matters');
15
+
16
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
17
+
18
+ var React4__default = /*#__PURE__*/_interopDefault(React4);
19
+ var AntDesign__default = /*#__PURE__*/_interopDefault(AntDesign);
20
+ var Entypo__default = /*#__PURE__*/_interopDefault(Entypo);
21
+ var Feather__default = /*#__PURE__*/_interopDefault(Feather);
22
+ var FontAwesome5__default = /*#__PURE__*/_interopDefault(FontAwesome5);
23
+ var MaterialIcons__default = /*#__PURE__*/_interopDefault(MaterialIcons);
24
+ var Ionicons__default = /*#__PURE__*/_interopDefault(Ionicons);
25
+
26
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
27
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
28
+ }) : x)(function(x) {
29
+ if (typeof require !== "undefined") return require.apply(this, arguments);
30
+ throw Error('Dynamic require of "' + x + '" is not supported');
31
+ });
32
+
33
+ // src/theme/colorUtils.ts
34
+ function hexToRgb(hex) {
35
+ const clean = hex.replace("#", "");
36
+ const full = clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean;
37
+ if (full.length !== 6) return null;
38
+ return {
39
+ r: parseInt(full.slice(0, 2), 16),
40
+ g: parseInt(full.slice(2, 4), 16),
41
+ b: parseInt(full.slice(4, 6), 16)
42
+ };
43
+ }
44
+ function componentToHex(c) {
45
+ return Math.round(Math.max(0, Math.min(255, c))).toString(16).padStart(2, "0");
46
+ }
47
+ function rgbToHex(r, g, b) {
48
+ return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`;
49
+ }
50
+ function withAlphaOnWhite(hex, alpha) {
51
+ const rgb = hexToRgb(hex);
52
+ if (!rgb) return hex;
53
+ const r = rgb.r * alpha + 255 * (1 - alpha);
54
+ const g = rgb.g * alpha + 255 * (1 - alpha);
55
+ const b = rgb.b * alpha + 255 * (1 - alpha);
56
+ return rgbToHex(r, g, b);
57
+ }
58
+ function withAlphaOnDark(hex, alpha, bgHex = "#0f0f0f") {
59
+ const rgb = hexToRgb(hex);
60
+ const bg = hexToRgb(bgHex);
61
+ if (!rgb || !bg) return hex;
62
+ const r = rgb.r * alpha + bg.r * (1 - alpha);
63
+ const g = rgb.g * alpha + bg.g * (1 - alpha);
64
+ const b = rgb.b * alpha + bg.b * (1 - alpha);
65
+ return rgbToHex(r, g, b);
66
+ }
67
+ function mixWithBackground(fgHex, bgHex, opacity) {
68
+ const fg = hexToRgb(fgHex);
69
+ const bg = hexToRgb(bgHex);
70
+ if (!fg || !bg) return fgHex;
71
+ const r = fg.r * opacity + bg.r * (1 - opacity);
72
+ const g = fg.g * opacity + bg.g * (1 - opacity);
73
+ const b = fg.b * opacity + bg.b * (1 - opacity);
74
+ return rgbToHex(r, g, b);
75
+ }
76
+ function lighten(hex, amount) {
77
+ return withAlphaOnWhite(hex, 1 - amount);
78
+ }
79
+ function darken(hex, amount) {
80
+ const rgb = hexToRgb(hex);
81
+ if (!rgb) return hex;
82
+ return rgbToHex(rgb.r * (1 - amount), rgb.g * (1 - amount), rgb.b * (1 - amount));
83
+ }
84
+
85
+ // src/theme/colors.ts
86
+ var defaultLight = {
87
+ background: "#ffffff",
88
+ foreground: "#1a1a1a",
89
+ card: "#ffffff",
90
+ primary: "#1a1a1a",
91
+ primaryForeground: "#ffffff",
92
+ // AUDIT FIX: brand accent — was undefined; falls back to primary when omitted
93
+ accent: "#d4561d",
94
+ accentForeground: "#ffffff",
95
+ border: "#dddddd",
96
+ // AUDIT FIX: was #e53935 (4.22:1 on white — fails AA); #c72828 = 5.59:1 ✓
97
+ destructive: "#c72828",
98
+ destructiveForeground: "#ffffff",
99
+ success: "#1a7a45",
100
+ successForeground: "#ffffff",
101
+ // AUDIT FIX: was #e67e00 (2.86:1 — severe fail); #9a5200 = 5.86:1 ✓ AAA-near
102
+ warning: "#9a5200",
103
+ warningForeground: "#ffffff"
104
+ };
105
+ function deriveColors(t, scheme) {
106
+ const dark = scheme === "dark";
107
+ const bg = t.background;
108
+ const foregroundSubtle = mixWithBackground(t.foreground, bg, 0.7);
109
+ const foregroundMuted = mixWithBackground(t.foreground, bg, 0.62);
110
+ const surface = dark ? lighten(bg, -0.06) : darken(bg, 0.04);
111
+ const surfaceStrong = dark ? lighten(bg, -0.12) : darken(bg, 0.08);
112
+ const destructiveTint = dark ? withAlphaOnDark(t.destructive, 0.15, bg) : withAlphaOnWhite(t.destructive, 0.08);
113
+ const destructiveBorder = dark ? withAlphaOnDark(t.destructive, 0.45, bg) : withAlphaOnWhite(t.destructive, 0.3);
114
+ const successTint = dark ? withAlphaOnDark(t.success, 0.15, bg) : withAlphaOnWhite(t.success, 0.08);
115
+ const successBorder = dark ? withAlphaOnDark(t.success, 0.45, bg) : withAlphaOnWhite(t.success, 0.3);
116
+ const warningTint = dark ? withAlphaOnDark(t.warning, 0.15, bg) : withAlphaOnWhite(t.warning, 0.08);
117
+ const warningBorder = dark ? withAlphaOnDark(t.warning, 0.45, bg) : withAlphaOnWhite(t.warning, 0.3);
118
+ return {
119
+ ...t,
120
+ foregroundSubtle,
121
+ foregroundMuted,
122
+ surface,
123
+ surfaceStrong,
124
+ destructiveTint,
125
+ destructiveBorder,
126
+ successTint,
127
+ successBorder,
128
+ warningTint,
129
+ warningBorder,
130
+ overlay: t.overlay ?? "rgba(0,0,0,0.45)",
131
+ accentResolved: t.accent ?? t.primary,
132
+ accentForegroundResolved: t.accentForeground ?? t.primaryForeground,
133
+ ring: t.accent ?? t.primary,
134
+ input: t.border,
135
+ separator: dark ? lighten(t.border, 0.22) : darken(t.border, 0.16)
136
+ };
137
+ }
138
+
139
+ // src/theme/ThemeProvider.tsx
140
+ var ThemeContext = React4.createContext({
141
+ colors: deriveColors(defaultLight, "light"),
142
+ colorScheme: "light"
143
+ });
144
+ function useTheme() {
145
+ const context = React4.useContext(ThemeContext);
146
+ if (!context) {
147
+ throw new Error("useTheme must be used within a ThemeProvider");
148
+ }
149
+ return context;
150
+ }
151
+ var glyphMapOf = (mod) => mod.glyphMap ?? {};
152
+ var ALL_FAMILIES = [
153
+ { name: "Ionicons", component: Ionicons__default.default, getGlyphMap: () => glyphMapOf(Ionicons__default.default) },
154
+ { name: "MaterialIcons", component: MaterialIcons__default.default, getGlyphMap: () => glyphMapOf(MaterialIcons__default.default) },
155
+ { name: "FontAwesome5", component: FontAwesome5__default.default, getGlyphMap: () => glyphMapOf(FontAwesome5__default.default) },
156
+ { name: "Entypo", component: Entypo__default.default, getGlyphMap: () => glyphMapOf(Entypo__default.default) },
157
+ { name: "AntDesign", component: AntDesign__default.default, getGlyphMap: () => glyphMapOf(AntDesign__default.default) },
158
+ { name: "Feather", component: Feather__default.default, getGlyphMap: () => glyphMapOf(Feather__default.default) }
159
+ ];
160
+ var activeFamilies = ALL_FAMILIES;
161
+ var resolvedCache = null;
162
+ function buildCache(families) {
163
+ const cache = /* @__PURE__ */ new Map();
164
+ for (const family of activeFamilies) {
165
+ const glyphMap = family.getGlyphMap();
166
+ for (const iconName of Object.keys(glyphMap)) {
167
+ cache.set(iconName, family);
168
+ }
169
+ }
170
+ return cache;
171
+ }
172
+ function resolveFamily(name) {
173
+ if (!resolvedCache) {
174
+ resolvedCache = buildCache();
175
+ }
176
+ return resolvedCache.get(name) ?? null;
177
+ }
178
+ function Icon({ name, size, color, family }) {
179
+ let resolved = null;
180
+ if (family) {
181
+ resolved = ALL_FAMILIES.find((f) => f.name === family) ?? null;
182
+ } else {
183
+ resolved = resolveFamily(name);
184
+ }
185
+ if (!resolved) return null;
186
+ const Component = resolved.component;
187
+ return React4__default.default.createElement(Component, { name, size, color });
188
+ }
189
+ function renderIcon(name, size, color) {
190
+ return React4__default.default.createElement(Icon, { name, size, color });
191
+ }
192
+
193
+ // src/utils/curatedIcons.ts
194
+ var CURATED_ICONS = [
195
+ // ─── Food ────────────────────────────────────────────────────────────────────
196
+ {
197
+ name: "food",
198
+ label: "Food",
199
+ labelEs: "Comida",
200
+ categoryIcon: "coffee",
201
+ icons: [
202
+ // Bebidas
203
+ "beer-outline",
204
+ "wine-outline",
205
+ "cafe-outline",
206
+ "water-outline",
207
+ "coffee",
208
+ // Comida
209
+ "pizza-outline",
210
+ "fast-food-outline",
211
+ "fish-outline",
212
+ "ice-cream-outline",
213
+ "egg-outline",
214
+ "nutrition-outline",
215
+ // Servicio y operación
216
+ "restaurant-outline",
217
+ "server-outline",
218
+ "menu-outline",
219
+ "basket-outline",
220
+ "receipt-outline",
221
+ "pricetag-outline",
222
+ "pricetags-outline",
223
+ "reorder-four-outline",
224
+ "reorder-three-outline",
225
+ "cart-outline",
226
+ "cash-outline",
227
+ "wallet-outline",
228
+ "storefront-outline",
229
+ // Delivery / pedidos
230
+ "truck",
231
+ "package",
232
+ "shopping-bag",
233
+ "shopping-cart",
234
+ // Ubicación y reserva
235
+ "map-pin",
236
+ "home",
237
+ "calendar",
238
+ "clock",
239
+ // Experiencia
240
+ "star",
241
+ "heart",
242
+ "bookmark",
243
+ "thumbs-up",
244
+ "check",
245
+ "gift"
246
+ ]
247
+ },
248
+ // ─── Sports ──────────────────────────────────────────────────────────────────
249
+ {
250
+ name: "sports",
251
+ label: "Sports",
252
+ labelEs: "Deportes",
253
+ categoryIcon: "trophy-outline",
254
+ icons: [
255
+ // Deportes
256
+ "american-football-outline",
257
+ "baseball-outline",
258
+ "basketball-outline",
259
+ "bicycle-outline",
260
+ "football-outline",
261
+ "tennisball-outline",
262
+ "golf-outline",
263
+ "fitness-outline",
264
+ "car-sport-outline",
265
+ "game-controller-outline",
266
+ // Competición y logros
267
+ "trophy-outline",
268
+ "medal-outline",
269
+ "award",
270
+ "target",
271
+ "flag",
272
+ "crosshair",
273
+ // Outdoor
274
+ "compass-outline",
275
+ "map-outline",
276
+ "trail-sign-outline",
277
+ "bonfire-outline",
278
+ "snow-outline",
279
+ "flame-outline",
280
+ "sun",
281
+ "droplet",
282
+ "wind",
283
+ "map",
284
+ "map-pin",
285
+ "navigation",
286
+ "navigation-2",
287
+ // Rendimiento y métricas
288
+ "stats-chart-outline",
289
+ "trending-up-outline",
290
+ "trending-down-outline",
291
+ "bar-chart-outline",
292
+ "pie-chart-outline",
293
+ "analytics-outline",
294
+ "activity",
295
+ "zap",
296
+ "watch",
297
+ "trending-up",
298
+ "trending-down",
299
+ "bar-chart-2",
300
+ "clock",
301
+ "calendar"
302
+ ]
303
+ },
304
+ // ─── Business ────────────────────────────────────────────────────────────────
305
+ {
306
+ name: "business",
307
+ label: "Business",
308
+ labelEs: "Negocios",
309
+ categoryIcon: "briefcase",
310
+ icons: [
311
+ // Empresa
312
+ "briefcase",
313
+ "users",
314
+ "user",
315
+ "user-plus",
316
+ "user-check",
317
+ "user-x",
318
+ "briefcase-outline",
319
+ "business-outline",
320
+ "id-card-outline",
321
+ // Comercio y operación
322
+ "shopping-cart",
323
+ "shopping-bag",
324
+ "credit-card",
325
+ "dollar-sign",
326
+ "percent",
327
+ "tag",
328
+ "gift",
329
+ "cart-outline",
330
+ "cash-outline",
331
+ "wallet-outline",
332
+ "storefront-outline",
333
+ "pricetag-outline",
334
+ "pricetags-outline",
335
+ "receipt-outline",
336
+ "card-outline",
337
+ // Logística
338
+ "truck",
339
+ "package",
340
+ // Documentos
341
+ "file",
342
+ "file-text",
343
+ "file-plus",
344
+ "folder",
345
+ "paperclip",
346
+ "document-outline",
347
+ "document-text-outline",
348
+ "documents-outline",
349
+ "folder-outline",
350
+ // Comunicación de negocio
351
+ "mail",
352
+ "phone",
353
+ "phone-call",
354
+ "send",
355
+ "message-square",
356
+ "mail-outline",
357
+ // Análisis
358
+ "bar-chart",
359
+ "bar-chart-2",
360
+ "pie-chart",
361
+ "trending-up",
362
+ "trending-down",
363
+ "activity",
364
+ "globe"
365
+ ]
366
+ },
367
+ // ─── Objects ─────────────────────────────────────────────────────────────────
368
+ {
369
+ name: "objects",
370
+ label: "Objects",
371
+ labelEs: "Objetos",
372
+ categoryIcon: "package",
373
+ icons: [
374
+ // Archivos y carpetas
375
+ "file",
376
+ "file-text",
377
+ "file-plus",
378
+ "file-minus",
379
+ "folder",
380
+ "folder-plus",
381
+ "folder-minus",
382
+ "archive",
383
+ "save",
384
+ "paperclip",
385
+ "document-outline",
386
+ "document-text-outline",
387
+ "documents-outline",
388
+ "folder-outline",
389
+ "folder-open-outline",
390
+ "file-tray-outline",
391
+ "file-tray-full-outline",
392
+ "file-tray-stacked-outline",
393
+ "archive-outline",
394
+ "save-outline",
395
+ // Seguridad
396
+ "lock",
397
+ "unlock",
398
+ "key",
399
+ "shield",
400
+ "shield-off",
401
+ "lock-closed-outline",
402
+ "lock-open-outline",
403
+ "key-outline",
404
+ "shield-outline",
405
+ "shield-checkmark-outline",
406
+ // Dispositivos
407
+ "monitor",
408
+ "tablet",
409
+ "smartphone",
410
+ "tv",
411
+ "server",
412
+ "database",
413
+ "hard-drive",
414
+ "cpu",
415
+ "radio",
416
+ "laptop-outline",
417
+ "phone-portrait-outline",
418
+ "phone-landscape-outline",
419
+ "tablet-landscape-outline",
420
+ "tablet-portrait-outline",
421
+ "tv-outline",
422
+ "server-outline",
423
+ "hardware-chip-outline",
424
+ "watch-outline"
425
+ ]
426
+ },
427
+ // ─── Status ──────────────────────────────────────────────────────────────────
428
+ {
429
+ name: "status",
430
+ label: "Status",
431
+ labelEs: "Estado",
432
+ categoryIcon: "alert-circle",
433
+ icons: [
434
+ // Alertas
435
+ "alert-circle",
436
+ "alert-triangle",
437
+ "alert-octagon",
438
+ "info",
439
+ "help-circle",
440
+ "alert-circle-outline",
441
+ "alert-outline",
442
+ "information-circle-outline",
443
+ "help-circle-outline",
444
+ // Notificaciones
445
+ "bell",
446
+ "bell-off",
447
+ "notifications-outline",
448
+ "notifications-off-outline",
449
+ "notifications-circle-outline",
450
+ // Visibilidad
451
+ "eye",
452
+ "eye-off",
453
+ "eye-outline",
454
+ "eye-off-outline",
455
+ // Indicadores
456
+ "flag",
457
+ "zap",
458
+ "zap-off",
459
+ "loader",
460
+ "activity",
461
+ "flash-outline",
462
+ "bulb-outline",
463
+ // Éxito / error / advertencia
464
+ "check",
465
+ "check-circle",
466
+ "x",
467
+ "x-circle",
468
+ "x-octagon",
469
+ "slash",
470
+ "plus-circle",
471
+ "minus-circle",
472
+ "checkmark-circle-outline",
473
+ "checkmark-done-circle-outline",
474
+ "close-circle-outline",
475
+ "add-circle-outline",
476
+ "remove-circle-outline",
477
+ // Estados de proceso
478
+ "play-circle",
479
+ "pause-circle",
480
+ "stop-circle",
481
+ "play-circle-outline",
482
+ "pause-circle-outline",
483
+ "stop-circle-outline"
484
+ ]
485
+ },
486
+ // ─── Actions ─────────────────────────────────────────────────────────────────
487
+ {
488
+ name: "actions",
489
+ label: "Actions",
490
+ labelEs: "Acciones",
491
+ categoryIcon: "edit-3",
492
+ icons: [
493
+ // Crear / añadir
494
+ "plus",
495
+ "plus-circle",
496
+ "plus-square",
497
+ "add-outline",
498
+ "add-circle-outline",
499
+ // Eliminar / quitar
500
+ "minus",
501
+ "minus-circle",
502
+ "minus-square",
503
+ "trash",
504
+ "trash-2",
505
+ "x",
506
+ "x-circle",
507
+ "x-square",
508
+ "x-octagon",
509
+ "slash",
510
+ "trash-outline",
511
+ "trash-bin-outline",
512
+ "remove-outline",
513
+ "remove-circle-outline",
514
+ "close-circle-outline",
515
+ "backspace-outline",
516
+ "cut-outline",
517
+ // Confirmar
518
+ "check",
519
+ "check-circle",
520
+ "check-square",
521
+ "checkmark-circle-outline",
522
+ // Editar
523
+ "edit",
524
+ "edit-2",
525
+ "edit-3",
526
+ "copy",
527
+ "clipboard",
528
+ "scissors",
529
+ "create-outline",
530
+ "pencil-outline",
531
+ "duplicate-outline",
532
+ "copy-outline",
533
+ "clipboard-outline",
534
+ // Mover datos
535
+ "download",
536
+ "download-cloud",
537
+ "upload",
538
+ "upload-cloud",
539
+ "download-outline",
540
+ "cloud-download-outline",
541
+ "cloud-upload-outline"
542
+ ]
543
+ },
544
+ // ─── Communication ───────────────────────────────────────────────────────────
545
+ {
546
+ name: "communication",
547
+ label: "Communication",
548
+ labelEs: "Comunicaci\xF3n",
549
+ categoryIcon: "message-circle",
550
+ icons: [
551
+ // Mensajería
552
+ "message-circle",
553
+ "message-square",
554
+ "send",
555
+ "mail",
556
+ "inbox",
557
+ "at-sign",
558
+ "mail-outline",
559
+ "mail-open-outline",
560
+ "mail-unread-outline",
561
+ "chatbubble-outline",
562
+ "chatbubble-ellipses-outline",
563
+ "chatbubbles-outline",
564
+ "send-outline",
565
+ "attach-outline",
566
+ "at-outline",
567
+ "at-circle-outline",
568
+ // Llamadas
569
+ "phone",
570
+ "phone-call",
571
+ "phone-incoming",
572
+ "phone-outgoing",
573
+ "phone-missed",
574
+ "phone-off",
575
+ "phone-forwarded",
576
+ "voicemail",
577
+ "call-outline",
578
+ "phone-portrait-outline",
579
+ "phone-landscape-outline",
580
+ // Personas
581
+ "user",
582
+ "user-plus",
583
+ "user-minus",
584
+ "user-check",
585
+ "user-x",
586
+ "users",
587
+ "person-outline",
588
+ "person-circle-outline",
589
+ "person-add-outline",
590
+ "person-remove-outline",
591
+ "people-outline",
592
+ "people-circle-outline",
593
+ // Reacciones
594
+ "smile",
595
+ "frown",
596
+ "meh",
597
+ "heart",
598
+ "thumbs-up",
599
+ "thumbs-down",
600
+ "happy-outline",
601
+ "sad-outline",
602
+ "heart-outline",
603
+ "thumbs-up-outline",
604
+ "thumbs-down-outline"
605
+ ]
606
+ },
607
+ // ─── Navigation ──────────────────────────────────────────────────────────────
608
+ {
609
+ name: "navigation",
610
+ label: "Navigation",
611
+ labelEs: "Navegaci\xF3n",
612
+ categoryIcon: "compass",
613
+ icons: [
614
+ // Flechas cardinales
615
+ "arrow-up",
616
+ "arrow-down",
617
+ "arrow-left",
618
+ "arrow-right",
619
+ "arrow-up-left",
620
+ "arrow-up-right",
621
+ "arrow-down-left",
622
+ "arrow-down-right",
623
+ "arrow-up-outline",
624
+ "arrow-down-outline",
625
+ "arrow-back-outline",
626
+ "arrow-forward-outline",
627
+ "arrow-undo-outline",
628
+ "arrow-redo-outline",
629
+ // Chevrones
630
+ "chevron-up",
631
+ "chevron-down",
632
+ "chevron-left",
633
+ "chevron-right",
634
+ "chevrons-up",
635
+ "chevrons-down",
636
+ "chevrons-left",
637
+ "chevrons-right",
638
+ "chevron-up-outline",
639
+ "chevron-down-outline",
640
+ "chevron-back-outline",
641
+ "chevron-forward-outline",
642
+ "chevron-collapse-outline",
643
+ "chevron-expand-outline",
644
+ // Esquinas
645
+ "corner-up-left",
646
+ "corner-up-right",
647
+ "corner-down-left",
648
+ "corner-down-right",
649
+ "corner-left-up",
650
+ "corner-left-down",
651
+ "corner-right-up",
652
+ "corner-right-down",
653
+ // Giro / refrescar
654
+ "refresh-cw",
655
+ "refresh-ccw",
656
+ "rotate-cw",
657
+ "rotate-ccw",
658
+ "refresh-outline",
659
+ "reload-outline",
660
+ // Orientación y mapa
661
+ "navigation",
662
+ "navigation-2",
663
+ "compass",
664
+ "map",
665
+ "map-pin",
666
+ "target",
667
+ "crosshair",
668
+ "home",
669
+ "anchor",
670
+ "compass-outline",
671
+ "map-outline",
672
+ "location-outline",
673
+ "navigate-outline",
674
+ "pin-outline",
675
+ "home-outline"
676
+ ]
677
+ },
678
+ // ─── Media ───────────────────────────────────────────────────────────────────
679
+ {
680
+ name: "media",
681
+ label: "Media",
682
+ labelEs: "Medios",
683
+ categoryIcon: "image",
684
+ icons: [
685
+ // Visual
686
+ "image",
687
+ "film",
688
+ "video",
689
+ "video-off",
690
+ "camera",
691
+ "camera-off",
692
+ "image-outline",
693
+ "images-outline",
694
+ "film-outline",
695
+ "videocam-outline",
696
+ "videocam-off-outline",
697
+ "camera-outline",
698
+ "camera-reverse-outline",
699
+ // Reproducción
700
+ "play",
701
+ "play-circle",
702
+ "pause",
703
+ "pause-circle",
704
+ "square",
705
+ "stop-circle",
706
+ "fast-forward",
707
+ "rewind",
708
+ "skip-forward",
709
+ "skip-back",
710
+ "repeat",
711
+ "shuffle",
712
+ "play-outline",
713
+ "pause-outline",
714
+ "play-circle-outline",
715
+ "pause-circle-outline",
716
+ "stop-circle-outline",
717
+ "play-back-outline",
718
+ "play-forward-outline",
719
+ "play-skip-back-outline",
720
+ "play-skip-forward-outline",
721
+ "repeat-outline",
722
+ "shuffle-outline",
723
+ // Audio
724
+ "music",
725
+ "headphones",
726
+ "speaker",
727
+ "volume",
728
+ "volume-1",
729
+ "volume-2",
730
+ "volume-x",
731
+ "mic",
732
+ "mic-off",
733
+ "mic-outline",
734
+ "mic-off-outline",
735
+ "mic-circle-outline",
736
+ "musical-note-outline",
737
+ "musical-notes-outline",
738
+ "volume-high-outline",
739
+ "volume-low-outline",
740
+ "volume-medium-outline",
741
+ "volume-mute-outline",
742
+ "volume-off-outline"
743
+ ]
744
+ },
745
+ // ─── Layout ──────────────────────────────────────────────────────────────────
746
+ {
747
+ name: "layout",
748
+ label: "Layout",
749
+ labelEs: "Dise\xF1o",
750
+ categoryIcon: "grid",
751
+ icons: [
752
+ // Estructura
753
+ "grid",
754
+ "columns",
755
+ "sidebar",
756
+ "layout",
757
+ "list",
758
+ "menu",
759
+ "table",
760
+ "trello",
761
+ "grid-outline",
762
+ "list-outline",
763
+ "menu-outline",
764
+ "layers-outline",
765
+ // Alineación
766
+ "align-left",
767
+ "align-center",
768
+ "align-right",
769
+ "align-justify",
770
+ // Tipografía
771
+ "bold",
772
+ "italic",
773
+ "underline",
774
+ "type",
775
+ "hash",
776
+ // Formas
777
+ "circle",
778
+ "square",
779
+ "triangle",
780
+ "hexagon",
781
+ "octagon",
782
+ "square-outline",
783
+ "triangle-outline",
784
+ "diamond-outline",
785
+ "shapes-outline",
786
+ // Herramientas de diseño
787
+ "pen-tool",
788
+ "crop",
789
+ "layers",
790
+ "filter",
791
+ "sliders",
792
+ "aperture",
793
+ "crop-outline",
794
+ "filter-outline",
795
+ "color-fill-outline",
796
+ "color-filter-outline",
797
+ "color-palette-outline",
798
+ "color-wand-outline",
799
+ "brush-outline",
800
+ // Edición
801
+ "edit",
802
+ "edit-2",
803
+ "edit-3",
804
+ "copy",
805
+ "trash",
806
+ "move",
807
+ "create-outline",
808
+ "pencil-outline",
809
+ "move-outline",
810
+ "resize-outline",
811
+ "duplicate-outline",
812
+ // Navegación UI
813
+ "more-horizontal",
814
+ "more-vertical",
815
+ "maximize",
816
+ "minimize",
817
+ "zoom-in",
818
+ "zoom-out",
819
+ "eye",
820
+ "eye-off",
821
+ "eye-outline",
822
+ "eye-off-outline",
823
+ "ellipsis-horizontal-circle-outline",
824
+ "ellipsis-vertical-circle-outline"
825
+ ]
826
+ },
827
+ // ─── Nature ──────────────────────────────────────────────────────────────────
828
+ {
829
+ name: "nature",
830
+ label: "Nature",
831
+ labelEs: "Naturaleza",
832
+ categoryIcon: "sunny-outline",
833
+ icons: [
834
+ // Sol, luna y estrellas
835
+ "sunny-outline",
836
+ "moon-outline",
837
+ "star-outline",
838
+ "star-half-outline",
839
+ "partly-sunny-outline",
840
+ "sun",
841
+ "moon",
842
+ "sunrise",
843
+ "sunset",
844
+ // Clima
845
+ "rainy-outline",
846
+ "thunderstorm-outline",
847
+ "snow-outline",
848
+ "cloudy-outline",
849
+ "cloudy-night-outline",
850
+ "cloud-outline",
851
+ "cloud-done-outline",
852
+ "cloud-download-outline",
853
+ "cloud-upload-outline",
854
+ "cloud-offline-outline",
855
+ "cloud-circle-outline",
856
+ "cloud",
857
+ "cloud-drizzle",
858
+ "cloud-lightning",
859
+ "cloud-rain",
860
+ "cloud-snow",
861
+ "cloud-off",
862
+ "umbrella-outline",
863
+ "thermometer-outline",
864
+ "droplet",
865
+ "wind",
866
+ // Agua y fuego
867
+ "water-outline",
868
+ "flame-outline",
869
+ "bonfire-outline",
870
+ "eyedrop-outline",
871
+ // Flora y fauna
872
+ "leaf-outline",
873
+ "flower-outline",
874
+ "bug-outline",
875
+ "fish-outline",
876
+ "paw-outline",
877
+ // Outdoor
878
+ "binoculars-outline",
879
+ "telescope-outline",
880
+ "compass-outline",
881
+ "map-outline",
882
+ "location-outline",
883
+ "flag-outline",
884
+ "trail-sign-outline",
885
+ "earth-outline",
886
+ "globe-outline",
887
+ "planet-outline",
888
+ "compass",
889
+ "map",
890
+ "map-pin",
891
+ "flag",
892
+ "navigation",
893
+ "navigation-2",
894
+ "target",
895
+ "crosshair",
896
+ "life-buoy"
897
+ ]
898
+ },
899
+ // ─── Brands ──────────────────────────────────────────────────────────────────
900
+ {
901
+ name: "brands",
902
+ label: "Brands",
903
+ labelEs: "Marcas",
904
+ categoryIcon: "globe",
905
+ icons: [
906
+ // Feather brand icons — outlined, consistent with the rest of the library
907
+ "github",
908
+ "gitlab",
909
+ "codepen",
910
+ "codesandbox",
911
+ "twitter",
912
+ "facebook",
913
+ "instagram",
914
+ "linkedin",
915
+ "youtube",
916
+ "dribbble",
917
+ "twitch",
918
+ "slack",
919
+ "figma",
920
+ "framer",
921
+ "chrome",
922
+ "rss",
923
+ // Filled / flat brand logos (FA5 brands) — kept in a second
924
+ // visual tier. Rendered as the brand's official silhouette.
925
+ // Visually consistent (all flat single-color) but heavier than the
926
+ // Feather outlined set above. Use these only when an outlined Feather
927
+ // version of the brand doesn't exist.
928
+ "reddit",
929
+ "tiktok",
930
+ "pinterest",
931
+ "whatsapp",
932
+ "discord",
933
+ "snapchat",
934
+ "telegram",
935
+ "viber",
936
+ "line",
937
+ "vimeo",
938
+ "tumblr",
939
+ "behance",
940
+ "medium",
941
+ "soundcloud",
942
+ "google",
943
+ "apple",
944
+ "android",
945
+ "windows",
946
+ "linux",
947
+ "amazon",
948
+ "paypal",
949
+ "stripe",
950
+ "shopify",
951
+ "dropbox",
952
+ "spotify",
953
+ "steam",
954
+ "atlassian",
955
+ "jira",
956
+ "confluence",
957
+ "bitbucket",
958
+ "jenkins",
959
+ "docker",
960
+ "aws",
961
+ "node",
962
+ "react",
963
+ "angular",
964
+ "wordpress",
965
+ "drupal",
966
+ "joomla",
967
+ "squarespace",
968
+ "wix",
969
+ "magento",
970
+ "terminal",
971
+ "pen-tool"
972
+ ]
973
+ }
974
+ ];
975
+ var ALL_CURATED_ICONS = [
976
+ ...new Set(CURATED_ICONS.flatMap((c) => c.icons))
977
+ ];
978
+ var _haptics = null;
979
+ var _hapticsLoaded = false;
980
+ async function getHaptics() {
981
+ if (reactNative.Platform.OS === "web") return null;
982
+ if (!_hapticsLoaded) {
983
+ _hapticsLoaded = true;
984
+ try {
985
+ _haptics = await import('expo-haptics');
986
+ } catch {
987
+ _haptics = null;
988
+ }
989
+ }
990
+ return _haptics;
991
+ }
992
+ var _pulsar = null;
993
+ var _pulsarChecked = false;
994
+ var _pulsarAvailable = false;
995
+ function isPulsarNativeRegistered() {
996
+ try {
997
+ const g = globalThis;
998
+ if (typeof g.__turboModuleProxy === "function") {
999
+ return g.__turboModuleProxy("RNPulsar") != null;
1000
+ }
1001
+ return reactNative.NativeModules?.RNPulsar != null;
1002
+ } catch {
1003
+ return false;
1004
+ }
1005
+ }
1006
+ function getPulsar() {
1007
+ if (reactNative.Platform.OS === "web") return null;
1008
+ if (!_pulsarChecked) {
1009
+ _pulsarChecked = true;
1010
+ try {
1011
+ if (isPulsarNativeRegistered()) {
1012
+ _pulsar = __require("react-native-pulsar");
1013
+ _pulsarAvailable = true;
1014
+ }
1015
+ } catch {
1016
+ _pulsar = null;
1017
+ _pulsarAvailable = false;
1018
+ }
1019
+ }
1020
+ return _pulsarAvailable ? _pulsar : null;
1021
+ }
1022
+ function selectionAsync() {
1023
+ if (reactNative.Platform.OS === "web") return;
1024
+ getHaptics().then((h) => {
1025
+ if (h) {
1026
+ h.selectionAsync();
1027
+ } else {
1028
+ getPulsar()?.Presets.System.selection();
1029
+ }
1030
+ });
1031
+ }
1032
+ function impactMedium() {
1033
+ if (reactNative.Platform.OS === "web") return;
1034
+ getHaptics().then((h) => {
1035
+ if (h) {
1036
+ h.impactAsync(h.ImpactFeedbackStyle.Medium);
1037
+ } else {
1038
+ getPulsar()?.Presets.System.impactMedium();
1039
+ }
1040
+ });
1041
+ }
1042
+ var isWeb = reactNative.Platform.OS === "web";
1043
+ var s = isWeb ? (n) => n : reactNativeSizeMatters.scale;
1044
+ var vs = isWeb ? (n) => n : reactNativeSizeMatters.verticalScale;
1045
+ var ms = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateScale;
1046
+ var mvs = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateVerticalScale;
1047
+
1048
+ // src/tokens.ts
1049
+ var RADIUS = {
1050
+ md: 14,
1051
+ full: 9999
1052
+ };
1053
+ var sizeMap = {
1054
+ sm: "small",
1055
+ md: "small",
1056
+ lg: "large"
1057
+ };
1058
+ var labelFontSize = {
1059
+ sm: ms(11),
1060
+ md: ms(13),
1061
+ lg: ms(14)
1062
+ };
1063
+ function Spinner({ size = "md", color, label, ...props }) {
1064
+ const { colors } = useTheme();
1065
+ const a11yLabel = label || "Loading";
1066
+ if (label) {
1067
+ return /* @__PURE__ */ React4__default.default.createElement(
1068
+ reactNative.View,
1069
+ {
1070
+ style: styles.wrapper,
1071
+ accessibilityRole: "progressbar",
1072
+ accessibilityLabel: a11yLabel,
1073
+ accessibilityState: { busy: true }
1074
+ },
1075
+ /* @__PURE__ */ React4__default.default.createElement(reactNative.ActivityIndicator, { size: sizeMap[size], color: color ?? colors.primary, ...props }),
1076
+ /* @__PURE__ */ React4__default.default.createElement(
1077
+ reactNative.Text,
1078
+ {
1079
+ style: [styles.label, { color: colors.foregroundMuted, fontSize: labelFontSize[size] }],
1080
+ allowFontScaling: true
1081
+ },
1082
+ label
1083
+ )
1084
+ );
1085
+ }
1086
+ return /* @__PURE__ */ React4__default.default.createElement(
1087
+ reactNative.ActivityIndicator,
1088
+ {
1089
+ size: sizeMap[size],
1090
+ color: color ?? colors.primary,
1091
+ accessibilityRole: "progressbar",
1092
+ accessibilityLabel: a11yLabel,
1093
+ accessibilityState: { busy: true },
1094
+ ...props
1095
+ }
1096
+ );
1097
+ }
1098
+ var styles = reactNative.StyleSheet.create({
1099
+ wrapper: {
1100
+ alignItems: "center",
1101
+ gap: vs(6)
1102
+ },
1103
+ label: {
1104
+ fontFamily: "Sohne-Regular",
1105
+ lineHeight: mvs(18)
1106
+ }
1107
+ });
1108
+
1109
+ // src/components/IconPicker/IconPicker.tsx
1110
+ var NUM_COLUMNS = 6;
1111
+ var GAP = 6;
1112
+ var TRIGGER_SIZE = s(56);
1113
+ var SCREEN_HEIGHT = reactNative.Dimensions.get("window").height;
1114
+ function IconCell({ name, selected, size, onPress }) {
1115
+ const { colors } = useTheme();
1116
+ const handlePress = () => {
1117
+ selectionAsync();
1118
+ onPress();
1119
+ };
1120
+ const iconColor = selected ? colors.primaryForeground : colors.foreground;
1121
+ const bg = selected ? colors.primary : "transparent";
1122
+ return /* @__PURE__ */ React4__default.default.createElement(
1123
+ reactNative.TouchableOpacity,
1124
+ {
1125
+ onPress: handlePress,
1126
+ activeOpacity: 0.6,
1127
+ touchSoundDisabled: true,
1128
+ accessibilityRole: "button",
1129
+ accessibilityState: { selected },
1130
+ accessibilityLabel: name,
1131
+ style: [styles2.cell, { width: size, height: size, backgroundColor: bg }]
1132
+ },
1133
+ renderIcon(name, ms(20), iconColor)
1134
+ );
1135
+ }
1136
+ var IconCellMemo = React4__default.default.memo(IconCell);
1137
+ function IconPicker({
1138
+ value,
1139
+ onChange,
1140
+ label,
1141
+ error,
1142
+ hint,
1143
+ disabled = false,
1144
+ numColumns = NUM_COLUMNS,
1145
+ gap = GAP,
1146
+ style
1147
+ }) {
1148
+ const { colors } = useTheme();
1149
+ const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
1150
+ const sheetRef = React4.useRef(null);
1151
+ const catScrollRef = React4.useRef(null);
1152
+ const [activeCategory, setActiveCategory] = React4.useState(null);
1153
+ const [containerWidth, setContainerWidth] = React4.useState(() => reactNative.Dimensions.get("window").width - s(16) * 2);
1154
+ const [ready, setReady] = React4.useState(false);
1155
+ const sheetName = React4.useId();
1156
+ const activeIcons = React4.useMemo(() => {
1157
+ if (activeCategory) {
1158
+ return CURATED_ICONS.find((c) => c.name === activeCategory)?.icons ?? ALL_CURATED_ICONS;
1159
+ }
1160
+ return ALL_CURATED_ICONS;
1161
+ }, [activeCategory]);
1162
+ const gapPx = s(gap);
1163
+ const cellSize = containerWidth > 0 ? Math.floor((containerWidth - gapPx * (numColumns - 1)) / numColumns) : 0;
1164
+ const rows = React4.useMemo(() => {
1165
+ const result = [];
1166
+ for (let i = 0; i < activeIcons.length; i += numColumns) {
1167
+ result.push(activeIcons.slice(i, i + numColumns));
1168
+ }
1169
+ return result;
1170
+ }, [activeIcons, numColumns]);
1171
+ const handleDismiss = React4.useCallback(() => {
1172
+ setActiveCategory(null);
1173
+ setReady(false);
1174
+ }, []);
1175
+ const handleSelect = React4.useCallback(
1176
+ (iconName) => {
1177
+ onChange(iconName);
1178
+ },
1179
+ [onChange]
1180
+ );
1181
+ const handleOpen = React4.useCallback(() => {
1182
+ if (disabled) return;
1183
+ impactMedium();
1184
+ setActiveCategory(null);
1185
+ setReady(false);
1186
+ sheetRef.current?.present();
1187
+ }, [disabled]);
1188
+ const renderBackdrop = React4.useCallback(
1189
+ (props) => /* @__PURE__ */ React4__default.default.createElement(bottomSheet.BottomSheetBackdrop, { ...props, disappearsOnIndex: -1, appearsOnIndex: 0, pressBehavior: "close" }),
1190
+ []
1191
+ );
1192
+ const selectedIcon = value ? renderIcon(value, ms(28), colors.foreground) : null;
1193
+ return /* @__PURE__ */ React4__default.default.createElement(reactNative.View, { style: [styles2.triggerContainer, style] }, label ? /* @__PURE__ */ React4__default.default.createElement(reactNative.Text, { style: [styles2.triggerLabel, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React4__default.default.createElement(
1194
+ reactNative.TouchableOpacity,
1195
+ {
1196
+ onPress: handleOpen,
1197
+ disabled,
1198
+ activeOpacity: 0.7,
1199
+ touchSoundDisabled: true,
1200
+ accessibilityRole: "button",
1201
+ accessibilityLabel: label ?? "Seleccionar icono",
1202
+ accessibilityState: { disabled },
1203
+ style: [
1204
+ styles2.trigger,
1205
+ {
1206
+ backgroundColor: disabled ? colors.surface : colors.background,
1207
+ width: TRIGGER_SIZE,
1208
+ height: TRIGGER_SIZE,
1209
+ borderColor: error ? colors.destructive : value ? colors.primary : colors.border
1210
+ },
1211
+ disabled && styles2.triggerDisabled
1212
+ ]
1213
+ },
1214
+ selectedIcon ?? renderIcon("plus", ms(24), colors.foregroundMuted)
1215
+ ), error ? /* @__PURE__ */ React4__default.default.createElement(
1216
+ reactNative.Text,
1217
+ {
1218
+ style: [styles2.helperText, { color: colors.destructive }],
1219
+ allowFontScaling: true,
1220
+ accessibilityLiveRegion: "polite"
1221
+ },
1222
+ error
1223
+ ) : null, !error && hint ? /* @__PURE__ */ React4__default.default.createElement(reactNative.Text, { style: [styles2.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null, /* @__PURE__ */ React4__default.default.createElement(
1224
+ bottomSheet.BottomSheetModal,
1225
+ {
1226
+ ref: sheetRef,
1227
+ name: sheetName,
1228
+ onDismiss: handleDismiss,
1229
+ enableDynamicSizing: true,
1230
+ maxDynamicContentSize: SCREEN_HEIGHT * 0.7,
1231
+ backdropComponent: renderBackdrop,
1232
+ backgroundStyle: { ...styles2.sheetBackground, backgroundColor: colors.card },
1233
+ handleIndicatorStyle: { ...styles2.handle, backgroundColor: colors.border },
1234
+ enablePanDownToClose: true,
1235
+ topInset: insets.top,
1236
+ android_keyboardInputMode: "adjustPan"
1237
+ },
1238
+ /* @__PURE__ */ React4__default.default.createElement(
1239
+ bottomSheet.BottomSheetScrollView,
1240
+ {
1241
+ contentContainerStyle: styles2.sheetContent,
1242
+ showsVerticalScrollIndicator: true
1243
+ },
1244
+ /* @__PURE__ */ React4__default.default.createElement(
1245
+ reactNative.View,
1246
+ {
1247
+ style: styles2.gridContainer,
1248
+ onLayout: (e) => {
1249
+ setContainerWidth(e.nativeEvent.layout.width);
1250
+ setReady(true);
1251
+ }
1252
+ },
1253
+ !ready ? /* @__PURE__ */ React4__default.default.createElement(reactNative.View, { style: styles2.loader }, /* @__PURE__ */ React4__default.default.createElement(Spinner, { size: "md", color: colors.primary, label: "Cargando iconos..." })) : /* @__PURE__ */ React4__default.default.createElement(React4__default.default.Fragment, null, /* @__PURE__ */ React4__default.default.createElement(reactNative.Text, { style: [styles2.sectionLabel, { color: colors.foregroundSubtle }], allowFontScaling: true }, "Categor\xEDas"), /* @__PURE__ */ React4__default.default.createElement(
1254
+ reactNativeGestureHandler.ScrollView,
1255
+ {
1256
+ ref: catScrollRef,
1257
+ horizontal: true,
1258
+ showsHorizontalScrollIndicator: false,
1259
+ contentContainerStyle: styles2.categoryStrip,
1260
+ style: styles2.categoryScroll
1261
+ },
1262
+ /* @__PURE__ */ React4__default.default.createElement(
1263
+ reactNative.TouchableOpacity,
1264
+ {
1265
+ onPress: () => setActiveCategory(null),
1266
+ activeOpacity: 0.7,
1267
+ touchSoundDisabled: true,
1268
+ accessibilityRole: "button",
1269
+ accessibilityLabel: "Todos",
1270
+ accessibilityState: { selected: activeCategory === null },
1271
+ style: [
1272
+ styles2.categoryChip,
1273
+ {
1274
+ backgroundColor: activeCategory === null ? colors.primary : colors.surface,
1275
+ borderColor: activeCategory === null ? colors.primary : colors.border
1276
+ }
1277
+ ]
1278
+ },
1279
+ /* @__PURE__ */ React4__default.default.createElement(reactNative.View, { style: styles2.categoryChipInner }, renderIcon("grid", ms(14), activeCategory === null ? colors.primaryForeground : colors.foregroundSubtle), /* @__PURE__ */ React4__default.default.createElement(
1280
+ reactNative.Text,
1281
+ {
1282
+ style: [
1283
+ styles2.categoryChipText,
1284
+ { color: activeCategory === null ? colors.primaryForeground : colors.foreground }
1285
+ ],
1286
+ allowFontScaling: true,
1287
+ numberOfLines: 1
1288
+ },
1289
+ "Todos"
1290
+ ))
1291
+ ),
1292
+ CURATED_ICONS.map((cat) => /* @__PURE__ */ React4__default.default.createElement(
1293
+ reactNative.TouchableOpacity,
1294
+ {
1295
+ key: cat.name,
1296
+ onPress: () => setActiveCategory(cat.name),
1297
+ activeOpacity: 0.7,
1298
+ touchSoundDisabled: true,
1299
+ accessibilityRole: "button",
1300
+ accessibilityLabel: cat.labelEs,
1301
+ accessibilityState: { selected: activeCategory === cat.name },
1302
+ style: [
1303
+ styles2.categoryChip,
1304
+ {
1305
+ backgroundColor: activeCategory === cat.name ? colors.primary : colors.surface,
1306
+ borderColor: activeCategory === cat.name ? colors.primary : colors.border
1307
+ }
1308
+ ]
1309
+ },
1310
+ /* @__PURE__ */ React4__default.default.createElement(reactNative.View, { style: styles2.categoryChipInner }, renderIcon(cat.categoryIcon, ms(14), activeCategory === cat.name ? colors.primaryForeground : colors.foregroundSubtle), /* @__PURE__ */ React4__default.default.createElement(
1311
+ reactNative.Text,
1312
+ {
1313
+ style: [
1314
+ styles2.categoryChipText,
1315
+ { color: activeCategory === cat.name ? colors.primaryForeground : colors.foreground }
1316
+ ],
1317
+ allowFontScaling: true,
1318
+ numberOfLines: 1
1319
+ },
1320
+ cat.labelEs
1321
+ ))
1322
+ ))
1323
+ ), /* @__PURE__ */ React4__default.default.createElement(reactNative.View, { style: [styles2.separator, { backgroundColor: colors.border }] }), cellSize > 0 ? rows.map((row, i) => /* @__PURE__ */ React4__default.default.createElement(reactNative.View, { key: row[0] ?? `row-${i}`, style: [styles2.row, { marginBottom: gapPx }] }, row.map((name) => /* @__PURE__ */ React4__default.default.createElement(
1324
+ IconCellMemo,
1325
+ {
1326
+ key: name,
1327
+ name,
1328
+ selected: value === name,
1329
+ size: cellSize,
1330
+ onPress: () => {
1331
+ handleSelect(name);
1332
+ sheetRef.current?.dismiss();
1333
+ }
1334
+ }
1335
+ )), Array.from({ length: numColumns - row.length }).map((_, j) => /* @__PURE__ */ React4__default.default.createElement(reactNative.View, { key: `spacer-${j}`, style: { width: cellSize, height: cellSize } })))) : null)
1336
+ )
1337
+ )
1338
+ ));
1339
+ }
1340
+ var styles2 = reactNative.StyleSheet.create({
1341
+ triggerContainer: {
1342
+ gap: vs(8)
1343
+ },
1344
+ triggerLabel: {
1345
+ fontFamily: "Sohne-Medium",
1346
+ fontSize: ms(14)
1347
+ },
1348
+ trigger: {
1349
+ borderRadius: RADIUS.md,
1350
+ borderWidth: 1,
1351
+ alignItems: "center",
1352
+ justifyContent: "center"
1353
+ },
1354
+ triggerDisabled: {
1355
+ opacity: 0.6
1356
+ },
1357
+ helperText: {
1358
+ fontFamily: "Sohne-Regular",
1359
+ fontSize: ms(13)
1360
+ },
1361
+ sheetBackground: {
1362
+ borderTopLeftRadius: ms(16),
1363
+ borderTopRightRadius: ms(16)
1364
+ },
1365
+ handle: {
1366
+ width: s(36),
1367
+ height: vs(4),
1368
+ borderRadius: ms(2)
1369
+ },
1370
+ sheetContent: {
1371
+ paddingHorizontal: s(16),
1372
+ paddingBottom: vs(24)
1373
+ },
1374
+ sectionLabel: {
1375
+ fontFamily: "Sohne-Medium",
1376
+ fontSize: ms(12),
1377
+ marginBottom: vs(8),
1378
+ textTransform: "uppercase",
1379
+ letterSpacing: 0.5
1380
+ },
1381
+ categoryScroll: {
1382
+ flexGrow: 0,
1383
+ flexShrink: 0
1384
+ },
1385
+ categoryStrip: {
1386
+ gap: s(8)
1387
+ },
1388
+ categoryChip: {
1389
+ borderRadius: RADIUS.full,
1390
+ borderWidth: 1,
1391
+ paddingVertical: vs(6),
1392
+ paddingHorizontal: s(12)
1393
+ },
1394
+ categoryChipInner: {
1395
+ flexDirection: "row",
1396
+ alignItems: "center",
1397
+ gap: s(6)
1398
+ },
1399
+ categoryChipText: {
1400
+ fontFamily: "Sohne-Medium",
1401
+ fontSize: ms(12)
1402
+ },
1403
+ separator: {
1404
+ height: reactNative.StyleSheet.hairlineWidth,
1405
+ marginVertical: vs(12)
1406
+ },
1407
+ gridContainer: {},
1408
+ row: {
1409
+ flexDirection: "row",
1410
+ gap: GAP
1411
+ },
1412
+ cell: {
1413
+ borderRadius: RADIUS.md,
1414
+ alignItems: "center",
1415
+ justifyContent: "center"
1416
+ },
1417
+ loader: {
1418
+ minHeight: vs(200),
1419
+ alignItems: "center",
1420
+ justifyContent: "center"
1421
+ }
1422
+ });
1423
+
1424
+ exports.IconPicker = IconPicker;