Skip to content

Commit

Permalink
added additional button component to make the pnael auto closable
Browse files Browse the repository at this point in the history
  • Loading branch information
coderwelsch committed Aug 6, 2024
1 parent c842ffb commit 56fa27c
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 59 deletions.
45 changes: 45 additions & 0 deletions src/components/popover-menu/popover-menu-panel-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from "react";
import { PopoverButton as HeadlessUiPopoverButton } from "@headlessui/react";
import { classNames } from "../../util/class-names";

const itemIntents = {
neutral: "text-neutral-700 fill-neutral-700 hover:bg-primary-100",
danger: "text-danger-500 fill-danger-500 hover:bg-danger-100",
};

const activeItemIntents = {
neutral: "bg-primary-100 fill-primary-400 text-primary-400 before:bg-primary-400",
danger: "bg-danger-100 fill-danger-400 text-danger-500 before:bg-danger-400",
};

export interface PopoverMenuPanelButtonProps {
children: React.ReactNode;
onClick?: () => void;
Icon?: React.ComponentType<{ className: string }>;
variant?: keyof typeof itemIntents;
active?: boolean;
}

export const PopoverMenuPanelButton = ({
children,
onClick,
Icon,
variant = "neutral",
active,
}: PopoverMenuPanelButtonProps) => {
return (
<HeadlessUiPopoverButton
className={classNames(
"relative flex w-full cursor-pointer flex-row items-center gap-3 overflow-hidden px-4 py-2 text-sm font-normal focus:ring-2 focus:ring-primary-200",
itemIntents[variant],
active && activeItemIntents[variant],
active &&
"before:absolute before:left-0 before:top-0 before:h-full before:w-0.5 before:rounded-r-md"
)}
onClick={onClick}
>
{Icon && <Icon className={classNames("h-3.5 w-3.5")} />}
{children}
</HeadlessUiPopoverButton>
);
};
48 changes: 17 additions & 31 deletions src/components/popover-menu/popover-menu-panel-item.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React from "react";
import { PopoverButton as HeadlessUiPopoverButton } from "@headlessui/react";
import { classNames } from "../../util/class-names";

const itemIntents = {
neutral: "text-neutral-700 fill-neutral-700 hover:bg-primary-100",
danger: "text-danger-500 fill-danger-500 hover:bg-danger-100",
};

