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