@scion/components 22.1.0 → 22.3.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 (43) hide show
  1. package/_index.scss +75 -5
  2. package/common/package.json +4 -0
  3. package/design/_theming.scss +25 -10
  4. package/design/components/_scion-component-dark-tokens.scss +153 -0
  5. package/design/components/_scion-component-light-tokens.scss +153 -0
  6. package/design/icons/_scion-icon-font.scss +50 -0
  7. package/design/themes/_scion-dark-theme.scss +2 -7
  8. package/design/themes/_scion-light-theme.scss +3 -8
  9. package/fesm2022/scion-components-common.mjs +251 -0
  10. package/fesm2022/scion-components-common.mjs.map +1 -0
  11. package/fesm2022/scion-components-dimension.mjs +7 -6
  12. package/fesm2022/scion-components-dimension.mjs.map +1 -1
  13. package/fesm2022/scion-components-icon.mjs +380 -0
  14. package/fesm2022/scion-components-icon.mjs.map +1 -0
  15. package/fesm2022/scion-components-menu.mjs +3271 -0
  16. package/fesm2022/scion-components-menu.mjs.map +1 -0
  17. package/fesm2022/scion-components-sashbox.mjs +21 -21
  18. package/fesm2022/scion-components-sashbox.mjs.map +1 -1
  19. package/fesm2022/scion-components-splitter.mjs +16 -13
  20. package/fesm2022/scion-components-splitter.mjs.map +1 -1
  21. package/fesm2022/scion-components-table.mjs +2265 -0
  22. package/fesm2022/scion-components-table.mjs.map +1 -0
  23. package/fesm2022/scion-components-text.mjs +322 -0
  24. package/fesm2022/scion-components-text.mjs.map +1 -0
  25. package/fesm2022/scion-components-throbber.mjs +15 -15
  26. package/fesm2022/scion-components-throbber.mjs.map +1 -1
  27. package/fesm2022/scion-components-viewport.mjs +142 -125
  28. package/fesm2022/scion-components-viewport.mjs.map +1 -1
  29. package/icon/package.json +4 -0
  30. package/menu/package.json +4 -0
  31. package/package.json +22 -2
  32. package/table/package.json +4 -0
  33. package/text/package.json +4 -0
  34. package/types/scion-components-common.d.ts +185 -0
  35. package/types/scion-components-icon.d.ts +146 -0
  36. package/types/scion-components-menu.d.ts +1922 -0
  37. package/types/scion-components-sashbox.d.ts +4 -2
  38. package/types/scion-components-splitter.d.ts +4 -3
  39. package/types/scion-components-table.d.ts +577 -0
  40. package/types/scion-components-text.d.ts +131 -0
  41. package/types/scion-components-viewport.d.ts +32 -39
  42. package/viewport/scrollbar/_scrollbar.scss +4 -4
  43. package/design/components/_scion-component-tokens.scss +0 -48
