css-variants
Version:
A lightweight, flexible API for managing CSS class variants.
69 lines • 2.36 kB
JavaScript
import { mergeProps } from './utils/merge-props';
import { cx } from './cx';
/**
* Creates a class variant function that combines base classes, variants, compound variants, and default variants.
*
* @template T - Type of the variant record
* @param config - Configuration object for creating class variants
* @returns A function that accepts variant props and returns a combined class string
*
* @example
* ```typescript
* const button = cv({
* base: 'px-4 py-2 rounded',
* variants: {
* color: {
* primary: 'bg-blue-500 text-white',
* secondary: 'bg-gray-500 text-white'
* },
* size: {
* sm: 'text-sm',
* lg: 'text-lg'
* }
* },
* defaultVariants: {
* color: 'primary',
* size: 'sm'
* }
* });
*
* button(); // => 'px-4 py-2 rounded bg-blue-500 text-white text-sm'
* button({ color: 'secondary' }); // => 'px-4 py-2 rounded bg-gray-500 text-white text-sm'
* ```
*/
export const cv = (config) => {
const { base, variants, compoundVariants, defaultVariants, classNameResolver = cx } = config;
if (!variants) {
return (props) => classNameResolver(base, props?.className);
}
return (props) => {
const { className, ...rest } = props ?? {};
const mergedProps = defaultVariants ? mergeProps(defaultVariants, rest) : rest;
const classValues = [];
for (const key in mergedProps) {
const classValue = variants[key][mergedProps[key]];
if (classValue) {
classValues.push(classValue);
}
}
if (compoundVariants) {
for (const { className: classValue, ...compoundVariant } of compoundVariants) {
let matches = true;
for (const key in compoundVariant) {
const value = compoundVariant[key];
const propValue = mergedProps[key];
if (Array.isArray(value) ? !value.includes(propValue) : value !== propValue) {
matches = false;
break;
}
}
if (matches) {
classValues.push(classValue);
}
}
}
return classNameResolver(base, classValues, className);
};
};
export default cv;
//# sourceMappingURL=cv.js.map