Basic example
Loading Management automatically init when you add
data-te-loading-management-init
attribute to your element.
Loading automatically attach to body element, so if you want attach loading
to element you have add data-te-parent-selector
with class or
id of your parent or by javascript with parentSelector
option.
<div id="loading-basic-example" class="h-[300px] w-full">
<div
data-te-loading-management-init
data-te-parent-selector="#loading-basic-example">
<div
data-te-loading-icon-ref
class="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent motion-reduce:animate-[spin_1.5s_linear_infinite]"
role="status"></div>
<span data-te-loading-text-ref>Loading...</span>
</div>
</div>
// Initialization for ES Users
import {
LoadingManagement,
initTE,
} from "tw-elements";
initTE({ LoadingManagement });
Hey there 👋 we want to make TW elements a community-driven project. It's open source and free, and we would like it to stay that way. If you enjoy it, help the project grow by sharing it with your peers. Every share counts, thank you!
JavaScript init
You can init loading component with JavaScript.
<div class="flex w-full justify-center">
<div id="loading-js" class="h-[300px] w-full">
<div id="loadingTE">
<div
data-te-loading-icon-ref
class="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent motion-reduce:animate-[spin_1.5s_linear_infinite]"
role="status"></div>
<span data-te-loading-text-ref>Loading...</span>
</div>
</div>
</div>
// Initialization for ES Users
import { LoadingManagement } from "tw-elements";
const loadingTE = document.getElementById("loadingTE");
new LoadingManagement(loadingTE, {
parentSelector: "#loading-js",
});
const loadingTE = document.getElementById("loadingTE");
new te.LoadingManagement(loadingTE, {
parentSelector: "#loading-js",
});
Colors
You can set a different colors to loader with class customization.
<div id="loading-colors" class="h-[300px] w-full">
<div
data-te-loading-management-init
data-te-parent-selector="#loading-colors"
data-te-class-spinner-color="text-success dark:text-success-400"
data-te-class-backdrop-color="bg-[rgba(0,0,255,0.2)]">
<div
data-te-loading-icon-ref
class="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent motion-reduce:animate-[spin_1.5s_linear_infinite]"
role="status"></div>
<span data-te-loading-text-ref>Loading...</span>
</div>
</div>
// Initialization for ES Users
import {
LoadingManagement,
initTE,
} from "tw-elements";
initTE({ LoadingManagement });
Custom spinners
TE Growing spinner
If you don’t fancy a border spinner, switch to the grow spinner. While it doesn’t technically spin, it does repeatedly grow!
<div id="loading-growing-spinner" class="h-[300px] w-full">
<div
data-te-loading-management-init
data-te-parent-selector="#loading-growing-spinner">
<div
data-te-loading-icon-ref
class="inline-block h-8 w-8 animate-[spinner-grow_0.75s_linear_infinite] rounded-full bg-current opacity-0 motion-reduce:animate-[spinner-grow_1.5s_linear_infinite]"
role="status"></div>
<span data-te-loading-text-ref>Loading...</span>
</div>
</div>
// Initialization for ES Users
import {
LoadingManagement,
initTE,
} from "tw-elements";
initTE({ LoadingManagement });
Custom icon
You can use various icons to indicate loading status. Here is an example:
<div id="loading-custom-icon" class="h-[300px] w-full">
<div
data-te-loading-management-init
data-te-parent-selector="#loading-custom-icon">
<div
data-te-loading-icon-ref
class="inline-block h-8 w-8 animate-spin border-transparent motion-reduce:animate-[spin_1.5s_linear_infinite]"
role="status">
<span class="[&>svg]:w-8">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99" />
</svg>
</span>
</div>
<span data-te-loading-text-ref>Loading...</span>
</div>
</div>
// Initialization for ES Users
import {
LoadingManagement,
initTE,
} from "tw-elements";
initTE({ LoadingManagement });
Delay
Use following code to delay the appearance of loading spinner.
<div id="delay-example">
<input
class="mr-2 mt-[0.3rem] h-3.5 w-8 appearance-none rounded-[0.4375rem] bg-neutral-300 before:pointer-events-none before:absolute before:h-3.5 before:w-3.5 before:rounded-full before:bg-transparent before:content-[''] after:absolute after:z-[2] after:-mt-[0.1875rem] after:h-5 after:w-5 after:rounded-full after:border-none after:bg-neutral-100 after:shadow-[0_0px_3px_0_rgb(0_0_0_/_7%),_0_2px_2px_0_rgb(0_0_0_/_4%)] after:transition-[background-color_0.2s,transform_0.2s] after:content-[''] checked:bg-primary checked:after:absolute checked:after:z-[2] checked:after:-mt-[3px] checked:after:ml-[1.0625rem] checked:after:h-5 checked:after:w-5 checked:after:rounded-full checked:after:border-none checked:after:bg-primary checked:after:shadow-[0_3px_1px_-2px_rgba(0,0,0,0.2),_0_2px_2px_0_rgba(0,0,0,0.14),_0_1px_5px_0_rgba(0,0,0,0.12)] checked:after:transition-[background-color_0.2s,transform_0.2s] checked:after:content-[''] hover:cursor-pointer focus:outline-none focus:ring-0 focus:before:scale-100 focus:before:opacity-[0.12] focus:before:shadow-[3px_-1px_0px_13px_rgba(0,0,0,0.6)] focus:before:transition-[box-shadow_0.2s,transform_0.2s] focus:after:absolute focus:after:z-[1] focus:after:block focus:after:h-5 focus:after:w-5 focus:after:rounded-full focus:after:content-[''] checked:focus:border-primary checked:focus:bg-primary checked:focus:before:ml-[1.0625rem] checked:focus:before:scale-100 checked:focus:before:shadow-[3px_-1px_0px_13px_#3b71ca] checked:focus:before:transition-[box-shadow_0.2s,transform_0.2s] dark:bg-neutral-600 dark:after:bg-neutral-400 dark:checked:bg-primary dark:checked:after:bg-primary dark:focus:before:shadow-[3px_-1px_0px_13px_rgba(255,255,255,0.4)] dark:checked:focus:before:shadow-[3px_-1px_0px_13px_#3b71ca]"
type="checkbox"
role="switch"
id="flexSwitchCheckDefault" />
<label
class="inline-block pl-[0.15rem] hover:cursor-pointer"
for="flexSwitchCheckDefault"
>Switch Delay</label
>
<div id="counter"></div>
</div>
// Initialization for ES Users
import { LoadingManagement } from "tw-elements";
const loaderDelay = `
<div id="loading-wrapper">
<div id="loading-delay">
<div
data-te-loading-icon-ref
class="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent motion-reduce:animate-[spin_1.5s_linear_infinite]"
role="status"></div>
<span data-te-loading-text-ref>Loading...</span>
</div>
</div>
`;
const switches = document.getElementById("flexSwitchCheckDefault");
let timeleft = 4;
switches.addEventListener("change", (e) => {
const test = document.getElementById("delay-example");
if (e.target.checked) {
test.insertAdjacentHTML("beforeend", loaderDelay);
const loadingDelay = document.getElementById("loading-delay");
const counter = document.getElementById("counter");
const downloadTimer = setInterval(function () {
counter.classList.add(
"text-3xl",
"font-semibold",
"flex",
"justify-center",
"items-center"
);
if (timeleft <= 0) {
clearInterval(downloadTimer);
timeleft = 4;
}
counter.innerHTML = timeleft;
timeleft -= 1;
}, 1000);
new LoadingManagement(loadingDelay, {
delay: 5000,
backdropID: "delay-backdrop",
});
setTimeout(() => {
const backdrop = document.getElementById("delay-backdrop");
backdrop.remove();
loadingDelay.remove();
document.body.classList.remove("overflow-hidden");
}, 8000);
} else {
const loadingDelay = document.getElementById("loading-wrapper");
loadingDelay.remove();
document.getElementById("counter").innerHTML = "";
}
});
const loaderDelay = `
<div id="loading-wrapper">
<div id="loading-delay">
<div
data-te-loading-icon-ref
class="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent motion-reduce:animate-[spin_1.5s_linear_infinite]"
role="status"></div>
<span data-te-loading-text-ref>Loading...</span>
</div>
</div>
`;
const switches = document.getElementById("flexSwitchCheckDefault");
let timeleft = 4;
switches.addEventListener("change", (e) => {
const test = document.getElementById("delay-example");
if (e.target.checked) {
test.insertAdjacentHTML("beforeend", loaderDelay);
const loadingDelay = document.getElementById("loading-delay");
const counter = document.getElementById("counter");
const downloadTimer = setInterval(function () {
counter.classList.add(
"text-3xl",
"font-semibold",
"flex",
"justify-center",
"items-center"
);
if (timeleft <= 0) {
clearInterval(downloadTimer);
timeleft = 4;
}
counter.innerHTML = timeleft;
timeleft -= 1;
}, 1000);
new te.LoadingManagement(loadingDelay, {
delay: 5000,
backdropID: "delay-backdrop",
});
setTimeout(() => {
const backdrop = document.getElementById("delay-backdrop");
backdrop.remove();
loadingDelay.remove();
document.body.classList.remove("overflow-hidden");
}, 8000);
} else {
const loadingDelay = document.getElementById("loading-wrapper");
loadingDelay.remove();
document.getElementById("counter").innerHTML = "";
}
});
Full screen
Use the code below to add spinner for larger content areas or for full-screen loading.
<div id="full-screen-example">
<button
id="btn-full-screen"
type="button"
data-te-ripple-init
data-te-ripple-color="light"
class="inline-block rounded bg-primary px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-primary-600 hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-primary-600 focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-primary-700 active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] dark:shadow-[0_4px_9px_-4px_rgba(59,113,202,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)]">
Full screen
</button>
</div>
// Initialization for ES Users
import {
LoadingManagement,
Ripple,
initTE,
} from "tw-elements";
initTE({ Ripple });
const loaderFull = `
<div id="loading-full">
<div
data-te-loading-icon-ref
class="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent motion-reduce:animate-[spin_1.5s_linear_infinite]"
role="status"></div>
<span data-te-loading-text-ref>Loading...</span>
</div>
`;
const btnfull = document.getElementById("btn-full-screen");
btnfull.addEventListener("click", () => {
const test2 = document.getElementById("full-screen-example");
test2.insertAdjacentHTML("beforeend", loaderFull);
const loadingFull = document.getElementById("loading-full");
const loading = new LoadingManagement(loadingFull, {
scroll: false,
backdropID: "full-backdrop",
});
setTimeout(() => {
loading.dispose();
document.body.classList.remove("overflow-hidden");
}, 5000);
});
const loaderFull = `
<div id="loading-full">
<div
data-te-loading-icon-ref
class="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent motion-reduce:animate-[spin_1.5s_linear_infinite]"
role="status"></div>
<span data-te-loading-text-ref>Loading...</span>
</div>
`;
const btnfull = document.getElementById("btn-full-screen");
btnfull.addEventListener("click", () => {
const test2 = document.getElementById("full-screen-example");
test2.insertAdjacentHTML("beforeend", loaderFull);
const loadingFull = document.getElementById("loading-full");
const loading = new te.LoadingManagement(loadingFull, {
scroll: false,
backdropID: "full-backdrop",
});
setTimeout(() => {
loading.dispose();
document.body.classList.remove("overflow-hidden");
}, 5000);
});