Skip to content

Commit

Permalink
[New Nav Feature] Move collapsible nav toggle button to be part of Eu…
Browse files Browse the repository at this point in the history
…iCollapsibleNav (#3168)

* Move collapsible nav toggle button to be part of EuiCollapsibleNav
* No role group
* Alterations to top links and added `pinnable` prop to pinnable list items
  • Loading branch information
cchaos authored Mar 26, 2020
1 parent 2696b02 commit 16518ef
Show file tree
Hide file tree
Showing 20 changed files with 365 additions and 283 deletions.
4 changes: 4 additions & 0 deletions src-docs/src/components/guide_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ $guideZLevelHighest: $euiZLevel9 + 1000;

.guideBody {
background: linear-gradient(90deg, $euiPageBackgroundColor 50%, $euiColorEmptyShade 50%);

&--overflowHidden {
overflow: hidden;
}
}

.guidePage {
Expand Down
11 changes: 11 additions & 0 deletions src-docs/src/services/full_screen/full_screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, {
FunctionComponent,
ReactElement,
ReactNode,
useEffect,
} from 'react';

import { EuiFocusTrap } from '../../../../src/components/focus_trap';
Expand All @@ -20,6 +21,16 @@ export const GuideFullScreen: FunctionComponent<{
}) => {
const [fullScreen, setFullScreen] = useState(isFullScreen);

// Watch for fullScreen status and appropriately add/remove body classes for hiding scroll
useEffect(() => {
if (fullScreen) {
document.body.classList.add('guideBody--overflowHidden');
}
return () => {
document.body.classList.remove('guideBody--overflowHidden');
};
}, [fullScreen]);

return (
<Fragment>
<EuiButton onClick={() => setFullScreen(true)} iconType="fullScreen">
Expand Down
61 changes: 33 additions & 28 deletions src-docs/src/views/collapsible_nav/collapsible_nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,46 @@ import { EuiCollapsibleNav } from '../../../../src/components/collapsible_nav';
import { EuiButton, EuiButtonToggle } from '../../../../src/components/button';
import { EuiTitle } from '../../../../src/components/title';
import { EuiSpacer } from '../../../../src/components/spacer';
import { EuiText } from '../../../../src/components/text';
import { EuiCode } from '../../../../src/components/code';

export default () => {
const [navIsOpen, setNavIsOpen] = useState(false);
const [navIsDocked, setNavIsDocked] = useState(false);

return (
<>
<EuiButton
onClick={() => setNavIsOpen(!navIsOpen)}
aria-label="Toggle main navigation"
aria-controls="guideCollapsibleNavExampleNav"
aria-expanded={navIsOpen}
aria-pressed={navIsOpen}>
Toggle nav
</EuiButton>
{navIsOpen && (
<EuiCollapsibleNav
id="guideCollapsibleNavExampleNav"
aria-label="Example of main navigation flyout"
docked={navIsDocked}
onClose={() => setNavIsOpen(false)}>
<div style={{ padding: 16 }}>
<EuiTitle>
<h2>I am some nav</h2>
</EuiTitle>
<EuiSpacer />
<EuiButtonToggle
label={`Docked: ${navIsDocked ? 'on' : 'off'}`}
fill={navIsDocked}
onChange={() => {
setNavIsDocked(!navIsDocked);
}}
/>
</div>
</EuiCollapsibleNav>
<EuiCollapsibleNav
isOpen={navIsOpen}
button={
<EuiButton onClick={() => setNavIsOpen(!navIsOpen)}>
Toggle nav
</EuiButton>
}
isDocked={navIsDocked}
onClose={() => setNavIsOpen(false)}>
<div style={{ padding: 16 }}>
<EuiTitle>
<h2>I am some nav</h2>
</EuiTitle>
<EuiSpacer />
<EuiButtonToggle
label={`Docked: ${navIsDocked ? 'on' : 'off'}`}
fill={navIsDocked}
onChange={() => {
setNavIsDocked(!navIsDocked);
}}
/>
</div>
</EuiCollapsibleNav>

{navIsDocked && (
<EuiText size="s" color="subdued">
<p>
The button gets hidden by default when nav is docked unless you set{' '}
<EuiCode language="js">hideButtonIfDocked = false</EuiCode>.
</p>
</EuiText>
)}
</>
);
Expand Down
233 changes: 117 additions & 116 deletions src-docs/src/views/collapsible_nav/collapsible_nav_all.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import _ from 'lodash';

import {
EuiCollapsibleNav,
EuiCollapsibleNavToggle,
EuiCollapsibleNavGroup,
} from '../../../../src/components/collapsible_nav';
import {
Expand All @@ -30,8 +29,15 @@ import {
} from './collapsible_nav_list';
import { EuiShowFor } from '../../../../src/components/responsive';

const TopLinks = [
{ label: 'Home', iconType: 'home', isActive: true, 'aria-current': true },
const TopLinks: EuiPinnableListGroupItemProps[] = [
{
label: 'Home',
iconType: 'home',
isActive: true,
'aria-current': true,
href: '#/navigation/collapsible-nav',
pinnable: false,
},
];
const KibanaLinks: EuiPinnableListGroupItemProps[] = KibanaNavLinks.map(
link => {
Expand Down Expand Up @@ -132,17 +138,115 @@ export default () => {
return `Unpin ${listItem.label}`;
}

const collapsibleNav = (
<EuiCollapsibleNav
id="guideCollapsibleNavAllExampleNav"
aria-label="Main navigation"
isOpen={navIsOpen}
isDocked={navIsDocked}
button={
<EuiHeaderSectionItemButton
aria-label="Toggle main navigation"
onClick={() => setNavIsOpen(!navIsOpen)}>
<EuiIcon type={'menu'} size="m" aria-hidden="true" />
</EuiHeaderSectionItemButton>
}
onClose={() => setNavIsOpen(false)}>
{/* Dark deployments section */}
<EuiFlexItem grow={false} style={{ flexShrink: 0 }}>
{DeploymentsGroup}
</EuiFlexItem>

{/* Shaded pinned section always with a home item */}
<EuiFlexItem grow={false} style={{ flexShrink: 0 }}>
<EuiCollapsibleNavGroup
background="light"
className="eui-yScroll"
style={{ maxHeight: '40vh' }}>
<EuiPinnableListGroup
aria-label="Pinned links" // A11y : Since this group doesn't have a visible `title` it should be provided an accessible description
listItems={alterLinksWithCurrentState(TopLinks).concat(
alterLinksWithCurrentState(pinnedItems, true)
)}
unpinTitle={addLinkNameToUnpinTitle}
onPinClick={removePin}
maxWidth="none"
color="text"
gutterSize="none"
size="s"
/>
</EuiCollapsibleNavGroup>
</EuiFlexItem>

<EuiHorizontalRule margin="none" />

{/* BOTTOM */}
<EuiFlexItem className="eui-yScroll">
{/* Kibana section */}
<EuiCollapsibleNavGroup
title="Kibana"
iconType="logoKibana"
isCollapsible={true}
initialIsOpen={openGroups.includes('Kibana')}
onToggle={(isOpen: boolean) => toggleAccordion(isOpen, 'Kibana')}>
<EuiPinnableListGroup
aria-label="Kibana" // A11y : EuiCollapsibleNavGroup can't correctly pass the `title` as the `aria-label` to the right HTML element, so it must be added manually
listItems={alterLinksWithCurrentState(KibanaLinks)}
pinTitle={addLinkNameToPinTitle}
onPinClick={addPin}
maxWidth="none"
color="subdued"
gutterSize="none"
size="s"
/>
</EuiCollapsibleNavGroup>

{/* Security callout */}
{SecurityGroup}

{/* Learn section */}
<EuiCollapsibleNavGroup
title="Learn"
iconType="training"
isCollapsible={true}
initialIsOpen={openGroups.includes('Learn')}
onToggle={(isOpen: boolean) => toggleAccordion(isOpen, 'Learn')}>
<EuiPinnableListGroup
aria-label="Learn" // A11y : EuiCollapsibleNavGroup can't correctly pass the `title` as the `aria-label` to the right HTML element, so it must be added manually
listItems={alterLinksWithCurrentState(LearnLinks)}
pinTitle={addLinkNameToPinTitle}
onPinClick={addPin}
maxWidth="none"
color="subdued"
gutterSize="none"
size="s"
/>
</EuiCollapsibleNavGroup>

{/* Docking button only for larger screens that can support it*/}
<EuiShowFor sizes={['l', 'xl']}>
<EuiCollapsibleNavGroup>
<EuiListGroupItem
size="xs"
color="subdued"
label={`${navIsDocked ? 'Undock' : 'Dock'} navigation`}
onClick={() => {
setNavIsDocked(!navIsDocked);
localStorage.setItem(
'navIsDocked',
JSON.stringify(!navIsDocked)
);
}}
iconType={navIsDocked ? 'lock' : 'lockOpen'}
/>
</EuiCollapsibleNavGroup>
</EuiShowFor>
</EuiFlexItem>
</EuiCollapsibleNav>
);

const leftSectionItems = [
<EuiCollapsibleNavToggle navIsDocked={navIsDocked}>
<EuiHeaderSectionItemButton
aria-label="Toggle main navigation"
aria-controls="guideCollapsibleNavAllExampleNav"
aria-expanded={navIsOpen}
aria-pressed={navIsOpen}
onClick={() => setNavIsOpen(!navIsOpen)}>
<EuiIcon type={'menu'} size="m" aria-hidden="true" />
</EuiHeaderSectionItemButton>
</EuiCollapsibleNavToggle>,
collapsibleNav,
<EuiHeaderLogo iconType="logoElastic">Elastic</EuiHeaderLogo>,
];

Expand All @@ -169,109 +273,6 @@ export default () => {
]}
/>

{navIsOpen && (
<EuiCollapsibleNav
id="guideCollapsibleNavAllExampleNav"
aria-label="Main navigation"
docked={navIsDocked}
onClose={() => setNavIsOpen(false)}>
{/* Dark deployments section */}
<EuiFlexItem grow={false} style={{ flexShrink: 0 }}>
{DeploymentsGroup}
</EuiFlexItem>

{/* Shaded pinned section always with a home item */}
<EuiFlexItem grow={false} style={{ flexShrink: 0 }}>
<EuiCollapsibleNavGroup
background="light"
className="eui-yScroll"
style={{ maxHeight: '40vh' }}>
<EuiPinnableListGroup
aria-label="Pinned links" // A11y : Since this group doesn't have a visible `title` it should be provided an accessible description
listItems={alterLinksWithCurrentState(TopLinks).concat(
alterLinksWithCurrentState(pinnedItems, true)
)}
unpinTitle={addLinkNameToUnpinTitle}
onPinClick={removePin}
maxWidth="none"
color="subdued"
gutterSize="none"
size="s"
/>
</EuiCollapsibleNavGroup>
</EuiFlexItem>

<EuiHorizontalRule margin="none" />

{/* BOTTOM */}
<EuiFlexItem className="eui-yScroll">
{/* Kibana section */}
<EuiCollapsibleNavGroup
title="Kibana"
iconType="logoKibana"
isCollapsible={true}
initialIsOpen={openGroups.includes('Kibana')}
onToggle={(isOpen: boolean) =>
toggleAccordion(isOpen, 'Kibana')
}>
<EuiPinnableListGroup
aria-label="Kibana" // A11y : EuiCollapsibleNavGroup can't correctly pass the `title` as the `aria-label` to the right HTML element, so it must be added manually
listItems={alterLinksWithCurrentState(KibanaLinks)}
pinTitle={addLinkNameToPinTitle}
onPinClick={addPin}
maxWidth="none"
color="subdued"
gutterSize="none"
size="s"
/>
</EuiCollapsibleNavGroup>

{/* Security callout */}
{SecurityGroup}

{/* Learn section */}
<EuiCollapsibleNavGroup
title="Learn"
iconType="training"
isCollapsible={true}
initialIsOpen={openGroups.includes('Learn')}
onToggle={(isOpen: boolean) =>
toggleAccordion(isOpen, 'Learn')
}>
<EuiPinnableListGroup
aria-label="Learn" // A11y : EuiCollapsibleNavGroup can't correctly pass the `title` as the `aria-label` to the right HTML element, so it must be added manually
listItems={alterLinksWithCurrentState(LearnLinks)}
pinTitle={addLinkNameToPinTitle}
onPinClick={addPin}
maxWidth="none"
color="subdued"
gutterSize="none"
size="s"
/>
</EuiCollapsibleNavGroup>

{/* Docking button only for larger screens that can support it*/}
<EuiShowFor sizes={['l', 'xl']}>
<EuiCollapsibleNavGroup>
<EuiListGroupItem
size="xs"
color="subdued"
label={`${navIsDocked ? 'Undock' : 'Dock'} navigation`}
onClick={() => {
setNavIsDocked(!navIsDocked);
localStorage.setItem(
'navIsDocked',
JSON.stringify(!navIsDocked)
);
}}
iconType={navIsDocked ? 'lock' : 'lockOpen'}
/>
</EuiCollapsibleNavGroup>
</EuiShowFor>
</EuiFlexItem>
</EuiCollapsibleNav>
)}

<EuiPage className="guideFullScreenOverlay" />
</React.Fragment>
)}
Expand Down
Loading

0 comments on commit 16518ef

Please sign in to comment.