import type { HTMLAttributes, ReactNode } from "react"; import { Children, isValidElement } from "react"; import { cx } from "../../utils/cx.utils"; import { Icon } from "../icons/icon"; import "./breadcrumbs.component.css"; /** Props accepted by {@link BreadCrumbs}. */ export interface BreadCrumbsProps extends HTMLAttributes { /** {@link BreadCrumbs.Item} elements making up the trail. */ children: ReactNode; /** Called with the `target` of the {@link BreadCrumbs.Item} that was clicked. */ onNavigate?: (target: string) => void; } /** Props accepted by {@link BreadCrumbs.Item}. */ export interface BreadCrumbsItemProps { /** Destination this item represents, passed to `onNavigate` when clicked. */ target: string; /** Item label. */ children: ReactNode; } /** * Single step of a {@link BreadCrumbs} trail. Can only be used inside * {@link BreadCrumbs}, which reads its `target` to report clicks. * * @example * ```tsx * Settings * ``` */ function BreadCrumbsItem({ children }: BreadCrumbsItemProps) { return <>{children}; } /** * Page navigation trail. Renders a house icon before the first * {@link BreadCrumbs.Item} and a `/` separator between items; clicking an * item calls `onNavigate` with its `target`. * * @example * ```tsx * router.push(target)}> * Home * Settings * Profile * * ``` */ export function BreadCrumbs({ className, children, onNavigate, ...rest }: BreadCrumbsProps) { const items = Children.toArray(children).filter( (child): child is React.ReactElement => isValidElement(child) && child.type === BreadCrumbsItem, ); return ( ); } BreadCrumbs.Item = BreadCrumbsItem;