bits-ui 1.8.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bits/accordion/accordion.svelte.d.ts +56 -53
- package/dist/bits/accordion/accordion.svelte.js +78 -89
- package/dist/bits/accordion/components/accordion-content.svelte +5 -3
- package/dist/bits/accordion/components/accordion-header.svelte +4 -2
- package/dist/bits/accordion/components/accordion-item.svelte +6 -3
- package/dist/bits/accordion/components/accordion-trigger.svelte +4 -2
- package/dist/bits/accordion/components/accordion.svelte +4 -2
- package/dist/bits/alert-dialog/components/alert-dialog-action.svelte +4 -2
- package/dist/bits/alert-dialog/components/alert-dialog-cancel.svelte +4 -2
- package/dist/bits/alert-dialog/components/alert-dialog-content.svelte +8 -3
- package/dist/bits/aspect-ratio/aspect-ratio.svelte.js +2 -2
- package/dist/bits/aspect-ratio/components/aspect-ratio.svelte +4 -2
- package/dist/bits/avatar/avatar.svelte.d.ts +2 -1
- package/dist/bits/avatar/avatar.svelte.js +8 -6
- package/dist/bits/avatar/components/avatar-fallback.svelte +4 -2
- package/dist/bits/avatar/components/avatar-image.svelte +4 -2
- package/dist/bits/avatar/components/avatar.svelte +4 -2
- package/dist/bits/button/components/button.svelte +1 -1
- package/dist/bits/calendar/calendar.svelte.d.ts +3 -9
- package/dist/bits/calendar/calendar.svelte.js +55 -41
- package/dist/bits/calendar/components/calendar-cell.svelte +4 -2
- package/dist/bits/calendar/components/calendar-day.svelte +4 -2
- package/dist/bits/calendar/components/calendar-grid-body.svelte +4 -2
- package/dist/bits/calendar/components/calendar-grid-head.svelte +4 -2
- package/dist/bits/calendar/components/calendar-grid-row.svelte +4 -2
- package/dist/bits/calendar/components/calendar-grid.svelte +4 -2
- package/dist/bits/calendar/components/calendar-head-cell.svelte +4 -2
- package/dist/bits/calendar/components/calendar-header.svelte +4 -2
- package/dist/bits/calendar/components/calendar-heading.svelte +4 -2
- package/dist/bits/calendar/components/calendar-next-button.svelte +4 -2
- package/dist/bits/calendar/components/calendar-prev-button.svelte +4 -2
- package/dist/bits/checkbox/checkbox.svelte.js +4 -14
- package/dist/bits/checkbox/components/checkbox-group-label.svelte +4 -2
- package/dist/bits/checkbox/components/checkbox-group.svelte +4 -2
- package/dist/bits/checkbox/components/checkbox.svelte +4 -2
- package/dist/bits/collapsible/collapsible.svelte.js +4 -10
- package/dist/bits/collapsible/components/collapsible-content.svelte +5 -3
- package/dist/bits/collapsible/components/collapsible-trigger.svelte +4 -2
- package/dist/bits/collapsible/components/collapsible.svelte +4 -2
- package/dist/bits/combobox/components/combobox-input.svelte +3 -3
- package/dist/bits/combobox/components/combobox.svelte +6 -1
- package/dist/bits/combobox/types.d.ts +18 -1
- package/dist/bits/command/command.svelte.js +13 -45
- package/dist/bits/command/components/_command-label.svelte +6 -7
- package/dist/bits/command/components/_command-label.svelte.d.ts +1 -1
- package/dist/bits/command/components/command-empty.svelte +4 -2
- package/dist/bits/command/components/command-group-heading.svelte +4 -2
- package/dist/bits/command/components/command-group-items.svelte +4 -2
- package/dist/bits/command/components/command-group.svelte +4 -2
- package/dist/bits/command/components/command-input.svelte +4 -2
- package/dist/bits/command/components/command-item.svelte +4 -2
- package/dist/bits/command/components/command-link-item.svelte +4 -2
- package/dist/bits/command/components/command-list.svelte +4 -2
- package/dist/bits/command/components/command-loading.svelte +4 -2
- package/dist/bits/command/components/command-separator.svelte +4 -2
- package/dist/bits/command/components/command-viewport.svelte +4 -2
- package/dist/bits/command/components/command.svelte +4 -2
- package/dist/bits/context-menu/components/context-menu-content-static.svelte +2 -3
- package/dist/bits/context-menu/components/context-menu-content.svelte +2 -3
- package/dist/bits/context-menu/components/context-menu-trigger.svelte +1 -1
- package/dist/bits/date-field/components/date-field-input.svelte +4 -2
- package/dist/bits/date-field/components/date-field-label.svelte +4 -2
- package/dist/bits/date-field/components/date-field-segment.svelte +4 -2
- package/dist/bits/date-field/date-field.svelte.d.ts +7 -5
- package/dist/bits/date-field/date-field.svelte.js +29 -38
- package/dist/bits/date-picker/components/date-picker-calendar.svelte +4 -2
- package/dist/bits/date-range-field/components/date-range-field-input.svelte +4 -2
- package/dist/bits/date-range-field/components/date-range-field-label.svelte +4 -2
- package/dist/bits/date-range-field/components/date-range-field.svelte +4 -2
- package/dist/bits/date-range-field/date-range-field.svelte.d.ts +2 -0
- package/dist/bits/date-range-field/date-range-field.svelte.js +6 -14
- package/dist/bits/date-range-picker/components/date-range-picker-calendar.svelte +4 -2
- package/dist/bits/dialog/components/dialog-close.svelte +4 -2
- package/dist/bits/dialog/components/dialog-content.svelte +8 -2
- package/dist/bits/dialog/components/dialog-description.svelte +4 -2
- package/dist/bits/dialog/components/dialog-overlay.svelte +8 -3
- package/dist/bits/dialog/components/dialog-title.svelte +4 -2
- package/dist/bits/dialog/components/dialog-trigger.svelte +4 -2
- package/dist/bits/dialog/dialog.svelte.d.ts +1 -1
- package/dist/bits/dialog/dialog.svelte.js +19 -47
- package/dist/bits/dropdown-menu/components/dropdown-menu-content-static.svelte +6 -5
- package/dist/bits/dropdown-menu/components/dropdown-menu-content.svelte +6 -5
- package/dist/bits/index.d.ts +2 -0
- package/dist/bits/index.js +2 -0
- package/dist/bits/label/components/label.svelte +4 -2
- package/dist/bits/label/label.svelte.js +2 -2
- package/dist/bits/link-preview/components/link-preview-content-static.svelte +6 -2
- package/dist/bits/link-preview/components/link-preview-content.svelte +6 -2
- package/dist/bits/link-preview/components/link-preview-trigger.svelte +5 -3
- package/dist/bits/link-preview/link-preview.svelte.d.ts +2 -0
- package/dist/bits/link-preview/link-preview.svelte.js +13 -19
- package/dist/bits/menu/components/menu-checkbox-group.svelte +4 -2
- package/dist/bits/menu/components/menu-checkbox-item.svelte +6 -4
- package/dist/bits/menu/components/menu-content-static.svelte +6 -5
- package/dist/bits/menu/components/menu-content.svelte +6 -5
- package/dist/bits/menu/components/menu-group-heading.svelte +4 -2
- package/dist/bits/menu/components/menu-group.svelte +4 -2
- package/dist/bits/menu/components/menu-item.svelte +4 -2
- package/dist/bits/menu/components/menu-radio-group.svelte +4 -2
- package/dist/bits/menu/components/menu-radio-item.svelte +4 -2
- package/dist/bits/menu/components/menu-separator.svelte +4 -2
- package/dist/bits/menu/components/menu-sub-content-static.svelte +6 -5
- package/dist/bits/menu/components/menu-sub-content.svelte +6 -5
- package/dist/bits/menu/components/menu-sub-trigger.svelte +6 -3
- package/dist/bits/menu/components/menu-trigger.svelte +5 -3
- package/dist/bits/menu/menu.svelte.d.ts +9 -20
- package/dist/bits/menu/menu.svelte.js +40 -63
- package/dist/bits/menubar/components/menubar-content-static.svelte +4 -2
- package/dist/bits/menubar/components/menubar-content.svelte +4 -2
- package/dist/bits/menubar/components/menubar-menu.svelte +4 -2
- package/dist/bits/menubar/components/menubar-trigger.svelte +14 -6
- package/dist/bits/menubar/components/menubar.svelte +4 -2
- package/dist/bits/menubar/menubar.svelte.d.ts +24 -20
- package/dist/bits/menubar/menubar.svelte.js +40 -56
- package/dist/bits/meter/components/meter.svelte +4 -2
- package/dist/bits/meter/meter.svelte.js +2 -2
- package/dist/bits/navigation-menu/components/navigation-menu-content-impl.svelte +5 -2
- package/dist/bits/navigation-menu/components/navigation-menu-content.svelte +8 -3
- package/dist/bits/navigation-menu/components/navigation-menu-indicator-impl.svelte +4 -2
- package/dist/bits/navigation-menu/components/navigation-menu-indicator.svelte +6 -4
- package/dist/bits/navigation-menu/components/navigation-menu-item.svelte +6 -3
- package/dist/bits/navigation-menu/components/navigation-menu-link.svelte +4 -2
- package/dist/bits/navigation-menu/components/navigation-menu-list.svelte +4 -2
- package/dist/bits/navigation-menu/components/navigation-menu-sub.svelte +4 -2
- package/dist/bits/navigation-menu/components/navigation-menu-trigger.svelte +4 -2
- package/dist/bits/navigation-menu/components/navigation-menu-viewport.svelte +5 -3
- package/dist/bits/navigation-menu/components/navigation-menu.svelte +4 -2
- package/dist/bits/navigation-menu/navigation-menu.svelte.d.ts +3 -1
- package/dist/bits/navigation-menu/navigation-menu.svelte.js +33 -60
- package/dist/bits/pagination/components/pagination-next-button.svelte +4 -2
- package/dist/bits/pagination/components/pagination-page.svelte +4 -2
- package/dist/bits/pagination/components/pagination-prev-button.svelte +4 -2
- package/dist/bits/pagination/components/pagination.svelte +4 -2
- package/dist/bits/pagination/pagination.svelte.js +4 -4
- package/dist/bits/pin-input/components/pin-input-cell.svelte +4 -2
- package/dist/bits/pin-input/components/pin-input.svelte +5 -3
- package/dist/bits/pin-input/pin-input.svelte.d.ts +4 -2
- package/dist/bits/pin-input/pin-input.svelte.js +20 -22
- package/dist/bits/pin-input/usePasswordManager.svelte.d.ts +3 -2
- package/dist/bits/pin-input/usePasswordManager.svelte.js +6 -5
- package/dist/bits/popover/components/popover-close.svelte +4 -2
- package/dist/bits/popover/components/popover-content-static.svelte +6 -2
- package/dist/bits/popover/components/popover-content.svelte +6 -2
- package/dist/bits/popover/components/popover-trigger.svelte +5 -3
- package/dist/bits/popover/popover.svelte.js +4 -18
- package/dist/bits/progress/components/progress.svelte +4 -2
- package/dist/bits/progress/progress.svelte.js +2 -2
- package/dist/bits/radio-group/components/radio-group-item.svelte +4 -2
- package/dist/bits/radio-group/components/radio-group.svelte +4 -2
- package/dist/bits/radio-group/radio-group.svelte.js +4 -7
- package/dist/bits/range-calendar/components/range-calendar-cell.svelte +4 -2
- package/dist/bits/range-calendar/components/range-calendar-day.svelte +4 -2
- package/dist/bits/range-calendar/components/range-calendar.svelte +4 -2
- package/dist/bits/range-calendar/range-calendar.svelte.d.ts +2 -0
- package/dist/bits/range-calendar/range-calendar.svelte.js +12 -6
- package/dist/bits/scroll-area/components/scroll-area-corner.svelte +8 -2
- package/dist/bits/scroll-area/components/scroll-area-scrollbar-auto.svelte +4 -1
- package/dist/bits/scroll-area/components/scroll-area-scrollbar-hover.svelte +1 -1
- package/dist/bits/scroll-area/components/scroll-area-scrollbar-scroll.svelte +5 -1
- package/dist/bits/scroll-area/components/scroll-area-scrollbar.svelte +4 -2
- package/dist/bits/scroll-area/components/scroll-area-thumb.svelte +8 -3
- package/dist/bits/scroll-area/components/scroll-area-viewport.svelte +4 -2
- package/dist/bits/scroll-area/components/scroll-area.svelte +4 -2
- package/dist/bits/scroll-area/scroll-area.svelte.d.ts +2 -0
- package/dist/bits/scroll-area/scroll-area.svelte.js +27 -58
- package/dist/bits/select/components/select-content-static.svelte +6 -2
- package/dist/bits/select/components/select-content.svelte +6 -2
- package/dist/bits/select/components/select-group-heading.svelte +3 -2
- package/dist/bits/select/components/select-group.svelte +4 -2
- package/dist/bits/select/components/select-item.svelte +4 -2
- package/dist/bits/select/components/select-scroll-down-button.svelte +4 -2
- package/dist/bits/select/components/select-scroll-up-button.svelte +4 -2
- package/dist/bits/select/components/select-trigger.svelte +5 -3
- package/dist/bits/select/components/select-viewport.svelte +4 -2
- package/dist/bits/select/components/select.svelte +7 -1
- package/dist/bits/select/select.svelte.d.ts +5 -19
- package/dist/bits/select/select.svelte.js +43 -60
- package/dist/bits/separator/components/separator.svelte +4 -2
- package/dist/bits/separator/separator.svelte.js +2 -2
- package/dist/bits/slider/components/slider-range.svelte +4 -2
- package/dist/bits/slider/components/slider-thumb-label.svelte +50 -0
- package/dist/bits/slider/components/slider-thumb-label.svelte.d.ts +4 -0
- package/dist/bits/slider/components/slider-thumb.svelte +4 -2
- package/dist/bits/slider/components/slider-tick-label.svelte +50 -0
- package/dist/bits/slider/components/slider-tick-label.svelte.d.ts +4 -0
- package/dist/bits/slider/components/slider-tick.svelte +4 -2
- package/dist/bits/slider/components/slider.svelte +24 -5
- package/dist/bits/slider/exports.d.ts +3 -1
- package/dist/bits/slider/exports.js +2 -0
- package/dist/bits/slider/helpers.d.ts +14 -0
- package/dist/bits/slider/helpers.js +122 -0
- package/dist/bits/slider/slider.svelte.d.ts +91 -5
- package/dist/bits/slider/slider.svelte.js +194 -101
- package/dist/bits/slider/types.d.ts +105 -11
- package/dist/bits/switch/components/switch-thumb.svelte +4 -2
- package/dist/bits/switch/components/switch.svelte +4 -2
- package/dist/bits/switch/switch.svelte.js +3 -3
- package/dist/bits/tabs/components/tabs-content.svelte +4 -2
- package/dist/bits/tabs/components/tabs-list.svelte +4 -2
- package/dist/bits/tabs/components/tabs-trigger.svelte +4 -2
- package/dist/bits/tabs/components/tabs.svelte +4 -2
- package/dist/bits/tabs/tabs.svelte.js +6 -6
- package/dist/bits/time-field/components/time-field-hidden-input.svelte +10 -0
- package/dist/bits/{date-field/components/date-field-error.svelte.d.ts → time-field/components/time-field-hidden-input.svelte.d.ts} +6 -14
- package/dist/bits/time-field/components/time-field-input.svelte +39 -0
- package/dist/bits/time-field/components/time-field-input.svelte.d.ts +4 -0
- package/dist/bits/time-field/components/time-field-label.svelte +34 -0
- package/dist/bits/time-field/components/time-field-label.svelte.d.ts +4 -0
- package/dist/bits/time-field/components/time-field-segment.svelte +37 -0
- package/dist/bits/time-field/components/time-field-segment.svelte.d.ts +4 -0
- package/dist/bits/time-field/components/time-field.svelte +94 -0
- package/dist/bits/time-field/components/time-field.svelte.d.ts +20 -0
- package/dist/bits/time-field/exports.d.ts +5 -0
- package/dist/bits/time-field/exports.js +4 -0
- package/dist/bits/time-field/index.d.ts +1 -0
- package/dist/bits/time-field/index.js +1 -0
- package/dist/bits/time-field/time-field.svelte.d.ts +417 -0
- package/dist/bits/time-field/time-field.svelte.js +980 -0
- package/dist/bits/time-field/types.d.ts +137 -0
- package/dist/bits/time-field/types.js +1 -0
- package/dist/bits/time-range-field/components/time-range-field-input.svelte +43 -0
- package/dist/bits/time-range-field/components/time-range-field-input.svelte.d.ts +4 -0
- package/dist/bits/time-range-field/components/time-range-field-label.svelte +34 -0
- package/dist/bits/time-range-field/components/time-range-field-label.svelte.d.ts +4 -0
- package/dist/bits/time-range-field/components/time-range-field.svelte +144 -0
- package/dist/bits/time-range-field/components/time-range-field.svelte.d.ts +20 -0
- package/dist/bits/time-range-field/exports.d.ts +5 -0
- package/dist/bits/time-range-field/exports.js +4 -0
- package/dist/bits/time-range-field/index.d.ts +1 -0
- package/dist/bits/time-range-field/index.js +1 -0
- package/dist/bits/time-range-field/time-range-field.svelte.d.ts +92 -0
- package/dist/bits/time-range-field/time-range-field.svelte.js +212 -0
- package/dist/bits/time-range-field/types.d.ts +150 -0
- package/dist/bits/time-range-field/types.js +1 -0
- package/dist/bits/toggle/components/toggle.svelte +4 -2
- package/dist/bits/toggle/toggle.svelte.js +2 -2
- package/dist/bits/toggle-group/components/toggle-group-item.svelte +4 -2
- package/dist/bits/toggle-group/components/toggle-group.svelte +4 -2
- package/dist/bits/toggle-group/toggle-group.svelte.js +4 -4
- package/dist/bits/toolbar/components/toolbar-button.svelte +4 -2
- package/dist/bits/toolbar/components/toolbar-group-item.svelte +4 -2
- package/dist/bits/toolbar/components/toolbar-group.svelte +4 -2
- package/dist/bits/toolbar/components/toolbar-link.svelte +4 -2
- package/dist/bits/toolbar/components/toolbar.svelte +4 -2
- package/dist/bits/toolbar/toolbar.svelte.js +7 -7
- package/dist/bits/tooltip/components/tooltip-content-static.svelte +6 -2
- package/dist/bits/tooltip/components/tooltip-content.svelte +6 -2
- package/dist/bits/tooltip/components/tooltip-trigger.svelte +5 -3
- package/dist/bits/tooltip/tooltip.svelte.d.ts +2 -0
- package/dist/bits/tooltip/tooltip.svelte.js +6 -15
- package/dist/bits/utilities/dismissible-layer/dismissible-layer.svelte +2 -0
- package/dist/bits/utilities/dismissible-layer/types.d.ts +2 -0
- package/dist/bits/utilities/dismissible-layer/use-dismissable-layer.svelte.d.ts +3 -3
- package/dist/bits/utilities/dismissible-layer/use-dismissable-layer.svelte.js +16 -25
- package/dist/bits/utilities/floating-layer/components/floating-layer-anchor.svelte +2 -1
- package/dist/bits/utilities/floating-layer/types.d.ts +1 -0
- package/dist/bits/utilities/floating-layer/use-floating-layer.svelte.d.ts +3 -2
- package/dist/bits/utilities/floating-layer/use-floating-layer.svelte.js +7 -27
- package/dist/bits/utilities/focus-scope/focus-scope.svelte +2 -0
- package/dist/bits/utilities/focus-scope/types.d.ts +2 -0
- package/dist/bits/utilities/focus-scope/use-focus-scope.svelte.d.ts +2 -1
- package/dist/bits/utilities/focus-scope/use-focus-scope.svelte.js +15 -16
- package/dist/bits/utilities/popper-layer/popper-layer-inner.svelte +4 -0
- package/dist/bits/utilities/popper-layer/popper-layer.svelte +3 -1
- package/dist/bits/utilities/portal/types.d.ts +1 -1
- package/dist/bits/utilities/presence-layer/presence-layer.svelte +2 -2
- package/dist/bits/utilities/presence-layer/types.d.ts +2 -1
- package/dist/bits/utilities/presence-layer/use-presence.svelte.d.ts +1 -1
- package/dist/bits/utilities/presence-layer/use-presence.svelte.js +19 -36
- package/dist/bits/utilities/text-selection-layer/text-selection-layer.svelte +2 -0
- package/dist/bits/utilities/text-selection-layer/types.d.ts +2 -0
- package/dist/bits/utilities/text-selection-layer/use-text-selection-layer.svelte.d.ts +5 -1
- package/dist/bits/utilities/text-selection-layer/use-text-selection-layer.svelte.js +8 -14
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/box-auto-reset.svelte.d.ts +7 -1
- package/dist/internal/box-auto-reset.svelte.js +11 -6
- package/dist/internal/create-id.d.ts +8 -0
- package/dist/internal/create-id.js +5 -0
- package/dist/internal/date-time/announcer.d.ts +1 -1
- package/dist/internal/date-time/announcer.js +20 -20
- package/dist/internal/date-time/calendar-helpers.svelte.js +7 -5
- package/dist/internal/date-time/field/helpers.d.ts +9 -2
- package/dist/internal/date-time/field/helpers.js +16 -9
- package/dist/internal/date-time/field/parts.d.ts +3 -1
- package/dist/internal/date-time/field/parts.js +10 -2
- package/dist/internal/date-time/field/segments.d.ts +9 -0
- package/dist/internal/date-time/field/segments.js +65 -0
- package/dist/internal/date-time/field/time-helpers.d.ts +83 -0
- package/dist/internal/date-time/field/time-helpers.js +301 -0
- package/dist/internal/date-time/field/types.d.ts +2 -2
- package/dist/internal/date-time/formatter.d.ts +11 -1
- package/dist/internal/date-time/formatter.js +56 -0
- package/dist/internal/date-time/utils.d.ts +7 -2
- package/dist/internal/date-time/utils.js +15 -1
- package/dist/internal/dom.d.ts +0 -1
- package/dist/internal/dom.js +0 -3
- package/dist/internal/focus.d.ts +2 -2
- package/dist/internal/focus.js +14 -9
- package/dist/internal/math.d.ts +0 -4
- package/dist/internal/math.js +0 -28
- package/dist/internal/tabbable.d.ts +0 -2
- package/dist/internal/tabbable.js +10 -14
- package/dist/internal/use-data-typeahead.svelte.d.ts +1 -0
- package/dist/internal/use-data-typeahead.svelte.js +4 -1
- package/dist/internal/use-dom-typeahead.svelte.d.ts +3 -1
- package/dist/internal/use-dom-typeahead.svelte.js +5 -2
- package/dist/internal/use-grace-area.svelte.js +9 -5
- package/dist/internal/use-roving-focus.svelte.d.ts +3 -3
- package/dist/internal/use-roving-focus.svelte.js +10 -11
- package/dist/shared/date/types.d.ts +27 -4
- package/dist/shared/index.d.ts +2 -2
- package/dist/types.d.ts +2 -0
- package/package.json +18 -16
- package/dist/bits/date-field/components/date-field-error.svelte +0 -0
- package/dist/internal/use-size.svelte.d.ts +0 -7
- package/dist/internal/use-size.svelte.js +0 -54
|
@@ -23,6 +23,22 @@ export function handleSegmentNavigation(e, fieldNode) {
|
|
|
23
23
|
next.focus();
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
+
export function handleTimeSegmentNavigation(e, fieldNode) {
|
|
27
|
+
const currentTarget = e.currentTarget;
|
|
28
|
+
if (!isHTMLElement(currentTarget))
|
|
29
|
+
return;
|
|
30
|
+
const { prev, next } = getPrevNextTimeSegments(currentTarget, fieldNode);
|
|
31
|
+
if (e.key === kbd.ARROW_LEFT) {
|
|
32
|
+
if (!prev)
|
|
33
|
+
return;
|
|
34
|
+
prev.focus();
|
|
35
|
+
}
|
|
36
|
+
else if (e.key === kbd.ARROW_RIGHT) {
|
|
37
|
+
if (!next)
|
|
38
|
+
return;
|
|
39
|
+
next.focus();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
26
42
|
/**
|
|
27
43
|
* Retrieves the next segment in the list of segments relative to the provided node.
|
|
28
44
|
*
|
|
@@ -70,6 +86,19 @@ export function getPrevNextSegments(startingNode, fieldNode) {
|
|
|
70
86
|
prev: getPrevSegment(startingNode, segments),
|
|
71
87
|
};
|
|
72
88
|
}
|
|
89
|
+
export function getPrevNextTimeSegments(startingNode, fieldNode) {
|
|
90
|
+
const segments = getTimeSegments(fieldNode);
|
|
91
|
+
if (!segments.length) {
|
|
92
|
+
return {
|
|
93
|
+
next: null,
|
|
94
|
+
prev: null,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
next: getNextSegment(startingNode, segments),
|
|
99
|
+
prev: getPrevSegment(startingNode, segments),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
73
102
|
/**
|
|
74
103
|
* Shifts the focus to the next segment in the list of segments
|
|
75
104
|
* within the field identified by the provided ID.
|
|
@@ -83,6 +112,24 @@ export function moveToNextSegment(e, fieldNode) {
|
|
|
83
112
|
return;
|
|
84
113
|
next.focus();
|
|
85
114
|
}
|
|
115
|
+
export function moveToNextTimeSegment(e, fieldNode) {
|
|
116
|
+
const node = e.currentTarget;
|
|
117
|
+
if (!isHTMLElement(node))
|
|
118
|
+
return;
|
|
119
|
+
const { next } = getPrevNextTimeSegments(node, fieldNode);
|
|
120
|
+
if (!next)
|
|
121
|
+
return;
|
|
122
|
+
next.focus();
|
|
123
|
+
}
|
|
124
|
+
export function moveToPrevTimeSegment(e, fieldNode) {
|
|
125
|
+
const node = e.currentTarget;
|
|
126
|
+
if (!isHTMLElement(node))
|
|
127
|
+
return;
|
|
128
|
+
const { prev } = getPrevNextTimeSegments(node, fieldNode);
|
|
129
|
+
if (!prev)
|
|
130
|
+
return;
|
|
131
|
+
prev.focus();
|
|
132
|
+
}
|
|
86
133
|
/**
|
|
87
134
|
* Shifts the focus to the previous segment in the list of segments
|
|
88
135
|
* within the field identified by the provided ID. If this is the first
|
|
@@ -120,6 +167,24 @@ export function getSegments(fieldNode) {
|
|
|
120
167
|
});
|
|
121
168
|
return segments;
|
|
122
169
|
}
|
|
170
|
+
export function getTimeSegments(fieldNode) {
|
|
171
|
+
if (!fieldNode)
|
|
172
|
+
return [];
|
|
173
|
+
const segments = Array.from(fieldNode.querySelectorAll("[data-segment]")).filter((el) => {
|
|
174
|
+
if (!isHTMLElement(el))
|
|
175
|
+
return false;
|
|
176
|
+
const segment = el.dataset.segment;
|
|
177
|
+
if (segment === "trigger")
|
|
178
|
+
return true;
|
|
179
|
+
if (segment === "literal")
|
|
180
|
+
return false;
|
|
181
|
+
return true;
|
|
182
|
+
});
|
|
183
|
+
return segments;
|
|
184
|
+
}
|
|
185
|
+
export function getFirstTimeSegment(fieldNode) {
|
|
186
|
+
return getTimeSegments(fieldNode)[0];
|
|
187
|
+
}
|
|
123
188
|
/**
|
|
124
189
|
* Get the first interactive segment within the field identified by the provided ID.
|
|
125
190
|
*/
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { EditableTimeSegmentPart, HourCycle, TimeGranularity, TimeSegmentContentObj, TimeSegmentStateMap, TimeSegmentValueObj, TimeValue } from "../../../shared/date/types.js";
|
|
2
|
+
import { CalendarDateTime, Time, ZonedDateTime } from "@internationalized/date";
|
|
3
|
+
import type { TimeFormatter } from "../formatter.js";
|
|
4
|
+
import type { TimeSegmentPart } from "./types.js";
|
|
5
|
+
export declare function initializeSegmentValues(): TimeSegmentValueObj;
|
|
6
|
+
type SharedTimeContentProps = {
|
|
7
|
+
granularity: TimeGranularity;
|
|
8
|
+
timeRef: TimeValue;
|
|
9
|
+
formatter: TimeFormatter;
|
|
10
|
+
hideTimeZone: boolean;
|
|
11
|
+
hourCycle: HourCycle | undefined;
|
|
12
|
+
};
|
|
13
|
+
type CreateTimeContentObjProps = SharedTimeContentProps & {
|
|
14
|
+
segmentValues: TimeSegmentValueObj;
|
|
15
|
+
locale: string;
|
|
16
|
+
};
|
|
17
|
+
type CreateTimeContentProps = CreateTimeContentObjProps;
|
|
18
|
+
export declare function createTimeContent(props: CreateTimeContentProps): {
|
|
19
|
+
obj: TimeSegmentContentObj;
|
|
20
|
+
arr: {
|
|
21
|
+
part: TimeSegmentPart;
|
|
22
|
+
value: string;
|
|
23
|
+
}[];
|
|
24
|
+
};
|
|
25
|
+
export declare function initTimeSegmentStates(): TimeSegmentStateMap;
|
|
26
|
+
export declare function initTimeSegmentIds(): any;
|
|
27
|
+
export declare function isEditableTimeSegmentPart(part: unknown): part is EditableTimeSegmentPart;
|
|
28
|
+
export declare function isAnyTimeSegmentPart(part: unknown): part is TimeSegmentPart;
|
|
29
|
+
type GetTimeValueFromSegments<T extends TimeValue = Time> = {
|
|
30
|
+
segmentObj: TimeSegmentValueObj;
|
|
31
|
+
fieldNode: HTMLElement | null;
|
|
32
|
+
timeRef: T;
|
|
33
|
+
};
|
|
34
|
+
export declare function getTimeValueFromSegments<T extends TimeValue = Time>(props: GetTimeValueFromSegments<T>): T;
|
|
35
|
+
/**
|
|
36
|
+
* Check if all the segments being used have been filled.
|
|
37
|
+
* We use this to determine when we should set the value
|
|
38
|
+
* store of the date field(s).
|
|
39
|
+
*
|
|
40
|
+
* @param segmentValues - The current `SegmentValueObj`
|
|
41
|
+
* @param fieldNode - The id of the date field
|
|
42
|
+
*/
|
|
43
|
+
export declare function areAllTimeSegmentsFilled(segmentValues: TimeSegmentValueObj, fieldNode: HTMLElement | null): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Infer the granularity to use based on the
|
|
46
|
+
* value and granularity props.
|
|
47
|
+
*/
|
|
48
|
+
export declare function inferTimeGranularity(granularity: TimeGranularity | undefined): TimeGranularity;
|
|
49
|
+
/**
|
|
50
|
+
* Determines if the element with the provided id is the first focusable
|
|
51
|
+
* segment in the date field with the provided fieldId.
|
|
52
|
+
*
|
|
53
|
+
* @param id - The id of the element to check if it's the first segment
|
|
54
|
+
* @param fieldNode - The id of the date field associated with the segment
|
|
55
|
+
*/
|
|
56
|
+
export declare function isFirstTimeSegment(id: string, fieldNode: HTMLElement | null): boolean;
|
|
57
|
+
type SetTimeDescriptionProps = {
|
|
58
|
+
id: string;
|
|
59
|
+
formatter: TimeFormatter;
|
|
60
|
+
value: TimeValue;
|
|
61
|
+
doc: Document;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Creates or updates a description element for a date field
|
|
65
|
+
* which enables screen readers to read the date field's value.
|
|
66
|
+
*
|
|
67
|
+
* This element is hidden from view, and is portalled to the body
|
|
68
|
+
* so it can be associated via `aria-describedby` and read by
|
|
69
|
+
* screen readers as the user interacts with the date field.
|
|
70
|
+
*/
|
|
71
|
+
export declare function setTimeDescription(props: SetTimeDescriptionProps): void;
|
|
72
|
+
/**
|
|
73
|
+
* Removes the description element for the date field with
|
|
74
|
+
* the provided ID. This function should be called when the
|
|
75
|
+
* date field is unmounted.
|
|
76
|
+
*/
|
|
77
|
+
export declare function removeTimeDescriptionElement(id: string, doc: Document): void;
|
|
78
|
+
export declare function convertTimeValueToDateValue(time: TimeValue): CalendarDateTime | ZonedDateTime;
|
|
79
|
+
export declare function convertTimeValueToTime(time: TimeValue): Time;
|
|
80
|
+
export declare function isTimeBefore(timeToCompare: Time, referenceTime: Time): boolean;
|
|
81
|
+
export declare function isTimeAfter(timeToCompare: Time, referenceTime: Time): boolean;
|
|
82
|
+
export declare function getISOTimeValue(time: TimeValue): string;
|
|
83
|
+
export {};
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { isBrowser, isNull } from "../../is.js";
|
|
2
|
+
import { CalendarDateTime, Time, ZonedDateTime } from "@internationalized/date";
|
|
3
|
+
import { ALL_TIME_SEGMENT_PARTS, EDITABLE_TIME_SEGMENT_PARTS } from "./parts.js";
|
|
4
|
+
import { getTimeSegments } from "./segments.js";
|
|
5
|
+
import { styleToString } from "svelte-toolbelt";
|
|
6
|
+
import { useId } from "../../use-id.js";
|
|
7
|
+
import { getPlaceholder } from "../placeholders.js";
|
|
8
|
+
import { isZonedDateTime } from "../utils.js";
|
|
9
|
+
export function initializeSegmentValues() {
|
|
10
|
+
const initialParts = EDITABLE_TIME_SEGMENT_PARTS.map((part) => {
|
|
11
|
+
if (part === "dayPeriod") {
|
|
12
|
+
return [part, "AM"];
|
|
13
|
+
}
|
|
14
|
+
return [part, null];
|
|
15
|
+
}).filter(([key]) => {
|
|
16
|
+
if (key === "literal" || key === null)
|
|
17
|
+
return false;
|
|
18
|
+
return true;
|
|
19
|
+
});
|
|
20
|
+
return Object.fromEntries(initialParts);
|
|
21
|
+
}
|
|
22
|
+
function createTimeContentObj(props) {
|
|
23
|
+
const { segmentValues, formatter, locale, timeRef } = props;
|
|
24
|
+
const content = Object.keys(segmentValues).reduce((obj, part) => {
|
|
25
|
+
if (!isEditableTimeSegmentPart(part))
|
|
26
|
+
return obj;
|
|
27
|
+
if (part === "dayPeriod") {
|
|
28
|
+
const value = segmentValues[part];
|
|
29
|
+
if (!isNull(value)) {
|
|
30
|
+
obj[part] = value;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
obj[part] = getPlaceholder(part, "AM", locale);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
obj[part] = getPartContent(part);
|
|
38
|
+
}
|
|
39
|
+
return obj;
|
|
40
|
+
}, {});
|
|
41
|
+
function getPartContent(part) {
|
|
42
|
+
const value = segmentValues[part];
|
|
43
|
+
const leadingZero = typeof value === "string" && value?.startsWith("0");
|
|
44
|
+
const intValue = value !== null ? Number.parseInt(value) : null;
|
|
45
|
+
if (!isNull(value) && !isNull(intValue)) {
|
|
46
|
+
const formatted = formatter.part(timeRef.set({ [part]: value }), part, {
|
|
47
|
+
hourCycle: props.hourCycle === 24 ? "h23" : undefined,
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* If we're operating in a 12 hour clock and the part is an hour, we handle
|
|
51
|
+
* the conversion to 12 hour format with 2 digit hours and leading zeros here.
|
|
52
|
+
*/
|
|
53
|
+
if (part === "hour" && "dayPeriod" in segmentValues && props.hourCycle !== 24) {
|
|
54
|
+
/**
|
|
55
|
+
* If the value is over 12, we convert to 12 hour format and add leading
|
|
56
|
+
* zeroes if the value is less than 10.
|
|
57
|
+
*/
|
|
58
|
+
if (intValue > 12) {
|
|
59
|
+
const hour = intValue - 12;
|
|
60
|
+
if (hour === 0) {
|
|
61
|
+
return "12";
|
|
62
|
+
}
|
|
63
|
+
else if (hour < 10) {
|
|
64
|
+
return `0${hour}`;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return `${hour}`;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* If the value is 0, we convert to 12, since 0 is not a valid 12 hour time.
|
|
72
|
+
*/
|
|
73
|
+
if (intValue === 0) {
|
|
74
|
+
return "12";
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* If the value is less than 10, we add a leading zero to the value.
|
|
78
|
+
*/
|
|
79
|
+
if (intValue < 10) {
|
|
80
|
+
return `0${intValue}`;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Otherwise, we don't need to do anything to the value.
|
|
84
|
+
*/
|
|
85
|
+
return `${intValue}`;
|
|
86
|
+
}
|
|
87
|
+
if (leadingZero && formatted.length === 1) {
|
|
88
|
+
return `0${formatted}`;
|
|
89
|
+
}
|
|
90
|
+
return formatted;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
return getPlaceholder(part, "", locale);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return content;
|
|
97
|
+
}
|
|
98
|
+
function createTimeContentArr(props) {
|
|
99
|
+
const { granularity, timeRef, formatter, contentObj, hideTimeZone, hourCycle } = props;
|
|
100
|
+
const parts = formatter.toParts(timeRef, getOptsByGranularity(granularity, hourCycle));
|
|
101
|
+
const timeSegmentContentArr = parts
|
|
102
|
+
.map((part) => {
|
|
103
|
+
const defaultParts = ["literal", "timeZoneName", null];
|
|
104
|
+
if (defaultParts.includes(part.type) || !isEditableTimeSegmentPart(part.type)) {
|
|
105
|
+
return {
|
|
106
|
+
part: part.type,
|
|
107
|
+
value: part.value,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
part: part.type,
|
|
112
|
+
value: contentObj[part.type],
|
|
113
|
+
};
|
|
114
|
+
})
|
|
115
|
+
.filter((segment) => {
|
|
116
|
+
if (isNull(segment.part) || isNull(segment.value))
|
|
117
|
+
return false;
|
|
118
|
+
if (segment.part === "timeZoneName" && (!isZonedDateTime(timeRef) || hideTimeZone)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
});
|
|
123
|
+
return timeSegmentContentArr;
|
|
124
|
+
}
|
|
125
|
+
export function createTimeContent(props) {
|
|
126
|
+
const contentObj = createTimeContentObj(props);
|
|
127
|
+
const contentArr = createTimeContentArr({
|
|
128
|
+
contentObj,
|
|
129
|
+
...props,
|
|
130
|
+
});
|
|
131
|
+
return {
|
|
132
|
+
obj: contentObj,
|
|
133
|
+
arr: contentArr,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function getOptsByGranularity(granularity, hourCycle) {
|
|
137
|
+
const opts = {
|
|
138
|
+
hour: "2-digit",
|
|
139
|
+
minute: "2-digit",
|
|
140
|
+
second: "2-digit",
|
|
141
|
+
timeZoneName: "short",
|
|
142
|
+
hourCycle: hourCycle === 24 ? "h23" : undefined,
|
|
143
|
+
hour12: hourCycle === 24 ? false : undefined,
|
|
144
|
+
};
|
|
145
|
+
if (granularity === "hour") {
|
|
146
|
+
delete opts.minute;
|
|
147
|
+
delete opts.second;
|
|
148
|
+
}
|
|
149
|
+
if (granularity === "minute") {
|
|
150
|
+
delete opts.second;
|
|
151
|
+
}
|
|
152
|
+
return opts;
|
|
153
|
+
}
|
|
154
|
+
export function initTimeSegmentStates() {
|
|
155
|
+
return EDITABLE_TIME_SEGMENT_PARTS.reduce((acc, key) => {
|
|
156
|
+
acc[key] = {
|
|
157
|
+
lastKeyZero: false,
|
|
158
|
+
hasLeftFocus: true,
|
|
159
|
+
updating: null,
|
|
160
|
+
};
|
|
161
|
+
return acc;
|
|
162
|
+
}, {});
|
|
163
|
+
}
|
|
164
|
+
export function initTimeSegmentIds() {
|
|
165
|
+
return Object.fromEntries(ALL_TIME_SEGMENT_PARTS.map((part) => {
|
|
166
|
+
return [part, useId()];
|
|
167
|
+
}).filter(([key]) => key !== "literal"));
|
|
168
|
+
}
|
|
169
|
+
export function isEditableTimeSegmentPart(part) {
|
|
170
|
+
return EDITABLE_TIME_SEGMENT_PARTS.includes(part);
|
|
171
|
+
}
|
|
172
|
+
export function isAnyTimeSegmentPart(part) {
|
|
173
|
+
return ALL_TIME_SEGMENT_PARTS.includes(part);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get the segments being used/ are rendered in the DOM.
|
|
177
|
+
* We're using this to determine when to set the value of
|
|
178
|
+
* the date picker, which is when all the segments have
|
|
179
|
+
* been filled.
|
|
180
|
+
*/
|
|
181
|
+
function getUsedTimeSegments(fieldNode) {
|
|
182
|
+
if (!isBrowser || !fieldNode)
|
|
183
|
+
return [];
|
|
184
|
+
const usedSegments = getTimeSegments(fieldNode)
|
|
185
|
+
.map((el) => el.dataset.segment)
|
|
186
|
+
.filter((part) => {
|
|
187
|
+
return EDITABLE_TIME_SEGMENT_PARTS.includes(part);
|
|
188
|
+
});
|
|
189
|
+
return usedSegments;
|
|
190
|
+
}
|
|
191
|
+
export function getTimeValueFromSegments(props) {
|
|
192
|
+
const usedSegments = getUsedTimeSegments(props.fieldNode);
|
|
193
|
+
for (const part of usedSegments) {
|
|
194
|
+
const value = props.segmentObj[part];
|
|
195
|
+
if (isNull(value))
|
|
196
|
+
continue;
|
|
197
|
+
// @ts-expect-error shhh
|
|
198
|
+
props.timeRef = props.timeRef.set({ [part]: props.segmentObj[part] });
|
|
199
|
+
}
|
|
200
|
+
return props.timeRef;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Check if all the segments being used have been filled.
|
|
204
|
+
* We use this to determine when we should set the value
|
|
205
|
+
* store of the date field(s).
|
|
206
|
+
*
|
|
207
|
+
* @param segmentValues - The current `SegmentValueObj`
|
|
208
|
+
* @param fieldNode - The id of the date field
|
|
209
|
+
*/
|
|
210
|
+
export function areAllTimeSegmentsFilled(segmentValues, fieldNode) {
|
|
211
|
+
const usedSegments = getUsedTimeSegments(fieldNode);
|
|
212
|
+
for (const part of usedSegments) {
|
|
213
|
+
if (segmentValues[part] === null)
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Infer the granularity to use based on the
|
|
220
|
+
* value and granularity props.
|
|
221
|
+
*/
|
|
222
|
+
export function inferTimeGranularity(granularity) {
|
|
223
|
+
if (granularity)
|
|
224
|
+
return granularity;
|
|
225
|
+
return "minute";
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Determines if the element with the provided id is the first focusable
|
|
229
|
+
* segment in the date field with the provided fieldId.
|
|
230
|
+
*
|
|
231
|
+
* @param id - The id of the element to check if it's the first segment
|
|
232
|
+
* @param fieldNode - The id of the date field associated with the segment
|
|
233
|
+
*/
|
|
234
|
+
export function isFirstTimeSegment(id, fieldNode) {
|
|
235
|
+
if (!isBrowser)
|
|
236
|
+
return false;
|
|
237
|
+
const segments = getTimeSegments(fieldNode);
|
|
238
|
+
return segments.length ? segments[0].id === id : false;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Creates or updates a description element for a date field
|
|
242
|
+
* which enables screen readers to read the date field's value.
|
|
243
|
+
*
|
|
244
|
+
* This element is hidden from view, and is portalled to the body
|
|
245
|
+
* so it can be associated via `aria-describedby` and read by
|
|
246
|
+
* screen readers as the user interacts with the date field.
|
|
247
|
+
*/
|
|
248
|
+
export function setTimeDescription(props) {
|
|
249
|
+
if (!isBrowser)
|
|
250
|
+
return;
|
|
251
|
+
const valueString = props.formatter.selectedTime(props.value);
|
|
252
|
+
const el = props.doc.getElementById(props.id);
|
|
253
|
+
if (!el) {
|
|
254
|
+
const div = props.doc.createElement("div");
|
|
255
|
+
div.style.cssText = styleToString({
|
|
256
|
+
display: "none",
|
|
257
|
+
});
|
|
258
|
+
div.id = props.id;
|
|
259
|
+
div.innerText = `Selected Time: ${valueString}`;
|
|
260
|
+
props.doc.body.appendChild(div);
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
el.innerText = `Selected Time: ${valueString}`;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Removes the description element for the date field with
|
|
268
|
+
* the provided ID. This function should be called when the
|
|
269
|
+
* date field is unmounted.
|
|
270
|
+
*/
|
|
271
|
+
export function removeTimeDescriptionElement(id, doc) {
|
|
272
|
+
if (!isBrowser)
|
|
273
|
+
return;
|
|
274
|
+
const el = doc.getElementById(id);
|
|
275
|
+
if (!el)
|
|
276
|
+
return;
|
|
277
|
+
doc.body.removeChild(el);
|
|
278
|
+
}
|
|
279
|
+
export function convertTimeValueToDateValue(time) {
|
|
280
|
+
if (time instanceof Time) {
|
|
281
|
+
return new CalendarDateTime(2020, 1, 1, time.hour, time.minute, time.second, time.millisecond);
|
|
282
|
+
}
|
|
283
|
+
return time;
|
|
284
|
+
}
|
|
285
|
+
export function convertTimeValueToTime(time) {
|
|
286
|
+
if (time instanceof Time)
|
|
287
|
+
return time;
|
|
288
|
+
return new Time(time.hour, time.minute, time.second, time.millisecond);
|
|
289
|
+
}
|
|
290
|
+
export function isTimeBefore(timeToCompare, referenceTime) {
|
|
291
|
+
return timeToCompare.compare(referenceTime) < 0;
|
|
292
|
+
}
|
|
293
|
+
export function isTimeAfter(timeToCompare, referenceTime) {
|
|
294
|
+
return timeToCompare.compare(referenceTime) > 0;
|
|
295
|
+
}
|
|
296
|
+
export function getISOTimeValue(time) {
|
|
297
|
+
if (time instanceof Time) {
|
|
298
|
+
return Time.toString();
|
|
299
|
+
}
|
|
300
|
+
return new Time(time.hour, time.minute, time.second, time.millisecond).toString();
|
|
301
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { DATE_SEGMENT_PARTS, EDITABLE_SEGMENT_PARTS, NON_EDITABLE_SEGMENT_PARTS,
|
|
1
|
+
import type { DATE_SEGMENT_PARTS, EDITABLE_SEGMENT_PARTS, NON_EDITABLE_SEGMENT_PARTS, EDITABLE_TIME_SEGMENT_PARTS } from "./parts.js";
|
|
2
2
|
export type DateSegmentPart = (typeof DATE_SEGMENT_PARTS)[number];
|
|
3
|
-
export type TimeSegmentPart = (typeof
|
|
3
|
+
export type TimeSegmentPart = (typeof EDITABLE_TIME_SEGMENT_PARTS)[number];
|
|
4
4
|
export type EditableSegmentPart = (typeof EDITABLE_SEGMENT_PARTS)[number];
|
|
5
5
|
export type NonEditableSegmentPart = (typeof NON_EDITABLE_SEGMENT_PARTS)[number];
|
|
6
6
|
export type SegmentPart = EditableSegmentPart | NonEditableSegmentPart;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type DateValue } from "@internationalized/date";
|
|
2
|
-
import type { HourCycle } from "../../shared/date/types.js";
|
|
2
|
+
import type { HourCycle, TimeValue } from "../../shared/date/types.js";
|
|
3
3
|
export type Formatter = ReturnType<typeof createFormatter>;
|
|
4
|
+
export type TimeFormatter = ReturnType<typeof createTimeFormatter>;
|
|
4
5
|
/**
|
|
5
6
|
* Creates a wrapper around the `DateFormatter`, which is
|
|
6
7
|
* an improved version of the {@link Intl.DateTimeFormat} API,
|
|
@@ -22,3 +23,12 @@ export declare function createFormatter(initialLocale: string): {
|
|
|
22
23
|
selectedDate: (date: DateValue, includeTime?: boolean) => string;
|
|
23
24
|
dayOfWeek: (date: Date, length?: Intl.DateTimeFormatOptions["weekday"]) => string;
|
|
24
25
|
};
|
|
26
|
+
export declare function createTimeFormatter(initialLocale: string): {
|
|
27
|
+
setLocale: (newLocale: string) => void;
|
|
28
|
+
getLocale: () => string;
|
|
29
|
+
toParts: (timeValue: TimeValue, options?: Intl.DateTimeFormatOptions) => Intl.DateTimeFormatPart[];
|
|
30
|
+
custom: (date: Date, options: Intl.DateTimeFormatOptions) => string;
|
|
31
|
+
part: (dateObj: TimeValue, type: Intl.DateTimeFormatPartTypes, options?: Intl.DateTimeFormatOptions) => string;
|
|
32
|
+
dayPeriod: (date: Date, hourCycle?: HourCycle | undefined) => "AM" | "PM";
|
|
33
|
+
selectedTime: (date: TimeValue) => string;
|
|
34
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DateFormatter } from "@internationalized/date";
|
|
2
2
|
import { hasTime, isZonedDateTime, toDate } from "./utils.js";
|
|
3
|
+
import { convertTimeValueToDateValue } from "./field/time-helpers.js";
|
|
3
4
|
const defaultPartOptions = {
|
|
4
5
|
year: "numeric",
|
|
5
6
|
month: "numeric",
|
|
@@ -95,3 +96,58 @@ export function createFormatter(initialLocale) {
|
|
|
95
96
|
dayOfWeek,
|
|
96
97
|
};
|
|
97
98
|
}
|
|
99
|
+
export function createTimeFormatter(initialLocale) {
|
|
100
|
+
let locale = initialLocale;
|
|
101
|
+
function setLocale(newLocale) {
|
|
102
|
+
locale = newLocale;
|
|
103
|
+
}
|
|
104
|
+
function getLocale() {
|
|
105
|
+
return locale;
|
|
106
|
+
}
|
|
107
|
+
function custom(date, options) {
|
|
108
|
+
return new DateFormatter(locale, options).format(date);
|
|
109
|
+
}
|
|
110
|
+
function selectedTime(date) {
|
|
111
|
+
return custom(toDate(convertTimeValueToDateValue(date)), {
|
|
112
|
+
timeStyle: "long",
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function toParts(timeValue, options) {
|
|
116
|
+
const dateValue = convertTimeValueToDateValue(timeValue);
|
|
117
|
+
if (isZonedDateTime(dateValue)) {
|
|
118
|
+
return new DateFormatter(locale, {
|
|
119
|
+
...options,
|
|
120
|
+
timeZone: dateValue.timeZone,
|
|
121
|
+
}).formatToParts(toDate(dateValue));
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
return new DateFormatter(locale, options).formatToParts(toDate(dateValue));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function dayPeriod(date, hourCycle = undefined) {
|
|
128
|
+
const parts = new DateFormatter(locale, {
|
|
129
|
+
hour: "numeric",
|
|
130
|
+
minute: "numeric",
|
|
131
|
+
hourCycle: hourCycle === 24 ? "h23" : undefined,
|
|
132
|
+
}).formatToParts(date);
|
|
133
|
+
const value = parts.find((p) => p.type === "dayPeriod")?.value;
|
|
134
|
+
if (value === "PM")
|
|
135
|
+
return "PM";
|
|
136
|
+
return "AM";
|
|
137
|
+
}
|
|
138
|
+
function part(dateObj, type, options = {}) {
|
|
139
|
+
const opts = { ...defaultPartOptions, ...options };
|
|
140
|
+
const parts = toParts(dateObj, opts);
|
|
141
|
+
const part = parts.find((p) => p.type === type);
|
|
142
|
+
return part ? part.value : "";
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
setLocale,
|
|
146
|
+
getLocale,
|
|
147
|
+
toParts,
|
|
148
|
+
custom,
|
|
149
|
+
part,
|
|
150
|
+
dayPeriod,
|
|
151
|
+
selectedTime,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { CalendarDateTime, type DateValue, ZonedDateTime } from "@internationalized/date";
|
|
2
|
-
import type { DateMatcher, Granularity } from "../../shared/date/types.js";
|
|
2
|
+
import type { DateMatcher, Granularity, TimeGranularity, TimeValue } from "../../shared/date/types.js";
|
|
3
3
|
type GetDefaultDateProps = {
|
|
4
4
|
defaultValue?: DateValue | DateValue[] | undefined;
|
|
5
5
|
granularity?: Granularity;
|
|
6
6
|
};
|
|
7
|
+
type GetDefaultTimeProps = {
|
|
8
|
+
defaultValue?: TimeValue | undefined;
|
|
9
|
+
granularity?: TimeGranularity;
|
|
10
|
+
};
|
|
7
11
|
/**
|
|
8
12
|
* A helper function used throughout the various date builders
|
|
9
13
|
* to generate a default `DateValue` using the `defaultValue`,
|
|
@@ -15,6 +19,7 @@ type GetDefaultDateProps = {
|
|
|
15
19
|
*
|
|
16
20
|
*/
|
|
17
21
|
export declare function getDefaultDate(opts: GetDefaultDateProps): DateValue;
|
|
22
|
+
export declare function getDefaultTime(opts: GetDefaultTimeProps): TimeValue;
|
|
18
23
|
/**
|
|
19
24
|
* Given a date string and a reference `DateValue` object, parse the
|
|
20
25
|
* string to the same type as the reference object.
|
|
@@ -31,7 +36,7 @@ export declare function parseStringToDateValue(dateStr: string, referenceVal: Da
|
|
|
31
36
|
export declare function toDate(dateValue: DateValue, tz?: string): Date;
|
|
32
37
|
export declare function getDateValueType(date: DateValue): string;
|
|
33
38
|
export declare function parseAnyDateValue(value: string, type: string): DateValue;
|
|
34
|
-
export declare function isZonedDateTime(dateValue: DateValue): dateValue is ZonedDateTime;
|
|
39
|
+
export declare function isZonedDateTime(dateValue: DateValue | TimeValue): dateValue is ZonedDateTime;
|
|
35
40
|
export declare function hasTime(dateValue: DateValue): dateValue is CalendarDateTime | ZonedDateTime;
|
|
36
41
|
/**
|
|
37
42
|
* Given a date, return the number of days in the month.
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { CalendarDate, CalendarDateTime, ZonedDateTime, getDayOfWeek, getLocalTimeZone, parseDate, parseDateTime, parseZonedDateTime, toCalendar, } from "@internationalized/date";
|
|
1
|
+
import { CalendarDate, CalendarDateTime, Time, ZonedDateTime, getDayOfWeek, getLocalTimeZone, parseDate, parseDateTime, parseZonedDateTime, toCalendar, } from "@internationalized/date";
|
|
2
2
|
const defaultDateDefaults = {
|
|
3
3
|
defaultValue: undefined,
|
|
4
4
|
granularity: "day",
|
|
5
5
|
};
|
|
6
|
+
const defaultTimeDefaults = {
|
|
7
|
+
defaultValue: undefined,
|
|
8
|
+
granularity: "minute",
|
|
9
|
+
};
|
|
6
10
|
/**
|
|
7
11
|
* A helper function used throughout the various date builders
|
|
8
12
|
* to generate a default `DateValue` using the `defaultValue`,
|
|
@@ -34,6 +38,16 @@ export function getDefaultDate(opts) {
|
|
|
34
38
|
return new CalendarDate(year, month, day);
|
|
35
39
|
}
|
|
36
40
|
}
|
|
41
|
+
export function getDefaultTime(opts) {
|
|
42
|
+
const withDefaults = { ...defaultTimeDefaults, ...opts };
|
|
43
|
+
const { defaultValue } = withDefaults;
|
|
44
|
+
if (defaultValue) {
|
|
45
|
+
return defaultValue;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return new Time(0, 0, 0);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
37
51
|
/**
|
|
38
52
|
* Given a date string and a reference `DateValue` object, parse the
|
|
39
53
|
* string to the same type as the reference object.
|
package/dist/internal/dom.d.ts
CHANGED
package/dist/internal/dom.js
CHANGED
package/dist/internal/focus.d.ts
CHANGED
|
@@ -20,9 +20,9 @@ export declare function focus(element?: FocusableTarget | null, { select }?: {
|
|
|
20
20
|
* Attempts to focus the first element in a list of candidates.
|
|
21
21
|
* Stops when focus is successful.
|
|
22
22
|
*/
|
|
23
|
-
export declare function focusFirst(candidates: HTMLElement[], { select }
|
|
23
|
+
export declare function focusFirst(candidates: HTMLElement[], { select }: {
|
|
24
24
|
select?: boolean | undefined;
|
|
25
|
-
}): true | undefined;
|
|
25
|
+
} | undefined, getActiveElement: () => HTMLElement | null): true | undefined;
|
|
26
26
|
/**
|
|
27
27
|
* Returns the first visible element in a list.
|
|
28
28
|
* NOTE: Only checks visibility up to the `container`.
|