@retray-dev/ui-kit 7.0.1 → 9.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 (234) hide show
  1. package/COMPONENTS.md +567 -14
  2. package/EXAMPLES.md +21 -14
  3. package/README.md +14 -8
  4. package/dist/Accordion.js +57 -5
  5. package/dist/Accordion.mjs +4 -3
  6. package/dist/AlertBanner.js +4 -1
  7. package/dist/AlertBanner.mjs +3 -2
  8. package/dist/AppHeader.d.mts +40 -0
  9. package/dist/AppHeader.d.ts +40 -0
  10. package/dist/AppHeader.js +515 -0
  11. package/dist/AppHeader.mjs +10 -0
  12. package/dist/Avatar.js +39 -29
  13. package/dist/Avatar.mjs +2 -1
  14. package/dist/Badge.js +11 -1
  15. package/dist/Badge.mjs +2 -1
  16. package/dist/Button.d.mts +8 -3
  17. package/dist/Button.d.ts +8 -3
  18. package/dist/Button.js +126 -108
  19. package/dist/Button.mjs +6 -5
  20. package/dist/ButtonGroup.mjs +1 -0
  21. package/dist/Card.js +90 -70
  22. package/dist/Card.mjs +5 -4
  23. package/dist/CategoryStrip.js +79 -22
  24. package/dist/CategoryStrip.mjs +6 -6
  25. package/dist/Checkbox.js +118 -86
  26. package/dist/Checkbox.mjs +5 -5
  27. package/dist/Chip.js +113 -80
  28. package/dist/Chip.mjs +5 -5
  29. package/dist/ConfirmDialog.js +140 -110
  30. package/dist/ConfirmDialog.mjs +7 -6
  31. package/dist/CurrencyDisplay.mjs +1 -0
  32. package/dist/CurrencyInput.d.mts +1 -1
  33. package/dist/CurrencyInput.d.ts +1 -1
  34. package/dist/CurrencyInput.js +9 -5
  35. package/dist/CurrencyInput.mjs +5 -4
  36. package/dist/DetailRow.mjs +1 -0
  37. package/dist/EmptyState.js +131 -111
  38. package/dist/EmptyState.mjs +7 -6
  39. package/dist/ErrorBoundary.d.mts +42 -0
  40. package/dist/ErrorBoundary.d.ts +42 -0
  41. package/dist/ErrorBoundary.js +351 -0
  42. package/dist/ErrorBoundary.mjs +7 -0
  43. package/dist/Form.mjs +1 -0
  44. package/dist/HolographicCard.d.mts +55 -0
  45. package/dist/HolographicCard.d.ts +55 -0
  46. package/dist/HolographicCard.js +316 -0
  47. package/dist/HolographicCard.mjs +191 -0
  48. package/dist/IconButton.d.mts +8 -3
  49. package/dist/IconButton.d.ts +8 -3
  50. package/dist/IconButton.js +115 -98
  51. package/dist/IconButton.mjs +5 -4
  52. package/dist/ImageViewer.d.mts +23 -0
  53. package/dist/ImageViewer.d.ts +23 -0
  54. package/dist/ImageViewer.js +582 -0
  55. package/dist/ImageViewer.mjs +8 -0
  56. package/dist/Input.mjs +4 -3
  57. package/dist/LabelValue.mjs +1 -0
  58. package/dist/ListGroup.mjs +1 -0
  59. package/dist/ListItem.js +131 -117
  60. package/dist/ListItem.mjs +6 -5
  61. package/dist/MediaCard.js +54 -6
  62. package/dist/MediaCard.mjs +6 -5
  63. package/dist/MenuGroup.mjs +1 -0
  64. package/dist/MenuItem.js +91 -79
  65. package/dist/MenuItem.mjs +6 -5
  66. package/dist/MonthPicker.d.mts +10 -2
  67. package/dist/MonthPicker.d.ts +10 -2
  68. package/dist/MonthPicker.js +80 -17
  69. package/dist/MonthPicker.mjs +3 -2
  70. package/dist/PagerDots.d.mts +35 -0
  71. package/dist/PagerDots.d.ts +35 -0
  72. package/dist/PagerDots.js +392 -0
  73. package/dist/PagerDots.mjs +7 -0
  74. package/dist/Pressable.d.mts +5 -5
  75. package/dist/Pressable.d.ts +5 -5
  76. package/dist/Pressable.js +97 -86
  77. package/dist/Pressable.mjs +5 -4
  78. package/dist/PricingCard.d.mts +50 -0
  79. package/dist/PricingCard.d.ts +50 -0
  80. package/dist/PricingCard.js +636 -0
  81. package/dist/PricingCard.mjs +11 -0
  82. package/dist/Progress.mjs +3 -2
  83. package/dist/RadioGroup.js +81 -30
  84. package/dist/RadioGroup.mjs +5 -5
  85. package/dist/RetrayProvider.d.mts +2 -0
  86. package/dist/RetrayProvider.d.ts +2 -0
  87. package/dist/RetrayProvider.js +214 -0
  88. package/dist/RetrayProvider.mjs +5 -0
  89. package/dist/Select.js +51 -4
  90. package/dist/Select.mjs +5 -4
  91. package/dist/SelectableGrid.d.mts +44 -0
  92. package/dist/SelectableGrid.d.ts +44 -0
  93. package/dist/SelectableGrid.js +448 -0
  94. package/dist/SelectableGrid.mjs +9 -0
  95. package/dist/Separator.mjs +1 -0
  96. package/dist/Sheet.d.mts +13 -1
  97. package/dist/Sheet.d.ts +13 -1
  98. package/dist/Sheet.js +115 -5
  99. package/dist/Sheet.mjs +4 -2
  100. package/dist/Skeleton.d.mts +50 -0
  101. package/dist/Skeleton.d.ts +50 -0
  102. package/dist/Skeleton.js +61 -0
  103. package/dist/Skeleton.mjs +4 -2
  104. package/dist/Slider.js +51 -4
  105. package/dist/Slider.mjs +3 -2
  106. package/dist/Spinner.js +28 -7
  107. package/dist/Spinner.mjs +2 -1
  108. package/dist/Switch.js +98 -48
  109. package/dist/Switch.mjs +4 -3
  110. package/dist/TabBar.d.mts +42 -0
  111. package/dist/TabBar.d.ts +42 -0
  112. package/dist/TabBar.js +361 -0
  113. package/dist/TabBar.mjs +6 -0
  114. package/dist/Tabs.js +92 -62
  115. package/dist/Tabs.mjs +5 -4
  116. package/dist/Text.js +16 -0
  117. package/dist/Text.mjs +2 -1
  118. package/dist/Textarea.mjs +4 -3
  119. package/dist/Toast.d.mts +7 -7
  120. package/dist/Toast.d.ts +7 -7
  121. package/dist/Toast.mjs +1 -0
  122. package/dist/Toggle.d.mts +6 -3
  123. package/dist/Toggle.d.ts +6 -3
  124. package/dist/Toggle.js +135 -120
  125. package/dist/Toggle.mjs +5 -5
  126. package/dist/VirtualList.mjs +1 -0
  127. package/dist/{chunk-7H2OR44A.mjs → chunk-26BCI223.mjs} +1 -1
  128. package/dist/{chunk-CRYBX2CM.mjs → chunk-2TFTAWVJ.mjs} +44 -59
  129. package/dist/chunk-3DKJ2GIC.mjs +30 -0
  130. package/dist/{chunk-KWCPOM6W.mjs → chunk-3U4SSNWP.mjs} +32 -48
  131. package/dist/chunk-4I7D47FH.mjs +139 -0
  132. package/dist/chunk-4K625MVM.mjs +142 -0
  133. package/dist/{chunk-MN7OG7IY.mjs → chunk-6OAZJ577.mjs} +6 -4
  134. package/dist/{chunk-L7E7TVEZ.mjs → chunk-756RAKE4.mjs} +2 -2
  135. package/dist/{chunk-HSPSMN6U.mjs → chunk-7QHVVCB3.mjs} +2 -2
  136. package/dist/{chunk-URLL5JBR.mjs → chunk-A3A6KNQN.mjs} +3 -3
  137. package/dist/chunk-AJ7ZDNBT.mjs +120 -0
  138. package/dist/{chunk-FTLJOUOQ.mjs → chunk-AV4EMIRH.mjs} +25 -28
  139. package/dist/chunk-AZJF2BLK.mjs +115 -0
  140. package/dist/chunk-BNP626TY.mjs +159 -0
  141. package/dist/{chunk-5IKW3VNC.mjs → chunk-DVK4G2GT.mjs} +17 -1
  142. package/dist/{chunk-6LQYY7HC.mjs → chunk-EH745HE5.mjs} +2 -2
  143. package/dist/chunk-EJ7ZPXOH.mjs +163 -0
  144. package/dist/{chunk-RKLHUDZS.mjs → chunk-GD6KXMG5.mjs} +29 -15
  145. package/dist/{chunk-RR2VQLKE.mjs → chunk-GQYFLP3D.mjs} +14 -17
  146. package/dist/{chunk-Y6MXOREN.mjs → chunk-ID72TK46.mjs} +8 -17
  147. package/dist/{chunk-NQGVLMWG.mjs → chunk-JMOZEC77.mjs} +1 -1
  148. package/dist/{chunk-GCWOGZYL.mjs → chunk-JT7HKXRB.mjs} +39 -29
  149. package/dist/{chunk-LWG526VX.mjs → chunk-KIHCWCWL.mjs} +47 -62
  150. package/dist/chunk-LXJIIOYQ.mjs +104 -0
  151. package/dist/{chunk-SBZYEV4S.mjs → chunk-M6ZXVBTK.mjs} +5 -2
  152. package/dist/{chunk-XDMN67KV.mjs → chunk-MAC465BB.mjs} +10 -8
  153. package/dist/chunk-MBMXYJJV.mjs +36 -0
  154. package/dist/chunk-MLF3EZFW.mjs +119 -0
  155. package/dist/chunk-NA7PARID.mjs +147 -0
  156. package/dist/{chunk-QXGYKWI7.mjs → chunk-O3HA6TYM.mjs} +9 -4
  157. package/dist/{chunk-63357L2X.mjs → chunk-OB4JUQ3O.mjs} +1 -1
  158. package/dist/{chunk-AU2VDY4P.mjs → chunk-PFZTM6D5.mjs} +52 -4
  159. package/dist/chunk-QKH5ZOD5.mjs +97 -0
  160. package/dist/{chunk-KZJRQOIU.mjs → chunk-TERDKCLE.mjs} +11 -1
  161. package/dist/{chunk-U4N7WF4Z.mjs → chunk-UREA2GYY.mjs} +28 -23
  162. package/dist/{chunk-TAJ2PQ2O.mjs → chunk-VGTDN7SW.mjs} +7 -6
  163. package/dist/{chunk-URDE3EUU.mjs → chunk-VQ57HWPL.mjs} +27 -15
  164. package/dist/chunk-WBOOUHSS.mjs +62 -0
  165. package/dist/{chunk-GNGLDL6Z.mjs → chunk-WJLKJMKR.mjs} +18 -0
  166. package/dist/{chunk-YZJAFS4P.mjs → chunk-X4G6APW6.mjs} +22 -19
  167. package/dist/chunk-Y6FXYEAI.mjs +8 -0
  168. package/dist/chunk-YFZ3ELX5.mjs +16 -0
  169. package/dist/{chunk-QCNARS3X.mjs → chunk-YNROWHQJ.mjs} +1 -1
  170. package/dist/chunk-Z4BVUWW6.mjs +196 -0
  171. package/dist/{chunk-GPOUINK5.mjs → chunk-ZJKGQMYH.mjs} +10 -27
  172. package/dist/index-wt-orHUi.d.mts +85 -0
  173. package/dist/index-wt-orHUi.d.ts +85 -0
  174. package/dist/index.d.mts +59 -51
  175. package/dist/index.d.ts +59 -51
  176. package/dist/index.js +1940 -744
  177. package/dist/index.mjs +49 -39
  178. package/package.json +35 -5
  179. package/src/components/Accordion/Accordion.tsx +12 -1
  180. package/src/components/AlertBanner/AlertBanner.tsx +5 -0
  181. package/src/components/AppHeader/AppHeader.tsx +172 -0
  182. package/src/components/AppHeader/index.ts +1 -0
  183. package/src/components/Avatar/Avatar.tsx +10 -2
  184. package/src/components/Badge/Badge.tsx +8 -1
  185. package/src/components/Button/Button.tsx +20 -27
  186. package/src/components/Card/Card.tsx +12 -23
  187. package/src/components/CategoryStrip/CategoryStrip.tsx +17 -21
  188. package/src/components/Checkbox/Checkbox.tsx +26 -40
  189. package/src/components/Chip/Chip.tsx +24 -33
  190. package/src/components/CurrencyInput/CurrencyInput.tsx +10 -8
  191. package/src/components/EmptyState/EmptyState.tsx +2 -1
  192. package/src/components/ErrorBoundary/ErrorBoundary.tsx +153 -0
  193. package/src/components/ErrorBoundary/index.ts +1 -0
  194. package/src/components/HolographicCard/HolographicCard.tsx +315 -0
  195. package/src/components/HolographicCard/index.ts +1 -0
  196. package/src/components/IconButton/IconButton.tsx +19 -27
  197. package/src/components/ImageViewer/ImageViewer.tsx +290 -0
  198. package/src/components/ImageViewer/index.ts +1 -0
  199. package/src/components/ListItem/ListItem.tsx +70 -67
  200. package/src/components/MediaCard/MediaCard.tsx +8 -2
  201. package/src/components/MenuItem/MenuItem.tsx +10 -25
  202. package/src/components/MonthPicker/MonthPicker.tsx +39 -13
  203. package/src/components/MonthPicker/index.ts +1 -1
  204. package/src/components/PagerDots/PagerDots.tsx +200 -0
  205. package/src/components/PagerDots/index.ts +1 -0
  206. package/src/components/Pressable/Pressable.tsx +19 -35
  207. package/src/components/PricingCard/PricingCard.tsx +220 -0
  208. package/src/components/PricingCard/index.ts +1 -0
  209. package/src/components/RadioGroup/RadioGroup.tsx +14 -27
  210. package/src/components/RetrayProvider/RetrayProvider.tsx +59 -0
  211. package/src/components/RetrayProvider/index.ts +1 -0
  212. package/src/components/SelectableGrid/SelectableGrid.tsx +205 -0
  213. package/src/components/SelectableGrid/index.ts +1 -0
  214. package/src/components/Sheet/Sheet.tsx +65 -1
  215. package/src/components/Skeleton/Skeleton.tsx +142 -1
  216. package/src/components/Spinner/Spinner.tsx +17 -2
  217. package/src/components/Switch/Switch.tsx +30 -58
  218. package/src/components/TabBar/TabBar.tsx +169 -0
  219. package/src/components/TabBar/index.ts +1 -0
  220. package/src/components/Tabs/Tabs.tsx +23 -26
  221. package/src/components/Text/Text.tsx +2 -0
  222. package/src/components/Toggle/Toggle.tsx +35 -51
  223. package/src/fonts.ts +4 -1
  224. package/src/index.ts +23 -2
  225. package/src/utils/animations.ts +29 -1
  226. package/src/utils/fontGuard.ts +34 -0
  227. package/src/utils/haptics.ts +211 -9
  228. package/src/utils/pressable.ts +66 -0
  229. package/dist/chunk-76PFOSM2.mjs +0 -41
  230. package/dist/chunk-DITNP6PL.mjs +0 -106
  231. package/dist/chunk-JBLL7U3U.mjs +0 -64
  232. package/dist/chunk-LG4DO3DK.mjs +0 -174
  233. package/dist/chunk-RMMK64W5.mjs +0 -54
  234. package/dist/chunk-RTC3CFXF.mjs +0 -29
