Va.Button — 표준 버튼 컴포넌트
VanillaFront의 가장 기본이 되는 인터랙션 컴포넌트로, 텍스트·아이콘·배지·상태를 하나의 API로 다루는 다목적 버튼입니다. <button> 엘리먼트를 감싸 표준 DOM 시맨틱을 유지하면서, 프레임워크의 컴포넌트 시스템에 편입되어 있습니다.
- 클래스: Va.Button — va_component.js:11965
- short name: button (config의 tagName:'button'으로 사용)
- 상속: Va.Component

1. 기본 사용
{
tagName: 'button',
text: '저장',
icon: 'ico_save',
appearance: 'primary',
onClick: 'onSave'
}
tagName:'button'은 프레임워크에 등록된 짧은 이름이고(va_component.js:12203), 이벤트 핸들러명은 뷰의 메서드명 문자열로 지정합니다.
2. 주요 속성
속성타입설명
| text | string | 버튼 라벨 (텍스트만) |
| innerHTML | string | HTML 포함 라벨. XSS 방지용 _sanitize 적용 |
| icon | string | 아이콘 클래스명 (예: ico_add, ico_emoji_fill) |
| iconPosition | 'left'|'right'|'top'|'bottom' | 아이콘 위치. top/bottom이면 자동으로 column 레이아웃 |
| iconOnly | boolean | 텍스트 숨기고 아이콘만 표시 |
| iconSize | string | 아이콘 크기 (버튼 size와 별도로 조절 가능) |
| iconRotate | number | 아이콘 회전 각도(°) |
| textAlign | 'left'|'center'|'right' | 텍스트 정렬 |
| appearance | 아래 11종 | 시각 스타일 |
| shape | 'rounded1'|'circular'|'square' | 모서리 형태 |
| size | 'xsmall'~'xlarge' | 크기 5단계 (기본 medium) |
| backgroundColor / color | string | 배경/글자색 직접 지정 |
| pressedBackgroundColor / pressedColor | string | 눌린 상태 색상 |
| actived | boolean | 활성 상태 (선택된 것처럼 강조) |
| disabled | boolean | 비활성화 |
| badge | object | 배지 옵션 {size, innerHTML, color} — Va.Badge 인스턴스가 자동 부착 |
| stopPropagation | boolean (기본 true) | 이벤트 버블링 차단 |
| iconStopPropagation | boolean | 아이콘 클릭 시 별도 버블링 제어 |
| preventDefault | boolean | contextmenu 기본 동작 차단 |
appearance 11종 (DemoButtons에서 실제 사용)
default · primary · secondary · tertiary · accent · inverted · subtle · outline · transparent · text · underline
text, underline 같은 "버튼처럼 안 생긴" 버튼도 같은 컴포넌트로 표현합니다.
3. 이벤트
events 배열에 등록된 커스텀 이벤트 (va_component.js:11976-11977):
이벤트발생 시점
| click | 클릭 시 |
| iconClick | 아이콘 영역만 클릭됐을 때 (텍스트 영역 클릭과 구분됨) |
| contextmenu | 우클릭 |
| focus / blur | 포커스 진입/이탈 |
| mousedown | 마우스 다운 |
iconClick이 별도로 있는 게 특징입니다. 예를 들어 "닫기 X 아이콘 달린 태그 버튼"에서, 태그 본체 클릭과 X 아이콘 클릭을 다르게 처리할 수 있습니다.
{
tagName: 'button',
text: '항목',
icon: 'ico_close',
iconPosition: 'right',
onClick: 'onSelect', // 본체 클릭
onIconClick: 'onRemove' // X만 클릭
}
4. 메서드
메서드설명
| setText(text) | 텍스트 변경 |
| setInnerHTML(html) | HTML 라벨 변경 |
| getText() | 현재 라벨 반환 (text 우선, 없으면 innerHTML) |
| setAppearance(v) / setShape(v) / setSize(v) | 시각 속성 변경 |
| setDisabled(bool) | 비활성화 토글 |
| focus() / blur() | 포커스 제어 |
| active() / inactive() | actived 토글 (setActive() 별칭 존재) |
| press() / release() | pressed 상태 토글 |
DemoButtons에서 실제 사용례를 확인할 수 있습니다 → DemoButtons.js:8-31
5. 내부 구조
Shadow DOM에 렌더되는 실제 구조:
<button elname="element" tabindex="0" class="va-button">
<span elname="inner" class="button-inner">
<span elname="badge" class="va-badge">…</span> ← 항상 존재, 옵션 없으면 숨김
<span elname="icon" class="icon ico_xxx">…</span> ← icon 지정 시
<span elname="text" class="text">라벨</span>
</span>
</button>
- inner span을 한 번 감싸는 이유: badge 위치 계산(absolute) 기준점 확보 + icon/text 정렬 제어
- badge는 Va.Badge 인스턴스로 항상 만들어 두고 옵션 없으면 display:none 처리 (va_component.js:12000-12008)
- ResizeObserver로 버튼 크기 변경 시 badge 위치를 자동 재계산 (va_component.js:12009-12015)
6. update()의 3단계 최적화
버튼은 setter 호출 시마다 update()가 실행되는데, 비용에 따라 3단계로 나눠져 있습니다 (va_component.js:12052-12160):
- 클래스 빌딩 — 항상 실행, 저비용 (disabled, focused, pressed 등 CSS 클래스만 조작)
- 변경 가드 — 비용 높은 DOM 조작은 _prevXxx 캐시와 비교해 값이 바뀌었을 때만 실행 (텍스트 세팅, icon 재배치 등)
- 인라인 스타일 — 항상 실행, 저비용 (backgroundColor, color 등)
리스트 안에 버튼이 수백 개 있을 때 리렌더 비용을 낮추기 위한 패턴입니다.
7. Badge 결합 예시
버튼과 배지를 별도 컴포넌트로 조합하지 않고, 한 옵션으로 처리합니다.
{
tagName: 'button',
text: '알림',
icon: 'ico_bell',
badge: {
size: 'medium',
innerHTML: '999',
color: 'primary'
}
}
8. 확장 계열
Va.Button을 상속하거나 유사 컨벤션을 따르는 버튼 컴포넌트가 12개 더 있습니다:
ToggleButton · CompoundButton · MenuButton · SplitButton · ExpandButton · ResponsiveButton · NavMenuButton · ResponsiveMenuButton · TabButton · TrapezoidButton · SimpleTabButton · AccordionButton
동일한 속성 규약(text, icon, iconPosition, appearance 등)이 그대로 이어져, 한 번 익히면 확장 계열도 바로 쓸 수 있습니다.
'컴포넌트 > 버튼' 카테고리의 다른 글
| SplitButton (분할버튼) (0) | 2026.09.09 |
|---|---|
| ResponsiveMenuButton (응답형메뉴버튼) (0) | 2026.09.09 |
| ExpandButton (확장버튼) (0) | 2026.09.09 |
| MenuButton (메뉴버튼) (0) | 2026.09.09 |
| CompoundButton (복합버튼) (0) | 2026.09.09 |