Customize the appearance of the date input box in MUI KeyboardDatePicker

Currently, I am attempting to customize the appearance of the KeyboardDatePicker component including board color, size, font, and padding. However, none of the methods I have tried seem to be effective. Here is what I have attempted so far:

1 . Utilizing useStyles :

const useStyles = (params: any) =>
  makeStyles(() =>
    createStyles({
      componentStyle: {
        width: params.width ? params.width : 'auto',
        color: params.color ? params.color : 'inherit',
        verticalAlign: 'middle',
        fontSize: '12px',
        border: 'solid 2px #0070D8',
      },
    })
  );

Unfortunately, this method does not override the default styles and a border still appears on the existing KeyboardDatePicker, with no change in size.

2 . Implementing Theme provider, which successfully overrides the calendar theme but not the date box within the KeyboardDatePicker.

<ThemeProvider theme={theme}>

3 . Adding inline styles directly into KeyboardDatePicker seems to be the only approach that works:

style={{width:"246px",height:"44px"}}

If you have any suggestions on how to properly modify the styles of the KeyboardDatePicker component without using the style={} approach, please let me know. It should be noted that I am using Material-UI version 4.

My KeyboardDatesPicker:

    <KeyboardDatePicker
      format="MM/dd/yyyy"
      margin="normal"
      id="date-picker-inline"
      defaultValue={props.value}
      value={selectedDate}
      required={props.required}
      showTodayButton={true}
      disableToolbar
      inputVariant="outlined"
      variant="inline"
      onChange={(selectedDate) => setSelectedDate(selectedDate)}
      KeyboardButtonProps={{
        "aria-label": "change date",
      }}
      keyboardIcon={<Icon icon={ICONS.Cool_icon} />}
      className={classes.componentStyle} // do not overide , but puts on top
    />

Answer №1

makeStyles is a function that creates a style hook (usually referred to as useStyles). Here's how you should use it:

const useStyles = makeStyles(...);

In the given code snippet, you need to define useStyles as a function that returns makeStyles, instead of attempting to create a new hook. This change is necessary for correct functionality. I have also corrected the styles for you. The text color styles should be specified within the InputBase component:

const useStyles = makeStyles(() =>
  createStyles({
    componentStyle: {
      verticalAlign: "middle",
      fontSize: "12px",
      width: (params) => (params.width ? params.width : "auto"),

      "& fieldset": {
        border: "solid 2px #0070D8"
      },
      "& .MuiInputBase-root": {
        height: (params) => (params.height ? params.height : "auto"),
        color: (params) => (params.color ? params.color : "inherit")
      }
    }
  })
);
const classes = useStyles({
  color: "red",
  width: 400,
  height: 80,
});
<KeyboardDatePicker
  onChange={() => {}}
  inputVariant="outlined"
  InputProps={{
    className: classes.componentStyle
  }}
/>

If you prefer styling via createMuiTheme, here is an alternative code snippet. Keep in mind that creating dynamic styles based on component props is not supported in this method compared to using useStyles:

const theme = createMuiTheme({
  overrides: {
    MuiTextField: {
      root: {
        verticalAlign: "middle",
        fontSize: "12px",
        width: 150,
        "& fieldset": {
          border: "solid 2px #0070D8"
        }
      }
    }
  }
});

By implementing these changes, your code should work as intended. For more insights, refer to this section on how to effectively use makeStyles with component props.

https://codesandbox.io/s/69608311-react-mui-keyboarddatepicker-change-styles-of-date-input-box-8mnhq?file=/demo.tsx

Answer №2

If you find yourself needing to create a custom hook like

useStyles = (params: any) => ...
, it's important to note that the hook provided by makeStyles already accepts a props parameter.

When styling Material-UI components, it's crucial to reference the API documentation for each component in order to determine the object structure required by makeStyles. For instance, the date picker component consists of multiple nested MUI components, each with their own set of props. To style the input within the datepicker, you would include the classes returned by the useStyle hook in InputProps, adhering to the root rule as outlined in the Input API, and adding additional rules for more specific styles if necessary.

const useInputStyles = makeStyles({
  root: {
    width: (props) => (props.width ? props.width : "auto"),
    color: (props) => (props.color ? props.color : "inherit"),
    verticalAlign: "middle",
    fontSize: "12px",
    border: "solid 2px #0070D8"
  }
});
...
    const inputClasses = useInputStyles()
