optikos 0.0.0-stage → 0.1.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 (430) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/LICENSE +21 -0
  3. package/README.md +211 -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-2UPUC4RK.js +2 -0
  8. package/dist/chunk-2UPUC4RK.js.map +7 -0
  9. package/dist/chunk-4AA4FQEM.js +2 -0
  10. package/dist/chunk-4AA4FQEM.js.map +7 -0
  11. package/dist/chunk-4C666HHU.js +2 -0
  12. package/dist/chunk-4C666HHU.js.map +7 -0
  13. package/dist/chunk-4COBH4QJ.js +2 -0
  14. package/dist/chunk-4COBH4QJ.js.map +7 -0
  15. package/dist/chunk-4DHQKECB.js +2 -0
  16. package/dist/chunk-4DHQKECB.js.map +7 -0
  17. package/dist/chunk-4Q67QI7J.js +2 -0
  18. package/dist/chunk-4Q67QI7J.js.map +7 -0
  19. package/dist/chunk-4SUKNSCY.js +2 -0
  20. package/dist/chunk-4SUKNSCY.js.map +7 -0
  21. package/dist/chunk-5AXLYDKU.js +2 -0
  22. package/dist/chunk-5AXLYDKU.js.map +7 -0
  23. package/dist/chunk-5GNEFX6F.js +2 -0
  24. package/dist/chunk-5GNEFX6F.js.map +7 -0
  25. package/dist/chunk-5Q6Y6CM4.js +2 -0
  26. package/dist/chunk-5Q6Y6CM4.js.map +7 -0
  27. package/dist/chunk-666O2GKD.js +2 -0
  28. package/dist/chunk-666O2GKD.js.map +7 -0
  29. package/dist/chunk-676AKAGF.js +2 -0
  30. package/dist/chunk-676AKAGF.js.map +7 -0
  31. package/dist/chunk-6NCXO5ZP.js +2 -0
  32. package/dist/chunk-6NCXO5ZP.js.map +7 -0
  33. package/dist/chunk-6NJW7QFD.js +2 -0
  34. package/dist/chunk-6NJW7QFD.js.map +7 -0
  35. package/dist/chunk-6O2BXCRN.js +2 -0
  36. package/dist/chunk-6O2BXCRN.js.map +7 -0
  37. package/dist/chunk-A66MDXHL.js +2 -0
  38. package/dist/chunk-A66MDXHL.js.map +7 -0
  39. package/dist/chunk-ARCW54L2.js +2 -0
  40. package/dist/chunk-ARCW54L2.js.map +7 -0
  41. package/dist/chunk-BIYNHKSA.js +2 -0
  42. package/dist/chunk-BIYNHKSA.js.map +7 -0
  43. package/dist/chunk-BNPVRIFT.js +2 -0
  44. package/dist/chunk-BNPVRIFT.js.map +7 -0
  45. package/dist/chunk-C3N7QTQB.js +2 -0
  46. package/dist/chunk-C3N7QTQB.js.map +7 -0
  47. package/dist/chunk-CEXY5A4T.js +2 -0
  48. package/dist/chunk-CEXY5A4T.js.map +7 -0
  49. package/dist/chunk-CN7USUJR.js +2 -0
  50. package/dist/chunk-CN7USUJR.js.map +7 -0
  51. package/dist/chunk-CQRHNTEX.js +2 -0
  52. package/dist/chunk-CQRHNTEX.js.map +7 -0
  53. package/dist/chunk-CUPAPOKC.js +2 -0
  54. package/dist/chunk-CUPAPOKC.js.map +7 -0
  55. package/dist/chunk-DXO3UJKL.js +2 -0
  56. package/dist/chunk-DXO3UJKL.js.map +7 -0
  57. package/dist/chunk-GZNQPENR.js +2 -0
  58. package/dist/chunk-GZNQPENR.js.map +7 -0
  59. package/dist/chunk-HFFK6K4K.js +2 -0
  60. package/dist/chunk-HFFK6K4K.js.map +7 -0
  61. package/dist/chunk-IHAYOSBR.js +2 -0
  62. package/dist/chunk-IHAYOSBR.js.map +7 -0
  63. package/dist/chunk-IO66A6G5.js +2 -0
  64. package/dist/chunk-IO66A6G5.js.map +7 -0
  65. package/dist/chunk-IW7PK4VS.js +2 -0
  66. package/dist/chunk-IW7PK4VS.js.map +7 -0
  67. package/dist/chunk-IYPKPLCU.js +2 -0
  68. package/dist/chunk-IYPKPLCU.js.map +7 -0
  69. package/dist/chunk-JTYWZMSZ.js +2 -0
  70. package/dist/chunk-JTYWZMSZ.js.map +7 -0
  71. package/dist/chunk-JVEPKW5X.js +2 -0
  72. package/dist/chunk-JVEPKW5X.js.map +7 -0
  73. package/dist/chunk-JZNEB7A7.js +2 -0
  74. package/dist/chunk-JZNEB7A7.js.map +7 -0
  75. package/dist/chunk-K2DGY6MP.js +2 -0
  76. package/dist/chunk-K2DGY6MP.js.map +7 -0
  77. package/dist/chunk-LBCWEWPN.js +2 -0
  78. package/dist/chunk-LBCWEWPN.js.map +7 -0
  79. package/dist/chunk-LEE2FEEL.js +2 -0
  80. package/dist/chunk-LEE2FEEL.js.map +7 -0
  81. package/dist/chunk-LMGCV35W.js +2 -0
  82. package/dist/chunk-LMGCV35W.js.map +7 -0
  83. package/dist/chunk-LV6HXFHU.js +3 -0
  84. package/dist/chunk-LV6HXFHU.js.map +7 -0
  85. package/dist/chunk-MA5BJL3S.js +2 -0
  86. package/dist/chunk-MA5BJL3S.js.map +7 -0
  87. package/dist/chunk-NDBFYIL6.js +2 -0
  88. package/dist/chunk-NDBFYIL6.js.map +7 -0
  89. package/dist/chunk-NHVEP72K.js +2 -0
  90. package/dist/chunk-NHVEP72K.js.map +7 -0
  91. package/dist/chunk-NV5AIBQP.js +2 -0
  92. package/dist/chunk-NV5AIBQP.js.map +7 -0
  93. package/dist/chunk-NWTTHDIM.js +2 -0
  94. package/dist/chunk-NWTTHDIM.js.map +7 -0
  95. package/dist/chunk-O4DCHALR.js +2 -0
  96. package/dist/chunk-O4DCHALR.js.map +7 -0
  97. package/dist/chunk-ODWPBBVL.js +2 -0
  98. package/dist/chunk-ODWPBBVL.js.map +7 -0
  99. package/dist/chunk-OW2ZSMGS.js +2 -0
  100. package/dist/chunk-OW2ZSMGS.js.map +7 -0
  101. package/dist/chunk-OWEQT2HN.js +2 -0
  102. package/dist/chunk-OWEQT2HN.js.map +7 -0
  103. package/dist/chunk-PSPQH35P.js +2 -0
  104. package/dist/chunk-PSPQH35P.js.map +7 -0
  105. package/dist/chunk-PZSHOSOS.js +2 -0
  106. package/dist/chunk-PZSHOSOS.js.map +7 -0
  107. package/dist/chunk-QEQIJAAB.js +2 -0
  108. package/dist/chunk-QEQIJAAB.js.map +7 -0
  109. package/dist/chunk-SNTHW4K2.js +2 -0
  110. package/dist/chunk-SNTHW4K2.js.map +7 -0
  111. package/dist/chunk-T4OYVG2X.js +2 -0
  112. package/dist/chunk-T4OYVG2X.js.map +7 -0
  113. package/dist/chunk-TBLICXWW.js +2 -0
  114. package/dist/chunk-TBLICXWW.js.map +7 -0
  115. package/dist/chunk-TK2RC3T5.js +2 -0
  116. package/dist/chunk-TK2RC3T5.js.map +7 -0
  117. package/dist/chunk-U3X2FW6U.js +2 -0
  118. package/dist/chunk-U3X2FW6U.js.map +7 -0
  119. package/dist/chunk-UPOBGNJ5.js +2 -0
  120. package/dist/chunk-UPOBGNJ5.js.map +7 -0
  121. package/dist/chunk-VV7CFMPZ.js +2 -0
  122. package/dist/chunk-VV7CFMPZ.js.map +7 -0
  123. package/dist/chunk-X2ASKUFD.js +2 -0
  124. package/dist/chunk-X2ASKUFD.js.map +7 -0
  125. package/dist/chunk-X6AULZI4.js +1 -0
  126. package/dist/chunk-X6AULZI4.js.map +7 -0
  127. package/dist/chunk-XVIC24AW.js +2 -0
  128. package/dist/chunk-XVIC24AW.js.map +7 -0
  129. package/dist/chunk-XZ5CUZZP.js +2 -0
  130. package/dist/chunk-XZ5CUZZP.js.map +7 -0
  131. package/dist/chunk-XZEOSW3Q.js +2 -0
  132. package/dist/chunk-XZEOSW3Q.js.map +7 -0
  133. package/dist/chunk-YET5PM6F.js +2 -0
  134. package/dist/chunk-YET5PM6F.js.map +7 -0
  135. package/dist/chunk-Z25NC4CS.js +2 -0
  136. package/dist/chunk-Z25NC4CS.js.map +7 -0
  137. package/dist/chunk-ZCAAM4NH.js +2 -0
  138. package/dist/chunk-ZCAAM4NH.js.map +7 -0
  139. package/dist/chunk-ZHVSHDLH.js +2 -0
  140. package/dist/chunk-ZHVSHDLH.js.map +7 -0
  141. package/dist/chunk-ZYUXCZX7.js +2 -0
  142. package/dist/chunk-ZYUXCZX7.js.map +7 -0
  143. package/dist/components/breadcrumb.js +2 -0
  144. package/dist/components/breadcrumb.js.map +7 -0
  145. package/dist/components/button.js +2 -0
  146. package/dist/components/button.js.map +7 -0
  147. package/dist/components/calendar.js +2 -0
  148. package/dist/components/calendar.js.map +7 -0
  149. package/dist/components/chat.js +2 -0
  150. package/dist/components/chat.js.map +7 -0
  151. package/dist/components/checkbox.js +2 -0
  152. package/dist/components/checkbox.js.map +7 -0
  153. package/dist/components/combobox.js +2 -0
  154. package/dist/components/combobox.js.map +7 -0
  155. package/dist/components/commandpalette.js +2 -0
  156. package/dist/components/commandpalette.js.map +7 -0
  157. package/dist/components/container.js +2 -0
  158. package/dist/components/container.js.map +7 -0
  159. package/dist/components/dataview.js +2 -0
  160. package/dist/components/dataview.js.map +7 -0
  161. package/dist/components/datefield.js +2 -0
  162. package/dist/components/datefield.js.map +7 -0
  163. package/dist/components/daterangefield.js +2 -0
  164. package/dist/components/daterangefield.js.map +7 -0
  165. package/dist/components/dropdown.js +2 -0
  166. package/dist/components/dropdown.js.map +7 -0
  167. package/dist/components/fieldset.js +2 -0
  168. package/dist/components/fieldset.js.map +7 -0
  169. package/dist/components/filterbuilder.js +2 -0
  170. package/dist/components/filterbuilder.js.map +7 -0
  171. package/dist/components/form.js +2 -0
  172. package/dist/components/form.js.map +7 -0
  173. package/dist/components/grid.js +2 -0
  174. package/dist/components/grid.js.map +7 -0
  175. package/dist/components/icon.js +2 -0
  176. package/dist/components/icon.js.map +7 -0
  177. package/dist/components/label.js +2 -0
  178. package/dist/components/label.js.map +7 -0
  179. package/dist/components/listbox.js +2 -0
  180. package/dist/components/listbox.js.map +7 -0
  181. package/dist/components/lookupfield.js +2 -0
  182. package/dist/components/lookupfield.js.map +7 -0
  183. package/dist/components/menu.js +2 -0
  184. package/dist/components/menu.js.map +7 -0
  185. package/dist/components/messagebox.js +2 -0
  186. package/dist/components/messagebox.js.map +7 -0
  187. package/dist/components/navmenu.js +2 -0
  188. package/dist/components/navmenu.js.map +7 -0
  189. package/dist/components/numberfield.js +2 -0
  190. package/dist/components/numberfield.js.map +7 -0
  191. package/dist/components/pagination.js +2 -0
  192. package/dist/components/pagination.js.map +7 -0
  193. package/dist/components/panel.js +2 -0
  194. package/dist/components/panel.js.map +7 -0
  195. package/dist/components/pickerfield.js +2 -0
  196. package/dist/components/pickerfield.js.map +7 -0
  197. package/dist/components/radiogroup.js +2 -0
  198. package/dist/components/radiogroup.js.map +7 -0
  199. package/dist/components/searchgrid.js +2 -0
  200. package/dist/components/searchgrid.js.map +7 -0
  201. package/dist/components/secretfield.js +2 -0
  202. package/dist/components/secretfield.js.map +7 -0
  203. package/dist/components/select.js +2 -0
  204. package/dist/components/select.js.map +7 -0
  205. package/dist/components/slider.js +2 -0
  206. package/dist/components/slider.js.map +7 -0
  207. package/dist/components/spacer.js +2 -0
  208. package/dist/components/spacer.js.map +7 -0
  209. package/dist/components/spinner.js +2 -0
  210. package/dist/components/spinner.js.map +7 -0
  211. package/dist/components/stepform.js +2 -0
  212. package/dist/components/stepform.js.map +7 -0
  213. package/dist/components/stepper.js +2 -0
  214. package/dist/components/stepper.js.map +7 -0
  215. package/dist/components/suggestfield.js +2 -0
  216. package/dist/components/suggestfield.js.map +7 -0
  217. package/dist/components/table.js +2 -0
  218. package/dist/components/table.js.map +7 -0
  219. package/dist/components/tabs.js +2 -0
  220. package/dist/components/tabs.js.map +7 -0
  221. package/dist/components/textarea.js +2 -0
  222. package/dist/components/textarea.js.map +7 -0
  223. package/dist/components/textfield.js +2 -0
  224. package/dist/components/textfield.js.map +7 -0
  225. package/dist/components/toast.js +2 -0
  226. package/dist/components/toast.js.map +7 -0
  227. package/dist/components/toolbar.js +2 -0
  228. package/dist/components/toolbar.js.map +7 -0
  229. package/dist/components/tooltip.js +2 -0
  230. package/dist/components/tooltip.js.map +7 -0
  231. package/dist/components/viewmanager.js +2 -0
  232. package/dist/components/viewmanager.js.map +7 -0
  233. package/dist/components/viewport.js +2 -0
  234. package/dist/components/viewport.js.map +7 -0
  235. package/dist/components/widget.js +2 -0
  236. package/dist/components/widget.js.map +7 -0
  237. package/dist/components/window.js +2 -0
  238. package/dist/components/window.js.map +7 -0
  239. package/dist/core.js +2 -0
  240. package/dist/core.js.map +7 -0
  241. package/dist/css/base.css +160 -0
  242. package/dist/css/breadcrumb.css +53 -0
  243. package/dist/css/button.css +101 -0
  244. package/dist/css/calendar.css +108 -0
  245. package/dist/css/chat.css +233 -0
  246. package/dist/css/checkbox.css +64 -0
  247. package/dist/css/commandpalette.css +167 -0
  248. package/dist/css/container.css +5 -0
  249. package/dist/css/core.css +88 -0
  250. package/dist/css/dataview.css +56 -0
  251. package/dist/css/dropdown.css +13 -0
  252. package/dist/css/field.css +62 -0
  253. package/dist/css/fieldset.css +32 -0
  254. package/dist/css/filterbuilder.css +125 -0
  255. package/dist/css/form.css +8 -0
  256. package/dist/css/grid.css +367 -0
  257. package/dist/css/icon.css +16 -0
  258. package/dist/css/label.css +12 -0
  259. package/dist/css/layout.css +116 -0
  260. package/dist/css/listbox.css +50 -0
  261. package/dist/css/menu.css +47 -0
  262. package/dist/css/messagebox.css +6 -0
  263. package/dist/css/motion.css +29 -0
  264. package/dist/css/navmenu.css +115 -0
  265. package/dist/css/pagination.css +23 -0
  266. package/dist/css/panel.css +77 -0
  267. package/dist/css/pickerfield.css +85 -0
  268. package/dist/css/radiogroup.css +53 -0
  269. package/dist/css/searchgrid.css +37 -0
  270. package/dist/css/secretfield.css +73 -0
  271. package/dist/css/slider.css +107 -0
  272. package/dist/css/spacer.css +7 -0
  273. package/dist/css/stepform.css +46 -0
  274. package/dist/css/stepper.css +117 -0
  275. package/dist/css/table.css +36 -0
  276. package/dist/css/tabs.css +99 -0
  277. package/dist/css/textarea.css +11 -0
  278. package/dist/css/textfield.css +59 -0
  279. package/dist/css/toast.css +91 -0
  280. package/dist/css/toolbar.css +14 -0
  281. package/dist/css/tooltip.css +17 -0
  282. package/dist/css/viewport.css +9 -0
  283. package/dist/css/widget.css +77 -0
  284. package/dist/css/window.css +31 -0
  285. package/dist/data.js +2 -0
  286. package/dist/data.js.map +7 -0
  287. package/dist/index.js +8 -0
  288. package/dist/index.js.map +7 -0
  289. package/dist/motion.js +2 -0
  290. package/dist/motion.js.map +7 -0
  291. package/dist/optikos.css +3145 -0
  292. package/dist/themes/brand.css +240 -0
  293. package/dist/themes/brutal.css +100 -0
  294. package/dist/themes/compact.css +17 -0
  295. package/dist/themes/corporate.css +112 -0
  296. package/dist/themes/dark.css +38 -0
  297. package/dist/themes/editorial.css +110 -0
  298. package/dist/themes/soft.css +101 -0
  299. package/dist/themes/terminal.css +91 -0
  300. package/dist/types/bind/index.d.ts +23 -0
  301. package/dist/types/components/base/button/button.d.ts +34 -0
  302. package/dist/types/components/base/icon/icon.d.ts +17 -0
  303. package/dist/types/components/base/label/label.d.ts +14 -0
  304. package/dist/types/components/breadcrumb.d.ts +1 -0
  305. package/dist/types/components/button.d.ts +1 -0
  306. package/dist/types/components/calendar.d.ts +1 -0
  307. package/dist/types/components/chat/chat/chat.d.ts +84 -0
  308. package/dist/types/components/chat.d.ts +1 -0
  309. package/dist/types/components/checkbox.d.ts +1 -0
  310. package/dist/types/components/combobox.d.ts +1 -0
  311. package/dist/types/components/commandpalette.d.ts +1 -0
  312. package/dist/types/components/container.d.ts +1 -0
  313. package/dist/types/components/data/dataview/dataview.d.ts +61 -0
  314. package/dist/types/components/data/filterbuilder/filterbuilder.d.ts +71 -0
  315. package/dist/types/components/data/grid/grid.d.ts +151 -0
  316. package/dist/types/components/data/pagination/pagination.d.ts +31 -0
  317. package/dist/types/components/data/searchgrid/searchgrid.d.ts +63 -0
  318. package/dist/types/components/data/table/table.d.ts +26 -0
  319. package/dist/types/components/data/viewmanager/viewmanager.d.ts +86 -0
  320. package/dist/types/components/dataview.d.ts +1 -0
  321. package/dist/types/components/datefield.d.ts +1 -0
  322. package/dist/types/components/daterangefield.d.ts +1 -0
  323. package/dist/types/components/dates/calendar/calendar.d.ts +48 -0
  324. package/dist/types/components/dropdown.d.ts +1 -0
  325. package/dist/types/components/feedback/spinner/spinner.d.ts +11 -0
  326. package/dist/types/components/fields/checkbox/checkbox.d.ts +20 -0
  327. package/dist/types/components/fields/combobox/combobox.d.ts +15 -0
  328. package/dist/types/components/fields/datefield/datefield.d.ts +30 -0
  329. package/dist/types/components/fields/daterangefield/daterangefield.d.ts +32 -0
  330. package/dist/types/components/fields/listbox/listbox.d.ts +54 -0
  331. package/dist/types/components/fields/lookupfield/lookupfield.d.ts +25 -0
  332. package/dist/types/components/fields/numberfield/numberfield.d.ts +31 -0
  333. package/dist/types/components/fields/pickerfield/pickerfield.d.ts +77 -0
  334. package/dist/types/components/fields/radiogroup/radiogroup.d.ts +26 -0
  335. package/dist/types/components/fields/secretfield/secretfield.d.ts +52 -0
  336. package/dist/types/components/fields/select/select.d.ts +10 -0
  337. package/dist/types/components/fields/slider/slider.d.ts +62 -0
  338. package/dist/types/components/fields/suggestfield/suggestfield.d.ts +34 -0
  339. package/dist/types/components/fields/textarea/textarea.d.ts +16 -0
  340. package/dist/types/components/fields/textfield/textfield.d.ts +38 -0
  341. package/dist/types/components/fieldset.d.ts +1 -0
  342. package/dist/types/components/filterbuilder.d.ts +1 -0
  343. package/dist/types/components/form/form/form.d.ts +51 -0
  344. package/dist/types/components/form/stepform/stepform.d.ts +62 -0
  345. package/dist/types/components/form.d.ts +1 -0
  346. package/dist/types/components/grid.d.ts +1 -0
  347. package/dist/types/components/icon.d.ts +1 -0
  348. package/dist/types/components/label.d.ts +1 -0
  349. package/dist/types/components/layout/container/container.d.ts +1 -0
  350. package/dist/types/components/layout/fieldset/fieldset.d.ts +21 -0
  351. package/dist/types/components/layout/panel/panel.d.ts +47 -0
  352. package/dist/types/components/layout/spacer/spacer.d.ts +12 -0
  353. package/dist/types/components/layout/toolbar/toolbar.d.ts +15 -0
  354. package/dist/types/components/layout/viewport/viewport.d.ts +7 -0
  355. package/dist/types/components/listbox.d.ts +1 -0
  356. package/dist/types/components/lookupfield.d.ts +1 -0
  357. package/dist/types/components/menu.d.ts +1 -0
  358. package/dist/types/components/messagebox.d.ts +1 -0
  359. package/dist/types/components/navigation/breadcrumb/breadcrumb.d.ts +32 -0
  360. package/dist/types/components/navigation/navmenu/navmenu.d.ts +63 -0
  361. package/dist/types/components/navigation/stepper/stepper.d.ts +31 -0
  362. package/dist/types/components/navigation/tabs/tabs.d.ts +49 -0
  363. package/dist/types/components/navmenu.d.ts +1 -0
  364. package/dist/types/components/numberfield.d.ts +1 -0
  365. package/dist/types/components/overlays/commandpalette/commandpalette.d.ts +80 -0
  366. package/dist/types/components/overlays/dropdown/dropdown.d.ts +41 -0
  367. package/dist/types/components/overlays/menu/menu.d.ts +41 -0
  368. package/dist/types/components/overlays/messagebox/messagebox.d.ts +53 -0
  369. package/dist/types/components/overlays/toast/toast.d.ts +45 -0
  370. package/dist/types/components/overlays/tooltip/tooltip.d.ts +13 -0
  371. package/dist/types/components/overlays/widget/widget.d.ts +48 -0
  372. package/dist/types/components/overlays/window/window.d.ts +31 -0
  373. package/dist/types/components/pagination.d.ts +1 -0
  374. package/dist/types/components/panel.d.ts +1 -0
  375. package/dist/types/components/pickerfield.d.ts +1 -0
  376. package/dist/types/components/radiogroup.d.ts +1 -0
  377. package/dist/types/components/searchgrid.d.ts +1 -0
  378. package/dist/types/components/secretfield.d.ts +1 -0
  379. package/dist/types/components/select.d.ts +1 -0
  380. package/dist/types/components/slider.d.ts +1 -0
  381. package/dist/types/components/spacer.d.ts +1 -0
  382. package/dist/types/components/spinner.d.ts +1 -0
  383. package/dist/types/components/stepform.d.ts +1 -0
  384. package/dist/types/components/stepper.d.ts +1 -0
  385. package/dist/types/components/suggestfield.d.ts +1 -0
  386. package/dist/types/components/table.d.ts +1 -0
  387. package/dist/types/components/tabs.d.ts +1 -0
  388. package/dist/types/components/textarea.d.ts +1 -0
  389. package/dist/types/components/textfield.d.ts +1 -0
  390. package/dist/types/components/toast.d.ts +1 -0
  391. package/dist/types/components/toolbar.d.ts +1 -0
  392. package/dist/types/components/tooltip.d.ts +1 -0
  393. package/dist/types/components/viewmanager.d.ts +1 -0
  394. package/dist/types/components/viewport.d.ts +1 -0
  395. package/dist/types/components/widget.d.ts +1 -0
  396. package/dist/types/components/window.d.ts +1 -0
  397. package/dist/types/core/component.d.ts +90 -0
  398. package/dist/types/core/container.d.ts +43 -0
  399. package/dist/types/core/date.d.ts +14 -0
  400. package/dist/types/core/dom.d.ts +11 -0
  401. package/dist/types/core/emitter.d.ts +12 -0
  402. package/dist/types/core/field.d.ts +78 -0
  403. package/dist/types/core/focus.d.ts +18 -0
  404. package/dist/types/core/i18n.d.ts +7 -0
  405. package/dist/types/core/index.d.ts +15 -0
  406. package/dist/types/core/layer.d.ts +6 -0
  407. package/dist/types/core/position.d.ts +16 -0
  408. package/dist/types/core/registry.d.ts +12 -0
  409. package/dist/types/core/validators.d.ts +10 -0
  410. package/dist/types/core/virtual.d.ts +24 -0
  411. package/dist/types/data/column.d.ts +27 -0
  412. package/dist/types/data/format.d.ts +4 -0
  413. package/dist/types/data/index.d.ts +5 -0
  414. package/dist/types/data/model.d.ts +28 -0
  415. package/dist/types/data/proxy.d.ts +61 -0
  416. package/dist/types/data/store.d.ts +94 -0
  417. package/dist/types/index.d.ts +53 -0
  418. package/dist/types/layout/layout.d.ts +27 -0
  419. package/dist/types/motion/config.d.ts +83 -0
  420. package/dist/types/motion/core.d.ts +40 -0
  421. package/dist/types/motion/extras.d.ts +66 -0
  422. package/dist/types/motion/index.d.ts +3 -0
  423. package/dist/types/themes/define.d.ts +30 -0
  424. package/dist/types/themes/index.d.ts +1 -0
  425. package/dist/types/ui/enums.d.ts +88 -0
  426. package/dist/types/ui/index.d.ts +2 -0
  427. package/dist/types/ui/ui.d.ts +58 -0
  428. package/dist/ui.js +2 -0
  429. package/dist/ui.js.map +7 -0
  430. package/package.json +99 -4
