/** * Segmented (web). A compact single-select control — a row of segments * with one active. For 2–4 mutually exclusive views (Review / Pack, * Edit / Score / Preview, theme mode). Sliding highlight tracks the * selection. * * */ import { type CSSProperties } from "react"; import { useTheme } from "@plyxui/styles"; import { radius, spacing } from "@plyxui/core"; export type SegmentedSize = "sm" | "md"; export interface SegmentedOption { label: string; value: T; disabled?: boolean; } export interface SegmentedProps { options: SegmentedOption[]; value: T; onChange: (value: T) => void; size?: SegmentedSize; fullWidth?: boolean; className?: string; style?: CSSProperties; } const heightMap: Record = { sm: 30, md: 36 }; export function Segmented({ options, value, onChange, size = "md", fullWidth, className, style, }: SegmentedProps) { const { colors } = useTheme(); const idx = Math.max(0, options.findIndex((o) => o.value === value)); const h = heightMap[size]; return ( {/* sliding highlight */} {options.map((o) => { const active = o.value === value; return ( !o.disabled && onChange(o.value)} style={{ position: "relative", zIndex: 1, background: "transparent", border: "none", cursor: o.disabled ? "default" : "pointer", padding: `0 ${spacing[3]}px`, font: "inherit", fontSize: size === "sm" ? 12.5 : 13.5, fontWeight: 600, color: active ? colors.text : colors.textMuted, opacity: o.disabled ? 0.5 : 1, transition: "color 0.2s ease", whiteSpace: "nowrap", }} > {o.label} ); })} ); }