at backyard

Color my life with the chaos of trouble.

Material UIでAutoCompleteで cursor:"not-allowrd"にする方法

Material UIを使う機会が割とあるのだが、個人的にはMaterial UIのAPIは分かりにくく苦手意識がある。

今回AutoCompleteコンポーネントに対して狙ったスタイルを当てる方法について備忘録を残しているが、ここまで行くのに色々と試行錯誤をしており、それなりに時間が溶けてしまった。

createTheme なども試してみたが、うまくいきそうに思えて、Autocompletedisabled 時のみ有効にする設定が動かなかったりして実現できなかった。
自分の書き方が悪いのか、それともMaterial UI側が上手く機能していないのかコードを見に行かないと分からなかったりする。が、あまりコードを見に行く気にならず(スタイルがあたっているかどうかをデバッグしていく時間と気力がなかった...)、結局このやり方は採用しなかった。
たぶん、自分がドキュメントの見落としているだけのような気もするけど...

mui.com

まえがきが長くなってしまったが本題に移る。

Material UIでAutoCompleteで cursor:"not-allowrd"にする方法

まずは実際に動いているところ。

結論としては makeStyles を使う形にした。 が、これv5で非推奨になっているんですよね。。。

v5では styled を使う形になっているが、こっちでは上手く実現できていない。
うーん、スッキリしないが、取りあえず動くコードを下記に抜粋して載せておく。

また、実際に動くサンプルはGitHubに載せてある。

github.com

import { useState } from 'react';
import Autocomplete from '@mui/material/Autocomplete';
import TextField from '@mui/material/TextField';
import Stack from '@mui/material/Stack';
import Button from '@mui/material/Button';
import makeStyles from '@mui/styles/makeStyles';
import './App.css';

const useStyles = makeStyles({
  disabled: {
      cursor: 'not-allowed !important'
  }
})

function App() {
  const [isDisabled, setIsDisabled ] = useState(false);
  const variant = isDisabled ? "outlined" : "contained";

  const classes = useStyles();

  return (
      <div className="App">
        <Stack spacing={3} sx={{ width: 500 }}>
          <Autocomplete
            multiple
            id="tags-outlined"
            options={top100Films}
            getOptionLabel={(option) => option.title}
            defaultValue={[top100Films[13]]}
            filterSelectedOptions
            disabled={isDisabled}
            classes={
              isDisabled ? {
              root: classes.disabled,
              input: classes.disabled,
              inputRoot: classes.disabled,
            } : {}}
            renderInput={(params) => (
              <TextField
                {...params}
                label="Favorite movie"
                placeholder="Favorites"
              />
            )}
          />
          <Button variant={variant} onClick={() => setIsDisabled(!isDisabled)}>
            {isDisabled ? "Enable" : "Disable"}
          </Button>
        </Stack>
      </div>
  );
}

基本的なコードは公式ドキュメントのデモを元にしており、disabledの切り替えと disabled 時にカーソルを変える部分のみを実装した。

mui.com

難しいよMUI...

追記:styledを用いてMaterial UIでAutoCompleteで cursor:"not-allowrd"にする方法

以下のようにやれば styled を用いても実現できることがわかったので追記。
※実際の変更コミットを貼る

github.com

Material UIではdisableになった際にclassに Mui-disabled が付与される。
Chromeなどのdevtoolsで実際にHTMLを見て確認)

それに合わせる形で

const CustomAutocomplete = styled(Autocomplete)({
  ".Mui-disabled": {
    cursor: 'not-allowed !important'
  }
})

という形でclass名を付与した。