Skip to content

Commit

Permalink
Feat(design-system): �홈 배너 상단 캐러셀 구현 (#80)
Browse files Browse the repository at this point in the history
* feat: TopCarousel 컴포넌트 구현

* feat: 캐러셀 구현

* feat: 홈배너 상단 캐러셀 구현

* feat: story 작성

* design: 스타일 추가

* feat: 탭 변경 시 패널 연결

* refactor: 필요없는 코드 삭제

* design: style 수정

* fix: 애니메이션 오류 해결

* fix: 타입 오류 제거

* feat: css 파일 vanila-extract로 변환

* chore: 목데이터 이미지 수정

* refactor: 코드리뷰 반영

* design: 스타일 theme 으로 변경

* refactor: 코드리뷰 반영
  • Loading branch information
seueooo authored Jan 16, 2025
1 parent 0f7a6b4 commit 925f9b3
Show file tree
Hide file tree
Showing 13 changed files with 582 additions and 11 deletions.
7 changes: 7 additions & 0 deletions apps/client/src/pages/home/page/home.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { style } from '@vanilla-extract/css';
import { themeVars } from '@confeti/design-system/styles';

export const mainStyle = style({
paddingTop: '3rem',
background: themeVars.color.confeti_purple_grad,
});
12 changes: 10 additions & 2 deletions apps/client/src/pages/home/page/home.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { Footer, Navigation } from '@confeti/design-system';
import { Footer, TopCarousel, Navigation } from '@confeti/design-system';
import { PERFORMANCE_DATA } from '@shared/mocks/top-carousel-mock';
import * as styles from './home.css';

import { TAB_MENU } from '../constants/menu';

const Home = () => {
Expand All @@ -11,10 +14,15 @@ const Home = () => {
</Navigation.List>
<Navigation.Panels>
{/* TODO: 추후 페이지 연결 */}
<Navigation.Panel>홈페이지</Navigation.Panel>
<Navigation.Panel>
<div className={styles.mainStyle}>
<TopCarousel performData={PERFORMANCE_DATA}></TopCarousel>
</div>
</Navigation.Panel>
<Navigation.Panel>타임테이블</Navigation.Panel>
</Navigation.Panels>
</Navigation.Root>

<Footer />
</>
);
Expand Down
65 changes: 65 additions & 0 deletions apps/client/src/shared/mocks/top-carousel-mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
export const PERFORMANCE_DATA = [
{
performanceId: 1,
type: 'concert',
title: '오아시스 내한공연1',
subTitle: 'LIVE NATION PRESENTS COLDPLAY',
performanceAt: '2025.10.21',
posterUrl:
'https://s3-alpha-sig.figma.com/img/961e/48da/36bf2a709612a4562cfb56af542eb961?Expires=1737936000&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=gTKYxz-Jsf68n0V2ZbrooxAwXN4r8tDUw1xLkmhhk1OnG2-nrLIxsnTOQiDaZOS1cC5ZvPZ3MyoVIbCYSa5qnnKIkyJ68oemZ-UD8Nmj2wCs7PsbbCF7yhGTUhhGnivzVFpYkpBrM91J0ZEhaFP4N4pdBoA~-ad15QfDaBJEcYKlD49bOUcYSN6Eu3kb3OzDPaAZjrBOBRTPM7iDIDMrQD5qIbSJgew9OPXnrHB0ZS4yD1QXrI5-2Zrvx9RpTEPxHstR88q8yw5VgXsKReKdSpV1CKVhh3oQ~uWmn0gSN1IQW097zpPR6b0E8fQHB1HLig1EhriCZhQmUYBjDOcBgg__',
},
{
performanceId: 2,
type: 'festival',
title: '오아시스 내한공연2',
subTitle: '',
performanceAt: '2025.10.21',
posterUrl:
'https://s3-alpha-sig.figma.com/img/f03d/9a2c/4854283ea449b35300d949bc3d7e3bcb?Expires=1737936000&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=bJBmX7kA6jAfx1I5CLhFl763ycOSD6eL3Gkg~Immdm8cGWDjSmOcW0VU1X23~q-wgDp0uTya6O9oMTy6dpHlkedb8RbZnTHMNlhVXbbNU5-TVwVJSTpIkCj8BkC8ble~jKhESsWt6OZq3f2uA5j4ESb-VaYMuq7iK-LlBTXcgKFfyZC5o7z2Y-7uASgM6-uWitKCsUUUXON4tft1PMI4~asveZyc4k2-ZGCyd0dwpNONefXkwXMwgYjmoOK12uzB7dKoSrGJPcWEDMYsdZHbG8x5rLsBVe87U~eTmfN5s-U5dDu0Sv0~u8s~W4vddQh0CaZSlqSViO5I373KI7pHOQ__',
},
{
performanceId: 3,
type: 'festival',
title: '오아시스 내한공연3',
subTitle: 'LIVE NATION PRESENTS COLDPLAY',
performanceAt: '2025.10.21',
posterUrl:
'https://s3-alpha-sig.figma.com/img/961e/48da/36bf2a709612a4562cfb56af542eb961?Expires=1737936000&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=gTKYxz-Jsf68n0V2ZbrooxAwXN4r8tDUw1xLkmhhk1OnG2-nrLIxsnTOQiDaZOS1cC5ZvPZ3MyoVIbCYSa5qnnKIkyJ68oemZ-UD8Nmj2wCs7PsbbCF7yhGTUhhGnivzVFpYkpBrM91J0ZEhaFP4N4pdBoA~-ad15QfDaBJEcYKlD49bOUcYSN6Eu3kb3OzDPaAZjrBOBRTPM7iDIDMrQD5qIbSJgew9OPXnrHB0ZS4yD1QXrI5-2Zrvx9RpTEPxHstR88q8yw5VgXsKReKdSpV1CKVhh3oQ~uWmn0gSN1IQW097zpPR6b0E8fQHB1HLig1EhriCZhQmUYBjDOcBgg__',
},
{
performanceId: 4,
type: 'festival',
title: '오아시스 내한공연4',
subTitle: '',
performanceAt: '2025.10.21',
posterUrl:
'https://s3-alpha-sig.figma.com/img/46b2/a7e8/7992b9ede09843fff6ebf8b566713967?Expires=1737936000&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=lyWMYVAsud4Do0xSlFj4Ex59sruTIo9ZQhQLPbLtxW9W5wOn0ppLfC81tFHXWgiyXKK4OiHc79CouyY0jFdN1AIrsGM3eKdJDjEh8yU0zQxH5Pyp5aOqX4uaiWqMP17Cyj7xaLrKJgDWPAwJAOsonzns~ihB67MrZKxdEqKo0F5nM-nYJwgYLQSlL5kmQwAm3ig2QUvSRNHhDWw2XPMD6Ng9JktfeWv4npBoRRG8WpboXSt2O72cVoNZbxPFuh1fBY5jRC4oNbucMiHRKCWRst-bRrDNKI-gS8segXXyGAXOyPTIls0SZ~bjOzFfSDmVzvmOvQ-Q4~xh502bV1tziQ__',
},
{
performanceId: 5,
type: 'festival',
title: '오아시스 내한공연5',
subTitle: 'LIVE NATION PRESENTS COLDPLAY',
performanceAt: '2025.10.21',
posterUrl:
'https://s3-alpha-sig.figma.com/img/abe0/2e69/dd0f1adcebbc0d20cddfb46a0c10804a?Expires=1737936000&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=frNVG9N10Y91eyJMOmBpHIfdL8MLvmJQYxcwGaeT0so8tFo57AyRO7N9Km5xUQ5Oi~afEqV1GVaMdh5cNH5CdU3qBrrMnMR2sEt4czvwPaGv-MraYWdXqvw-zoetcpDGihs9L-lRJ-jicTq~Fqz6UxKlREMGkAZ6kuItMFsuiKH~jQL0CjI7EwO1Bct6-iFJp7iKtO8I8h0tXCA2wScjmpCUAaro1adoMKVcLOeFNtKZo5TzirO5giGTtHCFRilR9uc0wl-P~ZehLklPRr~9BoPwUUs4O~67RlAFv38yoDFP~gdQ6zDuiU81u5Nmfc1ic52vKhzD4kU3TDDJXRXDZQ__',
},
{
performanceId: 6,
type: 'festival',
title: '오아시스 내한공연6',
subTitle: 'LIVE NATION PRESENTS COLDPLAY',
performanceAt: '2025.10.21',
posterUrl:
'https://s3-alpha-sig.figma.com/img/ddaf/3f4b/77a4449254ce1360254377e752a0f278?Expires=1737936000&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=DCAfi~ihZuq2YEIag2pfg8fj~BlBK9lhdf9l7MQe7Fb-kp8Jn0hqDyAD87jpbwQ3fgl-ZTkabk9zyfyZSUtD-eEuza-Or-706rik8uYXbZ8aCKydal66nuBDWVMNqe2xeg9qOf0m7xI5ePr1CHMbTs7zo3d2p-x~tIMfN16i4dz94aVrLgOnHq8LiG77Z7euT-RTQXoejMiTB8DJnME2peonChLdhTUKKApnfAw5HWZ8eHDk06d66LeVeQANuiITXu01Bd52Xd88-JjpQ~7TNjICViq8k96JQ3MJBo3wo~7msgf1e7WvXT59yaL~TNpu~1XeRtyO5IqoGiV-Uq3BSw__',
},
{
performanceId: 7,
type: 'festival',
title: '오아시스 내한공연7',
subTitle: '',
performanceAt: '2025.10.21',
posterUrl:
'https://s3-alpha-sig.figma.com/img/cd74/1748/2c7fa3513d56a30582a1b24ea7ceb408?Expires=1737936000&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=X0l2RAVxVnOjB6RIM81l-5cVWBY8w4Dm~uMXKQIybjN3I9q5i8rVEgI698FBwi0PG8~LTtqiON6wF6-LldHtV~syc~dOzMHTYWp~tN4s1qyoiHARHiR78SxWYHA3~h1ZSQloVvCUx0Kq4mCQ9yBBANwE1y5SLnx8P9IQpAIE48iyrk35sKVlF80rlfDaFAXTJXv940YoT7GOFqnYdkd5ep1bDQpj2wNmTNnl54jlV8k450yvvn~f5f9hV7YN62AgRAJ6YI-62UpSGBKIXoNXHRja2nl0RZngtgoXMccv33kvZ3KPE8iH~boEeolwVt6FL-lKlFqG8G5O4mZS994yZQ__',
},
];
5 changes: 4 additions & 1 deletion packages/design-system/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,15 @@
"vite": "^5.4.8"
},
"dependencies": {
"@types/react-slick": "^0.23.13",
"@vanilla-extract/css": "^1.17.0",
"@vanilla-extract/recipes": "^0.5.5",
"@vanilla-extract/sprinkles": "^1.6.3",
"clsx": "^2.1.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^7.1.1"
"react-router-dom": "^7.1.1",
"react-slick": "^0.30.3",
"slick-carousel": "^1.8.1"
}
}
1 change: 1 addition & 0 deletions packages/design-system/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export { default as FloatingButton } from './floating-button/floating-button';
export { default as ToastContainer } from './toast/toast-container';
export { toast } from './toast/utils/toast';
export { default as Header } from './header/header';
export { default as TopCarousel } from './top-carousel/top-carousel';
export { default as ArtistCard } from './artist-card/artist-card';
export { default as FestivalCard } from './festival-card/festival-card';
export { default as Spacing } from './spacing/spacing';
37 changes: 37 additions & 0 deletions packages/design-system/src/components/top-carousel/dots.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { globalStyle } from '@vanilla-extract/css';
import { themeVars } from '../../styles';

