Collapsible | CoUI

Collapsible

클릭으로 내용을 접거나 펼칠 수 있는 토글 가능한 영역 컴포넌트

Collapsible#

트리거를 클릭하여 내용을 접거나 펼칠 수 있는 토글 영역 컴포넌트입니다.

Live Preview#

Web
Toggle Content
This is the collapsible content that can be expanded or collapsed.
Flutter
Loading Flutter...
class CollapsibleDefaultExample extends StatelessComponent {
  const CollapsibleDefaultExample({super.key});

  @override
  Component build(BuildContext context) {
    return CoCollapsible(
      trigger: Component.text('Toggle Content'),
      content: Component.text(
        'This is the collapsible content that can be expanded or collapsed.',
      ),
    );
  }
}
class CollapsibleDefaultExample extends StatelessWidget {
  const CollapsibleDefaultExample({super.key});

  @override
  Widget build(BuildContext context) {
    return const CoCollapsible(
      trigger: Text('Toggle Content'),
      content: Text(
        'This is the collapsible content that can be expanded or collapsed.',
      ),
    );
  }
}

사용 시기 (When to Use)#

이 컴포넌트를 사용하세요:

  • 보조 정보나 상세 내용을 기본적으로 숨겨두고 필요 시 펼쳐 보여줄 때
  • 단일 섹션을 접기/펼치기로 제어할 때 (여러 섹션 관리는 Accordion 사용)
  • 필터 패널, 추가 옵션, 긴 약관 내용 등을 토글로 보여줄 때

대신 다른 컴포넌트를 사용하세요:

  • Accordion: 여러 개의 접기/펼치기 패널을 하나의 그룹으로 관리할 때
  • Tree: 계층 구조의 데이터를 트리 형태로 표시할 때

기본 사용법 (Basic Usage)#

// 기본 접기/펼치기
CoCollapsible(
  trigger: Text('상세 정보'),
  content: Text('여기에 상세 내용이 표시됩니다.'),
)

// 초기 펼침 상태
CoCollapsible(
  trigger: Text('약관 내용'),
  content: TermsContent(),
  expanded: true,
)

// 외부 제어
CoCollapsible(
  trigger: Text('필터 옵션'),
  content: FilterPanel(),
  expanded: isFilterExpanded,
  onExpandedChanged: (value) => setState(() => isFilterExpanded = value),
)

Props / Parameters#

속성타입기본값설명
trigger Widget / Component 필수 클릭 가능한 헤더
content Widget / Component 필수 펼쳤을 때 표시할 내용
expandedboolfalse초기 펼침 상태
onExpandedChanged void Function(bool)? null 상태 변경 콜백

변형 (Variants)#

기본 (닫힘 상태로 시작)#

CoCollapsible(
  trigger: Text('추가 옵션'),
  content: AdditionalOptions(),
)

기본 펼침#

CoCollapsible(
  trigger: Text('기본 정보'),
  content: UserInfoPanel(),
  expanded: true,
)

동작 스펙 (Behavior)#

인터랙션#

  • 클릭/탭: 트리거 영역 클릭 시 펼침/접힘 토글, onExpandedChanged 호출
  • 호버: 트리거 텍스트 밑줄 표시
  • 포커스: 트리거에 포커스 시 Enter/Space로 토글 가능

상태 전환#

  • collapsedexpanded: 트리거 클릭 시 내용 영역 펼침
  • expandedcollapsed: 트리거 재클릭 시 내용 영역 접음
  • 화살표 아이콘이 펼침/닫힘 상태에 따라 180도 회전

애니메이션#

  • 높이 전환: 200ms ease-in-out (CoreDuration.normal)
  • 화살표 아이콘 회전: 200ms ease-in-out

사용 가이드라인 (Usage Guidelines)#

✅ Do#

보조적인 내용을 기본 숨김 상태로 시작

CoCollapsible(
  trigger: Text('고급 설정'),
  content: AdvancedSettingsPanel(),
  // expanded 기본값 false
)

대부분의 사용자에게 불필요한 정보를 숨겨 페이지를 깔끔하게 유지한다.


❌ Don't#

필수 정보를 Collapsible 안에 숨기지 않기

// ❌ 중요한 오류 메시지를 접힌 상태로 숨김
CoCollapsible(
  trigger: Text('결제 오류'),
  content: Text('카드 정보가 유효하지 않습니다.'),
)

사용자가 중요한 정보를 놓칠 수 있으며, Alert나 Dialog로 즉시 표시해야 한다.

✅ Do#

여러 독립 섹션은 각각 별도 Collapsible로 관리

Column(
  children: [
    CoCollapsible(
      trigger: Text('기본 정보'),
      content: BasicInfoForm(),
      expanded: isBasicExpanded,
      onExpandedChanged: (v) => setState(() => isBasicExpanded = v),
    ),
    CoCollapsible(
      trigger: Text('추가 정보'),
      content: ExtraInfoForm(),
      expanded: isExtraExpanded,
      onExpandedChanged: (v) => setState(() => isExtraExpanded = v),
    ),
  ],
)

섹션들이 서로 독립적으로 열리고 닫혀 사용자가 원하는 섹션만 볼 수 있다.


❌ Don't#

너무 짧은 내용을 Collapsible로 감싸지 않기

// ❌ 한 줄 텍스트를 굳이 Collapsible로
CoCollapsible(
  trigger: Text('작성자'),
  content: Text('홍길동'),
)

짧은 내용은 바로 표시하는 것이 클릭 비용을 줄여 UX를 개선한다.

접근성 (Accessibility)#

키보드 인터랙션#

동작
Enter / Space트리거 토글 (펼침/접힘)
Tab다음 포커스 가능 요소로 이동

스크린 리더#

  • Flutter: FocusableActionDetector로 키보드/포커스 처리
  • Web: role="button", tabindex="0", aria-expanded 자동 적용

터치 타겟#

  • 트리거 영역 최소 높이: 48dp (CoreSpace.space16 × 2 + 텍스트 높이)

크로스 플랫폼 차이점 (Platform Differences)#

항목FlutterWeb
클래스명CoCollapsibleCoCollapsible
애니메이션 SizeTransition + AnimationController CSS grid-template-rows transition
ARIA FocusableActionDetector role="button", aria-expanded
화살표 아이콘 AnimatedBuilder + Transform.rotate CSS transform: rotate()
  • Accordion: 여러 Collapsible 패널을 그룹으로 관리할 때 사용
  • Tree: 계층적 데이터를 중첩 접기/펼치기로 표시할 때 사용