Skip to content

Commit 08d9cb9

Browse files
committed
Menu: Add LinkItem subcomponent
1 parent fdd7b4f commit 08d9cb9

6 files changed

Lines changed: 58 additions & 0 deletions

File tree

‎packages/ui/src/menu/index.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { GroupLabel } from './group-label';
44
import { Item } from './item';
55
import { ItemDescription } from './item-description';
66
import { ItemLabel } from './item-label';
7+
import { LinkItem } from './link-item';
78
import { Popup } from './popup';
89
import { Portal } from './portal';
910
import { Positioner } from './positioner';
@@ -22,6 +23,7 @@ export {
2223
Item,
2324
ItemDescription,
2425
ItemLabel,
26+
LinkItem,
2527
Popup,
2628
Portal,
2729
Positioner,

‎packages/ui/src/menu/link-item.tsx‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Menu as _Menu } from '@base-ui/react/menu';
2+
import clsx from 'clsx';
3+
import { forwardRef } from '@wordpress/element';
4+
import itemPopupStyles from '../utils/css/item-popup.module.css';
5+
import defenseStyles from '../utils/css/global-css-defense.module.css';
6+
import resetStyles from '../utils/css/resets.module.css';
7+
import styles from './style.module.css';
8+
import { ItemContent } from './item';
9+
import type { LinkItemProps } from './types';
10+
11+
/**
12+
* Renders a menu item that navigates to a link target.
13+
*/
14+
const LinkItem = forwardRef< Element, LinkItemProps >( function MenuLinkItem(
15+
{ children, className, prefix, suffix, ...props },
16+
ref
17+
) {
18+
return (
19+
<_Menu.LinkItem
20+
ref={ ref }
21+
className={ clsx(
22+
defenseStyles.a,
23+
resetStyles[ 'box-sizing' ],
24+
itemPopupStyles.item,
25+
styles.item,
26+
className
27+
) }
28+
{ ...props }
29+
>
30+
<ItemContent prefix={ prefix } suffix={ suffix }>
31+
{ children }
32+
</ItemContent>
33+
</_Menu.LinkItem>
34+
);
35+
} );
36+
37+
export { LinkItem };

‎packages/ui/src/menu/stories/index.story.tsx‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const meta: Meta< typeof Menu.Root > = {
1515
'Menu.Item': Menu.Item,
1616
'Menu.ItemLabel': Menu.ItemLabel,
1717
'Menu.ItemDescription': Menu.ItemDescription,
18+
'Menu.LinkItem': Menu.LinkItem,
1819
'Menu.CheckboxItem': Menu.CheckboxItem,
1920
'Menu.RadioGroup': Menu.RadioGroup,
2021
'Menu.RadioItem': Menu.RadioItem,
@@ -62,6 +63,9 @@ export const Default: Story = {
6263
<Menu.Item>Play last</Menu.Item>
6364
</Menu.Group>
6465
<Menu.Separator />
66+
<Menu.LinkItem href="https://wordpress.org">
67+
WordPress.org
68+
</Menu.LinkItem>
6569
<Menu.Item disabled>Unavailable action</Menu.Item>
6670
</Menu.Popup>
6771
</>

‎packages/ui/src/menu/style.module.css‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
display: grid;
6262
grid-column: 1 / -1;
6363
grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
64+
text-decoration: none;
6465

6566
@supports ( grid-template-columns: subgrid ) {
6667
grid-template-columns: subgrid;

‎packages/ui/src/menu/test/index.test.tsx‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ describe( 'Menu', () => {
1313
<Menu.Popup>
1414
<Menu.Item>Duplicate</Menu.Item>
1515
<Menu.Separator />
16+
<Menu.LinkItem href="https://wordpress.org">
17+
WordPress.org
18+
</Menu.LinkItem>
1619
<Menu.Item>Delete</Menu.Item>
1720
</Menu.Popup>
1821
</Menu.Root>
@@ -29,6 +32,9 @@ describe( 'Menu', () => {
2932
expect(
3033
screen.getByRole( 'menuitem', { name: 'Duplicate' } )
3134
).toBeVisible();
35+
expect(
36+
screen.getByRole( 'menuitem', { name: 'WordPress.org' } )
37+
).toHaveAttribute( 'href', 'https://wordpress.org' );
3238
expect( screen.getByRole( 'separator' ) ).toBeVisible();
3339
} );
3440

‎packages/ui/src/menu/types.ts‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ export type ItemProps = MenuItemComponentProps< typeof _Menu.Item > &
9494
children?: ReactNode;
9595
};
9696

97+
export type LinkItemProps = MenuItemComponentProps< typeof _Menu.LinkItem > &
98+
MenuItemLayoutProps & {
99+
/**
100+
* The content to be rendered inside the link menu item.
101+
*/
102+
children?: ReactNode;
103+
};
104+
97105
export type CheckboxItemProps = MenuItemComponentProps<
98106
typeof _Menu.CheckboxItem
99107
> &

0 commit comments

Comments
 (0)