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

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

Open
michaldudak opened this issue Jul 7, 2022 · 13 comments
Open

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

michaldudak opened this issue Jul 7, 2022 · 13 comments
Assignees
Labels
breaking change discussion package: base-ui Specific to @mui/base package: joy-ui Specific to @mui/joy package: material-ui Specific to @mui/material RFC Request For Comments

Comments

@michaldudak
Copy link
Member

michaldudak commented Jul 7, 2022

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 [RFC] What's the best API to override deep/nested elements? #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

  • Better alignment with the terms used throughout the documentation.
  • Use of a less ambiguous and generic term ("component" has a much broader meaning than "slot").
  • Shorter words require less typing and take less horizontal space in components' markup.

Camel-cased slots members

  • It'll be consistent with componentsProps.* . I often cringe when writing a component and having to override componentsProps.root and components.Root
  • Pascal-cased props/fields look weird and are not common in JS/TS
  • It would match the capitalization we use in for the theme component overrides https://mui.com/material-ui/customization/theme-components/#global-style-overrides.
  • I understand the reasoning behind introducing Pascal-cased identifiers (components are written this way by convention). However, what goes into a components.* doesn't have to be a React component (could be a div, for example). Besides, we don't actually pass components.* to JSX directly, so we don't have to rely on it being written in Pascal-case (we usually write const Root = components.Root ?? component ?? 'div')
  • We've got the component prop, not Component
  • It's easier to type - developers won't have to press Shift 🙂

Disadvantages

  • Developers accustomed to the existing patterns will have to relearn them.
  • Introducing breaking changes will require changes to downstream codebases.
  • 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".

Benchmark

@oliviertassinari
Copy link
Member

oliviertassinari commented Jul 7, 2022

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

  • in problem 1. using "slot" moves us a bit further away from the React terminology, meaning, we would decide to optimize for describing the concept over describing the expected type of the prop & how this is implemented. It feels like a tradeoff. It could make sense for the docs to focus on the concept, hence use "slots", and the API to focus on the implementation, hence use "components".
  • in problem 2. using the same capitalization would move us a bit further away from the React consistency conventions, where the upper case if for React components types and the lower case is for the types of objects. It feels like a tradeoff.

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
Copy link
Member Author

michaldudak commented Aug 12, 2022

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:

  • keep our non-deprecated API consistent across packages: you'll be able to use slots across the board,
  • teach developers the patterns we'd like to keep,
  • not break anyone using the stable packages.

@michaldudak michaldudak added package: material-ui Specific to @mui/material package: base-ui Specific to @mui/base package: joy-ui Specific to @mui/joy labels Aug 12, 2022
@oliviertassinari oliviertassinari changed the title [RFC] Rename of the components prop [RFC] Rename of the components prop to slots Aug 12, 2022
@oliviertassinari
Copy link
Member

oliviertassinari commented Aug 12, 2022

@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. #33183 with @alexfauquette.

@michaldudak
Copy link
Member Author

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
Copy link
Member

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.

@oliviertassinari oliviertassinari added the RFC Request For Comments label Aug 21, 2022
@michaldudak
Copy link
Member Author

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

@alexfauquette
Copy link
Member

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
Copy link
Member Author

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
Copy link
Member

Janpot commented Aug 29, 2022

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
Copy link
Member Author

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
Copy link
Member

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
Copy link

qwertie commented Sep 13, 2022

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
Copy link
Member

siriwatknp commented Sep 16, 2022

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.

  • Replace the HTML tag by preserving the default styles. One example is changing the Select's listbox from ul to div to achieve grouped options.
  • Replace the slot with a custom component. One example is the Github picker customization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change discussion package: base-ui Specific to @mui/base package: joy-ui Specific to @mui/joy package: material-ui Specific to @mui/material RFC Request For Comments
Projects
None yet
Development

No branches or pull requests

8 participants