import type { Meta, StoryObj } from "@storybook/react-vite"; import { Formik } from "formik"; import * as React from "react"; import { action } from "storybook/actions"; import { expect, fn, userEvent, waitFor, within } from "storybook/test"; import { FORM_TEST_DECORATOR, PAGE_DECORATOR, } from "../../../../.storybook/decorators"; import { Button } from "../../button"; import { Toolbar } from "../../toolbar"; import { Option } from "../choicefield"; import { Select } from "./select"; const meta: Meta = { title: "Form/Select", component: Select, decorators: [PAGE_DECORATOR], render: ({ name = "select", ...args }) => (



handleChange(e)} >
{JSON.stringify(values)}
)} ); }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); const select = canvas.getByRole("combobox"); userEvent.click(select, { delay: 10 }); const junior = await canvas.findByText("Junior"); userEvent.click(junior, { delay: 10 }); // Test that the FormData serialization returns the correct value. await waitFor(testFormikSerialization); async function testFormikSerialization() { const pre = await canvas.findByRole("log"); const data = JSON.parse(pre?.textContent || "{}"); await expect(data.school_year).toBe("JR"); } const clear = canvas.getByLabelText("Clear value"); await userEvent.click(clear, { delay: 10 }); }, }; const ALL_COUNTRIES: Option[] = [ { label: "Netherlands", value: "NL" }, { label: "Germany", value: "DE" }, { label: "Belgium", value: "BE" }, { label: "France", value: "FR" }, { label: "España", value: "ES" }, { label: "Côte d’Ivoire", value: "CI" }, { label: "Åland Islands", value: "AX" }, { label: "Curaçao", value: "CW" }, { label: "United Kingdom", value: "GB" }, { label: "United States", value: "US" }, { label: "Switzerland", value: "CH" }, { label: "Sweden", value: "SE" }, { label: "Norway", value: "NO" }, { label: "Denmark", value: "DK" }, { label: "Poland", value: "PL" }, { label: "Portugal", value: "PT" }, { label: "Czechia", value: "CZ" }, { label: "Slovakia", value: "SK" }, { label: "Slovenia", value: "SI" }, { label: "Türkiye", value: "TR" }, { label: "Greece", value: "GR" }, { label: "Iceland", value: "IS" }, { label: "Ireland", value: "IE" }, { label: "Italy", value: "IT" }, { label: "Austria", value: "AT" }, { label: "Romania", value: "RO" }, { label: "Bulgaria", value: "BG" }, { label: "Hungary", value: "HU" }, { label: "Lithuania", value: "LT" }, { label: "Latvia", value: "LV" }, { label: "Estonia", value: "EE" }, ]; const getSelectOptionsAsync = async (inputValue) => { await new Promise((r) => setTimeout(r, 600)); const normalize = (s: string) => s.toLowerCase(); const q = normalize(inputValue ?? ""); const filtered = ALL_COUNTRIES.filter((o) => { const label = normalize(String(o.label ?? "")); const val = normalize(String(o.value ?? "")); return label.includes(q) || val.includes(q); }); return filtered.slice(0, 10); }; export const AsyncOptions: Story = { args: { searchDebounceMs: 50, name: "country", placeholder: "Select country", fetchOnMount: false, options: getSelectOptionsAsync, }, decorators: [FORM_TEST_DECORATOR], render: ({ name = "select", ...args }) => ( ), play: async ({ canvasElement }) => { const canvas = within(canvasElement); const select = canvas.getByRole("combobox"); const nativeSelect = select.querySelector("select[hidden]")!; await userEvent.click(select); const searchbox = within(select).getByRole("textbox"); await userEvent.type(searchbox, "lan", { delay: 200 }); await expect( await within(select).findByRole("status", { name: "Loading options..." }), ).toBeInTheDocument(); const netherlands = await within(select).findByText("Netherlands"); const switzerland = await within(select).findByText("Switzerland"); const iceland = await within(select).findByText("Iceland"); await userEvent.click(netherlands); await userEvent.click(switzerland); await userEvent.click(iceland); await waitFor(() => assertNativeValue(nativeSelect, "NL")); await waitFor(() => assertFormValue(nativeSelect, ["NL", "CH", "IS"])); await userEvent.click(within(select).getByLabelText("Clear search")); const clear = within(select).getByLabelText("Clear value"); await userEvent.click(clear); await waitFor(() => assertNativeValue(nativeSelect, "")); await waitFor(() => assertFormValue(nativeSelect, [])); }, }; const getOptionsNoOptionsAsync = async (): Promise => { await new Promise((r) => setTimeout(r, 600)); return []; }; export const AsyncOptionsNoOptions: Story = { args: { name: "country", placeholder: "Select country", fetchOnMount: false, options: getOptionsNoOptionsAsync, }, decorators: [FORM_TEST_DECORATOR], render: ({ name = "select", ...args }) => (