UNPKG

8.63 kBTypeScriptView Raw
1import * as React from 'react';
2import { Simplify } from '@mui/types';
3import { ListAction } from './listActions.types';
4import { ActionWithContext, ControllableReducerAction, StateChangeCallback } from '../utils/useControllableReducer.types';
5import { EventHandlers } from '../utils';
6import type { ListContextValue } from './ListContext';
7import { MuiCancellableEventHandler } from '../utils/muiCancellableEvent';
8type 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 */
12export 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 */
20export 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 */
25export 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 */
42export type ListReducer<ItemValue, State extends ListState<ItemValue>, CustomActionContext> = (state: State, action: ListReducerAction<ItemValue, CustomActionContext>) => State;
43export type FocusManagementType = 'DOM' | 'activeDescendant';
44export 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 */
53export 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}
164export 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}
186interface 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}
193export type UseListRootSlotProps<TOther = {}> = TOther & UseListRootSlotOwnProps;
194export 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}
201export {};