DEV Community

Cover image for 90+ Vue UI Components Styled with Tailwind CSS
Cagatay Civici
Cagatay Civici

Posted on

90+ Vue UI Components Styled with Tailwind CSS

PrimeVue has recently announced the new Unstyled mode that removes the default styling and exposes the component internals via pass through props API. With the unstyled mode, components do the hard work by providing the feature set and accessibility out of the box but leaves out the styling to the user.

Although any CSS library like Bootstrap and Bulma can be used, Tailwind CSS integration is match made in heaven, there is even a built-in Tailwind theme available in PrimeVue.

Interested? Let's dive in!

Setup

This part assumes that Tailwind is already available in your application, if not visit the Tailwind CSS framework guides like Vite or Nuxt for the installation. The built-in default theme is basically a global pass through configuration that needs to be imported from primevue/passthrough/tailwind path and then defined during setup. Since the theme is exclusive to unstyled mode, the unstyled setting is required in addition.

import {createApp} from "vue";
import PrimeVue from "primevue/config";
import Tailwind from "primevue/passthrough/tailwind";

const app = createApp(App);

app.use(PrimeVue, { unstyled: true, pt: Tailwind });
Enter fullscreen mode Exit fullscreen mode

Tailwind uses PurgeCSS internally to remove unused classes, since PrimeVue components are loaded from node_modules the content property at tailwind.config.js needs to be aware of PrimeVue, otherwise the classes utilized in the theme will be removed as well.

export default {
    ...
    content: [
        "./index.html",
        "./src/**/*.{vue,js,ts,jsx,tsx}",
        "./node_modules/primevue/**/*.{vue,js,ts,jsx,tsx}"
    ],
    ...
}
Enter fullscreen mode Exit fullscreen mode

Voilà 💚, you now have 90+ awesome Vue UI components styled with Tailwind that will work in harmony with the rest of your application.

Customization

The built-in theme provides a strong base that can be extended further for your requirements. For customization, the pass through values need to be overriden. The unstyled section of the theming documentation for each component demonstrates the theme with an editable example. For instance, the panel component has the following default configuration.

panel: {
    header: ({ props }) => ({
        class: [
            'flex items-center justify-between', // flex and alignments
            'border border-gray-300 bg-gray-100 text-gray-700 rounded-tl-lg rounded-tr-lg', // borders and colors
            'dark:bg-gray-900 dark:border-blue-900/40 dark:text-white/80', // Dark mode
            { 'p-5': !props.toggleable, 'py-3 px-5': props.toggleable } // condition
        ]
    }),
    title: {
        class: ['leading-none font-bold']
    },
    toggler: {
        class: [
            'inline-flex items-center justify-center overflow-hidden relative no-underline', // alignments
            'w-8 h-8 text-gray-600 border-0 bg-transparent rounded-full transition duration-200 ease-in-out', // widths, borders, and transitions
            'hover:text-gray-900 hover:border-transparent hover:bg-gray-200 dark:hover:text-white/80 dark:hover:bg-gray-800/80 dark:focus:shadow-[inset_0_0_0_0.2rem_rgba(147,197,253,0.5)]', // hover
            'focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)]' // focus
        ]
    },
    togglerIcon: {
        class: ['inline-block']
    },
    content: {
        class: [
            'p-5 border border-gray-300 bg-white text-gray-700 border-t-0 last:rounded-br-lg last:rounded-bl-lg',
            'dark:bg-gray-900 dark:border-blue-900/40 dark:text-white/80' // Dark mode
        ] // padding, borders, and colors
    }
},
Enter fullscreen mode Exit fullscreen mode

Let's assume the title section should be lighter and bigger.

import {createApp} from "vue";
import PrimeVue from "primevue/config";
import { usePassThrough } from "primevue/passthrough";
import Tailwind from "primevue/passthrough/tailwind";

const app = createApp(App);

//Tailwind customization
const CustomTailwind = usePassThrough(
    Tailwind,
    {
        panel: {
            title: {
                class: ['leading-none font-light text-2xl']
            }
        }
    },
    {
        mergeSections: true,  // Used to merge with other PT sections. The default is true.
        mergeProps: false,    // Whether to use override or merge with existing configuration
    }
);

app.use(PrimeVue, { unstyled: true, pt: CustomTailwind });
Enter fullscreen mode Exit fullscreen mode

Example

Take a look at the CodeSandbox sample to see the Tailwind CSS + PrimeVue in action

Top comments (0)