optikos 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (527) hide show
  1. package/CHANGELOG.md +146 -0
  2. package/LICENSE +21 -0
  3. package/README.md +213 -2
  4. package/THIRD_PARTY_NOTICES.md +83 -0
  5. package/dist/bind.js +2 -0
  6. package/dist/bind.js.map +7 -0
  7. package/dist/chunk-23XLG2EM.js +2 -0
  8. package/dist/chunk-23XLG2EM.js.map +7 -0
  9. package/dist/chunk-27UZFEXD.js +2 -0
  10. package/dist/chunk-27UZFEXD.js.map +7 -0
  11. package/dist/chunk-2UPUC4RK.js +2 -0
  12. package/dist/chunk-2UPUC4RK.js.map +7 -0
  13. package/dist/chunk-2ZRNGG2N.js +2 -0
  14. package/dist/chunk-2ZRNGG2N.js.map +7 -0
  15. package/dist/chunk-2ZUZ5HDL.js +2 -0
  16. package/dist/chunk-2ZUZ5HDL.js.map +7 -0
  17. package/dist/chunk-3DBEZGOY.js +2 -0
  18. package/dist/chunk-3DBEZGOY.js.map +7 -0
  19. package/dist/chunk-3S24ZRPK.js +2 -0
  20. package/dist/chunk-3S24ZRPK.js.map +7 -0
  21. package/dist/chunk-3TAW4AKH.js +2 -0
  22. package/dist/chunk-3TAW4AKH.js.map +7 -0
  23. package/dist/chunk-4AA4FQEM.js +2 -0
  24. package/dist/chunk-4AA4FQEM.js.map +7 -0
  25. package/dist/chunk-4C666HHU.js +2 -0
  26. package/dist/chunk-4C666HHU.js.map +7 -0
  27. package/dist/chunk-4EZJ5FKJ.js +2 -0
  28. package/dist/chunk-4EZJ5FKJ.js.map +7 -0
  29. package/dist/chunk-4LZZ244E.js +2 -0
  30. package/dist/chunk-4LZZ244E.js.map +7 -0
  31. package/dist/chunk-4SYIIX5A.js +2 -0
  32. package/dist/chunk-4SYIIX5A.js.map +7 -0
  33. package/dist/chunk-5BC72727.js +2 -0
  34. package/dist/chunk-5BC72727.js.map +7 -0
  35. package/dist/chunk-5DJTP53N.js +2 -0
  36. package/dist/chunk-5DJTP53N.js.map +7 -0
  37. package/dist/chunk-5JEXM5S7.js +2 -0
  38. package/dist/chunk-5JEXM5S7.js.map +7 -0
  39. package/dist/chunk-5Q76ACVI.js +2 -0
  40. package/dist/chunk-5Q76ACVI.js.map +7 -0
  41. package/dist/chunk-5QUY72FX.js +2 -0
  42. package/dist/chunk-5QUY72FX.js.map +7 -0
  43. package/dist/chunk-5YS7OD5E.js +2 -0
  44. package/dist/chunk-5YS7OD5E.js.map +7 -0
  45. package/dist/chunk-676AKAGF.js +2 -0
  46. package/dist/chunk-676AKAGF.js.map +7 -0
  47. package/dist/chunk-6NCXO5ZP.js +2 -0
  48. package/dist/chunk-6NCXO5ZP.js.map +7 -0
  49. package/dist/chunk-6VBK2I5B.js +2 -0
  50. package/dist/chunk-6VBK2I5B.js.map +7 -0
  51. package/dist/chunk-7KMIFXHZ.js +2 -0
  52. package/dist/chunk-7KMIFXHZ.js.map +7 -0
  53. package/dist/chunk-A2NKDOYN.js +2 -0
  54. package/dist/chunk-A2NKDOYN.js.map +7 -0
  55. package/dist/chunk-ATFJ7PNA.js +2 -0
  56. package/dist/chunk-ATFJ7PNA.js.map +7 -0
  57. package/dist/chunk-BXYWVRKJ.js +2 -0
  58. package/dist/chunk-BXYWVRKJ.js.map +7 -0
  59. package/dist/chunk-CKXS375P.js +2 -0
  60. package/dist/chunk-CKXS375P.js.map +7 -0
  61. package/dist/chunk-CUN5QO4T.js +2 -0
  62. package/dist/chunk-CUN5QO4T.js.map +7 -0
  63. package/dist/chunk-DBMWS3O5.js +2 -0
  64. package/dist/chunk-DBMWS3O5.js.map +7 -0
  65. package/dist/chunk-E4VNLYO2.js +2 -0
  66. package/dist/chunk-E4VNLYO2.js.map +7 -0
  67. package/dist/chunk-EDUMAMK4.js +2 -0
  68. package/dist/chunk-EDUMAMK4.js.map +7 -0
  69. package/dist/chunk-ELYARUCN.js +2 -0
  70. package/dist/chunk-ELYARUCN.js.map +7 -0
  71. package/dist/chunk-EV73ADN2.js +2 -0
  72. package/dist/chunk-EV73ADN2.js.map +7 -0
  73. package/dist/chunk-FEHGU6EP.js +3 -0
  74. package/dist/chunk-FEHGU6EP.js.map +7 -0
  75. package/dist/chunk-FHM5NUS4.js +3 -0
  76. package/dist/chunk-FHM5NUS4.js.map +7 -0
  77. package/dist/chunk-G2DAD3MQ.js +2 -0
  78. package/dist/chunk-G2DAD3MQ.js.map +7 -0
  79. package/dist/chunk-G2KUK6AT.js +2 -0
  80. package/dist/chunk-G2KUK6AT.js.map +7 -0
  81. package/dist/chunk-GBPLNXMP.js +2 -0
  82. package/dist/chunk-GBPLNXMP.js.map +7 -0
  83. package/dist/chunk-GNU4VOOE.js +2 -0
  84. package/dist/chunk-GNU4VOOE.js.map +7 -0
  85. package/dist/chunk-GZ7X34QP.js +2 -0
  86. package/dist/chunk-GZ7X34QP.js.map +7 -0
  87. package/dist/chunk-HOF4JGMQ.js +2 -0
  88. package/dist/chunk-HOF4JGMQ.js.map +7 -0
  89. package/dist/chunk-HXDTGP2K.js +2 -0
  90. package/dist/chunk-HXDTGP2K.js.map +7 -0
  91. package/dist/chunk-I4SP6JTU.js +2 -0
  92. package/dist/chunk-I4SP6JTU.js.map +7 -0
  93. package/dist/chunk-IHE2MQ3W.js +2 -0
  94. package/dist/chunk-IHE2MQ3W.js.map +7 -0
  95. package/dist/chunk-II6ITOA6.js +2 -0
  96. package/dist/chunk-II6ITOA6.js.map +7 -0
  97. package/dist/chunk-JBLRAM7Z.js +2 -0
  98. package/dist/chunk-JBLRAM7Z.js.map +7 -0
  99. package/dist/chunk-JI265XFO.js +2 -0
  100. package/dist/chunk-JI265XFO.js.map +7 -0
  101. package/dist/chunk-JK74QK3M.js +2 -0
  102. package/dist/chunk-JK74QK3M.js.map +7 -0
  103. package/dist/chunk-JOFQJGZK.js +2 -0
  104. package/dist/chunk-JOFQJGZK.js.map +7 -0
  105. package/dist/chunk-KCEUD232.js +2 -0
  106. package/dist/chunk-KCEUD232.js.map +7 -0
  107. package/dist/chunk-KLLAY2IM.js +2 -0
  108. package/dist/chunk-KLLAY2IM.js.map +7 -0
  109. package/dist/chunk-LBJSMXLV.js +2 -0
  110. package/dist/chunk-LBJSMXLV.js.map +7 -0
  111. package/dist/chunk-LQRFNQ2N.js +2 -0
  112. package/dist/chunk-LQRFNQ2N.js.map +7 -0
  113. package/dist/chunk-LW2WRUVL.js +2 -0
  114. package/dist/chunk-LW2WRUVL.js.map +7 -0
  115. package/dist/chunk-M242VYZA.js +2 -0
  116. package/dist/chunk-M242VYZA.js.map +7 -0
  117. package/dist/chunk-MB3MU6HR.js +2 -0
  118. package/dist/chunk-MB3MU6HR.js.map +7 -0
  119. package/dist/chunk-MW3RWBZ7.js +2 -0
  120. package/dist/chunk-MW3RWBZ7.js.map +7 -0
  121. package/dist/chunk-NXSTUFS7.js +2 -0
  122. package/dist/chunk-NXSTUFS7.js.map +7 -0
  123. package/dist/chunk-OEAXCCVM.js +2 -0
  124. package/dist/chunk-OEAXCCVM.js.map +7 -0
  125. package/dist/chunk-OGRFQTXA.js +2 -0
  126. package/dist/chunk-OGRFQTXA.js.map +7 -0
  127. package/dist/chunk-OWEQT2HN.js +2 -0
  128. package/dist/chunk-OWEQT2HN.js.map +7 -0
  129. package/dist/chunk-PZSHOSOS.js +2 -0
  130. package/dist/chunk-PZSHOSOS.js.map +7 -0
  131. package/dist/chunk-REW4LR46.js +2 -0
  132. package/dist/chunk-REW4LR46.js.map +7 -0
  133. package/dist/chunk-RNN55473.js +2 -0
  134. package/dist/chunk-RNN55473.js.map +7 -0
  135. package/dist/chunk-SA53QUBF.js +2 -0
  136. package/dist/chunk-SA53QUBF.js.map +7 -0
  137. package/dist/chunk-TIPK3SCJ.js +2 -0
  138. package/dist/chunk-TIPK3SCJ.js.map +7 -0
  139. package/dist/chunk-TOLTUOZS.js +2 -0
  140. package/dist/chunk-TOLTUOZS.js.map +7 -0
  141. package/dist/chunk-TZOQWCVH.js +2 -0
  142. package/dist/chunk-TZOQWCVH.js.map +7 -0
  143. package/dist/chunk-VF7BGP6L.js +2 -0
  144. package/dist/chunk-VF7BGP6L.js.map +7 -0
  145. package/dist/chunk-VU3GIDZ3.js +2 -0
  146. package/dist/chunk-VU3GIDZ3.js.map +7 -0
  147. package/dist/chunk-VV7CFMPZ.js +2 -0
  148. package/dist/chunk-VV7CFMPZ.js.map +7 -0
  149. package/dist/chunk-W3H7GTJY.js +2 -0
  150. package/dist/chunk-W3H7GTJY.js.map +7 -0
  151. package/dist/chunk-X2ASKUFD.js +2 -0
  152. package/dist/chunk-X2ASKUFD.js.map +7 -0
  153. package/dist/chunk-X6AULZI4.js +1 -0
  154. package/dist/chunk-X6AULZI4.js.map +7 -0
  155. package/dist/chunk-XHOBNSBO.js +2 -0
  156. package/dist/chunk-XHOBNSBO.js.map +7 -0
  157. package/dist/chunk-XX2MVWFS.js +4 -0
  158. package/dist/chunk-XX2MVWFS.js.map +7 -0
  159. package/dist/chunk-XYZ6VZ5T.js +2 -0
  160. package/dist/chunk-XYZ6VZ5T.js.map +7 -0
  161. package/dist/chunk-YBAYEU25.js +2 -0
  162. package/dist/chunk-YBAYEU25.js.map +7 -0
  163. package/dist/chunk-YHEMA56R.js +2 -0
  164. package/dist/chunk-YHEMA56R.js.map +7 -0
  165. package/dist/chunk-Z2JBUHKA.js +2 -0
  166. package/dist/chunk-Z2JBUHKA.js.map +7 -0
  167. package/dist/chunk-Z2Z52GFT.js +2 -0
  168. package/dist/chunk-Z2Z52GFT.js.map +7 -0
  169. package/dist/chunk-ZPPELYNJ.js +2 -0
  170. package/dist/chunk-ZPPELYNJ.js.map +7 -0
  171. package/dist/chunk-ZVK4L5GK.js +2 -0
  172. package/dist/chunk-ZVK4L5GK.js.map +7 -0
  173. package/dist/chunk-ZWNQREWS.js +2 -0
  174. package/dist/chunk-ZWNQREWS.js.map +7 -0
  175. package/dist/components/badge.js +2 -0
  176. package/dist/components/badge.js.map +7 -0
  177. package/dist/components/breadcrumb.js +2 -0
  178. package/dist/components/breadcrumb.js.map +7 -0
  179. package/dist/components/button.js +2 -0
  180. package/dist/components/button.js.map +7 -0
  181. package/dist/components/calendar.js +2 -0
  182. package/dist/components/calendar.js.map +7 -0
  183. package/dist/components/cellediting.js +2 -0
  184. package/dist/components/cellediting.js.map +7 -0
  185. package/dist/components/chat.js +2 -0
  186. package/dist/components/chat.js.map +7 -0
  187. package/dist/components/checkbox.js +2 -0
  188. package/dist/components/checkbox.js.map +7 -0
  189. package/dist/components/checkboxgroup.js +2 -0
  190. package/dist/components/checkboxgroup.js.map +7 -0
  191. package/dist/components/chip.js +2 -0
  192. package/dist/components/chip.js.map +7 -0
  193. package/dist/components/codeviewer.js +2 -0
  194. package/dist/components/codeviewer.js.map +7 -0
  195. package/dist/components/combobox.js +2 -0
  196. package/dist/components/combobox.js.map +7 -0
  197. package/dist/components/commandpalette.js +2 -0
  198. package/dist/components/commandpalette.js.map +7 -0
  199. package/dist/components/container.js +2 -0
  200. package/dist/components/container.js.map +7 -0
  201. package/dist/components/dataview.js +2 -0
  202. package/dist/components/dataview.js.map +7 -0
  203. package/dist/components/datefield.js +2 -0
  204. package/dist/components/datefield.js.map +7 -0
  205. package/dist/components/daterangefield.js +2 -0
  206. package/dist/components/daterangefield.js.map +7 -0
  207. package/dist/components/dial.js +2 -0
  208. package/dist/components/dial.js.map +7 -0
  209. package/dist/components/dropdown.js +2 -0
  210. package/dist/components/dropdown.js.map +7 -0
  211. package/dist/components/fieldgroup.js +2 -0
  212. package/dist/components/fieldgroup.js.map +7 -0
  213. package/dist/components/fieldlist.js +2 -0
  214. package/dist/components/fieldlist.js.map +7 -0
  215. package/dist/components/fieldset.js +2 -0
  216. package/dist/components/fieldset.js.map +7 -0
  217. package/dist/components/filterbuilder.js +2 -0
  218. package/dist/components/filterbuilder.js.map +7 -0
  219. package/dist/components/form.js +2 -0
  220. package/dist/components/form.js.map +7 -0
  221. package/dist/components/formactions.js +2 -0
  222. package/dist/components/formactions.js.map +7 -0
  223. package/dist/components/formerrors.js +2 -0
  224. package/dist/components/formerrors.js.map +7 -0
  225. package/dist/components/formsection.js +2 -0
  226. package/dist/components/formsection.js.map +7 -0
  227. package/dist/components/grid.js +2 -0
  228. package/dist/components/grid.js.map +7 -0
  229. package/dist/components/icon.js +2 -0
  230. package/dist/components/icon.js.map +7 -0
  231. package/dist/components/inputgroup.js +2 -0
  232. package/dist/components/inputgroup.js.map +7 -0
  233. package/dist/components/label.js +2 -0
  234. package/dist/components/label.js.map +7 -0
  235. package/dist/components/listbox.js +2 -0
  236. package/dist/components/listbox.js.map +7 -0
  237. package/dist/components/lookupfield.js +2 -0
  238. package/dist/components/lookupfield.js.map +7 -0
  239. package/dist/components/menu.js +2 -0
  240. package/dist/components/menu.js.map +7 -0
  241. package/dist/components/messagebox.js +2 -0
  242. package/dist/components/messagebox.js.map +7 -0
  243. package/dist/components/navmenu.js +2 -0
  244. package/dist/components/navmenu.js.map +7 -0
  245. package/dist/components/numberfield.js +2 -0
  246. package/dist/components/numberfield.js.map +7 -0
  247. package/dist/components/pagination.js +2 -0
  248. package/dist/components/pagination.js.map +7 -0
  249. package/dist/components/panel.js +2 -0
  250. package/dist/components/panel.js.map +7 -0
  251. package/dist/components/pickerfield.js +2 -0
  252. package/dist/components/pickerfield.js.map +7 -0
  253. package/dist/components/radiogroup.js +2 -0
  254. package/dist/components/radiogroup.js.map +7 -0
  255. package/dist/components/searchgrid.js +2 -0
  256. package/dist/components/searchgrid.js.map +7 -0
  257. package/dist/components/secretfield.js +2 -0
  258. package/dist/components/secretfield.js.map +7 -0
  259. package/dist/components/select.js +2 -0
  260. package/dist/components/select.js.map +7 -0
  261. package/dist/components/slider.js +2 -0
  262. package/dist/components/slider.js.map +7 -0
  263. package/dist/components/spacer.js +2 -0
  264. package/dist/components/spacer.js.map +7 -0
  265. package/dist/components/spinner.js +2 -0
  266. package/dist/components/spinner.js.map +7 -0
  267. package/dist/components/stepform.js +2 -0
  268. package/dist/components/stepform.js.map +7 -0
  269. package/dist/components/stepper.js +2 -0
  270. package/dist/components/stepper.js.map +7 -0
  271. package/dist/components/suggestfield.js +2 -0
  272. package/dist/components/suggestfield.js.map +7 -0
  273. package/dist/components/table.js +2 -0
  274. package/dist/components/table.js.map +7 -0
  275. package/dist/components/tabs.js +2 -0
  276. package/dist/components/tabs.js.map +7 -0
  277. package/dist/components/textarea.js +2 -0
  278. package/dist/components/textarea.js.map +7 -0
  279. package/dist/components/textfield.js +2 -0
  280. package/dist/components/textfield.js.map +7 -0
  281. package/dist/components/toast.js +2 -0
  282. package/dist/components/toast.js.map +7 -0
  283. package/dist/components/toggle.js +2 -0
  284. package/dist/components/toggle.js.map +7 -0
  285. package/dist/components/toolbar.js +2 -0
  286. package/dist/components/toolbar.js.map +7 -0
  287. package/dist/components/tooltip.js +2 -0
  288. package/dist/components/tooltip.js.map +7 -0
  289. package/dist/components/tree.js +2 -0
  290. package/dist/components/tree.js.map +7 -0
  291. package/dist/components/viewmanager.js +2 -0
  292. package/dist/components/viewmanager.js.map +7 -0
  293. package/dist/components/viewport.js +2 -0
  294. package/dist/components/viewport.js.map +7 -0
  295. package/dist/components/widget.js +2 -0
  296. package/dist/components/widget.js.map +7 -0
  297. package/dist/components/window.js +2 -0
  298. package/dist/components/window.js.map +7 -0
  299. package/dist/core.js +2 -0
  300. package/dist/core.js.map +7 -0
  301. package/dist/css/badge.css +39 -0
  302. package/dist/css/base.css +180 -0
  303. package/dist/css/breadcrumb.css +53 -0
  304. package/dist/css/button.css +103 -0
  305. package/dist/css/calendar.css +108 -0
  306. package/dist/css/cellediting.css +33 -0
  307. package/dist/css/chat.css +232 -0
  308. package/dist/css/checkbox.css +64 -0
  309. package/dist/css/checkboxgroup.css +12 -0
  310. package/dist/css/chip.css +64 -0
  311. package/dist/css/codeviewer.css +109 -0
  312. package/dist/css/commandpalette.css +167 -0
  313. package/dist/css/container.css +5 -0
  314. package/dist/css/core.css +88 -0
  315. package/dist/css/dataview.css +56 -0
  316. package/dist/css/dial.css +203 -0
  317. package/dist/css/dropdown.css +13 -0
  318. package/dist/css/field.css +62 -0
  319. package/dist/css/fieldgroup.css +26 -0
  320. package/dist/css/fieldlist.css +84 -0
  321. package/dist/css/fieldset.css +68 -0
  322. package/dist/css/filterbuilder.css +125 -0
  323. package/dist/css/form.css +8 -0
  324. package/dist/css/formactions.css +40 -0
  325. package/dist/css/formerrors.css +39 -0
  326. package/dist/css/formsection.css +45 -0
  327. package/dist/css/grid.css +378 -0
  328. package/dist/css/icon.css +16 -0
  329. package/dist/css/inputgroup.css +58 -0
  330. package/dist/css/label.css +12 -0
  331. package/dist/css/layout.css +116 -0
  332. package/dist/css/listbox.css +50 -0
  333. package/dist/css/menu.css +92 -0
  334. package/dist/css/messagebox.css +6 -0
  335. package/dist/css/motion.css +29 -0
  336. package/dist/css/navmenu.css +115 -0
  337. package/dist/css/pagination.css +23 -0
  338. package/dist/css/panel.css +84 -0
  339. package/dist/css/pickerfield.css +85 -0
  340. package/dist/css/radiogroup.css +53 -0
  341. package/dist/css/searchgrid.css +37 -0
  342. package/dist/css/secretfield.css +73 -0
  343. package/dist/css/slider.css +107 -0
  344. package/dist/css/spacer.css +7 -0
  345. package/dist/css/stepform.css +46 -0
  346. package/dist/css/stepper.css +122 -0
  347. package/dist/css/table.css +36 -0
  348. package/dist/css/tabs.css +108 -0
  349. package/dist/css/textarea.css +11 -0
  350. package/dist/css/textfield.css +59 -0
  351. package/dist/css/toast.css +91 -0
  352. package/dist/css/toggle.css +39 -0
  353. package/dist/css/toolbar.css +14 -0
  354. package/dist/css/tooltip.css +17 -0
  355. package/dist/css/tree.css +94 -0
  356. package/dist/css/viewport.css +9 -0
  357. package/dist/css/widget.css +135 -0
  358. package/dist/css/window.css +35 -0
  359. package/dist/data.js +2 -0
  360. package/dist/data.js.map +7 -0
  361. package/dist/index.js +8 -0
  362. package/dist/index.js.map +7 -0
  363. package/dist/motion.js +2 -0
  364. package/dist/motion.js.map +7 -0
  365. package/dist/optikos.css +4240 -0
  366. package/dist/themes/compact.css +17 -0
  367. package/dist/themes/dark.css +53 -0
  368. package/dist/types/bind/index.d.ts +23 -0
  369. package/dist/types/components/badge.d.ts +1 -0
  370. package/dist/types/components/base/badge/badge.d.ts +18 -0
  371. package/dist/types/components/base/button/button.d.ts +34 -0
  372. package/dist/types/components/base/chip/chip.d.ts +27 -0
  373. package/dist/types/components/base/codeviewer/codeviewer.d.ts +48 -0
  374. package/dist/types/components/base/icon/icon.d.ts +17 -0
  375. package/dist/types/components/base/label/label.d.ts +14 -0
  376. package/dist/types/components/breadcrumb.d.ts +1 -0
  377. package/dist/types/components/button.d.ts +1 -0
  378. package/dist/types/components/calendar.d.ts +1 -0
  379. package/dist/types/components/cellediting.d.ts +1 -0
  380. package/dist/types/components/chat/chat/chat.d.ts +84 -0
  381. package/dist/types/components/chat.d.ts +1 -0
  382. package/dist/types/components/checkbox.d.ts +1 -0
  383. package/dist/types/components/checkboxgroup.d.ts +1 -0
  384. package/dist/types/components/chip.d.ts +1 -0
  385. package/dist/types/components/codeviewer.d.ts +1 -0
  386. package/dist/types/components/combobox.d.ts +1 -0
  387. package/dist/types/components/commandpalette.d.ts +1 -0
  388. package/dist/types/components/container.d.ts +1 -0
  389. package/dist/types/components/data/cellediting/cellediting.d.ts +10 -0
  390. package/dist/types/components/data/dataview/dataview.d.ts +61 -0
  391. package/dist/types/components/data/filterbuilder/filterbuilder.d.ts +73 -0
  392. package/dist/types/components/data/grid/grid.d.ts +177 -0
  393. package/dist/types/components/data/pagination/pagination.d.ts +31 -0
  394. package/dist/types/components/data/searchgrid/searchgrid.d.ts +63 -0
  395. package/dist/types/components/data/table/table.d.ts +26 -0
  396. package/dist/types/components/data/tree/tree.d.ts +71 -0
  397. package/dist/types/components/data/viewmanager/viewmanager.d.ts +86 -0
  398. package/dist/types/components/dataview.d.ts +1 -0
  399. package/dist/types/components/datefield.d.ts +1 -0
  400. package/dist/types/components/daterangefield.d.ts +1 -0
  401. package/dist/types/components/dates/calendar/calendar.d.ts +48 -0
  402. package/dist/types/components/dial.d.ts +1 -0
  403. package/dist/types/components/dropdown.d.ts +1 -0
  404. package/dist/types/components/feedback/spinner/spinner.d.ts +11 -0
  405. package/dist/types/components/fieldgroup.d.ts +1 -0
  406. package/dist/types/components/fieldlist.d.ts +1 -0
  407. package/dist/types/components/fields/checkbox/checkbox.d.ts +20 -0
  408. package/dist/types/components/fields/checkboxgroup/checkboxgroup.d.ts +27 -0
  409. package/dist/types/components/fields/combobox/combobox.d.ts +15 -0
  410. package/dist/types/components/fields/datefield/datefield.d.ts +30 -0
  411. package/dist/types/components/fields/daterangefield/daterangefield.d.ts +32 -0
  412. package/dist/types/components/fields/dial/dial.d.ts +84 -0
  413. package/dist/types/components/fields/listbox/listbox.d.ts +54 -0
  414. package/dist/types/components/fields/lookupfield/lookupfield.d.ts +25 -0
  415. package/dist/types/components/fields/numberfield/numberfield.d.ts +31 -0
  416. package/dist/types/components/fields/pickerfield/pickerfield.d.ts +77 -0
  417. package/dist/types/components/fields/radiogroup/radiogroup.d.ts +26 -0
  418. package/dist/types/components/fields/secretfield/secretfield.d.ts +52 -0
  419. package/dist/types/components/fields/select/select.d.ts +10 -0
  420. package/dist/types/components/fields/slider/slider.d.ts +62 -0
  421. package/dist/types/components/fields/suggestfield/suggestfield.d.ts +34 -0
  422. package/dist/types/components/fields/textarea/textarea.d.ts +16 -0
  423. package/dist/types/components/fields/textfield/textfield.d.ts +38 -0
  424. package/dist/types/components/fields/toggle/toggle.d.ts +9 -0
  425. package/dist/types/components/fieldset.d.ts +1 -0
  426. package/dist/types/components/filterbuilder.d.ts +1 -0
  427. package/dist/types/components/form/fieldgroup/fieldgroup.d.ts +33 -0
  428. package/dist/types/components/form/fieldlist/fieldlist.d.ts +58 -0
  429. package/dist/types/components/form/form/form.d.ts +68 -0
  430. package/dist/types/components/form/formactions/formactions.d.ts +34 -0
  431. package/dist/types/components/form/formerrors/formerrors.d.ts +23 -0
  432. package/dist/types/components/form/formsection/formsection.d.ts +26 -0
  433. package/dist/types/components/form/inputgroup/inputgroup.d.ts +28 -0
  434. package/dist/types/components/form/stepform/stepform.d.ts +64 -0
  435. package/dist/types/components/form.d.ts +1 -0
  436. package/dist/types/components/formactions.d.ts +1 -0
  437. package/dist/types/components/formerrors.d.ts +1 -0
  438. package/dist/types/components/formsection.d.ts +1 -0
  439. package/dist/types/components/grid.d.ts +1 -0
  440. package/dist/types/components/icon.d.ts +1 -0
  441. package/dist/types/components/inputgroup.d.ts +1 -0
  442. package/dist/types/components/label.d.ts +1 -0
  443. package/dist/types/components/layout/container/container.d.ts +1 -0
  444. package/dist/types/components/layout/fieldset/fieldset.d.ts +30 -0
  445. package/dist/types/components/layout/panel/panel.d.ts +53 -0
  446. package/dist/types/components/layout/panel/reload.d.ts +1 -0
  447. package/dist/types/components/layout/spacer/spacer.d.ts +12 -0
  448. package/dist/types/components/layout/toolbar/toolbar.d.ts +15 -0
  449. package/dist/types/components/layout/viewport/viewport.d.ts +7 -0
  450. package/dist/types/components/listbox.d.ts +1 -0
  451. package/dist/types/components/lookupfield.d.ts +1 -0
  452. package/dist/types/components/menu.d.ts +1 -0
  453. package/dist/types/components/messagebox.d.ts +1 -0
  454. package/dist/types/components/navigation/breadcrumb/breadcrumb.d.ts +32 -0
  455. package/dist/types/components/navigation/navmenu/navmenu.d.ts +63 -0
  456. package/dist/types/components/navigation/stepper/stepper.d.ts +31 -0
  457. package/dist/types/components/navigation/tabs/tabs.d.ts +57 -0
  458. package/dist/types/components/navmenu.d.ts +1 -0
  459. package/dist/types/components/numberfield.d.ts +1 -0
  460. package/dist/types/components/overlays/commandpalette/commandpalette.d.ts +80 -0
  461. package/dist/types/components/overlays/dropdown/dropdown.d.ts +41 -0
  462. package/dist/types/components/overlays/menu/menu.d.ts +56 -0
  463. package/dist/types/components/overlays/messagebox/messagebox.d.ts +61 -0
  464. package/dist/types/components/overlays/toast/toast.d.ts +45 -0
  465. package/dist/types/components/overlays/tooltip/tooltip.d.ts +13 -0
  466. package/dist/types/components/overlays/widget/widget.d.ts +61 -0
  467. package/dist/types/components/overlays/window/window.d.ts +38 -0
  468. package/dist/types/components/pagination.d.ts +1 -0
  469. package/dist/types/components/panel.d.ts +1 -0
  470. package/dist/types/components/pickerfield.d.ts +1 -0
  471. package/dist/types/components/radiogroup.d.ts +1 -0
  472. package/dist/types/components/searchgrid.d.ts +1 -0
  473. package/dist/types/components/secretfield.d.ts +1 -0
  474. package/dist/types/components/select.d.ts +1 -0
  475. package/dist/types/components/slider.d.ts +1 -0
  476. package/dist/types/components/spacer.d.ts +1 -0
  477. package/dist/types/components/spinner.d.ts +1 -0
  478. package/dist/types/components/stepform.d.ts +1 -0
  479. package/dist/types/components/stepper.d.ts +1 -0
  480. package/dist/types/components/suggestfield.d.ts +1 -0
  481. package/dist/types/components/table.d.ts +1 -0
  482. package/dist/types/components/tabs.d.ts +1 -0
  483. package/dist/types/components/textarea.d.ts +1 -0
  484. package/dist/types/components/textfield.d.ts +1 -0
  485. package/dist/types/components/toast.d.ts +1 -0
  486. package/dist/types/components/toggle.d.ts +1 -0
  487. package/dist/types/components/toolbar.d.ts +1 -0
  488. package/dist/types/components/tooltip.d.ts +1 -0
  489. package/dist/types/components/tree.d.ts +1 -0
  490. package/dist/types/components/viewmanager.d.ts +1 -0
  491. package/dist/types/components/viewport.d.ts +1 -0
  492. package/dist/types/components/widget.d.ts +1 -0
  493. package/dist/types/components/window.d.ts +1 -0
  494. package/dist/types/core/component.d.ts +94 -0
  495. package/dist/types/core/container.d.ts +43 -0
  496. package/dist/types/core/date.d.ts +14 -0
  497. package/dist/types/core/dom.d.ts +11 -0
  498. package/dist/types/core/emitter.d.ts +12 -0
  499. package/dist/types/core/field.d.ts +78 -0
  500. package/dist/types/core/focus.d.ts +18 -0
  501. package/dist/types/core/i18n.d.ts +12 -0
  502. package/dist/types/core/index.d.ts +15 -0
  503. package/dist/types/core/layer.d.ts +6 -0
  504. package/dist/types/core/position.d.ts +19 -0
  505. package/dist/types/core/registry.d.ts +12 -0
  506. package/dist/types/core/validators.d.ts +10 -0
  507. package/dist/types/core/virtual.d.ts +24 -0
  508. package/dist/types/data/column.d.ts +32 -0
  509. package/dist/types/data/format.d.ts +4 -0
  510. package/dist/types/data/index.d.ts +5 -0
  511. package/dist/types/data/model.d.ts +28 -0
  512. package/dist/types/data/proxy.d.ts +61 -0
  513. package/dist/types/data/store.d.ts +94 -0
  514. package/dist/types/index.d.ts +67 -0
  515. package/dist/types/layout/layout.d.ts +27 -0
  516. package/dist/types/motion/config.d.ts +83 -0
  517. package/dist/types/motion/core.d.ts +40 -0
  518. package/dist/types/motion/extras.d.ts +66 -0
  519. package/dist/types/motion/index.d.ts +3 -0
  520. package/dist/types/themes/define.d.ts +31 -0
  521. package/dist/types/themes/index.d.ts +1 -0
  522. package/dist/types/ui/enums.d.ts +82 -0
  523. package/dist/types/ui/index.d.ts +2 -0
  524. package/dist/types/ui/ui.d.ts +67 -0
  525. package/dist/ui.js +2 -0
  526. package/dist/ui.js.map +7 -0
  527. package/package.json +104 -4
