Button

Button

클릭·키보드 입력으로 사용자 액션이나 링크 이동을 실행하는 React 컴포넌트입니다. 스킨·색상·크기· 아이콘·상태를 props와 유틸리티 클래스로 조합합니다.

기본 유형

btn_filled · btn_outline · btn_ghost · btn_text 네 가지 기본 스킨을 제공합니다.

셀렉트 박스형

btn_select 클래스로 셀렉트 박스처럼 표시합니다. btn_select-text는 배경·테두리 없는 텍스트 형태입니다. 드롭다운·팝오버 트리거로 사용하며 aria-haspopuparia-expanded를 지정합니다.

텍스트 버튼

btn_text 계열 스킨으로 배경·테두리 없이 표시합니다. primary, muted, danger 등 색상 변형과 아이콘·크기·상태 조합을 지원합니다.

아이콘 + 텍스트

아이콘과 함께 사용하는 텍스트도 btn_label 클래스로 감쌉니다.

아이콘 + 텍스트 (세로)

btn_vertical 클래스로 아이콘을 위·텍스트를 아래에 배치합니다. 하단 탭·퀵 액션 등에 사용합니다.

아이콘 + 텍스트 (세로) · 균등 배분

btn_verticalbtn_row-equal을 함께 사용하면 부모 100% 너비에서 버튼을 균등 분배합니다. 하단 탭 바 등에 사용합니다.

텍스트 + 아이콘

텍스트를 앞에 두고 아이콘을 뒤에 배치합니다. 텍스트는 btn_label로 감쌉니다.

아이콘 버튼

텍스트 없이 아이콘만 표시합니다. btn_icon-only와 함께 사용하며, 접근성을 위해 aria-label을 반드시 지정합니다.

아이콘 버튼 크기

btn_sm, medium, btn_lg 세 가지 크기를 지원합니다.

색상 변형

상황에 맞는 색상 변형을 사용합니다.

크기

small, medium, large 세 가지 크기를 지원합니다.

라운드

btn_round 클래스로 pill(캡슐) 형태의 둥근 모서리를 적용합니다. btn_icon-only와 조합하면 원형 아이콘 버튼이 됩니다.

너비

부모 영역 기준으로 너비를 조절합니다. btn_block은 가로 전체, btn_row-equal은 부모 100% 너비에서 버튼을 균등 분배, btn_grow는 비율 분배, btn_fit은 콘텐츠 너비를 유지합니다.

상태

disabled, is-disabled, is-loading 상태를 표현합니다. 비활성은 스킨별로, 로딩은 텍스트·아이콘 버튼 모두 적용할 수 있습니다.

버튼 그룹

가로·세로 방향으로 버튼을 묶습니다. btn_group-fit은 콘텐츠 크기 맞춤, btn_group-block은 전체 너비 균등 분배, btn_group-align-start·center·end로 그룹 정렬을 지정합니다.

최신 버전 v2.0 · 릴리스 노트

루트 태그

tag prop으로 button · a · div를 선택합니다. div와 href 없는 a에는 키보드 접근을 위해 role과 tabIndex={0}을 자동 적용합니다.

a + href
div → role=button
a, role=link

API · Props

Prop타입기본값설명
variant'filled' | 'outline' | 'ghost' | 'text' | 'select'filled버튼 스킨. select는 셀렉트 박스형 트리거
color'primary' | 'default' | 'success' | 'warning' | 'danger' | 'muted'primary색상 변형. filled는 default·primary·success·warning·danger, text는 primary·muted·success·warning·danger 지원
size'sm' | 'md' | 'lg'md버튼 크기
labelReactNode버튼 텍스트. children으로 대체 가능
roundbooleanfalsepill(캡슐) 형태 모서리
verticalbooleanfalse아이콘 위 · 텍스트 아래 세로 배치
iconOnlybooleanfalse아이콘만 표시. ariaLabel 필수
blockbooleanfalse루트 버튼을 부모 너비 100%로 확장
growboolean | '2'falseflex 비율 분배. 2는 2배 너비
fitbooleanfalse콘텐츠 너비 유지
disabledbooleanfalsebutton은 HTML disabled, a·div는 aria-disabled와 상호작용 차단 적용
ariaDisabledbooleanfalseTab 순서에서 제외하고 is-disabled·aria-disabled·상호작용 차단 적용
loadingbooleanfalse스피너와 aria-busy를 표시하고 중복 상호작용 차단
openbooleanfalse셀렉트 트리거 열림 상태
errorbooleanfalse셀렉트 트리거 오류 상태
placeholderbooleanfalse셀렉트 미선택 placeholder 스타일
selectTextbooleanfalse배경·테두리 없는 셀렉트 텍스트 형태
selectCaretbooleanfalseselect 이외의 스킨에도 드롭다운 캐럿 표시
type'button' | 'submit' | 'reset'buttonbutton 요소 type 속성 (tag="button"일 때만)
tag'button' | 'a' | 'div'button루트 HTML 태그. div·href 없는 a는 role과 tabIndex={0} 자동 적용
hrefstringtag="a"일 때 href. 있으면 네이티브 링크, 없으면 role과 tabIndex 자동 적용
role'button' | 'link'tag="a"이고 href가 없을 때 의미 지정. 필요한 tabIndex는 자동 적용
tabIndexnumberReact tabIndex. div·href 없는 a는 기본 0, 비활성 -1
ariaLabelstring접근성 라벨 (iconOnly 시 필수)
haspopupboolean | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog'aria-haspopup (셀렉트·드롭다운 트리거)
expandedbooleanaria-expanded (셀렉트·팝오버 트리거)
invalidbooleanfalsearia-invalid (폼 오류)
ripplebooleantrue클릭 파장(ripple). true 시 data-ripple 활성 · false 비활성. 기본 활성

