Skip to content

Commit bfa5477

Browse files
committed
update date picker
1 parent 34b2189 commit bfa5477

26 files changed

+637
-381
lines changed

.changeset/full-peaches-yawn.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@salt-ds/lab": patch
3+
---
4+
5+
DatePicker updates
6+
7+
- fixed a bug where a disabled datepicker could still open the datepicker by clicking the input
8+
- improved screen reader support
9+
-

packages/lab/src/__tests__/__e2e__/date-picker/DatePicker.range.cy.tsx

Lines changed: 85 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,41 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
5353
});
5454

5555
it("SHOULD show calendar overlay when click the calendar icon button", () => {
56-
cy.mount(<Range />);
56+
cy.mount(<RangeControlled />);
57+
cy.findByRole("button", { name: "Open Calendar" }).should(
58+
"have.attr",
59+
"aria-expanded",
60+
"false",
61+
);
5762

5863
// Simulate opening the calendar
5964
cy.findByRole("button", { name: "Open Calendar" }).realClick();
6065
// Verify that the calendar is displayed
6166
cy.findAllByRole("application").should("have.length", 2);
67+
// cy.get used as we query elements which are non-visible when dialog is open
68+
cy.get('button[aria-label="Open Calendar"]')
69+
.should("exist")
70+
.and("have.attr", "aria-expanded", "true");
6271
});
6372

6473
it("SHOULD open calendar overlay when using down arrow", () => {
6574
cy.mount(<Range />);
75+
cy.findByRole("button", { name: "Open Calendar" }).should(
76+
"have.attr",
77+
"aria-expanded",
78+
"false",
79+
);
6680

6781
cy.findAllByRole("textbox")
6882
.eq(0)
6983
.click()
7084
.type("{downArrow}", { force: true });
7185
// Verify that the calendar is displayed
7286
cy.findAllByRole("application").should("have.length", 2);
87+
// cy.get used as we query elements which are non-visible when dialog is open
88+
cy.get('button[aria-label="Open Calendar"]')
89+
.should("exist")
90+
.and("have.attr", "aria-expanded", "true");
7391
});
7492

7593
it("SHOULD be able to enable the overlay to open on click", () => {
@@ -84,6 +102,16 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
84102
cy.findAllByRole("application").should("have.length", 2);
85103
});
86104

