import type { Meta, StoryObj } from "@storybook/react-vite"; import * as React from "react"; import { expect, userEvent, waitFor, within } from "storybook/test"; import { PAGE_DECORATOR } from "../../../.storybook/decorators"; import { Button, ButtonLink } from "../button"; import { Outline } from "../icon"; import { Toolbar } from "../toolbar"; import { Dropdown } from "./dropdown"; const meta: Meta = { title: "Controls/Dropdown", component: Dropdown, decorators: [PAGE_DECORATOR], parameters: { layout: "fullscreen", lastButtonText: "Uitloggen", }, play: async ({ canvasElement, parameters }) => { const canvas = within(canvasElement); const body = within(document.body); const button = canvas.getByText("Click me!"); // Click opens, escape closes. await userEvent.click(button, { delay: 10 }); await waitFor(() => body.findByRole("dialog"), { timeout: 300 }); await userEvent.keyboard("{Escape}", { delay: 10 }); await waitFor(() => expect(canvas.queryByRole("dialog")).toBeNull()); await userEvent.click(button, { delay: 10 }); for (let counter = 0; counter < 3; counter++) { await userEvent.tab({ delay: 20 }); } await expect(document.activeElement?.textContent).toBe( parameters.lastButtonText, ); }, }; const DEFAULT_CHILDREN = ( <> Admin ); export default meta; type Story = StoryObj; export const DropdownComponent: Story = { args: { label: ( <> Click me! ), children: DEFAULT_CHILDREN, }, }; export const ActivateOnHover: Story = { args: { activateOnHover: true, label: ( <> Hover me! ), children: DEFAULT_CHILDREN, }, play: async ({ canvasElement, parameters }) => { const canvas = within(canvasElement); const body = within(document.body); const button = canvas.getByText("Hover me!"); // Click opens, escape closes. await userEvent.hover(button, { delay: 10 }); await waitFor(() => body.findByRole("dialog"), { timeout: 300 }); await userEvent.keyboard("{Escape}", { delay: 10 }); await waitFor(() => expect(canvas.queryByRole("dialog")).toBeNull()); await userEvent.hover(button, { delay: 10 }); await waitFor(() => expect(document.activeElement?.textContent).toBe("Zaaktypen"), ); for (let counter = 0; counter < 3; counter++) { await userEvent.tab({ delay: 20 }); } await expect(document.activeElement?.textContent).toBe( parameters.lastButtonText, ); }, }; // FIXME: disabled due to flaky results. // export const ActivateOnFocus: Story = { // ...ActivateOnHover, // play: async ({ canvasElement, parameters }) => { // const canvas = within(canvasElement); // const body = within(document.body); // const button = canvas.getByText("Hover me!"); // // // Click opens, escape closes. // await userEvent.tab({ delay: 10 }); // button.focus(); // await waitFor(() => body.findByRole("dialog"), { timeout: 300 }); // await userEvent.keyboard("{Escape}"); // await waitFor(() => expect(body.queryByRole("dialog")).toBeNull()); // await userEvent.tab({ shift: true, delay: 10 }); // // await userEvent.tab({ delay: 10 }); // await waitFor(() => // expect(document.activeElement?.textContent).toBe("Zaaktypen"), // ); // // for (let counter = 0; counter < 3; counter++) { // await userEvent.tab({ delay: 20 }); // } // // await expect(document.activeElement?.textContent).toBe( // parameters.lastButtonText, // ); // }, // }; export const DropdownVariant: Story = { args: { label: ( <> Click me! ), variant: "transparent", children: DEFAULT_CHILDREN, }, }; export const HorizontalDropdown: Story = { args: { label: ( <> Click me! ), toolbarProps: { direction: "h", }, children: ( <> Admin ), }, }; export const DropdownInToolbar: Story = { args: { label: ( <> Click me! ), children: DEFAULT_CHILDREN, }, render: (args) => ( Admin ), }; export const NestedDropdown: Story = { args: { label: ( <> Click me! ), variant: "primary", children: ( <> Hover me! } placement="right" variant="transparent" > Admin ), }, play: async ({ canvasElement, parameters }) => { const canvas = within(canvasElement); const body = within(document.body); const button = canvas.getByText("Click me!"); // Click opens, escape closes. await userEvent.click(button, { delay: 10 }); await expect(await body.findByRole("dialog")).toBeVisible(); await userEvent.keyboard("{Escape}"); await waitFor(() => expect(canvas.queryByRole("dialog")).toBeNull()); await userEvent.click(button, { delay: 10 }); await waitFor(() => expect(document.activeElement?.textContent).toBe("Zaaktypen"), ); await userEvent.tab({ delay: 20 }); await waitFor(() => expect(document.activeElement?.textContent).toBe("Documenttypen"), ); await userEvent.tab({ delay: 20 }); await waitFor(() => expect(document.activeElement?.textContent).toBe("Admin"), ); await userEvent.tab({ delay: 20 }); await expect(document.activeElement?.textContent).toBe( parameters.lastButtonText, ); }, }; export const DropdownWithItemsProp: Story = { args: { label: ( <> {" "} Click me! ), items: [ { variant: "transparent", children: ( <> Zaaktypen ), }, { variant: "transparent", children: ( <> Documenttypen ), }, { href: "https://www.example.com", target: "_blank", variant: "transparent", children: ( <> Admin ), }, { variant: "transparent", children: ( <> Uitloggen ), }, ], }, };