import * as React from 'react'; import { InputWithOptions, InputWithOptionsProps, OnSelectFnSignature, } from '../InputWithOptions'; import { DropdownLayoutProps, DropdownLayoutValueOption, } from '../DropdownLayout'; import { TagProps } from '../Tag'; import { InputStatus } from '../Input'; export type MultiSelectStatus = InputStatus; export interface MultiSelectProps extends InputWithOptionsProps< (values: string[]) => void > { /** The id of the selected option in the list. */ selectedId?: DropdownLayoutProps['selectedId']; /** Closes list once list item is selected. */ closeOnSelect?: DropdownLayoutProps['closeOnSelect']; /** Whether the selected option is highlighted when the dropdown reopens. * @default true */ selectedHighlight?: DropdownLayoutProps['selectedHighlight']; /** Callback predicate for the filtering options function. */ predicate?: (option: DropdownLayoutValueOption) => boolean; /** Defines a message to be displayed instead of options when no options exist or no options pass the predicate filter function. */ emptyStateMessage?: React.ReactNode; /** Optional list of strings that are selected suggestions. */ tags?: MultiSelectTag[]; /** Max number of visible lines. */ maxNumRows?: number; /** Delimiters that trigger a Submit action (call to onTagsAdded). By default it is [,] but also enter and tab keys work. */ delimiters?: string[]; /** Passing 'select' renders a readOnly input with menuArrow suffix *. */ mode?: MultiSelectMode; /** The status of the input. */ status?: MultiSelectStatus; /** Text to be shown in the status icon tooltip. */ statusMessage?: React.ReactNode; /** When this callback function is set, tags can be reordered. The expected callback signature is `onReorder({addedIndex: number, removedIndex: number}) => void` *. */ onReorder?: OnReorderFn; /** A callback which is called when the user selects an option from the list. `onSelect(option: Option): void` - Option is the original option from the provided options prop. */ onSelect?: (option: DropdownLayoutValueOption) => void; /** Render a custom input instead of the default html input tag. By default, it renders an input that sizes itself to its text. */ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type -- TODO(backlog 20260610T131342): should be React.ElementType; fixing it requires cleaning up consumers that pass elements customInput?: React.ReactNode | Function; /** A node to display as input suffix when the dropdown is closed. */ customSuffix?: React.ReactNode; /** A node to display as input prefix when the dropdown is closed. */ customPrefix?: React.ReactNode; /** When set to true this component is disabled. */ disabled?: boolean; /** Specifies whether input should be read only. */ readOnly?: boolean; /** A callback function to be called when a tag should be removed. The expected callback signature is `onRemoveTag(tagId: number | string) => void.` */ onRemoveTag?: (tagId: TagProps['id']) => void; /** When set to false, the input won't be cleared on blur. * @default true */ clearOnBlur?: boolean; /** When set to true, the input is submitted as a new tag on blur. */ acceptOnBlur?: boolean; /** Adds a fixed footer container at the bottom of options list. */ fixedFooter?: React.ReactNode; } export class MultiSelect extends InputWithOptions< (values: string[]) => void, OnSelectFnSignature, MultiSelectProps > {} export type MultiSelectMode = 'select'; export type OnReorderFn = (data: { addedIndex: number; removedIndex: number; }) => void; export type MultiSelectTag = Omit & { // TODO: widen to React.ReactNode in the next major release (see docs/major-release.md) label: string; };