...
      <KeyboardDatePicker
        ...
        InputProps={{ classes: inputClasses }}
      />

If you're looking to style the "board" (potentially referring to the popover), especially when using the 'inline' variant, you can apply styles through PopoverProps by specifying the styles within the paper rule as indicated in the Popover API.

const usePopoverStyles = makeStyles({
  paper: {
    backgroundColor: "green"
  }
});
...
    const popoverClasses = usePopoverStyles();
      ...
      <KeyboardDatePicker
        ...
        PopoverProps={{ classes: popoverClasses }}
      />

To see these styling techniques in action, check out this example here.

Answer №3

My implementation in TypeScript is still a work in progress, but I believe it can be helpful to others. I plan on incorporating MuiFormLabel-root to customize the label styling further.

const useDatePickerStyles = makeStyles<ITheme, ITextFieldStyleProps>((theme) =>
  createStyles({
    datePickerContainer: ({ isValid, isError }) => ({
      border: 'solid',
      borderRadius: 4,
      borderWidth: theme.mvf.border.width.thin,
      borderColor: theme.mvf.palette.border,
      ...(!isError && {
        '&:hover': {
          boxShadow: theme.mvf.boxShadow.primary,
          borderColor: theme.mvf.palette.primary.main,
        },
        ...(isValid && {
          color: theme.mvf.palette.primary.main,
          boxShadow: theme.mvf.boxShadow.primary,
          borderColor: theme.mvf.palette.primary.main,
        }),
      }),
      ...(isError && {
        color: theme.mvf.palette.error,
        boxShadow: theme.mvf.boxShadow.error,
        borderColor: theme.mvf.palette.error,
      }),
    }),
    datePicker: () => ({
      margin: theme.mvf.spacing.small,
    }),
 }),
);

export default useDatePickerStyles;

To access classes:

