Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
a310e40
feat: 제네릭을 이용해 다형성 처리 시 forwardRef 를 돕는 헬퍼 함수를 생성합니다.
WonJuneKim Nov 14, 2025
6cc1bfd
refactor: Label 컴포넌트가 다양한 메타 태그로 사용될 수 있도록 다형성 처리를 적용합니다.
WonJuneKim Nov 14, 2025
16fc3a0
test: 스토리북에서 Label 컴포넌트의 색상이 주입되는 케이스를 추가합니다.
WonJuneKim Nov 14, 2025
c015c51
feat: 수정된 Label 컴포넌트 관련 속성을 barrel export합니다.
WonJuneKim Nov 14, 2025
a62328e
feat: 수정된 Label 컴포넌트의 영향을 받는 Badge 컴포넌트의 구조를 수정합니다.
WonJuneKim Nov 14, 2025
e3a3c63
feat: Interaction 유틸리티가 CSS Object 타입을 반환하도록 명시합니다.
WonJuneKim Nov 16, 2025
b7772f8
feat: 다형성 처리를 돕는 유틸리티 함수가 displayName을 지원하도록 변경합니다.
WonJuneKim Nov 16, 2025
527678a
feat: Image 컴포넌트가 다양한 메타 태그를 가질 수 있도록 변경합니다.
WonJuneKim Nov 16, 2025
b370ac8
feat: Compound Component 패턴을 사용하기 위한 내부 Context를 선언합니다.
WonJuneKim Nov 17, 2025
3710589
feat: Card 컴포넌트의 Image 부분을 구현합니다.
WonJuneKim Nov 17, 2025
4f5e869
feat: Compound Component에서 사용하는 스타일링 코드의 초안을 작성합니다.
WonJuneKim Nov 17, 2025
cca42a3
feat: CardContent의 구현 및 추가 스타일링을 처리합니다.
WonJuneKim Nov 17, 2025
c857afc
feat: Card의 context 내부에서 titleVariant 변경을 처리하지 않습니다.
WonJuneKim Nov 17, 2025
5e59580
feat: Card의 base가 되는 Card.Root를 선언합니다.
WonJuneKim Nov 17, 2025
7817326
feat: 변경된 context를 CardImage에 반영합니다.
WonJuneKim Nov 17, 2025
e9d417f
feat: 변경된 context를 스타일링에 반영합니다.
WonJuneKim Nov 17, 2025
f3e2a12
feat: Card 컴포넌트 중 Title 부분을 구현합니다.
WonJuneKim Nov 17, 2025
1810c8f
feat: Card 컴포넌트 중 label을 담당하는 컴포넌트 들을 구현합니다.
WonJuneKim Nov 17, 2025
f9cf24d
feat: Card 컴포넌트 중 MetaData를 전달하는 요소들을 구현합니다.
WonJuneKim Nov 18, 2025
a06cb32
feat: Card 컴포넌트의 Preset를 생성합니다.
WonJuneKim Nov 18, 2025
05f425f
feat: Label 컴포넌트의 스타일링과 동일한 액션을 수행하는 유틸리티 함수를 생성합니다.
WonJuneKim Nov 18, 2025
54f10c1
feat: 공통 InteractionLayer 를 생성하는 유틸리티 함수를 생성합니다.
WonJuneKim Nov 18, 2025
51904f7
feat: 구현한 컴포넌트들을 barrel export합니다.
WonJuneKim Nov 18, 2025
bd126b1
fix: where 로 표현된 의사 클래스의 미적용 문제를 직접 선언으로 해결합니다.
WonJuneKim Nov 18, 2025
7e38828
Merge branch 'dev' of github.com:JECT-Study/JECT-Official-WebSite-Cli…
WonJuneKim Nov 20, 2025
89e4976
feat: 변경된 스타일 토큰을 기존 스타일링에 반영합니다.
WonJuneKim Nov 20, 2025
ef203ff
feat: Card Root의 다형성 구조를 제거하고 Article Element Type으로 변경합니다.
WonJuneKim Nov 20, 2025
83bfa99
feat: 추상화된 비즈니스 레이어 내에서 Polymorphic한 구조를 사용하도록 변경합니다.
WonJuneKim Nov 20, 2025
335a244
test: Card 컴포넌트의 스토리북을 작성합니다.
WonJuneKim Nov 20, 2025
8a753dd
Merge branch 'dev' into feat/257-card-design-system
WonJuneKim Nov 20, 2025
3dbf6f5
chore: Storybook에 Globalstyles를 추가합니다.
WonJuneKim Nov 23, 2025
64043ed
feat: forwardRef의 타입캐스팅 방식을 변경하고, ref를 병합하는 방식을 변경합니다.
WonJuneKim Nov 24, 2025
5c14eaf
feat: Card의 인터렉션을 위한 Overlay를 추가합니다.
WonJuneKim Nov 25, 2025
5fab790
refactor: Card의 root는 div로 명시하고, context 내에서 interactive props을 관리하도록…
WonJuneKim Nov 25, 2025
7767dda
refactor: 스타일링에 overlay를 추가합니다.
WonJuneKim Nov 25, 2025
c90e677
refactor: 추상화된 프리셋 레이어에 유니온 타입을 활용해 특정 태그로 사용될 수 있음을 명시합니다.
WonJuneKim Nov 25, 2025
bab9f78
feat: CardImage의 구조를 variant 분기로 다른 구조를 가지도록합니다.
WonJuneKim Nov 25, 2025
dc44484
refactor: Image가 Card 내부에서 사용될 때 크기를 명시적으로 선언합니다.
WonJuneKim Nov 25, 2025
f1f54d2
refactor: Image가 Card 내부에서 사용될 때 크기를 명시적으로 선언합니다.
WonJuneKim Nov 25, 2025
0179168
feat: 프리셋에서 캡션의 위치를 변경합니다.
WonJuneKim Nov 25, 2025
f74bcbf
feat: 불필요한 description을 제거하고, 하위 요소의 말줄임 속성을 통일합니다.
WonJuneKim Nov 25, 2025
97fb6e0
test: 스토리북의 Card 테스트 케이스를 구체화합니다.
WonJuneKim Nov 25, 2025
c745938
feat: Card.Root와 Image는 항상 부모의 width와 height를 따르도록 합니다.
WonJuneKim Nov 25, 2025
dd75e06
test: Card 스토리북에 description을 작성하고, 부모 컨테이너의 스타일에 width, height를 명시합니다.
WonJuneKim Nov 25, 2025
9536e9d
feat: 작성한 컴포넌트들을 export합니다.
WonJuneKim Nov 25, 2025
6398a2b
Merge branch 'feat/257-card-design-system' of github.com:JECT-Study/J…
WonJuneKim Nov 25, 2025
5e17d2e
Merge branch 'dev' into feat/257-card-design-system
WonJuneKim Nov 25, 2025
0a28c72
docs: 불필요하게 처리된 개행을 제거합니다.
WonJuneKim Nov 25, 2025
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
1 change: 0 additions & 1 deletion packages/jds/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Preview } from '@storybook/react';
import { Global, ThemeProvider } from '@emotion/react';
import { theme } from '../src/tokens/theme';
import { globalStyles } from '../src/tokens/globalStyles';
import { GlobalStyles } from '../src/style/globalStyle';

