Skip to content

Conversation

alexfauquette
Copy link
Member

@alexfauquette alexfauquette commented Aug 12, 2025

Introduce keyboard navigation

The data format is fairly similar to the highlight plugin

Rendering aspect

  • The line series get a dedicated component to show the highlighted point since marks are not always rendered.
  • All the other series implemented use the outlined: 'auto' property to show the focus position. And they rely on data-focused=true for that.

Focus management

  • Zoom is not taken into account. Should we loop only on visible points, or move the zoom to have the focused element inside the drawing area?
  • The vocal assistant strategy I'm planning to use is to use aria-activedescendent to keep the focus on the SVG and target specific items like I'm already doing it with data-focused=true. I will probably add an id attribute only on the element of interest.
  • Will need an option to disable this keyboard navigation, such that user can do whatever they want. For eample the npm sparkline reproduction will be broken because of this feature (the focus can not be handled at the same time by the SVG and a parent div)

@alexfauquette alexfauquette added the scope: charts Changes related to the charts. label Aug 12, 2025
@mui-bot
Copy link

mui-bot commented Aug 12, 2025

Deploy preview: https://deploy-preview-19155--material-ui-x.netlify.app/

Updated pages:

Bundle size report

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) ▼-9B(-0.01%)
@mui/x-data-grid-premium 0B(0.00%) ▼-5B(0.00%)
@mui/x-charts 🔺+6.01KB(+1.90%) 🔺+1.48KB(+1.50%)
@mui/x-charts-pro 🔺+6.02KB(+1.47%) 🔺+1.42KB(+1.11%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) ▼-3B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) ▼-2B(-0.01%)

Details of bundle changes

Generated by 🚫 dangerJS against 8e7536a

Copy link

codspeed-hq bot commented Aug 13, 2025

CodSpeed Performance Report

Merging #19155 will not alter performance

Comparing alexfauquette:keyboard-navigation (8e7536a) with master (74f8873)1

Summary

✅ 12 untouched

Footnotes

  1. No successful run was found on master (5d22c6f) during the generation of this report, so 74f8873 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@alexfauquette alexfauquette added accessibility a11y type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. labels Aug 21, 2025
@alexfauquette alexfauquette changed the title [charts][WIP] Introduce keyboard navigation [charts] Introduce keyboard navigation Aug 21, 2025
@alexfauquette alexfauquette marked this pull request as ready for review August 21, 2025 14:25
Comment on lines 8 to 21
export const selectorChartsFocusedSeriesType = createSelector(
[selectKeyboardNavigation],
(item) => item?.type,
);

export const selectorChartsFocusedSeriesId = createSelector(
[selectKeyboardNavigation],
(item) => item?.seriesId,
);

export const selectorChartsFocusedDataIndex = createSelector(
[selectKeyboardNavigation],
(item) => item?.dataIndex,
);
Copy link
Member

Choose a reason for hiding this comment

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

Should we already account for non-regular identifiers here? 😉

This feels a bit static if we consider the identifier is configurable. Maybe we can have a more generic selector with a proper memo function? 🤔

Maybe we should have a compareIdentifier in the series config 💡

Copy link
Member Author

Choose a reason for hiding this comment

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

This feels a bit static if we consider the identifier is configurable

I assume you have scatter charts in mind ;)

The identifier will not be the biggest issue. it's the keyboard actions. For those who does not enter in the (seriesId, dataIndex) identifier framework, it might be easier to create a custom plugin for their keyboard navigation.

}

element.addEventListener('keydown', keyBoardHandler);
element.addEventListener('focus', focusNextItem);
Copy link
Member

Choose a reason for hiding this comment

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

I don't think focus should do anything 🤔

With focus whenever a user clicks anywhere in the chart, the first item will be selected, which I think is quite odd.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's inspired by ARIA guidelines from the data grid. When the element get focused, it set the focus to it's first sub element.

I could have a rule saying that if charts is focused, but has no internal element focus, I dislay the outlined on the entire SVG. But when user click on th charts I have to show it's getting the focus

Copy link
Member

Choose a reason for hiding this comment

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

Yeah that would be less disruptive I think. 🤔

Copy link
Member

