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

Show all breadcrumbs in a popover #2342

Merged
merged 26 commits into from
Sep 24, 2019
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8c1a8a4
Conditionally changing the ellipsis to a button.
daveyholler Sep 7, 2019
f779adc
Adding hook for popover state.
daveyholler Sep 12, 2019
3e6f777
Merge remote-tracking branch 'upstream/master' into responsive-breadc…
daveyholler Sep 12, 2019
3a9b16c
Showing breadcrumbs in a popover
daveyholler Sep 13, 2019
5ae1183
Adding an aria-label
daveyholler Sep 13, 2019
173dee8
Changelog entry
daveyholler Sep 13, 2019
7d24b61
Merge branch 'master' into responsive-breadcrumbs
daveyholler Sep 13, 2019
1288e1e
Updating doc example text.
daveyholler Sep 13, 2019
cba39e1
Merge branch 'responsive-breadcrumbs' of github.com:daveyholler/eui i…
daveyholler Sep 13, 2019
9d7355e
Using a badge style for the clickable ellipsis
daveyholler Sep 17, 2019
5adf6d4
Merge branch 'master' into responsive-breadcrumbs
daveyholler Sep 17, 2019
19a5f5e
Merge branch 'master' into responsive-breadcrumbs
daveyholler Sep 18, 2019
2ff3997
PR review changes
daveyholler Sep 18, 2019
55f3831
Removing an unused selector
daveyholler Sep 18, 2019
f95bebd
Merge branch 'master' into responsive-breadcrumbs
daveyholler Sep 18, 2019
7a2eb67
Update src/components/breadcrumbs/breadcrumbs.js
daveyholler Sep 18, 2019
9347c11
Removing unnecessary ID
daveyholler Sep 18, 2019
ae3ccaa
Only displaying the hidden items in the popover
daveyholler Sep 19, 2019
2d9413c
Updating tests, removing rogue comment
daveyholler Sep 19, 2019
fb4cebe
Merge branch 'master' into responsive-breadcrumbs
daveyholler Sep 19, 2019
2cf56b4
Copy changes
daveyholler Sep 19, 2019
eae3d39
Merge branch 'responsive-breadcrumbs' of github.com:daveyholler/eui i…
daveyholler Sep 19, 2019
88a8e95
Update src/components/breadcrumbs/breadcrumbs.js
daveyholler Sep 19, 2019
f0247a5
Updating a class name.
daveyholler Sep 19, 2019
49d3aa6
Refining the method of displaying hidden breadcrumbs.
daveyholler Sep 23, 2019
14f1d37
Merge branch 'master' into responsive-breadcrumbs
daveyholler Sep 24, 2019
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Added a popover option for `EuiBreadcrumbs` to display all items when a `max` is set. ([#2342](https://github.com/elastic/eui/pull/2342))
daveyholler marked this conversation as resolved.
Show resolved Hide resolved
- Add `compressed` option to `buttonSize` prop of EuiButtonGroup ([#2343](https://github.com/elastic/eui/pull/2343))

**Bug fixes**
Expand Down
34 changes: 34 additions & 0 deletions src-docs/src/views/breadcrumbs/breadcrumbs_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ const maxSnippet = `<EuiBreadcrumbs
/>
`;

import Popover from './popover';
const popoverSource = require('!!raw-loader!./popover');
const popoverHtml = renderToHtml(Popover);
const popoverSnippet = `<EuiBreadcrumbs
breadcrumbs={breadcrumbs}
showPopover
/>
`;

export const BreadcrumbsExample = {
title: 'Breadcrumbs',
sections: [
Expand Down Expand Up @@ -152,5 +161,30 @@ export const BreadcrumbsExample = {
snippet: maxSnippet,
demo: <Max />,
},
{
title: 'Show the full list in a popover',
source: [
{
type: GuideSectionTypes.JS,
code: popoverSource,
},
{
type: GuideSectionTypes.HTML,
code: popoverHtml,
},
],
text: (
<p>
When the breadcrumbs need to be truncated, but you wish to still allow
users to navigate to any item in the list, you can use the{' '}
<EuiCode>showPopover</EuiCode> prop. When used with the{' '}
daveyholler marked this conversation as resolved.
Show resolved Hide resolved
<EuiCode>max</EuiCode> prop, the entire list of breadcrumbs will be
rendered into an <EuiCode>EuiPopover</EuiCode>.
</p>
),
props: { EuiBreadcrumbs },
snippet: popoverSnippet,
demo: <Popover />,
},
],
};
63 changes: 63 additions & 0 deletions src-docs/src/views/breadcrumbs/popover.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { Fragment } from 'react';

import { EuiBreadcrumbs } from '../../../../src/components';

export default () => {
const breadcrumbs = [
{
text: 'root',
href: '#',
onClick: e => {
e.preventDefault();
console.log('You clicked root');
},
'data-test-subj': 'breadcrumbsroot',
},
{
text: 'src',
href: '#',
onClick: e => {
e.preventDefault();
console.log('You clicked src');
},
},
{
text: 'components',
href: '#',
onClick: e => {
e.preventDefault();
console.log('You clicked components');
},
},
{
text: 'button',
href: '#',
onClick: e => {
e.preventDefault();
console.log('You clicked button');
},
},
{
text: 'button_empty',
href: '#',
onClick: e => {
e.preventDefault();
console.log('You clicked button_empty');
},
},
{
text: 'button_empty.tsx',
},
];

return (
<Fragment>
<EuiBreadcrumbs
breadcrumbs={breadcrumbs}
truncate={false}
max={4}
showMaxPopover
/>
</Fragment>
);
};
18 changes: 18 additions & 0 deletions src/components/breadcrumbs/_breadcrumbs.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
.euiBreadcrumbs {
@include euiFontSizeS;

&.euiBreadcrumbs--wrap {
daveyholler marked this conversation as resolved.
Show resolved Hide resolved
flex-wrap: wrap;
}
}

.euiBreadcrumb {
Expand Down Expand Up @@ -29,6 +33,16 @@
background: $euiColorLightShade;
}

.euiBreadcrumbBadge {
height: $euiSize;
margin-top: -$euiSizeM / 2;
background-color: transparentize($euiColorDarkestShade, .85);

.euiBadge__content {
margin-top: -$euiSizeXS / 2;
}
}

/**
* 1. Can't target separator vs breadcrumb with -of-type because it takes
* the dom element into consideration too and there could be divs, or spans, or a's
Expand Down Expand Up @@ -96,6 +110,10 @@
// Align with flex versus inline-block misaligns the separator slightly
transform: translateY(0) rotate(15deg);
}

.euiBreadcrumbBadge {
margin-top: -$euiSizeXS / 2;
}
}

.euiBreadcrumb--truncate {
Expand Down
70 changes: 60 additions & 10 deletions src/components/breadcrumbs/breadcrumbs.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import React, { Fragment } from 'react';
import React, { Fragment, useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import { EuiBadge } from '../badge';
import { EuiI18n } from '../i18n';
import { EuiLink } from '../link';
import { EuiPopover } from '../popover';

const limitBreadcrumbs = (breadcrumbs, max) => {
const limitBreadcrumbs = (breadcrumbs, max, showMaxPopover, allBreadcrumbs) => {
const breadcrumbsAtStart = [];
const breadcrumbsAtEnd = [];
const limit = Math.min(max, breadcrumbs.length);
Expand All @@ -30,20 +33,58 @@ const limitBreadcrumbs = (breadcrumbs, max) => {
}
}

const EuiBreadcrumbCollapsed = () => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);

const ellipsisButton = (
<EuiI18n token="euiBreadcrumbs.ariaLabel" default="Show all breadcrumbs">
daveyholler marked this conversation as resolved.
Show resolved Hide resolved
{ariaLabel => (
<EuiBadge
aria-label={ariaLabel}
onClick={() => setIsPopoverOpen(!isPopoverOpen)}
onClickAriaLabel={ariaLabel}
daveyholler marked this conversation as resolved.
Show resolved Hide resolved
className="euiBreadcrumb euiBreadcrumbBadge">
daveyholler marked this conversation as resolved.
Show resolved Hide resolved
&hellip;
</EuiBadge>
)}
</EuiI18n>
);

if (showMaxPopover) {
return (
<Fragment>
<EuiPopover
id="showAllBreadcrumbsPopover"
daveyholler marked this conversation as resolved.
Show resolved Hide resolved
button={ellipsisButton}
isOpen={isPopoverOpen}
closePopover={() => setIsPopoverOpen(false)}>
<EuiBreadcrumbs
breadcrumbs={allBreadcrumbs}
responsive={false}
truncate={false}
max={0}
/>
</EuiPopover>
<EuiBreadcrumbSeparator />
</Fragment>
);
} else {
return (
<Fragment>
<div className="euiBreadcrumb euiBreadcrumb--collapsed">&hellip;</div>
<EuiBreadcrumbSeparator />
</Fragment>
);
}
};

if (max < breadcrumbs.length) {
breadcrumbsAtStart.push(<EuiBreadcrumbCollapsed key="collapsed" />);
}

return [...breadcrumbsAtStart, ...breadcrumbsAtEnd];
};

const EuiBreadcrumbCollapsed = () => (
<Fragment>
<div className="euiBreadcrumb euiBreadcrumb--collapsed">&#8230;</div>
<EuiBreadcrumbSeparator />
</Fragment>
);

const EuiBreadcrumbSeparator = () => <div className="euiBreadcrumbSeparator" />;

export const EuiBreadcrumbs = ({
Expand All @@ -52,6 +93,7 @@ export const EuiBreadcrumbs = ({
responsive,
truncate,
max,
showMaxPopover,
...rest
}) => {
const breadcrumbElements = breadcrumbs.map((breadcrumb, index) => {
Expand Down Expand Up @@ -83,6 +125,7 @@ export const EuiBreadcrumbs = ({
{text}
</span>
);
// if limitedBreadcrumbs && displayHidden
daveyholler marked this conversation as resolved.
Show resolved Hide resolved
} else {
link = (
<EuiLink
Expand Down Expand Up @@ -112,7 +155,7 @@ export const EuiBreadcrumbs = ({
});

const limitedBreadcrumbs = max
? limitBreadcrumbs(breadcrumbElements, max)
? limitBreadcrumbs(breadcrumbElements, max, showMaxPopover, breadcrumbs)
: breadcrumbElements;

const classes = classNames('euiBreadcrumbs', className, {
Expand Down Expand Up @@ -148,6 +191,12 @@ EuiBreadcrumbs.propTypes = {
*/
max: PropTypes.number,

/**
* Allows the entire list of breadcrumbs to be shown when
* a `max` is set and the ellipsis is clicked in responsive mode.
*/
showMaxPopover: PropTypes.bool,

/**
* The array of individual breadcrumbs, takes the following props.
* `text` (node) (required): visible label of the breadcrumb,
Expand All @@ -167,5 +216,6 @@ EuiBreadcrumbs.propTypes = {
EuiBreadcrumbs.defaultProps = {
responsive: true,
truncate: true,
showMaxPopover: false,
max: 5,
};