Skip to content

Fix period arrow keys hijacking custom-range calendar#6490

Open
sanne-san wants to merge 2 commits into
masterfrom
sanne-datepicker-shortcuts
Open

Fix period arrow keys hijacking custom-range calendar#6490
sanne-san wants to merge 2 commits into
masterfrom
sanne-datepicker-shortcuts

Conversation

@sanne-san

@sanne-san sanne-san commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Changes

  • On periods with < > controls (Today, Month to Date, Last Month, Year to Date, specific day/month/year), the document-level ArrowLeft/ArrowRight listener kept firing while the calendar popover was open, silently shifting the period and closing the calendar.
  • Suppress that listener whenever a flatpickr calendar is mounted, via a new isDateRangeCalendarOpen predicate on Keybind.shouldIgnoreWhen.
  • Added a regression test covering both directions: arrows still shift the period when the calendar is closed, and no longer do so while it's open.

Tests

  • Automated tests have been added

Changelog

  • Entry has been added to changelog

Documentation

  • This change does not need a documentation update

Dark mode

  • This PR does not change the UI

- On periods with `< >` controls (Today, Month to Date, Last Month, Year to Date, specific day/month/year), the document-level ArrowLeft/ArrowRight listener kept firing while the calendar popover was open, silently shifting the period and closing the calendar.
- Suppress that listener whenever a flatpickr calendar is mounted, via a new `isDateRangeCalendarOpen` predicate on `Keybind.shouldIgnoreWhen`.
- Added a regression test covering both directions: arrows still shift the period when the calendar is closed, and no longer do so while it's open.
@sanne-san sanne-san added bug Something isn't working preview labels Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Preview environment👷🏼‍♀️🏗️
PR-6490

1 similar comment
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Preview environment👷🏼‍♀️🏗️
PR-6490

@sanne-san sanne-san requested a review from a team July 8, 2026 08:59

@RobertJoonas RobertJoonas left a comment

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.

Tested on staging and it does what intended, so approving 👍

I feel like there's another side to actually making it work though -- the calendar doesn't automatically gain focus. For example, if I hit the down arrow right after opening the calendar, it'll start scrolling down the page (browser default). So even though left/right arrow keys are not affecting the rest of the page (which is correct of course), the keypresses are not registered by the calendar itself either. This is the behaviour I've experienced on Chrome and Safari at least.

expect(screen.getByText('July 2024')).toBeVisible()

await userEvent.keyboard('c')
await waitFor(() =>

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.

This should work fine without the waitFor wrapper. Everything that happens on keypress is synchronous.


return (
<NavigateKeybind
<Keybind

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.

Adding ignore conditions to NavigateKeybind sounds like something we might want to reuse later on, so we could extend the component with a new prop like shouldAlsoIgnoreWhen:

export function NavigateKeybind({
  keyboardKey,
  type,
  navigateProps,
  shouldAlsoIgnoreWhen = []
}: {
  keyboardKey: string
  type: KeyboardEventType
  navigateProps: AppNavigationTarget
  shouldAlsoIgnoreWhen?: Array<(event: KeyboardEvent) => boolean>
}) {
  const navigate = useAppNavigate()
  const handler = useCallback(() => {
    navigate({ ...navigateProps })
  }, [navigateProps, navigate])

  return (
    <Keybind
      keyboardKey={keyboardKey}
      type={type}
      handler={handler}
      shouldIgnoreWhen={[isModifierPressed, isTyping, ...shouldAlsoIgnoreWhen]}
      targetRef="document"
    />
  )
}

So here, we could still keep calling NavigateKeybind, just passing shouldAlsoIgnoreWhen = [isDateRangeCalendarOpen] as an extra prop.

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

Labels

bug Something isn't working preview

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants