Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGrid] Support data attributes #8845

Merged
merged 20 commits into from May 25, 2023
Merged

Conversation

romgrk
Copy link
Contributor

@romgrk romgrk commented May 3, 2023

Closes #8605

This PR adds support for custom data attributes on the grid root element, which is useful for automation, testing & some external libraries.

@romgrk romgrk added the component: data grid This is the name of the generic UI component, not the React module! label May 3, 2023
@romgrk romgrk marked this pull request as draft May 3, 2023 05:38
@mui-bot
Copy link

mui-bot commented May 3, 2023

Netlify deploy preview

Netlify deploy preview: https://deploy-preview-8845--material-ui-x.netlify.app/

Updated pages

No updates.

These are the results for the performance tests:

Test case Unit Min Max Median Mean σ
Filter 100k rows ms 654.8 1,018.1 705.4 828.02 135.743
Sort 100k rows ms 613.8 1,373.8 1,373.8 961.54 293.94
Select 100k rows ms 172.5 355.5 308.8 290.12 66.311
Deselect 100k rows ms 198.4 312.8 231.1 248.44 39.445

Generated by 🚫 dangerJS against 2c7578f

@romgrk romgrk marked this pull request as ready for review May 3, 2023 07:48
Comment on lines 9 to 23
it('should accept data attributes props', () => {
render(
<div style={{ width: 300, height: 500 }}>
<DataGrid
rows={[{ name: 'Bob' }]}
columns={[{ field: 'name' }]}
data-custom-id="grid-1"
/>
</div>,
);

const grid = document.querySelector('[data-custom-id="grid-1"]')

expect(grid).not.to.equal(null);
});
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added a test for this in the community version, but technically speaking the same test should be added in the pro & premium packages to cover the feature fully. But that wouldn't be very DRY. Suggestions welcome.

@romgrk romgrk requested a review from DanailH May 4, 2023 01:03
@romgrk romgrk requested a review from m4theushw May 9, 2023 15:05
@romgrk
Copy link
Contributor Author

romgrk commented May 10, 2023

The changes here are going to conflict with #8942.

@romgrk romgrk marked this pull request as draft May 11, 2023 14:10
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label May 13, 2023
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label May 15, 2023
@mui mui deleted a comment from github-actions bot May 15, 2023
@romgrk romgrk marked this pull request as ready for review May 15, 2023 09:01
@romgrk
Copy link
Contributor Author

romgrk commented May 15, 2023

This is ready for review. There is a CI failure, but it seems unrelated to this PR.

Copy link
Member

@m4theushw m4theushw 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 not sure if we're in the right direction. The MUI components, by convention, spread the remaining props to the root element, we don't do that. If we go with the approach implemented here we still won't support passing an id value or using other attributes, e.g. hidden. I think we should enhance the DataGridProps interface to also allow any DIV attribute, then pass the attributes we don't use to the root element.

@romgrk
Copy link
Contributor Author

romgrk commented May 15, 2023

IIUC, you're saying we should do something like this?

@m4theushw
Copy link
Member

Yes, take all props, filter out those that are used internally (e.g. pagination), and spread to the root element the remaining ones (e.g. data-*). It would be nice if we didn't have to duplicate the list of props and leverage the DataGridProps interface but I don't know if it's possible.

@romgrk
Copy link
Contributor Author

romgrk commented May 15, 2023

@romgrk
Copy link
Contributor Author

romgrk commented May 15, 2023

I've looked around and using the DataGridProps interface isn't super trivial, because we need to take into account that there is also DataGridProProps and DataGridPremiumProps, and all of these are composite parametric types built dynamically. So the ts-transformer-keys above won't work (parametric types). And I feel like defining an array of accepted keys for each of those types is going to be tedious and error-prone.

How about we define the list of HTML props (eg. id, hidden) & prop patterns (eg data-*) we accept, and restrict ourselves to forwarding those?

@romgrk
Copy link
Contributor Author

romgrk commented May 18, 2023

Ping @m4theushw, any opinion on the comment above?

@m4theushw
Copy link
Member

I'm not a big fan of creating a list of HTML attributes to forward. The MUI components have this convention of forwarding the rest and I think it would be nice if we supported it too. I'm more on the side of having a list of DataGrid attributes to not forward. If it's not possible to enforce via TS that every prop must be filtered out from the rest then I think we need to accept it and be cautious when adding new props. Maybe a ESLint could be built to check this but it might be overkill. Don't take my opinion as the only approach to follow, I'm open for the opinions from other members.

@romgrk
Copy link
Contributor Author

romgrk commented May 19, 2023

