Skip to main content

max / makeover-webview

0.26.0: a date field is a date field Takes makeover-layout 0.15.0 and emits type="date" and type="datetime-local" for its two new kinds. Both submit the format the description names, DATE_FORMAT and DATETIME_FORMAT, so honouring it costs this renderer nothing. The regression it closes is one the description could not express until now: an expiry asked for as FieldKind::Text with a hint reading "YYYY-MM-DD", which loses the native picker, the platform's validation and the touch keyboard, and asks prose to do all three. Asserted both ways: each kind emits its own type, and neither emits type="text".
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-11 23:04 UTC
Signed with PGP, not checked
Commit: ceed741b8432d6f678e211ebdd6ffcbce9a5fc6c
Parent: 4710cd2
2 files changed, +21 insertions, -2 deletions
M Cargo.toml +2 -2
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "makeover-webview"
3 - version = "0.25.1"
3 + version = "0.26.0"
4 4 edition = "2024"
5 5 description = "The webview renderer for makeover-layout. Emits CSS, and is the one renderer that needs no palette: var() is the late binding, so resolution stays with the browser."
6 6 license = "MIT"
@@ -12,7 +12,7 @@
12 12 # patch satisfy the requirement and still fail to compile. That happened once
13 13 # with `form::radio_html` calling `FieldKind::Radio`, and makeover-build is where
14 14 # it surfaced, one release later.
15 - makeover-layout = "0.14.0"
15 + makeover-layout = "0.15.0"
16 16 # The capability axis. `makeover-touch` decides whether a hover rule should be
17 17 # gated at all; `makeover-geometry` spells the gate as a media condition. Both
18 18 # answers are owned elsewhere and neither is re-derived here.
M src/form.rs +19
@@ -166,6 +166,12 @@
166 166 FieldKind::Email => "email",
167 167 FieldKind::Url => "url",
168 168 FieldKind::Tel => "tel",
169 + // The same argument, and it buys more here than anywhere else in this
170 + // list: a native picker as well as the keyboard and the validation.
171 + // Both submit the format `makeover-layout` names, `DATE_FORMAT` and
172 + // `DATETIME_FORMAT`, so honouring it costs this renderer nothing.
173 + FieldKind::Date => "date",
174 + FieldKind::DateTime => "datetime-local",
169 175 FieldKind::Radio => "radio",
170 176 // Select and Textarea are not inputs at all; they never reach here.
171 177 // Radio is one, but it is emitted once per option by `radio_html` and
@@ -893,6 +899,8 @@
893 899 (FieldKind::Email, "email"),
894 900 (FieldKind::Url, "url"),
895 901 (FieldKind::Tel, "tel"),
902 + (FieldKind::Date, "date"),
903 + (FieldKind::DateTime, "datetime-local"),
896 904 ] {
897 905 let html = field_html(&field(kind), &Filling::default(), &Emit::default());
898 906 assert!(
@@ -902,6 +910,17 @@
902 910 }
903 911 }
904 912
913 + #[test]
914 + fn a_temporal_field_is_a_native_control_and_not_a_hinted_text_box() {
915 + // The regression this closes: described as text with a hint reading
916 + // "YYYY-MM-DD", which loses the picker, the platform's validation and
917 + // the touch keyboard, and asks prose to do all three.
918 + for kind in [FieldKind::Date, FieldKind::DateTime] {
919 + let html = field_html(&field(kind), &Filling::default(), &Emit::default());
920 + assert!(!html.contains(r#"type="text""#), "{kind:?} emitted {html}");
921 + }
922 + }
923 +
905 924 #[test]
906 925 fn no_prefix_leaves_the_id_as_the_name() {
907 926 let html = field_html(