svd-kit
v1.1.0
Published
Styling variance decomposition kit supporting base styles, variants, modifiers, and compound variants.
Maintainers
Readme
svd-kit
Styling decomposition system supporting base styles, variants, modifiers, and compound variants.
What is SVD?
SVD (Styling Variance Decomposition) is a utility built to easily define and consume complex styling configurations. It addresses the limitations of standard variance systems by introducing flexible multi-slot mapping, base styles, boolean modifiers, and compound variants.
This utility comes in extremely handy when:
- Building scalable design systems with flexible slot mapping and granular component control.
- Developing highly customizable UI components requiring deep structural decomposition.
- Eliminating type boilerplate while retaining deep TypeScript autocomplete and safety.
Key Features
svd-kit was highly inspired by SVDM (Styling Variance Decomposition Module).
While SVDM introduced multi-slot object decomposition, svd-kit was built to solve real-world architectural scenarios that SVDM can't handle, such as:
- Merged or Split Usage: Use the full
stylesblock or extract isolated slots (e.g.,styles.variants.size). classNameMerging: ExternalclassNameprops can be automatically appended to the end of the chain.- Boolean Modifiers: Accepts both simple strings and full
{ true: "...", false: "..." }boolean objects. - Compounded Variants: Create styles that apply when multiple variant or modifier conditions are met.
.resolvedProperty: Exposes final values after merging inputs with defaults, perfect fordata-*attributes.
Installation
It is very easy to install svd-kit. You can install it with any package manager.
pnpm install svd-kitHow to Use SVD
Here you can find a very simple example of how to define styling configurations and use them in your components. More examples can be found in the documentation.
Definition and Structure
Every field (base, variants, modifiers, compound, defaults) is optional, use only what you need.
import { svd } from "svd-kit"
const buttonStyles = svd({
base: { layout: "flex gap-1", content: "text-sm" },
variants: {
variant: {
primary: { container: "bg-primary", content: "text-on-primary" },
secondary: { container: "bg-secondary", content: "text-on-secondary" },
},
size: { md: "h-8 px-2", sm: "h-7 px-1" },
},
modifiers: {
pill: { true: "rounded-full", false: "rounded-md" },
disabled: "opacity-50",
},
compound: [
{ size: "sm", pill: true, className: "px-3" },
],
defaults: {
variants: { variant: "primary", size: "md" },
modifiers: { pill: true },
}
});Applying on Components
Either pass the entire instance to merge everything or destructure the individual slots for granular layout control.
import { type SVDProps, splitProps } from "svd-kit"
import { cn } from "@/lib/utils"
type ButtonProps = ButtonPrimitive.Props & SVDProps<typeof buttonStyles>;
export function Button(props: ButtonProps) {
const [stylingProps, buttonProps] = splitProps(props, buttonStyles);
const styles = buttonStyles(stylingProps);
return (
<ButtonPrimitive
data-variant={styles.resolved.variants.variant}
{...buttonProps}
className={cn(styles)}
/>
)
}Built Out of Necessity
svd-kit was born out of necessity to solve the messy, unpredictable styling challenges that design systems face.
Its greatest strength is flexibility. Whether you're building a massive UI library or just quick conditional flags for a simple button, svd-kit works without getting in your way.
