A while back, around the alpha & beta iterations on the v1 version, we had to decide what was the best way to override the nested components. It's meant to help developers customize the rendering. We can find #11204 and #10476 as a legacy.
up until v1
So far, the tradeoff on this problem has been:
- Provide a
XXXComponent prop when overriding the nested element can be valuable for users. For instance:
https://github.com/mui-org/material-ui/blob/c6b95d2e773088af66823f8995c3e57508c82056/packages/material-ui/src/Modal/Modal.d.ts#L8
- Provide a
XXXProps prop when providing a custom XXXComponent component is too cumbersome. For instance:
https://github.com/mui-org/material-ui/blob/c6b95d2e773088af66823f8995c3e57508c82056/packages/material-ui/src/Modal/Modal.d.ts#L9
However, this original design constraint is increasingly more challenged by the following:
Autocomplete
The Autocomplete mixes the renderXXX approach with the XXXComponent approach. cc @oliviertassinari
https://github.com/mui-org/material-ui/blob/c6b95d2e773088af66823f8995c3e57508c82056/packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts#L164
https://github.com/mui-org/material-ui/blob/c6b95d2e773088af66823f8995c3e57508c82056/packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts#L142
Date Picker
The DatePicker mixes the renderXXX approach with the XXXComponent approach. cc @dmtrKovalenko
renderLoading?: () => React.ReactNode;
https://github.com/mui-org/material-ui-pickers/blob/c834f5cac5930df099aaad806ceb3fe4ec1669db/lib/src/views/Calendar/Calendar.tsx#L43
ToolbarComponent?: React.ComponentType<ToolbarComponentProps>;
https://github.com/mui-org/material-ui-pickers/blob/c834f5cac5930df099aaad806ceb3fe4ec1669db/lib/src/typings/BasePicker.tsx#L61
Data Drid
The DataGrid goes with xXXComponent approach, however, the name is confusing. Sometimes it's a render prop, sometimes it's a React element, it's never a component as the name suggests cc @dtassone
paginationComponent?: (props: PaginationProps) => React.ReactNode;
loadingOverlayComponent?: React.ReactNode;
noRowsOverlayComponent?: React.ReactNode;
footerComponent?: (params: ComponentParams) => React.ReactNode;
headerComponent?: (params: ComponentParams) => React.ReactNode;
https://github.com/mui-org/material-ui-x/blob/59d533642d5837ce6912fe88cbcdfc228f621594/packages/grid/x-grid-modules/src/models/gridOptions.tsx#L93-L97
Styled components
Styled components might request something brand new. cc @mnajdova
As the experimentation of #21104 showcases. If we want to keep the CSS specificity at it's lowest possible level (meaning one level) and expose unstyled components, we will have to expose an API to inject custom component. In older experimentation, I worked around the problem with a components prop.
components?: {
Root: React.ElementType<React.HTMLAttributes<HTMLDivElement>>;
Label: React.ElementType<React.HTMLAttributes<HTMLSpanElement>>;
}
https://github.com/oliviertassinari/material-ui/blob/153c1833fb204a28ee6712db1c2ac6a9308a163e/packages/material-ui/src/TableCell/TableCell.unstyled.js#L18
The problem
I think that it would be great to defines which API works best and in which cases. I would hope that by doing so, we can provide a consistent experience for the developers using the library to build applications and websites. I also think that by reducing the number of approaches we can reduce the learning curve for new users.
When should we use a component, when should we use a render prop, etc.?
Prior-arts
A while back, around the alpha & beta iterations on the v1 version, we had to decide what was the best way to override the nested components. It's meant to help developers customize the rendering. We can find #11204 and #10476 as a legacy.
up until v1
So far, the tradeoff on this problem has been:
XXXComponentprop when overriding the nested element can be valuable for users. For instance:https://github.com/mui-org/material-ui/blob/c6b95d2e773088af66823f8995c3e57508c82056/packages/material-ui/src/Modal/Modal.d.ts#L8
XXXPropsprop when providing a customXXXComponentcomponent is too cumbersome. For instance:https://github.com/mui-org/material-ui/blob/c6b95d2e773088af66823f8995c3e57508c82056/packages/material-ui/src/Modal/Modal.d.ts#L9
However, this original design constraint is increasingly more challenged by the following:
Autocomplete
The Autocomplete mixes the
renderXXXapproach with theXXXComponentapproach. cc @oliviertassinarihttps://github.com/mui-org/material-ui/blob/c6b95d2e773088af66823f8995c3e57508c82056/packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts#L164
https://github.com/mui-org/material-ui/blob/c6b95d2e773088af66823f8995c3e57508c82056/packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts#L142
Date Picker
The DatePicker mixes the
renderXXXapproach with theXXXComponentapproach. cc @dmtrKovalenkohttps://github.com/mui-org/material-ui-pickers/blob/c834f5cac5930df099aaad806ceb3fe4ec1669db/lib/src/views/Calendar/Calendar.tsx#L43
https://github.com/mui-org/material-ui-pickers/blob/c834f5cac5930df099aaad806ceb3fe4ec1669db/lib/src/typings/BasePicker.tsx#L61
Data Drid
The DataGrid goes with
xXXComponentapproach, however, the name is confusing. Sometimes it's a render prop, sometimes it's a React element, it's never a component as the name suggests cc @dtassonehttps://github.com/mui-org/material-ui-x/blob/59d533642d5837ce6912fe88cbcdfc228f621594/packages/grid/x-grid-modules/src/models/gridOptions.tsx#L93-L97
Styled components
Styled components might request something brand new. cc @mnajdova
As the experimentation of #21104 showcases. If we want to keep the CSS specificity at it's lowest possible level (meaning one level) and expose unstyled components, we will have to expose an API to inject custom component. In older experimentation, I worked around the problem with a
componentsprop.https://github.com/oliviertassinari/material-ui/blob/153c1833fb204a28ee6712db1c2ac6a9308a163e/packages/material-ui/src/TableCell/TableCell.unstyled.js#L18
The problem
I think that it would be great to defines which API works best and in which cases. I would hope that by doing so, we can provide a consistent experience for the developers using the library to build applications and websites. I also think that by reducing the number of approaches we can reduce the learning curve for new users.
When should we use a component, when should we use a render prop, etc.?
Prior-arts