Skip to content

Commit

Permalink
feat(breadcrumbs): Added overflow menu breadcrumb variant
Browse files Browse the repository at this point in the history
  • Loading branch information
ishakasliwal authored and Ayesha Mazumdar committed Oct 2, 2017
1 parent adb39a6 commit a69621c
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 8 deletions.
3 changes: 3 additions & 0 deletions ui/components/breadcrumbs/_doc.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
* utility. When you add the `.slds-breadcrumb` class, the separators are
* automatically generated.
*
* **Overflow Menu Variant**
* The overflow menu breadcrumbs variant is a composition of the overflow menu with actions example of the menus component and breadcrumbs component. To implement this, include the overflow menu as the first `<li>` in the breadcrumb component. In order to vertically align all of the breadcrumb items to the center, add the `.slds-grid_vertical-align-center` class to the `<ol>`.
*
* #### Accessibility
*
* Place the breadcrumb in a `nav` element with `role="navigation"`.
Expand Down
4 changes: 4 additions & 0 deletions ui/components/breadcrumbs/base/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,8 @@
}
}
}

.slds-dropdown-trigger {
margin-right: $spacing-x-small;
}
}
67 changes: 62 additions & 5 deletions ui/components/breadcrumbs/base/example.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,67 @@
import React from 'react';
import BreadCrumbs from '../index.react';
const { Crumb } = BreadCrumbs;
import { ButtonIcon } from '../../button-icons/base/example';
import { Trigger } from '../../menus/dropdown/example';
import { Menu } from '../../menus/dropdown/example';
import { MenuList } from '../../menus/dropdown/example';
import { MenuItem } from '../../menus/dropdown/example';

export default (
<BreadCrumbs>
<Crumb href="javascript:void(0);">Parent Entity</Crumb>
<Crumb href="javascript:void(0);">Parent Record Name</Crumb>
</BreadCrumbs>
const moreIcon = (
<ButtonIcon
className="slds-button_icon-border-filled slds-button_icon-x-small"
sprite="utility"
symbol="threedots"
assistiveText="Show More"
aria-haspopup="true"
title="Show More"
/>
);

let BreadcrumbMenu = props => (
<Trigger className="slds-is-open" triggerIcon={moreIcon}>
<Menu className="slds-dropdown_left slds-dropdown_actions">
<MenuList>
<MenuItem tabIndex="0">Menu Item One</MenuItem>
<MenuItem>Menu Item Two</MenuItem>
<MenuItem>Menu Item Three</MenuItem>
</MenuList>
</Menu>
</Trigger>
);

export let examples = [
{
id: 'base',
label: 'Base',
element: (
<BreadCrumbs>
<Crumb className="slds-text-title_caps" href="javascript:void(0);">
Parent Entity
</Crumb>
<Crumb className="slds-text-title_caps" href="javascript:void(0);">
Parent Record Name
</Crumb>
</BreadCrumbs>
)
},
{
id: 'overflow-breadcrumbs',
label: 'Breadcrumbs with Overflow Menu',
element: (
<div style={{ height: '250px' }}>
<BreadCrumbs listClassNames="slds-grid_vertical-align-center">
<Crumb hasMenu>
<BreadcrumbMenu />
</Crumb>
<Crumb className="slds-text-title_caps" href="javascript:void(0);">
Parent Entity
</Crumb>
<Crumb className="slds-text-title_caps" href="javascript:void(0);">
Parent Record Name
</Crumb>
</BreadCrumbs>
</div>
)
}
];
12 changes: 9 additions & 3 deletions ui/components/breadcrumbs/index.react.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license

import React from 'react';
import classNames from 'classnames';

const Crumb = props => (
<li className="slds-breadcrumb__item slds-text-title_caps">
<a href={props.href}>{props.children}</a>
<li className={classNames('slds-breadcrumb__item', props.className)}>
{props.hasMenu ? props.children : <a href={props.href}>{props.children}</a>}
</li>
);

Crumb.propTypes = { href: React.PropTypes.string };

const BreadCrumbs = props => (
<nav {...props} role="navigation" aria-label="Breadcrumbs">
<ol className="slds-breadcrumb slds-list_horizontal slds-wrap">
<ol
className={classNames(
'slds-breadcrumb slds-list_horizontal slds-wrap',
props.listClassNames
)}
>
{props.children}
</ol>
</nav>
Expand Down

3 comments on commit a69621c

@AnthonyIsaacs
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am curious about whether you were able to determine whether the overflow menu pattern was accessible in breadcrumb interactions? I've been trying something similar, but I'm not sure that it's a good experience for keyboard navigation or assistive technology users.

@SiTaggart
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pattern is plenty accessible, our menus are accessible, our breadcrumbs are accessible, so the 2 together are still "accessible".

Now, is it a good user experience? Is it clear and obvious? Could be debated, but it seems to work well for us when we are constrained by horizontal space and deep hierarchies.

@AnthonyIsaacs
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the reply!

Are you sure? When I tab through the BASE: BREADCRUMBS WITH OVERFLOW MENU example on https://www.lightningdesignsystem.com/components/breadcrumbs/, focus jumps onto Menu Item One as expected, but then skips the other menu items and goes to the PARENT ENTITY breadcrumb. Just because two components are accessible, any particular composition of those components is not necessarily accessible.

Are the docs supposed to include the ability to interact with the components in ways that you would on a production site? I found it really confusing that the breadcrumb overflow menu was just stuck open. I pulled the project down and ran the previewer locally, but I couldn't understand how to use it very well. I would have expected the examples to show the intended interactions that each component supports, not just various states of the component. Am I just missing something?

Please sign in to comment.