Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
MurhafSousli committed Nov 13, 2024
1 parent 72ac305 commit 379e87e
Show file tree
Hide file tree
Showing 11 changed files with 1,114 additions and 612 deletions.
9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# Changelog

## 16.0.0
## 16.1.0

- fix: `asyncDetection` scrollbars rendering delay.
- feat: Disable / Suppress the scroll bar during runtime, in [#658](https://github.com/MurhafSousli/ngx-scrollbar/issues/658).
- fix: Wrong track size when used in 3rd party dropdown components, in [#669](https://github.com/MurhafSousli/ngx-scrollbar/issues/669).
- fix: Scrollbar buttons icons not showing in Safari, in [#664](https://github.com/MurhafSousli/ngx-scrollbar/issues/664).

## 16.0.0-beta.2
## 16.0.0

- fix: `asyncDetection` scrollbars rendering delay.
- feat: `scrollViewport` directive can be a descent child, not necessarily a direct child of `<ng-scrollbar externalViewport>`.
- feat: Add `start`, `end`, `right`, `bottom` and `center` options to `scrollToElement` (supports RTL), closes [#637](https://github.com/MurhafSousli/ngx-scrollbar/issues/637).
- feat: Add `syncSpacer` directive that is applied on `<ng-scrollbar externalViewport>` component to sync spacer element with content dimension changes.
Expand Down
1,571 changes: 1,001 additions & 570 deletions package-lock.json

Large diffs are not rendered by default.

54 changes: 27 additions & 27 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,47 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^18.2.5",
"@angular/cdk": "^18.2.5",
"@angular/common": "^18.2.5",
"@angular/compiler": "^18.2.5",
"@angular/core": "^18.2.5",
"@angular/forms": "^18.2.5",
"@angular/material": "^18.2.5",
"@angular/platform-browser": "^18.2.5",
"@angular/platform-browser-dynamic": "^18.2.5",
"@angular/platform-server": "^18.2.5",
"@angular/router": "^18.2.5",
"@angular/ssr": "^18.2.5",
"@angular/animations": "^18.2.11",
"@angular/cdk": "^18.2.12",
"@angular/common": "^18.2.11",
"@angular/compiler": "^18.2.11",
"@angular/core": "^18.2.11",
"@angular/forms": "^18.2.11",
"@angular/material": "^18.2.12",
"@angular/platform-browser": "^18.2.11",
"@angular/platform-browser-dynamic": "^18.2.11",
"@angular/platform-server": "^18.2.11",
"@angular/router": "^18.2.11",
"@angular/ssr": "^18.2.11",
"@swimlane/ngx-datatable": "^20.1.0",
"ag-grid-angular": "^32.2.0",
"ag-grid-community": "^32.2.0",
"ag-grid-angular": "^32.3.2",
"ag-grid-community": "^32.3.2",
"chance": "^1.1.12",
"ng-zorro-antd": "^18.1.1",
"ng-zorro-antd": "^18.2.0",
"ngx-color-picker": "^17.0.0",
"ngx-infinite-scroll": "^18.0.0",
"primeng": "^17.18.10",
"primeng": "^17.18.11",
"rxjs": "~7.8.0",
"tslib": "^2.7.0",
"zone.js": "^0.14.10"
},
"devDependencies": {
"@angular-devkit/build-angular": "^18.2.5",
"@angular-eslint/builder": "18.3.1",
"@angular-eslint/eslint-plugin": "18.3.1",
"@angular-eslint/eslint-plugin-template": "18.3.1",
"@angular-eslint/schematics": "18.3.1",
"@angular-eslint/template-parser": "18.3.1",
"@angular/cli": "^18.2.5",
"@angular/compiler-cli": "^18.2.5",
"@angular-devkit/build-angular": "^18.2.11",
"@angular-eslint/builder": "18.4.0",
"@angular-eslint/eslint-plugin": "18.4.0",
"@angular-eslint/eslint-plugin-template": "18.4.0",
"@angular-eslint/schematics": "18.4.0",
"@angular-eslint/template-parser": "18.4.0",
"@angular/cli": "^18.2.11",
"@angular/compiler-cli": "^18.2.11",
"@types/express": "^4.17.17",
"@types/jasmine": "~5.1.0",
"@types/node": "^22.6.1",
"@typescript-eslint/eslint-plugin": "^8.7.0",
"@typescript-eslint/parser": "^8.7.0",
"eslint": "^9.11.1",
"express": "^4.21.0",
"jasmine-core": "^5.3.0",
"eslint": "^9.14.0",
"express": "^5.0.1",
"jasmine-core": "^5.4.0",
"karma": "~6.4.4",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
Expand Down
2 changes: 1 addition & 1 deletion projects/ngx-scrollbar/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ngx-scrollbar",
"version": "16.0.0",
"version": "16.1.0",
"license": "MIT",
"homepage": "https://ngx-scrollbar.netlify.app/",
"author": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
background-color: var(--INTERNAL-scrollbar-button-color);

svg {
// Must set height and width of SVG so it can render on Safari browsers
width: 100%;
height: 100%;
fill: var(--INTERNAL-scrollbar-button-fill);
}

Expand Down
2 changes: 2 additions & 0 deletions projects/ngx-scrollbar/src/lib/ng-scrollbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@

// The default value for overflow
--_viewport-overflow: auto;
--_viewport-pointer-events: auto;

// Scrollbar thumb color variables used to change when hovered or dragged
--_thumb-x-color: var(--INTERNAL-scrollbar-thumb-color);
Expand Down Expand Up @@ -130,6 +131,7 @@
}

&[disableInteraction="true"] {
--_viewport-pointer-events: none;
--_scrollbar-pointer-events: none;
}

Expand Down
3 changes: 3 additions & 0 deletions projects/ngx-scrollbar/src/lib/styles/viewport.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,8 @@

// In case scroll bounce need to be disabled
overscroll-behavior: var(--_viewport-overscroll-behavior);

// Disables scroll when disableInteraction is set to true
pointer-events: var(--_viewport-pointer-events);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ describe('disableInteraction option', () => {
const trackXWrapperStyles: CSSStyleDeclaration = getComputedStyle(trackX.nativeElement.parentElement);
const trackYWrapperStyles: CSSStyleDeclaration = getComputedStyle(trackY.nativeElement.parentElement);
expect(componentStyles.getPropertyValue('--_scrollbar-pointer-events')).toBe('auto');
expect(componentStyles.getPropertyValue('--_viewport-pointer-events')).toBe('auto');
expect(componentStyles.pointerEvents).toBe('auto');
expect(trackXWrapperStyles.pointerEvents).toBe('auto');
expect(trackYWrapperStyles.pointerEvents).toBe('auto');
}
Expand All @@ -89,6 +91,8 @@ describe('disableInteraction option', () => {
const trackXWrapperStyles: CSSStyleDeclaration = getComputedStyle(trackX.nativeElement.parentElement);
const trackYWrapperStyles: CSSStyleDeclaration = getComputedStyle(trackY.nativeElement.parentElement);
expect(componentStyles.getPropertyValue('--_scrollbar-pointer-events')).toBe('none');
expect(componentStyles.getPropertyValue('--_viewport-pointer-events')).toBe('none');
expect(componentStyles.pointerEvents).toBe('none');
expect(trackXWrapperStyles.pointerEvents).toBe('none');
expect(trackYWrapperStyles.pointerEvents).toBe('none');
}
Expand Down
64 changes: 61 additions & 3 deletions projects/ngx-scrollbar/src/lib/tests/ext-viewport-async.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import { afterTimeout } from './common-test.';
@if (show) {
<div class="some-wrapper">
<div class="my-custom-viewport">
<div class="my-custom-content-wrapper">
<div #sample class="content-sample">Content Sample</div>
</div>
@if (showWrapper) {
<div class="my-custom-content-wrapper">
<div #sample class="content-sample">Content Sample</div>
</div>
}
<div class="my-custom-spacer"></div>
</div>
</div>
Expand All @@ -25,6 +27,7 @@ import { afterTimeout } from './common-test.';
})
class SampleLibComponent {
show: boolean;
showWrapper: boolean = true;
@ViewChild('sample') content: ElementRef<HTMLElement>;
}

Expand Down Expand Up @@ -200,4 +203,59 @@ describe('External viewport via classes [AsyncDetection]', () => {
fixture.destroy();
expect(hostViewDestroySpy).toHaveBeenCalled();
});

it('[asyncDetection="auto"] should detect content wrapper removal', async () => {
component.externalViewport = '.my-custom-viewport';
component.externalContentWrapper = '.my-custom-content-wrapper';
component.asyncDetection = 'auto';
fixture.detectChanges();

expect(scrollbar.customViewport()).toBeFalsy();
expect(scrollbar.externalViewport()).toBeTruthy();
expect(scrollbar.externalContentWrapper()).toBeTruthy();
expect(scrollbar.externalSpacer()).toBeFalsy();
expect(scrollbar.skipInit).toBeTruthy();
expect(scrollbar.viewport.initialized()).toBeFalsy();

// Mock library render after the scrollbar has initialized
component.library.show = true;
fixture.detectChanges();

// Verify afterInit is called
await firstValueFrom(outputToObservable(scrollbar.afterInit));

const viewportElement: HTMLElement = fixture.debugElement.query(By.css(scrollbar.externalViewport()))?.nativeElement;
const contentWrapperElement: HTMLElement = fixture.debugElement.query(By.css(scrollbar.externalContentWrapper()))?.nativeElement;

// Verify the viewport
expect(scrollbar.viewport.nativeElement).toBe(viewportElement);
// Verify that the content wrapper here is the content wrapper element
expect(scrollbar.viewport.contentWrapperElement).toBe(contentWrapperElement);
// Verify that the content is a direct child of the content wrapper element
expect(component.library.content.nativeElement.parentElement).toBe(contentWrapperElement);

// Check if the scrollbars component is created
expect(scrollbar._scrollbars()).toBeTruthy();
const scrollbarsDebugElement: DebugElement = fixture.debugElement.query(By.directive(Scrollbars));
// Verify if the created scrollbars component is the same component instance queried
expect(scrollbar._scrollbars()).toBe(scrollbarsDebugElement.componentInstance);
// Check if the created scrollbars component is the direct child of content wrapper element
expect((scrollbarsDebugElement.nativeElement as Element).parentElement).toBe(scrollbar.viewport.contentWrapperElement);

// MutationObserver has a throttleTime 100ms, need to wait before triggering a detection
await afterTimeout(100);
// Mock library removes the content (such as dropdown)
component.library.showWrapper = false;
fixture.detectChanges();
// Wait a bit more than 100ms for change to take effect
await afterTimeout(110);

expect(scrollbar.viewport.initialized()).toBeFalse();
expect(scrollbar.viewport.nativeElement).toBeFalsy();
expect(scrollbar.viewport.contentWrapperElement).toBeFalsy();

const hostViewDestroySpy: jasmine.Spy = spyOn(scrollbar._scrollbarsRef.hostView, 'destroy');
fixture.destroy();
expect(hostViewDestroySpy).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ describe('External viewport via classes', () => {
const attachScrollbarSpy: jasmine.Spy = spyOn(scrollbarCmp, '_attachScrollbars').and.callThrough();
component.externalViewport = '.my-custom-viewport';


fixture.detectChanges();

expect(scrollbarCmp.customViewport()).toBeFalsy();
Expand Down Expand Up @@ -231,7 +230,7 @@ describe('External viewport via classes', () => {
expect(hostViewDestroySpy).toHaveBeenCalled();
});

it(`[Error handling - content wrapper doesn't exist] should NOT initialize viewport or attach scrollbars`, async () => {
it(`[Error handling - viewport doesn't exist] should NOT initialize viewport or attach scrollbars`, async () => {
const fixture: ComponentFixture<WithViewportDirectiveAndInputsComponent> = TestBed.createComponent(WithViewportDirectiveAndInputsComponent);
const component: WithViewportDirectiveAndInputsComponent = fixture.componentInstance;
const scrollbarCmp: NgScrollbarExt = component.scrollbar();
Expand All @@ -240,8 +239,7 @@ describe('External viewport via classes', () => {
const attachScrollbarSpy: jasmine.Spy = spyOn(scrollbarCmp, '_attachScrollbars').and.callThrough();
const consoleSpy: jasmine.Spy = spyOn(console, 'error').and.callThrough();

component.externalViewport = '.not-existing-viewport';

component.externalViewport = null;

fixture.detectChanges();

Expand Down
8 changes: 4 additions & 4 deletions projects/ngx-scrollbar/src/lib/track/track-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ export abstract class TrackAdapter extends PointerEventsAdapter {

// Scrollbar track length
get size(): number {
return this.clientRect[this.control.rectSizeProperty];
// Noticed that clientHeight is evaluated before getClientRect.height,
// causing a wrong track size when integrated in dropdown integration
return this.nativeElement[this.control.sizeProperty];
}

// Observable for track dragging events
Expand Down Expand Up @@ -114,9 +116,7 @@ export abstract class TrackAdapter extends PointerEventsAdapter {
effect(() => {
this.cmp.viewportDimension();
this.cmp.contentDimension();
untracked(() => {
requestAnimationFrame(() => this.control.trackSize.set(this.size));
});
untracked(() => this.control.trackSize.set(this.size));
});
super();
}
Expand Down

1 comment on commit 379e87e

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.