mui-x icon indicating copy to clipboard operation
mui-x copied to clipboard

[DataGrid] Spread forwardedProps onto grid element

Open samwato opened this issue 1 year ago • 7 comments

Closes #13522

Looking at the historical changes, the aria-* and data-* props were originally on the GridRoot component when it had the role of "grid". This PR moves the rootProps.forwardedProps back to that element which has moved into the GridMainContainer component.

Demo: https://codesandbox.io/p/sandbox/github/samwato/codesandbox/tree/main/mui-x-issue-13522

samwato avatar Aug 14 '24 04:08 samwato

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

Generated by :no_entry_sign: dangerJS against 0f8d8760dcdeef698b3af01c635f1be115f9519b

mui-bot avatar Aug 14 '24 04:08 mui-bot

@michelengelen Any reviews on this would be great.

samwato avatar Aug 19 '24 12:08 samwato

Update: strikeout because of #8525 ~~I think that it is more useful to move the generated aria attributes up and keep the ability for the users to add props to the root container. In both cases~~ the change should be treated as a breaking change since people may rely on the position of these attributes for styling, event listeners, tests, etc. The change should be introduced behind an experimental flag (same as here) Another example

arminmeh avatar Aug 22 '24 05:08 arminmeh

I've read the issue again and I think this could also classify as a bug. It's a breaking behavior that wasn't intended nor documented in the changelog, and it causes a11y issues. I think I'd be fine with merging the PR.

romgrk avatar Aug 22 '24 06:08 romgrk

I think that the fact that even in this PR a test had to be updated to target the right element shows that we should treat it as a breaking change.

To update on my previous comment

I think that it is more useful to move the generated aria attributes up and keep the ability for the users to add props to the root container.

