mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-20 18:20:37 +03:00
finish up angular component and improve vue docs
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
"@types/node": "^16.11.68",
|
"@types/node": "^16.11.68",
|
||||||
"@types/react": "^18.0.21",
|
"@types/react": "^18.0.21",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
"overlayscrollbars-react": "file:../../packages/overlayscrollbars-react",
|
"overlayscrollbars-react": "file:../../packages/overlayscrollbars-react/dist",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
|
|||||||
Generated
+12
-7
@@ -6,7 +6,7 @@
|
|||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"overlayscrollbars-vue": "file:../../packages/overlayscrollbars-vue",
|
"overlayscrollbars-vue": "file:../../packages/overlayscrollbars-vue/dist",
|
||||||
"vue": "^3.2.38"
|
"vue": "^3.2.38"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -19,6 +19,14 @@
|
|||||||
"vue-tsc": "^0.40.7"
|
"vue-tsc": "^0.40.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"../../packages/overlayscrollbars-vue/dist": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"overlayscrollbars": "^2.0.0",
|
||||||
|
"vue": "^3.2.25"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@ampproject/remapping": {
|
"node_modules/@ampproject/remapping": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
||||||
@@ -1481,11 +1489,8 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/overlayscrollbars-vue": {
|
"node_modules/overlayscrollbars-vue": {
|
||||||
"version": "0.4.0",
|
"resolved": "../../packages/overlayscrollbars-vue/dist",
|
||||||
"resolved": "file:../../packages/overlayscrollbars-vue",
|
"link": true
|
||||||
"peerDependencies": {
|
|
||||||
"vue": "^3.2.25"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/path-parse": {
|
"node_modules/path-parse": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
@@ -2741,7 +2746,7 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"overlayscrollbars-vue": {
|
"overlayscrollbars-vue": {
|
||||||
"version": "0.4.0",
|
"version": "file:../../packages/overlayscrollbars-vue/dist",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"path-parse": {
|
"path-parse": {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"overlayscrollbars-vue": "file:../../packages/overlayscrollbars-vue",
|
"overlayscrollbars-vue": "file:../../packages/overlayscrollbars-vue/dist",
|
||||||
"vue": "^3.2.38"
|
"vue": "^3.2.38"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue';
|
|||||||
<img alt="Vue logo" class="logo" src="./assets/logo.svg" width="125" height="125" />
|
<img alt="Vue logo" class="logo" src="./assets/logo.svg" width="125" height="125" />
|
||||||
|
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<OverlayScrollbarsComponent msg="hi" />
|
<OverlayScrollbarsComponent />
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -77,10 +77,10 @@
|
|||||||
"build:vue": "npm run build --workspace=overlayscrollbars-vue",
|
"build:vue": "npm run build --workspace=overlayscrollbars-vue",
|
||||||
"build:ngx": "npm run build --workspace=overlayscrollbars-ngx",
|
"build:ngx": "npm run build --workspace=overlayscrollbars-ngx",
|
||||||
"build:svelte": "npm run build --workspace=overlayscrollbars-svelte",
|
"build:svelte": "npm run build --workspace=overlayscrollbars-svelte",
|
||||||
"example:react": "npm run build:react && cd examples/react && npm i --install-links && npm run start",
|
"example:react": "npm run build:react && cd examples/react && npm i && npm run start",
|
||||||
"example:vue": "npm run build:vue && cd examples/vue && npm i --install-links && npm run dev",
|
"example:vue": "npm run build:vue && cd examples/vue && npm i && npm run dev",
|
||||||
"example:ngx": "npm run build:ngx && cd examples/angular && npm i --install-links && npm run start",
|
"example:ngx": "npm run build:ngx && cd examples/angular && npm i && npm run start",
|
||||||
"example:svelte": "npm run build:svelte && cd examples/svelte && npm i --install-links && npm run dev",
|
"example:svelte": "npm run build:svelte && cd examples/svelte && npm i && npm run dev",
|
||||||
"lint": "eslint ./packages/**/{src,test}/**/*.{js,jsx,ts,tsx}",
|
"lint": "eslint ./packages/**/{src,test}/**/*.{js,jsx,ts,tsx}",
|
||||||
"lint:fix": "eslint --fix ./packages/**/{src,test}/**/*.{js,jsx,ts,tsx}",
|
"lint:fix": "eslint --fix ./packages/**/{src,test}/**/*.{js,jsx,ts,tsx}",
|
||||||
"prettier": "prettier --check ./packages/**/{src,test}/**/*.{js,jsx,ts,tsx}",
|
"prettier": "prettier --check ./packages/**/{src,test}/**/*.{js,jsx,ts,tsx}",
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import {
|
|||||||
AfterViewInit,
|
AfterViewInit,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { OverlayScrollbars } from 'overlayscrollbars';
|
import { OverlayScrollbars } from 'overlayscrollbars';
|
||||||
import { OverlayScrollbarsDirective } from '~/overlayscrollbars.directive';
|
|
||||||
import type { PartialOptions, EventListeners, EventListenerMap } from 'overlayscrollbars';
|
import type { PartialOptions, EventListeners, EventListenerMap } from 'overlayscrollbars';
|
||||||
|
import { OverlayScrollbarsDirective } from './overlayscrollbars.directive';
|
||||||
|
|
||||||
const mergeEventListeners = (emits: EventListeners, events: EventListeners) =>
|
const mergeEventListeners = (emits: EventListeners, events: EventListeners) =>
|
||||||
(Object.keys(emits) as (keyof EventListeners)[]).reduce<EventListeners>(
|
(Object.keys(emits) as (keyof EventListeners)[]).reduce<EventListeners>(
|
||||||
@@ -29,17 +29,12 @@ const mergeEventListeners = (emits: EventListeners, events: EventListeners) =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[overlay-scrollbars-component]', // https://angular.io/guide/styleguide#component-selectors
|
selector: 'overlay-scrollbars, [overlay-scrollbars]', // https://angular.io/guide/styleguide#component-selectors
|
||||||
exportAs: 'overlayScrollbars',
|
|
||||||
host: { 'data-overlayscrollbars': '' },
|
host: { 'data-overlayscrollbars': '' },
|
||||||
template: `<div
|
template: `<div overlayScrollbars [options]="options" [events]="mergeEvents(events)" #content>
|
||||||
#content
|
|
||||||
[overlayScrollbarsDirective]
|
|
||||||
[options]="options"
|
|
||||||
[events]="mergeEvents(events)"
|
|
||||||
>
|
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
</div>`,
|
</div>`,
|
||||||
|
styles: [':host { display: block; }'],
|
||||||
})
|
})
|
||||||
export class OverlayScrollbarsComponent implements OnDestroy, AfterViewInit {
|
export class OverlayScrollbarsComponent implements OnDestroy, AfterViewInit {
|
||||||
@Input('options')
|
@Input('options')
|
||||||
@@ -91,7 +86,7 @@ export class OverlayScrollbarsComponent implements OnDestroy, AfterViewInit {
|
|||||||
this.osDirective?.instance()!.destroy();
|
this.osDirective?.instance()!.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private mergeEvents(originalEvents: OverlayScrollbarsComponent['events']) {
|
mergeEvents(originalEvents: OverlayScrollbarsComponent['events']) {
|
||||||
return mergeEventListeners(
|
return mergeEventListeners(
|
||||||
{
|
{
|
||||||
initialized: (...args) => this.onInitialized.emit(args),
|
initialized: (...args) => this.onInitialized.emit(args),
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ import type { InitializationTarget } from 'overlayscrollbars';
|
|||||||
import type { OverlayScrollbarsComponent } from '~/overlayscrollbars.component';
|
import type { OverlayScrollbarsComponent } from '~/overlayscrollbars.component';
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[overlayScrollbarsDirective]', // https://angular.io/guide/styleguide#component-selectors
|
selector: '[overlayScrollbars]', // https://angular.io/guide/styleguide#directive-selectors
|
||||||
exportAs: 'overlayScrollbars',
|
|
||||||
})
|
})
|
||||||
export class OverlayScrollbarsDirective implements OnChanges {
|
export class OverlayScrollbarsDirective implements OnChanges {
|
||||||
private instanceRef: OverlayScrollbars | null = null;
|
private instanceRef: OverlayScrollbars | null = null;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import type { EventListenerMap } from 'overlayscrollbars';
|
|||||||
@Component({
|
@Component({
|
||||||
template: `
|
template: `
|
||||||
<div
|
<div
|
||||||
[overlay-scrollbars-component]
|
overlay-scrollbars
|
||||||
[options]="options"
|
[options]="options"
|
||||||
[events]="events"
|
[events]="events"
|
||||||
(osInitialized)="onInitialized($event)"
|
(osInitialized)="onInitialized($event)"
|
||||||
@@ -70,6 +70,19 @@ class Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
template: `
|
||||||
|
<span overlay-scrollbars #span>span</span>
|
||||||
|
<overlay-scrollbars #os>span</overlay-scrollbars>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
class TestTag {
|
||||||
|
@ViewChild('span', { read: OverlayScrollbarsComponent })
|
||||||
|
spanRef?: OverlayScrollbarsComponent;
|
||||||
|
@ViewChild('os', { read: OverlayScrollbarsComponent })
|
||||||
|
osRef?: OverlayScrollbarsComponent;
|
||||||
|
}
|
||||||
|
|
||||||
describe('OverlayscrollbarsNgxComponent', () => {
|
describe('OverlayscrollbarsNgxComponent', () => {
|
||||||
let component: OverlayScrollbarsComponent;
|
let component: OverlayScrollbarsComponent;
|
||||||
let fixture: ComponentFixture<OverlayScrollbarsComponent>;
|
let fixture: ComponentFixture<OverlayScrollbarsComponent>;
|
||||||
@@ -77,7 +90,7 @@ describe('OverlayscrollbarsNgxComponent', () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
...new OverlayscrollbarsModule(),
|
...new OverlayscrollbarsModule(),
|
||||||
declarations: [OverlayScrollbarsComponent, OverlayScrollbarsDirective, Test],
|
declarations: [OverlayScrollbarsComponent, OverlayScrollbarsDirective, Test, TestTag],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|
||||||
fixture = TestBed.createComponent(OverlayScrollbarsComponent);
|
fixture = TestBed.createComponent(OverlayScrollbarsComponent);
|
||||||
@@ -349,4 +362,25 @@ describe('OverlayscrollbarsNgxComponent', () => {
|
|||||||
expect(onDestroyed).toHaveBeenCalledTimes(1);
|
expect(onDestroyed).toHaveBeenCalledTimes(1);
|
||||||
expect(onDestroyed).toHaveBeenCalledWith([jasmine.any(Object), jasmine.any(Boolean)]);
|
expect(onDestroyed).toHaveBeenCalledWith([jasmine.any(Object), jasmine.any(Boolean)]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('has correct tags', async () => {
|
||||||
|
const testFixture = TestBed.createComponent(TestTag);
|
||||||
|
const testInstance = testFixture.componentInstance;
|
||||||
|
|
||||||
|
testFixture.detectChanges();
|
||||||
|
|
||||||
|
const osRef = testInstance.osRef!;
|
||||||
|
const spanRef = testInstance.spanRef!;
|
||||||
|
|
||||||
|
expect(osRef).toBeDefined();
|
||||||
|
expect(spanRef).toBeDefined();
|
||||||
|
|
||||||
|
expect(OverlayScrollbars.valid(osRef.instance())).toBe(true);
|
||||||
|
expect(OverlayScrollbars.valid(spanRef.instance())).toBe(true);
|
||||||
|
|
||||||
|
testFixture.destroy();
|
||||||
|
|
||||||
|
expect(OverlayScrollbars.valid(osRef.instance())).toBe(false);
|
||||||
|
expect(OverlayScrollbars.valid(spanRef.instance())).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -90,6 +90,22 @@ It has three optional properties: `element`, `options` and `events`.
|
|||||||
/>
|
/>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Events
|
||||||
|
|
||||||
|
Additionally to the `events` property the `OverlayScrollbarsComponent` emits "native" Vue events. To prevent name collisions with DOM events, the events are prefixed with `os`. It doesn't matter whether you use the `events` property, the Vue events or both.
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// example usage
|
||||||
|
<template>
|
||||||
|
<OverlayScrollbarsComponent
|
||||||
|
@os-initialized="onInitialized"
|
||||||
|
@os-updated="onUpdated"
|
||||||
|
@os-destroyed="onDestroyed"
|
||||||
|
@os-scroll="onScroll"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
### Ref
|
### Ref
|
||||||
|
|
||||||
The `ref` of the `OverlayScrollbarsComponent` will give you an object with which you can access the OverlayScrollbars `instance` and the root `element` of the component.
|
The `ref` of the `OverlayScrollbarsComponent` will give you an object with which you can access the OverlayScrollbars `instance` and the root `element` of the component.
|
||||||
|
|||||||
@@ -8,9 +8,8 @@ import type {
|
|||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
import type { EventListeners, EventListenerMap } from 'overlayscrollbars';
|
import type { EventListeners, EventListenerMap } from 'overlayscrollbars';
|
||||||
|
|
||||||
type EmitName<N extends keyof EventListenerMap = keyof EventListenerMap> = `os${Capitalize<N>}`;
|
|
||||||
type EmitEventsMap = {
|
type EmitEventsMap = {
|
||||||
[N in keyof EventListenerMap]: EmitName<N>;
|
[N in keyof EventListenerMap]: `os${Capitalize<N>}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const emitEvents: EmitEventsMap = {
|
const emitEvents: EmitEventsMap = {
|
||||||
@@ -27,12 +26,12 @@ const props = defineProps({
|
|||||||
options: { type: Object as PropType<OverlayScrollbarsComponentProps['options']> },
|
options: { type: Object as PropType<OverlayScrollbarsComponentProps['options']> },
|
||||||
events: { type: Object as PropType<OverlayScrollbarsComponentProps['events']> },
|
events: { type: Object as PropType<OverlayScrollbarsComponentProps['events']> },
|
||||||
});
|
});
|
||||||
const emits = defineEmits({
|
const emits = defineEmits<{
|
||||||
osInitialized: (...args: EventListenerMap['initialized']) => true,
|
(name: 'osInitialized', ...args: EventListenerMap['initialized']): void;
|
||||||
osUpdated: (...args: EventListenerMap['updated']) => true,
|
(name: 'osUpdated', ...args: EventListenerMap['updated']): void;
|
||||||
osDestroyed: (...args: EventListenerMap['destroyed']) => true,
|
(name: 'osDestroyed', ...args: EventListenerMap['destroyed']): void;
|
||||||
osScroll: (...args: EventListenerMap['scroll']) => true,
|
(name: 'osScroll', ...args: EventListenerMap['scroll']): void;
|
||||||
} as Record<EmitName, any>);
|
}>();
|
||||||
|
|
||||||
const elementRef = shallowRef<HTMLElement | null>(null);
|
const elementRef = shallowRef<HTMLElement | null>(null);
|
||||||
const slotRef = shallowRef<HTMLElement | null>(null);
|
const slotRef = shallowRef<HTMLElement | null>(null);
|
||||||
@@ -73,8 +72,12 @@ watch(
|
|||||||
).reduce<EventListeners>(<N extends keyof EventListeners>(obj: EventListeners, name: N) => {
|
).reduce<EventListeners>(<N extends keyof EventListeners>(obj: EventListeners, name: N) => {
|
||||||
const eventListener = currEvents[name];
|
const eventListener = currEvents[name];
|
||||||
obj[name] = [
|
obj[name] = [
|
||||||
// @ts-ignore
|
(...args: EventListenerMap[N]) =>
|
||||||
(...args: EventListenerMap[N]) => emits(emitEvents[name], ...args),
|
emits(
|
||||||
|
emitEvents[name],
|
||||||
|
// @ts-ignore
|
||||||
|
...args
|
||||||
|
),
|
||||||
...(Array.isArray(eventListener) ? eventListener : [eventListener]).filter(Boolean),
|
...(Array.isArray(eventListener) ? eventListener : [eventListener]).filter(Boolean),
|
||||||
];
|
];
|
||||||
return obj;
|
return obj;
|
||||||
|
|||||||
Reference in New Issue
Block a user