focus-trap 6.2.3 → 6.5.1
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/CHANGELOG.md +37 -0
- package/README.md +79 -61
- package/dist/focus-trap.esm.js +142 -37
- package/dist/focus-trap.esm.js.map +1 -1
- package/dist/focus-trap.esm.min.js +2 -2
- package/dist/focus-trap.esm.min.js.map +1 -1
- package/dist/focus-trap.js +142 -37
- package/dist/focus-trap.js.map +1 -1
- package/dist/focus-trap.min.js +2 -2
- package/dist/focus-trap.min.js.map +1 -1
- package/dist/focus-trap.umd.js +142 -37
- package/dist/focus-trap.umd.js.map +1 -1
- package/dist/focus-trap.umd.min.js +2 -2
- package/dist/focus-trap.umd.min.js.map +1 -1
- package/index.d.ts +61 -14
- package/index.js +133 -35
- package/package.json +33 -29
package/index.d.ts
CHANGED
|
@@ -4,19 +4,65 @@ declare module 'focus-trap' {
|
|
|
4
4
|
* `document.querySelector()` to find the DOM node), or a function that
|
|
5
5
|
* returns a DOM node.
|
|
6
6
|
*/
|
|
7
|
-
export type FocusTarget = HTMLElement | string | { (): HTMLElement };
|
|
7
|
+
export type FocusTarget = HTMLElement | SVGElement | string | { (): HTMLElement | SVGElement };
|
|
8
8
|
|
|
9
|
-
type MouseEventToBoolean = (event: MouseEvent) => boolean
|
|
9
|
+
type MouseEventToBoolean = (event: MouseEvent | TouchEvent) => boolean
|
|
10
10
|
|
|
11
11
|
export interface Options {
|
|
12
12
|
/**
|
|
13
|
-
* A function that will be called
|
|
13
|
+
* A function that will be called **before** sending focus to the
|
|
14
|
+
* target element upon activation.
|
|
14
15
|
*/
|
|
15
16
|
onActivate?: () => void;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A function that will be called **after** focus has been sent to the
|
|
20
|
+
* target element upon activation.
|
|
21
|
+
*/
|
|
22
|
+
onPostActivate?: () => void
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A function for determining if it is safe to send focus to the focus trap
|
|
26
|
+
* or not.
|
|
27
|
+
*
|
|
28
|
+
* It should return a promise that only resolves once all the listed `containers`
|
|
29
|
+
* are able to receive focus.
|
|
30
|
+
*
|
|
31
|
+
* The purpose of this is to prevent early focus-trap activation on animated
|
|
32
|
+
* dialogs that fade in and out. When a dialog fades in, there is a brief delay
|
|
33
|
+
* between the activation of the trap and the trap element being focusable.
|
|
34
|
+
*/
|
|
35
|
+
checkCanFocusTrap?: (containers: Array<HTMLElement | SVGElement>) => Promise<void>
|
|
36
|
+
|
|
16
37
|
/**
|
|
17
|
-
* A function that will be called
|
|
38
|
+
* A function that will be called **before** sending focus to the
|
|
39
|
+
* trigger element upon deactivation.
|
|
18
40
|
*/
|
|
19
41
|
onDeactivate?: () => void;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* A function that will be called after the trap is deactivated, after `onDeactivate`.
|
|
45
|
+
* If `returnFocus` was set, it will be called **after** focus has been sent to the trigger
|
|
46
|
+
* element upon deactivation; otherwise, it will be called after deactivation completes.
|
|
47
|
+
*/
|
|
48
|
+
onPostDeactivate?: () => void
|
|
49
|
+
/**
|
|
50
|
+
* A function for determining if it is safe to send focus back to the `trigger` element.
|
|
51
|
+
*
|
|
52
|
+
* It should return a promise that only resolves once `trigger` is focusable.
|
|
53
|
+
*
|
|
54
|
+
* The purpose of this is to prevent the focus being sent to an animated trigger element too early.
|
|
55
|
+
* If a trigger element fades in upon trap deactivation, there is a brief delay between the deactivation
|
|
56
|
+
* of the trap and when the trigger element is focusable.
|
|
57
|
+
*
|
|
58
|
+
* `trigger` will be either the node that had focus prior to the trap being activated,
|
|
59
|
+
* or the result of the `setReturnFocus` option, if configured.
|
|
60
|
+
*
|
|
61
|
+
* This handler is **not** called if the `returnFocusOnDeactivate` configuration option
|
|
62
|
+
* (or the `returnFocus` deactivation option) is falsy.
|
|
63
|
+
*/
|
|
64
|
+
checkCanReturnFocus?: (trigger: HTMLElement | SVGElement) => Promise<void>
|
|
65
|
+
|
|
20
66
|
/**
|
|
21
67
|
* By default, when a focus trap is activated the first element in the
|
|
22
68
|
* focus trap's tab order will receive focus. With this option you can
|
|
@@ -51,19 +97,20 @@ declare module 'focus-trap' {
|
|
|
51
97
|
*/
|
|
52
98
|
escapeDeactivates?: boolean;
|
|
53
99
|
/**
|
|
54
|
-
*
|
|
55
|
-
* deactivate the focus trap and allow the click event to do its thing.
|
|
56
|
-
*
|
|
57
|
-
* to `true
|
|
100
|
+
* If `true` or returns `true`, a click outside the focus trap will
|
|
101
|
+
* deactivate the focus trap and allow the click event to do its thing (i.e.
|
|
102
|
+
* to pass-through to the element that was clicked). This option **takes
|
|
103
|
+
* precedence** over `allowOutsideClick` when it's set to `true`, causing
|
|
104
|
+
* that option to be ignored. Default: `false`.
|
|
58
105
|
*/
|
|
59
|
-
clickOutsideDeactivates?: boolean;
|
|
106
|
+
clickOutsideDeactivates?: boolean | MouseEventToBoolean;
|
|
60
107
|
/**
|
|
61
108
|
* If set and is or returns `true`, a click outside the focus trap will not
|
|
62
109
|
* be prevented, even when `clickOutsideDeactivates` is `false`. When
|
|
63
110
|
* `clickOutsideDeactivates` is `true`, this option is **ignored** (i.e.
|
|
64
111
|
* if it's a function, it will not be called). Use this option to control
|
|
65
112
|
* if (and even which) clicks are allowed outside the trap in conjunction
|
|
66
|
-
* with `clickOutsideDeactivates: false`.
|
|
113
|
+
* with `clickOutsideDeactivates: false`. Default: `false`.
|
|
67
114
|
*/
|
|
68
115
|
allowOutsideClick?: boolean | MouseEventToBoolean;
|
|
69
116
|
/**
|
|
@@ -80,9 +127,9 @@ declare module 'focus-trap' {
|
|
|
80
127
|
delayInitialFocus?: boolean;
|
|
81
128
|
}
|
|
82
129
|
|
|
83
|
-
type ActivateOptions = Pick<Options, 'onActivate'>;
|
|
130
|
+
type ActivateOptions = Pick<Options, 'onActivate' | 'onPostActivate' | 'checkCanFocusTrap'>;
|
|
84
131
|
|
|
85
|
-
interface DeactivateOptions extends Pick<Options, 'onDeactivate'> {
|
|
132
|
+
interface DeactivateOptions extends Pick<Options, 'onDeactivate' | 'onPostDeactivate' | 'checkCanReturnFocus'> {
|
|
86
133
|
returnFocus?: boolean;
|
|
87
134
|
}
|
|
88
135
|
|
|
@@ -91,7 +138,7 @@ declare module 'focus-trap' {
|
|
|
91
138
|
deactivate(deactivateOptions?: DeactivateOptions): FocusTrap;
|
|
92
139
|
pause(): FocusTrap;
|
|
93
140
|
unpause(): FocusTrap;
|
|
94
|
-
updateContainerElements(containerElements: HTMLElement | string | Array<HTMLElement | string>): FocusTrap;
|
|
141
|
+
updateContainerElements(containerElements: HTMLElement | SVGElement | string | Array<HTMLElement | SVGElement | string>): FocusTrap;
|
|
95
142
|
}
|
|
96
143
|
|
|
97
144
|
/**
|
|
@@ -102,7 +149,7 @@ declare module 'focus-trap' {
|
|
|
102
149
|
* find the element.
|
|
103
150
|
*/
|
|
104
151
|
export function createFocusTrap(
|
|
105
|
-
element: HTMLElement | string | Array<HTMLElement | string>,
|
|
152
|
+
element: HTMLElement | SVGElement | string | Array<HTMLElement | SVGElement | string>,
|
|
106
153
|
userOptions?: Options
|
|
107
154
|
): FocusTrap;
|
|
108
155
|
}
|
package/index.js
CHANGED
|
@@ -73,6 +73,17 @@ const findIndex = function (arr, fn) {
|
|
|
73
73
|
return idx;
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Get an option's value when it could be a plain value, or a handler that provides
|
|
78
|
+
* the value.
|
|
79
|
+
* @param {*} value Option's value to check.
|
|
80
|
+
* @param {...*} [params] Any parameters to pass to the handler, if `value` is a function.
|
|
81
|
+
* @returns {*} The `value`, or the handler's returned value.
|
|
82
|
+
*/
|
|
83
|
+
const valueOrHandler = function (value, ...params) {
|
|
84
|
+
return typeof value === 'function' ? value(...params) : value;
|
|
85
|
+
};
|
|
86
|
+
|
|
76
87
|
const createFocusTrap = function (elements, userOptions) {
|
|
77
88
|
const doc = document;
|
|
78
89
|
|
|
@@ -93,7 +104,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
93
104
|
// is active, but the trap should never get to a state where there isn't at least one group
|
|
94
105
|
// with at least one tabbable node in it (that would lead to an error condition that would
|
|
95
106
|
// result in an error being thrown)
|
|
96
|
-
// @type {Array<{ firstTabbableNode: HTMLElement|null, lastTabbableNode: HTMLElement|null }>}
|
|
107
|
+
// @type {Array<{ container: HTMLElement, firstTabbableNode: HTMLElement|null, lastTabbableNode: HTMLElement|null }>}
|
|
97
108
|
tabbableGroups: [],
|
|
98
109
|
|
|
99
110
|
nodeFocusedBeforeActivation: null,
|
|
@@ -104,6 +115,13 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
104
115
|
|
|
105
116
|
let trap; // eslint-disable-line prefer-const -- some private functions reference it, and its methods reference private functions, so we must declare here and define later
|
|
106
117
|
|
|
118
|
+
const getOption = (configOverrideOptions, optionName, configOptionName) => {
|
|
119
|
+
return configOverrideOptions &&
|
|
120
|
+
configOverrideOptions[optionName] !== undefined
|
|
121
|
+
? configOverrideOptions[optionName]
|
|
122
|
+
: config[configOptionName || optionName];
|
|
123
|
+
};
|
|
124
|
+
|
|
107
125
|
const containersContain = function (element) {
|
|
108
126
|
return state.containers.some((container) => container.contains(element));
|
|
109
127
|
};
|
|
@@ -163,6 +181,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
163
181
|
|
|
164
182
|
if (tabbableNodes.length > 0) {
|
|
165
183
|
return {
|
|
184
|
+
container,
|
|
166
185
|
firstTabbableNode: tabbableNodes[0],
|
|
167
186
|
lastTabbableNode: tabbableNodes[tabbableNodes.length - 1],
|
|
168
187
|
};
|
|
@@ -214,7 +233,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
214
233
|
return;
|
|
215
234
|
}
|
|
216
235
|
|
|
217
|
-
if (config.clickOutsideDeactivates) {
|
|
236
|
+
if (valueOrHandler(config.clickOutsideDeactivates, e)) {
|
|
218
237
|
// immediately deactivate the trap
|
|
219
238
|
trap.deactivate({
|
|
220
239
|
// if, on deactivation, we should return focus to the node originally-focused
|
|
@@ -236,12 +255,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
236
255
|
// This is needed for mobile devices.
|
|
237
256
|
// (If we'll only let `click` events through,
|
|
238
257
|
// then on mobile they will be blocked anyways if `touchstart` is blocked.)
|
|
239
|
-
if (
|
|
240
|
-
config.allowOutsideClick &&
|
|
241
|
-
(typeof config.allowOutsideClick === 'boolean'
|
|
242
|
-
? config.allowOutsideClick
|
|
243
|
-
: config.allowOutsideClick(e))
|
|
244
|
-
) {
|
|
258
|
+
if (valueOrHandler(config.allowOutsideClick, e)) {
|
|
245
259
|
// allow the click outside the trap to take place
|
|
246
260
|
return;
|
|
247
261
|
}
|
|
@@ -275,13 +289,48 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
275
289
|
let destinationNode = null;
|
|
276
290
|
|
|
277
291
|
if (state.tabbableGroups.length > 0) {
|
|
278
|
-
|
|
279
|
-
|
|
292
|
+
// make sure the target is actually contained in a group
|
|
293
|
+
// NOTE: the target may also be the container itself if it's tabbable
|
|
294
|
+
// with tabIndex='-1' and was given initial focus
|
|
295
|
+
const containerIndex = findIndex(state.tabbableGroups, ({ container }) =>
|
|
296
|
+
container.contains(e.target)
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
if (containerIndex < 0) {
|
|
300
|
+
// target not found in any group: quite possible focus has escaped the trap,
|
|
301
|
+
// so bring it back in to...
|
|
302
|
+
if (e.shiftKey) {
|
|
303
|
+
// ...the last node in the last group
|
|
304
|
+
destinationNode =
|
|
305
|
+
state.tabbableGroups[state.tabbableGroups.length - 1]
|
|
306
|
+
.lastTabbableNode;
|
|
307
|
+
} else {
|
|
308
|
+
// ...the first node in the first group
|
|
309
|
+
destinationNode = state.tabbableGroups[0].firstTabbableNode;
|
|
310
|
+
}
|
|
311
|
+
} else if (e.shiftKey) {
|
|
312
|
+
// REVERSE
|
|
313
|
+
|
|
314
|
+
// is the target the first tabbable node in a group?
|
|
315
|
+
let startOfGroupIndex = findIndex(
|
|
280
316
|
state.tabbableGroups,
|
|
281
317
|
({ firstTabbableNode }) => e.target === firstTabbableNode
|
|
282
318
|
);
|
|
283
319
|
|
|
320
|
+
if (
|
|
321
|
+
startOfGroupIndex < 0 &&
|
|
322
|
+
state.tabbableGroups[containerIndex].container === e.target
|
|
323
|
+
) {
|
|
324
|
+
// an exception case where the target is the container itself, in which
|
|
325
|
+
// case, we should handle shift+tab as if focus were on the container's
|
|
326
|
+
// first tabbable node, and go to the last tabbable node of the LAST group
|
|
327
|
+
startOfGroupIndex = containerIndex;
|
|
328
|
+
}
|
|
329
|
+
|
|
284
330
|
if (startOfGroupIndex >= 0) {
|
|
331
|
+
// YES: then shift+tab should go to the last tabbable node in the
|
|
332
|
+
// previous group (and wrap around to the last tabbable node of
|
|
333
|
+
// the LAST group if it's the first tabbable node of the FIRST group)
|
|
285
334
|
const destinationGroupIndex =
|
|
286
335
|
startOfGroupIndex === 0
|
|
287
336
|
? state.tabbableGroups.length - 1
|
|
@@ -291,12 +340,28 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
291
340
|
destinationNode = destinationGroup.lastTabbableNode;
|
|
292
341
|
}
|
|
293
342
|
} else {
|
|
294
|
-
|
|
343
|
+
// FORWARD
|
|
344
|
+
|
|
345
|
+
// is the target the last tabbable node in a group?
|
|
346
|
+
let lastOfGroupIndex = findIndex(
|
|
295
347
|
state.tabbableGroups,
|
|
296
348
|
({ lastTabbableNode }) => e.target === lastTabbableNode
|
|
297
349
|
);
|
|
298
350
|
|
|
351
|
+
if (
|
|
352
|
+
lastOfGroupIndex < 0 &&
|
|
353
|
+
state.tabbableGroups[containerIndex].container === e.target
|
|
354
|
+
) {
|
|
355
|
+
// an exception case where the target is the container itself, in which
|
|
356
|
+
// case, we should handle tab as if focus were on the container's
|
|
357
|
+
// last tabbable node, and go to the first tabbable node of the FIRST group
|
|
358
|
+
lastOfGroupIndex = containerIndex;
|
|
359
|
+
}
|
|
360
|
+
|
|
299
361
|
if (lastOfGroupIndex >= 0) {
|
|
362
|
+
// YES: then tab should go to the first tabbable node in the next
|
|
363
|
+
// group (and wrap around to the first tabbable node of the FIRST
|
|
364
|
+
// group if it's the last tabbable node of the LAST group)
|
|
300
365
|
const destinationGroupIndex =
|
|
301
366
|
lastOfGroupIndex === state.tabbableGroups.length - 1
|
|
302
367
|
? 0
|
|
@@ -314,6 +379,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
314
379
|
e.preventDefault();
|
|
315
380
|
tryFocus(destinationNode);
|
|
316
381
|
}
|
|
382
|
+
// else, let the browser take care of [shift+]tab and move the focus
|
|
317
383
|
};
|
|
318
384
|
|
|
319
385
|
const checkKey = function (e) {
|
|
@@ -330,7 +396,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
330
396
|
};
|
|
331
397
|
|
|
332
398
|
const checkClick = function (e) {
|
|
333
|
-
if (config.clickOutsideDeactivates) {
|
|
399
|
+
if (valueOrHandler(config.clickOutsideDeactivates, e)) {
|
|
334
400
|
return;
|
|
335
401
|
}
|
|
336
402
|
|
|
@@ -338,12 +404,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
338
404
|
return;
|
|
339
405
|
}
|
|
340
406
|
|
|
341
|
-
if (
|
|
342
|
-
config.allowOutsideClick &&
|
|
343
|
-
(typeof config.allowOutsideClick === 'boolean'
|
|
344
|
-
? config.allowOutsideClick
|
|
345
|
-
: config.allowOutsideClick(e))
|
|
346
|
-
) {
|
|
407
|
+
if (valueOrHandler(config.allowOutsideClick, e)) {
|
|
347
408
|
return;
|
|
348
409
|
}
|
|
349
410
|
|
|
@@ -416,21 +477,41 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
416
477
|
return this;
|
|
417
478
|
}
|
|
418
479
|
|
|
419
|
-
|
|
480
|
+
const onActivate = getOption(activateOptions, 'onActivate');
|
|
481
|
+
const onPostActivate = getOption(activateOptions, 'onPostActivate');
|
|
482
|
+
const checkCanFocusTrap = getOption(activateOptions, 'checkCanFocusTrap');
|
|
483
|
+
|
|
484
|
+
if (!checkCanFocusTrap) {
|
|
485
|
+
updateTabbableNodes();
|
|
486
|
+
}
|
|
420
487
|
|
|
421
488
|
state.active = true;
|
|
422
489
|
state.paused = false;
|
|
423
490
|
state.nodeFocusedBeforeActivation = doc.activeElement;
|
|
424
491
|
|
|
425
|
-
const onActivate =
|
|
426
|
-
activateOptions && activateOptions.onActivate
|
|
427
|
-
? activateOptions.onActivate
|
|
428
|
-
: config.onActivate;
|
|
429
492
|
if (onActivate) {
|
|
430
493
|
onActivate();
|
|
431
494
|
}
|
|
432
495
|
|
|
433
|
-
|
|
496
|
+
const finishActivation = () => {
|
|
497
|
+
if (checkCanFocusTrap) {
|
|
498
|
+
updateTabbableNodes();
|
|
499
|
+
}
|
|
500
|
+
addListeners();
|
|
501
|
+
if (onPostActivate) {
|
|
502
|
+
onPostActivate();
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
if (checkCanFocusTrap) {
|
|
507
|
+
checkCanFocusTrap(state.containers.concat()).then(
|
|
508
|
+
finishActivation,
|
|
509
|
+
finishActivation
|
|
510
|
+
);
|
|
511
|
+
return this;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
finishActivation();
|
|
434
515
|
return this;
|
|
435
516
|
},
|
|
436
517
|
|
|
@@ -447,25 +528,42 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
447
528
|
|
|
448
529
|
activeFocusTraps.deactivateTrap(trap);
|
|
449
530
|
|
|
450
|
-
const onDeactivate =
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
531
|
+
const onDeactivate = getOption(deactivateOptions, 'onDeactivate');
|
|
532
|
+
const onPostDeactivate = getOption(deactivateOptions, 'onPostDeactivate');
|
|
533
|
+
const checkCanReturnFocus = getOption(
|
|
534
|
+
deactivateOptions,
|
|
535
|
+
'checkCanReturnFocus'
|
|
536
|
+
);
|
|
537
|
+
|
|
454
538
|
if (onDeactivate) {
|
|
455
539
|
onDeactivate();
|
|
456
540
|
}
|
|
457
541
|
|
|
458
|
-
const returnFocus =
|
|
459
|
-
deactivateOptions
|
|
460
|
-
|
|
461
|
-
|
|
542
|
+
const returnFocus = getOption(
|
|
543
|
+
deactivateOptions,
|
|
544
|
+
'returnFocus',
|
|
545
|
+
'returnFocusOnDeactivate'
|
|
546
|
+
);
|
|
462
547
|
|
|
463
|
-
|
|
464
|
-
delay(
|
|
465
|
-
|
|
548
|
+
const finishDeactivation = () => {
|
|
549
|
+
delay(() => {
|
|
550
|
+
if (returnFocus) {
|
|
551
|
+
tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
|
|
552
|
+
}
|
|
553
|
+
if (onPostDeactivate) {
|
|
554
|
+
onPostDeactivate();
|
|
555
|
+
}
|
|
466
556
|
});
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
if (returnFocus && checkCanReturnFocus) {
|
|
560
|
+
checkCanReturnFocus(
|
|
561
|
+
getReturnFocusNode(state.nodeFocusedBeforeActivation)
|
|
562
|
+
).then(finishDeactivation, finishDeactivation);
|
|
563
|
+
return this;
|
|
467
564
|
}
|
|
468
565
|
|
|
566
|
+
finishDeactivation();
|
|
469
567
|
return this;
|
|
470
568
|
},
|
|
471
569
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "focus-trap",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.5.1",
|
|
4
4
|
"description": "Trap focus within a DOM node.",
|
|
5
5
|
"main": "dist/focus-trap.js",
|
|
6
6
|
"module": "dist/focus-trap.esm.js",
|
|
@@ -17,22 +17,24 @@
|
|
|
17
17
|
"dist"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
|
-
"demo-bundle": "browserify
|
|
21
|
-
"format": "prettier --write \"{*,src/**/*,test/**/*,
|
|
22
|
-
"format:check": "prettier --check \"{*,src/**/*,test/**/*,
|
|
23
|
-
"
|
|
20
|
+
"demo-bundle": "browserify docs/js/index.js -o docs/demo-bundle.js",
|
|
21
|
+
"format": "prettier --write \"{*,src/**/*,test/**/*,docs/js/**/*,.github/workflows/*,cypress/**/*}.+(js|yml)\"",
|
|
22
|
+
"format:check": "prettier --check \"{*,src/**/*,test/**/*,docs/js/**/*,.github/workflows/*,cypress/**/*}.+(js|yml)\"",
|
|
23
|
+
"format:watch": "onchange \"{*,src/**/*,test/**/*,docs/js/**/*,.github/workflows/*,cypress/**/*}.+(js|yml)\" -- prettier --write {{changed}}",
|
|
24
|
+
"lint": "eslint \"*.js\" \"docs/js/**/*.js\" \"cypress/**/*.js\"",
|
|
24
25
|
"clean": "rm -rf ./dist",
|
|
25
|
-
"compile:esm": "BUILD_ENV=esm BABEL_ENV=esm rollup -c",
|
|
26
|
-
"compile:cjs": "BUILD_ENV=cjs BABEL_ENV=es5 rollup -c",
|
|
27
|
-
"compile:umd": "BUILD_ENV=umd BABEL_ENV=es5 rollup -c",
|
|
26
|
+
"compile:esm": "cross-env BUILD_ENV=esm BABEL_ENV=esm rollup -c",
|
|
27
|
+
"compile:cjs": "cross-env BUILD_ENV=cjs BABEL_ENV=es5 rollup -c",
|
|
28
|
+
"compile:umd": "cross-env BUILD_ENV=umd BABEL_ENV=es5 rollup -c",
|
|
28
29
|
"compile": "yarn compile:esm && yarn compile:cjs && yarn compile:umd",
|
|
29
30
|
"build": "yarn clean && yarn compile",
|
|
30
|
-
"start": "yarn compile:cjs && budo
|
|
31
|
+
"start": "yarn compile:cjs && budo docs/js/index.js:demo-bundle.js --dir docs --live -- -t babelify",
|
|
31
32
|
"test:types": "tsc index.d.ts",
|
|
32
33
|
"test:unit": "echo \"No unit tests to run!\"",
|
|
33
34
|
"test:cypress": "start-server-and-test start 9966 'cypress open'",
|
|
34
|
-
"test:cypress
|
|
35
|
-
"test": "
|
|
35
|
+
"test:cypress:ci": "start-server-and-test start 9966 'cypress run --browser $CYPRESS_BROWSER --headless'",
|
|
36
|
+
"test:chrome": "CYPRESS_BROWSER=chrome yarn test:cypress:ci",
|
|
37
|
+
"test": "yarn format:check && yarn lint && yarn test:unit && yarn test:types && CYPRESS_BROWSER=chrome yarn test:cypress:ci",
|
|
36
38
|
"prepare": "yarn build",
|
|
37
39
|
"release": "yarn build && changeset publish"
|
|
38
40
|
},
|
|
@@ -58,34 +60,36 @@
|
|
|
58
60
|
},
|
|
59
61
|
"homepage": "https://github.com/focus-trap/focus-trap#readme",
|
|
60
62
|
"dependencies": {
|
|
61
|
-
"tabbable": "^5.
|
|
63
|
+
"tabbable": "^5.2.0"
|
|
62
64
|
},
|
|
63
65
|
"devDependencies": {
|
|
64
|
-
"@babel/cli": "^7.
|
|
65
|
-
"@babel/core": "^7.
|
|
66
|
-
"@babel/preset-env": "^7.
|
|
67
|
-
"@changesets/cli": "^2.
|
|
68
|
-
"@rollup/plugin-babel": "^5.
|
|
69
|
-
"@rollup/plugin-commonjs": "^
|
|
70
|
-
"@rollup/plugin-node-resolve": "^
|
|
71
|
-
"@testing-library/cypress": "^7.0.
|
|
66
|
+
"@babel/cli": "^7.14.5",
|
|
67
|
+
"@babel/core": "^7.14.6",
|
|
68
|
+
"@babel/preset-env": "^7.14.5",
|
|
69
|
+
"@changesets/cli": "^2.16.0",
|
|
70
|
+
"@rollup/plugin-babel": "^5.3.0",
|
|
71
|
+
"@rollup/plugin-commonjs": "^19.0.0",
|
|
72
|
+
"@rollup/plugin-node-resolve": "^13.0.0",
|
|
73
|
+
"@testing-library/cypress": "^7.0.6",
|
|
72
74
|
"@types/jquery": "^3.5.5",
|
|
73
|
-
"all-contributors-cli": "^6.
|
|
75
|
+
"all-contributors-cli": "^6.20.0",
|
|
74
76
|
"babel-eslint": "^10.1.0",
|
|
75
77
|
"babel-loader": "^8.2.2",
|
|
76
78
|
"babelify": "^10.0.0",
|
|
77
79
|
"browserify": "^17.0.0",
|
|
78
80
|
"budo": "^11.6.4",
|
|
79
|
-
"
|
|
81
|
+
"cross-env": "^7.0.3",
|
|
82
|
+
"cypress": "^7.5.0",
|
|
80
83
|
"cypress-plugin-tab": "^1.0.5",
|
|
81
|
-
"eslint": "^7.
|
|
82
|
-
"eslint-config-prettier": "^
|
|
83
|
-
"eslint-plugin-cypress": "^2.11.
|
|
84
|
-
"
|
|
85
|
-
"
|
|
84
|
+
"eslint": "^7.28.0",
|
|
85
|
+
"eslint-config-prettier": "^8.3.0",
|
|
86
|
+
"eslint-plugin-cypress": "^2.11.3",
|
|
87
|
+
"onchange": "^7.1.0",
|
|
88
|
+
"prettier": "^2.3.1",
|
|
89
|
+
"rollup": "^2.51.2",
|
|
86
90
|
"rollup-plugin-sourcemaps": "^0.6.3",
|
|
87
91
|
"rollup-plugin-terser": "^7.0.1",
|
|
88
|
-
"start-server-and-test": "^1.
|
|
89
|
-
"typescript": "^4.
|
|
92
|
+
"start-server-and-test": "^1.12.5",
|
|
93
|
+
"typescript": "^4.3.2"
|
|
90
94
|
}
|
|
91
95
|
}
|