Skip to content

Commit

Permalink
feat(input-time-picker, time-picker): add time-picker and input-time-…
Browse files Browse the repository at this point in the history
…picker components (#1736)
  • Loading branch information
eriklharper authored Jun 7, 2021
1 parent 7d71362 commit 6e4c81d
Show file tree
Hide file tree
Showing 20 changed files with 3,248 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,318 @@
import { newE2EPage } from "@stencil/core/testing";
import { accessible, defaults, focusable, reflects, renders } from "../../tests/commonTests";
import { formatTimePart } from "../../utils/time";

describe("calcite-input-time-picker", () => {
it("renders", async () => renders("calcite-input-time-picker"));

it("is accessible", async () =>
accessible(`
<label>
Input Time Picker
<calcite-input-time-picker name="test"></calcite-input-time-picker>
</label>
`));

it("has defaults", async () =>
defaults("calcite-input-time-picker", [
{ propertyName: "scale", defaultValue: "m" },
{ propertyName: "step", defaultValue: 60 }
]));

it("reflects", async () =>
reflects(`calcite-input-time-picker`, [
{ propertyName: "active", value: true },
{ propertyName: "disabled", value: true },
{ propertyName: "scale", value: "m" }
]));

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

it("opens the time picker on input keyboard focus", async () => {
const page = await newE2EPage({
html: `<calcite-input-time-picker></calcite-input-time-picker>`
});
const popover = await page.find("calcite-input-time-picker >>> calcite-popover");

await page.keyboard.press("Tab");
await page.waitForChanges();

expect(await popover.getProperty("open")).toBe(true);
});

it("opens the time picker on input click", async () => {
const page = await newE2EPage({
html: `<calcite-input-time-picker></calcite-input-time-picker>`
});
const input = await page.find("calcite-input-time-picker >>> calcite-input");
const popover = await page.find("calcite-input-time-picker >>> calcite-popover");

await input.click();
await page.waitForChanges();

expect(await popover.getProperty("open")).toBe(true);
});

it("changing hour, minute and second values reflects in the input, input-time-picker and time-picker for 24-hour display format", async () => {
const page = await newE2EPage({
html: `<calcite-input-time-picker hour-display-format="24" step="1"></calcite-input-time-picker>`
});

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

for (let second = 0; second < 10; second++) {
const date = new Date(0);
date.setSeconds(second);

const expectedValue = date.toISOString().substr(11, 8);
const expectedHour = expectedValue.substr(0, 2);
const expectedMinute = expectedValue.substr(3, 2);
const expectedSecond = expectedValue.substr(6, 2);

inputTimePicker.setProperty("value", expectedValue);

await page.waitForChanges();

const inputValue = await input.getProperty("value");
const inputTimePickerValue = await inputTimePicker.getProperty("value");
const timePickerHourValue = await timePicker.getProperty("hour");
const timePickerMinuteValue = await timePicker.getProperty("minute");
const timePickerSecondValue = await timePicker.getProperty("second");

expect(inputValue).toBe(expectedValue);
expect(inputTimePickerValue).toBe(expectedValue);
expect(timePickerHourValue).toBe(expectedHour);
expect(timePickerMinuteValue).toBe(expectedMinute);
expect(timePickerSecondValue).toBe(expectedSecond);
}

for (let minute = 0; minute < 10; minute++) {
const date = new Date(0);
date.setMinutes(minute);

const expectedValue = date.toISOString().substr(11, 8);
const expectedHour = expectedValue.substr(0, 2);
const expectedMinute = expectedValue.substr(3, 2);
const expectedSecond = expectedValue.substr(6, 2);

inputTimePicker.setProperty("value", expectedValue);

await page.waitForChanges();

const inputValue = await input.getProperty("value");
const inputTimePickerValue = await inputTimePicker.getProperty("value");
const timePickerHourValue = await timePicker.getProperty("hour");
const timePickerMinuteValue = await timePicker.getProperty("minute");
const timePickerSecondValue = await timePicker.getProperty("second");

expect(inputValue).toBe(expectedValue);
expect(inputTimePickerValue).toBe(expectedValue);
expect(timePickerHourValue).toBe(expectedHour);
expect(timePickerMinuteValue).toBe(expectedMinute);
expect(timePickerSecondValue).toBe(expectedSecond);
}

for (let hour = 0; hour < 10; hour++) {
const date = new Date(0);
date.setHours(hour);

const expectedValue = date.toISOString().substr(11, 8);
const expectedHour = expectedValue.substr(0, 2);
const expectedMinute = expectedValue.substr(3, 2);
const expectedSecond = expectedValue.substr(6, 2);

inputTimePicker.setProperty("value", expectedValue);

await page.waitForChanges();

const inputValue = await input.getProperty("value");
const inputTimePickerValue = await inputTimePicker.getProperty("value");
const timePickerHourValue = await timePicker.getProperty("hour");
const timePickerMinuteValue = await timePicker.getProperty("minute");
const timePickerSecondValue = await timePicker.getProperty("second");

expect(inputValue).toBe(expectedValue);
expect(inputTimePickerValue).toBe(expectedValue);
expect(timePickerHourValue).toBe(expectedHour);
expect(timePickerMinuteValue).toBe(expectedMinute);
expect(timePickerSecondValue).toBe(expectedSecond);
}
});

it("changing hour, minute and second values reflects in the input, input-time-picker and time-picker for 12-hour display format", async () => {
const page = await newE2EPage({
html: `<calcite-input-time-picker hour-display-format="12" step="1"></calcite-input-time-picker>`
});

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

for (let second = 0; second < 10; second++) {
const date = new Date(0);
date.setSeconds(second);

const expectedValue = date.toISOString().substr(11, 8);
const expectedHour = expectedValue.substr(0, 2);
const expectedHourAsNumber = parseInt(expectedValue.substr(0, 2));
const expectedDisplayHour =
expectedHourAsNumber > 12
? formatTimePart(expectedHourAsNumber - 12)
: expectedHourAsNumber === 0
? "12"
: formatTimePart(expectedHourAsNumber);
const expectedMinute = expectedValue.substr(3, 2);
const expectedSecond = expectedValue.substr(6, 2);

inputTimePicker.setProperty("value", expectedValue);

await page.waitForChanges();

const inputValue = await input.getProperty("value");
const inputTimePickerValue = await inputTimePicker.getProperty("value");
const timePickerHourValue = await timePicker.getProperty("hour");
const timePickerMinuteValue = await timePicker.getProperty("minute");
const timePickerSecondValue = await timePicker.getProperty("second");

expect(inputValue).toBe(expectedValue);
expect(inputTimePickerValue).toBe(expectedValue);
expect(timePickerHourValue).toBe(expectedHour);
expect(timePickerMinuteValue).toBe(expectedMinute);
expect(timePickerSecondValue).toBe(expectedSecond);
}

for (let minute = 0; minute < 10; minute++) {
const date = new Date(0);
date.setMinutes(minute);

const expectedValue = date.toISOString().substr(11, 8);
const expectedHour = expectedValue.substr(0, 2);
const expectedHourAsNumber = parseInt(expectedValue.substr(0, 2));
const expectedDisplayHour =
expectedHourAsNumber > 12
? formatTimePart(expectedHourAsNumber - 12)
: expectedHourAsNumber === 0
? "12"
: formatTimePart(expectedHourAsNumber);
const expectedMinute = expectedValue.substr(3, 2);
const expectedSecond = expectedValue.substr(6, 2);

inputTimePicker.setProperty("value", expectedValue);

await page.waitForChanges();

const inputValue = await input.getProperty("value");
const inputTimePickerValue = await inputTimePicker.getProperty("value");
const timePickerHourValue = await timePicker.getProperty("hour");
const timePickerMinuteValue = await timePicker.getProperty("minute");
const timePickerSecondValue = await timePicker.getProperty("second");

expect(inputValue).toBe(expectedValue);
expect(inputTimePickerValue).toBe(expectedValue);
expect(timePickerHourValue).toBe(expectedHour);
expect(timePickerMinuteValue).toBe(expectedMinute);
expect(timePickerSecondValue).toBe(expectedSecond);
}

for (let hour = 0; hour < 10; hour++) {
const date = new Date(0);
date.setHours(hour);

const expectedValue = date.toISOString().substr(11, 8);
const expectedHour = expectedValue.substr(0, 2);
const expectedHourAsNumber = parseInt(expectedValue.substr(0, 2));
const expectedDisplayHour =
expectedHourAsNumber > 12
? formatTimePart(expectedHourAsNumber - 12)
: expectedHourAsNumber === 0
? "12"
: formatTimePart(expectedHourAsNumber);
const expectedMinute = expectedValue.substr(3, 2);
const expectedSecond = expectedValue.substr(6, 2);

inputTimePicker.setProperty("value", expectedValue);

await page.waitForChanges();

const inputValue = await input.getProperty("value");
const inputTimePickerValue = await inputTimePicker.getProperty("value");
const timePickerHourValue = await timePicker.getProperty("hour");
const timePickerMinuteValue = await timePicker.getProperty("minute");
const timePickerSecondValue = await timePicker.getProperty("second");

expect(inputValue).toBe(expectedValue);
expect(inputTimePickerValue).toBe(expectedValue);
expect(timePickerHourValue).toBe(expectedHour);
expect(timePickerMinuteValue).toBe(expectedMinute);
expect(timePickerSecondValue).toBe(expectedSecond);
}
});

it("appropriately triggers calciteInputTimePickerChange event when the user types a value", async () => {
const page = await newE2EPage();
await page.setContent(`<calcite-input-time-picker step="1"></calcite-input-time-picker>`);

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

expect(changeEvent).toHaveReceivedEventTimes(0);

await page.keyboard.press("Tab");
await page.keyboard.press("1");
await page.keyboard.press(":");
await page.keyboard.press("2");

await page.waitForChanges();

expect(changeEvent).toHaveReceivedEventTimes(1);

await page.keyboard.press(":");
await page.keyboard.press("3");

await page.waitForChanges();

expect(changeEvent).toHaveReceivedEventTimes(2);
});

it("formats valid typed time value appropriately on blur", async () => {
const page = await newE2EPage();
await page.setContent(`<calcite-input-time-picker step="1"></calcite-input-time-picker><input>`);

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

await page.keyboard.press("Tab");
await page.keyboard.type("2:3:4");
await page.keyboard.press("Tab");
await page.waitForChanges();

expect(await inputTimePicker.getProperty("value")).toBe("02:03:04");
});

it("resets to previous value when default event behavior is prevented", async () => {
const page = await newE2EPage({
html: `<calcite-input-time-picker value="14:59"></calcite-input-time-picker>`
});
const inputTimePicker = await page.find("calcite-input-time-picker");

await page.evaluate(() => {
const inputTimePicker = document.querySelector("calcite-input-time-picker");
inputTimePicker.addEventListener("calciteInputTimePickerChange", (event) => {
event.preventDefault();
});
});

expect(await inputTimePicker.getProperty("value")).toBe("14:59");

await page.keyboard.press("Tab");
await page.keyboard.press(":");
await page.keyboard.press("5");
await page.waitForChanges();

expect(await inputTimePicker.getProperty("value")).toBe("14:59");
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:host {
@apply inline-block
select-none;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { number, select, text } from "@storybook/addon-knobs";
import { boolean } from "../../../.storybook/helpers";
import { darkBackground } from "../../../.storybook/utils";
import readme from "./readme.md";
import { html } from "../../tests/utils";

export default {
title: "Components/Controls/Time/Input Time Picker",

parameters: {
notes: readme
}
};

export const LightTheme = (): string => html`
<calcite-input-time-picker
${boolean("disabled", false)}
${boolean("hidden", false)}
hour-display-format="${select("hour-display-format", ["12", "24"], "12")}"
name="${text("name", "light")}"
scale="${select("scale", ["s", "m", "l"], "m")}"
step="${number("step", 1)}"
value="${text("value", "10:37")}"
>
</calcite-input-time-picker>
`;

export const DarkTheme = (): string => html`
<calcite-input-time-picker
${boolean("disabled", false)}
${boolean("hidden", false)}
class="calcite-theme-dark"
hour-display-format="${select("hour-display-format", ["12", "24"], "12")}"
name="${text("name", "dark")}"
scale="${select("scale", ["s", "m", "l"], "m")}"
step="${number("step", 1)}"
value="${text("value", "22:37")}"
>
</calcite-input-time-picker>
`;

DarkTheme.story = {
parameters: { backgrounds: darkBackground }
};
Loading

0 comments on commit 6e4c81d

Please sign in to comment.