@vielzeug/refine 2.1.0 → 2.1.2
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/dist/accordion-item.cjs +1 -1
- package/dist/accordion-item.cjs.map +1 -1
- package/dist/accordion-item.js +1 -1
- package/dist/accordion-item.js.map +1 -1
- package/dist/accordion.cjs +1 -1
- package/dist/accordion.cjs.map +1 -1
- package/dist/accordion.js +1 -1
- package/dist/accordion.js.map +1 -1
- package/dist/alert.cjs.map +1 -1
- package/dist/alert.js.map +1 -1
- package/dist/async.cjs.map +1 -1
- package/dist/async.js.map +1 -1
- package/dist/avatar-group.cjs.map +1 -1
- package/dist/avatar-group.js.map +1 -1
- package/dist/avatar.cjs +6 -6
- package/dist/avatar.cjs.map +1 -1
- package/dist/avatar.js +1 -2
- package/dist/avatar.js.map +1 -1
- package/dist/badge.cjs.map +1 -1
- package/dist/badge.js.map +1 -1
- package/dist/box.cjs.map +1 -1
- package/dist/box.js.map +1 -1
- package/dist/breadcrumb.cjs +3 -3
- package/dist/breadcrumb.cjs.map +1 -1
- package/dist/breadcrumb.js +4 -4
- package/dist/breadcrumb.js.map +1 -1
- package/dist/button-group.cjs +1 -1
- package/dist/button-group.cjs.map +1 -1
- package/dist/button-group.js +0 -1
- package/dist/button-group.js.map +1 -1
- package/dist/button.cjs.map +1 -1
- package/dist/button.js.map +1 -1
- package/dist/calendar.cjs.map +1 -1
- package/dist/calendar.js.map +1 -1
- package/dist/card.cjs +7 -7
- package/dist/card.cjs.map +1 -1
- package/dist/card.js +27 -27
- package/dist/card.js.map +1 -1
- package/dist/carousel.cjs +20 -20
- package/dist/carousel.cjs.map +1 -1
- package/dist/carousel.js +7 -8
- package/dist/carousel.js.map +1 -1
- package/dist/chat-message.cjs +10 -10
- package/dist/chat-message.cjs.map +1 -1
- package/dist/chat-message.js +1 -2
- package/dist/chat-message.js.map +1 -1
- package/dist/checkbox-group.cjs +7 -7
- package/dist/checkbox-group.cjs.map +1 -1
- package/dist/checkbox-group.js +26 -26
- package/dist/checkbox-group.js.map +1 -1
- package/dist/checkbox.cjs +2 -2
- package/dist/checkbox.cjs.map +1 -1
- package/dist/checkbox.js +33 -33
- package/dist/checkbox.js.map +1 -1
- package/dist/chip.cjs +16 -16
- package/dist/chip.cjs.map +1 -1
- package/dist/chip.js +1 -2
- package/dist/chip.js.map +1 -1
- package/dist/combobox.cjs +28 -28
- package/dist/combobox.cjs.map +1 -1
- package/dist/combobox.js +211 -211
- package/dist/combobox.js.map +1 -1
- package/dist/command-palette.cjs +21 -21
- package/dist/command-palette.cjs.map +1 -1
- package/dist/command-palette.js +27 -28
- package/dist/command-palette.js.map +1 -1
- package/dist/content/avatar/avatar.css.cjs +1 -1
- package/dist/content/avatar/avatar.css.js +1 -1
- package/dist/content/avatar/avatar.d.ts.map +1 -1
- package/dist/content/breadcrumb/breadcrumb.d.ts.map +1 -1
- package/dist/content/card/card.css.cjs +1 -1
- package/dist/content/card/card.css.cjs.map +1 -1
- package/dist/content/card/card.css.js +1 -1
- package/dist/content/card/card.css.js.map +1 -1
- package/dist/content/card/card.d.ts.map +1 -1
- package/dist/content/carousel/carousel-slide.cjs.map +1 -1
- package/dist/content/carousel/carousel-slide.js.map +1 -1
- package/dist/content/carousel/carousel.css.cjs +1 -1
- package/dist/content/carousel/carousel.css.cjs.map +1 -1
- package/dist/content/carousel/carousel.css.js +1 -1
- package/dist/content/carousel/carousel.css.js.map +1 -1
- package/dist/content/carousel/carousel.d.ts.map +1 -1
- package/dist/content/carousel/index.d.ts +1 -1
- package/dist/content/carousel/index.d.ts.map +1 -1
- package/dist/content/chat-message/chat-message.css.cjs +1 -1
- package/dist/content/chat-message/chat-message.css.js +1 -1
- package/dist/content/chat-message/chat-message.d.ts.map +1 -1
- package/dist/content/code-window/code-window.css.cjs +1 -1
- package/dist/content/code-window/code-window.css.js +1 -1
- package/dist/content/copy-command/copy-command.css.cjs +1 -1
- package/dist/content/copy-command/copy-command.css.js +1 -1
- package/dist/content/copy-command/copy-command.d.ts.map +1 -1
- package/dist/content/index.d.ts +22 -22
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/list/_list-item-reveal.cjs.map +1 -1
- package/dist/content/list/_list-item-reveal.d.ts +1 -1
- package/dist/content/list/_list-item-reveal.d.ts.map +1 -1
- package/dist/content/list/_list-item-reveal.js.map +1 -1
- package/dist/content/list/list-item.css.cjs +1 -1
- package/dist/content/list/list-item.css.cjs.map +1 -1
- package/dist/content/list/list-item.css.js +1 -1
- package/dist/content/list/list-item.css.js.map +1 -1
- package/dist/content/list/list.d.ts.map +1 -1
- package/dist/content/marquee/marquee.css.cjs +1 -1
- package/dist/content/marquee/marquee.css.js +1 -1
- package/dist/content/pagination/pagination.css.cjs +1 -1
- package/dist/content/pagination/pagination.css.js +1 -1
- package/dist/content/pagination/pagination.d.ts.map +1 -1
- package/dist/content/separator/separator.css.cjs +1 -1
- package/dist/content/separator/separator.css.js +1 -1
- package/dist/content/separator/separator.d.ts.map +1 -1
- package/dist/content/stepper/step.css.cjs.map +1 -1
- package/dist/content/stepper/step.css.js.map +1 -1
- package/dist/content/stepper/stepper.d.ts.map +1 -1
- package/dist/content/table/table.css.cjs +1 -1
- package/dist/content/table/table.css.js +1 -1
- package/dist/content/text/text.css.cjs +1 -1
- package/dist/content/text/text.css.js +1 -1
- package/dist/copy-command.cjs.map +1 -1
- package/dist/copy-command.js.map +1 -1
- package/dist/core/checkable.cjs +1 -1
- package/dist/core/checkable.cjs.map +1 -1
- package/dist/core/checkable.d.ts.map +1 -1
- package/dist/core/checkable.js +4 -4
- package/dist/core/checkable.js.map +1 -1
- package/dist/core/choice-field.cjs +1 -1
- package/dist/core/choice-field.cjs.map +1 -1
- package/dist/core/choice-field.d.ts.map +1 -1
- package/dist/core/choice-field.js +1 -2
- package/dist/core/choice-field.js.map +1 -1
- package/dist/core/date-picker.cjs +1 -1
- package/dist/core/date-picker.cjs.map +1 -1
- package/dist/core/date-picker.d.ts.map +1 -1
- package/dist/core/date-picker.js +3 -3
- package/dist/core/date-picker.js.map +1 -1
- package/dist/core/index.d.ts +17 -17
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/option-list.cjs +1 -1
- package/dist/core/option-list.cjs.map +1 -1
- package/dist/core/option-list.d.ts.map +1 -1
- package/dist/core/option-list.js +4 -4
- package/dist/core/option-list.js.map +1 -1
- package/dist/core/ref-callback.cjs +1 -1
- package/dist/core/ref-callback.cjs.map +1 -1
- package/dist/core/ref-callback.d.ts.map +1 -1
- package/dist/core/ref-callback.js +1 -1
- package/dist/core/ref-callback.js.map +1 -1
- package/dist/core/signals.cjs +1 -1
- package/dist/core/signals.cjs.map +1 -1
- package/dist/core/signals.d.ts.map +1 -1
- package/dist/core/signals.js +1 -2
- package/dist/core/signals.js.map +1 -1
- package/dist/core/slider.cjs.map +1 -1
- package/dist/core/slider.d.ts.map +1 -1
- package/dist/core/slider.js.map +1 -1
- package/dist/core/spinner.cjs.map +1 -1
- package/dist/core/spinner.d.ts.map +1 -1
- package/dist/core/spinner.js.map +1 -1
- package/dist/core/text-field.cjs +1 -1
- package/dist/core/text-field.cjs.map +1 -1
- package/dist/core/text-field.js +1 -1
- package/dist/core/text-field.js.map +1 -1
- package/dist/custom-elements.json +6036 -6036
- package/dist/datagrid.cjs +114 -114
- package/dist/datagrid.cjs.map +1 -1
- package/dist/datagrid.js +42 -43
- package/dist/datagrid.js.map +1 -1
- package/dist/date-picker.cjs.map +1 -1
- package/dist/date-picker.js.map +1 -1
- package/dist/dialog.cjs.map +1 -1
- package/dist/dialog.js.map +1 -1
- package/dist/disclosure/accordion/accordion.d.ts.map +1 -1
- package/dist/disclosure/accordion-item/accordion-item.css.cjs +1 -1
- package/dist/disclosure/accordion-item/accordion-item.css.cjs.map +1 -1
- package/dist/disclosure/accordion-item/accordion-item.css.js +1 -1
- package/dist/disclosure/accordion-item/accordion-item.css.js.map +1 -1
- package/dist/disclosure/index.d.ts +6 -6
- package/dist/disclosure/index.d.ts.map +1 -1
- package/dist/disclosure/tab-item/tab-item.css.cjs.map +1 -1
- package/dist/disclosure/tab-item/tab-item.css.js.map +1 -1
- package/dist/disclosure/tab-item/tab-item.d.ts.map +1 -1
- package/dist/disclosure/tabs/tabs.css.cjs +1 -1
- package/dist/disclosure/tabs/tabs.css.cjs.map +1 -1
- package/dist/disclosure/tabs/tabs.css.js +1 -1
- package/dist/disclosure/tabs/tabs.css.js.map +1 -1
- package/dist/disclosure/tabs/tabs.d.ts.map +1 -1
- package/dist/drawer.cjs +5 -5
- package/dist/drawer.cjs.map +1 -1
- package/dist/drawer.js +26 -26
- package/dist/drawer.js.map +1 -1
- package/dist/feedback/alert/alert.css.cjs +1 -1
- package/dist/feedback/alert/alert.css.js +1 -1
- package/dist/feedback/async/async.d.ts +1 -1
- package/dist/feedback/async/async.d.ts.map +1 -1
- package/dist/feedback/badge/badge.css.cjs +1 -1
- package/dist/feedback/badge/badge.css.js +1 -1
- package/dist/feedback/badge/badge.d.ts.map +1 -1
- package/dist/feedback/chip/chip.css.cjs.map +1 -1
- package/dist/feedback/chip/chip.css.js.map +1 -1
- package/dist/feedback/chip/chip.d.ts.map +1 -1
- package/dist/feedback/index.d.ts +12 -12
- package/dist/feedback/index.d.ts.map +1 -1
- package/dist/feedback/progress/progress.d.ts.map +1 -1
- package/dist/feedback/skeleton/skeleton.d.ts.map +1 -1
- package/dist/feedback/toast/index.d.ts +1 -1
- package/dist/feedback/toast/index.d.ts.map +1 -1
- package/dist/feedback/toast/toast.css.cjs +1 -1
- package/dist/feedback/toast/toast.css.cjs.map +1 -1
- package/dist/feedback/toast/toast.css.js +1 -1
- package/dist/feedback/toast/toast.css.js.map +1 -1
- package/dist/feedback/toast/toast.d.ts +1 -1
- package/dist/feedback/toast/toast.d.ts.map +1 -1
- package/dist/feedback/typing-indicator/typing-indicator.d.ts.map +1 -1
- package/dist/file-input.cjs +67 -67
- package/dist/file-input.cjs.map +1 -1
- package/dist/file-input.js +129 -130
- package/dist/file-input.js.map +1 -1
- package/dist/grid.cjs.map +1 -1
- package/dist/grid.js.map +1 -1
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js.map +1 -1
- package/dist/input.cjs +21 -21
- package/dist/input.cjs.map +1 -1
- package/dist/input.js +58 -58
- package/dist/input.js.map +1 -1
- package/dist/inputs/button/button.css.cjs +1 -1
- package/dist/inputs/button/button.css.js +1 -1
- package/dist/inputs/button/button.d.ts.map +1 -1
- package/dist/inputs/button-group/button-group.css.cjs.map +1 -1
- package/dist/inputs/button-group/button-group.css.js.map +1 -1
- package/dist/inputs/button-group/button-group.d.ts +1 -1
- package/dist/inputs/button-group/button-group.d.ts.map +1 -1
- package/dist/inputs/calendar/calendar.css.cjs +1 -1
- package/dist/inputs/calendar/calendar.css.cjs.map +1 -1
- package/dist/inputs/calendar/calendar.css.js +1 -1
- package/dist/inputs/calendar/calendar.css.js.map +1 -1
- package/dist/inputs/calendar/calendar.d.ts.map +1 -1
- package/dist/inputs/checkbox/checkbox.css.cjs +1 -1
- package/dist/inputs/checkbox/checkbox.css.js +1 -1
- package/dist/inputs/checkbox/checkbox.d.ts.map +1 -1
- package/dist/inputs/checkbox-group/checkbox-group.d.ts +1 -1
- package/dist/inputs/checkbox-group/checkbox-group.d.ts.map +1 -1
- package/dist/inputs/combobox/combobox.css.cjs +1 -1
- package/dist/inputs/combobox/combobox.css.js +1 -1
- package/dist/inputs/combobox/combobox.d.ts.map +1 -1
- package/dist/inputs/datagrid/datagrid-column.cjs.map +1 -1
- package/dist/inputs/datagrid/datagrid-column.d.ts.map +1 -1
- package/dist/inputs/datagrid/datagrid-column.js.map +1 -1
- package/dist/inputs/datagrid/datagrid-model.cjs +1 -1
- package/dist/inputs/datagrid/datagrid-model.cjs.map +1 -1
- package/dist/inputs/datagrid/datagrid-model.d.ts.map +1 -1
- package/dist/inputs/datagrid/datagrid-model.js +1 -2
- package/dist/inputs/datagrid/datagrid-model.js.map +1 -1
- package/dist/inputs/datagrid/datagrid.css.cjs +1 -1
- package/dist/inputs/datagrid/datagrid.css.cjs.map +1 -1
- package/dist/inputs/datagrid/datagrid.css.js +1 -1
- package/dist/inputs/datagrid/datagrid.css.js.map +1 -1
- package/dist/inputs/datagrid/datagrid.d.ts +1 -1
- package/dist/inputs/datagrid/datagrid.d.ts.map +1 -1
- package/dist/inputs/date-picker/date-picker.css.cjs +1 -1
- package/dist/inputs/date-picker/date-picker.css.cjs.map +1 -1
- package/dist/inputs/date-picker/date-picker.css.js +1 -1
- package/dist/inputs/date-picker/date-picker.css.js.map +1 -1
- package/dist/inputs/date-picker/date-picker.d.ts.map +1 -1
- package/dist/inputs/file-input/file-input-upload.cjs +1 -1
- package/dist/inputs/file-input/file-input-upload.cjs.map +1 -1
- package/dist/inputs/file-input/file-input-upload.d.ts.map +1 -1
- package/dist/inputs/file-input/file-input-upload.js +2 -3
- package/dist/inputs/file-input/file-input-upload.js.map +1 -1
- package/dist/inputs/file-input/file-input.css.cjs +1 -1
- package/dist/inputs/file-input/file-input.css.js +1 -1
- package/dist/inputs/file-input/file-input.d.ts.map +1 -1
- package/dist/inputs/index.d.ts +28 -28
- package/dist/inputs/index.d.ts.map +1 -1
- package/dist/inputs/input/input.css.cjs +1 -1
- package/dist/inputs/input/input.css.js +1 -1
- package/dist/inputs/input/input.d.ts.map +1 -1
- package/dist/inputs/message-composer/message-composer.css.cjs +1 -1
- package/dist/inputs/message-composer/message-composer.css.js +1 -1
- package/dist/inputs/message-composer/message-composer.d.ts +1 -1
- package/dist/inputs/message-composer/message-composer.d.ts.map +1 -1
- package/dist/inputs/number-input/number-input.d.ts.map +1 -1
- package/dist/inputs/otp-input/otp-input.d.ts.map +1 -1
- package/dist/inputs/radio/radio.css.cjs +1 -1
- package/dist/inputs/radio/radio.css.js +1 -1
- package/dist/inputs/radio/radio.d.ts.map +1 -1
- package/dist/inputs/radio-group/radio-group.d.ts +2 -2
- package/dist/inputs/radio-group/radio-group.d.ts.map +1 -1
- package/dist/inputs/rating/rating.d.ts.map +1 -1
- package/dist/inputs/select/select.css.cjs +1 -1
- package/dist/inputs/select/select.css.js +1 -1
- package/dist/inputs/select/select.d.ts.map +1 -1
- package/dist/inputs/shared/field-binding.cjs.map +1 -1
- package/dist/inputs/shared/field-binding.d.ts.map +1 -1
- package/dist/inputs/shared/field-binding.js.map +1 -1
- package/dist/inputs/shared/templates.cjs.map +1 -1
- package/dist/inputs/shared/templates.d.ts.map +1 -1
- package/dist/inputs/shared/templates.js.map +1 -1
- package/dist/inputs/slider/slider.d.ts.map +1 -1
- package/dist/inputs/switch/switch.css.cjs +1 -1
- package/dist/inputs/switch/switch.css.js +1 -1
- package/dist/inputs/switch/switch.d.ts.map +1 -1
- package/dist/inputs/textarea/textarea.css.cjs +1 -1
- package/dist/inputs/textarea/textarea.css.js +1 -1
- package/dist/inputs/textarea/textarea.d.ts.map +1 -1
- package/dist/inputs/time-picker/time-picker.css.cjs +1 -1
- package/dist/inputs/time-picker/time-picker.css.cjs.map +1 -1
- package/dist/inputs/time-picker/time-picker.css.js +1 -1
- package/dist/inputs/time-picker/time-picker.css.js.map +1 -1
- package/dist/inputs/time-picker/time-picker.d.ts.map +1 -1
- package/dist/layout/box/box.d.ts.map +1 -1
- package/dist/layout/grid/grid.d.ts.map +1 -1
- package/dist/layout/index.d.ts +6 -6
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/navbar/navbar.css.cjs +1 -1
- package/dist/layout/navbar/navbar.css.js +1 -1
- package/dist/layout/navbar/navbar.d.ts.map +1 -1
- package/dist/layout/sidebar/sidebar-group.css.cjs +1 -1
- package/dist/layout/sidebar/sidebar-group.css.cjs.map +1 -1
- package/dist/layout/sidebar/sidebar-group.css.js +1 -1
- package/dist/layout/sidebar/sidebar-group.css.js.map +1 -1
- package/dist/layout/sidebar/sidebar.css.cjs +1 -1
- package/dist/layout/sidebar/sidebar.css.cjs.map +1 -1
- package/dist/layout/sidebar/sidebar.css.js +1 -1
- package/dist/layout/sidebar/sidebar.css.js.map +1 -1
- package/dist/layout/sidebar/sidebar.d.ts.map +1 -1
- package/dist/list-item.cjs.map +1 -1
- package/dist/list-item.js.map +1 -1
- package/dist/list.cjs +2 -2
- package/dist/list.cjs.map +1 -1
- package/dist/list.js +15 -16
- package/dist/list.js.map +1 -1
- package/dist/marquee.cjs +1 -1
- package/dist/marquee.cjs.map +1 -1
- package/dist/marquee.js +1 -1
- package/dist/marquee.js.map +1 -1
- package/dist/menu.cjs +5 -5
- package/dist/menu.cjs.map +1 -1
- package/dist/menu.js +38 -39
- package/dist/menu.js.map +1 -1
- package/dist/message-composer.cjs +16 -16
- package/dist/message-composer.cjs.map +1 -1
- package/dist/message-composer.js +61 -61
- package/dist/message-composer.js.map +1 -1
- package/dist/navbar.cjs +9 -9
- package/dist/navbar.cjs.map +1 -1
- package/dist/navbar.js +1 -2
- package/dist/navbar.js.map +1 -1
- package/dist/navigation-menu.cjs +5 -5
- package/dist/navigation-menu.cjs.map +1 -1
- package/dist/navigation-menu.js +33 -34
- package/dist/navigation-menu.js.map +1 -1
- package/dist/number-input.cjs +24 -24
- package/dist/number-input.cjs.map +1 -1
- package/dist/number-input.js +41 -42
- package/dist/number-input.js.map +1 -1
- package/dist/otp-input.cjs +13 -13
- package/dist/otp-input.cjs.map +1 -1
- package/dist/otp-input.js +32 -33
- package/dist/otp-input.js.map +1 -1
- package/dist/overlay/command-palette/command-palette-items.cjs.map +1 -1
- package/dist/overlay/command-palette/command-palette-items.d.ts.map +1 -1
- package/dist/overlay/command-palette/command-palette-items.js.map +1 -1
- package/dist/overlay/command-palette/command-palette.css.cjs +1 -1
- package/dist/overlay/command-palette/command-palette.css.cjs.map +1 -1
- package/dist/overlay/command-palette/command-palette.css.js +1 -1
- package/dist/overlay/command-palette/command-palette.css.js.map +1 -1
- package/dist/overlay/command-palette/command-palette.d.ts.map +1 -1
- package/dist/overlay/dialog/dialog.css.cjs +1 -1
- package/dist/overlay/dialog/dialog.css.js +1 -1
- package/dist/overlay/dialog/dialog.d.ts.map +1 -1
- package/dist/overlay/drawer/drawer.css.cjs +1 -1
- package/dist/overlay/drawer/drawer.css.js +1 -1
- package/dist/overlay/drawer/drawer.d.ts +2 -2
- package/dist/overlay/drawer/drawer.d.ts.map +1 -1
- package/dist/overlay/index.d.ts +6 -6
- package/dist/overlay/index.d.ts.map +1 -1
- package/dist/overlay/menu/menu.css.cjs +1 -1
- package/dist/overlay/menu/menu.css.js +1 -1
- package/dist/overlay/menu/menu.d.ts +2 -2
- package/dist/overlay/menu/menu.d.ts.map +1 -1
- package/dist/overlay/navigation-menu/navigation-menu.d.ts.map +1 -1
- package/dist/overlay/popover/popover.d.ts +1 -1
- package/dist/overlay/popover/popover.d.ts.map +1 -1
- package/dist/overlay/shared/use-dialog.cjs +1 -1
- package/dist/overlay/shared/use-dialog.cjs.map +1 -1
- package/dist/overlay/shared/use-dialog.d.ts.map +1 -1
- package/dist/overlay/shared/use-dialog.js +4 -5
- package/dist/overlay/shared/use-dialog.js.map +1 -1
- package/dist/overlay/shared/use-floating-trigger.cjs +1 -1
- package/dist/overlay/shared/use-floating-trigger.cjs.map +1 -1
- package/dist/overlay/shared/use-floating-trigger.d.ts.map +1 -1
- package/dist/overlay/shared/use-floating-trigger.js +1 -2
- package/dist/overlay/shared/use-floating-trigger.js.map +1 -1
- package/dist/overlay/tooltip/tooltip.d.ts +1 -1
- package/dist/overlay/tooltip/tooltip.d.ts.map +1 -1
- package/dist/pagination.cjs.map +1 -1
- package/dist/pagination.js.map +1 -1
- package/dist/popover.cjs +1 -1
- package/dist/popover.cjs.map +1 -1
- package/dist/popover.js +0 -1
- package/dist/popover.js.map +1 -1
- package/dist/progress.cjs.map +1 -1
- package/dist/progress.js.map +1 -1
- package/dist/radio-group.cjs +5 -5
- package/dist/radio-group.cjs.map +1 -1
- package/dist/radio-group.js +26 -27
- package/dist/radio-group.js.map +1 -1
- package/dist/radio.cjs +2 -2
- package/dist/radio.cjs.map +1 -1
- package/dist/radio.js +41 -41
- package/dist/radio.js.map +1 -1
- package/dist/rating.cjs +4 -4
- package/dist/rating.cjs.map +1 -1
- package/dist/rating.js +36 -36
- package/dist/rating.js.map +1 -1
- package/dist/refine.cjs +686 -686
- package/dist/refine.cjs.map +1 -1
- package/dist/refine.iife.js +686 -686
- package/dist/refine.iife.js.map +1 -1
- package/dist/refine.js +737 -737
- package/dist/refine.js.map +1 -1
- package/dist/select.cjs +42 -42
- package/dist/select.cjs.map +1 -1
- package/dist/select.js +146 -147
- package/dist/select.js.map +1 -1
- package/dist/separator.cjs.map +1 -1
- package/dist/separator.js.map +1 -1
- package/dist/sidebar.cjs +17 -17
- package/dist/sidebar.cjs.map +1 -1
- package/dist/sidebar.js +7 -8
- package/dist/sidebar.js.map +1 -1
- package/dist/skeleton.cjs +3 -3
- package/dist/skeleton.cjs.map +1 -1
- package/dist/skeleton.js +1 -2
- package/dist/skeleton.js.map +1 -1
- package/dist/slider.cjs +12 -12
- package/dist/slider.cjs.map +1 -1
- package/dist/slider.js +54 -55
- package/dist/slider.js.map +1 -1
- package/dist/step.cjs.map +1 -1
- package/dist/step.js.map +1 -1
- package/dist/stepper.cjs +2 -2
- package/dist/stepper.cjs.map +1 -1
- package/dist/stepper.js +8 -7
- package/dist/stepper.js.map +1 -1
- package/dist/styles/index.d.ts +2 -2
- package/dist/styles/index.d.ts.map +1 -1
- package/dist/styles/preflight.css +1 -1
- package/dist/styles/theme.css +15 -30
- package/dist/switch.cjs +3 -3
- package/dist/switch.cjs.map +1 -1
- package/dist/switch.js +28 -28
- package/dist/switch.js.map +1 -1
- package/dist/tab-item.cjs +2 -2
- package/dist/tab-item.cjs.map +1 -1
- package/dist/tab-item.js +21 -21
- package/dist/tab-item.js.map +1 -1
- package/dist/tab-panel.cjs +2 -2
- package/dist/tab-panel.cjs.map +1 -1
- package/dist/tab-panel.js +9 -9
- package/dist/tab-panel.js.map +1 -1
- package/dist/table.cjs +1 -1
- package/dist/table.cjs.map +1 -1
- package/dist/table.js +1 -1
- package/dist/table.js.map +1 -1
- package/dist/tabs.cjs +6 -6
- package/dist/tabs.cjs.map +1 -1
- package/dist/tabs.js +14 -15
- package/dist/tabs.js.map +1 -1
- package/dist/textarea.cjs +11 -11
- package/dist/textarea.cjs.map +1 -1
- package/dist/textarea.js +59 -59
- package/dist/textarea.js.map +1 -1
- package/dist/time-picker.cjs.map +1 -1
- package/dist/time-picker.js.map +1 -1
- package/dist/toast.cjs +16 -16
- package/dist/toast.cjs.map +1 -1
- package/dist/toast.js +20 -21
- package/dist/toast.js.map +1 -1
- package/dist/tooltip.cjs.map +1 -1
- package/dist/tooltip.js.map +1 -1
- package/dist/typing-indicator.cjs +1 -1
- package/dist/typing-indicator.cjs.map +1 -1
- package/dist/typing-indicator.js +1 -1
- package/dist/typing-indicator.js.map +1 -1
- package/package.json +96 -97
package/dist/list-item.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-item.js","names":[],"sources":["../src/content/list/list-item.ts"],"sourcesContent":["import { define, html, inject, prop, bind, getHost, onCleanup, useEmit, useSlots, watchEffect } from '@vielzeug/ore';\nimport { computed } from '@vielzeug/ripple';\n\nimport { disablableBundle } from '../../shared';\nimport { reducedMotionMixin } from '../../styles';\nimport { createRevealState } from './_list-item-reveal';\nimport { LIST_CTX } from './list';\nimport componentStyles from './list-item.css?inline';\n\n/** Which side's action panel is currently revealed on a list item. */\nexport type ListItemRevealSide = 'left' | 'right';\n\n/** Events emitted by the list-item component */\nexport type OreListItemEvents = {\n /** Emitted when the revealed action panel closes (gesture, tap, or programmatic). */\n conceal: { item: HTMLElement };\n /**\n * Emitted when a swipe crosses the full-swipe-through distance — the \"swiped all the way\"\n * confirm gesture. Fired just before the slotted action's own click (if any).\n */\n confirm: { item: HTMLElement; side: ListItemRevealSide };\n /** Emitted when the item becomes deselected. */\n deselect: { item: HTMLElement; value: null | string };\n /** Emitted when a swipe/focus reveals an action panel. */\n reveal: { item: HTMLElement; side: ListItemRevealSide };\n /** Emitted when the item becomes selected (only meaningful inside a `selectable` `ore-list`). */\n select: { item: HTMLElement; value: null | string };\n};\n\n/** List-item component properties */\nexport type OreListItemProps = {\n /** Disable this item — blocks pointer interaction, swipe actions, and selection */\n disabled?: boolean;\n /** Which action panel is revealed: 'left' | 'right' (absent = closed). Settable programmatically. */\n revealed?: ListItemRevealSide;\n /**\n * Opaque value compared against the parent `selectable` `ore-list`'s own `value` to derive\n * `selected` — required for selection to work. There's no separate `selected` prop: the parent\n * list's `value` is the single source of truth, so this item's selected state can't drift from\n * it. Also reported in `select`/`deselect`/the parent's `change` event.\n */\n value?: string;\n};\n\n/** Maps a reveal side to its slot name — the one place this pairing is spelled out. */\nconst actionSlot = (side: ListItemRevealSide): 'actions-left' | 'actions-right' =>\n side === 'left' ? 'actions-left' : 'actions-right';\n\n/**\n * A single row inside `ore-list`. Renders `leading`/default (title)/`description`/`trailing`\n * content plus two off-canvas action panels (`actions-left`, `actions-right`) that a horizontal\n * pointer/touch swipe reveals — useful for mobile-style row actions (archive, delete, …). An\n * action panel only opens if it actually has slotted content; swiping the other direction is a\n * no-op. Revealed actions stay reachable from the keyboard (Tab focus on a slotted action button\n * reveals its panel via `:focus-within`, independent of any gesture).\n *\n * Swiping past the reveal distance snaps the panel fully open on release; swiping further still —\n * past the full-swipe-through distance — auto-confirms that side's action immediately (fires\n * `confirm` and clicks the slot's first element), the same \"swipe all the way\" shortcut as iOS\n * Mail's delete gesture.\n *\n * Closing a revealed panel is deliberately one-directional: tap/click the row itself, tap outside\n * the item, or open a different item's panel. Reverse-swiping an already-open item is not\n * supported — see `ore-list`'s docs for the reasoning.\n *\n * @element ore-list-item\n *\n * @attr {boolean} disabled - Disable this item\n * @attr {boolean} selected - Read-only reflected attribute: `true` when this item's `value` matches the parent `ore-list`'s `value`. Not independently settable.\n * @attr {string} value - Opaque value compared against the parent list's `value` to derive `selected`; also reported in select/change events\n * @attr {string} revealed - Which action panel is revealed: 'left' | 'right'\n *\n * @fires select - Item becomes selected. detail: { item: HTMLElement, value: string | null }\n * @fires deselect - Item becomes deselected. detail: { item: HTMLElement, value: string | null }\n * @fires reveal - An action panel opens. detail: { item: HTMLElement, side: 'left' | 'right' }\n * @fires conceal - The revealed action panel closes. detail: { item: HTMLElement }\n * @fires confirm - Swiped all the way through — fires before the slotted action's own click. detail: { item: HTMLElement, side: 'left' | 'right' }\n *\n * @slot leading - Content before the title (e.g. icon, avatar)\n * @slot - Item title\n * @slot description - Secondary line below the title\n * @slot trailing - Content after the title (e.g. meta text, chevron)\n * @slot actions-left - Buttons revealed by swiping right (or focusing into this slot)\n * @slot actions-right - Buttons revealed by swiping left (or focusing into this slot)\n *\n * @cssprop --list-item-actions-width - Width of each action panel (default 6rem)\n * @cssprop --list-item-bg - Row background color\n * @cssprop --list-item-hover-bg - Row background on hover\n * @cssprop --list-item-selected-bg - Row background when selected\n * @part row - The row wrapper (focusable, swipeable)\n * @part leading - The leading slot container\n * @part content - The title + description container\n * @part title - The title slot container\n * @part description - The description slot container\n * @part trailing - The trailing slot container\n * @part actions-start - The left action panel container\n * @part actions-end - The right action panel container\n * @example\n * ```html\n * <ore-list-item>\n * <ore-icon slot=\"leading\" name=\"mail\"></ore-icon>\n * Inbox\n * <span slot=\"trailing\">12</span>\n * </ore-list-item>\n * <ore-list-item>\n * Newsletter\n * <span slot=\"description\">From Acme Inc.</span>\n * <ore-button slot=\"actions-right\" color=\"error\">Delete</ore-button>\n * </ore-list-item>\n * ```\n */\nexport const LIST_ITEM_TAG = 'ore-list-item' as const;\ndefine<OreListItemProps>(LIST_ITEM_TAG, {\n props: {\n ...disablableBundle,\n revealed: prop.oneOf<ListItemRevealSide | undefined>(['left', 'right'], undefined),\n value: prop.string(),\n },\n\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreListItemEvents>();\n const slots = useSlots<'actions-left' | 'actions-right' | 'description' | 'leading' | 'trailing'>();\n\n const listCtx = inject(LIST_CTX);\n const isSelectable = computed(() => Boolean(listCtx?.selectable.value));\n // Derived, not owned: `ore-list`'s `value` is the single source of truth, so this can never\n // drift out of sync with a sibling the way an independently-settable `selected` prop could.\n const isSelected = computed(\n () => props.value.value != null && listCtx != null && listCtx.value.value === props.value.value,\n );\n\n const hasActions = (side: ListItemRevealSide): boolean => slots.has(actionSlot(side)).value;\n\n const swipe = createRevealState(el, {\n disabled: computed(() => props.disabled.value || Boolean(props.revealed.value)),\n hasActions,\n // Clicks the slot's own first element (the common case: a single action button) so its own\n // click handler runs the real action — `confirm` covers slots without a clickable element.\n onConfirm: (side) => {\n const target = slots.elements(actionSlot(side)).value[0] as HTMLElement | undefined;\n\n emit('confirm', { item: el, side });\n target?.click();\n },\n });\n\n onCleanup(() => swipe.dispose());\n\n // Reflects the derived `selected` state as a plain boolean attribute — the styling/\n // `[selected]`-selector hook — the same way `prop.bool()`'s own reflection would, since it\n // isn't a real settable prop anymore.\n watchEffect(() => {\n el.toggleAttribute('selected', isSelected.value);\n });\n\n // Emits select/deselect/reveal/conceal for both gesture-driven AND externally-set (attribute,\n // or the parent list's `value`) state changes — the plain-reflected-prop equivalent of\n // ore-accordion-item's native <details> `toggle`-event listener (there's no backing native\n // element here to piggyback on).\n let lastSelected = isSelected.value;\n\n watchEffect(() => {\n const current = isSelected.value;\n\n if (current === lastSelected) return;\n\n lastSelected = current;\n emit(current ? 'select' : 'deselect', { item: el, value: props.value.value ?? null });\n });\n\n let lastRevealed = props.revealed.value ?? null;\n\n watchEffect(() => {\n const current = props.revealed.value ?? null;\n\n if (current === lastRevealed) return;\n\n lastRevealed = current;\n\n if (current) {\n // Only one item may have its swipe actions revealed at a time — tell the list directly\n // instead of dispatching an event for it to listen for.\n listCtx?.requestReveal(el);\n emit('reveal', { item: el, side: current });\n } else {\n emit('conceal', { item: el });\n }\n });\n\n const handleActivate = (event: Event): void => {\n if (props.disabled.value) return;\n\n if (props.revealed.value) {\n event.preventDefault();\n event.stopPropagation();\n el.removeAttribute('revealed');\n\n return;\n }\n\n if (!isSelectable.value) return;\n\n const value = props.value.value;\n\n // Re-clicking an already-selected item deselects it; a value is required to select at all\n // (undefined would otherwise match every valueless item at once).\n if (value != null) listCtx?.select(isSelected.value ? undefined : value);\n };\n\n const handleRowKeydown = (event: KeyboardEvent): void => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n\n if (props.disabled.value || (!props.revealed.value && !isSelectable.value)) return;\n\n event.preventDefault();\n handleActivate(event);\n };\n\n bind({\n attr: {\n 'aria-disabled': () => (props.disabled.value ? 'true' : null),\n 'aria-selected': () => (isSelectable.value ? String(isSelected.value) : null),\n role: () => (isSelectable.value ? 'option' : 'listitem'),\n },\n });\n\n return html`\n <div\n class=\"row\"\n part=\"row\"\n tabindex=\"${() => (props.disabled.value ? '-1' : '0')}\"\n @click=\"${handleActivate}\"\n @keydown=\"${handleRowKeydown}\"\n @pointercancel=\"${(e: PointerEvent) => swipe.handlePointerCancel(e)}\"\n @pointerdown=\"${(e: PointerEvent) => swipe.handlePointerDown(e)}\"\n @pointermove=\"${(e: PointerEvent) => swipe.handlePointerMove(e)}\"\n @pointerup=\"${(e: PointerEvent) => swipe.handlePointerUp(e)}\">\n <span class=\"leading\" part=\"leading\"><slot name=\"leading\"></slot></span>\n <span class=\"content\" part=\"content\">\n <span class=\"title\" part=\"title\"><slot></slot></span>\n <span class=\"description\" part=\"description\"><slot name=\"description\"></slot></span>\n </span>\n <span class=\"trailing\" part=\"trailing\"><slot name=\"trailing\"></slot></span>\n </div>\n <span class=\"actions actions-left\" part=\"actions-start\"><slot name=\"actions-left\"></slot></span>\n <span class=\"actions actions-right\" part=\"actions-end\"><slot name=\"actions-right\"></slot></span>\n `;\n },\n\n shadow: { delegatesFocus: true },\n styles: [reducedMotionMixin, componentStyles],\n});\n"],"mappings":";;;;;;;;AA6CA,IAAM,KAAc,MAClB,MAAS,SAAS,iBAAiB,iBAiExB,IAAgB;AAC7B,EAAyB,GAAe;CACtC,OAAO;EACL,GAAG;EACH,UAAU,EAAK,MAAsC,CAAC,QAAQ,OAAO,GAAG,KAAA,CAAS;EACjF,OAAO,EAAK,OAAO;CACrB;CAEA,MAAM,GAAO;EACX,IAAM,IAAK,EAAQ,GACb,IAAO,EAA2B,GAClC,IAAQ,EAAoF,GAE5F,IAAU,EAAO,CAAQ,GACzB,IAAe,QAAe,EAAQ,GAAS,WAAW,KAAM,GAGhE,IAAa,QACX,EAAM,MAAM,SAAS,QAAQ,KAAW,QAAQ,EAAQ,MAAM,UAAU,EAAM,MAAM,KAC5F,GAIM,IAAQ,EAAkB,GAAI;GAClC,UAAU,QAAe,EAAM,SAAS,SAAS,EAAQ,EAAM,SAAS,KAAM;GAC9E,aAJkB,MAAsC,EAAM,IAAI,EAAW,CAAI,CAAC,CAAC,CAAC;GAOpF,YAAY,MAAS;IACnB,IAAM,IAAS,EAAM,SAAS,EAAW,CAAI,CAAC,CAAC,CAAC,MAAM;IAGtD,AADA,EAAK,WAAW;KAAE,MAAM;KAAI;IAAK,CAAC,GAClC,GAAQ,MAAM;GAChB;EACF,CAAC;EAOD,AALA,QAAgB,EAAM,QAAQ,CAAC,GAK/B,QAAkB;GAChB,EAAG,gBAAgB,YAAY,EAAW,KAAK;EACjD,CAAC;EAMD,IAAI,IAAe,EAAW;EAE9B,QAAkB;GAChB,IAAM,IAAU,EAAW;GAEvB,MAAY,MAEhB,IAAe,GACf,EAAK,IAAU,WAAW,YAAY;IAAE,MAAM;IAAI,OAAO,EAAM,MAAM,SAAS;GAAK,CAAC;EACtF,CAAC;EAED,IAAI,IAAe,EAAM,SAAS,SAAS;EAE3C,QAAkB;GAChB,IAAM,IAAU,EAAM,SAAS,SAAS;GAEpC,MAAY,MAEhB,IAAe,GAEX,KAGF,GAAS,cAAc,CAAE,GACzB,EAAK,UAAU;IAAE,MAAM;IAAI,MAAM;GAAQ,CAAC,KAE1C,EAAK,WAAW,EAAE,MAAM,EAAG,CAAC;EAEhC,CAAC;EAED,IAAM,KAAkB,MAAuB;GAC7C,IAAI,EAAM,SAAS,OAAO;GAE1B,IAAI,EAAM,SAAS,OAAO;IAGxB,AAFA,EAAM,eAAe,GACrB,EAAM,gBAAgB,GACtB,EAAG,gBAAgB,UAAU;IAE7B;GACF;GAEA,IAAI,CAAC,EAAa,OAAO;GAEzB,IAAM,IAAQ,EAAM,MAAM;GAI1B,AAAI,KAAS,QAAM,GAAS,OAAO,EAAW,QAAQ,KAAA,IAAY,CAAK;EACzE;EAmBA,OARA,EAAK,EACH,MAAM;GACJ,uBAAwB,EAAM,SAAS,QAAQ,SAAS;GACxD,uBAAwB,EAAa,QAAQ,OAAO,EAAW,KAAK,IAAI;GACxE,YAAa,EAAa,QAAQ,WAAW;EAC/C,EACF,CAAC,GAEM,CAAI;;;;0BAIY,EAAM,SAAS,QAAQ,OAAO,IAAK;kBAC5C,EAAe;qBAtBH,MAA+B;GACnD,GAAM,QAAQ,WAAW,EAAM,QAAQ,SAEvC,EAAM,SAAS,SAAU,CAAC,EAAM,SAAS,SAAS,CAAC,EAAa,UAEpE,EAAM,eAAe,GACrB,EAAe,CAAK;EACtB,EAgBiC;2BACV,MAAoB,EAAM,oBAAoB,CAAC,EAAE;yBACnD,MAAoB,EAAM,kBAAkB,CAAC,EAAE;yBAC/C,MAAoB,EAAM,kBAAkB,CAAC,EAAE;uBACjD,MAAoB,EAAM,gBAAgB,CAAC,EAAE;;;;;;;;;;;CAWlE;CAEA,QAAQ,EAAE,gBAAgB,GAAK;CAC/B,QAAQ,CAAC,GAAoB,CAAe;AAC9C,CAAC"}
|
|
1
|
+
{"version":3,"file":"list-item.js","names":[],"sources":["../src/content/list/list-item.ts"],"sourcesContent":["import { bind, define, getHost, html, inject, onCleanup, prop, useEmit, useSlots, watchEffect } from '@vielzeug/ore';\nimport { computed } from '@vielzeug/ripple';\n\nimport { disablableBundle } from '../../shared';\nimport { reducedMotionMixin } from '../../styles';\nimport { createRevealState } from './_list-item-reveal';\nimport { LIST_CTX } from './list';\nimport componentStyles from './list-item.css?inline';\n\n/** Which side's action panel is currently revealed on a list item. */\nexport type ListItemRevealSide = 'left' | 'right';\n\n/** Events emitted by the list-item component */\nexport type OreListItemEvents = {\n /** Emitted when the revealed action panel closes (gesture, tap, or programmatic). */\n conceal: { item: HTMLElement };\n /**\n * Emitted when a swipe crosses the full-swipe-through distance — the \"swiped all the way\"\n * confirm gesture. Fired just before the slotted action's own click (if any).\n */\n confirm: { item: HTMLElement; side: ListItemRevealSide };\n /** Emitted when the item becomes deselected. */\n deselect: { item: HTMLElement; value: null | string };\n /** Emitted when a swipe/focus reveals an action panel. */\n reveal: { item: HTMLElement; side: ListItemRevealSide };\n /** Emitted when the item becomes selected (only meaningful inside a `selectable` `ore-list`). */\n select: { item: HTMLElement; value: null | string };\n};\n\n/** List-item component properties */\nexport type OreListItemProps = {\n /** Disable this item — blocks pointer interaction, swipe actions, and selection */\n disabled?: boolean;\n /** Which action panel is revealed: 'left' | 'right' (absent = closed). Settable programmatically. */\n revealed?: ListItemRevealSide;\n /**\n * Opaque value compared against the parent `selectable` `ore-list`'s own `value` to derive\n * `selected` — required for selection to work. There's no separate `selected` prop: the parent\n * list's `value` is the single source of truth, so this item's selected state can't drift from\n * it. Also reported in `select`/`deselect`/the parent's `change` event.\n */\n value?: string;\n};\n\n/** Maps a reveal side to its slot name — the one place this pairing is spelled out. */\nconst actionSlot = (side: ListItemRevealSide): 'actions-left' | 'actions-right' =>\n side === 'left' ? 'actions-left' : 'actions-right';\n\n/**\n * A single row inside `ore-list`. Renders `leading`/default (title)/`description`/`trailing`\n * content plus two off-canvas action panels (`actions-left`, `actions-right`) that a horizontal\n * pointer/touch swipe reveals — useful for mobile-style row actions (archive, delete, …). An\n * action panel only opens if it actually has slotted content; swiping the other direction is a\n * no-op. Revealed actions stay reachable from the keyboard (Tab focus on a slotted action button\n * reveals its panel via `:focus-within`, independent of any gesture).\n *\n * Swiping past the reveal distance snaps the panel fully open on release; swiping further still —\n * past the full-swipe-through distance — auto-confirms that side's action immediately (fires\n * `confirm` and clicks the slot's first element), the same \"swipe all the way\" shortcut as iOS\n * Mail's delete gesture.\n *\n * Closing a revealed panel is deliberately one-directional: tap/click the row itself, tap outside\n * the item, or open a different item's panel. Reverse-swiping an already-open item is not\n * supported — see `ore-list`'s docs for the reasoning.\n *\n * @element ore-list-item\n *\n * @attr {boolean} disabled - Disable this item\n * @attr {boolean} selected - Read-only reflected attribute: `true` when this item's `value` matches the parent `ore-list`'s `value`. Not independently settable.\n * @attr {string} value - Opaque value compared against the parent list's `value` to derive `selected`; also reported in select/change events\n * @attr {string} revealed - Which action panel is revealed: 'left' | 'right'\n *\n * @fires select - Item becomes selected. detail: { item: HTMLElement, value: string | null }\n * @fires deselect - Item becomes deselected. detail: { item: HTMLElement, value: string | null }\n * @fires reveal - An action panel opens. detail: { item: HTMLElement, side: 'left' | 'right' }\n * @fires conceal - The revealed action panel closes. detail: { item: HTMLElement }\n * @fires confirm - Swiped all the way through — fires before the slotted action's own click. detail: { item: HTMLElement, side: 'left' | 'right' }\n *\n * @slot leading - Content before the title (e.g. icon, avatar)\n * @slot - Item title\n * @slot description - Secondary line below the title\n * @slot trailing - Content after the title (e.g. meta text, chevron)\n * @slot actions-left - Buttons revealed by swiping right (or focusing into this slot)\n * @slot actions-right - Buttons revealed by swiping left (or focusing into this slot)\n *\n * @cssprop --list-item-actions-width - Width of each action panel (default 6rem)\n * @cssprop --list-item-bg - Row background color\n * @cssprop --list-item-hover-bg - Row background on hover\n * @cssprop --list-item-selected-bg - Row background when selected\n * @part row - The row wrapper (focusable, swipeable)\n * @part leading - The leading slot container\n * @part content - The title + description container\n * @part title - The title slot container\n * @part description - The description slot container\n * @part trailing - The trailing slot container\n * @part actions-start - The left action panel container\n * @part actions-end - The right action panel container\n * @example\n * ```html\n * <ore-list-item>\n * <ore-icon slot=\"leading\" name=\"mail\"></ore-icon>\n * Inbox\n * <span slot=\"trailing\">12</span>\n * </ore-list-item>\n * <ore-list-item>\n * Newsletter\n * <span slot=\"description\">From Acme Inc.</span>\n * <ore-button slot=\"actions-right\" color=\"error\">Delete</ore-button>\n * </ore-list-item>\n * ```\n */\nexport const LIST_ITEM_TAG = 'ore-list-item' as const;\ndefine<OreListItemProps>(LIST_ITEM_TAG, {\n props: {\n ...disablableBundle,\n revealed: prop.oneOf<ListItemRevealSide | undefined>(['left', 'right'], undefined),\n value: prop.string(),\n },\n\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreListItemEvents>();\n const slots = useSlots<'actions-left' | 'actions-right' | 'description' | 'leading' | 'trailing'>();\n\n const listCtx = inject(LIST_CTX);\n const isSelectable = computed(() => Boolean(listCtx?.selectable.value));\n // Derived, not owned: `ore-list`'s `value` is the single source of truth, so this can never\n // drift out of sync with a sibling the way an independently-settable `selected` prop could.\n const isSelected = computed(\n () => props.value.value != null && listCtx != null && listCtx.value.value === props.value.value,\n );\n\n const hasActions = (side: ListItemRevealSide): boolean => slots.has(actionSlot(side)).value;\n\n const swipe = createRevealState(el, {\n disabled: computed(() => props.disabled.value || Boolean(props.revealed.value)),\n hasActions,\n // Clicks the slot's own first element (the common case: a single action button) so its own\n // click handler runs the real action — `confirm` covers slots without a clickable element.\n onConfirm: (side) => {\n const target = slots.elements(actionSlot(side)).value[0] as HTMLElement | undefined;\n\n emit('confirm', { item: el, side });\n target?.click();\n },\n });\n\n onCleanup(() => swipe.dispose());\n\n // Reflects the derived `selected` state as a plain boolean attribute — the styling/\n // `[selected]`-selector hook — the same way `prop.bool()`'s own reflection would, since it\n // isn't a real settable prop anymore.\n watchEffect(() => {\n el.toggleAttribute('selected', isSelected.value);\n });\n\n // Emits select/deselect/reveal/conceal for both gesture-driven AND externally-set (attribute,\n // or the parent list's `value`) state changes — the plain-reflected-prop equivalent of\n // ore-accordion-item's native <details> `toggle`-event listener (there's no backing native\n // element here to piggyback on).\n let lastSelected = isSelected.value;\n\n watchEffect(() => {\n const current = isSelected.value;\n\n if (current === lastSelected) return;\n\n lastSelected = current;\n emit(current ? 'select' : 'deselect', { item: el, value: props.value.value ?? null });\n });\n\n let lastRevealed = props.revealed.value ?? null;\n\n watchEffect(() => {\n const current = props.revealed.value ?? null;\n\n if (current === lastRevealed) return;\n\n lastRevealed = current;\n\n if (current) {\n // Only one item may have its swipe actions revealed at a time — tell the list directly\n // instead of dispatching an event for it to listen for.\n listCtx?.requestReveal(el);\n emit('reveal', { item: el, side: current });\n } else {\n emit('conceal', { item: el });\n }\n });\n\n const handleActivate = (event: Event): void => {\n if (props.disabled.value) return;\n\n if (props.revealed.value) {\n event.preventDefault();\n event.stopPropagation();\n el.removeAttribute('revealed');\n\n return;\n }\n\n if (!isSelectable.value) return;\n\n const value = props.value.value;\n\n // Re-clicking an already-selected item deselects it; a value is required to select at all\n // (undefined would otherwise match every valueless item at once).\n if (value != null) listCtx?.select(isSelected.value ? undefined : value);\n };\n\n const handleRowKeydown = (event: KeyboardEvent): void => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n\n if (props.disabled.value || (!props.revealed.value && !isSelectable.value)) return;\n\n event.preventDefault();\n handleActivate(event);\n };\n\n bind({\n attr: {\n 'aria-disabled': () => (props.disabled.value ? 'true' : null),\n 'aria-selected': () => (isSelectable.value ? String(isSelected.value) : null),\n role: () => (isSelectable.value ? 'option' : 'listitem'),\n },\n });\n\n return html`\n <div\n class=\"row\"\n part=\"row\"\n tabindex=\"${() => (props.disabled.value ? '-1' : '0')}\"\n @click=\"${handleActivate}\"\n @keydown=\"${handleRowKeydown}\"\n @pointercancel=\"${(e: PointerEvent) => swipe.handlePointerCancel(e)}\"\n @pointerdown=\"${(e: PointerEvent) => swipe.handlePointerDown(e)}\"\n @pointermove=\"${(e: PointerEvent) => swipe.handlePointerMove(e)}\"\n @pointerup=\"${(e: PointerEvent) => swipe.handlePointerUp(e)}\">\n <span class=\"leading\" part=\"leading\"><slot name=\"leading\"></slot></span>\n <span class=\"content\" part=\"content\">\n <span class=\"title\" part=\"title\"><slot></slot></span>\n <span class=\"description\" part=\"description\"><slot name=\"description\"></slot></span>\n </span>\n <span class=\"trailing\" part=\"trailing\"><slot name=\"trailing\"></slot></span>\n </div>\n <span class=\"actions actions-left\" part=\"actions-start\"><slot name=\"actions-left\"></slot></span>\n <span class=\"actions actions-right\" part=\"actions-end\"><slot name=\"actions-right\"></slot></span>\n `;\n },\n\n shadow: { delegatesFocus: true },\n styles: [reducedMotionMixin, componentStyles],\n});\n"],"mappings":";;;;;;;;AA6CA,IAAM,KAAc,MAClB,MAAS,SAAS,iBAAiB,iBAiExB,IAAgB;AAC7B,EAAyB,GAAe;CACtC,OAAO;EACL,GAAG;EACH,UAAU,EAAK,MAAsC,CAAC,QAAQ,OAAO,GAAG,KAAA,CAAS;EACjF,OAAO,EAAK,OAAO;CACrB;CAEA,MAAM,GAAO;EACX,IAAM,IAAK,EAAQ,GACb,IAAO,EAA2B,GAClC,IAAQ,EAAoF,GAE5F,IAAU,EAAO,CAAQ,GACzB,IAAe,QAAe,EAAQ,GAAS,WAAW,KAAM,GAGhE,IAAa,QACX,EAAM,MAAM,SAAS,QAAQ,KAAW,QAAQ,EAAQ,MAAM,UAAU,EAAM,MAAM,KAC5F,GAIM,IAAQ,EAAkB,GAAI;GAClC,UAAU,QAAe,EAAM,SAAS,SAAS,EAAQ,EAAM,SAAS,KAAM;GAC9E,aAJkB,MAAsC,EAAM,IAAI,EAAW,CAAI,CAAC,CAAC,CAAC;GAOpF,YAAY,MAAS;IACnB,IAAM,IAAS,EAAM,SAAS,EAAW,CAAI,CAAC,CAAC,CAAC,MAAM;IAGtD,AADA,EAAK,WAAW;KAAE,MAAM;KAAI;IAAK,CAAC,GAClC,GAAQ,MAAM;GAChB;EACF,CAAC;EAOD,AALA,QAAgB,EAAM,QAAQ,CAAC,GAK/B,QAAkB;GAChB,EAAG,gBAAgB,YAAY,EAAW,KAAK;EACjD,CAAC;EAMD,IAAI,IAAe,EAAW;EAE9B,QAAkB;GAChB,IAAM,IAAU,EAAW;GAEvB,MAAY,MAEhB,IAAe,GACf,EAAK,IAAU,WAAW,YAAY;IAAE,MAAM;IAAI,OAAO,EAAM,MAAM,SAAS;GAAK,CAAC;EACtF,CAAC;EAED,IAAI,IAAe,EAAM,SAAS,SAAS;EAE3C,QAAkB;GAChB,IAAM,IAAU,EAAM,SAAS,SAAS;GAEpC,MAAY,MAEhB,IAAe,GAEX,KAGF,GAAS,cAAc,CAAE,GACzB,EAAK,UAAU;IAAE,MAAM;IAAI,MAAM;GAAQ,CAAC,KAE1C,EAAK,WAAW,EAAE,MAAM,EAAG,CAAC;EAEhC,CAAC;EAED,IAAM,KAAkB,MAAuB;GAC7C,IAAI,EAAM,SAAS,OAAO;GAE1B,IAAI,EAAM,SAAS,OAAO;IAGxB,AAFA,EAAM,eAAe,GACrB,EAAM,gBAAgB,GACtB,EAAG,gBAAgB,UAAU;IAE7B;GACF;GAEA,IAAI,CAAC,EAAa,OAAO;GAEzB,IAAM,IAAQ,EAAM,MAAM;GAI1B,AAAI,KAAS,QAAM,GAAS,OAAO,EAAW,QAAQ,KAAA,IAAY,CAAK;EACzE;EAmBA,OARA,EAAK,EACH,MAAM;GACJ,uBAAwB,EAAM,SAAS,QAAQ,SAAS;GACxD,uBAAwB,EAAa,QAAQ,OAAO,EAAW,KAAK,IAAI;GACxE,YAAa,EAAa,QAAQ,WAAW;EAC/C,EACF,CAAC,GAEM,CAAI;;;;0BAIY,EAAM,SAAS,QAAQ,OAAO,IAAK;kBAC5C,EAAe;qBAtBH,MAA+B;GACnD,GAAM,QAAQ,WAAW,EAAM,QAAQ,SAEvC,EAAM,SAAS,SAAU,CAAC,EAAM,SAAS,SAAS,CAAC,EAAa,UAEpE,EAAM,eAAe,GACrB,EAAe,CAAK;EACtB,EAgBiC;2BACV,MAAoB,EAAM,oBAAoB,CAAC,EAAE;yBACnD,MAAoB,EAAM,kBAAkB,CAAC,EAAE;yBAC/C,MAAoB,EAAM,kBAAkB,CAAC,EAAE;uBACjD,MAAoB,EAAM,gBAAgB,CAAC,EAAE;;;;;;;;;;;CAWlE;CAEA,QAAQ,EAAE,gBAAgB,GAAK;CAC/B,QAAQ,CAAC,GAAoB,CAAe;AAC9C,CAAC"}
|
package/dist/list.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./core/ore.cjs"),n=require("./core/nav.cjs"),r=require("./shared/prop-bundles.cjs"),i=require("./shared/size-presets.cjs"),a=require("./content/list/list.css.cjs");let o=require("@vielzeug/ore"),s=require("@vielzeug/ripple");var c=(0,o.createContext)(`ListContext`),l=`ore-list`;(0,o.define)(l,{props:{...r.disablableBundle,...r.sizableBundle,selectable:o.prop.bool(!1),value:o.prop.string(),variant:o.prop.string()},setup(e){let r=(0,o.getHost)(),i=(0,o.useEmit)(),a=()=>[...r.querySelectorAll(`:scope > ore-list-item:not([disabled])`)],l=()=>[...r.querySelectorAll(`:scope > ore-list-item`)],u=e=>e.shadowRoot?.querySelector(`[part="row"]`)??null,d=()=>a().map(u).filter(e=>e!=null),f=n.createListControl({getItems:a,loop:!0,onNavigate:(e,t)=>{u(a()[t])?.focus()},signal:t.lifecycleSignal(o.onCleanup)}),p=(0,s.signal)(e.value.value);(0,s.watch)(e.value,e=>{p.value=e});let m=e=>{p.value!==e&&(p.value=e,i(`change`,{value:e??null}))},h=e=>{for(let t of l())t!==e&&t.removeAttribute(`revealed`)},g=e=>{let t=l().find(e=>e.hasAttribute(`revealed`));!t||e.composedPath().includes(t)||t.removeAttribute(`revealed`)};return document.addEventListener(`pointerdown`,g,{capture:!0}),(0,o.onCleanup)(()=>document.removeEventListener(`pointerdown`,g,{capture:!0})),(0,o.provide)(c,{requestReveal:h,select:m,selectable:(0,s.computed)(()=>!!e.selectable.value),value:p}),(0,o.bind)({attr:{"aria-disabled":()=>e.disabled.value?`true`:null,role:()=>e.selectable.value?`listbox`:`list`,value:()=>p.value??null},on:{keydown:t=>{if(!e.selectable.value||e.disabled.value)return;let n=t.composedPath().find(e=>e instanceof HTMLElement&&e.getAttribute(`part`)===`row`);if(!n)return;let r=d().indexOf(n);r!==-1&&(f.set(r),f.handleKeydown(t))}}}),o.html`
|
|
2
2
|
<slot></slot>
|
|
3
|
-
`},styles:[
|
|
3
|
+
`},styles:[e.sizeVariantMixin(i.LIST_SIZE_PRESET),a.default]}),exports.LIST_CTX=c,exports.LIST_TAG=l;
|
|
4
4
|
//# sourceMappingURL=list.cjs.map
|
package/dist/list.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.cjs","names":[],"sources":["../src/content/list/list.ts"],"sourcesContent":["import { createContext, define, html, prop, bind, getHost, onCleanup, provide, useEmit } from '@vielzeug/ore';\nimport { computed, signal, type Readable } from '@vielzeug/ripple';\nimport { watch } from '@vielzeug/ripple/watch';\n\nimport type { ComponentSize } from '../../types';\n\nimport { createListControl, lifecycleSignal } from '../../core';\nimport { disablableBundle, LIST_SIZE_PRESET, sizableBundle } from '../../shared';\nimport { sizeVariantMixin } from '../../styles';\nimport componentStyles from './list.css?inline';\n\n/** Visual variant for `ore-list`. */\nexport type ListVariant = 'bordered' | 'plain' | 'separated';\n\n/** Context provided by `ore-list` to its `ore-list-item` children. */\nexport type ListContext = {\n /**\n * Closes every other item's swipe-revealed action panel. Called directly by an item the moment\n * its own `revealed` attribute transitions to non-null (gesture or direct attribute set) —\n * replaces listening for a bubbled `reveal` event and re-deriving \"is this actually my direct\n * child\" with a plain function call, the same shape as `select` below.\n */\n requestReveal: (item: HTMLElement) => void;\n /**\n * Selects `value` (or clears the selection when `undefined`) and fires `change`. Called\n * directly by an activated item — mirrors `ore-radio-group`'s `RadioGroupContext.select()`.\n * No sibling bookkeeping needed here: every item's `selected` is *derived* from `value`, so\n * changing it here is the only thing that has to happen.\n */\n select: (value: string | undefined) => void;\n selectable: Readable<boolean>;\n /**\n * Single source of truth for the current selection — `ore-list-item` never owns its own\n * \"selected\" state; it's always derived by comparing its own `value` against this one (the\n * same shape as `ore-radio-group`'s `RadioGroupContext.value`).\n */\n value: Readable<string | undefined>;\n};\n/** Injection key for the list context. */\nexport const LIST_CTX = createContext<ListContext>('ListContext');\n\n/** Events emitted by the list component */\nexport type OreListEvents = {\n /** Emitted when the selected value changes (only when `selectable` is set). */\n change: { value: null | string };\n};\n\n/** List component properties */\nexport type OreListProps = {\n /** Disable the entire list — blocks pointer interaction and removes items from tab order */\n disabled?: boolean;\n /**\n * Enables single-selection listbox behavior: clicking (or pressing Enter/Space on) an item\n * selects it and deselects any previously-selected sibling. Arrow keys / Home / End move\n * focus between items. Omit for a plain, non-interactive display list.\n */\n selectable?: boolean;\n /** Size applied to all items (propagated via inherited CSS custom properties) */\n size?: ComponentSize;\n /**\n * Selected item's `value` (only meaningful when `selectable`) — the single source of truth for\n * selection. `ore-list-item` never owns its own selected state; set this directly, bind it for\n * two-way control, or read it back from `change`.\n */\n value?: string;\n /** Visual variant: 'plain' (default, no dividers) | 'bordered' (outer border + row dividers) | 'separated' (each item is its own card) */\n variant?: ListVariant;\n};\n\n/**\n * A vertical list container for `ore-list-item` children — plain display list by default, or a\n * keyboard-navigable single-select listbox via `selectable`. Each item can independently reveal\n * a left/right action panel via touch/pointer swipe (see `ore-list-item`'s `actions-left`/\n * `actions-right` slots) — useful for mobile-style row actions (archive, delete, …).\n *\n * @element ore-list\n * @element ore-list-item - Child element for each row\n *\n * @attr {boolean} disabled - Disable the entire list\n * @attr {boolean} selectable - Enable single-selection listbox behavior with arrow-key navigation\n * @attr {string} size - Size applied to all items: 'sm' | 'md' | 'lg'\n * @attr {string} value - Selected item's value (only meaningful when `selectable`) — the single source of truth for selection\n * @attr {string} variant - Visual variant: 'plain' | 'bordered' | 'separated'\n *\n * @fires change - Emitted when the selected value changes. detail: { value: string | null }\n *\n * @slot - `ore-list-item` elements\n *\n * @cssprop --list-radius - Border radius for the 'bordered'/'separated' variants\n *\n * @example\n * ```html\n * <ore-list variant=\"bordered\">\n * <ore-list-item>Inbox</ore-list-item>\n * <ore-list-item>Drafts</ore-list-item>\n * </ore-list>\n * <ore-list selectable value=\"inbox\">\n * <ore-list-item value=\"inbox\">Inbox</ore-list-item>\n * <ore-list-item value=\"drafts\">Drafts</ore-list-item>\n * </ore-list>\n * ```\n */\nexport const LIST_TAG = 'ore-list' as const;\ndefine<OreListProps>(LIST_TAG, {\n props: {\n ...disablableBundle,\n ...sizableBundle,\n selectable: prop.bool(false),\n value: prop.string(),\n variant: prop.string<ListVariant>(),\n },\n\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreListEvents>();\n\n const getItems = (): HTMLElement[] => [\n ...el.querySelectorAll<HTMLElement>(':scope > ore-list-item:not([disabled])'),\n ];\n\n const getAllItems = (): HTMLElement[] => [...el.querySelectorAll<HTMLElement>(':scope > ore-list-item')];\n\n // Reaches into each item's shadow root for its focusable row — mirrors `ore-accordion`'s\n // `getSummaryElements()` — rather than relying on `item.focus()` + `shadow: { delegatesFocus:\n // true }` to land focus correctly, since that cross-boundary reporting is inconsistent enough\n // between real browsers and jsdom that other multi-item components in this package\n // (`ore-menu`, `ore-tabs`) defensively check both forms too. Queried via `[part=\"row\"]`, not\n // the `.row` class — `part` is list-item's declared public seam for exactly this kind of\n // cross-component reach; the class name is a private styling detail that could change.\n const getRow = (item: Element): HTMLElement | null =>\n item.shadowRoot?.querySelector<HTMLElement>('[part=\"row\"]') ?? null;\n\n const getRows = (): HTMLElement[] =>\n getItems()\n .map(getRow)\n .filter((row): row is HTMLElement => row != null);\n\n const listControl = createListControl<HTMLElement>({\n getItems,\n loop: true,\n onNavigate: (_action, index) => {\n getRow(getItems()[index])?.focus();\n },\n signal: lifecycleSignal(onCleanup),\n });\n\n // Selection — `selectedValue` is the single source of truth (mirrors `ore-radio-group`'s\n // `selectedValue`/`RadioGroupContext.value` pattern): reflected onto the `value` attribute,\n // synced back in when set externally, and read by every item via context to derive its own\n // `selected` state. No sibling-clearing needed anywhere — changing this one signal is enough.\n const selectedValue = signal<string | undefined>(props.value.value);\n\n watch(props.value, (value) => {\n selectedValue.value = value;\n });\n\n const select = (value: string | undefined): void => {\n if (selectedValue.value === value) return;\n\n selectedValue.value = value;\n emit('change', { value: value ?? null });\n };\n\n // Only one item's swipe-revealed action panel is open at a time. The item calls this\n // directly the moment its own `revealed` attribute transitions to non-null — see\n // `ListContext.requestReveal`'s doc comment for why this replaced a bubbled event.\n const requestReveal = (item: HTMLElement): void => {\n for (const sibling of getAllItems()) {\n if (sibling !== item) sibling.removeAttribute('revealed');\n }\n };\n\n // Closes any swipe-revealed item when the user interacts anywhere outside of it — matches\n // the outside-pointerdown-closes pattern used by ore-date-picker/ore-time-picker's popovers.\n const handleOutsidePointerDown = (event: PointerEvent): void => {\n const open = getAllItems().find((item) => item.hasAttribute('revealed'));\n\n if (!open || event.composedPath().includes(open)) return;\n\n open.removeAttribute('revealed');\n };\n\n document.addEventListener('pointerdown', handleOutsidePointerDown, { capture: true });\n onCleanup(() => document.removeEventListener('pointerdown', handleOutsidePointerDown, { capture: true }));\n\n provide(LIST_CTX, {\n requestReveal,\n select,\n selectable: computed(() => Boolean(props.selectable.value)),\n value: selectedValue,\n });\n\n bind({\n attr: {\n 'aria-disabled': () => (props.disabled.value ? 'true' : null),\n role: () => (props.selectable.value ? 'listbox' : 'list'),\n value: () => selectedValue.value ?? null,\n },\n on: {\n keydown: (event: KeyboardEvent) => {\n if (!props.selectable.value || props.disabled.value) return;\n\n const row = event\n .composedPath()\n .find((node): node is HTMLElement => node instanceof HTMLElement && node.getAttribute('part') === 'row');\n\n if (!row) return;\n\n const focused = getRows().indexOf(row);\n\n if (focused === -1) return;\n\n listControl.set(focused);\n listControl.handleKeydown(event);\n },\n },\n });\n\n return html`\n <slot></slot>\n `;\n },\n\n styles: [sizeVariantMixin(LIST_SIZE_PRESET), componentStyles],\n});\n"],"mappings":"oYAuCA,IAAa,GAAA,EAAW,EAAA,cAAA,CAA2B,aAAa,EA+DnD,EAAW,YACxB,EAAA,EAAA,OAAA,CAAqB,EAAU,CAC7B,MAAO,CACL,GAAG,EAAA,iBACH,GAAG,EAAA,cACH,WAAY,EAAA,KAAK,KAAK,EAAK,EAC3B,MAAO,EAAA,KAAK,OAAO,EACnB,QAAS,EAAA,KAAK,OAAoB,CACpC,EAEA,MAAM,EAAO,CACX,IAAM,GAAA,EAAK,EAAA,QAAA,CAAQ,EACb,GAAA,EAAO,EAAA,QAAA,CAAuB,EAE9B,MAAgC,CACpC,GAAG,EAAG,iBAA8B,wCAAwC,CAC9E,EAEM,MAAmC,CAAC,GAAG,EAAG,iBAA8B,wBAAwB,CAAC,EASjG,EAAU,GACd,EAAK,YAAY,cAA2B,cAAc,GAAK,KAE3D,MACJ,EAAS,CAAC,CACP,IAAI,CAAM,CAAC,CACX,OAAQ,GAA4B,GAAO,IAAI,EAE9C,EAAc,EAAA,kBAA+B,CACjD,WACA,KAAM,GACN,YAAa,EAAS,IAAU,CAC9B,EAAO,EAAS,CAAC,CAAC,EAAM,CAAC,EAAE,MAAM,CACnC,EACA,OAAQ,EAAA,gBAAgB,EAAA,SAAS,CACnC,CAAC,EAMK,GAAA,EAAgB,EAAA,OAAA,CAA2B,EAAM,MAAM,KAAK,GAElE,EAAA,EAAA,MAAA,CAAM,EAAM,MAAQ,GAAU,CAC5B,EAAc,MAAQ,CACxB,CAAC,EAED,IAAM,EAAU,GAAoC,CAC9C,EAAc,QAAU,IAE5B,EAAc,MAAQ,EACtB,EAAK,SAAU,CAAE,MAAO,GAAS,IAAK,CAAC,EACzC,EAKM,EAAiB,GAA4B,CACjD,IAAK,IAAM,KAAW,EAAY,EAC5B,IAAY,GAAM,EAAQ,gBAAgB,UAAU,CAE5D,EAIM,EAA4B,GAA8B,CAC9D,IAAM,EAAO,EAAY,CAAC,CAAC,KAAM,GAAS,EAAK,aAAa,UAAU,CAAC,EAEnE,CAAC,GAAQ,EAAM,aAAa,CAAC,CAAC,SAAS,CAAI,GAE/C,EAAK,gBAAgB,UAAU,CACjC,EAsCA,OApCA,SAAS,iBAAiB,cAAe,EAA0B,CAAE,QAAS,EAAK,CAAC,GACpF,EAAA,EAAA,UAAA,KAAgB,SAAS,oBAAoB,cAAe,EAA0B,CAAE,QAAS,EAAK,CAAC,CAAC,GAExG,EAAA,EAAA,QAAA,CAAQ,EAAU,CAChB,gBACA,SACA,YAAA,EAAY,EAAA,SAAA,KAAe,EAAQ,EAAM,WAAW,KAAM,EAC1D,MAAO,CACT,CAAC,GAED,EAAA,EAAA,KAAA,CAAK,CACH,KAAM,CACJ,oBAAwB,EAAM,SAAS,MAAQ,OAAS,KACxD,SAAa,EAAM,WAAW,MAAQ,UAAY,OAClD,UAAa,EAAc,OAAS,IACtC,EACA,GAAI,CACF,QAAU,GAAyB,CACjC,GAAI,CAAC,EAAM,WAAW,OAAS,EAAM,SAAS,MAAO,OAErD,IAAM,EAAM,EACT,aAAa,CAAC,CACd,KAAM,GAA8B,aAAgB,aAAe,EAAK,aAAa,MAAM,IAAM,KAAK,EAEzG,GAAI,CAAC,EAAK,OAEV,IAAM,EAAU,EAAQ,CAAC,CAAC,QAAQ,CAAG,EAEjC,IAAY,KAEhB,EAAY,IAAI,CAAO,EACvB,EAAY,cAAc,CAAK,EACjC,CACF,CACF,CAAC,EAEM,EAAA,IAAI;;KAGb,EAEA,OAAQ,CAAC,EAAA,iBAAiB,EAAA,gBAAgB,EAAG,EAAA,OAAe,CAC9D,CAAC"}
|
|
1
|
+
{"version":3,"file":"list.cjs","names":[],"sources":["../src/content/list/list.ts"],"sourcesContent":["import { bind, createContext, define, getHost, html, onCleanup, prop, provide, useEmit } from '@vielzeug/ore';\nimport { computed, type Readable, signal, watch } from '@vielzeug/ripple';\nimport { createListControl, lifecycleSignal } from '../../core';\nimport { disablableBundle, LIST_SIZE_PRESET, sizableBundle } from '../../shared';\nimport { sizeVariantMixin } from '../../styles';\nimport type { ComponentSize } from '../../types';\nimport componentStyles from './list.css?inline';\n\n/** Visual variant for `ore-list`. */\nexport type ListVariant = 'bordered' | 'plain' | 'separated';\n\n/** Context provided by `ore-list` to its `ore-list-item` children. */\nexport type ListContext = {\n /**\n * Closes every other item's swipe-revealed action panel. Called directly by an item the moment\n * its own `revealed` attribute transitions to non-null (gesture or direct attribute set) —\n * replaces listening for a bubbled `reveal` event and re-deriving \"is this actually my direct\n * child\" with a plain function call, the same shape as `select` below.\n */\n requestReveal: (item: HTMLElement) => void;\n /**\n * Selects `value` (or clears the selection when `undefined`) and fires `change`. Called\n * directly by an activated item — mirrors `ore-radio-group`'s `RadioGroupContext.select()`.\n * No sibling bookkeeping needed here: every item's `selected` is *derived* from `value`, so\n * changing it here is the only thing that has to happen.\n */\n select: (value: string | undefined) => void;\n selectable: Readable<boolean>;\n /**\n * Single source of truth for the current selection — `ore-list-item` never owns its own\n * \"selected\" state; it's always derived by comparing its own `value` against this one (the\n * same shape as `ore-radio-group`'s `RadioGroupContext.value`).\n */\n value: Readable<string | undefined>;\n};\n/** Injection key for the list context. */\nexport const LIST_CTX = createContext<ListContext>('ListContext');\n\n/** Events emitted by the list component */\nexport type OreListEvents = {\n /** Emitted when the selected value changes (only when `selectable` is set). */\n change: { value: null | string };\n};\n\n/** List component properties */\nexport type OreListProps = {\n /** Disable the entire list — blocks pointer interaction and removes items from tab order */\n disabled?: boolean;\n /**\n * Enables single-selection listbox behavior: clicking (or pressing Enter/Space on) an item\n * selects it and deselects any previously-selected sibling. Arrow keys / Home / End move\n * focus between items. Omit for a plain, non-interactive display list.\n */\n selectable?: boolean;\n /** Size applied to all items (propagated via inherited CSS custom properties) */\n size?: ComponentSize;\n /**\n * Selected item's `value` (only meaningful when `selectable`) — the single source of truth for\n * selection. `ore-list-item` never owns its own selected state; set this directly, bind it for\n * two-way control, or read it back from `change`.\n */\n value?: string;\n /** Visual variant: 'plain' (default, no dividers) | 'bordered' (outer border + row dividers) | 'separated' (each item is its own card) */\n variant?: ListVariant;\n};\n\n/**\n * A vertical list container for `ore-list-item` children — plain display list by default, or a\n * keyboard-navigable single-select listbox via `selectable`. Each item can independently reveal\n * a left/right action panel via touch/pointer swipe (see `ore-list-item`'s `actions-left`/\n * `actions-right` slots) — useful for mobile-style row actions (archive, delete, …).\n *\n * @element ore-list\n * @element ore-list-item - Child element for each row\n *\n * @attr {boolean} disabled - Disable the entire list\n * @attr {boolean} selectable - Enable single-selection listbox behavior with arrow-key navigation\n * @attr {string} size - Size applied to all items: 'sm' | 'md' | 'lg'\n * @attr {string} value - Selected item's value (only meaningful when `selectable`) — the single source of truth for selection\n * @attr {string} variant - Visual variant: 'plain' | 'bordered' | 'separated'\n *\n * @fires change - Emitted when the selected value changes. detail: { value: string | null }\n *\n * @slot - `ore-list-item` elements\n *\n * @cssprop --list-radius - Border radius for the 'bordered'/'separated' variants\n *\n * @example\n * ```html\n * <ore-list variant=\"bordered\">\n * <ore-list-item>Inbox</ore-list-item>\n * <ore-list-item>Drafts</ore-list-item>\n * </ore-list>\n * <ore-list selectable value=\"inbox\">\n * <ore-list-item value=\"inbox\">Inbox</ore-list-item>\n * <ore-list-item value=\"drafts\">Drafts</ore-list-item>\n * </ore-list>\n * ```\n */\nexport const LIST_TAG = 'ore-list' as const;\ndefine<OreListProps>(LIST_TAG, {\n props: {\n ...disablableBundle,\n ...sizableBundle,\n selectable: prop.bool(false),\n value: prop.string(),\n variant: prop.string<ListVariant>(),\n },\n\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreListEvents>();\n\n const getItems = (): HTMLElement[] => [\n ...el.querySelectorAll<HTMLElement>(':scope > ore-list-item:not([disabled])'),\n ];\n\n const getAllItems = (): HTMLElement[] => [...el.querySelectorAll<HTMLElement>(':scope > ore-list-item')];\n\n // Reaches into each item's shadow root for its focusable row — mirrors `ore-accordion`'s\n // `getSummaryElements()` — rather than relying on `item.focus()` + `shadow: { delegatesFocus:\n // true }` to land focus correctly, since that cross-boundary reporting is inconsistent enough\n // between real browsers and jsdom that other multi-item components in this package\n // (`ore-menu`, `ore-tabs`) defensively check both forms too. Queried via `[part=\"row\"]`, not\n // the `.row` class — `part` is list-item's declared public seam for exactly this kind of\n // cross-component reach; the class name is a private styling detail that could change.\n const getRow = (item: Element): HTMLElement | null =>\n item.shadowRoot?.querySelector<HTMLElement>('[part=\"row\"]') ?? null;\n\n const getRows = (): HTMLElement[] =>\n getItems()\n .map(getRow)\n .filter((row): row is HTMLElement => row != null);\n\n const listControl = createListControl<HTMLElement>({\n getItems,\n loop: true,\n onNavigate: (_action, index) => {\n getRow(getItems()[index])?.focus();\n },\n signal: lifecycleSignal(onCleanup),\n });\n\n // Selection — `selectedValue` is the single source of truth (mirrors `ore-radio-group`'s\n // `selectedValue`/`RadioGroupContext.value` pattern): reflected onto the `value` attribute,\n // synced back in when set externally, and read by every item via context to derive its own\n // `selected` state. No sibling-clearing needed anywhere — changing this one signal is enough.\n const selectedValue = signal<string | undefined>(props.value.value);\n\n watch(props.value, (value) => {\n selectedValue.value = value;\n });\n\n const select = (value: string | undefined): void => {\n if (selectedValue.value === value) return;\n\n selectedValue.value = value;\n emit('change', { value: value ?? null });\n };\n\n // Only one item's swipe-revealed action panel is open at a time. The item calls this\n // directly the moment its own `revealed` attribute transitions to non-null — see\n // `ListContext.requestReveal`'s doc comment for why this replaced a bubbled event.\n const requestReveal = (item: HTMLElement): void => {\n for (const sibling of getAllItems()) {\n if (sibling !== item) sibling.removeAttribute('revealed');\n }\n };\n\n // Closes any swipe-revealed item when the user interacts anywhere outside of it — matches\n // the outside-pointerdown-closes pattern used by ore-date-picker/ore-time-picker's popovers.\n const handleOutsidePointerDown = (event: PointerEvent): void => {\n const open = getAllItems().find((item) => item.hasAttribute('revealed'));\n\n if (!open || event.composedPath().includes(open)) return;\n\n open.removeAttribute('revealed');\n };\n\n document.addEventListener('pointerdown', handleOutsidePointerDown, { capture: true });\n onCleanup(() => document.removeEventListener('pointerdown', handleOutsidePointerDown, { capture: true }));\n\n provide(LIST_CTX, {\n requestReveal,\n select,\n selectable: computed(() => Boolean(props.selectable.value)),\n value: selectedValue,\n });\n\n bind({\n attr: {\n 'aria-disabled': () => (props.disabled.value ? 'true' : null),\n role: () => (props.selectable.value ? 'listbox' : 'list'),\n value: () => selectedValue.value ?? null,\n },\n on: {\n keydown: (event: KeyboardEvent) => {\n if (!props.selectable.value || props.disabled.value) return;\n\n const row = event\n .composedPath()\n .find((node): node is HTMLElement => node instanceof HTMLElement && node.getAttribute('part') === 'row');\n\n if (!row) return;\n\n const focused = getRows().indexOf(row);\n\n if (focused === -1) return;\n\n listControl.set(focused);\n listControl.handleKeydown(event);\n },\n },\n });\n\n return html`\n <slot></slot>\n `;\n },\n\n styles: [sizeVariantMixin(LIST_SIZE_PRESET), componentStyles],\n});\n"],"mappings":"gWAoCA,IAAa,GAAA,EAAW,EAAA,cAAA,CAA2B,aAAa,EA+DnD,EAAW,YACxB,EAAA,EAAA,OAAA,CAAqB,EAAU,CAC7B,MAAO,CACL,GAAG,EAAA,iBACH,GAAG,EAAA,cACH,WAAY,EAAA,KAAK,KAAK,EAAK,EAC3B,MAAO,EAAA,KAAK,OAAO,EACnB,QAAS,EAAA,KAAK,OAAoB,CACpC,EAEA,MAAM,EAAO,CACX,IAAM,GAAA,EAAK,EAAA,QAAA,CAAQ,EACb,GAAA,EAAO,EAAA,QAAA,CAAuB,EAE9B,MAAgC,CACpC,GAAG,EAAG,iBAA8B,wCAAwC,CAC9E,EAEM,MAAmC,CAAC,GAAG,EAAG,iBAA8B,wBAAwB,CAAC,EASjG,EAAU,GACd,EAAK,YAAY,cAA2B,cAAc,GAAK,KAE3D,MACJ,EAAS,CAAC,CACP,IAAI,CAAM,CAAC,CACX,OAAQ,GAA4B,GAAO,IAAI,EAE9C,EAAc,EAAA,kBAA+B,CACjD,WACA,KAAM,GACN,YAAa,EAAS,IAAU,CAC9B,EAAO,EAAS,CAAC,CAAC,EAAM,CAAC,EAAE,MAAM,CACnC,EACA,OAAQ,EAAA,gBAAgB,EAAA,SAAS,CACnC,CAAC,EAMK,GAAA,EAAgB,EAAA,OAAA,CAA2B,EAAM,MAAM,KAAK,GAElE,EAAA,EAAA,MAAA,CAAM,EAAM,MAAQ,GAAU,CAC5B,EAAc,MAAQ,CACxB,CAAC,EAED,IAAM,EAAU,GAAoC,CAC9C,EAAc,QAAU,IAE5B,EAAc,MAAQ,EACtB,EAAK,SAAU,CAAE,MAAO,GAAS,IAAK,CAAC,EACzC,EAKM,EAAiB,GAA4B,CACjD,IAAK,IAAM,KAAW,EAAY,EAC5B,IAAY,GAAM,EAAQ,gBAAgB,UAAU,CAE5D,EAIM,EAA4B,GAA8B,CAC9D,IAAM,EAAO,EAAY,CAAC,CAAC,KAAM,GAAS,EAAK,aAAa,UAAU,CAAC,EAEnE,CAAC,GAAQ,EAAM,aAAa,CAAC,CAAC,SAAS,CAAI,GAE/C,EAAK,gBAAgB,UAAU,CACjC,EAsCA,OApCA,SAAS,iBAAiB,cAAe,EAA0B,CAAE,QAAS,EAAK,CAAC,GACpF,EAAA,EAAA,UAAA,KAAgB,SAAS,oBAAoB,cAAe,EAA0B,CAAE,QAAS,EAAK,CAAC,CAAC,GAExG,EAAA,EAAA,QAAA,CAAQ,EAAU,CAChB,gBACA,SACA,YAAA,EAAY,EAAA,SAAA,KAAe,EAAQ,EAAM,WAAW,KAAM,EAC1D,MAAO,CACT,CAAC,GAED,EAAA,EAAA,KAAA,CAAK,CACH,KAAM,CACJ,oBAAwB,EAAM,SAAS,MAAQ,OAAS,KACxD,SAAa,EAAM,WAAW,MAAQ,UAAY,OAClD,UAAa,EAAc,OAAS,IACtC,EACA,GAAI,CACF,QAAU,GAAyB,CACjC,GAAI,CAAC,EAAM,WAAW,OAAS,EAAM,SAAS,MAAO,OAErD,IAAM,EAAM,EACT,aAAa,CAAC,CACd,KAAM,GAA8B,aAAgB,aAAe,EAAK,aAAa,MAAM,IAAM,KAAK,EAEzG,GAAI,CAAC,EAAK,OAEV,IAAM,EAAU,EAAQ,CAAC,CAAC,QAAQ,CAAG,EAEjC,IAAY,KAEhB,EAAY,IAAI,CAAO,EACvB,EAAY,cAAc,CAAK,EACjC,CACF,CACF,CAAC,EAEM,EAAA,IAAI;;KAGb,EAEA,OAAQ,CAAC,EAAA,iBAAiB,EAAA,gBAAgB,EAAG,EAAA,OAAe,CAC9D,CAAC"}
|
package/dist/list.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { sizeVariantMixin as e } from "./styles/mixins/shape.css.js";
|
|
2
|
+
import { lifecycleSignal as t } from "./core/ore.js";
|
|
3
3
|
import { createListControl as n } from "./core/nav.js";
|
|
4
4
|
import { disablableBundle as r, sizableBundle as i } from "./shared/prop-bundles.js";
|
|
5
5
|
import { LIST_SIZE_PRESET as a } from "./shared/size-presets.js";
|
|
6
6
|
import o from "./content/list/list.css.js";
|
|
7
7
|
import { bind as s, createContext as c, define as l, getHost as u, html as d, onCleanup as f, prop as p, provide as m, useEmit as h } from "@vielzeug/ore";
|
|
8
|
-
import { computed as g, signal as _ } from "@vielzeug/ripple";
|
|
9
|
-
import { watch as v } from "@vielzeug/ripple/watch";
|
|
8
|
+
import { computed as g, signal as _, watch as v } from "@vielzeug/ripple";
|
|
10
9
|
//#region src/content/list/list.ts
|
|
11
10
|
var y = c("ListContext"), b = "ore-list";
|
|
12
11
|
l(b, {
|
|
@@ -17,16 +16,16 @@ l(b, {
|
|
|
17
16
|
value: p.string(),
|
|
18
17
|
variant: p.string()
|
|
19
18
|
},
|
|
20
|
-
setup(
|
|
19
|
+
setup(e) {
|
|
21
20
|
let r = u(), i = h(), a = () => [...r.querySelectorAll(":scope > ore-list-item:not([disabled])")], o = () => [...r.querySelectorAll(":scope > ore-list-item")], c = (e) => e.shadowRoot?.querySelector("[part=\"row\"]") ?? null, l = () => a().map(c).filter((e) => e != null), p = n({
|
|
22
21
|
getItems: a,
|
|
23
22
|
loop: !0,
|
|
24
23
|
onNavigate: (e, t) => {
|
|
25
24
|
c(a()[t])?.focus();
|
|
26
25
|
},
|
|
27
|
-
signal:
|
|
28
|
-
}), b = _(
|
|
29
|
-
v(
|
|
26
|
+
signal: t(f)
|
|
27
|
+
}), b = _(e.value.value);
|
|
28
|
+
v(e.value, (e) => {
|
|
30
29
|
b.value = e;
|
|
31
30
|
});
|
|
32
31
|
let x = (e) => {
|
|
@@ -40,26 +39,26 @@ l(b, {
|
|
|
40
39
|
return document.addEventListener("pointerdown", C, { capture: !0 }), f(() => document.removeEventListener("pointerdown", C, { capture: !0 })), m(y, {
|
|
41
40
|
requestReveal: S,
|
|
42
41
|
select: x,
|
|
43
|
-
selectable: g(() => !!
|
|
42
|
+
selectable: g(() => !!e.selectable.value),
|
|
44
43
|
value: b
|
|
45
44
|
}), s({
|
|
46
45
|
attr: {
|
|
47
|
-
"aria-disabled": () =>
|
|
48
|
-
role: () =>
|
|
46
|
+
"aria-disabled": () => e.disabled.value ? "true" : null,
|
|
47
|
+
role: () => e.selectable.value ? "listbox" : "list",
|
|
49
48
|
value: () => b.value ?? null
|
|
50
49
|
},
|
|
51
|
-
on: { keydown: (
|
|
52
|
-
if (!
|
|
53
|
-
let n =
|
|
50
|
+
on: { keydown: (t) => {
|
|
51
|
+
if (!e.selectable.value || e.disabled.value) return;
|
|
52
|
+
let n = t.composedPath().find((e) => e instanceof HTMLElement && e.getAttribute("part") === "row");
|
|
54
53
|
if (!n) return;
|
|
55
54
|
let r = l().indexOf(n);
|
|
56
|
-
r !== -1 && (p.set(r), p.handleKeydown(
|
|
55
|
+
r !== -1 && (p.set(r), p.handleKeydown(t));
|
|
57
56
|
} }
|
|
58
57
|
}), d`
|
|
59
58
|
<slot></slot>
|
|
60
59
|
`;
|
|
61
60
|
},
|
|
62
|
-
styles: [
|
|
61
|
+
styles: [e(a), o]
|
|
63
62
|
});
|
|
64
63
|
//#endregion
|
|
65
64
|
export { y as LIST_CTX, b as LIST_TAG };
|
package/dist/list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","names":[],"sources":["../src/content/list/list.ts"],"sourcesContent":["import { createContext, define, html, prop, bind, getHost, onCleanup, provide, useEmit } from '@vielzeug/ore';\nimport { computed, signal, type Readable } from '@vielzeug/ripple';\nimport { watch } from '@vielzeug/ripple/watch';\n\nimport type { ComponentSize } from '../../types';\n\nimport { createListControl, lifecycleSignal } from '../../core';\nimport { disablableBundle, LIST_SIZE_PRESET, sizableBundle } from '../../shared';\nimport { sizeVariantMixin } from '../../styles';\nimport componentStyles from './list.css?inline';\n\n/** Visual variant for `ore-list`. */\nexport type ListVariant = 'bordered' | 'plain' | 'separated';\n\n/** Context provided by `ore-list` to its `ore-list-item` children. */\nexport type ListContext = {\n /**\n * Closes every other item's swipe-revealed action panel. Called directly by an item the moment\n * its own `revealed` attribute transitions to non-null (gesture or direct attribute set) —\n * replaces listening for a bubbled `reveal` event and re-deriving \"is this actually my direct\n * child\" with a plain function call, the same shape as `select` below.\n */\n requestReveal: (item: HTMLElement) => void;\n /**\n * Selects `value` (or clears the selection when `undefined`) and fires `change`. Called\n * directly by an activated item — mirrors `ore-radio-group`'s `RadioGroupContext.select()`.\n * No sibling bookkeeping needed here: every item's `selected` is *derived* from `value`, so\n * changing it here is the only thing that has to happen.\n */\n select: (value: string | undefined) => void;\n selectable: Readable<boolean>;\n /**\n * Single source of truth for the current selection — `ore-list-item` never owns its own\n * \"selected\" state; it's always derived by comparing its own `value` against this one (the\n * same shape as `ore-radio-group`'s `RadioGroupContext.value`).\n */\n value: Readable<string | undefined>;\n};\n/** Injection key for the list context. */\nexport const LIST_CTX = createContext<ListContext>('ListContext');\n\n/** Events emitted by the list component */\nexport type OreListEvents = {\n /** Emitted when the selected value changes (only when `selectable` is set). */\n change: { value: null | string };\n};\n\n/** List component properties */\nexport type OreListProps = {\n /** Disable the entire list — blocks pointer interaction and removes items from tab order */\n disabled?: boolean;\n /**\n * Enables single-selection listbox behavior: clicking (or pressing Enter/Space on) an item\n * selects it and deselects any previously-selected sibling. Arrow keys / Home / End move\n * focus between items. Omit for a plain, non-interactive display list.\n */\n selectable?: boolean;\n /** Size applied to all items (propagated via inherited CSS custom properties) */\n size?: ComponentSize;\n /**\n * Selected item's `value` (only meaningful when `selectable`) — the single source of truth for\n * selection. `ore-list-item` never owns its own selected state; set this directly, bind it for\n * two-way control, or read it back from `change`.\n */\n value?: string;\n /** Visual variant: 'plain' (default, no dividers) | 'bordered' (outer border + row dividers) | 'separated' (each item is its own card) */\n variant?: ListVariant;\n};\n\n/**\n * A vertical list container for `ore-list-item` children — plain display list by default, or a\n * keyboard-navigable single-select listbox via `selectable`. Each item can independently reveal\n * a left/right action panel via touch/pointer swipe (see `ore-list-item`'s `actions-left`/\n * `actions-right` slots) — useful for mobile-style row actions (archive, delete, …).\n *\n * @element ore-list\n * @element ore-list-item - Child element for each row\n *\n * @attr {boolean} disabled - Disable the entire list\n * @attr {boolean} selectable - Enable single-selection listbox behavior with arrow-key navigation\n * @attr {string} size - Size applied to all items: 'sm' | 'md' | 'lg'\n * @attr {string} value - Selected item's value (only meaningful when `selectable`) — the single source of truth for selection\n * @attr {string} variant - Visual variant: 'plain' | 'bordered' | 'separated'\n *\n * @fires change - Emitted when the selected value changes. detail: { value: string | null }\n *\n * @slot - `ore-list-item` elements\n *\n * @cssprop --list-radius - Border radius for the 'bordered'/'separated' variants\n *\n * @example\n * ```html\n * <ore-list variant=\"bordered\">\n * <ore-list-item>Inbox</ore-list-item>\n * <ore-list-item>Drafts</ore-list-item>\n * </ore-list>\n * <ore-list selectable value=\"inbox\">\n * <ore-list-item value=\"inbox\">Inbox</ore-list-item>\n * <ore-list-item value=\"drafts\">Drafts</ore-list-item>\n * </ore-list>\n * ```\n */\nexport const LIST_TAG = 'ore-list' as const;\ndefine<OreListProps>(LIST_TAG, {\n props: {\n ...disablableBundle,\n ...sizableBundle,\n selectable: prop.bool(false),\n value: prop.string(),\n variant: prop.string<ListVariant>(),\n },\n\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreListEvents>();\n\n const getItems = (): HTMLElement[] => [\n ...el.querySelectorAll<HTMLElement>(':scope > ore-list-item:not([disabled])'),\n ];\n\n const getAllItems = (): HTMLElement[] => [...el.querySelectorAll<HTMLElement>(':scope > ore-list-item')];\n\n // Reaches into each item's shadow root for its focusable row — mirrors `ore-accordion`'s\n // `getSummaryElements()` — rather than relying on `item.focus()` + `shadow: { delegatesFocus:\n // true }` to land focus correctly, since that cross-boundary reporting is inconsistent enough\n // between real browsers and jsdom that other multi-item components in this package\n // (`ore-menu`, `ore-tabs`) defensively check both forms too. Queried via `[part=\"row\"]`, not\n // the `.row` class — `part` is list-item's declared public seam for exactly this kind of\n // cross-component reach; the class name is a private styling detail that could change.\n const getRow = (item: Element): HTMLElement | null =>\n item.shadowRoot?.querySelector<HTMLElement>('[part=\"row\"]') ?? null;\n\n const getRows = (): HTMLElement[] =>\n getItems()\n .map(getRow)\n .filter((row): row is HTMLElement => row != null);\n\n const listControl = createListControl<HTMLElement>({\n getItems,\n loop: true,\n onNavigate: (_action, index) => {\n getRow(getItems()[index])?.focus();\n },\n signal: lifecycleSignal(onCleanup),\n });\n\n // Selection — `selectedValue` is the single source of truth (mirrors `ore-radio-group`'s\n // `selectedValue`/`RadioGroupContext.value` pattern): reflected onto the `value` attribute,\n // synced back in when set externally, and read by every item via context to derive its own\n // `selected` state. No sibling-clearing needed anywhere — changing this one signal is enough.\n const selectedValue = signal<string | undefined>(props.value.value);\n\n watch(props.value, (value) => {\n selectedValue.value = value;\n });\n\n const select = (value: string | undefined): void => {\n if (selectedValue.value === value) return;\n\n selectedValue.value = value;\n emit('change', { value: value ?? null });\n };\n\n // Only one item's swipe-revealed action panel is open at a time. The item calls this\n // directly the moment its own `revealed` attribute transitions to non-null — see\n // `ListContext.requestReveal`'s doc comment for why this replaced a bubbled event.\n const requestReveal = (item: HTMLElement): void => {\n for (const sibling of getAllItems()) {\n if (sibling !== item) sibling.removeAttribute('revealed');\n }\n };\n\n // Closes any swipe-revealed item when the user interacts anywhere outside of it — matches\n // the outside-pointerdown-closes pattern used by ore-date-picker/ore-time-picker's popovers.\n const handleOutsidePointerDown = (event: PointerEvent): void => {\n const open = getAllItems().find((item) => item.hasAttribute('revealed'));\n\n if (!open || event.composedPath().includes(open)) return;\n\n open.removeAttribute('revealed');\n };\n\n document.addEventListener('pointerdown', handleOutsidePointerDown, { capture: true });\n onCleanup(() => document.removeEventListener('pointerdown', handleOutsidePointerDown, { capture: true }));\n\n provide(LIST_CTX, {\n requestReveal,\n select,\n selectable: computed(() => Boolean(props.selectable.value)),\n value: selectedValue,\n });\n\n bind({\n attr: {\n 'aria-disabled': () => (props.disabled.value ? 'true' : null),\n role: () => (props.selectable.value ? 'listbox' : 'list'),\n value: () => selectedValue.value ?? null,\n },\n on: {\n keydown: (event: KeyboardEvent) => {\n if (!props.selectable.value || props.disabled.value) return;\n\n const row = event\n .composedPath()\n .find((node): node is HTMLElement => node instanceof HTMLElement && node.getAttribute('part') === 'row');\n\n if (!row) return;\n\n const focused = getRows().indexOf(row);\n\n if (focused === -1) return;\n\n listControl.set(focused);\n listControl.handleKeydown(event);\n },\n },\n });\n\n return html`\n <slot></slot>\n `;\n },\n\n styles: [sizeVariantMixin(LIST_SIZE_PRESET), componentStyles],\n});\n"],"mappings":";;;;;;;;;;AAuCA,IAAa,IAAW,EAA2B,aAAa,GA+DnD,IAAW;AACxB,EAAqB,GAAU;CAC7B,OAAO;EACL,GAAG;EACH,GAAG;EACH,YAAY,EAAK,KAAK,EAAK;EAC3B,OAAO,EAAK,OAAO;EACnB,SAAS,EAAK,OAAoB;CACpC;CAEA,MAAM,GAAO;EACX,IAAM,IAAK,EAAQ,GACb,IAAO,EAAuB,GAE9B,UAAgC,CACpC,GAAG,EAAG,iBAA8B,wCAAwC,CAC9E,GAEM,UAAmC,CAAC,GAAG,EAAG,iBAA8B,wBAAwB,CAAC,GASjG,KAAU,MACd,EAAK,YAAY,cAA2B,gBAAc,KAAK,MAE3D,UACJ,EAAS,CAAC,CACP,IAAI,CAAM,CAAC,CACX,QAAQ,MAA4B,KAAO,IAAI,GAE9C,IAAc,EAA+B;GACjD;GACA,MAAM;GACN,aAAa,GAAS,MAAU;IAC9B,EAAO,EAAS,CAAC,CAAC,EAAM,CAAC,EAAE,MAAM;GACnC;GACA,QAAQ,EAAgB,CAAS;EACnC,CAAC,GAMK,IAAgB,EAA2B,EAAM,MAAM,KAAK;EAElE,EAAM,EAAM,QAAQ,MAAU;GAC5B,EAAc,QAAQ;EACxB,CAAC;EAED,IAAM,KAAU,MAAoC;GAC9C,EAAc,UAAU,MAE5B,EAAc,QAAQ,GACtB,EAAK,UAAU,EAAE,OAAO,KAAS,KAAK,CAAC;EACzC,GAKM,KAAiB,MAA4B;GACjD,KAAK,IAAM,KAAW,EAAY,GAChC,AAAI,MAAY,KAAM,EAAQ,gBAAgB,UAAU;EAE5D,GAIM,KAA4B,MAA8B;GAC9D,IAAM,IAAO,EAAY,CAAC,CAAC,MAAM,MAAS,EAAK,aAAa,UAAU,CAAC;GAEnE,CAAC,KAAQ,EAAM,aAAa,CAAC,CAAC,SAAS,CAAI,KAE/C,EAAK,gBAAgB,UAAU;EACjC;EAsCA,OApCA,SAAS,iBAAiB,eAAe,GAA0B,EAAE,SAAS,GAAK,CAAC,GACpF,QAAgB,SAAS,oBAAoB,eAAe,GAA0B,EAAE,SAAS,GAAK,CAAC,CAAC,GAExG,EAAQ,GAAU;GAChB;GACA;GACA,YAAY,QAAe,EAAQ,EAAM,WAAW,KAAM;GAC1D,OAAO;EACT,CAAC,GAED,EAAK;GACH,MAAM;IACJ,uBAAwB,EAAM,SAAS,QAAQ,SAAS;IACxD,YAAa,EAAM,WAAW,QAAQ,YAAY;IAClD,aAAa,EAAc,SAAS;GACtC;GACA,IAAI,EACF,UAAU,MAAyB;IACjC,IAAI,CAAC,EAAM,WAAW,SAAS,EAAM,SAAS,OAAO;IAErD,IAAM,IAAM,EACT,aAAa,CAAC,CACd,MAAM,MAA8B,aAAgB,eAAe,EAAK,aAAa,MAAM,MAAM,KAAK;IAEzG,IAAI,CAAC,GAAK;IAEV,IAAM,IAAU,EAAQ,CAAC,CAAC,QAAQ,CAAG;IAEjC,MAAY,OAEhB,EAAY,IAAI,CAAO,GACvB,EAAY,cAAc,CAAK;GACjC,EACF;EACF,CAAC,GAEM,CAAI;;;CAGb;CAEA,QAAQ,CAAC,EAAiB,CAAgB,GAAG,CAAe;AAC9D,CAAC"}
|
|
1
|
+
{"version":3,"file":"list.js","names":[],"sources":["../src/content/list/list.ts"],"sourcesContent":["import { bind, createContext, define, getHost, html, onCleanup, prop, provide, useEmit } from '@vielzeug/ore';\nimport { computed, type Readable, signal, watch } from '@vielzeug/ripple';\nimport { createListControl, lifecycleSignal } from '../../core';\nimport { disablableBundle, LIST_SIZE_PRESET, sizableBundle } from '../../shared';\nimport { sizeVariantMixin } from '../../styles';\nimport type { ComponentSize } from '../../types';\nimport componentStyles from './list.css?inline';\n\n/** Visual variant for `ore-list`. */\nexport type ListVariant = 'bordered' | 'plain' | 'separated';\n\n/** Context provided by `ore-list` to its `ore-list-item` children. */\nexport type ListContext = {\n /**\n * Closes every other item's swipe-revealed action panel. Called directly by an item the moment\n * its own `revealed` attribute transitions to non-null (gesture or direct attribute set) —\n * replaces listening for a bubbled `reveal` event and re-deriving \"is this actually my direct\n * child\" with a plain function call, the same shape as `select` below.\n */\n requestReveal: (item: HTMLElement) => void;\n /**\n * Selects `value` (or clears the selection when `undefined`) and fires `change`. Called\n * directly by an activated item — mirrors `ore-radio-group`'s `RadioGroupContext.select()`.\n * No sibling bookkeeping needed here: every item's `selected` is *derived* from `value`, so\n * changing it here is the only thing that has to happen.\n */\n select: (value: string | undefined) => void;\n selectable: Readable<boolean>;\n /**\n * Single source of truth for the current selection — `ore-list-item` never owns its own\n * \"selected\" state; it's always derived by comparing its own `value` against this one (the\n * same shape as `ore-radio-group`'s `RadioGroupContext.value`).\n */\n value: Readable<string | undefined>;\n};\n/** Injection key for the list context. */\nexport const LIST_CTX = createContext<ListContext>('ListContext');\n\n/** Events emitted by the list component */\nexport type OreListEvents = {\n /** Emitted when the selected value changes (only when `selectable` is set). */\n change: { value: null | string };\n};\n\n/** List component properties */\nexport type OreListProps = {\n /** Disable the entire list — blocks pointer interaction and removes items from tab order */\n disabled?: boolean;\n /**\n * Enables single-selection listbox behavior: clicking (or pressing Enter/Space on) an item\n * selects it and deselects any previously-selected sibling. Arrow keys / Home / End move\n * focus between items. Omit for a plain, non-interactive display list.\n */\n selectable?: boolean;\n /** Size applied to all items (propagated via inherited CSS custom properties) */\n size?: ComponentSize;\n /**\n * Selected item's `value` (only meaningful when `selectable`) — the single source of truth for\n * selection. `ore-list-item` never owns its own selected state; set this directly, bind it for\n * two-way control, or read it back from `change`.\n */\n value?: string;\n /** Visual variant: 'plain' (default, no dividers) | 'bordered' (outer border + row dividers) | 'separated' (each item is its own card) */\n variant?: ListVariant;\n};\n\n/**\n * A vertical list container for `ore-list-item` children — plain display list by default, or a\n * keyboard-navigable single-select listbox via `selectable`. Each item can independently reveal\n * a left/right action panel via touch/pointer swipe (see `ore-list-item`'s `actions-left`/\n * `actions-right` slots) — useful for mobile-style row actions (archive, delete, …).\n *\n * @element ore-list\n * @element ore-list-item - Child element for each row\n *\n * @attr {boolean} disabled - Disable the entire list\n * @attr {boolean} selectable - Enable single-selection listbox behavior with arrow-key navigation\n * @attr {string} size - Size applied to all items: 'sm' | 'md' | 'lg'\n * @attr {string} value - Selected item's value (only meaningful when `selectable`) — the single source of truth for selection\n * @attr {string} variant - Visual variant: 'plain' | 'bordered' | 'separated'\n *\n * @fires change - Emitted when the selected value changes. detail: { value: string | null }\n *\n * @slot - `ore-list-item` elements\n *\n * @cssprop --list-radius - Border radius for the 'bordered'/'separated' variants\n *\n * @example\n * ```html\n * <ore-list variant=\"bordered\">\n * <ore-list-item>Inbox</ore-list-item>\n * <ore-list-item>Drafts</ore-list-item>\n * </ore-list>\n * <ore-list selectable value=\"inbox\">\n * <ore-list-item value=\"inbox\">Inbox</ore-list-item>\n * <ore-list-item value=\"drafts\">Drafts</ore-list-item>\n * </ore-list>\n * ```\n */\nexport const LIST_TAG = 'ore-list' as const;\ndefine<OreListProps>(LIST_TAG, {\n props: {\n ...disablableBundle,\n ...sizableBundle,\n selectable: prop.bool(false),\n value: prop.string(),\n variant: prop.string<ListVariant>(),\n },\n\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreListEvents>();\n\n const getItems = (): HTMLElement[] => [\n ...el.querySelectorAll<HTMLElement>(':scope > ore-list-item:not([disabled])'),\n ];\n\n const getAllItems = (): HTMLElement[] => [...el.querySelectorAll<HTMLElement>(':scope > ore-list-item')];\n\n // Reaches into each item's shadow root for its focusable row — mirrors `ore-accordion`'s\n // `getSummaryElements()` — rather than relying on `item.focus()` + `shadow: { delegatesFocus:\n // true }` to land focus correctly, since that cross-boundary reporting is inconsistent enough\n // between real browsers and jsdom that other multi-item components in this package\n // (`ore-menu`, `ore-tabs`) defensively check both forms too. Queried via `[part=\"row\"]`, not\n // the `.row` class — `part` is list-item's declared public seam for exactly this kind of\n // cross-component reach; the class name is a private styling detail that could change.\n const getRow = (item: Element): HTMLElement | null =>\n item.shadowRoot?.querySelector<HTMLElement>('[part=\"row\"]') ?? null;\n\n const getRows = (): HTMLElement[] =>\n getItems()\n .map(getRow)\n .filter((row): row is HTMLElement => row != null);\n\n const listControl = createListControl<HTMLElement>({\n getItems,\n loop: true,\n onNavigate: (_action, index) => {\n getRow(getItems()[index])?.focus();\n },\n signal: lifecycleSignal(onCleanup),\n });\n\n // Selection — `selectedValue` is the single source of truth (mirrors `ore-radio-group`'s\n // `selectedValue`/`RadioGroupContext.value` pattern): reflected onto the `value` attribute,\n // synced back in when set externally, and read by every item via context to derive its own\n // `selected` state. No sibling-clearing needed anywhere — changing this one signal is enough.\n const selectedValue = signal<string | undefined>(props.value.value);\n\n watch(props.value, (value) => {\n selectedValue.value = value;\n });\n\n const select = (value: string | undefined): void => {\n if (selectedValue.value === value) return;\n\n selectedValue.value = value;\n emit('change', { value: value ?? null });\n };\n\n // Only one item's swipe-revealed action panel is open at a time. The item calls this\n // directly the moment its own `revealed` attribute transitions to non-null — see\n // `ListContext.requestReveal`'s doc comment for why this replaced a bubbled event.\n const requestReveal = (item: HTMLElement): void => {\n for (const sibling of getAllItems()) {\n if (sibling !== item) sibling.removeAttribute('revealed');\n }\n };\n\n // Closes any swipe-revealed item when the user interacts anywhere outside of it — matches\n // the outside-pointerdown-closes pattern used by ore-date-picker/ore-time-picker's popovers.\n const handleOutsidePointerDown = (event: PointerEvent): void => {\n const open = getAllItems().find((item) => item.hasAttribute('revealed'));\n\n if (!open || event.composedPath().includes(open)) return;\n\n open.removeAttribute('revealed');\n };\n\n document.addEventListener('pointerdown', handleOutsidePointerDown, { capture: true });\n onCleanup(() => document.removeEventListener('pointerdown', handleOutsidePointerDown, { capture: true }));\n\n provide(LIST_CTX, {\n requestReveal,\n select,\n selectable: computed(() => Boolean(props.selectable.value)),\n value: selectedValue,\n });\n\n bind({\n attr: {\n 'aria-disabled': () => (props.disabled.value ? 'true' : null),\n role: () => (props.selectable.value ? 'listbox' : 'list'),\n value: () => selectedValue.value ?? null,\n },\n on: {\n keydown: (event: KeyboardEvent) => {\n if (!props.selectable.value || props.disabled.value) return;\n\n const row = event\n .composedPath()\n .find((node): node is HTMLElement => node instanceof HTMLElement && node.getAttribute('part') === 'row');\n\n if (!row) return;\n\n const focused = getRows().indexOf(row);\n\n if (focused === -1) return;\n\n listControl.set(focused);\n listControl.handleKeydown(event);\n },\n },\n });\n\n return html`\n <slot></slot>\n `;\n },\n\n styles: [sizeVariantMixin(LIST_SIZE_PRESET), componentStyles],\n});\n"],"mappings":";;;;;;;;;AAoCA,IAAa,IAAW,EAA2B,aAAa,GA+DnD,IAAW;AACxB,EAAqB,GAAU;CAC7B,OAAO;EACL,GAAG;EACH,GAAG;EACH,YAAY,EAAK,KAAK,EAAK;EAC3B,OAAO,EAAK,OAAO;EACnB,SAAS,EAAK,OAAoB;CACpC;CAEA,MAAM,GAAO;EACX,IAAM,IAAK,EAAQ,GACb,IAAO,EAAuB,GAE9B,UAAgC,CACpC,GAAG,EAAG,iBAA8B,wCAAwC,CAC9E,GAEM,UAAmC,CAAC,GAAG,EAAG,iBAA8B,wBAAwB,CAAC,GASjG,KAAU,MACd,EAAK,YAAY,cAA2B,gBAAc,KAAK,MAE3D,UACJ,EAAS,CAAC,CACP,IAAI,CAAM,CAAC,CACX,QAAQ,MAA4B,KAAO,IAAI,GAE9C,IAAc,EAA+B;GACjD;GACA,MAAM;GACN,aAAa,GAAS,MAAU;IAC9B,EAAO,EAAS,CAAC,CAAC,EAAM,CAAC,EAAE,MAAM;GACnC;GACA,QAAQ,EAAgB,CAAS;EACnC,CAAC,GAMK,IAAgB,EAA2B,EAAM,MAAM,KAAK;EAElE,EAAM,EAAM,QAAQ,MAAU;GAC5B,EAAc,QAAQ;EACxB,CAAC;EAED,IAAM,KAAU,MAAoC;GAC9C,EAAc,UAAU,MAE5B,EAAc,QAAQ,GACtB,EAAK,UAAU,EAAE,OAAO,KAAS,KAAK,CAAC;EACzC,GAKM,KAAiB,MAA4B;GACjD,KAAK,IAAM,KAAW,EAAY,GAChC,AAAI,MAAY,KAAM,EAAQ,gBAAgB,UAAU;EAE5D,GAIM,KAA4B,MAA8B;GAC9D,IAAM,IAAO,EAAY,CAAC,CAAC,MAAM,MAAS,EAAK,aAAa,UAAU,CAAC;GAEnE,CAAC,KAAQ,EAAM,aAAa,CAAC,CAAC,SAAS,CAAI,KAE/C,EAAK,gBAAgB,UAAU;EACjC;EAsCA,OApCA,SAAS,iBAAiB,eAAe,GAA0B,EAAE,SAAS,GAAK,CAAC,GACpF,QAAgB,SAAS,oBAAoB,eAAe,GAA0B,EAAE,SAAS,GAAK,CAAC,CAAC,GAExG,EAAQ,GAAU;GAChB;GACA;GACA,YAAY,QAAe,EAAQ,EAAM,WAAW,KAAM;GAC1D,OAAO;EACT,CAAC,GAED,EAAK;GACH,MAAM;IACJ,uBAAwB,EAAM,SAAS,QAAQ,SAAS;IACxD,YAAa,EAAM,WAAW,QAAQ,YAAY;IAClD,aAAa,EAAc,SAAS;GACtC;GACA,IAAI,EACF,UAAU,MAAyB;IACjC,IAAI,CAAC,EAAM,WAAW,SAAS,EAAM,SAAS,OAAO;IAErD,IAAM,IAAM,EACT,aAAa,CAAC,CACd,MAAM,MAA8B,aAAgB,eAAe,EAAK,aAAa,MAAM,MAAM,KAAK;IAEzG,IAAI,CAAC,GAAK;IAEV,IAAM,IAAU,EAAQ,CAAC,CAAC,QAAQ,CAAG;IAEjC,MAAY,OAEhB,EAAY,IAAI,CAAO,GACvB,EAAY,cAAc,CAAK;GACjC,EACF;EACF,CAAC,GAEM,CAAI;;;CAGb;CAEA,QAAQ,CAAC,EAAiB,CAAgB,GAAG,CAAe;AAC9D,CAAC"}
|
package/dist/marquee.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./content/marquee/marquee.css.cjs");let t=require("@vielzeug/ore"),n=require("@vielzeug/ripple
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./content/marquee/marquee.css.cjs");let t=require("@vielzeug/ore"),n=require("@vielzeug/ripple");var r=`ore-marquee`;(0,t.define)(r,{props:{color:t.prop.string(),direction:t.prop.string(`left`),duration:t.prop.number(20),"pause-on-hover":t.prop.bool(!1),"show-controls":t.prop.bool(!0)},setup(e){let r=(0,t.getHost)(),i=0,a=[],o=[],s=null,c=0,l=null,u=null,d=t=>{if(!u||o.length===0)return;i=(t+o.length)%o.length;let n=o[i];if(!n||c===0)return;let r=e.duration.value??20,a=-(n.offsetLeft/c*r);u.style.setProperty(`animation-delay`,`${a}s`)};return(0,n.watch)(e.duration,e=>{r.style.setProperty(`--_marquee-duration`,`${e??20}s`)},{immediate:!0}),(0,t.onMounted)(()=>{u=r.shadowRoot?.querySelector(`.track`)??null;let e=r.shadowRoot?.querySelector(`slot`)??null,t=()=>{a.forEach(e=>e.remove()),a=[]},n=()=>{a.push(...o.map(e=>{let t=e.cloneNode(!0);return t.setAttribute(`aria-hidden`,`true`),t.setAttribute(`data-marquee-clone`,``),t.setAttribute(`inert`,``),r.appendChild(t),t}))},d=()=>{if(!u||o.length===0)return;let e=u;s!==null&&cancelAnimationFrame(s),t(),c=0,e.style.removeProperty(`--_marquee-translate`),n(),s=requestAnimationFrame(()=>{s=null;let t=a[0],i=o[0];if(!t||!i||(c=t.offsetLeft-i.offsetLeft,c<=0))return;let l=Math.max(2,Math.ceil((r.clientWidth+c)/c));for(let e=2;e<l;e+=1)n();e.style.setProperty(`--_marquee-translate`,`-${c}px`)})},f=()=>{let t=(e?.assignedElements()??[]).filter(e=>e instanceof HTMLElement&&!e.hasAttribute(`data-marquee-clone`));(t.length!==o.length||t.some((e,t)=>e!==o[t]))&&(o=t,i=Math.min(i,Math.max(o.length-1,0)),d())};return l=typeof ResizeObserver>`u`?null:new ResizeObserver(d),l?.observe(r),e?.addEventListener(`slotchange`,f),f(),()=>{s!==null&&cancelAnimationFrame(s),l?.disconnect(),e?.removeEventListener(`slotchange`,f),t(),u=null,o=[],c=0}}),t.html`
|
|
2
2
|
<div class="track" part="track" aria-live="off">
|
|
3
3
|
<slot></slot>
|
|
4
4
|
</div>
|
package/dist/marquee.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marquee.cjs","names":[],"sources":["../src/content/marquee/marquee.ts"],"sourcesContent":["import { define, getHost, html, onMounted, prop } from '@vielzeug/ore';\nimport { watch } from '@vielzeug/ripple
|
|
1
|
+
{"version":3,"file":"marquee.cjs","names":[],"sources":["../src/content/marquee/marquee.ts"],"sourcesContent":["import { define, getHost, html, onMounted, prop } from '@vielzeug/ore';\nimport { watch } from '@vielzeug/ripple';\n\nimport type { ThemeColor } from '../../types';\n\nimport '../icon/icon';\nimport '../../inputs/button/button';\nimport componentStyles from './marquee.css?inline';\n\nexport type MarqueeDirection = 'left' | 'right';\n\nexport type OreMarqueeProps = {\n /** Theme color for the navigation controls. */\n color?: ThemeColor;\n /** Scroll direction. Defaults to `'left'`. */\n direction?: MarqueeDirection;\n /** Duration in seconds for one complete ticker cycle. Defaults to `20`. */\n duration?: number;\n /** Pause the ticker while it is hovered. Defaults to `false`. */\n 'pause-on-hover'?: boolean;\n /** Show previous/next navigation controls. Defaults to `true`. */\n 'show-controls'?: boolean;\n};\n\n/**\n * A CSS-driven, continuously scrolling ticker.\n *\n * Direct child elements are duplicated internally for a seamless loop. Cloned\n * content is inert and hidden from assistive technology, so author interactive\n * content only in the original children.\n *\n * @element ore-marquee\n *\n * @attr {string} color - Theme color for the navigation controls.\n * @attr {number} duration - Duration in seconds for one ticker cycle (default: 20)\n * @attr {string} direction - 'left' (default) | 'right'\n * @attr {boolean} pause-on-hover - Pause while hovered (default: false)\n * @attr {boolean} show-controls - Show previous/next controls (default: true)\n *\n * @cssprop --marquee-gap - Gap between ticker items (default: var(--size-4))\n *\n * @part track - The animated ticker track.\n * @example\n * ```html\n * <ore-marquee duration=\"24\" pause-on-hover>\n * <span>Free shipping</span>\n * <span>New arrivals</span>\n * </ore-marquee>\n * ```\n */\nexport const MARQUEE_TAG = 'ore-marquee' as const;\n\ndefine<OreMarqueeProps>(MARQUEE_TAG, {\n props: {\n color: prop.string<ThemeColor>(),\n direction: prop.string<MarqueeDirection>('left'),\n duration: prop.number(20),\n 'pause-on-hover': prop.bool(false),\n 'show-controls': prop.bool(true),\n },\n setup(props) {\n const el = getHost();\n let activeIndex = 0;\n let clones: HTMLElement[] = [];\n let items: HTMLElement[] = [];\n let layoutFrame: number | null = null;\n let loopWidth = 0;\n let resizeObserver: ResizeObserver | null = null;\n let track: HTMLElement | null = null;\n\n const seekTo = (index: number): void => {\n if (!track || items.length === 0) return;\n\n activeIndex = (index + items.length) % items.length;\n\n const item = items[activeIndex];\n\n if (!item || loopWidth === 0) return;\n\n const duration = props.duration.value ?? 20;\n const delay = -((item.offsetLeft / loopWidth) * duration);\n\n track.style.setProperty('animation-delay', `${delay}s`);\n };\n\n watch(\n props.duration,\n (duration) => {\n el.style.setProperty('--_marquee-duration', `${duration ?? 20}s`);\n },\n { immediate: true },\n );\n\n onMounted(() => {\n track = el.shadowRoot?.querySelector<HTMLElement>('.track') ?? null;\n\n const slot = el.shadowRoot?.querySelector<HTMLSlotElement>('slot') ?? null;\n\n const removeClones = (): void => {\n clones.forEach((clone) => clone.remove());\n clones = [];\n };\n\n const appendCloneSet = (): void => {\n clones.push(\n ...items.map((item) => {\n const clone = item.cloneNode(true) as HTMLElement;\n\n clone.setAttribute('aria-hidden', 'true');\n clone.setAttribute('data-marquee-clone', '');\n clone.setAttribute('inert', '');\n el.appendChild(clone);\n\n return clone;\n }),\n );\n };\n\n const syncLoop = (): void => {\n if (!track || items.length === 0) return;\n\n const marqueeTrack = track;\n\n if (layoutFrame !== null) cancelAnimationFrame(layoutFrame);\n\n removeClones();\n loopWidth = 0;\n marqueeTrack.style.removeProperty('--_marquee-translate');\n appendCloneSet();\n\n layoutFrame = requestAnimationFrame(() => {\n layoutFrame = null;\n\n const firstClone = clones[0];\n const firstItem = items[0];\n\n if (!firstClone || !firstItem) return;\n\n loopWidth = firstClone.offsetLeft - firstItem.offsetLeft;\n\n if (loopWidth <= 0) return;\n\n const requiredSets = Math.max(2, Math.ceil((el.clientWidth + loopWidth) / loopWidth));\n\n for (let set = 2; set < requiredSets; set += 1) appendCloneSet();\n\n marqueeTrack.style.setProperty('--_marquee-translate', `-${loopWidth}px`);\n });\n };\n\n const refreshItems = (): void => {\n const nextItems = (slot?.assignedElements() ?? []).filter(\n (child): child is HTMLElement => child instanceof HTMLElement && !child.hasAttribute('data-marquee-clone'),\n );\n const itemsChanged =\n nextItems.length !== items.length || nextItems.some((item, index) => item !== items[index]);\n\n if (!itemsChanged) return;\n\n items = nextItems;\n activeIndex = Math.min(activeIndex, Math.max(items.length - 1, 0));\n syncLoop();\n };\n\n resizeObserver = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(syncLoop);\n resizeObserver?.observe(el);\n slot?.addEventListener('slotchange', refreshItems);\n refreshItems();\n\n return () => {\n if (layoutFrame !== null) cancelAnimationFrame(layoutFrame);\n\n resizeObserver?.disconnect();\n slot?.removeEventListener('slotchange', refreshItems);\n removeClones();\n track = null;\n items = [];\n loopWidth = 0;\n };\n });\n\n return html`\n <div class=\"track\" part=\"track\" aria-live=\"off\">\n <slot></slot>\n </div>\n ${() =>\n props['show-controls'].value !== false\n ? html`\n <div class=\"controls\" part=\"controls\">\n <ore-button\n class=\"nav-btn prev-btn\"\n part=\"prev-btn\"\n variant=\"ghost\"\n color=${() => props.color.value}\n rounded\n icon-only\n label=\"Previous item\"\n @click=${(event: Event) => {\n event.stopPropagation();\n seekTo(activeIndex - 1);\n }}>\n <ore-icon name=\"chevron-left\" size=\"16\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n </ore-button>\n <ore-button\n class=\"nav-btn next-btn\"\n part=\"next-btn\"\n variant=\"ghost\"\n color=${() => props.color.value}\n rounded\n icon-only\n label=\"Next item\"\n @click=${(event: Event) => {\n event.stopPropagation();\n seekTo(activeIndex + 1);\n }}>\n <ore-icon name=\"chevron-right\" size=\"16\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n </ore-button>\n </div>\n `\n : null}\n `;\n },\n styles: [componentStyles],\n});\n"],"mappings":"qLAkDA,IAAa,EAAc,eAE3B,EAAA,EAAA,OAAA,CAAwB,EAAa,CACnC,MAAO,CACL,MAAO,EAAA,KAAK,OAAmB,EAC/B,UAAW,EAAA,KAAK,OAAyB,MAAM,EAC/C,SAAU,EAAA,KAAK,OAAO,EAAE,EACxB,iBAAkB,EAAA,KAAK,KAAK,EAAK,EACjC,gBAAiB,EAAA,KAAK,KAAK,EAAI,CACjC,EACA,MAAM,EAAO,CACX,IAAM,GAAA,EAAK,EAAA,QAAA,CAAQ,EACf,EAAc,EACd,EAAwB,CAAC,EACzB,EAAuB,CAAC,EACxB,EAA6B,KAC7B,EAAY,EACZ,EAAwC,KACxC,EAA4B,KAE1B,EAAU,GAAwB,CACtC,GAAI,CAAC,GAAS,EAAM,SAAW,EAAG,OAElC,GAAe,EAAQ,EAAM,QAAU,EAAM,OAE7C,IAAM,EAAO,EAAM,GAEnB,GAAI,CAAC,GAAQ,IAAc,EAAG,OAE9B,IAAM,EAAW,EAAM,SAAS,OAAS,GACnC,EAAQ,EAAG,EAAK,WAAa,EAAa,GAEhD,EAAM,MAAM,YAAY,kBAAmB,GAAG,EAAM,EAAE,CACxD,EAkGA,OAhGA,EAAA,EAAA,MAAA,CACE,EAAM,SACL,GAAa,CACZ,EAAG,MAAM,YAAY,sBAAuB,GAAG,GAAY,GAAG,EAAE,CAClE,EACA,CAAE,UAAW,EAAK,CACpB,GAEA,EAAA,EAAA,UAAA,KAAgB,CACd,EAAQ,EAAG,YAAY,cAA2B,QAAQ,GAAK,KAE/D,IAAM,EAAO,EAAG,YAAY,cAA+B,MAAM,GAAK,KAEhE,MAA2B,CAC/B,EAAO,QAAS,GAAU,EAAM,OAAO,CAAC,EACxC,EAAS,CAAC,CACZ,EAEM,MAA6B,CACjC,EAAO,KACL,GAAG,EAAM,IAAK,GAAS,CACrB,IAAM,EAAQ,EAAK,UAAU,EAAI,EAOjC,OALA,EAAM,aAAa,cAAe,MAAM,EACxC,EAAM,aAAa,qBAAsB,EAAE,EAC3C,EAAM,aAAa,QAAS,EAAE,EAC9B,EAAG,YAAY,CAAK,EAEb,CACT,CAAC,CACH,CACF,EAEM,MAAuB,CAC3B,GAAI,CAAC,GAAS,EAAM,SAAW,EAAG,OAElC,IAAM,EAAe,EAEjB,IAAgB,MAAM,qBAAqB,CAAW,EAE1D,EAAa,EACb,EAAY,EACZ,EAAa,MAAM,eAAe,sBAAsB,EACxD,EAAe,EAEf,EAAc,0BAA4B,CACxC,EAAc,KAEd,IAAM,EAAa,EAAO,GACpB,EAAY,EAAM,GAMxB,GAJI,CAAC,GAAc,CAAC,IAEpB,EAAY,EAAW,WAAa,EAAU,WAE1C,GAAa,GAAG,OAEpB,IAAM,EAAe,KAAK,IAAI,EAAG,KAAK,MAAM,EAAG,YAAc,GAAa,CAAS,CAAC,EAEpF,IAAK,IAAI,EAAM,EAAG,EAAM,EAAc,GAAO,EAAG,EAAe,EAE/D,EAAa,MAAM,YAAY,uBAAwB,IAAI,EAAU,GAAG,CAC1E,CAAC,CACH,EAEM,MAA2B,CAC/B,IAAM,GAAa,GAAM,iBAAiB,GAAK,CAAC,EAAA,CAAG,OAChD,GAAgC,aAAiB,aAAe,CAAC,EAAM,aAAa,oBAAoB,CAC3G,GAEE,EAAU,SAAW,EAAM,QAAU,EAAU,MAAM,EAAM,IAAU,IAAS,EAAM,EAAM,KAI5F,EAAQ,EACR,EAAc,KAAK,IAAI,EAAa,KAAK,IAAI,EAAM,OAAS,EAAG,CAAC,CAAC,EACjE,EAAS,EACX,EAOA,MALA,GAAiB,OAAO,eAAmB,IAAc,KAAO,IAAI,eAAe,CAAQ,EAC3F,GAAgB,QAAQ,CAAE,EAC1B,GAAM,iBAAiB,aAAc,CAAY,EACjD,EAAa,MAEA,CACP,IAAgB,MAAM,qBAAqB,CAAW,EAE1D,GAAgB,WAAW,EAC3B,GAAM,oBAAoB,aAAc,CAAY,EACpD,EAAa,EACb,EAAQ,KACR,EAAQ,CAAC,EACT,EAAY,CACd,CACF,CAAC,EAEM,EAAA,IAAI;;;;YAKP,EAAM,gBAAgB,CAAC,QAAU,GAiC7B,KAhCA,EAAA,IAAI;;;;;;8BAMgB,EAAM,MAAM,MAAM;;;;2BAItB,GAAiB,CACzB,EAAM,gBAAgB,EACtB,EAAO,EAAc,CAAC,CACxB,EAAE;;;;;;;8BAOY,EAAM,MAAM,MAAM;;;;2BAItB,GAAiB,CACzB,EAAM,gBAAgB,EACtB,EAAO,EAAc,CAAC,CACxB,EAAE;;;;cAKH;KAEf,EACA,OAAQ,CAAC,EAAA,OAAe,CAC1B,CAAC"}
|
package/dist/marquee.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import e from "./content/marquee/marquee.css.js";
|
|
2
2
|
import { define as t, getHost as n, html as r, onMounted as i, prop as a } from "@vielzeug/ore";
|
|
3
|
-
import { watch as o } from "@vielzeug/ripple
|
|
3
|
+
import { watch as o } from "@vielzeug/ripple";
|
|
4
4
|
//#region src/content/marquee/marquee.ts
|
|
5
5
|
var s = "ore-marquee";
|
|
6
6
|
t(s, {
|
package/dist/marquee.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marquee.js","names":[],"sources":["../src/content/marquee/marquee.ts"],"sourcesContent":["import { define, getHost, html, onMounted, prop } from '@vielzeug/ore';\nimport { watch } from '@vielzeug/ripple
|
|
1
|
+
{"version":3,"file":"marquee.js","names":[],"sources":["../src/content/marquee/marquee.ts"],"sourcesContent":["import { define, getHost, html, onMounted, prop } from '@vielzeug/ore';\nimport { watch } from '@vielzeug/ripple';\n\nimport type { ThemeColor } from '../../types';\n\nimport '../icon/icon';\nimport '../../inputs/button/button';\nimport componentStyles from './marquee.css?inline';\n\nexport type MarqueeDirection = 'left' | 'right';\n\nexport type OreMarqueeProps = {\n /** Theme color for the navigation controls. */\n color?: ThemeColor;\n /** Scroll direction. Defaults to `'left'`. */\n direction?: MarqueeDirection;\n /** Duration in seconds for one complete ticker cycle. Defaults to `20`. */\n duration?: number;\n /** Pause the ticker while it is hovered. Defaults to `false`. */\n 'pause-on-hover'?: boolean;\n /** Show previous/next navigation controls. Defaults to `true`. */\n 'show-controls'?: boolean;\n};\n\n/**\n * A CSS-driven, continuously scrolling ticker.\n *\n * Direct child elements are duplicated internally for a seamless loop. Cloned\n * content is inert and hidden from assistive technology, so author interactive\n * content only in the original children.\n *\n * @element ore-marquee\n *\n * @attr {string} color - Theme color for the navigation controls.\n * @attr {number} duration - Duration in seconds for one ticker cycle (default: 20)\n * @attr {string} direction - 'left' (default) | 'right'\n * @attr {boolean} pause-on-hover - Pause while hovered (default: false)\n * @attr {boolean} show-controls - Show previous/next controls (default: true)\n *\n * @cssprop --marquee-gap - Gap between ticker items (default: var(--size-4))\n *\n * @part track - The animated ticker track.\n * @example\n * ```html\n * <ore-marquee duration=\"24\" pause-on-hover>\n * <span>Free shipping</span>\n * <span>New arrivals</span>\n * </ore-marquee>\n * ```\n */\nexport const MARQUEE_TAG = 'ore-marquee' as const;\n\ndefine<OreMarqueeProps>(MARQUEE_TAG, {\n props: {\n color: prop.string<ThemeColor>(),\n direction: prop.string<MarqueeDirection>('left'),\n duration: prop.number(20),\n 'pause-on-hover': prop.bool(false),\n 'show-controls': prop.bool(true),\n },\n setup(props) {\n const el = getHost();\n let activeIndex = 0;\n let clones: HTMLElement[] = [];\n let items: HTMLElement[] = [];\n let layoutFrame: number | null = null;\n let loopWidth = 0;\n let resizeObserver: ResizeObserver | null = null;\n let track: HTMLElement | null = null;\n\n const seekTo = (index: number): void => {\n if (!track || items.length === 0) return;\n\n activeIndex = (index + items.length) % items.length;\n\n const item = items[activeIndex];\n\n if (!item || loopWidth === 0) return;\n\n const duration = props.duration.value ?? 20;\n const delay = -((item.offsetLeft / loopWidth) * duration);\n\n track.style.setProperty('animation-delay', `${delay}s`);\n };\n\n watch(\n props.duration,\n (duration) => {\n el.style.setProperty('--_marquee-duration', `${duration ?? 20}s`);\n },\n { immediate: true },\n );\n\n onMounted(() => {\n track = el.shadowRoot?.querySelector<HTMLElement>('.track') ?? null;\n\n const slot = el.shadowRoot?.querySelector<HTMLSlotElement>('slot') ?? null;\n\n const removeClones = (): void => {\n clones.forEach((clone) => clone.remove());\n clones = [];\n };\n\n const appendCloneSet = (): void => {\n clones.push(\n ...items.map((item) => {\n const clone = item.cloneNode(true) as HTMLElement;\n\n clone.setAttribute('aria-hidden', 'true');\n clone.setAttribute('data-marquee-clone', '');\n clone.setAttribute('inert', '');\n el.appendChild(clone);\n\n return clone;\n }),\n );\n };\n\n const syncLoop = (): void => {\n if (!track || items.length === 0) return;\n\n const marqueeTrack = track;\n\n if (layoutFrame !== null) cancelAnimationFrame(layoutFrame);\n\n removeClones();\n loopWidth = 0;\n marqueeTrack.style.removeProperty('--_marquee-translate');\n appendCloneSet();\n\n layoutFrame = requestAnimationFrame(() => {\n layoutFrame = null;\n\n const firstClone = clones[0];\n const firstItem = items[0];\n\n if (!firstClone || !firstItem) return;\n\n loopWidth = firstClone.offsetLeft - firstItem.offsetLeft;\n\n if (loopWidth <= 0) return;\n\n const requiredSets = Math.max(2, Math.ceil((el.clientWidth + loopWidth) / loopWidth));\n\n for (let set = 2; set < requiredSets; set += 1) appendCloneSet();\n\n marqueeTrack.style.setProperty('--_marquee-translate', `-${loopWidth}px`);\n });\n };\n\n const refreshItems = (): void => {\n const nextItems = (slot?.assignedElements() ?? []).filter(\n (child): child is HTMLElement => child instanceof HTMLElement && !child.hasAttribute('data-marquee-clone'),\n );\n const itemsChanged =\n nextItems.length !== items.length || nextItems.some((item, index) => item !== items[index]);\n\n if (!itemsChanged) return;\n\n items = nextItems;\n activeIndex = Math.min(activeIndex, Math.max(items.length - 1, 0));\n syncLoop();\n };\n\n resizeObserver = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(syncLoop);\n resizeObserver?.observe(el);\n slot?.addEventListener('slotchange', refreshItems);\n refreshItems();\n\n return () => {\n if (layoutFrame !== null) cancelAnimationFrame(layoutFrame);\n\n resizeObserver?.disconnect();\n slot?.removeEventListener('slotchange', refreshItems);\n removeClones();\n track = null;\n items = [];\n loopWidth = 0;\n };\n });\n\n return html`\n <div class=\"track\" part=\"track\" aria-live=\"off\">\n <slot></slot>\n </div>\n ${() =>\n props['show-controls'].value !== false\n ? html`\n <div class=\"controls\" part=\"controls\">\n <ore-button\n class=\"nav-btn prev-btn\"\n part=\"prev-btn\"\n variant=\"ghost\"\n color=${() => props.color.value}\n rounded\n icon-only\n label=\"Previous item\"\n @click=${(event: Event) => {\n event.stopPropagation();\n seekTo(activeIndex - 1);\n }}>\n <ore-icon name=\"chevron-left\" size=\"16\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n </ore-button>\n <ore-button\n class=\"nav-btn next-btn\"\n part=\"next-btn\"\n variant=\"ghost\"\n color=${() => props.color.value}\n rounded\n icon-only\n label=\"Next item\"\n @click=${(event: Event) => {\n event.stopPropagation();\n seekTo(activeIndex + 1);\n }}>\n <ore-icon name=\"chevron-right\" size=\"16\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n </ore-button>\n </div>\n `\n : null}\n `;\n },\n styles: [componentStyles],\n});\n"],"mappings":";;;;AAkDA,IAAa,IAAc;AAE3B,EAAwB,GAAa;CACnC,OAAO;EACL,OAAO,EAAK,OAAmB;EAC/B,WAAW,EAAK,OAAyB,MAAM;EAC/C,UAAU,EAAK,OAAO,EAAE;EACxB,kBAAkB,EAAK,KAAK,EAAK;EACjC,iBAAiB,EAAK,KAAK,EAAI;CACjC;CACA,MAAM,GAAO;EACX,IAAM,IAAK,EAAQ,GACf,IAAc,GACd,IAAwB,CAAC,GACzB,IAAuB,CAAC,GACxB,IAA6B,MAC7B,IAAY,GACZ,IAAwC,MACxC,IAA4B,MAE1B,KAAU,MAAwB;GACtC,IAAI,CAAC,KAAS,EAAM,WAAW,GAAG;GAElC,KAAe,IAAQ,EAAM,UAAU,EAAM;GAE7C,IAAM,IAAO,EAAM;GAEnB,IAAI,CAAC,KAAQ,MAAc,GAAG;GAE9B,IAAM,IAAW,EAAM,SAAS,SAAS,IACnC,IAAQ,EAAG,EAAK,aAAa,IAAa;GAEhD,EAAM,MAAM,YAAY,mBAAmB,GAAG,EAAM,EAAE;EACxD;EAkGA,OAhGA,EACE,EAAM,WACL,MAAa;GACZ,EAAG,MAAM,YAAY,uBAAuB,GAAG,KAAY,GAAG,EAAE;EAClE,GACA,EAAE,WAAW,GAAK,CACpB,GAEA,QAAgB;GACd,IAAQ,EAAG,YAAY,cAA2B,QAAQ,KAAK;GAE/D,IAAM,IAAO,EAAG,YAAY,cAA+B,MAAM,KAAK,MAEhE,UAA2B;IAE/B,AADA,EAAO,SAAS,MAAU,EAAM,OAAO,CAAC,GACxC,IAAS,CAAC;GACZ,GAEM,UAA6B;IACjC,EAAO,KACL,GAAG,EAAM,KAAK,MAAS;KACrB,IAAM,IAAQ,EAAK,UAAU,EAAI;KAOjC,OALA,EAAM,aAAa,eAAe,MAAM,GACxC,EAAM,aAAa,sBAAsB,EAAE,GAC3C,EAAM,aAAa,SAAS,EAAE,GAC9B,EAAG,YAAY,CAAK,GAEb;IACT,CAAC,CACH;GACF,GAEM,UAAuB;IAC3B,IAAI,CAAC,KAAS,EAAM,WAAW,GAAG;IAElC,IAAM,IAAe;IASrB,AAPI,MAAgB,QAAM,qBAAqB,CAAW,GAE1D,EAAa,GACb,IAAY,GACZ,EAAa,MAAM,eAAe,sBAAsB,GACxD,EAAe,GAEf,IAAc,4BAA4B;KACxC,IAAc;KAEd,IAAM,IAAa,EAAO,IACpB,IAAY,EAAM;KAMxB,IAJI,CAAC,KAAc,CAAC,MAEpB,IAAY,EAAW,aAAa,EAAU,YAE1C,KAAa,IAAG;KAEpB,IAAM,IAAe,KAAK,IAAI,GAAG,KAAK,MAAM,EAAG,cAAc,KAAa,CAAS,CAAC;KAEpF,KAAK,IAAI,IAAM,GAAG,IAAM,GAAc,KAAO,GAAG,EAAe;KAE/D,EAAa,MAAM,YAAY,wBAAwB,IAAI,EAAU,GAAG;IAC1E,CAAC;GACH,GAEM,UAA2B;IAC/B,IAAM,KAAa,GAAM,iBAAiB,KAAK,CAAC,EAAA,CAAG,QAChD,MAAgC,aAAiB,eAAe,CAAC,EAAM,aAAa,oBAAoB,CAC3G;IAEE,GAAU,WAAW,EAAM,UAAU,EAAU,MAAM,GAAM,MAAU,MAAS,EAAM,EAAM,OAI5F,IAAQ,GACR,IAAc,KAAK,IAAI,GAAa,KAAK,IAAI,EAAM,SAAS,GAAG,CAAC,CAAC,GACjE,EAAS;GACX;GAOA,OALA,IAAiB,OAAO,iBAAmB,MAAc,OAAO,IAAI,eAAe,CAAQ,GAC3F,GAAgB,QAAQ,CAAE,GAC1B,GAAM,iBAAiB,cAAc,CAAY,GACjD,EAAa,SAEA;IAQX,AAPI,MAAgB,QAAM,qBAAqB,CAAW,GAE1D,GAAgB,WAAW,GAC3B,GAAM,oBAAoB,cAAc,CAAY,GACpD,EAAa,GACb,IAAQ,MACR,IAAQ,CAAC,GACT,IAAY;GACd;EACF,CAAC,GAEM,CAAI;;;;cAKP,EAAM,gBAAgB,CAAC,UAAU,KAiC7B,OAhCA,CAAI;;;;;;gCAMgB,EAAM,MAAM,MAAM;;;;4BAItB,MAAiB;GAEzB,AADA,EAAM,gBAAgB,GACtB,EAAO,IAAc,CAAC;EACxB,EAAE;;;;;;;gCAOY,EAAM,MAAM,MAAM;;;;4BAItB,MAAiB;GAEzB,AADA,EAAM,gBAAgB,GACtB,EAAO,IAAc,CAAC;EACxB,EAAE;;;;cAKH;;CAEf;CACA,QAAQ,CAAC,CAAe;AAC1B,CAAC"}
|
package/dist/menu.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./styles/mixins/theme.css.cjs"),n=require("./core/keyboard.cjs"),r=require("./core/ore.cjs"),i=require("./core/overlay.cjs"),a=require("./core/nav.cjs"),o=require("./core/positioner.cjs"),s=require("./shared/prop-bundles.cjs"),c=require("./shared/size-presets.cjs"),l=require("./overlay/menu/menu.css.cjs"),u=require("./overlay/menu/menu-item.css.cjs"),d=require("./overlay/menu/menu-separator.css.cjs");let f=require("@vielzeug/ore"),p=require("@vielzeug/ripple");var m=`ore-menu-item`;(0,f.define)(m,{props:{checked:f.prop.bool(!1),disabled:f.prop.bool(!1),type:f.prop.string(),value:f.prop.string()},setup(e){let t=()=>e.type.value===`checkbox`||e.type.value===`radio`,n=()=>t()&&e.checked.value;return t()?f.html`
|
|
2
2
|
<div
|
|
3
3
|
class="${()=>{let t=e.type.value;return[`item`,t===`checkbox`?`is-checkbox`:``,t===`radio`?`is-radio`:``,n()?`is-checked`:``].filter(Boolean).join(` `)}}"
|
|
4
4
|
tabindex="-1"
|
|
@@ -14,7 +14,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
|
|
|
14
14
|
<span class="icon-slot"><slot name="icon"></slot></span>
|
|
15
15
|
<span class="item-label"><slot></slot></span>
|
|
16
16
|
</div>
|
|
17
|
-
`},styles:[
|
|
17
|
+
`},styles:[t.colorThemeMixin,u.default]});var h=`ore-menu-separator`;(0,f.define)(h,{setup(){return f.html``},styles:[d.default]});var g=e=>e===`checkbox`||e===`radio`,_=e=>e==null?void 0:e===``||e===`true`,v=`ore-menu`;(0,f.define)(v,{props:{...s.sizableBundle,...s.disablableBundle,"default-open":f.prop.bool(!1),open:{default:void 0,parse:_},placement:f.prop.oneOf([`bottom`,`bottom-start`,`bottom-end`,`top`,`top-start`,`top-end`],`bottom-start`)},setup(e){let t=(0,f.getHost)(),s=(0,f.useEmit)(),c=(0,f.useSlots)(),l=f.watchEffect,u=(0,f.createStableId)(`menu`),d=(0,p.computed)(()=>!!e.disabled.value),m=r.lifecycleSignal(f.onCleanup),h=null,_=null,v=null;function y(){return Array.from(t.querySelectorAll(`ore-menu-item:not([disabled])`))}function b(e){return e?e.shadowRoot?.querySelector(`[role^="menuitem"]`)??e:null}function x(){return y().findIndex(e=>{let t=b(e);return e===document.activeElement||t===document.activeElement})}let S=(0,p.signal)(!1),C=null,w=o.createDropdownPositioner({getFloating:()=>_,getPlacement:()=>e.placement.value??`bottom-start`,getReference:()=>h,matchWidth:!1,offsetPx:4,padding:6}),T=a.createListControl({disabled:(0,p.computed)(()=>!S.value),getItems:y,isItemDisabled:e=>e.hasAttribute(`disabled`),onNavigate:(e,t)=>{let n=y()[t];b(n)?.focus()},signal:m}),E=(e=`programmatic`,t=!0)=>{S.value&&(S.value=!1,T.reset(),C?.(),C=null,t&&i.restoreTriggerFocus(()=>h),s(`open-change`,{open:!1,reason:e}))},D=(e=`programmatic`)=>{d.value||S.value||(S.value=!0,w.update(),C=w.startAutoUpdate?.()??null,s(`open-change`,{open:!0,reason:e}))},O=()=>{S.value?E(`trigger`):D(`click`)};i.createOutsidePointerDismissal({getTargets:()=>[t,_],isActive:()=>S.value,onDismiss:()=>E(`outsideClick`),signal:m});let k=!1;(0,p.watch)(e.open,t=>{t===void 0?k?E(`programmatic`):e[`default-open`].value&&D(`programmatic`):t?D(`programmatic`):E(`programmatic`),k=!0},{immediate:!0}),m.addEventListener(`abort`,()=>{S.value&&(S.value=!1,T.reset(),C?.(),C=null)},{once:!0});let A=e=>{let n=e.getAttribute(`type`),r=g(n);if(n===`checkbox`)e.toggleAttribute(`checked`,!e.hasAttribute(`checked`));else if(n===`radio`)for(let n of t.querySelectorAll(`ore-menu-item[type="radio"]`))n.toggleAttribute(`checked`,n===e);let i=e.getAttribute(`value`)??``,a=r?e.hasAttribute(`checked`):void 0;s(`select`,{checked:a,value:i}),r||E(`programmatic`)},j=n.createInteraction({keys:[`Enter`,` `,`ArrowDown`],onPress:()=>{D(`keyboard`),requestAnimationFrame(()=>T.set(0))}}),M=n.createInteraction({onPress:()=>{let e=T.getActiveItem();e&&A(e)}});function N(e){if(d.value)return;if(!S.value){j.handleKeydown(e);return}let t=x();if(t>=0&&T.set(t),e.key===`Escape`){e.preventDefault(),E(`escape`);return}if(!T.handleKeydown(e)){if(e.key===` `||e.key===`Enter`){M.handleKeydown(e);return}e.key===`Tab`&&E(`programmatic`)}}(0,f.bind)({on:{click:e=>{let t=e.composedPath();if(!S.value)return;let n=t.find(e=>e instanceof HTMLElement&&e.tagName===`ORE-MENU-ITEM`)??e.target?.closest(`ore-menu-item`)??null;!n||n.hasAttribute(`disabled`)||A(n)}}}),l(()=>{let e=S.value;_&&_.toggleAttribute(`data-open`,e)});function P(){if(v?.(),v=null,h=c.elements(`trigger`).value?.[0]??null,!h)return;let e=[],t=(0,f.bind)({aria:{controls:()=>u,disabled:()=>d.value,expanded:()=>String(S.value),haspopup:`menu`}},{target:h}),n=e=>{e.stopPropagation(),!d.value&&O()},r=e=>{N(e)};h.addEventListener(`click`,n),h.addEventListener(`keydown`,r),e.push(()=>h?.removeEventListener(`click`,n)),e.push(()=>h?.removeEventListener(`keydown`,r)),v=()=>{t();for(let t of e)t()}}return(0,p.watch)(c.elements(`trigger`),P,{immediate:!0}),(0,f.onMounted)(()=>(P(),()=>{v?.(),v=null})),f.html`
|
|
18
18
|
<slot name="trigger"></slot>
|
|
19
19
|
<div
|
|
20
20
|
class="menu-panel"
|
|
@@ -22,9 +22,9 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
|
|
|
22
22
|
id="${u}"
|
|
23
23
|
role="menu"
|
|
24
24
|
aria-orientation="vertical"
|
|
25
|
-
@keydown="${
|
|
26
|
-
ref="${e=>{
|
|
25
|
+
@keydown="${N}"
|
|
26
|
+
ref="${e=>{_=e,_?.toggleAttribute(`data-open`,S.value)}}">
|
|
27
27
|
<slot></slot>
|
|
28
28
|
</div>
|
|
29
|
-
`},styles:[
|
|
29
|
+
`},styles:[l.default,e.sizeVariantMixin(c.MENU_SIZE_PRESET),t.forcedColorsMixin]}),exports.MENU_ITEM_TAG=m,exports.MENU_TAG=v,exports.SEPARATOR_TAG=h;
|
|
30
30
|
//# sourceMappingURL=menu.cjs.map
|