@plexui/ui 0.7.44 → 0.7.45

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.
@@ -13,26 +13,68 @@ import { useDateContext } from "./context";
13
13
  const CALENDAR_WIDTH_PX = 210;
14
14
  const CALENDAR_GAP_PX = 32;
15
15
  const STEP_DISTANCE_PX = CALENDAR_WIDTH_PX + CALENDAR_GAP_PX;
16
+ const SHORT_MONTH_NAMES = Array.from({ length: 12 }, (_, i) => DateTime.local(2024, i + 1, 1).monthShort);
16
17
  export const DateCalendar = () => {
17
- const { value, min, max, onChangeRef } = useDateContext();
18
+ const { value, min, max, onChangeRef, captionLayout, showTime, yearRange } = useDateContext();
18
19
  const closePopover = usePopoverClose();
19
20
  const calendarContainerRef = useRef(null);
20
21
  const [calendarSteps, setCalendarSteps] = useState(0);
21
22
  const [forceRenderIncrement, setForceRenderIncrement] = useState(0);
22
23
  const [calendarDate, setCalendarDate] = useState(() => value ?? DateTime.now());
24
+ const isDropdown = captionLayout === "dropdown";
23
25
  const canGoBack = !min || isBefore(min, calendarDate.startOf("month"));
24
26
  const canGoForward = !max || isBefore(calendarDate.endOf("month"), max);
27
+ const [pendingHour, setPendingHour] = useState(() => value?.hour ?? 12);
28
+ const [pendingMinute, setPendingMinute] = useState(() => value?.minute ?? 0);
29
+ useEffect(() => {
30
+ if (value) {
31
+ setPendingHour(value.hour);
32
+ setPendingMinute(value.minute);
33
+ }
34
+ }, [value]);
25
35
  const handleNext = () => {
26
- setCalendarSteps((c) => c + 1);
27
- setCalendarDate((dt) => dt.plus({ months: 1 }));
36
+ if (isDropdown) {
37
+ setCalendarDate((dt) => dt.plus({ months: 1 }));
38
+ setForceRenderIncrement((c) => c + 1);
39
+ }
40
+ else {
41
+ setCalendarSteps((c) => c + 1);
42
+ setCalendarDate((dt) => dt.plus({ months: 1 }));
43
+ }
28
44
  };
29
45
  const handlePrevious = () => {
30
- setCalendarSteps((c) => c - 1);
31
- setCalendarDate((dt) => dt.minus({ months: 1 }));
46
+ if (isDropdown) {
47
+ setCalendarDate((dt) => dt.minus({ months: 1 }));
48
+ setForceRenderIncrement((c) => c + 1);
49
+ }
50
+ else {
51
+ setCalendarSteps((c) => c - 1);
52
+ setCalendarDate((dt) => dt.minus({ months: 1 }));
53
+ }
32
54
  };
33
55
  const handleDateSelect = (selectedDate) => {
34
- onChangeRef.current(selectedDate);
35
- closePopover();
56
+ if (showTime) {
57
+ onChangeRef.current(selectedDate.set({ hour: pendingHour, minute: pendingMinute }));
58
+ }
59
+ else {
60
+ onChangeRef.current(selectedDate);
61
+ closePopover();
62
+ }
63
+ };
64
+ const handleTimeChange = (hour, minute) => {
65
+ setPendingHour(hour);
66
+ setPendingMinute(minute);
67
+ if (value) {
68
+ onChangeRef.current(value.set({ hour, minute }));
69
+ }
70
+ };
71
+ const handleDropdownMonthChange = (month) => {
72
+ setCalendarDate(DateTime.local(calendarDate.year, month, 1));
73
+ setForceRenderIncrement((c) => c + 1);
74
+ };
75
+ const handleDropdownYearChange = (year) => {
76
+ setCalendarDate(DateTime.local(year, calendarDate.month, 1));
77
+ setForceRenderIncrement((c) => c + 1);
36
78
  };
37
79
  // Force re-renders when `value` changes out of band from direct user-selection
38
80
  useEffect(() => {
@@ -82,15 +124,105 @@ export const DateCalendar = () => {
82
124
  }
83
125
  });
84
126
  }, [calendarDate]);
