Select box with placeholder in React
はじめに
こんにちは。kimizuy です。
今回は React を使ってプレースホルダー付きのシンプルなセレクトボックスの実装例を紹介します。
セレクトボックスでテキストフィールドのようなプレースホルダーを表現するには一工夫が必要だったので、本記事ではそこで得た知見を共有できたら幸いです。
1 つのファイルで管理したいという目的のみでスタイリングには styled-components
を使っています。適宜、ご自身の環境に読みかえてください。
tldr
早速、コード例をご紹介します。
こだわりポイントは非クリック時のセレクトボックスの文字色です。
プレースホルダーのときはライトグレー、それ以外を選択しているときはブラックにして、有効/無効な値を選択しているかがわかるような見た目にしました。
CodeSandbox も用意しました。実際に触って挙動を確かめてみてください。
iimport styled from "styled-components";
import "./styles.css";
const StyledSelect = styled.select`
width: 200px;
height: 50px;
background-color: white;
&.-placeholder {
color: lightgrey;
}
`;
const StyledOption = styled.option`
color: black;
background-color: white;
`;
const Placeholder = styled.option`
color: lightgrey;
background-color: white;
`;
type Props = {
options: { value: string; label: string }[];
} & React.SelectHTMLAttributes<HTMLSelectElement>;
const SelectBoxWithPlaceholder = ({
options,
placeholder,
onChange,
...props
}: Props) => {
return (
<StyledSelect
{...props}
className={placeholder ? "-placeholder" : ""}
onChange={(event) => {
onChange?.(event);
if (placeholder) {
if (event.currentTarget.value) {
event.currentTarget.classList.remove("-placeholder");
return;
}
event.currentTarget.classList.add("-placeholder");
}
}}
>
{placeholder && (
<Placeholder value="" selected>
{placeholder}
</Placeholder>
)}
{options.map(({ value, label }, i) => {
return (
<StyledOption key={value} value={value}>
{label}
</StyledOption>
);
})}
</StyledSelect>
);
};
const sample: Props["options"] = [
{ value: "foo", label: "foo" },
{ value: "bar", label: "bar" },
{ value: "baz", label: "baz" }
];
export default function App() {
return (
<div className="App">
<SelectBoxWithPlaceholder
options={sample}
placeholder="選択してください"
/>
</div>
);
}
簡単な解説
onchange
のイベントハンドラ内で -placeholder
クラス(BEM でいうモディファイアクラスみたいなの)を値の有無に応じて追加したり削除したりしています。
例えば、値がある場合はプレースホルダー以外の選択肢が選ばれている状態なので、-placeholder
を削除する、といった処理をしています。
これによってセレクトボックスの文字色を変更しています。
onChange={(event) => {
onChange?.(event);
if (placeholder) {
if (event.currentTarget.value) {
event.currentTarget.classList.remove("-placeholder");
return;
}
event.currentTarget.classList.add("-placeholder");
}
}}
おわりに
今回はプレースホルダーのあるセレクトボックスの実装例をご紹介しました。
<option>
の見た目は OS やブラウザに大きく依存しているため、スタイルで融通が効きづらい点も覚えておくといいでしょう(参考)。
僕は最近まで知りませんでした。
以上、本記事が誰かのお役に立てれば幸いです。
弊社ではJamstackの知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?
もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!
求人応募してみる!