Currently some component have fixed variant. For example: const badgeVariants = cva(, const buttonVariants = cva( so I find some solution to add dynamic variant with minimum cost to modify ShadCN UI code.
I don't know if this is a good idea before proceeding to modify the code and create a pull request.
This solution need update any component in /components/ui that used = cva(. So the end-user (developer) cant override variant by update ONLY 1 file custom-vars.ts. It need shadcn tool (npx shadcn@latest) create/update (question) /components/ui/custom-vars.ts if file not exits.
This is example for update component button
Add merge variant function / customVars
For example customVars.button is override button variants. I use chat GPT, so maybe _deepMerge fn work not correctly.
// /src/components/ui/custom-vars.ts
type GetObjDifferentKeys<
T,
U,
T0 = Omit<T, keyof U> & Omit<U, keyof T>,
T1 = {
[K in keyof T0]: T0[K];
},
> = T1;
type GetObjSameKeys<T, U> = Omit<T | U, keyof GetObjDifferentKeys<T, U>>;
type MergeTwoObjects<
T,
U,
T0 = GetObjDifferentKeys<T, U> & { [K in keyof GetObjSameKeys<T, U>]: DeepMergeTwoTypes<T[K], U[K]> },
T1 = { [K in keyof T0]: T0[K] },
> = T1;
export type DeepMergeTwoTypes<T, U> = [T, U] extends [{ [key: string]: unknown }, { [key: string]: unknown }]
? MergeTwoObjects<NonNullable<T>, NonNullable<U>>
: NonNullable<T> | NonNullable<U>;
function _deepMerge<T extends object, U extends object>(target: T, source: U): DeepMergeTwoTypes<T, U> {
for (const key of Object.keys(source) as Array<keyof U>) {
if (source[key] instanceof Object && key in target) {
(target as any)[key] = _deepMerge((target as any)[key], source[key] as any);
} else {
(target as any)[key] = source[key];
}
}
return target as any;
}
export function mergeVariants<T, U>(baseConfig: T, customConfig: U): DeepMergeTwoTypes<T, U> {
return _deepMerge(baseConfig as any, customConfig as any) as any;
}
export const customVars = {
button: {
variants: {
variant: {
success: 'bg-success text-white hover:bg-success/80',
},
},
},
};
Feature description
Problem
Currently some component have fixed variant. For example:
const badgeVariants = cva(
,const buttonVariants = cva(
so I find some solution to add dynamic variant withminimum cost
to modify ShadCN UI code.I don't know if this is a good idea before proceeding to modify the code and create a pull request.
This solution need update any component in
/components/ui
that used= cva(
. So the end-user (developer) cant override variant by update ONLY 1 filecustom-vars.ts
. It needshadcn tool (npx shadcn@latest)
create/update (question)/components/ui/custom-vars.ts
if file not exits.This is example for update component button
Add merge variant function / customVars
For example
customVars.button
is overridebutton
variants. I use chat GPT, so maybe_deepMerge
fn work not correctly.Modify button.tsx
Usage button
Expected: Code should not throw error for
variant='success'
Update CSS
Update tailwind.config.js
Affected component/components
Alert, Badge, Button, Label, Sheet, Toast, Toggle
Additional Context
Additional details here...
Before submitting