svelte-ag 0.0.2-dev.72
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 +6 -0
- package/dist/app.css +209 -0
- package/dist/app.d.ts +13 -0
- package/dist/app.html +12 -0
- package/dist/icons.css +6 -0
- package/dist/lib/bits/internal/arrays.d.ts +95 -0
- package/dist/lib/bits/internal/arrays.js +250 -0
- package/dist/lib/bits/internal/arrays.test.d.ts +1 -0
- package/dist/lib/bits/internal/arrays.test.js +366 -0
- package/dist/lib/bits/internal/attrs.d.ts +22 -0
- package/dist/lib/bits/internal/attrs.js +69 -0
- package/dist/lib/bits/internal/box-auto-reset.svelte.d.ts +8 -0
- package/dist/lib/bits/internal/box-auto-reset.svelte.js +31 -0
- package/dist/lib/bits/internal/box.svelte.d.ts +21 -0
- package/dist/lib/bits/internal/box.svelte.js +26 -0
- package/dist/lib/bits/internal/clamp.d.ts +4 -0
- package/dist/lib/bits/internal/clamp.js +6 -0
- package/dist/lib/bits/internal/clamp.test.d.ts +1 -0
- package/dist/lib/bits/internal/clamp.test.js +31 -0
- package/dist/lib/bits/internal/create-event-hook.svelte.d.ts +18 -0
- package/dist/lib/bits/internal/create-event-hook.svelte.js +29 -0
- package/dist/lib/bits/internal/create-shared-hook.svelte.d.ts +2 -0
- package/dist/lib/bits/internal/create-shared-hook.svelte.js +27 -0
- package/dist/lib/bits/internal/date-time/announcer.d.ts +7 -0
- package/dist/lib/bits/internal/date-time/announcer.js +82 -0
- package/dist/lib/bits/internal/date-time/calendar-helpers.svelte.d.ts +201 -0
- package/dist/lib/bits/internal/date-time/calendar-helpers.svelte.js +510 -0
- package/dist/lib/bits/internal/date-time/field/helpers.d.ts +76 -0
- package/dist/lib/bits/internal/date-time/field/helpers.js +378 -0
- package/dist/lib/bits/internal/date-time/field/parts.d.ts +6 -0
- package/dist/lib/bits/internal/date-time/field/parts.js +9 -0
- package/dist/lib/bits/internal/date-time/field/segments.d.ts +51 -0
- package/dist/lib/bits/internal/date-time/field/segments.js +128 -0
- package/dist/lib/bits/internal/date-time/field/types.d.ts +25 -0
- package/dist/lib/bits/internal/date-time/field/types.js +1 -0
- package/dist/lib/bits/internal/date-time/formatter.d.ts +24 -0
- package/dist/lib/bits/internal/date-time/formatter.js +97 -0
- package/dist/lib/bits/internal/date-time/placeholders.d.ts +8 -0
- package/dist/lib/bits/internal/date-time/placeholders.js +129 -0
- package/dist/lib/bits/internal/date-time/utils.d.ts +69 -0
- package/dist/lib/bits/internal/date-time/utils.js +212 -0
- package/dist/lib/bits/internal/debounce.d.ts +4 -0
- package/dist/lib/bits/internal/debounce.js +19 -0
- package/dist/lib/bits/internal/debounce.test.d.ts +1 -0
- package/dist/lib/bits/internal/debounce.test.js +50 -0
- package/dist/lib/bits/internal/dom.d.ts +10 -0
- package/dist/lib/bits/internal/dom.js +38 -0
- package/dist/lib/bits/internal/elements.d.ts +2 -0
- package/dist/lib/bits/internal/elements.js +6 -0
- package/dist/lib/bits/internal/events.d.ts +21 -0
- package/dist/lib/bits/internal/events.js +49 -0
- package/dist/lib/bits/internal/floating-svelte/floating-utils.svelte.d.ts +7 -0
- package/dist/lib/bits/internal/floating-svelte/floating-utils.svelte.js +24 -0
- package/dist/lib/bits/internal/floating-svelte/types.d.ts +85 -0
- package/dist/lib/bits/internal/floating-svelte/types.js +1 -0
- package/dist/lib/bits/internal/floating-svelte/use-floating.svelte.d.ts +2 -0
- package/dist/lib/bits/internal/floating-svelte/use-floating.svelte.js +112 -0
- package/dist/lib/bits/internal/focus.d.ts +46 -0
- package/dist/lib/bits/internal/focus.js +109 -0
- package/dist/lib/bits/internal/get-directional-keys.d.ts +21 -0
- package/dist/lib/bits/internal/get-directional-keys.js +37 -0
- package/dist/lib/bits/internal/get-directional-keys.test.d.ts +1 -0
- package/dist/lib/bits/internal/get-directional-keys.test.js +46 -0
- package/dist/lib/bits/internal/is.d.ts +25 -0
- package/dist/lib/bits/internal/is.js +62 -0
- package/dist/lib/bits/internal/is.test.d.ts +1 -0
- package/dist/lib/bits/internal/is.test.js +34 -0
- package/dist/lib/bits/internal/kbd-constants.d.ts +40 -0
- package/dist/lib/bits/internal/kbd-constants.js +40 -0
- package/dist/lib/bits/internal/kbd.d.ts +1 -0
- package/dist/lib/bits/internal/kbd.js +1 -0
- package/dist/lib/bits/internal/locale.d.ts +6 -0
- package/dist/lib/bits/internal/locale.js +9 -0
- package/dist/lib/bits/internal/math.d.ts +5 -0
- package/dist/lib/bits/internal/math.js +43 -0
- package/dist/lib/bits/internal/math.test.d.ts +1 -0
- package/dist/lib/bits/internal/math.test.js +71 -0
- package/dist/lib/bits/internal/noop.d.ts +4 -0
- package/dist/lib/bits/internal/noop.js +4 -0
- package/dist/lib/bits/internal/should-trap-focus.d.ts +6 -0
- package/dist/lib/bits/internal/should-trap-focus.js +6 -0
- package/dist/lib/bits/internal/sleep.d.ts +1 -0
- package/dist/lib/bits/internal/sleep.js +3 -0
- package/dist/lib/bits/internal/tabbable.d.ts +10 -0
- package/dist/lib/bits/internal/tabbable.js +66 -0
- package/dist/lib/bits/internal/types.d.ts +92 -0
- package/dist/lib/bits/internal/types.js +1 -0
- package/dist/lib/bits/internal/use-after-animations.svelte.d.ts +5 -0
- package/dist/lib/bits/internal/use-after-animations.svelte.js +27 -0
- package/dist/lib/bits/internal/use-arrow-navigation.d.ts +62 -0
- package/dist/lib/bits/internal/use-arrow-navigation.js +76 -0
- package/dist/lib/bits/internal/use-body-scroll-lock.svelte.d.ts +6 -0
- package/dist/lib/bits/internal/use-body-scroll-lock.svelte.js +106 -0
- package/dist/lib/bits/internal/use-data-typeahead.svelte.d.ts +14 -0
- package/dist/lib/bits/internal/use-data-typeahead.svelte.js +31 -0
- package/dist/lib/bits/internal/use-dom-typeahead.svelte.d.ts +11 -0
- package/dist/lib/bits/internal/use-dom-typeahead.svelte.js +30 -0
- package/dist/lib/bits/internal/use-form-control.svelte.d.ts +4 -0
- package/dist/lib/bits/internal/use-form-control.svelte.js +16 -0
- package/dist/lib/bits/internal/use-grace-area.svelte.d.ts +12 -0
- package/dist/lib/bits/internal/use-grace-area.svelte.js +197 -0
- package/dist/lib/bits/internal/use-id.d.ts +4 -0
- package/dist/lib/bits/internal/use-id.js +8 -0
- package/dist/lib/bits/internal/use-resize-observer.svelte.d.ts +2 -0
- package/dist/lib/bits/internal/use-resize-observer.svelte.js +17 -0
- package/dist/lib/bits/internal/use-roving-focus.svelte.d.ts +38 -0
- package/dist/lib/bits/internal/use-roving-focus.svelte.js +91 -0
- package/dist/lib/bits/internal/use-size.svelte.d.ts +7 -0
- package/dist/lib/bits/internal/use-size.svelte.js +54 -0
- package/dist/lib/bits/internal/use-state-machine.svelte.d.ts +24 -0
- package/dist/lib/bits/internal/use-state-machine.svelte.js +28 -0
- package/dist/lib/bits/internal/use-timeout-fn.svelte.d.ts +25 -0
- package/dist/lib/bits/internal/use-timeout-fn.svelte.js +39 -0
- package/dist/lib/components/Typeahead.svelte.d.ts +47 -0
- package/dist/lib/components/Typeahead.svelte.js +150 -0
- package/dist/lib/components/animated/animated.svelte +244 -0
- package/dist/lib/components/animated/animated.svelte.d.ts +61 -0
- package/dist/lib/components/animated/index.d.ts +2 -0
- package/dist/lib/components/animated/index.js +2 -0
- package/dist/lib/components/combo/combo.svelte +186 -0
- package/dist/lib/components/combo/combo.svelte.d.ts +21 -0
- package/dist/lib/components/combo/index.d.ts +2 -0
- package/dist/lib/components/combo/index.js +2 -0
- package/dist/lib/components/dnd/Droppable.svelte +25 -0
- package/dist/lib/components/dnd/Droppable.svelte.d.ts +10 -0
- package/dist/lib/components/dnd/context.svelte.d.ts +22 -0
- package/dist/lib/components/dnd/context.svelte.js +25 -0
- package/dist/lib/components/dnd/dnd-context.svelte +45 -0
- package/dist/lib/components/dnd/dnd-context.svelte.d.ts +30 -0
- package/dist/lib/components/dnd/dnd-drag-overlay.svelte +44 -0
- package/dist/lib/components/dnd/dnd-drag-overlay.svelte.d.ts +27 -0
- package/dist/lib/components/dnd/dnd-drag-placeholder.svelte +24 -0
- package/dist/lib/components/dnd/dnd-drag-placeholder.svelte.d.ts +9 -0
- package/dist/lib/components/dnd/dnd-draghandle.svelte +30 -0
- package/dist/lib/components/dnd/dnd-draghandle.svelte.d.ts +6 -0
- package/dist/lib/components/dnd/dnd-overlay.svelte +0 -0
- package/dist/lib/components/dnd/dnd-overlay.svelte.d.ts +26 -0
- package/dist/lib/components/dnd/dnd-sortable-context.svelte +18 -0
- package/dist/lib/components/dnd/dnd-sortable-context.svelte.d.ts +8 -0
- package/dist/lib/components/dnd/dnd-sortable-item.svelte +68 -0
- package/dist/lib/components/dnd/dnd-sortable-item.svelte.d.ts +23 -0
- package/dist/lib/components/dnd/example.svelte +109 -0
- package/dist/lib/components/dnd/example.svelte.d.ts +3 -0
- package/dist/lib/components/dnd/exports.d.ts +9 -0
- package/dist/lib/components/dnd/exports.js +9 -0
- package/dist/lib/components/dnd/index.d.ts +1 -0
- package/dist/lib/components/dnd/index.js +1 -0
- package/dist/lib/components/dnd/sortable.svelte.d.ts +13 -0
- package/dist/lib/components/dnd/sortable.svelte.js +70 -0
- package/dist/lib/components/dnd/utils.svelte.d.ts +20 -0
- package/dist/lib/components/dnd/utils.svelte.js +20 -0
- package/dist/lib/components/search/combinations/searchPopover.svelte +68 -0
- package/dist/lib/components/search/combinations/searchPopover.svelte.d.ts +22 -0
- package/dist/lib/components/search/components/search-empty.svelte +28 -0
- package/dist/lib/components/search/components/search-empty.svelte.d.ts +4 -0
- package/dist/lib/components/search/components/search-input.svelte +53 -0
- package/dist/lib/components/search/components/search-input.svelte.d.ts +4 -0
- package/dist/lib/components/search/components/search-list.svelte +46 -0
- package/dist/lib/components/search/components/search-list.svelte.d.ts +4 -0
- package/dist/lib/components/search/components/search-pagnation.svelte +68 -0
- package/dist/lib/components/search/components/search-pagnation.svelte.d.ts +8 -0
- package/dist/lib/components/search/components/search.svelte +47 -0
- package/dist/lib/components/search/components/search.svelte.d.ts +4 -0
- package/dist/lib/components/search/exports.d.ts +6 -0
- package/dist/lib/components/search/exports.js +5 -0
- package/dist/lib/components/search/index.d.ts +2 -0
- package/dist/lib/components/search/index.js +2 -0
- package/dist/lib/components/search/search.svelte.d.ts +102 -0
- package/dist/lib/components/search/search.svelte.js +202 -0
- package/dist/lib/components/search/types.d.ts +28 -0
- package/dist/lib/components/search/types.js +1 -0
- package/dist/lib/components/utilities/arrow/arrow.svelte +23 -0
- package/dist/lib/components/utilities/arrow/arrow.svelte.d.ts +3 -0
- package/dist/lib/components/utilities/arrow/index.d.ts +2 -0
- package/dist/lib/components/utilities/arrow/index.js +1 -0
- package/dist/lib/components/utilities/arrow/types.d.ts +17 -0
- package/dist/lib/components/utilities/arrow/types.js +1 -0
- package/dist/lib/components/utilities/floating-layer/components/floating-layer-anchor.svelte +15 -0
- package/dist/lib/components/utilities/floating-layer/components/floating-layer-anchor.svelte.d.ts +4 -0
- package/dist/lib/components/utilities/floating-layer/components/floating-layer-arrow.svelte +20 -0
- package/dist/lib/components/utilities/floating-layer/components/floating-layer-arrow.svelte.d.ts +3 -0
- package/dist/lib/components/utilities/floating-layer/components/floating-layer-content-static.svelte +19 -0
- package/dist/lib/components/utilities/floating-layer/components/floating-layer-content-static.svelte.d.ts +13 -0
- package/dist/lib/components/utilities/floating-layer/components/floating-layer-content.svelte +61 -0
- package/dist/lib/components/utilities/floating-layer/components/floating-layer-content.svelte.d.ts +4 -0
- package/dist/lib/components/utilities/floating-layer/components/floating-layer.svelte +10 -0
- package/dist/lib/components/utilities/floating-layer/components/floating-layer.svelte.d.ts +7 -0
- package/dist/lib/components/utilities/floating-layer/components/index.d.ts +6 -0
- package/dist/lib/components/utilities/floating-layer/components/index.js +5 -0
- package/dist/lib/components/utilities/floating-layer/index.d.ts +1 -0
- package/dist/lib/components/utilities/floating-layer/index.js +1 -0
- package/dist/lib/components/utilities/floating-layer/types.d.ts +115 -0
- package/dist/lib/components/utilities/floating-layer/types.js +1 -0
- package/dist/lib/components/utilities/floating-layer/use-floating-layer.svelte.d.ts +118 -0
- package/dist/lib/components/utilities/floating-layer/use-floating-layer.svelte.js +311 -0
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +1 -0
- package/dist/lib/utils/asyncDerived.svelte.d.ts +12 -0
- package/dist/lib/utils/asyncDerived.svelte.js +26 -0
- package/dist/lib/utils/bits.d.ts +39 -0
- package/dist/lib/utils/bits.js +69 -0
- package/dist/lib/utils/index.d.ts +3 -0
- package/dist/lib/utils/index.js +3 -0
- package/dist/lib/utils/utils.d.ts +21 -0
- package/dist/lib/utils/utils.js +72 -0
- package/dist/routes/+layout.svelte +0 -0
- package/dist/routes/+layout.svelte.d.ts +26 -0
- package/package.json +79 -0
- package/src/app.css +209 -0
- package/src/app.d.ts +13 -0
- package/src/app.html +12 -0
- package/src/icons.css +6 -0
- package/src/lib/bits/internal/arrays.test.ts +460 -0
- package/src/lib/bits/internal/arrays.ts +301 -0
- package/src/lib/bits/internal/attrs.ts +97 -0
- package/src/lib/bits/internal/box-auto-reset.svelte.ts +40 -0
- package/src/lib/bits/internal/box.svelte.ts +60 -0
- package/src/lib/bits/internal/clamp.test.ts +37 -0
- package/src/lib/bits/internal/clamp.ts +6 -0
- package/src/lib/bits/internal/create-event-hook.svelte.ts +64 -0
- package/src/lib/bits/internal/create-shared-hook.svelte.ts +33 -0
- package/src/lib/bits/internal/date-time/announcer.ts +88 -0
- package/src/lib/bits/internal/date-time/calendar-helpers.svelte.ts +815 -0
- package/src/lib/bits/internal/date-time/field/helpers.ts +441 -0
- package/src/lib/bits/internal/date-time/field/parts.ts +9 -0
- package/src/lib/bits/internal/date-time/field/segments.ts +126 -0
- package/src/lib/bits/internal/date-time/field/types.ts +35 -0
- package/src/lib/bits/internal/date-time/formatter.ts +116 -0
- package/src/lib/bits/internal/date-time/placeholders.ts +143 -0
- package/src/lib/bits/internal/date-time/utils.ts +261 -0
- package/src/lib/bits/internal/debounce.test.ts +67 -0
- package/src/lib/bits/internal/debounce.ts +22 -0
- package/src/lib/bits/internal/dom.ts +47 -0
- package/src/lib/bits/internal/elements.ts +7 -0
- package/src/lib/bits/internal/events.ts +89 -0
- package/src/lib/bits/internal/floating-svelte/floating-utils.svelte.ts +28 -0
- package/src/lib/bits/internal/floating-svelte/types.ts +108 -0
- package/src/lib/bits/internal/floating-svelte/use-floating.svelte.ts +133 -0
- package/src/lib/bits/internal/focus.ts +111 -0
- package/src/lib/bits/internal/get-directional-keys.test.ts +51 -0
- package/src/lib/bits/internal/get-directional-keys.ts +43 -0
- package/src/lib/bits/internal/is.test.ts +40 -0
- package/src/lib/bits/internal/is.ts +78 -0
- package/src/lib/bits/internal/kbd-constants.ts +40 -0
- package/src/lib/bits/internal/kbd.ts +1 -0
- package/src/lib/bits/internal/locale.ts +13 -0
- package/src/lib/bits/internal/math.test.ts +88 -0
- package/src/lib/bits/internal/math.ts +50 -0
- package/src/lib/bits/internal/noop.ts +4 -0
- package/src/lib/bits/internal/should-trap-focus.ts +16 -0
- package/src/lib/bits/internal/sleep.ts +3 -0
- package/src/lib/bits/internal/tabbable.ts +76 -0
- package/src/lib/bits/internal/types.ts +91 -0
- package/src/lib/bits/internal/use-after-animations.svelte.ts +30 -0
- package/src/lib/bits/internal/use-arrow-navigation.ts +168 -0
- package/src/lib/bits/internal/use-body-scroll-lock.svelte.ts +138 -0
- package/src/lib/bits/internal/use-data-typeahead.svelte.ts +44 -0
- package/src/lib/bits/internal/use-dom-typeahead.svelte.ts +44 -0
- package/src/lib/bits/internal/use-form-control.svelte.ts +17 -0
- package/src/lib/bits/internal/use-grace-area.svelte.ts +229 -0
- package/src/lib/bits/internal/use-id.ts +9 -0
- package/src/lib/bits/internal/use-resize-observer.svelte.ts +19 -0
- package/src/lib/bits/internal/use-roving-focus.svelte.ts +141 -0
- package/src/lib/bits/internal/use-size.svelte.ts +60 -0
- package/src/lib/bits/internal/use-state-machine.svelte.ts +46 -0
- package/src/lib/bits/internal/use-timeout-fn.svelte.ts +80 -0
- package/src/lib/components/Typeahead.svelte.ts +200 -0
- package/src/lib/components/animated/animated.svelte +244 -0
- package/src/lib/components/animated/index.ts +3 -0
- package/src/lib/components/combo/combo.svelte +186 -0
- package/src/lib/components/combo/index.ts +3 -0
- package/src/lib/components/dnd/Droppable.svelte +25 -0
- package/src/lib/components/dnd/context.svelte.ts +30 -0
- package/src/lib/components/dnd/dnd-context.svelte +45 -0
- package/src/lib/components/dnd/dnd-drag-overlay.svelte +44 -0
- package/src/lib/components/dnd/dnd-drag-placeholder.svelte +24 -0
- package/src/lib/components/dnd/dnd-draghandle.svelte +30 -0
- package/src/lib/components/dnd/dnd-overlay.svelte +0 -0
- package/src/lib/components/dnd/dnd-sortable-context.svelte +18 -0
- package/src/lib/components/dnd/dnd-sortable-item.svelte +68 -0
- package/src/lib/components/dnd/example.svelte +109 -0
- package/src/lib/components/dnd/exports.ts +12 -0
- package/src/lib/components/dnd/index.ts +1 -0
- package/src/lib/components/dnd/sortable.svelte.ts +82 -0
- package/src/lib/components/dnd/utils.svelte.ts +29 -0
- package/src/lib/components/search/combinations/searchPopover.svelte +68 -0
- package/src/lib/components/search/components/search-empty.svelte +28 -0
- package/src/lib/components/search/components/search-input.svelte +53 -0
- package/src/lib/components/search/components/search-list.svelte +46 -0
- package/src/lib/components/search/components/search-pagnation.svelte +68 -0
- package/src/lib/components/search/components/search.svelte +47 -0
- package/src/lib/components/search/exports.ts +13 -0
- package/src/lib/components/search/index.ts +2 -0
- package/src/lib/components/search/search.svelte.ts +286 -0
- package/src/lib/components/search/types.ts +48 -0
- package/src/lib/components/utilities/arrow/arrow.svelte +23 -0
- package/src/lib/components/utilities/arrow/index.ts +2 -0
- package/src/lib/components/utilities/arrow/types.ts +20 -0
- package/src/lib/components/utilities/floating-layer/components/floating-layer-anchor.svelte +15 -0
- package/src/lib/components/utilities/floating-layer/components/floating-layer-arrow.svelte +20 -0
- package/src/lib/components/utilities/floating-layer/components/floating-layer-content-static.svelte +19 -0
- package/src/lib/components/utilities/floating-layer/components/floating-layer-content.svelte +61 -0
- package/src/lib/components/utilities/floating-layer/components/floating-layer.svelte +10 -0
- package/src/lib/components/utilities/floating-layer/components/index.ts +11 -0
- package/src/lib/components/utilities/floating-layer/index.ts +1 -0
- package/src/lib/components/utilities/floating-layer/types.ts +133 -0
- package/src/lib/components/utilities/floating-layer/use-floating-layer.svelte.ts +406 -0
- package/src/lib/index.ts +1 -0
- package/src/lib/utils/asyncDerived.svelte.ts +38 -0
- package/src/lib/utils/bits.ts +93 -0
- package/src/lib/utils/index.ts +3 -0
- package/src/lib/utils/utils.ts +97 -0
- package/src/routes/+layout.svelte +0 -0
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
import { endOfMonth, isSameDay, isSameMonth, startOfMonth, } from "@internationalized/date";
|
|
2
|
+
import { afterTick, styleToString } from "svelte-toolbelt";
|
|
3
|
+
import { untrack } from "svelte";
|
|
4
|
+
import { getDaysInMonth, getLastFirstDayOfWeek, getNextLastDayOfWeek, hasTime, isAfter, isBefore, parseAnyDateValue, parseStringToDateValue, toDate, } from "./utils.js";
|
|
5
|
+
import { getDataDisabled, getDataInvalid, getDataReadonly } from "../../../internal/attrs.js";
|
|
6
|
+
import { chunk, isValidIndex } from "../../../internal/arrays.js";
|
|
7
|
+
import { isBrowser, isHTMLElement } from "../../../internal/is.js";
|
|
8
|
+
import { kbd } from "../../../internal/kbd.js";
|
|
9
|
+
import { watch } from "runed";
|
|
10
|
+
/**
|
|
11
|
+
* Checks if a given node is a calendar cell element.
|
|
12
|
+
*
|
|
13
|
+
* @param node - The node to check.
|
|
14
|
+
*/
|
|
15
|
+
export function isCalendarDayNode(node) {
|
|
16
|
+
if (!isHTMLElement(node))
|
|
17
|
+
return false;
|
|
18
|
+
if (!node.hasAttribute("data-bits-day"))
|
|
19
|
+
return false;
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Retrieves an array of date values representing the days between
|
|
24
|
+
* the provided start and end dates.
|
|
25
|
+
*/
|
|
26
|
+
export function getDaysBetween(start, end) {
|
|
27
|
+
const days = [];
|
|
28
|
+
let dCurrent = start.add({ days: 1 });
|
|
29
|
+
const dEnd = end;
|
|
30
|
+
while (dCurrent.compare(dEnd) < 0) {
|
|
31
|
+
days.push(dCurrent);
|
|
32
|
+
dCurrent = dCurrent.add({ days: 1 });
|
|
33
|
+
}
|
|
34
|
+
return days;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Creates a calendar month object.
|
|
38
|
+
*
|
|
39
|
+
* @remarks
|
|
40
|
+
* Given a date, this function returns an object containing
|
|
41
|
+
* the necessary values to render a calendar month, including
|
|
42
|
+
* the month's date (the first day of that month), which can be
|
|
43
|
+
* used to render the name of the month, an array of all dates
|
|
44
|
+
* in that month, and an array of weeks. Each week is an array
|
|
45
|
+
* of dates, useful for rendering an accessible calendar grid
|
|
46
|
+
* using a loop and table elements.
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
function createMonth(props) {
|
|
50
|
+
const { dateObj, weekStartsOn, fixedWeeks, locale } = props;
|
|
51
|
+
const daysInMonth = getDaysInMonth(dateObj);
|
|
52
|
+
const datesArray = Array.from({ length: daysInMonth }, (_, i) => dateObj.set({ day: i + 1 }));
|
|
53
|
+
const firstDayOfMonth = startOfMonth(dateObj);
|
|
54
|
+
const lastDayOfMonth = endOfMonth(dateObj);
|
|
55
|
+
const lastSunday = getLastFirstDayOfWeek(firstDayOfMonth, weekStartsOn, locale);
|
|
56
|
+
const nextSaturday = getNextLastDayOfWeek(lastDayOfMonth, weekStartsOn, locale);
|
|
57
|
+
const lastMonthDays = getDaysBetween(lastSunday.subtract({ days: 1 }), firstDayOfMonth);
|
|
58
|
+
const nextMonthDays = getDaysBetween(lastDayOfMonth, nextSaturday.add({ days: 1 }));
|
|
59
|
+
const totalDays = lastMonthDays.length + datesArray.length + nextMonthDays.length;
|
|
60
|
+
if (fixedWeeks && totalDays < 42) {
|
|
61
|
+
const extraDays = 42 - totalDays;
|
|
62
|
+
let startFrom = nextMonthDays[nextMonthDays.length - 1];
|
|
63
|
+
if (!startFrom) {
|
|
64
|
+
startFrom = dateObj.add({ months: 1 }).set({ day: 1 });
|
|
65
|
+
}
|
|
66
|
+
let length = extraDays;
|
|
67
|
+
if (nextMonthDays.length === 0) {
|
|
68
|
+
length = extraDays - 1;
|
|
69
|
+
nextMonthDays.push(startFrom);
|
|
70
|
+
}
|
|
71
|
+
const extraDaysArray = Array.from({ length }, (_, i) => {
|
|
72
|
+
const incr = i + 1;
|
|
73
|
+
return startFrom.add({ days: incr });
|
|
74
|
+
});
|
|
75
|
+
nextMonthDays.push(...extraDaysArray);
|
|
76
|
+
}
|
|
77
|
+
const allDays = lastMonthDays.concat(datesArray, nextMonthDays);
|
|
78
|
+
const weeks = chunk(allDays, 7);
|
|
79
|
+
return {
|
|
80
|
+
value: dateObj,
|
|
81
|
+
dates: allDays,
|
|
82
|
+
weeks,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export function createMonths(props) {
|
|
86
|
+
const { numberOfMonths, dateObj, ...monthProps } = props;
|
|
87
|
+
const months = [];
|
|
88
|
+
if (!numberOfMonths || numberOfMonths === 1) {
|
|
89
|
+
months.push(createMonth({
|
|
90
|
+
...monthProps,
|
|
91
|
+
dateObj,
|
|
92
|
+
}));
|
|
93
|
+
return months;
|
|
94
|
+
}
|
|
95
|
+
months.push(createMonth({
|
|
96
|
+
...monthProps,
|
|
97
|
+
dateObj,
|
|
98
|
+
}));
|
|
99
|
+
// Create all the months, starting with the current month
|
|
100
|
+
for (let i = 1; i < numberOfMonths; i++) {
|
|
101
|
+
const nextMonth = dateObj.add({ months: i });
|
|
102
|
+
months.push(createMonth({
|
|
103
|
+
...monthProps,
|
|
104
|
+
dateObj: nextMonth,
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
return months;
|
|
108
|
+
}
|
|
109
|
+
export function getSelectableCells(calendarNode) {
|
|
110
|
+
if (!calendarNode)
|
|
111
|
+
return [];
|
|
112
|
+
const selectableSelector = `[data-bits-day]:not([data-disabled]):not([data-outside-visible-months])`;
|
|
113
|
+
return Array.from(calendarNode.querySelectorAll(selectableSelector)).filter((el) => isHTMLElement(el));
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* A helper function to extract the date from the `data-value`
|
|
117
|
+
* attribute of a date cell and set it as the placeholder value.
|
|
118
|
+
*
|
|
119
|
+
* Shared between the calendar and range calendar builders.
|
|
120
|
+
*
|
|
121
|
+
* @param node - The node to extract the date from.
|
|
122
|
+
* @param placeholder - The placeholder value store which will be set to the extracted date.
|
|
123
|
+
*/
|
|
124
|
+
export function setPlaceholderToNodeValue(node, placeholder) {
|
|
125
|
+
const cellValue = node.getAttribute("data-value");
|
|
126
|
+
if (!cellValue)
|
|
127
|
+
return;
|
|
128
|
+
placeholder.current = parseStringToDateValue(cellValue, placeholder.current);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Shared logic for shifting focus between cells in the
|
|
132
|
+
* calendar and range calendar.
|
|
133
|
+
*/
|
|
134
|
+
export function shiftCalendarFocus({ node, add, placeholder, calendarNode, isPrevButtonDisabled, isNextButtonDisabled, months, numberOfMonths, }) {
|
|
135
|
+
const candidateCells = getSelectableCells(calendarNode);
|
|
136
|
+
if (!candidateCells.length)
|
|
137
|
+
return;
|
|
138
|
+
const index = candidateCells.indexOf(node);
|
|
139
|
+
const nextIndex = index + add;
|
|
140
|
+
/**
|
|
141
|
+
* If the next cell is within the bounds of the displayed cells,
|
|
142
|
+
* easy day, we just focus it.
|
|
143
|
+
*/
|
|
144
|
+
if (isValidIndex(nextIndex, candidateCells)) {
|
|
145
|
+
const nextCell = candidateCells[nextIndex];
|
|
146
|
+
setPlaceholderToNodeValue(nextCell, placeholder);
|
|
147
|
+
return nextCell.focus();
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* When the next cell falls outside the displayed cells range,
|
|
151
|
+
* we update the focus to the previous or next month based on the
|
|
152
|
+
* direction, and then focus on the relevant cell.
|
|
153
|
+
*/
|
|
154
|
+
if (nextIndex < 0) {
|
|
155
|
+
/**
|
|
156
|
+
* To handle negative indices, we rewind by one month,
|
|
157
|
+
* retrieve candidate cells for that month, and shift focus
|
|
158
|
+
* by the difference between the nextIndex starting from the end
|
|
159
|
+
* of the array.
|
|
160
|
+
*/
|
|
161
|
+
// shift the calendar back a month unless prev month is disabled
|
|
162
|
+
if (isPrevButtonDisabled)
|
|
163
|
+
return;
|
|
164
|
+
const firstMonth = months[0]?.value;
|
|
165
|
+
if (!firstMonth)
|
|
166
|
+
return;
|
|
167
|
+
placeholder.current = firstMonth.subtract({ months: numberOfMonths });
|
|
168
|
+
// Without a tick here, it seems to be too quick for the DOM to update
|
|
169
|
+
afterTick(() => {
|
|
170
|
+
const newCandidateCells = getSelectableCells(calendarNode);
|
|
171
|
+
if (!newCandidateCells.length)
|
|
172
|
+
return;
|
|
173
|
+
/**
|
|
174
|
+
* Starting at the end of the array, shift focus by the diff
|
|
175
|
+
* between the nextIndex and the length of the array, since the
|
|
176
|
+
* nextIndex is negative.
|
|
177
|
+
*/
|
|
178
|
+
const newIndex = newCandidateCells.length - Math.abs(nextIndex);
|
|
179
|
+
if (isValidIndex(newIndex, newCandidateCells)) {
|
|
180
|
+
const newCell = newCandidateCells[newIndex];
|
|
181
|
+
setPlaceholderToNodeValue(newCell, placeholder);
|
|
182
|
+
return newCell.focus();
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
if (nextIndex >= candidateCells.length) {
|
|
187
|
+
/**
|
|
188
|
+
* Since we're in the positive index range, we need to go forward
|
|
189
|
+
* a month, refetch the candidate cells within that month, and then
|
|
190
|
+
* starting at the beginning of the array, shift focus by the nextIndex
|
|
191
|
+
* amount.
|
|
192
|
+
*/
|
|
193
|
+
// shift the calendar forward a month unless next month is disabled
|
|
194
|
+
if (isNextButtonDisabled)
|
|
195
|
+
return;
|
|
196
|
+
const firstMonth = months[0]?.value;
|
|
197
|
+
if (!firstMonth)
|
|
198
|
+
return;
|
|
199
|
+
placeholder.current = firstMonth.add({ months: numberOfMonths });
|
|
200
|
+
afterTick(() => {
|
|
201
|
+
const newCandidateCells = getSelectableCells(calendarNode);
|
|
202
|
+
if (!newCandidateCells.length)
|
|
203
|
+
return;
|
|
204
|
+
/**
|
|
205
|
+
* We need to determine how far into the next month we need to go
|
|
206
|
+
* to get the next index. So if we only went over the previous month
|
|
207
|
+
* by one, we need to go into the next month by 1 to get the right index.
|
|
208
|
+
*/
|
|
209
|
+
const newIndex = nextIndex - candidateCells.length;
|
|
210
|
+
if (isValidIndex(newIndex, newCandidateCells)) {
|
|
211
|
+
const nextCell = newCandidateCells[newIndex];
|
|
212
|
+
return nextCell.focus();
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const ARROW_KEYS = [kbd.ARROW_DOWN, kbd.ARROW_UP, kbd.ARROW_LEFT, kbd.ARROW_RIGHT];
|
|
218
|
+
const SELECT_KEYS = [kbd.ENTER, kbd.SPACE];
|
|
219
|
+
/**
|
|
220
|
+
* Shared keyboard event handler for the calendar and range calendar.
|
|
221
|
+
*/
|
|
222
|
+
export function handleCalendarKeydown({ event, handleCellClick, shiftFocus, placeholderValue, }) {
|
|
223
|
+
const currentCell = event.target;
|
|
224
|
+
if (!isCalendarDayNode(currentCell))
|
|
225
|
+
return;
|
|
226
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
227
|
+
if (!ARROW_KEYS.includes(event.key) && !SELECT_KEYS.includes(event.key))
|
|
228
|
+
return;
|
|
229
|
+
event.preventDefault();
|
|
230
|
+
const kbdFocusMap = {
|
|
231
|
+
[kbd.ARROW_DOWN]: 7,
|
|
232
|
+
[kbd.ARROW_UP]: -7,
|
|
233
|
+
[kbd.ARROW_LEFT]: -1,
|
|
234
|
+
[kbd.ARROW_RIGHT]: 1,
|
|
235
|
+
};
|
|
236
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
237
|
+
if (ARROW_KEYS.includes(event.key)) {
|
|
238
|
+
const add = kbdFocusMap[event.key];
|
|
239
|
+
if (add !== undefined) {
|
|
240
|
+
shiftFocus(currentCell, add);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (SELECT_KEYS.includes(event.key)) {
|
|
244
|
+
const cellValue = currentCell.getAttribute("data-value");
|
|
245
|
+
if (!cellValue)
|
|
246
|
+
return;
|
|
247
|
+
handleCellClick(event, parseStringToDateValue(cellValue, placeholderValue));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
export function handleCalendarNextPage({ months, setMonths, numberOfMonths, pagedNavigation, weekStartsOn, locale, fixedWeeks, setPlaceholder, }) {
|
|
251
|
+
const firstMonth = months[0]?.value;
|
|
252
|
+
if (!firstMonth)
|
|
253
|
+
return;
|
|
254
|
+
if (pagedNavigation) {
|
|
255
|
+
setPlaceholder(firstMonth.add({ months: numberOfMonths }));
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
const newMonths = createMonths({
|
|
259
|
+
dateObj: firstMonth.add({ months: 1 }),
|
|
260
|
+
weekStartsOn,
|
|
261
|
+
locale,
|
|
262
|
+
fixedWeeks,
|
|
263
|
+
numberOfMonths,
|
|
264
|
+
});
|
|
265
|
+
setMonths(newMonths);
|
|
266
|
+
const firstNewMonth = newMonths[0];
|
|
267
|
+
if (!firstNewMonth)
|
|
268
|
+
return;
|
|
269
|
+
setPlaceholder(firstNewMonth.value.set({ day: 1 }));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
export function handleCalendarPrevPage({ months, setMonths, numberOfMonths, pagedNavigation, weekStartsOn, locale, fixedWeeks, setPlaceholder, }) {
|
|
273
|
+
const firstMonth = months[0]?.value;
|
|
274
|
+
if (!firstMonth)
|
|
275
|
+
return;
|
|
276
|
+
if (pagedNavigation) {
|
|
277
|
+
setPlaceholder(firstMonth.subtract({ months: numberOfMonths }));
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
const newMonths = createMonths({
|
|
281
|
+
dateObj: firstMonth.subtract({ months: 1 }),
|
|
282
|
+
weekStartsOn,
|
|
283
|
+
locale,
|
|
284
|
+
fixedWeeks,
|
|
285
|
+
numberOfMonths,
|
|
286
|
+
});
|
|
287
|
+
setMonths(newMonths);
|
|
288
|
+
const firstNewMonth = newMonths[0];
|
|
289
|
+
if (!firstNewMonth)
|
|
290
|
+
return;
|
|
291
|
+
setPlaceholder(firstNewMonth.value.set({ day: 1 }));
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
export function getWeekdays({ months, formatter, weekdayFormat }) {
|
|
295
|
+
if (!months.length)
|
|
296
|
+
return [];
|
|
297
|
+
const firstMonth = months[0];
|
|
298
|
+
const firstWeek = firstMonth.weeks[0];
|
|
299
|
+
if (!firstWeek)
|
|
300
|
+
return [];
|
|
301
|
+
return firstWeek.map((date) => formatter.dayOfWeek(toDate(date), weekdayFormat));
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Updates the displayed months based on changes in the options values,
|
|
305
|
+
* which determines the month to show in the calendar.
|
|
306
|
+
*/
|
|
307
|
+
export function useMonthViewOptionsSync(props) {
|
|
308
|
+
const weekStartsOn = props.weekStartsOn.current;
|
|
309
|
+
const locale = props.locale.current;
|
|
310
|
+
const fixedWeeks = props.fixedWeeks.current;
|
|
311
|
+
const numberOfMonths = props.numberOfMonths.current;
|
|
312
|
+
untrack(() => {
|
|
313
|
+
const placeholder = props.placeholder.current;
|
|
314
|
+
if (!placeholder)
|
|
315
|
+
return;
|
|
316
|
+
const defaultMonthProps = {
|
|
317
|
+
weekStartsOn,
|
|
318
|
+
locale,
|
|
319
|
+
fixedWeeks,
|
|
320
|
+
numberOfMonths,
|
|
321
|
+
};
|
|
322
|
+
props.setMonths(createMonths({ ...defaultMonthProps, dateObj: placeholder }));
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Creates an accessible heading element for the calendar.
|
|
327
|
+
* Returns a function that removes the heading element.
|
|
328
|
+
*/
|
|
329
|
+
export function createAccessibleHeading({ calendarNode, label, accessibleHeadingId, }) {
|
|
330
|
+
const div = document.createElement("div");
|
|
331
|
+
div.style.cssText = styleToString({
|
|
332
|
+
border: "0px",
|
|
333
|
+
clip: "rect(0px, 0px, 0px, 0px)",
|
|
334
|
+
clipPath: "inset(50%)",
|
|
335
|
+
height: "1px",
|
|
336
|
+
margin: "-1px",
|
|
337
|
+
overflow: "hidden",
|
|
338
|
+
padding: "0px",
|
|
339
|
+
position: "absolute",
|
|
340
|
+
whiteSpace: "nowrap",
|
|
341
|
+
width: "1px",
|
|
342
|
+
});
|
|
343
|
+
const h2 = document.createElement("div");
|
|
344
|
+
h2.textContent = label;
|
|
345
|
+
h2.id = accessibleHeadingId;
|
|
346
|
+
h2.role = "heading";
|
|
347
|
+
h2.ariaLevel = "2";
|
|
348
|
+
calendarNode.insertBefore(div, calendarNode.firstChild);
|
|
349
|
+
div.appendChild(h2);
|
|
350
|
+
return () => {
|
|
351
|
+
const h2 = document.getElementById(accessibleHeadingId);
|
|
352
|
+
if (!h2)
|
|
353
|
+
return;
|
|
354
|
+
div.parentElement?.removeChild(div);
|
|
355
|
+
h2.remove();
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
export function useMonthViewPlaceholderSync({ placeholder, getVisibleMonths, weekStartsOn, locale, fixedWeeks, numberOfMonths, setMonths, }) {
|
|
359
|
+
$effect(() => {
|
|
360
|
+
placeholder.current;
|
|
361
|
+
untrack(() => {
|
|
362
|
+
/**
|
|
363
|
+
* If the placeholder's month is already in this visible months,
|
|
364
|
+
* we don't need to do anything.
|
|
365
|
+
*/
|
|
366
|
+
if (getVisibleMonths().some((month) => isSameMonth(month, placeholder.current))) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
const defaultMonthProps = {
|
|
370
|
+
weekStartsOn: weekStartsOn.current,
|
|
371
|
+
locale: locale.current,
|
|
372
|
+
fixedWeeks: fixedWeeks.current,
|
|
373
|
+
numberOfMonths: numberOfMonths.current,
|
|
374
|
+
};
|
|
375
|
+
setMonths(createMonths({ ...defaultMonthProps, dateObj: placeholder.current }));
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
export function getIsNextButtonDisabled({ maxValue, months, disabled, }) {
|
|
380
|
+
if (!maxValue || !months.length)
|
|
381
|
+
return false;
|
|
382
|
+
if (disabled)
|
|
383
|
+
return true;
|
|
384
|
+
const lastMonthInView = months[months.length - 1]?.value;
|
|
385
|
+
if (!lastMonthInView)
|
|
386
|
+
return false;
|
|
387
|
+
const firstMonthOfNextPage = lastMonthInView
|
|
388
|
+
.add({
|
|
389
|
+
months: 1,
|
|
390
|
+
})
|
|
391
|
+
.set({ day: 1 });
|
|
392
|
+
return isAfter(firstMonthOfNextPage, maxValue);
|
|
393
|
+
}
|
|
394
|
+
export function getIsPrevButtonDisabled({ minValue, months, disabled, }) {
|
|
395
|
+
if (!minValue || !months.length)
|
|
396
|
+
return false;
|
|
397
|
+
if (disabled)
|
|
398
|
+
return true;
|
|
399
|
+
const firstMonthInView = months[0]?.value;
|
|
400
|
+
if (!firstMonthInView)
|
|
401
|
+
return false;
|
|
402
|
+
const lastMonthOfPrevPage = firstMonthInView
|
|
403
|
+
.subtract({
|
|
404
|
+
months: 1,
|
|
405
|
+
})
|
|
406
|
+
.set({ day: 35 });
|
|
407
|
+
return isBefore(lastMonthOfPrevPage, minValue);
|
|
408
|
+
}
|
|
409
|
+
export function getCalendarHeadingValue({ months, locale, formatter, }) {
|
|
410
|
+
if (!months.length)
|
|
411
|
+
return "";
|
|
412
|
+
if (locale !== formatter.getLocale()) {
|
|
413
|
+
formatter.setLocale(locale);
|
|
414
|
+
}
|
|
415
|
+
if (months.length === 1) {
|
|
416
|
+
const month = toDate(months[0].value);
|
|
417
|
+
return `${formatter.fullMonthAndYear(month)}`;
|
|
418
|
+
}
|
|
419
|
+
const startMonth = toDate(months[0].value);
|
|
420
|
+
const endMonth = toDate(months[months.length - 1].value);
|
|
421
|
+
const startMonthName = formatter.fullMonth(startMonth);
|
|
422
|
+
const endMonthName = formatter.fullMonth(endMonth);
|
|
423
|
+
const startMonthYear = formatter.fullYear(startMonth);
|
|
424
|
+
const endMonthYear = formatter.fullYear(endMonth);
|
|
425
|
+
const content = startMonthYear === endMonthYear
|
|
426
|
+
? `${startMonthName} - ${endMonthName} ${endMonthYear}`
|
|
427
|
+
: `${startMonthName} ${startMonthYear} - ${endMonthName} ${endMonthYear}`;
|
|
428
|
+
return content;
|
|
429
|
+
}
|
|
430
|
+
export function getCalendarElementProps({ fullCalendarLabel, id, isInvalid, disabled, readonly, }) {
|
|
431
|
+
return {
|
|
432
|
+
id,
|
|
433
|
+
role: "application",
|
|
434
|
+
"aria-label": fullCalendarLabel,
|
|
435
|
+
"data-invalid": getDataInvalid(isInvalid),
|
|
436
|
+
"data-disabled": getDataDisabled(disabled),
|
|
437
|
+
"data-readonly": getDataReadonly(readonly),
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
export function pickerOpenFocus(e) {
|
|
441
|
+
const nodeToFocus = document.querySelector("[data-bits-day][data-focused]");
|
|
442
|
+
if (nodeToFocus) {
|
|
443
|
+
e.preventDefault();
|
|
444
|
+
nodeToFocus?.focus();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
export function getFirstNonDisabledDateInView(calendarRef) {
|
|
448
|
+
if (!isBrowser)
|
|
449
|
+
return;
|
|
450
|
+
const daysInView = Array.from(calendarRef.querySelectorAll("[data-bits-day]:not([aria-disabled=true])"));
|
|
451
|
+
if (daysInView.length === 0)
|
|
452
|
+
return;
|
|
453
|
+
const element = daysInView[0];
|
|
454
|
+
const value = element?.getAttribute("data-value");
|
|
455
|
+
const type = element?.getAttribute("data-type");
|
|
456
|
+
if (!value || !type)
|
|
457
|
+
return;
|
|
458
|
+
return parseAnyDateValue(value, type);
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Ensures the placeholder is not set to a disabled date,
|
|
462
|
+
* which would prevent the user from entering the Calendar
|
|
463
|
+
* via the keyboard.
|
|
464
|
+
*/
|
|
465
|
+
export function useEnsureNonDisabledPlaceholder({ ref, placeholder, defaultPlaceholder, minValue, maxValue, isDateDisabled, }) {
|
|
466
|
+
function isDisabled(date) {
|
|
467
|
+
if (isDateDisabled.current(date))
|
|
468
|
+
return true;
|
|
469
|
+
if (minValue.current && isBefore(date, minValue.current))
|
|
470
|
+
return true;
|
|
471
|
+
if (maxValue.current && isBefore(maxValue.current, date))
|
|
472
|
+
return true;
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
watch(() => ref.current, () => {
|
|
476
|
+
if (!ref.current)
|
|
477
|
+
return;
|
|
478
|
+
/**
|
|
479
|
+
* If the placeholder is still the default placeholder and it's a disabled date, find
|
|
480
|
+
* the first available date in the calendar view and set it as the placeholder.
|
|
481
|
+
*
|
|
482
|
+
* This prevents the placeholder from being a disabled date and no date being tabbable
|
|
483
|
+
* preventing the user from entering the Calendar. If all dates in the view are
|
|
484
|
+
* disabled, currently that is considered an error on the developer's part and should
|
|
485
|
+
* be handled by them.
|
|
486
|
+
*
|
|
487
|
+
* Perhaps in the future we can introduce a dev-only log message to prevent this from
|
|
488
|
+
* being a silent error.
|
|
489
|
+
*/
|
|
490
|
+
if (placeholder.current &&
|
|
491
|
+
isSameDay(placeholder.current, defaultPlaceholder) &&
|
|
492
|
+
isDisabled(defaultPlaceholder)) {
|
|
493
|
+
placeholder.current =
|
|
494
|
+
getFirstNonDisabledDateInView(ref.current) ?? defaultPlaceholder;
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
export function getDateWithPreviousTime(date, prev) {
|
|
499
|
+
if (!date || !prev)
|
|
500
|
+
return date;
|
|
501
|
+
if (hasTime(date) && hasTime(prev)) {
|
|
502
|
+
return date.set({
|
|
503
|
+
hour: prev.hour,
|
|
504
|
+
minute: prev.minute,
|
|
505
|
+
millisecond: prev.millisecond,
|
|
506
|
+
second: prev.second,
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
return date;
|
|
510
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { DateValue } from "@internationalized/date";
|
|
2
|
+
import type { Formatter } from "../formatter.js";
|
|
3
|
+
import type { DateAndTimeSegmentObj, DateSegmentPart, EditableSegmentPart, SegmentContentObj, SegmentPart, SegmentStateMap, SegmentValueObj } from "./types.js";
|
|
4
|
+
import type { Granularity, HourCycle } from "../../../../shared/date/types.js";
|
|
5
|
+
export declare function initializeSegmentValues(granularity: Granularity): SegmentValueObj;
|
|
6
|
+
type SharedContentProps = {
|
|
7
|
+
granularity: Granularity;
|
|
8
|
+
dateRef: DateValue;
|
|
9
|
+
formatter: Formatter;
|
|
10
|
+
hideTimeZone: boolean;
|
|
11
|
+
hourCycle: HourCycle | undefined;
|
|
12
|
+
};
|
|
13
|
+
type CreateContentObjProps = SharedContentProps & {
|
|
14
|
+
segmentValues: SegmentValueObj;
|
|
15
|
+
locale: string;
|
|
16
|
+
};
|
|
17
|
+
type CreateContentProps = CreateContentObjProps;
|
|
18
|
+
export declare function createContent(props: CreateContentProps): {
|
|
19
|
+
obj: SegmentContentObj;
|
|
20
|
+
arr: any;
|
|
21
|
+
};
|
|
22
|
+
export declare function initSegmentStates(): SegmentStateMap;
|
|
23
|
+
export declare function initSegmentIds(): any;
|
|
24
|
+
export declare function isDateSegmentPart(part: unknown): part is DateSegmentPart;
|
|
25
|
+
export declare function isSegmentPart(part: string): part is EditableSegmentPart;
|
|
26
|
+
export declare function isAnySegmentPart(part: unknown): part is SegmentPart;
|
|
27
|
+
type GetValueFromSegments = {
|
|
28
|
+
segmentObj: SegmentValueObj;
|
|
29
|
+
fieldNode: HTMLElement | null;
|
|
30
|
+
dateRef: DateValue;
|
|
31
|
+
};
|
|
32
|
+
export declare function getValueFromSegments(props: GetValueFromSegments): DateValue;
|
|
33
|
+
/**
|
|
34
|
+
* Check if all the segments being used have been filled.
|
|
35
|
+
* We use this to determine when we should set the value
|
|
36
|
+
* store of the date field(s).
|
|
37
|
+
*
|
|
38
|
+
* @param segmentValues - The current `SegmentValueObj`
|
|
39
|
+
* @param fieldNode - The id of the date field
|
|
40
|
+
*/
|
|
41
|
+
export declare function areAllSegmentsFilled(segmentValues: SegmentValueObj, fieldNode: HTMLElement | null): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Determines if the provided object is a valid `DateAndTimeSegmentObj`
|
|
44
|
+
* by checking if it has the correct keys and values for each key.
|
|
45
|
+
*/
|
|
46
|
+
export declare function isDateAndTimeSegmentObj(obj: unknown): obj is DateAndTimeSegmentObj;
|
|
47
|
+
/**
|
|
48
|
+
* Infer the granularity to use based on the
|
|
49
|
+
* value and granularity props.
|
|
50
|
+
*/
|
|
51
|
+
export declare function inferGranularity(value: DateValue, granularity: Granularity | undefined): Granularity;
|
|
52
|
+
export declare function isAcceptableSegmentKey(key: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Determines if the element with the provided id is the first focusable
|
|
55
|
+
* segment in the date field with the provided fieldId.
|
|
56
|
+
*
|
|
57
|
+
* @param id - The id of the element to check if it's the first segment
|
|
58
|
+
* @param fieldNode - The id of the date field associated with the segment
|
|
59
|
+
*/
|
|
60
|
+
export declare function isFirstSegment(id: string, fieldNode: HTMLElement | null): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Creates or updates a description element for a date field
|
|
63
|
+
* which enables screen readers to read the date field's value.
|
|
64
|
+
*
|
|
65
|
+
* This element is hidden from view, and is portalled to the body
|
|
66
|
+
* so it can be associated via `aria-describedby` and read by
|
|
67
|
+
* screen readers as the user interacts with the date field.
|
|
68
|
+
*/
|
|
69
|
+
export declare function setDescription(id: string, formatter: Formatter, value: DateValue): void;
|
|
70
|
+
/**
|
|
71
|
+
* Removes the description element for the date field with
|
|
72
|
+
* the provided ID. This function should be called when the
|
|
73
|
+
* date field is unmounted.
|
|
74
|
+
*/
|
|
75
|
+
export declare function removeDescriptionElement(id: string): void;
|
|
76
|
+
export {};
|