package/dist/TabBar.js ADDED
@@ -0,0 +1,361 @@
1
+ 'use strict';
2
+
3
+ var React3 = require('react');
4
+ var reactNative = require('react-native');
5
+ var reactNativeSafeAreaContext = require('react-native-safe-area-context');
6
+ var AntDesign = require('@expo/vector-icons/AntDesign');
7
+ var Entypo = require('@expo/vector-icons/Entypo');
8
+ var Feather = require('@expo/vector-icons/Feather');
9
+ var FontAwesome5 = require('@expo/vector-icons/FontAwesome5');
10
+ var MaterialIcons = require('@expo/vector-icons/MaterialIcons');
11
+ var Ionicons = require('@expo/vector-icons/Ionicons');
12
+ var reactNativeSizeMatters = require('react-native-size-matters');
13
+
14
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
+
16
+ var React3__default = /*#__PURE__*/_interopDefault(React3);
17
+ var AntDesign__default = /*#__PURE__*/_interopDefault(AntDesign);
18
+ var Entypo__default = /*#__PURE__*/_interopDefault(Entypo);
19
+ var Feather__default = /*#__PURE__*/_interopDefault(Feather);
20
+ var FontAwesome5__default = /*#__PURE__*/_interopDefault(FontAwesome5);
21
+ var MaterialIcons__default = /*#__PURE__*/_interopDefault(MaterialIcons);
22
+ var Ionicons__default = /*#__PURE__*/_interopDefault(Ionicons);
23
+
24
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
25
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
26
+ }) : x)(function(x) {
27
+ if (typeof require !== "undefined") return require.apply(this, arguments);
28
+ throw Error('Dynamic require of "' + x + '" is not supported');
29
+ });
30
+
31
+ // src/theme/colorUtils.ts
32
+ function hexToRgb(hex) {
33
+ const clean = hex.replace("#", "");
34
+ const full = clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean;
35
+ if (full.length !== 6) return null;
36
+ return {
37
+ r: parseInt(full.slice(0, 2), 16),
38
+ g: parseInt(full.slice(2, 4), 16),
39
+ b: parseInt(full.slice(4, 6), 16)
40
+ };
41
+ }
42
+ function componentToHex(c) {
43
+ return Math.round(Math.max(0, Math.min(255, c))).toString(16).padStart(2, "0");
44
+ }
45
+ function rgbToHex(r, g, b) {
46
+ return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`;
47
+ }
48
+ function withAlphaOnWhite(hex, alpha) {
49
+ const rgb = hexToRgb(hex);
50
+ if (!rgb) return hex;
51
+ const r = rgb.r * alpha + 255 * (1 - alpha);
52
+ const g = rgb.g * alpha + 255 * (1 - alpha);
53
+ const b = rgb.b * alpha + 255 * (1 - alpha);
54
+ return rgbToHex(r, g, b);
55
+ }
56
+ function withAlphaOnDark(hex, alpha, bgHex = "#0f0f0f") {
57
+ const rgb = hexToRgb(hex);
58
+ const bg = hexToRgb(bgHex);
59
+ if (!rgb || !bg) return hex;
60
+ const r = rgb.r * alpha + bg.r * (1 - alpha);
61
+ const g = rgb.g * alpha + bg.g * (1 - alpha);
62
+ const b = rgb.b * alpha + bg.b * (1 - alpha);
63
+ return rgbToHex(r, g, b);
64
+ }
65
+ function mixWithBackground(fgHex, bgHex, opacity) {
66
+ const fg = hexToRgb(fgHex);
67
+ const bg = hexToRgb(bgHex);
68
+ if (!fg || !bg) return fgHex;
69
+ const r = fg.r * opacity + bg.r * (1 - opacity);
70
+ const g = fg.g * opacity + bg.g * (1 - opacity);
71
+ const b = fg.b * opacity + bg.b * (1 - opacity);
72
+ return rgbToHex(r, g, b);
73
+ }
74
+ function lighten(hex, amount) {
75
+ return withAlphaOnWhite(hex, 1 - amount);
76
+ }
77
+ function darken(hex, amount) {
78
+ const rgb = hexToRgb(hex);
79
+ if (!rgb) return hex;
80
+ return rgbToHex(rgb.r * (1 - amount), rgb.g * (1 - amount), rgb.b * (1 - amount));
81
+ }
82
+
83
+ // src/theme/colors.ts
84
+ var defaultLight = {
85
+ background: "#ffffff",
86
+ foreground: "#1a1a1a",
87
+ card: "#ffffff",
88
+ primary: "#1a1a1a",
89
+ primaryForeground: "#ffffff",
90
+ // AUDIT FIX: brand accent — was undefined; falls back to primary when omitted
91
+ accent: "#d4561d",
92
+ accentForeground: "#ffffff",
93
+ border: "#dddddd",
94
+ // AUDIT FIX: was #e53935 (4.22:1 on white — fails AA); #c72828 = 5.59:1 ✓
95
+ destructive: "#c72828",
96
+ destructiveForeground: "#ffffff",
97
+ success: "#1a7a45",
98
+ successForeground: "#ffffff",
99
+ // AUDIT FIX: was #e67e00 (2.86:1 — severe fail); #9a5200 = 5.86:1 ✓ AAA-near
100
+ warning: "#9a5200",
101
+ warningForeground: "#ffffff"
102
+ };
103
+ function deriveColors(t, scheme) {
104
+ const dark = scheme === "dark";
105
+ const bg = t.background;
106
+ const foregroundSubtle = mixWithBackground(t.foreground, bg, 0.7);
107
+ const foregroundMuted = mixWithBackground(t.foreground, bg, 0.62);
108
+ const surface = dark ? lighten(bg, -0.06) : darken(bg, 0.04);
109
+ const surfaceStrong = dark ? lighten(bg, -0.12) : darken(bg, 0.08);
110
+ const destructiveTint = dark ? withAlphaOnDark(t.destructive, 0.15, bg) : withAlphaOnWhite(t.destructive, 0.08);
111
+ const destructiveBorder = dark ? withAlphaOnDark(t.destructive, 0.45, bg) : withAlphaOnWhite(t.destructive, 0.3);
112
+ const successTint = dark ? withAlphaOnDark(t.success, 0.15, bg) : withAlphaOnWhite(t.success, 0.08);
113
+ const successBorder = dark ? withAlphaOnDark(t.success, 0.45, bg) : withAlphaOnWhite(t.success, 0.3);
114
+ const warningTint = dark ? withAlphaOnDark(t.warning, 0.15, bg) : withAlphaOnWhite(t.warning, 0.08);
115
+ const warningBorder = dark ? withAlphaOnDark(t.warning, 0.45, bg) : withAlphaOnWhite(t.warning, 0.3);
116
+ return {
117
+ ...t,
118
+ foregroundSubtle,
119
+ foregroundMuted,
120
+ surface,
121
+ surfaceStrong,
122
+ destructiveTint,
123
+ destructiveBorder,
124
+ successTint,
125
+ successBorder,
126
+ warningTint,
127
+ warningBorder,
128
+ overlay: t.overlay ?? "rgba(0,0,0,0.45)",
129
+ accentResolved: t.accent ?? t.primary,
130
+ accentForegroundResolved: t.accentForeground ?? t.primaryForeground,
131
+ ring: t.accent ?? t.primary,
132
+ input: t.border,
133
+ separator: dark ? lighten(t.border, 0.22) : darken(t.border, 0.16)
134
+ };
135
+ }
136
+
137
+ // src/theme/ThemeProvider.tsx
138
+ var ThemeContext = React3.createContext({
139
+ colors: deriveColors(defaultLight, "light"),
140
+ colorScheme: "light"
141
+ });
142
+ function useTheme() {
143
+ const context = React3.useContext(ThemeContext);
144
+ if (!context) {
145
+ throw new Error("useTheme must be used within a ThemeProvider");
146
+ }
147
+ return context;
148
+ }
149
+ var glyphMapOf = (mod) => mod.glyphMap ?? {};
150
+ var ALL_FAMILIES = [
151
+ { name: "Ionicons", component: Ionicons__default.default, getGlyphMap: () => glyphMapOf(Ionicons__default.default) },
152
+ { name: "MaterialIcons", component: MaterialIcons__default.default, getGlyphMap: () => glyphMapOf(MaterialIcons__default.default) },
153
+ { name: "FontAwesome5", component: FontAwesome5__default.default, getGlyphMap: () => glyphMapOf(FontAwesome5__default.default) },
154
+ { name: "Entypo", component: Entypo__default.default, getGlyphMap: () => glyphMapOf(Entypo__default.default) },
155
+ { name: "AntDesign", component: AntDesign__default.default, getGlyphMap: () => glyphMapOf(AntDesign__default.default) },
156
+ { name: "Feather", component: Feather__default.default, getGlyphMap: () => glyphMapOf(Feather__default.default) }
157
+ ];
158
+ var activeFamilies = ALL_FAMILIES;
159
+ var resolvedCache = null;
160
+ function buildCache() {
161
+ const cache = /* @__PURE__ */ new Map();
162
+ for (const family of activeFamilies) {
163
+ const glyphMap = family.getGlyphMap();
164
+ for (const iconName of Object.keys(glyphMap)) {
165
+ cache.set(iconName, family);
166
+ }
167
+ }
168
+ return cache;
169
+ }
170
+ function resolveFamily(name) {
171
+ if (!resolvedCache) {
172
+ resolvedCache = buildCache();
173
+ }
174
+ return resolvedCache.get(name) ?? null;
175
+ }
176
+ function Icon({ name, size, color, family }) {
177
+ let resolved = null;
178
+ if (family) {
179
+ resolved = ALL_FAMILIES.find((f) => f.name === family) ?? null;
180
+ } else {
181
+ resolved = resolveFamily(name);
182
+ }
183
+ if (!resolved) return null;
184
+ const Component = resolved.component;
185
+ return React3__default.default.createElement(Component, { name, size, color });
186
+ }
187
+ function renderIcon(name, size, color) {
188
+ return React3__default.default.createElement(Icon, { name, size, color });
189
+ }
190
+ var _haptics = null;
191
+ var _hapticsLoaded = false;
192
+ async function getHaptics() {
193
+ if (reactNative.Platform.OS === "web") return null;
194
+ if (!_hapticsLoaded) {
195
+ _hapticsLoaded = true;
196
+ try {
197
+ _haptics = await import('expo-haptics');
198
+ } catch {
199
+ _haptics = null;
200
+ }
201
+ }
202
+ return _haptics;
203
+ }
204
+ var _pulsar = null;
205
+ var _pulsarChecked = false;
206
+ var _pulsarAvailable = false;
207
+ function isPulsarNativeRegistered() {
208
+ try {
209
+ const g = globalThis;
210
+ if (typeof g.__turboModuleProxy === "function") {
211
+ return g.__turboModuleProxy("RNPulsar") != null;
212
+ }
213
+ return reactNative.NativeModules?.RNPulsar != null;
214
+ } catch {
215
+ return false;
216
+ }
217
+ }
218
+ function getPulsar() {
219
+ if (reactNative.Platform.OS === "web") return null;
220
+ if (!_pulsarChecked) {
221
+ _pulsarChecked = true;
222
+ try {
223
+ if (isPulsarNativeRegistered()) {
224
+ _pulsar = __require("react-native-pulsar");
225
+ _pulsarAvailable = true;
226
+ }
227
+ } catch {
228
+ _pulsar = null;
229
+ _pulsarAvailable = false;
230
+ }
231
+ }
232
+ return _pulsarAvailable ? _pulsar : null;
233
+ }
234
+ function selectionAsync() {
235
+ if (reactNative.Platform.OS === "web") return;
236
+ getHaptics().then((h) => {
237
+ if (h) {
238
+ h.selectionAsync();
239
+ } else {
240
+ getPulsar()?.Presets.System.selection();
241
+ }
242
+ });
243
+ }
244
+ var isWeb = reactNative.Platform.OS === "web";
245
+ var s = isWeb ? (n) => n : reactNativeSizeMatters.scale;
246
+ var vs = isWeb ? (n) => n : reactNativeSizeMatters.verticalScale;
247
+ var ms = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateScale;
248
+ var mvs = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateVerticalScale;
249
+
250
+ // src/components/TabBar/TabBar.tsx
251
+ function TabBar({
252
+ items,
253
+ activeKey,
254
+ onTabPress,
255
+ activeColor,
256
+ inactiveColor,
257
+ withSafeArea = true,
258
+ style
259
+ }) {
260
+ const { colors } = useTheme();
261
+ const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
262
+ const resolvedActive = activeColor ?? colors.primary;
263
+ const resolvedInactive = inactiveColor ?? colors.foregroundMuted;
264
+ return /* @__PURE__ */ React3__default.default.createElement(
265
+ reactNative.View,
266
+ {
267
+ style: [
268
+ styles.container,
269
+ {
270
+ backgroundColor: colors.card,
271
+ borderTopColor: colors.border,
272
+ paddingBottom: withSafeArea ? insets.bottom : 0
273
+ },
274
+ style
275
+ ],
276
+ accessibilityRole: "tablist"
277
+ },
278
+ items.map((item) => {
279
+ const active = item.key === activeKey;
280
+ const tint = active ? resolvedActive : resolvedInactive;
281
+ const iconNode = item.icon ?? (item.iconName ? renderIcon(item.iconName, ms(24), tint) : null);
282
+ const showBadge = item.badge !== void 0 && item.badge !== false;
283
+ const badgeCount = typeof item.badge === "number" ? item.badge : void 0;
284
+ return /* @__PURE__ */ React3__default.default.createElement(
285
+ reactNative.TouchableOpacity,
286
+ {
287
+ key: item.key,
288
+ style: styles.tab,
289
+ onPress: () => {
290
+ if (!active) selectionAsync();
291
+ onTabPress(item.key);
292
+ },
293
+ activeOpacity: 0.7,
294
+ touchSoundDisabled: true,
295
+ accessibilityRole: "tab",
296
+ accessibilityState: { selected: active },
297
+ accessibilityLabel: item.label ?? item.key
298
+ },
299
+ /* @__PURE__ */ React3__default.default.createElement(reactNative.View, null, iconNode, showBadge ? /* @__PURE__ */ React3__default.default.createElement(
300
+ reactNative.View,
301
+ {
302
+ style: [
303
+ styles.badge,
304
+ { backgroundColor: colors.destructive, borderColor: colors.card },
305
+ badgeCount === void 0 && styles.badgeDot
306
+ ]
307
+ },
308
+ badgeCount !== void 0 ? /* @__PURE__ */ React3__default.default.createElement(reactNative.Text, { style: [styles.badgeText, { color: colors.destructiveForeground }], allowFontScaling: false }, badgeCount > 99 ? "99+" : badgeCount) : null
309
+ ) : null),
310
+ item.label ? /* @__PURE__ */ React3__default.default.createElement(reactNative.Text, { style: [styles.label, { color: tint }], numberOfLines: 1, allowFontScaling: true }, item.label) : null
311
+ );
312
+ })
313
+ );
314
+ }
315
+ var styles = reactNative.StyleSheet.create({
316
+ container: {
317
+ flexDirection: "row",
318
+ borderTopWidth: reactNative.StyleSheet.hairlineWidth
319
+ },
320
+ tab: {
321
+ flex: 1,
322
+ alignItems: "center",
323
+ justifyContent: "center",
324
+ paddingTop: vs(8),
325
+ paddingBottom: vs(6),
326
+ gap: vs(2),
327
+ minHeight: vs(48)
328
+ },
329
+ label: {
330
+ fontFamily: "Sohne-Medium",
331
+ fontSize: ms(11),
332
+ lineHeight: mvs(14)
333
+ },
334
+ badge: {
335
+ position: "absolute",
336
+ top: -vs(4),
337
+ right: -s(10),
338
+ minWidth: s(16),
339
+ height: s(16),
340
+ borderRadius: s(8),
341
+ borderWidth: 1.5,
342
+ alignItems: "center",
343
+ justifyContent: "center",
344
+ paddingHorizontal: s(3)
345
+ },
346
+ badgeDot: {
347
+ minWidth: s(10),
348
+ height: s(10),
349
+ borderRadius: s(5),
350
+ top: -vs(2),
351
+ right: -s(6),
352
+ paddingHorizontal: 0
353
+ },
354
+ badgeText: {
355
+ fontFamily: "Sohne-SemiBold",
356
+ fontSize: ms(9),
357
+ lineHeight: ms(11)
358
+ }
359
+ });
360
+
361
+ exports.TabBar = TabBar;
@@ -0,0 +1,6 @@
1
+ export { TabBar } from './chunk-MLF3EZFW.mjs';
2
+ import './chunk-EJ7ZPXOH.mjs';
3
+ import './chunk-T7XZ7H7Y.mjs';
4
+ import './chunk-SOYNZDVY.mjs';
5
+ import './chunk-2CE3TQVY.mjs';
6
+ import './chunk-Y6FXYEAI.mjs';
package/dist/Tabs.js CHANGED
@@ -4,24 +4,72 @@ var React2 = require('react');
4
4
  var reactNative = require('react-native');
5
5
  var Animated = require('react-native-reanimated');
6
6
  var reactNativeSizeMatters = require('react-native-size-matters');
7
+ var pressto = require('pressto');
7
8
 
8
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
10
 
10
11
  var React2__default = /*#__PURE__*/_interopDefault(React2);
11
12
  var Animated__default = /*#__PURE__*/_interopDefault(Animated);
12
13
 
13
- // src/components/Tabs/Tabs.tsx
14
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
15
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
16
+ }) : x)(function(x) {
17
+ if (typeof require !== "undefined") return require.apply(this, arguments);
18
+ throw Error('Dynamic require of "' + x + '" is not supported');
19
+ });
14
20
  var _haptics = null;
21
+ var _hapticsLoaded = false;
15
22
  async function getHaptics() {
16
23
  if (reactNative.Platform.OS === "web") return null;
17
- if (!_haptics) {
18
- _haptics = await import('expo-haptics');
24
+ if (!_hapticsLoaded) {
25
+ _hapticsLoaded = true;
26
+ try {
27
+ _haptics = await import('expo-haptics');
28
+ } catch {
29
+ _haptics = null;
30
+ }
19
31
  }
20
32
  return _haptics;
21
33
  }
34
+ var _pulsar = null;
35
+ var _pulsarChecked = false;
36
+ var _pulsarAvailable = false;
37
+ function isPulsarNativeRegistered() {
38
+ try {
39
+ const g = globalThis;
40
+ if (typeof g.__turboModuleProxy === "function") {
41
+ return g.__turboModuleProxy("RNPulsar") != null;
42
+ }
43
+ return reactNative.NativeModules?.RNPulsar != null;
44
+ } catch {
45
+ return false;
46
+ }
47
+ }
48
+ function getPulsar() {
49
+ if (reactNative.Platform.OS === "web") return null;
50
+ if (!_pulsarChecked) {
51
+ _pulsarChecked = true;
52
+ try {
53
+ if (isPulsarNativeRegistered()) {
54
+ _pulsar = __require("react-native-pulsar");
55
+ _pulsarAvailable = true;
56
+ }
57
+ } catch {
58
+ _pulsar = null;
59
+ _pulsarAvailable = false;
60
+ }
61
+ }
62
+ return _pulsarAvailable ? _pulsar : null;
63
+ }
22
64
  function selectionAsync() {
23
65
  if (reactNative.Platform.OS === "web") return;
24
- getHaptics().then((h) => h?.selectionAsync());
66
+ getHaptics().then((h) => {
67
+ if (h) {
68
+ h.selectionAsync();
69
+ } else {
70
+ getPulsar()?.Presets.System.selection();
71
+ }
72
+ });
25
73
  }
26
74
 
27
75
  // src/theme/colorUtils.ts
@@ -147,9 +195,6 @@ var s = isWeb ? (n) => n : reactNativeSizeMatters.scale;
147
195
  var vs = isWeb ? (n) => n : reactNativeSizeMatters.verticalScale;
148
196
  var ms = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateScale;
149
197
  var SPRINGS = {
150
- /** Tight, premium press feel — Buttons, Toggle, Tabs triggers. */
151
- pressIn: { stiffness: 600, damping: 35, mass: 0.8 },
152
- pressOut: { stiffness: 280, damping: 22, mass: 0.8 },
153
198
  /** Settled transitions for moving indicators — Tabs pill, Switch thumb. */
154
199
  glide: { stiffness: 380, damping: 38, mass: 1 }};
155
200
  ({
@@ -161,48 +206,36 @@ var SPRINGS = {
161
206
  collapse: Animated.Easing.in(Animated.Easing.ease)
162
207
  });
163
208
  var PRESS_SCALE = {
164
- button: 0.95};
165
- function useHover() {
166
- const [hovered, setHovered] = React2.useState(false);
167
- const onMouseEnter = React2.useCallback(() => setHovered(true), []);
168
- const onMouseLeave = React2.useCallback(() => setHovered(false), []);
169
- if (reactNative.Platform.OS !== "web") {
170
- return { hovered: false, hoverHandlers: {} };
171
- }
172
- return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
173
- }
174
-
175
- // src/utils/usePressScale.ts
176
- function usePressScale({
177
- pressScale = PRESS_SCALE.button,
178
- hoverScale = 1.02,
179
- pressInSpring = SPRINGS.pressIn,
180
- pressOutSpring = SPRINGS.pressOut,
181
- disabled = false
182
- } = {}) {
183
- const scale2 = Animated.useSharedValue(1);
184
- const { hovered, hoverHandlers } = useHover();
185
- const onPressIn = React2.useCallback(() => {
186
- if (disabled) return;
187
- scale2.value = Animated.withSpring(pressScale, pressInSpring);
188
- }, [disabled, pressScale, pressInSpring, scale2]);
189
- const onPressOut = React2.useCallback(() => {
190
- if (disabled) return;
191
- scale2.value = Animated.withSpring(1, pressOutSpring);
192
- }, [disabled, pressOutSpring, scale2]);
193
- const hoverActive = reactNative.Platform.OS === "web" && hovered && hoverScale !== 1 && !disabled;
194
- const animatedStyle = Animated.useAnimatedStyle(() => ({
195
- transform: [
196
- { scale: scale2.value * (hoverActive ? hoverScale : 1) }
197
- ]
198
- }));
199
- return {
200
- animatedStyle,
201
- onPressIn,
202
- onPressOut,
203
- hoverHandlers
204
- };
205
- }
209
+ button: 0.95,
210
+ card: 0.98,
211
+ row: 0.97,
212
+ chip: 0.94
213
+ };
214
+ pressto.createAnimatedPressable((progress) => {
215
+ "worklet";
216
+ const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
217
+ return { transform: [{ scale: scale2 }] };
218
+ });
219
+ pressto.createAnimatedPressable((progress) => {
220
+ "worklet";
221
+ const scale2 = 1 - (1 - PRESS_SCALE.card) * progress;
222
+ return { transform: [{ scale: scale2 }] };
223
+ });
224
+ pressto.createAnimatedPressable((progress) => {
225
+ "worklet";
226
+ const scale2 = 1 - (1 - PRESS_SCALE.row) * progress;
227
+ return { transform: [{ scale: scale2 }] };
228
+ });
229
+ pressto.createAnimatedPressable((progress) => {
230
+ "worklet";
231
+ const scale2 = 1 - (1 - PRESS_SCALE.chip) * progress;
232
+ return { transform: [{ scale: scale2 }] };
233
+ });
234
+ var PressableTab = pressto.createAnimatedPressable((progress) => {
235
+ "worklet";
236
+ const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
237
+ return { transform: [{ scale: scale2 }] };
238
+ });
206
239
 
207
240
  // src/components/Tabs/Tabs.tsx
208
241
  function TabTrigger({
@@ -213,12 +246,9 @@ function TabTrigger({
213
246
  variant
214
247
  }) {
215
248
  const { colors } = useTheme();
216
- const { animatedStyle, onPressIn, onPressOut } = usePressScale({
217
- pressScale: PRESS_SCALE.button
218
- });
219
249
  const isUnderline = variant === "underline";
220
- return /* @__PURE__ */ React2__default.default.createElement(
221
- reactNative.TouchableOpacity,
250
+ return /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { onLayout, style: styles.triggerWrap }, /* @__PURE__ */ React2__default.default.createElement(
251
+ PressableTab,
222
252
  {
223
253
  style: [
224
254
  styles.trigger,
@@ -226,16 +256,13 @@ function TabTrigger({
226
256
  isUnderline && isActive && { borderBottomColor: colors.primary }
227
257
  ],
228
258
  onPress,
229
- onPressIn,
230
- onPressOut,
231
- onLayout,
232
- activeOpacity: 1,
259
+ rippleColor: "transparent",
233
260
  touchSoundDisabled: true,
234
261
  accessibilityRole: "tab",
235
262
  accessibilityState: { selected: isActive },
236
263
  accessibilityLabel: tab.label
237
264
  },
238
- /* @__PURE__ */ React2__default.default.createElement(Animated__default.default.View, { style: animatedStyle }, /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: styles.triggerInner }, tab.icon ? typeof tab.icon === "function" ? tab.icon(isActive) : tab.icon : null, /* @__PURE__ */ React2__default.default.createElement(
265
+ /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: styles.triggerInner }, tab.icon ? typeof tab.icon === "function" ? tab.icon(isActive) : tab.icon : null, /* @__PURE__ */ React2__default.default.createElement(
239
266
  reactNative.Text,
240
267
  {
241
268
  style: [
@@ -249,8 +276,8 @@ function TabTrigger({
249
276
  allowFontScaling: true
250
277
  },
251
278
  tab.label
252
- )))
253
- );
279
+ ))
280
+ ));
254
281
  }
255
282
  function Tabs({ tabs, variant = "pill", value, onValueChange, children, style }) {
256
283
  const [internal, setInternal] = React2.useState(tabs[0]?.value ?? "");
@@ -351,6 +378,9 @@ var styles = reactNative.StyleSheet.create({
351
378
  borderBottomWidth: 1
352
379
  },
353
380
  pill: {},
381
+ triggerWrap: {
382
+ flex: 1
383
+ },
354
384
  trigger: {
355
385
  flex: 1,
356
386
  paddingVertical: vs(7),
@@ -361,7 +391,7 @@ var styles = reactNative.StyleSheet.create({
361
391
  zIndex: 1
362
392
  },
363
393
  triggerUnderline: {
364
- flex: 0,
394
+ flex: 1,
365
395
  paddingVertical: vs(12),
366
396
  paddingHorizontal: s(16),
367
397
  borderRadius: 0,
package/dist/Tabs.mjs CHANGED
@@ -1,6 +1,7 @@
1
- export { Tabs, TabsContent } from './chunk-RR2VQLKE.mjs';
2
- import './chunk-QCNARS3X.mjs';
3
- import './chunk-RTC3CFXF.mjs';
4
- import './chunk-5IKW3VNC.mjs';
1
+ export { Tabs, TabsContent } from './chunk-GQYFLP3D.mjs';
2
+ import './chunk-3DKJ2GIC.mjs';
3
+ import './chunk-EJ7ZPXOH.mjs';
4
+ import './chunk-DVK4G2GT.mjs';
5
5
  import './chunk-SOYNZDVY.mjs';
6
6
  import './chunk-2CE3TQVY.mjs';
7
+ import './chunk-Y6FXYEAI.mjs';
package/dist/Text.js CHANGED
@@ -3,6 +3,7 @@
3
3
  var React2 = require('react');
4
4
  var reactNative = require('react-native');
5
5
  var reactNativeSizeMatters = require('react-native-size-matters');
6
+ var expoFont = require('expo-font');
6
7
 
7
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
9
 
@@ -253,6 +254,20 @@ var TYPOGRAPHY = {
253
254
  var isWeb = reactNative.Platform.OS === "web";
254
255
  var ms = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateScale;
255
256
  var mvs = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateVerticalScale;
257
+ var warned = false;
258
+ function warnIfFontsMissing() {
259
+ if (warned) return;
260
+ if (typeof __DEV__ !== "undefined" && !__DEV__) return;
261
+ warned = true;
262
+ try {
263
+ if (!expoFont.isLoaded("Sohne-Regular")) {
264
+ console.warn(
265
+ "[retray-ui-kit] Sohne fonts are not loaded \u2014 text will fall back to the system font. Load them at your app root before rendering any UI kit component:\n\n import { useFonts } from 'expo-font'\n import { SohneFonts } from '@retray-dev/ui-kit/fonts'\n\n const [fontsLoaded] = useFonts(SohneFonts)\n if (!fontsLoaded) return null\n"
266
+ );
267
+ }
268
+ } catch {
269
+ }
270
+ }
256
271
 
257
272
  // src/components/Text/Text.tsx
258
273
  var variantStyles = {
@@ -293,6 +308,7 @@ var defaultColorVariant = {
293
308
  "button-sm": "foreground"
294
309
  };
295
310
  function TextBase({ variant = "body-md", color, style, children, ...props }) {
311
+ warnIfFontsMissing();
296
312
  const { colors } = useTheme();
297
313
  const colorKey = defaultColorVariant[variant] ?? "foreground";
298
314
  const resolvedColor = color ?? colors[colorKey];
package/dist/Text.mjs CHANGED
@@ -1,4 +1,5 @@
1
- export { Text } from './chunk-GNGLDL6Z.mjs';
1
+ export { Text } from './chunk-WJLKJMKR.mjs';
2
2
  import './chunk-QY3X2UYR.mjs';
3
3
  import './chunk-SOYNZDVY.mjs';
4
4
  import './chunk-2CE3TQVY.mjs';
5
+ import './chunk-Y6FXYEAI.mjs';
package/dist/Textarea.mjs CHANGED
@@ -1,6 +1,7 @@
1
- export { Textarea } from './chunk-6LQYY7HC.mjs';
2
- import './chunk-7H2OR44A.mjs';
1
+ export { Textarea } from './chunk-EH745HE5.mjs';
2
+ import './chunk-26BCI223.mjs';
3
+ import './chunk-DVK4G2GT.mjs';
3
4
  import './chunk-T7XZ7H7Y.mjs';
4
- import './chunk-5IKW3VNC.mjs';
5
5
  import './chunk-SOYNZDVY.mjs';
6
6
  import './chunk-2CE3TQVY.mjs';
7
+ import './chunk-Y6FXYEAI.mjs';