Tailwind Elements is a plugin that extends the functionality of the library with many interactive components.
In some dynamic components (like dropdowns or modals) we add custom JavaScript. However, they do not require any additional installation, all the necessary code is always included in the example and copied to any Tailwind project - it will work.
Tailwind Elements formats
Tailwind Elements, in order to meet the new, modular approach, allows the
use of ES
and UMD
formats. These formats will
differ in the way components are initialized and will be used in different
cases.
When to use ES or UMD format?
If your application:
- is based on
modules
- uses
bundler
functionality - needs
treeshaking
the ES
format will be most suitable for you, otherwise
UMD
is the way to go.
What is the difference between Tailwind Elements ES and UMD formats?
In short, the way to initialize components. In order to allow bundlers to
perform proper treeshaking, we have moved component initialization to the
initTE
method. Tailwind Elements in UMD
format
will work without adding more elements, but will lack treeshaking. Tailwind
Elements in ES
format, on the other hand, allows components to
be used as separate modules, resulting in the much smaller build size.
About the initTE
method
To use the initTE method, you need to import it from the
tw-elements
, same as for components. You can provide a second
argument that will be an object with options that you want to pass to the
init method. The options object can contain the following properties:
-
allowReinits
- by default it's value is set tofalse
. By changing the value totrue
, theinitTE
method won't check if components were already initialized. It can be helpful for example when using theTailwind Elements
package with frameworks that use routing (for example Vue SPA) -
checkOtherImports
- by default the value is also set tofalse
. How does it work? IfinitTE
finds a component that should be inited but has not been passed as an argument (for example, it finds a data attribute that would suggest that it should be initialized automatically), it will display a warning in a console. We encourage to use it in the last invocation ofinitTE
method because it shows what inits are lacking at the current moment.
How to use the initTE
method?
Import the method from the tw-elements
package inside your
project js
file and call it with the components you want to
initialize.
import { Datepicker, Input, initTE } from "tw-elements";
initTE({ Datepicker, Input }, { allowReinits: true });
1. Before starting the project make sure to install Node.js (LTS) and TailwindCSS.
2. Run the following command to install the package via NPM:
npm install tw-elements
3. Tailwind Elements is a plugin and should be included inside
tailwind.config.js
. It is also recommended to extend the
content
array with a js files pattern that loads dynamic
component classes. The final version of the config file should look like this:
module.exports = {
content: [
"./src/**/*.{html,js}",
"./node_modules/tw-elements/dist/js/**/*.js"
],
plugins: [require("tw-elements/dist/plugin.cjs")],
darkMode: "class"
};
4. Include the following JavaScript file before the end of the body element. Keep in mind that the path to the file may be different depending on the file structure of your project.
<script
type="text/javascript"
src="../node_modules/tw-elements/dist/js/tw-elements.umd.min.js"></script>
Now, the library is ready to use and available via the global
te
variable.
1. To start using MDB GO / CLI install it with one command:
npm install -g mdb-cli
2. Log into the CLI using your MDB account:
mdb login
3. Initialize a project and choose Tailwind Elements from the list:
mdb init tailwind-elements
4. Install the dependencies (inside the project directory):
npm install
5. Run the app:
npm start
6. Publish when you're ready:
mdb publish

