optikos 0.0.0-stage → 0.2.0

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 (527) hide show
  1. package/CHANGELOG.md +146 -0
  2. package/LICENSE +21 -0
  3. package/README.md +213 -2
  4. package/THIRD_PARTY_NOTICES.md +83 -0
  5. package/dist/bind.js +2 -0
  6. package/dist/bind.js.map +7 -0
  7. package/dist/chunk-23XLG2EM.js +2 -0
  8. package/dist/chunk-23XLG2EM.js.map +7 -0
  9. package/dist/chunk-27UZFEXD.js +2 -0
  10. package/dist/chunk-27UZFEXD.js.map +7 -0
  11. package/dist/chunk-2UPUC4RK.js +2 -0
  12. package/dist/chunk-2UPUC4RK.js.map +7 -0
  13. package/dist/chunk-2ZRNGG2N.js +2 -0
  14. package/dist/chunk-2ZRNGG2N.js.map +7 -0
  15. package/dist/chunk-2ZUZ5HDL.js +2 -0
  16. package/dist/chunk-2ZUZ5HDL.js.map +7 -0
  17. package/dist/chunk-3DBEZGOY.js +2 -0
  18. package/dist/chunk-3DBEZGOY.js.map +7 -0
  19. package/dist/chunk-3S24ZRPK.js +2 -0
  20. package/dist/chunk-3S24ZRPK.js.map +7 -0
  21. package/dist/chunk-3TAW4AKH.js +2 -0
  22. package/dist/chunk-3TAW4AKH.js.map +7 -0
  23. package/dist/chunk-4AA4FQEM.js +2 -0
  24. package/dist/chunk-4AA4FQEM.js.map +7 -0
  25. package/dist/chunk-4C666HHU.js +2 -0
  26. package/dist/chunk-4C666HHU.js.map +7 -0
  27. package/dist/chunk-4EZJ5FKJ.js +2 -0
  28. package/dist/chunk-4EZJ5FKJ.js.map +7 -0
  29. package/dist/chunk-4LZZ244E.js +2 -0
  30. package/dist/chunk-4LZZ244E.js.map +7 -0
  31. package/dist/chunk-4SYIIX5A.js +2 -0
  32. package/dist/chunk-4SYIIX5A.js.map +7 -0
  33. package/dist/chunk-5BC72727.js +2 -0
  34. package/dist/chunk-5BC72727.js.map +7 -0
  35. package/dist/chunk-5DJTP53N.js +2 -0
  36. package/dist/chunk-5DJTP53N.js.map +7 -0
  37. package/dist/chunk-5JEXM5S7.js +2 -0
  38. package/dist/chunk-5JEXM5S7.js.map +7 -0
  39. package/dist/chunk-5Q76ACVI.js +2 -0
  40. package/dist/chunk-5Q76ACVI.js.map +7 -0
  41. package/dist/chunk-5QUY72FX.js +2 -0
  42. package/dist/chunk-5QUY72FX.js.map +7 -0
  43. package/dist/chunk-5YS7OD5E.js +2 -0
  44. package/dist/chunk-5YS7OD5E.js.map +7 -0
  45. package/dist/chunk-676AKAGF.js +2 -0
  46. package/dist/chunk-676AKAGF.js.map +7 -0
  47. package/dist/chunk-6NCXO5ZP.js +2 -0
  48. package/dist/chunk-6NCXO5ZP.js.map +7 -0
  49. package/dist/chunk-6VBK2I5B.js +2 -0
  50. package/dist/chunk-6VBK2I5B.js.map +7 -0
  51. package/dist/chunk-7KMIFXHZ.js +2 -0
  52. package/dist/chunk-7KMIFXHZ.js.map +7 -0
  53. package/dist/chunk-A2NKDOYN.js +2 -0
  54. package/dist/chunk-A2NKDOYN.js.map +7 -0
  55. package/dist/chunk-ATFJ7PNA.js +2 -0
  56. package/dist/chunk-ATFJ7PNA.js.map +7 -0
  57. package/dist/chunk-BXYWVRKJ.js +2 -0
  58. package/dist/chunk-BXYWVRKJ.js.map +7 -0
  59. package/dist/chunk-CKXS375P.js +2 -0
  60. package/dist/chunk-CKXS375P.js.map +7 -0
  61. package/dist/chunk-CUN5QO4T.js +2 -0
  62. package/dist/chunk-CUN5QO4T.js.map +7 -0
  63. package/dist/chunk-DBMWS3O5.js +2 -0
  64. package/dist/chunk-DBMWS3O5.js.map +7 -0
  65. package/dist/chunk-E4VNLYO2.js +2 -0
  66. package/dist/chunk-E4VNLYO2.js.map +7 -0
  67. package/dist/chunk-EDUMAMK4.js +2 -0
  68. package/dist/chunk-EDUMAMK4.js.map +7 -0
  69. package/dist/chunk-ELYARUCN.js +2 -0
  70. package/dist/chunk-ELYARUCN.js.map +7 -0
  71. package/dist/chunk-EV73ADN2.js +2 -0
  72. package/dist/chunk-EV73ADN2.js.map +7 -0
  73. package/dist/chunk-FEHGU6EP.js +3 -0
  74. package/dist/chunk-FEHGU6EP.js.map +7 -0
  75. package/dist/chunk-FHM5NUS4.js +3 -0
  76. package/dist/chunk-FHM5NUS4.js.map +7 -0
  77. package/dist/chunk-G2DAD3MQ.js +2 -0
  78. package/dist/chunk-G2DAD3MQ.js.map +7 -0
  79. package/dist/chunk-G2KUK6AT.js +2 -0
  80. package/dist/chunk-G2KUK6AT.js.map +7 -0
  81. package/dist/chunk-GBPLNXMP.js +2 -0
  82. package/dist/chunk-GBPLNXMP.js.map +7 -0
  83. package/dist/chunk-GNU4VOOE.js +2 -0
  84. package/dist/chunk-GNU4VOOE.js.map +7 -0
  85. package/dist/chunk-GZ7X34QP.js +2 -0
  86. package/dist/chunk-GZ7X34QP.js.map +7 -0
  87. package/dist/chunk-HOF4JGMQ.js +2 -0
  88. package/dist/chunk-HOF4JGMQ.js.map +7 -0
  89. package/dist/chunk-HXDTGP2K.js +2 -0
  90. package/dist/chunk-HXDTGP2K.js.map +7 -0
  91. package/dist/chunk-I4SP6JTU.js +2 -0
  92. package/dist/chunk-I4SP6JTU.js.map +7 -0
  93. package/dist/chunk-IHE2MQ3W.js +2 -0
  94. package/dist/chunk-IHE2MQ3W.js.map +7 -0
  95. package/dist/chunk-II6ITOA6.js +2 -0
  96. package/dist/chunk-II6ITOA6.js.map +7 -0
  97. package/dist/chunk-JBLRAM7Z.js +2 -0
  98. package/dist/chunk-JBLRAM7Z.js.map +7 -0
  99. package/dist/chunk-JI265XFO.js +2 -0
  100. package/dist/chunk-JI265XFO.js.map +7 -0
  101. package/dist/chunk-JK74QK3M.js +2 -0
  102. package/dist/chunk-JK74QK3M.js.map +7 -0
  103. package/dist/chunk-JOFQJGZK.js +2 -0
  104. package/dist/chunk-JOFQJGZK.js.map +7 -0
  105. package/dist/chunk-KCEUD232.js +2 -0
  106. package/dist/chunk-KCEUD232.js.map +7 -0
  107. package/dist/chunk-KLLAY2IM.js +2 -0
  108. package/dist/chunk-KLLAY2IM.js.map +7 -0
  109. package/dist/chunk-LBJSMXLV.js +2 -0
  110. package/dist/chunk-LBJSMXLV.js.map +7 -0
  111. package/dist/chunk-LQRFNQ2N.js +2 -0
  112. package/dist/chunk-LQRFNQ2N.js.map +7 -0
  113. package/dist/chunk-LW2WRUVL.js +2 -0
  114. package/dist/chunk-LW2WRUVL.js.map +7 -0
  115. package/dist/chunk-M242VYZA.js +2 -0
  116. package/dist/chunk-M242VYZA.js.map +7 -0
  117. package/dist/chunk-MB3MU6HR.js +2 -0
  118. package/dist/chunk-MB3MU6HR.js.map +7 -0
  119. package/dist/chunk-MW3RWBZ7.js +2 -0
  120. package/dist/chunk-MW3RWBZ7.js.map +7 -0
  121. package/dist/chunk-NXSTUFS7.js +2 -0
  122. package/dist/chunk-NXSTUFS7.js.map +7 -0
  123. package/dist/chunk-OEAXCCVM.js +2 -0
  124. package/dist/chunk-OEAXCCVM.js.map +7 -0
  125. package/dist/chunk-OGRFQTXA.js +2 -0
  126. package/dist/chunk-OGRFQTXA.js.map +7 -0
  127. package/dist/chunk-OWEQT2HN.js +2 -0
  128. package/dist/chunk-OWEQT2HN.js.map +7 -0
  129. package/dist/chunk-PZSHOSOS.js +2 -0
  130. package/dist/chunk-PZSHOSOS.js.map +7 -0
  131. package/dist/chunk-REW4LR46.js +2 -0
  132. package/dist/chunk-REW4LR46.js.map +7 -0
  133. package/dist/chunk-RNN55473.js +2 -0
  134. package/dist/chunk-RNN55473.js.map +7 -0
  135. package/dist/chunk-SA53QUBF.js +2 -0
  136. package/dist/chunk-SA53QUBF.js.map +7 -0
  137. package/dist/chunk-TIPK3SCJ.js +2 -0
  138. package/dist/chunk-TIPK3SCJ.js.map +7 -0
  139. package/dist/chunk-TOLTUOZS.js +2 -0
  140. package/dist/chunk-TOLTUOZS.js.map +7 -0
  141. package/dist/chunk-TZOQWCVH.js +2 -0
  142. package/dist/chunk-TZOQWCVH.js.map +7 -0
  143. package/dist/chunk-VF7BGP6L.js +2 -0
  144. package/dist/chunk-VF7BGP6L.js.map +7 -0
  145. package/dist/chunk-VU3GIDZ3.js +2 -0
  146. package/dist/chunk-VU3GIDZ3.js.map +7 -0
  147. package/dist/chunk-VV7CFMPZ.js +2 -0
  148. package/dist/chunk-VV7CFMPZ.js.map +7 -0
  149. package/dist/chunk-W3H7GTJY.js +2 -0
  150. package/dist/chunk-W3H7GTJY.js.map +7 -0
  151. package/dist/chunk-X2ASKUFD.js +2 -0
  152. package/dist/chunk-X2ASKUFD.js.map +7 -0
  153. package/dist/chunk-X6AULZI4.js +1 -0
  154. package/dist/chunk-X6AULZI4.js.map +7 -0
  155. package/dist/chunk-XHOBNSBO.js +2 -0
  156. package/dist/chunk-XHOBNSBO.js.map +7 -0
  157. package/dist/chunk-XX2MVWFS.js +4 -0
  158. package/dist/chunk-XX2MVWFS.js.map +7 -0
  159. package/dist/chunk-XYZ6VZ5T.js +2 -0
  160. package/dist/chunk-XYZ6VZ5T.js.map +7 -0
  161. package/dist/chunk-YBAYEU25.js +2 -0
  162. package/dist/chunk-YBAYEU25.js.map +7 -0
  163. package/dist/chunk-YHEMA56R.js +2 -0
  164. package/dist/chunk-YHEMA56R.js.map +7 -0
  165. package/dist/chunk-Z2JBUHKA.js +2 -0
  166. package/dist/chunk-Z2JBUHKA.js.map +7 -0
  167. package/dist/chunk-Z2Z52GFT.js +2 -0
  168. package/dist/chunk-Z2Z52GFT.js.map +7 -0
  169. package/dist/chunk-ZPPELYNJ.js +2 -0
  170. package/dist/chunk-ZPPELYNJ.js.map +7 -0
  171. package/dist/chunk-ZVK4L5GK.js +2 -0
  172. package/dist/chunk-ZVK4L5GK.js.map +7 -0
  173. package/dist/chunk-ZWNQREWS.js +2 -0
  174. package/dist/chunk-ZWNQREWS.js.map +7 -0
  175. package/dist/components/badge.js +2 -0
  176. package/dist/components/badge.js.map +7 -0
  177. package/dist/components/breadcrumb.js +2 -0
  178. package/dist/components/breadcrumb.js.map +7 -0
  179. package/dist/components/button.js +2 -0
  180. package/dist/components/button.js.map +7 -0
  181. package/dist/components/calendar.js +2 -0
  182. package/dist/components/calendar.js.map +7 -0
  183. package/dist/components/cellediting.js +2 -0
  184. package/dist/components/cellediting.js.map +7 -0
  185. package/dist/components/chat.js +2 -0
  186. package/dist/components/chat.js.map +7 -0
  187. package/dist/components/checkbox.js +2 -0
  188. package/dist/components/checkbox.js.map +7 -0
  189. package/dist/components/checkboxgroup.js +2 -0
  190. package/dist/components/checkboxgroup.js.map +7 -0
  191. package/dist/components/chip.js +2 -0
  192. package/dist/components/chip.js.map +7 -0
  193. package/dist/components/codeviewer.js +2 -0
  194. package/dist/components/codeviewer.js.map +7 -0
  195. package/dist/components/combobox.js +2 -0
  196. package/dist/components/combobox.js.map +7 -0
  197. package/dist/components/commandpalette.js +2 -0
  198. package/dist/components/commandpalette.js.map +7 -0
  199. package/dist/components/container.js +2 -0
  200. package/dist/components/container.js.map +7 -0
  201. package/dist/components/dataview.js +2 -0
  202. package/dist/components/dataview.js.map +7 -0
  203. package/dist/components/datefield.js +2 -0
  204. package/dist/components/datefield.js.map +7 -0
  205. package/dist/components/daterangefield.js +2 -0
  206. package/dist/components/daterangefield.js.map +7 -0
  207. package/dist/components/dial.js +2 -0
  208. package/dist/components/dial.js.map +7 -0
  209. package/dist/components/dropdown.js +2 -0
  210. package/dist/components/dropdown.js.map +7 -0
  211. package/dist/components/fieldgroup.js +2 -0
  212. package/dist/components/fieldgroup.js.map +7 -0
  213. package/dist/components/fieldlist.js +2 -0
  214. package/dist/components/fieldlist.js.map +7 -0
  215. package/dist/components/fieldset.js +2 -0
  216. package/dist/components/fieldset.js.map +7 -0
  217. package/dist/components/filterbuilder.js +2 -0
  218. package/dist/components/filterbuilder.js.map +7 -0
  219. package/dist/components/form.js +2 -0
  220. package/dist/components/form.js.map +7 -0
  221. package/dist/components/formactions.js +2 -0
  222. package/dist/components/formactions.js.map +7 -0
  223. package/dist/components/formerrors.js +2 -0
  224. package/dist/components/formerrors.js.map +7 -0
  225. package/dist/components/formsection.js +2 -0
  226. package/dist/components/formsection.js.map +7 -0
  227. package/dist/components/grid.js +2 -0
  228. package/dist/components/grid.js.map +7 -0
  229. package/dist/components/icon.js +2 -0
  230. package/dist/components/icon.js.map +7 -0
  231. package/dist/components/inputgroup.js +2 -0
  232. package/dist/components/inputgroup.js.map +7 -0
  233. package/dist/components/label.js +2 -0
  234. package/dist/components/label.js.map +7 -0
  235. package/dist/components/listbox.js +2 -0
  236. package/dist/components/listbox.js.map +7 -0
  237. package/dist/components/lookupfield.js +2 -0
  238. package/dist/components/lookupfield.js.map +7 -0
  239. package/dist/components/menu.js +2 -0
  240. package/dist/components/menu.js.map +7 -0
  241. package/dist/components/messagebox.js +2 -0
  242. package/dist/components/messagebox.js.map +7 -0
  243. package/dist/components/navmenu.js +2 -0
  244. package/dist/components/navmenu.js.map +7 -0
  245. package/dist/components/numberfield.js +2 -0
  246. package/dist/components/numberfield.js.map +7 -0
  247. package/dist/components/pagination.js +2 -0
  248. package/dist/components/pagination.js.map +7 -0
  249. package/dist/components/panel.js +2 -0
  250. package/dist/components/panel.js.map +7 -0
  251. package/dist/components/pickerfield.js +2 -0
  252. package/dist/components/pickerfield.js.map +7 -0
  253. package/dist/components/radiogroup.js +2 -0
  254. package/dist/components/radiogroup.js.map +7 -0
  255. package/dist/components/searchgrid.js +2 -0
  256. package/dist/components/searchgrid.js.map +7 -0
  257. package/dist/components/secretfield.js +2 -0
  258. package/dist/components/secretfield.js.map +7 -0
  259. package/dist/components/select.js +2 -0
  260. package/dist/components/select.js.map +7 -0
  261. package/dist/components/slider.js +2 -0
  262. package/dist/components/slider.js.map +7 -0
  263. package/dist/components/spacer.js +2 -0
  264. package/dist/components/spacer.js.map +7 -0
  265. package/dist/components/spinner.js +2 -0
  266. package/dist/components/spinner.js.map +7 -0
  267. package/dist/components/stepform.js +2 -0
  268. package/dist/components/stepform.js.map +7 -0
  269. package/dist/components/stepper.js +2 -0
  270. package/dist/components/stepper.js.map +7 -0
  271. package/dist/components/suggestfield.js +2 -0
  272. package/dist/components/suggestfield.js.map +7 -0
  273. package/dist/components/table.js +2 -0
  274. package/dist/components/table.js.map +7 -0
  275. package/dist/components/tabs.js +2 -0
  276. package/dist/components/tabs.js.map +7 -0
  277. package/dist/components/textarea.js +2 -0
  278. package/dist/components/textarea.js.map +7 -0
  279. package/dist/components/textfield.js +2 -0
  280. package/dist/components/textfield.js.map +7 -0
  281. package/dist/components/toast.js +2 -0
  282. package/dist/components/toast.js.map +7 -0
  283. package/dist/components/toggle.js +2 -0
  284. package/dist/components/toggle.js.map +7 -0
  285. package/dist/components/toolbar.js +2 -0
  286. package/dist/components/toolbar.js.map +7 -0
  287. package/dist/components/tooltip.js +2 -0
  288. package/dist/components/tooltip.js.map +7 -0
  289. package/dist/components/tree.js +2 -0
  290. package/dist/components/tree.js.map +7 -0
  291. package/dist/components/viewmanager.js +2 -0
  292. package/dist/components/viewmanager.js.map +7 -0
  293. package/dist/components/viewport.js +2 -0
  294. package/dist/components/viewport.js.map +7 -0
  295. package/dist/components/widget.js +2 -0
  296. package/dist/components/widget.js.map +7 -0
  297. package/dist/components/window.js +2 -0
  298. package/dist/components/window.js.map +7 -0
  299. package/dist/core.js +2 -0
  300. package/dist/core.js.map +7 -0
  301. package/dist/css/badge.css +39 -0
  302. package/dist/css/base.css +180 -0
  303. package/dist/css/breadcrumb.css +53 -0
  304. package/dist/css/button.css +103 -0
  305. package/dist/css/calendar.css +108 -0
  306. package/dist/css/cellediting.css +33 -0
  307. package/dist/css/chat.css +232 -0
  308. package/dist/css/checkbox.css +64 -0
  309. package/dist/css/checkboxgroup.css +12 -0
  310. package/dist/css/chip.css +64 -0
  311. package/dist/css/codeviewer.css +109 -0
  312. package/dist/css/commandpalette.css +167 -0
  313. package/dist/css/container.css +5 -0
  314. package/dist/css/core.css +88 -0
  315. package/dist/css/dataview.css +56 -0
  316. package/dist/css/dial.css +203 -0
  317. package/dist/css/dropdown.css +13 -0
  318. package/dist/css/field.css +62 -0
  319. package/dist/css/fieldgroup.css +26 -0
  320. package/dist/css/fieldlist.css +84 -0
  321. package/dist/css/fieldset.css +68 -0
  322. package/dist/css/filterbuilder.css +125 -0
  323. package/dist/css/form.css +8 -0
  324. package/dist/css/formactions.css +40 -0
  325. package/dist/css/formerrors.css +39 -0
  326. package/dist/css/formsection.css +45 -0
  327. package/dist/css/grid.css +378 -0
  328. package/dist/css/icon.css +16 -0
  329. package/dist/css/inputgroup.css +58 -0
  330. package/dist/css/label.css +12 -0
  331. package/dist/css/layout.css +116 -0
  332. package/dist/css/listbox.css +50 -0
  333. package/dist/css/menu.css +92 -0
  334. package/dist/css/messagebox.css +6 -0
  335. package/dist/css/motion.css +29 -0
  336. package/dist/css/navmenu.css +115 -0
  337. package/dist/css/pagination.css +23 -0
  338. package/dist/css/panel.css +84 -0
  339. package/dist/css/pickerfield.css +85 -0
  340. package/dist/css/radiogroup.css +53 -0
  341. package/dist/css/searchgrid.css +37 -0
  342. package/dist/css/secretfield.css +73 -0
  343. package/dist/css/slider.css +107 -0
  344. package/dist/css/spacer.css +7 -0
  345. package/dist/css/stepform.css +46 -0
  346. package/dist/css/stepper.css +122 -0
  347. package/dist/css/table.css +36 -0
  348. package/dist/css/tabs.css +108 -0
  349. package/dist/css/textarea.css +11 -0
  350. package/dist/css/textfield.css +59 -0
  351. package/dist/css/toast.css +91 -0
  352. package/dist/css/toggle.css +39 -0
  353. package/dist/css/toolbar.css +14 -0
  354. package/dist/css/tooltip.css +17 -0
  355. package/dist/css/tree.css +94 -0
  356. package/dist/css/viewport.css +9 -0
  357. package/dist/css/widget.css +135 -0
  358. package/dist/css/window.css +35 -0
  359. package/dist/data.js +2 -0
  360. package/dist/data.js.map +7 -0
  361. package/dist/index.js +8 -0
  362. package/dist/index.js.map +7 -0
  363. package/dist/motion.js +2 -0
  364. package/dist/motion.js.map +7 -0
  365. package/dist/optikos.css +4240 -0
  366. package/dist/themes/compact.css +17 -0
  367. package/dist/themes/dark.css +53 -0
  368. package/dist/types/bind/index.d.ts +23 -0
  369. package/dist/types/components/badge.d.ts +1 -0
  370. package/dist/types/components/base/badge/badge.d.ts +18 -0
  371. package/dist/types/components/base/button/button.d.ts +34 -0
  372. package/dist/types/components/base/chip/chip.d.ts +27 -0
  373. package/dist/types/components/base/codeviewer/codeviewer.d.ts +48 -0
  374. package/dist/types/components/base/icon/icon.d.ts +17 -0
  375. package/dist/types/components/base/label/label.d.ts +14 -0
  376. package/dist/types/components/breadcrumb.d.ts +1 -0
  377. package/dist/types/components/button.d.ts +1 -0
  378. package/dist/types/components/calendar.d.ts +1 -0
  379. package/dist/types/components/cellediting.d.ts +1 -0
  380. package/dist/types/components/chat/chat/chat.d.ts +84 -0
  381. package/dist/types/components/chat.d.ts +1 -0
  382. package/dist/types/components/checkbox.d.ts +1 -0
  383. package/dist/types/components/checkboxgroup.d.ts +1 -0
  384. package/dist/types/components/chip.d.ts +1 -0
  385. package/dist/types/components/codeviewer.d.ts +1 -0
  386. package/dist/types/components/combobox.d.ts +1 -0
  387. package/dist/types/components/commandpalette.d.ts +1 -0
  388. package/dist/types/components/container.d.ts +1 -0
  389. package/dist/types/components/data/cellediting/cellediting.d.ts +10 -0
  390. package/dist/types/components/data/dataview/dataview.d.ts +61 -0
  391. package/dist/types/components/data/filterbuilder/filterbuilder.d.ts +73 -0
  392. package/dist/types/components/data/grid/grid.d.ts +177 -0
  393. package/dist/types/components/data/pagination/pagination.d.ts +31 -0
  394. package/dist/types/components/data/searchgrid/searchgrid.d.ts +63 -0
  395. package/dist/types/components/data/table/table.d.ts +26 -0
  396. package/dist/types/components/data/tree/tree.d.ts +71 -0
  397. package/dist/types/components/data/viewmanager/viewmanager.d.ts +86 -0
  398. package/dist/types/components/dataview.d.ts +1 -0
  399. package/dist/types/components/datefield.d.ts +1 -0
  400. package/dist/types/components/daterangefield.d.ts +1 -0
  401. package/dist/types/components/dates/calendar/calendar.d.ts +48 -0
  402. package/dist/types/components/dial.d.ts +1 -0
  403. package/dist/types/components/dropdown.d.ts +1 -0
  404. package/dist/types/components/feedback/spinner/spinner.d.ts +11 -0
  405. package/dist/types/components/fieldgroup.d.ts +1 -0
  406. package/dist/types/components/fieldlist.d.ts +1 -0
  407. package/dist/types/components/fields/checkbox/checkbox.d.ts +20 -0
  408. package/dist/types/components/fields/checkboxgroup/checkboxgroup.d.ts +27 -0
  409. package/dist/types/components/fields/combobox/combobox.d.ts +15 -0
  410. package/dist/types/components/fields/datefield/datefield.d.ts +30 -0
  411. package/dist/types/components/fields/daterangefield/daterangefield.d.ts +32 -0
  412. package/dist/types/components/fields/dial/dial.d.ts +84 -0
  413. package/dist/types/components/fields/listbox/listbox.d.ts +54 -0
  414. package/dist/types/components/fields/lookupfield/lookupfield.d.ts +25 -0
  415. package/dist/types/components/fields/numberfield/numberfield.d.ts +31 -0
  416. package/dist/types/components/fields/pickerfield/pickerfield.d.ts +77 -0
  417. package/dist/types/components/fields/radiogroup/radiogroup.d.ts +26 -0
  418. package/dist/types/components/fields/secretfield/secretfield.d.ts +52 -0
  419. package/dist/types/components/fields/select/select.d.ts +10 -0
  420. package/dist/types/components/fields/slider/slider.d.ts +62 -0
  421. package/dist/types/components/fields/suggestfield/suggestfield.d.ts +34 -0
  422. package/dist/types/components/fields/textarea/textarea.d.ts +16 -0
  423. package/dist/types/components/fields/textfield/textfield.d.ts +38 -0
  424. package/dist/types/components/fields/toggle/toggle.d.ts +9 -0
  425. package/dist/types/components/fieldset.d.ts +1 -0
  426. package/dist/types/components/filterbuilder.d.ts +1 -0
  427. package/dist/types/components/form/fieldgroup/fieldgroup.d.ts +33 -0
  428. package/dist/types/components/form/fieldlist/fieldlist.d.ts +58 -0
  429. package/dist/types/components/form/form/form.d.ts +68 -0
  430. package/dist/types/components/form/formactions/formactions.d.ts +34 -0
  431. package/dist/types/components/form/formerrors/formerrors.d.ts +23 -0
  432. package/dist/types/components/form/formsection/formsection.d.ts +26 -0
  433. package/dist/types/components/form/inputgroup/inputgroup.d.ts +28 -0
  434. package/dist/types/components/form/stepform/stepform.d.ts +64 -0
  435. package/dist/types/components/form.d.ts +1 -0
  436. package/dist/types/components/formactions.d.ts +1 -0
  437. package/dist/types/components/formerrors.d.ts +1 -0
  438. package/dist/types/components/formsection.d.ts +1 -0
  439. package/dist/types/components/grid.d.ts +1 -0
  440. package/dist/types/components/icon.d.ts +1 -0
  441. package/dist/types/components/inputgroup.d.ts +1 -0
  442. package/dist/types/components/label.d.ts +1 -0
  443. package/dist/types/components/layout/container/container.d.ts +1 -0
  444. package/dist/types/components/layout/fieldset/fieldset.d.ts +30 -0
  445. package/dist/types/components/layout/panel/panel.d.ts +53 -0
  446. package/dist/types/components/layout/panel/reload.d.ts +1 -0
  447. package/dist/types/components/layout/spacer/spacer.d.ts +12 -0
  448. package/dist/types/components/layout/toolbar/toolbar.d.ts +15 -0
  449. package/dist/types/components/layout/viewport/viewport.d.ts +7 -0
  450. package/dist/types/components/listbox.d.ts +1 -0
  451. package/dist/types/components/lookupfield.d.ts +1 -0
  452. package/dist/types/components/menu.d.ts +1 -0
  453. package/dist/types/components/messagebox.d.ts +1 -0
  454. package/dist/types/components/navigation/breadcrumb/breadcrumb.d.ts +32 -0
  455. package/dist/types/components/navigation/navmenu/navmenu.d.ts +63 -0
  456. package/dist/types/components/navigation/stepper/stepper.d.ts +31 -0
  457. package/dist/types/components/navigation/tabs/tabs.d.ts +57 -0
  458. package/dist/types/components/navmenu.d.ts +1 -0
  459. package/dist/types/components/numberfield.d.ts +1 -0
  460. package/dist/types/components/overlays/commandpalette/commandpalette.d.ts +80 -0
  461. package/dist/types/components/overlays/dropdown/dropdown.d.ts +41 -0
  462. package/dist/types/components/overlays/menu/menu.d.ts +56 -0
  463. package/dist/types/components/overlays/messagebox/messagebox.d.ts +61 -0
  464. package/dist/types/components/overlays/toast/toast.d.ts +45 -0
  465. package/dist/types/components/overlays/tooltip/tooltip.d.ts +13 -0
  466. package/dist/types/components/overlays/widget/widget.d.ts +61 -0
  467. package/dist/types/components/overlays/window/window.d.ts +38 -0
  468. package/dist/types/components/pagination.d.ts +1 -0
  469. package/dist/types/components/panel.d.ts +1 -0
  470. package/dist/types/components/pickerfield.d.ts +1 -0
  471. package/dist/types/components/radiogroup.d.ts +1 -0
  472. package/dist/types/components/searchgrid.d.ts +1 -0
  473. package/dist/types/components/secretfield.d.ts +1 -0
  474. package/dist/types/components/select.d.ts +1 -0
  475. package/dist/types/components/slider.d.ts +1 -0
  476. package/dist/types/components/spacer.d.ts +1 -0
  477. package/dist/types/components/spinner.d.ts +1 -0
  478. package/dist/types/components/stepform.d.ts +1 -0
  479. package/dist/types/components/stepper.d.ts +1 -0
  480. package/dist/types/components/suggestfield.d.ts +1 -0
  481. package/dist/types/components/table.d.ts +1 -0
  482. package/dist/types/components/tabs.d.ts +1 -0
  483. package/dist/types/components/textarea.d.ts +1 -0
  484. package/dist/types/components/textfield.d.ts +1 -0
  485. package/dist/types/components/toast.d.ts +1 -0
  486. package/dist/types/components/toggle.d.ts +1 -0
  487. package/dist/types/components/toolbar.d.ts +1 -0
  488. package/dist/types/components/tooltip.d.ts +1 -0
  489. package/dist/types/components/tree.d.ts +1 -0
  490. package/dist/types/components/viewmanager.d.ts +1 -0
  491. package/dist/types/components/viewport.d.ts +1 -0
  492. package/dist/types/components/widget.d.ts +1 -0
  493. package/dist/types/components/window.d.ts +1 -0
  494. package/dist/types/core/component.d.ts +94 -0
  495. package/dist/types/core/container.d.ts +43 -0
  496. package/dist/types/core/date.d.ts +14 -0
  497. package/dist/types/core/dom.d.ts +11 -0
  498. package/dist/types/core/emitter.d.ts +12 -0
  499. package/dist/types/core/field.d.ts +78 -0
  500. package/dist/types/core/focus.d.ts +18 -0
  501. package/dist/types/core/i18n.d.ts +12 -0
  502. package/dist/types/core/index.d.ts +15 -0
  503. package/dist/types/core/layer.d.ts +6 -0
  504. package/dist/types/core/position.d.ts +19 -0
  505. package/dist/types/core/registry.d.ts +12 -0
  506. package/dist/types/core/validators.d.ts +10 -0
  507. package/dist/types/core/virtual.d.ts +24 -0
  508. package/dist/types/data/column.d.ts +32 -0
  509. package/dist/types/data/format.d.ts +4 -0
  510. package/dist/types/data/index.d.ts +5 -0
  511. package/dist/types/data/model.d.ts +28 -0
  512. package/dist/types/data/proxy.d.ts +61 -0
  513. package/dist/types/data/store.d.ts +94 -0
  514. package/dist/types/index.d.ts +67 -0
  515. package/dist/types/layout/layout.d.ts +27 -0
  516. package/dist/types/motion/config.d.ts +83 -0
  517. package/dist/types/motion/core.d.ts +40 -0
  518. package/dist/types/motion/extras.d.ts +66 -0
  519. package/dist/types/motion/index.d.ts +3 -0
  520. package/dist/types/themes/define.d.ts +31 -0
  521. package/dist/types/themes/index.d.ts +1 -0
  522. package/dist/types/ui/enums.d.ts +82 -0
  523. package/dist/types/ui/index.d.ts +2 -0
  524. package/dist/types/ui/ui.d.ts +67 -0
  525. package/dist/ui.js +2 -0
  526. package/dist/ui.js.map +7 -0
  527. package/package.json +104 -4
