From 2efb07e0b12d1e5436fbde2136ee73f7aedeb334 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Fri, 21 Aug 2026 10:24:29 +0100 Subject: [PATCH] Toggle switch feels nicer to toggle (#4749) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two small tweaks to the `Switch` primitive, so every variant and call site picks them up: 1. **Track is 2px shorter.** `large` 44 → 42px, `medium` 32 → 30px, `small` 24 → 22px. The checked thumb travel drops by the same 2px so the thumb stays flush at both ends. 2. **Holding the switch down stretches the thumb into an oval** pointing the way it's about to travel — rightwards when off, leftwards when on. Pure CSS via `group-active:`, no new state or handlers. The thumb's `transition` shorthand doesn't cover `width`, so it's now `transition-[translate,width,background-color]` (same 150ms duration/easing as before). `size-N` on the thumb became `h-N w-N` so the press rule overrides the same `width` utility. Verified in headless Chrome across all five variants in both states: correct widths at rest, thumb flush at both ends, stretch grows the right direction, and no overflow of the track. CleanShot 2026-08-21 at 10 16 14 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- [Open workspace in Conductor](https://app.conductor.build/workspace/c1ce8d0f-9ed2-4fbc-8084-a3989484cc53) --------- Co-authored-by: Claude Opus 5 (1M context) --- .../app/components/primitives/Switch.tsx | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/apps/webapp/app/components/primitives/Switch.tsx b/apps/webapp/app/components/primitives/Switch.tsx index 99c8e4043..eed7799fe 100644 --- a/apps/webapp/app/components/primitives/Switch.tsx +++ b/apps/webapp/app/components/primitives/Switch.tsx @@ -8,16 +8,22 @@ import { type ShortcutDefinition, useShortcutKeys } from "~/hooks/useShortcutKey const small = { container: "flex items-center h-6 gap-x-1.5 rounded hover:bg-tertiary pr-1 py-[0.1rem] pl-1.5 hover:disabled:bg-background-raised transition focus-custom disabled:opacity-50 text-text-dimmed hover:text-text-bright disabled:hover:cursor-not-allowed hover:cursor-pointer disabled:hover:text-rose-500", - root: "h-3 w-6", - thumb: "size-2.5 data-[state=checked]:translate-x-2.5 data-[state=unchecked]:translate-x-0", + root: "h-3 w-5.5", + thumb: cn( + "h-2.5 w-2.5 data-[state=checked]:translate-x-2 data-[state=unchecked]:translate-x-0", + "group-active:w-3.25 group-active:data-[state=checked]:translate-x-1.25" + ), text: "text-xs text-text-dimmed", }; const variations = { large: { container: "flex items-center gap-x-2 rounded-md hover:bg-tertiary p-2 transition focus-custom", - root: "h-6 w-11", - thumb: "size-5 data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0", + root: "h-6 w-10.5", + thumb: cn( + "h-5 w-5 data-[state=checked]:translate-x-4.5 data-[state=unchecked]:translate-x-0", + "group-active:w-6.5 group-active:data-[state=checked]:translate-x-3" + ), text: "text-sm text-text-dimmed", }, small, @@ -48,8 +54,11 @@ const variations = { medium: { container: "flex items-center gap-x-2 rounded-md hover:bg-tertiary py-1.5 px-2 transition focus-custom", - root: "h-4 w-8", - thumb: "size-3.5 data-[state=checked]:translate-x-3.5 data-[state=unchecked]:translate-x-0", + root: "h-4 w-7.5", + thumb: cn( + "h-3.5 w-3.5 data-[state=checked]:translate-x-3 data-[state=unchecked]:translate-x-0", + "group-active:w-4.5 group-active:data-[state=checked]:translate-x-2" + ), text: "text-sm text-text-dimmed", }, }; @@ -96,7 +105,7 @@ export const Switch = React.forwardRef