Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiHeaderLinks] Providing more flexibility in display #4046

Merged
merged 15 commits into from
Sep 22, 2020
Merged
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## [`master`](https://github.com/elastic/eui/tree/master)

No public interface changes since `29.0.0`.
- Added `gutterSize`, `popoverBreakpoints`, `popoverButtonProps`, and `popoverProps` props to `EuiHeaderLinks` ([#4046](https://github.com/elastic/eui/pull/4046))
- Added `'all'` and `'none'` options to the `sizes` prop of `EuiHideFor` and `EuiShowFor` ([#4046](https://github.com/elastic/eui/pull/4046))


## [`29.0.0`](https://github.com/elastic/eui/tree/v29.0.0)

Expand Down
322 changes: 305 additions & 17 deletions src-docs/src/views/header/header.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
import React from 'react';
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
cchaos marked this conversation as resolved.
Show resolved Hide resolved

import {
EuiAvatar,
EuiButton,
EuiFlexGroup,
EuiFlexItem,
EuiHeader,
EuiHeaderBreadcrumbs,
EuiHeaderLogo,
EuiHeaderSection,
EuiHeaderSectionItem,
EuiHeaderSectionItemButton,
EuiHeaderLogo,
EuiIcon,
EuiKeyPadMenu,
EuiKeyPadMenuItem,
EuiLink,
EuiPopover,
EuiPopoverFooter,
EuiPopoverTitle,
EuiSelectable,
EuiSelectableMessage,
EuiSelectableTemplateSitewide,
EuiSpacer,
EuiText,
} from '../../../../src/components';

import HeaderAppMenu from './header_app_menu';
import HeaderUserMenu from './header_user_menu';
import HeaderSpacesMenu from './header_spaces_menu';
Comment on lines -13 to -15
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these imports to to be directly declared in this file. Now the CodeSandbox works 🎉

import { htmlIdGenerator } from '../../../../src/services';

export default () => {
const renderLogo = () => (
<EuiHeaderLogo
iconType="logoKibana"
iconType="logoElastic"
href="#"
onClick={e => e.preventDefault()}
aria-label="Go to home page"
/>
);
Expand All @@ -30,7 +44,6 @@ export default () => {
href: '#',
onClick: e => {
e.preventDefault();
console.log('You clicked management');
},
'data-test-subj': 'breadcrumbsAnimals',
className: 'customClass',
Expand All @@ -40,23 +53,20 @@ export default () => {
href: '#',
onClick: e => {
e.preventDefault();
console.log('You clicked truncation test');
},
},
{
text: 'hidden',
text: 'Hidden',
href: '#',
onClick: e => {
e.preventDefault();
console.log('You clicked hidden');
},
},
{
text: 'Users',
href: '#',
onClick: e => {
e.preventDefault();
console.log('You clicked users');
},
},
{
Expand All @@ -72,10 +82,29 @@ export default () => {
);
};

const renderSearch = () => (
<EuiHeaderSectionItemButton aria-label="Search">
<EuiIcon type="search" size="m" />
</EuiHeaderSectionItemButton>
const search = (
<EuiSelectableTemplateSitewide
options={[]}
searchProps={{
compressed: true,
}}
popoverButton={
<EuiHeaderSectionItemButton aria-label="Sitewide search">
<EuiIcon type="search" size="m" />
</EuiHeaderSectionItemButton>
}
emptyMessage={
<EuiSelectableMessage style={{ minHeight: 300 }}>
<p>
Please see the component page for{' '}
<Link to="/forms/selectable">
<strong>EuiSelectableTemplateSitewide</strong>
</Link>{' '}
on how to configure your sitewide search.
</p>
</EuiSelectableMessage>
}
/>
);

return (
Expand All @@ -92,7 +121,7 @@ export default () => {
{renderBreadcrumbs()}

<EuiHeaderSection side="right">
<EuiHeaderSectionItem>{renderSearch()}</EuiHeaderSectionItem>
<EuiHeaderSectionItem>{search}</EuiHeaderSectionItem>

<EuiHeaderSectionItem>
<HeaderUserMenu />
Expand All @@ -105,3 +134,262 @@ export default () => {
</EuiHeader>
);
};

const HeaderUserMenu = () => {
const id = htmlIdGenerator()();
const [isOpen, setIsOpen] = useState(false);

const onMenuButtonClick = () => {
setIsOpen(!isOpen);
};

const closeMenu = () => {
setIsOpen(false);
};

const button = (
<EuiHeaderSectionItemButton
aria-controls={id}
aria-expanded={isOpen}
aria-haspopup="true"
aria-label="Account menu"
onClick={onMenuButtonClick}>
<EuiAvatar name="John Username" size="s" />
</EuiHeaderSectionItemButton>
);

return (
<EuiPopover
id={id}
ownFocus
button={button}
isOpen={isOpen}
anchorPosition="downRight"
closePopover={closeMenu}
panelPaddingSize="none">
<div style={{ width: 320 }}>
<EuiFlexGroup
gutterSize="m"
className="euiHeaderProfile"
responsive={false}>
<EuiFlexItem grow={false}>
<EuiAvatar name="John Username" size="xl" />
</EuiFlexItem>

<EuiFlexItem>
<EuiText>
<p>John Username</p>
</EuiText>

<EuiSpacer size="m" />

<EuiFlexGroup>
<EuiFlexItem>
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiLink>Edit profile</EuiLink>
</EuiFlexItem>

<EuiFlexItem grow={false}>
<EuiLink>Log out</EuiLink>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</div>
</EuiPopover>
);
};

const HeaderSpacesMenu = () => {
const id = htmlIdGenerator()();
const spacesValues = [
{
label: 'Sales team',
prepend: <EuiAvatar type="space" name="Sales Team" size="s" />,
checked: 'on',
},
{
label: 'Engineering',
prepend: <EuiAvatar type="space" name="Engineering" size="s" />,
},
{
label: 'Security',
prepend: <EuiAvatar type="space" name="Security" size="s" />,
},
{
label: 'Default',
prepend: <EuiAvatar type="space" name="Default" size="s" />,
},
];

const additionalSpaces = [
{
label: 'Sales team 2',
prepend: <EuiAvatar type="space" name="Sales Team 2" size="s" />,
},
{
label: 'Engineering 2',
prepend: <EuiAvatar type="space" name="Engineering 2" size="s" />,
},
{
label: 'Security 2',
prepend: <EuiAvatar type="space" name="Security 2" size="s" />,
},
{
label: 'Default 2',
prepend: <EuiAvatar type="space" name="Default 2" size="s" />,
},
];

const [spaces, setSpaces] = useState(spacesValues);
const [selectedSpace, setSelectedSpace] = useState(
spaces.filter(option => option.checked)[0]
);
const [isOpen, setIsOpen] = useState(false);

const isListExtended = () => {
return spaces.length > 4 ? true : false;
};

const onMenuButtonClick = () => {
setIsOpen(!isOpen);
};

const closePopover = () => {
setIsOpen(false);
};

const onChange = options => {
setSpaces(options);
setSelectedSpace(options.filter(option => option.checked)[0]);
setIsOpen(false);
};

const addMoreSpaces = () => {
setSpaces(spaces.concat(additionalSpaces));
};

const button = (
<EuiHeaderSectionItemButton
aria-controls={id}
aria-expanded={isOpen}
aria-haspopup="true"
aria-label="Spaces menu"
onClick={onMenuButtonClick}>
{selectedSpace.prepend}
</EuiHeaderSectionItemButton>
);

return (
<EuiPopover
id={id}
ownFocus
button={button}
isOpen={isOpen}
anchorPosition="downLeft"
closePopover={closePopover}
panelPaddingSize="none">
<EuiSelectable
searchable={isListExtended()}
searchProps={{
placeholder: 'Find a space',
compressed: true,
}}
options={spaces}
singleSelection="always"
style={{ width: 300 }}
onChange={onChange}
listProps={{
rowHeight: 40,
showIcons: false,
}}>
{(list, search) => (
<>
<EuiPopoverTitle>{search || 'Your spaces'}</EuiPopoverTitle>
{list}
<EuiPopoverFooter>
<EuiButton
size="s"
fullWidth
onClick={addMoreSpaces}
disabled={isListExtended()}>
Add more spaces
</EuiButton>
</EuiPopoverFooter>
</>
)}
</EuiSelectable>
</EuiPopover>
);
};

const HeaderAppMenu = () => {
const idGenerator = htmlIdGenerator();
const popoverId = idGenerator('popover');
const keypadId = idGenerator('keypad');

const [isOpen, setIsOpen] = useState(false);

const onMenuButtonClick = () => {
setIsOpen(!isOpen);
};

const closeMenu = () => {
setIsOpen(false);
};

const button = (
<EuiHeaderSectionItemButton
aria-controls={keypadId}
aria-expanded={isOpen}
aria-haspopup="true"
aria-label="Apps menu with 1 new app"
notification="1"
onClick={onMenuButtonClick}>
<EuiIcon type="apps" size="m" />
</EuiHeaderSectionItemButton>
);

return (
<EuiPopover
id={popoverId}
ownFocus
button={button}
isOpen={isOpen}
anchorPosition="downRight"
closePopover={closeMenu}>
<EuiKeyPadMenu id={keypadId} style={{ width: 288 }}>
<EuiKeyPadMenuItem label="Discover">
<EuiIcon type="discoverApp" size="l" />
</EuiKeyPadMenuItem>

<EuiKeyPadMenuItem label="Dashboard">
<EuiIcon type="dashboardApp" size="l" />
</EuiKeyPadMenuItem>

<EuiKeyPadMenuItem label="Dev Tools">
<EuiIcon type="devToolsApp" size="l" />
</EuiKeyPadMenuItem>

<EuiKeyPadMenuItem label="Machine Learning">
<EuiIcon type="machineLearningApp" size="l" />
</EuiKeyPadMenuItem>

<EuiKeyPadMenuItem label="Graph">
<EuiIcon type="graphApp" size="l" />
</EuiKeyPadMenuItem>

<EuiKeyPadMenuItem label="Visualize">
<EuiIcon type="visualizeApp" size="l" />
</EuiKeyPadMenuItem>

<EuiKeyPadMenuItem label="Timelion" betaBadgeLabel="Beta">
<EuiIcon type="timelionApp" size="l" />
</EuiKeyPadMenuItem>
</EuiKeyPadMenu>
</EuiPopover>
);
};
Loading