@@ -1,15 +1,16 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, DOCUMENT, NgZone, Injectable, input, ElementRef, Renderer2, effect, untracked, Directive, DestroyRef, viewChild, computed, signal, Component, output, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
3
- import { fromEvent, race, tap, merge, finalize, timer, exhaustMap, of, concatWith, mergeWith } from 'rxjs';
2
+ import { inject, DOCUMENT, NgZone, Injectable, input, ElementRef, Renderer2, computed, effect, untracked, Directive, DestroyRef, viewChild, signal, Component, output, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
3
+ import { coerceElement } from '@angular/cdk/coercion';
4
+ import { fromEvent, race, tap, merge, finalize, timer, exhaustMap, of, concatWith, mergeWith, switchMap as switchMap$1, concat, map as map$1 } from 'rxjs';
4
5
  import { debounceTime, startWith, map, distinctUntilChanged, takeUntil, withLatestFrom, switchMap } from 'rxjs/operators';
5
- import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
+ import { toSignal, takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
6
7
  import { subscribeIn } from '@scion/toolkit/operators';
7
- import { coerceElement } from '@angular/cdk/coercion';
8
8
  import { fromResize$, fromMutation$ } from '@scion/toolkit/observable';
9
+ import { isBetween, clamp } from '@scion/toolkit/util';
9
10
  import { CdkScrollable } from '@angular/cdk/scrolling';
10
11
 
11
12
  /*
12
- * Copyright (c) 2018-2024 Swiss Federal Railways
13
+ * Copyright (c) 2018-2026 Swiss Federal Railways
13
14
  *
14
15
  * This program and the accompanying materials are made
15
16
  * available under the terms of the Eclipse Public License 2.0
@@ -17,25 +18,27 @@ import { CdkScrollable } from '@angular/cdk/scrolling';
17
18
  *
18
19
  * SPDX-License-Identifier: EPL-2.0
19
20
  */
20
- /**
21
- * Provides the native scrollbar tracksize.
22
- */
23
- class SciNativeScrollbarTrackSizeProvider {
21
+ /** @inheritDoc */
22
+ class ɵSciNativeScrollbarTrackSizeProvider {
24
23
  _document = inject(DOCUMENT);
25
- _zone = inject(NgZone);
26
- /**
27
- * Provides the track size of the native scrollbar, or `null` if the native scrollbars sit on top of the content.
28
- */
29
- trackSize;
30
- constructor() {
31
- this.trackSize = this.createNativeScrollbarTrackSizeSignal();
24
+ /** @inheritDoc */
25
+ trackSize = this.computeNativeScrollbarTrackSize();
26
+ computeNativeScrollbarTrackSize() {
27
+ // We compute the size of the native scrollbar track when the browser fires the onresize window event.
28
+ // This event is also fired on page zoom or when displaying a hidden document. Hidden documents do not have
29
+ // a scrollbar track size until being displayed, e.g., after showing hidden iframes.
30
+ const zone = inject(NgZone);
31
+ const trackSize$ = fromEvent(window, 'resize')
32
+ .pipe(subscribeIn(fn => zone.runOutsideAngular(fn)), debounceTime(5), startWith(null), // trigger the initial computation
33
+ map(() => this.calculateTrackSize()), distinctUntilChanged((t1, t2) => t1?.hScrollbarTrackHeight === t2?.hScrollbarTrackHeight && t1?.vScrollbarTrackWidth === t2?.vScrollbarTrackWidth));
34
+ return toSignal(trackSize$, { initialValue: null });
32
35
  }
33
36
  /**
34
37
  * Computes the native scrollbar track size.
35
38
  *
36
39
  * @returns native track size, or `null` if the native scrollbars sit on top of the content.
37
40
  */
38
- computeTrackSize() {
41
+ calculateTrackSize() {
39
42
  // Create temporary viewport and viewport client with native scrollbars to compute the scrolltrack width.
40
43
  const viewportDiv = this._document.createElement('div');
41
44
  setStyle(viewportDiv, {
@@ -68,22 +71,12 @@ class SciNativeScrollbarTrackSizeProvider {
68
71
  }
69
72
  return trackSize;
70
73
  }
71
- createNativeScrollbarTrackSizeSignal() {
72
- // We compute the size of the native scrollbar track when the browser fires the onresize window event.
73
- // This event is also fired on page zoom or when displaying a hidden document. Hidden documents do not have
74
- // a scrollbar track size until being displayed, e.g., after showing hidden iframes.
75
- const trackSize$ = fromEvent(window, 'resize')
76
- .pipe(subscribeIn(fn => this._zone.runOutsideAngular(fn)), debounceTime(5), startWith(null), // trigger the initial computation
77
- map(() => this.computeTrackSize()), distinctUntilChanged((t1, t2) => t1?.hScrollbarTrackHeight === t2?.hScrollbarTrackHeight && t1?.vScrollbarTrackWidth === t2?.vScrollbarTrackWidth));
78
- return toSignal(trackSize$, { initialValue: null });
79
- }
80
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
81
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, providedIn: 'root' });
74
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: ɵSciNativeScrollbarTrackSizeProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
75
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: ɵSciNativeScrollbarTrackSizeProvider });
82
76
  }
83
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, decorators: [{
84
- type: Injectable,
85
- args: [{ providedIn: 'root' }]
86
- }], ctorParameters: () => [] });
77
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: ɵSciNativeScrollbarTrackSizeProvider, decorators: [{
78
+ type: Injectable
79
+ }] });
87
80
  /**
88
81
  * Applies the given style(s) to the given element.
89
82
  *
@@ -96,6 +89,27 @@ function setStyle(element, styles) {
96
89
  Object.entries(styles).forEach(([name, value]) => element.style.setProperty(name, value));
97
90
  }
98
91
 
92
+ /*
93
+ * Copyright (c) 2018-2026 Swiss Federal Railways
94
+ *
95
+ * This program and the accompanying materials are made
96
+ * available under the terms of the Eclipse Public License 2.0
97
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
98
+ *
99
+ * SPDX-License-Identifier: EPL-2.0
100
+ */
101
+ /**
102
+ * Provides the native scrollbar tracksize.
103
+ */
104
+ class SciNativeScrollbarTrackSizeProvider {
105
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
106
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, providedIn: 'root', useClass: ɵSciNativeScrollbarTrackSizeProvider });
107
+ }
108
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, decorators: [{
109
+ type: Injectable,
110
+ args: [{ providedIn: 'root', useClass: ɵSciNativeScrollbarTrackSizeProvider }]
111
+ }] });
112
+
99
113
  /*
100
114
  * Copyright (c) 2018-2019 Swiss Federal Railways
101
115
  *
@@ -115,16 +129,37 @@ function setStyle(element, styles) {
115
129
  * This directive expects its host element to be the only child in document flow in its parent DOM element. It makes the host element
116
130
  * fill up the entire space (width and height set to 100%). The parent element must have its CSS `overflow` property set to `hidden`
117
131
  * to hide the pushed out native scrollbars.
132
+ *
133
+ * This directive provides the `isNativeScrollbarCropped` signal, which indicates whether native scrollbars are pushed out of the viewport element.
134
+ * In templates, access it via the exported template reference variable `sciScrollable`.
135
+ *
136
+ * ```html
137
+ * <div sciScrollable #sciScrollable="sciScrollable" #viewport>
138
+ * content
139
+ * </div>
140
+ *
141
+ * <!-- Render scrollbars only if native scrollbars are pushed out of the viewport element. -->
142
+ * @if (sciScrollable.isNativeScrollbarCropped()) {
143
+ * <sci-scrollbar [viewport]="viewport" direction="vscroll"/>
144
+ * <sci-scrollbar [viewport]="viewport" direction="hscroll"/>
145
+ * }
146
+ * ```
118
147
  */
