ngx-zoneless-scrollbar 21.0.17 → 21.0.19
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.
|
@@ -129,7 +129,7 @@ class NgxZonelessScrollbar {
|
|
|
129
129
|
<ng-content></ng-content>
|
|
130
130
|
</div>
|
|
131
131
|
</div>
|
|
132
|
-
`, isInline: true, styles: ["
|
|
132
|
+
`, isInline: true, styles: ["ngx-zoneless-scrollbar{display:block;height:100%;width:100%;position:relative;--scrollbar-size: 7px;--scrollbar-track-color: transparent;--scrollbar-track-radius: 4px;--scrollbar-thumb-color: rgba(0, 0, 0, .3);--scrollbar-thumb-color-hover: rgba(0, 0, 0, .5);--scrollbar-thumb-radius: 4px;--scrollbar-thumb-border: 0;--scrollbar-thumb-border-hover: 0;--scrollbar-thumb-shadow: none;--scrollbar-thumb-shadow-hover: none}ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport{height:100%;width:100%;overflow:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-content{min-height:100%;min-width:100%}ngx-zoneless-scrollbar[orientation=vertical] .ngx-zoneless-scrollbar-viewport{overflow-x:hidden;overflow-y:auto}ngx-zoneless-scrollbar[orientation=horizontal] .ngx-zoneless-scrollbar-viewport{overflow-x:auto;overflow-y:hidden}@supports not selector(::-webkit-scrollbar){ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport{scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb-color) var(--scrollbar-track-color)}}ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar{width:var(--scrollbar-size);height:var(--scrollbar-size)}ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-track{background:var(--scrollbar-track-color);border-radius:var(--scrollbar-track-radius)}ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-thumb{background:var(--scrollbar-thumb-color);border-radius:var(--scrollbar-thumb-radius);border:var(--scrollbar-thumb-border);box-shadow:var(--scrollbar-thumb-shadow);transition:background .2s ease,box-shadow .2s ease,border .2s ease}ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-thumb:hover,ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-thumb:active{background:var(--scrollbar-thumb-color-hover);border:var(--scrollbar-thumb-border-hover);box-shadow:var(--scrollbar-thumb-shadow-hover)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
133
133
|
}
|
|
134
134
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: NgxZonelessScrollbar, decorators: [{
|
|
135
135
|
type: Component,
|
|
@@ -141,7 +141,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
141
141
|
</div>
|
|
142
142
|
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
143
143
|
'[attr.orientation]': 'orientation()',
|
|
144
|
-
}, styles: ["
|
|
144
|
+
}, styles: ["ngx-zoneless-scrollbar{display:block;height:100%;width:100%;position:relative;--scrollbar-size: 7px;--scrollbar-track-color: transparent;--scrollbar-track-radius: 4px;--scrollbar-thumb-color: rgba(0, 0, 0, .3);--scrollbar-thumb-color-hover: rgba(0, 0, 0, .5);--scrollbar-thumb-radius: 4px;--scrollbar-thumb-border: 0;--scrollbar-thumb-border-hover: 0;--scrollbar-thumb-shadow: none;--scrollbar-thumb-shadow-hover: none}ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport{height:100%;width:100%;overflow:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-content{min-height:100%;min-width:100%}ngx-zoneless-scrollbar[orientation=vertical] .ngx-zoneless-scrollbar-viewport{overflow-x:hidden;overflow-y:auto}ngx-zoneless-scrollbar[orientation=horizontal] .ngx-zoneless-scrollbar-viewport{overflow-x:auto;overflow-y:hidden}@supports not selector(::-webkit-scrollbar){ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport{scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb-color) var(--scrollbar-track-color)}}ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar{width:var(--scrollbar-size);height:var(--scrollbar-size)}ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-track{background:var(--scrollbar-track-color);border-radius:var(--scrollbar-track-radius)}ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-thumb{background:var(--scrollbar-thumb-color);border-radius:var(--scrollbar-thumb-radius);border:var(--scrollbar-thumb-border);box-shadow:var(--scrollbar-thumb-shadow);transition:background .2s ease,box-shadow .2s ease,border .2s ease}ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-thumb:hover,ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-thumb:active{background:var(--scrollbar-thumb-color-hover);border:var(--scrollbar-thumb-border-hover);box-shadow:var(--scrollbar-thumb-shadow-hover)}\n"] }]
|
|
145
145
|
}], propDecorators: { viewportRef: [{
|
|
146
146
|
type: ViewChild,
|
|
147
147
|
args: ['viewport']
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngx-zoneless-scrollbar.mjs","sources":["../../../projects/ngx-zoneless-scrollbar/src/lib/ngx-zoneless-scrollbar.component.ts","../../../projects/ngx-zoneless-scrollbar/src/public-api.ts","../../../projects/ngx-zoneless-scrollbar/src/ngx-zoneless-scrollbar.ts"],"sourcesContent":["import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, input, OnDestroy, output, signal, ViewChild, ViewEncapsulation, WritableSignal } from '@angular/core';\nimport { ScrollbarOrientation, ScrollbarUpdateEvent } from './ngx-zoneless-scrollbar.models';\n\n/**\n * NgxZonelessScrollbar\n *\n * A lightweight, zoneless-compatible scrollbar component for Angular.\n * Uses native browser scrolling with CSS-styled scrollbars.\n *\n * Features:\n * - Uses native browser scrolling (100% reliable in zoneless mode)\n * - CSS-styled scrollbars for modern browsers (Chrome, Firefox, Safari)\n * - Detects if content is scrollable and exposes this via signals\n * - Emits events after content updates\n * - Touch-friendly with momentum scrolling\n *\n * @example\n * ```html\n * <ngx-zoneless-scrollbar (afterUpdate)=\"onScrollbarUpdated($event)\">\n * <div>Your scrollable content here</div>\n * </ngx-zoneless-scrollbar>\n * ```\n */\n@Component({\n selector: 'ngx-zoneless-scrollbar',\n standalone: true,\n template: `\n <div #viewport class=\"ngx-zoneless-scrollbar-viewport\" [class.vertical-scrollable]=\"isVerticallyScrollable()\" [class.horizontal-scrollable]=\"isHorizontallyScrollable()\">\n <div #content class=\"ngx-zoneless-scrollbar-content\">\n <ng-content></ng-content>\n </div>\n </div>\n `,\n styles: [\n `\n :host {\n display: block;\n height: 100%;\n width: 100%;\n position: relative;\n\n /* CSS Custom Properties for easy customization */\n --scrollbar-size: 7px;\n --scrollbar-track-color: transparent;\n --scrollbar-track-radius: 4px;\n --scrollbar-thumb-color: rgba(0, 0, 0, 0.3);\n --scrollbar-thumb-color-hover: rgba(0, 0, 0, 0.5);\n --scrollbar-thumb-radius: 4px;\n --scrollbar-thumb-shadow: unset;\n --scrollbar-thumb-shadow-hover: unset;\n --scrollbar-thumb-border: 0;\n --scrollbar-thumb-border-hover: 0;\n }\n\n .ngx-zoneless-scrollbar-viewport {\n height: 100%;\n width: 100%;\n overflow: auto;\n -webkit-overflow-scrolling: touch; /* Smooth scrolling on iOS */\n overscroll-behavior: contain; /* Prevent scroll chaining */\n\n /* Inherit CSS custom properties from :host */\n scrollbar-width: thin;\n scrollbar-color: var(--scrollbar-thumb-color, rgba(0, 0, 0, 0.3)) var(--scrollbar-track-color, transparent);\n }\n\n /* Custom scrollbar styling for webkit browsers (Chrome, Safari, Edge) */\n .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar {\n width: var(--scrollbar-size, 7px);\n height: var(--scrollbar-size, 7px);\n }\n\n .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-track {\n background: var(--scrollbar-track-color, transparent);\n border-radius: var(--scrollbar-track-radius, 4px);\n }\n\n .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-thumb {\n background: var(--scrollbar-thumb-color, rgba(0, 0, 0, 0.3));\n border-radius: var(--scrollbar-thumb-radius, 4px);\n border: var(--scrollbar-thumb-border, 0);\n box-shadow: var(--scrollbar-thumb-shadow, unset);\n transition: background 0.2s ease, box-shadow 0.2s ease, border 0.2s ease;\n }\n\n .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-thumb:hover {\n background: var(--scrollbar-thumb-color-hover, rgba(0, 0, 0, 0.5));\n border: var(--scrollbar-thumb-border-hover, 0);\n box-shadow: var(--scrollbar-thumb-shadow-hover, unset);\n }\n\n .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-thumb:active {\n background: var(--scrollbar-thumb-color-hover, rgba(0, 0, 0, 0.5));\n border: var(--scrollbar-thumb-border-hover, 0);\n box-shadow: var(--scrollbar-thumb-shadow-hover, unset);\n }\n\n /* Orientation-specific overflow behavior */\n :host([orientation='vertical']) .ngx-zoneless-scrollbar-viewport {\n overflow-x: hidden;\n overflow-y: auto;\n }\n\n :host([orientation='horizontal']) .ngx-zoneless-scrollbar-viewport {\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .ngx-zoneless-scrollbar-content {\n min-height: 100%;\n min-width: 100%;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n '[attr.orientation]': 'orientation()',\n },\n})\nexport class NgxZonelessScrollbar implements AfterViewInit, OnDestroy {\n @ViewChild('viewport') viewportRef!: ElementRef<HTMLElement>;\n @ViewChild('content') contentRef!: ElementRef<HTMLElement>;\n\n /**\n * Orientation of scrolling\n * - 'vertical': Only vertical scrolling (default)\n * - 'horizontal': Only horizontal scrolling\n * - 'auto': Both directions as needed\n */\n readonly orientation = input<ScrollbarOrientation>('vertical');\n\n /**\n * Emits after the scrollbar state is updated with scrollability info\n */\n readonly afterUpdate = output<ScrollbarUpdateEvent>();\n\n /**\n * Signal indicating if content is vertically scrollable\n */\n readonly isVerticallyScrollable: WritableSignal<boolean> = signal(false);\n\n /**\n * Signal indicating if content is horizontally scrollable\n */\n readonly isHorizontallyScrollable: WritableSignal<boolean> = signal(false);\n\n private resizeObserver: ResizeObserver | null = null;\n\n ngAfterViewInit(): void {\n // Initial check after view is ready\n this.checkScrollability();\n\n // Set up ResizeObserver to detect content changes\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => {\n this.checkScrollability();\n });\n\n // Observe both viewport and content for size changes\n this.resizeObserver.observe(this.viewportRef.nativeElement);\n this.resizeObserver.observe(this.contentRef.nativeElement);\n }\n }\n\n ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n }\n\n /**\n * Check if content is scrollable and emit update event\n */\n private checkScrollability(): void {\n const viewport = this.viewportRef?.nativeElement;\n const content = this.contentRef?.nativeElement;\n\n if (!viewport || !content) return;\n\n const isVertical = content.scrollHeight > viewport.clientHeight;\n const isHorizontal = content.scrollWidth > viewport.clientWidth;\n\n // Only update and emit if values changed\n const prevVertical = this.isVerticallyScrollable();\n const prevHorizontal = this.isHorizontallyScrollable();\n\n if (isVertical !== prevVertical || isHorizontal !== prevHorizontal) {\n this.isVerticallyScrollable.set(isVertical);\n this.isHorizontallyScrollable.set(isHorizontal);\n\n this.afterUpdate.emit({\n isVerticallyScrollable: isVertical,\n isHorizontallyScrollable: isHorizontal,\n });\n }\n }\n\n /**\n * Scroll to a specific position\n * @param options - ScrollToOptions with top, left, and behavior\n * @returns Promise that resolves when scroll is complete\n */\n scrollTo(options: ScrollToOptions): Promise<void> {\n return new Promise((resolve) => {\n this.viewportRef?.nativeElement?.scrollTo({\n top: options.top ?? 0,\n left: options.left ?? 0,\n behavior: options.behavior ?? 'smooth',\n });\n // Resolve after a short delay for smooth scroll\n setTimeout(resolve, options.behavior === 'instant' ? 0 : 300);\n });\n }\n\n /**\n * Manually trigger an update check\n */\n update(): void {\n this.checkScrollability();\n }\n\n /**\n * Get the viewport element for direct access if needed\n */\n get viewportElement(): HTMLElement | null {\n return this.viewportRef?.nativeElement ?? null;\n }\n\n /**\n * Get the current scroll position\n */\n get scrollTop(): number {\n return this.viewportRef?.nativeElement?.scrollTop ?? 0;\n }\n\n /**\n * Get the current horizontal scroll position\n */\n get scrollLeft(): number {\n return this.viewportRef?.nativeElement?.scrollLeft ?? 0;\n }\n}\n","/*\n * Public API Surface of ngx-zoneless-scrollbar\n */\n\nexport * from './lib/ngx-zoneless-scrollbar.component';\nexport * from './lib/ngx-zoneless-scrollbar.models';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngx-zoneless-scrollbar.mjs","sources":["../../../projects/ngx-zoneless-scrollbar/src/lib/ngx-zoneless-scrollbar.component.ts","../../../projects/ngx-zoneless-scrollbar/src/public-api.ts","../../../projects/ngx-zoneless-scrollbar/src/ngx-zoneless-scrollbar.ts"],"sourcesContent":["import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, input, OnDestroy, output, signal, ViewChild, ViewEncapsulation, WritableSignal } from '@angular/core';\nimport { ScrollbarOrientation, ScrollbarUpdateEvent } from './ngx-zoneless-scrollbar.models';\n\n/**\n * NgxZonelessScrollbar\n *\n * A lightweight, zoneless-compatible scrollbar component for Angular.\n * Uses native browser scrolling with CSS-styled scrollbars.\n *\n * Features:\n * - Uses native browser scrolling (100% reliable in zoneless mode)\n * - CSS-styled scrollbars for modern browsers (Chrome, Firefox, Safari)\n * - Detects if content is scrollable and exposes this via signals\n * - Emits events after content updates\n * - Touch-friendly with momentum scrolling\n *\n * @example\n * ```html\n * <ngx-zoneless-scrollbar (afterUpdate)=\"onScrollbarUpdated($event)\">\n * <div>Your scrollable content here</div>\n * </ngx-zoneless-scrollbar>\n * ```\n */\n@Component({\n selector: 'ngx-zoneless-scrollbar',\n standalone: true,\n template: `\n <div #viewport class=\"ngx-zoneless-scrollbar-viewport\" [class.vertical-scrollable]=\"isVerticallyScrollable()\" [class.horizontal-scrollable]=\"isHorizontallyScrollable()\">\n <div #content class=\"ngx-zoneless-scrollbar-content\">\n <ng-content></ng-content>\n </div>\n </div>\n `,\n styles: `\n /* Host element base styles */\n ngx-zoneless-scrollbar {\n display: block;\n height: 100%;\n width: 100%;\n position: relative;\n\n /* CSS Custom Properties - override these to customize the scrollbar */\n --scrollbar-size: 7px;\n --scrollbar-track-color: transparent;\n --scrollbar-track-radius: 4px;\n --scrollbar-thumb-color: rgba(0, 0, 0, 0.3);\n --scrollbar-thumb-color-hover: rgba(0, 0, 0, 0.5);\n --scrollbar-thumb-radius: 4px;\n --scrollbar-thumb-border: 0;\n --scrollbar-thumb-border-hover: 0;\n --scrollbar-thumb-shadow: none;\n --scrollbar-thumb-shadow-hover: none;\n }\n\n /* Viewport container */\n ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport {\n height: 100%;\n width: 100%;\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n overscroll-behavior: contain;\n }\n\n /* Content wrapper */\n ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-content {\n min-height: 100%;\n min-width: 100%;\n }\n\n /* Orientation variants */\n ngx-zoneless-scrollbar[orientation='vertical'] .ngx-zoneless-scrollbar-viewport {\n overflow-x: hidden;\n overflow-y: auto;\n }\n\n ngx-zoneless-scrollbar[orientation='horizontal'] .ngx-zoneless-scrollbar-viewport {\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n /* Firefox scrollbar - only when webkit is not supported */\n @supports not selector(::-webkit-scrollbar) {\n ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport {\n scrollbar-width: thin;\n scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-track-color);\n }\n }\n\n /* Webkit scrollbar styles (Chrome, Safari, Edge) */\n ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar {\n width: var(--scrollbar-size);\n height: var(--scrollbar-size);\n }\n\n ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-track {\n background: var(--scrollbar-track-color);\n border-radius: var(--scrollbar-track-radius);\n }\n\n ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-thumb {\n background: var(--scrollbar-thumb-color);\n border-radius: var(--scrollbar-thumb-radius);\n border: var(--scrollbar-thumb-border);\n box-shadow: var(--scrollbar-thumb-shadow);\n transition: background 0.2s ease, box-shadow 0.2s ease, border 0.2s ease;\n }\n\n ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-thumb:hover,\n ngx-zoneless-scrollbar .ngx-zoneless-scrollbar-viewport::-webkit-scrollbar-thumb:active {\n background: var(--scrollbar-thumb-color-hover);\n border: var(--scrollbar-thumb-border-hover);\n box-shadow: var(--scrollbar-thumb-shadow-hover);\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n '[attr.orientation]': 'orientation()',\n },\n})\nexport class NgxZonelessScrollbar implements AfterViewInit, OnDestroy {\n @ViewChild('viewport') viewportRef!: ElementRef<HTMLElement>;\n @ViewChild('content') contentRef!: ElementRef<HTMLElement>;\n\n /**\n * Orientation of scrolling\n * - 'vertical': Only vertical scrolling (default)\n * - 'horizontal': Only horizontal scrolling\n * - 'auto': Both directions as needed\n */\n readonly orientation = input<ScrollbarOrientation>('vertical');\n\n /**\n * Emits after the scrollbar state is updated with scrollability info\n */\n readonly afterUpdate = output<ScrollbarUpdateEvent>();\n\n /**\n * Signal indicating if content is vertically scrollable\n */\n readonly isVerticallyScrollable: WritableSignal<boolean> = signal(false);\n\n /**\n * Signal indicating if content is horizontally scrollable\n */\n readonly isHorizontallyScrollable: WritableSignal<boolean> = signal(false);\n\n private resizeObserver: ResizeObserver | null = null;\n\n ngAfterViewInit(): void {\n // Initial check after view is ready\n this.checkScrollability();\n\n // Set up ResizeObserver to detect content changes\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => {\n this.checkScrollability();\n });\n\n // Observe both viewport and content for size changes\n this.resizeObserver.observe(this.viewportRef.nativeElement);\n this.resizeObserver.observe(this.contentRef.nativeElement);\n }\n }\n\n ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n }\n\n /**\n * Check if content is scrollable and emit update event\n */\n private checkScrollability(): void {\n const viewport = this.viewportRef?.nativeElement;\n const content = this.contentRef?.nativeElement;\n\n if (!viewport || !content) return;\n\n const isVertical = content.scrollHeight > viewport.clientHeight;\n const isHorizontal = content.scrollWidth > viewport.clientWidth;\n\n // Only update and emit if values changed\n const prevVertical = this.isVerticallyScrollable();\n const prevHorizontal = this.isHorizontallyScrollable();\n\n if (isVertical !== prevVertical || isHorizontal !== prevHorizontal) {\n this.isVerticallyScrollable.set(isVertical);\n this.isHorizontallyScrollable.set(isHorizontal);\n\n this.afterUpdate.emit({\n isVerticallyScrollable: isVertical,\n isHorizontallyScrollable: isHorizontal,\n });\n }\n }\n\n /**\n * Scroll to a specific position\n * @param options - ScrollToOptions with top, left, and behavior\n * @returns Promise that resolves when scroll is complete\n */\n scrollTo(options: ScrollToOptions): Promise<void> {\n return new Promise((resolve) => {\n this.viewportRef?.nativeElement?.scrollTo({\n top: options.top ?? 0,\n left: options.left ?? 0,\n behavior: options.behavior ?? 'smooth',\n });\n // Resolve after a short delay for smooth scroll\n setTimeout(resolve, options.behavior === 'instant' ? 0 : 300);\n });\n }\n\n /**\n * Manually trigger an update check\n */\n update(): void {\n this.checkScrollability();\n }\n\n /**\n * Get the viewport element for direct access if needed\n */\n get viewportElement(): HTMLElement | null {\n return this.viewportRef?.nativeElement ?? null;\n }\n\n /**\n * Get the current scroll position\n */\n get scrollTop(): number {\n return this.viewportRef?.nativeElement?.scrollTop ?? 0;\n }\n\n /**\n * Get the current horizontal scroll position\n */\n get scrollLeft(): number {\n return this.viewportRef?.nativeElement?.scrollLeft ?? 0;\n }\n}\n","/*\n * Public API Surface of ngx-zoneless-scrollbar\n */\n\nexport * from './lib/ngx-zoneless-scrollbar.component';\nexport * from './lib/ngx-zoneless-scrollbar.models';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ngx-zoneless-scrollbar",
|
|
3
|
-
"version": "21.0.
|
|
3
|
+
"version": "21.0.19",
|
|
4
4
|
"description": "A lightweight, zoneless-compatible scrollbar component for Angular. Uses native browser scrolling with CSS-styled scrollbars, designed for Angular's zoneless change detection mode.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|