@cuby-ui/cdk 0.0.180 → 0.0.182

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 (141) hide show
  1. package/constants/empty.d.ts +10 -0
  2. package/constants/handlers.d.ts +8 -0
  3. package/constants/index.d.ts +2 -0
  4. package/directives/active-zone/active-zone.directive.d.ts +22 -0
  5. package/directives/active-zone/index.d.ts +1 -0
  6. package/directives/hovered/hovered.directive.d.ts +7 -0
  7. package/directives/hovered/hovered.service.d.ts +12 -0
  8. package/directives/hovered/index.d.ts +2 -0
  9. package/directives/index.d.ts +2 -0
  10. package/directives/let.directive.d.ts +1 -1
  11. package/directives/target.directive.d.ts +1 -1
  12. package/esm2022/constants/empty.mjs +24 -0
  13. package/esm2022/constants/handlers.mjs +11 -0
  14. package/esm2022/constants/index.mjs +4 -0
  15. package/esm2022/directives/active-zone/active-zone.directive.mjs +72 -0
  16. package/esm2022/directives/active-zone/index.mjs +2 -0
  17. package/{esm2020 → esm2022}/directives/auto-resizing.directive.mjs +4 -4
  18. package/{esm2020 → esm2022}/directives/click-outside.directive.mjs +4 -4
  19. package/{esm2020 → esm2022}/directives/content-editable-value-accessor.directive.mjs +4 -4
  20. package/{esm2020 → esm2022}/directives/dimensions-observer.directive.mjs +4 -4
  21. package/{esm2020 → esm2022}/directives/element.directive.mjs +4 -4
  22. package/{esm2020 → esm2022}/directives/focus-trap.directive.mjs +4 -4
  23. package/esm2022/directives/hovered/hovered.directive.mjs +21 -0
  24. package/esm2022/directives/hovered/hovered.service.mjs +34 -0
  25. package/esm2022/directives/hovered/index.mjs +3 -0
  26. package/esm2022/directives/index.mjs +13 -0
  27. package/{esm2020 → esm2022}/directives/item.directive.mjs +4 -4
  28. package/{esm2020 → esm2022}/directives/let.directive.mjs +4 -4
  29. package/{esm2020 → esm2022}/directives/target.directive.mjs +4 -4
  30. package/esm2022/observables/if-map.mjs +5 -0
  31. package/esm2022/observables/index.mjs +5 -0
  32. package/esm2022/observables/typed-from-event.mjs +9 -0
  33. package/esm2022/observables/watch.mjs +6 -0
  34. package/esm2022/observables/zone.mjs +34 -0
  35. package/{esm2020 → esm2022}/pipes/filter.pipe.mjs +4 -4
  36. package/{esm2020 → esm2022}/services/destroy.service.mjs +4 -4
  37. package/esm2022/services/id.service.mjs +18 -0
  38. package/{esm2020 → esm2022}/services/popover.service.mjs +4 -4
  39. package/esm2022/tokens/active-element.mjs +54 -0
  40. package/esm2022/tokens/environment.mjs +45 -0
  41. package/esm2022/tokens/index.mjs +10 -0
  42. package/esm2022/tokens/navigator.mjs +6 -0
  43. package/esm2022/tokens/removed-element.mjs +19 -0
  44. package/esm2022/tokens/user-agent.mjs +6 -0
  45. package/esm2022/types/context.mjs +2 -0
  46. package/esm2022/types/handler.mjs +2 -0
  47. package/esm2022/types/index.mjs +9 -0
  48. package/esm2022/utils/dom/element-checks.mjs +20 -0
  49. package/esm2022/utils/dom/get-actual-target.mjs +7 -0
  50. package/esm2022/utils/dom/get-document-or-shadow-root.mjs +6 -0
  51. package/esm2022/utils/dom/get-element-obscurers.mjs +44 -0
  52. package/esm2022/utils/dom/index.mjs +7 -0
  53. package/esm2022/utils/dom/inject-element.mjs +5 -0
  54. package/esm2022/utils/index.mjs +7 -0
  55. package/esm2022/utils/math/clamp.mjs +11 -0
  56. package/esm2022/utils/math/index.mjs +2 -0
  57. package/esm2022/utils/miscellaneous/array-remove.mjs +4 -0
  58. package/esm2022/utils/miscellaneous/index.mjs +5 -0
  59. package/esm2022/utils/miscellaneous/is-present.mjs +4 -0
  60. package/esm2022/utils/miscellaneous/pure.mjs +81 -0
  61. package/esm2022/utils/miscellaneous/px.mjs +7 -0
  62. package/esm2022/utils/platform/index.mjs +2 -0
  63. package/esm2022/utils/platform/is-ios.mjs +6 -0
  64. package/fesm2022/cuby-ui-cdk.mjs +1067 -0
  65. package/fesm2022/cuby-ui-cdk.mjs.map +1 -0
  66. package/observables/if-map.d.ts +3 -0
  67. package/observables/index.d.ts +4 -0
  68. package/observables/typed-from-event.d.ts +16 -0
  69. package/observables/watch.d.ts +3 -0
  70. package/observables/zone.d.ts +7 -0
  71. package/package.json +10 -15
  72. package/tokens/active-element.d.ts +5 -0
  73. package/tokens/environment.d.ts +19 -0
  74. package/tokens/index.d.ts +5 -0
  75. package/tokens/navigator.d.ts +2 -0
  76. package/tokens/removed-element.d.ts +4 -0
  77. package/tokens/user-agent.d.ts +2 -0
  78. package/types/context.d.ts +3 -0
  79. package/types/handler.d.ts +4 -0
  80. package/types/index.d.ts +2 -0
  81. package/utils/dom/element-checks.d.ts +6 -0
  82. package/utils/dom/get-actual-target.d.ts +4 -0
  83. package/utils/dom/get-document-or-shadow-root.d.ts +1 -0
  84. package/utils/dom/get-element-obscurers.d.ts +9 -0
  85. package/utils/dom/index.d.ts +5 -1
  86. package/utils/dom/inject-element.d.ts +1 -0
  87. package/utils/index.d.ts +3 -0
  88. package/utils/math/clamp.d.ts +8 -0
  89. package/utils/math/index.d.ts +1 -0
  90. package/utils/miscellaneous/array-remove.d.ts +1 -0
  91. package/utils/miscellaneous/index.d.ts +4 -0
  92. package/utils/miscellaneous/is-present.d.ts +1 -0
  93. package/utils/miscellaneous/pure.d.ts +21 -0
  94. package/utils/miscellaneous/px.d.ts +4 -0
  95. package/utils/platform/index.d.ts +1 -0
  96. package/utils/platform/is-ios.d.ts +3 -0
  97. package/esm2020/constants/index.mjs +0 -2
  98. package/esm2020/directives/index.mjs +0 -11
  99. package/esm2020/services/id.service.mjs +0 -18
  100. package/esm2020/tokens/index.mjs +0 -5
  101. package/esm2020/types/index.mjs +0 -7
  102. package/esm2020/utils/dom/index.mjs +0 -3
  103. package/esm2020/utils/dom/is-html-element.mjs +0 -4
  104. package/esm2020/utils/index.mjs +0 -4
  105. package/fesm2015/cuby-ui-cdk.mjs +0 -572
  106. package/fesm2015/cuby-ui-cdk.mjs.map +0 -1
  107. package/fesm2020/cuby-ui-cdk.mjs +0 -579
  108. package/fesm2020/cuby-ui-cdk.mjs.map +0 -1
  109. package/utils/dom/is-html-element.d.ts +0 -1
  110. /package/{esm2020 → esm2022}/constants/svg-node-filter.mjs +0 -0
  111. /package/{esm2020 → esm2022}/cuby-ui-cdk.mjs +0 -0
  112. /package/{esm2020 → esm2022}/date-time/index.mjs +0 -0
  113. /package/{esm2020 → esm2022}/date-time/time.mjs +0 -0
  114. /package/{esm2020 → esm2022}/directives/let.context.mjs +0 -0
  115. /package/{esm2020 → esm2022}/index.mjs +0 -0
  116. /package/{esm2020 → esm2022}/interfaces/dimensions.mjs +0 -0
  117. /package/{esm2020 → esm2022}/interfaces/index.mjs +0 -0
  118. /package/{esm2020 → esm2022}/interfaces/on-change.mjs +0 -0
  119. /package/{esm2020 → esm2022}/interfaces/on-touched.mjs +0 -0
  120. /package/{esm2020 → esm2022}/pipes/index.mjs +0 -0
  121. /package/{esm2020 → esm2022}/services/index.mjs +0 -0
  122. /package/{esm2020 → esm2022}/tokens/history.mjs +0 -0
  123. /package/{esm2020 → esm2022}/tokens/local-storage.mjs +0 -0
  124. /package/{esm2020 → esm2022}/tokens/session-storage.mjs +0 -0
  125. /package/{esm2020 → esm2022}/tokens/window.mjs +0 -0
  126. /package/{esm2020 → esm2022}/types/date-time.mjs +0 -0
  127. /package/{esm2020 → esm2022}/types/input-type.mjs +0 -0
  128. /package/{esm2020 → esm2022}/types/mapper.mjs +0 -0
  129. /package/{esm2020 → esm2022}/types/matcher.mjs +0 -0
  130. /package/{esm2020 → esm2022}/types/nullable.mjs +0 -0
  131. /package/{esm2020 → esm2022}/types/value-of.mjs +0 -0
  132. /package/{esm2020 → esm2022}/utils/dom/contains-or-after.mjs +0 -0
  133. /package/{esm2020 → esm2022}/utils/focus/blur-native-focused.mjs +0 -0
  134. /package/{esm2020 → esm2022}/utils/focus/get-closest-focusable.mjs +0 -0
  135. /package/{esm2020 → esm2022}/utils/focus/get-native-focused.mjs +0 -0
  136. /package/{esm2020 → esm2022}/utils/focus/index.mjs +0 -0
  137. /package/{esm2020 → esm2022}/utils/focus/is-native-keyboard-focusable.mjs +0 -0
  138. /package/{esm2020 → esm2022}/utils/focus/is-native-mouse-focusable.mjs +0 -0
  139. /package/{esm2020 → esm2022}/utils/token/create-token.mjs +0 -0
  140. /package/{esm2020 → esm2022}/utils/token/index.mjs +0 -0
  141. /package/{esm2020 → esm2022}/utils/token/provide.mjs +0 -0
