mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-08 23:52:28 +03:00
implement OverlayScrollbarsComponent for react
This commit is contained in:
@@ -1,24 +1,75 @@
|
||||
export interface OverlayScrollbarsComponentProps {
|
||||
element?: string;
|
||||
options?: {};
|
||||
events?: {};
|
||||
import { forwardRef, useEffect, useRef, useImperativeHandle } from 'react';
|
||||
import { OverlayScrollbars } from 'overlayscrollbars';
|
||||
import type { PartialOptions, EventListeners } from 'overlayscrollbars';
|
||||
import type { ComponentPropsWithoutRef, ElementRef, ForwardedRef } from 'react';
|
||||
|
||||
export type OverlayScrollbarsComponentProps<T extends keyof JSX.IntrinsicElements = 'div'> =
|
||||
ComponentPropsWithoutRef<T> & {
|
||||
element?: T;
|
||||
options?: PartialOptions;
|
||||
events?: EventListeners;
|
||||
};
|
||||
|
||||
export interface OverlayScrollbarsComponentRef<T extends keyof JSX.IntrinsicElements = 'div'> {
|
||||
osInstance(): OverlayScrollbars | null;
|
||||
osTarget(): ElementRef<T> | null;
|
||||
}
|
||||
|
||||
export const OverlayScrollbarsComponent = (props: OverlayScrollbarsComponentProps) => {
|
||||
const { msg } = props;
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<p>{msg}</p>
|
||||
<a
|
||||
className="App-link"
|
||||
href="https://reactjs.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Learn React
|
||||
</a>
|
||||
</header>
|
||||
</div>
|
||||
const OverlayScrollbarsComponent = <T extends keyof JSX.IntrinsicElements>(
|
||||
props: OverlayScrollbarsComponentProps<T>,
|
||||
ref: ForwardedRef<OverlayScrollbarsComponentRef<T>>
|
||||
) => {
|
||||
const { element = 'div', options, events, ...other } = props;
|
||||
const Tag = element;
|
||||
|
||||
const osTargetRef = useRef<ElementRef<T>>(null);
|
||||
const osInstanceRef = useRef<OverlayScrollbars | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const { current: target } = osTargetRef;
|
||||
if (target) {
|
||||
const instance = OverlayScrollbars(target as any, options || {});
|
||||
osInstanceRef.current = instance;
|
||||
|
||||
return () => instance.destroy();
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const { current: instance } = osInstanceRef;
|
||||
if (OverlayScrollbars.valid(instance) && options) {
|
||||
instance.options(options, true);
|
||||
}
|
||||
}, [options]);
|
||||
|
||||
useEffect(() => {
|
||||
const { current: instance } = osInstanceRef;
|
||||
if (OverlayScrollbars.valid(instance) && events) {
|
||||
return instance.on(events);
|
||||
}
|
||||
}, [events]);
|
||||
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => {
|
||||
return {
|
||||
osInstance: () => osInstanceRef.current,
|
||||
osTarget: () => osTargetRef.current,
|
||||
};
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
// @ts-ignore
|
||||
return <Tag data-overlayscrollbars="" {...other} ref={osTargetRef} />;
|
||||
};
|
||||
|
||||
const OverlayScrollbarsComponentForwardedRef = forwardRef(OverlayScrollbarsComponent) as <
|
||||
T extends keyof JSX.IntrinsicElements
|
||||
>(
|
||||
props: OverlayScrollbarsComponentProps<T> & {
|
||||
ref?: ForwardedRef<OverlayScrollbarsComponentRef<T>>;
|
||||
}
|
||||
) => ReturnType<typeof OverlayScrollbarsComponent>;
|
||||
|
||||
export { OverlayScrollbarsComponentForwardedRef as OverlayScrollbarsComponent };
|
||||
|
||||
Reference in New Issue
Block a user