@plexui/ui 0.7.43 → 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.
- package/dist/es/components/DatePicker/Calendar.js +146 -14
- package/dist/es/components/DatePicker/Calendar.js.map +1 -1
- package/dist/es/components/DatePicker/Calendar.module.css +107 -1
- package/dist/es/components/DatePicker/DatePicker.js +8 -2
- package/dist/es/components/DatePicker/DatePicker.js.map +1 -1
- package/dist/es/components/DatePicker/context.js.map +1 -1
- package/dist/es/components/Dialog/Dialog.js +63 -0
- package/dist/es/components/Dialog/Dialog.js.map +1 -0
- package/dist/es/components/Dialog/Dialog.module.css +128 -0
- package/dist/es/components/Dialog/index.js +2 -0
- package/dist/es/components/Dialog/index.js.map +1 -0
- package/dist/types/components/DatePicker/DatePicker.d.ts +17 -0
- package/dist/types/components/DatePicker/context.d.ts +3 -0
- package/dist/types/components/Dialog/Dialog.d.ts +31 -0
- package/dist/types/components/Dialog/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -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
|
-
|
|
27
|
-
|
|
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
|
-
|
|
31
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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 (
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
})) }) })
|
|
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
|
-
}
|
|
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:
|
|
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":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAClC,OAAO,EAAE,OAAO,EAA4B,MAAM,YAAY,CAAA;AAC9D,OAAO,EAAE,aAAa,EAA2B,MAAM,kBAAkB,CAAA;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,WAAW,EAAyB,MAAM,WAAW,CAAA;
|
|
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;
|
|
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"]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import { Dialog as RadixDialog } from "radix-ui";
|
|
5
|
+
import { createContext, useCallback, useContext, useMemo, useState, } from "react";
|
|
6
|
+
import { useEscCloseStack } from "../../hooks/useEscCloseStack";
|
|
7
|
+
import { preventDefaultHandler, toCssVariables } from "../../lib/helpers";
|
|
8
|
+
import { TransitionGroup } from "../Transition";
|
|
9
|
+
import s from "./Dialog.module.css";
|
|
10
|
+
const DialogContext = createContext(null);
|
|
11
|
+
const useDialogContext = () => {
|
|
12
|
+
const context = useContext(DialogContext);
|
|
13
|
+
if (!context) {
|
|
14
|
+
throw new Error("Dialog compound components must be used inside <Dialog>");
|
|
15
|
+
}
|
|
16
|
+
return context;
|
|
17
|
+
};
|
|
18
|
+
export const Dialog = ({ open: controlledOpen, onOpenChange: controlledOnOpenChange, children, }) => {
|
|
19
|
+
const [open, setOpen] = useState(false);
|
|
20
|
+
const isOpen = controlledOpen ?? open;
|
|
21
|
+
const handleOpenChange = useCallback((nextState) => {
|
|
22
|
+
controlledOnOpenChange?.(nextState);
|
|
23
|
+
setOpen(nextState);
|
|
24
|
+
}, [controlledOnOpenChange]);
|
|
25
|
+
const store = useMemo(() => ({
|
|
26
|
+
open: isOpen,
|
|
27
|
+
setOpen: handleOpenChange,
|
|
28
|
+
}), [isOpen, handleOpenChange]);
|
|
29
|
+
return (_jsx(DialogContext, { value: store, children: _jsx(RadixDialog.Root, { open: isOpen, onOpenChange: handleOpenChange, children: children }) }));
|
|
30
|
+
};
|
|
31
|
+
const Trigger = ({ children }) => {
|
|
32
|
+
return _jsx(RadixDialog.Trigger, { asChild: true, children: children });
|
|
33
|
+
};
|
|
34
|
+
const Content = ({ children, width = 480, showClose = true, className }) => {
|
|
35
|
+
const { open, setOpen } = useDialogContext();
|
|
36
|
+
useEscCloseStack(open, () => {
|
|
37
|
+
setOpen(false);
|
|
38
|
+
});
|
|
39
|
+
return (_jsx(RadixDialog.Portal, { forceMount: true, children: _jsx(TransitionGroup, { enterDuration: 250, exitDuration: 150, className: s.Transition, disableAnimations: true, children: open && (_jsxs("div", { children: [_jsx(RadixDialog.Overlay, { className: s.Overlay }), _jsx(RadixDialog.Content, { forceMount: true, className: s.Content, style: toCssVariables({ "dialog-width": width }), onEscapeKeyDown: preventDefaultHandler, children: _jsxs("div", { className: clsx(s.Panel, className), children: [showClose && (_jsx(RadixDialog.Close, { asChild: true, children: _jsx("button", { type: "button", className: s.CloseButton, "aria-label": "Close dialog", children: _jsx("svg", { className: s.CloseIcon, viewBox: "0 0 20 20", width: "20", height: "20", "aria-hidden": "true", children: _jsx("path", { fill: "currentColor", d: "M5.22 5.22a.75.75 0 0 1 1.06 0L10 8.94l3.72-3.72a.75.75 0 1 1 1.06 1.06L11.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06L10 11.06l-3.72 3.72a.75.75 0 1 1-1.06-1.06L8.94 10 5.22 6.28a.75.75 0 0 1 0-1.06" }) }) }) })), children] }) })] }, "dialog")) }) }));
|
|
40
|
+
};
|
|
41
|
+
const Header = ({ children, className }) => {
|
|
42
|
+
return _jsx("div", { className: clsx(s.Header, className), children: children });
|
|
43
|
+
};
|
|
44
|
+
const Footer = ({ children, className }) => {
|
|
45
|
+
return _jsx("div", { className: clsx(s.Footer, className), children: children });
|
|
46
|
+
};
|
|
47
|
+
const Title = ({ children, className }) => {
|
|
48
|
+
return _jsx(RadixDialog.Title, { className: clsx(s.Title, className), children: children });
|
|
49
|
+
};
|
|
50
|
+
const Description = ({ children, className }) => {
|
|
51
|
+
return (_jsx(RadixDialog.Description, { className: clsx(s.Description, className), children: children }));
|
|
52
|
+
};
|
|
53
|
+
const Close = ({ children }) => {
|
|
54
|
+
return _jsx(RadixDialog.Close, { asChild: true, children: children });
|
|
55
|
+
};
|
|
56
|
+
Dialog.Trigger = Trigger;
|
|
57
|
+
Dialog.Content = Content;
|
|
58
|
+
Dialog.Header = Header;
|
|
59
|
+
Dialog.Footer = Footer;
|
|
60
|
+
Dialog.Title = Title;
|
|
61
|
+
Dialog.Description = Description;
|
|
62
|
+
Dialog.Close = Close;
|
|
63
|
+
//# sourceMappingURL=Dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dialog.js","sourceRoot":"","sources":["../../../../src/components/Dialog/Dialog.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { Dialog as RadixDialog } from \"radix-ui\"\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\"\nimport { useEscCloseStack } from \"../../hooks/useEscCloseStack\"\nimport { preventDefaultHandler, toCssVariables } from \"../../lib/helpers\"\nimport { TransitionGroup } from \"../Transition\"\nimport s from \"./Dialog.module.css\"\n\ntype DialogContextValue = {\n open: boolean\n setOpen: (nextState: boolean) => void\n}\n\nconst DialogContext = createContext<DialogContextValue | null>(null)\n\nconst useDialogContext = () => {\n const context = useContext(DialogContext)\n\n if (!context) {\n throw new Error(\"Dialog compound components must be used inside <Dialog>\")\n }\n\n return context\n}\n\nexport type DialogProps = {\n open?: boolean\n onOpenChange?: (open: boolean) => void\n children: ReactNode\n}\n\nexport const Dialog = ({\n open: controlledOpen,\n onOpenChange: controlledOnOpenChange,\n children,\n}: DialogProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const isOpen = controlledOpen ?? open\n\n const handleOpenChange = useCallback(\n (nextState: boolean) => {\n controlledOnOpenChange?.(nextState)\n setOpen(nextState)\n },\n [controlledOnOpenChange],\n )\n\n const store = useMemo<DialogContextValue>(\n () => ({\n open: isOpen,\n setOpen: handleOpenChange,\n }),\n [isOpen, handleOpenChange],\n )\n\n return (\n <DialogContext value={store}>\n <RadixDialog.Root open={isOpen} onOpenChange={handleOpenChange}>\n {children}\n </RadixDialog.Root>\n </DialogContext>\n )\n}\n\nconst Trigger = ({ children }: { children: ReactNode }) => {\n return <RadixDialog.Trigger asChild>{children}</RadixDialog.Trigger>\n}\n\nexport type DialogContentProps = {\n children: ReactNode\n width?: number | string\n showClose?: boolean\n className?: string\n}\n\nconst Content = ({ children, width = 480, showClose = true, className }: DialogContentProps) => {\n const { open, setOpen } = useDialogContext()\n\n useEscCloseStack(open, () => {\n setOpen(false)\n })\n\n return (\n <RadixDialog.Portal forceMount>\n <TransitionGroup\n enterDuration={250}\n exitDuration={150}\n className={s.Transition}\n disableAnimations\n >\n {open && (\n <div key=\"dialog\">\n <RadixDialog.Overlay className={s.Overlay} />\n <RadixDialog.Content\n forceMount\n className={s.Content}\n style={toCssVariables({ \"dialog-width\": width })}\n onEscapeKeyDown={preventDefaultHandler}\n >\n <div className={clsx(s.Panel, className)}>\n {showClose && (\n <RadixDialog.Close asChild>\n <button type=\"button\" className={s.CloseButton} aria-label=\"Close dialog\">\n <svg\n className={s.CloseIcon}\n viewBox=\"0 0 20 20\"\n width=\"20\"\n height=\"20\"\n aria-hidden=\"true\"\n >\n <path\n fill=\"currentColor\"\n d=\"M5.22 5.22a.75.75 0 0 1 1.06 0L10 8.94l3.72-3.72a.75.75 0 1 1 1.06 1.06L11.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06L10 11.06l-3.72 3.72a.75.75 0 1 1-1.06-1.06L8.94 10 5.22 6.28a.75.75 0 0 1 0-1.06\"\n />\n </svg>\n </button>\n </RadixDialog.Close>\n )}\n {children}\n </div>\n </RadixDialog.Content>\n </div>\n )}\n </TransitionGroup>\n </RadixDialog.Portal>\n )\n}\n\ntype DialogSlotProps = {\n children: ReactNode\n className?: string\n}\n\nconst Header = ({ children, className }: DialogSlotProps) => {\n return <div className={clsx(s.Header, className)}>{children}</div>\n}\n\nconst Footer = ({ children, className }: DialogSlotProps) => {\n return <div className={clsx(s.Footer, className)}>{children}</div>\n}\n\nconst Title = ({ children, className }: DialogSlotProps) => {\n return <RadixDialog.Title className={clsx(s.Title, className)}>{children}</RadixDialog.Title>\n}\n\nconst Description = ({ children, className }: DialogSlotProps) => {\n return (\n <RadixDialog.Description className={clsx(s.Description, className)}>\n {children}\n </RadixDialog.Description>\n )\n}\n\nconst Close = ({ children }: { children: ReactNode }) => {\n return <RadixDialog.Close asChild>{children}</RadixDialog.Close>\n}\n\nDialog.Trigger = Trigger\nDialog.Content = Content\nDialog.Header = Header\nDialog.Footer = Footer\nDialog.Title = Title\nDialog.Description = Description\nDialog.Close = Close\n"]}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
@layer components {.Transition {
|
|
2
|
+
position: relative;
|
|
3
|
+
}.Overlay {
|
|
4
|
+
position: fixed;
|
|
5
|
+
inset: 0;
|
|
6
|
+
z-index: 50;
|
|
7
|
+
background: rgb(0 0 0 / 0.5);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.Transition[data-entering] .Overlay {
|
|
11
|
+
opacity: 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.Transition[data-entering-active] .Overlay,
|
|
15
|
+
.Transition[data-entering][data-interrupted] .Overlay {
|
|
16
|
+
opacity: 1;
|
|
17
|
+
transition: opacity 0.2s var(--cubic-enter);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.Transition[data-exiting] .Overlay {
|
|
21
|
+
opacity: 1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.Transition[data-exiting-active] .Overlay,
|
|
25
|
+
.Transition[data-exiting][data-interrupted] .Overlay {
|
|
26
|
+
opacity: 0;
|
|
27
|
+
transition: opacity 0.15s var(--cubic-exit);
|
|
28
|
+
}.Content {
|
|
29
|
+
position: fixed;
|
|
30
|
+
inset: 0;
|
|
31
|
+
z-index: 50;
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
justify-content: center;
|
|
35
|
+
padding: 1rem;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.Content:focus {
|
|
39
|
+
outline: none;
|
|
40
|
+
}.Panel {
|
|
41
|
+
position: relative;
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
gap: 1rem;
|
|
45
|
+
width: var(--dialog-width, 480px);
|
|
46
|
+
max-width: 100%;
|
|
47
|
+
max-height: calc(100vh - 2rem);
|
|
48
|
+
overflow: auto;
|
|
49
|
+
border-radius: var(--radius-xl);
|
|
50
|
+
background: var(--color-surface-elevated);
|
|
51
|
+
box-shadow: var(--shadow-lg), var(--shadow-hairline);
|
|
52
|
+
padding: 1.25rem;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.Transition[data-entering] .Panel {
|
|
56
|
+
opacity: 0;
|
|
57
|
+
transform: scale(0.95) translateY(8px);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.Transition[data-entering-active] .Panel,
|
|
61
|
+
.Transition[data-entering][data-interrupted] .Panel {
|
|
62
|
+
opacity: 1;
|
|
63
|
+
transform: scale(1) translateY(0);
|
|
64
|
+
transition: opacity 0.25s var(--cubic-enter), transform 0.25s var(--cubic-enter);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.Transition[data-exiting] .Panel {
|
|
68
|
+
opacity: 1;
|
|
69
|
+
transform: scale(1) translateY(0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.Transition[data-exiting-active] .Panel,
|
|
73
|
+
.Transition[data-exiting][data-interrupted] .Panel {
|
|
74
|
+
opacity: 0;
|
|
75
|
+
transform: scale(0.95) translateY(8px);
|
|
76
|
+
transition: opacity 0.15s var(--cubic-exit), transform 0.15s var(--cubic-exit);
|
|
77
|
+
}.CloseButton {
|
|
78
|
+
position: absolute;
|
|
79
|
+
top: 0.75rem;
|
|
80
|
+
right: 0.75rem;
|
|
81
|
+
display: inline-flex;
|
|
82
|
+
align-items: center;
|
|
83
|
+
justify-content: center;
|
|
84
|
+
width: 2rem;
|
|
85
|
+
height: 2rem;
|
|
86
|
+
border: 0;
|
|
87
|
+
border-radius: 0.5rem;
|
|
88
|
+
background: transparent;
|
|
89
|
+
color: var(--color-text-tertiary);
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
transition: background-color 0.2s var(--cubic-enter), color 0.2s var(--cubic-enter);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.CloseButton:hover {
|
|
95
|
+
background: color-mix(in srgb, var(--color-text-tertiary) 12%, transparent);
|
|
96
|
+
color: var(--color-text);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.CloseButton:focus-visible {
|
|
100
|
+
outline: 2px solid var(--color-text);
|
|
101
|
+
outline-offset: 2px;
|
|
102
|
+
}.CloseIcon {
|
|
103
|
+
display: block;
|
|
104
|
+
}.Header {
|
|
105
|
+
display: flex;
|
|
106
|
+
flex-direction: column;
|
|
107
|
+
gap: 0.25rem;
|
|
108
|
+
}.Footer {
|
|
109
|
+
display: flex;
|
|
110
|
+
justify-content: flex-end;
|
|
111
|
+
gap: 0.5rem;
|
|
112
|
+
}.Title {
|
|
113
|
+
margin: 0;
|
|
114
|
+
font-size: 1.125rem;
|
|
115
|
+
font-weight: 600;
|
|
116
|
+
line-height: 1.4;
|
|
117
|
+
color: var(--color-text);
|
|
118
|
+
}.Description {
|
|
119
|
+
margin: 0;
|
|
120
|
+
font-size: 0.875rem;
|
|
121
|
+
line-height: 1.5;
|
|
122
|
+
color: var(--color-text-secondary);
|
|
123
|
+
}@media (width <= 640px) {
|
|
124
|
+
.Footer {
|
|
125
|
+
flex-direction: column;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/Dialog/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA6C,MAAM,UAAU,CAAA","sourcesContent":["export { Dialog, type DialogContentProps, type DialogProps } from \"./Dialog\"\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>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export type DialogProps = {
|
|
3
|
+
open?: boolean;
|
|
4
|
+
onOpenChange?: (open: boolean) => void;
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
};
|
|
7
|
+
export declare const Dialog: {
|
|
8
|
+
({ open: controlledOpen, onOpenChange: controlledOnOpenChange, children, }: DialogProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
Trigger: ({ children }: {
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
Content: ({ children, width, showClose, className }: DialogContentProps) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
Header: ({ children, className }: DialogSlotProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
Footer: ({ children, className }: DialogSlotProps) => import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
Title: ({ children, className }: DialogSlotProps) => import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
Description: ({ children, className }: DialogSlotProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
Close: ({ children }: {
|
|
18
|
+
children: ReactNode;
|
|
19
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
};
|
|
21
|
+
export type DialogContentProps = {
|
|
22
|
+
children: ReactNode;
|
|
23
|
+
width?: number | string;
|
|
24
|
+
showClose?: boolean;
|
|
25
|
+
className?: string;
|
|
26
|
+
};
|
|
27
|
+
type DialogSlotProps = {
|
|
28
|
+
children: ReactNode;
|
|
29
|
+
className?: string;
|
|
30
|
+
};
|
|
31
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Dialog, type DialogContentProps, type DialogProps } from "./Dialog";
|