ladle icon indicating copy to clipboard operation
ladle copied to clipboard

Issue with latest tailwind (4.0.8) - styles disappear / not generated by tailwind

Open andrienko opened this issue 10 months ago • 9 comments

The issue

I am using tw4 in my vite project, with vite plugin. In the project itself it works as expected. In ladle it used to work before, but all of a sudden it stopped (still works in main app tho) after I updated my deps - tailwind just does not generate the styles needed by components, but generates ones used by ladle (added via .ladle/components.tsx.

There is nothing specific about ladle's config, it uses the same configs and roughly same styles as the main app.

Not sure if it is a ladle issue - or rather a tailwind issue, but as main app works and ladle doesn't - I suppose there is something specific either with ladle or how I am using it.

Workaround

Reverting tailwindcss and @tailwindcss/vite from 4.0.8 back to 4.0.6 and locking versions helps.

Reproduction

Was unable to start it in stackblitz (as tailwind apparently needs a native extensions, and they are forbidden in stackblitz)

Therefore I created a repo: https://github.com/andrienko/ladle-issue-reproduction

(it is a stripped down version of my setup, with all important stuff remaining, in case something is wrong with my setup)

Environment

Reproduces on windows 11 / macos ventura / arch 2025.02.01, and in latest chrome/firefox. Doubt the environment is relevant

andrienko avatar Feb 22 '25 15:02 andrienko

@tajo Same issue here. Can we please fix this asap? It's an important issue.

nourjandali avatar Mar 02 '25 00:03 nourjandali

Same

sporto avatar Mar 03 '25 02:03 sporto

Seeing this as well. Reverting to 4.0.6 did not resolve this for me.

g-sam7 avatar Mar 06 '25 23:03 g-sam7

Have the same problem. Can anyone help?

Walqer avatar Mar 20 '25 15:03 Walqer

I found a temporary solution. You need to create a css file inside .ladle and import tailwind

example @import 'tailwindcss' source(path to components);

don't forget to import index.css into ./ladle/components.tsx

UPD:

enough to specify in source (path of folders where your components are located) when importing tailwind

korpeev avatar Mar 23 '25 13:03 korpeev

@source "../../shared/ui/"; // path to ui components I added this to tailwind.css config file That solved the problem Detecting classes in source files

Walqer avatar Mar 26 '25 05:03 Walqer

Hi guys, thanks to your suggestion I found a solution that worked for me. I'm using:

  • tailwindcss: 4.1.6
  • @ladle/react: 5.0.3
  • daisyui: 5.0.35

I created a .ladle folder in the root project with 2 files:

  • components.tsx that just import the second file (import "./theme.css")
  • theme.css
@import "../src/index.css";
@source "../src/components/";

In my index.css there is another import to the real theme.css file where I configured daisyui with tailwind.

Hope it can helps someone

amoretti-dev avatar May 15 '25 06:05 amoretti-dev

Its something to deal with source parsing. Here is the best solution I found without locking versions. Basically, you want to specify sources for Ladle only

Split your src/index.css into two parts

src/index.css

@import "tailwindcss";
@import "@/theme.css";

src/theme.css (in my case I use shadcn)

@import "tw-animate-css";

@custom-variant dark (&:is(.dark *));

@theme inline {
    --radius-sm: calc(var(--radius) - 4px);
    --radius-md: calc(var(--radius) - 2px);
    --radius-lg: var(--radius);
    --radius-xl: calc(var(--radius) + 4px);
    --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-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);
    --color-sidebar: var(--sidebar);
    --color-sidebar-foreground: var(--sidebar-foreground);
    --color-sidebar-primary: var(--sidebar-primary);
    --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
    --color-sidebar-accent: var(--sidebar-accent);
    --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
    --color-sidebar-border: var(--sidebar-border);
    --color-sidebar-ring: var(--sidebar-ring);
}

