1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

型でButtonのスタイルを切り替える方法を変更してみた。

Last updated at Posted at 2024-09-21

はじめに

親要素から Button コンポーネントに variant を渡して Button のスタイルを変更させていたものを下のように変更した。

  • 変更前:MUI の Button がデフォで持っていた variant によって Button のスタイルを変更させる方法
  • 変更後:新たに Button に ui という型を持たせて Button のスタイルを変更させる方法
    ButtonComponent.png

さっそくコードと画像を用いて説明する。

前提知識

変更点を説明する前の前提知識として、MUI の Button はvariantというpropsを受け取れる。variant で受け取った値によって下記のように変更できる。
standard MUI Button.png

<Button variant="text">Text</Button>
<Button variant="contained">Contained</Button>
<Button variant="outlined">Outlined</Button>

変更前

変更前は、前提知識で紹介した MUI の Button がデフォルトで持っているvariantの値によってスタイルを以下のようにラップしていた。

hogeButton.tsx
export default function HoggButton() {
  interface HoggType {
    variant: string;
  }

  const HoggButton = styled(MuiButton)<HoggType>`
    width: 200px;
    padding: 10px;
    ${(props) => {
      if (props.variant === "outlined") {
        return css`
          background-color: #000;
          border: 5px solid green;
          &:hover {
            background-color: #fff;
            border: 5px solid red;
          }
        `;
      } else if (props.variant === "text") {
        return css`
          color: red;
          background-color: #fff;
          border: 5px solid yellow;
          &:hover {
            background-color: #fff;
            border: 5px solid blue;
          }
        `;
      }
    }}
  `;

  return (
    <div
      style={{ border: "5px solid red", padding: "5px", marginBottom: "5px" }}
    >
      <p style={{ textAlign: "center" }}>variant</p>
      <div
        style={{
          width: "100vw",
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
          gap: "20px",
        }}
      >
        <HoggButton variant={"contained"}>variant={"contained"}</HoggButton>
        <HoggButton variant={"outlined"}>variant={"outlined"}</HoggButton>
        <HoggButton variant={"text"}>variant={"text"}</HoggButton>
      </div>
    </div>
  );
}

ビジュアルで見ると下のようなイメージ
variant.gif

変更後

元々 MUI で持っていたvariantでのスタイル変更を辞め、新たにuiという型を作った。
値は、primarysecondaryというstringを受け取れるように宣言した。

fooButton.tsx
  export default function FooButton() {
  interface FooType {
    ui: "primary" | "secondary";
  }

  const FooButton = styled(MuiButton)<FooType>`
    width: 200px;
    padding: 10px;

    ${(props) => {
      if (props.ui === "primary") {
        return css`
          background-color: #fff;
          border: 5px solid blue;
          border-radius: 20px;
          &:hover {
            color: #909;
            border: 5px solid #909;
          }
        `;
      } else if (props.ui === "secondary") {
        return css`
          color: red;
          background-color: #fff;
          border-radius: 20px;
          border: 5px solid blue;
          &:hover {
            background-color: #fff;
            border: 5px solid red;
          }
        `;
      }
    }}
  `;

  return (
    <div
      style={{ border: "5px solid blue", padding: "5px", marginBottom: "5px" }}
    >
      <p style={{ textAlign: "center" }}>ui</p>
      <div
        style={{
          width: "100vw",
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
          gap: "20px",
        }}
      >
        <FooButton ui={"primary"}>ui={"primary"}</FooButton>
        <FooButton ui={"secondary"}>ui={"secondary"}</FooButton>
      </div>
    </div>
  );
}

ビジュアルで見ると下のようなイメージ
ui.gif

変更したコードのみを抽出してみた

hogeButton.tsx
// 変更前
if (props.variant === "text") {
        return css`
          color: red;
          background-color: #fff;
          border: 5px solid yellow;
          &:hover {
            background-color: #fff;
            border: 5px solid blue;
          }
        `;
        }

<HoggButton variant={"text"}>variant={"text"}</HoggButton>
fooButton.tsx
// 変更後
if (props.ui === "primary") {
        return css`
          background-color: #fff;
          border: 5px solid blue;
          border-radius: 20px;
          &:hover {
            color: #909;
            border: 5px solid #909;
          }
        `;
      }

<FooButton ui={"primary"}>ui={"primary"}</FooButton>

なんで変更したのか

今の現場では、主に利用している Button が 2 種類存在する。
変更前までは、varianttextを渡しているものを決定ボタンなどの主要ボタンとしており、variantoutlineを渡しているものをキャンセルボタンとしていた。

だが、同僚からvariantで渡しているボタンの名前どうにかならないの?というレビューを受けた。

対策としてuiという型を作り、primarysecondaryという値によってボタンのスタイルが変更できるようにした。1

まとめ

MUI が既存で持っている props(variant)でのスタイル変更から、Button に新しく型を持たせてスタイルを変更する方法についてまとめた。

ちなみに初めてテックブログ的なものを書いたので、月 1 回くらいのペースで継続していきたいと思う。

参考文献

  1. 主要で使うボタンだから、primary、その次に使うボタンだからsecondaryと安直に決めてしまったけど、良い命名とかあると教えて欲しい 🙇‍♂️

1
2
0

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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?