mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-05-28 00:14:07 +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/react": "^18.0.21",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"overlayscrollbars-react": "file:../../packages/overlayscrollbars-react",
|
||||
"overlayscrollbars-react": "file:../../packages/overlayscrollbars-react/dist",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "5.0.1",
|
||||
|
||||
Generated
+12
-7
@@ -6,7 +6,7 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"overlayscrollbars-vue": "file:../../packages/overlayscrollbars-vue",
|
||||
"overlayscrollbars-vue": "file:../../packages/overlayscrollbars-vue/dist",
|
||||
"vue": "^3.2.38"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -19,6 +19,14 @@
|
||||
"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": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
||||
@@ -1481,11 +1489,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/overlayscrollbars-vue": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "file:../../packages/overlayscrollbars-vue",
|
||||
"peerDependencies": {
|
||||
"vue": "^3.2.25"
|
||||
}
|
||||
"resolved": "../../packages/overlayscrollbars-vue/dist",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
@@ -2741,7 +2746,7 @@
|
||||
"dev": true
|
||||
},
|
||||
"overlayscrollbars-vue": {
|
||||
"version": "0.4.0",
|
||||
"version": "file:../../packages/overlayscrollbars-vue/dist",
|
||||
"requires": {}
|
||||
},
|
||||
"path-parse": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"overlayscrollbars-vue": "file:../../packages/overlayscrollbars-vue",
|
||||
"overlayscrollbars-vue": "file:../../packages/overlayscrollbars-vue/dist",
|
||||
"vue": "^3.2.38"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue';
|
||||
<img alt="Vue logo" class="logo" src="./assets/logo.svg" width="125" height="125" />
|
||||
|
||||
<div class="wrapper">
|
||||
<OverlayScrollbarsComponent msg="hi" />
|
||||
<OverlayScrollbarsComponent />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
+4
-4
@@ -77,10 +77,10 @@
|
||||
"build:vue": "npm run build --workspace=overlayscrollbars-vue",
|
||||
"build:ngx": "npm run build --workspace=overlayscrollbars-ngx",
|
||||
"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:vue": "npm run build:vue && cd examples/vue && npm i --install-links && npm run dev",
|
||||
"example:ngx": "npm run build:ngx && cd examples/angular && npm i --install-links && npm run start",
|
||||
"example:svelte": "npm run build:svelte && cd examples/svelte && npm i --install-links && npm run dev",
|
||||
"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 && npm run dev",
|
||||
"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 && npm run dev",
|
||||
"lint": "eslint ./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}",
|
||||
|
||||
@@ -10,8 +10,8 @@ import {
|
||||
AfterViewInit,
|
||||
} from '@angular/core';
|
||||
import { OverlayScrollbars } from 'overlayscrollbars';
|
||||
import { OverlayScrollbarsDirective } from '~/overlayscrollbars.directive';
|
||||
import type { PartialOptions, EventListeners, EventListenerMap } from 'overlayscrollbars';
|
||||
import { OverlayScrollbarsDirective } from './overlayscrollbars.directive';
|
||||
|
||||
const mergeEventListeners = (emits: EventListeners, events: EventListeners) =>
|
||||
(Object.keys(emits) as (keyof EventListeners)[]).reduce<EventListeners>(
|
||||
@@ -29,17 +29,12 @@ const mergeEventListeners = (emits: EventListeners, events: EventListeners) =>
|
||||
);
|
||||
|
||||
@Component({
|
||||
selector: '[overlay-scrollbars-component]', // https://angular.io/guide/styleguide#component-selectors
|
||||
exportAs: 'overlayScrollbars',
|
||||
selector: 'overlay-scrollbars, [overlay-scrollbars]', // https://angular.io/guide/styleguide#component-selectors
|
||||
host: { 'data-overlayscrollbars': '' },
|
||||
template: `<div
|
||||
#content
|
||||
[overlayScrollbarsDirective]
|
||||
[options]="options"
|
||||
[events]="mergeEvents(events)"
|
||||
>
|
||||
template: `<div overlayScrollbars [options]="options" [events]="mergeEvents(events)" #content>
|
||||
<ng-content></ng-content>
|
||||
</div>`,
|
||||
styles: [':host { display: block; }'],
|
||||
})
|
||||
export class OverlayScrollbarsComponent implements OnDestroy, AfterViewInit {
|
||||
@Input('options')
|
||||
@@ -91,7 +86,7 @@ export class OverlayScrollbarsComponent implements OnDestroy, AfterViewInit {
|
||||
this.osDirective?.instance()!.destroy();
|
||||
}
|
||||
|
||||
private mergeEvents(originalEvents: OverlayScrollbarsComponent['events']) {
|
||||
mergeEvents(originalEvents: OverlayScrollbarsComponent['events']) {
|
||||
return mergeEventListeners(
|
||||
{
|
||||
initialized: (...args) => this.onInitialized.emit(args),
|
||||
|
||||
@@ -5,8 +5,7 @@ import type { InitializationTarget } from 'overlayscrollbars';
|
||||
import type { OverlayScrollbarsComponent } from '~/overlayscrollbars.component';
|
||||
|
||||
@Directive({
|
||||
selector: '[overlayScrollbarsDirective]', // https://angular.io/guide/styleguide#component-selectors
|
||||
exportAs: 'overlayScrollbars',
|
||||
selector: '[overlayScrollbars]', // https://angular.io/guide/styleguide#directive-selectors
|
||||
})
|
||||
export class OverlayScrollbarsDirective implements OnChanges {
|
||||
private instanceRef: OverlayScrollbars | null = null;
|
||||
|
||||
@@ -12,7 +12,7 @@ import type { EventListenerMap } from 'overlayscrollbars';
|
||||
@Component({
|
||||
template: `
|
||||
<div
|
||||
[overlay-scrollbars-component]
|
||||
overlay-scrollbars
|
||||
[options]="options"
|
||||
[events]="events"
|
||||
(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', () => {
|
||||
let component: OverlayScrollbarsComponent;
|
||||
let fixture: ComponentFixture<OverlayScrollbarsComponent>;
|
||||
@@ -77,7 +90,7 @@ describe('OverlayscrollbarsNgxComponent', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
...new OverlayscrollbarsModule(),
|
||||
declarations: [OverlayScrollbarsComponent, OverlayScrollbarsDirective, Test],
|
||||
declarations: [OverlayScrollbarsComponent, OverlayScrollbarsDirective, Test, TestTag],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(OverlayScrollbarsComponent);
|
||||
@@ -349,4 +362,25 @@ describe('OverlayscrollbarsNgxComponent', () => {
|
||||
expect(onDestroyed).toHaveBeenCalledTimes(1);
|
||||
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
|
||||
|
||||
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 { EventListeners, EventListenerMap } from 'overlayscrollbars';
|
||||
|
||||
type EmitName<N extends keyof EventListenerMap = keyof EventListenerMap> = `os${Capitalize<N>}`;
|
||||
type EmitEventsMap = {
|
||||
[N in keyof EventListenerMap]: EmitName<N>;
|
||||
[N in keyof EventListenerMap]: `os${Capitalize<N>}`;
|
||||
};
|
||||
|
||||
const emitEvents: EmitEventsMap = {
|
||||
@@ -27,12 +26,12 @@ const props = defineProps({
|
||||
options: { type: Object as PropType<OverlayScrollbarsComponentProps['options']> },
|
||||
events: { type: Object as PropType<OverlayScrollbarsComponentProps['events']> },
|
||||
});
|
||||
const emits = defineEmits({
|
||||
osInitialized: (...args: EventListenerMap['initialized']) => true,
|
||||
osUpdated: (...args: EventListenerMap['updated']) => true,
|
||||
osDestroyed: (...args: EventListenerMap['destroyed']) => true,
|
||||
osScroll: (...args: EventListenerMap['scroll']) => true,
|
||||
} as Record<EmitName, any>);
|
||||
const emits = defineEmits<{
|
||||
(name: 'osInitialized', ...args: EventListenerMap['initialized']): void;
|
||||
(name: 'osUpdated', ...args: EventListenerMap['updated']): void;
|
||||
(name: 'osDestroyed', ...args: EventListenerMap['destroyed']): void;
|
||||
(name: 'osScroll', ...args: EventListenerMap['scroll']): void;
|
||||
}>();
|
||||
|
||||
const elementRef = 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) => {
|
||||
const eventListener = currEvents[name];
|
||||
obj[name] = [
|
||||
// @ts-ignore
|
||||
(...args: EventListenerMap[N]) => emits(emitEvents[name], ...args),
|
||||
(...args: EventListenerMap[N]) =>
|
||||
emits(
|
||||
emitEvents[name],
|
||||
// @ts-ignore
|
||||
...args
|
||||
),
|
||||
...(Array.isArray(eventListener) ? eventListener : [eventListener]).filter(Boolean),
|
||||
];
|
||||
return obj;
|
||||
|
||||
Reference in New Issue
Block a user