@retray-dev/ui-kit 10.0.0 → 10.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/COMPONENTS.md +150 -17
  2. package/CONSUMER.md +1 -1
  3. package/README.md +4 -4
  4. package/dist/Accordion.d.mts +1 -1
  5. package/dist/Accordion.d.ts +1 -1
  6. package/dist/Accordion.js +3 -3
  7. package/dist/Accordion.mjs +2 -2
  8. package/dist/AlertBanner.js +1 -1
  9. package/dist/AlertBanner.mjs +2 -2
  10. package/dist/AppHeader.js +1 -1
  11. package/dist/AppHeader.mjs +3 -3
  12. package/dist/Badge.js +1 -1
  13. package/dist/Badge.mjs +2 -2
  14. package/dist/Button.js +1 -1
  15. package/dist/Button.mjs +2 -2
  16. package/dist/CategoryStrip.js +1 -1
  17. package/dist/CategoryStrip.mjs +2 -2
  18. package/dist/Chip.js +1 -1
  19. package/dist/Chip.mjs +2 -2
  20. package/dist/ConfirmDialog.d.mts +6 -1
  21. package/dist/ConfirmDialog.d.ts +6 -1
  22. package/dist/ConfirmDialog.js +45 -15
  23. package/dist/ConfirmDialog.mjs +3 -3
  24. package/dist/CurrencyInput.js +1 -1
  25. package/dist/CurrencyInput.mjs +3 -3
  26. package/dist/DetailRow.d.mts +1 -1
  27. package/dist/DetailRow.d.ts +1 -1
  28. package/dist/DetailRow.js +1 -1
  29. package/dist/DetailRow.mjs +2 -2
  30. package/dist/EmptyState.js +1 -1
  31. package/dist/EmptyState.mjs +3 -3
  32. package/dist/ErrorBoundary.js +1 -1
  33. package/dist/ErrorBoundary.mjs +2 -2
  34. package/dist/IconButton.js +1 -1
  35. package/dist/IconButton.mjs +2 -2
  36. package/dist/IconPicker.d.mts +17 -0
  37. package/dist/IconPicker.d.ts +17 -0
  38. package/dist/IconPicker.js +997 -0
  39. package/dist/IconPicker.mjs +7 -0
  40. package/dist/ImageUpload.d.mts +3 -1
  41. package/dist/ImageUpload.d.ts +3 -1
  42. package/dist/ImageUpload.js +28 -10
  43. package/dist/ImageUpload.mjs +1 -1
  44. package/dist/ImageViewer.js +282 -141
  45. package/dist/ImageViewer.mjs +5 -3
  46. package/dist/Input.js +1 -1
  47. package/dist/Input.mjs +2 -2
  48. package/dist/LabelValue.js +1 -1
  49. package/dist/LabelValue.mjs +2 -2
  50. package/dist/ListItem.js +1 -1
  51. package/dist/ListItem.mjs +2 -2
  52. package/dist/MediaCard.js +1 -1
  53. package/dist/MediaCard.mjs +2 -2
  54. package/dist/MenuItem.js +1 -1
  55. package/dist/MenuItem.mjs +2 -2
  56. package/dist/NumberStepper.d.mts +19 -0
  57. package/dist/NumberStepper.d.ts +19 -0
  58. package/dist/NumberStepper.js +410 -0
  59. package/dist/NumberStepper.mjs +9 -0
  60. package/dist/PagerDots.js +1 -1
  61. package/dist/PagerDots.mjs +2 -2
  62. package/dist/PricingCard.js +1 -1
  63. package/dist/PricingCard.mjs +4 -4
  64. package/dist/SelectableGrid.js +1 -1
  65. package/dist/SelectableGrid.mjs +2 -2
  66. package/dist/Sheet.js +16 -13
  67. package/dist/Sheet.mjs +1 -1
  68. package/dist/SheetSelect.js +1 -1
  69. package/dist/SheetSelect.mjs +2 -2
  70. package/dist/Switch.js +40 -17
  71. package/dist/Switch.mjs +1 -1
  72. package/dist/TabBar.js +1 -1
  73. package/dist/TabBar.mjs +2 -2
  74. package/dist/Textarea.js +1 -1
  75. package/dist/Textarea.mjs +2 -2
  76. package/dist/Toggle.js +1 -1
  77. package/dist/Toggle.mjs +2 -2
  78. package/dist/chunk-53Z3NYGE.mjs +742 -0
  79. package/dist/{chunk-VQ57HWPL.mjs → chunk-6L4G6PBT.mjs} +1 -1
  80. package/dist/{chunk-6OAZJ577.mjs → chunk-6SECQ2ZF.mjs} +2 -2
  81. package/dist/{chunk-KIHCWCWL.mjs → chunk-7LWRKMF5.mjs} +1 -1
  82. package/dist/{chunk-4I7D47FH.mjs → chunk-AJRVDP2H.mjs} +3 -3
  83. package/dist/{chunk-6MKGPAR2.mjs → chunk-BEMIQXXU.mjs} +1 -1
  84. package/dist/chunk-BUMAMSTZ.mjs +126 -0
  85. package/dist/{chunk-UREA2GYY.mjs → chunk-DYT7BG5I.mjs} +1 -1
  86. package/dist/{chunk-Z4BVUWW6.mjs → chunk-ELXBDILQ.mjs} +20 -32
  87. package/dist/{chunk-A4MDAP7G.mjs → chunk-FCSSQK3L.mjs} +1 -1
  88. package/dist/{chunk-2TFTAWVJ.mjs → chunk-HTHGSXFG.mjs} +1 -1
  89. package/dist/{chunk-VGTDN7SW.mjs → chunk-IX3NYLYQ.mjs} +1 -1
  90. package/dist/{chunk-T7XZ7H7Y.mjs → chunk-KA7LTET3.mjs} +17 -3
  91. package/dist/{chunk-URI2WBIV.mjs → chunk-KOO4WITD.mjs} +1 -1
  92. package/dist/{chunk-JUXSWN54.mjs → chunk-NMU5FMQJ.mjs} +1 -1
  93. package/dist/{chunk-LXJIIOYQ.mjs → chunk-RYZC432S.mjs} +1 -1
  94. package/dist/{chunk-JB67UOB5.mjs → chunk-S2R7UVOE.mjs} +1 -1
  95. package/dist/{chunk-ZUR7AU5R.mjs → chunk-SXLKNTA4.mjs} +1 -1
  96. package/dist/{chunk-3U4SSNWP.mjs → chunk-T2KCAHOS.mjs} +1 -1
  97. package/dist/{chunk-ZJKGQMYH.mjs → chunk-TB6SD2FT.mjs} +1 -1
  98. package/dist/{chunk-AZJF2BLK.mjs → chunk-TBNZHU6C.mjs} +1 -1
  99. package/dist/{chunk-Y4GL2MHX.mjs → chunk-TZDGAP5N.mjs} +28 -10
  100. package/dist/{chunk-CZCQZHG6.mjs → chunk-U2XJFYED.mjs} +1 -1
  101. package/dist/{chunk-TERDKCLE.mjs → chunk-VF2ATYN3.mjs} +1 -1
  102. package/dist/{chunk-OHBNABL5.mjs → chunk-VKID2D2I.mjs} +1 -1
  103. package/dist/{chunk-QKH5ZOD5.mjs → chunk-WF2XDFRK.mjs} +40 -17
  104. package/dist/{chunk-FZZLPJ6B.mjs → chunk-WYEUNUTP.mjs} +44 -15
  105. package/dist/{chunk-PFZTM6D5.mjs → chunk-Y2NS74WS.mjs} +9 -7
  106. package/dist/{chunk-O3HA6TYM.mjs → chunk-YJ7I257J.mjs} +3 -3
  107. package/dist/{chunk-NA7PARID.mjs → chunk-Z4VHZ7B5.mjs} +1 -1
  108. package/dist/{chunk-MLF3EZFW.mjs → chunk-Z6SFHN6T.mjs} +1 -1
  109. package/dist/{chunk-4K625MVM.mjs → chunk-ZZ2R6KZ3.mjs} +1 -1
  110. package/dist/index.d.mts +4 -1
  111. package/dist/index.d.ts +4 -1
  112. package/dist/index.js +1011 -88
  113. package/dist/index.mjs +34 -32
  114. package/package.json +1 -1
  115. package/src/components/Accordion/Accordion.tsx +7 -3
  116. package/src/components/ConfirmDialog/ConfirmDialog.tsx +61 -23
  117. package/src/components/DetailRow/DetailRow.tsx +1 -1
  118. package/src/components/IconPicker/IconPicker.tsx +383 -0
  119. package/src/components/IconPicker/index.ts +1 -0
  120. package/src/components/ImageUpload/ImageUpload.tsx +34 -12
  121. package/src/components/ImageViewer/ImageViewer.tsx +25 -30
  122. package/src/components/NumberStepper/NumberStepper.tsx +147 -0
  123. package/src/components/NumberStepper/index.ts +1 -0
  124. package/src/components/Sheet/Sheet.tsx +10 -9
  125. package/src/components/Switch/Switch.tsx +30 -17
  126. package/src/index.ts +3 -1
  127. package/src/utils/curatedIcons.ts +286 -0
  128. package/src/utils/icons.ts +20 -2
