Prerequisites
Before starting the project make sure to install the following utilities:
Creating a new Next application
Let's create a fresh Next application so that we can go through all the steps together.
Step 1
Create new project
npx create-next-app@latest
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 -p
Step 2
Add the paths to all of your template files in your
tailwind.config.cjs
file.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./app/**/*.{js,ts,jsx,tsx}",
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
"./node_modules/tw-elements/dist/js/**/*.js"
// Or if using `src` directory:
"./src/**/*.{js,ts,jsx,tsx}",
"./node_modules/tw-elements/dist/js/**/*.js"
],
theme: {
extend: {},
},
darkMode: "class",
plugins: [require("tw-elements/dist/plugin.cjs")]
}
Step 3
Add the @tailwind
directives for each of Tailwind’s layers to
your ./src/styles/global.css
file.
@tailwind base;
@tailwind components;
@tailwind utilities;
Step 4
Attach the Roboto
font in _app.js
.
import "@/styles/globals.css";
import { Roboto } from "next/font/google";
const roboto = Roboto({ weight: "400", subsets: ["latin"] });
export default function App({ Component, pageProps }) {
return (
<>
<style jsx global>{`
html {
font-family: ${roboto.style.fontFamily};
}
`}</style>
<Component {...pageProps} />
</>
);
}
Step 5
Install Tailwind Elements.
npm install tw-elements
Step 6
Import globally in _app.js
Tailwind 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 MyDatepicker.js
in src/pages
directory) and import TE components which are you intend to use. Also include necessary function initTE
. Initialize initTE
in a lifecycle method.
import { Datepicker, Input, initTE } from "tw-elements";
import { useEffect } from "react";
const MyDatepicker = () => {
useEffect(() => {
initTE({ Datepicker, Input });
}, []);
return (
<div
className="relative mb-3"
data-te-datepicker-init
data-te-input-wrapper-init
>
<input
type="text"
className="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
htmlFor="floatingInput"
className="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>
);
};
export default MyDatepicker;
Step 8
Import (for example in index.js
) newly created component wrapping it into dynamic
import with ssr
object set to false
.
import dynamic from "next/dynamic";
const DynamicDatepicker = dynamic(() => import("./MyDatepicker"), { ssr: false });
const Home = () => {
return (
<>
<DynamicDatepicker />
</>
);
};
export default Home;
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 components in lifecycle hook.
import { Datepicker, Input } from "tw-elements";
import { useEffect } from "react";
const MyDatepicker = () => {
useEffect(() => {
const myInput = new Input(document.getElementById("myDatepicker"));
const options = {
format: "dd-mm-yyyy",
};
const myDatepicker = new Datepicker(
document.getElementById("myDatepicker"),
options
);
}, []);
return (
<div
className="relative mb-3"
id="myDatepicker"
>
<input
type="text"
className="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
htmlFor="floatingInput"
className="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>
);
};
export default MyDatepicker;