@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
@@ -1,13 +1,20 @@
1
1
  import { haptics } from './chunk-NY2U3PBI.js';
2
- import { Icon } from './chunk-TKVFVF5D.js';
2
+ import { useLabels } from './chunk-APCWFOZW.js';
3
+ import { Icon } from './chunk-UXGIW7OK.js';
3
4
  import * as React from 'react';
4
5
  import { Animated, AccessibilityInfo, Easing, Pressable, Text } from 'react-native';
5
6
  import { createStyleSheet, useStyles, useLoamTheme } from '@btndprojects/loam-theme-native';
6
7
  import { jsxs, jsx } from 'react/jsx-runtime';
7
8
 
8
9
  var DEFAULT_DURATION = 1200;
10
+ var DEFAULT_LABELS = {
11
+ hint: "Press and hold to confirm. Releasing early cancels.",
12
+ confirmed: "Confirmed",
13
+ holding: "Keep holding to confirm",
14
+ cancelled: "Cancelled"
15
+ };
9
16
  function useForeground(variant, disabled) {
10
- const theme = useLoamTheme();
17
+ const theme = useLoamTheme("hold-to-confirm");
11
18
  if (disabled) return theme.color.text3;
12
19
  return variant === "primary" ? theme.color.accentInk : theme.color.dangerInk;
13
20
  }
