Skip to content

Commit

Permalink
refactor: UI/UX 개선 (#488)
Browse files Browse the repository at this point in the history
* refactor: AlignSelect를 native select로 변경

- 실제 쿼리스트링과 select option을 동기화
- 아이콘 제거

* refactor: ALIGN_QUERY < REVIEW_ALIGN_QUERY 네이밍 변경

* feat: REVIEW_FILTER_QUERY_STRINGS 상수 추가

* refactor: 불필요한 콜백 제거

* refactor: 리뷰 메타데이터 타입을 상수를 활용하도록 변경

* feat: 리뷰 필터 상태와 쿼리스트링 동기화

* feat: 필터 아이콘 위치 우측으로 변경

* feat: 상수 적용 및 불필요한 useEffect 제거

* refactor: 견종 select 기본 화살표 제거

* feat: ReactQueryDevtools 추가

* refactor: StyledProps $props 형식을 카멜 케이스 네이밍에만 적용

* refactor: theme animation > keyframes로 변경 및 별도의 animation 속성 추가

* refactor: COMMENT_VISIBLE_LINE_LIMIT 오타 수정

* feat: ReviewItem Skeleton 추가

* refactor: 기존 ReviewList > ReviewListAndChart로 변경 및 ReviewList 컴포넌트 분리

* refactor: query key 템플릿 리터럴 제거

* refactor: 변경된 ReviewListAndChart 네이밍 적용

* refactor: query key에 queryString 추가

* refactor: refetch > query key에 queryString을 추가하는 방식으로 변경

* feat: SuspendedImg 추가

* refactor: StarRatingDisplay 별점 이미지 SuspenedImg로 변경

* feat: ReviewControls Skeleton 추가

* refactor: SuspensedImg src를 옵셔널로 변경

* refactor: ReviewItem img > SuspendedImg로 변경

* refactor: 누락됐던 FilterSelectionDisplay 재적용

* feat: SuspenedImg lazy loading 기능 추가

* feat: FoodList Skeleton 추가

* feat: foodList fixture imageUrl 추가

* feat: FoodItem Skeleton 추가 및 LazyImg > SuspendedImg로 변경

* feat: FoodList Skeleton 적용

* feat: FilterBottomSheet 최대 높이 지정

* feat: iPhone8 이하 사이즈 대응

* refactor: ReviewControls 레이아웃 수정

* chore: stylelint rule 추가

* refactor: 사료 필터 목록 레이아웃 최소 높이 설정

* refactor: GuideBanner 작은 디바이스에서 폰트 사이즈 작게 변경

* refactor: 영양기준 국기 이모지 > svg로 변경

* refactor: ReviewList 리뷰 결과 없음 컴포넌트 디자인을 식품 결과 없음과 통일

* fix: NutritionStandardBlock story State를 직접 명명

* refactor: NonEmptyArray type export로 변경

* refactor: styledprops $재적용
  • Loading branch information
n0eyes authored Oct 16, 2023
1 parent 9cbc55c commit ac4726e
Show file tree
Hide file tree
Showing 49 changed files with 776 additions and 422 deletions.
91 changes: 87 additions & 4 deletions frontend/.pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions frontend/.stylelintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,7 @@ module.exports = {
severity: 'error',
},
],

'property-no-vendor-prefix': null,
},
};
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
},
"dependencies": {
"@tanstack/react-query": "^4.29.19",
"@tanstack/react-query-devtools": "^4.36.1",
"axios": "^1.4.0",
"browser-image-compression": "^2.0.2",
"react": "^18.2.0",
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { useEffect } from 'react';
import { Outlet } from 'react-router-dom';
import { ThemeProvider } from 'styled-components';
Expand Down Expand Up @@ -41,6 +42,7 @@ const App = () => (
<ToastProvider>
<GlobalEvent />
<Outlet />
{isDevelopment && <ReactQueryDevtools initialIsOpen={false} />}
</ToastProvider>
</QueryBoundary>
</CriticalBoundary>
Expand Down
18 changes: 8 additions & 10 deletions frontend/src/components/@common/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const Button = (buttonProps: ButtonProps) => {
$kind={kind}
$fixed={fixed}
style={style}
$disabled={disabled}
disabled={disabled}
{...restProps}
>
Expand Down Expand Up @@ -64,7 +63,7 @@ const ButtonOuter = styled.div<ButtonStyleProps>`
`;

const ButtonWrapper = styled.button<ButtonStyleProps>`
cursor: ${({ $disabled }) => ($disabled ? 'not-allowed' : 'pointer')};
cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')};
display: flex;
gap: 0.4rem;
Expand All @@ -80,8 +79,8 @@ const ButtonWrapper = styled.button<ButtonStyleProps>`
color: ${({ theme }) => theme.color.white};
letter-spacing: 0.02rem;
background-color: ${({ $kind, theme, $disabled }) => {
if ($disabled) {
background-color: ${({ $kind, theme, disabled }) => {
if (disabled) {
return theme.color.grey300;
}
Expand All @@ -96,12 +95,11 @@ const ButtonWrapper = styled.button<ButtonStyleProps>`
transition: all 100ms ease-in-out;
${({ $disabled }) =>
!$disabled &&
` &:active {
scale: 0.98;
}
`}
&:not(:disabled) {
&:active {
scale: 0.98;
}
}
${({ $fixed }) =>
$fixed &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ const NavItem = styled.button<PropsWithFixedWith>`

const NavItemTitle = styled.h3<PropsWithClicked>`
font-size: 1.8rem;
font-weight: ${({ theme, $clicked }) => ($clicked ? 500 : 400)};
font-weight: ${({ $clicked }) => ($clicked ? 500 : 400)};
line-height: 1.8rem;
color: ${({ theme, $clicked }) => ($clicked ? theme.color.grey700 : theme.color.grey400)};
letter-spacing: -0.05rem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { css, styled } from 'styled-components';
import EmptyStarIcon from '@/assets/svg/empty_star_icon.svg';
import FilledStarIcon from '@/assets/svg/filled_star_icon.svg';

import SuspendedImg from '../../SuspendedImg/SuspendedImg';

interface StarRatingDisplayProps {
rating: number;
size?: 'small' | 'medium' | 'large';
Expand Down Expand Up @@ -37,7 +39,7 @@ const StarContainer = styled.div`
align-items: center;
`;

const Star = styled.img<{ size: 'small' | 'medium' | 'large' }>`
const Star = styled(SuspendedImg)<{ size: 'small' | 'medium' | 'large' }>`
${({ size }) => {
if (size === 'small') {
return css`
Expand Down
55 changes: 55 additions & 0 deletions frontend/src/components/@common/SuspendedImg/SuspendedImg.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { useQuery } from '@tanstack/react-query';
import { ComponentPropsWithoutRef, ComponentPropsWithRef, useEffect } from 'react';

import { useIntersectionObserver } from '@/hooks/@common/useIntersectionObserver';

interface SuspendedImgProps extends ComponentPropsWithoutRef<'img'> {
staleTime?: number;
cacheTime?: number;
enabled?: boolean;
lazy?: boolean;
}

// eslint-disable-next-line react/display-name
const SuspendedImg = (props: SuspendedImgProps) => {
const { src, cacheTime, staleTime, enabled, lazy, ...restProps } = props;

const img = new Image();

const { targetRef, isIntersected } = useIntersectionObserver<HTMLImageElement>({
observerOptions: { threshold: 0.1 },
});

const lazyOptions: ComponentPropsWithRef<'img'> & { 'data-src'?: string } = {
loading: 'lazy',
ref: targetRef,
'data-src': src,
};

useQuery({
queryKey: [src],
queryFn: () =>
new Promise(resolve => {
img.onload = resolve;
img.onerror = resolve;

img.src = src!;
}),
...(staleTime == null ? {} : { staleTime }),
...(cacheTime == null ? {} : { cacheTime }),
enabled: enabled && Boolean(src),
});

useEffect(() => {
if (!targetRef.current) return;

if ('loading' in HTMLImageElement.prototype || isIntersected) {
targetRef.current.src = String(targetRef.current.dataset.src);
}
}, [isIntersected]);

// eslint-disable-next-line jsx-a11y/alt-text
return <img {...restProps} {...(lazy ? lazyOptions : { src })} />;
};

export default SuspendedImg;
25 changes: 14 additions & 11 deletions frontend/src/components/@common/Template.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { createElement, isValidElement, PropsWithChildren, ReactNode } from 'react';
import styled, { css, isStyledComponent } from 'styled-components';

import { StyledProps } from '@/types/common/utility';
import { getComputedStyleOfSC } from '@/utils/styled-components';

import Footer from './Footer/Footer';
Expand Down Expand Up @@ -35,7 +36,7 @@ const Template = <T extends React.FC>(
return (
<Layout>
{createElement(fixedHeader ?? staticHeader!)}
<Container isFixedHeader={Boolean(fixedHeader)} headerHeight={headerHeight}>
<Container $isFixedHeader={Boolean(fixedHeader)} $headerHeight={headerHeight}>
{children}
</Container>
{footer && <Footer />}
Expand Down Expand Up @@ -70,26 +71,28 @@ const Layout = styled.div`
`;

const Container = styled.div<
| {
isFixedHeader: boolean;
headerHeight?: string;
}
| { isFixedHeader?: never; headerHeight?: never }
StyledProps<
| {
isFixedHeader: boolean;
headerHeight?: string;
}
| { isFixedHeader?: never; headerHeight?: never }
>
>`
width: 100%;
height: 100%;
min-height: calc((var(--vh, 1vh) * 100));
${({ isFixedHeader, headerHeight }) => {
if (isFixedHeader === true) {
${({ $isFixedHeader, $headerHeight }) => {
if ($isFixedHeader === true) {
return css`
padding-top: ${headerHeight};
padding-top: ${$headerHeight};
`;
}
if (isFixedHeader === false) {
if ($isFixedHeader === false) {
return css`
min-height: calc((var(--vh, 1vh) * 100) - ${headerHeight});
min-height: calc((var(--vh, 1vh) * 100) - ${$headerHeight});
`;
}
}}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/@common/Toast/Toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const ToastWrapper = styled.div<ToastStyleProps & { $isShow: boolean }>`
}};
border-radius: 20px;
box-shadow: 0 2px 8px 0
${({ theme, $type }) => {
${({ $type }) => {
if ($type === 'success') {
return 'rgb(62 94 142 / 50%);';
}
Expand Down
Loading

0 comments on commit ac4726e

Please sign in to comment.