Skip to content

About

jalali date input with date picker support both touch screen for mobile user and keyboard typing for desktop user

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

65 stars

Watchers

2 watching

Forks

Repository files navigation

jb-date-input

Published on webcomponents.org GitHub license NPM Version GitHub Created At

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 .value in English digits.
  • Supports min and max date 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, or YYYY_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, and jb-popover internally.
  • 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-input
import '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
dir 'ltr' | 'rtl' inherited Native layout direction inherited by the input and 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
valueAsDate Date | null yes Current complete value as a JavaScript Date, or null when empty/incomplete. Demo
displayValue 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
isOpen 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
open() void Opens the internal calendar popover.
close() void Closes the internal calendar popover.
reset() void Restores initialValue and clears displayed validation.
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

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.valueAsDate);

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. valueAsDate 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 and inline-end slots in the inline sections demo, and customize calendar-trigger-icon in the custom icon demo.

slot description
inline-start Content rendered at the start of the internal input box.
inline-end 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">Birthday</span>
  <span slot="inline-end">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 with ElementInternals.
  • 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

AI agent notes

  • Import jb-date-input once before using <jb-date-input>.
  • Use input-type / inputType for the date system the user sees.
  • Use value-type / valueType for the canonical value returned by .value.
  • Set format before setting string value, min, or max.
  • Read .value for form/submitted value and .valueAsDate when a JavaScript Date is needed.
  • Use show-persian-number only for display; .value remains English digits.
  • Use inline-start, inline-end, and calendar-trigger-icon slots. Do not use inline-start or inline-end directly on jb-date-input.
  • Use validation.list for custom validation; validators receive { text, inputObject, valueObject, valueText }.
  • This package includes custom-elements.json and points to it with the package.json customElements field. 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 and exports.kind: "custom-element-definition" maps the jb-date-input tag name to JBDateInputWebComponent.

About

jalali date input with date picker support both touch screen for mobile user and keyboard typing for desktop user

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

65 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages