'How to style Input in material ui

I am new to material ui.

I use fifth version.

            <InputBase
              ref={params.InputProps.ref}
              inputProps={params.inputProps}
              autoFocus
              sx={{
                ...InputCSS,
              }}
            />


const InputCSS = {
  width: '100%',
  textIndent: '17px',
  py: '12px',
  fontSize: '20px',
  borderRadius: '3px',
  border: '1.5px solid rgba(0, 0, 0, 0.4)',
  'MuiInputBase-root': { // does not work
    borderColor: 'red !important',
    color: 'red !important',
  },
  '&:focus' : { // does not work
     ...
   }
}

I could have used styled('input') and it works, I can set &:focus and it works but I can't type anything in the input.

I want to get rid of the initial border and set focus property.

How can I change the border for this class?

enter image description here

I know that in v5 we can style our components using variants or sx or styled.

What is the best advice for styling mui components? Because almost all the info in the internet uses outdated useStyle or makeStyles which doesn't work with react 18v.

sometimes I just struggle with components styling in mui



Solution 1:[1]

You have several ways to customize a Mui component, but my three favorite approaches are:

  1. Styled utility
  2. Sx prop
  3. Custom global theme

So when should I use each of these approaches?

Styled utility

If you want to make a component reusable across your app, go with styled, if you had ever used styled components then styled will be very familiar to you, here is an example of how to use it:

import * as React from 'react';
import Slider, { SliderProps } from '@mui/material/Slider';
import { alpha, styled } from '@mui/material/styles';

// if you are using typescript, don't forget to pass the component props on styled
const SuccessSlider = styled(Slider)<SliderProps>(({ theme }) => ({
  width: 300,
  color: theme.palette.success.main,
  // to override the styles of inner elements, 
 // you have to use the & selector followed by the class name.
  '&.MuiSlider-thumb': {
    '&:hover, &.Mui-focusVisible': {
      boxShadow: `0px 0px 0px 8px ${alpha(theme.palette.success.main, 0.16)}`,
    },
    '&.Mui-active': {
      boxShadow: `0px 0px 0px 14px ${alpha(theme.palette.success.main, 0.16)}`,
    },
  },
}));

export default function StyledCustomization() {
  return <SuccessSlider defaultValue={30} />;
}

To make the component even more dynamically, you can define custom props as well, like width, color, border and so on, read the styled docs to know more about it.

Sx prop

If you want to make an one time off style in a single component, the easiest way is to use the sx prop, but be careful with this approach because it can lead to a lot of repetition in your code. Following the code you gave:

<InputBase
   ref={params.InputProps.ref}
   inputProps={params.inputProps}
   autoFocus
   sx={{
   ...InputCSS,
   }}
/>

const InputCSS = {
  width: '100%',
  textIndent: '17px',
  py: '12px',
  fontSize: '20px',
  borderRadius: '3px',
  border: '1.5px solid rgba(0, 0, 0, 0.4)',
  // you should pass the & selector followed by the class that you want to override
  '&.MuiInputBase-root': {
  // avoid the use of !important
    borderColor: 'red',
    color: 'red',
  },
  '&.MuiInputBase-root:focus': {
     ...
   }
}

check it out on codeSandbox. Just a suggestion, depending on your case the component TextField could fit better as it comes with some good styles and you don't need to style it from scratch.

Side note:

Every mui component has an api doc with a css section where you can find all available classes to override, for instance, see the InputBase api docs, also read the docs about sx prop.

Custom theme

At last but not least, if you want to customize your whole app with custom palette, components, typography, breakpoints and so on, no doubt you should use a custom theme, as mui provides a powerful tool called createTheme to do so, what I like the most in custom theme is the possibility to make custom variants of the component, like so:

import * as React from "react";
import { createTheme, ThemeProvider } from "@mui/material/styles";
import Button from "@mui/material/Button";
import { red } from "@mui/material/colors";

 // if you are using typescript, you must declare the module with the 
// custom properties in order to get access of this property when using the component
declare module "@mui/material/Button" {
  // define custom variants
  interface ButtonPropsVariantOverrides {
    dashed: true;
    redVariant: true;
  }
}

const defaultTheme = createTheme();

const theme = createTheme({
  components: {
    MuiButton: {
      variants: [
        {
          // use the variant name defined earlier
          props: { variant: "dashed" },
          // set the styles for this variant
          style: {
            textTransform: "none",
            border: `2px dashed ${defaultTheme.palette.primary.main}`,
            color: defaultTheme.palette.primary.main
          }
        },
        {
          props: { variant: "redVariant" },
          style: {
            border: `2px solid ${red[300]}`,
            color: red[600]
          }
        }
      ]
    }
  }
});

export default function GlobalThemeVariants() {
  return (
    // use the theme provider to get access of custom theme
   // and variants within any child component
    <ThemeProvider theme={theme}>
      <Button variant="dashed" sx={{ m: 1 }}>
        Dashed
      </Button>
      <Button variant="redVariant" color="secondary">
        custom red variant
      </Button>
    </ThemeProvider>
  );
}

See the example, also take a look at the custom theme docs. Hope I clarified the things a bit!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1