@ceed/cds 1.30.1 → 1.31.1-next.1

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,
@@ -4967,6 +5183,7 @@ var DateRangePicker = (0, import_react29.forwardRef)((inProps, ref) => {
4967
5183
  hideClearButton,
4968
5184
  readOnly,
4969
5185
  presets,
5186
+ numberOfMonths,
4970
5187
  ...innerProps
4971
5188
  } = props;
4972
5189
  const innerRef = (0, import_react29.useRef)(null);
@@ -5163,7 +5380,7 @@ var DateRangePicker = (0, import_react29.forwardRef)((inProps, ref) => {
5163
5380
  "aria-label": "Calendar Tooltip",
5164
5381
  "aria-expanded": open
5165
5382
  },
5166
- /* @__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(
5167
5384
  Calendar_default,
5168
5385
  {
5169
5386
  rangeSelection: true,
@@ -5173,7 +5390,8 @@ var DateRangePicker = (0, import_react29.forwardRef)((inProps, ref) => {
5173
5390
  maxDate: maxDate ? new Date(maxDate) : void 0,
5174
5391
  disableFuture,
5175
5392
  disablePast,
5176
- locale
5393
+ locale,
5394
+ numberOfMonths
5177
5395
  }
5178
5396
  ), !hideClearButton && /* @__PURE__ */ import_react29.default.createElement(
5179
5397
  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,
@@ -4850,6 +5066,7 @@ var DateRangePicker = forwardRef8((inProps, ref) => {
4850
5066
  hideClearButton,
4851
5067
  readOnly,
4852
5068
  presets,
5069
+ numberOfMonths,
4853
5070
  ...innerProps
4854
5071
  } = props;
4855
5072
  const innerRef = useRef8(null);
@@ -5046,7 +5263,7 @@ var DateRangePicker = forwardRef8((inProps, ref) => {
5046
5263
  "aria-label": "Calendar Tooltip",
5047
5264
  "aria-expanded": open
5048
5265
  },
5049
- /* @__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(
5050
5267
  Calendar_default,
5051
5268
  {
5052
5269
  rangeSelection: true,
@@ -5056,7 +5273,8 @@ var DateRangePicker = forwardRef8((inProps, ref) => {
5056
5273
  maxDate: maxDate ? new Date(maxDate) : void 0,
5057
5274
  disableFuture,
5058
5275
  disablePast,
5059
- locale
5276
+ locale,
5277
+ numberOfMonths
5060
5278
  }
5061
5279
  ), !hideClearButton && /* @__PURE__ */ React26.createElement(
5062
5280
  DialogActions_default,