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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

TablePropsSizeOverrides customization via module augmentation #33802

Closed
2 tasks done
brentertz opened this issue Aug 4, 2022 · 4 comments 路 Fixed by #33816
Closed
2 tasks done

TablePropsSizeOverrides customization via module augmentation #33802

brentertz opened this issue Aug 4, 2022 · 4 comments 路 Fixed by #33816
Labels
bug 馃悰 Something doesn't work component: table This is the name of the generic UI component, not the React module! good first issue Great for first contributions. Enable to learn the contribution process. typescript

Comments

@brentertz
Copy link
Contributor

brentertz commented Aug 4, 2022

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Current behavior 馃槸

I am trying to augment the available Table sizes via module augmentation, to include a "large" size, in addition to the existing "small" and "medium" sizes.

This is currently defined at the top of my custom theme file.

declare module '@mui/material/Table' {
  interface TablePropsSizeOverrides {
    size?: 'small' | 'medium' | 'large';
  }
}

declare module '@mui/material/TableCell' {
  interface TableCellClasses {
    sizeLarge: string;
  }
}

While things render properly, it causes TypeScript issues in the component and in the theme.

Component

<Table size="large" /> // TS error - Type '"large"' is not assignable to type '"small" | "medium" | undefined'

Theme

{
    MuiTable: {
      defaultProps: {
        size: 'large', // TS error - Type '"large"' is not assignable to type '"small" | "medium" | undefined'
      },
    },
    MuiTableCell: {
      styleOverrides: {
        sizeLarge: { // This works!
          paddingBlock: 10,
        },
        sizeMedium: {
          paddingBlock: 5,
        },
        sizeSmall: {
          paddingBlock: 2,
        },
      },
    },
}

Expected behavior 馃

I would expect the first 2 errors in the example above to "just work" - that is to say that "large" would be a valid option for the size prop.

I am not sure if that would just work for the TableCell component as well. Perhaps it would require its own augmentation? The TableCell component does however add the "MuiTableCell-sizeLarge" CSS class, so it renders properly.

Steps to reproduce 馃暪

https://codesandbox.io/s/trusting-swanson-tpedid?file=/demo.tsx

Context 馃敠

I am trying to augment the available Table sizes via module augmentation, to include a "large" size, in addition to the existing "small" and "medium" sizes.

Alternatively, I suppose that I could create wrapper components for the Table and TableCell components and implement the size prop overrides that way. It seemed that module augmentation was the recommended approach however.

Your environment 馃寧

npx @mui/envinfo
  System:
    OS: macOS 12.3.1
  Binaries:
    Node: 16.13.2 - ~/.nvm/versions/node/v16.13.2/bin/node
    Yarn: 1.22.18 - ~/.nvm/versions/node/v16.13.2/bin/yarn
    npm: 8.1.2 - ~/.nvm/versions/node/v16.13.2/bin/npm
  Browsers:
    Chrome: 103.0.5060.134
    Edge: Not Found
    Firefox: 100.0.2
    Safari: 15.4
  npmPackages:
    @emotion/react:  11.10.0
    @emotion/styled:  11.10.0
    @mui/base:  5.0.0-alpha.92
    @mui/material:  5.9.3
    @mui/private-theming:  5.9.3
    @mui/styled-engine:  5.8.7
    @mui/styles:  5.9.3
    @mui/system:  5.9.3
    @mui/types:  7.1.5
    @mui/utils:  5.9.0
    @mui/x-data-grid:  5.13.0
    @mui/x-data-grid-pro:  5.13.0
    @mui/x-date-pickers:  5.0.0-beta.0
    @mui/x-date-pickers-pro:  5.0.0-beta.0
    @mui/x-license-pro:  5.12.1
    @types/react: ^17.0.0 || ^18.0.0 => 18.0.15
    react:  18.2.0
    react-dom:  18.2.0
    typescript: 4.6.3 => 4.6.3
@brentertz brentertz added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Aug 4, 2022
@siriwatknp siriwatknp added bug 馃悰 Something doesn't work component: table This is the name of the generic UI component, not the React module! typescript and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Aug 5, 2022
@siriwatknp
Copy link
Member

