@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/Button.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
- import { TouchableOpacityProps } from 'react-native';
2
+ import { ViewStyle } from 'react-native';
3
3
 
4
4
  type ButtonVariant = 'primary' | 'secondary' | 'text' | 'destructive';
5
5
  type ButtonSize = 'sm' | 'md' | 'lg';
6
- interface ButtonProps extends TouchableOpacityProps {
6
+ interface ButtonProps {
7
7
  label: string;
8
8
  variant?: ButtonVariant;
9
9
  size?: ButtonSize;
@@ -18,8 +18,13 @@ interface ButtonProps extends TouchableOpacityProps {
18
18
  iconName?: string;
19
19
  iconColor?: string;
20
20
  iconPosition?: 'left' | 'right';
21
+ disabled?: boolean;
22
+ style?: ViewStyle;
23
+ onPress?: () => void;
24
+ accessibilityLabel?: string;
25
+ accessibilityHint?: string;
21
26
  }
22
- declare function ButtonBase({ label, variant, size, loading, fullWidth, icon, iconName, iconColor, iconPosition, disabled, style, onPress, accessibilityLabel, accessibilityHint, ...props }: ButtonProps): React.JSX.Element;
27
+ declare function ButtonBase({ label, variant, size, loading, fullWidth, icon, iconName, iconColor, iconPosition, disabled, style, onPress, accessibilityLabel, accessibilityHint, }: ButtonProps): React.JSX.Element;
23
28
  declare const Button: React.MemoExoticComponent<typeof ButtonBase>;
24
29
 
25
30
  export { Button, type ButtonProps, type ButtonSize, type ButtonVariant };
package/dist/Button.js CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  var React3 = require('react');
4
4
  var reactNative = require('react-native');
5
- var Animated = require('react-native-reanimated');
6
5
  var reactNativeSizeMatters = require('react-native-size-matters');
7
6
  var AntDesign = require('@expo/vector-icons/AntDesign');
8
7
  var Entypo = require('@expo/vector-icons/Entypo');
@@ -10,11 +9,12 @@ var Feather = require('@expo/vector-icons/Feather');
10
9
  var FontAwesome5 = require('@expo/vector-icons/FontAwesome5');
11
10
  var MaterialIcons = require('@expo/vector-icons/MaterialIcons');
12
11
  var Ionicons = require('@expo/vector-icons/Ionicons');
12
+ var pressto = require('pressto');
13
+ var reactNativeReanimated = require('react-native-reanimated');
13
14
 
14
15
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
16
 
16
17
  var React3__default = /*#__PURE__*/_interopDefault(React3);
17
- var Animated__default = /*#__PURE__*/_interopDefault(Animated);
18
18
  var AntDesign__default = /*#__PURE__*/_interopDefault(AntDesign);
19
19
  var Entypo__default = /*#__PURE__*/_interopDefault(Entypo);
20
20
  var Feather__default = /*#__PURE__*/_interopDefault(Feather);
@@ -22,18 +22,65 @@ var FontAwesome5__default = /*#__PURE__*/_interopDefault(FontAwesome5);
22
22
  var MaterialIcons__default = /*#__PURE__*/_interopDefault(MaterialIcons);
23
23
  var Ionicons__default = /*#__PURE__*/_interopDefault(Ionicons);
24
24
 
25
- // src/components/Button/Button.tsx
25
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
26
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
27
+ }) : x)(function(x) {
28
+ if (typeof require !== "undefined") return require.apply(this, arguments);
29
+ throw Error('Dynamic require of "' + x + '" is not supported');
30
+ });
26
31
  var _haptics = null;
