diff --git a/.changeset/feat-switch-xs-size.md b/.changeset/feat-switch-xs-size.md new file mode 100644 index 0000000000..907f03933e --- /dev/null +++ b/.changeset/feat-switch-xs-size.md @@ -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). diff --git a/.opencode/package-lock.json b/.opencode/package-lock.json index e74899eb91..a427e44bff 100644 --- a/.opencode/package-lock.json +++ b/.opencode/package-lock.json @@ -5,7 +5,7 @@ "packages": { "": { "dependencies": { - "@opencode-ai/plugin": "1.4.6" + "@opencode-ai/plugin": "1.4.7" } }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { @@ -87,12 +87,12 @@ ] }, "node_modules/@opencode-ai/plugin": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@opencode-ai/plugin/-/plugin-1.4.6.tgz", - "integrity": "sha512-w+55uE4tCpFoK+MtWeGoPDmpuuabw8m5WVpmucIKoTO5SgD/3EwXVPBqAh44iS72ve1Eu+uhhzeVQ070x9bVjg==", + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@opencode-ai/plugin/-/plugin-1.4.7.tgz", + "integrity": "sha512-RbzMl7ILvQDHpZNvqzi6RCYaGcB3eBwNIMRZww467drLvMd1eOwr4/qAurrvYDsIIEctE6cKsrLuSGIKCW/Fxg==", "license": "MIT", "dependencies": { - "@opencode-ai/sdk": "1.4.6", + "@opencode-ai/sdk": "1.4.7", "effect": "4.0.0-beta.48", "zod": "4.1.8" }, @@ -110,9 +110,9 @@ } }, "node_modules/@opencode-ai/sdk": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.4.6.tgz", - "integrity": "sha512-sQaVfEfQW3m3DeCVlurSTUjgIYdIk+gIfOys51MVFYzJHw+FyjjuAt7EKKA+LeZU5AiWGlpkIRa1rJo5KWMXCw==", + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.4.7.tgz", + "integrity": "sha512-onEtaooQyoDP5gTShQeQSf0Sd8V7949G9pPNyIyRXnVtFqyDIhUDLGtL/a/+EIW9x5s+Y6lDy/3oVoGMvQ0rQQ==", "license": "MIT", "dependencies": { "cross-spawn": "7.0.6" diff --git a/packages/kumo-docs-astro/src/components/demos/SwitchDemo.tsx b/packages/kumo-docs-astro/src/components/demos/SwitchDemo.tsx index 66ba25d05d..4e198f68da 100644 --- a/packages/kumo-docs-astro/src/components/demos/SwitchDemo.tsx +++ b/packages/kumo-docs-astro/src/components/demos/SwitchDemo.tsx @@ -98,6 +98,12 @@ export function SwitchCustomIdDemo() { export function SwitchSizesDemo() { return (
+ {}} + /> Three sizes available: `sm`, `base` (default), and `lg`.

+

+ Four sizes available: `xs`, `sm`, `base` (default), and `lg`. The `xs` size is + designed for inline badges, pills, and compact toolbars. +

diff --git a/packages/kumo/src/components/switch/switch.tsx b/packages/kumo/src/components/switch/switch.tsx index 388bc64e06..1def26cc85 100644 --- a/packages/kumo/src/components/switch/switch.tsx +++ b/packages/kumo/src/components/switch/switch.tsx @@ -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", @@ -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 @@ -237,6 +243,7 @@ const SwitchBase = forwardRef( // 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" }, @@ -387,6 +394,7 @@ const SwitchItem = forwardRef( // 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" },