1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Atomicデザイン

Last updated at Posted at 2023-07-18

AtomicデザインとはReactなどのフロントエンドでコンポーネントに分割する際の考え方です。

コンポーネントを5つの要素でデザインする

それぞれを以下の5つにまとめました。

  1. Atoms 原子 最も小さくそれ以上分解できない要素
    1. ボタン、テキストボックス、アイコンなど単一のHTMLタグで構成されることが多い。主にCSSを適用させるために使う
  2. molecules 分子(Atoms)の組み合わせて使う、意味を持つコンポーネント
    1. アイコン+メニュー名、アイコンセット、プロフィール画像+テキストボックス
  3. organisms 有機体 moleculesを組み合わせ単体で意味を持つ要素群となる
    1. ツイート入力エリア、サイドメニュー、1つのツイートエリア
  4. templates ページのレイアウトのみを表現する要素、実際のデータは持たない
    1. サイドメニュー、メインエリア、トピックエリアなど
  5. pages 最終的に表示される1画面

以下プロフィールカードの例

Atoms カードの雛形主にCSS

import styled from "styled-components";

export const Card = (props) => {
  const { children } = props;

  return <SCard>{children}</SCard>;
};

const SCard = styled.div`
  background-color: #fff;
  box-shadow: #ddd 0px 0px 4px 2px;
  border-radius: 8px;
  padding: 16px;
`;

molecules 名前とアイコン

import styled from "styled-components";

export const UserIconWithName = (props) => {
  const { image, name } = props;
  return (
    <SContainer>
      <SImage height={160} width={160} src={image} alt={name} />
      <SName>{name}</SName>
    </SContainer>
  );
};

const SContainer = styled.div`
  text-align: center;
`;
const SImage = styled.img`
  border-radius: 50%;
`;
const SName = styled.p`
  font-size: 18px;
  font-weight: bold;
  margin: 0;
`;

Organisms 1人分のプロフィールカード

import styled from "styled-components";
import { Card } from "../../atoms/card/Card";
import { UserIconWithName } from "../../atoms/molecules/user/UserIconWithName";

export const UserCard = (props) => {
  const { user } = props;
  return (
    <Card>
      <UserIconWithName image={user.image} name={user.name} />
      <SDl>
        <dt>メール</dt>
        <dd>{user.email}</dd>
        <dt>会社名</dt>
        <dd>{user.company.name}</dd>
      </SDl>
    </Card>
  );
};

const SDl = styled.dl`
  text-align: left;
  margin-bottom: 0;
  dt {
    float: left;
  }
  dd {
    padding-left: 32px;
    padding-bottom: 8px;
    overflow-wrap: break-word;
  }
`;

templates 全体のレイアウト

import { Header } from "../atoms/layout/Header";
import { Footer } from "../atoms/layout/Footer";

export const DefaultLayout = (props) => {
  const { children } = props;
  return (
    <>
      <Header />
      {children}
      <Footer />
    </>
  );
};

pages 具体的なデータはここにある

import styled from "styled-components"
import {SearchInput} from "../molecules/SearchInput"
import { UserCard } from "../organisms/user/UserCard";

const users = [...Array(10).keys()].map((val) => {
  return {
    id: val,
    name: `パッチid${val}`,
    image: "https://source.unsplash.com/v0_MCllHY9M",
    email: "pachi@com",
    company: {
      name: "ぱち会社"
    }
  }
});

export const Users = () => {
  return (
    <SContainer>
      <h2>ユーザー一覧</h2>
      <SearchInput />
      <SUserArea>
        {users.map((user) =>(
          <UserCard key={user.id} user={user} />
        ))}
      </SUserArea>
    </SContainer>
  )
}

const SContainer = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 24px;
`
const SUserArea = styled.div`
  padding-top: 40px;
  width: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  grid-gap:20px;

`

ルーティング templateとpageが設定されている

import { BrowserRouter, Switch, Route } from "react-router-dom"
import { Top } from "../components/pages/Top"
import { Users } from "../components/pages/Users"
import { DefaultLayout } from "../components/templates/DefaultLayout"
import { HeaderOnly } from "../components/templates/HeaderOnly"

export const Router = () => {
  return (
    <BrowserRouter>
      <Switch>
        <Route exact path="/">
          <DefaultLayout>
            <Top />
          </DefaultLayout>
        </Route>
        <Route path="/users">
          <HeaderOnly>
            <Users />
          </HeaderOnly>
        </Route>
      </Switch>
    </BrowserRouter>
  )
}

使う上でのポイントは最初から分割するのではなく作っていくうちに必要に応じて分割していくことだと思います。
だから、小規模なページの場合は5つの要素全てを使う必要がない場合もあります。

参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?