@btndprojects/loam-ui-native 0.1.1 → 0.3.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 (412) hide show
  1. package/dist/accordion/index.js +7 -3
  2. package/dist/adaptive/index.js +16 -2
  3. package/dist/address-block/index.js +23 -0
  4. package/dist/alert/index.js +8 -2
  5. package/dist/analyzer/index.js +17 -6
  6. package/dist/announcement/index.js +18 -5
  7. package/dist/appearance-picker/index.js +15 -0
  8. package/dist/audio-player/index.js +29 -3
  9. package/dist/avatar/index.js +5 -2
  10. package/dist/avatar-group/index.js +9 -3
  11. package/dist/badge/index.js +10 -4
  12. package/dist/banner/index.js +6 -2
  13. package/dist/board/index.js +18 -6
  14. package/dist/button/index.js +9 -3
  15. package/dist/camera-permission/index.js +23 -12
  16. package/dist/capture-result/index.js +30 -17
  17. package/dist/card/index.js +10 -3
  18. package/dist/card-form/index.js +19 -9
  19. package/dist/carousel/index.js +6 -2
  20. package/dist/chart/index.js +18 -5
  21. package/dist/charts/index.js +21 -6
  22. package/dist/chat/index.js +41 -0
  23. package/dist/checkbox/index.js +9 -5
  24. package/dist/checklist/index.js +20 -8
  25. package/dist/checkout/index.js +30 -12
  26. package/dist/chip/index.js +11 -5
  27. package/dist/chunk-2BZD3NAP.js +1110 -0
  28. package/dist/chunk-2YKVID2V.js +35 -0
  29. package/dist/{chunk-JUAMLEHX.js → chunk-36DA3IPO.js} +137 -37
  30. package/dist/chunk-3A56MIAN.js +599 -0
  31. package/dist/chunk-3SCKCWF5.js +298 -0
  32. package/dist/chunk-3TZNDHKO.js +187 -0
  33. package/dist/chunk-43K3BLXV.js +9 -0
  34. package/dist/chunk-46ZJIQ2Z.js +208 -0
  35. package/dist/chunk-4CZMQDQL.js +192 -0
  36. package/dist/chunk-5DTKORLI.js +255 -0
  37. package/dist/{chunk-LOE5YNN3.js → chunk-5J4WFXFA.js} +68 -24
  38. package/dist/chunk-5KJ7TEQ6.js +305 -0
  39. package/dist/chunk-5NU33TXK.js +529 -0
  40. package/dist/chunk-5Z5ZYMOJ.js +1 -0
  41. package/dist/chunk-6KSUS7DF.js +690 -0
  42. package/dist/chunk-6RV6UW2J.js +349 -0
  43. package/dist/chunk-6RZM7RP2.js +520 -0
  44. package/dist/{chunk-4BXMXBJO.js → chunk-75BDCC7K.js} +24 -11
  45. package/dist/{chunk-PZXZJBMP.js → chunk-7CGJBQUA.js} +357 -32
  46. package/dist/{chunk-CJ5EOYZE.js → chunk-7IVF6JLJ.js} +24 -7
  47. package/dist/chunk-7IWCGXYA.js +143 -0
  48. package/dist/chunk-7LM4ASFH.js +172 -0
  49. package/dist/chunk-7MCEJFWV.js +341 -0
  50. package/dist/chunk-7NGMUVNU.js +245 -0
  51. package/dist/chunk-7PBSIXT7.js +355 -0
  52. package/dist/chunk-7QOYGENL.js +443 -0
  53. package/dist/{chunk-H6NIOQHK.js → chunk-A7SWYDE5.js} +66 -15
  54. package/dist/chunk-ADHPJALR.js +3051 -0
  55. package/dist/chunk-ALJYZLNQ.js +509 -0
  56. package/dist/chunk-APCWFOZW.js +28 -0
  57. package/dist/chunk-AQ5FIG74.js +419 -0
  58. package/dist/chunk-AWKQIE5I.js +139 -0
  59. package/dist/chunk-B2MMZZQB.js +426 -0
  60. package/dist/{chunk-ZVFE5QGU.js → chunk-B7JZ3N5G.js} +174 -97
  61. package/dist/chunk-BL37SW6G.js +1314 -0
  62. package/dist/chunk-BTRMA7GC.js +21 -0
  63. package/dist/chunk-C7IUWIUZ.js +643 -0
  64. package/dist/chunk-CA3DUVYD.js +10 -0
  65. package/dist/{chunk-S7F6XLTK.js → chunk-CBCJSO2B.js} +213 -54
  66. package/dist/chunk-CHPX4MFI.js +239 -0
  67. package/dist/chunk-CLGAMIOT.js +648 -0
  68. package/dist/chunk-CUE7VML6.js +1141 -0
  69. package/dist/chunk-CVU6S2E5.js +1587 -0
  70. package/dist/{chunk-AZRX6SAC.js → chunk-CXPQMA6Z.js} +112 -37
  71. package/dist/chunk-D2LN4I7I.js +581 -0
  72. package/dist/{chunk-UWFLYMAR.js → chunk-D34LNBO5.js} +635 -238
  73. package/dist/chunk-D4BCQICM.js +765 -0
  74. package/dist/chunk-EABKIIA4.js +1 -0
  75. package/dist/chunk-EICSYRAG.js +341 -0
  76. package/dist/chunk-EMWAJMAS.js +83 -0
  77. package/dist/chunk-EOLZWRV6.js +149 -0
  78. package/dist/chunk-EOQVTGB6.js +350 -0
  79. package/dist/{chunk-BEDBFJND.js → chunk-ESGUHNB2.js} +119 -43
  80. package/dist/{chunk-Q72LJOVE.js → chunk-F2KNBPKY.js} +74 -18
  81. package/dist/{chunk-O7AE6DAF.js → chunk-G7H3NX3G.js} +57 -24
  82. package/dist/chunk-GM7YIPB7.js +1052 -0
  83. package/dist/chunk-GVQQG435.js +581 -0
  84. package/dist/chunk-HE43OMEL.js +1056 -0
  85. package/dist/chunk-HHOMFQ7R.js +2535 -0
  86. package/dist/chunk-HJFFOOJ4.js +1 -0
  87. package/dist/chunk-HNAKS4Z3.js +207 -0
  88. package/dist/chunk-HP6ST2OW.js +352 -0
  89. package/dist/chunk-HW3OWDTU.js +1 -0
  90. package/dist/{chunk-3ENTMPQY.js → chunk-HZDB44K4.js} +102 -52
  91. package/dist/chunk-I2KLQ2HA.js +19 -0
  92. package/dist/chunk-I6CUP2LW.js +1155 -0
  93. package/dist/chunk-ICV4Y2WY.js +27 -0
  94. package/dist/chunk-IHSIENOE.js +3950 -0
  95. package/dist/{chunk-CUMUNPXY.js → chunk-IMMALLRU.js} +68 -32
  96. package/dist/chunk-J64KGCGX.js +55 -0
  97. package/dist/{chunk-IVNRBPGC.js → chunk-JA6TK7H2.js} +255 -84
  98. package/dist/{chunk-OOPPQH27.js → chunk-JAVZ5JPV.js} +83 -29
  99. package/dist/chunk-JCMTP3E4.js +1251 -0
  100. package/dist/{chunk-U7TFM2JA.js → chunk-JCXFFK64.js} +75 -18
  101. package/dist/chunk-JWCVBFDU.js +236 -0
  102. package/dist/chunk-JXRTD5RI.js +414 -0
  103. package/dist/chunk-JYIUZUIQ.js +1567 -0
  104. package/dist/chunk-K3TK3GIV.js +219 -0
  105. package/dist/chunk-KEVZIHM2.js +1511 -0
  106. package/dist/chunk-KHZDNQQD.js +171 -0
  107. package/dist/chunk-KL4GDV4V.js +131 -0
  108. package/dist/chunk-KNILMM4H.js +225 -0
  109. package/dist/chunk-KRBUZV45.js +25 -0
  110. package/dist/{chunk-ITTYJZWX.js → chunk-KXLDK6HB.js} +161 -45
  111. package/dist/chunk-KZ3X7TSL.js +196 -0
  112. package/dist/chunk-L2WMOA2V.js +474 -0
  113. package/dist/chunk-L4D5LHCH.js +109 -0
  114. package/dist/chunk-LAUJPLDB.js +853 -0
  115. package/dist/{chunk-SBMNWWBV.js → chunk-LGNTP5XA.js} +89 -17
  116. package/dist/chunk-LUZFCCSD.js +271 -0
  117. package/dist/{chunk-HPPW424V.js → chunk-LXJCP4PL.js} +129 -37
  118. package/dist/chunk-MCOZJWPU.js +731 -0
  119. package/dist/chunk-MG4SKWLL.js +2587 -0
  120. package/dist/chunk-MPEPTSER.js +414 -0
  121. package/dist/chunk-MWPJ4YGP.js +1 -0
  122. package/dist/{chunk-TKQYWZ5V.js → chunk-N7AX4OA4.js} +108 -41
  123. package/dist/chunk-NHSLM6SE.js +523 -0
  124. package/dist/chunk-NNCOFLNE.js +24 -0
  125. package/dist/{chunk-J7Q7VCVC.js → chunk-NNJLVA7M.js} +54 -15
  126. package/dist/chunk-NZG75DGA.js +282 -0
  127. package/dist/chunk-O76QXRBV.js +431 -0
  128. package/dist/chunk-OANH27AK.js +223 -0
  129. package/dist/chunk-OCHPK5YV.js +609 -0
  130. package/dist/chunk-OMHVEVX4.js +436 -0
  131. package/dist/{chunk-YF4NSSMT.js → chunk-ONKQUJWD.js} +220 -65
  132. package/dist/chunk-OVTK7A6T.js +615 -0
  133. package/dist/chunk-PCEFCOLN.js +120 -0
  134. package/dist/chunk-PFLNFIVB.js +186 -0
  135. package/dist/chunk-PHSZY37H.js +300 -0
  136. package/dist/chunk-PJLTKDVY.js +18 -0
  137. package/dist/{chunk-4YIP3CWS.js → chunk-PK7BN3MI.js} +89 -19
  138. package/dist/{chunk-KMI5ML5I.js → chunk-PWFRDRGS.js} +155 -29
  139. package/dist/chunk-PYPMD46W.js +707 -0
  140. package/dist/chunk-Q6CCHDI7.js +331 -0
  141. package/dist/chunk-QFA5WS2A.js +750 -0
  142. package/dist/chunk-QJMMM4RC.js +124 -0
  143. package/dist/chunk-QNZII37O.js +10 -0
  144. package/dist/chunk-QYWEVAM6.js +407 -0
  145. package/dist/chunk-R5T4VZ7Z.js +126 -0
  146. package/dist/chunk-R77HFLZD.js +1 -0
  147. package/dist/{chunk-YC6WORFL.js → chunk-RAESDNU5.js} +228 -102
  148. package/dist/chunk-RBYQUXNL.js +1 -0
  149. package/dist/chunk-RCM3DT5E.js +1 -0
  150. package/dist/chunk-RGNY56L7.js +282 -0
  151. package/dist/chunk-RIK6UX2K.js +344 -0
  152. package/dist/{chunk-LAECSR4H.js → chunk-RJA3RXO3.js} +75 -60
  153. package/dist/chunk-RJYRJ3LD.js +1 -0
  154. package/dist/chunk-RMA3NOY4.js +599 -0
  155. package/dist/{chunk-DM5QUKKO.js → chunk-RSWKKAHK.js} +160 -66
  156. package/dist/chunk-RVOIIX3V.js +204 -0
  157. package/dist/chunk-SA2RRBGT.js +1077 -0
  158. package/dist/chunk-SG3J4R45.js +1428 -0
  159. package/dist/chunk-SPUK7JD4.js +238 -0
  160. package/dist/chunk-SWXV2K5N.js +434 -0
  161. package/dist/chunk-SYJEPXP6.js +1303 -0
  162. package/dist/{chunk-N32RGOA5.js → chunk-SZLI34TA.js} +93 -28
  163. package/dist/{chunk-4GBOGOTV.js → chunk-T77WJA74.js} +143 -18
  164. package/dist/chunk-TDWWVJA4.js +630 -0
  165. package/dist/chunk-TFHI5XDR.js +610 -0
  166. package/dist/chunk-TH4PW2WU.js +17 -0
  167. package/dist/chunk-TTQ24HQX.js +12 -0
  168. package/dist/chunk-TUACVJNG.js +12 -0
  169. package/dist/{chunk-CYRBHQQZ.js → chunk-TUL5RUIA.js} +201 -59
  170. package/dist/{chunk-4ZAHCY44.js → chunk-TYOSA7JG.js} +74 -38
  171. package/dist/chunk-TYQTMMEV.js +1 -0
  172. package/dist/chunk-TZO6YDS7.js +346 -0
  173. package/dist/chunk-U3ETF22F.js +328 -0
  174. package/dist/chunk-U6BYHD2N.js +213 -0
  175. package/dist/{chunk-WSW6ZFAQ.js → chunk-UF6EJXPQ.js} +20 -5
  176. package/dist/chunk-UNNQIPGK.js +792 -0
  177. package/dist/chunk-UQEN55EY.js +1 -0
  178. package/dist/chunk-UQVO6AJV.js +171 -0
  179. package/dist/chunk-VFDQAAIW.js +351 -0
  180. package/dist/chunk-VIUE3VQT.js +1 -0
  181. package/dist/chunk-VJLSSSGC.js +438 -0
  182. package/dist/chunk-VLMT6KYT.js +350 -0
  183. package/dist/chunk-VMHGBUGS.js +35 -0
  184. package/dist/{chunk-7O2FMUPT.js → chunk-VQKPBYW6.js} +400 -139
  185. package/dist/{chunk-EJBDRVIH.js → chunk-VSSTWLC5.js} +61 -16
  186. package/dist/chunk-VZYYZRPN.js +1992 -0
  187. package/dist/chunk-W23G6JLF.js +37 -0
  188. package/dist/chunk-WAIJCD2V.js +480 -0
  189. package/dist/chunk-WFMQ3WKM.js +378 -0
  190. package/dist/chunk-WJ2KDRMY.js +66 -0
  191. package/dist/chunk-WKFZJO54.js +437 -0
  192. package/dist/{chunk-SYNOJOQO.js → chunk-WVVD3XOV.js} +189 -93
  193. package/dist/chunk-XAIWMSLB.js +1 -0
  194. package/dist/chunk-XBXUBBJZ.js +98 -0
  195. package/dist/chunk-XCU7MYBJ.js +1 -0
  196. package/dist/chunk-XHE4PGCI.js +717 -0
  197. package/dist/chunk-XRSJ32M3.js +331 -0
  198. package/dist/chunk-XTCVOEAW.js +1 -0
  199. package/dist/chunk-XWGXVQF6.js +58 -0
  200. package/dist/{chunk-35OFI3JG.js → chunk-Y3XKKO5K.js} +258 -123
  201. package/dist/chunk-Y4QNMBLO.js +533 -0
  202. package/dist/chunk-Y5H4CTKO.js +1 -0
  203. package/dist/chunk-YBQIN75A.js +403 -0
  204. package/dist/chunk-YJ5PXOX3.js +158 -0
  205. package/dist/{chunk-AWJOCGFZ.js → chunk-YLRSRUPS.js} +81 -55
  206. package/dist/chunk-YM6MPJ4A.js +1 -0
  207. package/dist/chunk-YV7KZENV.js +200 -0
  208. package/dist/chunk-Z7I4ZSO6.js +316 -0
  209. package/dist/chunk-ZIRMWD2B.js +555 -0
  210. package/dist/chunk-ZPMG3FWU.js +75 -0
  211. package/dist/{chunk-QWCMU5B2.js → chunk-ZTXMK2G7.js} +289 -115
  212. package/dist/chunk-ZVJCWXAL.js +541 -0
  213. package/dist/{chunk-P23EQNRQ.js → chunk-ZYQ23DPT.js} +215 -49
  214. package/dist/coachmark/index.js +10 -3
  215. package/dist/code-block/index.js +6 -3
  216. package/dist/color-field/index.js +15 -5
  217. package/dist/color-picker/index.js +23 -0
  218. package/dist/commerce/index.js +31 -17
  219. package/dist/confirm/index.js +31 -0
  220. package/dist/connection-card/index.js +34 -0
  221. package/dist/connectivity/index.js +6 -2
  222. package/dist/context-menu/index.js +13 -3
  223. package/dist/copy-button/index.js +5 -2
  224. package/dist/data-grid/index.js +35 -17
  225. package/dist/date-range-picker/index.js +22 -9
  226. package/dist/description-list/index.js +6 -1
  227. package/dist/device-frame/index.js +30 -0
  228. package/dist/dialog/index.js +10 -2
  229. package/dist/divider/index.js +2 -0
  230. package/dist/empty-state/index.js +15 -2
  231. package/dist/error-summary/index.js +9 -2
  232. package/dist/fab/index.js +7 -2
  233. package/dist/file-manager/index.js +44 -0
  234. package/dist/file-upload/index.js +16 -7
  235. package/dist/filter-bar/index.js +14 -7
  236. package/dist/flow-run/index.js +23 -13
  237. package/dist/form/index.js +32 -3
  238. package/dist/gallery/index.js +8 -2
  239. package/dist/hold-to-confirm/index.js +6 -2
  240. package/dist/hover-card/index.js +18 -0
  241. package/dist/icon-tile/index.js +10 -0
  242. package/dist/image/index.js +9 -0
  243. package/dist/index.d.ts +30789 -12332
  244. package/dist/index.js +424 -135
  245. package/dist/infinite-list/index.js +6 -2
  246. package/dist/inline-edit/index.js +8 -5
  247. package/dist/input/index.js +7 -4
  248. package/dist/interactions/index.js +5 -1
  249. package/dist/invoice/index.js +22 -9
  250. package/dist/job-row/index.js +22 -0
  251. package/dist/json-inspector/index.js +20 -0
  252. package/dist/kbd/index.js +5 -1
  253. package/dist/keyboard/index.js +9 -2
  254. package/dist/level-meter/index.js +9 -0
  255. package/dist/list-row/index.js +14 -4
  256. package/dist/log-viewer/index.js +11 -2
  257. package/dist/map-view/index.js +16 -3
  258. package/dist/markdown/index.js +12 -6
  259. package/dist/metric/index.js +10 -4
  260. package/dist/metric-strip/index.js +12 -0
  261. package/dist/money/index.js +16 -3
  262. package/dist/nav-drawer/index.js +8 -2
  263. package/dist/nav-header/index.js +15 -0
  264. package/dist/navigation/index.js +32 -2
  265. package/dist/notification-center/index.js +28 -12
  266. package/dist/number-roll/index.js +7 -2
  267. package/dist/onboarding-pager/index.js +22 -0
  268. package/dist/one-handed/index.js +5 -3
  269. package/dist/os-surfaces/index.js +9 -3
  270. package/dist/otp/index.js +9 -5
  271. package/dist/page-header/index.js +3 -1
  272. package/dist/pagination/index.js +8 -0
  273. package/dist/payment-method/index.js +21 -11
  274. package/dist/payment-status/index.js +26 -15
  275. package/dist/permission/index.js +21 -2
  276. package/dist/picker/index.js +22 -6
  277. package/dist/progress/index.js +11 -3
  278. package/dist/provenance/index.js +16 -0
  279. package/dist/pull-to-refresh/index.js +4 -2
  280. package/dist/qr-code/index.js +16 -0
  281. package/dist/query-builder/index.js +30 -0
  282. package/dist/radio-group/index.js +9 -5
  283. package/dist/rating/index.js +10 -2
  284. package/dist/receivables/index.js +35 -17
  285. package/dist/recording-indicator/index.js +21 -0
  286. package/dist/refund/index.js +28 -15
  287. package/dist/repeatable-rows/index.js +19 -0
  288. package/dist/save-status/index.js +7 -3
  289. package/dist/screen/index.js +3 -0
  290. package/dist/scroll-area/index.js +3 -1
  291. package/dist/search-field/index.js +13 -0
  292. package/dist/secret-field/index.js +19 -0
  293. package/dist/section-header/index.js +4 -0
  294. package/dist/segmented-control/index.js +4 -3
  295. package/dist/sheet/index.js +11 -3
  296. package/dist/shortcuts-sheet/index.js +2 -0
  297. package/dist/sign-in-screen/index.js +25 -0
  298. package/dist/skeleton/index.js +5 -1
  299. package/dist/slider/index.js +5 -2
  300. package/dist/sortable/index.js +8 -0
  301. package/dist/spinner/index.js +4 -1
  302. package/dist/split-button/index.js +21 -6
  303. package/dist/spotlight/index.js +9 -1
  304. package/dist/stack/index.js +2 -0
  305. package/dist/stage-timeline/index.js +8 -3
  306. package/dist/status-dot/index.js +8 -2
  307. package/dist/stepper/index.js +11 -4
  308. package/dist/streaming-text/index.js +4 -2
  309. package/dist/survey/index.js +29 -16
  310. package/dist/switch/index.js +9 -3
  311. package/dist/system-state/index.js +15 -4
  312. package/dist/tab-bar/index.js +13 -2
  313. package/dist/tabs/index.js +12 -2
  314. package/dist/tags-input/index.js +13 -0
  315. package/dist/text/index.js +4 -0
  316. package/dist/textarea/index.js +8 -5
  317. package/dist/thinking/index.js +6 -1
  318. package/dist/tile-rail/index.js +10 -0
  319. package/dist/time-field/index.js +20 -0
  320. package/dist/time-range-control/index.js +36 -0
  321. package/dist/timeline/index.js +4 -2
  322. package/dist/toast/index.js +6 -2
  323. package/dist/toolbar/index.js +5 -2
  324. package/dist/tour/index.js +15 -10
  325. package/dist/transcript/index.js +28 -0
  326. package/dist/truncation-notice/index.js +5 -2
  327. package/dist/update-notice/index.js +19 -9
  328. package/dist/video-player/index.js +29 -2
  329. package/dist/viewfinder/index.js +15 -5
  330. package/dist/widget/index.js +14 -4
  331. package/dist/wizard/index.js +10 -4
  332. package/package.json +13 -12
  333. package/dist/chunk-223Q2T2Q.js +0 -229
  334. package/dist/chunk-2A5NIQAK.js +0 -254
  335. package/dist/chunk-2GK6PHGE.js +0 -363
  336. package/dist/chunk-2ZZ7TDJ4.js +0 -324
  337. package/dist/chunk-3ARE4TES.js +0 -195
  338. package/dist/chunk-3NMD74ZU.js +0 -4
  339. package/dist/chunk-3WPW4KUN.js +0 -182
  340. package/dist/chunk-423B7SPN.js +0 -993
  341. package/dist/chunk-47FWHGUN.js +0 -394
  342. package/dist/chunk-4DS5ZWVC.js +0 -83
  343. package/dist/chunk-4SZYY6AN.js +0 -99
  344. package/dist/chunk-4YQOR7JM.js +0 -204
  345. package/dist/chunk-52X2VYTD.js +0 -228
  346. package/dist/chunk-5YNTNN5A.js +0 -177
  347. package/dist/chunk-6HT2LP62.js +0 -504
  348. package/dist/chunk-6N33LFQA.js +0 -35
  349. package/dist/chunk-6X6PQ443.js +0 -432
  350. package/dist/chunk-7CFF4HXS.js +0 -126
  351. package/dist/chunk-AI4DWZCD.js +0 -162
  352. package/dist/chunk-BTTFCMKG.js +0 -166
  353. package/dist/chunk-BV3B2HYZ.js +0 -1635
  354. package/dist/chunk-C2NTXVWM.js +0 -98
  355. package/dist/chunk-CDRZHT42.js +0 -424
  356. package/dist/chunk-DHWADYZX.js +0 -144
  357. package/dist/chunk-F5XNPWS7.js +0 -1024
  358. package/dist/chunk-FMYDDECK.js +0 -1521
  359. package/dist/chunk-GDKZTW34.js +0 -395
  360. package/dist/chunk-GL7B2DOW.js +0 -134
  361. package/dist/chunk-GNNJ4GCC.js +0 -471
  362. package/dist/chunk-HET4LLMX.js +0 -129
  363. package/dist/chunk-HZ6CNMAF.js +0 -870
  364. package/dist/chunk-IIQTAY3J.js +0 -715
  365. package/dist/chunk-JNH2TYIN.js +0 -96
  366. package/dist/chunk-JNY4ZHAR.js +0 -634
  367. package/dist/chunk-JXJB2X6M.js +0 -131
  368. package/dist/chunk-LRJNDEIA.js +0 -302
  369. package/dist/chunk-LSS54GLJ.js +0 -116
  370. package/dist/chunk-LZLHELAG.js +0 -137
  371. package/dist/chunk-MOUJOP55.js +0 -425
  372. package/dist/chunk-NKB7BZYK.js +0 -167
  373. package/dist/chunk-NQYBUO3K.js +0 -1795
  374. package/dist/chunk-O4AEHWII.js +0 -464
  375. package/dist/chunk-OETCUXQP.js +0 -134
  376. package/dist/chunk-OPXFZ4Y5.js +0 -204
  377. package/dist/chunk-PJXUJYS6.js +0 -248
  378. package/dist/chunk-PUPM2YGF.js +0 -376
  379. package/dist/chunk-QCDXZBC5.js +0 -247
  380. package/dist/chunk-QDYDBCFP.js +0 -197
  381. package/dist/chunk-QJJ6MADV.js +0 -274
  382. package/dist/chunk-QKXCPTFS.js +0 -349
  383. package/dist/chunk-RIBDXGUG.js +0 -108
  384. package/dist/chunk-RJQOOHT2.js +0 -214
  385. package/dist/chunk-RNGLIHFA.js +0 -191
  386. package/dist/chunk-RQ3HASCC.js +0 -6
  387. package/dist/chunk-RSOJT5YW.js +0 -124
  388. package/dist/chunk-RUZHTGKB.js +0 -237
  389. package/dist/chunk-RW6ZL2FQ.js +0 -284
  390. package/dist/chunk-TKVFVF5D.js +0 -95
  391. package/dist/chunk-TOXAGRDQ.js +0 -144
  392. package/dist/chunk-TUTI5HOZ.js +0 -112
  393. package/dist/chunk-UC2WGUP3.js +0 -627
  394. package/dist/chunk-UYG5L34B.js +0 -87
  395. package/dist/chunk-VBOXAEPI.js +0 -336
  396. package/dist/chunk-VCDBXW5H.js +0 -188
  397. package/dist/chunk-VEAYTRPX.js +0 -414
  398. package/dist/chunk-VQHPQEUH.js +0 -273
  399. package/dist/chunk-VXDZFJGP.js +0 -874
  400. package/dist/chunk-XNUVB5OL.js +0 -375
  401. package/dist/chunk-XOSCY2CW.js +0 -242
  402. package/dist/chunk-XXXEFXY5.js +0 -99
  403. package/dist/chunk-YDGVJETP.js +0 -60
  404. package/dist/chunk-YG3ZJHGU.js +0 -223
  405. package/dist/chunk-YTFKPRUK.js +0 -845
  406. package/dist/chunk-Z7H7VSFZ.js +0 -323
  407. package/dist/header/index.js +0 -5
  408. package/dist/search-bar/index.js +0 -5
  409. /package/dist/{chunk-3ECPOSKO.js → chunk-3BKLBYPK.js} +0 -0
  410. /package/dist/{chunk-JRLTGLN4.js → chunk-3UG6JUCV.js} +0 -0
  411. /package/dist/{chunk-RTIKSY6A.js → chunk-4QCR3K2J.js} +0 -0
  412. /package/dist/{chunk-VFCUIDRT.js → chunk-5WWRTEPS.js} +0 -0
