Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] feat: Skeleton UI 추가 #684

Merged
merged 8 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions frontend/src/components/Common/MoreButton/MoreButton.stories.tsx

This file was deleted.

46 changes: 0 additions & 46 deletions frontend/src/components/Common/MoreButton/MoreButton.tsx

This file was deleted.

18 changes: 18 additions & 0 deletions frontend/src/components/Common/Skeleton/Skeleton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { Meta, StoryObj } from '@storybook/react';

import Skeleton from './Skeleton';

const meta: Meta<typeof Skeleton> = {
title: 'common/Skeleton',
component: Skeleton,
};

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
width: 100,
height: 100,
},
};
36 changes: 36 additions & 0 deletions frontend/src/components/Common/Skeleton/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { ComponentPropsWithoutRef } from 'react';
import styled from 'styled-components';

interface SkeletonProps extends ComponentPropsWithoutRef<'div'> {
width?: string | number;
height?: string | number;
}

const Skeleton = ({ width, height }: SkeletonProps) => {
return <SkeletonContainer width={width} height={height} />;
};

export default Skeleton;

export const SkeletonContainer = styled.div<SkeletonProps>`
position: absolute;
width: ${({ width }) => (typeof width === 'number' ? width + 'px' : width)};
height: ${({ height }) => (typeof height === 'number' ? height + 'px' : height)};
border-radius: 8px;
background: linear-gradient(-90deg, #dddddd, #f7f7f7, #dddddd, #f7f7f7);
background-size: 400%;
overflow: hidden;
animation: skeleton-gradient 5s infinite ease-out;

@keyframes skeleton-gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
`;
2 changes: 1 addition & 1 deletion frontend/src/components/Common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export { default as ErrorBoundary } from './ErrorBoundary/ErrorBoundary';
export { default as ErrorComponent } from './ErrorComponent/ErrorComponent';
export { default as Loading } from './Loading/Loading';
export { default as MarkedText } from './MarkedText/MarkedText';
export { default as MoreButton } from './MoreButton/MoreButton';
export { default as NavigableSectionTitle } from './NavigableSectionTitle/NavigableSectionTitle';
export { default as Carousel } from './Carousel/Carousel';
export { default as RegisterButton } from './RegisterButton/RegisterButton';
export { default as CategoryItem } from './CategoryItem/CategoryItem';
export { default as CategoryList } from './CategoryList/CategoryList';
export { default as Skeleton } from './Skeleton/Skeleton';
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,5 @@ const MembersImage = styled.img`
margin-right: 16px;
border: 2px solid ${({ theme }) => theme.colors.primary};
border-radius: 50%;
object-fit: cover;
`;

This file was deleted.

78 changes: 0 additions & 78 deletions frontend/src/components/Product/PBProductItem/PBProductItem.tsx

This file was deleted.

This file was deleted.

47 changes: 0 additions & 47 deletions frontend/src/components/Product/PBProductList/PBProductList.tsx

This file was deleted.

15 changes: 13 additions & 2 deletions frontend/src/components/Product/ProductItem/ProductItem.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Text, useTheme } from '@fun-eat/design-system';
import { useState } from 'react';
import styled from 'styled-components';

import PreviewImage from '@/assets/characters.svg';
import { SvgIcon } from '@/components/Common';
import { Skeleton, SvgIcon } from '@/components/Common';
import type { Product } from '@/types/product';

interface ProductItemProps {
Expand All @@ -12,11 +13,21 @@ interface ProductItemProps {
const ProductItem = ({ product }: ProductItemProps) => {
const theme = useTheme();
const { name, price, image, averageRating, reviewCount } = product;
const [isImageLoading, setIsImageLoading] = useState(true);

return (
<ProductItemContainer>
{image !== null ? (
<ProductImage src={image} width={90} height={90} alt={`${name}사진`} />
<>
<ProductImage
src={image}
width={90}
height={90}
alt={`${name}사진`}
onLoad={() => setIsImageLoading(false)}
/>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리스트에 쓰이는 이미지에 loading='lazy' 넣어주세요.! 배너는 지연 로딩 없어도 될듯 맨위에 있어서

{isImageLoading && <Skeleton width={90} height={90} />}
</>
) : (
<PreviewImage width={90} height={90} />
)}
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/Product/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ export { default as ProductDetailItem } from './ProductDetailItem/ProductDetailI
export { default as ProductItem } from './ProductItem/ProductItem';
export { default as ProductList } from './ProductList/ProductList';
export { default as ProductOverviewItem } from './ProductOverviewItem/ProductOverviewItem';
export { default as PBProductList } from './PBProductList/PBProductList';
export { default as ProductRecipeList } from './ProductRecipeList/ProductRecipeList';
export { default as ProductTitle } from './ProductTitle/ProductTitle';
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Spacing, Text, useTheme } from '@fun-eat/design-system';
import { useState } from 'react';
import styled from 'styled-components';

import RecipePreviewImage from '@/assets/plate.svg';
import { SvgIcon } from '@/components/Common';
import { Skeleton, SvgIcon } from '@/components/Common';
import type { RecipeRanking } from '@/types/ranking';

interface RecipeRankingItemProps {
Expand All @@ -18,6 +19,7 @@ const RecipeRankingItem = ({ rank, recipe }: RecipeRankingItemProps) => {
author: { nickname, profileImage },
favoriteCount,
} = recipe;
const [isImageLoading, setIsImageLoading] = useState(true);

return (
<RecipeRankingItemContainer>
Expand All @@ -26,7 +28,16 @@ const RecipeRankingItem = ({ rank, recipe }: RecipeRankingItemProps) => {
<RankingRecipeWrapper>
<Spacing direction="horizontal" size={12} />
{image !== null ? (
<RecipeImage src={image} alt={`${rank}위 꿀조합`} width={60} height={60} />
<>
<RecipeImage
src={image}
alt={`${rank}위 꿀조합`}
width={60}
height={60}
onLoad={() => setIsImageLoading(false)}
/>
{isImageLoading && <Skeleton width={60} height={60} />}
</>
) : (
<RecipePreviewImage width={60} height={60} />
)}
Expand Down Expand Up @@ -74,6 +85,7 @@ const RankingRecipeWrapper = styled.div`

const RecipeImage = styled.img`
border-radius: 5px;
object-fit: cover;
`;

const TitleFavoriteWrapper = styled.div`
Expand All @@ -100,4 +112,5 @@ const AuthorWrapper = styled.div`
const AuthorImage = styled.img`
border: 2px solid ${({ theme }) => theme.colors.primary};
border-radius: 50%;
object-fit: cover;
`;
Loading