@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,21 +1,20 @@
1
- import { camInk, GlassIconButton, decorativeProps, untabbableProps, camMeta, pressedProps } from './chunk-RW6ZL2FQ.js';
2
- import { useReducedMotion } from './chunk-6N33LFQA.js';
3
- import { Icon } from './chunk-TKVFVF5D.js';
1
+ import { camInk, useViewfinderLabels, useAnalyzerCopy, GlassIconButton, decorativeProps, untabbableProps, camMeta, pressedProps } from './chunk-HJLPZA4X.js';
2
+ import { useLoamLocale } from './chunk-APCWFOZW.js';
3
+ import { Icon } from './chunk-UXGIW7OK.js';
4
+ import { useReducedMotion } from './chunk-J64KGCGX.js';
4
5
  import * as React3 from 'react';
5
6
  import { Animated, View, Text, Pressable, Easing, Dimensions, ScrollView } from 'react-native';
6
7
  import Svg2, { Path, Circle, Defs, LinearGradient, Stop, Rect, Line } from 'react-native-svg';
7
8
  import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
8
- import { TRACK_BAND_BOTTOM, EXPERT, CONTINUOUS_NOTICE, confidenceTone, TRACKING_MOTION, confidenceLabel, trackCountLabel, trackTone, chipRoom, chipAnchor, chipSlot, visibleChips, MAX_CHIPS, trackingSummaryLabel, readBatchLabel } from '@btndprojects/loam-analyzer';
9
+ import { TRACK_BAND_BOTTOM, confidenceTone, TRACKING_MOTION, confidenceLabel, trackCountLabel, trackTone, chipRoom, chipAnchor, chipSlot, visibleChips, MAX_CHIPS, trackingSummaryLabel, readBatchLabel } from '@btndprojects/loam-analyzer';
9
10
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
11
 
11
12
  var RING_R = 46;
12
13
  var RING_C = 2 * Math.PI * RING_R;
13
14
  var RING_STROKE = 6;
