@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
@@ -0,0 +1,1110 @@
1
+ import { DateRangePicker } from './chunk-CLGAMIOT.js';
2
+ import { MonthList } from './chunk-TZO6YDS7.js';
3
+ import { Sheet } from './chunk-B7JZ3N5G.js';
4
+ import { Button } from './chunk-5DTKORLI.js';
5
+ import { resolveTextRole } from './chunk-L4D5LHCH.js';
6
+ import { Skeleton } from './chunk-YJ5PXOX3.js';
7
+ import { SegmentedControl } from './chunk-NZG75DGA.js';
8
+ import { FieldMessage } from './chunk-BTRMA7GC.js';
9
+ import { Input } from './chunk-KXLDK6HB.js';
10
+ import { isAndroidIdiom } from './chunk-TH4PW2WU.js';
11
+ import { useLoamLocale } from './chunk-APCWFOZW.js';
12
+ import { Icon } from './chunk-PCEFCOLN.js';
13
+ import * as React2 from 'react';
14
+ import { View, Pressable, Text, ScrollView } from 'react-native';
15
+ import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
16
+ import { dateZone, absolute } from '@btndprojects/loam-date';
17
+ import { jsxs, jsx } from 'react/jsx-runtime';
18
+
19
+ var ISO = /^(\d{4})-(\d{2})-(\d{2})$/;
20
+ var Z = dateZone();
21
+ var DAY_MS = 864e5;
22
+ var RADIUS = 6;
23
+ function isoToMs(value) {
24
+ const m = value ? ISO.exec(value) : null;
25
+ return m ? Z.ms(Number(m[1]), Number(m[2]) - 1, Number(m[3]), 0, 0, 0) : null;
26
+ }
27
+ function msToIso(ms) {
28
+ const w = Z.wall(ms);
29
+ return `${String(w.y).padStart(4, "0")}-${String(w.mo + 1).padStart(2, "0")}-${String(w.d).padStart(2, "0")}`;
30
+ }
31
+ function QueryDateField({
32
+ value,
33
+ onChange,
34
+ label,
35
+ android,
36
+ surface
37
+ }) {
38
+ const { styles } = useStyles(sheet);
39
+ const locale = useLoamLocale();
40
+ const ms = isoToMs(value);
41
+ const ctx = React2.useMemo(
42
+ () => ({ Z, now: Date.now(), weekStartsOn: 1, granularity: "day", mode: "single", locale }),
43
+ [locale]
44
+ );
45
+ if (android) {
46
+ return /* @__PURE__ */ jsx(
47
+ DateRangePicker,
48
+ {
49
+ mode: "single",
50
+ platform: "android",
51
+ surface,
52
+ label,
53
+ placeholder: "YYYY-MM-DD",
54
+ presets: false,
55
+ clearable: false,
56
+ value: ms === null ? null : absolute(ms, ms + DAY_MS),
57
+ onChange: (_, resolved) => {
58
+ if (resolved.from !== null) onChange(msToIso(resolved.from));
59
+ }
60
+ }
61
+ );
62
+ }
63
+ return /* @__PURE__ */ jsx(View, { accessibilityLabel: label, style: styles.calendar, children: /* @__PURE__ */ jsx(
64
+ MonthList,
65
+ {
66
+ Z,
67
+ anchorMs: ms ?? ctx.now ?? Date.now(),
68
+ radius: RADIUS,
69
+ ctx,
70
+ from: ms,
71
+ to: ms === null ? null : Z.startOfDay(ms + DAY_MS),
72
+ onPick: (picked) => onChange(msToIso(Z.startOfDay(picked)))
73
+ }
74
+ ) });
75
+ }
76
+ var sheet = createStyleSheet((theme) => ({
77
+ calendar: { height: theme.space[256], minHeight: theme.space[224] }
78
+ }));
79
+
80
+ // src/query-builder/query-model.ts
81
+ function isGroup(node) {
82
+ return "children" in node;
83
+ }
84
+ var counter = 0;
85
+ function newGroupId() {
86
+ counter += 1;
87
+ return `g${counter}`;
88
+ }
89
+ function makeGroup(join = "AND", children = []) {
90
+ return { id: newGroupId(), join, children };
91
+ }
92
+ var NO_VALUE = /^(is (not )?(empty|set|null)|has no value|is blank)$/i;
93
+ var BETWEEN = /\bbetween\b/i;
94
+ var MULTI = /\b(any|none) of\b|\bin\b$|^in$/i;
95
+ var WITHIN = /^(in the last|within|in the next)$/i;
96
+ function editorFor(def, operator) {
97
+ if (NO_VALUE.test(operator)) return "none";
98
+ const type = def?.type;
99
+ if (!type) return "enum";
100
+ const between = BETWEEN.test(operator);
101
+ if (type === "text") return "text";
102
+ if (type === "number") return between ? "between" : "number";
103
+ if (type === "date") return between ? "between-date" : WITHIN.test(operator) ? "relative" : "date";
104
+ if (type === "boolean") return "boolean";
105
+ return def?.multiple || MULTI.test(operator) ? "multi" : "enum";
106
+ }
107
+ function emptyValue(def, operator) {
108
+ switch (editorFor(def, operator)) {
109
+ case "none":
110
+ return null;
111
+ case "enum":
112
+ return def?.values[0] ?? "";
113
+ case "multi":
114
+ return [];
115
+ case "between":
116
+ case "between-date":
117
+ return [null, null];
118
+ case "relative":
119
+ return { amount: null, unit: def?.units?.[0] ?? "days" };
120
+ case "boolean":
121
+ return null;
122
+ default:
123
+ return null;
124
+ }
125
+ }
126
+ var ISO2 = /^\d{4}-\d{2}-\d{2}$/;
127
+ function toNum(v) {
128
+ return typeof v === "number" ? v : Number(String(v ?? "").replace(/[,\s]/g, ""));
129
+ }
130
+ function blank(v) {
131
+ return v === null || v === void 0 || v === "" || typeof v === "number" && Number.isNaN(v);
132
+ }
133
+ function conditionIssue(c, def) {
134
+ const kind = editorFor(def, c.operator);
135
+ const v = c.value;
136
+ switch (kind) {
137
+ case "none":
138
+ return null;
139
+ case "enum":
140
+ return !def?.type ? null : blank(v) ? { kind: "empty", message: "Add a value, or remove this condition." } : null;
141
+ case "multi":
142
+ return Array.isArray(v) && v.length > 0 ? null : { kind: "empty", message: "Pick at least one value, or remove this condition." };
143
+ case "between":
144
+ case "between-date": {
145
+ const [a, b] = Array.isArray(v) ? v : [null, null];
146
+ if (blank(a) || blank(b)) return { kind: "empty", message: "Add both values, or remove this condition." };
147
+ if (kind === "between-date" && !(ISO2.test(String(a)) && ISO2.test(String(b)))) {
148
+ return { kind: "parse", message: "Use dates like 2026-10-12." };
149
+ }
150
+ const na = toNum(a);
151
+ const nb = toNum(b);
152
+ const larger = kind === "between" ? nb > na : String(b) > String(a);
153
+ if (kind === "between" && (Number.isNaN(na) || Number.isNaN(nb))) {
154
+ return { kind: "parse", message: "Enter numbers." };
155
+ }
156
+ return larger ? null : { kind: "range", message: "The second value must be larger than the first." };
157
+ }
158
+ case "relative": {
159
+ const amount = v && typeof v === "object" && !Array.isArray(v) ? v.amount : null;
160
+ return blank(amount) ? { kind: "empty", message: "Add a number, or remove this condition." } : null;
161
+ }
162
+ case "number": {
163
+ if (blank(v)) return { kind: "empty", message: "Add a value, or remove this condition." };
164
+ const n = toNum(v);
165
+ if (Number.isNaN(n)) return { kind: "parse", message: "Enter a number." };
166
+ if (def?.min !== void 0 && n < def.min) return { kind: "range", message: `Use ${def.min} or more.` };
167
+ if (def?.max !== void 0 && n > def.max) return { kind: "range", message: `Use ${def.max} or less.` };
168
+ return null;
169
+ }
170
+ case "date":
171
+ if (blank(v)) return { kind: "empty", message: "Add a value, or remove this condition." };
172
+ return ISO2.test(String(v)) ? null : { kind: "parse", message: "Use a date like 2026-10-12." };
173
+ default:
174
+ return blank(v) ? { kind: "empty", message: "Add a value, or remove this condition." } : null;
175
+ }
176
+ }
177
+ function collectIssues(root, fields) {
178
+ const out = [];
179
+ const walk = (g, path) => {
180
+ g.children.forEach((n, i) => {
181
+ if (isGroup(n)) return walk(n, [...path, i]);
182
+ const issue = conditionIssue(n, fields.find((f) => f.name === n.field));
183
+ if (issue) out.push({ path: [...path, i], ...issue });
184
+ });
185
+ };
186
+ walk(root, []);
187
+ return out;
188
+ }
189
+ function appliedGroup(root, fields) {
190
+ const prune = (g) => ({
191
+ ...g,
192
+ children: g.children.flatMap((n) => {
193
+ if (isGroup(n)) {
194
+ const inner = prune(n);
195
+ return inner.children.length > 0 ? [inner] : [];
196
+ }
197
+ return conditionIssue(n, fields.find((f) => f.name === n.field)) ? [] : [n];
198
+ })
199
+ });
200
+ return prune(root);
201
+ }
202
+ function countConditions(g) {
203
+ return g.children.reduce((n, c) => n + (isGroup(c) ? countConditions(c) : 1), 0);
204
+ }
205
+ function groupAt(root, path) {
206
+ let g = root;
207
+ for (const i of path) g = g.children[i];
208
+ return g;
209
+ }
210
+ function updateGroup(root, path, fn) {
211
+ if (path.length === 0) return fn(root);
212
+ const [head, ...rest] = path;
213
+ return {
214
+ ...root,
215
+ children: root.children.map((c, i) => i === head ? updateGroup(c, rest, fn) : c)
216
+ };
217
+ }
218
+ function escapeLiteral(value) {
219
+ return value.replace(/'/g, "''");
220
+ }
221
+ var SQL = {
222
+ is: "=",
223
+ "=": "=",
224
+ "is not": "!=",
225
+ "!=": "!=",
226
+ ">": ">",
227
+ "is over": ">",
228
+ "is greater than": ">",
229
+ after: ">",
230
+ "is after": ">",
231
+ "<": "<",
232
+ "is under": "<",
233
+ "is less than": "<",
234
+ before: "<",
235
+ "is before": "<",
236
+ ">=": ">=",
237
+ "is at least": ">=",
238
+ "is on or after": ">=",
239
+ "<=": "<=",
240
+ "is at most": "<=",
241
+ "is on or before": "<="
242
+ };
243
+ var quote = (s) => `'${escapeLiteral(s)}'`;
244
+ function formatCondition(c, def) {
245
+ const col = c.field.toLowerCase();
246
+ const kind = editorFor(def, c.operator);
247
+ const v = c.value;
248
+ const op = c.operator.toLowerCase();
249
+ if (!def?.type) return `${col} ${c.operator} ${quote(String(v ?? ""))}`;
250
+ if (kind === "none") return `${col} ${/not/.test(op) ? "IS NOT NULL" : "IS NULL"}`;
251
+ if (kind === "multi") {
252
+ const list = (Array.isArray(v) ? v : []).map((x) => quote(String(x))).join(", ");
253
+ return `${col} ${/none of|not in/.test(op) ? "NOT IN" : "IN"} (${list})`;
254
+ }
255
+ if (kind === "between" || kind === "between-date") {
256
+ const [a, b] = Array.isArray(v) ? v : [null, null];
257
+ const f = (x) => kind === "between" ? String(toNum(x)) : quote(String(x));
258
+ return `${col} ${/not/.test(op) ? "NOT BETWEEN" : "BETWEEN"} ${f(a)} AND ${f(b)}`;
259
+ }
260
+ if (kind === "relative") {
261
+ const r = v;
262
+ return `${col} >= now() - INTERVAL ${quote(`${r.amount} ${r.unit}`)}`;
263
+ }
264
+ if (kind === "boolean") {
265
+ const t = v === true || v === "Yes";
266
+ return `${col} ${/not/.test(op) ? "!=" : "="} ${t ? "TRUE" : "FALSE"}`;
267
+ }
268
+ if (kind === "text") {
269
+ const s = String(v ?? "");
270
+ if (op === "contains") return `${col} LIKE ${quote(`%${s}%`)}`;
271
+ if (op === "does not contain") return `${col} NOT LIKE ${quote(`%${s}%`)}`;
272
+ if (op === "starts with") return `${col} LIKE ${quote(`${s}%`)}`;
273
+ return `${col} ${SQL[op] ?? c.operator} ${quote(s)}`;
274
+ }
275
+ if (kind === "number") return `${col} ${SQL[op] ?? c.operator} ${toNum(v)}`;
276
+ return `${col} ${SQL[op] ?? c.operator} ${quote(String(v ?? ""))}`;
277
+ }
278
+ function formatNode(n, fields, nested) {
279
+ if (!isGroup(n)) return formatCondition(n, fields.find((f) => f.name === n.field));
280
+ const inner = n.children.map((c) => formatNode(c, fields, true)).join(` ${n.join} `);
281
+ return nested ? `(${inner})` : inner;
282
+ }
283
+ function formatGroup(root, fields, table = "projects") {
284
+ if (root.children.length === 0) return "";
285
+ const lines = root.children.map((c) => formatNode(c, fields, true));
286
+ return `SELECT * FROM ${table}
287
+ WHERE ${lines.join(`
288
+ ${root.join} `)}`;
289
+ }
290
+ function formatBody(root, fields) {
291
+ return root.children.map((c) => formatNode(c, fields, true)).join(`
292
+ ${root.join} `);
293
+ }
294
+ function tokenize(text) {
295
+ const out = [];
296
+ let line = 1;
297
+ let i = 0;
298
+ while (i < text.length) {
299
+ const ch = text[i];
300
+ if (ch === "\n") {
301
+ line += 1;
302
+ i += 1;
303
+ continue;
304
+ }
305
+ if (/\s/.test(ch)) {
306
+ i += 1;
307
+ continue;
308
+ }
309
+ if (ch === "-" && text[i + 1] === "-") {
310
+ while (i < text.length && text[i] !== "\n") i += 1;
311
+ continue;
312
+ }
313
+ if (ch === "'") {
314
+ let s = "";
315
+ i += 1;
316
+ while (i < text.length) {
317
+ if (text[i] === "'" && text[i + 1] === "'") {
318
+ s += "'";
319
+ i += 2;
320
+ continue;
321
+ }
322
+ if (text[i] === "'") break;
323
+ s += text[i];
324
+ i += 1;
325
+ }
326
+ if (text[i] !== "'") return { line, message: "A quoted value is missing its closing quote." };
327
+ i += 1;
328
+ out.push({ t: "str", v: s, line });
329
+ continue;
330
+ }
331
+ const num = /^-?\d+(\.\d+)?/.exec(text.slice(i));
332
+ if (num && (ch !== "-" || !/\w/.test(text[i - 1] ?? " "))) {
333
+ out.push({ t: "num", v: num[0], line });
334
+ i += num[0].length;
335
+ continue;
336
+ }
337
+ const word = /^[A-Za-z_][\w.]*/.exec(text.slice(i));
338
+ if (word) {
339
+ out.push({ t: "word", v: word[0], line });
340
+ i += word[0].length;
341
+ continue;
342
+ }
343
+ const sym = /^(!=|<>|<=|>=|=|<|>|\(|\)|,|%|\*|-)/.exec(text.slice(i));
344
+ if (sym) {
345
+ out.push({ t: "sym", v: sym[0], line });
346
+ i += sym[0].length;
347
+ continue;
348
+ }
349
+ return { line, message: `Unexpected \u201C${ch}\u201D.` };
350
+ }
351
+ out.push({ t: "end", v: "", line });
352
+ return out;
353
+ }
354
+ function distance(a, b) {
355
+ const d = Array.from({ length: a.length + 1 }, (_, i) => [i, ...Array(b.length).fill(0)]);
356
+ for (let j = 1; j <= b.length; j += 1) d[0][j] = j;
357
+ for (let i = 1; i <= a.length; i += 1)
358
+ for (let j = 1; j <= b.length; j += 1)
359
+ d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
360
+ return d[a.length][b.length];
361
+ }
362
+ function operatorFor(def, sql, kinds) {
363
+ return def.operators.find((o) => {
364
+ const k = editorFor(def, o);
365
+ if (!kinds.includes(k)) return false;
366
+ const low = o.toLowerCase();
367
+ if (sql === "IS NULL") return NO_VALUE.test(o) && !/not/.test(low);
368
+ if (sql === "IS NOT NULL") return NO_VALUE.test(o) && /not/.test(low);
369
+ if (sql === "IN") return k === "multi" && !/none|not/.test(low);
370
+ if (sql === "NOT IN") return k === "multi" && /none|not/.test(low);
371
+ if (sql === "BETWEEN") return /between/.test(low) && !/not/.test(low);
372
+ if (sql === "NOT BETWEEN") return /not between/.test(low);
373
+ if (sql === "WITHIN") return k === "relative";
374
+ if (sql === "LIKE_C") return low === "contains";
375
+ if (sql === "NOT LIKE_C") return low === "does not contain";
376
+ if (sql === "LIKE_S") return low === "starts with";
377
+ return (SQL[low] ?? low) === sql;
378
+ });
379
+ }
380
+ function parseQuery(text, fields) {
381
+ const toks = tokenize(text);
382
+ if (!Array.isArray(toks)) return { error: toks };
383
+ let p = 0;
384
+ const peek = () => toks[p];
385
+ const isW = (t, w) => t.t === "word" && t.v.toUpperCase() === w;
386
+ const fail = (message, fix, at = peek()) => ({
387
+ error: { line: at.line, message, ...{} }
388
+ });
389
+ if (isW(peek(), "SELECT")) {
390
+ while (!isW(peek(), "WHERE") && peek().t !== "end") p += 1;
391
+ }
392
+ if (isW(peek(), "WHERE")) p += 1;
393
+ if (peek().t === "end") return { value: makeGroup("AND") };
394
+ const readValue = () => {
395
+ const t = peek();
396
+ if (t.t === "str") {
397
+ p += 1;
398
+ return { ok: t.v };
399
+ }
400
+ if (t.t === "num") {
401
+ p += 1;
402
+ return { ok: Number(t.v) };
403
+ }
404
+ if (t.t === "word" && /^(TRUE|FALSE)$/i.test(t.v)) {
405
+ p += 1;
406
+ return { ok: t.v.toUpperCase() };
407
+ }
408
+ return { error: { line: t.line, message: "Expected a value here." } };
409
+ };
410
+ const cond = () => {
411
+ const ft = peek();
412
+ if (ft.t !== "word") return { error: { line: ft.line, message: "Expected a field name here." } };
413
+ const def = fields.find((f) => f.name.toLowerCase() === ft.v.toLowerCase());
414
+ if (!def) {
415
+ const best = [...fields].sort((a, b) => distance(a.name.toLowerCase(), ft.v.toLowerCase()) - distance(b.name.toLowerCase(), ft.v.toLowerCase()))[0];
416
+ const near = best && distance(best.name.toLowerCase(), ft.v.toLowerCase()) <= 2 ? best.name.toLowerCase() : void 0;
417
+ return {
418
+ error: {
419
+ line: ft.line,
420
+ message: `there is no field called \u201C${ft.v}\u201D.${near ? ` Use \u201C${near}\u201D` : ""}`,
421
+ ...near ? { fix: { label: `Use \u201C${near}\u201D`, text: text.replace(new RegExp(`\\b${ft.v}\\b`), near) } } : {}
422
+ }
423
+ };
424
+ }
425
+ p += 1;
426
+ const t = peek();
427
+ const mk = (sql, kinds, value) => {
428
+ const operator = operatorFor(def, sql, kinds);
429
+ if (!operator) return { error: { line: t.line, message: `\u201C${def.name.toLowerCase()}\u201D does not support ${sql}.` } };
430
+ return { ok: { field: def.name, operator, value } };
431
+ };
432
+ const typed = !!def.type;
433
+ if (isW(t, "IS")) {
434
+ p += 1;
435
+ const not2 = isW(peek(), "NOT");
436
+ if (not2) p += 1;
437
+ if (!isW(peek(), "NULL")) return { error: { line: peek().line, message: "Expected NULL after IS." } };
438
+ p += 1;
439
+ return mk(not2 ? "IS NOT NULL" : "IS NULL", ["none"], null);
440
+ }
441
+ let not = false;
442
+ if (isW(t, "NOT")) {
443
+ not = true;
444
+ p += 1;
445
+ }
446
+ const k = peek();
447
+ if (isW(k, "IN")) {
448
+ p += 1;
449
+ if (peek().v !== "(") return { error: { line: peek().line, message: "Expected ( after IN." } };
450
+ p += 1;
451
+ const list = [];
452
+ for (; ; ) {
453
+ const v = readValue();
454
+ if ("error" in v) return v;
455
+ list.push(String(v.ok));
456
+ if (peek().v === ",") {
457
+ p += 1;
458
+ continue;
459
+ }
460
+ break;
461
+ }
462
+ if (peek().v !== ")") return { error: { line: peek().line, message: "Expected ) to close the list." } };
463
+ p += 1;
464
+ return mk(not ? "NOT IN" : "IN", ["multi"], list);
465
+ }
466
+ if (isW(k, "BETWEEN")) {
467
+ p += 1;
468
+ const a = readValue();
469
+ if ("error" in a) return a;
470
+ if (!isW(peek(), "AND")) return { error: { line: peek().line, message: "Expected AND between the two values." } };
471
+ p += 1;
472
+ const b = readValue();
473
+ if ("error" in b) return b;
474
+ return mk(not ? "NOT BETWEEN" : "BETWEEN", ["between", "between-date"], [a.ok, b.ok]);
475
+ }
476
+ if (isW(k, "LIKE")) {
477
+ p += 1;
478
+ const v = readValue();
479
+ if ("error" in v) return v;
480
+ const s = String(v.ok);
481
+ const lead = s.startsWith("%");
482
+ const trail = s.endsWith("%");
483
+ const core = s.replace(/^%|%$/g, "");
484
+ if (lead && trail) return mk(not ? "NOT LIKE_C" : "LIKE_C", ["text"], core);
485
+ if (trail && !not) return mk("LIKE_S", ["text"], core);
486
+ return { error: { line: k.line, message: "Use LIKE with %value% or value%." } };
487
+ }
488
+ if (k.t === "sym" && ["=", "!=", "<>", "<", ">", "<=", ">="].includes(k.v)) {
489
+ p += 1;
490
+ const sql = k.v === "<>" ? "!=" : k.v;
491
+ if (isW(peek(), "NOW")) {
492
+ p += 1;
493
+ while (peek().v === "(" || peek().v === ")" || peek().v === "-" || isW(peek(), "INTERVAL")) p += 1;
494
+ const v2 = readValue();
495
+ if ("error" in v2) return v2;
496
+ const [amount, unit] = String(v2.ok).split(" ");
497
+ return mk("WITHIN", ["relative"], { amount: Number(amount), unit: unit ?? "days" });
498
+ }
499
+ const v = readValue();
500
+ if ("error" in v) return v;
501
+ if (typed && def.type === "boolean") {
502
+ return mk(sql, ["boolean"], String(v.ok).toUpperCase() === "TRUE");
503
+ }
504
+ const kinds = ["text", "number", "date", "enum"];
505
+ return mk(sql, kinds, typeof v.ok === "number" ? v.ok : v.ok);
506
+ }
507
+ return { error: { line: k.line, message: "Expected an operator after the field." } };
508
+ };
509
+ const expr = (depth) => {
510
+ const children = [];
511
+ let join = null;
512
+ for (; ; ) {
513
+ if (peek().v === "(") {
514
+ p += 1;
515
+ const inner = expr();
516
+ if ("error" in inner) return inner;
517
+ if (peek().v !== ")") return { error: { line: peek().line, message: "Expected ) to close the group." } };
518
+ p += 1;
519
+ children.push(inner.ok);
520
+ } else {
521
+ const c = cond();
522
+ if ("error" in c) return c;
523
+ children.push(c.ok);
524
+ }
525
+ const n = peek();
526
+ if (isW(n, "AND") || isW(n, "OR")) {
527
+ const j = n.v.toUpperCase();
528
+ if (join && join !== j) {
529
+ return { error: { line: n.line, message: "Mixing AND with OR needs parentheses." } };
530
+ }
531
+ join = j;
532
+ p += 1;
533
+ continue;
534
+ }
535
+ break;
536
+ }
537
+ return { ok: makeGroup(join ?? "AND", children) };
538
+ };
539
+ const r = expr();
540
+ if ("error" in r) return r;
541
+ if (peek().t !== "end") return fail("Unexpected text after the query.");
542
+ return { value: { ...r.ok, id: "root" } };
543
+ }
544
+ var DEFAULT_LABELS = {
545
+ title: "Filter",
546
+ addCondition: "Add condition",
547
+ addGroup: "Add group",
548
+ apply: "Apply",
549
+ cancel: "Cancel",
550
+ back: "Back",
551
+ field: "Field",
552
+ operator: "Operator",
553
+ value: "Value",
554
+ needsValue: "Needs a value",
555
+ remove: "Remove condition",
556
+ empty: "No conditions yet",
557
+ group: "Group",
558
+ conditions: "conditions",
559
+ conditionsOne: "condition",
560
+ and: "All",
561
+ or: "Any",
562
+ yes: "Yes",
563
+ no: "No",
564
+ leftOut: "left out",
565
+ done: "Done",
566
+ condition: "Condition",
567
+ match: "Match",
568
+ matchOf: "of",
569
+ from: "From",
570
+ to: "To"
571
+ };
572
+ var QUERY_ROW_HEIGHT = { ios: 60, android: 72 };
573
+ function displayValue(c) {
574
+ const v = c.value;
575
+ if (v === null || v === "") return "";
576
+ if (Array.isArray(v)) return v.join(" \u2013 ");
577
+ if (typeof v === "object") return `${v.amount ?? ""} ${v.unit}`.trim();
578
+ return String(v);
579
+ }
580
+ function QueryBuilder(props) {
581
+ const {
582
+ fields,
583
+ onChange,
584
+ onApply,
585
+ onCancel,
586
+ maxDepth = 2,
587
+ platform,
588
+ testID,
589
+ surface,
590
+ disabled = false,
591
+ readOnly = false,
592
+ size = "md",
593
+ loading = false,
594
+ error
595
+ } = props;
596
+ const locked = disabled || readOnly;
597
+ const labels = React2.useMemo(() => ({ ...DEFAULT_LABELS, ...props.labels }), [props.labels]);
598
+ const theme = useLoamTheme();
599
+ const android = isAndroidIdiom(theme, platform);
600
+ const { styles } = useStyles(sheet2);
601
+ const rowH = size === "sm" ? theme.space[android ? 56 : 44] : size === "lg" ? theme.space[android ? 80 : 72] : android ? QUERY_ROW_HEIGHT.android : QUERY_ROW_HEIGHT.ios;
602
+ const bodyRole = resolveTextRole(theme, "body", android);
603
+ const subRole = resolveTextRole(theme, "subheadline", android);
604
+ const rowPress = ({ pressed }) => !android && pressed ? { backgroundColor: theme.state.pressed } : null;
605
+ const ripple = android ? { color: theme.state.pressed } : void 0;
606
+ const [inner, setInner] = React2.useState(
607
+ () => props.defaultValue ?? makeGroup("AND")
608
+ );
609
+ const root = props.value ?? inner;
610
+ const [stack, setStack] = React2.useState([{ kind: "list", path: [] }]);
611
+ const top = stack[stack.length - 1] ?? { kind: "list", path: [] };
612
+ const sheetOpen = !android && top.kind === "row";
613
+ const shown = sheetOpen ? stack[stack.length - 2] ?? { kind: "list", path: [] } : top;
614
+ const commit = (next) => {
615
+ if (props.value === void 0) setInner(next);
616
+ onChange?.(next);
617
+ };
618
+ const push = (s) => setStack((st) => [...st, s]);
619
+ const pop = () => setStack((st) => st.length > 1 ? st.slice(0, -1) : st);
620
+ const defOf = (name) => fields.find((f) => f.name === name);
621
+ const issues = collectIssues(root, fields);
622
+ const issueKey = new Set(issues.map((i) => i.path.join(".")));
623
+ const edit = (path, fn) => {
624
+ if (locked) return;
625
+ commit(updateGroup(root, path, fn));
626
+ };
627
+ const setChild = (parent, index, node) => edit(parent, (g) => ({ ...g, children: g.children.map((c, i) => i === index ? node : c) }));
628
+ const addCondition = (path) => {
629
+ if (locked) return;
630
+ const f = fields[0];
631
+ if (!f) return;
632
+ const operator = f.operators[0] ?? "";
633
+ const cond = { field: f.name, operator, value: emptyValue(f, operator) };
634
+ edit(path, (g) => ({ ...g, children: [...g.children, cond] }));
635
+ push({ kind: "row", path: [...path, groupAt(root, path).children.length] });
636
+ };
637
+ const addGroup = (path) => {
638
+ if (locked) return;
639
+ edit(path, (g) => ({
640
+ ...g,
641
+ children: [...g.children, makeGroup(g.join === "AND" ? "OR" : "AND")]
642
+ }));
643
+ push({ kind: "list", path: [...path, groupAt(root, path).children.length] });
644
+ };
645
+ const renderList = (path) => {
646
+ const g = groupAt(root, path);
647
+ const depth = path.length;
648
+ const nodes = g.children.map((node, i) => {
649
+ const p = [...path, i];
650
+ const bad = isGroup(node) ? false : issueKey.has(p.join("."));
651
+ const title = isGroup(node) ? `${labels.group} \xB7 ${countConditions(node)} ${countConditions(node) === 1 ? labels.conditionsOne : labels.conditions}` : `${node.field} ${node.operator} ${displayValue(node)}`.trim();
652
+ return /* @__PURE__ */ jsxs(
653
+ Pressable,
654
+ {
655
+ accessibilityRole: "button",
656
+ accessibilityLabel: title,
657
+ onPress: () => push(isGroup(node) ? { kind: "list", path: p } : { kind: "row", path: p }),
658
+ android_ripple: ripple,
659
+ style: (st) => [
660
+ styles.row,
661
+ { minHeight: rowH },
662
+ i > 0 ? styles.rowDivider : null,
663
+ rowPress(st)
664
+ ],
665
+ children: [
666
+ /* @__PURE__ */ jsxs(View, { style: styles.rowText, children: [
667
+ /* @__PURE__ */ jsx(Text, { style: [styles.rowTitle, bodyRole], numberOfLines: 1, children: isGroup(node) ? `${labels.group} \xB7 ${countConditions(node)} ${labels.conditions}` : node.field }),
668
+ bad ? /* @__PURE__ */ jsx(Text, { style: styles.needs, children: labels.needsValue }) : /* @__PURE__ */ jsx(Text, { style: [styles.rowSub, subRole], numberOfLines: 1, children: isGroup(node) ? node.join === "AND" ? labels.and : labels.or : `${node.operator} ${displayValue(node)}`.trim() })
669
+ ] }),
670
+ /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: theme.icon.sm, color: theme.color.text3 })
671
+ ]
672
+ },
673
+ isGroup(node) ? node.id : `c${i}`
674
+ );
675
+ });
676
+ return /* @__PURE__ */ jsxs(View, { style: styles.screen, children: [
677
+ /* @__PURE__ */ jsxs(View, { style: styles.joinWrap, children: [
678
+ /* @__PURE__ */ jsx(Text, { style: styles.joinLabel, children: labels.match }),
679
+ /* @__PURE__ */ jsx(
680
+ SegmentedControl,
681
+ {
682
+ size: android ? "md" : "sm",
683
+ value: g.join,
684
+ onValueChange: (v) => edit(path, (x) => ({ ...x, join: v })),
685
+ items: [
686
+ { value: "AND", label: labels.and },
687
+ { value: "OR", label: labels.or }
688
+ ]
689
+ }
690
+ ),
691
+ /* @__PURE__ */ jsx(Text, { style: styles.joinLabel, children: labels.matchOf })
692
+ ] }),
693
+ /* @__PURE__ */ jsx(View, { style: [styles.group, android ? styles.groupAndroid : null], children: nodes.length === 0 ? /* @__PURE__ */ jsx(Text, { style: styles.empty, children: labels.empty }) : nodes }),
694
+ android ? /* @__PURE__ */ jsxs(View, { style: styles.actions, children: [
695
+ /* @__PURE__ */ jsx(
696
+ Button,
697
+ {
698
+ variant: "tonal",
699
+ leadingIcon: "plus",
700
+ disabled: locked,
701
+ onPress: () => addCondition(path),
702
+ children: labels.addCondition
703
+ }
704
+ ),
705
+ depth < maxDepth ? /* @__PURE__ */ jsx(Button, { variant: "outline", disabled: locked, onPress: () => addGroup(path), children: labels.addGroup }) : null
706
+ ] }) : /* @__PURE__ */ jsxs(View, { style: styles.group, children: [
707
+ /* @__PURE__ */ jsxs(
708
+ Pressable,
709
+ {
710
+ accessibilityRole: "button",
711
+ accessibilityLabel: labels.addCondition,
712
+ accessibilityState: { disabled: locked },
713
+ disabled: locked,
714
+ onPress: () => addCondition(path),
715
+ android_ripple: ripple,
716
+ style: (st) => [styles.row, { minHeight: QUERY_ROW_HEIGHT.ios }, rowPress(st)],
717
+ children: [
718
+ /* @__PURE__ */ jsx(Icon, { name: "plus", size: theme.icon.md, color: theme.color.accent }),
719
+ /* @__PURE__ */ jsx(Text, { style: [styles.addText, bodyRole], children: labels.addCondition })
720
+ ]
721
+ }
722
+ ),
723
+ depth < maxDepth ? /* @__PURE__ */ jsxs(
724
+ Pressable,
725
+ {
726
+ accessibilityRole: "button",
727
+ accessibilityLabel: labels.addGroup,
728
+ accessibilityState: { disabled: locked },
729
+ disabled: locked,
730
+ onPress: () => addGroup(path),
731
+ android_ripple: ripple,
732
+ style: (st) => [
733
+ styles.row,
734
+ styles.rowDivider,
735
+ { minHeight: QUERY_ROW_HEIGHT.ios },
736
+ rowPress(st)
737
+ ],
738
+ children: [
739
+ /* @__PURE__ */ jsx(Icon, { name: "plus", size: theme.icon.md, color: theme.color.accent }),
740
+ /* @__PURE__ */ jsx(Text, { style: [styles.addText, bodyRole], children: labels.addGroup })
741
+ ]
742
+ }
743
+ ) : null
744
+ ] })
745
+ ] });
746
+ };
747
+ const renderRow = (path) => {
748
+ const parent = path.slice(0, -1);
749
+ const index = path[path.length - 1] ?? 0;
750
+ const node = groupAt(root, parent).children[index];
751
+ if (!node || isGroup(node)) return null;
752
+ const def = defOf(node.field);
753
+ const kind = editorFor(def, node.operator);
754
+ const set = (patch) => setChild(parent, index, { ...node, ...patch });
755
+ const issue = conditionIssue(node, def);
756
+ const setValue = (value) => set({ value });
757
+ const choice = (text, on, press, multi = false) => /* @__PURE__ */ jsxs(
758
+ Pressable,
759
+ {
760
+ accessibilityRole: multi ? "checkbox" : "radio",
761
+ accessibilityState: multi ? { checked: on, disabled: locked } : { selected: on, disabled: locked },
762
+ disabled: locked,
763
+ onPress: press,
764
+ android_ripple: ripple,
765
+ style: (st) => [styles.row, { minHeight: theme.space[android ? 56 : 44] }, rowPress(st)],
766
+ children: [
767
+ /* @__PURE__ */ jsx(Text, { style: [styles.rowTitle, bodyRole], children: text }),
768
+ on ? /* @__PURE__ */ jsx(Icon, { name: "check", size: theme.icon.sm, color: theme.color.accent }) : null
769
+ ]
770
+ },
771
+ text
772
+ );
773
+ const pair = Array.isArray(node.value) ? node.value : [null, null];
774
+ const rel = node.value && typeof node.value === "object" && !Array.isArray(node.value) ? node.value : { amount: null, unit: def?.units?.[0] ?? "days" };
775
+ return /* @__PURE__ */ jsxs(View, { style: styles.screen, children: [
776
+ /* @__PURE__ */ jsx(Text, { style: styles.section, children: labels.field }),
777
+ /* @__PURE__ */ jsx(View, { style: styles.group, children: fields.map(
778
+ (f) => choice(f.name, f.name === node.field, () => {
779
+ const op = f.operators[0] ?? "";
780
+ set({ field: f.name, operator: op, value: emptyValue(f, op) });
781
+ })
782
+ ) }),
783
+ /* @__PURE__ */ jsx(Text, { style: styles.section, children: labels.operator }),
784
+ /* @__PURE__ */ jsx(View, { style: styles.group, children: (def?.operators ?? []).map(
785
+ (o) => choice(o, o === node.operator, () => set({ operator: o, value: emptyValue(def, o) }))
786
+ ) }),
787
+ kind !== "none" ? /* @__PURE__ */ jsx(Text, { style: styles.section, children: labels.value }) : null,
788
+ /* @__PURE__ */ jsxs(
789
+ View,
790
+ {
791
+ style: kind === "enum" || kind === "multi" || kind === "boolean" ? styles.group : styles.field,
792
+ children: [
793
+ kind === "text" ? /* @__PURE__ */ jsx(
794
+ Input,
795
+ {
796
+ size: "lg",
797
+ platform: android ? "android" : "ios",
798
+ surface,
799
+ editable: !locked,
800
+ accessibilityLabel: labels.value,
801
+ value: node.value === null ? "" : String(node.value),
802
+ onChangeText: (t) => setValue(t)
803
+ }
804
+ ) : null,
805
+ kind === "date" ? /* @__PURE__ */ jsx(
806
+ QueryDateField,
807
+ {
808
+ android,
809
+ surface,
810
+ label: labels.value,
811
+ value: typeof node.value === "string" ? node.value : "",
812
+ onChange: (iso) => setValue(iso)
813
+ }
814
+ ) : null,
815
+ kind === "number" ? /* @__PURE__ */ jsx(
816
+ Input,
817
+ {
818
+ size: "lg",
819
+ platform: android ? "android" : "ios",
820
+ surface,
821
+ editable: !locked,
822
+ accessibilityLabel: labels.value,
823
+ keyboardType: "numeric",
824
+ value: node.value === null ? "" : String(node.value),
825
+ onChangeText: (t) => setValue(t === "" ? null : toNum(t))
826
+ }
827
+ ) : null,
828
+ kind === "between" ? /* @__PURE__ */ jsx(View, { style: styles.pair, children: [0, 1].map((k) => /* @__PURE__ */ jsx(
829
+ Input,
830
+ {
831
+ size: "lg",
832
+ platform: android ? "android" : "ios",
833
+ surface,
834
+ editable: !locked,
835
+ accessibilityLabel: `${labels.value} ${k + 1}`,
836
+ keyboardType: "numeric",
837
+ value: pair[k] === null || pair[k] === void 0 ? "" : String(pair[k]),
838
+ onChangeText: (t) => {
839
+ const next = [
840
+ pair[0] ?? null,
841
+ pair[1] ?? null
842
+ ];
843
+ next[k] = t === "" ? null : toNum(t);
844
+ setValue(next);
845
+ }
846
+ },
847
+ k
848
+ )) }) : null,
849
+ kind === "between-date" ? /* @__PURE__ */ jsx(View, { style: styles.pair, children: [0, 1].map((k) => /* @__PURE__ */ jsxs(View, { style: styles.field, children: [
850
+ /* @__PURE__ */ jsx(Text, { style: styles.section, children: k === 0 ? labels.from : labels.to }),
851
+ /* @__PURE__ */ jsx(
852
+ QueryDateField,
853
+ {
854
+ android,
855
+ surface,
856
+ label: `${labels.value} ${k + 1}`,
857
+ value: typeof pair[k] === "string" ? pair[k] : "",
858
+ onChange: (iso) => {
859
+ const next = [
860
+ pair[0] ?? null,
861
+ pair[1] ?? null
862
+ ];
863
+ next[k] = iso;
864
+ setValue(next);
865
+ }
866
+ }
867
+ )
868
+ ] }, k)) }) : null,
869
+ kind === "relative" ? /* @__PURE__ */ jsxs(View, { style: styles.pair, children: [
870
+ /* @__PURE__ */ jsx(
871
+ Input,
872
+ {
873
+ size: "lg",
874
+ platform: android ? "android" : "ios",
875
+ surface,
876
+ editable: !locked,
877
+ accessibilityLabel: labels.value,
878
+ keyboardType: "numeric",
879
+ value: rel.amount === null ? "" : String(rel.amount),
880
+ onChangeText: (t) => setValue({ amount: t === "" ? null : toNum(t), unit: rel.unit })
881
+ }
882
+ ),
883
+ /* @__PURE__ */ jsx(
884
+ SegmentedControl,
885
+ {
886
+ size: android ? "md" : "sm",
887
+ value: rel.unit,
888
+ onValueChange: (u) => setValue({ amount: rel.amount, unit: u }),
889
+ items: (def?.units ?? ["days", "weeks", "months"]).map((u) => ({
890
+ value: u,
891
+ label: u
892
+ }))
893
+ }
894
+ )
895
+ ] }) : null,
896
+ kind === "enum" ? (def?.values ?? []).map((v) => choice(v, node.value === v, () => setValue(v))) : null,
897
+ kind === "multi" ? (def?.values ?? []).map((v) => {
898
+ const cur = Array.isArray(node.value) ? node.value : [];
899
+ const on = cur.includes(v);
900
+ return choice(
901
+ v,
902
+ on,
903
+ () => setValue(on ? cur.filter((x) => x !== v) : [...cur, v]),
904
+ true
905
+ );
906
+ }) : null,
907
+ kind === "boolean" ? [
908
+ choice(labels.yes, node.value === true, () => setValue(true)),
909
+ choice(labels.no, node.value === false, () => setValue(false))
910
+ ] : null,
911
+ issue && kind !== "none" ? /* @__PURE__ */ jsx(Text, { accessibilityRole: "alert", style: styles.needs, children: issue.kind === "empty" ? labels.needsValue : issue.message }) : null
912
+ ]
913
+ }
914
+ ),
915
+ /* @__PURE__ */ jsx(View, { style: styles.actions, children: /* @__PURE__ */ jsx(
916
+ Button,
917
+ {
918
+ variant: "danger",
919
+ disabled: locked,
920
+ onPress: () => {
921
+ edit(parent, (g) => ({ ...g, children: g.children.filter((_, i) => i !== index) }));
922
+ pop();
923
+ },
924
+ children: labels.remove
925
+ }
926
+ ) })
927
+ ] });
928
+ };
929
+ const skipped = issues.length;
930
+ const apply = () => {
931
+ if (locked) return;
932
+ const applied = appliedGroup(root, fields);
933
+ onApply?.(applied, formatBody(applied, fields));
934
+ };
935
+ const nested = stack.length > 1 && !sheetOpen;
936
+ const goBack = pop;
937
+ return /* @__PURE__ */ jsxs(
938
+ View,
939
+ {
940
+ testID,
941
+ accessibilityState: disabled || loading ? { disabled: disabled || void 0, busy: loading || void 0 } : void 0,
942
+ "aria-busy": loading || void 0,
943
+ pointerEvents: disabled || loading ? "none" : void 0,
944
+ style: [
945
+ styles.root,
946
+ android ? styles.rootAndroid : styles.rootIos,
947
+ error ? styles.rootError : null,
948
+ disabled ? { opacity: theme.state.disabledOpacity } : null
949
+ ],
950
+ children: [
951
+ android ? /* @__PURE__ */ jsxs(View, { style: styles.appBar, children: [
952
+ /* @__PURE__ */ jsx(
953
+ Pressable,
954
+ {
955
+ accessibilityRole: "button",
956
+ accessibilityLabel: nested ? labels.back : labels.cancel,
957
+ onPress: nested ? goBack : () => onCancel?.(),
958
+ style: styles.iconBtn,
959
+ children: /* @__PURE__ */ jsx(
960
+ Icon,
961
+ {
962
+ name: nested ? "arrow-left" : "x",
963
+ size: theme.icon.lg,
964
+ color: theme.color.text
965
+ }
966
+ )
967
+ }
968
+ ),
969
+ /* @__PURE__ */ jsx(Text, { accessibilityRole: "header", style: styles.appBarTitle, numberOfLines: 1, children: labels.title }),
970
+ skipped > 0 ? /* @__PURE__ */ jsxs(Text, { style: styles.rowSub, children: [
971
+ skipped,
972
+ " ",
973
+ labels.leftOut
974
+ ] }) : null,
975
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", disabled: disabled || readOnly, onPress: apply, children: labels.apply })
976
+ ] }) : /* @__PURE__ */ jsxs(View, { style: styles.navBar, children: [
977
+ /* @__PURE__ */ jsx(View, { style: [styles.navSide, styles.navLeft], children: nested ? /* @__PURE__ */ jsx(
978
+ Pressable,
979
+ {
980
+ accessibilityRole: "button",
981
+ accessibilityLabel: labels.back,
982
+ onPress: goBack,
983
+ style: styles.back,
984
+ children: /* @__PURE__ */ jsx(Icon, { name: "chevron-left", size: theme.icon.md, color: theme.color.accent })
985
+ }
986
+ ) : /* @__PURE__ */ jsx(Button, { variant: "ghost", onPress: () => onCancel?.(), children: labels.cancel }) }),
987
+ /* @__PURE__ */ jsxs(View, { style: styles.navTitle, children: [
988
+ /* @__PURE__ */ jsx(Text, { accessibilityRole: "header", style: styles.title, numberOfLines: 1, children: labels.title }),
989
+ skipped > 0 ? /* @__PURE__ */ jsxs(Text, { style: styles.rowSub, children: [
990
+ skipped,
991
+ " ",
992
+ labels.leftOut
993
+ ] }) : null
994
+ ] }),
995
+ /* @__PURE__ */ jsx(View, { style: [styles.navSide, styles.navRight], children: /* @__PURE__ */ jsx(Button, { variant: "ghost", disabled: disabled || readOnly, onPress: apply, children: labels.apply }) })
996
+ ] }),
997
+ typeof error === "string" && error ? /* @__PURE__ */ jsx(View, { accessibilityRole: "alert", style: styles.errorLine, children: /* @__PURE__ */ jsx(FieldMessage, { invalid: true, children: error }) }) : null,
998
+ /* @__PURE__ */ jsx(ScrollView, { contentContainerStyle: styles.scroll, children: loading ? /* @__PURE__ */ jsx(View, { testID: testID ? `${testID}-loading` : void 0, style: styles.group, children: [0, 1, 2].map((k) => /* @__PURE__ */ jsx(
999
+ View,
1000
+ {
1001
+ style: [styles.row, { minHeight: rowH }, k > 0 ? styles.rowDivider : null],
1002
+ children: /* @__PURE__ */ jsx(Skeleton, { variant: "text" })
1003
+ },
1004
+ k
1005
+ )) }) : shown.kind === "list" ? renderList(shown.path) : renderRow(shown.path) }),
1006
+ !android ? /* @__PURE__ */ jsx(
1007
+ Sheet,
1008
+ {
1009
+ open: sheetOpen,
1010
+ onClose: pop,
1011
+ title: labels.condition,
1012
+ detents: ["full"],
1013
+ footer: /* @__PURE__ */ jsx(View, { style: styles.sheetFooter, children: /* @__PURE__ */ jsx(Button, { size: "lg", fullWidth: true, onPress: pop, children: labels.done }) }),
1014
+ children: sheetOpen ? renderRow(top.path) : null
1015
+ }
1016
+ ) : null
1017
+ ]
1018
+ }
1019
+ );
1020
+ }
1021
+ var sheet2 = createStyleSheet((theme) => ({
1022
+ // iOS sits on the grouped background with surface cards; Android is one surface.
1023
+ root: { flex: 1, backgroundColor: theme.color.bg },
1024
+ rootError: { borderWidth: theme.borderWidth.base, borderColor: theme.edge.danger },
1025
+ errorLine: { paddingHorizontal: theme.space.s4, paddingBottom: theme.space.s2 },
1026
+ rootIos: { backgroundColor: theme.color.surface2 },
1027
+ rootAndroid: { backgroundColor: theme.color.surface },
1028
+ // iOS nav bar: Cancel | title | Apply.
1029
+ navBar: {
1030
+ flexDirection: "row",
1031
+ alignItems: "center",
1032
+ minHeight: theme.space[56],
1033
+ paddingHorizontal: theme.space.s2
1034
+ },
1035
+ navSide: { flex: 1, flexDirection: "row", alignItems: "center" },
1036
+ navLeft: { justifyContent: "flex-start" },
1037
+ navRight: { justifyContent: "flex-end" },
1038
+ navTitle: { alignItems: "center", justifyContent: "center" },
1039
+ title: { color: theme.color.text, ...theme.type.headline, textAlign: "center" },
1040
+ back: {
1041
+ minHeight: theme.hit.sm,
1042
+ minWidth: theme.hit.sm,
1043
+ alignItems: "center",
1044
+ justifyContent: "center"
1045
+ },
1046
+ // Android top app bar: close | title | Apply, 64 tall.
1047
+ appBar: {
1048
+ flexDirection: "row",
1049
+ alignItems: "center",
1050
+ gap: theme.space.s2,
1051
+ minHeight: theme.space[64],
1052
+ paddingHorizontal: theme.space.s2
1053
+ },
1054
+ appBarTitle: { flex: 1, color: theme.color.text, ...theme.type.title2 },
1055
+ iconBtn: {
1056
+ minHeight: theme.hit.sm,
1057
+ minWidth: theme.hit.sm,
1058
+ alignItems: "center",
1059
+ justifyContent: "center"
1060
+ },
1061
+ scroll: { paddingHorizontal: theme.space.s4, paddingBottom: theme.space.s4 },
1062
+ screen: { gap: theme.space.s4 },
1063
+ joinWrap: { flexDirection: "row", alignItems: "center", gap: theme.space.s2 },
1064
+ joinLabel: { color: theme.color.text2, ...theme.type.footnote },
1065
+ // Grouped list card: r 10 on iOS; Android rows run edge to edge on the dialog surface.
1066
+ group: {
1067
+ backgroundColor: theme.color.surface,
1068
+ borderRadius: theme.radius[10],
1069
+ overflow: "hidden"
1070
+ },
1071
+ groupAndroid: {
1072
+ borderRadius: 0,
1073
+ backgroundColor: "transparent",
1074
+ marginHorizontal: -theme.space.s4
1075
+ },
1076
+ field: { gap: theme.space.s2 },
1077
+ pair: { gap: theme.space.s2 },
1078
+ row: {
1079
+ flexDirection: "row",
1080
+ alignItems: "center",
1081
+ gap: theme.space.s3,
1082
+ paddingHorizontal: theme.space.s4,
1083
+ paddingVertical: theme.space.s2
1084
+ },
1085
+ rowDivider: { borderTopWidth: theme.borderWidth.thin, borderTopColor: theme.color.border },
1086
+ rowText: { flex: 1, gap: theme.space[2] },
1087
+ rowTitle: { flex: 1, color: theme.color.text },
1088
+ rowSub: { color: theme.color.text2, fontSize: theme.type.footnote.fontSize },
1089
+ addText: { color: theme.color.accentStrong },
1090
+ needs: {
1091
+ color: theme.color.dangerOnSoft,
1092
+ backgroundColor: theme.color.dangerSoft,
1093
+ borderWidth: theme.borderWidth.base,
1094
+ borderColor: theme.edge.danger,
1095
+ borderRadius: theme.radius.sm,
1096
+ paddingHorizontal: theme.space.s2,
1097
+ fontSize: theme.type.footnote.fontSize,
1098
+ alignSelf: "flex-start"
1099
+ },
1100
+ section: {
1101
+ color: theme.color.text2,
1102
+ fontSize: theme.type.footnote.fontSize,
1103
+ marginTop: theme.space.s2
1104
+ },
1105
+ empty: { color: theme.color.text2, padding: theme.space.s4, textAlign: "center" },
1106
+ actions: { gap: theme.space.s2, alignItems: "flex-start" },
1107
+ sheetFooter: { padding: theme.space.s4 }
1108
+ }));
1109
+
1110
+ export { QUERY_ROW_HEIGHT, QueryBuilder, formatGroup, makeGroup, parseQuery };