Skip to content

Commit 9c7d846

Browse files
authored
fix(time-picker): focus corresponding input when nudge buttons are clicked (#7650)
**Related Issue:** #7533 ## Summary This fixes an issue where clicking the up/down buttons doesn't focus the input that the buttons are changing the value of. --------- Co-authored-by: Erik Harper <[email protected]>
1 parent 73ff874 commit 9c7d846

File tree

4 files changed

+204
-21
lines changed

4 files changed

+204
-21
lines changed

packages/calcite-components/src/components/time-picker/resources.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const CSS = {
1919
fractionalSecond: "fractionalSecond",
2020
hour: "hour",
2121
input: "input",
22+
inputFocus: "inputFocus",
2223
meridiem: "meridiem",
2324
minute: "minute",
2425
second: "second",

packages/calcite-components/src/components/time-picker/time-picker.e2e.ts

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { newE2EPage } from "@stencil/core/testing";
22
import { accessible, defaults, focusable, hidden, renders, t9n } from "../../tests/commonTests";
33
import { formatTimePart } from "../../utils/time";
44
import { CSS } from "./resources";
5-
import { getElementXY } from "../../tests/utils";
5+
import { getElementXY, getFocusedElementProp } from "../../tests/utils";
66

77
const letterKeys = [
88
"a",
@@ -59,6 +59,106 @@ describe("calcite-time-picker", () => {
5959
]);
6060
});
6161

62+
describe("focusing", () => {
63+
it("should focus input when corresponding nudge up button is clicked", async () => {
64+
const page = await newE2EPage();
65+
await page.setContent(`<calcite-time-picker step=".001"></calcite-time-picker>`);
66+
67+
const minuteElAriaLabel = (await page.find(`calcite-time-picker >>> .${CSS.minute}`)).getAttribute("aria-label");
68+
const minuteUpEl = await page.find(`calcite-time-picker >>> .${CSS.buttonMinuteUp}`);
69+
70+
await minuteUpEl.click();
71+
await page.waitForChanges();
72+
73+
expect(await getFocusedElementProp(page, "ariaLabel", { shadow: true })).toEqual(minuteElAriaLabel);
74+
75+
const secondElAriaLabel = (await page.find(`calcite-time-picker >>> .${CSS.second}`)).getAttribute("aria-label");
76+
const secondUpEl = await page.find(`calcite-time-picker >>> .${CSS.buttonSecondUp}`);
77+
78+
await secondUpEl.click();
79+
await page.waitForChanges();
80+
81+
expect(await getFocusedElementProp(page, "ariaLabel", { shadow: true })).toEqual(secondElAriaLabel);
82+
83+
const fractionalSecondElAriaLabel = (
84+
await page.find(`calcite-time-picker >>> .${CSS.fractionalSecond}`)
85+
).getAttribute("aria-label");
86+
const fractionalSecondUpEl = await page.find(`calcite-time-picker >>> .${CSS.buttonFractionalSecondUp}`);
87+
88+
await fractionalSecondUpEl.click();
89+
await page.waitForChanges();
90+
91+
expect(await getFocusedElementProp(page, "ariaLabel", { shadow: true })).toEqual(fractionalSecondElAriaLabel);
92+
93+
const meridiemElAriaLabel = (await page.find(`calcite-time-picker >>> .${CSS.meridiem}`)).getAttribute(
94+
"aria-label"
95+
);
96+
const meridiemUpEl = await page.find(`calcite-time-picker >>> .${CSS.buttonMeridiemUp}`);
97+
98+
await meridiemUpEl.click();
99+
await page.waitForChanges();
100+
101+
expect(await getFocusedElementProp(page, "ariaLabel", { shadow: true })).toEqual(meridiemElAriaLabel);
102+
103+
const hourElAriaLabel = (await page.find(`calcite-time-picker >>> .${CSS.hour}`)).getAttribute("aria-label");
104+
const hourUpEl = await page.find(`calcite-time-picker >>> .${CSS.buttonHourUp}`);
105+
106+
await hourUpEl.click();
107+
await page.waitForChanges();
108+
109+
expect(await getFocusedElementProp(page, "ariaLabel", { shadow: true })).toEqual(hourElAriaLabel);
110+
});
111+
112+
it("should focus input when corresponding nudge down button is clicked", async () => {
113+
const page = await newE2EPage();
114+
await page.setContent(`<calcite-time-picker step=".001"></calcite-time-picker>`);
115+
116+
const minuteElAriaLabel = (await page.find(`calcite-time-picker >>> .${CSS.minute}`)).getAttribute("aria-label");
117+
const minuteDownEl = await page.find(`calcite-time-picker >>> .${CSS.buttonMinuteDown}`);
118+
119+
await minuteDownEl.click();
120+
await page.waitForChanges();
121+
122+
expect(await getFocusedElementProp(page, "ariaLabel", { shadow: true })).toEqual(minuteElAriaLabel);
123+
124+
const secondElAriaLabel = (await page.find(`calcite-time-picker >>> .${CSS.second}`)).getAttribute("aria-label");
125+
const secondDownEl = await page.find(`calcite-time-picker >>> .${CSS.buttonSecondDown}`);
126+
127+
await secondDownEl.click();
128+
await page.waitForChanges();
129+
130+
expect(await getFocusedElementProp(page, "ariaLabel", { shadow: true })).toEqual(secondElAriaLabel);
131+
132+
const fractionalSecondElAriaLabel = (
133+
await page.find(`calcite-time-picker >>> .${CSS.fractionalSecond}`)
134+
).getAttribute("aria-label");
135+
const fractionalSecondDownEl = await page.find(`calcite-time-picker >>> .${CSS.buttonFractionalSecondDown}`);
136+
137+
await fractionalSecondDownEl.click();
138+
await page.waitForChanges();
139+
140+
expect(await getFocusedElementProp(page, "ariaLabel", { shadow: true })).toEqual(fractionalSecondElAriaLabel);
141+
142+
const meridiemElAriaLabel = (await page.find(`calcite-time-picker >>> .${CSS.meridiem}`)).getAttribute(
143+
"aria-label"
144+
);
145+
const meridiemDownEl = await page.find(`calcite-time-picker >>> .${CSS.buttonMeridiemDown}`);
146+
147+
await meridiemDownEl.click();
148+
await page.waitForChanges();
149+
150+
expect(await getFocusedElementProp(page, "ariaLabel", { shadow: true })).toEqual(meridiemElAriaLabel);
151+
152+
const hourElAriaLabel = (await page.find(`calcite-time-picker >>> .${CSS.hour}`)).getAttribute("aria-label");
153+
const hourDownEl = await page.find(`calcite-time-picker >>> .${CSS.buttonHourDown}`);
154+
155+
await hourDownEl.click();
156+
await page.waitForChanges();
157+
158+
expect(await getFocusedElementProp(page, "ariaLabel", { shadow: true })).toEqual(hourElAriaLabel);
159+
});
160+
});
161+
62162
describe("should focus the first focusable element when setFocus is called (ltr)", () => {
63163
focusable(`calcite-time-picker`, {
64164
shadowFocusTargetSelector: `.${CSS.input}.${CSS.hour}`,

packages/calcite-components/src/components/time-picker/time-picker.scss

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,12 @@
6969
&:focus,
7070
&:hover:focus {
7171
@apply outline-none;
72+
outline-offset: 0;
73+
}
74+
&.inputFocus,
75+
&:hover.inputFocus {
7276
box-shadow: inset 0 0 0 2px var(--calcite-ui-brand);
7377
z-index: theme("zIndex.header");
74-
outline-offset: 0;
7578
}
7679
}
7780

0 commit comments

Comments
 (0)