Actually, the only way to deal with this is like in this PR (moving forwarded props down), because role cannot be moved up (https://github.com/mui/mui-x/issues/8525)

arminmeh avatar Aug 22 '24 07:08 arminmeh

I guess it would also be possible to introduce a new prop that targets the [role=grid] element.

By the way the prop is marked as undocumented, we should remove that @ignore if it's already being used by external users:

https://github.com/mui/mui-x/blob/c0463fde0636e3265b94a3f555e6beb5fce52847/packages/x-data-grid/src/models/props/DataGridProps.ts#L389-L392

romgrk avatar Aug 22 '24 08:08 romgrk

For context, I'm still on v6 as the migration to v7 breaks tests duo to the forwardedProps change and doesn't comply with our screen reader testing.

It is unfortunate that the changes in this PR are a breaking change on top of the v6 to v7 breaking change, but sounds like the right direction to go.

samwato avatar Aug 22 '24 22:08 samwato

I guess it would also be possible to introduce a new prop that targets the [role=grid] element.

Agreed, to avoid the breaking change, we could add a temporary separate prop like forwardedPropsV8 for v7 that targets the [role=grid] element. In v8, we could remove the prop and spread the forwarded props to the [role=grid] element by default.

MBilalShafi avatar Aug 29 '24 14:08 MBilalShafi

But it could also be a different prop like forwardedPropsGrid. Is there a use-case for both?

romgrk avatar Aug 30 '24 09:08 romgrk

Is there a use-case for both?

There might be, I haven't seen it yet though. For simplicity, maybe start with only the grid element and aim to reintroduce it on the root element if there's a clear need. Wdyt?

MBilalShafi avatar Sep 04 '24 08:09 MBilalShafi

I'm fine with that.

romgrk avatar Sep 04 '24 21:09 romgrk

Thank you @samwato for the effort on this PR. Would you mind updating the PR as discussed in the comment above? I can also take over the PR from here if you want. 🙏

MBilalShafi avatar Sep 06 '24 08:09 MBilalShafi

Thank you @samwato for the effort on this PR. Would you mind updating the PR as discussed in the comment above? I can also take over the PR from here if you want. 🙏

@MBilalShafi No problem, If you could take over the changes, that would be great. We can close this PR and start again if that's easier.

samwato avatar Sep 09 '24 20:09 samwato

I would favor adding forwardedPropsGrid instead of forwardedPropsV8, even if we're going to rename/remove them later.

romgrk avatar Sep 10 '24 21:09 romgrk

Break API convention / describeConformance(), extra props should land on the root element, it's not the case deploy-preview-14197--material-ui-x.netlify.app/x/react-data-grid

@oliviertassinari

As I understand WAI-ARIA Authoring Practices, extra attributes like aria-label, aria-describedby, etc. should be applied to the element with role="grid" for the screen readers to properly associate these attributes with the grid functionality.

I understand that we have an API convention to spread the extra props on to the DOM root element, this case seems to be an exception though as we can't move role attribute up.

What do you think about considering the logical root element (.MuiDataGrid-main/role="grid") as root rather than the actual DOM root (.MuiDataGrid-root) and spread the props on it?

An additional prop forwardedPropsRoot could be used alongside to support forwarding props on actual DOM root (.MuiDataGrid-root)

MBilalShafi avatar Nov 18 '24 10:11 MBilalShafi

@MBilalShafi I think this is where the slotProps prop steps in. Feeling in control as a developer feels more important than ease of use. It also makes the case to make it possible to decompose the data grid.

oliviertassinari avatar Nov 18 '24 23:11 oliviertassinari

I think this is where the slotProps prop steps in.

I agree. This is the least confusing option. Now, the naming:

  1. slotProps={{ main: {} }} – following the main CSS class we're already using
  2. slotProps={{ grid: {} }} – following the aria role.
  3. ...Other?

I'm in favor of option 1. @MBilalShafi What do you think?

cherniavskii avatar Dec 09 '24 15:12 cherniavskii

  1. slotProps={{ main: {} }} – following the main CSS class we're already using
  2. slotProps={{ grid: {} }} – following the aria role.

@cherniavskii Sounds good. However, I wonder if it would keep the same confusion (#13522) related to the screen readers. Would the users passing additional props directly to the <DataGrid /> instead of using slotProps expect them to be spread to the role="grid" element rather than .root?

Another option could be to follow a similar route as https://github.com/mui/mui-x/issues/10409#issuecomment-1777372115, i.e. stop forwarding additional props forwarded on the <DataGrid /> component, and introduce slotProps for both the elements. i.e slotProps={{ root: {}, main/grid: {} }}

Summing up, we have the following options to choose from.

  1. Spread the additional props to the root element (.MuiDataGrid-root) and introduce a slot prop (slotProps={{ main/grid: {} }}) to allow passing additional props to the role="grid" element.
  2. Reverse of 1. Spread the additional props to the grid element (.MuiDataGrid-main/role="grid") and introduce a slot prop (slotProps={{ root: {} }}) to allow passing additional props to the .root element.
  3. Don't forward additional props passed to the <DataGrid /> component at all, allow to do it via the slotProps only. (slotProps={{ root: {}, main/grid: {} }})

If I get it right, your suggestion is option 1, I proposed option 2, it seems option 3 could be the least confusing middle-ground. Wdyt?

MBilalShafi avatar Dec 09 '24 18:12 MBilalShafi

Don't forward additional props passed to the <DataGrid /> component at all

This only applies to data- and aria- attributes, but not className and sx, right?

cherniavskii avatar Dec 12 '24 12:12 cherniavskii

This only applies to data- and aria- attributes, but not className and sx, right?

Yes, only the forwarded props prefixed with aria- and data-.

MBilalShafi avatar Dec 12 '24 13:12 MBilalShafi

Then option 3 sounds good to me 👍🏻

cherniavskii avatar Dec 12 '24 13:12 cherniavskii

The simplicity of just providing the 'aria-' prop to the component and it just works with screen readers is nice. But option 3 allows flexibility to enable any use case so sounds good 👍

samwato avatar Dec 13 '24 00:12 samwato

Now, the naming: 1.slotProps={{ main: {} }} – following the main CSS class we're already using 2.slotProps={{ grid: {} }} – following the aria role. 3 ...Other?

For sure 1. no question, we have to keep the pattern consistent (class name slot name) for people to learn things once. If the aria role is important, then we can argue that main should be renamed to grid, but it's a different, for later, change.

  1. Don't forward additional props passed to the <DataGrid /> component at all, allow to do it via the slotProps only. (slotProps={{ root: {}, main/grid: {} }})

If we mean we can get rid of all of this: https://github.com/mui/mui-x/blob/99ce15ceddafb5455c4816cfd8baeb63107b47f5/packages/x-data-grid/src/internals/utils/useProps.ts#L19 it sounds like a performance win 👍. I guess it's also performance as to why we don't spread other props to the root. There are so many props supported, that it would add bundle-size bloat.

With compound components, we could improve the DX later on, while still making the current one-component API behavior easy to predict.

oliviertassinari avatar Dec 13 '24 01:12 oliviertassinari

Raised a follow-up PR based on the discussion above: #15870

When that is merged, we could close this one safely. Thank you everyone for your input 🙇

MBilalShafi avatar Dec 13 '24 08:12 MBilalShafi