컴포넌트/버튼

ToggleButton (토글버튼)

VanillaFront 2026. 9. 9. 16:47

Va.ToggleButton — 눌린 상태를 유지하는 토글 버튼

일반 Va.Button이 매번 눌렀다 놓아지는 순간 액션이라면, Va.ToggleButton은 눌린/안 눌린 상태(pressed)를 유지하는 이중 상태 버튼입니다. 볼드/이탤릭 같은 툴바 토글, 필터 on/off, 사이드바 표시 토글 같은 곳에 씁니다.

  • 클래스: Va.ToggleButton  va_component.js:12733
  • short name: toggleButton
  • 상속: Va.Component (Button 상속 아님, 별도 구현)
  • 베이스 CSS: va-button (Button과 스타일 계보 공유)


1. 기본 사용

{
    tagName: 'toggleButton',
    text: 'Bold',
    icon: 'ico_bold',
    pressed: false,           // 초기 상태
    onClick: 'onToggleBold'   // 클릭 시 pressed가 자동으로 반전됨
}

클릭할 때마다 내부에서 this.pressed = !this.pressed가 실행되고, update()가 CSS 클래스 pressed를 붙였다 뗐다 합니다 (va_component.js:12781-12789).


2. Va.Button과의 차이

항목Va.ButtonVa.ToggleButton

클릭 시 상태 순간 액션만 (actived/pressed는 있지만 자동 반전 안 됨) pressed 자동 토글
pressed 시각 스타일 pressed 클래스 (수동 제어) pressed 클래스 자동 부여
pressedIcon 지원 ✓ (눌림/해제에 따라 아이콘 스왑)
pressedBackgroundColor / pressedColor ✓ (하지만 selected 기준) ✓ (pressed 기준)
iconClick 이벤트
mousedown 이벤트
메서드 active/inactive, press/release press/unpress

한 줄 요약: Button은 "동작하는 버튼", ToggleButton은 "상태를 기억하는 버튼".


3. 주요 속성

상태

속성설명

pressed 핵심 상태 — 눌림/해제. 클릭 시 자동 반전
disabled 비활성화
focused 포커스 상태 (자동)

눌림 상태 시각 표현

속성설명

pressedIcon 눌림 상태에서 표시할 아이콘 (예: ico_bookmark  ico_bookmark_fill)
pressedBackgroundColor 눌림 상태 배경색 (인라인 스타일로 적용)
pressedColor 눌림 상태 글자색

버튼 표현 (Button 공통 규약)

속성설명

text / innerHTML 라벨
icon, iconPosition, iconOnly, iconSize, iconRotate 아이콘
appearance, shape, size 시각 스타일
textAlign 텍스트 정렬
backgroundColor / color 기본 배경/글자색
badge 배지 부착

4. 아이콘 스왑 (pressedIcon)

가장 유용한 전용 기능입니다. 눌림 상태에 따라 아이콘이 자동 교체됩니다 (va_component.js:12872-12880):

{
    tagName: 'toggleButton',
    icon: 'ico_favorite',          // 해제 상태 아이콘 (빈 하트)
    pressedIcon: 'ico_favorite_fill', // 눌림 상태 아이콘 (채운 하트)
    iconOnly: true,
    onClick: 'onToggleFavorite'
}

즐겨찾기 · 북마크 · 알림 켜기/끄기 · 좋아요 같은 UI에 정석 패턴입니다.


5. 이벤트

이벤트발생 시점

click 클릭 시 (내부 상태 토글 이후 dispatch)
focus / blur 포커스 진입/이탈
contextmenu 우클릭

중요: click 콜백이 호출되는 시점에는 이미 this.pressed가 반전된 뒤입니다. 따라서:

onToggleBold(component, element, evt) {
    console.log(component.pressed);  // 사용자가 방금 "켰는지 껐는지" 확인
    if (component.pressed) {
        // 볼드 적용
    } else {
        // 볼드 해제
    }
}

6. 메서드

메서드설명

