심화 가이드
접근성 지원

리스트박스

개요

사용자가 선택할 수 있는 옵션 목록을 표시하는 디렉티브입니다. 키보드 탐색, 단일/다중 선택, 스크린 리더를 지원합니다.

사용법

리스트박스는 선택, 다중 선택, 자동 완성 패턴에서 사용하는 기본 디렉티브입니다. 대부분의 드롭다운 요구사항에는 이 패턴의 가이드를 참고해서 구현하세요.

다음과 같은 경우에는 리스트박스를 직접 사용하는 것을 고려하세요.

  • 커스텀 선택 컴포넌트 개발: 특정 동작이 필요한 전용 인터페이스를 만들 때
  • 항상 표시되는 선택 목록: 선택할 항목을 드롭다운이 아닌 페이지에 직접 표시할 때
  • 커스텀 통합 패턴: 고유한 팝업이나 레이아웃 요구사항에 맞춰 통합할 때

다음과 같은 경우에는 리스트박스를 피하세요.

  • 탐색 메뉴가 필요한 경우: 작업과 명령에는 메뉴 디렉티브를 사용하세요.

주요 기능

Angular의 리스트박스는 다음과 같이 접근성을 갖춘 목록 구현을 제공합니다.

  • 키보드 탐색: 방향키로 옵션을 탐색하고 Enter나 Space로 선택합니다.
  • 스크린 리더 지원: role="listbox"를 비롯한 ARIA 어트리뷰트를 기본 제공합니다.
  • 단일/다중 선택: multi 어트리뷰트로 선택 모드를 제어합니다.
  • 수평/수직 배치: orientation 어트리뷰트로 배치 방향을 지정합니다.
  • 문자 입력 검색: 문자를 입력하면 일치하는 옵션으로 이동합니다.
  • 시그널 기반 반응성: Angular 시그널로 상태를 반응형으로 관리합니다.

예제

기본 리스트박스

애플리케이션에서는 선택 목록을 드롭다운 안에 숨기지 않고 페이지에 직접 표시해야 할 때가 있습니다. 리스트박스를 독립적으로 사용하면 이러한 목록 인터페이스에 키보드 탐색과 선택 기능을 제공할 수 있습니다.

value 모델 시그널은 선택된 항목에 대한 양방향 바인딩을 제공합니다. selectionMode="explicit"이면 사용자가 Space나 Enter를 눌러 옵션을 선택합니다. 리스트박스, 콤보박스, 오버레이 위치 지정을 결합한 드롭다운 패턴은 선택 패턴을 참고하세요.

수평 리스트박스

툴바와 비슷한 인터페이스나 탭 형태의 선택 UI처럼 목록을 수평으로 배치하는 것이 더 적합한 경우도 있습니다. orientation 어트리뷰트는 배치 방향과 키보드 탐색 방향을 함께 변경합니다.

orientation="horizontal"이면 위/아래 방향키 대신 왼쪽/오른쪽 방향키로 옵션 사이를 이동합니다. 리스트박스는 탐색 방향을 반대로 전환해서 오른쪽에서 왼쪽으로 쓰는 언어(RTL)를 자동으로 처리합니다.

선택 모드

리스트박스는 항목이 선택되는 시점을 제어하는 두 가지 선택 모드를 지원합니다.

'follow' 모드는 포커스가 있는 항목을 자동으로 선택해서 선택이 자주 바뀌는 경우 더 빠르게 조작할 수 있습니다. 'explicit' 모드는 Space나 Enter로 선택을 확정해야 하므로 탐색 도중 실수로 선택이 바뀌는 일을 방지합니다. 드롭다운 패턴의 단일 선택에는 대체로 'follow' 모드를 사용합니다.

명시적 선택

포커스에 따른 선택

모드 설명
'follow' 포커스가 있는 항목을 자동으로 선택해서 선택이 자주 바뀌는 경우 더 빠르게 조작할 수 있습니다.
'explicit' Space나 Enter로 선택을 확정해야 하므로 탐색 도중 실수로 선택이 바뀌는 일을 방지합니다.

TIP: 드롭다운 패턴의 단일 선택에는 대체로 'follow' 모드를 사용합니다.

테스트

Angular Aria는 리스트박스 컴포넌트를 테스트할 수 있는 컴포넌트 하네스를 제공합니다. 컴포넌트 테스트에서 하네스를 사용하는 예제는 다음과 같습니다.

import {ComponentFixture, TestBed} from '@angular/core/testing';
import {HarnessLoader} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {ListboxHarness} from '@angular/aria/listbox/testing';
import {MyListboxComponent} from './my-listbox'; // 테스트할 컴포넌트

describe('MyListboxComponent', () => {
  let fixture: ComponentFixture<MyListboxComponent>;
  let loader: HarnessLoader;

  beforeEach(async () => {
    TestBed.configureTestingModule({
      imports: [MyListboxComponent],
    });

    fixture = TestBed.createComponent(MyListboxComponent);
    await fixture.whenStable();
    loader = TestbedHarnessEnvironment.loader(fixture);
  });

  it('should allow selecting options', async () => {
    const listbox = await loader.getHarness(ListboxHarness);

    // 리스트박스 프로퍼티를 확인합니다.
    expect(await listbox.isMulti()).toBe(true);

    // 모든 옵션을 가져옵니다.
    const options = await listbox.getOptions();
    expect(options.length).toBe(2);

    // 옵션을 클릭합니다.
    await options[0].click();

    // 옵션이 선택되었는지 확인합니다.
    expect(await options[0].isSelected()).toBe(true);

    // 텍스트로 옵션을 필터링합니다.
    const bananaOption = await listbox.getOptions({text: 'Banana'});
    expect(bananaOption.length).toBe(1);
  });
});

API 레퍼런스

자세한 API 문서는 다음 API 레퍼런스를 참고하세요.

관련 패턴

리스트박스는 다음 문서에서 설명하는 드롭다운 패턴에 사용됩니다:

  • 단일 선택 - 읽기 전용 콤보박스와 리스트박스를 사용하는 단일 선택 드롭다운 패턴
  • 다중 선택 - 읽기 전용 콤보박스와 multi가 활성화된 리스트박스를 사용하는 다중 선택 드롭다운 패턴
  • 자동 완성 - 콤보박스와 리스트박스를 사용하는 필터링 가능한 드롭다운 패턴

트리거, 팝업, 오버레이 위치 지정이 포함된 완전한 드롭다운 패턴을 구현하려면 리스트박스만 사용하기보다 해당 패턴 가이드를 참고하세요.