import { createContext, useContext, Children, cloneElement, isValidElement, type ReactNode, type ReactElement, type AnchorHTMLAttributes } from 'react'; export interface BreadcrumbProps { children: ReactNode; 'aria-label'?: string; className?: string; } export interface BreadcrumbItemProps extends Omit< AnchorHTMLAttributes, 'children' > { children: ReactNode; active?: boolean; } interface BreadcrumbContextValue { total: number; index: number; } const BreadcrumbContext = createContext({ total: 0, index: 0 }); const SAFE_SCHEMES = /^(https?:|\/|#|mailto:|tel:)/i; function safeHref(href: string | undefined): string | undefined { if (!href) return undefined; if (!SAFE_SCHEMES.test(href)) { if (typeof console !== 'undefined') { console.warn(`[Breadcrumb] rejected href: ${href}`); } return undefined; } return href; } function BreadcrumbRoot({ children, className, 'aria-label': ariaLabel = 'Breadcrumb' }: BreadcrumbProps): ReactElement { const items = Children.toArray(children).filter(isValidElement); return ( ); } function BreadcrumbItem({ active, href, children, className, ...rest }: BreadcrumbItemProps): ReactElement { const { total, index } = useContext(BreadcrumbContext); const isLast = total > 0 && index === total - 1; const safe = safeHref(href); const isActive = active === true || (active === undefined && isLast && !safe); const liClass = ['breadcrumb__item', className].filter(Boolean).join(' '); if (isActive || !safe) { return (
  • {children}
  • ); } return (
  • {children}
  • ); } export const Breadcrumb = Object.assign(BreadcrumbRoot, { Item: BreadcrumbItem }); export default Breadcrumb;