mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-20 16:00:36 +03:00
improve code and public interface
This commit is contained in:
@@ -6,12 +6,12 @@ export const dataAttributeHost = 'data-overlayscrollbars';
|
|||||||
export const dataAttributeHostOverflowX = `${dataAttributeHost}-overflow-x`;
|
export const dataAttributeHostOverflowX = `${dataAttributeHost}-overflow-x`;
|
||||||
export const dataAttributeHostOverflowY = `${dataAttributeHost}-overflow-y`;
|
export const dataAttributeHostOverflowY = `${dataAttributeHost}-overflow-y`;
|
||||||
export const dataValueHostOverflowVisible = 'overflowVisible';
|
export const dataValueHostOverflowVisible = 'overflowVisible';
|
||||||
export const dataValueHostViewportScrollbarStyling = 'viewportStyled';
|
export const dataValueHostScrollbarHidden = 'scrollbarHidden';
|
||||||
export const classNamePadding = 'os-padding';
|
export const classNamePadding = 'os-padding';
|
||||||
export const classNameViewport = 'os-viewport';
|
export const classNameViewport = 'os-viewport';
|
||||||
export const classNameViewportArrange = `${classNameViewport}-arrange`;
|
export const classNameViewportArrange = `${classNameViewport}-arrange`;
|
||||||
export const classNameContent = 'os-content';
|
export const classNameContent = 'os-content';
|
||||||
export const classNameViewportScrollbarStyling = `${classNameViewport}-scrollbar-styled`;
|
export const classNameViewportScrollbarHidden = `${classNameViewport}-scrollbar-hidden`;
|
||||||
export const classNameOverflowVisible = `os-overflow-visible`;
|
export const classNameOverflowVisible = `os-overflow-visible`;
|
||||||
|
|
||||||
export const classNameSizeObserver = 'os-size-observer';
|
export const classNameSizeObserver = 'os-size-observer';
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ import {
|
|||||||
classNameEnvironment,
|
classNameEnvironment,
|
||||||
classNameEnvironmentFlexboxGlue,
|
classNameEnvironmentFlexboxGlue,
|
||||||
classNameEnvironmentFlexboxGlueMax,
|
classNameEnvironmentFlexboxGlueMax,
|
||||||
classNameViewportScrollbarStyling,
|
classNameViewportScrollbarHidden,
|
||||||
} from 'classnames';
|
} from 'classnames';
|
||||||
import { Options, defaultOptions } from 'options';
|
import { Options, defaultOptions } from 'options';
|
||||||
import { PartialOptions } from 'typings';
|
import { DeepPartial } from 'typings';
|
||||||
import { InitializationStrategy } from 'initialization';
|
import { DefaultInitialization } from 'initialization';
|
||||||
import { getPlugins, ScrollbarsHidingPluginInstance, scrollbarsHidingPluginName } from 'plugins';
|
import { getPlugins, ScrollbarsHidingPluginInstance, scrollbarsHidingPluginName } from 'plugins';
|
||||||
|
|
||||||
type EnvironmentEventMap = {
|
type EnvironmentEventMap = {
|
||||||
@@ -42,13 +42,13 @@ export interface InternalEnvironment {
|
|||||||
readonly _rtlScrollBehavior: { n: boolean; i: boolean };
|
readonly _rtlScrollBehavior: { n: boolean; i: boolean };
|
||||||
readonly _flexboxGlue: boolean;
|
readonly _flexboxGlue: boolean;
|
||||||
readonly _cssCustomProperties: boolean;
|
readonly _cssCustomProperties: boolean;
|
||||||
readonly _defaultInitializationStrategy: InitializationStrategy;
|
readonly _staticDefaultInitialization: DefaultInitialization;
|
||||||
readonly _defaultDefaultOptions: Options;
|
readonly _staticDefaultOptions: Options;
|
||||||
_addListener(listener: EventListener<EnvironmentEventMap, '_'>): () => void;
|
_addListener(listener: EventListener<EnvironmentEventMap, '_'>): () => void;
|
||||||
_getInitializationStrategy(): InitializationStrategy;
|
_getDefaultInitialization(): DefaultInitialization;
|
||||||
_setInitializationStrategy(newInitializationStrategy: Partial<InitializationStrategy>): void;
|
_setDefaultInitialization(newInitialization: DeepPartial<DefaultInitialization>): void;
|
||||||
_getDefaultOptions(): Options;
|
_getDefaultOptions(): Options;
|
||||||
_setDefaultOptions(newDefaultOptions: PartialOptions<Options>): void;
|
_setDefaultOptions(newDefaultOptions: DeepPartial<Options>): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
let environmentInstance: InternalEnvironment;
|
let environmentInstance: InternalEnvironment;
|
||||||
@@ -75,7 +75,7 @@ const getNativeScrollbarSize = (
|
|||||||
|
|
||||||
const getNativeScrollbarsHiding = (testElm: HTMLElement): boolean => {
|
const getNativeScrollbarsHiding = (testElm: HTMLElement): boolean => {
|
||||||
let result = false;
|
let result = false;
|
||||||
const revertClass = addClass(testElm, classNameViewportScrollbarStyling);
|
const revertClass = addClass(testElm, classNameViewportScrollbarHidden);
|
||||||
try {
|
try {
|
||||||
result =
|
result =
|
||||||
style(testElm, cssProperty('scrollbar-width')) === 'none' ||
|
style(testElm, cssProperty('scrollbar-width')) === 'none' ||
|
||||||
@@ -152,9 +152,13 @@ const createEnvironment = (): InternalEnvironment => {
|
|||||||
x: nativeScrollbarsSize.x === 0,
|
x: nativeScrollbarsSize.x === 0,
|
||||||
y: nativeScrollbarsSize.y === 0,
|
y: nativeScrollbarsSize.y === 0,
|
||||||
};
|
};
|
||||||
const initializationStrategy = {
|
const defaultInitialization = {
|
||||||
padding: !nativeScrollbarsHiding,
|
padding: !nativeScrollbarsHiding,
|
||||||
content: false,
|
content: false,
|
||||||
|
cancel: {
|
||||||
|
nativeScrollbarsOverlaid: true,
|
||||||
|
body: null,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const defaultDefaultOptions = assignDeep({}, defaultOptions);
|
const defaultDefaultOptions = assignDeep({}, defaultOptions);
|
||||||
|
|
||||||
@@ -166,20 +170,20 @@ const createEnvironment = (): InternalEnvironment => {
|
|||||||
_rtlScrollBehavior: getRtlScrollBehavior(envElm, envChildElm),
|
_rtlScrollBehavior: getRtlScrollBehavior(envElm, envChildElm),
|
||||||
_flexboxGlue: getFlexboxGlue(envElm, envChildElm),
|
_flexboxGlue: getFlexboxGlue(envElm, envChildElm),
|
||||||
_addListener: (listener) => addEvent('_', listener),
|
_addListener: (listener) => addEvent('_', listener),
|
||||||
_getInitializationStrategy: assignDeep<InitializationStrategy, InitializationStrategy>.bind(
|
_getDefaultInitialization: assignDeep<DefaultInitialization, DefaultInitialization>.bind(
|
||||||
0,
|
0,
|
||||||
{} as InitializationStrategy,
|
{} as DefaultInitialization,
|
||||||
initializationStrategy
|
defaultInitialization
|
||||||
),
|
),
|
||||||
_setInitializationStrategy(newInitializationStrategy) {
|
_setDefaultInitialization(newInitializationStrategy) {
|
||||||
assignDeep(initializationStrategy, newInitializationStrategy);
|
assignDeep(defaultInitialization, newInitializationStrategy);
|
||||||
},
|
},
|
||||||
_getDefaultOptions: assignDeep<Options, Options>.bind(0, {} as Options, defaultDefaultOptions),
|
_getDefaultOptions: assignDeep<Options, Options>.bind(0, {} as Options, defaultDefaultOptions),
|
||||||
_setDefaultOptions(newDefaultOptions) {
|
_setDefaultOptions(newDefaultOptions) {
|
||||||
assignDeep(defaultDefaultOptions, newDefaultOptions);
|
assignDeep(defaultDefaultOptions, newDefaultOptions);
|
||||||
},
|
},
|
||||||
_defaultInitializationStrategy: assignDeep({}, initializationStrategy),
|
_staticDefaultInitialization: assignDeep({}, defaultInitialization),
|
||||||
_defaultDefaultOptions: assignDeep({}, defaultDefaultOptions),
|
_staticDefaultOptions: assignDeep({}, defaultDefaultOptions),
|
||||||
};
|
};
|
||||||
|
|
||||||
removeAttr(envElm, 'style');
|
removeAttr(envElm, 'style');
|
||||||
|
|||||||
@@ -1,24 +1,37 @@
|
|||||||
import { isFunction, isNull, isUndefined } from 'support';
|
import { isBoolean, isFunction, isNull, isUndefined } from 'support';
|
||||||
import type {
|
import type {
|
||||||
StructureInitialization,
|
StructureInitialization,
|
||||||
StructureInitializationStrategy,
|
DefaultStructureInitialization,
|
||||||
} from 'setups/structureSetup';
|
} from 'setups/structureSetup';
|
||||||
import type {
|
import type {
|
||||||
ScrollbarsInitialization,
|
ScrollbarsInitialization,
|
||||||
ScrollbarsInitializationStrategy,
|
DefaultScrollbarsInitialization,
|
||||||
} from 'setups/scrollbarsSetup';
|
} from 'setups/scrollbarsSetup';
|
||||||
|
import { getEnvironment } from 'environment';
|
||||||
|
import { DeepPartial } from 'typings';
|
||||||
|
import { StructureSetupElementsObj } from 'setups/structureSetup/structureSetup.elements';
|
||||||
|
|
||||||
type StaticInitialization = HTMLElement | null | undefined;
|
type StaticInitialization = HTMLElement | null | undefined;
|
||||||
type DynamicInitialization = HTMLElement | boolean | null | undefined;
|
type DynamicInitialization = HTMLElement | boolean | null | undefined;
|
||||||
|
|
||||||
|
export type CancelInitialization = {
|
||||||
|
cancel: {
|
||||||
|
nativeScrollbarsOverlaid: boolean | undefined;
|
||||||
|
body: boolean | null | undefined;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export type InitializationTargetElement = HTMLElement | HTMLTextAreaElement;
|
export type InitializationTargetElement = HTMLElement | HTMLTextAreaElement;
|
||||||
|
|
||||||
export type InitializationTargetObject = StructureInitialization & ScrollbarsInitialization;
|
export type InitializationTargetObject = StructureInitialization &
|
||||||
|
ScrollbarsInitialization &
|
||||||
|
DeepPartial<CancelInitialization>;
|
||||||
|
|
||||||
export type InitializationTarget = InitializationTargetElement | InitializationTargetObject;
|
export type InitializationTarget = InitializationTargetElement | InitializationTargetObject;
|
||||||
|
|
||||||
export type InitializationStrategy = StructureInitializationStrategy &
|
export type DefaultInitialization = DefaultStructureInitialization &
|
||||||
ScrollbarsInitializationStrategy;
|
DefaultScrollbarsInitialization &
|
||||||
|
CancelInitialization;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static elements MUST be present.
|
* Static elements MUST be present.
|
||||||
@@ -39,9 +52,9 @@ export type DynamicInitializationElement<Args extends any[]> =
|
|||||||
| ((...args: Args) => DynamicInitialization)
|
| ((...args: Args) => DynamicInitialization)
|
||||||
| DynamicInitialization;
|
| DynamicInitialization;
|
||||||
|
|
||||||
export type InitializtationElementStrategy<InitElm> = Exclude<InitElm, HTMLElement>;
|
export type DefaultInitializtationElement<InitElm> = Exclude<InitElm, HTMLElement>;
|
||||||
|
|
||||||
export type DefaultInitializtationElementStrategy<
|
export type FallbackInitializtationElement<
|
||||||
InitElm extends StaticInitializationElement<any> | DynamicInitializationElement<any>
|
InitElm extends StaticInitializationElement<any> | DynamicInitializationElement<any>
|
||||||
> = Extract<InitElm, (...args: any[]) => any> extends (...args: infer P) => any
|
> = Extract<InitElm, (...args: any[]) => any> extends (...args: infer P) => any
|
||||||
? (...args: P) => HTMLElement
|
? (...args: P) => HTMLElement
|
||||||
@@ -52,20 +65,20 @@ const resolveInitialization = <T>(value: any, args: any): T =>
|
|||||||
|
|
||||||
const staticInitializationElement = <T extends StaticInitializationElement<any>>(
|
const staticInitializationElement = <T extends StaticInitializationElement<any>>(
|
||||||
args: Parameters<Extract<T, (...args: any[]) => any>>,
|
args: Parameters<Extract<T, (...args: any[]) => any>>,
|
||||||
defaultStaticInitializationElement: DefaultInitializtationElementStrategy<T>,
|
fallbackStaticInitializationElement: FallbackInitializtationElement<T>,
|
||||||
staticInitializationElementStrategy?: InitializtationElementStrategy<T>,
|
defaultStaticInitializationElementStrategy?: DefaultInitializtationElement<T>,
|
||||||
staticInitializationElementValue?: T | false
|
staticInitializationElementValue?: T | false
|
||||||
): HTMLElement =>
|
): HTMLElement =>
|
||||||
resolveInitialization<StaticInitialization>(
|
resolveInitialization<StaticInitialization>(
|
||||||
staticInitializationElementValue ||
|
staticInitializationElementValue ||
|
||||||
resolveInitialization<StaticInitialization>(staticInitializationElementStrategy, args),
|
resolveInitialization<StaticInitialization>(defaultStaticInitializationElementStrategy, args),
|
||||||
args
|
args
|
||||||
) || defaultStaticInitializationElement.apply(0, args);
|
) || fallbackStaticInitializationElement.apply(0, args);
|
||||||
|
|
||||||
const dynamicInitializationElement = <T extends DynamicInitializationElement<any>>(
|
const dynamicInitializationElement = <T extends DynamicInitializationElement<any>>(
|
||||||
args: Parameters<Extract<T, (...args: any[]) => any>>,
|
args: Parameters<Extract<T, (...args: any[]) => any>>,
|
||||||
defaultDynamicInitializationElement: DefaultInitializtationElementStrategy<T>,
|
fallbackDynamicInitializationElement: FallbackInitializtationElement<T>,
|
||||||
dynamicInitializationElementStrategy?: InitializtationElementStrategy<T>,
|
defaultDynamicInitializationElementStrategy?: DefaultInitializtationElement<T>,
|
||||||
dynamicInitializationElementValue?: T | false
|
dynamicInitializationElementValue?: T | false
|
||||||
): HTMLElement | false => {
|
): HTMLElement | false => {
|
||||||
let result = resolveInitialization<DynamicInitialization>(
|
let result = resolveInitialization<DynamicInitialization>(
|
||||||
@@ -75,14 +88,40 @@ const dynamicInitializationElement = <T extends DynamicInitializationElement<any
|
|||||||
|
|
||||||
if (isNull(result) || isUndefined(result)) {
|
if (isNull(result) || isUndefined(result)) {
|
||||||
result = resolveInitialization<DynamicInitialization>(
|
result = resolveInitialization<DynamicInitialization>(
|
||||||
dynamicInitializationElementStrategy,
|
defaultDynamicInitializationElementStrategy,
|
||||||
args
|
args
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result === true || isNull(result) || isUndefined(result)
|
return result === true || isNull(result) || isUndefined(result)
|
||||||
? defaultDynamicInitializationElement.apply(0, args)
|
? fallbackDynamicInitializationElement.apply(0, args)
|
||||||
: result;
|
: result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export { staticInitializationElement, dynamicInitializationElement };
|
const cancelInitialization = (
|
||||||
|
cancelInitializationValue: DeepPartial<CancelInitialization['cancel']> | false | null | undefined,
|
||||||
|
structureSetupElements: StructureSetupElementsObj
|
||||||
|
): boolean => {
|
||||||
|
const { nativeScrollbarsOverlaid, body } = cancelInitializationValue || {};
|
||||||
|
const { _isBody, _viewportIsTarget } = structureSetupElements;
|
||||||
|
const { _getDefaultInitialization, _nativeScrollbarsOverlaid } = getEnvironment();
|
||||||
|
const { nativeScrollbarsOverlaid: defaultNativeScrollbarsOverlaid, body: defaultbody } =
|
||||||
|
_getDefaultInitialization().cancel;
|
||||||
|
|
||||||
|
const resolvedNativeScrollbarsOverlaid =
|
||||||
|
nativeScrollbarsOverlaid ?? defaultNativeScrollbarsOverlaid;
|
||||||
|
const resolvedDocumentScrollingElement = isBoolean(body) || isNull(body) ? body : defaultbody;
|
||||||
|
|
||||||
|
const finalNativeScrollbarsOverlaid =
|
||||||
|
(_nativeScrollbarsOverlaid.x || _nativeScrollbarsOverlaid.y) &&
|
||||||
|
resolvedNativeScrollbarsOverlaid;
|
||||||
|
const finalDocumentScrollingElement =
|
||||||
|
_isBody &&
|
||||||
|
(isNull(resolvedDocumentScrollingElement)
|
||||||
|
? !_viewportIsTarget
|
||||||
|
: resolvedDocumentScrollingElement);
|
||||||
|
|
||||||
|
return !!finalNativeScrollbarsOverlaid || !!finalDocumentScrollingElement;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { staticInitializationElement, dynamicInitializationElement, cancelInitialization };
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { assignDeep, each, isObject, keys, isArray, hasOwnProperty, isFunction } from 'support';
|
import { assignDeep, each, isObject, keys, isArray, hasOwnProperty, isFunction } from 'support';
|
||||||
import { PartialOptions, ReadonlyOptions } from 'typings';
|
import { DeepPartial, ReadonlyOptions } from 'typings';
|
||||||
|
|
||||||
const opsStringify = (value: any) =>
|
const opsStringify = (value: any) =>
|
||||||
JSON.stringify(value, (_, val) => {
|
JSON.stringify(value, (_, val) => {
|
||||||
@@ -40,6 +40,7 @@ export type UpdatedCallback = (this: any, args?: UpdatedArgs) => void;
|
|||||||
|
|
||||||
export interface Options {
|
export interface Options {
|
||||||
paddingAbsolute: boolean;
|
paddingAbsolute: boolean;
|
||||||
|
showNativeOverlaidScrollbars: boolean;
|
||||||
updating: {
|
updating: {
|
||||||
elementEvents: Array<[elementSelector: string, eventNames: string]> | null;
|
elementEvents: Array<[elementSelector: string, eventNames: string]> | null;
|
||||||
attributes: string[] | null;
|
attributes: string[] | null;
|
||||||
@@ -59,10 +60,6 @@ export interface Options {
|
|||||||
clickScroll: boolean;
|
clickScroll: boolean;
|
||||||
touch: boolean;
|
touch: boolean;
|
||||||
};
|
};
|
||||||
nativeScrollbarsOverlaid: {
|
|
||||||
show: boolean;
|
|
||||||
initialize: boolean;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ReadonlyOSOptions = ReadonlyOptions<Options>;
|
export type ReadonlyOSOptions = ReadonlyOptions<Options>;
|
||||||
@@ -97,6 +94,7 @@ export interface UpdatedArgs {
|
|||||||
export const defaultOptions: Options = {
|
export const defaultOptions: Options = {
|
||||||
// resize: 'none', // none || both || horizontal || vertical || n || b || h || v
|
// resize: 'none', // none || both || horizontal || vertical || n || b || h || v
|
||||||
paddingAbsolute: false, // true || false
|
paddingAbsolute: false, // true || false
|
||||||
|
showNativeOverlaidScrollbars: false, // true || false
|
||||||
updating: {
|
updating: {
|
||||||
elementEvents: [['img', 'load']], // array of tuples || null
|
elementEvents: [['img', 'load']], // array of tuples || null
|
||||||
debounce: [0, 33], // number || number array || null
|
debounce: [0, 33], // number || number array || null
|
||||||
@@ -107,10 +105,6 @@ export const defaultOptions: Options = {
|
|||||||
x: 'scroll', // visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s
|
x: 'scroll', // visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s
|
||||||
y: 'scroll', // visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s
|
y: 'scroll', // visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s
|
||||||
},
|
},
|
||||||
nativeScrollbarsOverlaid: {
|
|
||||||
show: false, // true || false
|
|
||||||
initialize: false, // true || false
|
|
||||||
},
|
|
||||||
scrollbars: {
|
scrollbars: {
|
||||||
theme: 'os-theme-dark',
|
theme: 'os-theme-dark',
|
||||||
visibility: 'auto', // visible || hidden || auto || v || h || a
|
visibility: 'auto', // visible || hidden || auto || v || h || a
|
||||||
@@ -129,11 +123,8 @@ export const defaultOptions: Options = {
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getOptionsDiff = <T>(
|
export const getOptionsDiff = <T>(currOptions: T, newOptions: DeepPartial<T>): DeepPartial<T> => {
|
||||||
currOptions: T,
|
const diff: DeepPartial<T> = {};
|
||||||
newOptions: PartialOptions<T>
|
|
||||||
): PartialOptions<T> => {
|
|
||||||
const diff: PartialOptions<T> = {};
|
|
||||||
const optionsKeys = keys(newOptions).concat(keys(currOptions));
|
const optionsKeys = keys(newOptions).concat(keys(currOptions));
|
||||||
|
|
||||||
each(optionsKeys, (optionKey) => {
|
each(optionsKeys, (optionKey) => {
|
||||||
|
|||||||
@@ -20,11 +20,12 @@ import {
|
|||||||
OptionsValidationPluginInstance,
|
OptionsValidationPluginInstance,
|
||||||
} from 'plugins';
|
} from 'plugins';
|
||||||
import { addInstance, getInstance, removeInstance } from 'instances';
|
import { addInstance, getInstance, removeInstance } from 'instances';
|
||||||
import type { PartialOptions, OverflowStyle } from 'typings';
|
import type { DeepPartial, OverflowStyle } from 'typings';
|
||||||
import type {
|
import {
|
||||||
InitializationTarget,
|
InitializationTarget,
|
||||||
InitializationTargetObject,
|
InitializationTargetObject,
|
||||||
InitializationStrategy,
|
DefaultInitialization,
|
||||||
|
cancelInitialization,
|
||||||
} from 'initialization';
|
} from 'initialization';
|
||||||
import type {
|
import type {
|
||||||
InitialEventListeners as GeneralInitialEventListeners,
|
InitialEventListeners as GeneralInitialEventListeners,
|
||||||
@@ -34,7 +35,7 @@ import type {
|
|||||||
export interface OverlayScrollbarsStatic {
|
export interface OverlayScrollbarsStatic {
|
||||||
(
|
(
|
||||||
target: InitializationTarget | InitializationTargetObject,
|
target: InitializationTarget | InitializationTargetObject,
|
||||||
options?: PartialOptions<Options>,
|
options?: DeepPartial<Options>,
|
||||||
eventListeners?: GeneralInitialEventListeners<EventListenerMap>
|
eventListeners?: GeneralInitialEventListeners<EventListenerMap>
|
||||||
): OverlayScrollbars;
|
): OverlayScrollbars;
|
||||||
|
|
||||||
@@ -49,13 +50,13 @@ export interface Environment {
|
|||||||
rtlScrollBehavior: { n: boolean; i: boolean };
|
rtlScrollBehavior: { n: boolean; i: boolean };
|
||||||
flexboxGlue: boolean;
|
flexboxGlue: boolean;
|
||||||
cssCustomProperties: boolean;
|
cssCustomProperties: boolean;
|
||||||
defaultInitializationStrategy: InitializationStrategy;
|
staticDefaultInitialization: DefaultInitialization;
|
||||||
defaultDefaultOptions: Options;
|
staticDefaultOptions: Options;
|
||||||
|
|
||||||
getInitializationStrategy(): InitializationStrategy;
|
getDefaultInitialization(): DefaultInitialization;
|
||||||
setInitializationStrategy(newInitializationStrategy: Partial<InitializationStrategy>): void;
|
setDefaultInitialization(newDefaultInitialization: DeepPartial<DefaultInitialization>): void;
|
||||||
getDefaultOptions(): Options;
|
getDefaultOptions(): Options;
|
||||||
setDefaultOptions(newDefaultOptions: PartialOptions<Options>): void;
|
setDefaultOptions(newDefaultOptions: DeepPartial<Options>): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
@@ -87,7 +88,7 @@ export interface OnUpdatedEventListenerArgs {
|
|||||||
hostMutation: boolean;
|
hostMutation: boolean;
|
||||||
contentMutation: boolean;
|
contentMutation: boolean;
|
||||||
};
|
};
|
||||||
changedOptions: PartialOptions<Options>;
|
changedOptions: DeepPartial<Options>;
|
||||||
force: boolean;
|
force: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +104,7 @@ export type EventListenerMap = {
|
|||||||
/**
|
/**
|
||||||
* Triggered after all elements, observers and events are destroyed.
|
* Triggered after all elements, observers and events are destroyed.
|
||||||
*/
|
*/
|
||||||
destroyed: [instance: OverlayScrollbars, withdrawn: boolean];
|
destroyed: [instance: OverlayScrollbars, canceled: boolean];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type InitialEventListeners = GeneralInitialEventListeners<EventListenerMap>;
|
export type InitialEventListeners = GeneralInitialEventListeners<EventListenerMap>;
|
||||||
@@ -115,7 +116,7 @@ export type EventListener<Name extends keyof EventListenerMap> = GeneralEventLis
|
|||||||
|
|
||||||
export interface OverlayScrollbars {
|
export interface OverlayScrollbars {
|
||||||
options(): Options;
|
options(): Options;
|
||||||
options(newOptions?: PartialOptions<Options>): Options;
|
options(newOptions?: DeepPartial<Options>): Options;
|
||||||
|
|
||||||
update(force?: boolean): OverlayScrollbars;
|
update(force?: boolean): OverlayScrollbars;
|
||||||
|
|
||||||
@@ -143,13 +144,10 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|||||||
eventListeners?
|
eventListeners?
|
||||||
): OverlayScrollbars => {
|
): OverlayScrollbars => {
|
||||||
let destroyed = false;
|
let destroyed = false;
|
||||||
const {
|
const { _getDefaultOptions, _addListener: addEnvListener } = getEnvironment();
|
||||||
_getDefaultOptions,
|
|
||||||
_nativeScrollbarsOverlaid: _nativeScrollbarIsOverlaid,
|
|
||||||
_addListener: addEnvListener,
|
|
||||||
} = getEnvironment();
|
|
||||||
const plugins = getPlugins();
|
const plugins = getPlugins();
|
||||||
const instanceTarget = isHTMLElement(target) ? target : target.target;
|
const targetIsElement = isHTMLElement(target);
|
||||||
|
const instanceTarget = targetIsElement ? target : target.target;
|
||||||
const potentialInstance = getInstance(instanceTarget);
|
const potentialInstance = getInstance(instanceTarget);
|
||||||
if (potentialInstance) {
|
if (potentialInstance) {
|
||||||
return potentialInstance;
|
return potentialInstance;
|
||||||
@@ -158,7 +156,7 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|||||||
const optionsValidationPlugin = plugins[
|
const optionsValidationPlugin = plugins[
|
||||||
optionsValidationPluginName
|
optionsValidationPluginName
|
||||||
] as OptionsValidationPluginInstance;
|
] as OptionsValidationPluginInstance;
|
||||||
const validateOptions = (newOptions?: PartialOptions<Options>) => {
|
const validateOptions = (newOptions?: DeepPartial<Options>) => {
|
||||||
const opts = newOptions || {};
|
const opts = newOptions || {};
|
||||||
const validate = optionsValidationPlugin && optionsValidationPlugin._;
|
const validate = optionsValidationPlugin && optionsValidationPlugin._;
|
||||||
return validate ? validate(opts, true) : opts;
|
return validate ? validate(opts, true) : opts;
|
||||||
@@ -178,11 +176,11 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|||||||
currentOptions,
|
currentOptions,
|
||||||
structureState
|
structureState
|
||||||
);
|
);
|
||||||
const update = (changedOptions: PartialOptions<Options>, force?: boolean) => {
|
const update = (changedOptions: DeepPartial<Options>, force?: boolean) => {
|
||||||
updateStructure(changedOptions, !!force);
|
updateStructure(changedOptions, !!force);
|
||||||
};
|
};
|
||||||
const removeEnvListener = addEnvListener(update.bind(0, {}, true));
|
const removeEnvListener = addEnvListener(update.bind(0, {}, true));
|
||||||
const destroy = (withdrawn?: boolean) => {
|
const destroy = (canceled?: boolean) => {
|
||||||
removeInstance(instanceTarget);
|
removeInstance(instanceTarget);
|
||||||
removeEnvListener();
|
removeEnvListener();
|
||||||
|
|
||||||
@@ -192,12 +190,12 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|||||||
destroyed = true;
|
destroyed = true;
|
||||||
|
|
||||||
// eslint-disable-next-line no-use-before-define
|
// eslint-disable-next-line no-use-before-define
|
||||||
triggerEvent('destroyed', [instance, !!withdrawn]);
|
triggerEvent('destroyed', [instance, !!canceled]);
|
||||||
removeEvent();
|
removeEvent();
|
||||||
};
|
};
|
||||||
|
|
||||||
const instance: OverlayScrollbars = {
|
const instance: OverlayScrollbars = {
|
||||||
options(newOptions?: PartialOptions<Options>) {
|
options(newOptions?: DeepPartial<Options>) {
|
||||||
if (newOptions) {
|
if (newOptions) {
|
||||||
const changedOptions = getOptionsDiff(currentOptions, validateOptions(newOptions));
|
const changedOptions = getOptionsDiff(currentOptions, validateOptions(newOptions));
|
||||||
|
|
||||||
@@ -265,11 +263,7 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (
|
if (cancelInitialization(!targetIsElement && target.cancel, structureState._elements)) {
|
||||||
_nativeScrollbarIsOverlaid.x &&
|
|
||||||
_nativeScrollbarIsOverlaid.y &&
|
|
||||||
!currentOptions.nativeScrollbarsOverlaid.initialize
|
|
||||||
) {
|
|
||||||
destroy(true);
|
destroy(true);
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
@@ -323,10 +317,10 @@ OverlayScrollbars.env = () => {
|
|||||||
_rtlScrollBehavior,
|
_rtlScrollBehavior,
|
||||||
_flexboxGlue,
|
_flexboxGlue,
|
||||||
_cssCustomProperties,
|
_cssCustomProperties,
|
||||||
_defaultInitializationStrategy,
|
_staticDefaultInitialization,
|
||||||
_defaultDefaultOptions,
|
_staticDefaultOptions,
|
||||||
_getInitializationStrategy,
|
_getDefaultInitialization,
|
||||||
_setInitializationStrategy,
|
_setDefaultInitialization,
|
||||||
_getDefaultOptions,
|
_getDefaultOptions,
|
||||||
_setDefaultOptions,
|
_setDefaultOptions,
|
||||||
} = getEnvironment();
|
} = getEnvironment();
|
||||||
@@ -339,11 +333,11 @@ OverlayScrollbars.env = () => {
|
|||||||
rtlScrollBehavior: _rtlScrollBehavior,
|
rtlScrollBehavior: _rtlScrollBehavior,
|
||||||
flexboxGlue: _flexboxGlue,
|
flexboxGlue: _flexboxGlue,
|
||||||
cssCustomProperties: _cssCustomProperties,
|
cssCustomProperties: _cssCustomProperties,
|
||||||
defaultInitializationStrategy: _defaultInitializationStrategy,
|
staticDefaultInitialization: _staticDefaultInitialization,
|
||||||
defaultDefaultOptions: _defaultDefaultOptions,
|
staticDefaultOptions: _staticDefaultOptions,
|
||||||
|
|
||||||
getInitializationStrategy: _getInitializationStrategy,
|
getDefaultInitialization: _getDefaultInitialization,
|
||||||
setInitializationStrategy: _setInitializationStrategy,
|
setDefaultInitialization: _setDefaultInitialization,
|
||||||
getDefaultOptions: _getDefaultOptions,
|
getDefaultOptions: _getDefaultOptions,
|
||||||
setDefaultOptions: _setDefaultOptions,
|
setDefaultOptions: _setDefaultOptions,
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-7
@@ -10,7 +10,7 @@ import {
|
|||||||
OptionsTemplateValue,
|
OptionsTemplateValue,
|
||||||
optionsTemplateTypes as oTypes,
|
optionsTemplateTypes as oTypes,
|
||||||
} from 'plugins/optionsValidationPlugin/validation';
|
} from 'plugins/optionsValidationPlugin/validation';
|
||||||
import type { PartialOptions } from 'typings';
|
import type { DeepPartial } from 'typings';
|
||||||
import type { Plugin } from 'plugins';
|
import type { Plugin } from 'plugins';
|
||||||
|
|
||||||
const numberAllowedValues: OptionsTemplateValue<number> = oTypes.number;
|
const numberAllowedValues: OptionsTemplateValue<number> = oTypes.number;
|
||||||
@@ -26,6 +26,7 @@ const scrollbarsAutoHideAllowedValues: OptionsTemplateValue<ScrollbarAutoHideBeh
|
|||||||
const optionsTemplate: OptionsTemplate<Options> = {
|
const optionsTemplate: OptionsTemplate<Options> = {
|
||||||
// resize: resizeAllowedValues, // none || both || horizontal || vertical || n || b ||
|
// resize: resizeAllowedValues, // none || both || horizontal || vertical || n || b ||
|
||||||
paddingAbsolute: booleanAllowedValues, // true || false
|
paddingAbsolute: booleanAllowedValues, // true || false
|
||||||
|
showNativeOverlaidScrollbars: booleanAllowedValues, // true || false
|
||||||
updating: {
|
updating: {
|
||||||
elementEvents: arrayNullValues, // array of tuples || null
|
elementEvents: arrayNullValues, // array of tuples || null
|
||||||
attributes: arrayNullValues,
|
attributes: arrayNullValues,
|
||||||
@@ -52,21 +53,17 @@ const optionsTemplate: OptionsTemplate<Options> = {
|
|||||||
inheritedAttrs: stringArrayNullAllowedValues, // string || array || nul
|
inheritedAttrs: stringArrayNullAllowedValues, // string || array || nul
|
||||||
},
|
},
|
||||||
*/
|
*/
|
||||||
nativeScrollbarsOverlaid: {
|
|
||||||
show: booleanAllowedValues, // true || false
|
|
||||||
initialize: booleanAllowedValues, // true || false
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OptionsValidationPluginInstance = {
|
export type OptionsValidationPluginInstance = {
|
||||||
_: (options: PartialOptions<Options>, doWriteErrors?: boolean) => PartialOptions<Options>;
|
_: (options: DeepPartial<Options>, doWriteErrors?: boolean) => DeepPartial<Options>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const optionsValidationPluginName = '__osOptionsValidationPlugin';
|
export const optionsValidationPluginName = '__osOptionsValidationPlugin';
|
||||||
|
|
||||||
export const optionsValidationPlugin: Plugin<OptionsValidationPluginInstance> = {
|
export const optionsValidationPlugin: Plugin<OptionsValidationPluginInstance> = {
|
||||||
[optionsValidationPluginName]: {
|
[optionsValidationPluginName]: {
|
||||||
_: (options: PartialOptions<Options>, doWriteErrors?: boolean) => {
|
_: (options: DeepPartial<Options>, doWriteErrors?: boolean) => {
|
||||||
const [validated, foreign] = validateOptions(optionsTemplate, options, doWriteErrors);
|
const [validated, foreign] = validateOptions(optionsTemplate, options, doWriteErrors);
|
||||||
return { ...foreign, ...validated };
|
return { ...foreign, ...validated };
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { each, hasOwnProperty, keys, push, isEmptyObject } from 'support/utils';
|
import { each, hasOwnProperty, keys, push, isEmptyObject } from 'support/utils';
|
||||||
import { type, isArray, isUndefined, isPlainObject, isString } from 'support/utils/types';
|
import { type, isArray, isUndefined, isPlainObject, isString } from 'support/utils/types';
|
||||||
import { PlainObject, PartialOptions } from 'typings';
|
import { PlainObject, DeepPartial } from 'typings';
|
||||||
|
|
||||||
export type OptionsObjectType = Record<string, unknown>;
|
export type OptionsObjectType = Record<string, unknown>;
|
||||||
export type OptionsFunctionType = (this: any, ...args: any[]) => any;
|
export type OptionsFunctionType = (this: any, ...args: any[]) => any;
|
||||||
@@ -26,7 +26,7 @@ export type OptionsTemplate<T> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type OptionsValidationResult<T> = [
|
export type OptionsValidationResult<T> = [
|
||||||
PartialOptions<T>, // validated
|
DeepPartial<T>, // validated
|
||||||
Record<string, unknown> // foreign
|
Record<string, unknown> // foreign
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -88,12 +88,12 @@ const optionsTemplateTypes: OptionsTemplateTypesDictionary = {
|
|||||||
*/
|
*/
|
||||||
const validateRecursive = <T extends PlainObject>(
|
const validateRecursive = <T extends PlainObject>(
|
||||||
template: OptionsTemplate<T>,
|
template: OptionsTemplate<T>,
|
||||||
options: PartialOptions<T>,
|
options: DeepPartial<T>,
|
||||||
doWriteErrors?: boolean,
|
doWriteErrors?: boolean,
|
||||||
propPath?: string
|
propPath?: string
|
||||||
): OptionsValidationResult<T> => {
|
): OptionsValidationResult<T> => {
|
||||||
const validatedOptions: PartialOptions<T> = {};
|
const validatedOptions: DeepPartial<T> = {};
|
||||||
const optionsCopy: PartialOptions<T> = { ...options };
|
const optionsCopy: DeepPartial<T> = { ...options };
|
||||||
const props = keys(template).filter((prop) => hasOwnProperty(options, prop));
|
const props = keys(template).filter((prop) => hasOwnProperty(options, prop));
|
||||||
|
|
||||||
each(props, (prop: Extract<keyof T, string>) => {
|
each(props, (prop: Extract<keyof T, string>) => {
|
||||||
@@ -189,7 +189,7 @@ const validateRecursive = <T extends PlainObject>(
|
|||||||
*/
|
*/
|
||||||
const validateOptions = <T extends PlainObject>(
|
const validateOptions = <T extends PlainObject>(
|
||||||
template: OptionsTemplate<T>,
|
template: OptionsTemplate<T>,
|
||||||
options: PartialOptions<T>,
|
options: DeepPartial<T>,
|
||||||
doWriteErrors?: boolean
|
doWriteErrors?: boolean
|
||||||
): OptionsValidationResult<T> => validateRecursive<T>(template, options, doWriteErrors);
|
): OptionsValidationResult<T> => validateRecursive<T>(template, options, doWriteErrors);
|
||||||
|
|
||||||
|
|||||||
+3
-7
@@ -82,15 +82,11 @@ export const scrollbarsHidingPluginName = '__osScrollbarsHidingPlugin';
|
|||||||
export const scrollbarsHidingPlugin: Plugin<ScrollbarsHidingPluginInstance> = {
|
export const scrollbarsHidingPlugin: Plugin<ScrollbarsHidingPluginInstance> = {
|
||||||
[scrollbarsHidingPluginName]: {
|
[scrollbarsHidingPluginName]: {
|
||||||
_createUniqueViewportArrangeElement: (env: InternalEnvironment) => {
|
_createUniqueViewportArrangeElement: (env: InternalEnvironment) => {
|
||||||
const {
|
const { _nativeScrollbarsHiding, _nativeScrollbarsOverlaid, _cssCustomProperties } = env;
|
||||||
_nativeScrollbarsHiding: _nativeScrollbarStyling,
|
|
||||||
_nativeScrollbarsOverlaid: _nativeScrollbarIsOverlaid,
|
|
||||||
_cssCustomProperties,
|
|
||||||
} = env;
|
|
||||||
const create =
|
const create =
|
||||||
!_cssCustomProperties &&
|
!_cssCustomProperties &&
|
||||||
!_nativeScrollbarStyling &&
|
!_nativeScrollbarsHiding &&
|
||||||
(_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y);
|
(_nativeScrollbarsOverlaid.x || _nativeScrollbarsOverlaid.y);
|
||||||
const result = create ? document.createElement('style') : false;
|
const result = create ? document.createElement('style') : false;
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import type { InitializationTarget } from 'initialization';
|
|||||||
import type { StructureSetupElementsObj } from 'setups/structureSetup/structureSetup.elements';
|
import type { StructureSetupElementsObj } from 'setups/structureSetup/structureSetup.elements';
|
||||||
import type {
|
import type {
|
||||||
ScrollbarsInitialization,
|
ScrollbarsInitialization,
|
||||||
ScrollbarsInitializationStrategy,
|
DefaultScrollbarsInitialization,
|
||||||
ScrollbarsDynamicInitializationElement,
|
ScrollbarsDynamicInitializationElement,
|
||||||
} from 'setups/scrollbarsSetup/scrollbarsSetup.initialization';
|
} from 'setups/scrollbarsSetup/scrollbarsSetup.initialization';
|
||||||
import { StyleObject } from 'typings';
|
import { StyleObject } from 'typings';
|
||||||
@@ -85,19 +85,17 @@ export const createScrollbarsSetupElements = (
|
|||||||
target: InitializationTarget,
|
target: InitializationTarget,
|
||||||
structureSetupElements: StructureSetupElementsObj
|
structureSetupElements: StructureSetupElementsObj
|
||||||
): ScrollbarsSetupElements => {
|
): ScrollbarsSetupElements => {
|
||||||
const { _getInitializationStrategy } = getEnvironment();
|
const { _getDefaultInitialization } = getEnvironment();
|
||||||
const { scrollbarsSlot: environmentScrollbarSlot } =
|
const { scrollbarsSlot: defaultScrollbarSlot } =
|
||||||
_getInitializationStrategy() as ScrollbarsInitializationStrategy;
|
_getDefaultInitialization() as DefaultScrollbarsInitialization;
|
||||||
const { _documentElm, _target, _host, _viewport, _targetIsElm } = structureSetupElements;
|
const { _documentElm, _target, _host, _viewport, _targetIsElm } = structureSetupElements;
|
||||||
const initializationScrollbarSlot = _targetIsElm
|
const scrollbarSlot = _targetIsElm ? null : (target as ScrollbarsInitialization).scrollbarsSlot;
|
||||||
? null
|
|
||||||
: (target as ScrollbarsInitialization).scrollbarsSlot;
|
|
||||||
const evaluatedScrollbarSlot =
|
const evaluatedScrollbarSlot =
|
||||||
generalDynamicInitializationElement<ScrollbarsDynamicInitializationElement>(
|
generalDynamicInitializationElement<ScrollbarsDynamicInitializationElement>(
|
||||||
[_target, _host, _viewport],
|
[_target, _host, _viewport],
|
||||||
() => _host,
|
() => _host,
|
||||||
environmentScrollbarSlot,
|
defaultScrollbarSlot,
|
||||||
initializationScrollbarSlot
|
scrollbarSlot
|
||||||
);
|
);
|
||||||
const scrollbarsAddRemoveClass = (
|
const scrollbarsAddRemoveClass = (
|
||||||
scrollbarStructures: ScrollbarStructure[],
|
scrollbarStructures: ScrollbarStructure[],
|
||||||
|
|||||||
+3
-5
@@ -1,6 +1,6 @@
|
|||||||
import type {
|
import type {
|
||||||
InitializationTargetElement,
|
InitializationTargetElement,
|
||||||
InitializtationElementStrategy,
|
DefaultInitializtationElement,
|
||||||
DynamicInitializationElement,
|
DynamicInitializationElement,
|
||||||
} from 'initialization';
|
} from 'initialization';
|
||||||
|
|
||||||
@@ -20,8 +20,6 @@ export interface ScrollbarsInitialization {
|
|||||||
scrollbarsSlot?: ScrollbarsDynamicInitializationElement;
|
scrollbarsSlot?: ScrollbarsDynamicInitializationElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ScrollbarsInitializationStrategy = {
|
export type DefaultScrollbarsInitialization = {
|
||||||
[K in keyof ScrollbarsInitialization]: InitializtationElementStrategy<
|
[K in keyof ScrollbarsInitialization]: DefaultInitializtationElement<ScrollbarsInitialization[K]>;
|
||||||
ScrollbarsInitialization[K]
|
|
||||||
>;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { assignDeep, hasOwnProperty } from 'support';
|
import { assignDeep, hasOwnProperty } from 'support';
|
||||||
import type { Options, ReadonlyOSOptions } from 'options';
|
import type { Options, ReadonlyOSOptions } from 'options';
|
||||||
import type { PartialOptions } from 'typings';
|
import type { DeepPartial } from 'typings';
|
||||||
|
|
||||||
export type SetupElements<T extends Record<string, any>> = [elements: T, destroy: () => void];
|
export type SetupElements<T extends Record<string, any>> = [elements: T, destroy: () => void];
|
||||||
|
|
||||||
export type SetupUpdate<T extends any[]> = (
|
export type SetupUpdate<T extends any[]> = (
|
||||||
changedOptions: PartialOptions<Options>,
|
changedOptions: DeepPartial<Options>,
|
||||||
force: boolean,
|
force: boolean,
|
||||||
...args: T
|
...args: T
|
||||||
) => void;
|
) => void;
|
||||||
@@ -37,7 +37,7 @@ const getPropByPath = <T>(obj: any, path: string): T =>
|
|||||||
export const createOptionCheck =
|
export const createOptionCheck =
|
||||||
(
|
(
|
||||||
options: ReadonlyOSOptions,
|
options: ReadonlyOSOptions,
|
||||||
changedOptions: PartialOptions<Options>,
|
changedOptions: DeepPartial<Options>,
|
||||||
force?: boolean
|
force?: boolean
|
||||||
): SetupUpdateCheckOption =>
|
): SetupUpdateCheckOption =>
|
||||||
(path: string) =>
|
(path: string) =>
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import {
|
|||||||
attrClass,
|
attrClass,
|
||||||
hasAttrClass,
|
hasAttrClass,
|
||||||
ResizeObserverConstructor,
|
ResizeObserverConstructor,
|
||||||
|
hasOwnProperty,
|
||||||
|
noop,
|
||||||
} from 'support';
|
} from 'support';
|
||||||
import {
|
import {
|
||||||
dataAttributeHost,
|
dataAttributeHost,
|
||||||
@@ -28,7 +30,7 @@ import {
|
|||||||
classNamePadding,
|
classNamePadding,
|
||||||
classNameViewport,
|
classNameViewport,
|
||||||
classNameContent,
|
classNameContent,
|
||||||
classNameViewportScrollbarStyling,
|
classNameViewportScrollbarHidden,
|
||||||
} from 'classnames';
|
} from 'classnames';
|
||||||
import { getEnvironment } from 'environment';
|
import { getEnvironment } from 'environment';
|
||||||
import { getPlugins, scrollbarsHidingPluginName } from 'plugins';
|
import { getPlugins, scrollbarsHidingPluginName } from 'plugins';
|
||||||
@@ -36,11 +38,11 @@ import type { ScrollbarsHidingPluginInstance } from 'plugins/scrollbarsHidingPlu
|
|||||||
import {
|
import {
|
||||||
staticInitializationElement as generalStaticInitializationElement,
|
staticInitializationElement as generalStaticInitializationElement,
|
||||||
dynamicInitializationElement as generalDynamicInitializationElement,
|
dynamicInitializationElement as generalDynamicInitializationElement,
|
||||||
|
InitializationTargetObject,
|
||||||
} from 'initialization';
|
} from 'initialization';
|
||||||
import type { InitializationTarget, InitializationTargetElement } from 'initialization';
|
import type { InitializationTarget, InitializationTargetElement } from 'initialization';
|
||||||
import type {
|
import type {
|
||||||
StructureDynamicInitializationElement,
|
StructureDynamicInitializationElement,
|
||||||
StructureInitialization,
|
|
||||||
StructureStaticInitializationElement,
|
StructureStaticInitializationElement,
|
||||||
} from 'setups/structureSetup/structureSetup.initialization';
|
} from 'setups/structureSetup/structureSetup.initialization';
|
||||||
|
|
||||||
@@ -60,8 +62,6 @@ export interface StructureSetupElementsObj {
|
|||||||
// ctx ----
|
// ctx ----
|
||||||
_isTextarea: boolean;
|
_isTextarea: boolean;
|
||||||
_isBody: boolean;
|
_isBody: boolean;
|
||||||
_htmlElm: HTMLHtmlElement;
|
|
||||||
_bodyElm: HTMLBodyElement;
|
|
||||||
_windowElm: Window;
|
_windowElm: Window;
|
||||||
_documentElm: Document;
|
_documentElm: Document;
|
||||||
_targetIsElm: boolean;
|
_targetIsElm: boolean;
|
||||||
@@ -86,29 +86,35 @@ export const createStructureSetupElements = (
|
|||||||
target: InitializationTarget
|
target: InitializationTarget
|
||||||
): StructureSetupElements => {
|
): StructureSetupElements => {
|
||||||
const env = getEnvironment();
|
const env = getEnvironment();
|
||||||
const { _getInitializationStrategy, _nativeScrollbarsHiding } = env;
|
const { _getDefaultInitialization, _nativeScrollbarsHiding } = env;
|
||||||
const scrollbarsHidingPlugin = getPlugins()[scrollbarsHidingPluginName] as
|
const scrollbarsHidingPlugin = getPlugins()[scrollbarsHidingPluginName] as
|
||||||
| ScrollbarsHidingPluginInstance
|
| ScrollbarsHidingPluginInstance
|
||||||
| undefined;
|
| undefined;
|
||||||
const createUniqueViewportArrangeElement =
|
const createUniqueViewportArrangeElement =
|
||||||
scrollbarsHidingPlugin && scrollbarsHidingPlugin._createUniqueViewportArrangeElement;
|
scrollbarsHidingPlugin && scrollbarsHidingPlugin._createUniqueViewportArrangeElement;
|
||||||
const {
|
const {
|
||||||
host: hostInitializationStrategy,
|
host: defaultHostInitializationStrategy,
|
||||||
viewport: viewportInitializationStrategy,
|
viewport: defaultViewportInitializationStrategy,
|
||||||
padding: paddingInitializationStrategy,
|
padding: defaultPaddingInitializationStrategy,
|
||||||
content: contentInitializationStrategy,
|
content: defaultContentInitializationStrategy,
|
||||||
} = _getInitializationStrategy();
|
} = _getDefaultInitialization();
|
||||||
const targetIsElm = isHTMLElement(target);
|
const targetIsElm = isHTMLElement(target);
|
||||||
const targetStructureInitialization = target as StructureInitialization;
|
const targetStructureInitialization = (targetIsElm ? {} : target) as InitializationTargetObject;
|
||||||
const targetElement = targetIsElm
|
const {
|
||||||
? (target as InitializationTargetElement)
|
host: hostInitializationStrategy,
|
||||||
: targetStructureInitialization.target;
|
padding: paddingInitializationStrategy,
|
||||||
|
viewport: viewportInitializationStrategy,
|
||||||
|
content: contentInitializationStrategy,
|
||||||
|
} = targetStructureInitialization;
|
||||||
|
|
||||||
|
const targetElement = targetIsElm ? target : targetStructureInitialization.target;
|
||||||
const isTextarea = is(targetElement, 'textarea');
|
const isTextarea = is(targetElement, 'textarea');
|
||||||
const isBody = !isTextarea && is(targetElement, 'body');
|
const ownerDocument = targetElement.ownerDocument;
|
||||||
const ownerDocument = targetElement!.ownerDocument;
|
const isBody = targetElement === ownerDocument.body;
|
||||||
const bodyElm = ownerDocument.body as HTMLBodyElement;
|
|
||||||
const wnd = ownerDocument.defaultView as Window;
|
const wnd = ownerDocument.defaultView as Window;
|
||||||
const singleElmSupport = !!ResizeObserverConstructor && !isTextarea && _nativeScrollbarsHiding;
|
const singleElmSupport = isBody
|
||||||
|
? _nativeScrollbarsHiding
|
||||||
|
: !!ResizeObserverConstructor && !isTextarea && _nativeScrollbarsHiding;
|
||||||
const staticInitializationElement =
|
const staticInitializationElement =
|
||||||
generalStaticInitializationElement<StructureStaticInitializationElement>.bind(0, [
|
generalStaticInitializationElement<StructureStaticInitializationElement>.bind(0, [
|
||||||
targetElement,
|
targetElement,
|
||||||
@@ -120,13 +126,15 @@ export const createStructureSetupElements = (
|
|||||||
const viewportElement = [
|
const viewportElement = [
|
||||||
staticInitializationElement(
|
staticInitializationElement(
|
||||||
createNewDiv,
|
createNewDiv,
|
||||||
viewportInitializationStrategy,
|
defaultViewportInitializationStrategy,
|
||||||
targetStructureInitialization.viewport
|
isBody && !hasOwnProperty(targetStructureInitialization, 'viewport')
|
||||||
|
? targetElement
|
||||||
|
: viewportInitializationStrategy
|
||||||
),
|
),
|
||||||
staticInitializationElement(createNewDiv, viewportInitializationStrategy),
|
staticInitializationElement(createNewDiv, defaultViewportInitializationStrategy),
|
||||||
staticInitializationElement(createNewDiv),
|
staticInitializationElement(createNewDiv),
|
||||||
].filter((potentialViewport) =>
|
].filter((potentialViewport) =>
|
||||||
!singleElmSupport ? potentialViewport !== targetElement : true
|
singleElmSupport ? true : potentialViewport !== targetElement
|
||||||
)[0];
|
)[0];
|
||||||
const viewportIsTarget = viewportElement === targetElement;
|
const viewportIsTarget = viewportElement === targetElement;
|
||||||
const evaluatedTargetObj: StructureSetupElementsObj = {
|
const evaluatedTargetObj: StructureSetupElementsObj = {
|
||||||
@@ -134,8 +142,8 @@ export const createStructureSetupElements = (
|
|||||||
_host: isTextarea
|
_host: isTextarea
|
||||||
? staticInitializationElement(
|
? staticInitializationElement(
|
||||||
createNewDiv,
|
createNewDiv,
|
||||||
hostInitializationStrategy,
|
defaultHostInitializationStrategy,
|
||||||
targetStructureInitialization.host
|
hostInitializationStrategy
|
||||||
)
|
)
|
||||||
: (targetElement as HTMLElement),
|
: (targetElement as HTMLElement),
|
||||||
_viewport: viewportElement,
|
_viewport: viewportElement,
|
||||||
@@ -143,15 +151,15 @@ export const createStructureSetupElements = (
|
|||||||
!viewportIsTarget &&
|
!viewportIsTarget &&
|
||||||
dynamicInitializationElement(
|
dynamicInitializationElement(
|
||||||
createNewDiv,
|
createNewDiv,
|
||||||
paddingInitializationStrategy,
|
defaultPaddingInitializationStrategy,
|
||||||
targetStructureInitialization.padding
|
paddingInitializationStrategy
|
||||||
),
|
),
|
||||||
_content:
|
_content:
|
||||||
!viewportIsTarget &&
|
!viewportIsTarget &&
|
||||||
dynamicInitializationElement(
|
dynamicInitializationElement(
|
||||||
createNewDiv,
|
createNewDiv,
|
||||||
contentInitializationStrategy,
|
defaultContentInitializationStrategy,
|
||||||
targetStructureInitialization.content
|
contentInitializationStrategy
|
||||||
),
|
),
|
||||||
_viewportArrange:
|
_viewportArrange:
|
||||||
!viewportIsTarget &&
|
!viewportIsTarget &&
|
||||||
@@ -160,8 +168,6 @@ export const createStructureSetupElements = (
|
|||||||
createUniqueViewportArrangeElement(env),
|
createUniqueViewportArrangeElement(env),
|
||||||
_windowElm: wnd,
|
_windowElm: wnd,
|
||||||
_documentElm: ownerDocument,
|
_documentElm: ownerDocument,
|
||||||
_htmlElm: parent(bodyElm) as HTMLHtmlElement,
|
|
||||||
_bodyElm: bodyElm,
|
|
||||||
_isTextarea: isTextarea,
|
_isTextarea: isTextarea,
|
||||||
_isBody: isBody,
|
_isBody: isBody,
|
||||||
_targetIsElm: targetIsElm,
|
_targetIsElm: targetIsElm,
|
||||||
@@ -197,6 +203,9 @@ export const createStructureSetupElements = (
|
|||||||
const removePaddingClass = addClass(_padding, classNamePadding);
|
const removePaddingClass = addClass(_padding, classNamePadding);
|
||||||
const removeViewportClass = addClass(_viewport, !viewportIsTarget && classNameViewport);
|
const removeViewportClass = addClass(_viewport, !viewportIsTarget && classNameViewport);
|
||||||
const removeContentClass = addClass(_content, classNameContent);
|
const removeContentClass = addClass(_content, classNameContent);
|
||||||
|
const removeHtmlClass = isBody
|
||||||
|
? addClass(parent(targetElement), classNameViewportScrollbarHidden)
|
||||||
|
: noop;
|
||||||
|
|
||||||
// only insert host for textarea after target if it was generated
|
// only insert host for textarea after target if it was generated
|
||||||
if (isTextareaHostGenerated) {
|
if (isTextareaHostGenerated) {
|
||||||
@@ -214,6 +223,7 @@ export const createStructureSetupElements = (
|
|||||||
appendChildren(_viewport, _content);
|
appendChildren(_viewport, _content);
|
||||||
|
|
||||||
push(destroyFns, () => {
|
push(destroyFns, () => {
|
||||||
|
removeHtmlClass();
|
||||||
removeHostDataAttr();
|
removeHostDataAttr();
|
||||||
removeAttr(_viewport, dataAttributeHostOverflowX);
|
removeAttr(_viewport, dataAttributeHostOverflowX);
|
||||||
removeAttr(_viewport, dataAttributeHostOverflowY);
|
removeAttr(_viewport, dataAttributeHostOverflowY);
|
||||||
@@ -233,7 +243,7 @@ export const createStructureSetupElements = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (_nativeScrollbarsHiding && !viewportIsTarget) {
|
if (_nativeScrollbarsHiding && !viewportIsTarget) {
|
||||||
push(destroyFns, removeClass.bind(0, _viewport, classNameViewportScrollbarStyling));
|
push(destroyFns, removeClass.bind(0, _viewport, classNameViewportScrollbarHidden));
|
||||||
}
|
}
|
||||||
if (_viewportArrange) {
|
if (_viewportArrange) {
|
||||||
insertBefore(_viewport, _viewportArrange);
|
insertBefore(_viewport, _viewportArrange);
|
||||||
|
|||||||
+3
-3
@@ -2,7 +2,7 @@ import type {
|
|||||||
InitializationTargetElement,
|
InitializationTargetElement,
|
||||||
StaticInitializationElement,
|
StaticInitializationElement,
|
||||||
DynamicInitializationElement,
|
DynamicInitializationElement,
|
||||||
InitializtationElementStrategy,
|
DefaultInitializtationElement,
|
||||||
} from 'initialization';
|
} from 'initialization';
|
||||||
|
|
||||||
export type StructureStaticInitializationElement = StaticInitializationElement<
|
export type StructureStaticInitializationElement = StaticInitializationElement<
|
||||||
@@ -31,8 +31,8 @@ export interface StructureInitialization {
|
|||||||
content?: StructureDynamicInitializationElement;
|
content?: StructureDynamicInitializationElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type StructureInitializationStrategy = {
|
export type DefaultStructureInitialization = {
|
||||||
[K in keyof Omit<StructureInitialization, 'target'>]: InitializtationElementStrategy<
|
[K in keyof Omit<StructureInitialization, 'target'>]: DefaultInitializtationElement<
|
||||||
StructureInitialization[K]
|
StructureInitialization[K]
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import type { TRBL, XY, EventListener } from 'support';
|
|||||||
import type { Options, ReadonlyOSOptions } from 'options';
|
import type { Options, ReadonlyOSOptions } from 'options';
|
||||||
import type { Setup } from 'setups';
|
import type { Setup } from 'setups';
|
||||||
import type { InitializationTarget } from 'initialization';
|
import type { InitializationTarget } from 'initialization';
|
||||||
import type { PartialOptions, StyleObject, OverflowStyle } from 'typings';
|
import type { DeepPartial, StyleObject, OverflowStyle } from 'typings';
|
||||||
|
|
||||||
export interface StructureSetupState {
|
export interface StructureSetupState {
|
||||||
_padding: TRBL;
|
_padding: TRBL;
|
||||||
@@ -30,11 +30,7 @@ export interface StructureSetupStaticState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StructureSetupEventMap = {
|
type StructureSetupEventMap = {
|
||||||
u: [
|
u: [updateHints: StructureSetupUpdateHints, changedOptions: DeepPartial<Options>, force: boolean];
|
||||||
updateHints: StructureSetupUpdateHints,
|
|
||||||
changedOptions: PartialOptions<Options>,
|
|
||||||
force: boolean
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const initialXYNumber = { x: 0, y: 0 };
|
const initialXYNumber = { x: 0, y: 0 };
|
||||||
|
|||||||
@@ -57,13 +57,9 @@ export const createStructureSetupUpdate = (
|
|||||||
state: SetupState<StructureSetupState>
|
state: SetupState<StructureSetupState>
|
||||||
): StructureSetupUpdate => {
|
): StructureSetupUpdate => {
|
||||||
const { _viewport } = structureSetupElements;
|
const { _viewport } = structureSetupElements;
|
||||||
const {
|
const { _nativeScrollbarsHiding, _nativeScrollbarsOverlaid, _flexboxGlue } = getEnvironment();
|
||||||
_nativeScrollbarsHiding: _nativeScrollbarStyling,
|
|
||||||
_nativeScrollbarsOverlaid: _nativeScrollbarIsOverlaid,
|
|
||||||
_flexboxGlue,
|
|
||||||
} = getEnvironment();
|
|
||||||
const doViewportArrange =
|
const doViewportArrange =
|
||||||
!_nativeScrollbarStyling && (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y);
|
!_nativeScrollbarsHiding && (_nativeScrollbarsOverlaid.x || _nativeScrollbarsOverlaid.y);
|
||||||
|
|
||||||
const updateSegments: StructureSetupUpdateSegment[] = [
|
const updateSegments: StructureSetupUpdateSegment[] = [
|
||||||
createTrinsicUpdateSegment(structureSetupElements, state),
|
createTrinsicUpdateSegment(structureSetupElements, state),
|
||||||
|
|||||||
+5
-5
@@ -16,12 +16,12 @@ import {
|
|||||||
} from 'support';
|
} from 'support';
|
||||||
import { getEnvironment } from 'environment';
|
import { getEnvironment } from 'environment';
|
||||||
import {
|
import {
|
||||||
classNameViewportScrollbarStyling,
|
classNameViewportScrollbarHidden,
|
||||||
classNameOverflowVisible,
|
classNameOverflowVisible,
|
||||||
dataAttributeHost,
|
dataAttributeHost,
|
||||||
dataAttributeHostOverflowX,
|
dataAttributeHostOverflowX,
|
||||||
dataAttributeHostOverflowY,
|
dataAttributeHostOverflowY,
|
||||||
dataValueHostViewportScrollbarStyling,
|
dataValueHostScrollbarHidden,
|
||||||
dataValueHostOverflowVisible,
|
dataValueHostOverflowVisible,
|
||||||
} from 'classnames';
|
} from 'classnames';
|
||||||
import { getPlugins, scrollbarsHidingPluginName } from 'plugins';
|
import { getPlugins, scrollbarsHidingPluginName } from 'plugins';
|
||||||
@@ -328,7 +328,7 @@ export const createOverflowUpdateSegment: CreateStructureUpdateSegment = (
|
|||||||
} = updateHints;
|
} = updateHints;
|
||||||
const { _heightIntrinsic, _directionIsRTL } = getState();
|
const { _heightIntrinsic, _directionIsRTL } = getState();
|
||||||
const [showNativeOverlaidScrollbarsOption, showNativeOverlaidScrollbarsChanged] =
|
const [showNativeOverlaidScrollbarsOption, showNativeOverlaidScrollbarsChanged] =
|
||||||
checkOption<boolean>('nativeScrollbarsOverlaid.show');
|
checkOption<boolean>('showNativeOverlaidScrollbars');
|
||||||
const [overflow, overflowChanged] = checkOption<XY<OverflowBehavior>>('overflow');
|
const [overflow, overflowChanged] = checkOption<XY<OverflowBehavior>>('overflow');
|
||||||
|
|
||||||
const showNativeOverlaidScrollbars =
|
const showNativeOverlaidScrollbars =
|
||||||
@@ -356,8 +356,8 @@ export const createOverflowUpdateSegment: CreateStructureUpdateSegment = (
|
|||||||
|
|
||||||
if (showNativeOverlaidScrollbarsChanged && _nativeScrollbarsHiding) {
|
if (showNativeOverlaidScrollbarsChanged && _nativeScrollbarsHiding) {
|
||||||
_viewportAddRemoveClass(
|
_viewportAddRemoveClass(
|
||||||
classNameViewportScrollbarStyling,
|
classNameViewportScrollbarHidden,
|
||||||
dataValueHostViewportScrollbarStyling,
|
dataValueHostScrollbarHidden,
|
||||||
!showNativeOverlaidScrollbars
|
!showNativeOverlaidScrollbars
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,17 +53,20 @@
|
|||||||
.os-viewport {
|
.os-viewport {
|
||||||
-ms-overflow-style: scrollbar !important;
|
-ms-overflow-style: scrollbar !important;
|
||||||
}
|
}
|
||||||
[data-overlayscrollbars~='viewportStyled'],
|
[data-overlayscrollbars~='scrollbarHidden'],
|
||||||
.os-viewport-scrollbar-styled.os-environment,
|
html.os-viewport-scrollbar-hidden,
|
||||||
.os-viewport-scrollbar-styled.os-viewport {
|
.os-viewport-scrollbar-hidden.os-environment,
|
||||||
|
.os-viewport-scrollbar-hidden.os-viewport {
|
||||||
scrollbar-width: none !important;
|
scrollbar-width: none !important;
|
||||||
}
|
}
|
||||||
[data-overlayscrollbars~='viewportStyled']::-webkit-scrollbar,
|
[data-overlayscrollbars~='scrollbarHidden']::-webkit-scrollbar,
|
||||||
[data-overlayscrollbars~='viewportStyled']::-webkit-scrollbar-corner,
|
[data-overlayscrollbars~='scrollbarHidden']::-webkit-scrollbar-corner,
|
||||||
.os-viewport-scrollbar-styled.os-environment::-webkit-scrollbar,
|
html.os-viewport-scrollbar-hidden::-webkit-scrollbar,
|
||||||
.os-viewport-scrollbar-styled.os-viewport::-webkit-scrollbar,
|
html.os-viewport-scrollbar-hidden::-webkit-scrollbar-corner,
|
||||||
.os-viewport-scrollbar-styled.os-environment::-webkit-scrollbar-corner,
|
.os-viewport-scrollbar-hidden.os-environment::-webkit-scrollbar,
|
||||||
.os-viewport-scrollbar-styled.os-viewport::-webkit-scrollbar-corner {
|
.os-viewport-scrollbar-hidden.os-environment::-webkit-scrollbar-corner,
|
||||||
|
.os-viewport-scrollbar-hidden.os-viewport::-webkit-scrollbar,
|
||||||
|
.os-viewport-scrollbar-hidden.os-viewport::-webkit-scrollbar-corner {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
width: 0px !important;
|
width: 0px !important;
|
||||||
height: 0px !important;
|
height: 0px !important;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export type PartialOptions<T> = {
|
export type DeepPartial<T> = {
|
||||||
[P in keyof T]?: T[P] extends Record<string, unknown> ? PartialOptions<T[P]> : T[P];
|
[P in keyof T]?: T[P] extends Record<string, unknown> ? DeepPartial<T[P]> : T[P];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ReadonlyOptions<T> = {
|
export type ReadonlyOptions<T> = {
|
||||||
@@ -15,382 +15,3 @@ export type StyleObject<CustomCssProps = ''> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type OverflowStyle = 'scroll' | 'hidden' | 'visible';
|
export type OverflowStyle = 'scroll' | 'hidden' | 'visible';
|
||||||
|
|
||||||
/*
|
|
||||||
export namespace OverlayScrollbars {
|
|
||||||
export type ResizeBehavior = 'none' | 'both' | 'horizontal' | 'vertical';
|
|
||||||
|
|
||||||
export type OverflowBehavior = 'hidden' | 'scroll' | 'visible-hidden' | 'visible-scroll';
|
|
||||||
|
|
||||||
export type VisibilityBehavior = 'visible' | 'hidden' | 'auto';
|
|
||||||
|
|
||||||
export type AutoHideBehavior = 'never' | 'scroll' | 'leave' | 'move';
|
|
||||||
|
|
||||||
export type ScrollBehavior = 'always' | 'ifneeded' | 'never';
|
|
||||||
|
|
||||||
export type BlockBehavior = 'begin' | 'end' | 'center' | 'nearest';
|
|
||||||
|
|
||||||
export type Easing = string | null | undefined;
|
|
||||||
|
|
||||||
export type Margin = number | boolean;
|
|
||||||
|
|
||||||
export type Position = number | string;
|
|
||||||
|
|
||||||
export type Extensions = string | ReadonlyArray<string> | { [extensionName: string]: {} };
|
|
||||||
|
|
||||||
export type BasicEventCallback = (this: OverlayScrollbars) => void;
|
|
||||||
|
|
||||||
export type ScrollEventCallback = (this: OverlayScrollbars, args?: UIEvent) => void;
|
|
||||||
|
|
||||||
export type OverflowChangedCallback = (this: OverlayScrollbars, args?: OverflowChangedArgs) => void;
|
|
||||||
|
|
||||||
export type OverflowAmountChangedCallback = (this: OverlayScrollbars, args?: OverflowAmountChangedArgs) => void;
|
|
||||||
|
|
||||||
export type DirectionChangedCallback = (this: OverlayScrollbars, args?: DirectionChangedArgs) => void;
|
|
||||||
|
|
||||||
export type SizeChangedCallback = (this: OverlayScrollbars, args?: SizeChangedArgs) => void;
|
|
||||||
|
|
||||||
export type UpdatedCallback = (this: OverlayScrollbars, args?: UpdatedArgs) => void;
|
|
||||||
|
|
||||||
export type Coordinates =
|
|
||||||
| { x?: Position; y?: Position }
|
|
||||||
| { l?: Position; t?: Position }
|
|
||||||
| { left?: Position; top?: Position }
|
|
||||||
| [Position, Position]
|
|
||||||
| Position
|
|
||||||
| HTMLElement
|
|
||||||
| {
|
|
||||||
el: HTMLElement;
|
|
||||||
scroll?: ScrollBehavior | { x?: ScrollBehavior; y?: ScrollBehavior } | [ScrollBehavior, ScrollBehavior];
|
|
||||||
block?: BlockBehavior | { x?: BlockBehavior; y?: BlockBehavior } | [BlockBehavior, BlockBehavior];
|
|
||||||
margin?:
|
|
||||||
| Margin
|
|
||||||
| {
|
|
||||||
top?: Margin;
|
|
||||||
right?: Margin;
|
|
||||||
bottom?: Margin;
|
|
||||||
left?: Margin;
|
|
||||||
}
|
|
||||||
| [Margin, Margin]
|
|
||||||
| [Margin, Margin, Margin, Margin];
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface OverflowChangedArgs {
|
|
||||||
x: boolean;
|
|
||||||
y: boolean;
|
|
||||||
xScrollable: boolean;
|
|
||||||
yScrollable: boolean;
|
|
||||||
clipped: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OverflowAmountChangedArgs {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DirectionChangedArgs {
|
|
||||||
isRTL: number;
|
|
||||||
dir: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SizeChangedArgs {
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UpdatedArgs {
|
|
||||||
forced: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Options {
|
|
||||||
className?: string | null;
|
|
||||||
resize?: ResizeBehavior;
|
|
||||||
sizeAutoCapable?: boolean;
|
|
||||||
clipAlways?: boolean;
|
|
||||||
normalizeRTL?: boolean;
|
|
||||||
paddingAbsolute?: boolean;
|
|
||||||
autoUpdate?: boolean | null;
|
|
||||||
autoUpdateInterval?: number;
|
|
||||||
updateOnLoad?: string | ReadonlyArray<string> | null;
|
|
||||||
nativeScrollbarsOverlaid?: {
|
|
||||||
showNativeScrollbars?: boolean;
|
|
||||||
initialize?: boolean;
|
|
||||||
};
|
|
||||||
overflowBehavior?: {
|
|
||||||
x?: OverflowBehavior;
|
|
||||||
y?: OverflowBehavior;
|
|
||||||
};
|
|
||||||
scrollbars?: {
|
|
||||||
visibility?: VisibilityBehavior;
|
|
||||||
autoHide?: AutoHideBehavior;
|
|
||||||
autoHideDelay?: number;
|
|
||||||
dragScrolling?: boolean;
|
|
||||||
clickScrolling?: boolean;
|
|
||||||
touchSupport?: boolean;
|
|
||||||
snapHandle?: boolean;
|
|
||||||
};
|
|
||||||
textarea?: {
|
|
||||||
dynWidth?: boolean;
|
|
||||||
dynHeight?: boolean;
|
|
||||||
inheritedAttrs?: string | ReadonlyArray<string> | null;
|
|
||||||
};
|
|
||||||
callbacks?: {
|
|
||||||
onInitialized?: BasicEventCallback | null;
|
|
||||||
onInitializationWithdrawn?: BasicEventCallback | null;
|
|
||||||
onDestroyed?: BasicEventCallback | null;
|
|
||||||
onScrollStart?: ScrollEventCallback | null;
|
|
||||||
onScroll?: ScrollEventCallback | null;
|
|
||||||
onScrollStop?: ScrollEventCallback | null;
|
|
||||||
onOverflowChanged?: OverflowChangedCallback | null;
|
|
||||||
onOverflowAmountChanged?: OverflowAmountChangedCallback | null;
|
|
||||||
onDirectionChanged?: DirectionChangedCallback | null;
|
|
||||||
onContentSizeChanged?: SizeChangedCallback | null;
|
|
||||||
onHostSizeChanged?: SizeChangedCallback | null;
|
|
||||||
onUpdated?: UpdatedCallback | null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ScrollInfo {
|
|
||||||
position: {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
};
|
|
||||||
ratio: {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
};
|
|
||||||
handleOffset: {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
};
|
|
||||||
handleLength: {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
};
|
|
||||||
handleLengthRatio: {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
};
|
|
||||||
trackLength: {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
};
|
|
||||||
snappedHandleOffset: {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
};
|
|
||||||
isRTL: boolean;
|
|
||||||
isRTLNormalized: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Elements {
|
|
||||||
target: HTMLElement;
|
|
||||||
host: HTMLElement;
|
|
||||||
padding: HTMLElement;
|
|
||||||
viewport: HTMLElement;
|
|
||||||
content: HTMLElement;
|
|
||||||
scrollbarHorizontal: {
|
|
||||||
scrollbar: HTMLElement;
|
|
||||||
track: HTMLElement;
|
|
||||||
handle: HTMLElement;
|
|
||||||
};
|
|
||||||
scrollbarVertical: {
|
|
||||||
scrollbar: HTMLElement;
|
|
||||||
track: HTMLElement;
|
|
||||||
handle: HTMLElement;
|
|
||||||
};
|
|
||||||
scrollbarCorner: HTMLElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface State {
|
|
||||||
destroyed: boolean;
|
|
||||||
sleeping: boolean;
|
|
||||||
autoUpdate: boolean;
|
|
||||||
widthAuto: boolean;
|
|
||||||
heightAuto: boolean;
|
|
||||||
documentMixed: boolean;
|
|
||||||
padding: {
|
|
||||||
t: number;
|
|
||||||
r: number;
|
|
||||||
b: number;
|
|
||||||
l: number;
|
|
||||||
};
|
|
||||||
overflowAmount: {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
};
|
|
||||||
hideOverflow: {
|
|
||||||
x: boolean;
|
|
||||||
y: boolean;
|
|
||||||
xs: boolean;
|
|
||||||
ys: boolean;
|
|
||||||
};
|
|
||||||
hasOverflow: {
|
|
||||||
x: boolean;
|
|
||||||
y: boolean;
|
|
||||||
};
|
|
||||||
contentScrollSize: {
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
};
|
|
||||||
viewportSize: {
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
};
|
|
||||||
hostSize: {
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Extension {
|
|
||||||
contract(global: any): boolean;
|
|
||||||
|
|
||||||
added(options?: {}): void;
|
|
||||||
|
|
||||||
removed(): void;
|
|
||||||
|
|
||||||
on(
|
|
||||||
callbackName: string,
|
|
||||||
callbackArgs?: UIEvent | OverflowChangedArgs | OverflowAmountChangedArgs | DirectionChangedArgs | SizeChangedArgs | UpdatedArgs,
|
|
||||||
): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ExtensionInfo {
|
|
||||||
name: string;
|
|
||||||
extensionFactory: (this: OverlayScrollbars, defaultOptions: {}, compatibility: Compatibility, framework: any) => Extension;
|
|
||||||
defaultOptions?: {};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Globals {
|
|
||||||
defaultOptions: {};
|
|
||||||
autoUpdateLoop: boolean;
|
|
||||||
autoUpdateRecommended: boolean;
|
|
||||||
supportMutationObserver: boolean;
|
|
||||||
supportResizeObserver: boolean;
|
|
||||||
supportPassiveEvents: boolean;
|
|
||||||
supportTransform: boolean;
|
|
||||||
supportTransition: boolean;
|
|
||||||
restrictedMeasuring: boolean;
|
|
||||||
nativeScrollbarStyling: boolean;
|
|
||||||
cssCalc: string | null;
|
|
||||||
nativeScrollbarSize: {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
};
|
|
||||||
nativeScrollbarIsOverlaid: {
|
|
||||||
x: boolean;
|
|
||||||
y: boolean;
|
|
||||||
};
|
|
||||||
overlayScrollbarDummySize: {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
};
|
|
||||||
rtlScrollBehavior: {
|
|
||||||
i: boolean;
|
|
||||||
n: boolean;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Compatibility {
|
|
||||||
wW(): number;
|
|
||||||
wH(): number;
|
|
||||||
mO(): any;
|
|
||||||
rO(): any;
|
|
||||||
rAF(): (callback: (...args: any[]) => any) => number;
|
|
||||||
cAF(): (requestID: number) => void;
|
|
||||||
now(): number;
|
|
||||||
stpP(event: Event): void;
|
|
||||||
prvD(event: Event): void;
|
|
||||||
page(event: MouseEvent): { x: number; y: number };
|
|
||||||
mBtn(event: MouseEvent): number;
|
|
||||||
inA<T>(item: T, array: T[]): number;
|
|
||||||
isA(obj: any): boolean;
|
|
||||||
type(obj: any): string;
|
|
||||||
bind(func: (...args: any[]) => any, thisObj: any, ...args: any[]): any;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface OverlayScrollbars {
|
|
||||||
options(): OverlayScrollbars.Options;
|
|
||||||
options(options: OverlayScrollbars.Options): void;
|
|
||||||
options(optionName: string): any;
|
|
||||||
options(optionName: string, optionValue: {} | null): void;
|
|
||||||
|
|
||||||
update(force?: boolean): void;
|
|
||||||
|
|
||||||
sleep(): void;
|
|
||||||
|
|
||||||
scroll(): OverlayScrollbars.ScrollInfo;
|
|
||||||
scroll(
|
|
||||||
coordinates: OverlayScrollbars.Coordinates,
|
|
||||||
duration?: number,
|
|
||||||
easing?:
|
|
||||||
| OverlayScrollbars.Easing
|
|
||||||
| { x?: OverlayScrollbars.Easing; y?: OverlayScrollbars.Easing }
|
|
||||||
| [OverlayScrollbars.Easing, OverlayScrollbars.Easing],
|
|
||||||
complete?: (...args: any[]) => any,
|
|
||||||
): void;
|
|
||||||
scroll(coordinates: OverlayScrollbars.Coordinates, options: {}): void;
|
|
||||||
|
|
||||||
scrollStop(): OverlayScrollbars;
|
|
||||||
|
|
||||||
getElements(): OverlayScrollbars.Elements;
|
|
||||||
getElements(elementName: string): any;
|
|
||||||
|
|
||||||
getState(): OverlayScrollbars.State;
|
|
||||||
getState(stateProperty: string): any;
|
|
||||||
|
|
||||||
destroy(): void;
|
|
||||||
|
|
||||||
ext(): {};
|
|
||||||
ext(extensionName: string): OverlayScrollbars.Extension;
|
|
||||||
|
|
||||||
addExt(extensionName: string, options: {}): OverlayScrollbars.Extension;
|
|
||||||
|
|
||||||
removeExt(extensionName: string): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface OverlayScrollbarsStatic {
|
|
||||||
(element: HTMLElement | Element, options: OverlayScrollbars.Options, extensions?: OverlayScrollbars.Extensions): OverlayScrollbars;
|
|
||||||
(element: HTMLElement | Element | null): OverlayScrollbars | undefined;
|
|
||||||
|
|
||||||
(elements: NodeListOf<Element> | ReadonlyArray<Element>, options: OverlayScrollbars.Options, extensions?: OverlayScrollbars.Extensions):
|
|
||||||
| OverlayScrollbars
|
|
||||||
| OverlayScrollbars[]
|
|
||||||
| undefined;
|
|
||||||
(elements: NodeListOf<Element> | ReadonlyArray<Element>, filter?: string | ((element: Element, instance: OverlayScrollbars) => boolean)):
|
|
||||||
| OverlayScrollbars
|
|
||||||
| OverlayScrollbars[]
|
|
||||||
| undefined;
|
|
||||||
|
|
||||||
globals(): OverlayScrollbars.Globals;
|
|
||||||
|
|
||||||
defaultOptions(): OverlayScrollbars.Options;
|
|
||||||
defaultOptions(newDefaultOptions: OverlayScrollbars.Options): void;
|
|
||||||
|
|
||||||
extension(): {
|
|
||||||
[index: number]: OverlayScrollbars.ExtensionInfo;
|
|
||||||
length: number;
|
|
||||||
};
|
|
||||||
extension(extensionName: string): OverlayScrollbars.ExtensionInfo;
|
|
||||||
extension(
|
|
||||||
extensionName: string,
|
|
||||||
extensionFactory: (
|
|
||||||
this: OverlayScrollbars,
|
|
||||||
defaultOptions: {},
|
|
||||||
compatibility: OverlayScrollbars.Compatibility,
|
|
||||||
framework: any,
|
|
||||||
) => OverlayScrollbars.Extension,
|
|
||||||
defaultOptions?: {},
|
|
||||||
): void;
|
|
||||||
extension(extensionName: string, extensionFactory: null | undefined): void;
|
|
||||||
|
|
||||||
valid(osInstance: any): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|||||||
+5
-5
@@ -5,7 +5,7 @@ import {
|
|||||||
createStructureSetupElements,
|
createStructureSetupElements,
|
||||||
StructureSetupElementsObj,
|
StructureSetupElementsObj,
|
||||||
} from 'setups/structureSetup/structureSetup.elements';
|
} from 'setups/structureSetup/structureSetup.elements';
|
||||||
import type { InitializationTarget, InitializtationElementStrategy } from 'initialization';
|
import type { InitializationTarget, DefaultInitializtationElement } from 'initialization';
|
||||||
import type {
|
import type {
|
||||||
StructureInitialization,
|
StructureInitialization,
|
||||||
StructureStaticInitializationElement,
|
StructureStaticInitializationElement,
|
||||||
@@ -208,8 +208,8 @@ const assertCorrectSetupElements = (
|
|||||||
inputStrategy: StructureStaticInitializationElement | StructureDynamicInitializationElement,
|
inputStrategy: StructureStaticInitializationElement | StructureDynamicInitializationElement,
|
||||||
isStaticStrategy: boolean,
|
isStaticStrategy: boolean,
|
||||||
strategy:
|
strategy:
|
||||||
| InitializtationElementStrategy<StructureStaticInitializationElement>
|
| DefaultInitializtationElement<StructureStaticInitializationElement>
|
||||||
| InitializtationElementStrategy<StructureDynamicInitializationElement>,
|
| DefaultInitializtationElement<StructureDynamicInitializationElement>,
|
||||||
kind: 'padding' | 'viewport' | 'content' | 'host'
|
kind: 'padding' | 'viewport' | 'content' | 'host'
|
||||||
) => {
|
) => {
|
||||||
const input = isFunction(inputStrategy) ? inputStrategy(target) : inputStrategy;
|
const input = isFunction(inputStrategy) ? inputStrategy(target) : inputStrategy;
|
||||||
@@ -224,7 +224,7 @@ const assertCorrectSetupElements = (
|
|||||||
if (input === undefined) {
|
if (input === undefined) {
|
||||||
if (isStaticStrategy) {
|
if (isStaticStrategy) {
|
||||||
strategy =
|
strategy =
|
||||||
strategy as InitializtationElementStrategy<StructureStaticInitializationElement>;
|
strategy as DefaultInitializtationElement<StructureStaticInitializationElement>;
|
||||||
if (typeof strategy === 'function') {
|
if (typeof strategy === 'function') {
|
||||||
const result = strategy(target);
|
const result = strategy(target);
|
||||||
if (_viewportIsTarget) {
|
if (_viewportIsTarget) {
|
||||||
@@ -243,7 +243,7 @@ const assertCorrectSetupElements = (
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
strategy =
|
strategy =
|
||||||
strategy as InitializtationElementStrategy<StructureDynamicInitializationElement>;
|
strategy as DefaultInitializtationElement<StructureDynamicInitializationElement>;
|
||||||
|
|
||||||
if (typeof strategy === 'function') {
|
if (typeof strategy === 'function') {
|
||||||
const result = strategy(target);
|
const result = strategy(target);
|
||||||
|
|||||||
+6
-63
@@ -2,67 +2,10 @@ import './index.scss';
|
|||||||
import 'index.scss';
|
import 'index.scss';
|
||||||
import { OverlayScrollbars } from 'overlayscrollbars';
|
import { OverlayScrollbars } from 'overlayscrollbars';
|
||||||
|
|
||||||
OverlayScrollbars.env().setDefaultOptions({
|
// test with different cancel values for body
|
||||||
nativeScrollbarsOverlaid: { initialize: true },
|
|
||||||
|
OverlayScrollbars.env().setDefaultInitialization({
|
||||||
|
cancel: { nativeScrollbarsOverlaid: false },
|
||||||
});
|
});
|
||||||
|
// @ts-ignore
|
||||||
OverlayScrollbars.env().setInitializationStrategy({ viewport: (target) => target });
|
window.os = OverlayScrollbars({ target: document.body, cancel: { body: null } }, {});
|
||||||
|
|
||||||
window.os = OverlayScrollbars(document.body, {});
|
|
||||||
|
|
||||||
// test viewport inheritted attrs (tabindex) for multiple and single element init
|
|
||||||
// test appear & resize for multiple and single element init
|
|
||||||
// test children changing attr according to dom observer
|
|
||||||
|
|
||||||
/*
|
|
||||||
import { OverlayScrollbars } from 'overlayscrollbars';
|
|
||||||
|
|
||||||
import should from 'should';
|
|
||||||
import { resize } from '@/testing-browser/Resize';
|
|
||||||
import { timeout } from '@/testing-browser/timeout';
|
|
||||||
import { setTestResult, waitForOrFailTest } from '@/testing-browser/TestResult';
|
|
||||||
import { addClass, each, isArray, removeAttr, style } from 'support';
|
|
||||||
|
|
||||||
OverlayScrollbars.env().setDefaultOptions({
|
|
||||||
nativeScrollbarsOverlaid: { initialize: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
const startBtn: HTMLButtonElement | null = document.querySelector('#start');
|
|
||||||
const target: HTMLElement | null = document.querySelector('#target');
|
|
||||||
const updatesSlot: HTMLElement | null = document.querySelector('#update');
|
|
||||||
|
|
||||||
let updateCount = 0;
|
|
||||||
|
|
||||||
const osInstance = OverlayScrollbars(
|
|
||||||
{ target: target! },
|
|
||||||
{
|
|
||||||
updating: {
|
|
||||||
ignoreMutation(mutation) {
|
|
||||||
console.log(mutation);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
updated() {
|
|
||||||
updateCount++;
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
if (updatesSlot) {
|
|
||||||
updatesSlot.textContent = `${updateCount}`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const start = async () => {
|
|
||||||
setTestResult(null);
|
|
||||||
|
|
||||||
setTestResult(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
startBtn?.addEventListener('click', start);
|
|
||||||
*/
|
|
||||||
|
|||||||
+2
-2
@@ -18,8 +18,8 @@ if (!OverlayScrollbars.env().scrollbarsHiding) {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.OverlayScrollbars = OverlayScrollbars;
|
window.OverlayScrollbars = OverlayScrollbars;
|
||||||
|
|
||||||
OverlayScrollbars.env().setDefaultOptions({
|
OverlayScrollbars.env().setDefaultInitialization({
|
||||||
nativeScrollbarsOverlaid: { initialize: true },
|
cancel: { nativeScrollbarsOverlaid: false },
|
||||||
});
|
});
|
||||||
|
|
||||||
const startBtn: HTMLButtonElement | null = document.querySelector('#start');
|
const startBtn: HTMLButtonElement | null = document.querySelector('#start');
|
||||||
|
|||||||
+2
-2
@@ -14,8 +14,8 @@ import { timeout } from '@/testing-browser/timeout';
|
|||||||
import { setTestResult, waitForOrFailTest } from '@/testing-browser/TestResult';
|
import { setTestResult, waitForOrFailTest } from '@/testing-browser/TestResult';
|
||||||
import { addClass, each, isArray, removeAttr, style } from 'support';
|
import { addClass, each, isArray, removeAttr, style } from 'support';
|
||||||
|
|
||||||
OverlayScrollbars.env().setDefaultOptions({
|
OverlayScrollbars.env().setInitializationStrategy({
|
||||||
nativeScrollbarsOverlaid: { initialize: true },
|
cancel: { nativeScrollbarsOverlaid: false },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -23,7 +23,7 @@ import { setTestResult, waitForOrFailTest } from '@/testing-browser/TestResult';
|
|||||||
import { generateClassChangeSelectCallback, iterateSelect } from '@/testing-browser/Select';
|
import { generateClassChangeSelectCallback, iterateSelect } from '@/testing-browser/Select';
|
||||||
import { timeout } from '@/testing-browser/timeout';
|
import { timeout } from '@/testing-browser/timeout';
|
||||||
import { Options } from 'options';
|
import { Options } from 'options';
|
||||||
import { PartialOptions } from 'typings';
|
import { DeepPartial } from 'typings';
|
||||||
import { addPlugin, scrollbarsHidingPlugin, sizeObserverPlugin } from 'plugins';
|
import { addPlugin, scrollbarsHidingPlugin, sizeObserverPlugin } from 'plugins';
|
||||||
|
|
||||||
if (!window.ResizeObserver) {
|
if (!window.ResizeObserver) {
|
||||||
@@ -36,8 +36,8 @@ if (!OverlayScrollbars.env().scrollbarsHiding) {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.OverlayScrollbars = OverlayScrollbars;
|
window.OverlayScrollbars = OverlayScrollbars;
|
||||||
|
|
||||||
OverlayScrollbars.env().setDefaultOptions({
|
OverlayScrollbars.env().setDefaultInitialization({
|
||||||
nativeScrollbarsOverlaid: { initialize: true },
|
cancel: { nativeScrollbarsOverlaid: false },
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Metrics {
|
interface Metrics {
|
||||||
@@ -587,7 +587,7 @@ const iterateMinMax = async (afterEach?: () => any) => {
|
|||||||
await iterate(containerMinMaxSelect, afterEach);
|
await iterate(containerMinMaxSelect, afterEach);
|
||||||
};
|
};
|
||||||
|
|
||||||
const overflowTest = async (osOptions?: PartialOptions<Options>) => {
|
const overflowTest = async (osOptions?: DeepPartial<Options>) => {
|
||||||
const additiveOverflow = () => {
|
const additiveOverflow = () => {
|
||||||
if (isFractionalPixelRatio()) {
|
if (isFractionalPixelRatio()) {
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -1,297 +0,0 @@
|
|||||||
type CacheValues<T> = [
|
|
||||||
value: T,
|
|
||||||
changed: boolean,
|
|
||||||
previous?: T
|
|
||||||
];
|
|
||||||
type UpdateCache<Value> = (force?: boolean) => CacheValues<Value>;
|
|
||||||
interface WH<T> {
|
|
||||||
w: T;
|
|
||||||
h: T;
|
|
||||||
}
|
|
||||||
type PartialOptions<T> = {
|
|
||||||
[P in keyof T]?: T[P] extends Record<string, unknown> ? PartialOptions<T[P]> : T[P];
|
|
||||||
};
|
|
||||||
type StyleObject<CustomCssProps> = {
|
|
||||||
[Key in keyof CSSStyleDeclaration | (CustomCssProps extends string ? CustomCssProps : "")]?: string | number;
|
|
||||||
};
|
|
||||||
type OverflowStyle = "scroll" | "hidden" | "visible";
|
|
||||||
interface TRBL {
|
|
||||||
t: number;
|
|
||||||
r: number;
|
|
||||||
b: number;
|
|
||||||
l: number;
|
|
||||||
}
|
|
||||||
interface XY<T> {
|
|
||||||
x: T;
|
|
||||||
y: T;
|
|
||||||
}
|
|
||||||
type EventListener<EventMap extends Record<string, any[]>, Name extends keyof EventMap> = (...args: EventMap[Name]) => void;
|
|
||||||
type InitialEventListeners<EventMap extends Record<string, any[]>> = {
|
|
||||||
[K in keyof EventMap]?: EventListener<EventMap> | EventListener<EventMap>[];
|
|
||||||
};
|
|
||||||
type OverflowBehavior = "hidden" | "scroll" | "visible" | "visible-hidden" | "visible-scroll";
|
|
||||||
type ScrollbarVisibilityBehavior = "visible" | "hidden" | "auto";
|
|
||||||
type ScrollbarAutoHideBehavior = "never" | "scroll" | "leave" | "move";
|
|
||||||
interface Options {
|
|
||||||
paddingAbsolute: boolean;
|
|
||||||
updating: {
|
|
||||||
elementEvents: Array<[
|
|
||||||
elementSelector: string,
|
|
||||||
eventNames: string
|
|
||||||
]> | null;
|
|
||||||
attributes: string[] | null;
|
|
||||||
debounce: [
|
|
||||||
timeout: number,
|
|
||||||
maxWait: number
|
|
||||||
] | number | null; // (if tuple: [timeout: 0, maxWait: 33], if number: [timeout: number, maxWait: false]) debounce for content Changes
|
|
||||||
ignoreMutation: ((mutation: MutationRecord) => any) | null;
|
|
||||||
};
|
|
||||||
overflow: {
|
|
||||||
x: OverflowBehavior;
|
|
||||||
y: OverflowBehavior;
|
|
||||||
};
|
|
||||||
scrollbars: {
|
|
||||||
theme: string | null;
|
|
||||||
visibility: ScrollbarVisibilityBehavior;
|
|
||||||
autoHide: ScrollbarAutoHideBehavior;
|
|
||||||
autoHideDelay: number;
|
|
||||||
dragScroll: boolean;
|
|
||||||
clickScroll: boolean;
|
|
||||||
touch: boolean;
|
|
||||||
};
|
|
||||||
nativeScrollbarsOverlaid: {
|
|
||||||
show: boolean;
|
|
||||||
initialize: boolean;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
type PluginInstance = Record<string, unknown> | ((staticObj: OverlayScrollbarsStatic, instanceObj: OverlayScrollbars) => void);
|
|
||||||
type Plugin<T extends PluginInstance> = {
|
|
||||||
[pluginName: string]: T;
|
|
||||||
};
|
|
||||||
type OptionsValidationPluginInstance = {
|
|
||||||
_: (options: PartialOptions<Options>, doWriteErrors?: boolean) => PartialOptions<Options>;
|
|
||||||
};
|
|
||||||
declare const optionsValidationPlugin: Plugin<OptionsValidationPluginInstance>;
|
|
||||||
type SizeObserverPluginInstance = {
|
|
||||||
_: (listenerElement: HTMLElement, onSizeChangedCallback: (appear: boolean) => any, observeAppearChange: boolean) => [
|
|
||||||
appearCallback: () => any,
|
|
||||||
offFns: (() => any)[]
|
|
||||||
];
|
|
||||||
};
|
|
||||||
declare const sizeObserverPlugin: Plugin<SizeObserverPluginInstance>;
|
|
||||||
type StaticInitialization = HTMLElement | null | undefined;
|
|
||||||
type DynamicInitialization = HTMLElement | boolean | null | undefined;
|
|
||||||
type InitializationTargetElement = HTMLElement | HTMLTextAreaElement;
|
|
||||||
type InitializationTargetObject = StructureInitialization & ScrollbarsInitialization;
|
|
||||||
type InitializationTarget = InitializationTargetElement | InitializationTargetObject;
|
|
||||||
type InitializationStrategy = StructureInitializationStrategy & ScrollbarsInitializationStrategy;
|
|
||||||
/**
|
|
||||||
* Static elements MUST be present.
|
|
||||||
* Null or undefined behave like if this element wasn't specified during initialization.
|
|
||||||
*/
|
|
||||||
type StaticInitializationElement<Args extends any[]> = ((...args: Args) => StaticInitialization) | StaticInitialization;
|
|
||||||
/**
|
|
||||||
* Dynamic element CAN be present.
|
|
||||||
* If its a element the element will be handled as the repsective element.
|
|
||||||
* True means that the respective dynamic element is forced to be generated.
|
|
||||||
* False means that the respective dynamic element is forced NOT to be generated.
|
|
||||||
* Null or undefined behave like if this element wasn't specified during initialization.
|
|
||||||
*/
|
|
||||||
type DynamicInitializationElement<Args extends any[]> = ((...args: Args) => DynamicInitialization) | DynamicInitialization;
|
|
||||||
type InitializtationElementStrategy<InitElm> = Exclude<InitElm, HTMLElement>;
|
|
||||||
type ScrollbarsDynamicInitializationElement = DynamicInitializationElement<[
|
|
||||||
target: InitializationTargetElement,
|
|
||||||
host: HTMLElement,
|
|
||||||
viewport: HTMLElement
|
|
||||||
]>;
|
|
||||||
/**
|
|
||||||
* Object for special initialization.
|
|
||||||
*
|
|
||||||
* If element is provided, the provided element takes all its responsibilities.
|
|
||||||
* DOM hierarchy isn't checked in this case, its assumed that hieararchy is correct in such a case.
|
|
||||||
*
|
|
||||||
* Null or Undefined means that the environment initialization strategy is used.
|
|
||||||
*/
|
|
||||||
interface ScrollbarsInitialization {
|
|
||||||
scrollbarsSlot?: ScrollbarsDynamicInitializationElement;
|
|
||||||
}
|
|
||||||
type ScrollbarsInitializationStrategy = {
|
|
||||||
[K in keyof ScrollbarsInitialization]: InitializtationElementStrategy<ScrollbarsInitialization[K]>;
|
|
||||||
};
|
|
||||||
interface StructureSetupState {
|
|
||||||
_padding: TRBL;
|
|
||||||
_paddingAbsolute: boolean;
|
|
||||||
_viewportPaddingStyle: StyleObject;
|
|
||||||
_overflowEdge: XY<number>;
|
|
||||||
_overflowAmount: XY<number>;
|
|
||||||
_overflowStyle: XY<OverflowStyle>;
|
|
||||||
_hasOverflow: XY<boolean>;
|
|
||||||
_heightIntrinsic: boolean;
|
|
||||||
_directionIsRTL: boolean;
|
|
||||||
}
|
|
||||||
type StructureStaticInitializationElement = StaticInitializationElement<[
|
|
||||||
target: InitializationTargetElement
|
|
||||||
]>;
|
|
||||||
type StructureDynamicInitializationElement = DynamicInitializationElement<[
|
|
||||||
target: InitializationTargetElement
|
|
||||||
]>;
|
|
||||||
/**
|
|
||||||
* Object for special initialization.
|
|
||||||
*
|
|
||||||
* Target is always required, if element is not provided or undefined it will be generated.
|
|
||||||
*
|
|
||||||
* If element is provided, the provided element takes all its responsibilities.
|
|
||||||
* DOM hierarchy isn't checked in this case, its assumed that hieararchy is correct in such a case.
|
|
||||||
*
|
|
||||||
* Null or Undefined means that the environment initialization strategy is used.
|
|
||||||
*/
|
|
||||||
interface StructureInitialization {
|
|
||||||
target: InitializationTargetElement;
|
|
||||||
host?: StructureStaticInitializationElement; // only relevant for textarea
|
|
||||||
viewport?: StructureStaticInitializationElement;
|
|
||||||
padding?: StructureDynamicInitializationElement;
|
|
||||||
content?: StructureDynamicInitializationElement;
|
|
||||||
}
|
|
||||||
type StructureInitializationStrategy = {
|
|
||||||
[K in keyof Omit<StructureInitialization, "target">]: InitializtationElementStrategy<StructureInitialization[K]>;
|
|
||||||
};
|
|
||||||
interface ViewportOverflowState {
|
|
||||||
_scrollbarsHideOffset: XY<number>;
|
|
||||||
_scrollbarsHideOffsetArrange: XY<boolean>;
|
|
||||||
_overflowScroll: XY<boolean>;
|
|
||||||
_overflowStyle: XY<OverflowStyle>;
|
|
||||||
}
|
|
||||||
type GetViewportOverflowState = (showNativeOverlaidScrollbars: boolean, viewportStyleObj?: StyleObject) => ViewportOverflowState;
|
|
||||||
type HideNativeScrollbars = (viewportOverflowState: ViewportOverflowState, directionIsRTL: boolean, viewportArrange: boolean, viewportStyleObj: StyleObject) => void;
|
|
||||||
type EnvironmentEventMap = {
|
|
||||||
_: [
|
|
||||||
];
|
|
||||||
};
|
|
||||||
interface InternalEnvironment {
|
|
||||||
readonly _nativeScrollbarsSize: XY;
|
|
||||||
readonly _nativeScrollbarsOverlaid: XY<boolean>;
|
|
||||||
readonly _nativeScrollbarsHiding: boolean;
|
|
||||||
readonly _rtlScrollBehavior: {
|
|
||||||
n: boolean;
|
|
||||||
i: boolean;
|
|
||||||
};
|
|
||||||
readonly _flexboxGlue: boolean;
|
|
||||||
readonly _cssCustomProperties: boolean;
|
|
||||||
readonly _defaultInitializationStrategy: InitializationStrategy;
|
|
||||||
readonly _defaultDefaultOptions: Options;
|
|
||||||
_addListener(listener: EventListener<EnvironmentEventMap, "_">): () => void;
|
|
||||||
_getInitializationStrategy(): InitializationStrategy;
|
|
||||||
_setInitializationStrategy(newInitializationStrategy: Partial<InitializationStrategy>): void;
|
|
||||||
_getDefaultOptions(): Options;
|
|
||||||
_setDefaultOptions(newDefaultOptions: PartialOptions<Options>): void;
|
|
||||||
}
|
|
||||||
type ArrangeViewport = (viewportOverflowState: ViewportOverflowState, viewportScrollSize: WH<number>, sizeFraction: WH<number>, directionIsRTL: boolean) => boolean;
|
|
||||||
type UndoViewportArrangeResult = [
|
|
||||||
redoViewportArrange: () => void,
|
|
||||||
overflowState?: ViewportOverflowState
|
|
||||||
];
|
|
||||||
type UndoArrangeViewport = (showNativeOverlaidScrollbars: boolean, directionIsRTL: boolean, viewportOverflowState?: ViewportOverflowState) => UndoViewportArrangeResult;
|
|
||||||
type ScrollbarsHidingPluginInstance = {
|
|
||||||
_createUniqueViewportArrangeElement(env: InternalEnvironment): HTMLStyleElement | false;
|
|
||||||
_overflowUpdateSegment(doViewportArrange: boolean, flexboxGlue: boolean, viewport: HTMLElement, viewportArrange: HTMLStyleElement | false | null | undefined, getState: () => StructureSetupState, getViewportOverflowState: GetViewportOverflowState, hideNativeScrollbars: HideNativeScrollbars): [
|
|
||||||
ArrangeViewport,
|
|
||||||
UndoArrangeViewport
|
|
||||||
];
|
|
||||||
_envWindowZoom(): (envInstance: InternalEnvironment, updateNativeScrollbarSizeCache: UpdateCache<XY<number>>, triggerEvent: () => void) => void;
|
|
||||||
};
|
|
||||||
declare const scrollbarsHidingPlugin: Plugin<ScrollbarsHidingPluginInstance>;
|
|
||||||
type GeneralInitialEventListeners = InitialEventListeners;
|
|
||||||
type GeneralEventListener = EventListener;
|
|
||||||
interface OverlayScrollbarsStatic {
|
|
||||||
(target: InitializationTarget | InitializationTargetObject, options?: PartialOptions<Options>, eventListeners?: GeneralInitialEventListeners<EventListenerMap>): OverlayScrollbars;
|
|
||||||
plugin(plugin: Plugin | Plugin[]): void;
|
|
||||||
env(): Environment;
|
|
||||||
}
|
|
||||||
interface Environment {
|
|
||||||
scrollbarsSize: XY<number>;
|
|
||||||
scrollbarsOverlaid: XY<boolean>;
|
|
||||||
scrollbarsHiding: boolean;
|
|
||||||
rtlScrollBehavior: {
|
|
||||||
n: boolean;
|
|
||||||
i: boolean;
|
|
||||||
};
|
|
||||||
flexboxGlue: boolean;
|
|
||||||
cssCustomProperties: boolean;
|
|
||||||
defaultInitializationStrategy: InitializationStrategy;
|
|
||||||
defaultDefaultOptions: Options;
|
|
||||||
getInitializationStrategy(): InitializationStrategy;
|
|
||||||
setInitializationStrategy(newInitializationStrategy: Partial<InitializationStrategy>): void;
|
|
||||||
getDefaultOptions(): Options;
|
|
||||||
setDefaultOptions(newDefaultOptions: PartialOptions<Options>): void;
|
|
||||||
}
|
|
||||||
interface State {
|
|
||||||
padding: TRBL;
|
|
||||||
paddingAbsolute: boolean;
|
|
||||||
overflowEdge: XY<number>;
|
|
||||||
overflowAmount: XY<number>;
|
|
||||||
overflowStyle: XY<OverflowStyle>;
|
|
||||||
hasOverflow: XY<boolean>;
|
|
||||||
destroyed: boolean;
|
|
||||||
}
|
|
||||||
interface Elements {
|
|
||||||
target: HTMLElement;
|
|
||||||
host: HTMLElement;
|
|
||||||
padding: HTMLElement;
|
|
||||||
viewport: HTMLElement;
|
|
||||||
content: HTMLElement;
|
|
||||||
}
|
|
||||||
interface OnUpdatedEventListenerArgs {
|
|
||||||
updateHints: {
|
|
||||||
sizeChanged: boolean;
|
|
||||||
directionChanged: boolean;
|
|
||||||
heightIntrinsicChanged: boolean;
|
|
||||||
overflowEdgeChanged: boolean;
|
|
||||||
overflowAmountChanged: boolean;
|
|
||||||
overflowStyleChanged: boolean;
|
|
||||||
hostMutation: boolean;
|
|
||||||
contentMutation: boolean;
|
|
||||||
};
|
|
||||||
changedOptions: PartialOptions<Options>;
|
|
||||||
force: boolean;
|
|
||||||
}
|
|
||||||
type EventListenerMap = {
|
|
||||||
/**
|
|
||||||
* Triggered after all elements are initialized and appended.
|
|
||||||
*/
|
|
||||||
initialized: [
|
|
||||||
instance: OverlayScrollbars
|
|
||||||
];
|
|
||||||
/**
|
|
||||||
* Triggered after an update.
|
|
||||||
*/
|
|
||||||
updated: [
|
|
||||||
instance: OverlayScrollbars,
|
|
||||||
onUpdatedArgs: OnUpdatedEventListenerArgs
|
|
||||||
];
|
|
||||||
/**
|
|
||||||
* Triggered after all elements, observers and events are destroyed.
|
|
||||||
*/
|
|
||||||
destroyed: [
|
|
||||||
instance: OverlayScrollbars,
|
|
||||||
withdrawn: boolean
|
|
||||||
];
|
|
||||||
};
|
|
||||||
type EventListener$0<Name extends keyof EventListenerMap> = GeneralEventListener<EventListenerMap, Name>;
|
|
||||||
interface OverlayScrollbars {
|
|
||||||
options(): Options;
|
|
||||||
options(newOptions?: PartialOptions<Options>): Options;
|
|
||||||
update(force?: boolean): OverlayScrollbars;
|
|
||||||
destroy(): void;
|
|
||||||
state(): State;
|
|
||||||
elements(): Elements;
|
|
||||||
on<Name extends keyof EventListenerMap>(name: Name, listener: EventListener$0<Name>): () => void;
|
|
||||||
on<Name extends keyof EventListenerMap>(name: Name, listener: EventListener$0<Name>[]): () => void;
|
|
||||||
off<Name extends keyof EventListenerMap>(name: Name, listener: EventListener$0<Name>): void;
|
|
||||||
off<Name extends keyof EventListenerMap>(name: Name, listener: EventListener$0<Name>[]): void;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Notes:
|
|
||||||
* Height intrinsic detection use "content: true" init strategy - or open ticket for custom height intrinsic observer
|
|
||||||
*/
|
|
||||||
declare const OverlayScrollbars: OverlayScrollbarsStatic;
|
|
||||||
export { OverlayScrollbars, optionsValidationPlugin, scrollbarsHidingPlugin, sizeObserverPlugin };
|
|
||||||
Reference in New Issue
Block a user