A lightweight, dependency-free date picker for vanilla JavaScript, React, Vue, Angular, and any other framework.
- Zero dependencies — pure JavaScript, no external libraries
- Framework agnostic — works with React, Vue, Angular, Svelte, or plain HTML
- React-safe — properly triggers React's synthetic event system
- ~8KB minified — nothing you don't need
- Single date & date range — both modes supported out of the box
- Confirm / Cancel actions — optional in-popup action buttons for controlled confirmation flows
- Customisable — colours, format, locale, z-index
- Accessible — ARIA roles and keyboard-friendly
- Localised — automatic locale detection with full
Intlsupport
npm install esseal-date-pickerCDN (ES module):
<script type="module">
import EssealDatePicker from "https://cdn.jsdelivr.net/npm/esseal-date-picker/index.js";
</script><input type="text" id="date-picker" placeholder="Select a date" readonly />
<script type="module">
import EssealDatePicker from "esseal-date-picker";
new EssealDatePicker("#date-picker", {
onChange(date) {
console.log("Selected:", date);
},
});
</script>import { useEffect, useRef } from "react";
import EssealDatePicker from "esseal-date-picker";
function DatePickerField() {
const inputRef = useRef(null);
useEffect(() => {
const picker = new EssealDatePicker(inputRef.current, {
primaryColor: "#3b82f6",
onChange(date) {
console.log("Selected:", date);
},
});
return () => picker.destroy();
}, []);
return <input ref={inputRef} type="text" placeholder="Select a date" readOnly />;
}<template>
<input ref="dateInput" type="text" placeholder="Select a date" readonly />
</template>
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import EssealDatePicker from "esseal-date-picker";
const dateInput = ref(null);
let picker;
onMounted(() => {
picker = new EssealDatePicker(dateInput.value, {
onChange(date) {
console.log("Selected:", date);
},
});
});
onUnmounted(() => picker?.destroy());
</script>import { Component, ElementRef, ViewChild, OnInit, OnDestroy } from "@angular/core";
import EssealDatePicker from "esseal-date-picker";
@Component({
selector: "app-date-picker",
template: `<input #dateInput type="text" placeholder="Select a date" readonly />`,
})
export class DatePickerComponent implements OnInit, OnDestroy {
@ViewChild("dateInput", { static: true }) dateInput!: ElementRef;
private picker: any;
ngOnInit() {
this.picker = new EssealDatePicker(this.dateInput.nativeElement, {
onChange(date: Date) {
console.log("Selected:", date);
},
});
}
ngOnDestroy() {
this.picker?.destroy();
}
}new EssealDatePicker(target, options);| Parameter | Type | Description |
|---|---|---|
target |
string | HTMLInputElement |
CSS selector string or a DOM element |
options |
object |
Configuration — see below |
| Option | Type | Default | Description |
|---|---|---|---|
mode |
'single' | 'range' |
'single' |
Single date or date range selection |
showActions |
boolean |
false |
Adds Confirm and Cancel buttons inside the popup. Selection is not committed until Confirm is clicked. |
locale |
string |
navigator.language |
Locale for month/day labels (e.g. 'en-US', 'fr-FR') |
format |
function |
date.toLocaleDateString('en-CA') |
Custom formatter (date: Date) => string |
primaryColor |
string |
'#3b82f6' |
Accent colour — must be hex (#RRGGBB or #RGB) |
textColor |
string |
'#1f2937' |
Calendar text colour |
minDate |
Date | string | null |
null |
Earliest selectable date |
maxDate |
Date | string | null |
null |
Latest selectable date |
zIndex |
number |
9999 |
CSS z-index of the popup |
onChange |
function | null |
null |
Called when a date (or range) is committed. Receives a Date in single mode, or { start: Date, end: Date } in range mode. With showActions, this fires on Confirm — not on date click. |
| Method | Description |
|---|---|
open() |
Opens the calendar popup |
close() |
Closes the calendar popup |
destroy() |
Removes the popup DOM and all event listeners. Always call this on unmount in React, Vue, and Angular. |
new EssealDatePicker("#date-range", {
mode: "range",
onChange(range) {
console.log("Start:", range.start);
console.log("End:", range.end);
},
});Adds Confirm and Cancel buttons inside the popup. The onChange callback fires only when the user clicks Confirm, not on every date click.
new EssealDatePicker("#date-picker", {
showActions: true,
onChange(date) {
console.log("Confirmed:", date);
},
});Works with range mode too:
new EssealDatePicker("#date-range", {
mode: "range",
showActions: true,
onChange(range) {
console.log("Confirmed:", range.start, "→", range.end);
},
});new EssealDatePicker("#date-picker", {
minDate: new Date(2024, 0, 1), // Jan 1 2024
maxDate: new Date(2024, 11, 31), // Dec 31 2024
});new EssealDatePicker("#date-picker", {
primaryColor: "#10b981", // green
textColor: "#374151",
});new EssealDatePicker("#date-picker", {
format(date) {
const d = String(date.getDate()).padStart(2, "0");
const m = String(date.getMonth() + 1).padStart(2, "0");
return `${d}/${m}/${date.getFullYear()}`; // DD/MM/YYYY
},
});new EssealDatePicker("#date-picker", {
locale: "fr-FR",
format: (date) => date.toLocaleDateString("fr-FR"),
});const picker = new EssealDatePicker("#date-picker");
document.querySelector("#open-btn").addEventListener("click", () => picker.open());
document.querySelector("#close-btn").addEventListener("click", () => picker.close());Each instance is fully independent:
const start = new EssealDatePicker("#start-date", { primaryColor: "#3b82f6" });
const end = new EssealDatePicker("#end-date", { primaryColor: "#ef4444" });The range in-between highlight is computed by appending an alpha suffix (#3b82f620), so RGB and HSL strings will break it.
// ✅ Valid
primaryColor: "#3b82f6"
primaryColor: "#f00"
// ❌ Invalid
primaryColor: "rgb(59, 130, 246)"
primaryColor: "hsl(217, 91%, 60%)"// React
useEffect(() => {
const picker = new EssealDatePicker(ref.current, options);
return () => picker.destroy();
}, []);Prevents manual typing while still allowing the picker to update the value:
<input type="text" id="date-picker" readonly />Chrome, Firefox, Safari, and Edge (latest versions). IE11 is not supported.
MIT — free for personal and commercial use.
Part of the Esseal product suite · View product page