@patternfly/pfe-core 2.4.1 → 4.0.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.
Files changed (104) hide show
  1. package/README.md +0 -1
  2. package/controllers/activedescendant-controller.d.ts +99 -0
  3. package/controllers/activedescendant-controller.js +230 -0
  4. package/controllers/activedescendant-controller.js.map +1 -0
  5. package/controllers/at-focus-controller.d.ts +56 -0
  6. package/controllers/at-focus-controller.js +168 -0
  7. package/controllers/at-focus-controller.js.map +1 -0
  8. package/controllers/cascade-controller.d.ts +11 -0
  9. package/controllers/cascade-controller.js +10 -3
  10. package/controllers/cascade-controller.js.map +1 -1
  11. package/controllers/combobox-controller.d.ts +117 -0
  12. package/controllers/combobox-controller.js +611 -0
  13. package/controllers/combobox-controller.js.map +1 -0
  14. package/controllers/css-variable-controller.js +1 -1
  15. package/controllers/css-variable-controller.js.map +1 -1
  16. package/controllers/floating-dom-controller.d.ts +10 -3
  17. package/controllers/floating-dom-controller.js +93 -83
  18. package/controllers/floating-dom-controller.js.map +1 -1
  19. package/controllers/internals-controller.d.ts +104 -42
  20. package/controllers/internals-controller.js +354 -36
  21. package/controllers/internals-controller.js.map +1 -1
  22. package/controllers/light-dom-controller.js +2 -2
  23. package/controllers/light-dom-controller.js.map +1 -1
  24. package/controllers/listbox-controller.d.ts +143 -0
  25. package/controllers/listbox-controller.js +443 -0
  26. package/controllers/listbox-controller.js.map +1 -0
  27. package/controllers/logger.d.ts +33 -6
  28. package/controllers/logger.js +58 -13
  29. package/controllers/logger.js.map +1 -1
  30. package/controllers/overflow-controller.d.ts +10 -3
  31. package/controllers/overflow-controller.js +79 -44
  32. package/controllers/overflow-controller.js.map +1 -1
  33. package/controllers/perf-controller.js.map +1 -1
  34. package/controllers/property-observer-controller.d.ts +13 -16
  35. package/controllers/property-observer-controller.js +55 -27
  36. package/controllers/property-observer-controller.js.map +1 -1
  37. package/controllers/roving-tabindex-controller.d.ts +19 -50
  38. package/controllers/roving-tabindex-controller.js +64 -183
  39. package/controllers/roving-tabindex-controller.js.map +1 -1
  40. package/controllers/scroll-spy-controller.d.ts +4 -1
  41. package/controllers/scroll-spy-controller.js +94 -93
  42. package/controllers/scroll-spy-controller.js.map +1 -1
  43. package/controllers/slot-controller.d.ts +26 -19
  44. package/controllers/slot-controller.js +94 -83
  45. package/controllers/slot-controller.js.map +1 -1
  46. package/controllers/style-controller.js +3 -1
  47. package/controllers/style-controller.js.map +1 -1
  48. package/controllers/tabs-aria-controller.d.ts +31 -0
  49. package/controllers/tabs-aria-controller.js +97 -0
  50. package/controllers/tabs-aria-controller.js.map +1 -0
  51. package/controllers/test/combobox-controller.spec.d.ts +1 -0
  52. package/controllers/test/combobox-controller.spec.js +282 -0
  53. package/controllers/test/combobox-controller.spec.js.map +1 -0
  54. package/controllers/timestamp-controller.js +73 -70
  55. package/controllers/timestamp-controller.js.map +1 -1
  56. package/core.d.ts +3 -23
  57. package/core.js +1 -38
  58. package/core.js.map +1 -1
  59. package/custom-elements.json +7302 -2817
  60. package/decorators/bound.d.ts +3 -1
  61. package/decorators/bound.js +3 -1
  62. package/decorators/bound.js.map +1 -1
  63. package/decorators/cascades.d.ts +2 -0
  64. package/decorators/cascades.js +2 -0
  65. package/decorators/cascades.js.map +1 -1
  66. package/decorators/deprecation.d.ts +6 -5
  67. package/decorators/deprecation.js +6 -5
  68. package/decorators/deprecation.js.map +1 -1
  69. package/decorators/initializer.js.map +1 -1
  70. package/decorators/listen.d.ts +8 -0
  71. package/decorators/listen.js +22 -0
  72. package/decorators/listen.js.map +1 -0
  73. package/decorators/observed.d.ts +12 -16
  74. package/decorators/observed.js +39 -44
  75. package/decorators/observed.js.map +1 -1
  76. package/decorators/observes.d.ts +15 -0
  77. package/decorators/observes.js +30 -0
  78. package/decorators/observes.js.map +1 -0
  79. package/decorators/time.d.ts +1 -0
  80. package/decorators/time.js +6 -9
  81. package/decorators/time.js.map +1 -1
  82. package/decorators/trace.d.ts +4 -1
  83. package/decorators/trace.js +4 -1
  84. package/decorators/trace.js.map +1 -1
  85. package/decorators.d.ts +2 -0
  86. package/decorators.js +2 -0
  87. package/decorators.js.map +1 -1
  88. package/functions/arraysAreEquivalent.d.ts +9 -0
  89. package/functions/arraysAreEquivalent.js +28 -0
  90. package/functions/arraysAreEquivalent.js.map +1 -0
  91. package/functions/containsDeep.d.ts +8 -0
  92. package/functions/containsDeep.js +23 -0
  93. package/functions/containsDeep.js.map +1 -0
  94. package/functions/context.d.ts +8 -0
  95. package/functions/context.js +21 -0
  96. package/functions/context.js.map +1 -0
  97. package/functions/debounce.js.map +1 -1
  98. package/functions/isElementInView.d.ts +4 -6
  99. package/functions/isElementInView.js +9 -11
  100. package/functions/isElementInView.js.map +1 -1
  101. package/package.json +10 -4
  102. package/functions/deprecatedCustomEvent.d.ts +0 -5
  103. package/functions/deprecatedCustomEvent.js +0 -12
  104. package/functions/deprecatedCustomEvent.js.map +0 -1
