import { Fragment, type ReactNode, type RefObject } from 'react' import Block from '../Primitives/Block/Block' import PrimitiveText from '../Primitives/PrimitiveText/PrimitiveText' import { SelectItemV2 } from '../SelectV2' import VirtualList from '../VirtualList/VirtualList' import type { VirtualListItem, VirtualListRef } from '../VirtualList/types' import type { SelectListV2ChromeTokens, SelectListV2ItemType, SelectListV2Row, } from './selectListV2.types' export type SelectListV2VirtualizationConfig = { height: number itemHeight: number overscan: number listRef: RefObject onEndReached?: () => void endReachedThreshold?: number hasMore?: boolean isLoadingMore?: boolean paginationKey?: string | number } export type SelectListV2RowsProps = { rows: SelectListV2Row[] chrome: SelectListV2ChromeTokens mode: 'single' | 'multi' /** Single mode holds at most one value; kept as an array for one code path. */ selectedValues: string[] onToggle: (value: string) => void isItemDisabled: (item: SelectListV2ItemType) => boolean activeItemIndex: number getItemRef: ( itemIndex: number, value: string ) => (node: HTMLElement | null) => void /** Total option count, for `aria-setsize` on every rendered option. */ optionCount: number virtualization?: SelectListV2VirtualizationConfig loadingComponent?: ReactNode } const SelectListV2Rows = ({ rows, chrome, mode, selectedValues, onToggle, isItemDisabled, activeItemIndex, getItemRef, optionCount, virtualization, loadingComponent, }: SelectListV2RowsProps) => { // The visible label is decorative in both paths: the accessible name comes // from the `role="group"` wrapper (non-virtualized) or from // aria-setsize/aria-posinset (virtualized, where no wrapper is expressible). const renderGroupLabel = (label: string) => ( ) // Decorative: `listbox` permits only `option`/`group` as owned children, // so a `separator` role here fails aria-required-children. const renderSeparator = () => (