Skip to main content

Module date_range_edit

Module date_range_edit 

Source
Expand description

DateRangeEdit — single unified control for picking a DateRange.

Visually one widget: a single bordered frame containing two TextInputField halves separated by a painted arrow glyph, with a trailing built-in calendar button that opens a shared Calendar::range popover. Backed by Signal<Option<DateRange>>.

┌──────────────────────────────────────┐
│ 05/12/2026   →   05/19/2026   │ 📅  │
└──────────────────────────────────────┘

§Why one frame?

Two adjacent DateEdits (one frame each) visually read as two separate fields that happen to be next to each other. A single frame says “this is one range”. Same affordance the user is used to from booking sites and analytics dashboards.

§Behaviour

  • Two text halves — each masked from the resolved date pattern, each with its own validator + segment-stepping (Up/Down on the focused segment matches DateEdit).
  • Painted arrow separator — a thin chevron-right glyph, no text. Visual only; AT users see the wrapper’s Role::DateInput.
  • One trailing calendar button — Int UI IconButton::embedded() with the calendar glyph. Opens a single popover hosting Calendar::range bound to the outer signal. The two-anchor click model (start-then-end) commits the range and closes the popover. No per-half calendar buttons — there’s only one calendar, anchored to the wrapper.
  • One frame — focus-aware border (BorderRole::Focused while any half holds focus, otherwise Default), validation-aware border (Error for Invalid, Focused for Corrected).
  • One validation strip below the frame — composed feedback from both halves (worse of the two wins).

§Accessibility

  • Container — Role::DateInput with set_value formatted as YYYY-MM-DD/YYYY-MM-DD (ISO range).
  • Each TextInputField keeps its own Role::TextInput AT node; the wrapper’s Role::DateInput provides the range semantics.
// Requires ctx.signal() — shown as ignore per convention.
use teksilo_widgets::date_range_edit::DateRangeEdit;
use jiff::civil::Weekday;

let range = ctx.signal(None);
let _w = DateRangeEdit::new(range.clone())
    .first_day_of_week(Weekday::Monday)
    .on_value_changed(|r, _ctx| println!("{r:?}"));

Structs§

DateRangeEdit
Two-handle date picker over Signal<Option<DateRange>>. See the module docs for the visual layout and behaviour.