Junior Garcia baec55029d
Feat/select component (#1313)
* 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>
2023-08-21 12:28:01 +00:00

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]",
},
};