@@ -1,16 +1,19 @@
1
- import { Slider } from './chunk-H6NIOQHK.js';
2
- import { Textarea } from './chunk-BTTFCMKG.js';
3
- import { Picker } from './chunk-NKB7BZYK.js';
4
- import { Progress } from './chunk-2ZZ7TDJ4.js';
5
- import { Sheet } from './chunk-ZVFE5QGU.js';
6
- import { Chip } from './chunk-AI4DWZCD.js';
7
- import { Input } from './chunk-ITTYJZWX.js';
8
- import { Button } from './chunk-3ARE4TES.js';
9
- import { Icon } from './chunk-TKVFVF5D.js';
1
+ import { Slider } from './chunk-A7SWYDE5.js';
2
+ import { storageKey, readStored, writeStored } from './chunk-NNCOFLNE.js';
3
+ import { Textarea } from './chunk-RIK6UX2K.js';
4
+ import { Progress } from './chunk-L2WMOA2V.js';
5
+ import { Chip } from './chunk-7NGMUVNU.js';
6
+ import { Picker } from './chunk-MCOZJWPU.js';
7
+ import { Sheet } from './chunk-B7JZ3N5G.js';
8
+ import { Button } from './chunk-5DTKORLI.js';
9
+ import { Input } from './chunk-KXLDK6HB.js';
10
+ import { useLabels } from './chunk-APCWFOZW.js';
11
+ import { Icon } from './chunk-PCEFCOLN.js';
12
+ import { useResolvedMotion, springConfig } from './chunk-J64KGCGX.js';
10
13
  import * as React2 from 'react';
