"use client"; import { type ChangeEvent, type ComponentPropsWithRef, type ReactNode } from "react"; import { cx } from "../../utils"; export type FoxSegmentedControlItemSize = "lg" | "md" | "sm" | "xsm"; /** * 네이티브 ``가 받는 것을 그대로 넘겨받는다 — name·value·checked· * defaultChecked·disabled·required·form 등. 의미가 겹치는 것만 걷어내고 아래에서 다시 정의한다. */ type NativeRadioProps = Omit< ComponentPropsWithRef<"input">, "type" | "size" | "className" | "children" | "hidden" | "onChange" >; export interface FoxSegmentedControlItemProps extends NativeRadioProps { size?: FoxSegmentedControlItemSize; label: ReactNode; /** 글자 앞에 붙는 아이콘. 넘기지 않으면 자리를 만들지 않는다. */ icon?: ReactNode; /** * 이 칸이 선택될 때 부른다. 값이 첫 인자다 — 네이티브 `onChange`를 `Omit`으로 걷어내고 * 그 자리를 대신한다(`FoxRadio`와 같은 방식). */ onChange?: (value: string, event: ChangeEvent) => void; /** 참이면 렌더하지 않는다(DOM에 남지 않는다). */ hidden?: boolean; /** 배치 조정용. 모양이 달라야 하면 여기 말고 모디파이어를 추가한다. */ className?: string; } /** `Record`로 고정해 크기를 추가하면 항목 누락이 타입 에러가 되게 한다. */ const SIZE_CLASS: Record = { lg: "fox-segmented-control-item--lg", md: "fox-segmented-control-item--md", sm: "fox-segmented-control-item--sm", xsm: "fox-segmented-control-item--xsm", }; /** * @fox 세그먼티드 컨트롤의 칸 하나. 상태를 갖지 않는다 — 켜짐 여부는 네이티브 * ``가 소유한다. * * `name`이 같은 칸끼리는 브라우저가 그룹으로 묶어 단일 선택·화살표 이동·폼 전송을 처리한다. * `FoxSegmentedControl`이 하는 일은 그 `name`을 통일하고 테두리로 감싸는 것뿐이다. * * 루트가 `