Skip to content

Commit

Permalink
fix(input-date-picker, input-time-picker): focus input element on `se…
Browse files Browse the repository at this point in the history
…tFocus` (#9584)

**Related Issue:**
#9491

## Summary

Focuses input element on `setFocus` method.
  • Loading branch information
anveshmekala authored Jun 17, 2024
1 parent 5d9509b commit c7b8a68
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 11 deletions.
84 changes: 84 additions & 0 deletions packages/calcite-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,46 @@ export namespace Components {
*/
"startDate"?: Date;
}
interface CalciteDatePickerMonthFloatingMenu {
/**
* Active date
*/
"activeDate": Date;
/**
* Defines the available placements that can be used when a flip occurs.
*/
"flipPlacements": FlipPlacement[];
/**
* CLDR locale data for translated calendar info.
*/
"localeData": DateLocaleData;
/**
* When `true`, month will be abbreviated.
*/
"monthAbbreviations": boolean;
/**
* Whether the component is opened.
*/
"open": boolean;
/**
* Determines the type of positioning to use for the overlaid content. Using `"absolute"` will work for most cases. The component will be positioned inside of overflowing parent containers and will affect the container's layout. `"fixed"` should be used to escape an overflowing parent container, or when the reference element's `position` CSS property is `"fixed"`.
*/
"overlayPositioning": OverlayPositioning;
/**
* Specifies the placement of the `calcite-date-picker` relative to the component.
* @default "bottom-start"
*/
"placement": MenuPlacement;
/**
* Specifies the position of the component in a range date-picker.
*/
"position": "start" | "end";
/**
* Updates the position of the component.
* @param delayed
*/
"reposition": (delayed?: boolean) => Promise<void>;
}
interface CalciteDatePickerMonthHeader {
/**
* The focused date is indicated and will become the selected date if the user proceeds.
Expand Down Expand Up @@ -6499,6 +6539,12 @@ declare global {
prototype: HTMLCalciteDatePickerMonthElement;
new (): HTMLCalciteDatePickerMonthElement;
};
interface HTMLCalciteDatePickerMonthFloatingMenuElement extends Components.CalciteDatePickerMonthFloatingMenu, HTMLStencilElement {
}
var HTMLCalciteDatePickerMonthFloatingMenuElement: {
prototype: HTMLCalciteDatePickerMonthFloatingMenuElement;
new (): HTMLCalciteDatePickerMonthFloatingMenuElement;
};
interface HTMLCalciteDatePickerMonthHeaderElementEventMap {
"calciteInternalDatePickerSelect": Date;
}
Expand Down Expand Up @@ -7836,6 +7882,7 @@ declare global {
"calcite-date-picker": HTMLCalciteDatePickerElement;
"calcite-date-picker-day": HTMLCalciteDatePickerDayElement;
"calcite-date-picker-month": HTMLCalciteDatePickerMonthElement;
"calcite-date-picker-month-floating-menu": HTMLCalciteDatePickerMonthFloatingMenuElement;
"calcite-date-picker-month-header": HTMLCalciteDatePickerMonthHeaderElement;
"calcite-dropdown": HTMLCalciteDropdownElement;
"calcite-dropdown-group": HTMLCalciteDropdownGroupElement;
Expand Down Expand Up @@ -9415,6 +9462,41 @@ declare namespace LocalJSX {
*/
"startDate"?: Date;
}
interface CalciteDatePickerMonthFloatingMenu {
/**
* Active date
*/
"activeDate"?: Date;
/**
* Defines the available placements that can be used when a flip occurs.
*/
"flipPlacements"?: FlipPlacement[];
/**
* CLDR locale data for translated calendar info.
*/
"localeData"?: DateLocaleData;
/**
* When `true`, month will be abbreviated.
*/
"monthAbbreviations"?: boolean;
/**
* Whether the component is opened.
*/
"open"?: boolean;
/**
* Determines the type of positioning to use for the overlaid content. Using `"absolute"` will work for most cases. The component will be positioned inside of overflowing parent containers and will affect the container's layout. `"fixed"` should be used to escape an overflowing parent container, or when the reference element's `position` CSS property is `"fixed"`.
*/
"overlayPositioning"?: OverlayPositioning;
/**
* Specifies the placement of the `calcite-date-picker` relative to the component.
* @default "bottom-start"
*/
"placement"?: MenuPlacement;
/**
* Specifies the position of the component in a range date-picker.
*/
"position"?: "start" | "end";
}
interface CalciteDatePickerMonthHeader {
/**
* The focused date is indicated and will become the selected date if the user proceeds.
Expand Down Expand Up @@ -13782,6 +13864,7 @@ declare namespace LocalJSX {
"calcite-date-picker": CalciteDatePicker;
"calcite-date-picker-day": CalciteDatePickerDay;
"calcite-date-picker-month": CalciteDatePickerMonth;
"calcite-date-picker-month-floating-menu": CalciteDatePickerMonthFloatingMenu;
"calcite-date-picker-month-header": CalciteDatePickerMonthHeader;
"calcite-dropdown": CalciteDropdown;
"calcite-dropdown-group": CalciteDropdownGroup;
Expand Down Expand Up @@ -13898,6 +13981,7 @@ declare module "@stencil/core" {
"calcite-date-picker": LocalJSX.CalciteDatePicker & JSXBase.HTMLAttributes<HTMLCalciteDatePickerElement>;
"calcite-date-picker-day": LocalJSX.CalciteDatePickerDay & JSXBase.HTMLAttributes<HTMLCalciteDatePickerDayElement>;
"calcite-date-picker-month": LocalJSX.CalciteDatePickerMonth & JSXBase.HTMLAttributes<HTMLCalciteDatePickerMonthElement>;
"calcite-date-picker-month-floating-menu": LocalJSX.CalciteDatePickerMonthFloatingMenu & JSXBase.HTMLAttributes<HTMLCalciteDatePickerMonthFloatingMenuElement>;
"calcite-date-picker-month-header": LocalJSX.CalciteDatePickerMonthHeader & JSXBase.HTMLAttributes<HTMLCalciteDatePickerMonthHeaderElement>;
"calcite-dropdown": LocalJSX.CalciteDropdown & JSXBase.HTMLAttributes<HTMLCalciteDropdownElement>;
"calcite-dropdown-group": LocalJSX.CalciteDropdownGroup & JSXBase.HTMLAttributes<HTMLCalciteDropdownGroupElement>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
openClose,
renders,
t9n,
focusable,
} from "../../tests/commonTests";
import { html } from "../../../support/formatting";
import { CSS as MONTH_HEADER_CSS } from "../date-picker-month-header/resources";
Expand Down Expand Up @@ -76,6 +77,12 @@ describe("calcite-input-date-picker", () => {
t9n("calcite-input-date-picker");
});

describe("should focus the input when setFocus is called", () => {
focusable(`calcite-input-date-picker`, {
shadowFocusTargetSelector: "calcite-input-text",
});
});

async function navigateMonth(page: E2EPage, direction: "previous" | "next"): Promise<void> {
const linkIndex = direction === "previous" ? 0 : 1;

Expand Down Expand Up @@ -717,7 +724,6 @@ describe("calcite-input-date-picker", () => {
});

describe("cross-century date values", () => {

async function assertCenturyDateValue(year: number, timezone?: string) {
const initialValue = `${year}-03-12`;
const page = await newE2EPage();
Expand Down Expand Up @@ -748,7 +754,7 @@ describe("calcite-input-date-picker", () => {

it("sets value to the clicked day in the 1800s in Zurich timezone", async () => {
await assertCenturyDateValue(1850, "Europe/Zurich");
});
});
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,17 @@ export const widthSetToBreakpoints_TestOnly = (): string =>
createBreakpointStories(
html`<calcite-input-date-picker scale="{scale}" value="2020-12-12"></calcite-input-date-picker>`,
);

export const Focus = (): string =>
html`<calcite-input-date-picker></calcite-input-date-picker>
<script>
(async () => {
await customElements.whenDefined("calcite-input-date-picker");
const inputDatePicker = await document.querySelector("calcite-input-date-picker").componentOnReady();
await inputDatePicker.setFocus();
})();
</script>`;

Focus.parameters = {
chromatic: { delay: 2000 },
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
dateToISO,
inRange,
} from "../../utils/date";
import { toAriaBoolean } from "../../utils/dom";
import { focusFirstTabbable, toAriaBoolean } from "../../utils/dom";
import {
connectFloatingUI,
defaultMenuPlacement,
Expand Down Expand Up @@ -429,7 +429,7 @@ export class InputDatePicker
@Method()
async setFocus(): Promise<void> {
await componentFocusable(this);
this.el.focus();
focusFirstTabbable(this.el);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -630,15 +630,14 @@ describe("calcite-input-time-picker", () => {
await page.setContent(`<calcite-input-time-picker step="1" value="14:00:00"></calcite-input-time-picker>`);

const inputTimePicker = await page.find("calcite-input-time-picker");

await inputTimePicker.callMethod("setFocus");
await page.waitForChanges();
await page.keyboard.press("ArrowLeft");
await page.keyboard.press("ArrowRight");
await page.keyboard.press("ArrowRight");
await page.keyboard.press("ArrowRight");
await page.keyboard.press("ArrowRight");
await page.keyboard.press("ArrowRight");
await page.keyboard.press("ArrowLeft");
await page.keyboard.press("ArrowLeft");
await page.keyboard.press("ArrowLeft");
await page.keyboard.press("ArrowLeft");
await page.keyboard.press("ArrowLeft");
await page.keyboard.press("Backspace");
await page.keyboard.press("5");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,17 @@ export const validationMessageAllScales_TestOnly = (): string => html`

export const widthSetToBreakpoints_TestOnly = (): string =>
createBreakpointStories(html`<calcite-input-time-picker scale="{scale}" value="12:34"></calcite-input-time-picker>`);

export const Focus = (): string =>
html`<calcite-input-time-picker></calcite-input-time-picker>
<script>
(async () => {
await customElements.whenDefined("calcite-input-time-picker");
const inputDatePicker = await document.querySelector("calcite-input-time-picker").componentOnReady();
await inputDatePicker.setFocus();
})();
</script>`;

Focus.parameters = {
chromatic: { delay: 2000 },
};
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import { onToggleOpenCloseComponent, OpenCloseComponent } from "../../utils/open
import { decimalPlaces } from "../../utils/math";
import { getIconScale } from "../../utils/component";
import { Validation } from "../functional/Validation";
import { focusFirstTabbable } from "../../utils/dom";
import { CSS } from "./resources";
import { InputTimePickerMessages } from "./assets/input-time-picker/t9n";

Expand Down Expand Up @@ -523,7 +524,7 @@ export class InputTimePicker
@Method()
async setFocus(): Promise<void> {
await componentFocusable(this);
this.el.focus();
focusFirstTabbable(this.el);
}

/**
Expand Down

0 comments on commit c7b8a68

Please sign in to comment.