@@ -2,7 +2,7 @@ import { usePressScale } from './chunk-YNROWHQJ.mjs';
2
2
  import { selectionAsync } from './chunk-EJ7ZPXOH.mjs';
3
3
  import { PRESS_SCALE, COLOR_TRANSITION } from './chunk-DVK4G2GT.mjs';
4
4
  import { RADIUS } from './chunk-QY3X2UYR.mjs';
5
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
5
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
6
6
  import { useTheme } from './chunk-SOYNZDVY.mjs';
7
7
  import { ms, s, vs } from './chunk-2CE3TQVY.mjs';
8
8
  import React, { useCallback } from 'react';
@@ -1,5 +1,5 @@
1
- import { Button } from './chunk-2TFTAWVJ.mjs';
2
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
1
+ import { Button } from './chunk-HTHGSXFG.mjs';
2
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
3
3
  import { useTheme } from './chunk-SOYNZDVY.mjs';
4
4
  import { s, vs, mvs, ms } from './chunk-2CE3TQVY.mjs';
5
5
  import React from 'react';
@@ -1,7 +1,7 @@
1
1
  import { PressableButton } from './chunk-3DKJ2GIC.mjs';
2
2
  import { selectionAsync } from './chunk-EJ7ZPXOH.mjs';
3
3
  import { COLOR_TRANSITION } from './chunk-DVK4G2GT.mjs';
