PrimeVue | Vue UI Component Library (2024)

Integration between PrimeVue and Tailwind CSS both in styled and unstyled modes.

Overview #

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 class as in Bootstrap, Tailwind offers primitive classes like bg-blue-500, rounded and p-4 to apply a button. A set of reusable classes can also be grouped as a Tailwind CSS component and there are even a couple of libraries that take this approach to build components specifically for Tailwind.

Tailwind is an outstanding CSS library, however it lacks a true comprehensive UI suite when combined with Vue.js, this is where PrimeVue comes in by providing a wide range of highly accessible and feature rich UI component library. The core of PrimeVue does not depend on Tailwind CSS, instead we provide the necessary integration points such as the primeui tailwind plugin and the presets for the unstyled mode.

Presets #

Currently, the Tailwind CSS Presets are not compatible with v4 and will be with a future update after v4 final.

In unstyled mode of PrimeVue, default styling elements like design tokens and css classes are turned off so that you have full control over the component styling with pass-through properties. This feature is quite useful when you'd like to build your own UI library based on a custom design by wrapping PrimeVue components or simply utilitze Tailwind CSS to style the PrimeVue components.

The unstyled mode also use the preset concept just like the styled mode to define a theme. In styled mode a preset is a set of design tokens implemented with CSS variables whereas in unstyled mode a preset is a Pass-Through configuration object to inject Tailwind CSS classes into components. If you prefer to ignore the default styled mode theming api and use Tailwind CSS to style the PrimeVue UI components instead, learn more at the standalone Tailwind CSS Presets project website.

Plugin #

The tailwindcss-primeui is an official plugin by PrimeTek to provide first class integration between a Prime UI library like PrimeVue 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.

Plugin is available on npm.

npm i tailwindcss-primeui

After installation, configure the plugin at your tailwind configuration file.

// tailwind.config.jsmodule.exports = { // ... plugins: [require('tailwindcss-primeui')]};

Extensions #

The plugin extends the default configuration with a new set of utilities. All variants and breakpoints are supported e.g. dark:sm:hover:bg-primary.

Color Palette

ClassProperty
primary-[50-950]Primary color palette.
surface-[0-950]Surface color palette.
primaryDefault primary color.
primary-contrastDefault primary contrast color.
primary-emphasisDefault primary emphasis color.
border-surfaceDefault primary emphasis color.
bg-emphasisEmphasis background e.g. hovered element.
bg-highlightHighlight background.
bg-highlight-emphasisHighlight background with emphasis.
rounded-borderBorder radius.
text-colorText color with emphasis.
text-color-emphasisDefault primary emphasis color.
text-muted-colorSecondary text color.
text-muted-color-emphasisSecondary text color with emphasis.

Override #

In styled mode, Tailwind utilities may not be able to override the default styling due to css specificity, there are two possible solutions.

Important

Use the ! as a prefix to enforce the styling.

<InputText placeholder="Overriden" class="!p-8" />

CSS Layer

Enable PrimeVue CSS layer and configure the tailwind styles to have higher specificity with layering. This way, ! prefix is not required.

import PrimeVue from 'primevue/config';import Aura from '@primevue/themes/aura';const app = createApp(App);app.use(PrimeVue, { theme: { preset: Aura, options: { cssLayer: { name: 'primevue', order: 'tailwind-base, primevue, tailwind-utilities' } } } });
@layer tailwind-base, primevue, tailwind-utilities;@layer tailwind-base { @tailwind base;}@layer tailwind-utilities { @tailwind components; @tailwind utilities;}

Samples #

Example uses cases with PrimeVue and Tailwind CSS.

Color Palette #

PrimeVue color palette as utility classes.

  • primary

    50

    100

    200

    300

    400

    500

    600

    700

    800

    900

    950

  • surface

    50

    100

    200

    300

    400

    500

    600

    700

    800

    900

    950

primary

highlight

box

Form #

Using Tailwind utilities for the responsive layout of a form with PrimeVue components.

