@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,11 +1,12 @@
1
- import { ContinuousNotice, ShutterButton, TorchToggle, GridToggle, GuideOverlay, ExpertPanel, LensPicker, SequenceStrip, ShutterTray, FlipButton, TrackingOverlay, GridOverlay, FocusTapZone, FocusIndicator } from './chunk-BV3B2HYZ.js';
2
- import { PlaceholderFeed } from './chunk-LAECSR4H.js';
3
- import { decorativeProps, camInk, SurfaceLiveRegion, ViewfinderTopBar, GlassIconButton, GuidanceChip, GateHint, useSurfaceAnnounce } from './chunk-RW6ZL2FQ.js';
4
- import { Icon } from './chunk-TKVFVF5D.js';
1
+ import { ContinuousNotice, ShutterButton, TorchToggle, ViewfinderGridToggle, GuideOverlay, ExpertPanel, LensPicker, SequenceStrip, ShutterTray, FlipButton, TrackingOverlay, ViewfinderGridOverlay, FocusTapZone, FocusIndicator } from './chunk-XIDTBCBA.js';
2
+ import { PlaceholderFeed } from './chunk-5LAAAXFP.js';
3
+ import { decorativeProps, useAnalyzerCopy, camInk, useAnalyzerLabels, AnalyzerCopyScope, SurfaceLiveRegion, ViewfinderTopBar, GlassIconButton, GuidanceChip, GateHint, useSurfaceAnnounce } from './chunk-HJLPZA4X.js';
4
+ import { NAMED_ROLE } from './chunk-W23G6JLF.js';
5
+ import { Icon } from './chunk-UXGIW7OK.js';
5
6
  import * as React2 from 'react';
6
7
  import { View, Animated, Easing, Text, Pressable } from 'react-native';
7
8
  import { createStyleSheet, useStyles, useLoamTheme } from '@btndprojects/loam-theme-native';
8
- import { queueLabel, profile, caps, isFrozen, primaryCheck, TOASTS, gateHint, angleAt, viewfinderSubtitle, PRIVACY_STATEMENT, confidenceTone, confidenceLabel, CAPTURED_PILL, DONE_LABEL } from '@btndprojects/loam-analyzer';
9
+ import { queueLabel, localizeProfile, profile, caps, isFrozen, primaryCheck, gateHint, angleAt, viewfinderSubtitle, confidenceTone, confidenceLabel } from '@btndprojects/loam-analyzer';
9
10
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
10
11
 
11
12
  function numericRatio(ratio) {
@@ -60,7 +61,7 @@ function PreviewSlot({ preview, label, topInset }) {
60
61
  return /* @__PURE__ */ jsx(View, { style: styles.previewSlot, children: preview ?? /* @__PURE__ */ jsx(PlaceholderFeed, { label, topInset }) });
61
62
  }
62
63
  function CaptureFlash({ token = null }) {
63
- const theme = useLoamTheme();
64
+ const theme = useLoamTheme("analyzer");
64
65
  const { styles } = useStyles(stageSheet);
65
66
  const [flashes, setFlashes] = React2.useState(0);
66
67
  const first = React2.useRef(true);
@@ -91,11 +92,12 @@ function CaptureFlash({ token = null }) {
91
92
  }
92
93
  );
93
94
  }