@@ -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 } from '../../../core/i18n';\nimport { iconEl } from '../../base/icon/icon';\nimport { MessageBox } from '../../overlays/messagebox/messagebox';\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": ["MASK", "SecretField", "TextField", "config", "v", "wrap", "input", "h", "t", "e", "stored", "silent", "MessageBox", "on", "iconEl", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{c as t}from"./chunk-UPOBGNJ5.js";import{b as o}from"./chunk-IYPKPLCU.js";var e,r=class extends t{baseCls="op-viewport";constructor(n={}){if(super(n),e&&!e.destroyed)throw new Error("Optikos: only one Viewport can exist at a time");e=this}onRender(){this.config.layout??="fit",super.onRender()}};o("viewport",r);export{r as a};
2
+ //# sourceMappingURL=chunk-TBLICXWW.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/layout/viewport/viewport.ts"],
4
+ "sourcesContent": ["import { Container, type ContainerConfig } from '../../../core/container';\nimport { register } from '../../../core/registry';\n\nlet current: Viewport | undefined;\n\n/** Root container that fills the window. Only one can exist at a time. */\nexport class Viewport extends Container<ContainerConfig> {\n protected override baseCls = 'op-viewport';\n\n constructor(config: ContainerConfig = {}) {\n super(config);\n if (current && !current.destroyed) throw new Error('Optikos: only one Viewport can exist at a time');\n current = this;\n }\n\n protected override onRender() {\n this.config.layout ??= 'fit';\n super.onRender();\n }\n}\nregister('viewport', Viewport);\n"],
5
+ "mappings": "gFAGA,IAAIA,EAGSC,EAAN,cAAuBC,CAA2B,CACpC,QAAU,cAE7B,YAAYC,EAA0B,CAAC,EAAG,CAExC,GADA,MAAMA,CAAM,EACRH,GAAW,CAACA,EAAQ,UAAW,MAAM,IAAI,MAAM,gDAAgD,EACnGA,EAAU,IACZ,CAEmB,UAAW,CAC5B,KAAK,OAAO,SAAW,MACvB,MAAM,SAAS,CACjB,CACF,EACAI,EAAS,WAAYH,CAAQ",
6
+ "names": ["current", "Viewport", "Container", "config", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as d}from"./chunk-5Q6Y6CM4.js";import{a as m}from"./chunk-ZCAAM4NH.js";import{a as v}from"./chunk-XZEOSW3Q.js";import{a as f,b as c}from"./chunk-IYPKPLCU.js";import{b as l}from"./chunk-PZSHOSOS.js";import{e as n}from"./chunk-MA5BJL3S.js";var w=()=>globalThis.crypto?.randomUUID?.()??`${Date.now()}-${Math.random().toString(36).slice(2)}`;function P(a,e=localStorage){let t=()=>{try{let r=JSON.parse(e.getItem(a)??"[]");return Array.isArray(r)?r:[]}catch{return[]}},i=r=>e.setItem(a,JSON.stringify(r));return{list:t,save(r){let s={...r,id:r.id??w()},o=t(),u=o.findIndex(p=>p.id===s.id);return u<0?o.push(s):o[u]=s,i(o),s},remove(r){i(t().filter(s=>s.id!==r.id))}}}function M(a){let e=async(t,i="",r)=>{let s=await(a.fetch??fetch)(a.url+i,{method:t,headers:{"Content-Type":"application/json",...a.headers},body:r===void 0?void 0:JSON.stringify(r)});if(!s.ok)throw new Error(`Optikos views: ${t} ${a.url+i} \u2192 ${s.status}`);return s.status===204?void 0:s.json().catch(()=>{})};return{list:()=>e("GET"),save:t=>t.id?e("PUT",`/${encodeURIComponent(t.id)}`,t):e("POST","",t),remove:t=>e("DELETE",`/${encodeURIComponent(t.id)}`).then(()=>{})}}var h=class extends f{baseCls="op-viewmanager";btn;menu;views=[];current;initial={};build(){return this.btn=new v({text:n("views"),icon:"menu",variant:"ghost",handler:()=>this.openMenu()}),this.btn.el.setAttribute("aria-haspopup","menu"),this.own(()=>(this.btn.destroy(),this.menu?.destroy())),l("span",this.baseCls,{},this.btn.el)}onRender(){this.config.grid.render(),this.config.filters?.render(),this.initial=this.getState(),this.config.autoLoad!==!1&&this.reload()}notifyMount(){super.notifyMount(),this.btn.notifyMount()}getState(){let{grid:e,filters:t,extra:i}=this.config,r={columns:e.getColumnState(),filter:t?.getFilter()??null,sorters:[...e.getStore().getSorters()]};return i&&(r.extra=Object.fromEntries(Object.entries(i).map(([s,o])=>[s,o.get()]))),r}setState(e){let{grid:t,filters:i,extra:r}=this.config;e.columns&&t.setColumnState(e.columns);let s=e.sorters?.[0];t.getStore().sort(s?.field??null,s?.dir),i&&(i.setFilter(e.filter??null),i.apply());for(let o in e.extra)r?.[o]?.set(e.extra[o])}getViews(){return this.views}getCurrent(){return this.current}async reload(){await this.run(async()=>{this.views=await this.config.storage.list()??[],this.current=this.current&&this.views.find(t=>t.id===this.current.id);let e=this.views.find(t=>t.default);!this.current&&e&&this.config.autoLoad!==!1&&this.apply(e),this.paint()}),this.emit("load",this.views)}apply(e){let t=typeof e=="string"?this.views.find(i=>i.id===e):e;!t||this.emit("before-apply",t)===!1||(this.current=t,this.setState(t.state),this.paint(),this.emit("apply",t))}async save(){if(!this.current)return this.saveAs();await this.store({...this.current,state:this.getState()})}async saveAs(e){if(e??=await d.prompt(n("viewsName"),{title:n("viewsSaveAs")})??"",e=e.trim(),!e)return;let t=this.views.find(i=>i.name.toLowerCase()===e.toLowerCase());await this.store({...t,name:e,state:this.getState()})}async setDefault(e=!0){if(this.current){for(let t of this.views)t!==this.current&&t.default&&await this.store({...t,default:!1},!1);await this.store({...this.current,default:e})}}async remove(e=this.current){!e||!await d.confirm(n("viewsConfirmDelete",{n:e.name}),{danger:!0,okText:n("viewsDelete")})||await this.run(async()=>{await this.config.storage.remove(e),this.views=this.views.filter(t=>t!==e&&t.id!==e.id),this.current?.id===e.id&&(this.current=void 0),this.paint(),this.emit("remove",e)})}reset(){this.current=void 0,this.setState(this.initial),this.paint(),this.emit("reset")}async store(e,t=!0){await this.run(async()=>{let i=await this.config.storage.save(e)||e,r=this.views.findIndex(s=>i.id&&s.id===i.id||s===e);r<0?this.views.push(i):this.views[r]=i,t&&(this.current=i),this.paint(),this.emit("save",i)})}async run(e){try{await e()}catch(t){this.emit("error",t)}}paint(){this.btn.setText(this.current?.name??n("views"))}openMenu(){let e=this.current,t=[...this.views.map(i=>({text:i.default?`${i.name} \u2605`:i.name,checked:i===e||!!e?.id&&i.id===e.id,handler:()=>this.apply(i)})),...this.views.length?["-"]:[],{text:n("viewsSave"),handler:()=>{this.save()}},{text:n("viewsSaveAs"),handler:()=>{this.saveAs()}},...e?[{text:n("viewsDefault"),checked:!!e.default,handler:()=>{this.setDefault(!e.default)}},{text:n("viewsDelete"),handler:()=>{this.remove()}}]:[],"-",{text:n("viewsReset"),handler:()=>this.reset()}];this.menu??=new m({}),this.menu.setItems(t),this.menu.showBy(this.btn.el)}};c("viewmanager",h);export{P as a,M as b,h as c};
2
+ //# sourceMappingURL=chunk-TK2RC3T5.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/data/viewmanager/viewmanager.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 type { FilterGroup, Sorter } from '../../../data/proxy';\nimport { Button } from '../../base/button/button';\nimport { Menu, type MenuEntry } from '../../overlays/menu/menu';\nimport { MessageBox } from '../../overlays/messagebox/messagebox';\nimport type { Grid, ColumnState } from '../grid/grid';\nimport type { FilterBuilder } from '../filterbuilder/filterbuilder';\n\n/** Everything a view remembers: plain JSON, so it can travel to any backend. */\nexport interface ViewState {\n columns?: ColumnState[];\n filter?: FilterGroup | null;\n sorters?: Sorter[];\n /** Whatever the app registered in `extra` (panel collapsed, density...). */\n extra?: Record<string, unknown>;\n}\nexport interface SavedView {\n id?: string;\n name: string;\n default?: boolean;\n state: ViewState;\n}\n\n/** Where views live. Implement it for your endpoint; `localViewStorage` and `restViewStorage` are ready-made. */\nexport interface ViewStorage {\n list(): Promise<SavedView[]> | SavedView[];\n /** Create (no `id`) or update. May return the stored view (with the id the server gave it). */\n save(view: SavedView): Promise<SavedView | void> | SavedView | void;\n remove(view: SavedView): Promise<void> | void;\n}\n\nconst newId = () => globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n/** Views in the browser (`localStorage` by default) under one key. */\nexport function localViewStorage(key: string, storage: Storage = localStorage): ViewStorage {\n const read = (): SavedView[] => {\n try {\n const v = JSON.parse(storage.getItem(key) ?? '[]');\n return Array.isArray(v) ? v : [];\n } catch {\n return [];\n }\n };\n const write = (v: SavedView[]) => storage.setItem(key, JSON.stringify(v));\n return {\n list: read,\n save(view) {\n const saved = { ...view, id: view.id ?? newId() };\n const all = read();\n const i = all.findIndex((x) => x.id === saved.id);\n if (i < 0) all.push(saved);\n else all[i] = saved;\n write(all);\n return saved;\n },\n remove(view) {\n write(read().filter((x) => x.id !== view.id));\n },\n };\n}\n\nexport interface RestViewStorageConfig {\n /** `GET url` lists, `POST url` creates, `PUT url/:id` updates, `DELETE url/:id` removes. JSON in and out. */\n url: string;\n headers?: Record<string, string>;\n fetch?: typeof fetch;\n}\n\n/** Views on your server. Responses must be JSON (the list as an array, create/update returning the stored view). */\nexport function restViewStorage(cfg: RestViewStorageConfig): ViewStorage {\n const call = async (method: string, path = '', body?: unknown) => {\n const res = await (cfg.fetch ?? fetch)(cfg.url + path, { method, headers: { 'Content-Type': 'application/json', ...cfg.headers }, body: body === undefined ? undefined : JSON.stringify(body) });\n if (!res.ok) throw new Error(`Optikos views: ${method} ${cfg.url + path} \u2192 ${res.status}`);\n return res.status === 204 ? undefined : res.json().catch(() => undefined);\n };\n return {\n list: () => call('GET'),\n save: (v) => (v.id ? call('PUT', `/${encodeURIComponent(v.id)}`, v) : call('POST', '', v)),\n remove: (v) => call('DELETE', `/${encodeURIComponent(v.id!)}`).then(() => undefined),\n };\n}\n\nexport interface ViewManagerConfig extends ComponentConfig {\n grid: Grid;\n /** Its filter tree is part of the view. */\n filters?: FilterBuilder;\n storage: ViewStorage;\n /** Extra things to remember: `{ density: { get: () => ..., set: (v) => ... } }`. Stored in `state.extra`. */\n extra?: Record<string, { get(): unknown; set(value: unknown): void }>;\n /** Apply the default view when it opens. Default true. */\n autoLoad?: boolean;\n}\n\n/**\n * \"Views\" button for a Grid (and its FilterBuilder): saves and restores the visible columns and their order, the filters\n * (including nested AND/OR groups) and the sort, under a name, in the storage you give it.\n */\nexport class ViewManager extends Component<ViewManagerConfig> {\n protected override baseCls = 'op-viewmanager';\n private btn!: Button;\n private menu?: Menu;\n private views: SavedView[] = [];\n private current?: SavedView;\n private initial: ViewState = {};\n\n protected override build() {\n this.btn = new Button({ text: t('views'), icon: 'menu', variant: 'ghost', handler: () => this.openMenu() });\n this.btn.el.setAttribute('aria-haspopup', 'menu');\n this.own(() => (this.btn.destroy(), this.menu?.destroy()));\n return h('span', this.baseCls, {}, this.btn.el);\n }\n\n protected override onRender() {\n this.config.grid.render();\n this.config.filters?.render();\n this.initial = this.getState();\n if (this.config.autoLoad !== false) void this.reload();\n }\n\n override notifyMount() {\n super.notifyMount();\n this.btn.notifyMount();\n }\n\n // ---- state ---------------------------------------------------------------------------------\n\n /** The grid's and filter's current setup. */\n getState(): ViewState {\n const { grid, filters, extra } = this.config;\n const state: ViewState = { columns: grid.getColumnState(), filter: filters?.getFilter() ?? null, sorters: [...grid.getStore().getSorters()] };\n if (extra) state.extra = Object.fromEntries(Object.entries(extra).map(([k, e]) => [k, e.get()]));\n return state;\n }\n\n /** Puts a setup on the grid and the filter. */\n setState(s: ViewState): void {\n const { grid, filters, extra } = this.config;\n if (s.columns) grid.setColumnState(s.columns);\n const sort = s.sorters?.[0];\n grid.getStore().sort(sort?.field ?? null, sort?.dir);\n if (filters) {\n filters.setFilter(s.filter ?? null);\n filters.apply();\n }\n for (const k in s.extra) extra?.[k]?.set(s.extra[k]);\n }\n\n // ---- views ---------------------------------------------------------------------------------\n\n getViews(): SavedView[] {\n return this.views;\n }\n getCurrent(): SavedView | undefined {\n return this.current;\n }\n\n /** Reads the views from the storage and applies the default one (unless a view is already active). */\n async reload(): Promise<void> {\n await this.run(async () => {\n this.views = (await this.config.storage.list()) ?? [];\n this.current = this.current && this.views.find((v) => v.id === this.current!.id);\n const def = this.views.find((v) => v.default);\n if (!this.current && def && this.config.autoLoad !== false) this.apply(def);\n this.paint();\n });\n this.emit('load', this.views);\n }\n\n /** Applies a saved view (object or id). */\n apply(view: SavedView | string): void {\n const v = typeof view === 'string' ? this.views.find((x) => x.id === view) : view;\n if (!v || this.emit('before-apply', v) === false) return;\n this.current = v;\n this.setState(v.state);\n this.paint();\n this.emit('apply', v);\n }\n\n /** Saves the current setup into the active view; with none active, asks for a name first. */\n async save(): Promise<void> {\n if (!this.current) return this.saveAs();\n await this.store({ ...this.current, state: this.getState() });\n }\n\n /** Saves the current setup as a view with that name (asked for when omitted); an existing name is overwritten. */\n async saveAs(name?: string): Promise<void> {\n name ??= (await MessageBox.prompt(t('viewsName'), { title: t('viewsSaveAs') })) ?? '';\n name = name.trim();\n if (!name) return;\n const same = this.views.find((v) => v.name.toLowerCase() === name!.toLowerCase());\n await this.store({ ...same, name, state: this.getState() });\n }\n\n /** Marks the active view as the one applied on open (and unmarks the others). */\n async setDefault(on = true): Promise<void> {\n if (!this.current) return;\n for (const v of this.views) if (v !== this.current && v.default) await this.store({ ...v, default: false }, false);\n await this.store({ ...this.current, default: on });\n }\n\n async remove(view = this.current): Promise<void> {\n if (!view || !(await MessageBox.confirm(t('viewsConfirmDelete', { n: view.name }), { danger: true, okText: t('viewsDelete') }))) return;\n await this.run(async () => {\n await this.config.storage.remove(view);\n this.views = this.views.filter((v) => v !== view && v.id !== view.id);\n if (this.current?.id === view.id) this.current = undefined;\n this.paint();\n this.emit('remove', view);\n });\n }\n\n /** Back to the setup the grid had when the manager opened. */\n reset(): void {\n this.current = undefined;\n this.setState(this.initial);\n this.paint();\n this.emit('reset');\n }\n\n private async store(view: SavedView, makeCurrent = true): Promise<void> {\n await this.run(async () => {\n const saved = (await this.config.storage.save(view)) || view;\n const i = this.views.findIndex((v) => (saved.id && v.id === saved.id) || v === view);\n if (i < 0) this.views.push(saved);\n else this.views[i] = saved;\n if (makeCurrent) this.current = saved;\n this.paint();\n this.emit('save', saved);\n });\n }\n\n private async run(fn: () => Promise<void>): Promise<void> {\n try {\n await fn();\n } catch (err) {\n this.emit('error', err);\n }\n }\n\n // ---- UI ------------------------------------------------------------------------------------\n\n private paint(): void {\n this.btn.setText(this.current?.name ?? t('views'));\n }\n\n private openMenu(): void {\n const cur = this.current;\n const items: MenuEntry[] = [\n ...this.views.map((v) => ({ text: v.default ? `${v.name} \u2605` : v.name, checked: v === cur || (!!cur?.id && v.id === cur.id), handler: () => this.apply(v) })),\n ...(this.views.length ? (['-'] as const) : []),\n { text: t('viewsSave'), handler: () => void this.save() },\n { text: t('viewsSaveAs'), handler: () => void this.saveAs() },\n ...(cur ? [{ text: t('viewsDefault'), checked: !!cur.default, handler: () => void this.setDefault(!cur.default) }, { text: t('viewsDelete'), handler: () => void this.remove() }] : []),\n '-',\n { text: t('viewsReset'), handler: () => this.reset() },\n ];\n this.menu ??= new Menu({});\n this.menu.setItems(items);\n this.menu.showBy(this.btn.el);\n }\n}\nregister('viewmanager', ViewManager);\n"],
5
+ "mappings": "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",
6
+ "names": ["newId", "localViewStorage", "key", "storage", "read", "v", "write", "view", "saved", "all", "i", "x", "restViewStorage", "cfg", "call", "method", "path", "body", "res", "ViewManager", "Component", "Button", "t", "h", "grid", "filters", "extra", "state", "k", "e", "s", "sort", "def", "name", "MessageBox", "same", "on", "makeCurrent", "fn", "err", "cur", "items", "Menu", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as f}from"./chunk-4COBH4QJ.js";import{a as u}from"./chunk-ARCW54L2.js";import{a as h}from"./chunk-SNTHW4K2.js";import{f as o,g as p}from"./chunk-NWTTHDIM.js";import{c}from"./chunk-IHAYOSBR.js";import{b as l}from"./chunk-IYPKPLCU.js";import{b as d}from"./chunk-PZSHOSOS.js";import{e as n}from"./chunk-MA5BJL3S.js";var a=class extends h{baseCls="op-field op-textfield op-picker op-datefield";cal;dd;garbage=!1;emptyValue(){return null}isEmpty(e){return!e}parse(e){let t=p(e);return this.garbage=!!e.trim()&&!t,t}display(e){return e?o(e,{day:"2-digit",month:"2-digit",year:"numeric"}):""}createControl(){let e=super.createControl(),t=this.input;t.setAttribute("aria-haspopup","dialog"),t.setAttribute("aria-expanded","false");let r=d("button","op-picker__trigger",{type:"button",tabindex:-1,"aria-label":n("calOpen")},c("calendar"));this.listen(r,"mousedown",s=>s.preventDefault()),this.listen(r,"click",()=>{!this.config.disabled&&!this.config.readonly&&this.toggle()}),e.append(r);let i=this.config;return this.cal=new f({value:i.value,min:i.min,max:i.max,firstDay:i.firstDay}),this.dd=new u({anchor:e,content:this.cal,role:"presentation"}),this.cal.on("select",s=>{this.dd.close(),this.setValue(s),t.focus()}),this.dd.on("open",()=>{t.setAttribute("aria-expanded","true"),this.el.classList.add("is-open"),this.cal.setValue(this.value),this.cal.focusDay(),this.emit("expand")}),this.dd.on("close",()=>{t.setAttribute("aria-expanded","false"),this.el.classList.remove("is-open"),this.emit("collapse")}),this.own(()=>this.dd.destroy()),this.on("blur",()=>this.later(()=>{let s=document.activeElement;!this.el.contains(s)&&!this.dd.el.contains(s)&&this.dd.close()},0)),e}onKey(e){e.key==="ArrowDown"&&!this.dd.isOpen()?(e.preventDefault(),this.open()):super.onKey(e)}onInput(){super.onInput(),this.garbage?this.setError(n("date")):this.error&&this.validate()}applyValue(e){super.applyValue(e),this.garbage=!1}onDisabled(e){super.onDisabled(e),this.el.querySelector(".op-picker__trigger").disabled=e}check(){if(this.garbage)return n("date");let e=super.check(),t=this.value;if(e||!t)return e;let{min:r,max:i}=this.config;return r&&t<r?n("dateMin",{n:o(r)}):i&&t>i?n("dateMax",{n:o(i)}):""}open(){this.config.disabled||this.config.readonly||!this.rendered||this.dd.open()}close(){this.dd?.close()}toggle(){this.dd.isOpen()?this.close():this.open()}expand(){this.open()}collapse(){this.close()}setMin(e){this.config.min=e,this.cal?.setMin(e)}setMax(e){this.config.max=e,this.cal?.setMax(e)}};l("datefield",a);export{a};
2
+ //# sourceMappingURL=chunk-U3X2FW6U.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/fields/datefield/datefield.ts"],
4
+ "sourcesContent": ["import { TextField, type TextFieldConfig } from '../textfield/textfield';\nimport { register } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { t } from '../../../core/i18n';\nimport { parseDate, formatDate } from '../../../core/date';\nimport { iconEl } from '../../base/icon/icon';\nimport { Dropdown } from '../../overlays/dropdown/dropdown';\nimport { Calendar } from '../../dates/calendar/calendar';\n\nexport interface DateFieldConfig extends TextFieldConfig<string | null> {\n min?: string;\n max?: string;\n firstDay?: number;\n}\n\n/** Value is an ISO date string (`YYYY-MM-DD`) or null; the text shown and accepted follows the locale. */\nexport class DateField extends TextField<string | null, DateFieldConfig> {\n protected override baseCls = 'op-field op-textfield op-picker op-datefield';\n private cal!: Calendar;\n private dd!: Dropdown;\n private garbage = false;\n\n protected override emptyValue() {\n return null;\n }\n protected override isEmpty(v: string | null) {\n return !v;\n }\n\n protected override parse(text: string): string | null {\n const iso = parseDate(text);\n this.garbage = !!text.trim() && !iso;\n return iso;\n }\n protected override display(v: string | null) {\n return v ? formatDate(v, { day: '2-digit', month: '2-digit', year: 'numeric' }) : '';\n }\n\n protected override createControl() {\n const wrap = super.createControl();\n const input = this.input;\n input.setAttribute('aria-haspopup', 'dialog');\n input.setAttribute('aria-expanded', 'false');\n const trigger = h('button', 'op-picker__trigger', { type: 'button', tabindex: -1, 'aria-label': t('calOpen') }, iconEl('calendar'));\n this.listen(trigger, 'mousedown', (e: Event) => e.preventDefault());\n this.listen(trigger, 'click', () => {\n if (!this.config.disabled && !this.config.readonly) this.toggle();\n });\n wrap.append(trigger);\n const c = this.config;\n this.cal = new Calendar({ value: c.value, min: c.min, max: c.max, firstDay: c.firstDay });\n this.dd = new Dropdown({ anchor: wrap, content: this.cal, role: 'presentation' });\n this.cal.on('select', (iso: string) => {\n this.dd.close();\n this.setValue(iso);\n input.focus();\n });\n this.dd.on('open', () => {\n input.setAttribute('aria-expanded', 'true');\n this.el.classList.add('is-open');\n this.cal.setValue(this.value);\n this.cal.focusDay();\n this.emit('expand');\n });\n this.dd.on('close', () => {\n input.setAttribute('aria-expanded', 'false');\n this.el.classList.remove('is-open');\n this.emit('collapse');\n });\n this.own(() => this.dd.destroy());\n this.on('blur', () =>\n this.later(() => {\n const a = document.activeElement;\n if (!this.el.contains(a) && !this.dd.el.contains(a)) this.dd.close();\n }, 0),\n );\n return wrap;\n }\n\n protected override onKey(e: KeyboardEvent) {\n if (e.key === 'ArrowDown' && !this.dd.isOpen()) {\n e.preventDefault();\n this.open();\n } else super.onKey(e);\n }\n\n protected override onInput() {\n super.onInput();\n if (this.garbage) this.setError(t('date'));\n else if (this.error) this.validate();\n }\n protected override applyValue(v: string | null) {\n super.applyValue(v);\n this.garbage = false;\n }\n protected override onDisabled(disabled: boolean) {\n super.onDisabled(disabled);\n (this.el.querySelector('.op-picker__trigger') as HTMLButtonElement).disabled = disabled;\n }\n\n protected override check(): string {\n if (this.garbage) return t('date');\n const base = super.check();\n const v = this.value;\n if (base || !v) return base;\n const { min, max } = this.config;\n if (min && v < min) return t('dateMin', { n: formatDate(min) });\n if (max && v > max) return t('dateMax', { n: formatDate(max) });\n return '';\n }\n\n open() {\n if (this.config.disabled || this.config.readonly || !this.rendered) return;\n this.dd.open();\n }\n close() {\n this.dd?.close();\n }\n toggle() {\n if (this.dd.isOpen()) this.close();\n else this.open();\n }\n expand() {\n this.open();\n }\n collapse() {\n this.close();\n }\n setMin(min: string | undefined) {\n this.config.min = min;\n this.cal?.setMin(min);\n }\n setMax(max: string | undefined) {\n this.config.max = max;\n this.cal?.setMax(max);\n }\n}\nregister('datefield', DateField);\n"],
5
+ "mappings": "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",
6
+ "names": ["DateField", "TextField", "v", "text", "iso", "parseDate", "formatDate", "wrap", "input", "trigger", "h", "t", "iconEl", "e", "c", "Calendar", "Dropdown", "a", "disabled", "base", "min", "max", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as y,d as m}from"./chunk-IYPKPLCU.js";import{e as l}from"./chunk-PZSHOSOS.js";var g=new Map;function u(i,t){g.set(i,t)}function h(i){if(typeof i=="object"&&"init"in i)return i;let t=typeof i=="string"?{type:i}:i,o=g.get(t.type);if(!o)throw new Error(`Optikos: unknown layout "${t.type}"`);return o(t)}function c(i,t,o){let e=i.getBody(),n=!1,r=d=>{d!==n&&(n=d,e.classList.toggle("is-narrow",d),o?.(d),i.emit("narrow-change",d))};if(typeof ResizeObserver<"u"){let d=new ResizeObserver(()=>e.clientWidth>0&&r(e.clientWidth<t));d.observe(e),i.own(()=>d.disconnect())}return{isNarrow:()=>n,setNarrow:r}}var f=(i,t=[])=>o=>({init(e){let n=e.getBody();n.classList.add("op-layout",`op-layout-${i}`);for(let r of t)o[r]!=null&&n.style.setProperty(`--op-layout-${r}`,l(o[r]))}});u("fit",f("fit"));var w=f("hbox",["gap","align","justify","wrap"]);u("hbox",i=>{let t=w(i),o;return{...t,init(e){t.init(e),i.stackBelow&&(e.getBody().classList.add("op-layout-stack"),o=c(e,Number(i.stackBelow)))},isNarrow:()=>!!o?.isNarrow(),setNarrow:e=>o?.setNarrow(e)}});u("vbox",f("vbox",["gap","align","justify","wrap"]));u("grid",i=>{let t;return{init(o){let e=o.getBody();e.classList.add("op-layout","op-layout-grid"),i.gap!=null&&e.style.setProperty("--op-layout-gap",l(i.gap));let n=i.columns??1;if(typeof n=="number"){e.style.setProperty("--op-layout-columns",String(n));let r=i.narrowBelow==null?480:Number(i.narrowBelow);r>0&&n>1&&(t=c(o,r))}else e.style.gridTemplateColumns=n},add(o,e){let n=e.config.colspan;n&&(e.el.style.gridColumn=`span ${n}`)},isNarrow:()=>!!t?.isNarrow(),setNarrow:o=>t?.setNarrow(o)}});u("border",i=>{let t,o,e=()=>Array.from(o.getBody().children).filter(s=>s instanceof HTMLElement&&(s.dataset.region==="west"||s.dataset.region==="east")),n=s=>e().find(a=>a.dataset.region===s),r=()=>o.getBody().classList.toggle("has-open-region",e().some(s=>s.classList.contains("is-open"))),d=s=>{for(let a of e())(!s||a.dataset.region===s)&&a.classList.remove("is-open");r()};return{init(s){o=s;let a=s.getBody();a.classList.add("op-layout","op-layout-border"),i.gap!=null&&a.style.setProperty("--op-layout-gap",l(i.gap)),t=c(s,i.narrowBelow==null?768:Number(i.narrowBelow),p=>{p?i.open&&(n(String(i.open))?.classList.add("is-open"),r()):d()}),s.listen(a,"click",p=>p.target===a&&d()),s.listen(a,"keydown",p=>{p.key==="Escape"&&a.classList.contains("has-open-region")&&a.classList.contains("is-narrow")&&(p.stopPropagation(),d())})},add(s,a){let p=a.config.region??"center";a.el.style.gridArea=p,a.el.dataset.region=p},openRegion(s){let a=n(s);!a||!t?.isNarrow()||(d(),a.classList.add("is-open"),r(),(a.querySelector("input,button,[tabindex]")??a).focus?.())},closeRegion:d,toggleRegion(s){n(s)?.classList.contains("is-open")?d(s):this.openRegion(s)},isRegionOpen:s=>!!n(s)?.classList.contains("is-open"),isNarrow:()=>!!t?.isNarrow(),setNarrow:s=>t?.setNarrow(s)}});u("card",i=>{let t,o=(e,n)=>{t=n;for(let r of e.items)r.rendered?r.el.hidden=r!==n:r.config.hidden=r!==n;e.emit("activate",n)};return{init(e){e.getBody().classList.add("op-layout","op-layout-fit");let n=i.activeItem??e.config.activeItem??0;o(e,typeof n=="number"?e.items[n]:e.items.find(r=>r.id===n))},add(e,n){n.el.hidden=n!==t&&!!t,t||o(e,n)},remove(e,n,r){n===t&&o(e,e.items[Math.min(r,e.items.length-1)])},activate:o,getActive:()=>t}});var C=class i extends y{baseCls="op-container";defaultLayout;items=[];layout;constructor(t={}){super(t),this.items=(t.items??[]).map(o=>this.make(o))}getBody(){return this.el}shorthand(t){throw new Error(`Optikos: no shorthand for item "${t}" in ${this.baseCls}`)}make(t){typeof t=="string"&&(t=this.shorthand(t));let o=t instanceof y?t:m({type:this.config.defaultType,...this.config.defaults,...t});return o.parent=this,o}onRender(){let t=this.config.layout??this.defaultLayout;t&&(this.layout=h(t)).init(this),this.items.forEach((o,e)=>this.attach(o,e))}attach(t,o){let e=this.getBody(),n=this.items.slice(o+1).find(r=>r.rendered&&r.el.parentNode===e);e.insertBefore(t.el,n?.el??null),this.layout?.add?.(this,t,o),this.mounted&&t.notifyMount()}add(t){return this.insert(this.items.length,t)}insert(t,o){let e=this.make(o);return this.items.splice(t,0,e),this.rendered&&this.attach(e,t),this.emit("add",e),e}remove(t,o=!0){let e=typeof t=="number"?t:this.items.findIndex(r=>r===t||r.id===t),n=this.items[e];if(n)return this.items.splice(e,1),n.parent=void 0,this.layout?.remove?.(this,n,e),o?n.destroy():n.rendered&&n.el.remove(),this.emit("remove",n),n}removeAll(t=!0){for(let o of[...this.items])this.remove(o,t)}getItems(){return this.items}get(t){return this.items.find(o=>o.id===t)}query(t){let o=[];for(let e of this.items)t(e)&&o.push(e),e instanceof i&&o.push(...e.query(t));return o}getActiveItem(){return this.layout?.getActive?.(this)}setActiveItem(t){let o=typeof t=="number"?this.items[t]:this.items.find(e=>e===t||e.id===t);o&&this.layout?.activate?.(this,o)}notifyMount(){super.notifyMount();for(let t of this.items)t.notifyMount()}onDestroy(){for(let t of[...this.items])t.destroy()}setDisabled(t){super.setDisabled(t);for(let o of this.items)o.setDisabled(t)}};export{u as a,h as b,C as c};
2
+ //# sourceMappingURL=chunk-UPOBGNJ5.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/layout/layout.ts", "../src/core/container.ts"],
4
+ "sourcesContent": ["import type { Component } from '../core/component';\nimport type { Container } from '../core/container';\nimport { px } from '../core/dom';\n\nexport interface Layout {\n init(c: Container): void;\n add?(c: Container, cmp: Component, index: number): void;\n remove?(c: Container, cmp: Component, index: number): void;\n /** Card only. */\n activate?(c: Container, cmp: Component): void;\n getActive?(c: Container): Component | undefined;\n /** Border only: below `narrowBelow` the west/east regions become drawers; these open and close them. */\n openRegion?(name: string): void;\n closeRegion?(name?: string): void;\n toggleRegion?(name: string): void;\n isRegionOpen?(name: string): boolean;\n /** Layouts that adapt to the width: whether the container is currently narrow, and a way to force it (tests, previews). */\n isNarrow?(): boolean;\n setNarrow?(narrow: boolean): void;\n}\n\nexport type LayoutConfig = { type: string; [option: string]: unknown };\nexport type LayoutSpec = string | LayoutConfig | Layout;\nexport type LayoutFactory = (config: Record<string, any>) => Layout;\n\nconst factories = new Map<string, LayoutFactory>();\n\n/** Registers a layout strategy under a name; users add their own the same way. */\nexport function registerLayout(name: string, factory: LayoutFactory): void {\n factories.set(name, factory);\n}\n\nexport function createLayout(spec: LayoutSpec): Layout {\n if (typeof spec === 'object' && 'init' in spec) return spec as Layout;\n const cfg = (typeof spec === 'string' ? { type: spec } : spec) as LayoutConfig;\n const f = factories.get(cfg.type);\n if (!f) throw new Error(`Optikos: unknown layout \"${cfg.type}\"`);\n return f(cfg);\n}\n\n/**\n * Keeps the class `is-narrow` on the container body while it is narrower than `below` px (a ResizeObserver on the\n * container itself, not the window, so a layout inside a small panel adapts too). Emits `narrow-change` on the container.\n */\nfunction watchNarrow(c: Container, below: number, on?: (narrow: boolean) => void) {\n const body = c.getBody();\n let narrow = false;\n const set = (n: boolean) => {\n if (n === narrow) return;\n narrow = n;\n body.classList.toggle('is-narrow', n);\n on?.(n);\n c.emit('narrow-change', n);\n };\n if (typeof ResizeObserver !== 'undefined') {\n const ro = new ResizeObserver(() => body.clientWidth > 0 && set(body.clientWidth < below));\n ro.observe(body);\n c.own(() => ro.disconnect());\n }\n return { isNarrow: () => narrow, setNarrow: set };\n}\n\n/** Layouts that are only a class plus custom properties; the CSS does the work. */\nconst cssLayout =\n (name: string, vars: string[] = []): LayoutFactory =>\n (cfg) => ({\n init(c) {\n const body = c.getBody();\n body.classList.add('op-layout', `op-layout-${name}`);\n for (const v of vars) if (cfg[v] != null) body.style.setProperty(`--op-layout-${v}`, px(cfg[v]));\n },\n });\n\nregisterLayout('fit', cssLayout('fit'));\nconst hbox = cssLayout('hbox', ['gap', 'align', 'justify', 'wrap']);\n/** `stackBelow: 600`: under that width the row becomes a column. */\nregisterLayout('hbox', (cfg) => {\n const base = hbox(cfg);\n let w: ReturnType<typeof watchNarrow> | undefined;\n return {\n ...base,\n init(c) {\n base.init(c);\n if (cfg.stackBelow) {\n c.getBody().classList.add('op-layout-stack');\n w = watchNarrow(c, Number(cfg.stackBelow));\n }\n },\n isNarrow: () => !!w?.isNarrow(),\n setNarrow: (n) => w?.setNarrow(n),\n };\n});\nregisterLayout('vbox', cssLayout('vbox', ['gap', 'align', 'justify', 'wrap']));\n\n/** Numeric `columns` collapse to one column under `narrowBelow` px (default 480; `0` turns it off). */\nregisterLayout('grid', (cfg) => {\n let w: ReturnType<typeof watchNarrow> | undefined;\n return {\n init(c) {\n const body = c.getBody();\n body.classList.add('op-layout', 'op-layout-grid');\n if (cfg.gap != null) body.style.setProperty('--op-layout-gap', px(cfg.gap));\n const cols = cfg.columns ?? 1;\n if (typeof cols === 'number') {\n body.style.setProperty('--op-layout-columns', String(cols));\n const below = cfg.narrowBelow == null ? 480 : Number(cfg.narrowBelow);\n if (below > 0 && cols > 1) w = watchNarrow(c, below);\n } else body.style.gridTemplateColumns = cols;\n },\n add(_c, cmp) {\n const span = cmp.config.colspan;\n if (span) cmp.el.style.gridColumn = `span ${span}`;\n },\n isNarrow: () => !!w?.isNarrow(),\n setNarrow: (n) => w?.setNarrow(n),\n };\n});\n\n/**\n * Regions around a center. Under `narrowBelow` px (default 768) the west and east regions leave the grid and become\n * drawers over the center, closed until `openRegion('west')` (or `open: 'west'` in the layout config, to start open).\n * A scrim behind an open drawer closes it on click; Esc closes it too.\n */\nregisterLayout('border', (cfg) => {\n let w: ReturnType<typeof watchNarrow> | undefined;\n let cont!: Container;\n const regions = () => Array.from(cont.getBody().children).filter((e): e is HTMLElement => e instanceof HTMLElement && (e.dataset.region === 'west' || e.dataset.region === 'east'));\n const find = (name: string) => regions().find((e) => e.dataset.region === name);\n const sync = () => cont.getBody().classList.toggle('has-open-region', regions().some((e) => e.classList.contains('is-open')));\n const close = (name?: string) => {\n for (const e of regions()) if (!name || e.dataset.region === name) e.classList.remove('is-open');\n sync();\n };\n return {\n init(c) {\n cont = c;\n const body = c.getBody();\n body.classList.add('op-layout', 'op-layout-border');\n if (cfg.gap != null) body.style.setProperty('--op-layout-gap', px(cfg.gap));\n w = watchNarrow(c, cfg.narrowBelow == null ? 768 : Number(cfg.narrowBelow), (narrow) => {\n if (!narrow) close();\n else if (cfg.open) find(String(cfg.open))?.classList.add('is-open'), sync();\n });\n // the scrim is the body's own ::after: a click that lands on the body itself (not a child) closes the drawer\n c.listen(body, 'click', (e: Event) => e.target === body && close());\n c.listen(body, 'keydown', (e: KeyboardEvent) => {\n if (e.key === 'Escape' && body.classList.contains('has-open-region') && body.classList.contains('is-narrow')) {\n e.stopPropagation();\n close();\n }\n });\n },\n add(_c, cmp) {\n const region = cmp.config.region ?? 'center';\n cmp.el.style.gridArea = region;\n cmp.el.dataset.region = region;\n },\n openRegion(name) {\n const e = find(name);\n if (!e || !w?.isNarrow()) return;\n close();\n e.classList.add('is-open');\n sync();\n (e.querySelector<HTMLElement>('input,button,[tabindex]') ?? e).focus?.();\n },\n closeRegion: close,\n toggleRegion(name) {\n if (find(name)?.classList.contains('is-open')) close(name);\n else this.openRegion!(name);\n },\n isRegionOpen: (name) => !!find(name)?.classList.contains('is-open'),\n isNarrow: () => !!w?.isNarrow(),\n setNarrow: (n) => w?.setNarrow(n),\n };\n});\n\nregisterLayout('card', (cfg) => {\n let active: Component | undefined;\n // children that were never rendered (lazy tabs) only get the flag; their DOM is not built just to hide it\n const show = (c: Container, cmp: Component | undefined) => {\n active = cmp;\n for (const i of c.items) {\n if (i.rendered) i.el.hidden = i !== cmp;\n else i.config.hidden = i !== cmp;\n }\n c.emit('activate', cmp);\n };\n return {\n init(c) {\n c.getBody().classList.add('op-layout', 'op-layout-fit');\n const a = cfg.activeItem ?? c.config.activeItem ?? 0;\n show(c, typeof a === 'number' ? c.items[a] : c.items.find((i) => i.id === a));\n },\n add(c, cmp) {\n cmp.el.hidden = cmp !== active && !!active;\n if (!active) show(c, cmp);\n },\n remove(c, cmp, index) {\n if (cmp === active) show(c, c.items[Math.min(index, c.items.length - 1)]);\n },\n activate: show,\n getActive: () => active,\n };\n});\n", "import { Component, type ComponentConfig, type Parent } from './component';\nimport { create, type AnyConfig } from './registry';\nimport { createLayout, type Layout, type LayoutSpec } from '../layout/layout';\n\nexport interface ContainerConfig extends ComponentConfig {\n items?: Array<AnyConfig | Component | string>;\n layout?: LayoutSpec;\n /** Config merged into every item that does not set the key itself. */\n defaults?: Record<string, unknown>;\n /** `type` used by items that do not declare one. */\n defaultType?: string;\n /** Layout `card`: initial visible child (index or id). */\n activeItem?: number | string;\n}\n\nexport class Container<C extends ContainerConfig = ContainerConfig> extends Component<C> implements Parent {\n protected override baseCls = 'op-container';\n protected defaultLayout: LayoutSpec | undefined;\n items: Component[] = [];\n layout?: Layout;\n\n constructor(config: C = {} as C) {\n super(config);\n this.items = (config.items ?? []).map((i) => this.make(i));\n }\n\n /** Element that holds the children. Panels override it. */\n getBody(): HTMLElement {\n return this.el;\n }\n\n /** Turns shorthand strings (`'->'`) into configs. Subclasses override; the base has none. */\n protected shorthand(s: string): AnyConfig {\n throw new Error(`Optikos: no shorthand for item \"${s}\" in ${this.baseCls}`);\n }\n\n private make(item: AnyConfig | Component | string): Component {\n if (typeof item === 'string') item = this.shorthand(item);\n const c = item instanceof Component ? item : create({ type: this.config.defaultType, ...this.config.defaults, ...item });\n c.parent = this;\n return c;\n }\n\n protected override onRender(): void {\n const spec = this.config.layout ?? this.defaultLayout;\n if (spec) (this.layout = createLayout(spec)).init(this);\n this.items.forEach((c, i) => this.attach(c, i));\n }\n\n protected attach(c: Component, index: number): void {\n const body = this.getBody();\n const next = this.items.slice(index + 1).find((x) => x.rendered && x.el.parentNode === body);\n body.insertBefore(c.el, next?.el ?? null);\n this.layout?.add?.(this, c, index);\n if (this.mounted) c.notifyMount();\n }\n\n add(item: AnyConfig | Component | string): Component {\n return this.insert(this.items.length, item);\n }\n\n insert(index: number, item: AnyConfig | Component | string): Component {\n const c = this.make(item);\n this.items.splice(index, 0, c);\n if (this.rendered) this.attach(c, index);\n this.emit('add', c);\n return c;\n }\n\n /** Removes a child (by instance, id or index). Destroys it unless `destroy` is `false`. */\n remove(child: Component | string | number, destroy = true): Component | undefined {\n const i = typeof child === 'number' ? child : this.items.findIndex((c) => c === child || c.id === child);\n const c = this.items[i];\n if (!c) return;\n this.items.splice(i, 1);\n c.parent = undefined;\n this.layout?.remove?.(this, c, i);\n if (destroy) c.destroy();\n else if (c.rendered) c.el.remove();\n this.emit('remove', c);\n return c;\n }\n\n removeAll(destroy = true): void {\n for (const c of [...this.items]) this.remove(c, destroy);\n }\n\n getItems(): Component[] {\n return this.items;\n }\n\n /** Direct child by id. */\n get(id: string): Component | undefined {\n return this.items.find((c) => c.id === id);\n }\n\n /** All descendants (depth-first) matching `fn`. */\n query(fn: (c: Component) => boolean): Component[] {\n const out: Component[] = [];\n for (const c of this.items) {\n if (fn(c)) out.push(c);\n if (c instanceof Container) out.push(...c.query(fn));\n }\n return out;\n }\n\n /** Layout `card`: which child is visible. */\n getActiveItem(): Component | undefined {\n return this.layout?.getActive?.(this);\n }\n setActiveItem(item: Component | string | number): void {\n const c = typeof item === 'number' ? this.items[item] : this.items.find((x) => x === item || x.id === item);\n if (c) this.layout?.activate?.(this, c);\n }\n\n override notifyMount(): void {\n super.notifyMount();\n for (const c of this.items) c.notifyMount();\n }\n\n protected override onDestroy(): void {\n for (const c of [...this.items]) c.destroy();\n }\n\n override setDisabled(disabled: boolean): void {\n super.setDisabled(disabled);\n for (const c of this.items) c.setDisabled(disabled);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["factories", "registerLayout", "name", "factory", "createLayout", "spec", "cfg", "f", "watchNarrow", "c", "below", "on", "body", "narrow", "set", "n", "ro", "cssLayout", "vars", "v", "px", "hbox", "base", "w", "cols", "_c", "cmp", "span", "cont", "regions", "e", "find", "sync", "close", "region", "active", "show", "i", "a", "index", "Container", "_Container", "Component", "config", "i", "s", "item", "c", "create", "spec", "createLayout", "index", "body", "next", "x", "child", "destroy", "id", "fn", "out", "disabled"]
7
+ }
@@ -0,0 +1,2 @@
1
+ var E='a[href],button:not([disabled]),input:not([disabled]):not([type=hidden]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';function L(t){return Array.from(t.querySelectorAll(E)).filter(r=>!r.hidden&&!r.closest("[hidden],[inert]"))}function h(t){let r=o=>{if(o.key!=="Tab")return;let l=L(t);if(!l.length)return o.preventDefault();let f=l[0],c=l[l.length-1],a=document.activeElement;o.shiftKey&&(a===f||!t.contains(a))?(o.preventDefault(),c.focus()):!o.shiftKey&&(a===c||!t.contains(a))&&(o.preventDefault(),f.focus())};return t.addEventListener("keydown",r),()=>t.removeEventListener("keydown",r)}function b(t,r){let{orientation:o="horizontal",loop:l=!0}=r,f=()=>Array.from(t.querySelectorAll(r.selector)).filter(e=>e.getAttribute("aria-disabled")!=="true"&&!e.hidden),c=e=>{let n=f(),s=e&&n.includes(e)?e:n.find(d=>d.tabIndex===0)??n[0];for(let d of Array.from(t.querySelectorAll(r.selector)))d.tabIndex=d===s?0:-1},a=e=>{let n=f(),s=n.indexOf(e.target.closest(r.selector));if(s<0)return;let d=o==="vertical"?"ArrowUp":o==="horizontal"?"ArrowLeft":null,v=o==="vertical"?"ArrowDown":o==="horizontal"?"ArrowRight":null,y=e.key===d||o==="both"&&(e.key==="ArrowUp"||e.key==="ArrowLeft"),m=e.key===v||o==="both"&&(e.key==="ArrowDown"||e.key==="ArrowRight"),i=-1;y?i=s>0?s-1:l?n.length-1:0:m?i=s<n.length-1?s+1:l?0:s:e.key==="Home"?i=0:e.key==="End"&&(i=n.length-1),!(i<0)&&(e.preventDefault(),c(n[i]),n[i].focus(),r.onMove?.(n[i]))},u=e=>{let n=e.target.closest(r.selector);n&&c(n)};return t.addEventListener("keydown",a),t.addEventListener("focusin",u),c(),{sync:c,destroy(){t.removeEventListener("keydown",a),t.removeEventListener("focusin",u)}}}export{L as a,h as b,b as c};
2
+ //# sourceMappingURL=chunk-VV7CFMPZ.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/core/focus.ts"],
4
+ "sourcesContent": ["const FOCUSABLE = 'a[href],button:not([disabled]),input:not([disabled]):not([type=hidden]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\n\nexport function focusables(root: HTMLElement): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE)).filter((e) => !e.hidden && !e.closest('[hidden],[inert]'));\n}\n\n/** Keeps Tab inside `root`. Returns the release function. */\nexport function trapFocus(root: HTMLElement): () => void {\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== 'Tab') return;\n const list = focusables(root);\n if (!list.length) return e.preventDefault();\n const first = list[0];\n const last = list[list.length - 1];\n const active = document.activeElement;\n if (e.shiftKey && (active === first || !root.contains(active))) (e.preventDefault(), last.focus());\n else if (!e.shiftKey && (active === last || !root.contains(active))) (e.preventDefault(), first.focus());\n };\n root.addEventListener('keydown', onKey);\n return () => root.removeEventListener('keydown', onKey);\n}\n\nexport interface RovingOptions {\n /** Selector of the items inside the container. */\n selector: string;\n orientation?: 'horizontal' | 'vertical' | 'both';\n /** Wrap around at the ends. Default true. */\n loop?: boolean;\n /** Called when an arrow/Home/End key moves focus to an item. */\n onMove?: (item: HTMLElement) => void;\n}\n\n/** Roving tabindex: one item is the Tab stop, arrows/Home/End move focus. Returns `{ sync, destroy }`. */\nexport function roving(container: HTMLElement, o: RovingOptions) {\n const { orientation = 'horizontal', loop = true } = o;\n const items = () => Array.from(container.querySelectorAll<HTMLElement>(o.selector)).filter((e) => e.getAttribute('aria-disabled') !== 'true' && !e.hidden);\n const stop = (target?: HTMLElement) => {\n const list = items();\n const t = target && list.includes(target) ? target : (list.find((e) => e.tabIndex === 0) ?? list[0]);\n for (const e of Array.from(container.querySelectorAll<HTMLElement>(o.selector))) e.tabIndex = e === t ? 0 : -1;\n };\n const onKey = (e: KeyboardEvent) => {\n const list = items();\n const i = list.indexOf((e.target as HTMLElement).closest<HTMLElement>(o.selector)!);\n if (i < 0) return;\n const prev = orientation === 'vertical' ? 'ArrowUp' : orientation === 'horizontal' ? 'ArrowLeft' : null;\n const next = orientation === 'vertical' ? 'ArrowDown' : orientation === 'horizontal' ? 'ArrowRight' : null;\n const isPrev = e.key === prev || (orientation === 'both' && (e.key === 'ArrowUp' || e.key === 'ArrowLeft'));\n const isNext = e.key === next || (orientation === 'both' && (e.key === 'ArrowDown' || e.key === 'ArrowRight'));\n let j = -1;\n if (isPrev) j = i > 0 ? i - 1 : loop ? list.length - 1 : 0;\n else if (isNext) j = i < list.length - 1 ? i + 1 : loop ? 0 : i;\n else if (e.key === 'Home') j = 0;\n else if (e.key === 'End') j = list.length - 1;\n if (j < 0) return;\n e.preventDefault();\n stop(list[j]);\n list[j].focus();\n o.onMove?.(list[j]);\n };\n const onFocus = (e: FocusEvent) => {\n const item = (e.target as HTMLElement).closest<HTMLElement>(o.selector);\n if (item) stop(item);\n };\n container.addEventListener('keydown', onKey);\n container.addEventListener('focusin', onFocus);\n stop();\n return {\n /** Re-evaluates the tab stop (after items change). Pass the item that should be the stop. */\n sync: stop,\n destroy() {\n container.removeEventListener('keydown', onKey);\n container.removeEventListener('focusin', onFocus);\n },\n };\n}\n"],
5
+ "mappings": "AAAA,IAAMA,EAAY,0JAEX,SAASC,EAAWC,EAAkC,CAC3D,OAAO,MAAM,KAAKA,EAAK,iBAA8BF,CAAS,CAAC,EAAE,OAAQG,GAAM,CAACA,EAAE,QAAU,CAACA,EAAE,QAAQ,kBAAkB,CAAC,CAC5H,CAGO,SAASC,EAAUF,EAA+B,CACvD,IAAMG,EAASF,GAAqB,CAClC,GAAIA,EAAE,MAAQ,MAAO,OACrB,IAAMG,EAAOL,EAAWC,CAAI,EAC5B,GAAI,CAACI,EAAK,OAAQ,OAAOH,EAAE,eAAe,EAC1C,IAAMI,EAAQD,EAAK,CAAC,EACdE,EAAOF,EAAKA,EAAK,OAAS,CAAC,EAC3BG,EAAS,SAAS,cACpBN,EAAE,WAAaM,IAAWF,GAAS,CAACL,EAAK,SAASO,CAAM,IAAKN,EAAE,eAAe,EAAGK,EAAK,MAAM,GACvF,CAACL,EAAE,WAAaM,IAAWD,GAAQ,CAACN,EAAK,SAASO,CAAM,KAAKN,EAAE,eAAe,EAAGI,EAAM,MAAM,EACxG,EACA,OAAAL,EAAK,iBAAiB,UAAWG,CAAK,EAC/B,IAAMH,EAAK,oBAAoB,UAAWG,CAAK,CACxD,CAaO,SAASK,EAAOC,EAAwBC,EAAkB,CAC/D,GAAM,CAAE,YAAAC,EAAc,aAAc,KAAAC,EAAO,EAAK,EAAIF,EAC9CG,EAAQ,IAAM,MAAM,KAAKJ,EAAU,iBAA8BC,EAAE,QAAQ,CAAC,EAAE,OAAQ,GAAM,EAAE,aAAa,eAAe,IAAM,QAAU,CAAC,EAAE,MAAM,EACnJI,EAAQC,GAAyB,CACrC,IAAMX,EAAOS,EAAM,EACbG,EAAID,GAAUX,EAAK,SAASW,CAAM,EAAIA,EAAUX,EAAK,KAAMH,GAAMA,EAAE,WAAa,CAAC,GAAKG,EAAK,CAAC,EAClG,QAAWH,KAAK,MAAM,KAAKQ,EAAU,iBAA8BC,EAAE,QAAQ,CAAC,EAAGT,EAAE,SAAWA,IAAMe,EAAI,EAAI,EAC9G,EACMb,EAAS,GAAqB,CAClC,IAAMC,EAAOS,EAAM,EACbI,EAAIb,EAAK,QAAS,EAAE,OAAuB,QAAqBM,EAAE,QAAQ,CAAE,EAClF,GAAIO,EAAI,EAAG,OACX,IAAMC,EAAOP,IAAgB,WAAa,UAAYA,IAAgB,aAAe,YAAc,KAC7FQ,EAAOR,IAAgB,WAAa,YAAcA,IAAgB,aAAe,aAAe,KAChGS,EAAS,EAAE,MAAQF,GAASP,IAAgB,SAAW,EAAE,MAAQ,WAAa,EAAE,MAAQ,aACxFU,EAAS,EAAE,MAAQF,GAASR,IAAgB,SAAW,EAAE,MAAQ,aAAe,EAAE,MAAQ,cAC5FW,EAAI,GACJF,EAAQE,EAAIL,EAAI,EAAIA,EAAI,EAAIL,EAAOR,EAAK,OAAS,EAAI,EAChDiB,EAAQC,EAAIL,EAAIb,EAAK,OAAS,EAAIa,EAAI,EAAIL,EAAO,EAAIK,EACrD,EAAE,MAAQ,OAAQK,EAAI,EACtB,EAAE,MAAQ,QAAOA,EAAIlB,EAAK,OAAS,GACxC,EAAAkB,EAAI,KACR,EAAE,eAAe,EACjBR,EAAKV,EAAKkB,CAAC,CAAC,EACZlB,EAAKkB,CAAC,EAAE,MAAM,EACdZ,EAAE,SAASN,EAAKkB,CAAC,CAAC,EACpB,EACMC,EAAW,GAAkB,CACjC,IAAMC,EAAQ,EAAE,OAAuB,QAAqBd,EAAE,QAAQ,EAClEc,GAAMV,EAAKU,CAAI,CACrB,EACA,OAAAf,EAAU,iBAAiB,UAAWN,CAAK,EAC3CM,EAAU,iBAAiB,UAAWc,CAAO,EAC7CT,EAAK,EACE,CAEL,KAAMA,EACN,SAAU,CACRL,EAAU,oBAAoB,UAAWN,CAAK,EAC9CM,EAAU,oBAAoB,UAAWc,CAAO,CAClD,CACF,CACF",
6
+ "names": ["FOCUSABLE", "focusables", "root", "e", "trapFocus", "onKey", "list", "first", "last", "active", "roving", "container", "o", "orientation", "loop", "items", "stop", "target", "t", "i", "prev", "next", "isPrev", "isNext", "j", "onFocus", "item"]
7
+ }
@@ -0,0 +1,2 @@
1
+ var l=class{constructor(t=[]){this.rows=t}rows;read(){return{data:[...this.rows],total:this.rows.length}}},u=(s,t)=>t.split(".").reduce((a,r)=>a?.[r],s),p=class{constructor(t){this.cfg=t}cfg;async call(t,a){let r=await(this.cfg.fetch??fetch)(t,{...a,headers:{"Content-Type":"application/json",...this.cfg.headers}});if(!r.ok)throw new Error(`Optikos RestProxy: ${a.method??"GET"} ${t} \u2192 ${r.status}`);return r}itemUrl(t){return`${this.cfg.url.replace(/\/$/,"")}/${encodeURIComponent(t[this.cfg.idField??"id"])}`}async read(t,a){let{page:r,pageSize:c,sorters:d,filters:h,...n}=t,i=new URLSearchParams;r&&i.set("page",String(r)),c&&i.set("pageSize",String(c)),d?.length&&i.set("sort",d.map(e=>`${e.field}:${e.dir}`).join(","));for(let e of h??[])"filters"in e||Array.isArray(e.value)?i.append("filter",JSON.stringify(e)):i.set(!e.op||e.op==="eq"?e.field:`${e.field}__${e.op}`,String(e.value??""));for(let e in n)n[e]!=null&&i.set(e,String(n[e]));let f=i.toString(),y=await this.call(this.cfg.url+(f?(this.cfg.url.includes("?")?"&":"?")+f:""),{signal:a}),o=await y.json(),g=this.cfg.root?u(o,this.cfg.root):Array.isArray(o)?o:o.data??[],m=Number(y.headers.get("X-Total-Count")),T=this.cfg.totalKey?Number(u(o,this.cfg.totalKey)):m||g.length;return{data:g,total:T}}async create(t){return await(await this.call(this.cfg.url,{method:"POST",body:JSON.stringify(t)})).json()}async update(t){return await(await this.call(this.itemUrl(t),{method:"PUT",body:JSON.stringify(t)})).json().catch(()=>{})}async destroy(t){await this.call(this.itemUrl(t),{method:"DELETE"})}};export{l as a,p as b};
2
+ //# sourceMappingURL=chunk-X2ASKUFD.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/data/proxy.ts"],
4
+ "sourcesContent": ["export interface Sorter {\n field: string;\n dir: 'asc' | 'desc';\n}\nexport type FilterOp =\n | 'eq' | 'ne' | 'contains' | 'notContains' | 'startsWith' | 'endsWith'\n | 'gt' | 'ge' | 'lt' | 'le' | 'between' | 'notBetween' | 'in' | 'nin' | 'empty' | 'notEmpty';\nexport interface FilterSpec {\n field: string;\n op?: FilterOp;\n /** `between`/`notBetween`: `[from, to]`; `in`/`nin`: an array; `empty`/`notEmpty`: ignored. */\n value?: unknown;\n}\n/** A group of filters joined by AND or OR; groups nest. */\nexport interface FilterGroup {\n op: 'and' | 'or';\n filters: FilterNode[];\n}\nexport type FilterNode = FilterSpec | FilterGroup;\nexport interface ReadParams {\n page?: number;\n pageSize?: number;\n sorters?: Sorter[];\n filters?: FilterNode[];\n [extra: string]: unknown;\n}\nexport interface ReadResult<T = any> {\n data: T[];\n total?: number;\n}\n\n/** Where a Store gets (and writes) its data. Memory, function and REST implementations share this shape. */\nexport interface Proxy<T = any> {\n read(params: ReadParams, signal?: AbortSignal): Promise<ReadResult<T> | T[]> | ReadResult<T> | T[];\n create?(data: T): Promise<Partial<T> | void>;\n update?(data: T): Promise<Partial<T> | void>;\n destroy?(data: T): Promise<void>;\n}\n\nexport class MemoryProxy<T = any> implements Proxy<T> {\n constructor(public rows: T[] = []) {}\n read(): ReadResult<T> {\n return { data: [...this.rows], total: this.rows.length };\n }\n}\n\nexport interface RestProxyConfig {\n url: string;\n idField?: string;\n headers?: Record<string, string>;\n /** Dotted path of the rows in the JSON when it is an object (`'items'`, `'data.rows'`). */\n root?: string;\n /** Dotted path of the total count in the JSON. Falls back to the `X-Total-Count` header, then to the row count. */\n totalKey?: string;\n fetch?: typeof fetch;\n}\n\nconst path = (o: any, p: string) => p.split('.').reduce((v, k) => v?.[k], o);\n\n/** REST over `fetch`: `GET url?page&pageSize&sort=a:asc,b:desc&field=value`, `POST url`, `PUT url/:id`, `DELETE url/:id`. */\nexport class RestProxy<T extends Record<string, any> = any> implements Proxy<T> {\n constructor(private cfg: RestProxyConfig) {}\n\n private async call(url: string, init: RequestInit): Promise<Response> {\n const res = await (this.cfg.fetch ?? fetch)(url, { ...init, headers: { 'Content-Type': 'application/json', ...this.cfg.headers } });\n if (!res.ok) throw new Error(`Optikos RestProxy: ${init.method ?? 'GET'} ${url} \u2192 ${res.status}`);\n return res;\n }\n\n private itemUrl(d: T) {\n return `${this.cfg.url.replace(/\\/$/, '')}/${encodeURIComponent(d[this.cfg.idField ?? 'id'])}`;\n }\n\n async read(params: ReadParams, signal?: AbortSignal): Promise<ReadResult<T>> {\n const { page, pageSize, sorters, filters, ...extra } = params;\n const q = new URLSearchParams();\n if (page) q.set('page', String(page));\n if (pageSize) q.set('pageSize', String(pageSize));\n if (sorters?.length) q.set('sort', sorters.map((s) => `${s.field}:${s.dir}`).join(','));\n for (const f of filters ?? []) {\n // simple specs map to `field__op=value`; groups and list/range values travel as JSON in `filter`\n if ('filters' in f || Array.isArray(f.value)) q.append('filter', JSON.stringify(f));\n else q.set(!f.op || f.op === 'eq' ? f.field : `${f.field}__${f.op}`, String(f.value ?? ''));\n }\n for (const k in extra) if (extra[k] != null) q.set(k, String(extra[k]));\n const qs = q.toString();\n const res = await this.call(this.cfg.url + (qs ? (this.cfg.url.includes('?') ? '&' : '?') + qs : ''), { signal });\n const json = await res.json();\n const data: T[] = this.cfg.root ? path(json, this.cfg.root) : Array.isArray(json) ? json : (json.data ?? []);\n const header = Number(res.headers.get('X-Total-Count'));\n const total = this.cfg.totalKey ? Number(path(json, this.cfg.totalKey)) : header || data.length;\n return { data, total };\n }\n\n async create(d: T) {\n return (await (await this.call(this.cfg.url, { method: 'POST', body: JSON.stringify(d) })).json()) as Partial<T>;\n }\n async update(d: T) {\n return (await (await this.call(this.itemUrl(d), { method: 'PUT', body: JSON.stringify(d) })).json().catch(() => undefined)) as Partial<T> | undefined;\n }\n async destroy(d: T) {\n await this.call(this.itemUrl(d), { method: 'DELETE' });\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["MemoryProxy", "rows", "path", "o", "p", "v", "k", "RestProxy", "cfg", "url", "init", "res", "d", "params", "signal", "page", "pageSize", "sorters", "filters", "extra", "q", "s", "f", "qs", "json", "data", "header", "total"]
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=chunk-X6AULZI4.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as f}from"./chunk-LMGCV35W.js";import{c as m}from"./chunk-JTYWZMSZ.js";import{e as p}from"./chunk-4AA4FQEM.js";import{a as c,b as d}from"./chunk-IYPKPLCU.js";import{b as a}from"./chunk-PZSHOSOS.js";import{e as l}from"./chunk-MA5BJL3S.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-XVIC24AW.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": "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",
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{a as c}from"./chunk-LBCWEWPN.js";import{c as h}from"./chunk-UPOBGNJ5.js";import{a as b}from"./chunk-XZEOSW3Q.js";import{c as a}from"./chunk-IHAYOSBR.js";import{b as p}from"./chunk-IYPKPLCU.js";import{b as i,c as r}from"./chunk-PZSHOSOS.js";import{e as l}from"./chunk-MA5BJL3S.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 t=this.config,e=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 ${t.bodyCls??""}`,{id:this.bodyId}),e.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 t.tbar&&e.append(o(t.tbar,"op-panel__tbar")),e.append(this.bodyEl),t.bbar&&e.append(o(t.bbar,"op-panel__bbar")),t.buttons&&e.append(o(["->",...t.buttons.map(s=>new b(s))],"op-panel__footer")),e}onRender(){super.onRender();let t=this.config;this.setTitle(t.title??""),this.setIcon(t.icon??"");for(let e of t.tools??[])this.addTool(e.icon,e.label,o=>e.handler?.(this,o));t.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())),t.closable&&this.addTool("x",l("close"),()=>this.close()),this.setCollapsed(!!t.collapsed),this.updateHeader()}addTool(t,e,o){let s=i("button","op-panel__tool",{type:"button","aria-label":e,"data-op-tip":e},a(t));return this.listen(s,"click",o),this.toolsEl.append(s),s}updateHeader(){let t=this.config;this.headerEl.hidden=!t.title&&!t.icon&&!t.collapsible&&!t.closable&&!t.tools?.length}setTitle(t){this.config.title=t,this.rendered&&(this.titleEl.textContent=t,this.updateHeader())}setIcon(t){this.config.icon=t,this.rendered&&(this.iconHost.replaceChildren(...t?[a(t)]:[]),this.iconHost.hidden=!t,this.updateHeader())}setCollapsed(t){if(this.config.collapsed=t,!!this.rendered){this.el.classList.toggle("is-collapsed",t);for(let e of[this.bodyEl,...this.bars.map(o=>o.el)])e.hidden=t;this.toggleBtn&&(this.toggleBtn.setAttribute("aria-expanded",String(!t)),this.toggleBtn.setAttribute("aria-label",l(t?"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(t=>t.destroy())}};p("panel",d);export{d as a};
2
+ //# sourceMappingURL=chunk-XZ5CUZZP.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 { 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 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.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.tools?.length;\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{g as r}from"./chunk-4AA4FQEM.js";import{c as l}from"./chunk-IHAYOSBR.js";import{a as o,b as n}from"./chunk-IYPKPLCU.js";import{b as i}from"./chunk-PZSHOSOS.js";var s=class extends o{baseCls="op-button";tag="button";textEl;busyTextEl;iconHost;build(){let t=this.config,e=i("button","op-button",{type:t.htmlType??"button"});return this.iconHost=i("span","op-button__icon"),this.textEl=i("span","op-button__text"),this.busyTextEl=i("span","op-button__busy-text"),e.append(i("span","op-button__face",{},this.iconHost,this.textEl),i("span","op-button__busy",{"aria-hidden":"true"},i("span","op-spinner op-button__spinner"),this.busyTextEl)),e}onRender(){let t=this.config;this.setText(t.text??""),this.setIcon(t.icon??""),this.setVariant(t.variant??"default"),this.setPressed(!!t.pressed),!t.text&&!t.ariaLabel&&!t.tooltip&&console.warn("Optikos: icon-only Button needs ariaLabel"),this.listen(this.el,"click",e=>{if(t.disabled||t.loading||(t.toggle&&(this.setPressed(!t.pressed),this.emit("toggle",t.pressed)),this.emit("click",e)===!1))return e.preventDefault();t.handler?.(this,e)})}onDisabled(t){this.el.disabled=t}setText(t){this.config.text=t,this.rendered&&(this.textEl.textContent=t,this.textEl.hidden=!t,this.busyTextEl.textContent=this.config.loadingText??t)}setIcon(t){this.config.icon=t,this.rendered&&(this.iconHost.replaceChildren(...t?[l(t)]:[]),this.iconHost.hidden=!t,this.el.classList.toggle("op-button--icon-right",this.config.iconPos==="right"))}setVariant(t){if(this.config.variant=t,!!this.rendered)for(let e of["default","primary","danger","ghost"])this.el.classList.toggle(`op-button--${e}`,e===t)}setPressed(t){this.config.pressed=t,this.rendered&&(this.el.classList.toggle("is-pressed",t),this.config.toggle&&this.el.setAttribute("aria-pressed",String(t)))}setLoading(t){this.config.loading=t,typeof t=="string"&&this.setLoadingText(t),this.rendered&&(this.el.classList.toggle("is-loading",!!t),t?this.el.setAttribute("aria-busy","true"):this.el.removeAttribute("aria-busy"))}setLoadingText(t){this.config.loadingText=t,this.rendered&&(this.busyTextEl.textContent=t)}pulse(){r(this.el)}click(){this.el.click()}};n("button",s);export{s as a};
2
+ //# sourceMappingURL=chunk-XZEOSW3Q.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/base/button/button.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';\nimport { pulse } from '../../../motion/core';\n\nexport interface ButtonConfig extends ComponentConfig {\n text?: string;\n icon?: string;\n iconPos?: 'left' | 'right';\n variant?: 'default' | 'primary' | 'danger' | 'ghost';\n htmlType?: 'button' | 'submit' | 'reset';\n handler?: (button: Button, ev: MouseEvent) => unknown;\n /** Behaves as a toggle button (`aria-pressed`). */\n toggle?: boolean;\n pressed?: boolean;\n /** Text shown while loading. Default: `text`. Passing a string to `loading` sets it too. */\n loadingText?: string;\n}\n\nexport class Button extends Component<ButtonConfig> {\n protected override baseCls = 'op-button';\n protected override tag = 'button' as const;\n private textEl!: HTMLElement;\n private busyTextEl!: HTMLElement;\n private iconHost!: HTMLElement;\n\n protected override build() {\n const c = this.config;\n const el = h('button', 'op-button', { type: c.htmlType ?? 'button' });\n this.iconHost = h('span', 'op-button__icon');\n this.textEl = h('span', 'op-button__text');\n // Two layers share one grid cell: the normal face and the loading face. The inactive one is hidden by CSS,\n // so the button is as wide as the wider of the two and never jumps when loading starts.\n this.busyTextEl = h('span', 'op-button__busy-text');\n el.append(\n h('span', 'op-button__face', {}, this.iconHost, this.textEl),\n h('span', 'op-button__busy', { 'aria-hidden': 'true' }, h('span', 'op-spinner op-button__spinner'), this.busyTextEl),\n );\n return el;\n }\n\n protected override onRender() {\n const c = this.config;\n this.setText(c.text ?? '');\n this.setIcon(c.icon ?? '');\n this.setVariant(c.variant ?? 'default');\n this.setPressed(!!c.pressed);\n if (!c.text && !c.ariaLabel && !c.tooltip) console.warn('Optikos: icon-only Button needs ariaLabel');\n this.listen(this.el, 'click', (e: MouseEvent) => {\n if (c.disabled || c.loading) return e.preventDefault();\n if (c.toggle) {\n this.setPressed(!c.pressed);\n this.emit('toggle', c.pressed);\n }\n if (this.emit('click', e) === false) return e.preventDefault();\n c.handler?.(this, e);\n });\n }\n\n protected override onDisabled(disabled: boolean) {\n (this.el as HTMLButtonElement).disabled = disabled;\n }\n\n setText(text: string) {\n this.config.text = text;\n if (!this.rendered) return;\n this.textEl.textContent = text;\n this.textEl.hidden = !text;\n this.busyTextEl.textContent = this.config.loadingText ?? text;\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.el.classList.toggle('op-button--icon-right', this.config.iconPos === 'right');\n }\n\n setVariant(variant: NonNullable<ButtonConfig['variant']>) {\n this.config.variant = variant;\n if (!this.rendered) return;\n for (const v of ['default', 'primary', 'danger', 'ghost']) this.el.classList.toggle(`op-button--${v}`, v === variant);\n }\n\n setPressed(pressed: boolean) {\n this.config.pressed = pressed;\n if (!this.rendered) return;\n this.el.classList.toggle('is-pressed', pressed);\n if (this.config.toggle) this.el.setAttribute('aria-pressed', String(pressed));\n }\n\n /** The button shows its own spinner (no mask) and ignores clicks while loading. A string is the loading text. */\n override setLoading(loading: boolean | string) {\n this.config.loading = loading;\n if (typeof loading === 'string') this.setLoadingText(loading);\n if (!this.rendered) return;\n this.el.classList.toggle('is-loading', !!loading);\n if (loading) this.el.setAttribute('aria-busy', 'true');\n else this.el.removeAttribute('aria-busy');\n }\n\n setLoadingText(text: string) {\n this.config.loadingText = text;\n if (this.rendered) this.busyTextEl.textContent = text;\n }\n\n /** A subtle ring that confirms the action worked (motion rule 8). */\n pulse(): void {\n void pulse(this.el);\n }\n\n click() {\n (this.el as HTMLButtonElement).click();\n }\n}\nregister('button', Button);\n"],
5
+ "mappings": "uKAoBO,IAAMA,EAAN,cAAqBC,CAAwB,CAC/B,QAAU,YACV,IAAM,SACjB,OACA,WACA,SAEW,OAAQ,CACzB,IAAMC,EAAI,KAAK,OACTC,EAAKC,EAAE,SAAU,YAAa,CAAE,KAAMF,EAAE,UAAY,QAAS,CAAC,EACpE,YAAK,SAAWE,EAAE,OAAQ,iBAAiB,EAC3C,KAAK,OAASA,EAAE,OAAQ,iBAAiB,EAGzC,KAAK,WAAaA,EAAE,OAAQ,sBAAsB,EAClDD,EAAG,OACDC,EAAE,OAAQ,kBAAmB,CAAC,EAAG,KAAK,SAAU,KAAK,MAAM,EAC3DA,EAAE,OAAQ,kBAAmB,CAAE,cAAe,MAAO,EAAGA,EAAE,OAAQ,+BAA+B,EAAG,KAAK,UAAU,CACrH,EACOD,CACT,CAEmB,UAAW,CAC5B,IAAMD,EAAI,KAAK,OACf,KAAK,QAAQA,EAAE,MAAQ,EAAE,EACzB,KAAK,QAAQA,EAAE,MAAQ,EAAE,EACzB,KAAK,WAAWA,EAAE,SAAW,SAAS,EACtC,KAAK,WAAW,CAAC,CAACA,EAAE,OAAO,EACvB,CAACA,EAAE,MAAQ,CAACA,EAAE,WAAa,CAACA,EAAE,SAAS,QAAQ,KAAK,2CAA2C,EACnG,KAAK,OAAO,KAAK,GAAI,QAAU,GAAkB,CAM/C,GALIA,EAAE,UAAYA,EAAE,UAChBA,EAAE,SACJ,KAAK,WAAW,CAACA,EAAE,OAAO,EAC1B,KAAK,KAAK,SAAUA,EAAE,OAAO,GAE3B,KAAK,KAAK,QAAS,CAAC,IAAM,IAAO,OAAO,EAAE,eAAe,EAC7DA,EAAE,UAAU,KAAM,CAAC,CACrB,CAAC,CACH,CAEmB,WAAWG,EAAmB,CAC9C,KAAK,GAAyB,SAAWA,CAC5C,CAEA,QAAQC,EAAc,CACpB,KAAK,OAAO,KAAOA,EACd,KAAK,WACV,KAAK,OAAO,YAAcA,EAC1B,KAAK,OAAO,OAAS,CAACA,EACtB,KAAK,WAAW,YAAc,KAAK,OAAO,aAAeA,EAC3D,CAEA,QAAQC,EAAc,CACpB,KAAK,OAAO,KAAOA,EACd,KAAK,WACV,KAAK,SAAS,gBAAgB,GAAIA,EAAO,CAACC,EAAOD,CAAI,CAAC,EAAI,CAAC,CAAE,EAC7D,KAAK,SAAS,OAAS,CAACA,EACxB,KAAK,GAAG,UAAU,OAAO,wBAAyB,KAAK,OAAO,UAAY,OAAO,EACnF,CAEA,WAAWE,EAA+C,CAExD,GADA,KAAK,OAAO,QAAUA,EAClB,EAAC,KAAK,SACV,QAAWC,IAAK,CAAC,UAAW,UAAW,SAAU,OAAO,EAAG,KAAK,GAAG,UAAU,OAAO,cAAcA,CAAC,GAAIA,IAAMD,CAAO,CACtH,CAEA,WAAWE,EAAkB,CAC3B,KAAK,OAAO,QAAUA,EACjB,KAAK,WACV,KAAK,GAAG,UAAU,OAAO,aAAcA,CAAO,EAC1C,KAAK,OAAO,QAAQ,KAAK,GAAG,aAAa,eAAgB,OAAOA,CAAO,CAAC,EAC9E,CAGS,WAAWC,EAA2B,CAC7C,KAAK,OAAO,QAAUA,EAClB,OAAOA,GAAY,UAAU,KAAK,eAAeA,CAAO,EACvD,KAAK,WACV,KAAK,GAAG,UAAU,OAAO,aAAc,CAAC,CAACA,CAAO,EAC5CA,EAAS,KAAK,GAAG,aAAa,YAAa,MAAM,EAChD,KAAK,GAAG,gBAAgB,WAAW,EAC1C,CAEA,eAAeN,EAAc,CAC3B,KAAK,OAAO,YAAcA,EACtB,KAAK,WAAU,KAAK,WAAW,YAAcA,EACnD,CAGA,OAAc,CACPO,EAAM,KAAK,EAAE,CACpB,CAEA,OAAQ,CACL,KAAK,GAAyB,MAAM,CACvC,CACF,EACAC,EAAS,SAAUd,CAAM",
6
+ "names": ["Button", "Component", "c", "el", "h", "disabled", "text", "name", "iconEl", "variant", "v", "pressed", "loading", "pulse", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{c as n}from"./chunk-UPOBGNJ5.js";import{c as r}from"./chunk-IHAYOSBR.js";import{b as s}from"./chunk-IYPKPLCU.js";import{b as t}from"./chunk-PZSHOSOS.js";import{e as l}from"./chunk-MA5BJL3S.js";var o=class extends n{baseCls="op-fieldset";tag="fieldset";legend;bodyEl;toggleBtn;getBody(){return this.bodyEl}build(){let e=super.build();return this.legend=t("legend","op-fieldset__legend"),this.bodyEl=t("div","op-fieldset__body"),e.append(this.legend,this.bodyEl),e}onRender(){this.config.layout??={type:"vbox"},super.onRender(),this.config.collapsible&&(this.toggleBtn=t("button","op-fieldset__toggle",{type:"button"},r("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 i=this.legend.querySelector(".op-fieldset__title");i||this.legend.append(i=t("span","op-fieldset__title")),i.textContent=e,this.legend.hidden=!e&&!this.config.collapsible}setCollapsed(e){this.config.collapsed=e,this.rendered&&(this.el.classList.toggle("is-collapsed",e),this.bodyEl.hidden=e,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()}};s("fieldset",o);export{o as a};
2
+ //# sourceMappingURL=chunk-YET5PM6F.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 } from '../../../core/dom';\nimport { t } from '../../../core/i18n';\nimport { iconEl } from '../../base/icon/icon';\n\nexport interface FieldSetConfig extends ContainerConfig {\n title?: string;\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\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.bodyEl = h('div', 'op-fieldset__body');\n el.append(this.legend, this.bodyEl);\n return el;\n }\n\n protected override onRender() {\n this.config.layout ??= { type: 'vbox' };\n super.onRender();\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) this.legend.append((text = h('span', 'op-fieldset__title')));\n text.textContent = title;\n this.legend.hidden = !title && !this.config.collapsible;\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 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": "wMAYO,IAAMA,EAAN,cAAuBC,CAA0B,CACnC,QAAU,cACV,IAAM,WACjB,OACA,OACA,UAEC,SAAU,CACjB,OAAO,KAAK,MACd,CAEmB,OAAQ,CACzB,IAAMC,EAAK,MAAM,MAAM,EACvB,YAAK,OAASC,EAAE,SAAU,qBAAqB,EAC/C,KAAK,OAASA,EAAE,MAAO,mBAAmB,EAC1CD,EAAG,OAAO,KAAK,OAAQ,KAAK,MAAM,EAC3BA,CACT,CAEmB,UAAW,CAC5B,KAAK,OAAO,SAAW,CAAE,KAAM,MAAO,EACtC,MAAM,SAAS,EACX,KAAK,OAAO,cACd,KAAK,UAAYC,EAAE,SAAU,sBAAuB,CAAE,KAAM,QAAS,EAAGC,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,GAAM,KAAK,OAAO,OAAQA,EAAOH,EAAE,OAAQ,oBAAoB,CAAE,EACtEG,EAAK,YAAcD,EACnB,KAAK,OAAO,OAAS,CAACA,GAAS,CAAC,KAAK,OAAO,WAC9C,CAEA,aAAaE,EAAoB,CAC/B,KAAK,OAAO,UAAYA,EACnB,KAAK,WACV,KAAK,GAAG,UAAU,OAAO,eAAgBA,CAAS,EAClD,KAAK,OAAO,OAASA,EACrB,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,WAAYT,CAAQ",
6
+ "names": ["FieldSet", "Container", "el", "h", "iconEl", "title", "text", "collapsed", "t", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as d}from"./chunk-O4DCHALR.js";import{a as h}from"./chunk-ARCW54L2.js";import{a as l}from"./chunk-SNTHW4K2.js";import{c as r}from"./chunk-IHAYOSBR.js";import{b as n}from"./chunk-PZSHOSOS.js";var a=class extends l{baseCls="op-field op-textfield op-picker";items=[];selection;typed=!1;list;dd;triggerEl;idEl;wrapEl;buffer="";bufferTimer;editable(){return!0}hasTrigger(){return!0}onType(t){}toItem(t){if(typeof t!="object")return{value:t,label:String(t)};let e=this.config.valueField??"value",i=this.config.displayField??"label";return{value:t[e],label:String(t[i]??t[e]??""),disabled:!!t.disabled,raw:t,hint:this.config.showValue?String(t[e]):void 0}}loadItems(){let t=this.config;this.items=t.store?t.store.getData().map(e=>this.toItem(e)):(t.options??[]).map(e=>this.toItem(e))}setOptions(t){this.config.options=t,this.loadItems(),this.refreshList(),this.rendered&&this.applyValue(this.value)}setStore(t){this.config.store=t,this.bindStore(),this.loadItems(),this.refreshList()}offStore;bindStore(){this.offStore?.(),this.offStore=this.config.store?.subscribe(()=>{this.loadItems(),this.refreshList(),this.rendered&&this.applyValue(this.value)})}findItem(t){return this.items.find(e=>e.value===t)??(this.selection?.value===t?this.selection:void 0)}getSelection(){return this.selection}setSelection(t,e=!1){this.selection=t,this.setValue(t?t.value:this.emptyValue(),e)}visibleItems(){return this.items}refreshList(){if(!this.list)return;let t=this.visibleItems();this.list.setItems(t),this.list.setSelected(this.value);let e=t.findIndex(i=>i.value===this.value&&!i.disabled);this.list.setActive(this.typed||e<0?t.findIndex(i=>!i.disabled):e),this.syncActive()}syncActive(){if(!this.rendered)return;let t=this.list.getActiveId();t&&this.dd.isOpen()?this.input.setAttribute("aria-activedescendant",t):this.input.removeAttribute("aria-activedescendant")}createControl(){let t=super.createControl(),e=this.input;return this.wrapEl=t,this.config.showValue&&(this.idEl=n("span","op-picker__id"),this.idEl.hidden=!0,t.prepend(this.idEl)),this.list=new d({emptyText:this.config.emptyText,maxHeight:this.config.maxHeight,highlight:""}),e.setAttribute("role","combobox"),e.setAttribute("aria-haspopup","listbox"),e.setAttribute("aria-expanded","false"),e.setAttribute("aria-autocomplete",this.editable()?"list":"none"),e.setAttribute("aria-controls",this.list.id),e.autocomplete="off",this.hasTrigger()&&(this.triggerEl=n("button","op-picker__trigger",{type:"button",tabindex:-1,"aria-hidden":"true"},r("chevron-down")),this.listen(this.triggerEl,"mousedown",i=>i.preventDefault()),this.listen(this.triggerEl,"click",()=>{this.config.disabled||this.config.readonly||(e.focus(),this.toggle())}),t.append(this.triggerEl)),this.dd=new h({anchor:t,content:this.list,matchWidth:!0,role:"presentation"}),this.dd.on("open",()=>{e.setAttribute("aria-expanded","true"),this.el.classList.add("is-open"),this.list.refresh(),this.syncActive(),this.emit("expand")}),this.dd.on("close",()=>{e.setAttribute("aria-expanded","false"),this.el.classList.remove("is-open"),e.removeAttribute("aria-activedescendant"),this.emit("collapse")}),this.list.on("select",i=>this.pick(i)),this.list.on("active-change",()=>this.syncActive()),this.own(()=>{this.offStore?.(),this.dd.destroy()}),t}onRender(){this.bindStore(),this.loadItems(),super.onRender(),this.editable()?this.config.openOnFocus&&this.listen(this.input,"focus",()=>this.open()):(this.input.readOnly=!0,this.listen(this.input,"click",()=>this.toggle())),this.on("blur",()=>this.settle()),this.refreshList()}onReadonly(t){this.input.readOnly=t||!this.editable(),t&&this.dd?.close()}onDisabled(t){super.onDisabled(t),this.triggerEl&&(this.triggerEl.disabled=t),t&&this.dd?.close()}applyValue(t){let e=this.findItem(t);e?this.selection=e:this.selection&&this.selection.value!==t&&(this.selection=void 0),this.typed=!1,this.input.value=e?e.label:this.display(t),this.el.classList.toggle("has-value",!!this.input.value),this.list?.setSelected(t),this.paintId()}paintId(){let t=this.idEl;if(!t)return;let e=this.selection;t.hidden=!e||this.typed||this.isEmpty(this.value),t.textContent=t.hidden?"":String(e.value),this.wrapEl.style.setProperty("--op-picker-id-width",t.hidden?"0px":`${t.offsetWidth}px`),this.wrapEl.classList.toggle("has-id",!t.hidden)}getDisplayText(){return this.rendered?this.input.value:this.findItem(this.value)?.label??this.display(this.value)}open(){this.config.disabled||this.config.readonly||!this.rendered||(this.typed||this.refreshList(),this.dd.open())}close(){this.dd?.close()}toggle(){this.dd.isOpen()?this.close():this.open()}expand(){this.open()}collapse(){this.close()}pick(t){t.disabled||(this.selection=t,this.typed=!1,this.input.value=t.label,this.el.classList.add("has-value"),this.commit(t.value),this.paintId(),this.close(),this.emit("select",t))}settle(){if(this.close(),!this.editable()||!this.typed)return;this.typed=!1;let t=this.input.value;!t&&this.config.forceSelection!==!1?(this.selection=void 0,this.commit(this.emptyValue())):this.config.forceSelection===!1?(this.selection=void 0,this.commit(t)):this.input.value=this.selection?.label??"",this.el.classList.toggle("has-value",!!this.input.value),this.paintId(),this.refreshList()}onInput(){this.el.classList.toggle("has-value",!!this.input.value),this.editable()&&(this.typed=!0,this.paintId(),this.config.forceSelection===!1&&this.commit(this.input.value),this.onType(this.input.value))}onKey(t){let e=this.dd.isOpen();switch(t.key){case"ArrowDown":case"ArrowUp":{if(t.preventDefault(),!e)return this.open();this.list.moveActive(t.key==="ArrowDown"?1:-1);return}case"Enter":e?(t.preventDefault(),this.list.getActive()?this.list.activate():this.close()):super.onKey(t);return;case"Home":case"End":e&&!this.editable()&&(t.preventDefault(),this.list.setActive(t.key==="Home"?this.items.findIndex(i=>!i.disabled):this.items.length-1-[...this.items].reverse().findIndex(i=>!i.disabled)));return;case"Tab":e&&this.typed&&this.config.forceSelection!==!1&&this.list.getActive()&&this.list.activate();return;case" ":this.editable()||(t.preventDefault(),e&&this.list.getActive()?this.list.activate():this.open());return;default:!this.editable()&&t.key.length===1&&!t.ctrlKey&&!t.metaKey&&!t.altKey?this.typeahead(t.key):super.onKey(t)}}typeahead(t){clearTimeout(this.bufferTimer),this.buffer+=t.toLowerCase(),this.bufferTimer=setTimeout(()=>this.buffer="",600),this.own(()=>clearTimeout(this.bufferTimer));let e=this.visibleItems(),i=this.dd.isOpen()?this.list.getActiveIndex():e.findIndex(s=>s.value===this.value),o=[...e.keys()].map((s,p)=>(i+(this.buffer.length>1?0:1)+p)%e.length).find(s=>!e[s].disabled&&e[s].label.toLowerCase().startsWith(this.buffer));o!=null&&(this.dd.isOpen()?this.list.setActive(o):this.pick(e[o]))}setEmptyText(t){this.config.emptyText=t,this.list?.setEmptyText(t)}};export{a};
2
+ //# sourceMappingURL=chunk-Z25NC4CS.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/fields/pickerfield/pickerfield.ts"],
4
+ "sourcesContent": ["import { TextField, type TextFieldConfig } from '../textfield/textfield';\nimport { h } from '../../../core/dom';\nimport { iconEl } from '../../base/icon/icon';\nimport { Dropdown } from '../../overlays/dropdown/dropdown';\nimport { ListBox, type ListItem } from '../listbox/listbox';\nimport type { Store } from '../../../data/store';\n\nexport type { ListItem };\nexport type Option = string | number | Record<string, any>;\n\nexport interface PickerConfig<V = unknown> extends TextFieldConfig<V> {\n options?: Option[];\n store?: Store<any>;\n valueField?: string;\n displayField?: string;\n /** Text that does not match an item is discarded on blur. Default true. */\n forceSelection?: boolean;\n emptyText?: string;\n openOnFocus?: boolean;\n maxHeight?: number | string;\n /** Show the record's value (its id) as a badge inside the field and as a hint in every list row. Default false. */\n showValue?: boolean;\n}\n\n/**\n * Shared base of Select, ComboBox and SuggestField: an input that owns a Dropdown with a ListBox,\n * the ARIA combobox wiring and the keyboard model. Subclasses decide what typing does (`onType`)\n * and whether the input is editable.\n */\nexport abstract class PickerField<V = unknown, C extends PickerConfig<V> = PickerConfig<V>> extends TextField<V, C> {\n protected override baseCls = 'op-field op-textfield op-picker';\n protected items: ListItem[] = [];\n protected selection?: ListItem;\n /** The user typed since the last selection/blur; the input text is a search term, not the value's label. */\n protected typed = false;\n protected list!: ListBox;\n protected dd!: Dropdown;\n private triggerEl?: HTMLButtonElement;\n private idEl?: HTMLElement;\n private wrapEl?: HTMLElement;\n private buffer = '';\n private bufferTimer?: ReturnType<typeof setTimeout>;\n\n protected editable(): boolean {\n return true;\n }\n protected hasTrigger(): boolean {\n return true;\n }\n /** Called when the user types in an editable picker. */\n protected onType(_text: string): void {}\n\n // ---- items ---------------------------------------------------------------------------------\n\n protected toItem(o: Option): ListItem {\n if (typeof o !== 'object') return { value: o, label: String(o) };\n const vf = this.config.valueField ?? 'value';\n const df = this.config.displayField ?? 'label';\n return { value: o[vf], label: String(o[df] ?? o[vf] ?? ''), disabled: !!o.disabled, raw: o, hint: this.config.showValue ? String(o[vf]) : undefined };\n }\n\n protected loadItems(): void {\n const c = this.config;\n this.items = c.store ? c.store.getData().map((r) => this.toItem(r)) : (c.options ?? []).map((o) => this.toItem(o));\n }\n\n setOptions(options: Option[]): void {\n this.config.options = options;\n this.loadItems();\n this.refreshList();\n if (this.rendered) this.applyValue(this.value);\n }\n\n setStore(store: Store<any>): void {\n this.config.store = store;\n this.bindStore();\n this.loadItems();\n this.refreshList();\n }\n\n private offStore?: () => void;\n private bindStore(): void {\n this.offStore?.();\n this.offStore = this.config.store?.subscribe(() => {\n this.loadItems();\n this.refreshList();\n if (this.rendered) this.applyValue(this.value);\n });\n }\n\n protected findItem(value: unknown): ListItem | undefined {\n return this.items.find((i) => i.value === value) ?? (this.selection?.value === value ? this.selection : undefined);\n }\n\n getSelection(): ListItem | undefined {\n return this.selection;\n }\n\n /** Selects an item object directly (needed when the list does not contain it, e.g. a remote value). */\n setSelection(item: ListItem | undefined, silent = false): void {\n this.selection = item;\n this.setValue((item ? item.value : this.emptyValue()) as V, silent);\n }\n\n /** The items to display for the current search state. Default: all. */\n protected visibleItems(): ListItem[] {\n return this.items;\n }\n\n protected refreshList(): void {\n if (!this.list) return;\n const shown = this.visibleItems();\n this.list.setItems(shown);\n this.list.setSelected(this.value);\n const sel = shown.findIndex((i) => i.value === this.value && !i.disabled);\n this.list.setActive(this.typed || sel < 0 ? shown.findIndex((i) => !i.disabled) : sel);\n this.syncActive();\n }\n\n private syncActive(): void {\n if (!this.rendered) return;\n const id = this.list.getActiveId();\n if (id && this.dd.isOpen()) this.input.setAttribute('aria-activedescendant', id);\n else this.input.removeAttribute('aria-activedescendant');\n }\n\n // ---- rendering -----------------------------------------------------------------------------\n\n protected override createControl() {\n const wrap = super.createControl();\n const input = this.input;\n this.wrapEl = wrap;\n if (this.config.showValue) {\n this.idEl = h('span', 'op-picker__id');\n this.idEl.hidden = true;\n wrap.prepend(this.idEl);\n }\n this.list = new ListBox({ emptyText: this.config.emptyText, maxHeight: this.config.maxHeight, highlight: '' });\n input.setAttribute('role', 'combobox');\n input.setAttribute('aria-haspopup', 'listbox');\n input.setAttribute('aria-expanded', 'false');\n input.setAttribute('aria-autocomplete', this.editable() ? 'list' : 'none');\n input.setAttribute('aria-controls', this.list.id);\n input.autocomplete = 'off';\n if (this.hasTrigger()) {\n this.triggerEl = h('button', 'op-picker__trigger', { type: 'button', tabindex: -1, 'aria-hidden': 'true' }, iconEl('chevron-down'));\n this.listen(this.triggerEl, 'mousedown', (e: Event) => e.preventDefault());\n this.listen(this.triggerEl, 'click', () => {\n if (this.config.disabled || this.config.readonly) return;\n input.focus();\n this.toggle();\n });\n wrap.append(this.triggerEl);\n }\n this.dd = new Dropdown({ anchor: wrap, content: this.list, matchWidth: true, role: 'presentation' });\n this.dd.on('open', () => {\n input.setAttribute('aria-expanded', 'true');\n this.el.classList.add('is-open');\n this.list.refresh();\n this.syncActive();\n this.emit('expand');\n });\n this.dd.on('close', () => {\n input.setAttribute('aria-expanded', 'false');\n this.el.classList.remove('is-open');\n input.removeAttribute('aria-activedescendant');\n this.emit('collapse');\n });\n this.list.on('select', (item: ListItem) => this.pick(item));\n this.list.on('active-change', () => this.syncActive());\n this.own(() => {\n this.offStore?.();\n this.dd.destroy();\n });\n return wrap;\n }\n\n protected override onRender(): void {\n this.bindStore();\n this.loadItems();\n super.onRender();\n if (!this.editable()) {\n this.input.readOnly = true;\n this.listen(this.input, 'click', () => this.toggle());\n } else if (this.config.openOnFocus) {\n this.listen(this.input, 'focus', () => this.open());\n }\n this.on('blur', () => this.settle());\n this.refreshList();\n }\n\n protected override onReadonly(readonly: boolean): void {\n this.input.readOnly = readonly || !this.editable();\n if (readonly) this.dd?.close();\n }\n protected override onDisabled(disabled: boolean): void {\n super.onDisabled(disabled);\n if (this.triggerEl) this.triggerEl.disabled = disabled;\n if (disabled) this.dd?.close();\n }\n\n protected override applyValue(v: V): void {\n const it = this.findItem(v);\n if (it) this.selection = it;\n else if (this.selection && this.selection.value !== v) this.selection = undefined;\n this.typed = false;\n this.input.value = it ? it.label : this.display(v);\n this.el.classList.toggle('has-value', !!this.input.value);\n this.list?.setSelected(v);\n this.paintId();\n }\n\n /** The id badge (`showValue`): visible while a record is selected, and the input makes room for it. */\n protected paintId(): void {\n const el = this.idEl;\n if (!el) return;\n const sel = this.selection;\n el.hidden = !sel || this.typed || this.isEmpty(this.value);\n el.textContent = el.hidden ? '' : String(sel!.value);\n this.wrapEl!.style.setProperty('--op-picker-id-width', el.hidden ? '0px' : `${el.offsetWidth}px`);\n this.wrapEl!.classList.toggle('has-id', !el.hidden);\n }\n\n override getDisplayText(): string {\n return this.rendered ? this.input.value : (this.findItem(this.value)?.label ?? this.display(this.value));\n }\n\n // ---- behavior ------------------------------------------------------------------------------\n\n open(): void {\n if (this.config.disabled || this.config.readonly || !this.rendered) return;\n if (!this.typed) this.refreshList();\n this.dd.open();\n }\n close(): void {\n this.dd?.close();\n }\n toggle(): void {\n if (this.dd.isOpen()) this.close();\n else this.open();\n }\n expand(): void {\n this.open();\n }\n collapse(): void {\n this.close();\n }\n\n protected pick(item: ListItem): void {\n if (item.disabled) return;\n this.selection = item;\n this.typed = false;\n this.input.value = item.label;\n this.el.classList.add('has-value');\n this.commit(item.value as V);\n this.paintId();\n this.close();\n this.emit('select', item);\n }\n\n /** Called on blur: commits free text or reverts to the selected label. */\n protected settle(): void {\n this.close();\n if (!this.editable() || !this.typed) return;\n this.typed = false;\n const text = this.input.value;\n if (!text && this.config.forceSelection !== false) {\n this.selection = undefined;\n this.commit(this.emptyValue());\n } else if (this.config.forceSelection === false) {\n this.selection = undefined;\n this.commit(text as V);\n } else {\n this.input.value = this.selection?.label ?? '';\n }\n this.el.classList.toggle('has-value', !!this.input.value);\n this.paintId();\n this.refreshList();\n }\n\n protected override onInput(): void {\n this.el.classList.toggle('has-value', !!this.input.value);\n if (!this.editable()) return;\n this.typed = true;\n this.paintId();\n if (this.config.forceSelection === false) this.commit(this.input.value as V);\n this.onType(this.input.value);\n }\n\n protected override onKey(e: KeyboardEvent): void {\n const open = this.dd.isOpen();\n switch (e.key) {\n case 'ArrowDown':\n case 'ArrowUp': {\n e.preventDefault();\n if (!open) return this.open();\n this.list.moveActive(e.key === 'ArrowDown' ? 1 : -1);\n return;\n }\n case 'Enter':\n if (open) {\n e.preventDefault();\n if (this.list.getActive()) this.list.activate();\n else this.close();\n } else super.onKey(e);\n return;\n case 'Home':\n case 'End':\n if (open && !this.editable()) {\n e.preventDefault();\n this.list.setActive(e.key === 'Home' ? this.items.findIndex((i) => !i.disabled) : this.items.length - 1 - [...this.items].reverse().findIndex((i) => !i.disabled));\n }\n return;\n case 'Tab':\n if (open && this.typed && this.config.forceSelection !== false && this.list.getActive()) this.list.activate();\n return;\n case ' ':\n if (!this.editable()) {\n e.preventDefault();\n if (open && this.list.getActive()) this.list.activate();\n else this.open();\n }\n return;\n default:\n if (!this.editable() && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) this.typeahead(e.key);\n else super.onKey(e);\n }\n }\n\n /** Select-style type-ahead: letters jump to the next label that starts with them. */\n private typeahead(ch: string): void {\n clearTimeout(this.bufferTimer);\n this.buffer += ch.toLowerCase();\n this.bufferTimer = setTimeout(() => (this.buffer = ''), 600);\n this.own(() => clearTimeout(this.bufferTimer));\n const list = this.visibleItems();\n const from = this.dd.isOpen() ? this.list.getActiveIndex() : list.findIndex((i) => i.value === this.value);\n const order = [...list.keys()].map((_, k) => (from + (this.buffer.length > 1 ? 0 : 1) + k) % list.length);\n const hit = order.find((i) => !list[i].disabled && list[i].label.toLowerCase().startsWith(this.buffer));\n if (hit == null) return;\n if (this.dd.isOpen()) this.list.setActive(hit);\n else this.pick(list[hit]);\n }\n\n setEmptyText(text: string): void {\n this.config.emptyText = text;\n this.list?.setEmptyText(text);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["PickerField", "TextField", "_text", "o", "vf", "df", "c", "r", "options", "store", "value", "i", "item", "silent", "shown", "sel", "id", "wrap", "input", "h", "ListBox", "iconEl", "e", "Dropdown", "readonly", "disabled", "v", "it", "el", "text", "open", "ch", "list", "from", "hit", "_", "k"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as p}from"./chunk-ARCW54L2.js";import{c as d}from"./chunk-VV7CFMPZ.js";import{e as l}from"./chunk-4AA4FQEM.js";import{c as s}from"./chunk-IHAYOSBR.js";import{a as u,b as h}from"./chunk-IYPKPLCU.js";import{b as i}from"./chunk-PZSHOSOS.js";var r=".op-menu__item",a=class m extends u{baseCls="op-menu";parentMenu;dd;sub;subOwner;opener=null;hoverCancel;build(){return i("div","op-menu",{role:"menu"})}onRender(){this.renderItems();let e=d(this.el,{selector:r,orientation:"vertical"});this.own(()=>e.destroy()),this.listen(this.el,"click",t=>{let n=t.target.closest(r);n&&this.activate(n)}),this.listen(this.el,"keydown",t=>{let n=t.target.closest(r);if(t.key==="Tab")return this.closeAll();n&&(t.key==="Enter"||t.key===" "?(t.preventDefault(),this.activate(n)):t.key==="ArrowRight"&&n.getAttribute("aria-haspopup")?(t.preventDefault(),this.openSub(n,!0)):t.key==="ArrowLeft"&&this.parentMenu&&(t.preventDefault(),this.hide()))}),this.listen(this.el,"pointerover",t=>{let n=t.target.closest(r);!n||n.getAttribute("aria-disabled")==="true"||(this.hoverCancel?.(),n.focus(),n.getAttribute("aria-haspopup")?this.hoverCancel=this.later(()=>this.openSub(n,!1),150):this.sub?.hide())})}entries(){return this.config.items??[]}renderItems(){this.el.replaceChildren(...this.entries().map((e,t)=>{if(e==="-")return i("div","op-menu__sep",{role:"separator"});let n=e.checked!==void 0,o=i("div","op-menu__item",{role:n?"menuitemcheckbox":"menuitem",tabindex:-1,"data-i":t,"aria-disabled":e.disabled?"true":null,"aria-checked":n?String(!!e.checked):null,"aria-haspopup":e.items?"menu":null,"aria-expanded":e.items?"false":null});return o.append(i("span","op-menu__icon",{},e.icon?s(e.icon):n&&e.checked?s("check"):null),i("span","op-menu__text",{},e.text??"")),e.items&&o.append(i("span","op-menu__arrow",{},s("chevron-right"))),o}))}setItems(e){this.config.items=e,this.rendered&&this.renderItems()}activate(e){let t=this.entries()[Number(e.dataset.i)];if(!(!t||t.disabled)){if(t.items)return this.openSub(e,!0);t.checked!==void 0&&(t.checked=!t.checked),t.handler?.(t),this.root().emit("click",t),this.root().hide()}}root(){return this.parentMenu?this.parentMenu.root():this}openSub(e,t){let n=this.entries()[Number(e.dataset.i)];if(this.sub&&this.subOwner===e&&this.sub.isOpen())return t?this.sub.focusFirst():void 0;this.sub?.destroy(),this.sub=new m({items:n.items}),this.sub.parentMenu=this,this.subOwner=e,this.sub.on("hide",()=>e.setAttribute("aria-expanded","false")),e.setAttribute("aria-expanded","true"),this.sub.showBy(e,"right-start",t)}isOpen(){return!!this.dd?.isOpen()}focusFirst(){this.el.querySelector(`${r}:not([aria-disabled=true])`)?.focus()}showBy(e,t="bottom-start",n=!0){this.open({anchor:e,placement:t},n)}showAt(e,t){this.open({anchor:{x:e,y:t},placement:"bottom-start"},!0)}open(e,t){this.opener=document.activeElement,this.dd?(this.dd.setAnchor(e.anchor),this.dd.setPlacement(e.placement)):(this.dd=new p({...e,content:this.el,role:"presentation",flip:!0}),this.dd.on("close",()=>{this.sub?.hide(),this.emit("hide")})),this.dd.open(),l(Array.from(this.el.querySelectorAll(r)),{dy:4}),t&&this.focusFirst(),this.emit("show")}hide(){if(!this.dd?.isOpen())return;this.dd.close();let e=this.parentMenu?this.parentMenu.subOwner:this.opener;e instanceof HTMLElement&&e.isConnected&&e.focus()}closeAll(){this.root().hide()}onDestroy(){this.sub?.destroy(),this.dd?.destroy()}};h("menu",a);export{a};
2
+ //# sourceMappingURL=chunk-ZCAAM4NH.js.map