@ceed/cds 1.30.0 → 1.31.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/dist/index.cjs CHANGED
@@ -1028,8 +1028,12 @@ var useCalendarProps = (inProps) => {
1028
1028
  // src/components/Calendar/hooks/use-calendar.ts
1029
1029
  var import_react13 = require("react");
1030
1030
  var useCalendar = (ownerState) => {
1031
- const [hoverDay, setHoverDay] = (0, import_react13.useState)(null);
1032
- const [hoverMonth, setHoverMonth] = (0, import_react13.useState)(null);
1031
+ const [localHoverDay, setLocalHoverDay] = (0, import_react13.useState)(null);
1032
+ const [localHoverMonth, setLocalHoverMonth] = (0, import_react13.useState)(null);
1033
+ const hoverDay = ownerState.hoverDay !== void 0 ? ownerState.hoverDay : localHoverDay;
1034
+ const setHoverDay = ownerState.onHoverDayChange ?? setLocalHoverDay;
1035
+ const hoverMonth = ownerState.hoverMonth !== void 0 ? ownerState.hoverMonth : localHoverMonth;
1036
+ const setHoverMonth = ownerState.onHoverMonthChange ?? setLocalHoverMonth;
1033
1037
  return {
1034
1038
  calendarTitle: ownerState.view === "month" ? getYearName(ownerState.viewMonth, ownerState.locale || "default") : getMonthName(ownerState.viewMonth, ownerState.locale || "default"),
1035
1039
  onPrev: (0, import_react13.useCallback)(() => {
@@ -1228,11 +1232,18 @@ var MONTH_NAV_CLICK_THRESHOLD = 3;
1228
1232
  var MONTH_VIEW_HINT_DURATION_MS = 5e3;
1229
1233
  var MONTH_VIEW_HINT_COOLDOWN_MS = 3e4;
1230
1234
  var lastMonthViewAssistHintShownAt = 0;
1235
+ var CALENDAR_PANEL_WIDTH = 264;
1236
+ var CALENDAR_PANEL_GAP = 16;
1231
1237
  var CalendarRoot = (0, import_joy19.styled)("div", {
1232
1238
  name: "Calendar",
1233
1239
  slot: "root"
1240
+ })({});
1241
+ var CalendarMultiContainer = (0, import_joy19.styled)("div", {
1242
+ name: "Calendar",
1243
+ slot: "multiContainer"
1234
1244
  })({
1235
- maxWidth: "264px"
1245
+ display: "flex",
1246
+ gap: `${CALENDAR_PANEL_GAP}px`
1236
1247
  });
1237
1248
  var CalendarHeader = (0, import_joy19.styled)("div", {
1238
1249
  name: "Calendar",
@@ -1267,6 +1278,16 @@ var CalendarViewTable = (0, import_joy19.styled)(import_framer_motion13.motion.t
1267
1278
  paddingBottom: theme.spacing(2)
1268
1279
  }
1269
1280
  }));
1281
+ var StaticCalendarViewTable = (0, import_joy19.styled)("table")(({ theme }) => ({
1282
+ borderSpacing: 0,
1283
+ "& td, & th": {
1284
+ padding: 0
1285
+ },
1286
+ "& th": {
1287
+ paddingTop: theme.spacing(2),
1288
+ paddingBottom: theme.spacing(2)
1289
+ }
1290
+ }));
1270
1291
  var CalendarWeekHeaderContainer = (0, import_joy19.styled)("thead", {
1271
1292
  name: "Calendar",
1272
1293
  slot: "weekHeaderContainer"
@@ -1515,6 +1536,133 @@ var PickerMonths = (props) => {
1515
1536
  /* @__PURE__ */ import_react14.default.createElement("tbody", null, chunkedMonths.map((months, i) => /* @__PURE__ */ import_react14.default.createElement(import_react14.Fragment, { key: months.join("_") }, /* @__PURE__ */ import_react14.default.createElement("tr", null, months.map((monthIndex, j) => /* @__PURE__ */ import_react14.default.createElement(import_react14.Fragment, { key: monthIndex }, /* @__PURE__ */ import_react14.default.createElement(CalendarMonthCell, { ...getMonthCellProps(monthIndex) }, /* @__PURE__ */ import_react14.default.createElement(CalendarMonth, { size: "sm", variant: "plain", color: "neutral", ...getPickerMonthProps(monthIndex) }, getMonthNameFromIndex(monthIndex, ownerState.locale))), j < 3 && /* @__PURE__ */ import_react14.default.createElement("td", { style: { width: 4 }, "aria-hidden": "true", "aria-description": "cell-gap" })))), i < chunkedMonths.length - 1 && /* @__PURE__ */ import_react14.default.createElement("tr", { "aria-hidden": "true", "aria-description": "row-gap" }, /* @__PURE__ */ import_react14.default.createElement("td", { colSpan: 7, style: { height: 4 } })))))
1516
1537
  )));
1517
1538
  };
1539
+ var PlainPickerDays = ({ ownerState }) => {
1540
+ const { getPickerDayProps, getDayCellProps } = useCalendar(ownerState);
1541
+ const calendarDates = (0, import_react14.useMemo)(() => getCalendarDates(ownerState.viewMonth), [ownerState.viewMonth]);
1542
+ const weekdayNames = (0, import_react14.useMemo)(() => getWeekdayNames(ownerState.locale || "default"), [ownerState.locale]);
1543
+ return /* @__PURE__ */ import_react14.default.createElement(StaticCalendarViewTable, null, /* @__PURE__ */ import_react14.default.createElement(CalendarWeekHeaderContainer, null, /* @__PURE__ */ import_react14.default.createElement("tr", null, weekdayNames.map((name, i) => /* @__PURE__ */ import_react14.default.createElement(import_react14.Fragment, { key: `${ownerState.viewMonth}_${name}_${i}` }, /* @__PURE__ */ import_react14.default.createElement("th", null, /* @__PURE__ */ import_react14.default.createElement(Typography_default, { level: "body-xs", textAlign: "center" }, name)), i < 6 && /* @__PURE__ */ import_react14.default.createElement("th", { style: { width: 4 }, "aria-hidden": "true", "aria-description": "cell-gap" }))))), /* @__PURE__ */ import_react14.default.createElement(CalendarDayPickerContainer, null, calendarDates.map((weekDates, rowIndex) => /* @__PURE__ */ import_react14.default.createElement(import_react14.Fragment, { key: `${ownerState.viewMonth}_${rowIndex}` }, /* @__PURE__ */ import_react14.default.createElement("tr", null, weekDates.map(
1544
+ (date, i) => date ? /* @__PURE__ */ import_react14.default.createElement(import_react14.Fragment, { key: `${ownerState.viewMonth}_${date}_${i}` }, /* @__PURE__ */ import_react14.default.createElement(CalendarDayCell, { ...getDayCellProps(date) }, /* @__PURE__ */ import_react14.default.createElement(CalendarDay, { size: "sm", variant: "plain", color: "neutral", ...getPickerDayProps(date) }, date)), i < 6 && /* @__PURE__ */ import_react14.default.createElement("td", { "aria-hidden": "true", "aria-description": "cell-gap" })) : /* @__PURE__ */ import_react14.default.createElement(import_react14.Fragment, { key: `${ownerState.viewMonth}_${i}` }, /* @__PURE__ */ import_react14.default.createElement("td", null), i < 6 && /* @__PURE__ */ import_react14.default.createElement("td", { "aria-hidden": "true", "aria-description": "cell-gap" }))
1545
+ )), rowIndex < calendarDates.length - 1 && /* @__PURE__ */ import_react14.default.createElement("tr", { "aria-hidden": "true", "aria-description": "row-gap" }, /* @__PURE__ */ import_react14.default.createElement("td", { colSpan: 13, style: { height: 4 } }))))));
1546
+ };
1547
+ var MultiMonthPickerDays = ({
1548
+ panels,
1549
+ direction,
1550
+ numberOfMonths
1551
+ }) => {
1552
+ const slideDistance = CALENDAR_PANEL_WIDTH * numberOfMonths + CALENDAR_PANEL_GAP * (numberOfMonths - 1) + CALENDAR_PANEL_WIDTH;
1553
+ const multiVariants = {
1554
+ enter: (dir) => ({ x: dir > 0 ? slideDistance : -slideDistance, opacity: 0 }),
1555
+ center: { position: "relative", zIndex: 1, x: 0, opacity: 1 },
1556
+ exit: (dir) => ({
1557
+ position: "absolute",
1558
+ zIndex: 0,
1559
+ x: dir < 0 ? slideDistance : -slideDistance,
1560
+ opacity: 0
1561
+ })
1562
+ };
1563
+ const key = `${panels[0].viewMonth.toISOString()}_${direction}`;
1564
+ return /* @__PURE__ */ import_react14.default.createElement("div", { style: { position: "relative", overflow: "hidden", minHeight: "250px" } }, /* @__PURE__ */ import_react14.default.createElement(import_framer_motion13.AnimatePresence, { initial: false, custom: direction }, /* @__PURE__ */ import_react14.default.createElement(
1565
+ import_framer_motion13.motion.div,
1566
+ {
1567
+ key,
1568
+ custom: direction,
1569
+ variants: multiVariants,
1570
+ initial: "enter",
1571
+ animate: "center",
1572
+ exit: "exit",
1573
+ transition: {
1574
+ x: { type: "spring", stiffness: 300, damping: 30 },
1575
+ opacity: { duration: 0.2 }
1576
+ },
1577
+ drag: "x",
1578
+ dragConstraints: { left: 0, right: 0 },
1579
+ dragElastic: 1,
1580
+ onDragEnd: (e, { offset, velocity }) => {
1581
+ const swipe = swipePower(offset.x, velocity.x);
1582
+ if (swipe < -swipeConfidenceThreshold) {
1583
+ const date = new Date(panels[0].viewMonth);
1584
+ date.setMonth(date.getMonth() + 1);
1585
+ panels[0].onMonthChange?.(date);
1586
+ } else if (swipe > swipeConfidenceThreshold) {
1587
+ const date = new Date(panels[0].viewMonth);
1588
+ date.setMonth(date.getMonth() - 1);
1589
+ panels[0].onMonthChange?.(date);
1590
+ }
1591
+ },
1592
+ style: { display: "flex", gap: `${CALENDAR_PANEL_GAP}px`, top: 0, left: 0, width: "100%" }
1593
+ },
1594
+ panels.map((panelOwnerState) => /* @__PURE__ */ import_react14.default.createElement(
1595
+ "div",
1596
+ {
1597
+ key: panelOwnerState.viewMonth.toISOString(),
1598
+ style: {
1599
+ flex: "0 0 auto",
1600
+ width: `${CALENDAR_PANEL_WIDTH}px`,
1601
+ paddingLeft: "16px",
1602
+ paddingRight: "16px",
1603
+ boxSizing: "border-box"
1604
+ }
1605
+ },
1606
+ /* @__PURE__ */ import_react14.default.createElement(PlainPickerDays, { ownerState: panelOwnerState })
1607
+ ))
1608
+ )));
1609
+ };
1610
+ var CalendarPanel = ({
1611
+ ownerState,
1612
+ panelIndex,
1613
+ totalPanels,
1614
+ onPrev,
1615
+ onNext,
1616
+ onSwitchView,
1617
+ isMonthViewAssistHintOpen,
1618
+ monthViewHintMessage
1619
+ }) => {
1620
+ const showPrev = panelIndex === 0;
1621
+ const showNext = panelIndex === totalPanels - 1;
1622
+ const title = ownerState.view === "month" ? getYearName(ownerState.viewMonth, ownerState.locale || "default") : getMonthName(ownerState.viewMonth, ownerState.locale || "default");
1623
+ return /* @__PURE__ */ import_react14.default.createElement("div", { style: { flex: 1, maxWidth: `${CALENDAR_PANEL_WIDTH}px` } }, /* @__PURE__ */ import_react14.default.createElement(CalendarHeader, null, /* @__PURE__ */ import_react14.default.createElement(
1624
+ IconButton_default,
1625
+ {
1626
+ size: "sm",
1627
+ onClick: onPrev,
1628
+ "aria-label": `Previous ${ownerState.view === "day" ? "Month" : "Year"}`,
1629
+ style: { visibility: showPrev ? "visible" : "hidden" }
1630
+ },
1631
+ /* @__PURE__ */ import_react14.default.createElement(import_ChevronLeft.default, null)
1632
+ ), /* @__PURE__ */ import_react14.default.createElement(
1633
+ Tooltip_default,
1634
+ {
1635
+ title: monthViewHintMessage,
1636
+ arrow: true,
1637
+ open: panelIndex === 0 && isMonthViewAssistHintOpen,
1638
+ placement: "bottom",
1639
+ disableFocusListener: true,
1640
+ disableHoverListener: true,
1641
+ disableTouchListener: true,
1642
+ variant: "solid"
1643
+ },
1644
+ /* @__PURE__ */ import_react14.default.createElement(
1645
+ CalendarSwitchViewButton,
1646
+ {
1647
+ ownerState,
1648
+ variant: "plain",
1649
+ color: "neutral",
1650
+ onClick: onSwitchView,
1651
+ "aria-label": "Switch Calendar View"
1652
+ },
1653
+ title
1654
+ )
1655
+ ), /* @__PURE__ */ import_react14.default.createElement(
1656
+ IconButton_default,
1657
+ {
1658
+ size: "sm",
1659
+ onClick: onNext,
1660
+ "aria-label": `Next ${ownerState.view === "day" ? "Month" : "Year"}`,
1661
+ style: { visibility: showNext ? "visible" : "hidden" }
1662
+ },
1663
+ /* @__PURE__ */ import_react14.default.createElement(import_ChevronRight.default, null)
1664
+ )));
1665
+ };
1518
1666
  var Calendar = (0, import_react14.forwardRef)((inProps, ref) => {
1519
1667
  const [props, ownerState] = useCalendarProps(inProps);
1520
1668
  const {
@@ -1531,6 +1679,7 @@ var Calendar = (0, import_react14.forwardRef)((inProps, ref) => {
1531
1679
  maxDate,
1532
1680
  disableFuture,
1533
1681
  disablePast,
1682
+ numberOfMonths,
1534
1683
  ...others
1535
1684
  } = props;
1536
1685
  const { calendarTitle, onPrev, onNext } = useCalendar(ownerState);
@@ -1538,6 +1687,9 @@ var Calendar = (0, import_react14.forwardRef)((inProps, ref) => {
1538
1687
  const monthNavClickTimestampsRef = (0, import_react14.useRef)([]);
1539
1688
  const monthViewAssistHintShownInSessionRef = (0, import_react14.useRef)(false);
1540
1689
  const monthViewAssistHintTimeoutRef = (0, import_react14.useRef)(null);
1690
+ const [hoverDay, setHoverDay] = (0, import_react14.useState)(null);
1691
+ const [hoverMonth, setHoverMonth] = (0, import_react14.useState)(null);
1692
+ const resolvedNumberOfMonths = numberOfMonths ?? 1;
1541
1693
  const hasEndDate = Boolean(value?.[1]);
1542
1694
  const isRangeHintEligible = Boolean(rangeSelection && !hasEndDate);
1543
1695
  const isHintEligible = Boolean(view === "day" && (!rangeSelection || isRangeHintEligible));
@@ -1600,7 +1752,71 @@ var Calendar = (0, import_react14.forwardRef)((inProps, ref) => {
1600
1752
  closeMonthViewAssistHint();
1601
1753
  onViewChange?.();
1602
1754
  }, [closeMonthViewAssistHint, onViewChange]);
1603
- return /* @__PURE__ */ import_react14.default.createElement(CalendarRoot, { ref, ...others }, /* @__PURE__ */ import_react14.default.createElement(CalendarHeader, null, /* @__PURE__ */ import_react14.default.createElement(IconButton_default, { size: "sm", onClick: handlePrevClick, "aria-label": `Previous ${view === "day" ? "Month" : "Year"}` }, /* @__PURE__ */ import_react14.default.createElement(import_ChevronLeft.default, null)), /* @__PURE__ */ import_react14.default.createElement(
1755
+ const maxWidth = CALENDAR_PANEL_WIDTH * resolvedNumberOfMonths + CALENDAR_PANEL_GAP * (resolvedNumberOfMonths - 1);
1756
+ if (resolvedNumberOfMonths > 1) {
1757
+ const panels = Array.from({ length: resolvedNumberOfMonths }, (_, i) => {
1758
+ const panelViewMonth = new Date(ownerState.viewMonth);
1759
+ panelViewMonth.setMonth(panelViewMonth.getMonth() + i);
1760
+ panelViewMonth.setDate(1);
1761
+ panelViewMonth.setHours(0, 0, 0, 0);
1762
+ return {
1763
+ ...ownerState,
1764
+ viewMonth: panelViewMonth,
1765
+ hoverDay,
1766
+ onHoverDayChange: setHoverDay,
1767
+ hoverMonth,
1768
+ onHoverMonthChange: setHoverMonth
1769
+ };
1770
+ });
1771
+ return /* @__PURE__ */ import_react14.default.createElement(CalendarRoot, { ref, ...others, style: { maxWidth: `${maxWidth}px` } }, view === "month" ? (
1772
+ // Month view: single header + single month grid (consistent with single-month path)
1773
+ /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null, /* @__PURE__ */ import_react14.default.createElement(CalendarHeader, null, /* @__PURE__ */ import_react14.default.createElement(IconButton_default, { size: "sm", onClick: handlePrevClick, "aria-label": "Previous Year" }, /* @__PURE__ */ import_react14.default.createElement(import_ChevronLeft.default, null)), /* @__PURE__ */ import_react14.default.createElement(
1774
+ Tooltip_default,
1775
+ {
1776
+ title: monthViewHintMessage,
1777
+ arrow: true,
1778
+ open: false,
1779
+ placement: "bottom",
1780
+ disableFocusListener: true,
1781
+ disableHoverListener: true,
1782
+ disableTouchListener: true,
1783
+ variant: "solid"
1784
+ },
1785
+ /* @__PURE__ */ import_react14.default.createElement(
1786
+ CalendarSwitchViewButton,
1787
+ {
1788
+ ownerState,
1789
+ variant: "plain",
1790
+ color: "neutral",
1791
+ onClick: handleSwitchViewClick,
1792
+ "aria-label": "Switch Calendar View"
1793
+ },
1794
+ calendarTitle
1795
+ )
1796
+ ), /* @__PURE__ */ import_react14.default.createElement(IconButton_default, { size: "sm", onClick: handleNextClick, "aria-label": "Next Year" }, /* @__PURE__ */ import_react14.default.createElement(import_ChevronRight.default, null))), /* @__PURE__ */ import_react14.default.createElement(PickerMonths, { ownerState }))
1797
+ ) : /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null, /* @__PURE__ */ import_react14.default.createElement(CalendarMultiContainer, null, panels.map((panelOwnerState, i) => /* @__PURE__ */ import_react14.default.createElement(
1798
+ CalendarPanel,
1799
+ {
1800
+ key: panelOwnerState.viewMonth.toISOString(),
1801
+ ownerState: panelOwnerState,
1802
+ panelIndex: i,
1803
+ totalPanels: resolvedNumberOfMonths,
1804
+ onPrev: handlePrevClick,
1805
+ onNext: handleNextClick,
1806
+ onSwitchView: handleSwitchViewClick,
1807
+ isMonthViewAssistHintOpen,
1808
+ monthViewHintMessage
1809
+ }
1810
+ ))), /* @__PURE__ */ import_react14.default.createElement(
1811
+ MultiMonthPickerDays,
1812
+ {
1813
+ panels,
1814
+ direction: ownerState.direction,
1815
+ numberOfMonths: resolvedNumberOfMonths
1816
+ }
1817
+ )));
1818
+ }
1819
+ return /* @__PURE__ */ import_react14.default.createElement(CalendarRoot, { ref, ...others, style: { maxWidth: `${maxWidth}px` } }, /* @__PURE__ */ import_react14.default.createElement(CalendarHeader, null, /* @__PURE__ */ import_react14.default.createElement(IconButton_default, { size: "sm", onClick: handlePrevClick, "aria-label": `Previous ${view === "day" ? "Month" : "Year"}` }, /* @__PURE__ */ import_react14.default.createElement(import_ChevronLeft.default, null)), /* @__PURE__ */ import_react14.default.createElement(
1604
1820
  Tooltip_default,
1605
1821
  {
1606
1822
  title: monthViewHintMessage,
@@ -2918,7 +3134,8 @@ var DatePicker = (0, import_react20.forwardRef)((inProps, ref) => {
2918
3134
  maxDate: maxDate ? new Date(maxDate) : void 0,
2919
3135
  disableFuture,
2920
3136
  disablePast,
2921
- shouldDisableDate: shouldDisableDate ? (date) => shouldDisableDate(formatValueString(date, format)) : void 0
3137
+ shouldDisableDate: shouldDisableDate ? (date) => shouldDisableDate(formatValueString(date, format)) : void 0,
3138
+ locale
2922
3139
  }
2923
3140
  ), !hideClearButton && /* @__PURE__ */ import_react20.default.createElement(
2924
3141
  DialogActions_default,
@@ -4966,6 +5183,7 @@ var DateRangePicker = (0, import_react29.forwardRef)((inProps, ref) => {
4966
5183
  hideClearButton,
4967
5184
  readOnly,
4968
5185
  presets,
5186
+ numberOfMonths,
4969
5187
  ...innerProps
4970
5188
  } = props;
4971
5189
  const innerRef = (0, import_react29.useRef)(null);
@@ -5162,7 +5380,7 @@ var DateRangePicker = (0, import_react29.forwardRef)((inProps, ref) => {
5162
5380
  "aria-label": "Calendar Tooltip",
5163
5381
  "aria-expanded": open
5164
5382
  },
5165
- /* @__PURE__ */ import_react29.default.createElement(CalendarSheet2, { tabIndex: -1, role: "presentation" }, /* @__PURE__ */ import_react29.default.createElement(CalendarSheetContent2, null, /* @__PURE__ */ import_react29.default.createElement(CalendarSection2, null, /* @__PURE__ */ import_react29.default.createElement(
5383
+ /* @__PURE__ */ import_react29.default.createElement(CalendarSheet2, { tabIndex: -1, role: "presentation" }, /* @__PURE__ */ import_react29.default.createElement(CalendarSheetContent2, null, /* @__PURE__ */ import_react29.default.createElement(CalendarSection2, { style: { width: "auto" } }, /* @__PURE__ */ import_react29.default.createElement(
5166
5384
  Calendar_default,
5167
5385
  {
5168
5386
  rangeSelection: true,
@@ -5171,7 +5389,9 @@ var DateRangePicker = (0, import_react29.forwardRef)((inProps, ref) => {
5171
5389
  minDate: minDate ? new Date(minDate) : void 0,
5172
5390
  maxDate: maxDate ? new Date(maxDate) : void 0,
5173
5391
  disableFuture,
5174
- disablePast
5392
+ disablePast,
5393
+ locale,
5394
+ numberOfMonths
5175
5395
  }
5176
5396
  ), !hideClearButton && /* @__PURE__ */ import_react29.default.createElement(
5177
5397
  DialogActions_default,
@@ -6297,7 +6517,8 @@ var MonthRangePicker = (0, import_react39.forwardRef)((inProps, ref) => {
6297
6517
  minDate: minDate ? new Date(minDate) : void 0,
6298
6518
  maxDate: maxDate ? new Date(maxDate) : void 0,
6299
6519
  disableFuture,
6300
- disablePast
6520
+ disablePast,
6521
+ locale
6301
6522
  }
6302
6523
  ), /* @__PURE__ */ import_react39.default.createElement(
6303
6524
  DialogActions_default,
package/dist/index.js CHANGED
@@ -888,8 +888,12 @@ var useCalendarProps = (inProps) => {
888
888
  // src/components/Calendar/hooks/use-calendar.ts
889
889
  import { useCallback as useCallback4, useState as useState3 } from "react";
890
890
  var useCalendar = (ownerState) => {
891
- const [hoverDay, setHoverDay] = useState3(null);
892
- const [hoverMonth, setHoverMonth] = useState3(null);
891
+ const [localHoverDay, setLocalHoverDay] = useState3(null);
892
+ const [localHoverMonth, setLocalHoverMonth] = useState3(null);
893
+ const hoverDay = ownerState.hoverDay !== void 0 ? ownerState.hoverDay : localHoverDay;
894
+ const setHoverDay = ownerState.onHoverDayChange ?? setLocalHoverDay;
895
+ const hoverMonth = ownerState.hoverMonth !== void 0 ? ownerState.hoverMonth : localHoverMonth;
896
+ const setHoverMonth = ownerState.onHoverMonthChange ?? setLocalHoverMonth;
893
897
  return {
894
898
  calendarTitle: ownerState.view === "month" ? getYearName(ownerState.viewMonth, ownerState.locale || "default") : getMonthName(ownerState.viewMonth, ownerState.locale || "default"),
895
899
  onPrev: useCallback4(() => {
@@ -1088,11 +1092,18 @@ var MONTH_NAV_CLICK_THRESHOLD = 3;
1088
1092
  var MONTH_VIEW_HINT_DURATION_MS = 5e3;
1089
1093
  var MONTH_VIEW_HINT_COOLDOWN_MS = 3e4;
1090
1094
  var lastMonthViewAssistHintShownAt = 0;
1095
+ var CALENDAR_PANEL_WIDTH = 264;
1096
+ var CALENDAR_PANEL_GAP = 16;
1091
1097
  var CalendarRoot = styled5("div", {
1092
1098
  name: "Calendar",
1093
1099
  slot: "root"
1100
+ })({});
1101
+ var CalendarMultiContainer = styled5("div", {
1102
+ name: "Calendar",
1103
+ slot: "multiContainer"
1094
1104
  })({
1095
- maxWidth: "264px"
1105
+ display: "flex",
1106
+ gap: `${CALENDAR_PANEL_GAP}px`
1096
1107
  });
1097
1108
  var CalendarHeader = styled5("div", {
1098
1109
  name: "Calendar",
@@ -1127,6 +1138,16 @@ var CalendarViewTable = styled5(motion13.table, {
1127
1138
  paddingBottom: theme.spacing(2)
1128
1139
  }
1129
1140
  }));
1141
+ var StaticCalendarViewTable = styled5("table")(({ theme }) => ({
1142
+ borderSpacing: 0,
1143
+ "& td, & th": {
1144
+ padding: 0
1145
+ },
1146
+ "& th": {
1147
+ paddingTop: theme.spacing(2),
1148
+ paddingBottom: theme.spacing(2)
1149
+ }
1150
+ }));
1130
1151
  var CalendarWeekHeaderContainer = styled5("thead", {
1131
1152
  name: "Calendar",
1132
1153
  slot: "weekHeaderContainer"
@@ -1375,6 +1396,133 @@ var PickerMonths = (props) => {
1375
1396
  /* @__PURE__ */ React12.createElement("tbody", null, chunkedMonths.map((months, i) => /* @__PURE__ */ React12.createElement(Fragment, { key: months.join("_") }, /* @__PURE__ */ React12.createElement("tr", null, months.map((monthIndex, j) => /* @__PURE__ */ React12.createElement(Fragment, { key: monthIndex }, /* @__PURE__ */ React12.createElement(CalendarMonthCell, { ...getMonthCellProps(monthIndex) }, /* @__PURE__ */ React12.createElement(CalendarMonth, { size: "sm", variant: "plain", color: "neutral", ...getPickerMonthProps(monthIndex) }, getMonthNameFromIndex(monthIndex, ownerState.locale))), j < 3 && /* @__PURE__ */ React12.createElement("td", { style: { width: 4 }, "aria-hidden": "true", "aria-description": "cell-gap" })))), i < chunkedMonths.length - 1 && /* @__PURE__ */ React12.createElement("tr", { "aria-hidden": "true", "aria-description": "row-gap" }, /* @__PURE__ */ React12.createElement("td", { colSpan: 7, style: { height: 4 } })))))
1376
1397
  )));
1377
1398
  };
1399
+ var PlainPickerDays = ({ ownerState }) => {
1400
+ const { getPickerDayProps, getDayCellProps } = useCalendar(ownerState);
1401
+ const calendarDates = useMemo4(() => getCalendarDates(ownerState.viewMonth), [ownerState.viewMonth]);
1402
+ const weekdayNames = useMemo4(() => getWeekdayNames(ownerState.locale || "default"), [ownerState.locale]);
1403
+ return /* @__PURE__ */ React12.createElement(StaticCalendarViewTable, null, /* @__PURE__ */ React12.createElement(CalendarWeekHeaderContainer, null, /* @__PURE__ */ React12.createElement("tr", null, weekdayNames.map((name, i) => /* @__PURE__ */ React12.createElement(Fragment, { key: `${ownerState.viewMonth}_${name}_${i}` }, /* @__PURE__ */ React12.createElement("th", null, /* @__PURE__ */ React12.createElement(Typography_default, { level: "body-xs", textAlign: "center" }, name)), i < 6 && /* @__PURE__ */ React12.createElement("th", { style: { width: 4 }, "aria-hidden": "true", "aria-description": "cell-gap" }))))), /* @__PURE__ */ React12.createElement(CalendarDayPickerContainer, null, calendarDates.map((weekDates, rowIndex) => /* @__PURE__ */ React12.createElement(Fragment, { key: `${ownerState.viewMonth}_${rowIndex}` }, /* @__PURE__ */ React12.createElement("tr", null, weekDates.map(
1404
+ (date, i) => date ? /* @__PURE__ */ React12.createElement(Fragment, { key: `${ownerState.viewMonth}_${date}_${i}` }, /* @__PURE__ */ React12.createElement(CalendarDayCell, { ...getDayCellProps(date) }, /* @__PURE__ */ React12.createElement(CalendarDay, { size: "sm", variant: "plain", color: "neutral", ...getPickerDayProps(date) }, date)), i < 6 && /* @__PURE__ */ React12.createElement("td", { "aria-hidden": "true", "aria-description": "cell-gap" })) : /* @__PURE__ */ React12.createElement(Fragment, { key: `${ownerState.viewMonth}_${i}` }, /* @__PURE__ */ React12.createElement("td", null), i < 6 && /* @__PURE__ */ React12.createElement("td", { "aria-hidden": "true", "aria-description": "cell-gap" }))
1405
+ )), rowIndex < calendarDates.length - 1 && /* @__PURE__ */ React12.createElement("tr", { "aria-hidden": "true", "aria-description": "row-gap" }, /* @__PURE__ */ React12.createElement("td", { colSpan: 13, style: { height: 4 } }))))));
1406
+ };
1407
+ var MultiMonthPickerDays = ({
1408
+ panels,
1409
+ direction,
1410
+ numberOfMonths
1411
+ }) => {
1412
+ const slideDistance = CALENDAR_PANEL_WIDTH * numberOfMonths + CALENDAR_PANEL_GAP * (numberOfMonths - 1) + CALENDAR_PANEL_WIDTH;
1413
+ const multiVariants = {
1414
+ enter: (dir) => ({ x: dir > 0 ? slideDistance : -slideDistance, opacity: 0 }),
1415
+ center: { position: "relative", zIndex: 1, x: 0, opacity: 1 },
1416
+ exit: (dir) => ({
1417
+ position: "absolute",
1418
+ zIndex: 0,
1419
+ x: dir < 0 ? slideDistance : -slideDistance,
1420
+ opacity: 0
1421
+ })
1422
+ };
1423
+ const key = `${panels[0].viewMonth.toISOString()}_${direction}`;
1424
+ return /* @__PURE__ */ React12.createElement("div", { style: { position: "relative", overflow: "hidden", minHeight: "250px" } }, /* @__PURE__ */ React12.createElement(AnimatePresence, { initial: false, custom: direction }, /* @__PURE__ */ React12.createElement(
1425
+ motion13.div,
1426
+ {
1427
+ key,
1428
+ custom: direction,
1429
+ variants: multiVariants,
1430
+ initial: "enter",
1431
+ animate: "center",
1432
+ exit: "exit",
1433
+ transition: {
1434
+ x: { type: "spring", stiffness: 300, damping: 30 },
1435
+ opacity: { duration: 0.2 }
1436
+ },
1437
+ drag: "x",
1438
+ dragConstraints: { left: 0, right: 0 },
1439
+ dragElastic: 1,
1440
+ onDragEnd: (e, { offset, velocity }) => {
1441
+ const swipe = swipePower(offset.x, velocity.x);
1442
+ if (swipe < -swipeConfidenceThreshold) {
1443
+ const date = new Date(panels[0].viewMonth);
1444
+ date.setMonth(date.getMonth() + 1);
1445
+ panels[0].onMonthChange?.(date);
1446
+ } else if (swipe > swipeConfidenceThreshold) {
1447
+ const date = new Date(panels[0].viewMonth);
1448
+ date.setMonth(date.getMonth() - 1);
1449
+ panels[0].onMonthChange?.(date);
1450
+ }
1451
+ },
1452
+ style: { display: "flex", gap: `${CALENDAR_PANEL_GAP}px`, top: 0, left: 0, width: "100%" }
1453
+ },
1454
+ panels.map((panelOwnerState) => /* @__PURE__ */ React12.createElement(
1455
+ "div",
1456
+ {
1457
+ key: panelOwnerState.viewMonth.toISOString(),
1458
+ style: {
1459
+ flex: "0 0 auto",
1460
+ width: `${CALENDAR_PANEL_WIDTH}px`,
1461
+ paddingLeft: "16px",
1462
+ paddingRight: "16px",
1463
+ boxSizing: "border-box"
1464
+ }
1465
+ },
1466
+ /* @__PURE__ */ React12.createElement(PlainPickerDays, { ownerState: panelOwnerState })
1467
+ ))
1468
+ )));
1469
+ };
1470
+ var CalendarPanel = ({
1471
+ ownerState,
1472
+ panelIndex,
1473
+ totalPanels,
1474
+ onPrev,
1475
+ onNext,
1476
+ onSwitchView,
1477
+ isMonthViewAssistHintOpen,
1478
+ monthViewHintMessage
1479
+ }) => {
1480
+ const showPrev = panelIndex === 0;
1481
+ const showNext = panelIndex === totalPanels - 1;
1482
+ const title = ownerState.view === "month" ? getYearName(ownerState.viewMonth, ownerState.locale || "default") : getMonthName(ownerState.viewMonth, ownerState.locale || "default");
1483
+ return /* @__PURE__ */ React12.createElement("div", { style: { flex: 1, maxWidth: `${CALENDAR_PANEL_WIDTH}px` } }, /* @__PURE__ */ React12.createElement(CalendarHeader, null, /* @__PURE__ */ React12.createElement(
1484
+ IconButton_default,
1485
+ {
1486
+ size: "sm",
1487
+ onClick: onPrev,
1488
+ "aria-label": `Previous ${ownerState.view === "day" ? "Month" : "Year"}`,
1489
+ style: { visibility: showPrev ? "visible" : "hidden" }
1490
+ },
1491
+ /* @__PURE__ */ React12.createElement(ChevronLeftIcon, null)
1492
+ ), /* @__PURE__ */ React12.createElement(
1493
+ Tooltip_default,
1494
+ {
1495
+ title: monthViewHintMessage,
1496
+ arrow: true,
1497
+ open: panelIndex === 0 && isMonthViewAssistHintOpen,
1498
+ placement: "bottom",
1499
+ disableFocusListener: true,
1500
+ disableHoverListener: true,
1501
+ disableTouchListener: true,
1502
+ variant: "solid"
1503
+ },
1504
+ /* @__PURE__ */ React12.createElement(
1505
+ CalendarSwitchViewButton,
1506
+ {
1507
+ ownerState,
1508
+ variant: "plain",
1509
+ color: "neutral",
1510
+ onClick: onSwitchView,
1511
+ "aria-label": "Switch Calendar View"
1512
+ },
1513
+ title
1514
+ )
1515
+ ), /* @__PURE__ */ React12.createElement(
1516
+ IconButton_default,
1517
+ {
1518
+ size: "sm",
1519
+ onClick: onNext,
1520
+ "aria-label": `Next ${ownerState.view === "day" ? "Month" : "Year"}`,
1521
+ style: { visibility: showNext ? "visible" : "hidden" }
1522
+ },
1523
+ /* @__PURE__ */ React12.createElement(ChevronRightIcon, null)
1524
+ )));
1525
+ };
1378
1526
  var Calendar = forwardRef4((inProps, ref) => {
1379
1527
  const [props, ownerState] = useCalendarProps(inProps);
1380
1528
  const {
@@ -1391,6 +1539,7 @@ var Calendar = forwardRef4((inProps, ref) => {
1391
1539
  maxDate,
1392
1540
  disableFuture,
1393
1541
  disablePast,
1542
+ numberOfMonths,
1394
1543
  ...others
1395
1544
  } = props;
1396
1545
  const { calendarTitle, onPrev, onNext } = useCalendar(ownerState);
@@ -1398,6 +1547,9 @@ var Calendar = forwardRef4((inProps, ref) => {
1398
1547
  const monthNavClickTimestampsRef = useRef3([]);
1399
1548
  const monthViewAssistHintShownInSessionRef = useRef3(false);
1400
1549
  const monthViewAssistHintTimeoutRef = useRef3(null);
1550
+ const [hoverDay, setHoverDay] = useState4(null);
1551
+ const [hoverMonth, setHoverMonth] = useState4(null);
1552
+ const resolvedNumberOfMonths = numberOfMonths ?? 1;
1401
1553
  const hasEndDate = Boolean(value?.[1]);
1402
1554
  const isRangeHintEligible = Boolean(rangeSelection && !hasEndDate);
1403
1555
  const isHintEligible = Boolean(view === "day" && (!rangeSelection || isRangeHintEligible));
@@ -1460,7 +1612,71 @@ var Calendar = forwardRef4((inProps, ref) => {
1460
1612
  closeMonthViewAssistHint();
1461
1613
  onViewChange?.();
1462
1614
  }, [closeMonthViewAssistHint, onViewChange]);
1463
- return /* @__PURE__ */ React12.createElement(CalendarRoot, { ref, ...others }, /* @__PURE__ */ React12.createElement(CalendarHeader, null, /* @__PURE__ */ React12.createElement(IconButton_default, { size: "sm", onClick: handlePrevClick, "aria-label": `Previous ${view === "day" ? "Month" : "Year"}` }, /* @__PURE__ */ React12.createElement(ChevronLeftIcon, null)), /* @__PURE__ */ React12.createElement(
1615
+ const maxWidth = CALENDAR_PANEL_WIDTH * resolvedNumberOfMonths + CALENDAR_PANEL_GAP * (resolvedNumberOfMonths - 1);
1616
+ if (resolvedNumberOfMonths > 1) {
1617
+ const panels = Array.from({ length: resolvedNumberOfMonths }, (_, i) => {
1618
+ const panelViewMonth = new Date(ownerState.viewMonth);
1619
+ panelViewMonth.setMonth(panelViewMonth.getMonth() + i);
1620
+ panelViewMonth.setDate(1);
1621
+ panelViewMonth.setHours(0, 0, 0, 0);
1622
+ return {
1623
+ ...ownerState,
1624
+ viewMonth: panelViewMonth,
1625
+ hoverDay,
1626
+ onHoverDayChange: setHoverDay,
1627
+ hoverMonth,
1628
+ onHoverMonthChange: setHoverMonth
1629
+ };
1630
+ });
1631
+ return /* @__PURE__ */ React12.createElement(CalendarRoot, { ref, ...others, style: { maxWidth: `${maxWidth}px` } }, view === "month" ? (
1632
+ // Month view: single header + single month grid (consistent with single-month path)
1633
+ /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(CalendarHeader, null, /* @__PURE__ */ React12.createElement(IconButton_default, { size: "sm", onClick: handlePrevClick, "aria-label": "Previous Year" }, /* @__PURE__ */ React12.createElement(ChevronLeftIcon, null)), /* @__PURE__ */ React12.createElement(
1634
+ Tooltip_default,
1635
+ {
1636
+ title: monthViewHintMessage,
1637
+ arrow: true,
1638
+ open: false,
1639
+ placement: "bottom",
1640
+ disableFocusListener: true,
1641
+ disableHoverListener: true,
1642
+ disableTouchListener: true,
1643
+ variant: "solid"
1644
+ },
1645
+ /* @__PURE__ */ React12.createElement(
1646
+ CalendarSwitchViewButton,
1647
+ {
1648
+ ownerState,
1649
+ variant: "plain",
1650
+ color: "neutral",
1651
+ onClick: handleSwitchViewClick,
1652
+ "aria-label": "Switch Calendar View"
1653
+ },
1654
+ calendarTitle
1655
+ )
1656
+ ), /* @__PURE__ */ React12.createElement(IconButton_default, { size: "sm", onClick: handleNextClick, "aria-label": "Next Year" }, /* @__PURE__ */ React12.createElement(ChevronRightIcon, null))), /* @__PURE__ */ React12.createElement(PickerMonths, { ownerState }))
1657
+ ) : /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(CalendarMultiContainer, null, panels.map((panelOwnerState, i) => /* @__PURE__ */ React12.createElement(
1658
+ CalendarPanel,
1659
+ {
1660
+ key: panelOwnerState.viewMonth.toISOString(),
1661
+ ownerState: panelOwnerState,
1662
+ panelIndex: i,
1663
+ totalPanels: resolvedNumberOfMonths,
1664
+ onPrev: handlePrevClick,
1665
+ onNext: handleNextClick,
1666
+ onSwitchView: handleSwitchViewClick,
1667
+ isMonthViewAssistHintOpen,
1668
+ monthViewHintMessage
1669
+ }
1670
+ ))), /* @__PURE__ */ React12.createElement(
1671
+ MultiMonthPickerDays,
1672
+ {
1673
+ panels,
1674
+ direction: ownerState.direction,
1675
+ numberOfMonths: resolvedNumberOfMonths
1676
+ }
1677
+ )));
1678
+ }
1679
+ return /* @__PURE__ */ React12.createElement(CalendarRoot, { ref, ...others, style: { maxWidth: `${maxWidth}px` } }, /* @__PURE__ */ React12.createElement(CalendarHeader, null, /* @__PURE__ */ React12.createElement(IconButton_default, { size: "sm", onClick: handlePrevClick, "aria-label": `Previous ${view === "day" ? "Month" : "Year"}` }, /* @__PURE__ */ React12.createElement(ChevronLeftIcon, null)), /* @__PURE__ */ React12.createElement(
1464
1680
  Tooltip_default,
1465
1681
  {
1466
1682
  title: monthViewHintMessage,
@@ -2801,7 +3017,8 @@ var DatePicker = forwardRef6((inProps, ref) => {
2801
3017
  maxDate: maxDate ? new Date(maxDate) : void 0,
2802
3018
  disableFuture,
2803
3019
  disablePast,
2804
- shouldDisableDate: shouldDisableDate ? (date) => shouldDisableDate(formatValueString(date, format)) : void 0
3020
+ shouldDisableDate: shouldDisableDate ? (date) => shouldDisableDate(formatValueString(date, format)) : void 0,
3021
+ locale
2805
3022
  }
2806
3023
  ), !hideClearButton && /* @__PURE__ */ React18.createElement(
2807
3024
  DialogActions_default,
@@ -4849,6 +5066,7 @@ var DateRangePicker = forwardRef8((inProps, ref) => {
4849
5066
  hideClearButton,
4850
5067
  readOnly,
4851
5068
  presets,
5069
+ numberOfMonths,
4852
5070
  ...innerProps
4853
5071
  } = props;
4854
5072
  const innerRef = useRef8(null);
@@ -5045,7 +5263,7 @@ var DateRangePicker = forwardRef8((inProps, ref) => {
5045
5263
  "aria-label": "Calendar Tooltip",
5046
5264
  "aria-expanded": open
5047
5265
  },
5048
- /* @__PURE__ */ React26.createElement(CalendarSheet2, { tabIndex: -1, role: "presentation" }, /* @__PURE__ */ React26.createElement(CalendarSheetContent2, null, /* @__PURE__ */ React26.createElement(CalendarSection2, null, /* @__PURE__ */ React26.createElement(
5266
+ /* @__PURE__ */ React26.createElement(CalendarSheet2, { tabIndex: -1, role: "presentation" }, /* @__PURE__ */ React26.createElement(CalendarSheetContent2, null, /* @__PURE__ */ React26.createElement(CalendarSection2, { style: { width: "auto" } }, /* @__PURE__ */ React26.createElement(
5049
5267
  Calendar_default,
5050
5268
  {
5051
5269
  rangeSelection: true,
@@ -5054,7 +5272,9 @@ var DateRangePicker = forwardRef8((inProps, ref) => {
5054
5272
  minDate: minDate ? new Date(minDate) : void 0,
5055
5273
  maxDate: maxDate ? new Date(maxDate) : void 0,
5056
5274
  disableFuture,
5057
- disablePast
5275
+ disablePast,
5276
+ locale,
5277
+ numberOfMonths
5058
5278
  }
5059
5279
  ), !hideClearButton && /* @__PURE__ */ React26.createElement(
5060
5280
  DialogActions_default,
@@ -6186,7 +6406,8 @@ var MonthRangePicker = forwardRef10((inProps, ref) => {
6186
6406
  minDate: minDate ? new Date(minDate) : void 0,
6187
6407
  maxDate: maxDate ? new Date(maxDate) : void 0,
6188
6408
  disableFuture,
6189
- disablePast
6409
+ disablePast,
6410
+ locale
6190
6411
  }
6191
6412
  ), /* @__PURE__ */ React36.createElement(
6192
6413
  DialogActions_default,