const preview: Preview = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
} from './contentBadge.variants';

import { Icon } from '@/components/Icon';
import { Label } from '@/components/Label';

interface ContentBasicBadgeDivProps {
hierarchy: BasicHierarchy;
Expand All @@ -34,9 +35,6 @@ export const ContentBadgeBasicDiv = styled.div<ContentBasicBadgeDivProps>(
const backgroundColor = isMuted
? contentBadgeBasicMutedStylesMap(theme)[badgeStyle].bg
: contentBadgeBasicStylesMap(theme)[badgeStyle][hierarchy].bg;
const color = isMuted
? contentBadgeBasicMutedStylesMap(theme)[badgeStyle].color
: contentBadgeBasicStylesMap(theme)[badgeStyle][hierarchy].color;
const border = isMuted
? contentBadgeBasicMutedStylesMap(theme)[badgeStyle].border
: contentBadgeBasicStylesMap(theme)[badgeStyle][hierarchy].border;
Expand All @@ -49,13 +47,33 @@ export const ContentBadgeBasicDiv = styled.div<ContentBasicBadgeDivProps>(
alignItems: 'center',
gap: withIcon ? pxToRem(4) : '0',
backgroundColor,
color,
border: `1px solid ${border}`,
borderRadius: theme.scheme.semantic.radius[4],
};
},
);