const activeItemIntents = {
const selectedItemIntents = {
neutral: "bg-primary-100 fill-primary-400 text-primary-400 before:bg-primary-400",
danger: "bg-danger-100 fill-danger-400 text-danger-500 before:bg-danger-400",
};
Expand All @@ -17,45 +16,32 @@ export interface PopoverMenuPanelItemProps {
onClick?: () => void;
Icon?: React.ComponentType<{ className: string }>;
variant?: keyof typeof itemIntents;
active?: boolean;
closeOnClick?: boolean;
selected?: boolean;
}

export const PopoverMenuPanelItem = ({
children,
onClick,
Icon,
variant = "neutral",
active,
closeOnClick,
selected,
}: PopoverMenuPanelItemProps) => {
const intentStyles = itemIntents[variant];
const classes = classNames(
"relative flex w-full cursor-pointer flex-row items-center gap-3 overflow-hidden px-4 py-2 text-sm font-normal focus:ring-2 focus:ring-primary-200",
intentStyles,
active && activeItemIntents[variant],
active &&
"before:absolute before:left-0 before:top-0 before:h-full before:w-0.5 before:rounded-r-md"
);

const content = (
<>
return (
<div
className={classNames(
"relative flex w-full cursor-pointer flex-row items-center gap-3 overflow-hidden px-4 py-2 text-sm font-normal focus:ring-2 focus:ring-primary-200",
itemIntents[variant],
selected && selectedItemIntents[variant],
selected &&
"before:absolute before:left-0 before:top-0 before:h-full before:w-0.5 before:rounded-r-md"
)}
onClick={onClick}
role="menuitem"
onKeyDown={onClick}
tabIndex={0}
>
{Icon && <Icon className={classNames("h-3.5 w-3.5")} />}
{children}
</>
);

if (closeOnClick) {
return (
<HeadlessUiPopoverButton className={classes} onClick={onClick}>
{content}
</HeadlessUiPopoverButton>
);
}

return (
<div className={classes} onClick={onClick} role="menuitem" onKeyDown={onClick} tabIndex={0}>
{content}
</div>
);
};
2 changes: 2 additions & 0 deletions src/components/popover-menu/popover-menu-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { PopoverMenuPanelGroup } from "./popover-menu-panel-group";
import { PopoverMenuPanelItem } from "./popover-menu-panel-item";
import { PopoverMenuPanelDivider } from "./popover-menu-panel-divider";
import { PopoverMenuPanelTitle } from "./popover-menu-panel-title";
import { PopoverMenuPanelButton } from "./popover-menu-panel-button";

export interface PopoverMenuPanelProps {
children: React.ReactNode;
Expand All @@ -28,6 +29,7 @@ const PopoverMenuPanel = ({ children }: PopoverMenuPanelProps) => {
};

PopoverMenuPanel.Item = PopoverMenuPanelItem;
PopoverMenuPanel.Button = PopoverMenuPanelButton;
PopoverMenuPanel.Group = PopoverMenuPanelGroup;
PopoverMenuPanel.Divider = PopoverMenuPanelDivider;
PopoverMenuPanel.Title = PopoverMenuPanelTitle;
Expand Down
58 changes: 30 additions & 28 deletions src/components/popover-menu/popover-menu.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Meta, StoryObj } from "@storybook/react";
import React from "react";
import { PopoverMenu } from "./popover-menu";
import { AddIcon, ChatIcon, DeleteIcon, EditIcon } from "../../icons";
import { ChatIcon, DeleteIcon, EditIcon } from "../../icons";

const meta: Meta<typeof PopoverMenu> = {
title: "Popover Menu",
Expand All @@ -18,39 +18,41 @@ export default meta;
type Story = StoryObj<typeof PopoverMenu>;

export const Default: Story = {
render: () => (
<div className="relative flex min-h-screen min-w-736 flex-col">
<PopoverMenu>
<PopoverMenu.Button variant="secondary">Open Popover Menu</PopoverMenu.Button>
render: () => {
const [isActive, setIsActive] = React.useState(false);

<PopoverMenu.Overlay />
return (
<div className="relative flex min-h-screen min-w-736 flex-col">
<PopoverMenu>
<PopoverMenu.Button variant="secondary">Open Popover Menu</PopoverMenu.Button>

<PopoverMenu.Panel>
<PopoverMenu.Panel.Title>You</PopoverMenu.Panel.Title>
<PopoverMenu.Overlay />

<PopoverMenu.Panel.Item closeOnClick Icon={EditIcon}>
Edit profile
</PopoverMenu.Panel.Item>
<PopoverMenu.Panel>
<PopoverMenu.Panel.Title>You</PopoverMenu.Panel.Title>

<PopoverMenu.Panel.Item closeOnClick Icon={ChatIcon}>
Support
</PopoverMenu.Panel.Item>
<PopoverMenu.Panel.Item
Icon={EditIcon}
selected={isActive}
onClick={() => setIsActive(!isActive)}
>
Activate Mfa
</PopoverMenu.Panel.Item>

<PopoverMenu.Panel.Item closeOnClick Icon={AddIcon}>
Invite member
</PopoverMenu.Panel.Item>
<PopoverMenu.Panel.Item Icon={ChatIcon}>Support</PopoverMenu.Panel.Item>

<PopoverMenu.Panel.Divider />
<PopoverMenu.Panel.Divider />

<PopoverMenu.Panel.Group>
<PopoverMenu.Panel.Title>Danger Zone</PopoverMenu.Panel.Title>
<PopoverMenu.Panel.Group>
<PopoverMenu.Panel.Title>Danger Zone</PopoverMenu.Panel.Title>

<PopoverMenu.Panel.Item closeOnClick Icon={DeleteIcon} variant="danger">
Delete Account
</PopoverMenu.Panel.Item>
</PopoverMenu.Panel.Group>
</PopoverMenu.Panel>
</PopoverMenu>
</div>
),
<PopoverMenu.Panel.Button Icon={DeleteIcon} variant="danger">
Close this Dialog
</PopoverMenu.Panel.Button>
</PopoverMenu.Panel.Group>
</PopoverMenu.Panel>
</PopoverMenu>
</div>
);
},
};

0 comments on commit 56fa27c

Please sign in to comment.