import type { ControlSize } from "@charcuterie/tokens"
import type { ReactNode } from "react"
import { useEffect } from "react"
import { CONTROL_SIZE_CLASS } from "../controlStyles.ts"
import { FOCUS_RING_CLASS } from "../intentStyles.ts"
import { toClassName } from "../toClassName.ts"
import type { SegmentedItem } from "./SegmentedControl.tsx"
export type SegmentedOptionProps = {
isChecked: boolean
isFullWidth: boolean
item: SegmentedItem
onChoose: (value: string) => void
/** `RovingFocus.register` — membership of the arrow-key group. */
registerFocus: (value: string) => () => void
/** `SinglePicker.register` — membership of the choice. */
registerSelection: (value: string) => () => void
size: ControlSize
tabIndex: number
trackElement: (
value: string,
element: HTMLButtonElement | null,
) => void
}
/**
* Its own file for the same reason `TabTrigger` is: **both
* registrations are effects**, and an effect cannot run in a loop.
* Any member of a registering group ends up shaped like this.
*
* The checked option is filled rather than merely tinted. A
* segmented control's whole job is to be readable at a glance from
* across a room — rip-deck's lives above a nine-bay grid on a wall
* display — and a one-shade difference does not survive that or a
* `daylight` theme in sunlight.
*/
export const SegmentedOption = ({
isChecked,
isFullWidth,
item,
onChoose,
registerFocus,
registerSelection,
size,
tabIndex,
trackElement,
}: SegmentedOptionProps): ReactNode => {
const { isDisabled = false, label, value } = item
useEffect(
() => registerSelection(value),
[registerSelection, value],
)
useEffect(() => {
if (isDisabled) {
return
}
return registerFocus(value)
}, [isDisabled, registerFocus, value])
return (
// biome-ignore lint/a11y/useSemanticElements: `` owns `checked` *and* owns arrow-key navigation within a `name` group. That is the self-owning-control conflict `Modal` already has with `