focus-trap 6.5.0 → 6.7.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/CHANGELOG.md +56 -0
- package/README.md +31 -13
- package/dist/focus-trap.esm.js +102 -51
- 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 +102 -51
- 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 +105 -54
- 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 +36 -11
- package/index.js +114 -52
- package/package.json +30 -28
package/index.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { tabbable, isFocusable } from 'tabbable';
|
|
2
2
|
|
|
3
|
-
let activeFocusDelay;
|
|
4
|
-
|
|
5
3
|
const activeFocusTraps = (function () {
|
|
6
4
|
const trapQueue = [];
|
|
7
5
|
return {
|
|
@@ -84,8 +82,21 @@ const valueOrHandler = function (value, ...params) {
|
|
|
84
82
|
return typeof value === 'function' ? value(...params) : value;
|
|
85
83
|
};
|
|
86
84
|
|
|
85
|
+
const getActualTarget = function (event) {
|
|
86
|
+
// NOTE: If the trap is _inside_ a shadow DOM, event.target will always be the
|
|
87
|
+
// shadow host. However, event.target.composedPath() will be an array of
|
|
88
|
+
// nodes "clicked" from inner-most (the actual element inside the shadow) to
|
|
89
|
+
// outer-most (the host HTML document). If we have access to composedPath(),
|
|
90
|
+
// then use its first element; otherwise, fall back to event.target (and
|
|
91
|
+
// this only works for an _open_ shadow DOM; otherwise,
|
|
92
|
+
// composedPath()[0] === event.target always).
|
|
93
|
+
return event.target.shadowRoot && typeof event.composedPath === 'function'
|
|
94
|
+
? event.composedPath()[0]
|
|
95
|
+
: event.target;
|
|
96
|
+
};
|
|
97
|
+
|
|
87
98
|
const createFocusTrap = function (elements, userOptions) {
|
|
88
|
-
const doc = document;
|
|
99
|
+
const doc = userOptions.document || document;
|
|
89
100
|
|
|
90
101
|
const config = {
|
|
91
102
|
returnFocusOnDeactivate: true,
|
|
@@ -111,6 +122,10 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
111
122
|
mostRecentlyFocusedNode: null,
|
|
112
123
|
active: false,
|
|
113
124
|
paused: false,
|
|
125
|
+
|
|
126
|
+
// timer ID for when delayInitialFocus is true and initial focus in this trap
|
|
127
|
+
// has been delayed during activation
|
|
128
|
+
delayInitialFocusTimer: undefined,
|
|
114
129
|
};
|
|
115
130
|
|
|
116
131
|
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
|
|
@@ -123,28 +138,51 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
123
138
|
};
|
|
124
139
|
|
|
125
140
|
const containersContain = function (element) {
|
|
126
|
-
return
|
|
141
|
+
return !!(
|
|
142
|
+
element &&
|
|
143
|
+
state.containers.some((container) => container.contains(element))
|
|
144
|
+
);
|
|
127
145
|
};
|
|
128
146
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Gets the node for the given option, which is expected to be an option that
|
|
149
|
+
* can be either a DOM node, a string that is a selector to get a node, `false`
|
|
150
|
+
* (if a node is explicitly NOT given), or a function that returns any of these
|
|
151
|
+
* values.
|
|
152
|
+
* @param {string} optionName
|
|
153
|
+
* @returns {undefined | false | HTMLElement | SVGElement} Returns
|
|
154
|
+
* `undefined` if the option is not specified; `false` if the option
|
|
155
|
+
* resolved to `false` (node explicitly not given); otherwise, the resolved
|
|
156
|
+
* DOM node.
|
|
157
|
+
* @throws {Error} If the option is set, not `false`, and is not, or does not
|
|
158
|
+
* resolve to a node.
|
|
159
|
+
*/
|
|
160
|
+
const getNodeForOption = function (optionName, ...params) {
|
|
161
|
+
let optionValue = config[optionName];
|
|
134
162
|
|
|
135
|
-
|
|
163
|
+
if (typeof optionValue === 'function') {
|
|
164
|
+
optionValue = optionValue(...params);
|
|
165
|
+
}
|
|
136
166
|
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
throw new Error(`\`${optionName}\` refers to no known node`);
|
|
167
|
+
if (!optionValue) {
|
|
168
|
+
if (optionValue === undefined || optionValue === false) {
|
|
169
|
+
return optionValue;
|
|
141
170
|
}
|
|
171
|
+
// else, empty string (invalid), null (invalid), 0 (invalid)
|
|
172
|
+
|
|
173
|
+
throw new Error(
|
|
174
|
+
`\`${optionName}\` was specified but was not a node, or did not return a node`
|
|
175
|
+
);
|
|
142
176
|
}
|
|
143
177
|
|
|
144
|
-
|
|
145
|
-
|
|
178
|
+
let node = optionValue; // could be HTMLElement, SVGElement, or non-empty string at this point
|
|
179
|
+
|
|
180
|
+
if (typeof optionValue === 'string') {
|
|
181
|
+
node = doc.querySelector(optionValue); // resolve to node, or null if fails
|
|
146
182
|
if (!node) {
|
|
147
|
-
throw new Error(
|
|
183
|
+
throw new Error(
|
|
184
|
+
`\`${optionName}\` as selector refers to no known node`
|
|
185
|
+
);
|
|
148
186
|
}
|
|
149
187
|
}
|
|
150
188
|
|
|
@@ -152,17 +190,25 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
152
190
|
};
|
|
153
191
|
|
|
154
192
|
const getInitialFocusNode = function () {
|
|
155
|
-
let node;
|
|
193
|
+
let node = getNodeForOption('initialFocus');
|
|
156
194
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
195
|
+
// false explicitly indicates we want no initialFocus at all
|
|
196
|
+
if (node === false) {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (node === undefined) {
|
|
201
|
+
// option not specified: use fallback options
|
|
202
|
+
if (containersContain(doc.activeElement)) {
|
|
203
|
+
node = doc.activeElement;
|
|
204
|
+
} else {
|
|
205
|
+
const firstTabbableGroup = state.tabbableGroups[0];
|
|
206
|
+
const firstTabbableNode =
|
|
207
|
+
firstTabbableGroup && firstTabbableGroup.firstTabbableNode;
|
|
208
|
+
|
|
209
|
+
// NOTE: `fallbackFocus` option function cannot return `false` (not supported)
|
|
210
|
+
node = firstTabbableNode || getNodeForOption('fallbackFocus');
|
|
211
|
+
}
|
|
166
212
|
}
|
|
167
213
|
|
|
168
214
|
if (!node) {
|
|
@@ -194,7 +240,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
194
240
|
// throw if no groups have tabbable nodes and we don't have a fallback focus node either
|
|
195
241
|
if (
|
|
196
242
|
state.tabbableGroups.length <= 0 &&
|
|
197
|
-
!getNodeForOption('fallbackFocus')
|
|
243
|
+
!getNodeForOption('fallbackFocus') // returning false not supported for this option
|
|
198
244
|
) {
|
|
199
245
|
throw new Error(
|
|
200
246
|
'Your focus-trap must have at least one container with at least one tabbable node in it at all times'
|
|
@@ -203,9 +249,14 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
203
249
|
};
|
|
204
250
|
|
|
205
251
|
const tryFocus = function (node) {
|
|
252
|
+
if (node === false) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
206
256
|
if (node === doc.activeElement) {
|
|
207
257
|
return;
|
|
208
258
|
}
|
|
259
|
+
|
|
209
260
|
if (!node || !node.focus) {
|
|
210
261
|
tryFocus(getInitialFocusNode());
|
|
211
262
|
return;
|
|
@@ -220,15 +271,16 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
220
271
|
};
|
|
221
272
|
|
|
222
273
|
const getReturnFocusNode = function (previousActiveElement) {
|
|
223
|
-
const node = getNodeForOption('setReturnFocus');
|
|
224
|
-
|
|
225
|
-
return node ? node : previousActiveElement;
|
|
274
|
+
const node = getNodeForOption('setReturnFocus', previousActiveElement);
|
|
275
|
+
return node ? node : node === false ? false : previousActiveElement;
|
|
226
276
|
};
|
|
227
277
|
|
|
228
278
|
// This needs to be done on mousedown and touchstart instead of click
|
|
229
279
|
// so that it precedes the focus event.
|
|
230
280
|
const checkPointerDown = function (e) {
|
|
231
|
-
|
|
281
|
+
const target = getActualTarget(e);
|
|
282
|
+
|
|
283
|
+
if (containersContain(target)) {
|
|
232
284
|
// allow the click since it ocurred inside the trap
|
|
233
285
|
return;
|
|
234
286
|
}
|
|
@@ -247,7 +299,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
247
299
|
// that was clicked, whether it's focusable or not; by setting
|
|
248
300
|
// `returnFocus: true`, we'll attempt to re-focus the node originally-focused
|
|
249
301
|
// on activation (or the configured `setReturnFocus` node)
|
|
250
|
-
returnFocus: config.returnFocusOnDeactivate && !isFocusable(
|
|
302
|
+
returnFocus: config.returnFocusOnDeactivate && !isFocusable(target),
|
|
251
303
|
});
|
|
252
304
|
return;
|
|
253
305
|
}
|
|
@@ -266,11 +318,13 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
266
318
|
|
|
267
319
|
// In case focus escapes the trap for some strange reason, pull it back in.
|
|
268
320
|
const checkFocusIn = function (e) {
|
|
269
|
-
const
|
|
321
|
+
const target = getActualTarget(e);
|
|
322
|
+
const targetContained = containersContain(target);
|
|
323
|
+
|
|
270
324
|
// In Firefox when you Tab out of an iframe the Document is briefly focused.
|
|
271
|
-
if (targetContained ||
|
|
325
|
+
if (targetContained || target instanceof Document) {
|
|
272
326
|
if (targetContained) {
|
|
273
|
-
state.mostRecentlyFocusedNode =
|
|
327
|
+
state.mostRecentlyFocusedNode = target;
|
|
274
328
|
}
|
|
275
329
|
} else {
|
|
276
330
|
// escaped! pull it back in to where it just left
|
|
@@ -284,6 +338,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
284
338
|
// moment it can end up scrolling the page and causing confusion so we
|
|
285
339
|
// kind of need to capture the action at the keydown phase.
|
|
286
340
|
const checkTab = function (e) {
|
|
341
|
+
const target = getActualTarget(e);
|
|
287
342
|
updateTabbableNodes();
|
|
288
343
|
|
|
289
344
|
let destinationNode = null;
|
|
@@ -293,7 +348,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
293
348
|
// NOTE: the target may also be the container itself if it's tabbable
|
|
294
349
|
// with tabIndex='-1' and was given initial focus
|
|
295
350
|
const containerIndex = findIndex(state.tabbableGroups, ({ container }) =>
|
|
296
|
-
container.contains(
|
|
351
|
+
container.contains(target)
|
|
297
352
|
);
|
|
298
353
|
|
|
299
354
|
if (containerIndex < 0) {
|
|
@@ -314,12 +369,12 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
314
369
|
// is the target the first tabbable node in a group?
|
|
315
370
|
let startOfGroupIndex = findIndex(
|
|
316
371
|
state.tabbableGroups,
|
|
317
|
-
({ firstTabbableNode }) =>
|
|
372
|
+
({ firstTabbableNode }) => target === firstTabbableNode
|
|
318
373
|
);
|
|
319
374
|
|
|
320
375
|
if (
|
|
321
376
|
startOfGroupIndex < 0 &&
|
|
322
|
-
state.tabbableGroups[containerIndex].container ===
|
|
377
|
+
state.tabbableGroups[containerIndex].container === target
|
|
323
378
|
) {
|
|
324
379
|
// an exception case where the target is the container itself, in which
|
|
325
380
|
// case, we should handle shift+tab as if focus were on the container's
|
|
@@ -345,12 +400,12 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
345
400
|
// is the target the last tabbable node in a group?
|
|
346
401
|
let lastOfGroupIndex = findIndex(
|
|
347
402
|
state.tabbableGroups,
|
|
348
|
-
({ lastTabbableNode }) =>
|
|
403
|
+
({ lastTabbableNode }) => target === lastTabbableNode
|
|
349
404
|
);
|
|
350
405
|
|
|
351
406
|
if (
|
|
352
407
|
lastOfGroupIndex < 0 &&
|
|
353
|
-
state.tabbableGroups[containerIndex].container ===
|
|
408
|
+
state.tabbableGroups[containerIndex].container === target
|
|
354
409
|
) {
|
|
355
410
|
// an exception case where the target is the container itself, in which
|
|
356
411
|
// case, we should handle tab as if focus were on the container's
|
|
@@ -372,6 +427,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
372
427
|
}
|
|
373
428
|
}
|
|
374
429
|
} else {
|
|
430
|
+
// NOTE: the fallbackFocus option does not support returning false to opt-out
|
|
375
431
|
destinationNode = getNodeForOption('fallbackFocus');
|
|
376
432
|
}
|
|
377
433
|
|
|
@@ -383,7 +439,10 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
383
439
|
};
|
|
384
440
|
|
|
385
441
|
const checkKey = function (e) {
|
|
386
|
-
if (
|
|
442
|
+
if (
|
|
443
|
+
isEscapeEvent(e) &&
|
|
444
|
+
valueOrHandler(config.escapeDeactivates, e) !== false
|
|
445
|
+
) {
|
|
387
446
|
e.preventDefault();
|
|
388
447
|
trap.deactivate();
|
|
389
448
|
return;
|
|
@@ -400,7 +459,9 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
400
459
|
return;
|
|
401
460
|
}
|
|
402
461
|
|
|
403
|
-
|
|
462
|
+
const target = getActualTarget(e);
|
|
463
|
+
|
|
464
|
+
if (containersContain(target)) {
|
|
404
465
|
return;
|
|
405
466
|
}
|
|
406
467
|
|
|
@@ -426,7 +487,7 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
426
487
|
|
|
427
488
|
// Delay ensures that the focused element doesn't capture the event
|
|
428
489
|
// that caused the focus trap activation.
|
|
429
|
-
|
|
490
|
+
state.delayInitialFocusTimer = config.delayInitialFocus
|
|
430
491
|
? delay(function () {
|
|
431
492
|
tryFocus(getInitialFocusNode());
|
|
432
493
|
})
|
|
@@ -520,7 +581,8 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
520
581
|
return this;
|
|
521
582
|
}
|
|
522
583
|
|
|
523
|
-
clearTimeout(
|
|
584
|
+
clearTimeout(state.delayInitialFocusTimer); // noop if undefined
|
|
585
|
+
state.delayInitialFocusTimer = undefined;
|
|
524
586
|
|
|
525
587
|
removeListeners();
|
|
526
588
|
state.active = false;
|
|
@@ -546,14 +608,14 @@ const createFocusTrap = function (elements, userOptions) {
|
|
|
546
608
|
);
|
|
547
609
|
|
|
548
610
|
const finishDeactivation = () => {
|
|
549
|
-
|
|
550
|
-
|
|
611
|
+
delay(() => {
|
|
612
|
+
if (returnFocus) {
|
|
551
613
|
tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
556
|
-
}
|
|
614
|
+
}
|
|
615
|
+
if (onPostDeactivate) {
|
|
616
|
+
onPostDeactivate();
|
|
617
|
+
}
|
|
618
|
+
});
|
|
557
619
|
};
|
|
558
620
|
|
|
559
621
|
if (returnFocus && checkCanReturnFocus) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "focus-trap",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.7.0",
|
|
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": "
|
|
21
|
-
"format": "prettier --write \"{*,src/**/*,test/**/*,
|
|
22
|
-
"format:check": "prettier --check \"{*,src/**/*,test/**/*,
|
|
23
|
-
"format:watch": "onchange \"{*,src/**/*,test/**/*,
|
|
24
|
-
"lint": "eslint \"*.js\" \"
|
|
20
|
+
"demo-bundle": "yarn compile:demo",
|
|
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\"",
|
|
25
25
|
"clean": "rm -rf ./dist",
|
|
26
26
|
"compile:esm": "cross-env BUILD_ENV=esm BABEL_ENV=esm rollup -c",
|
|
27
27
|
"compile:cjs": "cross-env BUILD_ENV=cjs BABEL_ENV=es5 rollup -c",
|
|
28
28
|
"compile:umd": "cross-env BUILD_ENV=umd BABEL_ENV=es5 rollup -c",
|
|
29
|
+
"compile:demo": "cross-env BUILD_ENV=demo BABEL_ENV=es5 rollup -c",
|
|
29
30
|
"compile": "yarn compile:esm && yarn compile:cjs && yarn compile:umd",
|
|
30
31
|
"build": "yarn clean && yarn compile",
|
|
31
|
-
"start": "yarn compile:
|
|
32
|
+
"start": "yarn compile:demo --watch --environment SERVE,RELOAD,IS_CYPRESS_ENV:''",
|
|
33
|
+
"start:cypress": "yarn compile:demo --environment SERVE,IS_CYPRESS_ENV:\"$CYPRESS_BROWSER\"",
|
|
32
34
|
"test:types": "tsc index.d.ts",
|
|
33
35
|
"test:unit": "echo \"No unit tests to run!\"",
|
|
34
|
-
"test:cypress": "start-server-and-test start 9966 'cypress open'",
|
|
35
|
-
"test:cypress:ci": "start-server-and-test start 9966 'cypress run --browser $CYPRESS_BROWSER --headless'",
|
|
36
|
+
"test:cypress": "CYPRESS_BROWSER=ANY start-server-and-test start:cypress 9966 'cypress open'",
|
|
37
|
+
"test:cypress:ci": "start-server-and-test start:cypress 9966 'cypress run --browser $CYPRESS_BROWSER --headless'",
|
|
36
38
|
"test:chrome": "CYPRESS_BROWSER=chrome yarn test:cypress:ci",
|
|
37
39
|
"test": "yarn format:check && yarn lint && yarn test:unit && yarn test:types && CYPRESS_BROWSER=chrome yarn test:cypress:ci",
|
|
38
40
|
"prepare": "yarn build",
|
|
@@ -60,36 +62,36 @@
|
|
|
60
62
|
},
|
|
61
63
|
"homepage": "https://github.com/focus-trap/focus-trap#readme",
|
|
62
64
|
"dependencies": {
|
|
63
|
-
"tabbable": "^5.2.
|
|
65
|
+
"tabbable": "^5.2.1"
|
|
64
66
|
},
|
|
65
67
|
"devDependencies": {
|
|
66
|
-
"@babel/cli": "^7.
|
|
67
|
-
"@babel/core": "^7.
|
|
68
|
-
"@babel/preset-env": "^7.
|
|
69
|
-
"@changesets/cli": "^2.
|
|
68
|
+
"@babel/cli": "^7.15.7",
|
|
69
|
+
"@babel/core": "^7.15.5",
|
|
70
|
+
"@babel/preset-env": "^7.15.6",
|
|
71
|
+
"@changesets/cli": "^2.17.0",
|
|
70
72
|
"@rollup/plugin-babel": "^5.3.0",
|
|
71
|
-
"@rollup/plugin-commonjs": "^
|
|
72
|
-
"@rollup/plugin-node-resolve": "^13.0.
|
|
73
|
-
"@testing-library/cypress": "^
|
|
74
|
-
"@types/jquery": "^3.5.
|
|
73
|
+
"@rollup/plugin-commonjs": "^20.0.0",
|
|
74
|
+
"@rollup/plugin-node-resolve": "^13.0.5",
|
|
75
|
+
"@testing-library/cypress": "^8.0.1",
|
|
76
|
+
"@types/jquery": "^3.5.6",
|
|
75
77
|
"all-contributors-cli": "^6.20.0",
|
|
76
78
|
"babel-eslint": "^10.1.0",
|
|
77
79
|
"babel-loader": "^8.2.2",
|
|
78
|
-
"babelify": "^10.0.0",
|
|
79
|
-
"browserify": "^17.0.0",
|
|
80
|
-
"budo": "^11.6.4",
|
|
81
80
|
"cross-env": "^7.0.3",
|
|
82
|
-
"cypress": "^
|
|
81
|
+
"cypress": "^8.4.1",
|
|
83
82
|
"cypress-plugin-tab": "^1.0.5",
|
|
84
|
-
"eslint": "^7.
|
|
83
|
+
"eslint": "^7.32.0",
|
|
85
84
|
"eslint-config-prettier": "^8.3.0",
|
|
86
|
-
"eslint-plugin-cypress": "^2.
|
|
85
|
+
"eslint-plugin-cypress": "^2.12.1",
|
|
87
86
|
"onchange": "^7.1.0",
|
|
88
|
-
"prettier": "^2.
|
|
89
|
-
"rollup": "^2.
|
|
87
|
+
"prettier": "^2.4.1",
|
|
88
|
+
"rollup": "^2.57.0",
|
|
89
|
+
"rollup-plugin-inject-process-env": "^1.3.1",
|
|
90
|
+
"rollup-plugin-livereload": "^2.0.5",
|
|
91
|
+
"rollup-plugin-serve": "^1.1.0",
|
|
90
92
|
"rollup-plugin-sourcemaps": "^0.6.3",
|
|
91
93
|
"rollup-plugin-terser": "^7.0.1",
|
|
92
|
-
"start-server-and-test": "^1.
|
|
93
|
-
"typescript": "^4.3
|
|
94
|
+
"start-server-and-test": "^1.14.0",
|
|
95
|
+
"typescript": "^4.4.3"
|
|
94
96
|
}
|
|
95
97
|
}
|