diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7972930e30b4..0c1c5a4dd114 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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**
diff --git a/src-docs/src/routes.js b/src-docs/src/routes.js
index bde014ec8a9e..2c6b734d8be0 100644
--- a/src-docs/src/routes.js
+++ b/src-docs/src/routes.js
@@ -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';
@@ -286,6 +289,7 @@ const navigation = [{
}, {
name: 'Navigation',
items: [
+ BreadcrumbsExample,
ButtonExample,
ContextMenuExample,
KeyPadMenuExample,
diff --git a/src-docs/src/views/breadcrumbs/breadcrumbs.js b/src-docs/src/views/breadcrumbs/breadcrumbs.js
new file mode 100644
index 000000000000..d2db2028b9b7
--- /dev/null
+++ b/src-docs/src/views/breadcrumbs/breadcrumbs.js
@@ -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 (
+
+
+
+
+
+
+
+ Boa constrictor
+
+
+
+
+ Cancel
+
+
+
+ );
+};
diff --git a/src-docs/src/views/breadcrumbs/breadcrumbs_example.js b/src-docs/src/views/breadcrumbs/breadcrumbs_example.js
new file mode 100644
index 000000000000..e3e2121ffd64
--- /dev/null
+++ b/src-docs/src/views/breadcrumbs/breadcrumbs_example.js
@@ -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: (
+
+ EuiBreadcrumbs let the user track their progress within and back out of
+ a UX flow. They work well within EuiPageContentHeader but be careful
+ not to be use them within an app that also uses EuiHeaderBreadcrumbs .
+
+ ),
+ props: { EuiBreadcrumbs },
+ demo: ,
+ }],
+};
diff --git a/src/components/breadcrumbs/__snapshots__/breadcrumbs.test.js.snap b/src/components/breadcrumbs/__snapshots__/breadcrumbs.test.js.snap
new file mode 100644
index 000000000000..7226d1413b4b
--- /dev/null
+++ b/src/components/breadcrumbs/__snapshots__/breadcrumbs.test.js.snap
@@ -0,0 +1,94 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`EuiBreadcrumbs is rendered 1`] = `
+
+`;
diff --git a/src/components/breadcrumbs/_breadcrumbs.scss b/src/components/breadcrumbs/_breadcrumbs.scss
new file mode 100644
index 000000000000..3205a19e4aa9
--- /dev/null
+++ b/src/components/breadcrumbs/_breadcrumbs.scss
@@ -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);
+}
diff --git a/src/components/breadcrumbs/_index.scss b/src/components/breadcrumbs/_index.scss
new file mode 100644
index 000000000000..d4d56ed0d568
--- /dev/null
+++ b/src/components/breadcrumbs/_index.scss
@@ -0,0 +1,3 @@
+$euiBreadcrumbSpacing: $euiSizeXS;
+
+@import 'breadcrumbs';
diff --git a/src/components/breadcrumbs/breadcrumbs.js b/src/components/breadcrumbs/breadcrumbs.js
new file mode 100644
index 000000000000..01148f46af57
--- /dev/null
+++ b/src/components/breadcrumbs/breadcrumbs.js
@@ -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 = (
+
+ { text }
+
+ );
+ } else {
+ link = (
+
+ {text}
+
+ );
+ }
+
+ let arrow;
+
+ if (!isLastBreadcrumb) {
+ arrow = ;
+ }
+
+ return (
+
+ {link}
+ {arrow}
+
+ );
+ })
+
+ const classes = classNames('euiBreadcrumbs', className);
+
+ return (
+
+ {breadcrumbElements}
+
+ );
+};
+
+EuiBreadcrumbs.propTypes = {
+ className: PropTypes.string,
+ breadcrumbs: PropTypes.arrayOf(PropTypes.shape({
+ text: PropTypes.node.isRequired,
+ href: PropTypes.string,
+ onClick: PropTypes.func,
+ })).isRequired,
+};
diff --git a/src/components/breadcrumbs/breadcrumbs.test.js b/src/components/breadcrumbs/breadcrumbs.test.js
new file mode 100644
index 000000000000..49933c1c007a
--- /dev/null
+++ b/src/components/breadcrumbs/breadcrumbs.test.js
@@ -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(
+
+ );
+
+ expect(component).toMatchSnapshot();
+ });
+});
diff --git a/src/components/breadcrumbs/index.js b/src/components/breadcrumbs/index.js
new file mode 100644
index 000000000000..35a6bb68c4cb
--- /dev/null
+++ b/src/components/breadcrumbs/index.js
@@ -0,0 +1,3 @@
+export {
+ EuiBreadcrumbs,
+} from './breadcrumbs';
diff --git a/src/components/index.js b/src/components/index.js
index cb9863e38fa2..9734eba0acec 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -11,10 +11,19 @@ export {
EuiScreenReaderOnly,
} from './accessibility';
+export {
+ EuiBadge,
+ EuiBetaBadge,
+} from './badge';
+
export {
EuiBottomBar,
} from './bottom_bar';
+export {
+ EuiBreadcrumbs,
+} from './breadcrumbs';
+
export {
EuiButton,
EuiButtonEmpty,
@@ -22,18 +31,13 @@ export {
} from './button';
export {
- EuiBadge,
- EuiBetaBadge,
-} from './badge';
+ EuiCallOut,
+} from './call_out';
export {
EuiCard,
} from './card';
-export {
- EuiCallOut,
-} from './call_out';
-
export {
EuiCode,
EuiCodeBlock,
diff --git a/src/components/index.scss b/src/components/index.scss
index e736d0d2340c..cb290518e8e0 100644
--- a/src/components/index.scss
+++ b/src/components/index.scss
@@ -8,6 +8,7 @@
@import 'basic_table/index';
@import 'bottom_bar/index';
@import 'button/index';
+@import 'breadcrumbs/index';
@import 'call_out/index';
@import 'card/index';
@import 'code/index';
diff --git a/src/components/link/link.js b/src/components/link/link.js
index cee3b79cd5f9..573041a49621 100644
--- a/src/components/link/link.js
+++ b/src/components/link/link.js
@@ -24,6 +24,7 @@ export const EuiLink = ({
target,
rel,
type,
+ onClick,
...rest
}) => {
const classes = classNames('euiLink', colorsToClassNameMap[color], className);
@@ -33,6 +34,7 @@ export const EuiLink = ({
{children}
@@ -48,6 +50,7 @@ export const EuiLink = ({
href={href}
target={target}
rel={secureRel}
+ onClick={onClick}
{...rest}
>
{children}