diff --git a/packages/menu/README.md b/packages/menu/README.md
index 8c64ee2de..7e12bd282 100644
--- a/packages/menu/README.md
+++ b/packages/menu/README.md
@@ -18,6 +18,8 @@ Check out [storybook](https://zendeskgarden.github.io/react-containers) for live
### useMenu
+#### Menu items
+
```jsx
import { useMenu } from '@zendeskgarden/container-menu';
@@ -50,6 +52,40 @@ const Menu = () => {
};
```
+#### Menu links
+
+```jsx
+import { useMenu } from '@zendeskgarden/container-menu';
+
+const Menu = () => {
+ const triggerRef = useRef();
+ const menuRef = useRef();
+ const items = [
+ { value: 'home', label: 'Home', href="#", selected: true },
+ { value: 'about', label: 'About', href="www.example.com/about" },
+ { value: 'support', label: 'Support', href="www.support.example.com", external: true }
+ ];
+ const { isExpanded, getTriggerProps, getMenuProps, getItemProps, getAnchorProps } = useMenu({
+ triggerRef,
+ menuRef,
+ items
+ });
+
+ return (
+ <>
+
+
+ >
+ );
+};
+```
+
### MenuContainer
```jsx
@@ -61,27 +97,20 @@ const Menu = () => {
const items = [
{ value: 'value-1', label: 'One' },
{ value: 'value-2', label: 'Two' },
- { value: 'value-3', label: 'Three', href: '#0' },
- { value: 'value-4', label: 'Four' }
+ { value: 'value-3', label: 'Three' }
];
return (
- {({ isExpanded, getTriggerProps, getMenuProps, getItemProps, getSeparatorProps }) => (
+ {({ isExpanded, getTriggerProps, getMenuProps, getItemProps }) => (
<>
- {items.map(item =>
- item.href ? (
- -
- {item.label}
-
- ) : (
- -
- {item.label}
-
- )
- )}
+ {items.map(item => (
+ -
+ {item.label}
+
+ ))}
>
)}
diff --git a/packages/menu/demo/menu.stories.tsx b/packages/menu/demo/menu.stories.tsx
index 76723ddab..ddd81132d 100644
--- a/packages/menu/demo/menu.stories.tsx
+++ b/packages/menu/demo/menu.stories.tsx
@@ -48,6 +48,8 @@ export const Controlled: Story = {
return (
{
updateArgs(rest);
diff --git a/packages/menu/demo/stories/MenuStory.tsx b/packages/menu/demo/stories/MenuStory.tsx
index a60b8ecf8..4fc2a225e 100644
--- a/packages/menu/demo/stories/MenuStory.tsx
+++ b/packages/menu/demo/stories/MenuStory.tsx
@@ -5,7 +5,7 @@
* found at http://www.apache.org/licenses/LICENSE-2.0.
*/
-import React, { AnchorHTMLAttributes, LiHTMLAttributes, useRef } from 'react';
+import React, { useEffect, useRef } from 'react';
import { StoryFn } from '@storybook/react';
import classNames from 'classnames';
import {
@@ -29,18 +29,20 @@ interface IUseMenuComponentProps extends MenuReturnValue {
type MenuItemProps = {
item: IMenuItemBase;
getItemProps: IUseMenuComponentProps['getItemProps'];
+ getAnchorProps: IUseMenuComponentProps['getAnchorProps'];
focusedValue: IUseMenuComponentProps['focusedValue'];
isSelected?: boolean;
};
-const Item = ({ item, getItemProps, focusedValue, isSelected }: MenuItemProps) => {
- const itemProps = getItemProps({ item });
+const Item = ({ item, getAnchorProps, getItemProps, focusedValue, isSelected }: MenuItemProps) => {
+ const itemProps = getItemProps({ item });
+ const anchorProps = getAnchorProps({ item });
const itemChildren = (
<>
- {item?.type === 'radio' && !!isSelected && '•'}
- {item?.type === 'checkbox' && !!isSelected && '✓'}
+ {!!isSelected && item.type === 'radio' && '•'}
+ {!!isSelected && (item.type === 'checkbox' || !!item.href) && '✓'}
{item.label || item.value}
>
@@ -54,16 +56,21 @@ const Item = ({ item, getItemProps, focusedValue, isSelected }: MenuItemProps) =
'cursor-pointer': !item.disabled,
'cursor-default': item.disabled
})}
- role={itemProps.href ? 'none' : undefined}
- {...(!itemProps.href && (itemProps as LiHTMLAttributes))}
+ {...itemProps}
>
- {itemProps.href ? (
+ {anchorProps ? (
)}
- className="w-full rounded-sm outline-offset-0 transition-none border-width-none"
+ {...anchorProps}
+ className={classNames(
+ ' w-full rounded-sm outline-offset-0 transition-none border-width-none',
+ {
+ 'text-grey-400': item.disabled,
+ 'cursor-default': item.disabled
+ }
+ )}
>
{itemChildren}
- {!!item.isExternal && (
+ {anchorProps.target === '_blank' && (
<>
↗
(opens in new window)
@@ -85,11 +92,20 @@ const Component = ({
getTriggerProps,
getMenuProps,
getItemProps,
+ getAnchorProps,
getItemGroupProps,
getSeparatorProps
}: MenuReturnValue & UseMenuProps) => {
const selectedValues = selection.map(item => item.value);
+ useEffect(() => {
+ const originalWindowOpen = window.open;
+ window.open = () => null;
+ return () => {
+ window.open = originalWindowOpen;
+ };
+ }, []);
+
return (