Image Frame

사용자가 업로드한 이미지를 표시하기 위한 컴포넌트입니다.

import { ImageFrame } from "@seed-design/react";

export default function ImageFramePreview() {
  return (
    <ImageFrame
      ratio={4 / 3}
      rounded
      stroke
      src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
      alt="Landscape photograph by Tobias Tullius"
      width="300px"
    />
  );
}

Usage

import { ImageFrame } from "@seed-design/react";
<ImageFrame
  ratio={4 / 3}
  rounded
  stroke
  src="..."
  alt="..."
  fallback={<Skeleton />}
/>

Props

Prop

Type

Examples

Ratio

다양한 비율을 지정할 수 있습니다. 1은 정사각형, 4/3은 일반적인 사진 비율, 16/9는 와이드스크린 비율입니다.

import { ImageFrame, Flex, VStack, Text } from "@seed-design/react";

export default function ImageFrameRatio() {
  return (
    <Flex gap="x2" wrap="wrap" align="flex-end">
      <VStack gap="x2" alignItems="center">
        <ImageFrame
          ratio={1}
          rounded
          stroke
          src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
          alt="1:1"
          style={{ width: 120 }}
        />
        <Text color="palette.gray700" textStyle="t1Regular">
          1:1
        </Text>
      </VStack>
      <VStack gap="x2" alignItems="center">
        <ImageFrame
          ratio={4 / 3}
          rounded
          stroke
          src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
          alt="4:3"
          style={{ width: 160 }}
        />
        <Text color="palette.gray700" textStyle="t1Regular">
          4:3
        </Text>
      </VStack>
      <VStack gap="x2" alignItems="center">
        <ImageFrame
          ratio={16 / 9}
          rounded
          stroke
          src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
          alt="16:9"
          style={{ width: 200 }}
        />
        <Text color="palette.gray700" textStyle="t1Regular">
          16:9
        </Text>
      </VStack>
    </Flex>
  );
}

Rounded

rounded prop으로 모서리 라운드 스타일을 적용할 수 있습니다.

import { ImageFrame, Flex, VStack, Text } from "@seed-design/react";

export default function ImageFrameRounded() {
  return (
    <Flex gap="x4" wrap="wrap" align="flex-end">
      <VStack gap="x2" alignItems="center">
        <ImageFrame
          ratio={4 / 3}
          rounded={false}
          src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
          alt="rounded=false"
          style={{ width: 150 }}
        />
        <Text color="palette.gray700" textStyle="t1Regular">
          rounded=false
        </Text>
      </VStack>
      <VStack gap="x2" alignItems="center">
        <ImageFrame
          ratio={4 / 3}
          rounded={true}
          src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
          alt="rounded=true"
          style={{ width: 150 }}
        />
        <Text color="palette.gray700" textStyle="t1Regular">
          rounded=true
        </Text>
      </VStack>
    </Flex>
  );
}

Stroke

stroke prop으로 테두리 스타일을 적용할 수 있습니다.

import { ImageFrame, Flex, VStack, Text } from "@seed-design/react";

export default function ImageFrameStroke() {
  return (
    <Flex gap="x4" wrap="wrap" align="flex-end">
      <VStack gap="x2" alignItems="center">
        <ImageFrame
          ratio={4 / 3}
          stroke={false}
          src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
          alt="stroke=false"
          style={{ width: 150 }}
        />
        <Text color="palette.gray700" textStyle="t1Regular">
          stroke=false
        </Text>
      </VStack>
      <VStack gap="x2" alignItems="center">
        <ImageFrame
          ratio={4 / 3}
          stroke={true}
          src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
          alt="stroke=true"
          style={{ width: 150 }}
        />
        <Text color="palette.gray700" textStyle="t1Regular">
          stroke=true
        </Text>
      </VStack>
    </Flex>
  );
}

Overlay

ImageFrameFloater를 사용하여 이미지 위에 오버레이 요소를 배치할 수 있습니다. ImageFrameBadge, ImageFrameIcon, ImageFrameIndicator, ImageFrameReactionButton 등 다양한 오버레이 컴포넌트를 제공합니다.

import { IconCarrotFill } from "@karrotmarket/react-monochrome-icon";
import {
  ImageFrame,
  ImageFrameFloater,
  ImageFrameBadge,
  ImageFrameIcon,
  ImageFrameIndicator,
  ImageFrameReactionButton,
  Flex,
  VStack,
  Text,
} from "@seed-design/react";
import { useState } from "react";

