Repository navigation
qt_quick: dateTimeInput has no calendar/date-picker widget, just a formatted text field #1024
Description
Summary
morph::ui::dateTimeInput promises a date (or date-and-time) input, but the Qt Quick backend's implementation, src/qt_quick/qml/MorphDateTimeInput.qml, is a plain TextField with a format-hinting placeholder ("yyyy-mm-dd" or "yyyy-mm-dd hh:mm") and C++-side parse/format on blur. There is no calendar popup, spinner, or any clickable date-picking affordance — the node's own file comment says as much: "A date, or a date and a time, typed in the display zone."
For an app author following a design that expects a real date picker (click a field, pick a day from a calendar), dateTimeInput does not deliver one; it is behaviorally identical to a textInput with a date-shaped placeholder and validation. This was surfaced by a downstream user (LASTRADA's LicenceServer) expecting dateTimeInput to give users a picker for seat/feature expiry dates, since the node's name and spec entry (docs/spec/ui/document.md ui/1 table) suggest exactly that.
Repro
Author any screen with ui::dateTimeInput(value, label). Run it on the Qt Quick frontend. Click the field: a text cursor appears, no calendar.
What's missing
- A calendar/date-picker popup (or at minimum an optional one, toggled by
modeor a new option) in the Qt Quick backend'sMorphDateTimeInput.qml, matching what a user would expect from a field called "date input" rather than "formatted text input." - Searched
src/qt_quick/qml/for any calendar component (grep -il calendar,datepick): none exists in the tree at the inspected revision.
Scope
- A spec decision in
docs/spec/ui/document.md(andbackend_contract.md) on whetherdateTimeInputshould default to a picker, opt into one via a new option, or whether a distinct node (datePicker?) is warranted instead of changingdateTimeInput's existing contract. src/qt_quick/qml/MorphDateTimeInput.qml: add a calendar popup (Qt Quick Controls hasCalendar/DatePicker-equivalent building blocks viaQtQuick.Controlsor a custom popup) triggered by a button/icon inside the field, writing back through the samefire("edit", text)path so the C++ side needs no change.- TUI backend (
src/tui/) parity, or an explicit decision that the picker is Qt-Quick-only (terminal apps reasonably keep typed dates).
Verification status
Reproduced by reading the code: src/qt_quick/qml/MorphDateTimeInput.qml (full file, 45 lines) is a MorphField wrapping one TextField; no Calendar, Popup, or date-grid component is instantiated or imported. include/morph/ui/author.hpp's dateTimeInput(value, label, commit) free function exposes no option that would change this (no mode, despite docs/spec/ui/document.md's ui/1 table listing mode as one of dateTimeInput's fields — the authoring convenience wrapper omits it). Not yet checked whether mode is read by the interpreter/view layer even though the author wrapper omits it (i.e. whether a hand-built document node with "mode" set would do anything differently) — worth confirming before scoping the fix, since if mode already exists in the document schema but is simply unexposed in author.hpp, the fix may be narrower than described above.
Activity
Yaraslaut commentedon Oct 21, 2026
Additional finding from trying to adopt
dateTimeInputfor a plain string-typed "YYYY-MM-DD" draft field (LicenceServer's seat/feature dates, stored asstd::string, not a timestamp type): it's not a drop-in replacement fortextInputeven setting the missing-picker issue aside.include/morph/ui/interpreter.hpp(~line 6061-6084), thedateTimeInputdocument-node handler:spec.value = slotProp<std::optional<time::Timestamp>>([element]() -> std::optional<time::Timestamp> { time::DateTime const* const instant = element->draft.get().asTimestamp(); return instant == nullptr ? std::nullopt : std::optional<time::Timestamp>{time::Timestamp{*instant}}; });The bound value must be (or convert to) a
time::Timestamp-shaped value viaasTimestamp(); a plain string draft value that isn't already in that internal timestamp representation reads back asnullopt, so the field never displays what was typed and never round-trips throughonCommit/onChangethe waytextInputdoes for the same kind of string field. Confirmed by swapping a workingtextInput-backed "YYYY-MM-DD" field todateTimeInputwith no other change:client.type(...)+ reading the value back afterward returned empty every time (both via the GUI automation driver and by eye).This means an app with dates modeled as plain ISO date strings (a common, reasonable choice, especially for apps with pre-existing string-based persistence) cannot use
dateTimeInputat all today, calendar widget aside — it would first need to migrate its draft/value model to whatevertime::Timestamp/asTimestamp()expects. Worth covering explicitly in the spec decision this issue asks for in its Scope section: eitherdateTimeInputshould also accept a plain ISO date/datetime string value (coercing it, the way other inputs coalesce loosely-typed drafts), or the docs should say plainly that a string-backed date field must convert to morph's timestamp type first, with an example of how.Yaraslaut commentedon Oct 22, 2026
Confirmed the open question in the verification status:
modealready exists in the document schema and is read by the interpreter (interpreter.hpp:spec.mode = onceText("mode") == "date" ? DateMode::Date : DateMode::DateTime), butauthor::dateTimeInput(value, label, commit)has no parameter for it and never writes the"mode"key — so a hand-authored document node with.put("mode", "date")set directly would already render date-only, while the public wrapper function cannot reach that path at all. The fix for this half of the gap is narrow: add amodeparameter (or anoptionsstruct matchingtextInput's pattern) toauthor::dateTimeInputthat writes"mode"when set to date-only. This is separate from the calendar-popup widget work tracked in this issue's main body — LicenceServer needs themodefix to show a date without inviting a time-of-day the underlying value never carries.Yaraslaut commentedon Oct 22, 2026
Found and fixed a second, independent bug in the calendar popup itself while verifying it end-to-end against a real click (not just reading the code):
MorphDateTimeInput.qml'sopenPicker()function setspicker.viewDate,picker.hour,picker.minuteandpicker.hasDaybefore callingpopup.open()-- but thePopup's actualidispopup, notpicker(every other reference in the file correctly usespopup.*). This is a plain reference-name typo:pickeris never declared anywhere, soopenPicker()throws aReferenceErroron its very first line and the function returns having never calledpopup.open(). Since QML swallows an exception thrown from a signal handler as a console-only warning, the calendar trigger renders and is clickable, but clicking it has had zero visible effect since the feature was written -- it looks like nothing happens, no error shown anywhere a normal diagnostic workflow (screenshots, log files, GUI test assertions) would catch, since the thrown exception never reaches any of those. Confirmed via a temporarytry { root.openPicker() } catch (e) { field.text = "ERROR:" + e }instrumentation: the caught value was exactlyReferenceError: picker is not defined. Fix is a 4-line rename (picker.->popup.) inopenPicker(); verified the popup opens and a day can be picked after the fix.Declarative UI fixes: panel onToggle, table showHeader, row virtualiz…
Expose dateTimeInput's mode through an options overload (#1024)
Yaraslaut commentedon Oct 23, 2026
Partially addressed by #1038, which leaves this issue open.
What #1038 does:
dateTimeInput()gains aDateTimeInputOptionsoverload that exposesmode. This answers the open question in this issue's verification status:modewas already in the document schema and handled by the interpreter. Only the positional author wrapper didn't expose it.What is still missing (the core of this issue): the Qt Quick backend still has no calendar or date picker. #1038 doesn't change
src/qt_quick/qml/MorphDateTimeInput.qml, so clicking the field still gives a text cursor. The spec decision in Scope item 1 (picker by default, a picker opted into viamodeor a new option, or a separate node) is also still open, and so is the TUI-parity decision.Verification status: inferred from the PR's diff (file list and
author.hpphunk), not from running the app.Close when: the Qt Quick
dateTimeInputoffers a clickable date-picking affordance, and the spec records how it is chosen.Four remaining declarative-UI issues: Ghost emphasis, overlay width, …
Give every graphical date input a calendar
Give every graphical date input a calendar