Layout

Grid

Grid 컴포넌트는 CSS Grid를 사용하며 디자인 토큰을 JSX에서 사용할 수 있도록 도와줍니다.

import { Flex, Grid } from "@seed-design/react";

export default function GridPreview() {
  return (
    <Grid columns={3} gap="x2" width="full" height="full" p="x8">
      {Array.from({ length: 6 }).map((_, index) => (
        <Flex
          key={index}
          bg="palette.purple300"
          color="palette.purple700"
          borderRadius="r2"
          align="center"
          justify="center"
        >
          {index + 1}
        </Flex>
      ))}
    </Grid>
  );
}

Props

Grid

Prop

Type

GridItem

GridItem은 Grid 컨테이너 내에서 아이템의 배치를 제어하는 컴포넌트입니다. Grid 내부의 모든 아이템이 GridItem일 필요는 없습니다.

Prop

Type

Columns and Rows

<Grid>columns 또는 rows prop에 number를 지정하여 grid-template-columns 또는 grid-template-rowsrepeat(${columns|rows}, minmax(0, 1fr))로 설정할 수 있습니다.

import { Divider, Flex, Grid, HStack } from "@seed-design/react";

export default function GridNumber() {
  return (
    <HStack gap="x4" width="full" height="full" p="x8">
      <Grid flexGrow columns={2} gap="x2">
        {[1, 2, 3, 4, 5].map((n) => (
          <Flex
            key={n}
            bg="palette.purple300"
            color="palette.purple700"
            borderRadius="r2"
            align="center"
            justify="center"
          >
            {n}
          </Flex>
        ))}
      </Grid>
      <Divider orientation="vertical" />
      <Grid flexGrow rows={2} gap="x2" autoFlow="column">
        {[1, 2, 3, 4, 5].map((n) => (
          <Flex
            key={n}
            bg="palette.green300"
            color="palette.green700"
            borderRadius="r2"
            align="center"
            justify="center"
          >
            {n}
          </Flex>
        ))}
      </Grid>
    </HStack>
  );
}

<Grid>columns 또는 rowsgrid-template-columns 또는 grid-template-rows 값을 직접 지정할 수도 있습니다.

import { Divider, Flex, Grid, HStack } from "@seed-design/react";

export default function GridString() {
  return (
    <HStack gap="x4" width="full" height="full" p="x8">
      <Grid flexGrow columns="3fr 1fr" gap="x2">
        {[1, 2, 3, 4, 5].map((n) => (
          <Flex
            key={n}
            bg="palette.purple300"
            color="palette.purple700"
            borderRadius="r2"
            align="center"
            justify="center"
          >
            {n}
          </Flex>
        ))}
      </Grid>
      <Divider orientation="vertical" />
      <Grid flexGrow rows="1fr 3fr" gap="x2" autoFlow="column">
        {[1, 2, 3, 4, 5].map((n) => (
          <Flex
            key={n}
            bg="palette.green300"
            color="palette.green700"
            borderRadius="r2"
            align="center"
            justify="center"
          >
            {n}
          </Flex>
        ))}
      </Grid>
    </HStack>
  );
}

Spanning Items

<GridItem>을 활용하여 그리드 아이템이 여러 열이나 행을 차지하도록 할 수 있습니다.

  • colSpan 또는 colStart, colEnd prop으로 열 span을 지정합니다. colSpan="full"을 전달하면 행 전체 (좌우 양 끝)을 차지합니다.
  • rowSpan 또는 rowStart, rowEnd prop으로 행 span을 지정합니다. rowSpan="full"을 전달하면 열 전체 (상하 양 끝)을 차지합니다.
import { Divider, Grid, GridItem, HStack } from "@seed-design/react";

export default function Spanning() {
  return (
    <HStack gap="x4" width="full" height="full" p="x8">
      <Grid flexGrow columns={4} gap="x2">
        <GridItem
          colSpan={2}
          display="flex"
          bg="palette.purple600"
          color="palette.purple200"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          1
        </GridItem>
        <GridItem
          display="flex"
          bg="palette.purple300"
          color="palette.purple600"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          2
        </GridItem>
        <GridItem
          display="flex"
          bg="palette.purple300"
          color="palette.purple600"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          3
        </GridItem>
        <GridItem
          colSpan="full"
          display="flex"
          bg="palette.purple600"
          color="palette.purple200"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          4
        </GridItem>
        <GridItem
          display="flex"
          bg="palette.purple300"
          color="palette.purple600"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          5
        </GridItem>
        <GridItem
          rowSpan={2}
          display="flex"
          bg="palette.purple600"
          color="palette.purple200"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          6
        </GridItem>
        <GridItem
          display="flex"
          bg="palette.purple300"
          color="palette.purple600"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          7
        </GridItem>
        <GridItem
          colStart={2}
          colEnd={-1}
          display="flex"
          bg="palette.purple600"
          color="palette.purple200"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          8
        </GridItem>
      </Grid>
      <Divider orientation="vertical" />
      <Grid flexGrow rows={4} gap="x2" autoFlow="column">
        <GridItem
          rowSpan={2}
          display="flex"
          bg="palette.green600"
          color="palette.green200"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          1
        </GridItem>
        <GridItem
          display="flex"
          bg="palette.green300"
          color="palette.green600"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          2
        </GridItem>
        <GridItem
          display="flex"
          bg="palette.green300"
          color="palette.green600"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          3
        </GridItem>
        <GridItem
          rowSpan="full"
          display="flex"
          bg="palette.green600"
          color="palette.green200"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          4
        </GridItem>
        <GridItem
          display="flex"
          bg="palette.green300"
          color="palette.green600"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          5
        </GridItem>
        <GridItem
          colSpan={2}
          display="flex"
          bg="palette.green600"
          color="palette.green200"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          6
        </GridItem>
        <GridItem
          display="flex"
          bg="palette.green300"
          color="palette.green600"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          7
        </GridItem>
        <GridItem
          rowStart={2}
          rowEnd={-1}
          display="flex"
          bg="palette.green600"
          color="palette.green200"
          borderRadius="r2"
          alignItems="center"
          justifyContent="center"
        >
          8
        </GridItem>
      </Grid>
    </HStack>
  );
}

