@k2b/ui 0.50.0 → 0.51.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/base.css +32 -1
- package/dist/browser/actions/Button.js.map +1 -1
- package/dist/browser/actions/CommandList.js +861 -0
- package/dist/browser/actions/CommandList.js.map +1 -0
- package/dist/browser/actions/CommandMenu.js +237 -0
- package/dist/browser/actions/CommandMenu.js.map +1 -0
- package/dist/browser/actions/Dropdown.js +43 -10
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/command-dock.js +47 -0
- package/dist/browser/actions/command-dock.js.map +1 -0
- package/dist/browser/actions/command-items.js +84 -0
- package/dist/browser/actions/command-items.js.map +1 -0
- package/dist/browser/actions/command-messages.js +42 -0
- package/dist/browser/actions/command-messages.js.map +1 -0
- package/dist/browser/actions/index.js +1 -0
- package/dist/browser/actions/index.js.map +1 -1
- package/dist/browser/charts/core/area.js +3 -5
- package/dist/browser/charts/core/area.js.map +1 -1
- package/dist/browser/charts/core/calendar.js +1 -1
- package/dist/browser/charts/core/calendar.js.map +1 -1
- package/dist/browser/charts/core/chart-messages.js +17 -0
- package/dist/browser/charts/core/chart-messages.js.map +1 -0
- package/dist/browser/charts/core/hbar-layout.js +118 -0
- package/dist/browser/charts/core/hbar-layout.js.map +1 -0
- package/dist/browser/charts/core/hbar.js +39 -0
- package/dist/browser/charts/core/hbar.js.map +1 -0
- package/dist/browser/charts/core/index.js +7 -2
- package/dist/browser/charts/core/index.js.map +1 -1
- package/dist/browser/charts/core/map.js +116 -0
- package/dist/browser/charts/core/map.js.map +1 -0
- package/dist/browser/charts/core/registry.js +22 -15
- package/dist/browser/charts/core/registry.js.map +1 -1
- package/dist/browser/charts/core/render-size.js +13 -0
- package/dist/browser/charts/core/render-size.js.map +1 -0
- package/dist/browser/charts/core/render.js +20 -10
- package/dist/browser/charts/core/render.js.map +1 -1
- package/dist/browser/charts/core/snapshot.js +3 -3
- package/dist/browser/charts/core/snapshot.js.map +1 -1
- package/dist/browser/charts/core/svg-renderers.js +2406 -0
- package/dist/browser/charts/core/svg-renderers.js.map +1 -0
- package/dist/browser/charts/core/svg.js +4 -2525
- package/dist/browser/charts/core/svg.js.map +1 -1
- package/dist/browser/charts/core/types.js +0 -2
- package/dist/browser/charts/core/types.js.map +1 -1
- package/dist/browser/charts/core/waterfall.js +162 -0
- package/dist/browser/charts/core/waterfall.js.map +1 -0
- package/dist/browser/charts/description.js +2 -0
- package/dist/browser/charts/description.js.map +1 -0
- package/dist/browser/charts.js.map +1 -1
- package/dist/browser/content/Chart.js +14 -628
- package/dist/browser/content/Chart.js.map +1 -1
- package/dist/browser/content/ChartRoot.js +632 -0
- package/dist/browser/content/ChartRoot.js.map +1 -0
- package/dist/browser/content/ChartSparkline.js +24 -0
- package/dist/browser/content/ChartSparkline.js.map +1 -0
- package/dist/browser/content/FileView.js +111 -61
- package/dist/browser/content/FileView.js.map +1 -1
- package/dist/browser/content/Lightbox.js +8 -8
- package/dist/browser/content/Lightbox.js.map +1 -1
- package/dist/browser/content/MapView.js +30 -28
- package/dist/browser/content/MapView.js.map +1 -1
- package/dist/browser/content/PdfPreview.js +84 -52
- package/dist/browser/content/PdfPreview.js.map +1 -1
- package/dist/browser/content/PdfViewer.js +588 -0
- package/dist/browser/content/PdfViewer.js.map +1 -0
- package/dist/browser/content/chart-bar.js +246 -16
- package/dist/browser/content/chart-bar.js.map +1 -1
- package/dist/browser/content/chart-inspection-core.js +22 -21
- package/dist/browser/content/chart-inspection-core.js.map +1 -1
- package/dist/browser/content/chart-line-gaps.js +1 -1
- package/dist/browser/content/chart-line-gaps.js.map +1 -1
- package/dist/browser/content/chart-message-catalog.js +10 -0
- package/dist/browser/content/chart-message-catalog.js.map +1 -1
- package/dist/browser/content/chart-state-timeline.js +1 -1
- package/dist/browser/content/chart-state-timeline.js.map +1 -1
- package/dist/browser/content/chart-svg.js +2 -1
- package/dist/browser/content/chart-svg.js.map +1 -1
- package/dist/browser/content/index.js +1 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/pdf-document.js +29 -0
- package/dist/browser/content/pdf-document.js.map +1 -0
- package/dist/browser/content/pdf-limits.js +31 -0
- package/dist/browser/content/pdf-limits.js.map +1 -0
- package/dist/browser/content/pdf-messages.js +34 -2
- package/dist/browser/content/pdf-messages.js.map +1 -1
- package/dist/browser/content/pdf-viewer-engine.js +57 -0
- package/dist/browser/content/pdf-viewer-worker.js +28 -0
- package/dist/browser/inputs/ChoiceInputs.js +94 -51
- package/dist/browser/inputs/ChoiceInputs.js.map +1 -1
- package/dist/browser/inputs/ChoiceSlider.js +75 -58
- package/dist/browser/inputs/ChoiceSlider.js.map +1 -1
- package/dist/browser/inputs/DatePicker.js +113 -98
- package/dist/browser/inputs/DatePicker.js.map +1 -1
- package/dist/browser/inputs/PeriodPicker.js +874 -0
- package/dist/browser/inputs/PeriodPicker.js.map +1 -0
- package/dist/browser/inputs/index.js +4 -1
- package/dist/browser/inputs/index.js.map +1 -1
- package/dist/browser/inputs/input-messages.js +8 -2
- package/dist/browser/inputs/input-messages.js.map +1 -1
- package/dist/browser/inputs/markdown/MarkdownEditor.js +14 -10
- package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
- package/dist/browser/inputs/markdown/SlashCommands.js +402 -0
- package/dist/browser/inputs/markdown/SlashCommands.js.map +1 -0
- package/dist/browser/inputs/period-picker-messages.js +71 -0
- package/dist/browser/inputs/period-picker-messages.js.map +1 -0
- package/dist/browser/inputs/period.js +263 -0
- package/dist/browser/inputs/period.js.map +1 -0
- package/dist/browser/layout/DetailPanel.js +147 -120
- package/dist/browser/layout/DetailPanel.js.map +1 -1
- package/dist/browser/layout/Discussion.js +101 -108
- package/dist/browser/layout/Discussion.js.map +1 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/surfaces/DescriptionList.js +5 -2
- package/dist/browser/surfaces/DescriptionList.js.map +1 -1
- package/dist/browser/surfaces/StatCell.js +19 -14
- package/dist/browser/surfaces/StatCell.js.map +1 -1
- package/dist/browser/surfaces/delta-badge.js +16 -2
- package/dist/browser/surfaces/delta-badge.js.map +1 -1
- package/dist/browser/widgets/DashboardFrame.js +310 -0
- package/dist/browser/widgets/DashboardFrame.js.map +1 -0
- package/dist/browser/widgets/index.js +1 -0
- package/dist/browser/widgets/index.js.map +1 -1
- package/dist/licenses/pdfjs-dist.txt +177 -0
- package/dist/ssr/actions/Button.js.map +1 -1
- package/dist/ssr/actions/CommandList.js +638 -0
- package/dist/ssr/actions/CommandList.js.map +1 -0
- package/dist/ssr/actions/CommandMenu.js +197 -0
- package/dist/ssr/actions/CommandMenu.js.map +1 -0
- package/dist/ssr/actions/Dropdown.js +43 -10
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/command-dock.js +47 -0
- package/dist/ssr/actions/command-dock.js.map +1 -0
- package/dist/ssr/actions/command-items.js +84 -0
- package/dist/ssr/actions/command-items.js.map +1 -0
- package/dist/ssr/actions/command-messages.js +42 -0
- package/dist/ssr/actions/command-messages.js.map +1 -0
- package/dist/ssr/actions/index.js +1 -0
- package/dist/ssr/actions/index.js.map +1 -1
- package/dist/ssr/charts/core/area.js +3 -5
- package/dist/ssr/charts/core/area.js.map +1 -1
- package/dist/ssr/charts/core/calendar.js +1 -1
- package/dist/ssr/charts/core/calendar.js.map +1 -1
- package/dist/ssr/charts/core/chart-messages.js +17 -0
- package/dist/ssr/charts/core/chart-messages.js.map +1 -0
- package/dist/ssr/charts/core/hbar-layout.js +118 -0
- package/dist/ssr/charts/core/hbar-layout.js.map +1 -0
- package/dist/ssr/charts/core/hbar.js +39 -0
- package/dist/ssr/charts/core/hbar.js.map +1 -0
- package/dist/ssr/charts/core/index.js +7 -2
- package/dist/ssr/charts/core/index.js.map +1 -1
- package/dist/ssr/charts/core/map.js +116 -0
- package/dist/ssr/charts/core/map.js.map +1 -0
- package/dist/ssr/charts/core/registry.js +22 -15
- package/dist/ssr/charts/core/registry.js.map +1 -1
- package/dist/ssr/charts/core/render-size.js +13 -0
- package/dist/ssr/charts/core/render-size.js.map +1 -0
- package/dist/ssr/charts/core/render.js +20 -10
- package/dist/ssr/charts/core/render.js.map +1 -1
- package/dist/ssr/charts/core/snapshot.js +3 -3
- package/dist/ssr/charts/core/snapshot.js.map +1 -1
- package/dist/ssr/charts/core/svg-renderers.js +2406 -0
- package/dist/ssr/charts/core/svg-renderers.js.map +1 -0
- package/dist/ssr/charts/core/svg.js +4 -2525
- package/dist/ssr/charts/core/svg.js.map +1 -1
- package/dist/ssr/charts/core/types.js +0 -2
- package/dist/ssr/charts/core/types.js.map +1 -1
- package/dist/ssr/charts/core/waterfall.js +162 -0
- package/dist/ssr/charts/core/waterfall.js.map +1 -0
- package/dist/ssr/charts/description.js +2 -0
- package/dist/ssr/charts/description.js.map +1 -0
- package/dist/ssr/charts.js.map +1 -1
- package/dist/ssr/content/Chart.js +14 -471
- package/dist/ssr/content/Chart.js.map +1 -1
- package/dist/ssr/content/ChartRoot.js +475 -0
- package/dist/ssr/content/ChartRoot.js.map +1 -0
- package/dist/ssr/content/ChartSparkline.js +24 -0
- package/dist/ssr/content/ChartSparkline.js.map +1 -0
- package/dist/ssr/content/FileView.js +56 -7
- package/dist/ssr/content/FileView.js.map +1 -1
- package/dist/ssr/content/Lightbox.js +8 -8
- package/dist/ssr/content/Lightbox.js.map +1 -1
- package/dist/ssr/content/MapView.js +9 -9
- package/dist/ssr/content/MapView.js.map +1 -1
- package/dist/ssr/content/PdfPreview.js +49 -20
- package/dist/ssr/content/PdfPreview.js.map +1 -1
- package/dist/ssr/content/PdfViewer.js +484 -0
- package/dist/ssr/content/PdfViewer.js.map +1 -0
- package/dist/ssr/content/chart-bar.js +246 -16
- package/dist/ssr/content/chart-bar.js.map +1 -1
- package/dist/ssr/content/chart-inspection-core.js +22 -21
- package/dist/ssr/content/chart-inspection-core.js.map +1 -1
- package/dist/ssr/content/chart-line-gaps.js +1 -1
- package/dist/ssr/content/chart-line-gaps.js.map +1 -1
- package/dist/ssr/content/chart-message-catalog.js +10 -0
- package/dist/ssr/content/chart-message-catalog.js.map +1 -1
- package/dist/ssr/content/chart-state-timeline.js +1 -1
- package/dist/ssr/content/chart-state-timeline.js.map +1 -1
- package/dist/ssr/content/chart-svg.js +2 -1
- package/dist/ssr/content/chart-svg.js.map +1 -1
- package/dist/ssr/content/index.js +1 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/pdf-document.js +29 -0
- package/dist/ssr/content/pdf-document.js.map +1 -0
- package/dist/ssr/content/pdf-limits.js +31 -0
- package/dist/ssr/content/pdf-limits.js.map +1 -0
- package/dist/ssr/content/pdf-messages.js +34 -2
- package/dist/ssr/content/pdf-messages.js.map +1 -1
- package/dist/ssr/inputs/ChoiceInputs.js +49 -12
- package/dist/ssr/inputs/ChoiceInputs.js.map +1 -1
- package/dist/ssr/inputs/ChoiceSlider.js +17 -12
- package/dist/ssr/inputs/ChoiceSlider.js.map +1 -1
- package/dist/ssr/inputs/DatePicker.js +14 -9
- package/dist/ssr/inputs/DatePicker.js.map +1 -1
- package/dist/ssr/inputs/PeriodPicker.js +598 -0
- package/dist/ssr/inputs/PeriodPicker.js.map +1 -0
- package/dist/ssr/inputs/index.js +4 -1
- package/dist/ssr/inputs/index.js.map +1 -1
- package/dist/ssr/inputs/input-messages.js +8 -2
- package/dist/ssr/inputs/input-messages.js.map +1 -1
- package/dist/ssr/inputs/markdown/MarkdownEditor.js +3 -2
- package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
- package/dist/ssr/inputs/markdown/SlashCommands.js +339 -0
- package/dist/ssr/inputs/markdown/SlashCommands.js.map +1 -0
- package/dist/ssr/inputs/period-picker-messages.js +71 -0
- package/dist/ssr/inputs/period-picker-messages.js.map +1 -0
- package/dist/ssr/inputs/period.js +263 -0
- package/dist/ssr/inputs/period.js.map +1 -0
- package/dist/ssr/layout/DetailPanel.js +27 -4
- package/dist/ssr/layout/DetailPanel.js.map +1 -1
- package/dist/ssr/layout/Discussion.js +16 -2
- package/dist/ssr/layout/Discussion.js.map +1 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/surfaces/DescriptionList.js +1 -1
- package/dist/ssr/surfaces/DescriptionList.js.map +1 -1
- package/dist/ssr/surfaces/StatCell.js +4 -5
- package/dist/ssr/surfaces/StatCell.js.map +1 -1
- package/dist/ssr/surfaces/delta-badge.js +16 -2
- package/dist/ssr/surfaces/delta-badge.js.map +1 -1
- package/dist/ssr/widgets/DashboardFrame.js +200 -0
- package/dist/ssr/widgets/DashboardFrame.js.map +1 -0
- package/dist/ssr/widgets/index.js +1 -0
- package/dist/ssr/widgets/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/Button.d.ts +1 -1
- package/dist/types/actions/CommandList.d.ts +120 -0
- package/dist/types/actions/CommandMenu.d.ts +39 -0
- package/dist/types/actions/Dropdown.d.ts +17 -0
- package/dist/types/actions/command-dock.d.ts +8 -0
- package/dist/types/actions/command-items.d.ts +134 -0
- package/dist/types/actions/command-messages.d.ts +19 -0
- package/dist/types/actions/index.d.ts +3 -0
- package/dist/types/charts/core/calendar.d.ts +1 -1
- package/dist/types/charts/core/chart-messages.d.ts +5 -0
- package/dist/types/charts/core/hbar-layout.d.ts +74 -0
- package/dist/types/charts/core/hbar.d.ts +13 -0
- package/dist/types/charts/core/index.d.ts +7 -2
- package/dist/types/charts/core/map.d.ts +3 -0
- package/dist/types/charts/core/registry.d.ts +17 -11
- package/dist/types/charts/core/render-size.d.ts +7 -0
- package/dist/types/charts/core/render.d.ts +1 -4
- package/dist/types/charts/core/snapshot.d.ts +2 -2
- package/dist/types/charts/core/svg-renderers.d.ts +722 -0
- package/dist/types/charts/core/svg.d.ts +4 -698
- package/dist/types/charts/core/types.d.ts +1 -12
- package/dist/types/charts/core/waterfall.d.ts +68 -0
- package/dist/types/charts/description.d.ts +226 -0
- package/dist/types/charts.d.ts +1 -0
- package/dist/types/content/Chart.d.ts +3 -91
- package/dist/types/content/ChartRoot.d.ts +92 -0
- package/dist/types/content/ChartSparkline.d.ts +5 -0
- package/dist/types/content/PdfViewer.d.ts +32 -0
- package/dist/types/content/chart-bar.d.ts +95 -2
- package/dist/types/content/index.d.ts +2 -0
- package/dist/types/content/pdf-document.d.ts +5 -0
- package/dist/types/content/pdf-engine.d.ts +9 -0
- package/dist/types/content/pdf-limits.d.ts +43 -0
- package/dist/types/content/pdf-messages.d.ts +16 -0
- package/dist/types/inputs/ChoiceInputs.d.ts +4 -0
- package/dist/types/inputs/ChoiceSlider.d.ts +12 -0
- package/dist/types/inputs/DatePicker.d.ts +22 -0
- package/dist/types/inputs/PeriodPicker.d.ts +24 -0
- package/dist/types/inputs/index.d.ts +8 -2
- package/dist/types/inputs/input-messages.d.ts +3 -0
- package/dist/types/inputs/markdown/MarkdownEditor.d.ts +5 -0
- package/dist/types/inputs/markdown/SlashCommands.d.ts +20 -0
- package/dist/types/inputs/period-picker-messages.d.ts +34 -0
- package/dist/types/inputs/period.d.ts +134 -0
- package/dist/types/layout/DetailPanel.d.ts +12 -0
- package/dist/types/layout/index.d.ts +1 -1
- package/dist/types/surfaces/DescriptionList.d.ts +5 -0
- package/dist/types/surfaces/StatCell.d.ts +6 -1
- package/dist/types/widgets/DashboardFrame.d.ts +58 -0
- package/dist/types/widgets/index.d.ts +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,874 @@
|
|
|
1
|
+
import { template as _$template } from "solid-js/web";
|
|
2
|
+
import { delegateEvents as _$delegateEvents } from "solid-js/web";
|
|
3
|
+
import { className as _$className } from "solid-js/web";
|
|
4
|
+
import { setProperty as _$setProperty } from "solid-js/web";
|
|
5
|
+
import { effect as _$effect } from "solid-js/web";
|
|
6
|
+
import { getNextElement as _$getNextElement } from "solid-js/web";
|
|
7
|
+
import { runHydrationEvents as _$runHydrationEvents } from "solid-js/web";
|
|
8
|
+
import { getNextMarker as _$getNextMarker } from "solid-js/web";
|
|
9
|
+
import { insert as _$insert } from "solid-js/web";
|
|
10
|
+
import { setAttribute as _$setAttribute } from "solid-js/web";
|
|
11
|
+
import { use as _$use } from "solid-js/web";
|
|
12
|
+
import { createComponent as _$createComponent } from "solid-js/web";
|
|
13
|
+
import { memo as _$memo } from "solid-js/web";
|
|
14
|
+
var _tmpl$ = /*#__PURE__*/_$template(`<button type=button class=k2b-period-picker__trigger aria-haspopup=dialog><i class="ti ti-calendar"aria-hidden=true></i><span class=k2b-period-picker__value><span></span><!$><!/></span><i aria-hidden=true>`),
|
|
15
|
+
_tmpl$2 = /*#__PURE__*/_$template(`<div class=k2b-period-picker__popover popover=auto role=dialog>`),
|
|
16
|
+
_tmpl$3 = /*#__PURE__*/_$template(`<span class=k2b-period-picker__detail> · <!$><!/>`),
|
|
17
|
+
_tmpl$4 = /*#__PURE__*/_$template(`<span aria-hidden=true>`),
|
|
18
|
+
_tmpl$5 = /*#__PURE__*/_$template(`<button type=button role=option class="k2b-dropdown__item k2b-period-picker__option k2b-period-picker__custom"><span class=k2b-dropdown__copy><span></span></span><span class=k2b-period-picker__hint></span><i class="ti ti-chevron-right k2b-dropdown__check"aria-hidden=true>`),
|
|
19
|
+
_tmpl$6 = /*#__PURE__*/_$template(`<div class=k2b-period-picker__list role=listbox><!$><!/><!$><!/>`),
|
|
20
|
+
_tmpl$7 = /*#__PURE__*/_$template(`<div class=k2b-period-picker__panel><!$><!/><!$><!/>`),
|
|
21
|
+
_tmpl$8 = /*#__PURE__*/_$template(`<button type=button role=option class="k2b-dropdown__item k2b-period-picker__option"><span class=k2b-dropdown__copy><span></span></span><span class=k2b-period-picker__hint></span><i class="ti ti-check k2b-dropdown__check"aria-hidden=true>`),
|
|
22
|
+
_tmpl$9 = /*#__PURE__*/_$template(`<div class="k2b-field k2b-period-picker__field"><label class=k2b-field__label></label><div class=k2b-input-shell><input class=k2b-input type=text inputmode=numeric autocomplete=off></div><p class=k2b-period-picker__error>`),
|
|
23
|
+
_tmpl$0 = /*#__PURE__*/_$template(`<button type=button class=k2b-period-picker__back><i class="ti ti-chevron-left"aria-hidden=true></i><!$><!/>`),
|
|
24
|
+
_tmpl$1 = /*#__PURE__*/_$template(`<i class="ti ti-hourglass-low"aria-hidden=true>`),
|
|
25
|
+
_tmpl$10 = /*#__PURE__*/_$template(`<div class=k2b-period-picker__editor role=group><!$><!/><div class=k2b-period-picker__fields><!$><!/><!$><!/></div><div class=k2b-period-picker__months><!$><!/><!$><!/></div><div class=k2b-period-picker__actions><span class=k2b-date-duration aria-live=polite><!$><!/><!$><!/></span><button type=button class=k2b-date-apply>`);
|
|
26
|
+
import { dates } from "@k2b/stdlib";
|
|
27
|
+
import { batch, createComputed, createEffect, createMemo, createSignal, For, on, onCleanup, Show } from "solid-js";
|
|
28
|
+
import { prefersMenuSheet } from "../actions/phone-sheet";
|
|
29
|
+
import { createFieldMeta, Field, fieldDescribedBy } from "../internal/field";
|
|
30
|
+
import { returnFocus, ringOnReturn } from "../internal/focus-return";
|
|
31
|
+
import { useDateConfigLocale } from "../intl/locale";
|
|
32
|
+
import { useUiMessages } from "../intl/messages";
|
|
33
|
+
import { DatePickerPanel } from "./DatePicker";
|
|
34
|
+
import { dateInputPattern, formatDateInput, parseDateInput } from "./date-input";
|
|
35
|
+
import { resolveDateInputMessages } from "./date-input-messages";
|
|
36
|
+
import { errorText } from "./date-input-status";
|
|
37
|
+
import { parseDateValue, pickRangeDay, previewRange, rangeAnchor } from "./date-picker";
|
|
38
|
+
import { commitFieldValue, resolveMaybeAccessor } from "./field-contract";
|
|
39
|
+
import { formatPeriodDays, formatPeriodRange, periodContext, periodDayCount, widePeriodRangeSample } from "./period";
|
|
40
|
+
import { builtInPresetLabel, usePeriodPickerMessages } from "./period-picker-messages";
|
|
41
|
+
/** Two months side by side need room for the list and both calendars. */
|
|
42
|
+
const TWO_MONTHS_QUERY = "(min-width: 56rem)";
|
|
43
|
+
const presetLabel = (preset, t) => preset.label ?? builtInPresetLabel(t, preset.key) ?? preset.key;
|
|
44
|
+
|
|
45
|
+
/** Places the popover under (or over) the trigger; it grows toward the side with room, right-aligned near the right edge. */
|
|
46
|
+
const placePeriodPopover = (trigger, popover) => {
|
|
47
|
+
const margin = 8;
|
|
48
|
+
const gap = 4;
|
|
49
|
+
const rect = trigger.getBoundingClientRect();
|
|
50
|
+
const box = popover.getBoundingClientRect();
|
|
51
|
+
const width = Math.min(box.width, window.innerWidth - margin * 2);
|
|
52
|
+
const fromLeft = rect.left;
|
|
53
|
+
const fromRight = rect.right - width;
|
|
54
|
+
const left = fromLeft + width <= window.innerWidth - margin ? fromLeft : Math.max(margin, fromRight);
|
|
55
|
+
const roomBelow = window.innerHeight - rect.bottom - gap - margin;
|
|
56
|
+
const roomAbove = rect.top - gap - margin;
|
|
57
|
+
const above = box.height > roomBelow && roomAbove > roomBelow;
|
|
58
|
+
const top = above ? Math.max(margin, rect.top - box.height - gap) : Math.min(rect.bottom + gap, window.innerHeight - box.height - margin);
|
|
59
|
+
popover.style.left = `${Math.max(margin, Math.min(left, window.innerWidth - width - margin))}px`;
|
|
60
|
+
popover.style.top = `${Math.max(margin, top)}px`;
|
|
61
|
+
};
|
|
62
|
+
const popoverIsOpen = popover => {
|
|
63
|
+
try {
|
|
64
|
+
return Boolean(popover?.matches(":popover-open"));
|
|
65
|
+
} catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* PeriodPicker — one control for the period an evaluation or dashboard shows: presets such as "This month" plus a
|
|
72
|
+
* custom range, edited in the same popover (a bottom sheet on phones). The trigger shows the preset with its days or
|
|
73
|
+
* the custom days with their count, and keeps the width of its longest text so nothing beside it moves.
|
|
74
|
+
*/
|
|
75
|
+
export function PeriodPicker(props) {
|
|
76
|
+
const t = usePeriodPickerMessages();
|
|
77
|
+
const meta = createFieldMeta(props.id);
|
|
78
|
+
const dateConfig = useDateConfigLocale(() => props.dateConfig);
|
|
79
|
+
const locale = () => dateConfig().locale ?? "en";
|
|
80
|
+
const value = () => resolveMaybeAccessor(props.value);
|
|
81
|
+
const custom = () => props.custom ?? true;
|
|
82
|
+
const disabled = createMemo(() => Boolean(props.disabled || props.loading));
|
|
83
|
+
// Read again on every opening, so a picker left open past midnight shows the new day's presets next time.
|
|
84
|
+
const [clockTick, setClockTick] = createSignal(0);
|
|
85
|
+
const context = createMemo(() => {
|
|
86
|
+
clockTick();
|
|
87
|
+
return periodContext({
|
|
88
|
+
now: props.now,
|
|
89
|
+
timeZone: dateConfig().timeZone,
|
|
90
|
+
weekStartsOn: dateConfig().weekStartsOn ?? dateConfig().firstDayOfWeek
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
const since = date => t().since({
|
|
94
|
+
date
|
|
95
|
+
});
|
|
96
|
+
const presetText = preset => ({
|
|
97
|
+
label: presetLabel(preset, t()),
|
|
98
|
+
detail: formatPeriodDays(preset.resolve(context()), context().today, locale(), since)
|
|
99
|
+
});
|
|
100
|
+
const rangeText = range => ({
|
|
101
|
+
label: formatPeriodRange(range, locale()),
|
|
102
|
+
detail: t().days({
|
|
103
|
+
count: periodDayCount(range)
|
|
104
|
+
})
|
|
105
|
+
});
|
|
106
|
+
const selectedPreset = () => {
|
|
107
|
+
const current = value();
|
|
108
|
+
return current && "preset" in current ? props.presets.find(preset => preset.key === current.preset) : undefined;
|
|
109
|
+
};
|
|
110
|
+
const current = createMemo(() => {
|
|
111
|
+
const selected = value();
|
|
112
|
+
if (!selected) return undefined;
|
|
113
|
+
if ("preset" in selected) {
|
|
114
|
+
const preset = selectedPreset();
|
|
115
|
+
return preset ? presetText(preset) : undefined;
|
|
116
|
+
}
|
|
117
|
+
return rangeText(selected);
|
|
118
|
+
});
|
|
119
|
+
const joined = text => text.detail ? `${text.label} · ${text.detail}` : text.label;
|
|
120
|
+
// Every text the trigger can show shares one grid cell, so it keeps the widest one's width.
|
|
121
|
+
const widths = createMemo(() => [...props.presets.map(preset => joined(presetText(preset))), ...(custom() ? [joined(rangeText(widePeriodRangeSample(context().today)))] : []), t().choosePeriod]);
|
|
122
|
+
const [open, setOpen] = createSignal(false);
|
|
123
|
+
const [view, setView] = createSignal("list");
|
|
124
|
+
const [sheetOpen, setSheetOpen] = createSignal(false);
|
|
125
|
+
let trigger;
|
|
126
|
+
let popover;
|
|
127
|
+
let openedByKeyboard = false;
|
|
128
|
+
const popoverId = `${meta.controlId}-period`;
|
|
129
|
+
const sheetId = `${meta.controlId}-sheet`;
|
|
130
|
+
const valueId = `${meta.controlId}-value`;
|
|
131
|
+
|
|
132
|
+
// A trigger disabled while a change saves would drop keyboard focus on the page; it comes back once enabled.
|
|
133
|
+
let refocus = false;
|
|
134
|
+
createComputed(on(disabled, isDisabled => {
|
|
135
|
+
if (isDisabled) refocus = trigger !== undefined && document.activeElement === trigger;
|
|
136
|
+
}, {
|
|
137
|
+
defer: true
|
|
138
|
+
}));
|
|
139
|
+
createEffect(on(disabled, isDisabled => {
|
|
140
|
+
if (isDisabled || !refocus) return;
|
|
141
|
+
refocus = false;
|
|
142
|
+
const active = document.activeElement;
|
|
143
|
+
if (trigger?.isConnected && (active === null || active === document.body)) trigger.focus();
|
|
144
|
+
}, {
|
|
145
|
+
defer: true
|
|
146
|
+
}));
|
|
147
|
+
const place = () => {
|
|
148
|
+
if (trigger && popover && open()) placePeriodPopover(trigger, popover);
|
|
149
|
+
};
|
|
150
|
+
createEffect(() => {
|
|
151
|
+
if (!open()) return;
|
|
152
|
+
view();
|
|
153
|
+
queueMicrotask(place);
|
|
154
|
+
window.addEventListener("resize", place);
|
|
155
|
+
window.addEventListener("scroll", place, true);
|
|
156
|
+
onCleanup(() => {
|
|
157
|
+
window.removeEventListener("resize", place);
|
|
158
|
+
window.removeEventListener("scroll", place, true);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
const close = () => {
|
|
162
|
+
// Before hiding, so the popover does not return focus on its own.
|
|
163
|
+
if (popover?.contains(document.activeElement)) returnFocus(trigger, openedByKeyboard);
|
|
164
|
+
if (popoverIsOpen(popover)) popover?.hidePopover();
|
|
165
|
+
setOpen(false);
|
|
166
|
+
};
|
|
167
|
+
onCleanup(() => {
|
|
168
|
+
if (popoverIsOpen(popover)) popover?.hidePopover();
|
|
169
|
+
});
|
|
170
|
+
const pick = next => {
|
|
171
|
+
close();
|
|
172
|
+
if (sheetOpen()) return;
|
|
173
|
+
commitFieldValue(props, next);
|
|
174
|
+
};
|
|
175
|
+
const initialView = () => {
|
|
176
|
+
const selected = value();
|
|
177
|
+
return custom() && selected && !("preset" in selected) ? "custom" : "list";
|
|
178
|
+
};
|
|
179
|
+
const openSheet = async () => {
|
|
180
|
+
setSheetOpen(true);
|
|
181
|
+
const {
|
|
182
|
+
openDateSheet
|
|
183
|
+
} = await import("./date-sheet");
|
|
184
|
+
const result = await openDateSheet({
|
|
185
|
+
title: typeof props.label === "string" ? props.label : props["aria-label"] ?? t().period,
|
|
186
|
+
subtitle: current() ? joined(current()) : t().choosePeriod,
|
|
187
|
+
ariaLabel: typeof props.label === "string" ? props.label : props["aria-label"] ?? t().period,
|
|
188
|
+
id: sheetId,
|
|
189
|
+
locale: locale(),
|
|
190
|
+
content: closeSheet => _$createComponent(PeriodPanel, {
|
|
191
|
+
sheet: true,
|
|
192
|
+
get presets() {
|
|
193
|
+
return props.presets;
|
|
194
|
+
},
|
|
195
|
+
get custom() {
|
|
196
|
+
return custom();
|
|
197
|
+
},
|
|
198
|
+
value: value,
|
|
199
|
+
get initialView() {
|
|
200
|
+
return initialView();
|
|
201
|
+
},
|
|
202
|
+
context: context,
|
|
203
|
+
dateConfig: dateConfig,
|
|
204
|
+
presetText: presetText,
|
|
205
|
+
rangeText: rangeText,
|
|
206
|
+
get label() {
|
|
207
|
+
return props["aria-label"] ?? t().period;
|
|
208
|
+
},
|
|
209
|
+
onPick: closeSheet
|
|
210
|
+
})
|
|
211
|
+
});
|
|
212
|
+
setSheetOpen(false);
|
|
213
|
+
if (result) commitFieldValue(props, result);
|
|
214
|
+
trigger?.focus({
|
|
215
|
+
preventScroll: true
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
const show = () => {
|
|
219
|
+
if (disabled() || !popover) return;
|
|
220
|
+
setClockTick(tick => tick + 1);
|
|
221
|
+
openedByKeyboard = ringOnReturn(trigger);
|
|
222
|
+
if (prefersMenuSheet()) return void openSheet();
|
|
223
|
+
setView(initialView());
|
|
224
|
+
popover.showPopover();
|
|
225
|
+
setOpen(true);
|
|
226
|
+
queueMicrotask(() => {
|
|
227
|
+
place();
|
|
228
|
+
popover?.querySelector('[role="option"][tabindex="0"]')?.focus();
|
|
229
|
+
});
|
|
230
|
+
};
|
|
231
|
+
const name = () => props.label ? undefined : `${props["aria-label"] ?? t().period}: ${current() ? joined(current()) : t().choosePeriod}`;
|
|
232
|
+
return _$createComponent(Field, {
|
|
233
|
+
get ["class"]() {
|
|
234
|
+
return `k2b-period-picker ${props.class ?? ""}`;
|
|
235
|
+
},
|
|
236
|
+
get label() {
|
|
237
|
+
return props.label;
|
|
238
|
+
},
|
|
239
|
+
get description() {
|
|
240
|
+
return props.description;
|
|
241
|
+
},
|
|
242
|
+
get error() {
|
|
243
|
+
return props.error;
|
|
244
|
+
},
|
|
245
|
+
meta: meta,
|
|
246
|
+
get required() {
|
|
247
|
+
return props.required;
|
|
248
|
+
},
|
|
249
|
+
get disabled() {
|
|
250
|
+
return disabled();
|
|
251
|
+
},
|
|
252
|
+
get children() {
|
|
253
|
+
return [(() => {
|
|
254
|
+
var _el$ = _$getNextElement(_tmpl$),
|
|
255
|
+
_el$2 = _el$.firstChild,
|
|
256
|
+
_el$3 = _el$2.nextSibling,
|
|
257
|
+
_el$4 = _el$3.firstChild,
|
|
258
|
+
_el$5 = _el$4.nextSibling,
|
|
259
|
+
[_el$6, _co$] = _$getNextMarker(_el$5.nextSibling),
|
|
260
|
+
_el$7 = _el$3.nextSibling;
|
|
261
|
+
_el$.$$keydown = event => {
|
|
262
|
+
if ((event.key === "ArrowDown" || event.key === "ArrowUp") && !open()) {
|
|
263
|
+
event.preventDefault();
|
|
264
|
+
show();
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
_el$.$$click = () => open() ? close() : show();
|
|
268
|
+
var _ref$ = trigger;
|
|
269
|
+
typeof _ref$ === "function" ? _$use(_ref$, _el$) : trigger = _el$;
|
|
270
|
+
_$setAttribute(_el$4, "id", valueId);
|
|
271
|
+
_$insert(_el$4, _$createComponent(Show, {
|
|
272
|
+
get when() {
|
|
273
|
+
return current();
|
|
274
|
+
},
|
|
275
|
+
get fallback() {
|
|
276
|
+
return t().choosePeriod;
|
|
277
|
+
},
|
|
278
|
+
children: text => [_$memo(() => text().label), _$createComponent(Show, {
|
|
279
|
+
get when() {
|
|
280
|
+
return text().detail;
|
|
281
|
+
},
|
|
282
|
+
get children() {
|
|
283
|
+
var _el$9 = _$getNextElement(_tmpl$3),
|
|
284
|
+
_el$0 = _el$9.firstChild,
|
|
285
|
+
_el$1 = _el$0.nextSibling,
|
|
286
|
+
[_el$10, _co$2] = _$getNextMarker(_el$1.nextSibling);
|
|
287
|
+
_$insert(_el$9, () => text().detail, _el$10, _co$2);
|
|
288
|
+
return _el$9;
|
|
289
|
+
}
|
|
290
|
+
})]
|
|
291
|
+
}));
|
|
292
|
+
_$insert(_el$3, _$createComponent(For, {
|
|
293
|
+
get each() {
|
|
294
|
+
return widths();
|
|
295
|
+
},
|
|
296
|
+
children: text => (() => {
|
|
297
|
+
var _el$11 = _$getNextElement(_tmpl$4);
|
|
298
|
+
_$insert(_el$11, text);
|
|
299
|
+
return _el$11;
|
|
300
|
+
})()
|
|
301
|
+
}), _el$6, _co$);
|
|
302
|
+
_$effect(_p$ => {
|
|
303
|
+
var _v$ = meta.controlId,
|
|
304
|
+
_v$2 = open() || sheetOpen(),
|
|
305
|
+
_v$3 = sheetOpen() ? sheetId : popoverId,
|
|
306
|
+
_v$4 = name(),
|
|
307
|
+
_v$5 = props.label ? `${meta.labelId} ${valueId}` : undefined,
|
|
308
|
+
_v$6 = fieldDescribedBy(meta, props),
|
|
309
|
+
_v$7 = resolveMaybeAccessor(props.error) ? "true" : undefined,
|
|
310
|
+
_v$8 = props.loading ? "true" : undefined,
|
|
311
|
+
_v$9 = disabled(),
|
|
312
|
+
_v$0 = current() ? undefined : "true",
|
|
313
|
+
_v$1 = props.loading ? "ti ti-loader-2 k2b-spin" : "ti ti-chevron-down";
|
|
314
|
+
_v$ !== _p$.e && _$setAttribute(_el$, "id", _p$.e = _v$);
|
|
315
|
+
_v$2 !== _p$.t && _$setAttribute(_el$, "aria-expanded", _p$.t = _v$2);
|
|
316
|
+
_v$3 !== _p$.a && _$setAttribute(_el$, "aria-controls", _p$.a = _v$3);
|
|
317
|
+
_v$4 !== _p$.o && _$setAttribute(_el$, "aria-label", _p$.o = _v$4);
|
|
318
|
+
_v$5 !== _p$.i && _$setAttribute(_el$, "aria-labelledby", _p$.i = _v$5);
|
|
319
|
+
_v$6 !== _p$.n && _$setAttribute(_el$, "aria-describedby", _p$.n = _v$6);
|
|
320
|
+
_v$7 !== _p$.s && _$setAttribute(_el$, "aria-invalid", _p$.s = _v$7);
|
|
321
|
+
_v$8 !== _p$.h && _$setAttribute(_el$, "aria-busy", _p$.h = _v$8);
|
|
322
|
+
_v$9 !== _p$.r && _$setProperty(_el$, "disabled", _p$.r = _v$9);
|
|
323
|
+
_v$0 !== _p$.d && _$setAttribute(_el$3, "data-placeholder", _p$.d = _v$0);
|
|
324
|
+
_v$1 !== _p$.l && _$className(_el$7, _p$.l = _v$1);
|
|
325
|
+
return _p$;
|
|
326
|
+
}, {
|
|
327
|
+
e: undefined,
|
|
328
|
+
t: undefined,
|
|
329
|
+
a: undefined,
|
|
330
|
+
o: undefined,
|
|
331
|
+
i: undefined,
|
|
332
|
+
n: undefined,
|
|
333
|
+
s: undefined,
|
|
334
|
+
h: undefined,
|
|
335
|
+
r: undefined,
|
|
336
|
+
d: undefined,
|
|
337
|
+
l: undefined
|
|
338
|
+
});
|
|
339
|
+
_$runHydrationEvents();
|
|
340
|
+
return _el$;
|
|
341
|
+
})(), (() => {
|
|
342
|
+
var _el$8 = _$getNextElement(_tmpl$2);
|
|
343
|
+
_el$8.$$keydown = event => {
|
|
344
|
+
if (event.key !== "Escape") return;
|
|
345
|
+
event.preventDefault();
|
|
346
|
+
event.stopPropagation();
|
|
347
|
+
close();
|
|
348
|
+
};
|
|
349
|
+
_$use(element => {
|
|
350
|
+
popover = element;
|
|
351
|
+
// Light dismiss (a click outside) hides it without us; keep the state in step.
|
|
352
|
+
element.addEventListener("toggle", () => {
|
|
353
|
+
if (!popoverIsOpen(element)) setOpen(false);
|
|
354
|
+
});
|
|
355
|
+
}, _el$8);
|
|
356
|
+
_$setAttribute(_el$8, "id", popoverId);
|
|
357
|
+
_$insert(_el$8, _$createComponent(Show, {
|
|
358
|
+
get when() {
|
|
359
|
+
return open();
|
|
360
|
+
},
|
|
361
|
+
get children() {
|
|
362
|
+
return _$createComponent(PeriodPanel, {
|
|
363
|
+
get presets() {
|
|
364
|
+
return props.presets;
|
|
365
|
+
},
|
|
366
|
+
get custom() {
|
|
367
|
+
return custom();
|
|
368
|
+
},
|
|
369
|
+
value: value,
|
|
370
|
+
get initialView() {
|
|
371
|
+
return view();
|
|
372
|
+
},
|
|
373
|
+
onViewChange: setView,
|
|
374
|
+
context: context,
|
|
375
|
+
dateConfig: dateConfig,
|
|
376
|
+
presetText: presetText,
|
|
377
|
+
rangeText: rangeText,
|
|
378
|
+
get label() {
|
|
379
|
+
return props["aria-label"] ?? t().period;
|
|
380
|
+
},
|
|
381
|
+
onPick: pick
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
}));
|
|
385
|
+
_$effect(() => _$setAttribute(_el$8, "aria-label", props["aria-label"] ?? (typeof props.label === "string" ? props.label : t().period)));
|
|
386
|
+
_$runHydrationEvents();
|
|
387
|
+
return _el$8;
|
|
388
|
+
})()];
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
function PeriodPanel(props) {
|
|
393
|
+
const t = usePeriodPickerMessages();
|
|
394
|
+
const [view, setViewSignal] = createSignal(props.initialView);
|
|
395
|
+
const setView = next => {
|
|
396
|
+
setViewSignal(next);
|
|
397
|
+
props.onViewChange?.(next);
|
|
398
|
+
};
|
|
399
|
+
const selected = () => props.value();
|
|
400
|
+
const explicit = () => {
|
|
401
|
+
const current = selected();
|
|
402
|
+
return current && !("preset" in current) ? current : undefined;
|
|
403
|
+
};
|
|
404
|
+
const isSelected = preset => {
|
|
405
|
+
const current = selected();
|
|
406
|
+
return Boolean(current && "preset" in current && current.preset === preset.key);
|
|
407
|
+
};
|
|
408
|
+
const optionCount = () => props.presets.length + (props.custom ? 1 : 0);
|
|
409
|
+
const initialActive = () => {
|
|
410
|
+
const index = props.presets.findIndex(isSelected);
|
|
411
|
+
if (index >= 0) return index;
|
|
412
|
+
return explicit() && props.custom ? props.presets.length : 0;
|
|
413
|
+
};
|
|
414
|
+
const [active, setActive] = createSignal(initialActive());
|
|
415
|
+
let list;
|
|
416
|
+
const focusOption = index => {
|
|
417
|
+
setActive(index);
|
|
418
|
+
queueMicrotask(() => list?.querySelector(`[data-option-index="${index}"]`)?.focus());
|
|
419
|
+
};
|
|
420
|
+
const onListKeyDown = event => {
|
|
421
|
+
const count = optionCount();
|
|
422
|
+
const moves = {
|
|
423
|
+
ArrowDown: (active() + 1) % count,
|
|
424
|
+
ArrowUp: (active() - 1 + count) % count,
|
|
425
|
+
Home: 0,
|
|
426
|
+
End: count - 1
|
|
427
|
+
};
|
|
428
|
+
const next = moves[event.key];
|
|
429
|
+
if (next === undefined) return;
|
|
430
|
+
event.preventDefault();
|
|
431
|
+
focusOption(next);
|
|
432
|
+
};
|
|
433
|
+
let panel;
|
|
434
|
+
const openCustom = () => {
|
|
435
|
+
setActive(props.presets.length);
|
|
436
|
+
setView("custom");
|
|
437
|
+
// In the sheet the list goes away with the focused option; focus continues on the calendar's day.
|
|
438
|
+
if (props.sheet) queueMicrotask(() => panel?.querySelector('[data-date-focus="true"]')?.focus());
|
|
439
|
+
};
|
|
440
|
+
return (() => {
|
|
441
|
+
var _el$12 = _$getNextElement(_tmpl$7),
|
|
442
|
+
_el$22 = _el$12.firstChild,
|
|
443
|
+
[_el$23, _co$5] = _$getNextMarker(_el$22.nextSibling),
|
|
444
|
+
_el$24 = _el$23.nextSibling,
|
|
445
|
+
[_el$25, _co$6] = _$getNextMarker(_el$24.nextSibling);
|
|
446
|
+
var _ref$2 = panel;
|
|
447
|
+
typeof _ref$2 === "function" ? _$use(_ref$2, _el$12) : panel = _el$12;
|
|
448
|
+
_$insert(_el$12, _$createComponent(Show, {
|
|
449
|
+
get when() {
|
|
450
|
+
return !props.sheet || view() === "list";
|
|
451
|
+
},
|
|
452
|
+
get children() {
|
|
453
|
+
var _el$13 = _$getNextElement(_tmpl$6),
|
|
454
|
+
_el$18 = _el$13.firstChild,
|
|
455
|
+
[_el$19, _co$3] = _$getNextMarker(_el$18.nextSibling),
|
|
456
|
+
_el$20 = _el$19.nextSibling,
|
|
457
|
+
[_el$21, _co$4] = _$getNextMarker(_el$20.nextSibling);
|
|
458
|
+
_el$13.$$keydown = onListKeyDown;
|
|
459
|
+
var _ref$3 = list;
|
|
460
|
+
typeof _ref$3 === "function" ? _$use(_ref$3, _el$13) : list = _el$13;
|
|
461
|
+
_$insert(_el$13, _$createComponent(For, {
|
|
462
|
+
get each() {
|
|
463
|
+
return props.presets;
|
|
464
|
+
},
|
|
465
|
+
children: (preset, index) => {
|
|
466
|
+
const text = () => props.presetText(preset);
|
|
467
|
+
return (() => {
|
|
468
|
+
var _el$26 = _$getNextElement(_tmpl$8),
|
|
469
|
+
_el$27 = _el$26.firstChild,
|
|
470
|
+
_el$28 = _el$27.firstChild,
|
|
471
|
+
_el$29 = _el$27.nextSibling,
|
|
472
|
+
_el$30 = _el$29.nextSibling;
|
|
473
|
+
_el$26.$$click = () => props.onPick({
|
|
474
|
+
preset: preset.key
|
|
475
|
+
});
|
|
476
|
+
_el$26.addEventListener("focus", () => setActive(index()));
|
|
477
|
+
_$insert(_el$28, () => text().label);
|
|
478
|
+
_$insert(_el$29, () => text().detail);
|
|
479
|
+
_$effect(_p$ => {
|
|
480
|
+
var _v$15 = index(),
|
|
481
|
+
_v$16 = isSelected(preset) && view() === "list",
|
|
482
|
+
_v$17 = active() === index() ? 0 : -1,
|
|
483
|
+
_v$18 = isSelected(preset) && view() === "list" ? undefined : "true";
|
|
484
|
+
_v$15 !== _p$.e && _$setAttribute(_el$26, "data-option-index", _p$.e = _v$15);
|
|
485
|
+
_v$16 !== _p$.t && _$setAttribute(_el$26, "aria-selected", _p$.t = _v$16);
|
|
486
|
+
_v$17 !== _p$.a && _$setAttribute(_el$26, "tabindex", _p$.a = _v$17);
|
|
487
|
+
_v$18 !== _p$.o && _$setAttribute(_el$30, "data-hidden", _p$.o = _v$18);
|
|
488
|
+
return _p$;
|
|
489
|
+
}, {
|
|
490
|
+
e: undefined,
|
|
491
|
+
t: undefined,
|
|
492
|
+
a: undefined,
|
|
493
|
+
o: undefined
|
|
494
|
+
});
|
|
495
|
+
_$runHydrationEvents();
|
|
496
|
+
return _el$26;
|
|
497
|
+
})();
|
|
498
|
+
}
|
|
499
|
+
}), _el$19, _co$3);
|
|
500
|
+
_$insert(_el$13, _$createComponent(Show, {
|
|
501
|
+
get when() {
|
|
502
|
+
return props.custom;
|
|
503
|
+
},
|
|
504
|
+
get children() {
|
|
505
|
+
var _el$14 = _$getNextElement(_tmpl$5),
|
|
506
|
+
_el$15 = _el$14.firstChild,
|
|
507
|
+
_el$16 = _el$15.firstChild,
|
|
508
|
+
_el$17 = _el$15.nextSibling;
|
|
509
|
+
_el$14.$$click = openCustom;
|
|
510
|
+
_el$14.addEventListener("focus", () => setActive(props.presets.length));
|
|
511
|
+
_$insert(_el$16, () => t().custom);
|
|
512
|
+
_$insert(_el$17, (() => {
|
|
513
|
+
var _c$ = _$memo(() => !!explicit());
|
|
514
|
+
return () => _c$() ? props.rangeText(explicit()).label : "";
|
|
515
|
+
})());
|
|
516
|
+
_$effect(_p$ => {
|
|
517
|
+
var _v$10 = props.presets.length,
|
|
518
|
+
_v$11 = view() === "custom" || Boolean(explicit()),
|
|
519
|
+
_v$12 = active() === props.presets.length ? 0 : -1;
|
|
520
|
+
_v$10 !== _p$.e && _$setAttribute(_el$14, "data-option-index", _p$.e = _v$10);
|
|
521
|
+
_v$11 !== _p$.t && _$setAttribute(_el$14, "aria-selected", _p$.t = _v$11);
|
|
522
|
+
_v$12 !== _p$.a && _$setAttribute(_el$14, "tabindex", _p$.a = _v$12);
|
|
523
|
+
return _p$;
|
|
524
|
+
}, {
|
|
525
|
+
e: undefined,
|
|
526
|
+
t: undefined,
|
|
527
|
+
a: undefined
|
|
528
|
+
});
|
|
529
|
+
_$runHydrationEvents();
|
|
530
|
+
return _el$14;
|
|
531
|
+
}
|
|
532
|
+
}), _el$21, _co$4);
|
|
533
|
+
_$effect(() => _$setAttribute(_el$13, "aria-label", props.label));
|
|
534
|
+
_$runHydrationEvents();
|
|
535
|
+
return _el$13;
|
|
536
|
+
}
|
|
537
|
+
}), _el$23, _co$5);
|
|
538
|
+
_$insert(_el$12, _$createComponent(Show, {
|
|
539
|
+
get when() {
|
|
540
|
+
return view() === "custom";
|
|
541
|
+
},
|
|
542
|
+
get children() {
|
|
543
|
+
return _$createComponent(RangeEditor, {
|
|
544
|
+
get initial() {
|
|
545
|
+
const current = explicit();
|
|
546
|
+
if (current) return current;
|
|
547
|
+
const preset = props.presets.find(isSelected);
|
|
548
|
+
const range = preset?.resolve(props.context());
|
|
549
|
+
return range?.start && range.end ? {
|
|
550
|
+
start: range.start,
|
|
551
|
+
end: range.end
|
|
552
|
+
} : null;
|
|
553
|
+
},
|
|
554
|
+
get today() {
|
|
555
|
+
return props.context().today;
|
|
556
|
+
},
|
|
557
|
+
get dateConfig() {
|
|
558
|
+
return props.dateConfig;
|
|
559
|
+
},
|
|
560
|
+
get rangeText() {
|
|
561
|
+
return props.rangeText;
|
|
562
|
+
},
|
|
563
|
+
get sheet() {
|
|
564
|
+
return props.sheet;
|
|
565
|
+
},
|
|
566
|
+
onBack: () => {
|
|
567
|
+
setView("list");
|
|
568
|
+
focusOption(props.presets.length);
|
|
569
|
+
},
|
|
570
|
+
onApply: range => props.onPick(range)
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
}), _el$25, _co$6);
|
|
574
|
+
_$effect(_p$ => {
|
|
575
|
+
var _v$13 = view(),
|
|
576
|
+
_v$14 = props.sheet ? "true" : undefined;
|
|
577
|
+
_v$13 !== _p$.e && _$setAttribute(_el$12, "data-view", _p$.e = _v$13);
|
|
578
|
+
_v$14 !== _p$.t && _$setAttribute(_el$12, "data-sheet", _p$.t = _v$14);
|
|
579
|
+
return _p$;
|
|
580
|
+
}, {
|
|
581
|
+
e: undefined,
|
|
582
|
+
t: undefined
|
|
583
|
+
});
|
|
584
|
+
return _el$12;
|
|
585
|
+
})();
|
|
586
|
+
}
|
|
587
|
+
function RangeEditor(props) {
|
|
588
|
+
const t = usePeriodPickerMessages();
|
|
589
|
+
const ui = useUiMessages();
|
|
590
|
+
const locale = () => props.dateConfig().locale ?? "en";
|
|
591
|
+
const inputT = () => resolveDateInputMessages(locale());
|
|
592
|
+
const config = () => ({
|
|
593
|
+
...props.dateConfig(),
|
|
594
|
+
weekStartsOn: props.dateConfig().weekStartsOn ?? props.dateConfig().firstDayOfWeek ?? 1
|
|
595
|
+
});
|
|
596
|
+
const [draft, setDraft] = createSignal({
|
|
597
|
+
start: props.initial?.start ?? null,
|
|
598
|
+
end: props.initial?.end ?? null
|
|
599
|
+
});
|
|
600
|
+
const [anchor, setAnchor] = createSignal(null);
|
|
601
|
+
const [preview, setPreview] = createSignal(null);
|
|
602
|
+
const [startText, setStartText] = createSignal(props.initial ? formatDateInput(props.initial.start, locale()) : "");
|
|
603
|
+
const [endText, setEndText] = createSignal(props.initial ? formatDateInput(props.initial.end, locale()) : "");
|
|
604
|
+
const [startError, setStartError] = createSignal("");
|
|
605
|
+
const [endError, setEndError] = createSignal("");
|
|
606
|
+
// Follows the window: narrowing it below two months' room drops the second month, widening adds it.
|
|
607
|
+
const query = !props.sheet && typeof matchMedia === "function" ? matchMedia(TWO_MONTHS_QUERY) : undefined;
|
|
608
|
+
const [wide, setWide] = createSignal(Boolean(query?.matches));
|
|
609
|
+
if (query) {
|
|
610
|
+
const update = () => setWide(query.matches);
|
|
611
|
+
query.addEventListener("change", update);
|
|
612
|
+
onCleanup(() => query.removeEventListener("change", update));
|
|
613
|
+
}
|
|
614
|
+
const twoMonths = () => !props.sheet && wide();
|
|
615
|
+
// Months are anchored on their 1st: stepping from 31 March or 30 November never skips a month.
|
|
616
|
+
const monthOf = (key, offset = 0) => {
|
|
617
|
+
const year = Number(key.slice(0, 4));
|
|
618
|
+
const month = Number(key.slice(5, 7)) - 1 + offset;
|
|
619
|
+
return parseDateValue(`${year + Math.floor(month / 12)}-${String((month % 12 + 12) % 12 + 1).padStart(2, "0")}-01`, config());
|
|
620
|
+
};
|
|
621
|
+
const keyOf = date => dates.formatDateKey(date, config());
|
|
622
|
+
// The first visible month: the end's month, and the one before it when two months show.
|
|
623
|
+
const [first, setFirstMonth] = createSignal(monthOf(props.initial?.end ?? props.today, twoMonths() ? -1 : 0));
|
|
624
|
+
const setFirst = date => setFirstMonth(monthOf(keyOf(date)));
|
|
625
|
+
const second = createMemo(() => monthOf(keyOf(first()), 1));
|
|
626
|
+
const shown = createMemo(() => previewRange(draft(), anchor(), preview()));
|
|
627
|
+
let months;
|
|
628
|
+
const startId = createFieldMeta().controlId;
|
|
629
|
+
const endId = createFieldMeta().controlId;
|
|
630
|
+
const isShown = date => dates.isSameMonth(date, first(), config()) || twoMonths() && dates.isSameMonth(date, second(), config());
|
|
631
|
+
const fill = range => {
|
|
632
|
+
setStartText(range.start ? formatDateInput(range.start, locale()) : "");
|
|
633
|
+
setEndText(range.end ? formatDateInput(range.end, locale()) : "");
|
|
634
|
+
setStartError("");
|
|
635
|
+
setEndError("");
|
|
636
|
+
};
|
|
637
|
+
const pickDay = key => {
|
|
638
|
+
const next = pickRangeDay(draft(), anchor(), key);
|
|
639
|
+
batch(() => {
|
|
640
|
+
setDraft(next.range);
|
|
641
|
+
setAnchor(next.anchor);
|
|
642
|
+
setPreview(null);
|
|
643
|
+
fill(next.range);
|
|
644
|
+
});
|
|
645
|
+
};
|
|
646
|
+
/** Reads one typed half; returns the day, `null` for empty, or `undefined` after showing an error. */
|
|
647
|
+
const readText = (text, setError) => {
|
|
648
|
+
const result = parseDateInput(text, {
|
|
649
|
+
today: props.today,
|
|
650
|
+
locale: locale()
|
|
651
|
+
});
|
|
652
|
+
if (result.kind === "empty") return null;
|
|
653
|
+
if (result.kind === "error") {
|
|
654
|
+
setError(errorText(result.error, locale(), inputT(), props.today));
|
|
655
|
+
return undefined;
|
|
656
|
+
}
|
|
657
|
+
setError("");
|
|
658
|
+
return result.date;
|
|
659
|
+
};
|
|
660
|
+
const commitTyped = () => {
|
|
661
|
+
const start = readText(startText(), setStartError);
|
|
662
|
+
const end = readText(endText(), setEndError);
|
|
663
|
+
if (start === undefined || end === undefined) return undefined;
|
|
664
|
+
const range = {
|
|
665
|
+
start,
|
|
666
|
+
end
|
|
667
|
+
};
|
|
668
|
+
batch(() => {
|
|
669
|
+
setDraft(range);
|
|
670
|
+
setAnchor(null);
|
|
671
|
+
});
|
|
672
|
+
if (start && end && end < start) {
|
|
673
|
+
setEndError(inputT().endBeforeStart);
|
|
674
|
+
return undefined;
|
|
675
|
+
}
|
|
676
|
+
if (start && !end) setEndError(inputT().missingEnd);
|
|
677
|
+
if (end && !start) setStartError(inputT().missingStart);
|
|
678
|
+
const visible = end ?? start;
|
|
679
|
+
if (visible && !isShown(parseDateValue(visible, config()))) setFirstMonth(monthOf(visible, twoMonths() ? -1 : 0));
|
|
680
|
+
return start && end ? {
|
|
681
|
+
start,
|
|
682
|
+
end
|
|
683
|
+
} : undefined;
|
|
684
|
+
};
|
|
685
|
+
const complete = () => {
|
|
686
|
+
const range = draft();
|
|
687
|
+
return range.start && range.end && !startError() && !endError() ? {
|
|
688
|
+
start: range.start,
|
|
689
|
+
end: range.end
|
|
690
|
+
} : undefined;
|
|
691
|
+
};
|
|
692
|
+
const apply = () => {
|
|
693
|
+
const typed = commitTyped();
|
|
694
|
+
if (typed) props.onApply(typed);
|
|
695
|
+
};
|
|
696
|
+
const fieldKeyDown = event => {
|
|
697
|
+
if (event.key !== "Enter") return;
|
|
698
|
+
event.preventDefault();
|
|
699
|
+
apply();
|
|
700
|
+
};
|
|
701
|
+
const placeholder = () => dateInputPattern(locale(), {
|
|
702
|
+
day: inputT().dayLetters,
|
|
703
|
+
month: inputT().monthLetters,
|
|
704
|
+
year: inputT().yearLetters
|
|
705
|
+
});
|
|
706
|
+
const status = () => {
|
|
707
|
+
const range = shown();
|
|
708
|
+
return range.start && range.end ? props.rangeText({
|
|
709
|
+
start: range.start,
|
|
710
|
+
end: range.end
|
|
711
|
+
}).detail : "";
|
|
712
|
+
};
|
|
713
|
+
const field = fieldProps => (() => {
|
|
714
|
+
var _el$31 = _$getNextElement(_tmpl$9),
|
|
715
|
+
_el$32 = _el$31.firstChild,
|
|
716
|
+
_el$33 = _el$32.nextSibling,
|
|
717
|
+
_el$34 = _el$33.firstChild,
|
|
718
|
+
_el$35 = _el$33.nextSibling;
|
|
719
|
+
_$insert(_el$32, () => fieldProps.label);
|
|
720
|
+
_el$34.$$keydown = fieldKeyDown;
|
|
721
|
+
_el$34.addEventListener("blur", () => commitTyped());
|
|
722
|
+
_el$34.$$input = event => fieldProps.setText(event.currentTarget.value);
|
|
723
|
+
_$setAttribute(_el$34, "spellcheck", false);
|
|
724
|
+
_$insert(_el$35, () => fieldProps.error());
|
|
725
|
+
_$effect(_p$ => {
|
|
726
|
+
var _v$19 = fieldProps.error() ? "true" : undefined,
|
|
727
|
+
_v$20 = fieldProps.id,
|
|
728
|
+
_v$21 = fieldProps.id,
|
|
729
|
+
_v$22 = placeholder(),
|
|
730
|
+
_v$23 = fieldProps.error() ? "true" : undefined,
|
|
731
|
+
_v$24 = fieldProps.error() ? `${fieldProps.id}-error` : undefined,
|
|
732
|
+
_v$25 = `${fieldProps.id}-error`;
|
|
733
|
+
_v$19 !== _p$.e && _$setAttribute(_el$31, "data-invalid", _p$.e = _v$19);
|
|
734
|
+
_v$20 !== _p$.t && _$setAttribute(_el$32, "for", _p$.t = _v$20);
|
|
735
|
+
_v$21 !== _p$.a && _$setAttribute(_el$34, "id", _p$.a = _v$21);
|
|
736
|
+
_v$22 !== _p$.o && _$setAttribute(_el$34, "placeholder", _p$.o = _v$22);
|
|
737
|
+
_v$23 !== _p$.i && _$setAttribute(_el$34, "aria-invalid", _p$.i = _v$23);
|
|
738
|
+
_v$24 !== _p$.n && _$setAttribute(_el$34, "aria-describedby", _p$.n = _v$24);
|
|
739
|
+
_v$25 !== _p$.s && _$setAttribute(_el$35, "id", _p$.s = _v$25);
|
|
740
|
+
return _p$;
|
|
741
|
+
}, {
|
|
742
|
+
e: undefined,
|
|
743
|
+
t: undefined,
|
|
744
|
+
a: undefined,
|
|
745
|
+
o: undefined,
|
|
746
|
+
i: undefined,
|
|
747
|
+
n: undefined,
|
|
748
|
+
s: undefined
|
|
749
|
+
});
|
|
750
|
+
_$effect(() => _$setProperty(_el$34, "value", fieldProps.text()));
|
|
751
|
+
_$runHydrationEvents();
|
|
752
|
+
return _el$31;
|
|
753
|
+
})();
|
|
754
|
+
return (() => {
|
|
755
|
+
var _el$36 = _$getNextElement(_tmpl$10),
|
|
756
|
+
_el$59 = _el$36.firstChild,
|
|
757
|
+
[_el$60, _co$12] = _$getNextMarker(_el$59.nextSibling),
|
|
758
|
+
_el$41 = _el$60.nextSibling,
|
|
759
|
+
_el$42 = _el$41.firstChild,
|
|
760
|
+
[_el$43, _co$8] = _$getNextMarker(_el$42.nextSibling),
|
|
761
|
+
_el$44 = _el$43.nextSibling,
|
|
762
|
+
[_el$45, _co$9] = _$getNextMarker(_el$44.nextSibling),
|
|
763
|
+
_el$46 = _el$41.nextSibling,
|
|
764
|
+
_el$47 = _el$46.firstChild,
|
|
765
|
+
[_el$48, _co$0] = _$getNextMarker(_el$47.nextSibling),
|
|
766
|
+
_el$49 = _el$48.nextSibling,
|
|
767
|
+
[_el$50, _co$1] = _$getNextMarker(_el$49.nextSibling),
|
|
768
|
+
_el$51 = _el$46.nextSibling,
|
|
769
|
+
_el$52 = _el$51.firstChild,
|
|
770
|
+
_el$54 = _el$52.firstChild,
|
|
771
|
+
[_el$55, _co$10] = _$getNextMarker(_el$54.nextSibling),
|
|
772
|
+
_el$56 = _el$55.nextSibling,
|
|
773
|
+
[_el$57, _co$11] = _$getNextMarker(_el$56.nextSibling),
|
|
774
|
+
_el$58 = _el$52.nextSibling;
|
|
775
|
+
_$insert(_el$36, _$createComponent(Show, {
|
|
776
|
+
get when() {
|
|
777
|
+
return props.sheet;
|
|
778
|
+
},
|
|
779
|
+
get children() {
|
|
780
|
+
var _el$37 = _$getNextElement(_tmpl$0),
|
|
781
|
+
_el$38 = _el$37.firstChild,
|
|
782
|
+
_el$39 = _el$38.nextSibling,
|
|
783
|
+
[_el$40, _co$7] = _$getNextMarker(_el$39.nextSibling);
|
|
784
|
+
_el$37.$$click = () => props.onBack();
|
|
785
|
+
_$insert(_el$37, () => t().backToPresets, _el$40, _co$7);
|
|
786
|
+
_$runHydrationEvents();
|
|
787
|
+
return _el$37;
|
|
788
|
+
}
|
|
789
|
+
}), _el$60, _co$12);
|
|
790
|
+
_$insert(_el$41, () => field({
|
|
791
|
+
id: startId,
|
|
792
|
+
label: t().from,
|
|
793
|
+
text: startText,
|
|
794
|
+
setText: setStartText,
|
|
795
|
+
error: startError
|
|
796
|
+
}), _el$43, _co$8);
|
|
797
|
+
_$insert(_el$41, () => field({
|
|
798
|
+
id: endId,
|
|
799
|
+
label: t().to,
|
|
800
|
+
text: endText,
|
|
801
|
+
setText: setEndText,
|
|
802
|
+
error: endError
|
|
803
|
+
}), _el$45, _co$9);
|
|
804
|
+
var _ref$4 = months;
|
|
805
|
+
typeof _ref$4 === "function" ? _$use(_ref$4, _el$46) : months = _el$46;
|
|
806
|
+
_$insert(_el$46, _$createComponent(DatePickerPanel, {
|
|
807
|
+
visibleMonth: first,
|
|
808
|
+
setVisibleMonth: setFirst,
|
|
809
|
+
range: shown,
|
|
810
|
+
focusDate: () => draft().start,
|
|
811
|
+
onSelect: pickDay,
|
|
812
|
+
onDayPreview: key => setPreview(rangeAnchor(draft(), anchor()) ? key : null),
|
|
813
|
+
get dateConfig() {
|
|
814
|
+
return config();
|
|
815
|
+
},
|
|
816
|
+
get nav() {
|
|
817
|
+
return twoMonths() ? "previous" : "both";
|
|
818
|
+
},
|
|
819
|
+
get hideOutside() {
|
|
820
|
+
return twoMonths();
|
|
821
|
+
},
|
|
822
|
+
isShown: isShown,
|
|
823
|
+
focusRoot: () => months
|
|
824
|
+
}), _el$48, _co$0);
|
|
825
|
+
_$insert(_el$46, _$createComponent(Show, {
|
|
826
|
+
get when() {
|
|
827
|
+
return twoMonths();
|
|
828
|
+
},
|
|
829
|
+
get children() {
|
|
830
|
+
return _$createComponent(DatePickerPanel, {
|
|
831
|
+
visibleMonth: second,
|
|
832
|
+
setVisibleMonth: date => setFirstMonth(monthOf(keyOf(date), -1)),
|
|
833
|
+
range: shown,
|
|
834
|
+
focusDate: () => draft().end,
|
|
835
|
+
onSelect: pickDay,
|
|
836
|
+
onDayPreview: key => setPreview(rangeAnchor(draft(), anchor()) ? key : null),
|
|
837
|
+
get dateConfig() {
|
|
838
|
+
return config();
|
|
839
|
+
},
|
|
840
|
+
nav: "next",
|
|
841
|
+
hideOutside: true,
|
|
842
|
+
isShown: isShown,
|
|
843
|
+
focusRoot: () => months
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
}), _el$50, _co$1);
|
|
847
|
+
_$insert(_el$52, _$createComponent(Show, {
|
|
848
|
+
get when() {
|
|
849
|
+
return _$memo(() => !!shown().start)() && shown().end;
|
|
850
|
+
},
|
|
851
|
+
get children() {
|
|
852
|
+
return _$getNextElement(_tmpl$1);
|
|
853
|
+
}
|
|
854
|
+
}), _el$55, _co$10);
|
|
855
|
+
_$insert(_el$52, status, _el$57, _co$11);
|
|
856
|
+
_el$58.$$click = apply;
|
|
857
|
+
_$insert(_el$58, () => ui().apply);
|
|
858
|
+
_$effect(_p$ => {
|
|
859
|
+
var _v$26 = t().custom,
|
|
860
|
+
_v$27 = !complete();
|
|
861
|
+
_v$26 !== _p$.e && _$setAttribute(_el$36, "aria-label", _p$.e = _v$26);
|
|
862
|
+
_v$27 !== _p$.t && _$setProperty(_el$58, "disabled", _p$.t = _v$27);
|
|
863
|
+
return _p$;
|
|
864
|
+
}, {
|
|
865
|
+
e: undefined,
|
|
866
|
+
t: undefined
|
|
867
|
+
});
|
|
868
|
+
_$runHydrationEvents();
|
|
869
|
+
return _el$36;
|
|
870
|
+
})();
|
|
871
|
+
}
|
|
872
|
+
export default PeriodPicker;
|
|
873
|
+
_$delegateEvents(["click", "keydown", "input"]);
|
|
874
|
+
//# sourceMappingURL=PeriodPicker.js.map
|