85
- return (_jsx("div", { className: s.CalendarWrapper, children: _jsxs("div", { ref: calendarContainerRef, className: s.CalendarContainer, children: [_jsx("div", { className: s.Previous, children: _jsx(Button, { variant: "ghost", color: "secondary", size: "sm", gutterSize: "2xs", pill: false, iconSize: "sm", onClick: handlePrevious, disabled: !canGoBack, children: _jsx(ChevronLeft, {}) }) }), _jsx("div", { className: s.Next, children: _jsx(Button, { variant: "ghost", color: "secondary", size: "sm", gutterSize: "2xs", pill: false, iconSize: "sm", onClick: handleNext, disabled: !canGoForward, children: _jsx(ChevronRight, {}) }) }), _jsx("div", { className: s.CalendarRange, style: {
86
- transform: `translate(${calendarSteps * -1 * STEP_DISTANCE_PX}px, 0)`,
87
- }, children: _jsx(TransitionGroup, { enterDuration: 400, exitDuration: 400, children: _jsx(CalendarView, { stepPosition: calendarSteps, date: calendarDate, selectedDate: value, min: min, max: max, onDateSelect: handleDateSelect }, calendarDate.toLocaleString({
127
+ return (_jsxs("div", { className: s.CalendarWrapper, children: [_jsxs("div", { ref: calendarContainerRef, className: s.CalendarContainer, "data-dropdown": isDropdown ? "" : undefined, children: [_jsx("div", { className: s.Previous, children: _jsx(Button, { variant: "ghost", color: "secondary", size: "sm", gutterSize: "2xs", pill: false, iconSize: "sm", onClick: handlePrevious, disabled: !canGoBack, children: _jsx(ChevronLeft, {}) }) }), _jsx("div", { className: s.Next, children: _jsx(Button, { variant: "ghost", color: "secondary", size: "sm", gutterSize: "2xs", pill: false, iconSize: "sm", onClick: handleNext, disabled: !canGoForward, children: _jsx(ChevronRight, {}) }) }), isDropdown && (_jsx(DropdownCaption, { date: calendarDate, onMonthChange: handleDropdownMonthChange, onYearChange: handleDropdownYearChange, min: min, max: max, yearRange: yearRange })), _jsx("div", { className: s.CalendarRange, style: !isDropdown
128
+ ? { transform: `translate(${calendarSteps * -1 * STEP_DISTANCE_PX}px, 0)` }
129
+ : undefined, children: !isDropdown ? (_jsx(TransitionGroup, { enterDuration: 400, exitDuration: 400, children: _jsx(CalendarView, { stepPosition: calendarSteps, date: calendarDate, selectedDate: value, min: min, max: max, onDateSelect: handleDateSelect, hideMonthLabel: false }, calendarDate.toLocaleString({
130
+ month: "long",
131
+ year: "numeric",
132
+ })) })) : (_jsx(CalendarView, { stepPosition: 0, date: calendarDate, selectedDate: value, min: min, max: max, onDateSelect: handleDateSelect, hideMonthLabel: true }, calendarDate.toLocaleString({
88
133
  month: "long",
89
134
  year: "numeric",
90
- })) }) })] }) }, `stable-view-${forceRenderIncrement}`));
135
+ }))) })] }), showTime && (_jsx(TimeInput, { hour: pendingHour, minute: pendingMinute, onChange: handleTimeChange }))] }, `stable-view-${forceRenderIncrement}`));
136
+ };
137
+ const DropdownCaption = ({ date, onMonthChange, onYearChange, min, max, yearRange, }) => {
138
+ const currentYear = DateTime.now().year;
139
+ const minYear = yearRange?.[0] ?? min?.year ?? currentYear - 120;
140
+ const maxYear = yearRange?.[1] ?? max?.year ?? currentYear;
141
+ const years = useMemo(() => {
142
+ const result = [];
143
+ for (let y = maxYear; y >= minYear; y--) {
144
+ result.push(y);
145
+ }
146
+ return result;
147
+ }, [minYear, maxYear]);
148
+ return (_jsxs("div", { className: s.DropdownCaption, children: [_jsx("select", { className: s.DropdownSelect, value: date.month, onChange: (e) => onMonthChange(Number(e.target.value)), children: SHORT_MONTH_NAMES.map((name, i) => (_jsx("option", { value: i + 1, children: name }, name))) }), _jsx("select", { className: s.DropdownSelect, value: date.year, onChange: (e) => onYearChange(Number(e.target.value)), children: years.map((y) => (_jsx("option", { value: y, children: y }, y))) })] }));
149
+ };
150
+ const TimeInput = ({ hour, minute, onChange }) => {
151
+ const hourRef = useRef(null);
152
+ const minuteRef = useRef(null);
153
+ const [hourText, setHourText] = useState(() => String(hour).padStart(2, "0"));
154
+ const [minuteText, setMinuteText] = useState(() => String(minute).padStart(2, "0"));
155
+ useEffect(() => {
156
+ if (document.activeElement !== hourRef.current) {
157
+ setHourText(String(hour).padStart(2, "0"));
158
+ }
159
+ }, [hour]);
160
+ useEffect(() => {
161
+ if (document.activeElement !== minuteRef.current) {
162
+ setMinuteText(String(minute).padStart(2, "0"));
163
+ }
164
+ }, [minute]);
165
+ const handleHourChange = (e) => {
166
+ const raw = e.target.value.replace(/\D/g, "").slice(0, 2);
167
+ setHourText(raw);
168
+ if (raw.length === 2) {
169
+ onChange(Math.min(23, Number(raw)), minute);
170
+ minuteRef.current?.focus();
171
+ minuteRef.current?.select();
172
+ }
173
+ };
174
+ const handleHourBlur = (e) => {
175
+ const raw = e.currentTarget.value.replace(/\D/g, "").slice(0, 2);
176
+ const h = Math.min(23, Number(raw) || 0);
177
+ onChange(h, minute);
178
+ setHourText(String(h).padStart(2, "0"));
179
+ };
180
+ const handleMinuteChange = (e) => {
181
+ const raw = e.target.value.replace(/\D/g, "").slice(0, 2);
182
+ setMinuteText(raw);
183
+ if (raw.length === 2) {
184
+ onChange(hour, Math.min(59, Number(raw)));
185
+ }
186
+ };
187
+ const handleMinuteBlur = (e) => {
188
+ const raw = e.currentTarget.value.replace(/\D/g, "").slice(0, 2);
189
+ const m = Math.min(59, Number(raw) || 0);
190
+ onChange(hour, m);
191
+ setMinuteText(String(m).padStart(2, "0"));
192
+ };
193
+ const handleKeyDown = (e, type) => {
194
+ const step = e.shiftKey ? 10 : 1;
195
+ if (e.key === "ArrowUp") {
196
+ e.preventDefault();
197
+ if (type === "hour") {
198
+ const h = (hour + step) % 24;
199
+ onChange(h, minute);
200
+ setHourText(String(h).padStart(2, "0"));
201
+ }
202
+ else {
203
+ const m = (minute + step) % 60;
204
+ onChange(hour, m);
205
+ setMinuteText(String(m).padStart(2, "0"));
206
+ }
207
+ }
208
+ else if (e.key === "ArrowDown") {
209
+ e.preventDefault();
210
+ if (type === "hour") {
211
+ const h = (hour - step + 24) % 24;
212
+ onChange(h, minute);
213
+ setHourText(String(h).padStart(2, "0"));
214
+ }
215
+ else {
216
+ const m = (minute - step + 60) % 60;
217
+ onChange(hour, m);
218
+ setMinuteText(String(m).padStart(2, "0"));
219
+ }
220
+ }
221
+ };
222
+ return (_jsxs("div", { className: s.TimeFooter, children: [_jsx("span", { className: s.TimeLabel, children: "Time" }), _jsxs("div", { className: s.TimeInputGroup, children: [_jsx("input", { ref: hourRef, className: s.TimeField, type: "text", inputMode: "numeric", value: hourText, onChange: handleHourChange, onBlur: handleHourBlur, onFocus: (e) => e.target.select(), onKeyDown: (e) => handleKeyDown(e, "hour"), maxLength: 2, "aria-label": "Hour" }), _jsx("span", { className: s.TimeSeparator, children: ":" }), _jsx("input", { ref: minuteRef, className: s.TimeField, type: "text", inputMode: "numeric", value: minuteText, onChange: handleMinuteChange, onBlur: handleMinuteBlur, onFocus: (e) => e.target.select(), onKeyDown: (e) => handleKeyDown(e, "minute"), maxLength: 2, "aria-label": "Minute" })] })] }));
91
223
  };
92
224
  const daysOfTheWeekLabels = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
