import { html, nothing, type TemplateResult } from 'lit'; import type { NuiType } from '../../types/nui-type.js'; import { isOptionDisabled, isValueSelected, resolveOptionLabel, resolveOptionValue, } from './listbox-options.js'; import type { ListboxOption, ListboxPrimitive, ListboxValue } from './types.js'; export interface NuiListboxViewState { options: ListboxOption[]; visibleOptions: ListboxOption[]; optionLabel: string; optionValue: string; optionDisabled: string; value: ListboxValue; multiple: boolean; disabled: boolean; invalid: boolean; readonly: boolean; filter: boolean; filterPlaceholder: string; filterValue: string; listScrollHeight: string; striped: boolean; checkmark: boolean; highlightOnSelect: boolean; emptyMessage: string; emptyFilterMessage: string; fluid: boolean; tabindex: number; ariaLabel: string; ariaLabelledby: string; focusedIndex: number; nuiType: NuiType; listboxClass: string; } export interface ListboxRenderHandlers { onFilterInput: (event: Event) => void; onOptionClick: (index: number) => void; onListFocus: () => void; } export function getListboxClass(listboxClass: string): string { return ['nui-listbox', listboxClass].filter(Boolean).join(' '); } function renderOption( state: NuiListboxViewState, option: ListboxOption, index: number, handlers: ListboxRenderHandlers, ): TemplateResult { const optionVal = resolveOptionValue( option, state.optionValue, state.optionLabel, ); const selected = isValueSelected(state.value, optionVal, state.multiple); const disabled = state.disabled || isOptionDisabled(option, state.optionDisabled); const focused = state.focusedIndex === index; return html`