esseal-date-picker
v1.1.0
Published
A lightweight, dependency-free vanilla JS date picker with customisation support.
Downloads
36
Maintainers
Readme
EssealDatePicker
A lightweight, dependency-free date picker for vanilla JavaScript, React, Vue, Angular, and any other framework.
Features
- 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
Installation
npm install esseal-date-pickerCDN (ES module):
<script type="module">
import EssealDatePicker from "https://cdn.jsdelivr.net/npm/esseal-date-picker/index.js";
</script>Quick Start
Vanilla JavaScript
<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>React
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 />;
}Vue 3
<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>Angular
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();
}
}API Reference
Constructor
new EssealDatePicker(target, options);| Parameter | Type | Description |
|-----------|------|-------------|
| target | string \| HTMLInputElement | CSS selector string or a DOM element |
| options | object | Configuration — see below |
Options
| 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. |
Methods
| 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. |
Usage Examples
Date Range Selection
new EssealDatePicker("#date-range", {
mode: "range",
onChange(range) {
console.log("Start:", range.start);
console.log("End:", range.end);
},
});Confirm / Cancel Actions
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);
},
});Restrict Selectable Dates
new EssealDatePicker("#date-picker", {
minDate: new Date(2024, 0, 1), // Jan 1 2024
maxDate: new Date(2024, 11, 31), // Dec 31 2024
});Custom Colour Theme
new EssealDatePicker("#date-picker", {
primaryColor: "#10b981", // green
textColor: "#374151",
});Custom Date Format
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
},
});Localised Calendar
new EssealDatePicker("#date-picker", {
locale: "fr-FR",
format: (date) => date.toLocaleDateString("fr-FR"),
});Programmatic Control
const picker = new EssealDatePicker("#date-picker");
document.querySelector("#open-btn").addEventListener("click", () => picker.open());
document.querySelector("#close-btn").addEventListener("click", () => picker.close());Multiple Pickers
Each instance is fully independent:
const start = new EssealDatePicker("#start-date", { primaryColor: "#3b82f6" });
const end = new EssealDatePicker("#end-date", { primaryColor: "#ef4444" });Important Notes
primaryColor must be hex
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%)"Always call destroy() in framework components
// React
useEffect(() => {
const picker = new EssealDatePicker(ref.current, options);
return () => picker.destroy();
}, []);Use readonly on the input
Prevents manual typing while still allowing the picker to update the value:
<input type="text" id="date-picker" readonly />Browser Support
Chrome, Firefox, Safari, and Edge (latest versions). IE11 is not supported.
License
MIT — free for personal and commercial use.
Part of the Esseal product suite · View product page
