Initial Commit
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user