I HATE FLYING BUGS logoFE Chapter
Design SystemAction

Button

버튼은 사용자의 행동을 유도하는 가장 핵심적인 UI 요소입니다. 우선순위, 상태, 스타일에 따라 다양한 타입으로 제공되며, 일관된 사용자 경험을 위해 명확한 기준에 따라 설계되었습니다.

Variants

Impact
Top Tier

Impact 버튼의 핵심 상태를 한 화면에서 비교합니다. Inactive, Hover, Pressed, Disabled, Loading 순으로 정렬되어 있으며, 각 상태에서의 인터랙션과 시각 효과(그라데이션, 그림자, 활성화 피드백)를 확인할 수 있습니다.

Inactive

Hover

Pressed

Disabled

Loading

<Button variant="contained" color="impact" size="large">
  제출하기
</Button>
<Button variant="contained" color="impact" size="large" disabled>
  제출하기
</Button>
<Button variant="contained" color="impact" size="large" loading>
  제출하기
</Button>

Primary
1순위 위계

페이지나 모달에서 가장 중요한 사용자 액션을 유도하는 기본 버튼입니다. 주목성이 높고 텍스트나 아이콘과 함께 사용합니다. 한 화면에서 중복 사용은 지양하며 1개 사용을 권장합니다.

Inactive

Hover

Pressed

Disabled

Loading

<Button variant="contained" color="primary" size="large">
  제출하기
</Button>
<Button variant="contained" color="primary" size="large" disabled>
  제출하기
</Button>
<Button variant="contained" color="primary" size="large" loading>
  제출하기
</Button>

Strong
2순위 위계

사용자 일반적인 행동을 유도하는 기본 버튼입니다. 주목도는 낮지만, 텍스트나 아이콘 레이블을 포함할 수 있습니다. 기존 Secondary Green은 활성 상태로 사용됩니다.

Inactive

Hover

Pressed

Disabled

Loading

<Button variant="outlined" strong color="primary" size="large">
  변경하기
</Button>

Outline
3순위 위계

사용자의 2차 액션을 유도하는 보조용 버튼입니다. 기본 버튼보다 주목도가 낮고, 텍스트나 아이콘 레이블을 포함할 수 있습니다. 사용자의 1차 액션에 따라 노출되기도 합니다.

Inactive

Hover

Pressed

Disabled

Loading

<Button variant="outlined" color="primary" size="large">
  저장하기
</Button>

Text
4순위 위계

텍스트 버튼은 특정 이벤트를 발생시키는 용도로 사용됩니다. 텍스트 앞뒤에 아이콘을 조합할 수 있으며, Underline 사용 시 아이콘에는 적용되지 않습니다.

Inactive

Hover

Pressed

Disabled

Loading

<Button variant="text" color="primary" size="large">
  저장하기
</Button>

Selected
Positive Status

Primary와 동등하거나 더 높은 위계를 갖는 긍정형 CTA 버튼입니다. 조건 완료, 스위치 활성화 등 특정 상태에서 사용되며 텍스트나 아이콘과 함께 조합할 수 있습니다. Primary가 이미 존재할 경우 차별화된 CTA가 필요할 때 활용됩니다.

Inactive

Hover

Pressed

Disabled

Loading

<Button variant="contained" color="primary" selected size="large">
  제출하기
</Button>

Danger
Negative Status

복구 불가능한 작업이나 중대한 변화를 유도할 때, 강력한 경고의 의미로 사용되는 버튼입니다. 파괴적인 결과가 없는 경우에는 사용을 지양합니다.

Inactive

Hover

Pressed

Disabled

Loading

<Button variant="contained" color="error" size="large">
  제출하기
</Button>

Sizes

버튼은 사용 맥락에 따라 네 가지 사이즈로 제공됩니다. 텍스트 가독성, 터치 영역, UI 밀도 등을 고려하여 선택하며,각 사이즈는 버튼 타입 및 디바이스 환경에 맞춰 유연하게 적용됩니다.

