Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/feat-switch-xs-size.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@cloudflare/kumo": minor
---

feat(switch): add `xs` extra-small size variant

Adds a new `size="xs"` option to the Switch component for use in inline badges, pills, and compact toolbars where the existing `sm` size is too large. The `xs` switch renders at 14x28px (track) with a 14px thumb, following the same squircle shape, ring border, and thumb shadow as all other sizes.

Size progression: `xs` (14px) < `sm` (16px) < `base` (18px) < `lg` (20px).
16 changes: 8 additions & 8 deletions .opencode/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/kumo-docs-astro/src/components/demos/SwitchDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ export function SwitchCustomIdDemo() {
export function SwitchSizesDemo() {
return (
<div className="flex flex-col gap-4">
<Switch
label="Extra small"
size="xs"
checked={true}
onCheckedChange={() => {}}
/>
<Switch
label="Small"
size="sm"
Expand Down
5 changes: 4 additions & 1 deletion packages/kumo-docs-astro/src/pages/components/switch.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,10 @@ export default function Example() {

### Sizes

<p>Three sizes available: `sm`, `base` (default), and `lg`.</p>
<p>
Four sizes available: `xs`, `sm`, `base` (default), and `lg`. The `xs` size is
designed for inline badges, pills, and compact toolbars.
</p>
<ComponentExample demo="SwitchSizesDemo">
<SwitchSizesDemo client:visible />
</ComponentExample>
Expand Down
8 changes: 8 additions & 0 deletions packages/kumo/src/components/switch/switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ import { Fieldset } from "@base-ui/react/fieldset";
/** Switch size and variant definitions mapping names to their Tailwind classes. */
export const KUMO_SWITCH_VARIANTS = {
size: {
xs: {
classes: "h-4.5 w-7 min-h-6 min-w-6",
description:
"Extra-small switch for inline badges, pills, and compact toolbars. Track is visually compact but touch target meets WCAG 2.5.8 minimum (24x24px).",
},
sm: {
classes: "h-5.5 w-8.5",
description: "Small switch for compact UIs",
Expand Down Expand Up @@ -51,6 +56,7 @@ export type KumoSwitchVariant = keyof typeof KUMO_SWITCH_VARIANTS.variant;
export interface KumoSwitchVariantsProps {
/**
* Switch size.
* - `"xs"` — Extra-small for inline badges, pills, and compact toolbars
* - `"sm"` — Small for compact UIs
* - `"base"` — Default size
* - `"lg"` — Large for prominent toggles
Expand Down Expand Up @@ -237,6 +243,7 @@ const SwitchBase = forwardRef<HTMLButtonElement, SwitchProps>(

// Size styles matching Kyle's stratus implementation
const sizeStyles = {
xs: { track: "h-3.5 w-7", thumb: "w-3.5", slide: "left-3.5" },
sm: { track: "h-4 w-8", thumb: "w-4", slide: "left-4" },
base: { track: "h-4.5 w-9", thumb: "w-4.5", slide: "left-4.5" },
lg: { track: "h-5 w-10", thumb: "w-5", slide: "left-5" },
Expand Down Expand Up @@ -387,6 +394,7 @@ const SwitchItem = forwardRef<HTMLButtonElement, SwitchItemProps>(

// Size styles matching Kyle's stratus implementation
const sizeStyles = {
xs: { track: "h-3.5 w-7", thumb: "w-3.5", slide: "left-3.5" },
sm: { track: "h-4 w-8", thumb: "w-4", slide: "left-4" },
base: { track: "h-4.5 w-9", thumb: "w-4.5", slide: "left-4.5" },
lg: { track: "h-5 w-10", thumb: "w-5", slide: "left-5" },
Expand Down
Loading