UNPKG

@itwin/itwinui-react

Version:

A react component library for iTwinUI

192 lines (191 loc) 5.09 kB
import * as React from 'react'; import cx from 'classnames'; import { SvgChevronRight, Box, OverflowContainer, useWarningLogger, cloneElementWithRef, } from '../../utils/index.js'; import { Button } from '../Buttons/Button.js'; import { Anchor } from '../Typography/Anchor.js'; let BreadcrumbsComponent = React.forwardRef((props, forwardedRef) => { let { children: childrenProp, currentIndex = React.Children.count(childrenProp) - 1, separator, overflowButton, className, ...rest } = props; let items = React.useMemo( () => React.Children.toArray(childrenProp), [childrenProp], ); return React.createElement( Box, { as: 'nav', className: cx('iui-breadcrumbs', className), ref: forwardedRef, 'aria-label': 'Breadcrumb', ...rest, }, React.createElement( OverflowContainer, { as: 'ol', itemsCount: items.length, className: 'iui-breadcrumbs-list', }, React.createElement( BreadcrumbContent, { currentIndex: currentIndex, overflowButton: overflowButton, separator: separator, }, items, ), ), ); }); if ('development' === process.env.NODE_ENV) BreadcrumbsComponent.displayName = 'Breadcrumbs'; let BreadcrumbContent = (props) => { let { children: items, currentIndex, overflowButton, separator } = props; let { visibleCount } = OverflowContainer.useContext(); return React.createElement( React.Fragment, null, visibleCount > 1 && React.createElement( React.Fragment, null, React.createElement(ListItem, { item: items[0], isActive: 0 === currentIndex, }), React.createElement(Separator, { separator: separator, }), ), items.length - visibleCount > 0 && React.createElement( React.Fragment, null, React.createElement( Box, { as: 'li', className: 'iui-breadcrumbs-item', }, overflowButton ? overflowButton(visibleCount) : React.createElement( Box, { as: 'span', className: 'iui-breadcrumbs-content', }, '…', ), ), React.createElement(Separator, { separator: separator, }), ), items .slice( visibleCount > 1 ? items.length - visibleCount + 1 : items.length - 1, ) .map((_, _index) => { let index = visibleCount > 1 ? 1 + (items.length - visibleCount) + _index : items.length - 1; return React.createElement( React.Fragment, { key: index, }, React.createElement(ListItem, { item: items[index], isActive: currentIndex === index, }), index < items.length - 1 && React.createElement(Separator, { separator: separator, }), ); }), ); }; let ListItem = ({ item, isActive }) => { let children = item; let logWarning = useWarningLogger(); if ( children?.type === 'span' || children?.type === 'a' || children?.type === Button ) { if ('development' === process.env.NODE_ENV) logWarning( 'Directly using Button/a/span as Breadcrumbs children is deprecated, please use `Breadcrumbs.Item` instead.', ); children = React.createElement(BreadcrumbsItem, children.props); } let getProps = React.useCallback( (children) => { let defaultAriaCurrent = isActive ? 'location' : void 0; return { 'aria-current': children.props['aria-current'] ?? defaultAriaCurrent, }; }, [isActive], ); return React.createElement( Box, { as: 'li', className: 'iui-breadcrumbs-item', }, children ? cloneElementWithRef(children, getProps) : null, ); }; let Separator = ({ separator }) => React.createElement( Box, { as: 'li', className: 'iui-breadcrumbs-separator', 'aria-hidden': true, }, separator ?? React.createElement(SvgChevronRight, null), ); let BreadcrumbsItem = React.forwardRef((props, forwardedRef) => { let { as: asProp, ...rest } = props; let commonProps = { ...rest, className: cx('iui-breadcrumbs-content', props.className), ref: forwardedRef, }; if ( 'span' === String(asProp) || (null == props.href && null == props.onClick && null == asProp) ) return React.createElement(Box, { as: 'span', ...commonProps, }); return React.createElement(Button, { as: 'a' === asProp || (null == asProp && props.href) ? Anchor : asProp, styleType: 'borderless', ...commonProps, }); }); if ('development' === process.env.NODE_ENV) BreadcrumbsItem.displayName = 'Breadcrumbs.Item'; export const Breadcrumbs = Object.assign(BreadcrumbsComponent, { Item: BreadcrumbsItem, });