13
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Material-UI】TextFieldコンポーネントのdisabledスタイルをカスタマイズする方法

Last updated at Posted at 2020-05-29

はじめに

フレームワークやライブラリを利用して開発を行うと、やはり少なからず、カスタマイズする必要が出てくることがあります。
今回は、「React」 × 「UIフレームワークのMaterial-UI」を使って開発する際にちょっと手こずったポイントがありましたので紹介です。

対象のコンポーネント 【TextField】

インプットフィールドや、セレクトボックスなど、HTMLタグの<input>として活用できます。

Material-UIについて

Material-UIはもともとあらゆるAPIが用意されており、カスタマイズ性も結構担保されており使いやすい印象です。
しかし、今回紹介するTextFieldコンポーネントで入力させたくないdisabledのUIを変更したい際に問題が出てきました。

基本的なカスタマイズ

基本的に用意されているカスタマイズ方法として、公式ドキュメントをベースにButtonコンポーネントのカスタマイズを行った際のソースコードが以下です。

import React from "react";
import Button from "@material-ui/core/Button";
import FormLabel from "@material-ui/core/FormLabel";
import { makeStyles } from "@material-ui/core/styles";
import "./styles.css";

const styles = makeStyles(theme => ({
  rootBtn: { // Buttonクラスのrootクラス
    marginRight: "1em",
    backgroundColor: "#ff8800",
    "&:disabled": {
      color: "#bababa",
      backgroundColor: "#dadada"
    }
  }
}));

export default function App() {
  const classes = styles();

  return (
    <div className="App">
      <h1>ボタンの例</h1>
      <div>
        <Button className={classes.rootBtn}>Button</Button>
        <FormLabel>通常デザイン</FormLabel>
      </div>
      <div>
        <Button className={classes.rootBtn} disabled>
          Button
        </Button>
        <FormLabel>disabledデザイン</FormLabel>
      </div>
    </div>
  );
}

Image from Gyazo

上が機能するデザインで、下がdisabledにした場合になります。
公式ドキュメントにあるように、disabledAPIがtrueの場合、rootに対して擬似クラスを宣言するように指示されています。

Pseudo-class applied to the root element if disabled={true}.
参照:公式ドキュメントより

今回、rootクラスにrootBtnを指定して、その擬似クラスにdisabledのスタイルを定義しています。
有効になるトリガーは、disabledのAPIがtrueの場合になるため、下のボタンの時のみこのスタイルが有効になっています。

このように、APIにCSSクラスに用意されたものがあり、簡単にスタイルを環境に合わせてカスタマイズすることができるのは大きな魅力です。

TextFieldでのカスタマイズ

上記のButtonコンポーネントの感じで作っていたら失敗しました。
全然スタイルが効かない。仕方なく、ドキュメントを眺めていても一向に解決方法は見当たりませんでした。

そこで、構造を見にいくと、TextFieldコンポーネントは、いくつかのコンポーネントが合わさって構成されているようでした。

<!-- inputタグラップされて形成されている -->
<div class="TextField">
  <input class="input-base">
  ...
  </>
</>

disabledのスタイルは<input>で定義されているようだったので、どうにかここを上書きする方法が必要でした。

ローカルルールを参照させる $ruleName

こんな書き方があったなんて知らなかった。


const styles = {
  root: {
    '&$disabled': {
      color: 'white',
    },
  },
  disabled: {},
};

これを参考にスタイルするとうまくスタイルが効きました。
ソースは以下です。

import React from "react";
import TextField from "@material-ui/core/TextField";
import FormLabel from "@material-ui/core/FormLabel";
import { makeStyles } from "@material-ui/core/styles";
import "./styles.css";

const styles = makeStyles(theme => ({
  rootTxt: {
    marginRight: "1em",
    "&$disabled": {
      color: "#bababa",
      backgroundColor: "#dadada"
    }
  },
  disabled: {}
}));

export default function App() {
  const classes = styles();

  return (
    <div className="App">
      <h1>テキストフィールドの例</h1>
      <div>
        <TextField
          InputProps={{
            classes: {
              root: classes.rootTxt,
              disabled: classes.disabled
            }
          }}
          defaultValue="TextField"
        />
        <FormLabel>通常デザイン</FormLabel>
      </div>
      <br />
      <div>
        <TextField
          InputProps={{
            classes: {
              root: classes.rootTxt,
              disabled: classes.disabled
            }
          }}
          defaultValue="TextField"
          disabled
        />
        <FormLabel>disabledデザイン</FormLabel>
      </div>
    </div>
  );
}

Image from Gyazo

さいごに

今回取り上げたのは、TextFieldコンポーネントですが、他にもコンポーネントを掛け合わせた形で表現されているコンポーネントはたくさんあります。
そういったコンポーネントもおそらくこの書き方が必要になってきそうですね。

前提として知っているのと知っていないので、使い方や設計が大きく変わってきそうだなと感じながら今回はなんとか解決することができました!

紹介した内容のSnadbox

Edit Material-UI_TextField

P.S

気がついた頃にはこんなこと書いてた!

The TextField is a convenience wrapper for the most common cases (80%). It cannot be all things to all people, otherwise the API would grow out of control.

13
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?