File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
"use client";
import type { ReactNode, Ref } from "react";
import { cx } from "../../utils";
export interface FoxSelectOptionProps {
/** 목록을 여는 요소의 `aria-controls`가 가리킬 값. */
id?: string;
/** 목록에 이름을 주는 요소의 id — 보통 셀렉트의 라벨이다. */
labelledBy?: string;
/** `FoxSelectOptionItem`들. */
children?: ReactNode;
/** 배치 조정용. 모양이 달라야 하면 여기 말고 모디파이어를 추가한다. */
className?: string;
ref?: Ref<HTMLUListElement>;
}
/**
* @fox 셀렉트가 열렸을 때 뜨는 옵션 목록. 배치만 책임지고 상태를 갖지 않는다 —
* 열림 여부·활성 항목·선택 값은 전부 목록을 여는 쪽이 소유한다.
*
* 항목을 눌러도 포커스가 옮겨가지 않게 `mousedown` 기본 동작을 막는다. 콤보박스는 포커스가
* 여는 요소에 남아 있어야 `aria-activedescendant`가 성립하고, 막지 않으면 누르는 순간
* 포커스가 빠져 목록이 닫히면서 클릭이 성사되지 않는다.
*
* ⚠️ 스스로 위치를 잡지 못한다 — `position: absolute`라 위치 기준이 되는 조상이 필요하다.
* `FoxSelect` 안에서는 `fox-select__control`이 그 역할을 한다.
*
* ⚠️ 스타일은 이 파일이 import하지 않는다 — 호스트 앱이 `@use "@fox/styles/components"`
* (또는 개별 파티셜)로 한 번 불러와야 한다.
*/
export function FoxSelectOption({
id,
labelledBy,
children,
className,
ref,
}: FoxSelectOptionProps) {
return (
<ul
ref={ref}
id={id}
role="listbox"
aria-labelledby={labelledBy}
className={cx("fox-select-option", className)}
onMouseDown={(event) => event.preventDefault()}
>
{children}
</ul>
);
}