-
Notifications
You must be signed in to change notification settings - Fork 2
[refactor] 퍼널 공통 헤더 v2 전환 및 InteriorStyle 디자인 리뉴얼 #511
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
base: develop
Are you sure you want to change the base?
Changes from all commits
0bed44d
27ba0f4
777985a
95e9cbe
12b7325
40f5505
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,27 +1,32 @@ | ||
| import { style } from '@vanilla-extract/css'; | ||
|
|
||
| import { zIndex } from '@styles/tokens/zIndex'; | ||
| import { unitVars } from '@styles/tokensV2/unit.css'; | ||
|
|
||
| export const container = style({ | ||
| position: 'relative', | ||
| display: 'flex', | ||
| flex: 1, | ||
| flexDirection: 'column', | ||
| alignItems: 'center', | ||
| gap: unitVars.unit.gapPadding['800'], | ||
| marginBottom: '9.6rem', | ||
| padding: unitVars.unit.gapPadding['500'], | ||
| width: '100%', | ||
| }); | ||
|
|
||
| export const headingWrapper = style({ | ||
| display: 'flex', | ||
| width: '100%', | ||
| }); | ||
|
|
||
| // 데스크탑·모바일 모두에서 44rem 가상 프레임의 우하단에 2rem씩 띄운 floating 버튼 | ||
| // - 모바일(뷰포트 ≤ 44rem): right: 2rem — 뷰포트 우측에서 2rem | ||
| // - 데스크탑(뷰포트 > 44rem): right: calc((100vw - 44rem) / 2 + 2rem) — 프레임 우측에서 2rem 안쪽 | ||
| // - max()로 두 경우를 한 식에 통합 | ||
| export const buttonWrapper = style({ | ||
| position: 'fixed', | ||
| zIndex: zIndex.button, | ||
| right: 0, | ||
| bottom: '2rem', // CtaButton 최대 너비 설정 | ||
| left: 0, | ||
| display: 'flex', | ||
| justifyContent: 'center', | ||
| margin: '0 auto', | ||
| padding: '0 2rem 0 2rem', | ||
| width: '100%', | ||
| maxWidth: '44rem', | ||
| right: 'max(2rem, calc((100vw - 44rem) / 2 + 2rem))', | ||
| bottom: '2rem', | ||
|
jstar000 marked this conversation as resolved.
|
||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| import { style } from '@vanilla-extract/css'; | ||
| import { recipe } from '@vanilla-extract/recipes'; | ||
|
|
||
| import { colorVars } from '@styles/tokensV2/color.css'; | ||
| import { fontVars } from '@styles/tokensV2/font.css'; | ||
| import { unitVars } from '@styles/tokensV2/unit.css'; | ||
|
|
||
| // 카드 컨테이너 | ||
| // - default: 1px secondary 테두리, 둥근 사각형 | ||
| // - selected: 1.5px strong 테두리 | ||
| // - disabled: opacity 0.5 | ||
| export const card = recipe({ | ||
| base: { | ||
| aspectRatio: '164 / 240', | ||
| position: 'relative', | ||
| transition: 'transform 120ms ease', | ||
| border: `1px solid ${colorVars.color.border.secondary}`, | ||
| borderRadius: unitVars.unit.radius['600'], | ||
| backgroundColor: 'transparent', | ||
| cursor: 'pointer', | ||
| padding: 0, | ||
| width: '100%', | ||
| overflow: 'hidden', | ||
| font: 'inherit', | ||
| selectors: { | ||
| '&:active': { | ||
| transform: 'scale(0.95)', | ||
| }, | ||
| }, | ||
| }, | ||
| variants: { | ||
| state: { | ||
| default: {}, | ||
| selected: { | ||
| border: `1.5px solid ${colorVars.color.border.strong}`, | ||
| }, | ||
| disabled: { | ||
| opacity: 0.5, | ||
| cursor: 'not-allowed', | ||
| selectors: { | ||
| '&:active': { | ||
| transform: 'none', | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| defaultVariants: { | ||
| state: 'default', | ||
| }, | ||
| }); | ||
|
|
||
| export const image = style({ | ||
| display: 'block', | ||
| objectFit: 'cover', | ||
| objectPosition: 'center', | ||
| width: '100%', | ||
| height: '100%', | ||
| userSelect: 'none', | ||
| }); | ||
|
|
||
| // 체크박스 — 우상단에 패딩 16px 영역 안에 위치 | ||
| export const checkbox = recipe({ | ||
| base: { | ||
| position: 'absolute', | ||
| top: 0, | ||
| right: 0, | ||
| display: 'flex', | ||
| alignItems: 'center', | ||
| justifyContent: 'center', | ||
| border: 'none', | ||
| background: 'transparent', | ||
| pointerEvents: 'none', | ||
| padding: unitVars.unit.gapPadding['400'], | ||
| }, | ||
| variants: { | ||
| state: { | ||
| // default: 흰 stroke 빈 동그라미 20×20 | ||
| default: {}, | ||
| // selected: 다크 배경 24×24, 흰 숫자 | ||
| selected: {}, | ||
| }, | ||
| }, | ||
| }); | ||
|
Comment on lines
+76
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial 주석과 실제 구현 불일치 + 빈 variants 정리 필요 Line 78의 주석에 "20×20"이라고 되어 있지만, 또한 💡 제안된 수정 export const checkbox = recipe({
base: {
position: 'absolute',
top: 0,
right: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
border: 'none',
background: 'transparent',
pointerEvents: 'none',
padding: unitVars.unit.gapPadding['400'],
},
variants: {
state: {
- // default: 흰 stroke 빈 동그라미 20×20
+ // 스타일 차이는 circle 레시피에서 처리
default: {},
- // selected: 다크 배경 24×24, 흰 숫자
selected: {},
},
},
});🤖 Prompt for AI Agents |
||
|
|
||
| // 체크박스 안의 동그라미 | ||
| export const circle = recipe({ | ||
| base: { | ||
| display: 'flex', | ||
| alignItems: 'center', | ||
| justifyContent: 'center', | ||
| transition: | ||
| 'width 120ms ease, height 120ms ease, background-color 120ms ease', | ||
| borderRadius: unitVars.unit.radius.full, | ||
| }, | ||
| variants: { | ||
| state: { | ||
| default: { | ||
| border: `1px solid ${colorVars.color.border.secondary}`, | ||
| backgroundColor: `${colorVars.color.fill.inverseSecondary}`, | ||
| width: '2.4rem', | ||
| height: '2.4rem', | ||
| }, | ||
| selected: { | ||
| border: 'none', | ||
| backgroundColor: colorVars.color.fill.strong, | ||
| width: '2.4rem', | ||
| height: '2.4rem', | ||
| color: colorVars.color.text.inverse, | ||
| ...fontVars.font.body_m_14, | ||
| }, | ||
| }, | ||
| }, | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import * as styles from './MoodboardCard.css'; | ||
|
|
||
| interface MoodboardCardProps | ||
| extends Omit<React.ComponentPropsWithoutRef<'button'>, 'children' | 'type'> { | ||
| src: string; | ||
| alt: string; | ||
| selectOrder?: number; | ||
| } | ||
|
|
||
| const MoodboardCard = ({ | ||
| src, | ||
| alt, | ||
| selectOrder = 0, | ||
| disabled = false, | ||
| className, | ||
| ...rest | ||
| }: MoodboardCardProps) => { | ||
| const isSelected = selectOrder > 0; | ||
|
|
||
| // 카드 컨테이너 스타일 상태 (disabled가 우선) | ||
| const cardState = disabled ? 'disabled' : isSelected ? 'selected' : 'default'; | ||
| // 체크박스(index 동그라미) 스타일 상태 (선택 여부만 반영) | ||
| const checkState = isSelected ? 'selected' : 'default'; | ||
|
|
||
| return ( | ||
| <button | ||
| type="button" | ||
| disabled={disabled} | ||
| aria-pressed={isSelected} | ||
| className={`${styles.card({ state: cardState })}${className ? ` ${className}` : ''}`} | ||
| {...rest} | ||
| > | ||
| <img src={src} alt={alt} className={styles.image} draggable={false} /> | ||
| {!disabled && ( | ||
| <span className={styles.checkbox({ state: checkState })}> | ||
| <span className={styles.circle({ state: checkState })}> | ||
| {isSelected ? selectOrder : ''} | ||
| </span> | ||
| </span> | ||
| )} | ||
| </button> | ||
| ); | ||
| }; | ||
|
|
||
| export default MoodboardCard; |
Uh oh!
There was an error while loading. Please reload this page.