Skip to content

Fix: Improve date input UX and prevent manual editing issues#591

Open
gurusatsangi wants to merge 1 commit intofossasia:mainfrom
gurusatsangi:date-fix
Open

Fix: Improve date input UX and prevent manual editing issues#591
gurusatsangi wants to merge 1 commit intofossasia:mainfrom
gurusatsangi:date-fix

Conversation

@gurusatsangi
Copy link
Copy Markdown
Contributor

@gurusatsangi gurusatsangi commented Apr 21, 2026

🔧 Fixes

Fixes #590


📌 Summary of Changes

  • Disabled manual typing in date inputs using readonly
  • Replaced input event with change event
  • Replaced focus with click to ensure picker opens every time
  • Prevented inconsistent cursor and overwrite behavior

🎯 Problem

Date inputs had poor UX:

  • Backspace broke format
  • Partial selection caused overwrite
  • Cursor behaved inconsistently
  • Picker sometimes opened only once

✅ Solution

  • Restricted input to date picker only
  • Improved event handling for consistent behavior
  • Ensured stable and predictable UX

📸 Demo

❌ Before (Bug)

2026-04-21.21-17-20.online-video-cutter.com.mp4

✅ After (Fix)

2026-04-22.00-15-53.online-video-cutter.com.mp4

🧪 Testing

  • Picker opens on every click
  • No manual typing allowed
  • No formatting issues
  • Works consistently

📝 Reviewer Notes

This change removes unreliable manual editing behavior caused by native date inputs and ensures a consistent, bug-free user experience.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Apr 21, 2026

Reviewer's Guide

This PR refines the date range inputs in the popup to rely solely on the native date picker, switching date change handling from input to change events, auto-opening the picker on click, capping selectable dates to today, and marking the inputs as read-only with pointer cursor styling to avoid manual typing issues and UX glitches.

Sequence diagram for date input click and change handling

sequenceDiagram
  actor User
  participant startingDateInput
  participant endingDateInput
  participant NativeDatePicker as NativeDatePicker
  participant scrumDateRangeUtils
  participant browserStorageLocal

  User->>startingDateInput: click()
  startingDateInput->>startingDateInput: showPicker()
  startingDateInput->>NativeDatePicker: open picker
  User->>NativeDatePicker: select starting date
  NativeDatePicker-->>startingDateInput: set value (change event)
  startingDateInput->>scrumDateRangeUtils: normalizeSyncAndPersistDateRange(startingDateInput, endingDateInput)
  scrumDateRangeUtils->>browserStorageLocal: set normalized date range

  User->>endingDateInput: click()
  endingDateInput->>endingDateInput: showPicker()
  endingDateInput->>NativeDatePicker: open picker
  User->>NativeDatePicker: select ending date
  NativeDatePicker-->>endingDateInput: set value (change event)
  endingDateInput->>scrumDateRangeUtils: normalizeSyncAndPersistDateRange(startingDateInput, endingDateInput)
  scrumDateRangeUtils->>browserStorageLocal: set normalized date range
Loading

File-Level Changes

Change Details Files
Handle date range updates on change events instead of input to align with picker-based interaction.
  • Replaced input listeners on starting and ending date fields with change listeners.
  • Kept normalization and persistence logic the same via window.scrumDateRangeUtils.normalizeSyncAndPersistDateRange.
src/scripts/popup.js
Ensure the native date picker opens reliably and restrict selectable dates to today or earlier.
  • Added click listeners on starting and ending date fields that call showPicker() when available.
  • Computed today’s ISO date and set it as the max attribute for both date inputs.
src/scripts/popup.js
Disable manual text entry in date inputs and visually indicate click-based interaction only.
  • Marked both date inputs as readonly to prevent keyboard editing.
  • Adjusted inline styles to set the cursor to pointer for both date inputs.
src/popup.html

Possibly linked issues

  • #[Bug] Fix inconsistent behavior in date inputs during manual editing: PR applies readonly, change, and click handling to date inputs, fixing the inconsistent manual editing behavior described.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions github-actions Bot added javascript Pull requests that update javascript code frontend extension labels Apr 21, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 3 issues, and left some high level feedback:

  • Setting the date inputs to readonly and relying on click + showPicker() may degrade keyboard accessibility (e.g., no typing or arrow-key changes); consider adding keyboard event handling (Enter/Space) or an alternative accessible control path for non-pointer users.
  • The new max constraint limiting both dates to today changes behavior by disallowing future dates; verify this aligns with the intended use cases and, if needed, allow configuring or relaxing this constraint.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Setting the date inputs to `readonly` and relying on `click` + `showPicker()` may degrade keyboard accessibility (e.g., no typing or arrow-key changes); consider adding keyboard event handling (Enter/Space) or an alternative accessible control path for non-pointer users.
- The new `max` constraint limiting both dates to `today` changes behavior by disallowing future dates; verify this aligns with the intended use cases and, if needed, allow configuring or relaxing this constraint.

## Individual Comments

### Comment 1
<location path="src/scripts/popup.js" line_range="1030" />
<code_context>
+		}
 		});
+		
+		const today = new Date().toISOString().split('T')[0];
+		startingDateInput.max = today;
+		endingDateInput.max = today;
</code_context>
<issue_to_address>
**issue (bug_risk):** Using `toISOString()` can produce an off-by-one day value in some timezones.

Because the `<input type="date">` value is interpreted in local time, the max value should be built from local date parts instead of UTC. Consider something like:

```js
const now = new Date();
const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
```

This keeps the max constraint aligned with the user’s actual local date.
</issue_to_address>

### Comment 2
<location path="src/scripts/popup.js" line_range="1018-1001" />
<code_context>
+		});
+
+		
+		startingDateInput.addEventListener('click', () => {
+		if (startingDateInput.showPicker) {
+			startingDateInput.showPicker();
+		}
+		});
+
+		endingDateInput.addEventListener('click', () => {
</code_context>
<issue_to_address>
**issue (bug_risk):** Combining `readonly` with `showPicker` can make the field unusable where `showPicker` is unsupported.

Because the inputs are `readonly` and only open via `showPicker`, environments without `HTMLInputElement.prototype.showPicker` will leave them non-interactive, so users can’t set dates. Consider conditionally removing `readonly` when `showPicker` is unavailable or providing an alternate date input UI in that case.
</issue_to_address>

### Comment 3
<location path="src/scripts/popup.js" line_range="1003-1006" />
<code_context>
-				endingDateInput,
-			);
+		
+		startingDateInput.addEventListener('change', () => {
+		window.scrumDateRangeUtils.normalizeSyncAndPersistDateRange(
+			startingDateInput,
+			endingDateInput
+		);
 		});
</code_context>
<issue_to_address>
**suggestion:** Consider also handling keyboard-based interactions for opening the date picker.

At the moment the picker only opens on `click`. For keyboard users—especially with a `readonly` input—this may not reliably trigger, depending on the browser. To make this more robust and accessible, also handle `keydown` (e.g., Enter/Space) on the focused input or use `focus` to trigger `showPicker` where appropriate.

Suggested implementation:

```javascript
		startingDateInput.addEventListener('change', () => {
			window.scrumDateRangeUtils.normalizeSyncAndPersistDateRange(
				startingDateInput,
				endingDateInput,
			);
		});

		// Improve keyboard accessibility for the date picker on the starting date input
		startingDateInput.addEventListener('keydown', (event) => {
			if (event.key === 'Enter' || event.key === ' ') {
				// Some browsers expose showPicker on input[type="date"]
				if (typeof startingDateInput.showPicker === 'function') {
					event.preventDefault();
					startingDateInput.showPicker();
				}
			}
		});

```

1. If the ending date input also opens a date picker via click elsewhere in this file, consider adding a similar `keydown` handler for `endingDateInput` to keep behavior consistent.
2. If there's already a shared function that handles opening the picker on click (e.g. `openDatePicker(input)`), you may want to reuse it in the `keydown` handler instead of calling `showPicker` directly, to keep all open-picker logic in one place.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/scripts/popup.js
}
});

const today = new Date().toISOString().split('T')[0];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

issue (bug_risk): Using toISOString() can produce an off-by-one day value in some timezones.

Because the <input type="date"> value is interpreted in local time, the max value should be built from local date parts instead of UTC. Consider something like:

const now = new Date();
const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;

This keeps the max constraint aligned with the user’s actual local date.

Comment thread src/scripts/popup.js
@@ -999,20 +999,39 @@ document.addEventListener('DOMContentLoaded', () => {
yesterdayRadio.addEventListener('change', () => {
browser.storage.local.set({ yesterdayContribution: yesterdayRadio.checked });
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

issue (bug_risk): Combining readonly with showPicker can make the field unusable where showPicker is unsupported.

Because the inputs are readonly and only open via showPicker, environments without HTMLInputElement.prototype.showPicker will leave them non-interactive, so users can’t set dates. Consider conditionally removing readonly when showPicker is unavailable or providing an alternate date input UI in that case.

Comment thread src/scripts/popup.js
Comment on lines +1003 to +1006
startingDateInput.addEventListener('change', () => {
window.scrumDateRangeUtils.normalizeSyncAndPersistDateRange(
startingDateInput,
endingDateInput
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: Consider also handling keyboard-based interactions for opening the date picker.

At the moment the picker only opens on click. For keyboard users—especially with a readonly input—this may not reliably trigger, depending on the browser. To make this more robust and accessible, also handle keydown (e.g., Enter/Space) on the focused input or use focus to trigger showPicker where appropriate.

Suggested implementation:

		startingDateInput.addEventListener('change', () => {
			window.scrumDateRangeUtils.normalizeSyncAndPersistDateRange(
				startingDateInput,
				endingDateInput,
			);
		});

		// Improve keyboard accessibility for the date picker on the starting date input
		startingDateInput.addEventListener('keydown', (event) => {
			if (event.key === 'Enter' || event.key === ' ') {
				// Some browsers expose showPicker on input[type="date"]
				if (typeof startingDateInput.showPicker === 'function') {
					event.preventDefault();
					startingDateInput.showPicker();
				}
			}
		});
  1. If the ending date input also opens a date picker via click elsewhere in this file, consider adding a similar keydown handler for endingDateInput to keep behavior consistent.
  2. If there's already a shared function that handles opening the picker on click (e.g. openDatePicker(input)), you may want to reuse it in the keydown handler instead of calling showPicker directly, to keep all open-picker logic in one place.

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

Labels

extension frontend javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Fix inconsistent behavior in date inputs during manual editing

1 participant