@btndprojects/loam-ui-native 0.2.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 (365) hide show
  1. package/dist/accordion/index.js +4 -2
  2. package/dist/adaptive/index.js +12 -2
  3. package/dist/address-block/index.js +23 -0
  4. package/dist/alert/index.js +5 -2
  5. package/dist/analyzer/index.js +13 -5
  6. package/dist/announcement/index.js +15 -5
  7. package/dist/appearance-picker/index.js +15 -0
  8. package/dist/audio-player/index.js +26 -2
  9. package/dist/avatar/index.js +2 -2
  10. package/dist/avatar-group/index.js +5 -3
  11. package/dist/badge/index.js +6 -3
  12. package/dist/banner/index.js +3 -2
  13. package/dist/board/index.js +13 -6
  14. package/dist/button/index.js +6 -3
  15. package/dist/camera-permission/index.js +19 -11
  16. package/dist/capture-result/index.js +26 -16
  17. package/dist/card/index.js +7 -3
  18. package/dist/card-form/index.js +15 -9
  19. package/dist/carousel/index.js +3 -1
  20. package/dist/chart/index.js +15 -5
  21. package/dist/charts/index.js +18 -5
  22. package/dist/chat/index.js +35 -10
  23. package/dist/checkbox/index.js +6 -4
  24. package/dist/checklist/index.js +16 -7
  25. package/dist/checkout/index.js +25 -12
  26. package/dist/chip/index.js +7 -4
  27. package/dist/chunk-2BZD3NAP.js +1110 -0
  28. package/dist/chunk-2YKVID2V.js +35 -0
  29. package/dist/{chunk-H7DWSL4O.js → chunk-36DA3IPO.js} +115 -27
  30. package/dist/chunk-3A56MIAN.js +599 -0
  31. package/dist/{chunk-AEB7KCHQ.js → chunk-3SCKCWF5.js} +39 -28
  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-PMMTGBBS.js → chunk-4CZMQDQL.js} +75 -22
  36. package/dist/chunk-4QCR3K2J.js +1 -0
  37. package/dist/{chunk-E2E3I5W2.js → chunk-5DTKORLI.js} +54 -45
  38. package/dist/{chunk-5VFZRGVD.js → chunk-5J4WFXFA.js} +32 -15
  39. package/dist/{chunk-JBMLWFSJ.js → chunk-5KJ7TEQ6.js} +83 -48
  40. package/dist/chunk-5NU33TXK.js +529 -0
  41. package/dist/chunk-6KSUS7DF.js +690 -0
  42. package/dist/{chunk-3WEZCGHX.js → chunk-6RV6UW2J.js} +140 -56
  43. package/dist/chunk-6RZM7RP2.js +520 -0
  44. package/dist/{chunk-JJLPBRVZ.js → chunk-75BDCC7K.js} +2 -0
  45. package/dist/{chunk-U5NLHYV6.js → chunk-7CGJBQUA.js} +333 -22
  46. package/dist/{chunk-I4FHVKEC.js → chunk-7IVF6JLJ.js} +16 -5
  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-2SY63FCH.js → chunk-7NGMUVNU.js} +66 -30
  51. package/dist/chunk-7PBSIXT7.js +355 -0
  52. package/dist/chunk-7QOYGENL.js +443 -0
  53. package/dist/{chunk-TDMG26JI.js → chunk-A7SWYDE5.js} +40 -9
  54. package/dist/chunk-ADHPJALR.js +3051 -0
  55. package/dist/{chunk-ZLTO5VQI.js → chunk-ALJYZLNQ.js} +131 -61
  56. package/dist/{chunk-GDKVKNR2.js → chunk-AQ5FIG74.js} +110 -30
  57. package/dist/chunk-B2MMZZQB.js +426 -0
  58. package/dist/{chunk-QYPE5JX3.js → chunk-B7JZ3N5G.js} +142 -105
  59. package/dist/{chunk-QHTVYA65.js → chunk-BL37SW6G.js} +388 -102
  60. package/dist/chunk-BTRMA7GC.js +21 -0
  61. package/dist/{chunk-FUMHAAF3.js → chunk-C7IUWIUZ.js} +243 -92
  62. package/dist/chunk-CA3DUVYD.js +10 -0
  63. package/dist/{chunk-FYWNRX4F.js → chunk-CBCJSO2B.js} +143 -13
  64. package/dist/chunk-CHPX4MFI.js +239 -0
  65. package/dist/chunk-CLGAMIOT.js +648 -0
  66. package/dist/chunk-CUE7VML6.js +1141 -0
  67. package/dist/{chunk-D5N5QWI7.js → chunk-CVU6S2E5.js} +497 -235
  68. package/dist/{chunk-U23FYWME.js → chunk-CXPQMA6Z.js} +101 -34
  69. package/dist/{chunk-36EC2T6P.js → chunk-D2LN4I7I.js} +1 -1
  70. package/dist/{chunk-TLCIR6RG.js → chunk-D34LNBO5.js} +411 -155
  71. package/dist/{chunk-FV6HMP7W.js → chunk-D4BCQICM.js} +207 -65
  72. package/dist/chunk-EABKIIA4.js +1 -0
  73. package/dist/chunk-EICSYRAG.js +341 -0
  74. package/dist/chunk-EMWAJMAS.js +83 -0
  75. package/dist/chunk-EOLZWRV6.js +149 -0
  76. package/dist/chunk-EOQVTGB6.js +350 -0
  77. package/dist/{chunk-ZVATDZOM.js → chunk-ESGUHNB2.js} +106 -28
  78. package/dist/{chunk-46MMSDGL.js → chunk-F2KNBPKY.js} +104 -73
  79. package/dist/{chunk-KQZ3GLHR.js → chunk-G7H3NX3G.js} +40 -17
  80. package/dist/{chunk-3QMEOFW5.js → chunk-GM7YIPB7.js} +421 -207
  81. package/dist/{chunk-QHAITQIF.js → chunk-GVQQG435.js} +256 -86
  82. package/dist/chunk-HE43OMEL.js +1056 -0
  83. package/dist/{chunk-XIDTBCBA.js → chunk-HHOMFQ7R.js} +1049 -207
  84. package/dist/chunk-HNAKS4Z3.js +207 -0
  85. package/dist/chunk-HP6ST2OW.js +352 -0
  86. package/dist/chunk-HW3OWDTU.js +1 -0
  87. package/dist/{chunk-QP3KMOVF.js → chunk-HZDB44K4.js} +24 -14
  88. package/dist/chunk-I6CUP2LW.js +1155 -0
  89. package/dist/chunk-ICV4Y2WY.js +27 -0
  90. package/dist/chunk-IHSIENOE.js +3950 -0
  91. package/dist/{chunk-T5LTPKX6.js → chunk-IMMALLRU.js} +53 -25
  92. package/dist/{chunk-C4GTDLRC.js → chunk-JA6TK7H2.js} +154 -67
  93. package/dist/{chunk-EVOIGUBI.js → chunk-JAVZ5JPV.js} +43 -13
  94. package/dist/{chunk-CPTOADB2.js → chunk-JCMTP3E4.js} +527 -201
  95. package/dist/{chunk-OJQUBQWA.js → chunk-JCXFFK64.js} +73 -16
  96. package/dist/{chunk-V2OEB75Z.js → chunk-JWCVBFDU.js} +75 -35
  97. package/dist/chunk-JXRTD5RI.js +414 -0
  98. package/dist/chunk-JYIUZUIQ.js +1567 -0
  99. package/dist/chunk-K3TK3GIV.js +219 -0
  100. package/dist/chunk-KEVZIHM2.js +1511 -0
  101. package/dist/{chunk-VAOAKWUK.js → chunk-KHZDNQQD.js} +42 -8
  102. package/dist/chunk-KL4GDV4V.js +131 -0
  103. package/dist/{chunk-Q6NKEPRE.js → chunk-KNILMM4H.js} +73 -28
  104. package/dist/chunk-KRBUZV45.js +25 -0
  105. package/dist/{chunk-7BUIKDD6.js → chunk-KXLDK6HB.js} +91 -30
  106. package/dist/chunk-KZ3X7TSL.js +196 -0
  107. package/dist/{chunk-5UTRIXQ6.js → chunk-L2WMOA2V.js} +187 -43
  108. package/dist/chunk-L4D5LHCH.js +109 -0
  109. package/dist/{chunk-W63AJTM7.js → chunk-LAUJPLDB.js} +236 -71
  110. package/dist/{chunk-TN2ZNJUI.js → chunk-LGNTP5XA.js} +47 -13
  111. package/dist/chunk-LUZFCCSD.js +271 -0
  112. package/dist/{chunk-XTORZWRF.js → chunk-LXJCP4PL.js} +111 -30
  113. package/dist/chunk-MCOZJWPU.js +731 -0
  114. package/dist/{chunk-SATMR6SG.js → chunk-MG4SKWLL.js} +780 -142
  115. package/dist/{chunk-JUYWSSKW.js → chunk-MPEPTSER.js} +95 -16
  116. package/dist/chunk-MWPJ4YGP.js +1 -0
  117. package/dist/{chunk-LUMVGO2K.js → chunk-N7AX4OA4.js} +80 -29
  118. package/dist/chunk-NHSLM6SE.js +523 -0
  119. package/dist/{chunk-IT6FUXXG.js → chunk-NNJLVA7M.js} +43 -11
  120. package/dist/{chunk-TQVAIKFD.js → chunk-NZG75DGA.js} +102 -62
  121. package/dist/chunk-O76QXRBV.js +431 -0
  122. package/dist/chunk-OANH27AK.js +223 -0
  123. package/dist/chunk-OCHPK5YV.js +609 -0
  124. package/dist/chunk-OMHVEVX4.js +436 -0
  125. package/dist/{chunk-SWS5JQIF.js → chunk-ONKQUJWD.js} +187 -60
  126. package/dist/chunk-OVTK7A6T.js +615 -0
  127. package/dist/{chunk-UXGIW7OK.js → chunk-PCEFCOLN.js} +5 -1
  128. package/dist/{chunk-QIKT7LIB.js → chunk-PFLNFIVB.js} +91 -23
  129. package/dist/chunk-PHSZY37H.js +300 -0
  130. package/dist/chunk-PJLTKDVY.js +18 -0
  131. package/dist/{chunk-SHHY5OMK.js → chunk-PK7BN3MI.js} +83 -15
  132. package/dist/{chunk-YXOAPXMU.js → chunk-PWFRDRGS.js} +101 -14
  133. package/dist/{chunk-TY4MTKQJ.js → chunk-PYPMD46W.js} +332 -66
  134. package/dist/chunk-Q6CCHDI7.js +331 -0
  135. package/dist/chunk-QFA5WS2A.js +750 -0
  136. package/dist/chunk-QJMMM4RC.js +124 -0
  137. package/dist/chunk-QYWEVAM6.js +407 -0
  138. package/dist/chunk-R5T4VZ7Z.js +126 -0
  139. package/dist/chunk-R77HFLZD.js +1 -0
  140. package/dist/{chunk-LMPHCVJJ.js → chunk-RAESDNU5.js} +162 -68
  141. package/dist/chunk-RBYQUXNL.js +1 -0
  142. package/dist/chunk-RCM3DT5E.js +1 -0
  143. package/dist/chunk-RGNY56L7.js +282 -0
  144. package/dist/chunk-RIK6UX2K.js +344 -0
  145. package/dist/{chunk-5LAAAXFP.js → chunk-RJA3RXO3.js} +63 -54
  146. package/dist/chunk-RJYRJ3LD.js +1 -0
  147. package/dist/chunk-RMA3NOY4.js +599 -0
  148. package/dist/{chunk-VDPK5CY4.js → chunk-RSWKKAHK.js} +143 -61
  149. package/dist/{chunk-B7N4ASYE.js → chunk-RVOIIX3V.js} +17 -45
  150. package/dist/chunk-SA2RRBGT.js +1077 -0
  151. package/dist/{chunk-7OVVSVEZ.js → chunk-SG3J4R45.js} +440 -169
  152. package/dist/chunk-SPUK7JD4.js +238 -0
  153. package/dist/chunk-SWXV2K5N.js +434 -0
  154. package/dist/chunk-SYJEPXP6.js +1303 -0
  155. package/dist/{chunk-LKFC4CS7.js → chunk-SZLI34TA.js} +18 -9
  156. package/dist/{chunk-NBEF4EPJ.js → chunk-T77WJA74.js} +131 -16
  157. package/dist/chunk-TDWWVJA4.js +630 -0
  158. package/dist/chunk-TFHI5XDR.js +610 -0
  159. package/dist/chunk-TH4PW2WU.js +17 -0
  160. package/dist/chunk-TTQ24HQX.js +12 -0
  161. package/dist/chunk-TUACVJNG.js +12 -0
  162. package/dist/{chunk-F5B3UINI.js → chunk-TUL5RUIA.js} +171 -62
  163. package/dist/{chunk-C6APNDVA.js → chunk-TYOSA7JG.js} +63 -34
  164. package/dist/chunk-TYQTMMEV.js +1 -0
  165. package/dist/{chunk-DW3L54DQ.js → chunk-TZO6YDS7.js} +53 -12
  166. package/dist/{chunk-67IZZ2MJ.js → chunk-U3ETF22F.js} +75 -30
  167. package/dist/{chunk-EDCBJV7J.js → chunk-U6BYHD2N.js} +87 -31
  168. package/dist/{chunk-ENP3BMZU.js → chunk-UF6EJXPQ.js} +16 -1
  169. package/dist/{chunk-IPUNJMAQ.js → chunk-UNNQIPGK.js} +304 -68
  170. package/dist/chunk-UQVO6AJV.js +171 -0
  171. package/dist/{chunk-FZGAAOKS.js → chunk-VFDQAAIW.js} +138 -32
  172. package/dist/chunk-VIUE3VQT.js +1 -0
  173. package/dist/{chunk-5RENVKBQ.js → chunk-VJLSSSGC.js} +126 -30
  174. package/dist/chunk-VLMT6KYT.js +350 -0
  175. package/dist/chunk-VMHGBUGS.js +35 -0
  176. package/dist/{chunk-4IZXHVFJ.js → chunk-VQKPBYW6.js} +228 -172
  177. package/dist/{chunk-G6UESEVN.js → chunk-VSSTWLC5.js} +49 -11
  178. package/dist/{chunk-TRGFFU6A.js → chunk-VZYYZRPN.js} +866 -330
  179. package/dist/{chunk-JLC6PM5S.js → chunk-WAIJCD2V.js} +128 -54
  180. package/dist/chunk-WFMQ3WKM.js +378 -0
  181. package/dist/chunk-WJ2KDRMY.js +66 -0
  182. package/dist/chunk-WKFZJO54.js +437 -0
  183. package/dist/{chunk-QEYFDRHR.js → chunk-WVVD3XOV.js} +146 -84
  184. package/dist/chunk-XAIWMSLB.js +1 -0
  185. package/dist/chunk-XBXUBBJZ.js +98 -0
  186. package/dist/chunk-XCU7MYBJ.js +1 -0
  187. package/dist/chunk-XHE4PGCI.js +717 -0
  188. package/dist/chunk-XRSJ32M3.js +331 -0
  189. package/dist/chunk-XTCVOEAW.js +1 -0
  190. package/dist/chunk-XWGXVQF6.js +58 -0
  191. package/dist/{chunk-MKSNFG7H.js → chunk-Y3XKKO5K.js} +191 -109
  192. package/dist/chunk-Y4QNMBLO.js +533 -0
  193. package/dist/chunk-Y5H4CTKO.js +1 -0
  194. package/dist/chunk-YBQIN75A.js +403 -0
  195. package/dist/{chunk-PNF3NKB5.js → chunk-YJ5PXOX3.js} +28 -11
  196. package/dist/{chunk-M656FYNH.js → chunk-YLRSRUPS.js} +63 -49
  197. package/dist/chunk-YM6MPJ4A.js +1 -0
  198. package/dist/chunk-YV7KZENV.js +200 -0
  199. package/dist/chunk-Z7I4ZSO6.js +316 -0
  200. package/dist/{chunk-EY4DD67D.js → chunk-ZIRMWD2B.js} +199 -126
  201. package/dist/chunk-ZPMG3FWU.js +75 -0
  202. package/dist/{chunk-QRUMA22E.js → chunk-ZTXMK2G7.js} +92 -43
  203. package/dist/{chunk-2OLKPG4E.js → chunk-ZVJCWXAL.js} +189 -87
  204. package/dist/{chunk-YAAHPATV.js → chunk-ZYQ23DPT.js} +49 -34
  205. package/dist/coachmark/index.js +7 -3
  206. package/dist/code-block/index.js +4 -3
  207. package/dist/color-field/index.js +12 -4
  208. package/dist/color-picker/index.js +23 -0
  209. package/dist/commerce/index.js +27 -16
  210. package/dist/confirm/index.js +31 -0
  211. package/dist/connection-card/index.js +34 -0
  212. package/dist/connectivity/index.js +3 -2
  213. package/dist/context-menu/index.js +10 -2
  214. package/dist/copy-button/index.js +3 -2
  215. package/dist/data-grid/index.js +30 -17
  216. package/dist/date-range-picker/index.js +19 -9
  217. package/dist/description-list/index.js +4 -1
  218. package/dist/device-frame/index.js +30 -0
  219. package/dist/dialog/index.js +8 -2
  220. package/dist/divider/index.js +2 -0
  221. package/dist/empty-state/index.js +13 -2
  222. package/dist/error-summary/index.js +7 -2
  223. package/dist/fab/index.js +4 -2
  224. package/dist/file-manager/index.js +33 -17
  225. package/dist/file-upload/index.js +12 -6
  226. package/dist/filter-bar/index.js +10 -6
  227. package/dist/flow-run/index.js +19 -12
  228. package/dist/form/index.js +30 -3
  229. package/dist/gallery/index.js +5 -2
  230. package/dist/hold-to-confirm/index.js +4 -2
  231. package/dist/hover-card/index.js +18 -0
  232. package/dist/icon-tile/index.js +10 -0
  233. package/dist/image/index.js +9 -0
  234. package/dist/index.d.ts +29826 -17941
  235. package/dist/index.js +197 -141
  236. package/dist/infinite-list/index.js +4 -2
  237. package/dist/inline-edit/index.js +5 -4
  238. package/dist/input/index.js +4 -3
  239. package/dist/interactions/index.js +4 -1
  240. package/dist/invoice/index.js +18 -9
  241. package/dist/job-row/index.js +22 -0
  242. package/dist/json-inspector/index.js +20 -0
  243. package/dist/kbd/index.js +2 -2
  244. package/dist/keyboard/index.js +7 -2
  245. package/dist/level-meter/index.js +9 -0
  246. package/dist/list-row/index.js +11 -3
  247. package/dist/log-viewer/index.js +9 -2
  248. package/dist/map-view/index.js +13 -2
  249. package/dist/markdown/index.js +8 -5
  250. package/dist/metric/index.js +6 -3
  251. package/dist/metric-strip/index.js +12 -0
  252. package/dist/money/index.js +11 -4
  253. package/dist/nav-drawer/index.js +6 -2
  254. package/dist/nav-header/index.js +10 -4
  255. package/dist/navigation/index.js +29 -2
  256. package/dist/notification-center/index.js +24 -10
  257. package/dist/number-roll/index.js +3 -1
  258. package/dist/onboarding-pager/index.js +22 -0
  259. package/dist/one-handed/index.js +2 -2
  260. package/dist/os-surfaces/index.js +6 -3
  261. package/dist/otp/index.js +5 -4
  262. package/dist/page-header/index.js +2 -1
  263. package/dist/pagination/index.js +4 -2
  264. package/dist/payment-method/index.js +17 -11
  265. package/dist/payment-status/index.js +22 -14
  266. package/dist/permission/index.js +18 -2
  267. package/dist/picker/index.js +17 -6
  268. package/dist/progress/index.js +7 -2
  269. package/dist/provenance/index.js +16 -0
  270. package/dist/pull-to-refresh/index.js +2 -2
  271. package/dist/qr-code/index.js +16 -0
  272. package/dist/query-builder/index.js +30 -0
  273. package/dist/radio-group/index.js +6 -4
  274. package/dist/rating/index.js +7 -2
  275. package/dist/receivables/index.js +31 -18
  276. package/dist/recording-indicator/index.js +21 -0
  277. package/dist/refund/index.js +24 -15
  278. package/dist/repeatable-rows/index.js +19 -0
  279. package/dist/save-status/index.js +5 -3
  280. package/dist/screen/index.js +3 -0
  281. package/dist/scroll-area/index.js +1 -1
  282. package/dist/search-field/index.js +8 -3
  283. package/dist/secret-field/index.js +19 -0
  284. package/dist/section-header/index.js +4 -0
  285. package/dist/segmented-control/index.js +2 -2
  286. package/dist/sheet/index.js +9 -3
  287. package/dist/shortcuts-sheet/index.js +2 -0
  288. package/dist/sign-in-screen/index.js +25 -0
  289. package/dist/skeleton/index.js +3 -1
  290. package/dist/slider/index.js +2 -1
  291. package/dist/sortable/index.js +4 -3
  292. package/dist/spinner/index.js +2 -1
  293. package/dist/split-button/index.js +17 -5
  294. package/dist/spotlight/index.js +7 -1
  295. package/dist/stack/index.js +2 -0
  296. package/dist/stage-timeline/index.js +6 -3
  297. package/dist/status-dot/index.js +6 -2
  298. package/dist/stepper/index.js +7 -3
  299. package/dist/streaming-text/index.js +2 -1
  300. package/dist/survey/index.js +24 -14
  301. package/dist/switch/index.js +6 -2
  302. package/dist/system-state/index.js +12 -4
  303. package/dist/tab-bar/index.js +10 -2
  304. package/dist/tabs/index.js +10 -2
  305. package/dist/tags-input/index.js +8 -5
  306. package/dist/text/index.js +4 -0
  307. package/dist/textarea/index.js +5 -4
  308. package/dist/thinking/index.js +4 -1
  309. package/dist/tile-rail/index.js +10 -0
  310. package/dist/time-field/index.js +15 -7
  311. package/dist/time-range-control/index.js +26 -12
  312. package/dist/timeline/index.js +2 -2
  313. package/dist/toast/index.js +4 -2
  314. package/dist/toolbar/index.js +3 -2
  315. package/dist/tour/index.js +12 -10
  316. package/dist/transcript/index.js +28 -0
  317. package/dist/truncation-notice/index.js +2 -2
  318. package/dist/update-notice/index.js +15 -8
  319. package/dist/video-player/index.js +26 -2
  320. package/dist/viewfinder/index.js +12 -4
  321. package/dist/widget/index.js +11 -4
  322. package/dist/wizard/index.js +7 -4
  323. package/package.json +13 -13
  324. package/dist/chunk-2PKYGLQ6.js +0 -268
  325. package/dist/chunk-2SWKL3AJ.js +0 -466
  326. package/dist/chunk-2TXERVVA.js +0 -1081
  327. package/dist/chunk-3DUWIYV5.js +0 -437
  328. package/dist/chunk-3NMD74ZU.js +0 -4
  329. package/dist/chunk-4DS5ZWVC.js +0 -83
  330. package/dist/chunk-6YAQBXB3.js +0 -93
  331. package/dist/chunk-74FLKD24.js +0 -237
  332. package/dist/chunk-CMTVNF3D.js +0 -104
  333. package/dist/chunk-DN7MNQIP.js +0 -799
  334. package/dist/chunk-DVGBZ3TX.js +0 -455
  335. package/dist/chunk-F3H33DQX.js +0 -300
  336. package/dist/chunk-FAJI7BSC.js +0 -443
  337. package/dist/chunk-G3AFC24V.js +0 -60
  338. package/dist/chunk-HJLPZA4X.js +0 -369
  339. package/dist/chunk-HYEOQWT7.js +0 -647
  340. package/dist/chunk-IDM7JJMO.js +0 -110
  341. package/dist/chunk-IVKMZ7BB.js +0 -326
  342. package/dist/chunk-IXKWIFWZ.js +0 -334
  343. package/dist/chunk-JV5YOTOB.js +0 -164
  344. package/dist/chunk-KFJGFLMW.js +0 -158
  345. package/dist/chunk-LQP4KEXZ.js +0 -214
  346. package/dist/chunk-NTQ2F3AU.js +0 -257
  347. package/dist/chunk-O5V4TG3V.js +0 -329
  348. package/dist/chunk-OWAMM2DK.js +0 -280
  349. package/dist/chunk-PID3NJB7.js +0 -405
  350. package/dist/chunk-QDZGFXQD.js +0 -176
  351. package/dist/chunk-QPWDDJJ4.js +0 -385
  352. package/dist/chunk-ROCUG24E.js +0 -416
  353. package/dist/chunk-RU3ZPNL6.js +0 -1986
  354. package/dist/chunk-RXSCIO6W.js +0 -153
  355. package/dist/chunk-SKWO3SZF.js +0 -2284
  356. package/dist/chunk-UQGBTPXH.js +0 -218
  357. package/dist/chunk-UYGDJWMN.js +0 -273
  358. package/dist/chunk-W74TXYFB.js +0 -107
  359. package/dist/chunk-WRDSPUE7.js +0 -417
  360. package/dist/chunk-XBZGDDMR.js +0 -105
  361. package/dist/chunk-XN4KG3P4.js +0 -1040
  362. package/dist/chunk-XQXMLMH3.js +0 -211
  363. package/dist/chunk-ZECZOOSB.js +0 -245
  364. /package/dist/{chunk-VFCUIDRT.js → chunk-3BKLBYPK.js} +0 -0
  365. /package/dist/{chunk-GEIGMWNF.js → chunk-QNZII37O.js} +0 -0
