Integration between PrimeReact and Tailwind CSS both in styled and unstyled modes.
Tailwind CSS is a popular CSS framework based on a utility-first design. The core provides flexible CSS classes with predefined CSS rules to build your own UI elements. For example, instead of an opinionated btn
className as in
Bootstrap, Tailwind offers primitive classes like bg-blue-500
, rounded
and p-4
to apply a button.
Tailwind is an outstanding CSS library, however it lacks a true comprehensive UI suite when combined with Vue.js, this is where PrimeReact comes in by providing a wide range of highly accessible and feature rich UI component library. The core of PrimeReact does not depend on Tailwind CSS, instead we provide the necessary integration points such as the primeui tailwind plugin and the Tailwind version for the unstyled mode.
Tailwind CSS and PrimeReact can be used together via two main approaches. Simple approach is using Tailwind CSS around PrimeReact components for layout purposes as demonstrated in the samples section below, the advanced approach takes the integration a step further by allowing Tailwind CSS within the component internals to style the entire UI suite in unstyled mode.
PrimeTek offers the Tailwind CSS version of the entire PrimeReact UI suite in unstyled mode based on the @apply
directive with IntelliSense support. Visit the Tailwind version of PrimeReact for the documentation, demos and additional resources.
Tailwind version of PrimeReact instead of the default styled mode is not tested with Tailwind v4. For the next-gen version of this project, we are building a new UI Component library based on the code ownership model where components are located inside your project source instead of imported from npm. This new library is powered by Unstyled PrimeReact Core and Tailwind v4.
The tailwindcss-primeui is an official plugin by PrimeTek to provide first className integration between a Prime UI library like
PrimeReact and Tailwind CSS. It is designed to work both in styled and unstyled modes. In styled mode, for instance the semantic colors such as primary and surfaces are provided as Tailwind utilities e.g. bg-primary
,
text-surface-500
, text-muted-color
.
If you haven't already done so, start by integrating Tailwind into your project. Detailed steps for this process can be found in the Tailwind documentation. After successfully installing Tailwind, proceed with the installation of the PrimeUI plugin. This single npm package comes with two libraries: the CSS version is compatible with Tailwind v4, while the JS version is designed for Tailwind v3.
npm i tailwindcss-primeui
In the CSS file that contains the tailwindcss import, add the tailwindcss-primeui
import as well.
@import 'tailwindcss';
@import 'tailwindcss-primeui';
Use the plugins option in your Tailwind config file to configure the plugin.
// tailwind.config.js
import PrimeUI from 'tailwindcss-primeui';
export default {
// ...
plugins: [PrimeUI]
};
The plugin extends the default configuration with a new set of utilities whose values are derived from the PrimeReact theme in use. All variants and breakpoints are supported e.g. dark:sm:hover:bg-primary
.
Class | Property |
---|---|
primary-[50-950] | Primary color palette. |
surface-[0-950] | Surface color palette. |
primary | Default primary color. |
primary-contrast | Default primary contrast color. |
primary-emphasis | Default primary emphasis color. |
border-surface | Default primary emphasis color. |
bg-emphasis | Emphasis background e.g. hovered element. |
bg-highlight | Highlight background. |
bg-highlight-emphasis | Highlight background with emphasis. |
rounded-border | Border radius. |
text-color | Text color with emphasis. |
text-color-emphasis | Default primary emphasis color. |
text-muted-color | Secondary text color. |
text-muted-color-emphasis | Secondary text color with emphasis. |
In styled mode, PrimeReact uses the system
as the default darkModeSelector
in theme configuration. If you have a dark mode switch in your application, ensure that darkModeSelector
is aligned with the Tailwind dark
variant for seamless integration. Note that, this particular configuration isn't required if you're utilizing the default system color scheme.
Suppose that, the darkModeSelector is set as my-app-dark
in PrimeReact.
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.tsx';
import { PrimeReactProvider } from '@primereact/core';
import Aura from '@primeuix/themes/aura';
const primereact = {
theme: {
preset: Aura,
options: {
darkModeSelector: '.my-app-dark'
}
}
};
createRoot(document.getElementById('root')!).render(
<StrictMode>
<PrimeReactProvider {...primereact}>
<App />
</PrimeReactProvider>
</StrictMode>
);
Add a custom variant for dark with a custom selector.
@import "tailwindcss";
@import "tailwindcss-primeui";
@custom-variant dark (&:where(.my-app-dark, .my-app-dark *)); //dark mode configuration
Use the plugins option in your Tailwind config file to configure the plugin.
// tailwind.config.js
import PrimeUI from 'tailwindcss-primeui';
export default {
darkMode: ['selector', '[className~="my-app-dark"]'], //dark mode configuration
plugins: [PrimeUI]
};
Tailwind utilities may not be able to override the default styling of components due to css specificity, there are two possible solutions; Important and CSS Layer.
Use the !
as a prefix to enforce the styling. This is not the recommend approach, and should be used as last resort to avoid adding unnecessary style classes to your bundle.
<InputText placeholder="Overriden" className="p-8!" />
<InputText placeholder="Overriden" className="!p-8" />
CSS Layer provides control over the css specificity so that Tailwind utilities can safely override components.
Ensure primereact
layer is after theme
and base
, but before the other Tailwind layers such as utilities
.
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.tsx';
import { PrimeReactProvider } from '@primereact/core';
import Aura from '@primeuix/themes/aura';
const primereact = {
theme: {
preset: Aura,
options: {
cssLayer: {
name: 'primereact',
order: 'theme, base, primereact'
}
}
}
};
createRoot(document.getElementById('root')!).render(
<StrictMode>
<PrimeReactProvider {...primereact}>
<App />
</PrimeReactProvider>
</StrictMode>
);
No change in the CSS configuration is required.
@import 'tailwindcss';
@import 'tailwindcss-primeui';
The primereact
layer should be between base and utilities.
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.tsx';
import { PrimeReactProvider } from '@primereact/core';
import Aura from '@primeuix/themes/aura';
const primereact = {
theme: {
preset: Aura,
options: {
cssLayer: {
name: 'primereact',
order: 'tailwind-base, primereact, tailwind-utilities'
}
}
}
};
createRoot(document.getElementById('root')!).render(
<StrictMode>
<PrimeReactProvider {...primereact}>
<App />
</PrimeReactProvider>
</StrictMode>
);
Tailwind v3 does not use native layer
so needs to be defined with CSS.
@layer tailwind-base, primereact, tailwind-utilities;
@layer tailwind-base {
@tailwind base;
}
@layer tailwind-utilities {
@tailwind components;
@tailwind utilities;
}
Example uses cases with PrimeReact and Tailwind CSS.
PrimeReact color palette as utility classes.
<div className="flex flex-col gap-12">
<div className="flex gap-6 flex-wrap">
<div className="rounded-border p-4 border border-transparent flex items-center justify-center bg-primary hover:bg-primary-emphasis text-primary-contrast font-medium flex-auto transition-colors">primary</div>
<div className="rounded-border p-4 border border-transparent flex items-center justify-center bg-highlight hover:bg-highlight-emphasis font-medium flex-auto transition-colors">highlight</div>
<div className="rounded-border p-4 border border-surface flex items-center justify-center text-muted-color hover:text-color hover:bg-emphasis font-medium flex-auto transition-colors">box</div>
</div>
</div>
The Tailwind v4 and PrimeReact starter example is available to demonstrate the integration setup with an example dashboard.
The plugin also adds extended animation utilities that can be used with the styleclass and animateonscroll components.
Class | Property |
---|---|
animate-enter | animation-name: enter; --p-enter-opacity: initial; --p-enter-scale: initial; --p-enter-rotate: initial; --p-enter-translate-x: initial; --p-enter-translate-y: initial; |
animate-leave | animation-name: leave; --p-leave-opacity: initial; --p-leave-scale: initial; --p-leave-rotate: initial; --p-leave-translate-x: initial; --p-leave-translate-y: initial; |
animate-leave | fadein 0.15s linear |
animate-fadein | fadein 0.15s linear |
animate-fadeout | fadeout 0.15s linear |
animate-slidedown | slidedown 0.45s ease-in-out |
animate-slideup | slideup 0.45s cubic-bezier(0, 1, 0, 1) |
animate-scalein | scalein 0.15s linear |
animate-fadeinleft | fadeinleft 0.15s linear |
animate-fadeoutleft | fadeoutleft 0.15s linear |
animate-fadeinright | fadeinright 0.15s linear |
animate-fadeoutright | fadeoutright 0.15s linear |
animate-fadeinup | fadeinup 0.15s linear |
animate-fadeoutup | fadeoutup 0.15s linear |
animate-fadeindown | fadeindown 0.15s linear |
animate-fadeoutup | fadeoutup 0.15s linear |
animate-width | width 0.15s linear |
animate-flip | flip 0.15s linear |
animate-flipup | flipup 0.15s linear |
animate-flipleft | fadein 0.15s linear |
animate-flipright | flipright 0.15s linear |
animate-zoomin | zoomin 0.15s linear |
animate-zoomindown | zoomindown 0.15s linear |
animate-zoominleft | zoominleft 0.15s linear |
animate-zoominright | zoominright 0.15s linear |
animate-zoominup | zoominup 0.15s linear |
Class | Property |
---|---|
animate-duration-0 | animation-duration: 0s |
animate-duration-75 | animation-duration: 75ms |
animate-duration-100 | animation-duration: 100ms |
animate-duration-200 | animation-duration: 200ms |
animate-duration-300 | animation-duration: 300ms |
animate-duration-400 | animation-duration: 400ms |
animate-duration-500 | animation-duration: 500ms |
animate-duration-700 | animation-duration: 700ms |
animate-duration-1000 | animation-duration: 1000ms |
animate-duration-2000 | animation-duration: 2000ms |
animate-duration-3000 | animation-duration: 300ms |
animate-duration-[value] | animation-duration: value |
Class | Property |
---|---|
animate-delay-none | animation-duration: 0s |
animate-delay-75 | animation-delay: 75ms |
animate-delay-100 | animation-delay: 100ms |
animate-delay-150 | animation-delay: 150ms |
animate-delay-200 | animation-delay: 200ms |
animate-delay-300 | animation-delay: 300ms |
animate-delay-400 | animation-delay: 400ms |
animate-delay-500 | animation-delay: 500ms |
animate-delay-700 | animation-delay: 700ms |
animate-delay-1000 | animation-delay: 1000ms |
Class | Property |
---|---|
animate-infinite | animation-iteration-count: infinite |
animate-once | animation-iteration-count: 1 |
animate-twice | animation-iteration-count: 2 |
Class | Property |
---|---|
animate-normal | animation-direction: normal |
animate-reverse | animation-direction: reverse |
animate-alternate | animation-direction: alternate |
animate-alternate-reverse | animation-direction: alternate-reverse |
Class | Property |
---|---|
animate-ease-linear | animation-timing-function: linear |
animate-ease-in | animation-timing-function: cubic-bezier(0.4, 0, 1, 1) |
animate-ease-out | animation-timing-function: cubic-bezier(0, 0, 0.2, 1) |
animate-ease-in-out | animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1) |
Class | Property |
---|---|
animate-fill-none | animation-fill-mode: normal |
animate-fill-forwards | animation-fill-mode: forwards |
animate-fill-backwards | animation-fill-mode: backwards |
animate-fill-both | animation-fill-mode: both |
Class | Property |
---|---|
animate-running | animation-play-state: running |
animate-paused | animation-play-state: paused |
Class | Property |
---|---|
backface-visible | backface-visibility: visible |
backface-hidden | backface-visibility: hidden |
Values are derived from the Tailwind CSS opacity e.g. fade-in-50 and fade-out-20. Arbitrary values such as fade-in-[15] are also supported.
Class | Property |
---|---|
fade-in-{value} | --p-enter-opacity: {value} |
fade-out-{value} | --p-leave-opacity: {value} |
Values are derived from the Tailwind CSS scale e.g. zoom-in-50 and zoom-out-75. Arbitrary values such as zoom-in-[0.8] are also supported.
Class | Property |
---|---|
zoom-in-{value} | --p-enter-scale: {value} |
zoom-out-{value} | --p-leave-scale: {value} |
Values are derived from the Tailwind CSS rotate e.g. spin-in-45 and spin-out-90. Arbitrary values such as spin-in-[60deg] are also supported.
Class | Property |
---|---|
spin-in-{value} | --p-enter-rotate: {value} |
spin-out-{value} | --p-leave-rotate: {value} |
Values are derived from the Tailwind CSS translate e.g. slide-in-from-t-50 and slide-out-to-l-8. Arbitrary values such as slide-in-from-b-[8px] are also supported.
Class | Property |
---|---|
slide-in-from-t-{value} | --p-enter-translate-y: -{value} |
slide-in-from-b-{value} | --p-enter-translate-y: {value} |
slide-in-from-l-{value} | --p-enter-translate-x: -{value} |
slide-in-from-r-{value} | --p-enter-translate-x: {value} |
slide-out-to-t-{value} | --p-leave-translate-y: -{value} |
slide-out-to-b-{value} | --p-leave-translate-y: {value} |
slide-out-to-l-{value} | --p-leave-translate-x: -{value} |
slide-out-to-r-{value} | --p-leave-translate-x: {value} |