@@ -0,0 +1,2 @@
1
+ import{c as v}from"./chunk-ZWNQREWS.js";import{a as m}from"./chunk-2ZRNGG2N.js";import{c as u}from"./chunk-4EZJ5FKJ.js";import{a as w}from"./chunk-A2NKDOYN.js";import{b as r}from"./chunk-PZSHOSOS.js";import{a as y}from"./chunk-TIPK3SCJ.js";import{e as p,f as l}from"./chunk-MW3RWBZ7.js";p("en",{flAdd:"Add",flRemove:"Remove {row}",flUp:"Move {row} up",flDown:"Move {row} down",flEmpty:"Nothing added yet",flMin:"Add at least {n}",flMax:"At most {n}"});p("pt-BR",{flAdd:"Adicionar",flRemove:"Remover {row}",flUp:"Subir {row}",flDown:"Descer {row}",flEmpty:"Nada adicionado ainda",flMin:"Adicione pelo menos {n}",flMax:"No m\xE1ximo {n}"});var C=(a,t)=>t.split(".").reduce((e,o)=>e?.[o],a);function A(a,t,e){let o=t.split("."),s=o.pop();o.reduce((i,n)=>i[n]??={},a)[s]=e}var g=class extends m{baseCls="op-field op-fieldlist";rowsEl;addBtn;emptyEl;rows=[];syncing=!1;emptyValue(){return[]}isEmpty(t){return!t?.length}createControl(){return this.rowsEl=r("div","op-fieldlist__rows",{role:"group"}),this.emptyEl=r("div","op-fieldlist__empty",{},l("flEmpty")),this.addBtn=r("button","op-fieldlist__add",{type:"button"},u("plus"),r("span","",{},this.config.addText??l("flAdd"))),this.listen(this.addBtn,"click",()=>this.addRow()),this.inputEl=this.addBtn,r("div","op-fieldlist__box",{},this.rowsEl,this.emptyEl,this.addBtn)}onRender(){super.onRender(),this.rowsEl.setAttribute("aria-labelledby",this.el.querySelector(".op-field__label").id||=`${this.id}-label`)}label(t){return`${this.config.label??""} ${t+1}`.trim()}makeRow(t){let e=s=>{let i=s instanceof w?s.config:s,n={...i,...Array.isArray(i.items)?{items:i.items.map(e)}:{}};return s instanceof w?new s.constructor(n):n},o=new v({cls:"op-fieldlist__row",layout:this.config.rowLayout??{type:"hbox",align:"flex-start"},items:(this.config.items??[]).map(e)});for(let s of o.items)s.config.width!=null&&s.config.flex==null&&(s.config.flex="none");for(let s of this.rowFields(o)){let i=s.name?C(t,s.name):void 0;i!==void 0&&s.setValue(i,!0),s.on("change",()=>this.syncing||this.commitRows())}return o}rowFields(t){return t.query(e=>e instanceof m)}collect(){return this.rows.map(t=>{let e={};for(let o of this.rowFields(t))o.name&&A(e,o.name,o.getValue());return e})}commitRows(){this.commit(this.collect()),this.paintRows(),this.getError()&&this.validate()}paintRows(){if(!this.rendered)return;let{min:t=0,max:e=1/0,reorderable:o=!0}=this.config;this.rowsEl.replaceChildren(...this.rows.map((s,i)=>{let n=s.el;n.setAttribute("role","group"),n.setAttribute("aria-label",this.label(i)),n.classList.toggle("is-first",i===0),n.querySelector(":scope > .op-fieldlist__tools")?.remove();let d=(b,f,R,E)=>{let c=r("button","op-fieldlist__tool",{type:"button","data-act":f,"aria-label":l(f,{row:this.label(i)}),"data-op-tip":l(f,{row:this.label(i)})},u(b));return c.disabled=R||!!this.config.disabled||!!this.config.readonly,c.addEventListener("click",E),c},h=r("div","op-fieldlist__tools");return o&&h.append(d("chevron-up","flUp",i===0,()=>this.moveRow(i,i-1)),d("chevron-down","flDown",i===this.rows.length-1,()=>this.moveRow(i,i+1))),h.append(d("trash","flRemove",this.rows.length<=t,()=>this.removeRow(i))),n.append(h),n})),this.emptyEl.hidden=this.rows.length>0,this.el.classList.toggle("is-empty",!this.rows.length),this.addBtn.disabled=this.rows.length>=e||!!this.config.disabled||!!this.config.readonly}applyValue(t){this.syncing=!0,this.rows.forEach(o=>o.destroy()),this.rows=(t??[]).map(o=>this.makeRow(o)),this.syncing=!1;let e=this.isEqual(this.original,t);this.value=this.collect(),e&&(this.original=this.value),this.paintRows()}addRow(t){let e=this.config.max??1/0;if(this.rows.length>=e)return;let o=this.config.newRow;this.rows.push(this.makeRow(t??(typeof o=="function"?o():{...o}))),this.commitRows(),this.emit("add",this.rows.length-1),this.rowFields(this.rows[this.rows.length-1])[0]?.focus()}removeRow(t){if(!this.rows[t]||this.rows.length<=(this.config.min??0)||this.emit("before-remove",t)===!1)return;let[e]=this.rows.splice(t,1);e.destroy(),this.commitRows(),this.emit("remove",t);let o=this.rows[Math.min(t,this.rows.length-1)];o?this.rowFields(o)[0]?.focus():this.rendered&&this.addBtn.focus()}moveRow(t,e){if(!this.rows[t]||e<0||e>=this.rows.length||t===e)return;let[o]=this.rows.splice(t,1);this.rows.splice(e,0,o),this.commitRows(),this.emit("move",t,e);let s=["flUp","flDown"].map(i=>o.el.querySelector(`[data-act="${i}"]`));(e<t?s:s.reverse()).find(i=>i&&!i.disabled)?.focus()}getRows(){return this.rows}getRowFields(t){return this.rows[t]?this.rowFields(this.rows[t]):[]}setAddText(t){this.config.addText=t,this.rendered&&(this.addBtn.lastElementChild.textContent=t)}setMin(t){this.config.min=t,this.paintRows()}setMax(t){this.config.max=t,this.paintRows()}check(){let t=this.value?.length??0,{min:e=0,max:o=1/0}=this.config;return t&&t<e?l("flMin",{n:e}):t>o?l("flMax",{n:o}):super.check()}validate(){let t=this.rows.flatMap(e=>this.rowFields(e)).map(e=>e.validate()).every(Boolean);return super.validate()&&t}isValid(){return super.isValid()&&this.rows.every(t=>this.rowFields(t).every(e=>e.isValid()))}focus(){let t=this.rows.flatMap(e=>this.rowFields(e)).find(e=>e.getError());t?t.focus():this.addBtn?.focus()}onDisabled(t){this.rows.forEach(e=>e.setDisabled(t)),this.paintRows()}onReadonly(t){this.rows.forEach(e=>this.rowFields(e).forEach(o=>o.setReadonly(t))),this.paintRows()}onDestroy(){this.rows.forEach(t=>t.destroy()),super.onDestroy()}};y("fieldlist",g);export{g as a};
2
+ //# sourceMappingURL=chunk-LBJSMXLV.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/form/fieldlist/fieldlist.ts"],
4
+ "sourcesContent": ["import { Field, type FieldConfig } from '../../../core/field';\nimport { Container } from '../../../core/container';\nimport { register, type AnyConfig } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { addMessages, t } from '../../../core/i18n';\nimport type { LayoutSpec } from '../../../layout/layout';\nimport { Component } from '../../../core/component';\nimport { iconEl } from '../../base/icon/icon';\n\naddMessages('en', { flAdd: 'Add', flRemove: 'Remove {row}', flUp: 'Move {row} up', flDown: 'Move {row} down', flEmpty: 'Nothing added yet', flMin: 'Add at least {n}', flMax: 'At most {n}' });\naddMessages('pt-BR', { flAdd: 'Adicionar', flRemove: 'Remover {row}', flUp: 'Subir {row}', flDown: 'Descer {row}', flEmpty: 'Nada adicionado ainda', flMin: 'Adicione pelo menos {n}', flMax: 'No m\u00E1ximo {n}' });\n\ntype Row = Record<string, any>;\n\nexport interface FieldListConfig extends FieldConfig<Row[]> {\n /** The fields of one row (configs or instances such as `ui.text(...)`). Names are relative to the row (nested allowed). */\n items?: Array<AnyConfig | Component>;\n min?: number;\n max?: number;\n addText?: string;\n reorderable?: boolean;\n /** Values for a new row, or a function that returns them. */\n newRow?: Row | (() => Row);\n /** Layout of a row. Default `hbox` (the fields share the row). */\n rowLayout?: LayoutSpec;\n}\n\nconst getPath = (o: any, path: string) => path.split('.').reduce((v, k) => v?.[k], o);\nfunction setPath(o: any, path: string, value: unknown) {\n const keys = path.split('.');\n const last = keys.pop()!;\n keys.reduce((v, k) => (v[k] ??= {}), o)[last] = value;\n}\n\n/** A repeating block of fields: add, remove and reorder rows; the value is an array of row objects. */\nexport class FieldList extends Field<Row[], FieldListConfig> {\n protected override baseCls = 'op-field op-fieldlist';\n private rowsEl!: HTMLElement;\n private addBtn!: HTMLButtonElement;\n private emptyEl!: HTMLElement;\n private rows: Container[] = [];\n private syncing = false;\n\n protected override emptyValue(): Row[] {\n return [];\n }\n protected override isEmpty(v: Row[]): boolean {\n return !v?.length;\n }\n\n protected createControl() {\n this.rowsEl = h('div', 'op-fieldlist__rows', { role: 'group' });\n this.emptyEl = h('div', 'op-fieldlist__empty', {}, t('flEmpty'));\n this.addBtn = h('button', 'op-fieldlist__add', { type: 'button' }, iconEl('plus'), h('span', '', {}, this.config.addText ?? t('flAdd')));\n this.listen(this.addBtn, 'click', () => this.addRow());\n this.inputEl = this.addBtn;\n return h('div', 'op-fieldlist__box', {}, this.rowsEl, this.emptyEl, this.addBtn);\n }\n\n protected override onRender() {\n super.onRender();\n this.rowsEl.setAttribute('aria-labelledby', (this.el.querySelector('.op-field__label') as HTMLElement).id ||= `${this.id}-label`);\n }\n\n // ---- rows ---------------------------------------------------------------------------------\n\n private label(i: number): string {\n return `${this.config.label ?? ''} ${i + 1}`.trim();\n }\n\n private makeRow(values: Row): Container {\n // every row gets fresh fields: a config is copied, an instance (`ui.text(...)`) is rebuilt from a copy of its config\n const fresh = (c: AnyConfig | Component): AnyConfig | Component => {\n const cfg = (c instanceof Component ? c.config : c) as AnyConfig;\n const copy = { ...cfg, ...(Array.isArray(cfg.items) ? { items: (cfg.items as Array<AnyConfig | Component>).map(fresh) } : {}) };\n return c instanceof Component ? new (c.constructor as new (cfg: object) => Component)(copy) : copy;\n };\n const row = new Container({ cls: 'op-fieldlist__row', layout: this.config.rowLayout ?? { type: 'hbox', align: 'flex-start' }, items: (this.config.items ?? []).map(fresh) });\n for (const c of row.items) if (c.config.width != null && c.config.flex == null) c.config.flex = 'none'; // a set width is kept\n for (const f of this.rowFields(row)) {\n const v = f.name ? getPath(values, f.name) : undefined;\n if (v !== undefined) f.setValue(v, true);\n f.on('change', () => this.syncing || this.commitRows());\n }\n return row;\n }\n\n private rowFields(row: Container): Field<any>[] {\n return row.query((c) => c instanceof Field) as Field<any>[];\n }\n\n private collect(): Row[] {\n return this.rows.map((row) => {\n const out: Row = {};\n for (const f of this.rowFields(row)) if (f.name) setPath(out, f.name, f.getValue());\n return out;\n });\n }\n\n private commitRows() {\n this.commit(this.collect());\n this.paintRows();\n if (this.getError()) this.validate();\n }\n\n /** Puts every row in place: its group name, tools, and which tools are allowed. */\n private paintRows() {\n if (!this.rendered) return;\n const { min = 0, max = Infinity, reorderable = true } = this.config;\n this.rowsEl.replaceChildren(\n ...this.rows.map((row, i) => {\n const el = row.el;\n el.setAttribute('role', 'group');\n el.setAttribute('aria-label', this.label(i));\n el.classList.toggle('is-first', i === 0);\n el.querySelector(':scope > .op-fieldlist__tools')?.remove();\n const tool = (icon: string, key: string, disabled: boolean, run: () => void) => {\n const b = h('button', 'op-fieldlist__tool', { type: 'button', 'data-act': key, 'aria-label': t(key, { row: this.label(i) }), 'data-op-tip': t(key, { row: this.label(i) }) }, iconEl(icon));\n b.disabled = disabled || !!this.config.disabled || !!this.config.readonly;\n b.addEventListener('click', run);\n return b;\n };\n const tools = h('div', 'op-fieldlist__tools');\n if (reorderable) tools.append(tool('chevron-up', 'flUp', i === 0, () => this.moveRow(i, i - 1)), tool('chevron-down', 'flDown', i === this.rows.length - 1, () => this.moveRow(i, i + 1)));\n tools.append(tool('trash', 'flRemove', this.rows.length <= min, () => this.removeRow(i)));\n el.append(tools);\n return el;\n }),\n );\n this.emptyEl.hidden = this.rows.length > 0;\n this.el.classList.toggle('is-empty', !this.rows.length);\n this.addBtn.disabled = this.rows.length >= max || !!this.config.disabled || !!this.config.readonly;\n }\n\n protected applyValue(value: Row[]): void {\n this.syncing = true;\n this.rows.forEach((r) => r.destroy());\n this.rows = (value ?? []).map((v) => this.makeRow(v));\n this.syncing = false;\n const was = this.isEqual(this.original, value);\n this.value = this.collect(); // what the rows actually hold (a missing key becomes the field's empty value)\n if (was) this.original = this.value; // normalizing the starting value does not make the form dirty\n this.paintRows();\n }\n\n /** Adds a row (at the end) and focuses its first field. */\n addRow(values?: Row): void {\n const max = this.config.max ?? Infinity;\n if (this.rows.length >= max) return;\n const n = this.config.newRow;\n this.rows.push(this.makeRow(values ?? (typeof n === 'function' ? n() : { ...n })));\n this.commitRows();\n this.emit('add', this.rows.length - 1);\n this.rowFields(this.rows[this.rows.length - 1])[0]?.focus();\n }\n\n removeRow(index: number): void {\n if (!this.rows[index] || this.rows.length <= (this.config.min ?? 0) || this.emit('before-remove', index) === false) return;\n const [row] = this.rows.splice(index, 1);\n row.destroy();\n this.commitRows();\n this.emit('remove', index);\n const next = this.rows[Math.min(index, this.rows.length - 1)];\n if (next) this.rowFields(next)[0]?.focus();\n else if (this.rendered) this.addBtn.focus();\n }\n\n moveRow(from: number, to: number): void {\n if (!this.rows[from] || to < 0 || to >= this.rows.length || from === to) return;\n const [row] = this.rows.splice(from, 1);\n this.rows.splice(to, 0, row);\n this.commitRows();\n this.emit('move', from, to);\n // the focus follows the row: the same tool if it can still move that way, the other one at the end of the list\n const tools = ['flUp', 'flDown'].map((k) => row.el.querySelector<HTMLButtonElement>(`[data-act=\"${k}\"]`));\n (to < from ? tools : tools.reverse()).find((b) => b && !b.disabled)?.focus();\n }\n\n getRows(): Container[] {\n return this.rows;\n }\n getRowFields(index: number): Field<any>[] {\n return this.rows[index] ? this.rowFields(this.rows[index]) : [];\n }\n\n setAddText(text: string): void {\n this.config.addText = text;\n if (this.rendered) this.addBtn.lastElementChild!.textContent = text;\n }\n\n setMin(min: number): void {\n this.config.min = min;\n this.paintRows();\n }\n setMax(max: number): void {\n this.config.max = max;\n this.paintRows();\n }\n\n // ---- validation ---------------------------------------------------------------------------\n\n protected override check(): string {\n const n = this.value?.length ?? 0;\n const { min = 0, max = Infinity } = this.config;\n if (n && n < min) return t('flMin', { n: min });\n if (n > max) return t('flMax', { n: max });\n return super.check();\n }\n\n /** Validates every row too; the list is valid when its own rules and every field inside pass. */\n override validate(): boolean {\n const inner = this.rows.flatMap((r) => this.rowFields(r)).map((f) => f.validate()).every(Boolean);\n return super.validate() && inner;\n }\n\n override isValid(): boolean {\n return super.isValid() && this.rows.every((r) => this.rowFields(r).every((f) => f.isValid()));\n }\n\n /** The first invalid field inside, or the add button. */\n override focus(): void {\n const bad = this.rows.flatMap((r) => this.rowFields(r)).find((f) => f.getError());\n if (bad) bad.focus();\n else this.addBtn?.focus();\n }\n\n protected override onDisabled(disabled: boolean) {\n this.rows.forEach((r) => r.setDisabled(disabled));\n this.paintRows();\n }\n protected override onReadonly(readonly: boolean) {\n this.rows.forEach((r) => this.rowFields(r).forEach((f) => f.setReadonly(readonly)));\n this.paintRows();\n }\n\n protected override onDestroy(): void {\n this.rows.forEach((r) => r.destroy());\n super.onDestroy();\n }\n}\nregister('fieldlist', FieldList);\n"],
5
+ "mappings": "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",
6
+ "names": ["addMessages", "getPath", "o", "path", "v", "k", "setPath", "value", "keys", "last", "FieldList", "Field", "h", "t", "iconEl", "i", "values", "fresh", "c", "cfg", "Component", "copy", "row", "Container", "f", "out", "min", "max", "reorderable", "el", "tool", "icon", "key", "disabled", "run", "b", "tools", "r", "was", "n", "index", "next", "from", "to", "text", "inner", "bad", "readonly", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as c}from"./chunk-GNU4VOOE.js";import{c as h}from"./chunk-ZWNQREWS.js";import{a as b}from"./chunk-2ZUZ5HDL.js";import{c as a}from"./chunk-4EZJ5FKJ.js";import{b as i,c as r}from"./chunk-PZSHOSOS.js";import{a as p}from"./chunk-TIPK3SCJ.js";import{f as l}from"./chunk-MW3RWBZ7.js";var d=class extends h{baseCls="op-panel";headerEl;titleEl;bodyEl;toolsEl;iconHost;toggleBtn;bars=[];bodyId=r("op-body");titleId=r("op-title");getBody(){return this.bodyEl}build(){let e=this.config,t=i("div",this.baseCls,{role:"region","aria-labelledby":this.titleId});this.iconHost=i("span","op-panel__icon"),this.titleEl=i("span","op-panel__title",{id:this.titleId}),this.toolsEl=i("div","op-panel__tools"),this.headerEl=i("div","op-panel__header",{},this.iconHost,this.titleEl,this.toolsEl),this.bodyEl=i("div",`op-panel__body ${e.bodyCls??""}`,{id:this.bodyId}),t.append(this.headerEl);let o=(s,f)=>{let n=new c({items:s,cls:f});return n.parent=this,this.bars.push(n),n.el};return e.tbar&&t.append(o(e.tbar,"op-panel__tbar")),t.append(this.bodyEl),e.bbar&&t.append(o(e.bbar,"op-panel__bbar")),e.buttons&&t.append(o(["->",...e.buttons.map(s=>new b(s))],"op-panel__footer")),t}onRender(){super.onRender();let e=this.config;this.setTitle(e.title??""),this.setIcon(e.icon??"");for(let t of e.tools??[])this.addTool(t.icon,t.label,o=>t.handler?.(this,o));e.reloadable&&this.addTool("refresh",l("reload"),()=>{this.reload()}),e.collapsible&&(this.toggleBtn=this.addTool("chevron-up",l("collapse"),()=>this.toggle()),this.toggleBtn.setAttribute("aria-controls",this.bodyId),this.el.classList.add("op-panel--collapsible"),this.listen(this.titleEl,"click",()=>this.toggle())),e.closable&&this.addTool("x",l("close"),()=>this.close()),this.setCollapsed(!!e.collapsed),this.updateHeader()}addTool(e,t,o){let s=i("button","op-panel__tool",{type:"button","aria-label":t,"data-op-tip":t},a(e));return this.listen(s,"click",o),this.toolsEl.append(s),s}updateHeader(){let e=this.config;this.headerEl.hidden=!e.title&&!e.icon&&!e.collapsible&&!e.closable&&!e.reloadable&&!e.tools?.length}async reload(){let e=this.el;return e.classList.contains("is-reloading")||this.emit("before-reload")===!1?!1:(e.classList.add("is-reloading"),this.setLoading(!0),await Promise.resolve(this.config.onReload?.(this)).catch(()=>0),this.setLoading(!1),e.classList.remove("is-reloading"),this.emit("reload"),!0)}setTitle(e){this.config.title=e,this.rendered&&(this.titleEl.textContent=e,this.updateHeader())}setIcon(e){this.config.icon=e,this.rendered&&(this.iconHost.replaceChildren(...e?[a(e)]:[]),this.iconHost.hidden=!e,this.updateHeader())}setCollapsed(e){if(this.config.collapsed=e,!!this.rendered){this.el.classList.toggle("is-collapsed",e);for(let t of[this.bodyEl,...this.bars.map(o=>o.el)])t.hidden=e;this.toggleBtn&&(this.toggleBtn.setAttribute("aria-expanded",String(!e)),this.toggleBtn.setAttribute("aria-label",l(e?"expand":"collapse")))}}collapse(){this.config.collapsed||this.emit("before-collapse")===!1||(this.setCollapsed(!0),this.emit("collapse"))}expand(){!this.config.collapsed||this.emit("before-expand")===!1||(this.setCollapsed(!1),this.emit("expand"))}toggle(){this.config.collapsed?this.expand():this.collapse()}close(){this.emit("before-close")!==!1&&(this.emit("close"),this.config.closeAction==="hide"?this.hide():this.destroy())}onDestroy(){super.onDestroy(),this.bars.forEach(e=>e.destroy())}};p("panel",d);export{d as a};
2
+ //# sourceMappingURL=chunk-LQRFNQ2N.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/layout/panel/panel.ts"],
4
+ "sourcesContent": ["import { Container, type ContainerConfig } from '../../../core/container';\nimport './reload';\nimport { register } from '../../../core/registry';\nimport { h, uid } from '../../../core/dom';\nimport { t } from '../../../core/i18n';\nimport { iconEl } from '../../base/icon/icon';\nimport { Toolbar, type ToolbarConfig } from '../toolbar/toolbar';\nimport { Button } from '../../base/button/button';\nimport type { ButtonConfig } from '../../base/button/button';\n\nexport interface PanelTool {\n icon: string;\n label: string;\n handler?: (panel: Panel, ev: MouseEvent) => void;\n}\n\nexport interface PanelConfig extends ContainerConfig {\n title?: string;\n icon?: string;\n collapsible?: boolean;\n collapsed?: boolean;\n closable?: boolean;\n closeAction?: 'destroy' | 'hide';\n /** A \u21BB button in the header that calls `onReload` (a Promise shows the loading mask until it settles). */\n reloadable?: boolean;\n onReload?: (panel: Panel) => void | Promise<unknown>;\n tools?: PanelTool[];\n tbar?: ToolbarConfig['items'];\n bbar?: ToolbarConfig['items'];\n buttons?: ButtonConfig[];\n bodyCls?: string;\n}\n\nexport class Panel<C extends PanelConfig = PanelConfig> extends Container<C> {\n protected override baseCls = 'op-panel';\n protected headerEl!: HTMLElement;\n protected titleEl!: HTMLElement;\n protected bodyEl!: HTMLElement;\n private toolsEl!: HTMLElement;\n private iconHost!: HTMLElement;\n private toggleBtn?: HTMLButtonElement;\n private bars: Toolbar[] = [];\n private bodyId = uid('op-body');\n private titleId = uid('op-title');\n\n override getBody() {\n return this.bodyEl;\n }\n\n protected override build() {\n const c = this.config;\n const el = h('div', this.baseCls, { role: 'region', 'aria-labelledby': this.titleId });\n this.iconHost = h('span', 'op-panel__icon');\n this.titleEl = h('span', 'op-panel__title', { id: this.titleId });\n this.toolsEl = h('div', 'op-panel__tools');\n this.headerEl = h('div', 'op-panel__header', {}, this.iconHost, this.titleEl, this.toolsEl);\n this.bodyEl = h('div', `op-panel__body ${c.bodyCls ?? ''}`, { id: this.bodyId });\n el.append(this.headerEl);\n const bar = (cfg: ToolbarConfig['items'], cls: string) => {\n const tb = new Toolbar({ items: cfg, cls });\n tb.parent = this;\n this.bars.push(tb);\n return tb.el;\n };\n if (c.tbar) el.append(bar(c.tbar, 'op-panel__tbar'));\n el.append(this.bodyEl);\n if (c.bbar) el.append(bar(c.bbar, 'op-panel__bbar'));\n if (c.buttons) el.append(bar(['->', ...c.buttons.map((b) => new Button(b))], 'op-panel__footer'));\n return el;\n }\n\n protected override onRender() {\n super.onRender();\n const c = this.config;\n this.setTitle(c.title ?? '');\n this.setIcon(c.icon ?? '');\n for (const tool of c.tools ?? []) this.addTool(tool.icon, tool.label, (e) => tool.handler?.(this, e));\n if (c.reloadable) this.addTool('refresh', t('reload'), () => void this.reload());\n if (c.collapsible) {\n this.toggleBtn = this.addTool('chevron-up', t('collapse'), () => this.toggle());\n this.toggleBtn.setAttribute('aria-controls', this.bodyId);\n this.el.classList.add('op-panel--collapsible');\n this.listen(this.titleEl, 'click', () => this.toggle());\n }\n if (c.closable) this.addTool('x', t('close'), () => this.close());\n this.setCollapsed(!!c.collapsed);\n this.updateHeader();\n }\n\n private addTool(icon: string, label: string, onClick: (e: MouseEvent) => void) {\n const b = h('button', 'op-panel__tool', { type: 'button', 'aria-label': label, 'data-op-tip': label }, iconEl(icon));\n this.listen(b, 'click', onClick);\n this.toolsEl.append(b);\n return b;\n }\n\n private updateHeader() {\n const c = this.config;\n this.headerEl.hidden = !c.title && !c.icon && !c.collapsible && !c.closable && !c.reloadable && !c.tools?.length;\n }\n\n /** Runs `onReload` (`before-reload` can cancel); a returned Promise keeps the loading mask (and a turning \u21BB) until it settles. */\n async reload(): Promise<boolean> {\n const el = this.el;\n if (el.classList.contains('is-reloading') || this.emit('before-reload') === false) return false;\n el.classList.add('is-reloading');\n this.setLoading(true);\n await Promise.resolve(this.config.onReload?.(this)).catch(() => 0);\n this.setLoading(false);\n el.classList.remove('is-reloading');\n this.emit('reload');\n return true;\n }\n\n setTitle(title: string) {\n this.config.title = title;\n if (!this.rendered) return;\n this.titleEl.textContent = title;\n this.updateHeader();\n }\n\n setIcon(name: string) {\n this.config.icon = name;\n if (!this.rendered) return;\n this.iconHost.replaceChildren(...(name ? [iconEl(name)] : []));\n this.iconHost.hidden = !name;\n this.updateHeader();\n }\n\n /** Collapses/expands without events. Use `collapse()`/`expand()` for the full behavior. */\n setCollapsed(collapsed: boolean) {\n this.config.collapsed = collapsed;\n if (!this.rendered) return;\n this.el.classList.toggle('is-collapsed', collapsed);\n for (const e of [this.bodyEl, ...this.bars.map((b) => b.el)]) e.hidden = collapsed;\n if (this.toggleBtn) {\n this.toggleBtn.setAttribute('aria-expanded', String(!collapsed));\n this.toggleBtn.setAttribute('aria-label', t(collapsed ? 'expand' : 'collapse'));\n }\n }\n\n collapse() {\n if (this.config.collapsed || this.emit('before-collapse') === false) return;\n this.setCollapsed(true);\n this.emit('collapse');\n }\n expand() {\n if (!this.config.collapsed || this.emit('before-expand') === false) return;\n this.setCollapsed(false);\n this.emit('expand');\n }\n toggle() {\n if (this.config.collapsed) this.expand();\n else this.collapse();\n }\n\n close() {\n if (this.emit('before-close') === false) return;\n this.emit('close');\n if (this.config.closeAction === 'hide') this.hide();\n else this.destroy();\n }\n\n protected override onDestroy() {\n super.onDestroy();\n this.bars.forEach((b) => b.destroy());\n }\n}\nregister('panel', Panel);\n"],
5
+ "mappings": "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",
6
+ "names": ["Panel", "Container", "uid", "c", "el", "h", "bar", "cfg", "cls", "tb", "Toolbar", "b", "Button", "tool", "e", "t", "icon", "label", "onClick", "iconEl", "title", "name", "collapsed", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{d as o}from"./chunk-MW3RWBZ7.js";var n=()=>o()._lang,a=(t,e)=>{if(t==null||t==="")return"";let r=t instanceof Date?t:typeof t=="string"&&/^\d{4}-\d{2}-\d{2}$/.test(t)?new Date(+t.slice(0,4),+t.slice(5,7)-1,+t.slice(8,10)):new Date(t);return isNaN(+r)?String(t):new Intl.DateTimeFormat(n(),e).format(r)},i={number:(t,e)=>t==null||t===""?"":new Intl.NumberFormat(n(),e).format(t),money:(t,e)=>t==null||t===""?"":new Intl.NumberFormat(n(),{style:"currency",currency:o()._currency,...e}).format(t),percent:(t,e)=>t==null||t===""?"":new Intl.NumberFormat(n(),{style:"percent",maximumFractionDigits:1,...e}).format(t),date:(t,e)=>a(t,{dateStyle:"medium",...e}),datetime:(t,e)=>a(t,{dateStyle:"medium",timeStyle:"short",...e}),bool:t=>t?"\u2713":""};function s(t,e){i[t]=e}function m(t,e){let r=typeof t=="function"?t:i[t];if(!r)throw new Error(`Optikos: unknown format "${t}"`);return r(e)}function c(t,e){let r=e.data[t.field];return t.renderer?t.renderer(r,e,t):t.format?m(t.format,r):r==null?"":String(r)}export{s as a,m as b,c};
2
+ //# sourceMappingURL=chunk-LW2WRUVL.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/data/format.ts", "../src/data/column.ts"],
4
+ "sourcesContent": ["import { getLocale } from '../core/i18n';\n\nexport type Formatter = (value: any, options?: Record<string, any>) => string;\n\nconst lang = () => getLocale()._lang;\nconst date = (v: any, opts: Intl.DateTimeFormatOptions) => {\n if (v == null || v === '') return '';\n // ISO dates without time are local dates, not UTC.\n const d = v instanceof Date ? v : typeof v === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(v) ? new Date(+v.slice(0, 4), +v.slice(5, 7) - 1, +v.slice(8, 10)) : new Date(v);\n return isNaN(+d) ? String(v) : new Intl.DateTimeFormat(lang(), opts).format(d);\n};\n\nconst formats: Record<string, Formatter> = {\n number: (v, o) => (v == null || v === '' ? '' : new Intl.NumberFormat(lang(), o).format(v)),\n money: (v, o) => (v == null || v === '' ? '' : new Intl.NumberFormat(lang(), { style: 'currency', currency: getLocale()._currency, ...o }).format(v)),\n percent: (v, o) => (v == null || v === '' ? '' : new Intl.NumberFormat(lang(), { style: 'percent', maximumFractionDigits: 1, ...o }).format(v)),\n date: (v, o) => date(v, { dateStyle: 'medium', ...o }),\n datetime: (v, o) => date(v, { dateStyle: 'medium', timeStyle: 'short', ...o }),\n bool: (v) => (v ? '\u2713' : ''),\n};\n\n/** Registers a named formatter, usable as `format: 'name'` in columns. */\nexport function registerFormat(name: string, fn: Formatter): void {\n formats[name] = fn;\n}\n\nexport function format(fmt: string | Formatter, value: unknown): string {\n const fn = typeof fmt === 'function' ? fmt : formats[fmt];\n if (!fn) throw new Error(`Optikos: unknown format \"${fmt}\"`);\n return fn(value);\n}\n", "import { format, type Formatter } from './format';\nimport type { Model } from './model';\n\n/** A grid/table column. `T` is the record shape: `field` then autocompletes its keys (any string still works). */\nexport interface Column<T extends Record<string, any> = any> {\n field: Extract<keyof T, string> | (string & {});\n header?: string;\n /** Fixed width in px. */\n width?: number;\n /** Share of the free space (like CSS `fr`). Default 1 when there is no `width`. */\n flex?: number;\n /** A label that groups columns (\"Identification\", \"Values\"...): a band over the header and sections in the column menu. */\n group?: string;\n minWidth?: number;\n /** Upper bound when the user resizes it. */\n maxWidth?: number;\n /** `false` keeps a column's width fixed even when the grid has `resizableColumns`. */\n resizable?: boolean;\n align?: 'left' | 'center' | 'right';\n sortable?: boolean;\n hidden?: boolean;\n /** Name registered with `registerFormat` (`money`, `date`, `number`, `percent`, `bool`) or a function. */\n format?: string | Formatter;\n /** Full control over the cell content. Text is escaped; return a Node for markup. */\n renderer?: (value: any, rec: Model<T>, col: Column<T>) => string | Node;\n cls?: string;\n /** With the `cellEditing()` grid plugin: `true` (an editor for the value's type), a field type (`'select'`) or a field config. */\n editor?: boolean | string | Record<string, any>;\n /** With `cellEditing()`: whether this record's cell can be edited (default: every record, when `editor` is set). */\n editable?: (rec: Model<T>) => boolean;\n}\n\n/** Cell content for a record: `renderer` first, then `format`, then the plain value. */\nexport function cellContent<T extends Record<string, any>>(col: Column<T>, rec: Model<T>): string | Node {\n const v = rec.data[col.field];\n if (col.renderer) return col.renderer(v, rec, col);\n if (col.format) return format(col.format, v);\n return v == null ? '' : String(v);\n}\n"],
5
+ "mappings": "wCAIA,IAAMA,EAAO,IAAMC,EAAU,EAAE,MACzBC,EAAO,CAACC,EAAQC,IAAqC,CACzD,GAAID,GAAK,MAAQA,IAAM,GAAI,MAAO,GAElC,IAAME,EAAIF,aAAa,KAAOA,EAAI,OAAOA,GAAM,UAAY,sBAAsB,KAAKA,CAAC,EAAI,IAAI,KAAK,CAACA,EAAE,MAAM,EAAG,CAAC,EAAG,CAACA,EAAE,MAAM,EAAG,CAAC,EAAI,EAAG,CAACA,EAAE,MAAM,EAAG,EAAE,CAAC,EAAI,IAAI,KAAKA,CAAC,EACrK,OAAO,MAAM,CAACE,CAAC,EAAI,OAAOF,CAAC,EAAI,IAAI,KAAK,eAAeH,EAAK,EAAGI,CAAI,EAAE,OAAOC,CAAC,CAC/E,EAEMC,EAAqC,CACzC,OAAQ,CAACH,EAAGI,IAAOJ,GAAK,MAAQA,IAAM,GAAK,GAAK,IAAI,KAAK,aAAaH,EAAK,EAAGO,CAAC,EAAE,OAAOJ,CAAC,EACzF,MAAO,CAACA,EAAGI,IAAOJ,GAAK,MAAQA,IAAM,GAAK,GAAK,IAAI,KAAK,aAAaH,EAAK,EAAG,CAAE,MAAO,WAAY,SAAUC,EAAU,EAAE,UAAW,GAAGM,CAAE,CAAC,EAAE,OAAOJ,CAAC,EACnJ,QAAS,CAACA,EAAGI,IAAOJ,GAAK,MAAQA,IAAM,GAAK,GAAK,IAAI,KAAK,aAAaH,EAAK,EAAG,CAAE,MAAO,UAAW,sBAAuB,EAAG,GAAGO,CAAE,CAAC,EAAE,OAAOJ,CAAC,EAC7I,KAAM,CAACA,EAAGI,IAAML,EAAKC,EAAG,CAAE,UAAW,SAAU,GAAGI,CAAE,CAAC,EACrD,SAAU,CAACJ,EAAGI,IAAML,EAAKC,EAAG,CAAE,UAAW,SAAU,UAAW,QAAS,GAAGI,CAAE,CAAC,EAC7E,KAAOJ,GAAOA,EAAI,SAAM,EAC1B,EAGO,SAASK,EAAeC,EAAcC,EAAqB,CAChEJ,EAAQG,CAAI,EAAIC,CAClB,CAEO,SAASC,EAAOC,EAAyBC,EAAwB,CACtE,IAAMH,EAAK,OAAOE,GAAQ,WAAaA,EAAMN,EAAQM,CAAG,EACxD,GAAI,CAACF,EAAI,MAAM,IAAI,MAAM,4BAA4BE,CAAG,GAAG,EAC3D,OAAOF,EAAGG,CAAK,CACjB,CCGO,SAASC,EAA2CC,EAAgBC,EAA8B,CACvG,IAAMC,EAAID,EAAI,KAAKD,EAAI,KAAK,EAC5B,OAAIA,EAAI,SAAiBA,EAAI,SAASE,EAAGD,EAAKD,CAAG,EAC7CA,EAAI,OAAeG,EAAOH,EAAI,OAAQE,CAAC,EACpCA,GAAK,KAAO,GAAK,OAAOA,CAAC,CAClC",
6
+ "names": ["lang", "getLocale", "date", "v", "opts", "d", "formats", "o", "registerFormat", "name", "fn", "format", "fmt", "value", "cellContent", "col", "rec", "v", "format"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as f}from"./chunk-ZVK4L5GK.js";import{c as m}from"./chunk-OEAXCCVM.js";import{e as p}from"./chunk-4AA4FQEM.js";import{a as c}from"./chunk-A2NKDOYN.js";import{b as a}from"./chunk-PZSHOSOS.js";import{a as d}from"./chunk-TIPK3SCJ.js";import{f as l}from"./chunk-MW3RWBZ7.js";var h=class extends c{baseCls="op-dataview";store;itemsEl;emptyEl;pager;selected=new Set;active=0;anchor=-1;offStore;build(){let t=this.config,e=a("div",this.baseCls,{role:"listbox","aria-multiselectable":t.selection==="multi"?"true":null});return this.itemsEl=a("div","op-dataview__items"),this.emptyEl=a("div","op-dataview__empty"),e.append(this.itemsEl,this.emptyEl),t.itemWidth&&e.style.setProperty("--op-dataview-item-width",t.itemWidth),t.gap&&e.style.setProperty("--op-dataview-gap",t.gap),t.paging&&(this.pager=new f({cls:"op-dataview__pager"}),e.append(this.pager.el)),e}onRender(){let t=this.config;this.bindStore(t.store??new m({data:t.data??[]})),this.listen(this.itemsEl,"click",e=>this.onClick(e,"item-click")),this.listen(this.itemsEl,"dblclick",e=>this.onClick(e,"item-dblclick")),this.listen(this.itemsEl,"keydown",e=>this.onKey(e)),this.listen(this.itemsEl,"focusin",e=>{let i=this.indexOf(e);i>=0&&this.setActive(i,!1)}),this.pager&&(this.pager.setStore(this.store),this.store.pageSize||this.store.setPageSize(t.pageSize??24)),this.own(()=>this.pager?.destroy()),this.paint(!0)}notifyMount(){super.notifyMount(),this.pager?.notifyMount()}bindStore(t){this.offStore?.(),this.store=t;let e=t.subscribe(s=>this.rendered&&this.paint(["load","page","filter","sort"].includes(s.type))),i=t.on("loading",s=>this.setLoading(s));this.offStore=()=>(e(),i()),this.own(()=>this.offStore?.())}setStore(t){this.config.store=t,this.selected.clear(),this.active=0,this.rendered&&(this.bindStore(t),this.pager?.setStore(t),this.paint())}getStore(){return this.render(),this.store}paint(t=!1){let e=this.config;for(let s of this.selected)this.store.indexOf(s)<0&&this.selected.delete(s);this.active=Math.min(this.active,Math.max(0,this.store.count-1));let i=e.selection??"single";this.itemsEl.replaceChildren(...this.store.getRange().map((s,o)=>{let n=a("div",`op-dataview__item${this.selected.has(s)?" is-selected":""}${o===this.active?" is-active":""}${e.itemCls?` ${e.itemCls(s)}`:""}`,{role:"option",id:`${this.id}-i${o}`,"data-i":o,tabindex:o===this.active?0:-1,"aria-selected":i==="none"?null:String(this.selected.has(s))});return n.append(e.renderer(s,o)),n})),t&&e.stagger!==!1&&p(this.items(),{dy:8}),this.emptyEl.textContent=e.emptyText??l("empty"),this.emptyEl.hidden=this.store.count>0,this.el.classList.toggle("is-empty",this.store.count===0)}refresh(){this.rendered&&this.paint()}items(){return Array.from(this.itemsEl.children)}indexOf(t){let e=t.target.closest(".op-dataview__item");return e?Number(e.dataset.i):-1}columns(){let t=this.items();return t.length?Math.max(1,t.filter(e=>e.offsetTop===t[0].offsetTop).length):1}getSelection(){return[...this.selected]}select(t,e={}){let i=typeof t=="number"?this.store.getAt(t):t,s=this.config.selection??"single";!i||s==="none"||((s==="single"||!e.add)&&this.selected.clear(),this.selected.add(i),this.changed())}selectAll(){this.config.selection==="multi"&&(this.store.each(t=>this.selected.add(t)),this.changed())}deselectAll(){this.selected.size&&(this.selected.clear(),this.changed())}changed(){this.paintSelection(),this.emit("select",this.getSelection())}paintSelection(){this.items().forEach((t,e)=>{let i=this.selected.has(this.store.getAt(e));t.classList.toggle("is-selected",i),(this.config.selection??"single")!=="none"&&t.setAttribute("aria-selected",String(i))})}pick(t,e){let i=this.config.selection??"single",s=this.store.getAt(t);if(!(!s||i==="none")){if(i==="multi"&&e.shiftKey&&this.anchor>=0){this.selected.clear();for(let o of this.store.getRange(Math.min(this.anchor,t),Math.max(this.anchor,t)+1))this.selected.add(o)}else i==="multi"&&(e.ctrlKey||e.metaKey)?(this.selected.delete(s)||this.selected.add(s),this.anchor=t):(this.selected.clear(),this.selected.add(s),this.anchor=t);this.changed()}}onClick(t,e){let i=this.indexOf(t),s=this.store.getAt(i);if(!s)return;let o=t.target.closest("[data-op-action]");if(o){e==="item-click"&&this.emit("item-action",o.dataset.opAction,s,t);return}e==="item-click"&&(this.setActive(i,!1),this.pick(i,t)),this.emit(e,s,i,t)}setActive(t,e=!0){this.active=t,this.items().forEach((i,s)=>{i.tabIndex=s===t?0:-1,i.classList.toggle("is-active",s===t)}),e&&this.items()[t]?.focus(),this.emit("active-change",t)}focusItem(t){this.render(),this.setActive(Math.max(0,Math.min(t,this.store.count-1)))}onKey(t){let e=this.store.count;if(!e)return;let i=this.columns(),s=Math.max(1,Math.floor(this.el.clientHeight/Math.max(1,this.items()[0]?.offsetHeight??1))||3),o=this.active,n={ArrowRight:Math.min(e-1,o+1),ArrowLeft:Math.max(0,o-1),ArrowDown:Math.min(e-1,o+i),ArrowUp:Math.max(0,o-i),Home:0,End:e-1,PageDown:Math.min(e-1,o+i*s),PageUp:Math.max(0,o-i*s)},r=this.config.selection??"single";t.key in n?(t.preventDefault(),this.setActive(n[t.key]),r==="multi"&&t.shiftKey?this.pick(n[t.key],{shiftKey:!0}):r==="single"&&!t.ctrlKey&&this.pick(n[t.key],{}),r==="multi"&&t.shiftKey&&this.anchor<0&&(this.anchor=o)):t.key===" "?(t.preventDefault(),this.pick(o,r==="multi"?{ctrlKey:!0}:{})):t.key==="Enter"?this.emit("item-activate",this.store.getAt(o),o):(t.key==="a"||t.key==="A")&&(t.ctrlKey||t.metaKey)&&r==="multi"&&(t.preventDefault(),this.selectAll())}onDestroy(){this.pager?.destroy()}};d("dataview",h);export{h as a};
2
+ //# sourceMappingURL=chunk-M242VYZA.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/data/dataview/dataview.ts"],
4
+ "sourcesContent": ["import { Component, type ComponentConfig } from '../../../core/component';\nimport { register } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { t } from '../../../core/i18n';\nimport { Store } from '../../../data/store';\nimport type { Model } from '../../../data/model';\nimport { Pagination } from '../pagination/pagination';\nimport { stagger } from '../../../motion/core';\n\nexport interface DataViewConfig extends ComponentConfig {\n store?: Store<any>;\n /** Used when no `store` is given. */\n data?: Record<string, any>[];\n /** What one item shows. Text is escaped; return a Node for markup. */\n renderer: (rec: Model, index: number) => string | Node;\n selection?: 'none' | 'single' | 'multi';\n /** Minimum item width (CSS length): the columns adapt to the room there is. Default `10rem`. */\n itemWidth?: string;\n gap?: string;\n itemCls?: (rec: Model) => string;\n emptyText?: string;\n /** Items enter one after the other (30 ms apart, motion rule 3) when the data loads, the page or filter changes. Default true. */\n stagger?: boolean;\n /** A Pagination bar bound to the store. */\n paging?: boolean;\n pageSize?: number;\n}\n\n/** A Store as a responsive grid of cards: selection, 2-D keyboard navigation, per-item actions and optional paging. */\nexport class DataView extends Component<DataViewConfig> {\n protected override baseCls = 'op-dataview';\n private store!: Store<any>;\n private itemsEl!: HTMLElement;\n private emptyEl!: HTMLElement;\n private pager?: Pagination;\n private selected = new Set<Model>();\n private active = 0;\n private anchor = -1;\n private offStore?: () => void;\n\n protected override build() {\n const c = this.config;\n const el = h('div', this.baseCls, { role: 'listbox', 'aria-multiselectable': c.selection === 'multi' ? 'true' : null });\n this.itemsEl = h('div', 'op-dataview__items');\n this.emptyEl = h('div', 'op-dataview__empty');\n el.append(this.itemsEl, this.emptyEl);\n if (c.itemWidth) el.style.setProperty('--op-dataview-item-width', c.itemWidth);\n if (c.gap) el.style.setProperty('--op-dataview-gap', c.gap);\n if (c.paging) {\n this.pager = new Pagination({ cls: 'op-dataview__pager' });\n el.append(this.pager.el);\n }\n return el;\n }\n\n protected override onRender() {\n const c = this.config;\n this.bindStore(c.store ?? new Store({ data: c.data ?? [] }));\n this.listen(this.itemsEl, 'click', (e: MouseEvent) => this.onClick(e, 'item-click'));\n this.listen(this.itemsEl, 'dblclick', (e: MouseEvent) => this.onClick(e, 'item-dblclick'));\n this.listen(this.itemsEl, 'keydown', (e: KeyboardEvent) => this.onKey(e));\n this.listen(this.itemsEl, 'focusin', (e: Event) => {\n const i = this.indexOf(e);\n if (i >= 0) this.setActive(i, false);\n });\n if (this.pager) {\n this.pager.setStore(this.store);\n if (!this.store.pageSize) this.store.setPageSize(c.pageSize ?? 24);\n }\n this.own(() => this.pager?.destroy());\n this.paint(true);\n }\n\n override notifyMount() {\n super.notifyMount();\n this.pager?.notifyMount();\n }\n\n // ---- store -----------------------------------------------------------------------------------\n\n private bindStore(store: Store<any>) {\n this.offStore?.();\n this.store = store;\n const a = store.subscribe((c) => this.rendered && this.paint(['load', 'page', 'filter', 'sort'].includes(c.type)));\n const b = store.on('loading', (on: boolean) => this.setLoading(on));\n this.offStore = () => (a(), b());\n this.own(() => this.offStore?.());\n }\n\n setStore(store: Store<any>) {\n this.config.store = store;\n this.selected.clear();\n this.active = 0;\n if (!this.rendered) return;\n this.bindStore(store);\n this.pager?.setStore(store);\n this.paint();\n }\n getStore(): Store<any> {\n this.render();\n return this.store;\n }\n\n // ---- rendering -------------------------------------------------------------------------------\n\n private paint(animate = false) {\n const c = this.config;\n for (const r of this.selected) if (this.store.indexOf(r) < 0) this.selected.delete(r);\n this.active = Math.min(this.active, Math.max(0, this.store.count - 1));\n const mode = c.selection ?? 'single';\n this.itemsEl.replaceChildren(\n ...this.store.getRange().map((rec, i) => {\n const item = h('div', `op-dataview__item${this.selected.has(rec) ? ' is-selected' : ''}${i === this.active ? ' is-active' : ''}${c.itemCls ? ` ${c.itemCls(rec)}` : ''}`, {\n role: 'option', id: `${this.id}-i${i}`, 'data-i': i, tabindex: i === this.active ? 0 : -1, 'aria-selected': mode === 'none' ? null : String(this.selected.has(rec)),\n });\n item.append(c.renderer(rec, i));\n return item;\n }),\n );\n if (animate && c.stagger !== false) void stagger(this.items(), { dy: 8 });\n this.emptyEl.textContent = c.emptyText ?? t('empty');\n this.emptyEl.hidden = this.store.count > 0;\n this.el.classList.toggle('is-empty', this.store.count === 0);\n }\n\n /** Redraws the items (after a field of a record changed). */\n refresh() {\n if (this.rendered) this.paint();\n }\n\n private items(): HTMLElement[] {\n return Array.from(this.itemsEl.children) as HTMLElement[];\n }\n private indexOf(e: Event): number {\n const el = (e.target as HTMLElement).closest<HTMLElement>('.op-dataview__item');\n return el ? Number(el.dataset.i) : -1;\n }\n\n /** How many items fit in a row now (items that share the first one's top edge). */\n columns(): number {\n const els = this.items();\n if (!els.length) return 1;\n return Math.max(1, els.filter((el) => el.offsetTop === els[0].offsetTop).length);\n }\n\n // ---- selection -------------------------------------------------------------------------------\n\n getSelection(): Model[] {\n return [...this.selected];\n }\n\n select(target: Model | number, opts: { add?: boolean } = {}) {\n const rec = typeof target === 'number' ? this.store.getAt(target) : target;\n const mode = this.config.selection ?? 'single';\n if (!rec || mode === 'none') return;\n if (mode === 'single' || !opts.add) this.selected.clear();\n this.selected.add(rec);\n this.changed();\n }\n selectAll() {\n if (this.config.selection !== 'multi') return;\n this.store.each((r) => this.selected.add(r));\n this.changed();\n }\n deselectAll() {\n if (!this.selected.size) return;\n this.selected.clear();\n this.changed();\n }\n\n private changed() {\n this.paintSelection();\n this.emit('select', this.getSelection());\n }\n private paintSelection() {\n this.items().forEach((el, i) => {\n const on = this.selected.has(this.store.getAt(i)!);\n el.classList.toggle('is-selected', on);\n if ((this.config.selection ?? 'single') !== 'none') el.setAttribute('aria-selected', String(on));\n });\n }\n\n /** Click semantics: plain = replace, Ctrl/\u2318 = toggle, Shift = range from the anchor (multi only). */\n private pick(i: number, e: { ctrlKey?: boolean; metaKey?: boolean; shiftKey?: boolean }) {\n const mode = this.config.selection ?? 'single';\n const rec = this.store.getAt(i);\n if (!rec || mode === 'none') return;\n if (mode === 'multi' && e.shiftKey && this.anchor >= 0) {\n this.selected.clear();\n for (const r of this.store.getRange(Math.min(this.anchor, i), Math.max(this.anchor, i) + 1)) this.selected.add(r);\n } else if (mode === 'multi' && (e.ctrlKey || e.metaKey)) {\n if (!this.selected.delete(rec)) this.selected.add(rec);\n this.anchor = i;\n } else {\n this.selected.clear();\n this.selected.add(rec);\n this.anchor = i;\n }\n this.changed();\n }\n\n private onClick(e: MouseEvent, name: string) {\n const i = this.indexOf(e);\n const rec = this.store.getAt(i);\n if (!rec) return;\n const action = (e.target as HTMLElement).closest<HTMLElement>('[data-op-action]');\n if (action) {\n if (name === 'item-click') this.emit('item-action', action.dataset.opAction, rec, e);\n return; // a button inside the card is not a selection\n }\n if (name === 'item-click') {\n this.setActive(i, false);\n this.pick(i, e);\n }\n this.emit(name, rec, i, e);\n }\n\n // ---- focus and keyboard ----------------------------------------------------------------------\n\n private setActive(i: number, focus = true) {\n this.active = i;\n this.items().forEach((el, n) => {\n el.tabIndex = n === i ? 0 : -1;\n el.classList.toggle('is-active', n === i);\n });\n if (focus) this.items()[i]?.focus();\n this.emit('active-change', i);\n }\n focusItem(i: number) {\n this.render();\n this.setActive(Math.max(0, Math.min(i, this.store.count - 1)));\n }\n\n private onKey(e: KeyboardEvent) {\n const n = this.store.count;\n if (!n) return;\n const cols = this.columns();\n const rows = Math.max(1, Math.floor(this.el.clientHeight / Math.max(1, this.items()[0]?.offsetHeight ?? 1)) || 3);\n const cur = this.active;\n const to: Record<string, number> = {\n ArrowRight: Math.min(n - 1, cur + 1), ArrowLeft: Math.max(0, cur - 1),\n ArrowDown: Math.min(n - 1, cur + cols), ArrowUp: Math.max(0, cur - cols),\n Home: 0, End: n - 1, PageDown: Math.min(n - 1, cur + cols * rows), PageUp: Math.max(0, cur - cols * rows),\n };\n const mode = this.config.selection ?? 'single';\n if (e.key in to) {\n e.preventDefault();\n this.setActive(to[e.key]);\n if (mode === 'multi' && e.shiftKey) this.pick(to[e.key], { shiftKey: true });\n else if (mode === 'single' && !e.ctrlKey) this.pick(to[e.key], {});\n if (mode === 'multi' && e.shiftKey && this.anchor < 0) this.anchor = cur;\n } else if (e.key === ' ') {\n e.preventDefault();\n this.pick(cur, mode === 'multi' ? { ctrlKey: true } : {});\n } else if (e.key === 'Enter') {\n this.emit('item-activate', this.store.getAt(cur), cur);\n } else if ((e.key === 'a' || e.key === 'A') && (e.ctrlKey || e.metaKey) && mode === 'multi') {\n e.preventDefault();\n this.selectAll();\n }\n }\n\n protected override onDestroy() {\n this.pager?.destroy();\n }\n}\nregister('dataview', DataView);\n"],
5
+ "mappings": "wRA6BO,IAAMA,EAAN,cAAuBC,CAA0B,CACnC,QAAU,cACrB,MACA,QACA,QACA,MACA,SAAW,IAAI,IACf,OAAS,EACT,OAAS,GACT,SAEW,OAAQ,CACzB,IAAMC,EAAI,KAAK,OACTC,EAAKC,EAAE,MAAO,KAAK,QAAS,CAAE,KAAM,UAAW,uBAAwBF,EAAE,YAAc,QAAU,OAAS,IAAK,CAAC,EACtH,YAAK,QAAUE,EAAE,MAAO,oBAAoB,EAC5C,KAAK,QAAUA,EAAE,MAAO,oBAAoB,EAC5CD,EAAG,OAAO,KAAK,QAAS,KAAK,OAAO,EAChCD,EAAE,WAAWC,EAAG,MAAM,YAAY,2BAA4BD,EAAE,SAAS,EACzEA,EAAE,KAAKC,EAAG,MAAM,YAAY,oBAAqBD,EAAE,GAAG,EACtDA,EAAE,SACJ,KAAK,MAAQ,IAAIG,EAAW,CAAE,IAAK,oBAAqB,CAAC,EACzDF,EAAG,OAAO,KAAK,MAAM,EAAE,GAElBA,CACT,CAEmB,UAAW,CAC5B,IAAMD,EAAI,KAAK,OACf,KAAK,UAAUA,EAAE,OAAS,IAAII,EAAM,CAAE,KAAMJ,EAAE,MAAQ,CAAC,CAAE,CAAC,CAAC,EAC3D,KAAK,OAAO,KAAK,QAAS,QAAU,GAAkB,KAAK,QAAQ,EAAG,YAAY,CAAC,EACnF,KAAK,OAAO,KAAK,QAAS,WAAa,GAAkB,KAAK,QAAQ,EAAG,eAAe,CAAC,EACzF,KAAK,OAAO,KAAK,QAAS,UAAY,GAAqB,KAAK,MAAM,CAAC,CAAC,EACxE,KAAK,OAAO,KAAK,QAAS,UAAY,GAAa,CACjD,IAAM,EAAI,KAAK,QAAQ,CAAC,EACpB,GAAK,GAAG,KAAK,UAAU,EAAG,EAAK,CACrC,CAAC,EACG,KAAK,QACP,KAAK,MAAM,SAAS,KAAK,KAAK,EACzB,KAAK,MAAM,UAAU,KAAK,MAAM,YAAYA,EAAE,UAAY,EAAE,GAEnE,KAAK,IAAI,IAAM,KAAK,OAAO,QAAQ,CAAC,EACpC,KAAK,MAAM,EAAI,CACjB,CAES,aAAc,CACrB,MAAM,YAAY,EAClB,KAAK,OAAO,YAAY,CAC1B,CAIQ,UAAUK,EAAmB,CACnC,KAAK,WAAW,EAChB,KAAK,MAAQA,EACb,IAAMC,EAAID,EAAM,UAAWL,GAAM,KAAK,UAAY,KAAK,MAAM,CAAC,OAAQ,OAAQ,SAAU,MAAM,EAAE,SAASA,EAAE,IAAI,CAAC,CAAC,EAC3GO,EAAIF,EAAM,GAAG,UAAYG,GAAgB,KAAK,WAAWA,CAAE,CAAC,EAClE,KAAK,SAAW,KAAOF,EAAE,EAAGC,EAAE,GAC9B,KAAK,IAAI,IAAM,KAAK,WAAW,CAAC,CAClC,CAEA,SAASF,EAAmB,CAC1B,KAAK,OAAO,MAAQA,EACpB,KAAK,SAAS,MAAM,EACpB,KAAK,OAAS,EACT,KAAK,WACV,KAAK,UAAUA,CAAK,EACpB,KAAK,OAAO,SAASA,CAAK,EAC1B,KAAK,MAAM,EACb,CACA,UAAuB,CACrB,YAAK,OAAO,EACL,KAAK,KACd,CAIQ,MAAMI,EAAU,GAAO,CAC7B,IAAMT,EAAI,KAAK,OACf,QAAWU,KAAK,KAAK,SAAc,KAAK,MAAM,QAAQA,CAAC,EAAI,GAAG,KAAK,SAAS,OAAOA,CAAC,EACpF,KAAK,OAAS,KAAK,IAAI,KAAK,OAAQ,KAAK,IAAI,EAAG,KAAK,MAAM,MAAQ,CAAC,CAAC,EACrE,IAAMC,EAAOX,EAAE,WAAa,SAC5B,KAAK,QAAQ,gBACX,GAAG,KAAK,MAAM,SAAS,EAAE,IAAI,CAACY,EAAKC,IAAM,CACvC,IAAMC,EAAOZ,EAAE,MAAO,oBAAoB,KAAK,SAAS,IAAIU,CAAG,EAAI,eAAiB,EAAE,GAAGC,IAAM,KAAK,OAAS,aAAe,EAAE,GAAGb,EAAE,QAAU,IAAIA,EAAE,QAAQY,CAAG,CAAC,GAAK,EAAE,GAAI,CACxK,KAAM,SAAU,GAAI,GAAG,KAAK,EAAE,KAAKC,CAAC,GAAI,SAAUA,EAAG,SAAUA,IAAM,KAAK,OAAS,EAAI,GAAI,gBAAiBF,IAAS,OAAS,KAAO,OAAO,KAAK,SAAS,IAAIC,CAAG,CAAC,CACpK,CAAC,EACD,OAAAE,EAAK,OAAOd,EAAE,SAASY,EAAKC,CAAC,CAAC,EACvBC,CACT,CAAC,CACH,EACIL,GAAWT,EAAE,UAAY,IAAYe,EAAQ,KAAK,MAAM,EAAG,CAAE,GAAI,CAAE,CAAC,EACxE,KAAK,QAAQ,YAAcf,EAAE,WAAagB,EAAE,OAAO,EACnD,KAAK,QAAQ,OAAS,KAAK,MAAM,MAAQ,EACzC,KAAK,GAAG,UAAU,OAAO,WAAY,KAAK,MAAM,QAAU,CAAC,CAC7D,CAGA,SAAU,CACJ,KAAK,UAAU,KAAK,MAAM,CAChC,CAEQ,OAAuB,CAC7B,OAAO,MAAM,KAAK,KAAK,QAAQ,QAAQ,CACzC,CACQ,QAAQC,EAAkB,CAChC,IAAMhB,EAAMgB,EAAE,OAAuB,QAAqB,oBAAoB,EAC9E,OAAOhB,EAAK,OAAOA,EAAG,QAAQ,CAAC,EAAI,EACrC,CAGA,SAAkB,CAChB,IAAMiB,EAAM,KAAK,MAAM,EACvB,OAAKA,EAAI,OACF,KAAK,IAAI,EAAGA,EAAI,OAAQjB,GAAOA,EAAG,YAAciB,EAAI,CAAC,EAAE,SAAS,EAAE,MAAM,EADvD,CAE1B,CAIA,cAAwB,CACtB,MAAO,CAAC,GAAG,KAAK,QAAQ,CAC1B,CAEA,OAAOC,EAAwBC,EAA0B,CAAC,EAAG,CAC3D,IAAMR,EAAM,OAAOO,GAAW,SAAW,KAAK,MAAM,MAAMA,CAAM,EAAIA,EAC9DR,EAAO,KAAK,OAAO,WAAa,SAClC,CAACC,GAAOD,IAAS,UACjBA,IAAS,UAAY,CAACS,EAAK,MAAK,KAAK,SAAS,MAAM,EACxD,KAAK,SAAS,IAAIR,CAAG,EACrB,KAAK,QAAQ,EACf,CACA,WAAY,CACN,KAAK,OAAO,YAAc,UAC9B,KAAK,MAAM,KAAMF,GAAM,KAAK,SAAS,IAAIA,CAAC,CAAC,EAC3C,KAAK,QAAQ,EACf,CACA,aAAc,CACP,KAAK,SAAS,OACnB,KAAK,SAAS,MAAM,EACpB,KAAK,QAAQ,EACf,CAEQ,SAAU,CAChB,KAAK,eAAe,EACpB,KAAK,KAAK,SAAU,KAAK,aAAa,CAAC,CACzC,CACQ,gBAAiB,CACvB,KAAK,MAAM,EAAE,QAAQ,CAACT,EAAIY,IAAM,CAC9B,IAAML,EAAK,KAAK,SAAS,IAAI,KAAK,MAAM,MAAMK,CAAC,CAAE,EACjDZ,EAAG,UAAU,OAAO,cAAeO,CAAE,GAChC,KAAK,OAAO,WAAa,YAAc,QAAQP,EAAG,aAAa,gBAAiB,OAAOO,CAAE,CAAC,CACjG,CAAC,CACH,CAGQ,KAAKK,EAAW,EAAiE,CACvF,IAAMF,EAAO,KAAK,OAAO,WAAa,SAChCC,EAAM,KAAK,MAAM,MAAMC,CAAC,EAC9B,GAAI,GAACD,GAAOD,IAAS,QACrB,IAAIA,IAAS,SAAW,EAAE,UAAY,KAAK,QAAU,EAAG,CACtD,KAAK,SAAS,MAAM,EACpB,QAAWD,KAAK,KAAK,MAAM,SAAS,KAAK,IAAI,KAAK,OAAQG,CAAC,EAAG,KAAK,IAAI,KAAK,OAAQA,CAAC,EAAI,CAAC,EAAG,KAAK,SAAS,IAAIH,CAAC,CAClH,MAAWC,IAAS,UAAY,EAAE,SAAW,EAAE,UACxC,KAAK,SAAS,OAAOC,CAAG,GAAG,KAAK,SAAS,IAAIA,CAAG,EACrD,KAAK,OAASC,IAEd,KAAK,SAAS,MAAM,EACpB,KAAK,SAAS,IAAID,CAAG,EACrB,KAAK,OAASC,GAEhB,KAAK,QAAQ,EACf,CAEQ,QAAQI,EAAeI,EAAc,CAC3C,IAAM,EAAI,KAAK,QAAQJ,CAAC,EAClBL,EAAM,KAAK,MAAM,MAAM,CAAC,EAC9B,GAAI,CAACA,EAAK,OACV,IAAMU,EAAUL,EAAE,OAAuB,QAAqB,kBAAkB,EAChF,GAAIK,EAAQ,CACND,IAAS,cAAc,KAAK,KAAK,cAAeC,EAAO,QAAQ,SAAUV,EAAKK,CAAC,EACnF,MACF,CACII,IAAS,eACX,KAAK,UAAU,EAAG,EAAK,EACvB,KAAK,KAAK,EAAGJ,CAAC,GAEhB,KAAK,KAAKI,EAAMT,EAAK,EAAGK,CAAC,CAC3B,CAIQ,UAAUJ,EAAWU,EAAQ,GAAM,CACzC,KAAK,OAASV,EACd,KAAK,MAAM,EAAE,QAAQ,CAACZ,EAAIuB,IAAM,CAC9BvB,EAAG,SAAWuB,IAAMX,EAAI,EAAI,GAC5BZ,EAAG,UAAU,OAAO,YAAauB,IAAMX,CAAC,CAC1C,CAAC,EACGU,GAAO,KAAK,MAAM,EAAEV,CAAC,GAAG,MAAM,EAClC,KAAK,KAAK,gBAAiBA,CAAC,CAC9B,CACA,UAAUA,EAAW,CACnB,KAAK,OAAO,EACZ,KAAK,UAAU,KAAK,IAAI,EAAG,KAAK,IAAIA,EAAG,KAAK,MAAM,MAAQ,CAAC,CAAC,CAAC,CAC/D,CAEQ,MAAMI,EAAkB,CAC9B,IAAMO,EAAI,KAAK,MAAM,MACrB,GAAI,CAACA,EAAG,OACR,IAAMC,EAAO,KAAK,QAAQ,EACpBC,EAAO,KAAK,IAAI,EAAG,KAAK,MAAM,KAAK,GAAG,aAAe,KAAK,IAAI,EAAG,KAAK,MAAM,EAAE,CAAC,GAAG,cAAgB,CAAC,CAAC,GAAK,CAAC,EAC1GC,EAAM,KAAK,OACXC,EAA6B,CACjC,WAAY,KAAK,IAAIJ,EAAI,EAAGG,EAAM,CAAC,EAAG,UAAW,KAAK,IAAI,EAAGA,EAAM,CAAC,EACpE,UAAW,KAAK,IAAIH,EAAI,EAAGG,EAAMF,CAAI,EAAG,QAAS,KAAK,IAAI,EAAGE,EAAMF,CAAI,EACvE,KAAM,EAAG,IAAKD,EAAI,EAAG,SAAU,KAAK,IAAIA,EAAI,EAAGG,EAAMF,EAAOC,CAAI,EAAG,OAAQ,KAAK,IAAI,EAAGC,EAAMF,EAAOC,CAAI,CAC1G,EACMf,EAAO,KAAK,OAAO,WAAa,SAClCM,EAAE,OAAOW,GACXX,EAAE,eAAe,EACjB,KAAK,UAAUW,EAAGX,EAAE,GAAG,CAAC,EACpBN,IAAS,SAAWM,EAAE,SAAU,KAAK,KAAKW,EAAGX,EAAE,GAAG,EAAG,CAAE,SAAU,EAAK,CAAC,EAClEN,IAAS,UAAY,CAACM,EAAE,SAAS,KAAK,KAAKW,EAAGX,EAAE,GAAG,EAAG,CAAC,CAAC,EAC7DN,IAAS,SAAWM,EAAE,UAAY,KAAK,OAAS,IAAG,KAAK,OAASU,IAC5DV,EAAE,MAAQ,KACnBA,EAAE,eAAe,EACjB,KAAK,KAAKU,EAAKhB,IAAS,QAAU,CAAE,QAAS,EAAK,EAAI,CAAC,CAAC,GAC/CM,EAAE,MAAQ,QACnB,KAAK,KAAK,gBAAiB,KAAK,MAAM,MAAMU,CAAG,EAAGA,CAAG,GAC3CV,EAAE,MAAQ,KAAOA,EAAE,MAAQ,OAASA,EAAE,SAAWA,EAAE,UAAYN,IAAS,UAClFM,EAAE,eAAe,EACjB,KAAK,UAAU,EAEnB,CAEmB,WAAY,CAC7B,KAAK,OAAO,QAAQ,CACtB,CACF,EACAY,EAAS,WAAY/B,CAAQ",
6
+ "names": ["DataView", "Component", "c", "el", "h", "Pagination", "Store", "store", "a", "b", "on", "animate", "r", "mode", "rec", "i", "item", "stagger", "t", "e", "els", "target", "opts", "name", "action", "focus", "n", "cols", "rows", "cur", "to", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{c as r}from"./chunk-4EZJ5FKJ.js";import{a as o}from"./chunk-A2NKDOYN.js";import{b as t}from"./chunk-PZSHOSOS.js";import{a as i}from"./chunk-TIPK3SCJ.js";var n=class extends o{baseCls="op-badge";tag="span";textEl;onRender(){let e=this.config;e.dot&&this.el.append(t("span","op-badge__dot",{"aria-hidden":"true"})),e.icon&&this.el.append(r(e.icon)),this.textEl=this.el.appendChild(t("span","op-badge__text")),this.setText(e.text??""),this.setTone(e.tone??"neutral")}setText(e){this.config.text=e,this.rendered&&(this.textEl.textContent=String(e))}setTone(e){this.config.tone=e,this.rendered&&(this.el.className=this.el.className.replace(/\bop-badge--\w+/g,"").trim(),this.el.classList.add(`op-badge--${e}`))}};i("badge",n);export{n as a};
2
+ //# sourceMappingURL=chunk-MB3MU6HR.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/base/badge/badge.ts"],
4
+ "sourcesContent": ["import { Component, type ComponentConfig } from '../../../core/component';\nimport { register } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { iconEl } from '../icon/icon';\n\nexport type Tone = 'neutral' | 'primary' | 'success' | 'warning' | 'danger' | 'info';\nexport interface BadgeConfig extends ComponentConfig {\n text?: string | number;\n tone?: Tone;\n icon?: string;\n /** A small colored dot before the text (a status light). */\n dot?: boolean;\n}\n\n/** A small status label or count: \"Paid\", \"3 new\", \"Beta\". Not interactive (see Chip for that). */\nexport class Badge extends Component<BadgeConfig> {\n protected override baseCls = 'op-badge';\n protected override tag = 'span' as const;\n private textEl!: HTMLElement;\n\n protected override onRender() {\n const c = this.config;\n if (c.dot) this.el.append(h('span', 'op-badge__dot', { 'aria-hidden': 'true' }));\n if (c.icon) this.el.append(iconEl(c.icon));\n this.textEl = this.el.appendChild(h('span', 'op-badge__text'));\n this.setText(c.text ?? '');\n this.setTone(c.tone ?? 'neutral');\n }\n\n setText(text: string | number) {\n this.config.text = text;\n if (this.rendered) this.textEl.textContent = String(text);\n }\n setTone(tone: Tone) {\n this.config.tone = tone;\n if (!this.rendered) return;\n this.el.className = this.el.className.replace(/\\bop-badge--\\w+/g, '').trim();\n this.el.classList.add(`op-badge--${tone}`);\n }\n}\nregister('badge', Badge);\n"],
5
+ "mappings": "gKAeO,IAAMA,EAAN,cAAoBC,CAAuB,CAC7B,QAAU,WACV,IAAM,OACjB,OAEW,UAAW,CAC5B,IAAMC,EAAI,KAAK,OACXA,EAAE,KAAK,KAAK,GAAG,OAAOC,EAAE,OAAQ,gBAAiB,CAAE,cAAe,MAAO,CAAC,CAAC,EAC3ED,EAAE,MAAM,KAAK,GAAG,OAAOE,EAAOF,EAAE,IAAI,CAAC,EACzC,KAAK,OAAS,KAAK,GAAG,YAAYC,EAAE,OAAQ,gBAAgB,CAAC,EAC7D,KAAK,QAAQD,EAAE,MAAQ,EAAE,EACzB,KAAK,QAAQA,EAAE,MAAQ,SAAS,CAClC,CAEA,QAAQG,EAAuB,CAC7B,KAAK,OAAO,KAAOA,EACf,KAAK,WAAU,KAAK,OAAO,YAAc,OAAOA,CAAI,EAC1D,CACA,QAAQC,EAAY,CAClB,KAAK,OAAO,KAAOA,EACd,KAAK,WACV,KAAK,GAAG,UAAY,KAAK,GAAG,UAAU,QAAQ,mBAAoB,EAAE,EAAE,KAAK,EAC3E,KAAK,GAAG,UAAU,IAAI,aAAaA,CAAI,EAAE,EAC3C,CACF,EACAC,EAAS,QAASP,CAAK",
6
+ "names": ["Badge", "Component", "c", "h", "iconEl", "text", "tone", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ var l=class{handlers=new Map;on(e,n){let t=this.handlers.get(e);return t?t.push(n):this.handlers.set(e,[n]),()=>this.off(e,n)}once(e,n){let t=this.on(e,(...a)=>(t(),n(...a)));return t}off(e,n){if(!n)this.handlers.delete(e);else{let t=this.handlers.get(e);t&&this.handlers.set(e,t.filter(a=>a!==n))}}emit(e,...n){let t=!0;for(let a of this.handlers.get(e)??[])a(...n)===!1&&(t=!1);return t}clearListeners(){this.handlers.clear()}};var i={_lang:"en",_currency:"USD",_firstDay:"0",required:"This field is required",minLength:"Enter at least {n} characters",maxLength:"Enter at most {n} characters",pattern:"Invalid format",email:"Enter a valid email address",min:"Must be at least {n}",max:"Must be at most {n}",range:"Must be between {min} and {max}",number:"Enter a valid number",date:"Enter a valid date",loading:"Loading",close:"Close",ok:"OK",cancel:"Cancel",clear:"Clear",collapse:"Collapse",expand:"Expand",empty:"No data",search:"Search",noResults:"No results",results:"{n} results"},c={_lang:"pt-BR",_currency:"BRL",_firstDay:"0",required:"Campo obrigat\xF3rio",minLength:"Informe ao menos {n} caracteres",maxLength:"Informe no m\xE1ximo {n} caracteres",pattern:"Formato inv\xE1lido",email:"Informe um e-mail v\xE1lido",min:"Deve ser no m\xEDnimo {n}",max:"Deve ser no m\xE1ximo {n}",range:"Deve estar entre {min} e {max}",number:"Informe um n\xFAmero v\xE1lido",date:"Informe uma data v\xE1lida",loading:"Carregando",close:"Fechar",ok:"OK",cancel:"Cancelar",clear:"Limpar",collapse:"Recolher",expand:"Expandir",empty:"Sem dados",search:"Pesquisar",noResults:"Nenhum resultado",results:"{n} resultados"},s={en:i,"pt-BR":c},o=i;function m(r){typeof r=="string"?o=s[r]??s[Object.keys(s).find(e=>e.startsWith(r.split("-")[0]))??"en"]:(o={...i,...r},r._lang&&(s[r._lang]=o))}var g=()=>o;function u(r,e){let n=s[r]??={_lang:r};for(let t in e)t in n||(n[t]=e[t])}function h(r,e){let n=o[r]??i[r]??r;return e?n.replace(/\{(\w+)\}/g,(t,a)=>String(e[a]??"")):n}export{l as a,s as b,m as c,g as d,u as e,h as f};
2
+ //# sourceMappingURL=chunk-MW3RWBZ7.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/core/emitter.ts", "../src/core/i18n.ts"],
4
+ "sourcesContent": ["export type Handler = (...args: any[]) => unknown;\n\n/** Minimal observer. A handler that returns `false` makes `emit` return `false` (used by `before-*` events). */\nexport class Emitter {\n private handlers = new Map<string, Handler[]>();\n\n /** Subscribes; returns the unsubscribe function. */\n on(name: string, fn: Handler): () => void {\n const list = this.handlers.get(name);\n if (list) list.push(fn);\n else this.handlers.set(name, [fn]);\n return () => this.off(name, fn);\n }\n\n once(name: string, fn: Handler): () => void {\n const off = this.on(name, (...a) => {\n off();\n return fn(...a);\n });\n return off;\n }\n\n off(name: string, fn?: Handler): void {\n if (!fn) this.handlers.delete(name);\n else {\n const list = this.handlers.get(name);\n if (list) this.handlers.set(name, list.filter((f) => f !== fn));\n }\n }\n\n /** Returns `false` if any handler returned `false` (the event was cancelled). */\n emit(name: string, ...args: unknown[]): boolean {\n let ok = true;\n for (const fn of this.handlers.get(name) ?? []) if (fn(...args) === false) ok = false;\n return ok;\n }\n\n clearListeners(): void {\n this.handlers.clear();\n }\n}\n", "export type Locale = Record<string, string>;\n\n// Messages shared by the core and several components. Component-only keys live with the component (addMessages).\nconst en: Locale = {\n _lang: 'en',\n _currency: 'USD',\n _firstDay: '0',\n required: 'This field is required',\n minLength: 'Enter at least {n} characters',\n maxLength: 'Enter at most {n} characters',\n pattern: 'Invalid format',\n email: 'Enter a valid email address',\n min: 'Must be at least {n}',\n max: 'Must be at most {n}',\n range: 'Must be between {min} and {max}',\n number: 'Enter a valid number',\n date: 'Enter a valid date',\n loading: 'Loading',\n close: 'Close',\n ok: 'OK',\n cancel: 'Cancel',\n clear: 'Clear',\n collapse: 'Collapse',\n expand: 'Expand',\n empty: 'No data',\n search: 'Search',\n noResults: 'No results',\n results: '{n} results',\n};\n\nconst ptBR: Locale = {\n _lang: 'pt-BR',\n _currency: 'BRL',\n _firstDay: '0',\n required: 'Campo obrigat\u00F3rio',\n minLength: 'Informe ao menos {n} caracteres',\n maxLength: 'Informe no m\u00E1ximo {n} caracteres',\n pattern: 'Formato inv\u00E1lido',\n email: 'Informe um e-mail v\u00E1lido',\n min: 'Deve ser no m\u00EDnimo {n}',\n max: 'Deve ser no m\u00E1ximo {n}',\n range: 'Deve estar entre {min} e {max}',\n number: 'Informe um n\u00FAmero v\u00E1lido',\n date: 'Informe uma data v\u00E1lida',\n loading: 'Carregando',\n close: 'Fechar',\n ok: 'OK',\n cancel: 'Cancelar',\n clear: 'Limpar',\n collapse: 'Recolher',\n expand: 'Expandir',\n empty: 'Sem dados',\n search: 'Pesquisar',\n noResults: 'Nenhum resultado',\n results: '{n} resultados',\n};\n\nexport const locales: Record<string, Locale> = { en, 'pt-BR': ptBR };\nlet current: Locale = en;\n\n/** Picks a registered locale by name (`'pt-BR'`, or `'pt'` as a prefix) or merges a custom object over English. */\nexport function setLocale(l: string | Locale): void {\n if (typeof l === 'string') {\n current = locales[l] ?? locales[Object.keys(locales).find((k) => k.startsWith(l.split('-')[0])) ?? 'en'];\n } else {\n current = { ...en, ...l };\n if (l._lang) locales[l._lang] = current;\n }\n}\n\nexport const getLocale = (): Locale => current;\n\n/**\n * Adds messages to a locale (created if missing). Keys already there are kept, so an app's own overrides win.\n * Each component registers its own keys this way, so its messages only ship with it.\n */\nexport function addMessages(lang: string, messages: Locale): void {\n const target = (locales[lang] ??= { _lang: lang });\n for (const k in messages) if (!(k in target)) target[k] = messages[k];\n}\n\n/** Translates a key, replacing `{name}` placeholders. */\nexport function t(key: string, vars?: Record<string, string | number>): string {\n const s = current[key] ?? en[key] ?? key;\n return vars ? s.replace(/\\{(\\w+)\\}/g, (_, k) => String(vars[k] ?? '')) : s;\n}\n"],
5
+ "mappings": "AAGO,IAAMA,EAAN,KAAc,CACX,SAAW,IAAI,IAGvB,GAAGC,EAAcC,EAAyB,CACxC,IAAMC,EAAO,KAAK,SAAS,IAAIF,CAAI,EACnC,OAAIE,EAAMA,EAAK,KAAKD,CAAE,EACjB,KAAK,SAAS,IAAID,EAAM,CAACC,CAAE,CAAC,EAC1B,IAAM,KAAK,IAAID,EAAMC,CAAE,CAChC,CAEA,KAAKD,EAAcC,EAAyB,CAC1C,IAAME,EAAM,KAAK,GAAGH,EAAM,IAAI,KAC5BG,EAAI,EACGF,EAAG,GAAG,CAAC,EACf,EACD,OAAOE,CACT,CAEA,IAAIH,EAAcC,EAAoB,CACpC,GAAI,CAACA,EAAI,KAAK,SAAS,OAAOD,CAAI,MAC7B,CACH,IAAME,EAAO,KAAK,SAAS,IAAIF,CAAI,EAC/BE,GAAM,KAAK,SAAS,IAAIF,EAAME,EAAK,OAAQE,GAAMA,IAAMH,CAAE,CAAC,CAChE,CACF,CAGA,KAAKD,KAAiBK,EAA0B,CAC9C,IAAIC,EAAK,GACT,QAAWL,KAAM,KAAK,SAAS,IAAID,CAAI,GAAK,CAAC,EAAOC,EAAG,GAAGI,CAAI,IAAM,KAAOC,EAAK,IAChF,OAAOA,CACT,CAEA,gBAAuB,CACrB,KAAK,SAAS,MAAM,CACtB,CACF,ECrCA,IAAMC,EAAa,CACjB,MAAO,KACP,UAAW,MACX,UAAW,IACX,SAAU,yBACV,UAAW,gCACX,UAAW,+BACX,QAAS,iBACT,MAAO,8BACP,IAAK,uBACL,IAAK,sBACL,MAAO,kCACP,OAAQ,uBACR,KAAM,qBACN,QAAS,UACT,MAAO,QACP,GAAI,KACJ,OAAQ,SACR,MAAO,QACP,SAAU,WACV,OAAQ,SACR,MAAO,UACP,OAAQ,SACR,UAAW,aACX,QAAS,aACX,EAEMC,EAAe,CACnB,MAAO,QACP,UAAW,MACX,UAAW,IACX,SAAU,uBACV,UAAW,kCACX,UAAW,sCACX,QAAS,sBACT,MAAO,8BACP,IAAK,4BACL,IAAK,4BACL,MAAO,iCACP,OAAQ,iCACR,KAAM,6BACN,QAAS,aACT,MAAO,SACP,GAAI,KACJ,OAAQ,WACR,MAAO,SACP,SAAU,WACV,OAAQ,WACR,MAAO,YACP,OAAQ,YACR,UAAW,mBACX,QAAS,gBACX,EAEaC,EAAkC,CAAE,GAAAF,EAAI,QAASC,CAAK,EAC/DE,EAAkBH,EAGf,SAASI,EAAUC,EAA0B,CAC9C,OAAOA,GAAM,SACfF,EAAUD,EAAQG,CAAC,GAAKH,EAAQ,OAAO,KAAKA,CAAO,EAAE,KAAMI,GAAMA,EAAE,WAAWD,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAK,IAAI,GAEvGF,EAAU,CAAE,GAAGH,EAAI,GAAGK,CAAE,EACpBA,EAAE,QAAOH,EAAQG,EAAE,KAAK,EAAIF,GAEpC,CAEO,IAAMI,EAAY,IAAcJ,EAMhC,SAASK,EAAYC,EAAcC,EAAwB,CAChE,IAAMC,EAAUT,EAAQO,CAAI,IAAM,CAAE,MAAOA,CAAK,EAChD,QAAWH,KAAKI,EAAgBJ,KAAKK,IAASA,EAAOL,CAAC,EAAII,EAASJ,CAAC,EACtE,CAGO,SAASM,EAAEC,EAAaC,EAAgD,CAC7E,IAAMC,EAAIZ,EAAQU,CAAG,GAAKb,EAAGa,CAAG,GAAKA,EACrC,OAAOC,EAAOC,EAAE,QAAQ,aAAc,CAACC,EAAGV,IAAM,OAAOQ,EAAKR,CAAC,GAAK,EAAE,CAAC,EAAIS,CAC3E",
6
+ "names": ["Emitter", "name", "fn", "list", "off", "f", "args", "ok", "en", "ptBR", "locales", "current", "setLocale", "l", "k", "getLocale", "addMessages", "lang", "messages", "target", "t", "key", "vars", "s", "_"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as h}from"./chunk-KLLAY2IM.js";import{a as d}from"./chunk-W3H7GTJY.js";import{c as n}from"./chunk-4EZJ5FKJ.js";import{b as i}from"./chunk-PZSHOSOS.js";import{a as l}from"./chunk-TIPK3SCJ.js";import{e as o,f as s}from"./chunk-MW3RWBZ7.js";o("en",{secretShow:"Show value",secretHide:"Hide value",secretStored:"A value is saved. It cannot be shown again.",secretReplace:"Replace",secretKeep:"Keep current",secretWarnTitle:"Replace the saved value?",secretWarn:"The saved value cannot be displayed and will be discarded as soon as you replace it. Type the new value next; it takes effect when you save."});o("pt-BR",{secretShow:"Mostrar valor",secretHide:"Ocultar valor",secretStored:"H\xE1 um valor salvo. Ele n\xE3o pode ser exibido novamente.",secretReplace:"Substituir",secretKeep:"Manter o atual",secretWarnTitle:"Substituir o valor salvo?",secretWarn:"O valor salvo n\xE3o pode ser exibido e ser\xE1 descartado assim que voc\xEA o substituir. Digite o novo valor em seguida; ele s\xF3 vale quando voc\xEA salvar."});var p="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",a=class extends d{baseCls="op-field op-textfield op-secret";stored=!1;initialStored=!1;replacing=!1;revealed=!1;eyeBtn;replaceBtn;keepBtn;hint;constructor(e={}){super({autocomplete:"new-password",...e,inputType:"password"}),this.stored=this.initialStored=!!e.stored}emptyValue(){return null}isEmpty(e){return!this.stored&&(e==null||e==="")}createControl(){let e=super.createControl(),t=this.input;return t.spellcheck=!1,this.eyeBtn=i("button","op-secret__eye",{type:"button","aria-pressed":"false"}),this.replaceBtn=i("button","op-secret__replace",{type:"button"},s("secretReplace")),this.keepBtn=i("button","op-secret__keep",{type:"button"},s("secretKeep")),this.hint=i("div","op-secret__hint",{id:`${this.id}-hint`},i("span","op-secret__note",{},s("secretStored")),this.keepBtn),this.listen(this.eyeBtn,"mousedown",r=>r.preventDefault()),this.listen(this.eyeBtn,"click",()=>this.setRevealed(!this.revealed)),this.listen(this.replaceBtn,"click",()=>{this.replace()}),this.listen(this.keepBtn,"click",()=>this.keep()),this.listen(t,"click",()=>this.stored&&void this.replace()),this.listen(t,"keydown",r=>{this.stored&&(r.key==="Enter"||r.key===" ")&&(r.preventDefault(),this.replace())}),this.on("blur",()=>this.config.autoHide!==!1&&this.setRevealed(!1)),e.append(this.eyeBtn,this.replaceBtn),i("div","op-secret__box",{},e,this.hint)}onRender(){super.onRender(),this.paint()}isStored(){return this.stored}isReplacing(){return this.replacing}isRevealed(){return this.revealed}setStored(e){this.stored=e,this.replacing=!1,this.revealed=!1,super.setValue(null,!0),this.paint(),this.emit("stored-change",e)}setValue(e,t=!1){if(e===!0)return this.setStored(!0);e===!1&&(e=null),this.stored&&e!=null&&(this.stored=!1,this.replacing=!0),super.setValue(e,t),this.paint()}markClean(){super.markClean(),this.initialStored=this.stored}reset(){this.setStored(this.initialStored),super.reset()}async replace(){return!this.stored||this.config.readonly||this.config.disabled||this.emit("before-replace")===!1||this.config.confirmReplace!==!1&&!await h.confirm(this.config.replaceText??s("secretWarn"),{danger:!0,title:this.config.replaceTitle??s("secretWarnTitle"),okText:s("secretReplace")})?!1:(this.stored=!1,this.replacing=!0,super.setValue("",!1),this.paint(),this.input.focus(),this.emit("replace"),!0)}keep(){this.replacing&&(this.stored=!0,this.replacing=!1,this.revealed=!1,super.setValue(null,!1),this.paint(),this.emit("keep"))}setRevealed(e){this.stored&&(e=!1),this.revealed=e,this.paint()}getDisplayText(){return this.stored||(this.value??"")!==""?p:""}paint(){if(!this.rendered)return;let e=this.input,t=this.revealed&&!this.stored;e.type=t?"text":"password",e.readOnly=this.stored||!!this.config.readonly,e.placeholder=this.stored?p:this.config.placeholder??"",this.stored&&(e.value=""),e.setAttribute("aria-describedby",this.stored||this.replacing?this.hint.id:""),!this.stored&&!this.replacing&&e.removeAttribute("aria-describedby"),this.eyeBtn.hidden=this.stored,this.eyeBtn.setAttribute("aria-pressed",String(t)),this.eyeBtn.setAttribute("aria-label",s(t?"secretHide":"secretShow")),this.eyeBtn.replaceChildren(n(t?"eye-off":"eye")),this.replaceBtn.hidden=!this.stored,this.hint.hidden=!this.stored&&!this.replacing,this.hint.querySelector(".op-secret__note").hidden=!this.stored,this.keepBtn.hidden=!this.replacing,this.el.classList.toggle("is-stored",this.stored),this.el.classList.toggle("is-replacing",this.replacing),this.el.classList.toggle("is-revealed",t),this.el.classList.toggle("has-value",this.stored||!!e.value)}};l("secretfield",a);export{a};
2
+ //# sourceMappingURL=chunk-NXSTUFS7.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/fields/secretfield/secretfield.ts"],
4
+ "sourcesContent": ["import { TextField, type TextFieldConfig } from '../textfield/textfield';\nimport { register } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { t, addMessages } from '../../../core/i18n';\nimport { iconEl } from '../../base/icon/icon';\nimport { MessageBox } from '../../overlays/messagebox/messagebox';\n\naddMessages('en', {\n secretShow: 'Show value',\n secretHide: 'Hide value',\n secretStored: 'A value is saved. It cannot be shown again.',\n secretReplace: 'Replace',\n secretKeep: 'Keep current',\n secretWarnTitle: 'Replace the saved value?',\n secretWarn: 'The saved value cannot be displayed and will be discarded as soon as you replace it. Type the new value next; it takes effect when you save.',\n});\naddMessages('pt-BR', {\n secretShow: 'Mostrar valor',\n secretHide: 'Ocultar valor',\n secretStored: 'H\u00E1 um valor salvo. Ele n\u00E3o pode ser exibido novamente.',\n secretReplace: 'Substituir',\n secretKeep: 'Manter o atual',\n secretWarnTitle: 'Substituir o valor salvo?',\n secretWarn: 'O valor salvo n\u00E3o pode ser exibido e ser\u00E1 descartado assim que voc\u00EA o substituir. Digite o novo valor em seguida; ele s\u00F3 vale quando voc\u00EA salvar.',\n});\n\nexport interface SecretFieldConfig extends TextFieldConfig<string | null> {\n /** A secret is already saved. It can never be shown; it can only be replaced. `form.load({ key: true })` sets it too. */\n stored?: boolean;\n /** Ask before replacing a saved secret. Default true. */\n confirmReplace?: boolean;\n replaceTitle?: string;\n replaceText?: string;\n /** The eye hides the value again when the field loses focus. Default true. */\n autoHide?: boolean;\n}\n\nconst MASK = '\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022';\n\n/**\n * A field for secrets. While you type you can peek at what you typed (the eye); once a secret is saved it is shown only as a\n * mask and can never be read back: to change it you replace it, after a warning. `getValue()` is `null` while untouched\n * (keep what is saved), the new text once typed, `''` when replaced and left empty.\n */\nexport class SecretField extends TextField<string | null, SecretFieldConfig> {\n protected override baseCls = 'op-field op-textfield op-secret';\n private stored = false;\n private initialStored = false;\n private replacing = false;\n private revealed = false;\n private eyeBtn!: HTMLButtonElement;\n private replaceBtn!: HTMLButtonElement;\n private keepBtn!: HTMLButtonElement;\n private hint!: HTMLElement;\n\n constructor(config: SecretFieldConfig = {}) {\n super({ autocomplete: 'new-password', ...config, inputType: 'password' });\n this.stored = this.initialStored = !!config.stored;\n }\n\n protected override emptyValue(): string | null {\n return null;\n }\n /** A saved secret that was not touched counts as filled in (so `required` is satisfied). */\n protected override isEmpty(v: string | null) {\n return !this.stored && (v == null || v === '');\n }\n\n protected override createControl() {\n const wrap = super.createControl();\n const input = this.input;\n input.spellcheck = false;\n this.eyeBtn = h('button', 'op-secret__eye', { type: 'button', 'aria-pressed': 'false' });\n this.replaceBtn = h('button', 'op-secret__replace', { type: 'button' }, t('secretReplace'));\n this.keepBtn = h('button', 'op-secret__keep', { type: 'button' }, t('secretKeep'));\n this.hint = h('div', 'op-secret__hint', { id: `${this.id}-hint` }, h('span', 'op-secret__note', {}, t('secretStored')), this.keepBtn);\n this.listen(this.eyeBtn, 'mousedown', (e: Event) => e.preventDefault()); // keep the focus in the input (it would hide the value)\n this.listen(this.eyeBtn, 'click', () => this.setRevealed(!this.revealed));\n this.listen(this.replaceBtn, 'click', () => void this.replace());\n this.listen(this.keepBtn, 'click', () => this.keep());\n // a saved secret is opened for replacement by clicking or pressing a key in the (read-only) field\n this.listen(input, 'click', () => this.stored && void this.replace());\n this.listen(input, 'keydown', (e: KeyboardEvent) => {\n if (this.stored && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n void this.replace();\n }\n });\n this.on('blur', () => this.config.autoHide !== false && this.setRevealed(false));\n wrap.append(this.eyeBtn, this.replaceBtn);\n return h('div', 'op-secret__box', {}, wrap, this.hint);\n }\n\n protected override onRender() {\n super.onRender();\n this.paint();\n }\n\n // ---- state ---------------------------------------------------------------------------------\n\n isStored(): boolean {\n return this.stored;\n }\n /** The user chose to replace a saved secret and has not finished. */\n isReplacing(): boolean {\n return this.replacing;\n }\n isRevealed(): boolean {\n return this.revealed;\n }\n\n /** Says whether a secret is saved (a saved secret is never given to the field, only the fact that it exists). */\n setStored(stored: boolean): void {\n this.stored = stored;\n this.replacing = false;\n this.revealed = false;\n super.setValue(null, true);\n this.paint();\n this.emit('stored-change', stored);\n }\n\n /** `true` (what `form.load` passes for \"a secret exists\") means saved; a string is a new value typed or set by code. */\n override setValue(v: string | boolean | null, silent = false): void {\n if (v === true) return this.setStored(true);\n if (v === false) v = null;\n if (this.stored && v != null) {\n this.stored = false;\n this.replacing = true;\n }\n super.setValue(v, silent);\n this.paint();\n }\n\n override markClean(): void {\n super.markClean();\n this.initialStored = this.stored;\n }\n /** Back to what was loaded: the saved secret, untouched. */\n override reset(): void {\n this.setStored(this.initialStored);\n super.reset();\n }\n\n /** Warns, then turns a saved secret into an empty field to type the new value in. Resolves to whether it was replaced. */\n async replace(): Promise<boolean> {\n if (!this.stored || this.config.readonly || this.config.disabled || this.emit('before-replace') === false) return false;\n if (this.config.confirmReplace !== false) {\n const ok = await MessageBox.confirm(this.config.replaceText ?? t('secretWarn'), { danger: true, title: this.config.replaceTitle ?? t('secretWarnTitle'), okText: t('secretReplace') });\n if (!ok) return false;\n }\n this.stored = false;\n this.replacing = true;\n super.setValue('', false);\n this.paint();\n this.input.focus();\n this.emit('replace');\n return true;\n }\n\n /** Gives up replacing: the saved secret stays as it was. */\n keep(): void {\n if (!this.replacing) return;\n this.stored = true;\n this.replacing = false;\n this.revealed = false;\n super.setValue(null, false);\n this.paint();\n this.emit('keep');\n }\n\n setRevealed(on: boolean): void {\n if (this.stored) on = false; // there is nothing to see\n this.revealed = on;\n this.paint();\n }\n\n /** Never reveals: a mask when there is something, nothing otherwise. */\n override getDisplayText(): string {\n return this.stored || (this.value ?? '') !== '' ? MASK : '';\n }\n\n // ---- view ----------------------------------------------------------------------------------\n\n private paint(): void {\n if (!this.rendered) return;\n const input = this.input as HTMLInputElement;\n const on = this.revealed && !this.stored;\n input.type = on ? 'text' : 'password';\n input.readOnly = this.stored || !!this.config.readonly;\n input.placeholder = this.stored ? MASK : (this.config.placeholder ?? '');\n if (this.stored) input.value = '';\n input.setAttribute('aria-describedby', this.stored || this.replacing ? this.hint.id : '');\n if (!this.stored && !this.replacing) input.removeAttribute('aria-describedby');\n this.eyeBtn.hidden = this.stored;\n this.eyeBtn.setAttribute('aria-pressed', String(on));\n this.eyeBtn.setAttribute('aria-label', t(on ? 'secretHide' : 'secretShow'));\n this.eyeBtn.replaceChildren(iconEl(on ? 'eye-off' : 'eye'));\n this.replaceBtn.hidden = !this.stored;\n this.hint.hidden = !this.stored && !this.replacing;\n (this.hint.querySelector('.op-secret__note') as HTMLElement).hidden = !this.stored;\n this.keepBtn.hidden = !this.replacing;\n this.el.classList.toggle('is-stored', this.stored);\n this.el.classList.toggle('is-replacing', this.replacing);\n this.el.classList.toggle('is-revealed', on);\n this.el.classList.toggle('has-value', this.stored || !!input.value);\n }\n}\nregister('secretfield', SecretField);\n"],
5
+ "mappings": "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",
6
+ "names": ["addMessages", "MASK", "SecretField", "TextField", "config", "v", "wrap", "input", "h", "t", "e", "stored", "silent", "MessageBox", "on", "iconEl", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as p}from"./chunk-MW3RWBZ7.js";var y=0;function f(r,i){return r==null||!i?.type?r:i.type==="number"?r===""?null:Number(r):i.type==="boolean"?r==="false"?!1:!!r:String(r)}var d=class{constructor(i={},e={}){this.def=e;let t={...i};for(let s in e.fields){let o=e.fields[s];t[s]=f(t[s]===void 0?o.default:t[s],o)}this.data=t,this.phantom=this.data[e.idField??"id"]===void 0}def;data;phantom;owner;clientId=`c${++y}`;original={};get id(){return this.data[this.def.idField??"id"]??this.clientId}get(i){return this.data[i]}set(i,e){let t=f(e,this.def.fields?.[i]);this.data[i]!==t&&(i in this.original||(this.original[i]=this.data[i]),this.data[i]=t,this.owner?.recordChanged(this,i))}isDirty(){return Object.keys(this.original).length>0}getChanges(){let i={};for(let e in this.original)i[e]=this.data[e];return i}commit(){this.original={},this.phantom=!1}reject(){Object.assign(this.data,this.original),this.original={}}};var v,T=(r,i)=>r==null?i==null?0:1:i==null?-1:typeof r=="string"&&typeof i=="string"?(v??=new Intl.Collator(void 0,{numeric:!0})).compare(r,i):r<i?-1:r>i?1:0,l=r=>String(r??"").toLowerCase(),c=r=>r==null||r===""||Array.isArray(r)&&!r.length,b=/^\d{4}-\d{2}-\d{2}(T[\d:.]+Z?)?$/,n=r=>r instanceof Date?r.getTime():typeof r=="string"&&b.test(r)?Date.parse(r):r;function w(r,i){let e=r.value,t=n(i),s=()=>!c(i)&&t>=n(e[0])&&t<=n(e[1]),o=()=>e.some(a=>n(a)==t);switch(r.op??"eq"){case"eq":return t==n(e);case"ne":return t!=n(e);case"contains":return l(i).includes(l(e));case"notContains":return!l(i).includes(l(e));case"startsWith":return l(i).startsWith(l(e));case"endsWith":return l(i).endsWith(l(e));case"gt":return t>n(e);case"ge":return t>=n(e);case"lt":return t<n(e);case"le":return t<=n(e);case"between":return s();case"notBetween":return!s();case"in":return o();case"nin":return!o();case"empty":return c(i);case"notEmpty":return!c(i)}}function u(r,i){return"filters"in r?r.filters.length?r.op==="or"?r.filters.some(e=>u(e,i)):r.filters.every(e=>u(e,i)):!0:w(r,i[r.field])}var g=class extends p{constructor(e={}){super();this.cfg=e;this.sorters=e.sorters??[],this.pageLen=e.pageSize??0;for(let t in e.listeners)this.on(t,e.listeners[t]);e.proxy&&(this.proxy=typeof e.proxy=="function"?{read:e.proxy}:e.proxy),e.data&&this.setRecords(e.data.map(t=>this.wrap(t)),e.data.length),e.autoLoad&&this.proxy&&this.load()}cfg;all=[];rows=[];visible=[];removed=[];sorters;filters=[];params={};proxy;pageNo=1;pageLen;total=0;abort;loading=!1;get remote(){return!!this.cfg.remote&&!!this.proxy}wrap(e){let t=e instanceof d?e:new d(e,this.cfg.model);return t.owner=this,t}fire(e,...t){this.emit(e,...t),this.emit("change",{type:e})}get count(){return this.visible.length}get totalCount(){return this.remote?this.total:this.rows.length}getFiltered(){return this.rows}getAt(e){return this.visible[e]}getRange(e=0,t=this.visible.length){return this.visible.slice(e,t)}getById(e){return this.all.find(t=>t.id===e)}indexOf(e){return this.visible.indexOf(e)}getData(){return this.visible.map(e=>e.data)}each(e){this.visible.forEach(e)}loadData(e){this.removed=[],this.setRecords(e.map(t=>this.wrap(t)),e.length),this.fire("load")}async load(e){if(!this.proxy)throw new Error("Optikos Store: load() needs a proxy");e&&(this.params=e);let t={...this.params};if(this.remote&&Object.assign(t,{page:this.pageNo,pageSize:this.pageLen||void 0,sorters:this.sorters,filters:this.filters.filter(o=>typeof o!="function")}),this.emit("before-load",t)===!1)return;this.abort?.abort();let s=this.abort=new AbortController;this.loading=!0,this.emit("loading",!0);try{let o=await this.proxy.read(t,s.signal);if(s.signal.aborted)return;let{data:a,total:h}=Array.isArray(o)?{data:o,total:o.length}:o;this.removed=[],this.setRecords(a.map(m=>this.wrap(m)),h??a.length),this.loading=!1,this.emit("loading",!1),this.fire("load")}catch(o){if(s.signal.aborted)return;this.loading=!1,this.emit("loading",!1),this.emit("load-error",o)}}setRecords(e,t){this.all=e,this.total=t,this.refreshView()}refreshView(){if(this.remote){this.rows=this.visible=this.all;return}let e=this.all;this.filters.length&&(e=e.filter(s=>this.filters.every(o=>typeof o=="function"?o(s):u(o,s.data)))),this.sorters.length&&(e=[...e].sort((s,o)=>{for(let a of this.sorters){let h=T(s.data[a.field],o.data[a.field]);if(h)return a.dir==="desc"?-h:h}return 0})),this.rows=e;let t=this.pageCount;this.pageNo>t&&(this.pageNo=t),this.visible=this.pageLen?e.slice((this.pageNo-1)*this.pageLen,this.pageNo*this.pageLen):e}getSorters(){return this.sorters}sort(e,t){let s=this.sorters[0];this.sorters=e?[{field:e,dir:t??(s?.field===e&&s.dir==="asc"?"desc":"asc")}]:[],this.pageNo=1,this.changeView("sort")}filter(e){return this.filters=Array.isArray(e)?e:[e],this.pageNo=1,this.changeView("filter")}clearFilter(){return this.filters=[],this.pageNo=1,this.changeView("filter")}getFilters(){return this.filters.filter(e=>typeof e!="function")}changeView(e){return this.remote?this.load():(this.refreshView(),this.fire(e),Promise.resolve())}get page(){return this.pageNo}get pageSize(){return this.pageLen}get pageCount(){return this.pageLen?Math.max(1,Math.ceil(this.totalCount/this.pageLen)):1}setPage(e){e=Math.min(Math.max(1,e),this.pageCount),e!==this.pageNo&&(this.pageNo=e,this.remote?this.load():(this.refreshView(),this.fire("page")))}setPageSize(e){this.pageLen=e,this.pageNo=1,this.changeView("page")}add(e){let t=(Array.isArray(e)?e:[e]).map(s=>this.wrap(s));return this.all=[...this.all,...t],this.total+=t.length,this.refreshView(),this.fire("add",t),t}insert(e,t){let s=this.wrap(t);return this.all=[...this.all.slice(0,e),s,...this.all.slice(e)],this.total++,this.refreshView(),this.fire("add",[s]),s}remove(e){let s=(Array.isArray(e)?e:[typeof e=="number"?this.visible[e]:e]).filter(o=>o&&this.all.includes(o));s.length&&(this.all=this.all.filter(o=>!s.includes(o)),this.removed.push(...s.filter(o=>!o.phantom)),this.total-=s.length,this.refreshView(),this.fire("remove",s))}clear(){this.removed.push(...this.all.filter(e=>!e.phantom)),this.setRecords([],0),this.fire("remove",[])}recordChanged(e,t){(this.sorters.some(s=>s.field===t)||this.filters.length)&&this.refreshView(),this.fire("update",e,t)}getModified(){return this.all.filter(e=>e.phantom||e.isDirty())}getRemoved(){return this.removed}commitChanges(){this.all.forEach(e=>e.commit()),this.removed=[]}async sync(){let e=this.proxy;if(!e)throw new Error("Optikos Store: sync() needs a proxy");for(let t of this.removed)await e.destroy?.(t.data);this.removed=[];for(let t of this.all){if(t.phantom)Object.assign(t.data,await e.create?.(t.data)??{});else if(t.isDirty())Object.assign(t.data,await e.update?.(t.data)??{});else continue;t.commit()}this.fire("sync")}subscribe(e){return this.on("change",e)}};export{d as a,u as b,g as c};
2
+ //# sourceMappingURL=chunk-OEAXCCVM.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/data/model.ts", "../src/data/store.ts"],
4
+ "sourcesContent": ["export interface FieldDef {\n type?: 'string' | 'number' | 'boolean';\n default?: unknown;\n}\nexport interface ModelDef {\n idField?: string;\n fields?: Record<string, FieldDef>;\n}\n\nexport interface RecordOwner {\n recordChanged(rec: Model, field: string): void;\n}\n\nlet cid = 0;\n\nfunction convert(v: unknown, def?: FieldDef): unknown {\n if (v == null || !def?.type) return v;\n if (def.type === 'number') return v === '' ? null : Number(v);\n if (def.type === 'boolean') return v === 'false' ? false : Boolean(v);\n return String(v);\n}\n\n/** One record. `data` holds the values; `set` tracks the original value of each changed field. */\nexport class Model<T extends Record<string, any> = Record<string, any>> {\n data: T;\n phantom: boolean;\n owner?: RecordOwner;\n private readonly clientId = `c${++cid}`;\n private original: Partial<T> = {};\n\n constructor(raw: Partial<T> = {}, private def: ModelDef = {}) {\n const data: Record<string, unknown> = { ...raw };\n for (const f in def.fields) {\n const fd = def.fields[f];\n data[f] = convert(data[f] === undefined ? fd.default : data[f], fd);\n }\n this.data = data as T;\n this.phantom = this.data[def.idField ?? 'id'] === undefined;\n }\n\n get id(): string | number {\n return this.data[this.def.idField ?? 'id'] ?? this.clientId;\n }\n\n get<K extends keyof T>(field: K): T[K] {\n return this.data[field];\n }\n\n set<K extends keyof T>(field: K, value: T[K]): void {\n const v = convert(value, this.def.fields?.[field as string]) as T[K];\n if (this.data[field] === v) return;\n if (!(field in this.original)) this.original[field] = this.data[field];\n this.data[field] = v;\n this.owner?.recordChanged(this as Model, field as string);\n }\n\n isDirty(): boolean {\n return Object.keys(this.original).length > 0;\n }\n getChanges(): Partial<T> {\n const out: Partial<T> = {};\n for (const k in this.original) out[k] = this.data[k];\n return out;\n }\n commit(): void {\n this.original = {};\n this.phantom = false;\n }\n reject(): void {\n Object.assign(this.data, this.original);\n this.original = {};\n }\n}\n", "import { Emitter } from '../core/emitter';\nimport { Model, type ModelDef, type RecordOwner } from './model';\nimport type { FilterNode, FilterSpec, Proxy, ReadParams, ReadResult, Sorter } from './proxy';\n\nexport type StoreProxy<T> = Proxy<T> | ((params: ReadParams, signal?: AbortSignal) => Promise<ReadResult<T> | T[]> | ReadResult<T> | T[]);\nexport type FilterFn<T extends Record<string, any>> = (rec: Model<T>) => boolean;\n\nexport interface StoreConfig<T extends Record<string, any>> {\n data?: Partial<T>[];\n model?: ModelDef;\n proxy?: StoreProxy<T>;\n /** 0 = no paging. */\n pageSize?: number;\n /** Sort, filter and paging are done by the proxy (it receives them in `read`). Default false: done locally. */\n remote?: boolean;\n sorters?: Sorter[];\n autoLoad?: boolean;\n listeners?: Record<string, (...a: any[]) => unknown>;\n}\n\n// One collator, made on first use: `localeCompare` with options builds a new one per call (100k rows: 5.4 s \u2192 0.4 s).\nlet collator: Intl.Collator | undefined;\nconst cmp = (a: any, b: any) => (a == null ? (b == null ? 0 : 1) : b == null ? -1 : typeof a === 'string' && typeof b === 'string' ? (collator ??= new Intl.Collator(undefined, { numeric: true })).compare(a, b) : a < b ? -1 : a > b ? 1 : 0);\n\nconst text = (v: any) => String(v ?? '').toLowerCase();\nconst empty = (v: any) => v == null || v === '' || (Array.isArray(v) && !v.length);\nconst ISO = /^\\d{4}-\\d{2}-\\d{2}(T[\\d:.]+Z?)?$/;\n/** Dates (Date objects or ISO strings) compare by time; anything else compares as is. */\nconst num = (v: any) => (v instanceof Date ? v.getTime() : typeof v === 'string' && ISO.test(v) ? Date.parse(v) : v);\n\nfunction test(spec: FilterSpec, raw: any): boolean {\n const x = spec.value as any;\n const v = num(raw);\n const between = () => !empty(raw) && v >= num(x[0]) && v <= num(x[1]);\n const listed = () => (x as unknown[]).some((i) => num(i) == v);\n switch (spec.op ?? 'eq') {\n case 'eq': return v == num(x);\n case 'ne': return v != num(x);\n case 'contains': return text(raw).includes(text(x));\n case 'notContains': return !text(raw).includes(text(x));\n case 'startsWith': return text(raw).startsWith(text(x));\n case 'endsWith': return text(raw).endsWith(text(x));\n case 'gt': return v > num(x);\n case 'ge': return v >= num(x);\n case 'lt': return v < num(x);\n case 'le': return v <= num(x);\n case 'between': return between();\n case 'notBetween': return !between();\n case 'in': return listed();\n case 'nin': return !listed();\n case 'empty': return empty(raw);\n case 'notEmpty': return !empty(raw);\n }\n}\n\n/** Does a record's data satisfy a filter node? Groups are AND/OR; an empty group matches everything. */\nexport function matchFilter(node: FilterNode, data: Record<string, any>): boolean {\n if ('filters' in node) {\n if (!node.filters.length) return true;\n return node.op === 'or' ? node.filters.some((f) => matchFilter(f, data)) : node.filters.every((f) => matchFilter(f, data));\n }\n return test(node, data[node.field]);\n}\n\n/**\n * Records + a view over them (filtered, sorted, paged). Events: `load`, `before-load`, `load-error`, `add`, `remove`,\n * `update`, `sort`, `filter`, `page`, `sync`, and `change` for any of them (payload `{ type }`).\n */\nexport class Store<T extends Record<string, any> = Record<string, any>> extends Emitter implements RecordOwner {\n private all: Model<T>[] = [];\n private rows: Model<T>[] = [];\n private visible: Model<T>[] = [];\n private removed: Model<T>[] = [];\n private sorters: Sorter[];\n private filters: Array<FilterNode | FilterFn<T>> = [];\n private params: Record<string, unknown> = {};\n private proxy?: Proxy<T>;\n private pageNo = 1;\n private pageLen: number;\n private total = 0;\n private abort?: AbortController;\n loading = false;\n\n constructor(private cfg: StoreConfig<T> = {}) {\n super();\n this.sorters = cfg.sorters ?? [];\n this.pageLen = cfg.pageSize ?? 0;\n for (const k in cfg.listeners) this.on(k, cfg.listeners[k]);\n if (cfg.proxy) this.proxy = typeof cfg.proxy === 'function' ? { read: cfg.proxy } : cfg.proxy;\n if (cfg.data) this.setRecords(cfg.data.map((r) => this.wrap(r)), cfg.data.length);\n if (cfg.autoLoad && this.proxy) void this.load();\n }\n\n private get remote() {\n return !!this.cfg.remote && !!this.proxy;\n }\n private wrap(raw: Partial<T> | Model<T>): Model<T> {\n const m = raw instanceof Model ? raw : new Model<T>(raw, this.cfg.model);\n m.owner = this;\n return m;\n }\n private fire(type: string, ...args: unknown[]) {\n this.emit(type, ...args);\n this.emit('change', { type });\n }\n\n // ---- reading -------------------------------------------------------------------------------\n\n /** Number of records in the current view (the current page). */\n get count(): number {\n return this.visible.length;\n }\n /** Records matching the filters, across pages (remote: what the server reported). */\n get totalCount(): number {\n return this.remote ? this.total : this.rows.length;\n }\n /** Every record matching the filters, across pages (a remote store only knows the loaded page). */\n getFiltered(): Model<T>[] {\n return this.rows;\n }\n getAt(i: number): Model<T> | undefined {\n return this.visible[i];\n }\n getRange(start = 0, end = this.visible.length): Model<T>[] {\n return this.visible.slice(start, end);\n }\n getById(id: string | number): Model<T> | undefined {\n return this.all.find((r) => r.id === id);\n }\n indexOf(rec: Model<T>): number {\n return this.visible.indexOf(rec);\n }\n /** Plain data of the current view. */\n getData(): T[] {\n return this.visible.map((r) => r.data);\n }\n each(fn: (rec: Model<T>, i: number) => void): void {\n this.visible.forEach(fn);\n }\n\n // ---- loading -------------------------------------------------------------------------------\n\n /** Replaces all records with local data. */\n loadData(data: Partial<T>[]): void {\n this.removed = [];\n this.setRecords(data.map((r) => this.wrap(r)), data.length);\n this.fire('load');\n }\n\n /** Reads through the proxy. Extra `params` are sent to it and remembered for later reloads. A newer load cancels the older one. */\n async load(params?: Record<string, unknown>): Promise<void> {\n if (!this.proxy) throw new Error('Optikos Store: load() needs a proxy');\n if (params) this.params = params;\n const req: ReadParams = { ...this.params };\n if (this.remote) Object.assign(req, { page: this.pageNo, pageSize: this.pageLen || undefined, sorters: this.sorters, filters: this.filters.filter((f): f is FilterNode => typeof f !== 'function') });\n if (this.emit('before-load', req) === false) return;\n this.abort?.abort();\n const ctl = (this.abort = new AbortController());\n this.loading = true;\n this.emit('loading', true);\n try {\n const res = await this.proxy.read(req, ctl.signal);\n if (ctl.signal.aborted) return;\n const { data, total } = Array.isArray(res) ? { data: res, total: res.length } : res;\n this.removed = [];\n this.setRecords(data.map((r) => this.wrap(r)), total ?? data.length);\n this.loading = false;\n this.emit('loading', false);\n this.fire('load');\n } catch (err) {\n if (ctl.signal.aborted) return;\n this.loading = false;\n this.emit('loading', false);\n this.emit('load-error', err);\n }\n }\n\n private setRecords(recs: Model<T>[], total: number) {\n this.all = recs;\n this.total = total;\n this.refreshView();\n }\n\n /** Recomputes filtered/sorted/paged rows from `all`. */\n private refreshView() {\n if (this.remote) {\n this.rows = this.visible = this.all;\n return;\n }\n let rows = this.all;\n if (this.filters.length) rows = rows.filter((r) => this.filters.every((f) => (typeof f === 'function' ? f(r) : matchFilter(f, r.data))));\n if (this.sorters.length) {\n rows = [...rows].sort((a, b) => {\n for (const s of this.sorters) {\n const d = cmp(a.data[s.field], b.data[s.field]);\n if (d) return s.dir === 'desc' ? -d : d;\n }\n return 0;\n });\n }\n this.rows = rows;\n const pages = this.pageCount;\n if (this.pageNo > pages) this.pageNo = pages;\n this.visible = this.pageLen ? rows.slice((this.pageNo - 1) * this.pageLen, this.pageNo * this.pageLen) : rows;\n }\n\n // ---- sort / filter / paging ----------------------------------------------------------------\n\n getSorters(): Sorter[] {\n return this.sorters;\n }\n /** `sort('name')` toggles asc/desc when already sorted by it; `sort('name', 'desc')` is explicit; `sort(null)` clears. */\n sort(field: string | null, dir?: 'asc' | 'desc'): void {\n const cur = this.sorters[0];\n this.sorters = field ? [{ field, dir: dir ?? (cur?.field === field && cur.dir === 'asc' ? 'desc' : 'asc') }] : [];\n this.pageNo = 1;\n this.changeView('sort');\n }\n\n /**\n * Replaces the filters (top level = AND). Accepts specs, groups (`{ op: 'or', filters }`), or a predicate.\n * Resolves when the view is up to date (for a remote store, after the reload).\n */\n filter(f: FilterNode | FilterNode[] | FilterFn<T>): Promise<void> {\n this.filters = Array.isArray(f) ? f : [f];\n this.pageNo = 1;\n return this.changeView('filter');\n }\n clearFilter(): Promise<void> {\n this.filters = [];\n this.pageNo = 1;\n return this.changeView('filter');\n }\n /** The active filter nodes (predicates are not included). */\n getFilters(): FilterNode[] {\n return this.filters.filter((f): f is FilterNode => typeof f !== 'function');\n }\n\n private changeView(type: string): Promise<void> {\n if (this.remote) return this.load();\n this.refreshView();\n this.fire(type);\n return Promise.resolve();\n }\n\n get page(): number {\n return this.pageNo;\n }\n get pageSize(): number {\n return this.pageLen;\n }\n get pageCount(): number {\n return this.pageLen ? Math.max(1, Math.ceil(this.totalCount / this.pageLen)) : 1;\n }\n setPage(n: number): void {\n n = Math.min(Math.max(1, n), this.pageCount);\n if (n === this.pageNo) return;\n this.pageNo = n;\n if (this.remote) void this.load();\n else {\n this.refreshView();\n this.fire('page');\n }\n }\n setPageSize(n: number): void {\n this.pageLen = n;\n this.pageNo = 1;\n this.changeView('page');\n }\n\n // ---- editing -------------------------------------------------------------------------------\n\n add(raw: Partial<T> | Partial<T>[]): Model<T>[] {\n const recs = (Array.isArray(raw) ? raw : [raw]).map((r) => this.wrap(r));\n this.all = [...this.all, ...recs];\n this.total += recs.length;\n this.refreshView();\n this.fire('add', recs);\n return recs;\n }\n\n insert(index: number, raw: Partial<T>): Model<T> {\n const rec = this.wrap(raw);\n this.all = [...this.all.slice(0, index), rec, ...this.all.slice(index)];\n this.total++;\n this.refreshView();\n this.fire('add', [rec]);\n return rec;\n }\n\n remove(target: Model<T> | number | Array<Model<T>>): void {\n const list = Array.isArray(target) ? target : [typeof target === 'number' ? this.visible[target] : target];\n const gone = list.filter((r) => r && this.all.includes(r));\n if (!gone.length) return;\n this.all = this.all.filter((r) => !gone.includes(r));\n this.removed.push(...gone.filter((r) => !r.phantom));\n this.total -= gone.length;\n this.refreshView();\n this.fire('remove', gone);\n }\n\n clear(): void {\n this.removed.push(...this.all.filter((r) => !r.phantom));\n this.setRecords([], 0);\n this.fire('remove', []);\n }\n\n recordChanged(rec: Model, field: string): void {\n if (this.sorters.some((s) => s.field === field) || this.filters.length) this.refreshView();\n this.fire('update', rec, field);\n }\n\n getModified(): Model<T>[] {\n return this.all.filter((r) => r.phantom || r.isDirty());\n }\n getRemoved(): Model<T>[] {\n return this.removed;\n }\n commitChanges(): void {\n this.all.forEach((r) => r.commit());\n this.removed = [];\n }\n\n /** Writes pending changes through the proxy: deletes, then creates and updates, one at a time. */\n async sync(): Promise<void> {\n const p = this.proxy;\n if (!p) throw new Error('Optikos Store: sync() needs a proxy');\n for (const r of this.removed) await p.destroy?.(r.data);\n this.removed = [];\n for (const r of this.all) {\n if (r.phantom) Object.assign(r.data, (await p.create?.(r.data)) ?? {});\n else if (r.isDirty()) Object.assign(r.data, (await p.update?.(r.data)) ?? {});\n else continue;\n r.commit();\n }\n this.fire('sync');\n }\n\n /** Observable interface used by `optikos/bind`: calls `fn` on any change; returns the unsubscribe function. */\n subscribe(fn: (change: { type: string }) => void): () => void {\n return this.on('change', fn);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["cid", "convert", "v", "def", "Model", "raw", "data", "f", "fd", "field", "value", "out", "k", "collator", "cmp", "a", "b", "text", "v", "empty", "ISO", "num", "test", "spec", "raw", "x", "between", "listed", "i", "matchFilter", "node", "data", "f", "Store", "Emitter", "cfg", "k", "r", "m", "Model", "type", "args", "start", "end", "id", "rec", "fn", "params", "req", "ctl", "res", "total", "err", "recs", "rows", "s", "d", "pages", "field", "dir", "cur", "n", "index", "target", "gone", "p"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as l}from"./chunk-2ZRNGG2N.js";import{c as n}from"./chunk-4EZJ5FKJ.js";import{b as o}from"./chunk-PZSHOSOS.js";import{a as r}from"./chunk-TIPK3SCJ.js";var p=class extends l{baseCls="op-field op-checkboxgroup";group;inputs=[];emptyValue(){return[]}isEmpty(e){return!e?.length}isEqual(e,t){return(e??[]).length===(t??[]).length&&(e??[]).every((i,s)=>i===t[s])}createControl(){return this.group=o("div","op-checkboxgroup__options",{role:"group","aria-labelledby":`${this.id}-label`}),this.listen(this.group,"change",e=>{if(!this.inputs.includes(e.target))return;if(this.config.readonly)return this.applyValue(this.value);let t=this.opts();this.commit(this.inputs.flatMap((i,s)=>i.checked?[t[s].value]:[])),this.paint()}),this.buildOptions(),this.inputEl=this.inputs[0]??this.group,this.group}opts(){return(this.config.options??[]).map(e=>typeof e=="object"?e:{value:e,label:e,disabled:!1})}buildOptions(){this.inputs=[],this.group.replaceChildren(...this.opts().map(e=>{let t=o("input","op-checkbox__input",{type:"checkbox",value:String(e.value),disabled:!!e.disabled});return this.inputs.push(t),o("label","op-checkbox op-checkbox__label",{},t,o("span","op-checkbox__box",{},n("check")),o("span","op-checkbox__text",{},e.label))})),this.group.classList.toggle("op-checkboxgroup__options--horizontal",this.config.direction==="horizontal")}onRender(){super.onRender(),this.el.querySelector(".op-field__label").id=`${this.id}-label`}applyValue(e){let t=this.opts();this.inputs.forEach((i,s)=>i.checked=(e??[]).includes(t[s].value)),this.paint()}paint(){for(let e of this.inputs)e.closest("label").classList.toggle("is-checked",e.checked)}getDisplayText(){let e=this.getValue()??[];return this.opts().filter(t=>e.includes(t.value)).map(t=>t.label).join(", ")}onDisabled(e){this.inputs.forEach((t,i)=>t.disabled=e||!!this.opts()[i].disabled)}setOptions(e){this.config.options=e,this.rendered&&(this.buildOptions(),this.inputEl=this.inputs[0]??this.group,this.applyValue(this.value),this.onDisabled(!!this.config.disabled))}};r("checkboxgroup",p);export{p as a};
2
+ //# sourceMappingURL=chunk-OGRFQTXA.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/fields/checkboxgroup/checkboxgroup.ts"],
4
+ "sourcesContent": ["import { Field, type FieldConfig } from '../../../core/field';\nimport { register } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { iconEl } from '../../base/icon/icon';\nimport type { RadioOption } from '../radiogroup/radiogroup';\n\ntype Value = string | number;\nexport interface CheckboxGroupConfig extends FieldConfig<Value[]> {\n options?: RadioOption[];\n direction?: 'vertical' | 'horizontal';\n}\n\n/** Several choices from a few visible options; the value is the list of checked option values, in option order. */\nexport class CheckboxGroup extends Field<Value[], CheckboxGroupConfig> {\n protected override baseCls = 'op-field op-checkboxgroup';\n private group!: HTMLElement;\n private inputs: HTMLInputElement[] = [];\n\n protected override emptyValue(): Value[] {\n return [];\n }\n /** `required` means \"at least one\". */\n protected override isEmpty(v: Value[]) {\n return !v?.length;\n }\n protected override isEqual(a: Value[], b: Value[]) {\n return (a ?? []).length === (b ?? []).length && (a ?? []).every((x, i) => x === b[i]);\n }\n\n protected createControl() {\n this.group = h('div', 'op-checkboxgroup__options', { role: 'group', 'aria-labelledby': `${this.id}-label` });\n this.listen(this.group, 'change', (e: Event) => {\n if (!this.inputs.includes(e.target as HTMLInputElement)) return;\n if (this.config.readonly) return this.applyValue(this.value);\n const opts = this.opts();\n this.commit(this.inputs.flatMap((input, i) => (input.checked ? [opts[i].value] : [])));\n this.paint();\n });\n this.buildOptions();\n this.inputEl = this.inputs[0] ?? this.group;\n return this.group;\n }\n\n private opts() {\n return (this.config.options ?? []).map((o) => (typeof o === 'object' ? o : { value: o, label: o, disabled: false }));\n }\n\n private buildOptions() {\n this.inputs = [];\n this.group.replaceChildren(\n ...this.opts().map((o) => {\n const input = h('input', 'op-checkbox__input', { type: 'checkbox', value: String(o.value), disabled: !!o.disabled });\n this.inputs.push(input);\n // each option reuses the Checkbox look (`op-checkbox` + `is-checked` on the label)\n return h('label', 'op-checkbox op-checkbox__label', {}, input, h('span', 'op-checkbox__box', {}, iconEl('check')), h('span', 'op-checkbox__text', {}, o.label));\n }),\n );\n this.group.classList.toggle('op-checkboxgroup__options--horizontal', this.config.direction === 'horizontal');\n }\n\n protected override onRender() {\n super.onRender();\n (this.el.querySelector('.op-field__label') as HTMLElement).id = `${this.id}-label`;\n }\n\n protected applyValue(v: Value[]) {\n const opts = this.opts();\n this.inputs.forEach((input, i) => (input.checked = (v ?? []).includes(opts[i].value)));\n this.paint();\n }\n\n private paint() {\n for (const input of this.inputs) input.closest('label')!.classList.toggle('is-checked', input.checked);\n }\n\n override getDisplayText(): string {\n const v = this.getValue() ?? [];\n return this.opts().filter((o) => v.includes(o.value)).map((o) => o.label).join(', ');\n }\n\n protected override onDisabled(disabled: boolean) {\n this.inputs.forEach((i, n) => (i.disabled = disabled || !!this.opts()[n].disabled));\n }\n\n setOptions(options: RadioOption[]) {\n this.config.options = options;\n if (!this.rendered) return;\n this.buildOptions();\n this.inputEl = this.inputs[0] ?? this.group;\n this.applyValue(this.value);\n this.onDisabled(!!this.config.disabled);\n }\n}\nregister('checkboxgroup', CheckboxGroup);\n"],
5
+ "mappings": "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",
6
+ "names": ["CheckboxGroup", "Field", "v", "a", "b", "x", "i", "h", "opts", "input", "o", "iconEl", "disabled", "n", "options", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{b as a}from"./chunk-PZSHOSOS.js";function b(e){let u=e.overscan??6,{count:o,rowHeight:t}=e,p=a("div","op-virtual");e.scroller.appendChild(p);let s=[],h=[];function i(l=!1){p.style.height=`${o*t}px`;let c=e.scroller.clientHeight||400,n=Math.min(o,Math.ceil(c/t)+u*2+1);if(n!==s.length){for(;s.length>n;)s.pop().remove();for(;s.length<n;){let r=a("div",e.rowCls??"op-virtual__row");r.style.cssText="position:absolute;inset-inline:0;top:0",s.push(r),p.appendChild(r)}h.length=0,l=!0}let f=Math.max(0,Math.min(Math.floor(e.scroller.scrollTop/t)-u,o-n));for(let r=f;r<f+n;r++){let m=r%n;if(!l&&h[m]===r)continue;h[m]=r;let d=s[m];d.style.transform=`translateY(${r*t}px)`,d.style.height=`${t}px`,e.render(d,r)}}let v=()=>i();return e.scroller.addEventListener("scroll",v,{passive:!0}),i(!0),{spacer:p,rows:s,refresh:()=>i(!0),setCount(l){o=l,i(!0)},setRowHeight(l){t=l,i(!0)},scrollTo(l){let c=l*t,n=e.scroller.clientHeight||400;c<e.scroller.scrollTop?e.scroller.scrollTop=c:c+t>e.scroller.scrollTop+n&&(e.scroller.scrollTop=c+t-n),i()},destroy(){e.scroller.removeEventListener("scroll",v),p.remove()}}}function w(e,u){let o=a("div");o.style.cssText=`position:absolute;visibility:hidden;pointer-events:none;block-size:${u}`,e.appendChild(o);let t=o.offsetHeight;return o.remove(),t}export{b as a,w as b};
2
+ //# sourceMappingURL=chunk-OWEQT2HN.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/core/virtual.ts"],
4
+ "sourcesContent": ["import { h } from './dom';\n\nexport interface VirtualOptions {\n /** Scrolling element. */\n scroller: HTMLElement;\n count: number;\n rowHeight: number;\n /** Extra rows rendered above/below the viewport. Default 6. */\n overscan?: number;\n /** Fills a pooled row element with the data of row `index`. */\n render(row: HTMLElement, index: number): void;\n rowCls?: string;\n}\n\n/** Fixed-height virtual list: only the visible rows exist in the DOM, reused as a pool. */\nexport function virtualize(o: VirtualOptions) {\n const overscan = o.overscan ?? 6;\n let { count, rowHeight } = o;\n const spacer = h('div', 'op-virtual');\n o.scroller.appendChild(spacer);\n const pool: HTMLElement[] = [];\n const assigned: number[] = [];\n\n function update(force = false) {\n spacer.style.height = `${count * rowHeight}px`;\n const viewH = o.scroller.clientHeight || 400;\n const need = Math.min(count, Math.ceil(viewH / rowHeight) + overscan * 2 + 1);\n if (need !== pool.length) {\n while (pool.length > need) pool.pop()!.remove();\n while (pool.length < need) {\n const row = h('div', o.rowCls ?? 'op-virtual__row');\n // rows are positioned by transform inside the spacer, whatever class the caller gives them\n row.style.cssText = 'position:absolute;inset-inline:0;top:0';\n pool.push(row);\n spacer.appendChild(row);\n }\n assigned.length = 0;\n force = true;\n }\n const first = Math.max(0, Math.min(Math.floor(o.scroller.scrollTop / rowHeight) - overscan, count - need));\n for (let i = first; i < first + need; i++) {\n const slot = i % need;\n if (!force && assigned[slot] === i) continue;\n assigned[slot] = i;\n const row = pool[slot];\n row.style.transform = `translateY(${i * rowHeight}px)`;\n row.style.height = `${rowHeight}px`;\n o.render(row, i);\n }\n }\n\n const onScroll = () => update();\n o.scroller.addEventListener('scroll', onScroll, { passive: true });\n update(true);\n\n return {\n spacer,\n /** Rows currently in the DOM. */\n rows: pool,\n refresh: () => update(true),\n setCount(n: number) {\n count = n;\n update(true);\n },\n setRowHeight(px: number) {\n rowHeight = px;\n update(true);\n },\n scrollTo(index: number) {\n const top = index * rowHeight;\n const viewH = o.scroller.clientHeight || 400;\n if (top < o.scroller.scrollTop) o.scroller.scrollTop = top;\n else if (top + rowHeight > o.scroller.scrollTop + viewH) o.scroller.scrollTop = top + rowHeight - viewH;\n update();\n },\n destroy() {\n o.scroller.removeEventListener('scroll', onScroll);\n spacer.remove();\n },\n };\n}\n\n/** Resolves a CSS length (usually a token expression like `var(--op-row-height)`) to pixels in the context of `el`. Returns 0 when not laid out. */\nexport function measure(el: HTMLElement, length: string): number {\n const probe = h('div');\n probe.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;block-size:${length}`;\n el.appendChild(probe);\n const n = probe.offsetHeight;\n probe.remove();\n return n;\n}\n"],
5
+ "mappings": "wCAeO,SAASA,EAAWC,EAAmB,CAC5C,IAAMC,EAAWD,EAAE,UAAY,EAC3B,CAAE,MAAAE,EAAO,UAAAC,CAAU,EAAIH,EACrBI,EAASC,EAAE,MAAO,YAAY,EACpCL,EAAE,SAAS,YAAYI,CAAM,EAC7B,IAAME,EAAsB,CAAC,EACvBC,EAAqB,CAAC,EAE5B,SAASC,EAAOC,EAAQ,GAAO,CAC7BL,EAAO,MAAM,OAAS,GAAGF,EAAQC,CAAS,KAC1C,IAAMO,EAAQV,EAAE,SAAS,cAAgB,IACnCW,EAAO,KAAK,IAAIT,EAAO,KAAK,KAAKQ,EAAQP,CAAS,EAAIF,EAAW,EAAI,CAAC,EAC5E,GAAIU,IAASL,EAAK,OAAQ,CACxB,KAAOA,EAAK,OAASK,GAAML,EAAK,IAAI,EAAG,OAAO,EAC9C,KAAOA,EAAK,OAASK,GAAM,CACzB,IAAMC,EAAMP,EAAE,MAAOL,EAAE,QAAU,iBAAiB,EAElDY,EAAI,MAAM,QAAU,yCACpBN,EAAK,KAAKM,CAAG,EACbR,EAAO,YAAYQ,CAAG,CACxB,CACAL,EAAS,OAAS,EAClBE,EAAQ,EACV,CACA,IAAMI,EAAQ,KAAK,IAAI,EAAG,KAAK,IAAI,KAAK,MAAMb,EAAE,SAAS,UAAYG,CAAS,EAAIF,EAAUC,EAAQS,CAAI,CAAC,EACzG,QAASG,EAAID,EAAOC,EAAID,EAAQF,EAAMG,IAAK,CACzC,IAAMC,EAAOD,EAAIH,EACjB,GAAI,CAACF,GAASF,EAASQ,CAAI,IAAMD,EAAG,SACpCP,EAASQ,CAAI,EAAID,EACjB,IAAMF,EAAMN,EAAKS,CAAI,EACrBH,EAAI,MAAM,UAAY,cAAcE,EAAIX,CAAS,MACjDS,EAAI,MAAM,OAAS,GAAGT,CAAS,KAC/BH,EAAE,OAAOY,EAAKE,CAAC,CACjB,CACF,CAEA,IAAME,EAAW,IAAMR,EAAO,EAC9B,OAAAR,EAAE,SAAS,iBAAiB,SAAUgB,EAAU,CAAE,QAAS,EAAK,CAAC,EACjER,EAAO,EAAI,EAEJ,CACL,OAAAJ,EAEA,KAAME,EACN,QAAS,IAAME,EAAO,EAAI,EAC1B,SAASS,EAAW,CAClBf,EAAQe,EACRT,EAAO,EAAI,CACb,EACA,aAAaU,EAAY,CACvBf,EAAYe,EACZV,EAAO,EAAI,CACb,EACA,SAASW,EAAe,CACtB,IAAMC,EAAMD,EAAQhB,EACdO,EAAQV,EAAE,SAAS,cAAgB,IACrCoB,EAAMpB,EAAE,SAAS,UAAWA,EAAE,SAAS,UAAYoB,EAC9CA,EAAMjB,EAAYH,EAAE,SAAS,UAAYU,IAAOV,EAAE,SAAS,UAAYoB,EAAMjB,EAAYO,GAClGF,EAAO,CACT,EACA,SAAU,CACRR,EAAE,SAAS,oBAAoB,SAAUgB,CAAQ,EACjDZ,EAAO,OAAO,CAChB,CACF,CACF,CAGO,SAASiB,EAAQC,EAAiBC,EAAwB,CAC/D,IAAMC,EAAQnB,EAAE,KAAK,EACrBmB,EAAM,MAAM,QAAU,sEAAsED,CAAM,GAClGD,EAAG,YAAYE,CAAK,EACpB,IAAMP,EAAIO,EAAM,aAChB,OAAAA,EAAM,OAAO,EACNP,CACT",
6
+ "names": ["virtualize", "o", "overscan", "count", "rowHeight", "spacer", "h", "pool", "assigned", "update", "force", "viewH", "need", "row", "first", "i", "slot", "onScroll", "n", "px", "index", "top", "measure", "el", "length", "probe"]
7
+ }
@@ -0,0 +1,2 @@
1
+ function s(e,t){for(let n in t){let r=t[n];r==null||r===!1?e.removeAttribute(n):e.setAttribute(n,r===!0?"":String(r))}}function u(e,t="",n,...r){let i=document.createElement(e);t&&(i.className=t),n&&s(i,n);for(let o of r)o!=null&&o!==!1&&i.append(typeof o=="number"?String(o):o);return i}var l=0,m=(e="op")=>`${e}-${++l}`,p=e=>e.replace(/[A-Z]/g,t=>"-"+t.toLowerCase()),a=e=>typeof e=="number"?`${e}px`:e,f=(e,t,n)=>Math.min(Math.max(e,t),n);export{s as a,u as b,m as c,p as d,a as e,f};
2
+ //# sourceMappingURL=chunk-PZSHOSOS.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/core/dom.ts"],
4
+ "sourcesContent": ["export type Child = Node | string | number | null | undefined | false;\nexport type Attrs = Record<string, string | number | boolean | null | undefined>;\n\n/** Sets attributes; `null`, `undefined` and `false` remove, `true` sets an empty attribute. */\nexport function attr(el: Element, attrs: Attrs): void {\n for (const k in attrs) {\n const v = attrs[k];\n if (v == null || v === false) el.removeAttribute(k);\n else el.setAttribute(k, v === true ? '' : String(v));\n }\n}\n\n/** Tiny element factory: `h('button', 'op-button', { type: 'button' }, 'Save')`. */\nexport function h<K extends keyof HTMLElementTagNameMap>(tag: K, cls = '', attrs?: Attrs, ...kids: Child[]): HTMLElementTagNameMap[K] {\n const el = document.createElement(tag);\n if (cls) el.className = cls;\n if (attrs) attr(el, attrs);\n for (const k of kids) if (k != null && k !== false) el.append(typeof k === 'number' ? String(k) : k);\n return el;\n}\n\nlet seq = 0;\nexport const uid = (prefix = 'op'): string => `${prefix}-${++seq}`;\nexport const kebab = (s: string): string => s.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase());\nexport const px = (v: number | string): string => (typeof v === 'number' ? `${v}px` : v);\nexport const clamp = (n: number, min: number, max: number): number => Math.min(Math.max(n, min), max);\nexport const isEl = (v: unknown): v is HTMLElement => typeof HTMLElement !== 'undefined' && v instanceof HTMLElement;\n"],
5
+ "mappings": "AAIO,SAASA,EAAKC,EAAaC,EAAoB,CACpD,QAAWC,KAAKD,EAAO,CACrB,IAAME,EAAIF,EAAMC,CAAC,EACbC,GAAK,MAAQA,IAAM,GAAOH,EAAG,gBAAgBE,CAAC,EAC7CF,EAAG,aAAaE,EAAGC,IAAM,GAAO,GAAK,OAAOA,CAAC,CAAC,CACrD,CACF,CAGO,SAASC,EAAyCC,EAAQC,EAAM,GAAIL,KAAkBM,EAAyC,CACpI,IAAMP,EAAK,SAAS,cAAcK,CAAG,EACjCC,IAAKN,EAAG,UAAYM,GACpBL,GAAOF,EAAKC,EAAIC,CAAK,EACzB,QAAWC,KAAKK,EAAUL,GAAK,MAAQA,IAAM,IAAOF,EAAG,OAAO,OAAOE,GAAM,SAAW,OAAOA,CAAC,EAAIA,CAAC,EACnG,OAAOF,CACT,CAEA,IAAIQ,EAAM,EACGC,EAAM,CAACC,EAAS,OAAiB,GAAGA,CAAM,IAAI,EAAEF,CAAG,GACnDG,EAASC,GAAsBA,EAAE,QAAQ,SAAWC,GAAM,IAAMA,EAAE,YAAY,CAAC,EAC/EC,EAAMX,GAAgC,OAAOA,GAAM,SAAW,GAAGA,CAAC,KAAOA,EACzEY,EAAQ,CAACC,EAAWC,EAAaC,IAAwB,KAAK,IAAI,KAAK,IAAIF,EAAGC,CAAG,EAAGC,CAAG",
6
+ "names": ["attr", "el", "attrs", "k", "v", "h", "tag", "cls", "kids", "seq", "uid", "prefix", "kebab", "s", "m", "px", "clamp", "n", "min", "max"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{c as r}from"./chunk-ZWNQREWS.js";import{c as d}from"./chunk-4EZJ5FKJ.js";import{b as i,c as o}from"./chunk-PZSHOSOS.js";import{a as n}from"./chunk-TIPK3SCJ.js";import{f as l}from"./chunk-MW3RWBZ7.js";var s=class extends r{baseCls="op-fieldset";tag="fieldset";legend;bodyEl;toggleBtn;descEl;getBody(){return this.bodyEl}build(){let e=super.build();return this.legend=i("legend","op-fieldset__legend"),this.descEl=i("p","op-fieldset__desc",{id:o("op-fs-desc")}),this.bodyEl=i("div","op-fieldset__body"),e.append(this.legend,this.descEl,this.bodyEl),e}onRender(){this.config.layout??=this.config.columns?{type:"grid",columns:this.config.columns}:{type:"vbox"},super.onRender(),this.setVariant(this.config.variant??"box"),this.setDescription(this.config.description??""),this.config.collapsible&&(this.toggleBtn=i("button","op-fieldset__toggle",{type:"button"},d("chevron-up")),this.listen(this.toggleBtn,"click",()=>this.toggle()),this.legend.prepend(this.toggleBtn)),this.setTitle(this.config.title??""),this.setCollapsed(!!this.config.collapsed)}setTitle(e){if(this.config.title=e,!this.rendered)return;let t=this.legend.querySelector(".op-fieldset__title");t||(this.legend.append(t=i("span","op-fieldset__title")),this.config.collapsible&&this.listen(t,"click",()=>this.toggle())),t.textContent=e,this.legend.hidden=!e&&!this.config.collapsible}setDescription(e){this.config.description=e,this.rendered&&(this.descEl.textContent=e,this.descEl.hidden=!e,e?this.el.setAttribute("aria-describedby",this.descEl.id):this.el.removeAttribute("aria-describedby"))}setVariant(e){if(this.config.variant=e,!!this.rendered)for(let t of["box","line","plain"])this.el.classList.toggle(`op-fieldset--${t}`,t===e)}setCollapsed(e){this.config.collapsed=e,this.rendered&&(this.el.classList.toggle("is-collapsed",e),this.bodyEl.hidden=e,e?this.descEl.hidden=!0:this.descEl.hidden=!this.config.description,this.toggleBtn?.setAttribute("aria-expanded",String(!e)),this.toggleBtn?.setAttribute("aria-label",l(e?"expand":"collapse")))}collapse(){this.config.collapsed||this.emit("before-collapse")===!1||(this.setCollapsed(!0),this.emit("collapse"))}expand(){!this.config.collapsed||this.emit("before-expand")===!1||(this.setCollapsed(!1),this.emit("expand"))}toggle(){this.config.collapsed?this.expand():this.collapse()}};n("fieldset",s);export{s as a};
2
+ //# sourceMappingURL=chunk-REW4LR46.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/layout/fieldset/fieldset.ts"],
4
+ "sourcesContent": ["import { Container, type ContainerConfig } from '../../../core/container';\nimport { register } from '../../../core/registry';\nimport { h, uid } from '../../../core/dom';\nimport { t } from '../../../core/i18n';\nimport { iconEl } from '../../base/icon/icon';\n\nexport interface FieldSetConfig extends ContainerConfig {\n title?: string;\n /** A line under the legend, read as the group's description. */\n description?: string;\n /** `box` (a framed group, default), `line` (a rule under the legend, no frame) or `plain` (just the legend). */\n variant?: 'box' | 'line' | 'plain';\n /** Shortcut for a responsive grid layout; items take `colspan` (a number or `'full'`). */\n columns?: number;\n collapsible?: boolean;\n collapsed?: boolean;\n}\n\nexport class FieldSet extends Container<FieldSetConfig> {\n protected override baseCls = 'op-fieldset';\n protected override tag = 'fieldset' as const;\n private legend!: HTMLElement;\n private bodyEl!: HTMLElement;\n private toggleBtn?: HTMLButtonElement;\n private descEl!: HTMLElement;\n\n override getBody() {\n return this.bodyEl;\n }\n\n protected override build() {\n const el = super.build();\n this.legend = h('legend', 'op-fieldset__legend');\n this.descEl = h('p', 'op-fieldset__desc', { id: uid('op-fs-desc') });\n this.bodyEl = h('div', 'op-fieldset__body');\n el.append(this.legend, this.descEl, this.bodyEl);\n return el;\n }\n\n protected override onRender() {\n this.config.layout ??= this.config.columns ? { type: 'grid', columns: this.config.columns } : { type: 'vbox' };\n super.onRender();\n this.setVariant(this.config.variant ?? 'box');\n this.setDescription(this.config.description ?? '');\n if (this.config.collapsible) {\n this.toggleBtn = h('button', 'op-fieldset__toggle', { type: 'button' }, iconEl('chevron-up'));\n this.listen(this.toggleBtn, 'click', () => this.toggle());\n this.legend.prepend(this.toggleBtn);\n }\n this.setTitle(this.config.title ?? '');\n this.setCollapsed(!!this.config.collapsed);\n }\n\n setTitle(title: string) {\n this.config.title = title;\n if (!this.rendered) return;\n let text = this.legend.querySelector('.op-fieldset__title');\n if (!text) {\n this.legend.append((text = h('span', 'op-fieldset__title')));\n if (this.config.collapsible) this.listen(text, 'click', () => this.toggle()); // the title toggles too (the chevron is the button)\n }\n text.textContent = title;\n this.legend.hidden = !title && !this.config.collapsible;\n }\n\n setDescription(text: string) {\n this.config.description = text;\n if (!this.rendered) return;\n this.descEl.textContent = text;\n this.descEl.hidden = !text;\n if (text) this.el.setAttribute('aria-describedby', this.descEl.id);\n else this.el.removeAttribute('aria-describedby');\n }\n\n setVariant(variant: 'box' | 'line' | 'plain') {\n this.config.variant = variant;\n if (!this.rendered) return;\n for (const v of ['box', 'line', 'plain']) this.el.classList.toggle(`op-fieldset--${v}`, v === variant);\n }\n\n setCollapsed(collapsed: boolean) {\n this.config.collapsed = collapsed;\n if (!this.rendered) return;\n this.el.classList.toggle('is-collapsed', collapsed);\n this.bodyEl.hidden = collapsed;\n if (collapsed) this.descEl.hidden = true;\n else this.descEl.hidden = !this.config.description;\n this.toggleBtn?.setAttribute('aria-expanded', String(!collapsed));\n this.toggleBtn?.setAttribute('aria-label', t(collapsed ? 'expand' : 'collapse'));\n }\n collapse() {\n if (this.config.collapsed || this.emit('before-collapse') === false) return;\n this.setCollapsed(true);\n this.emit('collapse');\n }\n expand() {\n if (!this.config.collapsed || this.emit('before-expand') === false) return;\n this.setCollapsed(false);\n this.emit('expand');\n }\n toggle() {\n if (this.config.collapsed) this.expand();\n else this.collapse();\n }\n}\nregister('fieldset', FieldSet);\n"],
5
+ "mappings": "+MAkBO,IAAMA,EAAN,cAAuBC,CAA0B,CACnC,QAAU,cACV,IAAM,WACjB,OACA,OACA,UACA,OAEC,SAAU,CACjB,OAAO,KAAK,MACd,CAEmB,OAAQ,CACzB,IAAMC,EAAK,MAAM,MAAM,EACvB,YAAK,OAASC,EAAE,SAAU,qBAAqB,EAC/C,KAAK,OAASA,EAAE,IAAK,oBAAqB,CAAE,GAAIC,EAAI,YAAY,CAAE,CAAC,EACnE,KAAK,OAASD,EAAE,MAAO,mBAAmB,EAC1CD,EAAG,OAAO,KAAK,OAAQ,KAAK,OAAQ,KAAK,MAAM,EACxCA,CACT,CAEmB,UAAW,CAC5B,KAAK,OAAO,SAAW,KAAK,OAAO,QAAU,CAAE,KAAM,OAAQ,QAAS,KAAK,OAAO,OAAQ,EAAI,CAAE,KAAM,MAAO,EAC7G,MAAM,SAAS,EACf,KAAK,WAAW,KAAK,OAAO,SAAW,KAAK,EAC5C,KAAK,eAAe,KAAK,OAAO,aAAe,EAAE,EAC7C,KAAK,OAAO,cACd,KAAK,UAAYC,EAAE,SAAU,sBAAuB,CAAE,KAAM,QAAS,EAAGE,EAAO,YAAY,CAAC,EAC5F,KAAK,OAAO,KAAK,UAAW,QAAS,IAAM,KAAK,OAAO,CAAC,EACxD,KAAK,OAAO,QAAQ,KAAK,SAAS,GAEpC,KAAK,SAAS,KAAK,OAAO,OAAS,EAAE,EACrC,KAAK,aAAa,CAAC,CAAC,KAAK,OAAO,SAAS,CAC3C,CAEA,SAASC,EAAe,CAEtB,GADA,KAAK,OAAO,MAAQA,EAChB,CAAC,KAAK,SAAU,OACpB,IAAIC,EAAO,KAAK,OAAO,cAAc,qBAAqB,EACrDA,IACH,KAAK,OAAO,OAAQA,EAAOJ,EAAE,OAAQ,oBAAoB,CAAE,EACvD,KAAK,OAAO,aAAa,KAAK,OAAOI,EAAM,QAAS,IAAM,KAAK,OAAO,CAAC,GAE7EA,EAAK,YAAcD,EACnB,KAAK,OAAO,OAAS,CAACA,GAAS,CAAC,KAAK,OAAO,WAC9C,CAEA,eAAeC,EAAc,CAC3B,KAAK,OAAO,YAAcA,EACrB,KAAK,WACV,KAAK,OAAO,YAAcA,EAC1B,KAAK,OAAO,OAAS,CAACA,EAClBA,EAAM,KAAK,GAAG,aAAa,mBAAoB,KAAK,OAAO,EAAE,EAC5D,KAAK,GAAG,gBAAgB,kBAAkB,EACjD,CAEA,WAAWC,EAAmC,CAE5C,GADA,KAAK,OAAO,QAAUA,EAClB,EAAC,KAAK,SACV,QAAWC,IAAK,CAAC,MAAO,OAAQ,OAAO,EAAG,KAAK,GAAG,UAAU,OAAO,gBAAgBA,CAAC,GAAIA,IAAMD,CAAO,CACvG,CAEA,aAAaE,EAAoB,CAC/B,KAAK,OAAO,UAAYA,EACnB,KAAK,WACV,KAAK,GAAG,UAAU,OAAO,eAAgBA,CAAS,EAClD,KAAK,OAAO,OAASA,EACjBA,EAAW,KAAK,OAAO,OAAS,GAC/B,KAAK,OAAO,OAAS,CAAC,KAAK,OAAO,YACvC,KAAK,WAAW,aAAa,gBAAiB,OAAO,CAACA,CAAS,CAAC,EAChE,KAAK,WAAW,aAAa,aAAcC,EAAED,EAAY,SAAW,UAAU,CAAC,EACjF,CACA,UAAW,CACL,KAAK,OAAO,WAAa,KAAK,KAAK,iBAAiB,IAAM,KAC9D,KAAK,aAAa,EAAI,EACtB,KAAK,KAAK,UAAU,EACtB,CACA,QAAS,CACH,CAAC,KAAK,OAAO,WAAa,KAAK,KAAK,eAAe,IAAM,KAC7D,KAAK,aAAa,EAAK,EACvB,KAAK,KAAK,QAAQ,EACpB,CACA,QAAS,CACH,KAAK,OAAO,UAAW,KAAK,OAAO,EAClC,KAAK,SAAS,CACrB,CACF,EACAE,EAAS,WAAYZ,CAAQ",
6
+ "names": ["FieldSet", "Container", "el", "h", "uid", "iconEl", "title", "text", "variant", "v", "collapsed", "t", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{c as n}from"./chunk-ZWNQREWS.js";import{a as d}from"./chunk-2ZRNGG2N.js";import{b as r,c as o}from"./chunk-PZSHOSOS.js";import{a as s}from"./chunk-TIPK3SCJ.js";var l=class extends n{baseCls="op-field op-fieldgroup";labelEl;bodyEl;helpEl;errorEl;error="";constructor(e={}){super(e);for(let t of this.items)t.config.width!=null&&t.config.flex==null&&(t.config.flex="none");for(let t of this.getFields()){t.config.labelPos="top";for(let i of["invalid","valid"])t.on(i,()=>this.paintError())}}getBody(){return this.bodyEl}getFields(){return this.query(e=>e instanceof d)}getError(){return this.error}build(){let e=super.build();return this.labelEl=r("div","op-field__label",{id:o("op-fg")}),this.bodyEl=r("div","op-fieldgroup__body"),this.helpEl=r("div","op-field__help",{id:o("op-fg-help")}),this.errorEl=r("div","op-field__error",{id:o("op-fg-err"),role:"alert"}),e.append(this.labelEl,r("div","op-field__control",{},this.bodyEl),this.helpEl,this.errorEl),e.setAttribute("role","group"),e.setAttribute("aria-labelledby",this.labelEl.id),e}onRender(){let e=this.config;e.layout??={type:"hbox",stackBelow:e.stackBelow},super.onRender();let t=e.labelPos;for(let i=this.parent;!t&&i;i=i.parent)t=i.config.labelPos;this.el.classList.toggle("op-field--label-left",t==="left"),this.setLabel(e.label??""),this.setHelp(e.help??""),this.el.classList.toggle("is-required",!!e.required||this.getFields().some(i=>i.config.required)),this.listen(this.labelEl,"click",()=>this.getFields()[0]?.focus()),this.error="",this.paintError()}paintError(){let e=this.getFields().map(t=>t.getError()).find(Boolean)??"";e!==this.error&&(this.error=e,this.rendered&&(this.errorEl.textContent=e,this.el.classList.toggle("is-invalid",!!e),this.describe(),this.emit(e?"invalid":"valid",e)))}describe(){let e=[this.error&&this.errorEl.id,this.config.help&&this.helpEl.id].filter(Boolean);e.length?this.el.setAttribute("aria-describedby",e.join(" ")):this.el.removeAttribute("aria-describedby")}setLabel(e){this.config.label=e,this.rendered&&(this.labelEl.textContent=e,this.labelEl.hidden=!e)}setHelp(e){this.config.help=e,this.rendered&&(this.helpEl.textContent=e,this.helpEl.hidden=!e,this.describe())}};s("fieldgroup",l);export{l as a};
2
+ //# sourceMappingURL=chunk-RNN55473.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/form/fieldgroup/fieldgroup.ts"],
4
+ "sourcesContent": ["import { Container, type ContainerConfig } from '../../../core/container';\nimport { Field } from '../../../core/field';\nimport { register } from '../../../core/registry';\nimport { h, uid } from '../../../core/dom';\nimport type { Component } from '../../../core/component';\n\nexport interface FieldGroupConfig extends ContainerConfig {\n label?: string;\n help?: string;\n /** The `*` marker (also shown when any field inside is required). */\n required?: boolean;\n /** Default: the form's `labelPos`. */\n labelPos?: 'top' | 'left';\n /** Under this width (px) the row becomes a column. */\n stackBelow?: number;\n}\n\n/** Several inputs read as one field: one label, one help line and one error line over a row of fields. */\nexport class FieldGroup extends Container<FieldGroupConfig> {\n protected override baseCls = 'op-field op-fieldgroup';\n private labelEl!: HTMLElement;\n private bodyEl!: HTMLElement;\n private helpEl!: HTMLElement;\n private errorEl!: HTMLElement;\n private error = '';\n\n constructor(config: FieldGroupConfig = {}) {\n super(config);\n // the fields keep their labels for screen readers only: their own label position must not shape the row\n // a field that sets a width keeps it; the others share what is left\n for (const c of this.items) if (c.config.width != null && c.config.flex == null) c.config.flex = 'none' as never;\n for (const f of this.getFields()) {\n f.config.labelPos = 'top';\n for (const ev of ['invalid', 'valid']) f.on(ev, () => this.paintError()); // also before the group is rendered\n }\n }\n\n override getBody() {\n return this.bodyEl;\n }\n\n /** The fields inside (also inside nested containers). */\n getFields(): Field<any>[] {\n return this.query((c) => c instanceof Field) as Field<any>[];\n }\n\n getError(): string {\n return this.error;\n }\n\n protected override build() {\n const el = super.build();\n this.labelEl = h('div', 'op-field__label', { id: uid('op-fg') });\n this.bodyEl = h('div', 'op-fieldgroup__body');\n this.helpEl = h('div', 'op-field__help', { id: uid('op-fg-help') });\n this.errorEl = h('div', 'op-field__error', { id: uid('op-fg-err'), role: 'alert' });\n el.append(this.labelEl, h('div', 'op-field__control', {}, this.bodyEl), this.helpEl, this.errorEl);\n el.setAttribute('role', 'group');\n el.setAttribute('aria-labelledby', this.labelEl.id);\n return el;\n }\n\n protected override onRender() {\n const c = this.config;\n c.layout ??= { type: 'hbox', stackBelow: c.stackBelow };\n super.onRender();\n let pos = c.labelPos;\n for (let p: Component | undefined = this.parent as Component | undefined; !pos && p; p = p.parent as Component | undefined) pos = (p.config as FieldGroupConfig).labelPos;\n this.el.classList.toggle('op-field--label-left', pos === 'left');\n this.setLabel(c.label ?? '');\n this.setHelp(c.help ?? '');\n this.el.classList.toggle('is-required', !!c.required || this.getFields().some((f) => f.config.required));\n this.listen(this.labelEl, 'click', () => this.getFields()[0]?.focus());\n this.error = '';\n this.paintError();\n }\n\n /** The group shows the first error of its fields, in one line. */\n private paintError() {\n const msg = this.getFields().map((f) => f.getError()).find(Boolean) ?? '';\n if (msg === this.error) return;\n this.error = msg;\n if (!this.rendered) return;\n this.errorEl.textContent = msg;\n this.el.classList.toggle('is-invalid', !!msg);\n this.describe();\n this.emit(msg ? 'invalid' : 'valid', msg);\n }\n\n private describe() {\n const ids = [this.error && this.errorEl.id, this.config.help && this.helpEl.id].filter(Boolean);\n if (ids.length) this.el.setAttribute('aria-describedby', ids.join(' '));\n else this.el.removeAttribute('aria-describedby');\n }\n\n setLabel(label: string) {\n this.config.label = label;\n if (!this.rendered) return;\n this.labelEl.textContent = label;\n this.labelEl.hidden = !label;\n }\n\n setHelp(help: string) {\n this.config.help = help;\n if (!this.rendered) return;\n this.helpEl.textContent = help;\n this.helpEl.hidden = !help;\n this.describe();\n }\n}\nregister('fieldgroup', FieldGroup);\n"],
5
+ "mappings": "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",
6
+ "names": ["FieldGroup", "Container", "config", "c", "f", "ev", "Field", "el", "h", "uid", "pos", "p", "msg", "ids", "label", "help", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as s}from"./chunk-E4VNLYO2.js";import{b as u}from"./chunk-676AKAGF.js";import{b as l}from"./chunk-PZSHOSOS.js";var p=400,o,i,d,c=!1,r=e=>e instanceof Element?e.closest("[data-op-tip]"):null;function m(e){let t=e.dataset.opTip;t&&(o??=l("div","op-tooltip",{role:"tooltip",id:"op-tooltip"}),o.textContent=t,u(o,e),i=e,e.setAttribute("aria-describedby","op-tooltip"),s(o,e,{placement:"top",offset:6}))}function n(){clearTimeout(d),i&&i.removeAttribute("aria-describedby"),i=void 0,o?.remove()}function f(e,t){clearTimeout(d),i!==e&&(n(),d=setTimeout(()=>m(e),t))}function E(){c||typeof document>"u"||(c=!0,document.addEventListener("pointerover",e=>{if(e.pointerType==="touch")return;let t=r(e.target);t&&f(t,p)}),document.addEventListener("pointerout",e=>{let t=r(e.target);t&&!t.contains(e.relatedTarget)&&n()}),document.addEventListener("focusin",e=>{let t=r(e.target),a=!0;try{a=!!t?.matches(":focus-visible")}catch{}t&&a&&f(t,0)}),document.addEventListener("focusout",n),document.addEventListener("pointerdown",n,!0),document.addEventListener("keydown",e=>e.key==="Escape"&&n(),!0),document.addEventListener("scroll",n,!0))}E();var L={configure(e){e.delay!=null&&(p=e.delay)},show:m,hide:n};function b(e,t){e.dataset.opTip=t}export{L as a,b};
2
+ //# sourceMappingURL=chunk-SA53QUBF.js.map