@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/Chip.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  var React3 = require('react');
4
4
  var reactNative = require('react-native');
5
- var Animated = require('react-native-reanimated');
5
+ var reactNativeEase = require('react-native-ease');
6
6
  var reactNativeSizeMatters = require('react-native-size-matters');
7
7
  var AntDesign = require('@expo/vector-icons/AntDesign');
8
8
  var Entypo = require('@expo/vector-icons/Entypo');
@@ -10,11 +10,12 @@ var Feather = require('@expo/vector-icons/Feather');
10
10
  var FontAwesome5 = require('@expo/vector-icons/FontAwesome5');
11
11
  var MaterialIcons = require('@expo/vector-icons/MaterialIcons');
12
12
  var Ionicons = require('@expo/vector-icons/Ionicons');
13
+ var reactNativeReanimated = require('react-native-reanimated');
14
+ var pressto = require('pressto');
13
15
 
14
16
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
17
 
16
18
  var React3__default = /*#__PURE__*/_interopDefault(React3);
17
- var Animated__default = /*#__PURE__*/_interopDefault(Animated);
18
19
  var AntDesign__default = /*#__PURE__*/_interopDefault(AntDesign);
19
20
  var Entypo__default = /*#__PURE__*/_interopDefault(Entypo);
20
21
  var Feather__default = /*#__PURE__*/_interopDefault(Feather);
@@ -22,18 +23,65 @@ var FontAwesome5__default = /*#__PURE__*/_interopDefault(FontAwesome5);
22
23
  var MaterialIcons__default = /*#__PURE__*/_interopDefault(MaterialIcons);
23
24
  var Ionicons__default = /*#__PURE__*/_interopDefault(Ionicons);
24
25
 
25
- // src/components/Chip/Chip.tsx
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
+ });
26
32
  var _haptics = null;
