@btndprojects/loam-ui-native 0.1.1 → 0.2.1

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 (262) hide show
  1. package/dist/accordion/index.js +5 -3
  2. package/dist/adaptive/index.js +6 -2
  3. package/dist/alert/index.js +5 -2
  4. package/dist/analyzer/index.js +9 -6
  5. package/dist/announcement/index.js +8 -5
  6. package/dist/audio-player/index.js +5 -3
  7. package/dist/avatar/index.js +5 -2
  8. package/dist/avatar-group/index.js +7 -3
  9. package/dist/badge/index.js +7 -4
  10. package/dist/banner/index.js +5 -2
  11. package/dist/board/index.js +11 -6
  12. package/dist/button/index.js +6 -3
  13. package/dist/camera-permission/index.js +15 -12
  14. package/dist/capture-result/index.js +19 -16
  15. package/dist/card/index.js +6 -3
  16. package/dist/card-form/index.js +12 -8
  17. package/dist/carousel/index.js +4 -2
  18. package/dist/chart/index.js +8 -5
  19. package/dist/charts/index.js +8 -6
  20. package/dist/chat/index.js +16 -0
  21. package/dist/checkbox/index.js +6 -4
  22. package/dist/checklist/index.js +11 -8
  23. package/dist/checkout/index.js +16 -11
  24. package/dist/chip/index.js +7 -4
  25. package/dist/{chunk-XNUVB5OL.js → chunk-2OLKPG4E.js} +92 -28
  26. package/dist/{chunk-RUZHTGKB.js → chunk-2PKYGLQ6.js} +71 -40
  27. package/dist/{chunk-UC2WGUP3.js → chunk-2SWKL3AJ.js} +91 -252
  28. package/dist/{chunk-AI4DWZCD.js → chunk-2SY63FCH.js} +63 -16
  29. package/dist/{chunk-F5XNPWS7.js → chunk-2TXERVVA.js} +92 -35
  30. package/dist/chunk-36EC2T6P.js +581 -0
  31. package/dist/chunk-3DUWIYV5.js +437 -0
  32. package/dist/{chunk-JNY4ZHAR.js → chunk-3QMEOFW5.js} +275 -71
  33. package/dist/chunk-3WEZCGHX.js +265 -0
  34. package/dist/chunk-46MMSDGL.js +194 -0
  35. package/dist/{chunk-7O2FMUPT.js → chunk-4IZXHVFJ.js} +297 -92
  36. package/dist/{chunk-LAECSR4H.js → chunk-5LAAAXFP.js} +14 -8
  37. package/dist/{chunk-2A5NIQAK.js → chunk-5RENVKBQ.js} +134 -46
  38. package/dist/{chunk-2ZZ7TDJ4.js → chunk-5UTRIXQ6.js} +37 -31
  39. package/dist/{chunk-LOE5YNN3.js → chunk-5VFZRGVD.js} +37 -10
  40. package/dist/{chunk-52X2VYTD.js → chunk-67IZZ2MJ.js} +115 -60
  41. package/dist/{chunk-UYG5L34B.js → chunk-6YAQBXB3.js} +10 -4
  42. package/dist/{chunk-BTTFCMKG.js → chunk-74FLKD24.js} +94 -23
  43. package/dist/{chunk-ITTYJZWX.js → chunk-7BUIKDD6.js} +73 -18
  44. package/dist/{chunk-423B7SPN.js → chunk-7OVVSVEZ.js} +273 -109
  45. package/dist/chunk-AEB7KCHQ.js +287 -0
  46. package/dist/chunk-APCWFOZW.js +28 -0
  47. package/dist/chunk-AWKQIE5I.js +139 -0
  48. package/dist/{chunk-VCDBXW5H.js → chunk-B7N4ASYE.js} +86 -42
  49. package/dist/{chunk-IVNRBPGC.js → chunk-C4GTDLRC.js} +104 -20
  50. package/dist/{chunk-4ZAHCY44.js → chunk-C6APNDVA.js} +12 -5
  51. package/dist/{chunk-4SZYY6AN.js → chunk-CMTVNF3D.js} +18 -13
  52. package/dist/{chunk-HZ6CNMAF.js → chunk-CPTOADB2.js} +151 -96
  53. package/dist/chunk-D5N5QWI7.js +1325 -0
  54. package/dist/{chunk-IIQTAY3J.js → chunk-DN7MNQIP.js} +113 -29
  55. package/dist/{chunk-47FWHGUN.js → chunk-DVGBZ3TX.js} +84 -23
  56. package/dist/chunk-DW3L54DQ.js +305 -0
  57. package/dist/{chunk-3ARE4TES.js → chunk-E2E3I5W2.js} +69 -18
  58. package/dist/{chunk-DHWADYZX.js → chunk-EDCBJV7J.js} +41 -28
  59. package/dist/{chunk-WSW6ZFAQ.js → chunk-ENP3BMZU.js} +4 -4
  60. package/dist/{chunk-OOPPQH27.js → chunk-EVOIGUBI.js} +43 -19
  61. package/dist/{chunk-VEAYTRPX.js → chunk-EY4DD67D.js} +165 -97
  62. package/dist/{chunk-223Q2T2Q.js → chunk-F3H33DQX.js} +132 -61
  63. package/dist/{chunk-CYRBHQQZ.js → chunk-F5B3UINI.js} +68 -35
  64. package/dist/{chunk-6X6PQ443.js → chunk-FAJI7BSC.js} +20 -9
  65. package/dist/{chunk-MOUJOP55.js → chunk-FUMHAAF3.js} +96 -29
  66. package/dist/{chunk-6HT2LP62.js → chunk-FV6HMP7W.js} +192 -73
  67. package/dist/{chunk-S7F6XLTK.js → chunk-FYWNRX4F.js} +76 -47
  68. package/dist/{chunk-YG3ZJHGU.js → chunk-FZGAAOKS.js} +30 -8
  69. package/dist/{chunk-YDGVJETP.js → chunk-G3AFC24V.js} +1 -1
  70. package/dist/{chunk-EJBDRVIH.js → chunk-G6UESEVN.js} +15 -8
  71. package/dist/chunk-GDKVKNR2.js +339 -0
  72. package/dist/chunk-GEIGMWNF.js +10 -0
  73. package/dist/{chunk-JUAMLEHX.js → chunk-H7DWSL4O.js} +24 -12
  74. package/dist/chunk-HJFFOOJ4.js +1 -0
  75. package/dist/{chunk-RW6ZL2FQ.js → chunk-HJLPZA4X.js} +106 -21
  76. package/dist/chunk-HYEOQWT7.js +647 -0
  77. package/dist/chunk-I2KLQ2HA.js +19 -0
  78. package/dist/{chunk-CJ5EOYZE.js → chunk-I4FHVKEC.js} +11 -5
  79. package/dist/{chunk-JNH2TYIN.js → chunk-IDM7JJMO.js} +19 -5
  80. package/dist/{chunk-O4AEHWII.js → chunk-IPUNJMAQ.js} +141 -49
  81. package/dist/{chunk-J7Q7VCVC.js → chunk-IT6FUXXG.js} +13 -6
  82. package/dist/{chunk-QJJ6MADV.js → chunk-IVKMZ7BB.js} +80 -28
  83. package/dist/{chunk-Z7H7VSFZ.js → chunk-IXKWIFWZ.js} +17 -6
  84. package/dist/chunk-J64KGCGX.js +55 -0
  85. package/dist/chunk-JBMLWFSJ.js +270 -0
  86. package/dist/{chunk-4BXMXBJO.js → chunk-JJLPBRVZ.js} +22 -11
  87. package/dist/chunk-JLC6PM5S.js +406 -0
  88. package/dist/chunk-JUYWSSKW.js +335 -0
  89. package/dist/{chunk-7CFF4HXS.js → chunk-JV5YOTOB.js} +49 -11
  90. package/dist/{chunk-LZLHELAG.js → chunk-KFJGFLMW.js} +29 -8
  91. package/dist/{chunk-O7AE6DAF.js → chunk-KQZ3GLHR.js} +18 -8
  92. package/dist/{chunk-N32RGOA5.js → chunk-LKFC4CS7.js} +80 -24
  93. package/dist/{chunk-YC6WORFL.js → chunk-LMPHCVJJ.js} +82 -50
  94. package/dist/{chunk-3WPW4KUN.js → chunk-LQP4KEXZ.js} +45 -13
  95. package/dist/{chunk-TKQYWZ5V.js → chunk-LUMVGO2K.js} +47 -31
  96. package/dist/{chunk-AWJOCGFZ.js → chunk-M656FYNH.js} +25 -13
  97. package/dist/{chunk-35OFI3JG.js → chunk-MKSNFG7H.js} +73 -20
  98. package/dist/{chunk-4GBOGOTV.js → chunk-NBEF4EPJ.js} +16 -6
  99. package/dist/chunk-NNCOFLNE.js +24 -0
  100. package/dist/{chunk-4YQOR7JM.js → chunk-NTQ2F3AU.js} +73 -20
  101. package/dist/{chunk-QCDXZBC5.js → chunk-O5V4TG3V.js} +126 -44
  102. package/dist/{chunk-U7TFM2JA.js → chunk-OJQUBQWA.js} +3 -3
  103. package/dist/{chunk-VQHPQEUH.js → chunk-OWAMM2DK.js} +13 -6
  104. package/dist/chunk-PID3NJB7.js +405 -0
  105. package/dist/{chunk-HET4LLMX.js → chunk-PMMTGBBS.js} +27 -17
  106. package/dist/{chunk-RIBDXGUG.js → chunk-PNF3NKB5.js} +49 -16
  107. package/dist/{chunk-JXJB2X6M.js → chunk-Q6NKEPRE.js} +81 -32
  108. package/dist/chunk-QDZGFXQD.js +176 -0
  109. package/dist/{chunk-SYNOJOQO.js → chunk-QEYFDRHR.js} +60 -26
  110. package/dist/{chunk-VBOXAEPI.js → chunk-QHAITQIF.js} +97 -22
  111. package/dist/{chunk-VXDZFJGP.js → chunk-QHTVYA65.js} +230 -76
  112. package/dist/{chunk-TUTI5HOZ.js → chunk-QIKT7LIB.js} +14 -8
  113. package/dist/{chunk-3ENTMPQY.js → chunk-QP3KMOVF.js} +82 -42
  114. package/dist/{chunk-GNNJ4GCC.js → chunk-QPWDDJJ4.js} +62 -148
  115. package/dist/{chunk-QWCMU5B2.js → chunk-QRUMA22E.js} +205 -80
  116. package/dist/{chunk-ZVFE5QGU.js → chunk-QYPE5JX3.js} +50 -10
  117. package/dist/{chunk-PUPM2YGF.js → chunk-ROCUG24E.js} +76 -36
  118. package/dist/{chunk-NQYBUO3K.js → chunk-RU3ZPNL6.js} +333 -142
  119. package/dist/{chunk-TOXAGRDQ.js → chunk-RXSCIO6W.js} +14 -5
  120. package/dist/{chunk-FMYDDECK.js → chunk-SATMR6SG.js} +631 -203
  121. package/dist/{chunk-4YIP3CWS.js → chunk-SHHY5OMK.js} +7 -5
  122. package/dist/chunk-SKWO3SZF.js +2284 -0
  123. package/dist/{chunk-YF4NSSMT.js → chunk-SWS5JQIF.js} +41 -13
  124. package/dist/{chunk-CUMUNPXY.js → chunk-T5LTPKX6.js} +15 -7
  125. package/dist/{chunk-H6NIOQHK.js → chunk-TDMG26JI.js} +26 -6
  126. package/dist/{chunk-UWFLYMAR.js → chunk-TLCIR6RG.js} +267 -126
  127. package/dist/{chunk-SBMNWWBV.js → chunk-TN2ZNJUI.js} +47 -9
  128. package/dist/{chunk-5YNTNN5A.js → chunk-TQVAIKFD.js} +106 -41
  129. package/dist/chunk-TRGFFU6A.js +1456 -0
  130. package/dist/{chunk-2GK6PHGE.js → chunk-TY4MTKQJ.js} +100 -22
  131. package/dist/{chunk-AZRX6SAC.js → chunk-U23FYWME.js} +15 -7
  132. package/dist/{chunk-PZXZJBMP.js → chunk-U5NLHYV6.js} +26 -12
  133. package/dist/chunk-UQEN55EY.js +1 -0
  134. package/dist/chunk-UQGBTPXH.js +218 -0
  135. package/dist/chunk-UXGIW7OK.js +116 -0
  136. package/dist/{chunk-PJXUJYS6.js → chunk-UYGDJWMN.js} +55 -30
  137. package/dist/{chunk-QDYDBCFP.js → chunk-V2OEB75Z.js} +50 -51
  138. package/dist/{chunk-LSS54GLJ.js → chunk-VAOAKWUK.js} +34 -13
  139. package/dist/{chunk-DM5QUKKO.js → chunk-VDPK5CY4.js} +18 -6
  140. package/dist/chunk-W23G6JLF.js +37 -0
  141. package/dist/{chunk-CDRZHT42.js → chunk-W63AJTM7.js} +276 -12
  142. package/dist/{chunk-XXXEFXY5.js → chunk-W74TXYFB.js} +13 -5
  143. package/dist/{chunk-LRJNDEIA.js → chunk-WRDSPUE7.js} +144 -29
  144. package/dist/{chunk-C2NTXVWM.js → chunk-XBZGDDMR.js} +11 -4
  145. package/dist/{chunk-BV3B2HYZ.js → chunk-XIDTBCBA.js} +189 -131
  146. package/dist/{chunk-YTFKPRUK.js → chunk-XN4KG3P4.js} +348 -153
  147. package/dist/chunk-XQXMLMH3.js +211 -0
  148. package/dist/{chunk-HPPW424V.js → chunk-XTORZWRF.js} +19 -8
  149. package/dist/{chunk-P23EQNRQ.js → chunk-YAAHPATV.js} +181 -30
  150. package/dist/{chunk-KMI5ML5I.js → chunk-YXOAPXMU.js} +57 -18
  151. package/dist/{chunk-RJQOOHT2.js → chunk-ZECZOOSB.js} +59 -28
  152. package/dist/{chunk-QKXCPTFS.js → chunk-ZLTO5VQI.js} +121 -31
  153. package/dist/{chunk-BEDBFJND.js → chunk-ZVATDZOM.js} +16 -18
  154. package/dist/coachmark/index.js +6 -3
  155. package/dist/code-block/index.js +5 -3
  156. package/dist/color-field/index.js +6 -4
  157. package/dist/commerce/index.js +19 -16
  158. package/dist/connectivity/index.js +5 -2
  159. package/dist/context-menu/index.js +5 -3
  160. package/dist/copy-button/index.js +4 -2
  161. package/dist/data-grid/index.js +21 -16
  162. package/dist/date-range-picker/index.js +11 -8
  163. package/dist/description-list/index.js +3 -1
  164. package/dist/dialog/index.js +4 -2
  165. package/dist/empty-state/index.js +4 -2
  166. package/dist/error-summary/index.js +4 -2
  167. package/dist/fab/index.js +5 -2
  168. package/dist/file-manager/index.js +28 -0
  169. package/dist/file-upload/index.js +10 -7
  170. package/dist/filter-bar/index.js +9 -6
  171. package/dist/flow-run/index.js +15 -12
  172. package/dist/form/index.js +5 -3
  173. package/dist/gallery/index.js +5 -2
  174. package/dist/hold-to-confirm/index.js +4 -2
  175. package/dist/index.d.ts +9557 -2985
  176. package/dist/index.js +355 -122
  177. package/dist/infinite-list/index.js +4 -2
  178. package/dist/inline-edit/index.js +6 -4
  179. package/dist/input/index.js +5 -3
  180. package/dist/interactions/index.js +2 -1
  181. package/dist/invoice/index.js +13 -9
  182. package/dist/kbd/index.js +5 -1
  183. package/dist/keyboard/index.js +4 -2
  184. package/dist/list-row/index.js +6 -4
  185. package/dist/log-viewer/index.js +4 -2
  186. package/dist/map-view/index.js +5 -3
  187. package/dist/markdown/index.js +9 -6
  188. package/dist/metric/index.js +7 -4
  189. package/dist/money/index.js +9 -3
  190. package/dist/nav-drawer/index.js +4 -2
  191. package/dist/nav-header/index.js +9 -0
  192. package/dist/navigation/index.js +5 -2
  193. package/dist/notification-center/index.js +12 -10
  194. package/dist/number-roll/index.js +5 -2
  195. package/dist/one-handed/index.js +5 -3
  196. package/dist/os-surfaces/index.js +6 -3
  197. package/dist/otp/index.js +7 -4
  198. package/dist/page-header/index.js +1 -0
  199. package/dist/pagination/index.js +6 -0
  200. package/dist/payment-method/index.js +14 -10
  201. package/dist/payment-status/index.js +17 -14
  202. package/dist/permission/index.js +5 -2
  203. package/dist/picker/index.js +11 -6
  204. package/dist/progress/index.js +6 -3
  205. package/dist/pull-to-refresh/index.js +4 -2
  206. package/dist/radio-group/index.js +6 -4
  207. package/dist/rating/index.js +5 -2
  208. package/dist/receivables/index.js +21 -16
  209. package/dist/refund/index.js +18 -14
  210. package/dist/save-status/index.js +5 -3
  211. package/dist/scroll-area/index.js +3 -1
  212. package/dist/search-field/index.js +8 -0
  213. package/dist/segmented-control/index.js +4 -3
  214. package/dist/sheet/index.js +5 -3
  215. package/dist/skeleton/index.js +3 -1
  216. package/dist/slider/index.js +4 -2
  217. package/dist/sortable/index.js +7 -0
  218. package/dist/spinner/index.js +3 -1
  219. package/dist/split-button/index.js +9 -6
  220. package/dist/spotlight/index.js +3 -1
  221. package/dist/stage-timeline/index.js +5 -3
  222. package/dist/status-dot/index.js +4 -2
  223. package/dist/stepper/index.js +7 -4
  224. package/dist/streaming-text/index.js +3 -2
  225. package/dist/survey/index.js +18 -15
  226. package/dist/switch/index.js +5 -3
  227. package/dist/system-state/index.js +7 -4
  228. package/dist/tab-bar/index.js +5 -2
  229. package/dist/tabs/index.js +4 -2
  230. package/dist/tags-input/index.js +10 -0
  231. package/dist/textarea/index.js +6 -4
  232. package/dist/thinking/index.js +3 -1
  233. package/dist/time-field/index.js +12 -0
  234. package/dist/time-range-control/index.js +22 -0
  235. package/dist/timeline/index.js +4 -2
  236. package/dist/toast/index.js +4 -2
  237. package/dist/toolbar/index.js +4 -2
  238. package/dist/tour/index.js +12 -9
  239. package/dist/truncation-notice/index.js +5 -2
  240. package/dist/update-notice/index.js +12 -9
  241. package/dist/video-player/index.js +5 -2
  242. package/dist/viewfinder/index.js +6 -4
  243. package/dist/widget/index.js +7 -4
  244. package/dist/wizard/index.js +7 -4
  245. package/package.json +13 -12
  246. package/dist/chunk-6N33LFQA.js +0 -35
  247. package/dist/chunk-GDKZTW34.js +0 -395
  248. package/dist/chunk-GL7B2DOW.js +0 -134
  249. package/dist/chunk-NKB7BZYK.js +0 -167
  250. package/dist/chunk-OETCUXQP.js +0 -134
  251. package/dist/chunk-OPXFZ4Y5.js +0 -204
  252. package/dist/chunk-Q72LJOVE.js +0 -169
  253. package/dist/chunk-RNGLIHFA.js +0 -191
  254. package/dist/chunk-RQ3HASCC.js +0 -6
  255. package/dist/chunk-RSOJT5YW.js +0 -124
  256. package/dist/chunk-TKVFVF5D.js +0 -95
  257. package/dist/chunk-XOSCY2CW.js +0 -242
  258. package/dist/header/index.js +0 -5
  259. package/dist/search-bar/index.js +0 -5
  260. /package/dist/{chunk-3ECPOSKO.js → chunk-3UG6JUCV.js} +0 -0
  261. /package/dist/{chunk-JRLTGLN4.js → chunk-5WWRTEPS.js} +0 -0
  262. /package/dist/{chunk-RTIKSY6A.js → chunk-5Z5ZYMOJ.js} +0 -0