119
148
  class SciScrollableDirective {
120
149
  /**
121
150
  * Controls whether to display native scrollbars.
151
+ *
122
152
  * Has no effect if the native scrollbar sits on top of the content, e.g. in OS X.
123
153
  */
124
154
  displayNativeScrollbar = input(false, { ...(ngDevMode ? { debugName: "displayNativeScrollbar" } : /* istanbul ignore next */ {}), alias: 'sciScrollableDisplayNativeScrollbar' });
125
155
  _host = inject((ElementRef)).nativeElement;
126
156
  _renderer = inject(Renderer2);
127
157
  _nativeScrollbarTrackSizeProvider = inject(SciNativeScrollbarTrackSizeProvider);
158
+ /**
159
+ * Indicates whether native scrollbars are pushed out of the viewport element.
160
+ */
161
+ isNativeScrollbarCropped = computed(() => !this.displayNativeScrollbar() && this._nativeScrollbarTrackSizeProvider.trackSize() !== null, /* @ts-ignore */
162
+ ...(ngDevMode ? [{ debugName: "isNativeScrollbarCropped" }] : /* istanbul ignore next */ []));
128
163
  constructor() {
129
164
  this.controlDisplayOfNativeScrollbar();
130
165
  }
@@ -133,14 +168,9 @@ class SciScrollableDirective {
133
168
  */
134
169
  controlDisplayOfNativeScrollbar() {
135
170
  effect(() => {
136
- const displayNativeScrollbar = this.displayNativeScrollbar();
137
- if (displayNativeScrollbar) {
138
- untracked(() => this.useNativeScrollbars());
139
- return;
140
- }
141
- const nativeScrollbarTrackSize = this._nativeScrollbarTrackSizeProvider.trackSize();
142
- if (nativeScrollbarTrackSize) {
143
- untracked(() => this.shiftNativeScrollbars(nativeScrollbarTrackSize));
171
+ if (this.isNativeScrollbarCropped()) {
172
+ const trackSize = this._nativeScrollbarTrackSizeProvider.trackSize();
173
+ untracked(() => this.shiftNativeScrollbars(trackSize));
144
174
  }
145
175
  else {
146
176
  untracked(() => this.useNativeScrollbars());
@@ -162,24 +192,27 @@ class SciScrollableDirective {
162
192
  /**
163
193
  * Shifts the native scrollbars out of the visible viewport area.
164
194
  */
165
- shiftNativeScrollbars(nativeScrollbarTrackSize) {
195
+ shiftNativeScrollbars(trackSize) {
166
196
  this.setStyle(this._host, {
167
197
  overflow: 'scroll',
168
- width: `calc(100% + ${nativeScrollbarTrackSize.vScrollbarTrackWidth}px`,
169
- height: `calc(100% + ${nativeScrollbarTrackSize.hScrollbarTrackHeight}px`,
170
- marginRight: `-${nativeScrollbarTrackSize.vScrollbarTrackWidth}px`,
171
- marginBottom: `-${nativeScrollbarTrackSize.hScrollbarTrackHeight}px`,
198
+ width: `calc(100% + ${trackSize.vScrollbarTrackWidth}px`,
199
+ height: `calc(100% + ${trackSize.hScrollbarTrackHeight}px`,
200
+ marginRight: `-${trackSize.vScrollbarTrackWidth}px`,
201
+ marginBottom: `-${trackSize.hScrollbarTrackHeight}px`,
172
202
  });
173
203
  }
174
204
  setStyle(element, style) {
175
205
  Object.keys(style).forEach(key => this._renderer.setStyle(element, key, style[key]));
176
206
  }
177
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciScrollableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
178
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.1", type: SciScrollableDirective, isStandalone: true, selector: "[sciScrollable]", inputs: { displayNativeScrollbar: { classPropertyName: "displayNativeScrollbar", publicName: "sciScrollableDisplayNativeScrollbar", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
207
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciScrollableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
208
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: SciScrollableDirective, isStandalone: true, selector: "[sciScrollable]", inputs: { displayNativeScrollbar: { classPropertyName: "displayNativeScrollbar", publicName: "sciScrollableDisplayNativeScrollbar", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["sciScrollable"], ngImport: i0 });
179
209
  }
180
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciScrollableDirective, decorators: [{
210
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciScrollableDirective, decorators: [{
181
211
  type: Directive,
182
- args: [{ selector: '[sciScrollable]' }]
212
+ args: [{
213
+ selector: '[sciScrollable]',
214
+ exportAs: 'sciScrollable',
215
+ }]
183
216
  }], ctorParameters: () => [], propDecorators: { displayNativeScrollbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "sciScrollableDisplayNativeScrollbar", required: false }] }] } });
184
217
 
185
218
  /*
@@ -216,16 +249,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
216
249
  * ```
217
250
  */
218
251
  class SciScrollbarComponent {
219
- /**
220
- * Timeout for debouncing viewport resize events that trigger the scroll position computation.
221
- *
222
- * Debouncing is particularly important in the context of Angular animations, since they continuously
223
- * trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
224
- * expands a panel that contains a viewport.
225
- *
226
- * @internal
227
- */
228
- static VIEWPORT_RESIZE_DEBOUNCE_TIME = 50;
229
252
  /**
230
253
  * Specifies the direction of the scrollbar. Defaults to a vertical scrollbar.
231
254
  */
@@ -240,7 +263,8 @@ class SciScrollbarComponent {
240
263
  _document = inject(DOCUMENT);
241
264
  _zone = inject(NgZone);
242
265
  _destroyRef = inject(DestroyRef);
243
- _thumbElement = viewChild.required('thumb_handle');
266
+ _thumbElement = viewChild.required('thumb_handle', /* @ts-ignore */
267
+ ...(ngDevMode ? [{ debugName: "_thumbElement" }] : /* istanbul ignore next */ []));
244
268
  vertical = computed(() => this.direction() === 'vscroll', /* @ts-ignore */
245
269
  ...(ngDevMode ? [{ debugName: "vertical" }] : /* istanbul ignore next */ []));
246
270
  horizontal = computed(() => !this.vertical(), /* @ts-ignore */
@@ -277,9 +301,10 @@ class SciScrollbarComponent {
277
301
  this.scrolling.set(true);
278
302
  // Prevent text selection during drag.
279
303
  mousedownEvent.preventDefault();
304
+ // Calculate screen offset to convert screen coordinates into client coordinates, required for `sci-mousemove` events which originate from other documents (iframes).
305
+ const { screenOffsetX, screenOffsetY } = calculateScreenOffset(mousedownEvent);
280
306
  // Memoize offset where thumb was clicked.
281
- const [thumbStartPosition] = this.thumbPosition();
282
- const thumbStartOffset = (this.vertical() ? mousedownEvent.pageY : mousedownEvent.pageX) - thumbStartPosition;
307
+ const thumbStartOffset = this.vertical() ? mousedownEvent.offsetY : mousedownEvent.offsetX;
283
308
  // Stop scrolling when releasing the mouse. Handle the event in the capture phase and stop propagation to not close a potential overlay when releasing the mouse outside the overlay.
284
309
  const mouseUp$ = race(fromEvent(this._document, 'mouseup', { capture: true, once: true }), fromEvent(this._document, 'sci-mouseup', { once: true }))
285
310
  .pipe(tap(mouseupEvent => mouseupEvent.stopPropagation()));
@@ -291,7 +316,7 @@ class SciScrollbarComponent {
291
316
  // Prevent user agent scrolling while during drag.
292
317
  mousemoveEvent.preventDefault();
293
318
  // Calculate new thumb position.
294
- const pointerPosition = this.vertical() ? mousemoveEvent.pageY : mousemoveEvent.pageX;
319
+ const pointerPosition = this.vertical() ? mousemoveEvent.screenY - screenOffsetY : mousemoveEvent.screenX - screenOffsetX;
295
320
  this.scrollViewport(pointerPosition - thumbStartOffset);
296
321
  });
297
322
  }
@@ -301,13 +326,15 @@ class SciScrollbarComponent {
301
326
  * Scrolls in discrete steps to the pointer, then switches to regular scrolling until releasing the mouse.
302
327
  */
303
328
  onScrollTrackMouseDown(event) {
329
+ this.scrolling.set(true);
330
+ // Prevent text selection during drag.
331
+ event.preventDefault();
304
332
  const mouseMove$ = merge(fromEvent(this._document, 'mousemove'), fromEvent(this._document, 'sci-mousemove'));
305
- // Stop scrolling when releasing the mouse. Handle the event in the capture phase and stop propagation to not close a potential overlay when releasing the mouse outside the overlay.
333
+ // Handle the event in the capture phase and stop propagation to not close a potential overlay when releasing the mouse outside the overlay.
306
334
  const mouseUp$ = race(fromEvent(this._document, 'mouseup', { capture: true, once: true }), fromEvent(this._document, 'sci-mouseup', { once: true }))
307
335
  .pipe(tap(mouseupEvent => mouseupEvent.stopPropagation()));
308
- // Prevent text selection during drag.
309
- event.preventDefault();
310
- this.scrolling.set(true);
336
+ // Calculate screen offset to convert screen coordinates into client coordinates, required for `sci-mousemove` events which originate from other documents (iframes).
337
+ const { screenOffsetX, screenOffsetY } = calculateScreenOffset(event);
311
338
  // Scroll in discrete steps to the pointer position, then switch to regular scrolling.
312
339
  timer(250, 50)
313
340
  .pipe(
@@ -315,7 +342,7 @@ class SciScrollbarComponent {
315
342
  withLatestFrom(mouseMove$.pipe(startWith(event)), (_tick, event) => event),
316
343
  // Scroll immediately on initial click.
317
344
  startWith(event), subscribeIn(fn => this._zone.runOutsideAngular(fn)), exhaustMap(event => {
318
- const pointerPosition = this.vertical() ? event.pageY : event.pageX;
345
+ const pointerPosition = this.vertical() ? event.screenY - screenOffsetY : event.screenX - screenOffsetX;
319
346
  const [thumbStartPosition, thumbEndPosition] = this.thumbPosition();
320
347
  const thumbSize = thumbEndPosition - thumbStartPosition;
321
348
  // Step scroll until the pointer hits the thumb.
@@ -325,7 +352,7 @@ class SciScrollbarComponent {
325
352
  }
326
353
  // Switch to "smooth scrolling" following the pointer.
327
354
  return of(event)
328
- .pipe(concatWith(mouseMove$), map(event => (this.vertical() ? event.pageY : event.pageX) - (thumbSize / 2)));
355
+ .pipe(concatWith(mouseMove$), map(event => (this.vertical() ? event.screenY - screenOffsetY : event.screenX - screenOffsetX) - (thumbSize / 2)));
329
356
  }),
330
357
  // Stop on mouse release.
331
358
  takeUntil(mouseUp$), finalize(() => this.scrolling.set(false)))
@@ -342,8 +369,10 @@ class SciScrollbarComponent {
342
369
  const viewport = this.viewport();
343
370
  untracked(() => {
344
371
  const subscription = viewportScroll$(viewport)
345
- .pipe(mergeWith(viewportSize$(viewport, { debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME })), mergeWith(viewportClientSize$(viewport, { debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME })), subscribeIn(fn => this._zone.runOutsideAngular(fn)))
346
- .subscribe(() => this.renderScrollPosition());
372
+ .pipe(mergeWith(viewportSize$(viewport)), mergeWith(viewportClientSize$(viewport)), subscribeIn(fn => this._zone.runOutsideAngular(fn)))
373
+ .subscribe(() => {
374
+ this.renderScrollPosition();
375
+ });
347
376
  onCleanup(() => subscription.unsubscribe());
348
377
  });
349
378
  });
@@ -351,7 +380,7 @@ class SciScrollbarComponent {
351
380
  /**
352
381
  * Moves the scrollbar thumb to the specified position, scrolling the viewport accordingly.
353
382
  *
354
- * The thumb position must be given in page coordinates relative to the top-left corner of the document.
383
+ * The thumb position must be given in client coordinates (relative to the top-left corner of the page viewport).
355
384
  */
356
385
  scrollViewport(thumbPosition) {
357
386
  const [scrollbarComponentStartPosition] = this.scrollbarComponentPosition();
@@ -366,14 +395,14 @@ class SciScrollbarComponent {
366
395
  }
367
396
  }
368
397
  /**
369
- * Returns the position of this component in page coordinates.
398
+ * Returns the position of this component in client coordinates.
370
399
  *
371
- * Returned coordinates are relative to the top-left corner of the document.
400
+ * Returned coordinates are relative to the top-left corner of the page viewport.
372
401
  * Depending on the scrollbar orientation, returned coordinates are `[top, bottom]` or `[left, right]`.
373
402
  */
374
403
  scrollbarComponentPosition() {
375
404
  const boundingBox = this._host.getBoundingClientRect();
376
- return this.vertical() ? [boundingBox.top + window.scrollY, boundingBox.bottom + window.scrollY] : [boundingBox.left + window.scrollX, boundingBox.right + window.scrollX];
405
+ return this.vertical() ? [boundingBox.top, boundingBox.bottom] : [boundingBox.left, boundingBox.right];
377
406
  }
378
407
  /**
379
408
  * Returns the size of the viewport in pixels.
@@ -411,14 +440,14 @@ class SciScrollbarComponent {
411
440
  return this.vertical() ? thumbElement.offsetHeight : thumbElement.offsetWidth;
412
441
  }
413
442
  /**
414
- * Returns the current thumb position in page coordinates.
443
+ * Returns the current thumb position in client coordinates.
415
444
  *
416
- * Returned coordinates are relative to the top-left corner of the document.
445
+ * Returned coordinates are relative to the top-left corner of the page viewport.
417
446
  * Depending on the scrollbar orientation, returned coordinates are `[top, bottom]` or `[left, right]`.
418
447
  */
419
448
  thumbPosition() {
420
449
  const boundingBox = this._thumbElement().nativeElement.getBoundingClientRect();
421
- return this.vertical() ? [boundingBox.top + window.scrollY, boundingBox.bottom + window.scrollY] : [boundingBox.left + window.scrollX, boundingBox.right + window.scrollX];
450
+ return this.vertical() ? [boundingBox.top, boundingBox.bottom] : [boundingBox.left, boundingBox.right];
422
451
  }
423
452
  /**
424
453
  * Returns the size of the scrollbar track in pixels.
@@ -428,10 +457,10 @@ class SciScrollbarComponent {
428
457
  trackSize() {
429
458
  return this.vertical() ? this._host.clientHeight : this._host.clientWidth;
430
459
  }
431
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciScrollbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
432
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.1", type: SciScrollbarComponent, isStandalone: true, selector: "sci-scrollbar", inputs: { direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, viewport: { classPropertyName: "viewport", publicName: "viewport", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.vertical": "vertical()", "class.horizontal": "horizontal()", "class.scrolling": "scrolling()", "class.overflow": "overflow()", "style.--\u0275sci-scrollbar-thumb-position-fr": "thumbPositionFr()", "style.--\u0275sci-scrollbar-thumb-size-fr": "thumbSizeFr()" } }, viewQueries: [{ propertyName: "_thumbElement", first: true, predicate: ["thumb_handle"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- scrolltrack for moving the viewport client upwards (paging) -->\n<div class=\"scrolltrack\" (mousedown)=\"onScrollTrackMouseDown($event)\"></div>\n\n<!-- scrollthumb -->\n<div #thumb_handle\n class=\"thumb-handle\"\n [class.vertical]=\"vertical()\"\n [class.horizontal]=\"horizontal()\"\n (mousedown)=\"onThumbMouseDown($event)\">\n <div class=\"thumb e2e-thumb\"\n [class.vertical]=\"vertical()\"\n [class.horizontal]=\"horizontal()\">\n </div>\n</div>\n\n<!-- scrolltrack for moving the viewport client downwards (paging) -->\n<div class=\"scrolltrack\" (mousedown)=\"onScrollTrackMouseDown($event)\"></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;box-sizing:border-box;transition-duration:1s;transition-property:opacity;transition-timing-function:ease-out;--\\275sci-scrollbar-thumb-position-fr: 0;--\\275sci-scrollbar-thumb-size-fr: 0}:host.vertical{flex-direction:column;width:8px}:host.horizontal{flex-direction:row;height:8px}:host>div.scrolltrack:first-child{flex-grow:var(--\\275sci-scrollbar-thumb-position-fr)}:host:not(.overflow){display:none}:host:hover>div.thumb-handle>div.thumb,:host.scrolling>div.thumb-handle>div.thumb{background-color:var(--sci-scrollbar-color);opacity:.75}:host:hover>div.thumb-handle>div.thumb.vertical,:host.scrolling>div.thumb-handle>div.thumb.vertical{width:100%}:host:hover>div.thumb-handle>div.thumb.horizontal,:host.scrolling>div.thumb-handle>div.thumb.horizontal{height:100%}:host>div.thumb-handle{display:flex;flex-grow:var(--\\275sci-scrollbar-thumb-size-fr);align-items:center}:host>div.thumb-handle.vertical{flex-direction:column;min-height:20px}:host>div.thumb-handle.horizontal{flex-direction:row;min-width:20px}:host>div.thumb-handle>div.thumb{flex:auto;border-radius:4px;background-color:var(--sci-scrollbar-color);opacity:.4;transition-duration:125ms;transition-property:width,height;transition-timing-function:ease-out}:host>div.thumb-handle>div.thumb.vertical{width:60%}:host>div.thumb-handle>div.thumb.horizontal{height:60%}:host>div.scrolltrack:last-child{flex-grow:calc(1 - (var(--\\275sci-scrollbar-thumb-position-fr) + var(--\\275sci-scrollbar-thumb-size-fr)))}\n"] });
460
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciScrollbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
461
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.7", type: SciScrollbarComponent, isStandalone: true, selector: "sci-scrollbar", inputs: { direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, viewport: { classPropertyName: "viewport", publicName: "viewport", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.vertical": "vertical()", "class.horizontal": "horizontal()", "class.scrolling": "scrolling()", "class.overflow": "overflow()", "style.--\u0275sci-scrollbar-thumb-position-fr": "thumbPositionFr()", "style.--\u0275sci-scrollbar-thumb-size-fr": "thumbSizeFr()" } }, viewQueries: [{ propertyName: "_thumbElement", first: true, predicate: ["thumb_handle"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- scrolltrack for moving the viewport client upwards (paging) -->\n<div class=\"scrolltrack\" (mousedown)=\"onScrollTrackMouseDown($event)\"></div>\n\n<!-- scrollthumb -->\n<div #thumb_handle\n class=\"thumb-handle\"\n [class.vertical]=\"vertical()\"\n [class.horizontal]=\"horizontal()\"\n (mousedown)=\"onThumbMouseDown($event)\">\n <div class=\"thumb e2e-thumb\"\n [class.vertical]=\"vertical()\"\n [class.horizontal]=\"horizontal()\">\n </div>\n</div>\n\n<!-- scrolltrack for moving the viewport client downwards (paging) -->\n<div class=\"scrolltrack\" (mousedown)=\"onScrollTrackMouseDown($event)\"></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;box-sizing:border-box;transition-duration:1s;transition-property:opacity;transition-timing-function:ease-out;--\\275sci-scrollbar-thumb-position-fr: 0;--\\275sci-scrollbar-thumb-size-fr: 0}:host.vertical{flex-direction:column;width:8px}:host.horizontal{flex-direction:row;height:8px}:host>div.scrolltrack:first-child{flex-grow:var(--\\275sci-scrollbar-thumb-position-fr)}:host:not(.overflow){display:none}:host:hover>div.thumb-handle>div.thumb,:host.scrolling>div.thumb-handle>div.thumb{background-color:var(--sci-scrollbar-color);opacity:.75}:host:hover>div.thumb-handle>div.thumb.vertical,:host.scrolling>div.thumb-handle>div.thumb.vertical{width:100%}:host:hover>div.thumb-handle>div.thumb.horizontal,:host.scrolling>div.thumb-handle>div.thumb.horizontal{height:100%}:host>div.thumb-handle{display:flex;flex-grow:var(--\\275sci-scrollbar-thumb-size-fr);align-items:center}:host>div.thumb-handle.vertical{flex-direction:column;min-height:20px}:host>div.thumb-handle.horizontal{flex-direction:row;min-width:20px}:host>div.thumb-handle>div.thumb{flex:auto;border-radius:4px;background-color:var(--sci-scrollbar-color);opacity:.4;transition-duration:125ms;transition-property:width,height;transition-timing-function:ease-out}:host>div.thumb-handle>div.thumb.vertical{width:60%}:host>div.thumb-handle>div.thumb.horizontal{height:60%}:host>div.scrolltrack:last-child{flex-grow:calc(1 - (var(--\\275sci-scrollbar-thumb-position-fr) + var(--\\275sci-scrollbar-thumb-size-fr)))}\n"] });
433
462
  }
434
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciScrollbarComponent, decorators: [{
463
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciScrollbarComponent, decorators: [{
435
464
  type: Component,
436
465
  args: [{ selector: 'sci-scrollbar', host: {
437
466
  '[class.vertical]': 'vertical()',
@@ -451,27 +480,18 @@ function viewportScroll$(viewport) {
451
480
  /**
452
481
  * Emits on subscription, and then each time the size of the viewport changes.
453
482
  */
454
- function viewportSize$(viewport, options) {
455
- return fromResize$(viewport)
456
- .pipe(
457
- // Debouncing is particularly important in the context of Angular animations, since they continuously
458
- // trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
459
- // expands a panel that contains a viewport.
460
- debounceTime(options.debounceTime), map(() => undefined));
483
+ function viewportSize$(viewport) {
484
+ return fromResize$(viewport).pipe(map(() => undefined));
461
485
  }
462
486
  /**
463
487
  * Emits on subscription, and then each time the size or style property of the viewport client changes.
464
488
  */
465
- function viewportClientSize$(viewport, options) {
489
+ function viewportClientSize$(viewport) {
466
490
  return children$(viewport)
467
491
  .pipe(switchMap(children => merge(...children.map(child => merge(fromResize$(child),
468
492
  // Observe style mutations since some transformations change the scroll position without necessarily triggering a dimension change,
469
493
  // e.g., `scale` or `translate` used by some virtual scroll implementations
470
- fromMutation$(child, { subtree: false, childList: false, attributeFilter: ['style'] }))))),
471
- // Debouncing is particularly important in the context of Angular animations, since they continuously
472
- // trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
473
- // expands a panel that contains a viewport.
474
- debounceTime(options.debounceTime), map(() => undefined));
494
+ fromMutation$(child, { subtree: false, childList: false, attributeFilter: ['style'] }))))), map(() => undefined));
475
495
  }
476
496
  /**
477
497
  * Emits the children of the passed element, and then each time child elements are added or removed.
@@ -485,16 +505,18 @@ function children$(element) {
485
505
  .filter((child) => child instanceof HTMLElement)));
486
506
  }
487
507
  /**
488
- * Returns the value clamped to the inclusive range of min and max.
489
- */
490
- function clamp(value, minmax) {
491
- return Math.max(minmax.min, Math.min(value, minmax.max));
492
- }
493
- /**
494
- * Returns whether the value is between the specified range (inclusive).
508
+ * Calculates the distance between the top-left corner of the screen (monitor) and the top-left corner of the page viewport of this document.
509
+ *
510
+ * Use to convert screen coordinates from `sci-mousemove` and `sci-mouseup` events into client coordinates relative to the page viewport of the current document.
511
+ *
512
+ * The `sci-mousemove` and `sci-mouseup` events originate from other documents (iframes) and do not include client coordinates. Even if they did, they would be
513
+ * relative to the source document, not the current one.
495
514
  */
496
- function isBetween(value, range) {
497
- return value >= range.from && value <= range.to;
515
+ function calculateScreenOffset(mousedownEvent) {
516
+ return {
517
+ screenOffsetX: mousedownEvent.screenX - mousedownEvent.clientX,
518
+ screenOffsetY: mousedownEvent.screenY - mousedownEvent.clientY,
519
+ };
498
520
  }
499
521
 
500
522
  /*
@@ -584,12 +606,14 @@ class SciViewportComponent {
584
606
  */
585
607
  scroll = output(); // eslint-disable-line @angular-eslint/no-output-native
586
608
  _host = inject(ElementRef).nativeElement;
587
- _viewport = viewChild.required('viewport');
588
- _viewportClient = viewChild.required('viewport_client');
589
- nativeScrollbarTrackSizeProvider = inject(SciNativeScrollbarTrackSizeProvider);
590
- constructor() {
591
- this.installScrollEmitter();
592
- }
609
+ _viewport = viewChild.required('viewport', /* @ts-ignore */
610
+ ...(ngDevMode ? [{ debugName: "_viewport" }] : /* istanbul ignore next */ []));
611
+ _viewportClient = viewChild.required('viewport_client', /* @ts-ignore */
612
+ ...(ngDevMode ? [{ debugName: "_viewportClient" }] : /* istanbul ignore next */ []));
613
+ /**
614
+ * Indicates whether currently scrolling the viewport.
615
+ */
616
+ scrolling = this.computeScrolling(this._viewport);
593
617
  focus() {
594
618
  this.viewportElement.focus();
595
619
  }
@@ -735,24 +759,17 @@ class SciViewportComponent {
735
759
  return offset;
736
760
  }
737
761
  /**
738
- * Emits when the scroll position changes.
762
+ * Computes whether currently scrolling the viewport.
739
763
  */
740
- installScrollEmitter() {
764
+ computeScrolling(viewport) {
741
765
  const zone = inject(NgZone);
742
- effect(onCleanup => {
743
- const viewport = this._viewport();
744
- untracked(() => {
745
- const subscription = fromEvent(viewport.nativeElement, 'scroll')
746
- .pipe(subscribeIn(fn => zone.runOutsideAngular(fn)))
747
- .subscribe(event => this.scroll.emit(event));
748
- onCleanup(() => subscription.unsubscribe());
749
- });
750
- });
766
+ return toSignal(toObservable(viewport)
767
+ .pipe(switchMap$1(viewport => fromEvent(viewport.nativeElement, 'scroll', { passive: true }).pipe(subscribeIn(fn => zone.runOutsideAngular(fn)))), tap(event => this.scroll.emit(event)), switchMap$1(() => concat(of(true), timer(150).pipe(map$1(() => false))))), { initialValue: false });
751
768
  }
752
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciViewportComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
753
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: SciViewportComponent, isStandalone: true, selector: "sci-viewport", inputs: { scrollbarStyle: { classPropertyName: "scrollbarStyle", publicName: "scrollbarStyle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scroll: "scroll" }, host: { listeners: { "focus": "focus()" } }, viewQueries: [{ propertyName: "_viewport", first: true, predicate: ["viewport"], descendants: true, isSignal: true }, { propertyName: "_viewportClient", first: true, predicate: ["viewport_client"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- viewport and viewport client -->\n<div #viewport\n class=\"viewport\"\n tabindex=\"-1\"\n sciScrollable [sciScrollableDisplayNativeScrollbar]=\"scrollbarStyle() === 'native'\"\n cdkScrollable>\n <div #viewport_client class=\"viewport-client\" part=\"content\">\n <slot></slot>\n </div>\n</div>\n\n<!-- render emulated scrollbars which sit on-top -->\n@if (scrollbarStyle() === 'on-top' && nativeScrollbarTrackSizeProvider.trackSize() !== null) {\n <sci-scrollbar [direction]=\"'vscroll'\" [viewport]=\"viewport\" class=\"e2e-vertical\"/>\n <sci-scrollbar [direction]=\"'hscroll'\" [viewport]=\"viewport\" class=\"e2e-horizontal\"/>\n}\n", styles: [":host{display:grid;grid-template-columns:100%;grid-template-rows:100%;position:relative;overflow:hidden;outline:none}:host:is(:not(:hover):not(:active),:host(:not(:hover):not(:active))) sci-scrollbar:not(.scrolling){opacity:0}:host>div.viewport{display:grid;position:relative;outline:none;-webkit-overflow-scrolling:touch}:host>div.viewport>div.viewport-client{display:grid}:host>sci-scrollbar{--sci-scrollbar-color: var(--sci-viewport-scrollbar-color);position:absolute}:host>sci-scrollbar.vertical{top:1px;right:1px;bottom:1px}:host>sci-scrollbar.horizontal{left:1px;bottom:1px;right:1px}\n"], dependencies: [{ kind: "directive", type: SciScrollableDirective, selector: "[sciScrollable]", inputs: ["sciScrollableDisplayNativeScrollbar"] }, { kind: "component", type: SciScrollbarComponent, selector: "sci-scrollbar", inputs: ["direction", "viewport"] }, { kind: "directive", type: CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }], changeDetection: i0.ChangeDetectionStrategy.Eager, encapsulation: i0.ViewEncapsulation.ShadowDom });
769
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciViewportComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
770
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: SciViewportComponent, isStandalone: true, selector: "sci-viewport", inputs: { scrollbarStyle: { classPropertyName: "scrollbarStyle", publicName: "scrollbarStyle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scroll: "scroll" }, host: { listeners: { "focus": "focus()" } }, viewQueries: [{ propertyName: "_viewport", first: true, predicate: ["viewport"], descendants: true, isSignal: true }, { propertyName: "_viewportClient", first: true, predicate: ["viewport_client"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- viewport and viewport client -->\n<div #viewport\n class=\"viewport\"\n tabindex=\"-1\"\n sciScrollable [sciScrollableDisplayNativeScrollbar]=\"scrollbarStyle() === 'native'\" #sciScrollable=\"sciScrollable\"\n cdkScrollable>\n <div #viewport_client class=\"viewport-client\" part=\"content\">\n <slot></slot>\n </div>\n</div>\n\n<!-- render emulated scrollbars which sit on-top -->\n@if (scrollbarStyle() === 'on-top' && sciScrollable.isNativeScrollbarCropped()) {\n <sci-scrollbar direction=\"vscroll\" [viewport]=\"viewport\"/>\n <sci-scrollbar direction=\"hscroll\" [viewport]=\"viewport\"/>\n}\n", styles: [":host{display:grid;grid-template-columns:100%;grid-template-rows:100%;position:relative;overflow:hidden;outline:none}:host:is(:not(:hover):not(:active),:host(:not(:hover):not(:active))) sci-scrollbar:not(.scrolling){opacity:0}:host>div.viewport{display:grid;position:relative;outline:none;-webkit-overflow-scrolling:touch}:host>div.viewport>div.viewport-client{display:grid}:host>sci-scrollbar{--sci-scrollbar-color: var(--sci-viewport-scrollbar-color);position:absolute}:host>sci-scrollbar.vertical{top:2px;right:1px;bottom:2px}:host>sci-scrollbar.horizontal{left:2px;bottom:1px;right:2px}\n"], dependencies: [{ kind: "directive", type: SciScrollableDirective, selector: "[sciScrollable]", inputs: ["sciScrollableDisplayNativeScrollbar"], exportAs: ["sciScrollable"] }, { kind: "component", type: SciScrollbarComponent, selector: "sci-scrollbar", inputs: ["direction", "viewport"] }, { kind: "directive", type: CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }], changeDetection: i0.ChangeDetectionStrategy.Eager, encapsulation: i0.ViewEncapsulation.ShadowDom });
754
771
  }
755
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciViewportComponent, decorators: [{
772
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciViewportComponent, decorators: [{
756
773
  type: Component,
757
774
  args: [{ selector: 'sci-viewport', encapsulation: ViewEncapsulation.ShadowDom, imports: [
758
775
  SciScrollableDirective,
@@ -760,8 +777,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
760
777
  CdkScrollable,
761
778
  ], changeDetection: ChangeDetectionStrategy.Eager, host: {
762
779
  '(focus)': 'focus()',
763
- }, template: "<!-- viewport and viewport client -->\n<div #viewport\n class=\"viewport\"\n tabindex=\"-1\"\n sciScrollable [sciScrollableDisplayNativeScrollbar]=\"scrollbarStyle() === 'native'\"\n cdkScrollable>\n <div #viewport_client class=\"viewport-client\" part=\"content\">\n <slot></slot>\n </div>\n</div>\n\n<!-- render emulated scrollbars which sit on-top -->\n@if (scrollbarStyle() === 'on-top' && nativeScrollbarTrackSizeProvider.trackSize() !== null) {\n <sci-scrollbar [direction]=\"'vscroll'\" [viewport]=\"viewport\" class=\"e2e-vertical\"/>\n <sci-scrollbar [direction]=\"'hscroll'\" [viewport]=\"viewport\" class=\"e2e-horizontal\"/>\n}\n", styles: [":host{display:grid;grid-template-columns:100%;grid-template-rows:100%;position:relative;overflow:hidden;outline:none}:host:is(:not(:hover):not(:active),:host(:not(:hover):not(:active))) sci-scrollbar:not(.scrolling){opacity:0}:host>div.viewport{display:grid;position:relative;outline:none;-webkit-overflow-scrolling:touch}:host>div.viewport>div.viewport-client{display:grid}:host>sci-scrollbar{--sci-scrollbar-color: var(--sci-viewport-scrollbar-color);position:absolute}:host>sci-scrollbar.vertical{top:1px;right:1px;bottom:1px}:host>sci-scrollbar.horizontal{left:1px;bottom:1px;right:1px}\n"] }]
764
- }], ctorParameters: () => [], propDecorators: { scrollbarStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollbarStyle", required: false }] }], scroll: [{ type: i0.Output, args: ["scroll"] }], _viewport: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], _viewportClient: [{ type: i0.ViewChild, args: ['viewport_client', { isSignal: true }] }] } });
780
+ }, template: "<!-- viewport and viewport client -->\n<div #viewport\n class=\"viewport\"\n tabindex=\"-1\"\n sciScrollable [sciScrollableDisplayNativeScrollbar]=\"scrollbarStyle() === 'native'\" #sciScrollable=\"sciScrollable\"\n cdkScrollable>\n <div #viewport_client class=\"viewport-client\" part=\"content\">\n <slot></slot>\n </div>\n</div>\n\n<!-- render emulated scrollbars which sit on-top -->\n@if (scrollbarStyle() === 'on-top' && sciScrollable.isNativeScrollbarCropped()) {\n <sci-scrollbar direction=\"vscroll\" [viewport]=\"viewport\"/>\n <sci-scrollbar direction=\"hscroll\" [viewport]=\"viewport\"/>\n}\n", styles: [":host{display:grid;grid-template-columns:100%;grid-template-rows:100%;position:relative;overflow:hidden;outline:none}:host:is(:not(:hover):not(:active),:host(:not(:hover):not(:active))) sci-scrollbar:not(.scrolling){opacity:0}:host>div.viewport{display:grid;position:relative;outline:none;-webkit-overflow-scrolling:touch}:host>div.viewport>div.viewport-client{display:grid}:host>sci-scrollbar{--sci-scrollbar-color: var(--sci-viewport-scrollbar-color);position:absolute}:host>sci-scrollbar.vertical{top:2px;right:1px;bottom:2px}:host>sci-scrollbar.horizontal{left:2px;bottom:1px;right:2px}\n"] }]
781
+ }], propDecorators: { scrollbarStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollbarStyle", required: false }] }], scroll: [{ type: i0.Output, args: ["scroll"] }], _viewport: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], _viewportClient: [{ type: i0.ViewChild, args: ['viewport_client', { isSignal: true }] }] } });
765
782
 
766
783
  /*
767
784
  * Copyright (c) 2018-2019 Swiss Federal Railways