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

reactjs - Daisy ui dynamic(come from api) theme color not working - Stack Overflow

programmeradmin2浏览0评论

i have a project which is build by nextjs, tailwindcss + daisyui now I want to make the theme color dynamic like my theme colors is come from the API. but its not working I do some configure in my tailwind CSS config then only background color and text color is working others like opacity bg-primary/10 btn-primary badge-primary etc not working.

my tailwind.config.js file code

module.exports = {
  content: [
    "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      colors: {
        primary: "var(--primary-color)",
        secondary: "var(--secondary-color)",
        accent: "var(--accent-color)",
        success: "var(--success-color)",
        error: "var(--error-color)",
        light: "var(--light-color)",
        base100: "var(--base-100)",
      },
    },
  },
  plugins: [require("@tailwindcss/typography"), require("daisyui")],
};

my nextjs layout.js without imports


// Fetch site data
async function fetchSiteInfo(storeUserName) {
  if (!storeUserName) return {};
  const response = await apiClient.get(
    `${API_ROUTES.getSiteInfo}?storeUserName=${storeUserName}`,
    { ssr: true, session: null }
  );

  return response?.data || {};
}

export async function generateMetadata() {
  const cookiesInstance = await cookies();
  const storeUserName = cookiesInstance.get("store")?.value;
  const { setting } = await fetchSiteInfo(storeUserName);

  return {
    title: setting?.applicationName || "E-com Management",
    description: setting?.metaDescription || "Information not available",
    icons: {
      icon: setting?.favicon
        ? `${process.env.NEXT_PUBLIC_STORAGE_BASE_URL}${setting?.favicon}`
        : "/path-to-default-favicon.ico", // Default favicon path
    },
  };
}

// RootLayout Component
export default async function RootLayout({ children }) {
  const cookiesInstance = await cookies();
  const storeUserName = cookiesInstance.get("store")?.value;
  // Fetch data and session info
  const session = await auth();
  const locale = (await getLocale()) || "en";
  const messages = (await getMessages()) || {};
  const { setting } = await fetchSiteInfo(storeUserName);

  // Define theme with fallback values
  const theme = {
    primaryColor: setting?.primaryColor || "#f04d7e",
    secondaryColor: setting?.secondaryColor || "#ef4444",
    accentColor: setting?.accentColor || "#10b981",
    successColor: setting?.successColor || "#22c55e",
    errorColor: setting?.errorColor || "#f87171",
    lightColor: setting?.lightColor || "#f3f4f6",
    loadingColor: setting?.loadingColor || "#f3f4f6",
    backgroundColor: setting?.backgroundColor || "#ffffff",
  };

  return (
    <html lang={locale}>
      <head>
        <meta
          name="description"
          content={setting?.metaTitle || "Information not available"}
        />
        <meta
          name="description"
          content={setting?.metaDescription || "Information not available"}
        />
        <meta
          name="keywords"
          content={setting?.keywords || "e-commerce, online store, shop"}
        />
        <meta name="robots" content="index, follow" />
        <style>
          {`:root {
            --primary-color: ${theme.primaryColor};
            --secondary-color: ${theme.secondaryColor};
            --accent-color: ${theme.accentColor};
            --success-color: ${theme.successColor};
            --error-color: ${theme.errorColor};
            --light-color: ${theme.lightColor};
            --base-100: ${theme.backgroundColor};
            --loading-color: ${theme.loadingColor};
          }`}
        </style>
      </head>
      <body
        className={cn(
          geistSans.variable,
          geistMono.variable,
          "antialiased",
          "bg-base-100"
        )}
      >
      <main className="bg-[#EBF0F4] pb-10 px-3 lg:px-0">
      {children}
     </main>
      </body>
    </html>
  );
}

i have a project which is build by nextjs, tailwindcss + daisyui now I want to make the theme color dynamic like my theme colors is come from the API. but its not working I do some configure in my tailwind CSS config then only background color and text color is working others like opacity bg-primary/10 btn-primary badge-primary etc not working.

my tailwind.config.js file code

