diff --git a/packages/overlayscrollbars/src/eventListeners.ts b/packages/overlayscrollbars/src/eventListeners.ts index 4895823..ef253f7 100644 --- a/packages/overlayscrollbars/src/eventListeners.ts +++ b/packages/overlayscrollbars/src/eventListeners.ts @@ -4,6 +4,9 @@ import type { Options } from '~/options'; import type { EventListeners as GeneralEventListeners, EventListener as GeneralEventListener, + AddEvent as GeneralAddEvent, + RemoveEvent as GeneralRemoveEvent, + TriggerEvent as GeneralTriggerEvent, } from '~/support/eventListeners'; /** @@ -45,6 +48,8 @@ export type EventListenerMap = { updated: [instance: OverlayScrollbars, onUpdatedArgs: OnUpdatedEventListenerArgs]; /** Triggered after all elements, observers and events are destroyed. */ destroyed: [instance: OverlayScrollbars, canceled: boolean]; + /** Triggered on scroll. */ + scroll: [instance: OverlayScrollbars, event: Event]; }; /** @@ -61,3 +66,12 @@ export type EventListener = GeneralEventListen EventListenerMap, N >; + +/** A function which adds event listeners. */ +export type AddEvent = GeneralAddEvent; + +/** A function which removes event listeners. */ +export type RemoveEvent = GeneralRemoveEvent; + +/** A function which triggers event listeners. */ +export type TriggerEvent = GeneralTriggerEvent; diff --git a/packages/overlayscrollbars/src/overlayscrollbars.ts b/packages/overlayscrollbars/src/overlayscrollbars.ts index 74c6aae..c765b9b 100644 --- a/packages/overlayscrollbars/src/overlayscrollbars.ts +++ b/packages/overlayscrollbars/src/overlayscrollbars.ts @@ -262,7 +262,9 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = ( const [updateScrollbars, scrollbarsState, destroyScrollbars] = createScrollbarsSetup( target, currentOptions, - structureState + structureState, + // eslint-disable-next-line @typescript-eslint/no-use-before-define + (scrollEvent) => triggerEvent('scroll', [instance, scrollEvent]) ); const update = (changedOptions: DeepPartial, force?: boolean): boolean => updateStructure(changedOptions, !!force); diff --git a/packages/overlayscrollbars/src/setups/scrollbarsSetup/scrollbarsSetup.ts b/packages/overlayscrollbars/src/setups/scrollbarsSetup/scrollbarsSetup.ts index ab89b08..f24edd2 100644 --- a/packages/overlayscrollbars/src/setups/scrollbarsSetup/scrollbarsSetup.ts +++ b/packages/overlayscrollbars/src/setups/scrollbarsSetup/scrollbarsSetup.ts @@ -36,7 +36,8 @@ export interface ScrollbarsSetupStaticState { export const createScrollbarsSetup = ( target: InitializationTarget, options: ReadonlyOptions, - structureSetupState: (() => StructureSetupState) & StructureSetupStaticState + structureSetupState: (() => StructureSetupState) & StructureSetupStaticState, + onScroll: (event: Event) => void ): Setup< ScrollbarsSetupState, ScrollbarsSetupStaticState, @@ -132,7 +133,7 @@ export const createScrollbarsSetup = ( }); }); }), - on(_scrollEventElement, 'scroll', () => { + on(_scrollEventElement, 'scroll', (event) => { requestScrollAnimationFrame(() => { _refreshScrollbarsHandleOffset(structureSetupState()); @@ -142,6 +143,8 @@ export const createScrollbarsSetup = ( }); }); + onScroll(event); + _viewportIsTarget && styleHorizontal(styleScrollbarPosition); _viewportIsTarget && styleVertical(styleScrollbarPosition); }), diff --git a/packages/overlayscrollbars/src/support/eventListeners.ts b/packages/overlayscrollbars/src/support/eventListeners.ts index 68771f1..ed4bc21 100644 --- a/packages/overlayscrollbars/src/support/eventListeners.ts +++ b/packages/overlayscrollbars/src/support/eventListeners.ts @@ -10,6 +10,35 @@ export type EventListeners> = { [K in keyof EventMap]?: EventListener | EventListener[]; }; +export type RemoveEvent> = { + (name?: N, listener?: EventListener): void; + (name?: N, listener?: EventListener[]): void; + ( + name?: N, + listener?: EventListener | EventListener[] + ): void; +}; + +export type AddEvent> = { + (eventListeners: EventListeners): () => void; + (name: N, listener: EventListener): () => void; + (name: N, listener: EventListener[]): () => void; + ( + nameOrEventListeners: N | EventListeners, + listener?: EventListener | EventListener[] + ): () => void; +}; + +export type TriggerEvent> = { + (name: N, args?: EventMap[N]): void; +}; + +export type EventListenerHub> = [ + AddEvent, + RemoveEvent, + TriggerEvent +]; + const manageListener = , N extends keyof EventMap>( callback: (listener?: EventListener) => void, listener?: EventListener | EventListener[] @@ -19,33 +48,10 @@ const manageListener = , N extends keyof export const createEventListenerHub = >( initialEventListeners?: EventListeners -) => { - // eslint-disable-next-line @typescript-eslint/no-shadow - type EventListener = (...args: EventMap[N]) => void; - type RemoveEvent = { - (name?: N, listener?: EventListener): void; - (name?: N, listener?: EventListener[]): void; - (name?: N, listener?: EventListener | EventListener[]): void; - }; - type AddEvent = { - (eventListeners: EventListeners): () => void; - (name: N, listener: EventListener): () => void; - (name: N, listener: EventListener[]): () => void; - ( - nameOrEventListeners: N | EventListeners, - listener?: EventListener | EventListener[] - ): () => void; - }; - type TriggerEvent = { - (name: N, args?: EventMap[N]): void; - }; +): EventListenerHub => { + const events = new Map>>(); - const events = new Map>>(); - - const removeEvent: RemoveEvent = ( - name?: N, - listener?: EventListener | EventListener[] - ): void => { + const removeEvent: RemoveEvent = (name, listener) => { if (name) { const eventSet = events.get(name); manageListener((currListener) => { @@ -61,10 +67,7 @@ export const createEventListenerHub = >( } }; - const addEvent: AddEvent = ( - nameOrEventListeners: N | EventListeners, - listener?: EventListener | EventListener[] - ): (() => void) => { + const addEvent: AddEvent = ((nameOrEventListeners, listener) => { if (isString(nameOrEventListeners)) { const eventSet = events.get(nameOrEventListeners) || new Set(); events.set(nameOrEventListeners, eventSet); @@ -83,12 +86,9 @@ export const createEventListenerHub = >( }); return runEachAndClear.bind(0, offFns); - }; + }) as AddEvent; // sorry! - const triggerEvent: TriggerEvent = ( - name: N, - args?: EventMap[N] - ): void => { + const triggerEvent: TriggerEvent = (name, args) => { const eventSet = events.get(name); each(from(eventSet), (event) => { @@ -102,5 +102,5 @@ export const createEventListenerHub = >( addEvent(initialEventListeners || {}); - return [addEvent, removeEvent, triggerEvent] as [AddEvent, RemoveEvent, TriggerEvent]; + return [addEvent, removeEvent, triggerEvent]; };