diff --git a/.github/DEVELOPMENT.md b/.github/DEVELOPMENT.md
index 4c325e6c950..bf120692d0d 100644
--- a/.github/DEVELOPMENT.md
+++ b/.github/DEVELOPMENT.md
@@ -46,7 +46,7 @@ yarn start --scope @zendeskgarden/react-buttons
All elements must
-* Be implemented with associated `Conatiner` and `View` components
+* Be implemented with associated `Container` and `View` components
* Provide `uncontrolled` and `controlled` state management if necessary
* Be implemented with the `ControlledComponent` state abstractions if necessary
* Create an abstraction to benefit a majority of use cases
diff --git a/.travis.yml b/.travis.yml
index f05662cd518..4775e47048b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,7 @@ install: yarn --frozen-lockfile
script:
- yarn lint
+ - yarn format
- yarn test:all --coverage --runInBand
after_success: yarn coveralls < demo/coverage/lcov.info
diff --git a/README.md b/README.md
index b52d75a4efc..aa4e728e0d8 100644
--- a/README.md
+++ b/README.md
@@ -9,10 +9,6 @@ components are packaged and published individually, but combined under
this single repository. Components rely on [Garden
CSS](https://github.com/zendeskgarden/css-components) for styling.
-Try out the Garden React Components in a mock product environment with CodeSandbox
-
-[](https://codesandbox.io/s/43nwpkn717)
-
## Installation
See the individual package README for the React component you would like
@@ -22,6 +18,7 @@ Package | Version | Dependencies
------- | ------- | ------------
[`@zendeskgarden/react-autocomplete`](packages/autocomplete) | [![npm version][autocomplete npm version]][autocomplete npm link] | [![Dependency Status][autocomplete dependency status]][autocomplete dependency link]
[`@zendeskgarden/react-avatars`](packages/avatars) | [![npm version][avatars npm version]][avatars npm link] | [![Dependency Status][avatars dependency status]][avatars dependency link]
+[`@zendeskgarden/react-breadcrumbs`](packages/breadcrumbs) | [![npm version][breadcrumbs npm version]][breadcrumbs npm link] | [![Dependency Status][breadcrumbs dependency status]][breadcrumbs dependency link]
[`@zendeskgarden/react-buttons`](packages/buttons) | [![npm version][buttons npm version]][buttons npm link] | [![Dependency Status][buttons dependency status]][buttons dependency link]
[`@zendeskgarden/react-checkboxes`](packages/checkboxes) | [![npm version][checkboxes npm version]][checkboxes npm link] | [![Dependency Status][checkboxes dependency status]][checkboxes dependency link]
[`@zendeskgarden/react-chrome`](packages/chrome) | [![npm version][chrome npm version]][chrome npm link] | [![Dependency Status][chrome dependency status]][chrome dependency link]
@@ -54,6 +51,10 @@ Package | Version | Dependencies
[avatars npm link]: https://www.npmjs.com/package/@zendeskgarden/react-avatars
[avatars dependency status]: https://img.shields.io/david/zendeskgarden/react-components.svg?path=packages/avatars&style=flat-square
[avatars dependency link]: https://david-dm.org/zendeskgarden/react-components?path=packages/avatars
+[breadcrumbs npm version]: https://img.shields.io/npm/v/@zendeskgarden/react-breadcrumbs.svg?style=flat-square
+[breadcrumbs npm link]: https://www.npmjs.com/package/@zendeskgarden/react-breadcrumbs
+[breadcrumbs dependency status]: https://img.shields.io/david/zendeskgarden/react-components.svg?path=packages/breadcrumbs&style=flat-square
+[breadcrumbs dependency link]: https://david-dm.org/zendeskgarden/react-components?path=packages/breadcrumbs
[buttons npm version]: https://img.shields.io/npm/v/@zendeskgarden/react-buttons.svg?style=flat-square
[buttons npm link]: https://www.npmjs.com/package/@zendeskgarden/react-buttons
[buttons dependency status]: https://img.shields.io/david/zendeskgarden/react-components.svg?path=packages/buttons&style=flat-square
@@ -149,11 +150,11 @@ Package | Version | Dependencies
## Usage
-Our packages are easily consumable with [create-react-app](https://github.com/facebook/create-react-app)
-and standard webpack configs.
-
-All packages follow a similar installation process. Below is an example of
-consuming our [react-buttons](https://www.npmjs.com/package/@zendeskgarden/react-buttons)
+Our packages are easily consumable with
+[create-react-app](https://github.com/facebook/create-react-app)
+and standard webpack configs. All packages follow a similar installation process.
+Below is an example of consuming our
+[react-buttons](https://www.npmjs.com/package/@zendeskgarden/react-buttons)
package.
### Install dependencies
@@ -194,6 +195,10 @@ class App extends Component {
render(, document.getElementById('root'));
```
+Try out Garden React components in a mock product environment.
+
+[](https://codesandbox.io/s/43nwpkn717)
+
## Contribution
Thanks for your interest in Garden! Community involvement helps make our
diff --git a/demo/index.html b/demo/index.html
index 65e851ced3d..6040c846c56 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -91,6 +91,9 @@
React Components
+
@@ -109,11 +112,11 @@ React Components
+
+
-
@@ -133,10 +136,10 @@
React Components
Selection
diff --git a/packages/autocomplete/src/examples/multiselect.md b/packages/autocomplete/src/examples/multiselect.md
index 4e5e88b9796..decc4e4b62c 100644
--- a/packages/autocomplete/src/examples/multiselect.md
+++ b/packages/autocomplete/src/examples/multiselect.md
@@ -283,8 +283,8 @@ const MoreAnchor = styled(Anchor)`
style: Object.assign(
{ margin: '0 2px', flexGrow: 1, width: 60 },
Object.keys(state.selectedKeys).length !== 0 &&
- (!state.isFocused || tagFocusedKey !== undefined) &&
- !isOpen
+ (!state.isFocused || tagFocusedKey !== undefined) &&
+ !isOpen
? { opacity: 0, height: 0, minHeight: 0 }
: {}
)
diff --git a/packages/breadcrumbs/CHANGELOG.md b/packages/breadcrumbs/CHANGELOG.md
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/packages/breadcrumbs/CHANGELOG.md
@@ -0,0 +1 @@
+
diff --git a/packages/breadcrumbs/README.md b/packages/breadcrumbs/README.md
new file mode 100644
index 00000000000..9492a7531f3
--- /dev/null
+++ b/packages/breadcrumbs/README.md
@@ -0,0 +1,37 @@
+# @zendeskgarden/react-breadcrumbs [](https://www.npmjs.com/package/@zendeskgarden/react-breadcrumbs)
+
+This package includes components relating to breadcrumbs in the
+[Garden Design System](https://zendeskgarden.github.io/).
+
+## Installation
+
+```sh
+npm install @zendeskgarden/react-breadcrumbs
+
+# Peer Dependencies - Also Required
+npm install react react-dom prop-types styled-components @zendeskgarden/react-theming
+```
+
+## Usage
+
+```jsx static
+/**
+ * Include breadcrumbs styling at the root of your application
+ */
+import '@zendeskgarden/react-breadcrumbs/dist/styles.css';
+
+import { ThemeProvider } from '@zendeskgarden/react-theming';
+import { Breadcrumb, Item } from '@zendeskgarden/react-breadcrumbs';
+import { Anchor } from '@zendeskgarden/react-buttons';
+
+/**
+ * Place a `ThemeProvider` at the root of your React application
+ */
+
+
+ Root
+ Parent
+ - Self
+
+;
+```
diff --git a/packages/breadcrumbs/package.json b/packages/breadcrumbs/package.json
new file mode 100644
index 00000000000..882120c4202
--- /dev/null
+++ b/packages/breadcrumbs/package.json
@@ -0,0 +1,47 @@
+{
+ "name": "@zendeskgarden/react-breadcrumbs",
+ "description": "Components relating to breadcrumbs in the Garden Design System",
+ "license": "Apache-2.0",
+ "author": "Zendesk Garden
",
+ "homepage": "https://garden.zendesk.com/",
+ "repository": "https://github.com/zendeskgarden/react-components",
+ "bugs": {
+ "url": "https://github.com/zendeskgarden/react-components/issues"
+ },
+ "version": "0.0.0",
+ "main": "./dist/index.js",
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "build": "../../utils/scripts/build.sh",
+ "build:demo": "../../utils/scripts/build-demo.sh",
+ "start": "../../utils/scripts/start.sh"
+ },
+ "dependencies": {
+ "classnames": "^2.2.5"
+ },
+ "peerDependencies": {
+ "@zendeskgarden/react-theming": "^1.0.0 || ^2.0.0 || ^3.0.0",
+ "prop-types": "^15.6.1",
+ "react": "^0.14.0 || ^15.0.0 || ^16.0.0",
+ "react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0",
+ "styled-components": "^3.2.6"
+ },
+ "devDependencies": {
+ "@zendeskgarden/css-breadcrumbs": "0.1.2",
+ "@zendeskgarden/react-theming": "^3.1.3",
+ "@zendeskgarden/react-utilities": "^0.2.2"
+ },
+ "keywords": [
+ "components",
+ "garden",
+ "react",
+ "zendesk"
+ ],
+ "publishConfig": {
+ "access": "public"
+ },
+ "zendeskgarden:library": "GardenBreadcrumbs",
+ "zendeskgarden:src": "src/index.js"
+}
diff --git a/packages/breadcrumbs/src/containers/BreadcrumbContainer.example.md b/packages/breadcrumbs/src/containers/BreadcrumbContainer.example.md
new file mode 100644
index 00000000000..50928b9969b
--- /dev/null
+++ b/packages/breadcrumbs/src/containers/BreadcrumbContainer.example.md
@@ -0,0 +1,20 @@
+```jsx
+const { Anchor } = require('@zendeskgarden/react-buttons/src');
+
+
+ {({ getContainerProps }) => (
+ /* role not needed as `BreadcrumbView` is a navigation landmark. */
+
+
+ -
+ One
+
+ -
+ Two
+
+ - Three
+
+
+ )}
+;
+```
diff --git a/packages/breadcrumbs/src/containers/BreadcrumbContainer.js b/packages/breadcrumbs/src/containers/BreadcrumbContainer.js
new file mode 100644
index 00000000000..4210ab58ee7
--- /dev/null
+++ b/packages/breadcrumbs/src/containers/BreadcrumbContainer.js
@@ -0,0 +1,39 @@
+/**
+ * Copyright Zendesk, Inc.
+ *
+ * Use of this source code is governed under the Apache License, Version 2.0
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
+ */
+
+import { Component } from 'react';
+import PropTypes from 'prop-types';
+
+export default class BreadcrumbContainer extends Component {
+ static propTypes = {
+ /**
+ * @param {Object} renderProps
+ * @param {Function} renderProps.getContainerProps - Props to be spread onto containing element
+ */
+ children: PropTypes.func,
+ /**
+ * Identical to children
+ */
+ render: PropTypes.func
+ };
+
+ getContainerProps = ({ role = 'navigation', ...other } = {}) => {
+ return {
+ role,
+ 'aria-label': 'Breadcrumb navigation',
+ ...other
+ };
+ };
+
+ render() {
+ const { children, render = children } = this.props;
+
+ return render({
+ getContainerProps: this.getContainerProps
+ });
+ }
+}
diff --git a/packages/breadcrumbs/src/containers/BreadcrumbContainer.spec.js b/packages/breadcrumbs/src/containers/BreadcrumbContainer.spec.js
new file mode 100644
index 00000000000..8b5bd5a45e8
--- /dev/null
+++ b/packages/breadcrumbs/src/containers/BreadcrumbContainer.spec.js
@@ -0,0 +1,34 @@
+/**
+ * Copyright Zendesk, Inc.
+ *
+ * Use of this source code is governed under the Apache License, Version 2.0
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
+ */
+
+import React from 'react';
+import { mountWithTheme } from '@zendeskgarden/react-testing';
+
+import BreadcrumbContainer from './BreadcrumbContainer';
+
+describe('BreadcrumbContainer', () => {
+ let wrapper;
+
+ beforeEach(() => {
+ wrapper = mountWithTheme(
+
+ {({ getContainerProps }) => }
+
+ );
+ });
+
+ const findContainer = enzymeWrapper => enzymeWrapper.find('[data-test-id="container"]');
+
+ describe('getContainerProps()', () => {
+ it('applies correct accessibility attributes', () => {
+ const container = findContainer(wrapper);
+
+ expect(container).toHaveProp('role', 'navigation');
+ expect(container).toHaveProp('aria-label', 'Breadcrumb navigation');
+ });
+ });
+});
diff --git a/packages/breadcrumbs/src/elements/Breadcrumb.example.md b/packages/breadcrumbs/src/elements/Breadcrumb.example.md
new file mode 100644
index 00000000000..5788bf1e49c
--- /dev/null
+++ b/packages/breadcrumbs/src/elements/Breadcrumb.example.md
@@ -0,0 +1,14 @@
+The `Breadcrumb` component follows the
+[W3C breadcrumb accessibility design pattern](https://www.w3.org/TR/wai-aria-practices/#breadcrumb)
+and applies the correct accessibility attributes to the `BreadcrumbView` listed below.
+Implementations are expected to override `aria-label` with a translated value describing usage.
+
+```jsx
+const { Anchor } = require('@zendeskgarden/react-buttons/src');
+
+
+ Home
+ React Components
+ - Breadcrumbs
+;
+```
diff --git a/packages/breadcrumbs/src/elements/Breadcrumb.js b/packages/breadcrumbs/src/elements/Breadcrumb.js
new file mode 100644
index 00000000000..211258ac13e
--- /dev/null
+++ b/packages/breadcrumbs/src/elements/Breadcrumb.js
@@ -0,0 +1,57 @@
+/**
+ * Copyright Zendesk, Inc.
+ *
+ * Use of this source code is governed under the Apache License, Version 2.0
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
+ */
+
+import React, { Component, Children, cloneElement } from 'react';
+import PropTypes from 'prop-types';
+import { hasType } from '@zendeskgarden/react-utilities';
+
+import BreadcrumbContainer from '../containers/BreadcrumbContainer';
+import BreadcrumbView from '../views/BreadcrumbView';
+import List from '../views/List';
+import Item from '../views/Item';
+
+/**
+ * High-level abstraction for basic Breadcrumb implementations. Accepts all
+ * `` props.
+ */
+export default class Breadcrumb extends Component {
+ static propTypes = {
+ children: PropTypes.any
+ };
+
+ renderItems = items => {
+ const total = Children.count(items);
+
+ return Children.map(items, (item, index) => {
+ const itemProps = {
+ current: index === total - 1,
+ key: index
+ };
+
+ return hasType(item, Item) ? (
+ cloneElement(item, itemProps)
+ ) : (
+ - {item}
+ );
+ });
+ };
+
+ render() {
+ const { children, ...breadcrumbProps } = this.props;
+
+ return (
+
+ {({ getContainerProps }) => (
+ /* role not needed as `BreadcrumbView` is a navigation landmark. */
+
+ {this.renderItems(children)}
+
+ )}
+
+ );
+ }
+}
diff --git a/packages/breadcrumbs/src/elements/Breadcrumb.spec.js b/packages/breadcrumbs/src/elements/Breadcrumb.spec.js
new file mode 100644
index 00000000000..4d490a0bba1
--- /dev/null
+++ b/packages/breadcrumbs/src/elements/Breadcrumb.spec.js
@@ -0,0 +1,64 @@
+/**
+ * Copyright Zendesk, Inc.
+ *
+ * Use of this source code is governed under the Apache License, Version 2.0
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
+ */
+
+import React from 'react';
+import { mountWithTheme } from '@zendeskgarden/react-testing';
+
+import Breadcrumb from './Breadcrumb';
+import BreadcrumbView from '../views/BreadcrumbView';
+import List from '../views/List';
+import Item from '../views/Item';
+
+describe('Breadcrumb', () => {
+ let wrapper;
+
+ beforeEach(() => {
+ wrapper = mountWithTheme(
+
+ One
+
+ Two
+
+ - Three
+
+ );
+ });
+
+ describe('BreadcrumbView', () => {
+ it('receives BreadcrumbContainer props', () => {
+ expect(wrapper.find(BreadcrumbView)).toHaveProp('aria-label', 'Breadcrumb navigation');
+ });
+
+ it('does not receive BreadcrumbContainer `role` prop', () => {
+ expect(wrapper.find(BreadcrumbView)).not.toHaveProp('role', 'navigation');
+ });
+ });
+
+ describe('List', () => {
+ it('receives Breadcrumb props', () => {
+ expect(wrapper.find(List)).toHaveProp('data-test-breadcrumb', true);
+ });
+ });
+
+ describe('Item', () => {
+ it('receives Item props', () => {
+ expect(wrapper.find(Item).last()).toHaveProp('data-test-item', true);
+ });
+
+ it('does not receive non-Item props', () => {
+ expect(wrapper.find(Item).at(1)).not.toHaveProp('data-test-anchor', true);
+ });
+
+ it('receives current styling if last', () => {
+ expect(wrapper.find(Item).last()).toHaveProp('current', true);
+ });
+
+ it('does not receive current styling if not last', () => {
+ expect(wrapper.find(Item).first()).not.toHaveProp('current', true);
+ });
+ });
+});
diff --git a/packages/breadcrumbs/src/index.js b/packages/breadcrumbs/src/index.js
new file mode 100644
index 00000000000..45e1b1902ce
--- /dev/null
+++ b/packages/breadcrumbs/src/index.js
@@ -0,0 +1,12 @@
+/**
+ * Copyright Zendesk, Inc.
+ *
+ * Use of this source code is governed under the Apache License, Version 2.0
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
+ */
+
+export { default as Breadcrumb } from './elements/Breadcrumb';
+export { default as BreadcrumbContainer } from './containers/BreadcrumbContainer';
+export { default as BreadcrumbView } from './views/BreadcrumbView';
+export { default as List } from './views/List';
+export { default as Item } from './views/Item';
diff --git a/packages/breadcrumbs/src/views/BreadcrumbView.js b/packages/breadcrumbs/src/views/BreadcrumbView.js
new file mode 100644
index 00000000000..7781b34c3e9
--- /dev/null
+++ b/packages/breadcrumbs/src/views/BreadcrumbView.js
@@ -0,0 +1,24 @@
+/**
+ * Copyright Zendesk, Inc.
+ *
+ * Use of this source code is governed under the Apache License, Version 2.0
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
+ */
+
+import styled from 'styled-components';
+import { retrieveTheme } from '@zendeskgarden/react-theming';
+
+const COMPONENT_ID = 'breadcrumbs.breadcrumb_view';
+
+/**
+ * Accepts all `