mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
* chore(root): menu and select components in progress * chore(root): merged with main * feat(menu): stories created * feat(dropdown): menu migrated to menu component * feat(select): base implementation in progress * feat(select): listbox implemented * feat(select): scroll overflow and auto scroll added * feat(select): colors & variants improved, inside placement complete, outside pending * feat(scroll-shadow): new component in progress * feat(select): scroll shadow integrated * fix(select): popover implementation, more scroll shadow stories added * feat(listbox): custom styles example added to stories * chore(listbox): overflow hidden removed * feat(select): variants and styles completed * chore(select): description story added * feat(select): more stories added * fix(select): dynamic collections inference, styles improved, more stories added * fix(select): auto scroll to selected item, scroll padding added * chore(select): scroll behavior changed to nearest * feat(select): custom item story added * fix(select): autoscroll fixed * feat(select): multi select support added * feat(select): more examples added, clean-package modified to remove dev packages * chore(modal): useImperativeHandle removed * feat(select): render value story improved * feat(docs): listbox & scroll shadow docs done * feat(docs): select documentation in progress * fix: select aria label (#1425) * feat(docs): more examples added * feat(docs): select multiple added, storybook favicon changed * fix: added value to aria label of select (#1431) * feat(select): more examples added, storybook favicon changed * fix(popover): dialog role removed * feat(select): api added, async loading exampled added * fix: fixed list box on click not working with sr click (#1439) * feat(select): async items loading support added and documented * feat(root): input styles updated to be as the select ones * chore(root): listbox and scroll shadow readme updated * feat(select): ts examples added, banner updated * fix(popover): voiceover closes when focusing an item fixed * chore(select): focus scope removed * fix(popover): free solo popover added to use without a trigger * feat(select): blog post added * chore(docs): search meta generated, multi controlled onchange example fixed * chore(root): changeset added --------- Co-authored-by: Jakob Guddas <github@jguddas.de>
399 lines
9.8 KiB
TypeScript
399 lines
9.8 KiB
TypeScript
import React from "react";
|
|
import {Meta} from "@storybook/react";
|
|
import {menuItem} from "@nextui-org/theme";
|
|
import {
|
|
AddNoteBulkIcon,
|
|
CopyDocumentBulkIcon,
|
|
EditDocumentBulkIcon,
|
|
DeleteDocumentBulkIcon,
|
|
} from "@nextui-org/shared-icons";
|
|
import {clsx} from "@nextui-org/shared-utils";
|
|
|
|
import {Menu, MenuItem, MenuSection, MenuProps} from "../src";
|
|
|
|
export default {
|
|
title: "Components/Menu",
|
|
component: Menu,
|
|
argTypes: {
|
|
variant: {
|
|
control: {
|
|
type: "select",
|
|
},
|
|
options: ["solid", "bordered", "light", "flat", "faded", "shadow"],
|
|
},
|
|
color: {
|
|
control: {
|
|
type: "select",
|
|
},
|
|
options: ["default", "primary", "secondary", "success", "warning", "danger"],
|
|
},
|
|
},
|
|
decorators: [
|
|
(Story) => (
|
|
<div className="flex items-center justify-center w-screen h-screen">
|
|
<div className="w-full max-w-[260px] border-small px-1 py-2 rounded-small border-default-200 dark:border-default-100">
|
|
<Story />
|
|
</div>
|
|
</div>
|
|
),
|
|
],
|
|
} as Meta<typeof Menu>;
|
|
|
|
const defaultProps = {
|
|
...menuItem.defaultVariants,
|
|
};
|
|
|
|
const Template = ({color, variant, ...args}: MenuProps) => (
|
|
<Menu aria-label="Actions" color={color} variant={variant} onAction={alert} {...args}>
|
|
<MenuItem key="new">New file</MenuItem>
|
|
<MenuItem key="copy">Copy link</MenuItem>
|
|
<MenuItem key="edit">Edit file</MenuItem>
|
|
<MenuItem key="delete" className="text-danger" color="danger">
|
|
Delete file
|
|
</MenuItem>
|
|
</Menu>
|
|
);
|
|
|
|
const DisabledKeysTemplate = ({color, variant, ...args}: MenuProps) => (
|
|
<Menu
|
|
aria-label="Actions"
|
|
color={color}
|
|
disabledKeys={["edit", "delete"]}
|
|
variant={variant}
|
|
onAction={alert}
|
|
{...args}
|
|
>
|
|
<MenuItem key="new">New file</MenuItem>
|
|
<MenuItem key="copy">Copy link</MenuItem>
|
|
<MenuItem key="edit">Edit file</MenuItem>
|
|
<MenuItem key="delete" className="text-danger" color="danger">
|
|
Delete file
|
|
</MenuItem>
|
|
</Menu>
|
|
);
|
|
|
|
const SingleSelectionTemplate = ({color, variant, ...args}: MenuProps) => {
|
|
const [selected, setSelected] = React.useState<string | Set<React.Key>>(new Set(["text"]));
|
|
|
|
return (
|
|
<Menu
|
|
disallowEmptySelection
|
|
aria-label="Actions"
|
|
color={color}
|
|
selectedKeys={selected}
|
|
selectionMode="single"
|
|
variant={variant}
|
|
onSelectionChange={setSelected}
|
|
{...args}
|
|
>
|
|
<MenuItem key="text">Text</MenuItem>
|
|
<MenuItem key="number">Number</MenuItem>
|
|
<MenuItem key="date">Date</MenuItem>
|
|
<MenuItem key="single_date">Single Date</MenuItem>
|
|
<MenuItem key="iteration">Iteration</MenuItem>
|
|
</Menu>
|
|
);
|
|
};
|
|
|
|
const MultipleSelectionTemplate = ({color, variant, ...args}: MenuProps) => {
|
|
const [selected, setSelected] = React.useState<string | Set<React.Key>>(new Set(["text"]));
|
|
|
|
return (
|
|
<Menu
|
|
disallowEmptySelection
|
|
aria-label="Actions"
|
|
closeOnSelect={false}
|
|
color={color}
|
|
selectedKeys={selected}
|
|
selectionMode="multiple"
|
|
variant={variant}
|
|
onSelectionChange={setSelected}
|
|
{...args}
|
|
>
|
|
<MenuItem key="text">Text</MenuItem>
|
|
<MenuItem key="number">Number</MenuItem>
|
|
<MenuItem key="date">Date</MenuItem>
|
|
<MenuItem key="single_date">Single Date</MenuItem>
|
|
<MenuItem key="iteration">Iteration</MenuItem>
|
|
</Menu>
|
|
);
|
|
};
|
|
|
|
const WithShortcutTemplate = ({color, variant, ...args}) => (
|
|
<Menu aria-label="Actions" color={color} variant={variant} onAction={alert} {...args}>
|
|
<MenuItem key="new" shortcut="⌘N">
|
|
New file
|
|
</MenuItem>
|
|
<MenuItem key="copy" shortcut="⌘C">
|
|
Copy link
|
|
</MenuItem>
|
|
<MenuItem key="edit" shortcut="⌘⇧E">
|
|
Edit file
|
|
</MenuItem>
|
|
<MenuItem key="delete" className="text-danger" color="danger" shortcut="⌘⇧D">
|
|
Delete file
|
|
</MenuItem>
|
|
</Menu>
|
|
);
|
|
|
|
const WithStartContentTemplate = ({color, variant, disableAnimation, ...args}: MenuProps) => {
|
|
const iconClasses = "text-2xl text-secondary pointer-events-none flex-shrink-0";
|
|
|
|
return (
|
|
<Menu
|
|
aria-label="Actions"
|
|
color={color}
|
|
disableAnimation={disableAnimation}
|
|
variant={variant}
|
|
onAction={alert}
|
|
{...args}
|
|
>
|
|
<MenuItem key="new" shortcut="⌘N" startContent={<AddNoteBulkIcon className={iconClasses} />}>
|
|
New file
|
|
</MenuItem>
|
|
<MenuItem
|
|
key="copy"
|
|
shortcut="⌘C"
|
|
startContent={<CopyDocumentBulkIcon className={iconClasses} />}
|
|
>
|
|
Copy link
|
|
</MenuItem>
|
|
<MenuItem
|
|
key="edit"
|
|
shortcut="⌘⇧E"
|
|
startContent={<EditDocumentBulkIcon className={iconClasses} />}
|
|
>
|
|
Edit file
|
|
</MenuItem>
|
|
<MenuItem
|
|
key="delete"
|
|
className="text-danger"
|
|
color="danger"
|
|
shortcut="⌘⇧D"
|
|
startContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
|
|
>
|
|
Delete file
|
|
</MenuItem>
|
|
</Menu>
|
|
);
|
|
};
|
|
|
|
const WithEndContentTemplate = ({color, variant, disableAnimation, ...args}) => {
|
|
const iconClasses = "text-2xl text-default-500 pointer-events-none flex-shrink-0";
|
|
|
|
return (
|
|
<Menu
|
|
aria-label="Actions"
|
|
color={color}
|
|
disableAnimation={disableAnimation}
|
|
variant={variant}
|
|
onAction={alert}
|
|
{...args}
|
|
>
|
|
<MenuItem key="new" endContent={<AddNoteBulkIcon className={iconClasses} />}>
|
|
New file
|
|
</MenuItem>
|
|
<MenuItem key="copy" endContent={<CopyDocumentBulkIcon className={iconClasses} />}>
|
|
Copy link
|
|
</MenuItem>
|
|
<MenuItem key="edit" endContent={<EditDocumentBulkIcon className={iconClasses} />}>
|
|
Edit file
|
|
</MenuItem>
|
|
<MenuItem
|
|
key="delete"
|
|
className="text-danger"
|
|
color="danger"
|
|
endContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
|
|
>
|
|
Delete file
|
|
</MenuItem>
|
|
</Menu>
|
|
);
|
|
};
|
|
|
|
const WithDescriptionTemplate = ({color, variant, disableAnimation, ...args}) => {
|
|
const iconClasses = "text-2xl text-secondary pointer-events-none flex-shrink-0";
|
|
|
|
return (
|
|
<Menu
|
|
aria-label="Actions"
|
|
color={color}
|
|
disableAnimation={disableAnimation}
|
|
variant={variant}
|
|
onAction={alert}
|
|
{...args}
|
|
>
|
|
<MenuItem
|
|
key="new"
|
|
description="Create a new file"
|
|
shortcut="⌘N"
|
|
startContent={<AddNoteBulkIcon className={iconClasses} />}
|
|
>
|
|
New file
|
|
</MenuItem>
|
|
<MenuItem
|
|
key="copy"
|
|
description="Copy the file link"
|
|
shortcut="⌘C"
|
|
startContent={<CopyDocumentBulkIcon className={iconClasses} />}
|
|
>
|
|
Copy link
|
|
</MenuItem>
|
|
<MenuItem
|
|
key="edit"
|
|
description="Allows you to edit the file"
|
|
shortcut="⌘⇧E"
|
|
startContent={<EditDocumentBulkIcon className={iconClasses} />}
|
|
>
|
|
Edit file
|
|
</MenuItem>
|
|
<MenuItem
|
|
key="delete"
|
|
className="text-danger"
|
|
color="danger"
|
|
description="Permanently delete the file"
|
|
shortcut="⌘⇧D"
|
|
startContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
|
|
>
|
|
Delete file
|
|
</MenuItem>
|
|
</Menu>
|
|
);
|
|
};
|
|
|
|
const WithSectionsTemplate = ({color, variant, disableAnimation, ...args}) => {
|
|
const iconClasses = "text-2xl text-secondary pointer-events-none flex-shrink-0";
|
|
|
|
return (
|
|
<Menu
|
|
aria-label="Actions"
|
|
closeOnSelect={false}
|
|
color={color}
|
|
disableAnimation={disableAnimation}
|
|
variant={variant}
|
|
onAction={alert}
|
|
{...args}
|
|
>
|
|
<MenuSection title="Actions">
|
|
<MenuItem
|
|
key="new"
|
|
description="Create a new file"
|
|
shortcut="⌘N"
|
|
startContent={<AddNoteBulkIcon className={iconClasses} />}
|
|
>
|
|
New file
|
|
</MenuItem>
|
|
<MenuItem
|
|
key="copy"
|
|
description="Copy the file link"
|
|
shortcut="⌘C"
|
|
startContent={<CopyDocumentBulkIcon className={iconClasses} />}
|
|
>
|
|
Copy link
|
|
</MenuItem>
|
|
<MenuItem
|
|
key="edit"
|
|
description="Allows you to edit the file"
|
|
shortcut="⌘⇧E"
|
|
startContent={<EditDocumentBulkIcon className={iconClasses} />}
|
|
>
|
|
Edit file
|
|
</MenuItem>
|
|
</MenuSection>
|
|
<MenuSection title="Danger zone">
|
|
<MenuItem
|
|
key="delete"
|
|
className="text-danger"
|
|
color="danger"
|
|
description="Permanently delete the file"
|
|
shortcut="⌘⇧D"
|
|
startContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
|
|
>
|
|
Delete file
|
|
</MenuItem>
|
|
</MenuSection>
|
|
</Menu>
|
|
);
|
|
};
|
|
|
|
export const Default = {
|
|
render: Template,
|
|
args: {
|
|
...defaultProps,
|
|
},
|
|
};
|
|
|
|
export const DisabledKeys = {
|
|
render: DisabledKeysTemplate,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
},
|
|
};
|
|
|
|
export const SingleSelection = {
|
|
render: SingleSelectionTemplate,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
},
|
|
};
|
|
|
|
export const MultipleSelection = {
|
|
render: MultipleSelectionTemplate,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
},
|
|
};
|
|
|
|
export const WithShortcut = {
|
|
render: WithShortcutTemplate,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
},
|
|
};
|
|
|
|
export const WithStartContent = {
|
|
render: WithStartContentTemplate,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
variant: "flat",
|
|
color: "secondary",
|
|
},
|
|
};
|
|
|
|
export const WithEndContent = {
|
|
render: WithEndContentTemplate,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
variant: "faded",
|
|
color: "success",
|
|
},
|
|
};
|
|
|
|
export const WithDescription = {
|
|
render: WithDescriptionTemplate,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
variant: "flat",
|
|
color: "secondary",
|
|
className: "min-w-[240px]",
|
|
},
|
|
};
|
|
|
|
export const WithSections = {
|
|
render: WithSectionsTemplate,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
variant: "flat",
|
|
color: "secondary",
|
|
className: "min-w-[240px]",
|
|
},
|
|
};
|