interface ContentBadgeBasicLabelProps {
hierarchy: BasicHierarchy;
badgeStyle: ContentBadgeStyle;
isMuted: boolean;
}

export const ContentBadgeBasicLabel = styled(Label)<ContentBadgeBasicLabelProps>(({
theme,
hierarchy,
badgeStyle,
isMuted,
}) => {
const color = isMuted
? contentBadgeBasicMutedStylesMap(theme)[badgeStyle].color
: contentBadgeBasicStylesMap(theme)[badgeStyle][hierarchy].color;

return {
color,
};
});

interface BadgeIconProps {
hierarchy: BasicHierarchy;
badgeStyle: ContentBadgeStyle;
Expand Down Expand Up @@ -89,9 +107,6 @@ export const ContentBadgeFeedbackDiv = styled.div<ContentBadgeFeedbackDivProps>(
const backgroundColor = isMuted
? contentBadgeFeedbackMutedStylesMap(theme)[badgeStyle][variant].bg
: contentBadgeFeedbackStylesMap(theme)[badgeStyle][variant].bg;
const color = isMuted
? contentBadgeFeedbackMutedStylesMap(theme)[badgeStyle][variant].color
: contentBadgeFeedbackStylesMap(theme)[badgeStyle][variant].color;
const border = isMuted
? contentBadgeFeedbackMutedStylesMap(theme)[badgeStyle][variant].border
: contentBadgeFeedbackStylesMap(theme)[badgeStyle][variant].border;
Expand All @@ -104,13 +119,33 @@ export const ContentBadgeFeedbackDiv = styled.div<ContentBadgeFeedbackDivProps>(
alignItems: 'center',
gap: '0px',
backgroundColor,
color,
border: `1px solid ${border}`,
borderRadius: theme.scheme.semantic.radius['4'],
};
},
);

interface ContentBadgeFeedbackLabelProps {
variant: FeedbackVariant;
badgeStyle: ContentBadgeStyle;
isMuted: boolean;
}

export const ContentBadgeFeedbackLabel = styled(Label)<ContentBadgeFeedbackLabelProps>(({
theme,
variant,
badgeStyle,
isMuted,
}) => {
const color = isMuted
? contentBadgeFeedbackMutedStylesMap(theme)[badgeStyle][variant].color
: contentBadgeFeedbackStylesMap(theme)[badgeStyle][variant].color;

return {
color,
};
});

interface ContentBadgeThemeDivProps {
variant: ThemeVariant;
size: BadgeSize;
Expand All @@ -123,9 +158,6 @@ export const ContentBadgeThemeDiv = styled.div<ContentBadgeThemeDivProps>(
const backgroundColor = isMuted
? contentBadgeThemeMutedStylesMap(theme)[badgeStyle][variant].bg
: contentBadgeThemeStylesMap(theme)[badgeStyle][variant].bg;
const color = isMuted
? contentBadgeThemeMutedStylesMap(theme)[badgeStyle][variant].color
: contentBadgeThemeStylesMap(theme)[badgeStyle][variant].color;
const border = isMuted
? contentBadgeThemeMutedStylesMap(theme)[badgeStyle][variant].border
: contentBadgeThemeStylesMap(theme)[badgeStyle][variant].border;
Expand All @@ -138,9 +170,29 @@ export const ContentBadgeThemeDiv = styled.div<ContentBadgeThemeDivProps>(
alignItems: 'center',
gap: '0px',
backgroundColor,
color,
border: `1px solid ${border}`,
borderRadius: theme.scheme.semantic.radius[4],
};
},
);

interface ContentBadgeThemeLabelProps {
variant: ThemeVariant;
badgeStyle: ContentBadgeStyle;
isMuted: boolean;
}