선언되지 않은 HTML 속성·이벤트(id,data-*, onClick 등)는tag로 지정한 루트 요소에 그대로 전달됩니다.

API · Children

Children / Prop설명
childrenlabel을 대체하는 ReactNode. iconOnly이고 iconBefore가 없으면 아이콘 콘텐츠로 사용
iconBefore텍스트 앞에 렌더링할 ReactNode 아이콘
iconAfter텍스트 뒤에 렌더링할 ReactNode 아이콘

클래스 · 속성

React 컴포넌트가 렌더하는 OOCSS 클래스입니다. HTML 마크업으로 직접 작성할 때 동일하게 조합합니다.

클래스설명
btn루트 구조 클래스
btn_filled배경 채움 스킨
btn_outline테두리 스킨
btn_ghost투명 배경 스킨
btn_text텍스트만 스킨
btn_select셀렉트 박스형 트리거
btn_select-text텍스트형 셀렉트 트리거
btn_sm · btn_lg크기 변형
btn_roundpill(캡슐) 모서리
btn_vertical아이콘 위 · 텍스트 아래
btn_icon-only아이콘만
btn_block · btn_grow · btn_fit너비 레이아웃
icon · btn_label · btn_spinner내부 파트
btn_row · btn_group · btn_stack버튼 묶음 컨테이너
is-disabled · is-loading · is-open · is-error상태 클래스
color_primary · color_danger …색상 유틸 (스킨과 조합)
data-ripple클릭 파장 활성. data-ripple="surface"는 절대 위치 보조 버튼용
data-ripple="false"해당 요소 ripple 비활성
data-no-ripple하위 전체 ripple 비활성

디자인 토큰

토큰기본값설명
--btn-padding-y · --btn-padding-x · --btn-font-size0.5rem · 1rem · var(--text-size-base)기본(md) 패딩·타이포
--btn-padding-y-sm · --btn-padding-x-sm · --btn-font-size-sm0.3rem · 0.75rem · var(--text-size-sm)sm 크기
--btn-padding-y-lg · --btn-padding-x-lg · --btn-font-size-lg0.65rem · 1.25rem · var(--text-size-lg)lg 크기
--btn-font-weight · --btn-font-weight-normal · --btn-line-height600 · 400 · 1.4타이포 두께·줄높이
--btn-border-width · --btn-gap1px · var(--space-sm)테두리·내부 간격
--btn-icon-size · --btn-icon-size-md · --btn-icon-size-lg · --btn-icon-size-xl1em · 1.125em · 1.25em · 1.375em아이콘 크기
--btn-icon-only-padding · --btn-icon-only-padding-sm · --btn-icon-only-padding-lg0.5rem · 0.35rem · 0.65rem아이콘만 버튼 패딩
--btn-vertical-min-width · --btn-vertical-min-width-sm · --btn-vertical-min-width-lg4.5rem · 3.75rem · 5.25rem세로 배치 최소 너비
--btn-vertical-padding-y · --btn-vertical-padding-x0.65rem · 0.75rem세로 배치 패딩(md)
--btn-vertical-padding-y-sm · --btn-vertical-padding-x-sm0.5rem · 0.6rem세로 배치 패딩(sm)
--btn-vertical-padding-y-lg · --btn-vertical-padding-x-lg0.85rem · 0.9rem세로 배치 패딩(lg)
--btn-vertical-label-size · --btn-vertical-label-size-sm · --btn-vertical-label-size-lgvar(--text-size-sm) · var(--text-size-xs) · var(--text-size-base)세로 배치 라벨 크기
--btn-vertical-label-weight · --btn-vertical-label-line-height500 · 1.25세로 배치 라벨 두께·줄높이
--btn-select-min-width · --btn-select-max-width10rem · 320px셀렉트 트리거 너비
--btn-select-padding-right · --btn-select-padding-right-sm · --btn-select-padding-right-lg0.65rem · 0.5rem · 0.85rem셀렉트 캐럿 여백
--btn-select-text-padding-x · --btn-select-text-padding-right0.5rem · 0.35rem텍스트형 셀렉트 패딩
--btn-select-text-padding-x-sm · --btn-select-text-padding-right-sm0.35rem · 0.25rem텍스트형 셀렉트 패딩(sm)
--btn-select-text-padding-x-lg · --btn-select-text-padding-right-lg0.65rem · 0.45rem텍스트형 셀렉트 패딩(lg)
--btn-spinner-size · --btn-spinner-border · --btn-spinner-duration1em · 2px · 0.6s로딩 스피너
--btn-stack-text-size · --btn-stack-text-line-heightvar(--text-size-sm) · 1.5스택 하단 안내 텍스트
--btn-group-overlap-1px그룹 버튼 테두리 겹침