UI/MenuItem: Add support for shortcut labels (#62878)

* UI/MenuItem: Add support for shortcut labels

* Adjust spacing
This commit is contained in:
kay delaney 2023-02-07 13:41:38 +00:00 committed by GitHub
parent 8dd75f6c1f
commit f970745941
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 16 deletions

View File

@ -98,11 +98,11 @@ export function Examples() {
</Menu.Group>
</Menu>
</StoryExample>
<StoryExample name="With submenu">
<StoryExample name="With submenu and shortcuts">
<Menu>
<Menu.Item label="item1" icon="history" />
<Menu.Item label="item1" icon="history" shortcut="q p" />
<Menu.Item
label="item2"
label="Item with a very long title"
icon="apps"
childItems={[
<Menu.Item key="subitem1" label="subitem1" icon="history" />,
@ -118,8 +118,17 @@ export function Examples() {
]}
/>,
]}
shortcut="p s"
/>
<Menu.Item
label="item3"
icon="filter"
childItems={[
<Menu.Item key="subitem1" label="subitem1" icon="history" />,
<Menu.Item key="subitem2" label="subitem2" icon="apps" />,
<Menu.Item key="subitem3" label="subitem3" icon="search-plus" />,
]}
/>
<Menu.Item label="item3" icon="filter" />
</Menu>
</StoryExample>
</VerticalGroup>

View File

@ -44,6 +44,8 @@ export interface MenuItemProps<T = any> {
childItems?: Array<ReactElement<MenuItemProps>>;
/** Custom style for SubMenu */
customSubMenuContainerStyles?: CSSProperties;
/** Shortcut key combination */
shortcut?: string;
}
/** @internal */
@ -65,6 +67,7 @@ export const MenuItem = React.memo(
role = 'menuitem',
tabIndex = -1,
customSubMenuContainerStyles,
shortcut,
} = props;
const styles = useStyles2(getStyles);
const [isActive, setIsActive] = useState(active);
@ -132,6 +135,8 @@ export const MenuItem = React.memo(
localRef?.current?.focus();
};
const hasShortcut = Boolean(shortcut && shortcut.length > 0);
return (
<ItemElement
target={target}
@ -153,18 +158,26 @@ export const MenuItem = React.memo(
<>
{icon && <Icon name={icon} className={styles.icon} aria-hidden />}
{label}
</>
{hasSubMenu && (
<SubMenu
items={childItems}
isOpen={isSubMenuOpen}
openedWithArrow={openedWithArrow}
setOpenedWithArrow={setOpenedWithArrow}
close={closeSubMenu}
customStyle={customSubMenuContainerStyles}
/>
)}
<div className={cx(styles.rightWrapper, { [styles.withShortcut]: hasShortcut })}>
{hasShortcut && (
<div className={styles.shortcut}>
<Icon name="keyboard" aria-hidden />
{shortcut}
</div>
)}
{hasSubMenu && (
<SubMenu
items={childItems}
isOpen={isSubMenuOpen}
openedWithArrow={openedWithArrow}
setOpenedWithArrow={setOpenedWithArrow}
close={closeSubMenu}
customStyle={customSubMenuContainerStyles}
/>
)}
</div>
</>
</ItemElement>
);
})
@ -238,5 +251,24 @@ const getStyles = (theme: GrafanaTheme2) => {
margin-left: -4px;
color: ${theme.colors.text.secondary};
`,
rightWrapper: css`
display: flex;
align-items: center;
margin-left: auto;
`,
shortcutIcon: css`
margin-right: ${theme.spacing(1)};
`,
withShortcut: css`
min-width: ${theme.spacing(10.5)};
`,
shortcut: css`
display: flex;
align-items: center;
gap: ${theme.spacing(1)};
margin-left: ${theme.spacing(2)};
color: ${theme.colors.text.secondary};
opacity: 0.7;
`,
};
};

View File

@ -74,7 +74,7 @@ const getStyles = (theme: GrafanaTheme2) => {
`,
icon: css`
opacity: 0.7;
margin-left: ${theme.spacing(2)};
margin-left: ${theme.spacing(1)};
color: ${theme.colors.text.secondary};
`,
itemsWrapper: css`