npm.io
6.0.30 • Published 1 month ago

@dreamworld/dw-date-input

Licence
ISC
Version
6.0.30
Deps
7
Size
100 kB
Vulns
0
Weekly
0

@dreamworld/dw-date-input

A LitElement-based web component (<dw-date-input>) that provides a text field for date entry with smart auto-formatting, built-in validation (required, min/max date, future date), and an integrated Litepicker calendar popover for desktop and full-screen modal for mobile/tablet.


1. User Guide

Installation & Setup

yarn add @dreamworld/dw-date-input
Basic Usage
import '@dreamworld/dw-date-input/dw-date-input.js';
<dw-date-input
  label="Start Date"
  placeholder="DD/MM/YYYY"
  required
  value="2024-01-15"
  @change=${(e) => console.log(e.detail.value)}
></dw-date-input>

The value property is always read/written in valueFormat (default YYYY-MM-DD). The user types in inputFormat (default DD/MM/YYYY). The component converts between the two automatically.


API Reference
Props — <dw-date-input>
Name Type Default Required Description
name String "" No Name attribute forwarded to the inner input element.
value String "" No Current date value in valueFormat. Set this to pre-fill the field.
label String No Floating label shown above the input.
placeholder String "" No Placeholder text shown inside the input.
disabled Boolean false No Disables the input.
readOnly Boolean false No Makes the input read-only. Clicking will not open the calendar picker.
required Boolean false No Marks the input as required. Validation fails when empty.
noLabel Boolean false No Hides the label.
hint String "" No Helper text shown below the input.
hintPersistent Boolean false No When true, hint text is always visible regardless of focus.
noHintWrap Boolean false No Constrains hint text to a single line.
dense Boolean false No Applies dense (compact) styling.
autoSelect Boolean true No Auto-selects the text content when the input is focused.
inputFormat String "DD/MM/YYYY" No Format the user types in. Accepted values: DD/MM/YYYY, MM/DD/YYYY, DD-MM-YYYY, MM-DD-YYYY, etc. Case-insensitive.
valueFormat String "YYYY-MM-DD" No Format used for the value property and change event.
dateRepresentationFormat String "DD MMM YYYY" No Format used to display the selected date in the calendar picker header.
minDate String No Minimum allowed date (inclusive), in valueFormat. Dates before this trigger a validation error.
maxDate String No Maximum allowed date (inclusive), in valueFormat. Dates after this trigger a validation error.
showFutureError Boolean false No When true, selecting a future date is a validation error.
showFutureWarning Boolean false No When true, selecting a future date shows a warning (suppressed when an error is active).
supportRelativeDate Boolean false No When true, typing +N, -N, or +0 resolves to base date ± N days on blur, Enter, or paste. Resolution happens before validation, so minDate/maxDate/showFutureError apply to the resolved date.
relativeDateBase String No Anchor date (in valueFormat) used by supportRelativeDate. When omitted or unparseable, today is used as the base.
invalid Boolean false No Reflects the last validation result. Set externally to force an invalid state.
originalValue String "" No Reference value used with highlightChanged to detect user modifications.
highlightChanged Boolean false No When true and value !== originalValue, applies a visual highlight. Requires originalValue to be set.
error String | Function | Object No Custom error message or function. Overrides internal validation display.
warning String | Function | Object No Custom warning message or function.
errorMessages Object See below No Per-instance override of the default error message strings.
hintInTooltip Boolean No When true, shows the hint inside a tooltip on the trailing icon instead of inline.
errorInTooltip Boolean No When true, shows the error inside a tooltip on the trailing icon instead of inline.
warningInTooltip Boolean No When true, shows the warning inside a tooltip on the trailing icon instead of inline.
hintTooltipActions Array No Action buttons to render inside the hint tooltip.
errorTooltipActions Array No Action buttons to render inside the error tooltip.
warningTooltipActions Array No Action buttons to render inside the warning tooltip.
tipPlacement String "bottom-end" No Tippy.js placement for all tooltips. See Tippy.js placement docs.
tipExtraOptions Object No Extra options forwarded directly to Tippy.js.
iconTrailing String "date_range" No Material icon name for the trailing icon that opens the calendar.
mobileMode Boolean false No When true, the calendar opens as a full-screen modal. Input is pointer-events disabled.
tabletMode Boolean false No When true, applies tablet-specific layout. Input is pointer-events disabled.
zIndex Number 9999 No z-index of the calendar popover.
appendTo String | Element "parent" No DOM element (or "parent") to which the popover is appended.
triggerElement Element (auto) No Element used as the popover anchor. Defaults to the internal date-input element.

Events
Event detail Shape Description
change { value: string } Fired when the date value changes — on blur, paste, Enter key, or calendar date selection. value is in valueFormat, or "" for an invalid/cleared entry.
enter { value: string } Fired when the user presses Enter inside the text field.
date-picker-opened Fired when the calendar popover/modal opens.
date-picker-closed Fired when the calendar popover/modal closes.

