jb-date-input
v6.5.0
Published
jalali date input web component
Maintainers
Keywords
Readme
jb-date-input
jb-date-input is a form-associated Jalali and Gregorian date input web component with a typed input surface and a calendar popover.
- Supports Jalali and Gregorian input.
- Supports fast keyboard typing and ArrowUp/ArrowDown date-part changes.
- Opens a responsive, mobile-friendly calendar picker.
- Accepts Persian digits and can display Persian digits while keeping
.valuein English digits. - Supports
minandmaxdate limits. - Supports native HTML form submission through
ElementInternals. - Supports custom validation through
jb-validation. - Supports value output as Gregorian, Jalali, or timestamp.
- Supports custom value formats such as ISO strings,
YYYY/MM/DD, orYYYY_MM_DD. - Supports custom month names for Jalali and Gregorian calendars.
- Includes headless utilities for using the date typing logic with your own input.
- Supports TypeScript.
- Provides a smooth desktop typing experience.
- Supports ESM imports for modern JavaScript apps.
- Supports app-level i18n through
jb-core/i18n. - Supports custom styling with CSS variables and CSS parts. See CSS parts and variables.
- Uses
jb-input,jb-calendar, andjb-popoverinternally. - Framework friendly: use it in pure JavaScript or in frameworks such as React, Vue, and Angular.
When to use
Use jb-date-input when users should type or pick a date and the field needs Jalali/Gregorian conversion, form association, validation, min/max limits, custom value formats, or Persian digit display.
Use jb-calendar when you need only a calendar UI without an input field. Use jb-input when the value is plain text and not a date.
Demo
Using With JS Frameworks
See the React documentation.
Other integrations: Angular · Vue · Nuxt · Svelte · SvelteKit · SolidJS · Lit · Next.js · Astro · Blazor · Server-rendered templates · WordPress · Alpine.js and HTMX
Installation
npm i jb-date-inputimport 'jb-date-input';<jb-date-input label="Date"></jb-date-input>CDN
<script src="https://unpkg.com/jb-date-input/dist/jb-date-input.umd.js"></script>API reference
jb-date-input composes jb-input, jb-calendar, and jb-popover. For shared input styling and behavior, see the jb-input API.
Attributes
| name | type | default | description |
| --- | --- | --- | --- |
| value | string | empty date value | Date value in the configured value-type and format. Demo |
| value-type | 'GREGORIAN' \| 'JALALI' \| 'TIME_STAMP' | GREGORIAN | Controls the canonical .value returned by the component. Demo |
| input-type | 'GREGORIAN' \| 'JALALI' | locale based | Controls what date system users type and see in the calendar. Demo |
| format | string | YYYY-MM-DDTHH:mm:ss.SSS[Z] | Format used for .value, min, and max when value-type is GREGORIAN or JALALI. Demo |
| min | string | none | Minimum accepted date. Must use the configured value-type and format. Demo |
| max | string | none | Maximum accepted date. Must use the configured value-type and format. Demo |
| name | string | "" | Form field name. Demo |
| label | string | "" | Label forwarded to the internal jb-input. Demo |
| message | string | "" | Helper message forwarded to the internal jb-input. Demo |
| placeholder | string | null | Placeholder shown while the date value is empty. Demo |
| required | boolean | false | Enables required validation. Empty attribute and "true" mean true. Demo |
| disabled | boolean | false | Disables the internal input and sets the disabled custom state. Demo |
| error | string | "" | External validation error message. Demo |
| direction | 'ltr' \| 'rtl' | inherited | Direction forwarded to the internal calendar. Demo |
| show-persian-number | boolean | locale based | Displays Persian digits while .value remains English digits. Demo |
| size | 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' | md style defaults | Visual size forwarded to the internal jb-input. Demo |
| autocomplete | string | browser default | Forwarded to the internal jb-input. Demo |
| readonly | boolean | device based | Forwarded to the internal jb-input; mobile devices become readonly to favor the picker. Demo |
Properties
| name | type | readonly | description |
| --- | --- | --- | --- |
| value | string | no | Canonical value submitted with forms. Set with string, Date, or null. Demo |
| initialValue | string \| null | no | Default and reset value. It initializes value until the live value is explicitly set. Demo |
| valueInDate | Date \| null | yes | Current complete value as a JavaScript Date, or null when empty/incomplete. Demo |
| inputValue | string | yes | Visible typed text in YYYY/MM/DD display format. Demo |
| inputType | 'GREGORIAN' \| 'JALALI' | no | Date system used by the input UI and calendar. Demo |
| valueType | 'GREGORIAN' \| 'JALALI' \| 'TIME_STAMP' | no | Date system or timestamp mode used for .value. Demo |
| valueFormat | string | yes | Current value format. Change it with setFormat(). Demo |
| dateRestrictions | { min: Date \| null; max: Date \| null } | no | Runtime min/max restrictions used by validation and calendar. Demo |
| validation | ValidationHelper<ValidationValue> | yes | Validation helper from jb-validation; set validation.list for custom rules. Demo |
| isAutoValidationDisabled | boolean | no | Disables automatic validation when true. Demo |
| required | boolean | no | Enables required validation. Demo |
| disabled | boolean | no | Enables or disables the internal input. Demo |
| showPersianNumber | boolean | no | Displays Persian digits while .value remains English digits. Demo |
| showCalendar | boolean | no | Opens or closes the internal calendar popover. Demo |
| placeholder | string \| null | no | Placeholder shown while empty. |
| form | HTMLFormElement \| null | yes | Associated form from ElementInternals. Demo |
| isDirty | boolean | yes | true when current .value differs from initialValue. Demo |
| validationMessage | string | yes | Current validation message from ElementInternals. Demo |
| yearValue / monthValue / dayValue | number \| null | yes | Date parts in the configured valueType. Demo |
| yearDisplayValue / monthDisplayValue / dayDisplayValue | number \| null | yes | Date parts in the configured inputType. Demo |
| elements | ElementsObject | no | Internal input, calendar, popover, and calendarTriggerButton for advanced integrations. Demo |
Methods
| name | returns | description |
| --- | --- | --- |
| setFormat(newFormat) | void | Sets the value format used for .value, min, and max. Demo |
| setMinDate(minDate) | void | Sets or clears the minimum accepted date. Accepts string, Date, or null. Demo |
| setMaxDate(maxDate) | void | Sets or clears the maximum accepted date. Accepts string, Date, or null. Demo |
| setMonthList(inputType, monthName) | void | Overrides month labels for GREGORIAN or JALALI. Demo |
| setCalendarDefaultDateView(year, month, dateType?) | void | Sets the year/month shown when the value is empty. Demo |
| getDateValue(type?) | string | Returns current value in GREGORIAN, JALALI, or TIME_STAMP mode. Demo |
| focus() | void | Focuses the internal input and opens the calendar. Demo |
| setSelectionRange(start, end, direction?) | void | Forwards selection range to the internal input. Demo |
| checkValidity() | boolean | Runs validation without showing the error message. Dispatches invalid when invalid. Demo |
| reportValidity() | boolean | Runs validation and shows the first error message. Dispatches invalid when invalid. Demo |
| clearValidationError() | void | Clears the visible validation error. Demo |
| triggerInputValidation(showError?) | ValidationResult \| undefined | Deprecated; use checkValidity(), reportValidity(), or validation.checkValidity(). Demo |
Events
| event | description |
| --- | --- |
| load | Dispatched from connectedCallback before property initialization. Demo |
| init | Dispatched after internal components are defined and the initial value is applied. Demo |
| beforeinput | Cancelable event dispatched before typed input is applied. Demo |
| input | Dispatched after user typing changes the visible input text. Demo |
| change | Dispatched when the committed date value changes after blur or calendar selection. Canceling it reverts the date. Demo |
| select | Dispatched when the user selects a date from the calendar. Demo |
| focus | Re-dispatched when the internal input receives focus. Demo |
| blur | Re-dispatched when the internal input loses focus. Demo |
| keydown | Re-dispatched from the internal input. ArrowUp/ArrowDown change the selected date part. Demo |
| keyup | Re-dispatched from the internal input after the value object is updated. Demo |
| keypress | Re-dispatched from the internal input. Demo |
| invalid | Dispatched when checkValidity() or reportValidity() fails. Demo |
Value type and input type
input-type controls what users see and edit. value-type controls what developers receive from .value; compare the Jalali and Gregorian demo and value-type demo.
<!-- User sees Jalali, developer receives Gregorian ISO-like value. -->
<jb-date-input input-type="JALALI" value-type="GREGORIAN"></jb-date-input>
<!-- User sees Gregorian, developer receives Jalali formatted value. -->
<jb-date-input input-type="GREGORIAN" value-type="JALALI"></jb-date-input>
<!-- Developer receives a timestamp string. -->
<jb-date-input value-type="TIME_STAMP"></jb-date-input>const dateInput = document.querySelector('jb-date-input');
dateInput.inputType = 'JALALI';
dateInput.valueType = 'GREGORIAN';Value
Get and set value like a native input in the value demo.
const dateInput = document.querySelector('jb-date-input');
dateInput.value = '2024-01-15T00:00:00.000Z';
console.log(dateInput.value);
console.log(dateInput.valueInDate);
dateInput.value = new Date();
dateInput.value = null;Empty values are represented with an empty date in the configured format, for example 0000-00-00T00:00:00.000Z in the default Gregorian format. valueInDate returns null while the date is empty or incomplete.
Format
The default format is compatible with Date.prototype.toISOString(); see the custom format demo:
<jb-date-input value="2024-01-15T00:00:00.000Z"></jb-date-input>Use format when your backend needs a different string.
<jb-date-input
format="YYYY/MM/DD"
value="2024/01/15"
min="2024/01/01"
max="2024/12/29"
></jb-date-input>format also controls how string min and max are parsed. Set format before setting value, min, or max in JavaScript.
Min and max
Set date limits with attributes in the Gregorian min/max demo:
<jb-date-input
value="2020-08-10T08:51:23.176Z"
min="2020-08-05T08:51:23.176Z"
max="2020-08-15T08:51:23.176Z"
></jb-date-input>Or set them with JavaScript:
const dateInput = document.querySelector('jb-date-input');
dateInput.setMinDate(new Date());
dateInput.setMaxDate('2025-12-31T00:00:00.000Z');
dateInput.setMinDate(null);
dateInput.setMaxDate(null);min and max validation uses the configured valueType and format for string values.
Validation
jb-date-input uses jb-validation. Built-in validation handles required, error, min, and max; see the required and external error demos. Use validation.list for custom rules in the custom validation demo.
const dateInput = document.querySelector('jb-date-input');
dateInput.required = true;
dateInput.validation.list = [
{
validator: /^13.*$/g,
message: 'Date must be in the 13th century',
},
{
validator: ({ text, inputObject, valueObject, valueText }) => {
if (inputObject.year && inputObject.year < '1300') {
return 'Typed year must be 1300 or later';
}
return valueObject.jalali.day === 15;
},
message: 'Only the 15th day of the month is accepted',
},
];Custom validators receive:
| field | description |
| --- | --- |
| text | Visible input text in YYYY/MM/DD display format. |
| inputObject | Raw typed date parts before complete date conversion. |
| valueObject | Complete Gregorian, Jalali, timestamp, and time object. |
| valueText | Canonical .value. |
Calendar default date
When the input is empty, the calendar opens on the current month. Use setCalendarDefaultDateView() to change that view in the default calendar date demo.
const dateInput = document.querySelector('jb-date-input');
dateInput.setCalendarDefaultDateView(1360, 5);
dateInput.setCalendarDefaultDateView(1985, 8, 'GREGORIAN');
dateInput.setCalendarDefaultDateView(1360, 5, 'JALALI');Persian digits
<jb-date-input show-persian-number></jb-date-input>
<jb-date-input show-persian-number="true"></jb-date-input>
<jb-date-input show-persian-number="false"></jb-date-input>document.querySelector('jb-date-input').showPersianNumber = true;This affects display only. .value remains English digits; see the Persian number demo.
For app-wide locale, calendar, and numbering-system setup, configure jb-core/i18n.
Slots
Use the inline-start-section and inline-end-section slots in the inline sections demo, and customize calendar-trigger-icon in the custom icon demo.
| slot | description |
| --- | --- |
| inline-start-section | Content rendered at the start of the internal input box. |
| inline-end-section | Content rendered after the calendar trigger in the internal input end section. |
| calendar-trigger-icon | Custom calendar trigger icon. |
<jb-date-input label="Birthday">
<span slot="inline-start-section">Birthday</span>
<span slot="inline-end-section">optional</span>
</jb-date-input><jb-date-input>
<span slot="calendar-trigger-icon">open</span>
</jb-date-input>Month names
Override calendar month labels when your product needs custom locale names in the custom month name demo.
const dateInput = document.querySelector('jb-date-input');
dateInput.setMonthList('JALALI', [
'حَمَل',
'ثَور',
'جَوزا',
'سَرَطان',
'اَسَد',
'سُنبُله',
'میزان',
'عَقرَب',
'قَوس',
'جَدْی',
'دَلو',
'حوت',
]);
dateInput.setMonthList('GREGORIAN', [
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'11',
'12',
]);Overflow handler
When the calendar opens near the edge of a scroll area, configure the internal popover; compare the overflow handler and constrained parent demos.
const dateInput = document.querySelector('jb-date-input');
dateInput.elements.popover.overflowHandler = 'SLIDE';
dateInput.elements.popover.overflowDom = document.querySelector('.modal-body');CSS parts and variables
For complete styling guidance, live examples, and copyable style recipes, see the Styling docs and style gallery.
| part | description |
| --- | --- |
| input | Internal jb-input. |
| popover | Internal jb-popover. |
| calendar | Internal jb-calendar. |
| custom state | description |
| --- | --- |
| disabled | Applied when disabled is true. |
| invalid | Applied while a validation error is visible. |
jb-date-input {
--jb-date-input-margin: 1rem 0;
--jb-date-input-calendar-icon-color: #2563eb;
}
jb-date-input::part(input) {
--jb-input-border-radius: 0.5rem;
}
jb-date-input::part(popover) {
--jb-popover-bg-color: #ffffff;
--jb-popover-border-radius: 1rem;
--jb-popover-padding: 1rem;
--jb-popover-z-index: 1000;
}
jb-date-input::part(calendar) {
--jb-calendar-day-bg-color-selected: #2563eb;
--jb-calendar-day-color-selected: #ffffff;
}
jb-date-input:state(invalid)::part(input) {
--jb-input-border-color: #dc2626;
}Headless usage
Use the headless utilities when you want jb-date-input typing, caret, and date-string behavior in your own input component.
import {
emptyInputValueString,
getFixedCaretPos,
handleBeforeInput,
} from 'jb-date-input/module';For React, use the headless hook:
import { useJBDateInput } from 'jb-date-input/react';See the Headless demo and headless documentation for complete examples.
Accessibility notes
The standard input demo shows the labeled field used by assistive technologies.
- The component is form-associated and submits
.value. - The shadow root delegates focus to the internal
jb-input. label,message,required,disabled, and validation states are forwarded to the internal input or synchronized withElementInternals.- The calendar trigger is focusable and opens/closes the popover.
- On mobile, the internal input is set to readonly so users interact through the picker.
Related Docs
- See
jb-date-input/reactif you want to use this component in React. - See
jb-input,jb-calendar, andjb-popoverfor composed component APIs. - See All JB Design System Component List for more components.
- Use Contribution Guide if you want to contribute to this component.
AI agent notes
- Import
jb-date-inputonce before using<jb-date-input>. - Use
input-type/inputTypefor the date system the user sees. - Use
value-type/valueTypefor the canonical value returned by.value. - Set
formatbefore setting stringvalue,min, ormax. - Read
.valuefor form/submitted value and.valueInDatewhen a JavaScriptDateis needed. - Use
show-persian-numberonly for display;.valueremains English digits. - Use
inline-start-section,inline-end-section, andcalendar-trigger-iconslots. Do not usestart-sectionorend-sectiondirectly onjb-date-input. - Use
validation.listfor custom validation; validators receive{ text, inputObject, valueObject, valueText }. - This package includes
custom-elements.jsonand points to it with the package.jsoncustomElementsfield. The field is documented by the Custom Elements Manifest project in Referencing manifests from npm packages. - In
custom-elements.json,exports.kind: "js"describes JavaScript/TypeScript exports andexports.kind: "custom-element-definition"maps thejb-date-inputtag name toJBDateInputWebComponent.
