@ui-sdk/web 0.0.0-stage → 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +10 -2
- package/browser/web/accordion.js +1 -0
- package/browser/web/alert-dialog.js +1 -0
- package/browser/web/autocomplete.js +1 -0
- package/browser/web/avatar.js +1 -0
- package/browser/web/button.js +1 -0
- package/browser/web/calendar.js +1 -0
- package/browser/web/carousel.js +1 -0
- package/browser/web/checkbox.js +1 -0
- package/browser/web/chunks/0eRGibL6.js +1 -0
- package/browser/web/chunks/2bIEUO6_.js +1 -0
- package/browser/web/chunks/5A9w2ULz.js +1 -0
- package/browser/web/chunks/5RSyydjV.js +1 -0
- package/browser/web/chunks/9pWTy2wl.js +1 -0
- package/browser/web/chunks/B0f2j6zz.js +1 -0
- package/browser/web/chunks/B1rux6br.js +1 -0
- package/browser/web/chunks/B3-APaNf.js +1 -0
- package/browser/web/chunks/B7EgSgjQ.js +1 -0
- package/browser/web/chunks/B8QcOzJU.js +1 -0
- package/browser/web/chunks/BFueEkwm.js +3 -0
- package/browser/web/chunks/BJj3oS29.js +1 -0
- package/browser/web/chunks/BNSvTCpr.js +1 -0
- package/browser/web/chunks/BPD0kAZB.js +1 -0
- package/browser/web/chunks/BQeduZqT.js +1 -0
- package/browser/web/chunks/B_CVFyiz.js +1 -0
- package/browser/web/chunks/B_ns1YHO.js +1 -0
- package/browser/web/chunks/BcwkVTsR.js +1 -0
- package/browser/web/chunks/BeaQ6TYM.js +1 -0
- package/browser/web/chunks/BgBB013u.js +1 -0
- package/browser/web/chunks/BgsKhHDm.js +1 -0
- package/browser/web/chunks/BjMcbuhi.js +9 -0
- package/browser/web/chunks/Bjiy_F2N.js +1 -0
- package/browser/web/chunks/BqScCLwv.js +1 -0
- package/browser/web/chunks/BqX3Utqx.js +1 -0
- package/browser/web/chunks/BtVkQf3z.js +1 -0
- package/browser/web/chunks/By30h-7B.js +1 -0
- package/browser/web/chunks/C1zqYpy2.js +1 -0
- package/browser/web/chunks/C436juFf.js +1 -0
- package/browser/web/chunks/C4_bULs1.js +1 -0
- package/browser/web/chunks/C4omqJEz.js +1 -0
- package/browser/web/chunks/C7tt0T3n.js +1 -0
- package/browser/web/chunks/C8w7s5dg.js +1 -0
- package/browser/web/chunks/CElY4erO.js +1 -0
- package/browser/web/chunks/CFODo-m2.js +1 -0
- package/browser/web/chunks/CL4wjam9.js +1 -0
- package/browser/web/chunks/CMg-8UVf.js +1 -0
- package/browser/web/chunks/COWKfakj.js +1 -0
- package/browser/web/chunks/CQBU0qZ4.js +1 -0
- package/browser/web/chunks/CV6uABgc.js +1 -0
- package/browser/web/chunks/C_SWFpWQ.js +1 -0
- package/browser/web/chunks/C_Uanbrl.js +1 -0
- package/browser/web/chunks/Ce_CSanC.js +1 -0
- package/browser/web/chunks/Cg-ZmRhS.js +1 -0
- package/browser/web/chunks/Cgf2wPI_.js +1 -0
- package/browser/web/chunks/Cuep_3Vf.js +1 -0
- package/browser/web/chunks/D02PaHn6.js +1 -0
- package/browser/web/chunks/D5LiaI5R.js +1 -0
- package/browser/web/chunks/D9UgVYvF.js +1 -0
- package/browser/web/chunks/DC08tnkE.js +2 -0
- package/browser/web/chunks/DG8YGSvu.js +1 -0
- package/browser/web/chunks/DIQd0FYD.js +1 -0
- package/browser/web/chunks/DMLqacE8.js +1 -0
- package/browser/web/chunks/DSUI3yI-.js +1 -0
- package/browser/web/chunks/DT3Hb76X.js +1 -0
- package/browser/web/chunks/DY75g3-W.js +1 -0
- package/browser/web/chunks/DZpNQKZ9.js +1 -0
- package/browser/web/chunks/Db-W1wrC.js +1 -0
- package/browser/web/chunks/Dc1xK3Ii.js +1 -0
- package/browser/web/chunks/DdF6awFs.js +1 -0
- package/browser/web/chunks/DdaCLml8.js +1 -0
- package/browser/web/chunks/Dh8MLjQO.js +1 -0
- package/browser/web/chunks/DiuslJRy.js +1 -0
- package/browser/web/chunks/DjRcw3Y0.js +1 -0
- package/browser/web/chunks/Djdv-16J.js +1 -0
- package/browser/web/chunks/DnFXe_lF.js +1 -0
- package/browser/web/chunks/DneGv1oC.js +1 -0
- package/browser/web/chunks/DsVxP-p-.js +1 -0
- package/browser/web/chunks/DwDilCo2.js +1 -0
- package/browser/web/chunks/DwV48AXv.js +1 -0
- package/browser/web/chunks/F37aF4-L.js +1 -0
- package/browser/web/chunks/LyB6XIbN.js +1 -0
- package/browser/web/chunks/NKnbYGjC.js +1 -0
- package/browser/web/chunks/Vk-rVi16.js +1 -0
- package/browser/web/chunks/XsM0J1Ex.js +1 -0
- package/browser/web/chunks/asSN9iEp.js +1 -0
- package/browser/web/chunks/c-AjHfdF.js +1 -0
- package/browser/web/chunks/dR-12TPY.js +1 -0
- package/browser/web/chunks/hR4xM0EC.js +1 -0
- package/browser/web/chunks/hqOaBxAg.js +1 -0
- package/browser/web/chunks/kMKqqeG4.js +1 -0
- package/browser/web/chunks/kXboBcfi.js +1 -0
- package/browser/web/chunks/l4aQIg22.js +1 -0
- package/browser/web/chunks/tJC0JSU4.js +1 -0
- package/browser/web/chunks/wHdS_QYM.js +1 -0
- package/browser/web/chunks/yv8dTvNI.js +1 -0
- package/browser/web/chunks/yw9M3nfi.js +1 -0
- package/browser/web/collapsible.js +1 -0
- package/browser/web/color-picker.js +1 -0
- package/browser/web/combobox.js +2 -0
- package/browser/web/command.js +1 -0
- package/browser/web/core.js +5 -0
- package/browser/web/date-input.js +1 -0
- package/browser/web/date-picker.js +1 -0
- package/browser/web/dialog.js +1 -0
- package/browser/web/drawer.js +1 -0
- package/browser/web/field.js +1 -0
- package/browser/web/file-input.js +1 -0
- package/browser/web/hover-card.js +1 -0
- package/browser/web/image-cropper.js +1 -0
- package/browser/web/input.js +1 -0
- package/browser/web/label.js +1 -0
- package/browser/web/listbox.js +1 -0
- package/browser/web/menu.js +1 -0
- package/browser/web/menubar.js +1 -0
- package/browser/web/meter.js +1 -0
- package/browser/web/navigation-menu.js +1 -0
- package/browser/web/number-input.js +1 -0
- package/browser/web/otp-input.js +2 -0
- package/browser/web/overlays.js +1 -0
- package/browser/web/pagination.js +1 -0
- package/browser/web/password-input.js +1 -0
- package/browser/web/popover.js +1 -0
- package/browser/web/preferences.js +1 -0
- package/browser/web/progress.js +1 -0
- package/browser/web/radio.js +1 -0
- package/browser/web/rating.js +1 -0
- package/browser/web/resizable.js +1 -0
- package/browser/web/scroll-area.js +1 -0
- package/browser/web/segmented-control.js +1 -0
- package/browser/web/select.js +1 -0
- package/browser/web/separator.js +1 -0
- package/browser/web/slider.js +1 -0
- package/browser/web/switch.js +1 -0
- package/browser/web/tabs.js +1 -0
- package/browser/web/textarea.js +1 -0
- package/browser/web/time-input.js +1 -0
- package/browser/web/timeline.js +1 -0
- package/browser/web/toast.js +1 -0
- package/browser/web/toggle.js +1 -0
- package/browser/web/token-input.js +8 -0
- package/browser/web/toolbar.js +1 -0
- package/browser/web/tooltip.js +1 -0
- package/browser/web/tree.js +1 -0
- package/browser/web/trigger-menu.js +4 -0
- package/browser/web/waterfall.js +1 -0
- package/browser/web.css +3378 -0
- package/browser/web.js +3 -0
- package/custom-elements.json +32315 -0
- package/dist/accordion.d.ts +2 -0
- package/dist/accordion.js +57 -0
- package/dist/action.d.ts +16 -0
- package/dist/action.js +39 -0
- package/dist/agent.d.ts +2 -0
- package/dist/agent.js +7 -0
- package/dist/autocomplete.d.ts +2 -0
- package/dist/autocomplete.js +120 -0
- package/dist/autoload.d.ts +18 -0
- package/dist/autoload.js +63 -0
- package/dist/avatar.d.ts +2 -0
- package/dist/avatar.js +27 -0
- package/dist/browser-core.d.ts +2 -0
- package/dist/browser-core.js +8 -0
- package/dist/button.d.ts +2 -0
- package/dist/button.js +35 -0
- package/dist/calendar.d.ts +23 -0
- package/dist/calendar.js +429 -0
- package/dist/carousel.d.ts +2 -0
- package/dist/carousel.js +54 -0
- package/dist/checkbox.d.ts +4 -0
- package/dist/checkbox.js +75 -0
- package/dist/collapsible.d.ts +2 -0
- package/dist/collapsible.js +28 -0
- package/dist/color-picker.d.ts +2 -0
- package/dist/color-picker.js +64 -0
- package/dist/combobox.d.ts +2 -0
- package/dist/combobox.js +334 -0
- package/dist/command.d.ts +2 -0
- package/dist/command.js +122 -0
- package/dist/date-input.d.ts +3 -0
- package/dist/date-input.js +87 -0
- package/dist/date-picker.d.ts +2 -0
- package/dist/date-picker.js +174 -0
- package/dist/default-text.d.ts +3 -0
- package/dist/default-text.js +24 -0
- package/dist/define-element.d.ts +404 -0
- package/dist/define-element.js +1489 -0
- package/dist/dialog.d.ts +3 -0
- package/dist/dialog.js +94 -0
- package/dist/drawer.d.ts +2 -0
- package/dist/drawer.js +96 -0
- package/dist/entries/accordion.d.ts +3 -0
- package/dist/entries/accordion.js +7 -0
- package/dist/entries/alert-dialog.d.ts +3 -0
- package/dist/entries/alert-dialog.js +13 -0
- package/dist/entries/autocomplete.d.ts +3 -0
- package/dist/entries/autocomplete.js +7 -0
- package/dist/entries/avatar.d.ts +2 -0
- package/dist/entries/avatar.js +3 -0
- package/dist/entries/button.d.ts +2 -0
- package/dist/entries/button.js +3 -0
- package/dist/entries/calendar.d.ts +3 -0
- package/dist/entries/calendar.js +7 -0
- package/dist/entries/carousel.d.ts +3 -0
- package/dist/entries/carousel.js +7 -0
- package/dist/entries/checkbox.d.ts +3 -0
- package/dist/entries/checkbox.js +15 -0
- package/dist/entries/collapsible.d.ts +3 -0
- package/dist/entries/collapsible.js +7 -0
- package/dist/entries/color-picker.d.ts +3 -0
- package/dist/entries/color-picker.js +7 -0
- package/dist/entries/combobox.d.ts +3 -0
- package/dist/entries/combobox.js +7 -0
- package/dist/entries/command.d.ts +3 -0
- package/dist/entries/command.js +7 -0
- package/dist/entries/date-input.d.ts +3 -0
- package/dist/entries/date-input.js +7 -0
- package/dist/entries/date-picker.d.ts +3 -0
- package/dist/entries/date-picker.js +7 -0
- package/dist/entries/dialog.d.ts +3 -0
- package/dist/entries/dialog.js +7 -0
- package/dist/entries/drawer.d.ts +3 -0
- package/dist/entries/drawer.js +8 -0
- package/dist/entries/field.d.ts +2 -0
- package/dist/entries/field.js +3 -0
- package/dist/entries/file-input.d.ts +3 -0
- package/dist/entries/file-input.js +13 -0
- package/dist/entries/hover-card.d.ts +3 -0
- package/dist/entries/hover-card.js +7 -0
- package/dist/entries/image-cropper.d.ts +3 -0
- package/dist/entries/image-cropper.js +7 -0
- package/dist/entries/input.d.ts +3 -0
- package/dist/entries/input.js +8 -0
- package/dist/entries/label.d.ts +2 -0
- package/dist/entries/label.js +3 -0
- package/dist/entries/listbox.d.ts +3 -0
- package/dist/entries/listbox.js +7 -0
- package/dist/entries/menu.d.ts +3 -0
- package/dist/entries/menu.js +7 -0
- package/dist/entries/menubar.d.ts +3 -0
- package/dist/entries/menubar.js +7 -0
- package/dist/entries/meter.d.ts +2 -0
- package/dist/entries/meter.js +3 -0
- package/dist/entries/navigation-menu.d.ts +3 -0
- package/dist/entries/navigation-menu.js +7 -0
- package/dist/entries/number-input.d.ts +3 -0
- package/dist/entries/number-input.js +7 -0
- package/dist/entries/otp-input.d.ts +3 -0
- package/dist/entries/otp-input.js +7 -0
- package/dist/entries/overlays.d.ts +2 -0
- package/dist/entries/overlays.js +3 -0
- package/dist/entries/pagination.d.ts +3 -0
- package/dist/entries/pagination.js +11 -0
- package/dist/entries/password-input.d.ts +3 -0
- package/dist/entries/password-input.js +7 -0
- package/dist/entries/popover.d.ts +3 -0
- package/dist/entries/popover.js +7 -0
- package/dist/entries/preferences.d.ts +3 -0
- package/dist/entries/preferences.js +13 -0
- package/dist/entries/progress.d.ts +2 -0
- package/dist/entries/progress.js +3 -0
- package/dist/entries/radio.d.ts +3 -0
- package/dist/entries/radio.js +7 -0
- package/dist/entries/rating.d.ts +3 -0
- package/dist/entries/rating.js +8 -0
- package/dist/entries/resizable.d.ts +3 -0
- package/dist/entries/resizable.js +11 -0
- package/dist/entries/scroll-area.d.ts +3 -0
- package/dist/entries/scroll-area.js +7 -0
- package/dist/entries/segmented-control.d.ts +3 -0
- package/dist/entries/segmented-control.js +7 -0
- package/dist/entries/select.d.ts +3 -0
- package/dist/entries/select.js +7 -0
- package/dist/entries/separator.d.ts +2 -0
- package/dist/entries/separator.js +3 -0
- package/dist/entries/slider.d.ts +3 -0
- package/dist/entries/slider.js +7 -0
- package/dist/entries/switch.d.ts +3 -0
- package/dist/entries/switch.js +7 -0
- package/dist/entries/tabs.d.ts +3 -0
- package/dist/entries/tabs.js +7 -0
- package/dist/entries/textarea.d.ts +3 -0
- package/dist/entries/textarea.js +7 -0
- package/dist/entries/time-input.d.ts +3 -0
- package/dist/entries/time-input.js +7 -0
- package/dist/entries/timeline.d.ts +3 -0
- package/dist/entries/timeline.js +7 -0
- package/dist/entries/toast.d.ts +2 -0
- package/dist/entries/toast.js +3 -0
- package/dist/entries/toggle.d.ts +3 -0
- package/dist/entries/toggle.js +12 -0
- package/dist/entries/token-input.d.ts +3 -0
- package/dist/entries/token-input.js +17 -0
- package/dist/entries/toolbar.d.ts +3 -0
- package/dist/entries/toolbar.js +7 -0
- package/dist/entries/tooltip.d.ts +3 -0
- package/dist/entries/tooltip.js +7 -0
- package/dist/entries/tree.d.ts +3 -0
- package/dist/entries/tree.js +17 -0
- package/dist/entries/trigger-menu.d.ts +3 -0
- package/dist/entries/trigger-menu.js +11 -0
- package/dist/entries/waterfall.d.ts +3 -0
- package/dist/entries/waterfall.js +11 -0
- package/dist/events.d.ts +1658 -0
- package/dist/events.js +0 -0
- package/dist/field.d.ts +2 -0
- package/dist/field.js +101 -0
- package/dist/file-input.d.ts +2 -0
- package/dist/file-input.js +140 -0
- package/dist/forward-attributes.d.ts +2 -0
- package/dist/forward-attributes.js +22 -0
- package/dist/history.d.ts +2 -0
- package/dist/history.js +11 -0
- package/dist/hover-card.d.ts +2 -0
- package/dist/hover-card.js +31 -0
- package/dist/image-cropper.d.ts +2 -0
- package/dist/image-cropper.js +66 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +269 -0
- package/dist/input.d.ts +3 -0
- package/dist/input.js +69 -0
- package/dist/label.d.ts +2 -0
- package/dist/label.js +11 -0
- package/dist/list.d.ts +40 -0
- package/dist/list.js +192 -0
- package/dist/listbox.d.ts +2 -0
- package/dist/listbox.js +84 -0
- package/dist/menu.d.ts +4 -0
- package/dist/menu.js +295 -0
- package/dist/menubar.d.ts +4 -0
- package/dist/menubar.js +30 -0
- package/dist/meter.d.ts +2 -0
- package/dist/meter.js +22 -0
- package/dist/navigation-menu.d.ts +2 -0
- package/dist/navigation-menu.js +114 -0
- package/dist/number-input.d.ts +2 -0
- package/dist/number-input.js +73 -0
- package/dist/observe.d.ts +2 -0
- package/dist/observe.js +7 -0
- package/dist/otp-input.d.ts +2 -0
- package/dist/otp-input.js +72 -0
- package/dist/overlays.d.ts +13 -0
- package/dist/overlays.js +156 -0
- package/dist/pagination.d.ts +2 -0
- package/dist/pagination.js +127 -0
- package/dist/password-input.d.ts +2 -0
- package/dist/password-input.js +57 -0
- package/dist/popover.d.ts +2 -0
- package/dist/popover.js +64 -0
- package/dist/popup.d.ts +40 -0
- package/dist/popup.js +112 -0
- package/dist/preferences.d.ts +2 -0
- package/dist/preferences.js +56 -0
- package/dist/progress.d.ts +2 -0
- package/dist/progress.js +22 -0
- package/dist/radio.d.ts +2 -0
- package/dist/radio.js +33 -0
- package/dist/rating.d.ts +2 -0
- package/dist/rating.js +64 -0
- package/dist/resizable.d.ts +2 -0
- package/dist/resizable.js +42 -0
- package/dist/scroll-area.d.ts +2 -0
- package/dist/scroll-area.js +45 -0
- package/dist/segmented-control.d.ts +2 -0
- package/dist/segmented-control.js +28 -0
- package/dist/select.d.ts +2 -0
- package/dist/select.js +239 -0
- package/dist/separator.d.ts +2 -0
- package/dist/separator.js +11 -0
- package/dist/slider.d.ts +2 -0
- package/dist/slider.js +77 -0
- package/dist/tabs.d.ts +2 -0
- package/dist/tabs.js +37 -0
- package/dist/timeline.d.ts +2 -0
- package/dist/timeline.js +27 -0
- package/dist/toast.d.ts +20 -0
- package/dist/toast.js +177 -0
- package/dist/toggle.d.ts +3 -0
- package/dist/toggle.js +64 -0
- package/dist/token-input.d.ts +2 -0
- package/dist/token-input.js +103 -0
- package/dist/toolbar.d.ts +2 -0
- package/dist/toolbar.js +36 -0
- package/dist/tooltip.d.ts +2 -0
- package/dist/tooltip.js +35 -0
- package/dist/tree.d.ts +2 -0
- package/dist/tree.js +147 -0
- package/dist/trigger-menu.d.ts +2 -0
- package/dist/trigger-menu.js +133 -0
- package/dist/waterfall.d.ts +2 -0
- package/dist/waterfall.js +140 -0
- package/docs/README.md +89 -0
- package/docs/agents.md +1523 -0
- package/docs/components/accordion.md +1401 -0
- package/docs/components/alert-dialog.md +788 -0
- package/docs/components/autocomplete.md +1692 -0
- package/docs/components/avatar.md +261 -0
- package/docs/components/button.md +441 -0
- package/docs/components/calendar.md +1536 -0
- package/docs/components/carousel.md +1055 -0
- package/docs/components/checkbox.md +1045 -0
- package/docs/components/collapsible.md +535 -0
- package/docs/components/color-picker.md +651 -0
- package/docs/components/combobox.md +3274 -0
- package/docs/components/command.md +1431 -0
- package/docs/components/date-input.md +563 -0
- package/docs/components/date-picker.md +1136 -0
- package/docs/components/dialog.md +1360 -0
- package/docs/components/drawer.md +1201 -0
- package/docs/components/field.md +519 -0
- package/docs/components/file-input.md +617 -0
- package/docs/components/hover-card.md +486 -0
- package/docs/components/image-cropper.md +489 -0
- package/docs/components/input.md +327 -0
- package/docs/components/label.md +208 -0
- package/docs/components/listbox.md +1015 -0
- package/docs/components/menu.md +1212 -0
- package/docs/components/menubar.md +460 -0
- package/docs/components/meter.md +298 -0
- package/docs/components/navigation-menu.md +1573 -0
- package/docs/components/number-input.md +1087 -0
- package/docs/components/otp-input.md +558 -0
- package/docs/components/pagination.md +639 -0
- package/docs/components/password-input.md +649 -0
- package/docs/components/popover.md +1433 -0
- package/docs/components/preferences.md +243 -0
- package/docs/components/progress.md +406 -0
- package/docs/components/radio.md +855 -0
- package/docs/components/rating.md +431 -0
- package/docs/components/resizable.md +866 -0
- package/docs/components/scroll-area.md +898 -0
- package/docs/components/segmented-control.md +421 -0
- package/docs/components/select.md +1957 -0
- package/docs/components/separator.md +238 -0
- package/docs/components/slider.md +1018 -0
- package/docs/components/switch.md +583 -0
- package/docs/components/tabs.md +948 -0
- package/docs/components/textarea.md +331 -0
- package/docs/components/time-input.md +235 -0
- package/docs/components/timeline.md +622 -0
- package/docs/components/toast.md +1223 -0
- package/docs/components/toggle.md +522 -0
- package/docs/components/token-input.md +854 -0
- package/docs/components/toolbar.md +815 -0
- package/docs/components/tooltip.md +860 -0
- package/docs/components/tree.md +1243 -0
- package/docs/components/trigger-menu.md +1110 -0
- package/docs/components/waterfall.md +709 -0
- package/docs/controllers.md +66 -0
- package/docs/core.md +8027 -0
- package/docs/custom-parts.md +91 -0
- package/docs/first-component.md +88 -0
- package/docs/forms.md +125 -0
- package/docs/installation.md +141 -0
- package/docs/introduction.md +32 -0
- package/docs/lists-and-menus.md +166 -0
- package/docs/llms.txt +1566 -0
- package/docs/parts-and-composition.md +57 -0
- package/docs/popups.md +92 -0
- package/docs/rendering.md +71 -0
- package/docs/server-rendering.md +118 -0
- package/docs/state-and-events.md +134 -0
- package/docs/styling-and-animation.md +104 -0
- package/docs/utilities/async-options.md +332 -0
- package/docs/utilities/shortcuts.md +184 -0
- package/html-custom-data.json +14792 -0
- package/package.json +302 -3
|
@@ -0,0 +1,1489 @@
|
|
|
1
|
+
// src/define-element.ts
|
|
2
|
+
import {
|
|
3
|
+
applyAttrs,
|
|
4
|
+
attachFormInternals,
|
|
5
|
+
attrs as partAttrs,
|
|
6
|
+
bind,
|
|
7
|
+
bindElementInternals,
|
|
8
|
+
conditional,
|
|
9
|
+
connect,
|
|
10
|
+
elementMoved,
|
|
11
|
+
formCallback,
|
|
12
|
+
inDocumentOrder,
|
|
13
|
+
markAuthored,
|
|
14
|
+
portalTarget,
|
|
15
|
+
present as isPresent,
|
|
16
|
+
releaseAttrs,
|
|
17
|
+
renderVersion,
|
|
18
|
+
schemaOf,
|
|
19
|
+
selectedKeys,
|
|
20
|
+
subscribe,
|
|
21
|
+
validityChanged,
|
|
22
|
+
warn,
|
|
23
|
+
writeFromScript,
|
|
24
|
+
writeStyle
|
|
25
|
+
} from "@ui-sdk/core/renderer";
|
|
26
|
+
import { waitList } from "./action.js";
|
|
27
|
+
var autoIds = /* @__PURE__ */ new WeakMap();
|
|
28
|
+
var count = 0;
|
|
29
|
+
var claimed = /* @__PURE__ */ new Set();
|
|
30
|
+
function claimTag(tagName) {
|
|
31
|
+
if (typeof customElements === "undefined" || claimed.has(tagName)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
if (customElements.get(tagName)) {
|
|
35
|
+
warn(
|
|
36
|
+
`<${tagName}> is already defined by another library or another copy of ui-sdk. This one is skipped.`
|
|
37
|
+
);
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
claimed.add(tagName);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
function autoId(el) {
|
|
44
|
+
if (!autoIds.has(el)) {
|
|
45
|
+
autoIds.set(el, `auto-${++count}`);
|
|
46
|
+
}
|
|
47
|
+
return autoIds.get(el);
|
|
48
|
+
}
|
|
49
|
+
function wrappedButton(el) {
|
|
50
|
+
return el.querySelector(":scope > button, :scope > a") ?? el.firstElementChild;
|
|
51
|
+
}
|
|
52
|
+
var wrappedChild = (selector) => (el) => el.querySelector(`:scope > ${selector}`) ?? el.firstElementChild;
|
|
53
|
+
function ownButton(fill) {
|
|
54
|
+
return (el) => {
|
|
55
|
+
const written = wrappedButton(el);
|
|
56
|
+
if (written) {
|
|
57
|
+
return written;
|
|
58
|
+
}
|
|
59
|
+
const button = el.ownerDocument.createElement("button");
|
|
60
|
+
button.append(...el.childNodes);
|
|
61
|
+
if (!button.textContent?.trim()) {
|
|
62
|
+
fill?.(button);
|
|
63
|
+
}
|
|
64
|
+
el.append(button);
|
|
65
|
+
return button;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function boundElement(el, target) {
|
|
69
|
+
if (target) {
|
|
70
|
+
return target(el);
|
|
71
|
+
}
|
|
72
|
+
return el.hasAttribute("as-child") ? el.firstElementChild : el;
|
|
73
|
+
}
|
|
74
|
+
var rekeyed = (previous, next) => previous.id !== next.id || previous.value !== next.value;
|
|
75
|
+
var kebab = (name) => name.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);
|
|
76
|
+
var semantics = ["role", "aria-disabled"];
|
|
77
|
+
function parseAttribute(type, value) {
|
|
78
|
+
if (value === null) {
|
|
79
|
+
return void 0;
|
|
80
|
+
}
|
|
81
|
+
if (typeof type === "function") {
|
|
82
|
+
return type(value);
|
|
83
|
+
}
|
|
84
|
+
if (type === "boolean") {
|
|
85
|
+
return value !== "false";
|
|
86
|
+
}
|
|
87
|
+
if (type === "number") {
|
|
88
|
+
const number = Number(value);
|
|
89
|
+
return value.trim() === "" || Number.isNaN(number) ? void 0 : number;
|
|
90
|
+
}
|
|
91
|
+
if (type === "list") {
|
|
92
|
+
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
93
|
+
}
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
96
|
+
var presence = /* @__PURE__ */ new Set(["disabled", "required"]);
|
|
97
|
+
function readAttribute(el, name, type) {
|
|
98
|
+
const value = el.getAttribute(kebab(name));
|
|
99
|
+
if (type === "boolean" && presence.has(name)) {
|
|
100
|
+
return value === null ? void 0 : true;
|
|
101
|
+
}
|
|
102
|
+
return parseAttribute(type, value);
|
|
103
|
+
}
|
|
104
|
+
function readAttributes(el, schema) {
|
|
105
|
+
const result = {};
|
|
106
|
+
for (const [name, type] of Object.entries(schema)) {
|
|
107
|
+
const value = readAttribute(el, name, type);
|
|
108
|
+
if (value !== void 0) {
|
|
109
|
+
result[name] = value;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
var defaultOn = (el, value) => typeof value === "function" ? value(el) : value;
|
|
115
|
+
function reflectAttributes(proto, schema, defaults = {}) {
|
|
116
|
+
for (const [name, type] of Object.entries(schema)) {
|
|
117
|
+
if (name in proto) {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
const attribute = kebab(name);
|
|
121
|
+
Object.defineProperty(proto, name, {
|
|
122
|
+
configurable: true,
|
|
123
|
+
get() {
|
|
124
|
+
return readAttribute(this, name, type) ?? defaultOn(this, defaults[name]) ?? (type === "boolean" ? false : void 0);
|
|
125
|
+
},
|
|
126
|
+
set(value) {
|
|
127
|
+
const removes = value === false && type === "boolean" && !defaultOn(this, defaults[name]);
|
|
128
|
+
if (value == null || removes) {
|
|
129
|
+
this.removeAttribute(attribute);
|
|
130
|
+
} else {
|
|
131
|
+
this.setAttribute(
|
|
132
|
+
attribute,
|
|
133
|
+
value === true ? "" : Array.isArray(value) ? value.join(",") : String(value)
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function upgradeProperties(el, names) {
|
|
141
|
+
for (const name of names) {
|
|
142
|
+
if (!Object.prototype.hasOwnProperty.call(el, name)) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const value = el[name];
|
|
146
|
+
delete el[name];
|
|
147
|
+
el[name] = value;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
var quiet = /* @__PURE__ */ new Set();
|
|
151
|
+
function restoreQuietly(el, state, mode) {
|
|
152
|
+
quiet.add(el);
|
|
153
|
+
try {
|
|
154
|
+
return formCallback(el, "restore", state, mode);
|
|
155
|
+
} finally {
|
|
156
|
+
quiet.delete(el);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
var pendingRestores = /* @__PURE__ */ new Map();
|
|
160
|
+
function wroteFromScript(el) {
|
|
161
|
+
for (const waiting of pendingRestores.keys()) {
|
|
162
|
+
if (waiting.contains(el)) {
|
|
163
|
+
pendingRestores.delete(waiting);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function restoreOnceBound(el, state, mode) {
|
|
168
|
+
const token = {};
|
|
169
|
+
pendingRestores.set(el, token);
|
|
170
|
+
queueMicrotask(() => {
|
|
171
|
+
if (pendingRestores.get(el) !== token) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
pendingRestores.delete(el);
|
|
175
|
+
restoreQuietly(el, state, mode);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
function quietNow(el) {
|
|
179
|
+
const owner = partOwners.get(el);
|
|
180
|
+
if (quiet.has(el) || !!owner && quiet.has(owner)) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
for (const inside of quiet) {
|
|
184
|
+
if (el.contains(inside)) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
function detailsOnly(value, details) {
|
|
191
|
+
return details === void 0 && !!value && typeof value === "object" && "reason" in value && !(typeof Event !== "undefined" && value instanceof Event);
|
|
192
|
+
}
|
|
193
|
+
function withEvents(el, target, silent = [], actions = [], names = {}) {
|
|
194
|
+
return new Proxy(target, {
|
|
195
|
+
get(target2, key) {
|
|
196
|
+
if (key in target2 || typeof key !== "string" || !/^on[A-Z]/.test(key)) {
|
|
197
|
+
return target2[key];
|
|
198
|
+
}
|
|
199
|
+
if (silent.includes(key)) {
|
|
200
|
+
return void 0;
|
|
201
|
+
}
|
|
202
|
+
return (value, details) => {
|
|
203
|
+
if (quietNow(el)) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const only = detailsOnly(value, details);
|
|
207
|
+
const { cancel, canceled, ...rest } = (only ? value : details) ?? {};
|
|
208
|
+
const detail = only ? rest : { ...rest, value };
|
|
209
|
+
const wait = actions.includes(key) ? waitList() : void 0;
|
|
210
|
+
if (wait) {
|
|
211
|
+
detail.waitUntil = wait.waitUntil;
|
|
212
|
+
}
|
|
213
|
+
const event = new CustomEvent(
|
|
214
|
+
names[key] ?? key.slice(2).toLowerCase(),
|
|
215
|
+
{
|
|
216
|
+
detail,
|
|
217
|
+
bubbles: false,
|
|
218
|
+
// Only a change with details or an event to cancel is cancelable.
|
|
219
|
+
cancelable: typeof cancel === "function" || typeof value?.preventDefault === "function",
|
|
220
|
+
composed: true
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
const proceed = el.dispatchEvent(event);
|
|
224
|
+
const waiting = wait?.done() ?? [];
|
|
225
|
+
if (!proceed) {
|
|
226
|
+
if (typeof cancel === "function") {
|
|
227
|
+
cancel();
|
|
228
|
+
} else if (value && typeof value.preventDefault === "function") {
|
|
229
|
+
;
|
|
230
|
+
value.preventDefault();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return waiting.length > 1 ? Promise.all(waiting).then((values) => values.at(-1)) : waiting[0];
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
var instances = /* @__PURE__ */ new WeakMap();
|
|
239
|
+
function instanceOf(el) {
|
|
240
|
+
return el ? instances.get(el) : void 0;
|
|
241
|
+
}
|
|
242
|
+
var reads = /^(?:get|is|can)[A-Z]|^focus$/;
|
|
243
|
+
function controllerView(el, api, methods) {
|
|
244
|
+
const view = {};
|
|
245
|
+
for (const name of methods) {
|
|
246
|
+
const method = api[name];
|
|
247
|
+
if (typeof method === "function") {
|
|
248
|
+
view[name] = (...args) => {
|
|
249
|
+
if (!reads.test(name)) {
|
|
250
|
+
wroteFromScript(el);
|
|
251
|
+
}
|
|
252
|
+
return method.apply(api, args);
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return Object.freeze(view);
|
|
257
|
+
}
|
|
258
|
+
var display = /* @__PURE__ */ new Map();
|
|
259
|
+
var aligned = /* @__PURE__ */ new Set();
|
|
260
|
+
var styleId;
|
|
261
|
+
function documentStyle() {
|
|
262
|
+
if (styleId) {
|
|
263
|
+
return styleId;
|
|
264
|
+
}
|
|
265
|
+
const copies = globalThis;
|
|
266
|
+
const key = /* @__PURE__ */ Symbol.for("ui-sdk.web-styles@1");
|
|
267
|
+
copies[key] = (copies[key] ?? 0) + 1;
|
|
268
|
+
return styleId = `ui-sdk-web-${copies[key]}`;
|
|
269
|
+
}
|
|
270
|
+
var css = "";
|
|
271
|
+
var rulesVersion = 0;
|
|
272
|
+
var constructed = /* @__PURE__ */ new WeakMap();
|
|
273
|
+
function setDisplay(selector, value, align = false) {
|
|
274
|
+
if (align) {
|
|
275
|
+
aligned.add(selector);
|
|
276
|
+
}
|
|
277
|
+
if (!value && !align) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (value) {
|
|
281
|
+
display.set(selector, value);
|
|
282
|
+
}
|
|
283
|
+
css = rules();
|
|
284
|
+
writeStyle(document, documentStyle(), css);
|
|
285
|
+
rulesVersion++;
|
|
286
|
+
}
|
|
287
|
+
function rules() {
|
|
288
|
+
return [
|
|
289
|
+
"@layer ui-sdk {",
|
|
290
|
+
// Parts that aren't shown stay hidden whatever display a class gives them.
|
|
291
|
+
' :where([data-slot][hidden]:not([hidden="until-found"])) { display: none !important }',
|
|
292
|
+
// Content hidden until found is only hidden inside a box, so those keep theirs.
|
|
293
|
+
...[...display].map(
|
|
294
|
+
([selector, value]) => ` :where(${selector}:not([hidden]), ${selector}[hidden="until-found"]) { display: ${value} }`
|
|
295
|
+
),
|
|
296
|
+
...[...aligned].map(
|
|
297
|
+
(tag) => ` :where(${tag}[align]) { text-align: inherit }`
|
|
298
|
+
),
|
|
299
|
+
// A part with as-child hands its role to its child, so it has no box of its own.
|
|
300
|
+
" :where([as-child]) { display: contents }",
|
|
301
|
+
"}"
|
|
302
|
+
].join("\n");
|
|
303
|
+
}
|
|
304
|
+
function adoptStyles(el) {
|
|
305
|
+
const root = el.getRootNode();
|
|
306
|
+
if (!isShadowRoot(root)) {
|
|
307
|
+
return copyStyles(el.ownerDocument);
|
|
308
|
+
}
|
|
309
|
+
const shared = sharedSheet(root.ownerDocument);
|
|
310
|
+
if (!shared || root.adoptedStyleSheets.includes(shared)) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
root.adoptedStyleSheets = [shared, ...root.adoptedStyleSheets];
|
|
314
|
+
}
|
|
315
|
+
var isShadowRoot = (node) => node.nodeType === 11 && "host" in node;
|
|
316
|
+
function sharedSheet(doc) {
|
|
317
|
+
const view = doc.defaultView;
|
|
318
|
+
if (!view) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
let entry = constructed.get(doc);
|
|
322
|
+
if (!entry) {
|
|
323
|
+
constructed.set(
|
|
324
|
+
doc,
|
|
325
|
+
entry = { sheet: new view.CSSStyleSheet(), version: -1 }
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
if (entry.version !== rulesVersion) {
|
|
329
|
+
entry.sheet.replaceSync(rules());
|
|
330
|
+
entry.version = rulesVersion;
|
|
331
|
+
}
|
|
332
|
+
return entry.sheet;
|
|
333
|
+
}
|
|
334
|
+
function copyStyles(doc) {
|
|
335
|
+
if (css) {
|
|
336
|
+
writeStyle(doc, documentStyle(), css);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
var dependents = /* @__PURE__ */ new Set();
|
|
340
|
+
function reconfigureInside(el) {
|
|
341
|
+
for (const dependent of dependents) {
|
|
342
|
+
if (dependent !== el && el.contains(dependent)) {
|
|
343
|
+
dependent.reconfigure();
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
var portals = /* @__PURE__ */ new WeakMap();
|
|
348
|
+
var passedOn = /* @__PURE__ */ new WeakMap();
|
|
349
|
+
function passPortalOn(container, to) {
|
|
350
|
+
passedOn.set(container, to);
|
|
351
|
+
}
|
|
352
|
+
function inheritedPortal(el) {
|
|
353
|
+
for (let node = el.parentElement; node; node = node.parentElement) {
|
|
354
|
+
const target = portals.get(node);
|
|
355
|
+
if (target) {
|
|
356
|
+
return passedOn.has(target) ? passedOn.get(target) : target;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
var partOwners = /* @__PURE__ */ new WeakMap();
|
|
362
|
+
var slotParts = /* @__PURE__ */ new WeakMap();
|
|
363
|
+
function innerPart(part, owner) {
|
|
364
|
+
for (let node = part.el; node && node !== owner; node = node.parentElement) {
|
|
365
|
+
const other = slotParts.get(node);
|
|
366
|
+
if (other === part) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (other?.el === part.el && registered.has(other)) {
|
|
370
|
+
return other;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function handOver(part) {
|
|
375
|
+
part.dataSlot = void 0;
|
|
376
|
+
const sharing = [];
|
|
377
|
+
for (let node = part.el; node; node = node.parentElement) {
|
|
378
|
+
const other = slotParts.get(node);
|
|
379
|
+
if (other && other !== part && other.el === part.el && registered.has(other)) {
|
|
380
|
+
sharing.push(other);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (!sharing.length) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
part.el.removeAttribute("data-slot");
|
|
387
|
+
markAuthored(part.el, "data-slot");
|
|
388
|
+
for (const other of sharing) {
|
|
389
|
+
other.sync?.();
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
var registered = /* @__PURE__ */ new WeakSet();
|
|
393
|
+
var findOwnerAgain = /* @__PURE__ */ new WeakMap();
|
|
394
|
+
var hasRichValue = (props) => props.value !== void 0 && typeof props.value !== "string";
|
|
395
|
+
function propsAround(el, slot, owner) {
|
|
396
|
+
for (let node = el.parentElement; node; node = node.parentElement) {
|
|
397
|
+
const part = slotParts.get(node);
|
|
398
|
+
if (part?.slot !== slot || partOwners.get(node) !== owner) {
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
return part.keyed && hasRichValue(part.props) ? { ...part.props, value: part.props.id } : part.props;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
function findOwner(el, selector) {
|
|
405
|
+
const target = el.getAttribute("for");
|
|
406
|
+
if (target) {
|
|
407
|
+
const root = el.getRootNode();
|
|
408
|
+
const owner = "getElementById" in root ? root.getElementById(target) : null;
|
|
409
|
+
if (owner?.matches(selector)) {
|
|
410
|
+
return owner;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
for (let node = el.parentElement; node; node = node.parentElement) {
|
|
414
|
+
if (node.matches(selector)) {
|
|
415
|
+
return node;
|
|
416
|
+
}
|
|
417
|
+
const owner = partOwners.get(node);
|
|
418
|
+
if (owner?.matches(selector)) {
|
|
419
|
+
return owner;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
var unmatched = /* @__PURE__ */ new WeakMap();
|
|
424
|
+
function findContainer(el, selector) {
|
|
425
|
+
for (let root = el.getRootNode(); ; root = root.host.getRootNode()) {
|
|
426
|
+
const container = root.querySelector(selector);
|
|
427
|
+
if (container) {
|
|
428
|
+
return container;
|
|
429
|
+
}
|
|
430
|
+
if (!isShadowRoot(root)) {
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (unmatched.get(el) !== selector) {
|
|
435
|
+
warn(
|
|
436
|
+
`<${el.localName}> container="${selector}" matches no element yet, so it renders in place. A container rendered later is used from its next open.`
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
unmatched.set(el, selector);
|
|
440
|
+
return null;
|
|
441
|
+
}
|
|
442
|
+
function whenGone(el, run) {
|
|
443
|
+
queueMicrotask(() => {
|
|
444
|
+
if (!el.isConnected) {
|
|
445
|
+
run();
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
var formStates = /* @__PURE__ */ new WeakMap();
|
|
450
|
+
var bindInternals = (el, internals, options) => {
|
|
451
|
+
formStates.set(el, options.state);
|
|
452
|
+
return bindElementInternals(el, internals, options);
|
|
453
|
+
};
|
|
454
|
+
function formAssociated(Base) {
|
|
455
|
+
return class extends Base {
|
|
456
|
+
static formAssociated = true;
|
|
457
|
+
#internals;
|
|
458
|
+
constructor() {
|
|
459
|
+
super();
|
|
460
|
+
this.#internals = this.attachInternals();
|
|
461
|
+
attachFormInternals(this, this.#internals, bindInternals);
|
|
462
|
+
}
|
|
463
|
+
get form() {
|
|
464
|
+
return this.#internals.form;
|
|
465
|
+
}
|
|
466
|
+
get labels() {
|
|
467
|
+
return this.#internals.labels;
|
|
468
|
+
}
|
|
469
|
+
get name() {
|
|
470
|
+
return this.getAttribute("name") ?? "";
|
|
471
|
+
}
|
|
472
|
+
set name(value) {
|
|
473
|
+
this.setAttribute("name", value);
|
|
474
|
+
}
|
|
475
|
+
get validity() {
|
|
476
|
+
return this.#internals.validity;
|
|
477
|
+
}
|
|
478
|
+
get validationMessage() {
|
|
479
|
+
return this.#internals.validationMessage;
|
|
480
|
+
}
|
|
481
|
+
get willValidate() {
|
|
482
|
+
return this.#internals.willValidate;
|
|
483
|
+
}
|
|
484
|
+
checkValidity() {
|
|
485
|
+
return this.#internals.checkValidity();
|
|
486
|
+
}
|
|
487
|
+
reportValidity() {
|
|
488
|
+
return this.#internals.reportValidity();
|
|
489
|
+
}
|
|
490
|
+
setCustomValidity(message) {
|
|
491
|
+
if (!formCallback(this, "customValidity", message)) {
|
|
492
|
+
this.#internals.setValidity(
|
|
493
|
+
message ? { customError: true } : {},
|
|
494
|
+
message
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
formResetCallback() {
|
|
499
|
+
pendingRestores.delete(this);
|
|
500
|
+
formCallback(this, "reset");
|
|
501
|
+
}
|
|
502
|
+
formDisabledCallback(disabled) {
|
|
503
|
+
formCallback(this, "disabled", disabled);
|
|
504
|
+
}
|
|
505
|
+
formStateRestoreCallback(state, mode) {
|
|
506
|
+
pendingRestores.delete(this);
|
|
507
|
+
if (!restoreQuietly(this, state, mode)) {
|
|
508
|
+
restoreOnceBound(this, state, mode);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
var defaultOf = (name) => `default${name[0].toUpperCase()}${name.slice(1)}`;
|
|
514
|
+
function defineRootElement(tagName, primitive, config) {
|
|
515
|
+
if (!claimTag(tagName)) {
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
setDisplay(tagName, config.display);
|
|
519
|
+
const schema = {
|
|
520
|
+
debug: "boolean",
|
|
521
|
+
...config.attributes
|
|
522
|
+
};
|
|
523
|
+
const state = config.state ?? {};
|
|
524
|
+
const optionsOf = (el, properties, rendered) => {
|
|
525
|
+
const options = readAttributes(el, schema);
|
|
526
|
+
for (const name of rendered) {
|
|
527
|
+
delete options[name];
|
|
528
|
+
}
|
|
529
|
+
for (const [name, value] of Object.entries(properties)) {
|
|
530
|
+
if (value !== void 0) {
|
|
531
|
+
options[name] = value;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
for (const name of Object.keys(state)) {
|
|
535
|
+
if (!(name in options)) {
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
const fallback = defaultOf(name);
|
|
539
|
+
if (!(fallback in options)) {
|
|
540
|
+
options[fallback] = options[name];
|
|
541
|
+
}
|
|
542
|
+
delete options[name];
|
|
543
|
+
}
|
|
544
|
+
return { ...options, ...config.options?.(el) };
|
|
545
|
+
};
|
|
546
|
+
customElements.define(
|
|
547
|
+
tagName,
|
|
548
|
+
class Owner extends (config.formAssociated ? formAssociated(HTMLElement) : HTMLElement) {
|
|
549
|
+
static observedAttributes = [
|
|
550
|
+
...Object.keys(schema).map(kebab),
|
|
551
|
+
...semantics
|
|
552
|
+
];
|
|
553
|
+
#view;
|
|
554
|
+
get #instance() {
|
|
555
|
+
return instances.get(this);
|
|
556
|
+
}
|
|
557
|
+
// The controller's methods. Internals stay out of reach.
|
|
558
|
+
get api() {
|
|
559
|
+
if (!this.#instance) {
|
|
560
|
+
return void 0;
|
|
561
|
+
}
|
|
562
|
+
return this.#view ??= controllerView(
|
|
563
|
+
this,
|
|
564
|
+
this.#instance.api,
|
|
565
|
+
config.api ?? []
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
#parts = /* @__PURE__ */ new Set();
|
|
569
|
+
#pending = /* @__PURE__ */ new Set();
|
|
570
|
+
#connected = false;
|
|
571
|
+
#rendering = false;
|
|
572
|
+
#rendered = /* @__PURE__ */ new Set();
|
|
573
|
+
#applying = /* @__PURE__ */ new Set();
|
|
574
|
+
#stale = /* @__PURE__ */ new Set();
|
|
575
|
+
// Left the page and destroyed its instance, which a reconnect replaces.
|
|
576
|
+
#gone = false;
|
|
577
|
+
#properties = {};
|
|
578
|
+
// State properties set while there's no live instance, like before the
|
|
579
|
+
// element connects, where the next instance starts.
|
|
580
|
+
#state = {};
|
|
581
|
+
// What a form-associated element reported to its form when it left,
|
|
582
|
+
// which it restores when it's back.
|
|
583
|
+
#saved;
|
|
584
|
+
static {
|
|
585
|
+
for (const [name, { get, set }] of Object.entries(state)) {
|
|
586
|
+
Object.defineProperty(Owner.prototype, name, {
|
|
587
|
+
get() {
|
|
588
|
+
if (name in this.#state) {
|
|
589
|
+
return this.#state[name];
|
|
590
|
+
}
|
|
591
|
+
return this.#instance ? get(this.#instance.api) : void 0;
|
|
592
|
+
},
|
|
593
|
+
set(value) {
|
|
594
|
+
wroteFromScript(this);
|
|
595
|
+
if (this.#instance && !this.#gone) {
|
|
596
|
+
this.#quietly(() => set(this.#instance.api, value));
|
|
597
|
+
} else {
|
|
598
|
+
this.#state[name] = value;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
for (const name of config.properties ?? []) {
|
|
604
|
+
Object.defineProperty(Owner.prototype, name, {
|
|
605
|
+
get() {
|
|
606
|
+
return this.#properties[name];
|
|
607
|
+
},
|
|
608
|
+
set(value) {
|
|
609
|
+
if (Object.is(this.#properties[name], value)) {
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
this.#properties[name] = value;
|
|
613
|
+
if (!this.#connected) {
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
this.#configure();
|
|
617
|
+
this.#render();
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
reflectAttributes(
|
|
622
|
+
Owner.prototype,
|
|
623
|
+
schema,
|
|
624
|
+
config.defaults
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
// Options come from attributes and properties, with `defaults` over them.
|
|
628
|
+
// Re-read them into the instance.
|
|
629
|
+
#configure(defaults) {
|
|
630
|
+
this.#instance?.setOptions(
|
|
631
|
+
withEvents(
|
|
632
|
+
this,
|
|
633
|
+
{
|
|
634
|
+
...optionsOf(this, this.#properties, this.#rendered),
|
|
635
|
+
...defaults,
|
|
636
|
+
id: this.#instance.id
|
|
637
|
+
},
|
|
638
|
+
config.silent,
|
|
639
|
+
config.actions,
|
|
640
|
+
config.events
|
|
641
|
+
)
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
attributeChangedCallback(name, previous, value) {
|
|
645
|
+
markAuthored(this, name);
|
|
646
|
+
if (semantics.includes(name)) {
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
const key = name.replace(
|
|
650
|
+
/-(\w)/g,
|
|
651
|
+
(_, char) => char.toUpperCase()
|
|
652
|
+
);
|
|
653
|
+
if (key in state && value !== previous && !this.#rendering) {
|
|
654
|
+
wroteFromScript(this);
|
|
655
|
+
}
|
|
656
|
+
if (!this.#rendering || value === null) {
|
|
657
|
+
this.#rendered.delete(key);
|
|
658
|
+
} else if (previous === null) {
|
|
659
|
+
this.#rendered.add(key);
|
|
660
|
+
}
|
|
661
|
+
if (!this.#connected) {
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
this.#configure();
|
|
665
|
+
reconfigureInside(this);
|
|
666
|
+
if (!(key in state) || value === previous) {
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
const type = schema[key];
|
|
670
|
+
const cleared = type === "boolean" ? false : type === "list" ? [] : null;
|
|
671
|
+
this.#quietly(
|
|
672
|
+
() => state[key].set(
|
|
673
|
+
this.#instance.api,
|
|
674
|
+
value === null ? cleared : parseAttribute(type, value)
|
|
675
|
+
)
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
// State set from script commits without events, like a native input's
|
|
679
|
+
// `value`, so a page that renders the state back never hears its own write.
|
|
680
|
+
#quietly(write) {
|
|
681
|
+
const nested = quiet.has(this);
|
|
682
|
+
quiet.add(this);
|
|
683
|
+
try {
|
|
684
|
+
writeFromScript(this, write);
|
|
685
|
+
} finally {
|
|
686
|
+
if (!nested) {
|
|
687
|
+
quiet.delete(this);
|
|
688
|
+
validityChanged(this);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
connectedCallback() {
|
|
693
|
+
adoptStyles(this);
|
|
694
|
+
if (this.#connected) {
|
|
695
|
+
for (const part of this.#parts) {
|
|
696
|
+
elementMoved(part.el);
|
|
697
|
+
}
|
|
698
|
+
if (config.options) {
|
|
699
|
+
this.#configure();
|
|
700
|
+
}
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
upgradeProperties(this, [
|
|
704
|
+
...Object.keys(state),
|
|
705
|
+
...config.properties ?? [],
|
|
706
|
+
...Object.keys(schema)
|
|
707
|
+
]);
|
|
708
|
+
for (const [name, value] of Object.entries(config.host ?? {})) {
|
|
709
|
+
if (!this.hasAttribute(name)) {
|
|
710
|
+
this.setAttribute(name, value);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
const restore = this.#gone && !Object.keys(this.#state).length ? this.#saved : void 0;
|
|
714
|
+
const starts = {};
|
|
715
|
+
if (this.#gone && restore === void 0) {
|
|
716
|
+
for (const [name, { get }] of Object.entries(state)) {
|
|
717
|
+
starts[name] = get(this.#instance.api);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
Object.assign(starts, this.#state);
|
|
721
|
+
this.#state = {};
|
|
722
|
+
const last = Object.fromEntries(
|
|
723
|
+
Object.entries(starts).map(([name, value]) => [
|
|
724
|
+
defaultOf(name),
|
|
725
|
+
value
|
|
726
|
+
])
|
|
727
|
+
);
|
|
728
|
+
if (this.#gone) {
|
|
729
|
+
instances.delete(this);
|
|
730
|
+
this.#view = void 0;
|
|
731
|
+
this.#gone = false;
|
|
732
|
+
this.#saved = void 0;
|
|
733
|
+
}
|
|
734
|
+
let instance = this.#instance;
|
|
735
|
+
if (instance) {
|
|
736
|
+
this.#configure();
|
|
737
|
+
} else {
|
|
738
|
+
instance = primitive(
|
|
739
|
+
withEvents(
|
|
740
|
+
this,
|
|
741
|
+
{
|
|
742
|
+
...optionsOf(this, this.#properties, this.#rendered),
|
|
743
|
+
...last,
|
|
744
|
+
id: this.id || `ui-sdk-${tagName.replace(/^ui-/, "")}-${++count}`
|
|
745
|
+
},
|
|
746
|
+
config.silent,
|
|
747
|
+
config.actions,
|
|
748
|
+
config.events
|
|
749
|
+
)
|
|
750
|
+
);
|
|
751
|
+
instances.set(this, instance);
|
|
752
|
+
}
|
|
753
|
+
if (config.formAssociated && Object.keys(starts).length) {
|
|
754
|
+
const base = instance.startState(
|
|
755
|
+
optionsOf(this, this.#properties, this.#rendered)
|
|
756
|
+
);
|
|
757
|
+
this.#configure(
|
|
758
|
+
Object.fromEntries(
|
|
759
|
+
Object.keys(starts).map((name) => [defaultOf(name), base[name]])
|
|
760
|
+
)
|
|
761
|
+
);
|
|
762
|
+
}
|
|
763
|
+
this.#connected = true;
|
|
764
|
+
if (config.options) {
|
|
765
|
+
dependents.add(this);
|
|
766
|
+
}
|
|
767
|
+
if (config.self) {
|
|
768
|
+
const el = boundElement(this, config.target);
|
|
769
|
+
if (el) {
|
|
770
|
+
this.#registerSelf(el);
|
|
771
|
+
} else {
|
|
772
|
+
warn(`<${tagName}> needs an element inside it.`);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
for (const [slot, find] of Object.entries(config.children ?? {})) {
|
|
776
|
+
const child = find(this);
|
|
777
|
+
if (child) {
|
|
778
|
+
this.#registerChild(slot, child);
|
|
779
|
+
} else if (!config.optionalChildren?.includes(slot)) {
|
|
780
|
+
warn(
|
|
781
|
+
`<${tagName}> needs its native element inside it for "${slot}".`
|
|
782
|
+
);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
if (config.children || config.target) {
|
|
786
|
+
this.#childObserver = new MutationObserver(() => {
|
|
787
|
+
this.#syncChildren();
|
|
788
|
+
this.#syncSelf();
|
|
789
|
+
});
|
|
790
|
+
this.#childObserver.observe(this, { childList: true });
|
|
791
|
+
}
|
|
792
|
+
this.#render();
|
|
793
|
+
if (this.id) {
|
|
794
|
+
const root = this.getRootNode();
|
|
795
|
+
for (const el of root.querySelectorAll(
|
|
796
|
+
`[for="${CSS.escape(this.id)}"]`
|
|
797
|
+
)) {
|
|
798
|
+
findOwnerAgain.get(el)?.();
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
if (restore !== void 0) {
|
|
802
|
+
restoreOnceBound(this, restore, "restore");
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
#renderCleanup;
|
|
806
|
+
// Runs only while connected, when the instance exists.
|
|
807
|
+
#render() {
|
|
808
|
+
this.#renderCleanup?.();
|
|
809
|
+
this.#renderCleanup = config.render?.(this, this.#instance) || void 0;
|
|
810
|
+
}
|
|
811
|
+
reconfigure() {
|
|
812
|
+
if (this.#connected) {
|
|
813
|
+
this.#configure();
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
#childParts = /* @__PURE__ */ new Map();
|
|
817
|
+
#childObserver;
|
|
818
|
+
#selfPart;
|
|
819
|
+
#registerSelf(el) {
|
|
820
|
+
this.#selfPart = { slot: config.self, el, props: {} };
|
|
821
|
+
this.register(this.#selfPart);
|
|
822
|
+
}
|
|
823
|
+
// The element the own slot binds was replaced: the new one binds instead.
|
|
824
|
+
#syncSelf() {
|
|
825
|
+
if (!config.self || !config.target) {
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
const el = boundElement(this, config.target);
|
|
829
|
+
if (el === this.#selfPart?.el) {
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
if (this.#selfPart) {
|
|
833
|
+
this.unregister(this.#selfPart);
|
|
834
|
+
}
|
|
835
|
+
this.#selfPart = void 0;
|
|
836
|
+
this.#configure();
|
|
837
|
+
if (el) {
|
|
838
|
+
this.#registerSelf(el);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
#registerChild(slot, el) {
|
|
842
|
+
const part = {
|
|
843
|
+
slot,
|
|
844
|
+
el,
|
|
845
|
+
props: config.childProps?.read?.(el) ?? {}
|
|
846
|
+
};
|
|
847
|
+
if (config.childProps) {
|
|
848
|
+
part.observer = new MutationObserver(() => {
|
|
849
|
+
part.props = config.childProps.read?.(el) ?? {};
|
|
850
|
+
this.#configure();
|
|
851
|
+
this.update(part, false);
|
|
852
|
+
});
|
|
853
|
+
part.observer.observe(el, {
|
|
854
|
+
attributeFilter: config.childProps.attributes
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
this.#childParts.set(slot, part);
|
|
858
|
+
this.register(part);
|
|
859
|
+
}
|
|
860
|
+
#syncChildren() {
|
|
861
|
+
for (const [slot, find] of Object.entries(config.children ?? {})) {
|
|
862
|
+
const child = find(this);
|
|
863
|
+
const current = this.#childParts.get(slot);
|
|
864
|
+
if (current?.el === child) {
|
|
865
|
+
continue;
|
|
866
|
+
}
|
|
867
|
+
if (current) {
|
|
868
|
+
this.unregister(current);
|
|
869
|
+
this.#childParts.delete(slot);
|
|
870
|
+
}
|
|
871
|
+
if (child) {
|
|
872
|
+
this.#registerChild(slot, child);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
disconnectedCallback() {
|
|
877
|
+
whenGone(this, () => {
|
|
878
|
+
this.#saved = formStates.get(this)?.();
|
|
879
|
+
this.#renderCleanup?.();
|
|
880
|
+
this.#renderCleanup = void 0;
|
|
881
|
+
this.#childObserver?.disconnect();
|
|
882
|
+
this.#childObserver = void 0;
|
|
883
|
+
this.#childParts.clear();
|
|
884
|
+
this.#selfPart = void 0;
|
|
885
|
+
this.#connected = false;
|
|
886
|
+
dependents.delete(this);
|
|
887
|
+
for (const part of this.#parts) {
|
|
888
|
+
this.unregister(part);
|
|
889
|
+
}
|
|
890
|
+
this.#instance?.destroy();
|
|
891
|
+
this.#gone = true;
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
// Parts register as they upgrade, in no useful order. They sync together a
|
|
895
|
+
// microtask later in DOM order, so a trigger binds before an open popup.
|
|
896
|
+
register(part) {
|
|
897
|
+
this.#parts.add(part);
|
|
898
|
+
registered.add(part);
|
|
899
|
+
part.sync = () => this.#pending.has(part) || this.#sync(part);
|
|
900
|
+
if (!this.#pending.size) {
|
|
901
|
+
queueMicrotask(() => this.#flush());
|
|
902
|
+
}
|
|
903
|
+
this.#pending.add(part);
|
|
904
|
+
}
|
|
905
|
+
#flush() {
|
|
906
|
+
const parts = inDocumentOrder([...this.#pending]);
|
|
907
|
+
this.#pending.clear();
|
|
908
|
+
for (const part of parts) {
|
|
909
|
+
if (!this.#parts.has(part)) {
|
|
910
|
+
continue;
|
|
911
|
+
}
|
|
912
|
+
if (part.reread) {
|
|
913
|
+
part.props = part.reread();
|
|
914
|
+
}
|
|
915
|
+
if (part.feature) {
|
|
916
|
+
this.#instance.use(part.feature);
|
|
917
|
+
}
|
|
918
|
+
this.#watch(part);
|
|
919
|
+
this.#sync(part);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
// Syncs a part again when a change can affect it, so a highlight change
|
|
923
|
+
// reaches the two items it moves between, not every part. Live state is
|
|
924
|
+
// written by the core, so only changes to state that affects rendering
|
|
925
|
+
// apply attributes again. A part that selects on a live key, like an
|
|
926
|
+
// item on the highlight, hears that key alone, and has nothing to apply.
|
|
927
|
+
#watch(part) {
|
|
928
|
+
const instance = this.#instance;
|
|
929
|
+
part.unwatch?.();
|
|
930
|
+
const record = instance.part(part.slot, part.props);
|
|
931
|
+
part.record = record;
|
|
932
|
+
part.selected = selectedKeys(record);
|
|
933
|
+
part.version = renderVersion(instance);
|
|
934
|
+
part.unwatch = subscribe(record, (liveOnly) => {
|
|
935
|
+
if (isPresent(record) !== part.shown) {
|
|
936
|
+
part.version = renderVersion(instance);
|
|
937
|
+
return this.#sync(part);
|
|
938
|
+
}
|
|
939
|
+
if (liveOnly) {
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
const version = renderVersion(instance);
|
|
943
|
+
if (version === part.version) {
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
part.version = version;
|
|
947
|
+
this.#sync(part);
|
|
948
|
+
});
|
|
949
|
+
}
|
|
950
|
+
unregister(part) {
|
|
951
|
+
part.unwatch?.();
|
|
952
|
+
part.unwatch = void 0;
|
|
953
|
+
part.observer?.disconnect();
|
|
954
|
+
part.observer = void 0;
|
|
955
|
+
this.#unbind(part);
|
|
956
|
+
releaseAttrs(part.el, this.#channel);
|
|
957
|
+
part.disconnect?.();
|
|
958
|
+
part.disconnect = void 0;
|
|
959
|
+
this.#restore(part);
|
|
960
|
+
this.#parts.delete(part);
|
|
961
|
+
registered.delete(part);
|
|
962
|
+
this.#pending.delete(part);
|
|
963
|
+
handOver(part);
|
|
964
|
+
}
|
|
965
|
+
// Binds every bound part again, in DOM order, for what they found when
|
|
966
|
+
// they bound, like the menubar a menu joins, which may upgrade later.
|
|
967
|
+
rebind() {
|
|
968
|
+
const parts = inDocumentOrder(
|
|
969
|
+
[...this.#parts].filter((part) => !this.#pending.has(part))
|
|
970
|
+
);
|
|
971
|
+
for (const part of parts) {
|
|
972
|
+
this.#unbind(part);
|
|
973
|
+
}
|
|
974
|
+
for (const part of parts) {
|
|
975
|
+
this.#sync(part);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
// Props changed. A new key needs a new binding. Other parts can depend on
|
|
979
|
+
// this one's props, like radio items on their group's value, or on its
|
|
980
|
+
// attributes, like toolbar items on their group's `disabled`, so they
|
|
981
|
+
// read their props again and sync too.
|
|
982
|
+
update(part, rebind) {
|
|
983
|
+
if (this.#pending.has(part)) {
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
this.#rewatch(part, rebind);
|
|
987
|
+
this.#sync(part);
|
|
988
|
+
for (const other of this.#parts) {
|
|
989
|
+
if (other === part || this.#pending.has(other)) {
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
992
|
+
if (other.reread) {
|
|
993
|
+
const previous = other.props;
|
|
994
|
+
other.props = other.reread();
|
|
995
|
+
this.#rewatch(other, rekeyed(previous, other.props));
|
|
996
|
+
}
|
|
997
|
+
this.#sync(other);
|
|
998
|
+
}
|
|
999
|
+
reconfigureInside(part.el);
|
|
1000
|
+
}
|
|
1001
|
+
#rewatch(part, rebind) {
|
|
1002
|
+
if (rebind) {
|
|
1003
|
+
this.#unbind(part);
|
|
1004
|
+
}
|
|
1005
|
+
const record = this.#instance.part(part.slot, part.props);
|
|
1006
|
+
if (record !== part.record || selectedKeys(record) !== part.selected) {
|
|
1007
|
+
this.#watch(part);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
#sync(part) {
|
|
1011
|
+
if (this.#applying.has(part)) {
|
|
1012
|
+
return void this.#stale.add(part);
|
|
1013
|
+
}
|
|
1014
|
+
adoptStyles(part.el);
|
|
1015
|
+
const instance = this.#instance;
|
|
1016
|
+
const record = instance.part(part.slot, part.props);
|
|
1017
|
+
part.disconnect ??= connect(record, part.el);
|
|
1018
|
+
part.shown = isPresent(record);
|
|
1019
|
+
if (part.shown) {
|
|
1020
|
+
const target = this.#portalTarget(part);
|
|
1021
|
+
if (target !== void 0 && this.#moves(part, target)) {
|
|
1022
|
+
this.#unbind(part);
|
|
1023
|
+
this.#move(part, target);
|
|
1024
|
+
}
|
|
1025
|
+
const attrs = partAttrs(record);
|
|
1026
|
+
if (attrs.hidden === void 0 && (conditional(record) || "hidden" in attrs)) {
|
|
1027
|
+
part.el.removeAttribute("hidden");
|
|
1028
|
+
}
|
|
1029
|
+
this.#apply(part, attrs);
|
|
1030
|
+
if (!part.unbind) {
|
|
1031
|
+
this.#bind(part, record);
|
|
1032
|
+
}
|
|
1033
|
+
} else {
|
|
1034
|
+
if (part.unbind) {
|
|
1035
|
+
this.#apply(part, partAttrs(record));
|
|
1036
|
+
this.#unbind(part);
|
|
1037
|
+
}
|
|
1038
|
+
if (!part.el.hasAttribute("hidden")) {
|
|
1039
|
+
part.el.setAttribute("hidden", "");
|
|
1040
|
+
}
|
|
1041
|
+
const slot = partAttrs(record)["data-slot"];
|
|
1042
|
+
if (slot && !part.el.hasAttribute("data-slot")) {
|
|
1043
|
+
part.el.setAttribute("data-slot", slot);
|
|
1044
|
+
}
|
|
1045
|
+
this.#restore(part);
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
// Binding and unbinding can change state, which syncs parts again. The part
|
|
1049
|
+
// counts as bound from the start, so a nested sync never binds it twice,
|
|
1050
|
+
// and as unbound from the start, so it never unbinds twice.
|
|
1051
|
+
#bind(part, record) {
|
|
1052
|
+
let cleanup;
|
|
1053
|
+
let unbound = false;
|
|
1054
|
+
part.unbind = () => {
|
|
1055
|
+
unbound = true;
|
|
1056
|
+
cleanup?.();
|
|
1057
|
+
};
|
|
1058
|
+
cleanup = bind(record, part.el);
|
|
1059
|
+
if (unbound) {
|
|
1060
|
+
cleanup();
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
#unbind(part) {
|
|
1064
|
+
const unbind = part.unbind;
|
|
1065
|
+
part.unbind = void 0;
|
|
1066
|
+
unbind?.();
|
|
1067
|
+
}
|
|
1068
|
+
// Where a portaled slot's part belongs: a container, or null for in
|
|
1069
|
+
// place. Undefined for slots that never move.
|
|
1070
|
+
#portalTarget(part) {
|
|
1071
|
+
if (!config.portal?.slots.includes(part.slot)) {
|
|
1072
|
+
return void 0;
|
|
1073
|
+
}
|
|
1074
|
+
return portalTarget(config.portal.container(this, part));
|
|
1075
|
+
}
|
|
1076
|
+
#moves(part, target) {
|
|
1077
|
+
return target ? part.el.parentNode !== target : !!part.placeholder;
|
|
1078
|
+
}
|
|
1079
|
+
// Moves a part into its container, or back in place for null.
|
|
1080
|
+
#move(part, target) {
|
|
1081
|
+
this.#restore(part);
|
|
1082
|
+
if (!target) {
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
part.placeholder = document.createComment(`${tagName} ${part.slot}`);
|
|
1086
|
+
part.el.replaceWith(part.placeholder);
|
|
1087
|
+
target.appendChild(part.el);
|
|
1088
|
+
portals.set(part.el, target);
|
|
1089
|
+
}
|
|
1090
|
+
// An attribute the owner writes on itself is state, not an option, like a
|
|
1091
|
+
// grouped checkbox's `disabled` from its group, so it never disables it for good.
|
|
1092
|
+
#apply(part, attrs) {
|
|
1093
|
+
const inner = innerPart(part, this);
|
|
1094
|
+
if (inner?.dataSlot) {
|
|
1095
|
+
attrs = { ...attrs, "data-slot": inner.dataSlot };
|
|
1096
|
+
}
|
|
1097
|
+
part.dataSlot = attrs["data-slot"];
|
|
1098
|
+
const rendering = this.#rendering;
|
|
1099
|
+
this.#rendering = part.el === this;
|
|
1100
|
+
this.#applying.add(part);
|
|
1101
|
+
try {
|
|
1102
|
+
applyAttrs(part.el, attrs, this.#channel);
|
|
1103
|
+
} finally {
|
|
1104
|
+
this.#rendering = rendering;
|
|
1105
|
+
this.#applying.delete(part);
|
|
1106
|
+
}
|
|
1107
|
+
if (this.#stale.delete(part)) {
|
|
1108
|
+
this.#sync(part);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
// What the owner writes on its parts' elements. By host, not instance, so
|
|
1112
|
+
// one put back on the page replaces what its last instance wrote, like its parts' ids.
|
|
1113
|
+
get #channel() {
|
|
1114
|
+
return `render:${autoId(this)}`;
|
|
1115
|
+
}
|
|
1116
|
+
#restore(part) {
|
|
1117
|
+
if (!part.placeholder) {
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
part.placeholder.replaceWith(part.el);
|
|
1121
|
+
part.placeholder = void 0;
|
|
1122
|
+
portals.delete(part.el);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
);
|
|
1126
|
+
}
|
|
1127
|
+
function definePartElement(tagName, config) {
|
|
1128
|
+
if (!claimTag(tagName)) {
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1131
|
+
const schema = config.props ?? {};
|
|
1132
|
+
setDisplay(tagName, config.display, "align" in schema);
|
|
1133
|
+
customElements.define(
|
|
1134
|
+
tagName,
|
|
1135
|
+
class PartElement extends (config.formAssociated ? formAssociated(HTMLElement) : HTMLElement) {
|
|
1136
|
+
static observedAttributes = [
|
|
1137
|
+
...Object.keys(schema).map(kebab),
|
|
1138
|
+
"for",
|
|
1139
|
+
...semantics
|
|
1140
|
+
];
|
|
1141
|
+
#owner;
|
|
1142
|
+
#part;
|
|
1143
|
+
#properties = {};
|
|
1144
|
+
constructor() {
|
|
1145
|
+
super();
|
|
1146
|
+
findOwnerAgain.set(this, () => {
|
|
1147
|
+
if (this.isConnected) {
|
|
1148
|
+
this.connectedCallback();
|
|
1149
|
+
}
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
static {
|
|
1153
|
+
for (const name of config.properties ?? []) {
|
|
1154
|
+
Object.defineProperty(PartElement.prototype, name, {
|
|
1155
|
+
get() {
|
|
1156
|
+
return this.#properties[name] ?? (schema[name] && readAttribute(this, name, schema[name]));
|
|
1157
|
+
},
|
|
1158
|
+
set(value) {
|
|
1159
|
+
this.#properties[name] = value;
|
|
1160
|
+
this.attributeChangedCallback("");
|
|
1161
|
+
}
|
|
1162
|
+
});
|
|
1163
|
+
}
|
|
1164
|
+
reflectAttributes(PartElement.prototype, schema, config.defaults);
|
|
1165
|
+
}
|
|
1166
|
+
// What the element says itself, its attributes and properties, wins
|
|
1167
|
+
// over what its surroundings give it.
|
|
1168
|
+
#props() {
|
|
1169
|
+
const props = {
|
|
1170
|
+
...config.context?.(this),
|
|
1171
|
+
...readAttributes(this, schema)
|
|
1172
|
+
};
|
|
1173
|
+
for (const name of config.properties ?? []) {
|
|
1174
|
+
if (this.#properties[name] !== void 0) {
|
|
1175
|
+
props[name] = this.#properties[name];
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
for (const [name, { slot, prop }] of Object.entries(
|
|
1179
|
+
config.from ?? {}
|
|
1180
|
+
)) {
|
|
1181
|
+
props[name] ??= propsAround(this, slot, this.#owner)?.[prop];
|
|
1182
|
+
}
|
|
1183
|
+
for (const name of config.ids ?? []) {
|
|
1184
|
+
props[name] ??= autoId(this);
|
|
1185
|
+
}
|
|
1186
|
+
if (props.value === void 0 && props.id === void 0) {
|
|
1187
|
+
props.id = autoId(this);
|
|
1188
|
+
}
|
|
1189
|
+
if (config.keyed && hasRichValue(props)) {
|
|
1190
|
+
props.id ??= instanceOf(this.#owner)?.api.internal.keyOf(
|
|
1191
|
+
props.value
|
|
1192
|
+
);
|
|
1193
|
+
}
|
|
1194
|
+
return withEvents(this, props, [], config.actions);
|
|
1195
|
+
}
|
|
1196
|
+
// Watches the children for the element the part binds, which can come
|
|
1197
|
+
// later or be replaced, like a framework's conditional content.
|
|
1198
|
+
#children;
|
|
1199
|
+
connectedCallback() {
|
|
1200
|
+
upgradeProperties(this, [
|
|
1201
|
+
...config.properties ?? [],
|
|
1202
|
+
...Object.keys(schema)
|
|
1203
|
+
]);
|
|
1204
|
+
adoptStyles(this);
|
|
1205
|
+
if ((config.target || this.hasAttribute("as-child")) && !this.#children) {
|
|
1206
|
+
this.#children = new MutationObserver(() => this.#retarget());
|
|
1207
|
+
this.#children.observe(this, { childList: true });
|
|
1208
|
+
}
|
|
1209
|
+
const owner = findOwner(this, config.owner) ?? this.#owner;
|
|
1210
|
+
if (!owner) {
|
|
1211
|
+
return queueMicrotask(() => this.#findOwnerLater());
|
|
1212
|
+
}
|
|
1213
|
+
if (!("register" in owner)) {
|
|
1214
|
+
customElements.whenDefined(owner.localName).then(() => this.isConnected && this.connectedCallback());
|
|
1215
|
+
return;
|
|
1216
|
+
}
|
|
1217
|
+
if (owner === this.#owner && this.#part && registered.has(this.#part)) {
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
if (this.#owner && this.#part) {
|
|
1221
|
+
this.#owner.unregister(this.#part);
|
|
1222
|
+
}
|
|
1223
|
+
const el = boundElement(this, config.target);
|
|
1224
|
+
if (!el) {
|
|
1225
|
+
return queueMicrotask(() => {
|
|
1226
|
+
if (this.isConnected && !this.#part && !boundElement(this, config.target)) {
|
|
1227
|
+
warn(`<${tagName}> needs an element inside it.`);
|
|
1228
|
+
}
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
if (!this.#part) {
|
|
1232
|
+
config.render?.(this);
|
|
1233
|
+
if (this.#part) {
|
|
1234
|
+
return;
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
this.#owner = owner;
|
|
1238
|
+
this.#part = {
|
|
1239
|
+
slot: config.slot,
|
|
1240
|
+
feature: config.feature,
|
|
1241
|
+
el,
|
|
1242
|
+
props: this.#props(),
|
|
1243
|
+
reread: (config.context || config.from) && (() => this.#props()),
|
|
1244
|
+
keyed: config.keyed
|
|
1245
|
+
};
|
|
1246
|
+
partOwners.set(this, owner);
|
|
1247
|
+
slotParts.set(this, this.#part);
|
|
1248
|
+
owner.register(this.#part);
|
|
1249
|
+
}
|
|
1250
|
+
// Put back on the page, a part can connect before what leads to its owner
|
|
1251
|
+
// does, like an item in a list its owner renders again. Warned only when
|
|
1252
|
+
// the owner is still missing once the task's other elements connected.
|
|
1253
|
+
#findOwnerLater() {
|
|
1254
|
+
if (!this.isConnected || this.#owner) {
|
|
1255
|
+
return;
|
|
1256
|
+
}
|
|
1257
|
+
if (findOwner(this, config.owner)) {
|
|
1258
|
+
this.connectedCallback();
|
|
1259
|
+
} else if (config.alone) {
|
|
1260
|
+
config.alone(boundElement(this, config.target) ?? this, this);
|
|
1261
|
+
} else if (!this.hasAttribute("for")) {
|
|
1262
|
+
warn(`<${tagName}> must be inside ${config.owner}.`);
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
// The element the part binds came, left or was replaced: the part lets go
|
|
1266
|
+
// of the old one and registers again with what's there now. One the owner
|
|
1267
|
+
// moved into a portal, like an input a sheet puts in its header, stays bound.
|
|
1268
|
+
#retarget() {
|
|
1269
|
+
const old = this.#part?.el;
|
|
1270
|
+
if (!this.isConnected || old && portals.has(old)) {
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1273
|
+
const el = boundElement(this, config.target);
|
|
1274
|
+
if (el === (old ?? null)) {
|
|
1275
|
+
return;
|
|
1276
|
+
}
|
|
1277
|
+
if (this.#owner && this.#part) {
|
|
1278
|
+
this.#owner.unregister(this.#part);
|
|
1279
|
+
}
|
|
1280
|
+
this.#owner = void 0;
|
|
1281
|
+
this.#part = void 0;
|
|
1282
|
+
if (el) {
|
|
1283
|
+
this.connectedCallback();
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
disconnectedCallback() {
|
|
1287
|
+
whenGone(this, () => {
|
|
1288
|
+
this.#children?.disconnect();
|
|
1289
|
+
this.#children = void 0;
|
|
1290
|
+
if (this.#owner && this.#part) {
|
|
1291
|
+
this.#owner.unregister(this.#part);
|
|
1292
|
+
}
|
|
1293
|
+
partOwners.delete(this);
|
|
1294
|
+
slotParts.delete(this);
|
|
1295
|
+
this.#owner = void 0;
|
|
1296
|
+
this.#part = void 0;
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
attributeChangedCallback(name) {
|
|
1300
|
+
markAuthored(this, name);
|
|
1301
|
+
if (semantics.includes(name)) {
|
|
1302
|
+
return;
|
|
1303
|
+
}
|
|
1304
|
+
if (name === "for") {
|
|
1305
|
+
if (!this.isConnected) {
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1308
|
+
if (!findOwner(this, config.owner) && this.#owner && this.#part) {
|
|
1309
|
+
this.#owner.unregister(this.#part);
|
|
1310
|
+
this.#owner = void 0;
|
|
1311
|
+
partOwners.delete(this);
|
|
1312
|
+
}
|
|
1313
|
+
this.connectedCallback();
|
|
1314
|
+
return;
|
|
1315
|
+
}
|
|
1316
|
+
if (!this.#owner || !this.#part) {
|
|
1317
|
+
if (config.alone && this.isConnected && !findOwner(this, config.owner)) {
|
|
1318
|
+
config.alone(boundElement(this, config.target) ?? this, this);
|
|
1319
|
+
}
|
|
1320
|
+
return;
|
|
1321
|
+
}
|
|
1322
|
+
const previous = this.#part.props;
|
|
1323
|
+
this.#part.props = this.#props();
|
|
1324
|
+
const next = this.#part.props;
|
|
1325
|
+
const rebind = rekeyed(previous, next) || !!config.rebind?.some((name2) => previous[name2] !== next[name2]);
|
|
1326
|
+
this.#owner.update(this.#part, rebind);
|
|
1327
|
+
config.changed?.(this);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
);
|
|
1331
|
+
}
|
|
1332
|
+
var rootTags = /* @__PURE__ */ new WeakMap();
|
|
1333
|
+
function elementProps(props, schema, kinds = {}) {
|
|
1334
|
+
const attributes = {};
|
|
1335
|
+
const properties = [];
|
|
1336
|
+
const ids = [];
|
|
1337
|
+
const actions = [];
|
|
1338
|
+
let keyed = false;
|
|
1339
|
+
const from = {};
|
|
1340
|
+
for (const [name, spec] of Object.entries({ ...props, ...kinds })) {
|
|
1341
|
+
if (!spec) {
|
|
1342
|
+
continue;
|
|
1343
|
+
}
|
|
1344
|
+
if (typeof spec === "object") {
|
|
1345
|
+
const [slot, prop = name] = spec.from.split(".");
|
|
1346
|
+
if (slot in schema.slots) {
|
|
1347
|
+
from[name] = { slot, prop };
|
|
1348
|
+
}
|
|
1349
|
+
if (!(name in kinds)) {
|
|
1350
|
+
continue;
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
const kind = typeof spec === "object" ? spec.kind : spec;
|
|
1354
|
+
if (kind === "value") {
|
|
1355
|
+
properties.push(name);
|
|
1356
|
+
} else if (kind === "action") {
|
|
1357
|
+
actions.push(name);
|
|
1358
|
+
} else if (kind === "id") {
|
|
1359
|
+
ids.push(name);
|
|
1360
|
+
} else if (kind === "key") {
|
|
1361
|
+
keyed = true;
|
|
1362
|
+
}
|
|
1363
|
+
if (kind === "value" || kind === "action" || kind === "callback") {
|
|
1364
|
+
continue;
|
|
1365
|
+
}
|
|
1366
|
+
if (name !== "id" || name in kinds) {
|
|
1367
|
+
attributes[name] = kind === "id" || kind === "key" ? "string" : kind;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
return {
|
|
1371
|
+
attributes,
|
|
1372
|
+
properties,
|
|
1373
|
+
ids,
|
|
1374
|
+
actions,
|
|
1375
|
+
keyed,
|
|
1376
|
+
from: Object.keys(from).length ? from : void 0
|
|
1377
|
+
};
|
|
1378
|
+
}
|
|
1379
|
+
var tagOf = (tagOrOptions) => typeof tagOrOptions === "string" ? { tag: tagOrOptions } : tagOrOptions;
|
|
1380
|
+
function partElement(primitive, key, tagOrOptions, root) {
|
|
1381
|
+
const schema = schemaOf(primitive);
|
|
1382
|
+
if (key === "root") {
|
|
1383
|
+
const {
|
|
1384
|
+
tag: tag2,
|
|
1385
|
+
self,
|
|
1386
|
+
kinds: kinds2,
|
|
1387
|
+
properties: properties2 = [],
|
|
1388
|
+
...options2
|
|
1389
|
+
} = tagOf(tagOrOptions);
|
|
1390
|
+
rootTags.set(primitive, [
|
|
1391
|
+
.../* @__PURE__ */ new Set([...rootTags.get(primitive) ?? [], tag2])
|
|
1392
|
+
]);
|
|
1393
|
+
const { debug: _debug, ...optionSchema } = schema.options;
|
|
1394
|
+
const props2 = elementProps(optionSchema, schema, kinds2);
|
|
1395
|
+
const config2 = {
|
|
1396
|
+
...options2,
|
|
1397
|
+
self: self ?? ("root" in schema.slots && !options2.children?.root ? "root" : void 0),
|
|
1398
|
+
attributes: props2.attributes,
|
|
1399
|
+
// Live state has its own property.
|
|
1400
|
+
properties: [.../* @__PURE__ */ new Set([...props2.properties, ...properties2])].filter(
|
|
1401
|
+
(name) => !options2.state?.[name]
|
|
1402
|
+
),
|
|
1403
|
+
actions: props2.actions
|
|
1404
|
+
};
|
|
1405
|
+
return { kind: "owner", key, tagName: tag2, config: config2 };
|
|
1406
|
+
}
|
|
1407
|
+
const {
|
|
1408
|
+
tag,
|
|
1409
|
+
slot = key,
|
|
1410
|
+
owners = [],
|
|
1411
|
+
kinds,
|
|
1412
|
+
properties = [],
|
|
1413
|
+
...options
|
|
1414
|
+
} = tagOf(tagOrOptions);
|
|
1415
|
+
const roots = rootTags.get(primitive);
|
|
1416
|
+
if (!roots) {
|
|
1417
|
+
throw new Error(
|
|
1418
|
+
`<${tag}> is a part of ${primitive.name}: define its root first.`
|
|
1419
|
+
);
|
|
1420
|
+
}
|
|
1421
|
+
const slotSchema = schema.slots[slot] ?? (options.feature?.slots[slot] && (options.feature.slots[slot].props ?? {}));
|
|
1422
|
+
if (!slotSchema) {
|
|
1423
|
+
throw new Error(`<${tag}>: ${primitive.name} has no ${slot} slot.`);
|
|
1424
|
+
}
|
|
1425
|
+
const { attributes, ...props } = elementProps(slotSchema, schema, kinds);
|
|
1426
|
+
const config = {
|
|
1427
|
+
...options,
|
|
1428
|
+
slot,
|
|
1429
|
+
owner: [.../* @__PURE__ */ new Set([...root ? [root] : [], ...roots, ...owners])].join(
|
|
1430
|
+
", "
|
|
1431
|
+
),
|
|
1432
|
+
props: attributes,
|
|
1433
|
+
...props,
|
|
1434
|
+
properties: [.../* @__PURE__ */ new Set([...props.properties, ...properties])]
|
|
1435
|
+
};
|
|
1436
|
+
return { kind: "part", key, tagName: tag, config };
|
|
1437
|
+
}
|
|
1438
|
+
function partElements(primitive, tags) {
|
|
1439
|
+
const { root, ...parts } = tags;
|
|
1440
|
+
const owner = partElement(primitive, "root", root);
|
|
1441
|
+
return [
|
|
1442
|
+
owner,
|
|
1443
|
+
...Object.entries(
|
|
1444
|
+
parts
|
|
1445
|
+
).flatMap(
|
|
1446
|
+
([key, tag]) => tag ? [partElement(primitive, key, tag, owner.tagName)] : []
|
|
1447
|
+
)
|
|
1448
|
+
];
|
|
1449
|
+
}
|
|
1450
|
+
function defineElement(primitive, element) {
|
|
1451
|
+
if (element.kind === "owner") {
|
|
1452
|
+
defineRootElement(element.tagName, primitive, element.config);
|
|
1453
|
+
} else {
|
|
1454
|
+
definePartElement(element.tagName, element.config);
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
var pascal = (name) => name.replace(/(^|-)(\w)/g, (_, _dash, char) => char.toUpperCase());
|
|
1458
|
+
function createParts(primitive, tags) {
|
|
1459
|
+
const parts = {};
|
|
1460
|
+
for (const element of partElements(primitive, tags)) {
|
|
1461
|
+
defineElement(primitive, element);
|
|
1462
|
+
parts[pascal(element.key)] = typeof customElements === "undefined" ? void 0 : customElements.get(element.tagName);
|
|
1463
|
+
}
|
|
1464
|
+
return parts;
|
|
1465
|
+
}
|
|
1466
|
+
function definePart(primitive, slot, tagOrOptions) {
|
|
1467
|
+
defineElement(primitive, partElement(primitive, slot, tagOrOptions));
|
|
1468
|
+
}
|
|
1469
|
+
export {
|
|
1470
|
+
autoId,
|
|
1471
|
+
claimTag,
|
|
1472
|
+
createParts,
|
|
1473
|
+
definePart,
|
|
1474
|
+
findContainer,
|
|
1475
|
+
findOwner,
|
|
1476
|
+
inheritedPortal,
|
|
1477
|
+
instanceOf,
|
|
1478
|
+
ownButton,
|
|
1479
|
+
parseAttribute,
|
|
1480
|
+
partElement,
|
|
1481
|
+
partElements,
|
|
1482
|
+
passPortalOn,
|
|
1483
|
+
reconfigureInside,
|
|
1484
|
+
setDisplay,
|
|
1485
|
+
upgradeProperties,
|
|
1486
|
+
whenGone,
|
|
1487
|
+
wrappedButton,
|
|
1488
|
+
wrappedChild
|
|
1489
|
+
};
|