33
+ var _hapticsLoaded = false;
27
34
  async function getHaptics() {
28
35
  if (reactNative.Platform.OS === "web") return null;
29
- if (!_haptics) {
30
- _haptics = await import('expo-haptics');
36
+ if (!_hapticsLoaded) {
37
+ _hapticsLoaded = true;
38
+ try {
39
+ _haptics = await import('expo-haptics');
40
+ } catch {
41
+ _haptics = null;
42
+ }
31
43
  }
32
44
  return _haptics;
33
45
  }
46
+ var _pulsar = null;
47
+ var _pulsarChecked = false;
48
+ var _pulsarAvailable = false;
49
+ function isPulsarNativeRegistered() {
50
+ try {
51
+ const g = globalThis;
52
+ if (typeof g.__turboModuleProxy === "function") {
53
+ return g.__turboModuleProxy("RNPulsar") != null;
54
+ }
55
+ return reactNative.NativeModules?.RNPulsar != null;
56
+ } catch {
57
+ return false;
58
+ }
59
+ }
60
+ function getPulsar() {
61
+ if (reactNative.Platform.OS === "web") return null;
62
+ if (!_pulsarChecked) {
63
+ _pulsarChecked = true;
64
+ try {
65
+ if (isPulsarNativeRegistered()) {
66
+ _pulsar = __require("react-native-pulsar");
67
+ _pulsarAvailable = true;
68
+ }
69
+ } catch {
70
+ _pulsar = null;
71
+ _pulsarAvailable = false;
72
+ }
73
+ }
74
+ return _pulsarAvailable ? _pulsar : null;
75
+ }
34
76
  function selectionAsync() {
35
77
  if (reactNative.Platform.OS === "web") return;
36
- getHaptics().then((h) => h?.selectionAsync());
78
+ getHaptics().then((h) => {
79
+ if (h) {
80
+ h.selectionAsync();
81
+ } else {
82
+ getPulsar()?.Presets.System.selection();
83
+ }
84
+ });
37
85
  }
38
86
 
39
87
  // src/theme/colorUtils.ts
@@ -200,107 +248,92 @@ function Icon({ name, size, color, family }) {
200
248
  function renderIcon(name, size, color) {
201
249
  return React3__default.default.createElement(Icon, { name, size, color });
202
250
  }
203
- var SPRINGS = {
204
- /** Tight, premium press feel — Buttons, Toggle, Tabs triggers. */
205
- pressIn: { stiffness: 600, damping: 35, mass: 0.8 },
206
- pressOut: { stiffness: 280, damping: 22, mass: 0.8 }};
207
251
  var TIMINGS = {
208
252
  /** Color/opacity transitions on toggles, checkboxes, switches. */
209
253
  state: { duration: 160 }};
210
- var EASINGS = {
254
+ ({
211
255
  /** Material-style ease-out — natural deceleration for state changes. */
212
- standard: Animated.Easing.bezier(0.2, 0, 0, 1),
256
+ standard: reactNativeReanimated.Easing.bezier(0.2, 0, 0, 1),
213
257
  /** Strong ease-out for expanding surfaces (Accordion open). */
214
- expand: Animated.Easing.bezier(0.23, 1, 0.32, 1),
258
+ expand: reactNativeReanimated.Easing.bezier(0.23, 1, 0.32, 1),
215
259
  /** Quick ease-in for collapsing. */
216
- collapse: Animated.Easing.in(Animated.Easing.ease)
260
+ collapse: reactNativeReanimated.Easing.in(reactNativeReanimated.Easing.ease)
261
+ });
262
+ var COLOR_TRANSITION = {
263
+ type: "timing",
264
+ duration: TIMINGS.state.duration,
265
+ easing: [0.2, 0, 0, 1]
217
266
  };
218
267
  var PRESS_SCALE = {
219
268
  button: 0.95,
269
+ card: 0.98,
270
+ row: 0.97,
220
271
  chip: 0.94
221
272
  };
222
- function useHover() {
223
- const [hovered, setHovered] = React3.useState(false);
224
- const onMouseEnter = React3.useCallback(() => setHovered(true), []);
225
- const onMouseLeave = React3.useCallback(() => setHovered(false), []);
226
- if (reactNative.Platform.OS !== "web") {
227
- return { hovered: false, hoverHandlers: {} };
228
- }
229
- return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
230
- }
231
-
232
- // src/utils/usePressScale.ts
233
- function usePressScale({
234
- pressScale = PRESS_SCALE.button,
235
- hoverScale = 1.02,
236
- pressInSpring = SPRINGS.pressIn,
237
- pressOutSpring = SPRINGS.pressOut,
238
- disabled = false
239
- } = {}) {
240
- const scale2 = Animated.useSharedValue(1);
241
- const { hovered, hoverHandlers } = useHover();
242
- const onPressIn = React3.useCallback(() => {
243
- if (disabled) return;
244
- scale2.value = Animated.withSpring(pressScale, pressInSpring);
245
- }, [disabled, pressScale, pressInSpring, scale2]);
246
- const onPressOut = React3.useCallback(() => {
247
- if (disabled) return;
248
- scale2.value = Animated.withSpring(1, pressOutSpring);
249
- }, [disabled, pressOutSpring, scale2]);
250
- const hoverActive = reactNative.Platform.OS === "web" && hovered && hoverScale !== 1 && !disabled;
251
- const animatedStyle = Animated.useAnimatedStyle(() => ({
252
- transform: [
253
- { scale: scale2.value * (hoverActive ? hoverScale : 1) }
254
- ]
255
- }));
256
- return {
257
- animatedStyle,
258
- onPressIn,
259
- onPressOut,
260
- hoverHandlers
261
- };
262
- }
263
- function useColorTransition(active, options = {}) {
264
- const { duration = TIMINGS.state.duration } = options;
265
- const progress = Animated.useSharedValue(active ? 1 : 0);
266
- React3.useEffect(() => {
267
- progress.value = Animated.withTiming(active ? 1 : 0, { duration, easing: EASINGS.standard });
268
- }, [active, duration, progress]);
269
- return progress;
270
- }
273
+ pressto.createAnimatedPressable((progress) => {
274
+ "worklet";
275
+ const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
276
+ return { transform: [{ scale: scale2 }] };
277
+ });
278
+ pressto.createAnimatedPressable((progress) => {
279
+ "worklet";
280
+ const scale2 = 1 - (1 - PRESS_SCALE.card) * progress;
281
+ return { transform: [{ scale: scale2 }] };
282
+ });
283
+ pressto.createAnimatedPressable((progress) => {
284
+ "worklet";
285
+ const scale2 = 1 - (1 - PRESS_SCALE.row) * progress;
286
+ return { transform: [{ scale: scale2 }] };
287
+ });
288
+ var PressableChip = pressto.createAnimatedPressable((progress) => {
289
+ "worklet";
290
+ const scale2 = 1 - (1 - PRESS_SCALE.chip) * progress;
291
+ return { transform: [{ scale: scale2 }] };
292
+ });
293
+ pressto.createAnimatedPressable((progress) => {
294
+ "worklet";
295
+ const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
296
+ return { transform: [{ scale: scale2 }] };
297
+ });
271
298
 
272
299
  // src/components/Chip/Chip.tsx
273
300
  function ChipBase({ label, selected = false, onPress, icon, iconName, style, accessibilityLabel }) {
274
301
  const { colors } = useTheme();
275
- const { animatedStyle: scaleStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
276
- pressScale: PRESS_SCALE.chip
277
- });
278
- const colorProgress = useColorTransition(selected);
279
- const surfaceStyle = Animated.useAnimatedStyle(() => ({
280
- backgroundColor: Animated.interpolateColor(colorProgress.value, [0, 1], [colors.surface, colors.primary]),
281
- borderColor: Animated.interpolateColor(colorProgress.value, [0, 1], [colors.border, colors.primary])
282
- }));
283
- const textStyle = Animated.useAnimatedStyle(() => ({
284
- color: Animated.interpolateColor(colorProgress.value, [0, 1], [colors.foreground, colors.primaryForeground])
285
- }));
286
302
  const handlePress = () => {
287
303
  selectionAsync();
288
304
  onPress?.();
289
305
  };
290
306
  const resolvedIcon = iconName ? renderIcon(iconName, ms(13), selected ? colors.primaryForeground : colors.foreground) : icon;
291
- return /* @__PURE__ */ React3__default.default.createElement(Animated__default.default.View, { style: [styles.wrapper, scaleStyle, style], ...hoverHandlers }, /* @__PURE__ */ React3__default.default.createElement(
292
- reactNative.TouchableOpacity,
307
+ return /* @__PURE__ */ React3__default.default.createElement(reactNative.View, { style: [styles.wrapper, style] }, /* @__PURE__ */ React3__default.default.createElement(
308
+ PressableChip,
293
309
  {
294
310
  onPress: handlePress,
295
- onPressIn,
296
- onPressOut,
297
- activeOpacity: 1,
311
+ rippleColor: "transparent",
298
312
  touchSoundDisabled: true,
299
313
  accessibilityRole: "button",
300
314
  accessibilityLabel: accessibilityLabel ?? label,
301
315
  accessibilityState: { selected }
302
316
  },
303
- /* @__PURE__ */ React3__default.default.createElement(Animated__default.default.View, { style: [styles.chip, surfaceStyle] }, resolvedIcon ? /* @__PURE__ */ React3__default.default.createElement(reactNative.View, { style: styles.chipIcon }, resolvedIcon) : null, /* @__PURE__ */ React3__default.default.createElement(Animated__default.default.Text, { style: [styles.label, textStyle], allowFontScaling: true }, label))
317
+ /* @__PURE__ */ React3__default.default.createElement(
318
+ reactNativeEase.EaseView,
319
+ {
320
+ style: styles.chip,
321
+ animate: {
322
+ backgroundColor: selected ? colors.primary : colors.surface,
323
+ borderColor: selected ? colors.primary : colors.border
324
+ },
325
+ transition: COLOR_TRANSITION
326
+ },
327
+ resolvedIcon ? /* @__PURE__ */ React3__default.default.createElement(reactNative.View, { style: styles.chipIcon }, resolvedIcon) : null,
328
+ /* @__PURE__ */ React3__default.default.createElement(
329
+ reactNative.Text,
330
+ {
331
+ style: [styles.label, { color: selected ? colors.primaryForeground : colors.foreground }],
332
+ allowFontScaling: true
333
+ },
334
+ label
335
+ )
336
+ )
304
337
  ));
305
338
  }
306
339
  var Chip = React3__default.default.memo(ChipBase);
package/dist/Chip.mjs CHANGED
@@ -1,8 +1,8 @@
1
- export { Chip, ChipGroup } from './chunk-U4N7WF4Z.mjs';
2
- import './chunk-7H2OR44A.mjs';
1
+ export { Chip, ChipGroup } from './chunk-UREA2GYY.mjs';
2
+ import './chunk-3DKJ2GIC.mjs';
3
+ import './chunk-EJ7ZPXOH.mjs';
4
+ import './chunk-DVK4G2GT.mjs';
3
5
  import './chunk-T7XZ7H7Y.mjs';
4
- import './chunk-QCNARS3X.mjs';
5
- import './chunk-RTC3CFXF.mjs';
6
- import './chunk-5IKW3VNC.mjs';
7
6
  import './chunk-SOYNZDVY.mjs';
8
7
  import './chunk-2CE3TQVY.mjs';
8
+ import './chunk-Y6FXYEAI.mjs';
@@ -4,7 +4,6 @@ var React3 = require('react');
4
4
  var reactNative = require('react-native');
5
5
  var bottomSheet = require('@gorhom/bottom-sheet');
6
6
  var vectorIcons = require('@expo/vector-icons');
7
- var Animated = require('react-native-reanimated');
8
7
  var reactNativeSizeMatters = require('react-native-size-matters');
9
8
  var AntDesign = require('@expo/vector-icons/AntDesign');
10
9
  var Entypo = require('@expo/vector-icons/Entypo');
@@ -12,11 +11,12 @@ var Feather = require('@expo/vector-icons/Feather');
12
11
  var FontAwesome5 = require('@expo/vector-icons/FontAwesome5');
13
12
  var MaterialIcons = require('@expo/vector-icons/MaterialIcons');
14
13
  var Ionicons = require('@expo/vector-icons/Ionicons');
14
+ var pressto = require('pressto');
15
+ var reactNativeReanimated = require('react-native-reanimated');
15
16
 
16
17
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
17
18
 
18
19
  var React3__default = /*#__PURE__*/_interopDefault(React3);
19
- var Animated__default = /*#__PURE__*/_interopDefault(Animated);
20
20
  var AntDesign__default = /*#__PURE__*/_interopDefault(AntDesign);
21
21
  var Entypo__default = /*#__PURE__*/_interopDefault(Entypo);
22
22
  var Feather__default = /*#__PURE__*/_interopDefault(Feather);
@@ -24,26 +24,85 @@ var FontAwesome5__default = /*#__PURE__*/_interopDefault(FontAwesome5);
24
24
  var MaterialIcons__default = /*#__PURE__*/_interopDefault(MaterialIcons);
25
25
  var Ionicons__default = /*#__PURE__*/_interopDefault(Ionicons);
26
26
 
27
- // src/components/ConfirmDialog/ConfirmDialog.tsx
27
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
28
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
29
+ }) : x)(function(x) {
30
+ if (typeof require !== "undefined") return require.apply(this, arguments);
31
+ throw Error('Dynamic require of "' + x + '" is not supported');
32
+ });
28
33
  var _haptics = null;
34
+ var _hapticsLoaded = false;
29
35
  async function getHaptics() {
30
36
  if (reactNative.Platform.OS === "web") return null;
31
- if (!_haptics) {
32
- _haptics = await import('expo-haptics');
37
+ if (!_hapticsLoaded) {
38
+ _hapticsLoaded = true;
39
+ try {
40
+ _haptics = await import('expo-haptics');
41
+ } catch {
42
+ _haptics = null;
43
+ }
33
44
  }
34
45
  return _haptics;
35
46
  }
47
+ var _pulsar = null;
48
+ var _pulsarChecked = false;
49
+ var _pulsarAvailable = false;
50
+ function isPulsarNativeRegistered() {
51
+ try {
52
+ const g = globalThis;
53
+ if (typeof g.__turboModuleProxy === "function") {
54
+ return g.__turboModuleProxy("RNPulsar") != null;
55
+ }
56
+ return reactNative.NativeModules?.RNPulsar != null;
57
+ } catch {
58
+ return false;
59
+ }
60
+ }
61
+ function getPulsar() {
62
+ if (reactNative.Platform.OS === "web") return null;
63
+ if (!_pulsarChecked) {
64
+ _pulsarChecked = true;
65
+ try {
66
+ if (isPulsarNativeRegistered()) {
67
+ _pulsar = __require("react-native-pulsar");
68
+ _pulsarAvailable = true;
69
+ }
70
+ } catch {
71
+ _pulsar = null;
72
+ _pulsarAvailable = false;
73
+ }
74
+ }
75
+ return _pulsarAvailable ? _pulsar : null;
76
+ }
36
77
  function selectionAsync() {
37
78
  if (reactNative.Platform.OS === "web") return;
38
- getHaptics().then((h) => h?.selectionAsync());
79
+ getHaptics().then((h) => {
80
+ if (h) {
81
+ h.selectionAsync();
82
+ } else {
83
+ getPulsar()?.Presets.System.selection();
84
+ }
85
+ });
39
86
  }
40
87
  function impactMedium() {
41
88
  if (reactNative.Platform.OS === "web") return;
42
- getHaptics().then((h) => h?.impactAsync(h.ImpactFeedbackStyle.Medium));
89
+ getHaptics().then((h) => {
90
+ if (h) {
91
+ h.impactAsync(h.ImpactFeedbackStyle.Medium);
92
+ } else {
93
+ getPulsar()?.Presets.System.impactMedium();
94
+ }
95
+ });
43
96
  }
44
97
  function notificationSuccess() {
45
98
  if (reactNative.Platform.OS === "web") return;
46
- getHaptics().then((h) => h?.notificationAsync(h.NotificationFeedbackType.Success));
99
+ getHaptics().then((h) => {
100
+ if (h) {
101
+ h.notificationAsync(h.NotificationFeedbackType.Success);
102
+ } else {
103
+ getPulsar()?.Presets.System.notificationSuccess();
104
+ }
105
+ });
47
106
  }
48
107
 
49
108
  // src/theme/colorUtils.ts
@@ -230,65 +289,50 @@ var TYPOGRAPHY = {
230
289
  letterSpacing: 0
231
290
  }
232
291
  };
233
- var SPRINGS = {
234
- /** Tight, premium press feel — Buttons, Toggle, Tabs triggers. */
235
- pressIn: { stiffness: 600, damping: 35, mass: 0.8 },
236
- pressOut: { stiffness: 280, damping: 22, mass: 0.8 }};
237
292
  ({
238
293
  /** Material-style ease-out — natural deceleration for state changes. */
239
- standard: Animated.Easing.bezier(0.2, 0, 0, 1),
294
+ standard: reactNativeReanimated.Easing.bezier(0.2, 0, 0, 1),
240
295
  /** Strong ease-out for expanding surfaces (Accordion open). */
241
- expand: Animated.Easing.bezier(0.23, 1, 0.32, 1),
296
+ expand: reactNativeReanimated.Easing.bezier(0.23, 1, 0.32, 1),
242
297
  /** Quick ease-in for collapsing. */
243
- collapse: Animated.Easing.in(Animated.Easing.ease)
298
+ collapse: reactNativeReanimated.Easing.in(reactNativeReanimated.Easing.ease)
244
299
  });
245
300
  var PRESS_SCALE = {
246
- button: 0.95};
247
- function useHover() {
248
- const [hovered, setHovered] = React3.useState(false);
249
- const onMouseEnter = React3.useCallback(() => setHovered(true), []);
250
- const onMouseLeave = React3.useCallback(() => setHovered(false), []);
251
- if (reactNative.Platform.OS !== "web") {
252
- return { hovered: false, hoverHandlers: {} };
253
- }
254
- return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
255
- }
256
-
257
- // src/utils/usePressScale.ts
258
- function usePressScale({
259
- pressScale = PRESS_SCALE.button,
260
- hoverScale = 1.02,
261
- pressInSpring = SPRINGS.pressIn,
262
- pressOutSpring = SPRINGS.pressOut,
263
- disabled = false
264
- } = {}) {
265
- const scale2 = Animated.useSharedValue(1);
266
- const { hovered, hoverHandlers } = useHover();
267
- const onPressIn = React3.useCallback(() => {
268
- if (disabled) return;
269
- scale2.value = Animated.withSpring(pressScale, pressInSpring);
270
- }, [disabled, pressScale, pressInSpring, scale2]);
271
- const onPressOut = React3.useCallback(() => {
272
- if (disabled) return;
273
- scale2.value = Animated.withSpring(1, pressOutSpring);
274
- }, [disabled, pressOutSpring, scale2]);
275
- const hoverActive = reactNative.Platform.OS === "web" && hovered && hoverScale !== 1 && !disabled;
276
- const animatedStyle = Animated.useAnimatedStyle(() => ({
277
- transform: [
278
- { scale: scale2.value * (hoverActive ? hoverScale : 1) }
279
- ]
280
- }));
281
- return {
282
- animatedStyle,
283
- onPressIn,
284
- onPressOut,
285
- hoverHandlers
286
- };
287
- }
301
+ button: 0.95,
302
+ card: 0.98,
303
+ row: 0.97,
304
+ chip: 0.94
305
+ };
306
+ var PressableButton = pressto.createAnimatedPressable((progress) => {
307
+ "worklet";
308
+ const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
309
+ return { transform: [{ scale: scale2 }] };
310
+ });
311
+ pressto.createAnimatedPressable((progress) => {
312
+ "worklet";
313
+ const scale2 = 1 - (1 - PRESS_SCALE.card) * progress;
314
+ return { transform: [{ scale: scale2 }] };
315
+ });
316
+ pressto.createAnimatedPressable((progress) => {
317
+ "worklet";
318
+ const scale2 = 1 - (1 - PRESS_SCALE.row) * progress;
319
+ return { transform: [{ scale: scale2 }] };
320
+ });
321
+ pressto.createAnimatedPressable((progress) => {
322
+ "worklet";
323
+ const scale2 = 1 - (1 - PRESS_SCALE.chip) * progress;
324
+ return { transform: [{ scale: scale2 }] };
325
+ });
326
+ pressto.createAnimatedPressable((progress) => {
327
+ "worklet";
328
+ const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
329
+ return { transform: [{ scale: scale2 }] };
330
+ });
288
331
 