export const ContentBadgeThemeLabel = styled(Label)<ContentBadgeThemeLabelProps>(({
theme,
variant,
badgeStyle,
isMuted,
}) => {
const color = isMuted
? contentBadgeThemeMutedStylesMap(theme)[badgeStyle][variant].color
: contentBadgeThemeStylesMap(theme)[badgeStyle][variant].color;

return {
color,
};
});
38 changes: 30 additions & 8 deletions packages/jds/src/components/Badge/contentBadge/ContentBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import type { ReactNode } from 'react';
import {
BadgeIcon,
ContentBadgeBasicDiv,
ContentBadgeBasicLabel,
ContentBadgeFeedbackDiv,
ContentBadgeFeedbackLabel,
ContentBadgeThemeDiv,
ContentBadgeThemeLabel,
} from './ContentBadge.style';
import type {
BadgeSize,
Expand All @@ -15,8 +18,6 @@ import type {
} from '../badge.types';
import { iconSizeMap } from './contentBadge.variants';

import { Label } from '@/components/Label';

export interface ContentBadgeBasicProps {
hierarchy?: BasicHierarchy;
size?: BadgeSize;
Expand Down Expand Up @@ -44,9 +45,16 @@ const ContentBadgeBasic = ({
isMuted={isMuted}
withIcon={withIcon}
>
<Label as='span' size={size} textAlign='center' weight='normal' color='inherit'>
<ContentBadgeBasicLabel
size={size}
textAlign='center'
weight='normal'
hierarchy={hierarchy}
badgeStyle={badgeStyle}
isMuted={isMuted}
>
{children}
</Label>
</ContentBadgeBasicLabel>
{withIcon && (
<BadgeIcon
name='close-line'
Expand Down Expand Up @@ -84,9 +92,16 @@ const ContentBadgeFeedback = ({
badgeStyle={badgeStyle}
isMuted={isMuted}
>
<Label as='span' size={size} textAlign='center' weight='normal' color='inherit'>
<ContentBadgeFeedbackLabel
size={size}
textAlign='center'
weight='normal'
variant={variant}
badgeStyle={badgeStyle}
isMuted={isMuted}
>
{children}
</Label>
</ContentBadgeFeedbackLabel>
</ContentBadgeFeedbackDiv>
);
};
Expand All @@ -110,9 +125,16 @@ const ContentBadgeTheme = ({
}: ContentThemeBadgeProps) => {
return (
<ContentBadgeThemeDiv variant={variant} size={size} badgeStyle={badgeStyle} isMuted={isMuted}>
<Label as='span' size={size} textAlign='center' weight='normal' color='inherit'>
<ContentBadgeThemeLabel
size={size}
textAlign='center'
weight='normal'
variant={variant}
badgeStyle={badgeStyle}
isMuted={isMuted}
>
{children}
</Label>
</ContentBadgeThemeLabel>
</ContentBadgeThemeDiv>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
numericBadgeFeedbacksMutedStylesMap,
} from './numericBadge.variants';

import { Label } from '@/components/Label';

interface NumericBadgeBasicDivProps {
hierarchy: BasicHierarchy;
size: BadgeSize;
Expand All @@ -22,9 +24,6 @@ export const NumericBadgeBasicDiv = styled.div<NumericBadgeBasicDivProps>(
const backgroundColor = isMuted
? numericBadgeBasicMutedStylesMap(theme)[badgeStyle].bg
: numericBadgeBasicStylesMap(theme)[badgeStyle][hierarchy].bg;
const color = isMuted
? numericBadgeBasicMutedStylesMap(theme)[badgeStyle].color
: numericBadgeBasicStylesMap(theme)[badgeStyle][hierarchy].color;

return {
minWidth: pxToRem(numericBadgeSizeMap[size].minWidth),
Expand All @@ -33,12 +32,32 @@ export const NumericBadgeBasicDiv = styled.div<NumericBadgeBasicDivProps>(
justifyContent: 'center',
alignItems: 'center',
backgroundColor,
color,
borderRadius: theme.scheme.semantic.radius.max,
};
},
);

interface NumericBadgeBasicLabelProps {
hierarchy: BasicHierarchy;
badgeStyle: NumericBadgeStyle;
isMuted: boolean;
}

export const NumericBadgeBasicLabel = styled(Label)<NumericBadgeBasicLabelProps>(({
theme,
hierarchy,
badgeStyle,
isMuted,
}) => {
const color = isMuted
? numericBadgeBasicMutedStylesMap(theme)[badgeStyle].color
: numericBadgeBasicStylesMap(theme)[badgeStyle][hierarchy].color;

return {
color,
};
});

interface NumericBadgeFeedbackDivProps {
variant: FeedbackVariant;
size: BadgeSize;
Expand All @@ -51,9 +70,6 @@ export const NumericBadgeFeedbackDiv = styled.div<NumericBadgeFeedbackDivProps>(
const backgroundColor = isMuted
? numericBadgeFeedbacksMutedStylesMap(theme)[badgeStyle][variant].bg
: numericBadgeFeedbackStylesMap(theme)[badgeStyle][variant].bg;
const color = isMuted
? numericBadgeFeedbacksMutedStylesMap(theme)[badgeStyle][variant].color
: numericBadgeFeedbackStylesMap(theme)[badgeStyle][variant].color;

return {
minWidth: pxToRem(numericBadgeSizeMap[size].minWidth),
Expand All @@ -62,8 +78,28 @@ export const NumericBadgeFeedbackDiv = styled.div<NumericBadgeFeedbackDivProps>(
justifyContent: 'center',
alignItems: 'center',
backgroundColor,
color,
borderRadius: theme.scheme.semantic.radius.max,
};
},
);

interface NumericBadgeFeedbackLabelProps {
variant: FeedbackVariant;
badgeStyle: NumericBadgeStyle;
isMuted: boolean;
}

export const NumericBadgeFeedbackLabel = styled(Label)<NumericBadgeFeedbackLabelProps>(({
theme,
variant,
badgeStyle,
isMuted,
}) => {
const color = isMuted
? numericBadgeFeedbacksMutedStylesMap(theme)[badgeStyle][variant].color
: numericBadgeFeedbackStylesMap(theme)[badgeStyle][variant].color;

return {
color,
};
});
31 changes: 24 additions & 7 deletions packages/jds/src/components/Badge/numericBadge/NumericBadge.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type { ReactNode } from 'react';

import type { BadgeSize, BasicHierarchy, FeedbackVariant, NumericBadgeStyle } from '../badge.types';
import { NumericBadgeBasicDiv, NumericBadgeFeedbackDiv } from './NumericBadge.style';

import { Label } from '@/components/Label';
import {
NumericBadgeBasicDiv,
NumericBadgeBasicLabel,
NumericBadgeFeedbackDiv,
NumericBadgeFeedbackLabel,
} from './NumericBadge.style';

export interface NumericBadgeBasicProps {
hierarchy?: BasicHierarchy;
Expand All @@ -27,9 +30,16 @@ const NumericBadgeBasic = ({
badgeStyle={badgeStyle}
isMuted={isMuted}
>
<Label as='span' size={size} textAlign='center' weight='normal' color='inherit'>
<NumericBadgeBasicLabel
size={size}
textAlign='center'
weight='normal'
hierarchy={hierarchy}
badgeStyle={badgeStyle}
isMuted={isMuted}
>
{children}
</Label>
</NumericBadgeBasicLabel>
</NumericBadgeBasicDiv>
);
};
Expand Down Expand Up @@ -58,9 +68,16 @@ const NumericBadgeFeedback = ({
badgeStyle={badgeStyle}
isMuted={isMuted}
>
<Label as='span' size={size} textAlign='center' weight='normal' color='inherit'>
<NumericBadgeFeedbackLabel
size={size}
textAlign='center'
weight='normal'
variant={variant}
badgeStyle={badgeStyle}
isMuted={isMuted}
>
{children}
</Label>
</NumericBadgeFeedbackLabel>
</NumericBadgeFeedbackDiv>
);
};
Expand Down
23 changes: 23 additions & 0 deletions packages/jds/src/components/Card/Card.context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { createContext, useContext } from 'react';

import type { CardLayout, CardVariant, CardStyle } from './Card.types';

export interface CardContextValue {
layout: CardLayout;
variant: CardVariant;
cardStyle?: CardStyle;
isDisabled: boolean;
interactive: boolean;
}

export const CardContext = createContext<CardContextValue | null>(null);

export const useCardContext = (): CardContextValue => {
const context = useContext(CardContext);

if (!context) {
throw new Error('must be used within Card.Root');
}

return context;
};
Loading