feat(ui): restyle ToggleSwitch to shadcn capsule form, status-green on-state
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 <noreply@anthropic.com>
This commit is contained in:
parent
e2c6f4b4b7
commit
3da1bbcc5a
|
|
@ -8,6 +8,14 @@ export interface ToggleSwitchProps
|
||||||
size?: "default" | "lg";
|
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<
|
export const ToggleSwitch = React.forwardRef<
|
||||||
HTMLButtonElement,
|
HTMLButtonElement,
|
||||||
ToggleSwitchProps
|
ToggleSwitchProps
|
||||||
|
|
@ -27,12 +35,13 @@ export const ToggleSwitch = React.forwardRef<
|
||||||
data-slot="toggle"
|
data-slot="toggle"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative inline-flex shrink-0 items-center rounded-full transition-colors",
|
"relative inline-flex shrink-0 items-center rounded-full border-2 transition-all outline-none",
|
||||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
"focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/30",
|
||||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
// Track: larger on mobile (<640px), standard on desktop
|
isLg ? "h-6 w-12" : "h-5 w-11",
|
||||||
isLg ? "h-7 w-12 sm:h-6 sm:w-11" : "h-6 w-10 sm:h-5 sm:w-9",
|
checked
|
||||||
checked ? "bg-green-600" : "bg-muted",
|
? "border-(--status-task-done) bg-(--status-task-done)"
|
||||||
|
: "border-transparent bg-input/90",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
onClick={() => onCheckedChange(!checked)}
|
onClick={() => onCheckedChange(!checked)}
|
||||||
|
|
@ -40,15 +49,9 @@ export const ToggleSwitch = React.forwardRef<
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
"pointer-events-none inline-block rounded-full bg-white shadow-sm transition-transform",
|
"pointer-events-none inline-block rounded-full bg-background shadow-sm transition-transform not-dark:bg-clip-padding dark:bg-foreground",
|
||||||
// Thumb
|
isLg ? "h-5 w-7" : "h-4 w-6",
|
||||||
isLg ? "size-5.5 sm:size-5" : "size-4.5 sm:size-3.5",
|
checked ? "translate-x-4" : "translate-x-0",
|
||||||
// Slide position
|
|
||||||
checked
|
|
||||||
? isLg
|
|
||||||
? "translate-x-5 sm:translate-x-5"
|
|
||||||
: "translate-x-5 sm:translate-x-4.5"
|
|
||||||
: "translate-x-0.5",
|
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue