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 { EventHandlers } from '../utils';
|
6 | import type { ListContextValue } from './ListContext';
|
7 | import { MuiCancellableEventHandler } from '../utils/muiCancellableEvent';
|
8 | type ListActionContextRequiredKeys = 'disabledItemsFocusable' | 'disableListWrap' | 'focusManagement' | 'getItemAsString' | 'isItemDisabled' | 'itemComparer' | 'items' | 'orientation' | 'pageSize' | 'selectionMode';
|
9 | /**
|
10 | * The subset of `UseListParameters` that is passed to the list reducer actions.
|
11 | */
|
12 | export type ListActionContext<ItemValue> = Simplify<Required<Pick<UseListParameters<ItemValue, any, any>, ListActionContextRequiredKeys>>>;
|
13 | /**
|
14 | * The action object augmented with the action context ({@linkcode ListActionContext} instance).
|
15 | * Instances of this type are passed to the reducer.
|
16 | *
|
17 | * @template ItemValue The type of the item values.
|
18 | * @template CustomActionContext The shape of additional properties that will be added to actions when dispatched.
|
19 | */
|
20 | export type ListReducerAction<ItemValue, CustomActionContext = {}> = ActionWithContext<ListAction<ItemValue>, ListActionContext<ItemValue> & CustomActionContext>;
|
21 | /**
|
22 | * The state of the list.
|
23 | * Modifications to this state should be done via the reducer.
|
24 | */
|
25 | export interface ListState<ItemValue> {
|
26 | /**
|
27 | * The item that is currently highlighted.
|
28 | */
|
29 | highlightedValue: ItemValue | null;
|
30 | /**
|
31 | * The item(s) that are currently selected.
|
32 | */
|
33 | selectedValues: ItemValue[];
|
34 | }
|
35 | /**
|
36 | * Type of the reducer that operates on the list state.
|
37 | *
|
38 | * @template ItemValue The type of the item values.
|
39 | * @template State The type of the list state. This should be a subtype of ListState<ItemValue>.
|
40 | * @template CustomActionContext The shape of additional properties that will be added to actions when dispatched.
|
41 | */
|
42 | export type ListReducer<ItemValue, State extends ListState<ItemValue>, CustomActionContext> = (state: State, action: ListReducerAction<ItemValue, CustomActionContext>) => State;
|
43 | export type FocusManagementType = 'DOM' | 'activeDescendant';
|
44 | export type SelectionMode = 'none' | 'single' | 'multiple';
|
45 | /**
|
46 | * Parameters of the useList hook.
|
47 | *
|
48 | * @template ItemValue The type of the item values.
|
49 | * @template State The type of the list state. This should be a subtype of `ListState<ItemValue>`.
|
50 | * @template CustomAction The type of the actions that can be dispatched (besides the standard ListAction).
|
51 | * @template CustomActionContext The shape of additional properties that will be added to actions when dispatched.
|
52 | */
|
53 | export interface UseListParameters<ItemValue, State extends ListState<ItemValue> = ListState<ItemValue>, CustomAction extends ControllableReducerAction = never, CustomActionContext = {}> {
|
54 | /**
|
55 | * The externally controlled values (highlighted and selected item(s)) of the list.
|
56 | * If a custom state is used, this object can contain the added state fields as well.
|
57 | *
|
58 | * @default {}
|
59 | */
|
60 | controlledProps?: Partial<State>;
|
61 | /**
|
62 | * If `true`, it will be possible to highlight disabled items.
|
63 | * @default false
|
64 | */
|
65 | disabledItemsFocusable?: boolean;
|
66 | /**
|
67 | * If `true`, the highlight will not wrap around the list if arrow keys are used.
|
68 | * @default false
|
69 | */
|
70 | disableListWrap?: boolean;
|
71 | /**
|
72 | * The focus management strategy used by the list.
|
73 | * Controls the attributes used to set focus on the list items.
|
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 of 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 any of the state items change.
|
119 | * Note that in case of `selectedValues` and `highlightedValue` the strongly typed
|
120 | * `onChange` and `onHighlightChange` callbacks are also fired.
|
121 | */
|
122 | onStateChange?: StateChangeCallback<State>;
|
123 | /**
|
124 | * The number of items skip when using the page up and page down keys.
|
125 | *
|
126 | * @default 5
|
127 | */
|
128 | pageSize?: number;
|
129 | /**
|
130 | * A function that tests equality between two items' values.
|
131 | * @default (a, b) => a === b
|
132 | */
|
133 | itemComparer?: (itemValue1: ItemValue, itemValue2: ItemValue) => boolean;
|
134 | /**
|
135 | * A function that converts an object to its string representation
|
136 | * @default (o) => o
|
137 | */
|
138 | getItemAsString?: (option: ItemValue) => string | undefined;
|
139 | /**
|
140 | * Array of list items.
|
141 | */
|
142 | items: ItemValue[];
|
143 | /**
|
144 | * Additional data to be passed to all the reducer actions.
|
145 | * It will be available in the `context` property of the action when dispatched.
|
146 | */
|
147 | reducerActionContext?: CustomActionContext;
|
148 | /**
|
149 | * Orientation of the items in the list.
|
150 | * Determines the actions that are performed when arrow keys are pressed.
|
151 | */
|
152 | orientation?: 'horizontal-ltr' | 'horizontal-rtl' | 'vertical';
|
153 | /**
|
154 | * Controls how many items can be selected at once: none (the selection functionality is disabled in this case), one, or indefinitely many.
|
155 | * @default 'single'
|
156 | */
|
157 | selectionMode?: SelectionMode;
|
158 | /**
|
159 | * Custom state reducer function. It calculates the new state (highlighted and selected items + optional custom state)
|
160 | * based on the previous one and the performed action.
|
161 | */
|
162 | stateReducer?: (state: State, action: ActionWithContext<ListAction<ItemValue> | CustomAction, ListActionContext<ItemValue> & CustomActionContext>) => State;
|
163 | }
|
164 | export interface ListItemState {
|
165 | /**
|
166 | * If `true` the item is disabled.
|
167 | */
|
168 | disabled: boolean;
|
169 | /**
|
170 | * Determines if the item is focusable (its focus is managed by the DOM).
|
171 | */
|
172 | focusable: boolean;
|
173 | /**
|
174 | * If `true` the item is highlighted.
|
175 | */
|
176 | highlighted: boolean;
|
177 | /**
|
178 | * The 0-based index of the item.
|
179 | */
|
180 | index: number;
|
181 | /**
|
182 | * If `true` the item is selected.
|
183 | */
|
184 | selected: boolean;
|
185 | }
|
186 | interface UseListRootSlotOwnProps {
|
187 | 'aria-activedescendant'?: React.AriaAttributes['aria-activedescendant'];
|
188 | onBlur: MuiCancellableEventHandler<React.FocusEvent<HTMLElement>>;
|
189 | onKeyDown: MuiCancellableEventHandler<React.KeyboardEvent<HTMLElement>>;
|
190 | tabIndex: number;
|
191 | ref: React.RefCallback<Element> | null;
|
192 | }
|
193 | export type UseListRootSlotProps<TOther = {}> = TOther & UseListRootSlotOwnProps;
|
194 | export interface UseListReturnValue<ItemValue, State extends ListState<ItemValue>, CustomAction extends ControllableReducerAction> {
|
195 | contextValue: ListContextValue<ItemValue>;
|
196 | dispatch: (action: CustomAction | ListAction<ItemValue>) => void;
|
197 | getRootProps: <TOther extends EventHandlers = {}>(otherHandlers?: TOther) => UseListRootSlotProps<TOther>;
|
198 | rootRef: React.RefCallback<Element> | null;
|
199 | state: State;
|
200 | }
|
201 | export {};
|