Skip to content

Date picker: Don't clear value while user edits (closes #22738)#22996

Open
AndyButland wants to merge 2 commits into
v17/devfrom
v17/bugfix/22738-date-entry
Open

Date picker: Don't clear value while user edits (closes #22738)#22996
AndyButland wants to merge 2 commits into
v17/devfrom
v17/bugfix/22738-date-entry

Conversation

@AndyButland
Copy link
Copy Markdown
Contributor

@AndyButland AndyButland commented May 27, 2026

Description

When typing into a date property, the browser briefly reports an empty value while the typed digit doesn't yet form a valid date — e.g. a single 0 typed into a dd.MM.yyyy month segment before the second digit. uui-input.onInput reflected that empty value back into the underlying <input> via Lit's reactive .value binding, which programmatically clears all segments of a <input type="date"> — wiping the digit just typed and every other already-filled segment.

UmbInputDateElement now overrides onInput to skip the empty reflection while the user is editing, and a focusout listener syncs the value (and re-dispatches input/change) so an intentional clear still propagates.

Fixes #22738.

Testing

Automated

A test was added in input-date.test.ts covering the fix.

Manual

  1. Add a date property to a Document Type and edit content using that property.
  2. Enter a value such as 27.05.2026.
  3. Click into the month segment and type 0 (intending to enter 04).
  4. Verify the field still shows the date — typing the second digit (4) now leaves 27.04.2026 in place. Before this change, the first 0 keystroke wiped the whole input.
  5. Verify that the value is persisted correctly.

Copilot AI review requested due to automatic review settings May 27, 2026 14:11
@claude
Copy link
Copy Markdown

claude Bot commented May 27, 2026

Claude finished @AndyButland's task in 4m 10s —— View job


PR Review

Target: origin/v17/dev · Based on commit: 8e7c070b

Fixes a browser-specific edge case where <input type="date"> (and time/datetime-local) briefly reports value === '' during segment editing (e.g. typing 0 into the month field before the second digit). The prior code reflected that empty value back via Lit's reactive binding, clearing all filled segments. The fix overrides onInput to skip the empty reflection and uses a focusout listener to commit an intentional clear when focus leaves.

  • Other changes: Date inputs no longer clear while the user is mid-keystroke in a locale-formatted segment (e.g. dd.MM.yyyy in German). An intentional full clear is still committed on tab-out/blur.

Suggestions

  • input-date.element.ts:61UUIInputEvent.INPUT is dispatched unconditionally, even when target.value === '' and this.value was not updated. A consumer reading element.value inside their input handler will see the unchanged (stale) value — which produces correct downstream behaviour — but the event fires without any value change, which is semantically odd. Guarding the dispatch with the same condition would be cleaner (see inline comment). Fix this →

  • input-date.element.ts:37-44 — The focusout handler dispatches both INPUT and CHANGE when this.value !== native.value. If UUIInputElement also emits UUIInputEvent.CHANGE when it processes the native change event at blur (which fires before focusout), an intentional clear would produce two CHANGE events — the first with the stale value, the second with ''. Worth verifying against UUI source. If double-dispatch is confirmed, the native change listener in the parent could be suppressed or this handler could guard against it (e.g. by checking whether the native change event already propagated the correct empty value).

  • input-date.test.ts — Tests cover type="date" only. Since the element also supports type="time" and type="datetime-local", and transient-empty behaviour is consistent across these types, a brief note in the test file (or an additional test case) would make the intent more explicit to future maintainers.


Approved with Suggestions for improvement

Good to go — the core fix is correct, well-reasoned, and the three test cases cover the key scenarios described in the PR. The suggestions above are minor and don't block merging.

Labels applied: area/frontend, category/ux, category/ui

Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See overall summary in the Claude comment.

@claude claude Bot added area/frontend category/ux User experience category/ui User interface labels May 27, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a regression where typing into a native <input type="date"> (or time/datetime-local) caused the entire value to be wiped while the user was mid-edit. The browser reports a transiently empty .value for partial input (e.g. a single 0 in a month segment), and UUI's reactive value binding then programmatically cleared every segment. UmbInputDateElement now overrides onInput to skip reflecting empty values, and uses focusout to commit/clear once editing finishes.

Changes:

  • Override onInput in UmbInputDateElement to ignore transient empty native values, while still dispatching an input event.
  • Add a focusout listener that syncs value from the native input and dispatches input/change if the user committed an intentional clear.
  • Add regression tests covering the no-reflect, normal-reflect, and focusout-commits-clear paths; fix a typo ("demonination" → "denomination") in the class JSDoc.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/Umbraco.Web.UI.Client/src/packages/core/components/input-date/input-date.element.ts Add onInput override and focusout listener; fix JSDoc typo.
src/Umbraco.Web.UI.Client/src/packages/core/components/input-date/input-date.test.ts Add three regression tests for transient empty inputs and focusout commit behavior.

@leekelleher leekelleher self-requested a review May 28, 2026 13:23
Copy link
Copy Markdown
Member

@leekelleher leekelleher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested this out, it works when entering a zero 0 for the day and/or month parts, but not the year part. e.g. if I try to replace 2026 with 2025, the value will empty after I input 20.

I'll try look for a fix.

@AndyButland
Copy link
Copy Markdown
Contributor Author

Tested this out, it works when entering a zero 0 for the day and/or month parts, but not the year part. e.g. if I try to replace 2026 with 2025, the value will empty after I input 20.

Interesting. That's what the original report is about on the issue, but I couldn't seem to replicate that. I could type "2026" fine without anything tripping up on the "0". I would only see the issue typing a "0" for the month. Maybe there's a browser/operating system difference?

@leekelleher
Copy link
Copy Markdown
Member

I'm on Windows 11 / Chrome (148). Just tried with Firefox (151) and it all works as expected.

@AndyButland
Copy link
Copy Markdown
Contributor Author

AndyButland commented May 28, 2026

Also using Windows 11/Chrome - so actually that doesn't really explain it. I'll check again... no, seems I don't see it. Weird.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/frontend category/ui User interface category/ux User experience

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants