Skip to content

Commit

Permalink
Merge pull request #142 from abusix/pla-1313-hailstorm-add-popover-co…
Browse files Browse the repository at this point in the history
…mponent-for-evergreen-popover
  • Loading branch information
Coderwelsch authored Aug 6, 2024
2 parents bc36720 + 48784f1 commit 3632d35
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 25 deletions.
5 changes: 5 additions & 0 deletions src/components/popover-menu/popover-menu-panel-divider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from "react";

export const PopoverMenuPanelDivider = () => {
return <div className="h-px w-full bg-neutral-300" />;
};
9 changes: 9 additions & 0 deletions src/components/popover-menu/popover-menu-panel-group.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react";

export interface PopoverMenuGroupProps {
children: React.ReactNode;
}

export const PopoverMenuPanelGroup = ({ children }: PopoverMenuGroupProps) => {
return <div className="flex flex-col">{children}</div>;
};
49 changes: 49 additions & 0 deletions src/components/popover-menu/popover-menu-panel-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from "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 PopoverMenuPanelItemProps {
children: React.ReactNode;
onClick?: () => void;
Icon?: React.ComponentType<{ className: string }>;
variant?: keyof typeof itemIntents;
active?: boolean;
}

export const PopoverMenuPanelItem = ({
children,
onClick,
Icon,
variant = "neutral",
active,
}: PopoverMenuPanelItemProps) => {
const intentStyles = itemIntents[variant];

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",
intentStyles,
active && activeItemIntents[variant],
active &&
"before:absolute before:left-0 before:top-0 before:h-full before:w-0.5 before:rounded-r-md"
)}
role="menuitem"
tabIndex={0}
onClick={onClick}
onKeyDown={onClick}
>
{Icon && <Icon className={classNames("h-3.5 w-3.5")} />}
{children}
</div>
);
};
11 changes: 11 additions & 0 deletions src/components/popover-menu/popover-menu-panel-title.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from "react";

export interface PopoverMenuPanelTitleProps {
children: React.ReactNode;
}

export const PopoverMenuPanelTitle = ({ children }: PopoverMenuPanelTitleProps) => {
return (
<p className="px-4 pb-2 pt-3 text-xs font-normal uppercase text-neutral-700">{children}</p>
);
};
32 changes: 10 additions & 22 deletions src/components/popover-menu/popover-menu-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,16 @@
import { PopoverPanel as HeadlessUiPopoverPanel } from "@headlessui/react";
import React from "react";
import { usePopoverMenuContext } from "./popover-menu-context";
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";

export interface PopoverMenuPanelItemProps {
export interface PopoverMenuPanelProps {
children: React.ReactNode;
onClick?: () => void;
}

const PopoverMenuPanelItem = ({ children, onClick }: PopoverMenuPanelItemProps) => {
return (
<button
className="flex w-full cursor-pointer items-center overflow-hidden px-4 py-2 text-sm font-normal hover:bg-neutral-100 focus:ring-2 focus:ring-primary-200"
type="button"
tabIndex={0}
onClick={onClick}
onKeyDown={onClick}
>
{children}
</button>
);
};

export interface NavigationPopoverPanelProps {
children: React.ReactNode;
}

const PopoverMenuPanel = ({ children }: NavigationPopoverPanelProps) => {
const PopoverMenuPanel = ({ children }: PopoverMenuPanelProps) => {
const {
popoverPanel: { setPopperElement, styles, attributes },
} = usePopoverMenuContext();
Expand All @@ -35,13 +20,16 @@ const PopoverMenuPanel = ({ children }: NavigationPopoverPanelProps) => {
ref={(el) => el && setPopperElement(el)}
style={styles}
{...attributes}
className="z-40 ml-2 w-52 rounded bg-neutral-0 py-2 shadow"
className="z-40 w-52 rounded bg-neutral-0 py-2 shadow"
>
{children}
</HeadlessUiPopoverPanel>
);
};

PopoverMenuPanel.Item = PopoverMenuPanelItem;
PopoverMenuPanel.Group = PopoverMenuPanelGroup;
PopoverMenuPanel.Divider = PopoverMenuPanelDivider;
PopoverMenuPanel.Title = PopoverMenuPanelTitle;

export { PopoverMenuPanel };
19 changes: 16 additions & 3 deletions src/components/popover-menu/popover-menu.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +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";

const meta: Meta<typeof PopoverMenu> = {
title: "Popover Menu",
Expand All @@ -25,9 +26,21 @@ export const Default: Story = {
<PopoverMenu.Overlay />

<PopoverMenu.Panel>
<PopoverMenu.Panel.Item>Item 1</PopoverMenu.Panel.Item>
<PopoverMenu.Panel.Item>Item 1</PopoverMenu.Panel.Item>
<PopoverMenu.Panel.Item>Item 1</PopoverMenu.Panel.Item>
<PopoverMenu.Panel.Title>You</PopoverMenu.Panel.Title>

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

<PopoverMenu.Panel.Divider />

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

<PopoverMenu.Panel.Item Icon={DeleteIcon} variant="danger">
Item 1
</PopoverMenu.Panel.Item>
</PopoverMenu.Panel.Group>
</PopoverMenu.Panel>
</PopoverMenu>
</div>
Expand Down

0 comments on commit 3632d35

Please sign in to comment.