@lumx/react 4.0.1-alpha.8 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +1 -1
- package/index.js.map +1 -1
- package/package.json +5 -5
- package/utils/index.d.ts +263 -1
- package/utils/index.js +1405 -0
- package/utils/index.js.map +1 -1
package/package.json
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
"url": "https://github.com/lumapps/design-system/issues"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@lumx/core": "^4.
|
|
10
|
-
"@lumx/icons": "^4.
|
|
9
|
+
"@lumx/core": "^4.1.0",
|
|
10
|
+
"@lumx/icons": "^4.1.0",
|
|
11
11
|
"@popperjs/core": "^2.5.4",
|
|
12
12
|
"body-scroll-lock": "^3.1.5",
|
|
13
13
|
"react-popper": "^2.2.4"
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"focus-visible": "^5.0.2",
|
|
42
42
|
"glob": "^7.1.6",
|
|
43
43
|
"jsdom": "^27.2.0",
|
|
44
|
-
"lodash": "4.17.
|
|
44
|
+
"lodash": "4.17.23",
|
|
45
45
|
"react": "^18.3.1",
|
|
46
46
|
"react-dom": "^18.3.1",
|
|
47
47
|
"rollup": "^4.53.3",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"vitest": "^3.0.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"lodash": "4.17.
|
|
61
|
+
"lodash": "4.17.23",
|
|
62
62
|
"react": ">= 17.0.2",
|
|
63
63
|
"react-dom": ">= 17.0.2"
|
|
64
64
|
},
|
|
@@ -90,5 +90,5 @@
|
|
|
90
90
|
"build:storybook": "storybook build"
|
|
91
91
|
},
|
|
92
92
|
"sideEffects": false,
|
|
93
|
-
"version": "4.
|
|
93
|
+
"version": "4.1.0"
|
|
94
94
|
}
|
package/utils/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React__default, { RefObject } from 'react';
|
|
2
2
|
import { Falsy } from '@lumx/core/js/types';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import { ObjectValues } from '@lumx/core/src/js/types/ObjectValues';
|
|
4
5
|
|
|
5
6
|
interface ClickAwayParameters {
|
|
6
7
|
/**
|
|
@@ -78,5 +79,266 @@ declare function DisabledStateProvider({ children, ...value }: DisabledStateProv
|
|
|
78
79
|
*/
|
|
79
80
|
declare function useDisabledStateContext(): DisabledStateContextValue;
|
|
80
81
|
|
|
81
|
-
|
|
82
|
+
declare const LOOP_AROUND_TYPES: {
|
|
83
|
+
/**
|
|
84
|
+
* Will continue navigation to the next row or column and loop back to the start
|
|
85
|
+
* when the last tab stop is reached
|
|
86
|
+
*/
|
|
87
|
+
readonly nextLoop: "next-loop";
|
|
88
|
+
/**
|
|
89
|
+
* Will continue navigation to the next row or column until
|
|
90
|
+
* the last tab stop is reached
|
|
91
|
+
*/
|
|
92
|
+
readonly nextEnd: "next-end";
|
|
93
|
+
/**
|
|
94
|
+
* Will loop within the current row or column
|
|
95
|
+
*/
|
|
96
|
+
readonly inside: "inside";
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Base hook options
|
|
101
|
+
*/
|
|
102
|
+
type BaseHookOptions = [
|
|
103
|
+
/**
|
|
104
|
+
* The DOM element to include.
|
|
105
|
+
* This must be the same DOM element for the lifetime of the containing component.
|
|
106
|
+
*/
|
|
107
|
+
ref: React.RefObject<Element>,
|
|
108
|
+
/**
|
|
109
|
+
* Whether or not the DOM element is currently enabled. This value can be updated as appropriate throughout the
|
|
110
|
+
* lifetime of the containing component.
|
|
111
|
+
*/
|
|
112
|
+
disabled?: boolean,
|
|
113
|
+
/**
|
|
114
|
+
* An optional string value that must be populated if the roving tabindex is being used in a grid. In that case,
|
|
115
|
+
* set it to a unique key for all tabStops part of the same row that the given DOM element is currently part of. You can update this
|
|
116
|
+
* row key as appropriate throughout the lifetime of the containing component, for example if the shape of the
|
|
117
|
+
* grid can change dynamically.
|
|
118
|
+
*/
|
|
119
|
+
rowKey?: string | number | null,
|
|
120
|
+
/** Whether the tab stop should be set as selected by default */
|
|
121
|
+
autofocus?: boolean
|
|
122
|
+
];
|
|
123
|
+
type KeyDirection = 'horizontal' | 'vertical' | 'both';
|
|
124
|
+
type LoopTypes = ObjectValues<typeof LOOP_AROUND_TYPES>;
|
|
125
|
+
/**
|
|
126
|
+
* The behavior to set when the end of a column or row is reached
|
|
127
|
+
*/
|
|
128
|
+
type LoopAroundByAxis = {
|
|
129
|
+
col: LoopTypes;
|
|
130
|
+
row: LoopTypes;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* The LoopAround behavior to have.
|
|
134
|
+
* Can be a boolean as a shortcut
|
|
135
|
+
*
|
|
136
|
+
* * true => { row: 'next-loop', col: 'next-loop' }
|
|
137
|
+
* * false => { row: 'next-end', col: 'next-end' }
|
|
138
|
+
*/
|
|
139
|
+
type LoopAround = LoopAroundByAxis | boolean;
|
|
140
|
+
interface MovingFocusOptions {
|
|
141
|
+
/**
|
|
142
|
+
* An optional direction value that only applies when the roving tabindex is not being used within a grid.
|
|
143
|
+
* This value specifies the arrow key behaviour.
|
|
144
|
+
* The default value is 'horizontal'.
|
|
145
|
+
* When set to 'horizontal' then only the ArrowLeft and ArrowRight keys move to the previous and next tab stop
|
|
146
|
+
* respectively.
|
|
147
|
+
* When set to 'vertical' then only the ArrowUp and ArrowDown keys move to the previous and next tab stop
|
|
148
|
+
* respectively.
|
|
149
|
+
* When set to 'both' then both the ArrowLeft and ArrowUp keys can be used to move to the previous tab stop, and
|
|
150
|
+
* both the ArrowRight and ArrowDown keys can be used to move to the next tab stop.
|
|
151
|
+
* If you do not pass an explicit value then the 'horizontal' behaviour applies.
|
|
152
|
+
*/
|
|
153
|
+
direction: KeyDirection;
|
|
154
|
+
/**
|
|
155
|
+
* Direction in which initial virtual focus must be set focused on the virtual focus parent.
|
|
156
|
+
* Ex: With `firstFocusDirection: vertical`, pressing "left" and "right" arrows while virtual focus is
|
|
157
|
+
* not enabled yet will do nothing.
|
|
158
|
+
* /!\ Only used with `virtualFocus` hooks.
|
|
159
|
+
*/
|
|
160
|
+
firstFocusDirection?: KeyDirection;
|
|
161
|
+
/**
|
|
162
|
+
* An optional flag that, when set to `true`, will loop the tabindex around when the user tries to tab to the
|
|
163
|
+
* first or last elements in the roving tabindex, rather than stopping.
|
|
164
|
+
* The default value is `false` (no looping).
|
|
165
|
+
* Note that this option does not apply if the roving tabindex is being used on a grid.
|
|
166
|
+
*/
|
|
167
|
+
loopAround: LoopAround;
|
|
168
|
+
/**
|
|
169
|
+
* Id of the tab stop should accept focus if selectedId is undefined.
|
|
170
|
+
*/
|
|
171
|
+
defaultSelectedId: string | null;
|
|
172
|
+
/**
|
|
173
|
+
* Autofocus first or last item after the list/grid is mounted.
|
|
174
|
+
*/
|
|
175
|
+
autofocus?: 'first' | 'last';
|
|
176
|
+
/**
|
|
177
|
+
* The axis on which the "skip" shortcuts (home / end) must function.
|
|
178
|
+
*/
|
|
179
|
+
gridJumpToShortcutDirection?: 'vertical' | 'horizontal';
|
|
180
|
+
/**
|
|
181
|
+
* Enable default selected item focusing
|
|
182
|
+
*
|
|
183
|
+
* Note: The `allowFocusing` state property is set at "false" by default until an interaction is made.
|
|
184
|
+
* This is required to delay focusing of the selected tab stop DOM element
|
|
185
|
+
* until the user has started interacting with the roving tabindex's controls.
|
|
186
|
+
* If this delay did not occur, the selected control would be focused as soon as it was mounted, which is
|
|
187
|
+
* unlikely to be the desired behaviour for the page.
|
|
188
|
+
*/
|
|
189
|
+
allowFocusing: boolean;
|
|
190
|
+
/**
|
|
191
|
+
* An optional an unique key.
|
|
192
|
+
* If this key is set, tab stops will be re-registered each time the key changes.
|
|
193
|
+
* If this key is unset, tab stops will only be registered on mount and unregistered on unmount.
|
|
194
|
+
*
|
|
195
|
+
* This can be useful to set if you have cases where your tab stops might be reordered without being unmounted.
|
|
196
|
+
*/
|
|
197
|
+
listKey?: string;
|
|
198
|
+
}
|
|
199
|
+
type TabStopRowKey = string | number;
|
|
200
|
+
type BaseTypeStop = {
|
|
201
|
+
id: string;
|
|
202
|
+
domElementRef: React.RefObject<Element>;
|
|
203
|
+
disabled: boolean;
|
|
204
|
+
rowKey: TabStopRowKey | null;
|
|
205
|
+
autofocus?: boolean;
|
|
206
|
+
};
|
|
207
|
+
type TabStop = Readonly<BaseTypeStop>;
|
|
208
|
+
type GridMap = {
|
|
209
|
+
tabStopsByRowKey: Record<TabStopRowKey, TabStop[]>;
|
|
210
|
+
rowKeys: Array<TabStopRowKey>;
|
|
211
|
+
};
|
|
212
|
+
type State = Readonly<{
|
|
213
|
+
/**
|
|
214
|
+
* Id of the tab stop that can currently accept focus.
|
|
215
|
+
*/
|
|
216
|
+
selectedId: string | null;
|
|
217
|
+
/** Whether the user is currently using keyboard navigation */
|
|
218
|
+
isUsingKeyboard: boolean;
|
|
219
|
+
/**
|
|
220
|
+
* Array of tab stops
|
|
221
|
+
*/
|
|
222
|
+
tabStops: readonly TabStop[];
|
|
223
|
+
/**
|
|
224
|
+
* Note: The gridMap is only created if row-related navigation occurs (e.g., move to row start or end).
|
|
225
|
+
* The map gets cleared if registering, unregistering, or updating.
|
|
226
|
+
*/
|
|
227
|
+
gridMap: GridMap | null;
|
|
228
|
+
/** The loop behavior to apply to the columns and rows */
|
|
229
|
+
loopAround: LoopAroundByAxis;
|
|
230
|
+
} & Omit<MovingFocusOptions, 'loopAround'>>;
|
|
231
|
+
type RegisterAction = {
|
|
232
|
+
type: 'REGISTER_TAB_STOP';
|
|
233
|
+
payload: TabStop;
|
|
234
|
+
};
|
|
235
|
+
type UnregisterAction = {
|
|
236
|
+
type: 'UNREGISTER_TAB_STOP';
|
|
237
|
+
payload: {
|
|
238
|
+
id: TabStop['id'];
|
|
239
|
+
};
|
|
240
|
+
};
|
|
241
|
+
type UpdateTabStopAction = {
|
|
242
|
+
type: 'UPDATE_TAB_STOP';
|
|
243
|
+
payload: Pick<TabStop, 'id' | 'rowKey' | 'disabled'>;
|
|
244
|
+
};
|
|
245
|
+
type KeyNavAction = {
|
|
246
|
+
type: 'KEY_NAV';
|
|
247
|
+
payload: {
|
|
248
|
+
id?: TabStop['id'];
|
|
249
|
+
key: string;
|
|
250
|
+
ctrlKey: boolean;
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
type SetAllowFocusingAction = {
|
|
254
|
+
type: 'SET_ALLOW_FOCUSING';
|
|
255
|
+
payload: {
|
|
256
|
+
allow: boolean;
|
|
257
|
+
isKeyboardNavigation?: boolean;
|
|
258
|
+
};
|
|
259
|
+
};
|
|
260
|
+
type ResetSelectedTabStopAction = {
|
|
261
|
+
type: 'RESET_SELECTED_TAB_STOP';
|
|
262
|
+
};
|
|
263
|
+
type SelectTabStopAction = {
|
|
264
|
+
type: 'SELECT_TAB_STOP';
|
|
265
|
+
payload: {
|
|
266
|
+
id: TabStop['id'];
|
|
267
|
+
type?: 'pointer' | 'keyboard';
|
|
268
|
+
};
|
|
269
|
+
};
|
|
270
|
+
type OptionsUpdatedAction = {
|
|
271
|
+
type: 'OPTIONS_UPDATED';
|
|
272
|
+
payload: MovingFocusOptions;
|
|
273
|
+
};
|
|
274
|
+
type Action = RegisterAction | UnregisterAction | UpdateTabStopAction | KeyNavAction | SelectTabStopAction | OptionsUpdatedAction | SetAllowFocusingAction | ResetSelectedTabStopAction;
|
|
275
|
+
|
|
276
|
+
interface MovingFocusProviderProps {
|
|
277
|
+
/**
|
|
278
|
+
* The child content, which will include the DOM elements to rove between using the tab key.
|
|
279
|
+
*/
|
|
280
|
+
children: React__default.ReactNode;
|
|
281
|
+
/**
|
|
282
|
+
* An optional object to customize the behaviour of the moving focus. It is fine to pass a new object every time
|
|
283
|
+
* the containing component is rendered, and the options can be updated at any time.
|
|
284
|
+
*/
|
|
285
|
+
options?: Partial<MovingFocusOptions>;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Creates a roving tabindex context.
|
|
289
|
+
*/
|
|
290
|
+
declare const MovingFocusProvider: React__default.FC<MovingFocusProviderProps>;
|
|
291
|
+
|
|
292
|
+
type MovingFocusContext = Readonly<{
|
|
293
|
+
state: State;
|
|
294
|
+
dispatch: React__default.Dispatch<Action>;
|
|
295
|
+
}>;
|
|
296
|
+
declare const MovingFocusContext: React__default.Context<Readonly<{
|
|
297
|
+
state: State;
|
|
298
|
+
dispatch: React__default.Dispatch<Action>;
|
|
299
|
+
}>>;
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Hook options
|
|
303
|
+
*/
|
|
304
|
+
type Options = [
|
|
305
|
+
/** The DOM id of the tab stop. */
|
|
306
|
+
id: string,
|
|
307
|
+
...baseOptions: BaseHookOptions
|
|
308
|
+
];
|
|
309
|
+
/**
|
|
310
|
+
* Hook to use in tab stop element of a virtual focus (ex: options of a listbox in a combobox).
|
|
311
|
+
*
|
|
312
|
+
* @returns true if the current tab stop has virtual focus
|
|
313
|
+
*/
|
|
314
|
+
declare const useVirtualFocus: (...args: Options) => boolean;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Hook to use in a virtual focus parent (ex: `aria-activedescendant` on the input of a combobox).
|
|
318
|
+
* * @returns the id of the currently active tab stop (virtual focus)
|
|
319
|
+
*/
|
|
320
|
+
declare const useVirtualFocusParent: (ref: React__default.RefObject<HTMLElement>) => string | undefined;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* A tuple of values to be applied by the containing component for the roving tabindex to work correctly.
|
|
324
|
+
*/
|
|
325
|
+
type Output = [
|
|
326
|
+
/** The tabIndex value to apply to the tab stop element. */
|
|
327
|
+
tabIndex: number,
|
|
328
|
+
/** Whether focus() should be invoked on the tab stop element. */
|
|
329
|
+
focused: boolean,
|
|
330
|
+
/**
|
|
331
|
+
* The onKeyDown callback to apply to the tab stop element. If the key press is relevant to the hook then
|
|
332
|
+
* event.preventDefault() will be invoked on the event.
|
|
333
|
+
*/
|
|
334
|
+
handleKeyDown: (event: React__default.KeyboardEvent) => void,
|
|
335
|
+
/** The onClick callback to apply to the tab stop element. */
|
|
336
|
+
handleClick: () => void
|
|
337
|
+
];
|
|
338
|
+
/**
|
|
339
|
+
* Includes the given DOM element in the current roving tabindex.
|
|
340
|
+
*/
|
|
341
|
+
declare const useRovingTabIndex: (...args: BaseHookOptions) => Output;
|
|
342
|
+
|
|
343
|
+
export { ClickAwayProvider, DisabledStateProvider, MovingFocusContext, MovingFocusProvider, Portal, PortalProvider, useDisabledStateContext, useRovingTabIndex, useVirtualFocus, useVirtualFocusParent };
|
|
82
344
|
export type { PortalInit, PortalProps, PortalProviderProps };
|