@kalyx/react 1.0.0-rc.0 → 1.0.0-rc.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/dist/index.cjs CHANGED
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  'use strict';
2
3
 
3
4
  var react = require('react');
@@ -57,10 +58,10 @@ function DatePickerRoot({
57
58
  const currentValue = isControlled ? controlledValue ?? null : uncontrolledValue;
58
59
  const [isOpen, setIsOpen] = react.useState(false);
59
60
  const [viewMonth, setViewMonth] = react.useState(
60
- currentValue ?? adapter.today(displayTimezone)
61
+ () => currentValue ?? adapter.today(displayTimezone)
61
62
  );
62
63
  const [focusedDate, setFocusedDate] = react.useState(
63
- currentValue ?? adapter.today(displayTimezone)
64
+ () => currentValue ?? adapter.today(displayTimezone)
64
65
  );
65
66
  useChangeEffect(isOpen, onOpenChange);
66
67
  const viewMonthStart = react.useMemo(() => adapter.startOfMonth(viewMonth), [viewMonth, adapter]);
@@ -151,10 +152,11 @@ function DatePickerRoot({
151
152
  return /* @__PURE__ */ jsxRuntime.jsx(DatePickerContext.Provider, { value: contextValue, children });
152
153
  }
153
154
  var DatePickerInput = react.forwardRef(
154
- function DatePickerInput2({ format: formatProp, onClick, onBlur, onKeyDown, ...props }, ref) {
155
+ function DatePickerInput2({ format: formatProp, name, onClick, onBlur, onKeyDown, ...props }, ref) {
155
156
  const ctx = useDatePickerContext("DatePicker.Input");
156
157
  const displayFormat = formatProp ?? ctx.displayFormat;
157
158
  const [inputText, setInputText] = react.useState(null);
159
+ const isComposingRef = react.useRef(false);
158
160
  let formattedValue = "";
159
161
  if (ctx.value) {
160
162
  try {
@@ -171,47 +173,62 @@ var DatePickerInput = react.forwardRef(
171
173
  },
172
174
  [ctx, onClick]
173
175
  );
176
+ const commitText = react.useCallback(
177
+ (text) => {
178
+ if (!text) {
179
+ ctx.selectDate(null);
180
+ setInputText(null);
181
+ return true;
182
+ }
183
+ const parsed = core.parseInputValue(text, ctx.adapter);
184
+ if (parsed) {
185
+ ctx.selectDate(parsed);
186
+ setInputText(null);
187
+ return true;
188
+ }
189
+ return false;
190
+ },
191
+ [ctx]
192
+ );
174
193
  const handleBlur = react.useCallback(
175
194
  (e) => {
176
195
  if (inputText !== null) {
177
- const parsed = core.parseInputValue(inputText, ctx.adapter);
178
- if (parsed) {
179
- ctx.selectDate(parsed);
180
- }
196
+ commitText(inputText);
181
197
  setInputText(null);
182
198
  }
183
199
  onBlur?.(e);
184
200
  },
185
- [inputText, displayFormat, ctx, onBlur]
201
+ [inputText, commitText, onBlur]
186
202
  );
187
203
  const handleChange = react.useCallback(
188
204
  (e) => {
189
205
  const text = e.target.value;
190
206
  setInputText(text);
191
- if (!text) {
192
- ctx.selectDate(null);
193
- setInputText(null);
194
- return;
195
- }
196
- const parsed = core.parseInputValue(text, ctx.adapter);
197
- if (parsed) {
198
- ctx.selectDate(parsed);
199
- setInputText(null);
200
- }
207
+ if (isComposingRef.current) return;
208
+ commitText(text);
201
209
  },
202
- [displayFormat, ctx]
210
+ [commitText]
211
+ );
212
+ const handleCompositionStart = react.useCallback(() => {
213
+ isComposingRef.current = true;
214
+ }, []);
215
+ const handleCompositionEnd = react.useCallback(
216
+ (e) => {
217
+ isComposingRef.current = false;
218
+ commitText(e.target.value);
219
+ },
220
+ [commitText]
203
221
  );
204
222
  const handleKeyDown = react.useCallback(
205
223
  (e) => {
206
224
  if (e.key === "Escape") {
207
225
  ctx.close();
208
226
  } else if (e.key === "Enter") {
227
+ if (ctx.isOpen) e.preventDefault();
209
228
  if (inputText !== null) {
210
- const parsed = core.parseInputValue(inputText, ctx.adapter);
211
- if (parsed) {
212
- ctx.selectDate(parsed);
213
- setInputText(null);
214
- }
229
+ commitText(inputText);
230
+ } else if (ctx.isOpen) {
231
+ ctx.selectDate(ctx.focusedDate);
215
232
  }
216
233
  } else if (e.key === "ArrowDown" && !ctx.isOpen) {
217
234
  e.preventDefault();
@@ -219,36 +236,42 @@ var DatePickerInput = react.forwardRef(
219
236
  }
220
237
  onKeyDown?.(e);
221
238
  },
222
- [ctx, inputText, displayFormat, onKeyDown]
239
+ [ctx, inputText, commitText, onKeyDown]
223
240
  );
224
241
  const calendarId = `${ctx.pickerId}-calendar`;
225
- return /* @__PURE__ */ jsxRuntime.jsx(
226
- "input",
227
- {
228
- ref: (node) => {
229
- ctx.referenceRef.current = node;
230
- if (typeof ref === "function") ref(node);
231
- else if (ref) ref.current = node;
232
- },
233
- type: "text",
234
- role: "combobox",
235
- "aria-expanded": ctx.isOpen,
236
- "aria-haspopup": "dialog",
237
- "aria-controls": ctx.isOpen ? calendarId : void 0,
238
- "aria-autocomplete": "none",
239
- autoComplete: "off",
240
- value: displayValue,
241
- disabled: ctx.isDisabled || props.disabled,
242
- readOnly: ctx.isReadOnly,
243
- onChange: handleChange,
244
- onClick: handleClick,
245
- onBlur: handleBlur,
246
- onKeyDown: handleKeyDown,
247
- ...props
248
- }
249
- );
242
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
243
+ /* @__PURE__ */ jsxRuntime.jsx(
244
+ "input",
245
+ {
246
+ ref: (node) => {
247
+ ctx.referenceRef.current = node;
248
+ if (typeof ref === "function") ref(node);
249
+ else if (ref) ref.current = node;
250
+ },
251
+ type: "text",
252
+ role: "combobox",
253
+ "aria-expanded": ctx.isOpen,
254
+ "aria-haspopup": "dialog",
255
+ "aria-controls": ctx.isOpen ? calendarId : void 0,
256
+ "aria-autocomplete": "none",
257
+ autoComplete: "off",
258
+ value: displayValue,
259
+ disabled: ctx.isDisabled || props.disabled,
260
+ readOnly: ctx.isReadOnly,
261
+ onChange: handleChange,
262
+ onClick: handleClick,
263
+ onBlur: handleBlur,
264
+ onKeyDown: handleKeyDown,
265
+ onCompositionStart: handleCompositionStart,
266
+ onCompositionEnd: handleCompositionEnd,
267
+ ...props
268
+ }
269
+ ),
270
+ name ? /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: ctx.value ?? "" }) : null
271
+ ] });
250
272
  }
251
273
  );
274
+ DatePickerInput.displayName = "DatePicker.Input";
252
275
  var DatePickerTrigger = react.forwardRef(
253
276
  function DatePickerTrigger2({ onClick, children, ...props }, ref) {
254
277
  const ctx = useDatePickerContext("DatePicker.Trigger");
@@ -272,6 +295,7 @@ var DatePickerTrigger = react.forwardRef(
272
295
  tabIndex: 0,
273
296
  "aria-label": ctx.isOpen ? ctx.labels.triggerClose : ctx.labels.triggerOpen,
274
297
  "aria-expanded": ctx.isOpen,
298
+ "aria-haspopup": "dialog",
275
299
  "aria-controls": ctx.isOpen ? calendarId : void 0,
276
300
  disabled: ctx.isDisabled || props.disabled,
277
301
  onClick: handleClick,
@@ -302,13 +326,20 @@ var DatePickerTrigger = react.forwardRef(
302
326
  );
303
327
  }
304
328
  );
305
- function usePopover({ isOpen, close, referenceRef, placement = "bottom-start" }) {
329
+ DatePickerTrigger.displayName = "DatePicker.Trigger";
330
+ var POPOVER_MIDDLEWARE = [react$1.offset(4), react$1.flip(), react$1.shift({ padding: 8 })];
331
+ function usePopover({
332
+ isOpen,
333
+ close,
334
+ referenceRef,
335
+ placement = "bottom-start"
336
+ }) {
306
337
  const floatingRef = react.useRef(null);
307
338
  const previousFocusRef = react.useRef(null);
308
- const { refs, floatingStyles } = react$1.useFloating({
339
+ const { refs, floatingStyles, isPositioned } = react$1.useFloating({
309
340
  open: isOpen,
310
341
  placement,
311
- middleware: [react$1.offset(4), react$1.flip(), react$1.shift({ padding: 8 })],
342
+ middleware: POPOVER_MIDDLEWARE,
312
343
  whileElementsMounted: react$1.autoUpdate
313
344
  });
314
345
  react.useEffect(() => {
@@ -355,21 +386,46 @@ function usePopover({ isOpen, close, referenceRef, placement = "bottom-start" })
355
386
  document.addEventListener("keydown", handleKeyDown);
356
387
  return () => document.removeEventListener("keydown", handleKeyDown);
357
388
  }, [isOpen, close]);
358
- const setFloatingRef = (node) => {
359
- floatingRef.current = node;
360
- refs.setFloating(node);
361
- };
362
- return { floatingStyles, setFloatingRef };
389
+ react.useEffect(() => {
390
+ if (!isOpen) return;
391
+ function handleFocusOut(e) {
392
+ const next = e.relatedTarget;
393
+ const floating = floatingRef.current;
394
+ const reference = referenceRef.current;
395
+ if (!next) return;
396
+ const insideFloating = floating?.contains(next) ?? false;
397
+ const insideReference = reference?.contains(next) ?? false;
398
+ if (!insideFloating && !insideReference) {
399
+ close();
400
+ }
401
+ }
402
+ const node = floatingRef.current;
403
+ if (!node) return;
404
+ node.addEventListener("focusout", handleFocusOut);
405
+ return () => node.removeEventListener("focusout", handleFocusOut);
406
+ }, [isOpen, close, referenceRef]);
407
+ const setFloatingRef = react.useCallback(
408
+ (node) => {
409
+ floatingRef.current = node;
410
+ refs.setFloating(node);
411
+ if (node && referenceRef.current) {
412
+ refs.setReference(referenceRef.current);
413
+ }
414
+ },
415
+ [refs, referenceRef]
416
+ );
417
+ return { floatingStyles, setFloatingRef, isPositioned };
363
418
  }
364
419
  function DatePickerPopover({ children, ...props }) {
365
420
  const ctx = useDatePickerContext("DatePicker.Popover");
366
421
  const calendarId = `${ctx.pickerId}-calendar`;
367
- const { floatingStyles, setFloatingRef } = usePopover({
422
+ const { floatingStyles, setFloatingRef, isPositioned } = usePopover({
368
423
  isOpen: ctx.isOpen,
369
424
  close: ctx.close,
370
425
  referenceRef: ctx.referenceRef
371
426
  });
372
427
  if (!ctx.isOpen) return null;
428
+ const { style: userStyle, ...rest } = props;
373
429
  return /* @__PURE__ */ jsxRuntime.jsx(
374
430
  "div",
375
431
  {
@@ -378,8 +434,12 @@ function DatePickerPopover({ children, ...props }) {
378
434
  role: "dialog",
379
435
  "aria-label": ctx.labels.popoverLabel,
380
436
  "aria-modal": "false",
381
- style: floatingStyles,
382
- ...props,
437
+ ...rest,
438
+ style: {
439
+ ...userStyle,
440
+ ...floatingStyles,
441
+ visibility: isPositioned ? void 0 : "hidden"
442
+ },
383
443
  children
384
444
  }
385
445
  );
@@ -402,27 +462,32 @@ var srOnly = {
402
462
  whiteSpace: "nowrap",
403
463
  border: 0
404
464
  };
405
- function DatePickerCalendar({ classNames, onTitleClick, ...props }) {
465
+ function DatePickerCalendar({
466
+ classNames,
467
+ onTitleClick,
468
+ ...props
469
+ }) {
406
470
  const ctx = useDatePickerContext("DatePicker.Calendar");
407
471
  const gridRef = react.useRef(null);
408
472
  const [announcement, setAnnouncement] = react.useState("");
409
473
  const { adapter, viewMonth, focusedDate, weekStartsOn, disabled, locale, displayTimezone } = ctx;
410
- const weekdays = core.getWeekdayNames(locale, weekStartsOn);
411
- const weeks = core.getCalendarDays(viewMonth, adapter, {
412
- weekStartsOn,
413
- selected: ctx.value,
414
- focusedDate,
415
- disabled,
416
- timezone: displayTimezone
417
- });
474
+ const weekdays = react.useMemo(() => core.getWeekdayNames(locale, weekStartsOn), [locale, weekStartsOn]);
475
+ const weeks = react.useMemo(
476
+ () => core.getCalendarDays(viewMonth, adapter, {
477
+ weekStartsOn,
478
+ selected: ctx.value,
479
+ focusedDate,
480
+ disabled,
481
+ timezone: displayTimezone
482
+ }),
483
+ [viewMonth, adapter, weekStartsOn, ctx.value, focusedDate, disabled, displayTimezone]
484
+ );
418
485
  const year = adapter.getYear(viewMonth);
419
486
  const month = adapter.getMonth(viewMonth);
420
487
  const title = core.formatMonthYear(year, month, locale);
421
488
  react.useEffect(() => {
422
489
  if (!ctx.isOpen || !gridRef.current) return;
423
- const focusedButton = gridRef.current.querySelector(
424
- '[data-focused="true"]'
425
- );
490
+ const focusedButton = gridRef.current.querySelector('[data-focused="true"]');
426
491
  focusedButton?.focus({ preventScroll: true });
427
492
  }, [focusedDate, ctx.isOpen]);
428
493
  const navigateMonth = react.useCallback(
@@ -496,6 +561,15 @@ function DatePickerCalendar({ classNames, onTitleClick, ...props }) {
496
561
  }
497
562
  if (newFocused) {
498
563
  e.preventDefault();
564
+ const skipStep = e.key === "ArrowLeft" || e.key === "ArrowUp" || e.key === "PageUp" || e.key === "Home" ? -1 : 1;
565
+ let attempts = 0;
566
+ while (core.isDateDisabled(newFocused, disabled, adapter) && attempts < 42) {
567
+ newFocused = adapter.addDays(newFocused, skipStep);
568
+ attempts++;
569
+ }
570
+ if (attempts >= 42) {
571
+ return;
572
+ }
499
573
  ctx.setFocusedDate(newFocused);
500
574
  if (!adapter.isSameMonth(newFocused, viewMonth)) {
501
575
  ctx.setViewMonth(newFocused);
@@ -543,56 +617,69 @@ function DatePickerCalendar({ classNames, onTitleClick, ...props }) {
543
617
  ref: gridRef,
544
618
  role: "grid",
545
619
  "aria-label": title,
620
+ "aria-rowcount": weeks.length + 1,
621
+ "aria-colcount": 7,
546
622
  className: classNames?.grid,
547
623
  onKeyDown: handleKeyDown,
548
624
  children: [
549
- /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { role: "row", children: weekdays.map((day) => /* @__PURE__ */ jsxRuntime.jsx(
625
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { role: "row", "aria-rowindex": 1, children: weekdays.map((day, colIndex) => /* @__PURE__ */ jsxRuntime.jsx(
550
626
  "th",
551
627
  {
552
628
  role: "columnheader",
553
629
  abbr: day.full,
554
630
  scope: "col",
631
+ "aria-colindex": colIndex + 1,
555
632
  className: classNames?.weekdayHeader,
556
633
  children: day.short
557
634
  },
558
635
  day.short
559
636
  )) }) }),
560
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: weeks.map((week, weekIndex) => /* @__PURE__ */ jsxRuntime.jsx("tr", { role: "row", className: classNames?.gridRow, children: week.map((day) => {
561
- const dayClasses = [
562
- classNames?.day,
563
- day.isSelected && classNames?.daySelected,
564
- day.isToday && classNames?.dayToday,
565
- day.isDisabled && classNames?.dayDisabled,
566
- !day.isCurrentMonth && classNames?.dayOutsideMonth
567
- ].filter(Boolean).join(" ") || void 0;
568
- return /* @__PURE__ */ jsxRuntime.jsx(
569
- "td",
570
- {
571
- role: "gridcell",
572
- "aria-selected": day.isSelected || void 0,
573
- "aria-disabled": day.isDisabled || void 0,
574
- "aria-current": day.isToday ? "date" : void 0,
575
- className: classNames?.gridCell,
576
- children: /* @__PURE__ */ jsxRuntime.jsx(
577
- "button",
637
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: weeks.map((week, weekIndex) => /* @__PURE__ */ jsxRuntime.jsx(
638
+ "tr",
639
+ {
640
+ role: "row",
641
+ "aria-rowindex": weekIndex + 2,
642
+ className: classNames?.gridRow,
643
+ children: week.map((day, colIndex) => {
644
+ const dayClasses = [
645
+ classNames?.day,
646
+ day.isSelected && classNames?.daySelected,
647
+ day.isToday && classNames?.dayToday,
648
+ day.isDisabled && classNames?.dayDisabled,
649
+ !day.isCurrentMonth && classNames?.dayOutsideMonth
650
+ ].filter(Boolean).join(" ") || void 0;
651
+ return /* @__PURE__ */ jsxRuntime.jsx(
652
+ "td",
578
653
  {
579
- type: "button",
580
- tabIndex: day.isFocused ? 0 : -1,
581
- disabled: day.isDisabled,
582
- "data-focused": day.isFocused || void 0,
583
- "data-selected": day.isSelected || void 0,
584
- "data-today": day.isToday || void 0,
585
- "data-outside-month": !day.isCurrentMonth || void 0,
586
- className: dayClasses,
587
- onClick: () => handleDayClick(day),
588
- "aria-label": safeFormatFullDate(day.isoString, locale),
589
- children: day.dayNumber
590
- }
591
- )
592
- },
593
- day.isoString
594
- );
595
- }) }, weekIndex)) })
654
+ role: "gridcell",
655
+ "aria-colindex": colIndex + 1,
656
+ "aria-selected": day.isSelected || void 0,
657
+ "aria-disabled": day.isDisabled || void 0,
658
+ "aria-current": day.isToday ? "date" : void 0,
659
+ className: classNames?.gridCell,
660
+ children: /* @__PURE__ */ jsxRuntime.jsx(
661
+ "button",
662
+ {
663
+ type: "button",
664
+ tabIndex: day.isFocused ? 0 : -1,
665
+ disabled: day.isDisabled,
666
+ "data-focused": day.isFocused || void 0,
667
+ "data-selected": day.isSelected || void 0,
668
+ "data-today": day.isToday || void 0,
669
+ "data-outside-month": !day.isCurrentMonth || void 0,
670
+ className: dayClasses,
671
+ onClick: () => handleDayClick(day),
672
+ "aria-label": safeFormatFullDate(day.isoString, locale),
673
+ children: day.dayNumber
674
+ }
675
+ )
676
+ },
677
+ day.isoString
678
+ );
679
+ })
680
+ },
681
+ weekIndex
682
+ )) })
596
683
  ]
597
684
  }
598
685
  ),
@@ -645,15 +732,7 @@ function DatePickerMonthGrid({
645
732
  children: "<"
646
733
  }
647
734
  ),
648
- onTitleClick ? /* @__PURE__ */ jsxRuntime.jsx(
649
- "button",
650
- {
651
- type: "button",
652
- className: classNames?.title,
653
- onClick: onTitleClick,
654
- children: currentYear
655
- }
656
- ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: classNames?.title, children: currentYear }),
735
+ onTitleClick ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: classNames?.title, onClick: onTitleClick, children: currentYear }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: classNames?.title, children: currentYear }),
657
736
  /* @__PURE__ */ jsxRuntime.jsx(
658
737
  "button",
659
738
  {
@@ -698,11 +777,7 @@ function DatePickerMonthGrid({
698
777
  )
699
778
  ] });
700
779
  }
701
- function DatePickerYearGrid({
702
- classNames,
703
- onSelect,
704
- ...props
705
- }) {
780
+ function DatePickerYearGrid({ classNames, onSelect, ...props }) {
706
781
  const ctx = useDatePickerContext("DatePicker.YearGrid");
707
782
  const { adapter, viewMonth } = ctx;
708
783
  const currentYear = adapter.getYear(viewMonth);
@@ -796,16 +871,7 @@ function DatePickerYearGrid({
796
871
  }
797
872
  function DatePickerPresets({ classNames, children, ...props }) {
798
873
  const ctx = useDatePickerContext("DatePicker.Presets");
799
- return /* @__PURE__ */ jsxRuntime.jsx(
800
- "div",
801
- {
802
- role: "group",
803
- "aria-label": ctx.labels.popoverLabel,
804
- className: classNames?.root,
805
- ...props,
806
- children
807
- }
808
- );
874
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "group", "aria-label": ctx.labels.popoverLabel, className: classNames?.root, ...props, children });
809
875
  }
810
876
  function resolveDatePreset(key, today, adapter) {
811
877
  switch (key) {
@@ -859,11 +925,7 @@ function DatePickerPreset({
859
925
  if (directDate) {
860
926
  target = directDate;
861
927
  } else if (presetKey) {
862
- target = resolveDatePreset(
863
- presetKey,
864
- ctx.adapter.today(ctx.displayTimezone),
865
- ctx.adapter
866
- );
928
+ target = resolveDatePreset(presetKey, ctx.adapter.today(ctx.displayTimezone), ctx.adapter);
867
929
  } else {
868
930
  return false;
869
931
  }
@@ -938,10 +1000,10 @@ function RangePickerRoot({
938
1000
  const [selectingTarget, setSelectingTarget] = react.useState("start");
939
1001
  const [hoverDate, setHoverDate] = react.useState(null);
940
1002
  const [viewMonth, setViewMonth] = react.useState(
941
- currentValue.start ?? adapter.today(displayTimezone)
1003
+ () => currentValue.start ?? adapter.today(displayTimezone)
942
1004
  );
943
1005
  const [focusedDate, setFocusedDate] = react.useState(
944
- currentValue.start ?? adapter.today(displayTimezone)
1006
+ () => currentValue.start ?? adapter.today(displayTimezone)
945
1007
  );
946
1008
  useChangeEffect(isOpen, onOpenChange);
947
1009
  const viewMonthStart = react.useMemo(() => adapter.startOfMonth(viewMonth), [viewMonth, adapter]);
@@ -1091,6 +1153,8 @@ var RangePickerInput = react.forwardRef(
1091
1153
  (e) => {
1092
1154
  if (e.key === "Escape") {
1093
1155
  ctx.close();
1156
+ } else if (e.key === "Enter" && ctx.isOpen) {
1157
+ e.preventDefault();
1094
1158
  } else if (e.key === "ArrowDown" && !ctx.isOpen) {
1095
1159
  e.preventDefault();
1096
1160
  ctx.open();
@@ -1127,15 +1191,17 @@ var RangePickerInput = react.forwardRef(
1127
1191
  );
1128
1192
  }
1129
1193
  );
1194
+ RangePickerInput.displayName = "RangePicker.Input";
1130
1195
  function RangePickerPopover({ children, ...props }) {
1131
1196
  const ctx = useRangePickerContext("RangePicker.Popover");
1132
1197
  const calendarId = `${ctx.pickerId}-calendar`;
1133
- const { floatingStyles, setFloatingRef } = usePopover({
1198
+ const { floatingStyles, setFloatingRef, isPositioned } = usePopover({
1134
1199
  isOpen: ctx.isOpen,
1135
1200
  close: ctx.close,
1136
1201
  referenceRef: ctx.referenceRef
1137
1202
  });
1138
1203
  if (!ctx.isOpen) return null;
1204
+ const { style: userStyle, ...rest } = props;
1139
1205
  return /* @__PURE__ */ jsxRuntime.jsx(
1140
1206
  "div",
1141
1207
  {
@@ -1144,8 +1210,12 @@ function RangePickerPopover({ children, ...props }) {
1144
1210
  role: "dialog",
1145
1211
  "aria-label": ctx.labels.popoverLabel,
1146
1212
  "aria-modal": "false",
1147
- style: floatingStyles,
1148
- ...props,
1213
+ ...rest,
1214
+ style: {
1215
+ ...userStyle,
1216
+ ...floatingStyles,
1217
+ visibility: isPositioned ? void 0 : "hidden"
1218
+ },
1149
1219
  children
1150
1220
  }
1151
1221
  );
@@ -1188,23 +1258,24 @@ function RangePickerCalendar({
1188
1258
  displayTimezone
1189
1259
  } = ctx;
1190
1260
  const { locale } = ctx;
1191
- const weekdays = core.getWeekdayNames(locale, weekStartsOn);
1192
- const weeks = core.getCalendarDays(viewMonth, adapter, {
1193
- weekStartsOn,
1194
- focusedDate,
1195
- disabled,
1196
- range: value,
1197
- rangeHover: hoverDate,
1198
- timezone: displayTimezone
1199
- });
1261
+ const weekdays = react.useMemo(() => core.getWeekdayNames(locale, weekStartsOn), [locale, weekStartsOn]);
1262
+ const weeks = react.useMemo(
1263
+ () => core.getCalendarDays(viewMonth, adapter, {
1264
+ weekStartsOn,
1265
+ focusedDate,
1266
+ disabled,
1267
+ range: value,
1268
+ rangeHover: hoverDate,
1269
+ timezone: displayTimezone
1270
+ }),
1271
+ [viewMonth, adapter, weekStartsOn, focusedDate, disabled, value, hoverDate, displayTimezone]
1272
+ );
1200
1273
  const year = adapter.getYear(viewMonth);
1201
1274
  const month = adapter.getMonth(viewMonth);
1202
1275
  const title = core.formatMonthYear(year, month, locale);
1203
1276
  react.useEffect(() => {
1204
1277
  if (!ctx.isOpen || !gridRef.current) return;
1205
- const focusedButton = gridRef.current.querySelector(
1206
- '[data-focused="true"]'
1207
- );
1278
+ const focusedButton = gridRef.current.querySelector('[data-focused="true"]');
1208
1279
  focusedButton?.focus({ preventScroll: true });
1209
1280
  }, [focusedDate, ctx.isOpen]);
1210
1281
  const navigateMonth = react.useCallback(
@@ -1298,6 +1369,13 @@ function RangePickerCalendar({
1298
1369
  }
1299
1370
  if (newFocused) {
1300
1371
  e.preventDefault();
1372
+ const skipStep = e.key === "ArrowLeft" || e.key === "ArrowUp" || e.key === "PageUp" || e.key === "Home" ? -1 : 1;
1373
+ let attempts = 0;
1374
+ while (core.isDateDisabled(newFocused, disabled, adapter) && attempts < 42) {
1375
+ newFocused = adapter.addDays(newFocused, skipStep);
1376
+ attempts++;
1377
+ }
1378
+ if (attempts >= 42) return;
1301
1379
  ctx.setFocusedDate(newFocused);
1302
1380
  if (!adapter.isSameMonth(newFocused, viewMonth)) {
1303
1381
  ctx.setViewMonth(newFocused);
@@ -1307,7 +1385,18 @@ function RangePickerCalendar({
1307
1385
  }
1308
1386
  }
1309
1387
  },
1310
- [adapter, focusedDate, viewMonth, weekStartsOn, disabled, ctx, selectionMode, selectingTarget, value.start, commitDay]
1388
+ [
1389
+ adapter,
1390
+ focusedDate,
1391
+ viewMonth,
1392
+ weekStartsOn,
1393
+ disabled,
1394
+ ctx,
1395
+ selectionMode,
1396
+ selectingTarget,
1397
+ value.start,
1398
+ commitDay
1399
+ ]
1311
1400
  );
1312
1401
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classNames?.root, ...props, onMouseLeave: handleMouseLeave, children: [
1313
1402
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classNames?.header, children: [
@@ -1340,62 +1429,75 @@ function RangePickerCalendar({
1340
1429
  role: "grid",
1341
1430
  "aria-label": title,
1342
1431
  "aria-multiselectable": "true",
1432
+ "aria-rowcount": weeks.length + 1,
1433
+ "aria-colcount": 7,
1343
1434
  className: classNames?.grid,
1344
1435
  onKeyDown: handleKeyDown,
1345
1436
  children: [
1346
- /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { role: "row", children: weekdays.map((day) => /* @__PURE__ */ jsxRuntime.jsx(
1437
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { role: "row", "aria-rowindex": 1, children: weekdays.map((day, colIndex) => /* @__PURE__ */ jsxRuntime.jsx(
1347
1438
  "th",
1348
1439
  {
1349
1440
  role: "columnheader",
1350
1441
  abbr: day.full,
1351
1442
  scope: "col",
1443
+ "aria-colindex": colIndex + 1,
1352
1444
  className: classNames?.weekdayHeader,
1353
1445
  children: day.short
1354
1446
  },
1355
1447
  day.short
1356
1448
  )) }) }),
1357
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: weeks.map((week, weekIndex) => /* @__PURE__ */ jsxRuntime.jsx("tr", { role: "row", className: classNames?.gridRow, children: week.map((day) => {
1358
- const dayClasses = [
1359
- classNames?.day,
1360
- day.isRangeStart && classNames?.dayRangeStart,
1361
- day.isRangeEnd && classNames?.dayRangeEnd,
1362
- day.isInRange && classNames?.dayInRange,
1363
- day.isToday && classNames?.dayToday,
1364
- day.isDisabled && classNames?.dayDisabled,
1365
- !day.isCurrentMonth && classNames?.dayOutsideMonth
1366
- ].filter(Boolean).join(" ") || void 0;
1367
- const isSelected = selectionMode === "week" ? day.isRangeStart || day.isRangeEnd || day.isInRange : day.isRangeStart || day.isRangeEnd;
1368
- return /* @__PURE__ */ jsxRuntime.jsx(
1369
- "td",
1370
- {
1371
- role: "gridcell",
1372
- "aria-selected": isSelected || void 0,
1373
- "aria-disabled": day.isDisabled || void 0,
1374
- "aria-current": day.isToday ? "date" : void 0,
1375
- className: classNames?.gridCell,
1376
- children: /* @__PURE__ */ jsxRuntime.jsx(
1377
- "button",
1449
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: weeks.map((week, weekIndex) => /* @__PURE__ */ jsxRuntime.jsx(
1450
+ "tr",
1451
+ {
1452
+ role: "row",
1453
+ "aria-rowindex": weekIndex + 2,
1454
+ className: classNames?.gridRow,
1455
+ children: week.map((day, colIndex) => {
1456
+ const dayClasses = [
1457
+ classNames?.day,
1458
+ day.isRangeStart && classNames?.dayRangeStart,
1459
+ day.isRangeEnd && classNames?.dayRangeEnd,
1460
+ day.isInRange && classNames?.dayInRange,
1461
+ day.isToday && classNames?.dayToday,
1462
+ day.isDisabled && classNames?.dayDisabled,
1463
+ !day.isCurrentMonth && classNames?.dayOutsideMonth
1464
+ ].filter(Boolean).join(" ") || void 0;
1465
+ const isSelected = selectionMode === "week" ? day.isRangeStart || day.isRangeEnd || day.isInRange : day.isRangeStart || day.isRangeEnd;
1466
+ return /* @__PURE__ */ jsxRuntime.jsx(
1467
+ "td",
1378
1468
  {
1379
- type: "button",
1380
- tabIndex: day.isFocused ? 0 : -1,
1381
- disabled: day.isDisabled,
1382
- "data-focused": day.isFocused || void 0,
1383
- "data-range-start": day.isRangeStart || void 0,
1384
- "data-range-end": day.isRangeEnd || void 0,
1385
- "data-in-range": day.isInRange || void 0,
1386
- "data-today": day.isToday || void 0,
1387
- "data-outside-month": !day.isCurrentMonth || void 0,
1388
- className: dayClasses,
1389
- onClick: () => handleDayClick(day),
1390
- onMouseEnter: () => handleDayMouseEnter(day),
1391
- "aria-label": safeFormatFullDate2(day.isoString, locale),
1392
- children: day.dayNumber
1393
- }
1394
- )
1395
- },
1396
- day.isoString
1397
- );
1398
- }) }, weekIndex)) })
1469
+ role: "gridcell",
1470
+ "aria-colindex": colIndex + 1,
1471
+ "aria-selected": isSelected || void 0,
1472
+ "aria-disabled": day.isDisabled || void 0,
1473
+ "aria-current": day.isToday ? "date" : void 0,
1474
+ className: classNames?.gridCell,
1475
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1476
+ "button",
1477
+ {
1478
+ type: "button",
1479
+ tabIndex: day.isFocused ? 0 : -1,
1480
+ disabled: day.isDisabled,
1481
+ "data-focused": day.isFocused || void 0,
1482
+ "data-range-start": day.isRangeStart || void 0,
1483
+ "data-range-end": day.isRangeEnd || void 0,
1484
+ "data-in-range": day.isInRange || void 0,
1485
+ "data-today": day.isToday || void 0,
1486
+ "data-outside-month": !day.isCurrentMonth || void 0,
1487
+ className: dayClasses,
1488
+ onClick: () => handleDayClick(day),
1489
+ onMouseEnter: () => handleDayMouseEnter(day),
1490
+ "aria-label": safeFormatFullDate2(day.isoString, locale),
1491
+ children: day.dayNumber
1492
+ }
1493
+ )
1494
+ },
1495
+ day.isoString
1496
+ );
1497
+ })
1498
+ },
1499
+ weekIndex
1500
+ )) })
1399
1501
  ]
1400
1502
  }
1401
1503
  ),
@@ -1444,9 +1546,7 @@ function resolvePreset(key, today, adapter) {
1444
1546
  }
1445
1547
  case "thisYear": {
1446
1548
  const currentMonth = new Date(today).getUTCMonth();
1447
- const yearStart = adapter.startOfMonth(
1448
- adapter.addMonths(today, -currentMonth)
1449
- );
1549
+ const yearStart = adapter.startOfMonth(adapter.addMonths(today, -currentMonth));
1450
1550
  return { start: yearStart, end: today };
1451
1551
  }
1452
1552
  }
@@ -1582,7 +1682,19 @@ function TimePickerRoot({
1582
1682
  pickerId,
1583
1683
  labels: mergedLabels
1584
1684
  }),
1585
- [currentValue, setTime, format, step, withSeconds, displayTimezone, disabled, readOnly, currentTime, pickerId, mergedLabels]
1685
+ [
1686
+ currentValue,
1687
+ setTime,
1688
+ format,
1689
+ step,
1690
+ withSeconds,
1691
+ displayTimezone,
1692
+ disabled,
1693
+ readOnly,
1694
+ currentTime,
1695
+ pickerId,
1696
+ mergedLabels
1697
+ ]
1586
1698
  );
1587
1699
  return /* @__PURE__ */ jsxRuntime.jsx(TimePickerContext.Provider, { value: contextValue, children });
1588
1700
  }
@@ -1599,12 +1711,9 @@ var TimePickerInput = react.forwardRef(
1599
1711
  }
1600
1712
  setInputText(null);
1601
1713
  }, [inputText, ctx]);
1602
- const handleChange = react.useCallback(
1603
- (e) => {
1604
- setInputText(e.target.value);
1605
- },
1606
- []
1607
- );
1714
+ const handleChange = react.useCallback((e) => {
1715
+ setInputText(e.target.value);
1716
+ }, []);
1608
1717
  const handleBlur = react.useCallback(
1609
1718
  (e) => {
1610
1719
  commitInput();
@@ -1641,6 +1750,7 @@ var TimePickerInput = react.forwardRef(
1641
1750
  );
1642
1751
  }
1643
1752
  );
1753
+ TimePickerInput.displayName = "TimePicker.Input";
1644
1754
  function useListboxNavigation({
1645
1755
  items,
1646
1756
  onSelect,
@@ -1677,9 +1787,7 @@ function useListboxNavigation({
1677
1787
  onSelect(target);
1678
1788
  cancelAnimationFrame(rafIdRef.current);
1679
1789
  rafIdRef.current = requestAnimationFrame(() => {
1680
- const next = listRef.current?.querySelector(
1681
- '[data-selected="true"]'
1682
- );
1790
+ const next = listRef.current?.querySelector('[data-selected="true"]');
1683
1791
  next?.focus();
1684
1792
  });
1685
1793
  }
@@ -1691,7 +1799,7 @@ function useListboxNavigation({
1691
1799
  function TimePickerHourList({ classNames, ...props }) {
1692
1800
  const ctx = useTimePickerContext("TimePicker.HourList");
1693
1801
  const { format, currentTime, isDisabled, isReadOnly } = ctx;
1694
- const hours = core.generateHours(format);
1802
+ const hours = react.useMemo(() => core.generateHours(format), [format]);
1695
1803
  const selectedHourDisplay = format === "12h" ? core.to12Hour(currentTime.hours).hours12 : currentTime.hours;
1696
1804
  const currentPeriod = format === "12h" ? core.to12Hour(currentTime.hours).period : null;
1697
1805
  const handleSelect = react.useCallback(
@@ -1742,7 +1850,7 @@ function TimePickerHourList({ classNames, ...props }) {
1742
1850
  function TimePickerMinuteList({ classNames, ...props }) {
1743
1851
  const ctx = useTimePickerContext("TimePicker.MinuteList");
1744
1852
  const { step, currentTime, isDisabled, isReadOnly } = ctx;
1745
- const minutes = core.generateMinutes(step);
1853
+ const minutes = react.useMemo(() => core.generateMinutes(step), [step]);
1746
1854
  const handleSelect = react.useCallback(
1747
1855
  (minute) => {
1748
1856
  if (isDisabled || isReadOnly) return;
@@ -1816,10 +1924,19 @@ function TimePickerAmPmToggle({ classNames, ...props }) {
1816
1924
  }
1817
1925
  );
1818
1926
  };
1819
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "radiogroup", "aria-label": ctx.labels.amPmToggle, className: classNames?.root, ...props, children: [
1820
- renderButton("AM"),
1821
- renderButton("PM")
1822
- ] });
1927
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1928
+ "div",
1929
+ {
1930
+ role: "radiogroup",
1931
+ "aria-label": ctx.labels.amPmToggle,
1932
+ className: classNames?.root,
1933
+ ...props,
1934
+ children: [
1935
+ renderButton("AM"),
1936
+ renderButton("PM")
1937
+ ]
1938
+ }
1939
+ );
1823
1940
  }
1824
1941
 
1825
1942
  // src/components/TimePicker/index.ts
@@ -1867,10 +1984,10 @@ function DateTimePickerRoot({
1867
1984
  const currentValue = isControlled ? controlledValue ?? null : uncontrolledValue;
1868
1985
  const [isOpen, setIsOpen] = react.useState(false);
1869
1986
  const [viewMonth, setViewMonth] = react.useState(
1870
- currentValue ?? adapter.today(displayTimezone)
1987
+ () => currentValue ?? adapter.today(displayTimezone)
1871
1988
  );
1872
1989
  const [focusedDate, setFocusedDate] = react.useState(
1873
- currentValue ?? adapter.today(displayTimezone)
1990
+ () => currentValue ?? adapter.today(displayTimezone)
1874
1991
  );
1875
1992
  useChangeEffect(isOpen, onOpenChange);
1876
1993
  const viewMonthStart = react.useMemo(() => adapter.startOfMonth(viewMonth), [viewMonth, adapter]);
@@ -1989,7 +2106,18 @@ function DateTimePickerRoot({
1989
2106
  pickerId,
1990
2107
  labels: mergedTimeLabels
1991
2108
  }),
1992
- [currentValue, setTime, format, step, displayTimezone, isDisabled, readOnly, currentTime, pickerId, mergedTimeLabels]
2109
+ [
2110
+ currentValue,
2111
+ setTime,
2112
+ format,
2113
+ step,
2114
+ displayTimezone,
2115
+ isDisabled,
2116
+ readOnly,
2117
+ currentTime,
2118
+ pickerId,
2119
+ mergedTimeLabels
2120
+ ]
1993
2121
  );
1994
2122
  return /* @__PURE__ */ jsxRuntime.jsx(DatePickerContext.Provider, { value: dateContext, children: /* @__PURE__ */ jsxRuntime.jsx(TimePickerContext.Provider, { value: timeContext, children }) });
1995
2123
  }
@@ -2017,6 +2145,8 @@ var DateTimePickerInput = react.forwardRef(
2017
2145
  (e) => {
2018
2146
  if (e.key === "Escape") {
2019
2147
  ctx.close();
2148
+ } else if (e.key === "Enter" && ctx.isOpen) {
2149
+ e.preventDefault();
2020
2150
  } else if (e.key === "ArrowDown" && !ctx.isOpen) {
2021
2151
  e.preventDefault();
2022
2152
  ctx.open();
@@ -2052,6 +2182,7 @@ var DateTimePickerInput = react.forwardRef(
2052
2182
  );
2053
2183
  }
2054
2184
  );
2185
+ DateTimePickerInput.displayName = "DateTimePicker.Input";
2055
2186
 
2056
2187
  // src/components/DateTimePicker/index.ts
2057
2188
  var DateTimePicker = Object.assign(DateTimePickerRoot, {
@@ -2068,10 +2199,7 @@ function MonthPickerRoot(props) {
2068
2199
  const displayFormat = props.displayFormat ?? "yyyy-MM";
2069
2200
  return /* @__PURE__ */ jsxRuntime.jsx(DatePickerRoot, { ...props, displayFormat });
2070
2201
  }
2071
- function MonthPickerGrid({
2072
- classNames,
2073
- ...props
2074
- }) {
2202
+ function MonthPickerGrid({ classNames, ...props }) {
2075
2203
  const ctx = useDatePickerContext("MonthPicker.Grid");
2076
2204
  const { adapter, viewMonth, locale, value, displayTimezone, labels } = ctx;
2077
2205
  const currentYear = adapter.getYear(viewMonth);
@@ -2095,9 +2223,7 @@ function MonthPickerGrid({
2095
2223
  );
2096
2224
  const handleMonthSelect = react.useCallback(
2097
2225
  (monthIndex) => {
2098
- const target = new Date(
2099
- Date.UTC(currentYear, monthIndex, 1)
2100
- ).toISOString();
2226
+ const target = new Date(Date.UTC(currentYear, monthIndex, 1)).toISOString();
2101
2227
  ctx.selectDate(target);
2102
2228
  },
2103
2229
  [currentYear, ctx]
@@ -2132,45 +2258,37 @@ function MonthPickerGrid({
2132
2258
  }
2133
2259
  )
2134
2260
  ] }),
2135
- /* @__PURE__ */ jsxRuntime.jsx(
2261
+ /* @__PURE__ */ jsxRuntime.jsx("div", { role: "grid", "aria-label": `${currentYear} months`, className: classNames?.grid, children: Array.from({ length: 4 }, (_, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(
2136
2262
  "div",
2137
2263
  {
2138
- role: "grid",
2139
- "aria-label": `${currentYear} months`,
2140
- className: classNames?.grid,
2141
- children: Array.from({ length: 4 }, (_, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(
2142
- "div",
2143
- {
2144
- role: "row",
2145
- className: classNames?.gridRow,
2146
- style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)" },
2147
- children: months.slice(rowIndex * 3, rowIndex * 3 + 3).map((m) => {
2148
- const monthClass = [
2149
- classNames?.month,
2150
- m.isSelected && classNames?.monthSelected,
2151
- m.isCurrent && classNames?.monthCurrent
2152
- ].filter(Boolean).join(" ") || void 0;
2153
- return /* @__PURE__ */ jsxRuntime.jsx(
2154
- "button",
2155
- {
2156
- type: "button",
2157
- role: "gridcell",
2158
- "aria-selected": m.isSelected || void 0,
2159
- "aria-current": m.isCurrent ? "date" : void 0,
2160
- "data-selected": m.isSelected || void 0,
2161
- "data-current": m.isCurrent || void 0,
2162
- className: monthClass,
2163
- onClick: () => handleMonthSelect(m.index),
2164
- children: m.name
2165
- },
2166
- m.index
2167
- );
2168
- })
2169
- },
2170
- rowIndex
2171
- ))
2172
- }
2173
- )
2264
+ role: "row",
2265
+ className: classNames?.gridRow,
2266
+ style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)" },
2267
+ children: months.slice(rowIndex * 3, rowIndex * 3 + 3).map((m) => {
2268
+ const monthClass = [
2269
+ classNames?.month,
2270
+ m.isSelected && classNames?.monthSelected,
2271
+ m.isCurrent && classNames?.monthCurrent
2272
+ ].filter(Boolean).join(" ") || void 0;
2273
+ return /* @__PURE__ */ jsxRuntime.jsx(
2274
+ "button",
2275
+ {
2276
+ type: "button",
2277
+ role: "gridcell",
2278
+ "aria-selected": m.isSelected || void 0,
2279
+ "aria-current": m.isCurrent ? "date" : void 0,
2280
+ "data-selected": m.isSelected || void 0,
2281
+ "data-current": m.isCurrent || void 0,
2282
+ className: monthClass,
2283
+ onClick: () => handleMonthSelect(m.index),
2284
+ children: m.name
2285
+ },
2286
+ m.index
2287
+ );
2288
+ })
2289
+ },
2290
+ rowIndex
2291
+ )) })
2174
2292
  ] });
2175
2293
  }
2176
2294
 
@@ -2245,45 +2363,37 @@ function YearPickerGrid({ classNames, ...props }) {
2245
2363
  }
2246
2364
  )
2247
2365
  ] }),
2248
- /* @__PURE__ */ jsxRuntime.jsx(
2366
+ /* @__PURE__ */ jsxRuntime.jsx("div", { role: "grid", "aria-label": rangeLabel, className: classNames?.grid, children: Array.from({ length: 4 }, (_, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(
2249
2367
  "div",
2250
2368
  {
2251
- role: "grid",
2252
- "aria-label": rangeLabel,
2253
- className: classNames?.grid,
2254
- children: Array.from({ length: 4 }, (_, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(
2255
- "div",
2256
- {
2257
- role: "row",
2258
- className: classNames?.gridRow,
2259
- style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)" },
2260
- children: years.slice(rowIndex * 3, rowIndex * 3 + 3).map((y) => {
2261
- const yearClass = [
2262
- classNames?.year,
2263
- y.isSelected && classNames?.yearSelected,
2264
- y.isCurrent && classNames?.yearCurrent
2265
- ].filter(Boolean).join(" ") || void 0;
2266
- return /* @__PURE__ */ jsxRuntime.jsx(
2267
- "button",
2268
- {
2269
- type: "button",
2270
- role: "gridcell",
2271
- "aria-selected": y.isSelected || void 0,
2272
- "aria-current": y.isCurrent ? "date" : void 0,
2273
- "data-selected": y.isSelected || void 0,
2274
- "data-current": y.isCurrent || void 0,
2275
- className: yearClass,
2276
- onClick: () => handleYearSelect(y.value),
2277
- children: y.value
2278
- },
2279
- y.value
2280
- );
2281
- })
2282
- },
2283
- rowIndex
2284
- ))
2285
- }
2286
- )
2369
+ role: "row",
2370
+ className: classNames?.gridRow,
2371
+ style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)" },
2372
+ children: years.slice(rowIndex * 3, rowIndex * 3 + 3).map((y) => {
2373
+ const yearClass = [
2374
+ classNames?.year,
2375
+ y.isSelected && classNames?.yearSelected,
2376
+ y.isCurrent && classNames?.yearCurrent
2377
+ ].filter(Boolean).join(" ") || void 0;
2378
+ return /* @__PURE__ */ jsxRuntime.jsx(
2379
+ "button",
2380
+ {
2381
+ type: "button",
2382
+ role: "gridcell",
2383
+ "aria-selected": y.isSelected || void 0,
2384
+ "aria-current": y.isCurrent ? "date" : void 0,
2385
+ "data-selected": y.isSelected || void 0,
2386
+ "data-current": y.isCurrent || void 0,
2387
+ className: yearClass,
2388
+ onClick: () => handleYearSelect(y.value),
2389
+ children: y.value
2390
+ },
2391
+ y.value
2392
+ );
2393
+ })
2394
+ },
2395
+ rowIndex
2396
+ )) })
2287
2397
  ] });
2288
2398
  }
2289
2399
 
@@ -2546,14 +2656,8 @@ function useTimePicker(options = {}) {
2546
2656
  },
2547
2657
  [format, period, setTime]
2548
2658
  );
2549
- const setMinute = react.useCallback(
2550
- (minute) => setTime({ minutes: minute }),
2551
- [setTime]
2552
- );
2553
- const setSecond = react.useCallback(
2554
- (second) => setTime({ seconds: second }),
2555
- [setTime]
2556
- );
2659
+ const setMinute = react.useCallback((minute) => setTime({ minutes: minute }), [setTime]);
2660
+ const setSecond = react.useCallback((second) => setTime({ seconds: second }), [setTime]);
2557
2661
  const setPeriod = react.useCallback(
2558
2662
  (newPeriod) => {
2559
2663
  if (format !== "12h") return;