I recommend doing this https://codesandbox.io/s/naughty-lake-lp15nu?file=/demo.tsx, but there is a typescript bug on the TableCell.

When you customize the component based on props, use variants or a callback because the classes will be removed at some point.

variants
https://mui.com/material-ui/customization/theme-components/#creating-new-component-variants

MuiTableCell: {
  variants: [
    { props: { size: 'small', style: { paddingBlock: 2 },
    ...
  ]
}

styleOverrides callback
https://mui.com/material-ui/customization/theme-components/#overrides-based-on-props

MuiTableCell: {
  styleOverrides: {
    root: ({ ownerState }) => ({
      ...(ownerState.size === "small" && {
        paddingBlock: 2
      }),
      ...(ownerState.size === "medium" && {
        paddingBlock: 5
      }),
      ...(ownerState.size === "large" && {
        paddingBlock: 10
      })
    })
  }
}

@siriwatknp
Copy link
Member

siriwatknp commented Aug 5, 2022

Suggested fix:

diff --git a/packages/mui-material/src/TableCell/TableCell.d.ts b/packages/mui-material/src/TableCell/TableCell.d.ts
index 73f9ba19ed..94b0c32a17 100644
--- a/packages/mui-material/src/TableCell/TableCell.d.ts
+++ b/packages/mui-material/src/TableCell/TableCell.d.ts
@@ -1,8 +1,11 @@
 import * as React from 'react';
+import { OverridableStringUnion } from '@mui/types';
 import { SxProps } from '@mui/system';
 import { InternalStandardProps as StandardProps, Theme } from '..';
 import { TableCellClasses } from './tableCellClasses';
 
+export interface TableCellPropsSizeOverrides {}
+
 /**
  * `<TableCell>` will be rendered as an `<th>`or `<td>` depending
  * on the context it is used in. Where context literally is the
@@ -46,7 +49,7 @@ export interface TableCellProps extends StandardProps<TableCellBaseProps, 'align
    * Specify the size of the cell.
    * The prop defaults to the value (`'medium'`) inherited from the parent Table component.
    */
-  size?: 'small' | 'medium';
+  size?: OverridableStringUnion<'small' | 'medium', TableCellPropsSizeOverrides>;
   /**
    * Set aria-sort direction.
    */

Need to check the proptypes of Table & TableCell as well

@siriwatknp siriwatknp added the good first issue Great for first contributions. Enable to learn the contribution process. label Aug 5, 2022
@brentertz
Copy link
Contributor Author

brentertz commented Aug 5, 2022

@siriwatknp Thank you for your input. I have submitted a PR, with the updates that you recommended.

When you customize the component based on props, use variants or a callback because the classes will be removed at some point.

Okay, this is very good information to be aware of. Personally, I prefer the callback style as it seems most direct.

Can you briefly clarify what you mean by, "classes will be removed?" Do you just mean from the styleOverrides block in the theme, or that the component CSS API will eventually go away entirely, or perhaps something different? I am happy to read up on it if it has been discussed elsewhere. It sounds like the approach could really help avoid some CSS specificity issues making overrides easier. Thanks!

I am assuming that the recommended pattern to target child components in the callback will be to just use their CSS className, yes?

fictional example...

MuiChip: {
  styleOverrides: {
    root: ({ ownerState }) => ({
      '& .MuiChip-deleteIcon': {
        fontSize: theme.typography.pxToRem(14);
        
       ...(ownerState.size === "small" && {
        fontSize: theme.typography.pxToRem(11)
       }),
    })
  }
}

@siriwatknp
Copy link
Member

Can you briefly clarify what you mean by, "classes will be removed?" Do you just mean from the styleOverrides block in the theme.

Yes, just for the theming point of view. Here is why we want to remove it, those classes do not scale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 馃悰 Something doesn't work component: table This is the name of the generic UI component, not the React module! good first issue Great for first contributions. Enable to learn the contribution process. typescript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants