@kenos-ui/react-datepicker 0.4.0 → 0.4.2

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/CHANGELOG.md CHANGED
@@ -1,14 +1,122 @@
1
1
  # @kenos-ui/react-datepicker
2
2
 
3
+ ## 0.4.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 3222bd8: Sync controlled single `value` into reducer state via a new `SET_SELECTED_DATE` action, keeping the segmented input and calendar focused month in sync when the prop changes externally.
8
+
9
+ ## 0.4.1
10
+
11
+ ### Minor Changes
12
+
13
+ - **Kenos UI DatePicker — feature release** (`@kenos-ui/react-datepicker@0.4.1`)
14
+
15
+ Headless date & scheduling primitives for React 19+, fully unstyled and composition-first.
16
+
17
+ **Selection API**
18
+
19
+ - Unified `DatePicker.Root` with `mode`: `"single"` | `"range"` | `"multiple"`
20
+ - Controlled / uncontrolled `value`, `open`, and `onValueChange` / `onOpenChange`
21
+ - Range mode with live hover preview between `rangeStart` and `rangeEnd`
22
+ - `minDate`, `maxDate`, `disabled` (boolean or per-date function), `readOnly`, `closeOnSelect`
23
+
24
+ **Segmented input (timescape)**
25
+
26
+ - First-class `<DatePicker.Input />` — locale-aware month / day / year segments
27
+ - Dual inputs for range (`index={0}` / `index={1}`)
28
+ - Bidirectional sync: type in segments or pick from calendar
29
+ - Custom `segmentLabels` for screen readers
30
+
31
+ **Compound calendar parts**
32
+
33
+ - `Label`, `Trigger`, `Content`, `Calendar` (shorthand composition)
34
+ - `ViewControl`, `PrevTrigger`, `NextTrigger`, `ViewTrigger`
35
+ - `View` with `day` / `month` / `year` drill-down
36
+ - `Grid`, `Day` (render-prop `DayCellMeta`), `WeekDays`
37
+ - `MonthGrid` / `MonthCell`, `YearGrid` / `YearCell`
38
+ - `useDatePickerContext()` for custom layouts
39
+
40
+ **Positioning & popup policy**
41
+
42
+ - Floating UI via `Content`: `side`, `align`, `sideOffset`, `avoidCollisions`, `portal`
43
+ - `forceMount` for enter/exit animations (`data-state`)
44
+ - `modal` prop (default `false`) — opt-in focus trap + `aria-modal`; popup-policy friendly
45
+ - Focus restore to trigger / input on close; dialog-interop (`Escape` does not bubble)
46
+
47
+ **State & i18n**
48
+
49
+ - Reducer-driven state machine (`OPEN`, `SELECT_DATE`, `NAV_PREV`/`NAV_NEXT`, `SET_VIEW`, `COMMIT_INPUT`, …)
50
+ - `Intl`-based locale: week start, month/year labels, segment order & separators
51
+ - `weekStartsOn` override
52
+
53
+ **Accessibility & quality**
54
+
55
+ - WAI-ARIA: `role="dialog"`, `grid` / `gridcell`, labelled inputs, keyboard roving tabindex
56
+ - Test suite: reducer, calendar grid, date utils, ARIA, keyboard nav, dialog interop, axe (vitest-axe)
57
+ - Storybook: Single, Range, Multiple, Locales
58
+
59
+ **Docs**
60
+
61
+ - README with quick start, range / multiple examples, full composition, localization, and `Content` props
62
+
63
+ **Packaging**
64
+
65
+ - Add `license: MIT` to `package.json` (fixes npm registry showing "no license")
66
+
3
67
  ## 0.4.0
4
68
 
5
69
  ### Minor Changes
6
70
 
