nextui/packages/components/dropdown/stories/dropdown.stories.tsx
Junior Garcia 7abd68941a
v2.2.0 🕹️ (#1777)
* feat: Slider Component (#1686)

* feat(slider): initial structure

* chore(slider): readme improved

* fix: fixed border color of slider track

* docs: added range story

* feat: added rtl support to slider

* feat: improved value label formatting

* feat: refactor styling and add colors support to slider

* chore: improved thumb color

* docs: improved slider stories

* chore(slider): default color changed by foreground

* Update packages/core/theme/src/components/slider.ts

Co-authored-by: Jakob Guddas <github@jguddas.de>

* feat: added fillOffset prop

* Update packages/components/slider/src/use-slider.ts

* fix(slider): animation

* Update packages/components/slider/src/use-slider.ts

* Update packages/core/theme/src/components/slider.ts

* feat: slider steps

* refactor: renamed variables

* feat: improved slider step styling

* fix: hide infinite steps

* fix: fixed step transparency issue

* fix: fixed thumb focus issue

* Update packages/components/slider/src/use-slider.ts

Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>

* feat(slider): vertical orientation added, start & end content, bug fixes

* chore(slider): tests added

* fix(docs): scrollbar added to the sidebar (#1743)

* feat(slider): marks added

* chore(slider): example ts-doc changed

* feat(slider): vertical marks support

* feat(core): slider tooltip support added, popover modified (#1746)

* Feat/slider custom styles (#1751)

* feat(slider): custom styles story added

* fix(slider): custom styles on different sizes

* Fix/slider tooltip android position (#1753)

* feat(slider): custom styles story added

* fix(slider): tooltip update position dependecies added

* fix(popover): arrow placements improved

* feat(slider): docs started, custom thumb and custom output stories added

* feat(slider): render function added to custom render the slider parts

* feat(slider): docs in progress, new properties and examples added

* fix(slider): some issues fixed, output renamed to value, documentation improved

* feat(slider): docs done

* chore: changeset

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>

* Client side routing (#1764)

* feat(slider): initial structure

* chore(slider): readme improved

* fix: fixed border color of slider track

* docs: added range story

* feat: added rtl support to slider

* feat: improved value label formatting

* feat: refactor styling and add colors support to slider

* chore: improved thumb color

* docs: improved slider stories

* chore(slider): default color changed by foreground

* Update packages/core/theme/src/components/slider.ts

Co-authored-by: Jakob Guddas <github@jguddas.de>

* feat: added fillOffset prop

* Update packages/components/slider/src/use-slider.ts

* fix(slider): animation

* Update packages/components/slider/src/use-slider.ts

* Update packages/core/theme/src/components/slider.ts

* feat: slider steps

* refactor: renamed variables

* feat: improved slider step styling

* fix: hide infinite steps

* fix: fixed step transparency issue

* fix: fixed thumb focus issue

* Update packages/components/slider/src/use-slider.ts

Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>

* feat(slider): vertical orientation added, start & end content, bug fixes

* chore(slider): tests added

* feat(slider): marks added

* chore(slider): example ts-doc changed

* feat(slider): vertical marks support

* feat(core): slider tooltip support added, popover modified (#1746)

* Feat/slider custom styles (#1751)

* feat(slider): custom styles story added

* fix(slider): custom styles on different sizes

* Fix/slider tooltip android position (#1753)

* feat(slider): custom styles story added

* fix(slider): tooltip update position dependecies added

* fix(popover): arrow placements improved

* feat(slider): docs started, custom thumb and custom output stories added

* feat(slider): render function added to custom render the slider parts

* feat(slider): docs in progress, new properties and examples added

* fix(slider): some issues fixed, output renamed to value, documentation improved

* feat(slider): docs done

* chore: changeset

* chore: react aria packages upgraded

* feat(system): router provider added

* feat: client side routing support added to items components

* chore(docs): routing docs started

* chore: changeset

* feat(docs): client side routing documented

* feat(pagination): client router support added to pagination

* fix(link): csr added

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>

* feat: added RTL support to accordion component (#1725)

* feat: added RTL support to accordion component

* Create healthy-cobras-crash.md

* feat: added RTL support to avatar and avatar group component (#1727)

* feat: added RTL support to avatar and avatar group components

* Create tender-penguins-love.md

* Update tender-penguins-love.md

* feat: added RTL support to button group component (#1726)

* feat: added RTL support to button component

* feat: added RTL support to button component

* Create orange-bobcats-kneel.md

* Update button.ts

* refactor(root): styles refactor (#1688)

* refactor(root): styles refactor

* chore(tabs): remove needless type extends

* fix(tabs): typecheck

* Breadcrumbs component (#1794)

* feat(components): breadcrumbs initial structure

* feat(breadcrumbs): tests and examples added

* feat(docs): breadcrumbs documentation done

* feat(docs): breadcrumbs docs done

* chore(breadcrumbs): readme changed

* fix(slider): Place last dragged slider handle over the other handle (#1778)

* Set `data-focused` in handle

* Style focused handle on top

* Add tests

* fix(core): tests and build

* fix(button): show only spinner if button isLoading & isIconOnly (#1800)

* fix(button): show only spinner if button isLoading & isIconOnly

* chore: add changeset

* fix(button): remove repeating code

* Fix blur/opaque Popover (#1812)

* fix(popover): double underlay click

* chore: use ref instead of a state

* Feat/controlled scroll shadow (#1819)

* feat(scroll-shadow): logic improved, controlled support added

* feat(scroll-shadow): controlled visibility

* fix(scroll-shadow): visibility tests

* Autocomplete component (Single Selection) (#1797)

* feat(autocomplete): initial structure

* feat(core): use press custom hook implemented, autocomplete improved, input and select animations fixed

* chore(button): add console.log on press

* feat(core): select & input label position, autocomplete improvements, listbox and menu empty state

* chore: tailwind-variants upgraded

* chore: autocomplete stories in progress

* fix: input and select label placement

* fix(autocomplete): popover trigger

* chore(root): react-aria pkgs and framer-motion upgraded

* fix(input,select): outside label scale removed

* feat(autocomplete): more stories and use cases supported

* fix(core): custom items support on collection-based comps, menu generic items support added

* chore(core): tailwind-variants upgraded, custom tv function adapted

* chore(docs): select on-change controlled e.g. changed, sandpack theme fixed

* chore(autocomplete): docs started, tests added

* chore: in progress

* feat(menu): top and end content added, autocomplete docs improved

* feat(docs): autocomplete documentation almost done

* fix(input): outside styles

* feat(docs): autocomplete async filtering added

* chore(docs): autocomplete highlighted lines added

* feat(docs): autocomplete a11y and slots added

* feat(docs): autocomplete a11y and slots added

* feat(docs): autocomplete docs done

* fix(root): peer dependencies (#1848)

* Fix/small issues (#1851)

* fix(input): visible outline

* fix(button): button group radius prop

* chore(navbar): menu item active status added

* fix(docs): pagination missing keys custom items

* fix(core): extendVariants support added to collection-based components

* fix(theme): card body padding

* chore(theme): transition added to menu/listbox items

* fix(input): textarea styles fixed, new prop added

* chore(input): textarea height animated

* feat(button): hover opacity added

* chore(textarea): hide scroll when the limit hasn't been reached

* chore(docs): updated badge added to textarea

* feat(docs): blog v2.2.0 image and entry added

* fix(avatar): ring primary color

* chore(docs): tabs added again, autocomplete iframes removed

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
Co-authored-by: Maurici Abad Gutierrez <hello@mauriciabad.com>
Co-authored-by: Ivan Kucher <dev.kucher@gmail.com>
2023-11-03 11:05:16 -03:00

700 lines
18 KiB
TypeScript

import React from "react";
import {Meta} from "@storybook/react";
import {dropdown, popover} from "@nextui-org/theme";
import {Button} from "@nextui-org/button";
import {Avatar} from "@nextui-org/avatar";
import {User} from "@nextui-org/user";
import {
AddNoteBulkIcon,
CopyDocumentBulkIcon,
EditDocumentBulkIcon,
DeleteDocumentBulkIcon,
} from "@nextui-org/shared-icons";
import {clsx} from "@nextui-org/shared-utils";
import {
Dropdown,
DropdownSection,
DropdownTrigger,
DropdownMenu,
DropdownItem,
DropdownProps,
DropdownMenuProps,
} from "../src";
export default {
title: "Components/Dropdown",
component: Dropdown,
argTypes: {
variant: {
control: {
type: "select",
},
options: ["solid", "bordered", "light", "flat", "faded", "shadow"],
},
color: {
control: {
type: "select",
},
options: ["default", "primary", "secondary", "success", "warning", "danger"],
},
radius: {
control: {
type: "select",
},
options: ["none", "sm", "md", "lg", "full"],
},
placement: {
control: {
type: "select",
},
options: [
"top",
"bottom",
"right",
"left",
"top-start",
"top-end",
"bottom-start",
"bottom-end",
"left-start",
"left-end",
"right-start",
"right-end",
],
},
backdrop: {
control: {
type: "select",
},
options: ["transparent", "blur", "opaque"],
},
offset: {
control: {
type: "number",
},
},
defaultOpen: {
control: {
type: "boolean",
},
},
showArrow: {
control: {
type: "boolean",
},
},
disableAnimation: {
control: {
type: "boolean",
},
},
children: {
control: {
disable: true,
},
},
},
decorators: [
(Story) => (
<div className="flex items-center justify-center w-screen h-screen">
<Story />
</div>
),
],
} as Meta<typeof Dropdown>;
const defaultProps = {
...popover.defaultVariants,
...dropdown.defaultVariants,
placement: "bottom",
offset: 7,
defaultOpen: false,
disableAnimation: false,
};
const items = [
{
key: "new",
label: "New file",
},
{
key: "copy",
label: "Copy link",
},
{
key: "edit",
label: "Edit file",
},
{
key: "delete",
label: "Delete file",
},
];
const Template = ({color, variant, ...args}: DropdownProps & DropdownMenuProps) => (
<Dropdown {...args}>
<DropdownTrigger>
<Button>Trigger</Button>
</DropdownTrigger>
<DropdownMenu aria-label="Actions" color={color} variant={variant} onAction={alert}>
<DropdownItem key="new">New file</DropdownItem>
<DropdownItem key="copy">Copy link</DropdownItem>
<DropdownItem key="edit">Edit file</DropdownItem>
<DropdownItem key="delete" className="text-danger" color="danger">
Delete file
</DropdownItem>
</DropdownMenu>
</Dropdown>
);
const DynamicTemplate = ({color, variant, ...args}: DropdownProps & DropdownMenuProps) => (
<Dropdown {...args}>
<DropdownTrigger>
<Button>Trigger</Button>
</DropdownTrigger>
<DropdownMenu
aria-label="Actions"
color={color}
items={items}
variant={variant}
onAction={alert}
>
{(item) => (
<DropdownItem
key={item.key}
className={item.key === "delete" ? "text-danger" : ""}
color={item.key === "delete" ? "danger" : "default"}
>
{item.label}
</DropdownItem>
)}
</DropdownMenu>
</Dropdown>
);
const DividerTemplate = ({color, variant, ...args}: DropdownProps & DropdownMenuProps) => (
<Dropdown {...args}>
<DropdownTrigger>
<Button>Trigger</Button>
</DropdownTrigger>
<DropdownMenu aria-label="Actions" color={color} variant={variant} onAction={alert}>
<DropdownItem key="new">New file</DropdownItem>
<DropdownItem key="copy">Copy link</DropdownItem>
<DropdownItem key="edit" showDivider>
Edit file
</DropdownItem>
<DropdownItem key="delete" className="text-danger" color="danger">
Delete file
</DropdownItem>
</DropdownMenu>
</Dropdown>
);
const DisabledKeysTemplate = ({color, variant, ...args}: DropdownProps & DropdownMenuProps) => (
<Dropdown {...args}>
<DropdownTrigger>
<Button>Trigger</Button>
</DropdownTrigger>
<DropdownMenu
aria-label="Actions"
color={color}
disabledKeys={["edit", "delete"]}
variant={variant}
onAction={alert}
>
<DropdownItem key="new">New file</DropdownItem>
<DropdownItem key="copy">Copy link</DropdownItem>
<DropdownItem key="edit">Edit file</DropdownItem>
<DropdownItem key="delete" className="text-danger" color="danger">
Delete file
</DropdownItem>
</DropdownMenu>
</Dropdown>
);
const SingleSelectionTemplate = ({color, variant, ...args}: DropdownProps & DropdownMenuProps) => {
const [selected, setSelected] = React.useState<string | Set<React.Key>>(new Set(["text"]));
const selectedValue = React.useMemo(
() =>
Array.from(selected)
.map((key) => key.toString().replace("_", " "))
.join(", "),
[selected],
);
return (
<Dropdown {...args}>
<DropdownTrigger>
<Button>{selectedValue}</Button>
</DropdownTrigger>
<DropdownMenu
disallowEmptySelection
aria-label="Actions"
color={color}
selectedKeys={selected}
selectionMode="single"
variant={variant}
onSelectionChange={setSelected}
>
<DropdownItem key="text">Text</DropdownItem>
<DropdownItem key="number">Number</DropdownItem>
<DropdownItem key="date">Date</DropdownItem>
<DropdownItem key="single_date">Single Date</DropdownItem>
<DropdownItem key="iteration">Iteration</DropdownItem>
</DropdownMenu>
</Dropdown>
);
};
const MultipleSelectionTemplate = ({
color,
variant,
...args
}: DropdownProps & DropdownMenuProps) => {
const [selected, setSelected] = React.useState<string | Set<React.Key>>(new Set(["text"]));
const selectedValue = React.useMemo(
() =>
Array.from(selected)
.map((key) => key.toString().replace("_", " "))
.join(", "),
[selected],
);
return (
<Dropdown {...args}>
<DropdownTrigger>
<Button>{selectedValue}</Button>
</DropdownTrigger>
<DropdownMenu
disallowEmptySelection
aria-label="Actions"
closeOnSelect={false}
color={color}
selectedKeys={selected}
selectionMode="multiple"
variant={variant}
onSelectionChange={setSelected}
>
<DropdownItem key="text">Text</DropdownItem>
<DropdownItem key="number">Number</DropdownItem>
<DropdownItem key="date">Date</DropdownItem>
<DropdownItem key="single_date">Single Date</DropdownItem>
<DropdownItem key="iteration">Iteration</DropdownItem>
</DropdownMenu>
</Dropdown>
);
};
const WithShortcutTemplate = ({color, variant, ...args}) => (
<Dropdown {...args}>
<DropdownTrigger>
<Button>Trigger</Button>
</DropdownTrigger>
<DropdownMenu aria-label="Actions" color={color} variant={variant} onAction={alert}>
<DropdownItem key="new" shortcut="⌘N">
New file
</DropdownItem>
<DropdownItem key="copy" shortcut="⌘C">
Copy link
</DropdownItem>
<DropdownItem key="edit" shortcut="⌘⇧E">
Edit file
</DropdownItem>
<DropdownItem key="delete" className="text-danger" color="danger" shortcut="⌘⇧D">
Delete file
</DropdownItem>
</DropdownMenu>
</Dropdown>
);
const WithStartContentTemplate = ({
color,
variant,
disableAnimation,
...args
}: DropdownProps & DropdownMenuProps) => {
const iconClasses = "text-2xl text-secondary pointer-events-none flex-shrink-0";
return (
<Dropdown {...args} disableAnimation={disableAnimation}>
<DropdownTrigger>
<Button color="secondary" disableAnimation={disableAnimation} variant="flat">
Trigger
</Button>
</DropdownTrigger>
<DropdownMenu aria-label="Actions" color={color} variant={variant} onAction={alert}>
<DropdownItem
key="new"
shortcut="⌘N"
startContent={<AddNoteBulkIcon className={iconClasses} />}
>
New file
</DropdownItem>
<DropdownItem
key="copy"
shortcut="⌘C"
startContent={<CopyDocumentBulkIcon className={iconClasses} />}
>
Copy link
</DropdownItem>
<DropdownItem
key="edit"
shortcut="⌘⇧E"
startContent={<EditDocumentBulkIcon className={iconClasses} />}
>
Edit file
</DropdownItem>
<DropdownItem
key="delete"
className="text-danger"
color="danger"
shortcut="⌘⇧D"
startContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
>
Delete file
</DropdownItem>
</DropdownMenu>
</Dropdown>
);
};
const WithEndContentTemplate = ({color, variant, disableAnimation, ...args}) => {
const iconClasses = "text-2xl text-default-500 pointer-events-none flex-shrink-0";
return (
<Dropdown {...args} disableAnimation={disableAnimation}>
<DropdownTrigger>
<Button color="success" disableAnimation={disableAnimation} variant="faded">
Trigger
</Button>
</DropdownTrigger>
<DropdownMenu aria-label="Actions" color={color} variant={variant} onAction={alert}>
<DropdownItem key="new" endContent={<AddNoteBulkIcon className={iconClasses} />}>
New file
</DropdownItem>
<DropdownItem key="copy" endContent={<CopyDocumentBulkIcon className={iconClasses} />}>
Copy link
</DropdownItem>
<DropdownItem key="edit" endContent={<EditDocumentBulkIcon className={iconClasses} />}>
Edit file
</DropdownItem>
<DropdownItem
key="delete"
className="text-danger"
color="danger"
endContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
>
Delete file
</DropdownItem>
</DropdownMenu>
</Dropdown>
);
};
const WithDescriptionTemplate = ({color, variant, disableAnimation, ...args}) => {
const iconClasses = "text-2xl text-secondary pointer-events-none flex-shrink-0";
return (
<Dropdown {...args} disableAnimation={disableAnimation}>
<DropdownTrigger>
<Button color="secondary" disableAnimation={disableAnimation} variant="flat">
Trigger
</Button>
</DropdownTrigger>
<DropdownMenu aria-label="Actions" color={color} variant={variant} onAction={alert}>
<DropdownItem
key="new"
description="Create a new file"
shortcut="⌘N"
startContent={<AddNoteBulkIcon className={iconClasses} />}
>
New file
</DropdownItem>
<DropdownItem
key="copy"
description="Copy the file link"
shortcut="⌘C"
startContent={<CopyDocumentBulkIcon className={iconClasses} />}
>
Copy link
</DropdownItem>
<DropdownItem
key="edit"
description="Allows you to edit the file"
shortcut="⌘⇧E"
startContent={<EditDocumentBulkIcon className={iconClasses} />}
>
Edit file
</DropdownItem>
<DropdownItem
key="delete"
className="text-danger"
color="danger"
description="Permanently delete the file"
shortcut="⌘⇧D"
startContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
>
Delete file
</DropdownItem>
</DropdownMenu>
</Dropdown>
);
};
const WithSectionsTemplate = ({color, variant, disableAnimation, ...args}) => {
const iconClasses = "text-2xl text-secondary pointer-events-none flex-shrink-0";
return (
<Dropdown {...args} disableAnimation={disableAnimation}>
<DropdownTrigger>
<Button color="secondary" disableAnimation={disableAnimation} variant="flat">
Trigger
</Button>
</DropdownTrigger>
<DropdownMenu
aria-label="Actions"
closeOnSelect={false}
color={color}
variant={variant}
onAction={alert}
>
<DropdownSection title="Actions">
<DropdownItem
key="new"
description="Create a new file"
shortcut="⌘N"
startContent={<AddNoteBulkIcon className={iconClasses} />}
>
New file
</DropdownItem>
<DropdownItem
key="copy"
description="Copy the file link"
shortcut="⌘C"
startContent={<CopyDocumentBulkIcon className={iconClasses} />}
>
Copy link
</DropdownItem>
<DropdownItem
key="edit"
description="Allows you to edit the file"
shortcut="⌘⇧E"
startContent={<EditDocumentBulkIcon className={iconClasses} />}
>
Edit file
</DropdownItem>
</DropdownSection>
<DropdownSection title="Danger zone">
<DropdownItem
key="delete"
className="text-danger"
color="danger"
description="Permanently delete the file"
shortcut="⌘⇧D"
startContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
>
Delete file
</DropdownItem>
</DropdownSection>
</DropdownMenu>
</Dropdown>
);
};
const CustomTriggerTemplate = ({variant, ...args}) => {
return (
<div className="flex items-center gap-10">
<Dropdown {...args} placement="bottom-end">
<DropdownTrigger>
<Avatar
isBordered
as="button"
className="transition-transform"
color="secondary"
size="md"
src="https://i.pravatar.cc/150?u=a042581f4e29026704d"
/>
</DropdownTrigger>
<DropdownMenu aria-label="Profile Actions" color="secondary" variant={variant}>
<DropdownItem key="profile" className="h-14 gap-2">
<p className="font-semibold">Signed in as</p>
<p className="font-semibold">zoey@example.com</p>
</DropdownItem>
<DropdownItem key="settings">My Settings</DropdownItem>
<DropdownItem key="team_settings">Team Settings</DropdownItem>
<DropdownItem key="analytics">Analytics</DropdownItem>
<DropdownItem key="system">System</DropdownItem>
<DropdownItem key="configurations">Configurations</DropdownItem>
<DropdownItem key="help_and_feedback">Help & Feedback</DropdownItem>
<DropdownItem key="logout" color="danger">
Log Out
</DropdownItem>
</DropdownMenu>
</Dropdown>
<Dropdown {...args} placement="bottom-start">
<DropdownTrigger>
<User
as="button"
avatarProps={{
isBordered: true,
color: "primary",
size: "md",
src: "https://i.pravatar.cc/150?u=a042581f4e29026024d",
}}
className="transition-transform"
description="@tonyreichert"
name="Tony Reichert"
/>
</DropdownTrigger>
<DropdownMenu aria-label="User Actions" color="primary" variant={variant}>
<DropdownItem key="profile" className="h-14 gap-2">
<p className="font-bold">Signed in as</p>
<p className="font-bold">@tonyreichert</p>
</DropdownItem>
<DropdownItem key="settings">My Settings</DropdownItem>
<DropdownItem key="team_settings">Team Settings</DropdownItem>
<DropdownItem key="analytics">Analytics</DropdownItem>
<DropdownItem key="system">System</DropdownItem>
<DropdownItem key="configurations">Configurations</DropdownItem>
<DropdownItem key="help_and_feedback">Help & Feedback</DropdownItem>
<DropdownItem key="logout" color="danger">
Log Out
</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
);
};
export const Default = {
render: Template,
args: {
...defaultProps,
},
};
export const Dynamic = {
render: DynamicTemplate,
args: {
...defaultProps,
},
};
export const WithArrow = {
render: Template,
args: {
...defaultProps,
showArrow: true,
},
};
export const WithDivider = {
render: DividerTemplate,
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]",
},
};
export const WithCustomTrigger = {
render: CustomTriggerTemplate,
args: {
...defaultProps,
variant: "flat",
offset: 14,
},
};
export const DisableAnimation = {
render: WithStartContentTemplate,
args: {
...defaultProps,
showArrow: true,
variant: "flat",
color: "secondary",
disableAnimation: true,
},
};