Prerequisites
Before starting the project make sure to install the following utilities:
Creating a new Nuxt application
Let's create a fresh Nuxt application so that we can go through all the steps together.
Step 1
Create new project
npx nuxi init my-project
cd my-project
Installing and configuring Tailwind CSS and Tailwind Elements
Step 1
Install Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
Step 2
Add tailwindcss
and autoprefixer
to the
postcss.plugins
object in your
nuxt.config.js
file. And of cours you got to attach
css
object with localization of main .css file.
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
css: ['~/assets/css/main.css'],
postcss: {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
},
})
Step 3
Add the paths to all of your template files in your
tailwind.config.cjs
file.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./components/**/*.{js,vue,ts}",
"./layouts/**/*.vue",
"./pages/**/*.vue",
"./plugins/**/*.{js,ts}",
"./nuxt.config.{js,ts}",
"./app.vue",
"./node_modules/tw-elements/dist/js/**/*.js"
],
theme: {
extend: {},
},
darkMode: "class",
plugins: [require("tw-elements/dist/plugin.cjs")]
}
Step 4
Add the @tailwind
directives for each of Tailwind’s layers to
your ./assets/css/main.css
file.
@tailwind base;
@tailwind components;
@tailwind utilities;
Step 5
Attach the Roboto font in nuxt.config.js/ts
by creating an
app
object.
app: {
head: {
link: [
{
rel: "stylesheet",
href: "https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,900&display=swap",
},
],
},
},
Step 5
Install Tailwind Elements.
npm install tw-elements
Step 6
Import globally in app.vue
Tailiwind Elements CSS file (you
could do it also in specific component which are using TE).
import "tw-elements/dist/css/tw-elements.min.css";
Step 7
Create standalone file with name of your component (for example
Datepicker.vue
in src/components
directory) and
import TE components which are you intend to use. Also include necessary
function initTE
. Initialize initTE
in a lifecycle
method.
<template>
<div
class="relative mb-3"
data-te-datepicker-init
data-te-input-wrapper-init>
<input
type="text"
class="peer block min-h-[auto] w-full rounded border-0 bg-transparent px-3 py-[0.32rem] leading-[1.6] outline-none transition-all duration-200 ease-linear focus:placeholder:opacity-100 peer-focus:text-primary data-[te-input-state-active]:placeholder:opacity-100 motion-reduce:transition-none dark:text-neutral-200 dark:placeholder:text-neutral-200 dark:peer-focus:text-primary [&:not([data-te-input-placeholder-active])]:placeholder:opacity-0"
placeholder="Select a date" />
<label
for="floatingInput"
class="pointer-events-none absolute left-3 top-0 mb-0 max-w-[90%] origin-[0_0] truncate pt-[0.37rem] leading-[1.6] text-neutral-500 transition-all duration-200 ease-out peer-focus:-translate-y-[0.9rem] peer-focus:scale-[0.8] peer-focus:text-primary peer-data-[te-input-state-active]:-translate-y-[0.9rem] peer-data-[te-input-state-active]:scale-[0.8] motion-reduce:transition-none dark:text-neutral-200 dark:peer-focus:text-primary"
>Select a date</label
>
</div>
</template>
<script setup>
import { onMounted } from "vue";
import { Datepicker, Input, initTE } from "tw-elements";
onMounted(() => {
initTE({ Datepicker, Input });
});
</script>
Step 8
Import (for example in app.vue
) newly created component
wrapping it into ClientOnly
element.
Initializing via JS
By default all components have autoinit which means they are initialized by data attributes. But if you want to make init by JavaScript - there is also possibility to do that.
Step 1
Import components which are you intend to use and initialize them in lifecycle method.
<template>
<div class="relative mb-3" id="myDatepicker">
<input
type="text"
class="peer block min-h-[auto] w-full rounded border-0 bg-transparent px-3 py-[0.32rem] leading-[1.6] outline-none transition-all duration-200 ease-linear focus:placeholder:opacity-100 peer-focus:text-primary data-[te-input-state-active]:placeholder:opacity-100 motion-reduce:transition-none dark:text-neutral-200 dark:placeholder:text-neutral-200 dark:peer-focus:text-primary [&:not([data-te-input-placeholder-active])]:placeholder:opacity-0"
placeholder="Select a date" />
<label
for="floatingInput"
class="pointer-events-none absolute left-3 top-0 mb-0 max-w-[90%] origin-[0_0] truncate pt-[0.37rem] leading-[1.6] text-neutral-500 transition-all duration-200 ease-out peer-focus:-translate-y-[0.9rem] peer-focus:scale-[0.8] peer-focus:text-primary peer-data-[te-input-state-active]:-translate-y-[0.9rem] peer-data-[te-input-state-active]:scale-[0.8] motion-reduce:transition-none dark:text-neutral-200 dark:peer-focus:text-primary"
>Select a date</label
>
</div>
</template>
<script setup>
import { onMounted } from "vue";
import { Datepicker, Input } from "tw-elements";
onMounted(() => {
const myInput = new Input(document.getElementById("myDatepicker"));
const options = {
format: "dd-mm-yyyy",
};
const myDatepicker = new Datepicker(
document.getElementById("myDatepicker"),
options
);
});
</script>