Auto Flow

<Grid>autoFlow prop을 사용하여 아이템이 배치되는 방향을 지정할 수 있습니다.

import { useState } from "react";
import { Grid, type GridProps, GridItem, VStack } from "@seed-design/react";
import { SegmentedControl, SegmentedControlItem } from "seed-design/ui/segmented-control";

type AutoFlow = NonNullable<GridProps["autoFlow"]>;

export default function AutoFlow() {
  const [autoFlow, setAutoFlow] = useState<AutoFlow>("row");

  const isColumn = autoFlow.startsWith("column");
  const color = isColumn ? "green" : "purple";

  const gridProps = isColumn ? { rows: 3 } : { columns: 3 };
  const spanProps = isColumn ? { rowSpan: 2 } : { colSpan: 2 };

  return (
    <VStack gap="x6" width="full" height="full" p="x8" align="center">
      <Grid {...gridProps} alignSelf="stretch" flexGrow gap="x2" autoFlow={autoFlow}>
        {[1, 2].map((n) => (
          <GridItem
            key={n}
            {...spanProps}
            display="flex"
            bg={`palette.${color}600`}
            color={`palette.${color}200`}
            borderRadius="r2"
            alignItems="center"
            justifyContent="center"
          >
            {n}
          </GridItem>
        ))}
        {[3, 4, 5].map((n) => (
          <GridItem
            key={n}
            display="flex"
            bg={`palette.${color}300`}
            color={`palette.${color}600`}
            borderRadius="r2"
            alignItems="center"
            justifyContent="center"
          >
            {n}
          </GridItem>
        ))}
      </Grid>
      <SegmentedControl
        value={autoFlow}
        onValueChange={(value) => setAutoFlow(value as AutoFlow)}
        aria-label="Auto Flow"
      >
        <SegmentedControlItem value="row">row</SegmentedControlItem>
        <SegmentedControlItem value="row dense">row dense</SegmentedControlItem>
        <SegmentedControlItem value="column">column</SegmentedControlItem>
        <SegmentedControlItem value="column dense">column dense</SegmentedControlItem>
      </SegmentedControl>
    </VStack>
  );
}

Auto Rows / Columns

<Grid>autoRows 또는 autoColumns prop을 사용하여 암시적으로 생성되는 행이나 열의 크기를 지정할 수 있습니다. 동적으로 아이템이 추가되는 그리드에서 유용합니다.

import { Divider, Flex, Grid, HStack } from "@seed-design/react";

export default function AutoRowsColumns() {
  return (
    <HStack gap="x4" width="full" height="full" p="x8" align="flex-start">
      <Grid flexGrow columns={3} autoRows="1fr" gap="x2">
        {[1, 2, 3, 4, 5].map((n) => (
          <Flex
            key={n}
            bg={n === 2 ? "palette.purple600" : "palette.purple300"}
            color={n === 2 ? "palette.purple200" : "palette.purple700"}
            borderRadius="r2"
            align="center"
            justify="center"
            p="x4"
          >
            {n === 2
              ? "Ea anim non aute minim ea deserunt enim Elit deserunt laborum et quis sit."
              : n}
          </Flex>
        ))}
      </Grid>
      <Divider orientation="vertical" style={{ alignSelf: "stretch" }} />
      <Grid flexGrow rows={3} autoColumns="1fr" autoFlow="column" gap="x2">
        {[1, 2, 3, 4, 5].map((n) => (
          <Flex
            key={n}
            bg={n === 2 ? "palette.green600" : "palette.green300"}
            color={n === 2 ? "palette.green200" : "palette.green700"}
            borderRadius="r2"
            align="center"
            justify="center"
            p="x4"
          >
            {n === 2
              ? "Ea anim non aute minim ea deserunt enim Elit deserunt laborum et quis sit."
              : n}
          </Flex>
        ))}
      </Grid>
    </HStack>
  );
}

Using asChild Prop

GridItemasChild prop을 사용하여 자식 요소에 직접 grid 속성을 적용할 수 있습니다.

Composition

asChild prop에 대해 자세히 알아봅니다.

<Grid columns={3}>
  <GridItem colSpan={2} asChild>
    <a href="/link">Link spanning 2 columns</a>
  </GridItem>
</Grid>

Using Box for Grid Item Placement

GridItem은 내부적으로 colSpan, colStart, colEnd, rowSpan, rowStart, rowEnd prop을 gridColumngridRow 스타일로 변환하여 Box에 적용합니다.

따라서 Box 컴포넌트에서 gridColumn, gridRow prop을 직접 사용할 수도 있습니다.

<Grid columns={3}>
  <Box gridColumn="span 2">colSpan=2</Box>
  <Box gridColumn="1 / -1">colSpan=full</Box>
  <Box gridColumn="2 / 4">colStart=2 colEnd=4</Box>
</Grid>

Last updated on