@angular/cdk 19.0.0-next.8 → 19.0.0-rc.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/fesm2022/a11y.mjs +326 -282
- package/fesm2022/a11y.mjs.map +1 -1
- package/fesm2022/accordion.mjs +44 -49
- package/fesm2022/accordion.mjs.map +1 -1
- package/fesm2022/bidi.mjs +22 -23
- package/fesm2022/bidi.mjs.map +1 -1
- package/fesm2022/cdk.mjs +1 -1
- package/fesm2022/cdk.mjs.map +1 -1
- package/fesm2022/clipboard.mjs +34 -30
- package/fesm2022/clipboard.mjs.map +1 -1
- package/fesm2022/collections.mjs +31 -29
- package/fesm2022/collections.mjs.map +1 -1
- package/fesm2022/dialog.mjs +214 -135
- package/fesm2022/dialog.mjs.map +1 -1
- package/fesm2022/drag-drop.mjs +732 -494
- package/fesm2022/drag-drop.mjs.map +1 -1
- package/fesm2022/layout.mjs +21 -20
- package/fesm2022/layout.mjs.map +1 -1
- package/fesm2022/listbox.mjs +79 -67
- package/fesm2022/listbox.mjs.map +1 -1
- package/fesm2022/menu.mjs +247 -231
- package/fesm2022/menu.mjs.map +1 -1
- package/fesm2022/observers/private.mjs +16 -13
- package/fesm2022/observers/private.mjs.map +1 -1
- package/fesm2022/observers.mjs +26 -28
- package/fesm2022/observers.mjs.map +1 -1
- package/fesm2022/overlay.mjs +423 -293
- package/fesm2022/overlay.mjs.map +1 -1
- package/fesm2022/platform.mjs +51 -52
- package/fesm2022/platform.mjs.map +1 -1
- package/fesm2022/portal.mjs +115 -83
- package/fesm2022/portal.mjs.map +1 -1
- package/fesm2022/private.mjs +10 -11
- package/fesm2022/private.mjs.map +1 -1
- package/fesm2022/scrolling.mjs +191 -175
- package/fesm2022/scrolling.mjs.map +1 -1
- package/fesm2022/stepper.mjs +104 -78
- package/fesm2022/stepper.mjs.map +1 -1
- package/fesm2022/table.mjs +469 -279
- package/fesm2022/table.mjs.map +1 -1
- package/fesm2022/testing/selenium-webdriver.mjs +6 -0
- package/fesm2022/testing/selenium-webdriver.mjs.map +1 -1
- package/fesm2022/testing/testbed.mjs +16 -7
- package/fesm2022/testing/testbed.mjs.map +1 -1
- package/fesm2022/testing.mjs +7 -2
- package/fesm2022/testing.mjs.map +1 -1
- package/fesm2022/text-field.mjs +56 -49
- package/fesm2022/text-field.mjs.map +1 -1
- package/fesm2022/tree.mjs +243 -134
- package/fesm2022/tree.mjs.map +1 -1
- package/package.json +1 -1
- package/schematics/ng-add/index.js +1 -1
- package/schematics/ng-add/index.mjs +1 -1
- package/scrolling/index.d.ts +1 -1
- package/table/index.d.ts +21 -2
- package/tree/index.d.ts +3 -2
package/fesm2022/a11y.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { DOCUMENT } from '@angular/common';
|
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { inject, APP_ID, Injectable, QueryList, isSignal, effect, InjectionToken, afterNextRender, NgZone, Injector, ElementRef, booleanAttribute, Directive, Input, EventEmitter, Output, NgModule } from '@angular/core';
|
|
4
4
|
import { Platform, _getFocusedElementPierceShadowDom, normalizePassiveListenerOptions, _getEventTarget, _getShadowRoot } from '@angular/cdk/platform';
|
|
5
|
+
import { _CdkPrivateStyleLoader, _VisuallyHiddenLoader } from '@angular/cdk/private';
|
|
5
6
|
import { Subject, Subscription, isObservable, of, BehaviorSubject } from 'rxjs';
|
|
6
7
|
import { A, Z, ZERO, NINE, hasModifierKey, PAGE_DOWN, PAGE_UP, END, HOME, LEFT_ARROW, RIGHT_ARROW, UP_ARROW, DOWN_ARROW, TAB, ALT, CONTROL, MAC_META, META, SHIFT } from '@angular/cdk/keycodes';
|
|
7
8
|
import { tap, debounceTime, filter, map, take, skip, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
|
@@ -76,15 +77,16 @@ let nextId = 0;
|
|
|
76
77
|
* content.
|
|
77
78
|
*/
|
|
78
79
|
class AriaDescriber {
|
|
80
|
+
_platform = inject(Platform);
|
|
81
|
+
_document = inject(DOCUMENT);
|
|
82
|
+
/** Map of all registered message elements that have been placed into the document. */
|
|
83
|
+
_messageRegistry = new Map();
|
|
84
|
+
/** Container for all registered messages. */
|
|
85
|
+
_messagesContainer = null;
|
|
86
|
+
/** Unique ID for the service. */
|
|
87
|
+
_id = `${nextId++}`;
|
|
79
88
|
constructor() {
|
|
80
|
-
|
|
81
|
-
this._document = inject(DOCUMENT);
|
|
82
|
-
/** Map of all registered message elements that have been placed into the document. */
|
|
83
|
-
this._messageRegistry = new Map();
|
|
84
|
-
/** Container for all registered messages. */
|
|
85
|
-
this._messagesContainer = null;
|
|
86
|
-
/** Unique ID for the service. */
|
|
87
|
-
this._id = `${nextId++}`;
|
|
89
|
+
inject(_CdkPrivateStyleLoader).load(_VisuallyHiddenLoader);
|
|
88
90
|
this._id = inject(APP_ID) + '-' + nextId++;
|
|
89
91
|
}
|
|
90
92
|
describe(hostElement, message, role) {
|
|
@@ -242,10 +244,10 @@ class AriaDescriber {
|
|
|
242
244
|
_isElementNode(element) {
|
|
243
245
|
return element.nodeType === this._document.ELEMENT_NODE;
|
|
244
246
|
}
|
|
245
|
-
static
|
|
246
|
-
static
|
|
247
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: AriaDescriber, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
248
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: AriaDescriber, providedIn: 'root' });
|
|
247
249
|
}
|
|
248
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
250
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: AriaDescriber, decorators: [{
|
|
249
251
|
type: Injectable,
|
|
250
252
|
args: [{ providedIn: 'root' }]
|
|
251
253
|
}], ctorParameters: () => [] });
|
|
@@ -266,14 +268,15 @@ const DEFAULT_TYPEAHEAD_DEBOUNCE_INTERVAL_MS = 200;
|
|
|
266
268
|
* `role="listbox"` or `role="tree"` and other related roles.
|
|
267
269
|
*/
|
|
268
270
|
class Typeahead {
|
|
271
|
+
_letterKeyStream = new Subject();
|
|
272
|
+
_items = [];
|
|
273
|
+
_selectedItemIndex = -1;
|
|
274
|
+
/** Buffer for the letters that the user has pressed */
|
|
275
|
+
_pressedLetters = [];
|
|
276
|
+
_skipPredicateFn;
|
|
277
|
+
_selectedItem = new Subject();
|
|
278
|
+
selectedItem = this._selectedItem;
|
|
269
279
|
constructor(initialItems, config) {
|
|
270
|
-
this._letterKeyStream = new Subject();
|
|
271
|
-
this._items = [];
|
|
272
|
-
this._selectedItemIndex = -1;
|
|
273
|
-
/** Buffer for the letters that the user has pressed */
|
|
274
|
-
this._pressedLetters = [];
|
|
275
|
-
this._selectedItem = new Subject();
|
|
276
|
-
this.selectedItem = this._selectedItem;
|
|
277
280
|
const typeAheadInterval = typeof config?.debounceInterval === 'number'
|
|
278
281
|
? config.debounceInterval
|
|
279
282
|
: DEFAULT_TYPEAHEAD_DEBOUNCE_INTERVAL_MS;
|
|
@@ -346,28 +349,26 @@ class Typeahead {
|
|
|
346
349
|
* of items, it will set the active item correctly when arrow events occur.
|
|
347
350
|
*/
|
|
348
351
|
class ListKeyManager {
|
|
352
|
+
_items;
|
|
353
|
+
_activeItemIndex = -1;
|
|
354
|
+
_activeItem = null;
|
|
355
|
+
_wrap = false;
|
|
356
|
+
_typeaheadSubscription = Subscription.EMPTY;
|
|
357
|
+
_itemChangesSubscription;
|
|
358
|
+
_vertical = true;
|
|
359
|
+
_horizontal;
|
|
360
|
+
_allowedModifierKeys = [];
|
|
361
|
+
_homeAndEnd = false;
|
|
362
|
+
_pageUpAndDown = { enabled: false, delta: 10 };
|
|
363
|
+
_effectRef;
|
|
364
|
+
_typeahead;
|
|
365
|
+
/**
|
|
366
|
+
* Predicate function that can be used to check whether an item should be skipped
|
|
367
|
+
* by the key manager. By default, disabled items are skipped.
|
|
368
|
+
*/
|
|
369
|
+
_skipPredicateFn = (item) => item.disabled;
|
|
349
370
|
constructor(_items, injector) {
|
|
350
371
|
this._items = _items;
|
|
351
|
-
this._activeItemIndex = -1;
|
|
352
|
-
this._activeItem = null;
|
|
353
|
-
this._wrap = false;
|
|
354
|
-
this._typeaheadSubscription = Subscription.EMPTY;
|
|
355
|
-
this._vertical = true;
|
|
356
|
-
this._allowedModifierKeys = [];
|
|
357
|
-
this._homeAndEnd = false;
|
|
358
|
-
this._pageUpAndDown = { enabled: false, delta: 10 };
|
|
359
|
-
/**
|
|
360
|
-
* Predicate function that can be used to check whether an item should be skipped
|
|
361
|
-
* by the key manager. By default, disabled items are skipped.
|
|
362
|
-
*/
|
|
363
|
-
this._skipPredicateFn = (item) => item.disabled;
|
|
364
|
-
/**
|
|
365
|
-
* Stream that emits any time the TAB key is pressed, so components can react
|
|
366
|
-
* when focus is shifted off of the list.
|
|
367
|
-
*/
|
|
368
|
-
this.tabOut = new Subject();
|
|
369
|
-
/** Stream that emits whenever the active item of the list manager changes. */
|
|
370
|
-
this.change = new Subject();
|
|
371
372
|
// We allow for the items to be an array because, in some cases, the consumer may
|
|
372
373
|
// not have access to a QueryList of the items they want to manage (e.g. when the
|
|
373
374
|
// items aren't being collected via `ViewChildren` or `ContentChildren`).
|
|
@@ -381,6 +382,13 @@ class ListKeyManager {
|
|
|
381
382
|
this._effectRef = effect(() => this._itemsChanged(_items()), { injector });
|
|
382
383
|
}
|
|
383
384
|
}
|
|
385
|
+
/**
|
|
386
|
+
* Stream that emits any time the TAB key is pressed, so components can react
|
|
387
|
+
* when focus is shifted off of the list.
|
|
388
|
+
*/
|
|
389
|
+
tabOut = new Subject();
|
|
390
|
+
/** Stream that emits whenever the active item of the list manager changes. */
|
|
391
|
+
change = new Subject();
|
|
384
392
|
/**
|
|
385
393
|
* Sets the predicate function that determines which items should be skipped by the
|
|
386
394
|
* list key manager.
|
|
@@ -700,10 +708,7 @@ class ActiveDescendantKeyManager extends ListKeyManager {
|
|
|
700
708
|
}
|
|
701
709
|
|
|
702
710
|
class FocusKeyManager extends ListKeyManager {
|
|
703
|
-
|
|
704
|
-
super(...arguments);
|
|
705
|
-
this._origin = 'program';
|
|
706
|
-
}
|
|
711
|
+
_origin = 'program';
|
|
707
712
|
/**
|
|
708
713
|
* Sets the focus origin that will be passed in to the items for any subsequent `focus` calls.
|
|
709
714
|
* @param origin Focus origin to be used when focusing items.
|
|
@@ -726,6 +731,33 @@ class FocusKeyManager extends ListKeyManager {
|
|
|
726
731
|
* keyboard events occur.
|
|
727
732
|
*/
|
|
728
733
|
class TreeKeyManager {
|
|
734
|
+
/** The index of the currently active (focused) item. */
|
|
735
|
+
_activeItemIndex = -1;
|
|
736
|
+
/** The currently active (focused) item. */
|
|
737
|
+
_activeItem = null;
|
|
738
|
+
/** Whether or not we activate the item when it's focused. */
|
|
739
|
+
_shouldActivationFollowFocus = false;
|
|
740
|
+
/**
|
|
741
|
+
* The orientation that the tree is laid out in. In `rtl` mode, the behavior of Left and
|
|
742
|
+
* Right arrow are switched.
|
|
743
|
+
*/
|
|
744
|
+
_horizontalOrientation = 'ltr';
|
|
745
|
+
/**
|
|
746
|
+
* Predicate function that can be used to check whether an item should be skipped
|
|
747
|
+
* by the key manager.
|
|
748
|
+
*
|
|
749
|
+
* The default value for this doesn't skip any elements in order to keep tree items focusable
|
|
750
|
+
* when disabled. This aligns with ARIA guidelines:
|
|
751
|
+
* https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#focusabilityofdisabledcontrols.
|
|
752
|
+
*/
|
|
753
|
+
_skipPredicateFn = (_item) => false;
|
|
754
|
+
/** Function to determine equivalent items. */
|
|
755
|
+
_trackByFn = (item) => item;
|
|
756
|
+
/** Synchronous cache of the items to manage. */
|
|
757
|
+
_items = [];
|
|
758
|
+
_typeahead;
|
|
759
|
+
_typeaheadSubscription = Subscription.EMPTY;
|
|
760
|
+
_hasInitialFocused = false;
|
|
729
761
|
_initializeFocus() {
|
|
730
762
|
if (this._hasInitialFocused || this._items.length === 0) {
|
|
731
763
|
return;
|
|
@@ -762,34 +794,6 @@ class TreeKeyManager {
|
|
|
762
794
|
* default interval of 200ms.
|
|
763
795
|
*/
|
|
764
796
|
constructor(items, config) {
|
|
765
|
-
/** The index of the currently active (focused) item. */
|
|
766
|
-
this._activeItemIndex = -1;
|
|
767
|
-
/** The currently active (focused) item. */
|
|
768
|
-
this._activeItem = null;
|
|
769
|
-
/** Whether or not we activate the item when it's focused. */
|
|
770
|
-
this._shouldActivationFollowFocus = false;
|
|
771
|
-
/**
|
|
772
|
-
* The orientation that the tree is laid out in. In `rtl` mode, the behavior of Left and
|
|
773
|
-
* Right arrow are switched.
|
|
774
|
-
*/
|
|
775
|
-
this._horizontalOrientation = 'ltr';
|
|
776
|
-
/**
|
|
777
|
-
* Predicate function that can be used to check whether an item should be skipped
|
|
778
|
-
* by the key manager.
|
|
779
|
-
*
|
|
780
|
-
* The default value for this doesn't skip any elements in order to keep tree items focusable
|
|
781
|
-
* when disabled. This aligns with ARIA guidelines:
|
|
782
|
-
* https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#focusabilityofdisabledcontrols.
|
|
783
|
-
*/
|
|
784
|
-
this._skipPredicateFn = (_item) => false;
|
|
785
|
-
/** Function to determine equivalent items. */
|
|
786
|
-
this._trackByFn = (item) => item;
|
|
787
|
-
/** Synchronous cache of the items to manage. */
|
|
788
|
-
this._items = [];
|
|
789
|
-
this._typeaheadSubscription = Subscription.EMPTY;
|
|
790
|
-
this._hasInitialFocused = false;
|
|
791
|
-
/** Stream that emits any time the focused item changes. */
|
|
792
|
-
this.change = new Subject();
|
|
793
797
|
// We allow for the items to be an array or Observable because, in some cases, the consumer may
|
|
794
798
|
// not have access to a QueryList of the items they want to manage (e.g. when the
|
|
795
799
|
// items aren't being collected via `ViewChildren` or `ContentChildren`).
|
|
@@ -830,6 +834,8 @@ class TreeKeyManager {
|
|
|
830
834
|
this._setTypeAhead(config.typeAheadDebounceInterval);
|
|
831
835
|
}
|
|
832
836
|
}
|
|
837
|
+
/** Stream that emits any time the focused item changes. */
|
|
838
|
+
change = new Subject();
|
|
833
839
|
/** Cleans up the key manager. */
|
|
834
840
|
destroy() {
|
|
835
841
|
this._typeaheadSubscription.unsubscribe();
|
|
@@ -1084,12 +1090,10 @@ const TREE_KEY_MANAGER_FACTORY_PROVIDER = {
|
|
|
1084
1090
|
* @breaking-change 21.0.0
|
|
1085
1091
|
*/
|
|
1086
1092
|
class NoopTreeKeyManager {
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
this.change = new Subject();
|
|
1092
|
-
}
|
|
1093
|
+
_isNoopTreeKeyManager = true;
|
|
1094
|
+
// Provide change as required by TreeKeyManagerStrategy. NoopTreeKeyManager is a "noop"
|
|
1095
|
+
// implementation that does not emit to streams.
|
|
1096
|
+
change = new Subject();
|
|
1093
1097
|
destroy() {
|
|
1094
1098
|
this.change.complete();
|
|
1095
1099
|
}
|
|
@@ -1152,12 +1156,10 @@ const NOOP_TREE_KEY_MANAGER_FACTORY_PROVIDER = {
|
|
|
1152
1156
|
* Configuration for the isFocusable method.
|
|
1153
1157
|
*/
|
|
1154
1158
|
class IsFocusableConfig {
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
this.ignoreVisibility = false;
|
|
1160
|
-
}
|
|
1159
|
+
/**
|
|
1160
|
+
* Whether to count an element as focusable even if it is not currently visible.
|
|
1161
|
+
*/
|
|
1162
|
+
ignoreVisibility = false;
|
|
1161
1163
|
}
|
|
1162
1164
|
// The InteractivityChecker leans heavily on the ally.js accessibility utilities.
|
|
1163
1165
|
// Methods like `isTabbable` are only covering specific edge-cases for the browsers which are
|
|
@@ -1167,9 +1169,8 @@ class IsFocusableConfig {
|
|
|
1167
1169
|
* tabbable.
|
|
1168
1170
|
*/
|
|
1169
1171
|
class InteractivityChecker {
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
}
|
|
1172
|
+
_platform = inject(Platform);
|
|
1173
|
+
constructor() { }
|
|
1173
1174
|
/**
|
|
1174
1175
|
* Gets whether an element is disabled.
|
|
1175
1176
|
*
|
|
@@ -1274,10 +1275,10 @@ class InteractivityChecker {
|
|
|
1274
1275
|
!this.isDisabled(element) &&
|
|
1275
1276
|
(config?.ignoreVisibility || this.isVisible(element)));
|
|
1276
1277
|
}
|
|
1277
|
-
static
|
|
1278
|
-
static
|
|
1278
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: InteractivityChecker, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1279
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: InteractivityChecker, providedIn: 'root' });
|
|
1279
1280
|
}
|
|
1280
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
1281
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: InteractivityChecker, decorators: [{
|
|
1281
1282
|
type: Injectable,
|
|
1282
1283
|
args: [{ providedIn: 'root' }]
|
|
1283
1284
|
}], ctorParameters: () => [] });
|
|
@@ -1383,6 +1384,17 @@ function getWindow(node) {
|
|
|
1383
1384
|
* Things like `tabIndex > 0`, flex `order`, and shadow roots can cause the two to be misaligned.
|
|
1384
1385
|
*/
|
|
1385
1386
|
class FocusTrap {
|
|
1387
|
+
_element;
|
|
1388
|
+
_checker;
|
|
1389
|
+
_ngZone;
|
|
1390
|
+
_document;
|
|
1391
|
+
_injector;
|
|
1392
|
+
_startAnchor;
|
|
1393
|
+
_endAnchor;
|
|
1394
|
+
_hasAttached = false;
|
|
1395
|
+
// Event listeners for the anchors. Need to be regular functions so that we can unbind them later.
|
|
1396
|
+
startAnchorListener = () => this.focusLastTabbableElement();
|
|
1397
|
+
endAnchorListener = () => this.focusFirstTabbableElement();
|
|
1386
1398
|
/** Whether the focus trap is active. */
|
|
1387
1399
|
get enabled() {
|
|
1388
1400
|
return this._enabled;
|
|
@@ -1394,6 +1406,7 @@ class FocusTrap {
|
|
|
1394
1406
|
this._toggleAnchorTabIndex(value, this._endAnchor);
|
|
1395
1407
|
}
|
|
1396
1408
|
}
|
|
1409
|
+
_enabled = true;
|
|
1397
1410
|
constructor(_element, _checker, _ngZone, _document, deferAnchors = false,
|
|
1398
1411
|
/** @breaking-change 20.0.0 param to become required */
|
|
1399
1412
|
_injector) {
|
|
@@ -1402,11 +1415,6 @@ class FocusTrap {
|
|
|
1402
1415
|
this._ngZone = _ngZone;
|
|
1403
1416
|
this._document = _document;
|
|
1404
1417
|
this._injector = _injector;
|
|
1405
|
-
this._hasAttached = false;
|
|
1406
|
-
// Event listeners for the anchors. Need to be regular functions so that we can unbind them later.
|
|
1407
|
-
this.startAnchorListener = () => this.focusLastTabbableElement();
|
|
1408
|
-
this.endAnchorListener = () => this.focusFirstTabbableElement();
|
|
1409
|
-
this._enabled = true;
|
|
1410
1418
|
if (!deferAnchors) {
|
|
1411
1419
|
this.attachAnchors();
|
|
1412
1420
|
}
|
|
@@ -1652,11 +1660,12 @@ class FocusTrap {
|
|
|
1652
1660
|
* Factory that allows easy instantiation of focus traps.
|
|
1653
1661
|
*/
|
|
1654
1662
|
class FocusTrapFactory {
|
|
1663
|
+
_checker = inject(InteractivityChecker);
|
|
1664
|
+
_ngZone = inject(NgZone);
|
|
1665
|
+
_document = inject(DOCUMENT);
|
|
1666
|
+
_injector = inject(Injector);
|
|
1655
1667
|
constructor() {
|
|
1656
|
-
|
|
1657
|
-
this._ngZone = inject(NgZone);
|
|
1658
|
-
this._document = inject(DOCUMENT);
|
|
1659
|
-
this._injector = inject(Injector);
|
|
1668
|
+
inject(_CdkPrivateStyleLoader).load(_VisuallyHiddenLoader);
|
|
1660
1669
|
}
|
|
1661
1670
|
/**
|
|
1662
1671
|
* Creates a focus-trapped region around the given element.
|
|
@@ -1668,15 +1677,21 @@ class FocusTrapFactory {
|
|
|
1668
1677
|
create(element, deferCaptureElements = false) {
|
|
1669
1678
|
return new FocusTrap(element, this._checker, this._ngZone, this._document, deferCaptureElements, this._injector);
|
|
1670
1679
|
}
|
|
1671
|
-
static
|
|
1672
|
-
static
|
|
1680
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: FocusTrapFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1681
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: FocusTrapFactory, providedIn: 'root' });
|
|
1673
1682
|
}
|
|
1674
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
1683
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: FocusTrapFactory, decorators: [{
|
|
1675
1684
|
type: Injectable,
|
|
1676
1685
|
args: [{ providedIn: 'root' }]
|
|
1677
1686
|
}], ctorParameters: () => [] });
|
|
1678
1687
|
/** Directive for trapping focus within a region. */
|
|
1679
1688
|
class CdkTrapFocus {
|
|
1689
|
+
_elementRef = inject(ElementRef);
|
|
1690
|
+
_focusTrapFactory = inject(FocusTrapFactory);
|
|
1691
|
+
/** Underlying FocusTrap instance. */
|
|
1692
|
+
focusTrap;
|
|
1693
|
+
/** Previously focused element to restore focus to upon destroy when using autoCapture. */
|
|
1694
|
+
_previouslyFocusedElement = null;
|
|
1680
1695
|
/** Whether the focus trap is active. */
|
|
1681
1696
|
get enabled() {
|
|
1682
1697
|
return this.focusTrap?.enabled || false;
|
|
@@ -1686,11 +1701,12 @@ class CdkTrapFocus {
|
|
|
1686
1701
|
this.focusTrap.enabled = value;
|
|
1687
1702
|
}
|
|
1688
1703
|
}
|
|
1704
|
+
/**
|
|
1705
|
+
* Whether the directive should automatically move focus into the trapped region upon
|
|
1706
|
+
* initialization and return focus to the previous activeElement upon destruction.
|
|
1707
|
+
*/
|
|
1708
|
+
autoCapture;
|
|
1689
1709
|
constructor() {
|
|
1690
|
-
this._elementRef = inject(ElementRef);
|
|
1691
|
-
this._focusTrapFactory = inject(FocusTrapFactory);
|
|
1692
|
-
/** Previously focused element to restore focus to upon destroy when using autoCapture. */
|
|
1693
|
-
this._previouslyFocusedElement = null;
|
|
1694
1710
|
const platform = inject(Platform);
|
|
1695
1711
|
if (platform.isBrowser) {
|
|
1696
1712
|
this.focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement, true);
|
|
@@ -1729,15 +1745,14 @@ class CdkTrapFocus {
|
|
|
1729
1745
|
this._previouslyFocusedElement = _getFocusedElementPierceShadowDom();
|
|
1730
1746
|
this.focusTrap?.focusInitialElementWhenReady();
|
|
1731
1747
|
}
|
|
1732
|
-
static
|
|
1733
|
-
static
|
|
1748
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: CdkTrapFocus, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1749
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.0.0-next.10", type: CdkTrapFocus, isStandalone: true, selector: "[cdkTrapFocus]", inputs: { enabled: ["cdkTrapFocus", "enabled", booleanAttribute], autoCapture: ["cdkTrapFocusAutoCapture", "autoCapture", booleanAttribute] }, exportAs: ["cdkTrapFocus"], usesOnChanges: true, ngImport: i0 });
|
|
1734
1750
|
}
|
|
1735
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
1751
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: CdkTrapFocus, decorators: [{
|
|
1736
1752
|
type: Directive,
|
|
1737
1753
|
args: [{
|
|
1738
1754
|
selector: '[cdkTrapFocus]',
|
|
1739
1755
|
exportAs: 'cdkTrapFocus',
|
|
1740
|
-
standalone: true,
|
|
1741
1756
|
}]
|
|
1742
1757
|
}], ctorParameters: () => [], propDecorators: { enabled: [{
|
|
1743
1758
|
type: Input,
|
|
@@ -1754,6 +1769,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.8",
|
|
|
1754
1769
|
* See FocusTrapInertStrategy.
|
|
1755
1770
|
*/
|
|
1756
1771
|
class ConfigurableFocusTrap extends FocusTrap {
|
|
1772
|
+
_focusTrapManager;
|
|
1773
|
+
_inertStrategy;
|
|
1757
1774
|
/** Whether the FocusTrap is enabled. */
|
|
1758
1775
|
get enabled() {
|
|
1759
1776
|
return this._enabled;
|
|
@@ -1795,10 +1812,8 @@ class ConfigurableFocusTrap extends FocusTrap {
|
|
|
1795
1812
|
* listener to redirect focus back inside the FocusTrap.
|
|
1796
1813
|
*/
|
|
1797
1814
|
class EventListenerFocusTrapInertStrategy {
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
this._listener = null;
|
|
1801
|
-
}
|
|
1815
|
+
/** Focus event handler. */
|
|
1816
|
+
_listener = null;
|
|
1802
1817
|
/** Adds a document event listener that keeps focus inside the FocusTrap. */
|
|
1803
1818
|
preventFocus(focusTrap) {
|
|
1804
1819
|
// Ensure there's only one listener per document
|
|
@@ -1849,11 +1864,9 @@ const FOCUS_TRAP_INERT_STRATEGY = new InjectionToken('FOCUS_TRAP_INERT_STRATEGY'
|
|
|
1849
1864
|
|
|
1850
1865
|
/** Injectable that ensures only the most recently enabled FocusTrap is active. */
|
|
1851
1866
|
class FocusTrapManager {
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
this._focusTrapStack = [];
|
|
1856
|
-
}
|
|
1867
|
+
// A stack of the FocusTraps on the page. Only the FocusTrap at the
|
|
1868
|
+
// top of the stack is active.
|
|
1869
|
+
_focusTrapStack = [];
|
|
1857
1870
|
/**
|
|
1858
1871
|
* Disables the FocusTrap at the top of the stack, and then pushes
|
|
1859
1872
|
* the new FocusTrap onto the stack.
|
|
@@ -1883,22 +1896,23 @@ class FocusTrapManager {
|
|
|
1883
1896
|
}
|
|
1884
1897
|
}
|
|
1885
1898
|
}
|
|
1886
|
-
static
|
|
1887
|
-
static
|
|
1899
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: FocusTrapManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1900
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: FocusTrapManager, providedIn: 'root' });
|
|
1888
1901
|
}
|
|
1889
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
1902
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: FocusTrapManager, decorators: [{
|
|
1890
1903
|
type: Injectable,
|
|
1891
1904
|
args: [{ providedIn: 'root' }]
|
|
1892
1905
|
}] });
|
|
1893
1906
|
|
|
1894
1907
|
/** Factory that allows easy instantiation of configurable focus traps. */
|
|
1895
1908
|
class ConfigurableFocusTrapFactory {
|
|
1909
|
+
_checker = inject(InteractivityChecker);
|
|
1910
|
+
_ngZone = inject(NgZone);
|
|
1911
|
+
_focusTrapManager = inject(FocusTrapManager);
|
|
1912
|
+
_document = inject(DOCUMENT);
|
|
1913
|
+
_inertStrategy;
|
|
1914
|
+
_injector = inject(Injector);
|
|
1896
1915
|
constructor() {
|
|
1897
|
-
this._checker = inject(InteractivityChecker);
|
|
1898
|
-
this._ngZone = inject(NgZone);
|
|
1899
|
-
this._focusTrapManager = inject(FocusTrapManager);
|
|
1900
|
-
this._document = inject(DOCUMENT);
|
|
1901
|
-
this._injector = inject(Injector);
|
|
1902
1916
|
const inertStrategy = inject(FOCUS_TRAP_INERT_STRATEGY, { optional: true });
|
|
1903
1917
|
// TODO split up the strategies into different modules, similar to DateAdapter.
|
|
1904
1918
|
this._inertStrategy = inertStrategy || new EventListenerFocusTrapInertStrategy();
|
|
@@ -1913,10 +1927,10 @@ class ConfigurableFocusTrapFactory {
|
|
|
1913
1927
|
}
|
|
1914
1928
|
return new ConfigurableFocusTrap(element, this._checker, this._ngZone, this._document, this._focusTrapManager, this._inertStrategy, configObject, this._injector);
|
|
1915
1929
|
}
|
|
1916
|
-
static
|
|
1917
|
-
static
|
|
1930
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: ConfigurableFocusTrapFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1931
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: ConfigurableFocusTrapFactory, providedIn: 'root' });
|
|
1918
1932
|
}
|
|
1919
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
1933
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: ConfigurableFocusTrapFactory, decorators: [{
|
|
1920
1934
|
type: Injectable,
|
|
1921
1935
|
args: [{ providedIn: 'root' }]
|
|
1922
1936
|
}], ctorParameters: () => [] });
|
|
@@ -1998,70 +2012,76 @@ const modalityEventListenerOptions = normalizePassiveListenerOptions({
|
|
|
1998
2012
|
* undefined.
|
|
1999
2013
|
*/
|
|
2000
2014
|
class InputModalityDetector {
|
|
2015
|
+
_platform = inject(Platform);
|
|
2016
|
+
/** Emits whenever an input modality is detected. */
|
|
2017
|
+
modalityDetected;
|
|
2018
|
+
/** Emits when the input modality changes. */
|
|
2019
|
+
modalityChanged;
|
|
2001
2020
|
/** The most recently detected input modality. */
|
|
2002
2021
|
get mostRecentModality() {
|
|
2003
2022
|
return this._modality.value;
|
|
2004
2023
|
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2024
|
+
/**
|
|
2025
|
+
* The most recently detected input modality event target. Is null if no input modality has been
|
|
2026
|
+
* detected or if the associated event target is null for some unknown reason.
|
|
2027
|
+
*/
|
|
2028
|
+
_mostRecentTarget = null;
|
|
2029
|
+
/** The underlying BehaviorSubject that emits whenever an input modality is detected. */
|
|
2030
|
+
_modality = new BehaviorSubject(null);
|
|
2031
|
+
/** Options for this InputModalityDetector. */
|
|
2032
|
+
_options;
|
|
2033
|
+
/**
|
|
2034
|
+
* The timestamp of the last touch input modality. Used to determine whether mousedown events
|
|
2035
|
+
* should be attributed to mouse or touch.
|
|
2036
|
+
*/
|
|
2037
|
+
_lastTouchMs = 0;
|
|
2038
|
+
/**
|
|
2039
|
+
* Handles keydown events. Must be an arrow function in order to preserve the context when it gets
|
|
2040
|
+
* bound.
|
|
2041
|
+
*/
|
|
2042
|
+
_onKeydown = (event) => {
|
|
2043
|
+
// If this is one of the keys we should ignore, then ignore it and don't update the input
|
|
2044
|
+
// modality to keyboard.
|
|
2045
|
+
if (this._options?.ignoreKeys?.some(keyCode => keyCode === event.keyCode)) {
|
|
2046
|
+
return;
|
|
2047
|
+
}
|
|
2048
|
+
this._modality.next('keyboard');
|
|
2049
|
+
this._mostRecentTarget = _getEventTarget(event);
|
|
2050
|
+
};
|
|
2051
|
+
/**
|
|
2052
|
+
* Handles mousedown events. Must be an arrow function in order to preserve the context when it
|
|
2053
|
+
* gets bound.
|
|
2054
|
+
*/
|
|
2055
|
+
_onMousedown = (event) => {
|
|
2056
|
+
// Touches trigger both touch and mouse events, so we need to distinguish between mouse events
|
|
2057
|
+
// that were triggered via mouse vs touch. To do so, check if the mouse event occurs closely
|
|
2058
|
+
// after the previous touch event.
|
|
2059
|
+
if (Date.now() - this._lastTouchMs < TOUCH_BUFFER_MS) {
|
|
2060
|
+
return;
|
|
2061
|
+
}
|
|
2062
|
+
// Fake mousedown events are fired by some screen readers when controls are activated by the
|
|
2063
|
+
// screen reader. Attribute them to keyboard input modality.
|
|
2064
|
+
this._modality.next(isFakeMousedownFromScreenReader(event) ? 'keyboard' : 'mouse');
|
|
2065
|
+
this._mostRecentTarget = _getEventTarget(event);
|
|
2066
|
+
};
|
|
2067
|
+
/**
|
|
2068
|
+
* Handles touchstart events. Must be an arrow function in order to preserve the context when it
|
|
2069
|
+
* gets bound.
|
|
2070
|
+
*/
|
|
2071
|
+
_onTouchstart = (event) => {
|
|
2072
|
+
// Same scenario as mentioned in _onMousedown, but on touch screen devices, fake touchstart
|
|
2073
|
+
// events are fired. Again, attribute to keyboard input modality.
|
|
2074
|
+
if (isFakeTouchstartFromScreenReader(event)) {
|
|
2029
2075
|
this._modality.next('keyboard');
|
|
2030
|
-
|
|
2031
|
-
}
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
this.
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
// after the previous touch event.
|
|
2040
|
-
if (Date.now() - this._lastTouchMs < TOUCH_BUFFER_MS) {
|
|
2041
|
-
return;
|
|
2042
|
-
}
|
|
2043
|
-
// Fake mousedown events are fired by some screen readers when controls are activated by the
|
|
2044
|
-
// screen reader. Attribute them to keyboard input modality.
|
|
2045
|
-
this._modality.next(isFakeMousedownFromScreenReader(event) ? 'keyboard' : 'mouse');
|
|
2046
|
-
this._mostRecentTarget = _getEventTarget(event);
|
|
2047
|
-
};
|
|
2048
|
-
/**
|
|
2049
|
-
* Handles touchstart events. Must be an arrow function in order to preserve the context when it
|
|
2050
|
-
* gets bound.
|
|
2051
|
-
*/
|
|
2052
|
-
this._onTouchstart = (event) => {
|
|
2053
|
-
// Same scenario as mentioned in _onMousedown, but on touch screen devices, fake touchstart
|
|
2054
|
-
// events are fired. Again, attribute to keyboard input modality.
|
|
2055
|
-
if (isFakeTouchstartFromScreenReader(event)) {
|
|
2056
|
-
this._modality.next('keyboard');
|
|
2057
|
-
return;
|
|
2058
|
-
}
|
|
2059
|
-
// Store the timestamp of this touch event, as it's used to distinguish between mouse events
|
|
2060
|
-
// triggered via mouse vs touch.
|
|
2061
|
-
this._lastTouchMs = Date.now();
|
|
2062
|
-
this._modality.next('touch');
|
|
2063
|
-
this._mostRecentTarget = _getEventTarget(event);
|
|
2064
|
-
};
|
|
2076
|
+
return;
|
|
2077
|
+
}
|
|
2078
|
+
// Store the timestamp of this touch event, as it's used to distinguish between mouse events
|
|
2079
|
+
// triggered via mouse vs touch.
|
|
2080
|
+
this._lastTouchMs = Date.now();
|
|
2081
|
+
this._modality.next('touch');
|
|
2082
|
+
this._mostRecentTarget = _getEventTarget(event);
|
|
2083
|
+
};
|
|
2084
|
+
constructor() {
|
|
2065
2085
|
const ngZone = inject(NgZone);
|
|
2066
2086
|
const document = inject(DOCUMENT);
|
|
2067
2087
|
const options = inject(INPUT_MODALITY_DETECTOR_OPTIONS, { optional: true });
|
|
@@ -2090,10 +2110,10 @@ class InputModalityDetector {
|
|
|
2090
2110
|
document.removeEventListener('touchstart', this._onTouchstart, modalityEventListenerOptions);
|
|
2091
2111
|
}
|
|
2092
2112
|
}
|
|
2093
|
-
static
|
|
2094
|
-
static
|
|
2113
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: InputModalityDetector, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2114
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: InputModalityDetector, providedIn: 'root' });
|
|
2095
2115
|
}
|
|
2096
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
2116
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: InputModalityDetector, decorators: [{
|
|
2097
2117
|
type: Injectable,
|
|
2098
2118
|
args: [{ providedIn: 'root' }]
|
|
2099
2119
|
}], ctorParameters: () => [] });
|
|
@@ -2111,12 +2131,16 @@ const LIVE_ANNOUNCER_DEFAULT_OPTIONS = new InjectionToken('LIVE_ANNOUNCER_DEFAUL
|
|
|
2111
2131
|
|
|
2112
2132
|
let uniqueIds = 0;
|
|
2113
2133
|
class LiveAnnouncer {
|
|
2134
|
+
_ngZone = inject(NgZone);
|
|
2135
|
+
_defaultOptions = inject(LIVE_ANNOUNCER_DEFAULT_OPTIONS, {
|
|
2136
|
+
optional: true,
|
|
2137
|
+
});
|
|
2138
|
+
_liveElement;
|
|
2139
|
+
_document = inject(DOCUMENT);
|
|
2140
|
+
_previousTimeout;
|
|
2141
|
+
_currentPromise;
|
|
2142
|
+
_currentResolve;
|
|
2114
2143
|
constructor() {
|
|
2115
|
-
this._ngZone = inject(NgZone);
|
|
2116
|
-
this._defaultOptions = inject(LIVE_ANNOUNCER_DEFAULT_OPTIONS, {
|
|
2117
|
-
optional: true,
|
|
2118
|
-
});
|
|
2119
|
-
this._document = inject(DOCUMENT);
|
|
2120
2144
|
const elementToken = inject(LIVE_ANNOUNCER_ELEMENT_TOKEN, { optional: true });
|
|
2121
2145
|
this._liveElement = elementToken || this._createLiveElement();
|
|
2122
2146
|
}
|
|
@@ -2224,10 +2248,10 @@ class LiveAnnouncer {
|
|
|
2224
2248
|
}
|
|
2225
2249
|
}
|
|
2226
2250
|
}
|
|
2227
|
-
static
|
|
2228
|
-
static
|
|
2251
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: LiveAnnouncer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2252
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: LiveAnnouncer, providedIn: 'root' });
|
|
2229
2253
|
}
|
|
2230
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
2254
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: LiveAnnouncer, decorators: [{
|
|
2231
2255
|
type: Injectable,
|
|
2232
2256
|
args: [{ providedIn: 'root' }]
|
|
2233
2257
|
}], ctorParameters: () => [] });
|
|
@@ -2236,6 +2260,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.8",
|
|
|
2236
2260
|
* with a wider range of browsers and screen readers.
|
|
2237
2261
|
*/
|
|
2238
2262
|
class CdkAriaLive {
|
|
2263
|
+
_elementRef = inject(ElementRef);
|
|
2264
|
+
_liveAnnouncer = inject(LiveAnnouncer);
|
|
2265
|
+
_contentObserver = inject(ContentObserver);
|
|
2266
|
+
_ngZone = inject(NgZone);
|
|
2239
2267
|
/** The aria-live politeness level to use when announcing messages. */
|
|
2240
2268
|
get politeness() {
|
|
2241
2269
|
return this._politeness;
|
|
@@ -2263,27 +2291,27 @@ class CdkAriaLive {
|
|
|
2263
2291
|
});
|
|
2264
2292
|
}
|
|
2265
2293
|
}
|
|
2294
|
+
_politeness = 'polite';
|
|
2295
|
+
/** Time in milliseconds after which to clear out the announcer element. */
|
|
2296
|
+
duration;
|
|
2297
|
+
_previousAnnouncedText;
|
|
2298
|
+
_subscription;
|
|
2266
2299
|
constructor() {
|
|
2267
|
-
|
|
2268
|
-
this._liveAnnouncer = inject(LiveAnnouncer);
|
|
2269
|
-
this._contentObserver = inject(ContentObserver);
|
|
2270
|
-
this._ngZone = inject(NgZone);
|
|
2271
|
-
this._politeness = 'polite';
|
|
2300
|
+
inject(_CdkPrivateStyleLoader).load(_VisuallyHiddenLoader);
|
|
2272
2301
|
}
|
|
2273
2302
|
ngOnDestroy() {
|
|
2274
2303
|
if (this._subscription) {
|
|
2275
2304
|
this._subscription.unsubscribe();
|
|
2276
2305
|
}
|
|
2277
2306
|
}
|
|
2278
|
-
static
|
|
2279
|
-
static
|
|
2307
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: CdkAriaLive, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2308
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.0-next.10", type: CdkAriaLive, isStandalone: true, selector: "[cdkAriaLive]", inputs: { politeness: ["cdkAriaLive", "politeness"], duration: ["cdkAriaLiveDuration", "duration"] }, exportAs: ["cdkAriaLive"], ngImport: i0 });
|
|
2280
2309
|
}
|
|
2281
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
2310
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: CdkAriaLive, decorators: [{
|
|
2282
2311
|
type: Directive,
|
|
2283
2312
|
args: [{
|
|
2284
2313
|
selector: '[cdkAriaLive]',
|
|
2285
2314
|
exportAs: 'cdkAriaLive',
|
|
2286
|
-
standalone: true,
|
|
2287
2315
|
}]
|
|
2288
2316
|
}], ctorParameters: () => [], propDecorators: { politeness: [{
|
|
2289
2317
|
type: Input,
|
|
@@ -2320,65 +2348,76 @@ const captureEventListenerOptions = normalizePassiveListenerOptions({
|
|
|
2320
2348
|
});
|
|
2321
2349
|
/** Monitors mouse and keyboard events to determine the cause of focus events. */
|
|
2322
2350
|
class FocusMonitor {
|
|
2351
|
+
_ngZone = inject(NgZone);
|
|
2352
|
+
_platform = inject(Platform);
|
|
2353
|
+
_inputModalityDetector = inject(InputModalityDetector);
|
|
2354
|
+
/** The focus origin that the next focus event is a result of. */
|
|
2355
|
+
_origin = null;
|
|
2356
|
+
/** The FocusOrigin of the last focus event tracked by the FocusMonitor. */
|
|
2357
|
+
_lastFocusOrigin;
|
|
2358
|
+
/** Whether the window has just been focused. */
|
|
2359
|
+
_windowFocused = false;
|
|
2360
|
+
/** The timeout id of the window focus timeout. */
|
|
2361
|
+
_windowFocusTimeoutId;
|
|
2362
|
+
/** The timeout id of the origin clearing timeout. */
|
|
2363
|
+
_originTimeoutId;
|
|
2364
|
+
/**
|
|
2365
|
+
* Whether the origin was determined via a touch interaction. Necessary as properly attributing
|
|
2366
|
+
* focus events to touch interactions requires special logic.
|
|
2367
|
+
*/
|
|
2368
|
+
_originFromTouchInteraction = false;
|
|
2369
|
+
/** Map of elements being monitored to their info. */
|
|
2370
|
+
_elementInfo = new Map();
|
|
2371
|
+
/** The number of elements currently being monitored. */
|
|
2372
|
+
_monitoredElementCount = 0;
|
|
2373
|
+
/**
|
|
2374
|
+
* Keeps track of the root nodes to which we've currently bound a focus/blur handler,
|
|
2375
|
+
* as well as the number of monitored elements that they contain. We have to treat focus/blur
|
|
2376
|
+
* handlers differently from the rest of the events, because the browser won't emit events
|
|
2377
|
+
* to the document when focus moves inside of a shadow root.
|
|
2378
|
+
*/
|
|
2379
|
+
_rootNodeFocusListenerCount = new Map();
|
|
2380
|
+
/**
|
|
2381
|
+
* The specified detection mode, used for attributing the origin of a focus
|
|
2382
|
+
* event.
|
|
2383
|
+
*/
|
|
2384
|
+
_detectionMode;
|
|
2385
|
+
/**
|
|
2386
|
+
* Event listener for `focus` events on the window.
|
|
2387
|
+
* Needs to be an arrow function in order to preserve the context when it gets bound.
|
|
2388
|
+
*/
|
|
2389
|
+
_windowFocusListener = () => {
|
|
2390
|
+
// Make a note of when the window regains focus, so we can
|
|
2391
|
+
// restore the origin info for the focused element.
|
|
2392
|
+
this._windowFocused = true;
|
|
2393
|
+
this._windowFocusTimeoutId = window.setTimeout(() => (this._windowFocused = false));
|
|
2394
|
+
};
|
|
2395
|
+
/** Used to reference correct document/window */
|
|
2396
|
+
_document = inject(DOCUMENT, { optional: true });
|
|
2397
|
+
/** Subject for stopping our InputModalityDetector subscription. */
|
|
2398
|
+
_stopInputModalityDetector = new Subject();
|
|
2323
2399
|
constructor() {
|
|
2324
|
-
this._ngZone = inject(NgZone);
|
|
2325
|
-
this._platform = inject(Platform);
|
|
2326
|
-
this._inputModalityDetector = inject(InputModalityDetector);
|
|
2327
|
-
/** The focus origin that the next focus event is a result of. */
|
|
2328
|
-
this._origin = null;
|
|
2329
|
-
/** Whether the window has just been focused. */
|
|
2330
|
-
this._windowFocused = false;
|
|
2331
|
-
/**
|
|
2332
|
-
* Whether the origin was determined via a touch interaction. Necessary as properly attributing
|
|
2333
|
-
* focus events to touch interactions requires special logic.
|
|
2334
|
-
*/
|
|
2335
|
-
this._originFromTouchInteraction = false;
|
|
2336
|
-
/** Map of elements being monitored to their info. */
|
|
2337
|
-
this._elementInfo = new Map();
|
|
2338
|
-
/** The number of elements currently being monitored. */
|
|
2339
|
-
this._monitoredElementCount = 0;
|
|
2340
|
-
/**
|
|
2341
|
-
* Keeps track of the root nodes to which we've currently bound a focus/blur handler,
|
|
2342
|
-
* as well as the number of monitored elements that they contain. We have to treat focus/blur
|
|
2343
|
-
* handlers differently from the rest of the events, because the browser won't emit events
|
|
2344
|
-
* to the document when focus moves inside of a shadow root.
|
|
2345
|
-
*/
|
|
2346
|
-
this._rootNodeFocusListenerCount = new Map();
|
|
2347
|
-
/**
|
|
2348
|
-
* Event listener for `focus` events on the window.
|
|
2349
|
-
* Needs to be an arrow function in order to preserve the context when it gets bound.
|
|
2350
|
-
*/
|
|
2351
|
-
this._windowFocusListener = () => {
|
|
2352
|
-
// Make a note of when the window regains focus, so we can
|
|
2353
|
-
// restore the origin info for the focused element.
|
|
2354
|
-
this._windowFocused = true;
|
|
2355
|
-
this._windowFocusTimeoutId = window.setTimeout(() => (this._windowFocused = false));
|
|
2356
|
-
};
|
|
2357
|
-
/** Used to reference correct document/window */
|
|
2358
|
-
this._document = inject(DOCUMENT, { optional: true });
|
|
2359
|
-
/** Subject for stopping our InputModalityDetector subscription. */
|
|
2360
|
-
this._stopInputModalityDetector = new Subject();
|
|
2361
|
-
/**
|
|
2362
|
-
* Event listener for `focus` and 'blur' events on the document.
|
|
2363
|
-
* Needs to be an arrow function in order to preserve the context when it gets bound.
|
|
2364
|
-
*/
|
|
2365
|
-
this._rootNodeFocusAndBlurListener = (event) => {
|
|
2366
|
-
const target = _getEventTarget(event);
|
|
2367
|
-
// We need to walk up the ancestor chain in order to support `checkChildren`.
|
|
2368
|
-
for (let element = target; element; element = element.parentElement) {
|
|
2369
|
-
if (event.type === 'focus') {
|
|
2370
|
-
this._onFocus(event, element);
|
|
2371
|
-
}
|
|
2372
|
-
else {
|
|
2373
|
-
this._onBlur(event, element);
|
|
2374
|
-
}
|
|
2375
|
-
}
|
|
2376
|
-
};
|
|
2377
2400
|
const options = inject(FOCUS_MONITOR_DEFAULT_OPTIONS, {
|
|
2378
2401
|
optional: true,
|
|
2379
2402
|
});
|
|
2380
2403
|
this._detectionMode = options?.detectionMode || FocusMonitorDetectionMode.IMMEDIATE;
|
|
2381
2404
|
}
|
|
2405
|
+
/**
|
|
2406
|
+
* Event listener for `focus` and 'blur' events on the document.
|
|
2407
|
+
* Needs to be an arrow function in order to preserve the context when it gets bound.
|
|
2408
|
+
*/
|
|
2409
|
+
_rootNodeFocusAndBlurListener = (event) => {
|
|
2410
|
+
const target = _getEventTarget(event);
|
|
2411
|
+
// We need to walk up the ancestor chain in order to support `checkChildren`.
|
|
2412
|
+
for (let element = target; element; element = element.parentElement) {
|
|
2413
|
+
if (event.type === 'focus') {
|
|
2414
|
+
this._onFocus(event, element);
|
|
2415
|
+
}
|
|
2416
|
+
else {
|
|
2417
|
+
this._onBlur(event, element);
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
};
|
|
2382
2421
|
monitor(element, checkChildren = false) {
|
|
2383
2422
|
const nativeElement = coerceElement(element);
|
|
2384
2423
|
// Do nothing if we're not on the browser platform or the passed in node isn't an element.
|
|
@@ -2681,10 +2720,10 @@ class FocusMonitor {
|
|
|
2681
2720
|
}
|
|
2682
2721
|
return false;
|
|
2683
2722
|
}
|
|
2684
|
-
static
|
|
2685
|
-
static
|
|
2723
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: FocusMonitor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2724
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: FocusMonitor, providedIn: 'root' });
|
|
2686
2725
|
}
|
|
2687
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
2726
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: FocusMonitor, decorators: [{
|
|
2688
2727
|
type: Injectable,
|
|
2689
2728
|
args: [{ providedIn: 'root' }]
|
|
2690
2729
|
}], ctorParameters: () => [] });
|
|
@@ -2698,12 +2737,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.8",
|
|
|
2698
2737
|
* 2) cdkMonitorSubtreeFocus: considers an element focused if it or any of its children are focused.
|
|
2699
2738
|
*/
|
|
2700
2739
|
class CdkMonitorFocus {
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
}
|
|
2740
|
+
_elementRef = inject(ElementRef);
|
|
2741
|
+
_focusMonitor = inject(FocusMonitor);
|
|
2742
|
+
_monitorSubscription;
|
|
2743
|
+
_focusOrigin = null;
|
|
2744
|
+
cdkFocusChange = new EventEmitter();
|
|
2745
|
+
constructor() { }
|
|
2707
2746
|
get focusOrigin() {
|
|
2708
2747
|
return this._focusOrigin;
|
|
2709
2748
|
}
|
|
@@ -2722,15 +2761,14 @@ class CdkMonitorFocus {
|
|
|
2722
2761
|
this._monitorSubscription.unsubscribe();
|
|
2723
2762
|
}
|
|
2724
2763
|
}
|
|
2725
|
-
static
|
|
2726
|
-
static
|
|
2764
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: CdkMonitorFocus, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2765
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.0-next.10", type: CdkMonitorFocus, isStandalone: true, selector: "[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]", outputs: { cdkFocusChange: "cdkFocusChange" }, exportAs: ["cdkMonitorFocus"], ngImport: i0 });
|
|
2727
2766
|
}
|
|
2728
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
2767
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: CdkMonitorFocus, decorators: [{
|
|
2729
2768
|
type: Directive,
|
|
2730
2769
|
args: [{
|
|
2731
2770
|
selector: '[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]',
|
|
2732
2771
|
exportAs: 'cdkMonitorFocus',
|
|
2733
|
-
standalone: true,
|
|
2734
2772
|
}]
|
|
2735
2773
|
}], ctorParameters: () => [], propDecorators: { cdkFocusChange: [{
|
|
2736
2774
|
type: Output
|
|
@@ -2761,9 +2799,15 @@ const HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS = 'cdk-high-contrast-active';
|
|
|
2761
2799
|
* browser extension.
|
|
2762
2800
|
*/
|
|
2763
2801
|
class HighContrastModeDetector {
|
|
2802
|
+
_platform = inject(Platform);
|
|
2803
|
+
/**
|
|
2804
|
+
* Figuring out the high contrast mode and adding the body classes can cause
|
|
2805
|
+
* some expensive layouts. This flag is used to ensure that we only do it once.
|
|
2806
|
+
*/
|
|
2807
|
+
_hasCheckedHighContrastMode;
|
|
2808
|
+
_document = inject(DOCUMENT);
|
|
2809
|
+
_breakpointSubscription;
|
|
2764
2810
|
constructor() {
|
|
2765
|
-
this._platform = inject(Platform);
|
|
2766
|
-
this._document = inject(DOCUMENT);
|
|
2767
2811
|
this._breakpointSubscription = inject(BreakpointObserver)
|
|
2768
2812
|
.observe('(forced-colors: active)')
|
|
2769
2813
|
.subscribe(() => {
|
|
@@ -2828,10 +2872,10 @@ class HighContrastModeDetector {
|
|
|
2828
2872
|
}
|
|
2829
2873
|
}
|
|
2830
2874
|
}
|
|
2831
|
-
static
|
|
2832
|
-
static
|
|
2875
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: HighContrastModeDetector, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2876
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: HighContrastModeDetector, providedIn: 'root' });
|
|
2833
2877
|
}
|
|
2834
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
2878
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: HighContrastModeDetector, decorators: [{
|
|
2835
2879
|
type: Injectable,
|
|
2836
2880
|
args: [{ providedIn: 'root' }]
|
|
2837
2881
|
}], ctorParameters: () => [] });
|
|
@@ -2840,11 +2884,11 @@ class A11yModule {
|
|
|
2840
2884
|
constructor() {
|
|
2841
2885
|
inject(HighContrastModeDetector)._applyBodyHighContrastModeCssClasses();
|
|
2842
2886
|
}
|
|
2843
|
-
static
|
|
2844
|
-
static
|
|
2845
|
-
static
|
|
2887
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: A11yModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2888
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.0-next.10", ngImport: i0, type: A11yModule, imports: [ObserversModule, CdkAriaLive, CdkTrapFocus, CdkMonitorFocus], exports: [CdkAriaLive, CdkTrapFocus, CdkMonitorFocus] });
|
|
2889
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: A11yModule, imports: [ObserversModule] });
|
|
2846
2890
|
}
|
|
2847
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.
|
|
2891
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.10", ngImport: i0, type: A11yModule, decorators: [{
|
|
2848
2892
|
type: NgModule,
|
|
2849
2893
|
args: [{
|
|
2850
2894
|
imports: [ObserversModule, CdkAriaLive, CdkTrapFocus, CdkMonitorFocus],
|