mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-05-25 09:14:07 +03:00
117 lines
4.6 KiB
TypeScript
117 lines
4.6 KiB
TypeScript
import { isFunction, isHTMLElement, isNull, isUndefined } from 'support';
|
|
import type { StructureInitialization } from 'setups/structureSetup';
|
|
import type { ScrollbarsInitialization } from 'setups/scrollbarsSetup';
|
|
import { getEnvironment } from 'environment';
|
|
import { DeepPartial } from 'typings';
|
|
import { StructureSetupElementsObj } from 'setups/structureSetup/structureSetup.elements';
|
|
|
|
type StaticInitialization = HTMLElement | false | null;
|
|
type DynamicInitialization = HTMLElement | boolean | null;
|
|
|
|
export type Initialization = StructureInitialization &
|
|
ScrollbarsInitialization & {
|
|
cancel: {
|
|
nativeScrollbarsOverlaid: boolean;
|
|
body: boolean | null;
|
|
};
|
|
};
|
|
|
|
export type InitializationTargetElement = HTMLElement | HTMLTextAreaElement;
|
|
|
|
export type InitializationTargetObject = DeepPartial<Initialization> & {
|
|
target: InitializationTargetElement;
|
|
};
|
|
|
|
export type InitializationTarget = InitializationTargetElement | InitializationTargetObject;
|
|
|
|
/**
|
|
* Static elements MUST be present.
|
|
* With false, null or undefined the element will be generated, otherwise the specified element is taken.
|
|
*/
|
|
export type StaticInitializationElement<Args extends any[]> =
|
|
| ((...args: Args) => StaticInitialization)
|
|
| StaticInitialization;
|
|
|
|
/**
|
|
* Dynamic element CAN be present.
|
|
* If its a element the element will be taken as the repsective element.
|
|
* With true the element will be generated.
|
|
* With false, null or undefined the element won't be generated.
|
|
*/
|
|
export type DynamicInitializationElement<Args extends any[]> =
|
|
| ((...args: Args) => DynamicInitialization)
|
|
| DynamicInitialization;
|
|
|
|
export type FallbackInitializtationElement<
|
|
InitElm extends StaticInitializationElement<any> | DynamicInitializationElement<any>
|
|
> = Extract<InitElm, (...args: any[]) => any> extends (...args: infer P) => any
|
|
? (...args: P) => HTMLElement
|
|
: never;
|
|
|
|
const resolveInitialization = <T>(value: any, args: any): T =>
|
|
isFunction(value) ? value.apply(0, args) : value;
|
|
|
|
export const staticInitializationElement = <T extends StaticInitializationElement<any>>(
|
|
args: Parameters<Extract<T, (...initializationFnArgs: any[]) => any>>,
|
|
fallbackStaticInitializationElement: FallbackInitializtationElement<T>,
|
|
defaultStaticInitializationElementStrategy: T,
|
|
staticInitializationElementValue?: T
|
|
): HTMLElement => {
|
|
const staticInitialization = isUndefined(staticInitializationElementValue)
|
|
? defaultStaticInitializationElementStrategy
|
|
: staticInitializationElementValue;
|
|
const resolvedInitialization = resolveInitialization<StaticInitialization>(
|
|
staticInitialization,
|
|
args
|
|
);
|
|
return resolvedInitialization || fallbackStaticInitializationElement();
|
|
};
|
|
|
|
export const dynamicInitializationElement = <T extends DynamicInitializationElement<any>>(
|
|
args: Parameters<Extract<T, (...initializationFnArgs: any[]) => any>>,
|
|
fallbackDynamicInitializationElement: FallbackInitializtationElement<T>,
|
|
defaultDynamicInitializationElementStrategy: T,
|
|
dynamicInitializationElementValue?: T
|
|
): HTMLElement | false => {
|
|
const dynamicInitialization = isUndefined(dynamicInitializationElementValue)
|
|
? defaultDynamicInitializationElementStrategy
|
|
: dynamicInitializationElementValue;
|
|
const resolvedInitialization = resolveInitialization<DynamicInitialization>(
|
|
dynamicInitialization,
|
|
args
|
|
);
|
|
return (
|
|
!!resolvedInitialization &&
|
|
(isHTMLElement(resolvedInitialization)
|
|
? resolvedInitialization
|
|
: fallbackDynamicInitializationElement())
|
|
);
|
|
};
|
|
|
|
export const cancelInitialization = (
|
|
cancelInitializationValue: DeepPartial<Initialization['cancel']> | false | null | undefined,
|
|
structureSetupElements: StructureSetupElementsObj
|
|
): boolean => {
|
|
const { nativeScrollbarsOverlaid, body } = cancelInitializationValue || {};
|
|
const { _isBody } = structureSetupElements;
|
|
const { _getDefaultInitialization, _nativeScrollbarsOverlaid, _nativeScrollbarsHiding } =
|
|
getEnvironment();
|
|
const { nativeScrollbarsOverlaid: defaultNativeScrollbarsOverlaid, body: defaultbody } =
|
|
_getDefaultInitialization().cancel;
|
|
|
|
const resolvedNativeScrollbarsOverlaid =
|
|
nativeScrollbarsOverlaid ?? defaultNativeScrollbarsOverlaid;
|
|
const resolvedDocumentScrollingElement = isUndefined(body) ? defaultbody : body;
|
|
|
|
const finalNativeScrollbarsOverlaid =
|
|
(_nativeScrollbarsOverlaid.x || _nativeScrollbarsOverlaid.y) &&
|
|
resolvedNativeScrollbarsOverlaid;
|
|
const finalDocumentScrollingElement =
|
|
_isBody &&
|
|
(isNull(resolvedDocumentScrollingElement)
|
|
? !_nativeScrollbarsHiding
|
|
: resolvedDocumentScrollingElement);
|
|
|
|
return !!finalNativeScrollbarsOverlaid || !!finalDocumentScrollingElement;
|
|
};
|