@exsto/ds 0.0.1-rc.2 → 0.0.1-rc.21
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 +163 -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 +1185 -403
- package/dist/theme.css +122 -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 +93 -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.js +61 -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 +155 -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 +9 -8
- package/dist/ui/src/components/ui/tabs/tabs.js +50 -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-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 +52 -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
package/dist/theme.css
CHANGED
|
@@ -1,17 +1,70 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* @exsto/ds design tokens and their Tailwind mapping, uncompiled.
|
|
3
3
|
*
|
|
4
|
-
* Import this
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Import this when you want the design system vocabulary (bg-card,
|
|
5
|
+
* text-muted-foreground, rounded-lg, font-sans, text-2xs, ...) in your OWN
|
|
6
|
+
* markup. styles.css styles the components; this gives your Tailwind build the
|
|
7
|
+
* tokens behind them.
|
|
8
8
|
*
|
|
9
|
+
* ORDER, for a consumer who runs Tailwind:
|
|
10
|
+
*
|
|
11
|
+
* @import "@exsto/ds/styles.css";
|
|
9
12
|
* @import "tailwindcss";
|
|
10
13
|
* @import "@exsto/ds/theme.css";
|
|
11
|
-
*
|
|
14
|
+
*
|
|
15
|
+
* The @source line below is what makes that order enough. styles.css is a
|
|
16
|
+
* compiled Tailwind build, so its utilities share the utilities layer with the
|
|
17
|
+
* ones your build emits, and between two rules of equal weight the later one
|
|
18
|
+
* wins. Two separate builds cannot agree on a single order: ours put .hidden
|
|
19
|
+
* after your .md:block, and a sidebar marked `hidden md:block` stayed hidden at
|
|
20
|
+
* every width. The line points your build at the components' shipped code, so
|
|
21
|
+
* your build emits their utilities as well, each responsive variant after its
|
|
22
|
+
* own base, in one consistent order that lands last.
|
|
23
|
+
*
|
|
24
|
+
* Importing styles.css after your Tailwind entry puts its compiled utilities
|
|
25
|
+
* last instead, and they then outrank yours. Keep it first.
|
|
12
26
|
*/
|
|
13
27
|
|
|
28
|
+
@source "./**/*.js";
|
|
29
|
+
|
|
14
30
|
@custom-variant dark (&:is(.dark *));
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
* Brand layer.
|
|
34
|
+
*
|
|
35
|
+
* The colour ramps come from Tailwind v4 unchanged. The design system is built on
|
|
36
|
+
* the stock palette so the Figma library (Tailwind v4 + shadcn, style Nova) and the
|
|
37
|
+
* code cannot drift apart: there is no value here to keep in sync, because nothing
|
|
38
|
+
* here redefines a colour. The exact shadcn neutral semantic theme lives in
|
|
39
|
+
* tokens.css.
|
|
40
|
+
*
|
|
41
|
+
* The legacy Exsto palette this file used to carry was dropped when the design team
|
|
42
|
+
* moved to Tailwind defaults. It is in git history if a legacy surface ever needs it.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
@theme {
|
|
46
|
+
/* Inter is the typeface for the whole system. */
|
|
47
|
+
--font-sans: 'Inter', sans-serif;
|
|
48
|
+
|
|
49
|
+
/*
|
|
50
|
+
* The one step Tailwind's type scale does not have: a 10/14 footnote, used by
|
|
51
|
+
* badges, chips and dense table headers. Everything else is stock.
|
|
52
|
+
*/
|
|
53
|
+
--text-2xs: 10px;
|
|
54
|
+
--text-2xs--line-height: 14px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@layer base {
|
|
58
|
+
:root {
|
|
59
|
+
color-scheme: light;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
:root.dark,
|
|
63
|
+
.dark {
|
|
64
|
+
color-scheme: dark;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
15
68
|
/* Current shadcn Base Nova neutral theme. Product branding belongs in a separate layer. */
|
|
16
69
|
/* Base Nova deliberately uses the same black/10 backdrop in both modes; component-level backdrop blur supplies the remaining separation. */
|
|
17
70
|
|
|
@@ -35,7 +88,8 @@
|
|
|
35
88
|
--secondary-foreground: oklch(0.205 0 0);
|
|
36
89
|
|
|
37
90
|
--muted: oklch(0.97 0 0);
|
|
38
|
-
|
|
91
|
+
/* Muted text: 4.5:1 on the page (white), a card and the muted surface (oklch 0.97). 0.556 was 4.35:1 on the latter. */
|
|
92
|
+
--muted-foreground: oklch(0.545 0 0);
|
|
39
93
|
|
|
40
94
|
--accent: oklch(0.97 0 0);
|
|
41
95
|
--accent-foreground: oklch(0.205 0 0);
|
|
@@ -57,7 +111,9 @@
|
|
|
57
111
|
|
|
58
112
|
--border: oklch(0.922 0 0);
|
|
59
113
|
--input: oklch(0.922 0 0);
|
|
60
|
-
|
|
114
|
+
/* The outline of a control (field, trigger, outline button): 3:1 on the page and on a card (WCAG 1.4.11). --input stays the fill. */
|
|
115
|
+
--control-border: oklch(0.66 0 0);
|
|
116
|
+
--ring: oklch(0.6 0 0);
|
|
61
117
|
|
|
62
118
|
--chart-1: oklch(0.646 0.222 41.116);
|
|
63
119
|
--chart-2: oklch(0.6 0.118 184.704);
|
|
@@ -73,6 +129,38 @@
|
|
|
73
129
|
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
74
130
|
--sidebar-border: oklch(0.922 0 0);
|
|
75
131
|
--sidebar-ring: oklch(0.708 0 0);
|
|
132
|
+
|
|
133
|
+
/*
|
|
134
|
+
* Avatar palette: twelve hues, each a pair at an even perceived lightness, a
|
|
135
|
+
* soft tint with strong text of the same hue in the light theme and a deep tint
|
|
136
|
+
* with light text in the dark one. No yellows, olives or browns: they turn muddy.
|
|
137
|
+
* InitialsAvatar picks one by hashing the initials; every pair clears 4.5:1
|
|
138
|
+
* (packages/ui/src/components/edyn/initials-avatar/initials-avatar.test.tsx checks it).
|
|
139
|
+
*/
|
|
140
|
+
--avatar-1-bg: oklch(0.93 0.045 259); /* blue */
|
|
141
|
+
--avatar-1-fg: oklch(0.45 0.15 259);
|
|
142
|
+
--avatar-2-bg: oklch(0.93 0.045 277); /* indigo */
|
|
143
|
+
--avatar-2-fg: oklch(0.45 0.15 277);
|
|
144
|
+
--avatar-3-bg: oklch(0.93 0.045 293); /* violet */
|
|
145
|
+
--avatar-3-fg: oklch(0.45 0.15 293);
|
|
146
|
+
--avatar-4-bg: oklch(0.93 0.045 322); /* fuchsia */
|
|
147
|
+
--avatar-4-fg: oklch(0.45 0.15 322);
|
|
148
|
+
--avatar-5-bg: oklch(0.93 0.045 354); /* pink */
|
|
149
|
+
--avatar-5-fg: oklch(0.45 0.15 354);
|
|
150
|
+
--avatar-6-bg: oklch(0.93 0.045 16); /* rose */
|
|
151
|
+
--avatar-6-fg: oklch(0.45 0.15 16);
|
|
152
|
+
--avatar-7-bg: oklch(0.93 0.045 27); /* red */
|
|
153
|
+
--avatar-7-fg: oklch(0.45 0.15 27);
|
|
154
|
+
--avatar-8-bg: oklch(0.93 0.045 47); /* orange */
|
|
155
|
+
--avatar-8-fg: oklch(0.45 0.15 47);
|
|
156
|
+
--avatar-9-bg: oklch(0.93 0.045 163); /* emerald */
|
|
157
|
+
--avatar-9-fg: oklch(0.45 0.15 163);
|
|
158
|
+
--avatar-10-bg: oklch(0.93 0.045 183); /* teal */
|
|
159
|
+
--avatar-10-fg: oklch(0.45 0.15 183);
|
|
160
|
+
--avatar-11-bg: oklch(0.93 0.045 215); /* cyan */
|
|
161
|
+
--avatar-11-fg: oklch(0.45 0.15 215);
|
|
162
|
+
--avatar-12-bg: oklch(0.93 0.045 237); /* sky */
|
|
163
|
+
--avatar-12-fg: oklch(0.45 0.15 237);
|
|
76
164
|
}
|
|
77
165
|
|
|
78
166
|
.dark {
|
|
@@ -115,6 +203,7 @@
|
|
|
115
203
|
|
|
116
204
|
--border: oklch(1 0 0 / 10%);
|
|
117
205
|
--input: oklch(1 0 0 / 15%);
|
|
206
|
+
--control-border: oklch(1 0 0 / 35%);
|
|
118
207
|
--ring: oklch(0.556 0 0);
|
|
119
208
|
|
|
120
209
|
--chart-1: oklch(0.488 0.243 264.376);
|
|
@@ -131,6 +220,31 @@
|
|
|
131
220
|
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
132
221
|
--sidebar-border: oklch(1 0 0 / 10%);
|
|
133
222
|
--sidebar-ring: oklch(0.556 0 0);
|
|
223
|
+
|
|
224
|
+
--avatar-1-bg: oklch(0.32 0.07 259); /* blue */
|
|
225
|
+
--avatar-1-fg: oklch(0.86 0.09 259);
|
|
226
|
+
--avatar-2-bg: oklch(0.32 0.07 277); /* indigo */
|
|
227
|
+
--avatar-2-fg: oklch(0.86 0.09 277);
|
|
228
|
+
--avatar-3-bg: oklch(0.32 0.07 293); /* violet */
|
|
229
|
+
--avatar-3-fg: oklch(0.86 0.09 293);
|
|
230
|
+
--avatar-4-bg: oklch(0.32 0.07 322); /* fuchsia */
|
|
231
|
+
--avatar-4-fg: oklch(0.86 0.09 322);
|
|
232
|
+
--avatar-5-bg: oklch(0.32 0.07 354); /* pink */
|
|
233
|
+
--avatar-5-fg: oklch(0.86 0.09 354);
|
|
234
|
+
--avatar-6-bg: oklch(0.32 0.07 16); /* rose */
|
|
235
|
+
--avatar-6-fg: oklch(0.86 0.09 16);
|
|
236
|
+
--avatar-7-bg: oklch(0.32 0.07 27); /* red */
|
|
237
|
+
--avatar-7-fg: oklch(0.86 0.09 27);
|
|
238
|
+
--avatar-8-bg: oklch(0.32 0.07 47); /* orange */
|
|
239
|
+
--avatar-8-fg: oklch(0.86 0.09 47);
|
|
240
|
+
--avatar-9-bg: oklch(0.32 0.07 163); /* emerald */
|
|
241
|
+
--avatar-9-fg: oklch(0.86 0.09 163);
|
|
242
|
+
--avatar-10-bg: oklch(0.32 0.07 183); /* teal */
|
|
243
|
+
--avatar-10-fg: oklch(0.86 0.09 183);
|
|
244
|
+
--avatar-11-bg: oklch(0.32 0.07 215); /* cyan */
|
|
245
|
+
--avatar-11-fg: oklch(0.86 0.09 215);
|
|
246
|
+
--avatar-12-bg: oklch(0.32 0.07 237); /* sky */
|
|
247
|
+
--avatar-12-fg: oklch(0.86 0.09 237);
|
|
134
248
|
}
|
|
135
249
|
|
|
136
250
|
@theme inline {
|
|
@@ -169,6 +283,7 @@
|
|
|
169
283
|
--color-info-ring: var(--info-ring);
|
|
170
284
|
--color-border: var(--border);
|
|
171
285
|
--color-input: var(--input);
|
|
286
|
+
--color-control: var(--control-border);
|
|
172
287
|
--color-ring: var(--ring);
|
|
173
288
|
--color-chart-1: var(--chart-1);
|
|
174
289
|
--color-chart-2: var(--chart-2);
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { DEFAULT_TIME_FIELD_LABELS, EMPTY_TIME, TimeField, editSegment, formatTime, localeHourCycle, parseTime, rangeOf, stepValue, typeDigit } from "./ui/src/components/edyn/time-field/time-field.js";
|
|
2
|
+
export { DEFAULT_TIME_FIELD_LABELS, EMPTY_TIME, TimeField, editSegment, formatTime, localeHourCycle, parseTime, rangeOf, stepValue, typeDigit };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef, RefObject } from 'react';
|
|
2
|
+
/** Thousands separated, rounded to a whole number: the default way a count reads. */
|
|
3
|
+
export declare const formatCount: (value: number) => string;
|
|
4
|
+
/**
|
|
5
|
+
* The values to show for `targets` this frame, all on one clock and one curve, so a
|
|
6
|
+
* count and its bar move together. They start from 0 and move once `element` has
|
|
7
|
+
* been on screen.
|
|
8
|
+
*/
|
|
9
|
+
export declare const useAnimatedValues: (targets: number[], element: RefObject<Element | null>) => number[];
|
|
10
|
+
export interface IAnimatedNumberProps extends Omit<ComponentPropsWithoutRef<'span'>, 'children' | 'className'> {
|
|
11
|
+
value: number;
|
|
12
|
+
/** What it shows while it moves and once there (formatCount by default; a percentage formatter for shares). */
|
|
13
|
+
format?: (value: number) => string;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A number that moves to its new value. Its width holds the widest of where it starts
|
|
18
|
+
* and where it lands, in tabular figures, so nothing beside it moves while the digits
|
|
19
|
+
* change. Assistive technology reads only the final value.
|
|
20
|
+
*/
|
|
21
|
+
export declare const AnimatedNumber: ({ value, format, className, ...props }: IAnimatedNumberProps) => import('react').JSX.Element;
|
|
22
|
+
export interface INumberTextProps extends Omit<ComponentPropsWithoutRef<'span'>, 'children' | 'className'> {
|
|
23
|
+
element?: RefObject<HTMLSpanElement | null>;
|
|
24
|
+
shown: number;
|
|
25
|
+
value: number;
|
|
26
|
+
format?: (value: number) => string;
|
|
27
|
+
className?: string;
|
|
28
|
+
}
|
|
29
|
+
/** The text of a moving number: what it shows now, held at its widest, with the final value for assistive technology. */
|
|
30
|
+
export declare const NumberText: ({ element, shown, value, format, className, ...props }: INumberTextProps) => import('react').JSX.Element;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
//#region ../ui/src/components/edyn/animated-number/animated-number.tsx
|
|
4
|
+
var DURATION = 800;
|
|
5
|
+
var easeInOutCubic = (t) => t < .5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2;
|
|
6
|
+
var reducedMotion = () => window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
7
|
+
var NUMBER = new Intl.NumberFormat("en-GB");
|
|
8
|
+
/** Thousands separated, rounded to a whole number: the default way a count reads. */
|
|
9
|
+
var formatCount = (value) => NUMBER.format(Math.round(value) || 0);
|
|
10
|
+
var useSeen = (element) => {
|
|
11
|
+
const [seen, setSeen] = useState(() => typeof IntersectionObserver === "undefined");
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const target = element.current;
|
|
14
|
+
if (seen || target === null) return;
|
|
15
|
+
const observer = new IntersectionObserver((entries) => {
|
|
16
|
+
if (entries.some((entry) => entry.isIntersecting)) {
|
|
17
|
+
setSeen(true);
|
|
18
|
+
observer.disconnect();
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
observer.observe(target);
|
|
22
|
+
return () => observer.disconnect();
|
|
23
|
+
}, [element, seen]);
|
|
24
|
+
return seen;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The values to show for `targets` this frame, all on one clock and one curve, so a
|
|
28
|
+
* count and its bar move together. They start from 0 and move once `element` has
|
|
29
|
+
* been on screen.
|
|
30
|
+
*/
|
|
31
|
+
var useAnimatedValues = (targets, element) => {
|
|
32
|
+
const seen = useSeen(element);
|
|
33
|
+
const [shown, setShown] = useState(() => targets.map(() => 0));
|
|
34
|
+
const refCurrent = useRef(shown);
|
|
35
|
+
const key = targets.join(",");
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (!seen) return;
|
|
38
|
+
const goal = key.split(",").map(Number);
|
|
39
|
+
const from = goal.map((_, index) => refCurrent.current[index] ?? 0);
|
|
40
|
+
if (from.every((value, index) => value === goal[index])) return;
|
|
41
|
+
if (reducedMotion()) {
|
|
42
|
+
refCurrent.current = goal;
|
|
43
|
+
setShown(goal);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const start = performance.now();
|
|
47
|
+
let frame = 0;
|
|
48
|
+
const tick = (now) => {
|
|
49
|
+
const progress = Math.min(1, (now - start) / DURATION);
|
|
50
|
+
const eased = easeInOutCubic(progress);
|
|
51
|
+
const next = progress === 1 ? goal : goal.map((value, index) => (from[index] ?? 0) + (value - (from[index] ?? 0)) * eased);
|
|
52
|
+
refCurrent.current = next;
|
|
53
|
+
setShown(next);
|
|
54
|
+
if (progress < 1) frame = requestAnimationFrame(tick);
|
|
55
|
+
};
|
|
56
|
+
frame = requestAnimationFrame(tick);
|
|
57
|
+
return () => cancelAnimationFrame(frame);
|
|
58
|
+
}, [key, seen]);
|
|
59
|
+
return shown;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* A number that moves to its new value. Its width holds the widest of where it starts
|
|
63
|
+
* and where it lands, in tabular figures, so nothing beside it moves while the digits
|
|
64
|
+
* change. Assistive technology reads only the final value.
|
|
65
|
+
*/
|
|
66
|
+
var AnimatedNumber = ({ value, format = formatCount, className, ...props }) => {
|
|
67
|
+
const refElement = useRef(null);
|
|
68
|
+
const [shown = 0] = useAnimatedValues([value], refElement);
|
|
69
|
+
return /* @__PURE__ */ jsx(NumberText, {
|
|
70
|
+
element: refElement,
|
|
71
|
+
shown,
|
|
72
|
+
value,
|
|
73
|
+
format,
|
|
74
|
+
className,
|
|
75
|
+
...props
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
/** The text of a moving number: what it shows now, held at its widest, with the final value for assistive technology. */
|
|
79
|
+
var NumberText = ({ element, shown, value, format = formatCount, className, ...props }) => {
|
|
80
|
+
const now = format(shown);
|
|
81
|
+
const final = format(value);
|
|
82
|
+
const widest = now.length > final.length ? now : final;
|
|
83
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
84
|
+
"data-slot": "animated-number",
|
|
85
|
+
...props,
|
|
86
|
+
ref: element,
|
|
87
|
+
className,
|
|
88
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
89
|
+
"aria-hidden": "true",
|
|
90
|
+
className: "inline-grid tabular-nums",
|
|
91
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
92
|
+
"data-ghost": widest,
|
|
93
|
+
className: "invisible col-start-1 row-start-1 ghost-text"
|
|
94
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
95
|
+
"data-slot": "animated-number-value",
|
|
96
|
+
className: "col-start-1 row-start-1",
|
|
97
|
+
children: now
|
|
98
|
+
})]
|
|
99
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
100
|
+
className: "sr-only",
|
|
101
|
+
children: final
|
|
102
|
+
})]
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
//#endregion
|
|
106
|
+
export { AnimatedNumber, NumberText, formatCount, useAnimatedValues };
|
|
107
|
+
|
|
108
|
+
//# sourceMappingURL=animated-number.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animated-number.js","names":[],"sources":["../../../../../../../ui/src/components/edyn/animated-number/animated-number.tsx"],"sourcesContent":["import { type ComponentPropsWithoutRef, type RefObject, useEffect, useRef, useState } from 'react';\n\n// Numbers that move instead of jumping when a tab or a filter changes them: from the\n// value shown to the new one over 800ms, easing in and out; the first time, from 0\n// once it scrolls into view. Interrupted by another change, it carries on from where\n// it is, never back. With reduced motion, or when the value has not changed (a refetch\n// with the same answer), nothing moves.\n\nconst DURATION = 800;\n\nconst easeInOutCubic = (t: number): number => (t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2);\n\nconst reducedMotion = (): boolean => window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n\nconst NUMBER = new Intl.NumberFormat('en-GB');\n\n/** Thousands separated, rounded to a whole number: the default way a count reads. */\nexport const formatCount = (value: number): string => NUMBER.format(Math.round(value) || 0);\n\n// Whether the element has been on screen yet; once it has, it stays counted as seen.\nconst useSeen = (element: RefObject<Element | null>): boolean => {\n const [seen, setSeen] = useState(() => typeof IntersectionObserver === 'undefined');\n useEffect(() => {\n const target = element.current;\n if (seen || target === null) {\n return;\n }\n const observer = new IntersectionObserver((entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n setSeen(true);\n observer.disconnect();\n }\n });\n observer.observe(target);\n return () => observer.disconnect();\n }, [element, seen]);\n return seen;\n};\n\n/**\n * The values to show for `targets` this frame, all on one clock and one curve, so a\n * count and its bar move together. They start from 0 and move once `element` has\n * been on screen.\n */\nexport const useAnimatedValues = (targets: number[], element: RefObject<Element | null>): number[] => {\n const seen = useSeen(element);\n const [shown, setShown] = useState<number[]>(() => targets.map(() => 0));\n const refCurrent = useRef(shown);\n const key = targets.join(',');\n useEffect(() => {\n if (!seen) {\n return;\n }\n const goal = key.split(',').map(Number);\n const from = goal.map((_, index) => refCurrent.current[index] ?? 0);\n if (from.every((value, index) => value === goal[index])) {\n return;\n }\n if (reducedMotion()) {\n refCurrent.current = goal;\n setShown(goal);\n return;\n }\n const start = performance.now();\n let frame = 0;\n const tick = (now: number): void => {\n const progress = Math.min(1, (now - start) / DURATION);\n const eased = easeInOutCubic(progress);\n // Exactly the goal at the end, never a float a hair beside it.\n const next = progress === 1 ? goal : goal.map((value, index) => (from[index] ?? 0) + (value - (from[index] ?? 0)) * eased);\n refCurrent.current = next;\n setShown(next);\n if (progress < 1) {\n frame = requestAnimationFrame(tick);\n }\n };\n frame = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(frame);\n }, [key, seen]);\n return shown;\n};\n\nexport interface IAnimatedNumberProps extends Omit<ComponentPropsWithoutRef<'span'>, 'children' | 'className'> {\n value: number;\n /** What it shows while it moves and once there (formatCount by default; a percentage formatter for shares). */\n format?: (value: number) => string;\n className?: string;\n}\n\n/**\n * A number that moves to its new value. Its width holds the widest of where it starts\n * and where it lands, in tabular figures, so nothing beside it moves while the digits\n * change. Assistive technology reads only the final value.\n */\nexport const AnimatedNumber = ({ value, format = formatCount, className, ...props }: IAnimatedNumberProps) => {\n const refElement = useRef<HTMLSpanElement>(null);\n const [shown = 0] = useAnimatedValues([value], refElement);\n return <NumberText element={refElement} shown={shown} value={value} format={format} className={className} {...props} />;\n};\n\nexport interface INumberTextProps extends Omit<ComponentPropsWithoutRef<'span'>, 'children' | 'className'> {\n element?: RefObject<HTMLSpanElement | null>;\n shown: number;\n value: number;\n format?: (value: number) => string;\n className?: string;\n}\n\n/** The text of a moving number: what it shows now, held at its widest, with the final value for assistive technology. */\nexport const NumberText = ({ element, shown, value, format = formatCount, className, ...props }: INumberTextProps) => {\n const now = format(shown);\n const final = format(value);\n // The widest of the two, laid invisibly under the number: it holds the width of the\n // real figures (tabular digits are not exactly 1ch), so the number grows or shrinks\n // only once it has landed.\n const widest = now.length > final.length ? now : final;\n return (\n <span data-slot=\"animated-number\" {...props} ref={element} className={className}>\n <span aria-hidden=\"true\" className=\"inline-grid tabular-nums\">\n <span data-ghost={widest} className=\"invisible col-start-1 row-start-1 ghost-text\" />\n <span data-slot=\"animated-number-value\" className=\"col-start-1 row-start-1\">\n {now}\n </span>\n </span>\n <span className=\"sr-only\">{final}</span>\n </span>\n );\n};\n"],"mappings":";;;AAQA,IAAM,WAAW;AAEjB,IAAM,kBAAkB,MAAuB,IAAI,KAAM,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,MAAM,IAAI;AAE9F,IAAM,sBAA+B,OAAO,WAAW,kCAAkC,CAAC,CAAC;AAE3F,IAAM,SAAS,IAAI,KAAK,aAAa,OAAO;;AAG5C,IAAa,eAAe,UAA0B,OAAO,OAAO,KAAK,MAAM,KAAK,KAAK,CAAC;AAG1F,IAAM,WAAW,YAAgD;CAC/D,MAAM,CAAC,MAAM,WAAW,eAAe,OAAO,yBAAyB,WAAW;CAClF,gBAAgB;EACd,MAAM,SAAS,QAAQ;EACvB,IAAI,QAAQ,WAAW,MACrB;EAEF,MAAM,WAAW,IAAI,sBAAsB,YAAY;GACrD,IAAI,QAAQ,MAAM,UAAU,MAAM,cAAc,GAAG;IACjD,QAAQ,IAAI;IACZ,SAAS,WAAW;GACtB;EACF,CAAC;EACD,SAAS,QAAQ,MAAM;EACvB,aAAa,SAAS,WAAW;CACnC,GAAG,CAAC,SAAS,IAAI,CAAC;CAClB,OAAO;AACT;;;;;;AAOA,IAAa,qBAAqB,SAAmB,YAAiD;CACpG,MAAM,OAAO,QAAQ,OAAO;CAC5B,MAAM,CAAC,OAAO,YAAY,eAAyB,QAAQ,UAAU,CAAC,CAAC;CACvE,MAAM,aAAa,OAAO,KAAK;CAC/B,MAAM,MAAM,QAAQ,KAAK,GAAG;CAC5B,gBAAgB;EACd,IAAI,CAAC,MACH;EAEF,MAAM,OAAO,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM;EACtC,MAAM,OAAO,KAAK,KAAK,GAAG,UAAU,WAAW,QAAQ,UAAU,CAAC;EAClE,IAAI,KAAK,OAAO,OAAO,UAAU,UAAU,KAAK,MAAM,GACpD;EAEF,IAAI,cAAc,GAAG;GACnB,WAAW,UAAU;GACrB,SAAS,IAAI;GACb;EACF;EACA,MAAM,QAAQ,YAAY,IAAI;EAC9B,IAAI,QAAQ;EACZ,MAAM,QAAQ,QAAsB;GAClC,MAAM,WAAW,KAAK,IAAI,IAAI,MAAM,SAAS,QAAQ;GACrD,MAAM,QAAQ,eAAe,QAAQ;GAErC,MAAM,OAAO,aAAa,IAAI,OAAO,KAAK,KAAK,OAAO,WAAW,KAAK,UAAU,MAAM,SAAS,KAAK,UAAU,MAAM,KAAK;GACzH,WAAW,UAAU;GACrB,SAAS,IAAI;GACb,IAAI,WAAW,GACb,QAAQ,sBAAsB,IAAI;EAEtC;EACA,QAAQ,sBAAsB,IAAI;EAClC,aAAa,qBAAqB,KAAK;CACzC,GAAG,CAAC,KAAK,IAAI,CAAC;CACd,OAAO;AACT;;;;;;AAcA,IAAa,kBAAkB,EAAE,OAAO,SAAS,aAAa,WAAW,GAAG,YAAkC;CAC5G,MAAM,aAAa,OAAwB,IAAI;CAC/C,MAAM,CAAC,QAAQ,KAAK,kBAAkB,CAAC,KAAK,GAAG,UAAU;CACzD,OAAO,oBAAC,YAAD;EAAY,SAAS;EAAmB;EAAc;EAAe;EAAmB;EAAW,GAAI;CAAQ,CAAA;AACxH;;AAWA,IAAa,cAAc,EAAE,SAAS,OAAO,OAAO,SAAS,aAAa,WAAW,GAAG,YAA8B;CACpH,MAAM,MAAM,OAAO,KAAK;CACxB,MAAM,QAAQ,OAAO,KAAK;CAI1B,MAAM,SAAS,IAAI,SAAS,MAAM,SAAS,MAAM;CACjD,OACE,qBAAC,QAAD;EAAM,aAAU;EAAkB,GAAI;EAAO,KAAK;EAAoB;EAAtE,UAAA,CACE,qBAAC,QAAD;GAAM,eAAY;GAAO,WAAU;GAAnC,UAAA,CACE,oBAAC,QAAD;IAAM,cAAY;IAAQ,WAAU;GAAgD,CAAA,GACpF,oBAAC,QAAD;IAAM,aAAU;IAAwB,WAAU;IAC/C,UAAA;GACG,CAAA,CACF;EACN,CAAA,GAAA,oBAAC,QAAD;GAAM,WAAU;GAAW,UAAA;EAAY,CAAA,CACnC;;AAEV"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnimatedNumber: a number that moves to its new value, announced once.
|
|
3
|
+
*
|
|
4
|
+
* PATH TAKEN: the formatting, the markup and the reduced-motion and no-change
|
|
5
|
+
* paths are plain logic and run in happy-dom. The motion itself (a number really
|
|
6
|
+
* passing through values, a width that holds) needs a real clock and layout, so
|
|
7
|
+
* e2e/animated-number.spec.ts measures it in the browser.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './animated-number';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { TCssLength } from '../../../lib/utils';
|
|
2
|
-
|
|
2
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
3
|
+
export interface IAudioPlayerProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'className' | 'onPlay' | 'onPause' | 'onEnded' | 'onTimeUpdate' | 'role'> {
|
|
3
4
|
/** Audio source URL. */
|
|
4
5
|
src?: string;
|
|
5
6
|
/** Start muted. The volume control still works from here. */
|
|
@@ -26,4 +27,4 @@ export interface IAudioPlayerProps {
|
|
|
26
27
|
* time, a seekable timeline, and volume. Four elements in one rounded row, per
|
|
27
28
|
* the design-system anatomy.
|
|
28
29
|
*/
|
|
29
|
-
export declare const AudioPlayer: ({ src, muted, loop, disabled, width, className, "aria-label": ariaLabel, onPlay, onPause, onEnded, onTimeUpdate, }: IAudioPlayerProps) => import('react').JSX.Element;
|
|
30
|
+
export declare const AudioPlayer: ({ src, muted, loop, disabled, width, className, "aria-label": ariaLabel, style, onPlay, onPause, onEnded, onTimeUpdate, ...props }: IAudioPlayerProps) => import('react').JSX.Element;
|
|
@@ -0,0 +1,86 @@
|
|
|
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 { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { IconPlayerPauseFilled, IconPlayerPlayFilled, IconVolume, IconVolumeOff } from "@tabler/icons-react";
|
|
7
|
+
//#region ../ui/src/components/edyn/audio-player/audio-player.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Compact inline media control for audio content: play/pause, elapsed and total
|
|
10
|
+
* time, a seekable timeline, and volume. Four elements in one rounded row, per
|
|
11
|
+
* the design-system anatomy.
|
|
12
|
+
*/
|
|
13
|
+
var AudioPlayer = ({ src, muted = false, loop = false, disabled = false, width, className, "aria-label": ariaLabel = "Audio player", style, onPlay, onPause, onEnded, onTimeUpdate, ...props }) => {
|
|
14
|
+
const { refMedia, playing, currentTime, duration, muted: isMuted, toggle, seek, toggleMute } = useMediaPlayer({
|
|
15
|
+
onPlay,
|
|
16
|
+
onPause,
|
|
17
|
+
onEnded,
|
|
18
|
+
onTimeUpdate
|
|
19
|
+
});
|
|
20
|
+
const PlaybackIcon = playing ? IconPlayerPauseFilled : IconPlayerPlayFilled;
|
|
21
|
+
const VolumeIcon = isMuted ? IconVolumeOff : IconVolume;
|
|
22
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
23
|
+
"data-slot": "audio-player",
|
|
24
|
+
"data-playing": playing || void 0,
|
|
25
|
+
role: "group",
|
|
26
|
+
...props,
|
|
27
|
+
"aria-label": ariaLabel,
|
|
28
|
+
style: {
|
|
29
|
+
width: cssLength(width),
|
|
30
|
+
...style
|
|
31
|
+
},
|
|
32
|
+
className: cn("flex h-12 w-full items-center gap-2 rounded-lg bg-muted px-3 py-1.5", className),
|
|
33
|
+
children: [
|
|
34
|
+
/* @__PURE__ */ jsx(Button, {
|
|
35
|
+
type: "button",
|
|
36
|
+
variant: "ghost",
|
|
37
|
+
size: "icon",
|
|
38
|
+
disabled,
|
|
39
|
+
"aria-label": playing ? "Pause" : "Play",
|
|
40
|
+
onClick: toggle,
|
|
41
|
+
children: /* @__PURE__ */ jsx(PlaybackIcon, {})
|
|
42
|
+
}),
|
|
43
|
+
/* @__PURE__ */ jsxs("span", {
|
|
44
|
+
"data-slot": "audio-player-time",
|
|
45
|
+
className: "shrink-0 text-xs tabular-nums text-foreground/70",
|
|
46
|
+
children: [
|
|
47
|
+
formatMediaTime(currentTime),
|
|
48
|
+
" / ",
|
|
49
|
+
formatMediaTime(duration)
|
|
50
|
+
]
|
|
51
|
+
}),
|
|
52
|
+
/* @__PURE__ */ jsx(Slider, {
|
|
53
|
+
className: "flex-1 [&_[data-slot=slider-control]]:py-1.5 [&_[data-slot=slider-thumb]]:size-3 [&_[data-slot=slider-track]]:h-1 [&_[data-slot=slider-track]]:bg-foreground/15",
|
|
54
|
+
value: Math.min(currentTime, duration || 0),
|
|
55
|
+
min: 0,
|
|
56
|
+
max: duration || 0,
|
|
57
|
+
step: 1,
|
|
58
|
+
disabled: disabled || duration === 0,
|
|
59
|
+
"aria-label": "Seek",
|
|
60
|
+
onValueChange: (next) => {
|
|
61
|
+
seek(next);
|
|
62
|
+
}
|
|
63
|
+
}),
|
|
64
|
+
/* @__PURE__ */ jsx(Button, {
|
|
65
|
+
type: "button",
|
|
66
|
+
variant: "ghost",
|
|
67
|
+
size: "icon",
|
|
68
|
+
disabled,
|
|
69
|
+
"aria-label": isMuted ? "Unmute" : "Mute",
|
|
70
|
+
onClick: toggleMute,
|
|
71
|
+
children: /* @__PURE__ */ jsx(VolumeIcon, {})
|
|
72
|
+
}),
|
|
73
|
+
/* @__PURE__ */ jsx("audio", {
|
|
74
|
+
ref: refMedia,
|
|
75
|
+
src,
|
|
76
|
+
muted,
|
|
77
|
+
loop,
|
|
78
|
+
preload: "metadata"
|
|
79
|
+
})
|
|
80
|
+
]
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
//#endregion
|
|
84
|
+
export { AudioPlayer };
|
|
85
|
+
|
|
86
|
+
//# sourceMappingURL=audio-player.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-player.js","names":[],"sources":["../../../../../../../ui/src/components/edyn/audio-player/audio-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 { IconPlayerPauseFilled, IconPlayerPlayFilled, IconVolume, IconVolumeOff } from '@tabler/icons-react';\nimport type { ComponentPropsWithoutRef } from 'react';\n\nexport interface IAudioPlayerProps\n extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'className' | 'onPlay' | 'onPause' | 'onEnded' | 'onTimeUpdate' | 'role'> {\n /** Audio source URL. */\n src?: string;\n /** Start muted. The volume control still works from here. */\n muted?: boolean;\n /** Loop playback when the track ends. */\n loop?: boolean;\n /** Disable every control without hiding the player. */\n disabled?: boolean;\n /**\n * Bar width. A number is px, a string is any CSS length (`'100%'`, `'34rem'`).\n * Omitted, the bar fills the width it is given. The height is fixed at 48px by\n * the design: the row has to line up with the other form-height controls.\n */\n width?: TCssLength;\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 * Compact inline media control for audio content: play/pause, elapsed and total\n * time, a seekable timeline, and volume. Four elements in one rounded row, per\n * the design-system anatomy.\n */\nexport const AudioPlayer = ({\n src,\n muted = false,\n loop = false,\n disabled = false,\n width,\n className,\n 'aria-label': ariaLabel = 'Audio player',\n style,\n onPlay,\n onPause,\n onEnded,\n onTimeUpdate,\n ...props\n}: IAudioPlayerProps) => {\n const {\n refMedia,\n playing,\n currentTime,\n duration,\n muted: isMuted,\n toggle,\n seek,\n toggleMute,\n } = useMediaPlayer<HTMLAudioElement>({\n onPlay,\n onPause,\n onEnded,\n onTimeUpdate,\n });\n\n const PlaybackIcon = playing ? IconPlayerPauseFilled : IconPlayerPlayFilled;\n const VolumeIcon = isMuted ? IconVolumeOff : IconVolume;\n\n return (\n // biome-ignore lint/a11y/useSemanticElements: <fieldset> carries form semantics and UA styling this player does not want; role=\"group\" is the correct ARIA for a labelled set of related controls.\n <div\n data-slot=\"audio-player\"\n data-playing={playing || undefined}\n role=\"group\"\n {...props}\n aria-label={ariaLabel}\n style={{ width: cssLength(width), ...style }}\n className={cn('flex h-12 w-full items-center gap-2 rounded-lg bg-muted px-3 py-1.5', className)}\n >\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" disabled={disabled} aria-label={playing ? 'Pause' : 'Play'} onClick={toggle}>\n <PlaybackIcon />\n </Button>\n\n {/* `text-foreground/70` not `text-muted-foreground`: the latter on `bg-muted` is only 4.34:1, below AA. */}\n <span data-slot=\"audio-player-time\" className=\"shrink-0 text-xs tabular-nums text-foreground/70\">\n {formatMediaTime(currentTime)} / {formatMediaTime(duration)}\n </span>\n\n {/* Scope the form-sized Slider down to a timeline: thinner track, smaller thumb, and a track tint that\n reads against this bar (the Slider's default `bg-muted` track is invisible on a `bg-muted` container). */}\n <Slider\n className=\"flex-1 [&_[data-slot=slider-control]]:py-1.5 [&_[data-slot=slider-thumb]]:size-3 [&_[data-slot=slider-track]]:h-1 [&_[data-slot=slider-track]]:bg-foreground/15\"\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 <Button type=\"button\" variant=\"ghost\" size=\"icon\" disabled={disabled} aria-label={isMuted ? 'Unmute' : 'Mute'} onClick={toggleMute}>\n <VolumeIcon />\n </Button>\n\n {/* Visually hidden: the row above is the entire control surface. */}\n {/* No class needed: the UA stylesheet already hides `audio:not([controls])`, and that rule is `!important` so author CSS cannot change it either way. */}\n <audio ref={refMedia} src={src} muted={muted} loop={loop} preload=\"metadata\" />\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;AAqCA,IAAa,eAAe,EAC1B,KACA,QAAQ,OACR,OAAO,OACP,WAAW,OACX,OACA,WACA,cAAc,YAAY,gBAC1B,OACA,QACA,SACA,SACA,cACA,GAAG,YACoB;CACvB,MAAM,EACJ,UACA,SACA,aACA,UACA,OAAO,SACP,QACA,MACA,eACE,eAAiC;EACnC;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,eAAe,UAAU,wBAAwB;CACvD,MAAM,aAAa,UAAU,gBAAgB;CAE7C,OAEE,qBAAC,OAAD;EACE,aAAU;EACV,gBAAc,WAAW,KAAA;EACzB,MAAK;EACL,GAAI;EACJ,cAAY;EACZ,OAAO;GAAE,OAAO,UAAU,KAAK;GAAG,GAAG;EAAM;EAC3C,WAAW,GAAG,uEAAuE,SAAS;EAPhG,UAAA;GASE,oBAAC,QAAD;IAAQ,MAAK;IAAS,SAAQ;IAAQ,MAAK;IAAiB;IAAU,cAAY,UAAU,UAAU;IAAQ,SAAS;IACrH,UAAA,oBAAC,cAAD,CAAe,CAAA;GACT,CAAA;GAGR,qBAAC,QAAD;IAAM,aAAU;IAAoB,WAAU;IAA9C,UAAA;KACG,gBAAgB,WAAW;KAAE;KAAI,gBAAgB,QAAQ;IACtD;;GAIN,oBAAC,QAAD;IACE,WAAU;IACV,OAAO,KAAK,IAAI,aAAa,YAAY,CAAC;IAC1C,KAAK;IACL,KAAK,YAAY;IACjB,MAAM;IACN,UAAU,YAAY,aAAa;IACnC,cAAW;IACX,gBAAgB,SAAS;KACvB,KAAK,IAAI;IACX;GACD,CAAA;GAED,oBAAC,QAAD;IAAQ,MAAK;IAAS,SAAQ;IAAQ,MAAK;IAAiB;IAAU,cAAY,UAAU,WAAW;IAAQ,SAAS;IACtH,UAAA,oBAAC,YAAD,CAAa,CAAA;GACP,CAAA;GAIR,oBAAC,SAAD;IAAO,KAAK;IAAe;IAAY;IAAa;IAAM,SAAQ;GAAY,CAAA;EAC3E;;AAET"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Locale } from 'react-day-picker';
|
|
2
|
+
import { TDisabledDays } from './date-text';
|
|
3
|
+
/** Every word the component prints, so a product can translate it. */
|
|
4
|
+
export interface IDatePickerLabels {
|
|
5
|
+
/** The calendar button's accessible name. */
|
|
6
|
+
choose: string;
|
|
7
|
+
/** Said when the text is not a date; `pattern` is what to type, written the locale's way (`DD/MM/YYYY`). */
|
|
8
|
+
format: (pattern: string) => string;
|
|
9
|
+
notReal: string;
|
|
10
|
+
/** `min` and `max` are written the locale's way. */
|
|
11
|
+
beforeMin: (min: string) => string;
|
|
12
|
+
afterMax: (max: string) => string;
|
|
13
|
+
unavailable: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const DEFAULT_DATE_PICKER_LABELS: IDatePickerLabels;
|
|
16
|
+
/**
|
|
17
|
+
* What the field holds when it reports, so a parent can tell apart things that would otherwise look alike:
|
|
18
|
+
* - `day`: a usable day, typed or picked.
|
|
19
|
+
* - `empty`: the field was emptied, or nothing has been put in it. A required field is right to ask for a date.
|
|
20
|
+
* - `refused`: the field holds text that is not a day (not a day, or not a real one). The day reported is `undefined`.
|
|
21
|
+
* `text` is what was typed and `problem` the message the picker shows under the field, in the picker's `labels`.
|
|
22
|
+
* - `out-of-range`: the field holds a real day that `min`, `max` or `disabledDates` refuse. The day IS reported (as the
|
|
23
|
+
* first argument and as `day`), so a form's own rule can judge it and show its message; the field is marked invalid.
|
|
24
|
+
* Check `kind` before treating the day as a usable one.
|
|
25
|
+
*
|
|
26
|
+
* Inside a Field that renders a FieldError, that message is the only one: the picker does not show its own.
|
|
27
|
+
*/
|
|
28
|
+
export type TDatePickerState = {
|
|
29
|
+
kind: 'day';
|
|
30
|
+
} | {
|
|
31
|
+
kind: 'empty';
|
|
32
|
+
} | {
|
|
33
|
+
kind: 'refused';
|
|
34
|
+
text: string;
|
|
35
|
+
problem: string;
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'out-of-range';
|
|
38
|
+
day: string;
|
|
39
|
+
text: string;
|
|
40
|
+
problem: string;
|
|
41
|
+
};
|
|
42
|
+
export interface IDatePickerProps {
|
|
43
|
+
/** For a Label's htmlFor; inside a Field the Field's label is already wired. */
|
|
44
|
+
id?: string;
|
|
45
|
+
/**
|
|
46
|
+
* The chosen day as `yyyy-mm-dd`, or `undefined` for none (an empty string counts as none, so a value kept for an
|
|
47
|
+
* `<input type="date">` drops in). A string and not a Date, on purpose: a Date is an instant, and the instant for
|
|
48
|
+
* "5 March" is another calendar day in another time zone, so a Date serialised for an API drifts a day. The text is
|
|
49
|
+
* what `<input type="date">`, JSON and a .NET `DateOnly` use, and it compares as a day.
|
|
50
|
+
*/
|
|
51
|
+
value: string | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Called with a valid day, or with `undefined` when the field is emptied or its text is not a usable day. The second
|
|
54
|
+
* argument says which of the two it was (see `TDatePickerState`); a caller that has no use for it can ignore it.
|
|
55
|
+
* Text that is refused is reported each time it changes, also when the field held no day before, so a form that
|
|
56
|
+
* tracks the state hears about it. Emptying the field after that reports `empty`.
|
|
57
|
+
*/
|
|
58
|
+
onValueChange: (value: string | undefined, state: TDatePickerState) => void;
|
|
59
|
+
/** The earliest and latest day that can be chosen, as `yyyy-mm-dd`, both included. */
|
|
60
|
+
min?: string;
|
|
61
|
+
max?: string;
|
|
62
|
+
/** Days that cannot be chosen: a list of `yyyy-mm-dd`, or a function that says so for one (weekends, say). */
|
|
63
|
+
disabledDates?: TDisabledDays;
|
|
64
|
+
disabled?: boolean;
|
|
65
|
+
/** How a day is written and in which order it is typed (BCP 47); en-GB reads 05/03/2026. */
|
|
66
|
+
locale?: string;
|
|
67
|
+
/** The calendar's own words (month and weekday names), as a date-fns locale; English by default. The first weekday follows `locale`. */
|
|
68
|
+
calendarLocale?: Locale;
|
|
69
|
+
/** What the empty field shows; the pattern for the locale (`DD/MM/YYYY`) by default. */
|
|
70
|
+
placeholder?: string;
|
|
71
|
+
/** An accessible name, when there is no visible label to point at. */
|
|
72
|
+
'aria-label'?: string;
|
|
73
|
+
/** Marks the field invalid (the kit's destructive border), as a Field's invalid state does. */
|
|
74
|
+
'aria-invalid'?: boolean | 'true' | 'false';
|
|
75
|
+
/** The id of the text that explains it. Added to what a Field names already, and to the picker's own error. */
|
|
76
|
+
'aria-describedby'?: string;
|
|
77
|
+
labels?: Partial<IDatePickerLabels>;
|
|
78
|
+
/** Layout only (a width); the look is the kit's. */
|
|
79
|
+
className?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* One calendar day, typed or picked. The field takes the day in the locale's order (05/03/2026 in en-GB) and reads it
|
|
83
|
+
* when it loses focus, saying inline what is wrong with it; the button, or Alt+ArrowDown in the field, opens a calendar.
|
|
84
|
+
* Escape closes the calendar and gives the focus back to whichever of the two opened it; a day picked puts it on the field.
|
|
85
|
+
*/
|
|
86
|
+
export declare const DatePicker: ({ id, value, onValueChange, min, max, disabledDates, disabled, locale, calendarLocale, placeholder, "aria-label": ariaLabel, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy, labels: labelOverrides, className, }: IDatePickerProps) => import('react').JSX.Element;
|