@@ -1,22 +1,25 @@
1
- import { Picker } from './chunk-PID3NJB7.js';
2
- import { EmptyState } from './chunk-KFJGFLMW.js';
3
- import { Switch } from './chunk-FZGAAOKS.js';
4
- import { SegmentedControl } from './chunk-TQVAIKFD.js';
5
- import { Sheet } from './chunk-QYPE5JX3.js';
6
- import { Spinner } from './chunk-KQZ3GLHR.js';
7
- import { Skeleton } from './chunk-PNF3NKB5.js';
8
- import { Checkbox } from './chunk-Q6NKEPRE.js';
9
- import { Input } from './chunk-7BUIKDD6.js';
1
+ import { Checkbox } from './chunk-KNILMM4H.js';
2
+ import { EmptyState } from './chunk-QJMMM4RC.js';
3
+ import { Chip } from './chunk-7NGMUVNU.js';
4
+ import { Picker } from './chunk-MCOZJWPU.js';
5
+ import { Sheet } from './chunk-B7JZ3N5G.js';
6
+ import { Button } from './chunk-5DTKORLI.js';
7
+ import { resolveTextRole } from './chunk-L4D5LHCH.js';
8
+ import { Skeleton } from './chunk-YJ5PXOX3.js';
10
9
  import { expandedProps } from './chunk-W23G6JLF.js';
