@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,12 +1,14 @@
1
- import { Textarea } from './chunk-BTTFCMKG.js';
2
- import { KeyboardSpacer } from './chunk-HPPW424V.js';
3
- import { Sheet } from './chunk-ZVFE5QGU.js';
4
- import { Badge } from './chunk-SBMNWWBV.js';
5
- import { Button } from './chunk-3ARE4TES.js';
6
- import { Icon } from './chunk-TKVFVF5D.js';
1
+ import { Textarea } from './chunk-74FLKD24.js';
2
+ import { KeyboardSpacer } from './chunk-XTORZWRF.js';
3
+ import { Sheet } from './chunk-QYPE5JX3.js';
4
+ import { Badge } from './chunk-TN2ZNJUI.js';
5
+ import { Button } from './chunk-E2E3I5W2.js';
6
+ import { useLabels, useLoamLocale } from './chunk-APCWFOZW.js';
7
+ import { Icon } from './chunk-UXGIW7OK.js';
8
+ import { useResolvedMotion, springConfig } from './chunk-J64KGCGX.js';
7
9
  import { iconNameOr } from '@btndprojects/loam-icons';
8
- import * as React from 'react';
9
- import { View, Text, Pressable, ScrollView } from 'react-native';
10
+ import * as React4 from 'react';
11
+ import { View, Text, Animated, Easing, Pressable, ScrollView } from 'react-native';
10
12
  import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
11
13
  import { nodeType, SEVERITIES, rule, RUN_STATES, flowStepWalk, nodeCount, runStateFor } from '@btndprojects/loam-workflow';
12
14
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -31,6 +33,75 @@ var FLOW_TONE_BADGE = {
31
33
  good: "good",
32
34
  "text-3": "neutral"
33
35
  };