I prefer the solution currently implemented in this PR because it has a good complexity/maintainability cost vs benefit. We have received requests to support data-attributes, from a pragmatic POV I think we should limit ourselves to supporting that in this PR. I'll wait to hear comments from the rest of the team before adding props arrays for all the DataGrid components.

Copy link
Member

@cherniavskii cherniavskii left a comment

Choose a reason for hiding this comment

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

The trade-off looks good to me 👍

Copy link
Member

@MBilalShafi MBilalShafi left a comment

Choose a reason for hiding this comment

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

Looks good to me.

Should we use the groupDataProps middleware to also accommodate aria-* props? (Rename it to groupCustomProps or something like that.)

Currently we hard code aria-label and aria-labelledby but probably it's an opportunity to make it generic too, as more aria-* props like aria-description could be passed.

Example pain point: #9075

@romgrk
Copy link
Contributor Author

romgrk commented May 22, 2023

Makes sense to deal with aria- here. I've updated the function to accept aria- props. I've left aria-label and aria-labelledby in because otherwise our linting/testing fails, but we do accept any aria prop now.

Copy link
Member

@MBilalShafi MBilalShafi left a comment

Choose a reason for hiding this comment

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

otherwise our linting/testing fails

Since we now support aria-* attributes by default, would doing something like this resolve the linting errors you mentioned (and possibly add a little bit better IDE auto-completion, for aria-* attributes)?

diff --git a/packages/grid/x-data-grid/src/models/props/DataGridProps.ts b/packages/grid/x-data-grid/src/models/props/DataGridProps.ts
index 006af94b0..2936f2233 100644
--- a/packages/grid/x-data-grid/src/models/props/DataGridProps.ts
+++ b/packages/grid/x-data-grid/src/models/props/DataGridProps.ts
@@ -116,7 +116,7 @@ export interface DataGridPropsWithComplexDefaultValueBeforeProcessing {
  * The controlled model do not have a default value at the prop processing level, so they must be defined in `DataGridOtherProps`
  * TODO: add multiSortKey
  */
-export interface DataGridPropsWithDefaultValues {
+export interface DataGridPropsWithDefaultValues extends React.AriaAttributes {
   /**
    * If `true`, the grid height is dynamic and follow the number of rows in the grid.
    * @default false
@@ -677,14 +677,6 @@ export interface DataGridPropsWithoutDefaultValue<R extends GridValidRowModel =
    * @param {GridCallbackDetails} details Additional details for this callback.
    */
   onSortModelChange?: (model: GridSortModel, details: GridCallbackDetails) => void;
-  /**
-   * The label of the grid.
-   */
-  'aria-label'?: string;
-  /**
-   * The id of the element containing a label for the grid.
-   */
-  'aria-labelledby'?: string;
   /**
    * Set of columns of type [[GridColDef[]]].
    */

* Forwarded props for the grid root element.
* @ignore - do not document.
*/
forwardedProps?: Record<string, unknown>;
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this be in DataGridPropsWithoutDefaultValue?

@MBilalShafi
Copy link
Member

MBilalShafi commented May 24, 2023

Just a side note:

I am amazed this is not actually possible (context), but it'd have be great to only allow aria-* and data-* hyphen-cased props for better type coverage. (Lack of that is the very reason this issue came up to begin with, as the user passed data-* props, typescript did not complain, even though we didn't pass the props down to the dom element)

This probably supports @m4theushw's argument of destructuring { ...rest } as technically all hyphen-cased props are allowed by the TS but are not actually passed down to the DOM element. (possibly for those props which contain a hyphen propName.includes('-'), it will cover data-* and aria-* by default).

I am not sure though how practical is it to go in that direction right now.

@romgrk
Copy link
Contributor Author

romgrk commented May 24, 2023

React.AriaAttributes

I considered using it but it didn't like the solution, because it contains props such as aria-checked which make absolutely no sense on the datagrid. I feel like it's fine to accept everything (pros: future-proof, completeness) but not document that we accept everything. I'm open to using it if there is a strong feeling that it's a better solution.'

Destructuring

I'm not sure I see how it would help with the issues here. I don't think we can get a perfect (typed) solution here.

@romgrk
Copy link
Contributor Author

romgrk commented May 24, 2023

There is a failing test but it seems unrelated to this PR. If no one else has comments, I'll merge as it is before the release.

@romgrk romgrk merged commit 7c2cca1 into mui:master May 25, 2023
17 checks passed
@romgrk romgrk deleted the feat-grid-data-attributes branch May 25, 2023 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[data grid] Cannot add data attributes to data-tables, their rows, page buttons, etc
5 participants