@@ -1,55 +1,24 @@
1
- import type { ReactiveController, ReactiveControllerHost } from 'lit';
1
+ import { type ReactiveControllerHost } from 'lit';
2
+ import { ATFocusController, type ATFocusControllerOptions } from './at-focus-controller.js';
3
+ export type RovingTabindexControllerOptions<Item extends HTMLElement> = ATFocusControllerOptions<Item>;
2
4
  /**
3
5
  * Implements roving tabindex, as described in WAI-ARIA practices, [Managing Focus Within
4
- * Components Using a Roving
5
- * tabindex](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_roving_tabindex)
6
+ * Components Using a Roving tabindex][rti]
7
+ *
8
+ * [rti]: https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_roving_tabindex
6
9
  */
7
- export declare class RovingTabindexController<ItemType extends HTMLElement = HTMLElement> implements ReactiveController {
10
+ export declare class RovingTabindexController<Item extends HTMLElement = HTMLElement> extends ATFocusController<Item> {
8
11
  #private;
9
- host: ReactiveControllerHost & HTMLElement;
10
- /**
11
- * active item of array of items
12
- */
13
- get activeItem(): ItemType | undefined;
14
- /**
15
- * first item in array of focusable items
16
- */
17
- get firstItem(): ItemType | undefined;
18
- /**
19
- * last item in array of focusable items
20
- */
21
- get lastItem(): ItemType | undefined;
22
- /**
23
- * next item after active item in array of focusable items
24
- */
25
- get nextItem(): ItemType | undefined;
26
- /**
27
- * previous item after active item in array of focusable items
28
- */
29
- get prevItem(): ItemType | undefined;
30
- constructor(host: ReactiveControllerHost & HTMLElement);
31
- /**
32
- * sets tabindex of item based on whether or not it is active
33
- */
34
- updateActiveItem(item?: ItemType): void;
35
- /**
36
- * focuses on an item and sets it as active
37
- */
38
- focusOnItem(item?: ItemType): void;
39
- /**
40
- * Focuses next focusable item
41
- */
42
- updateItems(items: ItemType[]): void;
43
- /**
44
- * from array of HTML items, and sets active items
45
- */
46
- initItems(items: ItemType[], itemsContainer?: HTMLElement): void;
47
- /**
48
- * adds event listeners to items container
49
- */
50
- hostConnected(): void;
51
- /**
52
- * removes event listeners from items container
53
- */
54
- hostDisconnected(): void;
12
+ host: ReactiveControllerHost;
13
+ static of<Item extends HTMLElement>(host: ReactiveControllerHost, options: RovingTabindexControllerOptions<Item>): RovingTabindexController<Item>;
14
+ get atFocusedItemIndex(): number;
15
+ /**
16
+ * Sets the DOM Focus on the item with assistive technology focus
17
+ * @param item item
18
+ */
19
+ set atFocusedItemIndex(index: number);
20
+ get items(): Item[];
21
+ set items(items: Item[]);
22
+ private constructor();
23
+ protected onKeydown(event: KeyboardEvent): void;
55
24
  }
@@ -1,201 +1,82 @@
1
- const isFocusableElement = (el) => !!el &&
2
- !el.hasAttribute('disabled') &&
3
- !el.ariaHidden &&
4
- !el.hasAttribute('hidden');
1
+ var _RovingTabindexController_logger, _RovingTabindexController_gainedInitialFocus, _RovingTabindexController_itemsSet;
2
+ import { __classPrivateFieldGet, __classPrivateFieldSet, __decorate } from "tslib";
3
+ import { isServer } from 'lit';
4
+ import { ATFocusController } from './at-focus-controller.js';
5
+ import { Logger } from './logger.js';
6
+ import { bound } from '../decorators/bound.js';
5
7
  /**
6
8
  * Implements roving tabindex, as described in WAI-ARIA practices, [Managing Focus Within
7
- * Components Using a Roving
8
- * tabindex](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_roving_tabindex)
9
+ * Components Using a Roving tabindex][rti]
10
+ *
11
+ * [rti]: https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_roving_tabindex
9
12
  */
10
- export class RovingTabindexController {
11
- /** active focusable element */
12
- #activeItem;
13
- /** closest ancestor containing items */
14
- #itemsContainer;
15
- /** array of all focusable elements */
16
- #items = [];
17
- /**
18
- * finds focusable items from a group of items
19
- */
20
- get #focusableItems() {
21
- return this.#items.filter(isFocusableElement);
22
- }
23
- /**
24
- * index of active item in array of focusable items
25
- */
26
- get #activeIndex() {
27
- return !!this.#focusableItems && !!this.activeItem ? this.#focusableItems.indexOf(this.activeItem) : -1;
28
- }
29
- /**
30
- * index of active item in array of items
31
- */
32
- get #itemIndex() {
33
- return this.activeItem ? this.#items.indexOf(this.activeItem) : -1;
13
+ export class RovingTabindexController extends ATFocusController {
14
+ static of(host, options) {
15
+ return new RovingTabindexController(host, options);
34
16
  }
35
- /**
36
- * active item of array of items
37
- */
38
- get activeItem() {
39
- return this.#activeItem;
17
+ get atFocusedItemIndex() {
18
+ return super.atFocusedItemIndex;
40
19
  }
41
20
  /**
42
- * first item in array of focusable items
21
+ * Sets the DOM Focus on the item with assistive technology focus
22
+ * @param item item
43
23
  */
44
- get firstItem() {
45
- return this.#focusableItems[0];
46
- }
47
- /**
48
- * last item in array of focusable items
49
- */
50
- get lastItem() {
51
- return this.#focusableItems.at(-1);
24
+ set atFocusedItemIndex(index) {
25
+ super.atFocusedItemIndex = index;
26
+ const item = this.items.at(this.atFocusedItemIndex);
27
+ for (const i of this.items) {
28
+ i.tabIndex = item === i ? 0 : -1;
29
+ }
30
+ if (__classPrivateFieldGet(this, _RovingTabindexController_gainedInitialFocus, "f")) {
31
+ item?.focus();
32
+ }
33
+ this.host.requestUpdate();
52
34
  }
53
- /**
54
- * next item after active item in array of focusable items
55
- */
56
- get nextItem() {
57
- return (this.#activeIndex >= this.#focusableItems.length - 1 ? this.firstItem
58
- : this.#focusableItems[this.#activeIndex + 1]);
35
+ get items() {
36
+ return this._items;
59
37
  }
60
- /**
61
- * previous item after active item in array of focusable items
62
- */
63
- get prevItem() {
64
- return (this.#activeIndex > 0 ? this.#focusableItems[this.#activeIndex - 1]
65
- : this.lastItem);
38
+ set items(items) {
39
+ this._items = items;
40
+ __classPrivateFieldSet(this, _RovingTabindexController_itemsSet, new Set(items), "f");
41
+ const pivot = Math.max(0, this.atFocusedItemIndex);
42
+ const [firstFocusable] = this.atFocusableItems;
43
+ const firstFocusableIndex = firstFocusable ? items.indexOf(firstFocusable) : -1;
44
+ const pivotFocusableIndex = items.indexOf(this.items
45
+ .slice(pivot)
46
+ .concat(this.items.slice(0, pivot))
47
+ .find(item => this.atFocusableItems.includes(item)));
48
+ this.atFocusedItemIndex = Math.max(firstFocusableIndex, pivotFocusableIndex);
49
+ this.host.requestUpdate();
66
50
  }
67
- constructor(host) {
51
+ constructor(host, options) {
52
+ super(host, options);
68
53
  this.host = host;
69
- this.host.addController(this);
70
- }
71
- /**
72
- * handles keyboard navigation
73
- */
74
- #onKeydown = (event) => {
75
- if (event.ctrlKey ||
76
- event.altKey ||
77
- event.metaKey ||
78
- !this.#focusableItems.length ||
79
- !event.composedPath().some(x => this.#focusableItems.includes(x))) {
80
- return;
81
- }
82
- const item = this.activeItem;
83
- let shouldPreventDefault = false;
84
- const horizontalOnly = !item ? false
85
- : item.tagName === 'SELECT' ||
86
- item.getAttribute('role') === 'spinbutton';
87
- switch (event.key) {
88
- case 'ArrowLeft':
89
- this.focusOnItem(this.prevItem);
90
- shouldPreventDefault = true;
91
- break;
92
- case 'ArrowRight':
93
- this.focusOnItem(this.nextItem);
94
- shouldPreventDefault = true;
95
- break;
96
- case 'ArrowUp':
97
- if (horizontalOnly) {
98
- return;
99
- }
100
- this.focusOnItem(this.prevItem);
101
- shouldPreventDefault = true;
102
- break;
103
- case 'ArrowDown':
104
- if (horizontalOnly) {
105
- return;
106
- }
107
- this.focusOnItem(this.nextItem);
108
- shouldPreventDefault = true;
109
- break;
110
- case 'Home':
111
- this.focusOnItem(this.firstItem);
112
- shouldPreventDefault = true;
113
- break;
114
- case 'PageUp':
115
- if (horizontalOnly) {
116
- return;
117
- }
118
- this.focusOnItem(this.firstItem);
119
- shouldPreventDefault = true;
120
- break;
121
- case 'End':
122
- this.focusOnItem(this.lastItem);
123
- shouldPreventDefault = true;
124
- break;
125
- case 'PageDown':
126
- if (horizontalOnly) {
127
- return;
128
- }
129
- this.focusOnItem(this.lastItem);
130
- shouldPreventDefault = true;
131
- break;
132
- default:
133
- break;
134
- }
135
- if (shouldPreventDefault) {
136
- event.stopPropagation();
137
- event.preventDefault();
138
- }
139
- };
140
- /**
141
- * sets tabindex of item based on whether or not it is active
142
- */
143
- updateActiveItem(item) {
144
- if (item) {
145
- if (!!this.#activeItem && item !== this.#activeItem) {
146
- this.#activeItem.tabIndex = -1;
54
+ _RovingTabindexController_logger.set(this, new Logger(this.host));
55
+ _RovingTabindexController_gainedInitialFocus.set(this, false);
56
+ _RovingTabindexController_itemsSet.set(this, new Set());
57
+ this.initItems();
58
+ const container = options.getItemsContainer?.() ?? this.host;
59
+ if (!isServer) {
60
+ if (container instanceof HTMLElement) {
61
+ container.addEventListener('focusin', () => __classPrivateFieldSet(this, _RovingTabindexController_gainedInitialFocus, true, "f"), { once: true });
62
+ }
63
+ else {
64
+ __classPrivateFieldGet(this, _RovingTabindexController_logger, "f").warn('RovingTabindexController requires a getItemsContainer function');
147
65
  }
148
- item.tabIndex = 0;
149
- this.#activeItem = item;
150
66
  }
151
67
  }
152
- /**
153
- * focuses on an item and sets it as active
154
- */
155
- focusOnItem(item) {
156
- this.updateActiveItem(item || this.firstItem);
157
- this.#activeItem?.focus();
158
- this.host.requestUpdate();
159
- }
160
- /**
161
- * Focuses next focusable item
162
- */
163
- updateItems(items) {
164
- const sequence = [...items.slice(this.#itemIndex), ...items.slice(0, this.#itemIndex)];
165
- const first = sequence.find(item => this.#focusableItems.includes(item));
166
- this.focusOnItem(first || this.firstItem);
167
- }
168
- /**
169
- * from array of HTML items, and sets active items
170
- */
171
- initItems(items, itemsContainer = this.host) {
172
- this.#items = items ?? [];
173
- const focusableItems = this.#focusableItems;
174
- const [focusableItem] = focusableItems;
175
- this.#activeItem = focusableItem;
176
- for (const item of focusableItems) {
177
- item.tabIndex = this.#activeItem === item ? 0 : -1;
178
- }
179
- /**
180
- * removes listener on previous contained and applies it to new container
181
- */
182
- if (!this.#itemsContainer || itemsContainer !== this.#itemsContainer) {
183
- this.#itemsContainer?.removeEventListener('keydown', this.#onKeydown);
184
- this.#itemsContainer = itemsContainer;
185
- this.hostConnected();
68
+ onKeydown(event) {
69
+ if (!event.ctrlKey
70
+ && !event.altKey
71
+ && !event.metaKey
72
+ && !!this.atFocusableItems.length
73
+ && !!event.composedPath().some(node => __classPrivateFieldGet(this, _RovingTabindexController_itemsSet, "f").has(node))) {
74
+ super.onKeydown(event);
186
75
  }
187
76
  }
188
- /**
189
- * adds event listeners to items container
190
- */
191
- hostConnected() {
192
- this.#itemsContainer?.addEventListener('keydown', this.#onKeydown);
193
- }
194
- /**
195
- * removes event listeners from items container
196
- */
197
- hostDisconnected() {
198
- this.#itemsContainer?.removeEventListener('keydown', this.#onKeydown);
199
- }
200
77
  }
78
+ _RovingTabindexController_logger = new WeakMap(), _RovingTabindexController_gainedInitialFocus = new WeakMap(), _RovingTabindexController_itemsSet = new WeakMap();
79
+ __decorate([
80
+ bound
81
+ ], RovingTabindexController.prototype, "onKeydown", null);
201
82
  //# sourceMappingURL=roving-tabindex-controller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"roving-tabindex-controller.js","sourceRoot":"","sources":["roving-tabindex-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController, ReactiveControllerHost } from 'lit';\n\nconst isFocusableElement = (el: Element): el is HTMLElement =>\n !!el &&\n !el.hasAttribute('disabled') &&\n !el.ariaHidden &&\n !el.hasAttribute('hidden');\n\n/**\n * Implements roving tabindex, as described in WAI-ARIA practices, [Managing Focus Within\n * Components Using a Roving\n * tabindex](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_roving_tabindex)\n */\nexport class RovingTabindexController<\n ItemType extends HTMLElement = HTMLElement,\n> implements ReactiveController {\n /** active focusable element */\n #activeItem?: ItemType;\n\n /** closest ancestor containing items */\n #itemsContainer?: HTMLElement;\n\n /** array of all focusable elements */\n #items: ItemType[] = [];\n\n /**\n * finds focusable items from a group of items\n */\n get #focusableItems(): ItemType[] {\n return this.#items.filter(isFocusableElement);\n }\n\n /**\n * index of active item in array of focusable items\n */\n get #activeIndex(): number {\n return !!this.#focusableItems && !!this.activeItem ? this.#focusableItems.indexOf(this.activeItem) : -1;\n }\n\n /**\n * index of active item in array of items\n */\n get #itemIndex(): number {\n return this.activeItem ? this.#items.indexOf(this.activeItem) : -1;\n }\n\n /**\n * active item of array of items\n */\n get activeItem(): ItemType | undefined {\n return this.#activeItem;\n }\n\n /**\n * first item in array of focusable items\n */\n get firstItem(): ItemType | undefined {\n return this.#focusableItems[0];\n }\n\n /**\n * last item in array of focusable items\n */\n get lastItem(): ItemType | undefined {\n return this.#focusableItems.at(-1);\n }\n\n /**\n * next item after active item in array of focusable items\n */\n get nextItem(): ItemType | undefined {\n return (\n this.#activeIndex >= this.#focusableItems.length - 1 ? this.firstItem\n : this.#focusableItems[this.#activeIndex + 1]\n );\n }\n\n /**\n * previous item after active item in array of focusable items\n */\n get prevItem(): ItemType | undefined {\n return (\n this.#activeIndex > 0 ? this.#focusableItems[this.#activeIndex - 1]\n : this.lastItem\n );\n }\n\n constructor(public host: ReactiveControllerHost & HTMLElement) {\n this.host.addController(this);\n }\n\n /**\n * handles keyboard navigation\n */\n #onKeydown = (event: KeyboardEvent) => {\n if (event.ctrlKey ||\n event.altKey ||\n event.metaKey ||\n !this.#focusableItems.length ||\n !event.composedPath().some(x =>\n this.#focusableItems.includes(x as ItemType))) {\n return;\n }\n const item = this.activeItem;\n let shouldPreventDefault = false;\n const horizontalOnly =\n !item ? false\n : item.tagName === 'SELECT' ||\n item.getAttribute('role') === 'spinbutton';\n\n\n switch (event.key) {\n case 'ArrowLeft':\n this.focusOnItem(this.prevItem);\n shouldPreventDefault = true;\n break;\n case 'ArrowRight':\n this.focusOnItem(this.nextItem);\n shouldPreventDefault = true;\n break;\n case 'ArrowUp':\n if (horizontalOnly) {\n return;\n }\n this.focusOnItem(this.prevItem);\n shouldPreventDefault = true;\n break;\n case 'ArrowDown':\n if (horizontalOnly) {\n return;\n }\n this.focusOnItem(this.nextItem);\n shouldPreventDefault = true;\n break;\n case 'Home':\n this.focusOnItem(this.firstItem);\n shouldPreventDefault = true;\n break;\n case 'PageUp':\n if (horizontalOnly) {\n return;\n }\n this.focusOnItem(this.firstItem);\n shouldPreventDefault = true;\n break;\n case 'End':\n this.focusOnItem(this.lastItem);\n shouldPreventDefault = true;\n break;\n case 'PageDown':\n if (horizontalOnly) {\n return;\n }\n this.focusOnItem(this.lastItem);\n shouldPreventDefault = true;\n break;\n default:\n break;\n }\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n };\n\n /**\n * sets tabindex of item based on whether or not it is active\n */\n updateActiveItem(item?: ItemType): void {\n if (item) {\n if (!!this.#activeItem && item !== this.#activeItem) {\n this.#activeItem.tabIndex = -1;\n }\n item.tabIndex = 0;\n this.#activeItem = item;\n }\n }\n\n /**\n * focuses on an item and sets it as active\n */\n focusOnItem(item?: ItemType): void {\n this.updateActiveItem(item || this.firstItem);\n this.#activeItem?.focus();\n this.host.requestUpdate();\n }\n\n /**\n * Focuses next focusable item\n */\n updateItems(items: ItemType[]) {\n const sequence = [...items.slice(this.#itemIndex), ...items.slice(0, this.#itemIndex)];\n const first = sequence.find(item => this.#focusableItems.includes(item));\n this.focusOnItem(first || this.firstItem);\n }\n\n /**\n * from array of HTML items, and sets active items\n */\n initItems(items: ItemType[], itemsContainer: HTMLElement = this.host) {\n this.#items = items ?? [];\n const focusableItems = this.#focusableItems;\n const [focusableItem] = focusableItems;\n this.#activeItem = focusableItem;\n for (const item of focusableItems) {\n item.tabIndex = this.#activeItem === item ? 0 : -1;\n }\n /**\n * removes listener on previous contained and applies it to new container\n */\n if (!this.#itemsContainer || itemsContainer !== this.#itemsContainer) {\n this.#itemsContainer?.removeEventListener('keydown', this.#onKeydown);\n this.#itemsContainer = itemsContainer;\n this.hostConnected();\n }\n }\n\n /**\n * adds event listeners to items container\n */\n hostConnected() {\n this.#itemsContainer?.addEventListener('keydown', this.#onKeydown);\n }\n\n /**\n * removes event listeners from items container\n */\n hostDisconnected() {\n this.#itemsContainer?.removeEventListener('keydown', this.#onKeydown);\n }\n}\n"]}
1
+ {"version":3,"file":"roving-tabindex-controller.js","sourceRoot":"","sources":["roving-tabindex-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { isServer, type ReactiveControllerHost } from 'lit';\nimport { ATFocusController, type ATFocusControllerOptions } from './at-focus-controller.js';\nimport { Logger } from './logger.js';\nimport { bound } from '../decorators/bound.js';\n\nexport type RovingTabindexControllerOptions<Item extends HTMLElement> =\n ATFocusControllerOptions<Item>;\n\n/**\n * Implements roving tabindex, as described in WAI-ARIA practices, [Managing Focus Within\n * Components Using a Roving tabindex][rti]\n *\n * [rti]: https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_roving_tabindex\n */\nexport class RovingTabindexController<\n Item extends HTMLElement = HTMLElement\n> extends ATFocusController<Item> {\n static of<Item extends HTMLElement>(\n host: ReactiveControllerHost,\n options: RovingTabindexControllerOptions<Item>,\n ): RovingTabindexController<Item> {\n return new RovingTabindexController(host, options);\n }\n\n #logger = new Logger(this.host);\n\n #gainedInitialFocus = false;\n\n #itemsSet = new Set<Item>();\n\n get atFocusedItemIndex(): number {\n return super.atFocusedItemIndex;\n }\n\n /**\n * Sets the DOM Focus on the item with assistive technology focus\n * @param item item\n */\n set atFocusedItemIndex(index: number) {\n super.atFocusedItemIndex = index;\n const item = this.items.at(this.atFocusedItemIndex);\n for (const i of this.items) {\n i.tabIndex = item === i ? 0 : -1;\n }\n if (this.#gainedInitialFocus) {\n item?.focus();\n }\n this.host.requestUpdate();\n }\n\n get items() {\n return this._items;\n }\n\n public set items(items: Item[]) {\n this._items = items;\n this.#itemsSet = new Set(items);\n const pivot = Math.max(0, this.atFocusedItemIndex);\n const [firstFocusable] = this.atFocusableItems;\n const firstFocusableIndex = firstFocusable ? items.indexOf(firstFocusable) : -1;\n const pivotFocusableIndex = items.indexOf(this.items\n .slice(pivot)\n .concat(this.items.slice(0, pivot))\n .find(item => this.atFocusableItems.includes(item))!);\n this.atFocusedItemIndex = Math.max(firstFocusableIndex, pivotFocusableIndex);\n this.host.requestUpdate();\n }\n\n private constructor(\n public host: ReactiveControllerHost,\n options: RovingTabindexControllerOptions<Item>,\n ) {\n super(host, options);\n this.initItems();\n const container = options.getItemsContainer?.() ?? this.host;\n if (!isServer) {\n if (container instanceof HTMLElement) {\n container.addEventListener('focusin', () =>\n this.#gainedInitialFocus = true, { once: true });\n } else {\n this.#logger.warn('RovingTabindexController requires a getItemsContainer function');\n }\n }\n }\n\n @bound\n protected override onKeydown(event: KeyboardEvent): void {\n if (!event.ctrlKey\n && !event.altKey\n && !event.metaKey\n && !!this.atFocusableItems.length\n && !!event.composedPath().some(node => this.#itemsSet.has(node as Item))) {\n super.onKeydown(event);\n }\n }\n}\n"]}
@@ -32,6 +32,9 @@ export declare class ScrollSpyController implements ReactiveController {
32
32
  set threshold(v: number | number[]);
33
33
  constructor(host: ReactiveControllerHost & HTMLElement, options: ScrollSpyControllerOptions);
34
34
  hostConnected(): void;
35
- /** Explicitly set the active item */
35
+ /**
36
+ * Explicitly set the active item
37
+ * @param link usually an `<a>`
38
+ */
36
39
  setActive(link: EventTarget | null): Promise<void>;
37
40
  }
@@ -1,122 +1,123 @@
1
+ var _ScrollSpyController_instances, _ScrollSpyController_tagNames, _ScrollSpyController_activeAttribute, _ScrollSpyController_io, _ScrollSpyController_passedLinks, _ScrollSpyController_force, _ScrollSpyController_intersected, _ScrollSpyController_root, _ScrollSpyController_rootMargin, _ScrollSpyController_threshold, _ScrollSpyController_getRootNode, _ScrollSpyController_getHash, _ScrollSpyController_linkChildren_get, _ScrollSpyController_initIo, _ScrollSpyController_markPassed, _ScrollSpyController_setActive, _ScrollSpyController_nextIntersection, _ScrollSpyController_onIo;
2
+ import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
1
3
  export class ScrollSpyController {
2
- #tagNames;
3
- #activeAttribute;
4
- #io;
5
- /** Which link's targets have already scrolled past? */
6
- #passedLinks = new Set();
7
- /** Ignore intersections? */
8
- #force = false;
9
- /** Has the intersection observer found an element? */
10
- #intersected = false;
11
- #root;
12
- #rootMargin;
13
- #threshold;
14
- #rootNode;
15
- #getHash;
16
- get #linkChildren() {
17
- return Array.from(this.host.querySelectorAll(this.#tagNames.join(',')))
18
- .filter(this.#getHash);
19
- }
20
4
  get root() {
21
- return this.#root;
5
+ return __classPrivateFieldGet(this, _ScrollSpyController_root, "f");
22
6
  }
23
7
  set root(v) {
24
- this.#root = v;
25
- this.#io?.disconnect();
26
- this.#initIo();
8
+ __classPrivateFieldSet(this, _ScrollSpyController_root, v, "f");
9
+ __classPrivateFieldGet(this, _ScrollSpyController_io, "f")?.disconnect();
10
+ __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_initIo).call(this);
27
11
  }
28
12
  get rootMargin() {
29
- return this.#rootMargin;
13
+ return __classPrivateFieldGet(this, _ScrollSpyController_rootMargin, "f");
30
14
  }
31
15
  set rootMargin(v) {
32
- this.#rootMargin = v;
33
- this.#io?.disconnect();
34
- this.#initIo();
16
+ __classPrivateFieldSet(this, _ScrollSpyController_rootMargin, v, "f");
17
+ __classPrivateFieldGet(this, _ScrollSpyController_io, "f")?.disconnect();
18
+ __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_initIo).call(this);
35
19
  }
36
20
  get threshold() {
37
- return this.#threshold;
21
+ return __classPrivateFieldGet(this, _ScrollSpyController_threshold, "f");
38
22
  }
39
23
  set threshold(v) {
40
- this.#threshold = v;
41
- this.#io?.disconnect();
42
- this.#initIo();
24
+ __classPrivateFieldSet(this, _ScrollSpyController_threshold, v, "f");
25
+ __classPrivateFieldGet(this, _ScrollSpyController_io, "f")?.disconnect();
26
+ __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_initIo).call(this);
43
27
  }
44
28
  constructor(host, options) {
29
+ _ScrollSpyController_instances.add(this);
45
30
  this.host = host;
31
+ _ScrollSpyController_tagNames.set(this, void 0);
32
+ _ScrollSpyController_activeAttribute.set(this, void 0);
33
+ _ScrollSpyController_io.set(this, void 0);
34
+ /** Which link's targets have already scrolled past? */
35
+ _ScrollSpyController_passedLinks.set(this, new Set());
36
+ /** Ignore intersections? */
37
+ _ScrollSpyController_force.set(this, false);
38
+ /** Has the intersection observer found an element? */
39
+ _ScrollSpyController_intersected.set(this, false);
40
+ _ScrollSpyController_root.set(this, void 0);
41
+ _ScrollSpyController_rootMargin.set(this, void 0);
42
+ _ScrollSpyController_threshold.set(this, void 0);
43
+ _ScrollSpyController_getRootNode.set(this, void 0);
44
+ _ScrollSpyController_getHash.set(this, void 0);
46
45
  host.addController(this);
47
- this.#tagNames = options.tagNames;
48
- this.#root = options.root;
49
- this.#rootMargin = options.rootMargin;
50
- this.#activeAttribute = options.activeAttribute ?? 'active';
51
- this.#threshold = options.threshold ?? 0.85;
52
- this.#rootNode = options.rootNode ?? host.getRootNode();
53
- this.#getHash = options?.getHash ?? ((el) => el.getAttribute('href'));
46
+ __classPrivateFieldSet(this, _ScrollSpyController_tagNames, options.tagNames, "f");
47
+ __classPrivateFieldSet(this, _ScrollSpyController_root, options.root, "f");
48
+ __classPrivateFieldSet(this, _ScrollSpyController_rootMargin, options.rootMargin, "f");
49
+ __classPrivateFieldSet(this, _ScrollSpyController_activeAttribute, options.activeAttribute ?? 'active', "f");
50
+ __classPrivateFieldSet(this, _ScrollSpyController_threshold, options.threshold ?? 0.85, "f");
51
+ __classPrivateFieldSet(this, _ScrollSpyController_getRootNode, () => options.rootNode ?? host.getRootNode(), "f");
52
+ __classPrivateFieldSet(this, _ScrollSpyController_getHash, options?.getHash ?? ((el) => el.getAttribute('href')), "f");
54
53
  }
55
54
  hostConnected() {
56
- this.#initIo();
55
+ __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_initIo).call(this);
57
56
  }
58
- #initIo() {
59
- const rootNode = this.#rootNode;
60
- if (rootNode instanceof Document || rootNode instanceof ShadowRoot) {
61
- const { rootMargin, threshold, root } = this;
62
- this.#io = new IntersectionObserver(r => this.#onIo(r), { root, rootMargin, threshold });
63
- this.#linkChildren
64
- .map(x => this.#getHash(x))
65
- .filter((x) => !!x)
66
- .map(x => rootNode.getElementById(x.replace('#', '')))
67
- .filter((x) => !!x)
68
- .forEach(target => this.#io?.observe(target));
57
+ /**
58
+ * Explicitly set the active item
59
+ * @param link usually an `<a>`
60
+ */
61
+ async setActive(link) {
62
+ __classPrivateFieldSet(this, _ScrollSpyController_force, true, "f");
63
+ __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_setActive).call(this, link);
64
+ let sawActive = false;
65
+ for (const child of __classPrivateFieldGet(this, _ScrollSpyController_instances, "a", _ScrollSpyController_linkChildren_get)) {
66
+ __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_markPassed).call(this, child, !sawActive);
67
+ if (child === link) {
68
+ sawActive = true;
69
+ }
69
70
  }
71
+ await __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_nextIntersection).call(this);
72
+ __classPrivateFieldSet(this, _ScrollSpyController_force, false, "f");
70
73
  }
71
- #markPassed(link, force) {
72
- if (force) {
73
- this.#passedLinks.add(link);
74
- }
75
- else {
76
- this.#passedLinks.delete(link);
77
- }
74
+ }
75
+ _ScrollSpyController_tagNames = new WeakMap(), _ScrollSpyController_activeAttribute = new WeakMap(), _ScrollSpyController_io = new WeakMap(), _ScrollSpyController_passedLinks = new WeakMap(), _ScrollSpyController_force = new WeakMap(), _ScrollSpyController_intersected = new WeakMap(), _ScrollSpyController_root = new WeakMap(), _ScrollSpyController_rootMargin = new WeakMap(), _ScrollSpyController_threshold = new WeakMap(), _ScrollSpyController_getRootNode = new WeakMap(), _ScrollSpyController_getHash = new WeakMap(), _ScrollSpyController_instances = new WeakSet(), _ScrollSpyController_linkChildren_get = function _ScrollSpyController_linkChildren_get() {
76
+ return Array.from(this.host.querySelectorAll(__classPrivateFieldGet(this, _ScrollSpyController_tagNames, "f").join(',')))
77
+ .filter(__classPrivateFieldGet(this, _ScrollSpyController_getHash, "f"));
78
+ }, _ScrollSpyController_initIo = function _ScrollSpyController_initIo() {
79
+ const rootNode = __classPrivateFieldGet(this, _ScrollSpyController_getRootNode, "f").call(this);
80
+ if (rootNode instanceof Document || rootNode instanceof ShadowRoot) {
81
+ const { rootMargin, threshold, root } = this;
82
+ __classPrivateFieldSet(this, _ScrollSpyController_io, new IntersectionObserver(r => __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_onIo).call(this, r), { root, rootMargin, threshold }), "f");
83
+ __classPrivateFieldGet(this, _ScrollSpyController_instances, "a", _ScrollSpyController_linkChildren_get)
84
+ .map(x => __classPrivateFieldGet(this, _ScrollSpyController_getHash, "f").call(this, x))
85
+ .filter((x) => !!x)
86
+ .map(x => rootNode.getElementById(x.replace('#', '')))
87
+ .filter((x) => !!x)
88
+ .forEach(target => __classPrivateFieldGet(this, _ScrollSpyController_io, "f")?.observe(target));
78
89
  }
79
- #setActive(link) {
80
- for (const child of this.#linkChildren) {
81
- child.toggleAttribute(this.#activeAttribute, child === link);
82
- }
90
+ }, _ScrollSpyController_markPassed = function _ScrollSpyController_markPassed(link, force) {
91
+ if (force) {
92
+ __classPrivateFieldGet(this, _ScrollSpyController_passedLinks, "f").add(link);
83
93
  }
84
- async #nextIntersection() {
85
- this.#intersected = false;
86
- // safeguard the loop
87
- setTimeout(() => this.#intersected = false, 3000);
88
- while (!this.#intersected) {
89
- await new Promise(requestAnimationFrame);
90
- }
94
+ else {
95
+ __classPrivateFieldGet(this, _ScrollSpyController_passedLinks, "f").delete(link);
91
96
  }
92
- async #onIo(entries) {
93
- if (!this.#force) {
94
- for (const { target, boundingClientRect, intersectionRect } of entries) {
95
- const selector = `:is(${this.#tagNames.join(',')})[href="#${target.id}"]`;
96
- const link = this.host.querySelector(selector);
97
- if (link) {
98
- this.#markPassed(link, boundingClientRect.top < intersectionRect.top);
99
- }
100
- }
101
- const link = [...this.#passedLinks];
102
- const last = link.at(-1);
103
- this.#setActive(last ?? this.#linkChildren.at(0));
104
- }
105
- this.#intersected = true;
97
+ }, _ScrollSpyController_setActive = function _ScrollSpyController_setActive(link) {
98
+ for (const child of __classPrivateFieldGet(this, _ScrollSpyController_instances, "a", _ScrollSpyController_linkChildren_get)) {
99
+ child.toggleAttribute(__classPrivateFieldGet(this, _ScrollSpyController_activeAttribute, "f"), child === link);
106
100
  }
107
- /** Explicitly set the active item */
108
- async setActive(link) {
109
- this.#force = true;
110
- this.#setActive(link);
111
- let sawActive = false;
112
- for (const child of this.#linkChildren) {
113
- this.#markPassed(child, !sawActive);
114
- if (child === link) {
115
- sawActive = true;
101
+ }, _ScrollSpyController_nextIntersection = async function _ScrollSpyController_nextIntersection() {
102
+ __classPrivateFieldSet(this, _ScrollSpyController_intersected, false, "f");
103
+ // safeguard the loop
104
+ setTimeout(() => __classPrivateFieldSet(this, _ScrollSpyController_intersected, false, "f"), 3000);
105
+ while (!__classPrivateFieldGet(this, _ScrollSpyController_intersected, "f")) {
106
+ await new Promise(requestAnimationFrame);
107
+ }
108
+ }, _ScrollSpyController_onIo = async function _ScrollSpyController_onIo(entries) {
109
+ if (!__classPrivateFieldGet(this, _ScrollSpyController_force, "f")) {
110
+ for (const { target, boundingClientRect, intersectionRect } of entries) {
111
+ const selector = `:is(${__classPrivateFieldGet(this, _ScrollSpyController_tagNames, "f").join(',')})[href="#${target.id}"]`;
112
+ const link = this.host.querySelector(selector);
113
+ if (link) {
114
+ __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_markPassed).call(this, link, boundingClientRect.top < intersectionRect.top);
116
115
  }
117
116
  }
118
- await this.#nextIntersection();
119
- this.#force = false;
117
+ const link = [...__classPrivateFieldGet(this, _ScrollSpyController_passedLinks, "f")];
118
+ const last = link.at(-1);
119
+ __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_setActive).call(this, last ?? __classPrivateFieldGet(this, _ScrollSpyController_instances, "a", _ScrollSpyController_linkChildren_get).at(0));
120
120
  }
121
- }
121
+ __classPrivateFieldSet(this, _ScrollSpyController_intersected, true, "f");
122
+ };
122
123
  //# sourceMappingURL=scroll-spy-controller.js.map