289
332
  // src/components/Button/Button.tsx
290
333
  var containerSizeStyles = {
291
- sm: { paddingHorizontal: s(16), paddingVertical: vs(10), minHeight: 40 },
334
+ // AUDIT FIX: sm was 40pt below Apple HIG 44pt minimum touch target.
335
+ sm: { paddingHorizontal: s(16), paddingVertical: vs(12), minHeight: 44 },
292
336
  md: { paddingHorizontal: s(24), paddingVertical: vs(14), minHeight: 48 },
293
337
  lg: { paddingHorizontal: s(28), paddingVertical: vs(16), minHeight: 56 }
294
338
  };
@@ -312,18 +356,13 @@ function ButtonBase({
312
356
  style,
313
357
  onPress,
314
358
  accessibilityLabel,
315
- accessibilityHint,
316
- ...props
359
+ accessibilityHint
317
360
  }) {
318
361
  const { colors } = useTheme();
319
362
  const isDisabled = disabled || loading;
320
- const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
321
- pressScale: PRESS_SCALE.button,
322
- disabled: isDisabled
323
- });
324
- const handlePress = (e) => {
363
+ const handlePress = () => {
325
364
  impactMedium();
326
- onPress?.(e);
365
+ onPress?.();
327
366
  };
328
367
  const containerVariantStyle = {
329
368
  primary: { backgroundColor: colors.primary },
@@ -346,54 +385,45 @@ function ButtonBase({
346
385
  const styleArray = Array.isArray(style) ? style : style ? [style] : [];
347
386
  const flatStyle = reactNative.StyleSheet.flatten(styleArray);
348
387
  const { flex, ...restStyle } = flatStyle || {};
349
- return /* @__PURE__ */ React3__default.default.createElement(
350
- Animated__default.default.View,
388
+ return /* @__PURE__ */ React3__default.default.createElement(reactNative.View, { style: [fullWidth && styles.fullWidth, flex !== void 0 && { flex }] }, /* @__PURE__ */ React3__default.default.createElement(
389
+ PressableButton,
351
390
  {
352
- style: [fullWidth && styles.fullWidth, flex !== void 0 && { flex }, animatedStyle],
353
- ...hoverHandlers
391
+ style: [
392
+ styles.base,
393
+ containerVariantStyle,
394
+ containerSizeStyles[size],
395
+ fullWidth && styles.fullWidth,
396
+ isDisabled && styles.disabled,
397
+ restStyle
398
+ ],
399
+ enabled: !isDisabled,
400
+ onPress: handlePress,
401
+ rippleColor: "transparent",
402
+ touchSoundDisabled: true,
403
+ activateOnHover: true,
404
+ accessibilityRole: "button",
405
+ accessibilityLabel: accessibilityLabel ?? label,
406
+ accessibilityHint,
407
+ accessibilityState: { disabled: isDisabled, busy: loading }
354
408
  },
355
- /* @__PURE__ */ React3__default.default.createElement(
356
- reactNative.TouchableOpacity,
409
+ loading ? /* @__PURE__ */ React3__default.default.createElement(React3__default.default.Fragment, null, /* @__PURE__ */ React3__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor, style: { marginRight: s(6) } }), /* @__PURE__ */ React3__default.default.createElement(
410
+ reactNative.Text,
357
411
  {
358
- style: [
359
- styles.base,
360
- containerVariantStyle,
361
- containerSizeStyles[size],
362
- fullWidth && styles.fullWidth,
363
- isDisabled && styles.disabled,
364
- restStyle
365
- ],
366
- disabled: isDisabled,
367
- activeOpacity: 1,
368
- touchSoundDisabled: true,
369
- onPress: handlePress,
370
- onPressIn,
371
- onPressOut,
372
- accessibilityRole: "button",
373
- accessibilityLabel: accessibilityLabel ?? label,
374
- accessibilityHint,
375
- accessibilityState: { disabled: isDisabled, busy: loading },
376
- ...props
412
+ style: [styles.label, labelVariantStyle, labelSizeStyles[size], styles.labelLoading],
413
+ allowFontScaling: true,
414
+ numberOfLines: 1
377
415
  },
378
- loading ? /* @__PURE__ */ React3__default.default.createElement(React3__default.default.Fragment, null, /* @__PURE__ */ React3__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor, style: { marginRight: s(6) } }), /* @__PURE__ */ React3__default.default.createElement(
379
- reactNative.Text,
380
- {
381
- style: [styles.label, labelVariantStyle, labelSizeStyles[size], styles.labelLoading],
382
- allowFontScaling: true,
383
- numberOfLines: 1
384
- },
385
- label
386
- )) : /* @__PURE__ */ React3__default.default.createElement(React3__default.default.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React3__default.default.createElement(React3__default.default.Fragment, null, effectiveIcon), /* @__PURE__ */ React3__default.default.createElement(
387
- reactNative.Text,
388
- {
389
- style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
390
- allowFontScaling: true,
391
- numberOfLines: 1
392
- },
393
- label
394
- ), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React3__default.default.createElement(React3__default.default.Fragment, null, effectiveIcon))
395
- )
396
- );
416
+ label
417
+ )) : /* @__PURE__ */ React3__default.default.createElement(React3__default.default.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React3__default.default.createElement(React3__default.default.Fragment, null, effectiveIcon), /* @__PURE__ */ React3__default.default.createElement(
418
+ reactNative.Text,
419
+ {
420
+ style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
421
+ allowFontScaling: true,
422
+ numberOfLines: 1
423
+ },
424
+ label
425
+ ), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React3__default.default.createElement(React3__default.default.Fragment, null, effectiveIcon))
426
+ ));
397
427
  }
