Badge
Badge (배지)
Badge는 보통 알림이나 사용자 아바타 근처에 눈에 띄게 표시되며, 주로 읽지 않은 메시지 개수를 나타내는 컴포넌트예요.
출처: 문서
본문
언제 사용하나요
Badge는 보통 알림이나 사용자 아바타 근처에 눈에 띄게 나타나며, 주로 읽지 않은 메시지 개수를 표시해요.
예제 (Examples)
기본 (Basic)
가장 단순한 사용법이에요. count가 0이면 Badge는 숨겨지지만, showZero를 사용해 표시할 수 있어요.
import React from 'react';
import { ClockCircleOutlined } from '@ant-design/icons';
import { Avatar, Badge, Space } from 'antd';
const App: React.FC = () => (
<Space size="medium">
<Badge count={5}>
<Avatar shape="square" size="large" />
</Badge>
<Badge count={0} showZero>
<Avatar shape="square" size="large" />
</Badge>
<Badge count={<ClockCircleOutlined style={{ color: '#f5222d' }} />}>
<Avatar shape="square" size="large" />
</Badge>
</Space>
);
export default App;
단독 사용 (Standalone)
children이 비어 있을 때 단독으로 사용돼요.
import React, { useState } from 'react';
import { ClockCircleOutlined } from '@ant-design/icons';
import { Badge, Space, Switch } from 'antd';
const App: React.FC = () => {
const [show, setShow] = useState(true);
return (
<Space>
<Switch aria-label="Show badge counts" checked={show} onChange={() => setShow(!show)} />
<Badge count={show ? 11 : 0} showZero color="#faad14" />
<Badge count={show ? 25 : 0} />
<Badge count={show ? <ClockCircleOutlined style={{ color: '#f5222d' }} /> : 0} />
<Badge
className="site-badge-count-109"
count={show ? 109 : 0}
style={{ backgroundColor: '#52c41a' }}
/>
</Space>
);
};
export default App;
오버플로 개수 (Overflow Count)
count가 overflowCount보다 크면 ${overflowCount}+가 표시돼요. overflowCount의 기본값은 99예요.
import React from 'react';
import { Avatar, Badge, Space } from 'antd';
const App: React.FC = () => (
<Space size="large">
<Badge count={99}>
<Avatar shape="square" size="large" />
</Badge>
<Badge count={100}>
<Avatar shape="square" size="large" />
</Badge>
<Badge count={99} overflowCount={10}>
<Avatar shape="square" size="large" />
</Badge>
<Badge count={1000} overflowCount={999}>
<Avatar shape="square" size="large" />
</Badge>
</Space>
);
export default App;
빨간 점 (Red badge)
구체적인 개수 없이 빨간 점만 표시해요. count가 0이면 점을 표시하지 않아요.
import React from 'react';
import { NotificationOutlined } from '@ant-design/icons';
import { Badge, Space } from 'antd';
const App: React.FC = () => (
<Space>
<Badge dot>
<NotificationOutlined style={{ fontSize: 16 }} />
</Badge>
<Badge dot>
<a href="#">Link something</a>
</Badge>
</Space>
);
export default App;
동적 (Dynamic)
count가 변할 때 애니메이션 효과가 적용돼요.
import React, { useState } from 'react';
import { MinusOutlined, PlusOutlined, QuestionOutlined } from '@ant-design/icons';
import { Avatar, Badge, Button, Space, Switch } from 'antd';
const App: React.FC = () => {
const [count, setCount] = useState(5);
const [show, setShow] = useState(true);
const increase = () => {
setCount(count + 1);
};
const decline = () => {
let newCount = count - 1;
if (newCount < 0) {
newCount = 0;
}
setCount(newCount);
};
const random = () => {
const newCount = Math.floor(Math.random() * 100);
setCount(newCount);
};
const onChange = (checked: boolean) => {
setShow(checked);
};
return (
<Space vertical>
<Space size="large">
<Badge count={count}>
<Avatar shape="square" size="large" />
</Badge>
<Space.Compact>
<Button onClick={decline} icon={<MinusOutlined />} />
<Button onClick={increase} icon={<PlusOutlined />} />
<Button onClick={random} icon={<QuestionOutlined />} />
</Space.Compact>
</Space>
<Space size="large">
<Badge dot={show}>
<Avatar shape="square" size="large" />
</Badge>
<Switch aria-label="Show badge dot" onChange={onChange} checked={show} />
</Space>
</Space>
);
};
export default App;
클릭 가능 (Clickable)
Badge를 a 태그로 감싸 링크로 만들 수 있어요.
import React from 'react';
import { Avatar, Badge } from 'antd';
const App: React.FC = () => (
<a href="#">
<Badge count={5}>
<Avatar shape="square" size="large" />
</Badge>
</a>
);
export default App;
오프셋 (Offset)
배지 점의 오프셋을 설정해요. 형식은 [left, top]으로, 상태 점이 기본 위치의 왼쪽과 위에서 얼마나 떨어지는지를 나타내요.
import React from 'react';
import { Avatar, Badge } from 'antd';
const App: React.FC = () => (
<Badge count={5} offset={[10, 10]}>
<Avatar shape="square" size="large" />
</Badge>
);
export default App;
크기 (Size)
숫자 Badge의 크기를 설정해요.
import React from 'react';
import { Avatar, Badge, Space } from 'antd';
const App: React.FC = () => (
<Space size="medium">
<Badge size="medium" count={5}>
<Avatar shape="square" size="large" />
</Badge>
<Badge size="small" count={5}>
<Avatar shape="square" size="large" />
</Badge>
</Space>
);
export default App;
상태 (Status)
상태가 있는 단독 배지예요.
import React from 'react';
import { Badge, Space } from 'antd';
const App: React.FC = () => (
<>
<Space>
<Badge status="success" />
<Badge status="error" />
<Badge status="default" />
<Badge status="processing" />
<Badge status="warning" />
</Space>
<br />
<Space vertical>
<Badge status="success" text="Success" />
<Badge status="error" text="Error" />
<Badge status="default" text="Default" />
<Badge status="processing" text="Processing" />
<Badge status="warning" text="Warning" />
</Space>
</>
);
export default App;
컬러풀 Badge
다양한 상황에 쓰기 위한 일련의 컬러풀한 Badge 스타일을 미리 정의해 뒀어요. 커스텀 색을 위해 hex 색 문자열로도 설정할 수 있어요.
import React from 'react';
import { Badge, Divider, Space } from 'antd';
const colors = [
'pink',
'red',
'yellow',
'orange',
'cyan',
'green',
'blue',
'purple',
'geekblue',
'magenta',
'volcano',
'gold',
'lime',
];
const App: React.FC = () => (
<>
<Divider titlePlacement="start">Presets</Divider>
<Space vertical>
{colors.map((color) => (
<Badge key={color} color={color} text={color} />
))}
</Space>
<Divider titlePlacement="start">Custom</Divider>
<Space vertical>
<Badge color="#f50" text="#f50" />
<Badge color="rgb(45, 183, 245)" text="rgb(45, 183, 245)" />
<Badge color="hsl(102, 53%, 61%)" text="hsl(102, 53%, 61%)" />
<Badge color="hwb(205 6% 9%)" text="hwb(205 6% 9%)" />
</Space>
</>
);
export default App;
리본 (Ribbon)
리본 배지를 사용해요.
import React from 'react';
import { Badge, Card, Space } from 'antd';
const App: React.FC = () => (
<Space vertical size="medium" style={{ width: '100%' }}>
<Badge.Ribbon text="Hippies">
<Card title="Pushes open the window" size="small">
and raises the spyglass.
</Card>
</Badge.Ribbon>
<Badge.Ribbon text="Hippies" color="pink">
<Card title="Pushes open the window" size="small">
and raises the spyglass.
</Card>
</Badge.Ribbon>
<Badge.Ribbon text="Hippies" color="red">
<Card title="Pushes open the window" size="small">
and raises the spyglass.
</Card>
</Badge.Ribbon>
<Badge.Ribbon text="Hippies" color="cyan">
<Card title="Pushes open the window" size="small">
and raises the spyglass.
</Card>
</Badge.Ribbon>
<Badge.Ribbon text="Hippies" color="green">
<Card title="Pushes open the window" size="small">
and raises the spyglass.
</Card>
</Badge.Ribbon>
<Badge.Ribbon text="Hippies" color="purple">
<Card title="Pushes open the window" size="small">
and raises the spyglass.
</Card>
</Badge.Ribbon>
<Badge.Ribbon text="Hippies" color="volcano">
<Card title="Pushes open the window" size="small">
and raises the spyglass.
</Card>
</Badge.Ribbon>
<Badge.Ribbon text="Hippies" color="magenta">
<Card title="Pushes open the window" size="small">
and raises the spyglass.
</Card>
</Badge.Ribbon>
</Space>
);
export default App;
커스텀 시맨틱 DOM 스타일링
classNames와 styles에 객체/함수를 전달해 Badge의 시맨틱 DOM 스타일을 커스터마이즈할 수 있어요.
import React from 'react';
import { Avatar, Badge, Card, Flex, Space } from 'antd';
import type { BadgeProps, GetProp } from 'antd';
import { createStaticStyles } from 'antd-style';
import type { RibbonProps } from 'antd/es/badge/Ribbon';
const badgeClassNames = createStaticStyles(({ css }) => ({
indicator: css`
font-size: 10px;
`,
}));
const ribbonClassNames = createStaticStyles(({ css }) => ({
root: css`
width: 400px;
border: 1px solid #d9d9d9;
border-radius: 10px;
`,
}));
const badgeStyles: BadgeProps['styles'] = {
root: {
borderRadius: 8,
},
};
const ribbonStyles: RibbonProps['styles'] = {
indicator: {
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
},
};
const badgeStylesFn: BadgeProps['styles'] = (info): GetProp<RibbonProps, 'styles', 'Return'> => {
if (info.props.size === 'medium') {
return {
indicator: {
fontSize: 14,
backgroundColor: '#696FC7',
},
};
}
return {};
};
const ribbonStylesFn: RibbonProps['styles'] = (info): GetProp<RibbonProps, 'styles', 'Return'> => {
if (info.props.color === '#696FC7') {
return {
content: {
fontWeight: 'bold',
},
indicator: {
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
},
};
}
return {};
};
const App: React.FC = () => {
return (
<Space size="large" vertical>
<Flex gap="medium">
<Badge size="small" count={5} classNames={badgeClassNames} styles={badgeStyles}>
<Avatar shape="square" size="large" />
</Badge>
<Badge count={5} classNames={badgeClassNames} styles={badgeStylesFn}>
<Avatar shape="square" size="large" />
</Badge>
</Flex>
<Flex vertical gap="medium">
<Badge.Ribbon text="Custom Ribbon" classNames={ribbonClassNames} styles={ribbonStyles}>
<Card title="Card with custom ribbon" size="small">
This card has a customized ribbon with semantic classNames and styles.
</Card>
</Badge.Ribbon>
<Badge.Ribbon
text="Custom Ribbon"
color="#696FC7"
classNames={ribbonClassNames}
styles={ribbonStylesFn}
>
<Card title="Card with custom ribbon" size="small">
This card has a customized ribbon with semantic classNames and styles.
</Card>
</Badge.Ribbon>
</Flex>
</Space>
);
};
export default App;
API
공통 props 참고: Common props
Badge
| 속성 | 설명 | 타입 | 기본값 | 버전 | 전역 설정 |
|---|---|---|---|---|---|
| color | Badge 점 색 커스터마이즈 | string | - | × | |
| count | 배지에 표시할 숫자 | ReactNode | - | × | |
| classNames | 컴포넌트 내부 각 시맨틱 구조의 클래스 커스터마이즈. 객체 또는 함수 지원 | Record<SemanticDOM, string> | (info: { props })=> Record<SemanticDOM, string> | - | 5.7.0 | |
| dot | count 대신 빨간 점 표시 여부 |
boolean | false | × | |
| offset | 배지 점의 오프셋 설정 | [number, number] | - | × | |
| overflowCount | 표시할 최대 개수 | number | 99 | × | |
| showZero | count가 0일 때 배지 표시 여부 |
boolean | false | × | |
| size | count가 설정되면 size가 배지 크기를 결정 |
medium | small |
- | - | × |
| status | Badge를 상태 점으로 설정 | success | processing | default | error | warning |
- | × | |
| styles | 컴포넌트 내부 각 시맨틱 구조의 인라인 스타일 커스터마이즈. 객체 또는 함수 지원 | Record<SemanticDOM, CSSProperties> | (info: { props })=> Record<SemanticDOM, CSSProperties> | - | 5.7.0 | |
| text | status가 설정되면 text가 상태 dot의 표시 텍스트를 결정 |
ReactNode | - | × | |
| title | 배지에 마우스를 올렸을 때 표시할 텍스트. 네이티브 툴팁을 제거하려면 null 또는 false로 설정 |
string | null | false | - | 6.5.0 | × |
Badge.Ribbon
| 속성 | 설명 | 타입 | 기본값 | 버전 | 전역 설정 |
|---|---|---|---|---|---|
| classNames | 컴포넌트 내부 각 시맨틱 구조의 클래스 커스터마이즈. 객체 또는 함수 지원 | Record<SemanticDOM, string> | (info: { props })=> Record<SemanticDOM, string> | - | 6.0.0 | |
| color | Ribbon 색 커스터마이즈 | string | - | × | |
| placement | Ribbon의 위치, start와 end는 텍스트 방향(RTL 또는 LTR)을 따름 |
start | end |
end |
× | |
| styles | 컴포넌트 내부 각 시맨틱 구조의 인라인 스타일 커스터마이즈. 객체 또는 함수 지원 | Record<SemanticDOM, CSSProperties> | (info: { props })=> Record<SemanticDOM, CSSProperties> | - | 6.0.0 | |
| text | Ribbon 내부 콘텐츠 | ReactNode | - | × |
시맨틱 DOM (Semantic DOM)
Badge
https://ant.design/components/badge/semantic.md
Badge.Ribbon
https://ant.design/components/badge/semantic_ribbon.md
디자인 토큰 (Design Token)
컴포넌트 토큰 (Badge)
| 토큰 이름 | 설명 | 타입 | 기본값 |
|---|---|---|---|
| dotSize | 점 배지 크기 | number | 6 |
| indicatorHeight | 배지 높이 | string | number | 20 |
| indicatorHeightSM | 작은 배지 높이 | string | number | 14 |
| indicatorZIndex | 배지의 z-index | string | number | auto |
| paddingInline | 여러 단어 배지의 인라인 패딩 | string | number | 8 |
| statusSize | 상태 배지 크기 | number | 6 |
| textFontSize | 배지 텍스트의 폰트 크기 | number | 12 |
| textFontSizeSM | 작은 배지 텍스트의 폰트 크기 | number | 12 |
| textFontWeight | 배지 텍스트의 폰트 두께 | string | number | normal |
전역 토큰 (Global Token)
| 토큰 이름 | 설명 | 타입 | 기본값 |
|---|---|---|---|
| colorBorderBg | 요소의 배경 테두리 색 제어. | string | |
| colorError | 작업 실패의 시각 요소를 나타내는 데 사용. 예: 오류 Button, 오류 Result 컴포넌트 등 | string | |
| colorErrorHover | 오류 색의 호버 상태. | string | |
| colorInfo | 정보 토큰 시퀀스. Alert, Tag, Progress 등 컴포넌트가 이 map 토큰 사용 | string | |
| colorInfoTextHover | 정보 색의 텍스트 색 호버 상태. | string | |
| colorSuccess | 작업 성공의 토큰 시퀀스. Result, Progress 등 컴포넌트가 이 map 토큰 사용 | string | |
| colorText | W3C 표준을 준수하는 기본 텍스트 색. 가장 어두운 중성색이기도 함. | string | |
| colorTextLightSolid | 배경색이 있는 텍스트의 하이라이트 색 제어. 예: Primary Button의 텍스트 | string | |
| colorTextPlaceholder | placeholder 텍스트 색 제어. | string | |
| colorWarning | 경고 map 토큰. Notification, Alert 등이 사용. Alert 또는 Control 컴포넌트(Input)도 사용 | string | |
| fontFamily | 시스템 기본 인터페이스 폰트와 화면 표시에 적합한 대체 폰트 라이브러리 세트 제공 | string | |
| fontSize | 디자인 시스템에서 가장 널리 사용되는 폰트 크기. | number | |
| lineHeight | 텍스트의 줄 높이. | number | |
| lineWidth | 기본 컴포넌트의 테두리 너비 | number | |
| marginXS | 요소의 여백 제어, 작은 크기. | number | |
| motionDurationMid | 모션 속도, 중간 속도. 중간 요소 애니메이션 상호작용에 사용. | string | |
| motionDurationSlow | 모션 속도, 느린 속도. 대형 요소 애니메이션 상호작용에 사용. | string | |
| motionEaseOutBack | 프리셋 모션 곡선. | string |
더 알아보기 (Learn more)
- Avatar 컴포넌트 — 아바타 배지
- Tabs 컴포넌트 — 탭 배지
- Ant Design 시작하기 — 프로젝트 설정