1
votes

I am attempting to add a Tooltip to wrap the KeyboardDatePicker and simply wrapping it in the Tooltip provides the following error:

Warning: Failed prop type: Invalid prop children supplied to ForwardRef(Tooltip). Expected an element that can hold a ref. Did you accidentally use a plain function component for an element instead? For more information see https://material-ui.com/r/caveat-with-refs-guide in ForwardRef(Tooltip) (created by WithStyles(ForwardRef(Tooltip)))

in WithStyles(ForwardRef(Tooltip)) (at src/index.js:17)

in MuiPickersUtilsProvider (at src/index.js:16)

in App (at src/index.js:33)

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Check the render method of ForwardRef(Tooltip). in PickerWithState (at src/index.js:19) in ForwardRef(Tooltip) (created by WithStyles(ForwardRef(Tooltip))) in WithStyles(ForwardRef(Tooltip)) (at src/index.js:17) in MuiPickersUtilsProvider (at src/index.js:16) in App (at src/index.js:33)

If I wrap the tooltip in a it gets around the error but it seems like a hack and the tooltip is not aligned properly below the field. In my reading of ForwardRef I can't figure out how to solve this here. Can anyone help solve this correctly?

https://codesandbox.io/s/mui-pickers-tooltip-1hsn2

import React, { useState } from "react";
import ReactDOM from "react-dom";

import DayjsUtils from "@date-io/dayjs";
import {
  MuiPickersUtilsProvider,
  KeyboardDatePicker
} from "@material-ui/pickers";

import { Tooltip } from "@material-ui/core";

function App() {
  const [selectedDate, handleDateChange] = useState();

  return (
    <MuiPickersUtilsProvider utils={DayjsUtils}>
      <Tooltip placement={"bottom"} title={"This tooltip overlaps"}>
        {/*<span>*/}
        <KeyboardDatePicker
          label={"hello"}
          variant="inline"
          autoOk
          value={selectedDate}
          onChange={handleDateChange}
        />
        {/*</span>*/}
      </Tooltip>
    </MuiPickersUtilsProvider>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
1

1 Answers

1
votes

I wrestled with the same thing. I think you can get the result you want by using the TextFieldComponent prop on the KeyboardDatePicker component. One caveat is that if you use an inline function, render props style, then the input will lose focus during keyboard editing, but passing in named, functional component like this works.

KeyboardDatePicker API: https://material-ui-pickers.dev/api/KeyboardDatePicker

https://codesandbox.io/s/mui-pickers-tooltip-48fs5

import React, { useState } from "react";
import ReactDOM from "react-dom";

import DayjsUtils from "@date-io/dayjs";
import { TextField } from "@material-ui/core";
import {
  MuiPickersUtilsProvider,
  KeyboardDatePicker
} from "@material-ui/pickers";

import { Tooltip } from "@material-ui/core";

function TextFieldWithTooltip(props) {
  return (
    <Tooltip placement={"bottom"} title={"This tooltip should work"}>
      <TextField {...props} />
    </Tooltip>
  )
}

function App() {
  const [selectedDate, handleDateChange] = useState();

  return (
    <MuiPickersUtilsProvider utils={DayjsUtils}>
      <KeyboardDatePicker
        label={"hello"}
        variant="inline"
        autoOk
        value={selectedDate}
        onChange={handleDateChange}
        TextFieldComponent={TextFieldWithTooltip}
      />
    </MuiPickersUtilsProvider>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);