@gridui/date-picker 0.0.0-stage → 1.0.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 CHANGED
@@ -1,3 +1,69 @@
1
- # Temporary Holding Version
1
+ # @gridui/date-picker
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Single-date selection, inclusive date ranges and an independent embedded date panel. This family does not depend on the scheduling Calendar or Grid.
4
+
5
+ ```tsx
6
+ import "@gridui/theme/styles.css";
7
+ import "@gridui/button/styles.css";
8
+ import "@gridui/overlay/styles.css";
9
+ import "@gridui/popover/styles.css";
10
+ import "@gridui/date-picker/styles.css";
11
+
12
+ import { DatePicker, DateRangePicker, DatePickerPanel } from "@gridui/date-picker";
13
+
14
+ <DatePicker
15
+ label="Event date"
16
+ defaultMonth="2026-11-01"
17
+ defaultValue="2026-11-05"
18
+ name="eventDate"
19
+ />;
20
+
21
+ <DateRangePicker
22
+ label="Event dates"
23
+ defaultMonth="2026-11-01"
24
+ value={range}
25
+ onValueChange={setRange}
26
+ />;
27
+
28
+ <DatePickerPanel
29
+ defaultMonth="2026-11-01"
30
+ value={date}
31
+ onValueChange={setDate}
32
+ />;
33
+ ```
34
+
35
+ ## Selection and composition
36
+
37
+ `DatePickerPanel` is a standalone native date grid, with `mode="single"` (default) or `mode="range"`. It has no popover, application heading, form submission or persistence. Use it inside a GridItem, Popover, Drawer or custom form. It never requires another DatePicker component or provider. In range mode it reports the draft after each selection; applications can commit immediately or supply their own confirmation flow.
38
+
39
+ `DatePicker` and `DateRangePicker` compose that panel with GridUI Popover and Button. A single date commits and closes on selection. A range has separate draft state and commits only with Apply. Cancel, Escape and outside dismissal discard the draft when reopened. Clearing commits `null` immediately. Optional `footer` content belongs to the application; it can provide preset actions through controlled values or the standalone panel. Popover owns focus restoration, Escape and outside dismissal.
40
+
41
+ Use `value`/`onValueChange` for controlled state, or `defaultValue` for local state. Explicit `null` means empty. `open`/`onOpenChange` and `defaultOpen` provide the same choice for popups. Read-only and disabled pickers do not open or change values. Controlled consumers may reject changes. Native div props and refs reach the component root.
42
+
43
+ ## Dates, bounds and localization
44
+
45
+ `DateValue` is a Gregorian `YYYY-MM-DD` civil date, not an instant. The package does not infer a timezone or read the current clock during rendering. `defaultMonth` is required for deterministic SSR; supply `today` for the current-day marker and Today action. Values are validated instead of accepting JavaScript's invalid-day rollover.
46
+
47
+ `DateRange` has `start` and optional `end`. Both ends are **inclusive**; a missing end is an incomplete draft. Choosing an earlier endpoint sorts the range. A completed range starts over on the next selection.
48
+
49
+ `min`, `max` and `isDateDisabled` govern selection. Bounds are inclusive and ordered. A range cannot contain a disabled day: an attempted blocked interval starts a new draft at the clicked date. Existing controlled values are displayed even when later constraints make them unavailable; applications own validation of previously stored data. `isDateDisabled` must be a pure, inexpensive predicate.
50
+
51
+ `month`/`onMonthChange` optionally control the visible month; month values normalize to the first day. `months` accepts 1 or 2. Two months sit side by side when the panel has enough space and stack in narrow containers. `weekStartsOn` accepts 0–6 and defaults to Monday. `locale` defaults to `en-US`; date formatting uses an explicit UTC projection of civil dates so server/browser timezones cannot change the caption.
52
+
53
+ Localize navigation with `labels`, popup actions with `pickerLabels`, and displayed field values with `formatValue`. `label` is required on popup pickers. `size="standard" | "small"` selects date-cell/control density. Coarse pointers retain the standard cell height.
54
+
55
+ ## Keyboard and forms
56
+
57
+ The day grid has one tab stop across both visible months. Arrow keys move by day/week, Home/End by the configured week, PageUp/PageDown by month, and Shift+PageUp/PageDown by year. Horizontal movement follows writing direction. Enter/Space selects. Unavailable dates remain discoverable with `aria-disabled` but cannot be selected. Native focus indicators stay inside the date cell. Month navigation remains separate native buttons.
58
+
59
+ `name` adds a hidden form entry for a single date. Ranges use `${name}.start` and `${name}.end`. `form` supports external form ownership. Disabled entries do not submit; read-only entries do. Native reset restores uncontrolled initial values and discards drafts, respecting canceled reset events. Controlled values remain application-owned. These controls do not provide native `required` validation; applications validate submitted data and can use their Form messages.
60
+
61
+ ## Border ownership
62
+
63
+ The embedded panel defaults to `frame="none"` and paints no outer edge or day-cell borders. `frame="outline"` supplies an independent panel outline when needed. Popups always use an unframed panel because Popover owns their surface and outer border. The picker owns its functional trigger outline and internal footer separator.
64
+
65
+ Grid owns region seams and outer frames. Put an unframed DatePickerPanel directly in an unpadded GridItem; add GridItem padding when an inset is desired. Do not target private date cells from Layout styles or wrap a framed panel flush inside another frame.
66
+
67
+ CSS owns date-grid geometry, range fills and container reflow. CVA owns density and frame variants. Existing Button, Popover, focus and theme contracts supply shared interactions and styling.
68
+
69
+ See [component ownership](../../docs/component-ownership.md) and [release history](.changeset/history/).
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Date Picker
4
+ * @namespace DatePicker
5
+ * @description Date Picker
6
+ */
7
+ import type { SinglePickerOptions } from "../shared/picker-types";
8
+ import type { FC } from "react";
9
+ export type DatePickerProps = SinglePickerOptions;
10
+ export declare const DatePicker: FC<DatePickerProps>;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Date Picker
4
+ * @namespace DatePickerPanel
5
+ * @description Date Picker Panel
6
+ */
7
+ import type { DatePanelOptions, DateRange, DateValue } from "../shared/types";
8
+ import { type ComponentPropsWithRef, type FC } from "react";
9
+ export type DatePickerPanelProps = Omit<ComponentPropsWithRef<"div">, "defaultValue" | "onChange" | "children"> & DatePanelOptions & {
10
+ readonly frame?: "none" | "outline";
11
+ } & ({
12
+ readonly mode?: "single";
13
+ readonly value?: DateValue | null;
14
+ readonly defaultValue?: DateValue | null;
15
+ readonly onValueChange?: (value: DateValue | null) => void;
16
+ } | {
17
+ readonly mode: "range";
18
+ readonly value?: DateRange | null;
19
+ readonly defaultValue?: DateRange | null;
20
+ readonly onValueChange?: (value: DateRange | null) => void;
21
+ });
22
+ export declare const DatePickerPanel: FC<DatePickerPanelProps>;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Date Picker
4
+ * @namespace DatePickerPanel
5
+ * @description Month
6
+ */
7
+ import type { DateRange, DateValue } from "../shared/types";
8
+ import type { FC, KeyboardEvent } from "react";
9
+ export type MonthProps = {
10
+ readonly month: DateValue;
11
+ readonly label: string;
12
+ readonly days: readonly DateValue[];
13
+ readonly weekdays: readonly string[];
14
+ readonly getLabel: (day: DateValue) => string;
15
+ readonly getDayNumber: (day: DateValue) => number;
16
+ readonly focused: DateValue;
17
+ readonly today?: DateValue | undefined;
18
+ readonly selected: DateValue | null;
19
+ readonly range: DateRange | null;
20
+ readonly rangeMode: boolean;
21
+ readonly disabled: boolean;
22
+ readonly isAvailable: (day: DateValue) => boolean;
23
+ readonly onSelect: (day: DateValue) => void;
24
+ readonly onFocus: (day: DateValue) => void;
25
+ readonly onHover: (day: DateValue) => void;
26
+ readonly onKeyDown: (event: KeyboardEvent<HTMLButtonElement>, day: DateValue) => void;
27
+ readonly showCaption: boolean;
28
+ };
29
+ export declare const Month: FC<MonthProps>;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Date Picker
4
+ * @namespace DatePickerPanel
5
+ * @description Style
6
+ */
7
+ export declare const panelStyles: (props?: ({
8
+ frame?: "none" | "outline" | null | undefined;
9
+ size?: "standard" | "small" | null | undefined;
10
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Date Picker
4
+ * @namespace DatePickerPanel
5
+ * @description Use Panel
6
+ */
7
+ import type { DatePanelOptions, DateRange, DateValue } from "../shared/types";
8
+ import type { KeyboardEvent } from "react";
9
+ type PanelStateOptions = DatePanelOptions & {
10
+ readonly mode: "single" | "range" | undefined;
11
+ readonly value: DateValue | DateRange | null | undefined;
12
+ readonly defaultValue: DateValue | DateRange | null | undefined;
13
+ readonly onValueChange: (value: DateValue | DateRange | null) => void;
14
+ };
15
+ export declare const usePanel: (props: PanelStateOptions) => {
16
+ value: string | DateRange | null;
17
+ month: string;
18
+ visibleDays: string[];
19
+ focused: string;
20
+ hovered: string | null;
21
+ setHovered: import("react").Dispatch<import("react").SetStateAction<string | null>>;
22
+ setFocused: import("react").Dispatch<import("react").SetStateAction<string>>;
23
+ element: import("react").RefObject<HTMLDivElement | null>;
24
+ eligible: (day: DateValue) => boolean;
25
+ select: (day: DateValue) => void;
26
+ onKeyDown: (event: KeyboardEvent<HTMLButtonElement>, day: DateValue) => void;
27
+ canPrevious: boolean;
28
+ canNext: boolean;
29
+ previous: () => void;
30
+ next: () => void;
31
+ };
32
+ export {};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Date Picker
4
+ * @namespace DateRangePicker
5
+ * @description Date Range Picker
6
+ */
7
+ import type { RangePickerOptions } from "../shared/picker-types";
8
+ import type { FC } from "react";
9
+ export type DateRangePickerProps = RangePickerOptions;
10
+ export declare const DateRangePicker: FC<DateRangePickerProps>;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Date Picker
4
+ * @namespace Root
5
+ * @description Index
6
+ */
7
+ export type { DatePickerProps } from "./date-picker/date-picker";
8
+ export { DatePicker } from "./date-picker/date-picker";
9
+ export type { DatePickerPanelProps } from "./date-picker-panel/date-picker-panel";
10
+ export { DatePickerPanel } from "./date-picker-panel/date-picker-panel";
11
+ export type { DateRangePickerProps } from "./date-range-picker/date-range-picker";
12
+ export { DateRangePicker } from "./date-range-picker/date-range-picker";
13
+ export type { PickerLabels } from "./shared/picker-types";
14
+ export type { DateConstraints, DatePanelLabels, DatePanelOptions, DateRange, DateValue } from "./shared/types";