@angular/cdk 19.2.3 → 20.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/a11y/index.d.ts +12 -843
  2. package/a11y-module.d-7d03e079.d.ts +313 -0
  3. package/accordion/index.d.ts +1 -1
  4. package/activedescendant-key-manager.d-11921e3a.d.ts +31 -0
  5. package/bidi/index.d.ts +3 -52
  6. package/bidi-module.d-f8648621.d.ts +53 -0
  7. package/coercion/index.d.ts +2 -15
  8. package/collections/index.d.ts +10 -269
  9. package/data-source.d-7cab2c9d.d.ts +42 -0
  10. package/dialog/index.d.ts +17 -32
  11. package/drag-drop/index.d.ts +14 -18
  12. package/fesm2022/a11y-module-e6996d20.mjs +952 -0
  13. package/fesm2022/a11y-module-e6996d20.mjs.map +1 -0
  14. package/fesm2022/a11y.mjs +42 -2448
  15. package/fesm2022/a11y.mjs.map +1 -1
  16. package/fesm2022/accordion.mjs +12 -12
  17. package/fesm2022/accordion.mjs.map +1 -1
  18. package/fesm2022/activedescendant-key-manager-1351a9d3.mjs +16 -0
  19. package/fesm2022/activedescendant-key-manager-1351a9d3.mjs.map +1 -0
  20. package/fesm2022/array-ee3b4bab.mjs +6 -0
  21. package/fesm2022/array-ee3b4bab.mjs.map +1 -0
  22. package/fesm2022/backwards-compatibility-bcbe473e.mjs +25 -0
  23. package/fesm2022/backwards-compatibility-bcbe473e.mjs.map +1 -0
  24. package/fesm2022/bidi-module-0726b65c.mjs +78 -0
  25. package/fesm2022/bidi-module-0726b65c.mjs.map +1 -0
  26. package/fesm2022/bidi.mjs +4 -143
  27. package/fesm2022/bidi.mjs.map +1 -1
  28. package/fesm2022/breakpoints-observer-d4584b66.mjs +179 -0
  29. package/fesm2022/breakpoints-observer-d4584b66.mjs.map +1 -0
  30. package/fesm2022/cdk.mjs +1 -1
  31. package/fesm2022/cdk.mjs.map +1 -1
  32. package/fesm2022/clipboard.mjs +10 -10
  33. package/fesm2022/clipboard.mjs.map +1 -1
  34. package/fesm2022/coercion/private.mjs +2 -14
  35. package/fesm2022/coercion/private.mjs.map +1 -1
  36. package/fesm2022/coercion.mjs +5 -39
  37. package/fesm2022/coercion.mjs.map +1 -1
  38. package/fesm2022/collections.mjs +7 -472
  39. package/fesm2022/collections.mjs.map +1 -1
  40. package/fesm2022/css-pixel-value-286c9a60.mjs +10 -0
  41. package/fesm2022/css-pixel-value-286c9a60.mjs.map +1 -0
  42. package/fesm2022/data-source-5320b6fd.mjs +15 -0
  43. package/fesm2022/data-source-5320b6fd.mjs.map +1 -0
  44. package/fesm2022/dialog.mjs +37 -41
  45. package/fesm2022/dialog.mjs.map +1 -1
  46. package/fesm2022/directionality-7ea26429.mjs +72 -0
  47. package/fesm2022/directionality-7ea26429.mjs.map +1 -0
  48. package/fesm2022/dispose-view-repeater-strategy-b11b87ea.mjs +44 -0
  49. package/fesm2022/dispose-view-repeater-strategy-b11b87ea.mjs.map +1 -0
  50. package/fesm2022/drag-drop.mjs +48 -46
  51. package/fesm2022/drag-drop.mjs.map +1 -1
  52. package/fesm2022/element-705567fe.mjs +29 -0
  53. package/fesm2022/element-705567fe.mjs.map +1 -0
  54. package/fesm2022/fake-event-detection-7055b1bd.mjs +24 -0
  55. package/fesm2022/fake-event-detection-7055b1bd.mjs.map +1 -0
  56. package/fesm2022/focus-key-manager-58d29acd.mjs +22 -0
  57. package/fesm2022/focus-key-manager-58d29acd.mjs.map +1 -0
  58. package/fesm2022/focus-monitor-cebaa0d1.mjs +629 -0
  59. package/fesm2022/focus-monitor-cebaa0d1.mjs.map +1 -0
  60. package/fesm2022/id-generator-fba495fb.mjs +37 -0
  61. package/fesm2022/id-generator-fba495fb.mjs.map +1 -0
  62. package/fesm2022/keycodes-107cd3e4.mjs +122 -0
  63. package/fesm2022/keycodes-107cd3e4.mjs.map +1 -0
  64. package/fesm2022/keycodes.mjs +2 -132
  65. package/fesm2022/keycodes.mjs.map +1 -1
  66. package/fesm2022/layout.mjs +12 -180
  67. package/fesm2022/layout.mjs.map +1 -1
  68. package/fesm2022/list-key-manager-c7b5cefb.mjs +360 -0
  69. package/fesm2022/list-key-manager-c7b5cefb.mjs.map +1 -0
  70. package/fesm2022/listbox.mjs +21 -16
  71. package/fesm2022/listbox.mjs.map +1 -1
  72. package/fesm2022/menu.mjs +76 -56
  73. package/fesm2022/menu.mjs.map +1 -1
  74. package/fesm2022/modifiers-33a5859e.mjs +13 -0
  75. package/fesm2022/modifiers-33a5859e.mjs.map +1 -0
  76. package/fesm2022/observable-97c0792c.mjs +15 -0
  77. package/fesm2022/observable-97c0792c.mjs.map +1 -0
  78. package/fesm2022/observe-content-d2a6b5a0.mjs +210 -0
  79. package/fesm2022/observe-content-d2a6b5a0.mjs.map +1 -0
  80. package/fesm2022/observers/private.mjs +3 -3
  81. package/fesm2022/observers/private.mjs.map +1 -1
  82. package/fesm2022/observers.mjs +5 -209
  83. package/fesm2022/observers.mjs.map +1 -1
  84. package/fesm2022/overlay-module-863b82c9.mjs +3029 -0
  85. package/fesm2022/overlay-module-863b82c9.mjs.map +1 -0
  86. package/fesm2022/overlay.mjs +28 -3023
  87. package/fesm2022/overlay.mjs.map +1 -1
  88. package/fesm2022/passive-listeners-c0bdc49f.mjs +31 -0
  89. package/fesm2022/passive-listeners-c0bdc49f.mjs.map +1 -0
  90. package/fesm2022/platform-1be098b0.mjs +77 -0
  91. package/fesm2022/platform-1be098b0.mjs.map +1 -0
  92. package/fesm2022/platform.mjs +13 -289
  93. package/fesm2022/platform.mjs.map +1 -1
  94. package/fesm2022/portal-directives-c88fea11.mjs +615 -0
  95. package/fesm2022/portal-directives-c88fea11.mjs.map +1 -0
  96. package/fesm2022/portal.mjs +3 -675
  97. package/fesm2022/portal.mjs.map +1 -1
  98. package/fesm2022/private.mjs +3 -59
  99. package/fesm2022/private.mjs.map +1 -1
  100. package/fesm2022/recycle-view-repeater-strategy-c1712813.mjs +156 -0
  101. package/fesm2022/recycle-view-repeater-strategy-c1712813.mjs.map +1 -0
  102. package/fesm2022/scrolling-61955dd1.mjs +99 -0
  103. package/fesm2022/scrolling-61955dd1.mjs.map +1 -0
  104. package/fesm2022/scrolling-module-aa9eeac5.mjs +1463 -0
  105. package/fesm2022/scrolling-module-aa9eeac5.mjs.map +1 -0
  106. package/fesm2022/scrolling.mjs +12 -1459
  107. package/fesm2022/scrolling.mjs.map +1 -1
  108. package/fesm2022/selection-model-30243dba.mjs +221 -0
  109. package/fesm2022/selection-model-30243dba.mjs.map +1 -0
  110. package/fesm2022/shadow-dom-9f403d00.mjs +49 -0
  111. package/fesm2022/shadow-dom-9f403d00.mjs.map +1 -0
  112. package/fesm2022/stepper.mjs +32 -26
  113. package/fesm2022/stepper.mjs.map +1 -1
  114. package/fesm2022/style-loader-e14dc585.mjs +47 -0
  115. package/fesm2022/style-loader-e14dc585.mjs.map +1 -0
  116. package/fesm2022/table.mjs +87 -121
  117. package/fesm2022/table.mjs.map +1 -1
  118. package/fesm2022/test-environment-34eef1ee.mjs +19 -0
  119. package/fesm2022/test-environment-34eef1ee.mjs.map +1 -0
  120. package/fesm2022/testing/selenium-webdriver.mjs +2 -1
  121. package/fesm2022/testing/selenium-webdriver.mjs.map +1 -1
  122. package/fesm2022/testing/testbed.mjs +33 -34
  123. package/fesm2022/testing/testbed.mjs.map +1 -1
  124. package/fesm2022/testing.mjs +2 -697
  125. package/fesm2022/testing.mjs.map +1 -1
  126. package/fesm2022/text-field.mjs +20 -19
  127. package/fesm2022/text-field.mjs.map +1 -1
  128. package/fesm2022/text-filtering-b60ba8a2.mjs +698 -0
  129. package/fesm2022/text-filtering-b60ba8a2.mjs.map +1 -0
  130. package/fesm2022/tree-key-manager-2f20c79c.mjs +360 -0
  131. package/fesm2022/tree-key-manager-2f20c79c.mjs.map +1 -0
  132. package/fesm2022/tree.mjs +33 -29
  133. package/fesm2022/tree.mjs.map +1 -1
  134. package/fesm2022/typeahead-11ae39bd.mjs +88 -0
  135. package/fesm2022/typeahead-11ae39bd.mjs.map +1 -0
  136. package/fesm2022/unique-selection-dispatcher-1d6f91d8.mjs +49 -0
  137. package/fesm2022/unique-selection-dispatcher-1d6f91d8.mjs.map +1 -0
  138. package/fesm2022/visually-hidden-83aea4a0.mjs +18 -0
  139. package/fesm2022/visually-hidden-83aea4a0.mjs.map +1 -0
  140. package/focus-key-manager.d-415a6958.d.ts +33 -0
  141. package/focus-monitor.d-810a02e6.d.ts +209 -0
  142. package/harness-environment.d-4d615248.d.ts +619 -0
  143. package/list-key-manager.d-72e9a2e7.d.ts +164 -0
  144. package/listbox/index.d.ts +5 -4
  145. package/menu/index.d.ts +14 -6
  146. package/number-property.d-ce316715.d.ts +15 -0
  147. package/observe-content.d-c08bc882.d.ts +84 -0
  148. package/observers/index.d.ts +4 -84
  149. package/overlay/index.d.ts +16 -792
  150. package/overlay-module.d-5d06db8a.d.ts +790 -0
  151. package/package.json +3 -3
  152. package/platform/index.d.ts +2 -31
  153. package/platform.d-0a5b4792.d.ts +33 -0
  154. package/portal/index.d.ts +5 -266
  155. package/portal-directives.d-d345bd53.d.ts +210 -0
  156. package/private/index.d.ts +2 -19
  157. package/schematics/migration.json +4 -4
  158. package/schematics/ng-add/index.js +1 -1
  159. package/schematics/ng-add/index.mjs +1 -1
  160. package/schematics/ng-update/index.d.ts +2 -2
  161. package/schematics/ng-update/index.js +5 -5
  162. package/schematics/ng-update/index.mjs +5 -5
  163. package/schematics/update-tool/target-version.d.ts +1 -1
  164. package/schematics/update-tool/target-version.js +2 -2
  165. package/schematics/update-tool/target-version.mjs +2 -2
  166. package/scrolling/index.d.ts +7 -604
  167. package/scrolling-module.d-a08a462d.d.ts +551 -0
  168. package/selection-model.d-1a70542c.d.ts +111 -0
  169. package/stepper/index.d.ts +5 -3
  170. package/style-loader.d-19baab84.d.ts +21 -0
  171. package/table/index.d.ts +8 -19
  172. package/testing/index.d.ts +2 -618
  173. package/testing/selenium-webdriver/index.d.ts +1 -1
  174. package/testing/testbed/index.d.ts +1 -1
  175. package/text-field/index.d.ts +1 -1
  176. package/tree/index.d.ts +3 -2
  177. package/tree-key-manager-strategy.d-603161dd.d.ts +116 -0
  178. package/unique-selection-dispatcher.d-7993b9f5.d.ts +32 -0
  179. package/view-repeater.d-79039e1f.d.ts +88 -0
  180. package/viewport-ruler.d-f3d3e82f.d.ts +57 -0