@@ -0,0 +1,211 @@
1
+ import { useLabels } from './chunk-APCWFOZW.js';
2
+ import { Icon } from './chunk-UXGIW7OK.js';
3
+ import { useResolvedMotion, springConfig } from './chunk-J64KGCGX.js';
4
+ import * as React from 'react';
5
+ import { Pressable, View, Text, Animated } from 'react-native';
6
+ import { Svg, Path } from 'react-native-svg';
7
+ import { icons, ICON_VIEWBOX } from '@btndprojects/loam-icons';
8
+ import { createStyleSheet, useStyles, useLoamTheme } from '@btndprojects/loam-theme-native';
9
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
10
+
11
+ var DEFAULT_LABELS = {
12
+ rating: "Rating",
13
+ readOnlyLabel: (name, value, max) => `${name}: ${value} out of ${max} stars`,
14
+ rate: (value, max) => `Rate ${value} of ${max}`,
15
+ readout: (value, max) => `${value} of ${max}`,
16
+ readoutWithCount: (value, max, count) => `${value} of ${max} \xB7 ${count} reviews`
17
+ };
18
+ var ICON_SIZE = { sm: 20, md: 26, lg: 34 };
19
+ var STAR_PATH = icons.star.flatMap((part) => part.t === "path" ? [part.d] : []).join(" ");
20
+ function toHalfStep(value) {
21
+ return Math.round(value * 2) / 2;
22
+ }
23
+ function Star({
24
+ fraction,
25
+ size,
26
+ delay = 0,
27
+ kick = 0,
28
+ animate = false
29
+ }) {
30
+ const theme = useLoamTheme("rating");
31
+ const { styles } = useStyles(starSheet);
32
+ const filled = Math.max(0, Math.min(1, fraction));
33
+ const grow = React.useRef(new Animated.Value(1)).current;
34
+ const pulse = React.useRef(new Animated.Value(1)).current;
35
+ const wasFilled = React.useRef(filled > 0);
36
+ React.useEffect(() => {
37
+ const was = wasFilled.current;
38
+ wasFilled.current = filled > 0;
39
+ if (!animate || was || filled === 0) return;
40
+ grow.setValue(0.5);
41
+ const a = Animated.sequence([
42
+ Animated.delay(delay),
43
+ Animated.spring(grow, { ...springConfig(theme, "fs"), toValue: 1, useNativeDriver: true })
44
+ ]);
45
+ a.start();
46
+ return () => a.stop();
47
+ }, [filled > 0]);
48
+ React.useEffect(() => {
49
+ if (!animate || !kick) return;
50
+ pulse.setValue(1.2);
51
+ Animated.spring(pulse, {
52
+ ...springConfig(theme, "fs"),
53
+ toValue: 1,
54
+ useNativeDriver: true
55
+ }).start();
56
+ }, [kick]);
57
+ return /* @__PURE__ */ jsxs(View, { style: { width: size, height: size }, children: [
58
+ /* @__PURE__ */ jsx(Icon, { name: "star", size, color: theme.color.text3 }),
59
+ filled > 0 ? /* @__PURE__ */ jsx(
60
+ Animated.View,
61
+ {
62
+ testID: "rating-star-fill",
63
+ style: [
64
+ styles.clip,
65
+ {
66
+ width: size * filled,
67
+ opacity: grow,
68
+ transform: [{ scale: Animated.multiply(grow, pulse) }]
69
+ }
70
+ ],
71
+ children: /* @__PURE__ */ jsx(View, { style: styles.paint, children: /* @__PURE__ */ jsx(Svg, { width: size, height: size, viewBox: ICON_VIEWBOX, children: /* @__PURE__ */ jsx(
72
+ Path,
73
+ {
74
+ d: STAR_PATH,
75
+ fill: theme.color.warn,
76
+ stroke: theme.color.warn,
77
+ strokeWidth: theme.borderWidth.thick,
78
+ strokeLinecap: "round",
79
+ strokeLinejoin: "round"
80
+ }
81
+ ) }) })
82
+ }
83
+ ) : null
84
+ ] });
85
+ }
86
+ function Rating({
87
+ value,
88
+ defaultValue = 0,
89
+ onValueChange,
90
+ max = 5,
91
+ size = "md",
92
+ readOnly = false,
93
+ accessibilityLabel: accessibilityLabelProp,
94
+ showValue = false,
95
+ count,
96
+ motion = "full",
97
+ labels: labelsProp
98
+ }) {
99
+ const { styles } = useStyles(sheet, { size });
100
+ const labels = useLabels("rating", DEFAULT_LABELS, labelsProp);
101
+ const accessibilityLabel = accessibilityLabelProp ?? labels.rating;
102
+ const theme = useLoamTheme("rating");
103
+ const iconSize = ICON_SIZE[size];
104
+ const starSlopY = Math.max(0, (theme.tapMin - (iconSize + theme.space.s1 * 2)) / 2);
105
+ const isControlled = value !== void 0;
106
+ const [internal, setInternal] = React.useState(defaultValue);
107
+ const current = isControlled ? value : internal;
108
+ const animate = useResolvedMotion(motion, "rating") === "full" && !readOnly;
109
+ const [chosen, setChosen] = React.useState({ index: -1, n: 0 });
110
+ const before = React.useRef(0);
111
+ const setValue = (next) => {
112
+ before.current = Math.ceil(current);
113
+ setChosen((c) => ({ index: next - 1, n: c.n + 1 }));
114
+ if (!isControlled) setInternal(next);
115
+ onValueChange?.(next);
116
+ };
117
+ const clamped = Math.max(0, Math.min(max, current));
118
+ const snapped = readOnly ? Math.round(clamped * 10) / 10 : toHalfStep(clamped);
119
+ const shown = Number.isInteger(snapped) ? String(snapped) : snapped.toFixed(1);
120
+ const label = readOnly ? labels.readOnlyLabel(accessibilityLabel, shown, max) : accessibilityLabel;
121
+ const readoutLabel = count !== void 0 ? labels.readoutWithCount(shown, max, count) : labels.readout(shown, max);
122
+ const stars = /* @__PURE__ */ jsx(Fragment, { children: Array.from({ length: max }, (_, i) => {
123
+ const starValue = i + 1;
124
+ const fraction = Math.max(0, Math.min(1, snapped - i));
125
+ return /* @__PURE__ */ jsx(
126
+ Pressable,
127
+ {
128
+ style: styles.star,
129
+ accessibilityRole: "button",
130
+ accessibilityLabel: labels.rate(starValue, max),
131
+ accessibilityState: { disabled: readOnly, selected: fraction >= 0.5 },
132
+ disabled: readOnly,
133
+ hitSlop: { top: starSlopY, bottom: starSlopY },
134
+ onPress: readOnly ? void 0 : () => setValue(starValue),
135
+ children: /* @__PURE__ */ jsx(
136
+ Star,
137
+ {
138
+ fraction,
139
+ size: iconSize,
140
+ animate,
141
+ delay: Math.min(Math.max(0, i - before.current), 8) * 30,
142
+ kick: chosen.index === i ? chosen.n : 0
143
+ }
144
+ )
145
+ },
146
+ i
147
+ );
148
+ }) });
149
+ return /* @__PURE__ */ jsxs(View, { style: styles.wrapper, children: [
150
+ readOnly ? (
151
+ // A display, not a control: one image-like stop that reads the score,
152
+ // instead of five disabled "Rate N of 5" buttons to swipe through
153
+ // (WCAG 4.1.2; VoiceOver/TalkBack would announce each as dimmed).
154
+ /* @__PURE__ */ jsx(View, { accessible: true, accessibilityRole: "image", accessibilityLabel: label, children: /* @__PURE__ */ jsx(
155
+ View,
156
+ {
157
+ style: styles.row,
158
+ accessibilityElementsHidden: true,
159
+ importantForAccessibility: "no-hide-descendants",
160
+ ...{ "aria-hidden": true },
161
+ children: stars
162
+ }
163
+ ) })
164
+ ) : /* @__PURE__ */ jsx(View, { style: styles.row, role: "group", accessibilityLabel: label, children: stars }),
165
+ showValue ? /* @__PURE__ */ jsx(Text, { testID: "rating-readout", style: styles.readout, children: readoutLabel }) : null
166
+ ] });
167
+ }
168
+ var sheet = createStyleSheet((theme) => ({
169
+ // Outer wrapper groups the star row with the optional readout.
170
+ wrapper: {
171
+ flexDirection: "row",
172
+ alignItems: "center",
173
+ gap: theme.space.s2
174
+ },
175
+ row: {
176
+ flexDirection: "row",
177
+ alignItems: "center",
178
+ variants: {
179
+ size: {
180
+ sm: { gap: theme.space.s1 },
181
+ md: { gap: theme.space.s1 },
182
+ lg: { gap: theme.space.s2 }
183
+ }
184
+ }
185
+ },
186
+ star: {
187
+ padding: theme.space.s1
188
+ },
189
+ // Companion readout — uses body/sm weight and text2 tone so it reads as
190
+ // secondary information alongside the star icons.
191
+ readout: {
192
+ fontFamily: theme.font.sans,
193
+ fontSize: theme.fontSize[14],
194
+ color: theme.color.text2
195
+ }
196
+ }));
197
+ var starSheet = createStyleSheet(() => ({
198
+ // `start` + `overflow: 'hidden'` is the clip: the painted star inside keeps its
199
+ // full width and is cropped to the fraction, from the leading edge either way
200
+ // round, so RTL needs no sign flip.
201
+ clip: {
202
+ position: "absolute",
203
+ top: 0,
204
+ bottom: 0,
205
+ start: 0,
206
+ overflow: "hidden"
207
+ },
208
+ paint: { position: "absolute", top: 0, start: 0 }
209
+ }));
210
+
211
+ export { Rating };
@@ -1,4 +1,5 @@
1
- import { Icon } from './chunk-TKVFVF5D.js';
1
+ import { useLabels } from './chunk-APCWFOZW.js';
2
+ import { Icon } from './chunk-UXGIW7OK.js';
2
3
  import * as React2 from 'react';
