mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-20 05:00:36 +03:00
112 lines
3.4 KiB
TypeScript
112 lines
3.4 KiB
TypeScript
import { OSTarget, OSInitializationObject, PartialOptions } from 'typings';
|
|
import { assignDeep, isEmptyObject, each, isFunction, keys, isHTMLElement } from 'support';
|
|
import { createStructureSetup, StructureSetup } from 'setups/structureSetup';
|
|
import { createScrollbarsSetup, ScrollbarsSetup } from 'setups/scrollbarsSetup';
|
|
import { createLifecycleHub } from 'lifecycles/lifecycleHub';
|
|
import { getOptionsDiff, OSOptions } from 'options';
|
|
import { getEnvironment } from 'environment';
|
|
import {
|
|
getPlugins,
|
|
addPlugin,
|
|
optionsValidationPluginName,
|
|
OSPlugin,
|
|
OptionsValidationPluginInstance,
|
|
} from 'plugins';
|
|
import { addInstance, getInstance, removeInstance } from 'instances';
|
|
import { createEventHub, AddEvent, RemoveEvent } from './events';
|
|
|
|
export interface OverlayScrollbarsStatic {
|
|
(
|
|
target: OSTarget | OSInitializationObject,
|
|
options?: PartialOptions<OSOptions>,
|
|
extensions?: any
|
|
): OverlayScrollbars;
|
|
|
|
extend(osPlugin: OSPlugin | OSPlugin[]): void;
|
|
}
|
|
|
|
export interface OverlayScrollbars {
|
|
options(): OSOptions;
|
|
options(newOptions?: PartialOptions<OSOptions>): OSOptions;
|
|
|
|
update(force?: boolean): void;
|
|
destroy(): void;
|
|
|
|
state(): any;
|
|
|
|
on: AddEvent;
|
|
off: RemoveEvent;
|
|
}
|
|
|
|
export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|
target: OSTarget | OSInitializationObject,
|
|
options?: PartialOptions<OSOptions>
|
|
): OverlayScrollbars => {
|
|
const instanceTarget = isHTMLElement(target) ? target : target.target;
|
|
const potentialInstance = getInstance(instanceTarget);
|
|
if (potentialInstance) {
|
|
return potentialInstance;
|
|
}
|
|
|
|
const { _getDefaultOptions } = getEnvironment();
|
|
const plugins = getPlugins();
|
|
const optionsValidationPlugin = plugins[
|
|
optionsValidationPluginName
|
|
] as OptionsValidationPluginInstance;
|
|
const validateOptions = (newOptions?: PartialOptions<OSOptions>) => {
|
|
const opts = newOptions || {};
|
|
const validate = optionsValidationPlugin && optionsValidationPlugin._;
|
|
return validate ? validate(opts, true) : opts;
|
|
};
|
|
const [addEvent, removeEvent, triggerEvent] = createEventHub();
|
|
const currentOptions: OSOptions = assignDeep({}, _getDefaultOptions(), validateOptions(options));
|
|
const structureSetup: StructureSetup = createStructureSetup(target);
|
|
const scrollbarsSetup: ScrollbarsSetup = createScrollbarsSetup(target, structureSetup);
|
|
const lifecycleHub = createLifecycleHub(
|
|
currentOptions,
|
|
triggerEvent,
|
|
structureSetup,
|
|
scrollbarsSetup
|
|
);
|
|
|
|
const instance: OverlayScrollbars = {
|
|
options(newOptions?: PartialOptions<OSOptions>) {
|
|
if (newOptions) {
|
|
const changedOptions = getOptionsDiff(currentOptions, validateOptions(newOptions));
|
|
|
|
if (!isEmptyObject(changedOptions)) {
|
|
assignDeep(currentOptions, changedOptions);
|
|
lifecycleHub._update(changedOptions);
|
|
}
|
|
}
|
|
return currentOptions;
|
|
},
|
|
on: addEvent,
|
|
off: removeEvent,
|
|
state: () => lifecycleHub._state(),
|
|
update(force?: boolean) {
|
|
lifecycleHub._update({}, force);
|
|
},
|
|
destroy: () => {
|
|
lifecycleHub._destroy();
|
|
removeInstance(instanceTarget);
|
|
removeEvent();
|
|
},
|
|
};
|
|
|
|
each(keys(plugins), (pluginName) => {
|
|
const pluginInstance = plugins[pluginName];
|
|
if (isFunction(pluginInstance)) {
|
|
pluginInstance(OverlayScrollbars, instance);
|
|
}
|
|
});
|
|
|
|
instance.update(true);
|
|
|
|
addInstance(instanceTarget, instance);
|
|
|
|
return instance;
|
|
};
|
|
|
|
OverlayScrollbars.extend = addPlugin;
|