globalStyle('.dots_custom', {
display: 'flex',
justifyContent: 'center',
verticalAlign: 'middle',
margin: 0,
paddingTop: '0rem',
paddingBottom: '1.6rem',
});

globalStyle('.dots_custom li', {
listStyle: 'none',
cursor: 'pointer',
display: 'inline-block',
marginRight: '0.8rem',
padding: 0,
});

globalStyle('.dots_custom li button', {
border: 'none',
background: themeVars.color.white,
opacity: 0.2,
cursor: 'pointer',
display: 'block',
height: '0.6rem',
width: '0.6rem',
borderRadius: '100%',
padding: 0,
color: 'transparent',
});

globalStyle('.dots_custom li.slick-active button', {
backgroundColor: themeVars.color.confeti_lime3,
opacity: 1,
});
112 changes: 112 additions & 0 deletions packages/design-system/src/components/top-carousel/slick.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { globalStyle } from '@vanilla-extract/css';
import { themeVars } from '../../styles';

/* Slider */
globalStyle('.slick-slider', {
...themeVars.display.flexColumn,
boxSizing: 'border-box',

WebkitUserSelect: 'none',
MozUserSelect: 'none',
msUserSelect: 'none',
userSelect: 'none',

WebkitTouchCallout: 'none',
msTouchAction: 'pan-y',
touchAction: 'pan-y',
WebkitTapHighlightColor: 'transparent',
});