@@ -1,190 +1,22 @@
1
1
  import * as i0 from '@angular/core';
2
- import { NgModule, inject, CSP_NONCE, Injectable, NgZone } from '@angular/core';
3
- import { coerceArray } from '@angular/cdk/coercion';
4
- import { Subject, combineLatest, concat, Observable } from 'rxjs';
5
- import { take, skip, debounceTime, map, startWith, takeUntil } from 'rxjs/operators';
6
- import { Platform } from '@angular/cdk/platform';
2
+ import { NgModule } from '@angular/core';
3
+ export { B as BreakpointObserver, M as MediaMatcher } from './breakpoints-observer-d4584b66.mjs';
4
+ import 'rxjs';
5
+ import 'rxjs/operators';
6
+ import './platform-1be098b0.mjs';
7
+ import '@angular/common';
8
+ import './array-ee3b4bab.mjs';
7
9
 
8
10
  class LayoutModule {
9
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: LayoutModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
10
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.0", ngImport: i0, type: LayoutModule });
11
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: LayoutModule });
11
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0-next.1", ngImport: i0, type: LayoutModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
12
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.0-next.1", ngImport: i0, type: LayoutModule });
13
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.0-next.1", ngImport: i0, type: LayoutModule });
12
14
  }
13
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: LayoutModule, decorators: [{
15
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0-next.1", ngImport: i0, type: LayoutModule, decorators: [{
14
16
  type: NgModule,
15
17
  args: [{}]
16
18
  }] });