14
- function CountdownRing({
15
- value,
16
- label = "Auto-capturing"
17
- }) {
18
- const theme = useLoamTheme();
15
+ function CountdownRing({ value, label, labels }) {
16
+ const t = useViewfinderLabels(labels);
17
+ const theme = useLoamTheme("viewfinder");
19
18
  const reduced = useReducedMotion();
20
19
  const { styles } = useStyles(controlSheet);
21
20
  const pct2 = Math.min(100, Math.max(0, value));
@@ -25,7 +24,7 @@ function CountdownRing({
25
24
  {
26
25
  accessibilityRole: "progressbar",
27
26
  role: "progressbar",
28
- accessibilityLabel: label,
27
+ accessibilityLabel: label ?? t.autoCapturing,
29
28
  accessibilityValue: { min: 0, max: 100, now: Math.round(pct2) },
30
29
  style: styles.ringRoot,
31
30
  ...{
@@ -57,11 +56,13 @@ function ShutterButton({
57
56
  platform = "web",
58
57
  countdown = null,
59
58
  blockedToast,
60
- label = "Capture",
59
+ label,
60
+ labels,
61
61
  onPress,
62
62
  onBlocked
63
63
  }) {
64
- const theme = useLoamTheme();
64
+ const t = useViewfinderLabels(labels);
65
+ const theme = useLoamTheme("viewfinder");
65
66
  const { styles } = useStyles(controlSheet, { platform, enabled });
66
67
  const glyphColour = enabled ? theme.media.onInk : camInk(theme);
67
68
  if (mode === "continuous") return null;
@@ -69,7 +70,7 @@ function ShutterButton({
69
70
  Pressable,
70
71
  {
71
72
  accessibilityRole: "button",
72
- accessibilityLabel: label,
73
+ accessibilityLabel: label ?? t.capture,
73
74
  accessibilityState: { disabled: !enabled },
74
75
  testID: enabled ? "loam-shutter-open" : "loam-shutter-blocked",
75
76
  style: styles.shutter,
@@ -89,81 +90,95 @@ function ShutterButton({
89
90
  color: glyphColour
90
91
  }
91
92
  ) }),
92
- typeof countdown === "number" ? /* @__PURE__ */ jsx(CountdownRing, { value: countdown }) : null
93
+ typeof countdown === "number" ? /* @__PURE__ */ jsx(CountdownRing, { value: countdown, labels }) : null
93
94
  ]
94
95
  }
95
96
  );
96
97
  }
97
- function ContinuousNotice({
98
- text = CONTINUOUS_NOTICE
99
- }) {
100
- const theme = useLoamTheme();
98
+ function ContinuousNotice({ text, copy }) {
99
+ const words = useAnalyzerCopy(copy);
100
+ const theme = useLoamTheme("viewfinder");
101
101
  const { styles } = useStyles(controlSheet);
102
102
  const ink = camInk(theme);
103
103
  return /* @__PURE__ */ jsxs(View, { style: styles.notice, children: [
104
104
  /* @__PURE__ */ jsx(Icon, { name: "barcode", size: theme.icon.sm, color: ink }),
105
- /* @__PURE__ */ jsx(Text, { style: [styles.noticeText, { color: ink }], children: text })
105
+ /* @__PURE__ */ jsx(Text, { style: [styles.noticeText, { color: ink }], children: text ?? words.continuousNotice })
106
106
  ] });
107
107
  }
108
108
  function TorchToggle({
109
109
  on = false,
110
110
  available = true,
111
- label = "Torch",
111
+ label,
112
+ labels,
112
113
  onChange
113
114
  }) {
115
+ const t = useViewfinderLabels(labels);
114
116
  if (!available) return null;
115
117
  return /* @__PURE__ */ jsx(
116
118
  GlassIconButton,
117
119
  {
118
120
  icon: "flash",
119
- label,
121
+ label: label ?? t.torch,
120
122
  on,
121
123
  onPress: () => onChange?.(!on)
122
124
  }
123
125
  );
124
126
  }
125
- function GridToggle({
127
+ function ViewfinderGridToggle({
126
128
  on = false,
127
- label = "Grid",
129
+ label,
130
+ labels,
128
131
  onChange
129
132
  }) {
130
- return /* @__PURE__ */ jsx(GlassIconButton, { icon: "grid", label, on, onPress: () => onChange?.(!on) });
133
+ const t = useViewfinderLabels(labels);
134
+ return /* @__PURE__ */ jsx(GlassIconButton, { icon: "grid", label: label ?? t.grid, on, onPress: () => onChange?.(!on) });
131
135
  }
132
- function FlipButton({
133
- label = "Flip camera",
134
- onFlip
135
- }) {
136
- return /* @__PURE__ */ jsx(GlassIconButton, { icon: "flip", label, onPress: onFlip });
136
+ function FlipButton({ label, labels, onFlip }) {
137
+ const t = useViewfinderLabels(labels);
138
+ return /* @__PURE__ */ jsx(GlassIconButton, { icon: "flip", label: label ?? t.flipCamera, onPress: onFlip });
137
139
  }
138
140
  function LensStop({
139
141
  stop,
140
142
  on,
141
- onPick
143
+ onPick,
144
+ labels
142
145
  }) {
143
- const theme = useLoamTheme();
146
+ const t = useViewfinderLabels(labels);
147
+ const theme = useLoamTheme("viewfinder");
144
148
  const { styles } = useStyles(controlSheet, { on });
145
149
  return /* @__PURE__ */ jsx(
146
150
  Pressable,
147
151
  {
148
152
  accessibilityRole: "button",
149
- accessibilityLabel: `${stop}x`,
153
+ accessibilityLabel: t.zoomStop(stop),
150
154
  accessibilityState: { selected: on },
151
155
  style: styles.lensStop,
152
156
  hitSlop: Math.max(0, (theme.hit.lg - theme.ctl.md) / 2),
153
157
  onPress: onPick,
154
158
  ...pressedProps(on),
155
- children: /* @__PURE__ */ jsx(Text, { style: [styles.lensLabel, { color: on ? theme.media.onInk : camInk(theme) }], children: `${stop}x` })
159
+ children: /* @__PURE__ */ jsx(Text, { style: [styles.lensLabel, { color: on ? theme.media.onInk : camInk(theme) }], children: t.zoomStop(stop) })
156
160
  }
157
161
  );
158
162
  }
159
163
  function LensPicker({
160
164
  stops = [2, 1, 0.5],
161
165
  value = 1,
162
- label = "Zoom",
166
+ label,
167
+ labels,
163
168
  onChange
164
169
  }) {
170
+ const t = useViewfinderLabels(labels);
165
171
  const { styles } = useStyles(controlSheet);
166
- return /* @__PURE__ */ jsx(View, { role: "group", accessibilityLabel: label, style: styles.lensColumn, children: stops.map((stop) => /* @__PURE__ */ jsx(LensStop, { stop, on: stop === value, onPick: () => onChange?.(stop) }, stop)) });
172
+ return /* @__PURE__ */ jsx(View, { role: "group", accessibilityLabel: label ?? t.zoom, style: styles.lensColumn, children: stops.map((stop) => /* @__PURE__ */ jsx(
173
+ LensStop,
174
+ {
175
+ stop,
176
+ on: stop === value,
177
+ labels,
178
+ onPick: () => onChange?.(stop)
179
+ },
180
+ stop
181
+ )) });
167
182
  }
168
183
  var controlSheet = createStyleSheet((theme) => ({
169
184
  ringRoot: {
@@ -284,7 +299,7 @@ var controlSheet = createStyleSheet((theme) => ({
284
299
  }
285
300
  }));
286
301
  function ScanLine({ active = true, band, travel }) {
287
- const theme = useLoamTheme();
302
+ const theme = useLoamTheme("viewfinder");
288
303
  const reduced = useReducedMotion();
289
304
  const { styles } = useStyles(overlaySheet);
290
305
  const height = band ?? theme.space[80];
@@ -356,7 +371,7 @@ function GuideOverlay({
356
371
  hint,
357
372
  scanning = true
358
373
  }) {
359
- const theme = useLoamTheme();
374
+ const theme = useLoamTheme("viewfinder");
360
375
  const { styles } = useStyles(overlaySheet, { pass, dimmed });
361
376
  const snap = React3.useRef(new Animated.Value(pass ? 1 : 0)).current;
362
377
  React3.useEffect(() => {
@@ -459,7 +474,7 @@ function GuideOverlay({
459
474
  }
460
475
  );
461
476
  }
462
- function GridOverlay({ visible = false }) {
477
+ function ViewfinderGridOverlay({ visible = false }) {
463
478
  const { styles } = useStyles(overlaySheet);
464
479
  if (!visible) return null;
465
480
  return /* @__PURE__ */ jsxs(View, { accessible: false, testID: "loam-grid-overlay", style: styles.gridRoot, ...decorativeProps(), children: [
@@ -470,7 +485,7 @@ function GridOverlay({ visible = false }) {
470
485
  ] });
471
486
  }
472
487
  function FocusPulse({ point }) {
473
- const theme = useLoamTheme();
488
+ const theme = useLoamTheme("viewfinder");
474
489
  const reduced = useReducedMotion();
475
490
  const { styles } = useStyles(overlaySheet);
476
491
  const phase = React3.useRef(new Animated.Value(0)).current;
@@ -775,7 +790,7 @@ function TrackChip({
775
790
  staggerIndex = 0,
776
791
  frozen = false
777
792
  }) {
778
- const theme = useLoamTheme();
793
+ const theme = useLoamTheme("viewfinder");
779
794
  const reduced = useReducedMotion();
780
795
  const tone = confidenceTone(conf);
781
796
  const { styles } = useStyles(trackingSheet, { slot, tone, anchor });
@@ -811,10 +826,24 @@ function TrackChip({
811
826
  }
812
827
  ) });
813
828
  }
814
- function TrackCountPill({ count, label }) {
829
+ function TrackCountPill({
830
+ count,
831
+ label,
832
+ copy
833
+ }) {
834
+ const words = useAnalyzerCopy(copy);
815
835
  const { styles } = useStyles(trackingSheet);
816
836
  if (count <= 0) return null;
817
- return /* @__PURE__ */ jsx(View, { accessible: false, testID: "loam-track-count", style: styles.countPill, ...decorativeProps(), children: /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.countText, children: label ?? trackCountLabel(count) }) });
837
+ return /* @__PURE__ */ jsx(
838
+ View,
839
+ {
840
+ accessible: false,
841
+ testID: "loam-track-count",
842
+ style: styles.countPill,
843
+ ...decorativeProps(),
844
+ children: /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.countText, children: label ?? trackCountLabel(count, words) })
845
+ }
846
+ );
818
847
  }
819
848
  var OUTLINE_PATH = {
820
849
  /** A leafy blob — the plant profile's subject. */
@@ -834,7 +863,7 @@ function TrackedBox({
834
863
  ease = TRACKING_MOTION.ease,
835
864
  frozen = false
836
865
  }) {
837
- const theme = useLoamTheme();
866
+ const theme = useLoamTheme("viewfinder");
838
867
  const reduced = useReducedMotion();
839
868
  const [x, y, w, h] = object.box;
840
869
  const isLocked = locked ?? object.locked ?? false;
@@ -918,7 +947,10 @@ function TrackedBox({
918
947
  {
919
948
  accessible: false,
920
949
  testID: `loam-track-box-${object.id}`,
921
- style: [styles.box, { left: pct(geo.x), top: pct(geo.y), width: pct(geo.w), height: pct(geo.h) }],
950
+ style: [
951
+ styles.box,
952
+ { left: pct(geo.x), top: pct(geo.y), width: pct(geo.w), height: pct(geo.h) }
953
+ ],
922
954
  ...decorativeProps(),
923
955
  children: [
924
956
  /* @__PURE__ */ jsxs(Animated.View, { style: [styles.bracketLayer, { transform: [{ scale: lockScale }] }], children: [
@@ -976,13 +1008,15 @@ function TrackingOverlay({
976
1008
  frozen = false,
977
1009
  dimmed = false,
978
1010
  safeAreaBottom = 0,
979
- label
1011
+ label,
1012
+ copy
980
1013
  }) {
1014
+ const words = useAnalyzerCopy(copy);
981
1015
  const { styles } = useStyles(trackingSheet, { dimmed });
982
1016
  const [framePx, setFramePx] = React3.useState(0);
983
1017
  const { chips, overflow } = visibleChips([...objects], maxChips, framePx || void 0);
984
1018
  const chipIndex = new Map(chips.map((o, i) => [o.id, i]));
985
- const name = label === void 0 ? trackingSummaryLabel(objects) : label;
1019
+ const name = label === void 0 ? trackingSummaryLabel(objects, words) : label;
986
1020
  return /* @__PURE__ */ jsxs(
987
1021
  View,
988
1022
  {
@@ -1228,100 +1262,118 @@ function SequenceStrip({
1228
1262
  angles,
1229
1263
  mode = "angles",
1230
1264
  readLabel,
1265
+ labels,
1266
+ copy,
1231
1267
  onRedo,
1232
1268
  onRead
1233
1269
  }) {
1234
- const theme = useLoamTheme();
1270
+ const t = useViewfinderLabels(labels);
1271
+ const words = useAnalyzerCopy(copy);
1272
+ const theme = useLoamTheme("viewfinder");
1235
1273
  const { styles } = useStyles(sequenceSheet);
1236
1274
  const batch = mode === "batch";
1237
1275
  const count = batch ? Math.max(3, shots + 1) : total;
1238
1276
  const cells = Array.from({ length: count }, (_, i) => i);
1239
- return /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: batch ? "Captured pages" : "Capture sequence", style: styles.strip, children: [
1240
- /* @__PURE__ */ jsx(
1241
- ScrollView,
1242
- {
1243
- horizontal: true,
1244
- showsHorizontalScrollIndicator: false,
1245
- contentContainerStyle: styles.railContent,
1246
- style: styles.rail,
1247
- children: cells.map((i) => {
1248
- const done = i < shots;
1249
- const isCurrent = !done && i === current;
1250
- const name = batch ? `Page ${i + 1}` : angles?.[i]?.label ?? `Angle ${i + 1}`;
1251
- const label = done ? `${name} \u2014 captured, tap to redo` : name;
1252
- if (done) {
1253
- return /* @__PURE__ */ jsx(
1254
- Pressable,
1255
- {
1256
- accessibilityRole: "button",
1257
- accessibilityLabel: label,
1258
- style: styles.cellDone,
1259
- hitSlop: (theme.hit.lg - theme.space[32]) / 2,
1260
- onPress: () => onRedo?.(i),
1261
- children: /* @__PURE__ */ jsx(
1262
- Icon,
1277
+ return /* @__PURE__ */ jsxs(
1278
+ View,
1279
+ {
1280
+ role: "group",
1281
+ accessibilityLabel: batch ? t.capturedPages : t.captureSequence,
1282
+ style: styles.strip,
1283
+ children: [
1284
+ /* @__PURE__ */ jsx(
1285
+ ScrollView,
1286
+ {
1287
+ horizontal: true,
1288
+ showsHorizontalScrollIndicator: false,
1289
+ contentContainerStyle: styles.railContent,
1290
+ style: styles.rail,
1291
+ children: cells.map((i) => {
1292
+ const done = i < shots;
1293
+ const isCurrent = !done && i === current;
1294
+ const name = batch ? words.viewfinder.pageN(i + 1) : angles?.[i]?.label ?? words.viewfinder.angleN(i + 1);
1295
+ const label = done ? t.stepCaptured(name) : name;
1296
+ if (done) {
1297
+ return /* @__PURE__ */ jsx(
1298
+ Pressable,
1263
1299
  {
1264
- name: "check",
1265
- size: theme.icon.sm,
1266
- color: theme.color.goodInk,
1267
- strokeWidth: theme.icon.strokeBold
1268
- }
1269
- )
1270
- },
1271
- i
1272
- );
1300
+ accessibilityRole: "button",
1301
+ accessibilityLabel: label,
1302
+ style: styles.cellDone,
1303
+ hitSlop: (theme.hit.lg - theme.space[32]) / 2,
1304
+ onPress: () => onRedo?.(i),
1305
+ children: /* @__PURE__ */ jsx(
1306
+ Icon,
1307
+ {
1308
+ name: "check",
1309
+ size: theme.icon.sm,
1310
+ color: theme.color.goodInk,
1311
+ strokeWidth: theme.icon.strokeBold
1312
+ }
1313
+ )
1314
+ },
1315
+ i
1316
+ );
1317
+ }
1318
+ return /* @__PURE__ */ jsx(
1319
+ View,
1320
+ {
1321
+ accessible: true,
1322
+ accessibilityLabel: label,
1323
+ style: [styles.cellPending, isCurrent ? styles.cellCurrent : null],
1324
+ children: /* @__PURE__ */ jsx(Text, { style: styles.cellNumber, accessible: false, children: String(i + 1) })
1325
+ },
1326
+ i
1327
+ );
1328
+ })
1273
1329
  }
1274
- return /* @__PURE__ */ jsx(
1275
- View,
1330
+ ),
1331
+ batch && shots > 0 ? (
1332
+ // Pinned: outside the scroller, so eleven pages cannot push it off the
1333
+ // end of the rail.
1334
+ /* @__PURE__ */ jsx(
1335
+ Pressable,
1276
1336
  {
1277
- accessible: true,
1278
- accessibilityLabel: label,
1279
- style: [styles.cellPending, isCurrent ? styles.cellCurrent : null],
1280
- children: /* @__PURE__ */ jsx(Text, { style: styles.cellNumber, accessible: false, children: String(i + 1) })
1281
- },
1282
- i
1283
- );
1284
- })
1285
- }
1286
- ),
1287
- batch && shots > 0 ? (
1288
- // Pinned: outside the scroller, so eleven pages cannot push it off the
1289
- // end of the rail.
1290
- /* @__PURE__ */ jsx(
1291
- Pressable,
1292
- {
1293
- accessibilityRole: "button",
1294
- style: styles.pinned,
1295
- hitSlop: (theme.hit.lg - theme.space[32]) / 2,
1296
- onPress: onRead,
1297
- children: /* @__PURE__ */ jsx(Text, { style: styles.pinnedLabel, children: readLabel ?? readBatchLabel(shots) })
1298
- }
1299
- )
1300
- ) : null
1301
- ] });
1337
+ accessibilityRole: "button",
1338
+ style: styles.pinned,
1339
+ hitSlop: (theme.hit.lg - theme.space[32]) / 2,
1340
+ onPress: onRead,
1341
+ children: /* @__PURE__ */ jsx(Text, { style: styles.pinnedLabel, children: readLabel ?? readBatchLabel(shots, words) })
1342
+ }
1343
+ )
1344
+ ) : null
1345
+ ]
1346
+ }
1347
+ );
1302
1348
  }
1303
1349
  var EV_STOPS = Array.from(
1304
1350
  { length: 13 },
1305
1351
  (_, i) => Math.round((i - 6) / 3 * 100) / 100
1306
1352
  );
1307
- function evLabel(v) {
1353
+ function evLabel(v, locale) {
1308
1354
  if (v === 0) return "0";
1309
- return `${v > 0 ? "+" : ""}${v.toFixed(1)}`;
1355
+ return new Intl.NumberFormat(locale, {
1356
+ minimumFractionDigits: 1,
1357
+ maximumFractionDigits: 1,
1358
+ signDisplay: "exceptZero"
1359
+ }).format(v);
1360
+ }
1361
+ function groupNames(expert) {
1362
+ return {
1363
+ ev: expert[1]?.name ?? "EV compensation",
1364
+ torch: expert[3]?.name ?? "Torch level",
1365
+ format: expert[4]?.name ?? "Resolution and format",
1366
+ ae: expert[0]?.name ?? "Exposure lock",
1367
+ af: expert[2]?.name ?? "Focus lock",
1368
+ gridLevel: expert[5]?.name ?? "Grid and level"
1369
+ };
1310
1370
  }
1311
- var GROUP = {
1312
- ev: EXPERT[1]?.[0] ?? "EV compensation",
1313
- torch: EXPERT[3]?.[0] ?? "Torch level",
1314
- format: EXPERT[4]?.[0] ?? "Resolution and format",
1315
- ae: EXPERT[0]?.[0] ?? "Exposure lock",
1316
- af: EXPERT[2]?.[0] ?? "Focus lock",
1317
- gridLevel: EXPERT[5]?.[0] ?? "Grid and level"
1318
- };
1319
1371
  function Stop2({
1320
1372
  on,
1321
1373
  label,
1322
1374
  onPick
1323
1375
  }) {
1324
- const theme = useLoamTheme();
1376
+ const theme = useLoamTheme("viewfinder");
1325
1377
  const { styles } = useStyles(sequenceSheet, { on });
1326
1378
  return /* @__PURE__ */ jsx(
1327
1379
  Pressable,
@@ -1339,10 +1391,16 @@ function Stop2({
1339
1391
  function ExpertPanel({
1340
1392
  platform = "ios",
1341
1393
  values = {},
1394
+ labels,
1395
+ copy,
1342
1396
  onChange,
1343
1397
  onClose
1344
1398
  }) {
1345
- const theme = useLoamTheme();
1399
+ const t = useViewfinderLabels(labels);
1400
+ const words = useAnalyzerCopy(copy);
1401
+ const locale = useLoamLocale();
1402
+ const GROUP = groupNames(words.expert);
1403
+ const theme = useLoamTheme("viewfinder");
1346
1404
  const { styles } = useStyles(sequenceSheet);
1347
1405
  const {
1348
1406
  ev = 0,
@@ -1356,16 +1414,16 @@ function ExpertPanel({
1356
1414
  const toggles = [
1357
1415
  [GROUP.ae, aeLock, "aeLock"],
1358
1416
  [GROUP.af, afLock, "afLock"],
1359
- ["Level", level, "level"],
1360
- ["Grid", grid, "grid"]
1417
+ [t.level, level, "level"],
1418
+ [t.grid, grid, "grid"]
1361
1419
  ];
1362
- return /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: "Expert controls", style: styles.panel, children: [
1420
+ return /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: t.expertControls, style: styles.panel, children: [
1363
1421
  /* @__PURE__ */ jsxs(View, { style: styles.panelHead, children: [
1364
- /* @__PURE__ */ jsx(Text, { style: [styles.panelTitle, { color: camInk(theme) }], children: "Expert" }),
1365
- /* @__PURE__ */ jsx(View, { style: styles.panelHeadEnd, children: onClose ? /* @__PURE__ */ jsx(GlassIconButton, { icon: "x", label: "Close expert controls", onPress: onClose }) : null })
1422
+ /* @__PURE__ */ jsx(Text, { style: [styles.panelTitle, { color: camInk(theme) }], children: t.expert }),
1423
+ /* @__PURE__ */ jsx(View, { style: styles.panelHeadEnd, children: onClose ? /* @__PURE__ */ jsx(GlassIconButton, { icon: "x", label: t.closeExpert, onPress: onClose }) : null })
1366
1424
  ] }),
1367
1425
  /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: GROUP.ev, style: styles.group, children: [
1368
- /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, camMeta(theme)], children: GROUP.ev.toUpperCase() }),
1426
+ /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, camMeta(theme)], children: GROUP.ev.toLocaleUpperCase(locale) }),
1369
1427
  /* @__PURE__ */ jsx(
1370
1428
  ScrollView,
1371
1429
  {
@@ -1376,7 +1434,7 @@ function ExpertPanel({
1376
1434
  Stop2,
1377
1435
  {
1378
1436
  on: stop === ev,
1379
- label: evLabel(stop),
1437
+ label: evLabel(stop, locale),
1380
1438
  onPick: () => onChange?.({ control: "ev", value: stop })
1381
1439
  },
1382
1440
  stop
@@ -1385,24 +1443,24 @@ function ExpertPanel({
1385
1443
  )
1386
1444
  ] }),
1387
1445
  /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: GROUP.torch, style: styles.group, children: [
1388
- /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, camMeta(theme)], children: GROUP.torch.toUpperCase() }),
1446
+ /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, camMeta(theme)], children: GROUP.torch.toLocaleUpperCase(locale) }),
1389
1447
  /* @__PURE__ */ jsx(View, { style: styles.stopRow, children: ["off", "low", "high"].map((lvl) => /* @__PURE__ */ jsx(
1390
1448
  Stop2,
1391
1449
  {
1392
1450
  on: lvl === torch,
1393
- label: lvl,
1451
+ label: t.torchLevels[lvl],
1394
1452
  onPick: () => onChange?.({ control: "torch", value: lvl })
1395
1453
  },
1396
1454
  lvl
1397
1455
  )) })
1398
1456
  ] }),
1399
1457
  /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: GROUP.format, style: styles.group, children: [
1400
- /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, camMeta(theme)], children: GROUP.format.toUpperCase() }),
1458
+ /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, camMeta(theme)], children: GROUP.format.toLocaleUpperCase(locale) }),
1401
1459
  /* @__PURE__ */ jsx(View, { style: styles.stopRow, children: ["pipeline", "full"].map((f) => /* @__PURE__ */ jsx(
1402
1460
  Stop2,
1403
1461
  {
1404
1462
  on: f === format,
1405
- label: f === "pipeline" ? "Pipeline-native" : "Full sensor",
1463
+ label: t.formats[f],
1406
1464
  onPick: () => onChange?.({ control: "format", value: f })
1407
1465
  },
1408
1466
  f
@@ -1632,4 +1690,4 @@ var traySheet = createStyleSheet((theme) => ({
1632
1690
  }
1633
1691
  }));
1634
1692
 
1635
- export { ContinuousNotice, CountdownRing, EV_STOPS, ExpertPanel, FlipButton, FocusIndicator, FocusTapZone, GridOverlay, GridToggle, GuideOverlay, LensPicker, ScanLine, SequenceStrip, ShutterButton, ShutterTray, TorchToggle, TrackChip, TrackCountPill, TrackedBox, TrackingOverlay };
1693
+ export { ContinuousNotice, CountdownRing, EV_STOPS, ExpertPanel, FlipButton, FocusIndicator, FocusTapZone, GuideOverlay, LensPicker, ScanLine, SequenceStrip, ShutterButton, ShutterTray, TorchToggle, TrackChip, TrackCountPill, TrackedBox, TrackingOverlay, ViewfinderGridOverlay, ViewfinderGridToggle };