/** * A select bound to a form field. * * The select controller was the one kind built the other way round: it takes options, a value and a * callback, and a host drives it with eight imperative setters. Every other kind takes a field handle * and reads it. Two idioms in one package meant a renderer picked whichever the kind happened to * have — and `multiselect`, which is the same widget with more than one answer, sat on the opposite * side of the split from `select`. * * This is the adapter that closes it, in the direction that costs nothing: a form-shaped controller * on top of the standalone one. The standalone controller keeps working for a host that has no form * — which is the case it was written for and the reason it is not simply replaced. * * The verdict rule arrives with the binding: a select's `invalid` was a boolean its caller passed, * so a field the form was not asking about painted as failing unless the caller happened to know * better. It reads it from the handle now. */ import { type MdyFieldHandle, type MdyReactivity, type MdySelectOption } from "@modyra/core"; import type { MdyWidgetController } from "../contract.js"; import type { MdySelectIntent, MdySelectState } from "../select/select-types.js"; export interface MdySelectFieldControllerOptions { readonly widgetId: string; readonly handle: MdyFieldHandle; readonly options: readonly MdySelectOption[]; readonly keyFor?: (option: MdySelectOption) => string; /** Whether options are still arriving. Not a form state, so it stays a parameter. */ readonly loading?: boolean; readonly readonly?: boolean; /** Whether this select filters, which decides which of the kind's two shapes it is. ADR 0176. */ readonly searchable?: boolean; } export interface MdySelectFieldController extends MdyWidgetController, MdySelectIntent> { /** Which of the two texts under the field the trigger describes itself by. */ setDescribedBy(shown: { readonly errorsVisible?: boolean; readonly descriptionVisible?: boolean; }): void; /** Whether the panel is up. */ setOpen(open: boolean): void; /** Whether the panel's contents are in the document — a renderer may build them only on open. */ setPopupRendered(rendered: boolean): void; /** Replace the offered options — a list that arrives after the control is on screen. */ setOptions(options: readonly MdySelectOption[]): void; setLoading(loading: boolean): void; setReadonly(readonly: boolean): void; } export declare function createSelectFieldController(options: MdySelectFieldControllerOptions, reactivity?: MdyReactivity): MdySelectFieldController;