4
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
4
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
5
5
  import { useTheme } from './chunk-SOYNZDVY.mjs';
6
6
  import { vs, s, ms } from './chunk-2CE3TQVY.mjs';
7
7
  import React from 'react';
@@ -1,7 +1,7 @@
1
- import { Badge } from './chunk-TERDKCLE.mjs';
2
- import { Button } from './chunk-2TFTAWVJ.mjs';
1
+ import { Badge } from './chunk-VF2ATYN3.mjs';
2
+ import { Button } from './chunk-HTHGSXFG.mjs';
3
3
  import { RADIUS, SHADOWS } from './chunk-QY3X2UYR.mjs';
4
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
4
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
5
5
  import { useTheme } from './chunk-SOYNZDVY.mjs';
6
6
  import { mvs, ms, vs, s } from './chunk-2CE3TQVY.mjs';
7
7
  import React from 'react';
@@ -1,5 +1,5 @@
1
1
  import { RADIUS } from './chunk-QY3X2UYR.mjs';
2
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
2
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
3
3
  import { useTheme } from './chunk-SOYNZDVY.mjs';
4
4
  import { s, vs, ms } from './chunk-2CE3TQVY.mjs';
5
5
  import React from 'react';
@@ -0,0 +1,126 @@
1
+ import { PressableButton } from './chunk-3DKJ2GIC.mjs';
2
+ import { impactLight } from './chunk-EJ7ZPXOH.mjs';
3
+ import { RADIUS } from './chunk-QY3X2UYR.mjs';
4
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
5
+ import { useTheme } from './chunk-SOYNZDVY.mjs';
6
+ import { s, mvs, ms } from './chunk-2CE3TQVY.mjs';
7
+ import React from 'react';
8
+ import { StyleSheet, View, Text } from 'react-native';
9
+
10
+ var sizeConfig = {
11
+ sm: { button: s(40), icon: 16, valueFontSize: ms(18), valueLineHeight: mvs(24), valueMinWidth: s(32) },
12
+ md: { button: s(44), icon: 18, valueFontSize: ms(22), valueLineHeight: mvs(28), valueMinWidth: s(36) },
13
+ lg: { button: s(52), icon: 22, valueFontSize: ms(26), valueLineHeight: mvs(32), valueMinWidth: s(40) }
14
+ };
15
+ function NumberStepperBase({
16
+ value,
17
+ onValueChange,
18
+ min = 1,
19
+ max = 99,
20
+ step = 1,
21
+ size = "md",
22
+ disabled = false,
23
+ style,
24
+ accessibilityLabel
25
+ }) {
26
+ const { colors } = useTheme();
27
+ const canDecrement = value > min && !disabled;
28
+ const canIncrement = value < max && !disabled;
29
+ const handleDecrement = () => {
30
+ if (!canDecrement) return;
31
+ impactLight();
32
+ onValueChange(Math.max(min, value - step));
33
+ };
34
+ const handleIncrement = () => {
35
+ if (!canIncrement) return;
36
+ impactLight();
37
+ onValueChange(Math.min(max, value + step));
38
+ };
39
+ const { button: buttonSize, icon: iconSize, valueFontSize, valueLineHeight, valueMinWidth } = sizeConfig[size];
40
+ const displayValue = String(value);
41
+ return /* @__PURE__ */ React.createElement(View, { style: [styles.container, style] }, /* @__PURE__ */ React.createElement(
42
+ PressableButton,
43
+ {
44
+ style: [
45
+ styles.button,
46
+ {
47
+ width: buttonSize,
48
+ height: buttonSize,
49
+ backgroundColor: colors.surface,
50
+ borderColor: colors.border
51
+ },
52
+ !canDecrement && styles.buttonDisabled
53
+ ],
54
+ enabled: canDecrement,
55
+ onPress: handleDecrement,
56
+ rippleColor: "transparent",
57
+ touchSoundDisabled: true,
58
+ accessibilityRole: "button",
59
+ accessibilityLabel: `Decrease, current value ${displayValue}`,
60
+ accessibilityState: { disabled: !canDecrement }
61
+ },
62
+ renderIcon("minus", iconSize, canDecrement ? colors.foreground : colors.foregroundMuted)
63
+ ), /* @__PURE__ */ React.createElement(
64
+ Text,
65
+ {
66
+ style: [
67
+ styles.value,
68
+ {
69
+ color: colors.foreground,
70
+ fontSize: valueFontSize,
71
+ lineHeight: valueLineHeight,
72
+ minWidth: valueMinWidth
73
+ }
74
+ ],
75
+ allowFontScaling: true,
76
+ accessibilityLabel: accessibilityLabel ?? `Quantity: ${displayValue}`,
77
+ accessibilityRole: "text"
78
+ },
79
+ displayValue
80
+ ), /* @__PURE__ */ React.createElement(
81
+ PressableButton,
82
+ {
83
+ style: [
84
+ styles.button,
85
+ {
86
+ width: buttonSize,
87
+ height: buttonSize,
88
+ backgroundColor: colors.surface,
89
+ borderColor: colors.border
90
+ },
91
+ !canIncrement && styles.buttonDisabled
92
+ ],
93
+ enabled: canIncrement,
94
+ onPress: handleIncrement,
95
+ rippleColor: "transparent",
96
+ touchSoundDisabled: true,
97
+ accessibilityRole: "button",
98
+ accessibilityLabel: `Increase, current value ${displayValue}`,
99
+ accessibilityState: { disabled: !canIncrement }
100
+ },
101
+ renderIcon("plus", iconSize, canIncrement ? colors.foreground : colors.foregroundMuted)
102
+ ));
103
+ }
104
+ var NumberStepper = React.memo(NumberStepperBase);
105
+ var styles = StyleSheet.create({
106
+ container: {
107
+ flexDirection: "row",
108
+ alignItems: "center",
109
+ gap: s(12)
110
+ },
111
+ button: {
112
+ borderRadius: RADIUS.md,
113
+ alignItems: "center",
114
+ justifyContent: "center",
115
+ borderWidth: 1.5
116
+ },
117
+ buttonDisabled: {
118
+ opacity: 0.35
119
+ },
120
+ value: {
121
+ fontFamily: "Sohne-Medium",
122
+ textAlign: "center"
123
+ }
124
+ });
125
+
126
+ export { NumberStepper };
@@ -1,7 +1,7 @@
1
1
  import { PressableChip } from './chunk-3DKJ2GIC.mjs';
2
2
  import { selectionAsync } from './chunk-EJ7ZPXOH.mjs';
3
3
  import { COLOR_TRANSITION } from './chunk-DVK4G2GT.mjs';
4
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
4
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
5
5
  import { useTheme } from './chunk-SOYNZDVY.mjs';
6
6
  import { s, mvs, ms, vs } from './chunk-2CE3TQVY.mjs';
7
7
  import React from 'react';
@@ -1,8 +1,8 @@
1
- import { PagerDots } from './chunk-4K625MVM.mjs';
2
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
1
+ import { PagerDots } from './chunk-ZZ2R6KZ3.mjs';
2
+ import { IconButton } from './chunk-T2KCAHOS.mjs';
3
3
  import { s, vs } from './chunk-2CE3TQVY.mjs';
4
4
  import React, { useState, useCallback } from 'react';
5
- import { StyleSheet, useWindowDimensions, Modal, ScrollView, TouchableOpacity, View } from 'react-native';
5
+ import { StyleSheet, useWindowDimensions, Dimensions, Modal, View, ScrollView, Image } from 'react-native';
6
6
  import { Gesture, GestureHandlerRootView, GestureDetector } from 'react-native-gesture-handler';
7
7
  import Animated, { useSharedValue, runOnJS, withTiming, useAnimatedStyle } from 'react-native-reanimated';
8
8
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
@@ -62,17 +62,12 @@ function ZoomableImage({ source, width, height, onZoomChange }) {
62
62
  { scale: scale.value }
63
63
  ]
64
64
  }));
65
- return /* @__PURE__ */ React.createElement(GestureDetector, { gesture: composed }, /* @__PURE__ */ React.createElement(Animated.View, { style: [{ width, height }, styles.imageWrap] }, /* @__PURE__ */ React.createElement(
66
- Animated.Image,
67
- {
68
- source,
69
- style: [{ width, height }, animatedStyle],
70
- resizeMode: "contain"
71
- }
72
- )));
65
+ return /* @__PURE__ */ React.createElement(GestureDetector, { gesture: composed }, /* @__PURE__ */ React.createElement(View, { style: [{ width, height }, styles.imageWrap], collapsable: false }, /* @__PURE__ */ React.createElement(Animated.View, { style: [{ width, height }, animatedStyle] }, /* @__PURE__ */ React.createElement(Image, { source, style: { width, height }, resizeMode: "contain" }))));
73
66
  }
74
67
  function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
75
- const { width, height } = useWindowDimensions();
68
+ const window = useWindowDimensions();
69
+ const width = window.width > 0 ? window.width : Dimensions.get("window").width;
70
+ const height = window.height > 0 ? window.height : Dimensions.get("window").height;
76
71
  const insets = useSafeAreaInsets();
77
72
  const [index, setIndex] = useState(initialIndex);
78
73
  const [pagingEnabled, setPagingEnabled] = useState(true);
@@ -115,7 +110,7 @@ function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
115
110
  scrollRef.current?.scrollTo({ x: page * width, animated: true });
116
111
  setIndex(page);
117
112
  };
