UNPKG

9.02 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 type { ListContextValue } from './ListContext';
6import { MuiCancellableEventHandler } from '../utils/MuiCancellableEvent';
7type 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 */
11export 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 */
19export 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 */
24export 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 */
41export type ListReducer<ItemValue, State extends ListState<ItemValue>, CustomActionContext> = (state: State, action: ListReducerAction<ItemValue, CustomActionContext>) => State;
42export type FocusManagementType = 'DOM' | 'activeDescendant';
43export 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 */
52export 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}
176export 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}
190interface 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}
197export type UseListRootSlotProps<ExternalProps = {}> = ExternalProps & UseListRootSlotOwnProps;
198export 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}
210export {};