Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
# Switch Variants (cva config)
## Purpose
`switchVariants` and `switchThumbVariants` are the two cva (class-variance-authority) configurations that together power every `<Switch>` render. They are split from `switch.tsx` into their own module so an ejected source copy under `npx shadcn@latest add @suaveplan/switch` keeps the cva configurations in a dedicated file. Theme overrides flow through `useThemedVariants("Switch", switchVariants)`, so the runtime cva resolver can be replaced or extended by an active `ThemePlugin` without touching the component source.
The track and thumb are deliberately kept as separate cva instances so a `ThemePlugin` can override one independently of the other — for example a glossy-thumb theme with a flat track.
## Features
- Three sizes (`sm` → `h-4 w-7`, `default` → `h-5 w-9`, `lg` → `h-6 w-11`) for both track and thumb.
- `data-[state=checked]:bg-primary` flips the track colour when on.
- `data-[state=checked]:translate-x-*` slides the thumb across the track.
- `disabled:cursor-not-allowed disabled:opacity-50` for the native disabled state.
- `motion-reduce:transition-none` collapses both colour + transform transitions for `prefers-reduced-motion: reduce`.
- `focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2` for keyboard-only focus styling.
## Usage: Basic Example
```ts
import { switchVariants, switchThumbVariants } from "@suaveplan/react-ui";
const trackClassName = switchVariants({ size: "default" });
const thumbClassName = switchThumbVariants({ size: "default" });
```
## Usage: Advanced Example
```ts
import { switchVariants, switchThumbVariants, cn } from "@suaveplan/react-ui";
export function CustomSwitch() {
return (
<button
type="button"
role="switch"
aria-checked="false"
data-state="unchecked"
className={cn(switchVariants({ size: "lg" }), "ring-2 ring-accent")}
>
<span
className={cn(
switchThumbVariants({ size: "lg" }),
"bg-accent-foreground"
)}
/>
</button>
);
}
```
## API Reference
### `switchVariants(props?: { size?: "sm" | "default" | "lg" }): string`
Returns the cva-merged class string for the track. Omitted props fall back to the cva `defaultVariants` (`size: "default"`).
### `switchThumbVariants(props?: { size?: "sm" | "default" | "lg" }): string`
Returns the cva-merged class string for the thumb. The size axis MUST match the track's size — mismatched sizes produce a thumb that overflows or under-fills the track.
## Implementation Notes
- Both resolvers are tagged with `componentName: "Switch"` / `componentName: "SwitchThumb"` (non-enumerable, non-writable) via `defineVariants`.
- The thumb's `translate-x-*` per-size value is hard-coded rather than computed — cva is a string-templating library, not a runtime calculator. The math is `track-width − thumb-width − padding-x*2`.
- The track and thumb size axes are kept symmetric so a single `size` prop on `<Switch>` propagates to both. A future change could make them independent if the chassis ever needs an `extra-large-thumb` shape.