118
- return /* @__PURE__ */ React.createElement(Modal, { visible, transparent: false, animationType: "fade", onRequestClose: onClose, statusBarTranslucent: true }, /* @__PURE__ */ React.createElement(GestureHandlerRootView, { style: styles.root }, /* @__PURE__ */ React.createElement(Animated.View, { style: [styles.backdrop, backdropStyle], pointerEvents: "none" }), /* @__PURE__ */ React.createElement(Animated.View, { style: [styles.container, dismissStyle] }, /* @__PURE__ */ React.createElement(GestureDetector, { gesture: swipeDown }, /* @__PURE__ */ React.createElement(Animated.View, { style: styles.root }, /* @__PURE__ */ React.createElement(
113
+ return /* @__PURE__ */ React.createElement(Modal, { visible, transparent: false, animationType: "fade", onRequestClose: onClose, statusBarTranslucent: true }, /* @__PURE__ */ React.createElement(GestureHandlerRootView, { style: styles.root }, /* @__PURE__ */ React.createElement(Animated.View, { style: [styles.backdrop, backdropStyle], pointerEvents: "none" }), /* @__PURE__ */ React.createElement(Animated.View, { style: [styles.container, dismissStyle] }, /* @__PURE__ */ React.createElement(GestureDetector, { gesture: swipeDown }, /* @__PURE__ */ React.createElement(View, { style: styles.root, collapsable: false }, /* @__PURE__ */ React.createElement(
119
114
  ScrollView,
120
115
  {
121
116
  ref: scrollRef,
@@ -136,19 +131,18 @@ function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
136
131
  onZoomChange: (zoomed) => setPagingEnabled(!zoomed)
137
132
  }
138
133
  ))
139
- ))), /* @__PURE__ */ React.createElement(
140
- TouchableOpacity,
134
+ ))), /* @__PURE__ */ React.createElement(View, { style: [styles.closeButtonWrapper, { top: insets.top + vs(8) }] }, /* @__PURE__ */ React.createElement(
135
+ IconButton,
141
136
  {
142
- style: [styles.closeButton, { top: insets.top + vs(8) }],
137
+ iconName: "x",
138
+ size: "md",
139
+ variant: "text",
140
+ style: { backgroundColor: "rgba(255,255,255,0.18)" },
141
+ iconColor: "#fff",
143
142
  onPress: onClose,
144
- activeOpacity: 0.7,
145
- touchSoundDisabled: true,
146
- accessibilityRole: "button",
147
- accessibilityLabel: "Close",
148
- hitSlop: { top: 12, bottom: 12, left: 12, right: 12 }
149
- },
150
- renderIcon("x", 26, "#fff")
151
- ), images.length > 1 ? /* @__PURE__ */ React.createElement(View, { style: [styles.dots, { bottom: insets.bottom + vs(16) }], pointerEvents: "box-none" }, /* @__PURE__ */ React.createElement(
143
+ accessibilityLabel: "Close"
144
+ }
145
+ )), images.length > 1 ? /* @__PURE__ */ React.createElement(View, { style: [styles.dots, { bottom: insets.bottom + vs(16) }], pointerEvents: "box-none" }, /* @__PURE__ */ React.createElement(
152
146
  PagerDots,
153
147
  {
154
148
  count: images.length,
@@ -175,15 +169,9 @@ var styles = StyleSheet.create({
175
169
  justifyContent: "center",
176
170
  overflow: "hidden"
177
171
  },
178
- closeButton: {
172
+ closeButtonWrapper: {
179
173
  position: "absolute",
180
- right: s(12),
181
- width: s(40),
182
- height: s(40),
183
- borderRadius: s(20),
184
- backgroundColor: "rgba(0,0,0,0.4)",
185
- alignItems: "center",
186
- justifyContent: "center"
174
+ right: s(12)
187
175
  },
188
176
  dots: {
189
177
  position: "absolute",
@@ -1,4 +1,4 @@
1
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
1
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
2
2
  import { useTheme } from './chunk-SOYNZDVY.mjs';
3
3
  import { mvs, ms, s } from './chunk-2CE3TQVY.mjs';
4
4
  import React from 'react';
@@ -1,7 +1,7 @@
1
1
  import { PressableButton } from './chunk-3DKJ2GIC.mjs';
2
2
  import { impactMedium } from './chunk-EJ7ZPXOH.mjs';
3
3
  import { TYPOGRAPHY, RADIUS } from './chunk-QY3X2UYR.mjs';
4
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
4
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
5
5
  import { useTheme } from './chunk-SOYNZDVY.mjs';
6
6
  import { vs, s, mvs, ms } from './chunk-2CE3TQVY.mjs';
7
7
  import React from 'react';
@@ -2,7 +2,7 @@ import { useHover, usePressScale } from './chunk-YNROWHQJ.mjs';
2
2
  import { impactLight } from './chunk-EJ7ZPXOH.mjs';
3
3
  import { SPRINGS, PRESS_SCALE } from './chunk-DVK4G2GT.mjs';
4
4
  import { RADIUS, SHADOWS } from './chunk-QY3X2UYR.mjs';
5
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
5
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
6
6
  import { useTheme } from './chunk-SOYNZDVY.mjs';
7
7
  import { mvs, ms, vs, s } from './chunk-2CE3TQVY.mjs';
8
8
  import React from 'react';
@@ -23,9 +23,9 @@ function configureIconFamilies(families) {
23
23
  activeFamilies = order.length > 0 ? order : ALL_FAMILIES;
24
24
  resolvedCache = null;
25
25
  }
26
- function buildCache() {
26
+ function buildCache(families) {
27
27
  const cache = /* @__PURE__ */ new Map();
28
- for (const family of activeFamilies) {
28
+ for (const family of families ?? activeFamilies) {
29
29
  const glyphMap = family.getGlyphMap();
30
30
  for (const iconName of Object.keys(glyphMap)) {
31
31
  cache.set(iconName, family);
@@ -39,6 +39,20 @@ function resolveFamily(name) {
39
39
  }
40
40
  return resolvedCache.get(name) ?? null;
41
41
  }
42
+ var cachedIconNames = null;
43
+ function getValidIconNames(families) {
44
+ if (families && families.length > 0) {
45
+ const tempFamilies = families.map((n) => ALL_FAMILIES.find((f) => f.name === n)).filter((f) => f !== void 0);
46
+ if (tempFamilies.length === 0) return [];
47
+ const cache = buildCache(tempFamilies);
48
+ return Array.from(cache.keys());
49
+ }
50
+ if (!cachedIconNames) {
51
+ const cache = buildCache();
52
+ cachedIconNames = Array.from(cache.keys());
53
+ }
54
+ return cachedIconNames;
55
+ }
42
56
  function Icon({ name, size, color, family }) {
43
57
  let resolved = null;
44
58
  if (family) {
@@ -54,4 +68,4 @@ function renderIcon(name, size, color) {
54
68
  return React.createElement(Icon, { name, size, color });
55
69
  }
56
70
 
57
- export { Icon, configureIconFamilies, renderIcon };
71
+ export { Icon, configureIconFamilies, getValidIconNames, renderIcon };
@@ -2,7 +2,7 @@ import { PressableChip } from './chunk-3DKJ2GIC.mjs';
2
2
  import { selectionAsync } from './chunk-EJ7ZPXOH.mjs';
3
3
  import { COLOR_TRANSITION } from './chunk-DVK4G2GT.mjs';
4
4
  import { RADIUS } from './chunk-QY3X2UYR.mjs';
5
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
5
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
6
6
  import { useTheme } from './chunk-SOYNZDVY.mjs';
7
7
  import { ms, mvs, s, vs } from './chunk-2CE3TQVY.mjs';
8
8
  import React from 'react';
@@ -1,4 +1,4 @@
1
- import { Input } from './chunk-ZUR7AU5R.mjs';
1
+ import { Input } from './chunk-SXLKNTA4.mjs';
2
2
  import { ms, vs } from './chunk-2CE3TQVY.mjs';
3
3
  import React from 'react';
4
4
 
@@ -1,6 +1,6 @@
1
1
  import { impactLight } from './chunk-EJ7ZPXOH.mjs';
2
2
  import { RADIUS } from './chunk-QY3X2UYR.mjs';
3
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
3
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
4
4
  import { useTheme } from './chunk-SOYNZDVY.mjs';
5
5
  import { ms, vs, s, mvs } from './chunk-2CE3TQVY.mjs';
6
6
  import React from 'react';
@@ -1,4 +1,4 @@
1
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
1
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
2
2
  import { useTheme } from './chunk-SOYNZDVY.mjs';
3
3
  import { mvs, ms, s } from './chunk-2CE3TQVY.mjs';
4
4
  import React from 'react';
@@ -1,5 +1,5 @@
1
1
  import { COLOR_TRANSITION } from './chunk-DVK4G2GT.mjs';
2
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
2
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
3
3
  import { useTheme } from './chunk-SOYNZDVY.mjs';
4
4
  import { ms, s, vs } from './chunk-2CE3TQVY.mjs';
5
5
  import React, { useState } from 'react';
@@ -1,6 +1,6 @@
1
1
  import { PressableButton } from './chunk-3DKJ2GIC.mjs';
2
2
  import { impactLight } from './chunk-EJ7ZPXOH.mjs';
3
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
3
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
4
4
  import { useTheme } from './chunk-SOYNZDVY.mjs';
5
5
  import { s, ms } from './chunk-2CE3TQVY.mjs';
6
6
  import React from 'react';
@@ -1,7 +1,7 @@
1
1
  import { PressableRow } from './chunk-3DKJ2GIC.mjs';
2
2
  import { selectionAsync } from './chunk-EJ7ZPXOH.mjs';
3
3
  import { RADIUS } from './chunk-QY3X2UYR.mjs';
4
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
4
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
5
5
  import { useTheme } from './chunk-SOYNZDVY.mjs';
6
6
  import { vs, ms, s } from './chunk-2CE3TQVY.mjs';
7
7
  import React from 'react';
@@ -1,4 +1,4 @@
1
- import { IconButton } from './chunk-3U4SSNWP.mjs';
1
+ import { IconButton } from './chunk-T2KCAHOS.mjs';
2
2
  import { BREAKPOINTS } from './chunk-QY3X2UYR.mjs';
3
3
  import { useTheme } from './chunk-SOYNZDVY.mjs';
4
4
  import { mvs, ms, vs, s } from './chunk-2CE3TQVY.mjs';
@@ -13,6 +13,7 @@ function ImageUpload({
13
13
  onChange,
14
14
  loading = false,
15
15
  placeholder = "Tap to add image",
16
+ showPlaceholderText = true,
16
17
  width,
17
18
  height = 200,
18
19
  borderRadius = RADIUS.lg,
@@ -25,23 +26,31 @@ function ImageUpload({
25
26
  const handlePress = async () => {
26
27
  if (disabled || loading) return;
27
28
  impactLight();
28
- let ImagePicker;
29
+ let picker;
29
30
  try {
30
- ImagePicker = await import('expo-image-picker');
31
+ const mod = await import('expo-image-picker/build/ExponentImagePicker');
32
+ picker = mod.default;
31
33
  } catch {
32
- if (__DEV__) console.warn("[ImageUpload] expo-image-picker not installed. Add it as a dependency.");
33
- return;
34
+ try {
35
+ picker = await import('expo-image-picker');
36
+ } catch {
37
+ if (__DEV__) console.warn("[ImageUpload] expo-image-picker not installed.");
38
+ return;
39
+ }
34
40
  }
35
41
  if (Platform.OS !== "web") {
36
- const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
37
- if (status !== "granted") return;
42
+ try {
43
+ const { status } = await picker.requestMediaLibraryPermissionsAsync();
44
+ if (status !== "granted") return;
45
+ } catch {
46
+ }
38
47
  }
39
- const result = await ImagePicker.launchImageLibraryAsync({
48
+ const result = await picker.launchImageLibraryAsync({
40
49
  mediaTypes: ["images"],
41
50
  allowsEditing: true,
42
51
  quality: 0.8
43
52
  });
44
- if (!result.canceled && result.assets[0]) {
53
+ if (!result.canceled && result.assets?.[0]) {
45
54
  onChange?.(result.assets[0].uri);
46
55
  }
47
56
  };
@@ -74,7 +83,15 @@ function ImageUpload({
74
83
  style: [StyleSheet.absoluteFillObject, { borderRadius }],
75
84
  resizeMode
76
85
  }
77
- ) : /* @__PURE__ */ React.createElement(View, { style: styles.placeholder }, /* @__PURE__ */ React.createElement(Feather, { name: "image", size: ms(28), color: colors.foregroundMuted }), /* @__PURE__ */ React.createElement(Text, { style: [styles.placeholderText, { color: colors.foregroundMuted }], allowFontScaling: true }, placeholder)),
86
+ ) : /* @__PURE__ */ React.createElement(View, { style: styles.placeholder }, /* @__PURE__ */ React.createElement(Feather, { name: "image", size: ms(28), color: colors.foregroundMuted }), showPlaceholderText ? /* @__PURE__ */ React.createElement(
87
+ Text,
88
+ {
89
+ style: [styles.placeholderText, { color: colors.foregroundMuted }],
90
+ numberOfLines: 1,
91
+ allowFontScaling: true
92
+ },
93
+ placeholder
94
+ ) : null),
78
95
  loading ? /* @__PURE__ */ React.createElement(View, { style: [styles.loadingOverlay, { backgroundColor: colors.overlay }] }, /* @__PURE__ */ React.createElement(Spinner, { size: "md" })) : null,
79
96
  value && !loading ? /* @__PURE__ */ React.createElement(View, { style: styles.editBadge, pointerEvents: "none" }, /* @__PURE__ */ React.createElement(View, { style: [styles.editBadgeInner, { backgroundColor: colors.overlay }] }, /* @__PURE__ */ React.createElement(Feather, { name: "edit-2", size: ms(12), color: "#fff" }))) : null
80
97
  );
@@ -88,7 +105,8 @@ var styles = StyleSheet.create({
88
105
  },
89
106
  placeholderText: {
90
107
  fontFamily: "Sohne-Regular",
91
- fontSize: ms(13)
108
+ fontSize: ms(13),
109
+ textAlign: "center"
92
110
  },
93
111
  loadingOverlay: {
94
112
  ...StyleSheet.absoluteFillObject,
@@ -1,5 +1,5 @@
1
1
  import { TIMINGS, EASINGS } from './chunk-DVK4G2GT.mjs';
2
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
2
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
3
3
  import { useTheme } from './chunk-SOYNZDVY.mjs';
4
4
  import { vs, ms, s } from './chunk-2CE3TQVY.mjs';
5
5
  import React, { useState, useEffect } from 'react';
@@ -1,4 +1,4 @@
1
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
1
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
2
2
  import { useTheme } from './chunk-SOYNZDVY.mjs';
3
3
  import { vs, s, ms } from './chunk-2CE3TQVY.mjs';
4
4
  import React from 'react';
@@ -1,7 +1,7 @@
1
1
  import { PressableRow } from './chunk-3DKJ2GIC.mjs';
2
2
  import { selectionAsync } from './chunk-EJ7ZPXOH.mjs';
3
3
  import { RADIUS } from './chunk-QY3X2UYR.mjs';
4
- import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
4
+ import { renderIcon } from './chunk-KA7LTET3.mjs';
5
5
  import { useTheme } from './chunk-SOYNZDVY.mjs';
6
6
  import { ms, s, mvs, vs } from './chunk-2CE3TQVY.mjs';
7
7
  import React from 'react';
@@ -13,9 +13,11 @@ var THUMB_SIZE = s(24);
13
13
  var THUMB_OFFSET = s(3);
14
14
  var THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2;
15
15
  var ICON_SIZE = s(13);
16
+ var DISABLED_OPACITY = 0.45;
16
17
  function Switch({ checked = false, onCheckedChange, disabled, style, accessibilityLabel }) {
17
18
  const { colors } = useTheme();
18
- return /* @__PURE__ */ React.createElement(View, { style: [{ opacity: disabled ? 0.45 : 1, alignSelf: "flex-start" }, style] }, /* @__PURE__ */ React.createElement(
19
+ const isDisabled = !!disabled;
20
+ return /* @__PURE__ */ React.createElement(View, { style: [{ alignSelf: "flex-start" }, style] }, /* @__PURE__ */ React.createElement(
19
21
  TouchableOpacity,
20
22
  {
21
23
  onPress: () => {
@@ -27,47 +29,68 @@ function Switch({ checked = false, onCheckedChange, disabled, style, accessibili
27
29
  touchSoundDisabled: true,
28
30
  accessibilityRole: "switch",
29
31
  accessibilityLabel,
30
- accessibilityState: { checked, disabled: !!disabled },
32
+ accessibilityState: { checked, disabled: isDisabled },
31
33
  style: styles.touchable
32
34
  },
33
- /* @__PURE__ */ React.createElement(
35
+ /* @__PURE__ */ React.createElement(View, { style: styles.trackContainer }, /* @__PURE__ */ React.createElement(
34
36
  EaseView,
35
37
  {
36
- style: styles.track,
38
+ style: [styles.track, isDisabled && styles.disabledTrack],
37
39
  animate: { backgroundColor: checked ? colors.primary : colors.surfaceStrong },
38
40
  transition: COLOR_TRANSITION
41
+ }
42
+ ), /* @__PURE__ */ React.createElement(
43
+ EaseView,
44
+ {
45
+ style: [styles.trackBorder, { borderWidth: 1.5 }],
46
+ pointerEvents: "none",
47
+ animate: { borderColor: checked ? "transparent" : colors.border },
48
+ transition: COLOR_TRANSITION
49
+ }
50
+ ), /* @__PURE__ */ React.createElement(
51
+ EaseView,
52
+ {
53
+ style: [styles.thumb, { backgroundColor: colors.primaryForeground }],
54
+ animate: { translateX: checked ? THUMB_TRAVEL : 0 },
55
+ transition: SPRING_ELASTIC
39
56
  },
40
57
  /* @__PURE__ */ React.createElement(
41
58
  EaseView,
42
59
  {
43
- style: [styles.trackBorder, { borderWidth: 1.5 }],
44
- pointerEvents: "none",
45
- animate: { borderColor: checked ? "transparent" : colors.border },
46
- transition: COLOR_TRANSITION
47
- }
60
+ style: styles.iconWrapper,
61
+ animate: { opacity: checked ? isDisabled ? DISABLED_OPACITY : 1 : 0 },
62
+ transition: OPACITY_TRANSITION
63
+ },
64
+ /* @__PURE__ */ React.createElement(Feather, { name: "check", size: ICON_SIZE, color: colors.primary })
48
65
  ),
49
66
  /* @__PURE__ */ React.createElement(
50
67
  EaseView,
51
68
  {
52
- style: [styles.thumb, { backgroundColor: colors.primaryForeground }],
53
- animate: { translateX: checked ? THUMB_TRAVEL : 0 },
54
- transition: SPRING_ELASTIC
69
+ style: styles.iconWrapper,
70
+ animate: { opacity: checked ? 0 : isDisabled ? DISABLED_OPACITY : 1 },
71
+ transition: OPACITY_TRANSITION
55
72
  },
56
- /* @__PURE__ */ React.createElement(EaseView, { style: styles.iconWrapper, animate: { opacity: checked ? 1 : 0 }, transition: OPACITY_TRANSITION }, /* @__PURE__ */ React.createElement(Feather, { name: "check", size: ICON_SIZE, color: colors.primary })),
57
- /* @__PURE__ */ React.createElement(EaseView, { style: styles.iconWrapper, animate: { opacity: checked ? 0 : 1 }, transition: OPACITY_TRANSITION }, /* @__PURE__ */ React.createElement(Feather, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted }))
73
+ /* @__PURE__ */ React.createElement(Feather, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted })
58
74
  )
59
- )
75
+ ))
60
76
  ));
61
77
  }
62
78
  var styles = StyleSheet.create({
63
79
  touchable: {
64
80
  alignSelf: "flex-start"
65
81
  },
66
- track: {
82
+ trackContainer: {
83
+ position: "relative",
67
84
  width: TRACK_WIDTH,
68
- height: TRACK_HEIGHT,
85
+ height: TRACK_HEIGHT
86
+ },
87
+ track: {
88
+ ...StyleSheet.absoluteFillObject,
69
89
  borderRadius: TRACK_HEIGHT / 2
70
90
  },
91
+ disabledTrack: {
92
+ opacity: DISABLED_OPACITY
93
+ },
71
94
  trackBorder: {
72
95
  ...StyleSheet.absoluteFillObject,
73
96
  borderRadius: TRACK_HEIGHT / 2