11
- import { View, Text, Pressable } from 'react-native';
14
+ import { View, Text, Pressable, Image, Animated, Platform, findNodeHandle, AccessibilityInfo, BackHandler } from 'react-native';
12
15
  import { createStyleSheet, useStyles, useLoamTheme } from '@btndprojects/loam-theme-native';
13
- import { PMF_OPTIONS, scaleShape, resolveQuestion, resolveText, resolveHiddenFields, surveyPages, nextPageIndex, visibleQuestions, visiblePages, pickSurveyEnding, surveyCompletion, isQuestionRequired, isAnswerEmpty, prevPageIndex, npsBand, validatePage, branchedEndingId } from '@btndprojects/loam-engage';
16
+ import { PMF_OPTIONS, scaleShape, resolveQuestion, resolveText, resolveHiddenFields, surveyPages, nextPageIndex, visibleQuestions, visiblePages, pickSurveyEnding, surveyCompletion, isQuestionRequired, isAnswerEmpty, prevPageIndex, validatePage, branchedEndingId } from '@btndprojects/loam-engage';
14
17
  export { PMF_OPTIONS, SURVEY_OPERATORS, cesScore, csatScore, isAnswerEmpty, isPageVisible, matchSurveyCondition, nextPageIndex, npsBand, npsScore, prevPageIndex, scaleShape, surveyPages, surveyProgress, validatePage, visiblePages, visibleQuestions } from '@btndprojects/loam-engage';
15
18
  import { jsxs, jsx } from 'react/jsx-runtime';
16
19
 
@@ -27,7 +30,27 @@ var SURVEY_FIELD_LABELS = {
27
30
  rankHint: "Most important at the top",
28
31
  moveUp: "Move up",
29
32
  moveDown: "Move down",
30
- choosePlaceholder: "Choose one"
33
+ choosePlaceholder: "Choose one",
34
+ emailPlaceholder: "you@company.com",
35
+ datePlaceholder: "YYYY-MM-DD",
36
+ chooseFile: "Choose a file",
37
+ noFile: "No file chosen",
38
+ score: (value, top, ends) => `Score ${value} of ${top}${ends.map((end) => ` \u2014 ${end}`).join("")}`,
39
+ matrixScore: (row, value, points) => `${row}: ${value} of ${points}`,
40
+ selectedOfCap: (picked, cap) => `${picked} of up to ${cap} selected`,
41
+ answeredOf: (done, total) => `${done} / ${total} answered`
42
+ };
43
+ var SURVEY_LABELS = {
44
+ ...SURVEY_FIELD_LABELS,
45
+ back: "Back",
46
+ next: "Continue",
47
+ submit: "Send",
48
+ skip: "Skip",
49
+ close: "Close",
50
+ dismiss: "Dismiss survey",
51
+ doneTitle: "Thank you \u2014 logged.",
52
+ progress: (title, position, total) => `${title} \u2014 page ${position} of ${total}`,
53
+ validation: {}
31
54
  };
32
55
  var SURVEY_OTHER_PREFIX = "Other: ";
