@scion/components 22.5.0 → 22.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_index.scss +32 -88
- package/fesm2022/scion-components-common.mjs +133 -5
- package/fesm2022/scion-components-common.mjs.map +1 -1
- package/fesm2022/scion-components-dimension.mjs +3 -3
- package/fesm2022/scion-components-dimension.mjs.map +1 -1
- package/fesm2022/scion-components-icon.mjs +134 -98
- package/fesm2022/scion-components-icon.mjs.map +1 -1
- package/fesm2022/scion-components-menu.mjs +58 -51
- package/fesm2022/scion-components-menu.mjs.map +1 -1
- package/fesm2022/scion-components-sashbox.mjs +1 -1
- package/fesm2022/scion-components-sashbox.mjs.map +1 -1
- package/fesm2022/scion-components-splitter.mjs +1 -1
- package/fesm2022/scion-components-splitter.mjs.map +1 -1
- package/fesm2022/scion-components-table.mjs +352 -159
- package/fesm2022/scion-components-table.mjs.map +1 -1
- package/fesm2022/scion-components-text.mjs +83 -40
- package/fesm2022/scion-components-text.mjs.map +1 -1
- package/fesm2022/scion-components-throbber.mjs +1 -1
- package/fesm2022/scion-components-throbber.mjs.map +1 -1
- package/fesm2022/scion-components-viewport.mjs +31 -18
- package/fesm2022/scion-components-viewport.mjs.map +1 -1
- package/package.json +2 -2
- package/types/scion-components-common.d.ts +91 -4
- package/types/scion-components-icon.d.ts +42 -15
- package/types/scion-components-menu.d.ts +7 -2
- package/types/scion-components-sashbox.d.ts +1 -1
- package/types/scion-components-splitter.d.ts +1 -1
- package/types/scion-components-table.d.ts +440 -59
- package/types/scion-components-text.d.ts +6 -5
- package/types/scion-components-throbber.d.ts +1 -1
- package/types/scion-components-viewport.d.ts +20 -11
- package/viewport/scrollbar/_scrollbar.scss +12 -0
- package/design/icons/_scion-icon-font.scss +0 -50
package/_index.scss
CHANGED
|
@@ -4,10 +4,14 @@
|
|
|
4
4
|
* An application can define a custom theme to change the default look of the SCION components. Multiple themes are supported.
|
|
5
5
|
* A theme is a collection of design tokens, defining specific design aspects such as colors, spacings, etc. A design token can have a different value per theme.
|
|
6
6
|
*
|
|
7
|
-
* An application typically loads this module in the `styles.scss
|
|
7
|
+
* An application typically loads this module and required SCION icons in the `src/styles.scss`.
|
|
8
8
|
*
|
|
9
9
|
* ```scss
|
|
10
|
+
* // Load required styles.
|
|
10
11
|
* @use '@scion/components';
|
|
12
|
+
*
|
|
13
|
+
* // Load SCION icon font.
|
|
14
|
+
* @import url('https://cdn.jsdelivr.net/npm/@scion/icons/scion-icon-font.css');
|
|
11
15
|
* ```
|
|
12
16
|
*
|
|
13
17
|
* ## Themes
|
|
@@ -58,6 +62,33 @@
|
|
|
58
62
|
* ```html
|
|
59
63
|
* <html sci-theme="scion-dark">
|
|
60
64
|
* ```
|
|
65
|
+
*
|
|
66
|
+
* ## SCION Icons
|
|
67
|
+
* SCION requires the SCION icon font, which can be loaded from the CDN by importing `scion-icon-font.css` in `src/styles.scss`:
|
|
68
|
+
*
|
|
69
|
+
* ```scss
|
|
70
|
+
* @import url('https://cdn.jsdelivr.net/npm/@scion/icons/scion-icon-font.css');
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* Applications enforcing a Content Security Policy must whitelist the CDN using the `font-src` and `style-src` directives.
|
|
74
|
+
*
|
|
75
|
+
* ```
|
|
76
|
+
* Content-Security-Policy: font-src 'self' https://cdn.jsdelivr.net/npm/@scion/icons/; style-src 'self' https://cdn.jsdelivr.net/npm/@scion/icons/;
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* ### Self-Hosting the SCION Icon Font
|
|
80
|
+
* As an alternative to loading SCION icons from the CDN, you can host the SCION icon font directly within your application.
|
|
81
|
+
*
|
|
82
|
+
* To self-host the SCION icon font:
|
|
83
|
+
*
|
|
84
|
+
* Install the `@scion/icons` NPM package to get the required icon font files:
|
|
85
|
+
* ```shell
|
|
86
|
+
* npm install @scion/icons
|
|
87
|
+
* ```
|
|
88
|
+
* Include the SCION icon font in `src/styles.scss`.
|
|
89
|
+
* ```scss
|
|
90
|
+
* @use '@scion/icons/scion-icon-font.css';
|
|
91
|
+
* ```
|
|
61
92
|
*
|
|
62
93
|
* ## SCION Design Tokens
|
|
63
94
|
* SCION uses the following design tokens:
|
|
@@ -84,94 +115,11 @@
|
|
|
84
115
|
*
|
|
85
116
|
* [Semantic Tokens (light theme)](https://raw.githubusercontent.com/SchweizerischeBundesbahnen/scion-toolkit/master/projects/scion/components/design/themes/_scion-light-theme.scss)
|
|
86
117
|
* [Semantic Tokens (dark theme)](https://raw.githubusercontent.com/SchweizerischeBundesbahnen/scion-toolkit/master/projects/scion/components/design/themes/_scion-dark-theme.scss)
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* ## SCION Icon Font
|
|
90
|
-
* This module provides the standard icon font used by SCION components.
|
|
91
|
-
*
|
|
92
|
-
* By default, SCION icons are loaded from the CDN: https://cdn.jsdelivr.net/npm/@scion/icons.
|
|
93
|
-
*
|
|
94
|
-
* ### Content Security Policy (CSP)
|
|
95
|
-
* Applications enforcing a Content Security Policy must whitelist the CDN using the `font-src` directive.
|
|
96
|
-
*
|
|
97
|
-
* ```
|
|
98
|
-
* Content-Security-Policy: font-src 'self' https://cdn.jsdelivr.net/npm/@scion/icons/;
|
|
99
|
-
* ```
|
|
100
|
-
*
|
|
101
|
-
* ### Self-Hosting the SCION Icon Font
|
|
102
|
-
* As an alternative to loading SCION icons from the CDN, you can host the SCION icon font directly within your application.
|
|
103
|
-
*
|
|
104
|
-
* To self-host the SCION icon font:
|
|
105
|
-
*
|
|
106
|
-
* 1. Install the `@scion/icons` NPM module:
|
|
107
|
-
* ```
|
|
108
|
-
* npm install @scion/icons
|
|
109
|
-
* ```
|
|
110
|
-
* 2. Register the icon font files in `assets` in `angular.json`.
|
|
111
|
-
* ```
|
|
112
|
-
* "assets": [
|
|
113
|
-
* {
|
|
114
|
-
* "glob": "**\/*",
|
|
115
|
-
* "input": "node_modules/@scion/icons",
|
|
116
|
-
* "output": "/scion-icons"
|
|
117
|
-
* }
|
|
118
|
-
* ]
|
|
119
|
-
* ```
|
|
120
|
-
* 3. Configure `@scion/components` SCSS module to load the icon font from `/scion-icons` (leading slash required):
|
|
121
|
-
* ```scss
|
|
122
|
-
* @use '@scion/components' with (
|
|
123
|
-
* $icon-font: (
|
|
124
|
-
* directory: '/scion-icons'
|
|
125
|
-
* )
|
|
126
|
-
* );
|
|
127
|
-
* ```
|
|
128
|
-
*
|
|
129
|
-
* As an alternative to steps 1 and 2, you can manually download the icon font files from the CDN and place them directly into your application's public assets folder (`public/scion-icons/`):
|
|
130
|
-
* - https://cdn.jsdelivr.net/npm/@scion/icons/scion-icons.ttf
|
|
131
|
-
* - https://cdn.jsdelivr.net/npm/@scion/icons/scion-icons.svg
|
|
132
|
-
* - https://cdn.jsdelivr.net/npm/@scion/icons/scion-icons.woff
|
|
133
|
-
*
|
|
134
|
-
* ### Loading Self-Hosted Icon Font Relative to Document Base
|
|
135
|
-
* Applications deployed in a subdirectory must configure the `@scion/components` SCSS module to load the self-hosted icon font relative to the document base URL (defined by the `<base>` HTML tag) and exclude the icon font files from the application build.
|
|
136
|
-
*
|
|
137
|
-
* Different steps are required depending on whether building the application with esbuild or Webpack.
|
|
138
|
-
*
|
|
139
|
-
* **Using `@angular/build:application` (esbuild, default since Angular 20)**
|
|
140
|
-
*
|
|
141
|
-
* 1. Configure `@scion/components` SCSS module to load the icon font from `scion-icons` (no leading slash to be relative to the document base URL):
|
|
142
|
-
* ```scss
|
|
143
|
-
* @use '@scion/components' with (
|
|
144
|
-
* $icon-font: (
|
|
145
|
-
* directory: 'scion-icons'
|
|
146
|
-
* )
|
|
147
|
-
* );
|
|
148
|
-
* ```
|
|
149
|
-
* 2. Exclude the icon font files from the application build via `externalDependencies` in `angular.json`:
|
|
150
|
-
* ```
|
|
151
|
-
* "externalDependencies": [
|
|
152
|
-
* "scion-icons/*"
|
|
153
|
-
* ]
|
|
154
|
-
* ```
|
|
155
|
-
*
|
|
156
|
-
* **Using `@angular-devkit/build-angular:browser` (Webpack, deprecated since Angular 22)**
|
|
157
|
-
*
|
|
158
|
-
* Configure `@scion/components` SCSS module to load the icon font from `^scion-icons` (no leading slash to be relative to the document base URL):
|
|
159
|
-
*
|
|
160
|
-
* The leading caret (`^`) instructs Webpack to exclude the icon font files from the application build.
|
|
161
|
-
*
|
|
162
|
-
* ```scss
|
|
163
|
-
* @use '@scion/components' with (
|
|
164
|
-
* $icon-font: (
|
|
165
|
-
* directory: '^scion-icons'
|
|
166
|
-
* )
|
|
167
|
-
* );
|
|
168
|
-
* ```
|
|
169
118
|
*/
|
|
170
119
|
|
|
171
120
|
@use './design/theming' as sci-theming;
|
|
172
121
|
@use './design/themes/scion-light-theme';
|
|
173
122
|
@use './design/themes/scion-dark-theme';
|
|
174
|
-
@use './design/icons/scion-icon-font' as sci-icon-font;
|
|
175
123
|
@use 'sass:map';
|
|
176
124
|
|
|
177
125
|
// Install theme
|
|
@@ -182,7 +130,3 @@ $-built-in-themes: (
|
|
|
182
130
|
$themes: $-built-in-themes !default;
|
|
183
131
|
$themes: sci-theming.augment($themes, $-built-in-themes);
|
|
184
132
|
@include sci-theming.install($themes);
|
|
185
|
-
|
|
186
|
-
// Install icon font
|
|
187
|
-
$icon-font: null !default;
|
|
188
|
-
@include sci-icon-font.install-icon-font($icon-font);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { isSignal, signal, inject, Injector, effect, untracked, DestroyRef, assertInInjectionContext
|
|
2
|
+
import { isSignal, signal, inject, Injector, effect, untracked, DestroyRef, assertInInjectionContext, input, ElementRef, IterableDiffers, Renderer2, Directive, ViewContainerRef, inputBinding, InjectionToken, LOCALE_ID, computed } from '@angular/core';
|
|
3
3
|
import { of, Observable } from 'rxjs';
|
|
4
|
+
import { coerceElement } from '@angular/cdk/coercion';
|
|
4
5
|
|
|
5
6
|
/*
|
|
6
7
|
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
@@ -67,7 +68,7 @@ function toLazyObservable(signal, options) {
|
|
|
67
68
|
* @param options.providers - Specifies providers to associate with the injector.
|
|
68
69
|
* @param options.name - Names the injector, useful for debugging the injector hierarchy.
|
|
69
70
|
*/
|
|
70
|
-
function
|
|
71
|
+
function ɵcreateDestroyableInjector(options) {
|
|
71
72
|
const parentInjector = options?.parent ?? inject(Injector);
|
|
72
73
|
const injector = Injector.create({ parent: parentInjector, providers: options?.providers ?? [], name: options?.name });
|
|
73
74
|
// Destroy injector manually since not destroyed when the parent injector is destroyed.
|
|
@@ -86,14 +87,40 @@ function createDestroyableInjector(options) {
|
|
|
86
87
|
*
|
|
87
88
|
* @docs-private Not public API. For internal use only.
|
|
88
89
|
*/
|
|
89
|
-
function
|
|
90
|
+
function ɵassertInInjectionContext(debugFn, message) {
|
|
90
91
|
try {
|
|
91
|
-
assertInInjectionContext
|
|
92
|
+
assertInInjectionContext(debugFn);
|
|
92
93
|
}
|
|
93
94
|
catch {
|
|
94
95
|
throw Error([`${debugFn.name}() can only be used within an injection context.`].concat(message ? message : []).join(' '));
|
|
95
96
|
}
|
|
96
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Factory for creating new injectors.
|
|
100
|
+
*
|
|
101
|
+
* Creating a new injector automatically destroys the previous injector created by this factory.
|
|
102
|
+
*
|
|
103
|
+
* @docs-private Not public API. For internal use only.
|
|
104
|
+
*/
|
|
105
|
+
class ɵSingleActiveInjectorFactory {
|
|
106
|
+
_injector;
|
|
107
|
+
_options;
|
|
108
|
+
constructor(options) {
|
|
109
|
+
this._options = {
|
|
110
|
+
parent: options?.parent ?? inject(Injector),
|
|
111
|
+
providers: options?.providers,
|
|
112
|
+
name: options?.name,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Creates a new injector, destroying the previously created one, if any.
|
|
117
|
+
*/
|
|
118
|
+
create() {
|
|
119
|
+
this._injector?.destroy();
|
|
120
|
+
this._injector = ɵcreateDestroyableInjector({ parent: this._options.parent, providers: this._options.providers, name: this._options.name });
|
|
121
|
+
return this._injector;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
97
124
|
|
|
98
125
|
/*
|
|
99
126
|
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
@@ -106,6 +133,8 @@ function assertInInjectionContext(debugFn, message) {
|
|
|
106
133
|
*/
|
|
107
134
|
/**
|
|
108
135
|
* Use to add specified attributes to the host element.
|
|
136
|
+
*
|
|
137
|
+
* @docs-private Not public API. For internal use only.
|
|
109
138
|
*/
|
|
110
139
|
class SciAttributesDirective {
|
|
111
140
|
/**
|
|
@@ -274,6 +303,105 @@ const SCI_LOCALE = new InjectionToken('SCI_LOCALE', {
|
|
|
274
303
|
factory: () => signal(inject(LOCALE_ID)),
|
|
275
304
|
});
|
|
276
305
|
|
|
306
|
+
/**
|
|
307
|
+
* Displays element text content as a tooltip when text overflows.
|
|
308
|
+
*
|
|
309
|
+
* Uses the host element text content by default. The content source can be customized via {@link sourceElement} input.
|
|
310
|
+
*
|
|
311
|
+
* Usage:
|
|
312
|
+
*
|
|
313
|
+
* ```html
|
|
314
|
+
* <div sciTooltipOnOverflow>Content</div>
|
|
315
|
+
* ```
|
|
316
|
+
*
|
|
317
|
+
* Can also be used on input elements, displaying a tooltip when the value overflows.
|
|
318
|
+
*
|
|
319
|
+
* Usage:
|
|
320
|
+
*
|
|
321
|
+
* ```html
|
|
322
|
+
* <input sciTooltipOnOverflow>
|
|
323
|
+
* ```
|
|
324
|
+
*
|
|
325
|
+
* Supports appending additional text that is always displayed regardless of whether text overflows.
|
|
326
|
+
*
|
|
327
|
+
* If used as a host directive, configure via the following DI tokens:
|
|
328
|
+
* - {@link TOOLTIP_ON_OVERFLOW_DIRECTIVE_SOURCE_ELEMENT} and
|
|
329
|
+
* - {@link TOOLTIP_ON_OVERFLOW_DIRECTIVE_ADDITIONAL_TEXT}.
|
|
330
|
+
*/
|
|
331
|
+
class SciTooltipOnOverflowDirective {
|
|
332
|
+
/**
|
|
333
|
+
* Specifies the element from which to read text content for displaying as tooltip. Defaults to the host element.
|
|
334
|
+
*
|
|
335
|
+
* If used as a host directive, configure an alternative source using {@link TOOLTIP_ON_OVERFLOW_DIRECTIVE_SOURCE_ELEMENT} DI token.
|
|
336
|
+
*/
|
|
337
|
+
sourceElement = input(inject(ElementRef), { ...(ngDevMode ? { debugName: "sourceElement" } : /* istanbul ignore next */ {}), alias: 'sciTooltipOnOverflowSourceElement' });
|
|
338
|
+
/**
|
|
339
|
+
* Specifies additional text appended to the tooltip.
|
|
340
|
+
*
|
|
341
|
+
* This text is always displayed, regardless of whether text overflows.
|
|
342
|
+
*
|
|
343
|
+
* If used as a host directive, specify additional text via {@link TOOLTIP_ON_OVERFLOW_DIRECTIVE_ADDITIONAL_TEXT} DI token.
|
|
344
|
+
*/
|
|
345
|
+
additionalText = input(undefined, { ...(ngDevMode ? { debugName: "additionalText" } : /* istanbul ignore next */ {}), alias: 'sciTooltipOnOverflowAdditionalText' });
|
|
346
|
+
_sourceElement = this.computeSourceElement();
|
|
347
|
+
_additionalText = this.computeAdditionalText();
|
|
348
|
+
_hasOverflow = signal(false, /* @ts-ignore */
|
|
349
|
+
...(ngDevMode ? [{ debugName: "_hasOverflow" }] : /* istanbul ignore next */ []));
|
|
350
|
+
tooltip = this.computeTooltip();
|
|
351
|
+
onMouseEnter() {
|
|
352
|
+
const sourceElement = this._sourceElement();
|
|
353
|
+
this._hasOverflow.set(!!sourceElement && (sourceElement.scrollWidth > sourceElement.clientWidth || sourceElement.scrollHeight > sourceElement.clientHeight));
|
|
354
|
+
}
|
|
355
|
+
onMouseLeave() {
|
|
356
|
+
this._hasOverflow.set(false);
|
|
357
|
+
}
|
|
358
|
+
computeSourceElement() {
|
|
359
|
+
const sourceElement = coerceSignal(inject(TOOLTIP_ON_OVERFLOW_DIRECTIVE_SOURCE_ELEMENT, { optional: true }) ?? this.sourceElement);
|
|
360
|
+
return computed(() => coerceElement(sourceElement()));
|
|
361
|
+
}
|
|
362
|
+
computeAdditionalText() {
|
|
363
|
+
return coerceSignal(inject(TOOLTIP_ON_OVERFLOW_DIRECTIVE_ADDITIONAL_TEXT, { optional: true }) ?? this.additionalText);
|
|
364
|
+
}
|
|
365
|
+
computeTooltip() {
|
|
366
|
+
return computed(() => {
|
|
367
|
+
const tooltip = new Array();
|
|
368
|
+
const sourceElement = this._sourceElement();
|
|
369
|
+
if (this._hasOverflow()) {
|
|
370
|
+
tooltip.push(sourceElement instanceof HTMLInputElement ? sourceElement.value : sourceElement.textContent.trim());
|
|
371
|
+
}
|
|
372
|
+
if (this._additionalText()?.length) {
|
|
373
|
+
tooltip.push(this._additionalText());
|
|
374
|
+
}
|
|
375
|
+
return tooltip.join('\n') || undefined;
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciTooltipOnOverflowDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
379
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: SciTooltipOnOverflowDirective, isStandalone: true, selector: "[sciTooltipOnOverflow]", inputs: { sourceElement: { classPropertyName: "sourceElement", publicName: "sciTooltipOnOverflowSourceElement", isSignal: true, isRequired: false, transformFunction: null }, additionalText: { classPropertyName: "additionalText", publicName: "sciTooltipOnOverflowAdditionalText", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" }, properties: { "attr.title": "tooltip()" } }, ngImport: i0 });
|
|
380
|
+
}
|
|
381
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciTooltipOnOverflowDirective, decorators: [{
|
|
382
|
+
type: Directive,
|
|
383
|
+
args: [{
|
|
384
|
+
selector: '[sciTooltipOnOverflow]',
|
|
385
|
+
host: {
|
|
386
|
+
'(mouseenter)': 'onMouseEnter()',
|
|
387
|
+
'(mouseleave)': 'onMouseLeave()',
|
|
388
|
+
'[attr.title]': 'tooltip()',
|
|
389
|
+
},
|
|
390
|
+
}]
|
|
391
|
+
}], propDecorators: { sourceElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "sciTooltipOnOverflowSourceElement", required: false }] }], additionalText: [{ type: i0.Input, args: [{ isSignal: true, alias: "sciTooltipOnOverflowAdditionalText", required: false }] }] } });
|
|
392
|
+
/**
|
|
393
|
+
* Specifies the element from which to read text content for displaying as tooltip.
|
|
394
|
+
*
|
|
395
|
+
* Use this token to configure {@link SciTooltipOnOverflowDirective} if used as a host directive. Equivalent to {@link SciTooltipOnOverflowDirective.sourceElement}.
|
|
396
|
+
*/
|
|
397
|
+
const TOOLTIP_ON_OVERFLOW_DIRECTIVE_SOURCE_ELEMENT = new InjectionToken('TOOLTIP_ON_OVERFLOW_DIRECTIVE_SOURCE_ELEMENT');
|
|
398
|
+
/**
|
|
399
|
+
* Specifies additional text appended to the tooltip.
|
|
400
|
+
*
|
|
401
|
+
* Use this token to configure {@link SciTooltipOnOverflowDirective} if used as a host directive. Equivalent to {@link SciTooltipOnOverflowDirective.additionalText}.
|
|
402
|
+
*/
|
|
403
|
+
const TOOLTIP_ON_OVERFLOW_DIRECTIVE_ADDITIONAL_TEXT = new InjectionToken('TOOLTIP_ON_OVERFLOW_DIRECTIVE_ADDITIONAL_TEXT');
|
|
404
|
+
|
|
277
405
|
/*
|
|
278
406
|
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
279
407
|
*
|
|
@@ -293,5 +421,5 @@ const SCI_LOCALE = new InjectionToken('SCI_LOCALE', {
|
|
|
293
421
|
* Generated bundle index. Do not edit.
|
|
294
422
|
*/
|
|
295
423
|
|
|
296
|
-
export { SCI_LOCALE, SciAttributesDirective, SciComponentOutletDirective,
|
|
424
|
+
export { SCI_LOCALE, SciAttributesDirective, SciComponentOutletDirective, SciTooltipOnOverflowDirective, TOOLTIP_ON_OVERFLOW_DIRECTIVE_ADDITIONAL_TEXT, TOOLTIP_ON_OVERFLOW_DIRECTIVE_SOURCE_ELEMENT, coerceSignal, toLazyObservable, ɵSingleActiveInjectorFactory, ɵassertInInjectionContext, ɵcreateDestroyableInjector };
|
|
297
425
|
//# sourceMappingURL=scion-components-common.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scion-components-common.mjs","sources":["../../../../projects/scion/components/common/src/signal.util.ts","../../../../projects/scion/components/common/src/injector.util.ts","../../../../projects/scion/components/common/src/attributes.directive.ts","../../../../projects/scion/components/common/src/component-outlet.directive.ts","../../../../projects/scion/components/common/src/locale.ts","../../../../projects/scion/components/common/src/public_api.ts","../../../../projects/scion/components/common/src/scion-components-common.ts"],"sourcesContent":["/*\n * Copyright (c) 2018-2026 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {effect, inject, Injector, isSignal, signal, Signal, untracked} from '@angular/core';\nimport {Observable, of} from 'rxjs';\n\n/**\n * Represents a value or a {@link Signal} of that value.\n */\nexport type MaybeSignal<T> = T | Signal<T>;\n\n/**\n * Coerces the given value into a {@link Signal}. If the value is already a signal, it is returned as-is; otherwise, it is wrapped in a signal.\n *\n * Passing `undefined` returns `undefined`, unless the option `coerceUndefined` is set to `true`.\n *\n * @param value - Specifies the value to coerece.\n */\nexport function coerceSignal<T extends MaybeSignal<unknown>>(value: T): T extends Signal<unknown> ? T : T extends undefined ? undefined : Signal<T>;\n/**\n * Coerces the given value into a {@link Signal}. If the value is already a signal, it is returned as-is; otherwise, it is wrapped in a signal.\n *\n * @param value - Specifies the value to coerece.\n * @param options - Controls coercion.\n * @param options.coerceUndefined - If `true`, returns `signal(undefined)` for a `undefined` value. Defaults to `false`.\n */\nexport function coerceSignal<T>(value: MaybeSignal<T> | undefined, options: {coerceUndefined: true}): Signal<T | undefined>;\n\nexport function coerceSignal<T>(value: MaybeSignal<T>, options?: {coerceUndefined?: true}): Signal<T> | undefined {\n if (value === undefined && !options?.coerceUndefined) {\n return undefined;\n }\n return isSignal(value) ? value : signal(value);\n}\n\n/**\n * Like {@link toObservable}, but lazily creates the effect upon subscription, binding it to the subscription lifecycle instead of the injection context, plus, emits the signal's initial value synchronously.\n */\nexport function toLazyObservable<T>(signal: MaybeSignal<NonNullable<T>>, options?: {injector?: Injector}): Observable<NonNullable<T>>;\nexport function toLazyObservable<T>(signal: MaybeSignal<NonNullable<T>> | undefined, options?: {injector?: Injector}): Observable<NonNullable<T>> | undefined;\nexport function toLazyObservable<T>(signal: MaybeSignal<NonNullable<T>> | undefined, options?: {injector?: Injector}): Observable<NonNullable<T>> | undefined {\n if (signal === undefined) {\n return undefined;\n }\n if (!isSignal(signal)) {\n return of(signal);\n }\n\n const injector = options?.injector ?? inject(Injector);\n return new Observable(observer => {\n const initialValue = signal();\n let isFirstEffectRun = true;\n\n // Emit initial value synchronously.\n observer.next(initialValue);\n\n const effectRef = effect(() => {\n const value = signal();\n\n untracked(() => {\n if (!isFirstEffectRun || initialValue !== value) {\n observer.next(value);\n }\n isFirstEffectRun = false;\n });\n }, {injector, manualCleanup: true});\n\n return () => effectRef.destroy();\n });\n}\n","/*\n * Copyright (c) 2018-2026 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {assertInInjectionContext as ngAssertInInjectionContext, DestroyableInjector, DestroyRef, inject, Injector, Provider} from '@angular/core';\n\n/**\n * Creates a {@link DestroyableInjector} bound to the lifecycle of its parent injector. Defaults to the current injector if not configuring a parent injector.\n *\n * Unlike injectors created via {@link Injector.create}, the returned injector:\n * - Is destroyed with its parent, also if used outside a component injection context.\n * - Does not throw an error when invoking {@link DestroyableInjector.destroy} if already destroyed.\n * - Uses the current injection context as parent if no explicit parent injector is specified.\n *\n * @docs-private Not public API. For internal use only.\n *\n * @param options - Configures the injector.\n * @param options.parent - Specifies the parent injector. Defaults to the current injector.\n * @param options.providers - Specifies providers to associate with the injector.\n * @param options.name - Names the injector, useful for debugging the injector hierarchy.\n */\nexport function createDestroyableInjector(options?: {parent?: Injector; providers?: Provider[]; name?: string}): DestroyableInjector {\n const parentInjector = options?.parent ?? inject(Injector);\n const injector = Injector.create({parent: parentInjector, providers: options?.providers ?? [], name: options?.name});\n\n // Destroy injector manually since not destroyed when the parent injector is destroyed.\n // Angular only destroys child injectors in the scope of a component injector.\n parentInjector.get(DestroyRef).onDestroy(() => injector.destroy());\n\n // Patch `Injector.destroy` to not error if already destroyed.\n const realDestroyFn = injector.destroy;\n const destroyRef = injector.get(DestroyRef);\n injector.destroy = () => !destroyRef.destroyed && realDestroyFn.apply(injector);\n return injector;\n}\n\n/**\n * Asserts that the current stack frame is within an injection context and has access to inject.\n *\n * Delegates to `assertInInjectionContext` from @angular/core, adding the given message to the error if the assertion fails.\n *\n * @docs-private Not public API. For internal use only.\n */\nexport function assertInInjectionContext(debugFn: Function, message: string): void { // eslint-disable-line @typescript-eslint/no-unsafe-function-type\n try {\n ngAssertInInjectionContext(debugFn);\n }\n catch {\n throw Error([`${debugFn.name}() can only be used within an injection context.`].concat(message ? message : []).join(' '));\n }\n}\n","/*\n * Copyright (c) 2018-2026 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {Directive, effect, ElementRef, inject, input, IterableDiffers, Renderer2, untracked} from '@angular/core';\n\n/**\n * Use to add specified attributes to the host element.\n */\n@Directive({selector: '[sciAttributes]'})\nexport class SciAttributesDirective {\n\n /**\n * Specifies attributes to add to the host element.\n *\n * Attributes with `null` or `undefined` values are removed.\n */\n public readonly attributes = input<{[name: string]: unknown | undefined | null} | undefined | null>(undefined, {alias: 'sciAttributes'});\n\n constructor() {\n const host = inject(ElementRef).nativeElement as HTMLElement;\n const attributeDiffer = inject(IterableDiffers).find([]).create<string>();\n const renderer = inject(Renderer2);\n\n effect(() => {\n const attributes = this.attributes() ?? {};\n\n untracked(() => {\n // Delete removed attributes.\n const diff = attributeDiffer.diff(Object.keys(attributes));\n diff?.forEachRemovedItem(({item: name}) => renderer.removeAttribute(host, name));\n\n // Update added or changed attributes.\n Object.entries(attributes).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n renderer.setAttribute(host, key, `${value}`);\n }\n else {\n renderer.removeAttribute(host, key);\n }\n });\n });\n });\n }\n}\n","/*\n * Copyright (c) 2018-2026 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {Binding, ComponentRef, Directive, effect, inject, Injector, input, inputBinding, Provider, Type, untracked, ViewContainerRef} from '@angular/core';\nimport {ComponentType} from '@angular/cdk/portal';\nimport {SciAttributesDirective} from './attributes.directive';\nimport {coerceSignal, MaybeSignal} from './signal.util';\n\n/**\n * Renders a component based on a descriptor, similar to `ngComponentOutlet`, but with input bindings.\n *\n * Usage:\n *\n * ```html\n * <ng-container *sciComponentOutlet=\"descriptor\"/>\n * ````\n *\n * ```ts\n * protected readonly descriptor: SciComponentDescriptor = {\n * component: FilterComponent,\n * bindings: [\n * inputBinding('placeholder', signal('Filter items...')),\n * ],\n * };\n * ```\n */\n@Directive({selector: 'ng-template[sciComponentOutlet]'})\nexport class SciComponentOutletDirective {\n\n /**\n * Specifies the component to render.\n */\n public readonly descriptor = input.required<SciComponentDescriptor | undefined | null>({alias: 'sciComponentOutlet'});\n\n constructor() {\n const viewContainerRef = inject(ViewContainerRef);\n\n effect(onCleanup => {\n const descriptor = this.descriptor();\n\n untracked(() => {\n const component = descriptor && createComponent(viewContainerRef, descriptor);\n onCleanup(() => component?.destroy());\n });\n });\n }\n}\n\n/**\n * Instantiates the specified component and inserts it after the specified view container.\n */\nfunction createComponent(viewContainerRef: ViewContainerRef, descriptor: SciComponentDescriptor): ComponentRef<unknown> {\n // Provide providers via host directive.\n @Directive({providers: descriptor.providers ?? []})\n class ProvidersDirective {\n }\n\n // Provide CSS classes via host directive.\n @Directive({host: {'[class]': 'cssClass?.()'}})\n class CssClassDirective {\n protected readonly cssClass = coerceSignal(descriptor.cssClass);\n }\n\n return viewContainerRef.createComponent(descriptor.component, {\n directives: [\n ProvidersDirective,\n CssClassDirective,\n {type: SciAttributesDirective, bindings: [inputBinding('sciAttributes', coerceSignal(descriptor.attributes ?? {}))]},\n ...descriptor.directives ?? [],\n ],\n bindings: descriptor.bindings,\n injector: descriptor.injector,\n });\n}\n\n/**\n * Describes the rendering of a component.\n */\nexport interface SciComponentDescriptor {\n /**\n * Specifies the component to render.\n */\n component: ComponentType<unknown>;\n /**\n * Specifies input and output bindings.\n *\n * @example - Passing inputs to the component\n * ```ts\n * bindings: [inputBinding('placeholder', signal('Filter items...'))];\n * ```\n *\n * Inputs are available as input properties in the component.\n *\n * @example - Reading inputs in the component\n * ```ts\n * public placeholder = input.required<string>();\n * ```\n *\n * @see inputBinding\n * @see outputBinding\n * @see twoWayBinding\n */\n bindings?: Binding[];\n /**\n * Specifies directives to be applied to the component.\n */\n directives?: Array<Type<unknown> | {type: Type<unknown>; bindings: Binding[]}>;\n /**\n * Specifies the injector used to instantiate the component, giving control over which objects are available for injection. Defaults to the element injector.\n *\n * ```ts\n * Injector.create({\n * parent: ...,\n * providers: [\n * {provide: <TOKEN>, useValue: <VALUE>}\n * ],\n * })\n * ```\n */\n injector?: Injector;\n /**\n * Specifies providers available for injection in the component.\n */\n providers?: Provider[];\n /**\n * Specifies CSS classes to associate with the component.\n */\n cssClass?: MaybeSignal<string | string[]>;\n /**\n * Specifies HTML attributes to associate with the component.\n *\n * Data attributes should start with the `data-` prefix.\n */\n attributes?: MaybeSignal<{[name: string]: string | undefined}>;\n}\n","/*\n * Copyright (c) 2018-2026 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {inject, InjectionToken, LOCALE_ID, signal, WritableSignal} from '@angular/core';\n\n/**\n * DI token providing the current locale to SCION components for localizing dates and numbers.\n *\n * Defaults to {@link LOCALE_ID}. Changing the locale updates formatting in SCION components, unless overridden at the component level.\n *\n * Change the locale at runtime as follows:\n * ```ts\n * inject(SCI_LOCALE).set('de-CH');\n * ```\n *\n * Angular includes only `en-US` by default. Register other locales via `registerLocaleData()`, typically in an environment initializer at app startup:\n *\n * ```ts\n * import {bootstrapApplication} from '@angular/platform-browser';\n * import {provideEnvironmentInitializer} from '@angular/core';\n * import {registerLocaleData} from '@angular/common';\n *\n * import localeDeCH from '@angular/common/locales/de-CH';\n * import localeFrCH from '@angular/common/locales/fr-CH';\n * import localeItCH from '@angular/common/locales/it-CH';\n *\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideEnvironmentInitializer(() => {\n * registerLocaleData(localeDeCH);\n * registerLocaleData(localeFrCH);\n * registerLocaleData(localeItCH);\n * }),\n * ],\n * });\n * ```\n */\nexport const SCI_LOCALE = new InjectionToken<WritableSignal<string>>('SCI_LOCALE', {\n providedIn: 'root',\n factory: () => signal(inject(LOCALE_ID)),\n});\n","/*\n * Copyright (c) 2018-2026 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\n/*\n * Secondary entrypoint: '@scion/components/common'\n *\n * @see https://github.com/ng-packagr/ng-packagr/blob/master/docs/secondary-entrypoints.md\n */\nexport {coerceSignal, type MaybeSignal, toLazyObservable} from './signal.util';\nexport {createDestroyableInjector, assertInInjectionContext} from './injector.util';\nexport {type SciComponentDescriptor, SciComponentOutletDirective} from './component-outlet.directive';\nexport {SciAttributesDirective} from './attributes.directive';\nexport {type SciTemplateDescriptor} from './template-descriptor';\nexport {SCI_LOCALE} from './locale';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["ngAssertInInjectionContext"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scion-components-common.mjs","sources":["../../../../projects/scion/components/common/src/signal.util.ts","../../../../projects/scion/components/common/src/injector.util.ts","../../../../projects/scion/components/common/src/attributes.directive.ts","../../../../projects/scion/components/common/src/component-outlet.directive.ts","../../../../projects/scion/components/common/src/locale.ts","../../../../projects/scion/components/common/src/tooltip-on-overflow.directive.ts","../../../../projects/scion/components/common/src/public_api.ts","../../../../projects/scion/components/common/src/scion-components-common.ts"],"sourcesContent":["/*\n * Copyright (c) 2018-2026 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {effect, inject, Injector, isSignal, signal, Signal, untracked} from '@angular/core';\nimport {Observable, of} from 'rxjs';\n\n/**\n * Represents a value or a {@link Signal} of that value.\n */\nexport type MaybeSignal<T> = T | Signal<T>;\n\n/**\n * Coerces the given value into a {@link Signal}. If the value is already a signal, it is returned as-is; otherwise, it is wrapped in a signal.\n *\n * Passing `undefined` returns `undefined`, unless the option `coerceUndefined` is set to `true`.\n *\n * @param value - Specifies the value to coerece.\n */\nexport function coerceSignal<T extends MaybeSignal<unknown>>(value: T): T extends Signal<unknown> ? T : T extends undefined ? undefined : Signal<T>;\n/**\n * Coerces the given value into a {@link Signal}. If the value is already a signal, it is returned as-is; otherwise, it is wrapped in a signal.\n *\n * @param value - Specifies the value to coerece.\n * @param options - Controls coercion.\n * @param options.coerceUndefined - If `true`, returns `signal(undefined)` for a `undefined` value. Defaults to `false`.\n */\nexport function coerceSignal<T>(value: MaybeSignal<T> | undefined, options: {coerceUndefined: true}): Signal<T | undefined>;\n\nexport function coerceSignal<T>(value: MaybeSignal<T>, options?: {coerceUndefined?: true}): Signal<T> | undefined {\n if (value === undefined && !options?.coerceUndefined) {\n return undefined;\n }\n return isSignal(value) ? value : signal(value);\n}\n\n/**\n * Like {@link toObservable}, but lazily creates the effect upon subscription, binding it to the subscription lifecycle instead of the injection context, plus, emits the signal's initial value synchronously.\n */\nexport function toLazyObservable<T>(signal: MaybeSignal<NonNullable<T>>, options?: {injector?: Injector}): Observable<NonNullable<T>>;\nexport function toLazyObservable<T>(signal: MaybeSignal<NonNullable<T>> | undefined, options?: {injector?: Injector}): Observable<NonNullable<T>> | undefined;\nexport function toLazyObservable<T>(signal: MaybeSignal<NonNullable<T>> | undefined, options?: {injector?: Injector}): Observable<NonNullable<T>> | undefined {\n if (signal === undefined) {\n return undefined;\n }\n if (!isSignal(signal)) {\n return of(signal);\n }\n\n const injector = options?.injector ?? inject(Injector);\n return new Observable(observer => {\n const initialValue = signal();\n let isFirstEffectRun = true;\n\n // Emit initial value synchronously.\n observer.next(initialValue);\n\n const effectRef = effect(() => {\n const value = signal();\n\n untracked(() => {\n if (!isFirstEffectRun || initialValue !== value) {\n observer.next(value);\n }\n isFirstEffectRun = false;\n });\n }, {injector, manualCleanup: true});\n\n return () => effectRef.destroy();\n });\n}\n","/*\n * Copyright (c) 2018-2026 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {assertInInjectionContext as ngAssertInInjectionContext, DestroyableInjector, DestroyRef, inject, Injector, Provider} from '@angular/core';\n\n/**\n * Creates a {@link DestroyableInjector} bound to the lifecycle of its parent injector. Defaults to the current injector if not configuring a parent injector.\n *\n * Unlike injectors created via {@link Injector.create}, the returned injector:\n * - Is destroyed with its parent, also if used outside a component injection context.\n * - Does not throw an error when invoking {@link DestroyableInjector.destroy} if already destroyed.\n * - Uses the current injection context as parent if no explicit parent injector is specified.\n *\n * @docs-private Not public API. For internal use only.\n *\n * @param options - Configures the injector.\n * @param options.parent - Specifies the parent injector. Defaults to the current injector.\n * @param options.providers - Specifies providers to associate with the injector.\n * @param options.name - Names the injector, useful for debugging the injector hierarchy.\n */\nexport function ɵcreateDestroyableInjector(options?: {parent?: Injector; providers?: Provider[]; name?: string}): DestroyableInjector {\n const parentInjector = options?.parent ?? inject(Injector);\n const injector = Injector.create({parent: parentInjector, providers: options?.providers ?? [], name: options?.name});\n\n // Destroy injector manually since not destroyed when the parent injector is destroyed.\n // Angular only destroys child injectors in the scope of a component injector.\n parentInjector.get(DestroyRef).onDestroy(() => injector.destroy());\n\n // Patch `Injector.destroy` to not error if already destroyed.\n const realDestroyFn = injector.destroy;\n const destroyRef = injector.get(DestroyRef);\n injector.destroy = () => !destroyRef.destroyed && realDestroyFn.apply(injector);\n return injector;\n}\n\n/**\n * Asserts that the current stack frame is within an injection context and has access to inject.\n *\n * Delegates to `assertInInjectionContext` from @angular/core, adding the given message to the error if the assertion fails.\n *\n * @docs-private Not public API. For internal use only.\n */\nexport function ɵassertInInjectionContext(debugFn: Function, message: string): void { // eslint-disable-line @typescript-eslint/no-unsafe-function-type\n try {\n ngAssertInInjectionContext(debugFn);\n }\n catch {\n throw Error([`${debugFn.name}() can only be used within an injection context.`].concat(message ? message : []).join(' '));\n }\n}\n\n/**\n * Factory for creating new injectors.\n *\n * Creating a new injector automatically destroys the previous injector created by this factory.\n *\n * @docs-private Not public API. For internal use only.\n */\nexport class ɵSingleActiveInjectorFactory {\n\n private _injector: DestroyableInjector | undefined;\n private _options: {parent?: Injector; providers?: Provider[]; name?: string};\n\n constructor(options?: {parent?: Injector; providers?: Provider[]; name?: string}) {\n this._options = {\n parent: options?.parent ?? inject(Injector),\n providers: options?.providers,\n name: options?.name,\n };\n }\n\n /**\n * Creates a new injector, destroying the previously created one, if any.\n */\n public create(): Injector {\n this._injector?.destroy();\n this._injector = ɵcreateDestroyableInjector({parent: this._options.parent, providers: this._options.providers, name: this._options.name});\n return this._injector;\n }\n}\n","/*\n * Copyright (c) 2018-2026 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {Directive, effect, ElementRef, inject, input, IterableDiffers, Renderer2, untracked} from '@angular/core';\n\n/**\n * Use to add specified attributes to the host element.\n *\n * @docs-private Not public API. For internal use only.\n */\n@Directive({selector: '[sciAttributes]'})\nexport class SciAttributesDirective {\n\n /**\n * Specifies attributes to add to the host element.\n *\n * Attributes with `null` or `undefined` values are removed.\n */\n public readonly attributes = input<{[name: string]: unknown | undefined | null} | undefined | null>(undefined, {alias: 'sciAttributes'});\n\n constructor() {\n const host = inject(ElementRef).nativeElement as HTMLElement;\n const attributeDiffer = inject(IterableDiffers).find([]).create<string>();\n const renderer = inject(Renderer2);\n\n effect(() => {\n const attributes = this.attributes() ?? {};\n\n untracked(() => {\n // Delete removed attributes.\n const diff = attributeDiffer.diff(Object.keys(attributes));\n diff?.forEachRemovedItem(({item: name}) => renderer.removeAttribute(host, name));\n\n // Update added or changed attributes.\n Object.entries(attributes).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n renderer.setAttribute(host, key, `${value}`);\n }\n else {\n renderer.removeAttribute(host, key);\n }\n });\n });\n });\n }\n}\n","/*\n * Copyright (c) 2018-2026 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {Binding, ComponentRef, Directive, effect, inject, Injector, input, inputBinding, Provider, Type, untracked, ViewContainerRef} from '@angular/core';\nimport {ComponentType} from '@angular/cdk/portal';\nimport {SciAttributesDirective} from './attributes.directive';\nimport {coerceSignal, MaybeSignal} from './signal.util';\n\n/**\n * Renders a component based on a descriptor, similar to `ngComponentOutlet`, but with input bindings.\n *\n * Usage:\n *\n * ```html\n * <ng-container *sciComponentOutlet=\"descriptor\"/>\n * ````\n *\n * ```ts\n * protected readonly descriptor: SciComponentDescriptor = {\n * component: FilterComponent,\n * bindings: [\n * inputBinding('placeholder', signal('Filter items...')),\n * ],\n * };\n * ```\n */\n@Directive({selector: 'ng-template[sciComponentOutlet]'})\nexport class SciComponentOutletDirective {\n\n /**\n * Specifies the component to render.\n */\n public readonly descriptor = input.required<SciComponentDescriptor | undefined | null>({alias: 'sciComponentOutlet'});\n\n constructor() {\n const viewContainerRef = inject(ViewContainerRef);\n\n effect(onCleanup => {\n const descriptor = this.descriptor();\n\n untracked(() => {\n const component = descriptor && createComponent(viewContainerRef, descriptor);\n onCleanup(() => component?.destroy());\n });\n });\n }\n}\n\n/**\n * Instantiates the specified component and inserts it after the specified view container.\n */\nfunction createComponent(viewContainerRef: ViewContainerRef, descriptor: SciComponentDescriptor): ComponentRef<unknown> {\n // Provide providers via host directive.\n @Directive({providers: descriptor.providers ?? []})\n class ProvidersDirective {\n }\n\n // Provide CSS classes via host directive.\n @Directive({host: {'[class]': 'cssClass?.()'}})\n class CssClassDirective {\n protected readonly cssClass = coerceSignal(descriptor.cssClass);\n }\n\n return viewContainerRef.createComponent(descriptor.component, {\n directives: [\n ProvidersDirective,\n CssClassDirective,\n {type: SciAttributesDirective, bindings: [inputBinding('sciAttributes', coerceSignal(descriptor.attributes ?? {}))]},\n ...descriptor.directives ?? [],\n ],\n bindings: descriptor.bindings,\n injector: descriptor.injector,\n });\n}\n\n/**\n * Describes the rendering of a component.\n */\nexport interface SciComponentDescriptor {\n /**\n * Specifies the component to render.\n */\n component: ComponentType<unknown>;\n /**\n * Specifies input and output bindings.\n *\n * @example - Passing inputs to the component\n * ```ts\n * bindings: [inputBinding('placeholder', signal('Filter items...'))];\n * ```\n *\n * Inputs are available as input properties in the component.\n *\n * @example - Reading inputs in the component\n * ```ts\n * public placeholder = input.required<string>();\n * ```\n *\n * @see inputBinding\n * @see outputBinding\n * @see twoWayBinding\n */\n bindings?: Binding[];\n /**\n * Specifies directives to be applied to the component.\n */\n directives?: Array<Type<unknown> | {type: Type<unknown>; bindings: Binding[]}>;\n /**\n * Specifies the injector used to instantiate the component, giving control over which objects are available for injection. Defaults to the element injector.\n *\n * ```ts\n * Injector.create({\n * parent: ...,\n * providers: [\n * {provide: <TOKEN>, useValue: <VALUE>}\n * ],\n * })\n * ```\n */\n injector?: Injector;\n /**\n * Specifies providers available for injection in the component.\n */\n providers?: Provider[];\n /**\n * Specifies CSS classes to associate with the component.\n */\n cssClass?: MaybeSignal<string | string[]>;\n /**\n * Specifies HTML attributes to associate with the component.\n *\n * Data attributes should start with the `data-` prefix.\n */\n attributes?: MaybeSignal<{[name: string]: string | undefined}>;\n}\n","/*\n * Copyright (c) 2018-2026 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {inject, InjectionToken, LOCALE_ID, signal, WritableSignal} from '@angular/core';\n\n/**\n * DI token providing the current locale to SCION components for localizing dates and numbers.\n *\n * Defaults to {@link LOCALE_ID}. Changing the locale updates formatting in SCION components, unless overridden at the component level.\n *\n * Change the locale at runtime as follows:\n * ```ts\n * inject(SCI_LOCALE).set('de-CH');\n * ```\n *\n * Angular includes only `en-US` by default. Register other locales via `registerLocaleData()`, typically in an environment initializer at app startup:\n *\n * ```ts\n * import {bootstrapApplication} from '@angular/platform-browser';\n * import {provideEnvironmentInitializer} from '@angular/core';\n * import {registerLocaleData} from '@angular/common';\n *\n * import localeDeCH from '@angular/common/locales/de-CH';\n * import localeFrCH from '@angular/common/locales/fr-CH';\n * import localeItCH from '@angular/common/locales/it-CH';\n *\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideEnvironmentInitializer(() => {\n * registerLocaleData(localeDeCH);\n * registerLocaleData(localeFrCH);\n * registerLocaleData(localeItCH);\n * }),\n * ],\n * });\n * ```\n */\nexport const SCI_LOCALE = new InjectionToken<WritableSignal<string>>('SCI_LOCALE', {\n providedIn: 'root',\n factory: () => signal(inject(LOCALE_ID)),\n});\n","import {computed, Directive, ElementRef, inject, InjectionToken, input, Signal, signal} from '@angular/core';\nimport {coerceElement} from '@angular/cdk/coercion';\nimport {coerceSignal, MaybeSignal} from './signal.util';\n\n/**\n * Displays element text content as a tooltip when text overflows.\n *\n * Uses the host element text content by default. The content source can be customized via {@link sourceElement} input.\n *\n * Usage:\n *\n * ```html\n * <div sciTooltipOnOverflow>Content</div>\n * ```\n *\n * Can also be used on input elements, displaying a tooltip when the value overflows.\n *\n * Usage:\n *\n * ```html\n * <input sciTooltipOnOverflow>\n * ```\n *\n * Supports appending additional text that is always displayed regardless of whether text overflows.\n *\n * If used as a host directive, configure via the following DI tokens:\n * - {@link TOOLTIP_ON_OVERFLOW_DIRECTIVE_SOURCE_ELEMENT} and\n * - {@link TOOLTIP_ON_OVERFLOW_DIRECTIVE_ADDITIONAL_TEXT}.\n */\n@Directive({\n selector: '[sciTooltipOnOverflow]',\n host: {\n '(mouseenter)': 'onMouseEnter()',\n '(mouseleave)': 'onMouseLeave()',\n '[attr.title]': 'tooltip()',\n },\n})\nexport class SciTooltipOnOverflowDirective {\n\n /**\n * Specifies the element from which to read text content for displaying as tooltip. Defaults to the host element.\n *\n * If used as a host directive, configure an alternative source using {@link TOOLTIP_ON_OVERFLOW_DIRECTIVE_SOURCE_ELEMENT} DI token.\n */\n public readonly sourceElement = input<Element | ElementRef<Element> | undefined>(inject(ElementRef), {alias: 'sciTooltipOnOverflowSourceElement'});\n\n /**\n * Specifies additional text appended to the tooltip.\n *\n * This text is always displayed, regardless of whether text overflows.\n *\n * If used as a host directive, specify additional text via {@link TOOLTIP_ON_OVERFLOW_DIRECTIVE_ADDITIONAL_TEXT} DI token.\n */\n public readonly additionalText = input<string | undefined>(undefined, {alias: 'sciTooltipOnOverflowAdditionalText'});\n\n private readonly _sourceElement = this.computeSourceElement();\n private readonly _additionalText = this.computeAdditionalText();\n private readonly _hasOverflow = signal(false);\n\n protected readonly tooltip = this.computeTooltip();\n\n protected onMouseEnter(): void {\n const sourceElement = this._sourceElement();\n this._hasOverflow.set(!!sourceElement && (sourceElement.scrollWidth > sourceElement.clientWidth || sourceElement.scrollHeight > sourceElement.clientHeight));\n }\n\n protected onMouseLeave(): void {\n this._hasOverflow.set(false);\n }\n\n private computeSourceElement(): Signal<Element | undefined> {\n const sourceElement = coerceSignal(inject(TOOLTIP_ON_OVERFLOW_DIRECTIVE_SOURCE_ELEMENT, {optional: true}) ?? this.sourceElement);\n return computed(() => coerceElement(sourceElement()));\n }\n\n private computeAdditionalText(): Signal<string | undefined> {\n return coerceSignal(inject(TOOLTIP_ON_OVERFLOW_DIRECTIVE_ADDITIONAL_TEXT, {optional: true}) ?? this.additionalText);\n }\n\n private computeTooltip(): Signal<string | undefined> {\n return computed(() => {\n const tooltip = new Array<string>();\n const sourceElement = this._sourceElement();\n\n if (this._hasOverflow()) {\n tooltip.push(sourceElement instanceof HTMLInputElement ? sourceElement.value : sourceElement!.textContent.trim());\n }\n\n if (this._additionalText()?.length) {\n tooltip.push(this._additionalText()!);\n }\n\n return tooltip.join('\\n') || undefined;\n });\n }\n}\n\n/**\n * Specifies the element from which to read text content for displaying as tooltip.\n *\n * Use this token to configure {@link SciTooltipOnOverflowDirective} if used as a host directive. Equivalent to {@link SciTooltipOnOverflowDirective.sourceElement}.\n */\nexport const TOOLTIP_ON_OVERFLOW_DIRECTIVE_SOURCE_ELEMENT = new InjectionToken<MaybeSignal<Element | ElementRef<Element> | undefined>>('TOOLTIP_ON_OVERFLOW_DIRECTIVE_SOURCE_ELEMENT');\n\n/**\n * Specifies additional text appended to the tooltip.\n *\n * Use this token to configure {@link SciTooltipOnOverflowDirective} if used as a host directive. Equivalent to {@link SciTooltipOnOverflowDirective.additionalText}.\n */\nexport const TOOLTIP_ON_OVERFLOW_DIRECTIVE_ADDITIONAL_TEXT = new InjectionToken<MaybeSignal<string | undefined>>('TOOLTIP_ON_OVERFLOW_DIRECTIVE_ADDITIONAL_TEXT');\n","/*\n * Copyright (c) 2018-2026 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\n/*\n * Secondary entrypoint: '@scion/components/common'\n *\n * @see https://github.com/ng-packagr/ng-packagr/blob/master/docs/secondary-entrypoints.md\n */\nexport {coerceSignal, type MaybeSignal, toLazyObservable} from './signal.util';\nexport {ɵcreateDestroyableInjector, ɵassertInInjectionContext, ɵSingleActiveInjectorFactory} from './injector.util';\nexport {type SciComponentDescriptor, SciComponentOutletDirective} from './component-outlet.directive';\nexport {SciAttributesDirective} from './attributes.directive';\nexport {type SciTemplateDescriptor} from './template-descriptor';\nexport {SCI_LOCALE} from './locale';\nexport {SciTooltipOnOverflowDirective, TOOLTIP_ON_OVERFLOW_DIRECTIVE_SOURCE_ELEMENT, TOOLTIP_ON_OVERFLOW_DIRECTIVE_ADDITIONAL_TEXT} from './tooltip-on-overflow.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["ngAssertInInjectionContext"],"mappings":";;;;;AAAA;;;;;;;;AAQG;AA2BG,SAAU,YAAY,CAAI,KAAqB,EAAE,OAAkC,EAAA;IACvF,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,EAAE,eAAe,EAAE;AACpD,QAAA,OAAO,SAAS;IAClB;AACA,IAAA,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AAChD;AAOM,SAAU,gBAAgB,CAAI,MAA+C,EAAE,OAA+B,EAAA;AAClH,IAAA,IAAI,MAAM,KAAK,SAAS,EAAE;AACxB,QAAA,OAAO,SAAS;IAClB;AACA,IAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AACrB,QAAA,OAAO,EAAE,CAAC,MAAM,CAAC;IACnB;IAEA,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC;AACtD,IAAA,OAAO,IAAI,UAAU,CAAC,QAAQ,IAAG;AAC/B,QAAA,MAAM,YAAY,GAAG,MAAM,EAAE;QAC7B,IAAI,gBAAgB,GAAG,IAAI;;AAG3B,QAAA,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC;AAE3B,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,MAAK;AAC5B,YAAA,MAAM,KAAK,GAAG,MAAM,EAAE;YAEtB,SAAS,CAAC,MAAK;AACb,gBAAA,IAAI,CAAC,gBAAgB,IAAI,YAAY,KAAK,KAAK,EAAE;AAC/C,oBAAA,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;gBACtB;gBACA,gBAAgB,GAAG,KAAK;AAC1B,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,iFAAG,QAAQ,EAAE,aAAa,EAAE,IAAI,GAAE;AAEnC,QAAA,OAAO,MAAM,SAAS,CAAC,OAAO,EAAE;AAClC,IAAA,CAAC,CAAC;AACJ;;AC5EA;;;;;;;;AAQG;AAIH;;;;;;;;;;;;;;AAcG;AACG,SAAU,0BAA0B,CAAC,OAAoE,EAAA;IAC7G,MAAM,cAAc,GAAG,OAAO,EAAE,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC;IAC1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAC,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAC,CAAC;;;AAIpH,IAAA,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;;AAGlE,IAAA,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;IACtC,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC;AAC3C,IAAA,QAAQ,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,IAAI,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC;AAC/E,IAAA,OAAO,QAAQ;AACjB;AAEA;;;;;;AAMG;AACG,SAAU,yBAAyB,CAAC,OAAiB,EAAE,OAAe,EAAA;AAC1E,IAAA,IAAI;QACFA,wBAA0B,CAAC,OAAO,CAAC;IACrC;AACA,IAAA,MAAM;AACJ,QAAA,MAAM,KAAK,CAAC,CAAC,CAAA,EAAG,OAAO,CAAC,IAAI,CAAA,gDAAA,CAAkD,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3H;AACF;AAEA;;;;;;AAMG;MACU,4BAA4B,CAAA;AAE/B,IAAA,SAAS;AACT,IAAA,QAAQ;AAEhB,IAAA,WAAA,CAAY,OAAoE,EAAA;QAC9E,IAAI,CAAC,QAAQ,GAAG;YACd,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC;YAC3C,SAAS,EAAE,OAAO,EAAE,SAAS;YAC7B,IAAI,EAAE,OAAO,EAAE,IAAI;SACpB;IACH;AAEA;;AAEG;IACI,MAAM,GAAA;AACX,QAAA,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE;AACzB,QAAA,IAAI,CAAC,SAAS,GAAG,0BAA0B,CAAC,EAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAC,CAAC;QACzI,OAAO,IAAI,CAAC,SAAS;IACvB;AACD;;ACtFD;;;;;;;;AAQG;AAIH;;;;AAIG;MAEU,sBAAsB,CAAA;AAEjC;;;;AAIG;IACa,UAAU,GAAG,KAAK,CAAkE,SAAS,kFAAG,KAAK,EAAE,eAAe,EAAA,CAAE;AAExI,IAAA,WAAA,GAAA;QACE,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,aAA4B;AAC5D,QAAA,MAAM,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,EAAU;AACzE,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC;QAElC,MAAM,CAAC,MAAK;YACV,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE;YAE1C,SAAS,CAAC,MAAK;;AAEb,gBAAA,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC1D,IAAI,EAAE,kBAAkB,CAAC,CAAC,EAAC,IAAI,EAAE,IAAI,EAAC,KAAK,QAAQ,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;;AAGhF,gBAAA,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;oBAClD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE;wBACzC,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,CAAA,EAAG,KAAK,CAAA,CAAE,CAAC;oBAC9C;yBACK;AACH,wBAAA,QAAQ,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC;oBACrC;AACF,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;uGAjCW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAtB,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAtB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBADlC,SAAS;mBAAC,EAAC,QAAQ,EAAE,iBAAiB,EAAC;;;ACjBxC;;;;;;;;AAQG;AAOH;;;;;;;;;;;;;;;;;AAiBG;MAEU,2BAA2B,CAAA;AAEtC;;AAEG;IACa,UAAU,GAAG,KAAK,CAAC,QAAQ,iFAA6C,KAAK,EAAE,oBAAoB,EAAA,CAAE;AAErH,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;QAEjD,MAAM,CAAC,SAAS,IAAG;AACjB,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE;YAEpC,SAAS,CAAC,MAAK;gBACb,MAAM,SAAS,GAAG,UAAU,IAAI,eAAe,CAAC,gBAAgB,EAAE,UAAU,CAAC;gBAC7E,SAAS,CAAC,MAAM,SAAS,EAAE,OAAO,EAAE,CAAC;AACvC,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;uGAlBW,2BAA2B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAA3B,2BAA2B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iCAAA,EAAA,MAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,oBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAA3B,2BAA2B,EAAA,UAAA,EAAA,CAAA;kBADvC,SAAS;mBAAC,EAAC,QAAQ,EAAE,iCAAiC,EAAC;;AAsBxD;;AAEG;AACH,SAAS,eAAe,CAAC,gBAAkC,EAAE,UAAkC,EAAA;;AAE7F,IAAA,MACM,kBAAkB,CAAA;2GAAlB,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,QAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,SAAA,EADD,UAAU,CAAC,SAAS,IAAI,EAAE,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;+FAC3C,kBAAkB,EAAA,UAAA,EAAA,CAAA;sBADvB,SAAS;AAAC,gBAAA,IAAA,EAAA,CAAA,EAAC,SAAS,EAAE,UAAU,CAAC,SAAS,IAAI,EAAE,EAAC;;;AAKlD,IAAA,MACM,iBAAiB,CAAA;AACF,QAAA,QAAQ,GAAG,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC;2GAD3D,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;+FAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,cAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;+FAAjB,iBAAiB,EAAA,UAAA,EAAA,CAAA;sBADtB,SAAS;AAAC,gBAAA,IAAA,EAAA,CAAA,EAAC,IAAI,EAAE,EAAC,SAAS,EAAE,cAAc,EAAC,EAAC;;AAK9C,IAAA,OAAO,gBAAgB,CAAC,eAAe,CAAC,UAAU,CAAC,SAAS,EAAE;AAC5D,QAAA,UAAU,EAAE;YACV,kBAAkB;YAClB,iBAAiB;YACjB,EAAC,IAAI,EAAE,sBAAsB,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,YAAY,CAAC,UAAU,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,EAAC;AACpH,YAAA,GAAG,UAAU,CAAC,UAAU,IAAI,EAAE;AAC/B,SAAA;QACD,QAAQ,EAAE,UAAU,CAAC,QAAQ;QAC7B,QAAQ,EAAE,UAAU,CAAC,QAAQ;AAC9B,KAAA,CAAC;AACH;;AChFD;;;;;;;;AAQG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BG;MACU,UAAU,GAAG,IAAI,cAAc,CAAyB,YAAY,EAAE;AACjF,IAAA,UAAU,EAAE,MAAM;IAClB,OAAO,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACzC,CAAA;;AC3CD;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;MASU,6BAA6B,CAAA;AAExC;;;;AAIG;AACa,IAAA,aAAa,GAAG,KAAK,CAA4C,MAAM,CAAC,UAAU,CAAC,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,eAAA,EAAA,8BAAA,EAAA,CAAA,EAAG,KAAK,EAAE,mCAAmC,EAAA,CAAE;AAElJ;;;;;;AAMG;IACa,cAAc,GAAG,KAAK,CAAqB,SAAS,sFAAG,KAAK,EAAE,oCAAoC,EAAA,CAAE;AAEnG,IAAA,cAAc,GAAG,IAAI,CAAC,oBAAoB,EAAE;AAC5C,IAAA,eAAe,GAAG,IAAI,CAAC,qBAAqB,EAAE;IAC9C,YAAY,GAAG,MAAM,CAAC,KAAK;qFAAC;AAE1B,IAAA,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE;IAExC,YAAY,GAAA;AACpB,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE;QAC3C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,KAAK,aAAa,CAAC,WAAW,GAAG,aAAa,CAAC,WAAW,IAAI,aAAa,CAAC,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IAC9J;IAEU,YAAY,GAAA;AACpB,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;IAC9B;IAEQ,oBAAoB,GAAA;AAC1B,QAAA,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CAAC,4CAA4C,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC;QAChI,OAAO,QAAQ,CAAC,MAAM,aAAa,CAAC,aAAa,EAAE,CAAC,CAAC;IACvD;IAEQ,qBAAqB,GAAA;AAC3B,QAAA,OAAO,YAAY,CAAC,MAAM,CAAC,6CAA6C,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC;IACrH;IAEQ,cAAc,GAAA;QACpB,OAAO,QAAQ,CAAC,MAAK;AACnB,YAAA,MAAM,OAAO,GAAG,IAAI,KAAK,EAAU;AACnC,YAAA,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE;AAE3C,YAAA,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE;gBACvB,OAAO,CAAC,IAAI,CAAC,aAAa,YAAY,gBAAgB,GAAG,aAAa,CAAC,KAAK,GAAG,aAAc,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YACnH;AAEA,YAAA,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE,MAAM,EAAE;gBAClC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAG,CAAC;YACvC;YAEA,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS;AACxC,QAAA,CAAC,CAAC;IACJ;uGAzDW,6BAA6B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAA7B,6BAA6B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,mCAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,oCAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,YAAA,EAAA,gBAAA,EAAA,YAAA,EAAA,gBAAA,EAAA,EAAA,UAAA,EAAA,EAAA,YAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAA7B,6BAA6B,EAAA,UAAA,EAAA,CAAA;kBARzC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,wBAAwB;AAClC,oBAAA,IAAI,EAAE;AACJ,wBAAA,cAAc,EAAE,gBAAgB;AAChC,wBAAA,cAAc,EAAE,gBAAgB;AAChC,wBAAA,cAAc,EAAE,WAAW;AAC5B,qBAAA;AACF,iBAAA;;AA6DD;;;;AAIG;MACU,4CAA4C,GAAG,IAAI,cAAc,CAAyD,8CAA8C;AAErL;;;;AAIG;MACU,6CAA6C,GAAG,IAAI,cAAc,CAAkC,+CAA+C;;AC7GhK;;;;;;;;AAQG;AAEH;;;;AAIG;;ACdH;;AAEG;;"}
|
|
@@ -5,7 +5,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
|
5
5
|
import { subscribeIn, observeIn } from '@scion/toolkit/operators';
|
|
6
6
|
import { coerceElement } from '@angular/cdk/coercion';
|
|
7
7
|
import { Objects } from '@scion/toolkit/util';
|
|
8
|
-
import {
|
|
8
|
+
import { ɵassertInInjectionContext as _assertInInjectionContext } from '@scion/components/common';
|
|
9
9
|
|
|
10
10
|
/*
|
|
11
11
|
* Copyright (c) 2018-2024 Swiss Federal Railways
|
|
@@ -84,7 +84,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
84
84
|
function dimension(elementLike, options) {
|
|
85
85
|
assertNotInReactiveContext(dimension, 'Invoking `dimension` causes new subscriptions every time. Move `dimension` outside of the reactive context and read the signal value where needed.');
|
|
86
86
|
if (!options?.injector) {
|
|
87
|
-
|
|
87
|
+
_assertInInjectionContext(dimension, 'Must be called within an injection context, or an explicit `Injector` passed via options. Stops tracking the dimension when the injection context is destroyed.');
|
|
88
88
|
}
|
|
89
89
|
const injector = options?.injector ?? inject(Injector);
|
|
90
90
|
const zone = injector.get(NgZone);
|
|
@@ -143,7 +143,7 @@ function dimension(elementLike, options) {
|
|
|
143
143
|
function boundingClientRect(elementLike, options) {
|
|
144
144
|
assertNotInReactiveContext(boundingClientRect, 'Invoking `boundingClientRect` causes new subscriptions every time. Move `boundingClientRect` outside of the reactive context and read the signal value where needed.');
|
|
145
145
|
if (!options?.injector) {
|
|
146
|
-
|
|
146
|
+
_assertInInjectionContext(boundingClientRect, 'Must be called within an injection context, or an explicit `Injector` passed via options. Stops tracking the bounding box when the injection context is destroyed.');
|
|
147
147
|
}
|
|
148
148
|
const injector = options?.injector ?? inject(Injector);
|
|
149
149
|
const zone = injector.get(NgZone);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scion-components-dimension.mjs","sources":["../../../../projects/scion/components/dimension/src/dimension.directive.ts","../../../../projects/scion/components/dimension/src/dimension.signal.ts","../../../../projects/scion/components/dimension/src/bounding-client-rect.signal.ts","../../../../projects/scion/components/dimension/src/public_api.ts","../../../../projects/scion/components/dimension/src/scion-components-dimension.ts"],"sourcesContent":["/*\n * Copyright (c) 2018-2024 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {Directive, ElementRef, inject, input, NgZone, output, ɵZONELESS_ENABLED} from '@angular/core';\nimport {fromResize$} from '@scion/toolkit/observable';\nimport {takeUntilDestroyed} from '@angular/core/rxjs-interop';\nimport {observeIn, subscribeIn} from '@scion/toolkit/operators';\nimport {SciDimension} from './dimension';\n\n/**\n * Observes the size of the host element.\n *\n * ---\n * Usage:\n *\n * ```html\n * <div sciDimension (sciDimensionChange)=\"onDimensionChange($event)\"></div>\n * ```\n */\n@Directive({\n selector: '[sciDimension]',\n})\nexport class SciDimensionDirective {\n\n /**\n * Controls if to output outside the Angular zone. Defaults to `false`.\n */\n public readonly emitOutsideAngular = input(false);\n\n /**\n * Outputs the size of the element.\n */\n public readonly dimensionChange = output<SciDimension>({alias: 'sciDimensionChange'});\n\n constructor() {\n const host = inject(ElementRef).nativeElement as HTMLElement;\n const zone = inject(NgZone);\n const zonelessEnabled = inject(ɵZONELESS_ENABLED);\n\n fromResize$(host)\n .pipe(\n // Avoid triggering change detection cycle.\n subscribeIn(fn => zone.runOutsideAngular(fn)),\n // Run in animation frame to prevent 'ResizeObserver loop completed with undelivered notifications' error.\n // Do not use `animationFrameScheduler` because the scheduler does not necessarily execute in the current execution context, such as inside or outside Angular.\n // The scheduler always executes tasks in the context (e.g. zone) where the scheduler was first used in the application.\n observeIn(fn => requestAnimationFrame(fn)),\n observeIn(fn => this.emitOutsideAngular() ? fn() : zone.run(fn)),\n takeUntilDestroyed(),\n )\n .subscribe(() => {\n if (!zonelessEnabled) {\n // Assert Angular zone.\n this.emitOutsideAngular() ? NgZone.assertNotInAngularZone() : NgZone.assertInAngularZone();\n }\n\n this.dimensionChange.emit({\n clientWidth: host.clientWidth,\n offsetWidth: host.offsetWidth,\n clientHeight: host.clientHeight,\n offsetHeight: host.offsetHeight,\n element: host,\n });\n });\n }\n}\n","/*\n * Copyright (c) 2018-2024 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {assertNotInReactiveContext, computed, effect, ElementRef, inject, Injector, isSignal, NgZone, signal, Signal, untracked} from '@angular/core';\nimport {SciDimension} from './dimension';\nimport {coerceElement} from '@angular/cdk/coercion';\nimport {Objects} from '@scion/toolkit/util';\nimport {fromResize$} from '@scion/toolkit/observable';\nimport {observeIn, subscribeIn} from '@scion/toolkit/operators';\nimport {assertInInjectionContext} from '@scion/components/common';\n\n/**\n * Creates a signal observing the size of an element.\n *\n * The element can be passed as a signal, enabling observation of view children in the component constructor.\n *\n * The signal subscribes to the native {@link ResizeObserver} to monitor element size changes. Destroying the injection context will unsubscribe the observer.\n *\n * Usage:\n * - Must be called within an injection context or an injector provided. Destroying the injector will unsubscribe the signal.\n * - Must not be called within a reactive context to avoid repeated subscriptions.\n */\nexport function dimension(elementLike: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement>>, options?: {injector?: Injector}): Signal<SciDimension>;\nexport function dimension(elementLike: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | undefined>, options?: {injector?: Injector}): Signal<SciDimension | undefined>;\nexport function dimension(elementLike: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | undefined>, options?: {injector?: Injector}): Signal<SciDimension | undefined> {\n assertNotInReactiveContext(dimension, 'Invoking `dimension` causes new subscriptions every time. Move `dimension` outside of the reactive context and read the signal value where needed.');\n if (!options?.injector) {\n assertInInjectionContext(dimension, 'Must be called within an injection context, or an explicit `Injector` passed via options. Stops tracking the dimension when the injection context is destroyed.');\n }\n\n const injector = options?.injector ?? inject(Injector);\n const zone = injector.get(NgZone);\n const element = computed(() => coerceElement(isSignal(elementLike) ? elementLike() : elementLike));\n const onResize = signal<void>(undefined, {equal: () => false});\n\n // Subscribe to element size changes.\n effect(onCleanup => {\n const el = element();\n if (!el) {\n return;\n }\n\n untracked(() => {\n const subscription = fromResize$(el)\n .pipe(\n // Avoid triggering change detection cycle.\n subscribeIn(fn => zone.runOutsideAngular(fn)),\n // Run in animation frame to prevent 'ResizeObserver loop completed with undelivered notifications' error.\n // Do not use `animationFrameScheduler` because the scheduler does not necessarily execute in the current execution context, such as inside or outside Angular.\n // The scheduler always executes tasks in the context (e.g. zone) where the scheduler was first used in the application.\n observeIn(fn => requestAnimationFrame(fn)),\n )\n .subscribe(() => {\n NgZone.assertNotInAngularZone();\n onResize.set();\n });\n onCleanup(() => subscription.unsubscribe());\n });\n }, {injector});\n\n // Create signal that recomputes each time the size changes.\n return computed(() => {\n const el = element();\n if (!el) {\n return undefined;\n }\n\n // Track element size.\n onResize();\n\n return {\n clientWidth: el.clientWidth,\n offsetWidth: el.offsetWidth,\n clientHeight: el.clientHeight,\n offsetHeight: el.offsetHeight,\n element: el,\n };\n }, {equal: Objects.isEqual});\n}\n","/*\n * Copyright (c) 2018-2024 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {assertNotInReactiveContext, computed, effect, ElementRef, inject, Injector, isSignal, NgZone, signal, Signal, untracked} from '@angular/core';\nimport {coerceElement} from '@angular/cdk/coercion';\nimport {fromBoundingClientRect$} from '@scion/toolkit/observable';\nimport {subscribeIn} from '@scion/toolkit/operators';\nimport {assertInInjectionContext} from '@scion/components/common';\n\n/**\n * Creates a signal observing the bounding box of an element.\n *\n * The bounding box includes the element's position relative to the top-left of the viewport and its size.\n * Refer to https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect for more details.\n *\n * The element can be passed as a signal, enabling observation of view children in the component constructor.\n *\n * There is no native browser API to observe the position of an element. The signal uses {@link IntersectionObserver} and\n * {@link ResizeObserver} to detect position changes. For tracking only size changes, use the {@link dimension} signal instead.\n *\n * Usage:\n * - Must be called within an injection context or an injector provided. Destroying the injector will unsubscribe the signal.\n * - Must not be called within a reactive context to avoid repeated subscriptions.\n * - The element and the document root (`<html>`) must be positioned `relative` or `absolute`. If not, positioning is changed to `relative`.\n */\nexport function boundingClientRect(elementLike: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement>>, options?: {injector?: Injector}): Signal<DOMRect>;\nexport function boundingClientRect(elementLike: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | undefined>, options?: {injector?: Injector}): Signal<DOMRect | undefined>;\nexport function boundingClientRect(elementLike: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | undefined>, options?: {injector?: Injector}): Signal<DOMRect | undefined> {\n assertNotInReactiveContext(boundingClientRect, 'Invoking `boundingClientRect` causes new subscriptions every time. Move `boundingClientRect` outside of the reactive context and read the signal value where needed.');\n if (!options?.injector) {\n assertInInjectionContext(boundingClientRect, 'Must be called within an injection context, or an explicit `Injector` passed via options. Stops tracking the bounding box when the injection context is destroyed.');\n }\n\n const injector = options?.injector ?? inject(Injector);\n const zone = injector.get(NgZone);\n const element = computed(() => coerceElement(isSignal(elementLike) ? elementLike() : elementLike));\n const onBoundingBoxChange = signal<void>(undefined, {equal: () => false});\n\n // Subscribe to element bounding box changes.\n effect(onCleanup => {\n const el = element();\n if (!el) {\n return;\n }\n\n untracked(() => {\n const subscription = fromBoundingClientRect$(el)\n // Avoid triggering change detection cycle.\n .pipe(subscribeIn(fn => zone.runOutsideAngular(fn)))\n .subscribe(() => {\n NgZone.assertNotInAngularZone();\n onBoundingBoxChange.set();\n });\n onCleanup(() => subscription.unsubscribe());\n });\n }, {injector});\n\n // Create signal that recomputes each time the bounding box changes.\n return computed(() => {\n const el = element();\n if (!el) {\n return undefined;\n }\n\n // Track bounding box.\n onBoundingBoxChange();\n\n return el.getBoundingClientRect();\n }, {equal: isEqualDomRect});\n}\n\nfunction isEqualDomRect(a: DOMRect | undefined, b: DOMRect | undefined): boolean {\n return a?.top === b?.top && a?.right === b?.right && a?.bottom === b?.bottom && a?.left === b?.left;\n}\n","/*\n * Copyright (c) 2018-2019 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\n/*\n * Secondary entrypoint: '@scion/components/dimension'\n *\n * @see https://github.com/ng-packagr/ng-packagr/blob/master/docs/secondary-entrypoints.md\n */\nexport {SciDimensionDirective} from './dimension.directive';\nexport {dimension} from './dimension.signal';\nexport {boundingClientRect} from './bounding-client-rect.signal';\nexport {type SciDimension} from './dimension';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["ɵZONELESS_ENABLED"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scion-components-dimension.mjs","sources":["../../../../projects/scion/components/dimension/src/dimension.directive.ts","../../../../projects/scion/components/dimension/src/dimension.signal.ts","../../../../projects/scion/components/dimension/src/bounding-client-rect.signal.ts","../../../../projects/scion/components/dimension/src/public_api.ts","../../../../projects/scion/components/dimension/src/scion-components-dimension.ts"],"sourcesContent":["/*\n * Copyright (c) 2018-2024 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {Directive, ElementRef, inject, input, NgZone, output, ɵZONELESS_ENABLED} from '@angular/core';\nimport {fromResize$} from '@scion/toolkit/observable';\nimport {takeUntilDestroyed} from '@angular/core/rxjs-interop';\nimport {observeIn, subscribeIn} from '@scion/toolkit/operators';\nimport {SciDimension} from './dimension';\n\n/**\n * Observes the size of the host element.\n *\n * ---\n * Usage:\n *\n * ```html\n * <div sciDimension (sciDimensionChange)=\"onDimensionChange($event)\"></div>\n * ```\n */\n@Directive({\n selector: '[sciDimension]',\n})\nexport class SciDimensionDirective {\n\n /**\n * Controls if to output outside the Angular zone. Defaults to `false`.\n */\n public readonly emitOutsideAngular = input(false);\n\n /**\n * Outputs the size of the element.\n */\n public readonly dimensionChange = output<SciDimension>({alias: 'sciDimensionChange'});\n\n constructor() {\n const host = inject(ElementRef).nativeElement as HTMLElement;\n const zone = inject(NgZone);\n const zonelessEnabled = inject(ɵZONELESS_ENABLED);\n\n fromResize$(host)\n .pipe(\n // Avoid triggering change detection cycle.\n subscribeIn(fn => zone.runOutsideAngular(fn)),\n // Run in animation frame to prevent 'ResizeObserver loop completed with undelivered notifications' error.\n // Do not use `animationFrameScheduler` because the scheduler does not necessarily execute in the current execution context, such as inside or outside Angular.\n // The scheduler always executes tasks in the context (e.g. zone) where the scheduler was first used in the application.\n observeIn(fn => requestAnimationFrame(fn)),\n observeIn(fn => this.emitOutsideAngular() ? fn() : zone.run(fn)),\n takeUntilDestroyed(),\n )\n .subscribe(() => {\n if (!zonelessEnabled) {\n // Assert Angular zone.\n this.emitOutsideAngular() ? NgZone.assertNotInAngularZone() : NgZone.assertInAngularZone();\n }\n\n this.dimensionChange.emit({\n clientWidth: host.clientWidth,\n offsetWidth: host.offsetWidth,\n clientHeight: host.clientHeight,\n offsetHeight: host.offsetHeight,\n element: host,\n });\n });\n }\n}\n","/*\n * Copyright (c) 2018-2024 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {assertNotInReactiveContext, computed, effect, ElementRef, inject, Injector, isSignal, NgZone, signal, Signal, untracked} from '@angular/core';\nimport {SciDimension} from './dimension';\nimport {coerceElement} from '@angular/cdk/coercion';\nimport {Objects} from '@scion/toolkit/util';\nimport {fromResize$} from '@scion/toolkit/observable';\nimport {observeIn, subscribeIn} from '@scion/toolkit/operators';\nimport {ɵassertInInjectionContext} from '@scion/components/common';\n\n/**\n * Creates a signal observing the size of an element.\n *\n * The element can be passed as a signal, enabling observation of view children in the component constructor.\n *\n * The signal subscribes to the native {@link ResizeObserver} to monitor element size changes. Destroying the injection context will unsubscribe the observer.\n *\n * Usage:\n * - Must be called within an injection context or an injector provided. Destroying the injector will unsubscribe the signal.\n * - Must not be called within a reactive context to avoid repeated subscriptions.\n */\nexport function dimension(elementLike: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement>>, options?: {injector?: Injector}): Signal<SciDimension>;\nexport function dimension(elementLike: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | undefined>, options?: {injector?: Injector}): Signal<SciDimension | undefined>;\nexport function dimension(elementLike: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | undefined>, options?: {injector?: Injector}): Signal<SciDimension | undefined> {\n assertNotInReactiveContext(dimension, 'Invoking `dimension` causes new subscriptions every time. Move `dimension` outside of the reactive context and read the signal value where needed.');\n if (!options?.injector) {\n ɵassertInInjectionContext(dimension, 'Must be called within an injection context, or an explicit `Injector` passed via options. Stops tracking the dimension when the injection context is destroyed.');\n }\n\n const injector = options?.injector ?? inject(Injector);\n const zone = injector.get(NgZone);\n const element = computed(() => coerceElement(isSignal(elementLike) ? elementLike() : elementLike));\n const onResize = signal<void>(undefined, {equal: () => false});\n\n // Subscribe to element size changes.\n effect(onCleanup => {\n const el = element();\n if (!el) {\n return;\n }\n\n untracked(() => {\n const subscription = fromResize$(el)\n .pipe(\n // Avoid triggering change detection cycle.\n subscribeIn(fn => zone.runOutsideAngular(fn)),\n // Run in animation frame to prevent 'ResizeObserver loop completed with undelivered notifications' error.\n // Do not use `animationFrameScheduler` because the scheduler does not necessarily execute in the current execution context, such as inside or outside Angular.\n // The scheduler always executes tasks in the context (e.g. zone) where the scheduler was first used in the application.\n observeIn(fn => requestAnimationFrame(fn)),\n )\n .subscribe(() => {\n NgZone.assertNotInAngularZone();\n onResize.set();\n });\n onCleanup(() => subscription.unsubscribe());\n });\n }, {injector});\n\n // Create signal that recomputes each time the size changes.\n return computed(() => {\n const el = element();\n if (!el) {\n return undefined;\n }\n\n // Track element size.\n onResize();\n\n return {\n clientWidth: el.clientWidth,\n offsetWidth: el.offsetWidth,\n clientHeight: el.clientHeight,\n offsetHeight: el.offsetHeight,\n element: el,\n };\n }, {equal: Objects.isEqual});\n}\n","/*\n * Copyright (c) 2018-2024 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\nimport {assertNotInReactiveContext, computed, effect, ElementRef, inject, Injector, isSignal, NgZone, signal, Signal, untracked} from '@angular/core';\nimport {coerceElement} from '@angular/cdk/coercion';\nimport {fromBoundingClientRect$} from '@scion/toolkit/observable';\nimport {subscribeIn} from '@scion/toolkit/operators';\nimport {ɵassertInInjectionContext} from '@scion/components/common';\n\n/**\n * Creates a signal observing the bounding box of an element.\n *\n * The bounding box includes the element's position relative to the top-left of the viewport and its size.\n * Refer to https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect for more details.\n *\n * The element can be passed as a signal, enabling observation of view children in the component constructor.\n *\n * There is no native browser API to observe the position of an element. The signal uses {@link IntersectionObserver} and\n * {@link ResizeObserver} to detect position changes. For tracking only size changes, use the {@link dimension} signal instead.\n *\n * Usage:\n * - Must be called within an injection context or an injector provided. Destroying the injector will unsubscribe the signal.\n * - Must not be called within a reactive context to avoid repeated subscriptions.\n * - The element and the document root (`<html>`) must be positioned `relative` or `absolute`. If not, positioning is changed to `relative`.\n */\nexport function boundingClientRect(elementLike: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement>>, options?: {injector?: Injector}): Signal<DOMRect>;\nexport function boundingClientRect(elementLike: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | undefined>, options?: {injector?: Injector}): Signal<DOMRect | undefined>;\nexport function boundingClientRect(elementLike: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | undefined>, options?: {injector?: Injector}): Signal<DOMRect | undefined> {\n assertNotInReactiveContext(boundingClientRect, 'Invoking `boundingClientRect` causes new subscriptions every time. Move `boundingClientRect` outside of the reactive context and read the signal value where needed.');\n if (!options?.injector) {\n ɵassertInInjectionContext(boundingClientRect, 'Must be called within an injection context, or an explicit `Injector` passed via options. Stops tracking the bounding box when the injection context is destroyed.');\n }\n\n const injector = options?.injector ?? inject(Injector);\n const zone = injector.get(NgZone);\n const element = computed(() => coerceElement(isSignal(elementLike) ? elementLike() : elementLike));\n const onBoundingBoxChange = signal<void>(undefined, {equal: () => false});\n\n // Subscribe to element bounding box changes.\n effect(onCleanup => {\n const el = element();\n if (!el) {\n return;\n }\n\n untracked(() => {\n const subscription = fromBoundingClientRect$(el)\n // Avoid triggering change detection cycle.\n .pipe(subscribeIn(fn => zone.runOutsideAngular(fn)))\n .subscribe(() => {\n NgZone.assertNotInAngularZone();\n onBoundingBoxChange.set();\n });\n onCleanup(() => subscription.unsubscribe());\n });\n }, {injector});\n\n // Create signal that recomputes each time the bounding box changes.\n return computed(() => {\n const el = element();\n if (!el) {\n return undefined;\n }\n\n // Track bounding box.\n onBoundingBoxChange();\n\n return el.getBoundingClientRect();\n }, {equal: isEqualDomRect});\n}\n\nfunction isEqualDomRect(a: DOMRect | undefined, b: DOMRect | undefined): boolean {\n return a?.top === b?.top && a?.right === b?.right && a?.bottom === b?.bottom && a?.left === b?.left;\n}\n","/*\n * Copyright (c) 2018-2019 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier: EPL-2.0\n */\n\n/*\n * Secondary entrypoint: '@scion/components/dimension'\n *\n * @see https://github.com/ng-packagr/ng-packagr/blob/master/docs/secondary-entrypoints.md\n */\nexport {SciDimensionDirective} from './dimension.directive';\nexport {dimension} from './dimension.signal';\nexport {boundingClientRect} from './bounding-client-rect.signal';\nexport {type SciDimension} from './dimension';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["ɵZONELESS_ENABLED","ɵassertInInjectionContext"],"mappings":"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"}
|