mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-19 22:50:36 +03:00
add visibility, autoHide and autoHide delay functionality
This commit is contained in:
+122
-63
File diff suppressed because one or more lines are too long
+804
-653
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
+1086
-939
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
@@ -28,3 +28,7 @@ export const classNameScrollbarHorizontal = `${classNameScrollbar}-horizontal`;
|
|||||||
export const classNameScrollbarVertical = `${classNameScrollbar}-vertical`;
|
export const classNameScrollbarVertical = `${classNameScrollbar}-vertical`;
|
||||||
export const classNameScrollbarTrack = 'os-scrollbar-track';
|
export const classNameScrollbarTrack = 'os-scrollbar-track';
|
||||||
export const classNameScrollbarHandle = 'os-scrollbar-handle';
|
export const classNameScrollbarHandle = 'os-scrollbar-handle';
|
||||||
|
export const classNamesScrollbarVisible = `${classNameScrollbar}-visible`;
|
||||||
|
export const classNamesScrollbarCornerless = `${classNameScrollbar}-cornerless`;
|
||||||
|
export const classNamesScrollbarInteraction = `${classNameScrollbar}-interaction`;
|
||||||
|
export const classNamesScrollbarAutoHidden = `${classNameScrollbar}-auto-hidden`;
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ export type OverflowBehavior =
|
|||||||
| 'visible-hidden'
|
| 'visible-hidden'
|
||||||
| 'visible-scroll';
|
| 'visible-scroll';
|
||||||
|
|
||||||
export type VisibilityBehavior = 'visible' | 'hidden' | 'auto';
|
export type ScrollbarVisibilityBehavior = 'visible' | 'hidden' | 'auto';
|
||||||
|
|
||||||
export type AutoHideBehavior = 'never' | 'scroll' | 'leave' | 'move';
|
export type ScrollbarAutoHideBehavior = 'never' | 'scroll' | 'leave' | 'move';
|
||||||
|
|
||||||
export type ScrollBehavior = 'always' | 'ifneeded' | 'never';
|
export type ScrollBehavior = 'always' | 'ifneeded' | 'never';
|
||||||
|
|
||||||
@@ -51,8 +51,8 @@ export interface Options {
|
|||||||
y: OverflowBehavior;
|
y: OverflowBehavior;
|
||||||
};
|
};
|
||||||
scrollbars: {
|
scrollbars: {
|
||||||
visibility: VisibilityBehavior;
|
visibility: ScrollbarVisibilityBehavior;
|
||||||
autoHide: AutoHideBehavior;
|
autoHide: ScrollbarAutoHideBehavior;
|
||||||
autoHideDelay: number;
|
autoHideDelay: number;
|
||||||
dragScroll: boolean;
|
dragScroll: boolean;
|
||||||
clickScroll: boolean;
|
clickScroll: boolean;
|
||||||
|
|||||||
@@ -176,11 +176,10 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|||||||
const [updateScrollbars, scrollbarsState, destroyScrollbars] = createScrollbarsSetup(
|
const [updateScrollbars, scrollbarsState, destroyScrollbars] = createScrollbarsSetup(
|
||||||
target,
|
target,
|
||||||
currentOptions,
|
currentOptions,
|
||||||
structureState._elements
|
structureState
|
||||||
);
|
);
|
||||||
const update = (changedOptions: PartialOptions<Options>, force?: boolean) => {
|
const update = (changedOptions: PartialOptions<Options>, force?: boolean) => {
|
||||||
updateStructure(changedOptions, force);
|
updateStructure(changedOptions, !!force);
|
||||||
updateScrollbars(changedOptions, force);
|
|
||||||
};
|
};
|
||||||
const removeEnvListener = addEnvListener(update.bind(0, {}, true));
|
const removeEnvListener = addEnvListener(update.bind(0, {}, true));
|
||||||
const destroy = (withdrawn?: boolean) => {
|
const destroy = (withdrawn?: boolean) => {
|
||||||
@@ -255,6 +254,10 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|||||||
destroy: destroy.bind(0),
|
destroy: destroy.bind(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
structureState._addOnUpdatedListener((updateHints, changedOptions, force: boolean) => {
|
||||||
|
updateScrollbars(changedOptions, force, updateHints);
|
||||||
|
});
|
||||||
|
|
||||||
each(keys(plugins), (pluginName) => {
|
each(keys(plugins), (pluginName) => {
|
||||||
const pluginInstance = plugins[pluginName];
|
const pluginInstance = plugins[pluginName];
|
||||||
if (isFunction(pluginInstance)) {
|
if (isFunction(pluginInstance)) {
|
||||||
|
|||||||
+8
-3
@@ -1,4 +1,9 @@
|
|||||||
import { Options, OverflowBehavior, VisibilityBehavior, AutoHideBehavior } from 'options';
|
import {
|
||||||
|
Options,
|
||||||
|
OverflowBehavior,
|
||||||
|
ScrollbarVisibilityBehavior,
|
||||||
|
ScrollbarAutoHideBehavior,
|
||||||
|
} from 'options';
|
||||||
import {
|
import {
|
||||||
validateOptions,
|
validateOptions,
|
||||||
OptionsTemplate,
|
OptionsTemplate,
|
||||||
@@ -13,9 +18,9 @@ const booleanAllowedValues: OptionsTemplateValue<boolean> = oTypes.boolean;
|
|||||||
const arrayNullValues: OptionsTemplateValue<Array<unknown> | null> = [oTypes.array, oTypes.null];
|
const arrayNullValues: OptionsTemplateValue<Array<unknown> | null> = [oTypes.array, oTypes.null];
|
||||||
const overflowAllowedValues: OptionsTemplateValue<OverflowBehavior> =
|
const overflowAllowedValues: OptionsTemplateValue<OverflowBehavior> =
|
||||||
'hidden scroll visible visible-hidden';
|
'hidden scroll visible visible-hidden';
|
||||||
const scrollbarsVisibilityAllowedValues: OptionsTemplateValue<VisibilityBehavior> =
|
const scrollbarsVisibilityAllowedValues: OptionsTemplateValue<ScrollbarVisibilityBehavior> =
|
||||||
'visible hidden auto';
|
'visible hidden auto';
|
||||||
const scrollbarsAutoHideAllowedValues: OptionsTemplateValue<AutoHideBehavior> =
|
const scrollbarsAutoHideAllowedValues: OptionsTemplateValue<ScrollbarAutoHideBehavior> =
|
||||||
'never scroll leavemove';
|
'never scroll leavemove';
|
||||||
|
|
||||||
const optionsTemplate: OptionsTemplate<Options> = {
|
const optionsTemplate: OptionsTemplate<Options> = {
|
||||||
|
|||||||
+100
-30
@@ -1,10 +1,21 @@
|
|||||||
import { appendChildren, createDiv, removeElements } from 'support';
|
import {
|
||||||
|
addClass,
|
||||||
|
appendChildren,
|
||||||
|
createDiv,
|
||||||
|
each,
|
||||||
|
on,
|
||||||
|
push,
|
||||||
|
removeClass,
|
||||||
|
removeElements,
|
||||||
|
runEachAndClear,
|
||||||
|
} from 'support';
|
||||||
import {
|
import {
|
||||||
classNameScrollbar,
|
classNameScrollbar,
|
||||||
classNameScrollbarHorizontal,
|
classNameScrollbarHorizontal,
|
||||||
classNameScrollbarVertical,
|
classNameScrollbarVertical,
|
||||||
classNameScrollbarTrack,
|
classNameScrollbarTrack,
|
||||||
classNameScrollbarHandle,
|
classNameScrollbarHandle,
|
||||||
|
classNamesScrollbarInteraction,
|
||||||
} from 'classnames';
|
} from 'classnames';
|
||||||
import { getEnvironment } from 'environment';
|
import { getEnvironment } from 'environment';
|
||||||
import { dynamicInitializationElement as generalDynamicInitializationElement } from 'initialization';
|
import { dynamicInitializationElement as generalDynamicInitializationElement } from 'initialization';
|
||||||
@@ -22,9 +33,20 @@ export interface ScrollbarStructure {
|
|||||||
_handle: HTMLElement;
|
_handle: HTMLElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ScrollbarsSetupElement {
|
||||||
|
_scrollbarStructures: ScrollbarStructure[];
|
||||||
|
_clone: () => ScrollbarStructure;
|
||||||
|
_addRemoveClass: (classNames: string, add?: boolean) => void;
|
||||||
|
// _removeClass: (classNames: string) => void;
|
||||||
|
/*
|
||||||
|
_addEventListener: () => void;
|
||||||
|
_removeEventListener: () => void;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
export interface ScrollbarsSetupElementsObj {
|
export interface ScrollbarsSetupElementsObj {
|
||||||
_horizontalScrollbarStructure: ScrollbarStructure;
|
_horizontal: ScrollbarsSetupElement;
|
||||||
_verticalScrollbarStructure: ScrollbarStructure;
|
_vertical: ScrollbarsSetupElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ScrollbarsSetupElements = [
|
export type ScrollbarsSetupElements = [
|
||||||
@@ -33,20 +55,8 @@ export type ScrollbarsSetupElements = [
|
|||||||
destroy: () => void
|
destroy: () => void
|
||||||
];
|
];
|
||||||
|
|
||||||
const generateScrollbarDOM = (scrollbarClassName: string): ScrollbarStructure => {
|
const interactionStartEventNames = 'touchstart mouseenter';
|
||||||
const scrollbar = createDiv(`${classNameScrollbar} ${scrollbarClassName} os-theme-dark`);
|
const interactionEndEventNames = 'touchend touchcancel mouseleave';
|
||||||
const track = createDiv(classNameScrollbarTrack);
|
|
||||||
const handle = createDiv(classNameScrollbarHandle);
|
|
||||||
|
|
||||||
appendChildren(scrollbar, track);
|
|
||||||
appendChildren(track, handle);
|
|
||||||
|
|
||||||
return {
|
|
||||||
_scrollbar: scrollbar,
|
|
||||||
_track: track,
|
|
||||||
_handle: handle,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createScrollbarsSetupElements = (
|
export const createScrollbarsSetupElements = (
|
||||||
target: InitializationTarget,
|
target: InitializationTarget,
|
||||||
@@ -65,24 +75,84 @@ export const createScrollbarsSetupElements = (
|
|||||||
environmentScrollbarSlot,
|
environmentScrollbarSlot,
|
||||||
initializationScrollbarSlot
|
initializationScrollbarSlot
|
||||||
);
|
);
|
||||||
|
const scrollbarsAddRemoveClass = (
|
||||||
const horizontalScrollbarStructure = generateScrollbarDOM(classNameScrollbarHorizontal);
|
scrollbarStructures: ScrollbarStructure[],
|
||||||
const verticalScrollbarStructure = generateScrollbarDOM(classNameScrollbarVertical);
|
classNames: string,
|
||||||
|
add?: boolean
|
||||||
const { _scrollbar: horizontalScrollbar } = horizontalScrollbarStructure;
|
) => {
|
||||||
const { _scrollbar: verticalScrollbar } = verticalScrollbarStructure;
|
const action = add ? addClass : removeClass;
|
||||||
|
each(scrollbarStructures, (scrollbarStructure) => {
|
||||||
const appendElements = () => {
|
action(scrollbarStructure._scrollbar, classNames);
|
||||||
appendChildren(evaluatedScrollbarSlot, horizontalScrollbar);
|
});
|
||||||
appendChildren(evaluatedScrollbarSlot, verticalScrollbar);
|
|
||||||
};
|
};
|
||||||
|
const destroyFns: (() => void)[] = [];
|
||||||
|
const horizontalScrollbars: ScrollbarStructure[] = [];
|
||||||
|
const verticalScrollbars: ScrollbarStructure[] = [];
|
||||||
|
|
||||||
|
const addRemoveClassHorizontal = scrollbarsAddRemoveClass.bind(0, horizontalScrollbars);
|
||||||
|
const addRemoveClassVertical = scrollbarsAddRemoveClass.bind(0, verticalScrollbars);
|
||||||
|
const generateScrollbarDOM = (horizontal?: boolean): ScrollbarStructure => {
|
||||||
|
const scrollbarClassName = horizontal
|
||||||
|
? classNameScrollbarHorizontal
|
||||||
|
: classNameScrollbarVertical;
|
||||||
|
const arrToPush = horizontal ? horizontalScrollbars : verticalScrollbars;
|
||||||
|
const scrollbar = createDiv(`${classNameScrollbar} ${scrollbarClassName} os-theme-dark`);
|
||||||
|
const track = createDiv(classNameScrollbarTrack);
|
||||||
|
const handle = createDiv(classNameScrollbarHandle);
|
||||||
|
const result = {
|
||||||
|
_scrollbar: scrollbar,
|
||||||
|
_track: track,
|
||||||
|
_handle: handle,
|
||||||
|
};
|
||||||
|
|
||||||
|
appendChildren(scrollbar, track);
|
||||||
|
appendChildren(track, handle);
|
||||||
|
|
||||||
|
push(destroyFns, removeElements.bind(0, scrollbar));
|
||||||
|
push(arrToPush, result);
|
||||||
|
|
||||||
|
push(
|
||||||
|
destroyFns,
|
||||||
|
on(scrollbar, interactionStartEventNames, () => {
|
||||||
|
addRemoveClassHorizontal(classNamesScrollbarInteraction, true);
|
||||||
|
addRemoveClassVertical(classNamesScrollbarInteraction, true);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
push(
|
||||||
|
destroyFns,
|
||||||
|
on(scrollbar, interactionEndEventNames, () => {
|
||||||
|
addRemoveClassHorizontal(classNamesScrollbarInteraction);
|
||||||
|
addRemoveClassVertical(classNamesScrollbarInteraction);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
const generateHorizontalScrollbarStructure = generateScrollbarDOM.bind(0, true);
|
||||||
|
const generateVerticalScrollbarStructure = generateScrollbarDOM.bind(0, false);
|
||||||
|
const appendElements = () => {
|
||||||
|
appendChildren(evaluatedScrollbarSlot, horizontalScrollbars[0]._scrollbar);
|
||||||
|
appendChildren(evaluatedScrollbarSlot, verticalScrollbars[0]._scrollbar);
|
||||||
|
};
|
||||||
|
|
||||||
|
generateHorizontalScrollbarStructure();
|
||||||
|
generateVerticalScrollbarStructure();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
_horizontalScrollbarStructure: horizontalScrollbarStructure,
|
_horizontal: {
|
||||||
_verticalScrollbarStructure: verticalScrollbarStructure,
|
_scrollbarStructures: horizontalScrollbars,
|
||||||
|
_clone: generateHorizontalScrollbarStructure,
|
||||||
|
_addRemoveClass: addRemoveClassHorizontal,
|
||||||
|
},
|
||||||
|
_vertical: {
|
||||||
|
_scrollbarStructures: verticalScrollbars,
|
||||||
|
_clone: generateVerticalScrollbarStructure,
|
||||||
|
_addRemoveClass: addRemoveClassVertical,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
appendElements,
|
appendElements,
|
||||||
removeElements.bind(0, [horizontalScrollbar, verticalScrollbar]),
|
runEachAndClear.bind(0, destroyFns),
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,23 @@
|
|||||||
|
import { rAF, cAF, isFunction, on, runEachAndClear } from 'support';
|
||||||
import { createState, createOptionCheck } from 'setups/setups';
|
import { createState, createOptionCheck } from 'setups/setups';
|
||||||
import {
|
import {
|
||||||
createScrollbarsSetupElements,
|
createScrollbarsSetupElements,
|
||||||
ScrollbarsSetupElementsObj,
|
ScrollbarsSetupElementsObj,
|
||||||
} from 'setups/scrollbarsSetup/scrollbarsSetup.elements';
|
} from 'setups/scrollbarsSetup/scrollbarsSetup.elements';
|
||||||
import type { StructureSetupElementsObj } from 'setups/structureSetup/structureSetup.elements';
|
import {
|
||||||
import type { ReadonlyOSOptions } from 'options';
|
classNamesScrollbarVisible,
|
||||||
import type { Setup } from 'setups';
|
classNamesScrollbarCornerless,
|
||||||
|
classNamesScrollbarAutoHidden,
|
||||||
|
} from 'classnames';
|
||||||
|
import type { StructureSetupUpdateHints } from 'setups/structureSetup/structureSetup.update';
|
||||||
|
import type {
|
||||||
|
ReadonlyOSOptions,
|
||||||
|
ScrollbarVisibilityBehavior,
|
||||||
|
ScrollbarAutoHideBehavior,
|
||||||
|
} from 'options';
|
||||||
|
import type { Setup, StructureSetupState, StructureSetupStaticState } from 'setups';
|
||||||
import type { InitializationTarget } from 'initialization';
|
import type { InitializationTarget } from 'initialization';
|
||||||
|
import type { OverflowStyle } from 'typings';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||||
export interface ScrollbarsSetupState {}
|
export interface ScrollbarsSetupState {}
|
||||||
@@ -16,33 +27,154 @@ export interface ScrollbarsSetupStaticState {
|
|||||||
_appendElements: () => void;
|
_appendElements: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const createSelfCancelTimeout = (timeout?: number | (() => number)) => {
|
||||||
|
let id: number;
|
||||||
|
const setT = timeout ? (window.setTimeout as (...args: any[]) => number) : rAF!;
|
||||||
|
const clearT = timeout ? window.clearTimeout : cAF!;
|
||||||
|
return [
|
||||||
|
(callback: () => any) => {
|
||||||
|
clearT(id);
|
||||||
|
// @ts-ignore
|
||||||
|
id = setT(callback, isFunction(timeout) ? timeout() : timeout);
|
||||||
|
},
|
||||||
|
() => clearT(id),
|
||||||
|
] as [timeout: (callback: () => any) => void, clear: () => void];
|
||||||
|
};
|
||||||
|
|
||||||
export const createScrollbarsSetup = (
|
export const createScrollbarsSetup = (
|
||||||
target: InitializationTarget,
|
target: InitializationTarget,
|
||||||
options: ReadonlyOSOptions,
|
options: ReadonlyOSOptions,
|
||||||
structureSetupElements: StructureSetupElementsObj
|
structureSetupState: (() => StructureSetupState) & StructureSetupStaticState
|
||||||
): Setup<ScrollbarsSetupState, ScrollbarsSetupStaticState> => {
|
): Setup<ScrollbarsSetupState, ScrollbarsSetupStaticState, [StructureSetupUpdateHints]> => {
|
||||||
|
let globalAutoHideDelay = 0;
|
||||||
|
let autoHideIsMove: boolean;
|
||||||
|
let autoHideIsLeave: boolean;
|
||||||
|
let autoHideNotNever: boolean;
|
||||||
|
let mouseInHost: boolean;
|
||||||
const state = createState({});
|
const state = createState({});
|
||||||
const [getState] = state;
|
const [getState] = state;
|
||||||
|
const [requestMouseMoveAnimationFrame, cancelMouseMoveAnimationFrame] = createSelfCancelTimeout();
|
||||||
|
const [requestScrollAnimationFrame, cancelScrollAnimationFrame] = createSelfCancelTimeout();
|
||||||
|
const [scrollTimeout, clearScrollTimeout] = createSelfCancelTimeout(100);
|
||||||
|
const [auotHideMoveTimeout, clearAutoHideTimeout] = createSelfCancelTimeout(100);
|
||||||
|
const [auotHideTimeout, clearAutoTimeout] = createSelfCancelTimeout(() => globalAutoHideDelay);
|
||||||
const [elements, appendElements, destroyElements] = createScrollbarsSetupElements(
|
const [elements, appendElements, destroyElements] = createScrollbarsSetupElements(
|
||||||
target,
|
target,
|
||||||
structureSetupElements
|
structureSetupState._elements
|
||||||
);
|
);
|
||||||
|
const { _host, _viewport } = structureSetupState._elements;
|
||||||
|
const { _horizontal, _vertical } = elements;
|
||||||
|
const { _addRemoveClass: addRemoveClassHorizontal } = _horizontal;
|
||||||
|
const { _addRemoveClass: addRemoveClassVertical } = _vertical;
|
||||||
|
const manageScrollbarsAutoHide = (removeAutoHide: boolean, delayless?: boolean) => {
|
||||||
|
clearAutoTimeout();
|
||||||
|
if (removeAutoHide) {
|
||||||
|
addRemoveClassHorizontal(classNamesScrollbarAutoHidden);
|
||||||
|
addRemoveClassVertical(classNamesScrollbarAutoHidden);
|
||||||
|
} else {
|
||||||
|
const hide = () => {
|
||||||
|
addRemoveClassHorizontal(classNamesScrollbarAutoHidden, true);
|
||||||
|
addRemoveClassVertical(classNamesScrollbarAutoHidden, true);
|
||||||
|
};
|
||||||
|
if (globalAutoHideDelay > 0 && !delayless) {
|
||||||
|
auotHideTimeout(hide);
|
||||||
|
} else {
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const onHostMouseEnter = () => {
|
||||||
|
mouseInHost = autoHideIsLeave;
|
||||||
|
mouseInHost && manageScrollbarsAutoHide(true);
|
||||||
|
};
|
||||||
|
const destroyFns: (() => void)[] = [
|
||||||
|
clearScrollTimeout,
|
||||||
|
clearAutoTimeout,
|
||||||
|
clearAutoHideTimeout,
|
||||||
|
cancelScrollAnimationFrame,
|
||||||
|
cancelMouseMoveAnimationFrame,
|
||||||
|
destroyElements,
|
||||||
|
|
||||||
|
on(_host, 'mouseover', onHostMouseEnter, { _once: true }),
|
||||||
|
on(_host, 'mouseenter', onHostMouseEnter),
|
||||||
|
on(_host, 'mouseleave', () => {
|
||||||
|
mouseInHost = false;
|
||||||
|
autoHideIsLeave && manageScrollbarsAutoHide(false);
|
||||||
|
}),
|
||||||
|
on(_host, 'mousemove', () => {
|
||||||
|
autoHideIsMove &&
|
||||||
|
requestMouseMoveAnimationFrame(() => {
|
||||||
|
clearScrollTimeout();
|
||||||
|
manageScrollbarsAutoHide(true);
|
||||||
|
auotHideMoveTimeout(() => {
|
||||||
|
autoHideIsMove && manageScrollbarsAutoHide(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
on(_viewport, 'scroll', () => {
|
||||||
|
autoHideNotNever &&
|
||||||
|
requestScrollAnimationFrame(() => {
|
||||||
|
manageScrollbarsAutoHide(true);
|
||||||
|
scrollTimeout(() => {
|
||||||
|
autoHideNotNever && !mouseInHost && manageScrollbarsAutoHide(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
];
|
||||||
const scrollbarsSetupState = getState.bind(0) as (() => ScrollbarsSetupState) &
|
const scrollbarsSetupState = getState.bind(0) as (() => ScrollbarsSetupState) &
|
||||||
ScrollbarsSetupStaticState;
|
ScrollbarsSetupStaticState;
|
||||||
scrollbarsSetupState._elements = elements;
|
scrollbarsSetupState._elements = elements;
|
||||||
scrollbarsSetupState._appendElements = appendElements;
|
scrollbarsSetupState._appendElements = appendElements;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
(changedOptions, force?) => {
|
(changedOptions, force, structureUpdateHints) => {
|
||||||
|
const { _overflowEdgeChanged, _overflowAmountChanged, _overflowStyleChanged } =
|
||||||
|
structureUpdateHints;
|
||||||
const checkOption = createOptionCheck(options, changedOptions, force);
|
const checkOption = createOptionCheck(options, changedOptions, force);
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(checkOption);
|
const [visibility, visibilityChanged] =
|
||||||
|
checkOption<ScrollbarVisibilityBehavior>('scrollbars.visibility');
|
||||||
|
const [autoHide, autoHideChanged] =
|
||||||
|
checkOption<ScrollbarAutoHideBehavior>('scrollbars.autoHide');
|
||||||
|
const [autoHideDelay] = checkOption<number>('scrollbars.autoHideDelay');
|
||||||
|
const [dragScrolling, dragScrollingChanged] = checkOption<boolean>(
|
||||||
|
'scrollbars.dragScrolling'
|
||||||
|
);
|
||||||
|
const [touchSupport, touchSupportChanged] = checkOption<boolean>('scrollbars.touchSupport');
|
||||||
|
|
||||||
|
const updateHandleSize = _overflowEdgeChanged || _overflowAmountChanged;
|
||||||
|
const updateVisibility = _overflowStyleChanged || visibilityChanged;
|
||||||
|
|
||||||
|
const setScrollbarVisibility = (
|
||||||
|
overflowStyle: OverflowStyle,
|
||||||
|
addRemoveClass: (classNames: string, add?: boolean) => void
|
||||||
|
) => {
|
||||||
|
const isVisible =
|
||||||
|
visibility === 'visible' || (visibility === 'auto' && overflowStyle === 'scroll');
|
||||||
|
addRemoveClass(classNamesScrollbarVisible, isVisible);
|
||||||
|
return isVisible;
|
||||||
|
};
|
||||||
|
|
||||||
|
globalAutoHideDelay = autoHideDelay;
|
||||||
|
|
||||||
|
if (updateVisibility) {
|
||||||
|
const { _overflowStyle } = structureSetupState();
|
||||||
|
|
||||||
|
const xVisible = setScrollbarVisibility(_overflowStyle.x, addRemoveClassHorizontal);
|
||||||
|
const yVisible = setScrollbarVisibility(_overflowStyle.y, addRemoveClassVertical);
|
||||||
|
const hasCorner = xVisible && yVisible;
|
||||||
|
|
||||||
|
addRemoveClassHorizontal(classNamesScrollbarCornerless, !hasCorner);
|
||||||
|
addRemoveClassVertical(classNamesScrollbarCornerless, !hasCorner);
|
||||||
|
}
|
||||||
|
if (autoHideChanged) {
|
||||||
|
autoHideIsMove = autoHide === 'move';
|
||||||
|
autoHideIsLeave = autoHide === 'leave';
|
||||||
|
autoHideNotNever = autoHide !== 'never';
|
||||||
|
manageScrollbarsAutoHide(!autoHideNotNever, true);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
scrollbarsSetupState,
|
scrollbarsSetupState,
|
||||||
() => {
|
runEachAndClear.bind(0, destroyFns),
|
||||||
destroyElements();
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
import { each, isNumber, scrollLeft, scrollTop, assignDeep, keys } from 'support';
|
|
||||||
import { getEnvironment } from 'environment';
|
|
||||||
import {
|
|
||||||
createTrinsicUpdate,
|
|
||||||
createPaddingUpdate,
|
|
||||||
createOverflowUpdate,
|
|
||||||
} from 'setups/structureSetup/updateSegments';
|
|
||||||
import type { SetupState, SetupUpdateSegment, SetupUpdateCheckOption } from 'setups';
|
|
||||||
import type { StructureSetupState } from 'setups/structureSetup';
|
|
||||||
import type { StructureSetupElementsObj } from 'setups/structureSetup/structureSetup.elements';
|
|
||||||
|
|
||||||
export type CreateStructureUpdateSegment = (
|
|
||||||
structureSetupElements: StructureSetupElementsObj,
|
|
||||||
state: SetupState<StructureSetupState>
|
|
||||||
) => StructureSetupUpdateSegment;
|
|
||||||
|
|
||||||
export type StructureSetupUpdateSegment = SetupUpdateSegment<StructureSetupUpdateHints>;
|
|
||||||
|
|
||||||
export type StructureSetupUpdate = (
|
|
||||||
checkOption: SetupUpdateCheckOption,
|
|
||||||
updateHints: Partial<StructureSetupUpdateHints>,
|
|
||||||
force?: boolean
|
|
||||||
) => StructureSetupUpdateHints;
|
|
||||||
|
|
||||||
export interface StructureSetupUpdateHints {
|
|
||||||
_sizeChanged: boolean;
|
|
||||||
_directionChanged: boolean;
|
|
||||||
_heightIntrinsicChanged: boolean;
|
|
||||||
_overflowAmountChanged: boolean;
|
|
||||||
_overflowStyleChanged: boolean;
|
|
||||||
_paddingStyleChanged: boolean;
|
|
||||||
_hostMutation: boolean;
|
|
||||||
_contentMutation: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const prepareUpdateHints = <T extends StructureSetupUpdateHints>(
|
|
||||||
leading: Required<T>,
|
|
||||||
adaptive?: Partial<T>,
|
|
||||||
force?: boolean
|
|
||||||
): Required<T> => {
|
|
||||||
const result = {};
|
|
||||||
const finalAdaptive = adaptive || {};
|
|
||||||
const objKeys = keys(leading).concat(keys(finalAdaptive));
|
|
||||||
|
|
||||||
each(objKeys, (key) => {
|
|
||||||
const leadingValue = leading[key];
|
|
||||||
const adaptiveValue = finalAdaptive[key];
|
|
||||||
result[key] = !!(force || leadingValue || adaptiveValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
return result as Required<T>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createStructureSetupUpdate = (
|
|
||||||
structureSetupElements: StructureSetupElementsObj,
|
|
||||||
state: SetupState<StructureSetupState>
|
|
||||||
): StructureSetupUpdate => {
|
|
||||||
const { _viewport } = structureSetupElements;
|
|
||||||
const {
|
|
||||||
_nativeScrollbarsHiding: _nativeScrollbarStyling,
|
|
||||||
_nativeScrollbarsOverlaid: _nativeScrollbarIsOverlaid,
|
|
||||||
_flexboxGlue,
|
|
||||||
} = getEnvironment();
|
|
||||||
const doViewportArrange =
|
|
||||||
!_nativeScrollbarStyling && (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y);
|
|
||||||
|
|
||||||
const updateSegments: StructureSetupUpdateSegment[] = [
|
|
||||||
createTrinsicUpdate(structureSetupElements, state),
|
|
||||||
createPaddingUpdate(structureSetupElements, state),
|
|
||||||
createOverflowUpdate(structureSetupElements, state),
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
checkOption: SetupUpdateCheckOption,
|
|
||||||
updateHints: Partial<StructureSetupUpdateHints>,
|
|
||||||
force?: boolean
|
|
||||||
) => {
|
|
||||||
const initialUpdateHints = prepareUpdateHints(
|
|
||||||
assignDeep(
|
|
||||||
{
|
|
||||||
_sizeChanged: false,
|
|
||||||
_paddingStyleChanged: false,
|
|
||||||
_directionChanged: false,
|
|
||||||
_heightIntrinsicChanged: false,
|
|
||||||
_overflowAmountChanged: false,
|
|
||||||
_overflowStyleChanged: false,
|
|
||||||
_hostMutation: false,
|
|
||||||
_contentMutation: false,
|
|
||||||
},
|
|
||||||
updateHints
|
|
||||||
),
|
|
||||||
{},
|
|
||||||
force
|
|
||||||
);
|
|
||||||
const adjustScrollOffset = doViewportArrange || !_flexboxGlue;
|
|
||||||
const scrollOffsetX = adjustScrollOffset && scrollLeft(_viewport);
|
|
||||||
const scrollOffsetY = adjustScrollOffset && scrollTop(_viewport);
|
|
||||||
|
|
||||||
let adaptivedUpdateHints: Required<StructureSetupUpdateHints> = initialUpdateHints;
|
|
||||||
each(updateSegments, (updateSegment) => {
|
|
||||||
adaptivedUpdateHints = prepareUpdateHints<StructureSetupUpdateHints>(
|
|
||||||
adaptivedUpdateHints,
|
|
||||||
updateSegment(adaptivedUpdateHints, checkOption, !!force) || {},
|
|
||||||
force
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isNumber(scrollOffsetX)) {
|
|
||||||
scrollLeft(_viewport, scrollOffsetX);
|
|
||||||
}
|
|
||||||
if (isNumber(scrollOffsetY)) {
|
|
||||||
scrollTop(_viewport, scrollOffsetY);
|
|
||||||
}
|
|
||||||
|
|
||||||
return adaptivedUpdateHints;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -4,7 +4,11 @@ import type { PartialOptions } 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 = void> = (changedOptions: PartialOptions<Options>, force?: boolean) => T;
|
export type SetupUpdate<T extends any[]> = (
|
||||||
|
changedOptions: PartialOptions<Options>,
|
||||||
|
force: boolean,
|
||||||
|
...args: T
|
||||||
|
) => void;
|
||||||
|
|
||||||
export type SetupUpdateCheckOption = <T>(path: string) => [value: T, changed: boolean];
|
export type SetupUpdateCheckOption = <T>(path: string) => [value: T, changed: boolean];
|
||||||
|
|
||||||
@@ -19,11 +23,11 @@ export type SetupState<T extends Record<string, any>> = [
|
|||||||
set: (newState: Partial<T>) => void
|
set: (newState: Partial<T>) => void
|
||||||
];
|
];
|
||||||
|
|
||||||
export type Setup<DynamicState, StaticState extends Record<string, any> = Record<string, any>> = [
|
export type Setup<
|
||||||
update: SetupUpdate,
|
DynamicState,
|
||||||
state: (() => DynamicState) & StaticState,
|
StaticState extends Record<string, any> = Record<string, any>,
|
||||||
destroy: () => void
|
A extends any[] = []
|
||||||
];
|
> = [update: SetupUpdate<A>, state: (() => DynamicState) & StaticState, destroy: () => void];
|
||||||
|
|
||||||
const getPropByPath = <T>(obj: any, path: string): T =>
|
const getPropByPath = <T>(obj: any, path: string): T =>
|
||||||
obj
|
obj
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { each, isNumber, scrollLeft, scrollTop, assignDeep, keys } from 'support';
|
import { each, isNumber, scrollLeft, scrollTop, assignDeep, keys } from 'support';
|
||||||
import { getEnvironment } from 'environment';
|
import { getEnvironment } from 'environment';
|
||||||
import {
|
import {
|
||||||
createTrinsicUpdate,
|
createTrinsicUpdateSegment,
|
||||||
createPaddingUpdate,
|
createPaddingUpdateSegment,
|
||||||
createOverflowUpdate,
|
createOverflowUpdateSegment,
|
||||||
} from 'setups/structureSetup/updateSegments';
|
} from 'setups/structureSetup/updateSegments';
|
||||||
import type { SetupState, SetupUpdateSegment, SetupUpdateCheckOption } from 'setups';
|
import type { SetupState, SetupUpdateSegment, SetupUpdateCheckOption } from 'setups';
|
||||||
import type { StructureSetupState } from 'setups/structureSetup';
|
import type { StructureSetupState } from 'setups/structureSetup';
|
||||||
@@ -66,9 +66,9 @@ export const createStructureSetupUpdate = (
|
|||||||
!_nativeScrollbarStyling && (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y);
|
!_nativeScrollbarStyling && (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y);
|
||||||
|
|
||||||
const updateSegments: StructureSetupUpdateSegment[] = [
|
const updateSegments: StructureSetupUpdateSegment[] = [
|
||||||
createTrinsicUpdate(structureSetupElements, state),
|
createTrinsicUpdateSegment(structureSetupElements, state),
|
||||||
createPaddingUpdate(structureSetupElements, state),
|
createPaddingUpdateSegment(structureSetupElements, state),
|
||||||
createOverflowUpdate(structureSetupElements, state),
|
createOverflowUpdateSegment(structureSetupElements, state),
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
+1
-1
@@ -93,7 +93,7 @@ const overflowIsVisible = (overflowBehavior: string) => overflowBehavior.indexOf
|
|||||||
* @param structureUpdateHub
|
* @param structureUpdateHub
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const createOverflowUpdate: CreateStructureUpdateSegment = (
|
export const createOverflowUpdateSegment: CreateStructureUpdateSegment = (
|
||||||
structureSetupElements,
|
structureSetupElements,
|
||||||
state
|
state
|
||||||
) => {
|
) => {
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ import type { CreateStructureUpdateSegment } from 'setups/structureSetup/structu
|
|||||||
* @param structureUpdateHub
|
* @param structureUpdateHub
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const createPaddingUpdate: CreateStructureUpdateSegment = (
|
export const createPaddingUpdateSegment: CreateStructureUpdateSegment = (
|
||||||
structureSetupElements,
|
structureSetupElements,
|
||||||
state
|
state
|
||||||
) => {
|
) => {
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ import type { CreateStructureUpdateSegment } from 'setups/structureSetup/structu
|
|||||||
* @param structureUpdateHub
|
* @param structureUpdateHub
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const createTrinsicUpdate: CreateStructureUpdateSegment = (
|
export const createTrinsicUpdateSegment: CreateStructureUpdateSegment = (
|
||||||
structureSetupElements,
|
structureSetupElements,
|
||||||
state
|
state
|
||||||
) => {
|
) => {
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
.os-scrollbar-transition {
|
|
||||||
transition: opacity 0.3s, visibility 0.3s, top 0.3s, right 0.3s, bottom 0.3s, left 0.3s;
|
|
||||||
}
|
|
||||||
.os-scrollbar {
|
.os-scrollbar {
|
||||||
|
transition: opacity 0.3s, visibility 0.3s, top 0.3s, right 0.3s, bottom 0.3s, left 0.3s;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
opacity: 1;
|
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
.os-scrollbar-track {
|
.os-scrollbar-track {
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
@@ -48,14 +47,25 @@
|
|||||||
right: auto;
|
right: auto;
|
||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
.os-scrollbar-hidden {
|
.os-scrollbar-visible {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
.os-scrollbar-auto-hidden {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
pointer-events: none;
|
|
||||||
}
|
}
|
||||||
.os-scrollbar:hover {
|
.os-scrollbar-interaction.os-scrollbar-visible {
|
||||||
opacity: 1 !important;
|
opacity: 1;
|
||||||
visibility: visible !important;
|
visibility: visible;
|
||||||
|
}
|
||||||
|
.os-scrollbar.os-scrollbar-horizontal.os-scrollbar-cornerless {
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.os-scrollbar.os-scrollbar-vertical.os-scrollbar-cornerless {
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export const on = <T extends Event = Event>(
|
|||||||
options?: OnOptions
|
options?: OnOptions
|
||||||
): (() => void) => {
|
): (() => void) => {
|
||||||
const doSupportPassiveEvents = supportPassiveEvents();
|
const doSupportPassiveEvents = supportPassiveEvents();
|
||||||
const passive = (doSupportPassiveEvents && options && options._passive) || false;
|
const passive = (doSupportPassiveEvents && options && options._passive) ?? doSupportPassiveEvents;
|
||||||
const capture = (options && options._capture) || false;
|
const capture = (options && options._capture) || false;
|
||||||
const once = (options && options._once) || false;
|
const once = (options && options._once) || false;
|
||||||
const offListeners: (() => void)[] = [];
|
const offListeners: (() => void)[] = [];
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { from } from 'support/utils/array';
|
|||||||
import { rAF, cAF } from 'support/compatibility/apis';
|
import { rAF, cAF } from 'support/compatibility/apis';
|
||||||
|
|
||||||
const clearTimeouts = (id: number | undefined) => {
|
const clearTimeouts = (id: number | undefined) => {
|
||||||
id && window.clearTimeout(id);
|
id && clearTimeout(id);
|
||||||
id && cAF!(id);
|
id && cAF!(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ export const debounce = <FunctionToDebounce extends (...args: any) => any>(
|
|||||||
let prevArguments: Parameters<FunctionToDebounce> | null | undefined;
|
let prevArguments: Parameters<FunctionToDebounce> | null | undefined;
|
||||||
let latestArguments: Parameters<FunctionToDebounce> | null | undefined;
|
let latestArguments: Parameters<FunctionToDebounce> | null | undefined;
|
||||||
const { _timeout, _maxDelay, _mergeParams } = options || {};
|
const { _timeout, _maxDelay, _mergeParams } = options || {};
|
||||||
const setT = window.setTimeout;
|
const setT = setTimeout as (...args: any[]) => number;
|
||||||
|
|
||||||
const invokeFunctionToDebounce = function (args: IArguments) {
|
const invokeFunctionToDebounce = function (args: IArguments) {
|
||||||
clearTimeouts(timeoutId);
|
clearTimeouts(timeoutId);
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ export const isPlainObject = <T = any>(obj: any): obj is PlainObject<T> => {
|
|||||||
* @param obj The object which shall be checked.
|
* @param obj The object which shall be checked.
|
||||||
*/
|
*/
|
||||||
export const isHTMLElement = (obj: any): obj is HTMLElement => {
|
export const isHTMLElement = (obj: any): obj is HTMLElement => {
|
||||||
const instanceofObj = window.HTMLElement;
|
const instanceofObj = HTMLElement;
|
||||||
return obj
|
return obj
|
||||||
? instanceofObj
|
? instanceofObj
|
||||||
? obj instanceof instanceofObj
|
? obj instanceof instanceofObj
|
||||||
@@ -88,7 +88,7 @@ export const isHTMLElement = (obj: any): obj is HTMLElement => {
|
|||||||
* @param obj The object which shall be checked.
|
* @param obj The object which shall be checked.
|
||||||
*/
|
*/
|
||||||
export const isElement = (obj: any): obj is Element => {
|
export const isElement = (obj: any): obj is Element => {
|
||||||
const instanceofObj = window.Element;
|
const instanceofObj = Element;
|
||||||
return obj
|
return obj
|
||||||
? instanceofObj
|
? instanceofObj
|
||||||
? obj instanceof instanceofObj
|
? obj instanceof instanceofObj
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ describe('dom events', () => {
|
|||||||
const once = options?._once;
|
const once = options?._once;
|
||||||
const expectObjAdd = passive
|
const expectObjAdd = passive
|
||||||
? {
|
? {
|
||||||
passive: (options && options._passive) || false,
|
passive: (options && options._passive) ?? passive,
|
||||||
capture: (options && options._capture) || false,
|
capture: (options && options._capture) || false,
|
||||||
}
|
}
|
||||||
: options?._capture || false;
|
: options?._capture || false;
|
||||||
|
|||||||
@@ -104,6 +104,8 @@ body {
|
|||||||
background: blue;
|
background: blue;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
height: 10000px;
|
||||||
|
width: 10000px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.percent {
|
.percent {
|
||||||
|
|||||||
+7
-4
@@ -24,8 +24,8 @@ type InitialEventListeners<EventMap extends Record<string, any[]>> = {
|
|||||||
[K in keyof EventMap]?: EventListener<EventMap> | EventListener<EventMap>[];
|
[K in keyof EventMap]?: EventListener<EventMap> | EventListener<EventMap>[];
|
||||||
};
|
};
|
||||||
type OverflowBehavior = "hidden" | "scroll" | "visible" | "visible-hidden" | "visible-scroll";
|
type OverflowBehavior = "hidden" | "scroll" | "visible" | "visible-hidden" | "visible-scroll";
|
||||||
type VisibilityBehavior = "visible" | "hidden" | "auto";
|
type ScrollbarVisibilityBehavior = "visible" | "hidden" | "auto";
|
||||||
type AutoHideBehavior = "never" | "scroll" | "leave" | "move";
|
type ScrollbarAutoHideBehavior = "never" | "scroll" | "leave" | "move";
|
||||||
interface Options {
|
interface Options {
|
||||||
paddingAbsolute: boolean;
|
paddingAbsolute: boolean;
|
||||||
updating: {
|
updating: {
|
||||||
@@ -45,8 +45,8 @@ interface Options {
|
|||||||
y: OverflowBehavior;
|
y: OverflowBehavior;
|
||||||
};
|
};
|
||||||
scrollbars: {
|
scrollbars: {
|
||||||
visibility: VisibilityBehavior;
|
visibility: ScrollbarVisibilityBehavior;
|
||||||
autoHide: AutoHideBehavior;
|
autoHide: ScrollbarAutoHideBehavior;
|
||||||
autoHideDelay: number;
|
autoHideDelay: number;
|
||||||
dragScroll: boolean;
|
dragScroll: boolean;
|
||||||
clickScroll: boolean;
|
clickScroll: boolean;
|
||||||
@@ -115,6 +115,7 @@ interface StructureSetupState {
|
|||||||
_padding: TRBL;
|
_padding: TRBL;
|
||||||
_paddingAbsolute: boolean;
|
_paddingAbsolute: boolean;
|
||||||
_viewportPaddingStyle: StyleObject;
|
_viewportPaddingStyle: StyleObject;
|
||||||
|
_overflowEdge: XY<number>;
|
||||||
_overflowAmount: XY<number>;
|
_overflowAmount: XY<number>;
|
||||||
_overflowStyle: XY<OverflowStyle>;
|
_overflowStyle: XY<OverflowStyle>;
|
||||||
_hasOverflow: XY<boolean>;
|
_hasOverflow: XY<boolean>;
|
||||||
@@ -196,6 +197,7 @@ interface Environment {
|
|||||||
interface State {
|
interface State {
|
||||||
padding: TRBL;
|
padding: TRBL;
|
||||||
paddingAbsolute: boolean;
|
paddingAbsolute: boolean;
|
||||||
|
overflowEdge: XY<number>;
|
||||||
overflowAmount: XY<number>;
|
overflowAmount: XY<number>;
|
||||||
overflowStyle: XY<OverflowStyle>;
|
overflowStyle: XY<OverflowStyle>;
|
||||||
hasOverflow: XY<boolean>;
|
hasOverflow: XY<boolean>;
|
||||||
@@ -213,6 +215,7 @@ interface OnUpdatedEventListenerArgs {
|
|||||||
sizeChanged: boolean;
|
sizeChanged: boolean;
|
||||||
directionChanged: boolean;
|
directionChanged: boolean;
|
||||||
heightIntrinsicChanged: boolean;
|
heightIntrinsicChanged: boolean;
|
||||||
|
overflowEdgeChanged: boolean;
|
||||||
overflowAmountChanged: boolean;
|
overflowAmountChanged: boolean;
|
||||||
overflowStyleChanged: boolean;
|
overflowStyleChanged: boolean;
|
||||||
hostMutation: boolean;
|
hostMutation: boolean;
|
||||||
|
|||||||
@@ -66,33 +66,38 @@ export const resize = (element: HTMLElement) => {
|
|||||||
dragResizeBtn = undefined;
|
dragResizeBtn = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
on(resizeBtn, strMouseTouchDownEvent, (event: MouseEvent | TouchEvent) => {
|
on(
|
||||||
const { currentTarget } = event;
|
resizeBtn,
|
||||||
const correctButton = (event as MouseEvent).buttons === 1 || event.which === 1;
|
strMouseTouchDownEvent,
|
||||||
const isTouchEvent = (event as TouchEvent).touches !== undefined;
|
(event: MouseEvent | TouchEvent) => {
|
||||||
const mouseOffsetHolder = isTouchEvent
|
const { currentTarget } = event;
|
||||||
? (event as TouchEvent).touches[0]
|
const correctButton = (event as MouseEvent).buttons === 1 || event.which === 1;
|
||||||
: (event as MouseEvent);
|
const isTouchEvent = (event as TouchEvent).touches !== undefined;
|
||||||
|
const mouseOffsetHolder = isTouchEvent
|
||||||
|
? (event as TouchEvent).touches[0]
|
||||||
|
: (event as MouseEvent);
|
||||||
|
|
||||||
if (correctButton || isTouchEvent) {
|
if (correctButton || isTouchEvent) {
|
||||||
dragStartPosition.x = mouseOffsetHolder.pageX;
|
dragStartPosition.x = mouseOffsetHolder.pageX;
|
||||||
dragStartPosition.y = mouseOffsetHolder.pageY;
|
dragStartPosition.y = mouseOffsetHolder.pageY;
|
||||||
|
|
||||||
dragResizeBtn = currentTarget as HTMLElement;
|
dragResizeBtn = currentTarget as HTMLElement;
|
||||||
dragResizer = parent(currentTarget as HTMLElement) as HTMLElement;
|
dragResizer = parent(currentTarget as HTMLElement) as HTMLElement;
|
||||||
|
|
||||||
const cSize = clientSize(element);
|
const cSize = clientSize(element);
|
||||||
dragStartSize.w = cSize.w;
|
dragStartSize.w = cSize.w;
|
||||||
dragStartSize.h = cSize.h;
|
dragStartSize.h = cSize.h;
|
||||||
|
|
||||||
on(document, strSelectStartEvent, onSelectStart);
|
on(document, strSelectStartEvent, onSelectStart, { _passive: false });
|
||||||
on(document, strMouseTouchMoveEvent, resizerResize);
|
on(document, strMouseTouchMoveEvent, resizerResize, { _passive: false });
|
||||||
on(document, strMouseTouchUpEvent, resizerResized);
|
on(document, strMouseTouchUpEvent, resizerResized, { _passive: false });
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
{ _passive: false }
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
addResizeListener(listener: ResizeListener) {
|
addResizeListener(listener: ResizeListener) {
|
||||||
|
|||||||
Reference in New Issue
Block a user