Skip to content

Commit

Permalink
feat(breadcrumb): add overflow menu support (#7085)
Browse files Browse the repository at this point in the history
* feat(breadcrumb): add overflow menu support

* fix(storybook): use better example text

* fix(breadcrumb): tweak overflow styles

* fix(breadcrumb): few more tweaks

* fix(breadcrumb): use horizontal icon

* docs(breadcrumb): add docs / show code for overflow variant

* fix(a11y): add floating menu container to breadcrumb item

Co-authored-by: Taylor Jones <tay1orjones@users.noreply.github.com>
  • Loading branch information
tw15egan and tay1orjones committed Mar 29, 2021
1 parent 48e09a0 commit 431e5fc
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 0 deletions.
66 changes: 66 additions & 0 deletions packages/components/src/components/breadcrumb/_breadcrumb.scss
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,72 @@
}
}

// Overflow Menu overrides
.#{$prefix}--breadcrumb-item .#{$prefix}--overflow-menu {
position: relative;
width: rem(20px);
height: rem(20px);

&:focus {
outline: 1px solid $focus;
}

&:hover {
background: transparent;
}

// Used to mimic link underline
&::after {
position: absolute;
bottom: 2px;
width: rem(12px);
height: 1px;
background: $hover-primary-text;
opacity: 0;
transition: opacity $duration--fast-01 motion(standard, productive);
content: '';
}
}

.#{$prefix}--breadcrumb-item .#{$prefix}--overflow-menu:hover::after {
opacity: 1;
}

.#{$prefix}--breadcrumb-item
.#{$prefix}--overflow-menu.#{$prefix}--overflow-menu--open {
background: transparent;
box-shadow: none;
}

.#{$prefix}--breadcrumb-item .#{$prefix}--overflow-menu__icon {
position: relative;
transform: translateY(4px);
fill: $link-01;
}

.#{$prefix}--breadcrumb-item
.#{$prefix}--overflow-menu:hover
.#{$prefix}--overflow-menu__icon {
fill: $hover-primary-text;
}

.#{$prefix}--breadcrumb-menu-options:focus {
outline: none;
}

$caret-size: rem(7px);
.#{$prefix}--breadcrumb-menu-options.#{$prefix}--overflow-menu-options::after {
top: -$caret-size;
left: $caret-size * 2;
width: 0;
height: 0;
margin: 0 auto;
background: transparent;
border-right: $caret-size solid transparent;
border-bottom: $caret-size solid $field-01;
border-left: $caret-size solid transparent;
}

// Skeleton State
.#{$prefix}--breadcrumb.#{$prefix}--skeleton .#{$prefix}--link {
@include skeleton;
Expand Down
18 changes: 18 additions & 0 deletions packages/react/src/components/Breadcrumb/Breadcrumb-story.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import React from 'react';
import { action } from '@storybook/addon-actions';
import { withKnobs, boolean } from '@storybook/addon-knobs';
import { Breadcrumb, BreadcrumbItem, BreadcrumbSkeleton } from '../Breadcrumb';
import OverflowMenu from '../OverflowMenu';
import OverflowMenuItem from '../OverflowMenuItem';
import mdx from './Breadcrumb.mdx';

export default {
Expand Down Expand Up @@ -38,6 +40,22 @@ export const breadcrumb = () => (
</Breadcrumb>
);

export const breadcrumbWithOverflowMenu = () => (
<Breadcrumb>
<BreadcrumbItem>
<a href="/#">Breadcrumb 1</a>
</BreadcrumbItem>
<BreadcrumbItem href="#">Breadcrumb 2</BreadcrumbItem>
<BreadcrumbItem data-floating-menu-container>
<OverflowMenu>
<OverflowMenuItem itemText="Breadcrumb 3" />
<OverflowMenuItem itemText="Breadcrumb 4" />
</OverflowMenu>
</BreadcrumbItem>
<BreadcrumbItem href="#">Breadcrumb 5</BreadcrumbItem>
</Breadcrumb>
);

export const skeleton = () => <BreadcrumbSkeleton />;

const props = () => ({
Expand Down
11 changes: 11 additions & 0 deletions packages/react/src/components/Breadcrumb/Breadcrumb.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ responsible for displaying the page links in the hierarchy.
<Story id="components-breadcrumb--breadcrumb" />
</Preview>

## Breadcrumb with `OverflowMenu`

When space becomes limited, use an `OverflowMenu` to truncate the breadcrumbs.
The first and last two page links should be shown, but the remaining breadcrumbs
in between are condensed into an overflow menu. Breadcrumbs should never wrap
onto a second line.

<Preview>
<Story id="breadcrumb--breadcrumb-with-overflow-menu" />
</Preview>

## Skeleton state

You can use the `BreadcrumbSkeleton` component to render a skeleton variant of a
Expand Down
20 changes: 20 additions & 0 deletions packages/react/src/components/Breadcrumb/BreadcrumbItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import React from 'react';
import cx from 'classnames';
import { settings } from 'carbon-components';
import Link from '../Link';
import { OverflowMenuHorizontal16 } from '@carbon/icons-react';

const { prefix } = settings;

Expand All @@ -33,6 +34,25 @@ const BreadcrumbItem = React.forwardRef(function BreadcrumbItem(
[customClassName]: !!customClassName,
});

if (
children.type &&
children.type.displayName !== undefined &&
children.type.displayName === 'OverflowMenu'
) {
const horizontalOverflowIcon = (
<OverflowMenuHorizontal16 className={`${prefix}--overflow-menu__icon`} />
);
return (
<li className={className} {...rest}>
{React.cloneElement(children, {
menuOptionsClass: `${prefix}--breadcrumb-menu-options`,
menuOffset: { top: 10, left: 59 },
renderIcon: () => horizontalOverflowIcon,
})}
</li>
);
}

if (typeof children === 'string' && href) {
return (
<li className={className} ref={ref} {...rest}>
Expand Down

0 comments on commit 431e5fc

Please sign in to comment.