@vielzeug/refine 2.0.3 → 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.cjs.map +1 -1
- package/dist/content/text/text.css.js +1 -1
- package/dist/content/text/text.css.js.map +1 -1
- package/dist/content/text/text.d.ts +1 -1
- package/dist/content/text/text.d.ts.map +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/overlay.cjs.map +1 -1
- package/dist/core/overlay.d.ts +2 -2
- package/dist/core/overlay.d.ts.map +1 -1
- package/dist/core/overlay.js.map +1 -1
- package/dist/core/positioner.cjs +1 -1
- package/dist/core/positioner.cjs.map +1 -1
- package/dist/core/positioner.d.ts +6 -1
- package/dist/core/positioner.d.ts.map +1 -1
- package/dist/core/positioner.js +11 -11
- package/dist/core/positioner.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 +4926 -4678
- 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/frameworks/elements.d.ts +86 -0
- package/dist/frameworks/react.d.ts +18 -0
- package/dist/frameworks/vue.d.ts +16 -0
- 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.cjs.map +1 -1
- package/dist/inputs/button/button.css.js +1 -1
- package/dist/inputs/button/button.css.js.map +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 +40 -41
- 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 +11 -0
- package/dist/navigation-menu.cjs.map +1 -0
- package/dist/navigation-menu.js +138 -0
- package/dist/navigation-menu.js.map +1 -0
- 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 +7 -5
- 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-item.css.cjs +2 -0
- package/dist/overlay/navigation-menu/navigation-menu-item.css.cjs.map +1 -0
- package/dist/overlay/navigation-menu/navigation-menu-item.css.js +6 -0
- package/dist/overlay/navigation-menu/navigation-menu-item.css.js.map +1 -0
- package/dist/overlay/navigation-menu/navigation-menu-panel.css.cjs +2 -0
- package/dist/overlay/navigation-menu/navigation-menu-panel.css.cjs.map +1 -0
- package/dist/overlay/navigation-menu/navigation-menu-panel.css.js +6 -0
- package/dist/overlay/navigation-menu/navigation-menu-panel.css.js.map +1 -0
- package/dist/overlay/navigation-menu/navigation-menu.css.cjs +2 -0
- package/dist/overlay/navigation-menu/navigation-menu.css.cjs.map +1 -0
- package/dist/overlay/navigation-menu/navigation-menu.css.js +6 -0
- package/dist/overlay/navigation-menu/navigation-menu.css.js.map +1 -0
- package/dist/overlay/navigation-menu/navigation-menu.d.ts +75 -0
- package/dist/overlay/navigation-menu/navigation-menu.d.ts.map +1 -0
- 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 +692 -683
- package/dist/refine.cjs.map +1 -1
- package/dist/refine.iife.js +692 -683
- package/dist/refine.iife.js.map +1 -1
- package/dist/refine.js +743 -734
- 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/text.cjs.map +1 -1
- package/dist/text.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 +104 -78
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.cjs","names":[],"sources":["../../src/core/date-picker.ts"],"sourcesContent":["import { Temporal, format, parse } from '@vielzeug/tempo';\n\n// ── Public ISO helpers (single source of truth for both components) ───────────\n\n/**\n * Parses an ISO 8601 date string (`yyyy-MM-dd`) into a `Temporal.PlainDate`.\n * Returns `null` for any invalid / empty input — never throws.\n */\nexport function parseIso(iso: string | undefined | null): Temporal.PlainDate | null {\n if (!iso) return null;\n\n try {\n return parse(iso, { as: 'plainDate' });\n } catch {\n return null;\n }\n}\n\n/**\n * Serialises a `Temporal.PlainDate` (or `null`) to an ISO 8601 string (`yyyy-MM-dd`).\n * Returns `null` when the input is `null`.\n */\nexport function toIsoString(date: Temporal.PlainDate | null): string | null {\n return date ? date.toString() : null;\n}\n\n/**\n * Formats a `Temporal.PlainDate` for display in a given locale.\n * e.g. \"15 Jun 2025\" (default medium pattern).\n */\nexport function formatDisplayDate(date: Temporal.PlainDate, locale: string): string {\n return format(date, { intl: { day: 'numeric', month: 'short', year: 'numeric' }, locale, timeZone: 'UTC' });\n}\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type DatePickerView = 'day' | 'month' | 'year';\n\nexport type DateCell = {\n /** Day-of-month number (1–31) */\n day: number;\n isDisabled: boolean;\n /** ISO date string yyyy-MM-dd — stable key for rendering */\n iso: string;\n isOutsideMonth: boolean;\n isSelected: boolean;\n isToday: boolean;\n plain: Temporal.PlainDate;\n};\n\nexport type MonthCell = {\n isDisabled: boolean;\n isSelected: boolean;\n label: string;\n /** 1-based month number (Temporal convention: 1 = January … 12 = December) */\n month: number;\n shortLabel: string;\n};\n\nexport type YearCell = {\n isDisabled: boolean;\n isSelected: boolean;\n year: number;\n};\n\nexport type DatePickerControlOptions = {\n /** Locale for day/month names, defaults to `navigator.language` or `'en'` */\n locale?: string;\n /** Maximum selectable date (inclusive) */\n max?: Temporal.PlainDate | null;\n /** Minimum selectable date (inclusive) */\n min?: Temporal.PlainDate | null;\n /** Called when a date is committed by the user */\n onChange: (date: Temporal.PlainDate | null) => void;\n /** Currently selected date */\n value?: Temporal.PlainDate | null;\n /**\n * Which days of the week to disable (0 = Sunday … 6 = Saturday).\n * @example [0, 6] disables weekends\n */\n weekendDays?: number[];\n};\n\nexport type DatePickerControl = {\n /** Ordered day cells for the visible month grid (includes leading/trailing days) */\n dayCells(): DateCell[];\n /** Month currently shown in the header (1-indexed, Temporal convention) */\n displayMonth(): number;\n /** Year currently shown in the header */\n displayYear(): number;\n /** Jump to a specific display month/year without selecting */\n goTo(year: number, month: number): void;\n /** All 12 month cells */\n monthCells(): MonthCell[];\n /** Move display month forward by one */\n nextMonth(): void;\n /** Move display year forward by one */\n nextYear(): void;\n /** Move display month backward by one */\n prevMonth(): void;\n /** Move display year backward by one */\n prevYear(): void;\n /** Select a date. Pass null to clear. */\n select(date: Temporal.PlainDate | null): void;\n /** The currently selected date, or null */\n selected(): Temporal.PlainDate | null;\n /** Switch the calendar view */\n setView(view: DatePickerView): void;\n /** Currently rendered calendar view */\n view(): DatePickerView;\n /** Short week-day labels in locale order e.g. [\"Su\",\"Mo\",…] */\n weekdayLabels(): string[];\n /** Year cells for the visible decade window */\n yearCells(): YearCell[];\n};\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\n/**\n * Returns today as a `Temporal.PlainDate` in the ISO calendar.\n * @internal\n */\nfunction todayPlain(): Temporal.PlainDate {\n return Temporal.Now.plainDateISO();\n}\n\n/**\n * Converts a `Temporal.PlainDate.dayOfWeek` value (1=Mon…7=Sun) to the\n * 0-based weekday index (0=Sun…6=Sat) used in the `weekendDays` prop.\n * @internal\n */\nfunction temporalDowToIndex(dow: number): number {\n // Temporal: 1=Mon, 2=Tue, …, 7=Sun → 0=Sun, 1=Mon, …, 6=Sat\n return dow % 7;\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\n/**\n * Pure, framework-agnostic date-picker state machine backed by `Temporal.PlainDate`.\n *\n * All state is held in plain mutable variables — suitable for wrapping in any\n * reactive layer (ore `signal`, Vue ref, etc.). The factory returns a stable\n * handle object; callers are responsible for reactivity.\n *\n * Options with getter-based live bindings (e.g. `get min() { ... }`) are read\n * on every call so the control always reflects the latest reactive state.\n *\n * @example\n * ```ts\n * const ctrl = createDatePickerControl({\n * value: Temporal.PlainDate.from('2025-06-15'),\n * locale: 'en-US',\n * onChange: (date) => console.log(date?.toString()),\n * });\n *\n * ctrl.nextMonth();\n * ctrl.select(Temporal.PlainDate.from('2025-07-04'));\n * ```\n */\nexport function createDatePickerControl(options: DatePickerControlOptions): DatePickerControl {\n // ── Mutable state ─────────────────────────────────────────────────────────\n\n let _selected: Temporal.PlainDate | null = options.value ?? null;\n let _view: DatePickerView = 'day';\n\n const initial = _selected ?? todayPlain();\n\n let _displayYear = initial.year;\n let _displayMonth = initial.month; // 1-indexed (Temporal convention)\n\n // ── Live option accessors (always read from options for reactive compat) ───\n\n function locale(): string {\n return options.locale ?? (typeof navigator !== 'undefined' ? navigator.language : 'en');\n }\n\n function weekendDays(): number[] {\n return options.weekendDays ?? [];\n }\n\n // ── Range / disabled helpers ───────────────────────────────────────────────\n\n function isOutOfRange(date: Temporal.PlainDate): boolean {\n if (options.min && Temporal.PlainDate.compare(date, options.min) < 0) return true;\n\n if (options.max && Temporal.PlainDate.compare(date, options.max) > 0) return true;\n\n return false;\n }\n\n function isDayDisabled(date: Temporal.PlainDate): boolean {\n if (isOutOfRange(date)) return true;\n\n if (weekendDays().includes(temporalDowToIndex(date.dayOfWeek))) return true;\n\n return false;\n }\n\n // ── Grid builders ─────────────────────────────────────────────────────────\n\n function buildDayCells(): DateCell[] {\n const todayDate = todayPlain();\n const firstOfMonth = Temporal.PlainDate.from({ day: 1, month: _displayMonth, year: _displayYear });\n\n // Sunday-start grid: Temporal dayOfWeek is 1=Mon…7=Sun, convert to 0=Sun offset\n const startOffset = temporalDowToIndex(firstOfMonth.dayOfWeek);\n const cells: DateCell[] = [];\n\n // Leading days from previous month\n for (let i = startOffset - 1; i >= 0; i--) {\n const d = firstOfMonth.subtract({ days: i + 1 });\n\n cells.push({\n day: d.day,\n isDisabled: isDayDisabled(d),\n iso: d.toString(),\n isOutsideMonth: true,\n isSelected: _selected !== null && Temporal.PlainDate.compare(d, _selected) === 0,\n isToday: Temporal.PlainDate.compare(d, todayDate) === 0,\n plain: d,\n });\n }\n\n // Days in current month\n const daysInMonth = firstOfMonth.daysInMonth;\n\n for (let day = 1; day <= daysInMonth; day++) {\n const d = Temporal.PlainDate.from({ day, month: _displayMonth, year: _displayYear });\n\n cells.push({\n day,\n isDisabled: isDayDisabled(d),\n iso: d.toString(),\n isOutsideMonth: false,\n isSelected: _selected !== null && Temporal.PlainDate.compare(d, _selected) === 0,\n isToday: Temporal.PlainDate.compare(d, todayDate) === 0,\n plain: d,\n });\n }\n\n // Trailing days to fill last row (always end at multiple of 7)\n const remaining = (7 - (cells.length % 7)) % 7;\n const firstOfNext = firstOfMonth.add({ months: 1 });\n\n for (let i = 0; i < remaining; i++) {\n const d = firstOfNext.add({ days: i });\n\n cells.push({\n day: d.day,\n isDisabled: isDayDisabled(d),\n iso: d.toString(),\n isOutsideMonth: true,\n isSelected: _selected !== null && Temporal.PlainDate.compare(d, _selected) === 0,\n isToday: Temporal.PlainDate.compare(d, todayDate) === 0,\n plain: d,\n });\n }\n\n return cells;\n }\n\n function buildMonthCells(): MonthCell[] {\n const cells: MonthCell[] = [];\n const loc = locale();\n\n for (let m = 1; m <= 12; m++) {\n const plain = Temporal.PlainDate.from({ day: 1, month: m, year: _displayYear });\n const lastOfMonth = plain.with({ day: plain.daysInMonth });\n\n const isDisabled =\n (options.min !== null && options.min !== undefined\n ? Temporal.PlainDate.compare(lastOfMonth, options.min) < 0\n : false) ||\n (options.max !== null && options.max !== undefined\n ? Temporal.PlainDate.compare(plain, options.max) > 0\n : false);\n\n cells.push({\n isDisabled,\n isSelected: _selected !== null && _selected.year === _displayYear && _selected.month === m,\n label: format(plain, { intl: { month: 'long' }, locale: loc, timeZone: 'UTC' }),\n month: m,\n shortLabel: format(plain, { intl: { month: 'short' }, locale: loc, timeZone: 'UTC' }),\n });\n }\n\n return cells;\n }\n\n function buildYearCells(): YearCell[] {\n const decadeStart = Math.floor(_displayYear / 10) * 10;\n const cells: YearCell[] = [];\n\n for (let y = decadeStart; y < decadeStart + 12; y++) {\n const firstOfYear = Temporal.PlainDate.from({ day: 1, month: 1, year: y });\n const lastOfYear = Temporal.PlainDate.from({ day: 31, month: 12, year: y });\n\n const isDisabled =\n (options.min !== null && options.min !== undefined\n ? Temporal.PlainDate.compare(lastOfYear, options.min) < 0\n : false) ||\n (options.max !== null && options.max !== undefined\n ? Temporal.PlainDate.compare(firstOfYear, options.max) > 0\n : false);\n\n cells.push({\n isDisabled,\n isSelected: _selected !== null && _selected.year === y,\n year: y,\n });\n }\n\n return cells;\n }\n\n function buildWeekdayLabels(): string[] {\n // 2024-01-07 is a Sunday — use it as the Sunday anchor\n const sunday = parse('2024-01-07', { as: 'plainDate' });\n const loc = locale();\n\n return Array.from({ length: 7 }, (_, i) =>\n format(sunday.add({ days: i }), { intl: { weekday: 'short' }, locale: loc, timeZone: 'UTC' }),\n );\n }\n\n // ── Handle ────────────────────────────────────────────────────────────────\n\n return {\n dayCells: buildDayCells,\n displayMonth: () => _displayMonth,\n displayYear: () => _displayYear,\n\n goTo(year: number, month: number): void {\n if (!Number.isFinite(year)) return;\n\n _displayYear = year;\n _displayMonth = Math.max(1, Math.min(12, month));\n },\n\n monthCells: buildMonthCells,\n\n nextMonth(): void {\n if (_displayMonth === 12) {\n _displayMonth = 1;\n _displayYear++;\n } else {\n _displayMonth++;\n }\n },\n\n nextYear(): void {\n _displayYear++;\n },\n\n prevMonth(): void {\n if (_displayMonth === 1) {\n _displayMonth = 12;\n _displayYear--;\n } else {\n _displayMonth--;\n }\n },\n\n prevYear(): void {\n _displayYear--;\n },\n\n select(date: Temporal.PlainDate | null): void {\n if (date !== null && isDayDisabled(date)) return;\n\n _selected = date;\n\n if (_selected) {\n _displayYear = _selected.year;\n _displayMonth = _selected.month;\n }\n\n options.onChange(_selected);\n },\n\n selected: () => _selected,\n\n setView(view: DatePickerView): void {\n _view = view;\n },\n\n view: () => _view,\n\n weekdayLabels: buildWeekdayLabels,\n\n yearCells: buildYearCells,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"date-picker.cjs","names":[],"sources":["../../src/core/date-picker.ts"],"sourcesContent":["import { format, parse, Temporal } from '@vielzeug/tempo';\n\n// ── Public ISO helpers (single source of truth for both components) ───────────\n\n/**\n * Parses an ISO 8601 date string (`yyyy-MM-dd`) into a `Temporal.PlainDate`.\n * Returns `null` for any invalid / empty input — never throws.\n */\nexport function parseIso(iso: string | undefined | null): Temporal.PlainDate | null {\n if (!iso) return null;\n\n try {\n return parse(iso, { as: 'plainDate' });\n } catch {\n return null;\n }\n}\n\n/**\n * Serialises a `Temporal.PlainDate` (or `null`) to an ISO 8601 string (`yyyy-MM-dd`).\n * Returns `null` when the input is `null`.\n */\nexport function toIsoString(date: Temporal.PlainDate | null): string | null {\n return date ? date.toString() : null;\n}\n\n/**\n * Formats a `Temporal.PlainDate` for display in a given locale.\n * e.g. \"15 Jun 2025\" (default medium pattern).\n */\nexport function formatDisplayDate(date: Temporal.PlainDate, locale: string): string {\n return format(date, { intl: { day: 'numeric', month: 'short', year: 'numeric' }, locale, timeZone: 'UTC' });\n}\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type DatePickerView = 'day' | 'month' | 'year';\n\nexport type DateCell = {\n /** Day-of-month number (1–31) */\n day: number;\n isDisabled: boolean;\n /** ISO date string yyyy-MM-dd — stable key for rendering */\n iso: string;\n isOutsideMonth: boolean;\n isSelected: boolean;\n isToday: boolean;\n plain: Temporal.PlainDate;\n};\n\nexport type MonthCell = {\n isDisabled: boolean;\n isSelected: boolean;\n label: string;\n /** 1-based month number (Temporal convention: 1 = January … 12 = December) */\n month: number;\n shortLabel: string;\n};\n\nexport type YearCell = {\n isDisabled: boolean;\n isSelected: boolean;\n year: number;\n};\n\nexport type DatePickerControlOptions = {\n /** Locale for day/month names, defaults to `navigator.language` or `'en'` */\n locale?: string;\n /** Maximum selectable date (inclusive) */\n max?: Temporal.PlainDate | null;\n /** Minimum selectable date (inclusive) */\n min?: Temporal.PlainDate | null;\n /** Called when a date is committed by the user */\n onChange: (date: Temporal.PlainDate | null) => void;\n /** Currently selected date */\n value?: Temporal.PlainDate | null;\n /**\n * Which days of the week to disable (0 = Sunday … 6 = Saturday).\n * @example [0, 6] disables weekends\n */\n weekendDays?: number[];\n};\n\nexport type DatePickerControl = {\n /** Ordered day cells for the visible month grid (includes leading/trailing days) */\n dayCells(): DateCell[];\n /** Month currently shown in the header (1-indexed, Temporal convention) */\n displayMonth(): number;\n /** Year currently shown in the header */\n displayYear(): number;\n /** Jump to a specific display month/year without selecting */\n goTo(year: number, month: number): void;\n /** All 12 month cells */\n monthCells(): MonthCell[];\n /** Move display month forward by one */\n nextMonth(): void;\n /** Move display year forward by one */\n nextYear(): void;\n /** Move display month backward by one */\n prevMonth(): void;\n /** Move display year backward by one */\n prevYear(): void;\n /** Select a date. Pass null to clear. */\n select(date: Temporal.PlainDate | null): void;\n /** The currently selected date, or null */\n selected(): Temporal.PlainDate | null;\n /** Switch the calendar view */\n setView(view: DatePickerView): void;\n /** Currently rendered calendar view */\n view(): DatePickerView;\n /** Short week-day labels in locale order e.g. [\"Su\",\"Mo\",…] */\n weekdayLabels(): string[];\n /** Year cells for the visible decade window */\n yearCells(): YearCell[];\n};\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\n/**\n * Returns today as a `Temporal.PlainDate` in the ISO calendar.\n * @internal\n */\nfunction todayPlain(): Temporal.PlainDate {\n return Temporal.Now.plainDateISO();\n}\n\n/**\n * Converts a `Temporal.PlainDate.dayOfWeek` value (1=Mon…7=Sun) to the\n * 0-based weekday index (0=Sun…6=Sat) used in the `weekendDays` prop.\n * @internal\n */\nfunction temporalDowToIndex(dow: number): number {\n // Temporal: 1=Mon, 2=Tue, …, 7=Sun → 0=Sun, 1=Mon, …, 6=Sat\n return dow % 7;\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\n/**\n * Pure, framework-agnostic date-picker state machine backed by `Temporal.PlainDate`.\n *\n * All state is held in plain mutable variables — suitable for wrapping in any\n * reactive layer (ore `signal`, Vue ref, etc.). The factory returns a stable\n * handle object; callers are responsible for reactivity.\n *\n * Options with getter-based live bindings (e.g. `get min() { ... }`) are read\n * on every call so the control always reflects the latest reactive state.\n *\n * @example\n * ```ts\n * const ctrl = createDatePickerControl({\n * value: Temporal.PlainDate.from('2025-06-15'),\n * locale: 'en-US',\n * onChange: (date) => console.log(date?.toString()),\n * });\n *\n * ctrl.nextMonth();\n * ctrl.select(Temporal.PlainDate.from('2025-07-04'));\n * ```\n */\nexport function createDatePickerControl(options: DatePickerControlOptions): DatePickerControl {\n // ── Mutable state ─────────────────────────────────────────────────────────\n\n let _selected: Temporal.PlainDate | null = options.value ?? null;\n let _view: DatePickerView = 'day';\n\n const initial = _selected ?? todayPlain();\n\n let _displayYear = initial.year;\n let _displayMonth = initial.month; // 1-indexed (Temporal convention)\n\n // ── Live option accessors (always read from options for reactive compat) ───\n\n function locale(): string {\n return options.locale ?? (typeof navigator !== 'undefined' ? navigator.language : 'en');\n }\n\n function weekendDays(): number[] {\n return options.weekendDays ?? [];\n }\n\n // ── Range / disabled helpers ───────────────────────────────────────────────\n\n function isOutOfRange(date: Temporal.PlainDate): boolean {\n if (options.min && Temporal.PlainDate.compare(date, options.min) < 0) return true;\n\n if (options.max && Temporal.PlainDate.compare(date, options.max) > 0) return true;\n\n return false;\n }\n\n function isDayDisabled(date: Temporal.PlainDate): boolean {\n if (isOutOfRange(date)) return true;\n\n if (weekendDays().includes(temporalDowToIndex(date.dayOfWeek))) return true;\n\n return false;\n }\n\n // ── Grid builders ─────────────────────────────────────────────────────────\n\n function buildDayCells(): DateCell[] {\n const todayDate = todayPlain();\n const firstOfMonth = Temporal.PlainDate.from({ day: 1, month: _displayMonth, year: _displayYear });\n\n // Sunday-start grid: Temporal dayOfWeek is 1=Mon…7=Sun, convert to 0=Sun offset\n const startOffset = temporalDowToIndex(firstOfMonth.dayOfWeek);\n const cells: DateCell[] = [];\n\n // Leading days from previous month\n for (let i = startOffset - 1; i >= 0; i--) {\n const d = firstOfMonth.subtract({ days: i + 1 });\n\n cells.push({\n day: d.day,\n isDisabled: isDayDisabled(d),\n isOutsideMonth: true,\n iso: d.toString(),\n isSelected: _selected !== null && Temporal.PlainDate.compare(d, _selected) === 0,\n isToday: Temporal.PlainDate.compare(d, todayDate) === 0,\n plain: d,\n });\n }\n\n // Days in current month\n const daysInMonth = firstOfMonth.daysInMonth;\n\n for (let day = 1; day <= daysInMonth; day++) {\n const d = Temporal.PlainDate.from({ day, month: _displayMonth, year: _displayYear });\n\n cells.push({\n day,\n isDisabled: isDayDisabled(d),\n isOutsideMonth: false,\n iso: d.toString(),\n isSelected: _selected !== null && Temporal.PlainDate.compare(d, _selected) === 0,\n isToday: Temporal.PlainDate.compare(d, todayDate) === 0,\n plain: d,\n });\n }\n\n // Trailing days to fill last row (always end at multiple of 7)\n const remaining = (7 - (cells.length % 7)) % 7;\n const firstOfNext = firstOfMonth.add({ months: 1 });\n\n for (let i = 0; i < remaining; i++) {\n const d = firstOfNext.add({ days: i });\n\n cells.push({\n day: d.day,\n isDisabled: isDayDisabled(d),\n isOutsideMonth: true,\n iso: d.toString(),\n isSelected: _selected !== null && Temporal.PlainDate.compare(d, _selected) === 0,\n isToday: Temporal.PlainDate.compare(d, todayDate) === 0,\n plain: d,\n });\n }\n\n return cells;\n }\n\n function buildMonthCells(): MonthCell[] {\n const cells: MonthCell[] = [];\n const loc = locale();\n\n for (let m = 1; m <= 12; m++) {\n const plain = Temporal.PlainDate.from({ day: 1, month: m, year: _displayYear });\n const lastOfMonth = plain.with({ day: plain.daysInMonth });\n\n const isDisabled =\n (options.min !== null && options.min !== undefined\n ? Temporal.PlainDate.compare(lastOfMonth, options.min) < 0\n : false) ||\n (options.max !== null && options.max !== undefined\n ? Temporal.PlainDate.compare(plain, options.max) > 0\n : false);\n\n cells.push({\n isDisabled,\n isSelected: _selected !== null && _selected.year === _displayYear && _selected.month === m,\n label: format(plain, { intl: { month: 'long' }, locale: loc, timeZone: 'UTC' }),\n month: m,\n shortLabel: format(plain, { intl: { month: 'short' }, locale: loc, timeZone: 'UTC' }),\n });\n }\n\n return cells;\n }\n\n function buildYearCells(): YearCell[] {\n const decadeStart = Math.floor(_displayYear / 10) * 10;\n const cells: YearCell[] = [];\n\n for (let y = decadeStart; y < decadeStart + 12; y++) {\n const firstOfYear = Temporal.PlainDate.from({ day: 1, month: 1, year: y });\n const lastOfYear = Temporal.PlainDate.from({ day: 31, month: 12, year: y });\n\n const isDisabled =\n (options.min !== null && options.min !== undefined\n ? Temporal.PlainDate.compare(lastOfYear, options.min) < 0\n : false) ||\n (options.max !== null && options.max !== undefined\n ? Temporal.PlainDate.compare(firstOfYear, options.max) > 0\n : false);\n\n cells.push({\n isDisabled,\n isSelected: _selected !== null && _selected.year === y,\n year: y,\n });\n }\n\n return cells;\n }\n\n function buildWeekdayLabels(): string[] {\n // 2024-01-07 is a Sunday — use it as the Sunday anchor\n const sunday = parse('2024-01-07', { as: 'plainDate' });\n const loc = locale();\n\n return Array.from({ length: 7 }, (_, i) =>\n format(sunday.add({ days: i }), { intl: { weekday: 'short' }, locale: loc, timeZone: 'UTC' }),\n );\n }\n\n // ── Handle ────────────────────────────────────────────────────────────────\n\n return {\n dayCells: buildDayCells,\n displayMonth: () => _displayMonth,\n displayYear: () => _displayYear,\n\n goTo(year: number, month: number): void {\n if (!Number.isFinite(year)) return;\n\n _displayYear = year;\n _displayMonth = Math.max(1, Math.min(12, month));\n },\n\n monthCells: buildMonthCells,\n\n nextMonth(): void {\n if (_displayMonth === 12) {\n _displayMonth = 1;\n _displayYear++;\n } else {\n _displayMonth++;\n }\n },\n\n nextYear(): void {\n _displayYear++;\n },\n\n prevMonth(): void {\n if (_displayMonth === 1) {\n _displayMonth = 12;\n _displayYear--;\n } else {\n _displayMonth--;\n }\n },\n\n prevYear(): void {\n _displayYear--;\n },\n\n select(date: Temporal.PlainDate | null): void {\n if (date !== null && isDayDisabled(date)) return;\n\n _selected = date;\n\n if (_selected) {\n _displayYear = _selected.year;\n _displayMonth = _selected.month;\n }\n\n options.onChange(_selected);\n },\n\n selected: () => _selected,\n\n setView(view: DatePickerView): void {\n _view = view;\n },\n\n view: () => _view,\n\n weekdayLabels: buildWeekdayLabels,\n\n yearCells: buildYearCells,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../src/core/date-picker.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../src/core/date-picker.ts"],"names":[],"mappings":"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"}
|
package/dist/core/date-picker.js
CHANGED
|
@@ -53,8 +53,8 @@ function c(r) {
|
|
|
53
53
|
a.push({
|
|
54
54
|
day: r.day,
|
|
55
55
|
isDisabled: m(r),
|
|
56
|
-
iso: r.toString(),
|
|
57
56
|
isOutsideMonth: !0,
|
|
57
|
+
iso: r.toString(),
|
|
58
58
|
isSelected: i !== null && e.PlainDate.compare(r, i) === 0,
|
|
59
59
|
isToday: e.PlainDate.compare(r, t) === 0,
|
|
60
60
|
plain: r
|
|
@@ -70,8 +70,8 @@ function c(r) {
|
|
|
70
70
|
a.push({
|
|
71
71
|
day: n,
|
|
72
72
|
isDisabled: m(r),
|
|
73
|
-
iso: r.toString(),
|
|
74
73
|
isOutsideMonth: !1,
|
|
74
|
+
iso: r.toString(),
|
|
75
75
|
isSelected: i !== null && e.PlainDate.compare(r, i) === 0,
|
|
76
76
|
isToday: e.PlainDate.compare(r, t) === 0,
|
|
77
77
|
plain: r
|
|
@@ -83,8 +83,8 @@ function c(r) {
|
|
|
83
83
|
a.push({
|
|
84
84
|
day: r.day,
|
|
85
85
|
isDisabled: m(r),
|
|
86
|
-
iso: r.toString(),
|
|
87
86
|
isOutsideMonth: !0,
|
|
87
|
+
iso: r.toString(),
|
|
88
88
|
isSelected: i !== null && e.PlainDate.compare(r, i) === 0,
|
|
89
89
|
isToday: e.PlainDate.compare(r, t) === 0,
|
|
90
90
|
plain: r
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.js","names":[],"sources":["../../src/core/date-picker.ts"],"sourcesContent":["import { Temporal, format, parse } from '@vielzeug/tempo';\n\n// ── Public ISO helpers (single source of truth for both components) ───────────\n\n/**\n * Parses an ISO 8601 date string (`yyyy-MM-dd`) into a `Temporal.PlainDate`.\n * Returns `null` for any invalid / empty input — never throws.\n */\nexport function parseIso(iso: string | undefined | null): Temporal.PlainDate | null {\n if (!iso) return null;\n\n try {\n return parse(iso, { as: 'plainDate' });\n } catch {\n return null;\n }\n}\n\n/**\n * Serialises a `Temporal.PlainDate` (or `null`) to an ISO 8601 string (`yyyy-MM-dd`).\n * Returns `null` when the input is `null`.\n */\nexport function toIsoString(date: Temporal.PlainDate | null): string | null {\n return date ? date.toString() : null;\n}\n\n/**\n * Formats a `Temporal.PlainDate` for display in a given locale.\n * e.g. \"15 Jun 2025\" (default medium pattern).\n */\nexport function formatDisplayDate(date: Temporal.PlainDate, locale: string): string {\n return format(date, { intl: { day: 'numeric', month: 'short', year: 'numeric' }, locale, timeZone: 'UTC' });\n}\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type DatePickerView = 'day' | 'month' | 'year';\n\nexport type DateCell = {\n /** Day-of-month number (1–31) */\n day: number;\n isDisabled: boolean;\n /** ISO date string yyyy-MM-dd — stable key for rendering */\n iso: string;\n isOutsideMonth: boolean;\n isSelected: boolean;\n isToday: boolean;\n plain: Temporal.PlainDate;\n};\n\nexport type MonthCell = {\n isDisabled: boolean;\n isSelected: boolean;\n label: string;\n /** 1-based month number (Temporal convention: 1 = January … 12 = December) */\n month: number;\n shortLabel: string;\n};\n\nexport type YearCell = {\n isDisabled: boolean;\n isSelected: boolean;\n year: number;\n};\n\nexport type DatePickerControlOptions = {\n /** Locale for day/month names, defaults to `navigator.language` or `'en'` */\n locale?: string;\n /** Maximum selectable date (inclusive) */\n max?: Temporal.PlainDate | null;\n /** Minimum selectable date (inclusive) */\n min?: Temporal.PlainDate | null;\n /** Called when a date is committed by the user */\n onChange: (date: Temporal.PlainDate | null) => void;\n /** Currently selected date */\n value?: Temporal.PlainDate | null;\n /**\n * Which days of the week to disable (0 = Sunday … 6 = Saturday).\n * @example [0, 6] disables weekends\n */\n weekendDays?: number[];\n};\n\nexport type DatePickerControl = {\n /** Ordered day cells for the visible month grid (includes leading/trailing days) */\n dayCells(): DateCell[];\n /** Month currently shown in the header (1-indexed, Temporal convention) */\n displayMonth(): number;\n /** Year currently shown in the header */\n displayYear(): number;\n /** Jump to a specific display month/year without selecting */\n goTo(year: number, month: number): void;\n /** All 12 month cells */\n monthCells(): MonthCell[];\n /** Move display month forward by one */\n nextMonth(): void;\n /** Move display year forward by one */\n nextYear(): void;\n /** Move display month backward by one */\n prevMonth(): void;\n /** Move display year backward by one */\n prevYear(): void;\n /** Select a date. Pass null to clear. */\n select(date: Temporal.PlainDate | null): void;\n /** The currently selected date, or null */\n selected(): Temporal.PlainDate | null;\n /** Switch the calendar view */\n setView(view: DatePickerView): void;\n /** Currently rendered calendar view */\n view(): DatePickerView;\n /** Short week-day labels in locale order e.g. [\"Su\",\"Mo\",…] */\n weekdayLabels(): string[];\n /** Year cells for the visible decade window */\n yearCells(): YearCell[];\n};\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\n/**\n * Returns today as a `Temporal.PlainDate` in the ISO calendar.\n * @internal\n */\nfunction todayPlain(): Temporal.PlainDate {\n return Temporal.Now.plainDateISO();\n}\n\n/**\n * Converts a `Temporal.PlainDate.dayOfWeek` value (1=Mon…7=Sun) to the\n * 0-based weekday index (0=Sun…6=Sat) used in the `weekendDays` prop.\n * @internal\n */\nfunction temporalDowToIndex(dow: number): number {\n // Temporal: 1=Mon, 2=Tue, …, 7=Sun → 0=Sun, 1=Mon, …, 6=Sat\n return dow % 7;\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\n/**\n * Pure, framework-agnostic date-picker state machine backed by `Temporal.PlainDate`.\n *\n * All state is held in plain mutable variables — suitable for wrapping in any\n * reactive layer (ore `signal`, Vue ref, etc.). The factory returns a stable\n * handle object; callers are responsible for reactivity.\n *\n * Options with getter-based live bindings (e.g. `get min() { ... }`) are read\n * on every call so the control always reflects the latest reactive state.\n *\n * @example\n * ```ts\n * const ctrl = createDatePickerControl({\n * value: Temporal.PlainDate.from('2025-06-15'),\n * locale: 'en-US',\n * onChange: (date) => console.log(date?.toString()),\n * });\n *\n * ctrl.nextMonth();\n * ctrl.select(Temporal.PlainDate.from('2025-07-04'));\n * ```\n */\nexport function createDatePickerControl(options: DatePickerControlOptions): DatePickerControl {\n // ── Mutable state ─────────────────────────────────────────────────────────\n\n let _selected: Temporal.PlainDate | null = options.value ?? null;\n let _view: DatePickerView = 'day';\n\n const initial = _selected ?? todayPlain();\n\n let _displayYear = initial.year;\n let _displayMonth = initial.month; // 1-indexed (Temporal convention)\n\n // ── Live option accessors (always read from options for reactive compat) ───\n\n function locale(): string {\n return options.locale ?? (typeof navigator !== 'undefined' ? navigator.language : 'en');\n }\n\n function weekendDays(): number[] {\n return options.weekendDays ?? [];\n }\n\n // ── Range / disabled helpers ───────────────────────────────────────────────\n\n function isOutOfRange(date: Temporal.PlainDate): boolean {\n if (options.min && Temporal.PlainDate.compare(date, options.min) < 0) return true;\n\n if (options.max && Temporal.PlainDate.compare(date, options.max) > 0) return true;\n\n return false;\n }\n\n function isDayDisabled(date: Temporal.PlainDate): boolean {\n if (isOutOfRange(date)) return true;\n\n if (weekendDays().includes(temporalDowToIndex(date.dayOfWeek))) return true;\n\n return false;\n }\n\n // ── Grid builders ─────────────────────────────────────────────────────────\n\n function buildDayCells(): DateCell[] {\n const todayDate = todayPlain();\n const firstOfMonth = Temporal.PlainDate.from({ day: 1, month: _displayMonth, year: _displayYear });\n\n // Sunday-start grid: Temporal dayOfWeek is 1=Mon…7=Sun, convert to 0=Sun offset\n const startOffset = temporalDowToIndex(firstOfMonth.dayOfWeek);\n const cells: DateCell[] = [];\n\n // Leading days from previous month\n for (let i = startOffset - 1; i >= 0; i--) {\n const d = firstOfMonth.subtract({ days: i + 1 });\n\n cells.push({\n day: d.day,\n isDisabled: isDayDisabled(d),\n iso: d.toString(),\n isOutsideMonth: true,\n isSelected: _selected !== null && Temporal.PlainDate.compare(d, _selected) === 0,\n isToday: Temporal.PlainDate.compare(d, todayDate) === 0,\n plain: d,\n });\n }\n\n // Days in current month\n const daysInMonth = firstOfMonth.daysInMonth;\n\n for (let day = 1; day <= daysInMonth; day++) {\n const d = Temporal.PlainDate.from({ day, month: _displayMonth, year: _displayYear });\n\n cells.push({\n day,\n isDisabled: isDayDisabled(d),\n iso: d.toString(),\n isOutsideMonth: false,\n isSelected: _selected !== null && Temporal.PlainDate.compare(d, _selected) === 0,\n isToday: Temporal.PlainDate.compare(d, todayDate) === 0,\n plain: d,\n });\n }\n\n // Trailing days to fill last row (always end at multiple of 7)\n const remaining = (7 - (cells.length % 7)) % 7;\n const firstOfNext = firstOfMonth.add({ months: 1 });\n\n for (let i = 0; i < remaining; i++) {\n const d = firstOfNext.add({ days: i });\n\n cells.push({\n day: d.day,\n isDisabled: isDayDisabled(d),\n iso: d.toString(),\n isOutsideMonth: true,\n isSelected: _selected !== null && Temporal.PlainDate.compare(d, _selected) === 0,\n isToday: Temporal.PlainDate.compare(d, todayDate) === 0,\n plain: d,\n });\n }\n\n return cells;\n }\n\n function buildMonthCells(): MonthCell[] {\n const cells: MonthCell[] = [];\n const loc = locale();\n\n for (let m = 1; m <= 12; m++) {\n const plain = Temporal.PlainDate.from({ day: 1, month: m, year: _displayYear });\n const lastOfMonth = plain.with({ day: plain.daysInMonth });\n\n const isDisabled =\n (options.min !== null && options.min !== undefined\n ? Temporal.PlainDate.compare(lastOfMonth, options.min) < 0\n : false) ||\n (options.max !== null && options.max !== undefined\n ? Temporal.PlainDate.compare(plain, options.max) > 0\n : false);\n\n cells.push({\n isDisabled,\n isSelected: _selected !== null && _selected.year === _displayYear && _selected.month === m,\n label: format(plain, { intl: { month: 'long' }, locale: loc, timeZone: 'UTC' }),\n month: m,\n shortLabel: format(plain, { intl: { month: 'short' }, locale: loc, timeZone: 'UTC' }),\n });\n }\n\n return cells;\n }\n\n function buildYearCells(): YearCell[] {\n const decadeStart = Math.floor(_displayYear / 10) * 10;\n const cells: YearCell[] = [];\n\n for (let y = decadeStart; y < decadeStart + 12; y++) {\n const firstOfYear = Temporal.PlainDate.from({ day: 1, month: 1, year: y });\n const lastOfYear = Temporal.PlainDate.from({ day: 31, month: 12, year: y });\n\n const isDisabled =\n (options.min !== null && options.min !== undefined\n ? Temporal.PlainDate.compare(lastOfYear, options.min) < 0\n : false) ||\n (options.max !== null && options.max !== undefined\n ? Temporal.PlainDate.compare(firstOfYear, options.max) > 0\n : false);\n\n cells.push({\n isDisabled,\n isSelected: _selected !== null && _selected.year === y,\n year: y,\n });\n }\n\n return cells;\n }\n\n function buildWeekdayLabels(): string[] {\n // 2024-01-07 is a Sunday — use it as the Sunday anchor\n const sunday = parse('2024-01-07', { as: 'plainDate' });\n const loc = locale();\n\n return Array.from({ length: 7 }, (_, i) =>\n format(sunday.add({ days: i }), { intl: { weekday: 'short' }, locale: loc, timeZone: 'UTC' }),\n );\n }\n\n // ── Handle ────────────────────────────────────────────────────────────────\n\n return {\n dayCells: buildDayCells,\n displayMonth: () => _displayMonth,\n displayYear: () => _displayYear,\n\n goTo(year: number, month: number): void {\n if (!Number.isFinite(year)) return;\n\n _displayYear = year;\n _displayMonth = Math.max(1, Math.min(12, month));\n },\n\n monthCells: buildMonthCells,\n\n nextMonth(): void {\n if (_displayMonth === 12) {\n _displayMonth = 1;\n _displayYear++;\n } else {\n _displayMonth++;\n }\n },\n\n nextYear(): void {\n _displayYear++;\n },\n\n prevMonth(): void {\n if (_displayMonth === 1) {\n _displayMonth = 12;\n _displayYear--;\n } else {\n _displayMonth--;\n }\n },\n\n prevYear(): void {\n _displayYear--;\n },\n\n select(date: Temporal.PlainDate | null): void {\n if (date !== null && isDayDisabled(date)) return;\n\n _selected = date;\n\n if (_selected) {\n _displayYear = _selected.year;\n _displayMonth = _selected.month;\n }\n\n options.onChange(_selected);\n },\n\n selected: () => _selected,\n\n setView(view: DatePickerView): void {\n _view = view;\n },\n\n view: () => _view,\n\n weekdayLabels: buildWeekdayLabels,\n\n yearCells: buildYearCells,\n };\n}\n"],"mappings":";;AAQA,SAAgB,EAAS,GAA2D;CAClF,IAAI,CAAC,GAAK,OAAO;CAEjB,IAAI;EACF,OAAO,EAAM,GAAK,EAAE,IAAI,YAAY,CAAC;CACvC,QAAQ;EACN,OAAO;CACT;AACF;AAMA,SAAgB,EAAY,GAAgD;CAC1E,OAAO,IAAO,EAAK,SAAS,IAAI;AAClC;AAMA,SAAgB,EAAkB,GAA0B,GAAwB;CAClF,OAAO,EAAO,GAAM;EAAE,MAAM;GAAE,KAAK;GAAW,OAAO;GAAS,MAAM;EAAU;EAAG;EAAQ,UAAU;CAAM,CAAC;AAC5G;AA0FA,SAAS,IAAiC;CACxC,OAAO,EAAS,IAAI,aAAa;AACnC;AAOA,SAAS,EAAmB,GAAqB;CAE/C,OAAO,IAAM;AACf;AA0BA,SAAgB,EAAwB,GAAsD;CAG5F,IAAI,IAAuC,EAAQ,SAAS,MACxD,IAAwB,OAEtB,IAAU,KAAa,EAAW,GAEpC,IAAe,EAAQ,MACvB,IAAgB,EAAQ;CAI5B,SAAS,IAAiB;EACxB,OAAO,EAAQ,WAAW,OAAO,YAAc,MAAc,UAAU,WAAW;CACpF;CAEA,SAAS,IAAwB;EAC/B,OAAO,EAAQ,eAAe,CAAC;CACjC;CAIA,SAAS,EAAa,GAAmC;EAKvD,OAFA,GAFI,EAAQ,OAAO,EAAS,UAAU,QAAQ,GAAM,EAAQ,GAAG,IAAI,KAE/D,EAAQ,OAAO,EAAS,UAAU,QAAQ,GAAM,EAAQ,GAAG,IAAI;CAGrE;CAEA,SAAS,EAAc,GAAmC;EAKxD,OAFA,GAFI,EAAa,CAAI,KAEjB,EAAY,CAAC,CAAC,SAAS,EAAmB,EAAK,SAAS,CAAC;CAG/D;CAIA,SAAS,IAA4B;EACnC,IAAM,IAAY,EAAW,GACvB,IAAe,EAAS,UAAU,KAAK;GAAE,KAAK;GAAG,OAAO;GAAe,MAAM;EAAa,CAAC,GAG3F,IAAc,EAAmB,EAAa,SAAS,GACvD,IAAoB,CAAC;EAG3B,KAAK,IAAI,IAAI,IAAc,GAAG,KAAK,GAAG,KAAK;GACzC,IAAM,IAAI,EAAa,SAAS,EAAE,MAAM,IAAI,EAAE,CAAC;GAE/C,EAAM,KAAK;IACT,KAAK,EAAE;IACP,YAAY,EAAc,CAAC;IAC3B,KAAK,EAAE,SAAS;IAChB,gBAAgB;IAChB,YAAY,MAAc,QAAQ,EAAS,UAAU,QAAQ,GAAG,CAAS,MAAM;IAC/E,SAAS,EAAS,UAAU,QAAQ,GAAG,CAAS,MAAM;IACtD,OAAO;GACT,CAAC;EACH;EAGA,IAAM,IAAc,EAAa;EAEjC,KAAK,IAAI,IAAM,GAAG,KAAO,GAAa,KAAO;GAC3C,IAAM,IAAI,EAAS,UAAU,KAAK;IAAE;IAAK,OAAO;IAAe,MAAM;GAAa,CAAC;GAEnF,EAAM,KAAK;IACT;IACA,YAAY,EAAc,CAAC;IAC3B,KAAK,EAAE,SAAS;IAChB,gBAAgB;IAChB,YAAY,MAAc,QAAQ,EAAS,UAAU,QAAQ,GAAG,CAAS,MAAM;IAC/E,SAAS,EAAS,UAAU,QAAQ,GAAG,CAAS,MAAM;IACtD,OAAO;GACT,CAAC;EACH;EAGA,IAAM,KAAa,IAAK,EAAM,SAAS,KAAM,GACvC,IAAc,EAAa,IAAI,EAAE,QAAQ,EAAE,CAAC;EAElD,KAAK,IAAI,IAAI,GAAG,IAAI,GAAW,KAAK;GAClC,IAAM,IAAI,EAAY,IAAI,EAAE,MAAM,EAAE,CAAC;GAErC,EAAM,KAAK;IACT,KAAK,EAAE;IACP,YAAY,EAAc,CAAC;IAC3B,KAAK,EAAE,SAAS;IAChB,gBAAgB;IAChB,YAAY,MAAc,QAAQ,EAAS,UAAU,QAAQ,GAAG,CAAS,MAAM;IAC/E,SAAS,EAAS,UAAU,QAAQ,GAAG,CAAS,MAAM;IACtD,OAAO;GACT,CAAC;EACH;EAEA,OAAO;CACT;CAEA,SAAS,IAA+B;EACtC,IAAM,IAAqB,CAAC,GACtB,IAAM,EAAO;EAEnB,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,KAAK;GAC5B,IAAM,IAAQ,EAAS,UAAU,KAAK;IAAE,KAAK;IAAG,OAAO;IAAG,MAAM;GAAa,CAAC,GACxE,IAAc,EAAM,KAAK,EAAE,KAAK,EAAM,YAAY,CAAC,GAEnD,IACH,EAAQ,QAAQ,QAAQ,EAAQ,QAAQ,KAAA,KACrC,EAAS,UAAU,QAAQ,GAAa,EAAQ,GAAG,IAAI,KAE1D,EAAQ,QAAQ,QAAQ,EAAQ,QAAQ,KAAA,KACrC,EAAS,UAAU,QAAQ,GAAO,EAAQ,GAAG,IAAI;GAGvD,EAAM,KAAK;IACT;IACA,YAAY,MAAc,QAAQ,EAAU,SAAS,KAAgB,EAAU,UAAU;IACzF,OAAO,EAAO,GAAO;KAAE,MAAM,EAAE,OAAO,OAAO;KAAG,QAAQ;KAAK,UAAU;IAAM,CAAC;IAC9E,OAAO;IACP,YAAY,EAAO,GAAO;KAAE,MAAM,EAAE,OAAO,QAAQ;KAAG,QAAQ;KAAK,UAAU;IAAM,CAAC;GACtF,CAAC;EACH;EAEA,OAAO;CACT;CAEA,SAAS,IAA6B;EACpC,IAAM,IAAc,KAAK,MAAM,IAAe,EAAE,IAAI,IAC9C,IAAoB,CAAC;EAE3B,KAAK,IAAI,IAAI,GAAa,IAAI,IAAc,IAAI,KAAK;GACnD,IAAM,IAAc,EAAS,UAAU,KAAK;IAAE,KAAK;IAAG,OAAO;IAAG,MAAM;GAAE,CAAC,GACnE,IAAa,EAAS,UAAU,KAAK;IAAE,KAAK;IAAI,OAAO;IAAI,MAAM;GAAE,CAAC,GAEpE,IACH,EAAQ,QAAQ,QAAQ,EAAQ,QAAQ,KAAA,KACrC,EAAS,UAAU,QAAQ,GAAY,EAAQ,GAAG,IAAI,KAEzD,EAAQ,QAAQ,QAAQ,EAAQ,QAAQ,KAAA,KACrC,EAAS,UAAU,QAAQ,GAAa,EAAQ,GAAG,IAAI;GAG7D,EAAM,KAAK;IACT;IACA,YAAY,MAAc,QAAQ,EAAU,SAAS;IACrD,MAAM;GACR,CAAC;EACH;EAEA,OAAO;CACT;CAEA,SAAS,IAA+B;EAEtC,IAAM,IAAS,EAAM,cAAc,EAAE,IAAI,YAAY,CAAC,GAChD,IAAM,EAAO;EAEnB,OAAO,MAAM,KAAK,EAAE,QAAQ,EAAE,IAAI,GAAG,MACnC,EAAO,EAAO,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG;GAAE,MAAM,EAAE,SAAS,QAAQ;GAAG,QAAQ;GAAK,UAAU;EAAM,CAAC,CAC9F;CACF;CAIA,OAAO;EACL,UAAU;EACV,oBAAoB;EACpB,mBAAmB;EAEnB,KAAK,GAAc,GAAqB;GACjC,OAAO,SAAS,CAAI,MAEzB,IAAe,GACf,IAAgB,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,CAAK,CAAC;EACjD;EAEA,YAAY;EAEZ,YAAkB;GAChB,AAAI,MAAkB,MACpB,IAAgB,GAChB,OAEA;EAEJ;EAEA,WAAiB;GACf;EACF;EAEA,YAAkB;GAChB,AAAI,MAAkB,KACpB,IAAgB,IAChB,OAEA;EAEJ;EAEA,WAAiB;GACf;EACF;EAEA,OAAO,GAAuC;GACxC,MAAS,QAAQ,EAAc,CAAI,MAEvC,IAAY,GAER,MACF,IAAe,EAAU,MACzB,IAAgB,EAAU,QAG5B,EAAQ,SAAS,CAAS;EAC5B;EAEA,gBAAgB;EAEhB,QAAQ,GAA4B;GAClC,IAAQ;EACV;EAEA,YAAY;EAEZ,eAAe;EAEf,WAAW;CACb;AACF"}
|
|
1
|
+
{"version":3,"file":"date-picker.js","names":[],"sources":["../../src/core/date-picker.ts"],"sourcesContent":["import { format, parse, Temporal } from '@vielzeug/tempo';\n\n// ── Public ISO helpers (single source of truth for both components) ───────────\n\n/**\n * Parses an ISO 8601 date string (`yyyy-MM-dd`) into a `Temporal.PlainDate`.\n * Returns `null` for any invalid / empty input — never throws.\n */\nexport function parseIso(iso: string | undefined | null): Temporal.PlainDate | null {\n if (!iso) return null;\n\n try {\n return parse(iso, { as: 'plainDate' });\n } catch {\n return null;\n }\n}\n\n/**\n * Serialises a `Temporal.PlainDate` (or `null`) to an ISO 8601 string (`yyyy-MM-dd`).\n * Returns `null` when the input is `null`.\n */\nexport function toIsoString(date: Temporal.PlainDate | null): string | null {\n return date ? date.toString() : null;\n}\n\n/**\n * Formats a `Temporal.PlainDate` for display in a given locale.\n * e.g. \"15 Jun 2025\" (default medium pattern).\n */\nexport function formatDisplayDate(date: Temporal.PlainDate, locale: string): string {\n return format(date, { intl: { day: 'numeric', month: 'short', year: 'numeric' }, locale, timeZone: 'UTC' });\n}\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type DatePickerView = 'day' | 'month' | 'year';\n\nexport type DateCell = {\n /** Day-of-month number (1–31) */\n day: number;\n isDisabled: boolean;\n /** ISO date string yyyy-MM-dd — stable key for rendering */\n iso: string;\n isOutsideMonth: boolean;\n isSelected: boolean;\n isToday: boolean;\n plain: Temporal.PlainDate;\n};\n\nexport type MonthCell = {\n isDisabled: boolean;\n isSelected: boolean;\n label: string;\n /** 1-based month number (Temporal convention: 1 = January … 12 = December) */\n month: number;\n shortLabel: string;\n};\n\nexport type YearCell = {\n isDisabled: boolean;\n isSelected: boolean;\n year: number;\n};\n\nexport type DatePickerControlOptions = {\n /** Locale for day/month names, defaults to `navigator.language` or `'en'` */\n locale?: string;\n /** Maximum selectable date (inclusive) */\n max?: Temporal.PlainDate | null;\n /** Minimum selectable date (inclusive) */\n min?: Temporal.PlainDate | null;\n /** Called when a date is committed by the user */\n onChange: (date: Temporal.PlainDate | null) => void;\n /** Currently selected date */\n value?: Temporal.PlainDate | null;\n /**\n * Which days of the week to disable (0 = Sunday … 6 = Saturday).\n * @example [0, 6] disables weekends\n */\n weekendDays?: number[];\n};\n\nexport type DatePickerControl = {\n /** Ordered day cells for the visible month grid (includes leading/trailing days) */\n dayCells(): DateCell[];\n /** Month currently shown in the header (1-indexed, Temporal convention) */\n displayMonth(): number;\n /** Year currently shown in the header */\n displayYear(): number;\n /** Jump to a specific display month/year without selecting */\n goTo(year: number, month: number): void;\n /** All 12 month cells */\n monthCells(): MonthCell[];\n /** Move display month forward by one */\n nextMonth(): void;\n /** Move display year forward by one */\n nextYear(): void;\n /** Move display month backward by one */\n prevMonth(): void;\n /** Move display year backward by one */\n prevYear(): void;\n /** Select a date. Pass null to clear. */\n select(date: Temporal.PlainDate | null): void;\n /** The currently selected date, or null */\n selected(): Temporal.PlainDate | null;\n /** Switch the calendar view */\n setView(view: DatePickerView): void;\n /** Currently rendered calendar view */\n view(): DatePickerView;\n /** Short week-day labels in locale order e.g. [\"Su\",\"Mo\",…] */\n weekdayLabels(): string[];\n /** Year cells for the visible decade window */\n yearCells(): YearCell[];\n};\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\n/**\n * Returns today as a `Temporal.PlainDate` in the ISO calendar.\n * @internal\n */\nfunction todayPlain(): Temporal.PlainDate {\n return Temporal.Now.plainDateISO();\n}\n\n/**\n * Converts a `Temporal.PlainDate.dayOfWeek` value (1=Mon…7=Sun) to the\n * 0-based weekday index (0=Sun…6=Sat) used in the `weekendDays` prop.\n * @internal\n */\nfunction temporalDowToIndex(dow: number): number {\n // Temporal: 1=Mon, 2=Tue, …, 7=Sun → 0=Sun, 1=Mon, …, 6=Sat\n return dow % 7;\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\n/**\n * Pure, framework-agnostic date-picker state machine backed by `Temporal.PlainDate`.\n *\n * All state is held in plain mutable variables — suitable for wrapping in any\n * reactive layer (ore `signal`, Vue ref, etc.). The factory returns a stable\n * handle object; callers are responsible for reactivity.\n *\n * Options with getter-based live bindings (e.g. `get min() { ... }`) are read\n * on every call so the control always reflects the latest reactive state.\n *\n * @example\n * ```ts\n * const ctrl = createDatePickerControl({\n * value: Temporal.PlainDate.from('2025-06-15'),\n * locale: 'en-US',\n * onChange: (date) => console.log(date?.toString()),\n * });\n *\n * ctrl.nextMonth();\n * ctrl.select(Temporal.PlainDate.from('2025-07-04'));\n * ```\n */\nexport function createDatePickerControl(options: DatePickerControlOptions): DatePickerControl {\n // ── Mutable state ─────────────────────────────────────────────────────────\n\n let _selected: Temporal.PlainDate | null = options.value ?? null;\n let _view: DatePickerView = 'day';\n\n const initial = _selected ?? todayPlain();\n\n let _displayYear = initial.year;\n let _displayMonth = initial.month; // 1-indexed (Temporal convention)\n\n // ── Live option accessors (always read from options for reactive compat) ───\n\n function locale(): string {\n return options.locale ?? (typeof navigator !== 'undefined' ? navigator.language : 'en');\n }\n\n function weekendDays(): number[] {\n return options.weekendDays ?? [];\n }\n\n // ── Range / disabled helpers ───────────────────────────────────────────────\n\n function isOutOfRange(date: Temporal.PlainDate): boolean {\n if (options.min && Temporal.PlainDate.compare(date, options.min) < 0) return true;\n\n if (options.max && Temporal.PlainDate.compare(date, options.max) > 0) return true;\n\n return false;\n }\n\n function isDayDisabled(date: Temporal.PlainDate): boolean {\n if (isOutOfRange(date)) return true;\n\n if (weekendDays().includes(temporalDowToIndex(date.dayOfWeek))) return true;\n\n return false;\n }\n\n // ── Grid builders ─────────────────────────────────────────────────────────\n\n function buildDayCells(): DateCell[] {\n const todayDate = todayPlain();\n const firstOfMonth = Temporal.PlainDate.from({ day: 1, month: _displayMonth, year: _displayYear });\n\n // Sunday-start grid: Temporal dayOfWeek is 1=Mon…7=Sun, convert to 0=Sun offset\n const startOffset = temporalDowToIndex(firstOfMonth.dayOfWeek);\n const cells: DateCell[] = [];\n\n // Leading days from previous month\n for (let i = startOffset - 1; i >= 0; i--) {\n const d = firstOfMonth.subtract({ days: i + 1 });\n\n cells.push({\n day: d.day,\n isDisabled: isDayDisabled(d),\n isOutsideMonth: true,\n iso: d.toString(),\n isSelected: _selected !== null && Temporal.PlainDate.compare(d, _selected) === 0,\n isToday: Temporal.PlainDate.compare(d, todayDate) === 0,\n plain: d,\n });\n }\n\n // Days in current month\n const daysInMonth = firstOfMonth.daysInMonth;\n\n for (let day = 1; day <= daysInMonth; day++) {\n const d = Temporal.PlainDate.from({ day, month: _displayMonth, year: _displayYear });\n\n cells.push({\n day,\n isDisabled: isDayDisabled(d),\n isOutsideMonth: false,\n iso: d.toString(),\n isSelected: _selected !== null && Temporal.PlainDate.compare(d, _selected) === 0,\n isToday: Temporal.PlainDate.compare(d, todayDate) === 0,\n plain: d,\n });\n }\n\n // Trailing days to fill last row (always end at multiple of 7)\n const remaining = (7 - (cells.length % 7)) % 7;\n const firstOfNext = firstOfMonth.add({ months: 1 });\n\n for (let i = 0; i < remaining; i++) {\n const d = firstOfNext.add({ days: i });\n\n cells.push({\n day: d.day,\n isDisabled: isDayDisabled(d),\n isOutsideMonth: true,\n iso: d.toString(),\n isSelected: _selected !== null && Temporal.PlainDate.compare(d, _selected) === 0,\n isToday: Temporal.PlainDate.compare(d, todayDate) === 0,\n plain: d,\n });\n }\n\n return cells;\n }\n\n function buildMonthCells(): MonthCell[] {\n const cells: MonthCell[] = [];\n const loc = locale();\n\n for (let m = 1; m <= 12; m++) {\n const plain = Temporal.PlainDate.from({ day: 1, month: m, year: _displayYear });\n const lastOfMonth = plain.with({ day: plain.daysInMonth });\n\n const isDisabled =\n (options.min !== null && options.min !== undefined\n ? Temporal.PlainDate.compare(lastOfMonth, options.min) < 0\n : false) ||\n (options.max !== null && options.max !== undefined\n ? Temporal.PlainDate.compare(plain, options.max) > 0\n : false);\n\n cells.push({\n isDisabled,\n isSelected: _selected !== null && _selected.year === _displayYear && _selected.month === m,\n label: format(plain, { intl: { month: 'long' }, locale: loc, timeZone: 'UTC' }),\n month: m,\n shortLabel: format(plain, { intl: { month: 'short' }, locale: loc, timeZone: 'UTC' }),\n });\n }\n\n return cells;\n }\n\n function buildYearCells(): YearCell[] {\n const decadeStart = Math.floor(_displayYear / 10) * 10;\n const cells: YearCell[] = [];\n\n for (let y = decadeStart; y < decadeStart + 12; y++) {\n const firstOfYear = Temporal.PlainDate.from({ day: 1, month: 1, year: y });\n const lastOfYear = Temporal.PlainDate.from({ day: 31, month: 12, year: y });\n\n const isDisabled =\n (options.min !== null && options.min !== undefined\n ? Temporal.PlainDate.compare(lastOfYear, options.min) < 0\n : false) ||\n (options.max !== null && options.max !== undefined\n ? Temporal.PlainDate.compare(firstOfYear, options.max) > 0\n : false);\n\n cells.push({\n isDisabled,\n isSelected: _selected !== null && _selected.year === y,\n year: y,\n });\n }\n\n return cells;\n }\n\n function buildWeekdayLabels(): string[] {\n // 2024-01-07 is a Sunday — use it as the Sunday anchor\n const sunday = parse('2024-01-07', { as: 'plainDate' });\n const loc = locale();\n\n return Array.from({ length: 7 }, (_, i) =>\n format(sunday.add({ days: i }), { intl: { weekday: 'short' }, locale: loc, timeZone: 'UTC' }),\n );\n }\n\n // ── Handle ────────────────────────────────────────────────────────────────\n\n return {\n dayCells: buildDayCells,\n displayMonth: () => _displayMonth,\n displayYear: () => _displayYear,\n\n goTo(year: number, month: number): void {\n if (!Number.isFinite(year)) return;\n\n _displayYear = year;\n _displayMonth = Math.max(1, Math.min(12, month));\n },\n\n monthCells: buildMonthCells,\n\n nextMonth(): void {\n if (_displayMonth === 12) {\n _displayMonth = 1;\n _displayYear++;\n } else {\n _displayMonth++;\n }\n },\n\n nextYear(): void {\n _displayYear++;\n },\n\n prevMonth(): void {\n if (_displayMonth === 1) {\n _displayMonth = 12;\n _displayYear--;\n } else {\n _displayMonth--;\n }\n },\n\n prevYear(): void {\n _displayYear--;\n },\n\n select(date: Temporal.PlainDate | null): void {\n if (date !== null && isDayDisabled(date)) return;\n\n _selected = date;\n\n if (_selected) {\n _displayYear = _selected.year;\n _displayMonth = _selected.month;\n }\n\n options.onChange(_selected);\n },\n\n selected: () => _selected,\n\n setView(view: DatePickerView): void {\n _view = view;\n },\n\n view: () => _view,\n\n weekdayLabels: buildWeekdayLabels,\n\n yearCells: buildYearCells,\n };\n}\n"],"mappings":"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"}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -4,30 +4,30 @@
|
|
|
4
4
|
* This module is deliberately omitted from the package export map: its helpers
|
|
5
5
|
* encode component-specific Ore and Ripple behavior, not a stable public API.
|
|
6
6
|
*/
|
|
7
|
+
export { type AnnounceOptions, type AnnouncePoliteness, announce } from './announcer';
|
|
8
|
+
export { type AriaReflectionProperty, setAriaReflection } from './aria-reflection';
|
|
9
|
+
export { type AutoResizeControl, type AutoResizeOptions, createAutoResize } from './auto-resize';
|
|
10
|
+
export { type CheckableChangePayload, type CheckableHandle, type CheckableOptions, createCheckable } from './checkable';
|
|
11
|
+
export { type ChoiceChangeDetail, type ChoiceFieldHandle, type ChoiceFieldOptions, createChoiceField, } from './choice-field';
|
|
12
|
+
export { type ComposerControl, type ComposerControlOptions, createComposerControl, type SendShortcut, } from './composer';
|
|
13
|
+
export { createDatePickerControl, type DateCell, type DatePickerControl, type DatePickerControlOptions, type DatePickerView, formatDisplayDate, type MonthCell, parseIso, toIsoString, type YearCell, } from './date-picker';
|
|
14
|
+
export { type AssistiveStateHandle, type AssistiveStateOptions, type ControlValidationMode, type CounterOptions, type CounterState, counterClassName, createAssistiveState, createDirtyTracker, createErrorHelperState, createField, createLabelState, type DirtyTracker, type ErrorHelperOptions, type ErrorHelperState, type FieldHandle, type FieldOptions, type LabelPlacement, type LabelStateHandle, type LabelStateOptions, type ValidationTrigger, } from './field-base';
|
|
15
|
+
export { createFocusManager, type FocusManager, type FocusManagerOptions } from './focus';
|
|
16
|
+
export { getChoiceLabel, getLightChildrenByTag } from './light-dom';
|
|
17
|
+
export type { ListKeyAction, ListNavigationAction } from './nav';
|
|
18
|
+
export { toFiniteNumber, toFiniteNumberOr, toPositiveStep } from './numbers';
|
|
7
19
|
export { lifecycleSignal } from './ore';
|
|
8
|
-
export {
|
|
20
|
+
export { createOutsidePointerDismissal, type DialogCloseReason, type DropdownCloseReason, type OutsidePointerDismissalOptions, type OverlayCloseDetail, type OverlayOpenChangeDetail, type OverlayOpenDetail, type OverlayOpenReason, restoreTriggerFocus, } from './overlay';
|
|
9
21
|
export { bindRefCallback, type RefCallback } from './ref-callback';
|
|
10
|
-
export { setAriaReflection, type AriaReflectionProperty } from './aria-reflection';
|
|
11
|
-
export { createFocusManager, type FocusManager, type FocusManagerOptions } from './focus';
|
|
12
|
-
export { counterClassName, createAssistiveState, createDirtyTracker, createErrorHelperState, createField, createLabelState, type AssistiveStateHandle, type AssistiveStateOptions, type ControlValidationMode, type CounterOptions, type CounterState, type DirtyTracker, type ErrorHelperOptions, type ErrorHelperState, type FieldHandle, type FieldOptions, type LabelPlacement, type LabelStateHandle, type LabelStateOptions, type ValidationTrigger, } from './field-base';
|
|
13
|
-
export { createTextField, type TextFieldDetach, type TextFieldHandle, type TextFieldOptions } from './text-field';
|
|
14
|
-
export { createChoiceField, type ChoiceChangeDetail, type ChoiceFieldHandle, type ChoiceFieldOptions, } from './choice-field';
|
|
15
|
-
export { createCheckable, type CheckableChangePayload, type CheckableHandle, type CheckableOptions } from './checkable';
|
|
16
|
-
export { createComposerControl, type ComposerControl, type ComposerControlOptions, type SendShortcut, } from './composer';
|
|
17
|
-
export { createOutsidePointerDismissal, restoreTriggerFocus, type DialogCloseReason, type DropdownCloseReason, type OutsidePointerDismissalOptions, type OverlayCloseDetail, type OverlayOpenChangeDetail, type OverlayOpenDetail, type OverlayOpenReason, } from './overlay';
|
|
18
|
-
export { type ListKeyAction, type ListNavigationAction } from './nav';
|
|
19
|
-
export { createSpinnerControl, type SpinnerControl, type SpinnerControlOptions } from './spinner';
|
|
20
22
|
export { createSliderControl, type SliderControl, type SliderControlOptions } from './slider';
|
|
23
|
+
export { createSpinnerControl, type SpinnerControl, type SpinnerControlOptions } from './spinner';
|
|
21
24
|
export { createSwipeControl, type SwipeAxis, type SwipeControl, type SwipeControlDetail, type SwipeControlOptions, } from './swipe';
|
|
22
|
-
export {
|
|
23
|
-
export {
|
|
24
|
-
export { getChoiceLabel, getLightChildrenByTag } from './light-dom';
|
|
25
|
-
export { toFiniteNumber, toFiniteNumberOr, toPositiveStep } from './numbers';
|
|
26
|
-
export { createDropdownPositioner, type DropdownPositionerOptions, type OverlayPositioner } from './positioner';
|
|
25
|
+
export { createTextField, type TextFieldDetach, type TextFieldHandle, type TextFieldOptions } from './text-field';
|
|
26
|
+
export { elementDirection } from './direction';
|
|
27
27
|
export { createInteraction, dispatchKeyboardAction, type Interaction, type InteractionOptions, type KeyboardDispatchOptions, type PressTrigger, } from './keyboard';
|
|
28
28
|
export { createListControl, type ListControl, type ListNavigationOptions } from './nav';
|
|
29
29
|
export { createListboxDropdown, type ListboxDropdown, type ListboxDropdownOptions, type ListboxDropdownPlacementOptions, } from './option-list';
|
|
30
|
-
export { elementDirection } from './direction';
|
|
31
30
|
export { parseStringTriggers } from './parse';
|
|
31
|
+
export { createDropdownPositioner, type DropdownPositionerOptions, type OverlayPositioner } from './positioner';
|
|
32
32
|
export { syncedSignal } from './signals';
|
|
33
33
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../errors.cjs"),t=require("./overlay.cjs"),n=require("./
|
|
1
|
+
const e=require("../errors.cjs"),t=require("./overlay.cjs"),n=require("./nav.cjs"),r=require("./positioner.cjs");let i=require("@vielzeug/ripple");var a=a=>{if(typeof a.getBoundary!=`function`)throw new e.RefineConfigError(`createListboxDropdown: getBoundary is required`);if(typeof a.getPanel!=`function`)throw new e.RefineConfigError(`createListboxDropdown: getPanel is required`);if(typeof a.getReference!=`function`)throw new e.RefineConfigError(`createListboxDropdown: getReference is required`);let o=(0,i.signal)(!1),s=(0,i.computed)(()=>String(o.value)),c=null,l=r.createDropdownPositioner({...a.positioning,getFloating:a.getPanel,getReference:a.getReference}),u=()=>{a.getFocusedOptionElement?.()?.scrollIntoView({block:`nearest`})},d=n.createListControl({disabled:(0,i.computed)(()=>!o.value),getItemLabel:a.getItemLabel,getItems:a.getItems,isItemDisabled:a.isItemDisabled,keys:a.keys,loop:a.loop??!0,onNavigate:(e,t,n)=>{u(),t>=0&&a.onNavigate?.(e,t,n)},orientation:a.orientation,signal:a.signal}),f=(0,i.computed)(()=>{let e=d.focusedIndex.value;return a.getOptionId&&o.value&&e>=0?a.getOptionId(e):null}),p=()=>typeof a.restoreFocus==`function`?a.restoreFocus():a.restoreFocus??!0,m=(e=`programmatic`,n=!0)=>{o.value&&(o.value=!1,d.reset(),c?.(),c=null,n&&p()&&a.getTrigger&&t.restoreTriggerFocus(a.getTrigger),a.onClose?.(e))},h=(e=`programmatic`)=>{a.isDisabled?.()||o.value||(o.value=!0,l.update(),c=l.startAutoUpdate?.()??null,a.onOpen?.(e))},g=(e=`click`,t=`trigger`)=>{o.value?m(t):h(e)};t.createOutsidePointerDismissal({getTargets:()=>[a.getBoundary(),a.getPanel()],isActive:()=>o.value,onDismiss:()=>m(`outsideClick`),signal:a.signal});let _=!1,v=()=>{_||(_=!0,o.value&&(o.value=!1,d.reset(),c?.(),c=null))};return a.signal.addEventListener(`abort`,v,{once:!0}),{ariaActiveDescendant:f,ariaExpanded:s,close:m,dispose:v,get disposed(){return _},focusedIndex:d.focusedIndex,getActiveItem:d.getActiveItem,handleKeydown:e=>o.value?e.key===`Escape`?(e.preventDefault(),m(`escape`),!0):d.handleKeydown(e):!1,isOpen:o,navigate:d.navigate,open:h,scrollFocusedIntoView:u,set:d.set,[Symbol.dispose]:v,toggle:g,updatePosition:l.update}};exports.createListboxDropdown=a;
|
|
2
2
|
//# sourceMappingURL=option-list.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"option-list.cjs","names":[],"sources":["../../src/core/option-list.ts"],"sourcesContent":["import { computed, type Readable, signal } from '@vielzeug/ripple';\n\nimport { RefineConfigError } from '../errors';\nimport { createListControl, type ListKeyAction, type ListNavigationAction } from './nav';\nimport {\n createOutsidePointerDismissal,\n
|
|
1
|
+
{"version":3,"file":"option-list.cjs","names":[],"sources":["../../src/core/option-list.ts"],"sourcesContent":["import { computed, type Readable, signal } from '@vielzeug/ripple';\n\nimport { RefineConfigError } from '../errors';\nimport { createListControl, type ListKeyAction, type ListNavigationAction } from './nav';\nimport {\n createOutsidePointerDismissal,\n type DropdownCloseReason,\n type OverlayOpenReason,\n restoreTriggerFocus,\n} from './overlay';\nimport { createDropdownPositioner, type DropdownPositionerOptions } from './positioner';\n\nexport type ListboxItem = object;\n\n/** Placement-only options for the listbox dropdown positioner. */\nexport type ListboxDropdownPlacementOptions = Omit<DropdownPositionerOptions, 'getFloating' | 'getReference'>;\n\nexport type ListboxDropdownOptions<T extends ListboxItem> = {\n getBoundary: () => HTMLElement | null;\n getFocusedOptionElement?: () => HTMLElement | null;\n getItemLabel?: (item: T, index: number) => string;\n getItems: () => T[];\n getOptionId?: (index: number) => string;\n getPanel: () => HTMLElement | null;\n getReference: () => HTMLElement | null;\n getTrigger?: () => HTMLElement | null;\n isDisabled?: () => boolean;\n isItemDisabled?: (item: T, index: number) => boolean;\n keys?: Partial<Record<ListNavigationAction, string[]>>;\n loop?: boolean;\n onClose?: (reason: DropdownCloseReason) => void;\n onNavigate?: (action: ListKeyAction, index: number, event?: KeyboardEvent) => void;\n onOpen?: (reason: OverlayOpenReason) => void;\n orientation?: 'both' | 'horizontal' | 'vertical';\n positioning?: ListboxDropdownPlacementOptions;\n restoreFocus?: boolean | (() => boolean);\n signal: AbortSignal;\n};\n\nexport type ListboxDropdown<T extends ListboxItem> = {\n [Symbol.dispose](): void;\n readonly ariaActiveDescendant: Readable<string | null>;\n readonly ariaExpanded: Readable<string>;\n close(reason?: DropdownCloseReason): void;\n /** Closes the dropdown (without restoring focus) and disposes list navigation state. */\n dispose(): void;\n /** `true` after `dispose()` has been called. */\n readonly disposed: boolean;\n readonly focusedIndex: Readable<number>;\n getActiveItem(): T | undefined;\n handleKeydown(event: KeyboardEvent): boolean;\n readonly isOpen: Readable<boolean>;\n navigate(action: ListNavigationAction): number;\n open(reason?: OverlayOpenReason): void;\n scrollFocusedIntoView(): void;\n set(index: number): number;\n toggle(openReason?: OverlayOpenReason, closeReason?: DropdownCloseReason): void;\n updatePosition(): void;\n};\n\n/**\n * Internal listbox dropdown behavior for select and combobox. It owns only\n * listbox interactions; menu and other overlay families keep their own logic.\n */\nexport const createListboxDropdown = <T extends ListboxItem>(\n options: ListboxDropdownOptions<T>,\n): ListboxDropdown<T> => {\n if (typeof options.getBoundary !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getBoundary is required');\n }\n\n if (typeof options.getPanel !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getPanel is required');\n }\n\n if (typeof options.getReference !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getReference is required');\n }\n\n const isOpen = signal(false);\n const ariaExpanded = computed(() => String(isOpen.value));\n let stopPositioning: (() => void) | null = null;\n\n const positioner = createDropdownPositioner({\n ...options.positioning,\n getFloating: options.getPanel,\n getReference: options.getReference,\n });\n\n const scrollFocusedIntoView = (): void => {\n options.getFocusedOptionElement?.()?.scrollIntoView({ block: 'nearest' });\n };\n\n const list = createListControl<T>({\n disabled: computed(() => !isOpen.value),\n getItemLabel: options.getItemLabel,\n getItems: options.getItems,\n isItemDisabled: options.isItemDisabled,\n keys: options.keys,\n loop: options.loop ?? true,\n onNavigate: (action, index, event) => {\n scrollFocusedIntoView();\n\n if (index >= 0) options.onNavigate?.(action, index, event);\n },\n orientation: options.orientation,\n signal: options.signal,\n });\n\n const ariaActiveDescendant = computed<string | null>(() => {\n const index = list.focusedIndex.value;\n\n return options.getOptionId && isOpen.value && index >= 0 ? options.getOptionId(index) : null;\n });\n\n const shouldRestoreFocus = (): boolean => {\n return typeof options.restoreFocus === 'function' ? options.restoreFocus() : (options.restoreFocus ?? true);\n };\n\n const close = (reason: DropdownCloseReason = 'programmatic', shouldRestore = true): void => {\n if (!isOpen.value) return;\n\n isOpen.value = false;\n list.reset();\n stopPositioning?.();\n stopPositioning = null;\n\n if (shouldRestore && shouldRestoreFocus() && options.getTrigger) restoreTriggerFocus(options.getTrigger);\n\n options.onClose?.(reason);\n };\n\n const open = (reason: OverlayOpenReason = 'programmatic'): void => {\n if (options.isDisabled?.() || isOpen.value) return;\n\n isOpen.value = true;\n positioner.update();\n stopPositioning = positioner.startAutoUpdate?.() ?? null;\n options.onOpen?.(reason);\n };\n\n const toggle = (openReason: OverlayOpenReason = 'click', closeReason: DropdownCloseReason = 'trigger'): void => {\n if (isOpen.value) close(closeReason);\n else open(openReason);\n };\n\n createOutsidePointerDismissal({\n getTargets: () => [options.getBoundary(), options.getPanel()],\n isActive: () => isOpen.value,\n onDismiss: () => close('outsideClick'),\n signal: options.signal,\n });\n\n let disposed = false;\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n\n if (isOpen.value) {\n isOpen.value = false;\n list.reset();\n stopPositioning?.();\n stopPositioning = null;\n }\n };\n\n options.signal.addEventListener('abort', dispose, { once: true });\n\n const handleKeydown = (event: KeyboardEvent): boolean => {\n if (!isOpen.value) return false;\n\n if (event.key === 'Escape') {\n event.preventDefault();\n close('escape');\n\n return true;\n }\n\n return list.handleKeydown(event);\n };\n\n return {\n ariaActiveDescendant,\n ariaExpanded,\n close,\n dispose,\n get disposed() {\n return disposed;\n },\n focusedIndex: list.focusedIndex,\n getActiveItem: list.getActiveItem,\n handleKeydown,\n isOpen,\n navigate: list.navigate,\n open,\n scrollFocusedIntoView,\n set: list.set,\n [Symbol.dispose]: dispose,\n toggle,\n updatePosition: positioner.update,\n };\n};\n"],"mappings":"mJAgEA,IAAa,EACX,GACuB,CACvB,GAAI,OAAO,EAAQ,aAAgB,WACjC,MAAM,IAAI,EAAA,kBAAkB,gDAAgD,EAG9E,GAAI,OAAO,EAAQ,UAAa,WAC9B,MAAM,IAAI,EAAA,kBAAkB,6CAA6C,EAG3E,GAAI,OAAO,EAAQ,cAAiB,WAClC,MAAM,IAAI,EAAA,kBAAkB,iDAAiD,EAG/E,IAAM,GAAA,EAAS,EAAA,OAAA,CAAO,EAAK,EACrB,GAAA,EAAe,EAAA,SAAA,KAAe,OAAO,EAAO,KAAK,CAAC,EACpD,EAAuC,KAErC,EAAa,EAAA,yBAAyB,CAC1C,GAAG,EAAQ,YACX,YAAa,EAAQ,SACrB,aAAc,EAAQ,YACxB,CAAC,EAEK,MAAoC,CACxC,EAAQ,0BAA0B,CAAC,EAAE,eAAe,CAAE,MAAO,SAAU,CAAC,CAC1E,EAEM,EAAO,EAAA,kBAAqB,CAChC,UAAA,EAAU,EAAA,SAAA,KAAe,CAAC,EAAO,KAAK,EACtC,aAAc,EAAQ,aACtB,SAAU,EAAQ,SAClB,eAAgB,EAAQ,eACxB,KAAM,EAAQ,KACd,KAAM,EAAQ,MAAQ,GACtB,YAAa,EAAQ,EAAO,IAAU,CACpC,EAAsB,EAElB,GAAS,GAAG,EAAQ,aAAa,EAAQ,EAAO,CAAK,CAC3D,EACA,YAAa,EAAQ,YACrB,OAAQ,EAAQ,MAClB,CAAC,EAEK,GAAA,EAAuB,EAAA,SAAA,KAA8B,CACzD,IAAM,EAAQ,EAAK,aAAa,MAEhC,OAAO,EAAQ,aAAe,EAAO,OAAS,GAAS,EAAI,EAAQ,YAAY,CAAK,EAAI,IAC1F,CAAC,EAEK,MACG,OAAO,EAAQ,cAAiB,WAAa,EAAQ,aAAa,EAAK,EAAQ,cAAgB,GAGlG,GAAS,EAA8B,eAAgB,EAAgB,KAAe,CACrF,EAAO,QAEZ,EAAO,MAAQ,GACf,EAAK,MAAM,EACX,IAAkB,EAClB,EAAkB,KAEd,GAAiB,EAAmB,GAAK,EAAQ,YAAY,EAAA,oBAAoB,EAAQ,UAAU,EAEvG,EAAQ,UAAU,CAAM,EAC1B,EAEM,GAAQ,EAA4B,iBAAyB,CAC7D,EAAQ,aAAa,GAAK,EAAO,QAErC,EAAO,MAAQ,GACf,EAAW,OAAO,EAClB,EAAkB,EAAW,kBAAkB,GAAK,KACpD,EAAQ,SAAS,CAAM,EACzB,EAEM,GAAU,EAAgC,QAAS,EAAmC,YAAoB,CAC1G,EAAO,MAAO,EAAM,CAAW,EAC9B,EAAK,CAAU,CACtB,EAEA,EAAA,8BAA8B,CAC5B,eAAkB,CAAC,EAAQ,YAAY,EAAG,EAAQ,SAAS,CAAC,EAC5D,aAAgB,EAAO,MACvB,cAAiB,EAAM,cAAc,EACrC,OAAQ,EAAQ,MAClB,CAAC,EAED,IAAI,EAAW,GAET,MAAsB,CACtB,IAEJ,EAAW,GAEP,EAAO,QACT,EAAO,MAAQ,GACf,EAAK,MAAM,EACX,IAAkB,EAClB,EAAkB,MAEtB,EAiBA,OAfA,EAAQ,OAAO,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,EAezD,CACL,uBACA,eACA,QACA,UACA,IAAI,UAAW,CACb,OAAO,CACT,EACA,aAAc,EAAK,aACnB,cAAe,EAAK,cACpB,cAvBqB,GAChB,EAAO,MAER,EAAM,MAAQ,UAChB,EAAM,eAAe,EACrB,EAAM,QAAQ,EAEP,IAGF,EAAK,cAAc,CAAK,EATL,GAuB1B,SACA,SAAU,EAAK,SACf,OACA,wBACA,IAAK,EAAK,KACT,OAAO,SAAU,EAClB,SACA,eAAgB,EAAW,MAC7B,CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"option-list.d.ts","sourceRoot":"","sources":["../../src/core/option-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,QAAQ,EAAU,MAAM,kBAAkB,CAAC;AAGnE,OAAO,EAAqB,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AACzF,OAAO,
|
|
1
|
+
{"version":3,"file":"option-list.d.ts","sourceRoot":"","sources":["../../src/core/option-list.ts"],"names":[],"mappings":"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"}
|
package/dist/core/option-list.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { RefineConfigError as e } from "../errors.js";
|
|
2
2
|
import { createOutsidePointerDismissal as t, restoreTriggerFocus as n } from "./overlay.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { createListControl as r } from "./nav.js";
|
|
4
|
+
import { createDropdownPositioner as i } from "./positioner.js";
|
|
5
5
|
import { computed as a, signal as o } from "@vielzeug/ripple";
|
|
6
6
|
//#region src/core/option-list.ts
|
|
7
7
|
var s = (s) => {
|
|
8
8
|
if (typeof s.getBoundary != "function") throw new e("createListboxDropdown: getBoundary is required");
|
|
9
9
|
if (typeof s.getPanel != "function") throw new e("createListboxDropdown: getPanel is required");
|
|
10
10
|
if (typeof s.getReference != "function") throw new e("createListboxDropdown: getReference is required");
|
|
11
|
-
let c = o(!1), l = a(() => String(c.value)), u = null, d =
|
|
11
|
+
let c = o(!1), l = a(() => String(c.value)), u = null, d = i({
|
|
12
12
|
...s.positioning,
|
|
13
13
|
getFloating: s.getPanel,
|
|
14
14
|
getReference: s.getReference
|
|
15
15
|
}), f = () => {
|
|
16
16
|
s.getFocusedOptionElement?.()?.scrollIntoView({ block: "nearest" });
|
|
17
|
-
}, p =
|
|
17
|
+
}, p = r({
|
|
18
18
|
disabled: a(() => !c.value),
|
|
19
19
|
getItemLabel: s.getItemLabel,
|
|
20
20
|
getItems: s.getItems,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"option-list.js","names":[],"sources":["../../src/core/option-list.ts"],"sourcesContent":["import { computed, type Readable, signal } from '@vielzeug/ripple';\n\nimport { RefineConfigError } from '../errors';\nimport { createListControl, type ListKeyAction, type ListNavigationAction } from './nav';\nimport {\n createOutsidePointerDismissal,\n
|
|
1
|
+
{"version":3,"file":"option-list.js","names":[],"sources":["../../src/core/option-list.ts"],"sourcesContent":["import { computed, type Readable, signal } from '@vielzeug/ripple';\n\nimport { RefineConfigError } from '../errors';\nimport { createListControl, type ListKeyAction, type ListNavigationAction } from './nav';\nimport {\n createOutsidePointerDismissal,\n type DropdownCloseReason,\n type OverlayOpenReason,\n restoreTriggerFocus,\n} from './overlay';\nimport { createDropdownPositioner, type DropdownPositionerOptions } from './positioner';\n\nexport type ListboxItem = object;\n\n/** Placement-only options for the listbox dropdown positioner. */\nexport type ListboxDropdownPlacementOptions = Omit<DropdownPositionerOptions, 'getFloating' | 'getReference'>;\n\nexport type ListboxDropdownOptions<T extends ListboxItem> = {\n getBoundary: () => HTMLElement | null;\n getFocusedOptionElement?: () => HTMLElement | null;\n getItemLabel?: (item: T, index: number) => string;\n getItems: () => T[];\n getOptionId?: (index: number) => string;\n getPanel: () => HTMLElement | null;\n getReference: () => HTMLElement | null;\n getTrigger?: () => HTMLElement | null;\n isDisabled?: () => boolean;\n isItemDisabled?: (item: T, index: number) => boolean;\n keys?: Partial<Record<ListNavigationAction, string[]>>;\n loop?: boolean;\n onClose?: (reason: DropdownCloseReason) => void;\n onNavigate?: (action: ListKeyAction, index: number, event?: KeyboardEvent) => void;\n onOpen?: (reason: OverlayOpenReason) => void;\n orientation?: 'both' | 'horizontal' | 'vertical';\n positioning?: ListboxDropdownPlacementOptions;\n restoreFocus?: boolean | (() => boolean);\n signal: AbortSignal;\n};\n\nexport type ListboxDropdown<T extends ListboxItem> = {\n [Symbol.dispose](): void;\n readonly ariaActiveDescendant: Readable<string | null>;\n readonly ariaExpanded: Readable<string>;\n close(reason?: DropdownCloseReason): void;\n /** Closes the dropdown (without restoring focus) and disposes list navigation state. */\n dispose(): void;\n /** `true` after `dispose()` has been called. */\n readonly disposed: boolean;\n readonly focusedIndex: Readable<number>;\n getActiveItem(): T | undefined;\n handleKeydown(event: KeyboardEvent): boolean;\n readonly isOpen: Readable<boolean>;\n navigate(action: ListNavigationAction): number;\n open(reason?: OverlayOpenReason): void;\n scrollFocusedIntoView(): void;\n set(index: number): number;\n toggle(openReason?: OverlayOpenReason, closeReason?: DropdownCloseReason): void;\n updatePosition(): void;\n};\n\n/**\n * Internal listbox dropdown behavior for select and combobox. It owns only\n * listbox interactions; menu and other overlay families keep their own logic.\n */\nexport const createListboxDropdown = <T extends ListboxItem>(\n options: ListboxDropdownOptions<T>,\n): ListboxDropdown<T> => {\n if (typeof options.getBoundary !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getBoundary is required');\n }\n\n if (typeof options.getPanel !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getPanel is required');\n }\n\n if (typeof options.getReference !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getReference is required');\n }\n\n const isOpen = signal(false);\n const ariaExpanded = computed(() => String(isOpen.value));\n let stopPositioning: (() => void) | null = null;\n\n const positioner = createDropdownPositioner({\n ...options.positioning,\n getFloating: options.getPanel,\n getReference: options.getReference,\n });\n\n const scrollFocusedIntoView = (): void => {\n options.getFocusedOptionElement?.()?.scrollIntoView({ block: 'nearest' });\n };\n\n const list = createListControl<T>({\n disabled: computed(() => !isOpen.value),\n getItemLabel: options.getItemLabel,\n getItems: options.getItems,\n isItemDisabled: options.isItemDisabled,\n keys: options.keys,\n loop: options.loop ?? true,\n onNavigate: (action, index, event) => {\n scrollFocusedIntoView();\n\n if (index >= 0) options.onNavigate?.(action, index, event);\n },\n orientation: options.orientation,\n signal: options.signal,\n });\n\n const ariaActiveDescendant = computed<string | null>(() => {\n const index = list.focusedIndex.value;\n\n return options.getOptionId && isOpen.value && index >= 0 ? options.getOptionId(index) : null;\n });\n\n const shouldRestoreFocus = (): boolean => {\n return typeof options.restoreFocus === 'function' ? options.restoreFocus() : (options.restoreFocus ?? true);\n };\n\n const close = (reason: DropdownCloseReason = 'programmatic', shouldRestore = true): void => {\n if (!isOpen.value) return;\n\n isOpen.value = false;\n list.reset();\n stopPositioning?.();\n stopPositioning = null;\n\n if (shouldRestore && shouldRestoreFocus() && options.getTrigger) restoreTriggerFocus(options.getTrigger);\n\n options.onClose?.(reason);\n };\n\n const open = (reason: OverlayOpenReason = 'programmatic'): void => {\n if (options.isDisabled?.() || isOpen.value) return;\n\n isOpen.value = true;\n positioner.update();\n stopPositioning = positioner.startAutoUpdate?.() ?? null;\n options.onOpen?.(reason);\n };\n\n const toggle = (openReason: OverlayOpenReason = 'click', closeReason: DropdownCloseReason = 'trigger'): void => {\n if (isOpen.value) close(closeReason);\n else open(openReason);\n };\n\n createOutsidePointerDismissal({\n getTargets: () => [options.getBoundary(), options.getPanel()],\n isActive: () => isOpen.value,\n onDismiss: () => close('outsideClick'),\n signal: options.signal,\n });\n\n let disposed = false;\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n\n if (isOpen.value) {\n isOpen.value = false;\n list.reset();\n stopPositioning?.();\n stopPositioning = null;\n }\n };\n\n options.signal.addEventListener('abort', dispose, { once: true });\n\n const handleKeydown = (event: KeyboardEvent): boolean => {\n if (!isOpen.value) return false;\n\n if (event.key === 'Escape') {\n event.preventDefault();\n close('escape');\n\n return true;\n }\n\n return list.handleKeydown(event);\n };\n\n return {\n ariaActiveDescendant,\n ariaExpanded,\n close,\n dispose,\n get disposed() {\n return disposed;\n },\n focusedIndex: list.focusedIndex,\n getActiveItem: list.getActiveItem,\n handleKeydown,\n isOpen,\n navigate: list.navigate,\n open,\n scrollFocusedIntoView,\n set: list.set,\n [Symbol.dispose]: dispose,\n toggle,\n updatePosition: positioner.update,\n };\n};\n"],"mappings":";;;;;;AAgEA,IAAa,KACX,MACuB;CACvB,IAAI,OAAO,EAAQ,eAAgB,YACjC,MAAM,IAAI,EAAkB,gDAAgD;CAG9E,IAAI,OAAO,EAAQ,YAAa,YAC9B,MAAM,IAAI,EAAkB,6CAA6C;CAG3E,IAAI,OAAO,EAAQ,gBAAiB,YAClC,MAAM,IAAI,EAAkB,iDAAiD;CAG/E,IAAM,IAAS,EAAO,EAAK,GACrB,IAAe,QAAe,OAAO,EAAO,KAAK,CAAC,GACpD,IAAuC,MAErC,IAAa,EAAyB;EAC1C,GAAG,EAAQ;EACX,aAAa,EAAQ;EACrB,cAAc,EAAQ;CACxB,CAAC,GAEK,UAAoC;EACxC,EAAQ,0BAA0B,CAAC,EAAE,eAAe,EAAE,OAAO,UAAU,CAAC;CAC1E,GAEM,IAAO,EAAqB;EAChC,UAAU,QAAe,CAAC,EAAO,KAAK;EACtC,cAAc,EAAQ;EACtB,UAAU,EAAQ;EAClB,gBAAgB,EAAQ;EACxB,MAAM,EAAQ;EACd,MAAM,EAAQ,QAAQ;EACtB,aAAa,GAAQ,GAAO,MAAU;GAGpC,AAFA,EAAsB,GAElB,KAAS,KAAG,EAAQ,aAAa,GAAQ,GAAO,CAAK;EAC3D;EACA,aAAa,EAAQ;EACrB,QAAQ,EAAQ;CAClB,CAAC,GAEK,IAAuB,QAA8B;EACzD,IAAM,IAAQ,EAAK,aAAa;EAEhC,OAAO,EAAQ,eAAe,EAAO,SAAS,KAAS,IAAI,EAAQ,YAAY,CAAK,IAAI;CAC1F,CAAC,GAEK,UACG,OAAO,EAAQ,gBAAiB,aAAa,EAAQ,aAAa,IAAK,EAAQ,gBAAgB,IAGlG,KAAS,IAA8B,gBAAgB,IAAgB,OAAe;EACrF,EAAO,UAEZ,EAAO,QAAQ,IACf,EAAK,MAAM,GACX,IAAkB,GAClB,IAAkB,MAEd,KAAiB,EAAmB,KAAK,EAAQ,cAAY,EAAoB,EAAQ,UAAU,GAEvG,EAAQ,UAAU,CAAM;CAC1B,GAEM,KAAQ,IAA4B,mBAAyB;EAC7D,EAAQ,aAAa,KAAK,EAAO,UAErC,EAAO,QAAQ,IACf,EAAW,OAAO,GAClB,IAAkB,EAAW,kBAAkB,KAAK,MACpD,EAAQ,SAAS,CAAM;CACzB,GAEM,KAAU,IAAgC,SAAS,IAAmC,cAAoB;EAC9G,AAAI,EAAO,QAAO,EAAM,CAAW,IAC9B,EAAK,CAAU;CACtB;CAEA,EAA8B;EAC5B,kBAAkB,CAAC,EAAQ,YAAY,GAAG,EAAQ,SAAS,CAAC;EAC5D,gBAAgB,EAAO;EACvB,iBAAiB,EAAM,cAAc;EACrC,QAAQ,EAAQ;CAClB,CAAC;CAED,IAAI,IAAW,IAET,UAAsB;EACtB,MAEJ,IAAW,IAEP,EAAO,UACT,EAAO,QAAQ,IACf,EAAK,MAAM,GACX,IAAkB,GAClB,IAAkB;CAEtB;CAiBA,OAfA,EAAQ,OAAO,iBAAiB,SAAS,GAAS,EAAE,MAAM,GAAK,CAAC,GAezD;EACL;EACA;EACA;EACA;EACA,IAAI,WAAW;GACb,OAAO;EACT;EACA,cAAc,EAAK;EACnB,eAAe,EAAK;EACpB,gBAvBqB,MAChB,EAAO,QAER,EAAM,QAAQ,YAChB,EAAM,eAAe,GACrB,EAAM,QAAQ,GAEP,MAGF,EAAK,cAAc,CAAK,IATL;EAuB1B;EACA,UAAU,EAAK;EACf;EACA;EACA,KAAK,EAAK;GACT,OAAO,UAAU;EAClB;EACA,gBAAgB,EAAW;CAC7B;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.cjs","names":[],"sources":["../../src/core/overlay.ts"],"sourcesContent":["/**\n * Why an overlay was opened.\n * - `'click'` — user clicked the trigger element\n * - `'focus'` — focus entered the trigger (tooltip, popover)\n * - `'hover'` — pointer entered the trigger (tooltip)\n * - `'keyboard'` — keyboard shortcut or Enter/Space on a trigger\n * - `'programmatic'` — opened via the JS API without a user gesture\n * - `'trigger'` — opened via the Invoker Commands API (`command=\"show-modal\"`)\n */\nexport type OverlayOpenReason = 'click' | 'focus' | 'hover' | 'keyboard' | 'programmatic' | 'trigger';\n\n/** Close reasons valid for modal dialogs (includes 'swipe' for drawer). */\nexport type DialogCloseReason = 'escape' | 'outsideClick' | 'programmatic' | 'swipe' | 'trigger';\n/** Close reasons valid for dropdown overlays (no swipe). */\nexport type DropdownCloseReason = Exclude<DialogCloseReason, 'swipe'
|
|
1
|
+
{"version":3,"file":"overlay.cjs","names":[],"sources":["../../src/core/overlay.ts"],"sourcesContent":["/**\n * Why an overlay was opened.\n * - `'click'` — user clicked the trigger element\n * - `'focus'` — focus entered the trigger (tooltip, popover)\n * - `'hover'` — pointer entered the trigger (tooltip)\n * - `'keyboard'` — keyboard shortcut or Enter/Space on a trigger\n * - `'programmatic'` — opened via the JS API without a user gesture\n * - `'trigger'` — opened via the Invoker Commands API (`command=\"show-modal\"`)\n */\nexport type OverlayOpenReason = 'click' | 'focus' | 'hover' | 'keyboard' | 'programmatic' | 'trigger';\n\n/** Close reasons valid for modal dialogs (includes 'swipe' for drawer). */\nexport type DialogCloseReason = 'escape' | 'outsideClick' | 'programmatic' | 'swipe' | 'trigger';\n/** Close reasons valid for dropdown overlays (no swipe). */\nexport type DropdownCloseReason = Exclude<DialogCloseReason, 'swipe'> | 'select';\n\n/** Detail shape for overlay open events emitted by components. */\nexport type OverlayOpenDetail = { reason: OverlayOpenReason };\n/** Detail shape for overlay close events emitted by components. */\nexport type OverlayCloseDetail = { reason: DialogCloseReason };\n/** Detail shape for state changes emitted by overlay components. */\nexport type OverlayOpenChangeDetail = {\n open: boolean;\n reason: DialogCloseReason | DropdownCloseReason | OverlayOpenReason;\n};\n\nexport type OutsidePointerDismissalOptions = {\n getTargets: () => Array<Element | null | undefined>;\n isActive: () => boolean;\n onDismiss: () => void;\n signal: AbortSignal;\n};\n\n/**\n * Dismisses an active floating surface when a pointer begins outside all of its\n * supplied boundary elements. Components retain ownership of their open state.\n */\nexport const createOutsidePointerDismissal = (options: OutsidePointerDismissalOptions): (() => void) => {\n const onPointerDown = (event: PointerEvent): void => {\n if (!options.isActive()) return;\n\n const path = event.composedPath();\n const target = path[0] instanceof Node ? path[0] : event.target instanceof Node ? event.target : null;\n const inside = options.getTargets().some((element) => {\n return (\n element !== null &&\n element !== undefined &&\n (path.includes(element) || Boolean(target && element.contains(target)))\n );\n });\n\n if (!inside) options.onDismiss();\n };\n\n const dispose = (): void => {\n document.removeEventListener('pointerdown', onPointerDown, { capture: true });\n };\n\n document.addEventListener('pointerdown', onPointerDown, { capture: true });\n options.signal.addEventListener('abort', dispose, { once: true });\n\n return dispose;\n};\n\n/**\n * Restores focus to a dropdown/floating-panel trigger when the owning overlay closes.\n *\n * Named distinctly from `FocusManager.restoreFocus()` (`./focus.ts`) — that method restores a\n * captured dialog-opener element from internal state; this function takes the trigger directly,\n * for dropdown-style overlays (menu) that never captured one.\n */\nexport const restoreTriggerFocus = (getTrigger: () => HTMLElement | null | undefined): void => {\n getTrigger()?.focus();\n};\n"],"mappings":"AAqCA,IAAa,EAAiC,GAA0D,CACtG,IAAM,EAAiB,GAA8B,CACnD,GAAI,CAAC,EAAQ,SAAS,EAAG,OAEzB,IAAM,EAAO,EAAM,aAAa,EAC1B,EAAS,EAAK,aAAc,KAAO,EAAK,GAAK,EAAM,kBAAkB,KAAO,EAAM,OAAS,KAClF,EAAQ,WAAW,CAAC,CAAC,KAAM,GAEtC,GAAY,OAEX,EAAK,SAAS,CAAO,GAAK,GAAQ,GAAU,EAAQ,SAAS,CAAM,GAInE,GAAQ,EAAQ,UAAU,CACjC,EAEM,MAAsB,CAC1B,SAAS,oBAAoB,cAAe,EAAe,CAAE,QAAS,EAAK,CAAC,CAC9E,EAKA,OAHA,SAAS,iBAAiB,cAAe,EAAe,CAAE,QAAS,EAAK,CAAC,EACzE,EAAQ,OAAO,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,EAEzD,CACT,EASa,EAAuB,GAA2D,CAC7F,EAAW,CAAC,EAAE,MAAM,CACtB"}
|
package/dist/core/overlay.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export type OverlayOpenReason = 'click' | 'focus' | 'hover' | 'keyboard' | 'prog
|
|
|
11
11
|
/** Close reasons valid for modal dialogs (includes 'swipe' for drawer). */
|
|
12
12
|
export type DialogCloseReason = 'escape' | 'outsideClick' | 'programmatic' | 'swipe' | 'trigger';
|
|
13
13
|
/** Close reasons valid for dropdown overlays (no swipe). */
|
|
14
|
-
export type DropdownCloseReason = Exclude<DialogCloseReason, 'swipe'
|
|
14
|
+
export type DropdownCloseReason = Exclude<DialogCloseReason, 'swipe'> | 'select';
|
|
15
15
|
/** Detail shape for overlay open events emitted by components. */
|
|
16
16
|
export type OverlayOpenDetail = {
|
|
17
17
|
reason: OverlayOpenReason;
|
|
@@ -23,7 +23,7 @@ export type OverlayCloseDetail = {
|
|
|
23
23
|
/** Detail shape for state changes emitted by overlay components. */
|
|
24
24
|
export type OverlayOpenChangeDetail = {
|
|
25
25
|
open: boolean;
|
|
26
|
-
reason: DialogCloseReason | OverlayOpenReason;
|
|
26
|
+
reason: DialogCloseReason | DropdownCloseReason | OverlayOpenReason;
|
|
27
27
|
};
|
|
28
28
|
export type OutsidePointerDismissalOptions = {
|
|
29
29
|
getTargets: () => Array<Element | null | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/core/overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,cAAc,GAAG,SAAS,CAAC;AAEtG,2EAA2E;AAC3E,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,cAAc,GAAG,cAAc,GAAG,OAAO,GAAG,SAAS,CAAC;AACjG,4DAA4D;AAC5D,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/core/overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,cAAc,GAAG,SAAS,CAAC;AAEtG,2EAA2E;AAC3E,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,cAAc,GAAG,cAAc,GAAG,OAAO,GAAG,SAAS,CAAC;AACjG,4DAA4D;AAC5D,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC;AAEjF,kEAAkE;AAClE,MAAM,MAAM,iBAAiB,GAAG;IAAE,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAC9D,mEAAmE;AACnE,MAAM,MAAM,kBAAkB,GAAG;IAAE,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAC/D,oEAAoE;AACpE,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,iBAAiB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;CACrE,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC3C,UAAU,EAAE,MAAM,KAAK,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACpD,QAAQ,EAAE,MAAM,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,6BAA6B,GAAI,SAAS,8BAA8B,KAAG,CAAC,MAAM,IAAI,CAyBlG,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAAI,YAAY,MAAM,WAAW,GAAG,IAAI,GAAG,SAAS,KAAG,IAEtF,CAAC"}
|
package/dist/core/overlay.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.js","names":[],"sources":["../../src/core/overlay.ts"],"sourcesContent":["/**\n * Why an overlay was opened.\n * - `'click'` — user clicked the trigger element\n * - `'focus'` — focus entered the trigger (tooltip, popover)\n * - `'hover'` — pointer entered the trigger (tooltip)\n * - `'keyboard'` — keyboard shortcut or Enter/Space on a trigger\n * - `'programmatic'` — opened via the JS API without a user gesture\n * - `'trigger'` — opened via the Invoker Commands API (`command=\"show-modal\"`)\n */\nexport type OverlayOpenReason = 'click' | 'focus' | 'hover' | 'keyboard' | 'programmatic' | 'trigger';\n\n/** Close reasons valid for modal dialogs (includes 'swipe' for drawer). */\nexport type DialogCloseReason = 'escape' | 'outsideClick' | 'programmatic' | 'swipe' | 'trigger';\n/** Close reasons valid for dropdown overlays (no swipe). */\nexport type DropdownCloseReason = Exclude<DialogCloseReason, 'swipe'
|
|
1
|
+
{"version":3,"file":"overlay.js","names":[],"sources":["../../src/core/overlay.ts"],"sourcesContent":["/**\n * Why an overlay was opened.\n * - `'click'` — user clicked the trigger element\n * - `'focus'` — focus entered the trigger (tooltip, popover)\n * - `'hover'` — pointer entered the trigger (tooltip)\n * - `'keyboard'` — keyboard shortcut or Enter/Space on a trigger\n * - `'programmatic'` — opened via the JS API without a user gesture\n * - `'trigger'` — opened via the Invoker Commands API (`command=\"show-modal\"`)\n */\nexport type OverlayOpenReason = 'click' | 'focus' | 'hover' | 'keyboard' | 'programmatic' | 'trigger';\n\n/** Close reasons valid for modal dialogs (includes 'swipe' for drawer). */\nexport type DialogCloseReason = 'escape' | 'outsideClick' | 'programmatic' | 'swipe' | 'trigger';\n/** Close reasons valid for dropdown overlays (no swipe). */\nexport type DropdownCloseReason = Exclude<DialogCloseReason, 'swipe'> | 'select';\n\n/** Detail shape for overlay open events emitted by components. */\nexport type OverlayOpenDetail = { reason: OverlayOpenReason };\n/** Detail shape for overlay close events emitted by components. */\nexport type OverlayCloseDetail = { reason: DialogCloseReason };\n/** Detail shape for state changes emitted by overlay components. */\nexport type OverlayOpenChangeDetail = {\n open: boolean;\n reason: DialogCloseReason | DropdownCloseReason | OverlayOpenReason;\n};\n\nexport type OutsidePointerDismissalOptions = {\n getTargets: () => Array<Element | null | undefined>;\n isActive: () => boolean;\n onDismiss: () => void;\n signal: AbortSignal;\n};\n\n/**\n * Dismisses an active floating surface when a pointer begins outside all of its\n * supplied boundary elements. Components retain ownership of their open state.\n */\nexport const createOutsidePointerDismissal = (options: OutsidePointerDismissalOptions): (() => void) => {\n const onPointerDown = (event: PointerEvent): void => {\n if (!options.isActive()) return;\n\n const path = event.composedPath();\n const target = path[0] instanceof Node ? path[0] : event.target instanceof Node ? event.target : null;\n const inside = options.getTargets().some((element) => {\n return (\n element !== null &&\n element !== undefined &&\n (path.includes(element) || Boolean(target && element.contains(target)))\n );\n });\n\n if (!inside) options.onDismiss();\n };\n\n const dispose = (): void => {\n document.removeEventListener('pointerdown', onPointerDown, { capture: true });\n };\n\n document.addEventListener('pointerdown', onPointerDown, { capture: true });\n options.signal.addEventListener('abort', dispose, { once: true });\n\n return dispose;\n};\n\n/**\n * Restores focus to a dropdown/floating-panel trigger when the owning overlay closes.\n *\n * Named distinctly from `FocusManager.restoreFocus()` (`./focus.ts`) — that method restores a\n * captured dialog-opener element from internal state; this function takes the trigger directly,\n * for dropdown-style overlays (menu) that never captured one.\n */\nexport const restoreTriggerFocus = (getTrigger: () => HTMLElement | null | undefined): void => {\n getTrigger()?.focus();\n};\n"],"mappings":";AAqCA,IAAa,KAAiC,MAA0D;CACtG,IAAM,KAAiB,MAA8B;EACnD,IAAI,CAAC,EAAQ,SAAS,GAAG;EAEzB,IAAM,IAAO,EAAM,aAAa,GAC1B,IAAS,EAAK,cAAc,OAAO,EAAK,KAAK,EAAM,kBAAkB,OAAO,EAAM,SAAS;EASjG,AARe,EAAQ,WAAW,CAAC,CAAC,MAAM,MAEtC,KAAY,SAEX,EAAK,SAAS,CAAO,KAAK,GAAQ,KAAU,EAAQ,SAAS,CAAM,GAInE,KAAQ,EAAQ,UAAU;CACjC,GAEM,UAAsB;EAC1B,SAAS,oBAAoB,eAAe,GAAe,EAAE,SAAS,GAAK,CAAC;CAC9E;CAKA,OAHA,SAAS,iBAAiB,eAAe,GAAe,EAAE,SAAS,GAAK,CAAC,GACzE,EAAQ,OAAO,iBAAiB,SAAS,GAAS,EAAE,MAAM,GAAK,CAAC,GAEzD;AACT,GASa,KAAuB,MAA2D;CAC7F,EAAW,CAAC,EAAE,MAAM;AACtB"}
|
package/dist/core/positioner.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./direction.cjs");let t=require("@vielzeug/orbit");var n=e=>e.endsWith(`-start`)?e.replace(`-start`,`-end`):e.endsWith(`-end`)?e.replace(`-end`,`-start`):e;function r({boundary:r,getDir:i,getFloating:a,getPlacement:o,getReference:s,matchWidth:c=!0,offsetPx:l=0,padding:u=6}){function
|
|
1
|
+
const e=require("./direction.cjs");let t=require("@vielzeug/orbit");var n=e=>e.endsWith(`-start`)?e.replace(`-start`,`-end`):e.endsWith(`-end`)?e.replace(`-end`,`-start`):e;function r({boundary:r,getDir:i,getFloating:a,getPlacement:o,getReference:s,matchWidth:c=!0,offsetPx:l=0,padding:u=6,useClippingAncestor:d=!0}){function f(){let t=o?.()??`bottom-start`;return(i?.()??e.elementDirection(s()))===`rtl`?n(t):t}function p(){let e=s(),n=a();if(!e||!n)return;let i=f(),o=r??(d?(0,t.getClippingAncestorRect)(n):void 0),p=(0,t.computePosition)(e,n,{boundary:o,middleware:[...l?[(0,t.offset)(l)]:[],(0,t.flip)({padding:u}),(0,t.shift)({padding:u}),...c?[(0,t.size)({padding:u})]:[]],placement:i});n.style.left=`${p.x}px`,n.style.top=`${p.y}px`;let m=n.style.transition,h=n.style.transform;n.style.transition=`none`,n.style.transform=`none`;let g=n.getBoundingClientRect(),_=p.x-g.left,v=p.y-g.top;n.style.transition=m,n.style.transform=h,(_!==0||v!==0)&&(n.style.left=`${p.x+_}px`,n.style.top=`${p.y+v}px`),c&&(n.style.width=`${e.getBoundingClientRect().width}px`)}function m(){let e=s(),n=a();return!e||!n?()=>{}:(0,t.autoUpdate)(e,n,p)}return{floating:a,reference:s,startAutoUpdate:m,update:p}}exports.createDropdownPositioner=r;
|
|
2
2
|
//# sourceMappingURL=positioner.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"positioner.cjs","names":[],"sources":["../../src/core/positioner.ts"],"sourcesContent":["import {\n autoUpdate,\n computePosition,\n flip,\n getClippingAncestorRect,\n offset,\n type Placement,\n type Rect,\n shift,\n size,\n} from '@vielzeug/orbit';\n\nimport { elementDirection } from './direction';\n\n// ── Overlay positioner contract ──────────────────────────────────────────────\n\nexport type OverlayPositioner = {\n floating: () => HTMLElement | null;\n reference: () => HTMLElement | null;\n /** Start continuous position auto-updates. Returns a stop function. */\n startAutoUpdate?: () => () => void;\n update: () => void;\n};\n\n// ── Dropdown positioner ───────────────────────────────────────────────────────\n\nexport type DropdownPositionerOptions = {\n /**\n * Clipping boundary for flip/shift/size — the edges the dropdown must stay within.\n * Defaults to the nearest ancestor that actually clips content (`overflow:\n * hidden|auto|scroll|clip`, e.g. a dialog panel), auto-detected per update via\n * `getClippingAncestorRect()`, intersected with the viewport. Without this, flip/shift only\n * avoid the full page viewport — a dropdown can be \"in view\" by that measure while still\n * visibly overhanging a much smaller container it's actually nested in. Pass an explicit\n * boundary to override auto-detection.\n */\n boundary?: Element | Rect;\n /**\n * Returns the text direction used for placement mirroring. Defaults to the resolved\n * direction of the reference element (nearest `dir=\"ltr\"|\"rtl\"` ancestor, falling back to\n * computed style) — most callers never need to pass this explicitly.\n */\n getDir?: () => 'ltr' | 'rtl';\n /** Getter for the floating (dropdown panel) element. */\n getFloating: () => HTMLElement | null;\n /** Getter for the current placement. Defaults to 'bottom-start' (RTL-aware: flips to 'bottom-end'). */\n getPlacement?: () => Placement;\n /** Getter for the reference (trigger) element. */\n getReference: () => HTMLElement | null;\n /** Whether to match the floating element width to the reference. Default: true */\n matchWidth?: boolean;\n /** Additional offset in pixels between reference and floating element. Default: 0 */\n offsetPx?: number;\n /** Padding (px) used by flip, shift, and size middleware. Default: 6 */\n padding?: number;\n};\n\n/** Mirrors a start/end placement for RTL layouts. */\nconst rtlPlacement = (p: Placement): Placement => {\n if (p.endsWith('-start')) return p.replace('-start', '-end') as Placement;\n\n if (p.endsWith('-end')) return p.replace('-end', '-start') as Placement;\n\n return p;\n};\n\n/**\n * Creates an Orbit-powered positioner for dropdown overlays (select, combobox, menu).\n *\n * Uses flip + shift + optional width-matching middleware. Supports continuous\n * auto-update for repositioning on scroll or resize.\n *\n * RTL-aware: start/end placements are automatically mirrored so dropdowns open on the\n * correct side, based on `getDir` (or the reference element's resolved direction when\n * `getDir` is omitted).\n */\nexport function createDropdownPositioner({\n boundary,\n getDir,\n getFloating,\n getPlacement,\n getReference,\n matchWidth = true,\n offsetPx = 0,\n padding = 6,\n}: DropdownPositionerOptions): OverlayPositioner {\n function resolvedPlacement(): Placement {\n const base = getPlacement?.() ?? 'bottom-start';\n const dir = getDir?.() ?? elementDirection(getReference());\n\n return dir === 'rtl' ? rtlPlacement(base) : base;\n }\n\n function updatePosition(): void {\n const ref = getReference();\n const floating = getFloating();\n\n if (!ref || !floating) return;\n\n const placement = resolvedPlacement();\n // Defaults to `undefined` (meaning \"auto-detect\"), not the detected value itself —\n // re-running the detection on every update (rather than once, at positioner-creation time)\n // matters because the dialog/scroll-container an instance is rendered into can change\n // across opens (e.g. the same `<ore-select>` reused in different dialogs), and the detected\n // ancestor's own rect can change between opens even when it's the same element (a resized\n // dialog).\n const resolvedBoundary = boundary ?? getClippingAncestorRect(floating);\n\n const result = computePosition(ref, floating, {\n boundary: resolvedBoundary,\n middleware: [\n ...(offsetPx ? [offset(offsetPx)] : []),\n flip({ padding }),\n shift({ padding }),\n ...(matchWidth ? [size({ padding })] : []),\n ],\n placement,\n });\n\n floating.style.left = `${result.x}px`;\n floating.style.top = `${result.y}px`;\n\n // `computePosition()` assumes `left`/`top` resolve relative to the viewport (correct for\n // `position: fixed`) — true almost always, but not when some ancestor establishes a\n // containing block for fixed descendants (a non-`none` `transform`, even a visually-identity\n // one left over from an entrance transition that never resets to `none` at rest is a real,\n // easy-to-hit case — a modal dialog's panel, say). Analytically detecting *that* ancestor via\n // `getContainingBlock()` and pre-subtracting its rect turned out to be unreliable in\n // practice: browsers don't apply the \"ancestor transform traps fixed descendants\" rule\n // uniformly across every element nested under it in every case we tested — some floating\n // elements in the exact same subtree needed the correction and some didn't, for reasons we\n // couldn't fully pin down. Measuring what actually happened after writing `left`/`top`\n // and correcting only the observed gap sidesteps that: it's a no-op when the browser already\n // put the element where asked, and it fixes the same class of bug the moment there's a real\n // mismatch, regardless of which specific ancestor (if any) turns out to be responsible.\n //\n // The measurement itself must not be fooled by the floating element's *own* transform,\n // though: dropdowns/popovers here all use a `transform: translateY(...)` entrance transition\n // driven by a `[data-open]` attribute + `@starting-style` — right at open, before the\n // transition has visibly progressed, `getBoundingClientRect()` can still reflect that\n // starting offset (a handful of px, matching `--overlay-enter-translate-y`), which this\n // correction would otherwise misread as a permanent ancestor-driven mismatch and bake in\n // forever. Temporarily neutralizing the floating element's own transform for the measurement\n // (and restoring it before anything paints, so there's no visible flash) isolates the\n // correction to ancestor-driven offsets only, which is the only thing it's meant to fix.\n const prevTransition = floating.style.transition;\n const prevTransform = floating.style.transform;\n\n floating.style.transition = 'none';\n floating.style.transform = 'none';\n\n const actual = floating.getBoundingClientRect();\n const deltaX = result.x - actual.left;\n const deltaY = result.y - actual.top;\n\n floating.style.transition = prevTransition;\n floating.style.transform = prevTransform;\n\n if (deltaX !== 0 || deltaY !== 0) {\n floating.style.left = `${result.x + deltaX}px`;\n floating.style.top = `${result.y + deltaY}px`;\n }\n\n if (matchWidth) {\n floating.style.width = `${ref.getBoundingClientRect().width}px`;\n }\n }\n\n function startAutoUpdate(): () => void {\n const ref = getReference();\n const floating = getFloating();\n\n if (!ref || !floating) return () => {};\n\n return autoUpdate(ref, floating, updatePosition);\n }\n\n return { floating: getFloating, reference: getReference, startAutoUpdate, update: updatePosition };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"positioner.cjs","names":[],"sources":["../../src/core/positioner.ts"],"sourcesContent":["import {\n autoUpdate,\n computePosition,\n flip,\n getClippingAncestorRect,\n offset,\n type Placement,\n type Rect,\n shift,\n size,\n} from '@vielzeug/orbit';\n\nimport { elementDirection } from './direction';\n\n// ── Overlay positioner contract ──────────────────────────────────────────────\n\nexport type OverlayPositioner = {\n floating: () => HTMLElement | null;\n reference: () => HTMLElement | null;\n /** Start continuous position auto-updates. Returns a stop function. */\n startAutoUpdate?: () => () => void;\n update: () => void;\n};\n\n// ── Dropdown positioner ───────────────────────────────────────────────────────\n\nexport type DropdownPositionerOptions = {\n /**\n * Clipping boundary for flip/shift/size — the edges the dropdown must stay within.\n * Defaults to the nearest ancestor that actually clips content (`overflow:\n * hidden|auto|scroll|clip`, e.g. a dialog panel), auto-detected per update via\n * `getClippingAncestorRect()`, intersected with the viewport. Without this, flip/shift only\n * avoid the full page viewport — a dropdown can be \"in view\" by that measure while still\n * visibly overhanging a much smaller container it's actually nested in. Pass an explicit\n * boundary to override auto-detection.\n */\n boundary?: Element | Rect;\n /**\n * Returns the text direction used for placement mirroring. Defaults to the resolved\n * direction of the reference element (nearest `dir=\"ltr\"|\"rtl\"` ancestor, falling back to\n * computed style) — most callers never need to pass this explicitly.\n */\n getDir?: () => 'ltr' | 'rtl';\n /** Getter for the floating (dropdown panel) element. */\n getFloating: () => HTMLElement | null;\n /** Getter for the current placement. Defaults to 'bottom-start' (RTL-aware: flips to 'bottom-end'). */\n getPlacement?: () => Placement;\n /** Getter for the reference (trigger) element. */\n getReference: () => HTMLElement | null;\n /** Whether to match the floating element width to the reference. Default: true */\n matchWidth?: boolean;\n /** Additional offset in pixels between reference and floating element. Default: 0 */\n offsetPx?: number;\n /** Padding (px) used by flip, shift, and size middleware. Default: 6 */\n padding?: number;\n /**\n * Whether to constrain placement to a clipping ancestor when `boundary` is unset. Default:\n * true. Disable for native Popover API panels, which render in the top layer.\n */\n useClippingAncestor?: boolean;\n};\n\n/** Mirrors a start/end placement for RTL layouts. */\nconst rtlPlacement = (p: Placement): Placement => {\n if (p.endsWith('-start')) return p.replace('-start', '-end') as Placement;\n\n if (p.endsWith('-end')) return p.replace('-end', '-start') as Placement;\n\n return p;\n};\n\n/**\n * Creates an Orbit-powered positioner for dropdown overlays (select, combobox, menu).\n *\n * Uses flip + shift + optional width-matching middleware. Supports continuous\n * auto-update for repositioning on scroll or resize.\n *\n * RTL-aware: start/end placements are automatically mirrored so dropdowns open on the\n * correct side, based on `getDir` (or the reference element's resolved direction when\n * `getDir` is omitted).\n */\nexport function createDropdownPositioner({\n boundary,\n getDir,\n getFloating,\n getPlacement,\n getReference,\n matchWidth = true,\n offsetPx = 0,\n padding = 6,\n useClippingAncestor = true,\n}: DropdownPositionerOptions): OverlayPositioner {\n function resolvedPlacement(): Placement {\n const base = getPlacement?.() ?? 'bottom-start';\n const dir = getDir?.() ?? elementDirection(getReference());\n\n return dir === 'rtl' ? rtlPlacement(base) : base;\n }\n\n function updatePosition(): void {\n const ref = getReference();\n const floating = getFloating();\n\n if (!ref || !floating) return;\n\n const placement = resolvedPlacement();\n // Defaults to `undefined` (meaning \"auto-detect\"), not the detected value itself —\n // re-running the detection on every update (rather than once, at positioner-creation time)\n // matters because the dialog/scroll-container an instance is rendered into can change\n // across opens (e.g. the same `<ore-select>` reused in different dialogs), and the detected\n // ancestor's own rect can change between opens even when it's the same element (a resized\n // dialog).\n const resolvedBoundary = boundary ?? (useClippingAncestor ? getClippingAncestorRect(floating) : undefined);\n\n const result = computePosition(ref, floating, {\n boundary: resolvedBoundary,\n middleware: [\n ...(offsetPx ? [offset(offsetPx)] : []),\n flip({ padding }),\n shift({ padding }),\n ...(matchWidth ? [size({ padding })] : []),\n ],\n placement,\n });\n\n floating.style.left = `${result.x}px`;\n floating.style.top = `${result.y}px`;\n\n // `computePosition()` assumes `left`/`top` resolve relative to the viewport (correct for\n // `position: fixed`) — true almost always, but not when some ancestor establishes a\n // containing block for fixed descendants (a non-`none` `transform`, even a visually-identity\n // one left over from an entrance transition that never resets to `none` at rest is a real,\n // easy-to-hit case — a modal dialog's panel, say). Analytically detecting *that* ancestor via\n // `getContainingBlock()` and pre-subtracting its rect turned out to be unreliable in\n // practice: browsers don't apply the \"ancestor transform traps fixed descendants\" rule\n // uniformly across every element nested under it in every case we tested — some floating\n // elements in the exact same subtree needed the correction and some didn't, for reasons we\n // couldn't fully pin down. Measuring what actually happened after writing `left`/`top`\n // and correcting only the observed gap sidesteps that: it's a no-op when the browser already\n // put the element where asked, and it fixes the same class of bug the moment there's a real\n // mismatch, regardless of which specific ancestor (if any) turns out to be responsible.\n //\n // The measurement itself must not be fooled by the floating element's *own* transform,\n // though: dropdowns/popovers here all use a `transform: translateY(...)` entrance transition\n // driven by a `[data-open]` attribute + `@starting-style` — right at open, before the\n // transition has visibly progressed, `getBoundingClientRect()` can still reflect that\n // starting offset (a handful of px, matching `--overlay-enter-translate-y`), which this\n // correction would otherwise misread as a permanent ancestor-driven mismatch and bake in\n // forever. Temporarily neutralizing the floating element's own transform for the measurement\n // (and restoring it before anything paints, so there's no visible flash) isolates the\n // correction to ancestor-driven offsets only, which is the only thing it's meant to fix.\n const prevTransition = floating.style.transition;\n const prevTransform = floating.style.transform;\n\n floating.style.transition = 'none';\n floating.style.transform = 'none';\n\n const actual = floating.getBoundingClientRect();\n const deltaX = result.x - actual.left;\n const deltaY = result.y - actual.top;\n\n floating.style.transition = prevTransition;\n floating.style.transform = prevTransform;\n\n if (deltaX !== 0 || deltaY !== 0) {\n floating.style.left = `${result.x + deltaX}px`;\n floating.style.top = `${result.y + deltaY}px`;\n }\n\n if (matchWidth) {\n floating.style.width = `${ref.getBoundingClientRect().width}px`;\n }\n }\n\n function startAutoUpdate(): () => void {\n const ref = getReference();\n const floating = getFloating();\n\n if (!ref || !floating) return () => {};\n\n return autoUpdate(ref, floating, updatePosition);\n }\n\n return { floating: getFloating, reference: getReference, startAutoUpdate, update: updatePosition };\n}\n"],"mappings":"oEA+DA,IAAM,EAAgB,GAChB,EAAE,SAAS,QAAQ,EAAU,EAAE,QAAQ,SAAU,MAAM,EAEvD,EAAE,SAAS,MAAM,EAAU,EAAE,QAAQ,OAAQ,QAAQ,EAElD,EAaT,SAAgB,EAAyB,CACvC,WACA,SACA,cACA,eACA,eACA,aAAa,GACb,WAAW,EACX,UAAU,EACV,sBAAsB,IACyB,CAC/C,SAAS,GAA+B,CACtC,IAAM,EAAO,IAAe,GAAK,eAGjC,OAFY,IAAS,GAAK,EAAA,iBAAiB,EAAa,CAAC,KAE1C,MAAQ,EAAa,CAAI,EAAI,CAC9C,CAEA,SAAS,GAAuB,CAC9B,IAAM,EAAM,EAAa,EACnB,EAAW,EAAY,EAE7B,GAAI,CAAC,GAAO,CAAC,EAAU,OAEvB,IAAM,EAAY,EAAkB,EAO9B,EAAmB,IAAa,GAAA,EAAsB,EAAA,wBAAA,CAAwB,CAAQ,EAAI,IAAA,IAE1F,GAAA,EAAS,EAAA,gBAAA,CAAgB,EAAK,EAAU,CAC5C,SAAU,EACV,WAAY,CACV,GAAI,EAAW,EAAA,EAAC,EAAA,OAAA,CAAO,CAAQ,CAAC,EAAI,CAAC,GACrC,EAAA,EAAA,KAAA,CAAK,CAAE,SAAQ,CAAC,GAChB,EAAA,EAAA,MAAA,CAAM,CAAE,SAAQ,CAAC,EACjB,GAAI,EAAa,EAAA,EAAC,EAAA,KAAA,CAAK,CAAE,SAAQ,CAAC,CAAC,EAAI,CAAC,CAC1C,EACA,WACF,CAAC,EAED,EAAS,MAAM,KAAO,GAAG,EAAO,EAAE,IAClC,EAAS,MAAM,IAAM,GAAG,EAAO,EAAE,IAyBjC,IAAM,EAAiB,EAAS,MAAM,WAChC,EAAgB,EAAS,MAAM,UAErC,EAAS,MAAM,WAAa,OAC5B,EAAS,MAAM,UAAY,OAE3B,IAAM,EAAS,EAAS,sBAAsB,EACxC,EAAS,EAAO,EAAI,EAAO,KAC3B,EAAS,EAAO,EAAI,EAAO,IAEjC,EAAS,MAAM,WAAa,EAC5B,EAAS,MAAM,UAAY,GAEvB,IAAW,GAAK,IAAW,KAC7B,EAAS,MAAM,KAAO,GAAG,EAAO,EAAI,EAAO,IAC3C,EAAS,MAAM,IAAM,GAAG,EAAO,EAAI,EAAO,KAGxC,IACF,EAAS,MAAM,MAAQ,GAAG,EAAI,sBAAsB,CAAC,CAAC,MAAM,IAEhE,CAEA,SAAS,GAA8B,CACrC,IAAM,EAAM,EAAa,EACnB,EAAW,EAAY,EAI7B,MAFI,CAAC,GAAO,CAAC,MAAuB,CAAC,GAErC,EAAO,EAAA,WAAA,CAAW,EAAK,EAAU,CAAc,CACjD,CAEA,MAAO,CAAE,SAAU,EAAa,UAAW,EAAc,kBAAiB,OAAQ,CAAe,CACnG"}
|