Skip to content

Commit

Permalink
fix: support multi-level extend for compoundVariants (#170)
Browse files Browse the repository at this point in the history
* fix: support multi-level extend for `compoundVariants`

Fixes #168

* chore: add `test:watch` script for testing
  • Loading branch information
mskelton authored Mar 15, 2024
1 parent d6ac934 commit 8ec5f34
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"postpack": "clean-package restore",
"lint": "eslint -c .eslintrc.json ./src/**/*.{ts,tsx}",
"lint:fix": "eslint --fix -c .eslintrc.json ./src/**/*.{ts,tsx}",
"test": "jest --verbose"
"test": "jest --verbose",
"test:watch": "jest --watch --no-verbose"
},
"dependencies": {
"tailwind-merge": "^2.2.0"
Expand Down
31 changes: 31 additions & 0 deletions src/__tests__/tv.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2962,6 +2962,37 @@ describe("Tailwind Variants (TV) - Extends", () => {
expect(base()).toHaveClass(["menuBase", "menu"]);
expect(title()).toHaveClass(["title"]);
});

it("should support multi-level extends", () => {
const themeButton = tv({
base: "font-medium",
variants: {
color: {
primary: "text-blue-500",
},
disabled: {
true: "opacity-50",
},
},
compoundVariants: [
{
color: "primary",
disabled: true,
class: "bg-black",
},
],
defaultVariants: {
color: "primary",
disabled: true,
},
});

const appButton = tv({extend: themeButton});
const button = tv({extend: appButton});

expect(appButton()).toHaveClass("font-medium text-blue-500 opacity-50 bg-black");
expect(button()).toHaveClass("font-medium text-blue-500 opacity-50 bg-black");
});
});

describe("Tailwind Variants (TV) - Tailwind Merge", () => {
Expand Down
18 changes: 8 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const tv = (options, configProp) => {
extend = null,
slots: slotProps = {},
variants: variantsProps = {},
compoundVariants = [],
compoundVariants: compoundVariantsProps = [],
compoundSlots = [],
defaultVariants: defaultVariantsProps = {},
} = options;
Expand Down Expand Up @@ -109,6 +109,11 @@ export const tv = (options, configProp) => {
isEmptyObject(componentSlots) ? {base: options?.base} : componentSlots,
);

// merge compoundVariants with the "extended" compoundVariants
const compoundVariants = isEmptyObject(extend?.compoundVariants)
? compoundVariantsProps
: flatMergeArrays(extend?.compoundVariants, compoundVariantsProps);

const component = (props) => {
if (isEmptyObject(variants) && isEmptyObject(slotProps) && isExtendedSlotsEmpty) {
return cn(base, props?.class, props?.className)(config);
Expand Down Expand Up @@ -322,15 +327,8 @@ export const tv = (options, configProp) => {
return result;
};

const getCompoundVariantClassNames = (slotProps) => {
const cvValues = getCompoundVariantsValue(compoundVariants, slotProps);
const ecvValues = getCompoundVariantsValue(extend?.compoundVariants, slotProps);

return flatMergeArrays(ecvValues, cvValues);
};

const getCompoundVariantClassNamesBySlot = (slotProps) => {
const compoundClassNames = getCompoundVariantClassNames(slotProps);
const compoundClassNames = getCompoundVariantsValue(compoundVariants, slotProps);

if (!Array.isArray(compoundClassNames)) {
return compoundClassNames;
Expand Down Expand Up @@ -422,7 +420,7 @@ export const tv = (options, configProp) => {
return cn(
base,
getVariantClassNames(),
getCompoundVariantClassNames(),
getCompoundVariantsValue(compoundVariants),
props?.class,
props?.className,
)(config);
Expand Down

0 comments on commit 8ec5f34

Please sign in to comment.