@charcuterie/ui 3.0.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/Badge/Badge.d.ts +33 -3
- package/dist/Badge/Badge.d.ts.map +1 -1
- package/dist/Badge/Badge.js +20 -2
- package/dist/Badge/Badge.js.map +1 -1
- package/dist/Board/Board.d.ts +119 -0
- package/dist/Board/Board.d.ts.map +1 -0
- package/dist/Board/Board.js +165 -0
- package/dist/Board/Board.js.map +1 -0
- package/dist/Board/BoardCard.d.ts +120 -0
- package/dist/Board/BoardCard.d.ts.map +1 -0
- package/dist/Board/BoardCard.js +77 -0
- package/dist/Board/BoardCard.js.map +1 -0
- package/dist/Board/BoardLaneList.d.ts +103 -0
- package/dist/Board/BoardLaneList.d.ts.map +1 -0
- package/dist/Board/BoardLaneList.js +69 -0
- package/dist/Board/BoardLaneList.js.map +1 -0
- package/dist/Board/boardMove.d.ts +116 -0
- package/dist/Board/boardMove.d.ts.map +1 -0
- package/dist/Board/boardMove.js +116 -0
- package/dist/Board/boardMove.js.map +1 -0
- package/dist/Board/useBoardDrag.d.ts +44 -0
- package/dist/Board/useBoardDrag.d.ts.map +1 -0
- package/dist/Board/useBoardDrag.js +237 -0
- package/dist/Board/useBoardDrag.js.map +1 -0
- package/dist/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/Checkbox/Checkbox.js +15 -4
- package/dist/Checkbox/Checkbox.js.map +1 -1
- package/dist/DataTable/DataTable.d.ts +159 -0
- package/dist/DataTable/DataTable.d.ts.map +1 -0
- package/dist/DataTable/DataTable.js +197 -0
- package/dist/DataTable/DataTable.js.map +1 -0
- package/dist/DatePicker/DateGrid.d.ts +79 -0
- package/dist/DatePicker/DateGrid.d.ts.map +1 -0
- package/dist/DatePicker/DateGrid.js +220 -0
- package/dist/DatePicker/DateGrid.js.map +1 -0
- package/dist/DatePicker/DatePicker.d.ts +138 -0
- package/dist/DatePicker/DatePicker.d.ts.map +1 -0
- package/dist/DatePicker/DatePicker.js +384 -0
- package/dist/DatePicker/DatePicker.js.map +1 -0
- package/dist/DatePicker/datePresets.d.ts +29 -0
- package/dist/DatePicker/datePresets.d.ts.map +1 -0
- package/dist/DatePicker/datePresets.js +28 -0
- package/dist/DatePicker/datePresets.js.map +1 -0
- package/dist/DatePicker/parseDateInput.d.ts +106 -0
- package/dist/DatePicker/parseDateInput.d.ts.map +1 -0
- package/dist/DatePicker/parseDateInput.js +419 -0
- package/dist/DatePicker/parseDateInput.js.map +1 -0
- package/dist/DatePicker/plainDate.d.ts +167 -0
- package/dist/DatePicker/plainDate.d.ts.map +1 -0
- package/dist/DatePicker/plainDate.js +272 -0
- package/dist/DatePicker/plainDate.js.map +1 -0
- package/dist/Dialog/Dialog.d.ts +12 -2
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +2 -2
- package/dist/Dialog/Dialog.js.map +1 -1
- package/dist/MarkdownEditor/MarkdownEditor.d.ts +147 -0
- package/dist/MarkdownEditor/MarkdownEditor.d.ts.map +1 -0
- package/dist/MarkdownEditor/MarkdownEditor.js +492 -0
- package/dist/MarkdownEditor/MarkdownEditor.js.map +1 -0
- package/dist/MarkdownEditor/markdownCommands.d.ts +202 -0
- package/dist/MarkdownEditor/markdownCommands.d.ts.map +1 -0
- package/dist/MarkdownEditor/markdownCommands.js +379 -0
- package/dist/MarkdownEditor/markdownCommands.js.map +1 -0
- package/dist/MarkdownEditor/markdownSpans.d.ts +92 -0
- package/dist/MarkdownEditor/markdownSpans.d.ts.map +1 -0
- package/dist/MarkdownEditor/markdownSpans.js +303 -0
- package/dist/MarkdownEditor/markdownSpans.js.map +1 -0
- package/dist/Modal/Modal.d.ts +6 -2
- package/dist/Modal/Modal.d.ts.map +1 -1
- package/dist/Modal/Modal.js +1 -1
- package/dist/Modal/Modal.js.map +1 -1
- package/dist/Overlay/OverlayPanel.d.ts +13 -2
- package/dist/Overlay/OverlayPanel.d.ts.map +1 -1
- package/dist/Overlay/OverlayPanel.js +5 -1
- package/dist/Overlay/OverlayPanel.js.map +1 -1
- package/dist/categoricalStyles.d.ts +53 -0
- package/dist/categoricalStyles.d.ts.map +1 -0
- package/dist/categoricalStyles.js +195 -0
- package/dist/categoricalStyles.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/Badge/Badge.mdx +46 -0
- package/src/Badge/Badge.stories.tsx +98 -4
- package/src/Badge/Badge.test.tsx +157 -2
- package/src/Badge/Badge.tsx +49 -3
- package/src/Board/Board.mdx +199 -0
- package/src/Board/Board.stories.tsx +707 -0
- package/src/Board/Board.test.tsx +310 -0
- package/src/Board/Board.tsx +333 -0
- package/src/Board/BoardCard.tsx +290 -0
- package/src/Board/BoardLaneList.tsx +275 -0
- package/src/Board/boardMove.test.ts +213 -0
- package/src/Board/boardMove.ts +225 -0
- package/src/Board/useBoardDrag.ts +413 -0
- package/src/Checkbox/Checkbox.tsx +34 -3
- package/src/DataTable/DataTable.mdx +123 -0
- package/src/DataTable/DataTable.stories.tsx +411 -0
- package/src/DataTable/DataTable.test.tsx +386 -0
- package/src/DataTable/DataTable.tsx +497 -0
- package/src/DatePicker/DateGrid.tsx +467 -0
- package/src/DatePicker/DatePicker.mdx +170 -0
- package/src/DatePicker/DatePicker.stories.tsx +268 -0
- package/src/DatePicker/DatePicker.test.tsx +455 -0
- package/src/DatePicker/DatePicker.tsx +852 -0
- package/src/DatePicker/datePresets.ts +34 -0
- package/src/DatePicker/parseDateInput.test.ts +187 -0
- package/src/DatePicker/parseDateInput.ts +629 -0
- package/src/DatePicker/plainDate.test.ts +375 -0
- package/src/DatePicker/plainDate.ts +465 -0
- package/src/Dialog/Dialog.stories.tsx +48 -0
- package/src/Dialog/Dialog.test.tsx +30 -0
- package/src/Dialog/Dialog.tsx +13 -1
- package/src/MarkdownEditor/MarkdownEditor.mdx +189 -0
- package/src/MarkdownEditor/MarkdownEditor.stories.tsx +267 -0
- package/src/MarkdownEditor/MarkdownEditor.test.tsx +627 -0
- package/src/MarkdownEditor/MarkdownEditor.tsx +862 -0
- package/src/MarkdownEditor/markdownCommands.test.ts +384 -0
- package/src/MarkdownEditor/markdownCommands.ts +566 -0
- package/src/MarkdownEditor/markdownSpans.test.ts +217 -0
- package/src/MarkdownEditor/markdownSpans.ts +458 -0
- package/src/Modal/Modal.tsx +7 -1
- package/src/Overlay/OverlayPanel.tsx +17 -1
- package/src/argTypes.storyHelpers.ts +39 -0
- package/src/categoricalStyles.ts +244 -0
- package/src/index.ts +89 -0
- package/src/sourceRules.test.ts +52 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { ControlSize } from "@charcuterie/tokens";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
import type { SlotProps } from "../slotProps.ts";
|
|
4
|
+
import type { DatePreset } from "./datePresets.ts";
|
|
5
|
+
import type { DateInputKeywords } from "./parseDateInput.ts";
|
|
6
|
+
import type { DateRange } from "./plainDate.ts";
|
|
7
|
+
export type DatePickerProps = SlotProps & {
|
|
8
|
+
className?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Sunday 0 through Saturday 6. Omit and the locale decides, via
|
|
11
|
+
* `Intl.Locale`'s `getWeekInfo` — which is why there is no
|
|
12
|
+
* `isMondayFirst` here.
|
|
13
|
+
*/
|
|
14
|
+
firstDayOfWeek?: number;
|
|
15
|
+
isDisabled?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Start-and-end mode. A **mode, not a sibling component** — see
|
|
18
|
+
* the component docblock, and the `Combobox` `isMultiple`
|
|
19
|
+
* precedent it follows.
|
|
20
|
+
*/
|
|
21
|
+
isRange?: boolean;
|
|
22
|
+
/** Override the English relative words (`today`, `next`, `+3d`). */
|
|
23
|
+
keywords?: DateInputKeywords;
|
|
24
|
+
/**
|
|
25
|
+
* Required. It names the field for a screen reader **and** names
|
|
26
|
+
* the calendar dialog and its grids, which a `role="dialog"` takes
|
|
27
|
+
* from nothing else. Inside a `Field`, pass the same text as the
|
|
28
|
+
* `Field`'s own `label` — they are the same name and WCAG 2.5.3
|
|
29
|
+
* wants them to agree.
|
|
30
|
+
*/
|
|
31
|
+
label: string;
|
|
32
|
+
/** Omit for the platform's resolved locale. */
|
|
33
|
+
locale?: string;
|
|
34
|
+
/** ISO `YYYY-MM-DD`. Days after this are unselectable. */
|
|
35
|
+
maxValue?: string;
|
|
36
|
+
/** ISO `YYYY-MM-DD`. Days before this are unselectable. */
|
|
37
|
+
minValue?: string;
|
|
38
|
+
/**
|
|
39
|
+
* An ISO `YYYY-MM-DD` in single mode, a `{ end, start }` of them in
|
|
40
|
+
* range mode, and `null` when cleared. Never a `Date`, and that is
|
|
41
|
+
* the point — see the docblock.
|
|
42
|
+
*/
|
|
43
|
+
onChange?: (value: DateRange | null | string) => void;
|
|
44
|
+
placeholder?: string;
|
|
45
|
+
/** Pass `[]` to drop the shortcut row entirely. */
|
|
46
|
+
presets?: readonly DatePreset[];
|
|
47
|
+
size?: ControlSize;
|
|
48
|
+
/**
|
|
49
|
+
* Which zone's calendar "today" is read from, when `today` is
|
|
50
|
+
* omitted. Ignored when `today` is supplied — which is what every
|
|
51
|
+
* test and every story does.
|
|
52
|
+
*/
|
|
53
|
+
timeZone?: string;
|
|
54
|
+
/**
|
|
55
|
+
* The clock, injected, as an ISO `YYYY-MM-DD`.
|
|
56
|
+
*
|
|
57
|
+
* Every relative form (`tomorrow`, `next fri`, `+14d`), the
|
|
58
|
+
* `aria-current="date"` marker, and the preset row resolve against
|
|
59
|
+
* this. Supplying it is what makes the component testable at all:
|
|
60
|
+
* a date picker tested against the real "today" passes on the day
|
|
61
|
+
* it was written and fails silently afterwards. Omitted, it is
|
|
62
|
+
* read **once**, at mount, from `timeZone` or the device.
|
|
63
|
+
*/
|
|
64
|
+
today?: string;
|
|
65
|
+
/** **Initial** only, like every other value prop in this library. */
|
|
66
|
+
value?: DateRange | string;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* A date field: a text input you can actually type into, and a
|
|
70
|
+
* calendar dialog hanging off it.
|
|
71
|
+
*
|
|
72
|
+
* ### The value is a calendar date, never an instant
|
|
73
|
+
*
|
|
74
|
+
* `onChange` reports an ISO `YYYY-MM-DD` string — the same format
|
|
75
|
+
* `<input type="date">` uses — and never a `Date`. A `Date` is a
|
|
76
|
+
* count of milliseconds, so reading one back always goes through the
|
|
77
|
+
* browser's timezone, and a due date picked at 23:30 in Denver comes
|
|
78
|
+
* back as the previous day in London. `plainDate.ts` has the full
|
|
79
|
+
* argument and the arithmetic; `plainDate.test.ts` re-runs it under
|
|
80
|
+
* UTC+14 and UTC-11 and asserts nothing moves.
|
|
81
|
+
*
|
|
82
|
+
* ### Typing is the feature
|
|
83
|
+
*
|
|
84
|
+
* The grid is the fallback, not the interface. `tomorrow`,
|
|
85
|
+
* `next fri`, `+14d`, `19 aug`, `8/19`, `2026-08-19` and a bare `19`
|
|
86
|
+
* all resolve, in the active locale, against an injected `today` —
|
|
87
|
+
* and **the resolution is echoed underneath the field, in a live
|
|
88
|
+
* region, before anything commits.** Nothing here guesses in
|
|
89
|
+
* silence: an ambiguous month prefix comes back as "'ju' could be
|
|
90
|
+
* June or July", not as June. `parseDateInput.ts` is the grammar and
|
|
91
|
+
* the reasoning.
|
|
92
|
+
*
|
|
93
|
+
* ### Range is a mode, not a sibling
|
|
94
|
+
*
|
|
95
|
+
* `isRange` follows
|
|
96
|
+
* [Combobox's `isMultiple`](../../../docs/decisions/2026-08-05-combobox-multi-select-stays-ismultiple-not-a-separate-component.md)
|
|
97
|
+
* for the same three reasons, which hold even harder here:
|
|
98
|
+
*
|
|
99
|
+
* - **No distinct role.** The family is named by ARIA role. A range
|
|
100
|
+
* picker is the same `role="dialog"` over the same `role="grid"`;
|
|
101
|
+
* there is no `daterange` role to name a `DateRangePicker` after,
|
|
102
|
+
* so the name would describe a *presentation*.
|
|
103
|
+
* - **The delta is small and the shared part is everything.** The
|
|
104
|
+
* parser, the locale plumbing, the min/max clamp, the keyboard
|
|
105
|
+
* grid, the panel, the presets and the echo line are identical.
|
|
106
|
+
* What changes is a second input, a second month, and a band
|
|
107
|
+
* drawn between two days.
|
|
108
|
+
* - **`Combobox` already set the precedent for the value shape.**
|
|
109
|
+
* Its `selectedValue` is `readonly string[] | string`; this one is
|
|
110
|
+
* `DateRange | string`. A discriminated props union would type
|
|
111
|
+
* better and was rejected for that consistency, and because
|
|
112
|
+
* Storybook's docgen renders a union props type as an untyped
|
|
113
|
+
* object control.
|
|
114
|
+
*
|
|
115
|
+
* ### The panel is a container, and it is queried as one
|
|
116
|
+
*
|
|
117
|
+
* `@container` sits on the panel, and everything inside sizes to the
|
|
118
|
+
* panel's own inline size rather than to the window: one-letter
|
|
119
|
+
* weekday headers and 32px cells below `--cq-xs`, two-letter and
|
|
120
|
+
* 36px above it, 40px above `--cq-sm`, and in range mode the two
|
|
121
|
+
* months stack below `--cq-sm` and sit side by side above it. That
|
|
122
|
+
* is not the same question a media query asks — the owner browses
|
|
123
|
+
* zoomed in, where a 390px phone reports a 195px layout viewport and
|
|
124
|
+
* a desktop window at 200% has no room either. The `size` middleware
|
|
125
|
+
* clamps the panel to the space actually available, and the
|
|
126
|
+
* container query reads what it got.
|
|
127
|
+
*
|
|
128
|
+
* ### It owns its own open state, and its own value
|
|
129
|
+
*
|
|
130
|
+
* Assembled, like [`Picker`](../Picker/Picker.tsx): the
|
|
131
|
+
* `useVisibility` is in here, because a field that needs the caller
|
|
132
|
+
* to wire `isVisible` is a field the caller has to assemble. And
|
|
133
|
+
* `value` **seeds** rather than controls, matching `Select`,
|
|
134
|
+
* `SegmentedControl` and `Combobox` — one owner for the value, which
|
|
135
|
+
* is the whole of the state layer's argument.
|
|
136
|
+
*/
|
|
137
|
+
export declare const DatePicker: ({ className, firstDayOfWeek, isDisabled, isRange, keywords, label, locale, maxValue, minValue, onChange, placeholder, presets, size, timeZone, today, value, ...receivedSlotProps }: DatePickerProps) => ReactNode;
|
|
138
|
+
//# sourceMappingURL=DatePicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../src/DatePicker/DatePicker.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAKtD,OAAO,KAAK,EAEV,SAAS,EACV,MAAM,OAAO,CAAA;AAYd,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAIhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,gBAAgB,CAAA;AAc1D,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG;IACxC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,iBAAiB,CAAA;IAC5B;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,KAAK,IAAI,CAAA;IACrD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mDAAmD;IACnD,OAAO,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;IAC/B,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,qEAAqE;IACrE,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;CAC3B,CAAA;AAyCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,eAAO,MAAM,UAAU,GAAI,qLAkBxB,eAAe,KAAG,SAymBpB,CAAA"}
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import { createElement as _createElement } from "react";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useUniqueId, useVisibility, } from "@charcuterie/logic";
|
|
4
|
+
import { FloatingFocusManager, FloatingPortal, } from "@floating-ui/react";
|
|
5
|
+
import { useRef, useState } from "react";
|
|
6
|
+
import { Button } from "../Button/Button.js";
|
|
7
|
+
import { CONTROL_SIZE_CLASS } from "../controlStyles.js";
|
|
8
|
+
import { IconButton } from "../IconButton/IconButton.js";
|
|
9
|
+
import { DISABLED_CLASS, FOCUS_RING_CLASS, } from "../intentStyles.js";
|
|
10
|
+
import { PANEL_SURFACE_CLASS } from "../Overlay/overlayPanelClass.js";
|
|
11
|
+
import { useAnchoredOverlay } from "../Overlay/useAnchoredOverlay.js";
|
|
12
|
+
import { mergeSlotProps } from "../slotProps.js";
|
|
13
|
+
import { toClassName } from "../toClassName.js";
|
|
14
|
+
import { DateGrid } from "./DateGrid.js";
|
|
15
|
+
import { DEFAULT_DATE_PRESETS } from "./datePresets.js";
|
|
16
|
+
import { parseDateInput } from "./parseDateInput.js";
|
|
17
|
+
import { addDays, addMonths, clampPlainDate, comparePlainDates, formatPlainDate, getFirstDayOfWeek, getIsWithinRange, getLocalPlainDate, parseIsoDate, toIsoDate, } from "./plainDate.js";
|
|
18
|
+
const CHEVRON_PREVIOUS = (_jsx("svg", { "aria-hidden": "true", className: "size-4", fill: "none", focusable: false, stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.75, viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "m15 18-6-6 6-6" }) }));
|
|
19
|
+
const CHEVRON_NEXT = (_jsx("svg", { "aria-hidden": "true", className: "size-4", fill: "none", focusable: false, stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.75, viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "m9 18 6-6-6-6" }) }));
|
|
20
|
+
const INPUT_CLASS = "w-full min-w-0 rounded-md border border-border-default bg-surface-raised text-content-primary transition-colors duration-(--duration-fast) ease-standard placeholder:text-content-muted hover:border-border-strong aria-invalid:border-intent-danger-border";
|
|
21
|
+
/**
|
|
22
|
+
* A date field: a text input you can actually type into, and a
|
|
23
|
+
* calendar dialog hanging off it.
|
|
24
|
+
*
|
|
25
|
+
* ### The value is a calendar date, never an instant
|
|
26
|
+
*
|
|
27
|
+
* `onChange` reports an ISO `YYYY-MM-DD` string — the same format
|
|
28
|
+
* `<input type="date">` uses — and never a `Date`. A `Date` is a
|
|
29
|
+
* count of milliseconds, so reading one back always goes through the
|
|
30
|
+
* browser's timezone, and a due date picked at 23:30 in Denver comes
|
|
31
|
+
* back as the previous day in London. `plainDate.ts` has the full
|
|
32
|
+
* argument and the arithmetic; `plainDate.test.ts` re-runs it under
|
|
33
|
+
* UTC+14 and UTC-11 and asserts nothing moves.
|
|
34
|
+
*
|
|
35
|
+
* ### Typing is the feature
|
|
36
|
+
*
|
|
37
|
+
* The grid is the fallback, not the interface. `tomorrow`,
|
|
38
|
+
* `next fri`, `+14d`, `19 aug`, `8/19`, `2026-08-19` and a bare `19`
|
|
39
|
+
* all resolve, in the active locale, against an injected `today` —
|
|
40
|
+
* and **the resolution is echoed underneath the field, in a live
|
|
41
|
+
* region, before anything commits.** Nothing here guesses in
|
|
42
|
+
* silence: an ambiguous month prefix comes back as "'ju' could be
|
|
43
|
+
* June or July", not as June. `parseDateInput.ts` is the grammar and
|
|
44
|
+
* the reasoning.
|
|
45
|
+
*
|
|
46
|
+
* ### Range is a mode, not a sibling
|
|
47
|
+
*
|
|
48
|
+
* `isRange` follows
|
|
49
|
+
* [Combobox's `isMultiple`](../../../docs/decisions/2026-08-05-combobox-multi-select-stays-ismultiple-not-a-separate-component.md)
|
|
50
|
+
* for the same three reasons, which hold even harder here:
|
|
51
|
+
*
|
|
52
|
+
* - **No distinct role.** The family is named by ARIA role. A range
|
|
53
|
+
* picker is the same `role="dialog"` over the same `role="grid"`;
|
|
54
|
+
* there is no `daterange` role to name a `DateRangePicker` after,
|
|
55
|
+
* so the name would describe a *presentation*.
|
|
56
|
+
* - **The delta is small and the shared part is everything.** The
|
|
57
|
+
* parser, the locale plumbing, the min/max clamp, the keyboard
|
|
58
|
+
* grid, the panel, the presets and the echo line are identical.
|
|
59
|
+
* What changes is a second input, a second month, and a band
|
|
60
|
+
* drawn between two days.
|
|
61
|
+
* - **`Combobox` already set the precedent for the value shape.**
|
|
62
|
+
* Its `selectedValue` is `readonly string[] | string`; this one is
|
|
63
|
+
* `DateRange | string`. A discriminated props union would type
|
|
64
|
+
* better and was rejected for that consistency, and because
|
|
65
|
+
* Storybook's docgen renders a union props type as an untyped
|
|
66
|
+
* object control.
|
|
67
|
+
*
|
|
68
|
+
* ### The panel is a container, and it is queried as one
|
|
69
|
+
*
|
|
70
|
+
* `@container` sits on the panel, and everything inside sizes to the
|
|
71
|
+
* panel's own inline size rather than to the window: one-letter
|
|
72
|
+
* weekday headers and 32px cells below `--cq-xs`, two-letter and
|
|
73
|
+
* 36px above it, 40px above `--cq-sm`, and in range mode the two
|
|
74
|
+
* months stack below `--cq-sm` and sit side by side above it. That
|
|
75
|
+
* is not the same question a media query asks — the owner browses
|
|
76
|
+
* zoomed in, where a 390px phone reports a 195px layout viewport and
|
|
77
|
+
* a desktop window at 200% has no room either. The `size` middleware
|
|
78
|
+
* clamps the panel to the space actually available, and the
|
|
79
|
+
* container query reads what it got.
|
|
80
|
+
*
|
|
81
|
+
* ### It owns its own open state, and its own value
|
|
82
|
+
*
|
|
83
|
+
* Assembled, like [`Picker`](../Picker/Picker.tsx): the
|
|
84
|
+
* `useVisibility` is in here, because a field that needs the caller
|
|
85
|
+
* to wire `isVisible` is a field the caller has to assemble. And
|
|
86
|
+
* `value` **seeds** rather than controls, matching `Select`,
|
|
87
|
+
* `SegmentedControl` and `Combobox` — one owner for the value, which
|
|
88
|
+
* is the whole of the state layer's argument.
|
|
89
|
+
*/
|
|
90
|
+
export const DatePicker = ({ className, firstDayOfWeek, isDisabled = false, isRange = false, keywords, label, locale, maxValue, minValue, onChange, placeholder = "e.g. tomorrow, 8/19, +14d", presets = DEFAULT_DATE_PRESETS, size = "md", timeZone, today, value, ...receivedSlotProps }) => {
|
|
91
|
+
const baseId = useUniqueId();
|
|
92
|
+
const anchorElement = useRef(null);
|
|
93
|
+
const inputElements = useRef(new Map());
|
|
94
|
+
const { hide, isVisible, show } = useVisibility();
|
|
95
|
+
/**
|
|
96
|
+
* Read once, lazily, and never again.
|
|
97
|
+
*
|
|
98
|
+
* A component that re-read the clock on every render would change
|
|
99
|
+
* what `tomorrow` means underneath a user typing it at midnight,
|
|
100
|
+
* and would make every test a race. `today` as a prop is the
|
|
101
|
+
* supported way to control it, and every story and test passes it.
|
|
102
|
+
*/
|
|
103
|
+
const [resolvedToday] = useState(() => parseIsoDate(today) ??
|
|
104
|
+
getLocalPlainDate(new Date(), timeZone));
|
|
105
|
+
const todayDate = parseIsoDate(today) ?? resolvedToday;
|
|
106
|
+
const minimum = parseIsoDate(minValue) ?? undefined;
|
|
107
|
+
const maximum = parseIsoDate(maxValue) ?? undefined;
|
|
108
|
+
const resolvedFirstDayOfWeek = firstDayOfWeek ?? getFirstDayOfWeek(locale);
|
|
109
|
+
const seededRange = typeof value === "string"
|
|
110
|
+
? { end: null, start: value }
|
|
111
|
+
: (value ?? { end: null, start: null });
|
|
112
|
+
const [range, setRange] = useState(seededRange);
|
|
113
|
+
const toDisplayText = (isoDate) => {
|
|
114
|
+
const date = parseIsoDate(isoDate);
|
|
115
|
+
return date === null
|
|
116
|
+
? ""
|
|
117
|
+
: formatPlainDate(date, {
|
|
118
|
+
dateStyle: "medium",
|
|
119
|
+
locale,
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
const [texts, setTexts] = useState({
|
|
123
|
+
end: toDisplayText(seededRange.end),
|
|
124
|
+
start: toDisplayText(seededRange.start),
|
|
125
|
+
});
|
|
126
|
+
const [activeEndpoint, setActiveEndpoint] = useState("start");
|
|
127
|
+
const [isGridFocused, setIsGridFocused] = useState(false);
|
|
128
|
+
const [hoveredDate, setHoveredDate] = useState(null);
|
|
129
|
+
const [focusedDate, setFocusedDate] = useState(() => clampPlainDate(parseIsoDate(seededRange.start) ?? todayDate, minimum, maximum));
|
|
130
|
+
const [visibleMonth, setVisibleMonth] = useState(() => parseIsoDate(seededRange.start) ?? todayDate);
|
|
131
|
+
const parsed = parseDateInput(texts[activeEndpoint], {
|
|
132
|
+
keywords,
|
|
133
|
+
locale,
|
|
134
|
+
today: todayDate,
|
|
135
|
+
});
|
|
136
|
+
const echoId = `${baseId}-echo`;
|
|
137
|
+
const dismiss = () => {
|
|
138
|
+
hide();
|
|
139
|
+
setIsGridFocused(false);
|
|
140
|
+
setHoveredDate(null);
|
|
141
|
+
inputElements.current.get(activeEndpoint)?.focus();
|
|
142
|
+
};
|
|
143
|
+
const { context, floatingStyles, getFloatingProps, setFloating, } = useAnchoredOverlay({
|
|
144
|
+
anchorRef: anchorElement,
|
|
145
|
+
isVisible,
|
|
146
|
+
maxHeightPx: 520,
|
|
147
|
+
maxWidthPx: isRange ? 656 : 320,
|
|
148
|
+
offsetValue: 4,
|
|
149
|
+
onDismiss: () => {
|
|
150
|
+
dismiss();
|
|
151
|
+
},
|
|
152
|
+
role: "dialog",
|
|
153
|
+
trigger: undefined,
|
|
154
|
+
});
|
|
155
|
+
const { id: panelId, ...floatingProps } = getFloatingProps();
|
|
156
|
+
const report = (nextRange) => {
|
|
157
|
+
setRange(nextRange);
|
|
158
|
+
if (isRange) {
|
|
159
|
+
onChange?.(nextRange.end === null && nextRange.start === null
|
|
160
|
+
? null
|
|
161
|
+
: nextRange);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
onChange?.(nextRange.start);
|
|
165
|
+
};
|
|
166
|
+
const writeEndpoint = (endpoint, date) => {
|
|
167
|
+
const isoDate = date === null ? null : toIsoDate(date);
|
|
168
|
+
setTexts((previous) => ({
|
|
169
|
+
...previous,
|
|
170
|
+
[endpoint]: date === null ? "" : toDisplayText(isoDate),
|
|
171
|
+
}));
|
|
172
|
+
const nextRange = isRange
|
|
173
|
+
? { ...range, [endpoint]: isoDate }
|
|
174
|
+
: { end: null, start: isoDate };
|
|
175
|
+
// A range whose end precedes its start is not a range anybody
|
|
176
|
+
// typed on purpose, and rejecting it would throw away the day
|
|
177
|
+
// they just picked. Swapping keeps both dates and matches every
|
|
178
|
+
// range control in the wild.
|
|
179
|
+
const isBackwards = isRange &&
|
|
180
|
+
nextRange.end !== null &&
|
|
181
|
+
nextRange.start !== null &&
|
|
182
|
+
nextRange.end < nextRange.start;
|
|
183
|
+
report(isBackwards
|
|
184
|
+
? { end: nextRange.start, start: nextRange.end }
|
|
185
|
+
: nextRange);
|
|
186
|
+
};
|
|
187
|
+
const commitText = (endpoint) => {
|
|
188
|
+
const result = parseDateInput(texts[endpoint], {
|
|
189
|
+
keywords,
|
|
190
|
+
locale,
|
|
191
|
+
today: todayDate,
|
|
192
|
+
});
|
|
193
|
+
if (result.kind === "empty") {
|
|
194
|
+
writeEndpoint(endpoint, null);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (result.kind === "unparsed") {
|
|
198
|
+
// The text stays exactly as typed. Clearing it would throw
|
|
199
|
+
// away what the user has to edit, and rewriting it to the last
|
|
200
|
+
// good value would silently discard the thing they meant.
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
writeEndpoint(endpoint, clampPlainDate(result.date, minimum, maximum));
|
|
204
|
+
};
|
|
205
|
+
const handleTextChange = (endpoint, nextText) => {
|
|
206
|
+
setTexts((previous) => ({
|
|
207
|
+
...previous,
|
|
208
|
+
[endpoint]: nextText,
|
|
209
|
+
}));
|
|
210
|
+
const result = parseDateInput(nextText, {
|
|
211
|
+
keywords,
|
|
212
|
+
locale,
|
|
213
|
+
today: todayDate,
|
|
214
|
+
});
|
|
215
|
+
// Live preview: the grid follows what has been typed so far
|
|
216
|
+
// without committing it, which is what makes `next fri` legible
|
|
217
|
+
// rather than an act of faith.
|
|
218
|
+
if (result.kind === "date") {
|
|
219
|
+
setFocusedDate(result.date);
|
|
220
|
+
setVisibleMonth(result.date);
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
const chooseDate = (date) => {
|
|
224
|
+
setFocusedDate(date);
|
|
225
|
+
if (!isRange) {
|
|
226
|
+
writeEndpoint("start", date);
|
|
227
|
+
dismiss();
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const isStartingOver = range.start === null || range.end !== null;
|
|
231
|
+
if (isStartingOver) {
|
|
232
|
+
setTexts((previous) => ({ ...previous, end: "" }));
|
|
233
|
+
setRange({ end: null, start: toIsoDate(date) });
|
|
234
|
+
setTexts((previous) => ({
|
|
235
|
+
...previous,
|
|
236
|
+
start: toDisplayText(toIsoDate(date)),
|
|
237
|
+
}));
|
|
238
|
+
setActiveEndpoint("end");
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
writeEndpoint("end", date);
|
|
242
|
+
dismiss();
|
|
243
|
+
};
|
|
244
|
+
const handleInputKeyDown = (keyEvent, endpoint) => {
|
|
245
|
+
if (keyEvent.key === "ArrowDown") {
|
|
246
|
+
keyEvent.preventDefault();
|
|
247
|
+
show();
|
|
248
|
+
setIsGridFocused(true);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if (keyEvent.key === "Enter") {
|
|
252
|
+
keyEvent.preventDefault();
|
|
253
|
+
commitText(endpoint);
|
|
254
|
+
if (isVisible) {
|
|
255
|
+
dismiss();
|
|
256
|
+
}
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (keyEvent.key === "Escape" && isVisible) {
|
|
260
|
+
keyEvent.preventDefault();
|
|
261
|
+
dismiss();
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
const selectedDates = [
|
|
265
|
+
parseIsoDate(range.start),
|
|
266
|
+
parseIsoDate(range.end),
|
|
267
|
+
].filter((one) => one !== null);
|
|
268
|
+
const rangeStartDate = parseIsoDate(range.start);
|
|
269
|
+
const previewEnd = isRange
|
|
270
|
+
? (parseIsoDate(range.end) ??
|
|
271
|
+
(rangeStartDate === null
|
|
272
|
+
? null
|
|
273
|
+
: (hoveredDate ??
|
|
274
|
+
(comparePlainDates(focusedDate, rangeStartDate) >
|
|
275
|
+
0
|
|
276
|
+
? focusedDate
|
|
277
|
+
: null))))
|
|
278
|
+
: null;
|
|
279
|
+
const secondMonth = addMonths(visibleMonth, 1);
|
|
280
|
+
const monthLabel = (month) => formatPlainDate(month, {
|
|
281
|
+
locale,
|
|
282
|
+
month: "long",
|
|
283
|
+
year: "numeric",
|
|
284
|
+
});
|
|
285
|
+
const echoText = parsed.kind === "date"
|
|
286
|
+
? formatPlainDate(parsed.date, {
|
|
287
|
+
dateStyle: "full",
|
|
288
|
+
locale,
|
|
289
|
+
})
|
|
290
|
+
: parsed.kind === "unparsed"
|
|
291
|
+
? parsed.reason
|
|
292
|
+
: "";
|
|
293
|
+
const isInvalid = parsed.kind === "unparsed";
|
|
294
|
+
const renderInput = (endpoint) => {
|
|
295
|
+
const ownProps = {
|
|
296
|
+
"aria-controls": isVisible ? panelId : undefined,
|
|
297
|
+
"aria-describedby": echoId,
|
|
298
|
+
"aria-expanded": isVisible,
|
|
299
|
+
"aria-haspopup": "dialog",
|
|
300
|
+
"aria-invalid": activeEndpoint === endpoint && isInvalid
|
|
301
|
+
? true
|
|
302
|
+
: undefined,
|
|
303
|
+
"aria-label": isRange
|
|
304
|
+
? `${label} ${endpoint}`
|
|
305
|
+
: label,
|
|
306
|
+
autoComplete: "off",
|
|
307
|
+
className: toClassName(INPUT_CLASS, CONTROL_SIZE_CLASS[size], FOCUS_RING_CLASS, DISABLED_CLASS),
|
|
308
|
+
disabled: isDisabled,
|
|
309
|
+
id: `${baseId}-${endpoint}`,
|
|
310
|
+
// A date is digits far more often than it is words, and a
|
|
311
|
+
// numeric-leaning soft keyboard with letters still available is
|
|
312
|
+
// what lets `8/19` and `next fri` both be typed on a phone.
|
|
313
|
+
inputMode: "text",
|
|
314
|
+
onChange: (changeEvent) => {
|
|
315
|
+
handleTextChange(endpoint, changeEvent.currentTarget.value);
|
|
316
|
+
},
|
|
317
|
+
onClick: () => {
|
|
318
|
+
setActiveEndpoint(endpoint);
|
|
319
|
+
show();
|
|
320
|
+
},
|
|
321
|
+
onFocus: () => {
|
|
322
|
+
setActiveEndpoint(endpoint);
|
|
323
|
+
},
|
|
324
|
+
onKeyDown: (keyEvent) => {
|
|
325
|
+
handleInputKeyDown(keyEvent, endpoint);
|
|
326
|
+
},
|
|
327
|
+
placeholder,
|
|
328
|
+
ref: (element) => {
|
|
329
|
+
if (element) {
|
|
330
|
+
inputElements.current.set(endpoint, element);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
inputElements.current.delete(endpoint);
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
role: "combobox",
|
|
337
|
+
type: "text",
|
|
338
|
+
value: texts[endpoint],
|
|
339
|
+
};
|
|
340
|
+
return (_createElement("input", { ...(endpoint === "start"
|
|
341
|
+
? mergeSlotProps(receivedSlotProps, ownProps)
|
|
342
|
+
: ownProps), key: endpoint }));
|
|
343
|
+
};
|
|
344
|
+
const renderGrid = (month) => (_jsx(DateGrid, { firstDayOfWeek: resolvedFirstDayOfWeek, focusedDate: focusedDate, gridMonth: month, isGridFocused: isGridFocused, isRange: isRange, label: monthLabel(month), locale: locale, maximum: maximum, minimum: minimum, onFocusDate: (date) => {
|
|
345
|
+
setFocusedDate(date);
|
|
346
|
+
setVisibleMonth(date);
|
|
347
|
+
}, onHoverDate: setHoveredDate, onSelectDate: chooseDate, previewEnd: previewEnd, rangeStart: rangeStartDate, selectedDates: selectedDates, today: todayDate }, `${month.year}-${month.month}`));
|
|
348
|
+
return (_jsxs("div", { className: toClassName("flex flex-col gap-1", className), ref: anchorElement, children: [_jsxs("div", { className: "flex items-center gap-2", children: [renderInput("start"), isRange ? (_jsxs(_Fragment, { children: [_jsx("span", { "aria-hidden": "true", className: "shrink-0 text-content-secondary text-sm", children: "to" }), renderInput("end")] })) : null] }), _jsx("p", { "aria-live": "polite", className: toClassName("min-h-5 text-sm", isInvalid
|
|
349
|
+
? "text-intent-danger-content"
|
|
350
|
+
: "text-content-secondary"), id: echoId, role: "status", children: echoText }), isVisible ? (_jsx(FloatingPortal, { children: _jsx(FloatingFocusManager, { context: context,
|
|
351
|
+
// Focus stays where the user is typing until they ask for
|
|
352
|
+
// the grid with ArrowDown or a click. A calendar that
|
|
353
|
+
// steals the caret on open is a calendar you cannot type
|
|
354
|
+
// into, which is the whole point of this field.
|
|
355
|
+
disabled: true, modal: false, children: _jsxs("div", { ...floatingProps, "aria-label": `${label} calendar`, className: toClassName(PANEL_SURFACE_CLASS,
|
|
356
|
+
// `overflow-hidden`, because `maxHeightPx` reaches the
|
|
357
|
+
// panel as a `max-height` from the `size` middleware and
|
|
358
|
+
// nothing else clips: on a phone the preset row simply
|
|
359
|
+
// spilled out past the panel's own rounded edge and sat
|
|
360
|
+
// on the page behind it. The *months* are what scrolls
|
|
361
|
+
// (below), so the month nav and the shortcut row stay
|
|
362
|
+
// put — a preset you have to scroll to find is not a
|
|
363
|
+
// shortcut, and it is the fastest control here on a
|
|
364
|
+
// phone.
|
|
365
|
+
"@container z-[var(--layer-modal)] flex flex-col gap-3 overflow-hidden p-3 text-content-primary", isRange ? "w-[41rem]" : "w-80"), id: panelId, ref: setFloating, role: "dialog", style: floatingStyles, children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx(IconButton, { appearance: "ghost", label: "Previous month", onClick: () => {
|
|
366
|
+
setVisibleMonth(addMonths(visibleMonth, -1));
|
|
367
|
+
}, size: "sm", type: "button", children: CHEVRON_PREVIOUS }), _jsx("span", { "aria-live": "polite", className: "font-medium text-sm", children: isRange
|
|
368
|
+
? `${monthLabel(visibleMonth)} – ${monthLabel(secondMonth)}`
|
|
369
|
+
: monthLabel(visibleMonth) }), _jsx(IconButton, { appearance: "ghost", label: "Next month", onClick: () => {
|
|
370
|
+
setVisibleMonth(addMonths(visibleMonth, 1));
|
|
371
|
+
}, size: "sm", type: "button", children: CHEVRON_NEXT })] }), _jsxs("div", { className: "charcuterie-scrollbar flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto cq-sm:flex-row", children: [renderGrid(visibleMonth), isRange ? renderGrid(secondMonth) : null] }), presets.length > 0 ||
|
|
372
|
+
range.start !== null ? (_jsxs("div", { className: "flex flex-wrap items-center gap-1 border-border-subtle border-t pt-2", children: [presets.map((preset) => {
|
|
373
|
+
const presetDate = addDays(todayDate, preset.days);
|
|
374
|
+
return (_jsx(Button, { appearance: "ghost", isDisabled: !getIsWithinRange(presetDate, minimum, maximum), onClick: () => {
|
|
375
|
+
setVisibleMonth(presetDate);
|
|
376
|
+
chooseDate(presetDate);
|
|
377
|
+
}, size: "sm", type: "button", children: preset.label }, preset.label));
|
|
378
|
+
}), range.start === null ? null : (_jsx(Button, { appearance: "ghost", className: "ms-auto", intent: "danger", onClick: () => {
|
|
379
|
+
setTexts({ end: "", start: "" });
|
|
380
|
+
report({ end: null, start: null });
|
|
381
|
+
setActiveEndpoint("start");
|
|
382
|
+
}, size: "sm", type: "button", children: "Clear" }))] })) : null] }) }) })) : null] }));
|
|
383
|
+
};
|
|
384
|
+
//# sourceMappingURL=DatePicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.js","sourceRoot":"","sources":["../../src/DatePicker/DatePicker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shortcut row, in its own module.
|
|
3
|
+
*
|
|
4
|
+
* Its own file for two reasons, one design and one mechanical. The
|
|
5
|
+
* design one: a preset is an **offset from today**, not a date, so
|
|
6
|
+
* the preset row cannot become the one thing in the component that
|
|
7
|
+
* reads the system clock behind `today`'s back. The mechanical one:
|
|
8
|
+
* the barrel's assist merges same-source exports into one block, and
|
|
9
|
+
* `sourceRules.test.ts` asserts a literal `export { <Name> }` line
|
|
10
|
+
* for every component — so a component file with a second named
|
|
11
|
+
* export cannot be barrelled the way that rule expects. Same
|
|
12
|
+
* arrangement as `Toolbar/chooseVisibleCount.ts`.
|
|
13
|
+
*/
|
|
14
|
+
export type DatePreset = {
|
|
15
|
+
/** Whole days from `today`. Negative is allowed. */
|
|
16
|
+
days: number;
|
|
17
|
+
label: string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Words, not glyphs — the house rule, and it is the right default
|
|
21
|
+
* here anyway: "Today" is unambiguous in a way an icon of a calendar
|
|
22
|
+
* with a dot on it is not.
|
|
23
|
+
*
|
|
24
|
+
* Three, because a shortcut row that needs scanning is not a
|
|
25
|
+
* shortcut. `presets={[]}` removes it; a consumer with its own
|
|
26
|
+
* cadence (Docket's 14-day staleness) passes its own.
|
|
27
|
+
*/
|
|
28
|
+
export declare const DEFAULT_DATE_PRESETS: readonly DatePreset[];
|
|
29
|
+
//# sourceMappingURL=datePresets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datePresets.d.ts","sourceRoot":"","sources":["../../src/DatePicker/datePresets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,UAAU,GAAG;IACvB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,UAAU,EAIrD,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shortcut row, in its own module.
|
|
3
|
+
*
|
|
4
|
+
* Its own file for two reasons, one design and one mechanical. The
|
|
5
|
+
* design one: a preset is an **offset from today**, not a date, so
|
|
6
|
+
* the preset row cannot become the one thing in the component that
|
|
7
|
+
* reads the system clock behind `today`'s back. The mechanical one:
|
|
8
|
+
* the barrel's assist merges same-source exports into one block, and
|
|
9
|
+
* `sourceRules.test.ts` asserts a literal `export { <Name> }` line
|
|
10
|
+
* for every component — so a component file with a second named
|
|
11
|
+
* export cannot be barrelled the way that rule expects. Same
|
|
12
|
+
* arrangement as `Toolbar/chooseVisibleCount.ts`.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Words, not glyphs — the house rule, and it is the right default
|
|
16
|
+
* here anyway: "Today" is unambiguous in a way an icon of a calendar
|
|
17
|
+
* with a dot on it is not.
|
|
18
|
+
*
|
|
19
|
+
* Three, because a shortcut row that needs scanning is not a
|
|
20
|
+
* shortcut. `presets={[]}` removes it; a consumer with its own
|
|
21
|
+
* cadence (Docket's 14-day staleness) passes its own.
|
|
22
|
+
*/
|
|
23
|
+
export const DEFAULT_DATE_PRESETS = [
|
|
24
|
+
{ days: 0, label: "Today" },
|
|
25
|
+
{ days: 1, label: "Tomorrow" },
|
|
26
|
+
{ days: 7, label: "Next week" },
|
|
27
|
+
];
|
|
28
|
+
//# sourceMappingURL=datePresets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datePresets.js","sourceRoot":"","sources":["../../src/DatePicker/datePresets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA0B;IACzD,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE;IAC3B,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE;IAC9B,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE;CAChC,CAAA"}
|