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

[Feature] Added EuiCollapsibleNav component #2977

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
3 changes: 3 additions & 0 deletions src-docs/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ import { CodeEditorExample } from './views/code_editor/code_editor_example';

import { CodeExample } from './views/code/code_example';

import { CollapsibleNavExample } from './views/collapsible_nav/collapsible_nav_example';

import { ColorPickerExample } from './views/color_picker/color_picker_example';

import { ComboBoxExample } from './views/combo_box/combo_box_example';
Expand Down Expand Up @@ -323,6 +325,7 @@ const navigation = [
items: [
BreadcrumbsExample,
ButtonExample,
CollapsibleNavExample,
ContextMenuExample,
ControlBarExample,
FacetExample,
Expand Down
36 changes: 36 additions & 0 deletions src-docs/src/views/collapsible_nav/collapsible_nav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React, { useState } from 'react';

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';

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

return (
<>
<EuiButton onClick={() => setNavIsOpen(!navIsOpen)}>Toggle nav</EuiButton>
{navIsOpen && (
<EuiCollapsibleNav
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>
)}
</>
);
};
69 changes: 69 additions & 0 deletions src-docs/src/views/collapsible_nav/collapsible_nav_example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react';
import { Link } from 'react-router';

import { renderToHtml } from '../../services';

import { GuideSectionTypes } from '../../components';

import {
EuiCode,
EuiCollapsibleNav,
EuiText,
EuiSpacer,
EuiCallOut,
} from '../../../../src/components';

import CollapsibleNav from './collapsible_nav';
const collapsibleNavSource = require('!!raw-loader!./collapsible_nav');
const collapsibleNavHtml = renderToHtml(CollapsibleNav);

export const CollapsibleNavExample = {
title: 'Collapsible nav',
intro: (
<EuiText>
<p>
This is a high level component that creates a flyout-style navigational
pane. It is the next evolution of{' '}
<Link to="/layout/nav-drawer">
<strong>EuiNavDrawer</strong>
</Link>{' '}
which will be deprecated in the coming months.
</p>
<EuiSpacer size="m" />
</EuiText>
),
sections: [
{
source: [
{
type: GuideSectionTypes.JS,
code: collapsibleNavSource,
},
{
type: GuideSectionTypes.HTML,
code: collapsibleNavHtml,
},
],
text: (
<>
<p>
<strong>EuiCollapsibleNav</strong> is a similar implementation to{' '}
<Link to="/layout/flyout">
<strong>EuiFlyout</strong>
cchaos marked this conversation as resolved.
Show resolved Hide resolved
</Link>
; the visibility of which must be maintained by the consuming
application. An extra feature that it provides is the ability to{' '}
<EuiCode>dock</EuiCode> the flyout. This affixes the flyout to the
window and pushes the body content by adding left side padding.
</p>
<EuiCallOut
iconType="tableOfContents"
title="Docking is not possible on small screens because it would force less real estate for the page content."
/>
</>
),
props: { EuiCollapsibleNav },
demo: <CollapsibleNav />,
},
],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EuiCollapsibleNav can be docked 1`] = `
<div>
<div
data-focus-guard="true"
style="width:1px;height:0px;padding:0;overflow:hidden;position:fixed;top:1px;left:1px"
tabindex="-1"
/>
<div
data-focus-guard="true"
style="width:1px;height:0px;padding:0;overflow:hidden;position:fixed;top:1px;left:1px"
tabindex="-1"
/>
<div
data-focus-lock-disabled="disabled"
>
<nav
class="euiCollapsibleNav euiCollapsibleNav--isDocked"
>
<button
class="euiButtonEmpty euiButtonEmpty--primary euiButtonEmpty--xSmall euiCollapsibleNav__closeButton"
type="button"
>
<span
class="euiButtonEmpty__content"
>
<div
aria-hidden="true"
class="euiButtonEmpty__icon"
data-euiicon-type="cross"
/>
<span
class="euiButtonEmpty__text"
>
close
</span>
</span>
</button>
</nav>
</div>
<div
data-focus-guard="true"
style="width:1px;height:0px;padding:0;overflow:hidden;position:fixed;top:1px;left:1px"
tabindex="-1"
/>
</div>
`;

exports[`EuiCollapsibleNav is rendered 1`] = `
Array [
<div />,
<div>
<div
data-focus-guard="true"
style="width:1px;height:0px;padding:0;overflow:hidden;position:fixed;top:1px;left:1px"
tabindex="0"
/>
<div
data-focus-guard="true"
style="width:1px;height:0px;padding:0;overflow:hidden;position:fixed;top:1px;left:1px"
tabindex="1"
/>
<div
data-focus-lock-disabled="false"
>
<nav
aria-label="aria-label"
class="euiCollapsibleNav testClass1 testClass2"
data-test-subj="test subject string"
>
<button
class="euiButtonEmpty euiButtonEmpty--primary euiButtonEmpty--xSmall euiCollapsibleNav__closeButton"
type="button"
>
<span
class="euiButtonEmpty__content"
>
<div
aria-hidden="true"
class="euiButtonEmpty__icon"
data-euiicon-type="cross"
/>
<span
class="euiButtonEmpty__text"
>
close
</span>
</span>
</button>
</nav>
</div>
<div
data-focus-guard="true"
style="width:1px;height:0px;padding:0;overflow:hidden;position:fixed;top:1px;left:1px"
tabindex="0"
/>
</div>,
]
`;
52 changes: 52 additions & 0 deletions src/components/collapsible_nav/_collapsible_nav.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Extends euiFlyout
@use '../flyout/flyout';

.euiCollapsibleNav {
@extend %eui-flyout;
right: auto;
left: 0;
width: $euiCollapsibleNavWidth;
max-width: 80vw;

&:not(.euiCollapsibleNav--isDocked) {
animation: euiCollapsibleNavIn $euiAnimSpeedNormal $euiAnimSlightResistance;
}
}

.euiCollapsibleNav__closeButton {
position: absolute;
right: 0;
top: $euiSize;
margin-right: -25%;
}

@include euiBreakpoint('l', 'xl') {
cchaos marked this conversation as resolved.
Show resolved Hide resolved
// The addition of this class is handled through JS as well
// but adding under the breakpoint mixin is an additional fail-safe
.euiCollapsibleNav.euiCollapsibleNav--isDocked {
@include euiBottomShadowMedium;

.euiCollapsibleNav__closeButton {
display: none;
}
}

.euiBody--collapsibleNavIsDocked {
// Shrink the content from the left so it's no longer overlapped by the nav drawer (ALWAYS)
padding-left: $euiCollapsibleNavWidth !important; // sass-lint:disable-line no-important
transition: padding $euiAnimSpeedFast $euiAnimSlightResistance;
}
}

// Specific keyframes so in comes in from the left
@keyframes euiCollapsibleNavIn {
0% {
opacity: 0;
transform: translateX(-100%);
}

75% {
opacity: 1;
transform: translateX(0%);
}
}
2 changes: 2 additions & 0 deletions src/components/collapsible_nav/_index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@import 'variables';
@import 'collapsible_nav';
2 changes: 2 additions & 0 deletions src/components/collapsible_nav/_variables.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Sizing
$euiCollapsibleNavWidth: $euiSize * 20; // ~ 320px
27 changes: 27 additions & 0 deletions src/components/collapsible_nav/collapsible_nav.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { render } from 'enzyme';
import { requiredProps } from '../../test/required_props';

import { EuiCollapsibleNav } from './collapsible_nav';

jest.mock('../overlay_mask', () => ({
EuiOverlayMask: (props: any) => <div {...props} />,
}));

describe('EuiCollapsibleNav', () => {
test('is rendered', () => {
const component = render(
<EuiCollapsibleNav onClose={() => {}} {...requiredProps} />
);

expect(component).toMatchSnapshot();
});

test('can be docked', () => {
const component = render(
<EuiCollapsibleNav docked={true} onClose={() => {}} />
);

expect(component).toMatchSnapshot();
});
});
Loading