Skip to content

Commit

Permalink
Add EuiBreadcrumbs.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjcenizal committed May 10, 2018
1 parent 96ddf15 commit 079566e
Show file tree
Hide file tree
Showing 13 changed files with 340 additions and 8 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Added utility CSS classes for text and alignment concerns. ([#774](https://github.com/elastic/eui/pull/774))
- Added utility CSS classes for text and alignment concerns ([#774](https://github.com/elastic/eui/pull/774))
- Added `EuiBreadcrumbs` ([#815](https://github.com/elastic/eui/pull/815))

**Bug fixes**

Expand Down
4 changes: 4 additions & 0 deletions src-docs/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ import { BadgeExample }
import { BottomBarExample }
from './views/bottom_bar/bottom_bar_example';

import { BreadcrumbsExample }
from './views/breadcrumbs/breadcrumbs_example';

import { ButtonExample }
from './views/button/button_example';

Expand Down Expand Up @@ -286,6 +289,7 @@ const navigation = [{
}, {
name: 'Navigation',
items: [
BreadcrumbsExample,
ButtonExample,
ContextMenuExample,
KeyPadMenuExample,
Expand Down
49 changes: 49 additions & 0 deletions src-docs/src/views/breadcrumbs/breadcrumbs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { Fragment } from 'react';

import {
EuiBreadcrumbs,
EuiButton,
EuiPageContentHeader,
EuiPageContentHeaderSection,
EuiTitle,
EuiSpacer,
} from '../../../../src/components';

export default () => {
const breadcrumbs = [{
text: 'Animals',
href: '#',
onClick: (e) => { e.preventDefault(); console.log('You clicked Animals'); },
'data-test-subj': 'breadcrumbsAnimals',
className: 'customClass',
}, {
text: 'Reptiles',
href: '#',
onClick: (e) => { e.preventDefault(); console.log('You clicked Reptiles'); },
}, {
text: 'Boa constrictor',
href: '#',
onClick: (e) => { e.preventDefault(); console.log('You clicked Boa constrictor'); },
}, {
text: 'Edit',
}];

return (
<Fragment>
<EuiBreadcrumbs breadcrumbs={breadcrumbs} />
<EuiSpacer size="xs" />

<EuiPageContentHeader>
<EuiPageContentHeaderSection>
<EuiTitle size="l">
<h1>Boa constrictor</h1>
</EuiTitle>
</EuiPageContentHeaderSection>

<EuiPageContentHeaderSection>
<EuiButton>Cancel</EuiButton>
</EuiPageContentHeaderSection>
</EuiPageContentHeader>
</Fragment>
);
};
38 changes: 38 additions & 0 deletions src-docs/src/views/breadcrumbs/breadcrumbs_example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';

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

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

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

import Breadcrumbs from './breadcrumbs';
const breadcrumbsSource = require('!!raw-loader!./breadcrumbs');
const breadcrumbsHtml = renderToHtml(Breadcrumbs);

export const BreadcrumbsExample = {
title: 'Breadcrumbs',
sections: [{
source: [{
type: GuideSectionTypes.JS,
code: breadcrumbsSource,
}, {
type: GuideSectionTypes.HTML,
code: breadcrumbsHtml,
}],
text: (
<p>
<EuiCode>EuiBreadcrumbs</EuiCode> let the user track their progress within and back out of
a UX flow. They work well within <EuiCode>EuiPageContentHeader</EuiCode> but be careful
not to be use them within an app that also uses <EuiCode>EuiHeaderBreadcrumbs</EuiCode>.
</p>
),
props: { EuiBreadcrumbs },
demo: <Breadcrumbs />,
}],
};
94 changes: 94 additions & 0 deletions src/components/breadcrumbs/__snapshots__/breadcrumbs.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EuiBreadcrumbs is rendered 1`] = `
<div
aria-label="aria-label"
class="euiBreadcrumbs testClass1 testClass2"
data-test-subj="test subject string"
>
<a
class="euiLink euiLink--subdued customClass"
data-test-subj="breadcrumbsAnimals"
href="#"
>
Animals
</a>
<svg
class="euiIcon euiIcon--medium euiIcon--subdued euiBreadcrumbArrow"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fill-rule="nonzero"
href="#arrow_right-a"
transform="matrix(0 1 1 0 0 0)"
/>
</svg>
<a
class="euiLink euiLink--subdued euiBreadcrumb"
href="#"
>
Reptiles
</a>
<svg
class="euiIcon euiIcon--medium euiIcon--subdued euiBreadcrumbArrow"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fill-rule="nonzero"
href="#arrow_right-a"
transform="matrix(0 1 1 0 0 0)"
/>
</svg>
<a
class="euiLink euiLink--subdued euiBreadcrumb"
href="#"
>
Boa constrictor
</a>
<svg
class="euiIcon euiIcon--medium euiIcon--subdued euiBreadcrumbArrow"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fill-rule="nonzero"
href="#arrow_right-a"
transform="matrix(0 1 1 0 0 0)"
/>
</svg>
<span
class="euiBreadcrumb euiBreadcrumb--last"
>
Edit
</span>
</div>
`;
20 changes: 20 additions & 0 deletions src/components/breadcrumbs/_breadcrumbs.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.euiBreadcrumbs {
font-size: $euiFontSizeS;
}

.euiBreadcrumb {
display: inline-block;

&:not(.euiBreadcrumb--last) {
margin-right: $euiBreadcrumbSpacing;
}
}

.euiBreadcrumb--last {
font-weight: 500;
}

.euiBreadcrumbArrow {
margin-right: $euiBreadcrumbSpacing;
transform: translateY(-0.1em);
}
3 changes: 3 additions & 0 deletions src/components/breadcrumbs/_index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
$euiBreadcrumbSpacing: $euiSizeXS;

@import 'breadcrumbs';
79 changes: 79 additions & 0 deletions src/components/breadcrumbs/breadcrumbs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import { EuiIcon } from '../icon';
import { EuiLink } from '../link';

export const EuiBreadcrumbs = ({
breadcrumbs,
className,
...rest,
}) => {
const breadcrumbElements = breadcrumbs.map((breadcrumb, index) => {
const {
text,
href,
onClick,
...breadcrumbRest
} = breadcrumb;

const isLastBreadcrumb = index === breadcrumbs.length - 1;

const breadcrumbClasses = classNames('euiBreadcrumb', {
'euiBreadcrumb--last': isLastBreadcrumb,
});

let link;

if (isLastBreadcrumb) {
link = (
<span className={breadcrumbClasses} {...breadcrumbRest}>
{ text }
</span>
);
} else {
link = (
<EuiLink
color='subdued'
href={href}
onClick={onClick}
className={breadcrumbClasses}
{...breadcrumbRest}
>
{text}
</EuiLink>
);
}

let arrow;

if (!isLastBreadcrumb) {
arrow = <EuiIcon className='euiBreadcrumbArrow' type='arrowRight' color='subdued' />;
}

return (
<Fragment key={index}>
{link}
{arrow}
</Fragment>
);
})

const classes = classNames('euiBreadcrumbs', className);

return (
<div className={classes} {...rest}>
{breadcrumbElements}
</div>
);
};

EuiBreadcrumbs.propTypes = {
className: PropTypes.string,
breadcrumbs: PropTypes.arrayOf(PropTypes.shape({
text: PropTypes.node.isRequired,
href: PropTypes.string,
onClick: PropTypes.func,
})).isRequired,
};
33 changes: 33 additions & 0 deletions src/components/breadcrumbs/breadcrumbs.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import { render } from 'enzyme';
import { requiredProps } from '../../test';

import { EuiBreadcrumbs } from './breadcrumbs';

describe('EuiBreadcrumbs', () => {
const breadcrumbs = [{
text: 'Animals',
href: '#',
onClick: (e) => { e.preventDefault(); console.log('You clicked Animals'); },
'data-test-subj': 'breadcrumbsAnimals',
className: 'customClass',
}, {
text: 'Reptiles',
href: '#',
onClick: (e) => { e.preventDefault(); console.log('You clicked Reptiles'); },
}, {
text: 'Boa constrictor',
href: '#',
onClick: (e) => { e.preventDefault(); console.log('You clicked Boa constrictor'); },
}, {
text: 'Edit',
}];

test('is rendered', () => {
const component = render(
<EuiBreadcrumbs {...requiredProps} breadcrumbs={breadcrumbs} />
);

expect(component).toMatchSnapshot();
});
});
3 changes: 3 additions & 0 deletions src/components/breadcrumbs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export {
EuiBreadcrumbs,
} from './breadcrumbs';
18 changes: 11 additions & 7 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,33 @@ export {
EuiScreenReaderOnly,
} from './accessibility';

export {
EuiBadge,
EuiBetaBadge,
} from './badge';

export {
EuiBottomBar,
} from './bottom_bar';

export {
EuiBreadcrumbs,
} from './breadcrumbs';

export {
EuiButton,
EuiButtonEmpty,
EuiButtonIcon,
} from './button';

export {
EuiBadge,
EuiBetaBadge,
} from './badge';
EuiCallOut,
} from './call_out';

export {
EuiCard,
} from './card';

export {
EuiCallOut,
} from './call_out';

export {
EuiCode,
EuiCodeBlock,
Expand Down
Loading

0 comments on commit 079566e

Please sign in to comment.