sveltelean Primitives
Versionv0.2.0 GitHub

Note For an application date field, with the date in a display format, a placeholder, a clear button, a calendar popup and ranges, use the Date picker. It keeps a native date input underneath, so its form value is the one this page describes.

Example

Date and time inputs
<label for="start">Start date</label>
<input id="start" type="date" name="start" min="2026-01-01" data-slean="date-field" />

<label for="at">Time</label>
<input id="at" type="time" name="at" step="900" data-slean="date-field" />

<label for="when">Date and time</label>
<input id="when" type="datetime-local" name="when" data-slean="date-field" />
Tier 0: the two sources differ only by the stylesheet import. The segments follow the reader’s locale; the value is always ISO. Everything here works with page JavaScript disabled.

Why this implementation exists

Date entry is where component libraries spend the most JavaScript: masks, parsers, segment focus, locale tables. The platform already does all of it in <input type="date">, with the value in ISO form whatever the locale shows, and min, max and step checked by the form.

Svelte Lean ships the field as it is, sized and colored from the tokens. Its interface is the browser’s: a dd/mm/yyyy mask with no placeholder and a picker glyph and popup that differ in every engine. Under ADR 0007 that is below the bar of an application field, so the Date picker draws one over the same native input; the date field stays for the places where the native control is the point.

The browser owns

  • segmented entry in the reader’s locale and the ISO value
  • min, max and step validation, :user-invalid after an edit
  • the platform picker and its keyboard
  • form participation and the label association

Svelte Lean owns

  • date-field.css: size, border, colors and the themed picker indicator
  • the contract
  • documentation; for an application date field with a formatted value, a clear button, a calendar popup and ranges, the Date picker

Usage

The markup needs no package. Install @svelte-lean/styles for the stylesheet; @svelte-lean/primitives adds the typed contract and nothing at runtime.

npm install @svelte-lean/styles
stylesheets
import '@svelte-lean/styles/date-field.css';

Use type="date" for a day, time with step in seconds for a time, datetime-local for both. month and week exist but are not in every browser (see below).

Bind the value with bind:value; it is a string in ISO form, or empty.

For a date field in an application interface (a display format, a placeholder, a clear button, a calendar popup, ranges and presets), use the Date picker.

Anatomy

PartElementdata-slean-partRequiredNotes
root<input type="date|time|datetime-local|month|week" data-slean="date-field">–yesA label through <label for> or aria-label; min, max and step for the constraints.

Runtime profile

Tier 0: the field has no behavior module, the Vite plugin maps date-field to no module, and the native-only fixture proves the path ships no Svelte Lean JavaScript.

Accessibility contract

  • A label through <label for>; a hint or an error through aria-describedby.
  • Each segment is focusable and announced by the browser; the platform picker is keyboard-operable.
  • :user-invalid marks a field only after the user edited it, so an untouched required field is not red.

Keyboard

KeyWhenResult
digitsfocus on a segmentTypes the segment and moves on (native)
ArrowUp/ArrowDownfocus on a segmentSteps the segment (native)
ArrowLeft/ArrowRightfocus in the fieldMoves between segments (native)

Platform features

FeatureBaselineOutside the target
date, time, datetime-localBaseline 2021A text input
month, weekNot Baseline: missing in Firefox and Safari desktopA text input; validate on the server
:user-invalidBaseline 2023No invalid border after an edit

Without JavaScript

Fully functional.

Server rendering

The value attribute in ISO form renders the initial value.

Before hydration

Nothing is attached; the field works before and after hydration alike.

Styling

date-field.css sizes the box to the control height, sets the border, background and text from the tokens, themes the picker indicator through color-scheme, and marks :user-invalid with the danger token. The tokens it reads:

TokenDefault (light)Applies to
--slean-control-height-md2.25remmin-block-size
--slean-space-30.75rempadding-inline
--slean-control-bordervar(--slean-border-strong)border
--slean-radius-md0.625remborder-radius
--slean-control-bgvar(--slean-surface)background
--slean-fgvar(--slean-neutral-12)color
--slean-color-schemelightcolor-scheme
--slean-text-sm0.875remfont-size
--slean-duration-fast100mstransition
--slean-easecubic-bezier(0.2, 0, 0, 1)transition
--slean-space-20.5remmargin-inline-start
--slean-control-border-hovervar(--slean-accent)border-color
--slean-control-border-focusvar(--slean-accent)border-color
--slean-control-ring0 0 0 3px color-mix(in oklch, var(--slean-accent) 22%, transparent)box-shadow
--slean-warningoklch(76% 0.16 80)border-color
--slean-control-ring-warning0 0 0 3px color-mix(in oklch, var(--slean-warning) 28%, transparent)box-shadow
--slean-dangeroklch(55% 0.2 25)border-color
--slean-control-ring-danger0 0 0 3px color-mix(in oklch, var(--slean-danger) 22%, transparent)box-shadow
--slean-control-border-disabledvar(--slean-border)border-color
--slean-control-bg-disabledvar(--slean-muted)background-color
--slean-fg-mutedvar(--slean-neutral-11)color
--slean-text-md1remfont-size

State selectors the stylesheet targets, all from the platform or ARIA: ::-webkit-calendar-picker-indicator, ::-webkit-datetime-edit-fields-wrapper, :disabled, :focus-visible, :hover, :user-invalid, [aria-invalid="true"].

Variant attributes: data-status (warning, error).

Compatibility notes

date, time and datetime-local are Baseline 2021. month and week fall back to a text input in Firefox and Safari desktop: validate the value on the server.

Testing

Source