はじめに
React, Tailwind CSSでボタンコンポーネントを作ります。
初心者向けの記事です!
ボタンコンポーネント結構便利なので、毎回ボタンをベタ書きしている人がいたら是非作ってみてください。
ベタ書き辞めてコンポーネント化した時は、想像以上の快適さでびっくりした記憶があります。
何個もボタンあるけど、コンポーネント作ってないって方は是非作ってみてください!
※「ここが変」とかあったら教えてもらえると嬉しいです🙇♂️
メリット
- ボタンを作るのも変更するのも楽
- ボタンのスタイルが微妙に違うみたいなことが起きない
- 既に作ってあるボタンから使おうと思うから統一感が出る(スタイルの違うボタンが減る) などなど
コード
.tsx
type Props = React.ButtonHTMLAttributes<HTMLButtonElement> & {
children: React.ReactNode;
variant: keyof typeof buttonStyle;
};
const buttonStyle = {
"green-fill": "bg-green-400 text-white",
"red-gradation": "bg-gradient-to-r from-red-300 to-red-600 text-white, hover:from-red-600 hover:to-red-300",
"variantのkey名3": "スタイル",
"variantのkey名4": "スタイル",
} as const;
export const Button = ({ children, variant, className, ...props }: Props) => {
return (
<button
className={`rounded-md ....(ここら辺にボタンの共通のスタイル) ${buttonStyle[variant]} ${className}`}
{...props}
>
{children}
</button>
);
};
解説
buttonStyle
- variantによって複数の種類のボタンを切り替えることができ、種類ごとのスタイルをbuttonStyleに書いています。
- keyとvalue(スタイル)には好きな値を入れてください。
Button
- ボタン共通のスタイルは
rounded-md ....(ここら辺にボタンの共通のスタイル)
の部分に書きます。 -
buttonStyle[variant]
でvariantに指定したkey名のスタイルを取得しています。
variantがgreen-fillなら、buttonStyle[green-fill]
となり、bg-green-400 text-white
の値になります。 - classNameのスタイル、ボタンの共通のスタイル、variantごとのスタイルを全部くっつけたのがこのボタンのスタイルになります。
-
{...props}
では、className以外のbuttonの属性をbuttonタグに渡しています!
※ onClick、onFocus、id、、などなど
これで、buttonタグを扱うようにButtonコンポーネントを扱えるようになります!
Props
-
React.ButtonHTMLAttributes<HTMLButtonElement>
でbuttonタグが受け取れる属性をPorpsに受け取れるようになります!
※ className、onClick、name、id、、、などなど
なので、buttonタグを扱うようにButtonコンポーネントを扱えるようになります! -
variant: keyof typeof buttonStyle;
はbuttonStyleのkey名の型になります。
green-fill、red-gradation、などのkey名の文字列のみを指定することができるようになります。 -
children: React.ReactNode;
にすることで文字列以外もボタンの中に入れることができます。例えば、アイコンと文字を入れることが可能になります。
使い方
variantを指定して、ボタンの種類を選びます!
.tsx
<Button variant="green-fill">ボタン</Button>
onClickやclassNameなどbuttonに渡せるものは渡せます!
.tsx
<Button variant="green-fill" onClick={handleClick} className="px-10">ボタン</Button>
アイコンなどのコンポーネントも渡せます!
.tsx
<Button variant="red-gradation"><Icon/>ボタン</Button>