@exsto/ds 0.0.1-rc.2 → 0.0.1-rc.22
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/README.md +171 -28
- package/dist/date-picker.js +2 -0
- package/dist/ds/src/date-picker.d.ts +9 -0
- package/dist/ds/src/file-input.d.ts +9 -0
- package/dist/ds/src/index.d.ts +2 -3
- package/dist/ds/src/rich-text-editor.d.ts +8 -0
- package/dist/ds/src/time-field.d.ts +9 -0
- package/dist/file-input.js +2 -0
- package/dist/index.js +79 -2
- package/dist/rich-text-editor.js +4 -0
- package/dist/source-hash.txt +1 -0
- package/dist/styles.css +1201 -404
- package/dist/theme.css +125 -7
- package/dist/time-field.js +2 -0
- package/dist/ui/src/components/edyn/animated-number/animated-number.d.ts +30 -0
- package/dist/ui/src/components/edyn/animated-number/animated-number.js +108 -0
- package/dist/ui/src/components/edyn/animated-number/animated-number.js.map +1 -0
- package/dist/ui/src/components/edyn/animated-number/animated-number.test.d.ts +9 -0
- package/dist/ui/src/components/edyn/animated-number/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/audio-player/audio-player.d.ts +3 -2
- package/dist/ui/src/components/edyn/audio-player/audio-player.js +86 -0
- package/dist/ui/src/components/edyn/audio-player/audio-player.js.map +1 -0
- package/dist/ui/src/components/edyn/date-picker/date-picker.d.ts +86 -0
- package/dist/ui/src/components/edyn/date-picker/date-picker.js +302 -0
- package/dist/ui/src/components/edyn/date-picker/date-picker.js.map +1 -0
- package/dist/ui/src/components/edyn/date-picker/date-picker.state.test.d.ts +9 -0
- package/dist/ui/src/components/edyn/date-picker/date-text.d.ts +40 -0
- package/dist/ui/src/components/edyn/date-picker/date-text.js +105 -0
- package/dist/ui/src/components/edyn/date-picker/date-text.js.map +1 -0
- package/dist/ui/src/components/edyn/date-picker/index.d.ts +2 -0
- package/dist/ui/src/components/edyn/date-range-picker/date-range-picker.d.ts +28 -0
- package/dist/ui/src/components/edyn/date-range-picker/date-range-picker.js +70 -0
- package/dist/ui/src/components/edyn/date-range-picker/date-range-picker.js.map +1 -0
- package/dist/ui/src/components/edyn/date-range-picker/date-range-picker.test.d.ts +9 -0
- package/dist/ui/src/components/edyn/date-range-picker/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/file-input/file-input.d.ts +90 -0
- package/dist/ui/src/components/edyn/file-input/file-input.js +261 -0
- package/dist/ui/src/components/edyn/file-input/file-input.js.map +1 -0
- package/dist/ui/src/components/edyn/file-input/file-input.test.d.ts +8 -0
- package/dist/ui/src/components/edyn/file-input/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/initials-avatar/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/initials-avatar/initials-avatar.d.ts +54 -0
- package/dist/ui/src/components/edyn/initials-avatar/initials-avatar.js +86 -0
- package/dist/ui/src/components/edyn/initials-avatar/initials-avatar.js.map +1 -0
- package/dist/ui/src/components/edyn/initials-avatar/initials-avatar.test.d.ts +10 -0
- package/dist/ui/src/components/edyn/multi-select/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/multi-select/multi-select.d.ts +117 -0
- package/dist/ui/src/components/edyn/multi-select/multi-select.js +342 -0
- package/dist/ui/src/components/edyn/multi-select/multi-select.js.map +1 -0
- package/dist/ui/src/components/edyn/multi-select/multi-select.test.d.ts +9 -0
- package/dist/ui/src/components/edyn/presence/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/presence/presence.d.ts +15 -0
- package/dist/ui/src/components/edyn/presence/presence.js +58 -0
- package/dist/ui/src/components/edyn/presence/presence.js.map +1 -0
- package/dist/ui/src/components/edyn/presence/presence.test.d.ts +8 -0
- package/dist/ui/src/components/edyn/progress-line/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/progress-line/progress-line.d.ts +23 -0
- package/dist/ui/src/components/edyn/progress-line/progress-line.js +100 -0
- package/dist/ui/src/components/edyn/progress-line/progress-line.js.map +1 -0
- package/dist/ui/src/components/edyn/progress-line/progress-line.test.d.ts +9 -0
- package/dist/ui/src/components/edyn/rich-text-content/allow-list.d.ts +11 -0
- package/dist/ui/src/components/edyn/rich-text-content/allow-list.js +37 -0
- package/dist/ui/src/components/edyn/rich-text-content/allow-list.js.map +1 -0
- package/dist/ui/src/components/edyn/rich-text-content/index.d.ts +2 -0
- package/dist/ui/src/components/edyn/rich-text-content/rich-text-content.d.ts +22 -0
- package/dist/ui/src/components/edyn/rich-text-content/rich-text-content.js +124 -0
- package/dist/ui/src/components/edyn/rich-text-content/rich-text-content.js.map +1 -0
- package/dist/ui/src/components/edyn/rich-text-content/rich-text-content.test.d.ts +8 -0
- package/dist/ui/src/components/edyn/rich-text-editor/extensions.d.ts +18 -0
- package/dist/ui/src/components/edyn/rich-text-editor/extensions.js +124 -0
- package/dist/ui/src/components/edyn/rich-text-editor/extensions.js.map +1 -0
- package/dist/ui/src/components/edyn/rich-text-editor/index.d.ts +3 -0
- package/dist/ui/src/components/edyn/rich-text-editor/mention-list.d.ts +17 -0
- package/dist/ui/src/components/edyn/rich-text-editor/mention-list.js +232 -0
- package/dist/ui/src/components/edyn/rich-text-editor/mention-list.js.map +1 -0
- package/dist/ui/src/components/edyn/rich-text-editor/rich-text-editor.d.ts +53 -0
- package/dist/ui/src/components/edyn/rich-text-editor/rich-text-editor.js +244 -0
- package/dist/ui/src/components/edyn/rich-text-editor/rich-text-editor.js.map +1 -0
- package/dist/ui/src/components/edyn/rich-text-editor/rich-text-editor.test.d.ts +6 -0
- package/dist/ui/src/components/edyn/rich-text-editor/serialize.d.ts +13 -0
- package/dist/ui/src/components/edyn/rich-text-editor/serialize.js +55 -0
- package/dist/ui/src/components/edyn/rich-text-editor/serialize.js.map +1 -0
- package/dist/ui/src/components/edyn/rich-text-editor/sync.d.ts +19 -0
- package/dist/ui/src/components/edyn/rich-text-editor/sync.js +34 -0
- package/dist/ui/src/components/edyn/rich-text-editor/sync.js.map +1 -0
- package/dist/ui/src/components/edyn/rich-text-editor/sync.test.d.ts +11 -0
- package/dist/ui/src/components/edyn/rich-text-editor/toolbar.d.ts +20 -0
- package/dist/ui/src/components/edyn/rich-text-editor/toolbar.js +235 -0
- package/dist/ui/src/components/edyn/rich-text-editor/toolbar.js.map +1 -0
- package/dist/ui/src/components/edyn/rich-text-editor/types.d.ts +68 -0
- package/dist/ui/src/components/edyn/rich-text-editor/types.js +26 -0
- package/dist/ui/src/components/edyn/rich-text-editor/types.js.map +1 -0
- package/dist/ui/src/components/edyn/time-field/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/time-field/time-field.d.ts +85 -0
- package/dist/ui/src/components/edyn/time-field/time-field.js +337 -0
- package/dist/ui/src/components/edyn/time-field/time-field.js.map +1 -0
- package/dist/ui/src/components/edyn/time-field/time-field.test.d.ts +8 -0
- package/dist/ui/src/components/edyn/video-player/video-player.d.ts +2 -2
- package/dist/ui/src/components/edyn/video-player/video-player.js +132 -0
- package/dist/ui/src/components/edyn/video-player/video-player.js.map +1 -0
- package/dist/ui/src/components/forwarded-props.test.d.ts +8 -0
- package/dist/ui/src/components/ui/accordion/accordion.d.ts +9 -8
- package/dist/ui/src/components/ui/accordion/accordion.js +83 -0
- package/dist/ui/src/components/ui/accordion/accordion.js.map +1 -0
- package/dist/ui/src/components/ui/alert/alert.js +47 -0
- package/dist/ui/src/components/ui/alert/alert.js.map +1 -0
- package/dist/ui/src/components/ui/alert-dialog/alert-dialog.js +97 -0
- package/dist/ui/src/components/ui/alert-dialog/alert-dialog.js.map +1 -0
- package/dist/ui/src/components/ui/aspect-ratio/aspect-ratio.js +15 -0
- package/dist/ui/src/components/ui/aspect-ratio/aspect-ratio.js.map +1 -0
- package/dist/ui/src/components/ui/attachment/attachment.d.ts +1 -1
- package/dist/ui/src/components/ui/attachment/attachment.js +105 -0
- package/dist/ui/src/components/ui/attachment/attachment.js.map +1 -0
- package/dist/ui/src/components/ui/avatar/avatar.js +51 -0
- package/dist/ui/src/components/ui/avatar/avatar.js.map +1 -0
- package/dist/ui/src/components/ui/badge/badge.d.ts +1 -1
- package/dist/ui/src/components/ui/badge/badge.js +47 -0
- package/dist/ui/src/components/ui/badge/badge.js.map +1 -0
- package/dist/ui/src/components/ui/breadcrumb/breadcrumb.js +73 -0
- package/dist/ui/src/components/ui/breadcrumb/breadcrumb.js.map +1 -0
- package/dist/ui/src/components/ui/bubble/bubble.js +74 -0
- package/dist/ui/src/components/ui/bubble/bubble.js.map +1 -0
- package/dist/ui/src/components/ui/button/button.behavior.test.d.ts +8 -0
- package/dist/ui/src/components/ui/button/button.d.ts +1 -1
- package/dist/ui/src/components/ui/button/button.js +68 -0
- package/dist/ui/src/components/ui/button/button.js.map +1 -0
- package/dist/ui/src/components/ui/button-group/button-group.js +37 -0
- package/dist/ui/src/components/ui/button-group/button-group.js.map +1 -0
- package/dist/ui/src/components/ui/calendar/calendar.behavior.test.d.ts +9 -0
- package/dist/ui/src/components/ui/calendar/calendar.d.ts +1 -1
- package/dist/ui/src/components/ui/calendar/calendar.js +141 -0
- package/dist/ui/src/components/ui/calendar/calendar.js.map +1 -0
- package/dist/ui/src/components/ui/card/card.js +57 -0
- package/dist/ui/src/components/ui/card/card.js.map +1 -0
- package/dist/ui/src/components/ui/carousel/carousel.js +136 -0
- package/dist/ui/src/components/ui/carousel/carousel.js.map +1 -0
- package/dist/ui/src/components/ui/chart/chart.js +168 -0
- package/dist/ui/src/components/ui/chart/chart.js.map +1 -0
- package/dist/ui/src/components/ui/checkbox/checkbox.js +21 -0
- package/dist/ui/src/components/ui/checkbox/checkbox.js.map +1 -0
- package/dist/ui/src/components/ui/collapsible/collapsible.js +26 -0
- package/dist/ui/src/components/ui/collapsible/collapsible.js.map +1 -0
- package/dist/ui/src/components/ui/combobox/combobox.d.ts +15 -1
- package/dist/ui/src/components/ui/combobox/combobox.js +111 -0
- package/dist/ui/src/components/ui/combobox/combobox.js.map +1 -0
- package/dist/ui/src/components/ui/command/command.d.ts +17 -1
- package/dist/ui/src/components/ui/command/command.js +118 -0
- package/dist/ui/src/components/ui/command/command.js.map +1 -0
- package/dist/ui/src/components/ui/context-menu/context-menu.d.ts +1 -1
- package/dist/ui/src/components/ui/context-menu/context-menu.js +145 -0
- package/dist/ui/src/components/ui/context-menu/context-menu.js.map +1 -0
- package/dist/ui/src/components/ui/dialog/dialog.js +94 -0
- package/dist/ui/src/components/ui/dialog/dialog.js.map +1 -0
- package/dist/ui/src/components/ui/direction/direction.js +2 -0
- package/dist/ui/src/components/ui/drawer/drawer.js +88 -0
- package/dist/ui/src/components/ui/drawer/drawer.js.map +1 -0
- package/dist/ui/src/components/ui/dropdown-menu/dropdown-menu.d.ts +12 -1
- package/dist/ui/src/components/ui/dropdown-menu/dropdown-menu.js +159 -0
- package/dist/ui/src/components/ui/dropdown-menu/dropdown-menu.js.map +1 -0
- package/dist/ui/src/components/ui/empty/empty.d.ts +5 -1
- package/dist/ui/src/components/ui/empty/empty.js +72 -0
- package/dist/ui/src/components/ui/empty/empty.js.map +1 -0
- package/dist/ui/src/components/ui/field/field.js +36 -0
- package/dist/ui/src/components/ui/field/field.js.map +1 -0
- package/dist/ui/src/components/ui/hover-card/hover-card.js +39 -0
- package/dist/ui/src/components/ui/hover-card/hover-card.js.map +1 -0
- package/dist/ui/src/components/ui/indicator/indicator.js +79 -0
- package/dist/ui/src/components/ui/indicator/indicator.js.map +1 -0
- package/dist/ui/src/components/ui/input/input.js +16 -0
- package/dist/ui/src/components/ui/input/input.js.map +1 -0
- package/dist/ui/src/components/ui/input-group/input-group.d.ts +1 -1
- package/dist/ui/src/components/ui/input-group/input-group.js +77 -0
- package/dist/ui/src/components/ui/input-group/input-group.js.map +1 -0
- package/dist/ui/src/components/ui/input-otp/input-otp.js +48 -0
- package/dist/ui/src/components/ui/input-otp/input-otp.js.map +1 -0
- package/dist/ui/src/components/ui/item/item.d.ts +1 -1
- package/dist/ui/src/components/ui/item/item.js +122 -0
- package/dist/ui/src/components/ui/item/item.js.map +1 -0
- package/dist/ui/src/components/ui/kbd/kbd.js +21 -0
- package/dist/ui/src/components/ui/kbd/kbd.js.map +1 -0
- package/dist/ui/src/components/ui/label/label.js +14 -0
- package/dist/ui/src/components/ui/label/label.js.map +1 -0
- package/dist/ui/src/components/ui/marker/marker.js +44 -0
- package/dist/ui/src/components/ui/marker/marker.js.map +1 -0
- package/dist/ui/src/components/ui/menubar/menubar.js +140 -0
- package/dist/ui/src/components/ui/menubar/menubar.js.map +1 -0
- package/dist/ui/src/components/ui/message/message.js +50 -0
- package/dist/ui/src/components/ui/message/message.js.map +1 -0
- package/dist/ui/src/components/ui/message-scroller/message-scroller.js +61 -0
- package/dist/ui/src/components/ui/message-scroller/message-scroller.js.map +1 -0
- package/dist/ui/src/components/ui/native-select/native-select.js +39 -0
- package/dist/ui/src/components/ui/native-select/native-select.js.map +1 -0
- package/dist/ui/src/components/ui/navigation-menu/navigation-menu.js +87 -0
- package/dist/ui/src/components/ui/navigation-menu/navigation-menu.js.map +1 -0
- package/dist/ui/src/components/ui/pagination/pagination.d.ts +3 -2
- package/dist/ui/src/components/ui/pagination/pagination.js +104 -0
- package/dist/ui/src/components/ui/pagination/pagination.js.map +1 -0
- package/dist/ui/src/components/ui/popover/popover.d.ts +1 -1
- package/dist/ui/src/components/ui/popover/popover.js +59 -0
- package/dist/ui/src/components/ui/popover/popover.js.map +1 -0
- package/dist/ui/src/components/ui/progress/progress.behavior.test.d.ts +8 -0
- package/dist/ui/src/components/ui/progress/progress.d.ts +43 -1
- package/dist/ui/src/components/ui/progress/progress.js +70 -0
- package/dist/ui/src/components/ui/progress/progress.js.map +1 -0
- package/dist/ui/src/components/ui/questionnaire/questionnaire.js +171 -0
- package/dist/ui/src/components/ui/questionnaire/questionnaire.js.map +1 -0
- package/dist/ui/src/components/ui/radio-group/radio-group.js +29 -0
- package/dist/ui/src/components/ui/radio-group/radio-group.js.map +1 -0
- package/dist/ui/src/components/ui/resizable/resizable.js +29 -0
- package/dist/ui/src/components/ui/resizable/resizable.js.map +1 -0
- package/dist/ui/src/components/ui/scroll-area/index.d.ts +1 -0
- package/dist/ui/src/components/ui/scroll-area/popup-list-scroll.d.ts +13 -0
- package/dist/ui/src/components/ui/scroll-area/popup-list-scroll.js +69 -0
- package/dist/ui/src/components/ui/scroll-area/popup-list-scroll.js.map +1 -0
- package/dist/ui/src/components/ui/scroll-area/scroll-area.behavior.test.d.ts +12 -0
- package/dist/ui/src/components/ui/scroll-area/scroll-area.d.ts +57 -6
- package/dist/ui/src/components/ui/scroll-area/scroll-area.js +125 -0
- package/dist/ui/src/components/ui/scroll-area/scroll-area.js.map +1 -0
- package/dist/ui/src/components/ui/select/select.js +97 -0
- package/dist/ui/src/components/ui/select/select.js.map +1 -0
- package/dist/ui/src/components/ui/separator/separator.behavior.test.d.ts +14 -0
- package/dist/ui/src/components/ui/separator/separator.d.ts +14 -0
- package/dist/ui/src/components/ui/separator/separator.js +30 -0
- package/dist/ui/src/components/ui/separator/separator.js.map +1 -0
- package/dist/ui/src/components/ui/sheet/sheet.d.ts +8 -0
- package/dist/ui/src/components/ui/sheet/sheet.js +99 -0
- package/dist/ui/src/components/ui/sheet/sheet.js.map +1 -0
- package/dist/ui/src/components/ui/sidebar/sidebar.js +383 -0
- package/dist/ui/src/components/ui/sidebar/sidebar.js.map +1 -0
- package/dist/ui/src/components/ui/skeleton/skeleton.js +14 -0
- package/dist/ui/src/components/ui/skeleton/skeleton.js.map +1 -0
- package/dist/ui/src/components/ui/slider/slider.js +49 -0
- package/dist/ui/src/components/ui/slider/slider.js.map +1 -0
- package/dist/ui/src/components/ui/spinner/spinner.js +28 -0
- package/dist/ui/src/components/ui/spinner/spinner.js.map +1 -0
- package/dist/ui/src/components/ui/switch/switch.js +20 -0
- package/dist/ui/src/components/ui/switch/switch.js.map +1 -0
- package/dist/ui/src/components/ui/table/table.behavior.test.d.ts +4 -5
- package/dist/ui/src/components/ui/table/table.d.ts +15 -1
- package/dist/ui/src/components/ui/table/table.js +81 -0
- package/dist/ui/src/components/ui/table/table.js.map +1 -0
- package/dist/ui/src/components/ui/tabs/tabs.d.ts +14 -8
- package/dist/ui/src/components/ui/tabs/tabs.js +115 -0
- package/dist/ui/src/components/ui/tabs/tabs.js.map +1 -0
- package/dist/ui/src/components/ui/textarea/textarea.js +14 -0
- package/dist/ui/src/components/ui/textarea/textarea.js.map +1 -0
- package/dist/ui/src/components/ui/toast/toast.js +124 -0
- package/dist/ui/src/components/ui/toast/toast.js.map +1 -0
- package/dist/ui/src/components/ui/toggle/toggle.js +37 -0
- package/dist/ui/src/components/ui/toggle/toggle.js.map +1 -0
- package/dist/ui/src/components/ui/toggle-group/toggle-group.js +56 -0
- package/dist/ui/src/components/ui/toggle-group/toggle-group.js.map +1 -0
- package/dist/ui/src/components/ui/tooltip/tooltip.js +43 -0
- package/dist/ui/src/components/ui/tooltip/tooltip.js.map +1 -0
- package/dist/ui/src/hooks/use-holds-focusable.d.ts +3 -0
- package/dist/ui/src/hooks/use-holds-focusable.js +33 -0
- package/dist/ui/src/hooks/use-holds-focusable.js.map +1 -0
- package/dist/ui/src/hooks/use-media-player.js +140 -0
- package/dist/ui/src/hooks/use-media-player.js.map +1 -0
- package/dist/ui/src/hooks/use-merged-refs.js +18 -0
- package/dist/ui/src/hooks/use-merged-refs.js.map +1 -0
- package/dist/ui/src/hooks/use-mobile.js +20 -0
- package/dist/ui/src/hooks/use-mobile.js.map +1 -0
- package/dist/ui/src/index.d.ts +8 -0
- package/dist/ui/src/lib/first-weekday.d.ts +6 -0
- package/dist/ui/src/lib/first-weekday.js +34 -0
- package/dist/ui/src/lib/first-weekday.js.map +1 -0
- package/dist/ui/src/lib/focus-guards.d.ts +2 -0
- package/dist/ui/src/lib/focus-guards.js +44 -0
- package/dist/ui/src/lib/focus-guards.js.map +1 -0
- package/dist/ui/src/lib/focus-ring.test.d.ts +8 -0
- package/dist/ui/src/lib/popup-list.d.ts +75 -0
- package/dist/ui/src/lib/popup-list.js +48 -0
- package/dist/ui/src/lib/popup-list.js.map +1 -0
- package/dist/ui/src/lib/popup-list.test.d.ts +10 -0
- package/dist/ui/src/lib/utils.js +21 -0
- package/dist/ui/src/lib/utils.js.map +1 -0
- package/package.json +36 -8
- package/dist/chunks/toggle-group-ByNq8g7H.js +0 -4263
- package/dist/chunks/toggle-group-ByNq8g7H.js.map +0 -1
- package/dist/dom/src/context.d.ts +0 -34
- package/dist/dom/src/define-element.d.ts +0 -11
- package/dist/dom/src/field-control.d.ts +0 -5
- package/dist/dom/src/index.d.ts +0 -6
- package/dist/dom/src/mode.d.ts +0 -8
- package/dist/dom/src/styles.d.ts +0 -6
- package/dist/dom/src/theme-state.d.ts +0 -1
- package/dist/dom/src/types.d.ts +0 -65
- package/dist/ds/src/elements.d.ts +0 -12
- package/dist/elements/src/edx-accordion.d.ts +0 -14
- package/dist/elements/src/edx-accordion.test.d.ts +0 -1
- package/dist/elements/src/edx-alert.d.ts +0 -14
- package/dist/elements/src/edx-audio-player.d.ts +0 -11
- package/dist/elements/src/edx-avatar.d.ts +0 -10
- package/dist/elements/src/edx-badge.d.ts +0 -12
- package/dist/elements/src/edx-breadcrumb.d.ts +0 -11
- package/dist/elements/src/edx-button-group.d.ts +0 -7
- package/dist/elements/src/edx-button.d.ts +0 -20
- package/dist/elements/src/edx-calendar.d.ts +0 -21
- package/dist/elements/src/edx-card.d.ts +0 -8
- package/dist/elements/src/edx-checkbox.d.ts +0 -18
- package/dist/elements/src/edx-combobox.d.ts +0 -28
- package/dist/elements/src/edx-content-components.d.ts +0 -2
- package/dist/elements/src/edx-dialog.d.ts +0 -20
- package/dist/elements/src/edx-drawer.d.ts +0 -21
- package/dist/elements/src/edx-dropdown-menu.d.ts +0 -29
- package/dist/elements/src/edx-field.d.ts +0 -9
- package/dist/elements/src/edx-field.test.d.ts +0 -1
- package/dist/elements/src/edx-indicator.d.ts +0 -14
- package/dist/elements/src/edx-input-group.d.ts +0 -32
- package/dist/elements/src/edx-input-otp.d.ts +0 -19
- package/dist/elements/src/edx-input.d.ts +0 -31
- package/dist/elements/src/edx-interactive-components.d.ts +0 -2
- package/dist/elements/src/edx-label.d.ts +0 -6
- package/dist/elements/src/edx-pagination.d.ts +0 -8
- package/dist/elements/src/edx-popover.d.ts +0 -24
- package/dist/elements/src/edx-progress.d.ts +0 -10
- package/dist/elements/src/edx-radio-group.d.ts +0 -22
- package/dist/elements/src/edx-radio-group.test.d.ts +0 -1
- package/dist/elements/src/edx-scroll-area.d.ts +0 -15
- package/dist/elements/src/edx-scroll-area.test.d.ts +0 -1
- package/dist/elements/src/edx-select.d.ts +0 -34
- package/dist/elements/src/edx-separator.d.ts +0 -10
- package/dist/elements/src/edx-skeleton.d.ts +0 -8
- package/dist/elements/src/edx-slider.d.ts +0 -17
- package/dist/elements/src/edx-slider.test.d.ts +0 -1
- package/dist/elements/src/edx-switch.d.ts +0 -18
- package/dist/elements/src/edx-table.d.ts +0 -13
- package/dist/elements/src/edx-table.test.d.ts +0 -1
- package/dist/elements/src/edx-tabs.d.ts +0 -15
- package/dist/elements/src/edx-tabs.test.d.ts +0 -1
- package/dist/elements/src/edx-textarea.d.ts +0 -25
- package/dist/elements/src/edx-toggle-group.d.ts +0 -27
- package/dist/elements/src/edx-toggle-group.test.d.ts +0 -1
- package/dist/elements/src/edx-toggle.d.ts +0 -18
- package/dist/elements/src/edx-tooltip.d.ts +0 -28
- package/dist/elements/src/edx-video-player.d.ts +0 -16
- package/dist/elements/src/field-control-bridge.d.ts +0 -7
- package/dist/elements/src/index.d.ts +0 -14
- package/dist/elements/src/projected-content.test.d.ts +0 -1
- package/dist/elements/src/registry.d.ts +0 -39
- package/dist/elements/src/registry.test.d.ts +0 -1
- package/dist/elements.js +0 -4020
- package/dist/elements.js.map +0 -1
- /package/dist/{dom/src/define-element.test.d.ts → ui/src/components/edyn/date-picker/date-text.test.d.ts} +0 -0
- /package/dist/{dom/src/native-slot.test.d.ts → ui/src/lib/first-weekday.test.d.ts} +0 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { InputGroup, InputGroupAddon } from "../../ui/input-group/input-group.js";
|
|
3
|
+
import { useMemo, useRef, useState } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { IconClock } from "@tabler/icons-react";
|
|
6
|
+
//#region ../ui/src/components/edyn/time-field/time-field.tsx
|
|
7
|
+
var EMPTY_TIME = {
|
|
8
|
+
hour: null,
|
|
9
|
+
minute: null,
|
|
10
|
+
second: null,
|
|
11
|
+
period: null
|
|
12
|
+
};
|
|
13
|
+
var DEFAULT_TIME_FIELD_LABELS = {
|
|
14
|
+
hour: "Hours",
|
|
15
|
+
minute: "Minutes",
|
|
16
|
+
second: "Seconds",
|
|
17
|
+
period: "AM or PM",
|
|
18
|
+
empty: "Empty"
|
|
19
|
+
};
|
|
20
|
+
/** What an empty segment shows. Letters, as a DatePicker's pattern is, never a dash. */
|
|
21
|
+
var SEGMENT_PLACEHOLDER = {
|
|
22
|
+
hour: "HH",
|
|
23
|
+
minute: "MM",
|
|
24
|
+
second: "SS",
|
|
25
|
+
period: "AM"
|
|
26
|
+
};
|
|
27
|
+
var TIME = /^(\d{2}):(\d{2})(?::(\d{2}))?$/;
|
|
28
|
+
var two = (value) => String(value).padStart(2, "0");
|
|
29
|
+
/** 12 where the reader's locale writes AM and PM, 24 where it does not. */
|
|
30
|
+
var localeHourCycle = () => new Intl.DateTimeFormat(void 0, { hour: "numeric" }).resolvedOptions().hour12 ? 12 : 24;
|
|
31
|
+
/** `HH:mm` or `HH:mm:ss` (24-hour, as `<input type="time">` writes it) to the segments; anything else is no time. */
|
|
32
|
+
var parseTime = (value, hourCycle) => {
|
|
33
|
+
const match = TIME.exec(value);
|
|
34
|
+
if (match === null) return EMPTY_TIME;
|
|
35
|
+
const hour24 = Number(match[1]);
|
|
36
|
+
const minute = Number(match[2]);
|
|
37
|
+
const second = match[3] === void 0 ? 0 : Number(match[3]);
|
|
38
|
+
if (hour24 > 23 || minute > 59 || second > 59) return EMPTY_TIME;
|
|
39
|
+
if (hourCycle === 24) return {
|
|
40
|
+
hour: hour24,
|
|
41
|
+
minute,
|
|
42
|
+
second,
|
|
43
|
+
period: null
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
hour: hour24 % 12 === 0 ? 12 : hour24 % 12,
|
|
47
|
+
minute,
|
|
48
|
+
second,
|
|
49
|
+
period: hour24 >= 12 ? "PM" : "AM"
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
/** The segments to `HH:mm` or `HH:mm:ss`, or '' until every segment the field shows is in. */
|
|
53
|
+
var formatTime = (parts, hourCycle, granularity) => {
|
|
54
|
+
const { hour, minute, second, period } = parts;
|
|
55
|
+
if (hour === null || minute === null || granularity === "second" && second === null) return "";
|
|
56
|
+
let hour24 = hour;
|
|
57
|
+
if (hourCycle === 12) {
|
|
58
|
+
if (period === null || hour === 0) return "";
|
|
59
|
+
hour24 = hour % 12 + (period === "PM" ? 12 : 0);
|
|
60
|
+
}
|
|
61
|
+
return granularity === "second" ? `${two(hour24)}:${two(minute)}:${two(second ?? 0)}` : `${two(hour24)}:${two(minute)}`;
|
|
62
|
+
};
|
|
63
|
+
var rangeOf = (segment, hourCycle) => {
|
|
64
|
+
if (segment === "hour") return hourCycle === 12 ? {
|
|
65
|
+
min: 1,
|
|
66
|
+
max: 12
|
|
67
|
+
} : {
|
|
68
|
+
min: 0,
|
|
69
|
+
max: 23
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
min: 0,
|
|
73
|
+
max: 59
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
/** One step up or down inside a range, wrapping at the ends. A segment with nothing in it starts at the end the step is heading away from. */
|
|
77
|
+
var stepValue = (current, delta, { min, max }) => {
|
|
78
|
+
if (current === null) return delta > 0 ? min : max;
|
|
79
|
+
const size = max - min + 1;
|
|
80
|
+
return ((current - min + delta) % size + size) % size + min;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Types a digit into a segment. The second digit joins the first when it makes a number the segment can hold; otherwise it starts
|
|
84
|
+
* over. The segment is done, and focus moves on, at two digits or as soon as no second digit could fit (a 3 in the hours, a 6 in the
|
|
85
|
+
* minutes).
|
|
86
|
+
*/
|
|
87
|
+
var typeDigit = (buffer, digit, { min, max }) => {
|
|
88
|
+
let text = buffer + digit;
|
|
89
|
+
if (text.length > 2 || Number(text) > max) text = digit;
|
|
90
|
+
const value = Number(text);
|
|
91
|
+
const done = text.length === 2 || value * 10 > max;
|
|
92
|
+
return {
|
|
93
|
+
value: done && value < min ? min : value,
|
|
94
|
+
buffer: done ? "" : text,
|
|
95
|
+
done
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
var PAGE_STEP = {
|
|
99
|
+
hour: 3,
|
|
100
|
+
minute: 10,
|
|
101
|
+
second: 10
|
|
102
|
+
};
|
|
103
|
+
var withSegment = (parts, segment, value) => ({
|
|
104
|
+
...parts,
|
|
105
|
+
[segment]: value
|
|
106
|
+
});
|
|
107
|
+
/** What a key does to a segment, or null when the key is not one the segment handles (Tab, a letter in the hours...). */
|
|
108
|
+
var editSegment = (parts, segment, key, hourCycle, buffer) => {
|
|
109
|
+
if (segment === "period") {
|
|
110
|
+
const current = parts.period;
|
|
111
|
+
const set = (period) => ({
|
|
112
|
+
parts: {
|
|
113
|
+
...parts,
|
|
114
|
+
period
|
|
115
|
+
},
|
|
116
|
+
buffer: "",
|
|
117
|
+
advance: false
|
|
118
|
+
});
|
|
119
|
+
switch (key) {
|
|
120
|
+
case "a":
|
|
121
|
+
case "A": return {
|
|
122
|
+
...set("AM"),
|
|
123
|
+
advance: true
|
|
124
|
+
};
|
|
125
|
+
case "p":
|
|
126
|
+
case "P": return {
|
|
127
|
+
...set("PM"),
|
|
128
|
+
advance: true
|
|
129
|
+
};
|
|
130
|
+
case "ArrowUp":
|
|
131
|
+
case "ArrowDown": return set(current === null ? key === "ArrowUp" ? "AM" : "PM" : current === "AM" ? "PM" : "AM");
|
|
132
|
+
case "Home": return set("AM");
|
|
133
|
+
case "End": return set("PM");
|
|
134
|
+
case "Backspace":
|
|
135
|
+
case "Delete": return set(null);
|
|
136
|
+
default: return null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const range = rangeOf(segment, hourCycle);
|
|
140
|
+
const current = parts[segment];
|
|
141
|
+
const set = (value, advance = false) => ({
|
|
142
|
+
parts: withSegment(parts, segment, value),
|
|
143
|
+
buffer: "",
|
|
144
|
+
advance
|
|
145
|
+
});
|
|
146
|
+
if (/^[0-9]$/.test(key)) {
|
|
147
|
+
const typed = typeDigit(buffer, key, range);
|
|
148
|
+
return {
|
|
149
|
+
parts: withSegment(parts, segment, typed.value),
|
|
150
|
+
buffer: typed.buffer,
|
|
151
|
+
advance: typed.done
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
switch (key) {
|
|
155
|
+
case "ArrowUp": return set(stepValue(current, 1, range));
|
|
156
|
+
case "ArrowDown": return set(stepValue(current, -1, range));
|
|
157
|
+
case "PageUp": return set(stepValue(current, PAGE_STEP[segment], range));
|
|
158
|
+
case "PageDown": return set(stepValue(current, -PAGE_STEP[segment], range));
|
|
159
|
+
case "Home": return set(range.min);
|
|
160
|
+
case "End": return set(range.max);
|
|
161
|
+
case "Backspace":
|
|
162
|
+
case "Delete": return set(null);
|
|
163
|
+
default: return null;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
var SEGMENT_CLASS = "h-6 rounded-sm bg-transparent text-center text-sm tabular-nums caret-transparent outline-none selection:bg-transparent placeholder:text-muted-foreground focus:bg-foreground/10 disabled:cursor-not-allowed";
|
|
167
|
+
/**
|
|
168
|
+
* A time of day typed in segments, in the kit's field: hours, minutes, optional seconds, and AM/PM where the reader's locale uses it.
|
|
169
|
+
* It exists so an app does not fall back to `<input type="time">`, whose look differs between browsers and from the rest of the kit.
|
|
170
|
+
*
|
|
171
|
+
* Each segment is a spinbutton: type digits (the focus moves on by itself), ArrowUp and ArrowDown step with wrap-around, PageUp and
|
|
172
|
+
* PageDown step by more, Home and End jump to the ends, Backspace empties, ArrowLeft and ArrowRight move between segments, and A or P
|
|
173
|
+
* set the period. The group is named by `aria-label` or `aria-labelledby`; a screen reader reads each segment by its own name and value.
|
|
174
|
+
*/
|
|
175
|
+
var TimeField = ({ value, defaultValue = "", onValueChange, granularity = "minute", hourCycle: hourCycleProp, min, max, disabled = false, readOnly = false, invalid = false, name, labels: labelOverrides, className, ...rest }) => {
|
|
176
|
+
const labels = useMemo(() => ({
|
|
177
|
+
...DEFAULT_TIME_FIELD_LABELS,
|
|
178
|
+
...labelOverrides
|
|
179
|
+
}), [labelOverrides]);
|
|
180
|
+
const hourCycle = useMemo(() => hourCycleProp ?? localeHourCycle(), [hourCycleProp]);
|
|
181
|
+
const [parts, setParts] = useState(() => parseTime(value ?? defaultValue, hourCycle));
|
|
182
|
+
const [seen, setSeen] = useState(value);
|
|
183
|
+
const refSegments = useRef([]);
|
|
184
|
+
const refBuffer = useRef({
|
|
185
|
+
segment: "hour",
|
|
186
|
+
text: ""
|
|
187
|
+
});
|
|
188
|
+
const formatted = formatTime(parts, hourCycle, granularity);
|
|
189
|
+
const refReported = useRef(formatted);
|
|
190
|
+
const refParts = useRef(parts);
|
|
191
|
+
refParts.current = parts;
|
|
192
|
+
if (value !== seen) {
|
|
193
|
+
setSeen(value);
|
|
194
|
+
if (value !== void 0 && value !== formatted) {
|
|
195
|
+
setParts(parseTime(value, hourCycle));
|
|
196
|
+
refReported.current = value;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const segments = [
|
|
200
|
+
"hour",
|
|
201
|
+
"minute",
|
|
202
|
+
...granularity === "second" ? ["second"] : [],
|
|
203
|
+
...hourCycle === 12 ? ["period"] : []
|
|
204
|
+
];
|
|
205
|
+
const focusSegment = (index) => {
|
|
206
|
+
const target = refSegments.current[index];
|
|
207
|
+
if (target !== null && target !== void 0) {
|
|
208
|
+
target.focus();
|
|
209
|
+
target.select();
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
const report = (next) => {
|
|
213
|
+
const text = formatTime(next, hourCycle, granularity);
|
|
214
|
+
if (text !== refReported.current) {
|
|
215
|
+
refReported.current = text;
|
|
216
|
+
onValueChange?.(text);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
const edit = (segment, key) => {
|
|
220
|
+
const buffer = refBuffer.current.segment === segment ? refBuffer.current.text : "";
|
|
221
|
+
const result = editSegment(refParts.current, segment, key, hourCycle, buffer);
|
|
222
|
+
if (result === null) return false;
|
|
223
|
+
refBuffer.current = {
|
|
224
|
+
segment,
|
|
225
|
+
text: result.buffer
|
|
226
|
+
};
|
|
227
|
+
refParts.current = result.parts;
|
|
228
|
+
setParts(result.parts);
|
|
229
|
+
if (result.buffer === "") report(result.parts);
|
|
230
|
+
if (result.advance) focusSegment(segments.indexOf(segment) + 1);
|
|
231
|
+
return true;
|
|
232
|
+
};
|
|
233
|
+
const onKeyDown = (segment, event) => {
|
|
234
|
+
if (event.altKey || event.ctrlKey || event.metaKey) return;
|
|
235
|
+
const index = segments.indexOf(segment);
|
|
236
|
+
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
237
|
+
event.preventDefault();
|
|
238
|
+
focusSegment(index + (event.key === "ArrowRight" ? 1 : -1));
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (disabled || readOnly) return;
|
|
242
|
+
if (edit(segment, event.key)) event.preventDefault();
|
|
243
|
+
};
|
|
244
|
+
const onBlur = (segment) => {
|
|
245
|
+
const unfinished = refBuffer.current.segment === segment && refBuffer.current.text !== "";
|
|
246
|
+
refBuffer.current = {
|
|
247
|
+
segment,
|
|
248
|
+
text: ""
|
|
249
|
+
};
|
|
250
|
+
let settled = refParts.current;
|
|
251
|
+
if (segment === "hour" && hourCycle === 12 && settled.hour === 0) {
|
|
252
|
+
settled = {
|
|
253
|
+
...settled,
|
|
254
|
+
hour: null
|
|
255
|
+
};
|
|
256
|
+
refParts.current = settled;
|
|
257
|
+
setParts(settled);
|
|
258
|
+
}
|
|
259
|
+
if (unfinished) report(settled);
|
|
260
|
+
};
|
|
261
|
+
const onChange = (segment, event) => {
|
|
262
|
+
if (disabled || readOnly) return;
|
|
263
|
+
const typed = event.target.value.slice(-1);
|
|
264
|
+
edit(segment, typed);
|
|
265
|
+
};
|
|
266
|
+
const outOfRange = formatted !== "" && (min !== void 0 && formatted.slice(0, min.length) < min || max !== void 0 && formatted.slice(0, max.length) > max);
|
|
267
|
+
const flagged = invalid || outOfRange;
|
|
268
|
+
const display = (segment) => {
|
|
269
|
+
if (segment === "period") return parts.period ?? "";
|
|
270
|
+
const current = parts[segment];
|
|
271
|
+
return current === null ? "" : two(current);
|
|
272
|
+
};
|
|
273
|
+
return /* @__PURE__ */ jsxs(InputGroup, {
|
|
274
|
+
role: "group",
|
|
275
|
+
className: cn("w-fit", className),
|
|
276
|
+
...rest,
|
|
277
|
+
children: [
|
|
278
|
+
/* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(IconClock, { "aria-hidden": "true" }) }),
|
|
279
|
+
/* @__PURE__ */ jsx("div", {
|
|
280
|
+
className: "flex items-center gap-0.5 pr-2",
|
|
281
|
+
children: segments.map((segment, index) => {
|
|
282
|
+
const numeric = segment !== "period";
|
|
283
|
+
const range = numeric ? rangeOf(segment, hourCycle) : {
|
|
284
|
+
min: 0,
|
|
285
|
+
max: 1
|
|
286
|
+
};
|
|
287
|
+
const current = numeric ? parts[segment] : parts.period === null ? null : parts.period === "AM" ? 0 : 1;
|
|
288
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
289
|
+
className: "flex items-center gap-0.5",
|
|
290
|
+
children: [index > 0 && segment !== "period" && /* @__PURE__ */ jsx("span", {
|
|
291
|
+
"aria-hidden": "true",
|
|
292
|
+
className: "text-muted-foreground",
|
|
293
|
+
children: ":"
|
|
294
|
+
}), /* @__PURE__ */ jsx("input", {
|
|
295
|
+
ref: (node) => {
|
|
296
|
+
refSegments.current[index] = node;
|
|
297
|
+
},
|
|
298
|
+
"data-slot": "input-group-control",
|
|
299
|
+
"data-segment": segment,
|
|
300
|
+
role: "spinbutton",
|
|
301
|
+
inputMode: numeric ? "numeric" : "text",
|
|
302
|
+
autoComplete: "off",
|
|
303
|
+
autoCorrect: "off",
|
|
304
|
+
spellCheck: false,
|
|
305
|
+
value: display(segment),
|
|
306
|
+
placeholder: SEGMENT_PLACEHOLDER[segment],
|
|
307
|
+
disabled,
|
|
308
|
+
readOnly,
|
|
309
|
+
"aria-label": labels[segment],
|
|
310
|
+
"aria-readonly": readOnly || void 0,
|
|
311
|
+
"aria-invalid": flagged || void 0,
|
|
312
|
+
"aria-valuemin": range.min,
|
|
313
|
+
"aria-valuemax": range.max,
|
|
314
|
+
"aria-valuenow": current ?? void 0,
|
|
315
|
+
"aria-valuetext": current === null ? labels.empty : segment === "period" ? parts.period ?? labels.empty : two(current),
|
|
316
|
+
className: cn(SEGMENT_CLASS, segment === "period" ? "w-7" : "w-5"),
|
|
317
|
+
onKeyDown: (event) => onKeyDown(segment, event),
|
|
318
|
+
onChange: (event) => onChange(segment, event),
|
|
319
|
+
onFocus: (event) => event.currentTarget.select(),
|
|
320
|
+
onBlur: () => onBlur(segment)
|
|
321
|
+
})]
|
|
322
|
+
}, segment);
|
|
323
|
+
})
|
|
324
|
+
}),
|
|
325
|
+
name !== void 0 && /* @__PURE__ */ jsx("input", {
|
|
326
|
+
type: "hidden",
|
|
327
|
+
name,
|
|
328
|
+
value: formatted,
|
|
329
|
+
disabled
|
|
330
|
+
})
|
|
331
|
+
]
|
|
332
|
+
});
|
|
333
|
+
};
|
|
334
|
+
//#endregion
|
|
335
|
+
export { DEFAULT_TIME_FIELD_LABELS, EMPTY_TIME, TimeField, editSegment, formatTime, localeHourCycle, parseTime, rangeOf, stepValue, typeDigit };
|
|
336
|
+
|
|
337
|
+
//# sourceMappingURL=time-field.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time-field.js","names":[],"sources":["../../../../../../../ui/src/components/edyn/time-field/time-field.tsx"],"sourcesContent":["import { InputGroup, InputGroupAddon } from '@edyn/ui/components/ui/input-group';\nimport { cn } from '@edyn/ui/lib/utils';\nimport { IconClock } from '@tabler/icons-react';\nimport { type ChangeEvent, type ComponentPropsWithoutRef, type KeyboardEvent, useMemo, useRef, useState } from 'react';\n\nexport type TTimeFieldGranularity = 'minute' | 'second';\n\nexport type TTimeFieldHourCycle = 12 | 24;\n\nexport type TTimeFieldSegment = 'hour' | 'minute' | 'second' | 'period';\n\nexport type TTimeFieldPeriod = 'AM' | 'PM';\n\n/** The segments as they are shown: the hour in the field's own cycle (0 to 23, or 1 to 12 beside a period), each empty until entered. */\nexport interface ITimeParts {\n hour: number | null;\n minute: number | null;\n second: number | null;\n period: TTimeFieldPeriod | null;\n}\n\nexport const EMPTY_TIME: ITimeParts = { hour: null, minute: null, second: null, period: null };\n\nexport interface ITimeFieldLabels {\n hour: string;\n minute: string;\n second: string;\n /** The AM/PM segment. */\n period: string;\n /** Read for a segment with nothing in it. */\n empty: string;\n}\n\nexport const DEFAULT_TIME_FIELD_LABELS: ITimeFieldLabels = {\n hour: 'Hours',\n minute: 'Minutes',\n second: 'Seconds',\n period: 'AM or PM',\n empty: 'Empty',\n};\n\n/** What an empty segment shows. Letters, as a DatePicker's pattern is, never a dash. */\nconst SEGMENT_PLACEHOLDER: Record<TTimeFieldSegment, string> = { hour: 'HH', minute: 'MM', second: 'SS', period: 'AM' };\n\nconst TIME = /^(\\d{2}):(\\d{2})(?::(\\d{2}))?$/;\n\nconst two = (value: number): string => String(value).padStart(2, '0');\n\n/** 12 where the reader's locale writes AM and PM, 24 where it does not. */\nexport const localeHourCycle = (): TTimeFieldHourCycle =>\n new Intl.DateTimeFormat(undefined, { hour: 'numeric' }).resolvedOptions().hour12 ? 12 : 24;\n\n/** `HH:mm` or `HH:mm:ss` (24-hour, as `<input type=\"time\">` writes it) to the segments; anything else is no time. */\nexport const parseTime = (value: string, hourCycle: TTimeFieldHourCycle): ITimeParts => {\n const match = TIME.exec(value);\n if (match === null) {\n return EMPTY_TIME;\n }\n const hour24 = Number(match[1]);\n const minute = Number(match[2]);\n const second = match[3] === undefined ? 0 : Number(match[3]);\n if (hour24 > 23 || minute > 59 || second > 59) {\n return EMPTY_TIME;\n }\n if (hourCycle === 24) {\n return { hour: hour24, minute, second, period: null };\n }\n return { hour: hour24 % 12 === 0 ? 12 : hour24 % 12, minute, second, period: hour24 >= 12 ? 'PM' : 'AM' };\n};\n\n/** The segments to `HH:mm` or `HH:mm:ss`, or '' until every segment the field shows is in. */\nexport const formatTime = (parts: ITimeParts, hourCycle: TTimeFieldHourCycle, granularity: TTimeFieldGranularity): string => {\n const { hour, minute, second, period } = parts;\n if (hour === null || minute === null || (granularity === 'second' && second === null)) {\n return '';\n }\n let hour24 = hour;\n if (hourCycle === 12) {\n // 0 is only ever a first digit still waiting for its second.\n if (period === null || hour === 0) {\n return '';\n }\n hour24 = (hour % 12) + (period === 'PM' ? 12 : 0);\n }\n return granularity === 'second' ? `${two(hour24)}:${two(minute)}:${two(second ?? 0)}` : `${two(hour24)}:${two(minute)}`;\n};\n\nexport interface IRange {\n min: number;\n max: number;\n}\n\nexport const rangeOf = (segment: Exclude<TTimeFieldSegment, 'period'>, hourCycle: TTimeFieldHourCycle): IRange => {\n if (segment === 'hour') {\n return hourCycle === 12 ? { min: 1, max: 12 } : { min: 0, max: 23 };\n }\n return { min: 0, max: 59 };\n};\n\n/** One step up or down inside a range, wrapping at the ends. A segment with nothing in it starts at the end the step is heading away from. */\nexport const stepValue = (current: number | null, delta: number, { min, max }: IRange): number => {\n if (current === null) {\n return delta > 0 ? min : max;\n }\n const size = max - min + 1;\n return ((((current - min + delta) % size) + size) % size) + min;\n};\n\n/**\n * Types a digit into a segment. The second digit joins the first when it makes a number the segment can hold; otherwise it starts\n * over. The segment is done, and focus moves on, at two digits or as soon as no second digit could fit (a 3 in the hours, a 6 in the\n * minutes).\n */\nexport const typeDigit = (buffer: string, digit: string, { min, max }: IRange): { value: number; buffer: string; done: boolean } => {\n let text = buffer + digit;\n if (text.length > 2 || Number(text) > max) {\n text = digit;\n }\n const value = Number(text);\n const done = text.length === 2 || value * 10 > max;\n return { value: done && value < min ? min : value, buffer: done ? '' : text, done };\n};\n\nconst PAGE_STEP: Record<Exclude<TTimeFieldSegment, 'period'>, number> = { hour: 3, minute: 10, second: 10 };\n\nexport interface IEdit {\n parts: ITimeParts;\n /** The digits typed so far into this segment and not yet complete. */\n buffer: string;\n /** Move to the next segment: this one is finished. */\n advance: boolean;\n}\n\nconst withSegment = (parts: ITimeParts, segment: Exclude<TTimeFieldSegment, 'period'>, value: number | null): ITimeParts => ({\n ...parts,\n [segment]: value,\n});\n\n/** What a key does to a segment, or null when the key is not one the segment handles (Tab, a letter in the hours...). */\nexport const editSegment = (\n parts: ITimeParts,\n segment: TTimeFieldSegment,\n key: string,\n hourCycle: TTimeFieldHourCycle,\n buffer: string,\n): IEdit | null => {\n if (segment === 'period') {\n const current = parts.period;\n const set = (period: TTimeFieldPeriod | null): IEdit => ({ parts: { ...parts, period }, buffer: '', advance: false });\n switch (key) {\n case 'a':\n case 'A':\n return { ...set('AM'), advance: true };\n case 'p':\n case 'P':\n return { ...set('PM'), advance: true };\n case 'ArrowUp':\n case 'ArrowDown':\n return set(current === null ? (key === 'ArrowUp' ? 'AM' : 'PM') : current === 'AM' ? 'PM' : 'AM');\n case 'Home':\n return set('AM');\n case 'End':\n return set('PM');\n case 'Backspace':\n case 'Delete':\n return set(null);\n default:\n return null;\n }\n }\n\n const range = rangeOf(segment, hourCycle);\n const current = parts[segment];\n const set = (value: number | null, advance = false): IEdit => ({ parts: withSegment(parts, segment, value), buffer: '', advance });\n\n if (/^[0-9]$/.test(key)) {\n const typed = typeDigit(buffer, key, range);\n return { parts: withSegment(parts, segment, typed.value), buffer: typed.buffer, advance: typed.done };\n }\n switch (key) {\n case 'ArrowUp':\n return set(stepValue(current, 1, range));\n case 'ArrowDown':\n return set(stepValue(current, -1, range));\n case 'PageUp':\n return set(stepValue(current, PAGE_STEP[segment], range));\n case 'PageDown':\n return set(stepValue(current, -PAGE_STEP[segment], range));\n case 'Home':\n return set(range.min);\n case 'End':\n return set(range.max);\n case 'Backspace':\n case 'Delete':\n return set(null);\n default:\n return null;\n }\n};\n\nexport interface ITimeFieldProps extends Omit<ComponentPropsWithoutRef<'div'>, 'defaultValue' | 'onChange' | 'children' | 'role'> {\n /** The time as `HH:mm` or `HH:mm:ss`, 24-hour whatever the field shows, as `<input type=\"time\">` writes it. '' is no time. */\n value?: string;\n defaultValue?: string;\n /** Called with the time as soon as every segment is in, and with '' when one of a full time is cleared. */\n onValueChange?: (value: string) => void;\n /** `second` adds a seconds segment and a `HH:mm:ss` value. */\n granularity?: TTimeFieldGranularity;\n /** 12 shows an AM/PM segment, 24 does not. The default is what the reader's locale writes. */\n hourCycle?: TTimeFieldHourCycle;\n /** The earliest and the latest time, `HH:mm`. A time outside them is marked invalid; it is not refused. */\n min?: string;\n max?: string;\n disabled?: boolean;\n /** Shown, focusable and readable, not changeable. */\n readOnly?: boolean;\n invalid?: boolean;\n /** Submits the time with a form, under this name, as `HH:mm` or `HH:mm:ss`. */\n name?: string;\n labels?: Partial<ITimeFieldLabels>;\n}\n\nconst SEGMENT_CLASS =\n 'h-6 rounded-sm bg-transparent text-center text-sm tabular-nums caret-transparent outline-none selection:bg-transparent placeholder:text-muted-foreground focus:bg-foreground/10 disabled:cursor-not-allowed';\n\n/**\n * A time of day typed in segments, in the kit's field: hours, minutes, optional seconds, and AM/PM where the reader's locale uses it.\n * It exists so an app does not fall back to `<input type=\"time\">`, whose look differs between browsers and from the rest of the kit.\n *\n * Each segment is a spinbutton: type digits (the focus moves on by itself), ArrowUp and ArrowDown step with wrap-around, PageUp and\n * PageDown step by more, Home and End jump to the ends, Backspace empties, ArrowLeft and ArrowRight move between segments, and A or P\n * set the period. The group is named by `aria-label` or `aria-labelledby`; a screen reader reads each segment by its own name and value.\n */\nexport const TimeField = ({\n value,\n defaultValue = '',\n onValueChange,\n granularity = 'minute',\n hourCycle: hourCycleProp,\n min,\n max,\n disabled = false,\n readOnly = false,\n invalid = false,\n name,\n labels: labelOverrides,\n className,\n ...rest\n}: ITimeFieldProps) => {\n const labels = useMemo(() => ({ ...DEFAULT_TIME_FIELD_LABELS, ...labelOverrides }), [labelOverrides]);\n const hourCycle = useMemo(() => hourCycleProp ?? localeHourCycle(), [hourCycleProp]);\n const [parts, setParts] = useState<ITimeParts>(() => parseTime(value ?? defaultValue, hourCycle));\n const [seen, setSeen] = useState(value);\n const refSegments = useRef<Array<HTMLInputElement | null>>([]);\n const refBuffer = useRef<{ segment: TTimeFieldSegment; text: string }>({ segment: 'hour', text: '' });\n const formatted = formatTime(parts, hourCycle, granularity);\n // What the parent was last told, and the segments as the last key left them (state is a render behind inside one event).\n const refReported = useRef(formatted);\n const refParts = useRef(parts);\n refParts.current = parts;\n // A time handed in from outside replaces what is shown, unless it is the very time that is shown: clearing one segment of a full\n // time reports '', and taking that back as a new value would wipe the segments still being edited.\n if (value !== seen) {\n setSeen(value);\n if (value !== undefined && value !== formatted) {\n setParts(parseTime(value, hourCycle));\n refReported.current = value;\n }\n }\n\n const segments: TTimeFieldSegment[] = [\n 'hour',\n 'minute',\n ...(granularity === 'second' ? (['second'] as const) : []),\n ...(hourCycle === 12 ? (['period'] as const) : []),\n ];\n\n const focusSegment = (index: number): void => {\n const target = refSegments.current[index];\n if (target !== null && target !== undefined) {\n target.focus();\n target.select();\n }\n };\n\n const report = (next: ITimeParts): void => {\n const text = formatTime(next, hourCycle, granularity);\n if (text !== refReported.current) {\n refReported.current = text;\n onValueChange?.(text);\n }\n };\n\n const edit = (segment: TTimeFieldSegment, key: string): boolean => {\n const buffer = refBuffer.current.segment === segment ? refBuffer.current.text : '';\n const result = editSegment(refParts.current, segment, key, hourCycle, buffer);\n if (result === null) {\n return false;\n }\n refBuffer.current = { segment, text: result.buffer };\n refParts.current = result.parts;\n setParts(result.parts);\n // A segment still waiting for its second digit is not a time yet worth reporting (a 3 may become 30); it is reported when it is\n // done, or when the focus leaves it.\n if (result.buffer === '') {\n report(result.parts);\n }\n if (result.advance) {\n focusSegment(segments.indexOf(segment) + 1);\n }\n return true;\n };\n\n const onKeyDown = (segment: TTimeFieldSegment, event: KeyboardEvent<HTMLInputElement>): void => {\n if (event.altKey || event.ctrlKey || event.metaKey) {\n return;\n }\n const index = segments.indexOf(segment);\n if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {\n event.preventDefault();\n focusSegment(index + (event.key === 'ArrowRight' ? 1 : -1));\n return;\n }\n if (disabled || readOnly) {\n return;\n }\n if (edit(segment, event.key)) {\n event.preventDefault();\n }\n };\n\n // Leaving a segment ends what was being typed into it: coming back and typing a 2 must not make 12 of an old 1. A 0 left alone in a\n // 12-hour hour is the start of a number that never came, so it is emptied.\n const onBlur = (segment: TTimeFieldSegment): void => {\n const unfinished = refBuffer.current.segment === segment && refBuffer.current.text !== '';\n refBuffer.current = { segment, text: '' };\n let settled = refParts.current;\n if (segment === 'hour' && hourCycle === 12 && settled.hour === 0) {\n settled = { ...settled, hour: null };\n refParts.current = settled;\n setParts(settled);\n }\n if (unfinished) {\n report(settled);\n }\n };\n\n // A phone's keyboard does not send key events a page can use; what it types arrives as a change to the input.\n const onChange = (segment: TTimeFieldSegment, event: ChangeEvent<HTMLInputElement>): void => {\n if (disabled || readOnly) {\n return;\n }\n const typed = event.target.value.slice(-1);\n edit(segment, typed);\n };\n\n const outOfRange =\n formatted !== '' && ((min !== undefined && formatted.slice(0, min.length) < min) || (max !== undefined && formatted.slice(0, max.length) > max));\n const flagged = invalid || outOfRange;\n\n const display = (segment: TTimeFieldSegment): string => {\n if (segment === 'period') {\n return parts.period ?? '';\n }\n const current = parts[segment];\n return current === null ? '' : two(current);\n };\n\n return (\n <InputGroup role=\"group\" className={cn('w-fit', className)} {...rest}>\n <InputGroupAddon>\n <IconClock aria-hidden=\"true\" />\n </InputGroupAddon>\n <div className=\"flex items-center gap-0.5 pr-2\">\n {segments.map((segment, index) => {\n const numeric = segment !== 'period';\n const range = numeric ? rangeOf(segment, hourCycle) : { min: 0, max: 1 };\n const current = numeric ? parts[segment] : parts.period === null ? null : parts.period === 'AM' ? 0 : 1;\n return (\n <span key={segment} className=\"flex items-center gap-0.5\">\n {index > 0 && segment !== 'period' && (\n <span aria-hidden=\"true\" className=\"text-muted-foreground\">\n :\n </span>\n )}\n <input\n ref={(node) => {\n refSegments.current[index] = node;\n }}\n data-slot=\"input-group-control\"\n data-segment={segment}\n role=\"spinbutton\"\n inputMode={numeric ? 'numeric' : 'text'}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n value={display(segment)}\n placeholder={SEGMENT_PLACEHOLDER[segment]}\n disabled={disabled}\n readOnly={readOnly}\n aria-label={labels[segment]}\n aria-readonly={readOnly || undefined}\n aria-invalid={flagged || undefined}\n aria-valuemin={range.min}\n aria-valuemax={range.max}\n aria-valuenow={current ?? undefined}\n aria-valuetext={current === null ? labels.empty : segment === 'period' ? (parts.period ?? labels.empty) : two(current)}\n className={cn(SEGMENT_CLASS, segment === 'period' ? 'w-7' : 'w-5')}\n onKeyDown={(event) => onKeyDown(segment, event)}\n onChange={(event) => onChange(segment, event)}\n onFocus={(event) => event.currentTarget.select()}\n onBlur={() => onBlur(segment)}\n />\n </span>\n );\n })}\n </div>\n {name !== undefined && <input type=\"hidden\" name={name} value={formatted} disabled={disabled} />}\n </InputGroup>\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TimeField: the arithmetic of a time typed in segments, and the keyboard on a mounted field.
|
|
3
|
+
*
|
|
4
|
+
* PATH TAKEN: parsing, formatting, stepping and the typing rules are plain functions and run in happy-dom, and so does a mounted field
|
|
5
|
+
* driven by key events, which is where the focus moving on, the value reported and the roles are checked. How it looks in the kit's
|
|
6
|
+
* field, and the browser's own handling of focus, is for e2e/a11y.spec.ts and the visual cells.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TCssLength } from '../../../lib/utils';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
export interface IVideoPlayerProps {
|
|
3
|
+
export interface IVideoPlayerProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children' | 'className' | 'title' | 'onPlay' | 'onPause' | 'onEnded' | 'onTimeUpdate'> {
|
|
4
4
|
/** Video source URL. */
|
|
5
5
|
src?: string;
|
|
6
6
|
/** Still frame shown before playback starts. */
|
|
@@ -52,4 +52,4 @@ export interface IVideoPlayerProps {
|
|
|
52
52
|
* both themes. Video is dark, so the letterbox and controls must stay dark and
|
|
53
53
|
* light-on-dark; this re-scopes existing tokens rather than hardcoding a colour.
|
|
54
54
|
*/
|
|
55
|
-
export declare const VideoPlayer: ({ src, poster, title, description, muted, loop, disabled, width, height, ratio, className, "aria-label": ariaLabel, onPlay, onPause, onEnded, onTimeUpdate, }: IVideoPlayerProps) => React.JSX.Element;
|
|
55
|
+
export declare const VideoPlayer: ({ src, poster, title, description, muted, loop, disabled, width, height, ratio, className, "aria-label": ariaLabel, style, onPlay, onPause, onEnded, onTimeUpdate, ...props }: IVideoPlayerProps) => React.JSX.Element;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { cn, cssLength } from "../../../lib/utils.js";
|
|
2
|
+
import { Button } from "../../ui/button/button.js";
|
|
3
|
+
import { Slider } from "../../ui/slider/slider.js";
|
|
4
|
+
import { formatMediaTime, useMediaPlayer } from "../../../hooks/use-media-player.js";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { IconMaximize, IconPlayerPauseFilled, IconPlayerPlayFilled, IconVolume, IconVolumeOff } from "@tabler/icons-react";
|
|
8
|
+
//#region ../ui/src/components/edyn/video-player/video-player.tsx
|
|
9
|
+
/**
|
|
10
|
+
* Media surface with an overlaid control bar: title and description, elapsed and
|
|
11
|
+
* total time, a seekable scrubber, play/pause, volume, and fullscreen.
|
|
12
|
+
*
|
|
13
|
+
* The root carries the `dark` class so its tokens resolve to the dark palette in
|
|
14
|
+
* both themes. Video is dark, so the letterbox and controls must stay dark and
|
|
15
|
+
* light-on-dark; this re-scopes existing tokens rather than hardcoding a colour.
|
|
16
|
+
*/
|
|
17
|
+
var VideoPlayer = ({ src, poster, title, description, muted = false, loop = false, disabled = false, width, height, ratio = "auto", className, "aria-label": ariaLabel = "Video player", style, onPlay, onPause, onEnded, onTimeUpdate, ...props }) => {
|
|
18
|
+
const { refMedia, playing, currentTime, duration, muted: isMuted, toggle, seek, toggleMute } = useMediaPlayer({
|
|
19
|
+
onPlay,
|
|
20
|
+
onPause,
|
|
21
|
+
onEnded,
|
|
22
|
+
onTimeUpdate
|
|
23
|
+
});
|
|
24
|
+
const refContainer = React.useRef(null);
|
|
25
|
+
const PlaybackIcon = playing ? IconPlayerPauseFilled : IconPlayerPlayFilled;
|
|
26
|
+
const VolumeIcon = isMuted ? IconVolumeOff : IconVolume;
|
|
27
|
+
const isSizedBox = height != null || ratio !== "auto";
|
|
28
|
+
const requestFullscreen = () => {
|
|
29
|
+
const container = refContainer.current;
|
|
30
|
+
if (!container) return;
|
|
31
|
+
if (document.fullscreenElement) {
|
|
32
|
+
document.exitFullscreen().catch(() => void 0);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
container.requestFullscreen?.().catch(() => void 0);
|
|
36
|
+
};
|
|
37
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
38
|
+
ref: refContainer,
|
|
39
|
+
"data-slot": "video-player",
|
|
40
|
+
...props,
|
|
41
|
+
"data-playing": playing || void 0,
|
|
42
|
+
style: {
|
|
43
|
+
width: cssLength(width),
|
|
44
|
+
height: cssLength(height),
|
|
45
|
+
aspectRatio: height == null && ratio !== "auto" ? ratio : void 0,
|
|
46
|
+
...style
|
|
47
|
+
},
|
|
48
|
+
className: cn("dark relative isolate w-full overflow-hidden rounded-lg bg-background", className),
|
|
49
|
+
children: [/* @__PURE__ */ jsx("video", {
|
|
50
|
+
ref: refMedia,
|
|
51
|
+
src,
|
|
52
|
+
poster,
|
|
53
|
+
muted,
|
|
54
|
+
loop,
|
|
55
|
+
playsInline: true,
|
|
56
|
+
preload: "metadata",
|
|
57
|
+
"aria-label": ariaLabel,
|
|
58
|
+
className: cn("w-full bg-background", isSizedBox ? "h-full object-contain" : "h-auto")
|
|
59
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
60
|
+
className: "pointer-events-none absolute inset-x-0 bottom-0 flex flex-col gap-0.5 bg-gradient-to-t from-background via-background/75 to-transparent px-3 pt-12 pb-2 text-foreground",
|
|
61
|
+
children: [
|
|
62
|
+
/* @__PURE__ */ jsxs("div", {
|
|
63
|
+
className: "pointer-events-auto flex items-end justify-between gap-4",
|
|
64
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
65
|
+
className: "min-w-0",
|
|
66
|
+
children: [title ? /* @__PURE__ */ jsx("p", {
|
|
67
|
+
className: "truncate text-sm font-medium text-foreground",
|
|
68
|
+
children: title
|
|
69
|
+
}) : null, description ? /* @__PURE__ */ jsx("p", {
|
|
70
|
+
className: "truncate text-xs text-foreground/70",
|
|
71
|
+
children: description
|
|
72
|
+
}) : null]
|
|
73
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
74
|
+
className: "shrink-0 text-xs tabular-nums text-foreground/70",
|
|
75
|
+
children: [
|
|
76
|
+
formatMediaTime(currentTime),
|
|
77
|
+
" / ",
|
|
78
|
+
formatMediaTime(duration)
|
|
79
|
+
]
|
|
80
|
+
})]
|
|
81
|
+
}),
|
|
82
|
+
/* @__PURE__ */ jsx(Slider, {
|
|
83
|
+
className: "pointer-events-auto [&_[data-slot=slider-control]]:py-1.5 [&_[data-slot=slider-thumb]]:size-3 [&_[data-slot=slider-track]]:h-1",
|
|
84
|
+
value: Math.min(currentTime, duration || 0),
|
|
85
|
+
min: 0,
|
|
86
|
+
max: duration || 0,
|
|
87
|
+
step: 1,
|
|
88
|
+
disabled: disabled || duration === 0,
|
|
89
|
+
"aria-label": "Seek",
|
|
90
|
+
onValueChange: (next) => {
|
|
91
|
+
seek(next);
|
|
92
|
+
}
|
|
93
|
+
}),
|
|
94
|
+
/* @__PURE__ */ jsxs("div", {
|
|
95
|
+
className: "pointer-events-auto flex items-center justify-between",
|
|
96
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
97
|
+
className: "flex items-center gap-1",
|
|
98
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
99
|
+
type: "button",
|
|
100
|
+
variant: "ghost",
|
|
101
|
+
size: "icon",
|
|
102
|
+
disabled,
|
|
103
|
+
"aria-label": playing ? "Pause" : "Play",
|
|
104
|
+
onClick: toggle,
|
|
105
|
+
children: /* @__PURE__ */ jsx(PlaybackIcon, {})
|
|
106
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
107
|
+
type: "button",
|
|
108
|
+
variant: "ghost",
|
|
109
|
+
size: "icon",
|
|
110
|
+
disabled,
|
|
111
|
+
"aria-label": isMuted ? "Unmute" : "Mute",
|
|
112
|
+
onClick: toggleMute,
|
|
113
|
+
children: /* @__PURE__ */ jsx(VolumeIcon, {})
|
|
114
|
+
})]
|
|
115
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
116
|
+
type: "button",
|
|
117
|
+
variant: "ghost",
|
|
118
|
+
size: "icon",
|
|
119
|
+
disabled,
|
|
120
|
+
"aria-label": "Fullscreen",
|
|
121
|
+
onClick: requestFullscreen,
|
|
122
|
+
children: /* @__PURE__ */ jsx(IconMaximize, {})
|
|
123
|
+
})]
|
|
124
|
+
})
|
|
125
|
+
]
|
|
126
|
+
})]
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
//#endregion
|
|
130
|
+
export { VideoPlayer };
|
|
131
|
+
|
|
132
|
+
//# sourceMappingURL=video-player.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"video-player.js","names":[],"sources":["../../../../../../../ui/src/components/edyn/video-player/video-player.tsx"],"sourcesContent":["import { Button } from '@edyn/ui/components/ui/button';\nimport { Slider } from '@edyn/ui/components/ui/slider';\nimport { formatMediaTime, useMediaPlayer } from '@edyn/ui/hooks/use-media-player';\nimport type { TCssLength } from '@edyn/ui/lib/utils';\nimport { cn, cssLength } from '@edyn/ui/lib/utils';\nimport { IconMaximize, IconPlayerPauseFilled, IconPlayerPlayFilled, IconVolume, IconVolumeOff } from '@tabler/icons-react';\nimport * as React from 'react';\n\nexport interface IVideoPlayerProps\n extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children' | 'className' | 'title' | 'onPlay' | 'onPause' | 'onEnded' | 'onTimeUpdate'> {\n /** Video source URL. */\n src?: string;\n /** Still frame shown before playback starts. */\n poster?: string;\n /** Primary label rendered in the control overlay. */\n title?: string;\n /** Secondary label rendered under the title. */\n description?: string;\n /** Start muted. Required by browsers for unattended autoplay. */\n muted?: boolean;\n /** Loop playback when the video ends. */\n loop?: boolean;\n /** Disable every control without hiding the player. */\n disabled?: boolean;\n /**\n * Box width. A number is px, a string is any CSS length (`'100%'`, `'34rem'`).\n * Omitted, the player fills the width it is given.\n */\n width?: TCssLength;\n /**\n * Box height. A number is px, a string is any CSS length. Omitted, the height\n * comes from `ratio`. Setting this letterboxes a source that does not match.\n */\n height?: TCssLength;\n /**\n * Aspect ratio of the media box, as a CSS `aspect-ratio` value (`'16/9'`).\n *\n * Defaults to `auto`, so the height follows the source's own dimensions and a\n * portrait or 4:3 clip is shown whole rather than letterboxed. Pair `auto`\n * with a `poster`: a `<video>` reports a 300x150 intrinsic size until metadata\n * arrives, and the poster's dimensions stand in for it, which is what stops\n * the box from resizing when the first frame lands.\n *\n * Ignored when `height` is set.\n */\n ratio?: string;\n className?: string;\n 'aria-label'?: string;\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onTimeUpdate?: (currentTime: number, duration: number) => void;\n}\n\n/**\n * Media surface with an overlaid control bar: title and description, elapsed and\n * total time, a seekable scrubber, play/pause, volume, and fullscreen.\n *\n * The root carries the `dark` class so its tokens resolve to the dark palette in\n * both themes. Video is dark, so the letterbox and controls must stay dark and\n * light-on-dark; this re-scopes existing tokens rather than hardcoding a colour.\n */\nexport const VideoPlayer = ({\n src,\n poster,\n title,\n description,\n muted = false,\n loop = false,\n disabled = false,\n width,\n height,\n ratio = 'auto',\n className,\n 'aria-label': ariaLabel = 'Video player',\n style,\n onPlay,\n onPause,\n onEnded,\n onTimeUpdate,\n ...props\n}: IVideoPlayerProps) => {\n const {\n refMedia,\n playing,\n currentTime,\n duration,\n muted: isMuted,\n toggle,\n seek,\n toggleMute,\n } = useMediaPlayer<HTMLVideoElement>({ onPlay, onPause, onEnded, onTimeUpdate });\n const refContainer = React.useRef<HTMLDivElement>(null);\n\n const PlaybackIcon = playing ? IconPlayerPauseFilled : IconPlayerPlayFilled;\n const VolumeIcon = isMuted ? IconVolumeOff : IconVolume;\n\n // An explicit height wins over the ratio, and either one turns the root into\n // the sized box with the media fitted inside it. Without both, the media is\n // the only thing in flow and the root takes its height.\n const isSizedBox = height != null || ratio !== 'auto';\n\n const requestFullscreen = () => {\n const container = refContainer.current;\n if (!container) {\n return;\n }\n if (document.fullscreenElement) {\n void document.exitFullscreen().catch(() => undefined);\n return;\n }\n void container.requestFullscreen?.().catch(() => undefined);\n };\n\n return (\n <div\n ref={refContainer}\n data-slot=\"video-player\"\n {...props}\n data-playing={playing || undefined}\n style={{\n width: cssLength(width),\n height: cssLength(height),\n aspectRatio: height == null && ratio !== 'auto' ? ratio : undefined,\n ...style,\n }}\n className={cn('dark relative isolate w-full overflow-hidden rounded-lg bg-background', className)}\n >\n <video\n ref={refMedia}\n src={src}\n poster={poster}\n muted={muted}\n loop={loop}\n playsInline\n preload=\"metadata\"\n aria-label={ariaLabel}\n className={cn('w-full bg-background', isSizedBox ? 'h-full object-contain' : 'h-auto')}\n />\n\n {/* The scrim must carry the controls over arbitrarily bright footage, so it ramps to a solid base rather than fading to 90%. */}\n {/* `text-foreground` is explicit: the `dark` class re-scopes the token VALUES, but `color` itself\n still inherits from the surrounding page, so without this the controls stay page-dark on video. */}\n <div className=\"pointer-events-none absolute inset-x-0 bottom-0 flex flex-col gap-0.5 bg-gradient-to-t from-background via-background/75 to-transparent px-3 pt-12 pb-2 text-foreground\">\n <div className=\"pointer-events-auto flex items-end justify-between gap-4\">\n <div className=\"min-w-0\">\n {title ? <p className=\"truncate text-sm font-medium text-foreground\">{title}</p> : null}\n {description ? <p className=\"truncate text-xs text-foreground/70\">{description}</p> : null}\n </div>\n <span className=\"shrink-0 text-xs tabular-nums text-foreground/70\">\n {formatMediaTime(currentTime)} / {formatMediaTime(duration)}\n </span>\n </div>\n\n {/* Scope the form-sized Slider down to a scrubber: thinner track, smaller thumb, less vertical padding. */}\n <Slider\n className=\"pointer-events-auto [&_[data-slot=slider-control]]:py-1.5 [&_[data-slot=slider-thumb]]:size-3 [&_[data-slot=slider-track]]:h-1\"\n value={Math.min(currentTime, duration || 0)}\n min={0}\n max={duration || 0}\n step={1}\n disabled={disabled || duration === 0}\n aria-label=\"Seek\"\n onValueChange={(next) => {\n seek(next);\n }}\n />\n\n <div className=\"pointer-events-auto flex items-center justify-between\">\n <div className=\"flex items-center gap-1\">\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" disabled={disabled} aria-label={playing ? 'Pause' : 'Play'} onClick={toggle}>\n <PlaybackIcon />\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" disabled={disabled} aria-label={isMuted ? 'Unmute' : 'Mute'} onClick={toggleMute}>\n <VolumeIcon />\n </Button>\n </div>\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" disabled={disabled} aria-label=\"Fullscreen\" onClick={requestFullscreen}>\n <IconMaximize />\n </Button>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;AA8DA,IAAa,eAAe,EAC1B,KACA,QACA,OACA,aACA,QAAQ,OACR,OAAO,OACP,WAAW,OACX,OACA,QACA,QAAQ,QACR,WACA,cAAc,YAAY,gBAC1B,OACA,QACA,SACA,SACA,cACA,GAAG,YACoB;CACvB,MAAM,EACJ,UACA,SACA,aACA,UACA,OAAO,SACP,QACA,MACA,eACE,eAAiC;EAAE;EAAQ;EAAS;EAAS;CAAa,CAAC;CAC/E,MAAM,eAAe,MAAM,OAAuB,IAAI;CAEtD,MAAM,eAAe,UAAU,wBAAwB;CACvD,MAAM,aAAa,UAAU,gBAAgB;CAK7C,MAAM,aAAa,UAAU,QAAQ,UAAU;CAE/C,MAAM,0BAA0B;EAC9B,MAAM,YAAY,aAAa;EAC/B,IAAI,CAAC,WACH;EAEF,IAAI,SAAS,mBAAmB;GAC9B,SAAc,eAAe,CAAC,CAAC,YAAY,KAAA,CAAS;GACpD;EACF;EACA,UAAe,oBAAoB,CAAC,CAAC,YAAY,KAAA,CAAS;CAC5D;CAEA,OACE,qBAAC,OAAD;EACE,KAAK;EACL,aAAU;EACV,GAAI;EACJ,gBAAc,WAAW,KAAA;EACzB,OAAO;GACL,OAAO,UAAU,KAAK;GACtB,QAAQ,UAAU,MAAM;GACxB,aAAa,UAAU,QAAQ,UAAU,SAAS,QAAQ,KAAA;GAC1D,GAAG;EACL;EACA,WAAW,GAAG,yEAAyE,SAAS;EAXlG,UAAA,CAaE,oBAAC,SAAD;GACE,KAAK;GACA;GACG;GACD;GACD;GACN,aAAA;GACA,SAAQ;GACR,cAAY;GACZ,WAAW,GAAG,wBAAwB,aAAa,0BAA0B,QAAQ;EACtF,CAAA,GAKD,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,qBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACG,QAAQ,oBAAC,KAAD;OAAG,WAAU;OAAgD,UAAA;MAAS,CAAA,IAAI,MAClF,cAAc,oBAAC,KAAD;OAAG,WAAU;OAAuC,UAAA;MAAe,CAAA,IAAI,IACnF;KACL,CAAA,GAAA,qBAAC,QAAD;MAAM,WAAU;MAAhB,UAAA;OACG,gBAAgB,WAAW;OAAE;OAAI,gBAAgB,QAAQ;MACtD;KACH,CAAA,CAAA;;IAGL,oBAAC,QAAD;KACE,WAAU;KACV,OAAO,KAAK,IAAI,aAAa,YAAY,CAAC;KAC1C,KAAK;KACL,KAAK,YAAY;KACjB,MAAM;KACN,UAAU,YAAY,aAAa;KACnC,cAAW;KACX,gBAAgB,SAAS;MACvB,KAAK,IAAI;KACX;IACD,CAAA;IAED,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,qBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,oBAAC,QAAD;OAAQ,MAAK;OAAS,SAAQ;OAAQ,MAAK;OAAiB;OAAU,cAAY,UAAU,UAAU;OAAQ,SAAS;OACrH,UAAA,oBAAC,cAAD,CAAe,CAAA;MACT,CAAA,GACR,oBAAC,QAAD;OAAQ,MAAK;OAAS,SAAQ;OAAQ,MAAK;OAAiB;OAAU,cAAY,UAAU,WAAW;OAAQ,SAAS;OACtH,UAAA,oBAAC,YAAD,CAAa,CAAA;MACP,CAAA,CACL;KACL,CAAA,GAAA,oBAAC,QAAD;MAAQ,MAAK;MAAS,SAAQ;MAAQ,MAAK;MAAiB;MAAU,cAAW;MAAa,SAAS;MACrG,UAAA,oBAAC,cAAD,CAAe,CAAA;KACT,CAAA,CACL;;GACF;EACF,CAAA,CAAA;;AAET"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every exported component hands `aria-label`, `id` and `data-testid` to the element it documents as its root or main part.
|
|
3
|
+
* A component that took a closed list of props dropped the rest (Tabs' tablist had no accessible name even though the app
|
|
4
|
+
* passed `aria-label`), so this renders each one with the three and finds them again.
|
|
5
|
+
*
|
|
6
|
+
* Components that are not covered here, and why, are listed in INTENTIONAL_DROPS.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { Accordion as BaseAccordion } from '@base-ui/react/accordion';
|
|
1
2
|
import type * as React from 'react';
|
|
2
|
-
export interface IAccordionProps {
|
|
3
|
+
export interface IAccordionProps extends Omit<BaseAccordion.Root.Props, 'value' | 'defaultValue' | 'onValueChange' | 'multiple' | 'className' | 'children'> {
|
|
3
4
|
value?: string[];
|
|
4
5
|
defaultValue?: string[];
|
|
5
6
|
onValueChange?: (value: string[]) => void;
|
|
@@ -7,21 +8,21 @@ export interface IAccordionProps {
|
|
|
7
8
|
className?: string;
|
|
8
9
|
children: React.ReactNode;
|
|
9
10
|
}
|
|
10
|
-
export declare const Accordion: ({ value, defaultValue, onValueChange, multiple, className, children }: IAccordionProps) => React.JSX.Element;
|
|
11
|
-
export interface IAccordionItemProps {
|
|
11
|
+
export declare const Accordion: ({ value, defaultValue, onValueChange, multiple, className, children, ...props }: IAccordionProps) => React.JSX.Element;
|
|
12
|
+
export interface IAccordionItemProps extends Omit<BaseAccordion.Item.Props, 'value' | 'disabled' | 'className' | 'children'> {
|
|
12
13
|
value: string;
|
|
13
14
|
disabled?: boolean;
|
|
14
15
|
className?: string;
|
|
15
16
|
children: React.ReactNode;
|
|
16
17
|
}
|
|
17
|
-
export declare const AccordionItem: ({ value, disabled, className, children }: IAccordionItemProps) => React.JSX.Element;
|
|
18
|
-
export interface IAccordionTriggerProps {
|
|
18
|
+
export declare const AccordionItem: ({ value, disabled, className, children, ...props }: IAccordionItemProps) => React.JSX.Element;
|
|
19
|
+
export interface IAccordionTriggerProps extends Omit<BaseAccordion.Trigger.Props, 'className' | 'children'> {
|
|
19
20
|
className?: string;
|
|
20
21
|
children: React.ReactNode;
|
|
21
22
|
}
|
|
22
|
-
export declare const AccordionTrigger: ({ className, children }: IAccordionTriggerProps) => React.JSX.Element;
|
|
23
|
-
export interface IAccordionContentProps {
|
|
23
|
+
export declare const AccordionTrigger: ({ className, children, ...props }: IAccordionTriggerProps) => React.JSX.Element;
|
|
24
|
+
export interface IAccordionContentProps extends Omit<BaseAccordion.Panel.Props, 'className' | 'children'> {
|
|
24
25
|
className?: string;
|
|
25
26
|
children: React.ReactNode;
|
|
26
27
|
}
|
|
27
|
-
export declare const AccordionContent: ({ className, children }: IAccordionContentProps) => React.JSX.Element;
|
|
28
|
+
export declare const AccordionContent: ({ className, children, ...props }: IAccordionContentProps) => React.JSX.Element;
|