@@ -0,0 +1,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, addMessages } 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\naddMessages('en', {\n views: 'Views',\n viewsName: 'Name for this view',\n viewsSave: 'Save view',\n viewsSaveAs: 'Save as new view\u2026',\n viewsDefault: 'Open with this view',\n viewsDelete: 'Delete view',\n viewsConfirmDelete: 'Delete the view \"{n}\"?',\n viewsReset: 'Reset to initial',\n});\naddMessages('pt-BR', {\n views: 'Vis\u00F5es',\n viewsName: 'Nome desta vis\u00E3o',\n viewsSave: 'Salvar vis\u00E3o',\n viewsSaveAs: 'Salvar como nova vis\u00E3o\u2026',\n viewsDefault: 'Abrir com esta vis\u00E3o',\n viewsDelete: 'Excluir vis\u00E3o',\n viewsConfirmDelete: 'Excluir a vis\u00E3o \"{n}\"?',\n viewsReset: 'Voltar ao inicial',\n});\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": ["addMessages", "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{c as h}from"./chunk-ZWNQREWS.js";import{c as m}from"./chunk-VV7CFMPZ.js";import{c as d}from"./chunk-4EZJ5FKJ.js";import{b as r}from"./chunk-PZSHOSOS.js";import{a as f}from"./chunk-TIPK3SCJ.js";import{e as p,f as l}from"./chunk-MW3RWBZ7.js";p("en",{tabErrors:"errors"});p("pt-BR",{tabErrors:"erros"});var b=class extends h{baseCls="op-tabs";barEl;panelsEl;tabs=new Map;pending=new Set;rover;constructor(t={}){super({defaultType:"container",...t})}getBody(){return this.panelsEl}build(){let t=this.config.position==="left",e=r("div",`op-tabs${t?" op-tabs--left":""}`);return this.barEl=r("div","op-tabs__bar",{role:"tablist","aria-orientation":t?"vertical":"horizontal"}),this.panelsEl=r("div","op-tabs__panels"),e.append(this.barEl,this.panelsEl),e}onRender(){let t=this.config;t.layout={type:"card",activeItem:t.active??0},this.items.forEach(e=>this.addHeader(e)),this.rover=m(this.barEl,{selector:"[role=tab]",orientation:t.position==="left"?"vertical":"horizontal",onMove:e=>this.setActive(this.items.find(i=>this.tabs.get(i)===e))}),this.own(()=>this.rover?.destroy()),this.on("activate",e=>this.syncHeaders(e)),this.listen(this.barEl,"click",e=>{let i=e.target,s=i.closest("[role=tab]"),o=this.items.find(n=>this.tabs.get(n)===s);o&&(i.closest(".op-tabs__close")?this.closeTab(o):i.closest(".op-tabs__reload")?(this.setActive(o),this.reloadTab(o)):this.setActive(o))}),this.listen(this.barEl,"keydown",e=>{let i=this.items.find(s=>this.tabs.get(s)===e.target.closest("[role=tab]"));e.key==="Delete"&&i?this.closeTab(i):i&&(e.key==="r"||e.key==="R")&&!e.ctrlKey&&!e.metaKey&&!e.altKey&&this.tabConfig(i).reloadable&&this.reloadTab(i)}),super.onRender()}forcing;attach(t,e){if(this.config.lazy!==!1&&t!==this.getActiveItem()&&t!==this.forcing){this.pending.add(t);return}super.attach(t,e),t.el.setAttribute("role","tabpanel"),t.el.tabIndex=0;let i=this.tabs.get(t);i&&(t.el.setAttribute("aria-labelledby",i.id),i.setAttribute("aria-controls",t.el.id))}ensure(t){this.pending.delete(t)&&(this.forcing=t,this.attach(t,this.items.indexOf(t)),this.forcing=void 0)}tabConfig(t){let e=t.config;return{title:e.title??"",icon:e.icon,closable:e.closable??this.config.closable??!1,reloadable:e.reloadable??this.config.reloadable??!1,disabled:!!e.disabled}}addHeader(t){let{title:e,icon:i,closable:s,reloadable:o,disabled:n}=this.tabConfig(t),a=r("div","op-tabs__tab",{role:"tab",id:`${t.id}-tab`,tabindex:-1,"aria-selected":"false","aria-disabled":n?"true":null});a.append(i?d(i):"",r("span","op-tabs__title",{},e)),o&&a.append(r("span","op-tabs__reload",{"aria-hidden":"true","data-op-tip":l("reload")},d("refresh"))),s&&a.append(r("span","op-tabs__close",{"aria-hidden":"true","data-op-tip":l("close")},d("x"))),this.tabs.set(t,a),this.barEl.append(...[...this.items].filter(c=>this.tabs.has(c)).map(c=>this.tabs.get(c)))}syncHeaders(t){for(let[i,s]of this.tabs){let o=i===t;s.setAttribute("aria-selected",String(o)),s.classList.toggle("is-active",o)}let e=t&&this.tabs.get(t);this.rover?.sync(e||void 0)}getActive(){return this.getActiveItem()}setActive(t){let e=typeof t=="number"?this.items[t]:typeof t=="string"?this.items.find(s=>s.id===t):t,i=this.getActiveItem();!e||e===i||this.tabConfig(e).disabled||this.emit("before-change",e,i)!==!1&&(this.ensure(e),this.setActiveItem(e),this.emit("change",e,this.items.indexOf(e)))}insert(t,e){let i=super.insert(t,e);return this.rendered&&(this.addHeader(i),this.ensure(i),this.setActive(i)),i}async reloadTab(t){let e=typeof t=="number"?this.items[t]:typeof t=="string"?this.items.find(o=>o.id===t):t,i=e&&this.tabs.get(e);if(!e||i?.classList.contains("is-reloading")||this.emit("before-reload",e)===!1)return!1;i?.classList.add("is-reloading");let s=e.config.onReload?.(e);return s instanceof Promise&&(e.setLoading(!0),await s.catch(()=>{}),e.setLoading(!1)),i?.classList.remove("is-reloading"),this.emit("reload",e),!0}closeTab(t){let e=typeof t=="number"?this.items[t]:typeof t=="string"?this.items.find(i=>i.id===t):t;!e||this.emit("before-close",e)===!1||(this.remove(e),this.emit("close",e))}remove(t,e=!0){let i=typeof t=="number"?this.items[t]:typeof t=="string"?this.items.find(n=>n.id===t):t,s=i&&this.tabs.get(i)?.contains(document.activeElement),o=super.remove(t,e);if(i){this.tabs.get(i)?.remove(),this.tabs.delete(i),this.pending.delete(i);let n=this.getActiveItem();n&&this.ensure(n),s&&n&&this.tabs.get(n)?.focus()}return o}setTabState(t,e){let i=this.tabs.get(t);if(!i)return;i.classList.toggle("has-error",!!e.errors),i.classList.toggle("is-dirty",!!e.dirty);let s=i.querySelector(".op-tabs__badge");if(!e.errors)return s?.remove();s||(s=r("span","op-tabs__badge"),i.insertBefore(s,i.querySelector(".op-tabs__close"))),s.replaceChildren(String(e.errors),r("span","op-sr-only",{},` ${l("tabErrors")}`))}setTitle(t,e){t.config.title=e;let i=this.tabs.get(t)?.querySelector(".op-tabs__title");i&&(i.textContent=e)}};f("tabs",b);export{b as a};
2
+ //# sourceMappingURL=chunk-CKXS375P.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/navigation/tabs/tabs.ts"],
4
+ "sourcesContent": ["import { Container, type ContainerConfig } from '../../../core/container';\nimport '../../layout/panel/reload';\nimport { Component } from '../../../core/component';\nimport { register, type AnyConfig } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { t, addMessages } from '../../../core/i18n';\nimport { roving } from '../../../core/focus';\nimport { iconEl } from '../../base/icon/icon';\n\naddMessages('en', {\n tabErrors: 'errors',\n});\naddMessages('pt-BR', {\n tabErrors: 'erros',\n});\n\nexport interface TabsConfig extends ContainerConfig {\n /** Initially active tab (index or id). */\n active?: number | string;\n position?: 'top' | 'left';\n /** Build a panel's DOM only the first time its tab is activated. Default true. */\n lazy?: boolean;\n /** Default `closable` for tabs. */\n closable?: boolean;\n /** Default `reloadable` for tabs: a \u21BB in the tab that calls the panel's `onReload`. */\n reloadable?: boolean;\n}\n\n/**\n * Items are the panels. Each may carry `title`, `icon`, `closable` and `disabled` for its tab header.\n * Tabs reuse the `card` layout of Container for the panels.\n */\nexport class Tabs extends Container<TabsConfig> {\n protected override baseCls = 'op-tabs';\n private barEl!: HTMLElement;\n private panelsEl!: HTMLElement;\n private tabs = new Map<Component, HTMLElement>();\n private pending = new Set<Component>();\n private rover?: ReturnType<typeof roving>;\n\n constructor(config: TabsConfig = {}) {\n super({ defaultType: 'container', ...config });\n }\n\n override getBody() {\n return this.panelsEl;\n }\n\n protected override build() {\n const left = this.config.position === 'left';\n const el = h('div', `op-tabs${left ? ' op-tabs--left' : ''}`);\n this.barEl = h('div', 'op-tabs__bar', { role: 'tablist', 'aria-orientation': left ? 'vertical' : 'horizontal' });\n this.panelsEl = h('div', 'op-tabs__panels');\n el.append(this.barEl, this.panelsEl);\n return el;\n }\n\n protected override onRender() {\n const c = this.config;\n c.layout = { type: 'card', activeItem: c.active ?? 0 };\n this.items.forEach((p) => this.addHeader(p));\n this.rover = roving(this.barEl, {\n selector: '[role=tab]',\n orientation: c.position === 'left' ? 'vertical' : 'horizontal',\n onMove: (tab) => this.setActive(this.items.find((p) => this.tabs.get(p) === tab)!),\n });\n this.own(() => this.rover?.destroy());\n this.on('activate', (p?: Component) => this.syncHeaders(p));\n this.listen(this.barEl, 'click', (e: Event) => {\n const target = e.target as HTMLElement;\n const tab = target.closest<HTMLElement>('[role=tab]');\n const panel = this.items.find((p) => this.tabs.get(p) === tab);\n if (!panel) return;\n if (target.closest('.op-tabs__close')) this.closeTab(panel);\n else if (target.closest('.op-tabs__reload')) (this.setActive(panel), void this.reloadTab(panel));\n else this.setActive(panel);\n });\n this.listen(this.barEl, 'keydown', (e: KeyboardEvent) => {\n const panel = this.items.find((p) => this.tabs.get(p) === (e.target as HTMLElement).closest('[role=tab]'));\n if (e.key === 'Delete' && panel) this.closeTab(panel);\n else if (panel && (e.key === 'r' || e.key === 'R') && !e.ctrlKey && !e.metaKey && !e.altKey && this.tabConfig(panel).reloadable) void this.reloadTab(panel);\n });\n super.onRender();\n }\n\n private forcing?: Component;\n\n /** Lazy panels (everything but the active one) are attached the first time they are activated. */\n protected override attach(p: Component, index: number) {\n if (this.config.lazy !== false && p !== this.getActiveItem() && p !== this.forcing) {\n this.pending.add(p);\n return;\n }\n super.attach(p, index);\n p.el.setAttribute('role', 'tabpanel');\n p.el.tabIndex = 0; // APG: the panel is reachable by Tab even when its content has nothing focusable (or scrolls)\n const tab = this.tabs.get(p);\n if (tab) {\n p.el.setAttribute('aria-labelledby', tab.id);\n tab.setAttribute('aria-controls', p.el.id);\n }\n }\n\n /** Builds a pending panel's DOM now. */\n private ensure(p: Component) {\n if (!this.pending.delete(p)) return;\n this.forcing = p;\n this.attach(p, this.items.indexOf(p));\n this.forcing = undefined;\n }\n\n private tabConfig(p: Component) {\n const c = p.config as AnyConfig;\n return { title: (c.title as string) ?? '', icon: c.icon as string | undefined, closable: (c.closable as boolean) ?? this.config.closable ?? false, reloadable: (c.reloadable as boolean) ?? this.config.reloadable ?? false, disabled: !!c.disabled };\n }\n\n private addHeader(p: Component) {\n const { title, icon, closable, reloadable, disabled } = this.tabConfig(p);\n const tab = h('div', 'op-tabs__tab', { role: 'tab', id: `${p.id}-tab`, tabindex: -1, 'aria-selected': 'false', 'aria-disabled': disabled ? 'true' : null });\n tab.append(icon ? iconEl(icon) : '', h('span', 'op-tabs__title', {}, title));\n if (reloadable) tab.append(h('span', 'op-tabs__reload', { 'aria-hidden': 'true', 'data-op-tip': t('reload') }, iconEl('refresh')));\n if (closable) tab.append(h('span', 'op-tabs__close', { 'aria-hidden': 'true', 'data-op-tip': t('close') }, iconEl('x')));\n this.tabs.set(p, tab);\n this.barEl.append(...[...this.items].filter((x) => this.tabs.has(x)).map((x) => this.tabs.get(x)!));\n }\n\n private syncHeaders(active?: Component) {\n for (const [p, tab] of this.tabs) {\n const on = p === active;\n tab.setAttribute('aria-selected', String(on));\n tab.classList.toggle('is-active', on);\n }\n const tab = active && this.tabs.get(active);\n this.rover?.sync(tab || undefined);\n }\n\n // ---- API -----------------------------------------------------------------------------------\n\n getActive(): Component | undefined {\n return this.getActiveItem();\n }\n\n /** Activates a tab (instance, id or index). `before-change` can cancel. */\n setActive(tab: Component | string | number): void {\n const p = typeof tab === 'number' ? this.items[tab] : typeof tab === 'string' ? this.items.find((x) => x.id === tab) : tab;\n const prev = this.getActiveItem();\n if (!p || p === prev || this.tabConfig(p).disabled) return;\n if (this.emit('before-change', p, prev) === false) return;\n this.ensure(p);\n this.setActiveItem(p);\n this.emit('change', p, this.items.indexOf(p));\n }\n\n override insert(index: number, item: AnyConfig | Component | string): Component {\n const p = super.insert(index, item);\n if (this.rendered) {\n this.addHeader(p);\n this.ensure(p); // a tab added after render becomes the active one right away\n this.setActive(p);\n }\n return p;\n }\n\n /**\n * Reloads a tab: calls its panel's `onReload` (`before-reload` can cancel). While a returned Promise is pending the panel\n * shows its loading mask and the tab's \u21BB spins; `reload(panel)` fires when it is done.\n */\n async reloadTab(tab: Component | string | number): Promise<boolean> {\n const p = typeof tab === 'number' ? this.items[tab] : typeof tab === 'string' ? this.items.find((x) => x.id === tab) : tab;\n const head = p && this.tabs.get(p);\n if (!p || head?.classList.contains('is-reloading') || this.emit('before-reload', p) === false) return false;\n head?.classList.add('is-reloading');\n const busy = (p.config as AnyConfig).onReload?.(p) as unknown;\n if (busy instanceof Promise) {\n p.setLoading(true);\n await busy.catch(() => undefined);\n p.setLoading(false);\n }\n head?.classList.remove('is-reloading');\n this.emit('reload', p);\n return true;\n }\n\n /** Closes a tab (`before-close` can cancel). The neighbor becomes active. */\n closeTab(tab: Component | string | number): void {\n const p = typeof tab === 'number' ? this.items[tab] : typeof tab === 'string' ? this.items.find((x) => x.id === tab) : tab;\n if (!p || this.emit('before-close', p) === false) return;\n this.remove(p);\n this.emit('close', p);\n }\n\n override remove(child: Component | string | number, destroy = true): Component | undefined {\n const p = typeof child === 'number' ? this.items[child] : typeof child === 'string' ? this.items.find((x) => x.id === child) : child;\n const hadFocus = p && this.tabs.get(p)?.contains(document.activeElement);\n const removed = super.remove(child, destroy);\n if (p) {\n this.tabs.get(p)?.remove();\n this.tabs.delete(p);\n this.pending.delete(p);\n const active = this.getActiveItem();\n if (active) this.ensure(active);\n if (hadFocus && active) this.tabs.get(active)?.focus();\n }\n return removed;\n }\n\n /** Marks a tab header: a badge with the number of errors in its panel and a dot while something in it changed. */\n setTabState(tab: Component, state: { errors?: number; dirty?: boolean }): void {\n const el = this.tabs.get(tab);\n if (!el) return;\n el.classList.toggle('has-error', !!state.errors);\n el.classList.toggle('is-dirty', !!state.dirty);\n let badge = el.querySelector<HTMLElement>('.op-tabs__badge');\n if (!state.errors) return badge?.remove();\n if (!badge) {\n badge = h('span', 'op-tabs__badge');\n el.insertBefore(badge, el.querySelector('.op-tabs__close'));\n }\n badge.replaceChildren(String(state.errors), h('span', 'op-sr-only', {}, ` ${t('tabErrors')}`));\n }\n\n setTitle(tab: Component, title: string) {\n (tab.config as AnyConfig).title = title;\n const el = this.tabs.get(tab)?.querySelector('.op-tabs__title');\n if (el) el.textContent = title;\n }\n}\nregister('tabs', Tabs);\n"],
5
+ "mappings": "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",
6
+ "names": ["addMessages", "Tabs", "Container", "config", "left", "el", "h", "c", "p", "roving", "tab", "target", "panel", "index", "title", "icon", "closable", "reloadable", "disabled", "iconEl", "t", "x", "active", "on", "prev", "item", "head", "busy", "child", "destroy", "hadFocus", "removed", "state", "badge", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as h}from"./chunk-VF7BGP6L.js";import{a}from"./chunk-2ZUZ5HDL.js";import{a as f}from"./chunk-A2NKDOYN.js";import{b as o}from"./chunk-PZSHOSOS.js";import{a as p,c}from"./chunk-TIPK3SCJ.js";import{f as n}from"./chunk-MW3RWBZ7.js";var m=new Map;function M(r,e){m.set(r,e)}function g(r){let e=typeof r=="string"?m.get(r):r;if(!e)throw new Error(`Optikos: unknown lookup "${r}". Did you call registerLookup?`);return e}var y=r=>typeof r.store=="function"?r.store():r.store,v=r=>!r||r==="textfield"||r==="textarea",k=r=>r==null||r===""||Array.isArray(r)&&!r.length,l=class extends f{baseCls="op-searchgrid";def;store;fields=[];grid;form;build(){this.def=g(this.config.lookup),this.store=y(this.def);let e=this.def;this.form=o("div","op-searchgrid__filters",{role:"search"});let i=[new a({text:n("search"),icon:"search",variant:"primary",handler:()=>{this.search()}}),new a({text:n("clear"),handler:()=>this.clear()})];return this.fields=(e.filters??[]).map(t=>{let{op:s,field:x,...u}=t,d=c({...u,renderTo:void 0});return d.on("enter",()=>{this.search()}),{cfg:t,cmp:d}}),this.form.append(...this.fields.map(t=>t.cmp.el),o("div","op-searchgrid__buttons",{},...i.map(t=>t.el))),this.grid=new h({store:this.store,columns:e.columns,selection:e.selection??"single",paging:e.paging!==!1,flex:1}),this.grid.on("select",t=>this.emit("select",t)),this.grid.on("row-activate",()=>this.confirm()),this.grid.on("row-dblclick",()=>this.confirm()),this.own(()=>[...i,this.grid,...this.fields.map(t=>t.cmp)].forEach(t=>t.destroy())),o("div",this.baseCls,{},this.form,this.grid.el)}onRender(){this.def.autoSearch!==!1&&this.search()}notifyMount(){super.notifyMount(),this.fields.forEach(e=>e.cmp.notifyMount()),this.grid.notifyMount()}confirm(){let e=this.grid.getSelection();e.length&&this.emit("confirm",e)}getFilters(){return this.fields.flatMap(({cfg:e,cmp:i})=>{let t=i.getValue?.();if(k(t))return[];let s=e.field??e.name;return typeof t=="object"&&!Array.isArray(t)&&"start"in t?t.start?[{field:s,op:"between",value:[t.start,t.end??t.start]}]:[]:[{field:s,op:e.op??(v(e.type)?"contains":"eq"),value:t}]})}async search(e){e!=null&&this.setQuery(e);let i=this.getFilters();this.emit("before-search",i)!==!1&&(await(i.length?this.store.filter(i):this.store.clearFilter()),this.emit("search",i))}clear(){this.fields.forEach(e=>e.cmp.clear?.()),this.search()}setQuery(e){let i=this.def.queryField??this.def.filters?.[0]?.name;this.fields.find(t=>t.cfg.name===i)?.cmp?.setValue?.(e)}getSelection(){return this.grid.getSelection()}getGrid(){return this.grid}getStore(){return this.store}focus(){(this.fields[0]?.cmp??this.grid).focus()}};p("searchgrid",l);export{M as a,g as b,y as c,l as d};
2
+ //# sourceMappingURL=chunk-CUN5QO4T.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/data/searchgrid/searchgrid.ts"],
4
+ "sourcesContent": ["import { Component, type ComponentConfig } from '../../../core/component';\nimport { register, create, type AnyConfig } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { t } from '../../../core/i18n';\nimport type { Store } from '../../../data/store';\nimport type { Model } from '../../../data/model';\nimport type { Column } from '../../../data/column';\nimport type { FilterOp, FilterSpec } from '../../../data/proxy';\nimport { Button } from '../../base/button/button';\nimport { Grid } from '../grid/grid';\n\n/** A filter field of a lookup: any field config, plus how its value is matched. */\nexport type LookupFilter = AnyConfig & { name: string; op?: FilterOp; field?: string };\n\n/** Everything that describes \"search for a record\": shared by SearchGrid and LookupField. */\nexport interface LookupDef {\n /** A function gives every instance its own store (recommended when the definition is reused). */\n store: Store<any> | (() => Store<any>);\n columns: Column[];\n filters?: LookupFilter[];\n /** Name of the filter that receives the quick text (LookupField typing). Default: the first filter. */\n queryField?: string;\n valueField?: string;\n displayField?: string;\n selection?: 'single' | 'multi';\n paging?: boolean;\n /** Search when shown. Default true. */\n autoSearch?: boolean;\n title?: string;\n width?: number;\n height?: number;\n}\n\nconst defs = new Map<string, LookupDef>();\n/** Registers a lookup definition for declarative use by name (`lookup: 'people'`). */\nexport function registerLookup(name: string, def: LookupDef): void {\n defs.set(name, def);\n}\nexport function resolveLookup(lookup: LookupDef | string): LookupDef {\n const d = typeof lookup === 'string' ? defs.get(lookup) : lookup;\n if (!d) throw new Error(`Optikos: unknown lookup \"${lookup}\". Did you call registerLookup?`);\n return d;\n}\nexport const lookupStore = (def: LookupDef): Store<any> => (typeof def.store === 'function' ? def.store() : def.store);\n\nexport interface SearchGridConfig extends ComponentConfig {\n lookup: LookupDef | string;\n}\n\nconst textual = (type?: string) => !type || type === 'textfield' || type === 'textarea';\nconst blank = (v: unknown) => v == null || v === '' || (Array.isArray(v) && !v.length);\n\n/** Filters on top, results grid below. The Store does the searching; this component only turns the filter fields into specs. */\nexport class SearchGrid extends Component<SearchGridConfig> {\n protected override baseCls = 'op-searchgrid';\n private def!: LookupDef;\n private store!: Store<any>;\n private fields: Array<{ cfg: LookupFilter; cmp: Component }> = [];\n private grid!: Grid;\n private form!: HTMLElement;\n\n protected override build() {\n this.def = resolveLookup(this.config.lookup);\n this.store = lookupStore(this.def);\n const d = this.def;\n this.form = h('div', 'op-searchgrid__filters', { role: 'search' });\n const btns = [\n new Button({ text: t('search'), icon: 'search', variant: 'primary', handler: () => void this.search() }),\n new Button({ text: t('clear'), handler: () => this.clear() }),\n ];\n this.fields = (d.filters ?? []).map((cfg) => {\n const { op: _o, field: _f, ...fieldCfg } = cfg;\n const cmp = create({ ...fieldCfg, renderTo: undefined } as AnyConfig);\n cmp.on('enter', () => void this.search());\n return { cfg, cmp };\n });\n this.form.append(...this.fields.map((f) => f.cmp.el), h('div', 'op-searchgrid__buttons', {}, ...btns.map((b) => b.el)));\n this.grid = new Grid({ store: this.store, columns: d.columns, selection: d.selection ?? 'single', paging: d.paging !== false, flex: 1 });\n this.grid.on('select', (recs: Model[]) => this.emit('select', recs));\n this.grid.on('row-activate', () => this.confirm());\n this.grid.on('row-dblclick', () => this.confirm());\n this.own(() => [...btns, this.grid, ...this.fields.map((f) => f.cmp)].forEach((c) => c.destroy()));\n return h('div', this.baseCls, {}, this.form, this.grid.el);\n }\n\n protected override onRender() {\n if (this.def.autoSearch !== false) void this.search();\n }\n\n override notifyMount() {\n super.notifyMount();\n this.fields.forEach((f) => f.cmp.notifyMount());\n this.grid.notifyMount();\n }\n\n private confirm() {\n const recs = this.grid.getSelection();\n if (recs.length) this.emit('confirm', recs);\n }\n\n /** The non-empty filter fields as filter specs. */\n getFilters(): FilterSpec[] {\n return this.fields.flatMap(({ cfg, cmp }) => {\n const v = (cmp as any).getValue?.();\n if (blank(v)) return [];\n const field = cfg.field ?? cfg.name;\n if (typeof v === 'object' && !Array.isArray(v) && 'start' in v) return v.start ? [{ field, op: 'between' as const, value: [v.start, v.end ?? v.start] }] : [];\n return [{ field, op: cfg.op ?? (textual(cfg.type) ? 'contains' : 'eq'), value: v }];\n });\n }\n\n /** Filters the store with the current fields (or loads it, when there are none). Resolves when the results are in. */\n async search(query?: string): Promise<void> {\n if (query != null) this.setQuery(query);\n const specs = this.getFilters();\n if (this.emit('before-search', specs) === false) return;\n await (specs.length ? this.store.filter(specs) : this.store.clearFilter());\n this.emit('search', specs);\n }\n\n /** Empties the filter fields and searches again. */\n clear(): void {\n this.fields.forEach((f) => (f.cmp as any).clear?.());\n void this.search();\n }\n\n /** Fills the quick-search field (`queryField`, default the first filter) without searching. */\n setQuery(text: string): void {\n const name = this.def.queryField ?? this.def.filters?.[0]?.name;\n (this.fields.find((f) => f.cfg.name === name)?.cmp as any)?.setValue?.(text);\n }\n\n getSelection(): Model[] {\n return this.grid.getSelection();\n }\n getGrid(): Grid {\n return this.grid;\n }\n getStore(): Store<any> {\n return this.store;\n }\n override focus(): void {\n (this.fields[0]?.cmp ?? this.grid).focus();\n }\n}\nregister('searchgrid', SearchGrid);\n"],
5
+ "mappings": "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",
6
+ "names": ["defs", "registerLookup", "name", "def", "resolveLookup", "lookup", "d", "lookupStore", "textual", "type", "blank", "v", "SearchGrid", "Component", "h", "btns", "Button", "t", "cfg", "_o", "_f", "fieldCfg", "cmp", "create", "f", "b", "Grid", "recs", "c", "field", "query", "specs", "text", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{c}from"./chunk-4EZJ5FKJ.js";import{a as m}from"./chunk-A2NKDOYN.js";import{b as o}from"./chunk-PZSHOSOS.js";import{a as k}from"./chunk-TIPK3SCJ.js";import{e as f,f as u}from"./chunk-MW3RWBZ7.js";f("en",{treeLoading:"Loading\u2026",treeEmpty:"Nothing here"});f("pt-BR",{treeLoading:"Carregando\u2026",treeEmpty:"Nada aqui"});var g=class extends m{baseCls="op-tree";items=[];open=new Set;selected=new Set;loading=new Set;query="";focusId;root;onRender(){let e=this.config;this.items=e.items??[];let t=i=>i.forEach(s=>(s.expanded&&this.open.add(s.id),s.children&&t(s.children)));t(this.items),this.root=o("ul","op-tree__root",{role:"tree","aria-label":e.ariaLabel??null,"aria-multiselectable":e.selection==="multi"?"true":null}),this.el.removeAttribute("aria-label"),this.el.append(this.root),this.listen(this.root,"click",i=>{let s=i.target.closest(".op-tree__item");if(!s)return;let r=s.dataset.id;if(this.focusId=r,i.target.closest(".op-tree__toggle"))return this.toggle(r);if(i.target.closest(".op-tree__check"))return this.toggleChecked(r);this.pick(r,i.ctrlKey||i.metaKey)}),this.listen(this.root,"dblclick",i=>{let s=i.target.closest(".op-tree__item"),r=s&&this.getNode(s.dataset.id);r&&!r.disabled&&this.emit("activate",r)}),this.listen(this.root,"keydown",i=>this.onKey(i)),this.paint()}getNode(e,t=this.items){for(let i of t){if(i.id===e)return i;let s=i.children&&this.getNode(e,i.children);if(s)return s}}getPath(e,t=this.items,i=[]){for(let s of t){if(s.id===e)return i;let r=s.children&&this.getPath(e,s.children,[...i,s]);if(r)return r}}isLeaf(e){return e.leaf??(!e.children&&!this.config.load)}matches(e,t){return e.text.toLowerCase().includes(t)||!!e.children?.some(i=>this.matches(i,t))}walk(e,t){for(let i of e)t(i),i.children&&this.walk(i.children,t)}paint(){let e=this.items.filter(s=>!this.query||this.matches(s,this.query));this.root.replaceChildren(...e.map(s=>this.node(s,1))),e.length||this.root.append(o("li","op-tree__empty",{role:"none"},this.config.emptyText??u("treeEmpty")));let t=this.rows(),i=t.find(s=>s.dataset.id===this.focusId)??t.find(s=>s.getAttribute("aria-selected")==="true")??t[0];t.forEach(s=>s.tabIndex=s===i?0:-1)}node(e,t){let i=this.isLeaf(e),s=!i&&(this.query?!0:this.open.has(e.id)),r=this.loading.has(e.id),h=this.selected.has(e.id),l=this.config.selection??"single",n=this.checkState(e),d=o("li","op-tree__node",{role:"none"}),a=o("div",`op-tree__item${h?" is-selected":""}${e.disabled?" is-disabled":""}${s?" is-expanded":""}${r?" is-loading":""}`,{role:"treeitem","data-id":e.id,"aria-level":t,tabindex:-1,"aria-expanded":i?null:String(s),"aria-selected":l==="none"?null:String(h),"aria-checked":this.config.checkboxes?String(n):null,"aria-disabled":e.disabled?"true":null,"aria-busy":r?"true":null});if(a.style.setProperty("--_level",String(t-1)),a.append(o("span","op-tree__toggle",{"aria-hidden":"true"},i?"":r?o("span","op-spinner op-tree__spinner"):c("chevron-right"))),this.config.checkboxes&&a.append(o("span",`op-tree__check${n===!0?" is-checked":n==="mixed"?" is-mixed":""}`,{"aria-hidden":"true"},n==="mixed"?c("minus"):n?c("check"):"")),e.icon&&a.append(o("span","op-tree__icon",{},c(e.icon))),a.append(o("span","op-tree__text",{},e.text)),d.append(a),s&&e.children?.length){let b=e.children.filter(p=>!this.query||this.matches(p,this.query));d.append(o("ul","op-tree__group",{role:"group"},...b.map(p=>this.node(p,t+1))))}return d}async expand(e){let t=this.getNode(e);if(!(!t||this.isLeaf(t)||this.open.has(e)||this.loading.has(e))){if(!t.children&&this.config.load){this.loading.add(e),this.rendered&&this.paint();try{t.children=await this.config.load(t),this.config.checkboxes&&this.checkState(t)===!0&&t.children.forEach(i=>this.setBranch(i,!0)),this.emit("load",t,t.children)}catch(i){this.loading.delete(e),this.rendered&&this.paint(),this.emit("error",i,t);return}this.loading.delete(e)}this.open.add(e),this.rendered&&this.paint(),this.emit("expand",t)}}collapse(e){let t=this.getNode(e);!t||!this.open.delete(e)||(this.rendered&&this.paint(),this.emit("collapse",t))}toggle(e){this.open.has(e)?this.collapse(e):this.expand(e)}expandAll(){this.walk(this.items,e=>e.children?.length&&this.open.add(e.id)),this.rendered&&this.paint()}collapseAll(){this.open.clear(),this.rendered&&this.paint()}pick(e,t){let i=this.getNode(e),s=this.config.selection??"single";!i||i.disabled||s==="none"||(s==="multi"&&t?this.selected.delete(e)||this.selected.add(e):(this.selected.clear(),this.selected.add(e)),this.rendered&&this.paint(),this.emit("select",this.getSelection()))}select(e,t={}){for(let i of this.getPath(e)??[])this.open.add(i.id);this.focusId=e,this.pick(e,!!t.add)}getSelection(){return[...this.selected].map(e=>this.getNode(e)).filter(e=>!!e)}deselectAll(){this.selected.clear(),this.rendered&&this.paint(),this.emit("select",[])}checkState(e){if(!e.children?.length)return!!e.checked;let t=e.children.map(i=>this.checkState(i));return t.every(i=>i===!0)?!0:t.some(i=>i!==!1)?"mixed":!1}setBranch(e,t){e.checked=t,e.children?.forEach(i=>this.setBranch(i,t))}setChecked(e,t){let i=this.getNode(e);!i||i.disabled||(this.setBranch(i,t),this.rendered&&this.paint(),this.emit("check",this.getChecked(),i))}toggleChecked(e){let t=this.getNode(e);t&&this.setChecked(e,this.checkState(t)!==!0)}getChecked(){let e=[];return this.walk(this.items,t=>this.checkState(t)===!0&&e.push(t)),e}setItems(e){this.items=e,this.config.items=e,this.selected.clear(),this.rendered&&this.paint()}filter(e){this.query=e.trim().toLowerCase(),this.rendered&&this.paint()}rows(){return Array.from(this.root.querySelectorAll(".op-tree__item"))}focusRow(e){e&&(this.rows().forEach(t=>t.tabIndex=t===e?0:-1),this.focusId=e.dataset.id,e.focus())}onKey(e){let t=e.target.closest(".op-tree__item");if(!t)return;let i=this.rows(),s=i.indexOf(t),r=this.getNode(t.dataset.id),h=t.getAttribute("aria-expanded")==="true",l=t.getAttribute("aria-expanded")==="false";switch(e.key){case"ArrowDown":this.focusRow(i[s+1]);break;case"ArrowUp":this.focusRow(i[s-1]);break;case"Home":this.focusRow(i[0]);break;case"End":this.focusRow(i[i.length-1]);break;case"ArrowRight":l?this.expand(r.id):h&&this.focusRow(i[s+1]);break;case"ArrowLeft":if(h)this.collapse(r.id);else{let d=this.getPath(r.id)?.pop();d&&this.focusRow(i.find(a=>a.dataset.id===d.id))}break;case" ":this.config.checkboxes?this.toggleChecked(r.id):this.pick(r.id,this.config.selection==="multi");break;case"Enter":this.pick(r.id,!1),r.disabled||this.emit("activate",r);break;default:return}e.preventDefault();let n=this.root.querySelector(`[data-id="${CSS.escape(this.focusId??r.id)}"]`);n&&document.activeElement!==n&&this.focusRow(n)}};k("tree",g);export{g as a};
2
+ //# sourceMappingURL=chunk-DBMWS3O5.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/data/tree/tree.ts"],
4
+ "sourcesContent": ["import { Component, type ComponentConfig } from '../../../core/component';\nimport { register } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { t, addMessages } from '../../../core/i18n';\nimport { iconEl } from '../../base/icon/icon';\n\naddMessages('en', { treeLoading: 'Loading\u2026', treeEmpty: 'Nothing here' });\naddMessages('pt-BR', { treeLoading: 'Carregando\u2026', treeEmpty: 'Nada aqui' });\n\nexport interface TreeNode {\n id: string;\n text: string;\n icon?: string;\n children?: TreeNode[];\n /** No children and nothing to load: no expand arrow. Default: true when there are no `children` and no `load`. */\n leaf?: boolean;\n expanded?: boolean;\n disabled?: boolean;\n /** With `checkboxes`: the node's own state (a parent's state comes from its children). */\n checked?: boolean;\n data?: unknown;\n}\nexport type CheckState = boolean | 'mixed';\n\nexport interface TreeConfig extends ComponentConfig {\n items?: TreeNode[];\n /** `single` (default), `multi` (Ctrl/\u2318 + click or Space toggle) or `none`. */\n selection?: 'single' | 'multi' | 'none';\n /** A tri-state checkbox per node: checking a parent checks its whole branch; a parent shows \"mixed\" when partly checked. */\n checkboxes?: boolean;\n /** Children on demand: called the first time a node without `children` (and not `leaf`) is expanded. */\n load?: (node: TreeNode) => Promise<TreeNode[]> | TreeNode[];\n emptyText?: string;\n}\n\n/** A hierarchy: expand/collapse, single or multiple selection, tri-state checkboxes, children loaded on demand, filter, APG tree keyboard. */\nexport class Tree extends Component<TreeConfig> {\n protected override baseCls = 'op-tree';\n private items: TreeNode[] = [];\n private open = new Set<string>();\n private selected = new Set<string>();\n private loading = new Set<string>();\n private query = '';\n private focusId?: string;\n private root!: HTMLElement;\n\n protected override onRender() {\n const c = this.config;\n this.items = c.items ?? [];\n const seed = (list: TreeNode[]) => list.forEach((n) => (n.expanded && this.open.add(n.id), n.children && seed(n.children)));\n seed(this.items);\n this.root = h('ul', 'op-tree__root', { role: 'tree', 'aria-label': c.ariaLabel ?? null, 'aria-multiselectable': c.selection === 'multi' ? 'true' : null });\n this.el.removeAttribute('aria-label');\n this.el.append(this.root);\n this.listen(this.root, 'click', (e: MouseEvent) => {\n const row = (e.target as HTMLElement).closest<HTMLElement>('.op-tree__item');\n if (!row) return;\n const id = row.dataset.id!;\n this.focusId = id;\n if ((e.target as HTMLElement).closest('.op-tree__toggle')) return this.toggle(id);\n if ((e.target as HTMLElement).closest('.op-tree__check')) return this.toggleChecked(id);\n this.pick(id, e.ctrlKey || e.metaKey);\n });\n this.listen(this.root, 'dblclick', (e: Event) => {\n const row = (e.target as HTMLElement).closest<HTMLElement>('.op-tree__item');\n const n = row && this.getNode(row.dataset.id!);\n if (n && !n.disabled) this.emit('activate', n);\n });\n this.listen(this.root, 'keydown', (e: KeyboardEvent) => this.onKey(e));\n this.paint();\n }\n\n // ---- model -----------------------------------------------------------------------------------\n\n getNode(id: string, list = this.items): TreeNode | undefined {\n for (const n of list) {\n if (n.id === id) return n;\n const hit = n.children && this.getNode(id, n.children);\n if (hit) return hit;\n }\n }\n /** The ancestors of a node, from the root down. */\n getPath(id: string, list = this.items, trail: TreeNode[] = []): TreeNode[] | undefined {\n for (const n of list) {\n if (n.id === id) return trail;\n const hit = n.children && this.getPath(id, n.children, [...trail, n]);\n if (hit) return hit;\n }\n }\n private isLeaf(n: TreeNode) {\n return n.leaf ?? (!n.children && !this.config.load);\n }\n private matches(n: TreeNode, q: string): boolean {\n return n.text.toLowerCase().includes(q) || !!n.children?.some((c) => this.matches(c, q));\n }\n private walk(list: TreeNode[], fn: (n: TreeNode) => void) {\n for (const n of list) {\n fn(n);\n if (n.children) this.walk(n.children, fn);\n }\n }\n\n // ---- rendering -------------------------------------------------------------------------------\n\n private paint() {\n const shown = this.items.filter((n) => !this.query || this.matches(n, this.query));\n this.root.replaceChildren(...shown.map((n) => this.node(n, 1)));\n if (!shown.length) this.root.append(h('li', 'op-tree__empty', { role: 'none' }, this.config.emptyText ?? t('treeEmpty')));\n const rows = this.rows();\n const focus = rows.find((r) => r.dataset.id === this.focusId) ?? rows.find((r) => r.getAttribute('aria-selected') === 'true') ?? rows[0];\n rows.forEach((r) => (r.tabIndex = r === focus ? 0 : -1));\n }\n\n private node(n: TreeNode, level: number): HTMLElement {\n const leaf = this.isLeaf(n);\n const open = !leaf && (this.query ? true : this.open.has(n.id));\n const busy = this.loading.has(n.id);\n const sel = this.selected.has(n.id);\n const mode = this.config.selection ?? 'single';\n const state = this.checkState(n);\n const li = h('li', 'op-tree__node', { role: 'none' });\n const row = h('div', `op-tree__item${sel ? ' is-selected' : ''}${n.disabled ? ' is-disabled' : ''}${open ? ' is-expanded' : ''}${busy ? ' is-loading' : ''}`, {\n role: 'treeitem', 'data-id': n.id, 'aria-level': level, tabindex: -1,\n 'aria-expanded': leaf ? null : String(open), 'aria-selected': mode === 'none' ? null : String(sel),\n 'aria-checked': this.config.checkboxes ? String(state) : null, 'aria-disabled': n.disabled ? 'true' : null, 'aria-busy': busy ? 'true' : null,\n });\n row.style.setProperty('--_level', String(level - 1));\n row.append(h('span', 'op-tree__toggle', { 'aria-hidden': 'true' }, leaf ? '' : busy ? h('span', 'op-spinner op-tree__spinner') : iconEl('chevron-right')));\n if (this.config.checkboxes) row.append(h('span', `op-tree__check${state === true ? ' is-checked' : state === 'mixed' ? ' is-mixed' : ''}`, { 'aria-hidden': 'true' }, state === 'mixed' ? iconEl('minus') : state ? iconEl('check') : ''));\n if (n.icon) row.append(h('span', 'op-tree__icon', {}, iconEl(n.icon)));\n row.append(h('span', 'op-tree__text', {}, n.text));\n li.append(row);\n if (open && n.children?.length) {\n const kids = n.children.filter((c) => !this.query || this.matches(c, this.query));\n li.append(h('ul', 'op-tree__group', { role: 'group' }, ...kids.map((c) => this.node(c, level + 1))));\n }\n return li;\n }\n\n // ---- expand / load ---------------------------------------------------------------------------\n\n async expand(id: string): Promise<void> {\n const n = this.getNode(id);\n if (!n || this.isLeaf(n) || this.open.has(id) || this.loading.has(id)) return;\n if (!n.children && this.config.load) {\n this.loading.add(id);\n this.rendered && this.paint();\n try {\n n.children = await this.config.load(n);\n if (this.config.checkboxes && this.checkState(n) === true) n.children.forEach((c) => this.setBranch(c, true)); // a checked parent checks what it loads\n this.emit('load', n, n.children);\n } catch (err) {\n this.loading.delete(id);\n this.rendered && this.paint();\n this.emit('error', err, n);\n return;\n }\n this.loading.delete(id);\n }\n this.open.add(id);\n this.rendered && this.paint();\n this.emit('expand', n);\n }\n collapse(id: string) {\n const n = this.getNode(id);\n if (!n || !this.open.delete(id)) return;\n this.rendered && this.paint();\n this.emit('collapse', n);\n }\n toggle(id: string) {\n if (this.open.has(id)) this.collapse(id);\n else void this.expand(id);\n }\n /** Opens every node that already has its children (it does not load). */\n expandAll() {\n this.walk(this.items, (n) => n.children?.length && this.open.add(n.id));\n this.rendered && this.paint();\n }\n collapseAll() {\n this.open.clear();\n this.rendered && this.paint();\n }\n\n // ---- selection -------------------------------------------------------------------------------\n\n private pick(id: string, add: boolean) {\n const n = this.getNode(id);\n const mode = this.config.selection ?? 'single';\n if (!n || n.disabled || mode === 'none') return;\n if (mode === 'multi' && add) {\n if (!this.selected.delete(id)) this.selected.add(id);\n } else {\n this.selected.clear();\n this.selected.add(id);\n }\n this.rendered && this.paint();\n this.emit('select', this.getSelection());\n }\n /** Selects a node (opening its parents); `add` keeps the current selection in multi mode. */\n select(id: string, opts: { add?: boolean } = {}) {\n for (const p of this.getPath(id) ?? []) this.open.add(p.id);\n this.focusId = id;\n this.pick(id, !!opts.add);\n }\n getSelection(): TreeNode[] {\n return [...this.selected].map((id) => this.getNode(id)).filter((n): n is TreeNode => !!n);\n }\n deselectAll() {\n this.selected.clear();\n this.rendered && this.paint();\n this.emit('select', []);\n }\n\n // ---- checkboxes ------------------------------------------------------------------------------\n\n /** A node's state: its own `checked`, or for a parent with children, all / none / \"mixed\" of them. */\n checkState(n: TreeNode): CheckState {\n if (!n.children?.length) return !!n.checked;\n const states = n.children.map((c) => this.checkState(c));\n return states.every((s) => s === true) ? true : states.some((s) => s !== false) ? 'mixed' : false;\n }\n private setBranch(n: TreeNode, on: boolean) {\n n.checked = on;\n n.children?.forEach((c) => this.setBranch(c, on));\n }\n setChecked(id: string, on: boolean) {\n const n = this.getNode(id);\n if (!n || n.disabled) return;\n this.setBranch(n, on);\n this.rendered && this.paint();\n this.emit('check', this.getChecked(), n);\n }\n toggleChecked(id: string) {\n const n = this.getNode(id);\n if (n) this.setChecked(id, this.checkState(n) !== true);\n }\n /** Every checked node (a fully checked parent and its children all count). */\n getChecked(): TreeNode[] {\n const out: TreeNode[] = [];\n this.walk(this.items, (n) => this.checkState(n) === true && out.push(n));\n return out;\n }\n\n // ---- data ------------------------------------------------------------------------------------\n\n setItems(items: TreeNode[]) {\n this.items = items;\n this.config.items = items;\n this.selected.clear();\n this.rendered && this.paint();\n }\n /** Shows only what matches (and its ancestors, opened); empty text clears the filter. */\n filter(text: string) {\n this.query = text.trim().toLowerCase();\n this.rendered && this.paint();\n }\n\n // ---- keyboard (APG tree) ---------------------------------------------------------------------\n\n private rows(): HTMLElement[] {\n return Array.from(this.root.querySelectorAll<HTMLElement>('.op-tree__item'));\n }\n private focusRow(row?: HTMLElement) {\n if (!row) return;\n this.rows().forEach((r) => (r.tabIndex = r === row ? 0 : -1));\n this.focusId = row.dataset.id;\n row.focus();\n }\n\n private onKey(e: KeyboardEvent) {\n const row = (e.target as HTMLElement).closest<HTMLElement>('.op-tree__item');\n if (!row) return;\n const rows = this.rows();\n const i = rows.indexOf(row);\n const n = this.getNode(row.dataset.id!)!;\n const open = row.getAttribute('aria-expanded') === 'true';\n const closed = row.getAttribute('aria-expanded') === 'false';\n switch (e.key) {\n case 'ArrowDown': this.focusRow(rows[i + 1]); break;\n case 'ArrowUp': this.focusRow(rows[i - 1]); break;\n case 'Home': this.focusRow(rows[0]); break;\n case 'End': this.focusRow(rows[rows.length - 1]); break;\n case 'ArrowRight':\n if (closed) void this.expand(n.id);\n else if (open) this.focusRow(rows[i + 1]);\n break;\n case 'ArrowLeft':\n if (open) this.collapse(n.id);\n else {\n const parent = this.getPath(n.id)?.pop();\n if (parent) this.focusRow(rows.find((r) => r.dataset.id === parent.id));\n }\n break;\n case ' ':\n if (this.config.checkboxes) this.toggleChecked(n.id);\n else this.pick(n.id, this.config.selection === 'multi');\n break;\n case 'Enter':\n this.pick(n.id, false);\n if (!n.disabled) this.emit('activate', n);\n break;\n default: return;\n }\n e.preventDefault();\n // a repaint rebuilt the rows: put the focus back where the user is\n const again = this.root.querySelector<HTMLElement>(`[data-id=\"${CSS.escape(this.focusId ?? n.id)}\"]`);\n if (again && document.activeElement !== again) this.focusRow(again);\n }\n}\nregister('tree', Tree);\n"],
5
+ "mappings": "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",
6
+ "names": ["addMessages", "Tree", "Component", "c", "seed", "list", "n", "h", "e", "row", "id", "hit", "trail", "q", "fn", "shown", "t", "rows", "focus", "r", "level", "leaf", "open", "busy", "sel", "mode", "state", "li", "iconEl", "kids", "err", "add", "opts", "p", "states", "s", "on", "out", "items", "text", "i", "closed", "parent", "again", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ var w={top:"bottom",bottom:"top",left:"right",right:"left"};function y(e,i,s={}){let{offset:n=4,flip:b=!0,margin:r=8}=s,[x,c="center"]=(s.placement??"bottom-start").split("-"),t="getBoundingClientRect"in i?i.getBoundingClientRect():{left:i.x,right:i.x,top:i.y,bottom:i.y,width:0,height:0};s.matchWidth&&(e.style.minWidth=`${t.width}px`);let g=document.documentElement.clientWidth||window.innerWidth,f=document.documentElement.clientHeight||window.innerHeight,v=e.scrollTop;e.style.maxHeight=e.style.overflowY="";let m=e.offsetWidth,l=e.offsetHeight,h=d=>d==="bottom"?t.bottom+n+l<=f-r:d==="top"?t.top-n-l>=r:d==="right"?t.right+n+m<=g-r:t.left-n-m>=r,o=x;if(b&&!h(o)&&h(w[o])&&(o=w[o]),(o==="bottom"||o==="top")&&!h(o)){let d=f-r-t.bottom-n,u=t.top-n-r;b&&(o=d>=u?"bottom":"top"),l=Math.max(0,Math.floor(o==="bottom"?d:u)),e.style.maxHeight=`${l}px`,e.style.overflowY="auto",e.scrollTop=v}let a,p;o==="bottom"||o==="top"?(p=o==="bottom"?t.bottom+n:t.top-n-l,a=c==="start"?t.left:c==="end"?t.right-m:t.left+(t.width-m)/2):(a=o==="right"?t.right+n:t.left-n-m,p=c==="start"?t.top:c==="end"?t.bottom-l:t.top+(t.height-l)/2),a=Math.max(r,Math.min(a,g-m-r)),p=Math.max(r,Math.min(p,f-l-r)),e.style.left=`${a}px`,e.style.top=`${p}px`,e.dataset.side=o}function E(e){let i=!1,s=()=>{i||(i=!0,requestAnimationFrame(()=>{i=!1,e()}))};return window.addEventListener("scroll",s,!0),window.addEventListener("resize",s),()=>{window.removeEventListener("scroll",s,!0),window.removeEventListener("resize",s)}}export{y as a,E as b};
2
+ //# sourceMappingURL=chunk-E4VNLYO2.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/core/position.ts"],
4
+ "sourcesContent": ["export type Side = 'top' | 'bottom' | 'left' | 'right';\nexport type Placement = Side | `${Side}-start` | `${Side}-end`;\n\nexport interface PlaceOptions {\n placement?: Placement;\n offset?: number;\n flip?: boolean;\n matchWidth?: boolean;\n margin?: number;\n}\n\nconst opposite: Record<Side, Side> = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' };\n\n/**\n * Positions a floating element (`position: fixed`) next to an anchor element or a point, flipping and clamping to the viewport.\n * Taller than the room on either side (a long menu, a big theme): it goes where there is more room, capped to it, and scrolls.\n */\nexport function place(el: HTMLElement, anchor: Element | { x: number; y: number }, o: PlaceOptions = {}): void {\n const { offset = 4, flip = true, margin = 8 } = o;\n const [side0, align = 'center'] = (o.placement ?? 'bottom-start').split('-') as [Side, string?];\n const a = 'getBoundingClientRect' in anchor ? anchor.getBoundingClientRect() : { left: anchor.x, right: anchor.x, top: anchor.y, bottom: anchor.y, width: 0, height: 0 };\n if (o.matchWidth) el.style.minWidth = `${a.width}px`;\n const vw = document.documentElement.clientWidth || window.innerWidth;\n const vh = document.documentElement.clientHeight || window.innerHeight;\n const scrolled = el.scrollTop; // repositioning runs on every scroll, the element's own included: keep its place\n el.style.maxHeight = el.style.overflowY = ''; // measure the natural size again (the room may have grown)\n const w = el.offsetWidth;\n let hgt = el.offsetHeight;\n\n const fits = (s: Side) =>\n s === 'bottom' ? a.bottom + offset + hgt <= vh - margin : s === 'top' ? a.top - offset - hgt >= margin : s === 'right' ? a.right + offset + w <= vw - margin : a.left - offset - w >= margin;\n let side = side0;\n if (flip && !fits(side) && fits(opposite[side])) side = opposite[side];\n if ((side === 'bottom' || side === 'top') && !fits(side)) {\n const below = vh - margin - a.bottom - offset;\n const above = a.top - offset - margin;\n if (flip) side = below >= above ? 'bottom' : 'top';\n hgt = Math.max(0, Math.floor(side === 'bottom' ? below : above));\n el.style.maxHeight = `${hgt}px`;\n el.style.overflowY = 'auto';\n el.scrollTop = scrolled;\n }\n\n let left: number;\n let top: number;\n if (side === 'bottom' || side === 'top') {\n top = side === 'bottom' ? a.bottom + offset : a.top - offset - hgt;\n left = align === 'start' ? a.left : align === 'end' ? a.right - w : a.left + (a.width - w) / 2;\n } else {\n left = side === 'right' ? a.right + offset : a.left - offset - w;\n top = align === 'start' ? a.top : align === 'end' ? a.bottom - hgt : a.top + (a.height - hgt) / 2;\n }\n left = Math.max(margin, Math.min(left, vw - w - margin));\n top = Math.max(margin, Math.min(top, vh - hgt - margin));\n el.style.left = `${left}px`;\n el.style.top = `${top}px`;\n el.dataset.side = side;\n}\n\n/** Calls `fn` (throttled to a frame) on any scroll or resize. Returns the cleanup function. */\nexport function track(fn: () => void): () => void {\n let queued = false;\n const run = () => {\n if (queued) return;\n queued = true;\n requestAnimationFrame(() => {\n queued = false;\n fn();\n });\n };\n window.addEventListener('scroll', run, true);\n window.addEventListener('resize', run);\n return () => {\n window.removeEventListener('scroll', run, true);\n window.removeEventListener('resize', run);\n };\n}\n"],
5
+ "mappings": "AAWA,IAAMA,EAA+B,CAAE,IAAK,SAAU,OAAQ,MAAO,KAAM,QAAS,MAAO,MAAO,EAM3F,SAASC,EAAMC,EAAiBC,EAA4CC,EAAkB,CAAC,EAAS,CAC7G,GAAM,CAAE,OAAAC,EAAS,EAAG,KAAAC,EAAO,GAAM,OAAAC,EAAS,CAAE,EAAIH,EAC1C,CAACI,EAAOC,EAAQ,QAAQ,GAAKL,EAAE,WAAa,gBAAgB,MAAM,GAAG,EACrEM,EAAI,0BAA2BP,EAASA,EAAO,sBAAsB,EAAI,CAAE,KAAMA,EAAO,EAAG,MAAOA,EAAO,EAAG,IAAKA,EAAO,EAAG,OAAQA,EAAO,EAAG,MAAO,EAAG,OAAQ,CAAE,EACnKC,EAAE,aAAYF,EAAG,MAAM,SAAW,GAAGQ,EAAE,KAAK,MAChD,IAAMC,EAAK,SAAS,gBAAgB,aAAe,OAAO,WACpDC,EAAK,SAAS,gBAAgB,cAAgB,OAAO,YACrDC,EAAWX,EAAG,UACpBA,EAAG,MAAM,UAAYA,EAAG,MAAM,UAAY,GAC1C,IAAMY,EAAIZ,EAAG,YACTa,EAAMb,EAAG,aAEPc,EAAQC,GACZA,IAAM,SAAWP,EAAE,OAASL,EAASU,GAAOH,EAAKL,EAASU,IAAM,MAAQP,EAAE,IAAML,EAASU,GAAOR,EAASU,IAAM,QAAUP,EAAE,MAAQL,EAASS,GAAKH,EAAKJ,EAASG,EAAE,KAAOL,EAASS,GAAKP,EACpLW,EAAOV,EAEX,GADIF,GAAQ,CAACU,EAAKE,CAAI,GAAKF,EAAKhB,EAASkB,CAAI,CAAC,IAAGA,EAAOlB,EAASkB,CAAI,IAChEA,IAAS,UAAYA,IAAS,QAAU,CAACF,EAAKE,CAAI,EAAG,CACxD,IAAMC,EAAQP,EAAKL,EAASG,EAAE,OAASL,EACjCe,EAAQV,EAAE,IAAML,EAASE,EAC3BD,IAAMY,EAAOC,GAASC,EAAQ,SAAW,OAC7CL,EAAM,KAAK,IAAI,EAAG,KAAK,MAAMG,IAAS,SAAWC,EAAQC,CAAK,CAAC,EAC/DlB,EAAG,MAAM,UAAY,GAAGa,CAAG,KAC3Bb,EAAG,MAAM,UAAY,OACrBA,EAAG,UAAYW,CACjB,CAEA,IAAIQ,EACAC,EACAJ,IAAS,UAAYA,IAAS,OAChCI,EAAMJ,IAAS,SAAWR,EAAE,OAASL,EAASK,EAAE,IAAML,EAASU,EAC/DM,EAAOZ,IAAU,QAAUC,EAAE,KAAOD,IAAU,MAAQC,EAAE,MAAQI,EAAIJ,EAAE,MAAQA,EAAE,MAAQI,GAAK,IAE7FO,EAAOH,IAAS,QAAUR,EAAE,MAAQL,EAASK,EAAE,KAAOL,EAASS,EAC/DQ,EAAMb,IAAU,QAAUC,EAAE,IAAMD,IAAU,MAAQC,EAAE,OAASK,EAAML,EAAE,KAAOA,EAAE,OAASK,GAAO,GAElGM,EAAO,KAAK,IAAId,EAAQ,KAAK,IAAIc,EAAMV,EAAKG,EAAIP,CAAM,CAAC,EACvDe,EAAM,KAAK,IAAIf,EAAQ,KAAK,IAAIe,EAAKV,EAAKG,EAAMR,CAAM,CAAC,EACvDL,EAAG,MAAM,KAAO,GAAGmB,CAAI,KACvBnB,EAAG,MAAM,IAAM,GAAGoB,CAAG,KACrBpB,EAAG,QAAQ,KAAOgB,CACpB,CAGO,SAASK,EAAMC,EAA4B,CAChD,IAAIC,EAAS,GACPC,EAAM,IAAM,CACZD,IACJA,EAAS,GACT,sBAAsB,IAAM,CAC1BA,EAAS,GACTD,EAAG,CACL,CAAC,EACH,EACA,cAAO,iBAAiB,SAAUE,EAAK,EAAI,EAC3C,OAAO,iBAAiB,SAAUA,CAAG,EAC9B,IAAM,CACX,OAAO,oBAAoB,SAAUA,EAAK,EAAI,EAC9C,OAAO,oBAAoB,SAAUA,CAAG,CAC1C,CACF",
6
+ "names": ["opposite", "place", "el", "anchor", "o", "offset", "flip", "margin", "side0", "align", "a", "vw", "vh", "scrolled", "w", "hgt", "fits", "s", "side", "below", "above", "left", "top", "track", "fn", "queued", "run"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as f}from"./chunk-Z2JBUHKA.js";import{a as g}from"./chunk-W3H7GTJY.js";import{a as m}from"./chunk-G2DAD3MQ.js";import{f as a,g as o}from"./chunk-5JEXM5S7.js";import{c as h}from"./chunk-4EZJ5FKJ.js";import{b as c}from"./chunk-PZSHOSOS.js";import{a as u}from"./chunk-TIPK3SCJ.js";import{f as n}from"./chunk-MW3RWBZ7.js";var b=/\s*(?:–|—|\s-\s|\sto\s|\sa\s)\s*/,d=p=>a(p,{day:"2-digit",month:"2-digit",year:"numeric"}),l=class extends g{baseCls="op-field op-textfield op-picker op-datefield op-daterange";cal;dd;garbage=!1;emptyValue(){return null}isEmpty(e){return!e?.start}parse(e){if(this.garbage=!1,!e.trim())return null;let[r,s]=e.trim().split(b),t=o(r),i=s?o(s):null;return!t||s&&!i?(this.garbage=!0,null):i&&i<t?{start:i,end:t}:{start:t,end:i??t}}display(e){return e?.start?e.end&&e.end!==e.start?`${d(e.start)} \u2013 ${d(e.end)}`:d(e.start):""}createControl(){let e=super.createControl(),r=this.input;r.setAttribute("role","combobox"),r.setAttribute("aria-haspopup","dialog"),r.setAttribute("aria-expanded","false");let s=c("button","op-picker__trigger",{type:"button",tabindex:-1,"aria-label":n("calOpen")},h("calendar"));this.listen(s,"mousedown",i=>i.preventDefault()),this.listen(s,"click",()=>{!this.config.disabled&&!this.config.readonly&&this.toggle()}),e.append(s);let t=this.config;return this.cal=new m({range:!0,value:t.value,min:t.min,max:t.max,firstDay:t.firstDay}),this.dd=new f({anchor:e,content:this.cal,role:"presentation"}),this.cal.on("select",i=>{this.dd.close(),this.setValue(i),r.focus()}),this.dd.on("open",()=>{r.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",()=>{r.setAttribute("aria-expanded","false"),this.el.classList.remove("is-open"),this.emit("collapse")}),this.own(()=>this.dd.destroy()),this.on("blur",()=>this.later(()=>{let i=document.activeElement;!this.el.contains(i)&&!this.dd.el.contains(i)&&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(),r=this.value;if(e||!r)return e;let{min:s,max:t}=this.config;return s&&r.start<s?n("dateMin",{n:a(s)}):t&&(r.end??r.start)>t?n("dateMax",{n:a(t)}):""}open(){this.config.disabled||this.config.readonly||!this.rendered||this.dd.open()}close(){this.dd?.close()}toggle(){this.dd.isOpen()?this.close():this.open()}setMin(e){this.config.min=e,this.cal?.setMin(e)}setMax(e){this.config.max=e,this.cal?.setMax(e)}};u("daterangefield",l);export{l as a};
2
+ //# sourceMappingURL=chunk-EDUMAMK4.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/fields/daterangefield/daterangefield.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, type DateRange } from '../../dates/calendar/calendar';\n\nexport interface DateRangeFieldConfig extends TextFieldConfig<DateRange | null> {\n min?: string;\n max?: string;\n firstDay?: number;\n}\n\nconst SEP = /\\s*(?:\u2013|\u2014|\\s-\\s|\\sto\\s|\\sa\\s)\\s*/;\nconst short = (iso: string) => formatDate(iso, { day: '2-digit', month: '2-digit', year: 'numeric' });\n\n/**\n * Value is `{ start, end }` (ISO dates) or null. The text reads `01/03/2025 \u2013 15/03/2025` (typed or picked); the calendar\n * takes two clicks, and the popup closes on the second.\n */\nexport class DateRangeField extends TextField<DateRange | null, DateRangeFieldConfig> {\n protected override baseCls = 'op-field op-textfield op-picker op-datefield op-daterange';\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: DateRange | null) {\n return !v?.start;\n }\n\n protected override parse(text: string): DateRange | null {\n this.garbage = false;\n if (!text.trim()) return null;\n const [a, b] = text.trim().split(SEP);\n const start = parseDate(a);\n const end = b ? parseDate(b) : null;\n if (!start || (b && !end)) {\n this.garbage = true;\n return null;\n }\n return end && end < start ? { start: end, end: start } : { start, end: end ?? start };\n }\n protected override display(v: DateRange | null) {\n return v?.start ? (v.end && v.end !== v.start ? `${short(v.start)} \u2013 ${short(v.end)}` : short(v.start)) : '';\n }\n\n protected override createControl() {\n const wrap = super.createControl();\n const input = this.input;\n input.setAttribute('role', 'combobox'); // APG date picker combobox\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({ range: true, 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', (r: DateRange) => {\n this.dd.close();\n this.setValue(r);\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 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: DateRange | 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.start! < min) return t('dateMin', { n: formatDate(min) });\n if (max && (v.end ?? v.start!) > 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 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('daterangefield', DateRangeField);\n"],
5
+ "mappings": "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",
6
+ "names": ["SEP", "short", "iso", "formatDate", "DateRangeField", "TextField", "v", "text", "a", "b", "start", "parseDate", "end", "wrap", "input", "trigger", "h", "t", "iconEl", "e", "c", "Calendar", "Dropdown", "r", "disabled", "base", "min", "max", "register"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{c as r}from"./chunk-ZWNQREWS.js";import{a as o}from"./chunk-TIPK3SCJ.js";o("container",r);
2
+ //# sourceMappingURL=chunk-ELYARUCN.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/layout/container/container.ts"],
4
+ "sourcesContent": ["import { Container } from '../../../core/container';\nimport { register } from '../../../core/registry';\n\nexport { Container, type ContainerConfig } from '../../../core/container';\nregister('container', Container);\n"],
5
+ "mappings": "gFAIAA,EAAS,YAAaC,CAAS",
6
+ "names": ["register", "Container"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import{a as d}from"./chunk-5Q76ACVI.js";import{a as h}from"./chunk-Z2JBUHKA.js";import{a as l}from"./chunk-W3H7GTJY.js";import{c as r}from"./chunk-4EZJ5FKJ.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-EV73ADN2.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,3 @@
1
+ import{a as b}from"./chunk-2ZUZ5HDL.js";import{c as m}from"./chunk-4EZJ5FKJ.js";import{a as v}from"./chunk-A2NKDOYN.js";import{b as n}from"./chunk-PZSHOSOS.js";import{a as E}from"./chunk-TIPK3SCJ.js";import{d as y,e as p,f as a}from"./chunk-MW3RWBZ7.js";p("en",{chatPlaceholder:"Type a message",chatSend:"Send",chatTyping:"{n} is typing\u2026",chatToday:"Today",chatYesterday:"Yesterday",chatEmpty:"No messages yet",chatLog:"Conversation",chatSuggestions:"Suggestions",chatReply:"Reply"});p("pt-BR",{chatPlaceholder:"Digite uma mensagem",chatSend:"Enviar",chatTyping:"{n} est\xE1 digitando\u2026",chatToday:"Hoje",chatYesterday:"Ontem",chatEmpty:"Nenhuma mensagem ainda",chatLog:"Conversa",chatSuggestions:"Sugest\xF5es",chatReply:"Responder"});var _=/(\*\*[^*\n]+\*\*|\*[^*\n]+\*|`[^`\n]+`)/;function L(d){let t=[];return d.split(`
2
+ `).forEach((e,s)=>{s&&t.push(document.createElement("br"));for(let i of e.split(_))i&&(i.startsWith("**")&&i.endsWith("**")&&i.length>4?t.push(n("strong","",{},i.slice(2,-2))):i.startsWith("`")&&i.endsWith("`")&&i.length>2?t.push(n("code","op-chat__code",{},i.slice(1,-1))):i.startsWith("*")&&i.endsWith("*")&&i.length>2?t.push(n("em","",{},i.slice(1,-1))):t.push(document.createTextNode(i)))}),t}var l=d=>new Date(d).toDateString(),M=()=>y()._lang,u=class extends v{baseCls="op-chat";msgs=[];seq=0;logEl;emptyEl;typingEl;chipsEl;input;sendBtn;busy=!1;build(){let t=this.config;return this.logEl=n("div","op-chat__log",{role:"log","aria-live":"polite","aria-relevant":"additions","aria-label":a("chatLog"),tabindex:0}),this.emptyEl=n("div","op-chat__empty",{},a("chatEmpty")),this.typingEl=n("div","op-chat__typing",{"aria-hidden":"true"},n("span","op-chat__dots",{},n("i"),n("i"),n("i")),n("span","op-chat__typing-text")),this.typingEl.hidden=!0,this.chipsEl=n("div","op-chat__suggestions",{role:"group","aria-label":a("chatSuggestions")}),this.input=n("textarea","op-chat__input",{rows:1,placeholder:t.placeholder??a("chatPlaceholder"),"aria-label":t.placeholder??a("chatPlaceholder"),maxlength:t.maxLength??null}),this.sendBtn=new b({icon:"send",variant:"primary",ariaLabel:a("chatSend"),handler:()=>this.submit()}),this.own(()=>this.sendBtn.destroy()),n("div",this.baseCls,{},this.logEl,this.chipsEl,n("div","op-chat__composer",{},this.input,this.sendBtn.el))}onRender(){let t=this.config;this.listen(this.input,"input",()=>this.grow()),this.listen(this.input,"keydown",e=>{e.key!=="Enter"||e.shiftKey||e.isComposing||t.sendOnEnter===!1||(e.preventDefault(),this.submit())}),this.listen(this.chipsEl,"click",e=>{let s=e.target.closest("[data-s]");s&&(this.emit("suggestion",s.dataset.s),this.send(s.dataset.s))}),this.listen(this.logEl,"click",e=>{let s=e.target.closest(".op-chat__msg"),i=s&&this.msgs.find(o=>String(o.id)===s.dataset.id);i&&this.emit("message-click",i)}),this.setReadonly(!!t.readonly),this.msgs=(t.messages??[]).map(e=>this.norm(e)),this.setSuggestions(t.suggestions??[]),this.renderAll()}notifyMount(){super.notifyMount(),this.rendered&&(this.sendBtn.notifyMount(),this.scrollToBottom())}norm(t){let e=t.time==null?Date.now():new Date(t.time).getTime();return{...t,id:t.id??`m${++this.seq}`,at:e}}getMessages(){return this.msgs}addMessage(t){let e=this.norm(t);if(this.msgs.push(e),!this.rendered)return this.config.messages=this.msgs,e;let s=this.nearBottom()||e.from===this.config.me;return this.mountMsg(e,this.msgs.length-1),this.syncEmpty(),s&&this.scrollToBottom(),e}setMessages(t){this.msgs=t.map(e=>this.norm(e)),this.config.messages=this.msgs,this.rendered&&(this.renderAll(),this.scrollToBottom())}updateMessage(t,e){let s=this.msgs.findIndex(g=>g.id===t);if(s<0)return;let i=this.nearBottom();if(this.msgs[s]={...this.msgs[s],...e,at:e.time!=null?new Date(e.time).getTime():this.msgs[s].at},!this.rendered)return;let o=this.msgEl(t),r=this.buildMsg(this.msgs[s],s);o?o.replaceWith(r):this.logEl.insertBefore(r,this.typingEl),this.decorate(s),i&&this.scrollToBottom()}appendToMessage(t,e){let s=this.msgs.find(r=>r.id===t);if(!s)return;s.text+=e;let i=this.msgEl(t)?.querySelector(".op-chat__text");if(!i)return;let o=this.nearBottom();this.fill(i,s),o&&this.scrollToBottom()}removeMessage(t){this.msgs=this.msgs.filter(e=>e.id!==t),this.rendered&&this.renderAll()}msgEl(t){return this.logEl.querySelector(`[data-id="${CSS.escape(String(t))}"]`)}renderAll(){this.logEl.replaceChildren(this.emptyEl,...this.msgs.flatMap((t,e)=>this.nodesFor(t,e)),this.typingEl),this.syncEmpty()}nodesFor(t,e){let s=this.msgs[e-1],i=[];return(!s||l(s.at)!==l(t.at))&&i.push(n("div","op-chat__day",{role:"separator"},n("span","",{},this.dayLabel(t.at)))),i.push(this.buildMsg(t,e)),i}mountMsg(t,e){for(let s of this.nodesFor(t,e))this.logEl.insertBefore(s,this.typingEl);this.decorate(e-1),this.decorate(e)}dayLabel(t){let e=l(t),s=Date.now();return e===l(s)?a("chatToday"):e===l(s-864e5)?a("chatYesterday"):new Intl.DateTimeFormat(M(),{dateStyle:"medium"}).format(t)}fill(t,e){let s=this.config.renderer?this.config.renderer(e):L(e.text);t.replaceChildren(...Array.isArray(s)?s:[s])}buildMsg(t,e){let s=this.config,i=t.from===s.me,o=s.users?.[t.from],r=n("article",`op-chat__msg ${i?"is-me":"is-them"}`,{"data-id":String(t.id)}),g=n("div","op-chat__bubble");if(!i&&s.showAuthors!==!1&&o){let c=n("div","op-chat__author",{},o.name);o.color&&(c.style.color=o.color),g.append(c)}let h=t.replyTo!=null?this.msgs.find(c=>c.id===t.replyTo):void 0;h&&g.append(n("div","op-chat__reply",{"aria-label":a("chatReply")},n("strong","",{},h.from===s.me?"":s.users?.[h.from]?.name??h.from),h.text.length>80?`${h.text.slice(0,80)}\u2026`:h.text));let f=n("div","op-chat__text");this.fill(f,t);let T=new Intl.DateTimeFormat(M(),{hour:"2-digit",minute:"2-digit"}).format(t.at);return g.append(f,n("span","op-chat__meta",{},n("time","",{datetime:new Date(t.at).toISOString()},T),i&&t.status?this.statusEl(t.status):"")),r.append(g),this.group(r,e),r}statusEl(t){let e=n("span",`op-chat__status is-${t}`,{role:"img","aria-label":t});return t==="error"?e.append(m("alert")):t!=="sending"&&e.append(m("check"),...t==="sent"?[]:[m("check")]),e}group(t,e){let s=this.msgs[e],i=(o,r)=>!!o&&!!r&&o.from===r.from&&l(o.at)===l(r.at);t.classList.toggle("is-first",!i(this.msgs[e-1],s)),t.classList.toggle("is-last",!i(s,this.msgs[e+1])),t.querySelector(".op-chat__author")?.toggleAttribute("hidden",i(this.msgs[e-1],s))}decorate(t){let e=this.msgs[t],s=e&&this.msgEl(e.id);s&&this.group(s,t)}syncEmpty(){this.emptyEl.hidden=this.msgs.length>0,this.el.classList.toggle("is-empty",!this.msgs.length)}nearBottom(){let t=this.logEl;return t.scrollHeight-t.scrollTop-t.clientHeight<48}scrollToBottom(){this.render(),this.logEl.scrollTop=this.logEl.scrollHeight}setTyping(t){let e=this.nearBottom();this.typingEl.hidden=!t,this.typingEl.querySelector(".op-chat__typing-text").textContent=typeof t=="string"?a("chatTyping",{n:t}):"",t&&e&&this.scrollToBottom()}setSuggestions(t){this.config.suggestions=t,this.rendered&&(this.chipsEl.hidden=!t.length,this.chipsEl.replaceChildren(...t.map(e=>n("button","op-chat__chip",{type:"button","data-s":e},e))))}setBusy(t){this.busy=t,this.el.classList.toggle("is-busy",t),this.logEl.setAttribute("aria-busy",String(t)),this.sendBtn.setDisabled(t||!!this.config.readonly);for(let e of Array.from(this.chipsEl.children))e.disabled=t||!!this.config.readonly}setReadonly(t){this.config.readonly=t,this.rendered&&(this.input.readOnly=t,this.el.classList.toggle("is-readonly",t),this.setBusy(this.busy))}setPlaceholder(t){this.config.placeholder=t,this.rendered&&(this.input.placeholder=t)}focus(){this.render(),this.input.focus()}grow(){this.input.style.height="auto",this.input.style.height=`${this.input.scrollHeight}px`}submit(){let t=this.input.value;this.send(t)&&(this.input.value="",this.grow())}send(t){if(t=t.trim(),!t||this.busy||this.config.readonly||this.emit("before-send",t)===!1)return!1;let e=this.addMessage({from:this.config.me,text:t,time:Date.now(),status:"sending"});return this.emit("send",t,e),!0}};E("chat",u);export{u as a};
3
+ //# sourceMappingURL=chunk-FEHGU6EP.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/chat/chat/chat.ts"],
4
+ "sourcesContent": ["import { Component, type ComponentConfig } from '../../../core/component';\nimport { register } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { t, getLocale, addMessages } from '../../../core/i18n';\nimport { Button } from '../../base/button/button';\nimport { iconEl } from '../../base/icon/icon';\n\naddMessages('en', {\n chatPlaceholder: 'Type a message',\n chatSend: 'Send',\n chatTyping: '{n} is typing\u2026',\n chatToday: 'Today',\n chatYesterday: 'Yesterday',\n chatEmpty: 'No messages yet',\n chatLog: 'Conversation',\n chatSuggestions: 'Suggestions',\n chatReply: 'Reply',\n});\naddMessages('pt-BR', {\n chatPlaceholder: 'Digite uma mensagem',\n chatSend: 'Enviar',\n chatTyping: '{n} est\u00E1 digitando\u2026',\n chatToday: 'Hoje',\n chatYesterday: 'Ontem',\n chatEmpty: 'Nenhuma mensagem ainda',\n chatLog: 'Conversa',\n chatSuggestions: 'Sugest\u00F5es',\n chatReply: 'Responder',\n});\n\nexport interface ChatMessage {\n id?: string | number;\n /** The author's id (compare with the `me` of the config). */\n from: string;\n text: string;\n time?: number | Date | string;\n status?: 'sending' | 'sent' | 'delivered' | 'read' | 'error';\n /** The id of the message this one answers (shown as a quote). */\n replyTo?: string | number;\n /** Anything the app wants to keep with the message. */\n meta?: unknown;\n}\n\nexport interface ChatConfig extends ComponentConfig {\n messages?: ChatMessage[];\n /** The id of whoever is using the chat: their messages go on the right. */\n me: string;\n users?: Record<string, { name: string; color?: string }>;\n /** Show the author's name above the first bubble of a group of theirs. Default true. */\n showAuthors?: boolean;\n placeholder?: string;\n /** Prompt chips above the composer; clicking one sends it. */\n suggestions?: string[];\n readonly?: boolean;\n /** Enter sends and Shift+Enter breaks the line. Default true. */\n sendOnEnter?: boolean;\n maxLength?: number;\n /** Custom bubble content. The default is a minimal, safe formatting (`**bold**`, `*italic*`, `` `code` ``, line breaks). */\n renderer?: (msg: ChatMessage) => string | Node;\n}\n\ntype Msg = ChatMessage & { id: string | number; at: number };\n\nconst INLINE = /(\\*\\*[^*\\n]+\\*\\*|\\*[^*\\n]+\\*|`[^`\\n]+`)/;\n\n/** Text \u2192 nodes: bold, italic, code and line breaks only. Everything else stays text, so nothing can inject markup. */\nfunction format(text: string): Node[] {\n const out: Node[] = [];\n text.split('\\n').forEach((line, i) => {\n if (i) out.push(document.createElement('br'));\n for (const part of line.split(INLINE)) {\n if (!part) continue;\n if (part.startsWith('**') && part.endsWith('**') && part.length > 4) out.push(h('strong', '', {}, part.slice(2, -2)));\n else if (part.startsWith('`') && part.endsWith('`') && part.length > 2) out.push(h('code', 'op-chat__code', {}, part.slice(1, -1)));\n else if (part.startsWith('*') && part.endsWith('*') && part.length > 2) out.push(h('em', '', {}, part.slice(1, -1)));\n else out.push(document.createTextNode(part));\n }\n });\n return out;\n}\n\nconst dayKey = (at: number) => new Date(at).toDateString();\nconst lang = () => getLocale()._lang;\n\n/** Conversation view: bubbles grouped by author and day, delivery ticks, typing dots, streaming text, prompt chips and a composer. */\nexport class Chat extends Component<ChatConfig> {\n protected override baseCls = 'op-chat';\n private msgs: Msg[] = [];\n private seq = 0;\n private logEl!: HTMLElement;\n private emptyEl!: HTMLElement;\n private typingEl!: HTMLElement;\n private chipsEl!: HTMLElement;\n private input!: HTMLTextAreaElement;\n private sendBtn!: Button;\n private busy = false;\n\n protected override build() {\n const c = this.config;\n this.logEl = h('div', 'op-chat__log', { role: 'log', 'aria-live': 'polite', 'aria-relevant': 'additions', 'aria-label': t('chatLog'), tabindex: 0 });\n this.emptyEl = h('div', 'op-chat__empty', {}, t('chatEmpty'));\n this.typingEl = h('div', 'op-chat__typing', { 'aria-hidden': 'true' }, h('span', 'op-chat__dots', {}, h('i'), h('i'), h('i')), h('span', 'op-chat__typing-text'));\n this.typingEl.hidden = true;\n this.chipsEl = h('div', 'op-chat__suggestions', { role: 'group', 'aria-label': t('chatSuggestions') });\n this.input = h('textarea', 'op-chat__input', { rows: 1, placeholder: c.placeholder ?? t('chatPlaceholder'), 'aria-label': c.placeholder ?? t('chatPlaceholder'), maxlength: c.maxLength ?? null });\n this.sendBtn = new Button({ icon: 'send', variant: 'primary', ariaLabel: t('chatSend'), handler: () => this.submit() });\n this.own(() => this.sendBtn.destroy());\n return h('div', this.baseCls, {}, this.logEl, this.chipsEl, h('div', 'op-chat__composer', {}, this.input, this.sendBtn.el));\n }\n\n protected override onRender() {\n const c = this.config;\n this.listen(this.input, 'input', () => this.grow());\n this.listen(this.input, 'keydown', (e: KeyboardEvent) => {\n if (e.key !== 'Enter' || e.shiftKey || e.isComposing || c.sendOnEnter === false) return;\n e.preventDefault();\n this.submit();\n });\n this.listen(this.chipsEl, 'click', (e: Event) => {\n const b = (e.target as HTMLElement).closest<HTMLElement>('[data-s]');\n if (!b) return;\n this.emit('suggestion', b.dataset.s);\n this.send(b.dataset.s!);\n });\n this.listen(this.logEl, 'click', (e: Event) => {\n const el = (e.target as HTMLElement).closest<HTMLElement>('.op-chat__msg');\n const m = el && this.msgs.find((x) => String(x.id) === el.dataset.id);\n if (m) this.emit('message-click', m);\n });\n this.setReadonly(!!c.readonly);\n this.msgs = (c.messages ?? []).map((m) => this.norm(m));\n this.setSuggestions(c.suggestions ?? []);\n this.renderAll();\n }\n\n override notifyMount() {\n super.notifyMount();\n if (!this.rendered) return; // a Chat in a lazy tab is told it is mounted before it has a DOM\n this.sendBtn.notifyMount();\n this.scrollToBottom();\n }\n\n // ---- messages ------------------------------------------------------------------------------\n\n private norm(m: ChatMessage): Msg {\n const at = m.time == null ? Date.now() : new Date(m.time).getTime();\n return { ...m, id: m.id ?? `m${++this.seq}`, at };\n }\n\n getMessages(): ChatMessage[] {\n return this.msgs;\n }\n\n addMessage(msg: ChatMessage): ChatMessage {\n const m = this.norm(msg);\n this.msgs.push(m);\n if (!this.rendered) return (this.config.messages = this.msgs, m);\n const stick = this.nearBottom() || m.from === this.config.me;\n this.mountMsg(m, this.msgs.length - 1);\n this.syncEmpty();\n if (stick) this.scrollToBottom();\n return m;\n }\n\n setMessages(list: ChatMessage[]): void {\n this.msgs = list.map((m) => this.norm(m));\n this.config.messages = this.msgs; // so a chat that is not rendered yet (a lazy tab) starts with them\n if (this.rendered) {\n this.renderAll();\n this.scrollToBottom();\n }\n }\n\n updateMessage(id: string | number, patch: Partial<ChatMessage>): void {\n const i = this.msgs.findIndex((m) => m.id === id);\n if (i < 0) return;\n const stick = this.nearBottom();\n this.msgs[i] = { ...this.msgs[i], ...patch, at: patch.time != null ? new Date(patch.time).getTime() : this.msgs[i].at };\n if (!this.rendered) return;\n const old = this.msgEl(id);\n const fresh = this.buildMsg(this.msgs[i], i);\n old ? old.replaceWith(fresh) : this.logEl.insertBefore(fresh, this.typingEl);\n this.decorate(i);\n if (stick) this.scrollToBottom();\n }\n\n /** Adds text to a message: for answers that arrive in pieces (AI streaming). Only that bubble's text is redrawn. */\n appendToMessage(id: string | number, text: string): void {\n const m = this.msgs.find((x) => x.id === id);\n if (!m) return;\n m.text += text;\n const el = this.msgEl(id)?.querySelector('.op-chat__text');\n if (!el) return;\n const stick = this.nearBottom();\n this.fill(el as HTMLElement, m);\n if (stick) this.scrollToBottom();\n }\n\n removeMessage(id: string | number): void {\n this.msgs = this.msgs.filter((m) => m.id !== id);\n if (this.rendered) this.renderAll();\n }\n\n private msgEl(id: string | number): HTMLElement | null {\n return this.logEl.querySelector(`[data-id=\"${CSS.escape(String(id))}\"]`);\n }\n\n // ---- rendering -----------------------------------------------------------------------------\n\n private renderAll(): void {\n this.logEl.replaceChildren(this.emptyEl, ...this.msgs.flatMap((m, i) => this.nodesFor(m, i)), this.typingEl);\n this.syncEmpty();\n }\n\n /** The day separator (when the day changes) and the message itself. */\n private nodesFor(m: Msg, i: number): HTMLElement[] {\n const prev = this.msgs[i - 1];\n const nodes: HTMLElement[] = [];\n if (!prev || dayKey(prev.at) !== dayKey(m.at)) nodes.push(h('div', 'op-chat__day', { role: 'separator' }, h('span', '', {}, this.dayLabel(m.at))));\n nodes.push(this.buildMsg(m, i));\n return nodes;\n }\n\n private mountMsg(m: Msg, i: number): void {\n for (const n of this.nodesFor(m, i)) this.logEl.insertBefore(n, this.typingEl);\n this.decorate(i - 1);\n this.decorate(i);\n }\n\n private dayLabel(at: number): string {\n const d = dayKey(at);\n const now = Date.now();\n if (d === dayKey(now)) return t('chatToday');\n if (d === dayKey(now - 864e5)) return t('chatYesterday');\n return new Intl.DateTimeFormat(lang(), { dateStyle: 'medium' }).format(at);\n }\n\n private fill(el: HTMLElement, m: Msg): void {\n const out = this.config.renderer ? this.config.renderer(m) : format(m.text);\n el.replaceChildren(...(Array.isArray(out) ? out : [out]));\n }\n\n private buildMsg(m: Msg, i: number): HTMLElement {\n const c = this.config;\n const mine = m.from === c.me;\n const user = c.users?.[m.from];\n const el = h('article', `op-chat__msg ${mine ? 'is-me' : 'is-them'}`, { 'data-id': String(m.id) });\n const bubble = h('div', 'op-chat__bubble');\n if (!mine && c.showAuthors !== false && user) {\n const name = h('div', 'op-chat__author', {}, user.name);\n if (user.color) name.style.color = user.color;\n bubble.append(name);\n }\n const quoted = m.replyTo != null ? this.msgs.find((x) => x.id === m.replyTo) : undefined;\n if (quoted) bubble.append(h('div', 'op-chat__reply', { 'aria-label': t('chatReply') }, h('strong', '', {}, quoted.from === c.me ? '' : (c.users?.[quoted.from]?.name ?? quoted.from)), quoted.text.length > 80 ? `${quoted.text.slice(0, 80)}\u2026` : quoted.text));\n const text = h('div', 'op-chat__text');\n this.fill(text, m);\n const time = new Intl.DateTimeFormat(lang(), { hour: '2-digit', minute: '2-digit' }).format(m.at);\n bubble.append(text, h('span', 'op-chat__meta', {}, h('time', '', { datetime: new Date(m.at).toISOString() }, time), mine && m.status ? this.statusEl(m.status) : ''));\n el.append(bubble);\n this.group(el, i);\n return el;\n }\n\n private statusEl(s: NonNullable<ChatMessage['status']>): HTMLElement {\n const el = h('span', `op-chat__status is-${s}`, { role: 'img', 'aria-label': s });\n if (s === 'error') el.append(iconEl('alert'));\n else if (s !== 'sending') el.append(iconEl('check'), ...(s === 'sent' ? [] : [iconEl('check')]));\n return el;\n }\n\n /** Group classes: first/last bubble of a run by the same author on the same day. */\n private group(el: HTMLElement, i: number): void {\n const m = this.msgs[i];\n const same = (a?: Msg, b?: Msg) => !!a && !!b && a.from === b.from && dayKey(a.at) === dayKey(b.at);\n el.classList.toggle('is-first', !same(this.msgs[i - 1], m));\n el.classList.toggle('is-last', !same(m, this.msgs[i + 1]));\n el.querySelector('.op-chat__author')?.toggleAttribute('hidden', same(this.msgs[i - 1], m));\n }\n\n private decorate(i: number): void {\n const m = this.msgs[i];\n const el = m && this.msgEl(m.id);\n if (el) this.group(el, i);\n }\n\n private syncEmpty(): void {\n this.emptyEl.hidden = this.msgs.length > 0;\n this.el.classList.toggle('is-empty', !this.msgs.length);\n }\n\n private nearBottom(): boolean {\n const l = this.logEl;\n return l.scrollHeight - l.scrollTop - l.clientHeight < 48;\n }\n\n scrollToBottom(): void {\n this.render();\n this.logEl.scrollTop = this.logEl.scrollHeight;\n }\n\n // ---- typing, suggestions, state ------------------------------------------------------------\n\n /** `true` shows the dots, a name shows \"name is typing\u2026\", `false` hides them. */\n setTyping(who: boolean | string): void {\n const stick = this.nearBottom();\n this.typingEl.hidden = !who;\n this.typingEl.querySelector('.op-chat__typing-text')!.textContent = typeof who === 'string' ? t('chatTyping', { n: who }) : '';\n if (who && stick) this.scrollToBottom();\n }\n\n setSuggestions(list: string[]): void {\n this.config.suggestions = list;\n if (!this.rendered) return;\n this.chipsEl.hidden = !list.length;\n this.chipsEl.replaceChildren(...list.map((s) => h('button', 'op-chat__chip', { type: 'button', 'data-s': s }, s)));\n }\n\n /** While busy (an answer is on its way) sending is off and the log tells assistive tech to wait. */\n setBusy(busy: boolean): void {\n this.busy = busy;\n this.el.classList.toggle('is-busy', busy);\n this.logEl.setAttribute('aria-busy', String(busy));\n this.sendBtn.setDisabled(busy || !!this.config.readonly);\n for (const b of Array.from(this.chipsEl.children) as HTMLButtonElement[]) b.disabled = busy || !!this.config.readonly;\n }\n\n setReadonly(readonly: boolean): void {\n this.config.readonly = readonly;\n if (!this.rendered) return;\n this.input.readOnly = readonly;\n this.el.classList.toggle('is-readonly', readonly);\n this.setBusy(this.busy);\n }\n\n setPlaceholder(text: string): void {\n this.config.placeholder = text;\n if (this.rendered) this.input.placeholder = text;\n }\n\n override focus(): void {\n this.render();\n this.input.focus();\n }\n\n // ---- sending -------------------------------------------------------------------------------\n\n private grow(): void {\n this.input.style.height = 'auto';\n this.input.style.height = `${this.input.scrollHeight}px`;\n }\n\n private submit(): void {\n const text = this.input.value;\n if (this.send(text)) {\n this.input.value = '';\n this.grow();\n }\n }\n\n /** The same path as the send button. Returns false when nothing was sent (empty, busy, read-only or cancelled). */\n send(text: string): boolean {\n text = text.trim();\n if (!text || this.busy || this.config.readonly || this.emit('before-send', text) === false) return false;\n const msg = this.addMessage({ from: this.config.me, text, time: Date.now(), status: 'sending' });\n this.emit('send', text, msg);\n return true;\n }\n}\nregister('chat', Chat);\n"],
5
+ "mappings": "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",
6
+ "names": ["addMessages", "INLINE", "format", "text", "out", "line", "i", "part", "h", "dayKey", "at", "lang", "getLocale", "Chat", "Component", "c", "t", "Button", "b", "el", "m", "x", "msg", "stick", "list", "id", "patch", "old", "fresh", "prev", "nodes", "n", "d", "now", "mine", "user", "bubble", "name", "quoted", "time", "s", "iconEl", "same", "a", "l", "who", "busy", "readonly", "register"]
7
+ }
@@ -0,0 +1,3 @@
1
+ import{a as v}from"./chunk-Z2JBUHKA.js";import{c as f}from"./chunk-VV7CFMPZ.js";import{e as b}from"./chunk-4AA4FQEM.js";import{c as h}from"./chunk-4EZJ5FKJ.js";import{a as d}from"./chunk-A2NKDOYN.js";import{b as s}from"./chunk-PZSHOSOS.js";import{a as m}from"./chunk-TIPK3SCJ.js";import{f as a}from"./chunk-MW3RWBZ7.js";var n=".op-menu__item",p=class E extends d{baseCls="op-menu";parentMenu;dd;sub;subOwner;opener=null;hoverCancel;list;searchEl;emptyEl;build(){return s("div","op-menu")}shell(){let t=!!this.config.search;t&&!this.searchEl&&(this.searchEl=s("input","op-menu__search",{type:"search",placeholder:`${a("search")}\u2026`,"aria-label":a("search"),autocomplete:"off"}),this.emptyEl=s("div","op-menu__empty",{},a("noResults")),this.listen(this.searchEl,"input",()=>this.filter()),this.listen(this.searchEl,"keydown",e=>{let i=this.first();i&&(e.key==="ArrowDown"||e.key==="Enter")&&(e.preventDefault(),e.key==="Enter"?this.activate(i):i.focus())})),this.list=t?this.list!==this.el&&this.list||s("div","op-menu__list",{role:"menu"}):this.el,this.el.setAttribute("role",t?"none":"menu"),t&&this.el.replaceChildren(this.searchEl,this.list,this.emptyEl)}first(){return this.list.querySelector(`${n}:not([hidden]):not([aria-disabled=true])`)}filter(){let t=(this.searchEl?.value??"").trim().toLowerCase();this.el.classList.toggle("is-searching",!!t);for(let e of Array.from(this.list.querySelectorAll(n))){let i=e.parentElement.getAttribute("aria-label")??"";e.hidden=!!t&&!`${i}
2
+ ${e.textContent}`.toLowerCase().includes(t)}this.emptyEl&&(this.emptyEl.hidden=!!this.first()||!this.list.querySelector(n))}onRender(){this.shell(),this.renderItems();let t=f(this.el,{selector:n,orientation:"vertical"});this.own(()=>t.destroy()),this.listen(this.el,"click",e=>{let i=e.target.closest(n);i&&this.activate(i)}),this.listen(this.el,"keydown",e=>{let i=e.target.closest(n);if(e.target!==this.searchEl){if(e.key==="Tab")return this.closeAll();if(this.searchEl&&e.key.length===1&&e.key!==" "&&!e.ctrlKey&&!e.metaKey&&!e.altKey)return e.preventDefault(),this.searchEl.focus(),this.searchEl.value+=e.key,this.filter();i&&(e.key==="Enter"||e.key===" "?(e.preventDefault(),this.activate(i)):e.key==="ArrowRight"&&i.getAttribute("aria-haspopup")?(e.preventDefault(),this.openSub(i,!0)):e.key==="ArrowLeft"&&this.parentMenu&&(e.preventDefault(),this.hide()))}}),this.listen(this.el,"pointerover",e=>{let i=e.target.closest(n);!i||i.getAttribute("aria-disabled")==="true"||(this.hoverCancel?.(),i.focus(),i.getAttribute("aria-haspopup")?this.hoverCancel=this.later(()=>this.openSub(i,!1),150):this.sub?.hide())})}entries(){return this.config.items??[]}renderItems(){let t=this.entries(),e=t.map((r,o)=>{if(r==="-")return s("div","op-menu__sep",{role:"separator"});let l=r.checked!==void 0,u=s("div","op-menu__item",{role:l?"menuitemcheckbox":"menuitem",tabindex:-1,"data-i":o,"aria-disabled":r.disabled?"true":null,"aria-checked":l?String(!!r.checked):null,"aria-haspopup":r.items?"menu":null,"aria-expanded":r.items?"false":null});return u.append(s("span","op-menu__icon",{},r.icon?h(r.icon):l&&r.checked?h("check"):null),s("span","op-menu__text",{},r.text??"")),r.items&&u.append(s("span","op-menu__arrow",{},h("chevron-right"))),u}),i=r=>t[r]==="-"?"":t[r].group??"",c=[...new Set(t.map((r,o)=>i(o)).filter(Boolean))];if(!c.length)return this.list.replaceChildren(...e),this.filter();this.list.replaceChildren(...e.filter((r,o)=>!i(o)),...c.map(r=>s("div","op-menu__group",{role:"group","aria-label":r},s("div","op-menu__group-label",{"aria-hidden":"true"},r),...e.filter((o,l)=>i(l)===r)))),this.filter()}setItems(t){this.config.items=t,this.rendered&&this.renderItems()}setSearch(t){this.config.search=t,this.rendered&&(this.shell(),this.renderItems())}activate(t){let e=this.entries()[Number(t.dataset.i)];if(!(!e||e.disabled)){if(e.items)return this.openSub(t,!0);e.checked!==void 0&&(e.checked=!e.checked),e.handler?.(e),this.root().emit("click",e),this.root().hide()}}root(){return this.parentMenu?this.parentMenu.root():this}openSub(t,e){let i=this.entries()[Number(t.dataset.i)];if(this.sub&&this.subOwner===t&&this.sub.isOpen())return e?this.sub.focusFirst():void 0;this.sub?.destroy(),this.sub=new E({items:i.items}),this.sub.parentMenu=this,this.subOwner=t,this.sub.on("hide",()=>t.setAttribute("aria-expanded","false")),t.setAttribute("aria-expanded","true"),this.sub.showBy(t,"right-start",e)}isOpen(){return!!this.dd?.isOpen()}focusFirst(){this.first()?.focus()}showBy(t,e="bottom-start",i=!0){this.open({anchor:t,placement:e},i)}showAt(t,e){this.open({anchor:{x:t,y:e},placement:"bottom-start"},!0)}open(t,e){this.opener=document.activeElement,this.dd?(this.dd.setAnchor(t.anchor),this.dd.setPlacement(t.placement)):(this.dd=new v({...t,content:this.el,role:"presentation",flip:!0}),this.dd.on("close",()=>{this.sub?.hide(),this.emit("hide")})),this.searchEl&&this.config.search&&(this.searchEl.value="",this.filter()),this.dd.open(),b(Array.from(this.el.querySelectorAll(n)),{dy:4}),e&&this.focusFirst(),this.emit("show")}hide(){if(!this.dd?.isOpen())return;this.dd.close();let t=this.parentMenu?this.parentMenu.subOwner:this.opener;t instanceof HTMLElement&&t.isConnected&&t.focus()}closeAll(){this.root().hide()}onDestroy(){this.sub?.destroy(),this.dd?.destroy()}};m("menu",p);export{p as a};
3
+ //# sourceMappingURL=chunk-FHM5NUS4.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/components/overlays/menu/menu.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 { roving } from '../../../core/focus';\nimport type { Placement } from '../../../core/position';\nimport { iconEl } from '../../base/icon/icon';\nimport { Dropdown } from '../dropdown/dropdown';\nimport { stagger } from '../../../motion/core';\n\nexport interface MenuItem {\n text?: string;\n icon?: string;\n handler?: (item: MenuItem) => void;\n disabled?: boolean;\n /** Present (true/false) makes it a checkable item. */\n checked?: boolean;\n items?: MenuEntry[];\n /** Items with the same group sit together under its name (ungrouped items come first). */\n group?: string;\n}\nexport type MenuEntry = MenuItem | '-';\n\nexport interface MenuConfig extends ComponentConfig {\n items?: MenuEntry[];\n /** A search field over the items: filters as you type; a search that names a group shows the whole group. */\n search?: boolean;\n}\n\nconst ITEM = '.op-menu__item';\n\n/** Floating menu with submenus. Use `showBy(button)` for button menus and `showAt(x, y)` for context menus. */\nexport class Menu extends Component<MenuConfig> {\n protected override baseCls = 'op-menu';\n parentMenu?: Menu;\n private dd?: Dropdown;\n private sub?: Menu;\n private subOwner?: HTMLElement;\n private opener: Element | null = null;\n private hoverCancel?: () => void;\n /** The `role=menu` element: the root itself, or a list under the search field. */\n private list!: HTMLElement;\n private searchEl?: HTMLInputElement;\n private emptyEl?: HTMLElement;\n\n protected override build() {\n return h('div', 'op-menu');\n }\n\n /** Without search the root is the menu; with it, the root holds the field, the menu and the \"no results\" line. */\n private shell() {\n const on = !!this.config.search;\n if (on && !this.searchEl) {\n this.searchEl = h('input', 'op-menu__search', { type: 'search', placeholder: `${t('search')}\u2026`, 'aria-label': t('search'), autocomplete: 'off' });\n this.emptyEl = h('div', 'op-menu__empty', {}, t('noResults'));\n this.listen(this.searchEl, 'input', () => this.filter());\n this.listen(this.searchEl, 'keydown', (e: KeyboardEvent) => {\n const first = this.first();\n if (first && (e.key === 'ArrowDown' || e.key === 'Enter')) (e.preventDefault(), e.key === 'Enter' ? this.activate(first) : first.focus());\n });\n }\n this.list = on ? (this.list !== this.el && this.list) || h('div', 'op-menu__list', { role: 'menu' }) : this.el;\n this.el.setAttribute('role', on ? 'none' : 'menu');\n if (on) this.el.replaceChildren(this.searchEl!, this.list, this.emptyEl!);\n }\n\n private first(): HTMLElement | null {\n return this.list.querySelector<HTMLElement>(`${ITEM}:not([hidden]):not([aria-disabled=true])`);\n }\n\n /** Hides the items that do not match the search (a group whose name matches keeps all of them); empty groups hide in CSS. */\n private filter() {\n const q = (this.searchEl?.value ?? '').trim().toLowerCase();\n this.el.classList.toggle('is-searching', !!q);\n for (const row of Array.from(this.list.querySelectorAll<HTMLElement>(ITEM))) {\n const group = row.parentElement!.getAttribute('aria-label') ?? '';\n row.hidden = !!q && !`${group}\\n${row.textContent}`.toLowerCase().includes(q);\n }\n if (this.emptyEl) this.emptyEl.hidden = !!this.first() || !this.list.querySelector(ITEM);\n }\n\n protected override onRender() {\n this.shell();\n this.renderItems();\n const rover = roving(this.el, { selector: ITEM, orientation: 'vertical' });\n this.own(() => rover.destroy());\n this.listen(this.el, 'click', (e: Event) => {\n const row = (e.target as HTMLElement).closest<HTMLElement>(ITEM);\n if (row) this.activate(row);\n });\n this.listen(this.el, 'keydown', (e: KeyboardEvent) => {\n const row = (e.target as HTMLElement).closest<HTMLElement>(ITEM);\n if (e.target === this.searchEl) return;\n if (e.key === 'Tab') return this.closeAll();\n // type to search: a printable key on an item goes to the search field\n if (this.searchEl && e.key.length === 1 && e.key !== ' ' && !e.ctrlKey && !e.metaKey && !e.altKey) {\n e.preventDefault();\n this.searchEl.focus();\n this.searchEl.value += e.key;\n return this.filter();\n }\n if (!row) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.activate(row);\n } else if (e.key === 'ArrowRight' && row.getAttribute('aria-haspopup')) {\n e.preventDefault();\n this.openSub(row, true);\n } else if (e.key === 'ArrowLeft' && this.parentMenu) {\n e.preventDefault();\n this.hide();\n }\n });\n this.listen(this.el, 'pointerover', (e: Event) => {\n const row = (e.target as HTMLElement).closest<HTMLElement>(ITEM);\n if (!row || row.getAttribute('aria-disabled') === 'true') return;\n this.hoverCancel?.();\n row.focus();\n if (row.getAttribute('aria-haspopup')) this.hoverCancel = this.later(() => this.openSub(row, false), 150);\n else this.sub?.hide();\n });\n }\n\n private entries(): MenuEntry[] {\n return this.config.items ?? [];\n }\n\n private renderItems() {\n const entries = this.entries();\n const rows = entries.map((it, i) => {\n if (it === '-') return h('div', 'op-menu__sep', { role: 'separator' });\n const checkable = it.checked !== undefined;\n const row = h('div', 'op-menu__item', {\n role: checkable ? 'menuitemcheckbox' : 'menuitem',\n tabindex: -1,\n 'data-i': i,\n 'aria-disabled': it.disabled ? 'true' : null,\n 'aria-checked': checkable ? String(!!it.checked) : null,\n 'aria-haspopup': it.items ? 'menu' : null,\n 'aria-expanded': it.items ? 'false' : null,\n });\n row.append(h('span', 'op-menu__icon', {}, it.icon ? iconEl(it.icon) : checkable && it.checked ? iconEl('check') : null), h('span', 'op-menu__text', {}, it.text ?? ''));\n if (it.items) row.append(h('span', 'op-menu__arrow', {}, iconEl('chevron-right')));\n return row;\n });\n const groupOf = (i: number) => (entries[i] === '-' ? '' : ((entries[i] as MenuItem).group ?? ''));\n const groups = [...new Set(entries.map((_, i) => groupOf(i)).filter(Boolean))];\n if (!groups.length) return (this.list.replaceChildren(...rows), this.filter());\n // ungrouped entries first, then one role=group per name (its header is only visual: the group carries the name)\n this.list.replaceChildren(\n ...rows.filter((_, i) => !groupOf(i)),\n ...groups.map((g) => h('div', 'op-menu__group', { role: 'group', 'aria-label': g }, h('div', 'op-menu__group-label', { 'aria-hidden': 'true' }, g), ...rows.filter((_, i) => groupOf(i) === g))),\n );\n this.filter();\n }\n\n setItems(items: MenuEntry[]) {\n this.config.items = items;\n if (this.rendered) this.renderItems();\n }\n\n /** Turns the search field on or off. */\n setSearch(search: boolean) {\n this.config.search = search;\n if (!this.rendered) return;\n this.shell();\n this.renderItems();\n }\n\n private activate(row: HTMLElement) {\n const item = this.entries()[Number(row.dataset.i)] as MenuItem;\n if (!item || item.disabled) return;\n if (item.items) return this.openSub(row, true);\n if (item.checked !== undefined) item.checked = !item.checked;\n item.handler?.(item);\n this.root().emit('click', item);\n this.root().hide();\n }\n\n private root(): Menu {\n return this.parentMenu ? this.parentMenu.root() : this;\n }\n\n private openSub(row: HTMLElement, focus: boolean) {\n const item = this.entries()[Number(row.dataset.i)] as MenuItem;\n if (this.sub && this.subOwner === row && this.sub.isOpen()) return focus ? this.sub.focusFirst() : undefined;\n this.sub?.destroy();\n this.sub = new Menu({ items: item.items });\n this.sub.parentMenu = this;\n this.subOwner = row;\n this.sub.on('hide', () => row.setAttribute('aria-expanded', 'false'));\n row.setAttribute('aria-expanded', 'true');\n this.sub.showBy(row, 'right-start', focus);\n }\n\n isOpen(): boolean {\n return !!this.dd?.isOpen();\n }\n\n private focusFirst() {\n this.first()?.focus(); // never the search field on open: a phone keyboard would cover the menu\n }\n\n showBy(anchor: HTMLElement | Component, placement: Placement = 'bottom-start', focus = true) {\n this.open({ anchor, placement }, focus);\n }\n\n showAt(x: number, y: number) {\n this.open({ anchor: { x, y }, placement: 'bottom-start' }, true);\n }\n\n private open(cfg: { anchor: HTMLElement | Component | { x: number; y: number }; placement: Placement }, focus: boolean) {\n this.opener = document.activeElement;\n if (!this.dd) {\n this.dd = new Dropdown({ ...cfg, content: this.el, role: 'presentation', flip: true });\n this.dd.on('close', () => {\n this.sub?.hide();\n this.emit('hide');\n });\n } else {\n this.dd.setAnchor(cfg.anchor);\n this.dd.setPlacement(cfg.placement);\n }\n if (this.searchEl && this.config.search) {\n this.searchEl.value = '';\n this.filter();\n }\n this.dd.open();\n void stagger(Array.from(this.el.querySelectorAll(ITEM)), { dy: 4 }); // the rows settle one after the other\n if (focus) this.focusFirst();\n this.emit('show');\n }\n\n override hide() {\n if (!this.dd?.isOpen()) return;\n this.dd.close();\n // Closing a submenu returns to its parent item; closing the root returns to whatever opened it.\n const back = this.parentMenu ? this.parentMenu.subOwner : this.opener;\n if (back instanceof HTMLElement && back.isConnected) back.focus();\n }\n\n closeAll() {\n this.root().hide();\n }\n\n protected override onDestroy() {\n this.sub?.destroy();\n this.dd?.destroy();\n }\n}\nregister('menu', Menu);\n"],
5
+ "mappings": "gUA6BA,IAAMA,EAAO,iBAGAC,EAAN,MAAMC,UAAaC,CAAsB,CAC3B,QAAU,UAC7B,WACQ,GACA,IACA,SACA,OAAyB,KACzB,YAEA,KACA,SACA,QAEW,OAAQ,CACzB,OAAOC,EAAE,MAAO,SAAS,CAC3B,CAGQ,OAAQ,CACd,IAAMC,EAAK,CAAC,CAAC,KAAK,OAAO,OACrBA,GAAM,CAAC,KAAK,WACd,KAAK,SAAWD,EAAE,QAAS,kBAAmB,CAAE,KAAM,SAAU,YAAa,GAAGE,EAAE,QAAQ,CAAC,SAAK,aAAcA,EAAE,QAAQ,EAAG,aAAc,KAAM,CAAC,EAChJ,KAAK,QAAUF,EAAE,MAAO,iBAAkB,CAAC,EAAGE,EAAE,WAAW,CAAC,EAC5D,KAAK,OAAO,KAAK,SAAU,QAAS,IAAM,KAAK,OAAO,CAAC,EACvD,KAAK,OAAO,KAAK,SAAU,UAAY,GAAqB,CAC1D,IAAMC,EAAQ,KAAK,MAAM,EACrBA,IAAU,EAAE,MAAQ,aAAe,EAAE,MAAQ,WAAW,EAAE,eAAe,EAAG,EAAE,MAAQ,QAAU,KAAK,SAASA,CAAK,EAAIA,EAAM,MAAM,EACzI,CAAC,GAEH,KAAK,KAAOF,EAAM,KAAK,OAAS,KAAK,IAAM,KAAK,MAASD,EAAE,MAAO,gBAAiB,CAAE,KAAM,MAAO,CAAC,EAAI,KAAK,GAC5G,KAAK,GAAG,aAAa,OAAQC,EAAK,OAAS,MAAM,EAC7CA,GAAI,KAAK,GAAG,gBAAgB,KAAK,SAAW,KAAK,KAAM,KAAK,OAAQ,CAC1E,CAEQ,OAA4B,CAClC,OAAO,KAAK,KAAK,cAA2B,GAAGL,CAAI,0CAA0C,CAC/F,CAGQ,QAAS,CACf,IAAMQ,GAAK,KAAK,UAAU,OAAS,IAAI,KAAK,EAAE,YAAY,EAC1D,KAAK,GAAG,UAAU,OAAO,eAAgB,CAAC,CAACA,CAAC,EAC5C,QAAWC,KAAO,MAAM,KAAK,KAAK,KAAK,iBAA8BT,CAAI,CAAC,EAAG,CAC3E,IAAMU,EAAQD,EAAI,cAAe,aAAa,YAAY,GAAK,GAC/DA,EAAI,OAAS,CAAC,CAACD,GAAK,CAAC,GAAGE,CAAK;AAAA,EAAKD,EAAI,WAAW,GAAG,YAAY,EAAE,SAASD,CAAC,CAC9E,CACI,KAAK,UAAS,KAAK,QAAQ,OAAS,CAAC,CAAC,KAAK,MAAM,GAAK,CAAC,KAAK,KAAK,cAAcR,CAAI,EACzF,CAEmB,UAAW,CAC5B,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,IAAMW,EAAQC,EAAO,KAAK,GAAI,CAAE,SAAUZ,EAAM,YAAa,UAAW,CAAC,EACzE,KAAK,IAAI,IAAMW,EAAM,QAAQ,CAAC,EAC9B,KAAK,OAAO,KAAK,GAAI,QAAU,GAAa,CAC1C,IAAMF,EAAO,EAAE,OAAuB,QAAqBT,CAAI,EAC3DS,GAAK,KAAK,SAASA,CAAG,CAC5B,CAAC,EACD,KAAK,OAAO,KAAK,GAAI,UAAY,GAAqB,CACpD,IAAMA,EAAO,EAAE,OAAuB,QAAqBT,CAAI,EAC/D,GAAI,EAAE,SAAW,KAAK,SACtB,IAAI,EAAE,MAAQ,MAAO,OAAO,KAAK,SAAS,EAE1C,GAAI,KAAK,UAAY,EAAE,IAAI,SAAW,GAAK,EAAE,MAAQ,KAAO,CAAC,EAAE,SAAW,CAAC,EAAE,SAAW,CAAC,EAAE,OACzF,SAAE,eAAe,EACjB,KAAK,SAAS,MAAM,EACpB,KAAK,SAAS,OAAS,EAAE,IAClB,KAAK,OAAO,EAEhBS,IACD,EAAE,MAAQ,SAAW,EAAE,MAAQ,KACjC,EAAE,eAAe,EACjB,KAAK,SAASA,CAAG,GACR,EAAE,MAAQ,cAAgBA,EAAI,aAAa,eAAe,GACnE,EAAE,eAAe,EACjB,KAAK,QAAQA,EAAK,EAAI,GACb,EAAE,MAAQ,aAAe,KAAK,aACvC,EAAE,eAAe,EACjB,KAAK,KAAK,IAEd,CAAC,EACD,KAAK,OAAO,KAAK,GAAI,cAAgB,GAAa,CAChD,IAAMA,EAAO,EAAE,OAAuB,QAAqBT,CAAI,EAC3D,CAACS,GAAOA,EAAI,aAAa,eAAe,IAAM,SAClD,KAAK,cAAc,EACnBA,EAAI,MAAM,EACNA,EAAI,aAAa,eAAe,EAAG,KAAK,YAAc,KAAK,MAAM,IAAM,KAAK,QAAQA,EAAK,EAAK,EAAG,GAAG,EACnG,KAAK,KAAK,KAAK,EACtB,CAAC,CACH,CAEQ,SAAuB,CAC7B,OAAO,KAAK,OAAO,OAAS,CAAC,CAC/B,CAEQ,aAAc,CACpB,IAAMI,EAAU,KAAK,QAAQ,EACvBC,EAAOD,EAAQ,IAAI,CAACE,EAAIC,IAAM,CAChC,GAAID,IAAO,IAAK,OAAOX,EAAE,MAAO,eAAgB,CAAE,KAAM,WAAY,CAAC,EACrE,IAAMa,EAAYF,EAAG,UAAY,OAC3BN,EAAML,EAAE,MAAO,gBAAiB,CACpC,KAAMa,EAAY,mBAAqB,WACvC,SAAU,GACV,SAAUD,EACV,gBAAiBD,EAAG,SAAW,OAAS,KACxC,eAAgBE,EAAY,OAAO,CAAC,CAACF,EAAG,OAAO,EAAI,KACnD,gBAAiBA,EAAG,MAAQ,OAAS,KACrC,gBAAiBA,EAAG,MAAQ,QAAU,IACxC,CAAC,EACD,OAAAN,EAAI,OAAOL,EAAE,OAAQ,gBAAiB,CAAC,EAAGW,EAAG,KAAOG,EAAOH,EAAG,IAAI,EAAIE,GAAaF,EAAG,QAAUG,EAAO,OAAO,EAAI,IAAI,EAAGd,EAAE,OAAQ,gBAAiB,CAAC,EAAGW,EAAG,MAAQ,EAAE,CAAC,EAClKA,EAAG,OAAON,EAAI,OAAOL,EAAE,OAAQ,iBAAkB,CAAC,EAAGc,EAAO,eAAe,CAAC,CAAC,EAC1ET,CACT,CAAC,EACGU,EAAWH,GAAeH,EAAQG,CAAC,IAAM,IAAM,GAAOH,EAAQG,CAAC,EAAe,OAAS,GACvFI,EAAS,CAAC,GAAG,IAAI,IAAIP,EAAQ,IAAI,CAACQ,EAAGL,IAAMG,EAAQH,CAAC,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC,EAC7E,GAAI,CAACI,EAAO,OAAQ,OAAQ,KAAK,KAAK,gBAAgB,GAAGN,CAAI,EAAG,KAAK,OAAO,EAE5E,KAAK,KAAK,gBACR,GAAGA,EAAK,OAAO,CAACO,EAAGL,IAAM,CAACG,EAAQH,CAAC,CAAC,EACpC,GAAGI,EAAO,IAAKE,GAAMlB,EAAE,MAAO,iBAAkB,CAAE,KAAM,QAAS,aAAckB,CAAE,EAAGlB,EAAE,MAAO,uBAAwB,CAAE,cAAe,MAAO,EAAGkB,CAAC,EAAG,GAAGR,EAAK,OAAO,CAACO,EAAGL,IAAMG,EAAQH,CAAC,IAAMM,CAAC,CAAC,CAAC,CACjM,EACA,KAAK,OAAO,CACd,CAEA,SAASC,EAAoB,CAC3B,KAAK,OAAO,MAAQA,EAChB,KAAK,UAAU,KAAK,YAAY,CACtC,CAGA,UAAUC,EAAiB,CACzB,KAAK,OAAO,OAASA,EAChB,KAAK,WACV,KAAK,MAAM,EACX,KAAK,YAAY,EACnB,CAEQ,SAASf,EAAkB,CACjC,IAAMgB,EAAO,KAAK,QAAQ,EAAE,OAAOhB,EAAI,QAAQ,CAAC,CAAC,EACjD,GAAI,GAACgB,GAAQA,EAAK,UAClB,IAAIA,EAAK,MAAO,OAAO,KAAK,QAAQhB,EAAK,EAAI,EACzCgB,EAAK,UAAY,SAAWA,EAAK,QAAU,CAACA,EAAK,SACrDA,EAAK,UAAUA,CAAI,EACnB,KAAK,KAAK,EAAE,KAAK,QAASA,CAAI,EAC9B,KAAK,KAAK,EAAE,KAAK,EACnB,CAEQ,MAAa,CACnB,OAAO,KAAK,WAAa,KAAK,WAAW,KAAK,EAAI,IACpD,CAEQ,QAAQhB,EAAkBiB,EAAgB,CAChD,IAAMD,EAAO,KAAK,QAAQ,EAAE,OAAOhB,EAAI,QAAQ,CAAC,CAAC,EACjD,GAAI,KAAK,KAAO,KAAK,WAAaA,GAAO,KAAK,IAAI,OAAO,EAAG,OAAOiB,EAAQ,KAAK,IAAI,WAAW,EAAI,OACnG,KAAK,KAAK,QAAQ,EAClB,KAAK,IAAM,IAAIxB,EAAK,CAAE,MAAOuB,EAAK,KAAM,CAAC,EACzC,KAAK,IAAI,WAAa,KACtB,KAAK,SAAWhB,EAChB,KAAK,IAAI,GAAG,OAAQ,IAAMA,EAAI,aAAa,gBAAiB,OAAO,CAAC,EACpEA,EAAI,aAAa,gBAAiB,MAAM,EACxC,KAAK,IAAI,OAAOA,EAAK,cAAeiB,CAAK,CAC3C,CAEA,QAAkB,CAChB,MAAO,CAAC,CAAC,KAAK,IAAI,OAAO,CAC3B,CAEQ,YAAa,CACnB,KAAK,MAAM,GAAG,MAAM,CACtB,CAEA,OAAOC,EAAiCC,EAAuB,eAAgBF,EAAQ,GAAM,CAC3F,KAAK,KAAK,CAAE,OAAAC,EAAQ,UAAAC,CAAU,EAAGF,CAAK,CACxC,CAEA,OAAOG,EAAWC,EAAW,CAC3B,KAAK,KAAK,CAAE,OAAQ,CAAE,EAAAD,EAAG,EAAAC,CAAE,EAAG,UAAW,cAAe,EAAG,EAAI,CACjE,CAEQ,KAAKC,EAA2FL,EAAgB,CACtH,KAAK,OAAS,SAAS,cAClB,KAAK,IAOR,KAAK,GAAG,UAAUK,EAAI,MAAM,EAC5B,KAAK,GAAG,aAAaA,EAAI,SAAS,IAPlC,KAAK,GAAK,IAAIC,EAAS,CAAE,GAAGD,EAAK,QAAS,KAAK,GAAI,KAAM,eAAgB,KAAM,EAAK,CAAC,EACrF,KAAK,GAAG,GAAG,QAAS,IAAM,CACxB,KAAK,KAAK,KAAK,EACf,KAAK,KAAK,MAAM,CAClB,CAAC,GAKC,KAAK,UAAY,KAAK,OAAO,SAC/B,KAAK,SAAS,MAAQ,GACtB,KAAK,OAAO,GAEd,KAAK,GAAG,KAAK,EACRE,EAAQ,MAAM,KAAK,KAAK,GAAG,iBAAiBjC,CAAI,CAAC,EAAG,CAAE,GAAI,CAAE,CAAC,EAC9D0B,GAAO,KAAK,WAAW,EAC3B,KAAK,KAAK,MAAM,CAClB,CAES,MAAO,CACd,GAAI,CAAC,KAAK,IAAI,OAAO,EAAG,OACxB,KAAK,GAAG,MAAM,EAEd,IAAMQ,EAAO,KAAK,WAAa,KAAK,WAAW,SAAW,KAAK,OAC3DA,aAAgB,aAAeA,EAAK,aAAaA,EAAK,MAAM,CAClE,CAEA,UAAW,CACT,KAAK,KAAK,EAAE,KAAK,CACnB,CAEmB,WAAY,CAC7B,KAAK,KAAK,QAAQ,EAClB,KAAK,IAAI,QAAQ,CACnB,CACF,EACAC,EAAS,OAAQlC,CAAI",
6
+ "names": ["ITEM", "Menu", "_Menu", "Component", "h", "on", "t", "first", "q", "row", "group", "rover", "roving", "entries", "rows", "it", "i", "checkable", "iconEl", "groupOf", "groups", "_", "g", "items", "search", "item", "focus", "anchor", "placement", "x", "y", "cfg", "Dropdown", "stagger", "back", "register"]
7
+ }