3
4
  import { Platform, Easing, Keyboard, Animated, View, Pressable, Text, useWindowDimensions, ScrollView } from 'react-native';
4
5
  import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
@@ -30,7 +31,7 @@ function keyboardEasing(easing, fallback) {
30
31
  }
31
32
  }
32
33
  function useKeyboardInset() {
33
- const theme = useLoamTheme();
34
+ const theme = useLoamTheme("keyboard");
34
35
  const enterDuration = theme.motion.enter.duration;
35
36
  const exitDuration = theme.motion.exit.duration;
36
37
  const [state, setState] = React2.useState(() => ({
@@ -62,7 +63,7 @@ function useKeyboardInset() {
62
63
  return state;
63
64
  }
64
65
  function useAnimatedKeyboardInset(extra = 0) {
65
- const theme = useLoamTheme();
66
+ const theme = useLoamTheme("keyboard");
66
67
  const state = useKeyboardInset();
67
68
  const inset = React2.useRef(new Animated.Value(0)).current;
68
69
  const fallbackCurve = state.visible ? theme.motion.enter.easing : theme.motion.exit.easing;
@@ -79,6 +80,11 @@ function useAnimatedKeyboardInset(extra = 0) {
79
80
  }, [inset, target, state.duration, state.easing, fallbackCurve]);
80
81
  return { inset, state };
81
82
  }
83
+ var DEFAULT_LABELS = {
84
+ done: "Done",
85
+ previous: "Previous field",
86
+ next: "Next field"
87
+ };
82
88
  var PREVIOUS_ICON = "arrow-up";
83
89
  var NEXT_ICON = "arrow-down";
84
90
  var ACCESSORY_NAV_MIN_FIELDS = 3;
@@ -125,14 +131,19 @@ function KeyboardAccessoryBar({
125
131
  onPrevious,
126
132
  onNext,
127
133
  onDone,
128
- doneLabel = "Done",
129
- previousLabel = "Previous field",
130
- nextLabel = "Next field",
134
+ doneLabel: doneLabelProp,
135
+ previousLabel: previousLabelProp,
136
+ nextLabel: nextLabelProp,
137
+ labels: labelsProp,
131
138
  children,
132
139
  sticky = false,
133
140
  style,
134
141
  testID
135
142
  }) {
143
+ const labels = useLabels("keyboard", DEFAULT_LABELS, labelsProp);
144
+ const doneLabel = doneLabelProp ?? labels.done;
145
+ const previousLabel = previousLabelProp ?? labels.previous;
146
+ const nextLabel = nextLabelProp ?? labels.next;
136
147
  const { styles } = useStyles(sheet);
137
148
  const showNav = navigable && (fieldCount == null || fieldCount > ACCESSORY_NAV_MIN_FIELDS);
138
149
  const bar = /* @__PURE__ */ jsxs(View, { accessibilityRole: "toolbar", style: [styles.accessoryBar, style], testID, children: [
@@ -176,7 +187,7 @@ function AccessoryButton({
176
187
  disabled,
177
188
  onPress
178
189
  }) {
179
- const theme = useLoamTheme();
190
+ const theme = useLoamTheme("keyboard");
180
191
  const { styles } = useStyles(sheet, { disabled });
181
192
  return /* @__PURE__ */ jsx(
182
193
  Pressable,
@@ -204,7 +215,7 @@ function KeyboardAvoidingScrollView({
204
215
  testID,
205
216
  ...rest
206
217
  }) {
207
- const theme = useLoamTheme();
218
+ const theme = useLoamTheme("keyboard");
208
219
  const inset = useKeyboardInset();
209
220
  const { height: windowHeight } = useWindowDimensions();
210
221
  const clearance = extraBottom ?? theme.layout.screenPad;
@@ -1,20 +1,29 @@
1
- import { useTourHost, useTourInsets, useAnchorRect, Beacon } from './chunk-JUAMLEHX.js';
2
- import { Icon } from './chunk-TKVFVF5D.js';
1
+ import { useTourHost, useTourInsets, useAnchorRect, Beacon } from './chunk-H7DWSL4O.js';
2
+ import { useLabels } from './chunk-APCWFOZW.js';
3
+ import { Icon } from './chunk-UXGIW7OK.js';
4
+ import { springConfig } from './chunk-J64KGCGX.js';
3
5
  import * as React from 'react';
4
- import { View, Pressable, Animated, Easing, Text, LayoutAnimation } from 'react-native';
6
+ import { View, Pressable, Animated, Easing, Text, Platform, findNodeHandle, AccessibilityInfo, LayoutAnimation } from 'react-native';
5
7
  import { createStyleSheet, useStyles, useLoamTheme } from '@btndprojects/loam-theme-native';
6
8
  import { resolveAnchoredPosition, centreInContainer } from '@btndprojects/loam-engage';
7
9
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
10
 
11
+ var DEFAULT_LABELS = {
12
+ dismiss: "Dismiss",
13
+ step: (step, title) => `Step ${step}${title ? `: ${title}` : ""}`
14
+ };
9
15
  function CoachmarkDots({
10
16
  total,
11
17
  index,
12
18
  onSelect,
13
- stepLabel = "Step",
14
- titles
19
+ stepLabel,
20
+ titles,
21
+ labels: labelsProp
15
22
  }) {
23
+ const labels = useLabels("coachmark", DEFAULT_LABELS, labelsProp);
16
24
  const { styles } = useStyles(sheet);
17
- const theme = useLoamTheme();
25
+ const theme = useLoamTheme("coachmark");
26
+ const dotSlopY = Math.max(0, Math.round((theme.tapMin - theme.space[7]) / 2));
18
27
  return /* @__PURE__ */ jsx(View, { style: styles.dots, children: Array.from({ length: total }, (_, i) => {
19
28
  const done = i < index;
20
29
  const now = i === index;
@@ -23,13 +32,19 @@ function CoachmarkDots({
23
32
  Pressable,
24
33
  {
25
34
  accessibilityRole: "button",
26
- accessibilityLabel: `${stepLabel} ${i + 1}${title ? `: ${title}` : ""}`,
35
+ accessibilityLabel: stepLabel !== void 0 ? `${stepLabel} ${i + 1}${title ? `: ${title}` : ""}` : labels.step(i + 1, title),
27
36
  accessibilityState: { selected: now, disabled: !done || !onSelect },
28
37
  disabled: !done || !onSelect,
29
38
  onPress: done && onSelect ? () => onSelect(i) : void 0,
30
- hitSlop: theme.space[10],
31
- style: [
39
+ hitSlop: {
40
+ top: dotSlopY,
41
+ bottom: dotSlopY,
42
+ left: theme.space[3],
43
+ right: theme.space[3]
44
+ },
45
+ style: ({ pressed }) => [
32
46
  styles.dot,
47
+ pressed ? { opacity: theme.state.pressedOpacity } : null,
33
48
  now ? { width: theme.space[20], backgroundColor: theme.color.accent } : { backgroundColor: done ? theme.color.text3 : theme.color.borderStrong }
34
49
  ]
35
50
  },
@@ -37,12 +52,15 @@ function CoachmarkDots({
37
52
  );
38
53
  }) });
39
54
  }
40
- function CoachmarkHint({ children, motion = "full" }) {
41
- const theme = useLoamTheme();
55
+ function CoachmarkHint({
56
+ children,
57
+ motion = "full"
58
+ }) {
59
+ const theme = useLoamTheme("coachmark");
42
60
  const { styles } = useStyles(sheet);
43
61
  const blink = React.useRef(new Animated.Value(1)).current;
44
62
  React.useEffect(() => {
45
- if (motion === "none") return;
63
+ if (motion === "none" || theme.reduceMotion) return;
46
64
  const loop = Animated.loop(
47
65
  Animated.sequence([
48
66
  Animated.timing(blink, {
@@ -61,7 +79,7 @@ function CoachmarkHint({ children, motion = "full" }) {
61
79
  );
62
80
  loop.start();
63
81
  return () => loop.stop();
64
- }, [motion, blink, theme.loop.pulse]);
82
+ }, [motion, blink, theme.loop.pulse, theme.reduceMotion]);
65
83
  return /* @__PURE__ */ jsxs(View, { accessibilityRole: "text", accessibilityLiveRegion: "polite", style: styles.hint, children: [
66
84
  /* @__PURE__ */ jsx(Animated.View, { style: [styles.hintDot, { opacity: blink }] }),
67
85
  /* @__PURE__ */ jsx(Text, { style: styles.hintText, children })
@@ -90,12 +108,14 @@ function Coachmark({
90
108
  actions,
91
109
  headerActions,
92
110
  onClose,
93
- closeLabel = "Dismiss",
111
+ closeLabel,
94
112
  arrow = true,
95
113
  width,
96
- motion = "full"
114
+ motion = "full",
115
+ labels: labelsProp
97
116
  }) {
98
- const theme = useLoamTheme();
117
+ const labels = useLabels("coachmark", DEFAULT_LABELS, labelsProp);
118
+ const theme = useLoamTheme("coachmark");
99
119
  const { styles } = useStyles(sheet);
100
120
  const host = useTourHost();
101
121
  const insets = useTourInsets();
@@ -104,17 +124,84 @@ function Coachmark({
104
124
  const [size, setSize] = React.useState(null);
105
125
  const fade = React.useRef(new Animated.Value(0)).current;
106
126
  const animate = motion === "full" && !theme.reduceMotion;
127
+ const grow = React.useRef(new Animated.Value(0)).current;
128
+ const visible = mode !== "anchored" || size !== null;
129
+ const cardRef = React.useRef(null);
130
+ const titleRef = React.useRef(null);
131
+ const titleId = React.useId();
132
+ React.useEffect(() => {
133
+ if (Platform.OS !== "web" || typeof document === "undefined") return;
134
+ const before = document.activeElement;
135
+ return () => {
136
+ if (before?.isConnected) before.focus?.();
137
+ };
138
+ }, []);
139
+ React.useEffect(() => {
140
+ if (!visible) return;
141
+ if (Platform.OS === "web") {
142
+ cardRef.current?.focus?.({ preventScroll: true });
143
+ return;
144
+ }
145
+ const node = findNodeHandle(titleRef.current ?? cardRef.current);
146
+ if (node != null) AccessibilityInfo.setAccessibilityFocus(node);
147
+ }, [visible, title]);
148
+ React.useEffect(() => {
149
+ if (Platform.OS !== "web" || !onClose || typeof document === "undefined") return;
150
+ const onKey = (e) => {
151
+ if (e.key === "Escape") onClose();
152
+ };
153
+ document.addEventListener("keydown", onKey);
154
+ return () => document.removeEventListener("keydown", onKey);
155
+ }, [onClose]);
156
+ const glide = React.useRef(new Animated.ValueXY({ x: 0, y: 0 })).current;
157
+ const glideNow = React.useRef({ x: 0, y: 0 });
158
+ React.useEffect(() => {
159
+ const id = glide.addListener((v) => {
160
+ glideNow.current = v;
161
+ });
162
+ return () => glide.removeListener(id);
163
+ }, [glide]);
164
+ const spot = mode === "anchored" && rect && size ? resolveAnchoredPosition(rect, size, placement, gap) : null;
165
+ const lastSpot = React.useRef(null);
107
166
  React.useEffect(() => {
167
+ if (!spot) return;
168
+ const last = lastSpot.current;
169
+ lastSpot.current = { left: spot.left, top: spot.top };
170
+ if (!last || !animate || last.left === spot.left && last.top === spot.top) return;
171
+ glide.stopAnimation();
172
+ glide.setValue({
173
+ x: last.left + glideNow.current.x - spot.left,
174
+ y: last.top + glideNow.current.y - spot.top
175
+ });
176
+ Animated.spring(glide, {
177
+ ...springConfig(theme, "ds"),
178
+ toValue: { x: 0, y: 0 },
179
+ useNativeDriver: true
180
+ }).start();
181
+ }, [spot?.left, spot?.top, animate, glide, theme]);
182
+ React.useEffect(() => {
183
+ if (!visible) return;
108
184
  Animated.timing(fade, {
109
185
  toValue: 1,
110
- duration: animate ? theme.motion.enter.duration : 0,
186
+ duration: animate ? theme.spring.de.duration : theme.reduceMotion ? theme.duration.fast : 0,
111
187
  easing: Easing.bezier(...theme.motion.enter.easing),
112
188
  useNativeDriver: true
113
189
  }).start();
114
- }, [fade, animate, theme.motion.enter]);
190
+ if (animate) {
191
+ Animated.spring(grow, {
192
+ ...springConfig(theme, "fs"),
193
+ toValue: 1,
194
+ useNativeDriver: true
195
+ }).start();
196
+ } else {
197
+ grow.setValue(1);
198
+ }
199
+ }, [fade, grow, animate, visible, theme]);
115
200
  const onLayout = (e) => {
116
201
  const next = { width: e.nativeEvent.layout.width, height: e.nativeEvent.layout.height };
117
- setSize((prev) => prev && prev.width === next.width && prev.height === next.height ? prev : next);
202
+ setSize(
203
+ (prev) => prev && prev.width === next.width && prev.height === next.height ? prev : next
204
+ );
118
205
  };
119
206
  const hostWidth = host?.size.current?.width ?? 0;
120
207
  const requested = width ?? theme.panel.lg;
@@ -154,14 +241,58 @@ function Coachmark({
154
241
  bottom: theme.space[14] + insets.bottom
155
242
  };
156
243
  }
244
+ const facing = mode === "anchored" && placed ? placed.side : mode === "docked" ? "top" : null;
245
+ const START = 0.92;
246
+ const enterTransform = animate && size ? {
247
+ transform: [
248
+ ...facing === "bottom" || facing === "top" ? [
249
+ {
250
+ translateY: grow.interpolate({
251
+ inputRange: [0, 1],
252
+ outputRange: [
253
+ (facing === "bottom" ? -1 : 1) * (1 - START) * size.height / 2,
254
+ 0
255
+ ]
256
+ })
257
+ }
258
+ ] : facing === "left" || facing === "right" ? [
259
+ {
260
+ translateX: grow.interpolate({
261
+ inputRange: [0, 1],
262
+ outputRange: [
263
+ (facing === "right" ? -1 : 1) * (1 - START) * size.width / 2,
264
+ 0
265
+ ]
266
+ })
267
+ }
268
+ ] : [],
269
+ { scale: grow.interpolate({ inputRange: [0, 1], outputRange: [START, 1] }) },
270
+ { translateX: glide.x },
271
+ { translateY: glide.y }
272
+ ]
273
+ } : void 0;
157
274
  return /* @__PURE__ */ jsxs(
158
275
  Animated.View,
159
276
  {
160
- accessibilityRole: "alert",
277
+ ref: cardRef,
161
278
  accessibilityViewIsModal: false,
162
- accessibilityLabel: title,
279
+ accessibilityActions: onClose ? [{ name: "escape" }] : void 0,
280
+ onAccessibilityAction: (e) => {
281
+ if (e.nativeEvent.actionName === "escape") onClose?.();
282
+ },
283
+ ...Platform.OS === "web" ? {
284
+ role: "dialog",
285
+ "aria-modal": false,
286
+ "aria-labelledby": title ? titleId : void 0,
287
+ tabIndex: -1
288
+ } : null,
163
289
  onLayout,
164
- style: [styles.card, position, { opacity: position?.opacity === 0 ? 0 : fade }],
290
+ style: [
291
+ styles.card,
292
+ position,
293
+ { opacity: position?.opacity === 0 ? 0 : fade },
294
+ enterTransform
295
+ ],
165
296
  children: [
166
297
  mode === "anchored" && arrow && placed?.measured ? /* @__PURE__ */ jsx(CoachmarkArrow, { side: placed.side, offset: placed.arrowOffset }) : null,
167
298
  kicker || counter || headerActions || onClose ? /* @__PURE__ */ jsxs(View, { style: styles.header, children: [
@@ -172,21 +303,34 @@ function Coachmark({
172
303
  Pressable,
173
304
  {
174
305
  accessibilityRole: "button",
175
- accessibilityLabel: closeLabel,
306
+ accessibilityLabel: closeLabel ?? labels.dismiss,
176
307
  onPress: onClose,
177
308
  hitSlop: theme.space[10],
178
- style: [styles.iconButton, !kicker && !counter && !headerActions ? styles.pushEnd : null],
309
+ style: ({ pressed }) => [
310
+ styles.iconButton,
311
+ !kicker && !counter && !headerActions ? styles.pushEnd : null,
312
+ pressed ? { opacity: theme.state.pressedOpacity } : null
313
+ ],
179
314
  children: /* @__PURE__ */ jsx(Icon, { name: "x", size: theme.icon.sm, color: theme.color.text3 })
180
315
  }
181
316
  ) : null
182
317
  ] }) : null,
183
- title ? /* @__PURE__ */ jsx(Text, { style: styles.title, children: title }) : null,
318
+ title ? /* @__PURE__ */ jsx(
319
+ Text,
320
+ {
321
+ ref: titleRef,
322
+ nativeID: titleId,
323
+ accessibilityRole: "header",
324
+ style: styles.title,
325
+ children: title
326
+ }
327
+ ) : null,
184
328
  body ? /* @__PURE__ */ jsx(Text, { style: styles.body, children: body }) : null,
185
329
  media,
186
330
  children,
187
331
  hint ? /* @__PURE__ */ jsx(CoachmarkHint, { motion, children: hint }) : null,
188
332
  dots || actions ? /* @__PURE__ */ jsxs(View, { style: styles.footer, children: [
189
- dots ? /* @__PURE__ */ jsx(CoachmarkDots, { ...dots }) : null,
333
+ dots ? /* @__PURE__ */ jsx(CoachmarkDots, { labels: labelsProp, ...dots }) : null,
190
334
  /* @__PURE__ */ jsx(View, { style: [styles.footerActions, dots ? styles.pushEnd : styles.pushEnd], children: actions })
191
335
  ] }) : null
192
336
  ]
@@ -206,9 +350,10 @@ function Hotspot({
206
350
  defaultOpen = false,
207
351
  onOpenChange,
208
352
  onSpent,
209
- motion = "full"
353
+ motion = "full",
354
+ labels
210
355
  }) {
211
- const theme = useLoamTheme();
356
+ const theme = useLoamTheme("coachmark");
212
357
  const [uncontrolled, setUncontrolled] = React.useState(defaultOpen);
213
358
  const open = openProp ?? uncontrolled;
214
359
  const [opened, setOpened] = React.useState(defaultOpen);
@@ -243,7 +388,8 @@ function Hotspot({
243
388
  body,
244
389
  motion,
245
390
  onClose: () => setOpen(false),
246
- actions: action
391
+ actions: action,
392
+ labels
247
393
  }
248
394
  ) : null
249
395
  ] });
@@ -329,7 +475,12 @@ var sheet = createStyleSheet((theme) => ({
329
475
  textTransform: "uppercase",
330
476
  color: theme.color.accentOnSoft
331
477
  },
332
- footer: { flexDirection: "row", alignItems: "center", gap: theme.space[8], marginTop: theme.space[2] },
478
+ footer: {
479
+ flexDirection: "row",
480
+ alignItems: "center",
481
+ gap: theme.space[8],
482
+ marginTop: theme.space[2]
483
+ },
333
484
  footerActions: { flexDirection: "row", alignItems: "center", gap: theme.space[8] },
334
485
  dots: { flexDirection: "row", alignItems: "center", gap: theme.space[6] },
335
486
  dot: { width: theme.space[7], height: theme.space[7], borderRadius: theme.radius.full }