Material-UIでテキストフィールドをカスタマイズして実装する方法
こんにちは、 Gaji-Labo アシスタントエンジニアの石垣です。
今回は Material-UI でテキストフィールドを作る際にいくつかハマった点があったため、テキストフィールドの作成方法についてまとめたいと思います。
Material-UI でのテキストフィールドの作成方法
Material-UI には標準で TextField
というコンポーネントが用意されており、 import するだけで Material Design 準拠のテキストフィールドを使用することができます。
ただし、TextField
コンポーネントにはフィールドのラベル、フィールド本体、ヘルパーテキストの全てが同梱されているため、パーツそれぞれで細かいスタイル変更や挙動の変更を行おうとすると大変な手間がかかります。
TextField
コンポーネント自体が FormControl
、 FormLabel
、 OutlinedInput
などのコンポーネントが組み合わさって構成されているため、それぞれを単体で使用することでカスタマイズを行うことができます。
たとえば、TextField
ではデフォルトでは Material Design に準拠してフィールドのラベルがフィールド内に表示されており、フォーカス時に外側に移動するような挙動となっていますが、ラベルが常に外側に表示されているテキストフィールドを作成するには以下のように実装します。
import React from "react";
import {
FormControl,
FormLabel,
FormHelperText,
OutlinedInput,
} from "@material-ui/core/";
import { createMuiTheme, ThemeProvider } from "@material-ui/core/styles";
/* ... */
export function TextField({
error,
disabled,
label,
id,
name,
type,
placeholder,
required,
onBlur,
defaultValue,
helperText,
}) {
/* ... */
const theme = createMuiTheme({
overrides: {
MuiFormControl: {
/* 全体のスタイル */
},
MuiFormLabel: {
/* ラベルのスタイル */
},
MuiOutlinedInput: {
/* フィールドのスタイル */
},
MuiFormHelperText: {
/* ヘルパーテキストのスタイル */
},
},
});
return (
<ThemeProvider theme={theme}>
<FormControl error={error} disabled={disabled}>
<FormLabel>
<div>{label}</div>
<OutlinedInput
fullWidth
id={id}
name={name}
type={type}
placeholder={placeholder}
required={required}
onBlur={onBlur} // onBlur にフィールド変更時のイベントを渡す
defaultValue={defaultValue} // defaultValue でフィールドの値を持つ
/>
</FormLabel>
<FormHelperText>{helperText}</FormHelperText>
</FormControl>
</ThemeProvider>
);
}
フィールドの状態を管理するコンポーネント FormControl
で全体をラップし、 FormLabel
内にラベルの要素と OutlinedInput
を入れ、 FormHelperText
にヘルパーテキストを入れるようにしました。
これでラベルが常に表示されたテキストフィールドを実装することができました。このように分解してから組み合わせることで個別のパーツのカスタマイズが容易になります。
onChange + value ではなく onBlur + defaultValue で値を管理する
以上のコンポーネントでは、 onBlur
にフィールド変更時のイベントを渡し、 defaultValue
props で値を保持させるという風に実装しています。
最初は onBlur と defaultValue ではなく onChange と value で値を管理するようにしていましたが、この実装方法では入力するごとにフォーカスが外れてしまう問題がありました。これを防ぐために onBlur と defaultValue で実装をしています。
まとめ
今回は Material-UI でのテキストフィールドの作成方法についてまとめました。
TextField
のように、Material-UI には他にもいくつかのコンポーネントが組み合わさった形で構成されているコンポーネントがあります。1つ1つを分解して使用することでカスタマイズが容易になります。
今後も Material-UI でのコンポーネント実装方法について知見をブログで共有していきたいと考えています。
Gaji-Laboでは、JavaScriptフレームワーク経験が豊富なパートナーさんを募集しています
Gaji-Laboでは、開発チームの一員としてプロジェクトに一緒に取り組んでくれる業務委託のパートナーさんを募集しています。
現在は特にJavaScriptフレームワーク実践と業務経験が豊富なWebフロントエンドエンジニアを必要としています。React + TypeScript、Vue.js、Next.js、Nuxt.js など、あなたの得意なフレームワークを教えて下さい!
パートナー契約へのお問い合わせもお仕事へのお問い合わせも、どちらもいつでも大歓迎です。まずはオンラインでのリモート面談からはじめましょう。ぜひお気軽にお問い合わせください!
お問い合わせしてみる!