Instance Methods
Method Returns Description
focus() Promise<void> Focuses the inner text field. Async — awaits updateComplete.
validate() Boolean Alias for reportValidity().
reportValidity() Boolean Triggers validation and updates the invalid state. Returns true if valid.
checkValidity() Boolean Returns true if the current value passes all validation rules without updating the UI.

Static Methods
Method Parameters Description
DwDateInput.setErrorMessages(messages) messages: Object Merges messages into the global default error messages. Affects all <dw-date-input> instances that do not override errorMessages.

Validation & Error Messages

Default error messages (can be overridden globally via setErrorMessages or per-instance via the errorMessages prop):

{
  minDate:       "Must be > {minDate}",
  maxDate:       "Must be < {maxDate}",
  minMaxDate:    "Date must be between {minDate} and {maxDate}",
  invalidDate:   "Date is invalid",
  showFutureError: "Future date is not allowed."
}

The placeholders {minDate} and {maxDate} are replaced at runtime with the actual minDate/maxDate prop values.

The warning produced by showFutureWarning is hardcoded to "Future date is selected" in date-input.js and is not configurable via errorMessages.


CSS Custom Properties
Property Default Description
--dw-date-input-padding 12px 16px 14px Padding of the <input> element inside the outlined text field.
--dw-popover-border-radius 18px Border-radius of the calendar popover surface.
--dw-popover-width 360px Width of the calendar popover.
--dw-popover-min-width 360px Minimum width of the calendar popover.
--mdc-theme-primary (MDC theme) Color applied to the trailing calendar icon and active states when the picker is open.
--mdc-theme-surface (MDC theme) Calendar surface background.
--mdc-theme-text-primary-on-surface (MDC theme) Primary text color inside the calendar.
--mdc-theme-text-secondary-on-surface (MDC theme) Secondary text color (day-of-week label in header).
--mdc-theme-divider-color (MDC theme) Color of the divider line below the calendar header.

Advanced Usage
Pre-filled value with change highlight
html`
<dw-date-input
  label="Start Date"
  .value=${"2024-06-01"}
  .originalValue=${"2024-06-01"}
  highlightChanged
  @change=${(e) => console.log('New value:', e.detail.value)}
></dw-date-input>
`

When the user changes the date, the field is visually highlighted. Restoring to originalValue removes the highlight.


Min/Max date constraint
<dw-date-input
  label="Booking Date"
  min-date="2024-01-01"
  max-date="2024-12-31"
></dw-date-input>

Or in JavaScript (property binding):

el.minDate = '2024-01-01';
el.maxDate = '2024-12-31';

Blocking future dates
<!-- Error if future date is entered -->
<dw-date-input show-future-error></dw-date-input>

<!-- Warning (non-blocking) if future date is entered -->
<dw-date-input show-future-warning></dw-date-input>

Tooltip mode for hint/error/warning
html`
<dw-date-input
  label="Date"
  hint="Enter date in DD/MM/YYYY"
  hintInTooltip
  .warning=${"Selected date is in the past"}
  warningInTooltip
></dw-date-input>
`

Global error message customization
import { DwDateInput } from '@dreamworld/dw-date-input/dw-date-input.js';

DwDateInput.setErrorMessages({
  invalidDate: 'Please enter a valid date.',
  minDate: 'Date must be on or after {minDate}.',
});

Custom inputFormat
<!-- US format -->
<dw-date-input input-format="MM/DD/YYYY" label="Date"></dw-date-input>

<!-- ISO input -->
<dw-date-input input-format="YYYY-MM-DD" label="Date"></dw-date-input>

Mobile / Tablet mode
<!-- Full-screen calendar modal on mobile -->
<dw-date-input mobile-mode label="Date"></dw-date-input>

<!-- Tablet layout -->
<dw-date-input tablet-mode label="Date"></dw-date-input>

In these modes, the <input> element is pointer-events disabled; date entry is only possible through the calendar or dialog.


Arrow-key date increment

When the text field is focused and contains a valid date, pressing Arrow Up increments the date by 1 day and Arrow Down decrements by 1 day. If the field is empty, Arrow Up/Down sets the value to today's date.


Relative date shortcuts
<!-- Resolve +N / -N against today -->
<dw-date-input support-relative-date label="Due Date"></dw-date-input>

<!-- Resolve against an explicit base date (e.g., a transaction date) -->
<dw-date-input
  support-relative-date
  .relativeDateBase=${"2024-06-01"}
  label="Due Date"
></dw-date-input>

When supportRelativeDate is true, the user can type +N, -N, or +0 and the input is replaced on blur/Enter/paste with the resolved date:

  • +5 → base date + 5 days
  • -10 → base date − 10 days
  • +0 / -0 → base date

If relativeDateBase is set (in valueFormat), it acts as the anchor; otherwise today is used. An unparseable relativeDateBase silently falls back to today.