94
- function QueueBadge({ count, onPress }) {
95
- const theme = useLoamTheme();
95
+ function QueueBadge({ count, onPress, copy }) {
96
+ const theme = useLoamTheme("analyzer");
96
97
  const { styles } = useStyles(stageSheet);
98
+ const words = useAnalyzerCopy(copy);
97
99
  if (count <= 0) return null;
98
- const text = queueLabel(count);
100
+ const text = queueLabel(count, words);
99
101
  const ink = camInk(theme);
100
102
  const body = /* @__PURE__ */ jsxs(Fragment, { children: [
101
103
  /* @__PURE__ */ jsx(Icon, { name: "scan", size: theme.icon.sm, color: ink }),
@@ -113,7 +115,7 @@ function QueueBadge({ count, onPress }) {
113
115
  }
114
116
  );
115
117
  }
116
- return /* @__PURE__ */ jsx(View, { accessible: true, accessibilityLabel: text, style: styles.badge, children: body });
118
+ return /* @__PURE__ */ jsx(View, { accessible: true, accessibilityRole: NAMED_ROLE, accessibilityLabel: text, style: styles.badge, children: body });
117
119
  }
118
120
  var stageSheet = createStyleSheet((theme) => ({
119
121
  stage: {
@@ -183,22 +185,22 @@ var SCRIM_STOP = {
183
185
  analysing: "a10",
184
186
  failure: "a11"
185
187
  };
186
- function feedLabel(p, phase, platform, zoom) {
187
- const facing = platform === "web" ? "webcam \xB7 front" : "rear camera";
188
- if (phase === "live") return `${facing} \xB7 ${p.ratio} \xB7 ${zoom}x \xB7 placeholder feed`;
189
- if (phase === "captured") return `frozen frame \xB7 ${p.ratio} \xB7 placeholder`;
190
- if (phase === "analysing") return "frozen frame \xB7 analysing";
191
- if (phase === "result" || phase === "failure") return "frozen frame";
192
- if (phase === "done") return "captured frame";
193
- return `${facing} \xB7 ${p.ratio} \xB7 placeholder feed`;
188
+ function feedLabel(p, phase, platform, zoom, t) {
189
+ const facing = platform === "web" ? t.webcamFront : t.rearCamera;
190
+ if (phase === "live") return t.feedLive(facing, p.ratio, zoom);
191
+ if (phase === "captured") return t.feedCaptured(p.ratio);
192
+ if (phase === "analysing") return t.feedAnalysing;
193
+ if (phase === "result" || phase === "failure") return t.feedFrozen;
194
+ if (phase === "done") return t.feedDone;
195
+ return t.feedLive(facing, p.ratio, zoom);
194
196
  }
195
- function phaseMessage(p, phase) {
196
- if (phase === "live") return `${p.label}. ${p.subject}.`;
197
- if (phase === "captured") return CAPTURED_PILL;
198
- if (phase === "analysing") return "Analysing";
199
- if (phase === "result") return "Result ready";
200
- if (phase === "failure") return "Analysis failed";
201
- if (phase === "done") return DONE_LABEL;
197
+ function phaseMessage(p, phase, copy, t) {
198
+ if (phase === "live") return copy.viewfinder.phaseLine(p.label, p.subject);
199
+ if (phase === "captured") return copy.capturedPill;
200
+ if (phase === "analysing") return t.analysing;
201
+ if (phase === "result") return t.resultReady;
202
+ if (phase === "failure") return t.analysisFailed;
203
+ if (phase === "done") return copy.done;
202
204
  return null;
203
205
  }
204
206
  function detectedChip(detected, confidence) {
@@ -212,15 +214,17 @@ function detectedChip(detected, confidence) {
212
214
  function PhaseAnnouncer({
213
215
  profile: p,
214
216
  phase,
215
- detected
217
+ detected,
218
+ copy,
219
+ labels
216
220
  }) {
217
221
  const announce = useSurfaceAnnounce();
218
222
  const sink = React2.useRef(announce);
219
223
  sink.current = announce;
220
224
  React2.useEffect(() => {
221
- const message = phaseMessage(p, phase);
225
+ const message = phaseMessage(p, phase, copy, labels);
222
226
  if (message) sink.current?.(message);
223
- }, [p, phase]);
227
+ }, [p, phase, copy, labels]);
224
228
  React2.useEffect(() => {
225
229
  if (detected) sink.current?.(detected);
226
230
  }, [detected]);
@@ -252,7 +256,11 @@ function Analyzer({
252
256
  focusPoint = null,
253
257
  flashToken = null,
254
258
  title,
255
- privacyStatement = PRIVACY_STATEMENT,
259
+ privacyStatement,
260
+ enforceGate = true,
261
+ uploadLabel,
262
+ labels: labelsProp,
263
+ copy: copyProp,
256
264
  children,
257
265
  onCapture,
258
266
  onUpload,
@@ -270,9 +278,11 @@ function Analyzer({
270
278
  onGatePass,
271
279
  onNotify
272
280
  }) {
273
- const theme = useLoamTheme();
281
+ const theme = useLoamTheme("analyzer");
274
282
  const { styles } = useStyles(analyzerSheet);
275
- const p = profile(profileProp);
283
+ const copy = useAnalyzerCopy(copyProp);
284
+ const t = useAnalyzerLabels(labelsProp);
285
+ const p = React2.useMemo(() => localizeProfile(profile(profileProp), copy), [profileProp, copy]);
276
286
  const caps$1 = caps(level);
277
287
  const chip = detected ? detectedChip(detected, detectedConfidence) : null;
278
288
  const live = phase === "live";
@@ -281,10 +291,13 @@ function Analyzer({
281
291
  const tracking = objects.length > 0;
282
292
  const trackLocked = objects.some((o) => o.locked === true);
283
293
  const gateOpen = caps$1.gate ? gate.pass : true;
294
+ const captureOpen = enforceGate ? gateOpen : true;
284
295
  const blockedToast = React2.useMemo(() => {
285
296
  const check = primaryCheck(p, gate);
286
- return TOASTS.gateBlocked(check ? check.fix : gateHint(p, gate));
287
- }, [p, gate]);
297
+ return copy.toasts.gateBlocked(
298
+ check ? copy.checks[check.id]?.fix ?? check.fix : gateHint(p, gate, null, copy)
299
+ );
300
+ }, [p, gate, copy]);
288
301
  const notify = React2.useRef(onNotify);
289
302
  notify.current = onNotify;
290
303
  const gatePass = React2.useRef(onGatePass);
@@ -302,16 +315,16 @@ function Analyzer({
302
315
  (next) => {
303
316
  if (!caps$1.grid) return;
304
317
  onGridChange?.(next);
305
- notify.current?.({ title: TOASTS.grid(next) });
318
+ notify.current?.({ title: copy.toasts.grid(next) });
306
319
  },
307
320
  [caps$1.grid, onGridChange]
308
321
  );
309
322
  const close = React2.useCallback(() => {
310
323
  onClose?.();
311
- notify.current?.({ title: TOASTS.close });
324
+ notify.current?.({ title: copy.toasts.close });
312
325
  }, [onClose]);
313
326
  const angle = angleAt(p, angleIndex);
314
- const subtitle = viewfinderSubtitle(p, { angleIndex, shots });
327
+ const subtitle = viewfinderSubtitle(p, { angleIndex, shots }, copy);
315
328
  const sequence = caps$1.sequence && (p.frames === "multi" || typeof p.frames === "number" && p.frames > 1);
316
329
  const scrimStop = SCRIM_STOP[phase];
317
330
  const trayPrimary = continuous ? /* @__PURE__ */ jsx(ContinuousNotice, {}) : /* @__PURE__ */ jsx(
@@ -319,28 +332,37 @@ function Analyzer({
319
332
  {
320
333
  platform,
321
334
  mode: p.shutter,
322
- enabled: gateOpen,
335
+ enabled: captureOpen,
323
336
  countdown: caps$1.auto ? countdown : null,
324
337
  blockedToast,
325
338
  onPress: onCapture,
326
339
  onBlocked: blocked
327
340
  }
328
341
  );
329
- return /* @__PURE__ */ jsxs(SurfaceLiveRegion, { children: [
330
- /* @__PURE__ */ jsx(PhaseAnnouncer, { profile: p, phase, detected: chip ? chip.text : null }),
342
+ return /* @__PURE__ */ jsx(AnalyzerCopyScope.Provider, { value: copyProp, children: /* @__PURE__ */ jsxs(SurfaceLiveRegion, { children: [
343
+ /* @__PURE__ */ jsx(
344
+ PhaseAnnouncer,
345
+ {
346
+ profile: p,
347
+ phase,
348
+ detected: chip ? chip.text : null,
349
+ copy,
350
+ labels: t
351
+ }
352
+ ),
331
353
  /* @__PURE__ */ jsxs(
332
354
  CameraSurface,
333
355
  {
334
356
  ratio,
335
357
  platform,
336
358
  insets,
337
- accessibilityLabel: `${title ?? p.label} viewfinder`,
359
+ accessibilityLabel: copy.viewfinder.aria(title ?? p.label),
338
360
  feed: /* @__PURE__ */ jsxs(Fragment, { children: [
339
361
  /* @__PURE__ */ jsx(
340
362
  PreviewSlot,
341
363
  {
342
364
  preview,
343
- label: feedLabel(p, phase, platform, zoom),
365
+ label: feedLabel(p, phase, platform, zoom, t),
344
366
  topInset: insets?.top ?? 0
345
367
  }
346
368
  ),
@@ -362,7 +384,7 @@ function Analyzer({
362
384
  safeAreaBottom: insets?.bottom ?? 0
363
385
  }
364
386
  ) : null,
365
- live ? /* @__PURE__ */ jsx(GridOverlay, { visible: caps$1.grid && grid }) : null,
387
+ live ? /* @__PURE__ */ jsx(ViewfinderGridOverlay, { visible: caps$1.grid && grid }) : null,
366
388
  live ? /* @__PURE__ */ jsx(FocusTapZone, { onFocusPoint }) : null,
367
389
  live ? /* @__PURE__ */ jsx(
368
390
  FocusIndicator,
@@ -383,12 +405,12 @@ function Analyzer({
383
405
  onClose: onClose ? close : void 0,
384
406
  children: [
385
407
  caps$1.torch ? /* @__PURE__ */ jsx(TorchToggle, { on: torch, available: torchAvailable, onChange: onTorchChange }) : null,
386
- caps$1.grid ? /* @__PURE__ */ jsx(GridToggle, { on: grid, onChange: toggleGrid }) : null,
408
+ caps$1.grid ? /* @__PURE__ */ jsx(ViewfinderGridToggle, { on: grid, onChange: toggleGrid }) : null,
387
409
  caps$1.expert && onExpertOpenChange ? /* @__PURE__ */ jsx(
388
410
  GlassIconButton,
389
411
  {
390
412
  icon: "sliders",
391
- label: "Expert controls",
413
+ label: t.expertControls,
392
414
  on: expertOpen,
393
415
  onPress: () => onExpertOpenChange(!expertOpen)
394
416
  }
@@ -455,18 +477,25 @@ function Analyzer({
455
477
  ShutterTray,
456
478
  {
457
479
  platform,
458
- start: /* @__PURE__ */ jsx(GlassIconButton, { icon: "upload", label: "Upload a photo", onPress: onUpload }),
480
+ start: /* @__PURE__ */ jsx(
481
+ GlassIconButton,
482
+ {
483
+ icon: "upload",
484
+ label: uploadLabel ?? t.uploadPhoto,
485
+ onPress: onUpload
486
+ }
487
+ ),
459
488
  primary: trayPrimary,
460
489
  stack: continuous,
461
490
  end: caps$1.flip ? /* @__PURE__ */ jsx(FlipButton, { onFlip }) : null
462
491
  }
463
492
  ),
464
- /* @__PURE__ */ jsx(Text, { style: [styles.privacy, { color: camInk(theme) }], children: privacyStatement })
493
+ privacyStatement ? /* @__PURE__ */ jsx(Text, { style: [styles.privacy, { color: camInk(theme) }], children: privacyStatement }) : null
465
494
  ] }) : null
466
495
  ]
467
496
  }
468
497
  )
469
- ] });
498
+ ] }) });
470
499
  }
471
500
  var analyzerSheet = createStyleSheet((theme) => ({
472
501
  scrim: {
@@ -1,6 +1,7 @@
1
- import { Spinner } from './chunk-O7AE6DAF.js';
1
+ import { Spinner } from './chunk-KQZ3GLHR.js';
2
2
  import { haptics } from './chunk-NY2U3PBI.js';
3
- import { useResolvedMotion } from './chunk-6N33LFQA.js';
3
+ import { useLabels } from './chunk-APCWFOZW.js';
4
+ import { useResolvedMotion } from './chunk-J64KGCGX.js';
4
5
  import * as React from 'react';
5
6
  import { Animated, Easing, View, Pressable, Platform } from 'react-native';
6
7
  import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
@@ -39,12 +40,15 @@ function geometry(theme, os, size) {
39
40
  return { width, height, pad: 0, knob, travel: width - knob };
40
41
  }
41
42
  function useResolvedPlatform(explicit) {
42
- const theme = useLoamTheme();
43
+ const theme = useLoamTheme("switch");
43
44
  if (explicit) return explicit;
44
45
  if (Platform.OS === "ios") return "ios";
45
46
  if (Platform.OS === "android") return "android";
46
47
  return theme.platform === "iOS" ? "ios" : "android";
47
48
  }
49
+ var DEFAULT_LABELS = {
50
+ loading: "Loading"
51
+ };
48
52
  function Switch({
49
53
  value,
50
54
  defaultValue = false,
@@ -53,21 +57,24 @@ function Switch({
53
57
  platform,
54
58
  disabled = false,
55
59
  pending = false,
60
+ failed = false,
56
61
  motion = "full",
57
62
  accessibilityLabel,
58
- decorative = false
63
+ decorative = false,
64
+ labels: labelsProp
59
65
  }) {
66
+ const labels = useLabels("switch", DEFAULT_LABELS, labelsProp);
60
67
  const isControlled = value !== void 0;
61
68
  const [internal, setInternal] = React.useState(defaultValue);
62
69
  const checked = isControlled ? value : internal;
63
- const theme = useLoamTheme();
70
+ const theme = useLoamTheme("switch");
64
71
  const os = useResolvedPlatform(platform);
65
72
  const shape = `${os}-${size}`;
66
73
  const { styles } = useStyles(sheet, { shape, disabled });
67
74
  const { travel, width: trackW, height: trackH } = geometry(theme, os, size);
68
75
  const slopX = Math.max(0, (theme.tapMin - trackW) / 2);
69
76
  const slopY = Math.max(0, (theme.tapMin - trackH) / 2);
70
- const resolved = useResolvedMotion(motion);
77
+ const resolved = useResolvedMotion(motion, "switch");
71
78
  const tint = React.useRef(new Animated.Value(checked ? 1 : 0)).current;
72
79
  const slide = React.useRef(new Animated.Value(checked ? 1 : 0)).current;
73
80
  React.useEffect(() => {
@@ -108,6 +115,20 @@ function Switch({
108
115
  // needs mirroring by hand.
109
116
  outputRange: [0, theme.rtl ? -travel : travel]
110
117
  });
118
+ const shake = React.useRef(new Animated.Value(0)).current;
119
+ const wasFailed = React.useRef(false);
120
+ React.useEffect(() => {
121
+ if (failed && !wasFailed.current && resolved === "full") {
122
+ const step = theme.space[4];
123
+ const d = Math.max(1, Math.round(theme.duration.fast / 4));
124
+ Animated.sequence(
125
+ [-step, step, -step, 0].map(
126
+ (toValue) => Animated.timing(shake, { toValue, duration: d, useNativeDriver: true })
127
+ )
128
+ ).start();
129
+ }
130
+ wasFailed.current = failed;
131
+ }, [failed, resolved, shake, theme.space, theme.duration.fast]);
111
132
  const toggle = () => {
112
133
  const next = !checked;
113
134
  if (!isControlled) setInternal(next);
@@ -136,7 +157,7 @@ function Switch({
136
157
  size: "sm",
137
158
  color: theme.color.accent,
138
159
  motion,
139
- accessibilityLabel: "Loading"
160
+ accessibilityLabel: labels.loading
140
161
  }
141
162
  )
142
163
  }
@@ -155,10 +176,11 @@ function Switch({
155
176
  accessibilityState: { checked, disabled, busy: pending },
156
177
  "aria-checked": checked,
157
178
  "aria-busy": pending || void 0,
179
+ "aria-invalid": failed || void 0,
158
180
  disabled,
159
181
  onPress: disabled || pending ? void 0 : toggle,
160
182
  hitSlop: { top: slopY, bottom: slopY, left: slopX, right: slopX },
161
- children: visual
183
+ children: /* @__PURE__ */ jsx(Animated.View, { testID: "switch-shake", style: { transform: [{ translateX: shake }] }, children: visual })
162
184
  }
163
185
  );
164
186
  }
@@ -1,4 +1,4 @@
1
- import { ErrorSummary } from './chunk-C2NTXVWM.js';
1
+ import { ErrorSummary } from './chunk-XBZGDDMR.js';
2
2
  import * as React from 'react';
3
3
  import { View } from 'react-native';
4
4
  import { createStyleSheet, useStyles } from '@btndprojects/loam-theme-native';
@@ -1,14 +1,18 @@
1
- import { ContextMenuOverlay } from './chunk-PZXZJBMP.js';
2
- import { expandedProps } from './chunk-RQ3HASCC.js';
3
- import { Button } from './chunk-3ARE4TES.js';
4
- import { Icon } from './chunk-TKVFVF5D.js';
1
+ import { ContextMenuOverlay } from './chunk-U5NLHYV6.js';
2
+ import { expandedProps } from './chunk-W23G6JLF.js';
3
+ import { Button } from './chunk-E2E3I5W2.js';
4
+ import { useLabels } from './chunk-APCWFOZW.js';
5
+ import { Icon } from './chunk-UXGIW7OK.js';
5
6
  import * as React from 'react';
6
7
  import { Animated, View, Pressable } from 'react-native';
7
8
  import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
8
9
  import { jsxs, jsx } from 'react/jsx-runtime';
9
10
 
11
+ var DEFAULT_LABELS = {
12
+ menu: "More actions"
13
+ };
10
14
  function useChevronColors(variant, disabled) {
11
- const theme = useLoamTheme();
15
+ const theme = useLoamTheme("split-button");
12
16
  if (disabled) return { bg: theme.color.surface3, fg: theme.color.text3 };
13
17
  switch (variant) {
14
18
  case "primary":
@@ -28,10 +32,13 @@ function SplitButton({
28
32
  leadingIcon,
29
33
  disabled = false,
30
34
  loading = false,
31
- menuLabel = "More actions",
32
- motion = "full"
35
+ menuLabel: menuLabelProp,
36
+ motion = "full",
37
+ labels: labelsProp
33
38
  }) {
34
- const theme = useLoamTheme();
39
+ const theme = useLoamTheme("split-button");
40
+ const labels = useLabels("splitButton", DEFAULT_LABELS, labelsProp);
41
+ const menuLabel = menuLabelProp ?? labels.menu;
35
42
  const isDisabled = disabled || loading;
36
43
  const { styles } = useStyles(sheet, { size });
37
44
  const colors = useChevronColors(variant, isDisabled);