mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.51k stars 32.18k forks source link

[RFC] Rename of the `components` prop to `slots` #33416

Open michaldudak opened 2 years ago

michaldudak commented 2 years ago

Problem

This is a continuation of #21453. With some hindsight, we have surfaced possible limitations:

  1. In the documentation and comments we generally refer to sub-components of a component as "slots". However, the props to control these slots are called components and componentsProps (as per #21453). We have used "components" so far with the objective to be as close as possible to the React implementation. But is it intuitive?
  2. There is an inconsistency in the casing (members of components are Pascal-cased, while members of componentsProps are camel-cased) when comparing the props side-by-side.

    <Slider components={{ Root }} componentsProps={{ root: {} }} />

    The current casing aims to be consistent with the React conventions. In React components are Pascal-cased while elements props are camel-cased. But is it intuitive?

Solution

Therefore, I propose the following:

  1. Rename the components prop to slots.
  2. Rename the componentsProps prop to slotProps.
  3. Rename the members of slots to use camel-case (e.g. root instead of Root).

Execution

This obviously would be a breaking change. For stable packages, we should introduce a transition period where both sets of props would be available. We will then deprecate the old ones, and finally, remove them in a future major version. We could provide a codemod to aid in the transition.

As MUI Base is not stable yet, we may introduce this change sooner, without a transition period. The library hasn't been publicly announced yet, so there is an opportunity to introduce this change without impacting many developers.

Advantages

Rename of components and componentsProps

Camel-cased slots members

Disadvantages

Benchmark

oliviertassinari commented 2 years ago

I have updated a bit the description to bring some of the initial rationales on why the previous terminology/API. I have raised how:

Overall, no objections, it sounds like a step forward (more pros than cons).

I think that the question is about, how to actually make the change. I would be more in favor of moving slowly: keep all our products' API consistent, support both APIs, and have a migration period in the order of 24 months (one or two majors). We have done massive changes in v5, it didn't fly well, we likely have to rebuild trust with our audience now when it comes to BCs.

michaldudak commented 2 years ago

I propose the following approach to proceed with this further:

  1. Add the slots and slotProps props to Material UI components that already support components/componentsProps. References to componentsProps exist in 17 components within @mui/material as of today.
  2. In Material UI, add the deprecation notice to the components and componentsProps props in favor of the newly added ones.
  3. Rename the components/componentsProps props in MUI Base and Joy UI. I don't see much value in keeping both components and slots in the transition period. Let's teach developers how to use the props we intend to keep. What's more, introducing a new library with already deprecated props wouldn't look well.

We can decide at a later stage when to remove the components/componentsProps from Material UI.

This will:

oliviertassinari commented 2 years ago

@michaldudak For the angle of how to implement the changes, I think that it could work, I would only add two things:

For 1. I think that we should also include all the demos in the docs. For 2. I think that we should at least wait enough time to see how the community reacts to 1. The deprecations could happen as late as once we start to work on v6.

For the angle of either we should move forward. I think that ideally, we would want to get some feedback from the community, we are ultimately doing it for them. I'm not sure how. https://twitter.com/tannerlinsley/status/1531641545568333824 could be one way. I think that feedback from MUI X would also be great. They are as much impacted by these changes, e.g. https://github.com/mui/material-ui/pull/33183 with @alexfauquette.

michaldudak commented 2 years ago

Agreed, both make perfect sense.

As for MUI X, @flaviendelangle also mentioned they'll be affected by these changes. I'm eager to know if you guys consider these changes worth pursuing.

samuelsycamore commented 2 years ago

Just chiming in to say +1 to move forward with this! I think this concept and its implementation will be much easier for new users to grasp when the terminology is aligned here.

michaldudak commented 2 years ago

I've just created a poll to make a decision: #34080

alexfauquette commented 2 years ago

Maybe a dumb proposal, but could we use "component slot" instead of "slot" in the doc and keep the prop naming as it is?

michaldudak commented 2 years ago

There are no dumb proposals, @alexfauquette :). If we're going to stay with "components", we'll have to adjust the docs to match the API.

Please make sure to vote in the poll.

Janpot commented 2 years ago

There's another place where we use pascalcase for properties that are not React components: under the theme components property. Not that it should be part of this RFC, bit would it make sense to start thinking about moving these to camelcase as well?

michaldudak commented 2 years ago

I'd say it's less of an issue because there are no inconsistencies like in case of components and componentsProps. We could create another RFC to discuss it.

joserodolfofreitas commented 2 years ago

Just chiming in to say +1 to move forward with this! I think this concept and its implementation will be much easier for new users to grasp when the terminology is aligned here.

I agree. The changes are most welcome, although we kinda have a special case on date pickers, particularly considering we'll release the first v5 stable this week, and the v6 by the end of the year (packed with lots of breaking changes).

Some could argue that "components" is describing what the prop is doing more precisely. You might have to think twice about what's the returned type of the "slot" prop, while it could be more intuitive when seeing "components".

Would it help to call them slotComponents and slotProps?

qwertie commented 2 years ago

FWIW I have absolutely no idea why you would refer to subcomponents as "slots". (I found this page by Googling "mui slots" because I saw "slots" in the documentation and had no idea what it meant.) I remember that slots in Qt meant "event handler"...

siriwatknp commented 2 years ago

I have another RFC talking about the meaning of components and slots. Would be nice if it is resolved first so that everyone is on the same page.

I have a real-world use case that is bigger than MUI Base. For MUI Base, you always replace the slot because the default slots are plain strings (HTML tags).

However, for Material UI and Joy UI, the components are built with default styles so there are 2 possibilities to override.

DiegoAndai commented 4 months ago

All Material UI components have had components and componentsProps deprecated in favor of slots and slotProps: https://github.com/mui/material-ui/issues/41279. To be released in v6.

oliviertassinari commented 4 months ago

@DiegoAndai Great, so deprecation of the components prop in v6 and removal of the prop in v7 👍.

The only question I would have is what will happen with Material UI v7. If we move all the components to have one React component per DOM node, then we would also remove the slot prop. Developers might feel like we can't agree on a common vision for the future. To be fair, the same pattern is used in MUI X. So I guess we are good, just that it could look strange in retrospective 😁.

DiegoAndai commented 4 months ago

@oliviertassinari we'll be discussing this topic in the upcoming weeks 👍🏼

I'll add your comment to the discussion.