-
-
Notifications
You must be signed in to change notification settings - Fork 9.1k
/
Menu.tsx
103 lines (90 loc) · 2.51 KB
/
Menu.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import React, { FunctionComponent, useMemo, ComponentProps } from 'react';
import { styled } from '@storybook/theming';
import { WithTooltip, TooltipLinkList, Button, Icons } from '@storybook/components';
export type MenuList = ComponentProps<typeof TooltipLinkList>['links'];
export type MenuButtonProps = ComponentProps<typeof Button> &
// FIXME: Button should extends from the native <button>
ComponentProps<'button'> & {
highlighted: boolean;
};
const sharedStyles = {
height: 10,
width: 10,
marginLeft: -5,
marginRight: -5,
display: 'block',
};
const Icon = styled(Icons)(sharedStyles, ({ theme }) => ({
color: theme.color.secondary,
}));
const Img = styled.img(sharedStyles);
const Placeholder = styled.div(sharedStyles);
export interface ListItemIconProps {
icon?: ComponentProps<typeof Icons>['icon'];
imgSrc?: string;
}
export const MenuItemIcon = ({ icon, imgSrc }: ListItemIconProps) => {
if (icon) {
return <Icon icon={icon} />;
}
if (imgSrc) {
return <Img src={imgSrc} alt="image" />;
}
return <Placeholder />;
};
export const MenuButton = styled(Button)<MenuButtonProps>(({ highlighted, theme }) => ({
position: 'relative',
overflow: 'visible',
padding: 7,
'&:focus': {
background: theme.barBg,
boxShadow: `${theme.color.secondary} 0 0 0 1px inset`,
},
...(highlighted && {
'&:after': {
content: '""',
position: 'absolute',
top: 0,
right: 0,
width: 8,
height: 8,
borderRadius: 8,
background: theme.color.positive,
},
}),
}));
type ClickHandler = ComponentProps<typeof TooltipLinkList>['links'][number]['onClick'];
export const SidebarMenuList: FunctionComponent<{
menu: MenuList;
onHide: () => void;
}> = ({ menu, onHide }) => {
const links = useMemo(() => {
return menu.map(({ onClick, ...rest }) => ({
...rest,
onClick: ((event, item) => {
if (onClick) {
onClick(event, item);
}
onHide();
}) as ClickHandler,
}));
}, [menu]);
return <TooltipLinkList links={links} />;
};
export const SidebarMenu: FunctionComponent<{
menu: MenuList;
isHighlighted: boolean;
}> = ({ isHighlighted, menu }) => {
return (
<WithTooltip
placement="top"
trigger="click"
closeOnClick
tooltip={({ onHide }) => <SidebarMenuList onHide={onHide} menu={menu} />}
>
<MenuButton outline small containsIcon highlighted={isHighlighted} title="Shortcuts">
<Icons icon="ellipsis" />
</MenuButton>
</WithTooltip>
);
};