398
428
  var Button = React3__default.default.memo(ButtonBase);
399
429
  var styles = reactNative.StyleSheet.create({
@@ -1,9 +1,10 @@
1
- export { ConfirmDialog } from './chunk-HSPSMN6U.mjs';
2
- import './chunk-CRYBX2CM.mjs';
3
- import './chunk-T7XZ7H7Y.mjs';
4
- import './chunk-QCNARS3X.mjs';
5
- import './chunk-RTC3CFXF.mjs';
6
- import './chunk-5IKW3VNC.mjs';
1
+ export { ConfirmDialog } from './chunk-7QHVVCB3.mjs';
2
+ import './chunk-2TFTAWVJ.mjs';
3
+ import './chunk-3DKJ2GIC.mjs';
4
+ import './chunk-EJ7ZPXOH.mjs';
5
+ import './chunk-DVK4G2GT.mjs';
7
6
  import './chunk-QY3X2UYR.mjs';
7
+ import './chunk-T7XZ7H7Y.mjs';
8
8
  import './chunk-SOYNZDVY.mjs';
9
9
  import './chunk-2CE3TQVY.mjs';
10
+ import './chunk-Y6FXYEAI.mjs';
@@ -1,3 +1,4 @@
1
1
  export { CurrencyDisplay } from './chunk-BRKYVJVV.mjs';
2
2
  import './chunk-SOYNZDVY.mjs';
3
3
  import './chunk-2CE3TQVY.mjs';
4
+ import './chunk-Y6FXYEAI.mjs';
@@ -6,7 +6,7 @@ interface CurrencyInputProps {
6
6
  onChangeText?: (formatted: string) => void;
7
7
  /** Called with the parsed numeric value (no separators, no prefix). */
8
8
  onChangeValue?: (raw: number) => void;
9
- /** Symbol prepended to the formatted value. Defaults to `'$'`. */
9
+ /** Currency symbol shown left of the value. Any string (`'$'`, `'€'`, `'£'`, `'COP '`). Defaults to `'$'`. */
10
10
  prefix?: string;
11
11
  /** Character used to separate groups of three digits. Defaults to `'.'`. */
12
12
  thousandsSeparator?: '.' | ',';
@@ -6,7 +6,7 @@ interface CurrencyInputProps {
6
6
  onChangeText?: (formatted: string) => void;
7
7
  /** Called with the parsed numeric value (no separators, no prefix). */
8
8
  onChangeValue?: (raw: number) => void;
9
- /** Symbol prepended to the formatted value. Defaults to `'$'`. */
9
+ /** Currency symbol shown left of the value. Any string (`'$'`, `'€'`, `'£'`, `'COP '`). Defaults to `'$'`. */
10
10
  prefix?: string;
11
11
  /** Character used to separate groups of three digits. Defaults to `'.'`. */
12
12
  thousandsSeparator?: '.' | ',';