setText(text) / setInnerHTML(html) 라벨 변경
setIcon(icon) 아이콘 변경
setAppearance(v) / setShape(v) / setSize(v) 시각 속성 변경
setDisabled(bool) 비활성화
press() 눌림 상태로 강제 전환
unpress() 해제 상태로 강제 전환
focus() / blur() 포커스 제어

press/unpress는 사용자 클릭 없이 프로그램적으로 상태를 바꿀 때 씁니다 — 예: 폼 초기값을 서버에서 받아 채울 때, 다른 UI 조작 결과로 이 버튼 상태를 동기화할 때.


7. 내부 구조

<button elname="element" tabindex="0" class="va-button [pressed] [focused] [disabled]">
  <span elname="inner" class="button-inner">
    <span elname="icon" class="icon ico_xxx [left|right|top|bottom]">…</span>  ← icon 지정 시
    <span elname="text" class="text">라벨</span>
    <span cpname="badge">…</span>                                              ← badge 지정 시
  </span>
</button>

일반 Button과 거의 동일한 DOM 구조. 차이는 pressed 클래스의 존재와 자동 토글 로직뿐입니다. CSS에서 .va-button.pressed 스타일을 통해 시각 표현이 결정됩니다.


8. 언제 쓰나

ToggleButton이 맞을 때

  • on/off 상태를 시각적으로 유지해야 하는 UI
    • 툴바 서식 버튼 (볼드/이탤릭/밑줄)
    • 필터 활성화 (카테고리 다중 선택)
    • 사이드바/패널 표시 토글
    • 즐겨찾기/북마크/좋아요
    • 알림 켜기/끄기
  • 아이콘 자체가 "켜짐/꺼짐"을 나타낼 때 (pressedIcon으로 아이콘 스왑)

다른 걸 쓸 때

  • 순간 액션 (저장/삭제/제출) → Va.Button
  • 여러 개 중 하나만 선택 → Va.RadioGroup / Va.SegmentedControl
  • 서식 툴바처럼 여러 토글을 한 그룹으로 → Va.ButtonGroup 안에 ToggleButton 여러 개
  • 실행/취소 짝을 이루는 상태 → Va.Switch (스위치 UI가 더 자연스러움)

9. 알아두면 좋을 주의사항

  1. 자동 토글이 항상 발생  onClick 콜백을 등록해도 pressed 반전은 무조건 먼저 일어납니다. 조건부로 토글하려면 콜백에서 다시 press()/unpress()로 되돌려야 합니다.
  2. pressed와 selected/actived는 별개 — 코드상에 selected = false가 초기화되어 있지만, ToggleButton의 시각 상태는 오직 pressed만이 결정합니다.
  3. pressedBackgroundColor는 pressed 상태에서만 적용 — Button과 달리 selected 기준이 아님. 인라인 스타일이라 CSS 클래스보다 우선순위 높음.
  4. iconClick 이벤트 없음 — 아이콘만 별도로 클릭 처리하고 싶다면 Va.Button을 써야 합니다.
  5. 그룹 토글은 컨테이너 로직 필요 — 라디오처럼 "하나만 눌림" 동작이 필요하면 부모에서 다른 ToggleButton들을 unpress()해줘야 합니다.

10. 그룹 토글 패턴 예시

라디오처럼 하나만 눌리게 하려면:

onToggle(component) {
    if (!component.pressed) return;  // 방금 해제된 거면 무시
    // 형제 ToggleButton 모두 해제
    ['btn1', 'btn2', 'btn3'].forEach(ref => {
        if (this.getRef(ref) !== component) {
            this.getRef(ref).unpress();
        }
    });
}

VanillaFront에는 이런 그룹 로직이 내장된 별도 컴포넌트로 Va.SegmentedControl 계열이 있으니, 라디오형 토글이 많다면 그쪽을 먼저 검토하는 게 낫습니다.

'컴포넌트 > 버튼' 카테고리의 다른 글

FileButton (파일버튼)  (0) 2026.09.09
TabButton (탭버튼)  (0) 2026.09.09
SplitButton (분할버튼)  (0) 2026.09.09
ResponsiveMenuButton (응답형메뉴버튼)  (0) 2026.09.09
ExpandButton (확장버튼)  (0) 2026.09.09