UNPKG

8.79 kBTypeScriptView Raw
1import * as React from 'react';
2import { ListAction, ListState, UseListRootSlotProps } from '../useList';
3import { SelectOption } from '../useOption/useOption.types';
4import { SelectProviderValue } from './SelectProvider';
5import { MuiCancellableEventHandler } from '../utils/MuiCancellableEvent';
6import { UseButtonRootSlotProps } from '../useButton';
7export type SelectChangeEventType = React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element> | React.FocusEvent<Element, Element> | null;
8export type SelectValue<Value, Multiple> = Multiple extends true ? Value[] : Value | null;
9export interface SelectOptionDefinition<Value> {
10 value: Value;
11 disabled?: boolean;
12 label: string;
13}
14export interface UseSelectParameters<OptionValue, Multiple extends boolean = false> {
15 /**
16 * A function used to determine if two options' values are equal.
17 * By default, reference equality is used.
18 *
19 * There is a performance impact when using the `areOptionsEqual` prop (proportional to the number of options).
20 * Therefore, it's recommented to use the default reference equality comparison whenever possible.
21 */
22 areOptionsEqual?: (a: OptionValue, b: OptionValue) => boolean;
23 /**
24 * If `true`, the select will be open by default.
25 * @default false
26 */
27 defaultOpen?: boolean;
28 /**
29 * The default selected value. Use when the component is not controlled.
30 */
31 defaultValue?: SelectValue<OptionValue, Multiple>;
32 /**
33 * If `true`, the select is disabled.
34 * @default false
35 */
36 disabled?: boolean;
37 /**
38 * The ref of the trigger button element.
39 */
40 buttonRef?: React.Ref<Element>;
41 /**
42 * The `id` attribute of the listbox element.
43 */
44 listboxId?: string;
45 /**
46 * The ref of the listbox element.
47 */
48 listboxRef?: React.Ref<Element>;
49 /**
50 * If `true`, the end user can select multiple values.
51 * This affects the type of the `value`, `defaultValue`, and `onChange` props.
52 *
53 * @default false
54 */
55 multiple?: Multiple;
56 /**
57 * The `name` attribute of the hidden input element.
58 * This is useful when the select is embedded in a form and you want to access the selected value in the form data.
59 */
60 name?: string;
61 /**
62 * If `true`, the select embedded in a form must have a selected value.
63 * Otherwise, the form submission will fail.
64 */
65 required?: boolean;
66 /**
67 * Callback fired when an option is selected.
68 */
69 onChange?: (event: React.MouseEvent | React.KeyboardEvent | React.FocusEvent | null, value: SelectValue<OptionValue, Multiple>) => void;
70 /**
71 * Callback fired when an option is highlighted.
72 */
73 onHighlightChange?: (event: React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element> | React.FocusEvent<Element, Element> | null, highlighted: OptionValue | null) => void;
74 /**
75 * Callback fired when the listbox is opened or closed.
76 */
77 onOpenChange?: (open: boolean) => void;
78 /**
79 * Controls the open state of the select's listbox.
80 * This is the controlled equivalent of the `defaultOpen` prop.
81 */
82 open?: boolean;
83 /**
84 * An alternative way to specify the options.
85 * If this parameter is set, options defined as JSX children are ignored.
86 */
87 options?: ReadonlyArray<SelectOptionDefinition<OptionValue>>;
88 /**
89 * A function to convert the currently selected value to a string.
90 * Used to set a value of a hidden input associated with the select,
91 * so that the selected value can be posted with a form.
92 */
93 getSerializedValue?: (option: SelectValue<SelectOption<OptionValue>, Multiple>) => React.InputHTMLAttributes<HTMLInputElement>['value'];
94 /**
95 * A function used to convert the option label to a string.
96 * This is useful when labels are elements and need to be converted to plain text
97 * to enable keyboard navigation with character keys.
98 *
99 * @default defaultOptionStringifier
100 */
101 getOptionAsString?: (option: SelectOption<OptionValue>) => string;
102 /**
103 * The selected value.
104 * Set to `null` to deselect all options.
105 */
106 value?: SelectValue<OptionValue, Multiple>;
107 /**
108 * The name of the component using useSelect.
109 * For debugging purposes.
110 * @default 'useSelect'
111 */
112 componentName?: string;
113}
114interface UseSelectButtonSlotEventHandlers {
115 onMouseDown: MuiCancellableEventHandler<React.MouseEvent>;
116}
117export type UseSelectButtonSlotProps<TOther = {}> = UseButtonRootSlotProps<Omit<TOther, keyof UseSelectButtonSlotEventHandlers>> & UseSelectButtonSlotEventHandlers & {
118 'aria-expanded': React.AriaAttributes['aria-expanded'];
119 'aria-controls': React.AriaAttributes['aria-controls'];
120 role: React.HTMLAttributes<Element>['role'];
121 ref: React.RefCallback<Element> | null;
122};
123interface UseSelectHiddenInputSlotEventHandlers {
124 onChange: MuiCancellableEventHandler<React.ChangeEvent<HTMLInputElement>>;
125}
126export type UseSelectHiddenInputSlotProps<TOther = {}> = UseSelectHiddenInputSlotEventHandlers & React.InputHTMLAttributes<HTMLInputElement> & TOther;
127interface UseSelectListboxSlotEventHandlers {
128 onBlur: MuiCancellableEventHandler<React.FocusEvent<HTMLElement>>;
129}
130export type UseSelectListboxSlotProps<TOther = {}> = UseListRootSlotProps<Omit<TOther, keyof UseSelectListboxSlotEventHandlers>> & UseSelectListboxSlotEventHandlers & {
131 'aria-multiselectable': React.AriaAttributes['aria-multiselectable'];
132 id: string | undefined;
133 role: React.HTMLAttributes<Element>['role'];
134};
135export interface UseSelectReturnValue<Value, Multiple> {
136 /**
137 * If `true`, the trigger button is active (pressed).
138 */
139 buttonActive: boolean;
140 /**
141 * If `true`, the trigger button has a visible focus.
142 */
143 buttonFocusVisible: boolean;
144 /**
145 * Ref to the button slot DOM node.
146 */
147 buttonRef: React.RefCallback<Element> | null;
148 /**
149 * If `true`, the select is disabled.
150 */
151 disabled: boolean;
152 /**
153 * Action dispatcher for the select component.
154 * Allows to programmatically control the select.
155 */
156 dispatch: (action: ListAction<Value> | SelectAction<Value>) => void;
157 /**
158 * Resolver for the button slot's props.
159 * @param externalProps event handlers for the button slot
160 * @returns props that should be spread on the button slot
161 */
162 getButtonProps: <ExternalProps extends Record<string, unknown> = {}>(externalProps?: ExternalProps) => UseSelectButtonSlotProps<ExternalProps>;
163 /**
164 * Resolver for the hidden input slot's props.
165 * @param externalProps event handlers for the hidden input slot
166 * @returns HTML input attributes that should be spread on the hidden input slot
167 */
168 getHiddenInputProps: <ExternalProps extends Record<string, unknown> = {}>(externalProps?: ExternalProps) => UseSelectHiddenInputSlotProps<ExternalProps>;
169 /**
170 * Resolver for the listbox slot's props.
171 * @param externalProps event handlers for the listbox slot
172 * @returns props that should be spread on the listbox slot
173 */
174 getListboxProps: <ExternalProps extends Record<string, unknown> = {}>(externalProps?: ExternalProps) => UseSelectListboxSlotProps<ExternalProps>;
175 /**
176 * A function that returns the metadata of an option with a given value.
177 *
178 * @param optionValue the value of the option
179 * @returns
180 */
181 getOptionMetadata: (optionValue: Value) => SelectOption<Value> | undefined;
182 /**
183 * A value to be passed to the `SelectProvider` component.
184 */
185 contextValue: SelectProviderValue<Value>;
186 /**
187 * The value of the highlighted option.
188 */
189 highlightedOption: Value | null;
190 /**
191 * Ref to the listbox slot DOM node.
192 */
193 listboxRef: React.RefCallback<Element> | null;
194 /**
195 * If `true`, the listbox is open.
196 */
197 open: boolean;
198 /**
199 * Values of all the registered options.
200 */
201 options: Value[];
202 /**
203 * The value of the selected option(s).
204 */
205 value: SelectValue<Value, Multiple>;
206}
207export declare const SelectActionTypes: {
208 readonly buttonClick: "buttonClick";
209 readonly browserAutoFill: "browserAutoFill";
210};
211export interface ButtonClickAction {
212 type: typeof SelectActionTypes.buttonClick;
213 event: React.MouseEvent;
214}
215export interface BrowserAutofillAction<OptionValue> {
216 type: typeof SelectActionTypes.browserAutoFill;
217 item: OptionValue;
218 event: React.ChangeEvent;
219}
220export type SelectAction<OptionValue> = ButtonClickAction | BrowserAutofillAction<OptionValue>;
221export interface SelectInternalState<OptionValue> extends ListState<OptionValue> {
222 open: boolean;
223}
224export {};