Breadcrumbs
Navigate a folder hierarchy quickly with a table and breadcrumbs.
import * as React from 'react';
import { Breadcrumbs } from '@itwin/itwinui-react';
export default () => {
return (
<Breadcrumbs>
<Breadcrumbs.Item onClick={() => {}}>Root</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}}>Item 1</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}}>Item 2</Breadcrumbs.Item>
</Breadcrumbs>
);
};
Breadcrumbs are a way of navigating a folder structure. Breadcrumbs should be used in conjunction with tables, tiles, and website navigation. Once you start drilling in levels, the breadcrumbs are updated to navigate quickly between opened levels.
Appearance
There are two styles of breadcrumbs supported:
Links
The breadcrumb items can be displayed as clickable anchor links that the user can interact with to navigate back and forth. If clicking a breadcrumb item changes the URL, then using the link style is preferred.
import * as React from 'react';
import { Breadcrumbs } from '@itwin/itwinui-react';
export default () => {
return (
<Breadcrumbs>
<Breadcrumbs.Item href='#'>Home</Breadcrumbs.Item>
<Breadcrumbs.Item href='#'>Support</Breadcrumbs.Item>
<Breadcrumbs.Item>Contact us</Breadcrumbs.Item>
</Breadcrumbs>
);
};
Buttons
The breadcrumb items can be displayed as buttons. If clicking a breadcrumb item keeps the user on the same URL, but loads different content within the page, then using the button style is preferred.
import * as React from 'react';
import { Breadcrumbs } from '@itwin/itwinui-react';
export default () => {
return (
<Breadcrumbs>
<Breadcrumbs.Item onClick={() => {}}>Root</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}}>My files</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}}>Documents</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}}>Status reports</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}}>December</Breadcrumbs.Item>
</Breadcrumbs>
);
};
Usage
Folder navigation
When navigating a directory, there are additional options to enhance the user’s experience. Depending on how deep in the folder structure the user is, some breadcrumb items may need to be hidden or truncated. To make it easier to quickly navigate, we have 2 suggestions:
- Place a dropdown button at the front of the breadcrumbs that displays the full path within a dropdown menu.
- When clicking on the current location, the breadcrumb can be replaced with an input displaying the full path. This allows for quick navigation or sharing the path with another user.
import * as React from 'react';
import {
Breadcrumbs,
DropdownButton,
MenuItem,
Input,
} from '@itwin/itwinui-react';
import { SvgFolder } from '@itwin/itwinui-icons-react';
export default () => {
const items = React.useMemo(
() => ['Root', 'My files', 'Documents', 'Status reports'],
[],
);
const [lastIndex, setLastIndex] = React.useState(items.length - 1);
const [isEditing, setIsEditing] = React.useState(false);
const breadcrumbItems = React.useMemo(
() =>
items.slice(0, lastIndex + 1).map((item, index) => (
<Breadcrumbs.Item
key={`Breadcrumb${index}`}
onClick={() => {
if (lastIndex !== index) {
setLastIndex(index);
} else {
setIsEditing(true);
}
}}
>
{item}
</Breadcrumbs.Item>
)),
[items, lastIndex],
);
return (
<div className='demo-container'>
<DropdownButton
startIcon={<SvgFolder aria-hidden />}
styleType='borderless'
aria-label='All levels'
menuItems={(close) =>
items.map((item, index) => (
<MenuItem
key={`Item${index}`}
onClick={() => {
setLastIndex(index);
setIsEditing(false);
close();
}}
>
{item}
</MenuItem>
))
}
/>
{isEditing ? (
<Input
aria-label='Path'
defaultValue={items.slice(0, lastIndex + 1).join('/')}
onChange={({ target: { value } }) => {
const lastItem = value.substring(
value.lastIndexOf('/', value.length - 2) + 1,
);
setLastIndex(items.findIndex((item) => lastItem.includes(item)));
}}
onKeyDown={({ key }) => key === 'Enter' && setIsEditing(false)}
onBlur={() => setIsEditing(false)}
/>
) : (
<Breadcrumbs>{breadcrumbItems}</Breadcrumbs>
)}
</div>
);
};
Truncation
Show as many previously accessed folders as possible so that users can quickly go back to an upper level. If all breadcrumb items can be shown without horizontal scrolling, show them all. Try to keep the first level - the root folder - always accessible. When you start truncating, start with the secondly accessed folder and work your way from there.
import * as React from 'react';
import { Breadcrumbs } from '@itwin/itwinui-react';
export default () => {
return (
<div className='demo-container'>
<Breadcrumbs>
<Breadcrumbs.Item onClick={() => {}}>Root</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}}>My files</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}}>Documents</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}}>Status reports</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}}>December</Breadcrumbs.Item>
</Breadcrumbs>
</div>
);
};
If the available space does not allow to display both the previous folder and current folder, start truncating text.
import * as React from 'react';
import { Breadcrumbs, MiddleTextTruncation } from '@itwin/itwinui-react';
export default () => {
return (
<div className='demo-container'>
<Breadcrumbs>
<Breadcrumbs.Item onClick={() => {}} className='demo-breadcrumbs-item'>
<MiddleTextTruncation text='Root' endCharsCount={7} />
</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}} className='demo-breadcrumbs-item'>
<MiddleTextTruncation text='My files' endCharsCount={7} />
</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}} className='demo-breadcrumbs-item'>
<MiddleTextTruncation text='Documents' endCharsCount={7} />
</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}} className='demo-breadcrumbs-item'>
<MiddleTextTruncation text='Status reports' endCharsCount={7} />
</Breadcrumbs.Item>
<Breadcrumbs.Item onClick={() => {}} className='demo-breadcrumbs-item'>
<MiddleTextTruncation text='December' endCharsCount={7} />
</Breadcrumbs.Item>
</Breadcrumbs>
</div>
);
};
The property overflowButton
allows you to show a custom button when truncation is necessary. You could add a dropdown to show all of the hidden breadcrumbs, as in the example below.
import * as React from 'react';
import {
Breadcrumbs,
DropdownMenu,
MenuItem,
IconButton,
} from '@itwin/itwinui-react';
import { SvgMore } from '@itwin/itwinui-icons-react';
export default () => {
const items = Array(10)
.fill(null)
.map((_, index) => (
<Breadcrumbs.Item onClick={() => {}} key={index}>
Item {index}
</Breadcrumbs.Item>
));
return (
<div className='demo-container'>
<Breadcrumbs
overflowButton={(visibleCount) => (
<DropdownMenu
menuItems={(close) =>
Array(items.length - visibleCount)
.fill(null)
.map((_, _index) => {
const index = visibleCount > 1 ? _index + 1 : _index;
const onClick = () => {
// open breadcrumb
close();
};
return (
<MenuItem key={index} onClick={onClick}>
Item {index}
</MenuItem>
);
})
}
>
<IconButton
aria-label='Dropdown with more breadcrumbs'
styleType='borderless'
>
<SvgMore />
</IconButton>
</DropdownMenu>
)}
>
{items}
</Breadcrumbs>
</div>
);
};
Props
Prop | Description | Default |
---|---|---|
currentIndex | Index of the currently active breadcrumb.
Defaults to the index of the last breadcrumb item. number | |
children | Breadcrumb items. ReactNode[] | |
separator | Specify a custom separator element to show between breadcrumb items.
Defaults to the SvgChevronRight icon.ReactNode | |
overflowButton | If specified, this prop will be used to show a custom button when overflow happens,
i.e. when there is not enough space to fit all the breadcrumbs. Expects a function that takes the number of items that are visible and returns the ReactNode to render.(visibleCount: number) => ReactNode | |
as | "symbol" | "object" | "nav" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | ... 158 more ... | FunctionComponent<...> |