Material UIでz-index強めのTooltipへの対策

2022.08.31

こんにちは、こんばんわ。 「ゴルフが急激に下手になってきて、元気がないです。」 どうも、CX 事業本部 Delivery 部 MAD グループ@札幌の hiro です。

今回は、MUI(Material UI)(以後、MUIと省略)でTooltipを触れているときにz-indexに困ったことがあったので、その時の内容を記述していきます。

はじめに

MUIで定義されているTooltipのz-indexは、「1500」であり、Modalの下でTooltipを表示させたい場合に、ある程度調整する必要があります。 参考

そんなときに、調整したいと思い色々触れた時の内容を記述します。

また、注意にも記載していますが、 「Modal表示/非表示の際にTooltipを表示/非表示させて対応させる方法」ではなくTooltip自体の高さを変更することで対応しています。 その理由としては、仮にMUIでTooltipの高さを変更しようと思った時に「tooltip」ではなく「popper」のPropsで調整するのか!!っと戸惑ったため、あえてこの方法で記述しています。

ちなみに

UIライブラリで定義されているz-indexは、それぞれのライブラリによって様々で、Bootstrapであれば

$zindex-tooltip: 1070 !default;

と定義されています。参考

MUIのz-indexの値一覧は以下になっています。参考

  • mobile stepper: 1000
  • fab: 1050
  • speed dial: 1050
  • app bar: 1100
  • drawer: 1200
  • modal: 1300
  • snackbar: 1400
  • tooltip: 1500

注意

いくつか注意点があります。

  • 見た目などは一切考慮していないです
  • Reactが動作する環境の上に作成しています
  • 今回、MUIでもテンプレートを提供しているので、そちらのテンプレートの元構築しています※
  • Modal表示/非表示の際にTooltipを表示/非表示させて対応させる方法ではない方法で記述しています
  • etc

参考

ご了承ください。

事前準備と動作確認

□ 環境構築とライブラリのインストール

  • React環境整え
$ npx create-react-app web --template typescript
$ cd web
  • MUIインストール
$ npm install @mui/material @emotion/react @emotion/styled

参考

□ 動作確認

まずは、動作しているところから見ていただければと思います。

◇ うまくいっていないバージョン

以下のように、TooltipがModalの上部にきていることがわかると思います。

◇ うまくいっているバージョン

以下のように、TooltipがModalの下に隠れていることがわかると思います。

やってみよう

今回もやってみようということで、ファイル構成やファイル内容を記述していきたいと思います。

□ ファイル構成

以下のファイル構成で、記述します。 一つのファイルで完結させているので、記述するか迷いましたが、念の為記載しています・・・

.
└── App.tsx・・・・・・諸々見た目レンダリング

□ 諸々見た目レンダリング

ほとんど、参考を土台にしているので、Tooltipの部分のみ抜き出して記載します。

Tooltip APIのPropsで「tooltip」ではなく「popper」で高さ調整をします。 自分は始め、名前ベースで「tooltip」だろ高さ調整は。と思っていました。 しかし異なり、「popper」で調整するようでした。

ここでPropsを見ていただければ、どういうものか想像つくと思います。

App.tsx

・
・
・
import { Modal, Tooltip } from "@mui/material";

const theme = createTheme();

const style = {
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  width: 400,
  bgcolor: "background.paper",
  border: "2px solid #000",
  boxShadow: 24,
  p: 4,
};

const App = () => {
  const [open, setOpen] = React.useState(false);
  const [tooltipOpen, setTooltipOpen] = React.useState(false);
  const handleOpen = () => setOpen(true);
  const handleClose = () => setOpen(false);
  const handleTooltipClose = () => setTooltipOpen(false);
  const handleTooltipOpen = () => setTooltipOpen(true);

  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <main>
        <Modal
          open={open}
          onClose={handleClose}
          aria-labelledby="modal-modal-title"
          aria-describedby="modal-modal-description"
        >
          <Box sx={style}>
            <Typography id="modal-modal-title" variant="h6" component="h2">
              Text in a modal
            </Typography>
          </Box>
        </Modal>
        <Box
          sx={{
            bgcolor: "background.paper",
            pt: 8,
            pb: 6,
          }}
        >
          <Container maxWidth="sm">
            ・
            ・
            ・
            <Stack
              sx={{ pt: 4 }}
              direction="row"
              spacing={2}
              justifyContent="center"
            >
              <Button onClick={handleOpen}>Open modal</Button>
              <Tooltip
                title="Add"
                arrow
                componentsProps={{
                  popper: {
                    sx: {
                      zIndex: 1250,
                    },
                  },
                }}
                open={tooltipOpen}
                onClose={handleTooltipClose}
              >
                <Button variant="contained">ACTION1</Button>
              </Tooltip>
              <Button variant="outlined" onClick={handleTooltipOpen}>
                SHOW TOOLTIP
              </Button>
            </Stack>
          </Container>
        </Box>
        ・
        ・
        ・
      </main>
    </ThemeProvider>
  );
};

export default App;

上記のように実装しましたが、UIライブラリで定義されているz-indexを変更することには注意が必要です。

ここでも以下のように記載されています。

These values can always be customized. You will find them in the theme under the zIndex key of the theme. Customization of individual values is discouraged; should you change one, you likely need to change them all.

結論、個々でz-indexを編集することは推奨されないよ。全体変更する必要あるからね。ということです。 僕もそう思います。ただ、今回着手した理由は、「はじめに」で記載されています。

□ 再動作確認

記述した内容で、サーバーを動かします。

$ npm start

おわりに

チームでz-indexの定義を事前に相談しておくのがいいと思います。 例えば、「原則UIライブラリに従って、それ以外の部分はこうしよう」などなど。

割とProps名称だけで判断すると困ることがあるので、ドキュメントをしっかり見ながら、試しながら進んでいくのがいいと思います。

繰り返しになりますが、UIライブラリに依存するのであれば、その上でチーム定義しつつ、Tooltipは適切に管理するのがいいと思います。

ありがとうございました。