<Button size="xLarge">Extra Large</Button>
<Button size="large">Large</Button>
<Button size="medium">Medium</Button>
<Button size="small">Small</Button>
<Button size="xSmall">Extra Small</Button>
Size NameUse Case
xLarge페이지 내 단일 핵심 CTA 또는 강한 주목이 필요한 액션에 사용. 예: 가입/결제, 전체 레이아웃 내 Hero CTA
large폼 제출, 테이블 상단 주요 필터, 모달 내 대표 액션 등 중요하지만 X‑Large까지는 필요 없는 경우
medium기본 버튼 사이즈로 대부분의 일반 액션에 사용. 목록 내 액션 버튼, 설정 등 흐름을 끊지 않는 작업에 적합
small테이블 셀, 카드 내부, 필터/정렬/토글 등 보조 액션 또는 공간 제약이 있는 UI에서 사용
xSmall공간 제약이 있거나 보조 액션에 사용. 밀도 높은 UI에서 사용하며, 여전히 터치 가능한 최소 크기 유지

With Icons

버튼은 텍스트 외에도 아이콘을 함께 조합해 시각적 이해도를 높일 수 있습니다. 기능적 목적이나 UI 밀도에 따라 아이콘의 위치를 아래와 같이 선택할 수 있습니다.

<Button >텍스트만</Button>
<Button variant="outlined" startIcon={<ChevronLeft />}>다운로드</Button>
<Button variant="outlined" endIcon={<ChevronRight />}>계속하기</Button>
<Button variant="outlined" startIcon={<User />} endIcon={<CaretDown />}>저장</Button>
LabelDescription
Text Only텍스트만 포함된 기본 형태의 버튼
Start Icon아이콘이 텍스트 왼쪽에 위치 (예: 다운로드, 화살표 등 직관적 유도)
End Icon아이콘이 텍스트 오른쪽에 위치 (예: 더보기, 외부 링크 등 후행 동작 표현)
Both Icons아이콘이 텍스트의 양쪽에 모두 위치 (예: 복잡한 기능 또는 구분이 필요한 경우)

Loading State

<Button loading>Loading</Button>
<Button variant="outlined" loading>Please wait</Button>
<Button variant="contained" color="secondary" loading disabled>Processing</Button>

Button Group

Single

단일 버튼만 필요한 상황에서 사용됩니다. 사용자의 명확한 단일 액션을 유도할 때 적합합니다.

<Button variant="contained">확인</Button>

Twin

두 가지 상반되거나 보완적인 선택지를 제공할 때 사용됩니다. 사용자의 명확한 선택을 유도하는 상황에 적합합니다.

<HStack gap={8}>
  <Button variant="outlined">Button</Button>
  <Button variant="contained">Button</Button>
</HStack>
<VStack gap={8}>
  <Button variant="outlined">Button</Button>
  <Button variant="contained">Button</Button>
</VStack>

With Ref

ref를 사용하여 버튼에 직접 접근할 수 있습니다.

import { useRef } from 'react';

function ButtonWithRef() {
  const ref = useRef<HTMLButtonElement>(null);
  
  const handleClick = () => {
    console.log(ref.current);
  };
  
  return (
    <Button ref={ref} onClick={handleClick}>
      Click me
    </Button>
  );
}

Props

PropTypeDefault
variant?
"text" | "outlined" | "contained"
"text"
color?
"impact" | "primary" | "secondary" | "error" | "inherit"
"primary"
size?
"xLarge" | "large" | "medium" | "small" | "xSmall"
"medium"
disabled?
boolean
false
strong?
boolean
false
selected?
boolean
false
loading?
boolean
false
startIcon?
React.ReactNode
undefined
endIcon?
React.ReactNode
undefined
fullWidth?
boolean
false
asChild?
boolean
false
Edit on GitHub

Last updated on