css-variants
Version:
A lightweight, flexible API for managing CSS class variants.
65 lines • 2.22 kB
JavaScript
import { mergeProps } from './utils/merge-props';
/**
* Creates a style variant function based on the provided configuration.
*
* @template T - The type of the style variant record.
* @param {StyleVariantDefinition<T>} config - The configuration object for style variants.
* @returns {StyleVariantFn<T>} A function that takes props and returns the computed CSS properties.
*
* @example
* ```typescript
*
* const makeStyle = sv({
* base: { color: 'black' },
* variants: {
* size: {
* small: { fontSize: '12px' },
* large: { fontSize: '24px' }
* }
* },
* compoundVariants: [
* { size: 'large', style: { fontWeight: 'bold' } }
* ],
* defaultVariants: { size: 'small' }
* });
*
* const style = makeStyle({ size: 'large' });
* // style = { color: 'black', fontSize: '24px', fontWeight: 'bold' }
* ```
*/
export const sv = (config) => {
const { base, variants, compoundVariants, defaultVariants } = config;
if (!variants) {
return (props) => ({ ...base, ...props?.style });
}
return (props) => {
const { style, ...rest } = props ?? {};
let result = { ...base };
const mergedProps = defaultVariants ? mergeProps(defaultVariants, rest) : rest;
for (const key in mergedProps) {
const styleValue = variants[key][mergedProps[key]];
if (styleValue) {
result = { ...result, ...styleValue };
}
}
if (compoundVariants) {
for (const { style: styleValue, ...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) {
result = { ...result, ...styleValue };
}
}
}
return { ...result, ...style };
};
};
export default sv;
//# sourceMappingURL=sv.js.map