@a-type/ui 3.0.32 → 3.0.34
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/cjs/components/datePicker/Calendar.d.ts +11 -0
- package/dist/cjs/components/datePicker/Calendar.js +37 -0
- package/dist/cjs/components/datePicker/Calendar.js.map +1 -0
- package/dist/cjs/components/datePicker/DatePicker.d.ts +42 -13
- package/dist/cjs/components/datePicker/DatePicker.js +31 -71
- package/dist/cjs/components/datePicker/DatePicker.js.map +1 -1
- package/dist/cjs/components/datePicker/DatePicker.stories.d.ts +36 -1
- package/dist/cjs/components/datePicker/DatePicker.stories.js +19 -2
- package/dist/cjs/components/datePicker/DatePicker.stories.js.map +1 -1
- package/dist/cjs/components/datePicker/DateRangePicker.d.ts +55 -0
- package/dist/cjs/components/datePicker/DateRangePicker.js +89 -0
- package/dist/cjs/components/datePicker/DateRangePicker.js.map +1 -0
- package/dist/cjs/components/datePicker/index.d.ts +2 -0
- package/dist/cjs/components/datePicker/index.js +1 -0
- package/dist/cjs/components/datePicker/index.js.map +1 -1
- package/dist/css/main.css +1 -1
- package/dist/esm/components/datePicker/Calendar.d.ts +11 -0
- package/dist/esm/components/datePicker/Calendar.js +32 -0
- package/dist/esm/components/datePicker/Calendar.js.map +1 -0
- package/dist/esm/components/datePicker/DatePicker.d.ts +42 -13
- package/dist/esm/components/datePicker/DatePicker.js +32 -68
- package/dist/esm/components/datePicker/DatePicker.js.map +1 -1
- package/dist/esm/components/datePicker/DatePicker.stories.d.ts +36 -1
- package/dist/esm/components/datePicker/DatePicker.stories.js +20 -3
- package/dist/esm/components/datePicker/DatePicker.stories.js.map +1 -1
- package/dist/esm/components/datePicker/DateRangePicker.d.ts +55 -0
- package/dist/esm/components/datePicker/DateRangePicker.js +83 -0
- package/dist/esm/components/datePicker/DateRangePicker.js.map +1 -0
- package/dist/esm/components/datePicker/index.d.ts +2 -0
- package/dist/esm/components/datePicker/index.js +1 -0
- package/dist/esm/components/datePicker/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/datePicker/Calendar.tsx +83 -0
- package/src/components/datePicker/DatePicker.stories.tsx +38 -2
- package/src/components/datePicker/DatePicker.tsx +77 -222
- package/src/components/datePicker/DateRangePicker.tsx +161 -0
- package/src/components/datePicker/index.ts +2 -0
|
@@ -1,72 +1,76 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
CalendarDays,
|
|
5
|
-
} from 'calendar-blocks';
|
|
6
|
-
import classNames from 'clsx';
|
|
7
|
-
import { useCallback, useState } from 'react';
|
|
8
|
-
import { withClassName } from '../../hooks.js';
|
|
1
|
+
import { Calendar, CalendarDays, useCalendarContext } from 'calendar-blocks';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { ReactNode, useState } from 'react';
|
|
9
4
|
import { PaletteName } from '../../uno/index.js';
|
|
10
|
-
import { Button } from '../button/index.js';
|
|
11
5
|
import { Icon } from '../icon/index.js';
|
|
6
|
+
import {
|
|
7
|
+
CalendarDay,
|
|
8
|
+
CalendarGrid,
|
|
9
|
+
DayLabels,
|
|
10
|
+
MonthButton,
|
|
11
|
+
MonthLabel,
|
|
12
|
+
MonthRow,
|
|
13
|
+
} from './Calendar.js';
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
function DatePickerMonthControls({}: {}) {
|
|
16
|
+
const { setDisplayInfo, month, year } = useCalendarContext();
|
|
17
|
+
const monthLabel = new Date(year, month).toLocaleDateString('en-US', {
|
|
18
|
+
month: 'long',
|
|
19
|
+
year: 'numeric',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<MonthRow>
|
|
24
|
+
<MonthButton
|
|
25
|
+
emphasis="ghost"
|
|
26
|
+
onClick={() =>
|
|
27
|
+
setDisplayInfo({
|
|
28
|
+
month: month - 1,
|
|
29
|
+
year: year,
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
>
|
|
33
|
+
<Icon name="arrowLeft" />
|
|
34
|
+
</MonthButton>
|
|
35
|
+
<MonthLabel>{monthLabel}</MonthLabel>
|
|
36
|
+
<MonthButton
|
|
37
|
+
emphasis="ghost"
|
|
38
|
+
onClick={() =>
|
|
39
|
+
setDisplayInfo({
|
|
40
|
+
month: month + 1,
|
|
41
|
+
year: year,
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
>
|
|
45
|
+
<Icon name="arrowRight" />
|
|
46
|
+
</MonthButton>
|
|
47
|
+
</MonthRow>
|
|
48
|
+
);
|
|
18
49
|
}
|
|
19
50
|
|
|
20
|
-
|
|
21
|
-
value,
|
|
22
|
-
onChange,
|
|
51
|
+
function DatePickerRoot({
|
|
23
52
|
className,
|
|
24
53
|
color,
|
|
54
|
+
value,
|
|
55
|
+
onChange,
|
|
56
|
+
children,
|
|
25
57
|
...rest
|
|
26
|
-
}: DatePickerProps
|
|
58
|
+
}: DatePickerProps & {
|
|
59
|
+
children?: ReactNode;
|
|
60
|
+
}) {
|
|
27
61
|
const [{ month, year }, setDisplay] = useState(() => ({
|
|
28
62
|
month: new Date().getMonth(),
|
|
29
63
|
year: new Date().getFullYear(),
|
|
30
64
|
}));
|
|
31
|
-
const monthLabel = new Date(year, month).toLocaleDateString('en-US', {
|
|
32
|
-
month: 'long',
|
|
33
|
-
year: 'numeric',
|
|
34
|
-
});
|
|
35
65
|
|
|
36
66
|
return (
|
|
37
67
|
<div
|
|
38
|
-
className={
|
|
68
|
+
className={clsx(
|
|
39
69
|
color && `palette-${color}`,
|
|
40
70
|
'layer-components:(flex flex-col items-center justify-center w-[calc(var(--day-size,32px)*7)])',
|
|
41
|
-
className,
|
|
42
71
|
)}
|
|
43
72
|
{...rest}
|
|
44
73
|
>
|
|
45
|
-
<MonthRow>
|
|
46
|
-
<MonthButton
|
|
47
|
-
emphasis="ghost"
|
|
48
|
-
onClick={() =>
|
|
49
|
-
setDisplay((cur) => ({
|
|
50
|
-
month: cur.month - 1,
|
|
51
|
-
year: cur.year,
|
|
52
|
-
}))
|
|
53
|
-
}
|
|
54
|
-
>
|
|
55
|
-
<Icon name="arrowLeft" />
|
|
56
|
-
</MonthButton>
|
|
57
|
-
<MonthLabel>{monthLabel}</MonthLabel>
|
|
58
|
-
<MonthButton
|
|
59
|
-
emphasis="ghost"
|
|
60
|
-
onClick={() =>
|
|
61
|
-
setDisplay((cur) => ({
|
|
62
|
-
month: cur.month + 1,
|
|
63
|
-
year: cur.year,
|
|
64
|
-
}))
|
|
65
|
-
}
|
|
66
|
-
>
|
|
67
|
-
<Icon name="arrowRight" />
|
|
68
|
-
</MonthButton>
|
|
69
|
-
</MonthRow>
|
|
70
74
|
<Calendar
|
|
71
75
|
displayMonth={month}
|
|
72
76
|
displayYear={year}
|
|
@@ -74,188 +78,39 @@ export function DatePicker({
|
|
|
74
78
|
onChange={onChange}
|
|
75
79
|
onDisplayChange={setDisplay}
|
|
76
80
|
>
|
|
77
|
-
|
|
78
|
-
<DayLabels />
|
|
79
|
-
<CalendarDays>
|
|
80
|
-
{(value) => <CalendarDay value={value} key={value.key} />}
|
|
81
|
-
</CalendarDays>
|
|
82
|
-
</CalendarGrid>
|
|
81
|
+
{children}
|
|
83
82
|
</Calendar>
|
|
84
83
|
</div>
|
|
85
84
|
);
|
|
86
85
|
}
|
|
87
86
|
|
|
88
|
-
export interface
|
|
89
|
-
value:
|
|
90
|
-
onChange: (
|
|
87
|
+
export interface DatePickerProps {
|
|
88
|
+
value: Date | null;
|
|
89
|
+
onChange: (date: Date | null) => void;
|
|
91
90
|
className?: string;
|
|
91
|
+
color?: PaletteName;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
value,
|
|
96
|
-
onChange,
|
|
97
|
-
className,
|
|
98
|
-
}: DateRangePickerProps) {
|
|
99
|
-
const [{ month, year }, setDisplay] = useState(() => ({
|
|
100
|
-
month: new Date().getMonth(),
|
|
101
|
-
year: new Date().getFullYear(),
|
|
102
|
-
}));
|
|
103
|
-
const monthLabel = new Date(year, month).toLocaleDateString('en-US', {
|
|
104
|
-
month: 'long',
|
|
105
|
-
year: 'numeric',
|
|
106
|
-
});
|
|
107
|
-
const nextMonth = new Date(year, month + 1);
|
|
108
|
-
const nextMonthLabel = nextMonth.toLocaleDateString('en-US', {
|
|
109
|
-
month: 'long',
|
|
110
|
-
year: 'numeric',
|
|
111
|
-
});
|
|
112
|
-
const onDisplayChange = useCallback(
|
|
113
|
-
({ month: newMonth, year: newYear }: { month: number; year: number }) => {
|
|
114
|
-
/**
|
|
115
|
-
* Important UX consideration:
|
|
116
|
-
*
|
|
117
|
-
* since we are displaying 2 months at once, we don't
|
|
118
|
-
* always want to change our view if the user's cursor
|
|
119
|
-
* date moves from one month to another. Specifically,
|
|
120
|
-
* if they move from the first visible month to the
|
|
121
|
-
* second visible month, we don't need to change the view,
|
|
122
|
-
* since they are still within the visible range.
|
|
123
|
-
* So, we write logic to ignore that case!
|
|
124
|
-
*/
|
|
125
|
-
if (newMonth === month + 1 && newYear === year) {
|
|
126
|
-
return; // ignore movement from the first to the second frame
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
setDisplay({
|
|
130
|
-
month: newMonth,
|
|
131
|
-
year: newYear,
|
|
132
|
-
});
|
|
133
|
-
},
|
|
134
|
-
[month, year],
|
|
135
|
-
);
|
|
136
|
-
|
|
94
|
+
function DatePickerDefault(props: DatePickerProps) {
|
|
137
95
|
return (
|
|
138
|
-
<
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
className={classNames('flex justify-center', className)}
|
|
145
|
-
>
|
|
146
|
-
<RangeLayout>
|
|
147
|
-
<MonthButton
|
|
148
|
-
emphasis="ghost"
|
|
149
|
-
className="[grid-area:prevMonth]"
|
|
150
|
-
onClick={() =>
|
|
151
|
-
setDisplay((cur) => ({
|
|
152
|
-
month: cur.month - 1,
|
|
153
|
-
year: cur.year,
|
|
154
|
-
}))
|
|
155
|
-
}
|
|
156
|
-
>
|
|
157
|
-
<Icon name="arrowLeft" />
|
|
158
|
-
</MonthButton>
|
|
159
|
-
<MonthLabel className="[grid-area:leftMonth]">{monthLabel}</MonthLabel>
|
|
160
|
-
<MonthLabel className="[grid-area:rightMonth] !hidden !sm:block">
|
|
161
|
-
{nextMonthLabel}
|
|
162
|
-
</MonthLabel>
|
|
163
|
-
<MonthButton
|
|
164
|
-
emphasis="ghost"
|
|
165
|
-
className="[grid-area:nextMonth]"
|
|
166
|
-
onClick={() =>
|
|
167
|
-
setDisplay((cur) => ({
|
|
168
|
-
month: cur.month + 1,
|
|
169
|
-
year: cur.year,
|
|
170
|
-
}))
|
|
171
|
-
}
|
|
172
|
-
>
|
|
173
|
-
<Icon name="arrowRight" />
|
|
174
|
-
</MonthButton>
|
|
175
|
-
<CalendarGrid className="[grid-area:leftGrid]">
|
|
176
|
-
<DayLabels />
|
|
177
|
-
<CalendarDays>
|
|
178
|
-
{(value) => <CalendarDay value={value} key={value.key} />}
|
|
179
|
-
</CalendarDays>
|
|
180
|
-
</CalendarGrid>
|
|
181
|
-
<CalendarGrid className="[grid-area:rightGrid] !hidden !sm:grid">
|
|
182
|
-
<DayLabels />
|
|
183
|
-
<CalendarDays monthOffset={1}>
|
|
184
|
-
{(value) => <CalendarDay value={value} key={value.key} />}
|
|
185
|
-
</CalendarDays>
|
|
186
|
-
</CalendarGrid>
|
|
187
|
-
</RangeLayout>
|
|
188
|
-
</Calendar>
|
|
96
|
+
<DatePickerRoot {...props}>
|
|
97
|
+
<DatePickerMonthControls />
|
|
98
|
+
<CalendarGrid>
|
|
99
|
+
{(value) => <CalendarDay value={value} key={value.key} />}
|
|
100
|
+
</CalendarGrid>
|
|
101
|
+
</DatePickerRoot>
|
|
189
102
|
);
|
|
190
103
|
}
|
|
191
104
|
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
const CalendarGrid = withClassName(
|
|
206
|
-
'div',
|
|
207
|
-
'grid grid-cols-[repeat(7,var(--day-size,32px))] [grid-auto-rows:var(--day-size,32px)]',
|
|
208
|
-
'height-[calc(var(--day-size,32px)*7)] rounded overflow-hidden p-2',
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
const CalendarDay = withClassName(
|
|
212
|
-
BaseCalendarDay,
|
|
213
|
-
'border border-solid border-transparent bg-white mr--1px mb--1px relative color-black',
|
|
214
|
-
'flex items-center justify-center transition cursor-pointer',
|
|
215
|
-
'[&[data-highlighted]]:(z-1 ring-2 ring-accent)',
|
|
216
|
-
'hover:(z-1 ring-2 ring-accent)',
|
|
217
|
-
'active:(bg-main-light rounded)',
|
|
218
|
-
'[&[data-selected]]:(bg-main z-2 rounded)',
|
|
219
|
-
'[&[data-in-range]]:(bg-main-light rounded-none z-1)',
|
|
220
|
-
'[&[data-range-start]]:(bg-main rounded-l rounded-r-none z-1)',
|
|
221
|
-
'[&[data-range-end]]:(bg-main rounded-r rounded-l-none z-1)',
|
|
222
|
-
'disabled:(opacity-50 cursor-default)',
|
|
223
|
-
// today dot
|
|
224
|
-
"[&[data-today]]:before:(content-[''] absolute left-[1px] top-[1px] w-[6px] h-[6px] rounded-lg bg-attention border-1 border-solid border-black)",
|
|
225
|
-
// calendar edges
|
|
226
|
-
'[&[data-top-edge]]:(border-t-gray)',
|
|
227
|
-
'[&[data-bottom-edge]]:(border-b-gray)',
|
|
228
|
-
'[&[data-first-column]]:(border-l-gray)',
|
|
229
|
-
'[&[data-last-column]]:(border-r-gray)',
|
|
230
|
-
'[&[data-day-first]]:(border-l-gray rounded-tl)',
|
|
231
|
-
'[&[data-day-last]]:(border-r-gray rounded-br)',
|
|
232
|
-
'[&[data-first-column][data-bottom-edge]]:rounded-bl',
|
|
233
|
-
'[&[data-last-column][data-bottom-edge]]:rounded-br',
|
|
234
|
-
'[&[data-first-column][data-top-edge]]:rounded-tl',
|
|
235
|
-
'[&[data-last-column][data-top-edge]]:rounded-tr',
|
|
236
|
-
'[&[data-different-month]]:[visibility:hidden]',
|
|
237
|
-
);
|
|
238
|
-
|
|
239
|
-
const DayLabel = withClassName(
|
|
240
|
-
'div',
|
|
241
|
-
'flex items-center justify-center text-sm color-gray-dark',
|
|
242
|
-
);
|
|
243
|
-
|
|
244
|
-
const DayLabels = () => (
|
|
245
|
-
<>
|
|
246
|
-
<DayLabel>S</DayLabel>
|
|
247
|
-
<DayLabel>M</DayLabel>
|
|
248
|
-
<DayLabel>T</DayLabel>
|
|
249
|
-
<DayLabel>W</DayLabel>
|
|
250
|
-
<DayLabel>T</DayLabel>
|
|
251
|
-
<DayLabel>F</DayLabel>
|
|
252
|
-
<DayLabel>S</DayLabel>
|
|
253
|
-
</>
|
|
254
|
-
);
|
|
255
|
-
|
|
256
|
-
const RangeLayout = withClassName(
|
|
257
|
-
'div',
|
|
258
|
-
'grid [grid-template-areas:"prevMonth_leftMonth_nextMonth""leftGrid_leftGrid_leftGrid"] [grid-template-columns:auto_1fr_auto]',
|
|
259
|
-
'[grid-template-rows:auto_1fr] gap-2',
|
|
260
|
-
'sm:grid-areas-[prevMonth_leftMonth_rightMonth_nextMonth]-[leftGrid_leftGrid_rightGrid_rightGrid] sm:[grid-template-columns:auto_1fr_1fr_auto]',
|
|
261
|
-
);
|
|
105
|
+
export const DatePicker = Object.assign(DatePickerDefault, {
|
|
106
|
+
Root: DatePickerRoot,
|
|
107
|
+
Calendar,
|
|
108
|
+
CalendarDay,
|
|
109
|
+
CalendarDays,
|
|
110
|
+
CalendarGrid,
|
|
111
|
+
DayLabels,
|
|
112
|
+
MonthControls: DatePickerMonthControls,
|
|
113
|
+
MonthButton,
|
|
114
|
+
MonthLabel,
|
|
115
|
+
MonthRow,
|
|
116
|
+
});
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Calendar, CalendarDays, useCalendarContext } from 'calendar-blocks';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { ReactNode, useCallback, useState } from 'react';
|
|
4
|
+
import { withClassName } from '../../hooks.js';
|
|
5
|
+
import { PaletteName } from '../../uno/index.js';
|
|
6
|
+
import { Icon } from '../icon/Icon.js';
|
|
7
|
+
import {
|
|
8
|
+
CalendarDay,
|
|
9
|
+
CalendarGrid,
|
|
10
|
+
DayLabels,
|
|
11
|
+
MonthButton,
|
|
12
|
+
MonthLabel,
|
|
13
|
+
} from './Calendar.js';
|
|
14
|
+
|
|
15
|
+
const RangeLayout = withClassName(
|
|
16
|
+
'div',
|
|
17
|
+
'grid [grid-template-areas:"prevMonth_leftMonth_nextMonth""leftGrid_leftGrid_leftGrid"] [grid-template-columns:auto_1fr_auto]',
|
|
18
|
+
'[grid-template-rows:auto_1fr] gap-2',
|
|
19
|
+
'sm:grid-areas-[prevMonth_leftMonth_rightMonth_nextMonth]-[leftGrid_leftGrid_rightGrid_rightGrid] sm:[grid-template-columns:auto_1fr_1fr_auto]',
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
function DateRangePickerMonthControls() {
|
|
23
|
+
const { setDisplayInfo, month, year } = useCalendarContext();
|
|
24
|
+
const monthLabel = new Date(year, month).toLocaleDateString('en-US', {
|
|
25
|
+
month: 'long',
|
|
26
|
+
year: 'numeric',
|
|
27
|
+
});
|
|
28
|
+
const nextMonth = new Date(year, month + 1);
|
|
29
|
+
const nextMonthLabel = nextMonth.toLocaleDateString('en-US', {
|
|
30
|
+
month: 'long',
|
|
31
|
+
year: 'numeric',
|
|
32
|
+
});
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
<MonthButton
|
|
36
|
+
emphasis="ghost"
|
|
37
|
+
className="[grid-area:prevMonth]"
|
|
38
|
+
onClick={() =>
|
|
39
|
+
setDisplayInfo({
|
|
40
|
+
month: month - 1,
|
|
41
|
+
year: year,
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
>
|
|
45
|
+
<Icon name="arrowLeft" />
|
|
46
|
+
</MonthButton>
|
|
47
|
+
<MonthLabel className="[grid-area:leftMonth]">{monthLabel}</MonthLabel>
|
|
48
|
+
<MonthLabel className="[grid-area:rightMonth] !hidden !sm:block">
|
|
49
|
+
{nextMonthLabel}
|
|
50
|
+
</MonthLabel>
|
|
51
|
+
<MonthButton
|
|
52
|
+
emphasis="ghost"
|
|
53
|
+
className="[grid-area:nextMonth]"
|
|
54
|
+
onClick={() =>
|
|
55
|
+
setDisplayInfo({
|
|
56
|
+
month: month + 1,
|
|
57
|
+
year: year,
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
>
|
|
61
|
+
<Icon name="arrowRight" />
|
|
62
|
+
</MonthButton>
|
|
63
|
+
</>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function DateRangePickerRoot({
|
|
68
|
+
children,
|
|
69
|
+
color,
|
|
70
|
+
value,
|
|
71
|
+
onChange,
|
|
72
|
+
className,
|
|
73
|
+
...rest
|
|
74
|
+
}: DateRangePickerProps & {
|
|
75
|
+
children?: ReactNode;
|
|
76
|
+
}) {
|
|
77
|
+
const [{ month, year }, setDisplay] = useState(() => ({
|
|
78
|
+
month: new Date().getMonth(),
|
|
79
|
+
year: new Date().getFullYear(),
|
|
80
|
+
}));
|
|
81
|
+
|
|
82
|
+
const onDisplayChange = useCallback(
|
|
83
|
+
({ month: newMonth, year: newYear }: { month: number; year: number }) => {
|
|
84
|
+
/**
|
|
85
|
+
* Important UX consideration:
|
|
86
|
+
*
|
|
87
|
+
* since we are displaying 2 months at once, we don't
|
|
88
|
+
* always want to change our view if the user's cursor
|
|
89
|
+
* date moves from one month to another. Specifically,
|
|
90
|
+
* if they move from the first visible month to the
|
|
91
|
+
* second visible month, we don't need to change the view,
|
|
92
|
+
* since they are still within the visible range.
|
|
93
|
+
* So, we write logic to ignore that case!
|
|
94
|
+
*/
|
|
95
|
+
if (newMonth === month + 1 && newYear === year) {
|
|
96
|
+
return; // ignore movement from the first to the second frame
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
setDisplay({
|
|
100
|
+
month: newMonth,
|
|
101
|
+
year: newYear,
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
[month, year],
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<Calendar
|
|
109
|
+
displayMonth={month}
|
|
110
|
+
displayYear={year}
|
|
111
|
+
rangeValue={value}
|
|
112
|
+
onRangeChange={(range) => onChange(range)}
|
|
113
|
+
onDisplayChange={onDisplayChange}
|
|
114
|
+
className={clsx(
|
|
115
|
+
'flex justify-center',
|
|
116
|
+
color && `palette-${color}`,
|
|
117
|
+
className,
|
|
118
|
+
)}
|
|
119
|
+
{...rest}
|
|
120
|
+
>
|
|
121
|
+
<RangeLayout>{children}</RangeLayout>
|
|
122
|
+
</Calendar>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface DateRangePickerProps {
|
|
127
|
+
value: { start: Date | null; end: Date | null };
|
|
128
|
+
onChange: (value: { start: Date | null; end: Date | null }) => void;
|
|
129
|
+
className?: string;
|
|
130
|
+
color?: PaletteName;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function DateRangePickerBase(props: DateRangePickerProps) {
|
|
134
|
+
return (
|
|
135
|
+
<DateRangePickerRoot {...props}>
|
|
136
|
+
<DateRangePickerMonthControls />
|
|
137
|
+
<CalendarGrid className="[grid-area:leftGrid]">
|
|
138
|
+
{(value) => <CalendarDay value={value} key={value.key} />}
|
|
139
|
+
</CalendarGrid>
|
|
140
|
+
<CalendarGrid
|
|
141
|
+
className="[grid-area:rightGrid] !hidden !sm:grid"
|
|
142
|
+
monthOffset={1}
|
|
143
|
+
>
|
|
144
|
+
{(value) => <CalendarDay value={value} key={value.key} />}
|
|
145
|
+
</CalendarGrid>
|
|
146
|
+
</DateRangePickerRoot>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export const DateRangePicker = Object.assign(DateRangePickerBase, {
|
|
151
|
+
Root: DateRangePickerRoot,
|
|
152
|
+
RangeLayout,
|
|
153
|
+
DayLabels,
|
|
154
|
+
CalendarDay,
|
|
155
|
+
Calendar,
|
|
156
|
+
CalendarGrid,
|
|
157
|
+
CalendarDays,
|
|
158
|
+
MonthControls: DateRangePickerMonthControls,
|
|
159
|
+
MonthButton,
|
|
160
|
+
MonthLabel,
|
|
161
|
+
});
|