33
56
  function SurveyField({
@@ -35,37 +58,53 @@ function SurveyField({
35
58
  error,
36
59
  foot,
37
60
  labels: labelOverrides,
61
+ disabled = false,
38
62
  children
39
63
  }) {
40
64
  const { styles } = useStyles(sheet);
41
- const labels = { ...SURVEY_FIELD_LABELS, ...labelOverrides };
65
+ const theme = useLoamTheme("survey");
66
+ const labels = useLabels("survey", SURVEY_LABELS, labelOverrides);
42
67
  return (
43
68
  // No accessible name on the wrapper: the question text is a visible label
44
69
  // and every control below carries its own, so naming the group as well
45
70
  // makes the same sentence arrive twice.
46
- /* @__PURE__ */ jsxs(View, { style: styles.field, children: [
47
- /* @__PURE__ */ jsxs(View, { style: styles.labelRow, children: [
48
- /* @__PURE__ */ jsx(Text, { style: styles.label, children: question.text }),
49
- question.required ? /* @__PURE__ */ jsx(Text, { style: styles.requiredTag, children: labels.required }) : null
50
- ] }),
51
- question.help ? /* @__PURE__ */ jsx(Text, { style: styles.help, children: question.help }) : null,
52
- children,
53
- foot ? /* @__PURE__ */ jsx(View, { style: styles.foot, children: foot }) : null,
54
- error ? /* @__PURE__ */ jsx(SurveyFieldError, { children: error }) : null
55
- ] })
71
+ /* @__PURE__ */ jsxs(
72
+ View,
73
+ {
74
+ style: [styles.field, disabled ? { opacity: theme.state.disabledOpacity } : null],
75
+ "aria-disabled": disabled || void 0,
76
+ children: [
77
+ /* @__PURE__ */ jsxs(View, { style: styles.labelRow, children: [
78
+ /* @__PURE__ */ jsx(Text, { style: styles.label, children: question.text }),
79
+ question.required ? /* @__PURE__ */ jsx(Text, { style: styles.requiredTag, children: labels.required }) : null
80
+ ] }),
81
+ question.help ? /* @__PURE__ */ jsx(Text, { style: styles.help, children: question.help }) : null,
82
+ children,
83
+ foot ? /* @__PURE__ */ jsx(View, { style: styles.foot, children: foot }) : null,
84
+ error ? /* @__PURE__ */ jsx(SurveyFieldError, { children: error }) : null
85
+ ]
86
+ }
87
+ )
56
88
  );
57
89
  }
58
90
  function SurveyFieldError({ children }) {
59
- const theme = useLoamTheme();
91
+ const theme = useLoamTheme("survey");
60
92
  const { styles } = useStyles(sheet);
61
93
  return /* @__PURE__ */ jsxs(View, { accessibilityLiveRegion: "polite", style: styles.errorRow, children: [
62
94
  /* @__PURE__ */ jsx(Icon, { name: "alert-circle", size: theme.icon.xs, color: theme.color.danger }),
63
95
  /* @__PURE__ */ jsx(Text, { style: styles.errorText, children })
64
96
  ] });
65
97
  }
66
- function SurveyScale({ question, value, onChange }) {
67
- const theme = useLoamTheme();
98
+ function SurveyScale({
99
+ question,
100
+ value,
101
+ onChange,
102
+ labels: labelOverrides,
103
+ disabled = false
104
+ }) {
105
+ const theme = useLoamTheme("survey");
68
106
  const { styles } = useStyles(sheet);
107
+ const labels = useLabels("survey", SURVEY_LABELS, labelOverrides);
69
108
  const { count, from } = scaleShape(question);
70
109
  const top = from + count - 1;
71
110
  return /* @__PURE__ */ jsxs(View, { style: styles.stackSm, children: [
@@ -73,21 +112,23 @@ function SurveyScale({ question, value, onChange }) {
73
112
  const v = from + i;
74
113
  const on = value === v;
75
114
  const ends = [
76
- v === from && question.low ? ` \u2014 ${question.low}` : "",
77
- v === top && question.high ? ` \u2014 ${question.high}` : ""
78
- ].join("");
115
+ v === from && question.low ? question.low : "",
116
+ v === top && question.high ? question.high : ""
117
+ ].filter(Boolean);
79
118
  return /* @__PURE__ */ jsx(
80
119
  Pressable,
81
120
  {
82
121
  accessibilityRole: "radio",
83
- accessibilityState: { checked: on },
122
+ accessibilityState: { checked: on, disabled },
123
+ disabled,
84
124
  "aria-checked": on,
85
- accessibilityLabel: `Score ${v} of ${top}${ends}`,
125
+ accessibilityLabel: labels.score(v, top, ends),
86
126
  onPress: () => onChange(v, true),
87
127
  style: ({ pressed }) => [
88
128
  styles.scaleCell,
89
129
  on ? styles.scaleCellOn : null,
90
- pressed && !on ? { backgroundColor: theme.state.pressed } : null
130
+ pressed && !on ? { backgroundColor: theme.state.pressed } : null,
131
+ disabled ? { opacity: theme.state.disabledOpacity } : null
91
132
  ],
92
133
  children: /* @__PURE__ */ jsx(Text, { style: [styles.scaleNumber, on ? styles.scaleNumberOn : null], children: v })
93
134
  },
@@ -107,7 +148,7 @@ function SurveyOptionRow({
107
148
  role = "radio",
108
149
  disabled = false
109
150
  }) {
110
- const theme = useLoamTheme();
151
+ const theme = useLoamTheme("survey");
111
152
  const { styles } = useStyles(sheet);
112
153
  return /* @__PURE__ */ jsxs(
113
154
  Pressable,
@@ -124,8 +165,18 @@ function SurveyOptionRow({
124
165
  pressed && !checked ? { backgroundColor: theme.state.pressed } : null
125
166
  ],
126
167
  children: [
127
- /* @__PURE__ */ jsx(View, { style: [styles.mark, role === "checkbox" ? styles.markSquare : null, checked ? styles.markOn : null], children: checked ? role === "checkbox" ? /* @__PURE__ */ jsx(Icon, { name: "check", size: theme.icon.xs, color: theme.color.accentInk }) : /* @__PURE__ */ jsx(View, { style: styles.markDot }) : null }),
128
- /* @__PURE__ */ jsx(Text, { style: [styles.optionLabel, checked ? styles.optionLabelOn : null], children: label })
168
+ /* @__PURE__ */ jsx(
169
+ View,
170
+ {
171
+ style: [
172
+ styles.mark,
173
+ role === "checkbox" ? styles.markSquare : null,
174
+ checked ? styles.markOn : null
175
+ ],
176
+ children: checked ? role === "checkbox" ? /* @__PURE__ */ jsx(Icon, { name: "check", size: theme.icon.xs, color: theme.color.accentInk }) : /* @__PURE__ */ jsx(View, { style: styles.markDot }) : null
177
+ }
178
+ ),
179
+ /* @__PURE__ */ jsx(Text, { style: styles.optionLabel, children: label })
129
180
  ]
130
181
  }
131
182
  );
@@ -134,10 +185,12 @@ function SurveyOptions({
134
185
  question,
135
186
  value,
136
187
  onChange,
137
- labels: labelOverrides
188
+ labels: labelOverrides,
189
+ fieldSurface,
190
+ disabled = false
138
191
  }) {
139
192
  const { styles } = useStyles(sheet);
140
- const labels = { ...SURVEY_FIELD_LABELS, ...labelOverrides };
193
+ const labels = useLabels("survey", SURVEY_LABELS, labelOverrides);
141
194
  const options = question.options ?? (question.type === "pmf" ? PMF_RESOLVED : []);
142
195
  const raw = typeof value === "string" ? value : void 0;
143
196
  const isOther = Boolean(question.other && raw?.startsWith(SURVEY_OTHER_PREFIX));
@@ -147,6 +200,7 @@ function SurveyOptions({
147
200
  {
148
201
  label: o.label,
149
202
  checked: raw === o.value,
203
+ disabled,
150
204
  onPress: () => onChange(o.value, true)
151
205
  },
152
206
  o.value
@@ -156,6 +210,7 @@ function SurveyOptions({
156
210
  {
157
211
  label: labels.other,
158
212
  checked: isOther,
213
+ disabled,
159
214
  onPress: () => onChange(SURVEY_OTHER_PREFIX)
160
215
  }
161
216
  ) : null,
@@ -163,7 +218,9 @@ function SurveyOptions({
163
218
  Input,
164
219
  {
165
220
  size: "lg",
221
+ surface: fieldSurface,
166
222
  autoFocus: true,
223
+ editable: !disabled,
167
224
  placeholder: labels.otherPlaceholder,
168
225
  accessibilityLabel: `${question.text} \u2014 ${labels.other}`,
169
226
  value: (raw ?? SURVEY_OTHER_PREFIX).slice(SURVEY_OTHER_PREFIX.length),
@@ -172,14 +229,94 @@ function SurveyOptions({
172
229
  ) : null
173
230
  ] });
174
231
  }
175
- function SurveyCheckboxList({ question, value, onChange }) {
176
- const theme = useLoamTheme();
232
+ function SurveyImageChoice({
233
+ question,
234
+ value,
235
+ onChange,
236
+ disabled = false
237
+ }) {
238
+ const { styles } = useStyles(sheet);
239
+ const raw = typeof value === "string" ? value : void 0;
240
+ return /* @__PURE__ */ jsx(View, { style: styles.imageGrid, accessibilityRole: "radiogroup", children: (question.options ?? []).map((o) => {
241
+ const on = raw === o.value;
242
+ return /* @__PURE__ */ jsxs(
243
+ Pressable,
244
+ {
245
+ accessibilityRole: "radio",
246
+ accessibilityState: { checked: on, disabled },
247
+ "aria-checked": on,
248
+ accessibilityLabel: o.label,
249
+ disabled,
250
+ onPress: () => onChange(o.value, true),
251
+ style: [styles.imageCard, on ? styles.optionRowOn : null],
252
+ children: [
253
+ o.image ? /* @__PURE__ */ jsx(Image, { source: { uri: o.image }, accessibilityIgnoresInvertColors: true, style: styles.imageThumb }) : /* @__PURE__ */ jsx(View, { style: [styles.imageThumb, styles.imageThumbEmpty], children: /* @__PURE__ */ jsx(Text, { style: styles.imageThumbText, children: "Image" }) }),
254
+ /* @__PURE__ */ jsx(Text, { style: styles.optionLabel, children: o.label })
255
+ ]
256
+ },
257
+ o.value
258
+ );
259
+ }) });
260
+ }
261
+ function SurveyDate({
262
+ question,
263
+ value,
264
+ onChange,
265
+ error,
266
+ fieldSurface,
267
+ labels: labelOverrides,
268
+ disabled = false
269
+ }) {
270
+ const labels = useLabels("survey", SURVEY_LABELS, labelOverrides);
271
+ return /* @__PURE__ */ jsx(
272
+ Input,
273
+ {
274
+ size: "lg",
275
+ surface: fieldSurface,
276
+ accessibilityLabel: question.text,
277
+ keyboardType: "numbers-and-punctuation",
278
+ placeholder: question.placeholder ?? labels.datePlaceholder,
279
+ error: Boolean(error),
280
+ editable: !disabled,
281
+ value: value == null ? "" : String(value),
282
+ onChangeText: (next) => onChange(next.replace(/[^\d-]/g, "").slice(0, 10))
283
+ }
284
+ );
285
+ }
286
+ function SurveyFile({
287
+ value,
288
+ onPickFile,
289
+ labels: labelOverrides,
290
+ disabled = false
291
+ }) {
292
+ const { styles } = useStyles(sheet);
293
+ const labels = useLabels("survey", SURVEY_LABELS, labelOverrides);
294
+ const name = typeof value === "string" && value ? value : void 0;
295
+ return /* @__PURE__ */ jsxs(View, { style: styles.fileRow, children: [
296
+ /* @__PURE__ */ jsx(Button, { variant: "outline", leadingIcon: "upload", disabled, onPress: onPickFile, children: labels.chooseFile }),
297
+ /* @__PURE__ */ jsx(Text, { style: styles.metaText, numberOfLines: 1, children: name ?? labels.noFile })
298
+ ] });
299
+ }
300
+ function SurveyStatement({ question }) {
301
+ const { styles } = useStyles(sheet);
302
+ return /* @__PURE__ */ jsxs(View, { style: styles.statement, children: [
303
+ /* @__PURE__ */ jsx(Text, { style: styles.statementTitle, children: question.text }),
304
+ question.help ? /* @__PURE__ */ jsx(Text, { style: styles.metaText, children: question.help }) : null
305
+ ] });
306
+ }
307
+ function SurveyCheckboxList({
308
+ question,
309
+ value,
310
+ onChange,
311
+ disabled = false
312
+ }) {
313
+ const theme = useLoamTheme("survey");
177
314
  const { styles } = useStyles(sheet);
178
315
  const picked = Array.isArray(value) ? [...value] : [];
179
316
  const atCap = question.maxSelections != null && picked.length >= question.maxSelections;
180
317
  return /* @__PURE__ */ jsx(View, { style: styles.stackSm, children: (question.options ?? []).map((o) => {
181
318
  const on = picked.includes(o.value);
182
- const blocked = atCap && !on;
319
+ const blocked = disabled || atCap && !on;
183
320
  return /* @__PURE__ */ jsx(
184
321
  View,
185
322
  {
@@ -200,7 +337,12 @@ function SurveyCheckboxList({ question, value, onChange }) {
200
337
  );
201
338
  }) });
202
339
  }
203
- function SurveyChips({ question, value, onChange }) {
340
+ function SurveyChips({
341
+ question,
342
+ value,
343
+ onChange,
344
+ disabled = false
345
+ }) {
204
346
  const { styles } = useStyles(sheet);
205
347
  const picked = Array.isArray(value) ? [...value] : [];
206
348
  const atCap = question.maxSelections != null && picked.length >= question.maxSelections;
@@ -213,7 +355,7 @@ function SurveyChips({ question, value, onChange }) {
213
355
  size: "md",
214
356
  selectable: true,
215
357
  selected: on,
216
- disabled: !on && atCap,
358
+ disabled: disabled || !on && atCap,
217
359
  onSelectedChange: () => onChange(on ? picked.filter((p) => p !== o.value) : [...picked, o.value]),
218
360
  children: o.label
219
361
  },
@@ -225,10 +367,11 @@ function SurveyRank({
225
367
  question,
226
368
  value,
227
369
  onChange,
228
- labels: labelOverrides
370
+ labels: labelOverrides,
371
+ disabled = false
229
372
  }) {
230
373
  const { styles } = useStyles(sheet);
231
- const labels = { ...SURVEY_FIELD_LABELS, ...labelOverrides };
374
+ const labels = useLabels("survey", SURVEY_LABELS, labelOverrides);
232
375
  const declared = question.items ?? [];
233
376
  const labelOf = (v) => declared.find((x) => x.value === v)?.label ?? v;
234
377
  const items = Array.isArray(value) ? [...value] : declared.map((x) => x.value);
@@ -252,7 +395,7 @@ function SurveyRank({
252
395
  variant: "outline",
253
396
  leadingIcon: "chevron-up",
254
397
  accessibilityLabel: `${labels.moveUp}: ${labelOf(item)}`,
255
- disabled: i === 0,
398
+ disabled: disabled || i === 0,
256
399
  onPress: () => move(i, -1)
257
400
  }
258
401
  ),
@@ -263,48 +406,71 @@ function SurveyRank({
263
406
  variant: "outline",
264
407
  leadingIcon: "chevron-down",
265
408
  accessibilityLabel: `${labels.moveDown}: ${labelOf(item)}`,
266
- disabled: i === items.length - 1,
409
+ disabled: disabled || i === items.length - 1,
267
410
  onPress: () => move(i, 1)
268
411
  }
269
412
  )
270
413
  ] }, item)) });
271
414
  }
272
- function SurveyMatrix({ question, value, onChange }) {
273
- const theme = useLoamTheme();
415
+ function SurveyMatrix({
416
+ question,
417
+ value,
418
+ onChange,
419
+ labels: labelOverrides,
420
+ disabled = false
421
+ }) {
422
+ const theme = useLoamTheme("survey");
274
423
  const { styles } = useStyles(sheet);
424
+ const labels = useLabels("survey", SURVEY_LABELS, labelOverrides);
275
425
  const rows = question.rows ?? [];
276
426
  const points = question.points ?? 5;
277
427
  const current = value ?? {};
278
428
  return /* @__PURE__ */ jsx(View, { style: styles.stackMd, children: rows.map((row) => /* @__PURE__ */ jsxs(View, { style: styles.matrixCard, children: [
279
429
  /* @__PURE__ */ jsx(Text, { style: styles.matrixStatement, children: row.label }),
280
- /* @__PURE__ */ jsx(View, { accessibilityRole: "radiogroup", accessibilityLabel: row.label, style: styles.matrixRow, children: Array.from({ length: points }, (_, i) => i + 1).map((v) => {
281
- const on = current[row.value] === v;
282
- return /* @__PURE__ */ jsx(
283
- Pressable,
284
- {
285
- accessibilityRole: "radio",
286
- accessibilityState: { checked: on },
287
- "aria-checked": on,
288
- accessibilityLabel: `${row.label}: ${v} of ${points}`,
289
- onPress: () => onChange({ ...current, [row.value]: v }),
290
- style: ({ pressed }) => [
291
- styles.matrixCell,
292
- on ? styles.matrixCellOn : null,
293
- pressed && !on ? { backgroundColor: theme.state.pressed } : null
294
- ],
295
- children: /* @__PURE__ */ jsx(Text, { style: [styles.matrixNumber, on ? styles.scaleNumberOn : null], children: v })
296
- },
297
- v
298
- );
299
- }) }),
430
+ /* @__PURE__ */ jsx(
431
+ View,
432
+ {
433
+ accessibilityRole: "radiogroup",
434
+ accessibilityLabel: row.label,
435
+ style: styles.matrixRow,
436
+ children: Array.from({ length: points }, (_, i) => i + 1).map((v) => {
437
+ const on = current[row.value] === v;
438
+ return /* @__PURE__ */ jsx(
439
+ Pressable,
440
+ {
441
+ accessibilityRole: "radio",
442
+ accessibilityState: { checked: on, disabled },
443
+ "aria-checked": on,
444
+ disabled,
445
+ accessibilityLabel: labels.matrixScore(row.label, v, points),
446
+ onPress: () => onChange({ ...current, [row.value]: v }),
447
+ style: ({ pressed }) => [
448
+ styles.matrixScore,
449
+ on ? styles.matrixScoreOn : null,
450
+ pressed && !on ? { backgroundColor: theme.state.pressed } : null,
451
+ disabled ? { opacity: theme.state.disabledOpacity } : null
452
+ ],
453
+ children: /* @__PURE__ */ jsx(Text, { style: [styles.matrixNumber, on ? styles.scaleNumberOn : null], children: v })
454
+ },
455
+ v
456
+ );
457
+ })
458
+ }
459
+ ),
300
460
  /* @__PURE__ */ jsxs(View, { style: styles.endsRow, children: [
301
461
  /* @__PURE__ */ jsx(Text, { style: styles.endLabel, children: question.low }),
302
462
  /* @__PURE__ */ jsx(Text, { style: styles.endLabel, children: question.high })
303
463
  ] })
304
464
  ] }, row.value)) });
305
465
  }
306
- function SurveyConsent({ question, value, onChange, error }) {
307
- const theme = useLoamTheme();
466
+ function SurveyConsent({
467
+ question,
468
+ value,
469
+ onChange,
470
+ error,
471
+ disabled = false
472
+ }) {
473
+ const theme = useLoamTheme("survey");
308
474
  const { styles } = useStyles(sheet);
309
475
  const on = value === true;
310
476
  return /* @__PURE__ */ jsxs(View, { style: styles.stackSm, children: [
@@ -312,21 +478,31 @@ function SurveyConsent({ question, value, onChange, error }) {
312
478
  Pressable,
313
479
  {
314
480
  accessibilityRole: "checkbox",
315
- accessibilityState: { checked: on },
481
+ accessibilityState: { checked: on, disabled },
316
482
  "aria-checked": on,
317
483
  accessibilityLabel: question.text,
484
+ disabled,
318
485
  onPress: () => onChange(!on),
319
- style: [styles.consentCard, on ? styles.consentCardOn : null],
486
+ style: [
487
+ styles.consentCard,
488
+ on ? styles.consentCardOn : null,
489
+ disabled ? { opacity: theme.state.disabledOpacity } : null
490
+ ],
320
491
  children: [
321
492
  /* @__PURE__ */ jsx(View, { style: [styles.mark, styles.markSquare, on ? styles.markOn : null], children: on ? /* @__PURE__ */ jsx(Icon, { name: "check", size: theme.icon.xs, color: theme.color.accentInk }) : null }),
322
- /* @__PURE__ */ jsx(Text, { style: [styles.consentText, on ? styles.optionLabelOn : null], children: question.text })
493
+ /* @__PURE__ */ jsx(Text, { style: styles.consentText, children: question.text })
323
494
  ]
324
495
  }
325
496
  ),
326
497
  error ? /* @__PURE__ */ jsx(SurveyFieldError, { children: error }) : null
327
498
  ] });
328
499
  }
329
- function SurveySlider({ question, value, onChange }) {
500
+ function SurveySlider({
501
+ question,
502
+ value,
503
+ onChange,
504
+ disabled = false
505
+ }) {
330
506
  const { styles } = useStyles(sheet);
331
507
  const min = question.min ?? 0;
332
508
  const max = question.max ?? 100;
@@ -344,7 +520,8 @@ function SurveySlider({ question, value, onChange }) {
344
520
  step: question.step ?? 1,
345
521
  value: v,
346
522
  onValueChange: (next) => onChange(next),
347
- accessibilityLabel: question.text
523
+ accessibilityLabel: question.text,
524
+ disabled
348
525
  }
349
526
  ),
350
527
  /* @__PURE__ */ jsxs(View, { style: styles.endsRow, children: [
@@ -357,50 +534,83 @@ function SurveyBoolean({
357
534
  question,
358
535
  value,
359
536
  onChange,
360
- labels: labelOverrides
537
+ labels: labelOverrides,
538
+ disabled = false
361
539
  }) {
362
540
  const { styles } = useStyles(sheet);
363
- const labels = { ...SURVEY_FIELD_LABELS, ...labelOverrides };
364
- return /* @__PURE__ */ jsx(View, { style: styles.booleanRow, accessibilityRole: "radiogroup", accessibilityLabel: question.text, children: [[labels.yes, true], [labels.no, false]].map(([label, val]) => /* @__PURE__ */ jsx(View, { style: styles.grow, children: /* @__PURE__ */ jsx(
365
- Button,
541
+ const labels = useLabels("survey", SURVEY_LABELS, labelOverrides);
542
+ return /* @__PURE__ */ jsx(
543
+ View,
366
544
  {
367
- size: "lg",
368
- fullWidth: true,
369
- variant: value === val ? "primary" : "outline",
370
- accessibilityLabel: label,
371
- onPress: () => onChange(val, true),
372
- children: label
545
+ style: styles.booleanRow,
546
+ accessibilityRole: "radiogroup",
547
+ accessibilityLabel: question.text,
548
+ children: [
549
+ [labels.yes, true],
550
+ [labels.no, false]
551
+ ].map(([label, val]) => /* @__PURE__ */ jsx(View, { style: styles.grow, children: /* @__PURE__ */ jsx(
552
+ Button,
553
+ {
554
+ size: "lg",
555
+ fullWidth: true,
556
+ variant: value === val ? "primary" : "outline",
557
+ accessibilityLabel: label,
558
+ disabled,
559
+ onPress: () => onChange(val, true),
560
+ children: label
561
+ }
562
+ ) }, label))
373
563
  }
374
- ) }, label)) });
564
+ );
375
565
  }
376
- function SurveyOpenText({ question, value, onChange, error }) {
566
+ function SurveyOpenText({
567
+ question,
568
+ value,
569
+ onChange,
570
+ error,
571
+ fieldSurface,
572
+ disabled = false
573
+ }) {
377
574
  const text = typeof value === "string" ? value : "";
378
575
  return /* @__PURE__ */ jsx(
379
576
  Textarea,
380
577
  {
381
578
  accessibilityLabel: question.text,
579
+ surface: fieldSurface,
382
580
  placeholder: question.placeholder,
383
581
  maxLength: question.maxLength ?? 400,
384
582
  minRows: 3,
385
583
  error: Boolean(error),
584
+ disabled,
386
585
  value: text,
387
586
  onChangeText: (t) => onChange(t)
388
587
  }
389
588
  );
390
589
  }
391
- function SurveyTextInput({ question, value, onChange, error }) {
590
+ function SurveyTextInput({
591
+ question,
592
+ value,
593
+ onChange,
594
+ error,
595
+ fieldSurface,
596
+ labels: labelOverrides,
597
+ disabled = false
598
+ }) {
599
+ const labels = useLabels("survey", SURVEY_LABELS, labelOverrides);
392
600
  const t = question.type;
393
601
  const text = value == null ? "" : String(value);
394
602
  return /* @__PURE__ */ jsx(
395
603
  Input,
396
604
  {
397
605
  size: "lg",
606
+ surface: fieldSurface,
398
607
  accessibilityLabel: question.text,
399
608
  keyboardType: t === "number" ? "number-pad" : t === "email" ? "email-address" : "default",
400
609
  autoCapitalize: t === "email" ? "none" : "sentences",
401
610
  autoComplete: t === "email" ? "email" : void 0,
402
- placeholder: question.placeholder ?? (t === "email" ? "you@company.com" : void 0),
611
+ placeholder: question.placeholder ?? (t === "email" ? labels.emailPlaceholder : void 0),
403
612
  error: Boolean(error),
613
+ editable: !disabled,
404
614
  value: text,
405
615
  onChangeText: (next) => onChange(t === "number" ? next.replace(/[^\d.-]/g, "") : next)
406
616
  }
@@ -410,9 +620,11 @@ function SurveyDropdown({
410
620
  question,
411
621
  value,
412
622
  onChange,
413
- labels: labelOverrides
623
+ fieldSurface,
624
+ labels: labelOverrides,
625
+ disabled = false
414
626
  }) {
415
- const labels = { ...SURVEY_FIELD_LABELS, ...labelOverrides };
627
+ const labels = useLabels("survey", SURVEY_LABELS, labelOverrides);
416
628
  return /* @__PURE__ */ jsx(
417
629
  Picker,
418
630
  {
@@ -422,6 +634,8 @@ function SurveyDropdown({
422
634
  placeholder: question.placeholder ?? labels.choosePlaceholder,
423
635
  title: question.text,
424
636
  size: "lg",
637
+ surface: fieldSurface,
638
+ disabled,
425
639
  accessibilityLabel: question.text
426
640
  }
427
641
  );
@@ -440,14 +654,24 @@ function SurveyQuestionField({
440
654
  const props = { ...control, question };
441
655
  const { value, error, labels } = props;
442
656
  const t = question.type;
443
- const merged = { ...SURVEY_FIELD_LABELS, ...labels };
657
+ const merged = useLabels("survey", SURVEY_LABELS, labels);
444
658
  if (t === "consent") return /* @__PURE__ */ jsx(SurveyConsent, { ...props });
659
+ if (t === "statement") return /* @__PURE__ */ jsx(SurveyStatement, { ...props });
660
+ if (t === "image-choice") {
661
+ return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, disabled: props.disabled, children: /* @__PURE__ */ jsx(SurveyImageChoice, { ...props }) });
662
+ }
663
+ if (t === "date") {
664
+ return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, disabled: props.disabled, children: /* @__PURE__ */ jsx(SurveyDate, { ...props }) });
665
+ }
666
+ if (t === "file") {
667
+ return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, disabled: props.disabled, children: /* @__PURE__ */ jsx(SurveyFile, { ...props }) });
668
+ }
445
669
  const foot = (node) => node;
446
670
  if (t === "nps" || t === "csat" || t === "ces" || t === "scale") {
447
- return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, children: /* @__PURE__ */ jsx(SurveyScale, { ...props }) });
671
+ return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, disabled: props.disabled, children: /* @__PURE__ */ jsx(SurveyScale, { ...props }) });
448
672
  }
449
673
  if (t === "choice" || t === "pmf") {
450
- return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, children: /* @__PURE__ */ jsx(SurveyOptions, { ...props }) });
674
+ return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, disabled: props.disabled, children: /* @__PURE__ */ jsx(SurveyOptions, { ...props }) });
451
675
  }
452
676
  if (t === "multi" || t === "chips") {
453
677
  const picked = Array.isArray(value) ? value : [];
@@ -458,21 +682,22 @@ function SurveyQuestionField({
458
682
  question,
459
683
  error,
460
684
  labels,
685
+ disabled: props.disabled,
461
686
  foot: foot(
462
- cap ? /* @__PURE__ */ jsx(Text, { style: styles.metaText, children: t === "multi" ? `${picked.length} of up to ${cap} selected` : `${picked.length} / ${cap}` }) : null
687
+ cap ? /* @__PURE__ */ jsx(Text, { style: styles.metaText, children: t === "multi" ? merged.selectedOfCap(picked.length, cap) : `${picked.length} / ${cap}` }) : null
463
688
  ),
464
689
  children: t === "multi" ? /* @__PURE__ */ jsx(SurveyCheckboxList, { ...props }) : /* @__PURE__ */ jsx(SurveyChips, { ...props })
465
690
  }
466
691
  );
467
692
  }
468
693
  if (t === "dropdown") {
469
- return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, children: /* @__PURE__ */ jsx(SurveyDropdown, { ...props }) });
694
+ return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, disabled: props.disabled, children: /* @__PURE__ */ jsx(SurveyDropdown, { ...props }) });
470
695
  }
471
696
  if (t === "boolean") {
472
- return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, children: /* @__PURE__ */ jsx(SurveyBoolean, { ...props }) });
697
+ return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, disabled: props.disabled, children: /* @__PURE__ */ jsx(SurveyBoolean, { ...props }) });
473
698
  }
474
699
  if (t === "slider") {
475
- return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, children: /* @__PURE__ */ jsx(SurveySlider, { ...props }) });
700
+ return /* @__PURE__ */ jsx(SurveyField, { question, error, labels, disabled: props.disabled, children: /* @__PURE__ */ jsx(SurveySlider, { ...props }) });
476
701
  }
477
702
  if (t === "rank") {
478
703
  return /* @__PURE__ */ jsx(
@@ -481,6 +706,7 @@ function SurveyQuestionField({
481
706
  question,
482
707
  error,
483
708
  labels,
709
+ disabled: props.disabled,
484
710
  foot: /* @__PURE__ */ jsx(Text, { style: styles.metaText, children: merged.rankHint }),
485
711
  children: /* @__PURE__ */ jsx(SurveyRank, { ...props })
486
712
  }
@@ -494,12 +720,8 @@ function SurveyQuestionField({
494
720
  question,
495
721
  error,
496
722
  labels,
497
- foot: /* @__PURE__ */ jsxs(Text, { style: styles.metaText, children: [
498
- Object.keys(current).length,
499
- " / ",
500
- (question.rows ?? []).length,
501
- " answered"
502
- ] }),
723
+ disabled: props.disabled,
724
+ foot: /* @__PURE__ */ jsx(Text, { style: styles.metaText, children: merged.answeredOf(Object.keys(current).length, (question.rows ?? []).length) }),
503
725
  children: /* @__PURE__ */ jsx(SurveyMatrix, { ...props })
504
726
  }
505
727
  );
@@ -513,6 +735,7 @@ function SurveyQuestionField({
513
735
  question,
514
736
  error,
515
737
  labels,
738
+ disabled: props.disabled,
516
739
  foot: /* @__PURE__ */ jsxs(Text, { style: styles.metaText, children: [
517
740
  text.length,
518
741
  " / ",
@@ -528,33 +751,33 @@ function SurveyQuestionField({
528
751
  question,
529
752
  error,
530
753
  labels,
754
+ disabled: props.disabled,
531
755
  foot: question.suffix ? /* @__PURE__ */ jsx(Text, { style: styles.metaText, children: question.suffix }) : null,
532
756
  children: /* @__PURE__ */ jsx(SurveyTextInput, { ...props })
533
757
  }
534
758
  );
535
759
  }
536
760
  var sheet = createStyleSheet((theme) => ({
537
- field: { gap: theme.space[9] },
761
+ // Final 09 rhythm: help 4 below the question, the control 8 below.
762
+ field: { gap: theme.space[8] },
538
763
  labelRow: { flexDirection: "row", alignItems: "baseline", gap: theme.space[8] },
539
764
  label: {
540
765
  flexShrink: 1,
541
766
  fontFamily: theme.font.sans,
542
- fontWeight: theme.fontWeight.bold,
543
- fontSize: theme.type.callout.fontSize,
544
- lineHeight: theme.type.callout.lineHeight,
767
+ fontWeight: theme.fontWeight.semibold,
768
+ fontSize: theme.fontSize[16],
769
+ lineHeight: theme.fontSize[16] * 1.3,
545
770
  color: theme.color.text
546
771
  },
547
772
  requiredTag: {
773
+ ...theme.type.overline,
548
774
  fontFamily: theme.font.mono,
549
- fontSize: theme.type.caption2.fontSize,
550
- letterSpacing: theme.tracking.caps,
551
- textTransform: "uppercase",
552
775
  color: theme.color.text3
553
776
  },
554
777
  help: {
555
778
  fontFamily: theme.font.sans,
556
- fontSize: theme.type.footnote.fontSize,
557
- lineHeight: theme.type.footnote.lineHeight,
779
+ fontSize: theme.fontSize[12],
780
+ lineHeight: theme.fontSize[12] * 1.4,
558
781
  color: theme.color.text3,
559
782
  marginTop: -theme.space[4]
560
783
  },
@@ -567,12 +790,41 @@ var sheet = createStyleSheet((theme) => ({
567
790
  errorRow: { flexDirection: "row", alignItems: "center", gap: theme.space[7] },
568
791
  errorText: {
569
792
  fontFamily: theme.font.sans,
570
- fontWeight: theme.fontWeight.semibold,
571
- fontSize: theme.type.footnote.fontSize,
572
- color: theme.color.danger
793
+ fontSize: theme.fontSize[13],
794
+ color: theme.color.dangerOnSoft
573
795
  },
574
796
  stackXs: { gap: theme.space[6] },
575
797
  stackSm: { gap: theme.space[7] },
798
+ imageGrid: { flexDirection: "row", flexWrap: "wrap", gap: theme.space[8] },
799
+ imageCard: {
800
+ flexGrow: 1,
801
+ flexBasis: "45%",
802
+ gap: theme.space[8],
803
+ padding: theme.space[8],
804
+ borderRadius: theme.radius.md,
805
+ borderWidth: theme.borderWidth.thick,
806
+ borderColor: theme.color.borderStrong,
807
+ backgroundColor: theme.color.surface2
808
+ },
809
+ imageThumb: {
810
+ height: theme.space[80],
811
+ borderRadius: theme.radius.sm,
812
+ backgroundColor: theme.color.surface3
813
+ },
814
+ imageThumbEmpty: { alignItems: "center", justifyContent: "center" },
815
+ imageThumbText: {
816
+ fontFamily: theme.font.mono,
817
+ fontSize: theme.fontSize[12],
818
+ color: theme.color.text3
819
+ },
820
+ fileRow: { flexDirection: "row", alignItems: "center", gap: theme.space[12] },
821
+ statement: { gap: theme.space[4] },
822
+ statementTitle: {
823
+ fontFamily: theme.font.sans,
824
+ fontSize: theme.fontSize[16],
825
+ lineHeight: theme.fontSize[16] * 1.4,
826
+ color: theme.color.text
827
+ },
576
828
  stackMd: { gap: theme.space[12] },
577
829
  grow: { flex: 1 },
578
830
  scaleRow: { flexDirection: "row", gap: theme.space[4] },
@@ -605,17 +857,18 @@ var sheet = createStyleSheet((theme) => ({
605
857
  flexDirection: "row",
606
858
  alignItems: "center",
607
859
  gap: theme.space[11],
608
- minHeight: theme.tapMin + theme.space[4],
860
+ minHeight: theme.space[48],
609
861
  paddingHorizontal: theme.space[13],
610
862
  paddingVertical: theme.space[8],
611
863
  borderRadius: theme.radius.md,
612
- borderWidth: theme.borderWidth.thin,
864
+ borderWidth: theme.borderWidth.thick,
613
865
  borderColor: theme.color.borderStrong,
614
866
  backgroundColor: theme.color.surface2
615
867
  },
868
+ // Chosen: state-selected under a 1.5 accent edge; ink and weight kept (R7).
616
869
  optionRowOn: {
617
- borderColor: theme.edge.accent,
618
- backgroundColor: theme.color.accentSoft
870
+ borderColor: theme.focus.ringColor,
871
+ backgroundColor: theme.state.selected
619
872
  },
620
873
  optionLabel: {
621
874
  flex: 1,
@@ -623,7 +876,6 @@ var sheet = createStyleSheet((theme) => ({
623
876
  fontSize: theme.type.subheadline.fontSize,
624
877
  color: theme.color.text
625
878
  },
626
- optionLabelOn: { fontWeight: theme.fontWeight.bold, color: theme.color.accentOnSoft },
627
879
  mark: {
628
880
  width: theme.space[18],
629
881
  height: theme.space[18],
@@ -647,8 +899,8 @@ var sheet = createStyleSheet((theme) => ({
647
899
  alignItems: "center",
648
900
  gap: theme.space[10],
649
901
  minHeight: theme.tapMin + theme.space[4],
650
- paddingLeft: theme.space[12],
651
- paddingRight: theme.space[8],
902
+ paddingStart: theme.space[12],
903
+ paddingEnd: theme.space[8],
652
904
  paddingVertical: theme.space[6],
653
905
  borderRadius: theme.radius.md,
654
906
  borderWidth: theme.borderWidth.thin,
@@ -684,9 +936,10 @@ var sheet = createStyleSheet((theme) => ({
684
936
  color: theme.color.text
685
937
  },
686
938
  matrixRow: { flexDirection: "row", gap: theme.space[5] },
687
- matrixCell: {
939
+ matrixScore: {
688
940
  flex: 1,
689
- height: theme.space[40],
941
+ // Touch matrix cells are 44 (Final 09).
942
+ height: theme.space[44],
690
943
  alignItems: "center",
691
944
  justifyContent: "center",
692
945
  borderRadius: theme.radius.sm,
@@ -694,7 +947,7 @@ var sheet = createStyleSheet((theme) => ({
694
947
  borderColor: theme.color.borderStrong,
695
948
  backgroundColor: theme.color.surface
696
949
  },
697
- matrixCellOn: { borderColor: theme.color.accent, backgroundColor: theme.color.accent },
950
+ matrixScoreOn: { borderColor: theme.color.accent, backgroundColor: theme.color.accent },
698
951
  matrixNumber: {
699
952
  fontFamily: theme.font.mono,
700
953
  fontSize: theme.type.footnote.fontSize,
@@ -708,11 +961,11 @@ var sheet = createStyleSheet((theme) => ({
708
961
  gap: theme.space[11],
709
962
  padding: theme.space[12],
710
963
  borderRadius: theme.radius.md,
711
- borderWidth: theme.borderWidth.thin,
964
+ borderWidth: theme.borderWidth.thick,
712
965
  borderColor: theme.color.borderStrong,
713
966
  backgroundColor: theme.color.surface2
714
967
  },
715
- consentCardOn: { borderColor: theme.edge.accent, backgroundColor: theme.color.accentSoft },
968
+ consentCardOn: { borderColor: theme.focus.ringColor, backgroundColor: theme.state.selected },
716
969
  consentText: {
717
970
  flex: 1,
718
971
  fontFamily: theme.font.sans,
@@ -729,39 +982,41 @@ var sheet = createStyleSheet((theme) => ({
729
982
  fontVariant: ["tabular-nums"]
730
983
  }
731
984
  }));
732
- var DEFAULT_LABELS = {
733
- ...SURVEY_FIELD_LABELS,
734
- back: "Back",
735
- next: "Continue",
736
- submit: "Send",
737
- skip: "Skip",
738
- close: "Close",
739
- dismiss: "Dismiss survey",
740
- doneTitle: "Thank you \u2014 logged."
741
- };
742
985
  var TAP_TO_COMMIT = /* @__PURE__ */ new Set(["nps", "csat", "ces", "scale", "pmf", "boolean", "choice"]);
743
986
  function SurveyPager({ total, index }) {
744
- const theme = useLoamTheme();
987
+ const theme = useLoamTheme("survey");
745
988
  const { styles } = useStyles(sheetStyles);
746
- return /* @__PURE__ */ jsx(View, { accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", style: styles.pager, children: Array.from({ length: total }, (_, i) => /* @__PURE__ */ jsx(
989
+ return /* @__PURE__ */ jsx(
747
990
  View,
748
991
  {
749
- style: [
750
- styles.pagerDot,
751
- i === index ? { width: theme.space[16], backgroundColor: theme.color.accent } : { backgroundColor: i < index ? theme.color.text3 : theme.color.borderStrong }
752
- ]
753
- },
754
- i
755
- )) });
992
+ accessibilityElementsHidden: true,
993
+ importantForAccessibility: "no-hide-descendants",
994
+ style: styles.pager,
995
+ children: Array.from({ length: total }, (_, i) => /* @__PURE__ */ jsx(
996
+ View,
997
+ {
998
+ style: [
999
+ styles.pagerDot,
1000
+ i === index ? { width: theme.space[16], backgroundColor: theme.color.accent } : { backgroundColor: i < index ? theme.color.text3 : theme.color.borderStrong }
1001
+ ]
1002
+ },
1003
+ i
1004
+ ))
1005
+ }
1006
+ );
756
1007
  }
757
1008
  function SurveyDoneCard({
758
- title = "Thank you \u2014 logged.",
1009
+ title: titleProp,
759
1010
  body,
760
1011
  action,
761
1012
  onClose,
762
- closeLabel = "Close"
1013
+ closeLabel: closeLabelProp,
1014
+ labels: labelOverrides
763
1015
  }) {
764
- const theme = useLoamTheme();
1016
+ const labels = useLabels("survey", SURVEY_LABELS, labelOverrides);
1017
+ const title = titleProp ?? labels.doneTitle;
1018
+ const closeLabel = closeLabelProp ?? labels.close;
1019
+ const theme = useLoamTheme("survey");
765
1020
  const { styles } = useStyles(sheetStyles);
766
1021
  return /* @__PURE__ */ jsxs(View, { style: styles.doneBody, children: [
767
1022
  /* @__PURE__ */ jsxs(View, { style: styles.doneHead, children: [
@@ -784,23 +1039,32 @@ function Survey({
784
1039
  pageIndex: pageProp,
785
1040
  onPageIndexChange,
786
1041
  layout = "sheet",
1042
+ disabled = false,
1043
+ loading = false,
787
1044
  onSubmit,
788
1045
  onDismiss,
789
1046
  onAction,
790
1047
  onEvent,
791
- autoAdvance = true,
1048
+ autoAdvance = false,
1049
+ persistKey,
1050
+ storage,
792
1051
  autoCloseMs,
793
1052
  dismissible = true,
1053
+ showProgress = true,
1054
+ skippable = true,
794
1055
  locale,
795
1056
  hiddenFields,
796
1057
  metadata,
797
1058
  urlParams,
798
1059
  labels: labelOverrides,
799
- motion = "full"
1060
+ motion = "full",
1061
+ fieldSurface,
1062
+ density = "standard",
1063
+ size = "lg"
800
1064
  }) {
801
- const theme = useLoamTheme();
1065
+ const theme = useLoamTheme("survey");
802
1066
  const { styles } = useStyles(sheetStyles);
803
- const labels = React2.useMemo(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides]);
1067
+ const labels = useLabels("survey", SURVEY_LABELS, labelOverrides);
804
1068
  const fallbackLocale = survey.defaultLocale;
805
1069
  const t = React2.useCallback(
806
1070
  (value) => resolveText(value, locale, fallbackLocale),
@@ -808,23 +1072,68 @@ function Survey({
808
1072
  );
809
1073
  const ctx = React2.useMemo(
810
1074
  () => ({
811
- hidden: resolveHiddenFields(survey.hiddenFields, { supplied: hiddenFields, urlParams, metadata }),
1075
+ hidden: resolveHiddenFields(survey.hiddenFields, {
1076
+ supplied: hiddenFields,
1077
+ urlParams,
1078
+ metadata
1079
+ }),
812
1080
  metadata,
813
1081
  urlParams
814
1082
  }),
815
1083
  // eslint-disable-next-line react-hooks/exhaustive-deps
816
1084
  []
817
1085
  );
818
- const [uncontrolled, setUncontrolled] = React2.useState(defaultAnswers ?? {});
1086
+ const savedKey = persistKey ? storageKey("survey", persistKey) : void 0;
1087
+ const saved = React2.useMemo(
1088
+ () => savedKey ? readStored(storage, savedKey) : null,
1089
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1090
+ []
1091
+ );
1092
+ const [uncontrolled, setUncontrolled] = React2.useState(
1093
+ saved?.answers ?? defaultAnswers ?? {}
1094
+ );
819
1095
  const answers = answersProp ?? uncontrolled;
820
1096
  const pages = surveyPages(survey);
821
1097
  const firstPage = React2.useMemo(() => nextPageIndex(survey, answers, null, ctx), []);
822
- const [uncontrolledPage, setUncontrolledPage] = React2.useState(Math.max(0, firstPage));
1098
+ const [uncontrolledPage, setUncontrolledPage] = React2.useState(
1099
+ typeof saved?.page === "number" && saved.page >= 0 && saved.page < pages.length ? saved.page : Math.max(0, firstPage)
1100
+ );
823
1101
  const pageIdx = pageProp ?? uncontrolledPage;
1102
+ const level = useResolvedMotion(motion, "survey");
1103
+ const pageFade = React2.useRef(new Animated.Value(1)).current;
1104
+ const pageShift = React2.useRef(new Animated.Value(0)).current;
1105
+ const shownPage = React2.useRef(pageIdx);
1106
+ React2.useEffect(() => {
1107
+ if (shownPage.current === pageIdx) return;
1108
+ const direction = pageIdx > shownPage.current || pageIdx < 0 ? 1 : -1;
1109
+ shownPage.current = pageIdx;
1110
+ if (level === "none") return;
1111
+ pageFade.setValue(0);
1112
+ pageShift.setValue(level === "full" ? direction * theme.space.s6 : 0);
1113
+ Animated.parallel([
1114
+ Animated.spring(pageFade, {
1115
+ ...springConfig(theme, "de"),
1116
+ toValue: 1,
1117
+ useNativeDriver: true
1118
+ }),
1119
+ Animated.spring(pageShift, {
1120
+ ...springConfig(theme, "ds"),
1121
+ toValue: 0,
1122
+ useNativeDriver: true
1123
+ })
1124
+ ]).start();
1125
+ }, [pageIdx, level, pageFade, pageShift, theme]);
824
1126
  const page = pages[pageIdx];
825
1127
  const [errors, setErrors] = React2.useState({});
1128
+ const fieldRefs = React2.useRef(/* @__PURE__ */ new Map());
1129
+ const focusFirst = React2.useRef(null);
826
1130
  const [submitted, setSubmitted] = React2.useState(firstPage < 0);
827
1131
  const finished = submitted || pageIdx < 0;
1132
+ React2.useEffect(() => {
1133
+ if (!savedKey || !storage) return;
1134
+ if (finished) storage.removeItem?.(savedKey);
1135
+ else writeStored(storage, savedKey, { answers: uncontrolled, page: uncontrolledPage });
1136
+ }, [savedKey, storage, finished, uncontrolled, uncontrolledPage]);
828
1137
  const [trail, setTrail] = React2.useState([]);
829
1138
  const [endingId, setEndingId] = React2.useState(void 0);
830
1139
  const emit = React2.useCallback(
@@ -919,8 +1228,10 @@ function Survey({
919
1228
  [onSubmit, survey, ctx]
920
1229
  );
921
1230
  const advance = () => {
922
- const found = validatePage(page, answers, ctx, locale, fallbackLocale);
1231
+ if (disabled || loading) return;
1232
+ const found = validatePage(page, answers, ctx, locale, fallbackLocale, labels.validation);
923
1233
  if (Object.keys(found).length) {
1234
+ focusFirst.current = visibleQuestions(page, answers, ctx).find((q) => found[q.id])?.id ?? null;
924
1235
  setErrors(found);
925
1236
  emitRef.current("survey_validation_failed", {
926
1237
  page: page?.id,
@@ -936,12 +1247,24 @@ function Survey({
936
1247
  };
937
1248
  advanceRef.current = advance;
938
1249
  const back = () => {
1250
+ if (disabled || loading) return;
939
1251
  const previous = trail.length ? trail[trail.length - 1] : prevPageIndex(survey, answers, pageIdx, ctx);
940
1252
  if (previous < 0) return;
941
1253
  setTrail((t2) => t2.slice(0, -1));
942
1254
  setErrors({});
943
1255
  setPage(previous);
944
1256
  };
1257
+ React2.useEffect(() => {
1258
+ const id = focusFirst.current;
1259
+ focusFirst.current = null;
1260
+ const node = id ? fieldRefs.current.get(id) : null;
1261
+ if (!node) return;
1262
+ if (Platform.OS === "web") node.focus?.();
1263
+ else {
1264
+ const tag = findNodeHandle(node);
1265
+ if (tag != null) AccessibilityInfo.setAccessibilityFocus(tag);
1266
+ }
1267
+ }, [errors]);
945
1268
  const dismiss = React2.useCallback(
946
1269
  (reason) => {
947
1270
  if (reason !== "done") {
@@ -961,7 +1284,7 @@ function Survey({
961
1284
  );
962
1285
  const ending = pickSurveyEnding(survey, answers, ctx, endingId);
963
1286
  const doneCta = ending?.cta;
964
- const closeAfter = autoCloseMs ?? (doneCta ? 9e3 : 3400);
1287
+ const closeAfter = autoCloseMs ?? 0;
965
1288
  React2.useEffect(() => {
966
1289
  if (!finished || closeAfter <= 0) return;
967
1290
  const t2 = setTimeout(() => dismiss("done"), closeAfter);
@@ -972,86 +1295,157 @@ function Survey({
972
1295
  const allOptional = questions.length > 0 && questions.every((q) => !isQuestionRequired(q, answers, ctx) && isAnswerEmpty(q, answers[q.id]));
973
1296
  const isLast = nextPageIndex(survey, answers, pageIdx, ctx) < 0;
974
1297
  const canBack = trail.length > 0 || prevPageIndex(survey, answers, pageIdx, ctx) >= 0;
1298
+ const backRef = React2.useRef(null);
1299
+ backRef.current = !finished && open && canBack ? () => (back(), true) : null;
1300
+ React2.useEffect(() => {
1301
+ const sub = BackHandler.addEventListener(
1302
+ "hardwareBackPress",
1303
+ () => backRef.current?.() ?? false
1304
+ );
1305
+ return () => sub.remove();
1306
+ }, []);
975
1307
  const content = finished ? /* @__PURE__ */ jsxs(View, { style: styles.body, children: [
976
1308
  /* @__PURE__ */ jsx(Text, { style: styles.kicker, children: title }),
977
1309
  /* @__PURE__ */ jsx(
978
1310
  SurveyDoneCard,
979
1311
  {
980
1312
  title: t(ending?.title) ?? labels.doneTitle,
981
- body: t(ending?.body) ?? `Recorded against this account${typeof answers.nps === "number" ? ` as a ${npsBand(answers.nps)}` : ""}. You will not be asked this again for a while.`,
982
- action: doneCta ? /* @__PURE__ */ jsx(Button, { size: "md", variant: "outline", trailingIcon: "arrow-right", onPress: () => onAction?.(doneCta.action), children: t(doneCta.label) }) : null,
1313
+ body: t(ending?.body),
1314
+ action: doneCta ? /* @__PURE__ */ jsx(
1315
+ Button,
1316
+ {
1317
+ size: "md",
1318
+ variant: "outline",
1319
+ trailingIcon: "arrow-right",
1320
+ onPress: () => onAction?.(doneCta.action),
1321
+ children: t(doneCta.label)
1322
+ }
1323
+ ) : null,
983
1324
  onClose: () => dismiss("done"),
984
1325
  closeLabel: labels.close
985
1326
  }
986
1327
  )
987
- ] }) : /* @__PURE__ */ jsxs(View, { style: styles.body, children: [
988
- /* @__PURE__ */ jsxs(View, { style: styles.header, children: [
989
- /* @__PURE__ */ jsxs(View, { style: styles.headerText, children: [
990
- /* @__PURE__ */ jsx(Text, { style: styles.kicker, children: title }),
991
- page?.title ? /* @__PURE__ */ jsx(Text, { style: styles.pageTitle, children: t(page.title) }) : null
992
- ] }),
993
- answered.length > 1 ? /* @__PURE__ */ jsxs(Text, { style: styles.counter, children: [
994
- position,
995
- " / ",
996
- answered.length
997
- ] }) : null,
998
- dismissible ? /* @__PURE__ */ jsx(
999
- Pressable,
1000
- {
1001
- accessibilityRole: "button",
1002
- accessibilityLabel: labels.dismiss,
1003
- onPress: () => dismiss("user"),
1004
- hitSlop: theme.space[10],
1005
- style: styles.iconButton,
1006
- children: /* @__PURE__ */ jsx(Icon, { name: "x", size: theme.icon.sm, color: theme.color.text3 })
1007
- }
1008
- ) : null
1009
- ] }),
1010
- /* @__PURE__ */ jsx(
1011
- Progress,
1012
- {
1013
- size: "sm",
1014
- value: Math.max(0, position - 1),
1015
- max: Math.max(1, answered.length),
1016
- accessibilityLabel: `${title} \u2014 page ${position} of ${answered.length}`,
1017
- motion
1018
- }
1019
- ),
1020
- survey.intro && position === 1 ? /* @__PURE__ */ jsx(Text, { style: styles.intro, children: t(survey.intro) }) : null,
1021
- /* @__PURE__ */ jsx(View, { style: styles.questions, children: questions.map((q) => /* @__PURE__ */ jsx(
1022
- SurveyQuestionField,
1023
- {
1024
- question: q,
1025
- locale,
1026
- defaultLocale: fallbackLocale,
1027
- value: answers[q.id],
1028
- error: errors[q.id],
1029
- labels,
1030
- onChange: (value, commit) => setAnswer(q, value, commit)
1031
- },
1032
- q.id
1033
- )) }),
1034
- /* @__PURE__ */ jsxs(View, { style: styles.footer, children: [
1035
- canBack ? /* @__PURE__ */ jsx(Button, { size: "md", variant: "outline", leadingIcon: "arrow-left", onPress: back, children: labels.back }) : null,
1036
- answered.length > 1 ? /* @__PURE__ */ jsx(SurveyPager, { total: answered.length, index: position - 1 }) : /* @__PURE__ */ jsx(View, { style: styles.grow }),
1037
- allOptional && answered.length > 1 ? /* @__PURE__ */ jsx(
1038
- Button,
1039
- {
1040
- size: "md",
1041
- variant: "ghost",
1042
- onPress: () => {
1043
- emitRef.current("survey_page_skipped", { page: page?.id });
1044
- setTrail((t2) => [...t2, pageIdx]);
1045
- const next = nextPageIndex(survey, answers, pageIdx);
1046
- if (next < 0) finish(answers);
1047
- else setPage(next);
1048
- },
1049
- children: labels.skip
1050
- }
1051
- ) : null,
1052
- /* @__PURE__ */ jsx(Button, { size: "lg", variant: "primary", onPress: advance, children: isLast ? labels.submit : labels.next })
1053
- ] })
1054
- ] });
1328
+ ] }) : /* @__PURE__ */ jsxs(
1329
+ View,
1330
+ {
1331
+ style: [styles.body, density === "compact" ? styles.bodyCompact : null],
1332
+ "aria-busy": loading || void 0,
1333
+ children: [
1334
+ /* @__PURE__ */ jsxs(View, { style: styles.header, children: [
1335
+ /* @__PURE__ */ jsxs(View, { style: styles.headerText, children: [
1336
+ /* @__PURE__ */ jsx(Text, { style: styles.kicker, children: title }),
1337
+ page?.title ? /* @__PURE__ */ jsx(Text, { style: styles.pageTitle, children: t(page.title) }) : null
1338
+ ] }),
1339
+ showProgress && answered.length > 1 ? /* @__PURE__ */ jsxs(Text, { style: styles.counter, children: [
1340
+ position,
1341
+ " / ",
1342
+ answered.length
1343
+ ] }) : null,
1344
+ dismissible ? /* @__PURE__ */ jsx(
1345
+ Pressable,
1346
+ {
1347
+ accessibilityRole: "button",
1348
+ accessibilityLabel: labels.dismiss,
1349
+ onPress: () => dismiss("user"),
1350
+ hitSlop: (theme.hit.sm - theme.ctl.sm) / 2,
1351
+ style: ({ pressed }) => [
1352
+ styles.iconButton,
1353
+ pressed && { backgroundColor: theme.state.pressed }
1354
+ ],
1355
+ children: /* @__PURE__ */ jsx(Icon, { name: "x", size: theme.icon.sm, color: theme.color.text3 })
1356
+ }
1357
+ ) : null
1358
+ ] }),
1359
+ showProgress ? /* @__PURE__ */ jsx(
1360
+ Progress,
1361
+ {
1362
+ size: "sm",
1363
+ value: Math.max(0, position - 1),
1364
+ max: Math.max(1, answered.length),
1365
+ accessibilityLabel: labels.progress(title, position, answered.length),
1366
+ motion
1367
+ }
1368
+ ) : null,
1369
+ survey.intro && position === 1 ? /* @__PURE__ */ jsx(Text, { style: styles.intro, children: t(survey.intro) }) : null,
1370
+ /* @__PURE__ */ jsx(
1371
+ Animated.View,
1372
+ {
1373
+ style: [
1374
+ styles.questions,
1375
+ density === "compact" ? styles.questionsCompact : null,
1376
+ { opacity: pageFade, transform: [{ translateX: pageShift }] }
1377
+ ],
1378
+ children: questions.map((q) => /* @__PURE__ */ jsx(
1379
+ View,
1380
+ {
1381
+ ref: (node) => {
1382
+ fieldRefs.current.set(q.id, node);
1383
+ },
1384
+ ...{ tabIndex: -1 },
1385
+ children: /* @__PURE__ */ jsx(
1386
+ SurveyQuestionField,
1387
+ {
1388
+ question: q,
1389
+ locale,
1390
+ defaultLocale: fallbackLocale,
1391
+ value: answers[q.id],
1392
+ error: errors[q.id],
1393
+ labels,
1394
+ fieldSurface,
1395
+ disabled,
1396
+ onChange: (value, commit) => setAnswer(q, value, commit)
1397
+ }
1398
+ )
1399
+ },
1400
+ q.id
1401
+ ))
1402
+ }
1403
+ ),
1404
+ /* @__PURE__ */ jsxs(View, { style: styles.footer, children: [
1405
+ canBack ? /* @__PURE__ */ jsx(
1406
+ Button,
1407
+ {
1408
+ size,
1409
+ variant: "outline",
1410
+ leadingIcon: "arrow-left",
1411
+ disabled,
1412
+ onPress: back,
1413
+ children: labels.back
1414
+ }
1415
+ ) : null,
1416
+ /* @__PURE__ */ jsx(View, { style: styles.grow }),
1417
+ skippable && allOptional && answered.length > 1 ? /* @__PURE__ */ jsx(
1418
+ Button,
1419
+ {
1420
+ size,
1421
+ variant: "ghost",
1422
+ disabled,
1423
+ onPress: () => {
1424
+ if (loading) return;
1425
+ emitRef.current("survey_page_skipped", { page: page?.id });
1426
+ setTrail((t2) => [...t2, pageIdx]);
1427
+ const next = nextPageIndex(survey, answers, pageIdx);
1428
+ if (next < 0) finish(answers);
1429
+ else setPage(next);
1430
+ },
1431
+ children: labels.skip
1432
+ }
1433
+ ) : null,
1434
+ /* @__PURE__ */ jsx(
1435
+ Button,
1436
+ {
1437
+ size,
1438
+ variant: "primary",
1439
+ disabled,
1440
+ loading,
1441
+ onPress: advance,
1442
+ children: isLast ? labels.submit : labels.next
1443
+ }
1444
+ )
1445
+ ] })
1446
+ ]
1447
+ }
1448
+ );
1055
1449
  if (layout === "inline") return content;
1056
1450
  return /* @__PURE__ */ jsx(
1057
1451
  Sheet,
@@ -1067,33 +1461,35 @@ function Survey({
1067
1461
  }
1068
1462
  var sheetStyles = createStyleSheet((theme) => ({
1069
1463
  body: { gap: theme.space[16] },
1464
+ bodyCompact: { gap: theme.space[12] },
1070
1465
  header: { flexDirection: "row", alignItems: "center", gap: theme.space[9] },
1071
1466
  headerText: { flex: 1, gap: theme.space[2] },
1072
1467
  kicker: {
1468
+ ...theme.type.overline,
1073
1469
  fontFamily: theme.font.mono,
1074
- fontSize: theme.type.caption2.fontSize,
1075
- letterSpacing: theme.tracking.caps,
1076
- textTransform: "uppercase",
1077
1470
  color: theme.color.accentStrong
1078
1471
  },
1079
1472
  pageTitle: {
1080
1473
  fontFamily: theme.font.sans,
1081
- fontWeight: theme.fontWeight.bold,
1474
+ fontWeight: theme.fontWeight.semibold,
1082
1475
  fontSize: theme.type.subheadline.fontSize,
1083
1476
  color: theme.color.text
1084
1477
  },
1478
+ // Count style: mono 12 / 500, text-2.
1085
1479
  counter: {
1086
1480
  fontFamily: theme.font.mono,
1087
- fontSize: theme.type.caption2.fontSize,
1088
- color: theme.color.text3,
1481
+ fontWeight: theme.fontWeight.medium,
1482
+ fontSize: theme.fontSize[12],
1483
+ color: theme.color.text2,
1089
1484
  fontVariant: ["tabular-nums"]
1090
1485
  },
1486
+ // Ghost close: a ghost icon Button sm (30) with the 44 hit.
1091
1487
  iconButton: {
1092
1488
  width: theme.ctl.sm,
1093
1489
  height: theme.ctl.sm,
1094
1490
  alignItems: "center",
1095
1491
  justifyContent: "center",
1096
- borderRadius: theme.radius.full
1492
+ borderRadius: theme.ctl.r.sm
1097
1493
  },
1098
1494
  intro: {
1099
1495
  fontFamily: theme.font.sans,
@@ -1102,9 +1498,10 @@ var sheetStyles = createStyleSheet((theme) => ({
1102
1498
  color: theme.color.text3
1103
1499
  },
1104
1500
  questions: { gap: theme.space[20] },
1501
+ questionsCompact: { gap: theme.space[12] },
1105
1502
  footer: { flexDirection: "row", alignItems: "center", gap: theme.space[9] },
1106
1503
  grow: { flex: 1 },
1107
- pushEnd: { marginLeft: "auto" },
1504
+ pushEnd: { marginStart: "auto" },
1108
1505
  pager: { flex: 1, flexDirection: "row", alignItems: "center", gap: theme.space[5] },
1109
1506
  pagerDot: { width: theme.space[5], height: theme.space[5], borderRadius: theme.radius.full },
1110
1507
  doneBody: { gap: theme.space[11] },
@@ -1123,4 +1520,4 @@ var sheetStyles = createStyleSheet((theme) => ({
1123
1520
  }
1124
1521
  }));
1125
1522
 
1126
- export { SURVEY_FIELD_LABELS, SURVEY_OTHER_PREFIX, Survey, SurveyBoolean, SurveyCheckboxList, SurveyChips, SurveyConsent, SurveyDoneCard, SurveyDropdown, SurveyField, SurveyFieldError, SurveyMatrix, SurveyOpenText, SurveyOptionRow, SurveyOptions, SurveyPager, SurveyQuestionField, SurveyRank, SurveyScale, SurveySlider, SurveyTextInput };
1523
+ export { SURVEY_FIELD_LABELS, SURVEY_OTHER_PREFIX, Survey, SurveyBoolean, SurveyCheckboxList, SurveyChips, SurveyConsent, SurveyDate, SurveyDoneCard, SurveyDropdown, SurveyField, SurveyFieldError, SurveyFile, SurveyImageChoice, SurveyMatrix, SurveyOpenText, SurveyOptionRow, SurveyOptions, SurveyPager, SurveyQuestionField, SurveyRank, SurveyScale, SurveySlider, SurveyStatement, SurveyTextInput };