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

[base-ui] POC: Input using component-per-node pattern #40893

Closed

Conversation

michaldudak
Copy link
Member

@michaldudak michaldudak commented Feb 1, 2024

⚠️ POC, DO NOT MERGE ⚠️

This is a POC of using the component per DOM element pattern for the Input component.
I created a new component, Textbox, as I didn't want to fix all the usages of the existing Input in order to build the site. The Textbox is basically the Input broken down into individual components.
I simplified the implementation by removing the multiline logic. This was only to speed up the work by not having to deal with generics and refs pointing to either an input or a textarea. Having multiple components doesn't necessarily make it easier or harder to work with union props, but since this wasn't the main goal of this POC, I didn't want to waste too much time.
For the component replacement/customization API, I chose to use render props.

A few observations I had:

  • Having more smaller components generally lead to code that's easier to read...
  • ...however, in cases where interoperability between component is required, code becomes more complex (communication via contexts, passing refs, etc.).
  • It wasn't always obvious to me which prop should go to the root component and which on the subcomponents. This should be evaluated on a case-by-case basis.
  • Every component with multiple "slots" will have to use context to communicate between the root and subcomponents. This may have a small performance impact.
  • Tailwind CSS demos source looks much better.
  • MUI System demos are a bit more verbose (especially around the render props).
  • Splitting up the existing components won't be repeatable mechanical work. Each component will have to be approached individually to ensure the parts' responsibilities are well defined.
  • It should be fairly easy to create wrappers exposing the old API for our existing users:
      // pseudo-code, not tested
      function Input({ slots, slotProps }) {
        const Root = slots.root ?? 'div';
        const Input = slots.input ?? 'input';
    
        return (
          <Textbox render={(props) => <Root {...slotProps.root} />}>
            <Textbox.Input render={(props) => <Input {...slotProps.input} />} />
          </Textbox>
        );

Preview: https://deploy-preview-40893--material-ui.netlify.app/experiments/base/component-per-node/
Usage: https://github.com/michaldudak/material-ui/blob/poc/input-component-per-node/docs/pages/experiments/base/component-per-node.tsx

@michaldudak michaldudak changed the title [base-ui ] POC: Input using component-per-node pattern [base-ui] POC: Input using component-per-node pattern Feb 1, 2024
@michaldudak michaldudak added package: base-ui Specific to @mui/base proof of concept Studying and/or experimenting with a to be validated approach labels Feb 1, 2024
@mui-bot
Copy link

mui-bot commented Feb 1, 2024

Netlify deploy preview

@material-ui/unstyled: parsed: +2.19% , gzip: +2.12%

Bundle size report

Details of bundle changes (Toolpad)
Details of bundle changes

Generated by 🚫 dangerJS against 6659cf3

@mj12albert mj12albert mentioned this pull request Feb 8, 2024
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package: base-ui Specific to @mui/base proof of concept Studying and/or experimenting with a to be validated approach
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants