@retray-dev/ui-kit 12.2.0 → 13.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 (296) hide show
  1. package/CONSUMER.md +26 -11
  2. package/DESIGN.md +2 -2
  3. package/README.md +15 -11
  4. package/{COMPONENTS.md → SKILL.md} +374 -996
  5. package/dist/Accordion.d.mts +2 -0
  6. package/dist/Accordion.d.ts +2 -0
  7. package/dist/Accordion.js +49 -210
  8. package/dist/Accordion.mjs +6 -6
  9. package/dist/AlertBanner.js +29 -153
  10. package/dist/AlertBanner.mjs +3 -4
  11. package/dist/AppHeader.d.mts +5 -2
  12. package/dist/AppHeader.d.ts +5 -2
  13. package/dist/AppHeader.js +45 -239
  14. package/dist/AppHeader.mjs +6 -8
  15. package/dist/Avatar.d.mts +17 -1
  16. package/dist/Avatar.d.ts +17 -1
  17. package/dist/Avatar.js +80 -115
  18. package/dist/Avatar.mjs +2 -3
  19. package/dist/Badge.js +24 -149
  20. package/dist/Badge.mjs +3 -4
  21. package/dist/Button.js +79 -267
  22. package/dist/Button.mjs +6 -7
  23. package/dist/ButtonGroup.mjs +0 -1
  24. package/dist/Card.js +15 -200
  25. package/dist/Card.mjs +4 -6
  26. package/dist/CategoryStrip.d.mts +0 -5
  27. package/dist/CategoryStrip.d.ts +0 -5
  28. package/dist/CategoryStrip.js +47 -265
  29. package/dist/CategoryStrip.mjs +6 -7
  30. package/dist/Checkbox.d.mts +2 -1
  31. package/dist/Checkbox.d.ts +2 -1
  32. package/dist/Checkbox.js +18 -201
  33. package/dist/Checkbox.mjs +5 -6
  34. package/dist/Chip.js +44 -236
  35. package/dist/Chip.mjs +7 -7
  36. package/dist/ConfirmDialog.d.mts +2 -1
  37. package/dist/ConfirmDialog.d.ts +2 -1
  38. package/dist/ConfirmDialog.js +110 -300
  39. package/dist/ConfirmDialog.mjs +7 -8
  40. package/dist/CurrencyDisplay.js +1 -114
  41. package/dist/CurrencyDisplay.mjs +2 -3
  42. package/dist/CurrencyInput.js +35 -162
  43. package/dist/CurrencyInput.mjs +5 -6
  44. package/dist/DetailRow.js +25 -150
  45. package/dist/DetailRow.mjs +3 -4
  46. package/dist/EmptyState.js +80 -268
  47. package/dist/EmptyState.mjs +7 -8
  48. package/dist/ErrorBoundary.js +32 -199
  49. package/dist/ErrorBoundary.mjs +4 -5
  50. package/dist/Form.js +1 -114
  51. package/dist/Form.mjs +2 -3
  52. package/dist/HolographicCard.d.mts +0 -28
  53. package/dist/HolographicCard.d.ts +0 -28
  54. package/dist/HolographicCard.js +20 -130
  55. package/dist/HolographicCard.mjs +9 -33
  56. package/dist/IconButton.js +36 -234
  57. package/dist/IconButton.mjs +5 -7
  58. package/dist/IconPicker.js +222 -929
  59. package/dist/IconPicker.mjs +5 -6
  60. package/dist/ImageUpload.d.mts +3 -3
  61. package/dist/ImageUpload.d.ts +3 -3
  62. package/dist/ImageUpload.js +49 -238
  63. package/dist/ImageUpload.mjs +5 -7
  64. package/dist/ImageViewer.js +75 -266
  65. package/dist/ImageViewer.mjs +8 -9
  66. package/dist/Input.d.mts +1 -1
  67. package/dist/Input.d.ts +1 -1
  68. package/dist/Input.js +35 -162
  69. package/dist/Input.mjs +4 -5
  70. package/dist/LabelValue.js +24 -149
  71. package/dist/LabelValue.mjs +3 -4
  72. package/dist/ListGroup.js +1 -114
  73. package/dist/ListGroup.mjs +2 -3
  74. package/dist/ListItem.d.mts +2 -1
  75. package/dist/ListItem.d.ts +2 -1
  76. package/dist/ListItem.js +41 -236
  77. package/dist/ListItem.mjs +5 -7
  78. package/dist/MediaCard.d.mts +0 -14
  79. package/dist/MediaCard.d.ts +0 -14
  80. package/dist/MediaCard.js +69 -315
  81. package/dist/MediaCard.mjs +5 -7
  82. package/dist/MenuGroup.js +1 -114
  83. package/dist/MenuGroup.mjs +2 -3
  84. package/dist/MenuItem.d.mts +2 -1
  85. package/dist/MenuItem.d.ts +2 -1
  86. package/dist/MenuItem.js +39 -235
  87. package/dist/MenuItem.mjs +5 -7
  88. package/dist/MonthPicker.js +8 -163
  89. package/dist/MonthPicker.mjs +3 -4
  90. package/dist/NumberStepper.d.mts +2 -1
  91. package/dist/NumberStepper.d.ts +2 -1
  92. package/dist/NumberStepper.js +44 -239
  93. package/dist/NumberStepper.mjs +5 -7
  94. package/dist/PagerDots.d.mts +1 -1
  95. package/dist/PagerDots.d.ts +1 -1
  96. package/dist/PagerDots.js +69 -224
  97. package/dist/PagerDots.mjs +6 -6
  98. package/dist/Pressable.js +14 -85
  99. package/dist/Pressable.mjs +4 -5
  100. package/dist/PricingCard.js +87 -272
  101. package/dist/PricingCard.mjs +8 -9
  102. package/dist/Progress.js +3 -123
  103. package/dist/Progress.mjs +3 -4
  104. package/dist/RadioGroup.js +52 -265
  105. package/dist/RadioGroup.mjs +5 -6
  106. package/dist/RetrayProvider.js +3 -6
  107. package/dist/RetrayProvider.mjs +3 -4
  108. package/dist/Select.d.mts +3 -1
  109. package/dist/Select.d.ts +3 -1
  110. package/dist/Select.js +27 -233
  111. package/dist/Select.mjs +4 -6
  112. package/dist/SelectableCard.js +33 -209
  113. package/dist/SelectableCard.mjs +5 -6
  114. package/dist/SelectableGrid.d.mts +0 -21
  115. package/dist/SelectableGrid.d.ts +0 -21
  116. package/dist/SelectableGrid.js +49 -272
  117. package/dist/SelectableGrid.mjs +5 -7
  118. package/dist/Separator.js +1 -114
  119. package/dist/Separator.mjs +2 -3
  120. package/dist/Sheet.d.mts +1 -1
  121. package/dist/Sheet.d.ts +1 -1
  122. package/dist/Sheet.js +33 -175
  123. package/dist/Sheet.mjs +3 -4
  124. package/dist/SheetSelect.js +39 -236
  125. package/dist/SheetSelect.mjs +6 -7
  126. package/dist/Skeleton.js +4 -124
  127. package/dist/Skeleton.mjs +3 -4
  128. package/dist/Slider.d.mts +2 -1
  129. package/dist/Slider.d.ts +2 -1
  130. package/dist/Slider.js +8 -161
  131. package/dist/Slider.mjs +3 -4
  132. package/dist/Spinner.js +3 -116
  133. package/dist/Spinner.mjs +2 -3
  134. package/dist/Stats.js +36 -234
  135. package/dist/Stats.mjs +5 -7
  136. package/dist/Switch.d.mts +2 -1
  137. package/dist/Switch.d.ts +2 -1
  138. package/dist/Switch.js +26 -176
  139. package/dist/Switch.mjs +5 -5
  140. package/dist/TabBar.js +43 -200
  141. package/dist/TabBar.mjs +5 -5
  142. package/dist/Tabs.js +15 -199
  143. package/dist/Tabs.mjs +5 -6
  144. package/dist/Text.js +9 -130
  145. package/dist/Text.mjs +2 -3
  146. package/dist/Textarea.d.mts +2 -1
  147. package/dist/Textarea.d.ts +2 -1
  148. package/dist/Textarea.js +71 -219
  149. package/dist/Textarea.mjs +4 -5
  150. package/dist/Toast.d.mts +12 -10
  151. package/dist/Toast.d.ts +12 -10
  152. package/dist/Toast.js +1 -114
  153. package/dist/Toast.mjs +2 -3
  154. package/dist/Toggle.js +39 -236
  155. package/dist/Toggle.mjs +6 -7
  156. package/dist/{chunk-ELGEOM7I.mjs → chunk-2QXJDRVU.mjs} +13 -10
  157. package/dist/{chunk-LIS6I5UP.mjs → chunk-2VIDP72N.mjs} +3 -3
  158. package/dist/{chunk-NHDI3VQB.mjs → chunk-422IVD3H.mjs} +16 -12
  159. package/dist/{chunk-DF7JA72E.mjs → chunk-4NQFTHN3.mjs} +13 -7
  160. package/dist/{chunk-3XCFYSX4.mjs → chunk-5MYNAAFE.mjs} +13 -17
  161. package/dist/{chunk-E7NEHHXV.mjs → chunk-62BBSSUF.mjs} +3 -3
  162. package/dist/{chunk-UBUXUMER.mjs → chunk-77UOVFIS.mjs} +7 -5
  163. package/dist/{chunk-M3C7XM2M.mjs → chunk-7BZJRB77.mjs} +28 -18
  164. package/dist/chunk-ARONDO7M.mjs +40 -0
  165. package/dist/{chunk-GH67YXG6.mjs → chunk-AZV7KNJI.mjs} +3 -3
  166. package/dist/{chunk-2P2CB235.mjs → chunk-BULKGOIZ.mjs} +7 -8
  167. package/dist/{chunk-RJNLAH76.mjs → chunk-C5ZRMR2E.mjs} +4 -2
  168. package/dist/chunk-CM2DG4MR.mjs +142 -0
  169. package/dist/{chunk-UQ4742ET.mjs → chunk-COA2YZOX.mjs} +8 -6
  170. package/dist/{chunk-EDLCGYIO.mjs → chunk-CZN6L2QU.mjs} +11 -8
  171. package/dist/{chunk-TS7DGUIR.mjs → chunk-DBHSUUKU.mjs} +2 -2
  172. package/dist/{chunk-57V2LXCK.mjs → chunk-DE25XTVQ.mjs} +3 -3
  173. package/dist/{chunk-RMRS44MQ.mjs → chunk-E2PONRJG.mjs} +13 -9
  174. package/dist/{chunk-GUTDFUNF.mjs → chunk-EHGBHFMH.mjs} +9 -17
  175. package/dist/{chunk-ZIMY2QUM.mjs → chunk-ERWJPVX7.mjs} +2 -2
  176. package/dist/{chunk-NLZY4TXU.mjs → chunk-ESQDPO5E.mjs} +7 -7
  177. package/dist/{chunk-VJBUCITV.mjs → chunk-EW2FIDSM.mjs} +1 -1
  178. package/dist/{chunk-HC4VVCWY.mjs → chunk-FTTI6T5Q.mjs} +4 -4
  179. package/dist/{chunk-MVMGPZN6.mjs → chunk-H6MQL7PS.mjs} +12 -7
  180. package/dist/{chunk-CF27NBXO.mjs → chunk-HHOOFDBA.mjs} +38 -41
  181. package/dist/{chunk-2HFD4IHU.mjs → chunk-HUSSF6TF.mjs} +1 -1
  182. package/dist/{chunk-HEDQPK4I.mjs → chunk-IDVUZIVY.mjs} +16 -22
  183. package/dist/chunk-IFYMBOEN.mjs +14 -0
  184. package/dist/{chunk-QOLWA2PW.mjs → chunk-IGU223UM.mjs} +80 -4
  185. package/dist/chunk-IJCMPVW5.mjs +121 -0
  186. package/dist/{chunk-AENAVIKT.mjs → chunk-ITG4JQM3.mjs} +4 -4
  187. package/dist/{chunk-E5UKLSJZ.mjs → chunk-K3QX2M26.mjs} +11 -8
  188. package/dist/{chunk-4OORJ2DY.mjs → chunk-K7TKID3V.mjs} +8 -7
  189. package/dist/{chunk-2LG326TT.mjs → chunk-KAGADD2O.mjs} +4 -4
  190. package/dist/{chunk-IVSRW4HS.mjs → chunk-KC5QDYGZ.mjs} +4 -4
  191. package/dist/{chunk-7AFZWSCI.mjs → chunk-KPTY7UYQ.mjs} +1 -1
  192. package/dist/{chunk-YTXRIXNZ.mjs → chunk-KSSVIFYR.mjs} +9 -12
  193. package/dist/chunk-L3YKPTJQ.mjs +119 -0
  194. package/dist/chunk-M53LC4Q7.mjs +35 -0
  195. package/dist/chunk-MZ6WRTD2.mjs +40 -0
  196. package/dist/chunk-NGEN2EES.mjs +581 -0
  197. package/dist/{chunk-ZR6HSEAB.mjs → chunk-NPCBNGNE.mjs} +17 -26
  198. package/dist/{chunk-C43HRKXH.mjs → chunk-OBV72JD4.mjs} +1 -1
  199. package/dist/{chunk-LPV4NJJK.mjs → chunk-PGQ6FMXS.mjs} +6 -5
  200. package/dist/{chunk-MEPSKGBO.mjs → chunk-PI6RULJX.mjs} +1 -1
  201. package/dist/{chunk-F3YTWO3T.mjs → chunk-RA6SAAFE.mjs} +9 -8
  202. package/dist/{chunk-UNNRUJTM.mjs → chunk-RRKM4MKB.mjs} +7 -7
  203. package/dist/{chunk-ULGNQPNE.mjs → chunk-S2VGME7X.mjs} +1 -1
  204. package/dist/{chunk-OLVJFKXS.mjs → chunk-S44XWTTC.mjs} +35 -25
  205. package/dist/{chunk-YMYIEVZP.mjs → chunk-SZEKQAOY.mjs} +1 -1
  206. package/dist/{chunk-BXF4AMHY.mjs → chunk-TMH263OK.mjs} +5 -4
  207. package/dist/{chunk-NJG7DHVF.mjs → chunk-U6DEBYU5.mjs} +10 -9
  208. package/dist/{chunk-QXDGGOLC.mjs → chunk-UMZTPUB3.mjs} +33 -21
  209. package/dist/{chunk-KSUWPU2F.mjs → chunk-WIPEDNSD.mjs} +7 -7
  210. package/dist/{chunk-QDAZGZUF.mjs → chunk-XCIG6HT2.mjs} +3 -3
  211. package/dist/{chunk-4J2PXL36.mjs → chunk-Y6YS33GM.mjs} +40 -38
  212. package/dist/{chunk-4XOB5TTD.mjs → chunk-ZKDKKQCE.mjs} +5 -5
  213. package/dist/{chunk-LOBLCFMN.mjs → chunk-ZTPYUU5C.mjs} +5 -5
  214. package/dist/fonts.mjs +0 -2
  215. package/dist/index.d.mts +13 -73
  216. package/dist/index.d.ts +13 -73
  217. package/dist/index.js +1149 -1892
  218. package/dist/index.mjs +81 -86
  219. package/package.json +20 -20
  220. package/src/components/Accordion/Accordion.tsx +15 -9
  221. package/src/components/AlertBanner/AlertBanner.tsx +7 -6
  222. package/src/components/AppHeader/AppHeader.tsx +25 -10
  223. package/src/components/Avatar/Avatar.tsx +92 -1
  224. package/src/components/Avatar/index.ts +2 -2
  225. package/src/components/Badge/Badge.tsx +2 -2
  226. package/src/components/Button/Button.tsx +50 -46
  227. package/src/components/Card/Card.tsx +1 -0
  228. package/src/components/CategoryStrip/CategoryStrip.tsx +36 -49
  229. package/src/components/Checkbox/Checkbox.tsx +3 -0
  230. package/src/components/Chip/Chip.tsx +5 -4
  231. package/src/components/ConfirmDialog/ConfirmDialog.tsx +33 -17
  232. package/src/components/DetailRow/DetailRow.tsx +3 -3
  233. package/src/components/EmptyState/EmptyState.tsx +2 -2
  234. package/src/components/ErrorBoundary/ErrorBoundary.tsx +6 -6
  235. package/src/components/HolographicCard/HolographicCard.tsx +14 -95
  236. package/src/components/IconButton/IconButton.tsx +2 -2
  237. package/src/components/IconPicker/IconPicker.tsx +13 -12
  238. package/src/components/ImageUpload/ImageUpload.tsx +43 -46
  239. package/src/components/ImageViewer/ImageViewer.tsx +3 -3
  240. package/src/components/Input/Input.tsx +11 -5
  241. package/src/components/LabelValue/LabelValue.tsx +2 -2
  242. package/src/components/ListItem/ListItem.tsx +7 -4
  243. package/src/components/MediaCard/MediaCard.tsx +21 -59
  244. package/src/components/MenuItem/MenuItem.tsx +5 -2
  245. package/src/components/MonthPicker/MonthPicker.tsx +2 -2
  246. package/src/components/NumberStepper/NumberStepper.tsx +10 -6
  247. package/src/components/PagerDots/PagerDots.tsx +38 -28
  248. package/src/components/PricingCard/PricingCard.tsx +6 -6
  249. package/src/components/RadioGroup/RadioGroup.tsx +18 -31
  250. package/src/components/Select/Select.tsx +35 -39
  251. package/src/components/SelectableCard/SelectableCard.tsx +4 -6
  252. package/src/components/SelectableGrid/SelectableGrid.tsx +37 -72
  253. package/src/components/Sheet/Sheet.tsx +28 -15
  254. package/src/components/Sheet/index.ts +2 -2
  255. package/src/components/SheetSelect/SheetSelect.tsx +3 -3
  256. package/src/components/Skeleton/Skeleton.tsx +1 -1
  257. package/src/components/Slider/Slider.tsx +3 -0
  258. package/src/components/Spinner/Spinner.tsx +2 -2
  259. package/src/components/Stats/Stats.tsx +2 -2
  260. package/src/components/Switch/Switch.tsx +12 -7
  261. package/src/components/TabBar/TabBar.tsx +9 -8
  262. package/src/components/Text/Text.tsx +13 -1
  263. package/src/components/Textarea/Textarea.tsx +18 -32
  264. package/src/components/Toggle/Toggle.tsx +3 -3
  265. package/src/hooks/useConfirmDialog.ts +31 -42
  266. package/src/index.ts +3 -4
  267. package/src/theme/ThemeProvider.tsx +1 -4
  268. package/src/theme/colorUtils.ts +1 -72
  269. package/src/theme/colors.ts +40 -1
  270. package/src/theme/types.ts +2 -2
  271. package/src/utils/animations.ts +0 -47
  272. package/src/utils/curatedIcons.ts +93 -801
  273. package/src/utils/haptics.ts +13 -208
  274. package/src/utils/icons.ts +27 -91
  275. package/src/utils/pressable.ts +10 -61
  276. package/dist/VirtualList.d.mts +0 -19
  277. package/dist/VirtualList.d.ts +0 -19
  278. package/dist/VirtualList.js +0 -38
  279. package/dist/VirtualList.mjs +0 -2
  280. package/dist/chunk-2BA3JMKK.mjs +0 -136
  281. package/dist/chunk-3DKJ2GIC.mjs +0 -30
  282. package/dist/chunk-7ELGZ66G.mjs +0 -164
  283. package/dist/chunk-DVK4G2GT.mjs +0 -59
  284. package/dist/chunk-EJ7ZPXOH.mjs +0 -163
  285. package/dist/chunk-KA7LTET3.mjs +0 -71
  286. package/dist/chunk-LNPKGWBG.mjs +0 -134
  287. package/dist/chunk-NC5ZTR2Y.mjs +0 -32
  288. package/dist/chunk-SAWUXP3A.mjs +0 -1114
  289. package/dist/chunk-Y6FXYEAI.mjs +0 -8
  290. package/dist/chunk-YNROWHQJ.mjs +0 -46
  291. package/src/components/VirtualList/VirtualList.tsx +0 -60
  292. package/src/components/VirtualList/index.ts +0 -1
  293. package/src/utils/fontGuard.ts +0 -35
  294. package/src/utils/hover.ts +0 -25
  295. package/src/utils/useColorTransition.ts +0 -40
  296. package/src/utils/usePressScale.ts +0 -75
