@acorex/cdk 22.4.7 → 22.4.8
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.
|
@@ -0,0 +1,808 @@
|
|
|
1
|
+
import { DOCUMENT, isPlatformBrowser } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { inject, ElementRef, DestroyRef, PLATFORM_ID, input, afterRenderEffect, effect, afterNextRender, Directive } from '@angular/core';
|
|
4
|
+
|
|
5
|
+
/** CSS custom properties for overlay scrollbar styling (set on the scroll host or in CSS). */
|
|
6
|
+
const AX_OVERLAY_SCROLLBAR_CSS_VARS = {
|
|
7
|
+
size: '--ax-comp-overlay-scrollbar-size',
|
|
8
|
+
thumbRadius: '--ax-comp-overlay-scrollbar-thumb-radius',
|
|
9
|
+
trackRadius: '--ax-comp-overlay-scrollbar-track-radius',
|
|
10
|
+
trackColor: '--ax-comp-overlay-scrollbar-track-color',
|
|
11
|
+
thumbColor: '--ax-comp-overlay-scrollbar-thumb-color',
|
|
12
|
+
thumbActiveColor: '--ax-comp-overlay-scrollbar-thumb-active-color',
|
|
13
|
+
thumbHoverColor: '--ax-comp-overlay-scrollbar-thumb-hover-color',
|
|
14
|
+
trackActiveColor: '--ax-comp-overlay-scrollbar-track-active-color',
|
|
15
|
+
thumbBorderWidth: '--ax-comp-overlay-scrollbar-thumb-border-width',
|
|
16
|
+
thumbBorderColor: '--ax-comp-overlay-scrollbar-thumb-border-color',
|
|
17
|
+
trackBorderWidth: '--ax-comp-overlay-scrollbar-track-border-width',
|
|
18
|
+
trackBorderColor: '--ax-comp-overlay-scrollbar-track-border-color',
|
|
19
|
+
fadeDuration: '--ax-comp-overlay-scrollbar-fade-duration',
|
|
20
|
+
};
|
|
21
|
+
const OVERLAY_SCROLLBAR_TOKEN_NAMES = Object.values(AX_OVERLAY_SCROLLBAR_CSS_VARS);
|
|
22
|
+
const ROOT_CLASS = 'ax-cdk-overlay-scrollbar-root';
|
|
23
|
+
const RAIL_CLASS = 'ax-cdk-overlay-scrollbar__rail';
|
|
24
|
+
const TRACK_CLASS = 'ax-cdk-overlay-scrollbar__rail-track';
|
|
25
|
+
const THUMB_CLASS = 'ax-cdk-overlay-scrollbar__rail-thumb';
|
|
26
|
+
const NAV_BTN_CLASS = 'ax-cdk-overlay-scrollbar__nav-button';
|
|
27
|
+
const NAV_BTN_PRESSED_CLASS = 'ax-cdk-overlay-scrollbar__nav-button--pressed';
|
|
28
|
+
const NAV_ARROW_CLASS = 'ax-cdk-overlay-scrollbar__nav-arrow';
|
|
29
|
+
const RAIL_WITH_NAV_CLASS = 'ax-cdk-overlay-scrollbar__rail--with-nav';
|
|
30
|
+
const VISIBLE_CLASS = 'ax-cdk-overlay-scrollbar--active';
|
|
31
|
+
/** Applied while dragging the thumb (active fill; not used during wheel/content scroll). */
|
|
32
|
+
const ENGAGED_CLASS = 'ax-cdk-overlay-scrollbar--engaged';
|
|
33
|
+
/** Primary button down on the track (outside thumb); `:active` is unreliable with `preventDefault`. */
|
|
34
|
+
const TRACK_PRESSED_CLASS = 'ax-cdk-overlay-scrollbar--track-pressed';
|
|
35
|
+
const OVERLAY_SCROLLBAR_STYLES = `
|
|
36
|
+
.ax-cdk-overlay-scrollbar-root {
|
|
37
|
+
position: relative;
|
|
38
|
+
display: block;
|
|
39
|
+
min-height: 0;
|
|
40
|
+
--ax-comp-overlay-scrollbar-size: 6px;
|
|
41
|
+
--ax-comp-overlay-scrollbar-fade-duration: 0.35s;
|
|
42
|
+
--ax-comp-overlay-scrollbar-thumb-radius: 4px;
|
|
43
|
+
--ax-comp-overlay-scrollbar-track-radius: 4px;
|
|
44
|
+
--ax-comp-overlay-scrollbar-track-color: transparent;
|
|
45
|
+
--ax-comp-overlay-scrollbar-thumb-color: var(--ax-sys-scroller-thumb-color, #64748b);
|
|
46
|
+
--ax-comp-overlay-scrollbar-thumb-border-width: 0;
|
|
47
|
+
--ax-comp-overlay-scrollbar-thumb-border-color: transparent;
|
|
48
|
+
--ax-comp-overlay-scrollbar-track-border-width: 0;
|
|
49
|
+
--ax-comp-overlay-scrollbar-track-border-color: transparent;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.ax-cdk-overlay-scrollbar {
|
|
53
|
+
position: relative;
|
|
54
|
+
--ax-comp-overlay-scrollbar-size: 6px;
|
|
55
|
+
--ax-comp-overlay-scrollbar-fade-duration: 0.35s;
|
|
56
|
+
--ax-comp-overlay-scrollbar-thumb-radius: 4px;
|
|
57
|
+
--ax-comp-overlay-scrollbar-track-radius: 4px;
|
|
58
|
+
--ax-comp-overlay-scrollbar-track-color: transparent;
|
|
59
|
+
--ax-comp-overlay-scrollbar-thumb-color: var(--ax-sys-scroller-thumb-color, #64748b);
|
|
60
|
+
--ax-comp-overlay-scrollbar-thumb-border-width: 0;
|
|
61
|
+
--ax-comp-overlay-scrollbar-thumb-border-color: transparent;
|
|
62
|
+
--ax-comp-overlay-scrollbar-track-border-width: 0;
|
|
63
|
+
--ax-comp-overlay-scrollbar-track-border-color: transparent;
|
|
64
|
+
|
|
65
|
+
scrollbar-width: none !important;
|
|
66
|
+
-ms-overflow-style: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.ax-cdk-overlay-scrollbar::-webkit-scrollbar {
|
|
70
|
+
display: none !important;
|
|
71
|
+
width: 0 !important;
|
|
72
|
+
height: 0 !important;
|
|
73
|
+
background: transparent !important;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.ax-cdk-overlay-scrollbar__rail {
|
|
77
|
+
position: absolute;
|
|
78
|
+
top: 0;
|
|
79
|
+
bottom: 0;
|
|
80
|
+
inset-inline-end: 0;
|
|
81
|
+
width: var(--ax-comp-overlay-scrollbar-size, 6px);
|
|
82
|
+
overflow: hidden;
|
|
83
|
+
pointer-events: auto;
|
|
84
|
+
opacity: 0;
|
|
85
|
+
z-index: 10;
|
|
86
|
+
box-sizing: border-box;
|
|
87
|
+
border-radius: var(--ax-comp-overlay-scrollbar-track-radius, 4px);
|
|
88
|
+
background-color: var(--ax-comp-overlay-scrollbar-track-color, transparent);
|
|
89
|
+
border-width: var(--ax-comp-overlay-scrollbar-track-border-width, 0);
|
|
90
|
+
border-style: solid;
|
|
91
|
+
border-color: var(--ax-comp-overlay-scrollbar-track-border-color, transparent);
|
|
92
|
+
transition:
|
|
93
|
+
opacity var(--ax-comp-overlay-scrollbar-fade-duration, 0.35s) ease,
|
|
94
|
+
background-color 0.15s ease;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.ax-cdk-overlay-scrollbar-root.ax-cdk-overlay-scrollbar--active .ax-cdk-overlay-scrollbar__rail,
|
|
98
|
+
.ax-cdk-overlay-scrollbar.ax-cdk-overlay-scrollbar--active .ax-cdk-overlay-scrollbar__rail {
|
|
99
|
+
opacity: 1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.ax-cdk-overlay-scrollbar__rail-track {
|
|
103
|
+
position: absolute;
|
|
104
|
+
inset: 0;
|
|
105
|
+
box-sizing: border-box;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.ax-cdk-overlay-scrollbar-root.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--track-pressed
|
|
109
|
+
.ax-cdk-overlay-scrollbar__rail,
|
|
110
|
+
.ax-cdk-overlay-scrollbar.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--track-pressed
|
|
111
|
+
.ax-cdk-overlay-scrollbar__rail,
|
|
112
|
+
.ax-cdk-overlay-scrollbar-root.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--engaged
|
|
113
|
+
.ax-cdk-overlay-scrollbar__rail,
|
|
114
|
+
.ax-cdk-overlay-scrollbar.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--engaged
|
|
115
|
+
.ax-cdk-overlay-scrollbar__rail {
|
|
116
|
+
background-color: var(
|
|
117
|
+
--ax-comp-overlay-scrollbar-track-active-color,
|
|
118
|
+
var(--ax-comp-overlay-scrollbar-track-color, transparent)
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.ax-cdk-overlay-scrollbar__rail--with-nav {
|
|
123
|
+
display: flex;
|
|
124
|
+
flex-direction: column;
|
|
125
|
+
overflow: hidden;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.ax-cdk-overlay-scrollbar__rail--with-nav .ax-cdk-overlay-scrollbar__rail-track {
|
|
129
|
+
position: relative;
|
|
130
|
+
flex: 1 1 auto;
|
|
131
|
+
min-height: 0;
|
|
132
|
+
inset: auto;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.ax-cdk-overlay-scrollbar__nav-button {
|
|
136
|
+
display: none;
|
|
137
|
+
flex: 0 0 var(--ax-comp-overlay-scrollbar-size, 6px);
|
|
138
|
+
width: 100%;
|
|
139
|
+
min-height: var(--ax-comp-overlay-scrollbar-size, 6px);
|
|
140
|
+
margin: 0;
|
|
141
|
+
padding: 0;
|
|
142
|
+
border: none;
|
|
143
|
+
box-sizing: border-box;
|
|
144
|
+
cursor: default;
|
|
145
|
+
align-items: center;
|
|
146
|
+
justify-content: center;
|
|
147
|
+
background-color: transparent;
|
|
148
|
+
color: var(--ax-comp-overlay-scrollbar-thumb-color, var(--ax-sys-scroller-thumb-color, #64748b));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.ax-cdk-overlay-scrollbar__rail--with-nav .ax-cdk-overlay-scrollbar__nav-button {
|
|
152
|
+
display: flex;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.ax-cdk-overlay-scrollbar__nav-arrow {
|
|
156
|
+
width: 0;
|
|
157
|
+
height: 0;
|
|
158
|
+
border-left: 3px solid transparent;
|
|
159
|
+
border-right: 3px solid transparent;
|
|
160
|
+
pointer-events: none;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.ax-cdk-overlay-scrollbar__nav-arrow--up {
|
|
164
|
+
border-bottom: 4px solid currentColor;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.ax-cdk-overlay-scrollbar__nav-arrow--down {
|
|
168
|
+
border-top: 4px solid currentColor;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.ax-cdk-overlay-scrollbar__rail-thumb {
|
|
172
|
+
position: absolute;
|
|
173
|
+
top: 0;
|
|
174
|
+
inset-inline-start: 0;
|
|
175
|
+
width: 100%;
|
|
176
|
+
box-sizing: border-box;
|
|
177
|
+
border-radius: var(--ax-comp-overlay-scrollbar-thumb-radius, 4px);
|
|
178
|
+
background-color: var(--ax-comp-overlay-scrollbar-thumb-color, var(--ax-sys-scroller-thumb-color, #64748b));
|
|
179
|
+
border-width: var(--ax-comp-overlay-scrollbar-thumb-border-width, 0);
|
|
180
|
+
border-style: solid;
|
|
181
|
+
border-color: var(--ax-comp-overlay-scrollbar-thumb-border-color, transparent);
|
|
182
|
+
transition: background-color 0.15s ease;
|
|
183
|
+
pointer-events: auto;
|
|
184
|
+
touch-action: none;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.ax-cdk-overlay-scrollbar__rail-thumb::before {
|
|
188
|
+
content: '';
|
|
189
|
+
position: absolute;
|
|
190
|
+
inset: -4px -8px;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.ax-cdk-overlay-scrollbar-root.ax-cdk-overlay-scrollbar--active .ax-cdk-overlay-scrollbar__rail-thumb:hover,
|
|
194
|
+
.ax-cdk-overlay-scrollbar.ax-cdk-overlay-scrollbar--active .ax-cdk-overlay-scrollbar__rail-thumb:hover {
|
|
195
|
+
background-color: var(
|
|
196
|
+
--ax-comp-overlay-scrollbar-thumb-hover-color,
|
|
197
|
+
var(
|
|
198
|
+
--ax-comp-overlay-scrollbar-thumb-active-color,
|
|
199
|
+
var(--ax-comp-overlay-scrollbar-thumb-color, var(--ax-sys-scroller-thumb-color, #64748b))
|
|
200
|
+
)
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.ax-cdk-overlay-scrollbar-root.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--engaged
|
|
205
|
+
.ax-cdk-overlay-scrollbar__rail-thumb,
|
|
206
|
+
.ax-cdk-overlay-scrollbar.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--engaged
|
|
207
|
+
.ax-cdk-overlay-scrollbar__rail-thumb,
|
|
208
|
+
.ax-cdk-overlay-scrollbar-root.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--engaged
|
|
209
|
+
.ax-cdk-overlay-scrollbar__rail-thumb:hover,
|
|
210
|
+
.ax-cdk-overlay-scrollbar.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--engaged
|
|
211
|
+
.ax-cdk-overlay-scrollbar__rail-thumb:hover {
|
|
212
|
+
background-color: var(
|
|
213
|
+
--ax-comp-overlay-scrollbar-thumb-active-color,
|
|
214
|
+
var(--ax-comp-overlay-scrollbar-thumb-color, var(--ax-sys-scroller-thumb-color, #64748b))
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
`.trim();
|
|
218
|
+
const STYLE_ELEMENT_ID = 'ax-overlay-scrollbar-styles';
|
|
219
|
+
const DEFAULT_HIDE_DELAY_MS = 800;
|
|
220
|
+
const MIN_SCROLLBAR_WIDTH_PX = 2;
|
|
221
|
+
const MAX_SCROLLBAR_WIDTH_PX = 32;
|
|
222
|
+
const DEFAULT_SCROLLBAR_WIDTH_PX = 6;
|
|
223
|
+
const MIN_THUMB_HEIGHT_PX = 20;
|
|
224
|
+
const DEFAULT_NAV_SCROLL_STEP_PX = 40;
|
|
225
|
+
function clampOverlayScrollbarWidth(px) {
|
|
226
|
+
if (!Number.isFinite(px)) {
|
|
227
|
+
return DEFAULT_SCROLLBAR_WIDTH_PX;
|
|
228
|
+
}
|
|
229
|
+
return Math.min(MAX_SCROLLBAR_WIDTH_PX, Math.max(MIN_SCROLLBAR_WIDTH_PX, Math.round(px)));
|
|
230
|
+
}
|
|
231
|
+
function injectOverlayScrollbarStyles(document) {
|
|
232
|
+
const existing = document.getElementById(STYLE_ELEMENT_ID);
|
|
233
|
+
if (existing) {
|
|
234
|
+
existing.textContent = OVERLAY_SCROLLBAR_STYLES;
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const style = document.createElement('style');
|
|
238
|
+
style.id = STYLE_ELEMENT_ID;
|
|
239
|
+
style.textContent = OVERLAY_SCROLLBAR_STYLES;
|
|
240
|
+
document.head.appendChild(style);
|
|
241
|
+
}
|
|
242
|
+
/** Rail is a sibling of the host; copy resolved tokens from the host so the rail can use them. */
|
|
243
|
+
function syncOverlayScrollbarDesignTokens(host, root) {
|
|
244
|
+
if (!root) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const computed = getComputedStyle(host);
|
|
248
|
+
for (const varName of OVERLAY_SCROLLBAR_TOKEN_NAMES) {
|
|
249
|
+
const value = computed.getPropertyValue(varName).trim();
|
|
250
|
+
if (value) {
|
|
251
|
+
root.style.setProperty(varName, value);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
root.style.removeProperty(varName);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function readRailWidthPx(rail) {
|
|
259
|
+
const width = rail.offsetWidth;
|
|
260
|
+
if (width > 0) {
|
|
261
|
+
return width;
|
|
262
|
+
}
|
|
263
|
+
const parsed = Number.parseFloat(getComputedStyle(rail).width);
|
|
264
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
265
|
+
return parsed;
|
|
266
|
+
}
|
|
267
|
+
const sizeToken = getComputedStyle(rail).getPropertyValue(AX_OVERLAY_SCROLLBAR_CSS_VARS.size).trim();
|
|
268
|
+
const fromToken = Number.parseFloat(sizeToken);
|
|
269
|
+
if (Number.isFinite(fromToken) && fromToken > 0) {
|
|
270
|
+
return fromToken;
|
|
271
|
+
}
|
|
272
|
+
return DEFAULT_SCROLLBAR_WIDTH_PX;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Custom overlay scrollbar: native scrollbars are hidden; a positioned thumb reflects scroll position.
|
|
276
|
+
* Styles are injected once by this directive.
|
|
277
|
+
*/
|
|
278
|
+
class AXOverlayScrollbarDirective {
|
|
279
|
+
constructor() {
|
|
280
|
+
this.host = inject(ElementRef);
|
|
281
|
+
this.destroyRef = inject(DestroyRef);
|
|
282
|
+
this.platformId = inject(PLATFORM_ID);
|
|
283
|
+
this.document = inject(DOCUMENT);
|
|
284
|
+
this.rootEl = null;
|
|
285
|
+
this.railEl = null;
|
|
286
|
+
this.trackEl = null;
|
|
287
|
+
this.navUpEl = null;
|
|
288
|
+
this.navDownEl = null;
|
|
289
|
+
this.thumbEl = null;
|
|
290
|
+
this.resizeObserver = null;
|
|
291
|
+
this.designTokenMutationObserver = null;
|
|
292
|
+
this.designTokenSyncFrame = null;
|
|
293
|
+
this.thumbDragPointerId = null;
|
|
294
|
+
this.pointerOverRail = false;
|
|
295
|
+
this.trackPressReleaseListener = null;
|
|
296
|
+
this.unbindRailInteraction = null;
|
|
297
|
+
/** Thumb size derived from layout; position updates on scroll without re-measuring scrollHeight. */
|
|
298
|
+
this.thumbLayout = null;
|
|
299
|
+
this.hideDelay = input(DEFAULT_HIDE_DELAY_MS, /* @ts-ignore */
|
|
300
|
+
...(ngDevMode ? [{ debugName: "hideDelay" }] : /* istanbul ignore next */ []));
|
|
301
|
+
/**
|
|
302
|
+
* When true, shows browser-style up/down arrow buttons on the rail.
|
|
303
|
+
* Styling follows track/thumb CSS tokens.
|
|
304
|
+
*/
|
|
305
|
+
this.navigationButtons = input(false, /* @ts-ignore */
|
|
306
|
+
...(ngDevMode ? [{ debugName: "navigationButtons" }] : /* istanbul ignore next */ []));
|
|
307
|
+
/** Pixels to scroll per arrow click. */
|
|
308
|
+
this.navScrollStep = input(DEFAULT_NAV_SCROLL_STEP_PX, /* @ts-ignore */
|
|
309
|
+
...(ngDevMode ? [{ debugName: "navScrollStep" }] : /* istanbul ignore next */ []));
|
|
310
|
+
this.hideTimer = null;
|
|
311
|
+
afterRenderEffect(() => {
|
|
312
|
+
if (!isPlatformBrowser(this.platformId) || !this.rootEl) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
syncOverlayScrollbarDesignTokens(this.host.nativeElement, this.rootEl);
|
|
316
|
+
});
|
|
317
|
+
effect(() => {
|
|
318
|
+
if (!isPlatformBrowser(this.platformId)) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
this.navigationButtons();
|
|
322
|
+
this.remeasureCustomThumb();
|
|
323
|
+
});
|
|
324
|
+
afterNextRender(() => {
|
|
325
|
+
if (!isPlatformBrowser(this.platformId)) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
injectOverlayScrollbarStyles(this.document);
|
|
329
|
+
const element = this.host.nativeElement;
|
|
330
|
+
this.mountCustomScrollbar(element);
|
|
331
|
+
const interactionRoot = () => this.rootEl ?? element;
|
|
332
|
+
const onScroll = () => {
|
|
333
|
+
this.syncThumbPosition();
|
|
334
|
+
this.bumpVisibility();
|
|
335
|
+
};
|
|
336
|
+
const onScrollEnd = () => {
|
|
337
|
+
this.scheduleHide();
|
|
338
|
+
this.syncEngagedAfterScroll();
|
|
339
|
+
};
|
|
340
|
+
const onPointerEnter = () => this.bumpVisibility();
|
|
341
|
+
const onPointerMove = () => this.bumpVisibility();
|
|
342
|
+
const onPointerLeave = () => {
|
|
343
|
+
if (this.thumbDragPointerId === null) {
|
|
344
|
+
this.setScrollbarEngaged(false);
|
|
345
|
+
}
|
|
346
|
+
this.deactivateThumb();
|
|
347
|
+
};
|
|
348
|
+
element.addEventListener('scroll', onScroll, { passive: true });
|
|
349
|
+
element.addEventListener('scrollend', onScrollEnd);
|
|
350
|
+
const root = interactionRoot();
|
|
351
|
+
root.addEventListener('pointerenter', onPointerEnter);
|
|
352
|
+
root.addEventListener('pointermove', onPointerMove);
|
|
353
|
+
root.addEventListener('pointerleave', onPointerLeave);
|
|
354
|
+
this.bindRailInteraction(element);
|
|
355
|
+
this.resizeObserver = new ResizeObserver(() => this.remeasureCustomThumb());
|
|
356
|
+
this.resizeObserver.observe(element);
|
|
357
|
+
this.observeHostDesignTokenChanges(element);
|
|
358
|
+
this.queueDesignTokenSync();
|
|
359
|
+
this.remeasureCustomThumb();
|
|
360
|
+
this.destroyRef.onDestroy(() => {
|
|
361
|
+
this.clearHideTimer();
|
|
362
|
+
this.clearTrackPressed();
|
|
363
|
+
this.unbindRailInteraction?.();
|
|
364
|
+
this.unbindRailInteraction = null;
|
|
365
|
+
if (this.thumbEl && this.thumbDragPointerId !== null) {
|
|
366
|
+
try {
|
|
367
|
+
this.thumbEl.releasePointerCapture(this.thumbDragPointerId);
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
/* already released */
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
this.thumbDragPointerId = null;
|
|
374
|
+
this.resizeObserver?.disconnect();
|
|
375
|
+
this.resizeObserver = null;
|
|
376
|
+
this.designTokenMutationObserver?.disconnect();
|
|
377
|
+
this.designTokenMutationObserver = null;
|
|
378
|
+
if (this.designTokenSyncFrame !== null) {
|
|
379
|
+
cancelAnimationFrame(this.designTokenSyncFrame);
|
|
380
|
+
this.designTokenSyncFrame = null;
|
|
381
|
+
}
|
|
382
|
+
element.removeEventListener('scroll', onScroll);
|
|
383
|
+
element.removeEventListener('scrollend', onScrollEnd);
|
|
384
|
+
root.removeEventListener('pointerenter', onPointerEnter);
|
|
385
|
+
root.removeEventListener('pointermove', onPointerMove);
|
|
386
|
+
root.removeEventListener('pointerleave', onPointerLeave);
|
|
387
|
+
this.unmountCustomScrollbar(element);
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
/** Host and rail are siblings under the root; mirror CSS variables when the host style/class changes. */
|
|
392
|
+
observeHostDesignTokenChanges(host) {
|
|
393
|
+
this.designTokenMutationObserver?.disconnect();
|
|
394
|
+
this.designTokenMutationObserver = new MutationObserver(() => this.queueDesignTokenSync());
|
|
395
|
+
this.designTokenMutationObserver.observe(host, {
|
|
396
|
+
attributes: true,
|
|
397
|
+
attributeFilter: ['style', 'class'],
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
queueDesignTokenSync() {
|
|
401
|
+
if (!isPlatformBrowser(this.platformId)) {
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (this.designTokenSyncFrame !== null) {
|
|
405
|
+
cancelAnimationFrame(this.designTokenSyncFrame);
|
|
406
|
+
}
|
|
407
|
+
this.designTokenSyncFrame = requestAnimationFrame(() => {
|
|
408
|
+
this.designTokenSyncFrame = null;
|
|
409
|
+
syncOverlayScrollbarDesignTokens(this.host.nativeElement, this.rootEl);
|
|
410
|
+
this.remeasureCustomThumb();
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
/** Rail lives on a wrapper so it stays fixed while the host scrolls. */
|
|
414
|
+
ensureScrollRoot(scroller) {
|
|
415
|
+
const parent = scroller.parentElement;
|
|
416
|
+
if (parent?.classList.contains(ROOT_CLASS)) {
|
|
417
|
+
this.rootEl = parent;
|
|
418
|
+
return parent;
|
|
419
|
+
}
|
|
420
|
+
const root = this.document.createElement('div');
|
|
421
|
+
root.className = ROOT_CLASS;
|
|
422
|
+
parent?.insertBefore(root, scroller);
|
|
423
|
+
root.appendChild(scroller);
|
|
424
|
+
this.rootEl = root;
|
|
425
|
+
return root;
|
|
426
|
+
}
|
|
427
|
+
mountCustomScrollbar(element) {
|
|
428
|
+
const root = this.ensureScrollRoot(element);
|
|
429
|
+
const existingRail = root.querySelector(`.${RAIL_CLASS}`);
|
|
430
|
+
if (existingRail) {
|
|
431
|
+
this.railEl = existingRail;
|
|
432
|
+
this.ensureRailStructure(existingRail);
|
|
433
|
+
this.bindRailInteraction(element);
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const rail = this.document.createElement('div');
|
|
437
|
+
rail.className = RAIL_CLASS;
|
|
438
|
+
rail.setAttribute('aria-hidden', 'true');
|
|
439
|
+
this.ensureRailStructure(rail);
|
|
440
|
+
root.appendChild(rail);
|
|
441
|
+
this.railEl = rail;
|
|
442
|
+
this.bindRailInteraction(element);
|
|
443
|
+
}
|
|
444
|
+
ensureRailStructure(rail) {
|
|
445
|
+
let thumb = rail.querySelector(`.${THUMB_CLASS}`);
|
|
446
|
+
if (!thumb) {
|
|
447
|
+
thumb = this.document.createElement('div');
|
|
448
|
+
thumb.className = THUMB_CLASS;
|
|
449
|
+
thumb.addEventListener('pointerdown', (event) => this.onThumbPointerDown(event));
|
|
450
|
+
}
|
|
451
|
+
let track = rail.querySelector(`.${TRACK_CLASS}`);
|
|
452
|
+
if (!track) {
|
|
453
|
+
const navUp = this.createNavButton('up');
|
|
454
|
+
const navDown = this.createNavButton('down');
|
|
455
|
+
track = this.document.createElement('div');
|
|
456
|
+
track.className = TRACK_CLASS;
|
|
457
|
+
rail.replaceChildren(navUp, track, navDown);
|
|
458
|
+
track.appendChild(thumb);
|
|
459
|
+
this.navUpEl = navUp;
|
|
460
|
+
this.navDownEl = navDown;
|
|
461
|
+
}
|
|
462
|
+
else if (!track.contains(thumb)) {
|
|
463
|
+
track.appendChild(thumb);
|
|
464
|
+
this.navUpEl = rail.querySelector(`.${NAV_BTN_CLASS}--up`);
|
|
465
|
+
this.navDownEl = rail.querySelector(`.${NAV_BTN_CLASS}--down`);
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
this.navUpEl = rail.querySelector(`.${NAV_BTN_CLASS}--up`);
|
|
469
|
+
this.navDownEl = rail.querySelector(`.${NAV_BTN_CLASS}--down`);
|
|
470
|
+
}
|
|
471
|
+
this.trackEl = track;
|
|
472
|
+
this.thumbEl = thumb;
|
|
473
|
+
}
|
|
474
|
+
createNavButton(direction) {
|
|
475
|
+
const button = this.document.createElement('button');
|
|
476
|
+
button.type = 'button';
|
|
477
|
+
button.className = `${NAV_BTN_CLASS} ${NAV_BTN_CLASS}--${direction}`;
|
|
478
|
+
button.setAttribute('aria-label', direction === 'up' ? 'Scroll up' : 'Scroll down');
|
|
479
|
+
const arrow = this.document.createElement('span');
|
|
480
|
+
arrow.className = `${NAV_ARROW_CLASS} ${NAV_ARROW_CLASS}--${direction}`;
|
|
481
|
+
arrow.setAttribute('aria-hidden', 'true');
|
|
482
|
+
button.appendChild(arrow);
|
|
483
|
+
return button;
|
|
484
|
+
}
|
|
485
|
+
resolveNavScrollStepPx() {
|
|
486
|
+
const step = this.navScrollStep();
|
|
487
|
+
if (Number.isFinite(step) && step > 0) {
|
|
488
|
+
return Math.round(step);
|
|
489
|
+
}
|
|
490
|
+
return DEFAULT_NAV_SCROLL_STEP_PX;
|
|
491
|
+
}
|
|
492
|
+
scrollByNavStep(scroller, direction) {
|
|
493
|
+
scroller.scrollTop += direction * this.resolveNavScrollStepPx();
|
|
494
|
+
this.syncThumbPosition();
|
|
495
|
+
this.bumpVisibility();
|
|
496
|
+
}
|
|
497
|
+
bindRailInteraction(scroller) {
|
|
498
|
+
const rail = this.railEl;
|
|
499
|
+
if (!rail) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
this.unbindRailInteraction?.();
|
|
503
|
+
const onRailPointerEnter = () => {
|
|
504
|
+
this.pointerOverRail = true;
|
|
505
|
+
this.showScrollbar();
|
|
506
|
+
this.clearHideTimer();
|
|
507
|
+
};
|
|
508
|
+
const onRailPointerLeave = () => {
|
|
509
|
+
this.pointerOverRail = false;
|
|
510
|
+
this.clearTrackPressed();
|
|
511
|
+
this.syncEngagedAfterScroll();
|
|
512
|
+
this.scheduleHide();
|
|
513
|
+
};
|
|
514
|
+
const onRailWheel = (event) => {
|
|
515
|
+
event.preventDefault();
|
|
516
|
+
event.stopPropagation();
|
|
517
|
+
scroller.scrollTop += event.deltaY;
|
|
518
|
+
this.bumpVisibility();
|
|
519
|
+
};
|
|
520
|
+
const onRailPointerDown = (event) => {
|
|
521
|
+
const thumb = this.thumbEl;
|
|
522
|
+
const target = event.target;
|
|
523
|
+
if (thumb && (event.target === thumb || thumb.contains(target))) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
if (this.navUpEl?.contains(target) ||
|
|
527
|
+
this.navDownEl?.contains(target) ||
|
|
528
|
+
event.target === this.navUpEl ||
|
|
529
|
+
event.target === this.navDownEl) {
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
const track = this.trackEl;
|
|
533
|
+
if (!track || (event.target !== track && !track.contains(target))) {
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
if (this.isPointerOverThumbVisual(event.clientX, event.clientY)) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
event.preventDefault();
|
|
540
|
+
this.beginTrackPressed();
|
|
541
|
+
this.jumpScrollToTrackPointer(event, scroller);
|
|
542
|
+
};
|
|
543
|
+
const bindNavButton = (button, direction) => {
|
|
544
|
+
if (!button) {
|
|
545
|
+
return () => undefined;
|
|
546
|
+
}
|
|
547
|
+
const onNavPointerLeave = () => {
|
|
548
|
+
button.classList.remove(NAV_BTN_PRESSED_CLASS);
|
|
549
|
+
};
|
|
550
|
+
const onNavPointerDown = (event) => {
|
|
551
|
+
event.preventDefault();
|
|
552
|
+
event.stopPropagation();
|
|
553
|
+
button.classList.add(NAV_BTN_PRESSED_CLASS);
|
|
554
|
+
this.beginTrackPressed();
|
|
555
|
+
this.scrollByNavStep(scroller, direction);
|
|
556
|
+
};
|
|
557
|
+
const onNavPointerUp = () => {
|
|
558
|
+
button.classList.remove(NAV_BTN_PRESSED_CLASS);
|
|
559
|
+
};
|
|
560
|
+
button.addEventListener('pointerleave', onNavPointerLeave);
|
|
561
|
+
button.addEventListener('pointerdown', onNavPointerDown);
|
|
562
|
+
button.addEventListener('pointerup', onNavPointerUp);
|
|
563
|
+
button.addEventListener('pointercancel', onNavPointerUp);
|
|
564
|
+
return () => {
|
|
565
|
+
button.removeEventListener('pointerleave', onNavPointerLeave);
|
|
566
|
+
button.removeEventListener('pointerdown', onNavPointerDown);
|
|
567
|
+
button.removeEventListener('pointerup', onNavPointerUp);
|
|
568
|
+
button.removeEventListener('pointercancel', onNavPointerUp);
|
|
569
|
+
button.classList.remove(NAV_BTN_PRESSED_CLASS);
|
|
570
|
+
};
|
|
571
|
+
};
|
|
572
|
+
const unbindNavUp = bindNavButton(this.navUpEl, -1);
|
|
573
|
+
const unbindNavDown = bindNavButton(this.navDownEl, 1);
|
|
574
|
+
rail.addEventListener('pointerenter', onRailPointerEnter);
|
|
575
|
+
rail.addEventListener('pointerleave', onRailPointerLeave);
|
|
576
|
+
rail.addEventListener('wheel', onRailWheel, { passive: false });
|
|
577
|
+
rail.addEventListener('pointerdown', onRailPointerDown);
|
|
578
|
+
this.unbindRailInteraction = () => {
|
|
579
|
+
rail.removeEventListener('pointerenter', onRailPointerEnter);
|
|
580
|
+
rail.removeEventListener('pointerleave', onRailPointerLeave);
|
|
581
|
+
this.clearTrackPressed();
|
|
582
|
+
rail.removeEventListener('wheel', onRailWheel);
|
|
583
|
+
rail.removeEventListener('pointerdown', onRailPointerDown);
|
|
584
|
+
unbindNavUp?.();
|
|
585
|
+
unbindNavDown?.();
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
unmountCustomScrollbar(scroller) {
|
|
589
|
+
this.railEl?.remove();
|
|
590
|
+
this.railEl = null;
|
|
591
|
+
this.trackEl = null;
|
|
592
|
+
this.navUpEl = null;
|
|
593
|
+
this.navDownEl = null;
|
|
594
|
+
this.thumbEl = null;
|
|
595
|
+
this.thumbLayout = null;
|
|
596
|
+
const root = this.rootEl;
|
|
597
|
+
if (!root?.classList.contains(ROOT_CLASS)) {
|
|
598
|
+
this.rootEl = null;
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
const parent = root.parentElement;
|
|
602
|
+
if (parent) {
|
|
603
|
+
parent.insertBefore(scroller, root);
|
|
604
|
+
root.remove();
|
|
605
|
+
}
|
|
606
|
+
this.rootEl = null;
|
|
607
|
+
}
|
|
608
|
+
remeasureCustomThumb() {
|
|
609
|
+
const element = this.host.nativeElement;
|
|
610
|
+
const rail = this.railEl;
|
|
611
|
+
const thumb = this.thumbEl;
|
|
612
|
+
if (!rail || !thumb) {
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
syncOverlayScrollbarDesignTokens(element, this.rootEl);
|
|
616
|
+
const clientHeight = element.clientHeight;
|
|
617
|
+
rail.style.height = `${clientHeight}px`;
|
|
618
|
+
const widthPx = readRailWidthPx(rail);
|
|
619
|
+
const navigationEnabled = this.navigationButtons() === true;
|
|
620
|
+
rail.classList.toggle(RAIL_WITH_NAV_CLASS, navigationEnabled);
|
|
621
|
+
const track = this.trackEl;
|
|
622
|
+
let trackViewportHeight = track?.clientHeight ?? 0;
|
|
623
|
+
if (trackViewportHeight <= 0) {
|
|
624
|
+
trackViewportHeight = navigationEnabled ? Math.max(0, clientHeight - 2 * widthPx) : clientHeight;
|
|
625
|
+
}
|
|
626
|
+
const scrollHeight = element.scrollHeight;
|
|
627
|
+
const isScrollable = scrollHeight > clientHeight + 1;
|
|
628
|
+
rail.hidden = !isScrollable;
|
|
629
|
+
if (!isScrollable) {
|
|
630
|
+
this.thumbLayout = null;
|
|
631
|
+
thumb.style.height = '';
|
|
632
|
+
thumb.style.top = '';
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
const thumbHeight = Math.max(MIN_THUMB_HEIGHT_PX, (trackViewportHeight / scrollHeight) * trackViewportHeight);
|
|
636
|
+
const maxScroll = scrollHeight - clientHeight;
|
|
637
|
+
const maxThumbOffset = Math.max(0, trackViewportHeight - thumbHeight);
|
|
638
|
+
this.thumbLayout = { thumbHeight, maxScroll, maxThumbOffset };
|
|
639
|
+
thumb.style.height = `${thumbHeight}px`;
|
|
640
|
+
this.syncThumbPosition();
|
|
641
|
+
}
|
|
642
|
+
syncThumbPosition() {
|
|
643
|
+
const element = this.host.nativeElement;
|
|
644
|
+
const thumb = this.thumbEl;
|
|
645
|
+
const layout = this.thumbLayout;
|
|
646
|
+
if (!thumb || !layout) {
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
const { maxScroll, maxThumbOffset } = layout;
|
|
650
|
+
const scrollTop = element.scrollTop;
|
|
651
|
+
const thumbOffset = maxScroll > 0 ? (scrollTop / maxScroll) * maxThumbOffset : 0;
|
|
652
|
+
thumb.style.top = `${thumbOffset}px`;
|
|
653
|
+
}
|
|
654
|
+
/** Move thumb (and scroll position) to the pointer Y on the track. */
|
|
655
|
+
jumpScrollToTrackPointer(event, scroller) {
|
|
656
|
+
const rail = this.railEl;
|
|
657
|
+
const layout = this.thumbLayout;
|
|
658
|
+
if (!rail || !layout || layout.maxScroll <= 0 || layout.maxThumbOffset <= 0) {
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
const track = this.trackEl ?? rail;
|
|
662
|
+
const rect = track.getBoundingClientRect();
|
|
663
|
+
const offsetY = event.clientY - rect.top;
|
|
664
|
+
const thumbTop = Math.min(layout.maxThumbOffset, Math.max(0, offsetY - layout.thumbHeight / 2));
|
|
665
|
+
scroller.scrollTop = (thumbTop / layout.maxThumbOffset) * layout.maxScroll;
|
|
666
|
+
this.syncThumbPosition();
|
|
667
|
+
this.bumpVisibility();
|
|
668
|
+
}
|
|
669
|
+
onThumbPointerDown(event) {
|
|
670
|
+
event.preventDefault();
|
|
671
|
+
event.stopPropagation();
|
|
672
|
+
const element = this.host.nativeElement;
|
|
673
|
+
const thumb = this.thumbEl;
|
|
674
|
+
if (!thumb) {
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
this.setScrollbarEngaged(true);
|
|
678
|
+
this.bumpVisibility();
|
|
679
|
+
thumb.setPointerCapture(event.pointerId);
|
|
680
|
+
const startY = event.clientY;
|
|
681
|
+
const startScrollTop = element.scrollTop;
|
|
682
|
+
const layout = this.thumbLayout;
|
|
683
|
+
const clientHeight = element.clientHeight;
|
|
684
|
+
const maxScroll = layout?.maxScroll ?? element.scrollHeight - clientHeight;
|
|
685
|
+
const maxThumbOffset = layout?.maxThumbOffset ?? clientHeight - thumb.offsetHeight;
|
|
686
|
+
const onPointerMove = (moveEvent) => {
|
|
687
|
+
if (maxThumbOffset <= 0 || maxScroll <= 0) {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
const deltaY = moveEvent.clientY - startY;
|
|
691
|
+
const scrollDelta = (deltaY / maxThumbOffset) * maxScroll;
|
|
692
|
+
element.scrollTop = startScrollTop + scrollDelta;
|
|
693
|
+
};
|
|
694
|
+
const onPointerUp = (upEvent) => {
|
|
695
|
+
thumb.releasePointerCapture(upEvent.pointerId);
|
|
696
|
+
thumb.removeEventListener('pointermove', onPointerMove);
|
|
697
|
+
thumb.removeEventListener('pointerup', onPointerUp);
|
|
698
|
+
thumb.removeEventListener('pointercancel', onPointerUp);
|
|
699
|
+
this.thumbDragPointerId = null;
|
|
700
|
+
this.setScrollbarEngaged(false);
|
|
701
|
+
};
|
|
702
|
+
this.thumbDragPointerId = event.pointerId;
|
|
703
|
+
thumb.addEventListener('pointermove', onPointerMove);
|
|
704
|
+
thumb.addEventListener('pointerup', onPointerUp);
|
|
705
|
+
thumb.addEventListener('pointercancel', onPointerUp);
|
|
706
|
+
}
|
|
707
|
+
showScrollbar() {
|
|
708
|
+
this.host.nativeElement.classList.add(VISIBLE_CLASS);
|
|
709
|
+
this.rootEl?.classList.add(VISIBLE_CLASS);
|
|
710
|
+
}
|
|
711
|
+
bumpVisibility() {
|
|
712
|
+
this.showScrollbar();
|
|
713
|
+
if (this.pointerOverRail) {
|
|
714
|
+
this.clearHideTimer();
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
this.scheduleHide();
|
|
718
|
+
}
|
|
719
|
+
deactivateThumb() {
|
|
720
|
+
if (this.pointerOverRail) {
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
this.clearHideTimer();
|
|
724
|
+
this.host.nativeElement.classList.remove(VISIBLE_CLASS);
|
|
725
|
+
this.rootEl?.classList.remove(VISIBLE_CLASS);
|
|
726
|
+
this.setScrollbarEngaged(false);
|
|
727
|
+
}
|
|
728
|
+
setScrollbarEngaged(engaged) {
|
|
729
|
+
this.host.nativeElement.classList.toggle(ENGAGED_CLASS, engaged);
|
|
730
|
+
this.rootEl?.classList.toggle(ENGAGED_CLASS, engaged);
|
|
731
|
+
}
|
|
732
|
+
setTrackPressed(pressed) {
|
|
733
|
+
this.host.nativeElement.classList.toggle(TRACK_PRESSED_CLASS, pressed);
|
|
734
|
+
this.rootEl?.classList.toggle(TRACK_PRESSED_CLASS, pressed);
|
|
735
|
+
}
|
|
736
|
+
isPointerOverThumbVisual(clientX, clientY) {
|
|
737
|
+
const thumb = this.thumbEl;
|
|
738
|
+
if (!thumb) {
|
|
739
|
+
return false;
|
|
740
|
+
}
|
|
741
|
+
const rect = thumb.getBoundingClientRect();
|
|
742
|
+
return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
|
|
743
|
+
}
|
|
744
|
+
beginTrackPressed() {
|
|
745
|
+
this.clearTrackPressed();
|
|
746
|
+
this.setTrackPressed(true);
|
|
747
|
+
const release = () => {
|
|
748
|
+
this.setTrackPressed(false);
|
|
749
|
+
this.document.removeEventListener('pointerup', release);
|
|
750
|
+
this.document.removeEventListener('pointercancel', release);
|
|
751
|
+
this.trackPressReleaseListener = null;
|
|
752
|
+
};
|
|
753
|
+
this.trackPressReleaseListener = release;
|
|
754
|
+
this.document.addEventListener('pointerup', release);
|
|
755
|
+
this.document.addEventListener('pointercancel', release);
|
|
756
|
+
}
|
|
757
|
+
clearTrackPressed() {
|
|
758
|
+
if (this.trackPressReleaseListener) {
|
|
759
|
+
this.document.removeEventListener('pointerup', this.trackPressReleaseListener);
|
|
760
|
+
this.document.removeEventListener('pointercancel', this.trackPressReleaseListener);
|
|
761
|
+
this.trackPressReleaseListener = null;
|
|
762
|
+
}
|
|
763
|
+
this.setTrackPressed(false);
|
|
764
|
+
}
|
|
765
|
+
syncEngagedAfterScroll() {
|
|
766
|
+
if (this.thumbDragPointerId !== null) {
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
this.setScrollbarEngaged(false);
|
|
770
|
+
}
|
|
771
|
+
scheduleHide() {
|
|
772
|
+
if (this.pointerOverRail) {
|
|
773
|
+
this.clearHideTimer();
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
this.clearHideTimer();
|
|
777
|
+
const delay = Math.max(0, this.hideDelay());
|
|
778
|
+
this.hideTimer = setTimeout(() => {
|
|
779
|
+
this.deactivateThumb();
|
|
780
|
+
this.hideTimer = null;
|
|
781
|
+
}, delay);
|
|
782
|
+
}
|
|
783
|
+
clearHideTimer() {
|
|
784
|
+
if (this.hideTimer !== null) {
|
|
785
|
+
clearTimeout(this.hideTimer);
|
|
786
|
+
this.hideTimer = null;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXOverlayScrollbarDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
790
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: AXOverlayScrollbarDirective, isStandalone: true, selector: "[axOverlayScrollbar]", inputs: { hideDelay: { classPropertyName: "hideDelay", publicName: "hideDelay", isSignal: true, isRequired: false, transformFunction: null }, navigationButtons: { classPropertyName: "navigationButtons", publicName: "navigationButtons", isSignal: true, isRequired: false, transformFunction: null }, navScrollStep: { classPropertyName: "navScrollStep", publicName: "navScrollStep", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ax-cdk-overlay-scrollbar" }, exportAs: ["axOverlayScrollbar"], ngImport: i0 }); }
|
|
791
|
+
}
|
|
792
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXOverlayScrollbarDirective, decorators: [{
|
|
793
|
+
type: Directive,
|
|
794
|
+
args: [{
|
|
795
|
+
selector: '[axOverlayScrollbar]',
|
|
796
|
+
exportAs: 'axOverlayScrollbar',
|
|
797
|
+
host: {
|
|
798
|
+
class: 'ax-cdk-overlay-scrollbar',
|
|
799
|
+
},
|
|
800
|
+
}]
|
|
801
|
+
}], ctorParameters: () => [], propDecorators: { hideDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideDelay", required: false }] }], navigationButtons: [{ type: i0.Input, args: [{ isSignal: true, alias: "navigationButtons", required: false }] }], navScrollStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "navScrollStep", required: false }] }] } });
|
|
802
|
+
|
|
803
|
+
/**
|
|
804
|
+
* Generated bundle index. Do not edit.
|
|
805
|
+
*/
|
|
806
|
+
|
|
807
|
+
export { AXOverlayScrollbarDirective, AX_OVERLAY_SCROLLBAR_CSS_VARS, clampOverlayScrollbarWidth };
|
|
808
|
+
//# sourceMappingURL=acorex-cdk-overlay-scrollbar.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acorex-cdk-overlay-scrollbar.mjs","sources":["../../../../packages/cdk/overlay-scrollbar/src/lib/overlay-scrollbar.directive.ts","../../../../packages/cdk/overlay-scrollbar/src/acorex-cdk-overlay-scrollbar.ts"],"sourcesContent":["import { DOCUMENT, isPlatformBrowser } from '@angular/common';\n\nimport {\n afterNextRender,\n afterRenderEffect,\n DestroyRef,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n PLATFORM_ID,\n} from '@angular/core';\n\n/** CSS custom properties for overlay scrollbar styling (set on the scroll host or in CSS). */\nexport const AX_OVERLAY_SCROLLBAR_CSS_VARS = {\n size: '--ax-comp-overlay-scrollbar-size',\n thumbRadius: '--ax-comp-overlay-scrollbar-thumb-radius',\n trackRadius: '--ax-comp-overlay-scrollbar-track-radius',\n trackColor: '--ax-comp-overlay-scrollbar-track-color',\n thumbColor: '--ax-comp-overlay-scrollbar-thumb-color',\n thumbActiveColor: '--ax-comp-overlay-scrollbar-thumb-active-color',\n thumbHoverColor: '--ax-comp-overlay-scrollbar-thumb-hover-color',\n trackActiveColor: '--ax-comp-overlay-scrollbar-track-active-color',\n thumbBorderWidth: '--ax-comp-overlay-scrollbar-thumb-border-width',\n thumbBorderColor: '--ax-comp-overlay-scrollbar-thumb-border-color',\n trackBorderWidth: '--ax-comp-overlay-scrollbar-track-border-width',\n trackBorderColor: '--ax-comp-overlay-scrollbar-track-border-color',\n fadeDuration: '--ax-comp-overlay-scrollbar-fade-duration',\n} as const;\n\nconst OVERLAY_SCROLLBAR_TOKEN_NAMES = Object.values(AX_OVERLAY_SCROLLBAR_CSS_VARS);\n\nconst ROOT_CLASS = 'ax-cdk-overlay-scrollbar-root';\nconst RAIL_CLASS = 'ax-cdk-overlay-scrollbar__rail';\nconst TRACK_CLASS = 'ax-cdk-overlay-scrollbar__rail-track';\nconst THUMB_CLASS = 'ax-cdk-overlay-scrollbar__rail-thumb';\nconst NAV_BTN_CLASS = 'ax-cdk-overlay-scrollbar__nav-button';\nconst NAV_BTN_PRESSED_CLASS = 'ax-cdk-overlay-scrollbar__nav-button--pressed';\nconst NAV_ARROW_CLASS = 'ax-cdk-overlay-scrollbar__nav-arrow';\nconst RAIL_WITH_NAV_CLASS = 'ax-cdk-overlay-scrollbar__rail--with-nav';\nconst VISIBLE_CLASS = 'ax-cdk-overlay-scrollbar--active';\n/** Applied while dragging the thumb (active fill; not used during wheel/content scroll). */\nconst ENGAGED_CLASS = 'ax-cdk-overlay-scrollbar--engaged';\n/** Primary button down on the track (outside thumb); `:active` is unreliable with `preventDefault`. */\nconst TRACK_PRESSED_CLASS = 'ax-cdk-overlay-scrollbar--track-pressed';\n\nconst OVERLAY_SCROLLBAR_STYLES = `\n.ax-cdk-overlay-scrollbar-root {\n position: relative;\n display: block;\n min-height: 0;\n --ax-comp-overlay-scrollbar-size: 6px;\n --ax-comp-overlay-scrollbar-fade-duration: 0.35s;\n --ax-comp-overlay-scrollbar-thumb-radius: 4px;\n --ax-comp-overlay-scrollbar-track-radius: 4px;\n --ax-comp-overlay-scrollbar-track-color: transparent;\n --ax-comp-overlay-scrollbar-thumb-color: var(--ax-sys-scroller-thumb-color, #64748b);\n --ax-comp-overlay-scrollbar-thumb-border-width: 0;\n --ax-comp-overlay-scrollbar-thumb-border-color: transparent;\n --ax-comp-overlay-scrollbar-track-border-width: 0;\n --ax-comp-overlay-scrollbar-track-border-color: transparent;\n}\n\n.ax-cdk-overlay-scrollbar {\n position: relative;\n --ax-comp-overlay-scrollbar-size: 6px;\n --ax-comp-overlay-scrollbar-fade-duration: 0.35s;\n --ax-comp-overlay-scrollbar-thumb-radius: 4px;\n --ax-comp-overlay-scrollbar-track-radius: 4px;\n --ax-comp-overlay-scrollbar-track-color: transparent;\n --ax-comp-overlay-scrollbar-thumb-color: var(--ax-sys-scroller-thumb-color, #64748b);\n --ax-comp-overlay-scrollbar-thumb-border-width: 0;\n --ax-comp-overlay-scrollbar-thumb-border-color: transparent;\n --ax-comp-overlay-scrollbar-track-border-width: 0;\n --ax-comp-overlay-scrollbar-track-border-color: transparent;\n\n scrollbar-width: none !important;\n -ms-overflow-style: none;\n}\n\n.ax-cdk-overlay-scrollbar::-webkit-scrollbar {\n display: none !important;\n width: 0 !important;\n height: 0 !important;\n background: transparent !important;\n}\n\n.ax-cdk-overlay-scrollbar__rail {\n position: absolute;\n top: 0;\n bottom: 0;\n inset-inline-end: 0;\n width: var(--ax-comp-overlay-scrollbar-size, 6px);\n overflow: hidden;\n pointer-events: auto;\n opacity: 0;\n z-index: 10;\n box-sizing: border-box;\n border-radius: var(--ax-comp-overlay-scrollbar-track-radius, 4px);\n background-color: var(--ax-comp-overlay-scrollbar-track-color, transparent);\n border-width: var(--ax-comp-overlay-scrollbar-track-border-width, 0);\n border-style: solid;\n border-color: var(--ax-comp-overlay-scrollbar-track-border-color, transparent);\n transition:\n opacity var(--ax-comp-overlay-scrollbar-fade-duration, 0.35s) ease,\n background-color 0.15s ease;\n}\n\n.ax-cdk-overlay-scrollbar-root.ax-cdk-overlay-scrollbar--active .ax-cdk-overlay-scrollbar__rail,\n.ax-cdk-overlay-scrollbar.ax-cdk-overlay-scrollbar--active .ax-cdk-overlay-scrollbar__rail {\n opacity: 1;\n}\n\n.ax-cdk-overlay-scrollbar__rail-track {\n position: absolute;\n inset: 0;\n box-sizing: border-box;\n}\n\n.ax-cdk-overlay-scrollbar-root.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--track-pressed\n .ax-cdk-overlay-scrollbar__rail,\n.ax-cdk-overlay-scrollbar.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--track-pressed\n .ax-cdk-overlay-scrollbar__rail,\n.ax-cdk-overlay-scrollbar-root.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--engaged\n .ax-cdk-overlay-scrollbar__rail,\n.ax-cdk-overlay-scrollbar.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--engaged\n .ax-cdk-overlay-scrollbar__rail {\n background-color: var(\n --ax-comp-overlay-scrollbar-track-active-color,\n var(--ax-comp-overlay-scrollbar-track-color, transparent)\n );\n}\n\n.ax-cdk-overlay-scrollbar__rail--with-nav {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.ax-cdk-overlay-scrollbar__rail--with-nav .ax-cdk-overlay-scrollbar__rail-track {\n position: relative;\n flex: 1 1 auto;\n min-height: 0;\n inset: auto;\n}\n\n.ax-cdk-overlay-scrollbar__nav-button {\n display: none;\n flex: 0 0 var(--ax-comp-overlay-scrollbar-size, 6px);\n width: 100%;\n min-height: var(--ax-comp-overlay-scrollbar-size, 6px);\n margin: 0;\n padding: 0;\n border: none;\n box-sizing: border-box;\n cursor: default;\n align-items: center;\n justify-content: center;\n background-color: transparent;\n color: var(--ax-comp-overlay-scrollbar-thumb-color, var(--ax-sys-scroller-thumb-color, #64748b));\n}\n\n.ax-cdk-overlay-scrollbar__rail--with-nav .ax-cdk-overlay-scrollbar__nav-button {\n display: flex;\n}\n\n.ax-cdk-overlay-scrollbar__nav-arrow {\n width: 0;\n height: 0;\n border-left: 3px solid transparent;\n border-right: 3px solid transparent;\n pointer-events: none;\n}\n\n.ax-cdk-overlay-scrollbar__nav-arrow--up {\n border-bottom: 4px solid currentColor;\n}\n\n.ax-cdk-overlay-scrollbar__nav-arrow--down {\n border-top: 4px solid currentColor;\n}\n\n.ax-cdk-overlay-scrollbar__rail-thumb {\n position: absolute;\n top: 0;\n inset-inline-start: 0;\n width: 100%;\n box-sizing: border-box;\n border-radius: var(--ax-comp-overlay-scrollbar-thumb-radius, 4px);\n background-color: var(--ax-comp-overlay-scrollbar-thumb-color, var(--ax-sys-scroller-thumb-color, #64748b));\n border-width: var(--ax-comp-overlay-scrollbar-thumb-border-width, 0);\n border-style: solid;\n border-color: var(--ax-comp-overlay-scrollbar-thumb-border-color, transparent);\n transition: background-color 0.15s ease;\n pointer-events: auto;\n touch-action: none;\n}\n\n.ax-cdk-overlay-scrollbar__rail-thumb::before {\n content: '';\n position: absolute;\n inset: -4px -8px;\n}\n\n.ax-cdk-overlay-scrollbar-root.ax-cdk-overlay-scrollbar--active .ax-cdk-overlay-scrollbar__rail-thumb:hover,\n.ax-cdk-overlay-scrollbar.ax-cdk-overlay-scrollbar--active .ax-cdk-overlay-scrollbar__rail-thumb:hover {\n background-color: var(\n --ax-comp-overlay-scrollbar-thumb-hover-color,\n var(\n --ax-comp-overlay-scrollbar-thumb-active-color,\n var(--ax-comp-overlay-scrollbar-thumb-color, var(--ax-sys-scroller-thumb-color, #64748b))\n )\n );\n}\n\n.ax-cdk-overlay-scrollbar-root.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--engaged\n .ax-cdk-overlay-scrollbar__rail-thumb,\n.ax-cdk-overlay-scrollbar.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--engaged\n .ax-cdk-overlay-scrollbar__rail-thumb,\n.ax-cdk-overlay-scrollbar-root.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--engaged\n .ax-cdk-overlay-scrollbar__rail-thumb:hover,\n.ax-cdk-overlay-scrollbar.ax-cdk-overlay-scrollbar--active.ax-cdk-overlay-scrollbar--engaged\n .ax-cdk-overlay-scrollbar__rail-thumb:hover {\n background-color: var(\n --ax-comp-overlay-scrollbar-thumb-active-color,\n var(--ax-comp-overlay-scrollbar-thumb-color, var(--ax-sys-scroller-thumb-color, #64748b))\n );\n}\n`.trim();\n\nconst STYLE_ELEMENT_ID = 'ax-overlay-scrollbar-styles';\nconst DEFAULT_HIDE_DELAY_MS = 800;\nconst MIN_SCROLLBAR_WIDTH_PX = 2;\nconst MAX_SCROLLBAR_WIDTH_PX = 32;\nconst DEFAULT_SCROLLBAR_WIDTH_PX = 6;\nconst MIN_THUMB_HEIGHT_PX = 20;\nconst DEFAULT_NAV_SCROLL_STEP_PX = 40;\n\nexport function clampOverlayScrollbarWidth(px: number): number {\n if (!Number.isFinite(px)) {\n return DEFAULT_SCROLLBAR_WIDTH_PX;\n }\n return Math.min(MAX_SCROLLBAR_WIDTH_PX, Math.max(MIN_SCROLLBAR_WIDTH_PX, Math.round(px)));\n}\n\nfunction injectOverlayScrollbarStyles(document: Document): void {\n const existing = document.getElementById(STYLE_ELEMENT_ID);\n if (existing) {\n existing.textContent = OVERLAY_SCROLLBAR_STYLES;\n return;\n }\n\n const style = document.createElement('style');\n style.id = STYLE_ELEMENT_ID;\n style.textContent = OVERLAY_SCROLLBAR_STYLES;\n document.head.appendChild(style);\n}\n\n/** Rail is a sibling of the host; copy resolved tokens from the host so the rail can use them. */\nfunction syncOverlayScrollbarDesignTokens(host: HTMLElement, root: HTMLElement | null): void {\n if (!root) {\n return;\n }\n\n const computed = getComputedStyle(host);\n for (const varName of OVERLAY_SCROLLBAR_TOKEN_NAMES) {\n const value = computed.getPropertyValue(varName).trim();\n if (value) {\n root.style.setProperty(varName, value);\n } else {\n root.style.removeProperty(varName);\n }\n }\n}\n\nfunction readRailWidthPx(rail: HTMLElement): number {\n const width = rail.offsetWidth;\n if (width > 0) {\n return width;\n }\n const parsed = Number.parseFloat(getComputedStyle(rail).width);\n if (Number.isFinite(parsed) && parsed > 0) {\n return parsed;\n }\n const sizeToken = getComputedStyle(rail).getPropertyValue(AX_OVERLAY_SCROLLBAR_CSS_VARS.size).trim();\n const fromToken = Number.parseFloat(sizeToken);\n if (Number.isFinite(fromToken) && fromToken > 0) {\n return fromToken;\n }\n return DEFAULT_SCROLLBAR_WIDTH_PX;\n}\n\n/**\n * Custom overlay scrollbar: native scrollbars are hidden; a positioned thumb reflects scroll position.\n * Styles are injected once by this directive.\n */\n@Directive({\n selector: '[axOverlayScrollbar]',\n exportAs: 'axOverlayScrollbar',\n host: {\n class: 'ax-cdk-overlay-scrollbar',\n },\n})\nexport class AXOverlayScrollbarDirective {\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly platformId = inject(PLATFORM_ID);\n private readonly document = inject(DOCUMENT);\n\n private rootEl: HTMLElement | null = null;\n private railEl: HTMLElement | null = null;\n private trackEl: HTMLElement | null = null;\n private navUpEl: HTMLButtonElement | null = null;\n private navDownEl: HTMLButtonElement | null = null;\n private thumbEl: HTMLElement | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private designTokenMutationObserver: MutationObserver | null = null;\n private designTokenSyncFrame: number | null = null;\n private thumbDragPointerId: number | null = null;\n private pointerOverRail = false;\n private trackPressReleaseListener: (() => void) | null = null;\n private unbindRailInteraction: (() => void) | null = null;\n /** Thumb size derived from layout; position updates on scroll without re-measuring scrollHeight. */\n private thumbLayout: {\n thumbHeight: number;\n maxScroll: number;\n maxThumbOffset: number;\n } | null = null;\n\n readonly hideDelay = input(DEFAULT_HIDE_DELAY_MS);\n\n /**\n * When true, shows browser-style up/down arrow buttons on the rail.\n * Styling follows track/thumb CSS tokens.\n */\n readonly navigationButtons = input(false);\n\n /** Pixels to scroll per arrow click. */\n readonly navScrollStep = input(DEFAULT_NAV_SCROLL_STEP_PX);\n\n private hideTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n afterRenderEffect(() => {\n if (!isPlatformBrowser(this.platformId) || !this.rootEl) {\n return;\n }\n syncOverlayScrollbarDesignTokens(this.host.nativeElement, this.rootEl);\n });\n\n effect(() => {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n this.navigationButtons();\n this.remeasureCustomThumb();\n });\n\n afterNextRender(() => {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n\n injectOverlayScrollbarStyles(this.document);\n const element = this.host.nativeElement;\n this.mountCustomScrollbar(element);\n\n const interactionRoot = () => this.rootEl ?? element;\n\n const onScroll = () => {\n this.syncThumbPosition();\n this.bumpVisibility();\n };\n const onScrollEnd = () => {\n this.scheduleHide();\n this.syncEngagedAfterScroll();\n };\n const onPointerEnter = () => this.bumpVisibility();\n const onPointerMove = () => this.bumpVisibility();\n const onPointerLeave = () => {\n if (this.thumbDragPointerId === null) {\n this.setScrollbarEngaged(false);\n }\n this.deactivateThumb();\n };\n\n element.addEventListener('scroll', onScroll, { passive: true });\n element.addEventListener('scrollend', onScrollEnd);\n\n const root = interactionRoot();\n root.addEventListener('pointerenter', onPointerEnter);\n root.addEventListener('pointermove', onPointerMove);\n root.addEventListener('pointerleave', onPointerLeave);\n\n this.bindRailInteraction(element);\n\n this.resizeObserver = new ResizeObserver(() => this.remeasureCustomThumb());\n this.resizeObserver.observe(element);\n\n this.observeHostDesignTokenChanges(element);\n this.queueDesignTokenSync();\n this.remeasureCustomThumb();\n\n this.destroyRef.onDestroy(() => {\n this.clearHideTimer();\n this.clearTrackPressed();\n this.unbindRailInteraction?.();\n this.unbindRailInteraction = null;\n if (this.thumbEl && this.thumbDragPointerId !== null) {\n try {\n this.thumbEl.releasePointerCapture(this.thumbDragPointerId);\n } catch {\n /* already released */\n }\n }\n this.thumbDragPointerId = null;\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.designTokenMutationObserver?.disconnect();\n this.designTokenMutationObserver = null;\n if (this.designTokenSyncFrame !== null) {\n cancelAnimationFrame(this.designTokenSyncFrame);\n this.designTokenSyncFrame = null;\n }\n element.removeEventListener('scroll', onScroll);\n element.removeEventListener('scrollend', onScrollEnd);\n root.removeEventListener('pointerenter', onPointerEnter);\n root.removeEventListener('pointermove', onPointerMove);\n root.removeEventListener('pointerleave', onPointerLeave);\n this.unmountCustomScrollbar(element);\n });\n });\n }\n\n /** Host and rail are siblings under the root; mirror CSS variables when the host style/class changes. */\n private observeHostDesignTokenChanges(host: HTMLElement): void {\n this.designTokenMutationObserver?.disconnect();\n this.designTokenMutationObserver = new MutationObserver(() => this.queueDesignTokenSync());\n this.designTokenMutationObserver.observe(host, {\n attributes: true,\n attributeFilter: ['style', 'class'],\n });\n }\n\n private queueDesignTokenSync(): void {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n if (this.designTokenSyncFrame !== null) {\n cancelAnimationFrame(this.designTokenSyncFrame);\n }\n this.designTokenSyncFrame = requestAnimationFrame(() => {\n this.designTokenSyncFrame = null;\n syncOverlayScrollbarDesignTokens(this.host.nativeElement, this.rootEl);\n this.remeasureCustomThumb();\n });\n }\n\n /** Rail lives on a wrapper so it stays fixed while the host scrolls. */\n private ensureScrollRoot(scroller: HTMLElement): HTMLElement {\n const parent = scroller.parentElement;\n if (parent?.classList.contains(ROOT_CLASS)) {\n this.rootEl = parent;\n return parent;\n }\n\n const root = this.document.createElement('div');\n root.className = ROOT_CLASS;\n parent?.insertBefore(root, scroller);\n root.appendChild(scroller);\n this.rootEl = root;\n return root;\n }\n\n private mountCustomScrollbar(element: HTMLElement): void {\n const root = this.ensureScrollRoot(element);\n const existingRail = root.querySelector<HTMLElement>(`.${RAIL_CLASS}`);\n if (existingRail) {\n this.railEl = existingRail;\n this.ensureRailStructure(existingRail);\n this.bindRailInteraction(element);\n return;\n }\n\n const rail = this.document.createElement('div');\n rail.className = RAIL_CLASS;\n rail.setAttribute('aria-hidden', 'true');\n this.ensureRailStructure(rail);\n root.appendChild(rail);\n this.railEl = rail;\n this.bindRailInteraction(element);\n }\n\n private ensureRailStructure(rail: HTMLElement): void {\n let thumb = rail.querySelector<HTMLElement>(`.${THUMB_CLASS}`);\n if (!thumb) {\n thumb = this.document.createElement('div');\n thumb.className = THUMB_CLASS;\n thumb.addEventListener('pointerdown', (event) => this.onThumbPointerDown(event));\n }\n\n let track = rail.querySelector<HTMLElement>(`.${TRACK_CLASS}`);\n if (!track) {\n const navUp = this.createNavButton('up');\n const navDown = this.createNavButton('down');\n track = this.document.createElement('div');\n track.className = TRACK_CLASS;\n rail.replaceChildren(navUp, track, navDown);\n track.appendChild(thumb);\n this.navUpEl = navUp;\n this.navDownEl = navDown;\n } else if (!track.contains(thumb)) {\n track.appendChild(thumb);\n this.navUpEl = rail.querySelector<HTMLButtonElement>(`.${NAV_BTN_CLASS}--up`);\n this.navDownEl = rail.querySelector<HTMLButtonElement>(`.${NAV_BTN_CLASS}--down`);\n } else {\n this.navUpEl = rail.querySelector<HTMLButtonElement>(`.${NAV_BTN_CLASS}--up`);\n this.navDownEl = rail.querySelector<HTMLButtonElement>(`.${NAV_BTN_CLASS}--down`);\n }\n\n this.trackEl = track;\n this.thumbEl = thumb;\n }\n\n private createNavButton(direction: 'up' | 'down'): HTMLButtonElement {\n const button = this.document.createElement('button');\n button.type = 'button';\n button.className = `${NAV_BTN_CLASS} ${NAV_BTN_CLASS}--${direction}`;\n button.setAttribute('aria-label', direction === 'up' ? 'Scroll up' : 'Scroll down');\n\n const arrow = this.document.createElement('span');\n arrow.className = `${NAV_ARROW_CLASS} ${NAV_ARROW_CLASS}--${direction}`;\n arrow.setAttribute('aria-hidden', 'true');\n button.appendChild(arrow);\n return button;\n }\n\n private resolveNavScrollStepPx(): number {\n const step = this.navScrollStep();\n if (Number.isFinite(step) && step > 0) {\n return Math.round(step);\n }\n return DEFAULT_NAV_SCROLL_STEP_PX;\n }\n\n private scrollByNavStep(scroller: HTMLElement, direction: -1 | 1): void {\n scroller.scrollTop += direction * this.resolveNavScrollStepPx();\n this.syncThumbPosition();\n this.bumpVisibility();\n }\n\n private bindRailInteraction(scroller: HTMLElement): void {\n const rail = this.railEl;\n if (!rail) {\n return;\n }\n\n this.unbindRailInteraction?.();\n\n const onRailPointerEnter = () => {\n this.pointerOverRail = true;\n this.showScrollbar();\n this.clearHideTimer();\n };\n const onRailPointerLeave = () => {\n this.pointerOverRail = false;\n this.clearTrackPressed();\n this.syncEngagedAfterScroll();\n this.scheduleHide();\n };\n const onRailWheel = (event: WheelEvent) => {\n event.preventDefault();\n event.stopPropagation();\n scroller.scrollTop += event.deltaY;\n this.bumpVisibility();\n };\n const onRailPointerDown = (event: PointerEvent) => {\n const thumb = this.thumbEl;\n const target = event.target as Node;\n if (thumb && (event.target === thumb || thumb.contains(target))) {\n return;\n }\n if (\n this.navUpEl?.contains(target) ||\n this.navDownEl?.contains(target) ||\n event.target === this.navUpEl ||\n event.target === this.navDownEl\n ) {\n return;\n }\n const track = this.trackEl;\n if (!track || (event.target !== track && !track.contains(target))) {\n return;\n }\n if (this.isPointerOverThumbVisual(event.clientX, event.clientY)) {\n return;\n }\n event.preventDefault();\n this.beginTrackPressed();\n this.jumpScrollToTrackPointer(event, scroller);\n };\n\n const bindNavButton = (button: HTMLButtonElement | null, direction: -1 | 1): (() => void) => {\n if (!button) {\n return () => undefined;\n }\n\n const onNavPointerLeave = () => {\n button.classList.remove(NAV_BTN_PRESSED_CLASS);\n };\n const onNavPointerDown = (event: PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n button.classList.add(NAV_BTN_PRESSED_CLASS);\n this.beginTrackPressed();\n this.scrollByNavStep(scroller, direction);\n };\n const onNavPointerUp = () => {\n button.classList.remove(NAV_BTN_PRESSED_CLASS);\n };\n\n button.addEventListener('pointerleave', onNavPointerLeave);\n button.addEventListener('pointerdown', onNavPointerDown);\n button.addEventListener('pointerup', onNavPointerUp);\n button.addEventListener('pointercancel', onNavPointerUp);\n\n return () => {\n button.removeEventListener('pointerleave', onNavPointerLeave);\n button.removeEventListener('pointerdown', onNavPointerDown);\n button.removeEventListener('pointerup', onNavPointerUp);\n button.removeEventListener('pointercancel', onNavPointerUp);\n button.classList.remove(NAV_BTN_PRESSED_CLASS);\n };\n };\n\n const unbindNavUp = bindNavButton(this.navUpEl, -1);\n const unbindNavDown = bindNavButton(this.navDownEl, 1);\n\n rail.addEventListener('pointerenter', onRailPointerEnter);\n rail.addEventListener('pointerleave', onRailPointerLeave);\n rail.addEventListener('wheel', onRailWheel, { passive: false });\n rail.addEventListener('pointerdown', onRailPointerDown);\n\n this.unbindRailInteraction = () => {\n rail.removeEventListener('pointerenter', onRailPointerEnter);\n rail.removeEventListener('pointerleave', onRailPointerLeave);\n this.clearTrackPressed();\n rail.removeEventListener('wheel', onRailWheel);\n rail.removeEventListener('pointerdown', onRailPointerDown);\n unbindNavUp?.();\n unbindNavDown?.();\n };\n }\n\n private unmountCustomScrollbar(scroller: HTMLElement): void {\n this.railEl?.remove();\n this.railEl = null;\n this.trackEl = null;\n this.navUpEl = null;\n this.navDownEl = null;\n this.thumbEl = null;\n this.thumbLayout = null;\n\n const root = this.rootEl;\n if (!root?.classList.contains(ROOT_CLASS)) {\n this.rootEl = null;\n return;\n }\n\n const parent = root.parentElement;\n if (parent) {\n parent.insertBefore(scroller, root);\n root.remove();\n }\n this.rootEl = null;\n }\n\n private remeasureCustomThumb(): void {\n const element = this.host.nativeElement;\n const rail = this.railEl;\n const thumb = this.thumbEl;\n if (!rail || !thumb) {\n return;\n }\n\n syncOverlayScrollbarDesignTokens(element, this.rootEl);\n\n const clientHeight = element.clientHeight;\n rail.style.height = `${clientHeight}px`;\n\n const widthPx = readRailWidthPx(rail);\n const navigationEnabled = this.navigationButtons() === true;\n rail.classList.toggle(RAIL_WITH_NAV_CLASS, navigationEnabled);\n\n const track = this.trackEl;\n let trackViewportHeight = track?.clientHeight ?? 0;\n if (trackViewportHeight <= 0) {\n trackViewportHeight = navigationEnabled ? Math.max(0, clientHeight - 2 * widthPx) : clientHeight;\n }\n\n const scrollHeight = element.scrollHeight;\n const isScrollable = scrollHeight > clientHeight + 1;\n rail.hidden = !isScrollable;\n if (!isScrollable) {\n this.thumbLayout = null;\n thumb.style.height = '';\n thumb.style.top = '';\n return;\n }\n\n const thumbHeight = Math.max(MIN_THUMB_HEIGHT_PX, (trackViewportHeight / scrollHeight) * trackViewportHeight);\n const maxScroll = scrollHeight - clientHeight;\n const maxThumbOffset = Math.max(0, trackViewportHeight - thumbHeight);\n\n this.thumbLayout = { thumbHeight, maxScroll, maxThumbOffset };\n thumb.style.height = `${thumbHeight}px`;\n this.syncThumbPosition();\n }\n\n private syncThumbPosition(): void {\n const element = this.host.nativeElement;\n const thumb = this.thumbEl;\n const layout = this.thumbLayout;\n if (!thumb || !layout) {\n return;\n }\n\n const { maxScroll, maxThumbOffset } = layout;\n const scrollTop = element.scrollTop;\n const thumbOffset = maxScroll > 0 ? (scrollTop / maxScroll) * maxThumbOffset : 0;\n thumb.style.top = `${thumbOffset}px`;\n }\n\n /** Move thumb (and scroll position) to the pointer Y on the track. */\n private jumpScrollToTrackPointer(event: PointerEvent, scroller: HTMLElement): void {\n const rail = this.railEl;\n const layout = this.thumbLayout;\n if (!rail || !layout || layout.maxScroll <= 0 || layout.maxThumbOffset <= 0) {\n return;\n }\n\n const track = this.trackEl ?? rail;\n const rect = track.getBoundingClientRect();\n const offsetY = event.clientY - rect.top;\n const thumbTop = Math.min(layout.maxThumbOffset, Math.max(0, offsetY - layout.thumbHeight / 2));\n scroller.scrollTop = (thumbTop / layout.maxThumbOffset) * layout.maxScroll;\n this.syncThumbPosition();\n this.bumpVisibility();\n }\n\n private onThumbPointerDown(event: PointerEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n const element = this.host.nativeElement;\n const thumb = this.thumbEl;\n if (!thumb) {\n return;\n }\n\n this.setScrollbarEngaged(true);\n this.bumpVisibility();\n thumb.setPointerCapture(event.pointerId);\n\n const startY = event.clientY;\n const startScrollTop = element.scrollTop;\n const layout = this.thumbLayout;\n const clientHeight = element.clientHeight;\n const maxScroll = layout?.maxScroll ?? element.scrollHeight - clientHeight;\n const maxThumbOffset = layout?.maxThumbOffset ?? clientHeight - thumb.offsetHeight;\n\n const onPointerMove = (moveEvent: PointerEvent) => {\n if (maxThumbOffset <= 0 || maxScroll <= 0) {\n return;\n }\n const deltaY = moveEvent.clientY - startY;\n const scrollDelta = (deltaY / maxThumbOffset) * maxScroll;\n element.scrollTop = startScrollTop + scrollDelta;\n };\n\n const onPointerUp = (upEvent: PointerEvent) => {\n thumb.releasePointerCapture(upEvent.pointerId);\n thumb.removeEventListener('pointermove', onPointerMove);\n thumb.removeEventListener('pointerup', onPointerUp);\n thumb.removeEventListener('pointercancel', onPointerUp);\n this.thumbDragPointerId = null;\n this.setScrollbarEngaged(false);\n };\n\n this.thumbDragPointerId = event.pointerId;\n thumb.addEventListener('pointermove', onPointerMove);\n thumb.addEventListener('pointerup', onPointerUp);\n thumb.addEventListener('pointercancel', onPointerUp);\n }\n\n private showScrollbar(): void {\n this.host.nativeElement.classList.add(VISIBLE_CLASS);\n this.rootEl?.classList.add(VISIBLE_CLASS);\n }\n\n private bumpVisibility(): void {\n this.showScrollbar();\n if (this.pointerOverRail) {\n this.clearHideTimer();\n return;\n }\n this.scheduleHide();\n }\n\n private deactivateThumb(): void {\n if (this.pointerOverRail) {\n return;\n }\n this.clearHideTimer();\n this.host.nativeElement.classList.remove(VISIBLE_CLASS);\n this.rootEl?.classList.remove(VISIBLE_CLASS);\n this.setScrollbarEngaged(false);\n }\n\n private setScrollbarEngaged(engaged: boolean): void {\n this.host.nativeElement.classList.toggle(ENGAGED_CLASS, engaged);\n this.rootEl?.classList.toggle(ENGAGED_CLASS, engaged);\n }\n\n private setTrackPressed(pressed: boolean): void {\n this.host.nativeElement.classList.toggle(TRACK_PRESSED_CLASS, pressed);\n this.rootEl?.classList.toggle(TRACK_PRESSED_CLASS, pressed);\n }\n\n private isPointerOverThumbVisual(clientX: number, clientY: number): boolean {\n const thumb = this.thumbEl;\n if (!thumb) {\n return false;\n }\n const rect = thumb.getBoundingClientRect();\n return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;\n }\n\n private beginTrackPressed(): void {\n this.clearTrackPressed();\n this.setTrackPressed(true);\n const release = () => {\n this.setTrackPressed(false);\n this.document.removeEventListener('pointerup', release);\n this.document.removeEventListener('pointercancel', release);\n this.trackPressReleaseListener = null;\n };\n this.trackPressReleaseListener = release;\n this.document.addEventListener('pointerup', release);\n this.document.addEventListener('pointercancel', release);\n }\n\n private clearTrackPressed(): void {\n if (this.trackPressReleaseListener) {\n this.document.removeEventListener('pointerup', this.trackPressReleaseListener);\n this.document.removeEventListener('pointercancel', this.trackPressReleaseListener);\n this.trackPressReleaseListener = null;\n }\n this.setTrackPressed(false);\n }\n\n private syncEngagedAfterScroll(): void {\n if (this.thumbDragPointerId !== null) {\n return;\n }\n this.setScrollbarEngaged(false);\n }\n\n private scheduleHide(): void {\n if (this.pointerOverRail) {\n this.clearHideTimer();\n return;\n }\n this.clearHideTimer();\n const delay = Math.max(0, this.hideDelay());\n this.hideTimer = setTimeout(() => {\n this.deactivateThumb();\n this.hideTimer = null;\n }, delay);\n }\n\n private clearHideTimer(): void {\n if (this.hideTimer !== null) {\n clearTimeout(this.hideTimer);\n this.hideTimer = null;\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# @acorex/cdk/overlay-scrollbar
|
|
2
|
+
|
|
3
|
+
Thin overlay scrollbars: hidden while idle, visible while scrolling. **Behavior** is configured with directive inputs; **visuals** use CSS custom properties (`--ax-comp-overlay-scrollbar-*`) on the scroll host.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
import { AXOverlayScrollbarDirective } from '@acorex/cdk/overlay-scrollbar';
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<div
|
|
11
|
+
class="h-64 overflow-y-auto my-scroll-panel"
|
|
12
|
+
axOverlayScrollbar
|
|
13
|
+
[hideDelay]="800"
|
|
14
|
+
></div>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```css
|
|
18
|
+
.my-scroll-panel {
|
|
19
|
+
--ax-comp-overlay-scrollbar-size: 8px;
|
|
20
|
+
--ax-comp-overlay-scrollbar-thumb-color: #64748b;
|
|
21
|
+
--ax-comp-overlay-scrollbar-track-color: rgba(148, 163, 184, 0.35);
|
|
22
|
+
--ax-comp-overlay-scrollbar-thumb-radius: 6px;
|
|
23
|
+
--ax-comp-overlay-scrollbar-track-radius: 4px;
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
On first use the directive injects scrollbar rules and default design tokens into the document. No `@acorex/styles` import is required.
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acorex/cdk",
|
|
3
|
-
"version": "22.4.
|
|
3
|
+
"version": "22.4.8",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@acorex/core": "22.4.
|
|
5
|
+
"@acorex/core": "22.4.8",
|
|
6
6
|
"@tiptap/core": ">=3.31.4",
|
|
7
7
|
"@tiptap/extension-color": ">=3.31.4",
|
|
8
8
|
"@tiptap/extension-highlight": ">=3.31.4",
|
|
@@ -96,6 +96,10 @@
|
|
|
96
96
|
"types": "./types/acorex-cdk-overlay.d.ts",
|
|
97
97
|
"default": "./fesm2022/acorex-cdk-overlay.mjs"
|
|
98
98
|
},
|
|
99
|
+
"./overlay-scrollbar": {
|
|
100
|
+
"types": "./types/acorex-cdk-overlay-scrollbar.d.ts",
|
|
101
|
+
"default": "./fesm2022/acorex-cdk-overlay-scrollbar.mjs"
|
|
102
|
+
},
|
|
99
103
|
"./pan-view": {
|
|
100
104
|
"types": "./types/acorex-cdk-pan-view.d.ts",
|
|
101
105
|
"default": "./fesm2022/acorex-cdk-pan-view.mjs"
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
|
|
3
|
+
/** CSS custom properties for overlay scrollbar styling (set on the scroll host or in CSS). */
|
|
4
|
+
declare const AX_OVERLAY_SCROLLBAR_CSS_VARS: {
|
|
5
|
+
readonly size: "--ax-comp-overlay-scrollbar-size";
|
|
6
|
+
readonly thumbRadius: "--ax-comp-overlay-scrollbar-thumb-radius";
|
|
7
|
+
readonly trackRadius: "--ax-comp-overlay-scrollbar-track-radius";
|
|
8
|
+
readonly trackColor: "--ax-comp-overlay-scrollbar-track-color";
|
|
9
|
+
readonly thumbColor: "--ax-comp-overlay-scrollbar-thumb-color";
|
|
10
|
+
readonly thumbActiveColor: "--ax-comp-overlay-scrollbar-thumb-active-color";
|
|
11
|
+
readonly thumbHoverColor: "--ax-comp-overlay-scrollbar-thumb-hover-color";
|
|
12
|
+
readonly trackActiveColor: "--ax-comp-overlay-scrollbar-track-active-color";
|
|
13
|
+
readonly thumbBorderWidth: "--ax-comp-overlay-scrollbar-thumb-border-width";
|
|
14
|
+
readonly thumbBorderColor: "--ax-comp-overlay-scrollbar-thumb-border-color";
|
|
15
|
+
readonly trackBorderWidth: "--ax-comp-overlay-scrollbar-track-border-width";
|
|
16
|
+
readonly trackBorderColor: "--ax-comp-overlay-scrollbar-track-border-color";
|
|
17
|
+
readonly fadeDuration: "--ax-comp-overlay-scrollbar-fade-duration";
|
|
18
|
+
};
|
|
19
|
+
declare function clampOverlayScrollbarWidth(px: number): number;
|
|
20
|
+
/**
|
|
21
|
+
* Custom overlay scrollbar: native scrollbars are hidden; a positioned thumb reflects scroll position.
|
|
22
|
+
* Styles are injected once by this directive.
|
|
23
|
+
*/
|
|
24
|
+
declare class AXOverlayScrollbarDirective {
|
|
25
|
+
private readonly host;
|
|
26
|
+
private readonly destroyRef;
|
|
27
|
+
private readonly platformId;
|
|
28
|
+
private readonly document;
|
|
29
|
+
private rootEl;
|
|
30
|
+
private railEl;
|
|
31
|
+
private trackEl;
|
|
32
|
+
private navUpEl;
|
|
33
|
+
private navDownEl;
|
|
34
|
+
private thumbEl;
|
|
35
|
+
private resizeObserver;
|
|
36
|
+
private designTokenMutationObserver;
|
|
37
|
+
private designTokenSyncFrame;
|
|
38
|
+
private thumbDragPointerId;
|
|
39
|
+
private pointerOverRail;
|
|
40
|
+
private trackPressReleaseListener;
|
|
41
|
+
private unbindRailInteraction;
|
|
42
|
+
/** Thumb size derived from layout; position updates on scroll without re-measuring scrollHeight. */
|
|
43
|
+
private thumbLayout;
|
|
44
|
+
readonly hideDelay: _angular_core.InputSignal<number>;
|
|
45
|
+
/**
|
|
46
|
+
* When true, shows browser-style up/down arrow buttons on the rail.
|
|
47
|
+
* Styling follows track/thumb CSS tokens.
|
|
48
|
+
*/
|
|
49
|
+
readonly navigationButtons: _angular_core.InputSignal<boolean>;
|
|
50
|
+
/** Pixels to scroll per arrow click. */
|
|
51
|
+
readonly navScrollStep: _angular_core.InputSignal<number>;
|
|
52
|
+
private hideTimer;
|
|
53
|
+
constructor();
|
|
54
|
+
/** Host and rail are siblings under the root; mirror CSS variables when the host style/class changes. */
|
|
55
|
+
private observeHostDesignTokenChanges;
|
|
56
|
+
private queueDesignTokenSync;
|
|
57
|
+
/** Rail lives on a wrapper so it stays fixed while the host scrolls. */
|
|
58
|
+
private ensureScrollRoot;
|
|
59
|
+
private mountCustomScrollbar;
|
|
60
|
+
private ensureRailStructure;
|
|
61
|
+
private createNavButton;
|
|
62
|
+
private resolveNavScrollStepPx;
|
|
63
|
+
private scrollByNavStep;
|
|
64
|
+
private bindRailInteraction;
|
|
65
|
+
private unmountCustomScrollbar;
|
|
66
|
+
private remeasureCustomThumb;
|
|
67
|
+
private syncThumbPosition;
|
|
68
|
+
/** Move thumb (and scroll position) to the pointer Y on the track. */
|
|
69
|
+
private jumpScrollToTrackPointer;
|
|
70
|
+
private onThumbPointerDown;
|
|
71
|
+
private showScrollbar;
|
|
72
|
+
private bumpVisibility;
|
|
73
|
+
private deactivateThumb;
|
|
74
|
+
private setScrollbarEngaged;
|
|
75
|
+
private setTrackPressed;
|
|
76
|
+
private isPointerOverThumbVisual;
|
|
77
|
+
private beginTrackPressed;
|
|
78
|
+
private clearTrackPressed;
|
|
79
|
+
private syncEngagedAfterScroll;
|
|
80
|
+
private scheduleHide;
|
|
81
|
+
private clearHideTimer;
|
|
82
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXOverlayScrollbarDirective, never>;
|
|
83
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXOverlayScrollbarDirective, "[axOverlayScrollbar]", ["axOverlayScrollbar"], { "hideDelay": { "alias": "hideDelay"; "required": false; "isSignal": true; }; "navigationButtons": { "alias": "navigationButtons"; "required": false; "isSignal": true; }; "navScrollStep": { "alias": "navScrollStep"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { AXOverlayScrollbarDirective, AX_OVERLAY_SCROLLBAR_CSS_VARS, clampOverlayScrollbarWidth };
|