1 | import * as React from 'react';
|
2 | import { Simplify } from '@mui/types';
|
3 | import { ListAction } from './listActions.types';
|
4 | import { ActionWithContext, ControllableReducerAction, StateChangeCallback } from '../utils/useControllableReducer.types';
|
5 | import type { ListContextValue } from './ListContext';
|
6 | import { MuiCancellableEventHandler } from '../utils/MuiCancellableEvent';
|
7 | type ListActionContextRequiredKeys = 'disabledItemsFocusable' | 'disableListWrap' | 'focusManagement' | 'getItemAsString' | 'isItemDisabled' | 'itemComparer' | 'items' | 'orientation' | 'pageSize' | 'selectionMode';
|
8 | /**
|
9 | * The subset of `UseListParameters` that is passed to the list reducer actions.
|
10 | */
|
11 | export type ListActionContext<ItemValue> = Simplify<Required<Pick<UseListParameters<ItemValue, any, any>, ListActionContextRequiredKeys>>>;
|
12 | /**
|
13 | * The action object augmented with the action context ({@linkcode ListActionContext} instance).
|
14 | * Instances of this type are passed to the reducer.
|
15 | *
|
16 | * @template ItemValue The type of the item values.
|
17 | * @template CustomActionContext The shape of additional properties that will be added to actions when dispatched.
|
18 | */
|
19 | export type ListReducerAction<ItemValue, CustomActionContext = {}> = ActionWithContext<ListAction<ItemValue>, ListActionContext<ItemValue> & CustomActionContext>;
|
20 | /**
|
21 | * The state of the list.
|
22 | * Modifications to this state should be done via the reducer.
|
23 | */
|
24 | export interface ListState<ItemValue> {
|
25 | /**
|
26 | * The item that is currently highlighted.
|
27 | */
|
28 | highlightedValue: ItemValue | null;
|
29 | /**
|
30 | * The item(s) that are currently selected.
|
31 | */
|
32 | selectedValues: ItemValue[];
|
33 | }
|
34 | /**
|
35 | * Type of the reducer that operates on the list state.
|
36 | *
|
37 | * @template ItemValue The type of the item values.
|
38 | * @template State The type of the list state. This should be a subtype of ListState<ItemValue>.
|
39 | * @template CustomActionContext The shape of additional properties that will be added to actions when dispatched.
|
40 | */
|
41 | export type ListReducer<ItemValue, State extends ListState<ItemValue>, CustomActionContext> = (state: State, action: ListReducerAction<ItemValue, CustomActionContext>) => State;
|
42 | export type FocusManagementType = 'DOM' | 'activeDescendant';
|
43 | export type SelectionMode = 'none' | 'single' | 'multiple';
|
44 | /**
|
45 | * Parameters of the useList hook.
|
46 | *
|
47 | * @template ItemValue The type of the item values.
|
48 | * @template State The type of the list state. This should be a subtype of `ListState<ItemValue>`.
|
49 | * @template CustomAction The type of the actions that can be dispatched (besides the standard ListAction).
|
50 | * @template CustomActionContext The shape of additional properties that will be added to actions when dispatched.
|
51 | */
|
52 | export interface UseListParameters<ItemValue, State extends ListState<ItemValue> = ListState<ItemValue>, CustomAction extends ControllableReducerAction = never, CustomActionContext = {}> {
|
53 | /**
|
54 | * The externally controlled values (highlighted and selected item(s)) of the list.
|
55 | * If a custom state is used, this object can contain the added state fields as well.
|
56 | *
|
57 | * @default {}
|
58 | */
|
59 | controlledProps?: Partial<State>;
|
60 | /**
|
61 | * If `true`, it will be possible to highlight disabled items.
|
62 | * @default false
|
63 | */
|
64 | disabledItemsFocusable?: boolean;
|
65 | /**
|
66 | * If `true`, the highlight will not wrap around the list if arrow keys are used.
|
67 | * @default false
|
68 | */
|
69 | disableListWrap?: boolean;
|
70 | /**
|
71 | * The focus management strategy used by the list.
|
72 | * Controls the attributes used to set focus on the list items.
|
73 | * @default 'activeDescendant'
|
74 | */
|
75 | focusManagement?: FocusManagementType;
|
76 | /**
|
77 | * A function that returns the DOM element associated with an item.
|
78 | * This is required when using the `DOM` focus management.
|
79 | *
|
80 | * @param item List item to get the DOM element for.
|
81 | */
|
82 | getItemDomElement?: (itemValue: ItemValue) => HTMLElement | null;
|
83 | /**
|
84 | * A function that returns the id of an item.
|
85 | * This is required when using the `activeDescendant` focus management.
|
86 | *
|
87 | * @param itemValue List item to get the id for.
|
88 | */
|
89 | getItemId?: (itemValue: ItemValue) => string | undefined;
|
90 | /**
|
91 | * A function that intializes the state of the list.
|
92 | * It is required when using a custom state with mandatory fields.
|
93 | * If not provided, the state will be initialized with the default values (nothing highlighted or selected).
|
94 | *
|
95 | * @returns The initial state of the list.
|
96 | */
|
97 | getInitialState?: () => State;
|
98 | /**
|
99 | * A function that determines if a particular item is disabled.
|
100 | * @default () => false
|
101 | */
|
102 | isItemDisabled?: (itemValue: ItemValue, index: number) => boolean;
|
103 | /**
|
104 | * Ref to the list root DOM element.
|
105 | */
|
106 | rootRef?: React.Ref<Element>;
|
107 | /**
|
108 | * Callback fired when the selected value changes.
|
109 | * This is a strongly typed convenience event that can be used instead of `onStateChange`.
|
110 | */
|
111 | onChange?: (event: React.MouseEvent | React.KeyboardEvent | React.FocusEvent | null, value: ItemValue[], reason: string) => void;
|
112 | /**
|
113 | * Callback fired when the highlighted option changes.
|
114 | * This is a strongly typed convenience event that can be used instead of `onStateChange`.
|
115 | */
|
116 | onHighlightChange?: (event: React.MouseEvent | React.KeyboardEvent | React.FocusEvent | null, option: ItemValue | null, reason: string) => void;
|
117 | /**
|
118 | * Callback fired when the items change.
|
119 | *
|
120 | * @param items The new items collection
|
121 | */
|
122 | onItemsChange?: (items: ItemValue[]) => void;
|
123 | /**
|
124 | * Callback fired when the any of the state items change.
|
125 | * Note that in case of `selectedValues` and `highlightedValue` the strongly typed
|
126 | * `onChange` and `onHighlightChange` callbacks are also fired.
|
127 | */
|
128 | onStateChange?: StateChangeCallback<State>;
|
129 | /**
|
130 | * The number of items skip when using the page up and page down keys.
|
131 | *
|
132 | * @default 5
|
133 | */
|
134 | pageSize?: number;
|
135 | /**
|
136 | * A function that tests equality between two items' values.
|
137 | * @default (a, b) => a === b
|
138 | */
|
139 | itemComparer?: (itemValue1: ItemValue, itemValue2: ItemValue) => boolean;
|
140 | /**
|
141 | * A function that converts an object to its string representation
|
142 | * @default (o) => o
|
143 | */
|
144 | getItemAsString?: (option: ItemValue) => string | undefined;
|
145 | /**
|
146 | * Array of list items.
|
147 | */
|
148 | items: ItemValue[];
|
149 | /**
|
150 | * Additional data to be passed to all the reducer actions.
|
151 | * It will be available in the `context` property of the action when dispatched.
|
152 | */
|
153 | reducerActionContext?: CustomActionContext;
|
154 | /**
|
155 | * Orientation of the items in the list.
|
156 | * Determines the actions that are performed when arrow keys are pressed.
|
157 | */
|
158 | orientation?: 'horizontal-ltr' | 'horizontal-rtl' | 'vertical';
|
159 | /**
|
160 | * Controls how many items can be selected at once: none (the selection functionality is disabled in this case), one, or indefinitely many.
|
161 | * @default 'single'
|
162 | */
|
163 | selectionMode?: SelectionMode;
|
164 | /**
|
165 | * Custom state reducer function. It calculates the new state (highlighted and selected items + optional custom state)
|
166 | * based on the previous one and the performed action.
|
167 | */
|
168 | stateReducer?: (state: State, action: ActionWithContext<ListAction<ItemValue> | CustomAction, ListActionContext<ItemValue> & CustomActionContext>) => State;
|
169 | /**
|
170 | * The name of the component using useList.
|
171 | * For debugging purposes.
|
172 | * @default 'useList'
|
173 | */
|
174 | componentName?: string;
|
175 | }
|
176 | export interface ListItemState {
|
177 | /**
|
178 | * Determines if the item is focusable (its focus is managed by the DOM).
|
179 | */
|
180 | focusable: boolean;
|
181 | /**
|
182 | * If `true` the item is highlighted.
|
183 | */
|
184 | highlighted: boolean;
|
185 | /**
|
186 | * If `true` the item is selected.
|
187 | */
|
188 | selected: boolean;
|
189 | }
|
190 | interface UseListRootSlotOwnProps {
|
191 | 'aria-activedescendant'?: React.AriaAttributes['aria-activedescendant'];
|
192 | onBlur: MuiCancellableEventHandler<React.FocusEvent<HTMLElement>>;
|
193 | onKeyDown: MuiCancellableEventHandler<React.KeyboardEvent<HTMLElement>>;
|
194 | tabIndex: number;
|
195 | ref: React.RefCallback<Element> | null;
|
196 | }
|
197 | export type UseListRootSlotProps<ExternalProps = {}> = ExternalProps & UseListRootSlotOwnProps;
|
198 | export interface UseListReturnValue<ItemValue, State extends ListState<ItemValue>, CustomAction extends ControllableReducerAction> {
|
199 | contextValue: ListContextValue<ItemValue>;
|
200 | dispatch: (action: CustomAction | ListAction<ItemValue>) => void;
|
201 | /**
|
202 | * Resolver for the root slot's props.
|
203 | * @param externalProps additional props for the root slot
|
204 | * @returns props that should be spread on the root slot
|
205 | */
|
206 | getRootProps: <ExternalProps extends Record<string, unknown> = {}>(externalProps?: ExternalProps) => UseListRootSlotProps<ExternalProps>;
|
207 | rootRef: React.RefCallback<Element> | null;
|
208 | state: State;
|
209 | }
|
210 | export {};
|