@@ -23,10 +30,12 @@ function HoldToConfirm({
23
30
  leadingIcon,
24
31
  motion = "full",
25
32
  accessibilityLabel,
26
- onProgress
33
+ onProgress,
34
+ labels: labelsProp
27
35
  }) {
36
+ const labels = useLabels("holdToConfirm", DEFAULT_LABELS, labelsProp);
28
37
  const { styles } = useStyles(sheet, { variant, size, disabled, fullWidth });
29
- const theme = useLoamTheme();
38
+ const theme = useLoamTheme("hold-to-confirm");
30
39
  const fg = useForeground(variant, disabled);
31
40
  const iconSize = theme.ctl.icon[size];
32
41
  const slopY = Math.max(0, (theme.hit[size] - theme.ctl[size]) / 2);
@@ -60,14 +69,14 @@ function HoldToConfirm({
60
69
  const fireConfirm = React.useCallback(() => {
61
70
  clear();
62
71
  setHolding(false);
63
- setMessage("Confirmed");
72
+ setMessage(labels.confirmed);
64
73
  haptics.impact("heavy");
65
74
  onConfirm();
66
- }, [clear, onConfirm]);
75
+ }, [clear, onConfirm, labels.confirmed]);
67
76
  const start = React.useCallback(() => {
68
77
  if (disabled || timer.current !== void 0) return;
69
78
  setHolding(true);
70
- setMessage("Keep holding to confirm");
79
+ setMessage(labels.holding);
71
80
  progress.stopAnimation();
72
81
  progress.setValue(0);
73
82
  Animated.timing(progress, {
@@ -80,7 +89,7 @@ function HoldToConfirm({
80
89
  Animated.spring(scale, { toValue: 0.97, useNativeDriver: true, speed: 40, bounciness: 6 }).start();
81
90
  }
82
91
  timer.current = setTimeout(fireConfirm, duration);
83
- }, [disabled, duration, motion, progress, scale, fireConfirm]);
92
+ }, [disabled, duration, motion, progress, scale, fireConfirm, labels.holding]);
84
93
  const cancel = React.useCallback(() => {
85
94
  if (motion === "full") {
86
95
  Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 6 }).start();
@@ -88,7 +97,7 @@ function HoldToConfirm({
88
97
  if (timer.current === void 0) return;
89
98
  clear();
90
99
  setHolding(false);
91
- setMessage("Cancelled");
100
+ setMessage(labels.cancelled);
92
101
  progress.stopAnimation();
93
102
  Animated.timing(progress, {
94
103
  toValue: 0,
@@ -96,7 +105,7 @@ function HoldToConfirm({
96
105
  easing: Easing.bezier(...theme.motion.exit.easing),
97
106
  useNativeDriver: false
98
107
  }).start();
99
- }, [clear, motion, progress, scale, theme.motion.exit]);
108
+ }, [clear, motion, progress, scale, theme.motion.exit, labels.cancelled]);
100
109
  React.useEffect(() => clear, [clear]);
101
110
  const width = progress.interpolate({ inputRange: [0, 1], outputRange: ["0%", "100%"] });
102
111
  const label = holding && confirmingLabel ? confirmingLabel : children;
@@ -106,7 +115,7 @@ function HoldToConfirm({
106
115
  {
107
116
  accessibilityRole: "button",
108
117
  accessibilityLabel: a11yLabel,
109
- accessibilityHint: "Press and hold to confirm. Releasing early cancels.",
118
+ accessibilityHint: labels.hint,
110
119
  accessibilityState: { disabled },
111
120
  disabled,
112
121
  onPress: disabled || !srEnabled ? void 0 : fireConfirm,
@@ -174,13 +183,16 @@ var sheet = createStyleSheet((theme) => ({
174
183
  fullWidth: { true: { alignSelf: "stretch" }, false: {} }
175
184
  }
176
185
  },
177
- // Translucent state-layer fill, anchored to the start edge, behind the label.
186
+ // Darkening fill, anchored to the start edge, behind the label. A state-layer
187
+ // tint (~10%) vanishes on a saturated danger/accent fill; the scrim at 70%
188
+ // reads clearly in both themes while keeping the on-ink label legible.
178
189
  fill: {
179
190
  position: "absolute",
180
191
  top: 0,
181
192
  bottom: 0,
182
193
  start: 0,
183
- backgroundColor: theme.state.pressed
194
+ backgroundColor: theme.color.scrim,
195
+ opacity: theme.opacity[72]
184
196
  },
185
197
  label: {
186
198
  fontFamily: theme.font.sans,
@@ -1,9 +1,12 @@
1
- import { Thinking } from './chunk-XXXEFXY5.js';
2
- import { Spinner } from './chunk-O7AE6DAF.js';
3
- import { Icon } from './chunk-TKVFVF5D.js';
1
+ import { Thinking } from './chunk-W74TXYFB.js';
2
+ import { Spinner } from './chunk-KQZ3GLHR.js';
3
+ import { useLabels } from './chunk-APCWFOZW.js';
4
+ import { Icon } from './chunk-UXGIW7OK.js';
5
+ import { useResolvedMotion, springConfig } from './chunk-J64KGCGX.js';
4
6
  import * as React from 'react';
5
- import { StyleSheet, View, Text, Pressable } from 'react-native';
7
+ import { StyleSheet, View, Text, Pressable, Animated } from 'react-native';
6
8
  import { createStyleSheet, useStyles, useLoamTheme } from '@btndprojects/loam-theme-native';
9
+ import { MOTION_MOVE } from '@btndprojects/loam-tokens';
7
10
  import { jsxs, jsx } from 'react/jsx-runtime';
8
11
 
9
12
  var SYSTEM_STATE_META = {
@@ -13,8 +16,13 @@ var SYSTEM_STATE_META = {
13
16
  maintenance: { tone: "warn", icon: "wrench", code: "Soon" },
14
17
  offline: { tone: "info", icon: "wifi-off", code: "Offline" }
15
18
  };
19
+ var DEFAULT_LABELS = {
20
+ copyErrorId: (id) => `Copy error id ${id}`,
21
+ soon: "Soon",
22
+ offline: "Offline"
23
+ };
16
24
  function useTone(tone) {
17
- const theme = useLoamTheme();
25
+ const theme = useLoamTheme("system-state");
18
26
  switch (tone) {
19
27
  case "danger":
20
28
  return theme.color.dangerOnSoft;
@@ -37,11 +45,14 @@ function SystemState({
37
45
  secondaryLabel,
38
46
  onSecondary,
39
47
  errorId,
40
- onCopyErrorId
48
+ onCopyErrorId,
49
+ labels: labelsProp
41
50
  }) {
51
+ const labels = useLabels("systemState", DEFAULT_LABELS, labelsProp);
42
52
  const meta = SYSTEM_STATE_META[variant];
53
+ const variantCode = variant === "maintenance" ? labels.soon : variant === "offline" ? labels.offline : meta.code;
43
54
  const { styles } = useStyles(sheet, { tone: meta.tone });
44
- const theme = useLoamTheme();
55
+ const theme = useLoamTheme("system-state");
45
56
  const tone = useTone(meta.tone);
46
57
  if (process.env.NODE_ENV !== "production" && !primaryLabel && !secondaryLabel) {
47
58
  console.warn(
@@ -51,14 +62,14 @@ function SystemState({
51
62
  return /* @__PURE__ */ jsxs(View, { style: styles.base, accessibilityRole: "alert", children: [
52
63
  /* @__PURE__ */ jsxs(View, { style: styles.body, children: [
53
64
  /* @__PURE__ */ jsx(View, { style: styles.tile, children: /* @__PURE__ */ jsx(Icon, { name: icon ?? meta.icon, size: theme.icon.xl, color: tone }) }),
54
- /* @__PURE__ */ jsx(Text, { style: [styles.code, { color: tone }], children: code ?? meta.code }),
65
+ /* @__PURE__ */ jsx(Text, { style: [styles.code, { color: tone }], children: code ?? variantCode }),
55
66
  /* @__PURE__ */ jsx(Text, { style: styles.title, children: title }),
56
67
  description ? /* @__PURE__ */ jsx(Text, { style: styles.description, children: description }) : null,
57
68
  errorId ? /* @__PURE__ */ jsxs(
58
69
  Pressable,
59
70
  {
60
71
  accessibilityRole: "button",
61
- accessibilityLabel: `Copy error id ${errorId}`,
72
+ accessibilityLabel: labels.copyErrorId(errorId),
62
73
  onPress: onCopyErrorId ? () => onCopyErrorId(errorId) : void 0,
63
74
  style: ({ pressed }) => [styles.errorChip, pressed && styles.pressed],
64
75
  children: [
@@ -244,29 +255,45 @@ function useLate(active, after) {
244
255
  }, [active, after]);
245
256
  return late;
246
257
  }
258
+ var AREA_DEFAULT_LABELS = {
259
+ loading: "Loading",
260
+ late: "Still working\u2026",
261
+ errorTitle: "Couldn\u2019t load this",
262
+ retry: "Try again",
263
+ refresh: "Refresh",
264
+ refreshing: (refresh) => `${refresh}\u2026`,
265
+ empty: "Nothing here yet."
266
+ };
247
267
  function AreaState({
248
268
  state = "idle",
249
269
  children,
250
270
  minHeight = 160,
251
271
  loadingContent,
252
- loadingLabel = "Loading",
253
- lateLabel = "Still working\u2026",
272
+ loadingLabel: loadingLabelProp,
273
+ lateLabel: lateLabelProp,
254
274
  loadingFloor,
255
275
  lateAfter,
256
276
  empty,
257
277
  error,
258
- errorTitle = "Couldn\u2019t load this",
278
+ errorTitle: errorTitleProp,
259
279
  errorDescription,
260
- retryLabel = "Try again",
280
+ retryLabel: retryLabelProp,
261
281
  onRetry,
262
282
  staleLabel,
263
- refreshLabel = "Refresh",
283
+ refreshLabel: refreshLabelProp,
264
284
  onRefresh,
265
285
  refreshing = false,
266
286
  idle,
267
- motion = "full"
287
+ motion = "full",
288
+ labels: labelsProp
268
289
  }) {
269
- const theme = useLoamTheme();
290
+ const theme = useLoamTheme("system-state");
291
+ const labels = useLabels("areaState", AREA_DEFAULT_LABELS, labelsProp);
292
+ const loadingLabel = loadingLabelProp ?? labels.loading;
293
+ const lateLabel = lateLabelProp ?? labels.late;
294
+ const errorTitle = errorTitleProp ?? labels.errorTitle;
295
+ const retryLabel = retryLabelProp ?? labels.retry;
296
+ const refreshLabel = refreshLabelProp ?? labels.refresh;
270
297
  const { styles } = useStyles(areaSheet);
271
298
  const floor = loadingFloor ?? theme.timing.loadingFloor;
272
299
  const lateMs = lateAfter ?? theme.timing.lateAfter;
@@ -274,6 +301,32 @@ function AreaState({
274
301
  const showLoading = useLoadingFloor(isLoading, floor);
275
302
  const late = useLate(isLoading, lateMs);
276
303
  const busy = isLoading || showLoading;
304
+ const level = useResolvedMotion(motion, "system-state");
305
+ const phase = showLoading ? "loading" : state === "stale" ? "ready" : state;
306
+ const shownPhase = React.useRef(phase);
307
+ const through = React.useRef(new Animated.Value(1)).current;
308
+ React.useEffect(() => {
309
+ if (shownPhase.current === phase) return;
310
+ shownPhase.current = phase;
311
+ if (level === "none") return;
312
+ through.setValue(0);
313
+ Animated.spring(through, {
314
+ ...springConfig(theme, "de"),
315
+ toValue: 1,
316
+ useNativeDriver: true
317
+ }).start();
318
+ }, [phase, level, through, theme]);
319
+ const throughStyle = {
320
+ opacity: through,
321
+ transform: level === "full" ? [
322
+ {
323
+ scale: through.interpolate({
324
+ inputRange: [0, 1],
325
+ outputRange: [1 - MOTION_MOVE.scaleIn, 1]
326
+ })
327
+ }
328
+ ] : []
329
+ };
277
330
  const loadingView = /* @__PURE__ */ jsxs(View, { style: styles.center, children: [
278
331
  loadingContent ?? /* @__PURE__ */ jsx(Spinner, { size: "lg", accessibilityLabel: loadingLabel, motion }),
279
332
  late ? (
@@ -310,7 +363,7 @@ function AreaState({
310
363
  body = /* @__PURE__ */ jsx(View, { style: styles.fill });
311
364
  break;
312
365
  case "empty":
313
- body = empty ?? /* @__PURE__ */ jsx(View, { style: styles.center, children: /* @__PURE__ */ jsx(Text, { style: styles.errorBody, children: "Nothing here yet." }) });
366
+ body = empty ?? /* @__PURE__ */ jsx(View, { style: styles.center, children: /* @__PURE__ */ jsx(Text, { style: styles.errorBody, children: labels.empty }) });
314
367
  break;
315
368
  case "error":
316
369
  body = errorView;
@@ -333,13 +386,13 @@ function AreaState({
333
386
  Pressable,
334
387
  {
335
388
  accessibilityRole: "button",
336
- accessibilityLabel: refreshing ? `${refreshLabel}\u2026` : refreshLabel,
389
+ accessibilityLabel: refreshing ? labels.refreshing(refreshLabel) : refreshLabel,
337
390
  accessibilityState: { busy: refreshing, disabled: refreshing },
338
391
  disabled: refreshing,
339
392
  onPress: refreshing ? void 0 : onRefresh,
340
393
  style: ({ pressed }) => [styles.refresh, pressed && styles.pressed],
341
394
  children: [
342
- refreshing ? /* @__PURE__ */ jsx(Spinner, { size: "sm", accessibilityLabel: `${refreshLabel}\u2026` }) : /* @__PURE__ */ jsx(Icon, { name: "refresh", size: theme.icon.xs, color: theme.color.text }),
395
+ refreshing ? /* @__PURE__ */ jsx(Spinner, { size: "sm", accessibilityLabel: labels.refreshing(refreshLabel) }) : /* @__PURE__ */ jsx(Icon, { name: "refresh", size: theme.icon.xs, color: theme.color.text }),
343
396
  /* @__PURE__ */ jsx(Text, { style: styles.refreshLabel, children: refreshLabel })
344
397
  ]
345
398
  }
@@ -364,7 +417,7 @@ function AreaState({
364
417
  "aria-busy": busy,
365
418
  accessibilityState: { busy },
366
419
  ...{ "aria-live": "polite" },
367
- children: body
420
+ children: /* @__PURE__ */ jsx(Animated.View, { style: [styles.fill, throughStyle], children: body })
368
421
  }
369
422
  );
370
423
  }
@@ -1,10 +1,15 @@
1
- import { NODE_STATE_ICON } from './chunk-YLLCXTMC.js';
2
- import { Icon } from './chunk-TKVFVF5D.js';
1
+ import { NODE_STATE_WORD, NODE_STATE_ICON } from './chunk-YLLCXTMC.js';
2
+ import { useLabels } from './chunk-APCWFOZW.js';
3
+ import { Icon } from './chunk-UXGIW7OK.js';
3
4
  import * as React from 'react';
4
5
  import { View, Animated, Text, Easing } from 'react-native';
5
6
  import { createStyleSheet, useStyles, useLoamTheme } from '@btndprojects/loam-theme-native';
6
7
  import { jsx, jsxs } from 'react/jsx-runtime';
7
8
 
9
+ var DEFAULT_LABELS = {
10
+ states: { ...NODE_STATE_WORD },
11
+ latest: (count) => `${count} new`
12
+ };
8
13
  function toneSkin(theme, tone) {
9
14
  switch (tone) {
10
15
  case "accent":
@@ -52,9 +57,10 @@ function TimelineItem({
52
57
  isLast = true,
53
58
  animatedStyle
54
59
  }) {
55
- const { density } = React.useContext(TimelineContext);
60
+ const { density, labels: ctxLabels } = React.useContext(TimelineContext);
61
+ const labels = useLabels("timeline", DEFAULT_LABELS, ctxLabels);
56
62
  const { styles } = useStyles(sheet, { density });
57
- const theme = useLoamTheme();
63
+ const theme = useLoamTheme("timeline");
58
64
  const g = GEOMETRY[density];
59
65
  const nodeIcon = icon ?? (state ? NODE_STATE_ICON[state] : void 0);
60
66
  const skin = tone ? toneSkin(theme, tone) : state ? {
@@ -72,6 +78,9 @@ function TimelineItem({
72
78
  View,
73
79
  {
74
80
  testID: state ? `timeline-node-${state}` : `timeline-node-tone-${tone}`,
81
+ accessible: state ? true : void 0,
82
+ role: state ? "img" : void 0,
83
+ accessibilityLabel: state ? labels.states[state] : void 0,
75
84
  style: {
76
85
  width: g.node,
77
86
  height: g.node,
@@ -134,11 +143,12 @@ function Timeline({
134
143
  density = "comfortable",
135
144
  motion = "none",
136
145
  label,
146
+ labels,
137
147
  style,
138
148
  children
139
149
  }) {
140
150
  const { styles } = useStyles(sheet, { density });
141
- const theme = useLoamTheme();
151
+ const theme = useLoamTheme("timeline");
142
152
  const staggered = motion === "full" && !theme.reduceMotion;
143
153
  const childArray = items ? null : React.Children.toArray(children).filter(React.isValidElement);
144
154
  const count = items ? items.length : childArray?.length ?? 0;
@@ -150,7 +160,7 @@ function Timeline({
150
160
  );
151
161
  }
152
162
  const values = valuesRef.current;
153
- const ctx = React.useMemo(() => ({ density }), [density]);
163
+ const ctx = React.useMemo(() => ({ density, labels }), [density, labels]);
154
164
  React.useEffect(() => {
155
165
  if (!staggered) {
156
166
  values.forEach((v) => v.setValue(1));
@@ -0,0 +1,24 @@
1
+ // src/lib/storage.ts
2
+ function storageKey(component, id, version = 1) {
3
+ return `loam.${component}.${id}.v${version}`;
4
+ }
5
+ function readStored(storage, key) {
6
+ if (!storage) return null;
7
+ try {
8
+ const raw = storage.getItem(key);
9
+ if (!raw) return null;
10
+ const parsed = JSON.parse(raw);
11
+ return parsed && typeof parsed === "object" ? parsed : null;
12
+ } catch {
13
+ return null;
14
+ }
15
+ }
16
+ function writeStored(storage, key, value) {
17
+ if (!storage) return;
18
+ try {
19
+ storage.setItem(key, JSON.stringify(value));
20
+ } catch {
21
+ }
22
+ }
23
+
24
+ export { readStored, storageKey, writeStored };
@@ -1,17 +1,18 @@
1
- import { SearchExpand } from './chunk-47FWHGUN.js';
2
- import { Icon } from './chunk-TKVFVF5D.js';
3
- import 'react';
4
- import { Pressable, View, Text } from 'react-native';
1
+ import { ExpandingSearchField } from './chunk-DVGBZ3TX.js';
2
+ import { useLabels } from './chunk-APCWFOZW.js';
3
+ import { Icon } from './chunk-UXGIW7OK.js';
4
+ import * as React from 'react';
5
+ import { Pressable, View, Animated, Text } from 'react-native';
5
6
  import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
6
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
8
 
8
- function HeaderAction({
9
+ function NavHeaderAction({
9
10
  icon,
10
11
  accessibilityLabel,
11
12
  onPress,
12
13
  disabled = false
13
14
  }) {
14
- const theme = useLoamTheme();
15
+ const theme = useLoamTheme("nav-header");
15
16
  const { styles } = useStyles(sheet, { align: "left", large: false });
16
17
  const color = disabled ? theme.color.text3 : theme.color.text;
17
18
  return /* @__PURE__ */ jsx(
@@ -27,48 +28,100 @@ function HeaderAction({
27
28
  }
28
29
  );
29
30
  }
30
- function Header({
31
+ var DEFAULT_LABELS = {
32
+ back: "Back"
33
+ };
34
+ var STRETCH = 1.06;
35
+ var SHRINK = 0.9;
36
+ function NavHeader({
31
37
  title,
32
38
  subtitle,
33
39
  leading,
34
- leadingLabel = "Back",
40
+ leadingLabel,
35
41
  onLeadingPress,
36
42
  leadingSlot,
37
43
  trailing,
38
44
  align = "left",
39
45
  large = false,
40
46
  search = false,
41
- searchPlaceholder = "Search",
47
+ searchPlaceholder,
48
+ labels: labelsProp,
42
49
  searchRecents = [],
43
50
  searchValue,
44
51
  onSearchChangeText,
45
52
  onSearchCancel,
46
- searchSlot
53
+ searchSlot,
54
+ scrollY
47
55
  }) {
56
+ const labels = useLabels("navHeader", DEFAULT_LABELS, labelsProp);
48
57
  const { styles } = useStyles(sheet, { align, large });
58
+ const theme = useLoamTheme("nav-header");
49
59
  const showSearch = search || searchSlot != null;
60
+ const collapsing = large && scrollY != null;
61
+ const [span, setSpan] = React.useState(theme.space[48]);
62
+ const largeStyle = collapsing ? {
63
+ opacity: scrollY.interpolate({
64
+ inputRange: [0, span * 0.6],
65
+ outputRange: [1, 0],
66
+ extrapolate: "clamp"
67
+ }),
68
+ transform: [
69
+ {
70
+ scale: scrollY.interpolate({
71
+ inputRange: [-span, 0, span],
72
+ outputRange: [STRETCH, 1, SHRINK],
73
+ extrapolate: "clamp"
74
+ })
75
+ }
76
+ ],
77
+ transformOrigin: "left center"
78
+ } : null;
79
+ const inlineStyle = collapsing ? {
80
+ opacity: scrollY.interpolate({
81
+ inputRange: [span * 0.5, span],
82
+ outputRange: [0, 1],
83
+ extrapolate: "clamp"
84
+ })
85
+ } : null;
50
86
  return /* @__PURE__ */ jsxs(View, { accessibilityRole: "header", style: styles.container, children: [
51
87
  /* @__PURE__ */ jsxs(View, { style: styles.bar, children: [
52
88
  /* @__PURE__ */ jsx(View, { style: styles.leftSide, children: leadingSlot != null ? leadingSlot : leading ? /* @__PURE__ */ jsx(
53
- HeaderAction,
89
+ NavHeaderAction,
54
90
  {
55
91
  icon: leading,
56
- accessibilityLabel: leadingLabel,
92
+ accessibilityLabel: leadingLabel ?? labels.back,
57
93
  onPress: onLeadingPress
58
94
  }
59
95
  ) : null }),
60
- /* @__PURE__ */ jsx(View, { style: styles.titleWrap, children: large ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
96
+ /* @__PURE__ */ jsx(View, { style: styles.titleWrap, children: collapsing ? /* @__PURE__ */ jsx(
97
+ Animated.Text,
98
+ {
99
+ numberOfLines: 1,
100
+ style: [styles.title, inlineStyle],
101
+ "aria-hidden": true,
102
+ accessibilityElementsHidden: true,
103
+ importantForAccessibility: "no-hide-descendants",
104
+ children: title
105
+ }
106
+ ) : large ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
61
107
  /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.title, children: title }),
62
108
  subtitle ? /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.subtitle, children: subtitle }) : null
63
109
  ] }) }),
64
110
  /* @__PURE__ */ jsx(View, { style: styles.rightSide, children: trailing })
65
111
  ] }),
66
- large ? /* @__PURE__ */ jsxs(View, { style: styles.largeBlock, children: [
67
- /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.largeTitle, children: title }),
68
- subtitle ? /* @__PURE__ */ jsx(Text, { style: styles.largeSubtitle, children: subtitle }) : null
69
- ] }) : null,
112
+ large ? /* @__PURE__ */ jsxs(
113
+ View,
114
+ {
115
+ style: styles.largeBlock,
116
+ onLayout: (e) => setSpan(Math.max(1, e.nativeEvent.layout.height)),
117
+ children: [
118
+ /* @__PURE__ */ jsx(Animated.Text, { numberOfLines: 1, style: [styles.largeTitle, largeStyle], children: title }),
119
+ subtitle ? /* @__PURE__ */ jsx(Text, { style: styles.largeSubtitle, children: subtitle }) : null
120
+ ]
121
+ }
122
+ ) : null,
70
123
  showSearch ? /* @__PURE__ */ jsx(View, { style: styles.searchRow, children: searchSlot != null ? searchSlot : /* @__PURE__ */ jsx(
71
- SearchExpand,
124
+ ExpandingSearchField,
72
125
  {
73
126
  placeholder: searchPlaceholder,
74
127
  recents: searchRecents,
@@ -124,7 +177,7 @@ var sheet = createStyleSheet((theme) => ({
124
177
  }
125
178
  },
126
179
  // `type.headline` (17/22/600) is the nav-bar title role on both ramps (HIG
127
- // headline / M3 title), is what `NavigationStack`'s own `NavBar` already uses
180
+ // headline / M3 title), is what `NavStack`'s own `NavBar` already uses
128
181
  // for the same element, and is what the design reference draws (16/700). The
129
182
  // deprecated `fontSize[20]` (20) it replaced was the web h3, and left no room
130
183
  // for a subtitle inside the 44dp row.
@@ -201,4 +254,4 @@ var sheet = createStyleSheet((theme) => ({
201
254
  }
202
255
  }));
203
256
 
204
- export { Header, HeaderAction };
257
+ export { NavHeader, NavHeaderAction };