@spaced-out/ui-design-system
Version:
Sense UI components library
60 lines (49 loc) • 1.63 kB
Flow
// @flow strict
import * as React from 'react';
import classify from '../../utils/classify';
import {Icon} from '../Icon';
import type {BaseLinkProps} from '../Link';
import css from './Breadcrumbs.module.css';
type ClassNames = $ReadOnly<{wrapper?: string}>;
export type BreadcrumbsProps = {
classNames?: ClassNames,
children: React.Node,
linkComponent?: React.AbstractComponent<BaseLinkProps, ?HTMLAnchorElement>,
};
const BreadcrumbSeparator = (): React.Node => (
<Icon
className={css.separator}
name="chevron-right"
size="small"
color="secondary"
/>
);
export const Breadcrumbs: React$AbstractComponent<
BreadcrumbsProps,
HTMLDivElement,
> = React.forwardRef<BreadcrumbsProps, HTMLDivElement>(
({classNames, children, linkComponent}: BreadcrumbsProps, ref) => {
const total = React.Children.count(children);
return (
<div
ref={ref}
data-testid="Breadcrumbs"
className={classify(css.wrapper, classNames?.wrapper)}
>
{React.Children.map(children, (child, idx) => (
// eslint-disable-next-line react/no-array-index-key
<React.Fragment key={`crumb-${idx}`}>
{/*add linkComponent to BreadcrumbLinks only,
otherwise return original element */}
{React.isValidElement(child) &&
child?.type?.displayName === 'BreadcrumbLink'
? React.cloneElement(child, {linkComponent})
: child}
{/*Add Separator*/}
{idx < total - 1 && <BreadcrumbSeparator aria-hidden />}
</React.Fragment>
))}
</div>
);
},
);