Skip to content

Commit a49e2f2

Browse files
samejrclaude
andcommitted
feat(webapp): squish the toggle switch thumb while it's held down
Shorten every switch variant's track by 2px, and stretch the thumb into an oval towards the direction it's about to travel while the switch is held down. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent d044670 commit a49e2f2

1 file changed

Lines changed: 22 additions & 7 deletions

File tree

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

Lines changed: 22 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
};
@@ -93,10 +102,16 @@ export const Switch = React.forwardRef<React.ElementRef<typeof SwitchPrimitives.
93102
root
94103
)}
95104
>
105+
{/*
106+
The `group-active:` classes in `thumb` stretch it into an oval while the switch is held
107+
down. An unchecked thumb is flush with the left of the track, so extra width grows it
108+
rightwards on its own; a checked thumb gives back the same amount of translation to stay
109+
pinned right and grow leftwards instead.
110+
*/}
96111
<SwitchPrimitives.Thumb
97112
className={cn(
98113
thumb,
99-
"pointer-events-none block rounded-full bg-white transition dark:bg-charcoal-200 dark:group-data-[state=checked]:bg-text-bright"
114+
"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"
100115
)}
101116
/>
102117
</div>

0 commit comments

Comments
 (0)