module.exports = {
  content: [
    "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      colors: {
        primary: "var(--primary-color)",
        secondary: "var(--secondary-color)",
        accent: "var(--accent-color)",
        success: "var(--success-color)",
        error: "var(--error-color)",
        light: "var(--light-color)",
        base100: "var(--base-100)",
      },
    },
  },
  plugins: [require("@tailwindcss/typography"), require("daisyui")],
};

my nextjs layout.js without imports


// Fetch site data
async function fetchSiteInfo(storeUserName) {
  if (!storeUserName) return {};
  const response = await apiClient.get(
    `${API_ROUTES.getSiteInfo}?storeUserName=${storeUserName}`,
    { ssr: true, session: null }
  );

  return response?.data || {};
}

export async function generateMetadata() {
  const cookiesInstance = await cookies();
  const storeUserName = cookiesInstance.get("store")?.value;
  const { setting } = await fetchSiteInfo(storeUserName);

  return {
    title: setting?.applicationName || "E-com Management",
    description: setting?.metaDescription || "Information not available",
    icons: {
      icon: setting?.favicon
        ? `${process.env.NEXT_PUBLIC_STORAGE_BASE_URL}${setting?.favicon}`
        : "/path-to-default-favicon.ico", // Default favicon path
    },
  };
}

// RootLayout Component
export default async function RootLayout({ children }) {
  const cookiesInstance = await cookies();
  const storeUserName = cookiesInstance.get("store")?.value;
  // Fetch data and session info
  const session = await auth();
  const locale = (await getLocale()) || "en";
  const messages = (await getMessages()) || {};
  const { setting } = await fetchSiteInfo(storeUserName);

  // Define theme with fallback values
  const theme = {
    primaryColor: setting?.primaryColor || "#f04d7e",
    secondaryColor: setting?.secondaryColor || "#ef4444",
    accentColor: setting?.accentColor || "#10b981",
    successColor: setting?.successColor || "#22c55e",
    errorColor: setting?.errorColor || "#f87171",
    lightColor: setting?.lightColor || "#f3f4f6",
    loadingColor: setting?.loadingColor || "#f3f4f6",
    backgroundColor: setting?.backgroundColor || "#ffffff",
  };

  return (
    <html lang={locale}>
      <head>
        <meta
          name="description"
          content={setting?.metaTitle || "Information not available"}
        />
        <meta
          name="description"
          content={setting?.metaDescription || "Information not available"}
        />
        <meta
          name="keywords"
          content={setting?.keywords || "e-commerce, online store, shop"}
        />
        <meta name="robots" content="index, follow" />
        <style>
          {`:root {
            --primary-color: ${theme.primaryColor};
            --secondary-color: ${theme.secondaryColor};
            --accent-color: ${theme.accentColor};
            --success-color: ${theme.successColor};
            --error-color: ${theme.errorColor};
            --light-color: ${theme.lightColor};
            --base-100: ${theme.backgroundColor};
            --loading-color: ${theme.loadingColor};
          }`}
        </style>
      </head>
      <body
        className={cn(
          geistSans.variable,
          geistMono.variable,
          "antialiased",
          "bg-base-100"
        )}
      >
      <main className="bg-[#EBF0F4] pb-10 px-3 lg:px-0">
      {children}
     </main>
      </body>
    </html>
  );
}

Share Improve this question asked Mar 19 at 9:23 Md Rasel MahmudMd Rasel Mahmud 391 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 0

TailwindCSS v3

Problem reproduction:

tailwind.config = {
  theme: {
    extend: {
      colors: {
        primary: "var(--primary-color)",
        secondary: "var(--secondary-color)",
        // ...
      },
    },
  },
};
:root {
  --primary-color: #000;
  --secondary-color: #1F85DE;
}
<script src="https://cdn.tailwindcss"></script>

<div class="flex">
  <div class="w-16 h-16 bg-primary"></div>
  <div class="w-16 h-16 bg-primary/50">Why?</div>

  <div class="w-16 h-16 bg-secondary"></div>
  <div class="w-16 h-16 bg-secondary/50">Why?</div>
</div>

This is due to your color declaration. You specify the colors in HEX, but TailwindCSS requires them in HSL or RGB format.

