@scion/components 22.0.0 → 22.2.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.
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, DOCUMENT, NgZone, Injectable, input, ElementRef, Renderer2, effect, untracked, Directive, DestroyRef, viewChild, signal,
|
|
3
|
-
import { fromEvent, merge, mergeWith, timer, of } from 'rxjs';
|
|
4
|
-
import { debounceTime, startWith, map, distinctUntilChanged, first, withLatestFrom, takeWhile, takeUntil, switchMap } from 'rxjs/operators';
|
|
5
|
-
import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
6
|
-
import { subscribeIn, filterArray } from '@scion/toolkit/operators';
|
|
2
|
+
import { inject, DOCUMENT, NgZone, Injectable, input, ElementRef, Renderer2, computed, effect, untracked, Directive, DestroyRef, viewChild, signal, Component, output, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
|
|
7
3
|
import { coerceElement } from '@angular/cdk/coercion';
|
|
4
|
+
import { fromEvent, race, tap, merge, finalize, timer, exhaustMap, of, concatWith, mergeWith } from 'rxjs';
|
|
5
|
+
import { debounceTime, startWith, map, distinctUntilChanged, takeUntil, withLatestFrom, switchMap } from 'rxjs/operators';
|
|
6
|
+
import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
7
|
+
import { subscribeIn } from '@scion/toolkit/operators';
|
|
8
8
|
import { fromResize$, fromMutation$ } from '@scion/toolkit/observable';
|
|
9
9
|
import { CdkScrollable } from '@angular/cdk/scrolling';
|
|
10
10
|
|
|
11
11
|
/*
|
|
12
|
-
* Copyright (c) 2018-
|
|
12
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
13
13
|
*
|
|
14
14
|
* This program and the accompanying materials are made
|
|
15
15
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -17,25 +17,27 @@ import { CdkScrollable } from '@angular/cdk/scrolling';
|
|
|
17
17
|
*
|
|
18
18
|
* SPDX-License-Identifier: EPL-2.0
|
|
19
19
|
*/
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
*/
|
|
23
|
-
class SciNativeScrollbarTrackSizeProvider {
|
|
20
|
+
/** @inheritDoc */
|
|
21
|
+
class ɵSciNativeScrollbarTrackSizeProvider {
|
|
24
22
|
_document = inject(DOCUMENT);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
/** @inheritDoc */
|
|
24
|
+
trackSize = this.computeNativeScrollbarTrackSize();
|
|
25
|
+
computeNativeScrollbarTrackSize() {
|
|
26
|
+
// We compute the size of the native scrollbar track when the browser fires the onresize window event.
|
|
27
|
+
// This event is also fired on page zoom or when displaying a hidden document. Hidden documents do not have
|
|
28
|
+
// a scrollbar track size until being displayed, e.g., after showing hidden iframes.
|
|
29
|
+
const zone = inject(NgZone);
|
|
30
|
+
const trackSize$ = fromEvent(window, 'resize')
|
|
31
|
+
.pipe(subscribeIn(fn => zone.runOutsideAngular(fn)), debounceTime(5), startWith(null), // trigger the initial computation
|
|
32
|
+
map(() => this.calculateTrackSize()), distinctUntilChanged((t1, t2) => t1?.hScrollbarTrackHeight === t2?.hScrollbarTrackHeight && t1?.vScrollbarTrackWidth === t2?.vScrollbarTrackWidth));
|
|
33
|
+
return toSignal(trackSize$, { initialValue: null });
|
|
32
34
|
}
|
|
33
35
|
/**
|
|
34
36
|
* Computes the native scrollbar track size.
|
|
35
37
|
*
|
|
36
38
|
* @returns native track size, or `null` if the native scrollbars sit on top of the content.
|
|
37
39
|
*/
|
|
38
|
-
|
|
40
|
+
calculateTrackSize() {
|
|
39
41
|
// Create temporary viewport and viewport client with native scrollbars to compute the scrolltrack width.
|
|
40
42
|
const viewportDiv = this._document.createElement('div');
|
|
41
43
|
setStyle(viewportDiv, {
|
|
@@ -68,22 +70,12 @@ class SciNativeScrollbarTrackSizeProvider {
|
|
|
68
70
|
}
|
|
69
71
|
return trackSize;
|
|
70
72
|
}
|
|
71
|
-
|
|
72
|
-
|
|
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' });
|
|
73
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: ɵSciNativeScrollbarTrackSizeProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
74
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: ɵSciNativeScrollbarTrackSizeProvider });
|
|
82
75
|
}
|
|
83
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type:
|
|
84
|
-
type: Injectable
|
|
85
|
-
|
|
86
|
-
}], ctorParameters: () => [] });
|
|
76
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: ɵSciNativeScrollbarTrackSizeProvider, decorators: [{
|
|
77
|
+
type: Injectable
|
|
78
|
+
}] });
|
|
87
79
|
/**
|
|
88
80
|
* Applies the given style(s) to the given element.
|
|
89
81
|
*
|
|
@@ -96,6 +88,27 @@ function setStyle(element, styles) {
|
|
|
96
88
|
Object.entries(styles).forEach(([name, value]) => element.style.setProperty(name, value));
|
|
97
89
|
}
|
|
98
90
|
|
|
91
|
+
/*
|
|
92
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
93
|
+
*
|
|
94
|
+
* This program and the accompanying materials are made
|
|
95
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
96
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
97
|
+
*
|
|
98
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
99
|
+
*/
|
|
100
|
+
/**
|
|
101
|
+
* Provides the native scrollbar tracksize.
|
|
102
|
+
*/
|
|
103
|
+
class SciNativeScrollbarTrackSizeProvider {
|
|
104
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
105
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, providedIn: 'root', useClass: ɵSciNativeScrollbarTrackSizeProvider });
|
|
106
|
+
}
|
|
107
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, decorators: [{
|
|
108
|
+
type: Injectable,
|
|
109
|
+
args: [{ providedIn: 'root', useClass: ɵSciNativeScrollbarTrackSizeProvider }]
|
|
110
|
+
}] });
|
|
111
|
+
|
|
99
112
|
/*
|
|
100
113
|
* Copyright (c) 2018-2019 Swiss Federal Railways
|
|
101
114
|
*
|
|
@@ -115,16 +128,37 @@ function setStyle(element, styles) {
|
|
|
115
128
|
* 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
129
|
* fill up the entire space (width and height set to 100%). The parent element must have its CSS `overflow` property set to `hidden`
|
|
117
130
|
* to hide the pushed out native scrollbars.
|
|
131
|
+
*
|
|
132
|
+
* This directive provides the `isNativeScrollbarCropped` signal, which indicates whether native scrollbars are pushed out of the viewport element.
|
|
133
|
+
* In templates, access it via the exported template reference variable `sciScrollable`.
|
|
134
|
+
*
|
|
135
|
+
* ```html
|
|
136
|
+
* <div sciScrollable #sciScrollable="sciScrollable" #viewport>
|
|
137
|
+
* content
|
|
138
|
+
* </div>
|
|
139
|
+
*
|
|
140
|
+
* <!-- Render scrollbars only if native scrollbars are pushed out of the viewport element. -->
|
|
141
|
+
* @if (sciScrollable.isNativeScrollbarCropped()) {
|
|
142
|
+
* <sci-scrollbar [viewport]="viewport" direction="vscroll"/>
|
|
143
|
+
* <sci-scrollbar [viewport]="viewport" direction="hscroll"/>
|
|
144
|
+
* }
|
|
145
|
+
* ```
|
|
118
146
|
*/
|
|
119
147
|
class SciScrollableDirective {
|
|
120
148
|
/**
|
|
121
149
|
* Controls whether to display native scrollbars.
|
|
150
|
+
*
|
|
122
151
|
* Has no effect if the native scrollbar sits on top of the content, e.g. in OS X.
|
|
123
152
|
*/
|
|
124
153
|
displayNativeScrollbar = input(false, { ...(ngDevMode ? { debugName: "displayNativeScrollbar" } : /* istanbul ignore next */ {}), alias: 'sciScrollableDisplayNativeScrollbar' });
|
|
125
154
|
_host = inject((ElementRef)).nativeElement;
|
|
126
155
|
_renderer = inject(Renderer2);
|
|
127
156
|
_nativeScrollbarTrackSizeProvider = inject(SciNativeScrollbarTrackSizeProvider);
|
|
157
|
+
/**
|
|
158
|
+
* Indicates whether native scrollbars are pushed out of the viewport element.
|
|
159
|
+
*/
|
|
160
|
+
isNativeScrollbarCropped = computed(() => !this.displayNativeScrollbar() && this._nativeScrollbarTrackSizeProvider.trackSize() !== null, /* @ts-ignore */
|
|
161
|
+
...(ngDevMode ? [{ debugName: "isNativeScrollbarCropped" }] : /* istanbul ignore next */ []));
|
|
128
162
|
constructor() {
|
|
129
163
|
this.controlDisplayOfNativeScrollbar();
|
|
130
164
|
}
|
|
@@ -133,14 +167,9 @@ class SciScrollableDirective {
|
|
|
133
167
|
*/
|
|
134
168
|
controlDisplayOfNativeScrollbar() {
|
|
135
169
|
effect(() => {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
untracked(() => this.
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
const nativeScrollbarTrackSize = this._nativeScrollbarTrackSizeProvider.trackSize();
|
|
142
|
-
if (nativeScrollbarTrackSize) {
|
|
143
|
-
untracked(() => this.shiftNativeScrollbars(nativeScrollbarTrackSize));
|
|
170
|
+
if (this.isNativeScrollbarCropped()) {
|
|
171
|
+
const trackSize = this._nativeScrollbarTrackSizeProvider.trackSize();
|
|
172
|
+
untracked(() => this.shiftNativeScrollbars(trackSize));
|
|
144
173
|
}
|
|
145
174
|
else {
|
|
146
175
|
untracked(() => this.useNativeScrollbars());
|
|
@@ -162,24 +191,27 @@ class SciScrollableDirective {
|
|
|
162
191
|
/**
|
|
163
192
|
* Shifts the native scrollbars out of the visible viewport area.
|
|
164
193
|
*/
|
|
165
|
-
shiftNativeScrollbars(
|
|
194
|
+
shiftNativeScrollbars(trackSize) {
|
|
166
195
|
this.setStyle(this._host, {
|
|
167
196
|
overflow: 'scroll',
|
|
168
|
-
width: `calc(100% + ${
|
|
169
|
-
height: `calc(100% + ${
|
|
170
|
-
marginRight: `-${
|
|
171
|
-
marginBottom: `-${
|
|
197
|
+
width: `calc(100% + ${trackSize.vScrollbarTrackWidth}px`,
|
|
198
|
+
height: `calc(100% + ${trackSize.hScrollbarTrackHeight}px`,
|
|
199
|
+
marginRight: `-${trackSize.vScrollbarTrackWidth}px`,
|
|
200
|
+
marginBottom: `-${trackSize.hScrollbarTrackHeight}px`,
|
|
172
201
|
});
|
|
173
202
|
}
|
|
174
203
|
setStyle(element, style) {
|
|
175
204
|
Object.keys(style).forEach(key => this._renderer.setStyle(element, key, style[key]));
|
|
176
205
|
}
|
|
177
206
|
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 ɵ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 } }, exportAs: ["sciScrollable"], ngImport: i0 });
|
|
179
208
|
}
|
|
180
209
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciScrollableDirective, decorators: [{
|
|
181
210
|
type: Directive,
|
|
182
|
-
args: [{
|
|
211
|
+
args: [{
|
|
212
|
+
selector: '[sciScrollable]',
|
|
213
|
+
exportAs: 'sciScrollable',
|
|
214
|
+
}]
|
|
183
215
|
}], ctorParameters: () => [], propDecorators: { displayNativeScrollbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "sciScrollableDisplayNativeScrollbar", required: false }] }] } });
|
|
184
216
|
|
|
185
217
|
/*
|
|
@@ -195,7 +227,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
195
227
|
* Renders a vertical or horizontal scrollbar.
|
|
196
228
|
*
|
|
197
229
|
* The scrollbar features the following functionality:
|
|
198
|
-
* - allows to move the thumb by mouse
|
|
230
|
+
* - allows to move the thumb by mouse
|
|
199
231
|
* - enlarges the thumb if the mouse pointer is near the thumb
|
|
200
232
|
* - allows paging on mousedown on the scroll track
|
|
201
233
|
*
|
|
@@ -204,7 +236,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
204
236
|
* To customize the default look of SCION components or support different themes, configure the `@scion/components` SCSS module in `styles.scss`.
|
|
205
237
|
* To style a specific `sci-scrollbar` component, the following CSS variables can be set directly on the component.
|
|
206
238
|
*
|
|
207
|
-
* - sci-scrollbar-color: Sets the color of the scrollbar.
|
|
239
|
+
* - --sci-scrollbar-color: Sets the color of the scrollbar.
|
|
208
240
|
*
|
|
209
241
|
* Example:
|
|
210
242
|
*
|
|
@@ -232,7 +264,7 @@ class SciScrollbarComponent {
|
|
|
232
264
|
direction = input('vscroll', /* @ts-ignore */
|
|
233
265
|
...(ngDevMode ? [{ debugName: "direction" }] : /* istanbul ignore next */ []));
|
|
234
266
|
/**
|
|
235
|
-
*
|
|
267
|
+
* Specifies the viewport associated with the scrollbar.
|
|
236
268
|
*/
|
|
237
269
|
viewport = input.required(/* @ts-ignore */
|
|
238
270
|
...(ngDevMode ? [{ debugName: "viewport" }] : /* istanbul ignore next */ []));
|
|
@@ -241,89 +273,102 @@ class SciScrollbarComponent {
|
|
|
241
273
|
_zone = inject(NgZone);
|
|
242
274
|
_destroyRef = inject(DestroyRef);
|
|
243
275
|
_thumbElement = viewChild.required('thumb_handle');
|
|
244
|
-
_lastDragPosition = signal(null, /* @ts-ignore */
|
|
245
|
-
...(ngDevMode ? [{ debugName: "_lastDragPosition" }] : /* istanbul ignore next */ []));
|
|
246
276
|
vertical = computed(() => this.direction() === 'vscroll', /* @ts-ignore */
|
|
247
277
|
...(ngDevMode ? [{ debugName: "vertical" }] : /* istanbul ignore next */ []));
|
|
248
278
|
horizontal = computed(() => !this.vertical(), /* @ts-ignore */
|
|
249
279
|
...(ngDevMode ? [{ debugName: "horizontal" }] : /* istanbul ignore next */ []));
|
|
250
|
-
scrolling =
|
|
280
|
+
scrolling = signal(false, /* @ts-ignore */
|
|
251
281
|
...(ngDevMode ? [{ debugName: "scrolling" }] : /* istanbul ignore next */ []));
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
282
|
+
overflow = signal(false, /* @ts-ignore */
|
|
283
|
+
...(ngDevMode ? [{ debugName: "overflow" }] : /* istanbul ignore next */ []));
|
|
284
|
+
thumbSizeFr = signal(0, /* @ts-ignore */
|
|
285
|
+
...(ngDevMode ? [{ debugName: "thumbSizeFr" }] : /* istanbul ignore next */ []));
|
|
286
|
+
thumbPositionFr = signal(0, /* @ts-ignore */
|
|
287
|
+
...(ngDevMode ? [{ debugName: "thumbPositionFr" }] : /* istanbul ignore next */ []));
|
|
255
288
|
constructor() {
|
|
256
289
|
this.installScrollPositionRenderer();
|
|
257
290
|
}
|
|
258
291
|
/**
|
|
259
|
-
* Computes the scroll position and updates CSS variables to render the scroll position
|
|
292
|
+
* Computes the scroll position and updates CSS variables to render the scroll position.
|
|
260
293
|
*/
|
|
261
294
|
renderScrollPosition() {
|
|
262
295
|
NgZone.assertNotInAngularZone();
|
|
263
|
-
const viewportSize = this.viewportSize;
|
|
264
|
-
const viewportClientSize = this.viewportClientSize;
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if (thumbPositionFr !== this._thumbPositionFr || thumbSizeFr !== this._thumbSizeFr) {
|
|
269
|
-
this._thumbPositionFr = thumbPositionFr;
|
|
270
|
-
this._thumbSizeFr = thumbSizeFr;
|
|
271
|
-
this.setCssVariable('--ɵsci-scrollbar-thumb-position-fr', thumbPositionFr);
|
|
272
|
-
this.setCssVariable('--ɵsci-scrollbar-thumb-size-fr', thumbSizeFr);
|
|
273
|
-
}
|
|
274
|
-
if (overflow !== this._overflow) {
|
|
275
|
-
this._overflow = overflow;
|
|
276
|
-
overflow ? this._host.classList.add('overflow') : this._host.classList.remove('overflow');
|
|
277
|
-
}
|
|
296
|
+
const viewportSize = this.viewportSize();
|
|
297
|
+
const viewportClientSize = this.viewportClientSize();
|
|
298
|
+
this.thumbPositionFr.set(this.viewportScrollPosition() / viewportClientSize);
|
|
299
|
+
this.thumbSizeFr.set(viewportSize / viewportClientSize);
|
|
300
|
+
this.overflow.set(viewportClientSize > viewportSize);
|
|
278
301
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
onTouchMove(event) {
|
|
284
|
-
event.preventDefault();
|
|
285
|
-
const newDragPositionPx = this.vertical() ? event.touches[0].screenY : event.touches[0].screenX;
|
|
286
|
-
const scrollbarPanPx = newDragPositionPx - this._lastDragPosition();
|
|
287
|
-
const viewportPanPx = this.toViewportPanPx(scrollbarPanPx);
|
|
288
|
-
this._lastDragPosition.set(newDragPositionPx);
|
|
289
|
-
this.moveViewportClient(viewportPanPx);
|
|
290
|
-
}
|
|
291
|
-
onTouchEnd(event) {
|
|
292
|
-
event.preventDefault();
|
|
293
|
-
this._lastDragPosition.set(null);
|
|
294
|
-
}
|
|
295
|
-
onMouseDown(mousedownEvent) {
|
|
302
|
+
/**
|
|
303
|
+
* Method invoked when clicking on the scrollbar thumb.
|
|
304
|
+
*/
|
|
305
|
+
onThumbMouseDown(mousedownEvent) {
|
|
296
306
|
if (mousedownEvent.button !== 0) {
|
|
297
307
|
return;
|
|
298
308
|
}
|
|
309
|
+
this.scrolling.set(true);
|
|
310
|
+
// Prevent text selection during drag.
|
|
299
311
|
mousedownEvent.preventDefault();
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
312
|
+
// Calculate screen offset to convert screen coordinates into client coordinates, required for `sci-mousemove` events which originate from other documents (iframes).
|
|
313
|
+
const { screenOffsetX, screenOffsetY } = calculateScreenOffset(mousedownEvent);
|
|
314
|
+
// Memoize offset where thumb was clicked.
|
|
315
|
+
const thumbStartOffset = this.vertical() ? mousedownEvent.offsetY : mousedownEvent.offsetX;
|
|
316
|
+
// 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.
|
|
317
|
+
const mouseUp$ = race(fromEvent(this._document, 'mouseup', { capture: true, once: true }), fromEvent(this._document, 'sci-mouseup', { once: true }))
|
|
318
|
+
.pipe(tap(mouseupEvent => mouseupEvent.stopPropagation()));
|
|
319
|
+
// Track pointer until mouse release.
|
|
320
|
+
merge(fromEvent(this._document, 'mousemove'), fromEvent(this._document, 'sci-mousemove'))
|
|
321
|
+
.pipe(subscribeIn(fn => this._zone.runOutsideAngular(fn)), takeUntilDestroyed(this._destroyRef), takeUntil(mouseUp$), finalize(() => this.scrolling.set(false)))
|
|
304
322
|
.subscribe(mousemoveEvent => {
|
|
305
323
|
NgZone.assertNotInAngularZone();
|
|
324
|
+
// Prevent user agent scrolling while during drag.
|
|
306
325
|
mousemoveEvent.preventDefault();
|
|
307
|
-
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
this._lastDragPosition.set(newDragPositionPx);
|
|
311
|
-
this.moveViewportClient(viewportPanPx);
|
|
326
|
+
// Calculate new thumb position.
|
|
327
|
+
const pointerPosition = this.vertical() ? mousemoveEvent.screenY - screenOffsetY : mousemoveEvent.screenX - screenOffsetX;
|
|
328
|
+
this.scrollViewport(pointerPosition - thumbStartOffset);
|
|
312
329
|
});
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Method invoked when clicking on the scrollbar track.
|
|
333
|
+
*
|
|
334
|
+
* Scrolls in discrete steps to the pointer, then switches to regular scrolling until releasing the mouse.
|
|
335
|
+
*/
|
|
336
|
+
onScrollTrackMouseDown(event) {
|
|
337
|
+
this.scrolling.set(true);
|
|
338
|
+
// Prevent text selection during drag.
|
|
339
|
+
event.preventDefault();
|
|
340
|
+
const mouseMove$ = merge(fromEvent(this._document, 'mousemove'), fromEvent(this._document, 'sci-mousemove'));
|
|
341
|
+
// Handle the event in the capture phase and stop propagation to not close a potential overlay when releasing the mouse outside the overlay.
|
|
342
|
+
const mouseUp$ = race(fromEvent(this._document, 'mouseup', { capture: true, once: true }), fromEvent(this._document, 'sci-mouseup', { once: true }))
|
|
343
|
+
.pipe(tap(mouseupEvent => mouseupEvent.stopPropagation()));
|
|
344
|
+
// Calculate screen offset to convert screen coordinates into client coordinates, required for `sci-mousemove` events which originate from other documents (iframes).
|
|
345
|
+
const { screenOffsetX, screenOffsetY } = calculateScreenOffset(event);
|
|
346
|
+
// Scroll in discrete steps to the pointer position, then switch to regular scrolling.
|
|
347
|
+
timer(250, 50)
|
|
348
|
+
.pipe(
|
|
349
|
+
// Track current pointer position.
|
|
350
|
+
withLatestFrom(mouseMove$.pipe(startWith(event)), (_tick, event) => event),
|
|
351
|
+
// Scroll immediately on initial click.
|
|
352
|
+
startWith(event), subscribeIn(fn => this._zone.runOutsideAngular(fn)), exhaustMap(event => {
|
|
353
|
+
const pointerPosition = this.vertical() ? event.screenY - screenOffsetY : event.screenX - screenOffsetX;
|
|
354
|
+
const [thumbStartPosition, thumbEndPosition] = this.thumbPosition();
|
|
355
|
+
const thumbSize = thumbEndPosition - thumbStartPosition;
|
|
356
|
+
// Step scroll until the pointer hits the thumb.
|
|
357
|
+
if (!isBetween(pointerPosition, { from: thumbStartPosition - thumbSize, to: thumbEndPosition + thumbSize })) {
|
|
358
|
+
const scrollingDown = pointerPosition > thumbEndPosition;
|
|
359
|
+
return of(scrollingDown ? thumbStartPosition + thumbSize : thumbStartPosition - thumbSize);
|
|
360
|
+
}
|
|
361
|
+
// Switch to "smooth scrolling" following the pointer.
|
|
362
|
+
return of(event)
|
|
363
|
+
.pipe(concatWith(mouseMove$), map(event => (this.vertical() ? event.screenY - screenOffsetY : event.screenX - screenOffsetX) - (thumbSize / 2)));
|
|
364
|
+
}),
|
|
365
|
+
// Stop on mouse release.
|
|
366
|
+
takeUntil(mouseUp$), finalize(() => this.scrolling.set(false)))
|
|
367
|
+
.subscribe((thumbPosition) => {
|
|
317
368
|
NgZone.assertNotInAngularZone();
|
|
318
|
-
|
|
319
|
-
mousemoveListener.unsubscribe();
|
|
320
|
-
this._lastDragPosition.set(null);
|
|
369
|
+
this.scrollViewport(thumbPosition);
|
|
321
370
|
});
|
|
322
371
|
}
|
|
323
|
-
onScrollTrackMouseDown(event, direction) {
|
|
324
|
-
const signum = (direction === 'up' ? -1 : 1);
|
|
325
|
-
this.scrollWhileMouseDown(this.toViewportPanPx(signum * this.thumbSize), event);
|
|
326
|
-
}
|
|
327
372
|
/**
|
|
328
373
|
* Renders the current scroll position when the viewport is scrolled.
|
|
329
374
|
*/
|
|
@@ -339,74 +384,87 @@ class SciScrollbarComponent {
|
|
|
339
384
|
});
|
|
340
385
|
}
|
|
341
386
|
/**
|
|
342
|
-
*
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
const scrollRangePx = this.trackSize - this.thumbSize;
|
|
346
|
-
const scrollRatio = scrollbarPanPx / scrollRangePx;
|
|
347
|
-
return scrollRatio * (this.viewportClientSize - this.viewportSize);
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Moves the viewport client by the specified numbers of pixels.
|
|
387
|
+
* Moves the scrollbar thumb to the specified position, scrolling the viewport accordingly.
|
|
388
|
+
*
|
|
389
|
+
* The thumb position must be given in client coordinates (relative to the top-left corner of the page viewport).
|
|
351
390
|
*/
|
|
352
|
-
|
|
391
|
+
scrollViewport(thumbPosition) {
|
|
392
|
+
const [scrollbarComponentStartPosition] = this.scrollbarComponentPosition();
|
|
393
|
+
const scrollbarBorderWidth = this.vertical() ? this._host.clientTop : this._host.clientLeft;
|
|
394
|
+
const scrollRatio = clamp((thumbPosition - scrollbarComponentStartPosition - scrollbarBorderWidth) / (this.trackSize() - this.thumbSize()), { min: 0, max: 1 });
|
|
395
|
+
const viewportScrollPosition = scrollRatio * (this.viewportClientSize() - this.viewportSize());
|
|
353
396
|
if (this.vertical()) {
|
|
354
|
-
this.viewport().scrollTop
|
|
397
|
+
this.viewport().scrollTop = viewportScrollPosition;
|
|
355
398
|
}
|
|
356
399
|
else {
|
|
357
|
-
this.viewport().scrollLeft
|
|
400
|
+
this.viewport().scrollLeft = viewportScrollPosition;
|
|
358
401
|
}
|
|
359
402
|
}
|
|
360
403
|
/**
|
|
361
|
-
*
|
|
404
|
+
* Returns the position of this component in client coordinates.
|
|
405
|
+
*
|
|
406
|
+
* Returned coordinates are relative to the top-left corner of the page viewport.
|
|
407
|
+
* Depending on the scrollbar orientation, returned coordinates are `[top, bottom]` or `[left, right]`.
|
|
362
408
|
*/
|
|
363
|
-
|
|
364
|
-
|
|
409
|
+
scrollbarComponentPosition() {
|
|
410
|
+
const boundingBox = this._host.getBoundingClientRect();
|
|
411
|
+
return this.vertical() ? [boundingBox.top, boundingBox.bottom] : [boundingBox.left, boundingBox.right];
|
|
365
412
|
}
|
|
366
413
|
/**
|
|
367
|
-
*
|
|
414
|
+
* Returns the size of the viewport in pixels.
|
|
415
|
+
*
|
|
416
|
+
* The viewport is the container for scrollable content (viewport client), displaying scrollbars if it overflows.
|
|
417
|
+
* Depending on the scrollbar orientation, the returned size is `viewport.clientHeight` or `viewport.clientWidth`.
|
|
368
418
|
*/
|
|
369
|
-
|
|
370
|
-
// The `EventTarget` type of `Event.target` is not yet compatible with `FromEventTarget` used in `fromEvent`.
|
|
371
|
-
// This will be fixed in rxjs version 7.0.0. Refer to https://github.com/ReactiveX/rxjs/commit/5f022d784570684632e6fd5ae247fc259ee34c4b
|
|
372
|
-
// for more details.
|
|
373
|
-
const scrollTrackElement = mousedownEvent.target;
|
|
374
|
-
// scroll continuously every 50ms after an initial delay of 250ms
|
|
375
|
-
timer(250, 50)
|
|
376
|
-
.pipe(
|
|
377
|
-
// continue chain with latest mouse event
|
|
378
|
-
withLatestFrom(merge(of(mousedownEvent), fromEvent(scrollTrackElement, 'mousemove')), (tick, event) => event),
|
|
379
|
-
// start immediately
|
|
380
|
-
startWith(mousedownEvent),
|
|
381
|
-
// stop scrolling if the thumb hits the mouse pointer position
|
|
382
|
-
takeWhile((event) => scrollTrackElement === this._document.elementFromPoint(event.clientX, event.clientY)), debounceTime(10),
|
|
383
|
-
// stop scrolling on mouseout or mouseup
|
|
384
|
-
takeUntil(merge(fromEvent(scrollTrackElement, 'mouseout'), fromEvent(scrollTrackElement, 'mouseup'))))
|
|
385
|
-
.subscribe(() => {
|
|
386
|
-
this.moveViewportClient(viewportScrollPx);
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
setCssVariable(key, value) {
|
|
390
|
-
this._host.style.setProperty(key, `${value}`);
|
|
391
|
-
}
|
|
392
|
-
get viewportSize() {
|
|
419
|
+
viewportSize() {
|
|
393
420
|
return this.vertical() ? this.viewport().clientHeight : this.viewport().clientWidth;
|
|
394
421
|
}
|
|
395
|
-
|
|
422
|
+
/**
|
|
423
|
+
* Returns the size of the viewport client in pixels.
|
|
424
|
+
*
|
|
425
|
+
* The viewport client represents scrollable content displayed in the viewport.
|
|
426
|
+
* Depending on the scrollbar orientation, the returned size is `viewport.scrollHeight` or `viewport.scrollWidth`.
|
|
427
|
+
*/
|
|
428
|
+
viewportClientSize() {
|
|
396
429
|
return this.vertical() ? this.viewport().scrollHeight : this.viewport().scrollWidth;
|
|
397
430
|
}
|
|
398
|
-
|
|
431
|
+
/**
|
|
432
|
+
* Returns the viewport's scroll position in pixels.
|
|
433
|
+
*
|
|
434
|
+
* Depending on the scrollbar orientation, the returned position is `viewport.scrollTop` or `viewport.scrollLeft`.
|
|
435
|
+
*/
|
|
436
|
+
viewportScrollPosition() {
|
|
399
437
|
return this.vertical() ? this.viewport().scrollTop : this.viewport().scrollLeft;
|
|
400
438
|
}
|
|
401
|
-
|
|
439
|
+
/**
|
|
440
|
+
* Returns the size of the scrollbar thumb in pixels.
|
|
441
|
+
*
|
|
442
|
+
* The thumb is the handle used to scroll the scrollbar.
|
|
443
|
+
*/
|
|
444
|
+
thumbSize() {
|
|
402
445
|
const thumbElement = this._thumbElement().nativeElement;
|
|
403
|
-
return this.vertical() ? thumbElement.
|
|
446
|
+
return this.vertical() ? thumbElement.offsetHeight : thumbElement.offsetWidth;
|
|
404
447
|
}
|
|
405
|
-
|
|
448
|
+
/**
|
|
449
|
+
* Returns the current thumb position in client coordinates.
|
|
450
|
+
*
|
|
451
|
+
* Returned coordinates are relative to the top-left corner of the page viewport.
|
|
452
|
+
* Depending on the scrollbar orientation, returned coordinates are `[top, bottom]` or `[left, right]`.
|
|
453
|
+
*/
|
|
454
|
+
thumbPosition() {
|
|
455
|
+
const boundingBox = this._thumbElement().nativeElement.getBoundingClientRect();
|
|
456
|
+
return this.vertical() ? [boundingBox.top, boundingBox.bottom] : [boundingBox.left, boundingBox.right];
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Returns the size of the scrollbar track in pixels.
|
|
460
|
+
*
|
|
461
|
+
* The scrollbar track is the track along which the scrollbar thumb moves.
|
|
462
|
+
*/
|
|
463
|
+
trackSize() {
|
|
406
464
|
return this.vertical() ? this._host.clientHeight : this._host.clientWidth;
|
|
407
465
|
}
|
|
408
466
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciScrollbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
409
|
-
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()" } }, viewQueries: [{ propertyName: "_thumbElement", first: true, predicate: ["thumb_handle"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- scrolltrack
|
|
467
|
+
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"] });
|
|
410
468
|
}
|
|
411
469
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciScrollbarComponent, decorators: [{
|
|
412
470
|
type: Component,
|
|
@@ -414,10 +472,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
414
472
|
'[class.vertical]': 'vertical()',
|
|
415
473
|
'[class.horizontal]': 'horizontal()',
|
|
416
474
|
'[class.scrolling]': 'scrolling()',
|
|
417
|
-
|
|
475
|
+
'[class.overflow]': 'overflow()',
|
|
476
|
+
'[style.--ɵsci-scrollbar-thumb-position-fr]': 'thumbPositionFr()',
|
|
477
|
+
'[style.--ɵsci-scrollbar-thumb-size-fr]': 'thumbSizeFr()',
|
|
478
|
+
}, 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"] }]
|
|
418
479
|
}], ctorParameters: () => [], propDecorators: { direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], viewport: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewport", required: true }] }], _thumbElement: [{ type: i0.ViewChild, args: ['thumb_handle', { isSignal: true }] }] } });
|
|
419
480
|
/**
|
|
420
|
-
* Emits whenever the viewport
|
|
481
|
+
* Emits whenever the viewport is scrolled.
|
|
421
482
|
*/
|
|
422
483
|
function viewportScroll$(viewport) {
|
|
423
484
|
return fromEvent(viewport, 'scroll', { passive: true }).pipe(map(() => undefined));
|
|
@@ -452,7 +513,37 @@ function viewportClientSize$(viewport, options) {
|
|
|
452
513
|
*/
|
|
453
514
|
function children$(element) {
|
|
454
515
|
return fromMutation$(element, { subtree: false, childList: true })
|
|
455
|
-
.pipe(startWith(undefined), map(() => Array.from(element.children)
|
|
516
|
+
.pipe(startWith(undefined), map(() => Array.from(element.children)
|
|
517
|
+
// Map to slotted content if a slot (Shadow DOM).
|
|
518
|
+
.flatMap(child => child instanceof HTMLSlotElement ? child.assignedElements() : child)
|
|
519
|
+
// Filter HTML elements.
|
|
520
|
+
.filter((child) => child instanceof HTMLElement)));
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Returns the value clamped to the inclusive range of min and max.
|
|
524
|
+
*/
|
|
525
|
+
function clamp(value, minmax) {
|
|
526
|
+
return Math.max(minmax.min, Math.min(value, minmax.max));
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Returns whether the value is between the specified range (inclusive).
|
|
530
|
+
*/
|
|
531
|
+
function isBetween(value, range) {
|
|
532
|
+
return value >= range.from && value <= range.to;
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Calculates the distance between the top-left corner of the screen (monitor) and the top-left corner of the page viewport of this document.
|
|
536
|
+
*
|
|
537
|
+
* Use to convert screen coordinates from `sci-mousemove` and `sci-mouseup` events into client coordinates relative to the page viewport of the current document.
|
|
538
|
+
*
|
|
539
|
+
* 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
|
|
540
|
+
* relative to the source document, not the current one.
|
|
541
|
+
*/
|
|
542
|
+
function calculateScreenOffset(mousedownEvent) {
|
|
543
|
+
return {
|
|
544
|
+
screenOffsetX: mousedownEvent.screenX - mousedownEvent.clientX,
|
|
545
|
+
screenOffsetY: mousedownEvent.screenY - mousedownEvent.clientY,
|
|
546
|
+
};
|
|
456
547
|
}
|
|
457
548
|
|
|
458
549
|
/*
|
|
@@ -544,7 +635,6 @@ class SciViewportComponent {
|
|
|
544
635
|
_host = inject(ElementRef).nativeElement;
|
|
545
636
|
_viewport = viewChild.required('viewport');
|
|
546
637
|
_viewportClient = viewChild.required('viewport_client');
|
|
547
|
-
nativeScrollbarTrackSizeProvider = inject(SciNativeScrollbarTrackSizeProvider);
|
|
548
638
|
constructor() {
|
|
549
639
|
this.installScrollEmitter();
|
|
550
640
|
}
|
|
@@ -708,7 +798,7 @@ class SciViewportComponent {
|
|
|
708
798
|
});
|
|
709
799
|
}
|
|
710
800
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciViewportComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
711
|
-
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' &&
|
|
801
|
+
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'\" #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 });
|
|
712
802
|
}
|
|
713
803
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: SciViewportComponent, decorators: [{
|
|
714
804
|
type: Component,
|
|
@@ -718,7 +808,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
718
808
|
CdkScrollable,
|
|
719
809
|
], changeDetection: ChangeDetectionStrategy.Eager, host: {
|
|
720
810
|
'(focus)': 'focus()',
|
|
721
|
-
}, 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' &&
|
|
811
|
+
}, 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"] }]
|
|
722
812
|
}], 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 }] }] } });
|
|
723
813
|
|
|
724
814
|
/*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scion-components-viewport.mjs","sources":["../../../../projects/scion/components/viewport/src/native-scrollbar-track-size-provider.service.ts","../../../../projects/scion/components/viewport/src/scrollable.directive.ts","../../../../projects/scion/components/viewport/src/scrollbar/scrollbar.component.ts","../../../../projects/scion/components/viewport/src/scrollbar/scrollbar.component.html","../../../../projects/scion/components/viewport/src/viewport.component.ts","../../../../projects/scion/components/viewport/src/viewport.component.html","../../../../projects/scion/components/viewport/src/public_api.ts","../../../../projects/scion/components/viewport/src/scion-components-viewport.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 {inject, Injectable, NgZone, Signal, DOCUMENT} from '@angular/core';\nimport {fromEvent} from 'rxjs';\nimport {debounceTime, distinctUntilChanged, map, startWith} from 'rxjs/operators';\nimport {toSignal} from '@angular/core/rxjs-interop';\nimport {subscribeIn} from '@scion/toolkit/operators';\n\n/**\n * Provides the native scrollbar tracksize.\n */\n@Injectable({providedIn: 'root'})\nexport class SciNativeScrollbarTrackSizeProvider {\n\n private readonly _document = inject(DOCUMENT);\n private readonly _zone = inject(NgZone);\n\n /**\n * Provides the track size of the native scrollbar, or `null` if the native scrollbars sit on top of the content.\n */\n public trackSize: Signal<NativeScrollbarTrackSize | null>;\n\n constructor() {\n this.trackSize = this.createNativeScrollbarTrackSizeSignal();\n }\n\n /**\n * Computes the native scrollbar track size.\n *\n * @returns native track size, or `null` if the native scrollbars sit on top of the content.\n */\n private computeTrackSize(): NativeScrollbarTrackSize | null {\n // Create temporary viewport and viewport client with native scrollbars to compute the scrolltrack width.\n const viewportDiv = this._document.createElement('div');\n setStyle(viewportDiv, {\n position: 'absolute',\n overflow: 'scroll',\n height: '100px',\n width: '100px',\n border: '0',\n visibility: 'hidden',\n });\n\n const viewportClientDiv = this._document.createElement('div');\n setStyle(viewportClientDiv, {\n height: '100%',\n width: '100%',\n border: '0',\n });\n\n viewportDiv.appendChild(viewportClientDiv);\n this._document.body.appendChild(viewportDiv);\n\n // Do not use client and offset width/height to calculate the size of the scrollbar, as they are rounded, resulting in unwanted spacing when zooming the page.\n const viewportBounds = viewportDiv.getBoundingClientRect();\n const viewportClientBounds = viewportClientDiv.getBoundingClientRect();\n const trackSize: NativeScrollbarTrackSize = {\n hScrollbarTrackHeight: viewportBounds.height - viewportClientBounds.height,\n vScrollbarTrackWidth: viewportBounds.width - viewportClientBounds.width,\n };\n\n // Destroy temporary viewport.\n this._document.body.removeChild(viewportDiv);\n if (trackSize.hScrollbarTrackHeight === 0 && trackSize.vScrollbarTrackWidth === 0) {\n return null;\n }\n\n return trackSize;\n }\n\n private createNativeScrollbarTrackSizeSignal(): Signal<NativeScrollbarTrackSize | null> {\n // We compute the size of the native scrollbar track when the browser fires the onresize window event.\n // This event is also fired on page zoom or when displaying a hidden document. Hidden documents do not have\n // a scrollbar track size until being displayed, e.g., after showing hidden iframes.\n const trackSize$ = fromEvent(window, 'resize')\n .pipe(\n subscribeIn(fn => this._zone.runOutsideAngular(fn)),\n debounceTime(5),\n startWith(null), // trigger the initial computation\n map(() => this.computeTrackSize()),\n distinctUntilChanged((t1, t2) => t1?.hScrollbarTrackHeight === t2?.hScrollbarTrackHeight && t1?.vScrollbarTrackWidth === t2?.vScrollbarTrackWidth),\n );\n return toSignal(trackSize$, {initialValue: null});\n }\n}\n\n/**\n * Applies the given style(s) to the given element.\n *\n * Specify styles to be modified by passing a dictionary containing CSS property names (hyphen case).\n * To remove a style, set its value to `null`.\n *\n * @ignore\n */\nfunction setStyle(element: HTMLElement, styles: {[style: string]: string}): void {\n Object.entries(styles).forEach(([name, value]) => element.style.setProperty(name, value));\n}\n\n/**\n * Represents the native scrollbar track size.\n */\nexport interface NativeScrollbarTrackSize {\n hScrollbarTrackHeight: number;\n vScrollbarTrackWidth: number;\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\nimport {Directive, effect, ElementRef, inject, input, Renderer2, untracked} from '@angular/core';\nimport {NativeScrollbarTrackSize, SciNativeScrollbarTrackSizeProvider} from './native-scrollbar-track-size-provider.service';\nimport {Dictionary} from '@scion/toolkit/util';\n\n/**\n * Makes the host element natively scrollable and hides native scrollbars by default, unless native scrollbars\n * already sit on top of the viewport (e.g. in OS X).\n *\n * Because there is no cross-browser API to hide scrollbars without losing native scroll support, we set 'overflow'\n * to 'scroll' but shift the native scrollbars out of the visible viewport area. The shift offset is computed upfront.\n *\n * This directive expects its host element to be the only child in document flow in its parent DOM element. It makes the host element\n * fill up the entire space (width and height set to 100%). The parent element must have its CSS `overflow` property set to `hidden`\n * to hide the pushed out native scrollbars.\n */\n@Directive({selector: '[sciScrollable]'})\nexport class SciScrollableDirective {\n\n /**\n * Controls whether to display native scrollbars.\n * Has no effect if the native scrollbar sits on top of the content, e.g. in OS X.\n */\n public readonly displayNativeScrollbar = input(false, {alias: 'sciScrollableDisplayNativeScrollbar'});\n\n private readonly _host = inject(ElementRef<HTMLDivElement>).nativeElement as HTMLElement;\n private readonly _renderer = inject(Renderer2);\n private readonly _nativeScrollbarTrackSizeProvider = inject(SciNativeScrollbarTrackSizeProvider);\n\n constructor() {\n this.controlDisplayOfNativeScrollbar();\n }\n\n /**\n * Controls the display of the native scrollbar based on this directive's configuration.\n */\n private controlDisplayOfNativeScrollbar(): void {\n effect(() => {\n const displayNativeScrollbar = this.displayNativeScrollbar();\n if (displayNativeScrollbar) {\n untracked(() => this.useNativeScrollbars());\n return;\n }\n\n const nativeScrollbarTrackSize = this._nativeScrollbarTrackSizeProvider.trackSize();\n if (nativeScrollbarTrackSize) {\n untracked(() => this.shiftNativeScrollbars(nativeScrollbarTrackSize));\n }\n else {\n untracked(() => this.useNativeScrollbars());\n }\n });\n }\n\n /**\n * Uses the native scrollbars when content overflows.\n */\n private useNativeScrollbars(): void {\n this.setStyle(this._host, {\n overflow: 'auto',\n width: '100%',\n height: '100%',\n marginRight: 0,\n marginBottom: 0,\n });\n }\n\n /**\n * Shifts the native scrollbars out of the visible viewport area.\n */\n private shiftNativeScrollbars(nativeScrollbarTrackSize: NativeScrollbarTrackSize): void {\n this.setStyle(this._host, {\n overflow: 'scroll',\n width: `calc(100% + ${nativeScrollbarTrackSize.vScrollbarTrackWidth}px`,\n height: `calc(100% + ${nativeScrollbarTrackSize.hScrollbarTrackHeight}px`,\n marginRight: `-${nativeScrollbarTrackSize.vScrollbarTrackWidth}px`,\n marginBottom: `-${nativeScrollbarTrackSize.hScrollbarTrackHeight}px`,\n });\n }\n\n private setStyle(element: Element, style: Dictionary): void {\n Object.keys(style).forEach(key => this._renderer.setStyle(element, key, style[key]));\n }\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\nimport {Component, computed, DestroyRef, DOCUMENT, effect, ElementRef, inject, input, NgZone, signal, untracked, viewChild} from '@angular/core';\nimport {fromEvent, merge, mergeWith, Observable, of, timer} from 'rxjs';\nimport {debounceTime, first, map, startWith, switchMap, takeUntil, takeWhile, withLatestFrom} from 'rxjs/operators';\nimport {fromMutation$, fromResize$} from '@scion/toolkit/observable';\nimport {filterArray, subscribeIn} from '@scion/toolkit/operators';\nimport {takeUntilDestroyed} from '@angular/core/rxjs-interop';\n\n/**\n * Renders a vertical or horizontal scrollbar.\n *\n * The scrollbar features the following functionality:\n * - allows to move the thumb by mouse or touch\n * - enlarges the thumb if the mouse pointer is near the thumb\n * - allows paging on mousedown on the scroll track\n *\n * ### Styling:\n *\n * To customize the default look of SCION components or support different themes, configure the `@scion/components` SCSS module in `styles.scss`.\n * To style a specific `sci-scrollbar` component, the following CSS variables can be set directly on the component.\n *\n * - sci-scrollbar-color: Sets the color of the scrollbar.\n *\n * Example:\n *\n * ```css\n *\n * sci-scrollbar {\n * --sci-scrollbar-color: blue;\n * }\n * ```\n */\n@Component({\n selector: 'sci-scrollbar',\n templateUrl: './scrollbar.component.html',\n styleUrl: './scrollbar.component.scss',\n host: {\n '[class.vertical]': 'vertical()',\n '[class.horizontal]': 'horizontal()',\n '[class.scrolling]': 'scrolling()',\n },\n})\nexport class SciScrollbarComponent {\n\n /**\n * Timeout for debouncing viewport resize events that trigger the scroll position computation.\n *\n * Debouncing is particularly important in the context of Angular animations, since they continuously\n * trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user\n * expands a panel that contains a viewport.\n *\n * @internal\n */\n public static readonly VIEWPORT_RESIZE_DEBOUNCE_TIME = 50;\n\n /**\n * Specifies the direction of the scrollbar. Defaults to a vertical scrollbar.\n */\n public readonly direction = input<'vscroll' | 'hscroll'>('vscroll');\n\n /**\n * The viewport to provide scrollbars for.\n */\n public readonly viewport = input.required<HTMLElement>();\n\n private readonly _host = inject(ElementRef).nativeElement as HTMLElement;\n private readonly _document = inject(DOCUMENT);\n private readonly _zone = inject(NgZone);\n private readonly _destroyRef = inject(DestroyRef);\n private readonly _thumbElement = viewChild.required<ElementRef<HTMLDivElement>>('thumb_handle');\n private readonly _lastDragPosition = signal<number | null>(null);\n\n protected readonly vertical = computed(() => this.direction() === 'vscroll');\n protected readonly horizontal = computed(() => !this.vertical());\n protected readonly scrolling = computed(() => this._lastDragPosition() !== null);\n\n private _overflow = false;\n private _thumbSizeFr = 0;\n private _thumbPositionFr = 0;\n\n constructor() {\n this.installScrollPositionRenderer();\n }\n\n /**\n * Computes the scroll position and updates CSS variables to render the scroll position in the UI.\n */\n private renderScrollPosition(): void {\n NgZone.assertNotInAngularZone();\n const viewportSize = this.viewportSize;\n const viewportClientSize = this.viewportClientSize;\n const thumbPositionFr = this.scrollPosition / viewportClientSize;\n const thumbSizeFr = viewportSize / viewportClientSize;\n const overflow = viewportClientSize > viewportSize;\n\n if (thumbPositionFr !== this._thumbPositionFr || thumbSizeFr !== this._thumbSizeFr) {\n this._thumbPositionFr = thumbPositionFr;\n this._thumbSizeFr = thumbSizeFr;\n this.setCssVariable('--ɵsci-scrollbar-thumb-position-fr', thumbPositionFr);\n this.setCssVariable('--ɵsci-scrollbar-thumb-size-fr', thumbSizeFr);\n }\n\n if (overflow !== this._overflow) {\n this._overflow = overflow;\n overflow ? this._host.classList.add('overflow') : this._host.classList.remove('overflow');\n }\n }\n\n protected onTouchStart(event: TouchEvent): void {\n event.preventDefault();\n this._lastDragPosition.set(this.vertical() ? event.touches[0]!.screenY : event.touches[0]!.screenX);\n }\n\n protected onTouchMove(event: TouchEvent): void {\n event.preventDefault();\n\n const newDragPositionPx = this.vertical() ? event.touches[0]!.screenY : event.touches[0]!.screenX;\n const scrollbarPanPx = newDragPositionPx - this._lastDragPosition()!;\n const viewportPanPx = this.toViewportPanPx(scrollbarPanPx);\n this._lastDragPosition.set(newDragPositionPx);\n this.moveViewportClient(viewportPanPx);\n }\n\n protected onTouchEnd(event: TouchEvent): void {\n event.preventDefault();\n this._lastDragPosition.set(null);\n }\n\n protected onMouseDown(mousedownEvent: MouseEvent): void {\n if (mousedownEvent.button !== 0) {\n return;\n }\n\n mousedownEvent.preventDefault();\n this._lastDragPosition.set(this.vertical() ? mousedownEvent.screenY : mousedownEvent.screenX);\n\n // Listen for 'mousemove' events\n const mousemoveListener = merge(fromEvent<MouseEvent>(this._document, 'mousemove'), fromEvent<MouseEvent>(this._document, 'sci-mousemove'))\n .pipe(\n subscribeIn(fn => this._zone.runOutsideAngular(fn)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(mousemoveEvent => {\n NgZone.assertNotInAngularZone();\n mousemoveEvent.preventDefault();\n const newDragPositionPx = this.vertical() ? mousemoveEvent.screenY : mousemoveEvent.screenX;\n const scrollbarPanPx = newDragPositionPx - this._lastDragPosition()!;\n const viewportPanPx = this.toViewportPanPx(scrollbarPanPx);\n this._lastDragPosition.set(newDragPositionPx);\n this.moveViewportClient(viewportPanPx);\n });\n\n // Listen for 'mouseup' events; use 'capture phase' and 'stop propagation' to not close overlays\n merge(fromEvent<MouseEvent>(this._document, 'mouseup', {capture: true}), fromEvent<MouseEvent>(this._document, 'sci-mouseup'))\n .pipe(\n subscribeIn(fn => this._zone.runOutsideAngular(fn)),\n first(),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(mouseupEvent => {\n NgZone.assertNotInAngularZone();\n mouseupEvent.stopPropagation();\n mousemoveListener.unsubscribe();\n this._lastDragPosition.set(null);\n });\n }\n\n protected onScrollTrackMouseDown(event: MouseEvent, direction: 'up' | 'down'): void {\n const signum = (direction === 'up' ? -1 : 1);\n this.scrollWhileMouseDown(this.toViewportPanPx(signum * this.thumbSize), event);\n }\n\n /**\n * Renders the current scroll position when the viewport is scrolled.\n */\n private installScrollPositionRenderer(): void {\n effect(onCleanup => {\n const viewport = this.viewport();\n\n untracked(() => {\n const subscription = viewportScroll$(viewport)\n .pipe(\n mergeWith(viewportSize$(viewport, {debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME})),\n mergeWith(viewportClientSize$(viewport, {debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME})),\n subscribeIn(fn => this._zone.runOutsideAngular(fn)),\n )\n .subscribe(() => this.renderScrollPosition());\n onCleanup(() => subscription.unsubscribe());\n });\n });\n }\n\n /**\n * Projects the given scrollbar scroll pixels into viewport scroll pixels.\n */\n private toViewportPanPx(scrollbarPanPx: number): number {\n const scrollRangePx = this.trackSize - this.thumbSize;\n const scrollRatio = scrollbarPanPx / scrollRangePx;\n return scrollRatio * (this.viewportClientSize - this.viewportSize);\n }\n\n /**\n * Moves the viewport client by the specified numbers of pixels.\n */\n private moveViewportClient(viewportPanPx: number): void {\n if (this.vertical()) {\n this.viewport().scrollTop += viewportPanPx;\n }\n else {\n this.viewport().scrollLeft += viewportPanPx;\n }\n }\n\n /**\n * Indicates if the content overflows.\n */\n public get overflow(): boolean {\n return this._overflow;\n }\n\n /**\n * Scrolls continuously while holding the mouse pressed, or until the mouse leaves the scrolltrack.\n */\n private scrollWhileMouseDown(viewportScrollPx: number, mousedownEvent: MouseEvent): void {\n // The `EventTarget` type of `Event.target` is not yet compatible with `FromEventTarget` used in `fromEvent`.\n // This will be fixed in rxjs version 7.0.0. Refer to https://github.com/ReactiveX/rxjs/commit/5f022d784570684632e6fd5ae247fc259ee34c4b\n // for more details.\n const scrollTrackElement = mousedownEvent.target as Element;\n\n // scroll continuously every 50ms after an initial delay of 250ms\n timer(250, 50)\n .pipe(\n // continue chain with latest mouse event\n withLatestFrom(merge(of(mousedownEvent), fromEvent<MouseEvent>(scrollTrackElement, 'mousemove')), (tick, event) => event),\n // start immediately\n startWith(mousedownEvent),\n // stop scrolling if the thumb hits the mouse pointer position\n takeWhile((event: MouseEvent) => scrollTrackElement === this._document.elementFromPoint(event.clientX, event.clientY)),\n debounceTime(10),\n // stop scrolling on mouseout or mouseup\n takeUntil(merge(fromEvent(scrollTrackElement, 'mouseout'), fromEvent(scrollTrackElement, 'mouseup'))),\n )\n .subscribe(() => {\n this.moveViewportClient(viewportScrollPx);\n });\n }\n\n private setCssVariable(key: string, value: number): void {\n this._host.style.setProperty(key, `${value}`);\n }\n\n private get viewportSize(): number {\n return this.vertical() ? this.viewport().clientHeight : this.viewport().clientWidth;\n }\n\n private get viewportClientSize(): number {\n return this.vertical() ? this.viewport().scrollHeight : this.viewport().scrollWidth;\n }\n\n private get scrollPosition(): number {\n return this.vertical() ? this.viewport().scrollTop : this.viewport().scrollLeft;\n }\n\n private get thumbSize(): number {\n const thumbElement = this._thumbElement().nativeElement;\n return this.vertical() ? thumbElement.clientHeight : thumbElement.clientWidth;\n }\n\n private get trackSize(): number {\n return this.vertical() ? this._host.clientHeight : this._host.clientWidth;\n }\n}\n\n/**\n * Emits whenever the viewport scrolls.\n */\nfunction viewportScroll$(viewport: HTMLElement): Observable<void> {\n return fromEvent(viewport, 'scroll', {passive: true}).pipe(map(() => undefined));\n}\n\n/**\n * Emits on subscription, and then each time the size of the viewport changes.\n */\nfunction viewportSize$(viewport: HTMLElement, options: {debounceTime: number}): Observable<void> {\n return fromResize$(viewport)\n .pipe(\n // Debouncing is particularly important in the context of Angular animations, since they continuously\n // trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user\n // expands a panel that contains a viewport.\n debounceTime(options.debounceTime),\n map(() => undefined),\n );\n}\n\n/**\n * Emits on subscription, and then each time the size or style property of the viewport client changes.\n */\nfunction viewportClientSize$(viewport: HTMLElement, options: {debounceTime: number}): Observable<void> {\n return children$(viewport)\n .pipe(\n switchMap(children => merge(...children.map(child => merge(\n fromResize$(child),\n // Observe style mutations since some transformations change the scroll position without necessarily triggering a dimension change,\n // e.g., `scale` or `translate` used by some virtual scroll implementations\n fromMutation$(child, {subtree: false, childList: false, attributeFilter: ['style']})),\n ))),\n // Debouncing is particularly important in the context of Angular animations, since they continuously\n // trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user\n // expands a panel that contains a viewport.\n debounceTime(options.debounceTime),\n map(() => undefined),\n );\n}\n\n/**\n * Emits the children of the passed element, and then each time child elements are added or removed.\n */\nfunction children$(element: HTMLElement): Observable<HTMLElement[]> {\n return fromMutation$(element, {subtree: false, childList: true})\n .pipe(\n startWith(undefined as void),\n map(() => Array.from(element.children)),\n filterArray((child: Element): child is HTMLElement => child instanceof HTMLElement),\n );\n}\n","<!-- scrolltrack to move the viewport client upwards (paging) -->\n<div class=\"scrolltrack-start\" (mousedown)=\"onScrollTrackMouseDown($event, 'up')\"></div>\n\n<!-- scrollthumb -->\n<div #thumb_handle\n class=\"thumb-handle\"\n [class.vertical]=\"vertical()\"\n [class.horizontal]=\"horizontal()\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd($event)\"\n (touchcancel)=\"onTouchEnd($event)\">\n <div class=\"thumb\"\n [class.vertical]=\"vertical()\"\n [class.horizontal]=\"horizontal()\">\n </div>\n</div>\n\n<!-- scrolltrack to move the viewport client downwards (paging) -->\n<div class=\"scrolltrack-end\" (mousedown)=\"onScrollTrackMouseDown($event, 'down')\"></div>\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\nimport {Component, effect, ElementRef, inject, input, NgZone, output, untracked, viewChild, ViewEncapsulation, ChangeDetectionStrategy} from '@angular/core';\nimport {SciNativeScrollbarTrackSizeProvider} from './native-scrollbar-track-size-provider.service';\nimport {coerceElement} from '@angular/cdk/coercion';\nimport {SciScrollableDirective} from './scrollable.directive';\nimport {SciScrollbarComponent} from './scrollbar/scrollbar.component';\nimport {fromEvent} from 'rxjs';\nimport {subscribeIn} from '@scion/toolkit/operators';\nimport {CdkScrollable} from '@angular/cdk/scrolling';\n\n/**\n * Represents a viewport with slotted content (`<ng-content>`) used as scrollable content. By default, content is added to a CSS grid layout.\n *\n * The viewport component displays scrollbars when its content overflows. Scrollbars are displayed on top of the content, not next to it.\n * The component uses the native scrollbars of the operating system if they are already sitting on top, or falls back and renders scrollbars on top otherwise.\n * The viewport remains natively scrollable with the native scrollbars shifted out of the viewport's visible area. Consequently, the viewport keeps supporting\n * native scrolling features such as touch gestures, scroll speed acceleration, or scrolling near the viewport edges during drag-and-drop operations.\n *\n * ```html\n * <sci-viewport>\n * your content\n * </sci-viewport>\n * ```\n *\n * ## Adding the viewport to a layout\n *\n * Typically, you would add the viewport component to a flexible layout, filling the remaining space vertically and horizontally, such as a flexbox container\n * with the viewport's `flex` CSS property set to either `flex: auto` or `flex: 1 1 0`.\n *\n * The viewport is sized according to its content width and height. It grows to absorb any free space, thus overflowing its content only when encountering\n * a layout constraint. Depending on the layout, different steps may be necessary to prevent the viewport from growing to infinity.\n *\n * - If practical, give the viewport a fixed size or a maximum size.\n * - If you add the viewport to a flexbox layout, make sure that it cannot exceed the available space. Instead, the viewport should fill the remaining space,\n * vertically and horizontally. Be aware that, by default, a flex item does not shrink below its minimum content size. To change this, set the viewport's\n * `flex-basis` to `0` (instead of `auto`), or use the CSS shorthand property `flex: 1 1 0`. The `flex-basis` defines the default size of a flex item before\n * the remaining extra space is distributed. If the viewport does not appear after setting this property, check its parent elements' content sizes.\n * As an alternative to setting `flex: 1 1 0`, change the setting to `flex: auto` and hide the overflow in the parent element, as follows: `overflow: hidden`.\n * Another approach would be to set the minimum height of all parents to `0`, as follows: `min-height: 0`.\n *\n * For the complete documentation on the flex layout and its features, refer to https://developer.mozilla.org/en-US/docs/Web/CSS/flex.\n *\n *\n * ## Layouting the viewport's slotted content\n *\n * By default, the viewport's content is added to a CSS grid container with a single column, filling remaining space vertically and horizontally.\n * Using the `::part(content)` pseudo element selector, you can configure the grid container or apply a different layout, such as a flex or flow layout.\n *\n * #### Example of adding slotted content to a CSS flex container\n * ```css\n * sci-viewport::part(content) {\n * display: flex;\n * flex-direction: column;\n * }\n * ```\n *\n * #### Example of configuring CSS grid container with two columns\n * ```css\n * sci-viewport::part(content) {\n * grid-template-columns: 1fr 1fr;\n * gap: 1em;\n * }\n * ```\n *\n * ## Styling\n *\n * To customize the default look of SCION components or support different themes, configure the `@scion/components` SCSS module in `styles.scss`.\n * To style a specific `sci-viewport` component, the following CSS variables can be set directly on the component.\n *\n * - sci-viewport-scrollbar-color: Sets the color of the scrollbar.\n *\n * ```css\n * sci-viewport {\n * --sci-viewport-scrollbar-color: blue;\n * }\n * ```\n */\n@Component({\n selector: 'sci-viewport',\n templateUrl: './viewport.component.html',\n styleUrl: './viewport.component.scss',\n encapsulation: ViewEncapsulation.ShadowDom,\n imports: [\n SciScrollableDirective,\n SciScrollbarComponent,\n CdkScrollable,\n ],\n // Required for backward compatibility for zone-based applications to support child components with eager change detection.\n changeDetection: ChangeDetectionStrategy.Eager, // eslint-disable-line @angular-eslint/prefer-on-push-component-change-detection\n host: {\n '(focus)': 'focus()',\n },\n})\nexport class SciViewportComponent {\n\n /**\n * Controls if to use the native scrollbar or a scrollbar that sits on top of the viewport. Defaults to `on-top`.\n */\n public readonly scrollbarStyle = input<ScrollbarStyle>('on-top');\n\n /**\n * Emits when the viewport is scrolled. The event is emitted outside the Angular zone to avoid unnecessary change detection cycles.\n */\n public readonly scroll = output<Event>(); // eslint-disable-line @angular-eslint/no-output-native\n\n private readonly _host = inject(ElementRef).nativeElement as HTMLElement;\n private readonly _viewport = viewChild.required<ElementRef<HTMLDivElement>>('viewport');\n private readonly _viewportClient = viewChild.required<ElementRef<HTMLDivElement>>('viewport_client');\n\n protected readonly nativeScrollbarTrackSizeProvider = inject(SciNativeScrollbarTrackSizeProvider);\n\n constructor() {\n this.installScrollEmitter();\n }\n\n public focus(): void { // do not rename to expose the same focus method like `HTMLElement.focus()`.\n this.viewportElement.focus();\n }\n\n /**\n * Returns the number of pixels that the viewport client is scrolled vertically.\n *\n * @see Element.scrollTop\n */\n public get scrollTop(): number {\n return this.viewportElement.scrollTop;\n }\n\n /**\n * Sets the number of pixels that the viewport client is scrolled vertically.\n *\n * @see Element.scrollTop\n */\n public set scrollTop(scrollTop: number) {\n this.viewportElement.scrollTop = scrollTop;\n }\n\n /**\n * Returns the number of pixels that the viewport client is scrolled horizontally.\n *\n * @see Element.scrollLeft\n */\n public get scrollLeft(): number {\n return this.viewportElement.scrollLeft;\n }\n\n /**\n * Sets the number of pixels that the viewport client is scrolled horizontally.\n *\n * @see Element.scrollLeft\n */\n public set scrollLeft(scrollLeft: number) {\n this.viewportElement.scrollLeft = scrollLeft;\n }\n\n /**\n * Returns the height of the viewport client.\n *\n * @see Element.scrollHeight\n */\n public get scrollHeight(): number {\n return this.viewportElement.scrollHeight;\n }\n\n /**\n * Returns the width of the viewport client.\n *\n * @see Element.scrollWidth\n */\n public get scrollWidth(): number {\n return this.viewportElement.scrollWidth;\n }\n\n /**\n * Returns the viewport {HTMLElement}.\n */\n public get viewportElement(): HTMLElement {\n return this._viewport().nativeElement;\n }\n\n /**\n * Returns the viewport client {HTMLElement}.\n */\n public get viewportClientElement(): HTMLElement {\n return this._viewportClient().nativeElement;\n }\n\n /**\n * Checks if the specified element is scrolled into the viewport.\n *\n * @param element - the element to be checked\n * @param fit - control if the element must fully or partially fit into the viewport\n * @return `true` if the element is scrolled into the viewport, or `false` otherwise.\n */\n public isElementInView(element: ElementRef<HTMLElement> | HTMLElement, fit: 'full' | 'partial'): boolean {\n const elTop = this.computeOffset(element, 'top');\n if (elTop === null) {\n return false;\n }\n const elLeft = this.computeOffset(element, 'left');\n if (elLeft === null) {\n return false;\n }\n\n // Consider elements as scrolled into view when there is no viewport overflow.\n // The calculation of whether an element is scrolled into view may be wrong by a few pixels if the viewport contains elements with decimal sizes.\n // This can happen because `offsetLeft` and `offsetTop` operate on an integer (not a decimal), losing precision that can accumulate.\n // To avoid incorrect calculation when there is no viewport overflow, we consider all contained elements as scrolled into the view.\n if (this.viewportElement.scrollWidth <= this.viewportElement.clientWidth && this.viewportElement.scrollHeight <= this.viewportElement.clientHeight) {\n return true;\n }\n\n const elBottom = elTop + coerceElement(element).offsetHeight;\n const elRight = elLeft + coerceElement(element).offsetWidth;\n\n const vpTop = this.viewportElement.scrollTop;\n const vpLeft = this.viewportElement.scrollLeft;\n const vpBottom = vpTop + this.viewportElement.clientHeight;\n const vpRight = vpLeft + this.viewportElement.clientWidth;\n\n if (fit === 'full') {\n return (elTop >= vpTop && elBottom <= vpBottom) && (elLeft >= vpLeft && elRight <= vpRight);\n }\n else {\n return (elBottom >= vpTop && elTop <= vpBottom) && (elRight >= vpLeft && elLeft <= vpRight);\n }\n }\n\n /**\n * Scrolls the specified element into the viewport.\n *\n * @param element - the element to scroll into the viewport\n * @param offset - the gap between the element and the viewport\n */\n public scrollIntoView(element: ElementRef<HTMLElement> | HTMLElement, offset: number = 50): void {\n const top = this.computeOffset(element, 'top');\n if (top === null) {\n return;\n }\n const left = this.computeOffset(element, 'left');\n if (left === null) {\n return;\n }\n\n this.viewportElement.scrollTop = top - offset;\n this.viewportElement.scrollLeft = left - offset;\n }\n\n /**\n * Computes the distance of the element to the viewport's left or top border.\n *\n * @return distance of the element to the viewport's left or top border, or `null` if not contained\n * in the viewport or the element or any ancestor has the `display` property set to `none`.\n */\n public computeOffset(element: ElementRef<HTMLElement> | HTMLElement, border: 'left' | 'top'): number | null {\n let offset = 0;\n let el = coerceElement(element);\n do {\n offset += (border === 'left' ? el.offsetLeft : el.offsetTop);\n const offsetParent = el.offsetParent;\n if (offsetParent === null) {\n // `offsetParent` is `null` in the following situations:\n // - The element or any ancestor has the `display` property set to `none`\n // - The element has the position property set to fixed (Firefox returns <body>).\n // - The element is <body> or <html>.\n // See https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent.\n return null;\n }\n if (!(offsetParent instanceof HTMLElement)) {\n return null;\n }\n el = offsetParent;\n } while (el !== this._host);\n\n return offset;\n }\n\n /**\n * Emits when the scroll position changes.\n */\n private installScrollEmitter(): void {\n const zone = inject(NgZone);\n effect(onCleanup => {\n const viewport = this._viewport();\n untracked(() => {\n const subscription = fromEvent(viewport.nativeElement, 'scroll')\n .pipe(subscribeIn(fn => zone.runOutsideAngular(fn)))\n .subscribe(event => this.scroll.emit(event));\n onCleanup(() => subscription.unsubscribe());\n });\n });\n }\n}\n\n/**\n * Represents a scrollbar style.\n */\nexport type ScrollbarStyle = 'native' | 'on-top' | 'hidden';\n","<!-- 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","/*\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/viewport'\n *\n * @see https://github.com/ng-packagr/ng-packagr/blob/master/docs/secondary-entrypoints.md\n */\nexport {SciViewportComponent, type ScrollbarStyle} from './viewport.component';\nexport {SciScrollbarComponent} from './scrollbar/scrollbar.component';\nexport {SciScrollableDirective} from './scrollable.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scion-components-viewport.mjs","sources":["../../../../projects/scion/components/viewport/src/scrolltrack/ɵnative-scrollbar-track-size-provider.service.ts","../../../../projects/scion/components/viewport/src/scrolltrack/native-scrollbar-track-size-provider.service.ts","../../../../projects/scion/components/viewport/src/scrollable.directive.ts","../../../../projects/scion/components/viewport/src/scrollbar/scrollbar.component.ts","../../../../projects/scion/components/viewport/src/scrollbar/scrollbar.component.html","../../../../projects/scion/components/viewport/src/viewport.component.ts","../../../../projects/scion/components/viewport/src/viewport.component.html","../../../../projects/scion/components/viewport/src/public_api.ts","../../../../projects/scion/components/viewport/src/scion-components-viewport.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 {DOCUMENT, inject, Injectable, NgZone, Signal} from '@angular/core';\nimport {fromEvent} from 'rxjs';\nimport {debounceTime, distinctUntilChanged, map, startWith} from 'rxjs/operators';\nimport {toSignal} from '@angular/core/rxjs-interop';\nimport {subscribeIn} from '@scion/toolkit/operators';\nimport {SciNativeScrollbarTrackSize, SciNativeScrollbarTrackSizeProvider} from './native-scrollbar-track-size-provider.service';\n\n/** @inheritDoc */\n@Injectable()\nexport class ɵSciNativeScrollbarTrackSizeProvider implements SciNativeScrollbarTrackSizeProvider {\n\n private readonly _document = inject(DOCUMENT);\n\n /** @inheritDoc */\n public readonly trackSize = this.computeNativeScrollbarTrackSize();\n\n private computeNativeScrollbarTrackSize(): Signal<SciNativeScrollbarTrackSize | null> {\n // We compute the size of the native scrollbar track when the browser fires the onresize window event.\n // This event is also fired on page zoom or when displaying a hidden document. Hidden documents do not have\n // a scrollbar track size until being displayed, e.g., after showing hidden iframes.\n const zone = inject(NgZone);\n const trackSize$ = fromEvent(window, 'resize')\n .pipe(\n subscribeIn(fn => zone.runOutsideAngular(fn)),\n debounceTime(5),\n startWith(null), // trigger the initial computation\n map(() => this.calculateTrackSize()),\n distinctUntilChanged((t1, t2) => t1?.hScrollbarTrackHeight === t2?.hScrollbarTrackHeight && t1?.vScrollbarTrackWidth === t2?.vScrollbarTrackWidth),\n );\n return toSignal(trackSize$, {initialValue: null});\n }\n\n /**\n * Computes the native scrollbar track size.\n *\n * @returns native track size, or `null` if the native scrollbars sit on top of the content.\n */\n private calculateTrackSize(): SciNativeScrollbarTrackSize | null {\n // Create temporary viewport and viewport client with native scrollbars to compute the scrolltrack width.\n const viewportDiv = this._document.createElement('div');\n setStyle(viewportDiv, {\n position: 'absolute',\n overflow: 'scroll',\n height: '100px',\n width: '100px',\n border: '0',\n visibility: 'hidden',\n });\n\n const viewportClientDiv = this._document.createElement('div');\n setStyle(viewportClientDiv, {\n height: '100%',\n width: '100%',\n border: '0',\n });\n\n viewportDiv.appendChild(viewportClientDiv);\n this._document.body.appendChild(viewportDiv);\n\n // Do not use client and offset width/height to calculate the size of the scrollbar, as they are rounded, resulting in unwanted spacing when zooming the page.\n const viewportBounds = viewportDiv.getBoundingClientRect();\n const viewportClientBounds = viewportClientDiv.getBoundingClientRect();\n const trackSize: SciNativeScrollbarTrackSize = {\n hScrollbarTrackHeight: viewportBounds.height - viewportClientBounds.height,\n vScrollbarTrackWidth: viewportBounds.width - viewportClientBounds.width,\n };\n\n // Destroy temporary viewport.\n this._document.body.removeChild(viewportDiv);\n if (trackSize.hScrollbarTrackHeight === 0 && trackSize.vScrollbarTrackWidth === 0) {\n return null;\n }\n\n return trackSize;\n }\n}\n\n/**\n * Applies the given style(s) to the given element.\n *\n * Specify styles to be modified by passing a dictionary containing CSS property names (hyphen case).\n * To remove a style, set its value to `null`.\n *\n * @ignore\n */\nfunction setStyle(element: HTMLElement, styles: {[style: string]: string}): void {\n Object.entries(styles).forEach(([name, value]) => element.style.setProperty(name, value));\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 {Injectable, Signal} from '@angular/core';\nimport {ɵSciNativeScrollbarTrackSizeProvider} from './ɵnative-scrollbar-track-size-provider.service';\n\n/**\n * Provides the native scrollbar tracksize.\n */\n@Injectable({providedIn: 'root', useClass: ɵSciNativeScrollbarTrackSizeProvider})\nexport abstract class SciNativeScrollbarTrackSizeProvider {\n\n /**\n * Provides the track size of the native scrollbar, or `null` if the native scrollbars sit on top of the content.\n */\n public abstract readonly trackSize: Signal<SciNativeScrollbarTrackSize | null>;\n}\n\n/**\n * Represents the native scrollbar track size.\n */\nexport interface SciNativeScrollbarTrackSize {\n hScrollbarTrackHeight: number;\n vScrollbarTrackWidth: number;\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\nimport {computed, Directive, effect, ElementRef, inject, input, Renderer2, untracked} from '@angular/core';\nimport {SciNativeScrollbarTrackSize, SciNativeScrollbarTrackSizeProvider} from './scrolltrack/native-scrollbar-track-size-provider.service';\nimport {Dictionary} from '@scion/toolkit/util';\n\n/**\n * Makes the host element natively scrollable and hides native scrollbars by default, unless native scrollbars\n * already sit on top of the viewport (e.g. in OS X).\n *\n * Because there is no cross-browser API to hide scrollbars without losing native scroll support, we set 'overflow'\n * to 'scroll' but shift the native scrollbars out of the visible viewport area. The shift offset is computed upfront.\n *\n * This directive expects its host element to be the only child in document flow in its parent DOM element. It makes the host element\n * fill up the entire space (width and height set to 100%). The parent element must have its CSS `overflow` property set to `hidden`\n * to hide the pushed out native scrollbars.\n *\n * This directive provides the `isNativeScrollbarCropped` signal, which indicates whether native scrollbars are pushed out of the viewport element.\n * In templates, access it via the exported template reference variable `sciScrollable`.\n *\n * ```html\n * <div sciScrollable #sciScrollable=\"sciScrollable\" #viewport>\n * content\n * </div>\n *\n * <!-- Render scrollbars only if native scrollbars are pushed out of the viewport element. -->\n * @if (sciScrollable.isNativeScrollbarCropped()) {\n * <sci-scrollbar [viewport]=\"viewport\" direction=\"vscroll\"/>\n * <sci-scrollbar [viewport]=\"viewport\" direction=\"hscroll\"/>\n * }\n * ```\n */\n@Directive({\n selector: '[sciScrollable]',\n exportAs: 'sciScrollable',\n})\nexport class SciScrollableDirective {\n\n /**\n * Controls whether to display native scrollbars.\n *\n * Has no effect if the native scrollbar sits on top of the content, e.g. in OS X.\n */\n public readonly displayNativeScrollbar = input(false, {alias: 'sciScrollableDisplayNativeScrollbar'});\n\n private readonly _host = inject(ElementRef<HTMLDivElement>).nativeElement as HTMLElement;\n private readonly _renderer = inject(Renderer2);\n private readonly _nativeScrollbarTrackSizeProvider = inject(SciNativeScrollbarTrackSizeProvider);\n\n /**\n * Indicates whether native scrollbars are pushed out of the viewport element.\n */\n public readonly isNativeScrollbarCropped = computed(() => !this.displayNativeScrollbar() && this._nativeScrollbarTrackSizeProvider.trackSize() !== null);\n\n constructor() {\n this.controlDisplayOfNativeScrollbar();\n }\n\n /**\n * Controls the display of the native scrollbar based on this directive's configuration.\n */\n private controlDisplayOfNativeScrollbar(): void {\n effect(() => {\n if (this.isNativeScrollbarCropped()) {\n const trackSize = this._nativeScrollbarTrackSizeProvider.trackSize()!;\n untracked(() => this.shiftNativeScrollbars(trackSize));\n }\n else {\n untracked(() => this.useNativeScrollbars());\n }\n });\n }\n\n /**\n * Uses the native scrollbars when content overflows.\n */\n private useNativeScrollbars(): void {\n this.setStyle(this._host, {\n overflow: 'auto',\n width: '100%',\n height: '100%',\n marginRight: 0,\n marginBottom: 0,\n });\n }\n\n /**\n * Shifts the native scrollbars out of the visible viewport area.\n */\n private shiftNativeScrollbars(trackSize: SciNativeScrollbarTrackSize): void {\n this.setStyle(this._host, {\n overflow: 'scroll',\n width: `calc(100% + ${trackSize.vScrollbarTrackWidth}px`,\n height: `calc(100% + ${trackSize.hScrollbarTrackHeight}px`,\n marginRight: `-${trackSize.vScrollbarTrackWidth}px`,\n marginBottom: `-${trackSize.hScrollbarTrackHeight}px`,\n });\n }\n\n private setStyle(element: Element, style: Dictionary): void {\n Object.keys(style).forEach(key => this._renderer.setStyle(element, key, style[key]));\n }\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\nimport {Component, computed, DestroyRef, DOCUMENT, effect, ElementRef, inject, input, NgZone, signal, untracked, viewChild} from '@angular/core';\nimport {concatWith, exhaustMap, finalize, fromEvent, merge, mergeWith, Observable, of, race, tap, timer} from 'rxjs';\nimport {debounceTime, map, startWith, switchMap, takeUntil, withLatestFrom} from 'rxjs/operators';\nimport {fromMutation$, fromResize$} from '@scion/toolkit/observable';\nimport {subscribeIn} from '@scion/toolkit/operators';\nimport {takeUntilDestroyed} from '@angular/core/rxjs-interop';\n\n/**\n * Renders a vertical or horizontal scrollbar.\n *\n * The scrollbar features the following functionality:\n * - allows to move the thumb by mouse\n * - enlarges the thumb if the mouse pointer is near the thumb\n * - allows paging on mousedown on the scroll track\n *\n * ### Styling:\n *\n * To customize the default look of SCION components or support different themes, configure the `@scion/components` SCSS module in `styles.scss`.\n * To style a specific `sci-scrollbar` component, the following CSS variables can be set directly on the component.\n *\n * - --sci-scrollbar-color: Sets the color of the scrollbar.\n *\n * Example:\n *\n * ```css\n *\n * sci-scrollbar {\n * --sci-scrollbar-color: blue;\n * }\n * ```\n */\n@Component({\n selector: 'sci-scrollbar',\n templateUrl: './scrollbar.component.html',\n styleUrl: './scrollbar.component.scss',\n host: {\n '[class.vertical]': 'vertical()',\n '[class.horizontal]': 'horizontal()',\n '[class.scrolling]': 'scrolling()',\n '[class.overflow]': 'overflow()',\n '[style.--ɵsci-scrollbar-thumb-position-fr]': 'thumbPositionFr()',\n '[style.--ɵsci-scrollbar-thumb-size-fr]': 'thumbSizeFr()',\n },\n})\nexport class SciScrollbarComponent {\n\n /**\n * Timeout for debouncing viewport resize events that trigger the scroll position computation.\n *\n * Debouncing is particularly important in the context of Angular animations, since they continuously\n * trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user\n * expands a panel that contains a viewport.\n *\n * @internal\n */\n public static readonly VIEWPORT_RESIZE_DEBOUNCE_TIME = 50;\n\n /**\n * Specifies the direction of the scrollbar. Defaults to a vertical scrollbar.\n */\n public readonly direction = input<'vscroll' | 'hscroll'>('vscroll');\n\n /**\n * Specifies the viewport associated with the scrollbar.\n */\n public readonly viewport = input.required<HTMLElement>();\n\n private readonly _host = inject(ElementRef).nativeElement as HTMLElement;\n private readonly _document = inject(DOCUMENT);\n private readonly _zone = inject(NgZone);\n private readonly _destroyRef = inject(DestroyRef);\n private readonly _thumbElement = viewChild.required<ElementRef<HTMLDivElement>>('thumb_handle');\n\n protected readonly vertical = computed(() => this.direction() === 'vscroll');\n protected readonly horizontal = computed(() => !this.vertical());\n protected readonly scrolling = signal(false);\n protected readonly overflow = signal(false);\n protected readonly thumbSizeFr = signal(0);\n protected readonly thumbPositionFr = signal(0);\n\n constructor() {\n this.installScrollPositionRenderer();\n }\n\n /**\n * Computes the scroll position and updates CSS variables to render the scroll position.\n */\n private renderScrollPosition(): void {\n NgZone.assertNotInAngularZone();\n const viewportSize = this.viewportSize();\n const viewportClientSize = this.viewportClientSize();\n\n this.thumbPositionFr.set(this.viewportScrollPosition() / viewportClientSize);\n this.thumbSizeFr.set(viewportSize / viewportClientSize);\n this.overflow.set(viewportClientSize > viewportSize);\n }\n\n /**\n * Method invoked when clicking on the scrollbar thumb.\n */\n protected onThumbMouseDown(mousedownEvent: MouseEvent): void {\n if (mousedownEvent.button !== 0) {\n return;\n }\n\n this.scrolling.set(true);\n\n // Prevent text selection during drag.\n mousedownEvent.preventDefault();\n\n // Calculate screen offset to convert screen coordinates into client coordinates, required for `sci-mousemove` events which originate from other documents (iframes).\n const {screenOffsetX, screenOffsetY} = calculateScreenOffset(mousedownEvent);\n\n // Memoize offset where thumb was clicked.\n const thumbStartOffset = this.vertical() ? mousedownEvent.offsetY : mousedownEvent.offsetX;\n\n // 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.\n const mouseUp$ = race(fromEvent<MouseEvent>(this._document, 'mouseup', {capture: true, once: true}), fromEvent<MouseEvent>(this._document, 'sci-mouseup', {once: true}))\n .pipe(tap(mouseupEvent => mouseupEvent.stopPropagation()));\n\n // Track pointer until mouse release.\n merge(fromEvent<MouseEvent>(this._document, 'mousemove'), fromEvent<MouseEvent>(this._document, 'sci-mousemove'))\n .pipe(\n subscribeIn(fn => this._zone.runOutsideAngular(fn)),\n takeUntilDestroyed(this._destroyRef),\n takeUntil(mouseUp$),\n finalize(() => this.scrolling.set(false)),\n )\n .subscribe(mousemoveEvent => {\n NgZone.assertNotInAngularZone();\n\n // Prevent user agent scrolling while during drag.\n mousemoveEvent.preventDefault();\n\n // Calculate new thumb position.\n const pointerPosition = this.vertical() ? mousemoveEvent.screenY - screenOffsetY : mousemoveEvent.screenX - screenOffsetX;\n this.scrollViewport(pointerPosition - thumbStartOffset);\n });\n }\n\n /**\n * Method invoked when clicking on the scrollbar track.\n *\n * Scrolls in discrete steps to the pointer, then switches to regular scrolling until releasing the mouse.\n */\n protected onScrollTrackMouseDown(event: MouseEvent): void {\n this.scrolling.set(true);\n\n // Prevent text selection during drag.\n event.preventDefault();\n\n const mouseMove$ = merge(fromEvent<MouseEvent>(this._document, 'mousemove'), fromEvent<MouseEvent>(this._document, 'sci-mousemove'));\n\n // Handle the event in the capture phase and stop propagation to not close a potential overlay when releasing the mouse outside the overlay.\n const mouseUp$ = race(fromEvent<MouseEvent>(this._document, 'mouseup', {capture: true, once: true}), fromEvent<MouseEvent>(this._document, 'sci-mouseup', {once: true}))\n .pipe(tap(mouseupEvent => mouseupEvent.stopPropagation()));\n\n // Calculate screen offset to convert screen coordinates into client coordinates, required for `sci-mousemove` events which originate from other documents (iframes).\n const {screenOffsetX, screenOffsetY} = calculateScreenOffset(event);\n\n // Scroll in discrete steps to the pointer position, then switch to regular scrolling.\n timer(250, 50)\n .pipe(\n // Track current pointer position.\n withLatestFrom(mouseMove$.pipe(startWith(event)), (_tick, event) => event),\n // Scroll immediately on initial click.\n startWith(event),\n subscribeIn(fn => this._zone.runOutsideAngular(fn)),\n exhaustMap(event => {\n const pointerPosition = this.vertical() ? event.screenY - screenOffsetY : event.screenX - screenOffsetX;\n const [thumbStartPosition, thumbEndPosition] = this.thumbPosition();\n const thumbSize = thumbEndPosition - thumbStartPosition;\n\n // Step scroll until the pointer hits the thumb.\n if (!isBetween(pointerPosition, {from: thumbStartPosition - thumbSize, to: thumbEndPosition + thumbSize})) {\n const scrollingDown = pointerPosition > thumbEndPosition;\n return of(scrollingDown ? thumbStartPosition + thumbSize : thumbStartPosition - thumbSize);\n }\n\n // Switch to \"smooth scrolling\" following the pointer.\n return of(event)\n .pipe(\n concatWith(mouseMove$),\n map(event => (this.vertical() ? event.screenY - screenOffsetY : event.screenX - screenOffsetX) - (thumbSize / 2)),\n );\n }),\n // Stop on mouse release.\n takeUntil(mouseUp$),\n finalize(() => this.scrolling.set(false)),\n )\n .subscribe((thumbPosition: number) => {\n NgZone.assertNotInAngularZone();\n this.scrollViewport(thumbPosition);\n });\n }\n\n /**\n * Renders the current scroll position when the viewport is scrolled.\n */\n private installScrollPositionRenderer(): void {\n effect(onCleanup => {\n const viewport = this.viewport();\n\n untracked(() => {\n const subscription = viewportScroll$(viewport)\n .pipe(\n mergeWith(viewportSize$(viewport, {debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME})),\n mergeWith(viewportClientSize$(viewport, {debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME})),\n subscribeIn(fn => this._zone.runOutsideAngular(fn)),\n )\n .subscribe(() => this.renderScrollPosition());\n onCleanup(() => subscription.unsubscribe());\n });\n });\n }\n\n /**\n * Moves the scrollbar thumb to the specified position, scrolling the viewport accordingly.\n *\n * The thumb position must be given in client coordinates (relative to the top-left corner of the page viewport).\n */\n private scrollViewport(thumbPosition: number): void {\n const [scrollbarComponentStartPosition] = this.scrollbarComponentPosition();\n const scrollbarBorderWidth = this.vertical() ? this._host.clientTop : this._host.clientLeft;\n const scrollRatio = clamp((thumbPosition - scrollbarComponentStartPosition - scrollbarBorderWidth) / (this.trackSize() - this.thumbSize()), {min: 0, max: 1});\n const viewportScrollPosition = scrollRatio * (this.viewportClientSize() - this.viewportSize());\n\n if (this.vertical()) {\n this.viewport().scrollTop = viewportScrollPosition;\n }\n else {\n this.viewport().scrollLeft = viewportScrollPosition;\n }\n }\n\n /**\n * Returns the position of this component in client coordinates.\n *\n * Returned coordinates are relative to the top-left corner of the page viewport.\n * Depending on the scrollbar orientation, returned coordinates are `[top, bottom]` or `[left, right]`.\n */\n private scrollbarComponentPosition(): [number, number] {\n const boundingBox = this._host.getBoundingClientRect();\n return this.vertical() ? [boundingBox.top, boundingBox.bottom] : [boundingBox.left, boundingBox.right];\n }\n\n /**\n * Returns the size of the viewport in pixels.\n *\n * The viewport is the container for scrollable content (viewport client), displaying scrollbars if it overflows.\n * Depending on the scrollbar orientation, the returned size is `viewport.clientHeight` or `viewport.clientWidth`.\n */\n private viewportSize(): number {\n return this.vertical() ? this.viewport().clientHeight : this.viewport().clientWidth;\n }\n\n /**\n * Returns the size of the viewport client in pixels.\n *\n * The viewport client represents scrollable content displayed in the viewport.\n * Depending on the scrollbar orientation, the returned size is `viewport.scrollHeight` or `viewport.scrollWidth`.\n */\n private viewportClientSize(): number {\n return this.vertical() ? this.viewport().scrollHeight : this.viewport().scrollWidth;\n }\n\n /**\n * Returns the viewport's scroll position in pixels.\n *\n * Depending on the scrollbar orientation, the returned position is `viewport.scrollTop` or `viewport.scrollLeft`.\n */\n private viewportScrollPosition(): number {\n return this.vertical() ? this.viewport().scrollTop : this.viewport().scrollLeft;\n }\n\n /**\n * Returns the size of the scrollbar thumb in pixels.\n *\n * The thumb is the handle used to scroll the scrollbar.\n */\n private thumbSize(): number {\n const thumbElement = this._thumbElement().nativeElement;\n return this.vertical() ? thumbElement.offsetHeight : thumbElement.offsetWidth;\n }\n\n /**\n * Returns the current thumb position in client coordinates.\n *\n * Returned coordinates are relative to the top-left corner of the page viewport.\n * Depending on the scrollbar orientation, returned coordinates are `[top, bottom]` or `[left, right]`.\n */\n private thumbPosition(): [number, number] {\n const boundingBox = this._thumbElement().nativeElement.getBoundingClientRect();\n return this.vertical() ? [boundingBox.top, boundingBox.bottom] : [boundingBox.left, boundingBox.right];\n }\n\n /**\n * Returns the size of the scrollbar track in pixels.\n *\n * The scrollbar track is the track along which the scrollbar thumb moves.\n */\n private trackSize(): number {\n return this.vertical() ? this._host.clientHeight : this._host.clientWidth;\n }\n}\n\n/**\n * Emits whenever the viewport is scrolled.\n */\nfunction viewportScroll$(viewport: HTMLElement): Observable<void> {\n return fromEvent(viewport, 'scroll', {passive: true}).pipe(map(() => undefined));\n}\n\n/**\n * Emits on subscription, and then each time the size of the viewport changes.\n */\nfunction viewportSize$(viewport: HTMLElement, options: {debounceTime: number}): Observable<void> {\n return fromResize$(viewport)\n .pipe(\n // Debouncing is particularly important in the context of Angular animations, since they continuously\n // trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user\n // expands a panel that contains a viewport.\n debounceTime(options.debounceTime),\n map(() => undefined),\n );\n}\n\n/**\n * Emits on subscription, and then each time the size or style property of the viewport client changes.\n */\nfunction viewportClientSize$(viewport: HTMLElement, options: {debounceTime: number}): Observable<void> {\n return children$(viewport)\n .pipe(\n switchMap(children => merge(...children.map(child => merge(\n fromResize$(child),\n // Observe style mutations since some transformations change the scroll position without necessarily triggering a dimension change,\n // e.g., `scale` or `translate` used by some virtual scroll implementations\n fromMutation$(child, {subtree: false, childList: false, attributeFilter: ['style']})),\n ))),\n // Debouncing is particularly important in the context of Angular animations, since they continuously\n // trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user\n // expands a panel that contains a viewport.\n debounceTime(options.debounceTime),\n map(() => undefined),\n );\n}\n\n/**\n * Emits the children of the passed element, and then each time child elements are added or removed.\n */\nfunction children$(element: HTMLElement): Observable<HTMLElement[]> {\n return fromMutation$(element, {subtree: false, childList: true})\n .pipe(\n startWith(undefined as void),\n map(() => Array.from(element.children)\n // Map to slotted content if a slot (Shadow DOM).\n .flatMap(child => child instanceof HTMLSlotElement ? child.assignedElements() : child)\n // Filter HTML elements.\n .filter((child: Element): child is HTMLElement => child instanceof HTMLElement)),\n );\n}\n\n/**\n * Returns the value clamped to the inclusive range of min and max.\n */\nfunction clamp(value: number, minmax: {min: number; max: number}): number {\n return Math.max(minmax.min, Math.min(value, minmax.max));\n}\n\n/**\n * Returns whether the value is between the specified range (inclusive).\n */\nfunction isBetween(value: number, range: {from: number; to: number}): boolean {\n return value >= range.from && value <= range.to;\n}\n\n/**\n * Calculates the distance between the top-left corner of the screen (monitor) and the top-left corner of the page viewport of this document.\n *\n * Use to convert screen coordinates from `sci-mousemove` and `sci-mouseup` events into client coordinates relative to the page viewport of the current document.\n *\n * 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\n * relative to the source document, not the current one.\n */\nfunction calculateScreenOffset(mousedownEvent: MouseEvent): {screenOffsetX: number; screenOffsetY: number} {\n return {\n screenOffsetX: mousedownEvent.screenX - mousedownEvent.clientX,\n screenOffsetY: mousedownEvent.screenY - mousedownEvent.clientY,\n };\n}\n","<!-- 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","/*\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\nimport {ChangeDetectionStrategy, Component, effect, ElementRef, inject, input, NgZone, output, untracked, viewChild, ViewEncapsulation} from '@angular/core';\nimport {coerceElement} from '@angular/cdk/coercion';\nimport {SciScrollableDirective} from './scrollable.directive';\nimport {SciScrollbarComponent} from './scrollbar/scrollbar.component';\nimport {fromEvent} from 'rxjs';\nimport {subscribeIn} from '@scion/toolkit/operators';\nimport {CdkScrollable} from '@angular/cdk/scrolling';\n\n/**\n * Represents a viewport with slotted content (`<ng-content>`) used as scrollable content. By default, content is added to a CSS grid layout.\n *\n * The viewport component displays scrollbars when its content overflows. Scrollbars are displayed on top of the content, not next to it.\n * The component uses the native scrollbars of the operating system if they are already sitting on top, or falls back and renders scrollbars on top otherwise.\n * The viewport remains natively scrollable with the native scrollbars shifted out of the viewport's visible area. Consequently, the viewport keeps supporting\n * native scrolling features such as touch gestures, scroll speed acceleration, or scrolling near the viewport edges during drag-and-drop operations.\n *\n * ```html\n * <sci-viewport>\n * your content\n * </sci-viewport>\n * ```\n *\n * ## Adding the viewport to a layout\n *\n * Typically, you would add the viewport component to a flexible layout, filling the remaining space vertically and horizontally, such as a flexbox container\n * with the viewport's `flex` CSS property set to either `flex: auto` or `flex: 1 1 0`.\n *\n * The viewport is sized according to its content width and height. It grows to absorb any free space, thus overflowing its content only when encountering\n * a layout constraint. Depending on the layout, different steps may be necessary to prevent the viewport from growing to infinity.\n *\n * - If practical, give the viewport a fixed size or a maximum size.\n * - If you add the viewport to a flexbox layout, make sure that it cannot exceed the available space. Instead, the viewport should fill the remaining space,\n * vertically and horizontally. Be aware that, by default, a flex item does not shrink below its minimum content size. To change this, set the viewport's\n * `flex-basis` to `0` (instead of `auto`), or use the CSS shorthand property `flex: 1 1 0`. The `flex-basis` defines the default size of a flex item before\n * the remaining extra space is distributed. If the viewport does not appear after setting this property, check its parent elements' content sizes.\n * As an alternative to setting `flex: 1 1 0`, change the setting to `flex: auto` and hide the overflow in the parent element, as follows: `overflow: hidden`.\n * Another approach would be to set the minimum height of all parents to `0`, as follows: `min-height: 0`.\n *\n * For the complete documentation on the flex layout and its features, refer to https://developer.mozilla.org/en-US/docs/Web/CSS/flex.\n *\n *\n * ## Layouting the viewport's slotted content\n *\n * By default, the viewport's content is added to a CSS grid container with a single column, filling remaining space vertically and horizontally.\n * Using the `::part(content)` pseudo element selector, you can configure the grid container or apply a different layout, such as a flex or flow layout.\n *\n * #### Example of adding slotted content to a CSS flex container\n * ```css\n * sci-viewport::part(content) {\n * display: flex;\n * flex-direction: column;\n * }\n * ```\n *\n * #### Example of configuring CSS grid container with two columns\n * ```css\n * sci-viewport::part(content) {\n * grid-template-columns: 1fr 1fr;\n * gap: 1em;\n * }\n * ```\n *\n * ## Styling\n *\n * To customize the default look of SCION components or support different themes, configure the `@scion/components` SCSS module in `styles.scss`.\n * To style a specific `sci-viewport` component, the following CSS variables can be set directly on the component.\n *\n * - sci-viewport-scrollbar-color: Sets the color of the scrollbar.\n *\n * ```css\n * sci-viewport {\n * --sci-viewport-scrollbar-color: blue;\n * }\n * ```\n */\n@Component({\n selector: 'sci-viewport',\n templateUrl: './viewport.component.html',\n styleUrl: './viewport.component.scss',\n encapsulation: ViewEncapsulation.ShadowDom,\n imports: [\n SciScrollableDirective,\n SciScrollbarComponent,\n CdkScrollable,\n ],\n // Required for backward compatibility for zone-based applications to support child components with eager change detection.\n changeDetection: ChangeDetectionStrategy.Eager, // eslint-disable-line @angular-eslint/prefer-on-push-component-change-detection\n host: {\n '(focus)': 'focus()',\n },\n})\nexport class SciViewportComponent {\n\n /**\n * Controls if to use the native scrollbar or a scrollbar that sits on top of the viewport. Defaults to `on-top`.\n */\n public readonly scrollbarStyle = input<ScrollbarStyle>('on-top');\n\n /**\n * Emits when the viewport is scrolled. The event is emitted outside the Angular zone to avoid unnecessary change detection cycles.\n */\n public readonly scroll = output<Event>(); // eslint-disable-line @angular-eslint/no-output-native\n\n private readonly _host = inject(ElementRef).nativeElement as HTMLElement;\n private readonly _viewport = viewChild.required<ElementRef<HTMLDivElement>>('viewport');\n private readonly _viewportClient = viewChild.required<ElementRef<HTMLDivElement>>('viewport_client');\n\n constructor() {\n this.installScrollEmitter();\n }\n\n public focus(): void { // do not rename to expose the same focus method like `HTMLElement.focus()`.\n this.viewportElement.focus();\n }\n\n /**\n * Returns the number of pixels that the viewport client is scrolled vertically.\n *\n * @see Element.scrollTop\n */\n public get scrollTop(): number {\n return this.viewportElement.scrollTop;\n }\n\n /**\n * Sets the number of pixels that the viewport client is scrolled vertically.\n *\n * @see Element.scrollTop\n */\n public set scrollTop(scrollTop: number) {\n this.viewportElement.scrollTop = scrollTop;\n }\n\n /**\n * Returns the number of pixels that the viewport client is scrolled horizontally.\n *\n * @see Element.scrollLeft\n */\n public get scrollLeft(): number {\n return this.viewportElement.scrollLeft;\n }\n\n /**\n * Sets the number of pixels that the viewport client is scrolled horizontally.\n *\n * @see Element.scrollLeft\n */\n public set scrollLeft(scrollLeft: number) {\n this.viewportElement.scrollLeft = scrollLeft;\n }\n\n /**\n * Returns the height of the viewport client.\n *\n * @see Element.scrollHeight\n */\n public get scrollHeight(): number {\n return this.viewportElement.scrollHeight;\n }\n\n /**\n * Returns the width of the viewport client.\n *\n * @see Element.scrollWidth\n */\n public get scrollWidth(): number {\n return this.viewportElement.scrollWidth;\n }\n\n /**\n * Returns the viewport {HTMLElement}.\n */\n public get viewportElement(): HTMLElement {\n return this._viewport().nativeElement;\n }\n\n /**\n * Returns the viewport client {HTMLElement}.\n */\n public get viewportClientElement(): HTMLElement {\n return this._viewportClient().nativeElement;\n }\n\n /**\n * Checks if the specified element is scrolled into the viewport.\n *\n * @param element - the element to be checked\n * @param fit - control if the element must fully or partially fit into the viewport\n * @return `true` if the element is scrolled into the viewport, or `false` otherwise.\n */\n public isElementInView(element: ElementRef<HTMLElement> | HTMLElement, fit: 'full' | 'partial'): boolean {\n const elTop = this.computeOffset(element, 'top');\n if (elTop === null) {\n return false;\n }\n const elLeft = this.computeOffset(element, 'left');\n if (elLeft === null) {\n return false;\n }\n\n // Consider elements as scrolled into view when there is no viewport overflow.\n // The calculation of whether an element is scrolled into view may be wrong by a few pixels if the viewport contains elements with decimal sizes.\n // This can happen because `offsetLeft` and `offsetTop` operate on an integer (not a decimal), losing precision that can accumulate.\n // To avoid incorrect calculation when there is no viewport overflow, we consider all contained elements as scrolled into the view.\n if (this.viewportElement.scrollWidth <= this.viewportElement.clientWidth && this.viewportElement.scrollHeight <= this.viewportElement.clientHeight) {\n return true;\n }\n\n const elBottom = elTop + coerceElement(element).offsetHeight;\n const elRight = elLeft + coerceElement(element).offsetWidth;\n\n const vpTop = this.viewportElement.scrollTop;\n const vpLeft = this.viewportElement.scrollLeft;\n const vpBottom = vpTop + this.viewportElement.clientHeight;\n const vpRight = vpLeft + this.viewportElement.clientWidth;\n\n if (fit === 'full') {\n return (elTop >= vpTop && elBottom <= vpBottom) && (elLeft >= vpLeft && elRight <= vpRight);\n }\n else {\n return (elBottom >= vpTop && elTop <= vpBottom) && (elRight >= vpLeft && elLeft <= vpRight);\n }\n }\n\n /**\n * Scrolls the specified element into the viewport.\n *\n * @param element - the element to scroll into the viewport\n * @param offset - the gap between the element and the viewport\n */\n public scrollIntoView(element: ElementRef<HTMLElement> | HTMLElement, offset: number = 50): void {\n const top = this.computeOffset(element, 'top');\n if (top === null) {\n return;\n }\n const left = this.computeOffset(element, 'left');\n if (left === null) {\n return;\n }\n\n this.viewportElement.scrollTop = top - offset;\n this.viewportElement.scrollLeft = left - offset;\n }\n\n /**\n * Computes the distance of the element to the viewport's left or top border.\n *\n * @return distance of the element to the viewport's left or top border, or `null` if not contained\n * in the viewport or the element or any ancestor has the `display` property set to `none`.\n */\n public computeOffset(element: ElementRef<HTMLElement> | HTMLElement, border: 'left' | 'top'): number | null {\n let offset = 0;\n let el = coerceElement(element);\n do {\n offset += (border === 'left' ? el.offsetLeft : el.offsetTop);\n const offsetParent = el.offsetParent;\n if (offsetParent === null) {\n // `offsetParent` is `null` in the following situations:\n // - The element or any ancestor has the `display` property set to `none`\n // - The element has the position property set to fixed (Firefox returns <body>).\n // - The element is <body> or <html>.\n // See https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent.\n return null;\n }\n if (!(offsetParent instanceof HTMLElement)) {\n return null;\n }\n el = offsetParent;\n } while (el !== this._host);\n\n return offset;\n }\n\n /**\n * Emits when the scroll position changes.\n */\n private installScrollEmitter(): void {\n const zone = inject(NgZone);\n effect(onCleanup => {\n const viewport = this._viewport();\n untracked(() => {\n const subscription = fromEvent(viewport.nativeElement, 'scroll')\n .pipe(subscribeIn(fn => zone.runOutsideAngular(fn)))\n .subscribe(event => this.scroll.emit(event));\n onCleanup(() => subscription.unsubscribe());\n });\n });\n }\n}\n\n/**\n * Represents a scrollbar style.\n */\nexport type ScrollbarStyle = 'native' | 'on-top' | 'hidden';\n","<!-- 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","/*\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/viewport'\n *\n * @see https://github.com/ng-packagr/ng-packagr/blob/master/docs/secondary-entrypoints.md\n */\nexport {SciViewportComponent, type ScrollbarStyle} from './viewport.component';\nexport {SciScrollbarComponent} from './scrollbar/scrollbar.component';\nexport {SciScrollableDirective} from './scrollable.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scion/components",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.2.0",
|
|
4
4
|
"description": "Provides a collection of Angular components and directives primarily for use in SCION libraries such as `@scion/workbench` and `@scion/microfrontend-platform`. This library is not a comprehensive component library as its focus is on SCION requirements.",
|
|
5
5
|
"license": "EPL-2.0",
|
|
6
6
|
"private": false,
|
|
@@ -1,34 +1,5 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Provides the native scrollbar tracksize.
|
|
6
|
-
*/
|
|
7
|
-
declare class SciNativeScrollbarTrackSizeProvider {
|
|
8
|
-
private readonly _document;
|
|
9
|
-
private readonly _zone;
|
|
10
|
-
/**
|
|
11
|
-
* Provides the track size of the native scrollbar, or `null` if the native scrollbars sit on top of the content.
|
|
12
|
-
*/
|
|
13
|
-
trackSize: Signal<NativeScrollbarTrackSize | null>;
|
|
14
|
-
constructor();
|
|
15
|
-
/**
|
|
16
|
-
* Computes the native scrollbar track size.
|
|
17
|
-
*
|
|
18
|
-
* @returns native track size, or `null` if the native scrollbars sit on top of the content.
|
|
19
|
-
*/
|
|
20
|
-
private computeTrackSize;
|
|
21
|
-
private createNativeScrollbarTrackSizeSignal;
|
|
22
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SciNativeScrollbarTrackSizeProvider, never>;
|
|
23
|
-
static ɵprov: _angular_core.ɵɵInjectableDeclaration<SciNativeScrollbarTrackSizeProvider>;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Represents the native scrollbar track size.
|
|
27
|
-
*/
|
|
28
|
-
interface NativeScrollbarTrackSize {
|
|
29
|
-
hScrollbarTrackHeight: number;
|
|
30
|
-
vScrollbarTrackWidth: number;
|
|
31
|
-
}
|
|
2
|
+
import { ElementRef } from '@angular/core';
|
|
32
3
|
|
|
33
4
|
/**
|
|
34
5
|
* Represents a viewport with slotted content (`<ng-content>`) used as scrollable content. By default, content is added to a CSS grid layout.
|
|
@@ -109,7 +80,6 @@ declare class SciViewportComponent {
|
|
|
109
80
|
private readonly _host;
|
|
110
81
|
private readonly _viewport;
|
|
111
82
|
private readonly _viewportClient;
|
|
112
|
-
protected readonly nativeScrollbarTrackSizeProvider: SciNativeScrollbarTrackSizeProvider;
|
|
113
83
|
constructor();
|
|
114
84
|
focus(): void;
|
|
115
85
|
/**
|
|
@@ -194,7 +164,7 @@ type ScrollbarStyle = 'native' | 'on-top' | 'hidden';
|
|
|
194
164
|
* Renders a vertical or horizontal scrollbar.
|
|
195
165
|
*
|
|
196
166
|
* The scrollbar features the following functionality:
|
|
197
|
-
* - allows to move the thumb by mouse
|
|
167
|
+
* - allows to move the thumb by mouse
|
|
198
168
|
* - enlarges the thumb if the mouse pointer is near the thumb
|
|
199
169
|
* - allows paging on mousedown on the scroll track
|
|
200
170
|
*
|
|
@@ -203,7 +173,7 @@ type ScrollbarStyle = 'native' | 'on-top' | 'hidden';
|
|
|
203
173
|
* To customize the default look of SCION components or support different themes, configure the `@scion/components` SCSS module in `styles.scss`.
|
|
204
174
|
* To style a specific `sci-scrollbar` component, the following CSS variables can be set directly on the component.
|
|
205
175
|
*
|
|
206
|
-
* - sci-scrollbar-color: Sets the color of the scrollbar.
|
|
176
|
+
* - --sci-scrollbar-color: Sets the color of the scrollbar.
|
|
207
177
|
*
|
|
208
178
|
* Example:
|
|
209
179
|
*
|
|
@@ -220,7 +190,7 @@ declare class SciScrollbarComponent {
|
|
|
220
190
|
*/
|
|
221
191
|
readonly direction: _angular_core.InputSignal<"vscroll" | "hscroll">;
|
|
222
192
|
/**
|
|
223
|
-
*
|
|
193
|
+
* Specifies the viewport associated with the scrollbar.
|
|
224
194
|
*/
|
|
225
195
|
readonly viewport: _angular_core.InputSignal<HTMLElement>;
|
|
226
196
|
private readonly _host;
|
|
@@ -228,49 +198,83 @@ declare class SciScrollbarComponent {
|
|
|
228
198
|
private readonly _zone;
|
|
229
199
|
private readonly _destroyRef;
|
|
230
200
|
private readonly _thumbElement;
|
|
231
|
-
private readonly _lastDragPosition;
|
|
232
201
|
protected readonly vertical: _angular_core.Signal<boolean>;
|
|
233
202
|
protected readonly horizontal: _angular_core.Signal<boolean>;
|
|
234
|
-
protected readonly scrolling: _angular_core.
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
203
|
+
protected readonly scrolling: _angular_core.WritableSignal<boolean>;
|
|
204
|
+
protected readonly overflow: _angular_core.WritableSignal<boolean>;
|
|
205
|
+
protected readonly thumbSizeFr: _angular_core.WritableSignal<number>;
|
|
206
|
+
protected readonly thumbPositionFr: _angular_core.WritableSignal<number>;
|
|
238
207
|
constructor();
|
|
239
208
|
/**
|
|
240
|
-
* Computes the scroll position and updates CSS variables to render the scroll position
|
|
209
|
+
* Computes the scroll position and updates CSS variables to render the scroll position.
|
|
241
210
|
*/
|
|
242
211
|
private renderScrollPosition;
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
protected
|
|
247
|
-
|
|
212
|
+
/**
|
|
213
|
+
* Method invoked when clicking on the scrollbar thumb.
|
|
214
|
+
*/
|
|
215
|
+
protected onThumbMouseDown(mousedownEvent: MouseEvent): void;
|
|
216
|
+
/**
|
|
217
|
+
* Method invoked when clicking on the scrollbar track.
|
|
218
|
+
*
|
|
219
|
+
* Scrolls in discrete steps to the pointer, then switches to regular scrolling until releasing the mouse.
|
|
220
|
+
*/
|
|
221
|
+
protected onScrollTrackMouseDown(event: MouseEvent): void;
|
|
248
222
|
/**
|
|
249
223
|
* Renders the current scroll position when the viewport is scrolled.
|
|
250
224
|
*/
|
|
251
225
|
private installScrollPositionRenderer;
|
|
252
226
|
/**
|
|
253
|
-
*
|
|
227
|
+
* Moves the scrollbar thumb to the specified position, scrolling the viewport accordingly.
|
|
228
|
+
*
|
|
229
|
+
* The thumb position must be given in client coordinates (relative to the top-left corner of the page viewport).
|
|
254
230
|
*/
|
|
255
|
-
private
|
|
231
|
+
private scrollViewport;
|
|
256
232
|
/**
|
|
257
|
-
*
|
|
233
|
+
* Returns the position of this component in client coordinates.
|
|
234
|
+
*
|
|
235
|
+
* Returned coordinates are relative to the top-left corner of the page viewport.
|
|
236
|
+
* Depending on the scrollbar orientation, returned coordinates are `[top, bottom]` or `[left, right]`.
|
|
258
237
|
*/
|
|
259
|
-
private
|
|
238
|
+
private scrollbarComponentPosition;
|
|
260
239
|
/**
|
|
261
|
-
*
|
|
240
|
+
* Returns the size of the viewport in pixels.
|
|
241
|
+
*
|
|
242
|
+
* The viewport is the container for scrollable content (viewport client), displaying scrollbars if it overflows.
|
|
243
|
+
* Depending on the scrollbar orientation, the returned size is `viewport.clientHeight` or `viewport.clientWidth`.
|
|
262
244
|
*/
|
|
263
|
-
|
|
245
|
+
private viewportSize;
|
|
264
246
|
/**
|
|
265
|
-
*
|
|
247
|
+
* Returns the size of the viewport client in pixels.
|
|
248
|
+
*
|
|
249
|
+
* The viewport client represents scrollable content displayed in the viewport.
|
|
250
|
+
* Depending on the scrollbar orientation, the returned size is `viewport.scrollHeight` or `viewport.scrollWidth`.
|
|
251
|
+
*/
|
|
252
|
+
private viewportClientSize;
|
|
253
|
+
/**
|
|
254
|
+
* Returns the viewport's scroll position in pixels.
|
|
255
|
+
*
|
|
256
|
+
* Depending on the scrollbar orientation, the returned position is `viewport.scrollTop` or `viewport.scrollLeft`.
|
|
257
|
+
*/
|
|
258
|
+
private viewportScrollPosition;
|
|
259
|
+
/**
|
|
260
|
+
* Returns the size of the scrollbar thumb in pixels.
|
|
261
|
+
*
|
|
262
|
+
* The thumb is the handle used to scroll the scrollbar.
|
|
263
|
+
*/
|
|
264
|
+
private thumbSize;
|
|
265
|
+
/**
|
|
266
|
+
* Returns the current thumb position in client coordinates.
|
|
267
|
+
*
|
|
268
|
+
* Returned coordinates are relative to the top-left corner of the page viewport.
|
|
269
|
+
* Depending on the scrollbar orientation, returned coordinates are `[top, bottom]` or `[left, right]`.
|
|
270
|
+
*/
|
|
271
|
+
private thumbPosition;
|
|
272
|
+
/**
|
|
273
|
+
* Returns the size of the scrollbar track in pixels.
|
|
274
|
+
*
|
|
275
|
+
* The scrollbar track is the track along which the scrollbar thumb moves.
|
|
266
276
|
*/
|
|
267
|
-
private
|
|
268
|
-
private setCssVariable;
|
|
269
|
-
private get viewportSize();
|
|
270
|
-
private get viewportClientSize();
|
|
271
|
-
private get scrollPosition();
|
|
272
|
-
private get thumbSize();
|
|
273
|
-
private get trackSize();
|
|
277
|
+
private trackSize;
|
|
274
278
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SciScrollbarComponent, never>;
|
|
275
279
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SciScrollbarComponent, "sci-scrollbar", never, { "direction": { "alias": "direction"; "required": false; "isSignal": true; }; "viewport": { "alias": "viewport"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
276
280
|
}
|
|
@@ -285,16 +289,36 @@ declare class SciScrollbarComponent {
|
|
|
285
289
|
* This directive expects its host element to be the only child in document flow in its parent DOM element. It makes the host element
|
|
286
290
|
* fill up the entire space (width and height set to 100%). The parent element must have its CSS `overflow` property set to `hidden`
|
|
287
291
|
* to hide the pushed out native scrollbars.
|
|
292
|
+
*
|
|
293
|
+
* This directive provides the `isNativeScrollbarCropped` signal, which indicates whether native scrollbars are pushed out of the viewport element.
|
|
294
|
+
* In templates, access it via the exported template reference variable `sciScrollable`.
|
|
295
|
+
*
|
|
296
|
+
* ```html
|
|
297
|
+
* <div sciScrollable #sciScrollable="sciScrollable" #viewport>
|
|
298
|
+
* content
|
|
299
|
+
* </div>
|
|
300
|
+
*
|
|
301
|
+
* <!-- Render scrollbars only if native scrollbars are pushed out of the viewport element. -->
|
|
302
|
+
* @if (sciScrollable.isNativeScrollbarCropped()) {
|
|
303
|
+
* <sci-scrollbar [viewport]="viewport" direction="vscroll"/>
|
|
304
|
+
* <sci-scrollbar [viewport]="viewport" direction="hscroll"/>
|
|
305
|
+
* }
|
|
306
|
+
* ```
|
|
288
307
|
*/
|
|
289
308
|
declare class SciScrollableDirective {
|
|
290
309
|
/**
|
|
291
310
|
* Controls whether to display native scrollbars.
|
|
311
|
+
*
|
|
292
312
|
* Has no effect if the native scrollbar sits on top of the content, e.g. in OS X.
|
|
293
313
|
*/
|
|
294
314
|
readonly displayNativeScrollbar: _angular_core.InputSignal<boolean>;
|
|
295
315
|
private readonly _host;
|
|
296
316
|
private readonly _renderer;
|
|
297
317
|
private readonly _nativeScrollbarTrackSizeProvider;
|
|
318
|
+
/**
|
|
319
|
+
* Indicates whether native scrollbars are pushed out of the viewport element.
|
|
320
|
+
*/
|
|
321
|
+
readonly isNativeScrollbarCropped: _angular_core.Signal<boolean>;
|
|
298
322
|
constructor();
|
|
299
323
|
/**
|
|
300
324
|
* Controls the display of the native scrollbar based on this directive's configuration.
|
|
@@ -310,7 +334,7 @@ declare class SciScrollableDirective {
|
|
|
310
334
|
private shiftNativeScrollbars;
|
|
311
335
|
private setStyle;
|
|
312
336
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SciScrollableDirective, never>;
|
|
313
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SciScrollableDirective, "[sciScrollable]",
|
|
337
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SciScrollableDirective, "[sciScrollable]", ["sciScrollable"], { "displayNativeScrollbar": { "alias": "sciScrollableDisplayNativeScrollbar"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
314
338
|
}
|
|
315
339
|
|
|
316
340
|
export { SciScrollableDirective, SciScrollbarComponent, SciViewportComponent };
|
|
@@ -6,27 +6,18 @@
|
|
|
6
6
|
* Invoke from within the 'sci-scrollbar' selector.
|
|
7
7
|
*/
|
|
8
8
|
@mixin position() {
|
|
9
|
-
$scrollbar-size: 12px;
|
|
10
|
-
|
|
11
9
|
position: absolute;
|
|
12
|
-
transition-duration: 1s;
|
|
13
|
-
transition-property: opacity;
|
|
14
|
-
transition-timing-function: ease-out;
|
|
15
10
|
|
|
16
11
|
&.vertical {
|
|
17
|
-
top:
|
|
18
|
-
right:
|
|
19
|
-
bottom:
|
|
20
|
-
left: unset;
|
|
21
|
-
width: $scrollbar-size;
|
|
12
|
+
top: 2px;
|
|
13
|
+
right: 1px;
|
|
14
|
+
bottom: 2px;
|
|
22
15
|
}
|
|
23
16
|
|
|
24
17
|
&.horizontal {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
left: 0;
|
|
29
|
-
height: $scrollbar-size;
|
|
18
|
+
left: 2px;
|
|
19
|
+
bottom: 1px;
|
|
20
|
+
right: 2px;
|
|
30
21
|
}
|
|
31
22
|
}
|
|
32
23
|
|
|
@@ -39,7 +30,10 @@
|
|
|
39
30
|
* Invoke from within the viewport selector.
|
|
40
31
|
*/
|
|
41
32
|
@mixin hide-when-inactive() {
|
|
42
|
-
&:
|
|
33
|
+
&:is(
|
|
34
|
+
:not(:hover):not(:active), // Support "regular" host
|
|
35
|
+
:host(:not(:hover):not(:active)) // Support "shadow" host
|
|
36
|
+
) sci-scrollbar:not(.scrolling) {
|
|
43
37
|
opacity: 0; // do not use 'display' nor 'visibility' property to fade the scrollbar
|
|
44
38
|
}
|
|
45
39
|
}
|