export default function ImageFrameOverlayExample() {
  const [liked, setLiked] = useState(false);

  return (
    <Flex gap="x3" wrap="wrap" align="flex-end">
      <VStack gap="x2" alignItems="center">
        <ImageFrame
          ratio={1}
          rounded
          stroke
          src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
          alt="Landscape with badge overlay"
          style={{ width: 120 }}
        >
          <ImageFrameFloater placement="bottom-end">
            <ImageFrameBadge tone="brand" variant="solid">
              NEW
            </ImageFrameBadge>
          </ImageFrameFloater>
        </ImageFrame>
        <Text color="palette.gray700" textStyle="t1Regular">
          ImageFrameBadge
        </Text>
      </VStack>

      <VStack gap="x2" alignItems="center">
        <ImageFrame
          ratio={1}
          rounded
          stroke
          src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
          alt="Landscape with icon overlay"
          style={{ width: 120 }}
        >
          <ImageFrameFloater placement="bottom-end">
            <ImageFrameIcon svg={<IconCarrotFill />} />
          </ImageFrameFloater>
        </ImageFrame>
        <Text color="palette.gray700" textStyle="t1Regular">
          ImageFrameIcon
        </Text>
      </VStack>

      <VStack gap="x2" alignItems="center">
        <ImageFrame
          ratio={1}
          rounded
          stroke
          src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
          alt="Landscape with indicator overlay"
          style={{ width: 120 }}
        >
          <ImageFrameFloater placement="bottom-end">
            <ImageFrameIndicator>+9</ImageFrameIndicator>
          </ImageFrameFloater>
        </ImageFrame>
        <Text color="palette.gray700" textStyle="t1Regular">
          ImageFrameIndicator
        </Text>
      </VStack>

      <VStack gap="x2" alignItems="center">
        <ImageFrame
          ratio={1}
          rounded
          stroke
          src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
          alt="Landscape with reaction button overlay"
          style={{ width: 120 }}
        >
          <ImageFrameFloater placement="bottom-end">
            <ImageFrameReactionButton
              pressed={liked}
              onPressedChange={setLiked}
              aria-label="좋아요"
            />
          </ImageFrameFloater>
        </ImageFrame>
        <Text color="palette.gray700" textStyle="t1Regular">
          ImageFrameReactionButton
        </Text>
      </VStack>
    </Flex>
  );
}

Multiple Overlays

여러 위치에 오버레이를 동시에 배치할 수 있습니다.

import {
  ImageFrame,
  ImageFrameFloater,
  ImageFrameBadge,
  ImageFrameReactionButton,
} from "@seed-design/react";
import { useState } from "react";

export default function ImageFrameOverlayMultipleExample() {
  const [liked, setLiked] = useState(false);

  return (
    <ImageFrame
      ratio={1}
      rounded
      stroke
      src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
      alt="Landscape with multiple overlays"
      style={{ width: 200 }}
    >
      <ImageFrameFloater placement="top-start">
        <ImageFrameBadge tone="brand" variant="solid">
          NEW
        </ImageFrameBadge>
      </ImageFrameFloater>
      <ImageFrameFloater placement="bottom-end">
        <ImageFrameReactionButton pressed={liked} onPressedChange={setLiked} aria-label="좋아요" />
      </ImageFrameFloater>
    </ImageFrame>
  );
}

Custom Overlay

ImageFrameFloater는 모든 React 요소를 children으로 받을 수 있습니다. 미리 정의된 오버레이 컴포넌트 외에도 커스텀 UI를 배치할 수 있습니다.

import { ImageFrame, ImageFrameFloater } from "@seed-design/react";

export default function ImageFrameOverlayCustomExample() {
  return (
    <ImageFrame
      ratio={1}
      rounded
      stroke
      src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
      alt="Landscape with custom overlay"
      style={{ width: 200 }}
    >
      <ImageFrameFloater placement="bottom-end">
        <div
          style={{
            padding: "4px 8px",
            backgroundColor: "rgba(0, 0, 0, 0.6)",
            borderRadius: 4,
            color: "white",
            fontSize: 12,
          }}
        >
          Custom Element
        </div>
      </ImageFrameFloater>
    </ImageFrame>
  );
}

Offset

offsetX, offsetY prop으로 오버레이의 여백을 조절할 수 있습니다. 기본값은 6px입니다.

import { ImageFrame, ImageFrameFloater, ImageFrameIndicator } from "@seed-design/react";

export default function ImageFrameOverlayInsetExample() {
  return (
    <div style={{ display: "flex", gap: 12 }}>
      <ImageFrame
        ratio={1}
        rounded
        stroke
        src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
        alt="Landscape with default offset"
        style={{ width: 150 }}
      >
        <ImageFrameFloater placement="bottom-end">
          <ImageFrameIndicator>default</ImageFrameIndicator>
        </ImageFrameFloater>
      </ImageFrame>

      <ImageFrame
        ratio={1}
        rounded
        stroke
        src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
        alt="Landscape with 0 offset"
        style={{ width: 150 }}
      >
        <ImageFrameFloater placement="bottom-end" offsetX={0} offsetY={0}>
          <ImageFrameIndicator>offset=0</ImageFrameIndicator>
        </ImageFrameFloater>
      </ImageFrame>

      <ImageFrame
        ratio={1}
        rounded
        stroke
        src="https://images.unsplash.com/photo-1535025183041-0991a977e25b?w=300&dpr=2&q=80"
        alt="Landscape with 12 offset"
        style={{ width: 150 }}
      >
        <ImageFrameFloater placement="bottom-end" offsetX="12px" offsetY="12px">
          <ImageFrameIndicator>offset=12</ImageFrameIndicator>
        </ImageFrameFloater>
      </ImageFrame>
    </div>
  );
}

Last updated on