Apply `defaultProps` from theme to root `styled` component
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 99.1k
- Forks
- 32.5k
- Avg merge
- 2d 17h
- Merged PRs (30d)
- 106
Description
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the styled component options and the useThemeProps example shown in the issue, then trace how theme components currently provide variants and styleOverrides to styled components. Done means a root styled component can receive theme.components[name].defaultProps without a wrapper while preserving existing theme styling behavior; the issue does not name specific files or tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react, typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100