import { CaretRightRegularIcon } from "alouette-icons/phosphor-icons/CaretRight";
import { Children, type ReactNode, useMemo } from "react";
import type { AccentOrNeutral } from "../../core/AlouetteConfig";
import { tv } from "../../core/tv";
import { Box } from "../containers/Box";
import { Icon, type SVGIconElement } from "../primitives/Icon";
import {
BreadcrumbItemContextProvider,
type BreadcrumbItemContextValue,
} from "./BreadcrumbsContext";
// The trail has no ground of its own — it labels the page rather than framing
// it — and wraps rather than overflowing on a narrow screen.
const breadcrumbsVariants = tv({
slots: {
frame: "flex-row flex-wrap items-center",
separator: "text-muted",
},
});
interface BreadcrumbSlotProps extends BreadcrumbItemContextValue {
children: ReactNode;
}
function BreadcrumbSlot({
current,
disabled,
onNavigate,
children,
}: BreadcrumbSlotProps): ReactNode {
const context = useMemo(
() => ({ current, disabled, onNavigate }),
[current, disabled, onNavigate],
);
return (
{children}
);
}
export interface BreadcrumbsProps {
"aria-label"?: string;
/** Icon drawn between two crumbs. Defaults to a caret. */
separator?: SVGIconElement;
/**
* Called with the pressed crumb's `href`, for an app that routes in JS: the
* crumb then cancels the anchor's own navigation. Without it — and without an
* item `onPress` — the `` navigates on web and native does nothing.
*/
onNavigate?: (href: string) => void;
accent?: AccentOrNeutral;
disabled?: boolean;
/** `BreadcrumbItem`s, from the root down to the page being viewed. */
children: ReactNode;
className?: string;
}
/**
* Trail of the path to the current page. Each `BreadcrumbItem` is a link to an
* ancestor except the last one, which the trail marks as the current page.
*/
export function Breadcrumbs({
"aria-label": ariaLabel = "Breadcrumb",
separator = ,
onNavigate,
accent,
disabled = false,
children,
className,
}: BreadcrumbsProps): ReactNode {
const styles = breadcrumbsVariants();
const lastIndex = Children.count(children) - 1;
return (
{Children.map(children, (child, index) => (
{index > 0 ? (
) : null}
{child}
))}
);
}