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

Apply defaultProps from theme to root styled component #34539

Open
2 tasks done
GMchris opened this issue Oct 1, 2022 · 6 comments
Open
2 tasks done

Apply defaultProps from theme to root styled component #34539

GMchris opened this issue Oct 1, 2022 · 6 comments
Labels
package: system Specific to @mui/system waiting for 👍 Waiting for upvotes

Comments

@GMchris
Copy link

GMchris commented Oct 1, 2022

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Summary 💡

defaultProps defined under a custom component name should be picked up and applied by styled component, even if it required a setting within the styled function call. Currently variants and styleOverrides inside the theme can be referenced and used by styled components and are configurable using some of its options,.

Perhaps a setting like this to allow handling some of MUI's use-cases

styled('div', {
  name: 'MySheet',
  slot: 'Root',
  defaultPropsResolver: (defaultProps) => ({ ownerState: defaultProps })
})

or just a boolean parameter which enables or disables the styled component from accessing theme.components[name].defaultProps

styled('div', {
  name: 'MySheet',
  slot: 'Root',
  useDefaultProps: true,
})

Examples 🌈

The following custom component

export interface SheetProps {
    variant?: 'plain' | 'outlined';
}

const SheetRoot = styled('div', {
    name: 'MySheet',
    slot: 'Root',
    shouldForwardProp: (prop) => {
        switch (prop) {
            case 'variant':
            case 'sx':
                return false;
            default:
                return true;
        }
    },
    overridesResolver: ({ color, variant, padded }, styles) => [
        styles.root,
        variant === 'plain' && styles.plain,
        variant === 'outlined' && styles.outlined,
    ],
})<SheetProps>({});

With the following theme definition

const theme = createTheme({
  components: {
    MySheet: {
            defaultProps: {
                variant: 'outlined',
            },
            styleOverrides: {
                root: sx({
                    borderRadius: 1,
                }),
                outlined: sx({
                    borderWidth: 1,
                    borderStyle: 'solid',
                }),
            },
        },
  }
});

and rendered like this

<MySheet />

will NOT have its variant prop be set to outlined. Instead, by referencing some MUI components we see that useThemeProps is needed to extract the defaultProps from the theme.

const Sheet: FC<SheetProps> = (props) => {
    const compProps = useThemeProps({ name: 'MySheet', props });

    return <SheetRoot {...compProps} />;
};

This wrapper component is usually where classNames are generated and more complex components compose all their styled sub components. So it's only natural for Mui core components to require these defaults though the useThemeProps before the style component is even rendered.

Motivation 🔦

Having to wrap each custom component just to call a hook which passes a key we're already feeding into the styled component feels very redundant. Not to mention it adds to boilerplate for typescript and ref usage. Our projects share a base theme with custom properties and some custom styled components are also registered using the theme.components object. It would be very helpful to give each theme override a different set of defaultProps for our custom components.

@GMchris GMchris added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Oct 1, 2022
@mnajdova
Copy link
Member

mnajdova commented Oct 3, 2022

Thanks for the examples and detailed explanation. I would wait to see if issue gets more traction before adding overhead to the default styled() utility, mainly because it's use in all components and it could add unnecessary overhead.

@mnajdova mnajdova added waiting for 👍 Waiting for upvotes package: system Specific to @mui/system and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Oct 3, 2022
@aParadowski
Copy link

I'd like to bump this as well. We're converting from styles to the new styled api approach and just ran into this same issue. It would be nice to at least have it called out in the styled migration section if this is indeed a limitation of the current system.

@Gift-Stack
Copy link

Please assign this issue to me

@brandonscript
Copy link

Just some thoughts here, defaultProps is deprecated (well, has been for a long time) but there are some clear performance drawbacks to using it. A pretty good read on why: https://medium.com/@matanbobi/react-defaultprops-is-dying-whos-the-contender-443c19d9e7f1

@GMchris
Copy link
Author

GMchris commented Mar 17, 2023

@brandonscript

This issue relates to the theme properties called defaultProps not the defaultProps assigned to a component.

@idanamit4
Copy link

Is there any new information regarding this issue?
We're creating a design system based on MUI and really needs the option to define defaultProps from the theme itself

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package: system Specific to @mui/system waiting for 👍 Waiting for upvotes
Projects
None yet
Development

No branches or pull requests

6 participants