Shadcn/ui upgrade to Tailwindcss v.4 #2996
Replies: 7 comments 2 replies
-
Jack recorded/noticed some problems migrating shadcn-ui to Tailwind v4 |
Beta Was this translation helpful? Give feedback.
-
It might be time to revisit this since tailwind just dropped a public beta. |
Beta Was this translation helpful? Give feedback.
-
shadcn/ui works with Tailwindcss v4. Here is an example TW4 globals.css file: @import "tailwindcss";
@variant dark (&:is(.dark *));
@plugin "tailwindcss-animate";
@theme {
--color-background: hsl(var(--background));
--color-foreground: hsl(var(--foreground));
--color-card: hsl(var(--card));
--color-card-foreground: hsl(var(--card-foreground));
--color-popover: hsl(var(--popover));
--color-popover-foreground: hsl(var(--popover-foreground));
--color-primary: hsl(var(--primary));
--color-primary-foreground: hsl(var(--primary-foreground));
--color-secondary: hsl(var(--secondary));
--color-secondary-foreground: hsl(var(--secondary-foreground));
--color-muted: hsl(var(--muted));
--color-muted-foreground: hsl(var(--muted-foreground));
--color-accent: hsl(var(--accent));
--color-accent-foreground: hsl(var(--accent-foreground));
--color-destructive: hsl(var(--destructive));
--color-destructive-foreground: hsl(var(--destructive-foreground));
--color-border: hsl(var(--border));
--color-input: hsl(var(--input));
--color-ring: hsl(var(--ring));
--color-chart-1: hsl(var(--chart-1));
--color-chart-2: hsl(var(--chart-2));
--color-chart-3: hsl(var(--chart-3));
--color-chart-4: hsl(var(--chart-4));
--color-chart-5: hsl(var(--chart-5));
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);
}
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--card: 0 0% 100%;
--card-foreground: 0 0% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 0 0% 3.9%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 96.1%;
--secondary-foreground: 0 0% 9%;
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--ring: 0 0% 3.9%;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
--radius: 0.5rem;
}
.dark {
--background: 0 0% 3.9%;
--foreground: 0 0% 98%;
--card: 0 0% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 0 0% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 0 0% 9%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--border-shadow: 255, 255, 255, 0.145;
--input: 0 0% 14.9%;
--ring: 0 0% 83.1%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
} I am not sure if this is the best way but I would love a very simple Nextjs, Tailwind and shadcn/ui setup on Next v15 and Tailwind v4. I have that working but it seems like there should be a "better way" - I wish shadcn would just fully adopt tailwind variables and not have special "shadcn" variables. Also not sure if this is the best dark mode approach - but it's how shadcn currently works. Cheers! |
Beta Was this translation helpful? Give feedback.
-
Here's one that's a little cleaner and shows various ways to define the colors: @import "tailwindcss";
@variant dark (&:where(.dark, .dark *));
@plugin "tailwindcss-animate";
@theme {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);
}
@layer base {
:root {
--background: var(--color-neutral-50);
--foreground: var(--color-neutral-900);
--card: hsl(0 0% 100%);
--card-foreground: hsl(0 0% 3.9%);
--popover: hsl(0 0% 100%);
--popover-foreground: hsl(0 0% 3.9%);
--primary: hsl(0 0% 9%);
--primary-foreground: hsl(0 0% 98%);
--secondary: hsl(0 0% 96.1%);
--secondary-foreground: hsl(0 0% 9%);
--muted: hsl(0 0% 96.1%);
--muted-foreground: hsl(0 0% 45.1%);
--accent: hsl(0 0% 96.1%);
--accent-foreground: hsl(0 0% 9%);
--destructive: hsl(0 84.2% 60.2%);
--destructive-foreground: hsl(0 0% 98%);
--border: hsl(0 0% 89.8%);
--input: hsl(0 0% 89.8%);
--ring: hsl(0 0% 3.9%);
--chart-1: hsl(12 76% 61%);
--chart-2: hsl(173 58% 39%);
--chart-3: hsl(197 37% 24%);
--chart-4: hsl(43 74% 66%);
--chart-5: hsl(27 87% 67%);
--radius: 0.5rem;
}
.dark {
--background: var(--color-neutral-950);
--foreground: var(--color-neutral-100);
--card: hsl(0, 0%, 3.9%);
--card-foreground: hsl(0 0% 98%);
--popover: hsl(0 0% 3.9%);
--popover-foreground: hsl(0 0% 98%);
--primary: hsl(0 0% 98%);
--primary-foreground: hsl(0 0% 9%);
--secondary: hsl(0 0% 14.9%);
--secondary-foreground: hsl(0 0% 98%);
--muted: hsl(0 0% 14.9%);
--muted-foreground: hsl(0 0% 63.9%);
--accent: hsl(0 0% 14.9%);
--accent-foreground: hsl(0 0% 98%);
--destructive: hsl(0 62.8% 30.6%);
--destructive-foreground: hsl(0 0% 98%);
--border: hsl(0 0% 14.9%);
--input: hsl(0 0% 14.9%);
--ring: hsl(0 0% 83.1%);
--chart-1: hsl(220 70% 50%);
--chart-2: hsl(160 60% 45%);
--chart-3: hsl(30 80% 55%);
--chart-4: hsl(280 65% 60%);
--chart-5: hsl(340 75% 55%);
}
} |
Beta Was this translation helpful? Give feedback.
-
@dstroot I don't think that shadcn/ui works with Tailwindcss v4, most of the shadcn components are not displayed correctly when migrating to v4, and I had to update each component one by one to make them how they was before migration. I rolled back to v3 until official support ... |
Beta Was this translation helpful? Give feedback.
-
Can likely bin the hsl abstraction now thanks to simplified variable colours. @import "tailwindcss";
@plugin "tailwindcss-animate";
@variant dark (&:where(.dark, .dark *));
@theme {
--color-background: var(--color-white);
--color-foreground: var(--color-slate-900);
--color-card: var(--color-white);
--color-card-foreground: var(--color-slate-900);
--color-popover: var(--color-white);
--color-popover-foreground: var(--color-slate-900);
--color-primary: var(--color-slate-900);
--color-primary-foreground: var(--color-slate-50);
--color-secondary: var(--color-slate-100);
--color-secondary-foreground: var(--color-slate-900);
--color-muted: var(--color-slate-100);
--color-muted-foreground: var(--color-slate-500);
--color-accent: var(--color-slate-100);
--color-accent-foreground: var(--color-slate-900);
--color-destructive: var(--color-rose-500);
--color-destructive-foreground: var(--color-slate-50);
--color-border: var(--color-slate-200);
--color-input: var(--color-slate-200);
--color-ring: var(--color-slate-400);
--radius: 0.5rem;
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);
}
@layer theme {
.dark {
--color-background: var(--color-zinc-950);
--color-foreground: var(--color-zinc-50);
--color-card: var(--color-zinc-950);
--color-card-foreground: var(--color-zinc-50);
--color-popover: var(--color-zinc-950);
--color-popover-foreground: var(--color-zinc-50);
--color-primary: var(--color-zinc-50);
--color-primary-foreground: var(--color-zinc-900);
--color-secondary: var(--color-zinc-800);
--color-secondary-foreground: var(--color-zinc-50);
--color-muted: var(--color-zinc-800);
--color-muted-foreground: var(--color-zinc-400);
--color-accent: var(--color-zinc-800);
--color-accent-foreground: var(--color-zinc-50);
--color-destructive: var(--color-rose-700);
--color-destructive-foreground: var(--color-zinc-50);
--color-border: var(--color-zinc-800);
--color-input: var(--color-zinc-800);
--color-ring: var(--color-zinc-300);
}
}
@layer base {
*,
::before,
::after {
border-color: var(--color-border);
}
} |
Beta Was this translation helpful? Give feedback.
-
I like the approach of @dstroot but dark mode wasn't working for me without using the https://play.tailwindcss.com/ErFtdWw2f5?file=css @import "tailwindcss";
@variant dark (&:where(.dark, .dark *));
@plugin "tailwindcss-animate";
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);
}
/* Default theme */
@layer base {
:root {
--background: var(--color-white);
--foreground: var(--color-slate-900);
--card: var(--color-white);
--card-foreground: var(--color-slate-900);
--popover: var(--color-white);
--popover-foreground: var(--color-slate-900);
--primary: var(--color-slate-900);
--primary-foreground: var(--color-slate-50);
--secondary: var(--color-slate-100);
--secondary-foreground: var(--color-slate-900);
--muted: var(--color-slate-100);
--muted-foreground: var(--color-slate-500);
--accent: var(--color-slate-100);
--accent-foreground: var(--color-slate-900);
--destructive: var(--color-rose-500);
--destructive-foreground: var(--color-slate-50);
--border: var(--color-slate-200);
--input: var(--color-slate-200);
--ring: var(--color-slate-400);
--chart-1: hsl(12 76% 61%);
--chart-2: hsl(173 58% 39%);
--chart-3: hsl(197 37% 24%);
--chart-4: hsl(43 74% 66%);
--chart-5: hsl(27 87% 67%);
--radius: 0.5rem;
}
.dark {
--background: var(--color-zinc-950);
--foreground: var(--color-zinc-50);
--card: var(--color-zinc-950);
--card-foreground: var(--color-zinc-50);
--popover: var(--color-zinc-950);
--popover-foreground: var(--color-zinc-50);
--primary: var(--color-zinc-50);
--primary-foreground: var(--color-zinc-900);
--secondary: var(--color-zinc-800);
--secondary-foreground: var(--color-zinc-50);
--muted: var(--color-zinc-800);
--muted-foreground: var(--color-zinc-400);
--accent: var(--color-zinc-800);
--accent-foreground: var(--color-zinc-50);
--destructive: var(--color-rose-700);
--destructive-foreground: var(--color-zinc-50);
--border: var(--color-zinc-800);
--input: var(--color-zinc-800);
--ring: var(--color-zinc-300);
--chart-1: hsl(220 70% 50%);
--chart-2: hsl(160 60% 45%);
--chart-3: hsl(30 80% 55%);
--chart-4: hsl(280 65% 60%);
--chart-5: hsl(340 75% 55%);
}
}
/* Theme variant */
@layer base {
[data-theme="example"] {
--background: var(--color-blue-50);
--foreground: var(--color-gray-900);
--card: var(--color-blue-100);
--card-foreground: var(--color-gray-800);
--popover: var(--color-blue-50);
--popover-foreground: var(--color-gray-800);
--primary: var(--color-blue-100);
--primary-foreground: var(--color-gray-900);
--secondary: var(--color-blue-400);
--secondary-foreground: var(--color-gray-800);
--muted: var(--color-emerald-100);
--muted-foreground: var(--color-gray-600);
--accent: var(--color-emerald-200);
--accent-foreground: var(--color-gray-800);
--destructive: var(--color-red-700);
--destructive-foreground: var(--color-gray-200);
--border: var(--color-blue-600);
--input: var(--color-blue-800);
--ring: var(--color-blue-100);
--radius: 0.3rem;
}
.dark [data-theme="example"],
.dark[data-theme="example"] {
--background: var(--color-gray-900);
--foreground: var(--color-gray-200);
--card: var(--color-gray-900);
--card-foreground: var(--color-gray-200);
--popover: var(--color-gray-950);
--popover-foreground: var(--color-gray-200);
--primary: var(--color-blue-500);
--primary-foreground: var(--color-blue-50);
--secondary: var(--color-blue-800);
--secondary-foreground: var(--color-blue-50);
--muted: var(--color-emerald-900);
--muted-foreground: var(--color-gray-500);
--accent: var(--color-emerald-900);
--accent-foreground: var(--color-gray-200);
--destructive: var(--color-red-700);
--destructive-foreground: var(--color-gray-200);
--border: var(--color-blue-800);
--input: var(--color-blue-800);
--ring:var(--color-blue-100);
--radius: 0.3rem;
}
} |
Beta Was this translation helpful? Give feedback.
-
When will shadcn ui upgrade to tailwind css v.4? daisyUI has already done so...
Beta Was this translation helpful? Give feedback.
All reactions