rgb(var(--rgb-color-variable) / <alpha-value>)
  • Customizing Colors: Using CSS variables - TailwindCSS v3 Docs

To generate an HSL or RGB color from a HEX value, you need to use the CSS color-mix() function.

  • color-mix() function - MDN Docs
color-mix(in srgb, var(--hex-color-variable) calc(100% * <alpha-value>), transparent)
module.exports = {
  content: [
    "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      colors: {
        primary: "color-mix(in srgb, var(--primary-color) calc(100% * <alpha-value>), transparent)",
        secondary: "color-mix(in srgb, var(--secondary-color) calc(100% * <alpha-value>), transparent)",
        accent: "color-mix(in srgb, var(--accent-color) calc(100% * <alpha-value>), transparent)",
        success: "color-mix(in srgb, var(--success-color) calc(100% * <alpha-value>), transparent)",
        error: "color-mix(in srgb, var(--error-color) calc(100% * <alpha-value>), transparent)",
        light: "color-mix(in srgb, var(--light-color) calc(100% * <alpha-value>), transparent)",
        base100: "color-mix(in srgb, var(--base-100) calc(100% * <alpha-value>), transparent)",
      },
    },
  },
  plugins: [require("@tailwindcss/typography"), require("daisyui")],
};

Wongjn is a master of the TailwindCSS; see more from TailwindCSS's color declaration:

  • Opacity Issues with Dynamic Colors in TailwindCSS - StackOverflow

Successfully working code snippets:

tailwind.config = {
  theme: {
    extend: {
      colors: {
        primary: "color-mix(in srgb, var(--primary-color) calc(100% * <alpha-value>), transparent)",
        secondary: "color-mix(in srgb, var(--secondary-color) calc(100% * <alpha-value>), transparent)",
        // ...
      },
    },
  },
};
:root {
  --primary-color: #000;
  --secondary-color: #1F85DE;
}
<script src="https://cdn.tailwindcss"></script>

<div class="flex">
  <div class="w-16 h-16 bg-primary"></div>
  <div class="w-16 h-16 bg-primary/50"></div>

  <div class="w-16 h-16 bg-secondary"></div>
  <div class="w-16 h-16 bg-secondary/50"></div>
</div>

Without a lot's of code duplication:

const hexColors = {
  primary: 'primary-color',
  secondary: 'secondary-color',
  accent: 'accent-color',
  success: 'success-color',
  error: 'error-color',
  light: 'light-color',
  base: 'base-100',
};

const colorMix = (colorVar) => {
  return `color-mix(in srgb, var(--${colorVar}) calc(100% * <alpha-value>), transparent)`;
};

/** @type {import('tailwindcss').Config} */
tailwind.config = {
  theme: {
    extend: {
      colors: Object.fromEntries(
        Object.entries(hexColors).map(([key, varName]) => [
          key, 
          colorMix(varName)
        ]),
      ),
    },
  },
  plugins: [],
};
:root {
  --primary-color: #000;
  --secondary-color: #1F85DE;
}
<script src="https://cdn.tailwindcss"></script>

<div class="flex">
  <div class="w-16 h-16 bg-primary"></div>
  <div class="w-16 h-16 bg-primary/50"></div>

  <div class="w-16 h-16 bg-secondary"></div>
  <div class="w-16 h-16 bg-secondary/50"></div>
</div>

TailwindCSS v4

From v4 onwards, this issue is resolved in the CSS-first configuration, as it now performs automatically what you had to do manually in v3. It looks like this:

:root {
  --primary-color: #000;
  --secondary-color: #1F85DE;
}
<script src="https://cdn.jsdelivr/npm/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@theme {
  --color-primary: var(--primary-color);
  --color-secondary: var(--secondary-color);
  /* ... */
}
</style>

<div class="flex">
  <div class="w-16 h-16 bg-primary"></div>
  <div class="w-16 h-16 bg-primary/50"></div>

  <div class="w-16 h-16 bg-secondary"></div>
  <div class="w-16 h-16 bg-secondary/50"></div>
</div>

发布评论

评论列表(0)

  1. 暂无评论