メインコンテンツまでスキップ

· 約6分
山田 哲也

みなさん、こんにちは! 山田です。

前回の記事で Figma を使ってボタンコンポーネントを作ってみました。
今回はそのデザインを元に React と Tailwind CSS で実装していきたいと思います。

開発環境の準備

今回開発環境に Nextjs を選びました。
Next.js はセットアップ時に Tailwind CSS のインストールを選択できるので、すぐに開発を始められます。

セットアップ時の質問は全てデフォルトで進めていきます。

> npx create-next-app@latest
Need to install the following packages:
create-next-app@14.0.4
Ok to proceed? (y) y
✔ What is your project named? … button-ui-example
✔ Would you like to use TypeScript? … No / Yes # Yesを選択
✔ Would you like to use ESLint? … No / Yes # Yesを選択
✔ Would you like to use Tailwind CSS? … No / Yes # Yesを選択
✔ Would you like to use `src/` directory? … No / Yes # Noを選択
✔ Would you like to use App Router? (recommended) … No / Yes # Yesを選択
✔ Would you like to customize the default import alias (@/*)? … No / Yes # Noを選択

Next.js のセットアップが完了したら、プロジェクトのディレクトリに移動しておきます。

UI の確認は Storybook で行うので、こちらもセットアップします。

npx storybook@latest init

セットアップが完了すると、自動的に Storybook が起動します。

Storybook

プリセットでいくつかコンポーネントが用意されていますが、不要なので削除しておきます。

rm -rf stories/*

Storybook の設定

次に Storybook の設定を行います。

簡単なボタンコンポーネントのファイルを作成し、以下の内容で保存します。

// app/components/Button.tsx
import { ReactNode, FC } from "react";

type Props = {
children: ReactNode;
};

export const Button: FC<Props> = ({ children }) => {
return <button>{children}</button>;
};

次に、このコンポーネントを Storybook で確認できるようにします。

// stories/Button.stories.tsx
import type { Meta, StoryObj } from "@storybook/react";
import { Button } from "../app/components/Button";

const meta = {
component: Button,
parameters: {
layout: "centered",
},
tags: ["autodocs"],
} satisfies Meta<typeof Button>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Primary: Story = {
args: {
children: "ボタン",
},
};

Storybook を確認すると、ボタンコンポーネントが表示されます。

meta オブジェクトの tags に autodocs を指定することで、コンポーネントのドキュメントを自動生成することができます。
また、parameters に layout: "centered"を指定することで、コンポーネントを中央に表示することができるので覚えておくと便利です。

Storybook

最後に preview.js に globals.css を読み込ませます。
この時 globals.css に記載されている@tailwind xxxx以外の内容は不要なので削除しておきます。

// .storybook/preview.js
import type { Preview } from "@storybook/react";
import "../app/globals.css";

(省略)

これで Tailwind CSS によるスタイルが Storybook に反映されるようになりました。

ボタンコンポーネントの実装

Figma でデザインしたボタンコンポーネントにはいくつかのバリアントがありました。
ボタンコンポーネントに渡すプロパティの値によってバリアントを変化させるのが一般的かと思いますが、プロパティの数が多くなってくると、条件分岐を独自に実装するのはかなり面倒です。

そこで、「Class Variance Authority」というライブラリを使って、複数のバリアントを持つコンポーネントを簡単に実装できるようにします。

まずはライブラリをインストールします。

npm install class-variance-authority

次に、Button コンポーネントを以下のように修正します。

// app/components/Button.tsx
import { cva, type VariantProps } from "class-variance-authority";
import { ButtonHTMLAttributes, FC } from "react";

const button = cva("text-white rounded-md", {
variants: {
intent: {
primary: "bg-blue-500 hover:bg-blue-600",
secondary: "bg-pink-500 hover:bg-pink-600",
},
size: {
sm: "px-2 py-1 text-sm",
md: "px-4 py-2 text-base",
lg: "px-6 py-3 text-lg",
},
},
defaultVariants: {
intent: "primary",
size: "md",
},
});

export interface ButtonProps
extends ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof button> {}

export const Button: FC<ButtonProps> = ({
className,
intent,
size,
children,
...props
}) => {
return (
<button className={button({ intent, size, className })} {...props}>
{children}
</button>
);
};

cva メソッド利用してバリアントの型を構築していきます。
第一引数に共通で適用されるクラス、第二引数にバリアントとそのバリアントに適用されるクラスを指定することができます。
また、defaultVariants を追加することで、デフォルトで表示されるバリアントを指定することができます。

(なんて便利なんだ...)

では、最後に Storybook でコンポーネントを確認してみましょう。

Storybook

うまく切り替えができているようですね 🎉

以上でボタンコンポーネントの実装は完了です。
複数のバリアントを持つコンポーネントを実装する際は、ぜひこのライブラリを使ってみてください。

それではまた次回!

· 約5分
山田 哲也

みなさん、こんにちは! 山田です。

今回は Figma でボタンコンポーネントを作ってみようと思います!

「あれ、お前 SRE エンジニアじゃなかった?」🤔 と思われるかもしれませんが、実は Figma や React などフロント周りの技術も好きで触っていたりします。

あと、社内で Figma 部というコミュニティを作って勉強会を開いたりもしてるんです。
こちらもどんな雰囲気でやっているのか今度記事にしてみようと思ってますのでお楽しみに!

さて、前置きが長くなっちゃいましたが、早速作っていきましょう!

ボタンコンポーネントの仕様

今回作成するボタンコンポーネントの仕様は以下の通りです。

種類サイズテキスト色背景色ホバー時の背景色角丸パディングフォントサイズテキストの高さ
プライマリsm#FFFFFF#3B82F6#2563EB6px横: 8px, 縦: 4px14px20px
プライマリmd#FFFFFF#3B82F6#2563EB6px横: 16px, 縦: 8px16px24px
プライマリlg#FFFFFF#3B82F6#2563EB6px横: 24px, 縦: 12px18px28px
セカンダリsm#FFFFFF#EC4899#DB27776px横: 8px, 縦: 4px14px20px
セカンダリmd#FFFFFF#EC4899#DB27776px横: 16px, 縦: 8px16px24px
セカンダリlg#FFFFFF#EC4899#DB27776px横: 24px, 縦: 12px18px28px

ボタンコンポーネントの作成

まずは sm サイズのプライマリボタンから作ってみましょう。

  1. テキストツールでボタンという内容のテキストを作成 → フレーム化。
  2. 背景を#3B82F6に設定して、角丸を 6px 、パディングを横: 8px, 縦: 4px に設定。
  3. テキストを選択して、テキスト色を#FFFFFF、フォントサイズを 14px 、テキストの高さを 20px に設定。

するとこんな感じのボタンができ上がります。

smサイズのプライマリボタン

これをコンポーネント化します。

コンポーネント化

これで sm サイズのプライマリボタンが作成できました!

他のサイズのボタンも作りたいので、Variant という機能を使って、サイズや背景色などのプロパティを変更できるようにします。

コンポーネントを選択した状態で右クリック ▶︎ Main Component ▶︎ Add Variant で Variant を追加することができます。

Variantの追加

Variant を使って、md と lg サイズのボタンを作成していきます。

そうしてできたのがこちら。プロパティ名を size にして、sm, md, lg という値を設定しています。

mdとlgのサイズのボタン

次にホバー時の Variant を作成して、マウスオーバーした時に背景色が変わるようにします。

  1. 現在の 3 つの Variant をコピペして、コピーした Variant の背景色を#2563EBに変更
  2. hover プロパティを追加して、true, false という値を設定。
  3. ホバー前のボタンの選択し、prototype からホバー時にコピーした Variant に遷移するように設定

設定が完了するとこんな感じになります。

ホバー時のVariant

プレビュー画面で動作を確認してみると...

ホバー時のVariant

お、いい感じです 😊

さて、あとはセカンダリボタンを作るだけですね。

  1. プライマリボタンのコンポーネントをコピーして、背景色を#EC4899に変更、ホバー時の背景色を#DB2777に変更。
  2. intent プロパティを追加して、primary, secondary という値を設定。

するとこんな感じに。

セカンダリボタン

これでボタンの見た目を自由に変更できるようになりました ✌️

ボタンのプロパティ

次回はこのボタンコンポーネントを React で実装してみたいと思います!お楽しみに〜

· 約3分
山田 哲也

みなさん、こんにちは!株式会社リーディングマークの山田です。

ついに、弊社のテックブログが開設されました!

これから、技術情報や社内の取り組みなどをこちらで共有していきますが、まずはなぜこのブログを始めたのか、その背景をお話ししたいと思います。

認知度向上とアウトプット文化の醸成

私たちのサービス「ミキワメ」は多くの方に利用され、導入企業もますます増えています。しかし、まだ十分に世間に知られていないと感じています。

たくさんの人たちに私たちのことを知ってもらうために、エンジニアとデザイナーが集まる組織として何ができるか考えました。 プロダクトを開発していく中で得られた知見や取り組みを共有することが認知度を高める一つの方法だと思い、このブログを始めることにしました。

目標は認知度を上げることだけではないです。メンバーが学んだことを外に発信する文化を作ることも大切だと考えています。 開発の過程で新しい技術を導入したり、難しい課題に取り組んだりすることは、個人の成長につながります。こういった経験は共有することで、他のメンバーや同じ問題に直面している人たちにも役立つ知識になると思っています。

最後に

個人的にも、チームリーダーとしてメンバーがチャレンジできる機会をたくさん作っていきたいという想いがあったので、その一つとしてこのブログを立ち上げることができて非常に嬉しく思います。

まだまだアウトプットする文化が根付いているとは言えない状況ですが、この活動をきっかけに変化が生まれたらと思っています。

暖かい目で見守っていただけると嬉しいです。これからどうぞよろしくお願いします!