@siemens/element-ng 47.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +27 -0
  3. package/application-header/index.d.ts +17 -0
  4. package/application-header/launchpad/si-launchpad-app.component.d.ts +21 -0
  5. package/application-header/launchpad/si-launchpad-factory.component.d.ts +83 -0
  6. package/application-header/launchpad/si-launchpad.model.d.ts +33 -0
  7. package/application-header/package.json +3 -0
  8. package/application-header/si-application-header.component.d.ts +60 -0
  9. package/application-header/si-header-account-item.component.d.ts +13 -0
  10. package/application-header/si-header-action-item-icon-base.directive.d.ts +26 -0
  11. package/application-header/si-header-action-item.base.d.ts +19 -0
  12. package/application-header/si-header-action-item.component.d.ts +9 -0
  13. package/application-header/si-header-actions.directive.d.ts +5 -0
  14. package/application-header/si-header-brand.directive.d.ts +5 -0
  15. package/application-header/si-header-collapsible-actions.component.d.ts +33 -0
  16. package/application-header/si-header-logo.directive.d.ts +6 -0
  17. package/application-header/si-header-navigation-item.component.d.ts +10 -0
  18. package/application-header/si-header-navigation.component.d.ts +11 -0
  19. package/application-header/si-header-selection-item.component.d.ts +12 -0
  20. package/application-header/si-header-siemens-logo.component.d.ts +20 -0
  21. package/avatar/index.d.ts +6 -0
  22. package/avatar/package.json +3 -0
  23. package/avatar/si-avatar-background-color.directive.d.ts +35 -0
  24. package/avatar/si-avatar.component.d.ts +50 -0
  25. package/common/decorators/index.d.ts +5 -0
  26. package/common/decorators/webcomponent.decorator.d.ts +6 -0
  27. package/common/helpers/animation.helpers.d.ts +10 -0
  28. package/common/helpers/global-events.helpers.d.ts +5 -0
  29. package/common/helpers/index.d.ts +10 -0
  30. package/common/helpers/overlay-helper.d.ts +24 -0
  31. package/common/helpers/positioning.helpers.d.ts +58 -0
  32. package/common/helpers/rtl.d.ts +6 -0
  33. package/common/helpers/track-by.helper.d.ts +27 -0
  34. package/common/index.d.ts +8 -0
  35. package/common/models/color-variant.model.d.ts +8 -0
  36. package/common/models/index.d.ts +8 -0
  37. package/common/models/menu.model.d.ts +85 -0
  38. package/common/models/positions.model.d.ts +18 -0
  39. package/common/models/status-type.model.d.ts +19 -0
  40. package/common/package.json +3 -0
  41. package/common/services/blink.service.d.ts +41 -0
  42. package/common/services/index.d.ts +8 -0
  43. package/common/services/scrollbar-helper.service.d.ts +17 -0
  44. package/common/services/si-uistate.service.d.ts +61 -0
  45. package/common/services/text-measure.service.d.ts +21 -0
  46. package/element-ng.scss +14 -0
  47. package/fesm2022/siemens-element-ng-application-header.mjs +747 -0
  48. package/fesm2022/siemens-element-ng-application-header.mjs.map +1 -0
  49. package/fesm2022/siemens-element-ng-avatar.mjs +185 -0
  50. package/fesm2022/siemens-element-ng-avatar.mjs.map +1 -0
  51. package/fesm2022/siemens-element-ng-common.mjs +946 -0
  52. package/fesm2022/siemens-element-ng-common.mjs.map +1 -0
  53. package/fesm2022/siemens-element-ng-header-dropdown.mjs +384 -0
  54. package/fesm2022/siemens-element-ng-header-dropdown.mjs.map +1 -0
  55. package/fesm2022/siemens-element-ng-icon.mjs +236 -0
  56. package/fesm2022/siemens-element-ng-icon.mjs.map +1 -0
  57. package/fesm2022/siemens-element-ng-link.mjs +233 -0
  58. package/fesm2022/siemens-element-ng-link.mjs.map +1 -0
  59. package/fesm2022/siemens-element-ng-resize-observer.mjs +332 -0
  60. package/fesm2022/siemens-element-ng-resize-observer.mjs.map +1 -0
  61. package/fesm2022/siemens-element-ng-theme.mjs +770 -0
  62. package/fesm2022/siemens-element-ng-theme.mjs.map +1 -0
  63. package/fesm2022/siemens-element-ng-translate.mjs +22 -0
  64. package/fesm2022/siemens-element-ng-translate.mjs.map +1 -0
  65. package/fesm2022/siemens-element-ng.mjs +12 -0
  66. package/fesm2022/siemens-element-ng.mjs.map +1 -0
  67. package/header-dropdown/index.d.ts +9 -0
  68. package/header-dropdown/package.json +3 -0
  69. package/header-dropdown/si-header-dropdown-item.component.d.ts +23 -0
  70. package/header-dropdown/si-header-dropdown-items-factory.component.d.ts +14 -0
  71. package/header-dropdown/si-header-dropdown-trigger.directive.d.ts +57 -0
  72. package/header-dropdown/si-header-dropdown.component.d.ts +20 -0
  73. package/header-dropdown/si-header.model.d.ts +37 -0
  74. package/icon/element-icons.d.ts +12 -0
  75. package/icon/index.d.ts +9 -0
  76. package/icon/package.json +3 -0
  77. package/icon/si-icon-next.component.d.ts +68 -0
  78. package/icon/si-icon.component.d.ts +23 -0
  79. package/icon/si-icon.module.d.ts +7 -0
  80. package/icon/si-icons.d.ts +31 -0
  81. package/index.d.ts +5 -0
  82. package/link/aria-current.model.d.ts +5 -0
  83. package/link/index.d.ts +8 -0
  84. package/link/link.model.d.ts +57 -0
  85. package/link/package.json +3 -0
  86. package/link/si-link-action.service.d.ts +17 -0
  87. package/link/si-link.directive.d.ts +42 -0
  88. package/link/si-link.module.d.ts +7 -0
  89. package/package.json +86 -0
  90. package/public-api.d.ts +5 -0
  91. package/resize-observer/index.d.ts +8 -0
  92. package/resize-observer/package.json +3 -0
  93. package/resize-observer/resize-observer.service.d.ts +41 -0
  94. package/resize-observer/si-resize-observer.directive.d.ts +29 -0
  95. package/resize-observer/si-resize-observer.module.d.ts +8 -0
  96. package/resize-observer/si-responsive-container.directive.d.ts +73 -0
  97. package/theme/index.d.ts +7 -0
  98. package/theme/package.json +3 -0
  99. package/theme/si-theme-store.d.ts +82 -0
  100. package/theme/si-theme.model.d.ts +48 -0
  101. package/theme/si-theme.service.d.ts +129 -0
  102. package/translate/index.d.ts +7 -0
  103. package/translate/package.json +3 -0
  104. package/translate/si-translatable-keys.interface.d.ts +11 -0
  105. package/translate/si-translatable-overrides.provider.d.ts +7 -0
@@ -0,0 +1,946 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Injectable, InjectionToken, inject, PLATFORM_ID } from '@angular/core';
3
+ import { BehaviorSubject, timer } from 'rxjs';
4
+ import { filter, map, distinctUntilChanged, takeUntil, endWith, repeat, share } from 'rxjs/operators';
5
+ import { isPlatformBrowser, DOCUMENT } from '@angular/common';
6
+ import { OverlayConfig } from '@angular/cdk/overlay';
7
+
8
+ /**
9
+ * Copyright Siemens 2016 - 2025.
10
+ * SPDX-License-Identifier: MIT
11
+ */
12
+ /**
13
+ * A global blink pulse generator for synchronized blinking patterns across an entire application.
14
+ * Use to trigger any blinking by subscribing to `pulse$`.
15
+ */
16
+ class BlinkService {
17
+ pause$ = new BehaviorSubject(false);
18
+ off$ = this.pause$.pipe(filter(v => v));
19
+ on$ = this.pause$.pipe(filter(v => !v));
20
+ /**
21
+ * Blink pulse. Subscribe to it to toggle `on` CSS class when true, `off` CSS class when `false`.
22
+ * Do animations using CSS transitions
23
+ *
24
+ * @defaultValue
25
+ * ```
26
+ * timer(0, 1400).pipe(
27
+ * map(count => count % 2 === 0),
28
+ * distinctUntilChanged(),
29
+ * takeUntil(this.off$),
30
+ * endWith(false),
31
+ * repeat({ delay: () => this.on$ }),
32
+ * share()
33
+ * )
34
+ * ```
35
+ */
36
+ pulse$ = timer(0, 1400).pipe(map(count => count % 2 === 0), distinctUntilChanged(), takeUntil(this.off$), endWith(false), repeat({ delay: () => this.on$ }), share());
37
+ /**
38
+ * Pause the blinking.
39
+ */
40
+ pause() {
41
+ this.pause$.next(true);
42
+ }
43
+ /**
44
+ * Resume the blinking.
45
+ */
46
+ resume() {
47
+ this.pause$.next(false);
48
+ }
49
+ /**
50
+ * Whether the blinking is paused or not.
51
+ */
52
+ isPaused() {
53
+ return this.pause$.value;
54
+ }
55
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BlinkService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
56
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BlinkService, providedIn: 'root' });
57
+ }
58
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BlinkService, decorators: [{
59
+ type: Injectable,
60
+ args: [{ providedIn: 'root' }]
61
+ }] });
62
+
63
+ /**
64
+ * Copyright Siemens 2016 - 2025.
65
+ * SPDX-License-Identifier: MIT
66
+ */
67
+ const SI_UI_STATE_STORAGE = new InjectionToken('si.ui-state.storage', {
68
+ providedIn: 'root',
69
+ factory: () => {
70
+ if (isPlatformBrowser(inject(PLATFORM_ID))) {
71
+ return new LocalStorageUIStateStorage();
72
+ }
73
+ return { save: () => { }, load: () => null };
74
+ }
75
+ });
76
+ class LocalStorageUIStateStorage {
77
+ save(stateId, data) {
78
+ localStorage.setItem(`si.ui-state.${stateId}`, data);
79
+ }
80
+ load(stateId) {
81
+ return localStorage.getItem(`si.ui-state.${stateId}`);
82
+ }
83
+ }
84
+ /** @internal */
85
+ const SI_UI_STATE_SERVICE = new InjectionToken('si.ui-state.service');
86
+ /**
87
+ * Service to save and load UI states.
88
+ * @internal
89
+ */
90
+ class SiUIStateService {
91
+ storage = inject(SI_UI_STATE_STORAGE);
92
+ /**
93
+ * Saves the provided state in the storage.
94
+ * @param stateId - The unique id or key under which the state shall be saved.
95
+ * @param state - The state to be saved.
96
+ * @param version - The version of the state object.
97
+ * This can be used to migrate state objects.
98
+ */
99
+ save(stateId, state, version = 0) {
100
+ return (this.storage.save(stateId, JSON.stringify({
101
+ version,
102
+ state
103
+ })) ?? Promise.resolve());
104
+ }
105
+ /**
106
+ * Loads and returns the state for the given stateId and version.
107
+ * @param stateId - The unique id or key for which the state shall be loaded.
108
+ * @param version - The version of the state object.
109
+ * This can be used to migrate state objects.
110
+ * @returns A Promise containing the state or undefined if the state does not exist or the version did not match.
111
+ */
112
+ load(stateId, version = 0) {
113
+ // DO NOT ADD async keyword.
114
+ // This method should stay synchronous if the storage is synchronous.
115
+ // Otherwise, the navbar will play expand animations on load.
116
+ const dataOrPromise = this.storage.load(stateId);
117
+ if (dataOrPromise instanceof Promise) {
118
+ return dataOrPromise.then(data => this.readData(data, version));
119
+ }
120
+ else {
121
+ const promiseLike = {
122
+ then: onfulfilled => {
123
+ const data = this.readData(dataOrPromise, version);
124
+ if (onfulfilled) {
125
+ return onfulfilled(data);
126
+ }
127
+ else {
128
+ return promiseLike;
129
+ }
130
+ }
131
+ };
132
+ return promiseLike;
133
+ }
134
+ }
135
+ readData(data, version) {
136
+ if (data) {
137
+ const parsed = JSON.parse(data);
138
+ if (parsed.version === version) {
139
+ return parsed.state;
140
+ }
141
+ }
142
+ return undefined;
143
+ }
144
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiUIStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
145
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiUIStateService });
146
+ }
147
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiUIStateService, decorators: [{
148
+ type: Injectable
149
+ }] });
150
+ /** Enables the automatic storage of UI state for enabled components. */
151
+ const provideSiUiState = (config) => {
152
+ return [
153
+ { provide: SI_UI_STATE_SERVICE, useClass: SiUIStateService },
154
+ config?.store ? { provide: SI_UI_STATE_STORAGE, useClass: config.store } : []
155
+ ];
156
+ };
157
+
158
+ /**
159
+ * Copyright Siemens 2016 - 2025.
160
+ * SPDX-License-Identifier: MIT
161
+ */
162
+ class TextMeasureService {
163
+ measureCanvas;
164
+ defaultFont;
165
+ document = inject(DOCUMENT);
166
+ /** Measure text width in pixel. */
167
+ measureText(text, fontRef, overrides) {
168
+ this.ensureCanvas();
169
+ this.setFontStyle(fontRef, overrides);
170
+ return Math.ceil(this.measureCanvas.measureText(text).width);
171
+ }
172
+ /** Get font styles for `font` CSS short-hand property. */
173
+ getFontStyle(element, overrides) {
174
+ const style = getComputedStyle(element);
175
+ // note: can't use destructuring on `style` as it doesn't work on Firefox
176
+ const fontStyle = overrides?.fontStyle ?? style.fontStyle;
177
+ const fontVariant = overrides?.fontVariant ?? style.fontVariant;
178
+ const fontWeight = overrides?.fontWeight ?? style.fontWeight;
179
+ const fontSize = overrides?.fontSize ?? style.fontSize;
180
+ const fontFamily = overrides?.fontFamily ?? style.fontFamily;
181
+ return `${fontStyle} ${fontVariant} ${fontWeight} ${fontSize} ${fontFamily}`
182
+ .replace(/ +/g, ' ')
183
+ .trim();
184
+ }
185
+ ensureCanvas() {
186
+ if (this.measureCanvas) {
187
+ return;
188
+ }
189
+ const canvas = this.document.createElement('canvas');
190
+ this.measureCanvas = canvas.getContext('2d');
191
+ }
192
+ setFontStyle(fontRef, overrides) {
193
+ if (typeof fontRef === 'string') {
194
+ this.measureCanvas.font = fontRef;
195
+ return;
196
+ }
197
+ if (fontRef || overrides) {
198
+ this.measureCanvas.font = this.getFontStyle(fontRef ?? this.document.body, overrides);
199
+ return;
200
+ }
201
+ this.defaultFont ??= this.getFontStyle(this.document.body);
202
+ this.measureCanvas.font = this.defaultFont;
203
+ }
204
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TextMeasureService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
205
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TextMeasureService, providedIn: 'root' });
206
+ }
207
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TextMeasureService, decorators: [{
208
+ type: Injectable,
209
+ args: [{
210
+ providedIn: 'root'
211
+ }]
212
+ }] });
213
+
214
+ /**
215
+ * Copyright Siemens 2016 - 2025.
216
+ * SPDX-License-Identifier: MIT
217
+ */
218
+ /**
219
+ * Gets the width of the scrollbar. Nesc for windows
220
+ * http://stackoverflow.com/a/13382873/888165
221
+ */
222
+ class ScrollbarHelper {
223
+ document = inject(DOCUMENT);
224
+ /**
225
+ * The width of the scrollbar.
226
+ *
227
+ * @defaultValue this.getWidth()
228
+ */
229
+ width = this.getWidth();
230
+ getWidth() {
231
+ const outer = this.document.createElement('div');
232
+ outer.style.visibility = 'hidden';
233
+ outer.style.width = '100px';
234
+ outer.style.msOverflowStyle = 'scrollbar';
235
+ this.document.body.appendChild(outer);
236
+ const widthNoScroll = outer.offsetWidth;
237
+ outer.style.overflow = 'scroll';
238
+ const inner = this.document.createElement('div');
239
+ inner.style.width = '100%';
240
+ outer.appendChild(inner);
241
+ const widthWithScroll = inner.offsetWidth;
242
+ outer.parentNode?.removeChild(outer);
243
+ return widthNoScroll - widthWithScroll;
244
+ }
245
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: ScrollbarHelper, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
246
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: ScrollbarHelper, providedIn: 'root' });
247
+ }
248
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: ScrollbarHelper, decorators: [{
249
+ type: Injectable,
250
+ args: [{ providedIn: 'root' }]
251
+ }] });
252
+
253
+ /**
254
+ * Copyright Siemens 2016 - 2025.
255
+ * SPDX-License-Identifier: MIT
256
+ */
257
+
258
+ const STATUS_ICON = {
259
+ success: {
260
+ icon: 'element-circle-filled',
261
+ color: 'status-success',
262
+ stacked: 'element-state-tick smooth-auto',
263
+ stackedColor: 'status-success-contrast',
264
+ background: 'bg-base-success',
265
+ severity: 5
266
+ },
267
+ info: {
268
+ icon: 'element-square-filled',
269
+ color: 'status-info',
270
+ stacked: 'element-state-info smooth-auto',
271
+ stackedColor: 'status-info-contrast',
272
+ background: 'bg-base-info',
273
+ severity: 4
274
+ },
275
+ caution: {
276
+ icon: 'element-square-45-filled',
277
+ color: 'status-caution',
278
+ stacked: 'element-state-exclamation-mark smooth-auto',
279
+ stackedColor: 'status-caution-contrast',
280
+ background: 'bg-base-caution',
281
+ severity: 3
282
+ },
283
+ warning: {
284
+ icon: 'element-triangle-filled',
285
+ color: 'status-warning',
286
+ stacked: 'element-state-exclamation-mark smooth-auto',
287
+ stackedColor: 'status-warning-contrast',
288
+ background: 'bg-base-warning',
289
+ severity: 2
290
+ },
291
+ danger: {
292
+ icon: 'element-circle-filled',
293
+ color: 'status-danger',
294
+ stacked: 'element-state-exclamation-mark smooth-auto',
295
+ stackedColor: 'status-danger-contrast',
296
+ background: 'bg-base-danger',
297
+ severity: 1
298
+ },
299
+ critical: {
300
+ icon: 'element-octagon-filled',
301
+ color: 'status-critical',
302
+ stacked: 'element-state-exclamation-mark smooth-auto',
303
+ stackedColor: 'status-critical-contrast',
304
+ background: 'bg-base-danger',
305
+ severity: 0
306
+ },
307
+ progress: {
308
+ icon: 'element-circle-filled',
309
+ color: 'status-info',
310
+ stacked: 'element-state-progress smooth-auto',
311
+ stackedColor: 'status-info-contrast',
312
+ background: 'bg-base-info',
313
+ severity: 7
314
+ },
315
+ pending: {
316
+ icon: 'element-circle-filled',
317
+ color: 'status-caution',
318
+ stacked: 'element-state-pause smooth-auto',
319
+ stackedColor: 'status-caution-contrast',
320
+ background: 'bg-base-caution',
321
+ severity: 6
322
+ },
323
+ unknown: {
324
+ icon: 'element-circle-filled',
325
+ color: 'status-neutral',
326
+ stacked: 'element-state-question-mark',
327
+ stackedColor: 'text-body',
328
+ background: 'bg-base-0',
329
+ severity: 8
330
+ }
331
+ };
332
+
333
+ const positionStart = {
334
+ overlayX: 'end',
335
+ overlayY: 'center',
336
+ originX: 'start',
337
+ originY: 'center'
338
+ };
339
+ const positionEnd = {
340
+ overlayX: 'start',
341
+ overlayY: 'center',
342
+ originX: 'end',
343
+ originY: 'center'
344
+ };
345
+ const positionTopCenter = {
346
+ overlayX: 'center',
347
+ overlayY: 'bottom',
348
+ originX: 'center',
349
+ originY: 'top'
350
+ };
351
+ const positionTopStart = {
352
+ overlayX: 'start',
353
+ overlayY: 'bottom',
354
+ originX: 'center',
355
+ originY: 'top'
356
+ };
357
+ const positionTopEnd = {
358
+ overlayX: 'end',
359
+ overlayY: 'bottom',
360
+ originX: 'center',
361
+ originY: 'top'
362
+ };
363
+ const positionBottomCenter = {
364
+ overlayX: 'center',
365
+ overlayY: 'top',
366
+ originX: 'center',
367
+ originY: 'bottom'
368
+ };
369
+ const positionBottomStart = {
370
+ overlayX: 'start',
371
+ overlayY: 'top',
372
+ originX: 'center',
373
+ originY: 'bottom'
374
+ };
375
+ const positionBottomEnd = {
376
+ overlayX: 'end',
377
+ overlayY: 'top',
378
+ originX: 'center',
379
+ originY: 'bottom'
380
+ };
381
+ const positions = {
382
+ top: [
383
+ positionTopCenter,
384
+ positionTopStart,
385
+ positionTopEnd,
386
+ positionBottomCenter,
387
+ positionBottomStart,
388
+ positionBottomEnd,
389
+ positionStart,
390
+ positionEnd
391
+ ],
392
+ end: [
393
+ positionEnd,
394
+ positionTopCenter,
395
+ positionTopStart,
396
+ positionTopEnd,
397
+ positionBottomCenter,
398
+ positionBottomStart,
399
+ positionBottomEnd,
400
+ positionStart
401
+ ],
402
+ bottom: [
403
+ positionBottomCenter,
404
+ positionBottomStart,
405
+ positionBottomEnd,
406
+ positionTopCenter,
407
+ positionTopStart,
408
+ positionTopEnd,
409
+ positionStart,
410
+ positionEnd
411
+ ],
412
+ start: [
413
+ positionStart,
414
+ positionTopCenter,
415
+ positionTopStart,
416
+ positionTopEnd,
417
+ positionBottomCenter,
418
+ positionBottomStart,
419
+ positionBottomEnd,
420
+ positionEnd
421
+ ],
422
+ auto: [
423
+ positionTopCenter,
424
+ positionTopStart,
425
+ positionTopEnd,
426
+ positionBottomCenter,
427
+ positionBottomStart,
428
+ positionBottomEnd,
429
+ positionStart,
430
+ positionEnd
431
+ ]
432
+ };
433
+
434
+ /**
435
+ * Copyright Siemens 2016 - 2025.
436
+ * SPDX-License-Identifier: MIT
437
+ */
438
+
439
+ /**
440
+ * Copyright Siemens 2016 - 2025.
441
+ * SPDX-License-Identifier: MIT
442
+ */
443
+ /**
444
+ * @returns Returns whether animations are disabled via the CSS var. This is either set by
445
+ * an application on low-end devices or in case the device is configured for reduced motion
446
+ * (i.e. `@media (prefers-reduced-motion)` matches)
447
+ */
448
+ const areAnimationsDisabled = () => {
449
+ const style = getComputedStyle(document.documentElement);
450
+ const flag = style.getPropertyValue('--element-animations-enabled');
451
+ return parseInt(flag, 10) === 0;
452
+ };
453
+
454
+ /**
455
+ * Copyright Siemens 2016 - 2025.
456
+ * SPDX-License-Identifier: MIT
457
+ */
458
+ const isRTL = (elem) => getComputedStyle(elem ?? document.documentElement).direction === 'rtl';
459
+ const correctKeyRTL = (key) => {
460
+ if (!isRTL()) {
461
+ return key;
462
+ }
463
+ return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;
464
+ };
465
+
466
+ /**
467
+ * Copyright Siemens 2016 - 2025.
468
+ * SPDX-License-Identifier: MIT
469
+ */
470
+ const AXIS_X = {
471
+ axis: 'X',
472
+ directionRegular: 'end',
473
+ directionReverse: 'start',
474
+ upperBound: 'left',
475
+ lowerBound: 'right',
476
+ size: 'width',
477
+ windowSize: 'innerWidth'
478
+ };
479
+ const AXIS_Y = {
480
+ axis: 'Y',
481
+ directionRegular: 'down',
482
+ directionReverse: 'up',
483
+ upperBound: 'top',
484
+ lowerBound: 'bottom',
485
+ size: 'height',
486
+ windowSize: 'innerHeight'
487
+ };
488
+ const BOUNDING_RECT_WINDOW = {
489
+ getBoundingClientRect: () => ({
490
+ top: 0,
491
+ left: 0,
492
+ bottom: window.innerHeight,
493
+ right: window.innerWidth
494
+ })
495
+ };
496
+ const resolveReference = (hostElement, reference) => {
497
+ if (reference) {
498
+ const childReferenceCheck = hostElement.querySelector(reference);
499
+ if (childReferenceCheck) {
500
+ return childReferenceCheck;
501
+ }
502
+ const referenceCheck = hostElement.closest(reference);
503
+ if (referenceCheck) {
504
+ return referenceCheck;
505
+ }
506
+ const all = document.querySelectorAll(reference);
507
+ return all[all.length - 1] ?? null;
508
+ }
509
+ return null;
510
+ };
511
+ const getScrollParentsChain = (element, axis, scrollParentsList = []) => {
512
+ if (element) {
513
+ const overflowStyle = getComputedStyle(element)[axis === 'X' ? 'overflowX' : 'overflowY'] || 'visible';
514
+ if (element[axis === 'X' ? 'clientWidth' : 'clientHeight'] &&
515
+ overflowStyle !== 'visible' &&
516
+ overflowStyle !== 'hidden') {
517
+ scrollParentsList.push(document.documentElement === element ? BOUNDING_RECT_WINDOW : element);
518
+ }
519
+ if (element !== document.documentElement) {
520
+ getScrollParentsChain(element.dropdownParentElement ?? element.parentElement ?? document.body, axis, scrollParentsList);
521
+ }
522
+ }
523
+ return scrollParentsList;
524
+ };
525
+ const getCombinedBoundingClientRect = (elements) => {
526
+ let top = 0;
527
+ let bottom = 0;
528
+ let left = 0;
529
+ let right = 0;
530
+ if (elements.length > 0) {
531
+ const tops = [];
532
+ const bottoms = [];
533
+ const lefts = [];
534
+ const rights = [];
535
+ elements.forEach(element => {
536
+ const rect = element.getBoundingClientRect();
537
+ tops.push(rect.top);
538
+ bottoms.push(rect.bottom);
539
+ lefts.push(rect.left);
540
+ rights.push(rect.right);
541
+ });
542
+ top = Math.min(...tops);
543
+ bottom = Math.max(...bottoms);
544
+ left = Math.min(...lefts);
545
+ right = Math.max(...rights);
546
+ }
547
+ return { top, bottom, left, right };
548
+ };
549
+ const calculatePlacementRefOuterBounds = (currentAxis, placementReferenceElement) => {
550
+ // The chain of scroll parents of the placement ref element up to and often including the body, checking for possible overlaps.
551
+ const placementRefScrollParents = getScrollParentsChain(placementReferenceElement, currentAxis.axis);
552
+ const placementRefScrollParentRects = placementRefScrollParents.map(item => item.getBoundingClientRect());
553
+ // The biggest upper bound (top, left) of all scroll parents (and viewport = 0), the point before which content will be cut off.
554
+ const placementRefScrollParentsUpperBound = Math.max(0, ...placementRefScrollParentRects.map(item => item[currentAxis.upperBound]));
555
+ // The smallest lower bound (bottom, right) of all scroll parents (and viewport), the point after which content will be cut off.
556
+ const placementRefScrollParentsLowerBound = Math.min(window[currentAxis.windowSize], ...placementRefScrollParentRects.map(item => item[currentAxis.lowerBound]));
557
+ return { upper: placementRefScrollParentsUpperBound, lower: placementRefScrollParentsLowerBound };
558
+ };
559
+ const calculateDirectionFromPlacementRef = (params) => {
560
+ const { currentAxis, positionRegular, positionReverse, contentSize, placementRefBounds, currentDirection, rtl } = params;
561
+ // A number showing how many visible pixels would be available from the placement ref in regular / scroll (down, end) direction
562
+ const placementRefSpaceRegular = placementRefBounds.lower - positionRegular[currentAxis.upperBound];
563
+ // A number showing how many visible pixels would be available from the placement ref in reverse (up, start) direction
564
+ const placementRefSpaceReverse = positionReverse[currentAxis.upperBound] - placementRefBounds.upper;
565
+ if (placementRefSpaceReverse < contentSize && placementRefSpaceRegular < contentSize) {
566
+ // If there would not be enough room in both directions, always prefer regular / scroll (down, end) direction,
567
+ // since this way the element can expand and scroll while this cannot happen if there's not enough room in front.
568
+ return rtl ? currentAxis.directionReverse : currentAxis.directionRegular;
569
+ }
570
+ else if (placementRefSpaceReverse < contentSize) {
571
+ return currentAxis.directionRegular;
572
+ }
573
+ else if (placementRefSpaceRegular < contentSize) {
574
+ return currentAxis.directionReverse;
575
+ }
576
+ // If there would be enough room in both directions, use the set direction (or the regular one if not set).
577
+ return currentDirection;
578
+ };
579
+ const getAbsoluteContentPosition = (params) => {
580
+ const { direction, placement, element, align, rtl } = params;
581
+ const elementRect = element.getBoundingClientRect();
582
+ const start = rtl ? elementRect.right : elementRect.left;
583
+ const end = rtl ? elementRect.left : elementRect.right;
584
+ let relativeLeftOffset = 0;
585
+ if (direction === 'start' || direction === 'end') {
586
+ relativeLeftOffset =
587
+ placement.includes('end') || (!placement.includes('start') && direction === 'end')
588
+ ? end
589
+ : start;
590
+ }
591
+ else {
592
+ if (placement.includes('start')) {
593
+ relativeLeftOffset = start;
594
+ }
595
+ else {
596
+ if (placement.includes('end') || align === 'end') {
597
+ relativeLeftOffset = end;
598
+ }
599
+ else if (align === 'center') {
600
+ relativeLeftOffset = elementRect.left + (elementRect.right - elementRect.left) / 2;
601
+ }
602
+ else {
603
+ relativeLeftOffset = start;
604
+ }
605
+ }
606
+ }
607
+ let relativeTopOffset = 0;
608
+ if (direction === 'up') {
609
+ relativeTopOffset = placement.includes('bottom') ? elementRect.bottom : elementRect.top;
610
+ }
611
+ else if (direction === 'start' || direction === 'end') {
612
+ relativeTopOffset = !placement.includes('bottom') ? elementRect.top : elementRect.bottom;
613
+ }
614
+ else {
615
+ relativeTopOffset = placement.includes('top') ? elementRect.top : elementRect.bottom;
616
+ }
617
+ return { left: relativeLeftOffset, top: relativeTopOffset };
618
+ };
619
+ const getRelativeContentPosition = (params) => {
620
+ const { contentElement, direction, placement, placementReferenceElement, align, rtl } = params;
621
+ const contentParent = contentElement.offsetParent ?? document.body;
622
+ const contentParentRect = contentParent.getBoundingClientRect();
623
+ const relativePosition = getAbsoluteContentPosition({
624
+ direction,
625
+ placement,
626
+ element: placementReferenceElement,
627
+ align,
628
+ rtl
629
+ });
630
+ const leftOffset = relativePosition.left - contentParentRect.left + contentParent.scrollLeft;
631
+ const topOffset = relativePosition.top - contentParentRect.top + contentParent.scrollTop;
632
+ return { left: leftOffset, top: topOffset };
633
+ };
634
+ const getContentPositionString = (params) => {
635
+ const { contentElement, direction, placement, placementReferenceElement, align, rtl } = params;
636
+ const position = getRelativeContentPosition({
637
+ contentElement,
638
+ direction,
639
+ placement,
640
+ placementReferenceElement,
641
+ align,
642
+ rtl: rtl ?? isRTL()
643
+ });
644
+ return `translate3d(${position.left}px, ${position.top}px, 0px)`;
645
+ };
646
+ const responsivelyCheckDirection = (params) => {
647
+ const { isScrolling, currentDirection, contentElements, hostElement, placement, placementReferenceElement, align, responsiveDirectionToPlacement, closeOnPlacementReferenceScrollOut, closeOnContentScrollOut, minSpaceThresholdFactor, placementReverse, rtl } = params;
648
+ const actualRtl = rtl ?? isRTL();
649
+ let responsiveDirection;
650
+ const actualCurrentDirection = actualRtl
651
+ ? currentDirection === 'start'
652
+ ? 'end'
653
+ : currentDirection === 'end'
654
+ ? 'start'
655
+ : currentDirection
656
+ : currentDirection;
657
+ // Defines how the properties to access are named in the current axis.
658
+ const currentAxis = currentDirection === 'start' || currentDirection === 'end' ? AXIS_X : AXIS_Y;
659
+ // The combined (enclosing) client rect for all component contents.
660
+ const contentsRect = getCombinedBoundingClientRect(contentElements);
661
+ // The chain of scroll parents of the container host element up to and often including the body, checking for possible overlaps.
662
+ const containerScrollParents = getScrollParentsChain(hostElement, currentAxis.axis);
663
+ const containerScrollParentRects = containerScrollParents.map(item => item.getBoundingClientRect());
664
+ // The biggest upper bound (top, left) of all scroll parents (and viewport = 0), the point before which content will be cut off.
665
+ const scrollParentsUpperBound = Math.max(0, ...containerScrollParentRects.map(item => item[currentAxis.upperBound]));
666
+ // The smallest lower bound (bottom, right) of all scroll parents (and viewport), the point after which content will be cut off.
667
+ const scrollParentsLowerBound = Math.min(window[currentAxis.windowSize], ...containerScrollParentRects.map(item => item[currentAxis.lowerBound]));
668
+ // The point from which the component will be opened if opening in regular / scroll (down, end) direction.
669
+ // Influenced by `componentPlacementReference`, `componentPlacement` and `componentAlign`.
670
+ const positionRegular = getAbsoluteContentPosition({
671
+ direction: currentAxis.directionRegular,
672
+ placement,
673
+ element: placementReferenceElement,
674
+ align
675
+ });
676
+ // The point from which the component will be opened if opening in reverse (up, start) direction.
677
+ // Influenced by `componentPlacementReference`, `componentPlacement` and `componentAlign`.
678
+ const positionReverse = getAbsoluteContentPosition({
679
+ direction: currentAxis.directionReverse,
680
+ placement: placementReverse ?? placement,
681
+ element: placementReferenceElement,
682
+ align
683
+ });
684
+ // The enclosing size (height, width) of all contents combined
685
+ const contentsSize = contentsRect[currentAxis.lowerBound] - contentsRect[currentAxis.upperBound];
686
+ // A number showing how many visible pixels would be available in regular / scroll (down, end) direction
687
+ const spaceRegular = scrollParentsLowerBound - positionRegular[currentAxis.upperBound];
688
+ // A number showing how many visible pixels would be available in reverse (up, start) direction
689
+ const spaceReverse = positionReverse[currentAxis.upperBound] - scrollParentsUpperBound;
690
+ let placementRefBounds;
691
+ if (spaceReverse < contentsSize && spaceRegular < contentsSize) {
692
+ // If there would not be enough room in both directions, always prefer regular / scroll (down, end) direction,
693
+ // since this way the element can expand and scroll while this cannot happen if there's not enough room in front.
694
+ responsiveDirection = actualRtl ? currentAxis.directionReverse : currentAxis.directionRegular;
695
+ }
696
+ else if (minSpaceThresholdFactor) {
697
+ const contentsSizeWithThreshold = contentsSize + minSpaceThresholdFactor * contentsSize;
698
+ if (spaceReverse < contentsSizeWithThreshold && spaceRegular < contentsSizeWithThreshold) {
699
+ // If a threshold is set and there would not be enough space including the threshold in both directions
700
+ // use the direction with more space
701
+ if (spaceReverse < spaceRegular) {
702
+ responsiveDirection = currentAxis.directionRegular;
703
+ }
704
+ else {
705
+ responsiveDirection = currentAxis.directionReverse;
706
+ }
707
+ }
708
+ else if (spaceReverse < contentsSizeWithThreshold) {
709
+ responsiveDirection = currentAxis.directionRegular;
710
+ }
711
+ else if (spaceRegular < contentsSizeWithThreshold) {
712
+ responsiveDirection = currentAxis.directionReverse;
713
+ }
714
+ }
715
+ if (!responsiveDirection) {
716
+ if (spaceReverse < contentsSize) {
717
+ responsiveDirection = currentAxis.directionRegular;
718
+ }
719
+ else if (spaceRegular < contentsSize) {
720
+ responsiveDirection = currentAxis.directionReverse;
721
+ }
722
+ else {
723
+ if (responsiveDirectionToPlacement &&
724
+ placementReferenceElement &&
725
+ hostElement !== placementReferenceElement) {
726
+ placementRefBounds = calculatePlacementRefOuterBounds(currentAxis, placementReferenceElement);
727
+ responsiveDirection = calculateDirectionFromPlacementRef({
728
+ currentAxis,
729
+ positionRegular,
730
+ positionReverse,
731
+ contentSize: contentsSize,
732
+ placementRefBounds,
733
+ currentDirection: actualCurrentDirection,
734
+ rtl: actualRtl
735
+ });
736
+ }
737
+ else {
738
+ // If there would be enough room in both directions, use the set direction (or the regular one if not set).
739
+ responsiveDirection = actualCurrentDirection;
740
+ }
741
+ }
742
+ }
743
+ let close = false;
744
+ if (isScrolling) {
745
+ // Check if the container host or placement reference is hidden and close the component. (Mostly done when scrolling.)
746
+ if (closeOnPlacementReferenceScrollOut &&
747
+ placementReferenceElement &&
748
+ hostElement !== placementReferenceElement) {
749
+ placementRefBounds ??= calculatePlacementRefOuterBounds(currentAxis, placementReferenceElement);
750
+ const placementRefRect = placementReferenceElement.getBoundingClientRect();
751
+ // A number showing how many visible pixels of the placement ref would be shown in reverse (up, start) direction
752
+ const placementRefVisibleTop = placementRefRect[currentAxis.lowerBound] - placementRefBounds.upper;
753
+ // A number showing how many visible pixels of the placement ref would be shown in regular / scroll (down, end) direction
754
+ const placementRefVisibleBottom = placementRefBounds.lower - placementRefRect[currentAxis.upperBound];
755
+ if (placementRefVisibleTop < 0 || placementRefVisibleBottom < 0) {
756
+ // Close the component if the placement ref is not visible.
757
+ close = true;
758
+ }
759
+ }
760
+ if (!close && closeOnContentScrollOut) {
761
+ // A number showing how many visible pixels would be available the other way if set to regular / scroll (down, end) direction
762
+ const spaceRegularOtherSide = scrollParentsLowerBound - positionReverse[currentAxis.upperBound];
763
+ // A number showing how many visible pixels would be available the other way if set to reverse (up, start) direction
764
+ const spaceReverseOtherSide = positionRegular[currentAxis.upperBound] - scrollParentsUpperBound;
765
+ if (spaceRegularOtherSide < 0 || spaceReverseOtherSide < 0) {
766
+ // Close the component if there is not enough space even in the other direction.
767
+ close = true;
768
+ }
769
+ }
770
+ }
771
+ responsiveDirection = actualRtl
772
+ ? responsiveDirection === 'start'
773
+ ? 'end'
774
+ : responsiveDirection === 'end'
775
+ ? 'start'
776
+ : responsiveDirection
777
+ : responsiveDirection;
778
+ return { responsiveDirection, close };
779
+ };
780
+
781
+ const trackByIdentity = (index, item) => item;
782
+ /**
783
+ * Creates a trackByFunction for ngFor, that tracks an Item by its identity.
784
+ * It should be used with a generic parameter, to generate a proper type:
785
+ *
786
+ * @example
787
+ * ```ts
788
+ * @Input() trackByFunction = buildTrackByIdentity<ItemType>()
789
+ * ```
790
+ * @deprecated use the new control-flow syntax
791
+ */
792
+ const buildTrackByIdentity = () => trackByIdentity;
793
+ const trackByIndex = (index) => index;
794
+ /**
795
+ * Creates a trackByFunction for ngFor, that tracks an Item by its index.
796
+ * It should be used with a generic parameter, to generate a proper type:
797
+ *
798
+ * @example
799
+ * ```
800
+ * @Input() trackByFunction = buildTrackByIdentity<ItemType>()
801
+ * ```
802
+ * @deprecated use the new control-flow syntax
803
+ */
804
+ const buildTrackByIndex = () => trackByIndex;
805
+
806
+ /**
807
+ * Copyright Siemens 2016 - 2025.
808
+ * SPDX-License-Identifier: MIT
809
+ */
810
+ // Adds a window listener which can optionally be active, returns the unregister function.
811
+ // For some events (e.g. "touchmove") an explicit "passive: false" is required in order to
812
+ // be able to do $event.preventDefault(). Unfortunately there is no way in Angular to pass
813
+ // options to Rendrer2/EventManager event handling.
814
+ const listenGlobal = (eventName, handler, active) => {
815
+ let opts = false;
816
+ if (active !== undefined) {
817
+ opts = { passive: !active };
818
+ }
819
+ window.addEventListener(eventName, handler, opts);
820
+ return () => {
821
+ window.removeEventListener(eventName, handler, opts);
822
+ };
823
+ };
824
+
825
+ /**
826
+ * Copyright Siemens 2016 - 2025.
827
+ * SPDX-License-Identifier: MIT
828
+ */
829
+ /* eslint-disable prefer-arrow/prefer-arrow-functions */
830
+ function makePositionStrategy(elementRef, overlay, placement, constrain = false, center = true) {
831
+ if (!elementRef?.nativeElement) {
832
+ return overlay.position().global().centerHorizontally().centerVertically();
833
+ }
834
+ const popoverPositions = getOverlayPositions(elementRef, placement, center);
835
+ const positionStrategy = overlay
836
+ .position()
837
+ .flexibleConnectedTo(elementRef)
838
+ .withPush(false)
839
+ .withGrowAfterOpen(true)
840
+ .withFlexibleDimensions(constrain)
841
+ .withPositions(popoverPositions);
842
+ if (constrain) {
843
+ positionStrategy.withViewportMargin(8);
844
+ }
845
+ return positionStrategy;
846
+ }
847
+ function makeOverlay(positionStrategy, overlay, hasBackdrop) {
848
+ const config = new OverlayConfig();
849
+ config.positionStrategy = positionStrategy;
850
+ config.scrollStrategy = overlay.scrollStrategies.reposition();
851
+ config.direction = isRTL() ? 'rtl' : 'ltr';
852
+ if (hasBackdrop) {
853
+ config.hasBackdrop = true;
854
+ config.backdropClass = 'cdk-overlay-transparent-backdrop';
855
+ }
856
+ else {
857
+ config.hasBackdrop = false;
858
+ }
859
+ return overlay.create(config);
860
+ }
861
+ function getOverlay(elementRef, overlay, hasBackdrop, placement, constrain = false, center = true) {
862
+ const positionStrategy = makePositionStrategy(elementRef, overlay, placement, constrain, center);
863
+ return makeOverlay(positionStrategy, overlay, hasBackdrop);
864
+ }
865
+ function getPositionStrategy(overlayref) {
866
+ return overlayref.getConfig().positionStrategy;
867
+ }
868
+ function getOverlayPositions(elementRef, placement, center = true) {
869
+ if (elementRef.nativeElement && center) {
870
+ const rtl = isRTL();
871
+ const halfWidth = Math.round(elementRef.nativeElement.offsetWidth / 2);
872
+ positionTopStart.offsetX = positionBottomStart.offsetX = halfWidth * (rtl ? 1 : -1);
873
+ positionTopEnd.offsetX = positionBottomEnd.offsetX = halfWidth * (rtl ? -1 : 1);
874
+ }
875
+ else {
876
+ positionTopStart.offsetX = undefined;
877
+ positionTopEnd.offsetX = undefined;
878
+ positionBottomStart.offsetX = undefined;
879
+ positionBottomEnd.offsetX = undefined;
880
+ }
881
+ return typeof placement === 'string' ? positions[placement] : placement;
882
+ }
883
+ function hasTrigger(trigger, triggers) {
884
+ return (triggers?.split(/\s+/) ?? []).includes(trigger);
885
+ }
886
+ /**
887
+ * calculates the arrow position from left/right for tooltips, popovers, etc
888
+ * @param change - the event from the position strategy
889
+ * @param overlay - ElementRef for the overlay content, i.e. the popover/tooltip component
890
+ * @param anchor - ElementRef for the anchoring element, i.e. the trigger of the popover/tooltip
891
+ */
892
+ function calculateOverlayArrowPosition(change, overlay, anchor) {
893
+ if (anchor && ['bottom', 'top'].includes(change.connectionPair.originY)) {
894
+ // Calculate offset to the anchor element center
895
+ const anchorRect = anchor.nativeElement.getBoundingClientRect();
896
+ const overlayRect = overlay.nativeElement.getBoundingClientRect();
897
+ const center = anchorRect.left + anchorRect.width / 2;
898
+ // Position arrow centered to the anchor element
899
+ // prettier-ignore
900
+ return isRTL()
901
+ ? { right: overlayRect.right - center }
902
+ : { left: center - overlayRect.left };
903
+ }
904
+ const offsetX = change.connectionPair.offsetX;
905
+ if (offsetX) {
906
+ // prettier-ignore
907
+ return offsetX < 0
908
+ ? { left: -offsetX }
909
+ : { right: offsetX };
910
+ }
911
+ return {};
912
+ }
913
+
914
+ /**
915
+ * Copyright Siemens 2016 - 2025.
916
+ * SPDX-License-Identifier: MIT
917
+ */
918
+
919
+ // note: this _must_ be a function, not an arrow
920
+ // eslint-disable-next-line
921
+ function WebComponentContentChildren(host) {
922
+ // holds the Type information of child component and the property name of parent component which is used to hold it.
923
+ return (...args) => {
924
+ args[0].__contentQuery = {
925
+ host,
926
+ prop: args[1]
927
+ };
928
+ };
929
+ }
930
+
931
+ /**
932
+ * Copyright Siemens 2016 - 2025.
933
+ * SPDX-License-Identifier: MIT
934
+ */
935
+
936
+ /**
937
+ * Copyright Siemens 2016 - 2025.
938
+ * SPDX-License-Identifier: MIT
939
+ */
940
+
941
+ /**
942
+ * Generated bundle index. Do not edit.
943
+ */
944
+
945
+ export { AXIS_X, AXIS_Y, BOUNDING_RECT_WINDOW, BlinkService, SI_UI_STATE_SERVICE, STATUS_ICON, ScrollbarHelper, TextMeasureService, WebComponentContentChildren, areAnimationsDisabled, buildTrackByIdentity, buildTrackByIndex, calculateOverlayArrowPosition, correctKeyRTL, getContentPositionString, getOverlay, getOverlayPositions, getPositionStrategy, hasTrigger, isRTL, listenGlobal, makeOverlay, makePositionStrategy, positionBottomCenter, positionBottomEnd, positionBottomStart, positionTopCenter, positionTopEnd, positionTopStart, positions, provideSiUiState, resolveReference, responsivelyCheckDirection };
946
+ //# sourceMappingURL=siemens-element-ng-common.mjs.map