Skip to content

Commit

Permalink
feat: 이미지 컴포넌트 (#71)
Browse files Browse the repository at this point in the history
* feat: 이미지 컴포넌트

- 대표 색깔 기반의 스켈레톤
- 실패 시 슬픈 피우미 이미지

* refactor: 타입 import 분리

타입 import의 경우 명시적으로 분리

Co-authored-by: 유강현 <[email protected]>

---------

Co-authored-by: 유강현 <[email protected]>
  • Loading branch information
WaiNaat and bassyu authored Jul 18, 2023
1 parent 904245a commit 2fa5834
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 0 deletions.
Binary file added frontend/src/assets/sadpiumi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions frontend/src/components/Image/Image.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { Meta, StoryObj } from '@storybook/react';
import Image from '.';

const meta: Meta<typeof Image> = {
component: Image,

args: {
type: 'circle',
size: '77px',
},
};

export default meta;

type Story = StoryObj<typeof Image>;

export const Default: Story = {
args: {
src: 'https://images.unsplash.com/photo-1555841769-75541ae4fc9f',
alt: '참새',
loading: 'lazy',
},
};

export const Skeleton: Story = {
args: {
src: '',
alt: '무조건 실패하는 이미지',
},
};
35 changes: 35 additions & 0 deletions frontend/src/components/Image/Image.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { keyframes, styled } from 'styled-components';

export interface StyledImageProps {
type: 'circle' | 'square';
size: string;
}

const wave = (size: string) => keyframes`
0% {
background-position: -${size} 0;
}
100% {
background-position: ${size} 0;
}
`;

export const StyledImage = styled.img<StyledImageProps>`
display: inline-flex;
width: ${({ size }) => size};
height: ${({ size }) => size};
object-fit: cover;
background: linear-gradient(
to right,
${({ theme }) => theme.color.primary}33 7%,
${({ theme }) => theme.color.primary}4C 17%,
${({ theme }) => theme.color.primary}33 37%
);
background-size: 77px 77px;
border-radius: ${({ type }) => (type === 'circle' ? '50%' : 0)};
animation: ${({ size }) => wave(size)} 2.5s linear infinite;
`;
18 changes: 18 additions & 0 deletions frontend/src/components/Image/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { StyledImageProps } from './Image.style';
import { StyledImage } from './Image.style';
import sadpiumi from 'assets/sadpiumi.png';

type ImageProps = Omit<React.ImgHTMLAttributes<HTMLImageElement>, 'onError'> &
Partial<StyledImageProps>;

const Image = (props: ImageProps) => {
const { type = 'circle', size = '77px', ...imageProps } = props;

const setErrorImage: React.ReactEventHandler<HTMLImageElement> = ({ currentTarget }) => {
currentTarget.src = sadpiumi;
};

return <StyledImage type={type} size={size} onError={setErrorImage} {...imageProps} />;
};

export default Image;

0 comments on commit 2fa5834

Please sign in to comment.