@chancestv/tv-focus 0.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/dist/index.js ADDED
@@ -0,0 +1,1351 @@
1
+ import { inject, onMounted, onUnmounted, provide, shallowRef, ref, getCurrentInstance, onActivated, onDeactivated, defineComponent, openBlock, createBlock, resolveDynamicComponent, normalizeClass, unref, withCtx, renderSlot } from "vue";
2
+ var $ = null;
3
+ var GlobalConfig = {
4
+ selector: "",
5
+ // can be a valid <extSelector> except "@" syntax.
6
+ straightOnly: false,
7
+ straightOverlapThreshold: 0.5,
8
+ rememberSource: false,
9
+ disabled: false,
10
+ defaultElement: "",
11
+ // <extSelector> except "@" syntax.
12
+ enterTo: "",
13
+ // '', 'last-focused', 'default-element'
14
+ leaveFor: null,
15
+ // {left: <extSelector>, right: <extSelector>,
16
+ // up: <extSelector>, down: <extSelector>}
17
+ restrict: "self-first",
18
+ // 'self-first', 'self-only', 'none'
19
+ tabIndexIgnoreList: "a, input, select, textarea, button, iframe, [contentEditable=true]",
20
+ navigableFilter: null
21
+ };
22
+ var KEYMAPPING = {
23
+ "37": "left",
24
+ "38": "up",
25
+ "39": "right",
26
+ "40": "down"
27
+ };
28
+ var REVERSE = {
29
+ "left": "right",
30
+ "up": "down",
31
+ "right": "left",
32
+ "down": "up"
33
+ };
34
+ var EVENT_PREFIX = "sn:";
35
+ var ID_POOL_PREFIX = "section-";
36
+ var _idPool = 0;
37
+ var _ready = false;
38
+ var _pause = false;
39
+ var _sections = {};
40
+ var _sectionCount = 0;
41
+ var _defaultSectionId = "";
42
+ var _lastSectionId = "";
43
+ var _duringFocusChange = false;
44
+ var elementMatchesSelector = Element.prototype.matches || Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || function(selector) {
45
+ var matchedNodes = (this.parentNode || this.document).querySelectorAll(selector);
46
+ return [].slice.call(matchedNodes).indexOf(this) >= 0;
47
+ };
48
+ function getRect(elem) {
49
+ var cr = elem.getBoundingClientRect();
50
+ var rect = {
51
+ left: cr.left,
52
+ top: cr.top,
53
+ right: cr.right,
54
+ bottom: cr.bottom,
55
+ width: cr.width,
56
+ height: cr.height
57
+ };
58
+ rect.element = elem;
59
+ rect.center = {
60
+ x: rect.left + Math.floor(rect.width / 2),
61
+ y: rect.top + Math.floor(rect.height / 2)
62
+ };
63
+ rect.center.left = rect.center.right = rect.center.x;
64
+ rect.center.top = rect.center.bottom = rect.center.y;
65
+ return rect;
66
+ }
67
+ function partition(rects, targetRect, straightOverlapThreshold) {
68
+ var groups = [[], [], [], [], [], [], [], [], []];
69
+ for (var i = 0; i < rects.length; i++) {
70
+ var rect = rects[i];
71
+ var center = rect.center;
72
+ var x, y, groupId;
73
+ if (center.x < targetRect.left) {
74
+ x = 0;
75
+ } else if (center.x <= targetRect.right) {
76
+ x = 1;
77
+ } else {
78
+ x = 2;
79
+ }
80
+ if (center.y < targetRect.top) {
81
+ y = 0;
82
+ } else if (center.y <= targetRect.bottom) {
83
+ y = 1;
84
+ } else {
85
+ y = 2;
86
+ }
87
+ groupId = y * 3 + x;
88
+ groups[groupId].push(rect);
89
+ if ([0, 2, 6, 8].indexOf(groupId) !== -1) {
90
+ var threshold = straightOverlapThreshold;
91
+ if (rect.left <= targetRect.right - targetRect.width * threshold) {
92
+ if (groupId === 2) {
93
+ groups[1].push(rect);
94
+ } else if (groupId === 8) {
95
+ groups[7].push(rect);
96
+ }
97
+ }
98
+ if (rect.right >= targetRect.left + targetRect.width * threshold) {
99
+ if (groupId === 0) {
100
+ groups[1].push(rect);
101
+ } else if (groupId === 6) {
102
+ groups[7].push(rect);
103
+ }
104
+ }
105
+ if (rect.top <= targetRect.bottom - targetRect.height * threshold) {
106
+ if (groupId === 6) {
107
+ groups[3].push(rect);
108
+ } else if (groupId === 8) {
109
+ groups[5].push(rect);
110
+ }
111
+ }
112
+ if (rect.bottom >= targetRect.top + targetRect.height * threshold) {
113
+ if (groupId === 0) {
114
+ groups[3].push(rect);
115
+ } else if (groupId === 2) {
116
+ groups[5].push(rect);
117
+ }
118
+ }
119
+ }
120
+ }
121
+ return groups;
122
+ }
123
+ function generateDistanceFunction(targetRect) {
124
+ return {
125
+ nearPlumbLineIsBetter: function(rect) {
126
+ var d;
127
+ if (rect.center.x < targetRect.center.x) {
128
+ d = targetRect.center.x - rect.right;
129
+ } else {
130
+ d = rect.left - targetRect.center.x;
131
+ }
132
+ return d < 0 ? 0 : d;
133
+ },
134
+ nearHorizonIsBetter: function(rect) {
135
+ var d;
136
+ if (rect.center.y < targetRect.center.y) {
137
+ d = targetRect.center.y - rect.bottom;
138
+ } else {
139
+ d = rect.top - targetRect.center.y;
140
+ }
141
+ return d < 0 ? 0 : d;
142
+ },
143
+ nearTargetLeftIsBetter: function(rect) {
144
+ var d;
145
+ if (rect.center.x < targetRect.center.x) {
146
+ d = targetRect.left - rect.right;
147
+ } else {
148
+ d = rect.left - targetRect.left;
149
+ }
150
+ return d < 0 ? 0 : d;
151
+ },
152
+ nearTargetTopIsBetter: function(rect) {
153
+ var d;
154
+ if (rect.center.y < targetRect.center.y) {
155
+ d = targetRect.top - rect.bottom;
156
+ } else {
157
+ d = rect.top - targetRect.top;
158
+ }
159
+ return d < 0 ? 0 : d;
160
+ },
161
+ topIsBetter: function(rect) {
162
+ return rect.top;
163
+ },
164
+ bottomIsBetter: function(rect) {
165
+ return -1 * rect.bottom;
166
+ },
167
+ leftIsBetter: function(rect) {
168
+ return rect.left;
169
+ },
170
+ rightIsBetter: function(rect) {
171
+ return -1 * rect.right;
172
+ }
173
+ };
174
+ }
175
+ function prioritize(priorities) {
176
+ var destPriority = null;
177
+ for (var i = 0; i < priorities.length; i++) {
178
+ if (priorities[i].group.length) {
179
+ destPriority = priorities[i];
180
+ break;
181
+ }
182
+ }
183
+ if (!destPriority) {
184
+ return null;
185
+ }
186
+ var destDistance = destPriority.distance;
187
+ destPriority.group.sort(function(a, b) {
188
+ for (var i2 = 0; i2 < destDistance.length; i2++) {
189
+ var distance = destDistance[i2];
190
+ var delta = distance(a) - distance(b);
191
+ if (delta) {
192
+ return delta;
193
+ }
194
+ }
195
+ return 0;
196
+ });
197
+ return destPriority.group;
198
+ }
199
+ function navigate(target, direction, candidates, config, preferNearest) {
200
+ if (!target || !direction || !candidates || !candidates.length) {
201
+ return null;
202
+ }
203
+ var rects = [];
204
+ for (var i = 0; i < candidates.length; i++) {
205
+ var rect = getRect(candidates[i]);
206
+ if (rect) {
207
+ rects.push(rect);
208
+ }
209
+ }
210
+ if (!rects.length) {
211
+ return null;
212
+ }
213
+ var targetRect = getRect(target);
214
+ if (!targetRect) {
215
+ return null;
216
+ }
217
+ var distanceFunction = generateDistanceFunction(targetRect);
218
+ var groups = partition(
219
+ rects,
220
+ targetRect,
221
+ config.straightOverlapThreshold
222
+ );
223
+ var internalGroups = partition(
224
+ groups[4],
225
+ targetRect.center,
226
+ config.straightOverlapThreshold
227
+ );
228
+ var priorities;
229
+ var df = distanceFunction;
230
+ var internalGroup, straightGroup, diagonalGroups;
231
+ var internalDist, straightDist, diagonalDist, mergedDist;
232
+ switch (direction) {
233
+ case "left":
234
+ internalGroup = internalGroups[0].concat(internalGroups[3]).concat(internalGroups[6]);
235
+ straightGroup = groups[3];
236
+ diagonalGroups = groups[0].concat(groups[6]);
237
+ internalDist = [df.nearPlumbLineIsBetter, df.topIsBetter];
238
+ straightDist = [df.nearPlumbLineIsBetter, df.topIsBetter];
239
+ diagonalDist = [
240
+ df.nearHorizonIsBetter,
241
+ df.rightIsBetter,
242
+ df.nearTargetTopIsBetter
243
+ ];
244
+ mergedDist = [
245
+ df.nearPlumbLineIsBetter,
246
+ df.nearHorizonIsBetter,
247
+ df.topIsBetter
248
+ ];
249
+ break;
250
+ case "right":
251
+ internalGroup = internalGroups[2].concat(internalGroups[5]).concat(internalGroups[8]);
252
+ straightGroup = groups[5];
253
+ diagonalGroups = groups[2].concat(groups[8]);
254
+ internalDist = [df.nearPlumbLineIsBetter, df.topIsBetter];
255
+ straightDist = [df.nearPlumbLineIsBetter, df.topIsBetter];
256
+ diagonalDist = [
257
+ df.nearHorizonIsBetter,
258
+ df.leftIsBetter,
259
+ df.nearTargetTopIsBetter
260
+ ];
261
+ mergedDist = [
262
+ df.nearPlumbLineIsBetter,
263
+ df.nearHorizonIsBetter,
264
+ df.topIsBetter
265
+ ];
266
+ break;
267
+ case "up":
268
+ internalGroup = internalGroups[0].concat(internalGroups[1]).concat(internalGroups[2]);
269
+ straightGroup = groups[1];
270
+ diagonalGroups = groups[0].concat(groups[2]);
271
+ internalDist = [df.nearHorizonIsBetter, df.leftIsBetter];
272
+ straightDist = [df.nearHorizonIsBetter, df.leftIsBetter];
273
+ diagonalDist = [
274
+ df.nearPlumbLineIsBetter,
275
+ df.bottomIsBetter,
276
+ df.nearTargetLeftIsBetter
277
+ ];
278
+ mergedDist = [
279
+ df.nearHorizonIsBetter,
280
+ df.nearPlumbLineIsBetter,
281
+ df.leftIsBetter
282
+ ];
283
+ break;
284
+ case "down":
285
+ internalGroup = internalGroups[6].concat(internalGroups[7]).concat(internalGroups[8]);
286
+ straightGroup = groups[7];
287
+ diagonalGroups = groups[6].concat(groups[8]);
288
+ internalDist = [df.nearHorizonIsBetter, df.leftIsBetter];
289
+ straightDist = [df.nearHorizonIsBetter, df.leftIsBetter];
290
+ diagonalDist = [
291
+ df.nearPlumbLineIsBetter,
292
+ df.topIsBetter,
293
+ df.nearTargetLeftIsBetter
294
+ ];
295
+ mergedDist = [
296
+ df.nearHorizonIsBetter,
297
+ df.nearPlumbLineIsBetter,
298
+ df.leftIsBetter
299
+ ];
300
+ break;
301
+ default:
302
+ return null;
303
+ }
304
+ if (preferNearest) {
305
+ priorities = [
306
+ { group: internalGroup, distance: internalDist },
307
+ {
308
+ group: config.straightOnly ? straightGroup : straightGroup.concat(diagonalGroups),
309
+ distance: mergedDist
310
+ }
311
+ ];
312
+ } else {
313
+ priorities = [
314
+ { group: internalGroup, distance: internalDist },
315
+ { group: straightGroup, distance: straightDist },
316
+ { group: diagonalGroups, distance: diagonalDist }
317
+ ];
318
+ if (config.straightOnly) {
319
+ priorities.pop();
320
+ }
321
+ }
322
+ var destGroup = prioritize(priorities);
323
+ if (!destGroup) {
324
+ return null;
325
+ }
326
+ var dest = null;
327
+ if (config.rememberSource && config.previous && config.previous.destination === target && config.previous.reverse === direction) {
328
+ for (var j = 0; j < destGroup.length; j++) {
329
+ if (destGroup[j].element === config.previous.target) {
330
+ dest = destGroup[j].element;
331
+ break;
332
+ }
333
+ }
334
+ }
335
+ if (!dest) {
336
+ dest = destGroup[0].element;
337
+ }
338
+ return dest;
339
+ }
340
+ function generateId() {
341
+ var id;
342
+ while (true) {
343
+ id = ID_POOL_PREFIX + String(++_idPool);
344
+ if (!_sections[id]) {
345
+ break;
346
+ }
347
+ }
348
+ return id;
349
+ }
350
+ function parseSelector(selector) {
351
+ var result = [];
352
+ try {
353
+ if (selector) {
354
+ if ($) ;
355
+ else if (typeof selector === "string") {
356
+ result = [].slice.call(document.querySelectorAll(selector));
357
+ } else if (typeof selector === "object" && selector.length) {
358
+ result = [].slice.call(selector);
359
+ } else if (typeof selector === "object" && selector.nodeType === 1) {
360
+ result = [selector];
361
+ }
362
+ }
363
+ } catch (err) {
364
+ console.error(err);
365
+ }
366
+ return result;
367
+ }
368
+ function matchSelector(elem, selector) {
369
+ if (typeof selector === "string") {
370
+ return elementMatchesSelector.call(elem, selector);
371
+ } else if (typeof selector === "object" && selector.length) {
372
+ return selector.indexOf(elem) >= 0;
373
+ } else if (typeof selector === "object" && selector.nodeType === 1) {
374
+ return elem === selector;
375
+ }
376
+ return false;
377
+ }
378
+ function getCurrentFocusedElement() {
379
+ var activeElement = document.activeElement;
380
+ if (activeElement && activeElement !== document.body) {
381
+ return activeElement;
382
+ }
383
+ }
384
+ function extend(out) {
385
+ out = out || {};
386
+ for (var i = 1; i < arguments.length; i++) {
387
+ if (!arguments[i]) {
388
+ continue;
389
+ }
390
+ for (var key in arguments[i]) {
391
+ if (arguments[i].hasOwnProperty(key) && arguments[i][key] !== void 0) {
392
+ out[key] = arguments[i][key];
393
+ }
394
+ }
395
+ }
396
+ return out;
397
+ }
398
+ function exclude(elemList, excludedElem) {
399
+ if (!Array.isArray(excludedElem)) {
400
+ excludedElem = [excludedElem];
401
+ }
402
+ for (var i = 0, index; i < excludedElem.length; i++) {
403
+ index = elemList.indexOf(excludedElem[i]);
404
+ if (index >= 0) {
405
+ elemList.splice(index, 1);
406
+ }
407
+ }
408
+ return elemList;
409
+ }
410
+ function isNavigable(elem, sectionId, verifySectionSelector) {
411
+ if (!elem || !sectionId || !_sections[sectionId] || _sections[sectionId].disabled) {
412
+ return false;
413
+ }
414
+ if (elem.offsetWidth <= 0 && elem.offsetHeight <= 0 || elem.hasAttribute("disabled")) {
415
+ return false;
416
+ }
417
+ if (verifySectionSelector && !matchSelector(elem, _sections[sectionId].selector)) {
418
+ return false;
419
+ }
420
+ if (typeof _sections[sectionId].navigableFilter === "function") {
421
+ if (_sections[sectionId].navigableFilter(elem, sectionId) === false) {
422
+ return false;
423
+ }
424
+ } else if (typeof GlobalConfig.navigableFilter === "function") {
425
+ if (GlobalConfig.navigableFilter(elem, sectionId) === false) {
426
+ return false;
427
+ }
428
+ }
429
+ return true;
430
+ }
431
+ function getSectionId(elem) {
432
+ for (var id in _sections) {
433
+ if (!_sections[id].disabled && matchSelector(elem, _sections[id].selector)) {
434
+ return id;
435
+ }
436
+ }
437
+ }
438
+ function getSectionNavigableElements(sectionId) {
439
+ return parseSelector(_sections[sectionId].selector).filter(function(elem) {
440
+ return isNavigable(elem, sectionId);
441
+ });
442
+ }
443
+ function getSectionDefaultElement(sectionId) {
444
+ var defaultElement = parseSelector(_sections[sectionId].defaultElement).find(function(elem) {
445
+ return isNavigable(elem, sectionId, true);
446
+ });
447
+ if (!defaultElement) {
448
+ return null;
449
+ }
450
+ return defaultElement;
451
+ }
452
+ function getSectionLastFocusedElement(sectionId) {
453
+ var lastFocusedElement = _sections[sectionId].lastFocusedElement;
454
+ if (!isNavigable(lastFocusedElement, sectionId, true)) {
455
+ return null;
456
+ }
457
+ return lastFocusedElement;
458
+ }
459
+ function fireEvent(elem, type, details, cancelable) {
460
+ if (arguments.length < 4) {
461
+ cancelable = true;
462
+ }
463
+ var evt = document.createEvent("CustomEvent");
464
+ evt.initCustomEvent(EVENT_PREFIX + type, true, cancelable, details);
465
+ return elem.dispatchEvent(evt);
466
+ }
467
+ function focusElement(elem, sectionId, direction) {
468
+ if (!elem) {
469
+ return false;
470
+ }
471
+ var currentFocusedElement = getCurrentFocusedElement();
472
+ var silentFocus = function() {
473
+ if (currentFocusedElement) {
474
+ currentFocusedElement.blur();
475
+ }
476
+ elem.focus();
477
+ focusChanged(elem, sectionId);
478
+ };
479
+ if (_duringFocusChange) {
480
+ silentFocus();
481
+ return true;
482
+ }
483
+ _duringFocusChange = true;
484
+ if (_pause) {
485
+ silentFocus();
486
+ _duringFocusChange = false;
487
+ return true;
488
+ }
489
+ if (currentFocusedElement) {
490
+ var unfocusProperties = {
491
+ nextElement: elem,
492
+ nextSectionId: sectionId,
493
+ direction,
494
+ native: false
495
+ };
496
+ if (!fireEvent(currentFocusedElement, "willunfocus", unfocusProperties)) {
497
+ _duringFocusChange = false;
498
+ return false;
499
+ }
500
+ currentFocusedElement.blur();
501
+ fireEvent(currentFocusedElement, "unfocused", unfocusProperties, false);
502
+ }
503
+ var focusProperties = {
504
+ previousElement: currentFocusedElement,
505
+ sectionId,
506
+ direction,
507
+ native: false
508
+ };
509
+ if (!fireEvent(elem, "willfocus", focusProperties)) {
510
+ _duringFocusChange = false;
511
+ return false;
512
+ }
513
+ elem.focus();
514
+ fireEvent(elem, "focused", focusProperties, false);
515
+ _duringFocusChange = false;
516
+ focusChanged(elem, sectionId);
517
+ return true;
518
+ }
519
+ function focusChanged(elem, sectionId) {
520
+ if (!sectionId) {
521
+ sectionId = getSectionId(elem);
522
+ }
523
+ if (sectionId) {
524
+ _sections[sectionId].lastFocusedElement = elem;
525
+ _lastSectionId = sectionId;
526
+ }
527
+ }
528
+ function focusExtendedSelector(selector, direction) {
529
+ if (selector.charAt(0) == "@") {
530
+ if (selector.length == 1) {
531
+ return focusSection();
532
+ } else {
533
+ var sectionId = selector.substr(1);
534
+ return focusSection(sectionId);
535
+ }
536
+ } else {
537
+ var next = parseSelector(selector)[0];
538
+ if (next) {
539
+ var nextSectionId = getSectionId(next);
540
+ if (isNavigable(next, nextSectionId)) {
541
+ return focusElement(next, nextSectionId, direction);
542
+ }
543
+ }
544
+ }
545
+ return false;
546
+ }
547
+ function focusSection(sectionId) {
548
+ var range = [];
549
+ var addRange = function(id2) {
550
+ if (id2 && range.indexOf(id2) < 0 && _sections[id2] && !_sections[id2].disabled) {
551
+ range.push(id2);
552
+ }
553
+ };
554
+ if (sectionId) {
555
+ addRange(sectionId);
556
+ } else {
557
+ addRange(_defaultSectionId);
558
+ addRange(_lastSectionId);
559
+ Object.keys(_sections).map(addRange);
560
+ }
561
+ for (var i = 0; i < range.length; i++) {
562
+ var id = range[i];
563
+ var next;
564
+ if (_sections[id].enterTo == "last-focused") {
565
+ next = getSectionLastFocusedElement(id) || getSectionDefaultElement(id) || getSectionNavigableElements(id)[0];
566
+ } else {
567
+ next = getSectionDefaultElement(id) || getSectionLastFocusedElement(id) || getSectionNavigableElements(id)[0];
568
+ }
569
+ if (next) {
570
+ return focusElement(next, id);
571
+ }
572
+ }
573
+ return false;
574
+ }
575
+ function fireNavigatefailed(elem, direction) {
576
+ fireEvent(elem, "navigatefailed", {
577
+ direction
578
+ }, false);
579
+ }
580
+ function gotoLeaveFor(sectionId, direction) {
581
+ if (_sections[sectionId].leaveFor && _sections[sectionId].leaveFor[direction] !== void 0) {
582
+ var next = _sections[sectionId].leaveFor[direction];
583
+ if (typeof next === "string") {
584
+ if (next === "") {
585
+ return null;
586
+ }
587
+ return focusExtendedSelector(next, direction);
588
+ }
589
+ var nextSectionId = getSectionId(next);
590
+ if (isNavigable(next, nextSectionId)) {
591
+ return focusElement(next, nextSectionId, direction);
592
+ }
593
+ }
594
+ return false;
595
+ }
596
+ var _scrollScopeCache = /* @__PURE__ */ new WeakMap();
597
+ function getScrollScope(elem) {
598
+ if (_scrollScopeCache.has(elem)) {
599
+ return _scrollScopeCache.get(elem);
600
+ }
601
+ var scope = null;
602
+ var node = elem.parentElement;
603
+ while (node && node !== document.documentElement) {
604
+ var style = window.getComputedStyle(node);
605
+ var ox = style.overflowX;
606
+ var oy = style.overflowY;
607
+ if (ox === "auto" || ox === "scroll" || ox === "hidden" || ox === "clip" || oy === "auto" || oy === "scroll" || oy === "hidden" || oy === "clip") {
608
+ scope = node;
609
+ break;
610
+ }
611
+ node = node.parentElement;
612
+ }
613
+ _scrollScopeCache.set(elem, scope);
614
+ return scope;
615
+ }
616
+ function navigateWithinScrollScope(target, direction, candidates, config, preferNearest) {
617
+ if (!candidates || candidates.length < 2) {
618
+ return navigate(target, direction, candidates, config, preferNearest);
619
+ }
620
+ var targetScope = getScrollScope(target);
621
+ var inScope = [];
622
+ var outScope = [];
623
+ for (var i = 0; i < candidates.length; i++) {
624
+ if (getScrollScope(candidates[i]) === targetScope) {
625
+ inScope.push(candidates[i]);
626
+ } else {
627
+ outScope.push(candidates[i]);
628
+ }
629
+ }
630
+ if (inScope.length && outScope.length) {
631
+ return navigate(target, direction, inScope, config, preferNearest) || navigate(target, direction, outScope, config, preferNearest);
632
+ }
633
+ return navigate(target, direction, candidates, config, preferNearest);
634
+ }
635
+ function focusNext(direction, currentFocusedElement, currentSectionId) {
636
+ var extSelector = currentFocusedElement.getAttribute("data-sn-" + direction);
637
+ if (typeof extSelector === "string") {
638
+ if (extSelector === "" || !focusExtendedSelector(extSelector, direction)) {
639
+ fireNavigatefailed(currentFocusedElement, direction);
640
+ return false;
641
+ }
642
+ return true;
643
+ }
644
+ var sectionNavigableElements = {};
645
+ var allNavigableElements = [];
646
+ for (var id in _sections) {
647
+ sectionNavigableElements[id] = getSectionNavigableElements(id);
648
+ allNavigableElements = allNavigableElements.concat(sectionNavigableElements[id]);
649
+ }
650
+ var config = extend({}, GlobalConfig, _sections[currentSectionId]);
651
+ var next;
652
+ if (config.restrict == "self-only" || config.restrict == "self-first") {
653
+ var currentSectionNavigableElements = sectionNavigableElements[currentSectionId];
654
+ next = navigate(
655
+ currentFocusedElement,
656
+ direction,
657
+ exclude(currentSectionNavigableElements, currentFocusedElement),
658
+ config
659
+ );
660
+ if (!next && config.restrict == "self-first") {
661
+ next = navigateWithinScrollScope(
662
+ currentFocusedElement,
663
+ direction,
664
+ exclude(allNavigableElements, currentSectionNavigableElements),
665
+ config,
666
+ true
667
+ );
668
+ }
669
+ } else {
670
+ next = navigateWithinScrollScope(
671
+ currentFocusedElement,
672
+ direction,
673
+ exclude(allNavigableElements, currentFocusedElement),
674
+ config,
675
+ false
676
+ );
677
+ }
678
+ if (next) {
679
+ _sections[currentSectionId].previous = {
680
+ target: currentFocusedElement,
681
+ destination: next,
682
+ reverse: REVERSE[direction]
683
+ };
684
+ var nextSectionId = getSectionId(next);
685
+ if (currentSectionId != nextSectionId) {
686
+ var result = gotoLeaveFor(currentSectionId, direction);
687
+ if (result) {
688
+ return true;
689
+ } else if (result === null) {
690
+ fireNavigatefailed(currentFocusedElement, direction);
691
+ return false;
692
+ }
693
+ var enterToElement;
694
+ switch (_sections[nextSectionId].enterTo) {
695
+ case "last-focused":
696
+ enterToElement = getSectionLastFocusedElement(nextSectionId) || getSectionDefaultElement(nextSectionId);
697
+ break;
698
+ case "default-element":
699
+ enterToElement = getSectionDefaultElement(nextSectionId);
700
+ break;
701
+ }
702
+ if (enterToElement) {
703
+ next = enterToElement;
704
+ }
705
+ }
706
+ return focusElement(next, nextSectionId, direction);
707
+ } else if (gotoLeaveFor(currentSectionId, direction)) {
708
+ return true;
709
+ }
710
+ fireNavigatefailed(currentFocusedElement, direction);
711
+ return false;
712
+ }
713
+ function onKeyDown(evt) {
714
+ if (!_sectionCount || _pause || evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) {
715
+ return;
716
+ }
717
+ var currentFocusedElement;
718
+ var preventDefault = function() {
719
+ evt.preventDefault();
720
+ evt.stopPropagation();
721
+ return false;
722
+ };
723
+ var direction = KEYMAPPING[evt.keyCode];
724
+ if (!direction) {
725
+ if (evt.keyCode == 13) {
726
+ currentFocusedElement = getCurrentFocusedElement();
727
+ if (currentFocusedElement && getSectionId(currentFocusedElement)) {
728
+ if (!fireEvent(currentFocusedElement, "enter-down")) {
729
+ return preventDefault();
730
+ }
731
+ }
732
+ }
733
+ return;
734
+ }
735
+ currentFocusedElement = getCurrentFocusedElement();
736
+ if (!currentFocusedElement) {
737
+ if (_lastSectionId) {
738
+ currentFocusedElement = getSectionLastFocusedElement(_lastSectionId);
739
+ }
740
+ if (!currentFocusedElement) {
741
+ focusSection();
742
+ return preventDefault();
743
+ }
744
+ }
745
+ var currentSectionId = getSectionId(currentFocusedElement);
746
+ if (!currentSectionId) {
747
+ return;
748
+ }
749
+ var willmoveProperties = {
750
+ direction,
751
+ sectionId: currentSectionId,
752
+ cause: "keydown"
753
+ };
754
+ if (fireEvent(currentFocusedElement, "willmove", willmoveProperties)) {
755
+ focusNext(direction, currentFocusedElement, currentSectionId);
756
+ }
757
+ return preventDefault();
758
+ }
759
+ function onKeyUp(evt) {
760
+ if (evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) {
761
+ return;
762
+ }
763
+ if (!_pause && _sectionCount && evt.keyCode == 13) {
764
+ var currentFocusedElement = getCurrentFocusedElement();
765
+ if (currentFocusedElement && getSectionId(currentFocusedElement)) {
766
+ if (!fireEvent(currentFocusedElement, "enter-up")) {
767
+ evt.preventDefault();
768
+ evt.stopPropagation();
769
+ }
770
+ }
771
+ }
772
+ }
773
+ function onFocus(evt) {
774
+ var target = evt.target;
775
+ if (target !== window && target !== document && _sectionCount && !_duringFocusChange) {
776
+ var sectionId = getSectionId(target);
777
+ if (sectionId) {
778
+ if (_pause) {
779
+ focusChanged(target, sectionId);
780
+ return;
781
+ }
782
+ var focusProperties = {
783
+ sectionId,
784
+ native: true
785
+ };
786
+ if (!fireEvent(target, "willfocus", focusProperties)) {
787
+ _duringFocusChange = true;
788
+ target.blur();
789
+ _duringFocusChange = false;
790
+ } else {
791
+ fireEvent(target, "focused", focusProperties, false);
792
+ focusChanged(target, sectionId);
793
+ }
794
+ }
795
+ }
796
+ }
797
+ function onBlur(evt) {
798
+ var target = evt.target;
799
+ if (target !== window && target !== document && !_pause && _sectionCount && !_duringFocusChange && getSectionId(target)) {
800
+ var unfocusProperties = {
801
+ native: true
802
+ };
803
+ if (!fireEvent(target, "willunfocus", unfocusProperties)) {
804
+ _duringFocusChange = true;
805
+ setTimeout(function() {
806
+ target.focus();
807
+ _duringFocusChange = false;
808
+ });
809
+ } else {
810
+ fireEvent(target, "unfocused", unfocusProperties, false);
811
+ }
812
+ }
813
+ }
814
+ var SpatialNavigation$1 = {
815
+ init: function() {
816
+ if (!_ready) {
817
+ window.addEventListener("keydown", onKeyDown);
818
+ window.addEventListener("keyup", onKeyUp);
819
+ window.addEventListener("focus", onFocus, true);
820
+ window.addEventListener("blur", onBlur, true);
821
+ _ready = true;
822
+ }
823
+ },
824
+ uninit: function() {
825
+ window.removeEventListener("blur", onBlur, true);
826
+ window.removeEventListener("focus", onFocus, true);
827
+ window.removeEventListener("keyup", onKeyUp);
828
+ window.removeEventListener("keydown", onKeyDown);
829
+ SpatialNavigation$1.clear();
830
+ _idPool = 0;
831
+ _ready = false;
832
+ },
833
+ clear: function() {
834
+ _sections = {};
835
+ _sectionCount = 0;
836
+ _defaultSectionId = "";
837
+ _lastSectionId = "";
838
+ _duringFocusChange = false;
839
+ },
840
+ // set(<config>);
841
+ // set(<sectionId>, <config>);
842
+ set: function() {
843
+ var sectionId, config;
844
+ if (typeof arguments[0] === "object") {
845
+ config = arguments[0];
846
+ } else if (typeof arguments[0] === "string" && typeof arguments[1] === "object") {
847
+ sectionId = arguments[0];
848
+ config = arguments[1];
849
+ if (!_sections[sectionId]) {
850
+ throw new Error('Section "' + sectionId + `" doesn't exist!`);
851
+ }
852
+ } else {
853
+ return;
854
+ }
855
+ for (var key in config) {
856
+ if (GlobalConfig[key] !== void 0) {
857
+ if (sectionId) {
858
+ _sections[sectionId][key] = config[key];
859
+ } else if (config[key] !== void 0) {
860
+ GlobalConfig[key] = config[key];
861
+ }
862
+ }
863
+ }
864
+ if (sectionId) {
865
+ _sections[sectionId] = extend({}, _sections[sectionId]);
866
+ }
867
+ },
868
+ // add(<config>);
869
+ // add(<sectionId>, <config>);
870
+ add: function() {
871
+ var sectionId;
872
+ var config = {};
873
+ if (typeof arguments[0] === "object") {
874
+ config = arguments[0];
875
+ } else if (typeof arguments[0] === "string" && typeof arguments[1] === "object") {
876
+ sectionId = arguments[0];
877
+ config = arguments[1];
878
+ }
879
+ if (!sectionId) {
880
+ sectionId = typeof config.id === "string" ? config.id : generateId();
881
+ }
882
+ if (_sections[sectionId]) {
883
+ throw new Error('Section "' + sectionId + '" has already existed!');
884
+ }
885
+ _sections[sectionId] = {};
886
+ _sectionCount++;
887
+ SpatialNavigation$1.set(sectionId, config);
888
+ return sectionId;
889
+ },
890
+ remove: function(sectionId) {
891
+ if (!sectionId || typeof sectionId !== "string") {
892
+ throw new Error('Please assign the "sectionId"!');
893
+ }
894
+ if (_sections[sectionId]) {
895
+ _sections[sectionId] = void 0;
896
+ _sections = extend({}, _sections);
897
+ _sectionCount--;
898
+ if (_lastSectionId === sectionId) {
899
+ _lastSectionId = "";
900
+ }
901
+ return true;
902
+ }
903
+ return false;
904
+ },
905
+ disable: function(sectionId) {
906
+ if (_sections[sectionId]) {
907
+ _sections[sectionId].disabled = true;
908
+ return true;
909
+ }
910
+ return false;
911
+ },
912
+ enable: function(sectionId) {
913
+ if (_sections[sectionId]) {
914
+ _sections[sectionId].disabled = false;
915
+ return true;
916
+ }
917
+ return false;
918
+ },
919
+ pause: function() {
920
+ _pause = true;
921
+ },
922
+ resume: function() {
923
+ _pause = false;
924
+ },
925
+ // focus([silent])
926
+ // focus(<sectionId>, [silent])
927
+ // focus(<extSelector>, [silent])
928
+ // Note: "silent" is optional and default to false
929
+ focus: function(elem, silent) {
930
+ var result = false;
931
+ if (silent === void 0 && typeof elem === "boolean") {
932
+ silent = elem;
933
+ elem = void 0;
934
+ }
935
+ var autoPause = !_pause && silent;
936
+ if (autoPause) {
937
+ SpatialNavigation$1.pause();
938
+ }
939
+ if (!elem) {
940
+ result = focusSection();
941
+ } else {
942
+ if (typeof elem === "string") {
943
+ if (_sections[elem]) {
944
+ result = focusSection(elem);
945
+ } else {
946
+ result = focusExtendedSelector(elem);
947
+ }
948
+ } else {
949
+ var nextSectionId = getSectionId(elem);
950
+ if (isNavigable(elem, nextSectionId)) {
951
+ result = focusElement(elem, nextSectionId);
952
+ }
953
+ }
954
+ }
955
+ if (autoPause) {
956
+ SpatialNavigation$1.resume();
957
+ }
958
+ return result;
959
+ },
960
+ // move(<direction>)
961
+ // move(<direction>, <selector>)
962
+ move: function(direction, selector) {
963
+ direction = direction.toLowerCase();
964
+ if (!REVERSE[direction]) {
965
+ return false;
966
+ }
967
+ var elem = selector ? parseSelector(selector)[0] : getCurrentFocusedElement();
968
+ if (!elem) {
969
+ return false;
970
+ }
971
+ var sectionId = getSectionId(elem);
972
+ if (!sectionId) {
973
+ return false;
974
+ }
975
+ var willmoveProperties = {
976
+ direction,
977
+ sectionId,
978
+ cause: "api"
979
+ };
980
+ if (!fireEvent(elem, "willmove", willmoveProperties)) {
981
+ return false;
982
+ }
983
+ return focusNext(direction, elem, sectionId);
984
+ },
985
+ // makeFocusable()
986
+ // makeFocusable(<sectionId>)
987
+ makeFocusable: function(sectionId) {
988
+ var doMakeFocusable = function(section) {
989
+ var tabIndexIgnoreList = section.tabIndexIgnoreList !== void 0 ? section.tabIndexIgnoreList : GlobalConfig.tabIndexIgnoreList;
990
+ parseSelector(section.selector).forEach(function(elem) {
991
+ if (!matchSelector(elem, tabIndexIgnoreList)) {
992
+ if (!elem.getAttribute("tabindex")) {
993
+ elem.setAttribute("tabindex", "-1");
994
+ }
995
+ }
996
+ });
997
+ };
998
+ if (sectionId) {
999
+ if (_sections[sectionId]) {
1000
+ doMakeFocusable(_sections[sectionId]);
1001
+ } else {
1002
+ throw new Error('Section "' + sectionId + `" doesn't exist!`);
1003
+ }
1004
+ } else {
1005
+ for (var id in _sections) {
1006
+ doMakeFocusable(_sections[id]);
1007
+ }
1008
+ }
1009
+ },
1010
+ setDefaultSection: function(sectionId) {
1011
+ if (!sectionId) {
1012
+ _defaultSectionId = "";
1013
+ } else if (!_sections[sectionId]) {
1014
+ throw new Error('Section "' + sectionId + `" doesn't exist!`);
1015
+ } else {
1016
+ _defaultSectionId = sectionId;
1017
+ }
1018
+ }
1019
+ };
1020
+ if (typeof window !== "undefined") {
1021
+ window.SpatialNavigation = SpatialNavigation$1;
1022
+ }
1023
+ const SpatialNavigation = SpatialNavigation$1;
1024
+ let initialized = false;
1025
+ function setupFocus(options = {}) {
1026
+ if (initialized) return;
1027
+ SpatialNavigation.init();
1028
+ if (options.defaults) {
1029
+ SpatialNavigation.set(options.defaults);
1030
+ }
1031
+ initialized = true;
1032
+ }
1033
+ const ANDROID_TO_KEY = {
1034
+ 19: "ArrowUp",
1035
+ 20: "ArrowDown",
1036
+ 21: "ArrowLeft",
1037
+ 22: "ArrowRight",
1038
+ 23: "Enter",
1039
+ 66: "Enter",
1040
+ 4: "Escape",
1041
+ 67: "Backspace"
1042
+ };
1043
+ const KEY_STR_TO_KEY = {
1044
+ KEYCODE_DPAD_UP: "ArrowUp",
1045
+ KEYCODE_DPAD_DOWN: "ArrowDown",
1046
+ KEYCODE_DPAD_LEFT: "ArrowLeft",
1047
+ KEYCODE_DPAD_RIGHT: "ArrowRight",
1048
+ KEYCODE_DPAD_CENTER: "Enter",
1049
+ KEYCODE_ENTER: "Enter",
1050
+ KEYCODE_BACK: "Escape",
1051
+ KEYCODE_DEL: "Backspace"
1052
+ };
1053
+ const KEY_TO_CODE = {
1054
+ ArrowUp: 38,
1055
+ ArrowDown: 40,
1056
+ ArrowLeft: 37,
1057
+ ArrowRight: 39,
1058
+ Enter: 13,
1059
+ Escape: 27,
1060
+ Backspace: 8
1061
+ };
1062
+ function normalize(detail) {
1063
+ var _a;
1064
+ let key = detail.key;
1065
+ if (!key && typeof detail.keyCodeString === "string") {
1066
+ key = KEY_STR_TO_KEY[detail.keyCodeString];
1067
+ }
1068
+ if (!key && typeof detail.keyCode === "number") {
1069
+ key = ANDROID_TO_KEY[detail.keyCode];
1070
+ }
1071
+ if (!key) return null;
1072
+ const keyCode = (_a = KEY_TO_CODE[key]) != null ? _a : 0;
1073
+ return { key, keyCode };
1074
+ }
1075
+ let attachedEventName = null;
1076
+ let handler = null;
1077
+ function makeKbEvent(type, key, keyCode) {
1078
+ let evt;
1079
+ try {
1080
+ evt = new KeyboardEvent(type, { key, bubbles: true, cancelable: true });
1081
+ } catch (e) {
1082
+ evt = document.createEvent("Event");
1083
+ evt.initEvent(type, true, true);
1084
+ Object.defineProperty(evt, "key", { value: key, configurable: true });
1085
+ }
1086
+ Object.defineProperty(evt, "keyCode", { value: keyCode, configurable: true });
1087
+ Object.defineProperty(evt, "which", { value: keyCode, configurable: true });
1088
+ return evt;
1089
+ }
1090
+ function nativeKeyAdapter(eventName) {
1091
+ if (typeof window === "undefined") return () => void 0;
1092
+ if (attachedEventName && handler) {
1093
+ window.removeEventListener(attachedEventName, handler);
1094
+ }
1095
+ attachedEventName = eventName;
1096
+ handler = (e) => {
1097
+ const detail = e.detail || {};
1098
+ const n = normalize(detail);
1099
+ if (!n) return;
1100
+ window.dispatchEvent(makeKbEvent("keydown", n.key, n.keyCode));
1101
+ window.dispatchEvent(makeKbEvent("keyup", n.key, n.keyCode));
1102
+ };
1103
+ window.addEventListener(eventName, handler);
1104
+ return () => {
1105
+ if (attachedEventName && handler) {
1106
+ window.removeEventListener(attachedEventName, handler);
1107
+ attachedEventName = null;
1108
+ handler = null;
1109
+ }
1110
+ };
1111
+ }
1112
+ const activeSectionIds = /* @__PURE__ */ new Set();
1113
+ function registerSection(id) {
1114
+ activeSectionIds.add(id);
1115
+ }
1116
+ function unregisterSection(id) {
1117
+ activeSectionIds.delete(id);
1118
+ }
1119
+ function listSections() {
1120
+ const out = [];
1121
+ activeSectionIds.forEach((id) => out.push(id));
1122
+ return out;
1123
+ }
1124
+ const FOCUS_LAYER_KEY = Symbol("dwy:focus-layer");
1125
+ let sectionCounter = 0;
1126
+ const FOCUS_SECTION_KEY = Symbol("dwy:focus-section");
1127
+ function useFocusSection(options = {}) {
1128
+ var _a;
1129
+ const sectionId = (_a = options.id) != null ? _a : `dwy-section-${++sectionCounter}`;
1130
+ const selectorAttr = sectionId;
1131
+ const enclosingLayer = inject(FOCUS_LAYER_KEY, null);
1132
+ onMounted(() => {
1133
+ var _a2, _b, _c, _d, _e;
1134
+ SpatialNavigation.add(sectionId, {
1135
+ selector: `[data-sn-section="${selectorAttr}"]`,
1136
+ restrict: (_a2 = options.restrict) != null ? _a2 : "self-first",
1137
+ enterTo: (_b = options.enterTo) != null ? _b : "last-focused",
1138
+ leaveFor: (_c = options.leaveFor) != null ? _c : null,
1139
+ straightOnly: (_d = options.straightOnly) != null ? _d : false,
1140
+ rememberSource: (_e = options.rememberSource) != null ? _e : true,
1141
+ defaultElement: options.defaultElement
1142
+ });
1143
+ registerSection(sectionId);
1144
+ if (enclosingLayer) enclosingLayer.registerInnerSection(sectionId);
1145
+ });
1146
+ onUnmounted(() => {
1147
+ SpatialNavigation.remove(sectionId);
1148
+ unregisterSection(sectionId);
1149
+ });
1150
+ const ctx = { sectionId, selectorAttr };
1151
+ provide(FOCUS_SECTION_KEY, ctx);
1152
+ return ctx;
1153
+ }
1154
+ function useFocusable(options = {}) {
1155
+ const elRef = shallowRef(null);
1156
+ const focused = ref(false);
1157
+ const ctx = inject(FOCUS_SECTION_KEY, null);
1158
+ function handleFocused() {
1159
+ focused.value = true;
1160
+ if (options.onFocus) options.onFocus();
1161
+ }
1162
+ function handleUnfocused() {
1163
+ focused.value = false;
1164
+ if (options.onBlur) options.onBlur();
1165
+ }
1166
+ function handleEnter() {
1167
+ if (options.onEnter) options.onEnter();
1168
+ }
1169
+ onMounted(() => {
1170
+ const el = elRef.value;
1171
+ if (!el) {
1172
+ if (getCurrentInstance()) {
1173
+ console.warn("[dwy:focus] useFocusable 的 elRef 未绑定到任何元素");
1174
+ }
1175
+ return;
1176
+ }
1177
+ if (ctx) {
1178
+ el.setAttribute("data-sn-section", ctx.selectorAttr);
1179
+ } else {
1180
+ console.warn("[dwy:focus] useFocusable 未找到外层 FocusSection;当前元素不会被纳入任何导航区域");
1181
+ }
1182
+ if (options.focusKey) {
1183
+ el.setAttribute("data-focus-key", options.focusKey);
1184
+ }
1185
+ if (el.tabIndex < 0 && !el.getAttribute("tabindex")) {
1186
+ el.setAttribute("tabindex", "-1");
1187
+ }
1188
+ el.addEventListener("sn:focused", handleFocused);
1189
+ el.addEventListener("sn:unfocused", handleUnfocused);
1190
+ el.addEventListener("sn:enter-up", handleEnter);
1191
+ });
1192
+ onUnmounted(() => {
1193
+ const el = elRef.value;
1194
+ if (!el) return;
1195
+ el.removeEventListener("sn:focused", handleFocused);
1196
+ el.removeEventListener("sn:unfocused", handleUnfocused);
1197
+ el.removeEventListener("sn:enter-up", handleEnter);
1198
+ });
1199
+ return { elRef, focused };
1200
+ }
1201
+ function useKeepAliveFocus() {
1202
+ if (!getCurrentInstance()) return;
1203
+ onActivated(() => {
1204
+ SpatialNavigation.resume();
1205
+ });
1206
+ onDeactivated(() => {
1207
+ SpatialNavigation.pause();
1208
+ });
1209
+ }
1210
+ let openCount = 0;
1211
+ function pushLayer() {
1212
+ openCount += 1;
1213
+ }
1214
+ function popLayer() {
1215
+ openCount = Math.max(0, openCount - 1);
1216
+ }
1217
+ function hasOpenLayer() {
1218
+ return openCount > 0;
1219
+ }
1220
+ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
1221
+ __name: "Focusable",
1222
+ props: {
1223
+ focusKey: {},
1224
+ tag: { default: "div" }
1225
+ },
1226
+ emits: ["enter", "focus", "blur"],
1227
+ setup(__props, { expose: __expose, emit: __emit }) {
1228
+ const props = __props;
1229
+ const emit = __emit;
1230
+ const { elRef, focused } = useFocusable({
1231
+ focusKey: props.focusKey,
1232
+ onEnter: () => emit("enter"),
1233
+ onFocus: () => emit("focus"),
1234
+ onBlur: () => emit("blur")
1235
+ });
1236
+ __expose({ elRef, focused });
1237
+ return (_ctx, _cache) => {
1238
+ return openBlock(), createBlock(resolveDynamicComponent(__props.tag), {
1239
+ ref_key: "elRef",
1240
+ ref: elRef,
1241
+ class: normalizeClass(["dwy-focusable", { "is-focused": unref(focused) }]),
1242
+ tabindex: "-1"
1243
+ }, {
1244
+ default: withCtx(() => [
1245
+ renderSlot(_ctx.$slots, "default", { focused: unref(focused) })
1246
+ ]),
1247
+ _: 3
1248
+ }, 8, ["class"]);
1249
+ };
1250
+ }
1251
+ });
1252
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1253
+ __name: "FocusSection",
1254
+ props: {
1255
+ id: {},
1256
+ restrict: { default: "self-first" },
1257
+ enterTo: { default: "last-focused" },
1258
+ leaveFor: { default: null },
1259
+ straightOnly: { type: Boolean, default: false },
1260
+ rememberSource: { type: Boolean, default: true },
1261
+ tag: { default: "div" }
1262
+ },
1263
+ setup(__props) {
1264
+ const props = __props;
1265
+ const { sectionId } = useFocusSection({
1266
+ id: props.id,
1267
+ restrict: props.restrict,
1268
+ enterTo: props.enterTo,
1269
+ leaveFor: props.leaveFor,
1270
+ straightOnly: props.straightOnly,
1271
+ rememberSource: props.rememberSource
1272
+ });
1273
+ return (_ctx, _cache) => {
1274
+ return openBlock(), createBlock(resolveDynamicComponent(__props.tag), {
1275
+ class: "dwy-focus-section",
1276
+ "data-sn-section-root": unref(sectionId)
1277
+ }, {
1278
+ default: withCtx(() => [
1279
+ renderSlot(_ctx.$slots, "default", { sectionId: unref(sectionId) })
1280
+ ]),
1281
+ _: 3
1282
+ }, 8, ["data-sn-section-root"]);
1283
+ };
1284
+ }
1285
+ });
1286
+ const _sfc_main = /* @__PURE__ */ defineComponent({
1287
+ __name: "FocusLayer",
1288
+ props: {
1289
+ id: {},
1290
+ tag: { default: "div" }
1291
+ },
1292
+ setup(__props) {
1293
+ var _a;
1294
+ const props = __props;
1295
+ const innerSectionIds = /* @__PURE__ */ new Set();
1296
+ const layerCtx = {
1297
+ layerId: (_a = props.id) != null ? _a : "dwy-focus-layer",
1298
+ registerInnerSection(id) {
1299
+ innerSectionIds.add(id);
1300
+ }
1301
+ };
1302
+ provide(FOCUS_LAYER_KEY, layerCtx);
1303
+ let outerSections = [];
1304
+ let previousActiveElement = null;
1305
+ onMounted(() => {
1306
+ var _a2;
1307
+ pushLayer();
1308
+ previousActiveElement = (_a2 = document.activeElement) != null ? _a2 : null;
1309
+ outerSections = listSections().filter((id) => !innerSectionIds.has(id));
1310
+ outerSections.forEach((id) => {
1311
+ SpatialNavigation.disable(id);
1312
+ });
1313
+ });
1314
+ onUnmounted(() => {
1315
+ popLayer();
1316
+ outerSections.forEach((id) => {
1317
+ SpatialNavigation.enable(id);
1318
+ });
1319
+ outerSections = [];
1320
+ if (previousActiveElement && typeof previousActiveElement.focus === "function") {
1321
+ try {
1322
+ previousActiveElement.focus();
1323
+ } catch (e) {
1324
+ }
1325
+ }
1326
+ previousActiveElement = null;
1327
+ });
1328
+ return (_ctx, _cache) => {
1329
+ return openBlock(), createBlock(resolveDynamicComponent(__props.tag), { class: "dwy-focus-layer" }, {
1330
+ default: withCtx(() => [
1331
+ renderSlot(_ctx.$slots, "default")
1332
+ ]),
1333
+ _: 3
1334
+ });
1335
+ };
1336
+ }
1337
+ });
1338
+ export {
1339
+ FOCUS_SECTION_KEY,
1340
+ _sfc_main as FocusLayer,
1341
+ _sfc_main$1 as FocusSection,
1342
+ _sfc_main$2 as Focusable,
1343
+ SpatialNavigation,
1344
+ hasOpenLayer,
1345
+ nativeKeyAdapter,
1346
+ setupFocus,
1347
+ useFocusSection,
1348
+ useFocusable,
1349
+ useKeepAliveFocus
1350
+ };
1351
+ //# sourceMappingURL=index.js.map