UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

1,185 lines (1,184 loc) • 49.7 kB
/** * DevExtreme (esm/renovation/ui/scroll_view/scrollable_native.js) * Version: 21.1.4 * Build date: Mon Jun 21 2021 * * Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose"; import _extends from "@babel/runtime/helpers/esm/extends"; var _excluded = ["aria", "bounceEnabled", "children", "classes", "direction", "disabled", "forceGeneratePockets", "height", "needScrollViewContentWrapper", "needScrollViewLoadPanel", "onKeyDown", "onPullDown", "onReachBottom", "onScroll", "onUpdated", "pullDownEnabled", "pulledDownText", "pullingDownText", "reachBottomEnabled", "reachBottomText", "refreshingText", "rtlEnabled", "scrollByContent", "scrollByThumb", "showScrollbar", "updateManually", "useNative", "useSimulatedScrollbar", "visible", "width"]; import { createVNode, createComponentVNode, normalizeProps } from "inferno"; import { InfernoEffect, InfernoComponent, normalizeStyles } from "@devextreme/vdom"; import { subscribeToScrollEvent } from "../../utils/subscribe_to_event"; import { Widget, WidgetProps } from "../common/widget"; import { ScrollViewLoadPanel } from "./load_panel"; import { combineClasses } from "../../utils/combine_classes"; import { getScrollLeftMax } from "./utils/get_scroll_left_max"; import { getAugmentedLocation } from "./utils/get_augmented_location"; import { getBoundaryProps, isReachedBottom } from "./utils/get_boundary_props"; import devices from "../../../core/devices"; import browser from "../../../core/utils/browser"; import { isDefined } from "../../../core/utils/type"; import { BaseWidgetProps } from "../common/base_props"; import { ScrollableProps } from "./scrollable_props"; import { TopPocket } from "./top_pocket"; import { BottomPocket } from "./bottom_pocket"; import { nativeScrolling } from "../../../core/utils/support"; import "../../../events/gesture/emitter.gesture.scroll"; import { isDxMouseWheelEvent } from "../../../events/utils/index"; import { getScrollSign, getLocation, normalizeOffsetLeft } from "./scrollable_utils"; import { ScrollDirection } from "./utils/scroll_direction"; import { DIRECTION_VERTICAL, DIRECTION_HORIZONTAL, DIRECTION_BOTH, SCROLLABLE_CONTAINER_CLASS, SCROLLABLE_CONTENT_CLASS, SCROLLABLE_WRAPPER_CLASS, SCROLLVIEW_CONTENT_CLASS, SCROLLABLE_DISABLED_CLASS, SCROLLABLE_SCROLLBAR_SIMULATED, SCROLLABLE_SCROLLBARS_HIDDEN, TopPocketState } from "./common/consts"; import { Scrollbar } from "./scrollbar"; import { dxScrollInit, dxScrollMove, dxScrollEnd, dxScrollStop } from "../../../events/short"; import { getOffsetDistance } from "./utils/get_offset_distance"; var HIDE_SCROLLBAR_TIMEOUT = 500; export var viewFunction = viewModel => { var { bottomPocketRef: bottomPocketRef, containerClientHeight: containerClientHeight, containerClientWidth: containerClientWidth, containerRef: containerRef, contentClientHeight: contentClientHeight, contentClientWidth: contentClientWidth, contentRef: contentRef, contentStyles: contentStyles, contentTranslateTop: contentTranslateTop, cssClasses: cssClasses, direction: direction, hScrollLocation: hScrollLocation, hScrollbarRef: hScrollbarRef, isLoadPanelVisible: isLoadPanelVisible, needForceScrollbarsVisibility: needForceScrollbarsVisibility, props: { aria: aria, children: children, disabled: disabled, forceGeneratePockets: forceGeneratePockets, height: height, needScrollViewContentWrapper: needScrollViewContentWrapper, needScrollViewLoadPanel: needScrollViewLoadPanel, pullDownEnabled: pullDownEnabled, pulledDownText: pulledDownText, pullingDownText: pullingDownText, reachBottomEnabled: reachBottomEnabled, reachBottomText: reachBottomText, refreshingText: refreshingText, rtlEnabled: rtlEnabled, scrollByThumb: scrollByThumb, showScrollbar: showScrollbar, visible: visible, width: width }, pullDownIconAngle: pullDownIconAngle, pullDownOpacity: pullDownOpacity, pullDownTranslateTop: pullDownTranslateTop, refreshStrategy: refreshStrategy, restAttributes: restAttributes, scrollViewContentRef: scrollViewContentRef, scrollableRef: scrollableRef, topPocketRef: topPocketRef, topPocketState: topPocketState, topPocketTop: topPocketTop, useSimulatedScrollbar: useSimulatedScrollbar, vScrollLocation: vScrollLocation, vScrollbarRef: vScrollbarRef, windowResizeHandler: windowResizeHandler, wrapperRef: wrapperRef } = viewModel; return normalizeProps(createComponentVNode(2, Widget, _extends({ rootElementRef: scrollableRef, aria: aria, classes: cssClasses, disabled: disabled, rtlEnabled: rtlEnabled, height: height, width: width, visible: visible, onDimensionChanged: windowResizeHandler }, restAttributes, { children: [createVNode(1, "div", SCROLLABLE_WRAPPER_CLASS, createVNode(1, "div", SCROLLABLE_CONTAINER_CLASS, createVNode(1, "div", SCROLLABLE_CONTENT_CLASS, [forceGeneratePockets && createComponentVNode(2, TopPocket, { topPocketRef: topPocketRef, pullingDownText: pullingDownText, pulledDownText: pulledDownText, refreshingText: refreshingText, pocketState: topPocketState, refreshStrategy: refreshStrategy, pullDownTranslateTop: pullDownTranslateTop, pullDownIconAngle: pullDownIconAngle, topPocketTranslateTop: contentTranslateTop, pullDownOpacity: pullDownOpacity, pocketTop: topPocketTop, visible: !!pullDownEnabled }), needScrollViewContentWrapper ? createVNode(1, "div", SCROLLVIEW_CONTENT_CLASS, children, 0, { style: normalizeStyles(contentStyles) }, null, scrollViewContentRef) : createVNode(1, "div", null, children, 0), forceGeneratePockets && createComponentVNode(2, BottomPocket, { bottomPocketRef: bottomPocketRef, reachBottomText: reachBottomText, visible: !!reachBottomEnabled })], 0, null, null, contentRef), 2, null, null, containerRef), 2, null, null, wrapperRef), needScrollViewLoadPanel && createComponentVNode(2, ScrollViewLoadPanel, { targetElement: scrollableRef, refreshingText: refreshingText, visible: isLoadPanelVisible }), showScrollbar && useSimulatedScrollbar && direction.isHorizontal && createComponentVNode(2, Scrollbar, { direction: "horizontal", scrollByThumb: scrollByThumb, contentSize: contentClientWidth, containerSize: containerClientWidth, scrollLocation: hScrollLocation, forceVisibility: needForceScrollbarsVisibility }, null, hScrollbarRef), showScrollbar && useSimulatedScrollbar && direction.isVertical && createComponentVNode(2, Scrollbar, { direction: "vertical", scrollByThumb: scrollByThumb, contentSize: contentClientHeight, containerSize: containerClientHeight, scrollLocation: vScrollLocation, forceVisibility: needForceScrollbarsVisibility }, null, vScrollbarRef)] }))) }; export var ScrollableNativeProps = _extends({}, ScrollableProps); export var ScrollableNativePropsType = { useNative: ScrollableNativeProps.useNative, direction: ScrollableNativeProps.direction, showScrollbar: ScrollableNativeProps.showScrollbar, bounceEnabled: ScrollableNativeProps.bounceEnabled, scrollByContent: ScrollableNativeProps.scrollByContent, scrollByThumb: ScrollableNativeProps.scrollByThumb, updateManually: ScrollableNativeProps.updateManually, pullDownEnabled: ScrollableNativeProps.pullDownEnabled, reachBottomEnabled: ScrollableNativeProps.reachBottomEnabled, forceGeneratePockets: ScrollableNativeProps.forceGeneratePockets, needScrollViewContentWrapper: ScrollableNativeProps.needScrollViewContentWrapper, needScrollViewLoadPanel: ScrollableNativeProps.needScrollViewLoadPanel, aria: WidgetProps.aria, disabled: BaseWidgetProps.disabled, visible: BaseWidgetProps.visible }; import { createRef as infernoCreateRef } from "inferno"; export class ScrollableNative extends InfernoComponent { constructor(props) { super(props); this._currentState = null; this.scrollableRef = infernoCreateRef(); this.wrapperRef = infernoCreateRef(); this.contentRef = infernoCreateRef(); this.scrollViewContentRef = infernoCreateRef(); this.containerRef = infernoCreateRef(); this.vScrollbarRef = infernoCreateRef(); this.hScrollbarRef = infernoCreateRef(); this.topPocketRef = infernoCreateRef(); this.bottomPocketRef = infernoCreateRef(); this.locked = false; this.loadingIndicatorEnabled = true; this.initPageY = 0; this.deltaY = 0; this.lastLocation = { top: 0, left: 0 }; this.locationTop = 0; this.state = { containerClientWidth: 0, containerClientHeight: 0, contentClientWidth: 0, contentClientHeight: 0, needForceScrollbarsVisibility: false, topPocketState: TopPocketState.STATE_RELEASED, isLoadPanelVisible: false, pullDownTranslateTop: 0, pullDownIconAngle: 0, pullDownOpacity: 0, topPocketTop: -80, contentTranslateTop: 0, vScrollLocation: 0, hScrollLocation: 0 }; this.content = this.content.bind(this); this.update = this.update.bind(this); this.refresh = this.refresh.bind(this); this.release = this.release.bind(this); this.clearReleaseTimeout = this.clearReleaseTimeout.bind(this); this.disposeReleaseTimeout = this.disposeReleaseTimeout.bind(this); this.onRelease = this.onRelease.bind(this); this.onUpdated = this.onUpdated.bind(this); this.startLoading = this.startLoading.bind(this); this.finishLoading = this.finishLoading.bind(this); this.scrollTo = this.scrollTo.bind(this); this.scrollBy = this.scrollBy.bind(this); this.scrollToElement = this.scrollToElement.bind(this); this.getElementLocation = this.getElementLocation.bind(this); this.scrollHeight = this.scrollHeight.bind(this); this.scrollWidth = this.scrollWidth.bind(this); this.scrollOffset = this.scrollOffset.bind(this); this.scrollTop = this.scrollTop.bind(this); this.scrollLeft = this.scrollLeft.bind(this); this.clientHeight = this.clientHeight.bind(this); this.clientWidth = this.clientWidth.bind(this); this.scrollEffect = this.scrollEffect.bind(this); this.handleScroll = this.handleScroll.bind(this); this.handlePocketState = this.handlePocketState.bind(this); this.pullDownReady = this.pullDownReady.bind(this); this.onReachBottom = this.onReachBottom.bind(this); this.onPullDown = this.onPullDown.bind(this); this.stateReleased = this.stateReleased.bind(this); this.getEventArgs = this.getEventArgs.bind(this); this.effectDisabledState = this.effectDisabledState.bind(this); this.lock = this.lock.bind(this); this.unlock = this.unlock.bind(this); this.effectResetInactiveState = this.effectResetInactiveState.bind(this); this.updateScrollbarSize = this.updateScrollbarSize.bind(this); this.windowResizeHandler = this.windowResizeHandler.bind(this); this.updateSizes = this.updateSizes.bind(this); this.moveScrollbars = this.moveScrollbars.bind(this); this.disposeHideScrollbarTimeout = this.disposeHideScrollbarTimeout.bind(this); this.clearHideScrollbarTimeout = this.clearHideScrollbarTimeout.bind(this); this.scrollLocation = this.scrollLocation.bind(this); this.initEffect = this.initEffect.bind(this); this.getInitEventData = this.getInitEventData.bind(this); this.moveEffect = this.moveEffect.bind(this); this.endEffect = this.endEffect.bind(this); this.stopEffect = this.stopEffect.bind(this); this.handleInit = this.handleInit.bind(this); this.handleMove = this.handleMove.bind(this); this.handleEnd = this.handleEnd.bind(this); this.handleStop = this.handleStop.bind(this); this.pullDownComplete = this.pullDownComplete.bind(this); this.clearRefreshTimeout = this.clearRefreshTimeout.bind(this); this.disposeRefreshTimeout = this.disposeRefreshTimeout.bind(this); this.pullDownRefreshing = this.pullDownRefreshing.bind(this); this.movePullDown = this.movePullDown.bind(this); this.getPullDownHeight = this.getPullDownHeight.bind(this); this.getPullDownStartPosition = this.getPullDownStartPosition.bind(this); this.complete = this.complete.bind(this); this.releaseState = this.releaseState.bind(this); this.isSwipeDown = this.isSwipeDown.bind(this); this.isPullDown = this.isPullDown.bind(this); this.isReachBottom = this.isReachBottom.bind(this); this.tryGetAllowedDirection = this.tryGetAllowedDirection.bind(this); this.validate = this.validate.bind(this); this.isLocked = this.isLocked.bind(this); this.isScrollingOutOfBound = this.isScrollingOutOfBound.bind(this) } createEffects() { return [new InfernoEffect(this.disposeReleaseTimeout, []), new InfernoEffect(this.scrollEffect, [this.props.useSimulatedScrollbar, this.props.onScroll, this.props.rtlEnabled, this.props.direction, this.props.forceGeneratePockets, this.topPocketState, this.props.reachBottomEnabled, this.props.onReachBottom, this.props.pullDownEnabled]), new InfernoEffect(this.effectDisabledState, [this.props.disabled]), new InfernoEffect(this.effectResetInactiveState, [this.props.direction]), new InfernoEffect(this.updateScrollbarSize, [this.containerClientWidth, this.containerClientHeight, this.contentClientWidth, this.contentClientHeight, this.needForceScrollbarsVisibility, this.topPocketState, this.isLoadPanelVisible, this.pullDownTranslateTop, this.pullDownIconAngle, this.pullDownOpacity, this.topPocketTop, this.contentTranslateTop, this.vScrollLocation, this.hScrollLocation, this.props.useSimulatedScrollbar, this.props.children, this.props.useNative, this.props.direction, this.props.showScrollbar, this.props.bounceEnabled, this.props.scrollByContent, this.props.scrollByThumb, this.props.updateManually, this.props.classes, this.props.pullDownEnabled, this.props.reachBottomEnabled, this.props.forceGeneratePockets, this.props.needScrollViewContentWrapper, this.props.needScrollViewLoadPanel, this.props.onScroll, this.props.onUpdated, this.props.onPullDown, this.props.onReachBottom, this.props.pullingDownText, this.props.pulledDownText, this.props.refreshingText, this.props.reachBottomText, this.props.aria, this.props.disabled, this.props.height, this.props.onKeyDown, this.props.rtlEnabled, this.props.visible, this.props.width]), new InfernoEffect(this.disposeHideScrollbarTimeout, []), new InfernoEffect(this.initEffect, [this.props.forceGeneratePockets, this.topPocketState, this.props.direction, this.props.pullDownEnabled, this.props.disabled, this.props.updateManually, this.props.onUpdated, this.props.rtlEnabled, this.props.needScrollViewContentWrapper]), new InfernoEffect(this.moveEffect, [this.props.direction, this.props.pullDownEnabled, this.props.forceGeneratePockets, this.topPocketState]), new InfernoEffect(this.endEffect, [this.props.forceGeneratePockets, this.props.pullDownEnabled, this.topPocketState, this.props.onPullDown]), new InfernoEffect(this.stopEffect, [this.props.forceGeneratePockets, this.topPocketState, this.props.onPullDown]), new InfernoEffect(this.disposeRefreshTimeout, [])] } updateEffects() { var _this$_effects$, _this$_effects$2, _this$_effects$3, _this$_effects$4, _this$_effects$5, _this$_effects$6, _this$_effects$7, _this$_effects$8; null === (_this$_effects$ = this._effects[1]) || void 0 === _this$_effects$ ? void 0 : _this$_effects$.update([this.props.useSimulatedScrollbar, this.props.onScroll, this.props.rtlEnabled, this.props.direction, this.props.forceGeneratePockets, this.topPocketState, this.props.reachBottomEnabled, this.props.onReachBottom, this.props.pullDownEnabled]); null === (_this$_effects$2 = this._effects[2]) || void 0 === _this$_effects$2 ? void 0 : _this$_effects$2.update([this.props.disabled]); null === (_this$_effects$3 = this._effects[3]) || void 0 === _this$_effects$3 ? void 0 : _this$_effects$3.update([this.props.direction]); null === (_this$_effects$4 = this._effects[4]) || void 0 === _this$_effects$4 ? void 0 : _this$_effects$4.update([this.containerClientWidth, this.containerClientHeight, this.contentClientWidth, this.contentClientHeight, this.needForceScrollbarsVisibility, this.topPocketState, this.isLoadPanelVisible, this.pullDownTranslateTop, this.pullDownIconAngle, this.pullDownOpacity, this.topPocketTop, this.contentTranslateTop, this.vScrollLocation, this.hScrollLocation, this.props.useSimulatedScrollbar, this.props.children, this.props.useNative, this.props.direction, this.props.showScrollbar, this.props.bounceEnabled, this.props.scrollByContent, this.props.scrollByThumb, this.props.updateManually, this.props.classes, this.props.pullDownEnabled, this.props.reachBottomEnabled, this.props.forceGeneratePockets, this.props.needScrollViewContentWrapper, this.props.needScrollViewLoadPanel, this.props.onScroll, this.props.onUpdated, this.props.onPullDown, this.props.onReachBottom, this.props.pullingDownText, this.props.pulledDownText, this.props.refreshingText, this.props.reachBottomText, this.props.aria, this.props.disabled, this.props.height, this.props.onKeyDown, this.props.rtlEnabled, this.props.visible, this.props.width]); null === (_this$_effects$5 = this._effects[6]) || void 0 === _this$_effects$5 ? void 0 : _this$_effects$5.update([this.props.forceGeneratePockets, this.topPocketState, this.props.direction, this.props.pullDownEnabled, this.props.disabled, this.props.updateManually, this.props.onUpdated, this.props.rtlEnabled, this.props.needScrollViewContentWrapper]); null === (_this$_effects$6 = this._effects[7]) || void 0 === _this$_effects$6 ? void 0 : _this$_effects$6.update([this.props.direction, this.props.pullDownEnabled, this.props.forceGeneratePockets, this.topPocketState]); null === (_this$_effects$7 = this._effects[8]) || void 0 === _this$_effects$7 ? void 0 : _this$_effects$7.update([this.props.forceGeneratePockets, this.props.pullDownEnabled, this.topPocketState, this.props.onPullDown]); null === (_this$_effects$8 = this._effects[9]) || void 0 === _this$_effects$8 ? void 0 : _this$_effects$8.update([this.props.forceGeneratePockets, this.topPocketState, this.props.onPullDown]) } get containerClientWidth() { var state = this._currentState || this.state; return state.containerClientWidth } set_containerClientWidth(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { containerClientWidth: newValue } }) } get containerClientHeight() { var state = this._currentState || this.state; return state.containerClientHeight } set_containerClientHeight(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { containerClientHeight: newValue } }) } get contentClientWidth() { var state = this._currentState || this.state; return state.contentClientWidth } set_contentClientWidth(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { contentClientWidth: newValue } }) } get contentClientHeight() { var state = this._currentState || this.state; return state.contentClientHeight } set_contentClientHeight(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { contentClientHeight: newValue } }) } get needForceScrollbarsVisibility() { var state = this._currentState || this.state; return state.needForceScrollbarsVisibility } set_needForceScrollbarsVisibility(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { needForceScrollbarsVisibility: newValue } }) } get topPocketState() { var state = this._currentState || this.state; return state.topPocketState } set_topPocketState(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { topPocketState: newValue } }) } get isLoadPanelVisible() { var state = this._currentState || this.state; return state.isLoadPanelVisible } set_isLoadPanelVisible(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { isLoadPanelVisible: newValue } }) } get pullDownTranslateTop() { var state = this._currentState || this.state; return state.pullDownTranslateTop } set_pullDownTranslateTop(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { pullDownTranslateTop: newValue } }) } get pullDownIconAngle() { var state = this._currentState || this.state; return state.pullDownIconAngle } set_pullDownIconAngle(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { pullDownIconAngle: newValue } }) } get pullDownOpacity() { var state = this._currentState || this.state; return state.pullDownOpacity } set_pullDownOpacity(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { pullDownOpacity: newValue } }) } get topPocketTop() { var state = this._currentState || this.state; return state.topPocketTop } set_topPocketTop(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { topPocketTop: newValue } }) } get contentTranslateTop() { var state = this._currentState || this.state; return state.contentTranslateTop } set_contentTranslateTop(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { contentTranslateTop: newValue } }) } get vScrollLocation() { var state = this._currentState || this.state; return state.vScrollLocation } set_vScrollLocation(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { vScrollLocation: newValue } }) } get hScrollLocation() { var state = this._currentState || this.state; return state.hScrollLocation } set_hScrollLocation(value) { this.setState(state => { this._currentState = state; var newValue = value(); this._currentState = null; return { hScrollLocation: newValue } }) } disposeReleaseTimeout() { return () => this.clearReleaseTimeout() } scrollEffect() { return subscribeToScrollEvent(this.containerRef.current, e => { this.handleScroll(e) }) } effectDisabledState() { if (this.props.disabled) { this.lock() } else { this.unlock() } } effectResetInactiveState() { var containerEl = this.containerRef.current; if (this.props.direction === DIRECTION_BOTH || !isDefined(containerEl)) { return } containerEl[this.fullScrollInactiveProp] = 0 } updateScrollbarSize() { this.updateSizes() } disposeHideScrollbarTimeout() { return () => this.clearHideScrollbarTimeout() } initEffect() { dxScrollInit.on(this.wrapperRef.current, e => { this.handleInit(e) }, this.getInitEventData(), { namespace: "dxScrollable" }); return () => dxScrollInit.off(this.wrapperRef.current, { namespace: "dxScrollable" }) } moveEffect() { dxScrollMove.on(this.wrapperRef.current, e => { this.handleMove(e) }, { namespace: "dxScrollable" }); return () => dxScrollMove.off(this.wrapperRef.current, { namespace: "dxScrollable" }) } endEffect() { dxScrollEnd.on(this.wrapperRef.current, () => { this.handleEnd() }, { namespace: "dxScrollable" }); return () => dxScrollEnd.off(this.wrapperRef.current, { namespace: "dxScrollable" }) } stopEffect() { dxScrollStop.on(this.wrapperRef.current, () => { this.handleStop() }, { namespace: "dxScrollable" }); return () => dxScrollStop.off(this.wrapperRef.current, { namespace: "dxScrollable" }) } disposeRefreshTimeout() { return () => this.clearRefreshTimeout() } clearReleaseTimeout() { clearTimeout(this.releaseTimeout); this.releaseTimeout = void 0 } onRelease() { this.loadingIndicatorEnabled = true; this.finishLoading(); this.onUpdated() } onUpdated() { var _this$props$onUpdated, _this$props; null === (_this$props$onUpdated = (_this$props = this.props).onUpdated) || void 0 === _this$props$onUpdated ? void 0 : _this$props$onUpdated.call(_this$props, this.getEventArgs()) } startLoading() { if (this.loadingIndicatorEnabled) { this.set_isLoadPanelVisible(() => true) } this.lock() } finishLoading() { this.set_isLoadPanelVisible(() => false); this.unlock() } handleScroll(e) { var _this$props$onScroll, _this$props2; this.eventForUserAction = e; if (this.useSimulatedScrollbar) { this.moveScrollbars() } null === (_this$props$onScroll = (_this$props2 = this.props).onScroll) || void 0 === _this$props$onScroll ? void 0 : _this$props$onScroll.call(_this$props2, this.getEventArgs()); this.lastLocation = this.scrollLocation(); this.handlePocketState() } handlePocketState() { if (this.props.forceGeneratePockets) { if (this.topPocketState === TopPocketState.STATE_REFRESHING) { return } var currentLocation = -this.scrollLocation().top; var scrollDelta = this.locationTop - currentLocation; this.locationTop = currentLocation; if (this.isSwipeDownStrategy && scrollDelta > 0 && this.isReachBottom()) { this.onReachBottom(); return } if (this.isPullDownStrategy) { if (this.isPullDown()) { this.pullDownReady(); return } if (scrollDelta > 0 && this.isReachBottom()) { if (this.topPocketState !== TopPocketState.STATE_LOADING) { this.set_topPocketState(() => TopPocketState.STATE_LOADING); this.onReachBottom() } return } } this.stateReleased() } } pullDownReady() { if (this.topPocketState === TopPocketState.STATE_READY) { return } this.set_topPocketState(() => TopPocketState.STATE_READY) } onReachBottom() { var _this$props$onReachBo, _this$props3; null === (_this$props$onReachBo = (_this$props3 = this.props).onReachBottom) || void 0 === _this$props$onReachBo ? void 0 : _this$props$onReachBo.call(_this$props3, {}) } onPullDown() { var _this$props$onPullDow, _this$props4; null === (_this$props$onPullDow = (_this$props4 = this.props).onPullDown) || void 0 === _this$props$onPullDow ? void 0 : _this$props$onPullDow.call(_this$props4, {}) } stateReleased() { if (this.topPocketState === TopPocketState.STATE_RELEASED) { return } this.releaseState() } getEventArgs() { var scrollOffset = this.scrollOffset(); return _extends({ event: this.eventForUserAction, scrollOffset: scrollOffset }, getBoundaryProps(this.props.direction, scrollOffset, this.containerRef.current, 0)) } lock() { this.locked = true } unlock() { if (!this.props.disabled) { this.locked = false } } get fullScrollInactiveProp() { return this.props.direction === DIRECTION_HORIZONTAL ? "scrollTop" : "scrollLeft" } windowResizeHandler() { this.update() } updateSizes() { var containerEl = this.containerRef.current; var contentEl = this.contentRef.current; if (isDefined(containerEl)) { this.set_containerClientWidth(() => containerEl.clientWidth); this.set_containerClientHeight(() => containerEl.clientHeight) } if (isDefined(contentEl)) { this.set_contentClientWidth(() => contentEl.clientWidth); this.set_contentClientHeight(() => contentEl.clientHeight) } } moveScrollbars() { var { left: left, top: top } = this.scrollOffset(); this.set_hScrollLocation(() => -left); this.set_vScrollLocation(() => -top); this.set_needForceScrollbarsVisibility(() => true); this.clearHideScrollbarTimeout(); this.hideScrollbarTimeout = setTimeout(() => { this.set_needForceScrollbarsVisibility(() => false) }, HIDE_SCROLLBAR_TIMEOUT) } clearHideScrollbarTimeout() { clearTimeout(this.hideScrollbarTimeout); this.hideScrollbarTimeout = void 0 } scrollLocation() { return { top: this.containerRef.current.scrollTop, left: this.containerRef.current.scrollLeft } } getInitEventData() { return { getDirection: this.tryGetAllowedDirection, validate: this.validate, isNative: true, scrollTarget: this.containerRef.current } } handleInit(e) { if (this.props.forceGeneratePockets && this.isSwipeDownStrategy) { if (this.topPocketState === TopPocketState.STATE_RELEASED && 0 === this.scrollLocation().top) { this.initPageY = e.originalEvent.pageY; this.set_topPocketState(() => TopPocketState.STATE_TOUCHED) } } } handleMove(e) { if (this.locked) { e.cancel = true; return } if (isDefined(this.tryGetAllowedDirection())) { e.originalEvent.isScrollingEvent = true } if (this.props.forceGeneratePockets && this.isSwipeDownStrategy) { this.deltaY = e.originalEvent.pageY - this.initPageY; if (this.topPocketState === TopPocketState.STATE_TOUCHED) { if (this.pullDownEnabled && this.deltaY > 0) { this.set_topPocketState(() => TopPocketState.STATE_PULLED) } else { this.complete() } } if (this.topPocketState === TopPocketState.STATE_PULLED) { e.preventDefault(); this.movePullDown() } } } handleEnd() { if (this.props.forceGeneratePockets) { if (this.isSwipeDownStrategy) { if (this.isSwipeDown()) { this.pullDownRefreshing() } this.complete() } if (this.isPullDownStrategy) { this.pullDownComplete() } } } handleStop() { if (this.props.forceGeneratePockets) { if (this.isSwipeDownStrategy) { this.complete() } if (this.isPullDownStrategy) { this.pullDownComplete() } } } pullDownComplete() { if (this.topPocketState === TopPocketState.STATE_READY) { this.set_contentTranslateTop(() => this.topPocketHeight); this.clearRefreshTimeout(); this.refreshTimeout = setTimeout(() => { this.pullDownRefreshing() }, 400) } } clearRefreshTimeout() { clearTimeout(this.refreshTimeout); this.refreshTimeout = void 0 } get topPocketHeight() { var _this$topPocketRef$cu; return (null === (_this$topPocketRef$cu = this.topPocketRef.current) || void 0 === _this$topPocketRef$cu ? void 0 : _this$topPocketRef$cu.clientHeight) || 0 } pullDownRefreshing() { if (this.topPocketState === TopPocketState.STATE_REFRESHING) { return } this.set_topPocketState(() => TopPocketState.STATE_REFRESHING); if (this.isSwipeDownStrategy) { this.set_pullDownTranslateTop(() => this.getPullDownHeight()) } this.onPullDown() } movePullDown() { var pullDownHeight = this.getPullDownHeight(); var top = Math.min(3 * pullDownHeight, this.deltaY + this.getPullDownStartPosition()); var angle = 180 * top / pullDownHeight / 3; this.set_pullDownOpacity(() => 1); this.set_pullDownTranslateTop(() => top); this.set_pullDownIconAngle(() => angle) } getPullDownHeight() { return Math.round(.05 * this.scrollableRef.current.offsetHeight) } getPullDownStartPosition() { return -Math.round(1.5 * this.topPocketRef.current.clientHeight) } complete() { if (this.topPocketState === TopPocketState.STATE_TOUCHED || this.topPocketState === TopPocketState.STATE_PULLED) { this.releaseState() } } releaseState() { this.set_topPocketState(() => TopPocketState.STATE_RELEASED); this.set_pullDownOpacity(() => 0) } get refreshStrategy() { return "android" === this.platform ? "swipeDown" : "pullDown" } get isSwipeDownStrategy() { return "swipeDown" === this.refreshStrategy } get isPullDownStrategy() { return "pullDown" === this.refreshStrategy } isSwipeDown() { return this.pullDownEnabled && this.topPocketState === TopPocketState.STATE_PULLED && this.deltaY >= this.getPullDownHeight() - this.getPullDownStartPosition() } isPullDown() { return this.pullDownEnabled && this.scrollLocation().top <= -this.topPocketHeight } isReachBottom() { var { top: top } = this.scrollLocation(); return this.props.reachBottomEnabled && isReachedBottom(this.containerRef.current, top, this.bottomPocketHeight) } get bottomPocketHeight() { if (this.props.reachBottomEnabled && this.bottomPocketRef.current) { return this.bottomPocketRef.current.clientHeight } return 0 } tryGetAllowedDirection() { var { isBoth: isBoth, isHorizontal: isHorizontal, isVertical: isVertical } = new ScrollDirection(this.props.direction); var contentEl = this.contentRef.current; var containerEl = this.containerRef.current; var isOverflowVertical = isVertical && contentEl.clientHeight > containerEl.clientHeight || this.pullDownEnabled; var isOverflowHorizontal = isHorizontal && contentEl.clientWidth > containerEl.clientWidth || this.pullDownEnabled; if (isBoth && isOverflowVertical && isOverflowHorizontal) { return DIRECTION_BOTH } if (isHorizontal && isOverflowHorizontal) { return DIRECTION_HORIZONTAL } if (isVertical && isOverflowVertical) { return DIRECTION_VERTICAL } return } isLocked() { return this.locked } isScrollingOutOfBound(e) { var { delta: delta, shiftKey: shiftKey } = e; var { clientHeight: clientHeight, clientWidth: clientWidth, scrollHeight: scrollHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: scrollWidth } = this.containerRef.current; if (delta > 0) { return shiftKey ? !scrollLeft : !scrollTop } return shiftKey ? clientWidth >= scrollWidth - scrollLeft : clientHeight >= scrollHeight - scrollTop } get cssClasses() { var { classes: classes, direction: direction, disabled: disabled, showScrollbar: showScrollbar } = this.props; var classesMap = { ["dx-scrollable dx-scrollable-native dx-scrollable-native-".concat(this.platform, " dx-scrollable-renovated")]: true, ["dx-scrollable-".concat(direction)]: true, [SCROLLABLE_DISABLED_CLASS]: !!disabled, [SCROLLABLE_SCROLLBAR_SIMULATED]: showScrollbar && this.useSimulatedScrollbar, [SCROLLABLE_SCROLLBARS_HIDDEN]: !showScrollbar, ["".concat(classes)]: !!classes }; return combineClasses(classesMap) } get platform() { return devices.real().platform } get direction() { return new ScrollDirection(this.props.direction) } get useSimulatedScrollbar() { if (!isDefined(this.props.useSimulatedScrollbar)) { return nativeScrolling && "android" === this.platform && !browser.mozilla } return this.props.useSimulatedScrollbar } get pullDownEnabled() { return this.props.pullDownEnabled && "generic" !== this.platform } get contentStyles() { if (this.props.forceGeneratePockets && this.isPullDownStrategy) { return { transform: "translate(0px, ".concat(this.contentTranslateTop, "px)") } } return } get restAttributes() { var _this$props5 = this.props, restProps = _objectWithoutPropertiesLoose(_this$props5, _excluded); return restProps } content() { if (this.props.needScrollViewContentWrapper) { return this.scrollViewContentRef.current } return this.contentRef.current } update() { if (!this.props.updateManually) { this.updateSizes(); this.onUpdated() } } refresh() { this.set_topPocketState(() => TopPocketState.STATE_READY); this.startLoading(); this.onPullDown() } release() { this.clearReleaseTimeout(); if (this.isPullDownStrategy) { if (this.topPocketState === TopPocketState.STATE_LOADING) { this.set_topPocketState(() => TopPocketState.STATE_RELEASED) } } this.releaseTimeout = setTimeout(() => { if (this.isPullDownStrategy) { this.set_contentTranslateTop(() => 0) } this.stateReleased(); this.onRelease() }, this.isSwipeDownStrategy ? 800 : 400) } scrollTo(targetLocation) { var { direction: direction } = this.props; var distance = getOffsetDistance(targetLocation, direction, this.scrollOffset()); this.scrollBy(distance) } scrollBy(distance) { var location = getAugmentedLocation(distance); if (!location.top && !location.left) { return } var containerEl = this.containerRef.current; if (this.direction.isVertical) { containerEl.scrollTop += location.top } if (this.direction.isHorizontal) { containerEl.scrollLeft += getScrollSign(!!this.props.rtlEnabled) * location.left } } scrollToElement(element) { if (!isDefined(element)) { return } var { left: left, top: top } = this.scrollOffset(); element.scrollIntoView({ block: "nearest", inline: "nearest" }); var distance = getOffsetDistance({ top: top, left: left }, this.props.direction, this.scrollOffset()); var containerEl = this.containerRef.current; if (!this.direction.isHorizontal) { containerEl.scrollLeft += getScrollSign(!!this.props.rtlEnabled) * distance.left } if (!this.direction.isVertical) { containerEl.scrollTop += distance.top } } getElementLocation(element, direction, offset) { var scrollOffset = _extends({ top: 0, left: 0, right: 0, bottom: 0 }, offset); return getLocation(element, scrollOffset, direction, this.containerRef.current) } scrollHeight() { return this.content().offsetHeight } scrollWidth() { return this.content().offsetWidth } scrollOffset() { var { left: left, top: top } = this.scrollLocation(); var scrollLeftMax = getScrollLeftMax(this.containerRef.current); return { top: top, left: normalizeOffsetLeft(left, scrollLeftMax, !!this.props.rtlEnabled) } } scrollTop() { return this.scrollOffset().top } scrollLeft() { return this.scrollOffset().left } clientHeight() { return this.containerRef.current.clientHeight } clientWidth() { return this.containerRef.current.clientWidth } validate(e) { var { disabled: disabled } = this.props; if (this.isLocked()) { return false } this.update(); if (disabled || isDxMouseWheelEvent(e) && this.isScrollingOutOfBound(e)) { return false } return isDefined(this.tryGetAllowedDirection()) } render() { var props = this.props; return viewFunction({ props: _extends({}, props), containerClientWidth: this.containerClientWidth, containerClientHeight: this.containerClientHeight, contentClientWidth: this.contentClientWidth, contentClientHeight: this.contentClientHeight, needForceScrollbarsVisibility: this.needForceScrollbarsVisibility, topPocketState: this.topPocketState, isLoadPanelVisible: this.isLoadPanelVisible, pullDownTranslateTop: this.pullDownTranslateTop, pullDownIconAngle: this.pullDownIconAngle, pullDownOpacity: this.pullDownOpacity, topPocketTop: this.topPocketTop, contentTranslateTop: this.contentTranslateTop, vScrollLocation: this.vScrollLocation, hScrollLocation: this.hScrollLocation, scrollableRef: this.scrollableRef, wrapperRef: this.wrapperRef, contentRef: this.contentRef, scrollViewContentRef: this.scrollViewContentRef, containerRef: this.containerRef, topPocketRef: this.topPocketRef, bottomPocketRef: this.bottomPocketRef, vScrollbarRef: this.vScrollbarRef, hScrollbarRef: this.hScrollbarRef, clearReleaseTimeout: this.clearReleaseTimeout, onRelease: this.onRelease, onUpdated: this.onUpdated, startLoading: this.startLoading, finishLoading: this.finishLoading, handleScroll: this.handleScroll, handlePocketState: this.handlePocketState, pullDownReady: this.pullDownReady, onReachBottom: this.onReachBottom, onPullDown: this.onPullDown, stateReleased: this.stateReleased, getEventArgs: this.getEventArgs, lock: this.lock, unlock: this.unlock, fullScrollInactiveProp: this.fullScrollInactiveProp, windowResizeHandler: this.windowResizeHandler, updateSizes: this.updateSizes, moveScrollbars: this.moveScrollbars, clearHideScrollbarTimeout: this.clearHideScrollbarTimeout, scrollLocation: this.scrollLocation, getInitEventData: this.getInitEventData, handleInit: this.handleInit, handleMove: this.handleMove, handleEnd: this.handleEnd, handleStop: this.handleStop, pullDownComplete: this.pullDownComplete, clearRefreshTimeout: this.clearRefreshTimeout, topPocketHeight: this.topPocketHeight, pullDownRefreshing: this.pullDownRefreshing, movePullDown: this.movePullDown, getPullDownHeight: this.getPullDownHeight, getPullDownStartPosition: this.getPullDownStartPosition, complete: this.complete, releaseState: this.releaseState, refreshStrategy: this.refreshStrategy, isSwipeDownStrategy: this.isSwipeDownStrategy, isPullDownStrategy: this.isPullDownStrategy, isSwipeDown: this.isSwipeDown, isPullDown: this.isPullDown, isReachBottom: this.isReachBottom, bottomPocketHeight: this.bottomPocketHeight, tryGetAllowedDirection: this.tryGetAllowedDirection, isLocked: this.isLocked, isScrollingOutOfBound: this.isScrollingOutOfBound, cssClasses: this.cssClasses, platform: this.platform, direction: this.direction, useSimulatedScrollbar: this.useSimulatedScrollbar, pullDownEnabled: this.pullDownEnabled, contentStyles: this.contentStyles, restAttributes: this.restAttributes }) } } ScrollableNative.defaultProps = _extends({}, ScrollableNativePropsType);