mirror of
https://github.com/grafana/grafana.git
synced 2025-02-10 23:55:47 -06:00
UI/MenuItem: Add support for shortcut labels (#62878)
* UI/MenuItem: Add support for shortcut labels * Adjust spacing
This commit is contained in:
parent
8dd75f6c1f
commit
f970745941
@ -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>
|
||||
|
@ -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;
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
@ -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`
|
||||
|
Loading…
Reference in New Issue
Block a user