105+
it("SHOULD NOT be able to enable the overlay to open on click, if disabled", () => {
106+
cy.mount(<Range openOnClick disabled />);
107+
cy.findByRole("application").should("not.exist");
108+
// Simulate opening the calendar on click
109+
cy.findByLabelText("Start date").realClick();
110+
cy.findByRole("application").should("not.exist");
111+
cy.findByLabelText("End date").realClick();
112+
cy.findByRole("application").should("not.exist");
113+
});
114+
87115
it("SHOULD hide calendar upon focus out", () => {
88116
cy.mount(<Range />);
89117

@@ -200,7 +228,7 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
200228
cy.findAllByRole("application").should("have.length", 2);
201229
// Verify the first element focused in the first calendar is the start date
202230
cy.findByRole("button", {
203-
name: adapter.format(initialRangeDate.startDate, "DD MMMM YYYY"),
231+
name: `Start selected range: ${adapter.format(initialRangeDate.startDate, "dddd D MMMM YYYY")}`,
204232
}).should("be.focused");
205233
// Simulate tabbing to the next calendar
206234
cy.realPress("Tab");
@@ -220,7 +248,7 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
220248
"month",
221249
);
222250
cy.findByRole("button", {
223-
name: adapter.format(startOfEndCalendar, "DD MMMM YYYY"),
251+
name: `Start new range: ${adapter.format(startOfEndCalendar, "dddd D MMMM YYYY")}`,
224252
}).should("be.focused");
225253
// Simulate tabbing back to the first calendar
226254
cy.realPress("Tab");
@@ -236,7 +264,7 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
236264
cy.realPress("Tab");
237265
// Verify focus returns to the first focused element in the first calendar
238266
cy.findByRole("button", {
239-
name: adapter.format(initialRangeDate.startDate, "DD MMMM YYYY"),
267+
name: `Start selected range: ${adapter.format(initialRangeDate.startDate, "dddd D MMMM YYYY")}`,
240268
}).should("be.focused");
241269
// Simulate closing the overlay
242270
cy.realPress("Escape");
@@ -272,48 +300,48 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
272300
cy.findAllByRole("application").should("have.length", 2);
273301
// Verify that dates outside the min/max range are disabled
274302
cy.findByRole("button", {
275-
name: "14 January 2030",
303+
name: "Monday 14 January 2030",
276304
}).should("have.attr", "aria-disabled", "true");
277305
// Verify the navigation controls do not allow to navigate beyond the min/max
278-
cy.findAllByLabelText("Previous Month")
306+
cy.findAllByLabelText("Past dates are out of range")
279307
.eq(0)
280308
.should("have.attr", "aria-disabled", "true");
281309
cy.findAllByLabelText("Next Month")
282310
.eq(0)
283311
.should("not.have.attr", "aria-disabled", "true");
284312
cy.findAllByLabelText("Previous Month")
285-
.eq(1)
313+
.eq(0)
286314
.should("not.have.attr", "aria-disabled", "true");
287-
cy.findAllByLabelText("Next Month")
288-
.eq(1)
315+
cy.findAllByLabelText("Future dates are out of range")
316+
.eq(0)
289317
.should("have.attr", "aria-disabled", "true");
290318
// Verify first selectable date in range is focused
291319
cy.findByRole("button", {
292-
name: "15 January 2030",
320+
name: "Start new range: Tuesday 15 January 2030",
293321
}).should("be.focused");
294322
cy.findByRole("button", {
295-
name: "15 January 2030",
323+
name: "Start new range: Tuesday 15 January 2030",
296324
}).should("not.have.attr", "aria-disabled", "true");
297325
cy.findByRole("button", {
298-
name: "15 January 2031",
326+
name: "Start new range: Tuesday 15 January 2030",
299327
}).should("not.have.attr", "aria-disabled", "true");
300328
cy.findByRole("button", {
301-
name: "16 January 2031",
329+
name: "Thursday 16 January 2031",
302330
}).should("have.attr", "aria-disabled", "true");
303331
// Simulate selecting a date outside the min/max range
304332
cy.findByRole("button", {
305-
name: "14 January 2030",
333+
name: "Monday 14 January 2030",
306334
})
307335
.realHover()
308336
.realClick();
309337
cy.findAllByRole("application").should("have.length", 2);
310338
cy.get("@selectionChangeSpy").should("not.have.been.called");
311339
// Simulate selecting a date within the min/max range
312340
cy.findByRole("button", {
313-
name: "15 January 2030",
341+
name: "Tuesday 15 January 2030, minimum date",
314342
}).realClick();
315343
cy.findByRole("button", {
316-
name: "15 January 2031",
344+
name: "Wednesday 15 January 2031, maximum date",
317345
}).realClick();
318346
// Verify that the calendar is closed and the selected dates are displayed
319347
cy.findByRole("application").should("not.exist");
@@ -578,7 +606,7 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
578606
// Verify that the calendar is displayed
579607
cy.findAllByRole("application").should("have.length", 2);
580608
// Simulate selecting a tenor option
581-
cy.findByRole("option", {
609+
cy.findByRole("button", {
582610
name: "15 years",
583611
})
584612
.realHover()
@@ -633,10 +661,10 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
633661
cy.findAllByRole("application").should("have.length", 2);
634662
// Simulate selecting an unconfirmed date
635663
cy.findByRole("button", {
636-
name: "15 January 2025",
664+
name: "Wednesday 15 January 2025",
637665
}).realClick();
638666
cy.findByRole("button", {
639-
name: "16 January 2025",
667+
name: "Thursday 16 January 2025",
640668
}).realClick();
641669
cy.findAllByRole("application").should("have.length", 2);
642670
cy.findByLabelText("Start date").should("have.value", "15 Jan 2025");
@@ -654,7 +682,9 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
654682
);
655683
});
656684
// Simulate clicking the "Cancel" button
657-
cy.findByRole("button", { name: "Cancel" }).realClick();
685+
cy.findByRole("button", {
686+
name: "Cancel Wednesday 15 January 2025 to Thursday 16 January 2025",
687+
}).realClick();
658688
// Verify that the calendar is closed and the initial selected dates are restored
659689
cy.findByRole("application").should("not.exist");
660690
cy.get("@appliedDateSpy").should("not.have.been.called");
@@ -685,11 +715,11 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
685715
cy.findAllByRole("application").should("have.length", 2);
686716
// Simulate selecting a new date range
687717
cy.findByRole("button", {
688-
name: "15 January 2025",
718+
name: "Wednesday 15 January 2025",
689719
}).realClick();
690720
cy.findAllByRole("application").should("have.length", 2);
691721
cy.findByRole("button", {
692-
name: "16 January 2025",
722+
name: "Thursday 16 January 2025",
693723
}).realClick();
694724
// Verify that the new date range is displayed
695725
cy.findByLabelText("Start date").should("have.value", "15 Jan 2025");
@@ -708,7 +738,9 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
708738
});
709739
cy.findAllByRole("application").should("have.length", 2);
710740
// Simulate clicking the "Apply" button
711-
cy.findByRole("button", { name: "Apply" }).realClick();
741+
cy.findByRole("button", {
742+
name: "Apply Wednesday 15 January 2025 to Thursday 16 January 2025",
743+
}).realClick();
712744
// Verify that the calendar is closed and the new date range is applied
713745
cy.findByRole("application").should("not.exist");
714746
// biome-ignore lint/suspicious/noExplicitAny: spy
@@ -889,15 +921,15 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
889921
cy.findAllByRole("application").should("have.length", 2);
890922
//Verify the start date is focused
891923
cy.findByRole("button", {
892-
name: adapter.format(initialRangeDate.startDate, "DD MMMM YYYY"),
924+
name: `Start selected range: ${adapter.format(initialRangeDate.startDate, "dddd D MMMM YYYY")}`,
893925
}).should("be.focused");
894926
// Verify that the default selected dates are highlighted in the calendar
895927
cy.findByRole("button", {
896-
name: "05 January 2025",
897-
}).should("have.attr", "aria-pressed", "true");
928+
name: "Start selected range: Sunday 5 January 2025",
929+
}).should("exist");
898930
cy.findByRole("button", {
899-
name: "06 January 2025",
900-
}).should("have.attr", "aria-pressed", "true");
931+
name: "End selected range: Monday 6 January 2025",
932+
}).should("exist");
901933
});
902934

