Skip to content

Conversation

@SutuSebastian
Copy link
Collaborator

@SutuSebastian SutuSebastian commented Dec 7, 2025

Use CSS variables for tailwindcss@v4 instead of inline colors.

Changes

  • automatically generate tailwindcss@v4 config file
  • use css variables for the v4 config

Breaking changes

Only applicable to tailwindcss@v4:

before
@plugin "flowbite-react/plugins/tailwindcss" - this points to the legacy JS plugin (that uses inline colors)

after
@import "flowbite-react/plugins/tailwindcss" - this points to the CSS-based plugin (that uses CSS variables)

The breaking change is self-managed once upgrading flowbite-react and starting/building the app, which runs the flowbite-react dev or respectively flowbite-react build command that triggers the patch/fix/migration automatically.

Summary by CodeRabbit

  • New Features

    • Added Tailwind CSS v4 support using CSS variables for colors and styling.
    • Introduced automated conversion to a CSS-based Tailwind plugin during build/dev so upgrades apply migration steps automatically.
  • Breaking Changes

    • Tailwind v4 configuration now uses an import-based CSS plugin instead of the legacy plugin directive; configuration is migrated during upgrade/build.

✏️ Tip: You can customize this high-level summary in your review settings.

- Introduced `colorsAsVariables` and `colorsAsVariablesRef` to manage color variables and references
- Updated the Tailwind CSS plugin to add color variables to the `:root`
@SutuSebastian SutuSebastian requested a review from rluders December 7, 2025 08:11
@SutuSebastian SutuSebastian self-assigned this Dec 7, 2025
@SutuSebastian SutuSebastian added the 🐛 bug Something isn't working label Dec 7, 2025
@changeset-bot
Copy link

changeset-bot bot commented Dec 7, 2025

🦋 Changeset detected

Latest commit: 4aae918

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
flowbite-react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Dec 7, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
flowbite-react Ready Ready Preview Comment Dec 8, 2025 1:27pm
flowbite-react-storybook Ready Ready Preview Comment Dec 8, 2025 1:27pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 7, 2025

Walkthrough

Adds an automated CSS-based Tailwind v4 plugin generation and migration: generates a CSS file with theme CSS variables, updates build (Rollup) to produce and copy that file, updates package exports/scripts, and migrates CLI setup to replace legacy @plugin directives with @import where needed.

Changes

Cohort / File(s) Summary
Changelog & ignore
\.changeset/free-turkeys-lick.md, packages/ui/.gitignore
New changelog entry; added src/plugin/tailwindcss/index.css to .gitignore.
Package exports & scripts
packages/ui/package.json
Added export "style": "./dist/plugin/tailwindcss/index.css" for ./plugin/tailwindcss; added generate-tailwind-plugin-css-file script; updated prepare script to run CSS generator.
Build integration (Rollup)
packages/ui/rollup.config.js
Excluded plugin CSS from source entries; added hooks generateTailwindPluginCssFile (buildStart) and copyTailwindPluginCssFile (buildEnd) to invoke generation and copy output during build.
CSS generation script
packages/ui/scripts/generate-tailwind-plugin-css-file.ts
New script that builds CSS emitting :root variables, @theme color mappings, background-image and shadow sections from theme data and writes/formats src/plugin/tailwindcss/index.css.
CLI — build/dev integration
packages/ui/src/cli/commands/build.ts, packages/ui/src/cli/commands/dev.ts
Call setupTailwind() during dev and build initialization flow.
CLI — migration logic
packages/ui/src/cli/commands/setup-tailwind.ts
Added detection for legacy @plugin directive and migration to @import; handles presence/absence of both old and new directives and removes legacy lines when migrating.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as CLI (build/dev)
    participant Setup as setupTailwind
    participant Gen as CSS Generator (script)
    participant Rollup as Rollup Build
    participant FS as File system / dist

    User->>CLI: run build/dev
    CLI->>Setup: await setupTailwind()
    Setup->>Setup: detect legacy `@plugin` or existing `@import`
    alt legacy `@plugin` found
        Setup->>Setup: remove `@plugin` line and add `@import`
    end
    CLI->>Rollup: start build lifecycle
    Rollup->>Gen: buildStart -> invoke generator script
    Gen->>FS: write `src/plugin/tailwindcss/index.css`
    Rollup->>FS: buildEnd -> copy CSS to `dist/plugin/tailwindcss/index.css`
    Rollup->>User: build complete
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Attention areas:
    • packages/ui/scripts/generate-tailwind-plugin-css-file.ts: verify mapping of theme data to CSS variables and formatter integration.
    • packages/ui/rollup.config.js: confirm hook placement and handling of the CSS file in entry discovery and outputs.
    • packages/ui/src/cli/commands/setup-tailwind.ts: validate regex/migration logic to avoid accidental edits to consumer configs.
    • packages/ui/package.json: ensure export path and prepare script ordering are correct.

Possibly related issues

Possibly related PRs

Suggested reviewers

  • rluders
  • connerdavis47

Poem

🐇 I stitched the vars where colors hide,

root sprouts hues for Tailwind v4 with pride,
Old @plugin hops away at dawn,
@import now leads the meadow on,
Build hums, CSS blooms — hop, celebrate! 🎨✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: migrating from inline colors to CSS variables for Tailwind CSS v4 support, which aligns with the primary objective of the PR.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 1582-some-tailwind-4-color-variables-are-undefined-when-used-with-reactflowbite

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/ui/src/plugin/tailwindcss/colors.ts (1)

154-165: Simplify type assertions and remove ineffective as const.

The population loop has two type safety concerns:

  1. Line 159: The double cast as unknown as ShadeName<typeof name> bypasses type checking. While technically functional, it's a code smell that suggests the type inference could be improved.

  2. Line 160: The as const assertion on the template literal has no effect here since the value is immediately assigned to an index signature of type string. The assertion doesn't narrow the type.

Consider simplifying:

 for (const key in colors) {
   const name = key as ColorName;
   const color = colors[name];
   colorsAsVariablesRef[name] = {} as ColorsAsVariablesRef[typeof name];
   for (const key in color) {
-    const shade = key as unknown as ShadeName<typeof name>;
-    colorsAsVariables[`--color-${name}-${shade}` as const] = color[shade];
+    const shade = key as ShadeName<typeof name>;
+    colorsAsVariables[`--color-${name}-${shade}`] = color[shade];
     colorsAsVariablesRef[name][shade] =
       // add fallback to display Tailwind CSS intellisense color in IDE
       `var(--color-${name}-${shade}, ${color[shade]})`;
   }
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7b2e0e8 and 93d7bf0.

📒 Files selected for processing (3)
  • packages/ui/src/plugin/tailwindcss/colors.ts (1 hunks)
  • packages/ui/src/plugin/tailwindcss/index.ts (1 hunks)
  • packages/ui/src/plugin/tailwindcss/theme.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
packages/ui/src/plugin/tailwindcss/theme.ts (1)
packages/ui/src/plugin/tailwindcss/colors.ts (1)
  • colorsAsVariablesRef (152-152)
packages/ui/src/plugin/tailwindcss/index.ts (1)
packages/ui/src/plugin/tailwindcss/colors.ts (1)
  • colorsAsVariables (151-151)
🪛 GitHub Actions: CI
packages/ui/src/plugin/tailwindcss/theme.ts

[error] 1-1: flowbite-react format:check failed. Bun command exited with code 1.

packages/ui/src/plugin/tailwindcss/index.ts

[error] 1-1: flowbite-react format:check failed. Bun command exited with code 1.

packages/ui/src/plugin/tailwindcss/colors.ts

[error] 1-1: flowbite-react format:check failed. Bun command exited with code 1.

🔇 Additional comments (2)
packages/ui/src/plugin/tailwindcss/colors.ts (1)

144-149: LGTM! Well-structured type definitions.

The type definitions correctly model the color structure and will provide excellent IDE autocomplete support for color variable names.

packages/ui/src/plugin/tailwindcss/theme.ts (1)

2-2: LGTM! Correct integration with CSS variable system.

The switch from colors to colorsAsVariablesRef correctly integrates the new CSS variable approach. This allows Tailwind utilities to reference CSS variables while maintaining IDE color preview via fallback values.

Also applies to: 22-22

@SutuSebastian SutuSebastian marked this pull request as draft December 7, 2025 08:17
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 93d7bf0 and 6a38334.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • .changeset/free-turkeys-lick.md (1 hunks)
  • packages/ui/.gitignore (1 hunks)
  • packages/ui/package.json (2 hunks)
  • packages/ui/rollup.config.js (3 hunks)
  • packages/ui/scripts/generate-tailwind-plugin-css-file.ts (1 hunks)
  • packages/ui/src/cli/commands/build.ts (1 hunks)
  • packages/ui/src/cli/commands/dev.ts (1 hunks)
  • packages/ui/src/cli/commands/setup-tailwind.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/ui/.gitignore
🧰 Additional context used
🧬 Code graph analysis (3)
packages/ui/scripts/generate-tailwind-plugin-css-file.ts (2)
packages/ui/src/plugin/tailwindcss/colors.ts (1)
  • colors (139-142)
packages/ui/src/plugin/tailwindcss/theme.ts (2)
  • backgroundImage (4-13)
  • boxShadow (15-17)
packages/ui/rollup.config.js (1)
packages/ui/src/cli/consts.ts (1)
  • outputDir (7-7)
packages/ui/src/cli/commands/dev.ts (4)
packages/ui/src/cli/commands/setup-output-directory.ts (1)
  • setupOutputDirectory (9-16)
packages/ui/src/cli/utils/get-config.ts (1)
  • getConfig (14-16)
packages/ui/src/cli/commands/setup-init.ts (1)
  • setupInit (14-72)
packages/ui/src/cli/commands/setup-tailwind.ts (1)
  • setupTailwind (15-25)
🪛 ast-grep (0.40.0)
packages/ui/src/cli/commands/setup-tailwind.ts

[warning] 79-81: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(
@import\\s+['"](${pluginDirectivePath.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})['"](;|\\s|$),
)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)


[warning] 82-84: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(
@source\\s+['"](${sourceDirectivePath.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})['"](;|\\s|$),
)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🪛 LanguageTool
.changeset/free-turkeys-lick.md

[grammar] ~20-~20: Use a hyphen to join words.
Context: ...s/tailwindcss"` - this points to the CSS based plugin (that uses CSS variables) ...

(QB_NEW_EN_HYPHEN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: 🧰 Build
🔇 Additional comments (14)
packages/ui/src/cli/commands/dev.ts (2)

24-24: LGTM!

The import follows the established pattern and correctly imports setupTailwind from the sibling module.


30-30: LGTM!

The setupTailwind() invocation is correctly placed after configuration initialization and follows the same pattern as the build workflow.

packages/ui/src/cli/commands/build.ts (1)

10-10: LGTM!

The Tailwind setup integration mirrors the dev workflow exactly, ensuring consistent behavior across build and dev commands.

Also applies to: 18-18

packages/ui/src/cli/commands/setup-tailwind.ts (3)

77-85: LGTM! Static analysis warning is a false positive.

The regular expressions are constructed safely with proper escaping of special characters using .replace(/[.*+?^${}()|[\]\\]/g, "\\$&"). The patterns are simple and do not contain nested quantifiers or structures that could lead to catastrophic backtracking. The static analysis tool lacks context about the escaping mechanism.


87-101: LGTM! Migration logic is sound.

The code correctly:

  1. Detects the legacy @plugin directive using the OLD regex
  2. Removes the old directive line from the file
  3. Logs the migration action for user awareness

This prepares the file for the new @import directive to be added subsequently (lines 104-107), completing the migration from Tailwind v3 JS plugin to v4 CSS plugin.


103-111: LGTM! Correctly implements the new CSS-based plugin directive.

The code now uses @import instead of the legacy @plugin syntax, aligning with Tailwind CSS v4's CSS-based plugin system. The migration is seamless, preserving the quote style and adding the source directive as needed.

packages/ui/rollup.config.js (3)

7-10: LGTM! Correctly excludes the CSS file from JavaScript compilation.

The Tailwind plugin CSS file is properly excluded from Rollup's entry discovery, preventing it from being processed as a JavaScript module while still allowing it to be copied to the output directory.


58-58: LGTM! Plugins are correctly ordered in the build lifecycle.

The generation plugin runs at buildStart (before compilation) and the copy plugin runs at buildEnd (after compilation), ensuring the CSS file is ready before build starts and properly copied to the output directory after the build completes.

Also applies to: 63-63


97-113: LGTM! Plugin implementations follow Rollup conventions.

Both plugins are implemented correctly:

  • generateTailwindPluginCssFile delegates to a dedicated script via Bun
  • copyTailwindPluginCssFile efficiently copies the generated CSS file to the output directory

The separation of concerns (generation logic in script, copy logic in plugin) keeps the build configuration clean.

packages/ui/scripts/generate-tailwind-plugin-css-file.ts (3)

5-20: LGTM! Two-tier CSS variable system enables flexible theming.

The script generates base color variables (e.g., --blue-500) in :root and then creates theme-prefixed variables (e.g., --color-blue-500) that reference the base variables. This design allows users to customize colors by overriding the base variables without affecting the Tailwind theme structure.


22-46: LGTM! CSS template follows Tailwind CSS v4 conventions.

The generated CSS properly uses:

  • :root for base CSS variables (customizable by users)
  • @theme inline for color definitions (Tailwind v4 syntax for inlined theme colors)
  • @theme blocks for background images and shadows (standard theme tokens)

Based on library documentation, this structure aligns with Tailwind v4's CSS-first configuration approach.


48-60: LGTM! File writing includes formatting and proper error handling.

The script uses Prettier to format the generated CSS, ensuring consistent output formatting, and includes appropriate error handling with clear logging for both success and failure cases.

packages/ui/package.json (2)

153-154: LGTM! Style export enables CSS discovery by bundlers.

The "style" field in the package exports allows bundlers and build tools to automatically discover and import the Tailwind plugin CSS file, enabling the CSS-based plugin approach for Tailwind CSS v4.


256-256: LGTM! Scripts properly integrated into the build lifecycle.

The new CSS generation script is added and integrated into the prepare script, ensuring the Tailwind plugin CSS file is generated before package distribution. The sequential execution with && ensures both metadata and CSS generation complete successfully.

Also applies to: 260-260

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
.changeset/free-turkeys-lick.md (1)

17-17: Consider parallel phrasing for consistency with the "after" example.

Line 20 uses "CSS-based plugin" to describe the technology stack; for parallelism, consider using "JS-based plugin" on line 17 instead of "JS plugin" to maintain a consistent pattern across both examples.

Apply this diff for consistency:

-`@plugin "flowbite-react/plugins/tailwindcss"` - this points to the legacy JS plugin (that uses inline colors)
+`@plugin "flowbite-react/plugins/tailwindcss"` - this points to the legacy JS-based plugin (that uses inline colors)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a38334 and 4aae918.

📒 Files selected for processing (1)
  • .changeset/free-turkeys-lick.md (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: 🧰 Build

@SutuSebastian SutuSebastian merged commit 2024216 into main Dec 8, 2025
8 checks passed
@SutuSebastian SutuSebastian deleted the 1582-some-tailwind-4-color-variables-are-undefined-when-used-with-reactflowbite branch December 8, 2025 13:31
@github-actions github-actions bot mentioned this pull request Dec 8, 2025
2 tasks
@rickross
Copy link

rickross commented Dec 8, 2025

Thanks, Sebastian!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐛 bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Some Tailwind 4 color variables are undefined when used with ReactFlowbite

3 participants