Skip to content

Commit

Permalink
✨ - feat: add new Date(Range)Input components
Browse files Browse the repository at this point in the history
  • Loading branch information
svenvandescheur committed Oct 8, 2024
1 parent c09eafc commit 19fe611
Show file tree
Hide file tree
Showing 25 changed files with 1,316 additions and 34 deletions.
18 changes: 12 additions & 6 deletions src/components/form/.storybook/decorators.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
import { Decorator } from "@storybook/react";
import * as React from "react";
import { useState } from "react";
import { useEffect, useRef, useState } from "react";



import { serializeForm } from "../../../lib";


export const FORM_TEST_DECORATOR: Decorator = (Story) => {
// Solely here to force re-rendering story on change.
const [count, setCount] = useState(0);
const formRef = useRef<HTMLFormElement>(null);

useEffect(() => {
const update = () => setCount(count + 1);
formRef.current?.addEventListener("change", update);
return () => formRef.current?.removeEventListener("change", update);
}, [formRef.current, count]);

const getData = () => {
const form = document.forms[0];
return form && serializeForm(form);
};

return (
<form
onChange={() => setCount(count + 1)}
aria-label="form"
style={{ width: "100%" }}
>
<form ref={formRef} aria-label="form" style={{ width: "100%" }}>
<Story />
<pre role="log">{JSON.stringify(getData())}</pre>
</form>
Expand Down
36 changes: 36 additions & 0 deletions src/components/form/dateinput/dateinput.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.mykn-dateinput {
display: inline-flex;

&__input[aria-hidden="true"] {
opacity: 0;
position: absolute;
visibility: hidden;
z-index: -10;
}

.mykn-input {
box-sizing: content-box;
text-align: center;
width: 2em !important;
}

.mykn-input:focus {
z-index: 10;
}

.mykn-input[data-section="YY"] {
width: 3em !important;
}

.mykn-input:has(+ .mykn-input) {
border-start-end-radius: 0;
border-end-end-radius: 0;
border-inline-end-style: dashed;
}

.mykn-input + .mykn-input {
border-inline-start: none;
border-start-start-radius: 0;
border-end-start-radius: 0;
}
}
100 changes: 100 additions & 0 deletions src/components/form/dateinput/dateinput.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import type { Meta, StoryObj } from "@storybook/react";
import { expect, userEvent, within } from "@storybook/test";

import { FORM_TEST_DECORATOR } from "../.storybook/decorators";
import { DateInput } from "./dateinput";

const meta = {
title: "Form/DateInput",
component: DateInput,
} satisfies Meta<typeof DateInput>;

export default meta;
type Story = StoryObj<typeof meta>;

export const DateInputComponent: Story = {
args: {
name: "date",
},
};

export const SeparatedInputs: Story = {
args: {
name: "date",
format: "DDMMYYYY",
},
decorators: [FORM_TEST_DECORATOR],
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const log = canvas.getByRole("log");

const day = await canvas.getAllByRole("textbox")[0];
const month = await canvas.getAllByRole("textbox")[1];
const year = await canvas.getAllByRole("textbox")[2];

await userEvent.type(day, "15", { delay: 60 });
await userEvent.type(month, "09", { delay: 60 });
await userEvent.type(year, "2023", { delay: 60 });

await expect(JSON.parse(log.textContent || "{}").date).toBe("2023-09-15");
},
};

export const ContinuousTyping: Story = {
args: {
name: "date",
format: "DDMMYYYY",
},
decorators: [FORM_TEST_DECORATOR],
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const log = canvas.getByRole("log");

const input = await canvas.getAllByRole("textbox")[0];

await userEvent.type(input, "15092023", { delay: 60 });
await expect(JSON.parse(log.textContent || "{}").date).toBe("2023-09-15");
},
};

export const ClearSections: Story = {
args: {
name: "date",
format: "DDMMYYYY",
value: "2023-09-15",
},
decorators: [FORM_TEST_DECORATOR],
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const day = await canvas.getAllByRole("textbox")[0];
const year = await canvas.getAllByRole("textbox")[2];
const log = canvas.getByRole("log");

await userEvent.click(year);
await userEvent.keyboard("{Backspace}", { delay: 60 });
await userEvent.keyboard("{Backspace}", { delay: 60 });
await userEvent.keyboard("{Backspace}", { delay: 60 });

await expect(document.activeElement).toBe(day);
await userEvent.type(day, "02081988", { delay: 60 });
await expect(JSON.parse(log.textContent || "{}").date).toBe("1988-08-02");
},
};

export const IsoFormat: Story = {
args: {
name: "date",
format: "YYYYMMDD",
value: "2023-09-15",
},
decorators: [FORM_TEST_DECORATOR],
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const log = canvas.getByRole("log");

const input = await canvas.getAllByRole("textbox")[0];

await userEvent.type(input, "20230915", { delay: 60 });
await expect(JSON.parse(log.textContent || "{}").date).toBe("2023-09-15");
},
};
41 changes: 41 additions & 0 deletions src/components/form/dateinput/dateinput.translations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Define the structure of a single message descriptor
import { defineMessages } from "../../../lib";

export const TRANSLATIONS = defineMessages({
LABEL_DATE: {
id: "mykn.components.DateInput.labelDate",
description: "mykn.components.DateInput: The date field (accessible) label",
defaultMessage: "dag van de maand",
},

LABEL_MONTH: {
id: "mykn.components.DateInput.labelMonth",
description:
"mykn.components.DateInput: The month field (accessible) label",
defaultMessage: "maand",
},

LABEL_YEAR: {
id: "mykn.components.DateInput.labelYear",
description: "mykn.components.DateInput: The year field (accessible) label",
defaultMessage: "jaar",
},

PLACEHOLDER_DATE: {
id: "mykn.components.DateInput.placeholderDate",
description: "mykn.components.DateInput: The date field placeholder",
defaultMessage: "dd",
},

PLACEHOLDER_MONTH: {
id: "mykn.components.DateInput.placeholderMonth",
description: "mykn.components.DateInput: The month field placeholder",
defaultMessage: "mm",
},

PLACEHOLDER_YEAR: {
id: "mykn.components.DateInput.placeholderYear",
description: "mykn.components.DateInput: The year field placeholder",
defaultMessage: "jjjj",
},
});
Loading

0 comments on commit 19fe611

Please sign in to comment.