/* eslint-disable max-lines-per-function */ import { forwardRef, memo } from "react"; import { omit } from "../../utils"; import { IconButton } from "../icon-button"; import { Icons } from "../icons"; import { CrumbListItem, CrumbsList, CrumbText, OverflowContent, OverflowCrumbsTrigger, RadixNavigationMenuLink, Root, StyledCrumbButton, SubCrumbLink, Crumb as StyledCrumb, SubCrumbList, SubCrumbListItem, } from "./breadcrumbs.styled"; import { Crumb } from "./sub-components/crumb"; import { SubCrumb } from "./sub-components/sub-crumb"; import { useBreadcrumbs } from "./use-breadcrumbs"; import type { UrlObject } from "url"; import type { Link } from "../link"; type BaseCrumb = { Icon?: React.ReactElement; }; type Crumb = { label: string; href: string; linkProps?: Omit, "href">; } & BaseCrumb; type LinkCrumb = { linkElement: React.ReactElement<{ href: string | UrlObject; children: string; style?: React.CSSProperties; ref?: React.ForwardedRef; }>; } & BaseCrumb; type ButtonCrumb = { label: string; onClick: React.ButtonHTMLAttributes["onClick"]; buttonProps?: Omit, "onClick">; } & BaseCrumb; type TextCrumb = { label: string; } & BaseCrumb; interface Props extends Omit, "asChild"> { /** * Array of link elements with string children and optional icon */ crumbs: Array; /** * Optional custom divider */ divider?: React.ReactNode; /** * Sets Icon position to end of container. (only affects sub crumbs with icons) */ iconPosition?: "start" | "end"; /** * [Radix Documentation](https://www.radix-ui.com/primitives/docs/components/navigation-menu#list) */ crumbsListProps?: Omit, "data-crumb-list">; /** * [Radix Documentation](https://www.radix-ui.com/primitives/docs/components/navigation-menu#content) */ subCrumbListContainerProps?: React.ComponentProps; /** * [Radix Documentation](https://www.radix-ui.com/primitives/docs/components/navigation-menu#item) */ crumbItemProps?: React.ComponentProps; /** * [Radix Documentation](https://www.radix-ui.com/primitives/docs/components/navigation-menu#trigger) * Only applicable if there is overflow */ subCrumbTriggerProps?: React.ComponentProps; } const BreadcrumbsComponent = forwardRef((props, ref) => { const { crumbs, divider: customDivider, iconPosition, crumbsListProps, subCrumbListContainerProps, crumbItemProps, subCrumbTriggerProps, ...rest } = props; const { rootRef, overflowAtIndex, divider } = useBreadcrumbs({ crumbs, customDivider, ref, }); return ( {typeof overflowAtIndex === "number" && crumbs.length >= 3 ? ( <> } variant="secondary" /> {crumbs.slice(1, overflowAtIndex + 1).map((crumb, i) => ( ))} {crumbs.slice(overflowAtIndex + 1).map((crumb, i) => { const isLast = i === crumbs.slice(overflowAtIndex + 1).length - 1; return ( ); })} ) : ( crumbs.map((crumb, i) => { const isLastCrumb = i === crumbs.length - 1; const isFirst = i === 0; return ( ); }) )} {crumbs.map((crumb, i) => { const isLastCrumb = i === crumbs.length - 1; return ( ); })} ); }); BreadcrumbsComponent.displayName = "Breadcrumbs"; /** * Based on [Radix Primitives Navigation Menu](https://www.radix-ui.com/primitives/docs/components/navigation-menu) * * * The Breadcrumbs component is a navigational tool that visualises the user's path through a website or app. It renders a `