const DatePicker: DatePickerType = ({
  id,
  onChange,
  format,
  value,
  label,
  errorMessage,
  placeholder,
  isVerticallyCentered,
  ...props
}: IDatePickerProps) => {
  const isValid = !errorMessage && !!value;

  const classes = useDatePickerStyles({
    isError: !!errorMessage,
    isVerticallyCentered,
    isValid,
  });

  return (
    <div className={classes.datePickerContainer}>
      <MuiPickersUtilsProvider utils={DateFnsUtils}>
        <KeyboardDatePicker
          id={id}
          fullWidth
          maxDateMessage={''}
          minDateMessage={''}
          invalidDateMessage={''}
          className={classes.datePicker}
          label={isVerticallyCentered ? undefined : label} // don't show as label will be outside
          placeholder={placeholder}
          format={format} // of the displayed date
          emptyLabel={placeholder} // displayed value if empty
          name="datePicker"
          InputLabelProps={{
            className: classes.inputLabel,
          }}
          margin="normal"
          value={value}
          onChange={onChange}
          InputProps={{
            className: classes.inputPropsClasses,
            inputProps: { className: classes.textInput },
            disableUnderline: true,
          }}
          inputVariant="standard"
          KeyboardButtonProps={{
            className: classes.calendarButton,
          }}
          {...props}
        />
      </MuiPickersUtilsProvider>
    </div>
  );
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Insufficient column height when using CSS flex-grow property

I am facing an issue with my 3 flex columns that have varying text lengths, resulting in uneven heights. I have tried using flex-grow: 1; to make them match in height, but it does not seem to be working as intended. Can someone please help me identify what ...

Setting distinct values for various material selects by utilizing states in a functional component of React can be achieved in the following manner

I am a newbie to React and I am currently working with Material Design select boxes, which can be found at https://material-ui.com/components/selects/ When using the simple select box, I noticed that there are multiple select boxes available. However, whe ...

Adjust the height of the drawer in material-ui

In my current project using react and material-ui, I am facing a simple issue that has me stumped. I am trying to create a drawer with a specific height so that it does not overlap the app bar when opened. Unfortunately, there is no built-in parameter in ...

Updating a child component within a Modal: A step-by-step guide

I am using a global Modal component: export const ModalProvider = ({ children }: { children: React.ReactNode }) => { const [isModalOpen, setIsModalOpen] = React.useState(false); const [config, setConfig] = React.useState<ModalConfig | nu ...

What's causing these divs to be misaligned in various directions?

I am currently working with a front-end framework based on flexbox called Material-UI, and I have noticed that the layout of certain components, particularly the quantity control elements, appears to be different even though they all share the same styling ...

Utilizing Next.js with a unique custom Node.js backend implementation

I have successfully developed the frontend using Next.js in order to utilize SSR and enhance SEO. Additionally, I have a personalized NodeJS+express server for managing users and other database tasks (tested thoroughly with Postman). My next step is to in ...

Ways to abbreviate a URL using Next JS

While working on my Next.js application, I encountered an issue with passing an object between pages. To achieve this, I compressed my array of objects into JSON using JSON.stringify(result) on the index page and then parsed it on the second page using JSO ...

When a React Router link is activated, the React Bootstrap dropdown remains open instead of closing as expected

<NavDropdown className="userDropdownButton" title="dropdown" id="user-nav-dropdown" alignRight > <div className="userDropDown"> <Link to="/user" className="userDropDownheader"> user </Link> </div> < ...

The installation of npm consistently fails during the Jenkins build process with error code EPIPE

It's baffling because it worked smoothly for a prolonged period, but now every time I trigger the build job, it fails. However, when I connect to the Jenkins host via SSH and build using the command line, it runs without any errors. https://i.sstatic ...

Execute JavaScript function on click event in NextJS

Is it possible to execute a JavaScript function on the client side without using addEventListener? This situation works with addEventListener. MyComponent.js import Script from 'next/script' export default function MyComponent({ props }) { ...

Offspring element overrides styling of its parent

#popBox{ width:100%; height:100%; position:fixed; left:0; top:0; border-collapse:collapse; background:black; opacity:0.8; display:none; } <table id="popBox"> <tr> <td></td> <td></td> ...

Tips for creating a responsive background image without excessive scaling:

I'm currently working on a website with a focus on responsibility, and I've incorporated 'waves' SVG images as a background-image. The issue arises when viewing the site on smaller screens, such as mobile devices, where the background a ...

Angular 7 - Customize Mat-select-value color depending on a specific condition

One issue I am facing is changing the color of a selected value in a mat select based on a condition. This change should be visually apparent to the user. Although accessing mat-select-value from the styles is possible, implementing a condition using ng-cl ...

Personalized Bootstrap grid rows and columns

https://i.sstatic.net/R0yFY.png As a beginner in Bootstrap, I am having trouble achieving this specific layout in Bootstrap 4 grid. The areas marked in red are not appearing as expected. Here is what I have attempted so far: <div class="row"> ...

Personalizing a column using Reactstrap

Currently, I am utilizing reactstrap to showcase a grid of movie posters. My goal is to have 5 items per row out of the total 20 items. Despite setting the column size as md={2} for each item, I always find leftover white space at the end of the row. I a ...

What is the method for determining the type of search results returned by Algolia?

My connection between firestore and algoliasearch is working well. I am implementing it with the help of typescript in nextjs. I am attempting to fetch the results using the following code snippet products = index.search(name).then(({hits}) => { ret ...

What are the steps for incorporating @2x and @3x images into a React Native Project for both Android and iOS platforms?

When working on our platform to ensure compatibility across all devices, I included different versions of the same image (@2x and @3x) in the src > assets folder. However, a problem emerged as VSCode only recognizes the path.png without acknowledging th ...

Adjusting the settings in php.ini

Recently, I started using Mac OS X v10.6 (Snow Leopard) and decided to delve into PHP, despite being a complete novice in the language. As I followed a tutorial and attempted to execute a date() function in my code, I received an error message warning me a ...

Creating an Image on Demand with ReactJS

Updating an image dynamically in reactjs.... I am looking to change the displayed image dynamically based on a user's selection from a dropdown menu. <Col xs="6"> <Label for="name"><h2> Home Team </h2> </Label> ...

What is the best way to adjust the vertical margin in a vis.js timeline?

The vis.js timeline sets a margin of 5px in each row using inline styles that are controlled programmatically by the library. The height, top position, and transform of each item within the row are specified by the library as well. Attempting to manually ...