import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters" import type { Meta, StoryObj } from "@storybook/react" import { controlSizeArgType } from "../argTypes.storyHelpers.ts" import { ContainerBoard, StoryCell, StoryGrid, StorySection, } from "../board.storyHelpers.tsx" import { Card } from "../Card/Card.tsx" import { MoreIcon, RedoIcon, SettingsIcon, UndoIcon, } from "../icons.storyHelpers.tsx" import type { MenuEntry } from "../Menu/Menu.tsx" import { ActionMenu } from "./ActionMenu.tsx" const noop = () => undefined const SHELF_ACTIONS: MenuEntry[] = [ { icon: , key: "rename", label: "Rename", onSelect: noop, }, { icon: , key: "move", label: "Move to another place", onSelect: noop, }, { key: "divider", type: "separator" }, { icon: , isDisabled: true, key: "archive", label: "Archive", onSelect: noop, }, ] const meta = { title: "Components/Actions/ActionMenu", component: ActionMenu, parameters: { layout: "padded" }, argTypes: { size: controlSizeArgType }, args: { items: SHELF_ACTIONS, label: "Actions for Office Shelves", size: "md", }, } satisfies Meta export default meta type Story = StoryObj /** * At the end of its row, where it lives: the panel opens at * `bottom-end`, so its end edge lines up with the button's and it * opens inward. */ export const Playground: Story = { parameters: playgroundParameters, render: (actionMenuProps) => (
), } /** * The default dots against an app's own glyph, at every size. The * dots are three round boxes, not a `⋮` and not an SVG, so they draw * in a font that has no such character. */ export const AllVariants: Story = { render: (actionMenuProps) => ( {(["sm", "md", "lg"] as const).map((size) => ( ))} {(["sm", "md", "lg"] as const).map((size) => ( } size=${size}`} > } label={`Actions for bin ${size}`} size={size} /> ))} ), } /** * Rest, hover and focus on the trigger. The open state is `Menu`'s * own board; this component adds nothing to the panel. */ export const AllStates: Story = { parameters: { pseudo: { focusVisible: ["#focus-target button"], hover: ["#hover-target button"], }, }, render: (actionMenuProps) => (
), } /** * Where it lives: at the end of a card's header row. The title wraps * and the trigger keeps its size, at every container width. */ export const Responsive: Story = { render: (actionMenuProps) => ( {(width) => (

Office Shelves, the tall unit by the window

)}
), } /** * Enter or Space opens it and focus moves to the first item; the * arrows walk the items and skip the disabled one; choosing an item * or pressing Escape closes it. */ export const Interactive: Story = {}