Skip to content

Commit 2efb07e

Browse files
samejrclaude
andauthored
Toggle switch feels nicer to toggle (#4749)
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. <img width="266" height="108" alt="CleanShot 2026-08-21 at 10 16 14" src="https://github.com/user-attachments/assets/ee95a399-0a40-48c4-a325-a1166b3bd88a" /> 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- conductor-workspace-link --> --- [Open workspace in Conductor](https://app.conductor.build/workspace/c1ce8d0f-9ed2-4fbc-8084-a3989484cc53) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent d044670 commit 2efb07e

1 file changed

Lines changed: 16 additions & 7 deletions

File tree

apps/webapp/app/components/primitives/Switch.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,22 @@ import { type ShortcutDefinition, useShortcutKeys } from "~/hooks/useShortcutKey
88
const small = {
99
container:
1010
"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",
11-
root: "h-3 w-6",
12-
thumb: "size-2.5 data-[state=checked]:translate-x-2.5 data-[state=unchecked]:translate-x-0",
11+
root: "h-3 w-5.5",
12+
thumb: cn(
13+
"h-2.5 w-2.5 data-[state=checked]:translate-x-2 data-[state=unchecked]:translate-x-0",
14+
"group-active:w-3.25 group-active:data-[state=checked]:translate-x-1.25"
15+
),
1316
text: "text-xs text-text-dimmed",
1417
};
1518

1619
const variations = {
1720
large: {
1821
container: "flex items-center gap-x-2 rounded-md hover:bg-tertiary p-2 transition focus-custom",
19-
root: "h-6 w-11",
20-
thumb: "size-5 data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0",
22+
root: "h-6 w-10.5",
23+
thumb: cn(
24+
"h-5 w-5 data-[state=checked]:translate-x-4.5 data-[state=unchecked]:translate-x-0",
25+
"group-active:w-6.5 group-active:data-[state=checked]:translate-x-3"
26+
),
2127
text: "text-sm text-text-dimmed",
2228
},
2329
small,
@@ -48,8 +54,11 @@ const variations = {
4854
medium: {
4955
container:
5056
"flex items-center gap-x-2 rounded-md hover:bg-tertiary py-1.5 px-2 transition focus-custom",
51-
root: "h-4 w-8",
52-
thumb: "size-3.5 data-[state=checked]:translate-x-3.5 data-[state=unchecked]:translate-x-0",
57+
root: "h-4 w-7.5",
58+
thumb: cn(
59+
"h-3.5 w-3.5 data-[state=checked]:translate-x-3 data-[state=unchecked]:translate-x-0",
60+
"group-active:w-4.5 group-active:data-[state=checked]:translate-x-2"
61+
),
5362
text: "text-sm text-text-dimmed",
5463
},
5564
};
@@ -96,7 +105,7 @@ export const Switch = React.forwardRef<React.ElementRef<typeof SwitchPrimitives.
96105
<SwitchPrimitives.Thumb
97106
className={cn(
98107
thumb,
99-
"pointer-events-none block rounded-full bg-white transition dark:bg-charcoal-200 dark:group-data-[state=checked]:bg-text-bright"
108+
"pointer-events-none block rounded-full bg-white transition-[translate,width,background-color] dark:bg-charcoal-200 dark:group-data-[state=checked]:bg-text-bright"
100109
)}
101110
/>
102111
</div>

0 commit comments

Comments
 (0)