mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-05-17 04:19:40 +03:00
add emits to vue
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent, watchPostEffect, onBeforeUnmount, shallowRef, toRef } from 'vue';
|
||||
import { defineComponent, watch, watchPostEffect, ref, shallowRef, toRefs, onUnmounted } from 'vue';
|
||||
import { useOverlayScrollbars } from './useOverlayScrollbars';
|
||||
import type {
|
||||
OverlayScrollbarsComponentProps,
|
||||
OverlayScrollbarsComponentRef,
|
||||
} from './OverlayScrollbarsComponent.types';
|
||||
import type { PropType } from 'vue';
|
||||
import type { EventListeners, EventListenerMap } from 'overlayscrollbars';
|
||||
|
||||
const emitNames: (keyof EventListenerMap)[] = ['initialized', 'updated', 'destroyed', 'scroll'];
|
||||
|
||||
export default defineComponent({
|
||||
name: 'OverlayScrollbars',
|
||||
@@ -17,11 +20,18 @@ export default defineComponent({
|
||||
options: { type: Object as PropType<OverlayScrollbarsComponentProps['options']> },
|
||||
events: { type: Object as PropType<OverlayScrollbarsComponentProps['events']> },
|
||||
},
|
||||
setup(props, { expose }) {
|
||||
emits: {
|
||||
initialized: (...args: EventListenerMap['initialized']) => true,
|
||||
updated: (...args: EventListenerMap['updated']) => true,
|
||||
destroyed: (...args: EventListenerMap['destroyed']) => true,
|
||||
scroll: (...args: EventListenerMap['scroll']) => true,
|
||||
},
|
||||
setup(props, { expose, emit }) {
|
||||
const elementRef = shallowRef<HTMLElement | null>(null);
|
||||
const slotRef = shallowRef<HTMLElement | null>(null);
|
||||
const [initialize, instance] = useOverlayScrollbars(props);
|
||||
|
||||
const combinedEvents = ref<EventListeners>();
|
||||
const { element, options, events } = toRefs(props);
|
||||
const [initialize, instance] = useOverlayScrollbars({ options, events: combinedEvents });
|
||||
const exposed: OverlayScrollbarsComponentRef = {
|
||||
instance,
|
||||
element: () => elementRef.value,
|
||||
@@ -29,6 +39,26 @@ export default defineComponent({
|
||||
|
||||
expose(exposed);
|
||||
|
||||
watch(
|
||||
() => events.value,
|
||||
(rawCurrEvents) => {
|
||||
const currEvents = rawCurrEvents || {};
|
||||
combinedEvents.value = emitNames.reduce<EventListeners>(
|
||||
<N extends keyof EventListeners>(obj: EventListeners, name: N) => {
|
||||
const eventListener = currEvents[name];
|
||||
obj[name] = [
|
||||
// @ts-ignore
|
||||
(...args: EventListenerMap[N]) => emit(name, ...args),
|
||||
...(Array.isArray(eventListener) ? eventListener : [eventListener]).filter(Boolean),
|
||||
];
|
||||
return obj;
|
||||
},
|
||||
{}
|
||||
);
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
watchPostEffect((onCleanup) => {
|
||||
const { value: elm } = elementRef;
|
||||
const { value: slotElm } = slotRef;
|
||||
@@ -45,9 +75,9 @@ export default defineComponent({
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => instance()?.destroy());
|
||||
onUnmounted(() => instance()?.destroy());
|
||||
|
||||
return { elementRef, slotRef, element: toRef(props, 'element') };
|
||||
return { elementRef, slotRef, element };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -46,14 +46,10 @@ export const useOverlayScrollbars = (
|
||||
|
||||
watch(
|
||||
() => unref(paramsRef.value.options),
|
||||
() => {
|
||||
const {
|
||||
value: { options: rawOptions },
|
||||
} = paramsRef;
|
||||
(options) => {
|
||||
const {
|
||||
value: { instance },
|
||||
} = variables;
|
||||
const options = unref(rawOptions);
|
||||
|
||||
variables.value.options = options;
|
||||
|
||||
@@ -66,14 +62,10 @@ export const useOverlayScrollbars = (
|
||||
|
||||
watch(
|
||||
() => unref(paramsRef.value.events),
|
||||
() => {
|
||||
const {
|
||||
value: { events: rawEvents },
|
||||
} = paramsRef;
|
||||
(events) => {
|
||||
const {
|
||||
value: { instance },
|
||||
} = variables;
|
||||
const events = unref(rawEvents);
|
||||
|
||||
variables.value.events = events;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { onMounted, ref, toRefs } from 'vue';
|
||||
import { describe, test, expect, vitest } from 'vitest';
|
||||
import { OverlayScrollbars } from 'overlayscrollbars';
|
||||
import { render, screen } from '@testing-library/vue';
|
||||
import { fireEvent, render, screen } from '@testing-library/vue';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { OverlayScrollbarsComponent } from '~/overlayscrollbars-vue';
|
||||
|
||||
@@ -254,4 +254,26 @@ describe('OverlayScrollbarsComponent', () => {
|
||||
expect(onUpdatedInitial).toHaveBeenCalledTimes(3);
|
||||
expect(onUpdated).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
test('emits', async () => {
|
||||
const { emitted, unmount, container } = render(OverlayScrollbarsComponent);
|
||||
|
||||
expect(emitted('initialized')).toEqual([[expect.any(Object)]]);
|
||||
expect(emitted('updated')).toEqual([[expect.any(Object), expect.any(Object)]]);
|
||||
expect(emitted('scroll')).toBeUndefined();
|
||||
expect(emitted('destroyed')).toBeUndefined();
|
||||
|
||||
container.querySelectorAll('*').forEach((e) => {
|
||||
fireEvent.scroll(e);
|
||||
});
|
||||
|
||||
await Promise.resolve();
|
||||
|
||||
expect(emitted('scroll')).toEqual([[expect.any(Object), expect.any(UIEvent)]]);
|
||||
expect(emitted('destroyed')).toBeUndefined();
|
||||
|
||||
unmount();
|
||||
|
||||
expect(emitted('destroyed')).toEqual([[expect.any(Object), false]]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user