"use client"; import { AnimatePresence, motion, useReducedMotion } from "motion/react"; import { useId, useState, type ReactNode } from "react"; import { EASE_OUT, SPRING_LAYOUT } from "@/lib/ease"; import { useHoverCapable } from "@/lib/hooks/use-hover-capable"; import { cn } from "@/lib/utils"; export interface PreviewRailItem { id: string; label: string; description?: ReactNode; href: string; target?: "_blank" | "_self" | "_parent" | "_top"; rel?: string; } export interface PreviewRailProps { items: PreviewRailItem[]; orientation?: "vertical" | "horizontal"; activeId?: string; defaultActiveId?: string; onActiveChange?: (id: string) => void; renderPreview?: (item: PreviewRailItem) => ReactNode; children?: ReactNode; className?: string; railClassName?: string; previewClassName?: string; } function DefaultPreview({ item }: { item: PreviewRailItem }) { return (

{item.label}

{item.description ? (
{item.description}
) : null}
); } export function PreviewRail({ items, orientation = "vertical", activeId, defaultActiveId, onActiveChange, renderPreview, children, className, railClassName, previewClassName, }: PreviewRailProps) { const uid = useId(); const reduce = useReducedMotion(); const canHover = useHoverCapable(); const [internalActiveId, setInternalActiveId] = useState( defaultActiveId ?? items[0]?.id ?? "", ); const [hoveredId, setHoveredId] = useState(null); const [focusedId, setFocusedId] = useState(null); const requestedActiveId = activeId ?? internalActiveId; const selectedId = items.some((item) => item.id === requestedActiveId) ? requestedActiveId : (items[0]?.id ?? ""); const displayedId = hoveredId ?? focusedId ?? ""; const displayedIndex = items.findIndex((item) => item.id === displayedId); const rowTemplate = items.length ? `repeat(${items.length}, 1.25rem)` : undefined; const isHorizontal = orientation === "horizontal"; const selectItem = (id: string) => { if (activeId === undefined) setInternalActiveId(id); onActiveChange?.(id); }; return ( { if (!event.currentTarget.contains(event.relatedTarget)) { setFocusedId(null); } }} className={cn( "isolate relative flex w-full overflow-visible", isHorizontal ? "min-h-64 flex-col items-center justify-center" : "min-h-80", className, )} > {children ? (
{children}
) : null}
); }