컴포넌트/버튼

Button (버튼)

VanillaFront 2026. 9. 9. 14:27

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):

  1. 클래스 빌딩 — 항상 실행, 저비용 (disabled, focused, pressed 등 CSS 클래스만 조작)
  2. 변경 가드 — 비용 높은 DOM 조작은 _prevXxx 캐시와 비교해 값이 바뀌었을 때만 실행 (텍스트 세팅, icon 재배치 등)
  3. 인라인 스타일 — 항상 실행, 저비용 (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