globalStyle('.slick-list', {
gap: '2rem',
overflow: 'hidden',
margin: '0',
});

globalStyle('.slick-list:focus', {
outline: 'none',
});

globalStyle('.slick-list.dragging', {
cursor: 'pointer',
});

globalStyle('.slick-slider .slick-track, .slick-slider .slick-list', {
WebkitTransform: 'translate3d(0, 0, 0)',
MozTransform: 'translate3d(0, 0, 0)',
msTransform: 'translate3d(0, 0, 0)',
OTransform: 'translate3d(0, 0, 0)',
transform: 'translate3d(0, 0, 0)',
});

globalStyle('.slick-track', {
margin: 'auto',
paddingBottom: '2rem',
});

globalStyle('.slick-track:before, .slick-track:after', {
display: 'table',
content: "''",
});

globalStyle('.slick-track:after', {
clear: 'both',
});

globalStyle('.slick-loading .slick-track', {
visibility: 'hidden',
});

globalStyle('.slick-slide', {
display: 'none',
float: 'left',
height: '100%',
minHeight: '1px',
});

globalStyle("[dir='rtl'] .slick-slide", {
float: 'right',
});

globalStyle('.slick-slide img', {
display: 'block',
});

globalStyle('.slick-slide.slick-loading img', {
display: 'none',
});

globalStyle('.slick-slide.dragging img', {
pointerEvents: 'none',
});

globalStyle('.slick-initialized .slick-slide', {
display: 'block',
});

globalStyle('.slick-loading .slick-slide', {
visibility: 'hidden',
});

globalStyle('.slick-vertical .slick-slide', {
display: 'block',
height: 'auto',
border: '1px solid transparent',
});

globalStyle('.slick-arrow.slick-hidden', {
display: 'none',
});

/* 기본 슬라이드 스타일 */
globalStyle('.slick-slide', {
transition: 'transform 0.5s ease, opacity 0.5s ease',
opacity: 0.7,
transform: 'scale(0.8)',
});

/* 중앙 슬라이드 스타일 */
globalStyle('.slick-center', {
opacity: 1,
transform: 'scale(1)',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { globalStyle, keyframes } from '@vanilla-extract/css';
import { themeVars } from '../../styles';

export const fadeInOut = keyframes({
'0%': { opacity: 0 },
'50%': { opacity: 0.5 },
'100%': { opacity: 1 },
});

globalStyle('.banner-title', {
marginTop: '3rem',
height: '10.3rem',
});

globalStyle('.title-date', {
...themeVars.fontStyles.subtitle5_sb_12,
color: themeVars.color.white,
textAlign: 'center',
marginBottom: '1.2rem',
animation: `${fadeInOut} 1s ease-out forwards`,
});

globalStyle('.title-name', {
...themeVars.fontStyles.title1_b_24,
color: themeVars.color.white,
textAlign: 'center',
marginBottom: '4px',
animation: `${fadeInOut} 1s ease-out forwards`,
});

globalStyle('.title-sub', {
...themeVars.fontStyles.body3_m_14,
color: themeVars.color.gray500,
textAlign: 'center',
animation: `${fadeInOut} 1s ease-out forwards`,
});

globalStyle('.card', {
zIndex: 1,
width: '19.7rem',
height: '26.2rem',
borderRadius: '1rem',
boxShadow: '0px 3px 6px 1px rgba(0, 0, 0, 0.25)',
});
Loading

0 comments on commit 925f9b3

Please sign in to comment.