概要


Webページを作成する際のUIデザインにおいて、“どのようにコンポーネントを作成していくべきか"という問題は誰もが抱えたことのある問題だと思います。本記事では、ページデザインの中でも初歩の初歩であるCardコンポーネントについて、その作り方とファイル構成について紹介していきます。


実装の準備


わかりやすさのため、「社員のリストを作成する」という例を挙げて説明していきます。

ディレクトリ構成は下のようなものを作成します。

card-component-directory-tree


Cardコンポーネントの作成


はじめに、Cardコンポーネントに置く各部品(画像、タイトル、サブタイトル)を構成していきます。

// src/pages/card/components/card.tsx

import React from "react"
import { Box, Grid } from "@mui/material"

import { Title, SubTitle } from "src/components/typography/index"
import { DocImg } from "src/pages/admin/card/components/documentImage"
import sampleImg from "src/assets/imgs/sampleImg.png"

import { CardContents } from "src/types/cardContents"

interface CardPropTypes {
  item: CardContents
}

export const Card: React.FC<CardPropTypes> = ({ item }) => {
  return (
    <Grid item
      sx={{
        height: "146px",
        width: "235px"
      }}
    >
      <DocImg src={sampleImg} />
      <Box
        sx={{
          height: "50px",
          borderRadius: "0 0 0.4rem 0.4rem",
          bgcolor: "white",
          "&:hover": {
            bgcolor: "#BDBDBD",
          },
        }}
      >
        <Title sx={{ pl: "0.75rem", pt: "0.375rem" }}>{item.title}</Title>
        <SubTitle
          sx={{
            m: 0,
            pt: "0.5rem",
            pr: "0.5rem",
            textAlign: "right",
            color: "text.disabled",
          }}
        >
          {item.subTitle}
        </SubTitle>
      </Box>
    </Grid>
  )
}


// src/pages/card/components/documentImg.tsx

import React from "react"
import { Box } from "@mui/material"

interface ImgSrc {
  src: string
}

export const DocImg: React.FC<ImgSrc> = ({ src }) => {
  return (
    <Box
      sx={{
        height: "94px",
        width: "233px",
      }}
    >
      <img alt="User" src={src} width="100%" />
    </Box>
  )
}

作成したcomponentsをindexでまとめてCardコンポーネントとします。

// src/pages/card/index.tsx

import React from "react"
import { Box, Grid } from "@mui/material"

import contentsList from "src/assets/json/lists.json"
import { Card } from "src/pages/admin/card/components/card"
import { SubTitle } from "src/components/typography/index"

export const CardComponent: React.FC = () => {
  return (
    <>
      <Box
        sx={{
          pt: "1.5rem",
          height: "100%",
        }}
      >
        <Box
          sx={{
            bgcolor: "E0E0E0",
            marginX: "2rem",
            borderRadius: "1.125rem"
          }}
        >
          <SubTitle
            sx={{
              pt: "1.5rem",
              pl: "1.5rem",
            }}
          >
            Card Component
          </SubTitle>
          <Grid container
            sx={{
              pl: "0.875rem",
              pb: "1rem",
              mt: "1rem",
              display: "flex",
            }}
          >
            {contentsList.map((item) => {
              <Card key={item.key} item={item}>
            })}
          </Grid>
        </Box>
      </Box>
    </Box>
  )
}

以上でCardコンポーネントの大枠が完成です。最後に今回のコンポーネントで使用したTypography, typesファイルについて紹介します。

Typography

typography 【意味】文字の体裁(書体、サイズ、行間、配列など)のこと

typographyを設定することによって、同じスタイルを適用したいコンテンツを一括で操作することができるようになります。今回の例では、Title, SubTitleの2つの種類のコンテンツに対してtypographyを設定します。

// src/components/typography

import React from "react"
import { Typography, TypographyProps } from "@mui/material"

const TextStyleComponent = (defaultStyles: TypographyProps) => {
  const TextStyle = ({ children, ...rest }: TypographyProps) => {
    return (
      <Typography {...defaultStyles} {...rest}>
        {children}
      </Typography>
    )
  }
  return TextStyle
}

export const Title = TextStyleComponent({
  fontSize: "1rem",
  lineHeight: "1rem",
  fontWeight: 700,
})

export const SubTitle = TextStyleComponent({
  fontSize: "0.875rem",
  lineHeight: "0.875rem",
  fontWeight: 400,
})

Types

今回は1例として作成したコンポーネントのため、typeについての記載はsrc/pages/card/components/card.tsx内で問題ありませんが、再利用性を高めるため別ファイルに作成しておきます。

// src/types/cardContents

export interface CardContents {
  key: string
  title: string
  subTitle: string
}

まとめ


以上Cardコンポーネントの作成手順について紹介してきました。Cardコンポーネントに対して適用させたいリストを作成してこれを反復処理させることで、目的のUIを設計することができます。 よりスマートなコードを目指してコンポーネント設計を行っていきましょう。