Choose a reason for hiding this comment

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

Did you do anything regarding this comment? I still see the blue around it when clicking on the chart

}

element.addEventListener('keydown', keyBoardHandler);
element.addEventListener('focus', focusNextItem);
Copy link
Member

Choose a reason for hiding this comment

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

Yeah that would be less disruptive I think. 🤔


## Keyboard support

Set `enableKeyboardNavigation` to `true` to enable the keyboard navigation on your charts.
Copy link
Member

Choose a reason for hiding this comment

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

Should we have a global enable/disable toggle for this? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

I added a sentence about how to use theme provider to do so

Copy link
Member

@bernardobelchior bernardobelchior left a comment

Choose a reason for hiding this comment

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

I'm having a hard time using this feature in the docs. I can't seem to focus the chart. Do you know how I can do that? Do I need to enable some specific feature?


## Keyboard support

Set `enableKeyboardNavigation` to `true` to enable the keyboard navigation on your charts.
Copy link
Member

Choose a reason for hiding this comment

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

Should we add a demo?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done 👍

fill: color,
skipAnimation,
layout,
'data-focused': isFocused || undefined,
Copy link
Member

Choose a reason for hiding this comment

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

Base UI uses data-highlighted, but that might conflict with our current highlighted logic.

Image

Copy link
Member Author

Choose a reason for hiding this comment

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

data-highlighted could clearly conflict. But maybe data-active to use similar wording as aria-activedescendent

@alexfauquette
Copy link
Member Author

Do I need to enable some specific feature?

Yes, you need to add enableKeyboardNavigation prop to the chart. It should be enable by default but this would be a breaking change

@bernardobelchior
Copy link
Member

Do I need to enable some specific feature?

Yes, you need to add enableKeyboardNavigation prop to the chart. It should be enable by default but this would be a breaking change

I see. Should we add a demo, then? Otherwise people won't be able to easily test it from the docs

@bernardobelchior
Copy link
Member

Seems to work very well 😄

Screen.Recording.2025-09-09.at.08.42.23.mov

Do we want to show the tooltip when a mark is focused and the user presses some key?

alexfauquette and others added 4 commits September 11, 2025 16:39
Co-authored-by: Bernardo Belchior <[email protected]>
Co-authored-by: Jose C Quintas Jr <[email protected]>
Signed-off-by: Alexandre Fauquette <[email protected]>
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Sep 16, 2025
Copy link

This pull request has conflicts, please resolve those before we can evaluate the pull request.


# Accessibility

<p class="description">Learn how the Charts implement accessibility features and guidelines, including keyboard navigation that follows international standards.</p>
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
<p class="description">Learn how the Charts implement accessibility features and guidelines, including keyboard navigation that follows international standards.</p>
<p class="description">Learn how Charts implement accessibility features and guidelines, including keyboard navigation that follows international standards.</p>

This feature is currently supported by line, bar, pie, scatter, and sparkline charts.

This makes the SVG component focusable thanks to [`tabIndex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/tabindex).
When focused, the charts highlight a value item that can be modified with arrow navigation.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
When focused, the charts highlight a value item that can be modified with arrow navigation.
When focused, the chart highlights a value item that can be modified with arrow navigation.

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged. label Sep 18, 2025
Comment on lines +48 to +57
'&:focus': {
outline: 'none', // By default don't show focus on the SVG container
},
'&:focus-visible': {
// Show focus outline on the SVG container only when using keyboard navigation
outline: 'auto',
'&[data-has-focused-item=true]': {
// But not if the chart has a focused children item
outline: 'none',
},
Copy link
Member Author

Choose a reason for hiding this comment

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

@JCQuintas I went further with the focus display.

By relying on the :focus-visible the outlined is not display when the element get focused by click, but is visible when focused by Tab

Copy link
Member

Choose a reason for hiding this comment

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

Nice, interactions feels good now, thanks :D

Copy link
Member

@JCQuintas JCQuintas left a comment

Choose a reason for hiding this comment

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

small docs suggestions, everything else looks good

@alexfauquette alexfauquette merged commit edfd946 into mui:master Sep 19, 2025
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

accessibility a11y scope: charts Changes related to the charts. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants