I am developing an Electron application using React and Vite, incorporating the @heroui/react library (a UI component set) for buttons. The buttons display the click animation (ripple effect) correctly, but the color styles (e.g., color="primary" or variant="solid") and hover effects are not being applied. A CSS file (index-BQqo9mII.css) is generated by Vite and located in the out/renderer/assets directory, but it seems it is either not loading or the styles are not being properly generated/applied.
- Environment: Electron with Electron-Vite, React, Tailwind CSS v4, and HeroUI.
- Symptoms:
- The click animation (ripple effect) works.
- Color and style properties of the buttons (e.g.,
bg-primary) are not applied. - Errors related to PostCSS configuration and Tailwind v4 incompatibility have been encountered.
Solutions Attempted
- Initial CSS Path Configuration:
- Configured the CSS file path in
index.html(located atsrc/renderer/index.html) with<link rel="stylesheet" href="./out/renderer/assets/index-BQqo9mII.css" />, but it was not found indevmode.
- Configured the CSS file path in
- Simplifying
index.html:- Removed the CSS link and relied on Vite to inject the styles, but the styles were still not applied.
- Configuring
vite.config.js:- Set
outDirtoout/rendererandassetsDirtoassets. - Added
ssr.noExternalfor@heroui/reactto resolve SSR errors. - Included React and PostCSS plugins with
tailwindcss.
- Set
- Resolving Tailwind v4 Errors:
- Replaced
@tailwind baseand@tailwind componentswith@import "tailwindcss/preflight"and removedcomponents.
- Replaced
- Updating Packages:
- Updated versions of
@heroui/react,tailwindcss,postcss, andautoprefixerto the latest releases.
- Updated versions of
- Installing and Configuring
@tailwindcss/postcss:- Installed the
@tailwindcss/postcsspackage and replacedtailwindcsswith it invite.config.js.
- Installed the
- Project Cleanup:
- Deleted
node_modulesandpackage-lock.jsonand rebuilt withnpm install.
- Deleted
- Manual Loading of HeroUI Styles:
- Added
@import "@heroui/react/dist/index.css"toindex.css.
- Added
Codes Used
File src/renderer/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PingPlus</title>
<!-- Vite automatically injects CSS here -->
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
</html>
File src/renderer/index.css
@import "tailwindcss/preflight";
@tailwind utilities;
/* Import HeroUI styles */
@import "@heroui/react/dist/index.css";
body {
background-color: lightgray;
}
File vite.config.js
const { defineConfig } = require("electron-vite");
const react = require("@vitejs/plugin-react");
const tailwindcssPostcss = require("@tailwindcss/postcss");
module.exports = defineConfig({
main: {
build: {
rollupOptions: {
input: "src/main/index.js",
},
},
},
preload: {
build: {
rollupOptions: {
input: "src/preload/index.js",
},
},
},
renderer: {
build: {
rollupOptions: {
input: "index.html",
},
outDir: "out/renderer",
assetsDir: "assets",
emptyOutDir: false,
minify: false,
},
resolve: {
alias: {
"@": "src",
},
},
plugins: [react()],
css: {
postcss: {
plugins: [tailwindcssPostcss],
},
},
server: {
open: true,
watch: {
usePolling: true,
},
},
ssr: {
noExternal: ["@heroui/react"],
},
},
});
File src/renderer/App.tsx
import React from "react";
import { Button } from "@heroui/react";
export default function App() {
return (
<div className="p-4">
<h1 className="text-2xl font-bold">Test HeroUI</h1>
<Button color="primary" variant="solid">
Primary Solid
</Button>
<Button color="danger" variant="solid" className="ml-2">
Danger Solid
</Button>
<Button color="warning" variant="light" className="ml-2">
Warning Light
</Button>
</div>
);
}
File src/renderer/TitleBar.tsx
import React from "react";
import { Button } from "@heroui/react";
export default function TitleBar() {
const handleMinimize = () => {
window.electronAPI.minimize();
};
const handleClose = () => {
window.electronAPI.close();
};
return (
<div
data-tauri-drag-region
className="h-10 bg-gray-900 flex items-center justify-between p-0 text-white shadow-md"
>
<span className="font-semibold pl-2">PingPlus</span>
<div className="flex gap-0">
<Button
size="sm"
color="warning"
variant="solid"
onClick={handleMinimize}
className="w-10 h-10"
>
-
</Button>
<Button
size="sm"
color="danger"
variant="solid"
onClick={handleClose}
className="w-10 h-10"
>
X
</Button>
</div>
</div>
);
}
File src/renderer/main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";
import { HeroUIProvider } from "@heroui/react";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<HeroUIProvider>
<App />
</HeroUIProvider>
</React.StrictMode>
);
File tailwind.config.js
const { heroui } = require("@heroui/react");
module.exports = {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
"./node_modules/@heroui/theme/dist/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
darkMode: "class",
plugins: [heroui()],
};
Commands Executed
npm install @heroui/react@latest tailwindcss@latest postcss@latest autoprefixer@latestnpm install @tailwindcss/postcssnpm cache clean --forceRemove-Item -Recurse -Force node_modulesRemove-Item -Force package-lock.jsonnpm installnpm run dev:electron