Skip to content

Commit 2890523

Browse files
DateRangePicker: add ability to use predefined ranges (#608)
1 parent 97ed6a6 commit 2890523

File tree

9 files changed

+794
-58
lines changed

9 files changed

+794
-58
lines changed

src/components/DatePicker/Common.tsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,7 @@ import { Container } from "../Container/Container";
66
import { useCalendar, UseCalendarOptions } from "@h6s/calendar";
77
import { IconButton } from "../IconButton/IconButton";
88
import { Text } from "../Typography/Text/Text";
9-
10-
const locale = "en-US";
11-
const selectedDateFormatter = new Intl.DateTimeFormat(locale, {
12-
day: "2-digit",
13-
month: "short",
14-
year: "numeric",
15-
});
9+
import { headerDateFormatter, selectedDateFormatter, weekdayFormatter } from "./utils";
1610

1711
const explicitWidth = "250px";
1812

@@ -137,12 +131,6 @@ export const DateRangePickerInput = ({
137131
);
138132
};
139133

140-
const weekdayFormatter = new Intl.DateTimeFormat(locale, { weekday: "short" });
141-
const headerDateFormatter = new Intl.DateTimeFormat(locale, {
142-
month: "short",
143-
year: "numeric",
144-
});
145-
146134
const DatePickerContainer = styled(Container)`
147135
background: ${({ theme }) =>
148136
theme.click.datePicker.dateOption.color.background.default};
@@ -277,13 +265,15 @@ export const CalendarRenderer = ({
277265
orientation="horizontal"
278266
>
279267
<IconButton
268+
data-testid="calendar-previous-month"
280269
icon="chevron-left"
281270
onClick={handlePreviousClick}
282271
size="sm"
283272
type="ghost"
284273
/>
285274
<UnselectableTitle>{headerDateFormatter.format(headerDate)}</UnselectableTitle>
286275
<IconButton
276+
data-testid="calendar-next-month"
287277
icon="chevron-right"
288278
onClick={handleNextClick}
289279
size="sm"

src/components/DatePicker/DatePicker.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useEffect, useState } from "react";
22
import { isSameDate, UseCalendarOptions } from "@h6s/calendar";
3-
import Dropdown from "../Dropdown/Dropdown";
3+
import { Dropdown } from "../Dropdown/Dropdown";
44
import { Body, CalendarRenderer, DatePickerInput, DateTableCell } from "./Common";
55

66
interface CalendarProps {
Lines changed: 156 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,182 @@
1-
import { Args } from "@storybook/react";
1+
import { Args, Meta, StoryObj } from "@storybook/react";
22
import { DateRangePicker } from "./DateRangePicker";
3+
import { getPredefinedMonthsForDateRangePicker } from "./utils";
34

4-
const defaultStory = {
5+
const meta: Meta<typeof DateRangePicker> = {
6+
component: DateRangePicker,
57
args: {
8+
maxRangeLength: undefined,
69
onSelectDateRange: (startDate: Date, endDate: Date) => {
710
console.log("Date range selected: ", startDate, endDate);
811
},
912
},
10-
argTypes: {
11-
startDate: {
12-
control: "date",
13-
},
14-
endDate: {
15-
control: "date",
16-
},
17-
futureDatesDisabled: {
18-
control: "boolean",
19-
},
20-
placeholder: {
21-
control: "text",
22-
},
23-
onSelectDateRange: {
24-
control: "object",
25-
},
13+
tags: ["autodocs"],
14+
title: "Display/DateRangePicker",
15+
};
16+
17+
export default meta;
18+
19+
type Story = StoryObj<typeof meta>;
20+
21+
export const Default: Story = {
22+
args: {
23+
predefinedDatesList: [],
2624
},
27-
component: DateRangePicker,
2825
render: (args: Args) => {
2926
const endDate = args.endDate ? new Date(args.endDate) : undefined;
3027
const startDate = args.startDate ? new Date(args.startDate) : undefined;
28+
3129
return (
3230
<DateRangePicker
31+
key="default"
3332
endDate={endDate}
3433
disabled={args.disabled}
3534
futureDatesDisabled={args.futureDatesDisabled}
35+
futureStartDatesDisabled={args.futureStartDatesDisabled}
36+
maxRangeLength={args.maxRangeLength}
3637
onSelectDateRange={args.onSelectDateRange}
3738
placeholder={args.placeholder}
3839
startDate={startDate}
3940
/>
4041
);
4142
},
42-
title: "Display/DateRangePicker",
43-
tags: ["autodocs"],
4443
};
4544

46-
export default defaultStory;
45+
export const DateRangeWithMaxRange: Story = {
46+
args: {
47+
maxRangeLength: 15,
48+
predefinedDatesList: [],
49+
},
50+
render: (args: Args) => {
51+
const endDate = args.endDate ? new Date(args.endDate) : undefined;
52+
const startDate = args.startDate ? new Date(args.startDate) : undefined;
4753

48-
export const Playground = {
49-
...defaultStory,
54+
return (
55+
<DateRangePicker
56+
key="default"
57+
endDate={endDate}
58+
disabled={args.disabled}
59+
futureDatesDisabled={args.futureDatesDisabled}
60+
futureStartDatesDisabled={args.futureStartDatesDisabled}
61+
maxRangeLength={args.maxRangeLength}
62+
onSelectDateRange={args.onSelectDateRange}
63+
placeholder={args.placeholder}
64+
startDate={startDate}
65+
/>
66+
);
67+
},
68+
};
69+
70+
export const DateRangeFutureStartDatesDisabled: Story = {
71+
args: {
72+
futureStartDatesDisabled: true,
73+
predefinedDatesList: [],
74+
},
75+
};
76+
77+
export const PredefinedDatesLastSixMonths: Story = {
78+
render: (args: Args) => {
79+
const endDate = args.endDate ? new Date(args.endDate) : undefined;
80+
const startDate = args.startDate ? new Date(args.startDate) : undefined;
81+
const predefinedDatesList = getPredefinedMonthsForDateRangePicker(-6);
82+
83+
return (
84+
<DateRangePicker
85+
key="default"
86+
endDate={endDate}
87+
disabled={args.disabled}
88+
futureDatesDisabled={args.futureDatesDisabled}
89+
futureStartDatesDisabled={args.futureStartDatesDisabled}
90+
maxRangeLength={args.maxRangeLength}
91+
onSelectDateRange={args.onSelectDateRange}
92+
placeholder={args.placeholder}
93+
predefinedDatesList={predefinedDatesList}
94+
startDate={startDate}
95+
/>
96+
);
97+
},
98+
};
99+
100+
export const PredefinedDatesNextSixMonths: Story = {
101+
render: (args: Args) => {
102+
const endDate = args.endDate ? new Date(args.endDate) : undefined;
103+
const startDate = args.startDate ? new Date(args.startDate) : undefined;
104+
const predefinedDatesList = getPredefinedMonthsForDateRangePicker(6);
105+
106+
return (
107+
<DateRangePicker
108+
key="default"
109+
endDate={endDate}
110+
disabled={args.disabled}
111+
futureDatesDisabled={args.futureDatesDisabled}
112+
futureStartDatesDisabled={args.futureStartDatesDisabled}
113+
maxRangeLength={args.maxRangeLength}
114+
onSelectDateRange={args.onSelectDateRange}
115+
placeholder={args.placeholder}
116+
predefinedDatesList={predefinedDatesList}
117+
startDate={startDate}
118+
/>
119+
);
120+
},
121+
};
122+
123+
export const PredefinedDatesArbitraryDates: Story = {
124+
render: (args: Args) => {
125+
const endDate = args.endDate ? new Date(args.endDate) : undefined;
126+
const startDate = args.startDate ? new Date(args.startDate) : undefined;
127+
const predefinedDatesList = [
128+
{ startDate: new Date("04/14/2025"), endDate: new Date("05/14/2025") },
129+
{ startDate: new Date("05/14/2025"), endDate: new Date("06/14/2025") },
130+
{ startDate: new Date("06/14/2025"), endDate: new Date("07/14/2025") },
131+
];
132+
133+
return (
134+
<DateRangePicker
135+
key="default"
136+
endDate={endDate}
137+
disabled={args.disabled}
138+
futureDatesDisabled={args.futureDatesDisabled}
139+
futureStartDatesDisabled={args.futureStartDatesDisabled}
140+
maxRangeLength={args.maxRangeLength}
141+
onSelectDateRange={args.onSelectDateRange}
142+
placeholder={args.placeholder}
143+
predefinedDatesList={predefinedDatesList}
144+
startDate={startDate}
145+
/>
146+
);
147+
},
148+
};
149+
150+
export const PredefinedDatesScrollable: Story = {
151+
render: (args: Args) => {
152+
const endDate = args.endDate ? new Date(args.endDate) : undefined;
153+
const startDate = args.startDate ? new Date(args.startDate) : undefined;
154+
const predefinedDatesList = [
155+
{ startDate: new Date("09/14/2024"), endDate: new Date("10/14/2024") },
156+
{ startDate: new Date("10/14/2024"), endDate: new Date("11/14/2024") },
157+
{ startDate: new Date("11/14/2024"), endDate: new Date("12/14/2024") },
158+
{ startDate: new Date("12/14/2024"), endDate: new Date("01/14/2025") },
159+
{ startDate: new Date("01/14/2025"), endDate: new Date("02/14/2025") },
160+
{ startDate: new Date("02/14/2025"), endDate: new Date("03/14/2025") },
161+
{ startDate: new Date("03/14/2025"), endDate: new Date("04/14/2025") },
162+
{ startDate: new Date("04/14/2025"), endDate: new Date("05/14/2025") },
163+
{ startDate: new Date("05/14/2025"), endDate: new Date("06/14/2025") },
164+
{ startDate: new Date("06/14/2025"), endDate: new Date("07/14/2025") },
165+
];
166+
167+
return (
168+
<DateRangePicker
169+
key="default"
170+
endDate={endDate}
171+
disabled={args.disabled}
172+
futureDatesDisabled={args.futureDatesDisabled}
173+
futureStartDatesDisabled={args.futureStartDatesDisabled}
174+
maxRangeLength={args.maxRangeLength}
175+
onSelectDateRange={args.onSelectDateRange}
176+
placeholder={args.placeholder}
177+
predefinedDatesList={predefinedDatesList}
178+
startDate={startDate}
179+
/>
180+
);
181+
},
50182
};

0 commit comments

Comments
 (0)