Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

DateEdit

DateEdit preview

DateEdit — text input + calendar popover, bound to Signal<Option<Date>>.

Public types

KindName
enumWidthPolicy — How a datetime widget claims horizontal space
enumValidationBehavior — How the date editor reacts to out-of-range or partially invalid input
structDateEdit — Single-line date input with optional calendar popover

Public functions

DateEdit

Detailed description

A single-line editable date field. The underlying surface is a TextInputField displaying the formatted date; commit on Enter or blur parses the input against the active pattern, clamps to [min_date, max_date], and writes the result back. A trailing calendar-icon button opens a Calendar popover anchored below the field for graphical date selection.

Behaviour

  • Value binding: Signal<Option<Date>> is the source of truth. External writes re-format the text. None shows the placeholder.
  • Pattern: locale-derived strftime-subset (%Y-%m-%d, %m/%d/%Y, …); override via format_pattern.
  • Step keys (preview-pass on the field): the step is segment-relative — it moves the field under the caret (year, month or day), which is what QDateTimeEdit does.
    • Arrow Up / Down → ±1 unit of that segment; Shift+ → ±10.
    • Page Up / Page Down → ±10 units; Shift+ → ±100.
    • Alt+ArrowDown (or click the calendar icon) → opens the calendar popover; Alt+ArrowUp closes it and F4 toggles it.
    • A chord holding Ctrl or Super is not the field's and falls through to the application.
  • Calendar popover: dismisses on click-outside or Escape, commits on cell click. The request carries no fade_duration, so it appears and goes without a fade.
  • Min / Max: clamps on commit and on step. Out-of-range values in the popover cell are disabled.

Accessibility

  • Container: Role::DateInput, named from the .label() builder, its value the selected day in full in the tree's locale ("samedi 2 mai 2026", "Saturday, May 2, 2026"), and set_placeholder when the value is None. The field inside shows the editable pattern; this value is written for someone listening, not for a parser. UIA and macOS expose it; AT-SPI carries a string value on no interface.
  • Calendar trigger button — Role::Button, named from its tooltip. set_has_popup(HasPopup::Grid) and set_expanded(open) sit on the container node above, not on the button.
  • Internally the editing surface remains a Role::TextInput for AT discoverability (so screen readers know it accepts text); the wrapper carries the DateInput role on the outer node. The field is where focus lands, so it carries the same name, and it is the composite's accessibility_proxy: an access_label or an access_described_by given to the DateEdit lands on the field. A labelled_by relation (a FormLayout row's) lands there too, but AccessKit reads a node's own name before its relations, so name a date field in a form with .label().
  • The calendar opens on the date the field holds (the text typed in it is committed first), on its days, whatever an earlier opening left.

Example

use teksilo::widgets::{DateEdit, common::datetime::Date};

let date = ctx.signal(Some(Date::constant(2026, 5, 2)));
ctx.add(
    DateEdit::new(date.clone())
        .min_date(Date::constant(2020, 1, 1))
        .max_date(Date::constant(2030, 12, 31))
        .label(lit!("Birth date")),
);

Touch and pen

Nothing to declare here, and the reason applies to the whole date/time family (TimeEdit, DateTimeEdit, DateRangeEdit): the composite's own handler set carries focus_within and on_key_preview only — no tap, no drag, no scroll — so its pointer surface is entirely the embedded text field, the trigger IconButton and the popover Calendar, each of which answers for itself. In particular the family does not declare touch_action(NONE): it produces no value from a press position, and declaring it would stop a finger scrolling a form that contains a date field.

Density

The picture above is the widget at TargetDensity::Compact, the mouse-and-keyboard ladder. Below is the same subject on the same canvas with only the ladder changed, so what moves is the density and nothing else — where the subject no longer fits, that is what the denser targets cost it at that size. See docs/density-and-targets.md.

Touch

DateEdit at Touch density

API reference

📖 Full rustdoc API for this module

pub enum WidthPolicy

Import: use teksilo::widgets::WidthPolicy;

How a datetime widget claims horizontal space.

Shared across DateEdit, TimeEdit, DateRangeEdit, and DateTimeEdit. For the two-half widgets the policy applies to the trailing half only — the leading half always sizes to its mask-derived natural width so the date never reflows when only the time half changes.

#![allow(unused)]
fn main() {
pub enum WidthPolicy { /* variants */ }
}

Variants

  • Default — Default. The widget claims its natural width: the mask-derived empty template (__/__/____ for ISO date, __:__ for 24h time) measured in the theme body font plus surrounding chrome. The footprint stays fixed as the user types — Int UI form-density convention. This is the Default.
  • Fill — The widget expands to fill the horizontal space its parent offers, instead of capping at the natural mask width. Use inside toolbars, inspector panels, or an Expand::horizontal column that should stretch with the surrounding layout.

pub enum ValidationBehavior

Import: use teksilo::widgets::date_edit::ValidationBehavior;

How the date editor reacts to out-of-range or partially invalid input.

#![allow(unused)]
fn main() {
pub enum ValidationBehavior { /* variants */ }
}

Variants

  • AutoCorrect — Out-of-range inputs are clamped to the nearest valid value (e.g. 12/50/2026 → 12/31/2026) and announced via Live::Polite. Matches macOS Calendar and iOS DatePicker. This is the Default.
  • Reject — Out-of-range inputs are rejected with an inline error message; the field's text is left as-typed so the user can correct it. The bound value is unchanged until a valid date is committed. Matches Excel / Material strict-validation patterns. Use for high-precision contexts where silently rounding is unacceptable.

pub struct DateEdit

Import: use teksilo::widgets::DateEdit;

Single-line date input with optional calendar popover. See the module docs for the full feature list.

#![allow(unused)]
fn main() {
pub struct DateEdit { /* fields */ }
}

Methods

pub fn new(value: Signal<Option<Date>>) -> Self

Construct a date editor bound to a nullable date signal.

pub fn style(mut self, style: impl teksilo_core::styles::DateEditStyle) -> Self

Per-call style override for the date-edit chrome.

pub fn required(value: Signal<Date>) -> Self

Construct from a non-nullable date signal. Internally backed by a Signal<Option<Date>> proxy that mirrors the source in both directions. The placeholder is normally unused — the proxy is initialized to Some(value.get()), and only goes None transiently when a commit clears the text (the mirror then leaves the source alone until the next valid commit re-establishes it).

pub fn min_date(mut self, d: Date) -> Self (default: None)

Clamp the selectable range from below. Dates earlier than d are clamped up to d on commit and on step, and are shown as disabled in the calendar popover.

pub fn max_date(mut self, d: Date) -> Self (default: None)

Clamp the selectable range from above. Dates later than d are clamped down to d on commit and on step, and are shown as disabled in the calendar popover.

pub fn format_pattern(mut self, pat: impl Into<String>) -> Self (default: None)

Override the locale-derived format pattern (strftime subset, see crate::common::datetime::pattern).

pub fn placeholder(mut self, text: impl Into<LocalizedString>) -> Self

Text displayed when the bound value is None. Defaults to empty (no placeholder rendered).

pub fn first_day_of_week(mut self, w: Weekday) -> Self

Override which weekday heads the calendar's column grid. Defaults to the locale's convention if not set.

pub fn show_calendar_button(mut self, show: bool) -> Self

Show or hide the trailing calendar-icon trigger button that opens the calendar popover. Default true.

pub fn calendar_popover_placement(mut self, p: OverlayPlacement) -> Self

Override where the calendar popover appears relative to the field. Default is OverlayPlacement::BelowPreferred.

pub fn enabled(mut self, enabled: impl Into<Prop<bool>>) -> Self (default: true)

Set the enabled state, statically or reactively. Forwarded to the arena at build time.

pub fn read_only(mut self, read_only: bool) -> Self (default: false)

Make the field read-only: text is selectable and copyable but not editable, and step keys are suppressed.

pub fn validation_behavior(mut self, behavior: ValidationBehavior) -> Self

How parse failures are surfaced. Default ValidationBehavior::AutoCorrect (clamp + announce); switch to ValidationBehavior::Reject for strict-validation form contexts.

pub fn width_policy(mut self, policy: WidthPolicy) -> Self

How the widget claims horizontal space. Default WidthPolicy::Default — the field sizes to its natural mask-derived width. Switch to WidthPolicy::Fill to make the field stretch to fill the parent's offered width (toolbar / inspector pattern).

pub fn validation_feedback_signal(&self) -> Signal<ValidationFeedback>

Reactive handle on the live validation feedback (mirrored from the inner field). Composites that want to render their own feedback UI elsewhere can bind to this; the default ValidationStrip slot below the field uses it internally.

pub fn label(mut self, label: impl Into<LocalizedString>) -> Self

Set the accessible label for the field (also shown by any paired FormLayout label slot). Defaults to the localized "Date" string.

pub fn on_value_changed( mut self, f: impl Fn(Option<Date>, &mut EventContext) + 'static, ) -> Self

Register a callback fired on every committed value change with the new Option<Date> and a live EventContext. Fires only on user-driven commits (typing + blur, Enter, calendar selection), not on external writes to the bound signal.

pub fn value(&self) -> Signal<Option<Date>>

Return a clone of the bound value signal for external observation.

pub fn tooltip(mut self, text: impl Into<LocalizedString>) -> Self

Attach a plain single-line tooltip shown after a hover delay. Mutually exclusive with Self::rich_tooltip, Self::rich_tooltip_content, and Self::composite_tooltip — this call clears those slots.

pub fn rich_tooltip(mut self, key: impl Into<String>) -> Self

Attach a rich tooltip looked up by registry key. Mutually exclusive with Self::tooltip, Self::rich_tooltip_content, and Self::composite_tooltip — this call clears those slots.

pub fn rich_tooltip_content(mut self, content: crate::tooltip::TooltipContent) -> Self

Attach a rich tooltip from inline content. Mutually exclusive with Self::tooltip, Self::rich_tooltip, and Self::composite_tooltip — this call clears those slots.

pub fn composite_tooltip(mut self, content: impl Widget + 'static) -> Self

Attach a composite tooltip whose body is an arbitrary widget tree. Mutually exclusive with Self::tooltip, Self::rich_tooltip, and Self::rich_tooltip_content — this call clears those slots.