From 3da1bbcc5a583c3fb72dde0c5525772db265a49b Mon Sep 17 00:00:00 2001 From: scotttong Date: Mon, 6 Jul 2026 18:41:11 -0700 Subject: [PATCH] feat(ui): restyle ToggleSwitch to shadcn capsule form, status-green on-state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Registry radix-luma Switch form (border-2 capsule track, oval thumb, bg-input off-state) on the existing button API — no Radix dep, no call-site changes. On-state uses var(--status-task-done) per user ruling instead of bg-primary; deviation documented in the component. Co-Authored-By: Claude Fable 5 --- ui/src/components/ui/toggle-switch.tsx | 31 ++++++++++++++------------ 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/ui/src/components/ui/toggle-switch.tsx b/ui/src/components/ui/toggle-switch.tsx index d4995f2556..de471adf32 100644 --- a/ui/src/components/ui/toggle-switch.tsx +++ b/ui/src/components/ui/toggle-switch.tsx @@ -8,6 +8,14 @@ export interface ToggleSwitchProps size?: "default" | "lg"; } +/* + * Custom API (checked/onCheckedChange button, no Radix dep) with the shadcn + * radix-luma Switch's capsule form: border-2 track, oval thumb, bg-input + * off-state. Deliberate deviation from the registry: the on-state is the + * status-system green (var(--status-task-done)), not bg-primary — user + * ruling, DECISION-SHEET "toggle form" note. Do not swap for the registry + * Switch without revisiting that ruling (C7). + */ export const ToggleSwitch = React.forwardRef< HTMLButtonElement, ToggleSwitchProps @@ -27,12 +35,13 @@ export const ToggleSwitch = React.forwardRef< data-slot="toggle" disabled={disabled} className={cn( - "relative inline-flex shrink-0 items-center rounded-full transition-colors", - "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", + "relative inline-flex shrink-0 items-center rounded-full border-2 transition-all outline-none", + "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/30", "disabled:cursor-not-allowed disabled:opacity-50", - // Track: larger on mobile (<640px), standard on desktop - isLg ? "h-7 w-12 sm:h-6 sm:w-11" : "h-6 w-10 sm:h-5 sm:w-9", - checked ? "bg-green-600" : "bg-muted", + isLg ? "h-6 w-12" : "h-5 w-11", + checked + ? "border-(--status-task-done) bg-(--status-task-done)" + : "border-transparent bg-input/90", className, )} onClick={() => onCheckedChange(!checked)} @@ -40,15 +49,9 @@ export const ToggleSwitch = React.forwardRef< >