Basic example
The datepicker allows users to enter a date either through text input, or by choosing a date from the calendar. Date pickers can be embedded into dialogs on mobile and text field dropdowns on desktop.
<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>
// Initialization for ES Users
import {
Datepicker,
Input,
initTE,
} from "tw-elements";
initTE({ Datepicker, Input });
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!
Inline version
Use the data-te-inline="true"
attribute to initialize and set
the default date for an inline datepicker inside a block element.
<div
class="relative mb-3"
data-te-datepicker-init
data-te-inline="true"
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>
// Initialization for ES Users
import {
Datepicker,
Input,
initTE,
} from "tw-elements";
initTE({ Datepicker, Input });
Translations
The picker can be customized to add support for internationalization. Modify the component options to add translations.
<div
id="datepicker-translated"
class="relative"
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>
import {
Datepicker,
Input,
initTE,
} from "tw-elements";
initTE({ Input });
const datepickerTranslated = new Datepicker(
document.querySelector("#datepicker-translated"),
{
title: "Datum auswählen",
monthsFull: [
"Januar",
"Februar",
"März",
"April",
"Mai",
"Juni",
"Juli",
"August",
"September",
"Oktober",
"November",
"Dezember",
],
monthsShort: [
"Jan",
"Feb",
"Mär",
"Apr",
"Mai",
"Jun",
"Jul",
"Aug",
"Sep",
"Okt",
"Nov",
"Dez",
],
weekdaysFull: [
"Sonntag",
"Montag",
"Dienstag",
"Mittwoch",
"Donnerstag",
"Freitag",
"Samstag",
],
weekdaysShort: ["Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam"],
weekdaysNarrow: ["S", "M", "D", "M", "D", "F", "S"],
okBtnText: "Ok",
clearBtnText: "Klar",
cancelBtnText: "Schließen",
}
);
const datepickerTranslated = new te.Datepicker(
document.querySelector("#datepicker-translated"),
{
title: "Datum auswählen",
monthsFull: [
"Januar",
"Februar",
"März",
"April",
"Mai",
"Juni",
"Juli",
"August",
"September",
"Oktober",
"November",
"Dezember",
],
monthsShort: [
"Jan",
"Feb",
"Mär",
"Apr",
"Mai",
"Jun",
"Jul",
"Aug",
"Sep",
"Okt",
"Nov",
"Dez",
],
weekdaysFull: [
"Sonntag",
"Montag",
"Dienstag",
"Mittwoch",
"Donnerstag",
"Freitag",
"Samstag",
],
weekdaysShort: ["Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam"],
weekdaysNarrow: ["S", "M", "D", "M", "D", "F", "S"],
okBtnText: "Ok",
clearBtnText: "Klar",
cancelBtnText: "Schließen",
}
);
Formats
Use format
option to display date in a human-friendly format.
<div
class="relative mb-3"
data-te-datepicker-init
data-te-format="dd, mmm, yyyy"
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>
// Initialization for ES Users
import {
Datepicker,
Input,
initTE,
} from "tw-elements";
initTE({ Datepicker, Input });
Formatting rules
The following rules can be used to format any date:
ddd
and
dddd
formats, you need to also provide d
or
dd
. For example:
data-mdb-format="ddd, dd, mmm, yyyy"
Rule | Description | Result |
---|---|---|
d | Date of the month | 1 – 31 |
dd | Date of the month with a leading zero | 01 – 31 |
ddd | Day of the week in short form | Sun – Sat |
dddd | Day of the week in full form | Sunday – Saturday |
m | Month of the year | 1 – 12 |
mm | Month of the year with a leading zero | 01 – 12 |
mmm | Month name in short form | Jan – Dec |
mmmm | Month name in full form | January – December |
yy | Year in short form * | 00 – 99 |
yyyy | Year in full form | 2000 – 2999 |
Date limits
Set the minimum and maximum selectable dates with the min
and
max
options.
<div
class="relative mb-3"
id="datepicker-with-limits"
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>
import {
Datepicker,
Input,
initTE,
} from "tw-elements";
initTE({ Input });
const datepickerWithLimits = document.getElementById('datepicker-with-limits');
new Datepicker(datepickerWithLimits, {
min: new Date(2020, 5, 10),
max: new Date(2023, 5, 20)
});
const datepickerWithLimits = document.getElementById('datepicker-with-limits');
new te.Datepicker(datepickerWithLimits, {
min: new Date(2020, 5, 10),
max: new Date(2023, 5, 20)
});
Disable past
Use the disablePast
option to disallow past date selection.
<div
class="relative mb-3"
id="datepicker-disable-past"
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>
import {
Datepicker,
Input,
initTE,
} from "tw-elements";
initTE({ Input });
const datepickerDisablePast = document.getElementById('datepicker-disable-past');
new Datepicker(datepickerDisablePast, {
disablePast: true
});
const datepickerDisablePast = document.getElementById('datepicker-disable-past');
new te.Datepicker(datepickerDisablePast, {
disablePast: true
});
Disable future
Use the disableFuture
option to disallow past date selection.
<div
class="relative mb-3"
id="datepicker-disable-future"
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>
import {
Datepicker,
Input,
initTE,
} from "tw-elements";
initTE({ Input });
const datepickerDisableFuture = document.getElementById('datepicker-disable-future');
new Datepicker(datepickerDisableFuture, {
disableFuture: true
});
const datepickerDisableFuture = document.getElementById('datepicker-disable-future');
new te.Datepicker(datepickerDisableFuture, {
disableFuture: true
});
Disabled dates
The filter
option accept function in which you can specify
conditions for date filtering. A result of true indicates that the date
should be valid and a result of false indicates that it should be disabled.
In the following example all saturdays and sundays will be disabled.
<div
class="relative mb-3"
id="datepicker-disabled-dates"
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>
import {
Datepicker,
Input,
initTE,
} from "tw-elements";
initTE({ Input });
const datepickerWithFilter = document.getElementById('datepicker-disabled-dates');
const filterFunction = (date) => {
const isSaturday = date.getDay() === 6;
const isSunday = date.getDay() === 0;
return !isSaturday && !isSunday;
}
new Datepicker(datepickerWithFilter, { filter: filterFunction });
const datepickerWithFilter = document.getElementById('datepicker-disabled-dates');
const filterFunction = (date) => {
const isSaturday = date.getDay() === 6;
const isSunday = date.getDay() === 0;
return !isSaturday && !isSunday;
}
new te.Datepicker(datepickerWithFilter, { filter: filterFunction });
Input toggle
Add data-te-datepicker-toggle-ref
and
data-te-datepicker-toggle-button-ref
to the input element to
enable toggling on input click.
<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"
data-te-datepicker-toggle-ref
data-te-datepicker-toggle-button-ref />
<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>
// Initialization for ES Users
import {
Datepicker,
Input,
initTE,
} from "tw-elements";
initTE({ Datepicker, Input });
Custom toggle icon
Customize the toggle icon by adding a toggle button template to the component.
<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
>
<button
data-te-datepicker-toggle-ref
data-te-datepicker-toggle-button-ref
class="justify-content-center absolute right-0.5 top-1/2 flex -translate-x-1/2 -translate-y-1/2 items-center border-none bg-transparent outline-none hover:text-primary focus:text-primary dark:text-neutral-200 dark:hover:text-primary-400 dark:focus:text-primary-400 [&>svg]:h-5 [&>svg]:w-5">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor">
<path
fill-rule="evenodd"
d="M11.47 4.72a.75.75 0 011.06 0l7.5 7.5a.75.75 0 11-1.06 1.06L12 6.31l-6.97 6.97a.75.75 0 01-1.06-1.06l7.5-7.5zm.53 7.59l-6.97 6.97a.75.75 0 01-1.06-1.06l7.5-7.5a.75.75 0 011.06 0l7.5 7.5a.75.75 0 11-1.06 1.06L12 12.31z"
clip-rule="evenodd" />
</svg>
</button>
</div>
// Initialization for ES Users
import {
Datepicker,
Input,
initTE,
} from "tw-elements";
initTE({ Datepicker, Input });
Close without confirmation
This option close datepicker when the date is selected.
<div
class="relative mb-3"
id="datepicker-close-without-confirmation"
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>
import {
Datepicker,
Input,
initTE,
} from "tw-elements";
initTE({ Input });
const confirmDateOnSelect = document.getElementById('datepicker-close-without-confirmation');
new Datepicker(confirmDateOnSelect, {
confirmDateOnSelect: true,
});
const confirmDateOnSelect = document.getElementById('datepicker-close-without-confirmation');
new te.Datepicker(confirmDateOnSelect, {
confirmDateOnSelect: true,
});
Remove Action Buttons
You can use options removeOkBtn
,
removeCancelBtn
or removeClearBtn
to remove action
buttons that you don't need in your datepicker modal.
<div
class="relative mb-3"
id="datepicker-remove-action-buttons"
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>
import {
Datepicker,
Input,
initTE,
} from "tw-elements";
initTE({ Input });
const datepickerWithoutClearButton = document.getElementById('datepicker-remove-action-buttons');
new Datepicker(datepickerWithoutClearButton , {
removeClearBtn: true,
});
const datepickerWithoutClearButton = document.getElementById('datepicker-remove-action-buttons');
new te.Datepicker(datepickerWithoutClearButton , {
removeClearBtn: true,
});
Accessibility
We added proper aria attributes to the datepicker controls to make the component accessible. It's possible to change the values of those attributes by modifying the component options:
okBtnLabel: 'Confirm selection', clearBtnLabel: 'Clear selection',
cancelBtnLabel: 'Cancel selection', nextMonthLabel: 'Next month',
prevMonthLabel: 'Previous month', nextYearLabel: 'Next year',
prevYearLabel: 'Previous year', nextMultiYearLabel: 'Next 24 years',
prevMultiYearLabel: 'Previous 24 years', switchToMultiYearViewLabel:
'Choose year and month', switchToMonthViewLabel: 'Choose date',
switchToDayViewLabel: 'Choose date',