I’m creating a NextJS application that uses TailwindCSS for theming and styles but I’m also using NextUI for a component library.
In my tailwind.config.ts
file, I have defined some custom colors.
import type { Config } from "tailwindcss";
import { nextui } from "@nextui-org/react";
const config: Config = {
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}",
],
theme: {
colors: {
transparent: 'transparent',
red: {
25: '#fcf7f8',
50: '#f9eff1',
100: '#f6dee2',
200: '#f1b9c1',
// ...
},
orange: {
25: '#fcf9f7',
50: '#f9f1ed',
100: '#f5e3d9',
200: '#efc5af',
// ...
},
yellow: {
25: '#fcfbf7',
50: '#f8f5ed',
100: '#f3edd9',
200: '#ecddae',
// ...
},
green: {
25: '#f7fafa',
50: '#eaf1f0',
100: '#d4e5e2',
200: '#a7cdc6',
// ...
},
blue: {
25: '#f7fafc',
50: '#ebf1f6',
100: '#d6e3ef',
200: '#a9c7e3',
// ...
500: '#0a73d7'
// ...
},
purple: {
25: '#f8f7fa',
50: '#eeedf2',
100: '#e5dced',
200: '#cbb5de',
// ...
},
gray: {
25: '#f8f8f9',
50: '#f1f2f2',
100: '#e3e5e7',
200: '#c7cbcf',
// ...
},
black: '#000000',
white: '#ffffff',
},
},
darkMode: 'class',
plugins: [nextui()],
};
export default config;
However, when I try to use a color token such as primary
in a NextUI component, it’s the color that appears on the page is NextUI’s default theming color values. For example:
import { Tabs } from "@nextui-org/react";
export default function TabsMenu() {
return (
<Tabs variant="solid" color="primary" fullWidth={true}>
// ...
</Tabs>
)
}
In the browser, the active tab shows up as rgb(0, 111, 238)
/#006fee
, which is NextUI’s color setting for ‘primary’, but I want it to be rgb(10, 115, 215)
/#0a73d7
from my Tailwind theme.
According to NextUI’s documentation on creating a theme I could manually duplicate all my color objects into the NextUI plugin, but that’s rather ineffective since each color definition has 12 individual shades.
There should be a way for me to programmatically tell NextUI that it should use custom colors set in the Tailwind theme. How can I accomplish this?
The best way I found to do this required a bit of digging between the NextUI and Tailwind docs.
Note: step numbers are referenced in comments in the tailwind.config.ts
file below
- Import
resolveConfig
function from Tailwind. - Remove the
plugins
key from theconfig
object. - Use the resolveConfig function you imported to get the full Tailwind config. Pass the
config
object to it. - Get a reference to the custom Tailwind colors as a variable. This would work for custom properties you’ve set on your Tailwind theme, not just colors.
- Add the
plugins
key back to theconfig
object, and set NextUI’s color tokens to specific custom colors using thecolors
variable you set in #4.- The reason I removed
plugins
from theconfig
object and added it back later is to prevent possible circular dependencies between theresolveConfig
function and thenextui()
plugin function.
- The reason I removed
import type { Config } from "tailwindcss";
import { nextui } from "@nextui-org/react";
import resolveConfig from 'tailwindcss/resolveConfig'; // (1)
const config: Config = {
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}",
],
theme: {
colors: {
transparent: 'transparent',
red: { ... },
orange: { ... },
yellow: { ... },
green: { ... },
blue: { ... },
purple: { ... },
gray: { ... },
black: '#000000',
white: '#ffffff',
},
},
darkMode: 'class',
// (2)
};
const fullConfig = resolveConfig(config); // (3)
const { colors } = fullConfig.theme; // (4)
// (5)
config.plugins = [
nextui({
themes: {
'my-theme': {
extend: 'light',
colors: {
primary: colors.blue[500],
secondary: colors.purple[500],
success: colors.green[500],
warning: colors.orange[500],
danger: colors.red[500],
default: colors.gray[500],
}
}
}
})
];
export default config;
- Set your custom theme name (here,
my-theme
) as a class on wrapping element of your app. Which element this is depends on your project structure; mine looks like this:
_app.tsx
:
import type { AppProps } from "next/app";
import Layout from '@/components/layout';
import "@/styles/globals.css";
export default function App({ Component, pageProps }: AppProps) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}
layout.tsx
:
import {Providers} from "@/components/providers";
export default function Layout({children}) {
return (
<>
<Providers>
<main className="my-theme"> // (6)
{children}
</main>
</Providers>
</>
)
}
Now, as long as a NextUI component is used inside the element that has the my-theme
class, any color tokens that have been set to custom Tailwind colors will function properly.
In my original example,
import { Tabs } from "@nextui-org/react";
export default function TabsMenu() {
return (
<Tabs variant="solid" color="primary" fullWidth={true}>
// ...
</Tabs>
)
}
the active tab is now rendered with my custom blue[500] color as I would expect: rgb(10, 115, 215)
/#0a73d7
.