mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-20 11:20:35 +03:00
improve intialization to body and fix showNativeOverlaidScrollbars option
This commit is contained in:
@@ -3,6 +3,7 @@ export const classNameEnvironmentFlexboxGlue = `${classNameEnvironment}-flexbox-
|
|||||||
export const classNameEnvironmentFlexboxGlueMax = `${classNameEnvironmentFlexboxGlue}-max`;
|
export const classNameEnvironmentFlexboxGlueMax = `${classNameEnvironmentFlexboxGlue}-max`;
|
||||||
|
|
||||||
export const dataAttributeHost = 'data-overlayscrollbars';
|
export const dataAttributeHost = 'data-overlayscrollbars';
|
||||||
|
export const dataAttributeInitialize = 'data-overlayscrollbars-initialize';
|
||||||
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';
|
||||||
@@ -24,18 +25,19 @@ export const classNameSizeObserverListenerItemFinal = `${classNameSizeObserverLi
|
|||||||
|
|
||||||
export const classNameTrinsicObserver = 'os-trinsic-observer';
|
export const classNameTrinsicObserver = 'os-trinsic-observer';
|
||||||
|
|
||||||
|
export const classNameScrollbarThemeNone = 'os-theme-none';
|
||||||
export const classNameScrollbar = 'os-scrollbar';
|
export const classNameScrollbar = 'os-scrollbar';
|
||||||
export const classNameScrollbarRtl = `${classNameScrollbar}-rtl`;
|
export const classNameScrollbarRtl = `${classNameScrollbar}-rtl`;
|
||||||
export const classNameScrollbarHorizontal = `${classNameScrollbar}-horizontal`;
|
export const classNameScrollbarHorizontal = `${classNameScrollbar}-horizontal`;
|
||||||
export const classNameScrollbarVertical = `${classNameScrollbar}-vertical`;
|
export const classNameScrollbarVertical = `${classNameScrollbar}-vertical`;
|
||||||
export const classNameScrollbarTrack = `${classNameScrollbar}-track`;
|
export const classNameScrollbarTrack = `${classNameScrollbar}-track`;
|
||||||
export const classNameScrollbarHandle = `${classNameScrollbar}-handle`;
|
export const classNameScrollbarHandle = `${classNameScrollbar}-handle`;
|
||||||
export const classNamesScrollbarVisible = `${classNameScrollbar}-visible`;
|
export const classNameScrollbarVisible = `${classNameScrollbar}-visible`;
|
||||||
export const classNamesScrollbarCornerless = `${classNameScrollbar}-cornerless`;
|
export const classNameScrollbarCornerless = `${classNameScrollbar}-cornerless`;
|
||||||
export const classNamesScrollbarTransitionless = `${classNameScrollbar}-transitionless`;
|
export const classNameScrollbarTransitionless = `${classNameScrollbar}-transitionless`;
|
||||||
export const classNamesScrollbarInteraction = `${classNameScrollbar}-interaction`;
|
export const classNameScrollbarInteraction = `${classNameScrollbar}-interaction`;
|
||||||
export const classNamesScrollbarUnusable = `${classNameScrollbar}-unusable`;
|
export const classNameScrollbarUnusable = `${classNameScrollbar}-unusable`;
|
||||||
export const classNamesScrollbarAutoHidden = `${classNameScrollbar}-auto-hidden`;
|
export const classNameScrollbarAutoHidden = `${classNameScrollbar}-auto-hidden`;
|
||||||
export const classNamesScrollbarWheel = `${classNameScrollbar}-wheel`;
|
export const classNameScrollbarWheel = `${classNameScrollbar}-wheel`;
|
||||||
export const classNamesScrollbarTrackInteractive = `${classNameScrollbarTrack}-interactive`;
|
export const classNameScrollbarTrackInteractive = `${classNameScrollbarTrack}-interactive`;
|
||||||
export const classNamesScrollbarHandleInteractive = `${classNameScrollbarHandle}-interactive`;
|
export const classNameScrollbarHandleInteractive = `${classNameScrollbarHandle}-interactive`;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
classNameScrollbarVertical,
|
classNameScrollbarVertical,
|
||||||
classNameScrollbarTrack,
|
classNameScrollbarTrack,
|
||||||
classNameScrollbarHandle,
|
classNameScrollbarHandle,
|
||||||
classNamesScrollbarTransitionless,
|
classNameScrollbarTransitionless,
|
||||||
} from '~/classnames';
|
} from '~/classnames';
|
||||||
import { getEnvironment } from '~/environment';
|
import { getEnvironment } from '~/environment';
|
||||||
import { dynamicInitializationElement as generalDynamicInitializationElement } from '~/initialization';
|
import { dynamicInitializationElement as generalDynamicInitializationElement } from '~/initialization';
|
||||||
@@ -79,13 +79,26 @@ export const createScrollbarsSetupElements = (
|
|||||||
const { _getDefaultInitialization } = getEnvironment();
|
const { _getDefaultInitialization } = getEnvironment();
|
||||||
const { scrollbars: defaultInitScrollbars } = _getDefaultInitialization();
|
const { scrollbars: defaultInitScrollbars } = _getDefaultInitialization();
|
||||||
const { slot: defaultInitScrollbarsSlot } = defaultInitScrollbars;
|
const { slot: defaultInitScrollbarsSlot } = defaultInitScrollbars;
|
||||||
const { _documentElm, _target, _host, _viewport, _targetIsElm, _scrollOffsetElement } =
|
const {
|
||||||
structureSetupElements;
|
_documentElm,
|
||||||
|
_target,
|
||||||
|
_host,
|
||||||
|
_viewport,
|
||||||
|
_targetIsElm,
|
||||||
|
_scrollOffsetElement,
|
||||||
|
_isBody,
|
||||||
|
_viewportIsTarget,
|
||||||
|
} = structureSetupElements;
|
||||||
const { scrollbars: scrollbarsInit } = (_targetIsElm ? {} : target) as InitializationTargetObject;
|
const { scrollbars: scrollbarsInit } = (_targetIsElm ? {} : target) as InitializationTargetObject;
|
||||||
const { slot: initScrollbarsSlot } = scrollbarsInit || {};
|
const { slot: initScrollbarsSlot } = scrollbarsInit || {};
|
||||||
const evaluatedScrollbarSlot = generalDynamicInitializationElement<
|
const evaluatedScrollbarSlot = generalDynamicInitializationElement<
|
||||||
[InitializationTargetElement, HTMLElement, HTMLElement]
|
[InitializationTargetElement, HTMLElement, HTMLElement]
|
||||||
>([_target, _host, _viewport], () => _host, defaultInitScrollbarsSlot, initScrollbarsSlot);
|
>(
|
||||||
|
[_target, _host, _viewport],
|
||||||
|
() => (_viewportIsTarget && _isBody ? _target : _host),
|
||||||
|
defaultInitScrollbarsSlot,
|
||||||
|
initScrollbarsSlot
|
||||||
|
);
|
||||||
const scrollbarStructureAddRemoveClass = (
|
const scrollbarStructureAddRemoveClass = (
|
||||||
scrollbarStructures: ScrollbarStructure[],
|
scrollbarStructures: ScrollbarStructure[],
|
||||||
classNames: string | false | null | undefined,
|
classNames: string | false | null | undefined,
|
||||||
@@ -181,7 +194,7 @@ export const createScrollbarsSetupElements = (
|
|||||||
? classNameScrollbarHorizontal
|
? classNameScrollbarHorizontal
|
||||||
: classNameScrollbarVertical;
|
: classNameScrollbarVertical;
|
||||||
const arrToPush = isHorizontal ? horizontalScrollbars : verticalScrollbars;
|
const arrToPush = isHorizontal ? horizontalScrollbars : verticalScrollbars;
|
||||||
const transitionlessClass = isEmptyArray(arrToPush) ? classNamesScrollbarTransitionless : '';
|
const transitionlessClass = isEmptyArray(arrToPush) ? classNameScrollbarTransitionless : '';
|
||||||
const scrollbar = createDiv(
|
const scrollbar = createDiv(
|
||||||
`${classNameScrollbar} ${scrollbarClassName} ${transitionlessClass}`
|
`${classNameScrollbar} ${scrollbarClassName} ${transitionlessClass}`
|
||||||
);
|
);
|
||||||
@@ -218,7 +231,7 @@ export const createScrollbarsSetupElements = (
|
|||||||
appendChildren(evaluatedScrollbarSlot, verticalScrollbars[0]._scrollbar);
|
appendChildren(evaluatedScrollbarSlot, verticalScrollbars[0]._scrollbar);
|
||||||
|
|
||||||
setT(() => {
|
setT(() => {
|
||||||
scrollbarsAddRemoveClass(classNamesScrollbarTransitionless);
|
scrollbarsAddRemoveClass(classNameScrollbarTransitionless);
|
||||||
}, 300);
|
}, 300);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import { getPlugins, clickScrollPluginName } from '~/plugins';
|
|||||||
import { getEnvironment } from '~/environment';
|
import { getEnvironment } from '~/environment';
|
||||||
import {
|
import {
|
||||||
classNameScrollbarHandle,
|
classNameScrollbarHandle,
|
||||||
classNamesScrollbarInteraction,
|
classNameScrollbarInteraction,
|
||||||
classNamesScrollbarWheel,
|
classNameScrollbarWheel,
|
||||||
} from '~/classnames';
|
} from '~/classnames';
|
||||||
import type { XY } from '~/support';
|
import type { XY } from '~/support';
|
||||||
import type { ClickScrollPluginInstance } from '~/plugins';
|
import type { ClickScrollPluginInstance } from '~/plugins';
|
||||||
@@ -187,10 +187,10 @@ export const createScrollbarsSetupEvents =
|
|||||||
|
|
||||||
return runEachAndClear.bind(0, [
|
return runEachAndClear.bind(0, [
|
||||||
on(_scrollbar, 'pointerenter', () => {
|
on(_scrollbar, 'pointerenter', () => {
|
||||||
scrollbarsAddRemoveClass(classNamesScrollbarInteraction, true);
|
scrollbarsAddRemoveClass(classNameScrollbarInteraction, true);
|
||||||
}),
|
}),
|
||||||
on(_scrollbar, 'pointerleave pointercancel', () => {
|
on(_scrollbar, 'pointerleave pointercancel', () => {
|
||||||
scrollbarsAddRemoveClass(classNamesScrollbarInteraction);
|
scrollbarsAddRemoveClass(classNameScrollbarInteraction);
|
||||||
}),
|
}),
|
||||||
on(
|
on(
|
||||||
_scrollbar,
|
_scrollbar,
|
||||||
@@ -208,10 +208,10 @@ export const createScrollbarsSetupEvents =
|
|||||||
}
|
}
|
||||||
|
|
||||||
wheelScrollBy = false;
|
wheelScrollBy = false;
|
||||||
scrollbarsAddRemoveClass(classNamesScrollbarWheel, true);
|
scrollbarsAddRemoveClass(classNameScrollbarWheel, true);
|
||||||
wheelTimeout(() => {
|
wheelTimeout(() => {
|
||||||
wheelScrollBy = true;
|
wheelScrollBy = true;
|
||||||
scrollbarsAddRemoveClass(classNamesScrollbarWheel);
|
scrollbarsAddRemoveClass(classNameScrollbarWheel);
|
||||||
});
|
});
|
||||||
|
|
||||||
preventDefault(wheelEvent);
|
preventDefault(wheelEvent);
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
import { on, runEachAndClear, parent, scrollLeft, scrollTop, selfClearTimeout } from '~/support';
|
import { on, runEachAndClear, parent, scrollLeft, scrollTop, selfClearTimeout } from '~/support';
|
||||||
|
import { getEnvironment } from '~/environment';
|
||||||
import { createState, createOptionCheck } from '~/setups/setups';
|
import { createState, createOptionCheck } from '~/setups/setups';
|
||||||
import { createScrollbarsSetupEvents } from '~/setups/scrollbarsSetup/scrollbarsSetup.events';
|
import { createScrollbarsSetupEvents } from '~/setups/scrollbarsSetup/scrollbarsSetup.events';
|
||||||
import { createScrollbarsSetupElements } from '~/setups/scrollbarsSetup/scrollbarsSetup.elements';
|
import { createScrollbarsSetupElements } from '~/setups/scrollbarsSetup/scrollbarsSetup.elements';
|
||||||
import {
|
import {
|
||||||
classNamesScrollbarVisible,
|
classNameScrollbarThemeNone,
|
||||||
classNamesScrollbarUnusable,
|
classNameScrollbarVisible,
|
||||||
classNamesScrollbarCornerless,
|
classNameScrollbarUnusable,
|
||||||
classNamesScrollbarAutoHidden,
|
classNameScrollbarCornerless,
|
||||||
classNamesScrollbarHandleInteractive,
|
classNameScrollbarAutoHidden,
|
||||||
classNamesScrollbarTrackInteractive,
|
classNameScrollbarHandleInteractive,
|
||||||
|
classNameScrollbarTrackInteractive,
|
||||||
classNameScrollbarRtl,
|
classNameScrollbarRtl,
|
||||||
} from '~/classnames';
|
} from '~/classnames';
|
||||||
import type {
|
import type {
|
||||||
@@ -73,7 +75,7 @@ export const createScrollbarsSetup = (
|
|||||||
const {
|
const {
|
||||||
_horizontal,
|
_horizontal,
|
||||||
_vertical,
|
_vertical,
|
||||||
_scrollbarsAddRemoveClass: scrollbarsAddRemoveClass,
|
_scrollbarsAddRemoveClass,
|
||||||
_refreshScrollbarsHandleLength,
|
_refreshScrollbarsHandleLength,
|
||||||
_refreshScrollbarsHandleOffset,
|
_refreshScrollbarsHandleOffset,
|
||||||
} = elements;
|
} = elements;
|
||||||
@@ -94,9 +96,9 @@ export const createScrollbarsSetup = (
|
|||||||
const manageScrollbarsAutoHide = (removeAutoHide: boolean, delayless?: boolean) => {
|
const manageScrollbarsAutoHide = (removeAutoHide: boolean, delayless?: boolean) => {
|
||||||
clearAutoTimeout();
|
clearAutoTimeout();
|
||||||
if (removeAutoHide) {
|
if (removeAutoHide) {
|
||||||
scrollbarsAddRemoveClass(classNamesScrollbarAutoHidden);
|
_scrollbarsAddRemoveClass(classNameScrollbarAutoHidden);
|
||||||
} else {
|
} else {
|
||||||
const hide = () => scrollbarsAddRemoveClass(classNamesScrollbarAutoHidden, true);
|
const hide = () => _scrollbarsAddRemoveClass(classNameScrollbarAutoHidden, true);
|
||||||
if (globalAutoHideDelay > 0 && !delayless) {
|
if (globalAutoHideDelay > 0 && !delayless) {
|
||||||
auotHideTimeout(hide);
|
auotHideTimeout(hide);
|
||||||
} else {
|
} else {
|
||||||
@@ -162,9 +164,12 @@ export const createScrollbarsSetup = (
|
|||||||
_overflowStyleChanged,
|
_overflowStyleChanged,
|
||||||
_directionChanged,
|
_directionChanged,
|
||||||
} = structureUpdateHints;
|
} = structureUpdateHints;
|
||||||
|
const { _nativeScrollbarsOverlaid } = getEnvironment();
|
||||||
const checkOption = createOptionCheck(options, changedOptions, force);
|
const checkOption = createOptionCheck(options, changedOptions, force);
|
||||||
const currStructureSetupState = structureSetupState();
|
const currStructureSetupState = structureSetupState();
|
||||||
const { _overflowAmount, _overflowStyle, _directionIsRTL } = currStructureSetupState;
|
const { _overflowAmount, _overflowStyle, _directionIsRTL } = currStructureSetupState;
|
||||||
|
const [showNativeOverlaidScrollbarsOption, showNativeOverlaidScrollbarsChanged] =
|
||||||
|
checkOption<boolean>('showNativeOverlaidScrollbars');
|
||||||
const [theme, themeChanged] = checkOption<string | null>('scrollbars.theme');
|
const [theme, themeChanged] = checkOption<string | null>('scrollbars.theme');
|
||||||
const [visibility, visibilityChanged] =
|
const [visibility, visibilityChanged] =
|
||||||
checkOption<ScrollbarsVisibilityBehavior>('scrollbars.visibility');
|
checkOption<ScrollbarsVisibilityBehavior>('scrollbars.visibility');
|
||||||
@@ -174,22 +179,28 @@ export const createScrollbarsSetup = (
|
|||||||
const [dragScroll, dragScrollChanged] = checkOption<boolean>('scrollbars.dragScroll');
|
const [dragScroll, dragScrollChanged] = checkOption<boolean>('scrollbars.dragScroll');
|
||||||
const [clickScroll, clickScrollChanged] = checkOption<boolean>('scrollbars.clickScroll');
|
const [clickScroll, clickScrollChanged] = checkOption<boolean>('scrollbars.clickScroll');
|
||||||
|
|
||||||
const updateHandle =
|
const updateHandle = _overflowEdgeChanged || _overflowAmountChanged || _directionChanged;
|
||||||
_overflowEdgeChanged || _overflowAmountChanged || _directionChanged || force;
|
const updateVisibility = _overflowStyleChanged || visibilityChanged;
|
||||||
const updateVisibility = _overflowStyleChanged || visibilityChanged || force;
|
const showNativeOverlaidScrollbars =
|
||||||
|
showNativeOverlaidScrollbarsOption &&
|
||||||
|
_nativeScrollbarsOverlaid.x &&
|
||||||
|
_nativeScrollbarsOverlaid.y;
|
||||||
|
|
||||||
const setScrollbarVisibility = (overflowStyle: OverflowStyle, isHorizontal: boolean) => {
|
const setScrollbarVisibility = (overflowStyle: OverflowStyle, isHorizontal: boolean) => {
|
||||||
const isVisible =
|
const isVisible =
|
||||||
visibility === 'visible' || (visibility === 'auto' && overflowStyle === 'scroll');
|
visibility === 'visible' || (visibility === 'auto' && overflowStyle === 'scroll');
|
||||||
scrollbarsAddRemoveClass(classNamesScrollbarVisible, isVisible, isHorizontal);
|
_scrollbarsAddRemoveClass(classNameScrollbarVisible, isVisible, isHorizontal);
|
||||||
return isVisible;
|
return isVisible;
|
||||||
};
|
};
|
||||||
|
|
||||||
globalAutoHideDelay = autoHideDelay;
|
globalAutoHideDelay = autoHideDelay;
|
||||||
|
|
||||||
|
if (showNativeOverlaidScrollbarsChanged) {
|
||||||
|
_scrollbarsAddRemoveClass(classNameScrollbarThemeNone, showNativeOverlaidScrollbars);
|
||||||
|
}
|
||||||
if (themeChanged) {
|
if (themeChanged) {
|
||||||
scrollbarsAddRemoveClass(prevTheme);
|
_scrollbarsAddRemoveClass(prevTheme);
|
||||||
scrollbarsAddRemoveClass(theme, true);
|
_scrollbarsAddRemoveClass(theme, true);
|
||||||
|
|
||||||
prevTheme = theme;
|
prevTheme = theme;
|
||||||
}
|
}
|
||||||
@@ -200,25 +211,25 @@ export const createScrollbarsSetup = (
|
|||||||
manageScrollbarsAutoHide(!autoHideNotNever, true);
|
manageScrollbarsAutoHide(!autoHideNotNever, true);
|
||||||
}
|
}
|
||||||
if (dragScrollChanged) {
|
if (dragScrollChanged) {
|
||||||
scrollbarsAddRemoveClass(classNamesScrollbarHandleInteractive, dragScroll);
|
_scrollbarsAddRemoveClass(classNameScrollbarHandleInteractive, dragScroll);
|
||||||
}
|
}
|
||||||
if (clickScrollChanged) {
|
if (clickScrollChanged) {
|
||||||
scrollbarsAddRemoveClass(classNamesScrollbarTrackInteractive, clickScroll);
|
_scrollbarsAddRemoveClass(classNameScrollbarTrackInteractive, clickScroll);
|
||||||
}
|
}
|
||||||
if (updateVisibility) {
|
if (updateVisibility) {
|
||||||
const xVisible = setScrollbarVisibility(_overflowStyle.x, true);
|
const xVisible = setScrollbarVisibility(_overflowStyle.x, true);
|
||||||
const yVisible = setScrollbarVisibility(_overflowStyle.y, false);
|
const yVisible = setScrollbarVisibility(_overflowStyle.y, false);
|
||||||
const hasCorner = xVisible && yVisible;
|
const hasCorner = xVisible && yVisible;
|
||||||
|
|
||||||
scrollbarsAddRemoveClass(classNamesScrollbarCornerless, !hasCorner);
|
_scrollbarsAddRemoveClass(classNameScrollbarCornerless, !hasCorner);
|
||||||
}
|
}
|
||||||
if (updateHandle) {
|
if (updateHandle) {
|
||||||
_refreshScrollbarsHandleLength(currStructureSetupState);
|
_refreshScrollbarsHandleLength(currStructureSetupState);
|
||||||
_refreshScrollbarsHandleOffset(currStructureSetupState);
|
_refreshScrollbarsHandleOffset(currStructureSetupState);
|
||||||
|
|
||||||
scrollbarsAddRemoveClass(classNamesScrollbarUnusable, !_overflowAmount.x, true);
|
_scrollbarsAddRemoveClass(classNameScrollbarUnusable, !_overflowAmount.x, true);
|
||||||
scrollbarsAddRemoveClass(classNamesScrollbarUnusable, !_overflowAmount.y, false);
|
_scrollbarsAddRemoveClass(classNameScrollbarUnusable, !_overflowAmount.y, false);
|
||||||
scrollbarsAddRemoveClass(classNameScrollbarRtl, _directionIsRTL && !_isBody);
|
_scrollbarsAddRemoveClass(classNameScrollbarRtl, _directionIsRTL && !_isBody);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scrollbarsSetupState,
|
scrollbarsSetupState,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import {
|
|||||||
} from '~/support';
|
} from '~/support';
|
||||||
import {
|
import {
|
||||||
dataAttributeHost,
|
dataAttributeHost,
|
||||||
|
dataAttributeInitialize,
|
||||||
dataAttributeHostOverflowX,
|
dataAttributeHostOverflowX,
|
||||||
dataAttributeHostOverflowY,
|
dataAttributeHostOverflowY,
|
||||||
classNamePadding,
|
classNamePadding,
|
||||||
@@ -146,15 +147,20 @@ export const createStructureSetupElements = (
|
|||||||
const viewportIsContentContent = defaultContentElementPresent
|
const viewportIsContentContent = defaultContentElementPresent
|
||||||
? possibleContentElement
|
? possibleContentElement
|
||||||
: generateContentElement();
|
: generateContentElement();
|
||||||
const viewportElement = viewportIsContent ? viewportIstContentViewport : possibleViewportElement;
|
const nonBodyViewportElement = viewportIsContent
|
||||||
|
? viewportIstContentViewport
|
||||||
|
: possibleViewportElement;
|
||||||
|
const viewportElement = viewportIsTargetBody ? docElement : nonBodyViewportElement;
|
||||||
|
const nonBodyHostElement = isTextarea
|
||||||
|
? staticInitializationElement(createNewDiv, defaultHostInitialization, hostInitialization)
|
||||||
|
: (targetElement as HTMLElement);
|
||||||
|
const hostElement = viewportIsTargetBody ? viewportElement : nonBodyHostElement;
|
||||||
const contentElement = viewportIsContent ? viewportIsContentContent : possibleContentElement;
|
const contentElement = viewportIsContent ? viewportIsContentContent : possibleContentElement;
|
||||||
const activeElm = ownerDocument.activeElement;
|
const activeElm = ownerDocument.activeElement;
|
||||||
const setViewportFocus = !viewportIsTarget && wnd.top === wnd && activeElm === targetElement;
|
const setViewportFocus = !viewportIsTarget && wnd.top === wnd && activeElm === targetElement;
|
||||||
const evaluatedTargetObj: StructureSetupElementsObj = {
|
const evaluatedTargetObj: StructureSetupElementsObj = {
|
||||||
_target: targetElement,
|
_target: targetElement,
|
||||||
_host: isTextarea
|
_host: hostElement,
|
||||||
? staticInitializationElement(createNewDiv, defaultHostInitialization, hostInitialization)
|
|
||||||
: (targetElement as HTMLElement),
|
|
||||||
_viewport: viewportElement,
|
_viewport: viewportElement,
|
||||||
_padding:
|
_padding:
|
||||||
!viewportIsTarget &&
|
!viewportIsTarget &&
|
||||||
@@ -196,10 +202,13 @@ export const createStructureSetupElements = (
|
|||||||
const { _target, _host, _padding, _viewport, _content, _viewportArrange } = evaluatedTargetObj;
|
const { _target, _host, _padding, _viewport, _content, _viewportArrange } = evaluatedTargetObj;
|
||||||
const destroyFns: (() => any)[] = [
|
const destroyFns: (() => any)[] = [
|
||||||
() => {
|
() => {
|
||||||
// always remove dataAttributeHost from host and from <html> element if target is body
|
// always remove dataAttributeHost & dataAttributeInitialize from host and from <html> element if target is body
|
||||||
removeAttr(_host, dataAttributeHost);
|
removeAttr(_host, dataAttributeHost);
|
||||||
|
removeAttr(_host, dataAttributeInitialize);
|
||||||
|
removeAttr(_target, dataAttributeInitialize);
|
||||||
if (isBody) {
|
if (isBody) {
|
||||||
removeAttr(docElement, dataAttributeHost);
|
removeAttr(docElement, dataAttributeHost);
|
||||||
|
removeAttr(docElement, dataAttributeInitialize);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -211,16 +220,17 @@ export const createStructureSetupElements = (
|
|||||||
(elm) => elementIsGenerated(elm) === false
|
(elm) => elementIsGenerated(elm) === false
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
const contentSlot = _content || _viewport;
|
const contentSlot = viewportIsTargetBody ? _target : _content || _viewport;
|
||||||
const appendElements = () => {
|
const appendElements = () => {
|
||||||
attr(_host, dataAttributeHost, viewportIsTarget ? 'viewport' : 'host');
|
attr(_host, dataAttributeHost, viewportIsTarget ? 'viewport' : 'host');
|
||||||
|
|
||||||
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
|
const removeHtmlClass =
|
||||||
? addClass(parent(targetElement), classNameViewportScrollbarHidden)
|
isBody && !viewportIsTarget
|
||||||
: noop;
|
? 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) {
|
||||||
|
|||||||
@@ -63,7 +63,6 @@
|
|||||||
}
|
}
|
||||||
[data-overlayscrollbars-initialize],
|
[data-overlayscrollbars-initialize],
|
||||||
[data-overlayscrollbars~='scrollbarHidden'],
|
[data-overlayscrollbars~='scrollbarHidden'],
|
||||||
html.os-viewport-scrollbar-hidden,
|
|
||||||
.os-viewport-scrollbar-hidden.os-environment,
|
.os-viewport-scrollbar-hidden.os-environment,
|
||||||
.os-viewport-scrollbar-hidden.os-viewport {
|
.os-viewport-scrollbar-hidden.os-viewport {
|
||||||
scrollbar-width: none !important;
|
scrollbar-width: none !important;
|
||||||
@@ -72,30 +71,39 @@ html.os-viewport-scrollbar-hidden,
|
|||||||
[data-overlayscrollbars-initialize]::-webkit-scrollbar-corner,
|
[data-overlayscrollbars-initialize]::-webkit-scrollbar-corner,
|
||||||
[data-overlayscrollbars~='scrollbarHidden']::-webkit-scrollbar,
|
[data-overlayscrollbars~='scrollbarHidden']::-webkit-scrollbar,
|
||||||
[data-overlayscrollbars~='scrollbarHidden']::-webkit-scrollbar-corner,
|
[data-overlayscrollbars~='scrollbarHidden']::-webkit-scrollbar-corner,
|
||||||
html.os-viewport-scrollbar-hidden::-webkit-scrollbar,
|
|
||||||
html.os-viewport-scrollbar-hidden::-webkit-scrollbar-corner,
|
|
||||||
.os-viewport-scrollbar-hidden.os-environment::-webkit-scrollbar,
|
.os-viewport-scrollbar-hidden.os-environment::-webkit-scrollbar,
|
||||||
.os-viewport-scrollbar-hidden.os-environment::-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,
|
||||||
.os-viewport-scrollbar-hidden.os-viewport::-webkit-scrollbar-corner {
|
.os-viewport-scrollbar-hidden.os-viewport::-webkit-scrollbar-corner {
|
||||||
|
appearance: none !important;
|
||||||
display: none !important;
|
display: none !important;
|
||||||
width: 0px !important;
|
width: 0 !important;
|
||||||
height: 0px !important;
|
height: 0 !important;
|
||||||
visibility: hidden !important;
|
}
|
||||||
background: transparent !important;
|
|
||||||
|
/**
|
||||||
|
* elements wont suddenly crop after initialization is done
|
||||||
|
*/
|
||||||
|
|
||||||
|
[data-overlayscrollbars-initialize] {
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* applied to body
|
* applied to body
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
html[data-overlayscrollbars],
|
||||||
html.os-viewport-scrollbar-hidden,
|
html.os-viewport-scrollbar-hidden,
|
||||||
html.os-viewport-scrollbar-hidden > body[data-overlayscrollbars] {
|
html.os-viewport-scrollbar-hidden > body {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
html[data-overlayscrollbars] > body {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* structure setup
|
* structure setup
|
||||||
@@ -143,22 +151,22 @@ html.os-viewport-scrollbar-hidden > body[data-overlayscrollbars] {
|
|||||||
|
|
||||||
[data-overlayscrollbars~='host'],
|
[data-overlayscrollbars~='host'],
|
||||||
[data-overlayscrollbars~='viewport'] {
|
[data-overlayscrollbars~='viewport'] {
|
||||||
overflow: hidden !important;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
[data-overlayscrollbars~='overflowVisible'] {
|
[data-overlayscrollbars~='overflowVisible'] {
|
||||||
overflow: visible !important;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
[data-overlayscrollbars-overflow-x='hidden'] {
|
[data-overlayscrollbars-overflow-x='hidden'] {
|
||||||
overflow-x: hidden !important;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
[data-overlayscrollbars-overflow-x='scroll'] {
|
[data-overlayscrollbars-overflow-x='scroll'] {
|
||||||
overflow-x: scroll !important;
|
overflow-x: scroll;
|
||||||
}
|
}
|
||||||
[data-overlayscrollbars-overflow-x='hidden'] {
|
[data-overlayscrollbars-overflow-x='hidden'] {
|
||||||
overflow-y: hidden !important;
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
[data-overlayscrollbars-overflow-y='scroll'] {
|
[data-overlayscrollbars-overflow-y='scroll'] {
|
||||||
overflow-y: scroll !important;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.os-padding,
|
.os-padding,
|
||||||
|
|||||||
+3
-3
@@ -6,7 +6,7 @@ import {
|
|||||||
classNameScrollbarVertical,
|
classNameScrollbarVertical,
|
||||||
classNameScrollbarTrack,
|
classNameScrollbarTrack,
|
||||||
classNameScrollbarHandle,
|
classNameScrollbarHandle,
|
||||||
classNamesScrollbarTransitionless,
|
classNameScrollbarTransitionless,
|
||||||
} from '~/classnames';
|
} from '~/classnames';
|
||||||
import type { StructureSetupElementsObj } from '~/setups/structureSetup/structureSetup.elements';
|
import type { StructureSetupElementsObj } from '~/setups/structureSetup/structureSetup.elements';
|
||||||
import type {
|
import type {
|
||||||
@@ -93,7 +93,7 @@ const assertCorrectDOMStructure = (
|
|||||||
expect(_track.classList.length).toBe(1);
|
expect(_track.classList.length).toBe(1);
|
||||||
expect(_handle.classList.length).toBe(1);
|
expect(_handle.classList.length).toBe(1);
|
||||||
if (isMainStructure) {
|
if (isMainStructure) {
|
||||||
expect(domScrollbar.classList.contains(classNamesScrollbarTransitionless)).toBe(true);
|
expect(domScrollbar.classList.contains(classNameScrollbarTransitionless)).toBe(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// structure
|
// structure
|
||||||
@@ -348,7 +348,7 @@ describe('scrollbarsSetup.elements', () => {
|
|||||||
expected: boolean
|
expected: boolean
|
||||||
) => {
|
) => {
|
||||||
const { _scrollbar } = setupElement._scrollbarStructures[0];
|
const { _scrollbar } = setupElement._scrollbarStructures[0];
|
||||||
expect(_scrollbar.classList.contains(classNamesScrollbarTransitionless)).toBe(expected);
|
expect(_scrollbar.classList.contains(classNameScrollbarTransitionless)).toBe(expected);
|
||||||
};
|
};
|
||||||
|
|
||||||
testHasTransitionlessClass(elements._horizontal, true);
|
testHasTransitionlessClass(elements._horizontal, true);
|
||||||
|
|||||||
+30
-16
@@ -2,6 +2,7 @@ import { hasClass, is, isHTMLElement } from '~/support';
|
|||||||
import { resolveInitialization } from '~/initialization';
|
import { resolveInitialization } from '~/initialization';
|
||||||
import {
|
import {
|
||||||
dataAttributeHost,
|
dataAttributeHost,
|
||||||
|
dataAttributeInitialize,
|
||||||
classNamePadding,
|
classNamePadding,
|
||||||
classNameViewport,
|
classNameViewport,
|
||||||
classNameContent,
|
classNameContent,
|
||||||
@@ -112,7 +113,7 @@ const assertCorrectDOMStructure = (
|
|||||||
) => {
|
) => {
|
||||||
const { target, host, padding, viewport, content, children } = getElements(targetType);
|
const { target, host, padding, viewport, content, children } = getElements(targetType);
|
||||||
const { _getDefaultInitialization } = env;
|
const { _getDefaultInitialization } = env;
|
||||||
const { _viewportIsTarget, _viewportIsContent, _viewport, _content } = elements;
|
const { _viewportIsTarget, _viewportIsContent, _viewport, _content, _isBody } = elements;
|
||||||
|
|
||||||
expect(children).toBeDefined();
|
expect(children).toBeDefined();
|
||||||
expect((_content || _viewport).contains(children)).toBe(true);
|
expect((_content || _viewport).contains(children)).toBe(true);
|
||||||
@@ -121,7 +122,12 @@ const assertCorrectDOMStructure = (
|
|||||||
expect(host.getAttribute(dataAttributeHost)).toBe('viewport');
|
expect(host.getAttribute(dataAttributeHost)).toBe('viewport');
|
||||||
expect(_viewportIsContent).toBe(false);
|
expect(_viewportIsContent).toBe(false);
|
||||||
|
|
||||||
expect(target).toBe(host);
|
if (_isBody) {
|
||||||
|
expect(target.parentElement).toBe(host);
|
||||||
|
} else {
|
||||||
|
expect(target).toBe(host);
|
||||||
|
}
|
||||||
|
|
||||||
expect(host).toBeTruthy();
|
expect(host).toBeTruthy();
|
||||||
expect(padding).toBeFalsy();
|
expect(padding).toBeFalsy();
|
||||||
expect(viewport).toBeFalsy();
|
expect(viewport).toBeFalsy();
|
||||||
@@ -228,7 +234,11 @@ const assertCorrectSetupElements = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_viewportIsTarget) {
|
if (_viewportIsTarget) {
|
||||||
expect(_viewport).toBe(_target);
|
if (isBody) {
|
||||||
|
expect(_viewport).toBe(_target.parentElement);
|
||||||
|
} else {
|
||||||
|
expect(_viewport).toBe(_target);
|
||||||
|
}
|
||||||
} else if (viewport || _viewport) {
|
} else if (viewport || _viewport) {
|
||||||
expect(_viewport).toBe(viewport);
|
expect(_viewport).toBe(viewport);
|
||||||
} else {
|
} else {
|
||||||
@@ -413,8 +423,8 @@ const assertCorrectSetupElements = (
|
|||||||
|
|
||||||
_viewportAddRemoveClass(className, attrName, true);
|
_viewportAddRemoveClass(className, attrName, true);
|
||||||
if (_viewportIsTarget) {
|
if (_viewportIsTarget) {
|
||||||
expect(_host.getAttribute(dataAttributeHost)!.indexOf(attrName) >= 0).toBe(true);
|
|
||||||
expect(_viewportHasClass('', attrName)).toBe(true);
|
expect(_viewportHasClass('', attrName)).toBe(true);
|
||||||
|
expect(_host.getAttribute(dataAttributeHost)!.indexOf(attrName) >= 0).toBe(true);
|
||||||
} else {
|
} else {
|
||||||
expect(hasClass(_viewport, className)).toBe(true);
|
expect(hasClass(_viewport, className)).toBe(true);
|
||||||
expect(_viewportHasClass(className, '')).toBe(true);
|
expect(_viewportHasClass(className, '')).toBe(true);
|
||||||
@@ -1294,9 +1304,13 @@ describe('structureSetup.elements', () => {
|
|||||||
currEnv
|
currEnv
|
||||||
);
|
);
|
||||||
expect(elements._viewportIsTarget).toBe(true);
|
expect(elements._viewportIsTarget).toBe(true);
|
||||||
expect(elements._host).toBe(elements._target);
|
expect(elements._host).toBe(
|
||||||
|
elements._isBody ? elements._target.parentElement : elements._target
|
||||||
|
);
|
||||||
expect(elements._padding).toBeFalsy();
|
expect(elements._padding).toBeFalsy();
|
||||||
expect(elements._viewport).toBe(elements._target);
|
expect(elements._viewport).toBe(
|
||||||
|
elements._isBody ? elements._target.parentElement : elements._target
|
||||||
|
);
|
||||||
expect(elements._content).toBeFalsy();
|
expect(elements._content).toBeFalsy();
|
||||||
|
|
||||||
assertCorrectDOMStructure(targetType, currEnv, elements);
|
assertCorrectDOMStructure(targetType, currEnv, elements);
|
||||||
@@ -1356,34 +1370,34 @@ describe('structureSetup.elements', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('data-overlayscrollbars attribute', () => {
|
describe('data-overlayscrollbars-initialize attribute', () => {
|
||||||
test('already set data-overlayscrollbars attribute is removed', () => {
|
test('already set data-overlayscrollbars-initialize attribute is removed', () => {
|
||||||
const target = document.body;
|
const target = document.body;
|
||||||
target.setAttribute(dataAttributeHost, '');
|
target.setAttribute(dataAttributeInitialize, '');
|
||||||
|
|
||||||
const { destroy } = createStructureSetupElementsProxy(target);
|
const { destroy } = createStructureSetupElementsProxy(target);
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
expect(document.body.getAttribute(dataAttributeHost)).toBe(null);
|
expect(document.body.getAttribute(dataAttributeInitialize)).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('already set data-overlayscrollbars attribute is removed even if initialization gets canceled', () => {
|
test('already set data-overlayscrollbars-initialize attribute is removed even if initialization gets canceled', () => {
|
||||||
const target = document.body;
|
const target = document.body;
|
||||||
target.setAttribute(dataAttributeHost, '');
|
target.setAttribute(dataAttributeInitialize, '');
|
||||||
|
|
||||||
const { destroy } = createStructureSetupElementsProxy(target, { autoAppend: false });
|
const { destroy } = createStructureSetupElementsProxy(target, { autoAppend: false });
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
expect(document.body.getAttribute(dataAttributeHost)).toBe(null);
|
expect(document.body.getAttribute(dataAttributeInitialize)).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('already set data-overlayscrollbars attribute on html element is removed if target is body', () => {
|
test('already set data-overlayscrollbars-initialize attribute on html element is removed if target is body', () => {
|
||||||
document.documentElement.setAttribute(dataAttributeHost, '');
|
document.documentElement.setAttribute(dataAttributeInitialize, '');
|
||||||
|
|
||||||
const { destroy } = createStructureSetupElementsProxy(document.body);
|
const { destroy } = createStructureSetupElementsProxy(document.body);
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
expect(document.documentElement.getAttribute(dataAttributeHost)).toBe(null);
|
expect(document.documentElement.getAttribute(dataAttributeInitialize)).toBe(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user