7
- - docs(readme): major update to README
8
- - Document the unified `DatePicker.Root` + `mode` API correctly
9
- - Highlight the segmented `<DatePicker.Input />` as the main feature
10
- - Add clear examples for range (dual inputs + hover preview), multiple, and full composition
11
- - Improve props, localization and advanced Content sections
71
+ - **Kenos UI DatePicker feature release** (`@kenos-ui/react-datepicker@0.4.0`)
72
+
73
+ Headless date & scheduling primitives for React 19+, fully unstyled and composition-first.
74
+
75
+ **Selection API**
76
+
77
+ - Unified `DatePicker.Root` with `mode`: `"single"` | `"range"` | `"multiple"`
78
+ - Controlled / uncontrolled `value`, `open`, and `onValueChange` / `onOpenChange`
79
+ - Range mode with live hover preview between `rangeStart` and `rangeEnd`
80
+ - `minDate`, `maxDate`, `disabled` (boolean or per-date function), `readOnly`, `closeOnSelect`
81
+
82
+ **Segmented input (timescape)**
83
+
84
+ - First-class `<DatePicker.Input />` — locale-aware month / day / year segments
85
+ - Dual inputs for range (`index={0}` / `index={1}`)
86
+ - Bidirectional sync: type in segments or pick from calendar
87
+ - Custom `segmentLabels` for screen readers
88
+
89
+ **Compound calendar parts**
90
+
91
+ - `Label`, `Trigger`, `Content`, `Calendar` (shorthand composition)
92
+ - `ViewControl`, `PrevTrigger`, `NextTrigger`, `ViewTrigger`
93
+ - `View` with `day` / `month` / `year` drill-down
94
+ - `Grid`, `Day` (render-prop `DayCellMeta`), `WeekDays`
95
+ - `MonthGrid` / `MonthCell`, `YearGrid` / `YearCell`
96
+ - `useDatePickerContext()` for custom layouts
97
+
98
+ **Positioning & popup policy**
99
+
100
+ - Floating UI via `Content`: `side`, `align`, `sideOffset`, `avoidCollisions`, `portal`
101
+ - `forceMount` for enter/exit animations (`data-state`)
102
+ - `modal` prop (default `false`) — opt-in focus trap + `aria-modal`; popup-policy friendly
103
+ - Focus restore to trigger / input on close; dialog-interop (`Escape` does not bubble)
104
+
105
+ **State & i18n**
106
+
107
+ - Reducer-driven state machine (`OPEN`, `SELECT_DATE`, `NAV_PREV`/`NAV_NEXT`, `SET_VIEW`, `COMMIT_INPUT`, …)
108
+ - `Intl`-based locale: week start, month/year labels, segment order & separators
109
+ - `weekStartsOn` override
110
+
111
+ **Accessibility & quality**
112
+
113
+ - WAI-ARIA: `role="dialog"`, `grid` / `gridcell`, labelled inputs, keyboard roving tabindex
114
+ - Test suite: reducer, calendar grid, date utils, ARIA, keyboard nav, dialog interop, axe (vitest-axe)
115
+ - Storybook: Single, Range, Multiple, Locales
116
+
117
+ **Docs**
118
+
119
+ - README with quick start, range / multiple examples, full composition, localization, and `Content` props
12
120
 
13
121
  ## 0.3.3
14
122
 
@@ -38,6 +146,7 @@
38
146
  ### Minor Changes
39
147
 
40
148
  - Axis lift-and-shift: publish DatePicker under `@at5/axis-datepicker`.
149
+
41
150
  - Add `@at5/axis-datepicker` — same DatePicker API and behavior as `@at5/kairo` (migrated from `packages/kairo` to `packages/datepicker`)
42
151
  - Add `@at5/axis` — aggregator re-exporting `DatePicker`
43
152
  - `@at5/kairo` — deprecated; thin re-export of `@at5/axis-datepicker` for transition
package/dist/index.cjs CHANGED
@@ -362,6 +362,20 @@ function datePickerReducer(state, action, config) {
362
362
  } : {}
363
363
  };
364
364
  }
365
+ case "SET_SELECTED_DATE": {
366
+ const d = action.date ? startOfDay(action.date) : null;
367
+ return {
368
+ ...state,
369
+ selectedDate: d,
370
+ inputValue: d ? formatDate(d, config.locale) : "",
371
+ ...d ? {
372
+ focusedDate: d,
373
+ focusedMonth: d.getMonth(),
374
+ focusedYear: d.getFullYear(),
375
+ yearPageStart: yearPageStart(d.getFullYear())
376
+ } : {}
377
+ };
378
+ }
365
379
  case "SET_INPUT":
366
380
  return { ...state, inputValue: action.value };
367
381
  case "COMMIT_INPUT": {
@@ -488,6 +502,17 @@ function useDatePicker(props) {
488
502
  prevSelectedRef.current = state.selectedDate;
489
503
  }
490
504
  }, [state.selectedDate]);
505
+ const controlledSingleValue = (!props.mode || props.mode === "single") && "value" in props && props.value !== void 0 ? props.value : void 0;
506
+ const propSelectedT = controlledSingleValue?.getTime() ?? null;
507
+ const lastSyncedPropSelectedRef = React.useRef(null);
508
+ React.useEffect(() => {
509
+ if (controlledSingleValue === void 0) return;
510
+ if (lastSyncedPropSelectedRef.current === propSelectedT) return;
511
+ lastSyncedPropSelectedRef.current = propSelectedT;
512
+ const stateT = state.selectedDate?.getTime() ?? null;
513
+ if (propSelectedT === stateT) return;
514
+ dispatch({ type: "SET_SELECTED_DATE", date: controlledSingleValue });
515
+ }, [propSelectedT, dispatch]);
491
516
  const controlledRangeValue = props.mode === "range" && "value" in props && props.value !== void 0 ? props.value : void 0;
492
517
  const lastSyncedPropRangeRef = React.useRef(
493
518
  null