Skip to content

Commit e729692

Browse files
Cleanup and tests
1 parent 2b7d066 commit e729692

File tree

5 files changed

+170
-95
lines changed

5 files changed

+170
-95
lines changed

src/components/DatePicker/Common.tsx

Lines changed: 1 addition & 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-
export 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};

src/components/DatePicker/DateRangePicker.stories.tsx

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,6 @@
11
import { Args, Meta, StoryObj } from "@storybook/react";
2-
import { DateRange, DateRangePicker } from "./DateRangePicker";
3-
import dayjs from "dayjs";
4-
5-
const getMonthsByNumber = (numberOfMonths: number): Array<DateRange> => {
6-
const now = dayjs();
7-
8-
if (numberOfMonths < 0) {
9-
const lastSixMonths: Array<DateRange> = [];
10-
for (let i = 0; i < Math.abs(numberOfMonths); i++) {
11-
const date = now.subtract(i, "month");
12-
lastSixMonths.push({
13-
startDate: date.startOf("month").toDate(),
14-
endDate: i === 0 ? now.toDate() : date.endOf("month").toDate(),
15-
});
16-
}
17-
18-
return lastSixMonths.reverse();
19-
}
20-
21-
const nextSixMonths: Array<DateRange> = [];
22-
for (let i = 0; i < numberOfMonths; i++) {
23-
const date = now.add(i, "month");
24-
nextSixMonths.push({
25-
startDate: date.startOf("month").toDate(),
26-
endDate: i === 0 ? now.toDate() : date.endOf("month").toDate(),
27-
});
28-
}
29-
30-
return nextSixMonths;
31-
};
2+
import { DateRangePicker } from "./DateRangePicker";
3+
import { getPredefinedMonthsByNumber } from "./utils";
324

335
const meta: Meta<typeof DateRangePicker> = {
346
component: DateRangePicker,
@@ -98,6 +70,24 @@ export const DateRangeWithMaxRange: Story = {
9870
maxRangeLength: 15,
9971
predefinedDatesList: [],
10072
},
73+
render: (args: Args) => {
74+
const endDate = args.endDate ? new Date(args.endDate) : undefined;
75+
const startDate = args.startDate ? new Date(args.startDate) : undefined;
76+
77+
return (
78+
<DateRangePicker
79+
key="default"
80+
endDate={endDate}
81+
disabled={args.disabled}
82+
futureDatesDisabled={args.futureDatesDisabled}
83+
futureStartDatesDisabled={args.futureStartDatesDisabled}
84+
maxRangeLength={args.maxRangeLength}
85+
onSelectDateRange={args.onSelectDateRange}
86+
placeholder={args.placeholder}
87+
startDate={startDate}
88+
/>
89+
);
90+
},
10191
};
10292