11
- import { Button } from './chunk-E2E3I5W2.js';
10
+ import { Switch } from './chunk-VFDQAAIW.js';
11
+ import { SegmentedControl } from './chunk-NZG75DGA.js';
12
+ import { Input } from './chunk-KXLDK6HB.js';
12
13
  import { haptics } from './chunk-NY2U3PBI.js';
14
+ import { Spinner } from './chunk-G7H3NX3G.js';
15
+ import { isAndroidIdiom } from './chunk-TH4PW2WU.js';
13
16
  import { useLabels, useLoamLocale } from './chunk-APCWFOZW.js';
14
- import { Icon } from './chunk-UXGIW7OK.js';
17
+ import { Icon } from './chunk-PCEFCOLN.js';
15
18
  import { useResolvedMotion, motionTiming } from './chunk-J64KGCGX.js';
16
- import * as React2 from 'react';
17
- import { View, Text, Pressable, ScrollView, LayoutAnimation, FlatList, Animated } from 'react-native';
19
+ import * as React3 from 'react';
20
+ import { View, Text, Pressable, ScrollView, LayoutAnimation, Animated, FlatList, PanResponder } from 'react-native';
18
21
  import { createStyleSheet, useStyles, useLoamTheme } from '@btndprojects/loam-theme-native';
19
- import { getValue, formatValue, resolveColumns, useGridState, buildRowModel, DENSITY_ROW_PX } from '@btndprojects/loam-data-grid-core';
22
+ import { getValue, formatValue, resolveColumns, useGridState, buildRowModel, DENSITY_ROW_PX, rangeRect, parseClipboardMatrix, NUMERIC_TYPES } from '@btndprojects/loam-data-grid-core';
20
23
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
21
24
 
22
25
  // src/data-grid/data-grid-labels.ts
@@ -126,6 +129,19 @@ var DEFAULT_DATA_GRID_LABELS = {
126
129
  columns: "Columns",
127
130
  lastColumnHint: "The last visible column cannot be hidden",
128
131
  headerWithUnit: (header, unit) => `${header} (${unit})`,
132
+ copy: "Copy",
133
+ paste: "Paste",
134
+ fill: "Fill",
135
+ clear: "Clear",
136
+ rangeSummary: (rows, cols, cells) => `${rows} ${rows === 1 ? "row" : "rows"} by ${cols} ${cols === 1 ? "column" : "columns"}, ${cells} ${cells === 1 ? "cell" : "cells"}`,
137
+ copiedCells: (cells) => `Copied ${cells} ${cells === 1 ? "cell" : "cells"}`,
138
+ filledCells: (cells, rejected) => `Filled ${cells} ${cells === 1 ? "cell" : "cells"}${rejected ? ` \xB7 ${rejected} rejected` : ""}`,
139
+ clearedCells: (cells) => `Cleared ${cells} ${cells === 1 ? "cell" : "cells"}`,
140
+ pastedCells: (cells, rejected) => `Pasted ${cells} ${cells === 1 ? "cell" : "cells"}${rejected ? ` \xB7 ${rejected} rejected` : ""}`,
141
+ rangeStartHandle: "Range start",
142
+ rangeEndHandle: "Range end",
143
+ rangeHandleHint: "Drag to change the range",
144
+ cellName: (header, value) => `${header}: ${value}`,
129
145
  saveFailed: "Could not save",
130
146
  datePlaceholder: "YYYY-MM-DD"
131
147
  };