:root {
    --radius: 0.625rem;
    --background: oklch(1 0 0);
    --foreground: oklch(0.145 0 0);
    --card: oklch(1 0 0);
    --card-foreground: oklch(0.145 0 0);
    --popover: oklch(1 0 0);
    --popover-foreground: oklch(0.145 0 0);
    --primary: oklch(0.205 0 0);
    --primary-foreground: oklch(0.985 0 0);
    --secondary: oklch(0.97 0 0);
    --secondary-foreground: oklch(0.205 0 0);
    --muted: oklch(0.97 0 0);
    --muted-foreground: oklch(0.556 0 0);
    --accent: oklch(0.97 0 0);
    --accent-foreground: oklch(0.205 0 0);
    --destructive: oklch(0.577 0.245 27.325);
    --border: oklch(0.922 0 0);
    --input: oklch(0.922 0 0);
    --ring: oklch(0.708 0 0);
    --chart-1: oklch(0.646 0.222 41.116);
    --chart-2: oklch(0.6 0.118 184.704);
    --chart-3: oklch(0.398 0.07 227.392);
    --chart-4: oklch(0.828 0.189 84.429);
    --chart-5: oklch(0.769 0.188 70.08);
    --sidebar: oklch(0.985 0 0);
    --sidebar-foreground: oklch(0.145 0 0);
    --sidebar-primary: oklch(0.205 0 0);
    --sidebar-primary-foreground: oklch(0.985 0 0);
    --sidebar-accent: oklch(0.97 0 0);
    --sidebar-accent-foreground: oklch(0.205 0 0);
    --sidebar-border: oklch(0.922 0 0);
    --sidebar-ring: oklch(0.708 0 0);
}

.dark {
    --background: oklch(0.145 0 0);
    --foreground: oklch(0.985 0 0);
    --card: oklch(0.205 0 0);
    --card-foreground: oklch(0.985 0 0);
    --popover: oklch(0.205 0 0);
    --popover-foreground: oklch(0.985 0 0);
    --primary: oklch(0.922 0 0);
    --primary-foreground: oklch(0.205 0 0);
    --secondary: oklch(0.269 0 0);
    --secondary-foreground: oklch(0.985 0 0);
    --muted: oklch(0.269 0 0);
    --muted-foreground: oklch(0.708 0 0);
    --accent: oklch(0.269 0 0);
    --accent-foreground: oklch(0.985 0 0);
    --destructive: oklch(0.704 0.191 22.216);
    --border: oklch(1 0 0 / 10%);
    --input: oklch(1 0 0 / 15%);
    --ring: oklch(0.556 0 0);
    --chart-1: oklch(0.488 0.243 264.376);
    --chart-2: oklch(0.696 0.17 162.48);
    --chart-3: oklch(0.769 0.188 70.08);
    --chart-4: oklch(0.627 0.265 303.9);
    --chart-5: oklch(0.645 0.246 16.439);
    --sidebar: oklch(0.205 0 0);
    --sidebar-foreground: oklch(0.985 0 0);
    --sidebar-primary: oklch(0.488 0.243 264.376);
    --sidebar-primary-foreground: oklch(0.985 0 0);
    --sidebar-accent: oklch(0.269 0 0);
    --sidebar-accent-foreground: oklch(0.985 0 0);
    --sidebar-border: oklch(1 0 0 / 10%);
    --sidebar-ring: oklch(0.556 0 0);
}

@layer base {
    * {
        @apply border-border outline-ring/50;
    }
    body {
        @apply bg-background text-foreground;
    }
}

Then, you need to set up .ladle in the next way:

.ladle/components.tsx

import "./ladle.css";
import "@/index.css";

.ladle/ladle.css

@import "tailwindcss" source("../src/");
@import "@/theme.css";

pelykh avatar Jun 24 '25 07:06 pelykh

Thanks @pelykh. That did it.

I tried a bunch of combinations and finally this is what worked thanks to your comment:

/* .ladle/styles.css */
@import "tailwindcss" source("../src/");
@import "../src/styles.css";

and then

// .ladle/components.tsx
import "./styles.css";

sankargorthi avatar Jul 15 '25 23:07 sankargorthi