mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-05-23 14:34:08 +03:00
improve code
This commit is contained in:
+23
-21
@@ -19,7 +19,7 @@
|
||||
z-index: -1;
|
||||
contain: strict;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
padding: inherit;
|
||||
border: inherit;
|
||||
@@ -118,11 +118,15 @@
|
||||
min-height: 1px;
|
||||
min-width: 1px; }
|
||||
|
||||
[data-overlayscrollbars~='updating'] > .os-scrollbar {
|
||||
display: none !important; }
|
||||
|
||||
.os-scrollbar {
|
||||
contain: strict;
|
||||
transition: opacity 0.3s, visibility 0.3s, top 0.3s, right 0.3s, bottom 0.3s, left 0.3s;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
z-index: 99999;
|
||||
opacity: 0;
|
||||
visibility: hidden; }
|
||||
|
||||
@@ -133,30 +137,24 @@ body > .os-scrollbar {
|
||||
transition: none; }
|
||||
|
||||
.os-scrollbar-track {
|
||||
pointer-events: none;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
direction: ltr !important;
|
||||
padding: 0 !important;
|
||||
border: none !important; }
|
||||
|
||||
.os-scrollbar-handle {
|
||||
position: absolute; }
|
||||
|
||||
.os-scrollbar-track,
|
||||
.os-scrollbar-handle {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%; }
|
||||
|
||||
.os-scrollbar-handle-interactive,
|
||||
.os-scrollbar-track-interactive {
|
||||
pointer-events: auto; }
|
||||
|
||||
.os-scrollbar-unusable,
|
||||
.os-scrollbar-unusable * {
|
||||
pointer-events: none !important; }
|
||||
|
||||
.os-scrollbar-unusable .os-scrollbar-handle {
|
||||
opacity: 0 !important;
|
||||
visibility: hidden Im !important; }
|
||||
.os-scrollbar.os-scrollbar-track-interactive .os-scrollbar-track,
|
||||
.os-scrollbar.os-scrollbar-handle-interactive .os-scrollbar-handle {
|
||||
pointer-events: auto;
|
||||
touch-action: none; }
|
||||
|
||||
.os-scrollbar-horizontal {
|
||||
bottom: 0;
|
||||
@@ -173,7 +171,8 @@ body > .os-scrollbar {
|
||||
right: auto;
|
||||
left: 0; }
|
||||
|
||||
.os-scrollbar-visible {
|
||||
.os-scrollbar-visible,
|
||||
.os-scrollbar-interaction.os-scrollbar-visible {
|
||||
opacity: 1;
|
||||
visibility: visible; }
|
||||
|
||||
@@ -181,9 +180,12 @@ body > .os-scrollbar {
|
||||
opacity: 0;
|
||||
visibility: hidden; }
|
||||
|
||||
.os-scrollbar-interaction.os-scrollbar-visible {
|
||||
opacity: 1;
|
||||
visibility: visible; }
|
||||
.os-scrollbar-unusable,
|
||||
.os-scrollbar-unusable * {
|
||||
pointer-events: none !important; }
|
||||
|
||||
.os-scrollbar-unusable .os-scrollbar-handle {
|
||||
opacity: 0 !important; }
|
||||
|
||||
.os-scrollbar.os-scrollbar-horizontal.os-scrollbar-cornerless {
|
||||
left: 0;
|
||||
|
||||
+806
-666
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1067
-930
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,9 +1,7 @@
|
||||
import {
|
||||
Cache,
|
||||
CacheValues,
|
||||
createCache,
|
||||
createDOM,
|
||||
style,
|
||||
scrollLeft,
|
||||
scrollTop,
|
||||
runEachAndClear,
|
||||
@@ -18,6 +16,7 @@ import {
|
||||
isObject,
|
||||
stopPropagation,
|
||||
appendChildren,
|
||||
directionIsRTL,
|
||||
} from 'support';
|
||||
import { getEnvironment } from 'environment';
|
||||
import {
|
||||
@@ -41,7 +40,6 @@ export interface SizeObserverCallbackParams {
|
||||
export type SizeObserver = [destroy: () => void, append: () => void];
|
||||
|
||||
const scrollAmount = 3333333;
|
||||
const getElmDirectionIsRTL = (elm: HTMLElement): boolean => style(elm, 'direction') === 'rtl';
|
||||
const domRectHasDimensions = (rect?: DOMRectReadOnly) => rect && (rect.height || rect.width);
|
||||
|
||||
/**
|
||||
@@ -67,7 +65,7 @@ export const createSizeObserver = (
|
||||
);
|
||||
const sizeObserver = baseElements[0] as HTMLElement;
|
||||
const listenerElement = sizeObserver.firstChild as HTMLElement;
|
||||
const getIsDirectionRTL = getElmDirectionIsRTL.bind(0, sizeObserver);
|
||||
const getIsDirectionRTL = directionIsRTL.bind(0, target);
|
||||
const [updateResizeObserverContentRectCache] = createCache<DOMRectReadOnly | undefined>({
|
||||
_initialValue: undefined,
|
||||
_alwaysUpdateValues: true,
|
||||
@@ -117,7 +115,7 @@ export const createSizeObserver = (
|
||||
if (observeDirectionChange && doDirectionScroll) {
|
||||
const rtl = hasDirectionCache
|
||||
? (sizeChangedContext as CacheValues<boolean>)[0]
|
||||
: getElmDirectionIsRTL(sizeObserver);
|
||||
: directionIsRTL(sizeObserver);
|
||||
scrollLeft(
|
||||
sizeObserver,
|
||||
rtl
|
||||
@@ -145,7 +143,6 @@ export const createSizeObserver = (
|
||||
let appearCallback: ((...args: any) => any) | false = observeAppearChange
|
||||
? onSizeChangedCallbackProxy
|
||||
: false;
|
||||
let directionIsRTLCache: Cache<boolean> | undefined;
|
||||
|
||||
return [
|
||||
() => {
|
||||
@@ -170,23 +167,22 @@ export const createSizeObserver = (
|
||||
}
|
||||
|
||||
if (observeDirectionChange) {
|
||||
directionIsRTLCache = createCache(
|
||||
const [updateDirectionIsRTLCache] = createCache(
|
||||
{
|
||||
_initialValue: !getIsDirectionRTL(), // invert current value to trigger initial change
|
||||
},
|
||||
getIsDirectionRTL
|
||||
);
|
||||
const [updateDirectionIsRTLCache] = directionIsRTLCache;
|
||||
|
||||
push(
|
||||
offListeners,
|
||||
on(sizeObserver, 'scroll', (event: Event) => {
|
||||
const directionIsRTLCacheValues = updateDirectionIsRTLCache();
|
||||
const [directionIsRTL, directionIsRTLChanged] = directionIsRTLCacheValues;
|
||||
const [directionIsRTLCache, directionIsRTLCacheChanged] = directionIsRTLCacheValues;
|
||||
|
||||
if (directionIsRTLChanged) {
|
||||
if (directionIsRTLCacheChanged) {
|
||||
removeClass(listenerElement, 'ltr rtl');
|
||||
if (directionIsRTL) {
|
||||
if (directionIsRTLCache) {
|
||||
addClass(listenerElement, 'rtl');
|
||||
} else {
|
||||
addClass(listenerElement, 'ltr');
|
||||
|
||||
@@ -61,6 +61,7 @@ export interface State {
|
||||
overflowAmount: XY<number>;
|
||||
overflowStyle: XY<OverflowStyle>;
|
||||
hasOverflow: XY<boolean>;
|
||||
directionRTL: boolean;
|
||||
destroyed: boolean;
|
||||
}
|
||||
|
||||
@@ -213,6 +214,7 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
||||
_hasOverflow,
|
||||
_padding,
|
||||
_paddingAbsolute,
|
||||
_directionIsRTL,
|
||||
} = structureState();
|
||||
return assignDeep(
|
||||
{},
|
||||
@@ -223,6 +225,7 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
||||
hasOverflow: _hasOverflow,
|
||||
padding: _padding,
|
||||
paddingAbsolute: _paddingAbsolute,
|
||||
directionRTL: _directionIsRTL,
|
||||
destroyed,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
addClass,
|
||||
appendChildren,
|
||||
createDiv,
|
||||
directionIsRTL,
|
||||
each,
|
||||
isBoolean,
|
||||
isEmptyArray,
|
||||
@@ -138,7 +139,7 @@ export const createScrollbarsSetupElements = (
|
||||
_track,
|
||||
_scrollOffsetElement,
|
||||
structureSetupState,
|
||||
style(_scrollbar, 'direction') === 'rtl',
|
||||
directionIsRTL(_scrollbar),
|
||||
isHorizontal
|
||||
);
|
||||
// eslint-disable-next-line no-self-compare
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import {
|
||||
directionIsRTL,
|
||||
getBoundingClientRect,
|
||||
offsetSize,
|
||||
on,
|
||||
preventDefault,
|
||||
runEachAndClear,
|
||||
stopPropagation,
|
||||
style,
|
||||
XY,
|
||||
} from 'support';
|
||||
import { classNamesScrollbarInteraction } from 'classnames';
|
||||
@@ -25,7 +25,7 @@ export type ScrollbarsSetupEvents = (
|
||||
isHorizontal?: boolean
|
||||
) => () => void;
|
||||
|
||||
const { round, abs } = Math;
|
||||
const { round } = Math;
|
||||
const getPageOffset = (event: PointerEvent): XY<number> => ({
|
||||
x: event.pageX,
|
||||
y: event.pageY,
|
||||
@@ -81,12 +81,11 @@ const createDragScrollingEvents = (
|
||||
const handleTrackDiff = offsetSize(_track)[whKey] - offsetSize(_handle)[whKey];
|
||||
const scrollDeltaPercent = movement / handleTrackDiff;
|
||||
const scrollDelta = scrollDeltaPercent * _overflowAmount[xyKey];
|
||||
const isRTL = style(_scrollbar, 'direction') === 'rtl';
|
||||
const isRTL = directionIsRTL(_scrollbar);
|
||||
const negateMultiplactor =
|
||||
isRTL && isHorizontal ? (_rtlScrollBehavior.n || _rtlScrollBehavior.i ? 1 : -1) : 1;
|
||||
|
||||
scrollOffsetElement[scrollOffsetKey] =
|
||||
abs(mouseDownScroll) + scrollDelta * negateMultiplactor;
|
||||
scrollOffsetElement[scrollOffsetKey] = mouseDownScroll + scrollDelta * negateMultiplactor;
|
||||
};
|
||||
|
||||
return on(_handle, 'pointerdown', (pointerDownEvent: PointerEvent) => {
|
||||
|
||||
@@ -158,6 +158,7 @@ export const createStructureSetupObservers = (
|
||||
_heightIntrinsicChanged: heightIntrinsicChanged,
|
||||
};
|
||||
setState({ _heightIntrinsic: heightIntrinsic });
|
||||
|
||||
!fromRecords && structureSetupUpdate(updateHints);
|
||||
return updateHints;
|
||||
};
|
||||
@@ -175,6 +176,7 @@ export const createStructureSetupObservers = (
|
||||
if (_directionIsRTLCache) {
|
||||
const [directionIsRTL, directionIsRTLChanged] = _directionIsRTLCache;
|
||||
directionChanged = directionIsRTLChanged;
|
||||
|
||||
setState({ _directionIsRTL: directionIsRTL });
|
||||
}
|
||||
|
||||
|
||||
@@ -109,6 +109,9 @@ export const show = (elm: HTMLElement | false | null | undefined): void => {
|
||||
style(elm, { display: 'block' });
|
||||
};
|
||||
|
||||
export const directionIsRTL = (elm: HTMLElement | false | null | undefined): boolean =>
|
||||
style(elm, 'direction') === 'rtl';
|
||||
|
||||
/**
|
||||
* Returns the top right bottom left values of the passed css property.
|
||||
* @param elm The element of which the values shall be returned.
|
||||
|
||||
+24
-33
@@ -58,7 +58,7 @@ interface Options {
|
||||
autoHideDelay: number;
|
||||
dragScroll: boolean;
|
||||
clickScroll: boolean;
|
||||
touch: boolean;
|
||||
pointers: string[] | null;
|
||||
};
|
||||
}
|
||||
type PluginInstance = Record<string, unknown> | ((staticObj: OverlayScrollbarsStatic, instanceObj: OverlayScrollbars) => void);
|
||||
@@ -72,32 +72,29 @@ type SizeObserverPluginInstance = {
|
||||
];
|
||||
};
|
||||
declare const sizeObserverPlugin: Plugin<SizeObserverPluginInstance>;
|
||||
type StaticInitialization = HTMLElement | null | undefined;
|
||||
type DynamicInitialization = HTMLElement | boolean | null | undefined;
|
||||
type CancelInitialization = {
|
||||
type StaticInitialization = HTMLElement | false | null;
|
||||
type DynamicInitialization = HTMLElement | boolean | null;
|
||||
type InitializationTargetElement = HTMLElement | HTMLTextAreaElement;
|
||||
type Initialization = Omit<StructureInitialization, "target"> & ScrollbarsInitialization & {
|
||||
cancel: {
|
||||
nativeScrollbarsOverlaid: boolean | undefined;
|
||||
body: boolean | null | undefined;
|
||||
nativeScrollbarsOverlaid: boolean;
|
||||
body: boolean | null;
|
||||
};
|
||||
};
|
||||
type InitializationTargetElement = HTMLElement | HTMLTextAreaElement;
|
||||
type InitializationTargetObject = StructureInitialization & ScrollbarsInitialization & DeepPartial<CancelInitialization>;
|
||||
type InitializationTargetObject = DeepPartial<Initialization> & Pick<StructureInitialization, "target">;
|
||||
type InitializationTarget = InitializationTargetElement | InitializationTargetObject;
|
||||
type DefaultInitialization = DefaultStructureInitialization & DefaultScrollbarsInitialization & CancelInitialization;
|
||||
/**
|
||||
* Static elements MUST be present.
|
||||
* Null or undefined behave like if this element wasn't specified during initialization.
|
||||
* With false, null or undefined the element will be generated, otherwise the specified element is taken.
|
||||
*/
|
||||
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.
|
||||
* If its a element the element will be taken as the repsective element.
|
||||
* With true the element will be generated.
|
||||
* With false, null or undefined the element won't be generated.
|
||||
*/
|
||||
type DynamicInitializationElement<Args extends any[]> = ((...args: Args) => DynamicInitialization) | DynamicInitialization;
|
||||
type DefaultInitializtationElement<InitElm> = Exclude<InitElm, HTMLElement>;
|
||||
type ScrollbarsDynamicInitializationElement = DynamicInitializationElement<[
|
||||
target: InitializationTargetElement,
|
||||
host: HTMLElement,
|
||||
@@ -112,11 +109,8 @@ type ScrollbarsDynamicInitializationElement = DynamicInitializationElement<[
|
||||
* Null or Undefined means that the environment initialization strategy is used.
|
||||
*/
|
||||
interface ScrollbarsInitialization {
|
||||
scrollbarsSlot?: ScrollbarsDynamicInitializationElement;
|
||||
scrollbarsSlot: ScrollbarsDynamicInitializationElement;
|
||||
}
|
||||
type DefaultScrollbarsInitialization = {
|
||||
[K in keyof ScrollbarsInitialization]: DefaultInitializtationElement<ScrollbarsInitialization[K]>;
|
||||
};
|
||||
interface StructureSetupState {
|
||||
_padding: TRBL;
|
||||
_paddingAbsolute: boolean;
|
||||
@@ -146,14 +140,11 @@ type StructureDynamicInitializationElement = DynamicInitializationElement<[
|
||||
*/
|
||||
interface StructureInitialization {
|
||||
target: InitializationTargetElement;
|
||||
host?: StructureStaticInitializationElement; // only relevant for textarea
|
||||
viewport?: StructureStaticInitializationElement;
|
||||
padding?: StructureDynamicInitializationElement;
|
||||
content?: StructureDynamicInitializationElement;
|
||||
host: StructureStaticInitializationElement; // only relevant for textarea
|
||||
viewport: StructureStaticInitializationElement;
|
||||
padding: StructureDynamicInitializationElement;
|
||||
content: StructureDynamicInitializationElement;
|
||||
}
|
||||
type DefaultStructureInitialization = {
|
||||
[K in keyof Omit<StructureInitialization, "target">]: DefaultInitializtationElement<StructureInitialization[K]>;
|
||||
};
|
||||
interface ViewportOverflowState {
|
||||
_scrollbarsHideOffset: XY<number>;
|
||||
_scrollbarsHideOffsetArrange: XY<boolean>;
|
||||
@@ -176,11 +167,11 @@ interface InternalEnvironment {
|
||||
};
|
||||
readonly _flexboxGlue: boolean;
|
||||
readonly _cssCustomProperties: boolean;
|
||||
readonly _staticDefaultInitialization: DefaultInitialization;
|
||||
readonly _staticDefaultInitialization: Initialization;
|
||||
readonly _staticDefaultOptions: Options;
|
||||
_addListener(listener: EventListener<EnvironmentEventMap, "_">): () => void;
|
||||
_getDefaultInitialization(): DefaultInitialization;
|
||||
_setDefaultInitialization(newInitialization: DeepPartial<DefaultInitialization>): void;
|
||||
_getDefaultInitialization(): Initialization;
|
||||
_setDefaultInitialization(newInitialization: DeepPartial<Initialization>): void;
|
||||
_getDefaultOptions(): Options;
|
||||
_setDefaultOptions(newDefaultOptions: DeepPartial<Options>): void;
|
||||
}
|
||||
@@ -202,7 +193,7 @@ declare const scrollbarsHidingPlugin: Plugin<ScrollbarsHidingPluginInstance>;
|
||||
type GeneralInitialEventListeners = InitialEventListeners;
|
||||
type GeneralEventListener = EventListener;
|
||||
interface OverlayScrollbarsStatic {
|
||||
(target: InitializationTarget | InitializationTargetObject, options?: DeepPartial<Options>, eventListeners?: GeneralInitialEventListeners<EventListenerMap>): OverlayScrollbars;
|
||||
(target: InitializationTarget, options?: DeepPartial<Options>, eventListeners?: GeneralInitialEventListeners<EventListenerMap>): OverlayScrollbars;
|
||||
plugin(plugin: Plugin | Plugin[]): void;
|
||||
env(): Environment;
|
||||
}
|
||||
@@ -216,10 +207,10 @@ interface Environment {
|
||||
};
|
||||
flexboxGlue: boolean;
|
||||
cssCustomProperties: boolean;
|
||||
staticDefaultInitialization: DefaultInitialization;
|
||||
staticDefaultInitialization: Initialization;
|
||||
staticDefaultOptions: Options;
|
||||
getDefaultInitialization(): DefaultInitialization;
|
||||
setDefaultInitialization(newDefaultInitialization: DeepPartial<DefaultInitialization>): void;
|
||||
getDefaultInitialization(): Initialization;
|
||||
setDefaultInitialization(newDefaultInitialization: DeepPartial<Initialization>): void;
|
||||
getDefaultOptions(): Options;
|
||||
setDefaultOptions(newDefaultOptions: DeepPartial<Options>): void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user