10393
export const DateRangeFutureStartDatesDisabled: Story = {
@@ -111,7 +101,7 @@ export const PredefinedDatesLastSixMonths: Story = {
111101
render: (args: Args) => {
112102
const endDate = args.endDate ? new Date(args.endDate) : undefined;
113103
const startDate = args.startDate ? new Date(args.startDate) : undefined;
114-
const predefinedDatesList = getMonthsByNumber(-6);
104+
const predefinedDatesList = getPredefinedMonthsByNumber(-6);
115105

116106
return (
117107
<DateRangePicker
@@ -134,7 +124,7 @@ export const PredefinedDatesNextSixMonths: Story = {
134124
render: (args: Args) => {
135125
const endDate = args.endDate ? new Date(args.endDate) : undefined;
136126
const startDate = args.startDate ? new Date(args.startDate) : undefined;
137-
const predefinedDatesList = getMonthsByNumber(6);
127+
const predefinedDatesList = getPredefinedMonthsByNumber(6);
138128

139129
return (
140130
<DateRangePicker

src/components/DatePicker/DateRangePicker.test.tsx

Lines changed: 84 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { renderCUI } from "@/utils/test-utils";
22
import { DateRangePicker } from "./DateRangePicker";
33
import userEvent from "@testing-library/user-event";
4+
import { getPredefinedMonthsByNumber } from "./utils";
5+
import { fireEvent } from "@testing-library/dom";
46

57
describe("DateRangePicker", () => {
68
it("opens the calendar on click", async () => {
@@ -149,6 +151,28 @@ describe("DateRangePicker", () => {
149151

150152
expect(handleSelectDate).not.toHaveBeenCalled();
151153
});
154+
155+
it("allows restricting the max range length", async () => {
156+
const startDate = new Date("07-04-2020");
157+
const handleSelectDate = vi.fn();
158+
const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime });
159+
160+
const { getByTestId, findByText } = renderCUI(
161+
<DateRangePicker
162+
startDate={startDate}
163+
onSelectDateRange={handleSelectDate}
164+
maxRangeLength={15}
165+
/>
166+
);
167+
168+
user.click(getByTestId("daterangepicker-input"));
169+
user.click(await findByText("25"));
170+
171+
expect(handleSelectDate).not.toHaveBeenCalled();
172+
173+
fireEvent.click(await findByText("15"));
174+
expect(handleSelectDate).toHaveBeenCalled();
175+
});
152176
});
153177

154178
describe("predefined date ranges", () => {
@@ -160,7 +184,7 @@ describe("DateRangePicker", () => {
160184
vi.useRealTimers();
161185
});
162186

163-
it("doesn't show any preselected dates if the value isn't set", async () => {
187+
it("doesn't show any preselected dates if the predefined dates list isn't set", async () => {
164188
const handleSelectDate = vi.fn();
165189

166190
const { getByTestId, queryByTestId } = renderCUI(
@@ -172,33 +196,58 @@ describe("DateRangePicker", () => {
172196
expect(queryByTestId("predefined-dates-list")).not.toBeInTheDocument();
173197
});
174198

175-
it("shows dates in the past if the value is negative", async () => {
199+
it("shows dates in the past if getPredefinedMonthsByNumber's value is negative", async () => {
176200
const handleSelectDate = vi.fn();
177201

202+
const predefinedDatesList = getPredefinedMonthsByNumber(-6);
178203
const { getByTestId, getByText } = renderCUI(
179204
<DateRangePicker
180205
onSelectDateRange={handleSelectDate}
181-
predefinedDatesCount={-6}
206+
predefinedDatesList={predefinedDatesList}
182207
/>
183208
);
184209

185210
await userEvent.click(getByTestId("daterangepicker-input"));
186211

187-
expect(getByText("Jul 2020")).toBeInTheDocument();
212+
expect(getByText("Jul 01, 2020 - Jul 04, 2020")).toBeInTheDocument();
213+
expect(getByText("Jun 2020")).toBeInTheDocument();
214+
expect(getByText("May 2020")).toBeInTheDocument();
215+
expect(getByText("Apr 2020")).toBeInTheDocument();
216+
expect(getByText("Mar 2020")).toBeInTheDocument();
217+
expect(getByText("Feb 2020")).toBeInTheDocument();
218+
});
219+
220+
it("doesn't show a range of a single day when using the past six months and its the first of the month", async () => {
221+
vi.setSystemTime(new Date("07-01-2020"));
222+
223+
const handleSelectDate = vi.fn();
224+
225+
const predefinedDatesList = getPredefinedMonthsByNumber(-6);
226+
const { getByTestId, getByText, queryByText } = renderCUI(
227+
<DateRangePicker
228+
onSelectDateRange={handleSelectDate}
229+
predefinedDatesList={predefinedDatesList}
230+
/>
231+
);
232+
233+
await userEvent.click(getByTestId("daterangepicker-input"));
234+
235+
expect(queryByText("Jul")).not.toBeInTheDocument();
188236
expect(getByText("Jun 2020")).toBeInTheDocument();
189237
expect(getByText("May 2020")).toBeInTheDocument();
190238
expect(getByText("Apr 2020")).toBeInTheDocument();
191239
expect(getByText("Mar 2020")).toBeInTheDocument();
192240
expect(getByText("Feb 2020")).toBeInTheDocument();
193241
});
194242

195-
it("shows dates in the future if the value is positive", async () => {
243+
it("shows dates in the future if getPredefinedMonthsByNumber's value is positive", async () => {
196244
const handleSelectDate = vi.fn();
197245

246+
const predefinedDatesList = getPredefinedMonthsByNumber(6);
198247
const { getByTestId, getByText } = renderCUI(
199248
<DateRangePicker
200249
onSelectDateRange={handleSelectDate}
201-
predefinedDatesCount={6}
250+
predefinedDatesList={predefinedDatesList}
202251
/>
203252
);
204253

@@ -212,69 +261,72 @@ describe("DateRangePicker", () => {
212261
expect(getByText("Dec 2020")).toBeInTheDocument();
213262
});
214263

215-
it("allows showing the full calendar", async () => {
264+
it("shows the current current month if it's the first day of month if getPredefinedMonthsByNumber's value is positive", async () => {
265+
vi.setSystemTime(new Date("07-01-2020"));
216266
const handleSelectDate = vi.fn();
217267

218-
const { getByTestId, getByText, queryByTestId } = renderCUI(
268+
const predefinedDatesList = getPredefinedMonthsByNumber(6);
269+
const { getByTestId, getByText } = renderCUI(
219270
<DateRangePicker
220271
onSelectDateRange={handleSelectDate}
221-
predefinedDatesCount={-12}
272+
predefinedDatesList={predefinedDatesList}
222273
/>
223274
);
224275

225-
expect(queryByTestId("datepicker-calendar-container")).not.toBeInTheDocument();
226-
227276
await userEvent.click(getByTestId("daterangepicker-input"));
228-
await userEvent.click(getByText("Custom time period"));
229277

230-
expect(getByTestId("datepicker-calendar-container")).toBeInTheDocument();
278+
expect(getByText("Jul 2020")).toBeInTheDocument();
279+
expect(getByText("Aug 2020")).toBeInTheDocument();
280+
expect(getByText("Sep 2020")).toBeInTheDocument();
281+
expect(getByText("Oct 2020")).toBeInTheDocument();
282+
expect(getByText("Nov 2020")).toBeInTheDocument();
283+
expect(getByText("Dec 2020")).toBeInTheDocument();
231284
});
232285

233-
it("shows at maximum six dates in the past or future", async () => {
286+
it("allows showing the full calendar", async () => {
234287
const handleSelectDate = vi.fn();
235288

236-
const { getByTestId, getByText, queryByText } = renderCUI(
289+
const predefinedDatesList = getPredefinedMonthsByNumber(6);
290+
const { getByTestId, getByText, queryByTestId } = renderCUI(
237291
<DateRangePicker
238292
onSelectDateRange={handleSelectDate}
239-
predefinedDatesCount={-12}
293+
predefinedDatesList={predefinedDatesList}
240294
/>
241295
);
242296

243-
await userEvent.click(getByTestId("daterangepicker-input"));
297+
expect(queryByTestId("datepicker-calendar-container")).not.toBeInTheDocument();
244298

245-
expect(getByText("Jul 2020")).toBeInTheDocument();
246-
expect(getByText("Jun 2020")).toBeInTheDocument();
247-
expect(getByText("May 2020")).toBeInTheDocument();
248-
expect(getByText("Apr 2020")).toBeInTheDocument();
249-
expect(getByText("Mar 2020")).toBeInTheDocument();
250-
expect(getByText("Feb 2020")).toBeInTheDocument();
299+
await userEvent.click(getByTestId("daterangepicker-input"));
300+
await userEvent.click(getByText("Custom time period"));
251301

252-
expect(queryByText("Jan 2020")).not.toBeInTheDocument();
302+
expect(getByTestId("datepicker-calendar-container")).toBeInTheDocument();
253303
});
254304

255305
it("selects up to the current date if the current month is selected", async () => {
256306
const handleSelectDate = vi.fn();
257307

308+
const predefinedDatesList = getPredefinedMonthsByNumber(-6);
258309
const { getByTestId, getByText } = renderCUI(
259310
<DateRangePicker
260311
onSelectDateRange={handleSelectDate}
261-
predefinedDatesCount={-6}
312+
predefinedDatesList={predefinedDatesList}
262313
/>
263314
);
264315

265316
await userEvent.click(getByTestId("daterangepicker-input"));
266317

267-
await userEvent.click(getByText("Jul 2020"));
318+
await userEvent.click(getByTestId("Jul 01, 2020 - Jul 04, 2020"));
268319
expect(getByText("Jul 01, 2020 – Jul 04, 2020")).toBeInTheDocument();
269320
});
270321

271322
it("selects the full month if a date in the past or future is selected", async () => {
272323
const handleSelectDate = vi.fn();
273324

325+
const predefinedDatesList = getPredefinedMonthsByNumber(-6);
274326
const { getByTestId, getByText } = renderCUI(
275327
<DateRangePicker
276328
onSelectDateRange={handleSelectDate}
277-
predefinedDatesCount={-6}
329+
predefinedDatesList={predefinedDatesList}
278330
/>
279331
);
280332

@@ -287,10 +339,11 @@ describe("DateRangePicker", () => {
287339
it("shows the selected month if an entire month is manually selected", async () => {
288340
const handleSelectDate = vi.fn();
289341

342+
const predefinedDatesList = getPredefinedMonthsByNumber(-6);
290343
const { getByTestId, getAllByText, getByText } = renderCUI(
291344
<DateRangePicker
292345
onSelectDateRange={handleSelectDate}
293-
predefinedDatesCount={-6}
346+
predefinedDatesList={predefinedDatesList}
294347
/>
295348
);
296349

@@ -311,16 +364,17 @@ describe("DateRangePicker", () => {
311364
vi.setSystemTime(new Date("03-04-2020"));
312365
const handleSelectDate = vi.fn();
313366

367+
const predefinedDatesList = getPredefinedMonthsByNumber(-6);
314368
const { getByTestId, getByText } = renderCUI(
315369
<DateRangePicker
316370
onSelectDateRange={handleSelectDate}
317-
predefinedDatesCount={-6}
371+
predefinedDatesList={predefinedDatesList}
318372
/>
319373
);
320374

321375
await userEvent.click(getByTestId("daterangepicker-input"));
322376

323-
expect(getByText("Mar 2020")).toBeInTheDocument();
377+
expect(getByText("Mar 01, 2020 - Mar 04, 2020")).toBeInTheDocument();
324378
expect(getByText("Feb 2020")).toBeInTheDocument();
325379
expect(getByText("Jan 2020")).toBeInTheDocument();
326380
expect(getByText("Dec 2019")).toBeInTheDocument();

0 commit comments

Comments
 (0)