32
+ var _hapticsLoaded = false;
27
33
  async function getHaptics() {
28
34
  if (reactNative.Platform.OS === "web") return null;
29
- if (!_haptics) {
30
- _haptics = await import('expo-haptics');
35
+ if (!_hapticsLoaded) {
36
+ _hapticsLoaded = true;
37
+ try {
38
+ _haptics = await import('expo-haptics');
39
+ } catch {
40
+ _haptics = null;
41
+ }
31
42
  }
32
43
  return _haptics;
33
44
  }
45
+ var _pulsar = null;
46
+ var _pulsarChecked = false;
47
+ var _pulsarAvailable = false;
48
+ function isPulsarNativeRegistered() {
49
+ try {
50
+ const g = globalThis;
51
+ if (typeof g.__turboModuleProxy === "function") {
52
+ return g.__turboModuleProxy("RNPulsar") != null;
53
+ }
54
+ return reactNative.NativeModules?.RNPulsar != null;
55
+ } catch {
56
+ return false;
57
+ }
58
+ }
59
+ function getPulsar() {
60
+ if (reactNative.Platform.OS === "web") return null;
61
+ if (!_pulsarChecked) {
62
+ _pulsarChecked = true;
63
+ try {
64
+ if (isPulsarNativeRegistered()) {
65
+ _pulsar = __require("react-native-pulsar");
66
+ _pulsarAvailable = true;
67
+ }
68
+ } catch {
69
+ _pulsar = null;
70
+ _pulsarAvailable = false;
71
+ }
72
+ }
73
+ return _pulsarAvailable ? _pulsar : null;
74
+ }
34
75
  function impactMedium() {
35
76
  if (reactNative.Platform.OS === "web") return;
36
- getHaptics().then((h) => h?.impactAsync(h.ImpactFeedbackStyle.Medium));
77
+ getHaptics().then((h) => {
78
+ if (h) {
79
+ h.impactAsync(h.ImpactFeedbackStyle.Medium);
80
+ } else {
81
+ getPulsar()?.Presets.System.impactMedium();
82
+ }
83
+ });
37
84
  }
38
85
 
39
86
  // src/theme/colorUtils.ts
@@ -220,65 +267,50 @@ var TYPOGRAPHY = {
220
267
  letterSpacing: 0
221
268
  }
222
269
  };
223
- var SPRINGS = {
224
- /** Tight, premium press feel — Buttons, Toggle, Tabs triggers. */
225
- pressIn: { stiffness: 600, damping: 35, mass: 0.8 },
226
- pressOut: { stiffness: 280, damping: 22, mass: 0.8 }};
227
270
  ({
228
271
  /** Material-style ease-out — natural deceleration for state changes. */
229
- standard: Animated.Easing.bezier(0.2, 0, 0, 1),
272
+ standard: reactNativeReanimated.Easing.bezier(0.2, 0, 0, 1),
230
273
  /** Strong ease-out for expanding surfaces (Accordion open). */
231
- expand: Animated.Easing.bezier(0.23, 1, 0.32, 1),
274
+ expand: reactNativeReanimated.Easing.bezier(0.23, 1, 0.32, 1),
232
275
  /** Quick ease-in for collapsing. */
233
- collapse: Animated.Easing.in(Animated.Easing.ease)
276
+ collapse: reactNativeReanimated.Easing.in(reactNativeReanimated.Easing.ease)
234
277
  });
235
278
  var PRESS_SCALE = {
236
- button: 0.95};
237
- function useHover() {
238
- const [hovered, setHovered] = React3.useState(false);
239
- const onMouseEnter = React3.useCallback(() => setHovered(true), []);
240
- const onMouseLeave = React3.useCallback(() => setHovered(false), []);
241
- if (reactNative.Platform.OS !== "web") {
242
- return { hovered: false, hoverHandlers: {} };
243
- }
244
- return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
245
- }
246
-
247
- // src/utils/usePressScale.ts
248
- function usePressScale({
249
- pressScale = PRESS_SCALE.button,
250
- hoverScale = 1.02,
251
- pressInSpring = SPRINGS.pressIn,
252
- pressOutSpring = SPRINGS.pressOut,
253
- disabled = false
254
- } = {}) {
255
- const scale2 = Animated.useSharedValue(1);
256
- const { hovered, hoverHandlers } = useHover();
257
- const onPressIn = React3.useCallback(() => {
258
- if (disabled) return;
259
- scale2.value = Animated.withSpring(pressScale, pressInSpring);
260
- }, [disabled, pressScale, pressInSpring, scale2]);
261
- const onPressOut = React3.useCallback(() => {
262
- if (disabled) return;
263
- scale2.value = Animated.withSpring(1, pressOutSpring);
264
- }, [disabled, pressOutSpring, scale2]);
265
- const hoverActive = reactNative.Platform.OS === "web" && hovered && hoverScale !== 1 && !disabled;
266
- const animatedStyle = Animated.useAnimatedStyle(() => ({
267
- transform: [
268
- { scale: scale2.value * (hoverActive ? hoverScale : 1) }
269
- ]
270
- }));
271
- return {
272
- animatedStyle,
273
- onPressIn,
274
- onPressOut,
275
- hoverHandlers
276
- };
277
- }
279
+ button: 0.95,
280
+ card: 0.98,
281
+ row: 0.97,
282
+ chip: 0.94
283
+ };
284
+ var PressableButton = pressto.createAnimatedPressable((progress) => {
285
+ "worklet";
286
+ const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
287
+ return { transform: [{ scale: scale2 }] };
288
+ });
289
+ pressto.createAnimatedPressable((progress) => {
290
+ "worklet";
291
+ const scale2 = 1 - (1 - PRESS_SCALE.card) * progress;
292
+ return { transform: [{ scale: scale2 }] };
293
+ });
294
+ pressto.createAnimatedPressable((progress) => {
295
+ "worklet";
296
+ const scale2 = 1 - (1 - PRESS_SCALE.row) * progress;
297
+ return { transform: [{ scale: scale2 }] };
298
+ });
299
+ pressto.createAnimatedPressable((progress) => {
300
+ "worklet";
301
+ const scale2 = 1 - (1 - PRESS_SCALE.chip) * progress;
302
+ return { transform: [{ scale: scale2 }] };
303
+ });
304
+ pressto.createAnimatedPressable((progress) => {
305
+ "worklet";
306
+ const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
307
+ return { transform: [{ scale: scale2 }] };
308
+ });
278
309
 