17
19
 
18
- /** Global registry for all dynamically-created, injected media queries. */
19
- const mediaQueriesForWebkitCompatibility = new Set();
20
- /** Style tag that holds all of the dynamically-created media queries. */
21
- let mediaQueryStyleNode;
22
- /** A utility for calling matchMedia queries. */
23
- class MediaMatcher {
24
- _platform = inject(Platform);
25
- _nonce = inject(CSP_NONCE, { optional: true });
26
- /** The internal matchMedia method to return back a MediaQueryList like object. */
27
- _matchMedia;
28
- constructor() {
29
- this._matchMedia =
30
- this._platform.isBrowser && window.matchMedia
31
- ? // matchMedia is bound to the window scope intentionally as it is an illegal invocation to
32
- // call it from a different scope.
33
- window.matchMedia.bind(window)
34
- : noopMatchMedia;
35
- }
36
- /**
37
- * Evaluates the given media query and returns the native MediaQueryList from which results
38
- * can be retrieved.
39
- * Confirms the layout engine will trigger for the selector query provided and returns the
40
- * MediaQueryList for the query provided.
41
- */
42
- matchMedia(query) {
43
- if (this._platform.WEBKIT || this._platform.BLINK) {
44
- createEmptyStyleRule(query, this._nonce);
45
- }
46
- return this._matchMedia(query);
47
- }
48
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: MediaMatcher, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
49
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: MediaMatcher, providedIn: 'root' });
50
- }
51
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: MediaMatcher, decorators: [{
52
- type: Injectable,
53
- args: [{ providedIn: 'root' }]
54
- }], ctorParameters: () => [] });
55
- /**
56
- * Creates an empty stylesheet that is used to work around browser inconsistencies related to
57
- * `matchMedia`. At the time of writing, it handles the following cases:
58
- * 1. On WebKit browsers, a media query has to have at least one rule in order for `matchMedia`
59
- * to fire. We work around it by declaring a dummy stylesheet with a `@media` declaration.
60
- * 2. In some cases Blink browsers will stop firing the `matchMedia` listener if none of the rules
61
- * inside the `@media` match existing elements on the page. We work around it by having one rule
62
- * targeting the `body`. See https://github.com/angular/components/issues/23546.
63
- */
64
- function createEmptyStyleRule(query, nonce) {
65
- if (mediaQueriesForWebkitCompatibility.has(query)) {
66
- return;
67
- }
68
- try {
69
- if (!mediaQueryStyleNode) {
70
- mediaQueryStyleNode = document.createElement('style');
71
- if (nonce) {
72
- mediaQueryStyleNode.setAttribute('nonce', nonce);
73
- }
74
- mediaQueryStyleNode.setAttribute('type', 'text/css');
75
- document.head.appendChild(mediaQueryStyleNode);
76
- }
77
- if (mediaQueryStyleNode.sheet) {
78
- mediaQueryStyleNode.sheet.insertRule(`@media ${query} {body{ }}`, 0);
79
- mediaQueriesForWebkitCompatibility.add(query);
80
- }
81
- }
82
- catch (e) {
83
- console.error(e);
84
- }
85
- }
86
- /** No-op matchMedia replacement for non-browser platforms. */
87
- function noopMatchMedia(query) {
88
- // Use `as any` here to avoid adding additional necessary properties for
89
- // the noop matcher.
90
- return {
91
- matches: query === 'all' || query === '',
92
- media: query,
93
- addListener: () => { },
94
- removeListener: () => { },
95
- };
96
- }
97
-
98
- /** Utility for checking the matching state of `@media` queries. */
99
- class BreakpointObserver {
100
- _mediaMatcher = inject(MediaMatcher);
101
- _zone = inject(NgZone);
102
- /** A map of all media queries currently being listened for. */
103
- _queries = new Map();
104
- /** A subject for all other observables to takeUntil based on. */
105
- _destroySubject = new Subject();
106
- constructor() { }
107
- /** Completes the active subject, signalling to all other observables to complete. */
108
- ngOnDestroy() {
109
- this._destroySubject.next();
110
- this._destroySubject.complete();
111
- }
112
- /**
113
- * Whether one or more media queries match the current viewport size.
114
- * @param value One or more media queries to check.
115
- * @returns Whether any of the media queries match.
116
- */
117
- isMatched(value) {
118
- const queries = splitQueries(coerceArray(value));
119
- return queries.some(mediaQuery => this._registerQuery(mediaQuery).mql.matches);
120
- }
121
- /**
122
- * Gets an observable of results for the given queries that will emit new results for any changes
123
- * in matching of the given queries.
124
- * @param value One or more media queries to check.
125
- * @returns A stream of matches for the given queries.
126
- */
127
- observe(value) {
128
- const queries = splitQueries(coerceArray(value));
129
- const observables = queries.map(query => this._registerQuery(query).observable);
130
- let stateObservable = combineLatest(observables);
131
- // Emit the first state immediately, and then debounce the subsequent emissions.
132
- stateObservable = concat(stateObservable.pipe(take(1)), stateObservable.pipe(skip(1), debounceTime(0)));
133
- return stateObservable.pipe(map(breakpointStates => {
134
- const response = {
135
- matches: false,
136
- breakpoints: {},
137
- };
138
- breakpointStates.forEach(({ matches, query }) => {
139
- response.matches = response.matches || matches;
140
- response.breakpoints[query] = matches;
141
- });
142
- return response;
143
- }));
144
- }
145
- /** Registers a specific query to be listened for. */
146
- _registerQuery(query) {
147
- // Only set up a new MediaQueryList if it is not already being listened for.
148
- if (this._queries.has(query)) {
149
- return this._queries.get(query);
150
- }
151
- const mql = this._mediaMatcher.matchMedia(query);
152
- // Create callback for match changes and add it is as a listener.
153
- const queryObservable = new Observable((observer) => {
154
- // Listener callback methods are wrapped to be placed back in ngZone. Callbacks must be placed
155
- // back into the zone because matchMedia is only included in Zone.js by loading the
156
- // webapis-media-query.js file alongside the zone.js file. Additionally, some browsers do not
157
- // have MediaQueryList inherit from EventTarget, which causes inconsistencies in how Zone.js
158
- // patches it.
159
- const handler = (e) => this._zone.run(() => observer.next(e));
160
- mql.addListener(handler);
161
- return () => {
162
- mql.removeListener(handler);
163
- };
164
- }).pipe(startWith(mql), map(({ matches }) => ({ query, matches })), takeUntil(this._destroySubject));
165
- // Add the MediaQueryList to the set of queries.
166
- const output = { observable: queryObservable, mql };
167
- this._queries.set(query, output);
168
- return output;
169
- }
170
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: BreakpointObserver, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
171
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: BreakpointObserver, providedIn: 'root' });
172
- }
173
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: BreakpointObserver, decorators: [{
174
- type: Injectable,
175
- args: [{ providedIn: 'root' }]
176
- }], ctorParameters: () => [] });
177
- /**
178
- * Split each query string into separate query strings if two queries are provided as comma
179
- * separated.
180
- */
181
- function splitQueries(queries) {
182
- return queries
183
- .map(query => query.split(','))
184
- .reduce((a1, a2) => a1.concat(a2))
185
- .map(query => query.trim());
186
- }
187
-
188
20
  // PascalCase is being used as Breakpoints is used like an enum.