@@ -0,0 +1,1067 @@
1
+ import * as i0 from '@angular/core';
2
+ import { QueryList, inject, ChangeDetectorRef, NgZone, InjectionToken, ElementRef, Directive, Output, Input, Injectable, HostListener, EventEmitter, HostBinding, ViewContainerRef, TemplateRef, Pipe } from '@angular/core';
3
+ import { __decorate } from 'tslib';
4
+ import { NgControl, NgModel, NG_VALUE_ACCESSOR } from '@angular/forms';
5
+ import { pipe, switchMap, EMPTY, fromEvent, tap, Observable, asyncScheduler, BehaviorSubject, timer, map, startWith, share, merge, filter, takeUntil, repeat, withLatestFrom, of, take, distinctUntilChanged, skip, Subject } from 'rxjs';
6
+ import { DOCUMENT } from '@angular/common';
7
+ import { ɵAnimationEngine } from '@angular/animations/browser';
8
+ import { toSignal } from '@angular/core/rxjs-interop';
9
+
10
+ const rect = {
11
+ bottom: 0,
12
+ height: 0,
13
+ left: 0,
14
+ right: 0,
15
+ top: 0,
16
+ width: 0,
17
+ x: 0,
18
+ y: 0,
19
+ };
20
+ /**
21
+ * For type safety when using @ContentChildren and @ViewChildren
22
+ *
23
+ * NOTE: Be careful subscribing to 'changes'
24
+ */
25
+ const EMPTY_QUERY = new QueryList();
26
+ const EMPTY_ARRAY = [];
27
+ const EMPTY_FUNCTION = () => { };
28
+ const EMPTY_CLIENT_RECT = {
29
+ ...rect,
30
+ toJSON: () => rect,
31
+ };
32
+
33
+ /**
34
+ * Handler that always returns `false`.
35
+ */
36
+ // eslint-disable-next-line no-restricted-syntax
37
+ const CUI_FALSE_HANDLER = () => false;
38
+ /**
39
+ * Handler that always returns `true`.
40
+ */
41
+ // eslint-disable-next-line no-restricted-syntax
42
+ const CUI_TRUE_HANDLER = () => true;
43
+
44
+ const svgNodeFilter = {
45
+ acceptNode(node) {
46
+ return 'ownerSVGElement' in node
47
+ ? NodeFilter.FILTER_REJECT
48
+ : NodeFilter.FILTER_ACCEPT;
49
+ },
50
+ };
51
+
52
+ class CuiTime {
53
+ constructor(hours, minutes, seconds = 0, ms = 0) {
54
+ this.hours = hours;
55
+ this.minutes = minutes;
56
+ this.seconds = seconds;
57
+ this.ms = ms;
58
+ }
59
+ static fromString(time) {
60
+ const hours = this.parseHours(time);
61
+ const minutes = Number(time.slice(3, 5)) || 0;
62
+ const seconds = Number(time.slice(6, 8)) || 0;
63
+ const ms = Number(time.slice(9, 12)) || 0;
64
+ return new CuiTime(hours, minutes, seconds, ms);
65
+ }
66
+ static fromPT(time) {
67
+ let duration = time.trim().toUpperCase();
68
+ if (!duration.startsWith('P')) {
69
+ throw new Error('Invalid PT format: does not start with P');
70
+ }
71
+ duration = duration.substring(1);
72
+ if (duration.startsWith('T')) {
73
+ duration = duration.substring(1);
74
+ }
75
+ const regex = /(\d+(\.\d+)?)([HMS])/g;
76
+ let match;
77
+ let hours = 0, minutes = 0, seconds = 0, ms = 0;
78
+ while ((match = regex.exec(duration)) !== null) {
79
+ const value = parseFloat(match[1]);
80
+ const unit = match[3];
81
+ if (unit === 'H') {
82
+ hours = value;
83
+ }
84
+ else if (unit === 'M') {
85
+ minutes = value;
86
+ }
87
+ else if (unit === 'S') {
88
+ seconds = Math.floor(value);
89
+ ms = Math.round((value - seconds) * 1000);
90
+ }
91
+ }
92
+ return new CuiTime(hours, minutes, seconds, ms);
93
+ }
94
+ static parseHours(time) {
95
+ return Number(time.slice(0, 2));
96
+ }
97
+ toString(mode) {
98
+ const needAddMs = mode?.startsWith('HH:MM:SS.MSS') || (!mode && this.ms > 0);
99
+ const needAddSeconds = needAddMs || mode?.startsWith('HH:MM:SS') || (!mode && this.seconds > 0);
100
+ const hhMm = `${this.formatTime(this.hours)}:${this.formatTime(this.minutes)}`;
101
+ const ss = needAddSeconds ? `:${this.formatTime(this.seconds)}` : '';
102
+ const mss = needAddMs ? `.${this.formatTime(this.ms, 3)}` : '';
103
+ return `${hhMm}${ss}${mss}`;
104
+ }
105
+ toPT(mode) {
106
+ let duration = 'PT';
107
+ if (this.hours !== 0) {
108
+ duration += `${this.hours}H`;
109
+ }
110
+ if (this.minutes !== 0) {
111
+ duration += `${this.minutes}M`;
112
+ }
113
+ const totalSeconds = this.seconds + this.ms / 1000;
114
+ if (totalSeconds !== 0 || duration === 'PT') {
115
+ duration += `${parseFloat(totalSeconds.toFixed(3))}S`;
116
+ }
117
+ return duration;
118
+ }
119
+ formatTime(time, digits = 2) {
120
+ return String(time).padStart(digits, '0');
121
+ }
122
+ }
123
+
124
+ function cuiIfMap(project, predicate = Boolean) {
125
+ return pipe(switchMap((value) => (predicate(value) ? project(value) : EMPTY)));
126
+ }
127
+
128
+ function cuiTypedFromEvent(target, event, options = {}) {
129
+ /**
130
+ * @note:
131
+ * in RxJS 7 type signature `CuiTypedEventTarget<E>` !== `HasEventTargetAddRemove<E>`
132
+ */
133
+ return fromEvent(target, event, options);
134
+ }
135
+
136
+ function cuiWatch(cdr = inject(ChangeDetectorRef)) {
137
+ return tap(() => cdr.markForCheck());
138
+ }
139
+
140
+ function cuiZonefull(zone = inject(NgZone)) {
141
+ return (source) => new Observable((subscriber) => source.subscribe({
142
+ next: (value) => zone.run(() => subscriber.next(value)),
143
+ error: (error) => zone.run(() => subscriber.error(error)),
144
+ complete: () => zone.run(() => subscriber.complete()),
145
+ }));
146
+ }
147
+ function cuiZonefree(zone = inject(NgZone)) {
148
+ return (source) => new Observable((subscriber) => zone.runOutsideAngular(() => source.subscribe(subscriber)));
149
+ }
150
+ function cuiZoneOptimized(zone = inject(NgZone)) {
151
+ return pipe(cuiZonefree(zone), cuiZonefull(zone));
152
+ }
153
+ class CuiZoneScheduler {
154
+ constructor(zoneConditionFn, scheduler = asyncScheduler) {
155
+ this.zoneConditionFn = zoneConditionFn;
156
+ this.scheduler = scheduler;
157
+ }
158
+ now() {
159
+ return this.scheduler.now();
160
+ }
161
+ schedule(...args) {
162
+ return this.zoneConditionFn(() => this.scheduler.schedule(...args));
163
+ }
164
+ }
165
+ function cuiZonefreeScheduler(zone = inject(NgZone), scheduler = asyncScheduler) {
166
+ return new CuiZoneScheduler(zone.runOutsideAngular.bind(zone), scheduler);
167
+ }
168
+ function cuiZonefullScheduler(zone = inject(NgZone), scheduler = asyncScheduler) {
169
+ return new CuiZoneScheduler(zone.run.bind(zone), scheduler);
170
+ }
171
+
172
+ function cuiCreateToken(defaults) {
173
+ return cuiCreateTokenFromFactory(() => defaults);
174
+ }
175
+ function cuiCreateTokenFromFactory(factory) {
176
+ return new InjectionToken('', { factory });
177
+ }
178
+
179
+ function cuiProvide(provide, useExisting, multi = false) {
180
+ return { provide, useExisting, multi };
181
+ }
182
+
183
+ const CUI_WINDOW = cuiCreateTokenFromFactory(() => {
184
+ const { defaultView } = inject(DOCUMENT);
185
+ if (!defaultView) {
186
+ throw new Error('Window is not available');
187
+ }
188
+ return defaultView;
189
+ });
190
+
191
+ function cuiContainsOrAfter(current, node) {
192
+ try {
193
+ return (current.contains(node) ||
194
+ !!(node.compareDocumentPosition(current) & Node.DOCUMENT_POSITION_PRECEDING));
195
+ }
196
+ catch {
197
+ return false;
198
+ }
199
+ }
200
+
201
+ function cuiIsInput(element) {
202
+ return element.matches('input');
203
+ }
204
+ function cuiIsTextarea(element) {
205
+ return element.matches('textarea');
206
+ }
207
+ function cuiIsTextfield(element) {
208
+ return cuiIsInput(element) || cuiIsTextarea(element);
209
+ }
210
+ function cuiIsElement(node) {
211
+ return !!node && 'nodeType' in node && node.nodeType === Node.ELEMENT_NODE;
212
+ }
213
+ function cuiIsHTMLElement(node) {
214
+ const defaultView = node?.ownerDocument.defaultView;
215
+ return !!node && !!defaultView && node instanceof defaultView.HTMLElement;
216
+ }
217
+ function cuiIsTextNode(node) {
218
+ return node.nodeType === Node.TEXT_NODE;
219
+ }
220
+
221
+ /**
222
+ * Gets actual target from open Shadow DOM if event happened within it
223
+ */
224
+ function cuiGetActualTarget(event) {
225
+ return event.composedPath()[0];
226
+ }
227
+
228
+ function cuiGetDocumentOrShadowRoot(node) {
229
+ return 'getRootNode' in node && node.isConnected
230
+ ? node.getRootNode()
231
+ : node.ownerDocument;
232
+ }
233
+
234
+ /**
235
+ * Clamps a value between two inclusive limits
236
+ *
237
+ * @param value
238
+ * @param min lower limit
239
+ * @param max upper limit
240
+ */
241
+ function cuiClamp(value, min, max) {
242
+ return Math.min(max, Math.max(min, value));
243
+ }
244
+
245
+ function cuiArrayRemove(array, index) {
246
+ return array.slice(0, Math.max(index, 0)).concat(array.slice(Math.max(index + 1, 0)));
247
+ }
248
+
249
+ function cuiIsPresent(value) {
250
+ return value !== null && value !== undefined;
251
+ }
252
+
253
+ function decorateMethod(originalMethod) {
254
+ let previousArgs = [];
255
+ let originalFnWasCalledLeastAtOnce = false;
256
+ let pureValue;
257
+ return function cuiPureMethodPatched(...args) {
258
+ const isPure = originalFnWasCalledLeastAtOnce &&
259
+ previousArgs.length === args.length &&
260
+ args.every((arg, index) => arg === previousArgs[index]);
261
+ if (isPure) {
262
+ return pureValue;
263
+ }
264
+ previousArgs = args;
265
+ pureValue = originalMethod.apply(this, args);
266
+ originalFnWasCalledLeastAtOnce = true;
267
+ return pureValue;
268
+ };
269
+ }
270
+ function decorateGetter(originalGetter, propertyKey, enumerable = true) {
271
+ return function cuiPureGetterPatched() {
272
+ const value = originalGetter.call(this);
273
+ Object.defineProperty(this, propertyKey, { enumerable, value });
274
+ return value;
275
+ };
276
+ }
277
+ function cuiPure(target, propertyKeyOrContext, descriptor) {
278
+ if (typeof target === 'function') {
279
+ const context = propertyKeyOrContext;
280
+ if (context.kind === 'getter') {
281
+ return decorateGetter(target, context.name);
282
+ }
283
+ if (context.kind === 'method') {
284
+ return decorateMethod(target);
285
+ }
286
+ throw new CuiPureException();
287
+ }
288
+ const { get, enumerable, value } = descriptor;
289
+ const propertyKey = propertyKeyOrContext;
290
+ if (get) {
291
+ return {
292
+ configurable: true,
293
+ enumerable,
294
+ get: decorateGetter(get, propertyKey, enumerable),
295
+ };
296
+ }
297
+ if (typeof value !== 'function') {
298
+ throw new CuiPureException();
299
+ }
300
+ const original = value;
301
+ return {
302
+ configurable: true,
303
+ enumerable,
304
+ get() {
305
+ let previousArgs = [];
306
+ let originalFnWasCalledLeastAtOnce = false;
307
+ let pureValue;
308
+ const patched = (...args) => {
309
+ const isPure = originalFnWasCalledLeastAtOnce &&
310
+ previousArgs.length === args.length &&
311
+ args.every((arg, index) => arg === previousArgs[index]);
312
+ if (isPure) {
313
+ return pureValue;
314
+ }
315
+ previousArgs = args;
316
+ pureValue = original.apply(this, args);
317
+ originalFnWasCalledLeastAtOnce = true;
318
+ return pureValue;
319
+ };
320
+ Object.defineProperty(this, propertyKey, {
321
+ configurable: true,
322
+ value: patched,
323
+ });
324
+ return patched;
325
+ },
326
+ };
327
+ }
328
+ class CuiPureException extends Error {
329
+ constructor() {
330
+ super('cuiPure can only be used with functions or getters');
331
+ }
332
+ }
333
+
334
+ /**
335
+ * Adds 'px' to the number and turns it into a string
336
+ */
337
+ function cuiPx(value) {
338
+ return `${value}px`;
339
+ }
340
+
341
+ /**
342
+ * Returns array of Elements covering edges of given element or null if at least one edge middle point is visible
343
+ *
344
+ * CAUTION: Empty array means element if offscreen i.e. covered by no elements, rather than not covered
345
+ * ```ts
346
+ * function cuiGetElementObscures(element: Element): readonly [Element, Element, Element, Element] | [] | null
347
+ * ```
348
+ */
349
+ function cuiGetElementObscures(element) {
350
+ const { ownerDocument } = element;
351
+ if (!ownerDocument?.defaultView || !element.getBoundingClientRect) {
352
+ return null;
353
+ }
354
+ const { innerWidth, innerHeight } = ownerDocument.defaultView;
355
+ const doc = cuiGetDocumentOrShadowRoot(element);
356
+ const rect = element.getBoundingClientRect();
357
+ if (rect.width === 0 && rect.height === 0) {
358
+ return null;
359
+ }
360
+ const left = cuiClamp(Math.round(rect.left) + 2, 0, innerWidth);
361
+ const top = cuiClamp(Math.round(rect.top) + 2, 0, innerHeight);
362
+ const right = cuiClamp(Math.round(rect.right) - 2, 0, innerWidth);
363
+ const bottom = cuiClamp(Math.round(rect.bottom) - 2, 0, innerHeight);
364
+ const horizontalMiddle = cuiClamp(Math.round(rect.left + rect.width / 2), 0, innerWidth);
365
+ const verticalMiddle = cuiClamp(Math.round(rect.top + rect.height / 2), 0, innerHeight);
366
+ const elements = [
367
+ doc.elementFromPoint(horizontalMiddle, top),
368
+ doc.elementFromPoint(horizontalMiddle, bottom),
369
+ doc.elementFromPoint(left, verticalMiddle),
370
+ doc.elementFromPoint(right, verticalMiddle),
371
+ ];
372
+ const nonNull = elements.filter(cuiIsPresent);
373
+ if (!nonNull.length) {
374
+ return [];
375
+ }
376
+ const filtered = nonNull.filter((el) => !element.contains(el) && !el.contains(element));
377
+ return filtered.length === 4
378
+ ? filtered
379
+ : null;
380
+ }
381
+
382
+ function cuiInjectElement() {
383
+ return inject(ElementRef).nativeElement;
384
+ }
385
+
386
+ function cuiGetNativeFocused({ activeElement }) {
387
+ if (!activeElement?.shadowRoot) {
388
+ return activeElement;
389
+ }
390
+ let element = activeElement.shadowRoot.activeElement;
391
+ while (element?.shadowRoot) {
392
+ element = element.shadowRoot.activeElement;
393
+ }
394
+ return element;
395
+ }
396
+
397
+ function cuiBlurNativeFocused(document) {
398
+ const activeElement = cuiGetNativeFocused(document);
399
+ if (cuiIsHTMLElement(activeElement)) {
400
+ activeElement.blur();
401
+ }
402
+ }
403
+
404
+ function cuiIsNativeKeyboardFocusable(element) {
405
+ if (element.hasAttribute('disabled') || element.getAttribute('tabIndex') === '-1') {
406
+ return false;
407
+ }
408
+ if ((cuiIsHTMLElement(element) && element.isContentEditable) ||
409
+ element.getAttribute('tabIndex') === '0') {
410
+ return true;
411
+ }
412
+ switch (element.tagName) {
413
+ case 'BUTTON':
414
+ case 'SELECT':
415
+ case 'TEXTAREA':
416
+ return true;
417
+ case 'VIDEO':
418
+ case 'AUDIO':
419
+ return element.hasAttribute('controls');
420
+ case 'INPUT':
421
+ return element.getAttribute('type') !== 'hidden';
422
+ case 'A':
423
+ case 'LINK':
424
+ return element.hasAttribute('href');
425
+ default:
426
+ return false;
427
+ }
428
+ }
429
+
430
+ function cuiIsNativeMouseFocusable(element) {
431
+ return (!element.hasAttribute('disabled') &&
432
+ (element.getAttribute('tabIndex') === '-1' ||
433
+ cuiIsNativeKeyboardFocusable(element)));
434
+ }
435
+
436
+ function cuiGetClosestFocusable({ initial, root, previous = false, keyboard = true, }) {
437
+ if (!root.ownerDocument) {
438
+ return null;
439
+ }
440
+ const check = keyboard ? cuiIsNativeKeyboardFocusable : cuiIsNativeMouseFocusable;
441
+ const treeWalker = root.ownerDocument.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, svgNodeFilter);
442
+ treeWalker.currentNode = initial;
443
+ while (previous ? treeWalker.previousNode() : treeWalker.nextNode()) {
444
+ if (cuiIsHTMLElement(treeWalker.currentNode)) {
445
+ initial = treeWalker.currentNode;
446
+ }
447
+ if (cuiIsHTMLElement(initial) && check(initial)) {
448
+ return initial;
449
+ }
450
+ }
451
+ return null;
452
+ }
453
+
454
+ const CUI_SAFARI_REG_EXP = /^((?!chrome|android).)*safari/i;
455
+ const CUI_IOS_REG_EXP = /ipad|iphone|ipod/i;
456
+ function cuiIsIos({ userAgent, maxTouchPoints }) {
457
+ return CUI_SAFARI_REG_EXP.test(userAgent) || (CUI_IOS_REG_EXP.test(userAgent) && maxTouchPoints > 1);
458
+ }
459
+
460
+ /**
461
+ * Element currently being removed by AnimationEngine
462
+ */
463
+ const CUI_REMOVED_ELEMENT = cuiCreateTokenFromFactory(() => {
464
+ const stub = { onRemovalComplete: () => { } };
465
+ const element$ = new BehaviorSubject(null);
466
+ const engine = inject(ɵAnimationEngine, { optional: true }) || stub;
467
+ const { onRemovalComplete = stub.onRemovalComplete } = engine;
468
+ engine.onRemovalComplete = (element, context) => {
469
+ element$.next(element);
470
+ onRemovalComplete.call(engine, element, context);
471
+ };
472
+ return element$.pipe(switchMap((element) => timer(0).pipe(map(() => null), startWith(element))), share());
473
+ });
474
+
475
+ // Checks if focusout event should be considered leaving active zone
476
+ function isValidFocusout(target, removedElement = null) {
477
+ return (
478
+ // Not due to switching tabs/going to DevTools
479
+ cuiGetDocumentOrShadowRoot(target).activeElement !== target &&
480
+ // Not due to button/input becoming disabled or under disabled fieldset
481
+ !target.matches(':disabled') &&
482
+ // Not due to element being removed from DOM
483
+ !removedElement?.contains(target) &&
484
+ // Not due to scrollable element became non-scrollable
485
+ cuiIsNativeMouseFocusable(target));
486
+ }
487
+ function shadowRootActiveElement(root) {
488
+ return merge(cuiTypedFromEvent(root, 'focusin').pipe(map(({ target }) => target)), cuiTypedFromEvent(root, 'focusout').pipe(filter(({ target, relatedTarget }) => !!relatedTarget && isValidFocusout(target)), map(({ relatedTarget }) => relatedTarget)));
489
+ }
490
+ /**
491
+ * Active element on the document for ActiveZone
492
+ */
493
+ const CUI_ACTIVE_ELEMENT = cuiCreateTokenFromFactory(() => {
494
+ const removedElement$ = inject(CUI_REMOVED_ELEMENT);
495
+ const win = inject(CUI_WINDOW);
496
+ const doc = inject(DOCUMENT);
497
+ const zone = inject(NgZone);
498
+ const focusout$ = cuiTypedFromEvent(win, 'focusout', { capture: true });
499
+ const focusin$ = cuiTypedFromEvent(win, 'focusin', { capture: true });
500
+ const blur$ = cuiTypedFromEvent(win, 'blur');
501
+ const mousedown$ = cuiTypedFromEvent(win, 'mousedown');
502
+ const mouseup$ = cuiTypedFromEvent(win, 'mouseup');
503
+ return merge(focusout$.pipe(takeUntil(mousedown$), repeat({ delay: () => mouseup$ }), withLatestFrom(removedElement$), filter(([event, removedElement]) => isValidFocusout(cuiGetActualTarget(event), removedElement)), map(([{ relatedTarget }]) => relatedTarget)), blur$.pipe(map(() => doc.activeElement), filter((element) => !!element?.matches('iframe'))), focusin$.pipe(switchMap((event) => {
504
+ const target = cuiGetActualTarget(event);
505
+ const root = cuiGetDocumentOrShadowRoot(target);
506
+ return root === doc
507
+ ? of(target)
508
+ : shadowRootActiveElement(root).pipe(startWith(target));
509
+ })), mousedown$.pipe(switchMap((event) => {
510
+ const actualTargetInCurrentTime = cuiGetActualTarget(event);
511
+ return !doc.activeElement || doc.activeElement === doc.body
512
+ ? of(actualTargetInCurrentTime)
513
+ : focusout$.pipe(take(1), map(
514
+ /**
515
+ * Do not use `map(() => cuiGetActualTarget(event))`
516
+ * because we have different result in runtime
517
+ */
518
+ () => actualTargetInCurrentTime), takeUntil(timer(0, cuiZonefreeScheduler(zone))));
519
+ }))).pipe(distinctUntilChanged(), share());
520
+ });
521
+
522
+ // https://stackoverflow.com/a/11381730/2706426 http://detectmobilebrowsers.com/
523
+ const firstRegex =
524
+ // eslint-disable-next-line sonarjs/regex-complexity
525
+ /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series([46])0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/;
526
+ const secondRegex =
527
+ // eslint-disable-next-line sonarjs/regex-complexity
528
+ /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br([ev])w|bumb|bw-([nu])|c55\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do([cp])o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly([-_])|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-([mpt])|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c([- _agpst])|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac([ \-/])|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja([tv])a|jbro|jemu|jigs|kddi|keji|kgt([ /])|klon|kpt |kwc-|kyo([ck])|le(no|xi)|lg( g|\/([klu])|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t([- ov])|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30([02])|n50([025])|n7(0([01])|10)|ne(([cm])-|on|tf|wf|wg|wt)|nok([6i])|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan([adt])|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\/|se(c([-01])|47|mc|nd|ri)|sgh-|shar|sie([-m])|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel([im])|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c([- ])|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/;
529
+ const CUI_IS_MOBILE = cuiCreateTokenFromFactory(() => firstRegex.test(inject(CUI_USER_AGENT).toLowerCase()) ||
530
+ secondRegex.test(inject(CUI_USER_AGENT).slice(0, 4).toLowerCase()));
531
+ const CUI_IS_IOS = cuiCreateTokenFromFactory(() => cuiIsIos(inject(CUI_NAVIGATOR)));
532
+ const CUI_IS_ANDROID = cuiCreateTokenFromFactory(() => inject(CUI_IS_MOBILE) && !inject(CUI_IS_IOS));
533
+ const CUI_IS_WEBKIT = cuiCreateTokenFromFactory(() => !!inject(CUI_WINDOW)?.webkitConvertPointFromNodeToPage);
534
+ const CUI_PLATFORM = cuiCreateTokenFromFactory(() => {
535
+ if (inject(CUI_IS_IOS)) {
536
+ return 'ios';
537
+ }
538
+ return inject(CUI_IS_ANDROID) ? 'android' : 'web';
539
+ });
540
+ const CUI_IS_TOUCH = cuiCreateTokenFromFactory(() => {
541
+ const media = inject(CUI_WINDOW).matchMedia('(pointer: coarse)');
542
+ return toSignal(fromEvent(media, 'change').pipe(map(() => media.matches)), {
543
+ initialValue: media.matches,
544
+ });
545
+ });
546
+ /**
547
+ * Detect if app is running under Cypress
548
+ * {@link https://docs.cypress.io/faq/questions/using-cypress-faq#Is-there-any-way-to-detect-if-my-app-is-running-under-Cypress Cypress docs}
549
+ */
550
+ const CUI_IS_CYPRESS = cuiCreateTokenFromFactory(() => !!inject(CUI_WINDOW).Cypress);
551
+ /**
552
+ * Manually provide `true` when running tests in Playwright
553
+ */
554
+ const CUI_IS_PLAYWRIGHT = cuiCreateTokenFromFactory(CUI_FALSE_HANDLER);
555
+ /**
556
+ * Detect if app is running under any of test frameworks
557
+ */
558
+ const CUI_IS_E2E = cuiCreateTokenFromFactory(() => inject(CUI_IS_CYPRESS) || inject(CUI_IS_PLAYWRIGHT));
559
+
560
+ const CUI_HISTORY = cuiCreateTokenFromFactory(() => inject(CUI_WINDOW).history);
561
+
562
+ const CUI_LOCAL_STORAGE = cuiCreateTokenFromFactory(() => inject(CUI_WINDOW).localStorage);
563
+
564
+ const CUI_NAVIGATOR = new InjectionToken('[CUI_NAVIGATOR]', {
565
+ factory: () => inject(CUI_WINDOW).navigator,
566
+ });
567
+
568
+ const CUI_SESSION_STORAGE = cuiCreateTokenFromFactory(() => inject(CUI_WINDOW).sessionStorage);
569
+
570
+ const CUI_USER_AGENT = new InjectionToken('[CUI_USER_AGENT]', {
571
+ factory: () => inject(CUI_NAVIGATOR).userAgent,
572
+ });
573
+
574
+ class CuiActiveZone {
575
+ constructor() {
576
+ this.control = inject(NgControl, { self: true, optional: true });
577
+ this.active$ = inject(CUI_ACTIVE_ELEMENT);
578
+ this.zone = inject(NgZone);
579
+ this.el = cuiInjectElement();
580
+ this.cuiActiveZoneParent = null;
581
+ this.subActiveZones = [];
582
+ this.directParentActiveZone = inject(CuiActiveZone, {
583
+ skipSelf: true,
584
+ optional: true,
585
+ });
586
+ this.cuiActiveZoneChange = this.active$.pipe(map((element) => !!element && this.contains(element)), startWith(false), distinctUntilChanged(), skip(1), tap((active) => {
587
+ if (!active && typeof this.control?.valueAccessor.onTouched === 'function') {
588
+ this.control.valueAccessor.onTouched();
589
+ }
590
+ }), cuiZoneOptimized(this.zone));
591
+ this.directParentActiveZone?.addSubActiveZone(this);
592
+ }
593
+ set cuiActiveZoneParentSetter(zone) {
594
+ this.setZone(zone);
595
+ }
596
+ ngOnDestroy() {
597
+ this.directParentActiveZone?.removeSubActiveZone(this);
598
+ this.cuiActiveZoneParent?.removeSubActiveZone(this);
599
+ }
600
+ contains(node) {
601
+ return (this.el.contains(node) ||
602
+ this.subActiveZones.some((item, index, array) => array.indexOf(item) === index && item.contains(node)));
603
+ }
604
+ setZone(zone) {
605
+ this.cuiActiveZoneParent?.removeSubActiveZone(this);
606
+ zone?.addSubActiveZone(this);
607
+ this.cuiActiveZoneParent = zone;
608
+ }
609
+ addSubActiveZone(activeZone) {
610
+ this.subActiveZones = [...this.subActiveZones, activeZone];
611
+ }
612
+ removeSubActiveZone(activeZone) {
613
+ this.subActiveZones = cuiArrayRemove(this.subActiveZones, this.subActiveZones.indexOf(activeZone));
614
+ }
615
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiActiveZone, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
616
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CuiActiveZone, isStandalone: true, selector: "[cuiActiveZone]:not(ng-container), [cuiActiveZoneChange]:not(ng-container), [cuiActiveZoneParent]:not(ng-container)", inputs: { cuiActiveZoneParentSetter: ["cuiActiveZoneParent", "cuiActiveZoneParentSetter"] }, outputs: { cuiActiveZoneChange: "cuiActiveZoneChange" }, host: { listeners: { "document:mousedown.silent": "(0)" } }, exportAs: ["cuiActiveZone"], ngImport: i0 }); }
617
+ }
618
+ __decorate([
619
+ cuiPure
620
+ ], CuiActiveZone.prototype, "setZone", null);
621
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiActiveZone, decorators: [{
622
+ type: Directive,
623
+ args: [{
624
+ standalone: true,
625
+ selector: '[cuiActiveZone]:not(ng-container), [cuiActiveZoneChange]:not(ng-container), [cuiActiveZoneParent]:not(ng-container)',
626
+ exportAs: 'cuiActiveZone',
627
+ host: {
628
+ '(document:mousedown.silent)': '(0)',
629
+ },
630
+ }]
631
+ }], ctorParameters: function () { return []; }, propDecorators: { cuiActiveZoneChange: [{
632
+ type: Output
633
+ }], cuiActiveZoneParentSetter: [{
634
+ type: Input,
635
+ args: ['cuiActiveZoneParent']
636
+ }], setZone: [] } });
637
+
638
+ function movedOut({ currentTarget, relatedTarget }) {
639
+ return (!cuiIsElement(relatedTarget) ||
640
+ !cuiIsElement(currentTarget) ||
641
+ !currentTarget.contains(relatedTarget));
642
+ }
643
+ class CuiHoveredService extends Observable {
644
+ constructor() {
645
+ super((subscriber) => this.stream$.subscribe(subscriber));
646
+ this.el = cuiInjectElement();
647
+ this.zone = inject(NgZone);
648
+ this.stream$ = merge(cuiTypedFromEvent(this.el, 'mouseenter').pipe(map(CUI_TRUE_HANDLER)), cuiTypedFromEvent(this.el, 'mouseleave').pipe(map(CUI_FALSE_HANDLER)),
649
+ // Hello, Safari
650
+ cuiTypedFromEvent(this.el, 'mouseout').pipe(filter(movedOut), map(CUI_FALSE_HANDLER))).pipe(distinctUntilChanged(), cuiZoneOptimized(this.zone));
651
+ }
652
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiHoveredService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
653
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiHoveredService }); }
654
+ }
655
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiHoveredService, decorators: [{
656
+ type: Injectable
657
+ }], ctorParameters: function () { return []; } });
658
+ function cuiHovered() {
659
+ return toSignal(inject(CUI_IS_MOBILE) ? of(false) : inject(CuiHoveredService).pipe(cuiWatch()), {
660
+ initialValue: false,
661
+ });
662
+ }
663
+
664
+ class CuiHovered {
665
+ constructor() {
666
+ this.cuiHoveredChange = inject(CuiHoveredService);
667
+ }
668
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiHovered, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
669
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CuiHovered, isStandalone: true, selector: "[cuiHoveredChange]", outputs: { cuiHoveredChange: "cuiHoveredChange" }, providers: [CuiHoveredService], ngImport: i0 }); }
670
+ }
671
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiHovered, decorators: [{
672
+ type: Directive,
673
+ args: [{
674
+ standalone: true,
675
+ selector: '[cuiHoveredChange]',
676
+ providers: [CuiHoveredService],
677
+ }]
678
+ }], propDecorators: { cuiHoveredChange: [{
679
+ type: Output
680
+ }] } });
681
+
682
+ class CuiDestroyService extends Subject {
683
+ ngOnDestroy() {
684
+ this.next();
685
+ this.complete();
686
+ }
687
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiDestroyService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
688
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiDestroyService }); }
689
+ }
690
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiDestroyService, decorators: [{
691
+ type: Injectable
692
+ }] });
693
+
694
+ const CUI = 'cui_';
695
+ class CuiIdService {
696
+ static { this.autoId = 0; }
697
+ generate() {
698
+ return `${CUI}${CuiIdService.autoId++}${Date.now()}`;
699
+ }
700
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiIdService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
701
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiIdService, providedIn: 'root' }); }
702
+ }
703
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiIdService, decorators: [{
704
+ type: Injectable,
705
+ args: [{
706
+ providedIn: 'root'
707
+ }]
708
+ }] });
709
+
710
+ class CuiPopoverService {
711
+ constructor(items, component, options = {}) {
712
+ this.options = options;
713
+ this.cuiIdService = inject(CuiIdService);
714
+ this.items$ = inject(items);
715
+ this.component = component;
716
+ }
717
+ open(content, options = {}) {
718
+ return new Observable(observer => {
719
+ const item = {
720
+ ...this.options,
721
+ ...options,
722
+ $implicit: observer,
723
+ id: this.cuiIdService.generate(),
724
+ component: this.component,
725
+ content: content,
726
+ completeWith: (result) => {
727
+ observer.next(result);
728
+ observer.complete();
729
+ },
730
+ };
731
+ this.items$.next([...this.items$.value, item]);
732
+ return () => {
733
+ this.items$.next(this.items$.value.filter(value => value !== item));
734
+ };
735
+ });
736
+ }
737
+ closeAll() {
738
+ this.items$.next([]);
739
+ }
740
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiPopoverService, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable }); }
741
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiPopoverService }); }
742
+ }
743
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiPopoverService, decorators: [{
744
+ type: Injectable
745
+ }], ctorParameters: function () { return [{ type: undefined }, { type: undefined }, { type: undefined }]; } });
746
+
747
+ class CuiAutoResizingDirective {
748
+ constructor() {
749
+ this.window = inject(CUI_WINDOW);
750
+ this.element = inject(ElementRef).nativeElement;
751
+ this.ngControl = inject(NgControl, { self: true, optional: true });
752
+ this.ngModel = inject(NgModel, { self: true, optional: true });
753
+ this.destroy$ = inject(CuiDestroyService, { self: true });
754
+ this.elementStyles = this.element.style;
755
+ }
756
+ ngOnInit() {
757
+ this.initNgControlValueChangeSubscription();
758
+ this.initNgModelValueChangeSubscription();
759
+ }
760
+ ngAfterViewChecked() {
761
+ this.resize();
762
+ }
763
+ onInput() {
764
+ this.resize();
765
+ }
766
+ initNgControlValueChangeSubscription() {
767
+ if (!this.ngControl) {
768
+ return;
769
+ }
770
+ this.ngControl.valueChanges
771
+ .pipe(takeUntil(this.destroy$))
772
+ .subscribe(this.resize.bind(this));
773
+ }
774
+ initNgModelValueChangeSubscription() {
775
+ if (!this.ngModel) {
776
+ return;
777
+ }
778
+ this.ngModel.valueChanges
779
+ .pipe(takeUntil(this.destroy$))
780
+ .subscribe(this.resize.bind(this));
781
+ }
782
+ resize() {
783
+ const { maxHeight: computedMaxHeight, borderTopWidth, borderBottomWidth } = this.window.getComputedStyle(this.element);
784
+ this.elementStyles.height = 'auto';
785
+ this.elementStyles.height =
786
+ this.element.scrollHeight + parseFloat(borderTopWidth) + parseFloat(borderBottomWidth) + 'px';
787
+ if (parseFloat(this.element.style.height) < parseFloat(computedMaxHeight)) {
788
+ this.elementStyles.overflow = 'hidden';
789
+ return;
790
+ }
791
+ this.elementStyles.overflowY = 'scroll';
792
+ this.elementStyles.height = computedMaxHeight;
793
+ }
794
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiAutoResizingDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
795
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CuiAutoResizingDirective, isStandalone: true, selector: "textarea[cuiAutoResizing]", host: { listeners: { "input": "onInput()" } }, providers: [CuiDestroyService], ngImport: i0 }); }
796
+ }
797
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiAutoResizingDirective, decorators: [{
798
+ type: Directive,
799
+ args: [{
800
+ standalone: true,
801
+ selector: 'textarea[cuiAutoResizing]',
802
+ providers: [CuiDestroyService]
803
+ }]
804
+ }], propDecorators: { onInput: [{
805
+ type: HostListener,
806
+ args: ['input']
807
+ }] } });
808
+
809
+ class CuiClickOutsideDirective {
810
+ constructor() {
811
+ this.element = inject(ElementRef).nativeElement;
812
+ this.cuiClickOutside = new EventEmitter();
813
+ }
814
+ onClickOutside(target) {
815
+ if (this.element.contains(target)) {
816
+ return;
817
+ }
818
+ this.cuiClickOutside.emit(target);
819
+ }
820
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiClickOutsideDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
821
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CuiClickOutsideDirective, isStandalone: true, selector: "(cuiClickOutside)", outputs: { cuiClickOutside: "cuiClickOutside" }, host: { listeners: { "document:click": "onClickOutside($event.target)" } }, ngImport: i0 }); }
822
+ }
823
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiClickOutsideDirective, decorators: [{
824
+ type: Directive,
825
+ args: [{
826
+ standalone: true,
827
+ selector: '(cuiClickOutside)'
828
+ }]
829
+ }], propDecorators: { cuiClickOutside: [{
830
+ type: Output
831
+ }], onClickOutside: [{
832
+ type: HostListener,
833
+ args: ['document:click', ['$event.target']]
834
+ }] } });
835
+
836
+ class CuiDimensionsObserverDirective {
837
+ constructor() {
838
+ this.element = inject(ElementRef).nativeElement;
839
+ this.observer = new ResizeObserver((entries) => {
840
+ entries.forEach(() => this.cuiResizeObserver.emit({
841
+ width: this.element.offsetWidth,
842
+ height: this.element.offsetHeight
843
+ }));
844
+ });
845
+ this.cuiResizeObserver = new EventEmitter();
846
+ }
847
+ ngOnInit() {
848
+ this.observer.observe(this.element);
849
+ }
850
+ ngOnDestroy() {
851
+ this.observer.disconnect();
852
+ }
853
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiDimensionsObserverDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
854
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CuiDimensionsObserverDirective, isStandalone: true, selector: "[cuiResizeObserver]", outputs: { cuiResizeObserver: "cuiResizeObserver" }, ngImport: i0 }); }
855
+ }
856
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiDimensionsObserverDirective, decorators: [{
857
+ type: Directive,
858
+ args: [{
859
+ standalone: true,
860
+ selector: '[cuiResizeObserver]'
861
+ }]
862
+ }], propDecorators: { cuiResizeObserver: [{
863
+ type: Output
864
+ }] } });
865
+
866
+ class CuiContentEditableValueAccessorDirective {
867
+ constructor() {
868
+ this.element = inject(ElementRef).nativeElement;
869
+ }
870
+ writeValue(value) {
871
+ this.element.innerText = value ?? '';
872
+ }
873
+ registerOnChange(fn) {
874
+ this.onChange = fn;
875
+ }
876
+ registerOnTouched(fn) {
877
+ this.onTouched = fn;
878
+ }
879
+ setDisabledState(isDisabled) {
880
+ this.element.contentEditable = String(!isDisabled);
881
+ }
882
+ onInput() {
883
+ this.onChange(this.element.innerHTML === '<br>' ? '' : this.element.innerText);
884
+ }
885
+ onBlur() {
886
+ this.onTouched();
887
+ }
888
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiContentEditableValueAccessorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
889
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CuiContentEditableValueAccessorDirective, isStandalone: true, selector: "[contenteditable][formControlName], [contenteditable][formControl], [contenteditable][ngModel]", host: { listeners: { "input": "onInput()", "blur": "onBlur()" } }, providers: [cuiProvide(NG_VALUE_ACCESSOR, CuiContentEditableValueAccessorDirective, true)], ngImport: i0 }); }
890
+ }
891
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiContentEditableValueAccessorDirective, decorators: [{
892
+ type: Directive,
893
+ args: [{
894
+ standalone: true,
895
+ selector: '[contenteditable][formControlName], [contenteditable][formControl], [contenteditable][ngModel]',
896
+ providers: [cuiProvide(NG_VALUE_ACCESSOR, CuiContentEditableValueAccessorDirective, true)]
897
+ }]
898
+ }], propDecorators: { onInput: [{
899
+ type: HostListener,
900
+ args: ['input']
901
+ }], onBlur: [{
902
+ type: HostListener,
903
+ args: ['blur']
904
+ }] } });
905
+
906
+ class CuiElementDirective {
907
+ constructor() {
908
+ this.nativeElement = inject((ElementRef)).nativeElement;
909
+ return new ElementRef(this.nativeElement);
910
+ }
911
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiElementDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
912
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CuiElementDirective, isStandalone: true, selector: "[cuiElement]", exportAs: ["elementRef"], ngImport: i0 }); }
913
+ }
914
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiElementDirective, decorators: [{
915
+ type: Directive,
916
+ args: [{
917
+ standalone: true,
918
+ selector: '[cuiElement]',
919
+ exportAs: 'elementRef',
920
+ }]
921
+ }], ctorParameters: function () { return []; } });
922
+
923
+ class CuiFocusTrapDirective {
924
+ constructor() {
925
+ this.document = inject(DOCUMENT);
926
+ this.element = inject(ElementRef).nativeElement;
927
+ this.activeElement = cuiGetNativeFocused(this.document);
928
+ this.tabIndex = 0;
929
+ this.initElementFocus();
930
+ }
931
+ ngOnDestroy() {
932
+ cuiBlurNativeFocused(this.document);
933
+ Promise.resolve().then(() => {
934
+ if (!cuiIsHTMLElement(this.activeElement)) {
935
+ return;
936
+ }
937
+ this.activeElement.focus();
938
+ });
939
+ }
940
+ onFocusIn(node) {
941
+ if (cuiContainsOrAfter(this.element, node)) {
942
+ return;
943
+ }
944
+ cuiGetClosestFocusable({
945
+ initial: this.element,
946
+ root: this.element,
947
+ })?.focus();
948
+ }
949
+ initElementFocus() {
950
+ Promise.resolve().then(() => this.element.focus());
951
+ }
952
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiFocusTrapDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
953
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CuiFocusTrapDirective, isStandalone: true, selector: "[cuiFocusTrap]", host: { listeners: { "window:focusin": "onFocusIn($event.target)" }, properties: { "tabIndex": "this.tabIndex" } }, ngImport: i0 }); }
954
+ }
955
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiFocusTrapDirective, decorators: [{
956
+ type: Directive,
957
+ args: [{
958
+ standalone: true,
959
+ selector: '[cuiFocusTrap]',
960
+ }]
961
+ }], ctorParameters: function () { return []; }, propDecorators: { tabIndex: [{
962
+ type: HostBinding,
963
+ args: ['tabIndex']
964
+ }], onFocusIn: [{
965
+ type: HostListener,
966
+ args: ['window:focusin', ['$event.target']]
967
+ }] } });
968
+
969
+ class CuiItemDirective {
970
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
971
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CuiItemDirective, isStandalone: true, selector: "[cuiItem]", ngImport: i0 }); }
972
+ }
973
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiItemDirective, decorators: [{
974
+ type: Directive,
975
+ args: [{
976
+ standalone: true,
977
+ selector: '[cuiItem]'
978
+ }]
979
+ }] });
980
+
981
+ class CuiLetContext {
982
+ constructor(internalDirectiveInstance) {
983
+ this.internalDirectiveInstance = internalDirectiveInstance;
984
+ }
985
+ get $implicit() {
986
+ return this.internalDirectiveInstance.cuiLet;
987
+ }
988
+ get cuiLet() {
989
+ return this.internalDirectiveInstance.cuiLet;
990
+ }
991
+ }
992
+
993
+ class CuiLetDirective {
994
+ constructor() {
995
+ inject(ViewContainerRef).createEmbeddedView(inject((TemplateRef)), new CuiLetContext(this));
996
+ }
997
+ static ngTemplateContextGuard(_dir, _ctx) {
998
+ return true;
999
+ }
1000
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiLetDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1001
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CuiLetDirective, isStandalone: true, selector: "[cuiLet]", inputs: { cuiLet: "cuiLet" }, ngImport: i0 }); }
1002
+ }
1003
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiLetDirective, decorators: [{
1004
+ type: Directive,
1005
+ args: [{
1006
+ standalone: true,
1007
+ selector: '[cuiLet]'
1008
+ }]
1009
+ }], ctorParameters: function () { return []; }, propDecorators: { cuiLet: [{
1010
+ type: Input
1011
+ }] } });
1012
+
1013
+ class CuiTargetDirective {
1014
+ constructor() {
1015
+ this.clickListener = (event) => {
1016
+ this.clicked.emit(event);
1017
+ };
1018
+ this.clicked = new EventEmitter();
1019
+ }
1020
+ ngOnInit() {
1021
+ this.initClickListener();
1022
+ }
1023
+ ngOnDestroy() {
1024
+ this.destroyClickListener();
1025
+ }
1026
+ initClickListener() {
1027
+ this.ccTarget.addEventListener('click', this.clickListener);
1028
+ }
1029
+ destroyClickListener() {
1030
+ this.ccTarget.removeEventListener('click', this.clickListener);
1031
+ }
1032
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiTargetDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1033
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CuiTargetDirective, isStandalone: true, selector: "[ccTarget]", inputs: { ccTarget: "ccTarget" }, outputs: { clicked: "clicked" }, ngImport: i0 }); }
1034
+ }
1035
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiTargetDirective, decorators: [{
1036
+ type: Directive,
1037
+ args: [{
1038
+ standalone: true,
1039
+ selector: '[ccTarget]',
1040
+ }]
1041
+ }], propDecorators: { ccTarget: [{
1042
+ type: Input
1043
+ }], clicked: [{
1044
+ type: Output
1045
+ }] } });
1046
+
1047
+ class CuiFilterPipe {
1048
+ transform(items, matcher, ...args) {
1049
+ return items.filter(item => matcher(item, ...args));
1050
+ }
1051
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiFilterPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1052
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: CuiFilterPipe, isStandalone: true, name: "cuiFilter" }); }
1053
+ }
1054
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CuiFilterPipe, decorators: [{
1055
+ type: Pipe,
1056
+ args: [{
1057
+ standalone: true,
1058
+ name: 'cuiFilter'
1059
+ }]
1060
+ }] });
1061
+
1062
+ /**
1063
+ * Generated bundle index. Do not edit.
1064
+ */
1065
+
1066
+ export { CUI_ACTIVE_ELEMENT, CUI_FALSE_HANDLER, CUI_HISTORY, CUI_IOS_REG_EXP, CUI_IS_ANDROID, CUI_IS_CYPRESS, CUI_IS_E2E, CUI_IS_IOS, CUI_IS_MOBILE, CUI_IS_PLAYWRIGHT, CUI_IS_TOUCH, CUI_IS_WEBKIT, CUI_LOCAL_STORAGE, CUI_NAVIGATOR, CUI_PLATFORM, CUI_REMOVED_ELEMENT, CUI_SAFARI_REG_EXP, CUI_SESSION_STORAGE, CUI_TRUE_HANDLER, CUI_USER_AGENT, CUI_WINDOW, CuiActiveZone, CuiAutoResizingDirective, CuiClickOutsideDirective, CuiContentEditableValueAccessorDirective, CuiDestroyService, CuiDimensionsObserverDirective, CuiElementDirective, CuiFilterPipe, CuiFocusTrapDirective, CuiHovered, CuiHoveredService, CuiIdService, CuiItemDirective, CuiLetContext, CuiLetDirective, CuiPopoverService, CuiPureException, CuiTargetDirective, CuiTime, EMPTY_ARRAY, EMPTY_CLIENT_RECT, EMPTY_FUNCTION, EMPTY_QUERY, cuiArrayRemove, cuiBlurNativeFocused, cuiClamp, cuiContainsOrAfter, cuiCreateToken, cuiCreateTokenFromFactory, cuiGetActualTarget, cuiGetClosestFocusable, cuiGetDocumentOrShadowRoot, cuiGetElementObscures, cuiGetNativeFocused, cuiHovered, cuiInjectElement, cuiIsElement, cuiIsHTMLElement, cuiIsInput, cuiIsIos, cuiIsNativeKeyboardFocusable, cuiIsNativeMouseFocusable, cuiIsPresent, cuiIsTextNode, cuiIsTextarea, cuiIsTextfield, cuiProvide, cuiPure, cuiPx, svgNodeFilter };
1067
+ //# sourceMappingURL=cuby-ui-cdk.mjs.map