Skip to content

Commit

Permalink
chore: extend prop added to variantKeys
Browse files Browse the repository at this point in the history
  • Loading branch information
jrgarciadev committed Jul 25, 2023
1 parent 4325314 commit e52f7dd
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 27 deletions.
21 changes: 13 additions & 8 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,10 @@ export type TVReturnProps<
B extends ClassValue,
EV extends TVVariants<ES>,
ES extends TVSlots,
// @ts-expect-error
E extends TVReturnType = undefined,
> = {
extend: E;
base: B;
slots: S;
variants: V;
Expand All @@ -197,13 +200,15 @@ export type TVReturnType<
C extends TVConfig<V, EV>,
EV extends TVVariants<ES>,
ES extends TVSlots,
// @ts-expect-error
E extends TVReturnType = undefined,
> = {
(props?: TVProps<V, S, C, EV, ES>): ES extends undefined
? S extends undefined
? string
: {[K in TVSlotsWithBase<S, B>]: (slotProps?: ClassProp) => string}
: {[K in TVSlotsWithBase<ES & S, B>]: (slotProps?: ClassProp) => string};
} & TVReturnProps<V, S, B, EV, ES>;
} & TVReturnProps<V, S, B, EV, ES, E>;

export type TV = {
<
Expand All @@ -229,7 +234,7 @@ export type TV = {
>(
options: {
/**
* Extend allows easily compose components.
* Extend allows for easy composition of components.
* @see https://www.tailwind-variants.org/docs/composing-components
*/
extend?: E;
Expand All @@ -238,22 +243,22 @@ export type TV = {
*/
base?: B;
/**
* Slots allows you to separate an component into multiple parts.
* Slots allow you to separate a component into multiple parts.
* @see https://www.tailwind-variants.org/docs/slots
*/
slots?: S;
/**
* Variants allows you to create multiple versions of the same component.
* Variants allow you to create multiple versions of the same component.
* @see https://www.tailwind-variants.org/docs/variants#adding-variants
*/
variants?: V;
/**
* Compound variants allow apply classes to multiple variants at once.
* Compound variants allow you to apply classes to multiple variants at once.
* @see https://www.tailwind-variants.org/docs/variants#compound-variants
*/
compoundVariants?: CV;
/**
* Compound slots allow apply classes to multiple slots at once.
* Compound slots allow you to apply classes to multiple slots at once.
*/
compoundSlots?: TVCompoundSlots<V, S, B>;
/**
Expand All @@ -263,11 +268,11 @@ export type TV = {
defaultVariants?: DV;
},
/**
* The config object to modify the default configuration.
* The config object allows you to modify the default configuration.
* @see https://www.tailwind-variants.org/docs/api-reference#config-optional
*/
config?: C,
): TVReturnType<V, S, B, C, EV, ES>;
): TVReturnType<V, S, B, C, EV, ES, E>;
};

// main function
Expand Down
28 changes: 16 additions & 12 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const joinObjects = (obj1, obj2) => {

export const tv = (options, configProp) => {
const {
extend = null,
slots: slotProps = {},
variants: variantsProps = {},
compoundVariants = [],
Expand All @@ -64,9 +65,15 @@ export const tv = (options, configProp) => {

const config = {...defaultConfig, ...configProp};

const base = cnBase(options?.extend?.base, options?.base);
const variants = mergeObjects(variantsProps, options?.extend?.variants);
const defaultVariants = {...options?.extend?.defaultVariants, ...defaultVariantsProps};
const base = extend?.base ? cnBase(extend.base, options?.base) : options?.base;
const variants =
extend?.variants && !isEmptyObject(extend.variants)
? mergeObjects(variantsProps, extend.variants)
: variantsProps;
const defaultVariants =
extend?.defaultVariants && !isEmptyObject(extend.defaultVariants)
? {...extend.defaultVariants, ...defaultVariantsProps}
: defaultVariantsProps;

// save twMergeConfig to the cache
if (!isEmptyObject(config.twMergeConfig) && !isEqual(config.twMergeConfig, cachedTwMergeConfig)) {
Expand All @@ -83,19 +90,15 @@ export const tv = (options, configProp) => {
: {};

// merge slots with the "extended" slots
const slots = isEmptyObject(options?.extend?.slots)
const slots = isEmptyObject(extend?.slots)
? componentSlots
: joinObjects(
options?.extend?.slots,
extend?.slots,
isEmptyObject(componentSlots) ? {base: options?.base} : componentSlots,
);

const component = (props) => {
if (
isEmptyObject(variants) &&
isEmptyObject(slotProps) &&
isEmptyObject(options?.extend?.slots)
) {
if (isEmptyObject(variants) && isEmptyObject(slotProps) && isEmptyObject(extend?.slots)) {
return cn(base, props?.class, props?.className)(config);
}

Expand Down Expand Up @@ -259,7 +262,7 @@ export const tv = (options, configProp) => {

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

return flatMergeArrays(ecvValues, cvValues);
};
Expand Down Expand Up @@ -323,7 +326,7 @@ export const tv = (options, configProp) => {
};

// with slots
if (!isEmptyObject(slotProps) || !isEmptyObject(options?.extend?.slots)) {
if (!isEmptyObject(slotProps) || !isEmptyObject(extend?.slots)) {
const compoundClassNames = getCompoundVariantClassNamesBySlot() ?? [];
const compoundSlotClassNames = getCompoundSlotClassNameBySlot() ?? [];

Expand Down Expand Up @@ -366,6 +369,7 @@ export const tv = (options, configProp) => {
};

component.variantKeys = getVariantKeys();
component.extend = extend;
component.base = base;
component.slots = slots;
component.variants = variants;
Expand Down
14 changes: 7 additions & 7 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ export const isEmptyObject = (obj) =>
export const isEqual = (obj1, obj2) => JSON.stringify(obj1) === JSON.stringify(obj2);

function flat(arr, target) {
arr.forEach(function (el) {
if (Array.isArray(el)) flat(el, target);
else target.push(el);
});
arr.forEach(function (el) {
if (Array.isArray(el)) flat(el, target);
else target.push(el);
});
}

export function flatArray(arr) {
const flattened = [];
const flattened = [];

flat(arr, flattened);
flat(arr, flattened);

return flattened;
return flattened;
}

export const flatMergeArrays = (...arrays) => flatArray(arrays).filter(Boolean);
Expand Down

0 comments on commit e52f7dd

Please sign in to comment.