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

Creating a navigation bar in React using react-scroll

Is anyone able to assist me with resolving the issue I am facing similar to what was discussed in React bootstrap navbar collapse not working? The problem is that although everything seems to be functioning properly, the navbar does not collapse when cli ...

The GraphQl Code Generator fails to correctly generate the graphql() function in Next.js applications

While working on my next.js project, I integrated GraphQL to generate types for queries. However, the code generator is not functioning properly and displaying an error message: "The query argument is unknown! Please regenerate the types." within the gql.t ...

Trouble with displaying images on material-ui card elements

I have been trying to showcase my photos on an iterated card component within Material-UI. After thoroughly examining my Redux store, I can confirm that all the URLs are valid and lead to images when directly entered into the address bar in Firefox. Even t ...

Styling a list using multiple columns with CSS

My goal is to design a columned list using only HTML and CSS. I have experimented with floats and inline-block, but it seems like inline-block is the best option for me due to these specific requirements: The layout must be in columns; The number of colu ...

What is the reason for choosing to use the render method outside of components instead of within

I built a component that includes the following code: interface Props { email: string; } const getErrorMessage = (payload: any) => { if (typeof payload.data === 'string') { return payload.data; } else if (payload.data && &apo ...

Identifying errors in a React component upon loading

As I delve into my project, my main focus lies on detecting errors within a component. The ultimate goal is to seamlessly redirect to the home page upon error detection or display an alternate page for redirection. I am seeking a programmatic solution to ...

Failure to Present Outcome on Screen

Seeking assistance! I attempted to create a mini loan eligibility web app using JavaScript, but encountered an issue where the displayed result did not match the expected outcome upon clicking the eligibility button. Here is the HTML and JavaScript Code I ...

What is the best way to transfer state information from a hook to be displayed in the App component in React

Is there a way to transfer the state(data) of info to the App hook, in order to showcase the properties within div elements? The function setInfo(info) saves the data intended for display on the Map hook and inspecting console.log(info) within _onClick rev ...

Enhancing Date formatting in Jquery Data tables following ASP.NET Serialization

Currently, I am facing an issue with formatting dates in a SQL database query that is being serialized by ASP and then converted to JSON for display in Datatables using JavaScript. Instead of the correct date format, I am seeing: /Date(1424563200000)/. I ...

Prop in a React component is undergoing mutation

I encountered a strange situation where a prop in a React component is being changed. Although it's technically not a mutation since it's an array in JavaScript, it should not be modified. To replicate the issue, I created a simple example: htt ...

Tips for sending files from react to my .net server

Can someone help me with uploading images to my server using React? This is what my controller looks like so far: [Authorize] public object UploadAvatar() { var file = HttpContext.Current.Request.Files.Count > 0 ? HttpContext.Current.Requ ...

Tips for disabling scrolling on a <div> using another <div> as a lock

I am facing an issue with a page where a div is appended to the body of an HTML. The problem is that there are two scrolls appearing - one on the new overlaying div and another behind it. Here is an approximate structure of the page, how can I ensure that ...

Switch up the primary color on the React Material UI speed dial component

Looking to customize the color of my React Material UI SpeedDial component from its default primary color. Any tips on how to change it to a different color? ...

Eliminating data from selection options on a HTML menu list

Currently, I am facing an issue while attempting to incorporate a menu bar into my HTML page. After adding the icons, they are displaying with both underlines and dots at the back. I have tried using text-decoration=none; to remove the underline, but unf ...

Setting the position of the center to be relative inside a table cell

I need help with centering a +/- animation within my table rows to create an accordion toggle effect for revealing more information. Despite finding a nice looking animation, I'm struggling to position it correctly within the td element in my code. He ...

Horizontal navigation bar encroaching on slideshow graphics

I'm encountering difficulties aligning the horizontal menu below the image slider. When I have just an image without the slider, the menu aligns properly (vertically), but as soon as I introduce the code for the slider, the menu moves to the top and d ...

unable to adjust the maximum height limit

I've been struggling to set a maximum height on the slider I'm currently using. No matter what height value I input, it doesn't seem to take effect. Additionally, I attempted setting the width for the echo img row in the PHP section but enco ...

Wait for AngularJS to load when the background image of a div becomes visible

Currently, I am utilizing the ng-repeat feature to fetch data from a $http.post request and then save it to the $scope.data variable. <div ng-repeat="key in [] | range:data.pages"> <div class="pageBackground" id="page_{{ (key+1) }}" ng-style= ...

Does the 'span' element negatively impact the vertical alignment of text?

While working on my code, I noticed an issue with vertical alignment when using span tags to change the background of the text based on its content. The problem occurs specifically when viewing the code in the Android Chrome browser. You can view the initi ...

Utilizing an object as a prop within React-router's Link functionality

Looking for a solution to pass the entire product object from ProductList component to Product component. Currently, I am passing the id as a route param and fetching the product object again in the Product component. However, I want to directly send the ...