903935
it("SHOULD not be able to select un-selectable dates", () => {
@@ -917,7 +949,16 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
917949
cy.findAllByRole("application").should("have.length", 2);
918950

919951
while (currentDate <= endDate) {
920-
const formattedDate = adapter.format(currentDate, "DD MMMM YYYY");
952+
let formattedDate = adapter.format(currentDate, "dddd D MMMM YYYY");
953+
if (
954+
adapter.isSame(currentDate, initialRangeDate.startDate, "day")
955+
) {
956+
formattedDate = `Start selected range: ${adapter.format(currentDate, "dddd D MMMM YYYY")}`;
957+
} else if (
958+
adapter.isSame(currentDate, initialRangeDate.endDate, "day")
959+
) {
960+
formattedDate = `End selected range: ${adapter.format(currentDate, "dddd D MMMM YYYY")}`;
961+
}
921962
const dayOfWeek = adapter.getDayOfWeek(currentDate);
922963
const isWeekend =
923964
(adapter.lib === "luxon" &&
@@ -953,19 +994,19 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
953994
cy.findAllByRole("application").should("have.length", 2);
954995
// Simulate selecting a new start date
955996
cy.findByRole("button", {
956-
name: "15 January 2025",
997+
name: "Wednesday 15 January 2025",
957998
}).should("exist");
958999
cy.findByRole("button", {
959-
name: "15 January 2025",
1000+
name: "Wednesday 15 January 2025",
9601001
}).realClick();
9611002
// Verify that the new date range resets the end date, whilst the calendar is open
9621003
cy.findByLabelText("End date").should("have.value", "");
9631004
// Simulate selecting a new end date
9641005
cy.findByRole("button", {
965-
name: "16 January 2025",
1006+
name: "Thursday 16 January 2025",
9661007
}).should("exist");
9671008
cy.findByRole("button", {
968-
name: "16 January 2025",
1009+
name: "Thursday 16 January 2025",
9691010
}).realClick();
9701011
// Verify that the calendar is closed and the new date range is displayed
9711012
cy.findByRole("application").should("not.exist");
@@ -996,20 +1037,20 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
9961037
cy.findAllByRole("application").should("have.length", 2);
9971038
//Verify the start date is focused
9981039
cy.findByRole("button", {
999-
name: adapter.format(initialRangeDate.startDate, "DD MMMM YYYY"),
1040+
name: `Start selected range: ${adapter.format(initialRangeDate.startDate, "dddd D MMMM YYYY")}`,
10001041
}).should("be.focused");
10011042
// Verify that the selected dates are highlighted in the calendar
10021043
cy.findByRole("button", {
1003-
name: "05 January 2025",
1004-
}).should("have.attr", "aria-pressed", "true");
1044+
name: "Start selected range: Sunday 5 January 2025",
1045+
}).should("exist");
10051046
cy.findByRole("button", {
1006-
name: "06 January 2025",
1007-
}).should("have.attr", "aria-pressed", "true");
1047+
name: "End selected range: Monday 6 January 2025",
1048+
}).should("exist");
10081049
cy.findByRole("button", {
1009-
name: "01 January 2025",
1050+
name: "Wednesday 1 January 2025",
10101051
}).realClick();
10111052
cy.findByRole("button", {
1012-
name: "02 January 2025",
1053+
name: "Thursday 2 January 2025",
10131054
}).realClick();
10141055

10151056
// Reset/set programatically
@@ -1046,19 +1087,19 @@ describe("GIVEN a DatePicker where selectionVariant is range", () => {
10461087
cy.findAllByRole("application").should("have.length", 2);
10471088
// Simulate selecting a new start date
10481089
cy.findByRole("button", {
1049-
name: "15 January 2025",
1090+
name: "Wednesday 15 January 2025",
10501091
}).should("exist");
10511092
cy.findByRole("button", {
1052-
name: "15 January 2025",
1093+
name: "Wednesday 15 January 2025",
10531094
}).realClick();
10541095
// Verify that the new date range resets the end date, whilst the calendar is open
10551096
cy.findByLabelText("End date").should("have.value", "");
10561097
// Simulate selecting a new end date
10571098
cy.findByRole("button", {
1058-
name: "16 January 2025",
1099+
name: "Thursday 16 January 2025",
10591100
}).should("exist");
10601101
cy.findByRole("button", {
1061-
name: "16 January 2025",
1102+
name: "Thursday 16 January 2025",
10621103
}).realClick();
10631104
// Verify that the calendar is closed and the new date range is displayed
10641105
cy.findByRole("application").should("not.exist");

0 commit comments

Comments
 (0)