> ## Documentation Index
> Fetch the complete documentation index at: https://docs.viamoss.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 인터랙티브 요소 라벨링

> Moss가 아이콘 전용 버튼을 식별하고 사용자를 안내할 수 있도록 접근성 라벨을 추가하는 방법

# 인터랙티브 요소 라벨링

Moss는 페이지의 인터랙티브 요소를 접근성 이름(accessible name)으로 식별합니다. 버튼에 SVG 아이콘만 있고 텍스트가 없으면, Moss는 해당 버튼의 기능을 파악할 수 없으며 안내 지침에서 참조할 수 없습니다.

아이콘 전용 버튼에 `aria-label`을 추가하면 이 문제가 해결되며, 스크린 리더 사용자의 접근성도 함께 향상됩니다.

## 문제점

SVG 아이콘만 포함된 버튼에는 접근성 이름이 없습니다:

```html theme={null}
<!-- Moss가 이 버튼을 식별할 수 없습니다 -->
<button>
  <svg viewBox="0 0 24 24">
    <path d="M6 19c0 ..." />
  </svg>
</button>
```

Moss가 이러한 요소를 만나면 라벨이 없기 때문에 *"삭제 버튼을 클릭하세요"* 와 같은 명확한 안내를 생성할 수 없습니다.

## 해결 방법

버튼의 기능을 설명하는 `aria-label` 속성을 추가하세요:

```html theme={null}
<button aria-label="항목 삭제">
  <svg aria-hidden="true" viewBox="0 0 24 24">
    <path d="M6 19c0 ..." />
  </svg>
</button>
```

<Info>
  SVG에 `aria-hidden="true"`를 추가하면 장식용으로 표시됩니다. 버튼의 `aria-label`이 의미를 전달합니다.
</Info>

## 컴포넌트 라이브러리 사용 시

컴포넌트 라이브러리를 사용하여 HTML 요소를 직접 관리하지 않는 경우에도 `aria-label`은 동일하게 작동합니다. React는 모든 `aria-*` props를 기본 DOM 요소로 전달하므로, 클릭 가능한 요소를 렌더링하는 모든 컴포넌트에 적용됩니다.

<Tabs>
  <Tab title="MUI">
    ```tsx theme={null}
    import { IconButton } from '@mui/material';
    import DeleteIcon from '@mui/icons-material/Delete';

    <IconButton aria-label="항목 삭제">
      <DeleteIcon />
    </IconButton>
    ```
  </Tab>

  <Tab title="Chakra UI">
    ```tsx theme={null}
    import { IconButton } from '@chakra-ui/react';
    import { CloseIcon } from '@chakra-ui/icons';

    <IconButton aria-label="대화상자 닫기" icon={<CloseIcon />} />
    ```
  </Tab>

  <Tab title="Ant Design">
    ```tsx theme={null}
    import { Button } from 'antd';
    import { EditOutlined } from '@ant-design/icons';

    <Button aria-label="프로필 편집" icon={<EditOutlined />} />
    ```
  </Tab>

  <Tab title="Radix / shadcn/ui">
    ```tsx theme={null}
    import { Button } from '@/components/ui/button';
    import { GearIcon } from '@radix-ui/react-icons';

    <Button aria-label="설정" variant="ghost" size="icon">
      <GearIcon />
    </Button>
    ```
  </Tab>
</Tabs>

### 커스텀 아이콘 버튼 컴포넌트

팀에서 공유 아이콘 버튼 래퍼를 사용하는 경우, 나머지 props를 기본 요소에 전개(spread)하여 `aria-label`이 전달되도록 하세요:

```tsx theme={null}
function IconButton({ icon, ...props }) {
  return (
    <button {...props}>
      {icon}
    </button>
  );
}

// 사용 예시
<IconButton aria-label="보고서 다운로드" icon={<DownloadIcon />} />
```

### 툴팁이 있는 버튼

버튼에 이미 툴팁이 있다면, 동일한 텍스트를 `aria-label`로 사용하세요:

```tsx theme={null}
<Tooltip content="삭제">
  <IconButton aria-label="삭제">
    <TrashIcon />
  </IconButton>
</Tooltip>
```

## 좋은 라벨 작성하기

| 올바른 예                   | 잘못된 예                  |
| ----------------------- | ---------------------- |
| `aria-label="항목 삭제"`    | `aria-label="휴지통 아이콘"` |
| `aria-label="대화상자 닫기"`  | `aria-label="X"`       |
| `aria-label="보고서 다운로드"` | `aria-label="버튼"`      |
| `aria-label="설정 열기"`    | `aria-label="톱니바퀴"`    |

* **아이콘이 아닌 동작을 설명하세요.** 사용자와 Moss는 버튼이 *무엇을 하는지* 알아야 합니다.
* **간결하게 작성하세요** — 보통 1\~3단어면 충분합니다.
* **텍스트가 이미 보이면 라벨을 생략하세요.** 아이콘 옆에 이미 "저장"이라는 텍스트가 있는 버튼에는 `aria-label`이 필요하지 않습니다.

## 라벨이 없는 버튼 찾기

브라우저 콘솔에서 아래 스니펫을 실행하면 라벨이 필요한 버튼을 찾을 수 있습니다:

```js theme={null}
document.querySelectorAll('button, [role="button"]').forEach(el => {
  const hasText = el.textContent?.trim().length > 0;
  const hasLabel = el.getAttribute('aria-label');
  const hasLabelledBy = el.getAttribute('aria-labelledby');
  if (!hasText && !hasLabel && !hasLabelledBy) {
    console.warn('라벨이 없는 버튼:', el);
  }
});
```

<Tip>
  애플리케이션의 주요 페이지마다 이 스크립트를 실행하여 라벨이 필요한 버튼의 전체 목록을 확인하세요.
</Tip>

## 요약

| 수행 사항                            | 이유                               |
| -------------------------------- | -------------------------------- |
| 모든 아이콘 전용 버튼에 `aria-label` 추가    | Moss가 안내 지침에서 버튼을 식별하는 데 사용      |
| 장식용 SVG에 `aria-hidden="true"` 추가 | 스크린 리더가 SVG 경로 데이터를 읽는 것을 방지     |
| 동작 중심의 라벨 사용                     | "**항목 삭제**를 클릭하세요"와 같은 명확한 안내 생성 |

이는 [WCAG 2.1 요구사항](https://www.w3.org/WAI/WCAG21/Understanding/name-role-value.html)(성공 기준 4.1.2: 이름, 역할, 값)이기도 하므로, 이러한 라벨을 추가하면 모든 사용자의 접근성이 향상됩니다.
