Skip to content

Commit 663dc26

Browse files
committed
feat: sidebar
1 parent a22a170 commit 663dc26

File tree

5 files changed

+198
-139
lines changed

5 files changed

+198
-139
lines changed

electron/renderer/components/layout.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { EuiPageTemplate } from '@elastic/eui';
22
import type { ReactNode } from 'react';
3-
import { SidebarContainer } from './sidebar';
3+
import { Sidebar } from './sidebar';
44

55
export interface LayoutProps {
66
/**
@@ -22,7 +22,7 @@ export const Layout: React.FC<LayoutProps> = (
2222
return (
2323
<EuiPageTemplate grow={true} responsive={[]}>
2424
<EuiPageTemplate.Sidebar minWidth={50} paddingSize="xs" responsive={[]}>
25-
<SidebarContainer />
25+
<Sidebar />
2626
</EuiPageTemplate.Sidebar>
2727
<EuiPageTemplate.Section paddingSize="none" grow={true}>
2828
{children}
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
export * from './sidebar-container';
1+
export * from './sidebar';
2+
export * from './sidebar-item';

electron/renderer/components/sidebar/sidebar-container.tsx

-136
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import type { EuiButtonIconProps } from '@elastic/eui';
2+
import { EuiButtonIcon, EuiPopover, EuiToolTip } from '@elastic/eui';
3+
import type { ReactNode } from 'react';
4+
import { useCallback, useState } from 'react';
5+
6+
export interface SidebarItemProps {
7+
label: EuiButtonIconProps['aria-label'];
8+
iconType: EuiButtonIconProps['iconType'];
9+
iconColor?: EuiButtonIconProps['color'];
10+
iconSize?: EuiButtonIconProps['iconSize'];
11+
/**
12+
* The content of the popover when the button is clicked.
13+
* Ignored if `onClick` is defined.
14+
*/
15+
popoverContent?: ReactNode;
16+
/**
17+
* Callback to be notified when the button is clicked.
18+
* Designed when you don't want to use a popover but
19+
* rather take some other custom action, such as routing.
20+
* If defined then `popoverContent` is ignored.
21+
*/
22+
onClick?: () => void;
23+
}
24+
25+
export const SidebarItem: React.FC<SidebarItemProps> = (
26+
props: SidebarItemProps
27+
): ReactNode => {
28+
const { label, iconType, iconColor, iconSize, popoverContent } = props;
29+
30+
const [showTooltip, setShowTooltip] = useState(true);
31+
const [showPopover, setShowPopover] = useState(false);
32+
33+
const onClosePopover = useCallback(() => {
34+
setShowTooltip(true);
35+
setShowPopover(false);
36+
}, []);
37+
38+
const togglePopoverAndTooltip = useCallback(() => {
39+
if (!popoverContent) {
40+
return;
41+
}
42+
setShowTooltip((prev) => !prev);
43+
setShowPopover((prev) => !prev);
44+
}, [popoverContent]);
45+
46+
const onClickButton = props.onClick ?? togglePopoverAndTooltip;
47+
48+
const buttonElmt = (
49+
<EuiPopover
50+
isOpen={showPopover}
51+
closePopover={onClosePopover}
52+
button={
53+
<EuiButtonIcon
54+
aria-label={label}
55+
iconType={iconType}
56+
color={iconColor}
57+
iconSize={iconSize}
58+
css={{
59+
'min-width': 50,
60+
'min-height': 50,
61+
'height': 50,
62+
'width': 50,
63+
}}
64+
onClick={onClickButton}
65+
/>
66+
}
67+
>
68+
{popoverContent}
69+
</EuiPopover>
70+
);
71+
72+
if (showTooltip) {
73+
return (
74+
<EuiToolTip aria-label={label} content={label} position="right">
75+
{buttonElmt}
76+
</EuiToolTip>
77+
);
78+
}
79+
80+
return buttonElmt;
81+
};
82+
83+
SidebarItem.displayName = 'SidebarItem';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { EuiFlexGroup, EuiFlexItem, EuiFlyout, EuiPanel } from '@elastic/eui';
2+
import type { ReactNode } from 'react';
3+
import { useState } from 'react';
4+
import { SidebarItem } from './sidebar-item';
5+
6+
export const Sidebar: React.FC = (): ReactNode => {
7+
const [showCharacters, setShowCharacters] = useState(false);
8+
const [showAccounts, setShowAccounts] = useState(false);
9+
const [showSettings, setShowSettings] = useState(false);
10+
11+
return (
12+
<>
13+
<EuiFlexGroup direction="column" css={{ height: '100%' }}>
14+
<EuiFlexItem grow={false}>
15+
<EuiFlexGroup
16+
direction="column"
17+
gutterSize="none"
18+
alignItems="center"
19+
>
20+
<EuiFlexItem grow={false}>
21+
<SidebarItem
22+
label="Characters"
23+
iconType="user"
24+
iconColor="primary"
25+
iconSize="l"
26+
onClick={() => setShowCharacters(!showCharacters)}
27+
/>
28+
</EuiFlexItem>
29+
<EuiFlexItem grow={false}>
30+
<SidebarItem
31+
label="Accounts"
32+
iconType="key"
33+
iconColor="primary"
34+
iconSize="l"
35+
onClick={() => setShowAccounts(!showAccounts)}
36+
/>
37+
</EuiFlexItem>
38+
</EuiFlexGroup>
39+
</EuiFlexItem>
40+
<EuiFlexItem grow={true}>{/* empty space in the middle */}</EuiFlexItem>
41+
<EuiFlexItem grow={false}>
42+
<EuiFlexGroup
43+
direction="column"
44+
gutterSize="none"
45+
alignItems="center"
46+
>
47+
<EuiFlexItem grow={false}>
48+
<SidebarItem
49+
label="Help"
50+
iconType="questionInCircle"
51+
iconColor="text"
52+
iconSize="xl" // https://github.com/elastic/eui/issues/6322
53+
popoverContent={<div>Help Center</div>}
54+
></SidebarItem>
55+
</EuiFlexItem>
56+
<EuiFlexItem grow={false}>
57+
<SidebarItem
58+
label="Settings"
59+
iconType="gear"
60+
iconColor="text"
61+
iconSize="l"
62+
onClick={() => setShowSettings(!showSettings)}
63+
/>
64+
</EuiFlexItem>
65+
</EuiFlexGroup>
66+
</EuiFlexItem>
67+
</EuiFlexGroup>
68+
69+
{showCharacters && (
70+
<EuiFlyout
71+
side="left"
72+
type="overlay"
73+
paddingSize="s"
74+
size="s"
75+
outsideClickCloses={true}
76+
onClose={() => setShowCharacters(false)}
77+
>
78+
<EuiPanel>Characters</EuiPanel>
79+
</EuiFlyout>
80+
)}
81+
82+
{showAccounts && (
83+
<EuiFlyout
84+
side="left"
85+
type="overlay"
86+
paddingSize="s"
87+
size="s"
88+
outsideClickCloses={true}
89+
onClose={() => setShowAccounts(false)}
90+
>
91+
<EuiPanel>Accounts</EuiPanel>
92+
</EuiFlyout>
93+
)}
94+
95+
{showSettings && (
96+
<EuiFlyout
97+
side="left"
98+
type="overlay"
99+
paddingSize="s"
100+
size="s"
101+
outsideClickCloses={true}
102+
onClose={() => setShowSettings(false)}
103+
>
104+
<EuiPanel>Settings</EuiPanel>
105+
</EuiFlyout>
106+
)}
107+
</>
108+
);
109+
};
110+
111+
Sidebar.displayName = 'Sidebar';

0 commit comments

Comments
 (0)