@@ -274,18 +290,13 @@ function FilterSheet({
274
290
  nullary ? null : values ? /* @__PURE__ */ jsx(View, { style: styles.chips, children: values.map((value) => {
275
291
  const active = String(filter.value ?? "") === value;
276
292
  return /* @__PURE__ */ jsx(
277
- Pressable,
293
+ Chip,
278
294
  {
279
- accessibilityRole: "button",
280
- accessibilityState: { selected: active },
281
- accessibilityLabel: value,
282
- onPress: () => update(index, { value: active ? "" : value }),
283
- style: ({ pressed }) => [
284
- styles.chip,
285
- active && styles.chipOn,
286
- pressed && styles.pressed
287
- ],
288
- children: /* @__PURE__ */ jsx(Text, { style: [styles.chipText, active && styles.chipTextOn], children: value })
295
+ size: "sm",
296
+ selectable: true,
297
+ selected: active,
298
+ onSelectedChange: () => update(index, { value: active ? "" : value }),
299
+ children: value
289
300
  },
290
301
  value
291
302
  );
@@ -365,6 +376,7 @@ function DisplaySheet({
365
376
  {
366
377
  accessibilityRole: "checkbox",
367
378
  accessibilityState: { checked: state.zebra },
379
+ "aria-checked": state.zebra,
368
380
  accessibilityLabel: labels.shadeRows,
369
381
  onPress: () => onSetState({ zebra: !state.zebra }, "display"),
370
382
  style: ({ pressed }) => [styles.row, pressed && styles.pressed],
@@ -378,35 +390,27 @@ function DisplaySheet({
378
390
  /* @__PURE__ */ jsx(Text, { style: styles.section, children: labels.groupBy }),
379
391
  /* @__PURE__ */ jsxs(View, { style: styles.chips, children: [
380
392
  /* @__PURE__ */ jsx(
381
- Pressable,
393
+ Chip,
382
394
  {
383
- accessibilityRole: "button",
384
- accessibilityState: { selected: state.grouping.length === 0 },
395
+ size: "sm",
396
+ selectable: true,
397
+ selected: state.grouping.length === 0,
398
+ onSelectedChange: () => onSetState({ grouping: [] }, "group"),
385
399
  accessibilityLabel: labels.noGrouping,
386
- onPress: () => onSetState({ grouping: [] }, "group"),
387
- style: ({ pressed }) => [
388
- styles.chip,
389
- state.grouping.length === 0 && styles.chipOn,
390
- pressed && styles.pressed
391
- ],
392
- children: /* @__PURE__ */ jsx(Text, { style: [styles.chipText, state.grouping.length === 0 && styles.chipTextOn], children: labels.none })
400
+ children: labels.none
393
401
  }
394
402
  ),
395
403
  groupable.map((column) => {
396
404
  const active = state.grouping[0] === column.id;
397
405
  return /* @__PURE__ */ jsx(
398
- Pressable,
406
+ Chip,
399
407
  {
400
- accessibilityRole: "button",
401
- accessibilityState: { selected: active },
408
+ size: "sm",
409
+ selectable: true,
410
+ selected: active,
411
+ onSelectedChange: () => onSetState({ grouping: active ? [] : [column.id] }, "group"),
402
412
  accessibilityLabel: labels.groupByColumn(column.header),
403
- onPress: () => onSetState({ grouping: active ? [] : [column.id] }, "group"),
404
- style: ({ pressed }) => [
405
- styles.chip,
406
- active && styles.chipOn,
407
- pressed && styles.pressed
408
- ],
409
- children: /* @__PURE__ */ jsx(Text, { style: [styles.chipText, active && styles.chipTextOn], children: column.header })
413
+ children: column.header
410
414
  },
411
415
  column.id
412
416
  );
@@ -422,6 +426,7 @@ function DisplaySheet({
422
426
  {
423
427
  accessibilityRole: "checkbox",
424
428
  accessibilityState: { checked: on, disabled: !column.hideable || last },
429
+ "aria-checked": on,
425
430
  accessibilityLabel: column.header,
426
431
  accessibilityHint: last ? labels.lastColumnHint : void 0,
427
432
  disabled: !column.hideable || last,
@@ -490,11 +495,11 @@ function DetailField({
490
495
  const theme = useLoamTheme("data-grid");
491
496
  const { styles } = useStyles(sheet);
492
497
  const level = useResolvedMotion(motion, "data-grid");
493
- const [draft, setDraft] = React2.useState(() => toField(column, value));
494
- const [error, setError] = React2.useState(null);
495
- const [pending, setPending] = React2.useState(false);
496
- const wash = React2.useRef(new Animated.Value(0)).current;
497
- React2.useEffect(() => setDraft(toField(column, value)), [column, value]);
498
+ const [draft, setDraft] = React3.useState(() => toField(column, value));
499
+ const [error, setError] = React3.useState(null);
500
+ const [pending, setPending] = React3.useState(false);
501
+ const wash = React3.useRef(new Animated.Value(0)).current;
502
+ React3.useEffect(() => setDraft(toField(column, value)), [column, value]);
498
503
  const commit = async (next) => {
499
504
  if (same(next, value)) {
500
505
  setError(null);
@@ -696,10 +701,12 @@ var sheet = createStyleSheet((theme) => ({
696
701
  operands: { flexDirection: "row", gap: theme.space.s2 },
697
702
  operand: { flex: 1 },
698
703
  chips: { flexDirection: "row", flexWrap: "wrap", gap: theme.space.s1 },
704
+ // The record sheet's enum radios: Chip sm metrics, drawn here because a
705
+ // radio group needs `role="radio"` on each one. On keeps the label weight.
699
706
  chip: {
700
- minHeight: theme.tapMin,
707
+ minHeight: theme.ctl.sm,
701
708
  justifyContent: "center",
702
- paddingHorizontal: theme.space.s3,
709
+ paddingHorizontal: theme.ctl.px.sm,
703
710
  borderRadius: theme.radius.full,
704
711
  borderWidth: theme.borderWidth.base,
705
712
  borderColor: theme.color.border,
@@ -715,7 +722,7 @@ var sheet = createStyleSheet((theme) => ({
715
722
  lineHeight: theme.type.footnote.lineHeight,
716
723
  color: theme.color.text
717
724
  },
718
- chipTextOn: { color: theme.color.accentOnSoft, fontWeight: theme.fontWeight.bold },
725
+ chipTextOn: { color: theme.color.accentOnSoft },
719
726
  detailRow: {
720
727
  gap: theme.space[2],
721
728
  paddingBottom: theme.space.s2,
@@ -759,6 +766,384 @@ var sheet = createStyleSheet((theme) => ({
759
766
  mono: { fontFamily: theme.font.mono },
760
767
  pressed: { opacity: theme.state.pressedOpacity }
761
768
  }));
769
+ function isEditable(column, row) {
770
+ const e = column.editable;
771
+ return typeof e === "function" ? e(row) : e === true;
772
+ }
773
+ function coerce2(column, row, raw) {
774
+ let value = raw;
775
+ if (typeof raw === "string") {
776
+ if (NUMERIC_TYPES.includes(column.type)) {
777
+ const n = Number(raw.replace(/[^0-9.eE+-]/g, ""));
778
+ if (!Number.isFinite(n)) return null;
779
+ value = n;
780
+ } else if (column.type === "date") {
781
+ const time = new Date(raw).getTime();
782
+ if (Number.isNaN(time)) return null;
783
+ value = time;
784
+ } else if (column.type === "boolean") {
785
+ value = /^(true|yes|1|y)$/i.test(raw.trim());
786
+ } else if (column.type === "tags") {
787
+ value = raw.split(/[,;]/).map((s) => s.trim()).filter(Boolean);
788
+ }
789
+ }
790
+ return column.validate?.(value, row) ? null : { value };
791
+ }
792
+ function useNativeRange(o) {
793
+ const {
794
+ enabled,
795
+ nodes,
796
+ columns,
797
+ ctx,
798
+ range,
799
+ setRange,
800
+ onCellEditCommit,
801
+ clipboard,
802
+ labels,
803
+ announce
804
+ } = o;
805
+ const [touched, setTouched] = React3.useState(false);
806
+ const nodeIndex = React3.useMemo(() => new Map(nodes.map((n, i) => [n.id, i])), [nodes]);
807
+ const colIndex = React3.useMemo(() => new Map(columns.map((c, i) => [c.id, i])), [columns]);
808
+ const rect = enabled ? rangeRect(range, nodeIndex, colIndex) : null;
809
+ const cellAt = (row, col) => {
810
+ const node = nodes[Math.max(0, Math.min(nodes.length - 1, row))];
811
+ const column = columns[Math.max(0, Math.min(columns.length - 1, col))];
812
+ return node && column ? { rowId: node.id, colId: column.id } : null;
813
+ };
814
+ const summary = (r) => {
815
+ const rows = r.r1 - r.r0 + 1;
816
+ const cols = r.c1 - r.c0 + 1;
817
+ return labels.rangeSummary(rows, cols, rows * cols);
818
+ };
819
+ const press = (row, col) => {
820
+ const cell = cellAt(row, col);
821
+ if (!cell) return;
822
+ setTouched(false);
823
+ setRange({ anchor: cell, focus: cell });
824
+ };
825
+ const longPress = (row, col) => {
826
+ const cell = cellAt(row, col);
827
+ if (!cell) return;
828
+ setTouched(true);
829
+ setRange({ anchor: cell, focus: cell });
830
+ announce(labels.rangeSummary(1, 1, 1));
831
+ };
832
+ const extend = (edge, row, col) => {
833
+ if (!rect) return;
834
+ const fixed = edge === "start" ? cellAt(rect.r1, rect.c1) : cellAt(rect.r0, rect.c0);
835
+ const moving = cellAt(row, col);
836
+ if (!fixed || !moving) return;
837
+ if (range && range.anchor.rowId === fixed.rowId && range.anchor.colId === fixed.colId && range.focus.rowId === moving.rowId && range.focus.colId === moving.colId)
838
+ return;
839
+ setRange({ anchor: fixed, focus: moving });
840
+ };
841
+ const settle = () => {
842
+ if (rect) announce(summary(rect));
843
+ };
844
+ const cells = (r) => {
845
+ const out = [];
846
+ for (let i = r.r0; i <= r.r1; i++) {
847
+ const node = nodes[i];
848
+ if (!node || node.kind !== "leaf") continue;
849
+ for (let c = r.c0; c <= r.c1; c++) {
850
+ const column = columns[c];
851
+ if (column) out.push({ node, column, dr: i - r.r0, dc: c - r.c0 });
852
+ }
853
+ }
854
+ return out;
855
+ };
856
+ const write = (list) => {
857
+ for (const { node, column, value } of list) {
858
+ void onCellEditCommit?.({
859
+ rowId: node.id,
860
+ row: node.row,
861
+ colId: column.id,
862
+ value,
863
+ previous: getValue(ctx, node.row, column.id)
864
+ });
865
+ }
866
+ };
867
+ const done = (message) => {
868
+ setTouched(false);
869
+ announce(message);
870
+ };
871
+ const copy = () => {
872
+ if (!rect) return;
873
+ const lines = [];
874
+ for (const { node, column, dr } of cells(rect)) {
875
+ (lines[dr] ??= []).push(
876
+ String(formatValue(ctx, column, getValue(ctx, node.row, column.id), node.row))
877
+ );
878
+ }
879
+ clipboard?.setString(
880
+ lines.filter(Boolean).map((l) => l.join(" ")).join("\n")
881
+ );
882
+ done(labels.copiedCells(lines.reduce((n, l) => n + (l?.length ?? 0), 0)));
883
+ };
884
+ const editing = !!onCellEditCommit;
885
+ const paste = async () => {
886
+ if (!rect || !clipboard) return;
887
+ const matrix = parseClipboardMatrix(String(await clipboard.getString()));
888
+ const out = [];
889
+ let rejected = 0;
890
+ matrix.forEach((line, dr) => {
891
+ const node = nodes[rect.r0 + dr];
892
+ if (!node || node.kind !== "leaf") return;
893
+ line.forEach((raw, dc) => {
894
+ const column = columns[rect.c0 + dc];
895
+ const ok = column && isEditable(column, node.row) ? coerce2(column, node.row, raw) : null;
896
+ if (!column || !ok) rejected += 1;
897
+ else out.push({ node, column, value: ok.value });
898
+ });
899
+ });
900
+ write(out);
901
+ done(labels.pastedCells(out.length, rejected));
902
+ };
903
+ const fill = () => {
904
+ if (!rect) return;
905
+ const all = cells(rect);
906
+ const source = new Map(all.filter((c) => c.dr === all[0]?.dr).map((c) => [c.dc, c]));
907
+ const out = [];
908
+ let rejected = 0;
909
+ for (const cell of all) {
910
+ const from = source.get(cell.dc);
911
+ if (!from || cell.dr === from.dr) continue;
912
+ const raw = getValue(ctx, from.node.row, from.column.id);
913
+ const ok = isEditable(cell.column, cell.node.row) ? coerce2(cell.column, cell.node.row, raw) : null;
914
+ if (!ok) rejected += 1;
915
+ else out.push({ node: cell.node, column: cell.column, value: ok.value });
916
+ }
917
+ write(out);
918
+ done(labels.filledCells(out.length, rejected));
919
+ };
920
+ const clear = () => {
921
+ if (!rect) return;
922
+ const out = cells(rect).filter(
923
+ ({ node, column }) => isEditable(column, node.row) && getValue(ctx, node.row, column.id) != null
924
+ ).map(({ node, column }) => ({ node, column, value: null }));
925
+ write(out);
926
+ done(labels.clearedCells(out.length));
927
+ };
928
+ return {
929
+ rect,
930
+ anchor: rect ? range.anchor : null,
931
+ touched: touched && !!rect,
932
+ press,
933
+ longPress,
934
+ extend,
935
+ settle,
936
+ copy,
937
+ paste: editing && clipboard ? () => void paste() : null,
938
+ fill: editing && rect && rect.r1 > rect.r0 ? fill : null,
939
+ clear: editing ? clear : null
940
+ };
941
+ }
942
+ function colAt(g, x) {
943
+ for (let i = g.lefts.length - 1; i >= 0; i--) if (x >= g.lefts[i]) return i;
944
+ return 0;
945
+ }
946
+ function Handle({
947
+ x,
948
+ y,
949
+ edge,
950
+ geometry,
951
+ onMove,
952
+ onEnd,
953
+ label,
954
+ hint
955
+ }) {
956
+ const { styles } = useStyles(sheet2);
957
+ const theme = useLoamTheme("data-grid");
958
+ const hit = isAndroidIdiom(theme) ? theme.space[48] : theme.tapMin;
959
+ const latest = React3.useRef({ x, y, geometry, onMove, onEnd });
960
+ latest.current = { x, y, geometry, onMove, onEnd };
961
+ const origin = React3.useRef({ x: 0, y: 0 });
962
+ const responder = React3.useMemo(
963
+ () => (
964
+ // eslint-disable-next-line loam/no-pan-responder -- a range handle is a free 2-D drag; no RN gesture covers it
965
+ PanResponder.create({
966
+ onStartShouldSetPanResponder: () => true,
967
+ onMoveShouldSetPanResponder: () => true,
968
+ onPanResponderTerminationRequest: () => false,
969
+ onPanResponderGrant: () => {
970
+ origin.current = { x: latest.current.x, y: latest.current.y };
971
+ },
972
+ onPanResponderMove: (_, g) => {
973
+ const { geometry: geo } = latest.current;
974
+ const inset = edge === "start" ? 1 : -1;
975
+ const px = origin.current.x + g.dx + inset;
976
+ const py = origin.current.y + g.dy + inset;
977
+ const row = Math.max(0, Math.min(geo.rows - 1, Math.floor(py / geo.rowHeight)));
978
+ latest.current.onMove(row, colAt(geo, px));
979
+ },
980
+ onPanResponderRelease: () => latest.current.onEnd(),
981
+ onPanResponderTerminate: () => latest.current.onEnd()
982
+ })
983
+ ),
984
+ [edge]
985
+ );
986
+ const step = (by) => {
987
+ const { geometry: geo } = latest.current;
988
+ const row = Math.floor((y + (edge === "start" ? 1 : -1)) / geo.rowHeight) + by;
989
+ onMove(Math.max(0, Math.min(geo.rows - 1, row)), colAt(geo, x + (edge === "start" ? 1 : -1)));
990
+ onEnd();
991
+ };
992
+ return /* @__PURE__ */ jsx(
993
+ View,
994
+ {
995
+ ...responder.panHandlers,
996
+ accessible: true,
997
+ accessibilityRole: "adjustable",
998
+ accessibilityLabel: label,
999
+ accessibilityHint: hint,
1000
+ accessibilityActions: [{ name: "increment" }, { name: "decrement" }],
1001
+ onAccessibilityAction: (e) => step(e.nativeEvent.actionName === "increment" ? 1 : -1),
1002
+ testID: `range-handle-${edge}`,
1003
+ style: [styles.handleHit, { width: hit, height: hit, left: x - hit / 2, top: y - hit / 2 }],
1004
+ children: /* @__PURE__ */ jsx(View, { style: styles.handle })
1005
+ }
1006
+ );
1007
+ }
1008
+ function RangeOverlay({
1009
+ range,
1010
+ geometry,
1011
+ scrollY,
1012
+ top,
1013
+ labels
1014
+ }) {
1015
+ const { styles } = useStyles(sheet2);
1016
+ const theme = useLoamTheme("data-grid");
1017
+ const android = isAndroidIdiom(theme);
1018
+ const { rect } = range;
1019
+ if (!rect) return null;
1020
+ const x0 = geometry.lefts[rect.c0] ?? 0;
1021
+ const x1 = (geometry.lefts[rect.c1] ?? 0) + (geometry.widths[rect.c1] ?? 0);
1022
+ const y0 = rect.r0 * geometry.rowHeight;
1023
+ const y1 = (rect.r1 + 1) * geometry.rowHeight;
1024
+ const items = [
1025
+ { key: "copy", label: labels.copy, run: range.copy },
1026
+ { key: "paste", label: labels.paste, run: range.paste },
1027
+ { key: "fill", label: labels.fill, run: range.fill },
1028
+ { key: "clear", label: labels.clear, run: range.clear }
1029
+ ].filter((i) => !!i.run);
1030
+ const menuH = android ? theme.space[48] : theme.tapMin;
1031
+ const menuTop = y0 >= menuH + theme.space.s2 ? y0 - menuH - theme.space.s2 : y1 + theme.space.s2;
1032
+ return /* @__PURE__ */ jsx(View, { pointerEvents: "box-none", style: [styles.layer, { top }], children: /* @__PURE__ */ jsxs(
1033
+ Animated.View,
1034
+ {
1035
+ pointerEvents: "box-none",
1036
+ style: [styles.fill, { transform: [{ translateY: Animated.multiply(scrollY, -1) }] }],
1037
+ children: [
1038
+ /* @__PURE__ */ jsx(
1039
+ View,
1040
+ {
1041
+ pointerEvents: "none",
1042
+ testID: "range-edge",
1043
+ style: [styles.edge, { left: x0, top: y0, width: x1 - x0, height: y1 - y0 }]
1044
+ }
1045
+ ),
1046
+ range.touched ? /* @__PURE__ */ jsxs(Fragment, { children: [
1047
+ /* @__PURE__ */ jsx(
1048
+ Handle,
1049
+ {
1050
+ x: x0,
1051
+ y: y0,
1052
+ edge: "start",
1053
+ geometry,
1054
+ onMove: (r, c) => range.extend("start", r, c),
1055
+ onEnd: range.settle,
1056
+ label: labels.rangeStartHandle,
1057
+ hint: labels.rangeHandleHint
1058
+ }
1059
+ ),
1060
+ /* @__PURE__ */ jsx(
1061
+ Handle,
1062
+ {
1063
+ x: x1,
1064
+ y: y1,
1065
+ edge: "end",
1066
+ geometry,
1067
+ onMove: (r, c) => range.extend("end", r, c),
1068
+ onEnd: range.settle,
1069
+ label: labels.rangeEndHandle,
1070
+ hint: labels.rangeHandleHint
1071
+ }
1072
+ ),
1073
+ /* @__PURE__ */ jsx(
1074
+ View,
1075
+ {
1076
+ role: "menu",
1077
+ style: [
1078
+ styles.menu,
1079
+ android && styles.menuAndroid,
1080
+ {
1081
+ top: menuTop,
1082
+ left: Math.max(0, (x0 + x1) / 2 - items.length * theme.space[72] / 2)
1083
+ }
1084
+ ],
1085
+ children: items.map((item, i) => /* @__PURE__ */ jsx(
1086
+ Pressable,
1087
+ {
1088
+ role: "menuitem",
1089
+ accessibilityRole: "button",
1090
+ accessibilityLabel: item.label,
1091
+ onPress: item.run,
1092
+ style: ({ pressed }) => [
1093
+ styles.menuItem,
1094
+ { minHeight: menuH },
1095
+ i > 0 && !android && styles.menuSeparator,
1096
+ pressed && styles.pressed
1097
+ ],
1098
+ children: /* @__PURE__ */ jsx(Text, { style: [styles.menuText, android && styles.menuTextAndroid], children: item.label })
1099
+ },
1100
+ item.key
1101
+ ))
1102
+ }
1103
+ )
1104
+ ] }) : null
1105
+ ]
1106
+ }
1107
+ ) });
1108
+ }
1109
+ var sheet2 = createStyleSheet((theme) => ({
1110
+ layer: { position: "absolute", start: 0, end: 0, bottom: 0, overflow: "hidden" },
1111
+ fill: { position: "absolute", top: 0, start: 0, end: 0, bottom: 0 },
1112
+ edge: {
1113
+ position: "absolute",
1114
+ borderWidth: theme.borderWidth.thick,
1115
+ borderColor: theme.focus.ringColor
1116
+ },
1117
+ handleHit: { position: "absolute", alignItems: "center", justifyContent: "center" },
1118
+ handle: {
1119
+ width: theme.space.s3,
1120
+ height: theme.space.s3,
1121
+ borderRadius: theme.radius.full,
1122
+ borderWidth: theme.borderWidth.thick,
1123
+ borderColor: theme.focus.ringColor,
1124
+ backgroundColor: theme.color.surface
1125
+ },
1126
+ menu: {
1127
+ position: "absolute",
1128
+ flexDirection: "row",
1129
+ borderRadius: theme.radius.md,
1130
+ backgroundColor: theme.color.surface,
1131
+ borderWidth: theme.borderWidth.hair,
1132
+ borderColor: theme.color.border,
1133
+ overflow: "hidden",
1134
+ ...theme.shadow.md
1135
+ },
1136
+ menuAndroid: { borderRadius: theme.radius.sm },
1137
+ menuItem: { justifyContent: "center", paddingHorizontal: theme.space.s3 },
1138
+ menuSeparator: { borderStartWidth: theme.borderWidth.hair, borderStartColor: theme.color.border },
1139
+ menuText: {
1140
+ fontFamily: theme.font.sans,
1141
+ fontSize: theme.type.subheadline.fontSize,
1142
+ color: theme.color.text
1143
+ },
1144
+ menuTextAndroid: { fontWeight: theme.fontWeight.medium },
1145
+ pressed: { backgroundColor: theme.state.pressed }
1146
+ }));
762
1147
  var TABLE_MIN_WIDTH = 680;
763
1148
  var SKELETON_ROWS = 6;
764
1149
  var CARD_FIELD_LIMIT = 4;
@@ -770,12 +1155,14 @@ function DataGrid({
770
1155
  primaryColumn,
771
1156
  layout = "auto",
772
1157
  density,
1158
+ size,
773
1159
  initialState,
774
1160
  state: controlled,
775
1161
  onStateChange,
776
1162
  gridId,
777
1163
  storage,
778
- selectionMode = "none",
1164
+ selectionMode: selectionProp = "none",
1165
+ clipboard,
779
1166
  bulkActions,
780
1167
  onRowPress,
781
1168
  onCellEditCommit,
@@ -789,18 +1176,18 @@ function DataGrid({
789
1176
  style,
790
1177
  motion = "full"
791
1178
  }) {
792
- const { styles } = useStyles(sheet2);
1179
+ const { styles } = useStyles(sheet3);
793
1180
  const theme = useLoamTheme("data-grid");
794
1181
  const level = useResolvedMotion(motion, "data-grid");
795
1182
  const labels = useLabels("dataGrid", DEFAULT_DATA_GRID_LABELS, labelsProp);
796
1183
  const providerLocale = useLoamLocale();
797
1184
  const locale = localeProp ?? providerLocale;
798
- const resolved = React2.useMemo(() => resolveColumns(columns), [columns]);
799
- const identify = React2.useMemo(
1185
+ const resolved = React3.useMemo(() => resolveColumns(columns), [columns]);
1186
+ const identify = React3.useMemo(
800
1187
  () => getRowId ?? ((row) => String(row.id)),
801
1188
  [getRowId]
802
1189
  );
803
- const seed = React2.useMemo(
1190
+ const seed = React3.useMemo(
804
1191
  () => density ? { ...initialState, density } : initialState ?? {},
805
1192
  // `density` is a starting tier, not a controlled slice — a caller that wants
806
1193
  // to own it passes `state={{ density }}`, which is the one write path.
@@ -815,7 +1202,7 @@ function DataGrid({
815
1202
  gridId,
816
1203
  storage
817
1204
  });
818
- const setState = React2.useCallback(
1205
+ const setState = React3.useCallback(
819
1206
  (...args) => {
820
1207
  if (args[1] === "sort" && level === "full") {
821
1208
  const ds = theme.spring.ds;
@@ -828,11 +1215,11 @@ function DataGrid({
828
1215
  },
829
1216
  [writeState, level, theme.spring.ds]
830
1217
  );
831
- const visibleColumns = React2.useMemo(
1218
+ const visibleColumns = React3.useMemo(
832
1219
  () => state.columnOrder.map((id) => resolved.find((c) => c.id === id)).filter((c) => !!c && state.columnVisibility[c.id] !== false),
833
1220
  [resolved, state.columnOrder, state.columnVisibility]
834
1221
  );
835
- const ctx = React2.useMemo(
1222
+ const ctx = React3.useMemo(
836
1223
  () => ({
837
1224
  columnsById: new Map(resolved.map((c) => [c.id, c])),
838
1225
  getRowId: identify,
@@ -849,7 +1236,7 @@ function DataGrid({
849
1236
  }),
850
1237
  [resolved, identify, state.formulas, locale, currency, now, labels]
851
1238
  );
852
- const model = React2.useMemo(
1239
+ const model = React3.useMemo(
853
1240
  () => buildRowModel({
854
1241
  rows,
855
1242
  visibleColumns,
@@ -861,15 +1248,30 @@ function DataGrid({
861
1248
  }),
862
1249
  [rows, visibleColumns, state, ctx]
863
1250
  );
864
- const [width, setWidth] = React2.useState(0);
1251
+ const [width, setWidth] = React3.useState(0);
865
1252
  const onLayout = (event) => {
866
1253
  const next = event.nativeEvent.layout.width;
867
1254
  if (next > 0 && Math.abs(next - width) > 1) setWidth(next);
868
1255
  };
869
1256
  const table = layout === "table" || layout === "auto" && width >= TABLE_MIN_WIDTH;
870
- const rowHeight = Math.max(DENSITY_ROW_PX[state.density], theme.tapMin);
871
- const [message, setMessage] = React2.useState("");
872
- const toggleSort = React2.useCallback(
1257
+ const rangeMode = selectionProp === "range" && table;
1258
+ const selectionMode = selectionProp === "range" ? table ? "none" : "multi" : selectionProp;
1259
+ const android = isAndroidIdiom(theme);
1260
+ const rowHeight = size ? theme.ctl[size] : Math.max(DENSITY_ROW_PX[state.density], android ? theme.space[56] : theme.tapMin);
1261
+ const [message, setMessage] = React3.useState("");
1262
+ const range = useNativeRange({
1263
+ enabled: rangeMode,
1264
+ nodes: model.nodes,
1265
+ columns: visibleColumns,
1266
+ ctx,
1267
+ range: state.range,
1268
+ setRange: (next) => setState({ range: next, focusedCell: next?.focus ?? null }, "range"),
1269
+ onCellEditCommit,
1270
+ clipboard,
1271
+ labels,
1272
+ announce: setMessage
1273
+ });
1274
+ const toggleSort = React3.useCallback(
873
1275
  (colId) => {
874
1276
  const column = resolved.find((c) => c.id === colId);
875
1277
  if (!column?.sortable) return;
@@ -889,15 +1291,15 @@ function DataGrid({
889
1291
  },
890
1292
  [resolved, state.sorting, setState, labels]
891
1293
  );
892
- const selectedIds = React2.useMemo(
1294
+ const selectedIds = React3.useMemo(
893
1295
  () => Object.keys(state.rowSelection).filter((id) => state.rowSelection[id]),
894
1296
  [state.rowSelection]
895
1297
  );
896
- const selectedRows = React2.useMemo(
1298
+ const selectedRows = React3.useMemo(
897
1299
  () => model.filteredRows.filter((row) => state.rowSelection[identify(row)]),
898
1300
  [model.filteredRows, state.rowSelection, identify]
899
1301
  );
900
- const toggleRow = React2.useCallback(
1302
+ const toggleRow = React3.useCallback(
901
1303
  (row) => {
902
1304
  const id = identify(row);
903
1305
  const next = selectionMode === "single" ? state.rowSelection[id] ? {} : { [id]: true } : { ...state.rowSelection };
@@ -909,10 +1311,10 @@ function DataGrid({
909
1311
  },
910
1312
  [identify, selectionMode, state.rowSelection, setState]
911
1313
  );
912
- const clearSelection = React2.useCallback(() => {
1314
+ const clearSelection = React3.useCallback(() => {
913
1315
  setState({ rowSelection: {} }, "select");
914
1316
  }, [setState]);
915
- const toggleGroup = React2.useCallback(
1317
+ const toggleGroup = React3.useCallback(
916
1318
  (key) => {
917
1319
  const next = { ...state.expanded };
918
1320
  if (next[key]) delete next[key];
@@ -921,21 +1323,21 @@ function DataGrid({
921
1323
  },
922
1324
  [state.expanded, setState]
923
1325
  );
924
- const [openSheet, setOpenSheet] = React2.useState(null);
925
- const [detailId, setDetailId] = React2.useState(null);
926
- const detail = React2.useMemo(
1326
+ const [openSheet, setOpenSheet] = React3.useState(null);
1327
+ const [detailId, setDetailId] = React3.useState(null);
1328
+ const detail = React3.useMemo(
927
1329
  () => detailId == null ? null : rows.find((row) => identify(row) === detailId) ?? null,
928
1330
  [rows, detailId, identify]
929
1331
  );
930
- const openRow = React2.useCallback(
1332
+ const openRow = React3.useCallback(
931
1333
  (row) => {
932
1334
  if (onRowPress) onRowPress(row);
933
1335
  else setDetailId(identify(row));
934
1336
  },
935
1337
  [onRowPress, identify]
936
1338
  );
937
- const [focusIndex, setFocusIndex] = React2.useState(0);
938
- const leaves = React2.useMemo(
1339
+ const [focusIndex, setFocusIndex] = React3.useState(0);
1340
+ const leaves = React3.useMemo(
939
1341
  () => model.nodes.filter((n) => n.kind === "leaf"),
940
1342
  [model.nodes]
941
1343
  );
@@ -951,7 +1353,7 @@ function DataGrid({
951
1353
  }
952
1354
  };
953
1355
  const keyProps = { onKeyDown: onGridKey };
954
- const primary = React2.useMemo(
1356
+ const primary = React3.useMemo(
955
1357
  () => visibleColumns.find((c) => c.id === primaryColumn) ?? visibleColumns[0],
956
1358
  [visibleColumns, primaryColumn]
957
1359
  );
@@ -990,6 +1392,7 @@ function DataGrid({
990
1392
  selectionMode,
991
1393
  focusIndex,
992
1394
  leaves,
1395
+ range: rangeMode ? range : null,
993
1396
  onToggleSort: toggleSort,
994
1397
  onToggleRow: toggleRow,
995
1398
  onToggleGroup: toggleGroup,
@@ -1020,7 +1423,16 @@ function DataGrid({
1020
1423
  style: [styles.root, style],
1021
1424
  ...keyProps,
1022
1425
  children: [
1023
- /* @__PURE__ */ jsx(
1426
+ android && selectedIds.length > 0 ? /* @__PURE__ */ jsx(
1427
+ ContextualAppBar,
1428
+ {
1429
+ count: selectedIds.length,
1430
+ actions: bulkActions,
1431
+ rows: selectedRows,
1432
+ onClear: clearSelection,
1433
+ labels
1434
+ }
1435
+ ) : /* @__PURE__ */ jsx(
1024
1436
  GridToolbar,
1025
1437
  {
1026
1438
  label,
@@ -1058,7 +1470,7 @@ function DataGrid({
1058
1470
  labels
1059
1471
  }
1060
1472
  ) : null,
1061
- selectedIds.length > 0 ? /* @__PURE__ */ jsx(
1473
+ !android && selectedIds.length > 0 ? /* @__PURE__ */ jsx(
1062
1474
  BulkBar,
1063
1475
  {
1064
1476
  count: selectedIds.length,
@@ -1151,7 +1563,7 @@ function GridToolbar({
1151
1563
  onOpen,
1152
1564
  labels
1153
1565
  }) {
1154
- const { styles } = useStyles(sheet2);
1566
+ const { styles } = useStyles(sheet3);
1155
1567
  return /* @__PURE__ */ jsxs(View, { style: styles.toolbar, children: [
1156
1568
  searchable ? /* @__PURE__ */ jsx(
1157
1569
  Input,
@@ -1206,7 +1618,7 @@ function ToolPill({
1206
1618
  activeLabel,
1207
1619
  onPress
1208
1620
  }) {
1209
- const { styles } = useStyles(sheet2);
1621
+ const { styles } = useStyles(sheet3);
1210
1622
  const theme = useLoamTheme("data-grid");
1211
1623
  return /* @__PURE__ */ jsxs(
1212
1624
  Pressable,
@@ -1230,7 +1642,7 @@ function CountLine({
1230
1642
  busy,
1231
1643
  labels
1232
1644
  }) {
1233
- const { styles } = useStyles(sheet2);
1645
+ const { styles } = useStyles(sheet3);
1234
1646
  return /* @__PURE__ */ jsxs(View, { style: styles.countLine, children: [
1235
1647
  /* @__PURE__ */ jsx(Text, { style: styles.countText, children: labels.countLine(shown, total, selected) }),
1236
1648
  busy ? /* @__PURE__ */ jsx(Spinner, { size: "sm" }) : null
@@ -1246,16 +1658,28 @@ function TableSurface({
1246
1658
  focusIndex,
1247
1659
  leaves,
1248
1660
  onToggleSort,
1661
+ range,
1249
1662
  onToggleRow,
1250
1663
  onToggleGroup,
1251
1664
  onOpenRow,
1252
1665
  labels
1253
1666
  }) {
1254
- const { styles } = useStyles(sheet2);
1667
+ const { styles } = useStyles(sheet3);
1255
1668
  const theme = useLoamTheme("data-grid");
1256
1669
  const selectWidth = selectionMode === "none" ? 0 : theme.tapMin;
1257
1670
  const widths = columns.map((c) => state.columnSizing[c.id] ?? c.size);
1258
1671
  const total = widths.reduce((sum, w) => sum + w, 0) + selectWidth;
1672
+ const scrollY = React3.useRef(new Animated.Value(0)).current;
1673
+ const [headerH, setHeaderH] = React3.useState(rowHeight);
1674
+ const geometry = React3.useMemo(() => {
1675
+ const lefts = [];
1676
+ let x = selectWidth;
1677
+ for (const w of widths) {
1678
+ lefts.push(x);
1679
+ x += w;
1680
+ }
1681
+ return { lefts, widths, rowHeight, rows: model.nodes.length };
1682
+ }, [widths, selectWidth, rowHeight, model.nodes.length]);
1259
1683
  const renderNode = ({ item, index }) => {
1260
1684
  if (item.kind === "group") {
1261
1685
  return /* @__PURE__ */ jsx(
@@ -1289,20 +1713,52 @@ function TableSurface({
1289
1713
  styles.tableRow,
1290
1714
  { width: total, minHeight: rowHeight },
1291
1715
  state.zebra && index % 2 === 1 && styles.zebra,
1292
- selected && styles.selectedRow,
1293
- focused && styles.focusedRow
1716
+ selected && styles.selectedRow
1294
1717
  ],
1295
1718
  children: [
1719
+ focused ? /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: styles.focusedRow }) : null,
1296
1720
  selectionMode === "none" ? null : /* @__PURE__ */ jsx(View, { style: [styles.selectCell, { width: selectWidth }], children: /* @__PURE__ */ jsx(
1297
- Checkbox,
1721
+ RowMark,
1298
1722
  {
1299
- checked: selected,
1300
- onCheckedChange: () => onToggleRow(item.row),
1301
- accessibilityLabel: labels.selectRow(name),
1302
- size: "sm"
1723
+ selected,
1724
+ onToggle: () => onToggleRow(item.row),
1725
+ accessibilityLabel: labels.selectRow(name)
1303
1726
  }
1304
1727
  ) }),
1305
- /* @__PURE__ */ jsx(
1728
+ range ? /* @__PURE__ */ jsx(View, { style: styles.tableRowBody, children: columns.map((column, i) => {
1729
+ const rect = range.rect;
1730
+ const inRange = !!rect && index >= rect.r0 && index <= rect.r1 && i >= rect.c0 && i <= rect.c1;
1731
+ const anchor = range.anchor?.rowId === item.id && range.anchor.colId === column.id;
1732
+ const multi = !!rect && (rect.r1 > rect.r0 || rect.c1 > rect.c0);
1733
+ return /* @__PURE__ */ jsx(
1734
+ Pressable,
1735
+ {
1736
+ accessibilityRole: "button",
1737
+ accessibilityLabel: labels.cellName(
1738
+ column.header,
1739
+ String(formatValue(ctx, column, getValue(ctx, item.row, column.id), item.row))
1740
+ ),
1741
+ accessibilityState: { selected: inRange },
1742
+ onPress: () => anchor && !multi ? onOpenRow(item.row) : range.press(index, i),
1743
+ onLongPress: () => range.longPress(index, i),
1744
+ style: ({ pressed }) => [
1745
+ inRange && multi && !anchor && styles.rangeWash,
1746
+ pressed && styles.pressed
1747
+ ],
1748
+ children: /* @__PURE__ */ jsx(
1749
+ Cell,
1750
+ {
1751
+ column,
1752
+ ctx,
1753
+ row: item.row,
1754
+ width: widths[i],
1755
+ depth: i === 0 ? item.depth : 0
1756
+ }
1757
+ )
1758
+ },
1759
+ column.id
1760
+ );
1761
+ }) }) : /* @__PURE__ */ jsx(
1306
1762
  Pressable,
1307
1763
  {
1308
1764
  accessibilityRole: "button",
@@ -1335,24 +1791,32 @@ function TableSurface({
1335
1791
  {
1336
1792
  horizontal: true,
1337
1793
  showsHorizontalScrollIndicator: true,
1794
+ style: styles.tableScroll,
1338
1795
  contentContainerStyle: { minWidth: "100%" },
1339
1796
  children: /* @__PURE__ */ jsxs(View, { style: { width: total, flex: 1 }, children: [
1340
- /* @__PURE__ */ jsxs(View, { style: [styles.headerRow, { width: total, minHeight: rowHeight }], children: [
1341
- selectionMode === "none" ? null : /* @__PURE__ */ jsx(View, { style: { width: selectWidth } }),
1342
- columns.map((column, i) => /* @__PURE__ */ jsx(
1343
- HeaderCell,
1344
- {
1345
- column,
1346
- width: widths[i],
1347
- sort: state.sorting.find((s) => s.id === column.id),
1348
- rank: state.sorting.findIndex((s) => s.id === column.id),
1349
- multi: state.sorting.length > 1,
1350
- onPress: () => onToggleSort(column.id),
1351
- labels
1352
- },
1353
- column.id
1354
- ))
1355
- ] }),
1797
+ /* @__PURE__ */ jsxs(
1798
+ View,
1799
+ {
1800
+ onLayout: (e) => setHeaderH(e.nativeEvent.layout.height),
1801
+ style: [styles.headerRow, { width: total, minHeight: rowHeight }],
1802
+ children: [
1803
+ selectionMode === "none" ? null : /* @__PURE__ */ jsx(View, { style: { width: selectWidth } }),
1804
+ columns.map((column, i) => /* @__PURE__ */ jsx(
1805
+ HeaderCell,
1806
+ {
1807
+ column,
1808
+ width: widths[i],
1809
+ sort: state.sorting.find((s) => s.id === column.id),
1810
+ rank: state.sorting.findIndex((s) => s.id === column.id),
1811
+ multi: state.sorting.length > 1,
1812
+ onPress: () => onToggleSort(column.id),
1813
+ labels
1814
+ },
1815
+ column.id
1816
+ ))
1817
+ ]
1818
+ }
1819
+ ),
1356
1820
  /* @__PURE__ */ jsx(
1357
1821
  FlatList,
1358
1822
  {
@@ -1364,9 +1828,24 @@ function TableSurface({
1364
1828
  length: rowHeight,
1365
1829
  offset: rowHeight * index,
1366
1830
  index
1367
- })
1831
+ }),
1832
+ onScroll: range ? Animated.event([{ nativeEvent: { contentOffset: { y: scrollY } } }], {
1833
+ useNativeDriver: false
1834
+ }) : void 0,
1835
+ scrollEventThrottle: 16,
1836
+ extraData: range?.rect
1368
1837
  }
1369
- )
1838
+ ),
1839
+ range ? /* @__PURE__ */ jsx(
1840
+ RangeOverlay,
1841
+ {
1842
+ range,
1843
+ geometry,
1844
+ scrollY,
1845
+ top: headerH,
1846
+ labels
1847
+ }
1848
+ ) : null
1370
1849
  ] })
1371
1850
  }
1372
1851
  );
@@ -1380,8 +1859,10 @@ function HeaderCell({
1380
1859
  onPress,
1381
1860
  labels
1382
1861
  }) {
1383
- const { styles } = useStyles(sheet2);
1862
+ const { styles } = useStyles(sheet3);
1384
1863
  const theme = useLoamTheme("data-grid");
1864
+ const android = isAndroidIdiom(theme);
1865
+ const head = resolveTextRole(theme, android ? "labelLarge" : "footnote", android);
1385
1866
  return /* @__PURE__ */ jsxs(
1386
1867
  Pressable,
1387
1868
  {
@@ -1398,18 +1879,32 @@ function HeaderCell({
1398
1879
  style: ({ pressed }) => [
1399
1880
  styles.headerCell,
1400
1881
  { width },
1401
- column.align === "end" && styles.alignEnd,
1402
- column.align === "center" && styles.alignCentre,
1882
+ column.align === "end" && styles.headerEnd,
1883
+ column.align === "center" && styles.headerCentre,
1403
1884
  pressed && styles.pressed
1404
1885
  ],
1405
1886
  children: [
1406
- /* @__PURE__ */ jsxs(Text, { numberOfLines: 1, style: styles.headerText, children: [
1407
- column.header,
1408
- column.headerUnit ? /* @__PURE__ */ jsxs(Text, { style: styles.headerUnit, children: [
1409
- " ",
1410
- column.headerUnit
1411
- ] }) : null
1412
- ] }),
1887
+ /* @__PURE__ */ jsxs(
1888
+ Text,
1889
+ {
1890
+ numberOfLines: 1,
1891
+ style: [
1892
+ styles.headerText,
1893
+ {
1894
+ fontSize: head.fontSize,
1895
+ lineHeight: head.lineHeight,
1896
+ fontWeight: android ? head.fontWeight : theme.fontWeight.semibold
1897
+ }
1898
+ ],
1899
+ children: [
1900
+ column.header,
1901
+ column.headerUnit ? /* @__PURE__ */ jsxs(Text, { style: styles.headerUnit, children: [
1902
+ " ",
1903
+ column.headerUnit
1904
+ ] }) : null
1905
+ ]
1906
+ }
1907
+ ),
1413
1908
  sort ? /* @__PURE__ */ jsxs(View, { style: styles.sortMark, children: [
1414
1909
  /* @__PURE__ */ jsx(
1415
1910
  Icon,
@@ -1425,6 +1920,45 @@ function HeaderCell({
1425
1920
  }
1426
1921
  );
1427
1922
  }
1923
+ function RowMark({
1924
+ selected,
1925
+ onToggle,
1926
+ accessibilityLabel
1927
+ }) {
1928
+ const { styles } = useStyles(sheet3);
1929
+ const theme = useLoamTheme("data-grid");
1930
+ if (isAndroidIdiom(theme)) {
1931
+ return /* @__PURE__ */ jsx(
1932
+ Checkbox,
1933
+ {
1934
+ checked: selected,
1935
+ onCheckedChange: onToggle,
1936
+ accessibilityLabel,
1937
+ size: "sm"
1938
+ }
1939
+ );
1940
+ }
1941
+ return /* @__PURE__ */ jsx(
1942
+ Pressable,
1943
+ {
1944
+ accessibilityRole: "checkbox",
1945
+ accessibilityState: { checked: selected },
1946
+ "aria-checked": selected,
1947
+ accessibilityLabel,
1948
+ onPress: onToggle,
1949
+ style: styles.rowMarkHit,
1950
+ children: /* @__PURE__ */ jsx(View, { style: [styles.rowMark, selected && styles.rowMarkOn], children: selected ? /* @__PURE__ */ jsx(
1951
+ Icon,
1952
+ {
1953
+ name: "check",
1954
+ size: theme.icon.sm,
1955
+ color: theme.color.accentInk,
1956
+ strokeWidth: theme.icon.strokeBold
1957
+ }
1958
+ ) : null })
1959
+ }
1960
+ );
1961
+ }
1428
1962
  function Cell({
1429
1963
  column,
1430
1964
  ctx,
@@ -1432,10 +1966,11 @@ function Cell({
1432
1966
  width,
1433
1967
  depth
1434
1968
  }) {
1435
- const { styles } = useStyles(sheet2);
1969
+ const { styles } = useStyles(sheet3);
1436
1970
  const theme = useLoamTheme("data-grid");
1437
1971
  const value = getValue(ctx, row, column.id);
1438
1972
  const text = formatValue(ctx, column, value, row);
1973
+ const body = resolveTextRole(theme, "body", isAndroidIdiom(theme));
1439
1974
  return /* @__PURE__ */ jsx(
1440
1975
  View,
1441
1976
  {
@@ -1451,6 +1986,7 @@ function Cell({
1451
1986
  numberOfLines: 1,
1452
1987
  style: [
1453
1988
  styles.cellText,
1989
+ { fontSize: body.fontSize, lineHeight: body.lineHeight },
1454
1990
  column.mono && styles.mono,
1455
1991
  column.align === "end" && styles.tabular
1456
1992
  ],
@@ -1470,7 +2006,7 @@ function GroupRow({
1470
2006
  onToggle,
1471
2007
  labels
1472
2008
  }) {
1473
- const { styles } = useStyles(sheet2);
2009
+ const { styles } = useStyles(sheet3);
1474
2010
  const theme = useLoamTheme("data-grid");
1475
2011
  const field = ctx.columnsById.get(node.field);
1476
2012
  const summary = columns.map((c) => {
@@ -1525,7 +2061,7 @@ function CardSurface({
1525
2061
  onOpenRow,
1526
2062
  labels
1527
2063
  }) {
1528
- const { styles } = useStyles(sheet2);
2064
+ const { styles } = useStyles(sheet3);
1529
2065
  const fields = columns.filter((c) => c.id !== primary?.id);
1530
2066
  const shown = fields.slice(0, CARD_FIELD_LIMIT);
1531
2067
  const hidden = fields.length - shown.length;
@@ -1600,7 +2136,7 @@ function FooterStrip({
1600
2136
  state,
1601
2137
  labels
1602
2138
  }) {
1603
- const { styles } = useStyles(sheet2);
2139
+ const { styles } = useStyles(sheet3);
1604
2140
  const cells = columns.map((column) => ({ column, cell: model.footer[column.id] })).filter((entry) => !!entry.cell);
1605
2141
  if (cells.length === 0) return null;
1606
2142
  const filtered = model.filteredCount !== model.totalCount;
@@ -1626,7 +2162,7 @@ function BulkBar({
1626
2162
  onClear,
1627
2163
  labels
1628
2164
  }) {
1629
- const { styles } = useStyles(sheet2);
2165
+ const { styles } = useStyles(sheet3);
1630
2166
  const theme = useLoamTheme("data-grid");
1631
2167
  return /* @__PURE__ */ jsxs(View, { role: "toolbar", accessibilityLabel: labels.selectedCount(count), style: styles.bulkBar, children: [
1632
2168
  /* @__PURE__ */ jsx(
@@ -1645,10 +2181,10 @@ function BulkBar({
1645
2181
  {
1646
2182
  accessibilityRole: "button",
1647
2183
  accessibilityLabel: action.label,
1648
- onPress: () => action.onRun(rows),
2184
+ onPress: () => action.onSelect(rows),
1649
2185
  style: ({ pressed }) => [
1650
2186
  styles.bulkAction,
1651
- action.destructive && styles.bulkActionDanger,
2187
+ action.danger && styles.bulkActionDanger,
1652
2188
  pressed && styles.pressed
1653
2189
  ],
1654
2190
  children: [
@@ -1657,22 +2193,69 @@ function BulkBar({
1657
2193
  {
1658
2194
  name: action.icon,
1659
2195
  size: theme.icon.sm,
1660
- color: action.destructive ? theme.color.dangerInk : theme.color.accentInk
2196
+ color: action.danger ? theme.color.dangerInk : theme.color.accentInk
1661
2197
  }
1662
2198
  ) : null,
1663
- /* @__PURE__ */ jsx(
1664
- Text,
1665
- {
1666
- style: [styles.bulkActionText, action.destructive && styles.bulkActionTextDanger],
1667
- children: action.label
1668
- }
1669
- )
2199
+ /* @__PURE__ */ jsx(Text, { style: [styles.bulkActionText, action.danger && styles.bulkActionTextDanger], children: action.label })
1670
2200
  ]
1671
2201
  },
1672
2202
  action.id
1673
2203
  )) })
1674
2204
  ] });
1675
2205
  }
2206
+ function ContextualAppBar({
2207
+ count,
2208
+ actions,
2209
+ rows,
2210
+ onClear,
2211
+ labels
2212
+ }) {
2213
+ const { styles } = useStyles(sheet3);
2214
+ const theme = useLoamTheme("data-grid");
2215
+ const title = resolveTextRole(theme, "titleLarge", true);
2216
+ return /* @__PURE__ */ jsxs(View, { role: "toolbar", accessibilityLabel: labels.selectedCount(count), style: styles.cab, children: [
2217
+ /* @__PURE__ */ jsx(
2218
+ Pressable,
2219
+ {
2220
+ accessibilityRole: "button",
2221
+ accessibilityLabel: labels.clearSelection,
2222
+ onPress: onClear,
2223
+ style: ({ pressed }) => [styles.cabIcon, pressed && styles.pressed],
2224
+ children: /* @__PURE__ */ jsx(Icon, { name: "x", size: theme.icon.md, color: theme.color.text })
2225
+ }
2226
+ ),
2227
+ /* @__PURE__ */ jsx(
2228
+ Text,
2229
+ {
2230
+ numberOfLines: 1,
2231
+ accessibilityRole: "header",
2232
+ style: [styles.cabTitle, { fontSize: title.fontSize, lineHeight: title.lineHeight }],
2233
+ children: labels.selectedCount(count)
2234
+ }
2235
+ ),
2236
+ (actions ?? []).map((action) => /* @__PURE__ */ jsx(
2237
+ Pressable,
2238
+ {
2239
+ accessibilityRole: "button",
2240
+ accessibilityLabel: action.label,
2241
+ onPress: () => action.onSelect(rows),
2242
+ style: ({ pressed }) => [
2243
+ action.icon ? styles.cabIcon : styles.cabText,
2244
+ pressed && styles.pressed
2245
+ ],
2246
+ children: action.icon ? /* @__PURE__ */ jsx(
2247
+ Icon,
2248
+ {
2249
+ name: action.icon,
2250
+ size: theme.icon.md,
2251
+ color: action.danger ? theme.color.dangerOnSoft : theme.color.text2
2252
+ }
2253
+ ) : /* @__PURE__ */ jsx(Text, { style: [styles.cabActionText, action.danger && styles.cabActionDanger], children: action.label })
2254
+ },
2255
+ action.id
2256
+ ))
2257
+ ] });
2258
+ }
1676
2259
  function rowLabel(ctx, columns, row, labels) {
1677
2260
  return labels.rowSummary(
1678
2261
  columns.slice(0, CARD_FIELD_LIMIT + 1).map((column) => ({
@@ -1681,7 +2264,7 @@ function rowLabel(ctx, columns, row, labels) {
1681
2264
  }))
1682
2265
  );
1683
2266
  }
1684
- var sheet2 = createStyleSheet((theme) => ({
2267
+ var sheet3 = createStyleSheet((theme) => ({
1685
2268
  root: { flex: 1, alignSelf: "stretch", gap: theme.space.s2 },
1686
2269
  body: { flex: 1, minHeight: theme.space[40] },
1687
2270
  centre: { flex: 1, alignItems: "center", justifyContent: "center", padding: theme.space.s6 },
@@ -1759,11 +2342,10 @@ var sheet2 = createStyleSheet((theme) => ({
1759
2342
  },
1760
2343
  headerText: {
1761
2344
  flexShrink: 1,
2345
+ ...theme.type.footnote,
1762
2346
  fontFamily: theme.font.sans,
1763
- fontSize: theme.type.caption1.fontSize,
1764
- lineHeight: theme.type.caption1.lineHeight,
1765
- fontWeight: theme.fontWeight.bold,
1766
- color: theme.color.text
2347
+ fontWeight: theme.platform === "Android" ? theme.fontWeight.medium : theme.fontWeight.semibold,
2348
+ color: theme.color.text2
1767
2349
  },
1768
2350
  headerUnit: { fontWeight: theme.fontWeight.regular, color: theme.color.text2 },
1769
2351
  sortMark: { flexDirection: "row", alignItems: "center", gap: theme.space[2] },
@@ -1773,6 +2355,7 @@ var sheet2 = createStyleSheet((theme) => ({
1773
2355
  color: theme.color.accentOnSoft
1774
2356
  },
1775
2357
  tableBody: { flex: 1 },
2358
+ tableScroll: { flex: 1 },
1776
2359
  tableRow: {
1777
2360
  flexDirection: "row",
1778
2361
  alignItems: "stretch",
@@ -1782,9 +2365,33 @@ var sheet2 = createStyleSheet((theme) => ({
1782
2365
  },
1783
2366
  zebra: { backgroundColor: theme.color.surface2 },
1784
2367
  selectedRow: { backgroundColor: theme.state.selected },
2368
+ // loam-contrast-ignore — a selection-range wash spanning cells; a per-cell edge would stripe the grid.
2369
+ rangeWash: { backgroundColor: theme.color.accentSoft },
1785
2370
  focusedRow: {
1786
- borderStartWidth: theme.borderWidth.heavy,
1787
- borderStartColor: theme.focus.ringColor
2371
+ position: "absolute",
2372
+ top: 0,
2373
+ bottom: 0,
2374
+ start: 0,
2375
+ end: 0,
2376
+ borderWidth: theme.borderWidth.thick,
2377
+ borderColor: theme.focus.ringColor
2378
+ },
2379
+ // iOS edit-mode mark: a 20 circle, accent filled with the check when on.
2380
+ rowMark: {
2381
+ width: theme.icon.lg,
2382
+ height: theme.icon.lg,
2383
+ borderRadius: theme.radius.full,
2384
+ borderWidth: theme.borderWidth.thick,
2385
+ borderColor: theme.color.borderStrong,
2386
+ alignItems: "center",
2387
+ justifyContent: "center"
2388
+ },
2389
+ rowMarkOn: { backgroundColor: theme.color.accent, borderColor: theme.color.accent },
2390
+ rowMarkHit: {
2391
+ minWidth: theme.tapMin,
2392
+ minHeight: theme.tapMin,
2393
+ alignItems: "center",
2394
+ justifyContent: "center"
1788
2395
  },
1789
2396
  selectCell: { alignItems: "center", justifyContent: "center" },
1790
2397
  tableRowBody: { flex: 1, flexDirection: "row", alignItems: "center" },
@@ -1801,6 +2408,9 @@ var sheet2 = createStyleSheet((theme) => ({
1801
2408
  skeletonRows: { alignSelf: "stretch", gap: theme.space.s2, padding: theme.space.s3 },
1802
2409
  alignEnd: { alignItems: "flex-end" },
1803
2410
  alignCentre: { alignItems: "center" },
2411
+ // The header cell lays out in a row, so its alignment is on the main axis.
2412
+ headerEnd: { justifyContent: "flex-end" },
2413
+ headerCentre: { justifyContent: "center" },
1804
2414
  groupRow: {
1805
2415
  flexDirection: "row",
1806
2416
  alignItems: "center",
@@ -1907,6 +2517,34 @@ var sheet2 = createStyleSheet((theme) => ({
1907
2517
  backgroundColor: theme.color.accent,
1908
2518
  ...theme.shadow.md
1909
2519
  },
2520
+ cab: {
2521
+ flexDirection: "row",
2522
+ alignItems: "center",
2523
+ gap: theme.space[2],
2524
+ minHeight: theme.layout.appbarH,
2525
+ paddingHorizontal: theme.space[2],
2526
+ backgroundColor: theme.state.selected
2527
+ },
2528
+ cabIcon: {
2529
+ width: theme.tapMin,
2530
+ height: theme.tapMin,
2531
+ borderRadius: theme.radius.full,
2532
+ alignItems: "center",
2533
+ justifyContent: "center"
2534
+ },
2535
+ cabText: {
2536
+ minHeight: theme.tapMin,
2537
+ paddingHorizontal: theme.space.s3,
2538
+ justifyContent: "center"
2539
+ },
2540
+ cabTitle: { flex: 1, fontFamily: theme.font.sans, color: theme.color.text },
2541
+ cabActionText: {
2542
+ fontFamily: theme.font.sans,
2543
+ fontSize: theme.type.subheadline.fontSize,
2544
+ fontWeight: theme.fontWeight.medium,
2545
+ color: theme.color.accentOnSoft
2546
+ },
2547
+ cabActionDanger: { color: theme.color.dangerOnSoft },
1910
2548
  bulkClear: {
1911
2549
  minWidth: theme.tapMin,
1912
2550
  minHeight: theme.tapMin,