optikos 0.1.0 → 0.3.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.
- package/CHANGELOG.md +135 -0
- package/README.md +13 -11
- package/dist/chunk-23XLG2EM.js +2 -0
- package/dist/{chunk-666O2GKD.js.map → chunk-23XLG2EM.js.map} +1 -1
- package/dist/chunk-2YZB6XQR.js +2 -0
- package/dist/chunk-2YZB6XQR.js.map +7 -0
- package/dist/chunk-2ZRNGG2N.js +2 -0
- package/dist/chunk-2ZRNGG2N.js.map +7 -0
- package/dist/chunk-2ZUZ5HDL.js +2 -0
- package/dist/chunk-2ZUZ5HDL.js.map +7 -0
- package/dist/chunk-3S24ZRPK.js +2 -0
- package/dist/chunk-3S24ZRPK.js.map +7 -0
- package/dist/chunk-3TAW4AKH.js +2 -0
- package/dist/chunk-3TAW4AKH.js.map +7 -0
- package/dist/chunk-4EQEHJB3.js +2 -0
- package/dist/chunk-4EQEHJB3.js.map +7 -0
- package/dist/chunk-4EZJ5FKJ.js +2 -0
- package/dist/{chunk-IHAYOSBR.js.map → chunk-4EZJ5FKJ.js.map} +1 -1
- package/dist/chunk-4LZZ244E.js +2 -0
- package/dist/chunk-4LZZ244E.js.map +7 -0
- package/dist/chunk-4SYIIX5A.js +2 -0
- package/dist/chunk-4SYIIX5A.js.map +7 -0
- package/dist/chunk-5BC72727.js +2 -0
- package/dist/chunk-5BC72727.js.map +7 -0
- package/dist/chunk-5DJTP53N.js +2 -0
- package/dist/{chunk-ODWPBBVL.js.map → chunk-5DJTP53N.js.map} +1 -1
- package/dist/{chunk-NWTTHDIM.js → chunk-5JEXM5S7.js} +2 -2
- package/dist/chunk-5Q76ACVI.js +2 -0
- package/dist/{chunk-O4DCHALR.js.map → chunk-5Q76ACVI.js.map} +1 -1
- package/dist/chunk-5QUY72FX.js +2 -0
- package/dist/chunk-5QUY72FX.js.map +7 -0
- package/dist/{chunk-NV5AIBQP.js → chunk-6VBK2I5B.js} +2 -2
- package/dist/{chunk-ZYUXCZX7.js → chunk-7KMIFXHZ.js} +2 -2
- package/dist/{chunk-IYPKPLCU.js → chunk-A2NKDOYN.js} +2 -2
- package/dist/chunk-A2NKDOYN.js.map +7 -0
- package/dist/chunk-CKXS375P.js +2 -0
- package/dist/chunk-CKXS375P.js.map +7 -0
- package/dist/chunk-DBMWS3O5.js +2 -0
- package/dist/chunk-DBMWS3O5.js.map +7 -0
- package/dist/chunk-E4VNLYO2.js +2 -0
- package/dist/chunk-E4VNLYO2.js.map +7 -0
- package/dist/chunk-EDUMAMK4.js +2 -0
- package/dist/chunk-EDUMAMK4.js.map +7 -0
- package/dist/chunk-EJGWCKE4.js +2 -0
- package/dist/{chunk-4DHQKECB.js.map → chunk-EJGWCKE4.js.map} +1 -1
- package/dist/chunk-ELYARUCN.js +2 -0
- package/dist/{chunk-Z25NC4CS.js → chunk-EV73ADN2.js} +2 -2
- package/dist/{chunk-LV6HXFHU.js → chunk-FEHGU6EP.js} +3 -3
- package/dist/chunk-FEHGU6EP.js.map +7 -0
- package/dist/chunk-G2DAD3MQ.js +2 -0
- package/dist/chunk-G2DAD3MQ.js.map +7 -0
- package/dist/chunk-G2KUK6AT.js +2 -0
- package/dist/chunk-GD5JGKM7.js +2 -0
- package/dist/chunk-GD5JGKM7.js.map +7 -0
- package/dist/{chunk-LBCWEWPN.js → chunk-GNU4VOOE.js} +2 -2
- package/dist/{chunk-IW7PK4VS.js → chunk-GZ7X34QP.js} +2 -2
- package/dist/chunk-HOF4JGMQ.js +2 -0
- package/dist/chunk-HOF4JGMQ.js.map +7 -0
- package/dist/chunk-HXDTGP2K.js +2 -0
- package/dist/chunk-HXDTGP2K.js.map +7 -0
- package/dist/{chunk-QEQIJAAB.js → chunk-I4SP6JTU.js} +2 -2
- package/dist/chunk-IHE2MQ3W.js +2 -0
- package/dist/{chunk-OW2ZSMGS.js.map → chunk-IHE2MQ3W.js.map} +1 -1
- package/dist/chunk-JBLRAM7Z.js +2 -0
- package/dist/{chunk-JZNEB7A7.js.map → chunk-JBLRAM7Z.js.map} +1 -1
- package/dist/{chunk-4SUKNSCY.js → chunk-JI265XFO.js} +2 -2
- package/dist/chunk-JK74QK3M.js +2 -0
- package/dist/chunk-JK74QK3M.js.map +7 -0
- package/dist/chunk-JOFQJGZK.js +2 -0
- package/dist/chunk-JOFQJGZK.js.map +7 -0
- package/dist/chunk-KCEUD232.js +2 -0
- package/dist/chunk-KCEUD232.js.map +7 -0
- package/dist/chunk-KLLAY2IM.js +2 -0
- package/dist/chunk-KLLAY2IM.js.map +7 -0
- package/dist/chunk-LBJSMXLV.js +2 -0
- package/dist/chunk-LBJSMXLV.js.map +7 -0
- package/dist/chunk-LQRFNQ2N.js +2 -0
- package/dist/chunk-LQRFNQ2N.js.map +7 -0
- package/dist/{chunk-NDBFYIL6.js → chunk-LW2WRUVL.js} +2 -2
- package/dist/{chunk-NDBFYIL6.js.map → chunk-LW2WRUVL.js.map} +2 -2
- package/dist/chunk-M242VYZA.js +2 -0
- package/dist/{chunk-XVIC24AW.js.map → chunk-M242VYZA.js.map} +1 -1
- package/dist/chunk-MB3MU6HR.js +2 -0
- package/dist/chunk-MB3MU6HR.js.map +7 -0
- package/dist/chunk-MW3RWBZ7.js +2 -0
- package/dist/chunk-MW3RWBZ7.js.map +7 -0
- package/dist/chunk-NXSTUFS7.js +2 -0
- package/dist/chunk-NXSTUFS7.js.map +7 -0
- package/dist/chunk-OEAXCCVM.js +2 -0
- package/dist/chunk-OEAXCCVM.js.map +7 -0
- package/dist/chunk-OGRFQTXA.js +2 -0
- package/dist/chunk-OGRFQTXA.js.map +7 -0
- package/dist/chunk-Q26YZYTD.js +2 -0
- package/dist/chunk-Q26YZYTD.js.map +7 -0
- package/dist/chunk-REW4LR46.js +2 -0
- package/dist/chunk-REW4LR46.js.map +7 -0
- package/dist/chunk-RNN55473.js +2 -0
- package/dist/chunk-RNN55473.js.map +7 -0
- package/dist/{chunk-6NJW7QFD.js → chunk-SA53QUBF.js} +2 -2
- package/dist/chunk-TIPK3SCJ.js +2 -0
- package/dist/chunk-TIPK3SCJ.js.map +7 -0
- package/dist/{chunk-TBLICXWW.js → chunk-TOLTUOZS.js} +2 -2
- package/dist/{chunk-DXO3UJKL.js → chunk-TZOQWCVH.js} +2 -2
- package/dist/chunk-UB5RYS7T.js +2 -0
- package/dist/chunk-UB5RYS7T.js.map +7 -0
- package/dist/chunk-UXXJOU5J.js +2 -0
- package/dist/chunk-UXXJOU5J.js.map +7 -0
- package/dist/chunk-VU3GIDZ3.js +2 -0
- package/dist/chunk-VU3GIDZ3.js.map +7 -0
- package/dist/chunk-W2BAFOCN.js +3 -0
- package/dist/chunk-W2BAFOCN.js.map +7 -0
- package/dist/{chunk-SNTHW4K2.js → chunk-W3H7GTJY.js} +2 -2
- package/dist/chunk-WFGTQZIQ.js +2 -0
- package/dist/chunk-WFGTQZIQ.js.map +7 -0
- package/dist/{chunk-ZHVSHDLH.js → chunk-XHOBNSBO.js} +2 -2
- package/dist/chunk-XX2MVWFS.js +4 -0
- package/dist/chunk-XX2MVWFS.js.map +7 -0
- package/dist/chunk-XYZ6VZ5T.js +2 -0
- package/dist/chunk-XYZ6VZ5T.js.map +7 -0
- package/dist/chunk-YBAYEU25.js +2 -0
- package/dist/chunk-YBAYEU25.js.map +7 -0
- package/dist/chunk-YF75HKL6.js +2 -0
- package/dist/chunk-YF75HKL6.js.map +7 -0
- package/dist/chunk-YHEMA56R.js +2 -0
- package/dist/{chunk-5GNEFX6F.js.map → chunk-YHEMA56R.js.map} +1 -1
- package/dist/chunk-Z2JBUHKA.js +2 -0
- package/dist/chunk-Z2JBUHKA.js.map +7 -0
- package/dist/{chunk-6O2BXCRN.js → chunk-Z2Z52GFT.js} +2 -2
- package/dist/chunk-ZPPELYNJ.js +2 -0
- package/dist/chunk-ZPPELYNJ.js.map +7 -0
- package/dist/chunk-ZVK4L5GK.js +2 -0
- package/dist/chunk-ZVK4L5GK.js.map +7 -0
- package/dist/chunk-ZWNQREWS.js +2 -0
- package/dist/chunk-ZWNQREWS.js.map +7 -0
- package/dist/components/badge.js +2 -0
- package/dist/components/badge.js.map +7 -0
- package/dist/components/breadcrumb.js +1 -1
- package/dist/components/button.js +1 -1
- package/dist/components/calendar.js +1 -1
- package/dist/components/cellediting.js +2 -0
- package/dist/components/cellediting.js.map +7 -0
- package/dist/components/chat.js +1 -1
- package/dist/components/checkbox.js +1 -1
- package/dist/components/checkboxgroup.js +2 -0
- package/dist/components/checkboxgroup.js.map +7 -0
- package/dist/components/chip.js +2 -0
- package/dist/components/chip.js.map +7 -0
- package/dist/components/codeviewer.js +2 -0
- package/dist/components/codeviewer.js.map +7 -0
- package/dist/components/combobox.js +1 -1
- package/dist/components/commandpalette.js +1 -1
- package/dist/components/container.js +1 -1
- package/dist/components/dataview.js +1 -1
- package/dist/components/datefield.js +1 -1
- package/dist/components/daterangefield.js +1 -1
- package/dist/components/dial.js +2 -0
- package/dist/components/dial.js.map +7 -0
- package/dist/components/dropdown.js +1 -1
- package/dist/components/fieldgroup.js +2 -0
- package/dist/components/fieldgroup.js.map +7 -0
- package/dist/components/fieldlist.js +2 -0
- package/dist/components/fieldlist.js.map +7 -0
- package/dist/components/fieldset.js +1 -1
- package/dist/components/filterbuilder.js +1 -1
- package/dist/components/form.js +1 -1
- package/dist/components/formactions.js +2 -0
- package/dist/components/formactions.js.map +7 -0
- package/dist/components/formerrors.js +2 -0
- package/dist/components/formerrors.js.map +7 -0
- package/dist/components/formsection.js +2 -0
- package/dist/components/formsection.js.map +7 -0
- package/dist/components/grid.js +1 -1
- package/dist/components/icon.js +1 -1
- package/dist/components/inputgroup.js +2 -0
- package/dist/components/inputgroup.js.map +7 -0
- package/dist/components/label.js +1 -1
- package/dist/components/listbox.js +1 -1
- package/dist/components/lookupfield.js +1 -1
- package/dist/components/menu.js +1 -1
- package/dist/components/messagebox.js +1 -1
- package/dist/components/navmenu.js +1 -1
- package/dist/components/numberfield.js +1 -1
- package/dist/components/pagination.js +1 -1
- package/dist/components/panel.js +1 -1
- package/dist/components/pickerfield.js +1 -1
- package/dist/components/radiogroup.js +1 -1
- package/dist/components/searchgrid.js +1 -1
- package/dist/components/secretfield.js +1 -1
- package/dist/components/select.js +1 -1
- package/dist/components/slider.js +1 -1
- package/dist/components/spacer.js +1 -1
- package/dist/components/spinner.js +1 -1
- package/dist/components/stepform.js +1 -1
- package/dist/components/stepper.js +1 -1
- package/dist/components/suggestfield.js +1 -1
- package/dist/components/table.js +1 -1
- package/dist/components/tabs.js +1 -1
- package/dist/components/textarea.js +1 -1
- package/dist/components/textfield.js +1 -1
- package/dist/components/toast.js +1 -1
- package/dist/components/toggle.js +2 -0
- package/dist/components/toggle.js.map +7 -0
- package/dist/components/toolbar.js +1 -1
- package/dist/components/tooltip.js +1 -1
- package/dist/components/tree.js +2 -0
- package/dist/components/tree.js.map +7 -0
- package/dist/components/viewmanager.js +1 -1
- package/dist/components/viewport.js +1 -1
- package/dist/components/widget.js +1 -1
- package/dist/components/window.js +1 -1
- package/dist/core.js +1 -1
- package/dist/css/badge.css +39 -0
- package/dist/css/base.css +71 -51
- package/dist/css/button.css +2 -0
- package/dist/css/cellediting.css +33 -0
- package/dist/css/chat.css +0 -1
- package/dist/css/checkboxgroup.css +12 -0
- package/dist/css/chip.css +64 -0
- package/dist/css/codeviewer.css +109 -0
- package/dist/css/dial.css +203 -0
- package/dist/css/fieldgroup.css +26 -0
- package/dist/css/fieldlist.css +84 -0
- package/dist/css/fieldset.css +36 -0
- package/dist/css/formactions.css +40 -0
- package/dist/css/formerrors.css +39 -0
- package/dist/css/formsection.css +45 -0
- package/dist/css/grid.css +14 -3
- package/dist/css/inputgroup.css +58 -0
- package/dist/css/menu.css +54 -0
- package/dist/css/navmenu.css +9 -7
- package/dist/css/panel.css +8 -1
- package/dist/css/stepform.css +9 -0
- package/dist/css/stepper.css +7 -2
- package/dist/css/tabs.css +12 -3
- package/dist/css/toggle.css +39 -0
- package/dist/css/tree.css +94 -0
- package/dist/css/widget.css +58 -0
- package/dist/css/window.css +4 -0
- package/dist/data.js +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +3 -3
- package/dist/optikos.css +1221 -106
- package/dist/themes/dark.css +47 -32
- package/dist/types/components/badge.d.ts +1 -0
- package/dist/types/components/base/badge/badge.d.ts +18 -0
- package/dist/types/components/base/chip/chip.d.ts +27 -0
- package/dist/types/components/base/codeviewer/codeviewer.d.ts +48 -0
- package/dist/types/components/cellediting.d.ts +1 -0
- package/dist/types/components/checkboxgroup.d.ts +1 -0
- package/dist/types/components/chip.d.ts +1 -0
- package/dist/types/components/codeviewer.d.ts +1 -0
- package/dist/types/components/data/cellediting/cellediting.d.ts +10 -0
- package/dist/types/components/data/filterbuilder/filterbuilder.d.ts +3 -1
- package/dist/types/components/data/grid/grid.d.ts +42 -16
- package/dist/types/components/data/tree/tree.d.ts +71 -0
- package/dist/types/components/dial.d.ts +1 -0
- package/dist/types/components/fieldgroup.d.ts +1 -0
- package/dist/types/components/fieldlist.d.ts +1 -0
- package/dist/types/components/fields/checkboxgroup/checkboxgroup.d.ts +27 -0
- package/dist/types/components/fields/dial/dial.d.ts +84 -0
- package/dist/types/components/fields/toggle/toggle.d.ts +9 -0
- package/dist/types/components/form/fieldgroup/fieldgroup.d.ts +33 -0
- package/dist/types/components/form/fieldlist/fieldlist.d.ts +58 -0
- package/dist/types/components/form/form/form.d.ts +19 -2
- package/dist/types/components/form/formactions/formactions.d.ts +34 -0
- package/dist/types/components/form/formerrors/formerrors.d.ts +23 -0
- package/dist/types/components/form/formsection/formsection.d.ts +26 -0
- package/dist/types/components/form/inputgroup/inputgroup.d.ts +28 -0
- package/dist/types/components/form/stepform/stepform.d.ts +30 -4
- package/dist/types/components/formactions.d.ts +1 -0
- package/dist/types/components/formerrors.d.ts +1 -0
- package/dist/types/components/formsection.d.ts +1 -0
- package/dist/types/components/inputgroup.d.ts +1 -0
- package/dist/types/components/layout/fieldset/fieldset.d.ts +9 -0
- package/dist/types/components/layout/panel/panel.d.ts +6 -0
- package/dist/types/components/layout/panel/reload.d.ts +1 -0
- package/dist/types/components/navigation/navmenu/navmenu.d.ts +6 -0
- package/dist/types/components/navigation/tabs/tabs.d.ts +8 -0
- package/dist/types/components/overlays/menu/menu.d.ts +17 -0
- package/dist/types/components/overlays/messagebox/messagebox.d.ts +8 -0
- package/dist/types/components/overlays/widget/widget.d.ts +13 -0
- package/dist/types/components/overlays/window/window.d.ts +8 -1
- package/dist/types/components/toggle.d.ts +1 -0
- package/dist/types/components/tree.d.ts +1 -0
- package/dist/types/core/component.d.ts +6 -2
- package/dist/types/core/i18n.d.ts +5 -0
- package/dist/types/core/index.d.ts +1 -1
- package/dist/types/core/position.d.ts +4 -1
- package/dist/types/data/column.d.ts +9 -4
- package/dist/types/index.d.ts +14 -0
- package/dist/types/themes/define.d.ts +4 -3
- package/dist/types/ui/enums.d.ts +0 -6
- package/dist/types/ui/ui.d.ts +12 -3
- package/dist/ui.js +1 -1
- package/package.json +6 -1
- package/dist/chunk-4COBH4QJ.js +0 -2
- package/dist/chunk-4COBH4QJ.js.map +0 -7
- package/dist/chunk-4DHQKECB.js +0 -2
- package/dist/chunk-4Q67QI7J.js +0 -2
- package/dist/chunk-4Q67QI7J.js.map +0 -7
- package/dist/chunk-5AXLYDKU.js +0 -2
- package/dist/chunk-5AXLYDKU.js.map +0 -7
- package/dist/chunk-5GNEFX6F.js +0 -2
- package/dist/chunk-5Q6Y6CM4.js +0 -2
- package/dist/chunk-5Q6Y6CM4.js.map +0 -7
- package/dist/chunk-666O2GKD.js +0 -2
- package/dist/chunk-A66MDXHL.js +0 -2
- package/dist/chunk-A66MDXHL.js.map +0 -7
- package/dist/chunk-ARCW54L2.js +0 -2
- package/dist/chunk-ARCW54L2.js.map +0 -7
- package/dist/chunk-BIYNHKSA.js +0 -2
- package/dist/chunk-BIYNHKSA.js.map +0 -7
- package/dist/chunk-BNPVRIFT.js +0 -2
- package/dist/chunk-BNPVRIFT.js.map +0 -7
- package/dist/chunk-C3N7QTQB.js +0 -2
- package/dist/chunk-C3N7QTQB.js.map +0 -7
- package/dist/chunk-CEXY5A4T.js +0 -2
- package/dist/chunk-CN7USUJR.js +0 -2
- package/dist/chunk-CN7USUJR.js.map +0 -7
- package/dist/chunk-CQRHNTEX.js +0 -2
- package/dist/chunk-CUPAPOKC.js +0 -2
- package/dist/chunk-CUPAPOKC.js.map +0 -7
- package/dist/chunk-GZNQPENR.js +0 -2
- package/dist/chunk-GZNQPENR.js.map +0 -7
- package/dist/chunk-HFFK6K4K.js +0 -2
- package/dist/chunk-HFFK6K4K.js.map +0 -7
- package/dist/chunk-IHAYOSBR.js +0 -2
- package/dist/chunk-IO66A6G5.js +0 -2
- package/dist/chunk-IO66A6G5.js.map +0 -7
- package/dist/chunk-IYPKPLCU.js.map +0 -7
- package/dist/chunk-JTYWZMSZ.js +0 -2
- package/dist/chunk-JTYWZMSZ.js.map +0 -7
- package/dist/chunk-JVEPKW5X.js +0 -2
- package/dist/chunk-JVEPKW5X.js.map +0 -7
- package/dist/chunk-JZNEB7A7.js +0 -2
- package/dist/chunk-K2DGY6MP.js +0 -2
- package/dist/chunk-K2DGY6MP.js.map +0 -7
- package/dist/chunk-LEE2FEEL.js +0 -2
- package/dist/chunk-LEE2FEEL.js.map +0 -7
- package/dist/chunk-LMGCV35W.js +0 -2
- package/dist/chunk-LMGCV35W.js.map +0 -7
- package/dist/chunk-LV6HXFHU.js.map +0 -7
- package/dist/chunk-MA5BJL3S.js +0 -2
- package/dist/chunk-MA5BJL3S.js.map +0 -7
- package/dist/chunk-NHVEP72K.js +0 -2
- package/dist/chunk-NHVEP72K.js.map +0 -7
- package/dist/chunk-O4DCHALR.js +0 -2
- package/dist/chunk-ODWPBBVL.js +0 -2
- package/dist/chunk-OW2ZSMGS.js +0 -2
- package/dist/chunk-PSPQH35P.js +0 -2
- package/dist/chunk-PSPQH35P.js.map +0 -7
- package/dist/chunk-T4OYVG2X.js +0 -2
- package/dist/chunk-T4OYVG2X.js.map +0 -7
- package/dist/chunk-TK2RC3T5.js +0 -2
- package/dist/chunk-TK2RC3T5.js.map +0 -7
- package/dist/chunk-U3X2FW6U.js +0 -2
- package/dist/chunk-U3X2FW6U.js.map +0 -7
- package/dist/chunk-UPOBGNJ5.js +0 -2
- package/dist/chunk-UPOBGNJ5.js.map +0 -7
- package/dist/chunk-XVIC24AW.js +0 -2
- package/dist/chunk-XZ5CUZZP.js +0 -2
- package/dist/chunk-XZ5CUZZP.js.map +0 -7
- package/dist/chunk-XZEOSW3Q.js +0 -2
- package/dist/chunk-XZEOSW3Q.js.map +0 -7
- package/dist/chunk-YET5PM6F.js +0 -2
- package/dist/chunk-YET5PM6F.js.map +0 -7
- package/dist/chunk-ZCAAM4NH.js +0 -2
- package/dist/chunk-ZCAAM4NH.js.map +0 -7
- package/dist/themes/brand.css +0 -240
- package/dist/themes/brutal.css +0 -100
- package/dist/themes/corporate.css +0 -112
- package/dist/themes/editorial.css +0 -110
- package/dist/themes/soft.css +0 -101
- package/dist/themes/terminal.css +0 -91
- /package/dist/{chunk-NWTTHDIM.js.map → chunk-5JEXM5S7.js.map} +0 -0
- /package/dist/{chunk-NV5AIBQP.js.map → chunk-6VBK2I5B.js.map} +0 -0
- /package/dist/{chunk-ZYUXCZX7.js.map → chunk-7KMIFXHZ.js.map} +0 -0
- /package/dist/{chunk-CEXY5A4T.js.map → chunk-ELYARUCN.js.map} +0 -0
- /package/dist/{chunk-Z25NC4CS.js.map → chunk-EV73ADN2.js.map} +0 -0
- /package/dist/{chunk-CQRHNTEX.js.map → chunk-G2KUK6AT.js.map} +0 -0
- /package/dist/{chunk-LBCWEWPN.js.map → chunk-GNU4VOOE.js.map} +0 -0
- /package/dist/{chunk-IW7PK4VS.js.map → chunk-GZ7X34QP.js.map} +0 -0
- /package/dist/{chunk-QEQIJAAB.js.map → chunk-I4SP6JTU.js.map} +0 -0
- /package/dist/{chunk-4SUKNSCY.js.map → chunk-JI265XFO.js.map} +0 -0
- /package/dist/{chunk-6NJW7QFD.js.map → chunk-SA53QUBF.js.map} +0 -0
- /package/dist/{chunk-TBLICXWW.js.map → chunk-TOLTUOZS.js.map} +0 -0
- /package/dist/{chunk-DXO3UJKL.js.map → chunk-TZOQWCVH.js.map} +0 -0
- /package/dist/{chunk-SNTHW4K2.js.map → chunk-W3H7GTJY.js.map} +0 -0
- /package/dist/{chunk-ZHVSHDLH.js.map → chunk-XHOBNSBO.js.map} +0 -0
- /package/dist/{chunk-6O2BXCRN.js.map → chunk-Z2Z52GFT.js.map} +0 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var l=class{handlers=new Map;on(e,n){let t=this.handlers.get(e);return t?t.push(n):this.handlers.set(e,[n]),()=>this.off(e,n)}once(e,n){let t=this.on(e,(...a)=>(t(),n(...a)));return t}off(e,n){if(!n)this.handlers.delete(e);else{let t=this.handlers.get(e);t&&this.handlers.set(e,t.filter(a=>a!==n))}}emit(e,...n){let t=!0;for(let a of this.handlers.get(e)??[])a(...n)===!1&&(t=!1);return t}clearListeners(){this.handlers.clear()}};var i={_lang:"en",_currency:"USD",_firstDay:"0",required:"This field is required",minLength:"Enter at least {n} characters",maxLength:"Enter at most {n} characters",pattern:"Invalid format",email:"Enter a valid email address",min:"Must be at least {n}",max:"Must be at most {n}",range:"Must be between {min} and {max}",number:"Enter a valid number",date:"Enter a valid date",loading:"Loading",close:"Close",ok:"OK",cancel:"Cancel",clear:"Clear",collapse:"Collapse",expand:"Expand",empty:"No data",search:"Search",noResults:"No results",results:"{n} results"},c={_lang:"pt-BR",_currency:"BRL",_firstDay:"0",required:"Campo obrigat\xF3rio",minLength:"Informe ao menos {n} caracteres",maxLength:"Informe no m\xE1ximo {n} caracteres",pattern:"Formato inv\xE1lido",email:"Informe um e-mail v\xE1lido",min:"Deve ser no m\xEDnimo {n}",max:"Deve ser no m\xE1ximo {n}",range:"Deve estar entre {min} e {max}",number:"Informe um n\xFAmero v\xE1lido",date:"Informe uma data v\xE1lida",loading:"Carregando",close:"Fechar",ok:"OK",cancel:"Cancelar",clear:"Limpar",collapse:"Recolher",expand:"Expandir",empty:"Sem dados",search:"Pesquisar",noResults:"Nenhum resultado",results:"{n} resultados"},s={en:i,"pt-BR":c},o=i;function m(r){typeof r=="string"?o=s[r]??s[Object.keys(s).find(e=>e.startsWith(r.split("-")[0]))??"en"]:(o={...i,...r},r._lang&&(s[r._lang]=o))}var g=()=>o;function u(r,e){let n=s[r]??={_lang:r};for(let t in e)t in n||(n[t]=e[t])}function h(r,e){let n=o[r]??i[r]??r;return e?n.replace(/\{(\w+)\}/g,(t,a)=>String(e[a]??"")):n}export{l as a,s as b,m as c,g as d,u as e,h as f};
|
|
2
|
+
//# sourceMappingURL=chunk-MW3RWBZ7.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/core/emitter.ts", "../src/core/i18n.ts"],
|
|
4
|
+
"sourcesContent": ["export type Handler = (...args: any[]) => unknown;\n\n/** Minimal observer. A handler that returns `false` makes `emit` return `false` (used by `before-*` events). */\nexport class Emitter {\n private handlers = new Map<string, Handler[]>();\n\n /** Subscribes; returns the unsubscribe function. */\n on(name: string, fn: Handler): () => void {\n const list = this.handlers.get(name);\n if (list) list.push(fn);\n else this.handlers.set(name, [fn]);\n return () => this.off(name, fn);\n }\n\n once(name: string, fn: Handler): () => void {\n const off = this.on(name, (...a) => {\n off();\n return fn(...a);\n });\n return off;\n }\n\n off(name: string, fn?: Handler): void {\n if (!fn) this.handlers.delete(name);\n else {\n const list = this.handlers.get(name);\n if (list) this.handlers.set(name, list.filter((f) => f !== fn));\n }\n }\n\n /** Returns `false` if any handler returned `false` (the event was cancelled). */\n emit(name: string, ...args: unknown[]): boolean {\n let ok = true;\n for (const fn of this.handlers.get(name) ?? []) if (fn(...args) === false) ok = false;\n return ok;\n }\n\n clearListeners(): void {\n this.handlers.clear();\n }\n}\n", "export type Locale = Record<string, string>;\n\n// Messages shared by the core and several components. Component-only keys live with the component (addMessages).\nconst en: Locale = {\n _lang: 'en',\n _currency: 'USD',\n _firstDay: '0',\n required: 'This field is required',\n minLength: 'Enter at least {n} characters',\n maxLength: 'Enter at most {n} characters',\n pattern: 'Invalid format',\n email: 'Enter a valid email address',\n min: 'Must be at least {n}',\n max: 'Must be at most {n}',\n range: 'Must be between {min} and {max}',\n number: 'Enter a valid number',\n date: 'Enter a valid date',\n loading: 'Loading',\n close: 'Close',\n ok: 'OK',\n cancel: 'Cancel',\n clear: 'Clear',\n collapse: 'Collapse',\n expand: 'Expand',\n empty: 'No data',\n search: 'Search',\n noResults: 'No results',\n results: '{n} results',\n};\n\nconst ptBR: Locale = {\n _lang: 'pt-BR',\n _currency: 'BRL',\n _firstDay: '0',\n required: 'Campo obrigat\u00F3rio',\n minLength: 'Informe ao menos {n} caracteres',\n maxLength: 'Informe no m\u00E1ximo {n} caracteres',\n pattern: 'Formato inv\u00E1lido',\n email: 'Informe um e-mail v\u00E1lido',\n min: 'Deve ser no m\u00EDnimo {n}',\n max: 'Deve ser no m\u00E1ximo {n}',\n range: 'Deve estar entre {min} e {max}',\n number: 'Informe um n\u00FAmero v\u00E1lido',\n date: 'Informe uma data v\u00E1lida',\n loading: 'Carregando',\n close: 'Fechar',\n ok: 'OK',\n cancel: 'Cancelar',\n clear: 'Limpar',\n collapse: 'Recolher',\n expand: 'Expandir',\n empty: 'Sem dados',\n search: 'Pesquisar',\n noResults: 'Nenhum resultado',\n results: '{n} resultados',\n};\n\nexport const locales: Record<string, Locale> = { en, 'pt-BR': ptBR };\nlet current: Locale = en;\n\n/** Picks a registered locale by name (`'pt-BR'`, or `'pt'` as a prefix) or merges a custom object over English. */\nexport function setLocale(l: string | Locale): void {\n if (typeof l === 'string') {\n current = locales[l] ?? locales[Object.keys(locales).find((k) => k.startsWith(l.split('-')[0])) ?? 'en'];\n } else {\n current = { ...en, ...l };\n if (l._lang) locales[l._lang] = current;\n }\n}\n\nexport const getLocale = (): Locale => current;\n\n/**\n * Adds messages to a locale (created if missing). Keys already there are kept, so an app's own overrides win.\n * Each component registers its own keys this way, so its messages only ship with it.\n */\nexport function addMessages(lang: string, messages: Locale): void {\n const target = (locales[lang] ??= { _lang: lang });\n for (const k in messages) if (!(k in target)) target[k] = messages[k];\n}\n\n/** Translates a key, replacing `{name}` placeholders. */\nexport function t(key: string, vars?: Record<string, string | number>): string {\n const s = current[key] ?? en[key] ?? key;\n return vars ? s.replace(/\\{(\\w+)\\}/g, (_, k) => String(vars[k] ?? '')) : s;\n}\n"],
|
|
5
|
+
"mappings": "AAGO,IAAMA,EAAN,KAAc,CACX,SAAW,IAAI,IAGvB,GAAGC,EAAcC,EAAyB,CACxC,IAAMC,EAAO,KAAK,SAAS,IAAIF,CAAI,EACnC,OAAIE,EAAMA,EAAK,KAAKD,CAAE,EACjB,KAAK,SAAS,IAAID,EAAM,CAACC,CAAE,CAAC,EAC1B,IAAM,KAAK,IAAID,EAAMC,CAAE,CAChC,CAEA,KAAKD,EAAcC,EAAyB,CAC1C,IAAME,EAAM,KAAK,GAAGH,EAAM,IAAI,KAC5BG,EAAI,EACGF,EAAG,GAAG,CAAC,EACf,EACD,OAAOE,CACT,CAEA,IAAIH,EAAcC,EAAoB,CACpC,GAAI,CAACA,EAAI,KAAK,SAAS,OAAOD,CAAI,MAC7B,CACH,IAAME,EAAO,KAAK,SAAS,IAAIF,CAAI,EAC/BE,GAAM,KAAK,SAAS,IAAIF,EAAME,EAAK,OAAQE,GAAMA,IAAMH,CAAE,CAAC,CAChE,CACF,CAGA,KAAKD,KAAiBK,EAA0B,CAC9C,IAAIC,EAAK,GACT,QAAWL,KAAM,KAAK,SAAS,IAAID,CAAI,GAAK,CAAC,EAAOC,EAAG,GAAGI,CAAI,IAAM,KAAOC,EAAK,IAChF,OAAOA,CACT,CAEA,gBAAuB,CACrB,KAAK,SAAS,MAAM,CACtB,CACF,ECrCA,IAAMC,EAAa,CACjB,MAAO,KACP,UAAW,MACX,UAAW,IACX,SAAU,yBACV,UAAW,gCACX,UAAW,+BACX,QAAS,iBACT,MAAO,8BACP,IAAK,uBACL,IAAK,sBACL,MAAO,kCACP,OAAQ,uBACR,KAAM,qBACN,QAAS,UACT,MAAO,QACP,GAAI,KACJ,OAAQ,SACR,MAAO,QACP,SAAU,WACV,OAAQ,SACR,MAAO,UACP,OAAQ,SACR,UAAW,aACX,QAAS,aACX,EAEMC,EAAe,CACnB,MAAO,QACP,UAAW,MACX,UAAW,IACX,SAAU,uBACV,UAAW,kCACX,UAAW,sCACX,QAAS,sBACT,MAAO,8BACP,IAAK,4BACL,IAAK,4BACL,MAAO,iCACP,OAAQ,iCACR,KAAM,6BACN,QAAS,aACT,MAAO,SACP,GAAI,KACJ,OAAQ,WACR,MAAO,SACP,SAAU,WACV,OAAQ,WACR,MAAO,YACP,OAAQ,YACR,UAAW,mBACX,QAAS,gBACX,EAEaC,EAAkC,CAAE,GAAAF,EAAI,QAASC,CAAK,EAC/DE,EAAkBH,EAGf,SAASI,EAAUC,EAA0B,CAC9C,OAAOA,GAAM,SACfF,EAAUD,EAAQG,CAAC,GAAKH,EAAQ,OAAO,KAAKA,CAAO,EAAE,KAAMI,GAAMA,EAAE,WAAWD,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAK,IAAI,GAEvGF,EAAU,CAAE,GAAGH,EAAI,GAAGK,CAAE,EACpBA,EAAE,QAAOH,EAAQG,EAAE,KAAK,EAAIF,GAEpC,CAEO,IAAMI,EAAY,IAAcJ,EAMhC,SAASK,EAAYC,EAAcC,EAAwB,CAChE,IAAMC,EAAUT,EAAQO,CAAI,IAAM,CAAE,MAAOA,CAAK,EAChD,QAAWH,KAAKI,EAAgBJ,KAAKK,IAASA,EAAOL,CAAC,EAAII,EAASJ,CAAC,EACtE,CAGO,SAASM,EAAEC,EAAaC,EAAgD,CAC7E,IAAMC,EAAIZ,EAAQU,CAAG,GAAKb,EAAGa,CAAG,GAAKA,EACrC,OAAOC,EAAOC,EAAE,QAAQ,aAAc,CAACC,EAAGV,IAAM,OAAOQ,EAAKR,CAAC,GAAK,EAAE,CAAC,EAAIS,CAC3E",
|
|
6
|
+
"names": ["Emitter", "name", "fn", "list", "off", "f", "args", "ok", "en", "ptBR", "locales", "current", "setLocale", "l", "k", "getLocale", "addMessages", "lang", "messages", "target", "t", "key", "vars", "s", "_"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as h}from"./chunk-KLLAY2IM.js";import{a as d}from"./chunk-W3H7GTJY.js";import{c as n}from"./chunk-4EZJ5FKJ.js";import{b as i}from"./chunk-PZSHOSOS.js";import{a as l}from"./chunk-TIPK3SCJ.js";import{e as o,f as s}from"./chunk-MW3RWBZ7.js";o("en",{secretShow:"Show value",secretHide:"Hide value",secretStored:"A value is saved. It cannot be shown again.",secretReplace:"Replace",secretKeep:"Keep current",secretWarnTitle:"Replace the saved value?",secretWarn:"The saved value cannot be displayed and will be discarded as soon as you replace it. Type the new value next; it takes effect when you save."});o("pt-BR",{secretShow:"Mostrar valor",secretHide:"Ocultar valor",secretStored:"H\xE1 um valor salvo. Ele n\xE3o pode ser exibido novamente.",secretReplace:"Substituir",secretKeep:"Manter o atual",secretWarnTitle:"Substituir o valor salvo?",secretWarn:"O valor salvo n\xE3o pode ser exibido e ser\xE1 descartado assim que voc\xEA o substituir. Digite o novo valor em seguida; ele s\xF3 vale quando voc\xEA salvar."});var p="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",a=class extends d{baseCls="op-field op-textfield op-secret";stored=!1;initialStored=!1;replacing=!1;revealed=!1;eyeBtn;replaceBtn;keepBtn;hint;constructor(e={}){super({autocomplete:"new-password",...e,inputType:"password"}),this.stored=this.initialStored=!!e.stored}emptyValue(){return null}isEmpty(e){return!this.stored&&(e==null||e==="")}createControl(){let e=super.createControl(),t=this.input;return t.spellcheck=!1,this.eyeBtn=i("button","op-secret__eye",{type:"button","aria-pressed":"false"}),this.replaceBtn=i("button","op-secret__replace",{type:"button"},s("secretReplace")),this.keepBtn=i("button","op-secret__keep",{type:"button"},s("secretKeep")),this.hint=i("div","op-secret__hint",{id:`${this.id}-hint`},i("span","op-secret__note",{},s("secretStored")),this.keepBtn),this.listen(this.eyeBtn,"mousedown",r=>r.preventDefault()),this.listen(this.eyeBtn,"click",()=>this.setRevealed(!this.revealed)),this.listen(this.replaceBtn,"click",()=>{this.replace()}),this.listen(this.keepBtn,"click",()=>this.keep()),this.listen(t,"click",()=>this.stored&&void this.replace()),this.listen(t,"keydown",r=>{this.stored&&(r.key==="Enter"||r.key===" ")&&(r.preventDefault(),this.replace())}),this.on("blur",()=>this.config.autoHide!==!1&&this.setRevealed(!1)),e.append(this.eyeBtn,this.replaceBtn),i("div","op-secret__box",{},e,this.hint)}onRender(){super.onRender(),this.paint()}isStored(){return this.stored}isReplacing(){return this.replacing}isRevealed(){return this.revealed}setStored(e){this.stored=e,this.replacing=!1,this.revealed=!1,super.setValue(null,!0),this.paint(),this.emit("stored-change",e)}setValue(e,t=!1){if(e===!0)return this.setStored(!0);e===!1&&(e=null),this.stored&&e!=null&&(this.stored=!1,this.replacing=!0),super.setValue(e,t),this.paint()}markClean(){super.markClean(),this.initialStored=this.stored}reset(){this.setStored(this.initialStored),super.reset()}async replace(){return!this.stored||this.config.readonly||this.config.disabled||this.emit("before-replace")===!1||this.config.confirmReplace!==!1&&!await h.confirm(this.config.replaceText??s("secretWarn"),{danger:!0,title:this.config.replaceTitle??s("secretWarnTitle"),okText:s("secretReplace")})?!1:(this.stored=!1,this.replacing=!0,super.setValue("",!1),this.paint(),this.input.focus(),this.emit("replace"),!0)}keep(){this.replacing&&(this.stored=!0,this.replacing=!1,this.revealed=!1,super.setValue(null,!1),this.paint(),this.emit("keep"))}setRevealed(e){this.stored&&(e=!1),this.revealed=e,this.paint()}getDisplayText(){return this.stored||(this.value??"")!==""?p:""}paint(){if(!this.rendered)return;let e=this.input,t=this.revealed&&!this.stored;e.type=t?"text":"password",e.readOnly=this.stored||!!this.config.readonly,e.placeholder=this.stored?p:this.config.placeholder??"",this.stored&&(e.value=""),e.setAttribute("aria-describedby",this.stored||this.replacing?this.hint.id:""),!this.stored&&!this.replacing&&e.removeAttribute("aria-describedby"),this.eyeBtn.hidden=this.stored,this.eyeBtn.setAttribute("aria-pressed",String(t)),this.eyeBtn.setAttribute("aria-label",s(t?"secretHide":"secretShow")),this.eyeBtn.replaceChildren(n(t?"eye-off":"eye")),this.replaceBtn.hidden=!this.stored,this.hint.hidden=!this.stored&&!this.replacing,this.hint.querySelector(".op-secret__note").hidden=!this.stored,this.keepBtn.hidden=!this.replacing,this.el.classList.toggle("is-stored",this.stored),this.el.classList.toggle("is-replacing",this.replacing),this.el.classList.toggle("is-revealed",t),this.el.classList.toggle("has-value",this.stored||!!e.value)}};l("secretfield",a);export{a};
|
|
2
|
+
//# sourceMappingURL=chunk-NXSTUFS7.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/components/fields/secretfield/secretfield.ts"],
|
|
4
|
+
"sourcesContent": ["import { TextField, type TextFieldConfig } from '../textfield/textfield';\nimport { register } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { t, addMessages } from '../../../core/i18n';\nimport { iconEl } from '../../base/icon/icon';\nimport { MessageBox } from '../../overlays/messagebox/messagebox';\n\naddMessages('en', {\n secretShow: 'Show value',\n secretHide: 'Hide value',\n secretStored: 'A value is saved. It cannot be shown again.',\n secretReplace: 'Replace',\n secretKeep: 'Keep current',\n secretWarnTitle: 'Replace the saved value?',\n secretWarn: 'The saved value cannot be displayed and will be discarded as soon as you replace it. Type the new value next; it takes effect when you save.',\n});\naddMessages('pt-BR', {\n secretShow: 'Mostrar valor',\n secretHide: 'Ocultar valor',\n secretStored: 'H\u00E1 um valor salvo. Ele n\u00E3o pode ser exibido novamente.',\n secretReplace: 'Substituir',\n secretKeep: 'Manter o atual',\n secretWarnTitle: 'Substituir o valor salvo?',\n secretWarn: 'O valor salvo n\u00E3o pode ser exibido e ser\u00E1 descartado assim que voc\u00EA o substituir. Digite o novo valor em seguida; ele s\u00F3 vale quando voc\u00EA salvar.',\n});\n\nexport interface SecretFieldConfig extends TextFieldConfig<string | null> {\n /** A secret is already saved. It can never be shown; it can only be replaced. `form.load({ key: true })` sets it too. */\n stored?: boolean;\n /** Ask before replacing a saved secret. Default true. */\n confirmReplace?: boolean;\n replaceTitle?: string;\n replaceText?: string;\n /** The eye hides the value again when the field loses focus. Default true. */\n autoHide?: boolean;\n}\n\nconst MASK = '\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022';\n\n/**\n * A field for secrets. While you type you can peek at what you typed (the eye); once a secret is saved it is shown only as a\n * mask and can never be read back: to change it you replace it, after a warning. `getValue()` is `null` while untouched\n * (keep what is saved), the new text once typed, `''` when replaced and left empty.\n */\nexport class SecretField extends TextField<string | null, SecretFieldConfig> {\n protected override baseCls = 'op-field op-textfield op-secret';\n private stored = false;\n private initialStored = false;\n private replacing = false;\n private revealed = false;\n private eyeBtn!: HTMLButtonElement;\n private replaceBtn!: HTMLButtonElement;\n private keepBtn!: HTMLButtonElement;\n private hint!: HTMLElement;\n\n constructor(config: SecretFieldConfig = {}) {\n super({ autocomplete: 'new-password', ...config, inputType: 'password' });\n this.stored = this.initialStored = !!config.stored;\n }\n\n protected override emptyValue(): string | null {\n return null;\n }\n /** A saved secret that was not touched counts as filled in (so `required` is satisfied). */\n protected override isEmpty(v: string | null) {\n return !this.stored && (v == null || v === '');\n }\n\n protected override createControl() {\n const wrap = super.createControl();\n const input = this.input;\n input.spellcheck = false;\n this.eyeBtn = h('button', 'op-secret__eye', { type: 'button', 'aria-pressed': 'false' });\n this.replaceBtn = h('button', 'op-secret__replace', { type: 'button' }, t('secretReplace'));\n this.keepBtn = h('button', 'op-secret__keep', { type: 'button' }, t('secretKeep'));\n this.hint = h('div', 'op-secret__hint', { id: `${this.id}-hint` }, h('span', 'op-secret__note', {}, t('secretStored')), this.keepBtn);\n this.listen(this.eyeBtn, 'mousedown', (e: Event) => e.preventDefault()); // keep the focus in the input (it would hide the value)\n this.listen(this.eyeBtn, 'click', () => this.setRevealed(!this.revealed));\n this.listen(this.replaceBtn, 'click', () => void this.replace());\n this.listen(this.keepBtn, 'click', () => this.keep());\n // a saved secret is opened for replacement by clicking or pressing a key in the (read-only) field\n this.listen(input, 'click', () => this.stored && void this.replace());\n this.listen(input, 'keydown', (e: KeyboardEvent) => {\n if (this.stored && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n void this.replace();\n }\n });\n this.on('blur', () => this.config.autoHide !== false && this.setRevealed(false));\n wrap.append(this.eyeBtn, this.replaceBtn);\n return h('div', 'op-secret__box', {}, wrap, this.hint);\n }\n\n protected override onRender() {\n super.onRender();\n this.paint();\n }\n\n // ---- state ---------------------------------------------------------------------------------\n\n isStored(): boolean {\n return this.stored;\n }\n /** The user chose to replace a saved secret and has not finished. */\n isReplacing(): boolean {\n return this.replacing;\n }\n isRevealed(): boolean {\n return this.revealed;\n }\n\n /** Says whether a secret is saved (a saved secret is never given to the field, only the fact that it exists). */\n setStored(stored: boolean): void {\n this.stored = stored;\n this.replacing = false;\n this.revealed = false;\n super.setValue(null, true);\n this.paint();\n this.emit('stored-change', stored);\n }\n\n /** `true` (what `form.load` passes for \"a secret exists\") means saved; a string is a new value typed or set by code. */\n override setValue(v: string | boolean | null, silent = false): void {\n if (v === true) return this.setStored(true);\n if (v === false) v = null;\n if (this.stored && v != null) {\n this.stored = false;\n this.replacing = true;\n }\n super.setValue(v, silent);\n this.paint();\n }\n\n override markClean(): void {\n super.markClean();\n this.initialStored = this.stored;\n }\n /** Back to what was loaded: the saved secret, untouched. */\n override reset(): void {\n this.setStored(this.initialStored);\n super.reset();\n }\n\n /** Warns, then turns a saved secret into an empty field to type the new value in. Resolves to whether it was replaced. */\n async replace(): Promise<boolean> {\n if (!this.stored || this.config.readonly || this.config.disabled || this.emit('before-replace') === false) return false;\n if (this.config.confirmReplace !== false) {\n const ok = await MessageBox.confirm(this.config.replaceText ?? t('secretWarn'), { danger: true, title: this.config.replaceTitle ?? t('secretWarnTitle'), okText: t('secretReplace') });\n if (!ok) return false;\n }\n this.stored = false;\n this.replacing = true;\n super.setValue('', false);\n this.paint();\n this.input.focus();\n this.emit('replace');\n return true;\n }\n\n /** Gives up replacing: the saved secret stays as it was. */\n keep(): void {\n if (!this.replacing) return;\n this.stored = true;\n this.replacing = false;\n this.revealed = false;\n super.setValue(null, false);\n this.paint();\n this.emit('keep');\n }\n\n setRevealed(on: boolean): void {\n if (this.stored) on = false; // there is nothing to see\n this.revealed = on;\n this.paint();\n }\n\n /** Never reveals: a mask when there is something, nothing otherwise. */\n override getDisplayText(): string {\n return this.stored || (this.value ?? '') !== '' ? MASK : '';\n }\n\n // ---- view ----------------------------------------------------------------------------------\n\n private paint(): void {\n if (!this.rendered) return;\n const input = this.input as HTMLInputElement;\n const on = this.revealed && !this.stored;\n input.type = on ? 'text' : 'password';\n input.readOnly = this.stored || !!this.config.readonly;\n input.placeholder = this.stored ? MASK : (this.config.placeholder ?? '');\n if (this.stored) input.value = '';\n input.setAttribute('aria-describedby', this.stored || this.replacing ? this.hint.id : '');\n if (!this.stored && !this.replacing) input.removeAttribute('aria-describedby');\n this.eyeBtn.hidden = this.stored;\n this.eyeBtn.setAttribute('aria-pressed', String(on));\n this.eyeBtn.setAttribute('aria-label', t(on ? 'secretHide' : 'secretShow'));\n this.eyeBtn.replaceChildren(iconEl(on ? 'eye-off' : 'eye'));\n this.replaceBtn.hidden = !this.stored;\n this.hint.hidden = !this.stored && !this.replacing;\n (this.hint.querySelector('.op-secret__note') as HTMLElement).hidden = !this.stored;\n this.keepBtn.hidden = !this.replacing;\n this.el.classList.toggle('is-stored', this.stored);\n this.el.classList.toggle('is-replacing', this.replacing);\n this.el.classList.toggle('is-revealed', on);\n this.el.classList.toggle('has-value', this.stored || !!input.value);\n }\n}\nregister('secretfield', SecretField);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["addMessages", "MASK", "SecretField", "TextField", "config", "v", "wrap", "input", "h", "t", "e", "stored", "silent", "MessageBox", "on", "iconEl", "register"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as p}from"./chunk-MW3RWBZ7.js";var y=0;function f(r,i){return r==null||!i?.type?r:i.type==="number"?r===""?null:Number(r):i.type==="boolean"?r==="false"?!1:!!r:String(r)}var d=class{constructor(i={},e={}){this.def=e;let t={...i};for(let s in e.fields){let o=e.fields[s];t[s]=f(t[s]===void 0?o.default:t[s],o)}this.data=t,this.phantom=this.data[e.idField??"id"]===void 0}def;data;phantom;owner;clientId=`c${++y}`;original={};get id(){return this.data[this.def.idField??"id"]??this.clientId}get(i){return this.data[i]}set(i,e){let t=f(e,this.def.fields?.[i]);this.data[i]!==t&&(i in this.original||(this.original[i]=this.data[i]),this.data[i]=t,this.owner?.recordChanged(this,i))}isDirty(){return Object.keys(this.original).length>0}getChanges(){let i={};for(let e in this.original)i[e]=this.data[e];return i}commit(){this.original={},this.phantom=!1}reject(){Object.assign(this.data,this.original),this.original={}}};var v,T=(r,i)=>r==null?i==null?0:1:i==null?-1:typeof r=="string"&&typeof i=="string"?(v??=new Intl.Collator(void 0,{numeric:!0})).compare(r,i):r<i?-1:r>i?1:0,l=r=>String(r??"").toLowerCase(),c=r=>r==null||r===""||Array.isArray(r)&&!r.length,b=/^\d{4}-\d{2}-\d{2}(T[\d:.]+Z?)?$/,n=r=>r instanceof Date?r.getTime():typeof r=="string"&&b.test(r)?Date.parse(r):r;function w(r,i){let e=r.value,t=n(i),s=()=>!c(i)&&t>=n(e[0])&&t<=n(e[1]),o=()=>e.some(a=>n(a)==t);switch(r.op??"eq"){case"eq":return t==n(e);case"ne":return t!=n(e);case"contains":return l(i).includes(l(e));case"notContains":return!l(i).includes(l(e));case"startsWith":return l(i).startsWith(l(e));case"endsWith":return l(i).endsWith(l(e));case"gt":return t>n(e);case"ge":return t>=n(e);case"lt":return t<n(e);case"le":return t<=n(e);case"between":return s();case"notBetween":return!s();case"in":return o();case"nin":return!o();case"empty":return c(i);case"notEmpty":return!c(i)}}function u(r,i){return"filters"in r?r.filters.length?r.op==="or"?r.filters.some(e=>u(e,i)):r.filters.every(e=>u(e,i)):!0:w(r,i[r.field])}var g=class extends p{constructor(e={}){super();this.cfg=e;this.sorters=e.sorters??[],this.pageLen=e.pageSize??0;for(let t in e.listeners)this.on(t,e.listeners[t]);e.proxy&&(this.proxy=typeof e.proxy=="function"?{read:e.proxy}:e.proxy),e.data&&this.setRecords(e.data.map(t=>this.wrap(t)),e.data.length),e.autoLoad&&this.proxy&&this.load()}cfg;all=[];rows=[];visible=[];removed=[];sorters;filters=[];params={};proxy;pageNo=1;pageLen;total=0;abort;loading=!1;get remote(){return!!this.cfg.remote&&!!this.proxy}wrap(e){let t=e instanceof d?e:new d(e,this.cfg.model);return t.owner=this,t}fire(e,...t){this.emit(e,...t),this.emit("change",{type:e})}get count(){return this.visible.length}get totalCount(){return this.remote?this.total:this.rows.length}getFiltered(){return this.rows}getAt(e){return this.visible[e]}getRange(e=0,t=this.visible.length){return this.visible.slice(e,t)}getById(e){return this.all.find(t=>t.id===e)}indexOf(e){return this.visible.indexOf(e)}getData(){return this.visible.map(e=>e.data)}each(e){this.visible.forEach(e)}loadData(e){this.removed=[],this.setRecords(e.map(t=>this.wrap(t)),e.length),this.fire("load")}async load(e){if(!this.proxy)throw new Error("Optikos Store: load() needs a proxy");e&&(this.params=e);let t={...this.params};if(this.remote&&Object.assign(t,{page:this.pageNo,pageSize:this.pageLen||void 0,sorters:this.sorters,filters:this.filters.filter(o=>typeof o!="function")}),this.emit("before-load",t)===!1)return;this.abort?.abort();let s=this.abort=new AbortController;this.loading=!0,this.emit("loading",!0);try{let o=await this.proxy.read(t,s.signal);if(s.signal.aborted)return;let{data:a,total:h}=Array.isArray(o)?{data:o,total:o.length}:o;this.removed=[],this.setRecords(a.map(m=>this.wrap(m)),h??a.length),this.loading=!1,this.emit("loading",!1),this.fire("load")}catch(o){if(s.signal.aborted)return;this.loading=!1,this.emit("loading",!1),this.emit("load-error",o)}}setRecords(e,t){this.all=e,this.total=t,this.refreshView()}refreshView(){if(this.remote){this.rows=this.visible=this.all;return}let e=this.all;this.filters.length&&(e=e.filter(s=>this.filters.every(o=>typeof o=="function"?o(s):u(o,s.data)))),this.sorters.length&&(e=[...e].sort((s,o)=>{for(let a of this.sorters){let h=T(s.data[a.field],o.data[a.field]);if(h)return a.dir==="desc"?-h:h}return 0})),this.rows=e;let t=this.pageCount;this.pageNo>t&&(this.pageNo=t),this.visible=this.pageLen?e.slice((this.pageNo-1)*this.pageLen,this.pageNo*this.pageLen):e}getSorters(){return this.sorters}sort(e,t){let s=this.sorters[0];this.sorters=e?[{field:e,dir:t??(s?.field===e&&s.dir==="asc"?"desc":"asc")}]:[],this.pageNo=1,this.changeView("sort")}filter(e){return this.filters=Array.isArray(e)?e:[e],this.pageNo=1,this.changeView("filter")}clearFilter(){return this.filters=[],this.pageNo=1,this.changeView("filter")}getFilters(){return this.filters.filter(e=>typeof e!="function")}changeView(e){return this.remote?this.load():(this.refreshView(),this.fire(e),Promise.resolve())}get page(){return this.pageNo}get pageSize(){return this.pageLen}get pageCount(){return this.pageLen?Math.max(1,Math.ceil(this.totalCount/this.pageLen)):1}setPage(e){e=Math.min(Math.max(1,e),this.pageCount),e!==this.pageNo&&(this.pageNo=e,this.remote?this.load():(this.refreshView(),this.fire("page")))}setPageSize(e){this.pageLen=e,this.pageNo=1,this.changeView("page")}add(e){let t=(Array.isArray(e)?e:[e]).map(s=>this.wrap(s));return this.all=[...this.all,...t],this.total+=t.length,this.refreshView(),this.fire("add",t),t}insert(e,t){let s=this.wrap(t);return this.all=[...this.all.slice(0,e),s,...this.all.slice(e)],this.total++,this.refreshView(),this.fire("add",[s]),s}remove(e){let s=(Array.isArray(e)?e:[typeof e=="number"?this.visible[e]:e]).filter(o=>o&&this.all.includes(o));s.length&&(this.all=this.all.filter(o=>!s.includes(o)),this.removed.push(...s.filter(o=>!o.phantom)),this.total-=s.length,this.refreshView(),this.fire("remove",s))}clear(){this.removed.push(...this.all.filter(e=>!e.phantom)),this.setRecords([],0),this.fire("remove",[])}recordChanged(e,t){(this.sorters.some(s=>s.field===t)||this.filters.length)&&this.refreshView(),this.fire("update",e,t)}getModified(){return this.all.filter(e=>e.phantom||e.isDirty())}getRemoved(){return this.removed}commitChanges(){this.all.forEach(e=>e.commit()),this.removed=[]}async sync(){let e=this.proxy;if(!e)throw new Error("Optikos Store: sync() needs a proxy");for(let t of this.removed)await e.destroy?.(t.data);this.removed=[];for(let t of this.all){if(t.phantom)Object.assign(t.data,await e.create?.(t.data)??{});else if(t.isDirty())Object.assign(t.data,await e.update?.(t.data)??{});else continue;t.commit()}this.fire("sync")}subscribe(e){return this.on("change",e)}};export{d as a,u as b,g as c};
|
|
2
|
+
//# sourceMappingURL=chunk-OEAXCCVM.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/data/model.ts", "../src/data/store.ts"],
|
|
4
|
+
"sourcesContent": ["export interface FieldDef {\n type?: 'string' | 'number' | 'boolean';\n default?: unknown;\n}\nexport interface ModelDef {\n idField?: string;\n fields?: Record<string, FieldDef>;\n}\n\nexport interface RecordOwner {\n recordChanged(rec: Model, field: string): void;\n}\n\nlet cid = 0;\n\nfunction convert(v: unknown, def?: FieldDef): unknown {\n if (v == null || !def?.type) return v;\n if (def.type === 'number') return v === '' ? null : Number(v);\n if (def.type === 'boolean') return v === 'false' ? false : Boolean(v);\n return String(v);\n}\n\n/** One record. `data` holds the values; `set` tracks the original value of each changed field. */\nexport class Model<T extends Record<string, any> = Record<string, any>> {\n data: T;\n phantom: boolean;\n owner?: RecordOwner;\n private readonly clientId = `c${++cid}`;\n private original: Partial<T> = {};\n\n constructor(raw: Partial<T> = {}, private def: ModelDef = {}) {\n const data: Record<string, unknown> = { ...raw };\n for (const f in def.fields) {\n const fd = def.fields[f];\n data[f] = convert(data[f] === undefined ? fd.default : data[f], fd);\n }\n this.data = data as T;\n this.phantom = this.data[def.idField ?? 'id'] === undefined;\n }\n\n get id(): string | number {\n return this.data[this.def.idField ?? 'id'] ?? this.clientId;\n }\n\n get<K extends keyof T>(field: K): T[K] {\n return this.data[field];\n }\n\n set<K extends keyof T>(field: K, value: T[K]): void {\n const v = convert(value, this.def.fields?.[field as string]) as T[K];\n if (this.data[field] === v) return;\n if (!(field in this.original)) this.original[field] = this.data[field];\n this.data[field] = v;\n this.owner?.recordChanged(this as Model, field as string);\n }\n\n isDirty(): boolean {\n return Object.keys(this.original).length > 0;\n }\n getChanges(): Partial<T> {\n const out: Partial<T> = {};\n for (const k in this.original) out[k] = this.data[k];\n return out;\n }\n commit(): void {\n this.original = {};\n this.phantom = false;\n }\n reject(): void {\n Object.assign(this.data, this.original);\n this.original = {};\n }\n}\n", "import { Emitter } from '../core/emitter';\nimport { Model, type ModelDef, type RecordOwner } from './model';\nimport type { FilterNode, FilterSpec, Proxy, ReadParams, ReadResult, Sorter } from './proxy';\n\nexport type StoreProxy<T> = Proxy<T> | ((params: ReadParams, signal?: AbortSignal) => Promise<ReadResult<T> | T[]> | ReadResult<T> | T[]);\nexport type FilterFn<T extends Record<string, any>> = (rec: Model<T>) => boolean;\n\nexport interface StoreConfig<T extends Record<string, any>> {\n data?: Partial<T>[];\n model?: ModelDef;\n proxy?: StoreProxy<T>;\n /** 0 = no paging. */\n pageSize?: number;\n /** Sort, filter and paging are done by the proxy (it receives them in `read`). Default false: done locally. */\n remote?: boolean;\n sorters?: Sorter[];\n autoLoad?: boolean;\n listeners?: Record<string, (...a: any[]) => unknown>;\n}\n\n// One collator, made on first use: `localeCompare` with options builds a new one per call (100k rows: 5.4 s \u2192 0.4 s).\nlet collator: Intl.Collator | undefined;\nconst cmp = (a: any, b: any) => (a == null ? (b == null ? 0 : 1) : b == null ? -1 : typeof a === 'string' && typeof b === 'string' ? (collator ??= new Intl.Collator(undefined, { numeric: true })).compare(a, b) : a < b ? -1 : a > b ? 1 : 0);\n\nconst text = (v: any) => String(v ?? '').toLowerCase();\nconst empty = (v: any) => v == null || v === '' || (Array.isArray(v) && !v.length);\nconst ISO = /^\\d{4}-\\d{2}-\\d{2}(T[\\d:.]+Z?)?$/;\n/** Dates (Date objects or ISO strings) compare by time; anything else compares as is. */\nconst num = (v: any) => (v instanceof Date ? v.getTime() : typeof v === 'string' && ISO.test(v) ? Date.parse(v) : v);\n\nfunction test(spec: FilterSpec, raw: any): boolean {\n const x = spec.value as any;\n const v = num(raw);\n const between = () => !empty(raw) && v >= num(x[0]) && v <= num(x[1]);\n const listed = () => (x as unknown[]).some((i) => num(i) == v);\n switch (spec.op ?? 'eq') {\n case 'eq': return v == num(x);\n case 'ne': return v != num(x);\n case 'contains': return text(raw).includes(text(x));\n case 'notContains': return !text(raw).includes(text(x));\n case 'startsWith': return text(raw).startsWith(text(x));\n case 'endsWith': return text(raw).endsWith(text(x));\n case 'gt': return v > num(x);\n case 'ge': return v >= num(x);\n case 'lt': return v < num(x);\n case 'le': return v <= num(x);\n case 'between': return between();\n case 'notBetween': return !between();\n case 'in': return listed();\n case 'nin': return !listed();\n case 'empty': return empty(raw);\n case 'notEmpty': return !empty(raw);\n }\n}\n\n/** Does a record's data satisfy a filter node? Groups are AND/OR; an empty group matches everything. */\nexport function matchFilter(node: FilterNode, data: Record<string, any>): boolean {\n if ('filters' in node) {\n if (!node.filters.length) return true;\n return node.op === 'or' ? node.filters.some((f) => matchFilter(f, data)) : node.filters.every((f) => matchFilter(f, data));\n }\n return test(node, data[node.field]);\n}\n\n/**\n * Records + a view over them (filtered, sorted, paged). Events: `load`, `before-load`, `load-error`, `add`, `remove`,\n * `update`, `sort`, `filter`, `page`, `sync`, and `change` for any of them (payload `{ type }`).\n */\nexport class Store<T extends Record<string, any> = Record<string, any>> extends Emitter implements RecordOwner {\n private all: Model<T>[] = [];\n private rows: Model<T>[] = [];\n private visible: Model<T>[] = [];\n private removed: Model<T>[] = [];\n private sorters: Sorter[];\n private filters: Array<FilterNode | FilterFn<T>> = [];\n private params: Record<string, unknown> = {};\n private proxy?: Proxy<T>;\n private pageNo = 1;\n private pageLen: number;\n private total = 0;\n private abort?: AbortController;\n loading = false;\n\n constructor(private cfg: StoreConfig<T> = {}) {\n super();\n this.sorters = cfg.sorters ?? [];\n this.pageLen = cfg.pageSize ?? 0;\n for (const k in cfg.listeners) this.on(k, cfg.listeners[k]);\n if (cfg.proxy) this.proxy = typeof cfg.proxy === 'function' ? { read: cfg.proxy } : cfg.proxy;\n if (cfg.data) this.setRecords(cfg.data.map((r) => this.wrap(r)), cfg.data.length);\n if (cfg.autoLoad && this.proxy) void this.load();\n }\n\n private get remote() {\n return !!this.cfg.remote && !!this.proxy;\n }\n private wrap(raw: Partial<T> | Model<T>): Model<T> {\n const m = raw instanceof Model ? raw : new Model<T>(raw, this.cfg.model);\n m.owner = this;\n return m;\n }\n private fire(type: string, ...args: unknown[]) {\n this.emit(type, ...args);\n this.emit('change', { type });\n }\n\n // ---- reading -------------------------------------------------------------------------------\n\n /** Number of records in the current view (the current page). */\n get count(): number {\n return this.visible.length;\n }\n /** Records matching the filters, across pages (remote: what the server reported). */\n get totalCount(): number {\n return this.remote ? this.total : this.rows.length;\n }\n /** Every record matching the filters, across pages (a remote store only knows the loaded page). */\n getFiltered(): Model<T>[] {\n return this.rows;\n }\n getAt(i: number): Model<T> | undefined {\n return this.visible[i];\n }\n getRange(start = 0, end = this.visible.length): Model<T>[] {\n return this.visible.slice(start, end);\n }\n getById(id: string | number): Model<T> | undefined {\n return this.all.find((r) => r.id === id);\n }\n indexOf(rec: Model<T>): number {\n return this.visible.indexOf(rec);\n }\n /** Plain data of the current view. */\n getData(): T[] {\n return this.visible.map((r) => r.data);\n }\n each(fn: (rec: Model<T>, i: number) => void): void {\n this.visible.forEach(fn);\n }\n\n // ---- loading -------------------------------------------------------------------------------\n\n /** Replaces all records with local data. */\n loadData(data: Partial<T>[]): void {\n this.removed = [];\n this.setRecords(data.map((r) => this.wrap(r)), data.length);\n this.fire('load');\n }\n\n /** Reads through the proxy. Extra `params` are sent to it and remembered for later reloads. A newer load cancels the older one. */\n async load(params?: Record<string, unknown>): Promise<void> {\n if (!this.proxy) throw new Error('Optikos Store: load() needs a proxy');\n if (params) this.params = params;\n const req: ReadParams = { ...this.params };\n if (this.remote) Object.assign(req, { page: this.pageNo, pageSize: this.pageLen || undefined, sorters: this.sorters, filters: this.filters.filter((f): f is FilterNode => typeof f !== 'function') });\n if (this.emit('before-load', req) === false) return;\n this.abort?.abort();\n const ctl = (this.abort = new AbortController());\n this.loading = true;\n this.emit('loading', true);\n try {\n const res = await this.proxy.read(req, ctl.signal);\n if (ctl.signal.aborted) return;\n const { data, total } = Array.isArray(res) ? { data: res, total: res.length } : res;\n this.removed = [];\n this.setRecords(data.map((r) => this.wrap(r)), total ?? data.length);\n this.loading = false;\n this.emit('loading', false);\n this.fire('load');\n } catch (err) {\n if (ctl.signal.aborted) return;\n this.loading = false;\n this.emit('loading', false);\n this.emit('load-error', err);\n }\n }\n\n private setRecords(recs: Model<T>[], total: number) {\n this.all = recs;\n this.total = total;\n this.refreshView();\n }\n\n /** Recomputes filtered/sorted/paged rows from `all`. */\n private refreshView() {\n if (this.remote) {\n this.rows = this.visible = this.all;\n return;\n }\n let rows = this.all;\n if (this.filters.length) rows = rows.filter((r) => this.filters.every((f) => (typeof f === 'function' ? f(r) : matchFilter(f, r.data))));\n if (this.sorters.length) {\n rows = [...rows].sort((a, b) => {\n for (const s of this.sorters) {\n const d = cmp(a.data[s.field], b.data[s.field]);\n if (d) return s.dir === 'desc' ? -d : d;\n }\n return 0;\n });\n }\n this.rows = rows;\n const pages = this.pageCount;\n if (this.pageNo > pages) this.pageNo = pages;\n this.visible = this.pageLen ? rows.slice((this.pageNo - 1) * this.pageLen, this.pageNo * this.pageLen) : rows;\n }\n\n // ---- sort / filter / paging ----------------------------------------------------------------\n\n getSorters(): Sorter[] {\n return this.sorters;\n }\n /** `sort('name')` toggles asc/desc when already sorted by it; `sort('name', 'desc')` is explicit; `sort(null)` clears. */\n sort(field: string | null, dir?: 'asc' | 'desc'): void {\n const cur = this.sorters[0];\n this.sorters = field ? [{ field, dir: dir ?? (cur?.field === field && cur.dir === 'asc' ? 'desc' : 'asc') }] : [];\n this.pageNo = 1;\n this.changeView('sort');\n }\n\n /**\n * Replaces the filters (top level = AND). Accepts specs, groups (`{ op: 'or', filters }`), or a predicate.\n * Resolves when the view is up to date (for a remote store, after the reload).\n */\n filter(f: FilterNode | FilterNode[] | FilterFn<T>): Promise<void> {\n this.filters = Array.isArray(f) ? f : [f];\n this.pageNo = 1;\n return this.changeView('filter');\n }\n clearFilter(): Promise<void> {\n this.filters = [];\n this.pageNo = 1;\n return this.changeView('filter');\n }\n /** The active filter nodes (predicates are not included). */\n getFilters(): FilterNode[] {\n return this.filters.filter((f): f is FilterNode => typeof f !== 'function');\n }\n\n private changeView(type: string): Promise<void> {\n if (this.remote) return this.load();\n this.refreshView();\n this.fire(type);\n return Promise.resolve();\n }\n\n get page(): number {\n return this.pageNo;\n }\n get pageSize(): number {\n return this.pageLen;\n }\n get pageCount(): number {\n return this.pageLen ? Math.max(1, Math.ceil(this.totalCount / this.pageLen)) : 1;\n }\n setPage(n: number): void {\n n = Math.min(Math.max(1, n), this.pageCount);\n if (n === this.pageNo) return;\n this.pageNo = n;\n if (this.remote) void this.load();\n else {\n this.refreshView();\n this.fire('page');\n }\n }\n setPageSize(n: number): void {\n this.pageLen = n;\n this.pageNo = 1;\n this.changeView('page');\n }\n\n // ---- editing -------------------------------------------------------------------------------\n\n add(raw: Partial<T> | Partial<T>[]): Model<T>[] {\n const recs = (Array.isArray(raw) ? raw : [raw]).map((r) => this.wrap(r));\n this.all = [...this.all, ...recs];\n this.total += recs.length;\n this.refreshView();\n this.fire('add', recs);\n return recs;\n }\n\n insert(index: number, raw: Partial<T>): Model<T> {\n const rec = this.wrap(raw);\n this.all = [...this.all.slice(0, index), rec, ...this.all.slice(index)];\n this.total++;\n this.refreshView();\n this.fire('add', [rec]);\n return rec;\n }\n\n remove(target: Model<T> | number | Array<Model<T>>): void {\n const list = Array.isArray(target) ? target : [typeof target === 'number' ? this.visible[target] : target];\n const gone = list.filter((r) => r && this.all.includes(r));\n if (!gone.length) return;\n this.all = this.all.filter((r) => !gone.includes(r));\n this.removed.push(...gone.filter((r) => !r.phantom));\n this.total -= gone.length;\n this.refreshView();\n this.fire('remove', gone);\n }\n\n clear(): void {\n this.removed.push(...this.all.filter((r) => !r.phantom));\n this.setRecords([], 0);\n this.fire('remove', []);\n }\n\n recordChanged(rec: Model, field: string): void {\n if (this.sorters.some((s) => s.field === field) || this.filters.length) this.refreshView();\n this.fire('update', rec, field);\n }\n\n getModified(): Model<T>[] {\n return this.all.filter((r) => r.phantom || r.isDirty());\n }\n getRemoved(): Model<T>[] {\n return this.removed;\n }\n commitChanges(): void {\n this.all.forEach((r) => r.commit());\n this.removed = [];\n }\n\n /** Writes pending changes through the proxy: deletes, then creates and updates, one at a time. */\n async sync(): Promise<void> {\n const p = this.proxy;\n if (!p) throw new Error('Optikos Store: sync() needs a proxy');\n for (const r of this.removed) await p.destroy?.(r.data);\n this.removed = [];\n for (const r of this.all) {\n if (r.phantom) Object.assign(r.data, (await p.create?.(r.data)) ?? {});\n else if (r.isDirty()) Object.assign(r.data, (await p.update?.(r.data)) ?? {});\n else continue;\n r.commit();\n }\n this.fire('sync');\n }\n\n /** Observable interface used by `optikos/bind`: calls `fn` on any change; returns the unsubscribe function. */\n subscribe(fn: (change: { type: string }) => void): () => void {\n return this.on('change', fn);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["cid", "convert", "v", "def", "Model", "raw", "data", "f", "fd", "field", "value", "out", "k", "collator", "cmp", "a", "b", "text", "v", "empty", "ISO", "num", "test", "spec", "raw", "x", "between", "listed", "i", "matchFilter", "node", "data", "f", "Store", "Emitter", "cfg", "k", "r", "m", "Model", "type", "args", "start", "end", "id", "rec", "fn", "params", "req", "ctl", "res", "total", "err", "recs", "rows", "s", "d", "pages", "field", "dir", "cur", "n", "index", "target", "gone", "p"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as l}from"./chunk-2ZRNGG2N.js";import{c as n}from"./chunk-4EZJ5FKJ.js";import{b as o}from"./chunk-PZSHOSOS.js";import{a as r}from"./chunk-TIPK3SCJ.js";var p=class extends l{baseCls="op-field op-checkboxgroup";group;inputs=[];emptyValue(){return[]}isEmpty(e){return!e?.length}isEqual(e,t){return(e??[]).length===(t??[]).length&&(e??[]).every((i,s)=>i===t[s])}createControl(){return this.group=o("div","op-checkboxgroup__options",{role:"group","aria-labelledby":`${this.id}-label`}),this.listen(this.group,"change",e=>{if(!this.inputs.includes(e.target))return;if(this.config.readonly)return this.applyValue(this.value);let t=this.opts();this.commit(this.inputs.flatMap((i,s)=>i.checked?[t[s].value]:[])),this.paint()}),this.buildOptions(),this.inputEl=this.inputs[0]??this.group,this.group}opts(){return(this.config.options??[]).map(e=>typeof e=="object"?e:{value:e,label:e,disabled:!1})}buildOptions(){this.inputs=[],this.group.replaceChildren(...this.opts().map(e=>{let t=o("input","op-checkbox__input",{type:"checkbox",value:String(e.value),disabled:!!e.disabled});return this.inputs.push(t),o("label","op-checkbox op-checkbox__label",{},t,o("span","op-checkbox__box",{},n("check")),o("span","op-checkbox__text",{},e.label))})),this.group.classList.toggle("op-checkboxgroup__options--horizontal",this.config.direction==="horizontal")}onRender(){super.onRender(),this.el.querySelector(".op-field__label").id=`${this.id}-label`}applyValue(e){let t=this.opts();this.inputs.forEach((i,s)=>i.checked=(e??[]).includes(t[s].value)),this.paint()}paint(){for(let e of this.inputs)e.closest("label").classList.toggle("is-checked",e.checked)}getDisplayText(){let e=this.getValue()??[];return this.opts().filter(t=>e.includes(t.value)).map(t=>t.label).join(", ")}onDisabled(e){this.inputs.forEach((t,i)=>t.disabled=e||!!this.opts()[i].disabled)}setOptions(e){this.config.options=e,this.rendered&&(this.buildOptions(),this.inputEl=this.inputs[0]??this.group,this.applyValue(this.value),this.onDisabled(!!this.config.disabled))}};r("checkboxgroup",p);export{p as a};
|
|
2
|
+
//# sourceMappingURL=chunk-OGRFQTXA.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/components/fields/checkboxgroup/checkboxgroup.ts"],
|
|
4
|
+
"sourcesContent": ["import { Field, type FieldConfig } from '../../../core/field';\nimport { register } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { iconEl } from '../../base/icon/icon';\nimport type { RadioOption } from '../radiogroup/radiogroup';\n\ntype Value = string | number;\nexport interface CheckboxGroupConfig extends FieldConfig<Value[]> {\n options?: RadioOption[];\n direction?: 'vertical' | 'horizontal';\n}\n\n/** Several choices from a few visible options; the value is the list of checked option values, in option order. */\nexport class CheckboxGroup extends Field<Value[], CheckboxGroupConfig> {\n protected override baseCls = 'op-field op-checkboxgroup';\n private group!: HTMLElement;\n private inputs: HTMLInputElement[] = [];\n\n protected override emptyValue(): Value[] {\n return [];\n }\n /** `required` means \"at least one\". */\n protected override isEmpty(v: Value[]) {\n return !v?.length;\n }\n protected override isEqual(a: Value[], b: Value[]) {\n return (a ?? []).length === (b ?? []).length && (a ?? []).every((x, i) => x === b[i]);\n }\n\n protected createControl() {\n this.group = h('div', 'op-checkboxgroup__options', { role: 'group', 'aria-labelledby': `${this.id}-label` });\n this.listen(this.group, 'change', (e: Event) => {\n if (!this.inputs.includes(e.target as HTMLInputElement)) return;\n if (this.config.readonly) return this.applyValue(this.value);\n const opts = this.opts();\n this.commit(this.inputs.flatMap((input, i) => (input.checked ? [opts[i].value] : [])));\n this.paint();\n });\n this.buildOptions();\n this.inputEl = this.inputs[0] ?? this.group;\n return this.group;\n }\n\n private opts() {\n return (this.config.options ?? []).map((o) => (typeof o === 'object' ? o : { value: o, label: o, disabled: false }));\n }\n\n private buildOptions() {\n this.inputs = [];\n this.group.replaceChildren(\n ...this.opts().map((o) => {\n const input = h('input', 'op-checkbox__input', { type: 'checkbox', value: String(o.value), disabled: !!o.disabled });\n this.inputs.push(input);\n // each option reuses the Checkbox look (`op-checkbox` + `is-checked` on the label)\n return h('label', 'op-checkbox op-checkbox__label', {}, input, h('span', 'op-checkbox__box', {}, iconEl('check')), h('span', 'op-checkbox__text', {}, o.label));\n }),\n );\n this.group.classList.toggle('op-checkboxgroup__options--horizontal', this.config.direction === 'horizontal');\n }\n\n protected override onRender() {\n super.onRender();\n (this.el.querySelector('.op-field__label') as HTMLElement).id = `${this.id}-label`;\n }\n\n protected applyValue(v: Value[]) {\n const opts = this.opts();\n this.inputs.forEach((input, i) => (input.checked = (v ?? []).includes(opts[i].value)));\n this.paint();\n }\n\n private paint() {\n for (const input of this.inputs) input.closest('label')!.classList.toggle('is-checked', input.checked);\n }\n\n override getDisplayText(): string {\n const v = this.getValue() ?? [];\n return this.opts().filter((o) => v.includes(o.value)).map((o) => o.label).join(', ');\n }\n\n protected override onDisabled(disabled: boolean) {\n this.inputs.forEach((i, n) => (i.disabled = disabled || !!this.opts()[n].disabled));\n }\n\n setOptions(options: RadioOption[]) {\n this.config.options = options;\n if (!this.rendered) return;\n this.buildOptions();\n this.inputEl = this.inputs[0] ?? this.group;\n this.applyValue(this.value);\n this.onDisabled(!!this.config.disabled);\n }\n}\nregister('checkboxgroup', CheckboxGroup);\n"],
|
|
5
|
+
"mappings": "gKAaO,IAAMA,EAAN,cAA4BC,CAAoC,CAClD,QAAU,4BACrB,MACA,OAA6B,CAAC,EAEnB,YAAsB,CACvC,MAAO,CAAC,CACV,CAEmB,QAAQC,EAAY,CACrC,MAAO,CAACA,GAAG,MACb,CACmB,QAAQC,EAAYC,EAAY,CACjD,OAAQD,GAAK,CAAC,GAAG,UAAYC,GAAK,CAAC,GAAG,SAAWD,GAAK,CAAC,GAAG,MAAM,CAACE,EAAGC,IAAMD,IAAMD,EAAEE,CAAC,CAAC,CACtF,CAEU,eAAgB,CACxB,YAAK,MAAQC,EAAE,MAAO,4BAA6B,CAAE,KAAM,QAAS,kBAAmB,GAAG,KAAK,EAAE,QAAS,CAAC,EAC3G,KAAK,OAAO,KAAK,MAAO,SAAW,GAAa,CAC9C,GAAI,CAAC,KAAK,OAAO,SAAS,EAAE,MAA0B,EAAG,OACzD,GAAI,KAAK,OAAO,SAAU,OAAO,KAAK,WAAW,KAAK,KAAK,EAC3D,IAAMC,EAAO,KAAK,KAAK,EACvB,KAAK,OAAO,KAAK,OAAO,QAAQ,CAACC,EAAOH,IAAOG,EAAM,QAAU,CAACD,EAAKF,CAAC,EAAE,KAAK,EAAI,CAAC,CAAE,CAAC,EACrF,KAAK,MAAM,CACb,CAAC,EACD,KAAK,aAAa,EAClB,KAAK,QAAU,KAAK,OAAO,CAAC,GAAK,KAAK,MAC/B,KAAK,KACd,CAEQ,MAAO,CACb,OAAQ,KAAK,OAAO,SAAW,CAAC,GAAG,IAAKI,GAAO,OAAOA,GAAM,SAAWA,EAAI,CAAE,MAAOA,EAAG,MAAOA,EAAG,SAAU,EAAM,CAAE,CACrH,CAEQ,cAAe,CACrB,KAAK,OAAS,CAAC,EACf,KAAK,MAAM,gBACT,GAAG,KAAK,KAAK,EAAE,IAAKA,GAAM,CACxB,IAAMD,EAAQF,EAAE,QAAS,qBAAsB,CAAE,KAAM,WAAY,MAAO,OAAOG,EAAE,KAAK,EAAG,SAAU,CAAC,CAACA,EAAE,QAAS,CAAC,EACnH,YAAK,OAAO,KAAKD,CAAK,EAEfF,EAAE,QAAS,iCAAkC,CAAC,EAAGE,EAAOF,EAAE,OAAQ,mBAAoB,CAAC,EAAGI,EAAO,OAAO,CAAC,EAAGJ,EAAE,OAAQ,oBAAqB,CAAC,EAAGG,EAAE,KAAK,CAAC,CAChK,CAAC,CACH,EACA,KAAK,MAAM,UAAU,OAAO,wCAAyC,KAAK,OAAO,YAAc,YAAY,CAC7G,CAEmB,UAAW,CAC5B,MAAM,SAAS,EACd,KAAK,GAAG,cAAc,kBAAkB,EAAkB,GAAK,GAAG,KAAK,EAAE,QAC5E,CAEU,WAAWR,EAAY,CAC/B,IAAMM,EAAO,KAAK,KAAK,EACvB,KAAK,OAAO,QAAQ,CAACC,EAAOH,IAAOG,EAAM,SAAWP,GAAK,CAAC,GAAG,SAASM,EAAKF,CAAC,EAAE,KAAK,CAAE,EACrF,KAAK,MAAM,CACb,CAEQ,OAAQ,CACd,QAAWG,KAAS,KAAK,OAAQA,EAAM,QAAQ,OAAO,EAAG,UAAU,OAAO,aAAcA,EAAM,OAAO,CACvG,CAES,gBAAyB,CAChC,IAAMP,EAAI,KAAK,SAAS,GAAK,CAAC,EAC9B,OAAO,KAAK,KAAK,EAAE,OAAQQ,GAAMR,EAAE,SAASQ,EAAE,KAAK,CAAC,EAAE,IAAKA,GAAMA,EAAE,KAAK,EAAE,KAAK,IAAI,CACrF,CAEmB,WAAWE,EAAmB,CAC/C,KAAK,OAAO,QAAQ,CAACN,EAAGO,IAAOP,EAAE,SAAWM,GAAY,CAAC,CAAC,KAAK,KAAK,EAAEC,CAAC,EAAE,QAAS,CACpF,CAEA,WAAWC,EAAwB,CACjC,KAAK,OAAO,QAAUA,EACjB,KAAK,WACV,KAAK,aAAa,EAClB,KAAK,QAAU,KAAK,OAAO,CAAC,GAAK,KAAK,MACtC,KAAK,WAAW,KAAK,KAAK,EAC1B,KAAK,WAAW,CAAC,CAAC,KAAK,OAAO,QAAQ,EACxC,CACF,EACAC,EAAS,gBAAiBf,CAAa",
|
|
6
|
+
"names": ["CheckboxGroup", "Field", "v", "a", "b", "x", "i", "h", "opts", "input", "o", "iconEl", "disabled", "n", "options", "register"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as u}from"./chunk-W2BAFOCN.js";import{c as p}from"./chunk-4EZJ5FKJ.js";import{a as d}from"./chunk-A2NKDOYN.js";import{b as i}from"./chunk-PZSHOSOS.js";import{a as l}from"./chunk-TIPK3SCJ.js";import{e as m,f as h}from"./chunk-MW3RWBZ7.js";m("en",{breadcrumb:"Breadcrumb",breadcrumbMore:"Show more"});m("pt-BR",{breadcrumb:"Trilha de navega\xE7\xE3o",breadcrumbMore:"Mostrar mais"});var c=class extends d{baseCls="op-breadcrumb";tag="nav";list;menu;onRender(){this.list=i("ol","op-breadcrumb__list"),this.el.append(this.list),this.config.ariaLabel||this.el.setAttribute("aria-label",h("breadcrumb")),this.config.separator!=null&&this.setSeparator(this.config.separator),this.listen(this.list,"click",e=>{let r=e.target;if(r.closest(".op-breadcrumb__more"))return this.showHidden(r.closest("button"));let t=r.closest("[data-i]");t&&this.go(Number(t.dataset.i),e)}),this.own(()=>this.menu?.destroy()),this.paint()}items(){return this.config.items??[]}collapsed(){let e=this.items().length,r=Math.max(3,this.config.maxItems??4);return e<=r?[]:Array.from({length:e-(r-1)},(t,s)=>s+1)}paint(){let e=this.items(),r=this.collapsed(),t=e.length-1,s=[];e.forEach((a,n)=>{if(r.includes(n)){n===r[0]&&s.push(i("li","",{},i("button","op-breadcrumb__more",{type:"button","aria-label":h("breadcrumbMore"),"aria-haspopup":"menu","aria-expanded":"false"},"\u2026")));return}let o=[a.icon?p(a.icon):null,a.text],b=n===t?i("span","op-breadcrumb__current",{"aria-current":"page"},...o):a.href?i("a","op-breadcrumb__item",{href:a.href,"data-i":n},...o):i("button","op-breadcrumb__item",{type:"button","data-i":n},...o);s.push(i("li","",{},b))}),this.list.replaceChildren(...s)}go(e,r){let t=this.items()[e];return!t||e===this.items().length-1?!1:this.emit("before-navigate",t,e)===!1?(r?.preventDefault(),!1):(t.handler?.(t),this.emit("navigate",t,e),!0)}showHidden(e){let r=this.items();this.menu??=new u({}),this.menu.setItems(this.collapsed().map(t=>({text:r[t].text,icon:r[t].icon,handler:()=>{this.go(t)&&r[t].href&&(location.href=r[t].href)}}))),this.menu.on("show",()=>e.setAttribute("aria-expanded","true")),this.menu.on("hide",()=>e.setAttribute("aria-expanded","false")),this.menu.showBy(e)}setItems(e){this.config.items=e,this.rendered&&this.paint()}setMaxItems(e){this.config.maxItems=e,this.rendered&&this.paint()}setSeparator(e){this.config.separator=e,this.rendered&&this.el.style.setProperty("--op-breadcrumb-separator",JSON.stringify(e))}};l("breadcrumb",c);export{c as a};
|
|
2
|
+
//# sourceMappingURL=chunk-Q26YZYTD.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/components/navigation/breadcrumb/breadcrumb.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';\nimport { Menu } from '../../overlays/menu/menu';\n\naddMessages('en', {\n breadcrumb: 'Breadcrumb',\n breadcrumbMore: 'Show more',\n});\naddMessages('pt-BR', {\n breadcrumb: 'Trilha de navega\u00E7\u00E3o',\n breadcrumbMore: 'Mostrar mais',\n});\n\nexport interface BreadcrumbItem {\n text: string;\n icon?: string;\n /** Renders a real link (native navigation, middle-click, copy link). */\n href?: string;\n handler?: (item: BreadcrumbItem) => void;\n}\n\nexport interface BreadcrumbConfig extends ComponentConfig {\n items?: BreadcrumbItem[];\n /** More items than this collapse the middle into a \"\u2026\" menu. Minimum 3, default 4. */\n maxItems?: number;\n separator?: string;\n}\n\nexport class Breadcrumb extends Component<BreadcrumbConfig> {\n protected override baseCls = 'op-breadcrumb';\n protected override tag = 'nav' as const;\n private list!: HTMLElement;\n private menu?: Menu;\n\n protected override onRender() {\n this.list = h('ol', 'op-breadcrumb__list');\n this.el.append(this.list);\n if (!this.config.ariaLabel) this.el.setAttribute('aria-label', t('breadcrumb'));\n if (this.config.separator != null) this.setSeparator(this.config.separator);\n this.listen(this.list, 'click', (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (target.closest('.op-breadcrumb__more')) return this.showHidden(target.closest('button')!);\n const el = target.closest<HTMLElement>('[data-i]');\n if (el) this.go(Number(el.dataset.i), e);\n });\n this.own(() => this.menu?.destroy());\n this.paint();\n }\n\n private items(): BreadcrumbItem[] {\n return this.config.items ?? [];\n }\n\n /** Indexes hidden behind the \"\u2026\" button (empty when everything fits). */\n private collapsed(): number[] {\n const n = this.items().length;\n const max = Math.max(3, this.config.maxItems ?? 4);\n if (n <= max) return [];\n return Array.from({ length: n - (max - 1) }, (_, i) => i + 1);\n }\n\n private paint() {\n const items = this.items();\n const hidden = this.collapsed();\n const last = items.length - 1;\n const lis: HTMLElement[] = [];\n items.forEach((item, i) => {\n if (hidden.includes(i)) {\n if (i === hidden[0]) lis.push(h('li', '', {}, h('button', 'op-breadcrumb__more', { type: 'button', 'aria-label': t('breadcrumbMore'), 'aria-haspopup': 'menu', 'aria-expanded': 'false' }, '\u2026')));\n return;\n }\n const content = [item.icon ? iconEl(item.icon) : null, item.text];\n const node =\n i === last\n ? h('span', 'op-breadcrumb__current', { 'aria-current': 'page' }, ...content)\n : item.href\n ? h('a', 'op-breadcrumb__item', { href: item.href, 'data-i': i }, ...content)\n : h('button', 'op-breadcrumb__item', { type: 'button', 'data-i': i }, ...content);\n lis.push(h('li', '', {}, node));\n });\n this.list.replaceChildren(...lis);\n }\n\n /** Runs `before-navigate` / handler / `navigate`. Returns false when cancelled. */\n private go(i: number, e?: Event): boolean {\n const item = this.items()[i];\n if (!item || i === this.items().length - 1) return false;\n if (this.emit('before-navigate', item, i) === false) {\n e?.preventDefault();\n return false;\n }\n item.handler?.(item);\n this.emit('navigate', item, i);\n return true;\n }\n\n private showHidden(button: HTMLElement) {\n const items = this.items();\n this.menu ??= new Menu({});\n this.menu.setItems(\n this.collapsed().map((i) => ({\n text: items[i].text,\n icon: items[i].icon,\n handler: () => {\n if (this.go(i) && items[i].href) location.href = items[i].href!;\n },\n })),\n );\n this.menu.on('show', () => button.setAttribute('aria-expanded', 'true'));\n this.menu.on('hide', () => button.setAttribute('aria-expanded', 'false'));\n this.menu.showBy(button);\n }\n\n setItems(items: BreadcrumbItem[]) {\n this.config.items = items;\n if (this.rendered) this.paint();\n }\n\n setMaxItems(max: number) {\n this.config.maxItems = max;\n if (this.rendered) this.paint();\n }\n\n /** Any text, e.g. `'/'` or `'\u203A'`. */\n setSeparator(separator: string) {\n this.config.separator = separator;\n if (this.rendered) this.el.style.setProperty('--op-breadcrumb-separator', JSON.stringify(separator));\n }\n}\nregister('breadcrumb', Breadcrumb);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["addMessages", "Breadcrumb", "Component", "h", "t", "target", "el", "n", "max", "_", "i", "items", "hidden", "last", "lis", "item", "content", "iconEl", "node", "e", "button", "Menu", "separator", "register"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{c as r}from"./chunk-ZWNQREWS.js";import{c as d}from"./chunk-4EZJ5FKJ.js";import{b as i,c as o}from"./chunk-PZSHOSOS.js";import{a as n}from"./chunk-TIPK3SCJ.js";import{f as l}from"./chunk-MW3RWBZ7.js";var s=class extends r{baseCls="op-fieldset";tag="fieldset";legend;bodyEl;toggleBtn;descEl;getBody(){return this.bodyEl}build(){let e=super.build();return this.legend=i("legend","op-fieldset__legend"),this.descEl=i("p","op-fieldset__desc",{id:o("op-fs-desc")}),this.bodyEl=i("div","op-fieldset__body"),e.append(this.legend,this.descEl,this.bodyEl),e}onRender(){this.config.layout??=this.config.columns?{type:"grid",columns:this.config.columns}:{type:"vbox"},super.onRender(),this.setVariant(this.config.variant??"box"),this.setDescription(this.config.description??""),this.config.collapsible&&(this.toggleBtn=i("button","op-fieldset__toggle",{type:"button"},d("chevron-up")),this.listen(this.toggleBtn,"click",()=>this.toggle()),this.legend.prepend(this.toggleBtn)),this.setTitle(this.config.title??""),this.setCollapsed(!!this.config.collapsed)}setTitle(e){if(this.config.title=e,!this.rendered)return;let t=this.legend.querySelector(".op-fieldset__title");t||(this.legend.append(t=i("span","op-fieldset__title")),this.config.collapsible&&this.listen(t,"click",()=>this.toggle())),t.textContent=e,this.legend.hidden=!e&&!this.config.collapsible}setDescription(e){this.config.description=e,this.rendered&&(this.descEl.textContent=e,this.descEl.hidden=!e,e?this.el.setAttribute("aria-describedby",this.descEl.id):this.el.removeAttribute("aria-describedby"))}setVariant(e){if(this.config.variant=e,!!this.rendered)for(let t of["box","line","plain"])this.el.classList.toggle(`op-fieldset--${t}`,t===e)}setCollapsed(e){this.config.collapsed=e,this.rendered&&(this.el.classList.toggle("is-collapsed",e),this.bodyEl.hidden=e,e?this.descEl.hidden=!0:this.descEl.hidden=!this.config.description,this.toggleBtn?.setAttribute("aria-expanded",String(!e)),this.toggleBtn?.setAttribute("aria-label",l(e?"expand":"collapse")))}collapse(){this.config.collapsed||this.emit("before-collapse")===!1||(this.setCollapsed(!0),this.emit("collapse"))}expand(){!this.config.collapsed||this.emit("before-expand")===!1||(this.setCollapsed(!1),this.emit("expand"))}toggle(){this.config.collapsed?this.expand():this.collapse()}};n("fieldset",s);export{s as a};
|
|
2
|
+
//# sourceMappingURL=chunk-REW4LR46.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/components/layout/fieldset/fieldset.ts"],
|
|
4
|
+
"sourcesContent": ["import { Container, type ContainerConfig } from '../../../core/container';\nimport { register } from '../../../core/registry';\nimport { h, uid } from '../../../core/dom';\nimport { t } from '../../../core/i18n';\nimport { iconEl } from '../../base/icon/icon';\n\nexport interface FieldSetConfig extends ContainerConfig {\n title?: string;\n /** A line under the legend, read as the group's description. */\n description?: string;\n /** `box` (a framed group, default), `line` (a rule under the legend, no frame) or `plain` (just the legend). */\n variant?: 'box' | 'line' | 'plain';\n /** Shortcut for a responsive grid layout; items take `colspan` (a number or `'full'`). */\n columns?: number;\n collapsible?: boolean;\n collapsed?: boolean;\n}\n\nexport class FieldSet extends Container<FieldSetConfig> {\n protected override baseCls = 'op-fieldset';\n protected override tag = 'fieldset' as const;\n private legend!: HTMLElement;\n private bodyEl!: HTMLElement;\n private toggleBtn?: HTMLButtonElement;\n private descEl!: HTMLElement;\n\n override getBody() {\n return this.bodyEl;\n }\n\n protected override build() {\n const el = super.build();\n this.legend = h('legend', 'op-fieldset__legend');\n this.descEl = h('p', 'op-fieldset__desc', { id: uid('op-fs-desc') });\n this.bodyEl = h('div', 'op-fieldset__body');\n el.append(this.legend, this.descEl, this.bodyEl);\n return el;\n }\n\n protected override onRender() {\n this.config.layout ??= this.config.columns ? { type: 'grid', columns: this.config.columns } : { type: 'vbox' };\n super.onRender();\n this.setVariant(this.config.variant ?? 'box');\n this.setDescription(this.config.description ?? '');\n if (this.config.collapsible) {\n this.toggleBtn = h('button', 'op-fieldset__toggle', { type: 'button' }, iconEl('chevron-up'));\n this.listen(this.toggleBtn, 'click', () => this.toggle());\n this.legend.prepend(this.toggleBtn);\n }\n this.setTitle(this.config.title ?? '');\n this.setCollapsed(!!this.config.collapsed);\n }\n\n setTitle(title: string) {\n this.config.title = title;\n if (!this.rendered) return;\n let text = this.legend.querySelector('.op-fieldset__title');\n if (!text) {\n this.legend.append((text = h('span', 'op-fieldset__title')));\n if (this.config.collapsible) this.listen(text, 'click', () => this.toggle()); // the title toggles too (the chevron is the button)\n }\n text.textContent = title;\n this.legend.hidden = !title && !this.config.collapsible;\n }\n\n setDescription(text: string) {\n this.config.description = text;\n if (!this.rendered) return;\n this.descEl.textContent = text;\n this.descEl.hidden = !text;\n if (text) this.el.setAttribute('aria-describedby', this.descEl.id);\n else this.el.removeAttribute('aria-describedby');\n }\n\n setVariant(variant: 'box' | 'line' | 'plain') {\n this.config.variant = variant;\n if (!this.rendered) return;\n for (const v of ['box', 'line', 'plain']) this.el.classList.toggle(`op-fieldset--${v}`, v === variant);\n }\n\n setCollapsed(collapsed: boolean) {\n this.config.collapsed = collapsed;\n if (!this.rendered) return;\n this.el.classList.toggle('is-collapsed', collapsed);\n this.bodyEl.hidden = collapsed;\n if (collapsed) this.descEl.hidden = true;\n else this.descEl.hidden = !this.config.description;\n this.toggleBtn?.setAttribute('aria-expanded', String(!collapsed));\n this.toggleBtn?.setAttribute('aria-label', t(collapsed ? 'expand' : 'collapse'));\n }\n collapse() {\n if (this.config.collapsed || this.emit('before-collapse') === false) return;\n this.setCollapsed(true);\n this.emit('collapse');\n }\n expand() {\n if (!this.config.collapsed || this.emit('before-expand') === false) return;\n this.setCollapsed(false);\n this.emit('expand');\n }\n toggle() {\n if (this.config.collapsed) this.expand();\n else this.collapse();\n }\n}\nregister('fieldset', FieldSet);\n"],
|
|
5
|
+
"mappings": "+MAkBO,IAAMA,EAAN,cAAuBC,CAA0B,CACnC,QAAU,cACV,IAAM,WACjB,OACA,OACA,UACA,OAEC,SAAU,CACjB,OAAO,KAAK,MACd,CAEmB,OAAQ,CACzB,IAAMC,EAAK,MAAM,MAAM,EACvB,YAAK,OAASC,EAAE,SAAU,qBAAqB,EAC/C,KAAK,OAASA,EAAE,IAAK,oBAAqB,CAAE,GAAIC,EAAI,YAAY,CAAE,CAAC,EACnE,KAAK,OAASD,EAAE,MAAO,mBAAmB,EAC1CD,EAAG,OAAO,KAAK,OAAQ,KAAK,OAAQ,KAAK,MAAM,EACxCA,CACT,CAEmB,UAAW,CAC5B,KAAK,OAAO,SAAW,KAAK,OAAO,QAAU,CAAE,KAAM,OAAQ,QAAS,KAAK,OAAO,OAAQ,EAAI,CAAE,KAAM,MAAO,EAC7G,MAAM,SAAS,EACf,KAAK,WAAW,KAAK,OAAO,SAAW,KAAK,EAC5C,KAAK,eAAe,KAAK,OAAO,aAAe,EAAE,EAC7C,KAAK,OAAO,cACd,KAAK,UAAYC,EAAE,SAAU,sBAAuB,CAAE,KAAM,QAAS,EAAGE,EAAO,YAAY,CAAC,EAC5F,KAAK,OAAO,KAAK,UAAW,QAAS,IAAM,KAAK,OAAO,CAAC,EACxD,KAAK,OAAO,QAAQ,KAAK,SAAS,GAEpC,KAAK,SAAS,KAAK,OAAO,OAAS,EAAE,EACrC,KAAK,aAAa,CAAC,CAAC,KAAK,OAAO,SAAS,CAC3C,CAEA,SAASC,EAAe,CAEtB,GADA,KAAK,OAAO,MAAQA,EAChB,CAAC,KAAK,SAAU,OACpB,IAAIC,EAAO,KAAK,OAAO,cAAc,qBAAqB,EACrDA,IACH,KAAK,OAAO,OAAQA,EAAOJ,EAAE,OAAQ,oBAAoB,CAAE,EACvD,KAAK,OAAO,aAAa,KAAK,OAAOI,EAAM,QAAS,IAAM,KAAK,OAAO,CAAC,GAE7EA,EAAK,YAAcD,EACnB,KAAK,OAAO,OAAS,CAACA,GAAS,CAAC,KAAK,OAAO,WAC9C,CAEA,eAAeC,EAAc,CAC3B,KAAK,OAAO,YAAcA,EACrB,KAAK,WACV,KAAK,OAAO,YAAcA,EAC1B,KAAK,OAAO,OAAS,CAACA,EAClBA,EAAM,KAAK,GAAG,aAAa,mBAAoB,KAAK,OAAO,EAAE,EAC5D,KAAK,GAAG,gBAAgB,kBAAkB,EACjD,CAEA,WAAWC,EAAmC,CAE5C,GADA,KAAK,OAAO,QAAUA,EAClB,EAAC,KAAK,SACV,QAAWC,IAAK,CAAC,MAAO,OAAQ,OAAO,EAAG,KAAK,GAAG,UAAU,OAAO,gBAAgBA,CAAC,GAAIA,IAAMD,CAAO,CACvG,CAEA,aAAaE,EAAoB,CAC/B,KAAK,OAAO,UAAYA,EACnB,KAAK,WACV,KAAK,GAAG,UAAU,OAAO,eAAgBA,CAAS,EAClD,KAAK,OAAO,OAASA,EACjBA,EAAW,KAAK,OAAO,OAAS,GAC/B,KAAK,OAAO,OAAS,CAAC,KAAK,OAAO,YACvC,KAAK,WAAW,aAAa,gBAAiB,OAAO,CAACA,CAAS,CAAC,EAChE,KAAK,WAAW,aAAa,aAAcC,EAAED,EAAY,SAAW,UAAU,CAAC,EACjF,CACA,UAAW,CACL,KAAK,OAAO,WAAa,KAAK,KAAK,iBAAiB,IAAM,KAC9D,KAAK,aAAa,EAAI,EACtB,KAAK,KAAK,UAAU,EACtB,CACA,QAAS,CACH,CAAC,KAAK,OAAO,WAAa,KAAK,KAAK,eAAe,IAAM,KAC7D,KAAK,aAAa,EAAK,EACvB,KAAK,KAAK,QAAQ,EACpB,CACA,QAAS,CACH,KAAK,OAAO,UAAW,KAAK,OAAO,EAClC,KAAK,SAAS,CACrB,CACF,EACAE,EAAS,WAAYZ,CAAQ",
|
|
6
|
+
"names": ["FieldSet", "Container", "el", "h", "uid", "iconEl", "title", "text", "variant", "v", "collapsed", "t", "register"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{c as n}from"./chunk-ZWNQREWS.js";import{a as d}from"./chunk-2ZRNGG2N.js";import{b as r,c as o}from"./chunk-PZSHOSOS.js";import{a as s}from"./chunk-TIPK3SCJ.js";var l=class extends n{baseCls="op-field op-fieldgroup";labelEl;bodyEl;helpEl;errorEl;error="";constructor(e={}){super(e);for(let t of this.items)t.config.width!=null&&t.config.flex==null&&(t.config.flex="none");for(let t of this.getFields()){t.config.labelPos="top";for(let i of["invalid","valid"])t.on(i,()=>this.paintError())}}getBody(){return this.bodyEl}getFields(){return this.query(e=>e instanceof d)}getError(){return this.error}build(){let e=super.build();return this.labelEl=r("div","op-field__label",{id:o("op-fg")}),this.bodyEl=r("div","op-fieldgroup__body"),this.helpEl=r("div","op-field__help",{id:o("op-fg-help")}),this.errorEl=r("div","op-field__error",{id:o("op-fg-err"),role:"alert"}),e.append(this.labelEl,r("div","op-field__control",{},this.bodyEl),this.helpEl,this.errorEl),e.setAttribute("role","group"),e.setAttribute("aria-labelledby",this.labelEl.id),e}onRender(){let e=this.config;e.layout??={type:"hbox",stackBelow:e.stackBelow},super.onRender();let t=e.labelPos;for(let i=this.parent;!t&&i;i=i.parent)t=i.config.labelPos;this.el.classList.toggle("op-field--label-left",t==="left"),this.setLabel(e.label??""),this.setHelp(e.help??""),this.el.classList.toggle("is-required",!!e.required||this.getFields().some(i=>i.config.required)),this.listen(this.labelEl,"click",()=>this.getFields()[0]?.focus()),this.error="",this.paintError()}paintError(){let e=this.getFields().map(t=>t.getError()).find(Boolean)??"";e!==this.error&&(this.error=e,this.rendered&&(this.errorEl.textContent=e,this.el.classList.toggle("is-invalid",!!e),this.describe(),this.emit(e?"invalid":"valid",e)))}describe(){let e=[this.error&&this.errorEl.id,this.config.help&&this.helpEl.id].filter(Boolean);e.length?this.el.setAttribute("aria-describedby",e.join(" ")):this.el.removeAttribute("aria-describedby")}setLabel(e){this.config.label=e,this.rendered&&(this.labelEl.textContent=e,this.labelEl.hidden=!e)}setHelp(e){this.config.help=e,this.rendered&&(this.helpEl.textContent=e,this.helpEl.hidden=!e,this.describe())}};s("fieldgroup",l);export{l as a};
|
|
2
|
+
//# sourceMappingURL=chunk-RNN55473.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/components/form/fieldgroup/fieldgroup.ts"],
|
|
4
|
+
"sourcesContent": ["import { Container, type ContainerConfig } from '../../../core/container';\nimport { Field } from '../../../core/field';\nimport { register } from '../../../core/registry';\nimport { h, uid } from '../../../core/dom';\nimport type { Component } from '../../../core/component';\n\nexport interface FieldGroupConfig extends ContainerConfig {\n label?: string;\n help?: string;\n /** The `*` marker (also shown when any field inside is required). */\n required?: boolean;\n /** Default: the form's `labelPos`. */\n labelPos?: 'top' | 'left';\n /** Under this width (px) the row becomes a column. */\n stackBelow?: number;\n}\n\n/** Several inputs read as one field: one label, one help line and one error line over a row of fields. */\nexport class FieldGroup extends Container<FieldGroupConfig> {\n protected override baseCls = 'op-field op-fieldgroup';\n private labelEl!: HTMLElement;\n private bodyEl!: HTMLElement;\n private helpEl!: HTMLElement;\n private errorEl!: HTMLElement;\n private error = '';\n\n constructor(config: FieldGroupConfig = {}) {\n super(config);\n // the fields keep their labels for screen readers only: their own label position must not shape the row\n // a field that sets a width keeps it; the others share what is left\n for (const c of this.items) if (c.config.width != null && c.config.flex == null) c.config.flex = 'none' as never;\n for (const f of this.getFields()) {\n f.config.labelPos = 'top';\n for (const ev of ['invalid', 'valid']) f.on(ev, () => this.paintError()); // also before the group is rendered\n }\n }\n\n override getBody() {\n return this.bodyEl;\n }\n\n /** The fields inside (also inside nested containers). */\n getFields(): Field<any>[] {\n return this.query((c) => c instanceof Field) as Field<any>[];\n }\n\n getError(): string {\n return this.error;\n }\n\n protected override build() {\n const el = super.build();\n this.labelEl = h('div', 'op-field__label', { id: uid('op-fg') });\n this.bodyEl = h('div', 'op-fieldgroup__body');\n this.helpEl = h('div', 'op-field__help', { id: uid('op-fg-help') });\n this.errorEl = h('div', 'op-field__error', { id: uid('op-fg-err'), role: 'alert' });\n el.append(this.labelEl, h('div', 'op-field__control', {}, this.bodyEl), this.helpEl, this.errorEl);\n el.setAttribute('role', 'group');\n el.setAttribute('aria-labelledby', this.labelEl.id);\n return el;\n }\n\n protected override onRender() {\n const c = this.config;\n c.layout ??= { type: 'hbox', stackBelow: c.stackBelow };\n super.onRender();\n let pos = c.labelPos;\n for (let p: Component | undefined = this.parent as Component | undefined; !pos && p; p = p.parent as Component | undefined) pos = (p.config as FieldGroupConfig).labelPos;\n this.el.classList.toggle('op-field--label-left', pos === 'left');\n this.setLabel(c.label ?? '');\n this.setHelp(c.help ?? '');\n this.el.classList.toggle('is-required', !!c.required || this.getFields().some((f) => f.config.required));\n this.listen(this.labelEl, 'click', () => this.getFields()[0]?.focus());\n this.error = '';\n this.paintError();\n }\n\n /** The group shows the first error of its fields, in one line. */\n private paintError() {\n const msg = this.getFields().map((f) => f.getError()).find(Boolean) ?? '';\n if (msg === this.error) return;\n this.error = msg;\n if (!this.rendered) return;\n this.errorEl.textContent = msg;\n this.el.classList.toggle('is-invalid', !!msg);\n this.describe();\n this.emit(msg ? 'invalid' : 'valid', msg);\n }\n\n private describe() {\n const ids = [this.error && this.errorEl.id, this.config.help && this.helpEl.id].filter(Boolean);\n if (ids.length) this.el.setAttribute('aria-describedby', ids.join(' '));\n else this.el.removeAttribute('aria-describedby');\n }\n\n setLabel(label: string) {\n this.config.label = label;\n if (!this.rendered) return;\n this.labelEl.textContent = label;\n this.labelEl.hidden = !label;\n }\n\n setHelp(help: string) {\n this.config.help = help;\n if (!this.rendered) return;\n this.helpEl.textContent = help;\n this.helpEl.hidden = !help;\n this.describe();\n }\n}\nregister('fieldgroup', FieldGroup);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["FieldGroup", "Container", "config", "c", "f", "ev", "Field", "el", "h", "uid", "pos", "p", "msg", "ids", "label", "help", "register"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as s}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import{a as s}from"./chunk-E4VNLYO2.js";import{b as u}from"./chunk-676AKAGF.js";import{b as l}from"./chunk-PZSHOSOS.js";var p=400,o,i,d,c=!1,r=e=>e instanceof Element?e.closest("[data-op-tip]"):null;function m(e){let t=e.dataset.opTip;t&&(o??=l("div","op-tooltip",{role:"tooltip",id:"op-tooltip"}),o.textContent=t,u(o,e),i=e,e.setAttribute("aria-describedby","op-tooltip"),s(o,e,{placement:"top",offset:6}))}function n(){clearTimeout(d),i&&i.removeAttribute("aria-describedby"),i=void 0,o?.remove()}function f(e,t){clearTimeout(d),i!==e&&(n(),d=setTimeout(()=>m(e),t))}function E(){c||typeof document>"u"||(c=!0,document.addEventListener("pointerover",e=>{if(e.pointerType==="touch")return;let t=r(e.target);t&&f(t,p)}),document.addEventListener("pointerout",e=>{let t=r(e.target);t&&!t.contains(e.relatedTarget)&&n()}),document.addEventListener("focusin",e=>{let t=r(e.target),a=!0;try{a=!!t?.matches(":focus-visible")}catch{}t&&a&&f(t,0)}),document.addEventListener("focusout",n),document.addEventListener("pointerdown",n,!0),document.addEventListener("keydown",e=>e.key==="Escape"&&n(),!0),document.addEventListener("scroll",n,!0))}E();var L={configure(e){e.delay!=null&&(p=e.delay)},show:m,hide:n};function b(e,t){e.dataset.opTip=t}export{L as a,b};
|
|
2
|
+
//# sourceMappingURL=chunk-SA53QUBF.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=new Map;function r(o,n){n.type=o,e.set(o,n)}var s=o=>e.get(o);function i(o){if(typeof o.render=="function")return o;let n=o,t=n.type?e.get(n.type):void 0;if(!t)throw new Error(`Optikos: unknown component type "${n.type}". Did you import or register it?`);let p=new t(n);return n.renderTo&&p.mount(n.renderTo),p}export{r as a,s as b,i as c};
|
|
2
|
+
//# sourceMappingURL=chunk-TIPK3SCJ.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/core/registry.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Component, ComponentConfig } from './component';\n\nexport type ComponentClass = { new (config: any): Component<any>; type?: string };\n/** Config accepted by `create` and `items`: the base keys plus whatever the chosen `type` understands. */\nexport type AnyConfig = ComponentConfig & Record<string, any>;\n\nconst types = new Map<string, ComponentClass>();\n\n/** Registers a component class under a `type`. Users register their own the same way. */\nexport function register(type: string, cls: ComponentClass): void {\n cls.type = type;\n types.set(type, cls);\n}\n\nexport const getType = (type: string): ComponentClass | undefined => types.get(type);\n\n/** Builds a component from a config (or passes an instance through). `renderTo` mounts it. */\nexport function create<T extends Component = Component>(config: AnyConfig | Component): T {\n if (typeof (config as Component).render === 'function') return config as T;\n const cfg = config as AnyConfig;\n const Cls = cfg.type ? types.get(cfg.type) : undefined;\n if (!Cls) throw new Error(`Optikos: unknown component type \"${cfg.type}\". Did you import or register it?`);\n const cmp = new Cls(cfg) as T;\n if (cfg.renderTo) cmp.mount(cfg.renderTo);\n return cmp;\n}\n"],
|
|
5
|
+
"mappings": "AAMA,IAAMA,EAAQ,IAAI,IAGX,SAASC,EAASC,EAAcC,EAA2B,CAChEA,EAAI,KAAOD,EACXF,EAAM,IAAIE,EAAMC,CAAG,CACrB,CAEO,IAAMC,EAAWF,GAA6CF,EAAM,IAAIE,CAAI,EAG5E,SAASG,EAAwCC,EAAkC,CACxF,GAAI,OAAQA,EAAqB,QAAW,WAAY,OAAOA,EAC/D,IAAMC,EAAMD,EACNE,EAAMD,EAAI,KAAOP,EAAM,IAAIO,EAAI,IAAI,EAAI,OAC7C,GAAI,CAACC,EAAK,MAAM,IAAI,MAAM,oCAAoCD,EAAI,IAAI,mCAAmC,EACzG,IAAME,EAAM,IAAID,EAAID,CAAG,EACvB,OAAIA,EAAI,UAAUE,EAAI,MAAMF,EAAI,QAAQ,EACjCE,CACT",
|
|
6
|
+
"names": ["types", "register", "type", "cls", "getType", "create", "config", "cfg", "Cls", "cmp"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as t}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import{c as t}from"./chunk-ZWNQREWS.js";import{a as o}from"./chunk-TIPK3SCJ.js";var e,r=class extends t{baseCls="op-viewport";constructor(n={}){if(super(n),e&&!e.destroyed)throw new Error("Optikos: only one Viewport can exist at a time");e=this}onRender(){this.config.layout??="fit",super.onRender()}};o("viewport",r);export{r as a};
|
|
2
|
+
//# sourceMappingURL=chunk-TOLTUOZS.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as l}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import{a as l}from"./chunk-EV73ADN2.js";import{c as a}from"./chunk-4EZJ5FKJ.js";import{b as s}from"./chunk-PZSHOSOS.js";import{a as h}from"./chunk-TIPK3SCJ.js";import{f as o}from"./chunk-MW3RWBZ7.js";var n=class extends l{baseCls="op-field op-textfield op-picker op-suggest";seq=0;abort;cancelWait;live;hasTrigger(){return!1}emptyValue(){return null}isEmpty(e){return e==null||e===""}createControl(){let e=super.createControl();return this.config.icon!==!1&&(e.classList.add("has-icon"),e.prepend(s("span","op-suggest__icon",{"aria-hidden":"true"},a(this.config.icon??"search")))),e.append(s("span","op-spinner op-picker__spinner",{"aria-hidden":"true"})),this.live=s("div","op-sr-only",{"aria-live":"polite"}),e.append(this.live),this.own(()=>this.abort?.abort()),e}onRender(){super.onRender(),this.config.store?.on("load",()=>this.showResults(this.items))}onType(e){if(this.cancelWait?.(),this.abort?.abort(),e.trim().length<(this.config.minChars??1))return this.items=[],this.refreshList(),this.setSearching(!1),this.close();this.cancelWait=this.later(()=>{this.search(e)},this.config.delay??250)}async search(e){if(this.emit("before-query",e)===!1)return;let i=++this.seq,c=this.abort=new AbortController;this.setSearching(!0),this.emit("query",e);try{let t=this.config,r;if(t.store?(await t.store.load({query:e}),r=t.store.getData()):r=await t.query?.(e,{signal:c.signal})??[],i!==this.seq)return;this.items=r.map(p=>this.toItem(p)),this.showResults(this.items,e),this.emit("load",this.items)}catch(t){if(i!==this.seq)return;this.setSearching(!1),this.close(),this.emit("error",t)}}showResults(e,i=this.input.value){this.setSearching(!1),this.typed=!0,this.refreshList(),this.list.setHighlight(this.config.highlight===!1?"":i),this.live.textContent=e.length?o("results",{n:e.length}):o("noResults"),document.activeElement===this.input&&this.open()}setSearching(e){this.el.classList.toggle("is-searching",e),this.input.setAttribute("aria-busy",String(e))}setQuery(e){this.config.query=e}clearSuggestions(){this.items=[],this.refreshList(),this.close()}pick(e){super.pick(e),this.list.setHighlight("")}};h("suggestfield",n);export{n as a};
|
|
2
|
+
//# sourceMappingURL=chunk-TZOQWCVH.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as c}from"./chunk-TZOQWCVH.js";import{b as h,c as g,d as k}from"./chunk-EJGWCKE4.js";import{a as f}from"./chunk-4LZZ244E.js";import{c as u}from"./chunk-4EZJ5FKJ.js";import{b as d}from"./chunk-PZSHOSOS.js";import{a}from"./chunk-TIPK3SCJ.js";import{e as l,f as s}from"./chunk-MW3RWBZ7.js";l("en",{lookupOpen:"Open search",lookupSelect:"Select"});l("pt-BR",{lookupOpen:"Abrir pesquisa",lookupSelect:"Selecionar"});var p=class extends c{baseCls="op-field op-textfield op-picker op-suggest op-lookup";def;suggestStore;win;constructor(e){let t=h(e.lookup);super({...e,icon:!1,valueField:t.valueField??"id",displayField:t.displayField??"name",query:o=>this.suggest(o)}),this.def=t}async suggest(e){let t=this.suggestStore??=g(this.def),o=this.def.queryField??this.def.filters?.[0]?.name??this.config.displayField,i=this.def.filters?.find(n=>n.name===o)?.field??o;return await t.filter({field:i,op:"contains",value:e}),t.getData()}createControl(){let e=super.createControl(),t=d("button","op-picker__trigger op-lookup__btn",{type:"button",tabindex:-1,"aria-label":s("lookupOpen"),"aria-haspopup":"dialog"},u("search"));return this.listen(t,"mousedown",o=>o.preventDefault()),this.listen(t,"click",()=>this.openDialog()),e.append(t),this.own(()=>this.win?.destroy()),e}onKey(e){e.key==="F4"||e.altKey&&e.key==="ArrowDown"?(e.preventDefault(),this.openDialog()):super.onKey(e)}onDisabled(e){super.onDisabled(e),this.el.querySelector(".op-lookup__btn").disabled=e}openDialog(){if(this.win||this.config.disabled||this.config.readonly||!this.rendered)return;this.close();let e=this.def,t=new k({lookup:e,flex:1}),o=this.typed?this.input.value:"";t.on("confirm",r=>i(r));let i=r=>{r[0]&&this.pickRecord(r[0]),n.close()},n=this.win=new f({title:e.title??s("search"),width:e.width??720,height:e.height??520,layout:"fit",items:[t],buttons:[{text:s("cancel"),handler:()=>n.close()},{text:s("lookupSelect"),variant:"primary",handler:()=>i(t.getSelection())}]});n.on("destroy",()=>{this.win=void 0,this.rendered&&this.input.focus()}),n.show(),o&&t.search(o)}pickRecord(e){let{valueField:t,displayField:o}=this.config,i={value:e.get(t),label:String(e.get(o)??e.get(t)??""),raw:e.data};this.pick(i)}};a("lookupfield",p);export{p as a};
|
|
2
|
+
//# sourceMappingURL=chunk-UB5RYS7T.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/components/fields/lookupfield/lookupfield.ts"],
|
|
4
|
+
"sourcesContent": ["import { SuggestField, type SuggestConfig } from '../suggestfield/suggestfield';\nimport { register } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { t, addMessages } from '../../../core/i18n';\nimport type { Model } from '../../../data/model';\nimport type { Store } from '../../../data/store';\nimport { iconEl } from '../../base/icon/icon';\nimport { Window } from '../../overlays/window/window';\nimport { SearchGrid, resolveLookup, lookupStore, type LookupDef } from '../../data/searchgrid/searchgrid';\n\naddMessages('en', {\n lookupOpen: 'Open search',\n lookupSelect: 'Select',\n});\naddMessages('pt-BR', {\n lookupOpen: 'Abrir pesquisa',\n lookupSelect: 'Selecionar',\n});\n\nexport interface LookupFieldConfig<V = unknown> extends SuggestConfig<V> {\n /** A definition or the name given to `registerLookup`. */\n lookup: LookupDef | string;\n}\n\n/**\n * Pick a record from a big set: type to get suggestions, or press the magnifier (or F4) to open a search window\n * with filters and a grid. The value is the record's `valueField`; the text is its `displayField`.\n */\nexport class LookupField<V = unknown> extends SuggestField<V> {\n protected override baseCls = 'op-field op-textfield op-picker op-suggest op-lookup';\n private def: LookupDef;\n private suggestStore?: Store<any>;\n private win?: Window;\n\n constructor(config: LookupFieldConfig<V>) {\n const def = resolveLookup(config.lookup);\n super({\n ...config,\n icon: false,\n valueField: def.valueField ?? 'id',\n displayField: def.displayField ?? 'name',\n query: (text) => this.suggest(text),\n });\n this.def = def;\n }\n\n /** Typing: filter a private store by the quick-search field and offer its page of records. */\n private async suggest(text: string) {\n const s = (this.suggestStore ??= lookupStore(this.def));\n const name = this.def.queryField ?? this.def.filters?.[0]?.name ?? this.config.displayField!;\n const field = this.def.filters?.find((f) => f.name === name)?.field ?? name;\n await s.filter({ field, op: 'contains', value: text });\n return s.getData();\n }\n\n protected override createControl() {\n const wrap = super.createControl();\n const btn = h('button', 'op-picker__trigger op-lookup__btn', { type: 'button', tabindex: -1, 'aria-label': t('lookupOpen'), 'aria-haspopup': 'dialog' }, iconEl('search'));\n this.listen(btn, 'mousedown', (e: Event) => e.preventDefault());\n this.listen(btn, 'click', () => this.openDialog());\n wrap.append(btn);\n this.own(() => this.win?.destroy());\n return wrap;\n }\n\n protected override onKey(e: KeyboardEvent) {\n if (e.key === 'F4' || (e.altKey && e.key === 'ArrowDown')) {\n e.preventDefault();\n this.openDialog();\n } else super.onKey(e);\n }\n\n protected override onDisabled(disabled: boolean) {\n super.onDisabled(disabled);\n (this.el.querySelector('.op-lookup__btn') as HTMLButtonElement).disabled = disabled;\n }\n\n /** Opens the search window; the text typed so far pre-fills the quick-search field. */\n openDialog(): void {\n if (this.win || this.config.disabled || this.config.readonly || !this.rendered) return;\n this.close();\n const d = this.def;\n const sg = new SearchGrid({ lookup: d, flex: 1 });\n const text = this.typed ? this.input.value : '';\n sg.on('confirm', (recs: Model[]) => done(recs));\n const done = (recs: Model[]) => {\n if (recs[0]) this.pickRecord(recs[0]);\n win.close();\n };\n const win: Window = (this.win = new Window({\n title: d.title ?? t('search'),\n width: d.width ?? 720,\n height: d.height ?? 520,\n layout: 'fit',\n items: [sg],\n buttons: [{ text: t('cancel'), handler: () => win.close() }, { text: t('lookupSelect'), variant: 'primary', handler: () => done(sg.getSelection()) }],\n }));\n win.on('destroy', () => {\n this.win = undefined;\n if (this.rendered) this.input.focus();\n });\n win.show();\n if (text) void sg.search(text);\n }\n\n private pickRecord(rec: Model): void {\n const { valueField, displayField } = this.config;\n const item = { value: rec.get(valueField!), label: String(rec.get(displayField!) ?? rec.get(valueField!) ?? ''), raw: rec.data };\n this.pick(item as any);\n }\n}\nregister('lookupfield', LookupField);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["addMessages", "LookupField", "SuggestField", "config", "def", "resolveLookup", "text", "s", "lookupStore", "name", "field", "f", "wrap", "btn", "h", "t", "iconEl", "e", "disabled", "d", "sg", "SearchGrid", "recs", "done", "win", "Window", "rec", "valueField", "displayField", "item", "register"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as v}from"./chunk-KLLAY2IM.js";import{a as m}from"./chunk-W2BAFOCN.js";import{a as w}from"./chunk-2ZUZ5HDL.js";import{a as f}from"./chunk-A2NKDOYN.js";import{b as u}from"./chunk-PZSHOSOS.js";import{a as c}from"./chunk-TIPK3SCJ.js";import{e as d,f as n}from"./chunk-MW3RWBZ7.js";d("en",{views:"Views",viewsName:"Name for this view",viewsSave:"Save view",viewsSaveAs:"Save as new view\u2026",viewsDefault:"Open with this view",viewsDelete:"Delete view",viewsConfirmDelete:'Delete the view "{n}"?',viewsReset:"Reset to initial"});d("pt-BR",{views:"Vis\xF5es",viewsName:"Nome desta vis\xE3o",viewsSave:"Salvar vis\xE3o",viewsSaveAs:"Salvar como nova vis\xE3o\u2026",viewsDefault:"Abrir com esta vis\xE3o",viewsDelete:"Excluir vis\xE3o",viewsConfirmDelete:'Excluir a vis\xE3o "{n}"?',viewsReset:"Voltar ao inicial"});var g=()=>globalThis.crypto?.randomUUID?.()??`${Date.now()}-${Math.random().toString(36).slice(2)}`;function M(a,e=localStorage){let t=()=>{try{let s=JSON.parse(e.getItem(a)??"[]");return Array.isArray(s)?s:[]}catch{return[]}},i=s=>e.setItem(a,JSON.stringify(s));return{list:t,save(s){let r={...s,id:s.id??g()},o=t(),h=o.findIndex(p=>p.id===r.id);return h<0?o.push(r):o[h]=r,i(o),r},remove(s){i(t().filter(r=>r.id!==s.id))}}}function P(a){let e=async(t,i="",s)=>{let r=await(a.fetch??fetch)(a.url+i,{method:t,headers:{"Content-Type":"application/json",...a.headers},body:s===void 0?void 0:JSON.stringify(s)});if(!r.ok)throw new Error(`Optikos views: ${t} ${a.url+i} \u2192 ${r.status}`);return r.status===204?void 0:r.json().catch(()=>{})};return{list:()=>e("GET"),save:t=>t.id?e("PUT",`/${encodeURIComponent(t.id)}`,t):e("POST","",t),remove:t=>e("DELETE",`/${encodeURIComponent(t.id)}`).then(()=>{})}}var l=class extends f{baseCls="op-viewmanager";btn;menu;views=[];current;initial={};build(){return this.btn=new w({text:n("views"),icon:"menu",variant:"ghost",handler:()=>this.openMenu()}),this.btn.el.setAttribute("aria-haspopup","menu"),this.own(()=>(this.btn.destroy(),this.menu?.destroy())),u("span",this.baseCls,{},this.btn.el)}onRender(){this.config.grid.render(),this.config.filters?.render(),this.initial=this.getState(),this.config.autoLoad!==!1&&this.reload()}notifyMount(){super.notifyMount(),this.btn.notifyMount()}getState(){let{grid:e,filters:t,extra:i}=this.config,s={columns:e.getColumnState(),filter:t?.getFilter()??null,sorters:[...e.getStore().getSorters()]};return i&&(s.extra=Object.fromEntries(Object.entries(i).map(([r,o])=>[r,o.get()]))),s}setState(e){let{grid:t,filters:i,extra:s}=this.config;e.columns&&t.setColumnState(e.columns);let r=e.sorters?.[0];t.getStore().sort(r?.field??null,r?.dir),i&&(i.setFilter(e.filter??null),i.apply());for(let o in e.extra)s?.[o]?.set(e.extra[o])}getViews(){return this.views}getCurrent(){return this.current}async reload(){await this.run(async()=>{this.views=await this.config.storage.list()??[],this.current=this.current&&this.views.find(t=>t.id===this.current.id);let e=this.views.find(t=>t.default);!this.current&&e&&this.config.autoLoad!==!1&&this.apply(e),this.paint()}),this.emit("load",this.views)}apply(e){let t=typeof e=="string"?this.views.find(i=>i.id===e):e;!t||this.emit("before-apply",t)===!1||(this.current=t,this.setState(t.state),this.paint(),this.emit("apply",t))}async save(){if(!this.current)return this.saveAs();await this.store({...this.current,state:this.getState()})}async saveAs(e){if(e??=await v.prompt(n("viewsName"),{title:n("viewsSaveAs")})??"",e=e.trim(),!e)return;let t=this.views.find(i=>i.name.toLowerCase()===e.toLowerCase());await this.store({...t,name:e,state:this.getState()})}async setDefault(e=!0){if(this.current){for(let t of this.views)t!==this.current&&t.default&&await this.store({...t,default:!1},!1);await this.store({...this.current,default:e})}}async remove(e=this.current){!e||!await v.confirm(n("viewsConfirmDelete",{n:e.name}),{danger:!0,okText:n("viewsDelete")})||await this.run(async()=>{await this.config.storage.remove(e),this.views=this.views.filter(t=>t!==e&&t.id!==e.id),this.current?.id===e.id&&(this.current=void 0),this.paint(),this.emit("remove",e)})}reset(){this.current=void 0,this.setState(this.initial),this.paint(),this.emit("reset")}async store(e,t=!0){await this.run(async()=>{let i=await this.config.storage.save(e)||e,s=this.views.findIndex(r=>i.id&&r.id===i.id||r===e);s<0?this.views.push(i):this.views[s]=i,t&&(this.current=i),this.paint(),this.emit("save",i)})}async run(e){try{await e()}catch(t){this.emit("error",t)}}paint(){this.btn.setText(this.current?.name??n("views"))}openMenu(){let e=this.current,t=[...this.views.map(i=>({text:i.default?`${i.name} \u2605`:i.name,checked:i===e||!!e?.id&&i.id===e.id,handler:()=>this.apply(i)})),...this.views.length?["-"]:[],{text:n("viewsSave"),handler:()=>{this.save()}},{text:n("viewsSaveAs"),handler:()=>{this.saveAs()}},...e?[{text:n("viewsDefault"),checked:!!e.default,handler:()=>{this.setDefault(!e.default)}},{text:n("viewsDelete"),handler:()=>{this.remove()}}]:[],"-",{text:n("viewsReset"),handler:()=>this.reset()}];this.menu??=new m({}),this.menu.setItems(t),this.menu.showBy(this.btn.el)}};c("viewmanager",l);export{M as a,P as b,l as c};
|
|
2
|
+
//# sourceMappingURL=chunk-UXXJOU5J.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/components/data/viewmanager/viewmanager.ts"],
|
|
4
|
+
"sourcesContent": ["import { Component, type ComponentConfig } from '../../../core/component';\nimport { register } from '../../../core/registry';\nimport { h } from '../../../core/dom';\nimport { t, 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": "+RAWAA,EAAY,KAAM,CAChB,MAAO,QACP,UAAW,qBACX,UAAW,YACX,YAAa,yBACb,aAAc,sBACd,YAAa,cACb,mBAAoB,yBACpB,WAAY,kBACd,CAAC,EACDA,EAAY,QAAS,CACnB,MAAO,YACP,UAAW,sBACX,UAAW,kBACX,YAAa,kCACb,aAAc,0BACd,YAAa,mBACb,mBAAoB,4BACpB,WAAY,mBACd,CAAC,EAyBD,IAAMC,EAAQ,IAAM,WAAW,QAAQ,aAAa,GAAK,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC,GAGtG,SAASC,EAAiBC,EAAaC,EAAmB,aAA2B,CAC1F,IAAMC,EAAO,IAAmB,CAC9B,GAAI,CACF,IAAMC,EAAI,KAAK,MAAMF,EAAQ,QAAQD,CAAG,GAAK,IAAI,EACjD,OAAO,MAAM,QAAQG,CAAC,EAAIA,EAAI,CAAC,CACjC,MAAQ,CACN,MAAO,CAAC,CACV,CACF,EACMC,EAASD,GAAmBF,EAAQ,QAAQD,EAAK,KAAK,UAAUG,CAAC,CAAC,EACxE,MAAO,CACL,KAAMD,EACN,KAAKG,EAAM,CACT,IAAMC,EAAQ,CAAE,GAAGD,EAAM,GAAIA,EAAK,IAAMP,EAAM,CAAE,EAC1CS,EAAML,EAAK,EACXM,EAAID,EAAI,UAAWE,GAAMA,EAAE,KAAOH,EAAM,EAAE,EAChD,OAAIE,EAAI,EAAGD,EAAI,KAAKD,CAAK,EACpBC,EAAIC,CAAC,EAAIF,EACdF,EAAMG,CAAG,EACFD,CACT,EACA,OAAOD,EAAM,CACXD,EAAMF,EAAK,EAAE,OAAQO,GAAMA,EAAE,KAAOJ,EAAK,EAAE,CAAC,CAC9C,CACF,CACF,CAUO,SAASK,EAAgBC,EAAyC,CACvE,IAAMC,EAAO,MAAOC,EAAgBC,EAAO,GAAIC,IAAmB,CAChE,IAAMC,EAAM,MAAOL,EAAI,OAAS,OAAOA,EAAI,IAAMG,EAAM,CAAE,OAAAD,EAAQ,QAAS,CAAE,eAAgB,mBAAoB,GAAGF,EAAI,OAAQ,EAAG,KAAMI,IAAS,OAAY,OAAY,KAAK,UAAUA,CAAI,CAAE,CAAC,EAC/L,GAAI,CAACC,EAAI,GAAI,MAAM,IAAI,MAAM,kBAAkBH,CAAM,IAAIF,EAAI,IAAMG,CAAI,WAAME,EAAI,MAAM,EAAE,EACzF,OAAOA,EAAI,SAAW,IAAM,OAAYA,EAAI,KAAK,EAAE,MAAM,IAAG,EAAY,CAC1E,EACA,MAAO,CACL,KAAM,IAAMJ,EAAK,KAAK,EACtB,KAAOT,GAAOA,EAAE,GAAKS,EAAK,MAAO,IAAI,mBAAmBT,EAAE,EAAE,CAAC,GAAIA,CAAC,EAAIS,EAAK,OAAQ,GAAIT,CAAC,EACxF,OAASA,GAAMS,EAAK,SAAU,IAAI,mBAAmBT,EAAE,EAAG,CAAC,EAAE,EAAE,KAAK,IAAG,EAAY,CACrF,CACF,CAiBO,IAAMc,EAAN,cAA0BC,CAA6B,CACzC,QAAU,iBACrB,IACA,KACA,MAAqB,CAAC,EACtB,QACA,QAAqB,CAAC,EAEX,OAAQ,CACzB,YAAK,IAAM,IAAIC,EAAO,CAAE,KAAMC,EAAE,OAAO,EAAG,KAAM,OAAQ,QAAS,QAAS,QAAS,IAAM,KAAK,SAAS,CAAE,CAAC,EAC1G,KAAK,IAAI,GAAG,aAAa,gBAAiB,MAAM,EAChD,KAAK,IAAI,KAAO,KAAK,IAAI,QAAQ,EAAG,KAAK,MAAM,QAAQ,EAAE,EAClDC,EAAE,OAAQ,KAAK,QAAS,CAAC,EAAG,KAAK,IAAI,EAAE,CAChD,CAEmB,UAAW,CAC5B,KAAK,OAAO,KAAK,OAAO,EACxB,KAAK,OAAO,SAAS,OAAO,EAC5B,KAAK,QAAU,KAAK,SAAS,EACzB,KAAK,OAAO,WAAa,IAAY,KAAK,OAAO,CACvD,CAES,aAAc,CACrB,MAAM,YAAY,EAClB,KAAK,IAAI,YAAY,CACvB,CAKA,UAAsB,CACpB,GAAM,CAAE,KAAAC,EAAM,QAAAC,EAAS,MAAAC,CAAM,EAAI,KAAK,OAChCC,EAAmB,CAAE,QAASH,EAAK,eAAe,EAAG,OAAQC,GAAS,UAAU,GAAK,KAAM,QAAS,CAAC,GAAGD,EAAK,SAAS,EAAE,WAAW,CAAC,CAAE,EAC5I,OAAIE,IAAOC,EAAM,MAAQ,OAAO,YAAY,OAAO,QAAQD,CAAK,EAAE,IAAI,CAAC,CAACE,EAAGC,CAAC,IAAM,CAACD,EAAGC,EAAE,IAAI,CAAC,CAAC,CAAC,GACxFF,CACT,CAGA,SAASG,EAAoB,CAC3B,GAAM,CAAE,KAAAN,EAAM,QAAAC,EAAS,MAAAC,CAAM,EAAI,KAAK,OAClCI,EAAE,SAASN,EAAK,eAAeM,EAAE,OAAO,EAC5C,IAAMC,EAAOD,EAAE,UAAU,CAAC,EAC1BN,EAAK,SAAS,EAAE,KAAKO,GAAM,OAAS,KAAMA,GAAM,GAAG,EAC/CN,IACFA,EAAQ,UAAUK,EAAE,QAAU,IAAI,EAClCL,EAAQ,MAAM,GAEhB,QAAWG,KAAKE,EAAE,MAAOJ,IAAQE,CAAC,GAAG,IAAIE,EAAE,MAAMF,CAAC,CAAC,CACrD,CAIA,UAAwB,CACtB,OAAO,KAAK,KACd,CACA,YAAoC,CAClC,OAAO,KAAK,OACd,CAGA,MAAM,QAAwB,CAC5B,MAAM,KAAK,IAAI,SAAY,CACzB,KAAK,MAAS,MAAM,KAAK,OAAO,QAAQ,KAAK,GAAM,CAAC,EACpD,KAAK,QAAU,KAAK,SAAW,KAAK,MAAM,KAAMvB,GAAMA,EAAE,KAAO,KAAK,QAAS,EAAE,EAC/E,IAAM2B,EAAM,KAAK,MAAM,KAAM3B,GAAMA,EAAE,OAAO,EACxC,CAAC,KAAK,SAAW2B,GAAO,KAAK,OAAO,WAAa,IAAO,KAAK,MAAMA,CAAG,EAC1E,KAAK,MAAM,CACb,CAAC,EACD,KAAK,KAAK,OAAQ,KAAK,KAAK,CAC9B,CAGA,MAAMzB,EAAgC,CACpC,IAAMF,EAAI,OAAOE,GAAS,SAAW,KAAK,MAAM,KAAMI,GAAMA,EAAE,KAAOJ,CAAI,EAAIA,EACzE,CAACF,GAAK,KAAK,KAAK,eAAgBA,CAAC,IAAM,KAC3C,KAAK,QAAUA,EACf,KAAK,SAASA,EAAE,KAAK,EACrB,KAAK,MAAM,EACX,KAAK,KAAK,QAASA,CAAC,EACtB,CAGA,MAAM,MAAsB,CAC1B,GAAI,CAAC,KAAK,QAAS,OAAO,KAAK,OAAO,EACtC,MAAM,KAAK,MAAM,CAAE,GAAG,KAAK,QAAS,MAAO,KAAK,SAAS,CAAE,CAAC,CAC9D,CAGA,MAAM,OAAO4B,EAA8B,CAGzC,GAFAA,IAAU,MAAMC,EAAW,OAAOZ,EAAE,WAAW,EAAG,CAAE,MAAOA,EAAE,aAAa,CAAE,CAAC,GAAM,GACnFW,EAAOA,EAAK,KAAK,EACb,CAACA,EAAM,OACX,IAAME,EAAO,KAAK,MAAM,KAAM9B,GAAMA,EAAE,KAAK,YAAY,IAAM4B,EAAM,YAAY,CAAC,EAChF,MAAM,KAAK,MAAM,CAAE,GAAGE,EAAM,KAAAF,EAAM,MAAO,KAAK,SAAS,CAAE,CAAC,CAC5D,CAGA,MAAM,WAAWG,EAAK,GAAqB,CACzC,GAAK,KAAK,QACV,SAAW/B,KAAK,KAAK,MAAWA,IAAM,KAAK,SAAWA,EAAE,SAAS,MAAM,KAAK,MAAM,CAAE,GAAGA,EAAG,QAAS,EAAM,EAAG,EAAK,EACjH,MAAM,KAAK,MAAM,CAAE,GAAG,KAAK,QAAS,QAAS+B,CAAG,CAAC,EACnD,CAEA,MAAM,OAAO7B,EAAO,KAAK,QAAwB,CAC3C,CAACA,GAAQ,CAAE,MAAM2B,EAAW,QAAQZ,EAAE,qBAAsB,CAAE,EAAGf,EAAK,IAAK,CAAC,EAAG,CAAE,OAAQ,GAAM,OAAQe,EAAE,aAAa,CAAE,CAAC,GAC7H,MAAM,KAAK,IAAI,SAAY,CACzB,MAAM,KAAK,OAAO,QAAQ,OAAOf,CAAI,EACrC,KAAK,MAAQ,KAAK,MAAM,OAAQF,GAAMA,IAAME,GAAQF,EAAE,KAAOE,EAAK,EAAE,EAChE,KAAK,SAAS,KAAOA,EAAK,KAAI,KAAK,QAAU,QACjD,KAAK,MAAM,EACX,KAAK,KAAK,SAAUA,CAAI,CAC1B,CAAC,CACH,CAGA,OAAc,CACZ,KAAK,QAAU,OACf,KAAK,SAAS,KAAK,OAAO,EAC1B,KAAK,MAAM,EACX,KAAK,KAAK,OAAO,CACnB,CAEA,MAAc,MAAMA,EAAiB8B,EAAc,GAAqB,CACtE,MAAM,KAAK,IAAI,SAAY,CACzB,IAAM7B,EAAS,MAAM,KAAK,OAAO,QAAQ,KAAKD,CAAI,GAAMA,EAClDG,EAAI,KAAK,MAAM,UAAWL,GAAOG,EAAM,IAAMH,EAAE,KAAOG,EAAM,IAAOH,IAAME,CAAI,EAC/EG,EAAI,EAAG,KAAK,MAAM,KAAKF,CAAK,EAC3B,KAAK,MAAME,CAAC,EAAIF,EACjB6B,IAAa,KAAK,QAAU7B,GAChC,KAAK,MAAM,EACX,KAAK,KAAK,OAAQA,CAAK,CACzB,CAAC,CACH,CAEA,MAAc,IAAI8B,EAAwC,CACxD,GAAI,CACF,MAAMA,EAAG,CACX,OAASC,EAAK,CACZ,KAAK,KAAK,QAASA,CAAG,CACxB,CACF,CAIQ,OAAc,CACpB,KAAK,IAAI,QAAQ,KAAK,SAAS,MAAQjB,EAAE,OAAO,CAAC,CACnD,CAEQ,UAAiB,CACvB,IAAMkB,EAAM,KAAK,QACXC,EAAqB,CACzB,GAAG,KAAK,MAAM,IAAKpC,IAAO,CAAE,KAAMA,EAAE,QAAU,GAAGA,EAAE,IAAI,UAAOA,EAAE,KAAM,QAASA,IAAMmC,GAAQ,CAAC,CAACA,GAAK,IAAMnC,EAAE,KAAOmC,EAAI,GAAK,QAAS,IAAM,KAAK,MAAMnC,CAAC,CAAE,EAAE,EAC3J,GAAI,KAAK,MAAM,OAAU,CAAC,GAAG,EAAc,CAAC,EAC5C,CAAE,KAAMiB,EAAE,WAAW,EAAG,QAAS,IAAG,CAAQ,KAAK,KAAK,EAAE,EACxD,CAAE,KAAMA,EAAE,aAAa,EAAG,QAAS,IAAG,CAAQ,KAAK,OAAO,EAAE,EAC5D,GAAIkB,EAAM,CAAC,CAAE,KAAMlB,EAAE,cAAc,EAAG,QAAS,CAAC,CAACkB,EAAI,QAAS,QAAS,IAAG,CAAQ,KAAK,WAAW,CAACA,EAAI,OAAO,EAAE,EAAG,CAAE,KAAMlB,EAAE,aAAa,EAAG,QAAS,IAAG,CAAQ,KAAK,OAAO,EAAE,CAAC,EAAI,CAAC,EACrL,IACA,CAAE,KAAMA,EAAE,YAAY,EAAG,QAAS,IAAM,KAAK,MAAM,CAAE,CACvD,EACA,KAAK,OAAS,IAAIoB,EAAK,CAAC,CAAC,EACzB,KAAK,KAAK,SAASD,CAAK,EACxB,KAAK,KAAK,OAAO,KAAK,IAAI,EAAE,CAC9B,CACF,EACAE,EAAS,cAAexB,CAAW",
|
|
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 a}from"./chunk-ZWNQREWS.js";import{a as o}from"./chunk-2ZRNGG2N.js";import{e as c}from"./chunk-PZSHOSOS.js";import{a as h}from"./chunk-TIPK3SCJ.js";var y=(n,e)=>e.split(".").reduce((t,i)=>t?.[i],n);function u(n,e,t){let i=e.split("."),s=i.pop(),r=i.reduce((l,d)=>l[d]??={},n);r[s]=t}var f=class extends a{baseCls="op-form";tag="form";ruledOut=new Set;dirty=!1;constructor(e={}){let t=[...e.items??[]];e.tabs&&t.push({type:"tabs",flex:1,items:e.tabs.map(i=>({type:"container",title:i.title,icon:i.icon,cls:"op-form__tab",layout:i.layout??{type:"grid",columns:2,gap:12},items:i.items}))}),super({...e,items:t})}build(){let e=super.build();return e.setAttribute("novalidate",""),e}onRender(){if(this.config.layout??=this.config.columns?{type:"grid",columns:this.config.columns}:{type:"vbox"},this.config.labelWidth!=null&&this.setLabelWidth(this.config.labelWidth),this.config.labelPos)for(let e of this.getFields())e.config.labelPos??=this.config.labelPos;super.onRender(),this.config.readonly&&this.setReadonly(!0);for(let e of this.getFields())for(let t of["invalid","valid","dirty-change","change"])e.on(t,()=>this.syncTabs());for(let e of this.getFields())e.on("change",()=>this.changed());for(let e of this.getFields())e.on("dirty-change",()=>this.changed());this.applyRules(),this.listen(this.el,"submit",e=>{e.preventDefault(),this.submit()}),this.listen(this.el,"keydown",e=>{let t=e.target;e.key==="Enter"&&t instanceof HTMLInputElement&&!e.defaultPrevented&&t.type!=="button"&&(e.preventDefault(),this.submit())})}getFields(){return this.query(e=>e instanceof o)}getField(e){return this.getFields().find(t=>t.name===e)}getValues(e={}){let t={};for(let i of this.counted())i.name&&(!e.dirtyOnly||i.isDirty())&&u(t,i.name,i.getValue());return t}counted(){return this.getFields().filter(e=>{for(let t=e;t&&t!==this;t=t.parent)if(this.ruledOut.has(t))return!1;return!0})}changed(){this.applyRules();let e=this.isDirty();e!==this.dirty&&this.emit("dirty-change",this.dirty=e)}applyRules(){let e={};for(let t of this.getFields())t.name&&u(e,t.name,t.getValue());for(let t of this.query(i=>!!(i.config.showIf||i.config.enableIf))){let{showIf:i,enableIf:s}=t.config;if(i){let r=!!i(e);if(r===this.ruledOut.has(t))if(r)this.ruledOut.delete(t),t.show();else{this.ruledOut.add(t),t.hide();for(let l of t instanceof o?[t]:t instanceof a?t.query(d=>d instanceof o):[])l.clearError()}}s&&t.setDisabled(!s(e))}}focusField(e){this.reveal(e),e.focus()}setValues(e){for(let t of this.getFields()){let i=t.name?y(e,t.name):void 0;i!==void 0&&t.setValue(i,!0)}}load(e){this.setValues("data"in e&&"get"in e?e.data:e),this.markClean(),this.clearErrors(),this.emit("load",e)}reveal(e){let t=e;for(;t.parent;){let i=t.parent;i.items?.includes(t)&&(typeof i.setActive=="function"?i.setActive(t):i.layout?.activate&&i.layout.activate(i,t)),t=i}}syncTabs(){for(let e of this.query(t=>typeof t.setTabState=="function"))for(let t of e.items){let i=t instanceof a?t.query(s=>s instanceof o):[];e.setTabState(t,{errors:i.filter(s=>s.getError()).length,dirty:i.some(s=>s.isDirty())})}}updateRecord(e){let t=this.getValues(),i=new Set(this.getFields().filter(s=>s.name&&s.isDirty()).map(s=>s.name.split(".")[0]));for(let s of i)e.set(s,t[s])}markClean(){this.getFields().forEach(e=>e.markClean()),this.syncTabs()}reset(){this.getFields().forEach(e=>e.reset()),this.syncTabs()}isDirty(){return this.getFields().some(e=>e.isDirty())}isValid(){return this.counted().every(e=>e.config.disabled||e.isValid())}clearErrors(){this.getFields().forEach(e=>e.clearError()),this.syncTabs()}validate(){let e=this.counted().filter(i=>!i.config.disabled);for(let i of this.getFields())e.includes(i)||i.clearError();let t=e.filter(i=>!i.validate());return this.syncTabs(),t.length&&(this.reveal(t[0]),t[0].focus(),this.emit("invalid",t)),this.el.classList.toggle("is-invalid",!!t.length),!t.length}submit(){return this.emit("before-submit")===!1||!this.validate()?!1:(this.emit("submit",this.getValues()),!0)}setLabelWidth(e){this.config.labelWidth=e,this.rendered&&this.el.style.setProperty("--op-field-label-width",c(e))}setReadonly(e){this.config.readonly=e,this.getFields().forEach(t=>t.setReadonly(e))}};h("form",f);export{f as a};
|
|
2
|
+
//# sourceMappingURL=chunk-VU3GIDZ3.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/components/form/form/form.ts"],
|
|
4
|
+
"sourcesContent": ["import { Container, type ContainerConfig } from '../../../core/container';\nimport { Field } from '../../../core/field';\nimport { register } from '../../../core/registry';\nimport type { Model } from '../../../data/model';\nimport type { Component } from '../../../core/component';\nimport type { LayoutSpec } from '../../../layout/layout';\nimport { px } from '../../../core/dom';\n\nexport interface FormTab {\n title: string;\n icon?: string;\n items: ContainerConfig['items'];\n /** Default: two columns (one on a phone). */\n layout?: LayoutSpec;\n}\n\nexport interface FormConfig extends ContainerConfig {\n /** Shortcut: the fields in tabs, still one form (one `getValues`, one `validate`, one dirty). */\n tabs?: FormTab[];\n /** Default `labelPos` for fields that do not set their own. */\n labelPos?: 'top' | 'left';\n /** Width of the labels on the left (`labelPos: 'left'`), so they line up in a column. Number = px. */\n labelWidth?: number | string;\n /** Shortcut for a responsive grid layout (one column on narrow screens); items take `colspan` (a number or `'full'`). */\n columns?: number;\n readonly?: boolean;\n}\n\nconst getPath = (o: any, path: string) => path.split('.').reduce((v, k) => v?.[k], o);\nfunction setPath(o: any, path: string, value: unknown) {\n const keys = path.split('.');\n const last = keys.pop()!;\n const target = keys.reduce((v, k) => (v[k] ??= {}), o);\n target[last] = value;\n}\n\nexport class Form extends Container<FormConfig> {\n protected override baseCls = 'op-form';\n protected override tag = 'form' as const;\n /** Components hidden by their `showIf` rule: their fields do not count (no validation, not in `getValues`). */\n private ruledOut = new Set<Component>();\n private dirty = false;\n\n constructor(config: FormConfig = {}) {\n const items = [...(config.items ?? [])];\n if (config.tabs) {\n items.push({\n type: 'tabs',\n flex: 1,\n items: config.tabs.map((t) => ({ type: 'container', title: t.title, icon: t.icon, cls: 'op-form__tab', layout: t.layout ?? { type: 'grid', columns: 2, gap: 12 }, items: t.items })),\n } as never);\n }\n super({ ...config, items });\n }\n\n protected override build() {\n const el = super.build();\n el.setAttribute('novalidate', '');\n return el;\n }\n\n protected override onRender() {\n this.config.layout ??= this.config.columns ? { type: 'grid', columns: this.config.columns } : { type: 'vbox' };\n if (this.config.labelWidth != null) this.setLabelWidth(this.config.labelWidth);\n if (this.config.labelPos) for (const f of this.getFields()) f.config.labelPos ??= this.config.labelPos;\n super.onRender();\n if (this.config.readonly) this.setReadonly(true);\n for (const f of this.getFields()) for (const ev of ['invalid', 'valid', 'dirty-change', 'change']) f.on(ev, () => this.syncTabs());\n for (const f of this.getFields()) f.on('change', () => this.changed());\n for (const f of this.getFields()) f.on('dirty-change', () => this.changed());\n this.applyRules();\n // Native submit (a `type=submit` button) and Enter inside a single-line field both go through submit().\n this.listen(this.el, 'submit', (e: Event) => {\n e.preventDefault();\n this.submit();\n });\n this.listen(this.el, 'keydown', (e: KeyboardEvent) => {\n const t = e.target as HTMLElement;\n if (e.key === 'Enter' && t instanceof HTMLInputElement && !e.defaultPrevented && t.type !== 'button') {\n e.preventDefault();\n this.submit();\n }\n });\n }\n\n getFields(): Field<any>[] {\n return this.query((c) => c instanceof Field) as Field<any>[];\n }\n\n getField(name: string): Field<any> | undefined {\n return this.getFields().find((f) => f.name === name);\n }\n\n /** Nested object built from field names (`address.city` \u2192 `{ address: { city } }`). Fields hidden by `showIf` are left out. */\n getValues(opts: { dirtyOnly?: boolean } = {}): Record<string, any> {\n const out: Record<string, any> = {};\n for (const f of this.counted()) if (f.name && (!opts.dirtyOnly || f.isDirty())) setPath(out, f.name, f.getValue());\n return out;\n }\n\n /** The fields that count: not inside something its `showIf` rule hid. */\n private counted(): Field<any>[] {\n return this.getFields().filter((f) => {\n for (let c: Component | undefined = f; c && c !== this; c = c.parent as Component | undefined) if (this.ruledOut.has(c)) return false;\n return true;\n });\n }\n\n /** A field changed: rerun the `showIf`/`enableIf` rules and say when the form as a whole became (un)changed. */\n private changed(): void {\n this.applyRules();\n const d = this.isDirty();\n if (d !== this.dirty) this.emit('dirty-change', (this.dirty = d));\n }\n\n /** Shows/hides and enables/disables every item that has a rule, from the current values (hidden fields included). */\n applyRules(): void {\n const values: Record<string, any> = {};\n for (const f of this.getFields()) if (f.name) setPath(values, f.name, f.getValue());\n for (const c of this.query((x) => !!(x.config.showIf || x.config.enableIf))) {\n const { showIf, enableIf } = c.config;\n if (showIf) {\n const show = !!showIf(values);\n if (show === this.ruledOut.has(c)) {\n if (show) (this.ruledOut.delete(c), c.show());\n else {\n this.ruledOut.add(c);\n c.hide();\n // what nobody can see has nothing to fix: its errors go with it\n for (const f of c instanceof Field ? [c] : c instanceof Container ? (c.query((x) => x instanceof Field) as Field<any>[]) : []) f.clearError();\n }\n }\n }\n if (enableIf) c.setDisabled(!enableIf(values));\n }\n }\n\n /** Brings a field into view (opening its tab or step) and focuses it. */\n focusField(field: Field<any>): void {\n this.reveal(field);\n field.focus();\n }\n\n /** Sets the fields present in `values` (silently). */\n setValues(values: Record<string, any>): void {\n for (const f of this.getFields()) {\n const v = f.name ? getPath(values, f.name) : undefined;\n if (v !== undefined) f.setValue(v, true);\n }\n }\n\n /** Fills the form from a plain object or a Model, and makes it the \"clean\" state. */\n load(record: Record<string, any> | Model): void {\n this.setValues('data' in record && 'get' in record ? (record as Model).data : record);\n this.markClean();\n this.clearErrors();\n this.emit('load', record);\n }\n\n /** Brings a field into view: asks every ancestor that shows one child at a time (Tabs, a card layout) to show the branch. */\n protected reveal(field: Component): void {\n let node: Component = field;\n while (node.parent) {\n const p = node.parent as any;\n if (p.items?.includes(node)) {\n if (typeof p.setActive === 'function') p.setActive(node);\n else if (p.layout?.activate) p.layout.activate(p, node);\n }\n node = p;\n }\n }\n\n /** Error counts and \"changed\" dots on the headers of every Tabs inside the form. */\n protected syncTabs(): void {\n for (const tabs of this.query((c) => typeof (c as any).setTabState === 'function') as any[]) {\n for (const panel of tabs.items as Component[]) {\n const fields = panel instanceof Container ? (panel.query((c) => c instanceof Field) as Field<any>[]) : [];\n tabs.setTabState(panel, { errors: fields.filter((f) => f.getError()).length, dirty: fields.some((f) => f.isDirty()) });\n }\n }\n }\n\n /** Writes the changed fields back into a Model. */\n updateRecord(model: Model): void {\n const all = this.getValues();\n const keys = new Set(this.getFields().filter((f) => f.name && f.isDirty()).map((f) => f.name!.split('.')[0]));\n for (const k of keys) model.set(k, all[k]);\n }\n\n markClean(): void {\n this.getFields().forEach((f) => f.markClean());\n this.syncTabs();\n }\n reset(): void {\n this.getFields().forEach((f) => f.reset());\n this.syncTabs();\n }\n isDirty(): boolean {\n return this.getFields().some((f) => f.isDirty());\n }\n isValid(): boolean {\n return this.counted().every((f) => f.config.disabled || f.isValid());\n }\n clearErrors(): void {\n this.getFields().forEach((f) => f.clearError());\n this.syncTabs();\n }\n\n /** Validates every field that counts (marks errors) and focuses the first invalid one. */\n validate(): boolean {\n // a hidden or disabled field is not validated: the user could not fix it\n const counted = this.counted().filter((f) => !f.config.disabled);\n for (const f of this.getFields()) if (!counted.includes(f)) f.clearError();\n const bad = counted.filter((f) => !f.validate());\n this.syncTabs();\n if (bad.length) {\n this.reveal(bad[0]); // the tab / step that holds it comes forward first\n bad[0].focus();\n this.emit('invalid', bad);\n }\n this.el.classList.toggle('is-invalid', !!bad.length);\n return !bad.length;\n }\n\n submit(): boolean {\n if (this.emit('before-submit') === false) return false;\n if (!this.validate()) return false;\n this.emit('submit', this.getValues());\n return true;\n }\n\n /** Width of the labels on the left (number = px); they line up in a column. */\n setLabelWidth(width: number | string): void {\n this.config.labelWidth = width;\n if (this.rendered) this.el.style.setProperty('--op-field-label-width', px(width));\n }\n\n setReadonly(readonly: boolean): void {\n this.config.readonly = readonly;\n this.getFields().forEach((f) => f.setReadonly(readonly));\n }\n}\nregister('form', Form);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["getPath", "o", "path", "v", "k", "setPath", "value", "keys", "last", "target", "Form", "Container", "config", "items", "t", "el", "f", "ev", "c", "Field", "name", "opts", "out", "d", "values", "x", "showIf", "enableIf", "show", "field", "record", "node", "p", "tabs", "panel", "fields", "model", "all", "counted", "bad", "width", "px", "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 u}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 h}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:`${h("search")}\u2026`,"aria-label":h("search"),autocomplete:"off"}),this.emptyEl=s("div","op-menu__empty",{},h("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 a=r.checked!==void 0,l=s("div","op-menu__item",{role:a?"menuitemcheckbox":"menuitem",tabindex:-1,"data-i":o,"aria-disabled":r.disabled?"true":null,"aria-checked":a?String(!!r.checked):null,"aria-haspopup":r.items?"menu":null,"aria-expanded":r.items?"false":null});return l.append(s("span","op-menu__icon",{},r.icon?u(r.icon):a&&r.checked?u("check"):null),s("span","op-menu__text",{},r.text??"")),r.badge!=null&&r.badge!==""&&l.append(s("span","op-menu__badge",{},String(r.badge))),r.items&&l.append(s("span","op-menu__arrow",{},u("chevron-right"))),l}),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,a)=>i(a)===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-W2BAFOCN.js.map
|