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

Updated the section Collapsable Nav #330

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src-docs/src/views/collapsible_nav/collapsible_nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default () => {
onClose={() => setNavIsOpen(false)}>
<div style={{ padding: 16 }}>
<OuiTitle>
<h2>I am some nav</h2>
<h2>Navigation</h2>
</OuiTitle>
<OuiSpacer />
<OuiText size="s" color="subdued">
Expand Down
170 changes: 37 additions & 133 deletions src-docs/src/views/collapsible_nav/collapsible_nav_all.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
*/

import React, { useState } from 'react';
import find from 'lodash/find';
import findIndex from 'lodash/findIndex';

import {
OuiCollapsibleNav,
Expand All @@ -26,48 +24,21 @@ import { OuiIcon } from '../../../../src/components/icon';
import { OuiButtonEmpty } from '../../../../src/components/button';
import { OuiPageTemplate } from '../../../../src/components/page';
import {
OuiPinnableListGroup,
OuiListGroupItem,
OuiPinnableListGroupItemProps,
OuiListGroup,
} from '../../../../src/components/list_group';
import { OuiFlexItem } from '../../../../src/components/flex';
import { OuiHorizontalRule } from '../../../../src/components/horizontal_rule';

import {
DeploymentsGroup,
KibanaNavLinks,
SecurityGroup,
ManagementLinks,
OpenSearchDashboardsLinks,
OpenSearchPluginLinks,
} from './collapsible_nav_list';
import { OuiShowFor } from '../../../../src/components/responsive';
import { OuiImage } from '../../../../src/components/image';
import contentSvg from '../../images/content.svg';
import { useExitPath } from '../../services/routing/routing';

const TopLinks: OuiPinnableListGroupItemProps[] = [
{
label: 'Home',
iconType: 'home',
isActive: true,
'aria-current': true,
onClick: () => {},
pinnable: false,
},
];
const KibanaLinks: OuiPinnableListGroupItemProps[] = KibanaNavLinks.map(
(link) => {
return {
...link,
onClick: () => {},
};
}
);
const LearnLinks: OuiPinnableListGroupItemProps[] = [
{ label: 'Docs', onClick: () => {} },
{ label: 'Blogs', onClick: () => {} },
{ label: 'Webinars', onClick: () => {} },
{ label: 'Elastic.co', href: 'https://elastic.co' },
];

const CollapsibleNavAll = () => {
const exitPath = useExitPath();
const [navIsOpen, setNavIsOpen] = useState(true);
Expand All @@ -80,8 +51,9 @@ const CollapsibleNavAll = () => {
*/
const [openGroups, setOpenGroups] = useState(
JSON.parse(String(localStorage.getItem('openNavGroups'))) || [
'Kibana',
'Learn',
'OpenSearch Dashboards',
'OpenSearch Plugins',
'Management',
]
);

Expand All @@ -102,55 +74,6 @@ const CollapsibleNavAll = () => {
localStorage.setItem('openNavGroups', JSON.stringify(openGroups));
};

/**
* Pinning
*/
const [pinnedItems, setPinnedItems] = useState<
OuiPinnableListGroupItemProps[]
>(JSON.parse(String(localStorage.getItem('pinnedItems'))) || []);

const addPin = (item: any) => {
if (!item || find(pinnedItems, { label: item.label })) {
return;
}
item.pinned = true;
const newPinnedItems = pinnedItems ? pinnedItems.concat(item) : [item];
setPinnedItems(newPinnedItems);
localStorage.setItem('pinnedItems', JSON.stringify(newPinnedItems));
};

const removePin = (item: any) => {
const pinIndex = findIndex(pinnedItems, { label: item.label });
if (pinIndex > -1) {
item.pinned = false;
const newPinnedItems = pinnedItems;
newPinnedItems.splice(pinIndex, 1);
setPinnedItems([...newPinnedItems]);
localStorage.setItem('pinnedItems', JSON.stringify(newPinnedItems));
}
};

function alterLinksWithCurrentState(
links: OuiPinnableListGroupItemProps[],
showPinned = false
): OuiPinnableListGroupItemProps[] {
return links.map((link) => {
const { pinned, ...rest } = link;
return {
pinned: showPinned ? pinned : false,
...rest,
};
});
}

function addLinkNameToPinTitle(listItem: OuiPinnableListGroupItemProps) {
return `Pin ${listItem.label} to top`;
}

function addLinkNameToUnpinTitle(listItem: OuiPinnableListGroupItemProps) {
return `Unpin ${listItem.label}`;
}

const collapsibleNav = (
<OuiCollapsibleNav
id="guideCollapsibleNavAllExampleNav"
Expand All @@ -165,70 +88,51 @@ const CollapsibleNavAll = () => {
</OuiHeaderSectionItemButton>
}
onClose={() => setNavIsOpen(false)}>
{/* Dark deployments section */}
<OuiFlexItem grow={false} style={{ flexShrink: 0 }}>
{DeploymentsGroup}
</OuiFlexItem>

{/* Shaded pinned section always with a home item */}
<OuiFlexItem grow={false} style={{ flexShrink: 0 }}>
{/* BOTTOM */}
<OuiFlexItem className="oui-yScroll">
{/* OpenSearch Dashboards section */}
<OuiCollapsibleNavGroup
background="light"
className="oui-yScroll"
style={{ maxHeight: '40vh' }}>
<OuiPinnableListGroup
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}
title="OpenSearch Dashboards"
iconType="logoOpenSearch"
isCollapsible={true}
initialIsOpen={openGroups.includes('OpenSearch Dashboards')}
onToggle={(isOpen: boolean) =>
toggleAccordion(isOpen, 'OpenSearch Dashboards')
}>
<OuiListGroup
aria-label="OpenSearch Dashboards" // A11y : OuiCollapsibleNavGroup can't correctly pass the `title` as the `aria-label` to the right HTML element, so it must be added manually
listItems={OpenSearchDashboardsLinks}
maxWidth="none"
color="text"
color="subdued"
gutterSize="none"
size="s"
/>
</OuiCollapsibleNavGroup>
</OuiFlexItem>

<OuiHorizontalRule margin="none" />

{/* BOTTOM */}
<OuiFlexItem className="oui-yScroll">
{/* Kibana section */}
<OuiCollapsibleNavGroup
title="Kibana"
iconType="logoKibana"
title="OpenSearch Plugins"
isCollapsible={true}
initialIsOpen={openGroups.includes('Kibana')}
onToggle={(isOpen: boolean) => toggleAccordion(isOpen, 'Kibana')}>
<OuiPinnableListGroup
aria-label="Kibana" // A11y : OuiCollapsibleNavGroup 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}
initialIsOpen={openGroups.includes('OpenSearch Plugins')}
onToggle={(isOpen: boolean) =>
toggleAccordion(isOpen, 'OpenSearch Plugins')
}>
<OuiListGroup
aria-label="OpenSearch Plugins" // A11y : OuiCollapsibleNavGroup can't correctly pass the `title` as the `aria-label` to the right HTML element, so it must be added manually
listItems={OpenSearchPluginLinks}
maxWidth="none"
color="subdued"
gutterSize="none"
size="s"
/>
</OuiCollapsibleNavGroup>

{/* Security callout */}
{SecurityGroup}

{/* Learn section */}
<OuiCollapsibleNavGroup
title="Learn"
iconType="training"
title="Management"
isCollapsible={true}
initialIsOpen={openGroups.includes('Learn')}
onToggle={(isOpen: boolean) => toggleAccordion(isOpen, 'Learn')}>
<OuiPinnableListGroup
aria-label="Learn" // A11y : OuiCollapsibleNavGroup 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}
initialIsOpen={openGroups.includes('Management')}
onToggle={(isOpen: boolean) => toggleAccordion(isOpen, 'Management')}>
<OuiListGroup
aria-label="Management" // A11y : OuiCollapsibleNavGroup can't correctly pass the `title` as the `aria-label` to the right HTML element, so it must be added manually
listItems={ManagementLinks}
maxWidth="none"
color="subdued"
gutterSize="none"
Expand Down Expand Up @@ -260,8 +164,8 @@ const CollapsibleNavAll = () => {

const leftSectionItems = [
collapsibleNav,
<OuiHeaderLogo href={exitPath} iconType="logoElastic">
Elastic
<OuiHeaderLogo href={exitPath} iconType="logoOpenSearch">
OpenSearch UI
</OuiHeaderLogo>,
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export const CollapsibleNavExample = {
</OuiCollapsibleNavGroup>`,
},
{
title: 'Full pattern with header and saved pins',
title: 'Full pattern with header',
source: [
{
type: GuideSectionTypes.JS,
Expand All @@ -196,8 +196,7 @@ export const CollapsibleNavExample = {
</Link>{' '}
with a toggle button to open an <strong>OuiCollapsibleNav</strong>.
The contents of which are multiple{' '}
<strong>OuiCollapsibleNavGroups</strong> and saves the
open/closed/pinned state for each section and item in local store.
<strong>OuiCollapsibleNavGroups</strong>
</p>
<p>
This is just a pattern and should be treated as such. Consuming
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ export default () => (
<p>This is a basic group without any modifications</p>
</OuiText>
</OuiCollapsibleNavGroup>
<OuiCollapsibleNavGroup
data-test-subj="TEST"
title="Nav group"
iconType="logoElastic">
<OuiCollapsibleNavGroup data-test-subj="TEST" title="Nav group">
<OuiText size="s" color="subdued">
<p>
This is a nice group with a heading supplied via{' '}
Expand All @@ -38,7 +35,6 @@ export default () => (
background="light"
title="Nav group"
isCollapsible={true}
iconType="logoElastic"
initialIsOpen={true}>
<OuiText size="s" color="subdued">
<p>
Expand All @@ -51,8 +47,6 @@ export default () => (
</OuiCollapsibleNavGroup>
<OuiCollapsibleNavGroup
title="Nav group"
iconType="logoGCPMono"
iconSize="xxl"
titleSize="s"
isCollapsible={true}
initialIsOpen={false}
Expand Down
Loading