@scion/components 18.1.0 → 19.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dimension/dimension.module.d.ts +2 -0
- package/dimension/public_api.d.ts +1 -1
- package/fesm2022/scion-components-dimension.mjs +36 -23
- package/fesm2022/scion-components-dimension.mjs.map +1 -1
- package/fesm2022/scion-components-sashbox.mjs +73 -43
- package/fesm2022/scion-components-sashbox.mjs.map +1 -1
- package/fesm2022/scion-components-splitter.mjs +40 -33
- package/fesm2022/scion-components-splitter.mjs.map +1 -1
- package/fesm2022/scion-components-throbber.mjs +39 -39
- package/fesm2022/scion-components-throbber.mjs.map +1 -1
- package/fesm2022/scion-components-viewport.mjs +225 -277
- package/fesm2022/scion-components-viewport.mjs.map +1 -1
- package/package.json +5 -17
- package/sashbox/sashbox.module.d.ts +2 -0
- package/splitter/public_api.d.ts +1 -1
- package/splitter/splitter.module.d.ts +2 -0
- package/throbber/throbber.module.d.ts +2 -0
- package/viewport/native-scrollbar-track-size-provider.service.d.ts +6 -16
- package/viewport/public_api.d.ts +1 -1
- package/viewport/scrollable.directive.d.ts +9 -10
- package/viewport/scrollbar/scrollbar.component.d.ts +17 -32
- package/viewport/viewport.component.d.ts +14 -16
- package/viewport/viewport.module.d.ts +2 -0
- package/esm2022/dimension/bounding-client-rect.signal.mjs +0 -53
- package/esm2022/dimension/dimension.directive.mjs +0 -62
- package/esm2022/dimension/dimension.mjs +0 -11
- package/esm2022/dimension/dimension.module.mjs +0 -34
- package/esm2022/dimension/dimension.signal.mjs +0 -58
- package/esm2022/dimension/public_api.mjs +0 -19
- package/esm2022/dimension/scion-components-dimension.mjs +0 -5
- package/esm2022/public-api.mjs +0 -11
- package/esm2022/sashbox/element-ref.directive.mjs +0 -31
- package/esm2022/sashbox/public_api.mjs +0 -18
- package/esm2022/sashbox/sash-initializer.directive.mjs +0 -35
- package/esm2022/sashbox/sash.directive.mjs +0 -145
- package/esm2022/sashbox/sashbox-accessor.mjs +0 -6
- package/esm2022/sashbox/sashbox.component.mjs +0 -282
- package/esm2022/sashbox/sashbox.module.mjs +0 -55
- package/esm2022/sashbox/scion-components-sashbox.mjs +0 -5
- package/esm2022/scion-components.mjs +0 -5
- package/esm2022/splitter/public_api.mjs +0 -17
- package/esm2022/splitter/scion-components-splitter.mjs +0 -5
- package/esm2022/splitter/splitter.component.mjs +0 -226
- package/esm2022/splitter/splitter.module.mjs +0 -38
- package/esm2022/throbber/ellipsis-throbber/ellipsis-throbber.component.mjs +0 -25
- package/esm2022/throbber/public_api.mjs +0 -17
- package/esm2022/throbber/ripple-throbber/ripple-throbber.component.mjs +0 -25
- package/esm2022/throbber/roller-throbber/roller-throbber.component.mjs +0 -25
- package/esm2022/throbber/scion-components-throbber.mjs +0 -5
- package/esm2022/throbber/spinner-throbber/spinner-throbber.component.mjs +0 -26
- package/esm2022/throbber/throbber.component.mjs +0 -72
- package/esm2022/throbber/throbber.module.mjs +0 -32
- package/esm2022/viewport/native-scrollbar-track-size-provider.service.mjs +0 -115
- package/esm2022/viewport/public_api.mjs +0 -19
- package/esm2022/viewport/scion-components-viewport.mjs +0 -5
- package/esm2022/viewport/scrollable.directive.mjs +0 -94
- package/esm2022/viewport/scrollbar/scrollbar.component.mjs +0 -323
- package/esm2022/viewport/viewport.component.mjs +0 -288
- package/esm2022/viewport/viewport.module.mjs +0 -42
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable,
|
|
2
|
+
import { inject, NgZone, Injectable, ElementRef, Renderer2, input, effect, untracked, Directive, DestroyRef, viewChild, computed, Component, ChangeDetectionStrategy, HostBinding, output, ViewEncapsulation, HostListener, NgModule } from '@angular/core';
|
|
3
|
+
import { DOCUMENT } from '@angular/common';
|
|
4
|
+
import { fromEvent, merge, mergeWith, timer, of } from 'rxjs';
|
|
5
|
+
import { debounceTime, startWith, map, distinctUntilChanged, first, withLatestFrom, takeWhile, takeUntil, switchMap } from 'rxjs/operators';
|
|
6
|
+
import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
7
|
+
import { subscribeIn, filterArray } from '@scion/toolkit/operators';
|
|
3
8
|
import { coerceElement } from '@angular/cdk/coercion';
|
|
4
|
-
import { debounceTime, startWith, map, distinctUntilChanged, takeUntil, switchMap, first, withLatestFrom, takeWhile } from 'rxjs/operators';
|
|
5
|
-
import { BehaviorSubject, Subject, fromEvent, merge, of, timer } from 'rxjs';
|
|
6
|
-
import { DOCUMENT, AsyncPipe } from '@angular/common';
|
|
7
9
|
import { fromResize$, fromMutation$ } from '@scion/toolkit/observable';
|
|
8
|
-
import
|
|
9
|
-
import * as i2 from '@angular/cdk/scrolling';
|
|
10
|
+
import * as i1 from '@angular/cdk/scrolling';
|
|
10
11
|
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
11
12
|
|
|
12
13
|
/*
|
|
13
|
-
* Copyright (c) 2018-
|
|
14
|
+
* Copyright (c) 2018-2024 Swiss Federal Railways
|
|
14
15
|
*
|
|
15
16
|
* This program and the accompanying materials are made
|
|
16
17
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -22,26 +23,14 @@ import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
|
22
23
|
* Provides the native scrollbar tracksize.
|
|
23
24
|
*/
|
|
24
25
|
class SciNativeScrollbarTrackSizeProvider {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this._zone = _zone;
|
|
28
|
-
this._trackSize$ = new BehaviorSubject(null);
|
|
29
|
-
this._destroy$ = new Subject();
|
|
30
|
-
this.installNativeScrollbarTrackSizeListener();
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Returns an {Observable} which emits the native scrollbar track size, if any, or else `null`.
|
|
34
|
-
*
|
|
35
|
-
* Upon subscription, it emits the track size immediately, and then continuously emits when the track size changes.
|
|
36
|
-
*/
|
|
37
|
-
get trackSize$() {
|
|
38
|
-
return this._trackSize$;
|
|
39
|
-
}
|
|
26
|
+
_document = inject(DOCUMENT);
|
|
27
|
+
_zone = inject(NgZone);
|
|
40
28
|
/**
|
|
41
|
-
*
|
|
29
|
+
* Provides the track size of the native scrollbar, or `null` if the native scrollbars sit on top of the content.
|
|
42
30
|
*/
|
|
43
|
-
|
|
44
|
-
|
|
31
|
+
trackSize;
|
|
32
|
+
constructor() {
|
|
33
|
+
this.trackSize = this.createNativeScrollbarTrackSizeSignal();
|
|
45
34
|
}
|
|
46
35
|
/**
|
|
47
36
|
* Computes the native scrollbar track size.
|
|
@@ -49,7 +38,7 @@ class SciNativeScrollbarTrackSizeProvider {
|
|
|
49
38
|
* @returns native track size, or `null` if the native scrollbars sit on top of the content.
|
|
50
39
|
*/
|
|
51
40
|
computeTrackSize() {
|
|
52
|
-
//
|
|
41
|
+
// Create temporary viewport and viewport client with native scrollbars to compute the scrolltrack width.
|
|
53
42
|
const viewportDiv = this._document.createElement('div');
|
|
54
43
|
setStyle(viewportDiv, {
|
|
55
44
|
position: 'absolute',
|
|
@@ -74,39 +63,29 @@ class SciNativeScrollbarTrackSizeProvider {
|
|
|
74
63
|
hScrollbarTrackHeight: viewportBounds.height - viewportClientBounds.height,
|
|
75
64
|
vScrollbarTrackWidth: viewportBounds.width - viewportClientBounds.width,
|
|
76
65
|
};
|
|
77
|
-
//
|
|
66
|
+
// Destroy temporary viewport.
|
|
78
67
|
this._document.body.removeChild(viewportDiv);
|
|
79
68
|
if (trackSize.hScrollbarTrackHeight === 0 && trackSize.vScrollbarTrackWidth === 0) {
|
|
80
69
|
return null;
|
|
81
70
|
}
|
|
82
71
|
return trackSize;
|
|
83
72
|
}
|
|
84
|
-
|
|
73
|
+
createNativeScrollbarTrackSizeSignal() {
|
|
85
74
|
// We compute the size of the native scrollbar track when the browser fires the onresize window event.
|
|
86
75
|
// This event is also fired on page zoom or when displaying a hidden document. Hidden documents do not have
|
|
87
76
|
// a scrollbar track size until being displayed, e.g., after showing hidden iframes.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
.subscribe(trackSize => {
|
|
93
|
-
this._zone.run(() => this._trackSize$.next(trackSize));
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
ngOnDestroy() {
|
|
98
|
-
this._destroy$.next();
|
|
77
|
+
const trackSize$ = fromEvent(window, 'resize')
|
|
78
|
+
.pipe(subscribeIn(fn => this._zone.runOutsideAngular(fn)), debounceTime(5), startWith(null), // trigger the initial computation
|
|
79
|
+
map(() => this.computeTrackSize()), distinctUntilChanged((t1, t2) => t1?.hScrollbarTrackHeight === t2?.hScrollbarTrackHeight && t1?.vScrollbarTrackWidth === t2?.vScrollbarTrackWidth));
|
|
80
|
+
return toSignal(trackSize$, { initialValue: null });
|
|
99
81
|
}
|
|
100
|
-
static
|
|
101
|
-
static
|
|
82
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
83
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, providedIn: 'root' });
|
|
102
84
|
}
|
|
103
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
85
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, decorators: [{
|
|
104
86
|
type: Injectable,
|
|
105
87
|
args: [{ providedIn: 'root' }]
|
|
106
|
-
}], ctorParameters: () => [
|
|
107
|
-
type: Inject,
|
|
108
|
-
args: [DOCUMENT]
|
|
109
|
-
}] }, { type: i0.NgZone }] });
|
|
88
|
+
}], ctorParameters: () => [] });
|
|
110
89
|
/**
|
|
111
90
|
* Applies the given style(s) to the given element.
|
|
112
91
|
*
|
|
@@ -140,24 +119,33 @@ function setStyle(element, style) {
|
|
|
140
119
|
* to hide the pushed out native scrollbars.
|
|
141
120
|
*/
|
|
142
121
|
class SciScrollableDirective {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
this.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
122
|
+
_host = inject((ElementRef)).nativeElement;
|
|
123
|
+
_renderer = inject(Renderer2);
|
|
124
|
+
_nativeScrollbarTrackSizeProvider = inject(SciNativeScrollbarTrackSizeProvider);
|
|
125
|
+
/**
|
|
126
|
+
* Controls whether to display native scrollbars.
|
|
127
|
+
* Has no effect if the native scrollbar sits on top of the content, e.g. in OS X.
|
|
128
|
+
*/
|
|
129
|
+
displayNativeScrollbar = input(false, { alias: 'sciScrollableDisplayNativeScrollbar' });
|
|
130
|
+
constructor() {
|
|
131
|
+
this.controlDisplayOfNativeScrollbar();
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Controls the display of the native scrollbar based on this directive's configuration.
|
|
135
|
+
*/
|
|
136
|
+
controlDisplayOfNativeScrollbar() {
|
|
137
|
+
effect(() => {
|
|
138
|
+
const displayNativeScrollbar = this.displayNativeScrollbar();
|
|
139
|
+
if (displayNativeScrollbar) {
|
|
140
|
+
untracked(() => this.useNativeScrollbars());
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const nativeScrollbarTrackSize = this._nativeScrollbarTrackSizeProvider.trackSize();
|
|
144
|
+
if (nativeScrollbarTrackSize) {
|
|
145
|
+
untracked(() => this.shiftNativeScrollbars(nativeScrollbarTrackSize));
|
|
158
146
|
}
|
|
159
147
|
else {
|
|
160
|
-
|
|
148
|
+
untracked(() => this.useNativeScrollbars());
|
|
161
149
|
}
|
|
162
150
|
});
|
|
163
151
|
}
|
|
@@ -165,7 +153,7 @@ class SciScrollableDirective {
|
|
|
165
153
|
* Uses the native scrollbars when content overflows.
|
|
166
154
|
*/
|
|
167
155
|
useNativeScrollbars() {
|
|
168
|
-
this.setStyle(this._host
|
|
156
|
+
this.setStyle(this._host, {
|
|
169
157
|
overflow: 'auto',
|
|
170
158
|
width: '100%',
|
|
171
159
|
height: '100%',
|
|
@@ -177,7 +165,7 @@ class SciScrollableDirective {
|
|
|
177
165
|
* Shifts the native scrollbars out of the visible viewport area.
|
|
178
166
|
*/
|
|
179
167
|
shiftNativeScrollbars(nativeScrollbarTrackSize) {
|
|
180
|
-
this.setStyle(this._host
|
|
168
|
+
this.setStyle(this._host, {
|
|
181
169
|
overflow: 'scroll',
|
|
182
170
|
width: `calc(100% + ${nativeScrollbarTrackSize.vScrollbarTrackWidth}px`,
|
|
183
171
|
height: `calc(100% + ${nativeScrollbarTrackSize.hScrollbarTrackHeight}px`,
|
|
@@ -188,25 +176,15 @@ class SciScrollableDirective {
|
|
|
188
176
|
setStyle(element, style) {
|
|
189
177
|
Object.keys(style).forEach(key => this._renderer.setStyle(element, key, style[key]));
|
|
190
178
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
ngOnDestroy() {
|
|
195
|
-
this._destroy$.next();
|
|
196
|
-
}
|
|
197
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: SciScrollableDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: SciNativeScrollbarTrackSizeProvider }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
198
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.1", type: SciScrollableDirective, isStandalone: true, selector: "[sciScrollable]", inputs: { isDisplayNativeScrollbar: ["sciScrollableDisplayNativeScrollbar", "isDisplayNativeScrollbar"] }, usesOnChanges: true, ngImport: i0 }); }
|
|
179
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SciScrollableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
180
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.0", type: SciScrollableDirective, isStandalone: true, selector: "[sciScrollable]", inputs: { displayNativeScrollbar: { classPropertyName: "displayNativeScrollbar", publicName: "sciScrollableDisplayNativeScrollbar", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
199
181
|
}
|
|
200
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
182
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SciScrollableDirective, decorators: [{
|
|
201
183
|
type: Directive,
|
|
202
184
|
args: [{
|
|
203
185
|
selector: '[sciScrollable]',
|
|
204
|
-
standalone: true,
|
|
205
186
|
}]
|
|
206
|
-
}], ctorParameters: () => [
|
|
207
|
-
type: Input,
|
|
208
|
-
args: ['sciScrollableDisplayNativeScrollbar']
|
|
209
|
-
}] } });
|
|
187
|
+
}], ctorParameters: () => [] });
|
|
210
188
|
|
|
211
189
|
/*
|
|
212
190
|
* Copyright (c) 2018-2019 Swiss Federal Railways
|
|
@@ -251,54 +229,38 @@ class SciScrollbarComponent {
|
|
|
251
229
|
*
|
|
252
230
|
* @internal
|
|
253
231
|
*/
|
|
254
|
-
static
|
|
232
|
+
static VIEWPORT_RESIZE_DEBOUNCE_TIME = 50;
|
|
233
|
+
_host = inject((ElementRef)).nativeElement;
|
|
234
|
+
_document = inject(DOCUMENT);
|
|
235
|
+
_zone = inject(NgZone);
|
|
236
|
+
_destroyRef = inject(DestroyRef);
|
|
237
|
+
_lastDragPosition = null;
|
|
238
|
+
_overflow = false;
|
|
239
|
+
_thumbSizeFr = 0;
|
|
240
|
+
_thumbPositionFr = 0;
|
|
241
|
+
_thumbElement = viewChild.required('thumb_handle');
|
|
242
|
+
_vertical = computed(() => this.direction() === 'vscroll');
|
|
255
243
|
get vertical() {
|
|
256
|
-
return this.
|
|
244
|
+
return this._vertical();
|
|
257
245
|
}
|
|
258
246
|
get horizontal() {
|
|
259
|
-
return this.
|
|
247
|
+
return !this._vertical();
|
|
260
248
|
}
|
|
261
249
|
get scrolling() {
|
|
262
250
|
return this._lastDragPosition !== null;
|
|
263
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* Specifies the direction of the scrollbar.
|
|
254
|
+
*
|
|
255
|
+
* By default, if not specified, renders a vertical scrollbar.
|
|
256
|
+
*/
|
|
257
|
+
direction = input('vscroll');
|
|
264
258
|
/**
|
|
265
259
|
* The viewport to provide scrollbars for.
|
|
266
260
|
*/
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
this.
|
|
270
|
-
}
|
|
271
|
-
constructor(_host, _document, _zone) {
|
|
272
|
-
this._host = _host;
|
|
273
|
-
this._document = _document;
|
|
274
|
-
this._zone = _zone;
|
|
275
|
-
this._destroy$ = new Subject();
|
|
276
|
-
this._viewportChange$ = new Subject();
|
|
277
|
-
this._lastDragPosition = null;
|
|
278
|
-
this._overflow = false;
|
|
279
|
-
this._thumbSizeFr = 0;
|
|
280
|
-
this._thumbPositionFr = 0;
|
|
281
|
-
/**
|
|
282
|
-
* Specifies the direction of the scrollbar.
|
|
283
|
-
*
|
|
284
|
-
* By default, if not specified, renders a vertical scrollbar.
|
|
285
|
-
*/
|
|
286
|
-
this.direction = 'vscroll';
|
|
287
|
-
this._viewportChange$
|
|
288
|
-
.pipe(switchMap(() => {
|
|
289
|
-
if (!this._viewport) {
|
|
290
|
-
return of(undefined);
|
|
291
|
-
}
|
|
292
|
-
return merge(this.viewportScrollChange$(), this.viewportDimensionChange$({ debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME }), this.viewportClientDimensionChange$({ debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME }));
|
|
293
|
-
}), subscribeInside(continueFn => this._zone.runOutsideAngular(continueFn)), takeUntil(this._destroy$))
|
|
294
|
-
.subscribe(() => {
|
|
295
|
-
if (this._viewport) {
|
|
296
|
-
this.renderScrollPosition();
|
|
297
|
-
}
|
|
298
|
-
else {
|
|
299
|
-
this.unsetScrollPosition();
|
|
300
|
-
}
|
|
301
|
-
});
|
|
261
|
+
viewport = input.required();
|
|
262
|
+
constructor() {
|
|
263
|
+
this.installScrollPositionRenderer();
|
|
302
264
|
}
|
|
303
265
|
/**
|
|
304
266
|
* Computes the scroll position and updates CSS variables to render the scroll position in the UI.
|
|
@@ -318,7 +280,7 @@ class SciScrollbarComponent {
|
|
|
318
280
|
}
|
|
319
281
|
if (overflow !== this._overflow) {
|
|
320
282
|
this._overflow = overflow;
|
|
321
|
-
overflow ? this._host.
|
|
283
|
+
overflow ? this._host.classList.add('overflow') : this._host.classList.remove('overflow');
|
|
322
284
|
}
|
|
323
285
|
}
|
|
324
286
|
/**
|
|
@@ -331,14 +293,12 @@ class SciScrollbarComponent {
|
|
|
331
293
|
this._overflow = false;
|
|
332
294
|
this.setCssVariable('--ɵsci-scrollbar-thumb-position-fr', 0);
|
|
333
295
|
this.setCssVariable('--ɵsci-scrollbar-thumb-size-fr', 0);
|
|
334
|
-
this._host.
|
|
296
|
+
this._host.classList.remove('overflow');
|
|
335
297
|
}
|
|
336
|
-
/* @docs-private */
|
|
337
298
|
onTouchStart(event) {
|
|
338
299
|
event.preventDefault();
|
|
339
300
|
this._lastDragPosition = this.vertical ? event.touches[0].screenY : event.touches[0].screenX;
|
|
340
301
|
}
|
|
341
|
-
/* @docs-private */
|
|
342
302
|
onTouchMove(event) {
|
|
343
303
|
event.preventDefault();
|
|
344
304
|
const newDragPositionPx = this.vertical ? event.touches[0].screenY : event.touches[0].screenX;
|
|
@@ -347,12 +307,10 @@ class SciScrollbarComponent {
|
|
|
347
307
|
this._lastDragPosition = newDragPositionPx;
|
|
348
308
|
this.moveViewportClient(viewportPanPx);
|
|
349
309
|
}
|
|
350
|
-
/* @docs-private */
|
|
351
310
|
onTouchEnd(event) {
|
|
352
311
|
event.preventDefault();
|
|
353
312
|
this._lastDragPosition = null;
|
|
354
313
|
}
|
|
355
|
-
/* @docs-private */
|
|
356
314
|
onMouseDown(mousedownEvent) {
|
|
357
315
|
if (mousedownEvent.button !== 0) {
|
|
358
316
|
return;
|
|
@@ -360,32 +318,49 @@ class SciScrollbarComponent {
|
|
|
360
318
|
mousedownEvent.preventDefault();
|
|
361
319
|
this._lastDragPosition = this.vertical ? mousedownEvent.screenY : mousedownEvent.screenX;
|
|
362
320
|
// Listen for 'mousemove' events
|
|
363
|
-
this.
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
321
|
+
const mousemoveListener = merge(fromEvent(this._document, 'mousemove'), fromEvent(this._document, 'sci-mousemove'))
|
|
322
|
+
.pipe(subscribeIn(fn => this._zone.runOutsideAngular(fn)), takeUntilDestroyed(this._destroyRef))
|
|
323
|
+
.subscribe(mousemoveEvent => {
|
|
324
|
+
NgZone.assertNotInAngularZone();
|
|
325
|
+
mousemoveEvent.preventDefault();
|
|
326
|
+
const newDragPositionPx = this.vertical ? mousemoveEvent.screenY : mousemoveEvent.screenX;
|
|
327
|
+
const scrollbarPanPx = newDragPositionPx - this._lastDragPosition;
|
|
328
|
+
const viewportPanPx = this.toViewportPanPx(scrollbarPanPx);
|
|
329
|
+
this._lastDragPosition = newDragPositionPx;
|
|
330
|
+
this.moveViewportClient(viewportPanPx);
|
|
331
|
+
});
|
|
332
|
+
// Listen for 'mouseup' events; use 'capture phase' and 'stop propagation' to not close overlays
|
|
333
|
+
merge(fromEvent(this._document, 'mouseup', { capture: true }), fromEvent(this._document, 'sci-mouseup'))
|
|
334
|
+
.pipe(subscribeIn(fn => this._zone.runOutsideAngular(fn)), first(), takeUntilDestroyed(this._destroyRef))
|
|
335
|
+
.subscribe(mouseupEvent => {
|
|
336
|
+
NgZone.assertNotInAngularZone();
|
|
337
|
+
mouseupEvent.stopPropagation();
|
|
338
|
+
mousemoveListener.unsubscribe();
|
|
339
|
+
this._lastDragPosition = null;
|
|
382
340
|
});
|
|
383
341
|
}
|
|
384
|
-
/* @docs-private */
|
|
385
342
|
onScrollTrackMouseDown(event, direction) {
|
|
386
343
|
const signum = (direction === 'up' ? -1 : +1);
|
|
387
344
|
this.scrollWhileMouseDown(this.toViewportPanPx(signum * this.thumbSize), event);
|
|
388
345
|
}
|
|
346
|
+
/**
|
|
347
|
+
* Renders the current scroll position when the viewport is scrolled.
|
|
348
|
+
*/
|
|
349
|
+
installScrollPositionRenderer() {
|
|
350
|
+
effect(onCleanup => {
|
|
351
|
+
const viewport = this.viewport();
|
|
352
|
+
untracked(() => {
|
|
353
|
+
if (!viewport) {
|
|
354
|
+
this.unsetScrollPosition();
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
const subscription = viewportScroll$(viewport)
|
|
358
|
+
.pipe(mergeWith(viewportSize$(viewport, { debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME })), mergeWith(viewportClientSize$(viewport, { debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME })), subscribeIn(fn => this._zone.runOutsideAngular(fn)))
|
|
359
|
+
.subscribe(() => this.renderScrollPosition());
|
|
360
|
+
onCleanup(() => subscription.unsubscribe());
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
}
|
|
389
364
|
/**
|
|
390
365
|
* Projects the given scrollbar scroll pixels into viewport scroll pixels.
|
|
391
366
|
*/
|
|
@@ -399,10 +374,10 @@ class SciScrollbarComponent {
|
|
|
399
374
|
*/
|
|
400
375
|
moveViewportClient(viewportPanPx) {
|
|
401
376
|
if (this.vertical) {
|
|
402
|
-
this.
|
|
377
|
+
this.viewport().scrollTop += viewportPanPx;
|
|
403
378
|
}
|
|
404
379
|
else {
|
|
405
|
-
this.
|
|
380
|
+
this.viewport().scrollLeft += viewportPanPx;
|
|
406
381
|
}
|
|
407
382
|
}
|
|
408
383
|
/**
|
|
@@ -434,81 +409,32 @@ class SciScrollbarComponent {
|
|
|
434
409
|
this.moveViewportClient(viewportScrollPx);
|
|
435
410
|
});
|
|
436
411
|
}
|
|
437
|
-
/**
|
|
438
|
-
* Emits whenever the viewport scrolls.
|
|
439
|
-
*/
|
|
440
|
-
viewportScrollChange$() {
|
|
441
|
-
return fromEvent(this._viewport, 'scroll', { passive: true }).pipe(map(() => undefined));
|
|
442
|
-
}
|
|
443
|
-
/**
|
|
444
|
-
* Emits on subscription, and then each time the size of the viewport changes.
|
|
445
|
-
*/
|
|
446
|
-
viewportDimensionChange$(options) {
|
|
447
|
-
return fromResize$(this._viewport)
|
|
448
|
-
.pipe(
|
|
449
|
-
// Debouncing is particularly important in the context of Angular animations, since they continuously
|
|
450
|
-
// trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
|
|
451
|
-
// expands a panel that contains a viewport.
|
|
452
|
-
debounceTime(options.debounceTime), map(() => undefined));
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* Emits on subscription, and then each time the size or style property of the viewport client changes.
|
|
456
|
-
*/
|
|
457
|
-
viewportClientDimensionChange$(options) {
|
|
458
|
-
return this.children$(this._viewport)
|
|
459
|
-
.pipe(switchMap(children => merge(...children.map(child => merge(fromResize$(child),
|
|
460
|
-
// Observe style mutations since some transformations change the scroll position without necessarily triggering a dimension change,
|
|
461
|
-
// e.g., `scale` or `translate` used by some virtual scroll implementations
|
|
462
|
-
fromMutation$(child, { subtree: false, childList: false, attributeFilter: ['style'] }))))),
|
|
463
|
-
// Debouncing is particularly important in the context of Angular animations, since they continuously
|
|
464
|
-
// trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
|
|
465
|
-
// expands a panel that contains a viewport.
|
|
466
|
-
debounceTime(options.debounceTime), map(() => undefined));
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* Emits the children of the passed element, and then each time child elements are added or removed.
|
|
470
|
-
*/
|
|
471
|
-
children$(element) {
|
|
472
|
-
return fromMutation$(element, { subtree: false, childList: true })
|
|
473
|
-
.pipe(startWith(undefined), map(() => Array.from(element.children)), filterArray((child) => child instanceof HTMLElement));
|
|
474
|
-
}
|
|
475
412
|
setCssVariable(key, value) {
|
|
476
|
-
this._host.
|
|
413
|
+
this._host.style.setProperty(key, value);
|
|
477
414
|
}
|
|
478
415
|
get viewportSize() {
|
|
479
|
-
return this.
|
|
416
|
+
return this.viewport() ? (this.vertical ? this.viewport().clientHeight : this.viewport().clientWidth) : 0;
|
|
480
417
|
}
|
|
481
418
|
get viewportClientSize() {
|
|
482
|
-
return this.
|
|
419
|
+
return this.viewport() ? (this.vertical ? this.viewport().scrollHeight : this.viewport().scrollWidth) : 0;
|
|
483
420
|
}
|
|
484
421
|
get scrollPosition() {
|
|
485
|
-
return this.
|
|
422
|
+
return this.viewport() ? (this.vertical ? this.viewport().scrollTop : this.viewport().scrollLeft) : 0;
|
|
486
423
|
}
|
|
487
424
|
get thumbSize() {
|
|
488
|
-
const thumbElement = this.
|
|
425
|
+
const thumbElement = this._thumbElement().nativeElement;
|
|
489
426
|
return this.vertical ? thumbElement.clientHeight : thumbElement.clientWidth;
|
|
490
427
|
}
|
|
491
428
|
get trackSize() {
|
|
492
|
-
|
|
493
|
-
return this.vertical ? trackElement.clientHeight : trackElement.clientWidth;
|
|
494
|
-
}
|
|
495
|
-
/* @docs-private */
|
|
496
|
-
ngOnDestroy() {
|
|
497
|
-
this._destroy$.next();
|
|
429
|
+
return this.vertical ? this._host.clientHeight : this._host.clientWidth;
|
|
498
430
|
}
|
|
499
|
-
static
|
|
500
|
-
static
|
|
431
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SciScrollbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
432
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.0.0", 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": "this.vertical", "class.horizontal": "this.horizontal", "class.scrolling": "this.scrolling" } }, viewQueries: [{ propertyName: "_thumbElement", first: true, predicate: ["thumb_handle"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- 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", styles: ["@charset \"UTF-8\";:host{display:flex;border:2px solid transparent;box-sizing:border-box;--\\275sci-scrollbar-thumb-position-fr: 0;--\\275sci-scrollbar-thumb-size-fr: 0}:host.vertical{flex-direction:column}:host.horizontal{flex-direction:row}:host>div.scrolltrack-start{flex-grow:var(--\\275sci-scrollbar-thumb-position-fr)}:host>div.thumb-handle{flex-basis:20px;display:flex;flex-grow:var(--\\275sci-scrollbar-thumb-size-fr);align-items:center}:host>div.thumb-handle.vertical{flex-direction:column}:host>div.thumb-handle.horizontal{flex-direction:row}: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-end{flex-grow:calc(1 - (var(--\\275sci-scrollbar-thumb-position-fr) + var(--\\275sci-scrollbar-thumb-size-fr)))}:host-context:not(.overflow){display:none}:host-context:hover>div.thumb-handle>div.thumb,:host-context(.scrolling)>div.thumb-handle>div.thumb{background-color:var(--sci-scrollbar-color);opacity:.75}:host-context:hover>div.thumb-handle>div.thumb.vertical,:host-context(.scrolling)>div.thumb-handle>div.thumb.vertical{width:100%}:host-context:hover>div.thumb-handle>div.thumb.horizontal,:host-context(.scrolling)>div.thumb-handle>div.thumb.horizontal{height:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
501
433
|
}
|
|
502
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
434
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SciScrollbarComponent, decorators: [{
|
|
503
435
|
type: Component,
|
|
504
|
-
args: [{ selector: 'sci-scrollbar', changeDetection: ChangeDetectionStrategy.OnPush,
|
|
505
|
-
}], ctorParameters: () => [
|
|
506
|
-
type: Inject,
|
|
507
|
-
args: [DOCUMENT]
|
|
508
|
-
}] }, { type: i0.NgZone }], propDecorators: { thumbElement: [{
|
|
509
|
-
type: ViewChild,
|
|
510
|
-
args: ['thumb_handle', { static: true }]
|
|
511
|
-
}], vertical: [{
|
|
436
|
+
args: [{ selector: 'sci-scrollbar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- 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", styles: ["@charset \"UTF-8\";:host{display:flex;border:2px solid transparent;box-sizing:border-box;--\\275sci-scrollbar-thumb-position-fr: 0;--\\275sci-scrollbar-thumb-size-fr: 0}:host.vertical{flex-direction:column}:host.horizontal{flex-direction:row}:host>div.scrolltrack-start{flex-grow:var(--\\275sci-scrollbar-thumb-position-fr)}:host>div.thumb-handle{flex-basis:20px;display:flex;flex-grow:var(--\\275sci-scrollbar-thumb-size-fr);align-items:center}:host>div.thumb-handle.vertical{flex-direction:column}:host>div.thumb-handle.horizontal{flex-direction:row}: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-end{flex-grow:calc(1 - (var(--\\275sci-scrollbar-thumb-position-fr) + var(--\\275sci-scrollbar-thumb-size-fr)))}:host-context:not(.overflow){display:none}:host-context:hover>div.thumb-handle>div.thumb,:host-context(.scrolling)>div.thumb-handle>div.thumb{background-color:var(--sci-scrollbar-color);opacity:.75}:host-context:hover>div.thumb-handle>div.thumb.vertical,:host-context(.scrolling)>div.thumb-handle>div.thumb.vertical{width:100%}:host-context:hover>div.thumb-handle>div.thumb.horizontal,:host-context(.scrolling)>div.thumb-handle>div.thumb.horizontal{height:100%}\n"] }]
|
|
437
|
+
}], ctorParameters: () => [], propDecorators: { vertical: [{
|
|
512
438
|
type: HostBinding,
|
|
513
439
|
args: ['class.vertical']
|
|
514
440
|
}], horizontal: [{
|
|
@@ -517,12 +443,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImpor
|
|
|
517
443
|
}], scrolling: [{
|
|
518
444
|
type: HostBinding,
|
|
519
445
|
args: ['class.scrolling']
|
|
520
|
-
}], direction: [{
|
|
521
|
-
type: Input
|
|
522
|
-
}], setViewport: [{
|
|
523
|
-
type: Input,
|
|
524
|
-
args: [{ alias: 'viewport', required: true }]
|
|
525
446
|
}] } });
|
|
447
|
+
/**
|
|
448
|
+
* Emits whenever the viewport scrolls.
|
|
449
|
+
*/
|
|
450
|
+
function viewportScroll$(viewport) {
|
|
451
|
+
return fromEvent(viewport, 'scroll', { passive: true }).pipe(map(() => undefined));
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Emits on subscription, and then each time the size of the viewport changes.
|
|
455
|
+
*/
|
|
456
|
+
function viewportSize$(viewport, options) {
|
|
457
|
+
return fromResize$(viewport)
|
|
458
|
+
.pipe(
|
|
459
|
+
// Debouncing is particularly important in the context of Angular animations, since they continuously
|
|
460
|
+
// trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
|
|
461
|
+
// expands a panel that contains a viewport.
|
|
462
|
+
debounceTime(options.debounceTime), map(() => undefined));
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Emits on subscription, and then each time the size or style property of the viewport client changes.
|
|
466
|
+
*/
|
|
467
|
+
function viewportClientSize$(viewport, options) {
|
|
468
|
+
return children$(viewport)
|
|
469
|
+
.pipe(switchMap(children => merge(...children.map(child => merge(fromResize$(child),
|
|
470
|
+
// Observe style mutations since some transformations change the scroll position without necessarily triggering a dimension change,
|
|
471
|
+
// e.g., `scale` or `translate` used by some virtual scroll implementations
|
|
472
|
+
fromMutation$(child, { subtree: false, childList: false, attributeFilter: ['style'] }))))),
|
|
473
|
+
// Debouncing is particularly important in the context of Angular animations, since they continuously
|
|
474
|
+
// trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
|
|
475
|
+
// expands a panel that contains a viewport.
|
|
476
|
+
debounceTime(options.debounceTime), map(() => undefined));
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Emits the children of the passed element, and then each time child elements are added or removed.
|
|
480
|
+
*/
|
|
481
|
+
function children$(element) {
|
|
482
|
+
return fromMutation$(element, { subtree: false, childList: true })
|
|
483
|
+
.pipe(startWith(undefined), map(() => Array.from(element.children)), filterArray((child) => child instanceof HTMLElement));
|
|
484
|
+
}
|
|
526
485
|
|
|
527
486
|
/*
|
|
528
487
|
* Copyright (c) 2018-2019 Swiss Federal Railways
|
|
@@ -601,40 +560,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImpor
|
|
|
601
560
|
* ```
|
|
602
561
|
*/
|
|
603
562
|
class SciViewportComponent {
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
/** @internal */
|
|
609
|
-
set setViewportClient(viewportClient) {
|
|
610
|
-
this._viewportClient = coerceElement(viewportClient);
|
|
611
|
-
}
|
|
563
|
+
_viewport = viewChild.required('viewport');
|
|
564
|
+
_viewportClient = viewChild.required('viewport_client');
|
|
565
|
+
_host = inject((ElementRef)).nativeElement;
|
|
566
|
+
nativeScrollbarTrackSizeProvider = inject(SciNativeScrollbarTrackSizeProvider);
|
|
612
567
|
/**
|
|
613
|
-
* Controls
|
|
614
|
-
* In the latter, the viewport client remains natively scrollable.
|
|
568
|
+
* Controls if to use the native scrollbar or a scrollbar that sits on top of the viewport. Defaults to `on-top`.
|
|
615
569
|
*/
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
this.host = host;
|
|
624
|
-
this.nativeScrollbarTrackSizeProvider = nativeScrollbarTrackSizeProvider;
|
|
625
|
-
this._scrollbarStyle = 'on-top';
|
|
626
|
-
/**
|
|
627
|
-
* Emits upon a scroll event.
|
|
628
|
-
*
|
|
629
|
-
* You can add [sciDimension] directive to the viewport or viewport client to be notified about layout changes.
|
|
630
|
-
*/
|
|
631
|
-
this.scroll = new EventEmitter(); // eslint-disable-line @angular-eslint/no-output-native
|
|
570
|
+
scrollbarStyle = input('on-top');
|
|
571
|
+
/**
|
|
572
|
+
* Emits when the viewport is scrolled. The event is emitted outside the Angular zone to avoid unnecessary change detection cycles.
|
|
573
|
+
*/
|
|
574
|
+
scroll = output();
|
|
575
|
+
constructor() {
|
|
576
|
+
this.installScrollEmitter();
|
|
632
577
|
}
|
|
633
578
|
focus() {
|
|
634
|
-
this.
|
|
635
|
-
}
|
|
636
|
-
onScroll(event) {
|
|
637
|
-
this.scroll.emit(event);
|
|
579
|
+
this.viewportElement.focus();
|
|
638
580
|
}
|
|
639
581
|
/**
|
|
640
582
|
* Returns the number of pixels that the viewport client is scrolled vertically.
|
|
@@ -642,7 +584,7 @@ class SciViewportComponent {
|
|
|
642
584
|
* @see Element.scrollTop
|
|
643
585
|
*/
|
|
644
586
|
get scrollTop() {
|
|
645
|
-
return this.
|
|
587
|
+
return this.viewportElement.scrollTop;
|
|
646
588
|
}
|
|
647
589
|
/**
|
|
648
590
|
* Sets the number of pixels that the viewport client is scrolled vertically.
|
|
@@ -650,7 +592,7 @@ class SciViewportComponent {
|
|
|
650
592
|
* @see Element.scrollTop
|
|
651
593
|
*/
|
|
652
594
|
set scrollTop(scrollTop) {
|
|
653
|
-
this.
|
|
595
|
+
this.viewportElement.scrollTop = scrollTop;
|
|
654
596
|
}
|
|
655
597
|
/**
|
|
656
598
|
* Returns the number of pixels that the viewport client is scrolled horizontally.
|
|
@@ -658,7 +600,7 @@ class SciViewportComponent {
|
|
|
658
600
|
* @see Element.scrollLeft
|
|
659
601
|
*/
|
|
660
602
|
get scrollLeft() {
|
|
661
|
-
return this.
|
|
603
|
+
return this.viewportElement.scrollLeft;
|
|
662
604
|
}
|
|
663
605
|
/**
|
|
664
606
|
* Sets the number of pixels that the viewport client is scrolled horizontally.
|
|
@@ -666,7 +608,7 @@ class SciViewportComponent {
|
|
|
666
608
|
* @see Element.scrollLeft
|
|
667
609
|
*/
|
|
668
610
|
set scrollLeft(scrollLeft) {
|
|
669
|
-
this.
|
|
611
|
+
this.viewportElement.scrollLeft = scrollLeft;
|
|
670
612
|
}
|
|
671
613
|
/**
|
|
672
614
|
* Returns the height of the viewport client.
|
|
@@ -674,7 +616,7 @@ class SciViewportComponent {
|
|
|
674
616
|
* @see Element.scrollHeight
|
|
675
617
|
*/
|
|
676
618
|
get scrollHeight() {
|
|
677
|
-
return this.
|
|
619
|
+
return this.viewportElement.scrollHeight;
|
|
678
620
|
}
|
|
679
621
|
/**
|
|
680
622
|
* Returns the width of the viewport client.
|
|
@@ -682,19 +624,19 @@ class SciViewportComponent {
|
|
|
682
624
|
* @see Element.scrollWidth
|
|
683
625
|
*/
|
|
684
626
|
get scrollWidth() {
|
|
685
|
-
return this.
|
|
627
|
+
return this.viewportElement.scrollWidth;
|
|
686
628
|
}
|
|
687
629
|
/**
|
|
688
630
|
* Returns the viewport {HTMLElement}.
|
|
689
631
|
*/
|
|
690
632
|
get viewportElement() {
|
|
691
|
-
return this.
|
|
633
|
+
return this._viewport().nativeElement;
|
|
692
634
|
}
|
|
693
635
|
/**
|
|
694
636
|
* Returns the viewport client {HTMLElement}.
|
|
695
637
|
*/
|
|
696
638
|
get viewportClientElement() {
|
|
697
|
-
return this._viewportClient;
|
|
639
|
+
return this._viewportClient().nativeElement;
|
|
698
640
|
}
|
|
699
641
|
/**
|
|
700
642
|
* Checks if the specified element is scrolled into the viewport.
|
|
@@ -716,15 +658,15 @@ class SciViewportComponent {
|
|
|
716
658
|
// 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.
|
|
717
659
|
// This can happen because `offsetLeft` and `offsetTop` operate on an integer (not a decimal), losing precision that can accumulate.
|
|
718
660
|
// To avoid incorrect calculation when there is no viewport overflow, we consider all contained elements as scrolled into the view.
|
|
719
|
-
if (this.
|
|
661
|
+
if (this.viewportElement.scrollWidth <= this.viewportElement.clientWidth && this.viewportElement.scrollHeight <= this.viewportElement.clientHeight) {
|
|
720
662
|
return true;
|
|
721
663
|
}
|
|
722
664
|
const elBottom = elTop + coerceElement(element).offsetHeight;
|
|
723
665
|
const elRight = elLeft + coerceElement(element).offsetWidth;
|
|
724
|
-
const vpTop = this.
|
|
725
|
-
const vpLeft = this.
|
|
726
|
-
const vpBottom = vpTop + this.
|
|
727
|
-
const vpRight = vpLeft + this.
|
|
666
|
+
const vpTop = this.viewportElement.scrollTop;
|
|
667
|
+
const vpLeft = this.viewportElement.scrollLeft;
|
|
668
|
+
const vpBottom = vpTop + this.viewportElement.clientHeight;
|
|
669
|
+
const vpRight = vpLeft + this.viewportElement.clientWidth;
|
|
728
670
|
if (fit === 'full') {
|
|
729
671
|
return (elTop >= vpTop && elBottom <= vpBottom) && (elLeft >= vpLeft && elRight <= vpRight);
|
|
730
672
|
}
|
|
@@ -747,8 +689,8 @@ class SciViewportComponent {
|
|
|
747
689
|
if (left === null) {
|
|
748
690
|
return;
|
|
749
691
|
}
|
|
750
|
-
this.
|
|
751
|
-
this.
|
|
692
|
+
this.viewportElement.scrollTop = top - offset;
|
|
693
|
+
this.viewportElement.scrollLeft = left - offset;
|
|
752
694
|
}
|
|
753
695
|
/**
|
|
754
696
|
* Computes the distance of the element to the viewport's left or top border.
|
|
@@ -774,31 +716,35 @@ class SciViewportComponent {
|
|
|
774
716
|
return null;
|
|
775
717
|
}
|
|
776
718
|
el = offsetParent;
|
|
777
|
-
} while (el !== this.
|
|
719
|
+
} while (el !== this._host);
|
|
778
720
|
return offset;
|
|
779
721
|
}
|
|
780
|
-
|
|
781
|
-
|
|
722
|
+
/**
|
|
723
|
+
* Emits when the scroll position changes.
|
|
724
|
+
*/
|
|
725
|
+
installScrollEmitter() {
|
|
726
|
+
const zone = inject(NgZone);
|
|
727
|
+
effect(onCleanup => {
|
|
728
|
+
const viewport = this._viewport();
|
|
729
|
+
untracked(() => {
|
|
730
|
+
const subscription = fromEvent(viewport.nativeElement, 'scroll')
|
|
731
|
+
.pipe(subscribeIn(fn => zone.runOutsideAngular(fn)))
|
|
732
|
+
.subscribe(event => this.scroll.emit(event));
|
|
733
|
+
onCleanup(() => subscription.unsubscribe());
|
|
734
|
+
});
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SciViewportComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
738
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: SciViewportComponent, isStandalone: true, selector: "sci-viewport", inputs: { scrollbarStyle: { classPropertyName: "scrollbarStyle", publicName: "scrollbarStyle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scroll: "scroll" }, host: { listeners: { "focus": "focus()" } }, viewQueries: [{ propertyName: "_viewport", first: true, predicate: ["viewport"], descendants: true, isSignal: true }, { propertyName: "_viewportClient", first: true, predicate: ["viewport_client"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- viewport and viewport client -->\n<div #viewport\n class=\"viewport\"\n tabindex=\"-1\"\n sciScrollable [sciScrollableDisplayNativeScrollbar]=\"scrollbarStyle() === 'native'\"\n cdkScrollable>\n <div #viewport_client class=\"viewport-client\" part=\"content\">\n <slot></slot>\n </div>\n</div>\n\n<!-- render emulated scrollbars which sit on-top -->\n@if (scrollbarStyle() === 'on-top' && nativeScrollbarTrackSizeProvider.trackSize() !== null) {\n <sci-scrollbar [direction]=\"'vscroll'\" [viewport]=\"viewport\" class=\"e2e-vertical\"/>\n <sci-scrollbar [direction]=\"'hscroll'\" [viewport]=\"viewport\" class=\"e2e-horizontal\"/>\n}\n", styles: [":host{display:grid;grid-template-columns:100%;grid-template-rows:100%;position:relative;overflow:hidden;outline:none}:host:host-context(: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;transition-duration:1s;transition-property:opacity;transition-timing-function:ease-out}:host>sci-scrollbar.vertical{top:0;right:0;bottom:0;left:unset;width:12px}:host>sci-scrollbar.horizontal{top:unset;right:0;bottom:0;left:0;height:12px}\n"], dependencies: [{ kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "directive", type: SciScrollableDirective, selector: "[sciScrollable]", inputs: ["sciScrollableDisplayNativeScrollbar"] }, { kind: "component", type: SciScrollbarComponent, selector: "sci-scrollbar", inputs: ["direction", "viewport"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
782
739
|
}
|
|
783
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
740
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SciViewportComponent, decorators: [{
|
|
784
741
|
type: Component,
|
|
785
|
-
args: [{ selector: 'sci-viewport', encapsulation: ViewEncapsulation.ShadowDom,
|
|
786
|
-
AsyncPipe,
|
|
742
|
+
args: [{ selector: 'sci-viewport', encapsulation: ViewEncapsulation.ShadowDom, imports: [
|
|
787
743
|
ScrollingModule,
|
|
788
744
|
SciScrollableDirective,
|
|
789
745
|
SciScrollbarComponent,
|
|
790
|
-
], template: "<!-- viewport and viewport client -->\n<div #viewport\n class=\"viewport\"\n tabindex=\"-1\"\n sciScrollable [sciScrollableDisplayNativeScrollbar]=\"scrollbarStyle === 'native'\"\n cdkScrollable
|
|
791
|
-
}], ctorParameters: () => [
|
|
792
|
-
type: ViewChild,
|
|
793
|
-
args: ['viewport', { static: true }]
|
|
794
|
-
}], setViewportClient: [{
|
|
795
|
-
type: ViewChild,
|
|
796
|
-
args: ['viewport_client', { static: true }]
|
|
797
|
-
}], scrollbarStyle: [{
|
|
798
|
-
type: Input
|
|
799
|
-
}], scroll: [{
|
|
800
|
-
type: Output
|
|
801
|
-
}], focus: [{
|
|
746
|
+
], template: "<!-- viewport and viewport client -->\n<div #viewport\n class=\"viewport\"\n tabindex=\"-1\"\n sciScrollable [sciScrollableDisplayNativeScrollbar]=\"scrollbarStyle() === 'native'\"\n cdkScrollable>\n <div #viewport_client class=\"viewport-client\" part=\"content\">\n <slot></slot>\n </div>\n</div>\n\n<!-- render emulated scrollbars which sit on-top -->\n@if (scrollbarStyle() === 'on-top' && nativeScrollbarTrackSizeProvider.trackSize() !== null) {\n <sci-scrollbar [direction]=\"'vscroll'\" [viewport]=\"viewport\" class=\"e2e-vertical\"/>\n <sci-scrollbar [direction]=\"'hscroll'\" [viewport]=\"viewport\" class=\"e2e-horizontal\"/>\n}\n", styles: [":host{display:grid;grid-template-columns:100%;grid-template-rows:100%;position:relative;overflow:hidden;outline:none}:host:host-context(: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;transition-duration:1s;transition-property:opacity;transition-timing-function:ease-out}:host>sci-scrollbar.vertical{top:0;right:0;bottom:0;left:unset;width:12px}:host>sci-scrollbar.horizontal{top:unset;right:0;bottom:0;left:0;height:12px}\n"] }]
|
|
747
|
+
}], ctorParameters: () => [], propDecorators: { focus: [{
|
|
802
748
|
type: HostListener,
|
|
803
749
|
args: ['focus']
|
|
804
750
|
}] } });
|
|
@@ -814,17 +760,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImpor
|
|
|
814
760
|
*/
|
|
815
761
|
/**
|
|
816
762
|
* Provides a viewport component with scrollbars that sit on top of the viewport client.
|
|
763
|
+
*
|
|
764
|
+
* @deprecated since version 19.0.0; Import standalone components and directive instead; API will be removed in a future release.
|
|
817
765
|
*/
|
|
818
766
|
class SciViewportModule {
|
|
819
|
-
static
|
|
820
|
-
static
|
|
767
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SciViewportModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
768
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.0", ngImport: i0, type: SciViewportModule, imports: [SciViewportComponent,
|
|
821
769
|
SciScrollbarComponent,
|
|
822
770
|
SciScrollableDirective], exports: [SciViewportComponent,
|
|
823
771
|
SciScrollbarComponent,
|
|
824
|
-
SciScrollableDirective] });
|
|
825
|
-
static
|
|
772
|
+
SciScrollableDirective] });
|
|
773
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SciViewportModule, imports: [SciViewportComponent] });
|
|
826
774
|
}
|
|
827
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
775
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SciViewportModule, decorators: [{
|
|
828
776
|
type: NgModule,
|
|
829
777
|
args: [{
|
|
830
778
|
imports: [
|