The regex is strict — + 5, ++5, bare +, etc. are not treated as relative-date input and fall through to normal date parsing. The resolved date is then run through standard minDate/maxDate/showFutureError validation.


dateParse(value, format) Utility
import { dateParse } from '@dreamworld/dw-date-input/date-parse.js';

const result = dateParse('25 Jan 2024', 'DD/MM/YYYY');
// Returns: "25/01/2024"

Parameters:

Parameter Type Description
value String Raw user input in any supported format (see below).
format String Target dayjs-compatible format string the result should be returned in.

Returns: String — the parsed date in format, or null if the input cannot be parsed.

Supported input formats:

Category Examples
Slash-separated DD/MM/YYYY, MM/DD/YYYY, D/M/YYYY
Dash-separated DD-MM-YYYY, MM-DD-YYYY
ISO YYYY-MM-DD, YYYY/MM/DD
Spaced separators DD / MM / YYYY, MM / DD / YYYY, YYYY - MM - DD
Month name (abbrev.) DD MMM YYYY, DD MMM, YYYY, MMM DD YYYY, MMM DD, YYYY
Month name (full) MMMM D, YYYY, MMMM DD, YYYY
Numeric only 1212 → auto-parsed as day+month using inputFormat
Year-omitted 25 Jan, 01/15 → current year is auto-filled

Behavior notes:

  • Month names are case-insensitive.
  • For numeric-only input, day/month order follows the provided format.
  • If day and month values exceed valid ranges, the parser swaps them automatically.
  • Two-digit years (24) are expanded to 2024.

currentYearFormat Constant
import { currentYearFormat } from '@dreamworld/dw-date-input/constants.js';

Maps a full-year date format to its corresponding current-year (year-omitted) format.

Full format Year-omitted format
DD-MM-YYYY DD-MM
DD/MM/YYYY DD/MM
MM/DD/YYYY MM/DD
MM-DD-YYYY MM-DD
YYYY/MM/DD MM/DD
YYYY-MM-DD MM-DD
DD MMM YYYY DD MMM
MMM DD, YYYY MMM DD

2. Developer Guide / Architecture

Component Hierarchy
DwDateInput  <dw-date-input>          extends DwFormElement(LitElement)
├── DateInput  <date-input>            extends DwInput  (internal text field)
│   ├── dw-icon-button                 (trailing calendar icon)
│   └── dw-tooltip                    (conditional hint/error/warning tooltip)
├── DwDatePicker  <dw-date-picker>     extends DwCompositeDialog  (lazy — rendered only when _pickerOpened)
│   ├── Litepicker instance            (inline calendar, keyboardnav + mobilefriendly plugins)
│   ├── DwDateInput                    (edit mode input inside picker header)
│   └── dw-button (Cancel / Apply)    (edit mode actions)
└── DwDateInputDialog <dw-date-input-dialog>  extends DwCompositeDialog  (modal for mobile/tablet)
    ├── DateInput  <date-input>
    └── dw-button (Cancel / Apply)
Module Responsibilities
File Exported Name Role
dw-date-input.js DwDateInput Orchestrator. Owns value state, format normalization, validation delegation, picker lifecycle.
date-input.js DateInput Low-level text field. Handles raw input, dateParse on blur/paste/Enter, arrow-key date change, format display, and validation error/warning computation.
dw-date-picker.js DwDatePicker Litepicker-based calendar dialog (popover on desktop, modal on mobile). Manages picker instance lifecycle.
dw-date-input-dialog.js DwDateInputDialog Modal dialog wrapping a DateInput for explicit Apply/Cancel flow. Emits mode-changed when switching to the calendar.
date-parse.js dateParse Pure utility. Parses freeform date strings into a specified dayjs format.
constants.js currentYearFormat Static map from full formats to year-omitted equivalents.
Design Patterns

Mixin — DwFormElement DwDateInput applies the DwFormElement mixin from @dreamworld/dw-form, integrating it into form validation workflows (checkValidity, reportValidity).

Composition via Lit templates DwDateInput.render() conditionally composes three sub-templates: dateInputTemplate (always rendered), datePickerTemplate (rendered only when _pickerOpened === true), and dateInputDialogTemplate. This lazy-renders the heavy Litepicker calendar.

Strategy pattern — _error / _warning getters DwDateInput exposes _error and _warning as overridable getters. Subclasses can extend DwDateInput, override these getters to inject additional validation logic, and call super to preserve the base behaviour. This avoids conflicts with the public error/warning props that integrators use.

Format normalization All format strings (inputFormat, valueFormat, dateRepresentationFormat) are uppercased internally (_inputFormat, _valueFormat, _dateRepresentationFormat) in willUpdate. This means props are accepted case-insensitively (dd/mm/yyyy and DD/MM/YYYY are both valid).

Development Server
yarn start
# Launches @web/dev-server with demo/index.html