最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - My react and tailwind app are applying the class but the style does not change - Stack Overflow

programmeradmin1浏览0评论

I have theme change functionality in my app using context. The theme (dark/light) class is being applied, but the colors don't change. I don't know if it's my tailwind config because when I try to type the "bg-primary" in the header, the autocomplete doesn't show the primary var, or it's the ThemeContext logic.

ThemeContext.tsx

    import React, { Dispatch, SetStateAction, ReactNode } from "react";

const getInitialTheme = () => {
    if (typeof window !== "undefined" && window.localStorage) {
        const storedPrefs = window.localStorage.getItem("color-theme") as
            | "light"
            | "dark"
            | null;
        if (storedPrefs) {
            return storedPrefs;
        }
    }
    return "light";
};

interface ThemeContextType {
    theme: "light" | "dark";
    setTheme: Dispatch<SetStateAction<"light" | "dark">>;
}

export const ThemeContext = React.createContext<ThemeContextType | undefined>(
    undefined,
);

export const ThemeProvider = ({ children }: { children: ReactNode }) => {
    const [theme, setTheme] = React.useState<"light" | "dark">(getInitialTheme);

    const rawSetTheme = (theme: "light" | "dark") => {
        const root = window.document.documentElement;
        const isDark = theme === "dark";

        root.classList.remove(isDark ? "light" : "dark");
        root.classList.add(theme);

        localStorage.setItem("color-theme", theme);
    };

    React.useEffect(() => {
        rawSetTheme(theme);
    }, [theme]);

    return (
        <ThemeContext.Provider value={{ theme, setTheme }}>
            {children}
        </ThemeContext.Provider>
    );
};

ThemeToggler.tsx

import { ReactElement } from "react";
import { useTheme } from "../../hooks/useTheme";
import { Sun, Moon } from "lucide-react";

function ThemeToggler(): ReactElement {
    const { theme, setTheme } = useTheme();

    function toggleTheme() {
        setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
    }
    return theme === "light" ? (
        <Moon onClick={toggleTheme} />
    ) : (
        <Sun onClick={toggleTheme} />
    );
}

export default ThemeToggler;

useTheme.tsx

import { useContext } from "react";
import { ThemeContext } from "../Contexts/ThemeContext";

export const useTheme = () => {
    const context = useContext(ThemeContext);
    if (!context) {
        throw new Error("useTheme deve ser usado dentro de um ThemeProvider");
    }
    return context;
};

Header.tsx

import { ReactElement } from "react";
import ThemeToggler from "../ui/ThemeToggler";

function Header(): ReactElement {
    return (
        <header
            className={
                "flex h-20 w-svw items-center justify-between px-4 text-xl"
            }
        >
            <div>
                <h1>CashierApp</h1>
            </div>
            <div>
                <nav>
                    <ul className="flex flex-row items-center gap-8">
                        <li>Home</li>
                        <li>Controle de caixa</li>
                        <li>Cadastros</li>
                    </ul>
                </nav>
            </div>
            <div>
                <ThemeToggler />
            </div>
        </header>
    );
}

export default Header;

tailwind.config.ts

/** @type {import('tailwindcss').Config} */
export default {
    content: ["./index.html", "./src/**/*.{html,js,jsx,ts,tsx}"],
    theme: {
        extend: {
            colors: {
                primary: "var(--color-bg-primary)",
                secondary: "var(--color-bg-secondary)",
                textPrimary: "var(--color-text-primary)",
                textSecondary: "var(--color-text-secondary)",
                textAccent: "var(--color-text-accent)",
            },
        },
    },
    plugins: [],
};

Edit: I'm using tailwindcss v4, and my css file has the following statements:

@import "tailwindcss";

@tailwind utilities;

I have theme change functionality in my app using context. The theme (dark/light) class is being applied, but the colors don't change. I don't know if it's my tailwind config because when I try to type the "bg-primary" in the header, the autocomplete doesn't show the primary var, or it's the ThemeContext logic.

ThemeContext.tsx

    import React, { Dispatch, SetStateAction, ReactNode } from "react";

const getInitialTheme = () => {
    if (typeof window !== "undefined" && window.localStorage) {
        const storedPrefs = window.localStorage.getItem("color-theme") as
            | "light"
            | "dark"
            | null;
        if (storedPrefs) {
            return storedPrefs;
        }
    }
    return "light";
};

interface ThemeContextType {
    theme: "light" | "dark";
    setTheme: Dispatch<SetStateAction<"light" | "dark">>;
}

export const ThemeContext = React.createContext<ThemeContextType | undefined>(
    undefined,
);

export const ThemeProvider = ({ children }: { children: ReactNode }) => {
    const [theme, setTheme] = React.useState<"light" | "dark">(getInitialTheme);

    const rawSetTheme = (theme: "light" | "dark") => {
        const root = window.document.documentElement;
        const isDark = theme === "dark";

        root.classList.remove(isDark ? "light" : "dark");
        root.classList.add(theme);

        localStorage.setItem("color-theme", theme);
    };

    React.useEffect(() => {
        rawSetTheme(theme);
    }, [theme]);

    return (
        <ThemeContext.Provider value={{ theme, setTheme }}>
            {children}
        </ThemeContext.Provider>
    );
};

ThemeToggler.tsx

import { ReactElement } from "react";
import { useTheme } from "../../hooks/useTheme";
import { Sun, Moon } from "lucide-react";

function ThemeToggler(): ReactElement {
    const { theme, setTheme } = useTheme();

    function toggleTheme() {
        setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
    }
    return theme === "light" ? (
        <Moon onClick={toggleTheme} />
    ) : (
        <Sun onClick={toggleTheme} />
    );
}

export default ThemeToggler;

useTheme.tsx

import { useContext } from "react";
import { ThemeContext } from "../Contexts/ThemeContext";

export const useTheme = () => {
    const context = useContext(ThemeContext);
    if (!context) {
        throw new Error("useTheme deve ser usado dentro de um ThemeProvider");
    }
    return context;
};

Header.tsx

import { ReactElement } from "react";
import ThemeToggler from "../ui/ThemeToggler";

function Header(): ReactElement {
    return (
        <header
            className={
                "flex h-20 w-svw items-center justify-between px-4 text-xl"
            }
        >
            <div>
                <h1>CashierApp</h1>
            </div>
            <div>
                <nav>
                    <ul className="flex flex-row items-center gap-8">
                        <li>Home</li>
                        <li>Controle de caixa</li>
                        <li>Cadastros</li>
                    </ul>
                </nav>
            </div>
            <div>
                <ThemeToggler />
            </div>
        </header>
    );
}

export default Header;

tailwind.config.ts

/** @type {import('tailwindcss').Config} */
export default {
    content: ["./index.html", "./src/**/*.{html,js,jsx,ts,tsx}"],
    theme: {
        extend: {
            colors: {
                primary: "var(--color-bg-primary)",
                secondary: "var(--color-bg-secondary)",
                textPrimary: "var(--color-text-primary)",
                textSecondary: "var(--color-text-secondary)",
                textAccent: "var(--color-text-accent)",
            },
        },
    },
    plugins: [],
};

Edit: I'm using tailwindcss v4, and my css file has the following statements:

@import "tailwindcss";

@tailwind utilities;

Share Improve this question edited Mar 15 at 10:59 Luckkks asked Mar 14 at 2:08 LuckkksLuckkks 231 silver badge7 bronze badges 12
  • What version of TailwindCSS are you using? v3 or v4? How did you implement Tailwind in the CSS? – rozsazoltan Commented Mar 14 at 11:46
  • How to use custom color themes in TailwindCSS v4 or How can I implement the darkmode in my project? or How to disable dark mode in TailwindCSS 4 – rozsazoltan Commented Mar 14 at 11:49
  • 1 I'll try the @theme directive, thank you – Luckkks Commented Mar 15 at 11:03
  • 1 I think the example in the first link is exactly the answer to your question. There, different values needed to be set for the light and dark themes: TailwindCSS v4 dark theme by class not working without dark tag -- TailwindCSS dark mode can't change <html> or add class="dark" -- If you have any further questions, feel free to ask them in the form of a New Question and provide a similarly detailed description to reproduce the issue. – rozsazoltan Commented Mar 15 at 16:17
  • 1 works perfectly, thank you for helping me – Luckkks Commented Mar 15 at 22:07
 |  Show 7 more comments

1 Answer 1

Reset to default 1

CSS-first configuration from TailwindCSS v4

Since you're using v4, you don't need the tailwind.config.js file; instead, you should use the CSS-first directives.

  • CSS-first configuration - TailwindCSS v4 Blog
  • Functions and directives - TailwindCSS v4 Docs
  • New configuration option in v4 - StackOverflow

In CSS-first, you can define custom styles using the @theme directive.

@import "tailwindcss";

@theme {
  --font-display: "Satoshi", "sans-serif";
  --breakpoint-3xl: 120rem;
  --color-avocado-100: oklch(0.99 0 0);
  --color-avocado-200: oklch(0.98 0.04 113.22);
  --color-avocado-300: oklch(0.94 0.11 115.03);
  --color-avocado-400: oklch(0.92 0.19 114.08);
  --color-avocado-500: oklch(0.84 0.18 117.33);
  --color-avocado-600: oklch(0.53 0.12 118.34);
  --ease-fluid: cubic-bezier(0.3, 0, 0, 1);
  --ease-snappy: cubic-bezier(0.2, 0, 0, 1);
  /* ... */
}
  • @theme directive - TailwindCSS v4 Docs

Theme variables are defined in namespaces and each namespace corresponds to one or more utility class or variant APIs.

  • Theme variable namespaces - TailwindCSS v4 Docs
  • Default theme variable reference - TailwindCSS v4 Docs

How to use legacy JavaScript based configuration

However, it is still possible to continue using the tailwind.config.js through the @config directive.

  • TailwindCSS v4 is backwards compatible with v3 - StackOverflow

Related:

  • What's changed in TailwindCSS v4?
发布评论

评论列表(0)

  1. 暂无评论