Skip to content

Commit

Permalink
feat(Menu)!: introduce 2.0 component (#1894)
Browse files Browse the repository at this point in the history
- add stories
- also update constituent sub-components
- nest stories in storybook
- export from index
  • Loading branch information
booc0mtaco authored Mar 19, 2024
1 parent e952d33 commit 3f540f9
Show file tree
Hide file tree
Showing 13 changed files with 959 additions and 1 deletion.
35 changes: 35 additions & 0 deletions src/components/Menu/Menu-v2.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@import '../../design-tokens/mixins.css';

/*------------------------------------*\
# MENU
\*------------------------------------*/

/**
* Menu
*/
.menu {
position: relative;
}

.menu__button {
font: var(--eds-theme-typography-body-md);

color: var(--eds-theme-color-text-neutral-subtle);
background-color: var(--eds-theme-color-form-background);
border-color: var(--eds-theme-color-form-border);
font-weight: var(--eds-font-weight-light);
}

.menu__button--with-chevron {
color: var(--eds-theme-color-icon-neutral-default);
}

.menu__item {
text-decoration: none;
color: inherit;
}

/* Unset the hover on the menu item, as this is handled by the PopoverListItem */
.menu__item:hover {
color: unset;
}
258 changes: 258 additions & 0 deletions src/components/Menu/Menu-v2.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
import type { StoryObj, Meta } from '@storybook/react';
import { userEvent } from '@storybook/testing-library';
import React from 'react';

import { Menu } from './Menu-v2';
import type { MenuProps } from './Menu-v2';
import icons from '../../icons/spritemap';
import type { IconName } from '../../icons/spritemap';
import { Avatar } from '../Avatar/Avatar';

import { Icon } from '../Icon/Icon';
export default {
title: 'Components/V2/Menu',
component: Menu,
parameters: {
badges: ['intro-1.2', 'current-2.0'],
layout: 'centered',
},
argTypes: {
children: {
control: {
type: null,
},
},
},
decorators: [
(Story) => (
<div className="p-8">
<Story />
</div>
),
],
} as Meta<MenuProps>;

export const Default: StoryObj<MenuProps> = {
args: {
children: (
<>
<Menu.Button>Documentation Links</Menu.Button>
<Menu.Items data-testid="menu-content">
<Menu.Item
href="https://headlessui.com/react/menu#menu-button"
icon="link"
>
Headless UI Docs
</Menu.Item>
<Menu.Item
href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu"
icon="link"
>
MDN: Menu
</Menu.Item>
<Menu.Item href="#index" onClick={() => console.log('Item clicked')}>
Trigger Action
</Menu.Item>
<Menu.Item disabled href="https://example.org/" icon="warning">
Not Possible (disabled)
</Menu.Item>
</Menu.Items>
</>
),
},
};

export const WithLongButtonText: StoryObj<MenuProps> = {
args: {
children: (
<>
<Menu.Button>
Long Trigger Button Text to Demonstrate Popover Matching
</Menu.Button>
<Menu.Items data-testid="menu-content">
<Menu.Item
href="https://headlessui.com/react/menu#menu-button"
icon="link"
>
Headless UI Docs
</Menu.Item>
<Menu.Item
href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu"
icon="link"
>
MDN: Menu
</Menu.Item>
{/* eslint-disable-next-line no-alert */}
<Menu.Item onClick={() => alert('Item clicked')}>
Trigger Action
</Menu.Item>
<Menu.Item disabled href="https://example.org/" icon="warning">
Not Possible (disabled)
</Menu.Item>
</Menu.Items>
</>
),
},
};

export const WithShortButtonText: StoryObj<MenuProps> = {
args: {
children: (
<>
<Menu.Button>Menu</Menu.Button>
<Menu.Items data-testid="menu-content">
<Menu.Item
href="https://headlessui.com/react/menu#menu-button"
icon="link"
>
Headless UI Docs
</Menu.Item>
<Menu.Item
href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu"
icon="link"
>
MDN: Menu
</Menu.Item>
{/* eslint-disable-next-line no-alert */}
<Menu.Item onClick={() => alert('Item clicked')}>
Trigger Action
</Menu.Item>
<Menu.Item disabled href="https://example.org/" icon="warning">
Not Possible (disabled)
</Menu.Item>
</Menu.Items>
</>
),
},
};

export const WithCustomButton: StoryObj<MenuProps> = {
args: {
children: (
<>
<Menu.PlainButton>
<div className="fpo">Menu Button</div>
</Menu.PlainButton>
<Menu.Items data-testid="menu-content">
<Menu.Item
href="https://headlessui.com/react/menu#menu-button"
icon="link"
>
Headless UI Docs
</Menu.Item>
<Menu.Item
href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu"
icon="link"
>
MDN: Menu
</Menu.Item>
{/* eslint-disable-next-line no-alert */}
<Menu.Item onClick={() => alert('Item clicked')}>
Trigger Action
</Menu.Item>
<Menu.Item disabled href="https://example.org/" icon="warning">
Not Possible (disabled)
</Menu.Item>
</Menu.Items>
</>
),
},
};

export const MenuWithAvatarButton: StoryObj<MenuProps> = {
parameters: {
badges: ['intro-1.3', 'implementationExample'],
},
args: {
children: (
<>
<Menu.PlainButton>
<Avatar user={{ fullName: 'Josie Sandberg' }} />
</Menu.PlainButton>
<Menu.Items data-testid="menu-content">
<Menu.Item
href="https://headlessui.com/react/menu#menu-button"
icon="link"
>
Headless UI Docs
</Menu.Item>
<Menu.Item
href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu"
icon="link"
>
MDN: Menu
</Menu.Item>
{/* eslint-disable-next-line no-alert */}
<Menu.Item onClick={() => alert('Item clicked')}>
Trigger Action
</Menu.Item>
<Menu.Item disabled href="https://example.org/" icon="warning">
Not Possible (disabled)
</Menu.Item>
</Menu.Items>
</>
),
},
};

export const Opened: StoryObj<MenuProps> = {
...Default,
parameters: {
...Default.parameters,
// Sets the delay (in milliseconds) for a specific story.
chromatic: { delay: 300 },
},
play: async () => {
await userEvent.tab();
await userEvent.keyboard(' ', { delay: 300 });
},
};

export const MenuWithIconButton: StoryObj<MenuProps & { iconName: IconName }> =
{
argTypes: {
iconName: {
control: 'radio',
options: Object.keys(icons),
},
},
args: {
iconName: 'dots-vertical',
},
parameters: {
badges: ['intro-1.2', 'implementationExample'],
},
render: ({ iconName }) => (
<Menu>
<Menu.PlainButton>
<Icon
name={iconName}
purpose="informative"
size="2rem"
title="show more"
/>
</Menu.PlainButton>
<Menu.Items data-testid="menu-content">
<Menu.Item
href="https://headlessui.com/react/menu#menu-button"
icon="link"
>
Headless UI Docs
</Menu.Item>
<Menu.Item
href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu"
icon="link"
>
MDN: Menu
</Menu.Item>
{/* eslint-disable-next-line no-alert */}
<Menu.Item onClick={() => alert('Item clicked')}>
Trigger Action
</Menu.Item>
<Menu.Item disabled href="https://example.org/" icon="warning">
Not Possible (disabled)
</Menu.Item>
</Menu.Items>
</Menu>
),
};
Loading

0 comments on commit 3f540f9

Please sign in to comment.