package/dist/AppHeader.js CHANGED
@@ -11,7 +11,6 @@ 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
13
  var pressto = require('pressto');
14
- var reactNativeReanimated = require('react-native-reanimated');
15
14
 
16
15
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
17
16
 
@@ -23,126 +22,8 @@ var FontAwesome5__default = /*#__PURE__*/_interopDefault(FontAwesome5);
23
22
  var MaterialIcons__default = /*#__PURE__*/_interopDefault(MaterialIcons);
24
23
  var Ionicons__default = /*#__PURE__*/_interopDefault(Ionicons);
25
24
 
26
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
27
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
28
- }) : x)(function(x) {
29
- if (typeof require !== "undefined") return require.apply(this, arguments);
30
- throw Error('Dynamic require of "' + x + '" is not supported');
31
- });
32
-
33
- // src/theme/colorUtils.ts
34
- function hexToRgb(hex) {
35
- const clean = hex.replace("#", "");
36
- const full = clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean;
37
- if (full.length !== 6) return null;
38
- return {
39
- r: parseInt(full.slice(0, 2), 16),
40
- g: parseInt(full.slice(2, 4), 16),
41
- b: parseInt(full.slice(4, 6), 16)
42
- };
43
- }
44
- function componentToHex(c) {
45
- return Math.round(Math.max(0, Math.min(255, c))).toString(16).padStart(2, "0");
46
- }
47
- function rgbToHex(r, g, b) {
48
- return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`;
49
- }
50
- function withAlphaOnWhite(hex, alpha) {
51
- const rgb = hexToRgb(hex);
52
- if (!rgb) return hex;
53
- const r = rgb.r * alpha + 255 * (1 - alpha);
54
- const g = rgb.g * alpha + 255 * (1 - alpha);
55
- const b = rgb.b * alpha + 255 * (1 - alpha);
56
- return rgbToHex(r, g, b);
57
- }
58
- function withAlphaOnDark(hex, alpha, bgHex = "#0f0f0f") {
59
- const rgb = hexToRgb(hex);
60
- const bg = hexToRgb(bgHex);
61
- if (!rgb || !bg) return hex;
62
- const r = rgb.r * alpha + bg.r * (1 - alpha);
63
- const g = rgb.g * alpha + bg.g * (1 - alpha);
64
- const b = rgb.b * alpha + bg.b * (1 - alpha);
65
- return rgbToHex(r, g, b);
66
- }
67
- function mixWithBackground(fgHex, bgHex, opacity) {
68
- const fg = hexToRgb(fgHex);
69
- const bg = hexToRgb(bgHex);
70
- if (!fg || !bg) return fgHex;
71
- const r = fg.r * opacity + bg.r * (1 - opacity);
72
- const g = fg.g * opacity + bg.g * (1 - opacity);
73
- const b = fg.b * opacity + bg.b * (1 - opacity);
74
- return rgbToHex(r, g, b);
75
- }
76
- function lighten(hex, amount) {
77
- return withAlphaOnWhite(hex, 1 - amount);
78
- }
79
- function darken(hex, amount) {
80
- const rgb = hexToRgb(hex);
81
- if (!rgb) return hex;
82
- return rgbToHex(rgb.r * (1 - amount), rgb.g * (1 - amount), rgb.b * (1 - amount));
83
- }
84
-
85
- // src/theme/colors.ts
86
- var defaultLight = {
87
- background: "#ffffff",
88
- foreground: "#1a1a1a",
89
- card: "#ffffff",
90
- primary: "#1a1a1a",
91
- primaryForeground: "#ffffff",
92
- // AUDIT FIX: brand accent — was undefined; falls back to primary when omitted
93
- accent: "#d4561d",
94
- accentForeground: "#ffffff",
95
- border: "#dddddd",
96
- // AUDIT FIX: was #e53935 (4.22:1 on white — fails AA); #c72828 = 5.59:1 ✓
97
- destructive: "#c72828",
98
- destructiveForeground: "#ffffff",
99
- success: "#1a7a45",
100
- successForeground: "#ffffff",
101
- // AUDIT FIX: was #e67e00 (2.86:1 — severe fail); #9a5200 = 5.86:1 ✓ AAA-near
102
- warning: "#9a5200",
103
- warningForeground: "#ffffff"
104
- };
105
- function deriveColors(t, scheme) {
106
- const dark = scheme === "dark";
107
- const bg = t.background;
108
- const foregroundSubtle = mixWithBackground(t.foreground, bg, 0.7);
109
- const foregroundMuted = mixWithBackground(t.foreground, bg, 0.62);
110
- const surface = dark ? lighten(bg, -0.06) : darken(bg, 0.04);
111
- const surfaceStrong = dark ? lighten(bg, -0.12) : darken(bg, 0.08);
112
- const skeleton = dark ? lighten(bg, -0.1) : darken(bg, 0.1);
113
- const destructiveTint = dark ? withAlphaOnDark(t.destructive, 0.15, bg) : withAlphaOnWhite(t.destructive, 0.08);
114
- const destructiveBorder = dark ? withAlphaOnDark(t.destructive, 0.45, bg) : withAlphaOnWhite(t.destructive, 0.3);
115
- const successTint = dark ? withAlphaOnDark(t.success, 0.15, bg) : withAlphaOnWhite(t.success, 0.08);
116
- const successBorder = dark ? withAlphaOnDark(t.success, 0.45, bg) : withAlphaOnWhite(t.success, 0.3);
117
- const warningTint = dark ? withAlphaOnDark(t.warning, 0.15, bg) : withAlphaOnWhite(t.warning, 0.08);
118
- const warningBorder = dark ? withAlphaOnDark(t.warning, 0.45, bg) : withAlphaOnWhite(t.warning, 0.3);
119
- return {
120
- ...t,
121
- foregroundSubtle,
122
- foregroundMuted,
123
- surface,
124
- surfaceStrong,
125
- skeleton,
126
- destructiveTint,
127
- destructiveBorder,
128
- successTint,
129
- successBorder,
130
- warningTint,
131
- warningBorder,
132
- overlay: t.overlay ?? "rgba(0,0,0,0.45)",
133
- accentResolved: t.accent ?? t.primary,
134
- accentForegroundResolved: t.accentForeground ?? t.primaryForeground,
135
- ring: t.accent ?? t.primary,
136
- input: t.border,
137
- separator: dark ? lighten(t.border, 0.22) : darken(t.border, 0.16)
138
- };
139
- }
140
-
141
- // src/theme/ThemeProvider.tsx
142
- var ThemeContext = React4.createContext({
143
- colors: deriveColors(defaultLight, "light"),
144
- colorScheme: "light"
145
- });
25
+ // src/components/AppHeader/AppHeader.tsx
26
+ var ThemeContext = React4.createContext(void 0);
146
27
  function useTheme() {
147
28
  const context = React4.useContext(ThemeContext);
148
29
  if (!context) {
@@ -151,11 +32,11 @@ function useTheme() {
151
32
  return context;
152
33
  }
153
34
  var _haptics = null;
154
- var _hapticsLoaded = false;
35
+ var _loaded = false;
155
36
  async function getHaptics() {
156
37
  if (reactNative.Platform.OS === "web") return null;
157
- if (!_hapticsLoaded) {
158
- _hapticsLoaded = true;
38
+ if (!_loaded) {
39
+ _loaded = true;
159
40
  try {
160
41
  _haptics = await import('expo-haptics');
161
42
  } catch {
@@ -164,131 +45,52 @@ async function getHaptics() {
164
45
  }
165
46
  return _haptics;
166
47
  }
167
- var _pulsar = null;
168
- var _pulsarChecked = false;
169
- var _pulsarAvailable = false;
170
- function isPulsarNativeRegistered() {
171
- try {
172
- const g = globalThis;
173
- if (typeof g.__turboModuleProxy === "function") {
174
- return g.__turboModuleProxy("RNPulsar") != null;
175
- }
176
- return reactNative.NativeModules?.RNPulsar != null;
177
- } catch {
178
- return false;
179
- }
180
- }
181
- function getPulsar() {
182
- if (reactNative.Platform.OS === "web") return null;
183
- if (!_pulsarChecked) {
184
- _pulsarChecked = true;
185
- try {
186
- if (isPulsarNativeRegistered()) {
187
- _pulsar = __require("react-native-pulsar");
188
- _pulsarAvailable = true;
189
- }
190
- } catch {
191
- _pulsar = null;
192
- _pulsarAvailable = false;
193
- }
194
- }
195
- return _pulsarAvailable ? _pulsar : null;
196
- }
197
48
  function impactLight() {
198
- if (reactNative.Platform.OS === "web") return;
199
- getHaptics().then((h) => {
200
- if (h) {
201
- h.impactAsync(h.ImpactFeedbackStyle.Light);
202
- } else {
203
- getPulsar()?.Presets.System.impactLight();
204
- }
205
- });
49
+ getHaptics().then((h) => h?.impactAsync(h.ImpactFeedbackStyle.Light));
206
50
  }
207
51
  var isWeb = reactNative.Platform.OS === "web";
208
52
  var s = isWeb ? (n) => n : reactNativeSizeMatters.scale;
209
53
  var vs = isWeb ? (n) => n : reactNativeSizeMatters.verticalScale;
210
54
  var ms = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateScale;
211
55
  var mvs = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateVerticalScale;
212
- var glyphMapOf = (mod) => mod.glyphMap ?? {};
213
56
  var ALL_FAMILIES = [
214
- { name: "Ionicons", component: Ionicons__default.default, getGlyphMap: () => glyphMapOf(Ionicons__default.default) },
215
- { name: "MaterialIcons", component: MaterialIcons__default.default, getGlyphMap: () => glyphMapOf(MaterialIcons__default.default) },
216
- { name: "FontAwesome5", component: FontAwesome5__default.default, getGlyphMap: () => glyphMapOf(FontAwesome5__default.default) },
217
- { name: "Entypo", component: Entypo__default.default, getGlyphMap: () => glyphMapOf(Entypo__default.default) },
218
- { name: "AntDesign", component: AntDesign__default.default, getGlyphMap: () => glyphMapOf(AntDesign__default.default) },
219
- { name: "Feather", component: Feather__default.default, getGlyphMap: () => glyphMapOf(Feather__default.default) }
57
+ { name: "Feather", component: Feather__default.default },
58
+ { name: "AntDesign", component: AntDesign__default.default },
59
+ { name: "Entypo", component: Entypo__default.default },
60
+ { name: "FontAwesome5", component: FontAwesome5__default.default },
61
+ { name: "MaterialIcons", component: MaterialIcons__default.default },
62
+ { name: "Ionicons", component: Ionicons__default.default }
220
63
  ];
221
- var activeFamilies = ALL_FAMILIES;
222
- var resolvedCache = null;
223
- function buildCache(families) {
224
- const cache = /* @__PURE__ */ new Map();
225
- for (const family of activeFamilies) {
226
- const glyphMap = family.getGlyphMap();
227
- for (const iconName of Object.keys(glyphMap)) {
228
- cache.set(iconName, family);
64
+ var glyphCacheInitialized = false;
65
+ function ensureGlyphCache() {
66
+ if (glyphCacheInitialized) return;
67
+ glyphCacheInitialized = true;
68
+ for (const entry of ALL_FAMILIES) {
69
+ try {
70
+ entry.glyphMap = entry.component.glyphMap;
71
+ } catch {
72
+ entry.glyphMap = {};
229
73
  }
230
74
  }
231
- return cache;
232
- }
233
- function resolveFamily(name) {
234
- if (!resolvedCache) {
235
- resolvedCache = buildCache();
236
- }
237
- return resolvedCache.get(name) ?? null;
238
75
  }
239
76
  function Icon({ name, size, color, family }) {
240
- let resolved = null;
241
- if (family) {
242
- resolved = ALL_FAMILIES.find((f) => f.name === family) ?? null;
243
- } else {
244
- resolved = resolveFamily(name);
245
- }
246
- if (!resolved) return null;
247
- const Component = resolved.component;
248
- return React4__default.default.createElement(Component, { name, size, color });
249
- }
250
- function renderIcon(name, size, color) {
251
- return React4__default.default.createElement(Icon, { name, size, color });
77
+ ensureGlyphCache();
78
+ const entry = family ? ALL_FAMILIES.find((f) => f.name === family) : ALL_FAMILIES.find((f) => {
79
+ const glyphMap = f.glyphMap;
80
+ return glyphMap ? name in glyphMap : false;
81
+ });
82
+ if (!entry) return null;
83
+ return React4__default.default.createElement(entry.component, { name, size, color });
252
84
  }
253
- ({
254
- /** Material-style ease-out — natural deceleration for state changes. */
255
- standard: reactNativeReanimated.Easing.bezier(0.2, 0, 0, 1),
256
- /** Strong ease-out for expanding surfaces (Accordion open). */
257
- expand: reactNativeReanimated.Easing.bezier(0.23, 1, 0.32, 1),
258
- /** Quick ease-in for collapsing. */
259
- collapse: reactNativeReanimated.Easing.in(reactNativeReanimated.Easing.ease)
260
- });
261
- var PRESS_SCALE = {
262
- button: 0.95,
263
- card: 0.98,
264
- row: 0.97,
265
- chip: 0.94
266
- };
267
- var PressableButton = pressto.createAnimatedPressable((progress) => {
268
- "worklet";
269
- const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
270
- return { transform: [{ scale: scale2 }] };
271
- });
272
- pressto.createAnimatedPressable((progress) => {
273
- "worklet";
274
- const scale2 = 1 - (1 - PRESS_SCALE.card) * progress;
275
- return { transform: [{ scale: scale2 }] };
276
- });
277
- pressto.createAnimatedPressable((progress) => {
85
+ var makePressable = (scale2) => pressto.createAnimatedPressable((progress) => {
278
86
  "worklet";
279
- const scale2 = 1 - (1 - PRESS_SCALE.row) * progress;
280
- return { transform: [{ scale: scale2 }] };
281
- });
282
- pressto.createAnimatedPressable((progress) => {
283
- "worklet";
284
- const scale2 = 1 - (1 - PRESS_SCALE.chip) * progress;
285
- return { transform: [{ scale: scale2 }] };
286
- });
287
- pressto.createAnimatedPressable((progress) => {
288
- "worklet";
289
- const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
290
- return { transform: [{ scale: scale2 }] };
87
+ return { transform: [{ scale: 1 - (1 - scale2) * progress }] };
291
88
  });
89
+ var PressableButton = makePressable(0.95);
90
+ makePressable(0.98);
91
+ makePressable(0.97);
92
+ makePressable(0.94);
93
+ makePressable(0.95);
292
94
 
293
95
  // src/components/IconButton/IconButton.tsx
294
96
  var sizeMap = {
@@ -333,7 +135,7 @@ function IconButtonBase({
333
135
  }[variant];
334
136
  const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary" ? colors.primaryForeground : colors.foreground;
335
137
  const { container: containerSize, icon: iconSize } = sizeMap[size];
336
- const resolvedIcon = iconName ? renderIcon(iconName, iconSize, iconColor ?? defaultIconColor) : icon;
138
+ const resolvedIcon = iconName ? /* @__PURE__ */ React4__default.default.createElement(Icon, { name: iconName, size: iconSize, color: iconColor ?? defaultIconColor }) : icon;
337
139
  const showBadge = badge !== void 0 && badge !== false && badge !== 0;
338
140
  const badgeCount = typeof badge === "number" ? Math.min(badge, 99) : null;
339
141
  const showCount = typeof badge === "number" && badge > 0;
@@ -413,6 +215,7 @@ function AppHeader({
413
215
  subtitle,
414
216
  onBack,
415
217
  backIconName = "chevron-left",
218
+ iconName,
416
219
  left,
417
220
  right,
418
221
  titleAlign = "auto",
@@ -426,16 +229,16 @@ function AppHeader({
426
229
  const { width } = reactNative.useWindowDimensions();
427
230
  const isWide = width >= BREAKPOINTS.wide;
428
231
  const centered = titleAlign === "center" || titleAlign === "auto" && isWide;
429
- const leftNode = left ?? (onBack ? /* @__PURE__ */ React4__default.default.createElement(
232
+ const leftNode = left ?? /* @__PURE__ */ React4__default.default.createElement(React4__default.default.Fragment, null, onBack ? /* @__PURE__ */ React4__default.default.createElement(
430
233
  IconButton,
431
234
  {
432
235
  iconName: backIconName,
433
236
  variant: "text",
434
237
  size: "md",
435
238
  onPress: onBack,
436
- accessibilityLabel: "Go back"
239
+ accessibilityLabel: "Atr\xE1s"
437
240
  }
438
- ) : null);
241
+ ) : null, iconName && !left ? /* @__PURE__ */ React4__default.default.createElement(Icon, { name: iconName, size: 20, color: colors.foreground }) : null);
439
242
  const titleBlock = /* @__PURE__ */ React4__default.default.createElement(reactNative.View, { style: [styles2.titleBlock, centered && styles2.titleBlockCentered], pointerEvents: "none" }, title ? /* @__PURE__ */ React4__default.default.createElement(
440
243
  reactNative.Text,
441
244
  {
@@ -485,10 +288,13 @@ var styles2 = reactNative.StyleSheet.create({
485
288
  minWidth: s(44),
486
289
  flexDirection: "row",
487
290
  alignItems: "center",
488
- justifyContent: "flex-start"
291
+ justifyContent: "flex-start",
292
+ paddingLeft: s(8),
293
+ gap: s(4)
489
294
  },
490
295
  sideRight: {
491
- justifyContent: "flex-end"
296
+ justifyContent: "flex-end",
297
+ paddingRight: s(8)
492
298
  },
493
299
  titleBlock: {
494
300
  flex: 1,
@@ -1,10 +1,8 @@
1
- export { AppHeader } from './chunk-MVMGPZN6.mjs';
2
- import './chunk-LOBLCFMN.mjs';
3
- import './chunk-3DKJ2GIC.mjs';
4
- import './chunk-EJ7ZPXOH.mjs';
5
- import './chunk-DVK4G2GT.mjs';
1
+ export { AppHeader } from './chunk-H6MQL7PS.mjs';
2
+ import './chunk-ZTPYUU5C.mjs';
3
+ import './chunk-IFYMBOEN.mjs';
4
+ import './chunk-ARONDO7M.mjs';
6
5
  import './chunk-QY3X2UYR.mjs';
7
- import './chunk-KA7LTET3.mjs';
8
- import './chunk-YTXRIXNZ.mjs';
6
+ import './chunk-MZ6WRTD2.mjs';
7
+ import './chunk-KSSVIFYR.mjs';
9
8
  import './chunk-2CE3TQVY.mjs';
10
- import './chunk-Y6FXYEAI.mjs';
package/dist/Avatar.d.mts CHANGED
@@ -16,5 +16,21 @@ interface AvatarProps {
16
16
  }
17
17
  declare function AvatarBase({ src, fallback, fallbackText, size, status, style }: AvatarProps): React.JSX.Element;
18
18
  declare const Avatar: React.MemoExoticComponent<typeof AvatarBase>;
19
+ interface AvatarGroupProps {
20
+ users: {
21
+ name: string;
22
+ src?: string;
23
+ }[];
24
+ /** Max avatars visible before +N overflow badge. Default 3. */
25
+ max?: number;
26
+ /** Avatar size preset. Default 'sm'. */
27
+ size?: AvatarSize;
28
+ /** Overlap between avatars in points. Default 8 (spacing.sm). */
29
+ overlap?: number;
30
+ /** Called when +N overflow badge is tapped. */
31
+ onOverflowPress?: () => void;
32
+ style?: ViewStyle;
33
+ }
34
+ declare function AvatarGroup({ users, max, size, overlap, onOverflowPress, style, }: AvatarGroupProps): React.JSX.Element;
19
35
 
20
- export { Avatar, type AvatarProps, type AvatarSize };
36
+ export { Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type AvatarSize };
package/dist/Avatar.d.ts CHANGED
@@ -16,5 +16,21 @@ interface AvatarProps {
16
16
  }
17
17
  declare function AvatarBase({ src, fallback, fallbackText, size, status, style }: AvatarProps): React.JSX.Element;
18
18
  declare const Avatar: React.MemoExoticComponent<typeof AvatarBase>;
19
+ interface AvatarGroupProps {
20
+ users: {
21
+ name: string;
22
+ src?: string;
23
+ }[];
24
+ /** Max avatars visible before +N overflow badge. Default 3. */
25
+ max?: number;
26
+ /** Avatar size preset. Default 'sm'. */
27
+ size?: AvatarSize;
28
+ /** Overlap between avatars in points. Default 8 (spacing.sm). */
29
+ overlap?: number;
30
+ /** Called when +N overflow badge is tapped. */
31
+ onOverflowPress?: () => void;
32
+ style?: ViewStyle;
33
+ }
34
+ declare function AvatarGroup({ users, max, size, overlap, onOverflowPress, style, }: AvatarGroupProps): React.JSX.Element;
19
35
 
20
- export { Avatar, type AvatarProps, type AvatarSize };
36
+ export { Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type AvatarSize };
package/dist/Avatar.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var React2 = require('react');
4
+ var expoImage = require('expo-image');
4
5
  var reactNative = require('react-native');
5
6
  var reactNativeSizeMatters = require('react-native-size-matters');
6
7
 
@@ -9,120 +10,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
10
  var React2__default = /*#__PURE__*/_interopDefault(React2);
10
11
 
11
12
  // src/components/Avatar/Avatar.tsx
12
-
13
- // src/theme/colorUtils.ts
14
- function hexToRgb(hex) {
15
- const clean = hex.replace("#", "");
16
- const full = clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean;
17
- if (full.length !== 6) return null;
18
- return {
19
- r: parseInt(full.slice(0, 2), 16),
20
- g: parseInt(full.slice(2, 4), 16),
21
- b: parseInt(full.slice(4, 6), 16)
22
- };
23
- }
24
- function componentToHex(c) {
25
- return Math.round(Math.max(0, Math.min(255, c))).toString(16).padStart(2, "0");
26
- }
27
- function rgbToHex(r, g, b) {
28
- return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`;
29
- }
30
- function withAlphaOnWhite(hex, alpha) {
31
- const rgb = hexToRgb(hex);
32
- if (!rgb) return hex;
33
- const r = rgb.r * alpha + 255 * (1 - alpha);
34
- const g = rgb.g * alpha + 255 * (1 - alpha);
35
- const b = rgb.b * alpha + 255 * (1 - alpha);
36
- return rgbToHex(r, g, b);
37
- }
38
- function withAlphaOnDark(hex, alpha, bgHex = "#0f0f0f") {
39
- const rgb = hexToRgb(hex);
40
- const bg = hexToRgb(bgHex);
41
- if (!rgb || !bg) return hex;
42
- const r = rgb.r * alpha + bg.r * (1 - alpha);
43
- const g = rgb.g * alpha + bg.g * (1 - alpha);
44
- const b = rgb.b * alpha + bg.b * (1 - alpha);
45
- return rgbToHex(r, g, b);
46
- }
47
- function mixWithBackground(fgHex, bgHex, opacity) {
48
- const fg = hexToRgb(fgHex);
49
- const bg = hexToRgb(bgHex);
50
- if (!fg || !bg) return fgHex;
51
- const r = fg.r * opacity + bg.r * (1 - opacity);
52
- const g = fg.g * opacity + bg.g * (1 - opacity);
53
- const b = fg.b * opacity + bg.b * (1 - opacity);
54
- return rgbToHex(r, g, b);
55
- }
56
- function lighten(hex, amount) {
57
- return withAlphaOnWhite(hex, 1 - amount);
58
- }
59
- function darken(hex, amount) {
60
- const rgb = hexToRgb(hex);
61
- if (!rgb) return hex;
62
- return rgbToHex(rgb.r * (1 - amount), rgb.g * (1 - amount), rgb.b * (1 - amount));
63
- }
64
-
65
- // src/theme/colors.ts
66
- var defaultLight = {
67
- background: "#ffffff",
68
- foreground: "#1a1a1a",
69
- card: "#ffffff",
70
- primary: "#1a1a1a",
71
- primaryForeground: "#ffffff",
72
- // AUDIT FIX: brand accent — was undefined; falls back to primary when omitted
73
- accent: "#d4561d",
74
- accentForeground: "#ffffff",
75
- border: "#dddddd",
76
- // AUDIT FIX: was #e53935 (4.22:1 on white — fails AA); #c72828 = 5.59:1 ✓
77
- destructive: "#c72828",
78
- destructiveForeground: "#ffffff",
79
- success: "#1a7a45",
80
- successForeground: "#ffffff",
81
- // AUDIT FIX: was #e67e00 (2.86:1 — severe fail); #9a5200 = 5.86:1 ✓ AAA-near
82
- warning: "#9a5200",
83
- warningForeground: "#ffffff"
84
- };
85
- function deriveColors(t, scheme) {
86
- const dark = scheme === "dark";
87
- const bg = t.background;
88
- const foregroundSubtle = mixWithBackground(t.foreground, bg, 0.7);
89
- const foregroundMuted = mixWithBackground(t.foreground, bg, 0.62);
90
- const surface = dark ? lighten(bg, -0.06) : darken(bg, 0.04);
91
- const surfaceStrong = dark ? lighten(bg, -0.12) : darken(bg, 0.08);
92
- const skeleton = dark ? lighten(bg, -0.1) : darken(bg, 0.1);
93
- const destructiveTint = dark ? withAlphaOnDark(t.destructive, 0.15, bg) : withAlphaOnWhite(t.destructive, 0.08);
94
- const destructiveBorder = dark ? withAlphaOnDark(t.destructive, 0.45, bg) : withAlphaOnWhite(t.destructive, 0.3);
95
- const successTint = dark ? withAlphaOnDark(t.success, 0.15, bg) : withAlphaOnWhite(t.success, 0.08);
96
- const successBorder = dark ? withAlphaOnDark(t.success, 0.45, bg) : withAlphaOnWhite(t.success, 0.3);
97
- const warningTint = dark ? withAlphaOnDark(t.warning, 0.15, bg) : withAlphaOnWhite(t.warning, 0.08);
98
- const warningBorder = dark ? withAlphaOnDark(t.warning, 0.45, bg) : withAlphaOnWhite(t.warning, 0.3);
99
- return {
100
- ...t,
101
- foregroundSubtle,
102
- foregroundMuted,
103
- surface,
104
- surfaceStrong,
105
- skeleton,
106
- destructiveTint,
107
- destructiveBorder,
108
- successTint,
109
- successBorder,
110
- warningTint,
111
- warningBorder,
112
- overlay: t.overlay ?? "rgba(0,0,0,0.45)",
113
- accentResolved: t.accent ?? t.primary,
114
- accentForegroundResolved: t.accentForeground ?? t.primaryForeground,
115
- ring: t.accent ?? t.primary,
116
- input: t.border,
117
- separator: dark ? lighten(t.border, 0.22) : darken(t.border, 0.16)
118
- };
119
- }
120
-
121
- // src/theme/ThemeProvider.tsx
122
- var ThemeContext = React2.createContext({
123
- colors: deriveColors(defaultLight, "light"),
124
- colorScheme: "light"
125
- });
13
+ var ThemeContext = React2.createContext(void 0);
126
14
  function useTheme() {
127
15
  const context = React2.useContext(ThemeContext);
128
16
  if (!context) {
@@ -132,6 +20,7 @@ function useTheme() {
132
20
  }
133
21
  var isWeb = reactNative.Platform.OS === "web";
134
22
  var s = isWeb ? (n) => n : reactNativeSizeMatters.scale;
23
+ var vs = isWeb ? (n) => n : reactNativeSizeMatters.verticalScale;
135
24
  var ms = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateScale;
136
25
 
137
26
  // src/components/Avatar/Avatar.tsx
@@ -191,7 +80,7 @@ function AvatarBase({ src, fallback, fallbackText, size = "md", status, style })
191
80
  accessibilityLabel: a11yLabel
192
81
  },
193
82
  /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: [styles.base, containerStyle] }, !showFallback ? /* @__PURE__ */ React2__default.default.createElement(
194
- reactNative.Image,
83
+ expoImage.Image,
195
84
  {
196
85
  source: { uri: src },
197
86
  style: { width: dimension, height: dimension },
@@ -224,6 +113,66 @@ function AvatarBase({ src, fallback, fallbackText, size = "md", status, style })
224
113
  );
225
114
  }
226
115
  var Avatar = React2__default.default.memo(AvatarBase);
116
+ function AvatarGroup({
117
+ users,
118
+ max = 3,
119
+ size = "sm",
120
+ overlap = vs(8),
121
+ onOverflowPress,
122
+ style
123
+ }) {
124
+ const { colors } = useTheme();
125
+ const visible = users.slice(0, max);
126
+ const overflowCount = users.length - max;
127
+ const dimension = sizeMap[size];
128
+ return /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: [styles.group, style], accessibilityLabel: `${users.length} avatares` }, visible.map((user, i) => /* @__PURE__ */ React2__default.default.createElement(
129
+ reactNative.View,
130
+ {
131
+ key: `${user.name}-${i}`,
132
+ style: [
133
+ styles.groupItem,
134
+ i > 0 && { marginLeft: -overlap },
135
+ { zIndex: visible.length - i }
136
+ ]
137
+ },
138
+ /* @__PURE__ */ React2__default.default.createElement(
139
+ Avatar,
140
+ {
141
+ src: user.src,
142
+ fallbackText: user.name,
143
+ size
144
+ }
145
+ )
146
+ )), overflowCount > 0 ? /* @__PURE__ */ React2__default.default.createElement(
147
+ reactNative.TouchableOpacity,
148
+ {
149
+ style: [
150
+ styles.overflowBadge,
151
+ {
152
+ width: dimension,
153
+ height: dimension,
154
+ borderRadius: dimension / 2,
155
+ backgroundColor: colors.surfaceStrong,
156
+ marginLeft: -overlap
157
+ }
158
+ ],
159
+ onPress: onOverflowPress,
160
+ disabled: !onOverflowPress,
161
+ activeOpacity: 0.7,
162
+ accessibilityRole: "button",
163
+ accessibilityLabel: `${overflowCount} avatares m\xE1s`
164
+ },
165
+ /* @__PURE__ */ React2__default.default.createElement(
166
+ reactNative.Text,
167
+ {
168
+ style: [styles.overflowText, { color: colors.foregroundMuted }],
169
+ allowFontScaling: true
170
+ },
171
+ "+",
172
+ overflowCount
173
+ )
174
+ ) : null);
175
+ }
227
176
  var styles = reactNative.StyleSheet.create({
228
177
  wrapper: {
229
178
  alignSelf: "flex-start",
@@ -240,7 +189,23 @@ var styles = reactNative.StyleSheet.create({
240
189
  position: "absolute",
241
190
  bottom: 0,
242
191
  right: 0
192
+ },
193
+ group: {
194
+ flexDirection: "row",
195
+ alignItems: "center"
196
+ },
197
+ groupItem: {
198
+ borderRadius: 999
199
+ },
200
+ overflowBadge: {
201
+ alignItems: "center",
202
+ justifyContent: "center"
203
+ },
204
+ overflowText: {
205
+ fontFamily: "Sohne-SemiBold",
206
+ fontSize: ms(11)
243
207
  }
244
208
  });
245
209
 
246
210
  exports.Avatar = Avatar;
211
+ exports.AvatarGroup = AvatarGroup;
package/dist/Avatar.mjs CHANGED
@@ -1,4 +1,3 @@
1
- export { Avatar } from './chunk-QOLWA2PW.mjs';
2
- import './chunk-YTXRIXNZ.mjs';
1
+ export { Avatar, AvatarGroup } from './chunk-IGU223UM.mjs';
2
+ import './chunk-KSSVIFYR.mjs';
3
3
  import './chunk-2CE3TQVY.mjs';
4
- import './chunk-Y6FXYEAI.mjs';