93
- const CalendarView = ({ date, selectedDate, min, max, onDateSelect, stepPosition, }) => {
225
+ const CalendarView = ({ date, selectedDate, min, max, onDateSelect, stepPosition, hideMonthLabel = false, }) => {
94
226
  // Lock position on mount and don't respond to changes
95
227
  const [position] = useState(stepPosition);
96
228
  const { startOfMonth, weeks, enabledInterval } = useMemo(() => {
@@ -108,14 +240,14 @@ const CalendarView = ({ date, selectedDate, min, max, onDateSelect, stepPosition
108
240
  enabledInterval: enabledDateInterval,
109
241
  };
110
242
  }, [date, min, max]);
111
- return (_jsxs("div", { className: s.Calendar, style: { left: position * STEP_DISTANCE_PX }, "data-calendar": true, children: [_jsxs("p", { className: s.MonthLabel, children: [startOfMonth.monthLong, " ", startOfMonth.year] }), _jsx("div", { className: s.Week, children: daysOfTheWeekLabels.map((day) => (_jsx("div", { className: s.DayLabel, children: day }, day))) }), weeks.map((week, weekIndex) => (_jsx("div", { className: s.Week, children: week.map((d, dayIndex) => {
243
+ return (_jsxs("div", { className: s.Calendar, style: hideMonthLabel ? undefined : { left: position * STEP_DISTANCE_PX }, "data-calendar": true, "data-static": hideMonthLabel ? "" : undefined, children: [hideMonthLabel ? (_jsx("div", { className: s.MonthLabelSpacer, "aria-hidden": "true" })) : (_jsxs("p", { className: s.MonthLabel, children: [startOfMonth.monthLong, " ", startOfMonth.year] })), _jsx("div", { className: s.Week, children: daysOfTheWeekLabels.map((day) => (_jsx("div", { className: s.DayLabel, children: day }, day))) }), weeks.map((week, weekIndex) => (_jsx("div", { className: s.Week, children: week.map((d, dayIndex) => {
112
244
  if (!d) {
113
245
  return _jsx("div", { className: s.Day }, `${weekIndex}-${dayIndex}`);
114
246
  }
115
247
  const enabled = enabledInterval.contains(d);
116
248
  const isSelected = enabled && selectedDate && isSameDay(d, selectedDate);
117
249
  const dayIsToday = isToday(d);
118
- return (_jsx("div", { className: s.Day, "data-is-selected": isSelected ? "" : undefined, children: _jsxs("button", { className: s.InteractiveDay, disabled: !enabled, onClick: () => d && onDateSelect?.(d), children: [d.day, dayIsToday && _jsx("span", { className: s.TodayDot })] }) }, dayIndex));
250
+ return (_jsx("div", { className: s.Day, "data-is-selected": isSelected ? "" : undefined, children: _jsxs("button", { type: "button", className: s.InteractiveDay, disabled: !enabled, onClick: () => d && onDateSelect?.(d), children: [d.day, dayIsToday && _jsx("span", { className: s.TodayDot })] }) }, dayIndex));
119
251
  }) }, weekIndex)))] }));
120
252
  };
121
253
  //# sourceMappingURL=Calendar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Calendar.js","sourceRoot":"","sources":["../../../../src/components/DatePicker/Calendar.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport { DateTime, Interval } from \"luxon\"\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport { chunkIntoWeeks, getDaysOfMonth, isBefore, isSameDay, isToday } from \"../../lib/dateUtils\"\nimport { waitForAnimationFrame } from \"../../lib/helpers\"\nimport { Button } from \"../Button\"\nimport { ChevronLeft, ChevronRight } from \"../Icon\"\nimport { usePopoverClose } from \"../Popover/usePopoverController\"\nimport { TransitionGroup } from \"../Transition\"\nimport s from \"./Calendar.module.css\"\nimport { useDateContext } from \"./context\"\n\nconst CALENDAR_WIDTH_PX = 210\nconst CALENDAR_GAP_PX = 32\nconst STEP_DISTANCE_PX = CALENDAR_WIDTH_PX + CALENDAR_GAP_PX\n\nexport const DateCalendar = () => {\n const { value, min, max, onChangeRef } = useDateContext()\n const closePopover = usePopoverClose()\n const calendarContainerRef = useRef<HTMLDivElement | null>(null)\n const [calendarSteps, setCalendarSteps] = useState<number>(0)\n const [forceRenderIncrement, setForceRenderIncrement] = useState<number>(0)\n const [calendarDate, setCalendarDate] = useState<DateTime>(() => value ?? DateTime.now())\n\n const canGoBack = !min || isBefore(min, calendarDate.startOf(\"month\"))\n const canGoForward = !max || isBefore(calendarDate.endOf(\"month\"), max)\n\n const handleNext = () => {\n setCalendarSteps((c) => c + 1)\n setCalendarDate((dt) => dt.plus({ months: 1 }))\n }\n\n const handlePrevious = () => {\n setCalendarSteps((c) => c - 1)\n setCalendarDate((dt) => dt.minus({ months: 1 }))\n }\n\n const handleDateSelect = (selectedDate: DateTime) => {\n onChangeRef.current(selectedDate)\n closePopover()\n }\n\n // Force re-renders when `value` changes out of band from direct user-selection\n useEffect(() => {\n // No-op when value is empty\n if (!value) {\n return\n }\n\n // Check if `value` is still within view of our calendar\n const viewInterval = Interval.fromDateTimes(\n calendarDate.startOf(\"month\"),\n calendarDate.endOf(\"month\"),\n )\n const isValueInRangeOfCalendar = viewInterval.contains(value)\n if (!isValueInRangeOfCalendar) {\n // Reset state the calendar view entirely\n setCalendarSteps(0)\n setCalendarDate(value)\n setForceRenderIncrement((c) => c + 1)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- Only re-run this hook when value changes\n }, [value])\n\n // Detect height changes when new calendars are rendered\n useEffect(() => {\n waitForAnimationFrame(() => {\n const container = calendarContainerRef.current\n\n if (!container) {\n return\n }\n\n let maxHeight = -Infinity\n\n // Find the tallest calendar\n container.querySelectorAll(\"[data-calendar]\")?.forEach((element) => {\n // NOTE: clientHeight does not respect the scale() that popover uses to animate in, which is what we want\n // We want to know the full height of the element, without any transform applied.\n const height = element.clientHeight\n\n // Ignore calendars that are exiting\n if (element.closest(\"[data-exiting\")) {\n return\n }\n\n if (height > maxHeight) {\n maxHeight = height\n }\n })\n\n container.style.height = `${maxHeight}px`\n\n // Don't animate the initial height.\n // This is relevant when the calendar opens to a larger size than the default.\n if (!container.style.transition) {\n waitForAnimationFrame(() => {\n container.style.transition = `height 0.25s var(--cubic-move)`\n })\n }\n })\n }, [calendarDate])\n\n return (\n <div className={s.CalendarWrapper} key={`stable-view-${forceRenderIncrement}`}>\n <div ref={calendarContainerRef} className={s.CalendarContainer}>\n <div className={s.Previous}>\n <Button\n variant=\"ghost\"\n color=\"secondary\"\n size=\"sm\"\n gutterSize=\"2xs\"\n pill={false}\n iconSize=\"sm\"\n onClick={handlePrevious}\n disabled={!canGoBack}\n >\n <ChevronLeft />\n </Button>\n </div>\n <div className={s.Next}>\n <Button\n variant=\"ghost\"\n color=\"secondary\"\n size=\"sm\"\n gutterSize=\"2xs\"\n pill={false}\n iconSize=\"sm\"\n onClick={handleNext}\n disabled={!canGoForward}\n >\n <ChevronRight />\n </Button>\n </div>\n <div\n className={s.CalendarRange}\n style={{\n transform: `translate(${calendarSteps * -1 * STEP_DISTANCE_PX}px, 0)`,\n }}\n >\n <TransitionGroup enterDuration={400} exitDuration={400}>\n <CalendarView\n key={calendarDate.toLocaleString({\n month: \"long\",\n year: \"numeric\",\n })}\n stepPosition={calendarSteps}\n date={calendarDate}\n selectedDate={value}\n min={min}\n max={max}\n onDateSelect={handleDateSelect}\n />\n </TransitionGroup>\n </div>\n </div>\n </div>\n )\n}\n\ntype CalendarViewProps = {\n // Can be any day within the given month that the calendar should render for\n date: DateTime\n selectedDate?: DateTime | null\n onDateSelect?: (dt: DateTime) => void\n min?: DateTime\n max?: DateTime\n stepPosition: number\n}\n\nconst daysOfTheWeekLabels = [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"]\n\nconst CalendarView = ({\n date,\n selectedDate,\n min,\n max,\n onDateSelect,\n stepPosition,\n}: CalendarViewProps) => {\n // Lock position on mount and don't respond to changes\n const [position] = useState(stepPosition)\n const { startOfMonth, weeks, enabledInterval } = useMemo(() => {\n const monthStart = date.startOf(\"month\")\n const endOfMonth = date.endOf(\"month\")\n\n const daysBeforeMonthStart = monthStart.weekday % 7\n const blankDays = new Array(daysBeforeMonthStart).fill(null)\n const daysInMonth = getDaysOfMonth(monthStart)\n const calendarCells = [...blankDays, ...daysInMonth]\n\n const enabledDateInterval = Interval.fromDateTimes(min || monthStart, max || endOfMonth)\n\n return {\n startOfMonth: monthStart,\n endOfMonth,\n weeks: chunkIntoWeeks(calendarCells, 7),\n enabledInterval: enabledDateInterval,\n }\n }, [date, min, max])\n\n return (\n <div className={s.Calendar} style={{ left: position * STEP_DISTANCE_PX }} data-calendar>\n <p className={s.MonthLabel}>\n {startOfMonth.monthLong} {startOfMonth.year}\n </p>\n <div className={s.Week}>\n {daysOfTheWeekLabels.map((day) => (\n <div key={day} className={s.DayLabel}>\n {day}\n </div>\n ))}\n </div>\n {weeks.map((week, weekIndex) => (\n <div className={s.Week} key={weekIndex}>\n {week.map((d, dayIndex) => {\n if (!d) {\n return <div className={s.Day} key={`${weekIndex}-${dayIndex}`} />\n }\n\n const enabled = enabledInterval.contains(d)\n const isSelected = enabled && selectedDate && isSameDay(d, selectedDate)\n const dayIsToday = isToday(d)\n\n return (\n <div className={s.Day} key={dayIndex} data-is-selected={isSelected ? \"\" : undefined}>\n <button\n className={s.InteractiveDay}\n disabled={!enabled}\n onClick={() => d && onDateSelect?.(d)}\n >\n {d.day}\n {dayIsToday && <span className={s.TodayDot} />}\n </button>\n </div>\n )\n })}\n </div>\n ))}\n </div>\n )\n}\n"]}
1
+ {"version":3,"file":"Calendar.js","sourceRoot":"","sources":["../../../../src/components/DatePicker/Calendar.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport { DateTime, Interval } from \"luxon\"\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport { chunkIntoWeeks, getDaysOfMonth, isBefore, isSameDay, isToday } from \"../../lib/dateUtils\"\nimport { waitForAnimationFrame } from \"../../lib/helpers\"\nimport { Button } from \"../Button\"\nimport { ChevronLeft, ChevronRight } from \"../Icon\"\nimport { usePopoverClose } from \"../Popover/usePopoverController\"\nimport { TransitionGroup } from \"../Transition\"\nimport s from \"./Calendar.module.css\"\nimport { useDateContext } from \"./context\"\n\nconst CALENDAR_WIDTH_PX = 210\nconst CALENDAR_GAP_PX = 32\nconst STEP_DISTANCE_PX = CALENDAR_WIDTH_PX + CALENDAR_GAP_PX\n\nconst SHORT_MONTH_NAMES = Array.from({ length: 12 }, (_, i) =>\n DateTime.local(2024, i + 1, 1).monthShort!,\n)\n\nexport const DateCalendar = () => {\n const { value, min, max, onChangeRef, captionLayout, showTime, yearRange } = useDateContext()\n const closePopover = usePopoverClose()\n const calendarContainerRef = useRef<HTMLDivElement | null>(null)\n const [calendarSteps, setCalendarSteps] = useState<number>(0)\n const [forceRenderIncrement, setForceRenderIncrement] = useState<number>(0)\n const [calendarDate, setCalendarDate] = useState<DateTime>(() => value ?? DateTime.now())\n\n const isDropdown = captionLayout === \"dropdown\"\n\n const canGoBack = !min || isBefore(min, calendarDate.startOf(\"month\"))\n const canGoForward = !max || isBefore(calendarDate.endOf(\"month\"), max)\n\n const [pendingHour, setPendingHour] = useState<number>(() => value?.hour ?? 12)\n const [pendingMinute, setPendingMinute] = useState<number>(() => value?.minute ?? 0)\n\n useEffect(() => {\n if (value) {\n setPendingHour(value.hour)\n setPendingMinute(value.minute)\n }\n }, [value])\n\n const handleNext = () => {\n if (isDropdown) {\n setCalendarDate((dt) => dt.plus({ months: 1 }))\n setForceRenderIncrement((c) => c + 1)\n } else {\n setCalendarSteps((c) => c + 1)\n setCalendarDate((dt) => dt.plus({ months: 1 }))\n }\n }\n\n const handlePrevious = () => {\n if (isDropdown) {\n setCalendarDate((dt) => dt.minus({ months: 1 }))\n setForceRenderIncrement((c) => c + 1)\n } else {\n setCalendarSteps((c) => c - 1)\n setCalendarDate((dt) => dt.minus({ months: 1 }))\n }\n }\n\n const handleDateSelect = (selectedDate: DateTime) => {\n if (showTime) {\n onChangeRef.current(selectedDate.set({ hour: pendingHour, minute: pendingMinute }))\n } else {\n onChangeRef.current(selectedDate)\n closePopover()\n }\n }\n\n const handleTimeChange = (hour: number, minute: number) => {\n setPendingHour(hour)\n setPendingMinute(minute)\n if (value) {\n onChangeRef.current(value.set({ hour, minute }))\n }\n }\n\n const handleDropdownMonthChange = (month: number) => {\n setCalendarDate(DateTime.local(calendarDate.year, month, 1))\n setForceRenderIncrement((c) => c + 1)\n }\n\n const handleDropdownYearChange = (year: number) => {\n setCalendarDate(DateTime.local(year, calendarDate.month, 1))\n setForceRenderIncrement((c) => c + 1)\n }\n\n // Force re-renders when `value` changes out of band from direct user-selection\n useEffect(() => {\n // No-op when value is empty\n if (!value) {\n return\n }\n\n // Check if `value` is still within view of our calendar\n const viewInterval = Interval.fromDateTimes(\n calendarDate.startOf(\"month\"),\n calendarDate.endOf(\"month\"),\n )\n const isValueInRangeOfCalendar = viewInterval.contains(value)\n if (!isValueInRangeOfCalendar) {\n // Reset state the calendar view entirely\n setCalendarSteps(0)\n setCalendarDate(value)\n setForceRenderIncrement((c) => c + 1)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- Only re-run this hook when value changes\n }, [value])\n\n // Detect height changes when new calendars are rendered\n useEffect(() => {\n waitForAnimationFrame(() => {\n const container = calendarContainerRef.current\n\n if (!container) {\n return\n }\n\n let maxHeight = -Infinity\n\n // Find the tallest calendar\n container.querySelectorAll(\"[data-calendar]\")?.forEach((element) => {\n // NOTE: clientHeight does not respect the scale() that popover uses to animate in, which is what we want\n // We want to know the full height of the element, without any transform applied.\n const height = element.clientHeight\n\n // Ignore calendars that are exiting\n if (element.closest(\"[data-exiting\")) {\n return\n }\n\n if (height > maxHeight) {\n maxHeight = height\n }\n })\n\n container.style.height = `${maxHeight}px`\n\n // Don't animate the initial height.\n // This is relevant when the calendar opens to a larger size than the default.\n if (!container.style.transition) {\n waitForAnimationFrame(() => {\n container.style.transition = `height 0.25s var(--cubic-move)`\n })\n }\n })\n }, [calendarDate])\n\n return (\n <div className={s.CalendarWrapper} key={`stable-view-${forceRenderIncrement}`}>\n <div ref={calendarContainerRef} className={s.CalendarContainer} data-dropdown={isDropdown ? \"\" : undefined}>\n <div className={s.Previous}>\n <Button\n variant=\"ghost\"\n color=\"secondary\"\n size=\"sm\"\n gutterSize=\"2xs\"\n pill={false}\n iconSize=\"sm\"\n onClick={handlePrevious}\n disabled={!canGoBack}\n >\n <ChevronLeft />\n </Button>\n </div>\n <div className={s.Next}>\n <Button\n variant=\"ghost\"\n color=\"secondary\"\n size=\"sm\"\n gutterSize=\"2xs\"\n pill={false}\n iconSize=\"sm\"\n onClick={handleNext}\n disabled={!canGoForward}\n >\n <ChevronRight />\n </Button>\n </div>\n {isDropdown && (\n <DropdownCaption\n date={calendarDate}\n onMonthChange={handleDropdownMonthChange}\n onYearChange={handleDropdownYearChange}\n min={min}\n max={max}\n yearRange={yearRange}\n />\n )}\n <div\n className={s.CalendarRange}\n style={\n !isDropdown\n ? { transform: `translate(${calendarSteps * -1 * STEP_DISTANCE_PX}px, 0)` }\n : undefined\n }\n >\n {!isDropdown ? (\n <TransitionGroup enterDuration={400} exitDuration={400}>\n <CalendarView\n key={calendarDate.toLocaleString({\n month: \"long\",\n year: \"numeric\",\n })}\n stepPosition={calendarSteps}\n date={calendarDate}\n selectedDate={value}\n min={min}\n max={max}\n onDateSelect={handleDateSelect}\n hideMonthLabel={false}\n />\n </TransitionGroup>\n ) : (\n <CalendarView\n key={calendarDate.toLocaleString({\n month: \"long\",\n year: \"numeric\",\n })}\n stepPosition={0}\n date={calendarDate}\n selectedDate={value}\n min={min}\n max={max}\n onDateSelect={handleDateSelect}\n hideMonthLabel\n />\n )}\n </div>\n </div>\n {showTime && (\n <TimeInput\n hour={pendingHour}\n minute={pendingMinute}\n onChange={handleTimeChange}\n />\n )}\n </div>\n )\n}\n\ntype DropdownCaptionProps = {\n date: DateTime\n onMonthChange: (month: number) => void\n onYearChange: (year: number) => void\n min?: DateTime\n max?: DateTime\n yearRange?: [number, number]\n}\n\nconst DropdownCaption = ({\n date,\n onMonthChange,\n onYearChange,\n min,\n max,\n yearRange,\n}: DropdownCaptionProps) => {\n const currentYear = DateTime.now().year\n const minYear = yearRange?.[0] ?? min?.year ?? currentYear - 120\n const maxYear = yearRange?.[1] ?? max?.year ?? currentYear\n\n const years = useMemo(() => {\n const result: number[] = []\n for (let y = maxYear; y >= minYear; y--) {\n result.push(y)\n }\n return result\n }, [minYear, maxYear])\n\n return (\n <div className={s.DropdownCaption}>\n <select\n className={s.DropdownSelect}\n value={date.month}\n onChange={(e) => onMonthChange(Number(e.target.value))}\n >\n {SHORT_MONTH_NAMES.map((name, i) => (\n <option key={name} value={i + 1}>\n {name}\n </option>\n ))}\n </select>\n <select\n className={s.DropdownSelect}\n value={date.year}\n onChange={(e) => onYearChange(Number(e.target.value))}\n >\n {years.map((y) => (\n <option key={y} value={y}>\n {y}\n </option>\n ))}\n </select>\n </div>\n )\n}\n\ntype TimeInputProps = {\n hour: number\n minute: number\n onChange: (hour: number, minute: number) => void\n}\n\nconst TimeInput = ({ hour, minute, onChange }: TimeInputProps) => {\n const hourRef = useRef<HTMLInputElement>(null)\n const minuteRef = useRef<HTMLInputElement>(null)\n const [hourText, setHourText] = useState(() => String(hour).padStart(2, \"0\"))\n const [minuteText, setMinuteText] = useState(() => String(minute).padStart(2, \"0\"))\n\n useEffect(() => {\n if (document.activeElement !== hourRef.current) {\n setHourText(String(hour).padStart(2, \"0\"))\n }\n }, [hour])\n\n useEffect(() => {\n if (document.activeElement !== minuteRef.current) {\n setMinuteText(String(minute).padStart(2, \"0\"))\n }\n }, [minute])\n\n const handleHourChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const raw = e.target.value.replace(/\\D/g, \"\").slice(0, 2)\n setHourText(raw)\n if (raw.length === 2) {\n onChange(Math.min(23, Number(raw)), minute)\n minuteRef.current?.focus()\n minuteRef.current?.select()\n }\n }\n\n const handleHourBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n const raw = e.currentTarget.value.replace(/\\D/g, \"\").slice(0, 2)\n const h = Math.min(23, Number(raw) || 0)\n onChange(h, minute)\n setHourText(String(h).padStart(2, \"0\"))\n }\n\n const handleMinuteChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const raw = e.target.value.replace(/\\D/g, \"\").slice(0, 2)\n setMinuteText(raw)\n if (raw.length === 2) {\n onChange(hour, Math.min(59, Number(raw)))\n }\n }\n\n const handleMinuteBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n const raw = e.currentTarget.value.replace(/\\D/g, \"\").slice(0, 2)\n const m = Math.min(59, Number(raw) || 0)\n onChange(hour, m)\n setMinuteText(String(m).padStart(2, \"0\"))\n }\n\n const handleKeyDown = (\n e: React.KeyboardEvent<HTMLInputElement>,\n type: \"hour\" | \"minute\",\n ) => {\n const step = e.shiftKey ? 10 : 1\n if (e.key === \"ArrowUp\") {\n e.preventDefault()\n if (type === \"hour\") {\n const h = (hour + step) % 24\n onChange(h, minute)\n setHourText(String(h).padStart(2, \"0\"))\n } else {\n const m = (minute + step) % 60\n onChange(hour, m)\n setMinuteText(String(m).padStart(2, \"0\"))\n }\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault()\n if (type === \"hour\") {\n const h = (hour - step + 24) % 24\n onChange(h, minute)\n setHourText(String(h).padStart(2, \"0\"))\n } else {\n const m = (minute - step + 60) % 60\n onChange(hour, m)\n setMinuteText(String(m).padStart(2, \"0\"))\n }\n }\n }\n\n return (\n <div className={s.TimeFooter}>\n <span className={s.TimeLabel}>Time</span>\n <div className={s.TimeInputGroup}>\n <input\n ref={hourRef}\n className={s.TimeField}\n type=\"text\"\n inputMode=\"numeric\"\n value={hourText}\n onChange={handleHourChange}\n onBlur={handleHourBlur}\n onFocus={(e) => e.target.select()}\n onKeyDown={(e) => handleKeyDown(e, \"hour\")}\n maxLength={2}\n aria-label=\"Hour\"\n />\n <span className={s.TimeSeparator}>:</span>\n <input\n ref={minuteRef}\n className={s.TimeField}\n type=\"text\"\n inputMode=\"numeric\"\n value={minuteText}\n onChange={handleMinuteChange}\n onBlur={handleMinuteBlur}\n onFocus={(e) => e.target.select()}\n onKeyDown={(e) => handleKeyDown(e, \"minute\")}\n maxLength={2}\n aria-label=\"Minute\"\n />\n </div>\n </div>\n )\n}\n\ntype CalendarViewProps = {\n date: DateTime\n selectedDate?: DateTime | null\n onDateSelect?: (dt: DateTime) => void\n min?: DateTime\n max?: DateTime\n stepPosition: number\n hideMonthLabel?: boolean\n}\n\nconst daysOfTheWeekLabels = [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"]\n\nconst CalendarView = ({\n date,\n selectedDate,\n min,\n max,\n onDateSelect,\n stepPosition,\n hideMonthLabel = false,\n}: CalendarViewProps) => {\n // Lock position on mount and don't respond to changes\n const [position] = useState(stepPosition)\n const { startOfMonth, weeks, enabledInterval } = useMemo(() => {\n const monthStart = date.startOf(\"month\")\n const endOfMonth = date.endOf(\"month\")\n\n const daysBeforeMonthStart = monthStart.weekday % 7\n const blankDays = new Array(daysBeforeMonthStart).fill(null)\n const daysInMonth = getDaysOfMonth(monthStart)\n const calendarCells = [...blankDays, ...daysInMonth]\n\n const enabledDateInterval = Interval.fromDateTimes(min || monthStart, max || endOfMonth)\n\n return {\n startOfMonth: monthStart,\n endOfMonth,\n weeks: chunkIntoWeeks(calendarCells, 7),\n enabledInterval: enabledDateInterval,\n }\n }, [date, min, max])\n\n return (\n <div\n className={s.Calendar}\n style={hideMonthLabel ? undefined : { left: position * STEP_DISTANCE_PX }}\n data-calendar\n data-static={hideMonthLabel ? \"\" : undefined}\n >\n {hideMonthLabel ? (\n <div className={s.MonthLabelSpacer} aria-hidden=\"true\" />\n ) : (\n <p className={s.MonthLabel}>\n {startOfMonth.monthLong} {startOfMonth.year}\n </p>\n )}\n <div className={s.Week}>\n {daysOfTheWeekLabels.map((day) => (\n <div key={day} className={s.DayLabel}>\n {day}\n </div>\n ))}\n </div>\n {weeks.map((week, weekIndex) => (\n <div className={s.Week} key={weekIndex}>\n {week.map((d, dayIndex) => {\n if (!d) {\n return <div className={s.Day} key={`${weekIndex}-${dayIndex}`} />\n }\n\n const enabled = enabledInterval.contains(d)\n const isSelected = enabled && selectedDate && isSameDay(d, selectedDate)\n const dayIsToday = isToday(d)\n\n return (\n <div className={s.Day} key={dayIndex} data-is-selected={isSelected ? \"\" : undefined}>\n <button\n type=\"button\"\n className={s.InteractiveDay}\n disabled={!enabled}\n onClick={() => d && onDateSelect?.(d)}\n >\n {d.day}\n {dayIsToday && <span className={s.TodayDot} />}\n </button>\n </div>\n )\n })}\n </div>\n ))}\n </div>\n )\n}\n"]}
@@ -71,6 +71,11 @@
71
71
  }/* Lift the inner button above the pseudo elements to avoid clipping in the focus ring box shadow. */.Next button[type="button"],
72
72
  .Previous button[type="button"] {
73
73
  z-index: 2;
74
+ }.CalendarContainer[data-dropdown] .Previous::before,
75
+ .CalendarContainer[data-dropdown] .Previous::after,
76
+ .CalendarContainer[data-dropdown] .Next::before,
77
+ .CalendarContainer[data-dropdown] .Next::after {
78
+ display: none;
74
79
  }.CalendarWrapper {
75
80
  overflow: hidden;
76
81
  padding: 10px 12px 12px;
@@ -84,7 +89,11 @@
84
89
  top: 0;
85
90
  width: 210px;
86
91
  font-size: 14px;
87
- }.Week {
92
+ }
93
+
94
+ .Calendar[data-static] {
95
+ position: relative;
96
+ }.Week {
88
97
  display: flex;
89
98
  margin-bottom: var(--cell-vertical-gutter);
90
99
  }
@@ -190,5 +199,102 @@ background-color: var(--alpha-08);
190
199
 
191
200
  [data-is-selected] .TodayDot {
192
201
  background-color: var(--gray-0);
202
+ }.MonthLabelSpacer {
203
+ height: 28px;
204
+ margin: 0 0 6px;
205
+ }.DropdownCaption {
206
+ position: absolute;
207
+ top: 0;
208
+ right: 0;
209
+ left: 0;
210
+ z-index: 1;
211
+ display: flex;
212
+ align-items: center;
213
+ justify-content: center;
214
+ gap: 2px;
215
+ height: 28px;
216
+ pointer-events: none;
217
+ }.DropdownSelect {
218
+ height: 28px;
219
+ padding: 0 18px 0 8px;
220
+ border: 0;
221
+ border-radius: var(--radius-sm);
222
+ -webkit-appearance: none;
223
+ -moz-appearance: none;
224
+ appearance: none;
225
+ background-color: transparent;
226
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' fill='none'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23999' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
227
+ background-position: right 4px center;
228
+ background-repeat: no-repeat;
229
+ color: var(--color-text);
230
+ cursor: pointer;
231
+ font-size: 13px;
232
+ font-weight: var(--font-weight-semibold);
233
+ pointer-events: auto;
234
+ transition: background-color 0.15s var(--cubic-enter);
235
+ }
236
+
237
+ @media (hover: hover) and (pointer: fine) {.DropdownSelect:hover, :where([data-theme="light"]) .DropdownSelect:hover {
238
+ background-color: var(--alpha-04);
239
+ }:where([data-theme="dark"]) .DropdownSelect:hover {
240
+ background-color: var(--alpha-06);
241
+ }
242
+ }
243
+
244
+ .DropdownSelect:focus-visible {
245
+ border-radius: var(--radius-sm);
246
+ outline: 2px solid var(--color-focus-ring);
247
+ outline-offset: -2px;
248
+ }.TimeFooter {
249
+ display: flex;
250
+ align-items: center;
251
+ justify-content: space-between;
252
+ padding-top: 10px;
253
+ margin-top: 10px;
254
+ }.TimeFooter, :where([data-theme="light"]) .TimeFooter {
255
+ border-top: 1px solid var(--alpha-06);
256
+ }:where([data-theme="dark"]) .TimeFooter {
257
+ border-top: 1px solid var(--alpha-08);
258
+ }.TimeLabel {
259
+ color: var(--color-text-secondary);
260
+ font-size: 13px;
261
+ }.TimeInputGroup {
262
+ display: flex;
263
+ align-items: center;
264
+ gap: 2px;
265
+ }.TimeField {
266
+ width: 32px;
267
+ height: 28px;
268
+ padding: 0;
269
+ border: 0;
270
+ border-radius: var(--radius-sm);
271
+ color: var(--color-text);
272
+ font-size: 13px;
273
+ font-variant-numeric: tabular-nums;
274
+ font-weight: var(--font-weight-semibold);
275
+ text-align: center;
276
+ transition: background-color 0.15s var(--cubic-enter);
277
+ }.TimeField, :where([data-theme="light"]) .TimeField {
278
+ background-color: var(--alpha-04);
279
+ }:where([data-theme="dark"]) .TimeField {
280
+ background-color: var(--alpha-06);
281
+ }
282
+
283
+ .TimeField:focus {
284
+ outline: 2px solid var(--color-focus-ring);
285
+ outline-offset: -2px;
193
286
  }
287
+
288
+ .TimeField:focus, :where([data-theme="light"]) .TimeField:focus {
289
+ background-color: var(--alpha-06);
290
+ }
291
+
292
+ :where([data-theme="dark"]) .TimeField:focus {
293
+ background-color: var(--alpha-08);
294
+ }.TimeSeparator {
295
+ color: var(--color-text-secondary);
296
+ font-size: 13px;
297
+ font-weight: var(--font-weight-semibold);
298
+ line-height: 1;
299
+ }
194
300
  }
@@ -10,7 +10,7 @@ import { SelectControl } from "../SelectControl";
10
10
  import { DateCalendar } from "./Calendar";
11
11
  import { DateContext } from "./context";
12
12
  export const DatePicker = (props) => {
13
- const { id, value, onChange, min, max, side = "bottom", sideOffset = 8, align = "center", alignOffset, variant = "outline", size = "md", clearable = false, disabled = false, dropdownIconType, placeholder = "Select date...", pill = true, block = false, triggerClassName, triggerShowIcon = true, triggerDateFormat = "MM/dd/yy", } = props;
13
+ const { id, value, onChange, min, max, side = "bottom", sideOffset = 8, align = "center", alignOffset, variant = "outline", size = "md", clearable = false, disabled = false, dropdownIconType, placeholder = "Select date...", pill = true, block = false, triggerClassName, triggerShowIcon = true, captionLayout = "buttons", showTime = false, yearRange, triggerDateFormat = showTime ? "MM/dd/yy HH:mm" : "MM/dd/yy", } = props;
14
14
  if (min && max && !isBefore(min, max)) {
15
15
  throw new Error("DatePicker error: `min` date must be before the `max` date");
16
16
  }
@@ -31,6 +31,9 @@ export const DatePicker = (props) => {
31
31
  triggerClassName,
32
32
  triggerShowIcon,
33
33
  triggerDateFormat,
34
+ captionLayout,
35
+ showTime,
36
+ yearRange,
34
37
  onChangeRef,
35
38
  }), [
36
39
  value,
@@ -47,11 +50,14 @@ export const DatePicker = (props) => {
47
50
  triggerClassName,
48
51
  triggerShowIcon,
49
52
  triggerDateFormat,
53
+ captionLayout,
54
+ showTime,
55
+ yearRange,
50
56
  onChangeRef,
51
57
  ]);
52
58
  const handleClearClick = () => {
53
59
  onChangeRef.current(null);
54
60
  };
55
- return (_jsx(DateContext, { value: store, children: _jsxs(Popover, { children: [_jsx(Popover.Trigger, { children: _jsx(SelectControl, { id: id, className: triggerClassName, selected: !!value, variant: variant, pill: pill, block: block, size: size, disabled: disabled, StartIcon: triggerShowIcon ? Calendar : undefined, dropdownIconType: dropdownIconType, onClearClick: clearable ? handleClearClick : undefined, children: _jsx("span", { className: "tabular-nums", children: value?.toFormat(triggerDateFormat) ?? placeholder }) }) }), _jsx(Popover.Content, { minWidth: 230, side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset ?? (align === "center" ? 0 : -5), children: _jsx(DateCalendar, {}) })] }) }));
61
+ return (_jsx(DateContext, { value: store, children: _jsxs(Popover, { children: [_jsx(Popover.Trigger, { children: _jsx(SelectControl, { id: id, className: triggerClassName, selected: !!value, variant: variant, pill: pill, block: block, size: size, disabled: disabled, StartIcon: triggerShowIcon ? Calendar : undefined, dropdownIconType: dropdownIconType, onClearClick: clearable ? handleClearClick : undefined, children: value?.toFormat(triggerDateFormat) ?? placeholder }) }), _jsx(Popover.Content, { minWidth: 230, side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset ?? (align === "center" ? 0 : -5), children: _jsx(DateCalendar, {}) })] }) }));
56
62
  };
57
63
  //# sourceMappingURL=DatePicker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.js","sourceRoot":"","sources":["../../../../src/components/DatePicker/DatePicker.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport { DateTime } from \"luxon\"\nimport { useMemo } from \"react\"\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { isBefore } from \"../../lib/dateUtils\"\nimport { Calendar } from \"../Icon\"\nimport { Popover, type PopoverContentProps } from \"../Popover\"\nimport { SelectControl, type SelectControlProps } from \"../SelectControl\"\nimport { DateCalendar } from \"./Calendar\"\nimport { DateContext, type DateContextValue } from \"./context\"\n\nexport type DatePickerProps = {\n /**\n * Allow targeting the input for forms and accessibility.\n */\n id: string\n /**\n * The selected date value.\n */\n value: DateTime | null\n /**\n * Handler that is triggered when the date changes.\n */\n onChange: (nextValue: DateTime | null) => void\n /**\n * Defines the earliest selectable date (inclusive).\n */\n min?: DateTime\n /**\n * Defines the latest selectable date (inclusive).\n */\n max?: DateTime\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default bottom\n */\n side?: PopoverContentProps[\"side\"]\n /**\n * The distance in pixels from the trigger.\n * @default 8\n */\n sideOffset?: PopoverContentProps[\"sideOffset\"]\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: PopoverContentProps[\"align\"]\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: PopoverContentProps[\"alignOffset\"]\n\n /**\n * Disables the select visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Placeholder text for the select\n * @default Select date...\n */\n placeholder?: string\n /**\n * Style variant for the select trigger\n * @default outline\n */\n variant?: SelectControlProps[\"variant\"]\n /**\n * Determines if the select trigger should be a fully rounded pill shape\n * @default false\n */\n pill?: boolean\n /**\n * Determines size of the size and spacing of the control.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n * @default md\n */\n size?: SelectControlProps[\"size\"]\n /**\n * Icon displayed in the far right of the select trigger\n * @default dropdown\n */\n dropdownIconType?: SelectControlProps[\"dropdownIconType\"]\n /**\n * Custom class applied to the select trigger\n */\n triggerClassName?: string\n /**\n * Display calendar icon at the start of the trigger\n * @default true\n */\n triggerShowIcon?: boolean\n /**\n * Format of dates displayed in the trigger\n */\n triggerDateFormat: string\n /**\n * Display a clear action that allows the select to be unset.\n * @default false\n */\n clearable?: boolean\n /**\n * Extends select to 100% of available width.\n * @default true\n */\n block?: boolean\n}\n\nexport const DatePicker = (props: DatePickerProps) => {\n const {\n id,\n value,\n onChange,\n min,\n max,\n side = \"bottom\",\n sideOffset = 8,\n align = \"center\",\n alignOffset,\n variant = \"outline\",\n size = \"md\",\n clearable = false,\n disabled = false,\n dropdownIconType,\n placeholder = \"Select date...\",\n pill = true,\n block = false,\n triggerClassName,\n triggerShowIcon = true,\n triggerDateFormat = \"MM/dd/yy\",\n } = props\n\n if (min && max && !isBefore(min, max)) {\n throw new Error(\"DatePicker error: `min` date must be before the `max` date\")\n }\n\n // Create stable, mutable references to avoid memoization requirements from consumers\n const onChangeRef = useLatestValue(onChange)\n\n const store = useMemo<DateContextValue>(\n () => ({\n value,\n min,\n max,\n variant,\n size,\n dropdownIconType,\n clearable,\n disabled,\n placeholder,\n block,\n pill,\n triggerClassName,\n triggerShowIcon,\n triggerDateFormat,\n onChangeRef,\n }),\n [\n value,\n min,\n max,\n variant,\n size,\n dropdownIconType,\n clearable,\n disabled,\n placeholder,\n block,\n pill,\n triggerClassName,\n triggerShowIcon,\n triggerDateFormat,\n onChangeRef,\n ],\n )\n\n const handleClearClick = () => {\n onChangeRef.current(null)\n }\n\n return (\n <DateContext value={store}>\n <Popover>\n <Popover.Trigger>\n <SelectControl\n id={id}\n className={triggerClassName}\n selected={!!value}\n variant={variant}\n pill={pill}\n block={block}\n size={size}\n disabled={disabled}\n StartIcon={triggerShowIcon ? Calendar : undefined}\n dropdownIconType={dropdownIconType}\n onClearClick={clearable ? handleClearClick : undefined}\n >\n <span className=\"tabular-nums\">\n {value?.toFormat(triggerDateFormat) ?? placeholder}\n </span>\n </SelectControl>\n </Popover.Trigger>\n <Popover.Content\n minWidth={230}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset ?? (align === \"center\" ? 0 : -5)}\n >\n <DateCalendar />\n </Popover.Content>\n </Popover>\n </DateContext>\n )\n}\n"]}
1
+ {"version":3,"file":"DatePicker.js","sourceRoot":"","sources":["../../../../src/components/DatePicker/DatePicker.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport { DateTime } from \"luxon\"\nimport { useMemo } from \"react\"\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { isBefore } from \"../../lib/dateUtils\"\nimport { Calendar } from \"../Icon\"\nimport { Popover, type PopoverContentProps } from \"../Popover\"\nimport { SelectControl, type SelectControlProps } from \"../SelectControl\"\nimport { DateCalendar } from \"./Calendar\"\nimport { DateContext, type DateContextValue } from \"./context\"\n\nexport type DatePickerProps = {\n /**\n * Allow targeting the input for forms and accessibility.\n */\n id: string\n /**\n * The selected date value.\n */\n value: DateTime | null\n /**\n * Handler that is triggered when the date changes.\n */\n onChange: (nextValue: DateTime | null) => void\n /**\n * Defines the earliest selectable date (inclusive).\n */\n min?: DateTime\n /**\n * Defines the latest selectable date (inclusive).\n */\n max?: DateTime\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default bottom\n */\n side?: PopoverContentProps[\"side\"]\n /**\n * The distance in pixels from the trigger.\n * @default 8\n */\n sideOffset?: PopoverContentProps[\"sideOffset\"]\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: PopoverContentProps[\"align\"]\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: PopoverContentProps[\"alignOffset\"]\n\n /**\n * Disables the select visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Placeholder text for the select\n * @default Select date...\n */\n placeholder?: string\n /**\n * Style variant for the select trigger\n * @default outline\n */\n variant?: SelectControlProps[\"variant\"]\n /**\n * Determines if the select trigger should be a fully rounded pill shape\n * @default false\n */\n pill?: boolean\n /**\n * Determines size of the size and spacing of the control.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n * @default md\n */\n size?: SelectControlProps[\"size\"]\n /**\n * Icon displayed in the far right of the select trigger\n * @default dropdown\n */\n dropdownIconType?: SelectControlProps[\"dropdownIconType\"]\n /**\n * Custom class applied to the select trigger\n */\n triggerClassName?: string\n /**\n * Display calendar icon at the start of the trigger\n * @default true\n */\n triggerShowIcon?: boolean\n /**\n * Format of dates displayed in the trigger\n */\n triggerDateFormat: string\n /**\n * Display a clear action that allows the select to be unset.\n * @default false\n */\n clearable?: boolean\n /**\n * Extends select to 100% of available width.\n * @default true\n */\n block?: boolean\n /**\n * Controls how the calendar header is rendered.\n * - `\"buttons\"` — Arrow navigation between months (default)\n * - `\"dropdown\"` — Month and year dropdown selects (ideal for date of birth)\n * @default buttons\n */\n captionLayout?: \"buttons\" | \"dropdown\"\n /**\n * Show time input below the calendar for combined date and time selection.\n * @default false\n */\n showTime?: boolean\n /**\n * Range of selectable years when `captionLayout` is `\"dropdown\"`.\n * @default [currentYear - 120, currentYear]\n */\n yearRange?: [number, number]\n}\n\nexport const DatePicker = (props: DatePickerProps) => {\n const {\n id,\n value,\n onChange,\n min,\n max,\n side = \"bottom\",\n sideOffset = 8,\n align = \"center\",\n alignOffset,\n variant = \"outline\",\n size = \"md\",\n clearable = false,\n disabled = false,\n dropdownIconType,\n placeholder = \"Select date...\",\n pill = true,\n block = false,\n triggerClassName,\n triggerShowIcon = true,\n captionLayout = \"buttons\",\n showTime = false,\n yearRange,\n triggerDateFormat = showTime ? \"MM/dd/yy HH:mm\" : \"MM/dd/yy\",\n } = props\n\n if (min && max && !isBefore(min, max)) {\n throw new Error(\"DatePicker error: `min` date must be before the `max` date\")\n }\n\n // Create stable, mutable references to avoid memoization requirements from consumers\n const onChangeRef = useLatestValue(onChange)\n\n const store = useMemo<DateContextValue>(\n () => ({\n value,\n min,\n max,\n variant,\n size,\n dropdownIconType,\n clearable,\n disabled,\n placeholder,\n block,\n pill,\n triggerClassName,\n triggerShowIcon,\n triggerDateFormat,\n captionLayout,\n showTime,\n yearRange,\n onChangeRef,\n }),\n [\n value,\n min,\n max,\n variant,\n size,\n dropdownIconType,\n clearable,\n disabled,\n placeholder,\n block,\n pill,\n triggerClassName,\n triggerShowIcon,\n triggerDateFormat,\n captionLayout,\n showTime,\n yearRange,\n onChangeRef,\n ],\n )\n\n const handleClearClick = () => {\n onChangeRef.current(null)\n }\n\n return (\n <DateContext value={store}>\n <Popover>\n <Popover.Trigger>\n <SelectControl\n id={id}\n className={triggerClassName}\n selected={!!value}\n variant={variant}\n pill={pill}\n block={block}\n size={size}\n disabled={disabled}\n StartIcon={triggerShowIcon ? Calendar : undefined}\n dropdownIconType={dropdownIconType}\n onClearClick={clearable ? handleClearClick : undefined}\n >\n {value?.toFormat(triggerDateFormat) ?? placeholder}\n </SelectControl>\n </Popover.Trigger>\n <Popover.Content\n minWidth={230}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset ?? (align === \"center\" ? 0 : -5)}\n >\n <DateCalendar />\n </Popover.Content>\n </Popover>\n </DateContext>\n )\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../src/components/DatePicker/context.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAsB1C,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAA0B,IAAI,CAAC,CAAA;AAEvE,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IACjC,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,CAAC,CAAA;IAEhC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACtE,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA","sourcesContent":["\"use client\"\n\nimport { DateTime } from \"luxon\"\nimport { createContext, use } from \"react\"\nimport type { SelectControlProps } from \"../SelectControl\"\n\nexport type DateContextValue = {\n value: DateTime | null\n min?: DateTime\n max?: DateTime\n triggerClassName?: string\n triggerShowIcon?: boolean\n triggerDateFormat: string\n disabled: boolean\n variant?: SelectControlProps[\"variant\"]\n pill: boolean\n block: boolean\n size?: SelectControlProps[\"size\"]\n dropdownIconType?: SelectControlProps[\"dropdownIconType\"]\n clearable: boolean\n placeholder: string\n // References\n onChangeRef: React.MutableRefObject<(nextValue: DateTime | null) => void>\n}\n\nexport const DateContext = createContext<DateContextValue | null>(null)\n\nexport const useDateContext = () => {\n const context = use(DateContext)\n\n if (!context) {\n throw new Error(\"Date components must be wrapped in <DatePicker />\")\n }\n\n return context\n}\n"]}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../src/components/DatePicker/context.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAyB1C,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAA0B,IAAI,CAAC,CAAA;AAEvE,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IACjC,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,CAAC,CAAA;IAEhC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACtE,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA","sourcesContent":["\"use client\"\n\nimport { DateTime } from \"luxon\"\nimport { createContext, use } from \"react\"\nimport type { SelectControlProps } from \"../SelectControl\"\n\nexport type DateContextValue = {\n value: DateTime | null\n min?: DateTime\n max?: DateTime\n triggerClassName?: string\n triggerShowIcon?: boolean\n triggerDateFormat: string\n disabled: boolean\n variant?: SelectControlProps[\"variant\"]\n pill: boolean\n block: boolean\n size?: SelectControlProps[\"size\"]\n dropdownIconType?: SelectControlProps[\"dropdownIconType\"]\n clearable: boolean\n placeholder: string\n captionLayout: \"buttons\" | \"dropdown\"\n showTime: boolean\n yearRange?: [number, number]\n // References\n onChangeRef: React.MutableRefObject<(nextValue: DateTime | null) => void>\n}\n\nexport const DateContext = createContext<DateContextValue | null>(null)\n\nexport const useDateContext = () => {\n const context = use(DateContext)\n\n if (!context) {\n throw new Error(\"Date components must be wrapped in <DatePicker />\")\n }\n\n return context\n}\n"]}
@@ -99,5 +99,22 @@ export type DatePickerProps = {
99
99
  * @default true
100
100
  */
101
101
  block?: boolean;
102
+ /**
103
+ * Controls how the calendar header is rendered.
104
+ * - `"buttons"` — Arrow navigation between months (default)
105
+ * - `"dropdown"` — Month and year dropdown selects (ideal for date of birth)
106
+ * @default buttons
107
+ */
108
+ captionLayout?: "buttons" | "dropdown";
109
+ /**
110
+ * Show time input below the calendar for combined date and time selection.
111
+ * @default false
112
+ */
113
+ showTime?: boolean;
114
+ /**
115
+ * Range of selectable years when `captionLayout` is `"dropdown"`.
116
+ * @default [currentYear - 120, currentYear]
117
+ */
118
+ yearRange?: [number, number];
102
119
  };
103
120
  export declare const DatePicker: (props: DatePickerProps) => import("react/jsx-runtime").JSX.Element;
@@ -15,6 +15,9 @@ export type DateContextValue = {
15
15
  dropdownIconType?: SelectControlProps["dropdownIconType"];
16
16
  clearable: boolean;
17
17
  placeholder: string;
18
+ captionLayout: "buttons" | "dropdown";
19
+ showTime: boolean;
20
+ yearRange?: [number, number];
18
21
  onChangeRef: React.MutableRefObject<(nextValue: DateTime | null) => void>;
19
22
  };
20
23
  export declare const DateContext: import("react").Context<DateContextValue | null>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plexui/ui",
3
- "version": "0.7.44",
3
+ "version": "0.7.45",
4
4
  "description": "Modern design system for building high-quality applications",
5
5
  "type": "module",
6
6
  "license": "MIT",