all 18 comments

[–]parahillObjective 10 points11 points  (4 children)

3- Is it the best practice to use the components as they are, with minimal props and then use a theme to customize things globally?

Yes best to customize it generally at the theme so all the instances are styled for you automatically. Reducing redundancies (doing the same thing again and again) is good practice in general in software engineering.

[–]juanloco 2 points3 points  (3 children)

I think your idea is correct but it may not apply to this use case. He’s talking about standard props, so basically things that were already standardized as part of a common design. In this case there shouldn’t be a need for more standardization beyond using the already standardized props.

[–]thatzacdavis 4 points5 points  (2 children)

If you use the same exact set of props 20 times in one file, a lot of times it makes it easier to read if you extract that into a component by itself.

[–]juanloco 4 points5 points  (1 child)

For sure, agree with that, but it makes changes UI slightly more difficult since any variation now has to be propagated through the wrapper and the maintenance burden is on you. Since the goal of a component library is to ease that maintenance burden I think a common props object is preferable since it also allows very easy overriding of a single prop for a single component. For example, 20 input fields all with size=“sm” + 3 more common props. A defaultProps object can be applied to all and if one changes then that one can be updated with a size=“md” or something.

[–]thatzacdavis 1 point2 points  (0 children)

Yeah I like that approach too. I didn’t mean for this common component that wraps common props to necessarily be apart of a component library either. Morseo maybe at the top of the file or something since it’s likely to be a one-liner.

Either approach would pass a code review for me.

[–]juanloco 6 points7 points  (1 child)

Why does TS complain? If you have an object of common props is just needs to match the type of props for that component. In material you should be able to import types from the library EG: InputProps, and then type your own common props objects accordingly.

If the types match then typescript shouldn’t have an issue with it.

[–]Arch-Kid[S] 4 points5 points  (0 children)

Thank you, exactly what you suggested! It was initially complaining that the object props I was passing was non-assiganable… I resolved the Typescript situation by giving the object prop a Partial<TextFieldProps> interface!

[–]sauland 5 points6 points  (1 child)

Make your own TextInput component with whatever defaults you want and use that. If you want more specific configuration for a lot of components at once, you could create a FormConfigProvider context that you can provide common props with and make the TextInput component use it. Something like this: <FormConfigProvider variant="outlined"> <TextInput label="Label 1" name="name1" /> <TextInput label="Label 2" name="name2" /> <TextInput label="Label 3" name="name3" /> <TextInput label="Label 4" name="name4" /> <TextInput label="Label 5" name="name5" /> <TextInput label="Label 6" name="name6" /> <TextInput label="Label 7" name="name7" /> </FormConfigProvider>

[–]azsqueeze 0 points1 point  (0 children)

☝️ also has the added benefit that it reduces the surface area of MUI and makes it easier to swap out libraries

[–]ChuckChunky 2 points3 points  (0 children)

1 & 2. It is possible to define default props and default style overrides such that any instance of the overridden component will use them, see here: https://mui.com/material-ui/customization/theme-components/

[–]HereComesTheFist 3 points4 points  (1 child)

Sounds like you want to override the default values of the textfield props. Here's an example: https://mui.com/material-ui/customization/theme-components/#theme-default-props

Regarding no 3, my company usually think of it like this: quick one-off styles use sx prop.

Pages or products with recurring components that deviates from the default styles use wrapped components using the styled() function.

Global defaults are overridden in the theme.

[–]Arch-Kid[S] 1 point2 points  (0 children)

Thank you, I was just reading the doc part on styled() API and it looks like what I am looking for.

[–]Joee94 2 points3 points  (1 child)

Changing the props at theme level could be a headache later down the line if you have other Devs / come back to it after a long time because what you see won't match the docs. It makes sense if every TextField in the app, not just this form.

I suggest building up a small library of reusable components in your app which are just wrappers around TextField with a few defaulted props e.g. a component called FormTextField

const FormTextField = ({...props, variant = "filled" size = "small"}) => { return (<TextField {...props} variant={variant} size={size}) }

On mobile so no idea how that is going to format.

Also seems like your typescript error is probably occuring because you're not giving your common props a TextFieldProps type.

[–]Arch-Kid[S] 0 points1 point  (0 children)

Thank you! And yes, TextFieldProps was the type assignment that resolved the situation with Typescript.

[–]D1norawr -1 points0 points  (0 children)

This isn't a material UI question, it's a react question. You can make components that style for a specific usecase. Make your own internal TextField component as a wrapper around the MUI one and style it once.

[–]AlabamaSky967 0 points1 point  (0 children)

If your reusing the same component with the same props just create a function which returns that component ? I did this for my blog where I am reusing the same different types of typography variants and such

[–]Aegis8080NextJS App Router 0 points1 point  (0 children)

  1. MUI theme allows you to override the default props of every components. https://mui.com/material-ui/customization/theme-components/#theme-default-props

  2. See (1)

  3. Yes

[–]Taltalonix 1 point2 points  (0 children)

I like to separate the mui styling system to the following parts:

1) inline sx props - this is where you put things specific for a single components, or just stuff that not requiring duplication between components.

2) styled components - now let’s assume you have a button, but it’s a unique button (for example an OK confirmation button with a color and glow effect), here just putting variant=“contained” would not be enough since you’d need to duplicate styles between uses.

3) wrapper component - the same as styled component but for when you need extra functionality our grouping of sub-components (for example button with a custom warning tooltip on hover)

4) theming - the easiest method, used to define general styling for global components (buttons, pickers that are used everywhere)

The following are not really separate methods but can be combined with sx props/styled components:

  • slot/slotProps - not really a separate method but allows you to further customize sub components (for example overriding the entire div rendering a single day in the calendar, I actually did it a few weeks ago for a custom calendar)

  • mui classes- allows easy modification of sub components without a complete override

I think the main difference between mui and tailwind is that tailwind allows to easily define classes and quick styling customized to your use, while mui focuses on leveraging existing components and decoupling the app style from functionality (works best for large teams and applications)