189
21
  // tslint:disable-next-line:variable-name
190
22
  const Breakpoints = {
@@ -207,5 +39,5 @@ const Breakpoints = {
207
39
  WebLandscape: '(min-width: 1280px) and (orientation: landscape)',
208
40
  };
209
41
 
210
- export { BreakpointObserver, Breakpoints, LayoutModule, MediaMatcher };
42
+ export { Breakpoints, LayoutModule };
211
43
  //# sourceMappingURL=layout.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout.mjs","sources":["../../../../../../src/cdk/layout/layout-module.ts","../../../../../../src/cdk/layout/media-matcher.ts","../../../../../../src/cdk/layout/breakpoints-observer.ts","../../../../../../src/cdk/layout/breakpoints.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport {NgModule} from '@angular/core';\n\n@NgModule({})\nexport class LayoutModule {}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport {Injectable, CSP_NONCE, inject} from '@angular/core';\nimport {Platform} from '@angular/cdk/platform';\n\n/** Global registry for all dynamically-created, injected media queries. */\nconst mediaQueriesForWebkitCompatibility: Set<string> = new Set<string>();\n\n/** Style tag that holds all of the dynamically-created media queries. */\nlet mediaQueryStyleNode: HTMLStyleElement | undefined;\n\n/** A utility for calling matchMedia queries. */\n@Injectable({providedIn: 'root'})\nexport class MediaMatcher {\n private _platform = inject(Platform);\n private _nonce = inject(CSP_NONCE, {optional: true});\n\n /** The internal matchMedia method to return back a MediaQueryList like object. */\n private _matchMedia: (query: string) => MediaQueryList;\n\n constructor(...args: unknown[]);\n\n constructor() {\n this._matchMedia =\n this._platform.isBrowser && window.matchMedia\n ? // matchMedia is bound to the window scope intentionally as it is an illegal invocation to\n // call it from a different scope.\n window.matchMedia.bind(window)\n : noopMatchMedia;\n }\n\n /**\n * Evaluates the given media query and returns the native MediaQueryList from which results\n * can be retrieved.\n * Confirms the layout engine will trigger for the selector query provided and returns the\n * MediaQueryList for the query provided.\n */\n matchMedia(query: string): MediaQueryList {\n if (this._platform.WEBKIT || this._platform.BLINK) {\n createEmptyStyleRule(query, this._nonce);\n }\n return this._matchMedia(query);\n }\n}\n\n/**\n * Creates an empty stylesheet that is used to work around browser inconsistencies related to\n * `matchMedia`. At the time of writing, it handles the following cases:\n * 1. On WebKit browsers, a media query has to have at least one rule in order for `matchMedia`\n * to fire. We work around it by declaring a dummy stylesheet with a `@media` declaration.\n * 2. In some cases Blink browsers will stop firing the `matchMedia` listener if none of the rules\n * inside the `@media` match existing elements on the page. We work around it by having one rule\n * targeting the `body`. See https://github.com/angular/components/issues/23546.\n */\nfunction createEmptyStyleRule(query: string, nonce: string | undefined | null) {\n if (mediaQueriesForWebkitCompatibility.has(query)) {\n return;\n }\n\n try {\n if (!mediaQueryStyleNode) {\n mediaQueryStyleNode = document.createElement('style');\n\n if (nonce) {\n mediaQueryStyleNode.setAttribute('nonce', nonce);\n }\n\n mediaQueryStyleNode.setAttribute('type', 'text/css');\n document.head!.appendChild(mediaQueryStyleNode);\n }\n\n if (mediaQueryStyleNode.sheet) {\n mediaQueryStyleNode.sheet.insertRule(`@media ${query} {body{ }}`, 0);\n mediaQueriesForWebkitCompatibility.add(query);\n }\n } catch (e) {\n console.error(e);\n }\n}\n\n/** No-op matchMedia replacement for non-browser platforms. */\nfunction noopMatchMedia(query: string): MediaQueryList {\n // Use `as any` here to avoid adding additional necessary properties for\n // the noop matcher.\n return {\n matches: query === 'all' || query === '',\n media: query,\n addListener: () => {},\n removeListener: () => {},\n } as any;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {coerceArray} from '@angular/cdk/coercion';\nimport {Injectable, NgZone, OnDestroy, inject} from '@angular/core';\nimport {combineLatest, concat, Observable, Observer, Subject} from 'rxjs';\nimport {debounceTime, map, skip, startWith, take, takeUntil} from 'rxjs/operators';\nimport {MediaMatcher} from './media-matcher';\n\n/** The current state of a layout breakpoint. */\nexport interface BreakpointState {\n /** Whether the breakpoint is currently matching. */\n matches: boolean;\n /**\n * A key boolean pair for each query provided to the observe method,\n * with its current matched state.\n */\n breakpoints: {\n [key: string]: boolean;\n };\n}\n\n/** The current state of a layout breakpoint. */\ninterface InternalBreakpointState {\n /** Whether the breakpoint is currently matching. */\n matches: boolean;\n /** The media query being to be matched */\n query: string;\n}\n\ninterface Query {\n observable: Observable<InternalBreakpointState>;\n mql: MediaQueryList;\n}\n\n/** Utility for checking the matching state of `@media` queries. */\n@Injectable({providedIn: 'root'})\nexport class BreakpointObserver implements OnDestroy {\n private _mediaMatcher = inject(MediaMatcher);\n private _zone = inject(NgZone);\n\n /** A map of all media queries currently being listened for. */\n private _queries = new Map<string, Query>();\n /** A subject for all other observables to takeUntil based on. */\n private readonly _destroySubject = new Subject<void>();\n\n constructor(...args: unknown[]);\n constructor() {}\n\n /** Completes the active subject, signalling to all other observables to complete. */\n ngOnDestroy() {\n this._destroySubject.next();\n this._destroySubject.complete();\n }\n\n /**\n * Whether one or more media queries match the current viewport size.\n * @param value One or more media queries to check.\n * @returns Whether any of the media queries match.\n */\n isMatched(value: string | readonly string[]): boolean {\n const queries = splitQueries(coerceArray(value));\n return queries.some(mediaQuery => this._registerQuery(mediaQuery).mql.matches);\n }\n\n /**\n * Gets an observable of results for the given queries that will emit new results for any changes\n * in matching of the given queries.\n * @param value One or more media queries to check.\n * @returns A stream of matches for the given queries.\n */\n observe(value: string | readonly string[]): Observable<BreakpointState> {\n const queries = splitQueries(coerceArray(value));\n const observables = queries.map(query => this._registerQuery(query).observable);\n\n let stateObservable = combineLatest(observables);\n // Emit the first state immediately, and then debounce the subsequent emissions.\n stateObservable = concat(\n stateObservable.pipe(take(1)),\n stateObservable.pipe(skip(1), debounceTime(0)),\n );\n return stateObservable.pipe(\n map(breakpointStates => {\n const response: BreakpointState = {\n matches: false,\n breakpoints: {},\n };\n breakpointStates.forEach(({matches, query}) => {\n response.matches = response.matches || matches;\n response.breakpoints[query] = matches;\n });\n return response;\n }),\n );\n }\n\n /** Registers a specific query to be listened for. */\n private _registerQuery(query: string): Query {\n // Only set up a new MediaQueryList if it is not already being listened for.\n if (this._queries.has(query)) {\n return this._queries.get(query)!;\n }\n\n const mql = this._mediaMatcher.matchMedia(query);\n\n // Create callback for match changes and add it is as a listener.\n const queryObservable = new Observable((observer: Observer<MediaQueryListEvent>) => {\n // Listener callback methods are wrapped to be placed back in ngZone. Callbacks must be placed\n // back into the zone because matchMedia is only included in Zone.js by loading the\n // webapis-media-query.js file alongside the zone.js file. Additionally, some browsers do not\n // have MediaQueryList inherit from EventTarget, which causes inconsistencies in how Zone.js\n // patches it.\n const handler = (e: MediaQueryListEvent): void => this._zone.run(() => observer.next(e));\n mql.addListener(handler);\n\n return () => {\n mql.removeListener(handler);\n };\n }).pipe(\n startWith(mql),\n map(({matches}) => ({query, matches})),\n takeUntil(this._destroySubject),\n );\n\n // Add the MediaQueryList to the set of queries.\n const output = {observable: queryObservable, mql};\n this._queries.set(query, output);\n return output;\n }\n}\n\n/**\n * Split each query string into separate query strings if two queries are provided as comma\n * separated.\n */\nfunction splitQueries(queries: readonly string[]): readonly string[] {\n return queries\n .map(query => query.split(','))\n .reduce((a1, a2) => a1.concat(a2))\n .map(query => query.trim());\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n// PascalCase is being used as Breakpoints is used like an enum.\n// tslint:disable-next-line:variable-name\nexport const Breakpoints = {\n XSmall: '(max-width: 599.98px)',\n Small: '(min-width: 600px) and (max-width: 959.98px)',\n Medium: '(min-width: 960px) and (max-width: 1279.98px)',\n Large: '(min-width: 1280px) and (max-width: 1919.98px)',\n XLarge: '(min-width: 1920px)',\n\n Handset:\n '(max-width: 599.98px) and (orientation: portrait), ' +\n '(max-width: 959.98px) and (orientation: landscape)',\n Tablet:\n '(min-width: 600px) and (max-width: 839.98px) and (orientation: portrait), ' +\n '(min-width: 960px) and (max-width: 1279.98px) and (orientation: landscape)',\n Web:\n '(min-width: 840px) and (orientation: portrait), ' +\n '(min-width: 1280px) and (orientation: landscape)',\n\n HandsetPortrait: '(max-width: 599.98px) and (orientation: portrait)',\n TabletPortrait: '(min-width: 600px) and (max-width: 839.98px) and (orientation: portrait)',\n WebPortrait: '(min-width: 840px) and (orientation: portrait)',\n\n HandsetLandscape: '(max-width: 959.98px) and (orientation: landscape)',\n TabletLandscape: '(min-width: 960px) and (max-width: 1279.98px) and (orientation: landscape)',\n WebLandscape: '(min-width: 1280px) and (orientation: landscape)',\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"layout.mjs","sources":["../../../../../../src/cdk/layout/layout-module.ts","../../../../../../src/cdk/layout/breakpoints.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport {NgModule} from '@angular/core';\n\n@NgModule({})\nexport class LayoutModule {}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n// PascalCase is being used as Breakpoints is used like an enum.\n// tslint:disable-next-line:variable-name\nexport const Breakpoints = {\n XSmall: '(max-width: 599.98px)',\n Small: '(min-width: 600px) and (max-width: 959.98px)',\n Medium: '(min-width: 960px) and (max-width: 1279.98px)',\n Large: '(min-width: 1280px) and (max-width: 1919.98px)',\n XLarge: '(min-width: 1920px)',\n\n Handset:\n '(max-width: 599.98px) and (orientation: portrait), ' +\n '(max-width: 959.98px) and (orientation: landscape)',\n Tablet:\n '(min-width: 600px) and (max-width: 839.98px) and (orientation: portrait), ' +\n '(min-width: 960px) and (max-width: 1279.98px) and (orientation: landscape)',\n Web:\n '(min-width: 840px) and (orientation: portrait), ' +\n '(min-width: 1280px) and (orientation: landscape)',\n\n HandsetPortrait: '(max-width: 599.98px) and (orientation: portrait)',\n TabletPortrait: '(min-width: 600px) and (max-width: 839.98px) and (orientation: portrait)',\n WebPortrait: '(min-width: 840px) and (orientation: portrait)',\n\n HandsetLandscape: '(max-width: 959.98px) and (orientation: landscape)',\n TabletLandscape: '(min-width: 960px) and (max-width: 1279.98px) and (orientation: landscape)',\n WebLandscape: '(min-width: 1280px) and (orientation: landscape)',\n};\n"],"names":[],"mappings":";;;;;;;;;MAUa,YAAY,CAAA;8GAAZ,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;+GAAZ,YAAY,EAAA,CAAA,CAAA;+GAAZ,YAAY,EAAA,CAAA,CAAA;;kGAAZ,YAAY,EAAA,UAAA,EAAA,CAAA;kBADxB,QAAQ;mBAAC,EAAE,CAAA;;;ACFZ;AACA;AACa,MAAA,WAAW,GAAG;AACzB,IAAA,MAAM,EAAE,uBAAuB;AAC/B,IAAA,KAAK,EAAE,8CAA8C;AACrD,IAAA,MAAM,EAAE,+CAA+C;AACvD,IAAA,KAAK,EAAE,gDAAgD;AACvD,IAAA,MAAM,EAAE,qBAAqB;AAE7B,IAAA,OAAO,EACL,qDAAqD;QACrD,oDAAoD;AACtD,IAAA,MAAM,EACJ,4EAA4E;QAC5E,4EAA4E;AAC9E,IAAA,GAAG,EACD,kDAAkD;QAClD,kDAAkD;AAEpD,IAAA,eAAe,EAAE,mDAAmD;AACpE,IAAA,cAAc,EAAE,0EAA0E;AAC1F,IAAA,WAAW,EAAE,gDAAgD;AAE7D,IAAA,gBAAgB,EAAE,oDAAoD;AACtE,IAAA,eAAe,EAAE,4EAA4E;AAC7F,IAAA,YAAY,EAAE,kDAAkD;;;;;"}
@@ -0,0 +1,360 @@
1
+ import { signal, QueryList, isSignal, effect } from '@angular/core';
2
+ import { Subscription, Subject } from 'rxjs';
3
+ import { T as Typeahead } from './typeahead-11ae39bd.mjs';
4
+ import { h as hasModifierKey } from './modifiers-33a5859e.mjs';
5
+ import { P as PAGE_DOWN, b as PAGE_UP, E as END, H as HOME, L as LEFT_ARROW, R as RIGHT_ARROW, U as UP_ARROW, D as DOWN_ARROW, T as TAB } from './keycodes-107cd3e4.mjs';
6
+
7
+ /**
8
+ * This class manages keyboard events for selectable lists. If you pass it a query list
9
+ * of items, it will set the active item correctly when arrow events occur.
10
+ */
11
+ class ListKeyManager {
12
+ _items;
13
+ _activeItemIndex = -1;
14
+ _activeItem = signal(null);
15
+ _wrap = false;
16
+ _typeaheadSubscription = Subscription.EMPTY;
17
+ _itemChangesSubscription;
18
+ _vertical = true;
19
+ _horizontal;
20
+ _allowedModifierKeys = [];
21
+ _homeAndEnd = false;
22
+ _pageUpAndDown = { enabled: false, delta: 10 };
23
+ _effectRef;
24
+ _typeahead;
25
+ /**
26
+ * Predicate function that can be used to check whether an item should be skipped
27
+ * by the key manager. By default, disabled items are skipped.
28
+ */
29
+ _skipPredicateFn = (item) => item.disabled;
30
+ constructor(_items, injector) {
31
+ this._items = _items;
32
+ // We allow for the items to be an array because, in some cases, the consumer may
33
+ // not have access to a QueryList of the items they want to manage (e.g. when the
34
+ // items aren't being collected via `ViewChildren` or `ContentChildren`).
35
+ if (_items instanceof QueryList) {
36
+ this._itemChangesSubscription = _items.changes.subscribe((newItems) => this._itemsChanged(newItems.toArray()));
37
+ }
38
+ else if (isSignal(_items)) {
39
+ if (!injector && (typeof ngDevMode === 'undefined' || ngDevMode)) {
40
+ throw new Error('ListKeyManager constructed with a signal must receive an injector');
41
+ }
42
+ this._effectRef = effect(() => this._itemsChanged(_items()), { injector });
43
+ }
44
+ }
45
+ /**
46
+ * Stream that emits any time the TAB key is pressed, so components can react
47
+ * when focus is shifted off of the list.
48
+ */
49
+ tabOut = new Subject();
50
+ /** Stream that emits whenever the active item of the list manager changes. */
51
+ change = new Subject();
52
+ /**
53
+ * Sets the predicate function that determines which items should be skipped by the
54
+ * list key manager.
55
+ * @param predicate Function that determines whether the given item should be skipped.
56
+ */
57
+ skipPredicate(predicate) {
58
+ this._skipPredicateFn = predicate;
59
+ return this;
60
+ }
61
+ /**
62
+ * Configures wrapping mode, which determines whether the active item will wrap to
63
+ * the other end of list when there are no more items in the given direction.
64
+ * @param shouldWrap Whether the list should wrap when reaching the end.
65
+ */
66
+ withWrap(shouldWrap = true) {
67
+ this._wrap = shouldWrap;
68
+ return this;
69
+ }
70
+ /**
71
+ * Configures whether the key manager should be able to move the selection vertically.
72
+ * @param enabled Whether vertical selection should be enabled.
73
+ */
74
+ withVerticalOrientation(enabled = true) {
75
+ this._vertical = enabled;
76
+ return this;
77
+ }
78
+ /**
79
+ * Configures the key manager to move the selection horizontally.
80
+ * Passing in `null` will disable horizontal movement.
81
+ * @param direction Direction in which the selection can be moved.
82
+ */
83
+ withHorizontalOrientation(direction) {
84
+ this._horizontal = direction;
85
+ return this;
86
+ }
87
+ /**
88
+ * Modifier keys which are allowed to be held down and whose default actions will be prevented
89
+ * as the user is pressing the arrow keys. Defaults to not allowing any modifier keys.
90
+ */
91
+ withAllowedModifierKeys(keys) {
92
+ this._allowedModifierKeys = keys;
93
+ return this;
94
+ }
95
+ /**
96
+ * Turns on typeahead mode which allows users to set the active item by typing.
97
+ * @param debounceInterval Time to wait after the last keystroke before setting the active item.
98
+ */
99
+ withTypeAhead(debounceInterval = 200) {
100
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
101
+ const items = this._getItemsArray();
102
+ if (items.length > 0 && items.some(item => typeof item.getLabel !== 'function')) {
103
+ throw Error('ListKeyManager items in typeahead mode must implement the `getLabel` method.');
104
+ }
105
+ }
106
+ this._typeaheadSubscription.unsubscribe();
107
+ const items = this._getItemsArray();
108
+ this._typeahead = new Typeahead(items, {
109
+ debounceInterval: typeof debounceInterval === 'number' ? debounceInterval : undefined,
110
+ skipPredicate: item => this._skipPredicateFn(item),
111
+ });
112
+ this._typeaheadSubscription = this._typeahead.selectedItem.subscribe(item => {
113
+ this.setActiveItem(item);
114
+ });
115
+ return this;
116
+ }
117
+ /** Cancels the current typeahead sequence. */
118
+ cancelTypeahead() {
119
+ this._typeahead?.reset();
120
+ return this;
121
+ }
122
+ /**
123
+ * Configures the key manager to activate the first and last items
124
+ * respectively when the Home or End key is pressed.
125
+ * @param enabled Whether pressing the Home or End key activates the first/last item.
126
+ */
127
+ withHomeAndEnd(enabled = true) {
128
+ this._homeAndEnd = enabled;
129
+ return this;
130
+ }
131
+ /**
132
+ * Configures the key manager to activate every 10th, configured or first/last element in up/down direction
133
+ * respectively when the Page-Up or Page-Down key is pressed.
134
+ * @param enabled Whether pressing the Page-Up or Page-Down key activates the first/last item.
135
+ * @param delta Whether pressing the Home or End key activates the first/last item.
136
+ */
137
+ withPageUpDown(enabled = true, delta = 10) {
138
+ this._pageUpAndDown = { enabled, delta };
139
+ return this;
140
+ }
141
+ setActiveItem(item) {
142
+ const previousActiveItem = this._activeItem();
143
+ this.updateActiveItem(item);
144
+ if (this._activeItem() !== previousActiveItem) {
145
+ this.change.next(this._activeItemIndex);
146
+ }
147
+ }
148
+ /**
149
+ * Sets the active item depending on the key event passed in.
150
+ * @param event Keyboard event to be used for determining which element should be active.
151
+ */
152
+ onKeydown(event) {
153
+ const keyCode = event.keyCode;
154
+ const modifiers = ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'];
155
+ const isModifierAllowed = modifiers.every(modifier => {
156
+ return !event[modifier] || this._allowedModifierKeys.indexOf(modifier) > -1;
157
+ });
158
+ switch (keyCode) {
159
+ case TAB:
160
+ this.tabOut.next();
161
+ return;
162
+ case DOWN_ARROW:
163
+ if (this._vertical && isModifierAllowed) {
164
+ this.setNextItemActive();
165
+ break;
166
+ }
167
+ else {
168
+ return;
169
+ }
170
+ case UP_ARROW:
171
+ if (this._vertical && isModifierAllowed) {
172
+ this.setPreviousItemActive();
173
+ break;
174
+ }
175
+ else {
176
+ return;
177
+ }
178
+ case RIGHT_ARROW:
179
+ if (this._horizontal && isModifierAllowed) {
180
+ this._horizontal === 'rtl' ? this.setPreviousItemActive() : this.setNextItemActive();
181
+ break;
182
+ }
183
+ else {
184
+ return;
185
+ }
186
+ case LEFT_ARROW:
187
+ if (this._horizontal && isModifierAllowed) {
188
+ this._horizontal === 'rtl' ? this.setNextItemActive() : this.setPreviousItemActive();
189
+ break;
190
+ }
191
+ else {
192
+ return;
193
+ }
194
+ case HOME:
195
+ if (this._homeAndEnd && isModifierAllowed) {
196
+ this.setFirstItemActive();
197
+ break;
198
+ }
199
+ else {
200
+ return;
201
+ }
202
+ case END:
203
+ if (this._homeAndEnd && isModifierAllowed) {
204
+ this.setLastItemActive();
205
+ break;
206
+ }
207
+ else {
208
+ return;
209
+ }
210
+ case PAGE_UP:
211
+ if (this._pageUpAndDown.enabled && isModifierAllowed) {
212
+ const targetIndex = this._activeItemIndex - this._pageUpAndDown.delta;
213
+ this._setActiveItemByIndex(targetIndex > 0 ? targetIndex : 0, 1);
214
+ break;
215
+ }
216
+ else {
217
+ return;
218
+ }
219
+ case PAGE_DOWN:
220
+ if (this._pageUpAndDown.enabled && isModifierAllowed) {
221
+ const targetIndex = this._activeItemIndex + this._pageUpAndDown.delta;
222
+ const itemsLength = this._getItemsArray().length;
223
+ this._setActiveItemByIndex(targetIndex < itemsLength ? targetIndex : itemsLength - 1, -1);
224
+ break;
225
+ }
226
+ else {
227
+ return;
228
+ }
229
+ default:
230
+ if (isModifierAllowed || hasModifierKey(event, 'shiftKey')) {
231
+ this._typeahead?.handleKey(event);
232
+ }
233
+ // Note that we return here, in order to avoid preventing
234
+ // the default action of non-navigational keys.
235
+ return;
236
+ }
237
+ this._typeahead?.reset();
238
+ event.preventDefault();
239
+ }
240
+ /** Index of the currently active item. */
241
+ get activeItemIndex() {
242
+ return this._activeItemIndex;
243
+ }
244
+ /** The active item. */
245
+ get activeItem() {
246
+ return this._activeItem();
247
+ }
248
+ /** Gets whether the user is currently typing into the manager using the typeahead feature. */
249
+ isTyping() {
250
+ return !!this._typeahead && this._typeahead.isTyping();
251
+ }
252
+ /** Sets the active item to the first enabled item in the list. */
253
+ setFirstItemActive() {
254
+ this._setActiveItemByIndex(0, 1);
255
+ }
256
+ /** Sets the active item to the last enabled item in the list. */
257
+ setLastItemActive() {
258
+ this._setActiveItemByIndex(this._getItemsArray().length - 1, -1);
259
+ }
260
+ /** Sets the active item to the next enabled item in the list. */
261
+ setNextItemActive() {
262
+ this._activeItemIndex < 0 ? this.setFirstItemActive() : this._setActiveItemByDelta(1);
263
+ }
264
+ /** Sets the active item to a previous enabled item in the list. */
265
+ setPreviousItemActive() {
266
+ this._activeItemIndex < 0 && this._wrap
267
+ ? this.setLastItemActive()
268
+ : this._setActiveItemByDelta(-1);
269
+ }
270
+ updateActiveItem(item) {
271
+ const itemArray = this._getItemsArray();
272
+ const index = typeof item === 'number' ? item : itemArray.indexOf(item);
273
+ const activeItem = itemArray[index];
274
+ // Explicitly check for `null` and `undefined` because other falsy values are valid.
275
+ this._activeItem.set(activeItem == null ? null : activeItem);
276
+ this._activeItemIndex = index;
277
+ this._typeahead?.setCurrentSelectedItemIndex(index);
278
+ }
279
+ /** Cleans up the key manager. */
280
+ destroy() {
281
+ this._typeaheadSubscription.unsubscribe();
282
+ this._itemChangesSubscription?.unsubscribe();
283
+ this._effectRef?.destroy();
284
+ this._typeahead?.destroy();
285
+ this.tabOut.complete();
286
+ this.change.complete();
287
+ }
288
+ /**
289
+ * This method sets the active item, given a list of items and the delta between the
290
+ * currently active item and the new active item. It will calculate differently
291
+ * depending on whether wrap mode is turned on.
292
+ */
293
+ _setActiveItemByDelta(delta) {
294
+ this._wrap ? this._setActiveInWrapMode(delta) : this._setActiveInDefaultMode(delta);
295
+ }
296
+ /**
297
+ * Sets the active item properly given "wrap" mode. In other words, it will continue to move
298
+ * down the list until it finds an item that is not disabled, and it will wrap if it
299
+ * encounters either end of the list.
300
+ */
301
+ _setActiveInWrapMode(delta) {
302
+ const items = this._getItemsArray();
303
+ for (let i = 1; i <= items.length; i++) {
304
+ const index = (this._activeItemIndex + delta * i + items.length) % items.length;
305
+ const item = items[index];
306
+ if (!this._skipPredicateFn(item)) {
307
+ this.setActiveItem(index);
308
+ return;
309
+ }
310
+ }
311
+ }
312
+ /**
313
+ * Sets the active item properly given the default mode. In other words, it will
314
+ * continue to move down the list until it finds an item that is not disabled. If
315
+ * it encounters either end of the list, it will stop and not wrap.
316
+ */
317
+ _setActiveInDefaultMode(delta) {
318
+ this._setActiveItemByIndex(this._activeItemIndex + delta, delta);
319
+ }
320
+ /**
321
+ * Sets the active item to the first enabled item starting at the index specified. If the
322
+ * item is disabled, it will move in the fallbackDelta direction until it either
323
+ * finds an enabled item or encounters the end of the list.
324
+ */
325
+ _setActiveItemByIndex(index, fallbackDelta) {
326
+ const items = this._getItemsArray();
327
+ if (!items[index]) {
328
+ return;
329
+ }
330
+ while (this._skipPredicateFn(items[index])) {
331
+ index += fallbackDelta;
332
+ if (!items[index]) {
333
+ return;
334
+ }
335
+ }
336
+ this.setActiveItem(index);
337
+ }
338
+ /** Returns the items as an array. */
339
+ _getItemsArray() {
340
+ if (isSignal(this._items)) {
341
+ return this._items();
342
+ }
343
+ return this._items instanceof QueryList ? this._items.toArray() : this._items;
344
+ }
345
+ /** Callback for when the items have changed. */
346
+ _itemsChanged(newItems) {
347
+ this._typeahead?.setItems(newItems);
348
+ const activeItem = this._activeItem();
349
+ if (activeItem) {
350
+ const newIndex = newItems.indexOf(activeItem);
351
+ if (newIndex > -1 && newIndex !== this._activeItemIndex) {
352
+ this._activeItemIndex = newIndex;
353
+ this._typeahead?.setCurrentSelectedItemIndex(newIndex);
354
+ }
355
+ }
356
+ }
357
+ }
358
+
359
+ export { ListKeyManager as L };
360
+ //# sourceMappingURL=list-key-manager-c7b5cefb.mjs.map