메인 콘텐츠로 건너뛰기

접근성

@lh-ui/react는 패밀리의 다른 라이브러리와 동일한 접근성 계약을 공유합니다: 시맨틱 태그, ARIA 속성, 키보드 인터랙션이 모두 @lh-ui/share/core에 정의되어 있으며, 각 플랫폼 구현이 일치합니다. 이 라이브러리는 추가로 React 생태계의 일반적인 a11y 함정이 발생하지 않도록 보장합니다.

시맨틱과 ARIA​

  • **LhSwitch**는 시각적으로 위장한 checkbox가 아닌 <div role="switch" aria-checked>를 렌더링합니다
  • LhSelect 트리거는 role="combobox", 펼쳐진 패널은 role="listbox", 옵션은 role="option"이며 aria-activedescendant로 키보드 하이라이트를 동기화합니다
  • **LhDialog**는 role="dialog" aria-modal이고, 제목에 aria-label 폴백과 aria-labelledby 정확한 연결을 동시에 제공합니다
  • **LhTooltip**는 aria-describedby로 힌트를 트리거에 연결합니다
  • **LhTag**는 클릭 가능할 때 role="button"으로 승격되고 Enter / Space에 반응합니다
  • **LhFormItem**는 검증 실패 시 role="alert" 에러 힌트를 렌더링하고 aria-invalid를 설정합니다

키보드 인터랙션​

컴포넌트키
LhButton / LhTagEnter / Space로 클릭 트리거
LhSwitchEnter / Space로 전환
LhSelectArrowUp / ArrowDown 옵션 하이라이트, Enter 선택, Escape 닫기
LhDialogEscape 닫기(스택 최상단 오버레이만 반응)
LhTooltipEscape 닫기

오버레이가 여러 개 겹쳤을 때는 useLhOverlayStack가 열린 순서 스택을 유지하고, Escape는 최상단만 닫아 한 번의 키 입력에 모든 오버레이가 닫히는 것을 막습니다.

포커스 관리​

  • **LhDialog**는 열릴 때 useLhFocusTrap로 포커스를 dialog 내부에 제한하고(Tab / Shift+Tab이 외부로 나가지 않음), 닫은 뒤 포커스를 트리거로 되돌립니다
  • **LhFormItem**는 label 클릭 시 콘텐츠 영역의 첫 번째 포커스 가능 요소에 포커스를 맞춥니다(focusControl). 복합 컨트롤에서는 네이티브 label 래핑 동작이 신뢰할 수 없기 때문입니다

장식용 아이콘​

LhIcon은 기본적으로 decorative입니다: aria-hidden="true"를 출력해 스크린 리더에 보이지 않습니다. 의미가 필요하면 decorative={false} + ariaLabel을 전달하세요:

<LhIcon name="search" decorative={false} ariaLabel="검색" />

이때 <svg role="img" aria-label="검색">으로 렌더링됩니다.

StrictMode 안전성​

모든 컴포넌트는 React StrictMode에서 안전합니다: effect의 cleanup과 중복 마운트를 모두 멱등하게 처리했습니다(오버레이 스택 등록 / 해제, 스크롤 락 소유자 검증, focus trap 해제).

패밀리 일관성​

접근성 동작은 docs/设计语言基线.md에 등록되어 있으며, 두 혈통(web / 네이티브)의 통일 계약입니다. 각 플랫폼은 동일한 @lh-ui/share/core 로직으로 구현되어, aria 속성과 키 의미론이 일치합니다.