<div class="flex flex-col gap-6 w-full sm:w-auto"> <div class="flex flex-col sm:flex-row sm:items-center gap-6"> <div class="flex-auto"> <label for="firstname" class="block font-semibold mb-2">Firstname</label> <InputText id="firstname" class="w-full" /> </div> <div class="flex-auto"> <label for="lastname" class="block font-semibold mb-2">Lastname</label> <InputText id="lastname" class="w-full" /> </div> </div> <div class="flex flex-col sm:flex-row sm:items-center gap-6"> <div class="flex-1"> <label for="date" class="block font-semibold mb-2">Date</label> <DatePicker inputId="date" class="w-full" /> </div> <div class="flex-1"> <label for="country" class="block font-semibold mb-2">Country</label> <Select v-model="selectedCountry" inputId="country" :options="countries" optionLabel="name" placeholder="Select a Country" class="w-full"> <template #value="slotProps"> <div v-if="slotProps.value" class="flex items-center"> <img :alt="slotProps.value.label" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`mr-2 flag flag-${slotProps.value.code.toLowerCase()}`" style="width: 18px" /> <div>{{ slotProps.value.name }}</div> </div> <span v-else> {{ slotProps.placeholder }} </span> </template> <template #option="slotProps"> <div class="flex items-center"> <img :alt="slotProps.option.label" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`mr-2 flag flag-${slotProps.option.code.toLowerCase()}`" style="width: 18px" /> <div>{{ slotProps.option.name }}</div> </div> </template> </Select> </div> </div> <div class="flex-auto"> <label for="message" class="block font-semibold mb-2">Message</label> <Textarea id="message" class="w-full" rows="4" /> </div></div>

Headless #

A headless PrimeVue dialog with a custom UI.

<Button label="Login" icon="pi pi-user" @click="visible = true" /><Dialog v-model:visible="visible" pt:root:class="!border-0" pt:mask:class="backdrop-blur-sm"> <template #container="{ closeCallback }"> <div class="flex flex-col px-8 py-8 gap-6" style="border-radius: 12px; background-image: radial-gradient(circle at left top, var(--p-primary-400), var(--p-primary-700))"> <svg width="35" height="40" viewBox="0 0 35 40" fill="none" xmlns="http://www.w3.org/2000/svg" class="block mx-auto"> <path d="M25.87 18.05L23.16 17.45L25.27 20.46V29.78L32.49 23.76V13.53L29.18 14.73L25.87 18.04V18.05ZM25.27 35.49L29.18 31.58V27.67L25.27 30.98V35.49ZM20.16 17.14H20.03H20.17H20.16ZM30.1 5.19L34.89 4.81L33.08 12.33L24.1 15.67L30.08 5.2L30.1 5.19ZM5.72 14.74L2.41 13.54V23.77L9.63 29.79V20.47L11.74 17.46L9.03 18.06L5.72 14.75V14.74ZM9.63 30.98L5.72 27.67V31.58L9.63 35.49V30.98ZM4.8 5.2L10.78 15.67L1.81 12.33L0 4.81L4.79 5.19L4.8 5.2ZM24.37 21.05V34.59L22.56 37.29L20.46 39.4H14.44L12.34 37.29L10.53 34.59V21.05L12.42 18.23L17.45 26.8L22.48 18.23L24.37 21.05ZM22.85 0L22.57 0.69L17.45 13.08L12.33 0.69L12.05 0H22.85Z" fill="var(--p-primary-700)" /> <path d="M30.69 4.21L24.37 4.81L22.57 0.69L22.86 0H26.48L30.69 4.21ZM23.75 5.67L22.66 3.08L18.05 14.24V17.14H19.7H20.03H20.16H20.2L24.1 15.7L30.11 5.19L23.75 5.67ZM4.21002 4.21L10.53 4.81L12.33 0.69L12.05 0H8.43002L4.22002 4.21H4.21002ZM21.9 17.4L20.6 18.2H14.3L13 17.4L12.4 18.2L12.42 18.23L17.45 26.8L22.48 18.23L22.5 18.2L21.9 17.4ZM4.79002 5.19L10.8 15.7L14.7 17.14H14.74H15.2H16.85V14.24L12.24 3.09L11.15 5.68L4.79002 5.2V5.19Z" fill="var(--p-primary-200)" /> </svg> <div class="inline-flex flex-col gap-2"> <label for="username" class="text-primary-50 font-semibold">Username</label> <InputText id="username" class="!bg-white/20 !border-0 !p-4 !text-primary-50 w-80"></InputText> </div> <div class="inline-flex flex-col gap-2"> <label for="password" class="text-primary-50 font-semibold">Password</label> <InputText id="password" class="!bg-white/20 !border-0 !p-4 !text-primary-50 w-80" type="password"></InputText> </div> <div class="flex items-center gap-4"> <Button label="Cancel" @click="closeCallback" text class="!p-4 w-full !text-primary-50 !border !border-white/30 hover:!bg-white/10"></Button> <Button label="Sign-In" @click="closeCallback" text class="!p-4 w-full !text-primary-50 !border !border-white/30 hover:!bg-white/10"></Button> </div> </div> </template></Dialog>

Animations #