Vite
Node.js version 16.17.0 + / 18.1.0 +
installed. Please update
if your package manager asks for it. If you are expecting issues with
vite.config.js
and you don't want to update the npm, try
using the 4.3.9
version of vite.
Vite (French word for "fast", pronounced /vit/) is a build tool that aims to provide a faster and leaner development experience for modern web projects. Tailwind Elements can be imported in Vite applications according to the following procedure:
1. Create a new vite project and enter the newly created directory. Pick
Vanilla
framework and JavaScript
variant. You can
skip this step if you already have it installed.
npm create vite@latest my-project
cd my-project
2. Install tailwind CSS and its dependencies. After that,
init
the tailwind with the Tailwind CLI tool to create
tailwind.config.cjs
file.
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
3. Go to the tailwind.config.cjs
file and add paths where your
html files are going to be stored. You can change the
index.html
location but make sure to change to
root folder
inside the vite.config.js
file.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
4. Add the necessary Tailwind directives to your style.css
file
to be able to use Tailwind classes on your website. Unless you changed it,
style.css
should be in the root directory of your app. You can
also remove the default content of the style.css
file if you
want.
@tailwind base;
@layer base {
html {
@apply text-neutral-800;
}
html.dark {
@apply text-neutral-50;
@apply bg-neutral-800;
}
}
@tailwind components;
@tailwind utilities;
5. Link the css file inside the index.html
.
<head>
...
<link rel="stylesheet" href="style.css" />
...
</head>
6. Tailwind should be connected properly to the vite app. If you type the code
bellow, you will see the default vite index.html
page (without
any styles if you deleted them from style.css
).
npm run dev
7. Install the tw-elements
package.
npm install tw-elements
8. Add js files patterns that loads dynamic component classes to the content
array inside the tailwind.config.cjs
. Extend the default tailwind
classes by adding the Tailwind Elements
plugin.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./index.html",
"./src/**/*.{html,js}",
"./node_modules/tw-elements/dist/js/**/*.js",
],
plugins: [require("tw-elements/dist/plugin.cjs")],
darkMode: "class"
};
9. Now you can start working on your app. Since the package.json created by
vite has a type set to module
, we are going to use the
ES
. Lets try to import some code and see if everything is working
correctly. Don't forget to call the initTE
method. The carousel
component should have proper styles, and change the current image after arrow
click or after some delay.
initTE({ Carousel, Datepicker, Select, Timepicker });
<body class="dark:bg-neutral-800">
<div
id="carouselExampleCaptions"
class="relative"
data-te-carousel-init
data-te-carousel-slide>
<div
class="absolute bottom-0 left-0 right-0 z-[2] mx-[15%] mb-4 flex list-none justify-center p-0"
data-te-carousel-indicators>
<button
type="button"
data-te-target="#carouselExampleCaptions"
data-te-slide-to="0"
data-te-carousel-active
class="mx-[3px] box-content h-[3px] w-[30px] flex-initial cursor-pointer border-0 border-y-[10px] border-solid border-transparent bg-white bg-clip-padding p-0 -indent-[999px] opacity-50 transition-opacity duration-[600ms] ease-[cubic-bezier(0.25,0.1,0.25,1.0)] motion-reduce:transition-none"
aria-current="true"
aria-label="Slide 1"></button>
<button
type="button"
data-te-target="#carouselExampleCaptions"
data-te-slide-to="1"
class="mx-[3px] box-content h-[3px] w-[30px] flex-initial cursor-pointer border-0 border-y-[10px] border-solid border-transparent bg-white bg-clip-padding p-0 -indent-[999px] opacity-50 transition-opacity duration-[600ms] ease-[cubic-bezier(0.25,0.1,0.25,1.0)] motion-reduce:transition-none"
aria-label="Slide 2"></button>
<button
type="button"
data-te-target="#carouselExampleCaptions"
data-te-slide-to="2"
class="mx-[3px] box-content h-[3px] w-[30px] flex-initial cursor-pointer border-0 border-y-[10px] border-solid border-transparent bg-white bg-clip-padding p-0 -indent-[999px] opacity-50 transition-opacity duration-[600ms] ease-[cubic-bezier(0.25,0.1,0.25,1.0)] motion-reduce:transition-none"
aria-label="Slide 3"></button>
</div>
<div
class="relative w-full overflow-hidden after:clear-both after:block after:content-['']">
<div
class="relative float-left -mr-[100%] w-full transition-transform duration-[600ms] ease-in-out motion-reduce:transition-none"
data-te-carousel-active
data-te-carousel-item
style="backface-visibility: hidden">
<img
src="https://tecdn.b-cdn.net/img/Photos/Slides/img%20(15).jpg"
class="block w-full"
alt="..." />
<div
class="absolute inset-x-[15%] bottom-5 hidden py-5 text-center text-white md:block">
<h5 class="text-xl">First slide label</h5>
<p>Some representative placeholder content for the first slide.</p>
</div>
</div>
<div
class="relative float-left -mr-[100%] hidden w-full transition-transform duration-[600ms] ease-in-out motion-reduce:transition-none"
data-te-carousel-item
style="backface-visibility: hidden">
<img
src="https://tecdn.b-cdn.net/img/Photos/Slides/img%20(22).jpg"
class="block w-full"
alt="..." />
<div
class="absolute inset-x-[15%] bottom-5 hidden py-5 text-center text-white md:block">
<h5 class="text-xl">Second slide label</h5>
<p>Some representative placeholder content for the second slide.</p>
</div>
</div>
<div
class="relative float-left -mr-[100%] hidden w-full transition-transform duration-[600ms] ease-in-out motion-reduce:transition-none"
data-te-carousel-item
style="backface-visibility: hidden">
<img
src="https://tecdn.b-cdn.net/img/Photos/Slides/img%20(23).jpg"
class="block w-full"
alt="..." />
<div
class="absolute inset-x-[15%] bottom-5 hidden py-5 text-center text-white md:block">
<h5 class="text-xl">Third slide label</h5>
<p>Some representative placeholder content for the third slide.</p>
</div>
</div>
</div>
<button
class="absolute bottom-0 left-0 top-0 z-[1] flex w-[15%] items-center justify-center border-0 bg-none p-0 text-center text-white opacity-50 transition-opacity duration-150 ease-[cubic-bezier(0.25,0.1,0.25,1.0)] hover:text-white hover:no-underline hover:opacity-90 hover:outline-none focus:text-white focus:no-underline focus:opacity-90 focus:outline-none motion-reduce:transition-none"
type="button"
data-te-target="#carouselExampleCaptions"
data-te-slide="prev">
<span class="inline-block h-8 w-8">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="h-6 w-6">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 19.5L8.25 12l7.5-7.5" />
</svg>
</span>
<span
class="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]"
>Previous</span
>
</button>
<button
class="absolute bottom-0 right-0 top-0 z-[1] flex w-[15%] items-center justify-center border-0 bg-none p-0 text-center text-white opacity-50 transition-opacity duration-150 ease-[cubic-bezier(0.25,0.1,0.25,1.0)] hover:text-white hover:no-underline hover:opacity-90 hover:outline-none focus:text-white focus:no-underline focus:opacity-90 focus:outline-none motion-reduce:transition-none"
type="button"
data-te-target="#carouselExampleCaptions"
data-te-slide="next">
<span class="inline-block h-8 w-8">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="h-6 w-6">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M8.25 4.5l7.5 7.5-7.5 7.5" />
</svg>
</span>
<span
class="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]"
>Next</span
>
</button>
</div>
<script type="module" src="/main.js"></script>
</body>
import { Carousel, initTE } from "tw-elements";
initTE({ Carousel }, true ); // set second parameter to true if you want to use a debugger
<link
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,900&display=swap"
rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/tw-elements/dist/css/tw-elements.min.css" />
<script src="https://cdn.tailwindcss.com/3.3.0"></script>
<script>
tailwind.config = {
darkMode: "class",
theme: {
fontFamily: {
sans: ["Roboto", "sans-serif"],
body: ["Roboto", "sans-serif"],
mono: ["ui-monospace", "monospace"],
},
},
corePlugins: {
preflight: false,
},
};
</script>
Require the js bundled file right before the body
closing tag.
Use the UMD
file if used without a bundler.
<script src="https://cdn.jsdelivr.net/npm/tw-elements/dist/js/tw-elements.umd.min.js"></script>