279
310
  // src/components/Button/Button.tsx
280
311
  var containerSizeStyles = {
281
- sm: { paddingHorizontal: s(16), paddingVertical: vs(10), minHeight: 40 },
312
+ // AUDIT FIX: sm was 40pt below Apple HIG 44pt minimum touch target.
313
+ sm: { paddingHorizontal: s(16), paddingVertical: vs(12), minHeight: 44 },
282
314
  md: { paddingHorizontal: s(24), paddingVertical: vs(14), minHeight: 48 },
283
315
  lg: { paddingHorizontal: s(28), paddingVertical: vs(16), minHeight: 56 }
284
316
  };
@@ -302,18 +334,13 @@ function ButtonBase({
302
334
  style,
303
335
  onPress,
304
336
  accessibilityLabel,
305
- accessibilityHint,
306
- ...props
337
+ accessibilityHint
307
338
  }) {
308
339
  const { colors } = useTheme();
309
340
  const isDisabled = disabled || loading;
310
- const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
311
- pressScale: PRESS_SCALE.button,
312
- disabled: isDisabled
313
- });
314
- const handlePress = (e) => {
341
+ const handlePress = () => {
315
342
  impactMedium();
316
- onPress?.(e);
343
+ onPress?.();
317
344
  };
318
345
  const containerVariantStyle = {
319
346
  primary: { backgroundColor: colors.primary },
@@ -336,54 +363,45 @@ function ButtonBase({
336
363
  const styleArray = Array.isArray(style) ? style : style ? [style] : [];
337
364
  const flatStyle = reactNative.StyleSheet.flatten(styleArray);
338
365
  const { flex, ...restStyle } = flatStyle || {};
339
- return /* @__PURE__ */ React3__default.default.createElement(
340
- Animated__default.default.View,
366
+ return /* @__PURE__ */ React3__default.default.createElement(reactNative.View, { style: [fullWidth && styles.fullWidth, flex !== void 0 && { flex }] }, /* @__PURE__ */ React3__default.default.createElement(
367
+ PressableButton,
341
368
  {
342
- style: [fullWidth && styles.fullWidth, flex !== void 0 && { flex }, animatedStyle],
343
- ...hoverHandlers
369
+ style: [
370
+ styles.base,
371
+ containerVariantStyle,
372
+ containerSizeStyles[size],
373
+ fullWidth && styles.fullWidth,
374
+ isDisabled && styles.disabled,
375
+ restStyle
376
+ ],
377
+ enabled: !isDisabled,
378
+ onPress: handlePress,
379
+ rippleColor: "transparent",
380
+ touchSoundDisabled: true,
381
+ activateOnHover: true,
382
+ accessibilityRole: "button",
383
+ accessibilityLabel: accessibilityLabel ?? label,
384
+ accessibilityHint,
385
+ accessibilityState: { disabled: isDisabled, busy: loading }
344
386
  },
345
- /* @__PURE__ */ React3__default.default.createElement(
346
- reactNative.TouchableOpacity,
387
+ 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(
388
+ reactNative.Text,
389
+ {
390
+ style: [styles.label, labelVariantStyle, labelSizeStyles[size], styles.labelLoading],
391
+ allowFontScaling: true,
392
+ numberOfLines: 1
393
+ },
394
+ label
395
+ )) : /* @__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(
396
+ reactNative.Text,
347
397
  {
348
- style: [
349
- styles.base,
350
- containerVariantStyle,
351
- containerSizeStyles[size],
352
- fullWidth && styles.fullWidth,
353
- isDisabled && styles.disabled,
354
- restStyle
355
- ],
356
- disabled: isDisabled,
357
- activeOpacity: 1,
358
- touchSoundDisabled: true,
359
- onPress: handlePress,
360
- onPressIn,
361
- onPressOut,
362
- accessibilityRole: "button",
363
- accessibilityLabel: accessibilityLabel ?? label,
364
- accessibilityHint,
365
- accessibilityState: { disabled: isDisabled, busy: loading },
366
- ...props
398
+ style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
399
+ allowFontScaling: true,
400
+ numberOfLines: 1
367
401
  },
368
- 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(
369
- reactNative.Text,
370
- {
371
- style: [styles.label, labelVariantStyle, labelSizeStyles[size], styles.labelLoading],
372
- allowFontScaling: true,
373
- numberOfLines: 1
374
- },
375
- label
376
- )) : /* @__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(
377
- reactNative.Text,
378
- {
379
- style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
380
- allowFontScaling: true,
381
- numberOfLines: 1
382
- },
383
- label
384
- ), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React3__default.default.createElement(React3__default.default.Fragment, null, effectiveIcon))
385
- )
386
- );
402
+ label
403
+ ), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React3__default.default.createElement(React3__default.default.Fragment, null, effectiveIcon))
404
+ ));
387
405
  }
388
406
  var Button = React3__default.default.memo(ButtonBase);
389
407
  var styles = reactNative.StyleSheet.create({
package/dist/Button.mjs CHANGED
@@ -1,8 +1,9 @@
1
- export { Button } from './chunk-CRYBX2CM.mjs';
2
- import './chunk-T7XZ7H7Y.mjs';
3
- import './chunk-QCNARS3X.mjs';
4
- import './chunk-RTC3CFXF.mjs';
5
- import './chunk-5IKW3VNC.mjs';
1
+ export { Button } from './chunk-2TFTAWVJ.mjs';
2
+ import './chunk-3DKJ2GIC.mjs';
3
+ import './chunk-EJ7ZPXOH.mjs';
4
+ import './chunk-DVK4G2GT.mjs';
6
5
  import './chunk-QY3X2UYR.mjs';
6
+ import './chunk-T7XZ7H7Y.mjs';
7
7
  import './chunk-SOYNZDVY.mjs';
8
8
  import './chunk-2CE3TQVY.mjs';
9
+ import './chunk-Y6FXYEAI.mjs';
@@ -1,2 +1,3 @@
1
1
  export { ButtonGroup } from './chunk-3BBOZ3OQ.mjs';
2
2
  import './chunk-2CE3TQVY.mjs';
3
+ import './chunk-Y6FXYEAI.mjs';
package/dist/Card.js CHANGED
@@ -2,26 +2,73 @@
2
2
 
3
3
  var React2 = require('react');
4
4
  var reactNative = require('react-native');
5
- var Animated = require('react-native-reanimated');
6
5
  var reactNativeSizeMatters = require('react-native-size-matters');
6
+ var pressto = require('pressto');
7
+ var reactNativeReanimated = require('react-native-reanimated');
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
- var Animated__default = /*#__PURE__*/_interopDefault(Animated);
12
12
 
13
- // src/components/Card/Card.tsx
13
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
14
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
15
+ }) : x)(function(x) {
16
+ if (typeof require !== "undefined") return require.apply(this, arguments);
17
+ throw Error('Dynamic require of "' + x + '" is not supported');
18
+ });
14
19
  var _haptics = null;
20
+ var _hapticsLoaded = false;
15
21
  async function getHaptics() {
16
22
  if (reactNative.Platform.OS === "web") return null;
17
- if (!_haptics) {
18
- _haptics = await import('expo-haptics');
23
+ if (!_hapticsLoaded) {
24
+ _hapticsLoaded = true;
25
+ try {
26
+ _haptics = await import('expo-haptics');
27
+ } catch {
28
+ _haptics = null;
29
+ }
19
30
  }
20
31
  return _haptics;
21
32
  }
33
+ var _pulsar = null;
34
+ var _pulsarChecked = false;
35
+ var _pulsarAvailable = false;
36
+ function isPulsarNativeRegistered() {
37
+ try {
38
+ const g = globalThis;
39
+ if (typeof g.__turboModuleProxy === "function") {
40
+ return g.__turboModuleProxy("RNPulsar") != null;
41
+ }
42
+ return reactNative.NativeModules?.RNPulsar != null;
43
+ } catch {
44
+ return false;
45
+ }
46
+ }
47
+ function getPulsar() {
48
+ if (reactNative.Platform.OS === "web") return null;
49
+ if (!_pulsarChecked) {
50
+ _pulsarChecked = true;
51
+ try {
52
+ if (isPulsarNativeRegistered()) {
53
+ _pulsar = __require("react-native-pulsar");
54
+ _pulsarAvailable = true;
55
+ }
56
+ } catch {
57
+ _pulsar = null;
58
+ _pulsarAvailable = false;
59
+ }
60
+ }
61
+ return _pulsarAvailable ? _pulsar : null;
62
+ }
22
63
  function impactLight() {
23
64
  if (reactNative.Platform.OS === "web") return;
24
- getHaptics().then((h) => h?.impactAsync(h.ImpactFeedbackStyle.Light));
65
+ getHaptics().then((h) => {
66
+ if (h) {
67
+ h.impactAsync(h.ImpactFeedbackStyle.Light);
68
+ } else {
69
+ getPulsar()?.Presets.System.impactLight();
70
+ }
71
+ });
25
72
  }
26
73
 
27
74
  // src/theme/colorUtils.ts
@@ -151,75 +198,49 @@ var mvs = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateVerticalSca
151
198
  // src/tokens.ts
152
199
  var RADIUS = {
153
200
  md: 14};
154
- var SPRINGS = {
155
- /** Tight, premium press feel — Buttons, Toggle, Tabs triggers. */
156
- pressIn: { stiffness: 600, damping: 35, mass: 0.8 },
157
- pressOut: { stiffness: 280, damping: 22, mass: 0.8 },
158
- /** Slightly softer for larger surfaces — Card, ListItem, MenuItem. */
159
- surfacePressIn: { stiffness: 380, damping: 30, mass: 0.95 },
160
- surfacePressOut: { stiffness: 220, damping: 20, mass: 0.95 }};
161
201
  ({
162
202
  /** Material-style ease-out — natural deceleration for state changes. */
163
- standard: Animated.Easing.bezier(0.2, 0, 0, 1),
203
+ standard: reactNativeReanimated.Easing.bezier(0.2, 0, 0, 1),
164
204
  /** Strong ease-out for expanding surfaces (Accordion open). */
165
- expand: Animated.Easing.bezier(0.23, 1, 0.32, 1),
205
+ expand: reactNativeReanimated.Easing.bezier(0.23, 1, 0.32, 1),
166
206
  /** Quick ease-in for collapsing. */
167
- collapse: Animated.Easing.in(Animated.Easing.ease)
207
+ collapse: reactNativeReanimated.Easing.in(reactNativeReanimated.Easing.ease)
168
208
  });
169
209
  var PRESS_SCALE = {
170
210
  button: 0.95,
171
- card: 0.98};
172
- function useHover() {
173
- const [hovered, setHovered] = React2.useState(false);
174
- const onMouseEnter = React2.useCallback(() => setHovered(true), []);
175
- const onMouseLeave = React2.useCallback(() => setHovered(false), []);
176
- if (reactNative.Platform.OS !== "web") {
177
- return { hovered: false, hoverHandlers: {} };
178
- }
179
- return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
180
- }
181
-
182
- // src/utils/usePressScale.ts
183
- function usePressScale({
184
- pressScale = PRESS_SCALE.button,
185
- hoverScale = 1.02,
186
- pressInSpring = SPRINGS.pressIn,
187
- pressOutSpring = SPRINGS.pressOut,
188
- disabled = false
189
- } = {}) {
190
- const scale2 = Animated.useSharedValue(1);
191
- const { hovered, hoverHandlers } = useHover();
192
- const onPressIn = React2.useCallback(() => {
193
- if (disabled) return;
194
- scale2.value = Animated.withSpring(pressScale, pressInSpring);
195
- }, [disabled, pressScale, pressInSpring, scale2]);
196
- const onPressOut = React2.useCallback(() => {
197
- if (disabled) return;
198
- scale2.value = Animated.withSpring(1, pressOutSpring);
199
- }, [disabled, pressOutSpring, scale2]);
200
- const hoverActive = reactNative.Platform.OS === "web" && hovered && hoverScale !== 1 && !disabled;
201
- const animatedStyle = Animated.useAnimatedStyle(() => ({
202
- transform: [
203
- { scale: scale2.value * (hoverActive ? hoverScale : 1) }
204
- ]
205
- }));
206
- return {
207
- animatedStyle,
208
- onPressIn,
209
- onPressOut,
210
- hoverHandlers
211
- };
212
- }
211
+ card: 0.98,
212
+ row: 0.97,
213
+ chip: 0.94
214
+ };
215
+ pressto.createAnimatedPressable((progress) => {
216
+ "worklet";
217
+ const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
218
+ return { transform: [{ scale: scale2 }] };
219
+ });
220
+ var PressableCard = pressto.createAnimatedPressable((progress) => {
221
+ "worklet";
222
+ const scale2 = 1 - (1 - PRESS_SCALE.card) * progress;
223
+ return { transform: [{ scale: scale2 }] };
224
+ });
225
+ pressto.createAnimatedPressable((progress) => {
226
+ "worklet";
227
+ const scale2 = 1 - (1 - PRESS_SCALE.row) * progress;
228
+ return { transform: [{ scale: scale2 }] };
229
+ });
230
+ pressto.createAnimatedPressable((progress) => {
231
+ "worklet";
232
+ const scale2 = 1 - (1 - PRESS_SCALE.chip) * progress;
233
+ return { transform: [{ scale: scale2 }] };
234
+ });
235
+ pressto.createAnimatedPressable((progress) => {
236
+ "worklet";
237
+ const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
238
+ return { transform: [{ scale: scale2 }] };
239
+ });
213
240
 
214
241
  // src/components/Card/Card.tsx
215
242
  function Card({ children, variant = "elevated", onPress, style, accessibilityLabel }) {
216
243
  const { colors } = useTheme();
217
- const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
218
- pressScale: PRESS_SCALE.card,
219
- pressInSpring: SPRINGS.surfacePressIn,
220
- pressOutSpring: SPRINGS.surfacePressOut,
221
- disabled: !onPress
222
- });
223
244
  const handlePress = () => {
224
245
  if (!onPress) return;
225
246
  impactLight();
@@ -253,19 +274,18 @@ function Card({ children, variant = "elevated", onPress, style, accessibilityLab
253
274
  }[variant];
254
275
  const cardContent = /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: [styles.card, variantStyle, style] }, children);
255
276
  if (onPress) {
256
- return /* @__PURE__ */ React2__default.default.createElement(Animated__default.default.View, { style: animatedStyle, ...hoverHandlers }, /* @__PURE__ */ React2__default.default.createElement(
257
- reactNative.TouchableOpacity,
277
+ return /* @__PURE__ */ React2__default.default.createElement(
278
+ PressableCard,
258
279
  {
259
280
  onPress: handlePress,
260
- onPressIn,
261
- onPressOut,
262
- activeOpacity: 1,
281
+ rippleColor: "transparent",
263
282
  touchSoundDisabled: true,
283
+ activateOnHover: true,
264
284
  accessibilityRole: "button",
265
285
  accessibilityLabel
266
286
  },
267
287
  cardContent
268
- ));
288
+ );
269
289
  }
270
290
  return cardContent;
271
291
  }
package/dist/Card.mjs CHANGED
@@ -1,7 +1,8 @@
1
- export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-Y6MXOREN.mjs';
2
- import './chunk-QCNARS3X.mjs';
3
- import './chunk-RTC3CFXF.mjs';
4
- import './chunk-5IKW3VNC.mjs';
1
+ export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-ID72TK46.mjs';
2
+ import './chunk-3DKJ2GIC.mjs';
3
+ import './chunk-EJ7ZPXOH.mjs';
4
+ import './chunk-DVK4G2GT.mjs';
5
5
  import './chunk-QY3X2UYR.mjs';
6
6
  import './chunk-SOYNZDVY.mjs';
7
7
  import './chunk-2CE3TQVY.mjs';
8
+ import './chunk-Y6FXYEAI.mjs';