
EssealDatePicker is a lightweight framework-agnostic JavaScript date picker library that supports single date selection, date ranges, and localization.
You can attach the date picker to any text input and use it natively in React, Vue, Angular, and plain HTML environments.
Features:
- Range Selection Mode: Switch between single-date and date-range picking with one configuration option.
- Custom Theming: Accepts hex color codes for primary and text colors.
- Date Restrictions: Set minimum and maximum selectable dates.
- Keyboard Accessible: Includes ARIA labels and keyboard navigation support for screen readers.
- Locale Support: Automatically detects browser locale.
- Custom Formatters: Replace default date formatting with your own function.
How To Use It:
1. Import the EssealDatePicker into your document.
import EssealDatePicker from "./index.js";
2. Attach the date picker to a standard input field.
<input id="example" type="text" placeholder="Select a date" readonly />
const picker = new EssealDatePicker("#example", {
// options here
});3. Configuration options.
mode(string): Sets selection behavior. Accepts'single'for one date or'range'for start/end selection. Default is'single'.locale(string): Defines language for month names and date formatting. Uses browser default if not specified. Examples:'en-US','fr-FR','ja-JP'.minDate(Date | string | null): Blocks selection of dates before this value. Users cannot click disabled dates. Pass a Date object or ISO string. Default isnull(no minimum).maxDate(Date | string | null): Blocks selection of dates after this value. Prevents future date selection when needed. Pass a Date object or ISO string. Default isnull(no maximum).primaryColor(string): Sets the highlight color for selected dates. Must be hexadecimal format (#3b82f6or#f00). RGB and HSL formats will not work. Default is'#3b82f6'.textColor(string): Controls text color throughout the calendar interface. Must be hex format. Default is'#1f2937'.zIndex(number): Positions the calendar popup in the stacking context. Increase this value if other elements cover the calendar. Default is9999.format(function): Customizes how dates display in the input field. Receives a Date object and returns a string. Default formats as YYYY-MM-DD (date.toLocaleDateString('en-CA')).onChange(function | null): Callback that fires when user selects a date. Receives the selected Date object (single mode) or an object withstartandendproperties (range mode). Default isnull.
const picker = new EssealDatePicker("#example", {
mode: 'single',
locale: navigator.language || 'en-US',
minDate: null,
maxDate: null,
primaryColor: '#3b82f6',
textColor: '#1f2937',
zIndex: 9999,
format: (date) => date.toLocaleDateString('en-CA'),
onChange: null,
});4. API methods.
// Opens the calendar popup programmatically // Useful for custom trigger buttons picker.open(); // Closes the calendar popup // Call this to hide the picker without selecting a date picker.close(); // Removes all event listeners and DOM elements // CRITICAL: Always call this before removing the picker // Prevents memory leaks in React, Vue, and Angular picker.destroy();
React Integration:
import { useEffect, useRef } from "react";
import EssealDatePicker from "esseal-date-picker";
function DatePickerComponent() {
const inputRef = useRef(null);
const pickerRef = useRef(null);
useEffect(() => {
// Initialize the date picker after component mounts
pickerRef.current = new EssealDatePicker(inputRef.current, {
primaryColor: "#3b82f6",
onChange: (date) => {
console.log("Selected:", date);
// The input value updates automatically
// React state will sync on next render
},
});
// Critical: destroy() prevents memory leaks
return () => {
if (pickerRef.current) {
pickerRef.current.destroy();
}
};
}, []); // Empty dependency array = run once on mount
return (
<div>
<label htmlFor="date-picker">Select Date:</label>
{/* readOnly prevents manual text entry */}
<input
ref={inputRef}
type="text"
id="date-picker"
placeholder="Click to select date"
readOnly
/>
</div>
);
}
export default DatePickerComponent;Vue 3 Integration
<template>
<div>
<label for="date-picker">Select Date:</label>
<!-- ref creates a reference to this DOM element -->
<input
ref="dateInput"
type="text"
id="date-picker"
placeholder="Click to select date"
readonly
/>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import EssealDatePicker from "esseal-date-picker";
const dateInput = ref(null);
let picker = null;
onMounted(() => {
// Access the native DOM element with .value
picker = new EssealDatePicker(dateInput.value, {
onChange: (date) => {
console.log("Selected:", date);
},
});
});
// Clean up when component unmounts
onUnmounted(() => {
if (picker) {
picker.destroy();
}
});
</script>Angular Integration
import {
Component,
ElementRef,
ViewChild,
OnInit,
OnDestroy,
} from "@angular/core";
import EssealDatePicker from "esseal-date-picker";
@Component({
selector: "app-date-picker",
template: `
<div>
<label for="date-picker">Select Date:</label>
<!-- #dateInput creates a template reference -->
<input
#dateInput
type="text"
id="date-picker"
placeholder="Click to select date"
readonly
/>
</div>
`,
})
export class DatePickerComponent implements OnInit, OnDestroy {
@ViewChild("dateInput", { static: true }) dateInput!: ElementRef;
private picker: any;
ngOnInit() {
// Access native element through ElementRef
this.picker = new EssealDatePicker(this.dateInput.nativeElement, {
onChange: (date: Date) => {
console.log("Selected:", date);
},
});
}
// Angular calls this before destroying component
ngOnDestroy() {
if (this.picker) {
this.picker.destroy();
}
}
}FAQs:
Q: Can I style the calendar beyond just changing colors?
A: The picker injects CSS with the class prefix dp-. You can add your own stylesheet that targets these classes. Override properties like border-radius, font-family, or box-shadow.
Q: How do I get the selected date value for form submission?
A: The picker updates the input’s value attribute automatically. Standard form submissions include this value. Access it with formData.get('inputName') or input.value in JavaScript. The format depends on your format option.
Q: Why do I get a “Target input not found” error?
A: The picker runs before the DOM element exists. This happens when you pass a CSS selector but the element hasn’t rendered yet. Move initialization after the element appears. In frameworks, use lifecycle hooks (useEffect, onMounted, ngOnInit) to delay initialization.