The plugin also adds extended animation utilities that can be used with the styleclass and animateonscroll directives.

<Select v-model="animation" :options="animations" placeholder="Select One" class="w-full sm:w-44" /><div class="py-8 overflow-hidden"> <div :class="`rounded-border bg-primary w-16 h-16 mx-auto animate-${animation} animate-once animate-duration-1000`"></div></div>

Animations

ClassProperty
animate-fadeinfadein 0.15s linear
animate-fadeoutfadeout 0.15s linear
animate-slidedownslidedown 0.45s ease-in-out
animate-slideupslideup 0.45s cubic-bezier(0, 1, 0, 1)
animate-scaleinscalein 0.15s linear
animate-fadeinleftfadeinleft 0.15s linear
animate-fadeoutleftfadeoutleft 0.15s linear
animate-fadeinrightfadeinright 0.15s linear
animate-fadeoutrightfadeoutright 0.15s linear
animate-fadeinupfadeinup 0.15s linear
animate-fadeoutupfadeoutup 0.15s linear
animate-fadeindownfadeindown 0.15s linear
animate-fadeoutupfadeoutup 0.15s linear
animate-widthwidth 0.15s linear
animate-flipflip 0.15s linear
animate-flipupflipup 0.15s linear
animate-flipleftfadein 0.15s linear
animate-fliprightflipright 0.15s linear
animate-zoominzoomin 0.15s linear
animate-zoomindownzoomindown 0.15s linear
animate-zoominleftzoominleft 0.15s linear
animate-zoominrightzoominright 0.15s linear
animate-zoominupzoominup 0.15s linear

Animation Duration

ClassProperty
animate-duration-0animation-duration: 0s
animate-duration-75animation-duration: 75ms
animate-duration-100animation-duration: 100ms
animate-duration-200animation-duration: 200ms
animate-duration-300animation-duration: 300ms
animate-duration-400animation-duration: 400ms
animate-duration-500animation-duration: 500ms
animate-duration-700animation-duration: 700ms
animate-duration-1000animation-duration: 1000ms
animate-duration-2000animation-duration: 2000ms
animate-duration-3000animation-duration: 300ms

Animation Delay

ClassProperty
animate-delay-noneanimation-duration: 0s
animate-delay-75animation-delay: 75ms
animate-delay-100animation-delay: 100ms
animate-delay-150animation-delay: 150ms
animate-delay-200animation-delay: 200ms
animate-delay-300animation-delay: 300ms
animate-delay-400animation-delay: 400ms
animate-delay-500animation-delay: 500ms
animate-delay-700animation-delay: 700ms
animate-delay-1000animation-delay: 1000ms

Iteration Count

ClassProperty
animate-infiniteanimation-iteration-count: infinite
animate-onceanimation-iteration-count: 1
animate-twiceanimation-iteration-count: 2

Direction

ClassProperty
animate-normalanimation-direction: normal
animate-reverseanimation-direction: reverse
animate-alternateanimation-direction: alternate
animate-alternate-reverseanimation-direction: alternate-reverse

Timing Function

ClassProperty
animate-ease-linearanimation-timing-function: linear
animate-ease-inanimation-timing-function: cubic-bezier(0.4, 0, 1, 1)
animate-ease-outanimation-timing-function: cubic-bezier(0, 0, 0.2, 1)
animate-ease-in-outanimation-timing-function: cubic-bezier(0.4, 0, 0.2, 1)

Fill Mode

ClassProperty
animate-fill-noneanimation-fill-mode: normal
animate-fill-forwardsanimation-fill-mode: forwards
animate-fill-backwardsanimation-fill-mode: backwards
animate-fill-bothanimation-fill-mode: both

Play State

ClassProperty
animate-runninganimation-play-state: running
animate-pausedanimation-play-state: paused

Backface Visibility State

ClassProperty
backface-visiblebackface-visibility: visible
backface-hiddenbackface-visibility: hidden
PrimeVue | Vue UI Component Library (2024)

References

Top Articles
Latest Posts
Article information

Author: Kerri Lueilwitz

Last Updated:

Views: 6050

Rating: 4.7 / 5 (67 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Kerri Lueilwitz

Birthday: 1992-10-31

Address: Suite 878 3699 Chantelle Roads, Colebury, NC 68599

Phone: +6111989609516

Job: Chief Farming Manager

Hobby: Mycology, Stone skipping, Dowsing, Whittling, Taxidermy, Sand art, Roller skating

Introduction: My name is Kerri Lueilwitz, I am a courageous, gentle, quaint, thankful, outstanding, brave, vast person who loves writing and wants to share my knowledge and understanding with you.