36
+
37
+ // src/flow-run/flow-run-labels.ts
38
+ var FLOW_RUN_LABELS = {
39
+ failedAt: (name) => `Failed at ${name}.`,
40
+ failedBody: "The error edge is the one that fired, and the run continued along it \u2014 which is why the error path belongs in the graph rather than in node config.",
41
+ runLog: "Run log",
42
+ runLogEmpty: "Press Run. The canvas shows state; this pane shows time.",
43
+ duration: (ms) => `${ms}ms`,
44
+ stepLabel: (n, name, state, ms) => `Step ${n}: ${name}, ${state}, ${ms} milliseconds`,
45
+ failed: "failed",
46
+ running: "running",
47
+ succeeded: "succeeded",
48
+ stepList: "Flow steps",
49
+ preset: "Flow",
50
+ flowTitle: (preset) => `${preset} flow`,
51
+ stepCount: (count) => `${count} steps \xB7 read-only on a phone`,
52
+ run: "Run",
53
+ replay: "Replay",
54
+ openMap: "Open the map",
55
+ phoneNote: "Approving a run on a phone: yes. Rewiring sixteen nodes on a phone: no.",
56
+ stepName: (type, label, f) => `${type}: ${label}` + (f.decide ? " \u2014 waiting on you, tap to approve" : "") + (f.repeat ? " \u2014 repeats" : "") + (f.orphan ? " \u2014 not reachable from the trigger" : ""),
57
+ tapToDecide: "Tap to decide",
58
+ notReachable: "Not reachable",
59
+ note: "Note",
60
+ validation: "Validation",
61
+ decideApproval: "Decide this approval",
62
+ noteLabel: "Note (optional)",
63
+ configuration: "Configuration",
64
+ waitingOnYou: "Waiting on you",
65
+ reject: "Reject",
66
+ approve: "Approve"
67
+ };
68
+ function useFlowRunLabels(own) {
69
+ return useLabels("flowRun", FLOW_RUN_LABELS, own);
70
+ }
71
+ var DEFAULT_LABELS = {
72
+ nodeTypes: {},
73
+ severities: {},
74
+ rules: {},
75
+ issues: {},
76
+ runStates: {},
77
+ edgeKinds: {},
78
+ lanes: {},
79
+ routes: {}
80
+ };
81
+ function flowVocabulary(labels) {
82
+ return {
83
+ nodeLabel: (def) => labels.nodeTypes[def.id]?.label ?? def.label,
84
+ nodeBlurb: (def) => labels.nodeTypes[def.id]?.blurb ?? def.blurb,
85
+ configNote: (def, key, fallback) => labels.nodeTypes[def.id]?.config?.[key] ?? fallback,
86
+ portLabel: (def, portId, fallback) => labels.nodeTypes[def.id]?.ports?.[portId] ?? fallback,
87
+ severity: (sev, fallback) => labels.severities[sev] ?? fallback,
88
+ ruleWhy: (ruleId, fallback) => labels.rules[ruleId]?.why ?? fallback,
89
+ issue: (issue) => {
90
+ const fn = issue.code ? labels.issues[issue.code] : void 0;
91
+ return fn ? fn(issue.params ?? {}) : issue.msg;
92
+ },
93
+ runState: (state, fallback) => labels.runStates[state] ?? fallback,
94
+ edgeKind: (kind, fallback) => labels.edgeKinds[kind]?.label ?? fallback,
95
+ edgeKindBlurb: (kind, fallback) => labels.edgeKinds[kind]?.blurb ?? fallback,
96
+ laneLabel: (lane) => labels.lanes[lane.id]?.label ?? lane.label,
97
+ laneNote: (lane) => labels.lanes[lane.id]?.note ?? lane.note,
98
+ route: (style, fallback) => labels.routes[style] ?? fallback
99
+ };
100
+ }
101
+ function useFlowVocabulary(own) {
102
+ const labels = useLabels("flowVocabulary", DEFAULT_LABELS, own);
103
+ return React4.useMemo(() => flowVocabulary(labels), [labels]);
104
+ }
34
105
  function FlowApprovalSheet({
35
106
  node,
36
107
  type,
@@ -40,31 +111,43 @@ function FlowApprovalSheet({
40
111
  onOpenChange,
41
112
  detents = ["half", "full"],
42
113
  noteField = false,
43
- noteLabel = "Note (optional)",
114
+ noteLabel: noteLabelProp,
44
115
  noteValue,
45
116
  onNoteChange,
46
117
  noteError,
47
118
  safeAreaBottom = 0,
48
- rejectLabel = "Reject",
49
- approveLabel = "Approve",
119
+ rejectLabel: rejectLabelProp,
120
+ approveLabel: approveLabelProp,
50
121
  motion = "full",
122
+ loading = false,
123
+ notice,
51
124
  onDecide,
52
125
  onIntent,
53
126
  style,
54
- testID
127
+ testID,
128
+ labels: labelsProp,
129
+ vocabulary
55
130
  }) {
56
- const theme = useLoamTheme();
131
+ const theme = useLoamTheme("flow-run");
57
132
  const { styles } = useStyles(sheetStyles);
58
133
  const def = type ?? nodeType(node.type);
59
- const labelId = React.useId();
60
- const errorId = React.useId();
61
- const [internalNote, setInternalNote] = React.useState("");
134
+ const labels = useFlowRunLabels(labelsProp);
135
+ const v = useFlowVocabulary(vocabulary);
136
+ const noteLabel = noteLabelProp ?? labels.noteLabel;
137
+ const rejectLabel = rejectLabelProp ?? labels.reject;
138
+ const approveLabel = approveLabelProp ?? labels.approve;
139
+ const labelId = React4.useId();
140
+ const errorId = React4.useId();
141
+ const [internalNote, setInternalNote] = React4.useState("");
62
142
  const note = noteValue ?? internalNote;
63
143
  const setNote = (next) => {
64
144
  if (noteValue === void 0) setInternalNote(next);
65
145
  onNoteChange?.(next);
66
146
  };
147
+ const [chosen, setChosen] = React4.useState(null);
67
148
  const decide = (decision) => {
149
+ if (loading) return;
150
+ setChosen(decision);
68
151
  const trimmed = note.trim();
69
152
  onDecide?.(decision, trimmed || void 0);
70
153
  onIntent?.({
@@ -76,21 +159,13 @@ function FlowApprovalSheet({
76
159
  onOpenChange?.(false);
77
160
  };
78
161
  const body = /* @__PURE__ */ jsxs(View, { testID, style: [styles.body, style], children: [
79
- layout === "inline" ? /* @__PURE__ */ jsx(
80
- Text,
81
- {
82
- accessibilityRole: "header",
83
- style: styles.title,
84
- ...{ "aria-level": 2 },
85
- children: context.title
86
- }
87
- ) : null,
88
- /* @__PURE__ */ jsx(Text, { style: styles.eyebrow, children: def.label }),
162
+ layout === "inline" ? /* @__PURE__ */ jsx(Text, { accessibilityRole: "header", style: styles.title, ...{ "aria-level": 2 }, children: context.title }) : null,
163
+ /* @__PURE__ */ jsx(Text, { style: styles.eyebrow, children: v.nodeLabel(def) }),
89
164
  /* @__PURE__ */ jsxs(Text, { style: styles.nodeLine, children: [
90
165
  node.label,
91
166
  node.detail ? ` \xB7 ${node.detail}` : ""
92
167
  ] }),
93
- /* @__PURE__ */ jsx(Text, { style: styles.blurb, children: def.blurb }),
168
+ /* @__PURE__ */ jsx(Text, { style: styles.blurb, children: v.nodeBlurb(def) }),
94
169
  /* @__PURE__ */ jsx(View, { style: styles.context, children: typeof context.body === "string" ? /* @__PURE__ */ jsx(Text, { style: styles.contextText, children: context.body }) : context.body }),
95
170
  /* @__PURE__ */ jsxs(View, { style: styles.section, children: [
96
171
  /* @__PURE__ */ jsx(
@@ -99,15 +174,15 @@ function FlowApprovalSheet({
99
174
  accessibilityRole: "header",
100
175
  style: styles.eyebrow,
101
176
  ...{ "aria-level": 3 },
102
- children: "Configuration"
177
+ children: labels.configuration
103
178
  }
104
179
  ),
105
180
  def.config.map(([key, description]) => /* @__PURE__ */ jsxs(View, { style: styles.configRow, children: [
106
181
  /* @__PURE__ */ jsx(Text, { style: styles.configKey, children: key }),
107
- /* @__PURE__ */ jsx(Text, { style: styles.configValue, children: description })
182
+ /* @__PURE__ */ jsx(Text, { style: styles.configValue, children: v.configNote(def, key, description) })
108
183
  ] }, key))
109
184
  ] }),
110
- /* @__PURE__ */ jsxs(View, { style: styles.waiting, children: [
185
+ notice ? /* @__PURE__ */ jsxs(View, { style: styles.waiting, children: [
111
186
  /* @__PURE__ */ jsxs(View, { style: styles.waitingHead, children: [
112
187
  /* @__PURE__ */ jsx(
113
188
  Icon,
@@ -124,12 +199,12 @@ function FlowApprovalSheet({
124
199
  accessibilityRole: "header",
125
200
  style: styles.waitingEyebrow,
126
201
  ...{ "aria-level": 3 },
127
- children: "Waiting on you"
202
+ children: labels.waitingOnYou
128
203
  }
129
204
  )
130
205
  ] }),
131
- /* @__PURE__ */ jsx(Text, { style: styles.waitingBody, children: "Approve is recorded with your name, the time and what you were shown. Reject continues the run along the rejected edge." })
132
- ] }),
206
+ typeof notice === "string" ? /* @__PURE__ */ jsx(Text, { style: styles.waitingBody, children: notice }) : notice
207
+ ] }) : null,
133
208
  noteField ? /* @__PURE__ */ jsxs(View, { style: styles.section, children: [
134
209
  /* @__PURE__ */ jsx(Text, { nativeID: labelId, style: styles.fieldLabel, children: noteLabel }),
135
210
  /* @__PURE__ */ jsx(
@@ -155,6 +230,7 @@ function FlowApprovalSheet({
155
230
  fullWidth: true,
156
231
  leadingIcon: "x",
157
232
  accessibilityLabel: rejectLabel,
233
+ loading: loading && chosen === "rejected",
158
234
  onPress: () => decide("rejected"),
159
235
  children: rejectLabel
160
236
  }
@@ -167,6 +243,7 @@ function FlowApprovalSheet({
167
243
  fullWidth: true,
168
244
  leadingIcon: "check",
169
245
  accessibilityLabel: approveLabel,
246
+ loading: loading && chosen === "approved",
170
247
  onPress: () => decide("approved"),
171
248
  children: approveLabel
172
249
  }
@@ -313,17 +390,23 @@ function FlowStepSheet({
313
390
  onOpenChange,
314
391
  detents = ["half", "full"],
315
392
  canApprove = false,
316
- approveLabel = "Decide this approval",
393
+ approveLabel: approveLabelProp,
317
394
  onApprove,
318
395
  motion = "full",
319
396
  style,
320
- testID
397
+ testID,
398
+ labels: labelsProp,
399
+ vocabulary
321
400
  }) {
322
- const theme = useLoamTheme();
401
+ const theme = useLoamTheme("flow-run");
402
+ const labels = useFlowRunLabels(labelsProp);
403
+ const v = useFlowVocabulary(vocabulary);
404
+ const locale = useLoamLocale();
405
+ const approveLabel = approveLabelProp ?? labels.decideApproval;
323
406
  const def = type ?? (node ? nodeType(node.type) : null);
324
407
  const tone = def ? def.tone : "text-3";
325
408
  const { styles } = useStyles(sheetStyles2, { tone });
326
- const mine = React.useMemo(
409
+ const mine = React4.useMemo(
327
410
  () => node ? issues.filter((i) => i.node === node.id).slice().sort((a, b) => SEVERITIES[a.sev].rank - SEVERITIES[b.sev].rank) : [],
328
411
  [issues, node]
329
412
  );
@@ -340,7 +423,7 @@ function FlowStepSheet({
340
423
  strokeWidth: theme.icon.stroke
341
424
  }
342
425
  ) }),
343
- /* @__PURE__ */ jsx(Text, { style: styles.eyebrow, children: def.label })
426
+ /* @__PURE__ */ jsx(Text, { style: styles.eyebrow, children: v.nodeLabel(def) })
344
427
  ] }),
345
428
  layout === "inline" ? /* @__PURE__ */ jsx(
346
429
  Text,
@@ -351,8 +434,8 @@ function FlowStepSheet({
351
434
  children: node.label
352
435
  }
353
436
  ) : null,
354
- /* @__PURE__ */ jsx(Text, { style: styles.detail, children: node.detail || def.label.toLowerCase() }),
355
- /* @__PURE__ */ jsx(Text, { style: styles.blurb, children: def.blurb }),
437
+ /* @__PURE__ */ jsx(Text, { style: styles.detail, children: node.detail || v.nodeLabel(def).toLocaleLowerCase(locale) }),
438
+ /* @__PURE__ */ jsx(Text, { style: styles.blurb, children: v.nodeBlurb(def) }),
356
439
  /* @__PURE__ */ jsxs(View, { style: styles.section, children: [
357
440
  /* @__PURE__ */ jsx(
358
441
  Text,
@@ -360,25 +443,25 @@ function FlowStepSheet({
360
443
  accessibilityRole: "header",
361
444
  style: styles.eyebrow,
362
445
  ...{ "aria-level": 3 },
363
- children: "Configuration"
446
+ children: labels.configuration
364
447
  }
365
448
  ),
366
449
  def.config.map(([key, description]) => /* @__PURE__ */ jsxs(View, { style: styles.configRow, children: [
367
450
  /* @__PURE__ */ jsx(Text, { style: styles.configKey, children: key }),
368
- /* @__PURE__ */ jsx(Text, { style: styles.configValue, children: description })
451
+ /* @__PURE__ */ jsx(Text, { style: styles.configValue, children: v.configNote(def, key, description) })
369
452
  ] }, key))
370
453
  ] }),
371
- mine.length > 0 ? /* @__PURE__ */ jsxs(View, { accessibilityLabel: "Validation", style: styles.section, children: [
454
+ mine.length > 0 ? /* @__PURE__ */ jsxs(View, { accessibilityLabel: labels.validation, style: styles.section, children: [
372
455
  /* @__PURE__ */ jsx(
373
456
  Text,
374
457
  {
375
458
  accessibilityRole: "header",
376
459
  style: styles.eyebrow,
377
460
  ...{ "aria-level": 3 },
378
- children: "Validation"
461
+ children: labels.validation
379
462
  }
380
463
  ),
381
- mine.map((issue) => /* @__PURE__ */ jsx(IssueRow, { issue }, `${issue.rule}:${issue.msg}`))
464
+ mine.map((issue) => /* @__PURE__ */ jsx(IssueRow, { issue, v }, `${issue.rule}:${issue.msg}`))
382
465
  ] }) : null,
383
466
  human && canApprove && onApprove ? /* @__PURE__ */ jsx(
384
467
  Button,
@@ -405,13 +488,16 @@ function FlowStepSheet({
405
488
  }
406
489
  );
407
490
  }
408
- function IssueRow({ issue }) {
491
+ function IssueRow({
492
+ issue,
493
+ v
494
+ }) {
409
495
  const sev = SEVERITIES[issue.sev];
410
496
  const { styles } = useStyles(issueSheet, { sev: sev.tone });
411
- const why = rule(issue.rule)?.why;
497
+ const why = v.ruleWhy(issue.rule, rule(issue.rule)?.why);
412
498
  return /* @__PURE__ */ jsxs(View, { style: styles.box, children: [
413
- /* @__PURE__ */ jsx(Badge, { variant: FLOW_TONE_BADGE[sev.tone], size: "sm", leadingIcon: flowIconName(sev.icon), children: sev.label }),
414
- /* @__PURE__ */ jsx(Text, { style: styles.msg, children: issue.msg }),
499
+ /* @__PURE__ */ jsx(Badge, { variant: FLOW_TONE_BADGE[sev.tone], size: "sm", leadingIcon: flowIconName(sev.icon), children: v.severity(issue.sev, sev.label) }),
500
+ /* @__PURE__ */ jsx(Text, { style: styles.msg, children: v.issue(issue) }),
415
501
  why ? /* @__PURE__ */ jsx(Text, { style: styles.why, children: why }) : null
416
502
  ] });
417
503
  }
@@ -529,7 +615,7 @@ var issueSheet = createStyleSheet((theme) => ({
529
615
  }
530
616
  }));
531
617
  function useToneInk(tone) {
532
- const theme = useLoamTheme();
618
+ const theme = useLoamTheme("flow-run");
533
619
  switch (tone) {
534
620
  case "accent":
535
621
  return theme.color.accentOnSoft;
@@ -560,9 +646,46 @@ function FlowStepRow({
560
646
  onPress,
561
647
  accessibilityLabel,
562
648
  style,
563
- testID
649
+ testID,
650
+ motion = "full",
651
+ labels: labelsProp,
652
+ vocabulary
564
653
  }) {
565
- const theme = useLoamTheme();
654
+ const theme = useLoamTheme("flow-run");
655
+ const labels = useFlowRunLabels(labelsProp);
656
+ const v = useFlowVocabulary(vocabulary);
657
+ const locale = useLoamLocale();
658
+ const level = useResolvedMotion(motion, "flow-run");
659
+ const breathe = React4.useRef(new Animated.Value(1)).current;
660
+ React4.useEffect(() => {
661
+ if (runState !== "running" || level !== "full") {
662
+ breathe.setValue(1);
663
+ return;
664
+ }
665
+ const half = theme.loop.pulse / 2;
666
+ const easing = Easing.bezier(...theme.easing.inOut);
667
+ const loop = Animated.loop(
668
+ Animated.sequence([
669
+ Animated.timing(breathe, { toValue: 0.4, duration: half, easing, useNativeDriver: true }),
670
+ Animated.timing(breathe, { toValue: 1, duration: half, easing, useNativeDriver: true })
671
+ ])
672
+ );
673
+ loop.start();
674
+ return () => loop.stop();
675
+ }, [runState, level, theme.loop.pulse, theme.easing.inOut, breathe]);
676
+ const pop = React4.useRef(new Animated.Value(1)).current;
677
+ const prevRun = React4.useRef(runState);
678
+ React4.useEffect(() => {
679
+ const was = prevRun.current;
680
+ prevRun.current = runState;
681
+ if (runState !== "ok" || was === "ok" || level !== "full") return;
682
+ pop.setValue(0.5);
683
+ Animated.spring(pop, {
684
+ ...springConfig(theme, "fs"),
685
+ toValue: 1,
686
+ useNativeDriver: true
687
+ }).start();
688
+ }, [runState, level, pop, theme]);
566
689
  const def = type ?? nodeType(node.type);
567
690
  const human = def.kind === "human";
568
691
  const running = runState !== "idle";
@@ -570,8 +693,9 @@ function FlowStepRow({
570
693
  const glyph = running ? FLOW_RUN_STATE_ICON[runState] : flowIconName(def.icon);
571
694
  const { styles } = useStyles(sheet, { tone, note });
572
695
  const ink = useToneInk(tone);
573
- const detail = node.detail || def.label.toLowerCase();
574
- const name = accessibilityLabel ?? `${def.label}: ${node.label}` + (human && canDecide ? " \u2014 waiting on you, tap to approve" : "") + (repeat ? " \u2014 repeats" : "") + (orphan ? " \u2014 not reachable from the trigger" : "");
696
+ const typeName = v.nodeLabel(def);
697
+ const detail = node.detail || typeName.toLocaleLowerCase(locale);
698
+ const name = accessibilityLabel ?? labels.stepName(typeName, node.label, { decide: human && canDecide, repeat, orphan });
575
699
  return /* @__PURE__ */ jsxs(
576
700
  Pressable,
577
701
  {
@@ -589,7 +713,7 @@ function FlowStepRow({
589
713
  ],
590
714
  children: [
591
715
  /* @__PURE__ */ jsxs(View, { style: styles.rail, pointerEvents: "none", children: [
592
- /* @__PURE__ */ jsx(View, { style: styles.node, children: /* @__PURE__ */ jsx(Icon, { name: glyph, size: theme.icon.xs, color: ink, strokeWidth: theme.icon.stroke }) }),
716
+ /* @__PURE__ */ jsx(Animated.View, { style: [styles.node, { opacity: breathe, transform: [{ scale: pop }] }], children: /* @__PURE__ */ jsx(Icon, { name: glyph, size: theme.icon.xs, color: ink, strokeWidth: theme.icon.stroke }) }),
593
717
  last ? null : /* @__PURE__ */ jsx(View, { style: styles.connector })
594
718
  ] }),
595
719
  /* @__PURE__ */ jsxs(View, { style: styles.card, children: [
@@ -605,13 +729,13 @@ function FlowStepRow({
605
729
  strokeWidth: theme.icon.stroke
606
730
  }
607
731
  ) : null,
608
- running ? /* @__PURE__ */ jsx(Badge, { variant: FLOW_TONE_BADGE[tone], size: "sm", leadingIcon: glyph, children: RUN_STATES[runState].label }) : null,
609
- human && canDecide ? /* @__PURE__ */ jsx(Badge, { variant: "accent", size: "sm", leadingIcon: "user", children: "Tap to decide" }) : null,
610
- orphan ? /* @__PURE__ */ jsx(Badge, { variant: "danger", size: "sm", leadingIcon: "alert-triangle", children: "Not reachable" }) : null,
611
- note ? /* @__PURE__ */ jsx(Badge, { variant: "warn", size: "sm", leadingIcon: "edit", children: "Note" }) : null
732
+ running ? /* @__PURE__ */ jsx(Badge, { variant: FLOW_TONE_BADGE[tone], size: "sm", leadingIcon: glyph, children: v.runState(runState, RUN_STATES[runState].label) }) : null,
733
+ human && canDecide ? /* @__PURE__ */ jsx(Badge, { variant: "accent", size: "sm", leadingIcon: "user", children: labels.tapToDecide }) : null,
734
+ orphan ? /* @__PURE__ */ jsx(Badge, { variant: "danger", size: "sm", leadingIcon: "alert-triangle", children: labels.notReachable }) : null,
735
+ note ? /* @__PURE__ */ jsx(Badge, { variant: "warn", size: "sm", leadingIcon: "edit", children: labels.note }) : null
612
736
  ] }),
613
- /* @__PURE__ */ jsxs(Text, { numberOfLines: 1, style: styles.sub, children: [
614
- def.label,
737
+ /* @__PURE__ */ jsxs(Text, { numberOfLines: 2, style: styles.sub, children: [
738
+ typeName,
615
739
  " \xB7 ",
616
740
  detail
617
741
  ] })
@@ -633,40 +757,39 @@ function FlowStepList({
633
757
  graph,
634
758
  steps,
635
759
  run = null,
636
- presetLabel = "Flow",
760
+ presetLabel: presetLabelProp,
637
761
  canApprove = false,
638
- label = "Flow steps",
762
+ label: labelProp,
639
763
  safeAreaBottom = 0,
640
764
  onStepOpen,
641
765
  onOpenMap,
642
766
  onIntent,
643
767
  style,
644
- testID
768
+ testID,
769
+ labels: labelsProp,
770
+ vocabulary
645
771
  }) {
646
- const theme = useLoamTheme();
772
+ const theme = useLoamTheme("flow-run");
773
+ const labels = useFlowRunLabels(labelsProp);
774
+ const presetLabel = presetLabelProp ?? labels.preset;
775
+ const label = labelProp ?? labels.stepList;
647
776
  const { styles } = useStyles(listSheet);
648
- const walked = React.useMemo(() => steps ?? flowStepWalk(graph), [steps, graph]);
649
- const count = React.useMemo(() => nodeCount(graph), [graph]);
777
+ const walked = React4.useMemo(() => steps ?? flowStepWalk(graph), [steps, graph]);
778
+ const count = React4.useMemo(() => nodeCount(graph), [graph]);
650
779
  return /* @__PURE__ */ jsxs(View, { accessibilityLabel: label, testID, style: [styles.root, style], children: [
651
780
  /* @__PURE__ */ jsxs(View, { style: styles.header, children: [
652
781
  /* @__PURE__ */ jsxs(View, { style: styles.headerText, children: [
653
- /* @__PURE__ */ jsxs(
782
+ /* @__PURE__ */ jsx(
654
783
  Text,
655
784
  {
656
785
  accessibilityRole: "header",
657
786
  numberOfLines: 1,
658
787
  style: styles.title,
659
788
  ...{ "aria-level": 2 },
660
- children: [
661
- presetLabel,
662
- " flow"
663
- ]
789
+ children: labels.flowTitle(presetLabel)
664
790
  }
665
791
  ),
666
- /* @__PURE__ */ jsxs(Text, { numberOfLines: 1, style: styles.headerSub, children: [
667
- count,
668
- " steps \xB7 read-only on a phone"
669
- ] })
792
+ /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.headerSub, children: labels.stepCount(count) })
670
793
  ] }),
671
794
  /* @__PURE__ */ jsx(
672
795
  Button,
@@ -675,7 +798,7 @@ function FlowStepList({
675
798
  size: "sm",
676
799
  leadingIcon: run ? "refresh" : "play",
677
800
  onPress: () => onIntent?.({ t: "run" }),
678
- children: run ? "Replay" : "Run"
801
+ children: run ? labels.replay : labels.run
679
802
  }
680
803
  )
681
804
  ] }),
@@ -692,12 +815,14 @@ function FlowStepList({
692
815
  runState: run ? runStateFor(graph, run.trace, run.index, step.node.id) : "idle",
693
816
  canDecide: canApprove && step.type.kind === "human",
694
817
  last: i === walked.length - 1,
818
+ labels: labelsProp,
819
+ ...vocabulary ? { vocabulary } : {},
695
820
  ...onStepOpen ? { onPress: onStepOpen } : {}
696
821
  }
697
822
  ) }, step.key)) }),
698
823
  /* @__PURE__ */ jsxs(View, { style: [styles.footer, { paddingBottom: theme.space[12] + safeAreaBottom }], children: [
699
- onOpenMap ? /* @__PURE__ */ jsx(Button, { variant: "outline", size: "md", fullWidth: true, leadingIcon: "map-pin", onPress: onOpenMap, children: "Open the map" }) : null,
700
- /* @__PURE__ */ jsx(Text, { style: styles.footerNote, children: "Approving a run on a phone: yes. Rewiring sixteen nodes on a phone: no." })
824
+ onOpenMap ? /* @__PURE__ */ jsx(Button, { variant: "outline", size: "md", fullWidth: true, leadingIcon: "map-pin", onPress: onOpenMap, children: labels.openMap }) : null,
825
+ /* @__PURE__ */ jsx(Text, { style: styles.footerNote, children: labels.phoneNote })
701
826
  ] })
702
827
  ] });
703
828
  }
@@ -857,4 +982,4 @@ var listSheet = createStyleSheet((theme) => ({
857
982
  }
858
983
  }));
859
984
 
860
- export { FLOW_RUN_STATE_ICON, FLOW_TONE_BADGE, FlowApprovalSheet, FlowStepList, FlowStepRow, FlowStepSheet, flowIconName };
985
+ export { FLOW_RUN_STATE_ICON, FLOW_TONE_BADGE, FlowApprovalSheet, FlowStepList, FlowStepRow, FlowStepSheet, flowIconName, flowVocabulary, useFlowRunLabels, useFlowVocabulary };
@@ -1,6 +1,7 @@
1
- import { defaultRememberStorage } from './chunk-OPXFZ4Y5.js';
1
+ import { defaultRememberStorage } from './chunk-GDKVKNR2.js';
2
+ import { useLabels } from './chunk-APCWFOZW.js';
2
3
  import * as React from 'react';
3
- import { useWindowDimensions, Animated, Easing, PanResponder, Modal, View, StyleSheet, Pressable, Text, ScrollView } from 'react-native';
4
+ import { useWindowDimensions, Animated, Easing, PanResponder, Platform, findNodeHandle, AccessibilityInfo, Modal, View, StyleSheet, Pressable, Text, ScrollView } from 'react-native';
4
5
  import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
5
6
  import { jsx, jsxs } from 'react/jsx-runtime';
6
7
 
@@ -30,6 +31,11 @@ function SheetStackProvider({
30
31
  }
31
32
  return /* @__PURE__ */ jsx(SheetStackContext.Provider, { value, children });
32
33
  }
34
+ var DEFAULT_LABELS = {
35
+ close: "Close",
36
+ grabber: "Resize sheet",
37
+ detents: { peek: "peek", half: "half", full: "full" }
38
+ };
33
39
  function clamp(n, lo, hi) {
34
40
  return Math.max(lo, Math.min(hi, n));
35
41
  }
@@ -43,17 +49,20 @@ function Sheet({
43
49
  children,
44
50
  footer,
45
51
  safeAreaBottom = 0,
46
- closeLabel = "Close",
52
+ closeLabel,
47
53
  dismissible = true,
48
54
  detents,
49
- grabberLabel = "Resize sheet",
55
+ initialDetent,
56
+ grabberLabel,
57
+ labels: labelsProp,
50
58
  dismissFraction = DEFAULT_DISMISS_FRACTION,
51
59
  remember = false,
52
60
  rememberKey,
53
61
  storage = defaultRememberStorage,
54
62
  motion = "full"
55
63
  }) {
56
- const theme = useLoamTheme();
64
+ const theme = useLoamTheme("sheet");
65
+ const labels = useLabels("sheet", DEFAULT_LABELS, labelsProp);
57
66
  const { styles } = useStyles(sheet);
58
67
  const { height: windowHeight } = useWindowDimensions();
59
68
  const controlled = open !== void 0;
@@ -97,7 +106,7 @@ function Sheet({
97
106
  const n = raw == null ? NaN : Number(raw);
98
107
  if (Number.isInteger(n)) return n;
99
108
  }
100
- return 0;
109
+ return initialDetent ? Math.max(0, detentList.indexOf(initialDetent)) : 0;
101
110
  });
102
111
  const activeIndex = hasDetents ? clamp(detentIndex, 0, detentList.length - 1) : 0;
103
112
  const detentPx = React.useCallback(
@@ -353,6 +362,25 @@ function Sheet({
353
362
  const headerPan = !hasDetents && dismissible ? pan.panHandlers : {};
354
363
  const pushScale = pushAnim.interpolate({ inputRange: [0, 1], outputRange: [1, 0.955] });
355
364
  const pushLift = pushAnim.interpolate({ inputRange: [0, 1], outputRange: [0, -10] });
365
+ const titleRef = React.useRef(null);
366
+ const panelRef = React.useRef(null);
367
+ React.useEffect(() => {
368
+ if (!mounted || !actualOpen || Platform.OS === "web") return;
369
+ const node = titleRef.current ?? panelRef.current;
370
+ const tag = node ? findNodeHandle(node) : null;
371
+ if (tag !== null) AccessibilityInfo.setAccessibilityFocus(tag);
372
+ }, [mounted, actualOpen]);
373
+ const onGrabberKey = (event) => {
374
+ const last = detentList.length - 1;
375
+ let next = null;
376
+ if (event.key === "ArrowUp" || event.key === "ArrowRight") next = activeIndex + 1;
377
+ else if (event.key === "ArrowDown" || event.key === "ArrowLeft") next = activeIndex - 1;
378
+ else if (event.key === "Home") next = 0;
379
+ else if (event.key === "End") next = last;
380
+ if (next === null) return;
381
+ event.preventDefault?.();
382
+ commitDetent(next);
383
+ };
356
384
  const onDetentAction = (name) => {
357
385
  if (name === "increment") commitDetent(activeIndex + 1);
358
386
  else if (name === "decrement") commitDetent(activeIndex - 1);
@@ -375,7 +403,7 @@ function Sheet({
375
403
  {
376
404
  style: StyleSheet.absoluteFill,
377
405
  accessibilityRole: "button",
378
- accessibilityLabel: closeLabel,
406
+ accessibilityLabel: closeLabel ?? labels.close,
379
407
  onPress: requestDismiss
380
408
  }
381
409
  ) : null
@@ -384,6 +412,7 @@ function Sheet({
384
412
  /* @__PURE__ */ jsxs(
385
413
  Animated.View,
386
414
  {
415
+ ref: panelRef,
387
416
  role: "dialog",
388
417
  accessibilityViewIsModal: true,
389
418
  accessibilityLabel: title,
@@ -403,13 +432,15 @@ function Sheet({
403
432
  View,
404
433
  {
405
434
  accessibilityRole: "adjustable",
406
- accessibilityLabel: grabberLabel,
435
+ accessibilityLabel: grabberLabel ?? labels.grabber,
407
436
  "aria-valuemin": 0,
408
437
  "aria-valuemax": detentList.length - 1,
409
438
  "aria-valuenow": activeIndex,
410
- "aria-valuetext": detentList[activeIndex],
439
+ "aria-valuetext": detentList[activeIndex] ? labels.detents[detentList[activeIndex]] : void 0,
411
440
  accessibilityActions: [{ name: "increment" }, { name: "decrement" }],
412
441
  onAccessibilityAction: (e) => onDetentAction(e.nativeEvent.actionName),
442
+ focusable: true,
443
+ ...{ onKeyDown: onGrabberKey },
413
444
  style: styles.grabberHit,
414
445
  ...grabberPan.panHandlers,
415
446
  children: /* @__PURE__ */ jsx(View, { style: styles.handle })
@@ -419,7 +450,16 @@ function Sheet({
419
450
  // `role="heading"` + a cast `aria-level`, the idiom this repo
420
451
  // already uses in `calendar.tsx` — RN's own `accessibilityRole`
421
452
  // carries no level, and react-native-web needs the ARIA pair.
422
- /* @__PURE__ */ jsx(Text, { style: styles.title, role: "heading", ...{ "aria-level": titleLevel }, children: title })
453
+ /* @__PURE__ */ jsx(
454
+ Text,
455
+ {
456
+ ref: titleRef,
457
+ style: styles.title,
458
+ role: "heading",
459
+ ...{ "aria-level": titleLevel },
460
+ children: title
461
+ }
462
+ )
423
463
  ) : null
424
464
  ] }),
425
465
  /* @__PURE__ */ jsx(