import { Pencil } from "lucide-react"; import { Button } from "@/components/ui/button"; interface HoverEditButtonProps { onClick: () => void; label?: string; /** Controls visibility below the `md:` (768px) breakpoint. * * - `always` (default): the button is always visible on mobile/touch. * - `hover`: keep the legacy opacity-0-everywhere behavior. * * At `md:` and above the hover-reveal aesthetic is always preserved * (`md:opacity-0 md:group-hover:opacity-100`), so desktop is not regressed. * See OpenSpec change `mobile-responsive-parity`, spec R5. */ mobile?: "always" | "hover"; } /** * Hover-to-reveal edit affordance (desktop) / always-visible (mobile). * * Keeps the `rail-edit` class plus the opacity base + transition so the * existing hover-reveal rules in consuming pages (Actions, Settings) still * target it (`&:hover .rail-edit { opacity: 1 }`) until those pages migrate. * * Mobile behavior (`mobile="always"`, the default): the button is visible by * default below `md` because hover does not fire on touch. The hover-reveal * aesthetic is layered back on at `md:` and above via `md:opacity-0 * md:group-hover:opacity-100`. MUI IconButton + EditOutlined → shadcn `Button * variant="ghost" size="icon-sm"` + lucide `Pencil`. Same exported props/display * name. See OpenSpec change `mobile-responsive-parity`, spec R5. */ export function HoverEditButton({ onClick, label = "Edit", mobile = "always", }: HoverEditButtonProps) { // Legacy mode: opacity-0 everywhere, revealed by group hover (the consuming // row supplies `group`). const hoverClasses = mobile === "hover" ? "opacity-0 transition-opacity duration-100 ease-out group-hover:opacity-100" : "md:opacity-0 md:transition-opacity md:duration-100 md:ease-out md:group-hover:opacity-100"; return ( ); }