mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-25 12:20:35 +03:00
merge conflicts
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
||||
createDiv,
|
||||
each,
|
||||
isEmptyArray,
|
||||
noop,
|
||||
on,
|
||||
push,
|
||||
removeClass,
|
||||
@@ -11,6 +12,7 @@ import {
|
||||
runEachAndClear,
|
||||
setT,
|
||||
stopPropagation,
|
||||
style,
|
||||
} from 'support';
|
||||
import {
|
||||
classNameScrollbar,
|
||||
@@ -30,6 +32,7 @@ import type {
|
||||
ScrollbarsInitializationStrategy,
|
||||
ScrollbarsDynamicInitializationElement,
|
||||
} from 'setups/scrollbarsSetup/scrollbarsSetup.initialization';
|
||||
import { StyleObject } from 'typings';
|
||||
|
||||
export interface ScrollbarStructure {
|
||||
_scrollbar: HTMLElement;
|
||||
@@ -40,7 +43,16 @@ export interface ScrollbarStructure {
|
||||
export interface ScrollbarsSetupElement {
|
||||
_scrollbarStructures: ScrollbarStructure[];
|
||||
_clone: () => ScrollbarStructure;
|
||||
_addRemoveClass: (classNames: string | false | null | undefined, add?: boolean) => void;
|
||||
_addRemoveClass: (
|
||||
classNames: string,
|
||||
add?: boolean,
|
||||
elm?: (scrollbarStructure: ScrollbarStructure) => HTMLElement | false | null | undefined
|
||||
) => void;
|
||||
_handleStyle: (
|
||||
elmStyle: (
|
||||
scrollbarStructure: ScrollbarStructure
|
||||
) => [HTMLElement | false | null | undefined, StyleObject]
|
||||
) => void;
|
||||
// _removeClass: (classNames: string) => void;
|
||||
/*
|
||||
_addEventListener: () => void;
|
||||
@@ -89,12 +101,24 @@ export const createScrollbarsSetupElements = (
|
||||
);
|
||||
const scrollbarsAddRemoveClass = (
|
||||
scrollbarStructures: ScrollbarStructure[],
|
||||
classNames: string | false | null | undefined,
|
||||
add?: boolean
|
||||
classNames: string,
|
||||
add?: boolean,
|
||||
elm?: (scrollbarStructure: ScrollbarStructure) => HTMLElement | false | null | undefined
|
||||
) => {
|
||||
const action = add ? addClass : removeClass;
|
||||
each(scrollbarStructures, (scrollbarStructure) => {
|
||||
action(scrollbarStructure._scrollbar, classNames);
|
||||
action((elm || noop)(scrollbarStructure) || scrollbarStructure._scrollbar, classNames);
|
||||
});
|
||||
};
|
||||
const scrollbarsHandleStyle = (
|
||||
scrollbarStructures: ScrollbarStructure[],
|
||||
elmStyle: (
|
||||
scrollbarStructure: ScrollbarStructure
|
||||
) => [HTMLElement | false | null | undefined, StyleObject]
|
||||
) => {
|
||||
each(scrollbarStructures, (scrollbarStructure) => {
|
||||
const [elm, styles] = elmStyle(scrollbarStructure);
|
||||
style(elm, styles);
|
||||
});
|
||||
};
|
||||
const destroyFns: (() => void)[] = [];
|
||||
@@ -160,11 +184,13 @@ export const createScrollbarsSetupElements = (
|
||||
_scrollbarStructures: horizontalScrollbars,
|
||||
_clone: generateHorizontalScrollbarStructure,
|
||||
_addRemoveClass: addRemoveClassHorizontal,
|
||||
_handleStyle: scrollbarsHandleStyle.bind(0, horizontalScrollbars),
|
||||
},
|
||||
_vertical: {
|
||||
_scrollbarStructures: verticalScrollbars,
|
||||
_clone: generateVerticalScrollbarStructure,
|
||||
_addRemoveClass: addRemoveClassVertical,
|
||||
_handleStyle: scrollbarsHandleStyle.bind(0, verticalScrollbars),
|
||||
},
|
||||
},
|
||||
appendElements,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { rAF, cAF, isFunction, on, runEachAndClear, setT, clearT } from 'support
|
||||
import { createState, createOptionCheck } from 'setups/setups';
|
||||
import {
|
||||
createScrollbarsSetupElements,
|
||||
ScrollbarsSetupElement,
|
||||
ScrollbarsSetupElementsObj,
|
||||
} from 'setups/scrollbarsSetup/scrollbarsSetup.elements';
|
||||
import {
|
||||
@@ -17,7 +18,7 @@ import type {
|
||||
} from 'options';
|
||||
import type { Setup, StructureSetupState, StructureSetupStaticState } from 'setups';
|
||||
import type { InitializationTarget } from 'initialization';
|
||||
import type { OverflowStyle } from 'typings';
|
||||
import type { OverflowStyle, StyleObject } from 'typings';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface ScrollbarsSetupState {}
|
||||
@@ -27,6 +28,7 @@ export interface ScrollbarsSetupStaticState {
|
||||
_appendElements: () => void;
|
||||
}
|
||||
|
||||
const { min } = Math;
|
||||
const createSelfCancelTimeout = (timeout?: number | (() => number)) => {
|
||||
let id: number;
|
||||
const setTFn = timeout ? setT : rAF!;
|
||||
@@ -41,6 +43,105 @@ const createSelfCancelTimeout = (timeout?: number | (() => number)) => {
|
||||
] as [timeout: (callback: () => any) => void, clear: () => void];
|
||||
};
|
||||
|
||||
const refreshScrollbarHandleLength = (
|
||||
setStyleFn: ScrollbarsSetupElement['_handleStyle'],
|
||||
structureSetupState: StructureSetupState,
|
||||
isHorizontal?: boolean
|
||||
) => {
|
||||
const { _overflowAmount, _overflowEdge } = structureSetupState;
|
||||
const axis = isHorizontal ? 'x' : 'y';
|
||||
const viewportSize = _overflowEdge[axis];
|
||||
const overflowAmount = _overflowAmount[axis];
|
||||
const handleRatio = min(1, viewportSize / (viewportSize + overflowAmount));
|
||||
|
||||
setStyleFn((structure) => [
|
||||
structure._handle,
|
||||
{
|
||||
[isHorizontal ? 'width' : 'height']: `${(handleRatio * 100).toFixed(3)}%`,
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
const refreshScrollbarHandlePosition = (
|
||||
setStyleFn: (styles: StyleObject) => void,
|
||||
structureSetupState: StructureSetupState,
|
||||
isHorizontal?: boolean
|
||||
) => {
|
||||
/*
|
||||
//measure the handle length to respect min & max length
|
||||
var handleLength = scrollbarVarsInfo._handleLength;
|
||||
var trackLength = scrollbarVars._track[0]['offset' + scrollbarVars._Width_Height];
|
||||
var handleTrackDiff = trackLength - handleLength;
|
||||
var handleCSS = {};
|
||||
var transformOffset;
|
||||
var translateValue;
|
||||
|
||||
//DONT use the variable '_contentScrollSizeCache[scrollbarVars._w_h]' instead of '_viewportElement[0]['scroll' + scrollbarVars._Width_Height]'
|
||||
// because its a bit behind during the small delay when content size updates
|
||||
//(delay = mutationObserverContentLag, if its 0 then this var could be used)
|
||||
var maxScroll =
|
||||
(_viewportElementNative[_strScroll + scrollbarVars._Width_Height] -
|
||||
_viewportElementNative['client' + scrollbarVars._Width_Height]) *
|
||||
(_rtlScrollBehavior.n && isRTLisHorizontal ? -1 : 1); //* -1 if rtl scroll max is negative
|
||||
var getScrollRatio = function (base) {
|
||||
return isNaN(base / maxScroll) ? 0 : MATH.max(0, MATH.min(1, base / maxScroll));
|
||||
};
|
||||
var getHandleOffset = function (scrollRatio) {
|
||||
var offset = handleTrackDiff * scrollRatio;
|
||||
offset = isNaN(offset) ? 0 : offset;
|
||||
offset =
|
||||
isRTLisHorizontal && !_rtlScrollBehavior.i ? trackLength - handleLength - offset : offset;
|
||||
offset = MATH.max(0, offset);
|
||||
return offset;
|
||||
};
|
||||
var scrollRatio = getScrollRatio(nativeScroll);
|
||||
var unsnappedScrollRatio = getScrollRatio(currentScroll);
|
||||
var handleOffset = getHandleOffset(unsnappedScrollRatio);
|
||||
var snappedHandleOffset = getHandleOffset(scrollRatio);
|
||||
|
||||
scrollbarVarsInfo._maxScroll = maxScroll;
|
||||
scrollbarVarsInfo._currentScroll = nativeScroll;
|
||||
scrollbarVarsInfo._currentScrollRatio = scrollRatio;
|
||||
|
||||
if (_supportTransform) {
|
||||
transformOffset = isRTLisHorizontal
|
||||
? -(trackLength - handleLength - handleOffset)
|
||||
: handleOffset; //in px
|
||||
//transformOffset = (transformOffset / trackLength * 100) * (trackLength / handleLength); //in %
|
||||
translateValue = isHorizontal
|
||||
? strTranslateBrace + transformOffset + 'px, 0)'
|
||||
: strTranslateBrace + '0, ' + transformOffset + 'px)';
|
||||
|
||||
handleCSS[strTransform] = translateValue;
|
||||
|
||||
//apply or clear up transition
|
||||
if (_supportTransition)
|
||||
handleCSS[strTransition] =
|
||||
transition && MATH.abs(handleOffset - scrollbarVarsInfo._handleOffset) > 1
|
||||
? getCSSTransitionString(scrollbarVars._handle) +
|
||||
', ' +
|
||||
(strTransform + _strSpace + transitionDuration + 'ms')
|
||||
: _strEmpty;
|
||||
} else handleCSS[scrollbarVars._left_top] = handleOffset;
|
||||
|
||||
//only apply css if offset has changed and overflow exists.
|
||||
if (!nativeOverlayScrollbarsAreActive()) {
|
||||
scrollbarVars._handle.css(handleCSS);
|
||||
|
||||
//clear up transition
|
||||
if (_supportTransform && _supportTransition && transition) {
|
||||
scrollbarVars._handle.one(_strTransitionEndEvent, function () {
|
||||
if (!_destroyed) scrollbarVars._handle.css(strTransition, _strEmpty);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
scrollbarVarsInfo._handleOffset = handleOffset;
|
||||
scrollbarVarsInfo._snappedHandleOffset = snappedHandleOffset;
|
||||
scrollbarVarsInfo._trackLength = trackLength;
|
||||
*/
|
||||
};
|
||||
|
||||
export const createScrollbarsSetup = (
|
||||
target: InitializationTarget,
|
||||
options: ReadonlyOSOptions,
|
||||
@@ -66,8 +167,8 @@ export const createScrollbarsSetup = (
|
||||
);
|
||||
const { _host, _viewport } = structureSetupState._elements;
|
||||
const { _horizontal, _vertical } = elements;
|
||||
const { _addRemoveClass: addRemoveClassHorizontal } = _horizontal;
|
||||
const { _addRemoveClass: addRemoveClassVertical } = _vertical;
|
||||
const { _addRemoveClass: addRemoveClassHorizontal, _handleStyle: styleHorizontal } = _horizontal;
|
||||
const { _addRemoveClass: addRemoveClassVertical, _handleStyle: styleVertical } = _vertical;
|
||||
const manageScrollbarsAutoHide = (removeAutoHide: boolean, delayless?: boolean) => {
|
||||
clearAutoTimeout();
|
||||
if (removeAutoHide) {
|
||||
@@ -133,6 +234,7 @@ export const createScrollbarsSetup = (
|
||||
const { _overflowEdgeChanged, _overflowAmountChanged, _overflowStyleChanged } =
|
||||
structureUpdateHints;
|
||||
const checkOption = createOptionCheck(options, changedOptions, force);
|
||||
const currStructureSetupState = structureSetupState();
|
||||
|
||||
const [theme, themeChanged] = checkOption<string | null>('scrollbars.theme');
|
||||
const [visibility, visibilityChanged] =
|
||||
@@ -145,7 +247,7 @@ export const createScrollbarsSetup = (
|
||||
);
|
||||
const [touchSupport, touchSupportChanged] = checkOption<boolean>('scrollbars.touchSupport');
|
||||
|
||||
const updateHandleSize = _overflowEdgeChanged || _overflowAmountChanged;
|
||||
const updateHandle = _overflowEdgeChanged || _overflowAmountChanged;
|
||||
const updateVisibility = _overflowStyleChanged || visibilityChanged;
|
||||
|
||||
const setScrollbarVisibility = (
|
||||
@@ -161,7 +263,7 @@ export const createScrollbarsSetup = (
|
||||
globalAutoHideDelay = autoHideDelay;
|
||||
|
||||
if (updateVisibility) {
|
||||
const { _overflowStyle } = structureSetupState();
|
||||
const { _overflowStyle } = currStructureSetupState;
|
||||
|
||||
const xVisible = setScrollbarVisibility(_overflowStyle.x, addRemoveClassHorizontal);
|
||||
const yVisible = setScrollbarVisibility(_overflowStyle.y, addRemoveClassVertical);
|
||||
@@ -184,6 +286,10 @@ export const createScrollbarsSetup = (
|
||||
autoHideNotNever = autoHide !== 'never';
|
||||
manageScrollbarsAutoHide(!autoHideNotNever, true);
|
||||
}
|
||||
if (updateHandle) {
|
||||
refreshScrollbarHandleLength(styleHorizontal, currStructureSetupState, true);
|
||||
refreshScrollbarHandleLength(styleVertical, currStructureSetupState);
|
||||
}
|
||||
},
|
||||
scrollbarsSetupState,
|
||||
runEachAndClear.bind(0, destroyFns),
|
||||
|
||||
@@ -20,6 +20,8 @@ import {
|
||||
closest,
|
||||
assignDeep,
|
||||
push,
|
||||
scrollLeft,
|
||||
scrollTop,
|
||||
} from 'support';
|
||||
import { getEnvironment } from 'environment';
|
||||
import {
|
||||
@@ -28,6 +30,7 @@ import {
|
||||
classNameViewport,
|
||||
classNameOverflowVisible,
|
||||
classNameScrollbar,
|
||||
classNameViewportArrange,
|
||||
} from 'classnames';
|
||||
import { createSizeObserver, SizeObserverCallbackParams } from 'observers/sizeObserver';
|
||||
import { createTrinsicObserver } from 'observers/trinsicObserver';
|
||||
@@ -91,14 +94,21 @@ export const createStructureSetupObservers = (
|
||||
_initialValue: { w: 0, h: 0 },
|
||||
},
|
||||
() => {
|
||||
const has = _viewportHasClass(classNameOverflowVisible, dataValueHostOverflowVisible);
|
||||
has && _viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible);
|
||||
const hasOver = _viewportHasClass(classNameOverflowVisible, dataValueHostOverflowVisible);
|
||||
const hasVpStyle = _viewportHasClass(classNameViewportArrange, '');
|
||||
const scrollOffsetX = hasVpStyle && scrollLeft(_viewport);
|
||||
const scrollOffsetY = hasVpStyle && scrollTop(_viewport);
|
||||
_viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible);
|
||||
_viewportAddRemoveClass(classNameViewportArrange, '');
|
||||
|
||||
const contentScroll = scrollSize(_content);
|
||||
const viewportScroll = scrollSize(_viewport);
|
||||
const fractional = fractionalSize(_viewport);
|
||||
|
||||
has && _viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible, true);
|
||||
_viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible, hasOver);
|
||||
_viewportAddRemoveClass(classNameViewportArrange, '', hasVpStyle);
|
||||
scrollLeft(_viewport, scrollOffsetX);
|
||||
scrollTop(_viewport, scrollOffsetY);
|
||||
return {
|
||||
w: viewportScroll.w + contentScroll.w + fractional.w,
|
||||
h: viewportScroll.h + contentScroll.h + fractional.h,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { each, isNumber, scrollLeft, scrollTop, assignDeep, keys } from 'support';
|
||||
import { each, scrollLeft, scrollTop, assignDeep, keys } from 'support';
|
||||
import { getEnvironment } from 'environment';
|
||||
import {
|
||||
createTrinsicUpdateSegment,
|
||||
@@ -107,12 +107,8 @@ export const createStructureSetupUpdate = (
|
||||
);
|
||||
});
|
||||
|
||||
if (isNumber(scrollOffsetX)) {
|
||||
scrollLeft(_viewport, scrollOffsetX);
|
||||
}
|
||||
if (isNumber(scrollOffsetY)) {
|
||||
scrollTop(_viewport, scrollOffsetY);
|
||||
}
|
||||
|
||||
return adaptivedUpdateHints;
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ body > .os-scrollbar {
|
||||
transition: none;
|
||||
}
|
||||
.os-scrollbar-track {
|
||||
pointer-events: auto;
|
||||
pointer-events: none;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@@ -21,14 +21,14 @@ body > .os-scrollbar {
|
||||
border: none !important;
|
||||
}
|
||||
.os-scrollbar-handle {
|
||||
pointer-events: auto;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.os-scrollbar-handle-off,
|
||||
.os-scrollbar-track-off {
|
||||
pointer-events: none;
|
||||
.os-scrollbar-handle-interactive,
|
||||
.os-scrollbar-track-interactive {
|
||||
pointer-events: auto;
|
||||
}
|
||||
.os-scrollbar-unusable,
|
||||
.os-scrollbar-unusable * {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { from } from 'support/utils/array';
|
||||
import { isUndefined } from 'support/utils/types';
|
||||
import { isNull, isUndefined } from 'support/utils/types';
|
||||
|
||||
type GetSetPropName = 'scrollLeft' | 'scrollTop' | 'value';
|
||||
|
||||
@@ -14,20 +14,20 @@ type Attr = {
|
||||
|
||||
type GetSetProp<T> = {
|
||||
(elm: HTMLElement | false | null | undefined): T;
|
||||
(elm: HTMLElement | false | null | undefined, value: T): void;
|
||||
(elm: HTMLElement | false | null | undefined, value?: T): number | void;
|
||||
(elm: HTMLElement | false | null | undefined, value: T | false | null): void;
|
||||
(elm: HTMLElement | false | null | undefined, value?: T | false | null): T | void;
|
||||
};
|
||||
|
||||
const getSetProp = (
|
||||
topLeft: GetSetPropName,
|
||||
fallback: number | string,
|
||||
elm: HTMLElement | HTMLInputElement | false | null | undefined,
|
||||
value?: number | string
|
||||
value?: number | string | false | null
|
||||
): number | string | void => {
|
||||
if (isUndefined(value)) {
|
||||
return elm ? elm[topLeft] : fallback;
|
||||
}
|
||||
elm && (elm[topLeft] = value);
|
||||
elm && !isNull(value) && value !== false && (elm[topLeft] = value);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -61,11 +61,13 @@ export const attrClass = (
|
||||
value: string,
|
||||
add?: boolean
|
||||
) => {
|
||||
if (value) {
|
||||
const currValues = attr(elm, attrName) || '';
|
||||
const currValuesSet = new Set(currValues.split(' '));
|
||||
currValuesSet[add ? 'add' : 'delete'](value);
|
||||
|
||||
attr(elm, attrName, from(currValuesSet).join(' ').trim());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -101,7 +103,7 @@ export const removeAttr = (elm: Element | false | null | undefined, attrName: st
|
||||
*/
|
||||
export const scrollLeft = ((
|
||||
elm: HTMLElement | false | null | undefined,
|
||||
value?: number
|
||||
value?: number | false | null
|
||||
): number | void => getSetProp('scrollLeft', 0, elm, value) as number) as GetSetProp<number>;
|
||||
|
||||
/**
|
||||
@@ -111,7 +113,7 @@ export const scrollLeft = ((
|
||||
*/
|
||||
export const scrollTop = ((
|
||||
elm: HTMLElement | false | null | undefined,
|
||||
value?: number
|
||||
value?: number | false | null
|
||||
): number | void => getSetProp('scrollTop', 0, elm, value) as number) as GetSetProp<number>;
|
||||
|
||||
/**
|
||||
|
||||
@@ -74,7 +74,7 @@ const contents = (elm: InputElementType): ReadonlyArray<ChildNode> =>
|
||||
*/
|
||||
const parent = (elm: InputElementType): OutputElementType => (elm ? elm.parentElement : null);
|
||||
|
||||
export const closest = (elm: InputElementType, selector: string): OutputElementType => {
|
||||
const closest = (elm: InputElementType, selector: string): OutputElementType => {
|
||||
if (isElement(elm)) {
|
||||
const closestFn = elmPrototype.closest;
|
||||
if (closestFn) {
|
||||
@@ -113,4 +113,4 @@ const liesBetween = (
|
||||
: false;
|
||||
};
|
||||
|
||||
export { find, findFirst, is, children, contents, parent, liesBetween };
|
||||
export { find, findFirst, is, children, contents, parent, liesBetween, closest };
|
||||
|
||||
-1
@@ -30,7 +30,6 @@ if (!window.ResizeObserver) {
|
||||
addPlugin(sizeObserverPlugin);
|
||||
}
|
||||
if (!OverlayScrollbars.env().scrollbarsHiding) {
|
||||
console.log('added');
|
||||
addPlugin(scrollbarsHidingPlugin);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user