UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

957 lines (956 loc) • 41.8 kB
/** * DevExtreme (esm/renovation/ui/scroll_view/strategy/native.js) * Version: 22.1.9 * Build date: Tue Apr 18 2023 * * Copyright (c) 2012 - 2023 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 = ["addWidgetClass", "aria", "bounceEnabled", "children", "classes", "direction", "disabled", "forceGeneratePockets", "height", "loadPanelTemplate", "needRenderScrollbars", "needScrollViewContentWrapper", "onPullDown", "onReachBottom", "onScroll", "onUpdated", "pullDownEnabled", "pulledDownText", "pullingDownText", "reachBottomEnabled", "reachBottomText", "refreshStrategy", "refreshingText", "rtlEnabled", "scrollByContent", "showScrollbar", "useSimulatedScrollbar", "visible", "width"]; import { createVNode, createComponentVNode, normalizeProps } from "inferno"; import { InfernoEffect, InfernoComponent } from "@devextreme/runtime/inferno"; import { normalizeStyles } from "@devextreme/runtime/inferno"; import "../../../../events/gesture/emitter.gesture.scroll"; import { subscribeToScrollEvent, subscribeToScrollInitEvent, subscribeToDXScrollEndEvent, subscribeToDXScrollMoveEvent, subscribeToDXScrollStopEvent } from "../../../utils/subscribe_to_event"; import { Widget } from "../../common/widget"; import { combineClasses } from "../../../utils/combine_classes"; import { getScrollLeftMax } from "../utils/get_scroll_left_max"; import { getBoundaryProps } from "../utils/get_boundary_props"; import { normalizeOffsetLeft } from "../utils/normalize_offset_left"; import { getElementOverflowX, getElementOverflowY } from "../utils/get_element_style"; import devices from "../../../../core/devices"; import { isDefined } from "../../../../core/utils/type"; import { TopPocket } from "../internal/pocket/top"; import { BottomPocket } from "../internal/pocket/bottom"; import { isDxMouseWheelEvent } from "../../../../events/utils/index"; import { ScrollDirection } from "../utils/scroll_direction"; import { 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/scrollbar"; import { isElementVisible } from "../utils/is_element_visible"; import { ScrollableNativeProps } from "../common/native_strategy_props"; import { allowedDirection } from "../utils/get_allowed_direction"; import { getScrollTopMax } from "../utils/get_scroll_top_max"; import { subscribeToResize } from "../utils/subscribe_to_resize"; export var viewFunction = viewModel => { var { bottomPocketRef: bottomPocketRef, containerClientHeight: containerClientHeight, containerClientWidth: containerClientWidth, containerRef: containerRef, contentHeight: contentHeight, contentRef: contentRef, contentStyles: contentStyles, contentTranslateTop: contentTranslateTop, contentWidth: contentWidth, cssClasses: cssClasses, direction: direction, hScrollLocation: hScrollLocation, hScrollOffsetMax: hScrollOffsetMax, hScrollbarRef: hScrollbarRef, isLoadPanelVisible: isLoadPanelVisible, props: { aria: aria, children: children, disabled: disabled, forceGeneratePockets: forceGeneratePockets, height: height, loadPanelTemplate: LoadPanelTemplate, needRenderScrollbars: needRenderScrollbars, needScrollViewContentWrapper: needScrollViewContentWrapper, pullDownEnabled: pullDownEnabled, pulledDownText: pulledDownText, pullingDownText: pullingDownText, reachBottomEnabled: reachBottomEnabled, reachBottomText: reachBottomText, refreshStrategy: refreshStrategy, refreshingText: refreshingText, rtlEnabled: rtlEnabled, showScrollbar: showScrollbar, useSimulatedScrollbar: useSimulatedScrollbar, visible: visible, width: width }, pullDownIconAngle: pullDownIconAngle, pullDownOpacity: pullDownOpacity, pullDownTranslateTop: pullDownTranslateTop, restAttributes: restAttributes, scrollViewContentRef: scrollViewContentRef, scrollableRef: scrollableRef, scrolling: scrolling, topPocketHeight: topPocketHeight, topPocketRef: topPocketRef, topPocketState: topPocketState, vScrollLocation: vScrollLocation, vScrollOffsetMax: vScrollOffsetMax, vScrollbarRef: vScrollbarRef, wrapperRef: wrapperRef } = viewModel; return normalizeProps(createComponentVNode(2, Widget, _extends({ rootElementRef: scrollableRef, aria: aria, addWidgetClass: false, classes: cssClasses, disabled: disabled, rtlEnabled: rtlEnabled, height: height, width: width, visible: visible }, 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: topPocketHeight, visible: !!pullDownEnabled }), needScrollViewContentWrapper ? createVNode(1, "div", SCROLLVIEW_CONTENT_CLASS, children, 0, { style: normalizeStyles(contentStyles) }, null, scrollViewContentRef) : children, forceGeneratePockets && createComponentVNode(2, BottomPocket, { bottomPocketRef: bottomPocketRef, reachBottomText: reachBottomText, visible: !!reachBottomEnabled })], 0, null, null, contentRef), 2, null, null, containerRef), 2, null, null, wrapperRef), viewModel.props.loadPanelTemplate && LoadPanelTemplate({ targetElement: scrollableRef, refreshingText: refreshingText, visible: isLoadPanelVisible }), needRenderScrollbars && "never" !== showScrollbar && useSimulatedScrollbar && direction.isHorizontal && createComponentVNode(2, Scrollbar, { direction: "horizontal", showScrollbar: "onScroll", contentSize: contentWidth, containerSize: containerClientWidth, maxOffset: hScrollOffsetMax, scrollLocation: hScrollLocation, visible: scrolling }, null, hScrollbarRef), needRenderScrollbars && "never" !== showScrollbar && useSimulatedScrollbar && direction.isVertical && createComponentVNode(2, Scrollbar, { direction: "vertical", showScrollbar: "onScroll", contentSize: contentHeight, containerSize: containerClientHeight, maxOffset: vScrollOffsetMax, scrollLocation: vScrollLocation, visible: scrolling }, null, vScrollbarRef)] }))) }; import { createRef as infernoCreateRef } from "inferno"; var getTemplate = TemplateProp => TemplateProp && (TemplateProp.defaultProps ? props => normalizeProps(createComponentVNode(2, TemplateProp, _extends({}, props))) : TemplateProp); export class ScrollableNative extends InfernoComponent { constructor(props) { super(props); this.scrollableRef = infernoCreateRef(); this.topPocketRef = infernoCreateRef(); this.bottomPocketRef = infernoCreateRef(); this.wrapperRef = infernoCreateRef(); this.contentRef = infernoCreateRef(); this.scrollViewContentRef = infernoCreateRef(); this.containerRef = infernoCreateRef(); this.vScrollbarRef = infernoCreateRef(); this.hScrollbarRef = infernoCreateRef(); this.locked = false; this.loadingIndicatorEnabled = true; this.initPageY = 0; this.deltaY = 0; this.locationTop = 0; this.__getterCache = {}; this.state = { containerClientWidth: 0, containerClientHeight: 0, contentClientWidth: 0, contentClientHeight: 0, contentScrollWidth: 0, contentScrollHeight: 0, topPocketHeight: 0, bottomPocketHeight: 0, scrolling: false, topPocketState: TopPocketState.STATE_RELEASED, isLoadPanelVisible: false, pullDownTranslateTop: 0, pullDownIconAngle: 0, pullDownOpacity: 0, contentTranslateTop: 0, vScrollLocation: 0, hScrollLocation: 0 }; this.content = this.content.bind(this); this.container = this.container.bind(this); this.refresh = this.refresh.bind(this); this.release = this.release.bind(this); this.disposeReleaseTimer = this.disposeReleaseTimer.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.effectDisabledState = this.effectDisabledState.bind(this); this.resetInactiveOffsetToInitial = this.resetInactiveOffsetToInitial.bind(this); this.initEffect = this.initEffect.bind(this); this.moveEffect = this.moveEffect.bind(this); this.endEffect = this.endEffect.bind(this); this.stopEffect = this.stopEffect.bind(this); this.disposeRefreshTimer = this.disposeRefreshTimer.bind(this); this.validate = this.validate.bind(this); this.moveIsAllowed = this.moveIsAllowed.bind(this); this.updateHandler = this.updateHandler.bind(this); this.updateDimensions = this.updateDimensions.bind(this); this.subscribeContainerToResize = this.subscribeContainerToResize.bind(this); this.subscribeContentToResize = this.subscribeContentToResize.bind(this); this.scrollByLocation = this.scrollByLocation.bind(this); this.clearReleaseTimer = this.clearReleaseTimer.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.setPocketState = this.setPocketState.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.lock = this.lock.bind(this); this.unlock = this.unlock.bind(this); this.updateElementDimensions = this.updateElementDimensions.bind(this); this.setContainerDimensions = this.setContainerDimensions.bind(this); this.setContentHeight = this.setContentHeight.bind(this); this.setContentWidth = this.setContentWidth.bind(this); this.syncScrollbarsWithContent = this.syncScrollbarsWithContent.bind(this); this.getInitEventData = this.getInitEventData.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.clearRefreshTimer = this.clearRefreshTimer.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.pulledDown = this.pulledDown.bind(this); this.isReachBottom = this.isReachBottom.bind(this); this.tryGetAllowedDirection = this.tryGetAllowedDirection.bind(this); this.isLocked = this.isLocked.bind(this); this.isScrollingOutOfBound = this.isScrollingOutOfBound.bind(this) } createEffects() { return [new InfernoEffect(this.disposeReleaseTimer, []), new InfernoEffect(this.scrollEffect, [this.props.useSimulatedScrollbar, this.props.onScroll, this.props.rtlEnabled, this.props.direction, this.props.forceGeneratePockets, this.state.topPocketState, this.props.refreshStrategy, this.props.reachBottomEnabled, this.state.contentClientHeight, this.state.contentScrollHeight, this.state.containerClientHeight, this.props.onReachBottom, this.props.pullDownEnabled, this.state.topPocketHeight]), new InfernoEffect(this.effectDisabledState, [this.props.disabled]), new InfernoEffect(this.resetInactiveOffsetToInitial, [this.props.direction]), new InfernoEffect(this.initEffect, [this.props.forceGeneratePockets, this.props.refreshStrategy, this.state.topPocketState, this.props.direction, this.props.disabled]), new InfernoEffect(this.moveEffect, [this.props.direction, this.props.forceGeneratePockets, this.props.refreshStrategy, this.state.topPocketState, this.props.pullDownEnabled, this.state.topPocketHeight]), new InfernoEffect(this.endEffect, [this.props.forceGeneratePockets, this.props.refreshStrategy, this.props.pullDownEnabled, this.state.topPocketState, this.state.topPocketHeight, this.props.onPullDown]), new InfernoEffect(this.stopEffect, [this.props.forceGeneratePockets, this.props.refreshStrategy, this.state.topPocketState, this.state.topPocketHeight, this.props.onPullDown]), new InfernoEffect(this.disposeRefreshTimer, []), new InfernoEffect(this.updateDimensions, []), new InfernoEffect(this.subscribeContainerToResize, []), new InfernoEffect(this.subscribeContentToResize, [])] } updateEffects() { var _this$_effects$, _this$_effects$2, _this$_effects$3, _this$_effects$4, _this$_effects$5, _this$_effects$6, _this$_effects$7; 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.state.topPocketState, this.props.refreshStrategy, this.props.reachBottomEnabled, this.state.contentClientHeight, this.state.contentScrollHeight, this.state.containerClientHeight, this.props.onReachBottom, this.props.pullDownEnabled, this.state.topPocketHeight]); 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.props.forceGeneratePockets, this.props.refreshStrategy, this.state.topPocketState, this.props.direction, this.props.disabled]); null === (_this$_effects$5 = this._effects[5]) || void 0 === _this$_effects$5 ? void 0 : _this$_effects$5.update([this.props.direction, this.props.forceGeneratePockets, this.props.refreshStrategy, this.state.topPocketState, this.props.pullDownEnabled, this.state.topPocketHeight]); null === (_this$_effects$6 = this._effects[6]) || void 0 === _this$_effects$6 ? void 0 : _this$_effects$6.update([this.props.forceGeneratePockets, this.props.refreshStrategy, this.props.pullDownEnabled, this.state.topPocketState, this.state.topPocketHeight, this.props.onPullDown]); null === (_this$_effects$7 = this._effects[7]) || void 0 === _this$_effects$7 ? void 0 : _this$_effects$7.update([this.props.forceGeneratePockets, this.props.refreshStrategy, this.state.topPocketState, this.state.topPocketHeight, this.props.onPullDown]) } disposeReleaseTimer() { return () => this.clearReleaseTimer() } scrollEffect() { return subscribeToScrollEvent(this.containerRef.current, event => { this.handleScroll(event) }) } effectDisabledState() { if (this.props.disabled) { this.lock() } else { this.unlock() } } resetInactiveOffsetToInitial() { if (this.props.direction === DIRECTION_BOTH) { return } this.containerRef.current[this.fullScrollInactiveProp] = 0 } initEffect() { return subscribeToScrollInitEvent(this.wrapperRef.current, event => { this.handleInit(event) }, this.getInitEventData()) } moveEffect() { return subscribeToDXScrollMoveEvent(this.wrapperRef.current, event => { this.handleMove(event) }) } endEffect() { return subscribeToDXScrollEndEvent(this.wrapperRef.current, () => { this.handleEnd() }) } stopEffect() { return subscribeToDXScrollStopEvent(this.wrapperRef.current, () => { this.handleStop() }) } disposeRefreshTimer() { return () => this.clearRefreshTimer() } updateDimensions() { this.updateElementDimensions() } subscribeContainerToResize() { return subscribeToResize(this.containerRef.current, element => { this.setContainerDimensions(element) }) } subscribeContentToResize() { return subscribeToResize(this.content(), element => { this.setContentHeight(element); this.setContentWidth(element) }) } clearReleaseTimer() { clearTimeout(this.releaseTimer); this.releaseTimer = void 0 } onRelease() { this.loadingIndicatorEnabled = true; this.finishLoading() } 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 && isElementVisible(this.scrollableRef.current)) { this.setState(__state_argument => ({ isLoadPanelVisible: true })) } this.lock() } finishLoading() { this.setState(__state_argument => ({ isLoadPanelVisible: false })); this.unlock() } setPocketState(newState) { this.setState(__state_argument => ({ topPocketState: newState })) } handleScroll(event) { var _this$props$onScroll, _this$props2; this.eventForUserAction = event; if (this.props.useSimulatedScrollbar) { this.setState(__state_argument => ({ scrolling: true })); this.syncScrollbarsWithContent(); this.setState(__state_argument => ({ scrolling: false })) } 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.handlePocketState() } handlePocketState() { if (this.props.forceGeneratePockets) { if (this.state.topPocketState === TopPocketState.STATE_REFRESHING) { return } var { scrollTop: scrollTop } = this.containerRef.current; var scrollDelta = this.locationTop + scrollTop; this.locationTop = -scrollTop; if (this.isSwipeDownStrategy && scrollDelta > 0 && this.isReachBottom()) { this.onReachBottom(); return } if (this.isPullDownStrategy) { if (this.pulledDown()) { this.pullDownReady(); return } if (scrollDelta > 0 && this.isReachBottom()) { if (this.state.topPocketState !== TopPocketState.STATE_LOADING) { this.setPocketState(TopPocketState.STATE_LOADING); this.onReachBottom() } return } } this.stateReleased() } } pullDownReady() { if (this.state.topPocketState === TopPocketState.STATE_READY) { return } this.setPocketState(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.state.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)) } lock() { this.locked = true } unlock() { if (!this.props.disabled) { this.locked = false } } get fullScrollInactiveProp() { return this.props.direction === DIRECTION_HORIZONTAL ? "scrollTop" : "scrollLeft" } updateElementDimensions() { this.setContentHeight(this.content()); this.setContentWidth(this.content()); this.setContainerDimensions(this.containerRef.current) } setContainerDimensions(containerEl) { this.setState(__state_argument => ({ containerClientWidth: containerEl.clientWidth })); this.setState(__state_argument => ({ containerClientHeight: containerEl.clientHeight })) } setContentHeight(contentEl) { this.setState(__state_argument => ({ contentClientHeight: contentEl.clientHeight })); this.setState(__state_argument => ({ contentScrollHeight: contentEl.scrollHeight })); if (this.props.forceGeneratePockets) { this.setState(__state_argument => { var _this$topPocketRef; return { topPocketHeight: (null === (_this$topPocketRef = this.topPocketRef) || void 0 === _this$topPocketRef ? void 0 : _this$topPocketRef.current.clientHeight) || 0 } }); this.setState(__state_argument => { var _this$bottomPocketRef; return { bottomPocketHeight: (null === (_this$bottomPocketRef = this.bottomPocketRef) || void 0 === _this$bottomPocketRef ? void 0 : _this$bottomPocketRef.current.clientHeight) || 0 } }) } } setContentWidth(contentEl) { this.setState(__state_argument => ({ contentClientWidth: contentEl.clientWidth })); this.setState(__state_argument => ({ contentScrollWidth: contentEl.scrollWidth })) } syncScrollbarsWithContent() { var { left: left, top: top } = this.scrollOffset(); this.setState(__state_argument => ({ hScrollLocation: -left })); this.setState(__state_argument => ({ vScrollLocation: -top })) } getInitEventData() { return { getDirection: () => this.tryGetAllowedDirection(), validate: event => this.validate(event), isNative: true, scrollTarget: this.containerRef.current } } handleInit(event) { if (this.props.forceGeneratePockets && this.isSwipeDownStrategy) { var { scrollTop: scrollTop } = this.containerRef.current; if (this.state.topPocketState === TopPocketState.STATE_RELEASED && 0 === scrollTop) { this.initPageY = event.originalEvent.pageY; this.setPocketState(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.state.topPocketState === TopPocketState.STATE_TOUCHED) { if (this.pullDownEnabled && this.deltaY > 0) { this.setPocketState(TopPocketState.STATE_PULLED) } else { this.complete() } } if (this.state.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.state.topPocketState === TopPocketState.STATE_READY) { this.setState(__state_argument => ({ contentTranslateTop: this.state.topPocketHeight })); this.clearRefreshTimer(); this.refreshTimer = setTimeout(() => { this.pullDownRefreshing() }, 400) } } clearRefreshTimer() { clearTimeout(this.refreshTimer); this.refreshTimer = void 0 } pullDownRefreshing() { if (this.state.topPocketState === TopPocketState.STATE_REFRESHING) { return } this.setPocketState(TopPocketState.STATE_REFRESHING); if (this.isSwipeDownStrategy) { this.setState(__state_argument => ({ 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.setState(__state_argument => ({ pullDownOpacity: 1 })); this.setState(__state_argument => ({ pullDownTranslateTop: top })); this.setState(__state_argument => ({ pullDownIconAngle: angle })) } getPullDownHeight() { return Math.round(.05 * this.scrollableRef.current.offsetHeight) } getPullDownStartPosition() { return -Math.round(1.5 * this.state.topPocketHeight) } complete() { if (this.state.topPocketState === TopPocketState.STATE_TOUCHED || this.state.topPocketState === TopPocketState.STATE_PULLED) { this.releaseState() } } releaseState() { this.setPocketState(TopPocketState.STATE_RELEASED); this.setState(__state_argument => ({ pullDownOpacity: 0 })) } get isSwipeDownStrategy() { return "swipeDown" === this.props.refreshStrategy } get isPullDownStrategy() { return "pullDown" === this.props.refreshStrategy } isSwipeDown() { return this.pullDownEnabled && this.state.topPocketState === TopPocketState.STATE_PULLED && this.deltaY >= this.getPullDownHeight() - this.getPullDownStartPosition() } pulledDown() { var { scrollTop: scrollTop } = this.containerRef.current; return this.pullDownEnabled && scrollTop <= -this.state.topPocketHeight } isReachBottom() { var { scrollTop: scrollTop } = this.containerRef.current; return this.props.reachBottomEnabled && Math.round(-scrollTop - this.vScrollOffsetMax) <= 1 } tryGetAllowedDirection() { var containerEl = this.containerRef.current; return allowedDirection(this.props.direction, getScrollTopMax(containerEl), getScrollLeftMax(containerEl), false) } isLocked() { return this.locked } isScrollingOutOfBound(event) { var { delta: delta, shiftKey: shiftKey } = event; 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(devices.real().platform)]: true, ["dx-scrollable-".concat(direction)]: true, [SCROLLABLE_DISABLED_CLASS]: !!disabled, [SCROLLABLE_SCROLLBAR_SIMULATED]: "never" !== showScrollbar && this.props.useSimulatedScrollbar, [SCROLLABLE_SCROLLBARS_HIDDEN]: "never" === showScrollbar, [String(classes)]: !!classes }; return combineClasses(classesMap) } get direction() { if (void 0 !== this.__getterCache.direction) { return this.__getterCache.direction } return this.__getterCache.direction = (() => new ScrollDirection(this.props.direction))() } get pullDownEnabled() { return this.props.pullDownEnabled && "generic" !== devices.real().platform } get contentStyles() { if (void 0 !== this.__getterCache.contentStyles) { return this.__getterCache.contentStyles } return this.__getterCache.contentStyles = (() => { if (this.props.forceGeneratePockets && this.isPullDownStrategy) { return { transform: "translate(0px, ".concat(this.state.contentTranslateTop, "px)") } } return })() } get contentHeight() { var _this$contentRef; return "hidden" === getElementOverflowY(null === (_this$contentRef = this.contentRef) || void 0 === _this$contentRef ? void 0 : _this$contentRef.current) ? this.state.contentClientHeight : Math.max(this.state.contentScrollHeight, this.state.contentClientHeight) } get contentWidth() { var _this$contentRef2; return "hidden" === getElementOverflowX(null === (_this$contentRef2 = this.contentRef) || void 0 === _this$contentRef2 ? void 0 : _this$contentRef2.current) ? this.state.contentClientWidth : Math.max(this.state.contentScrollWidth, this.state.contentClientWidth) } get hScrollOffsetMax() { return -Math.max(this.contentWidth - this.state.containerClientWidth, 0) } get vScrollOffsetMax() { return -Math.max(this.contentHeight - this.state.containerClientHeight, 0) } 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 } container() { return this.containerRef.current } refresh() { this.setPocketState(TopPocketState.STATE_READY); this.startLoading(); this.onPullDown() } release() { this.clearReleaseTimer(); if (this.isPullDownStrategy) { if (this.state.topPocketState === TopPocketState.STATE_LOADING) { this.setPocketState(TopPocketState.STATE_RELEASED) } } this.releaseTimer = setTimeout(() => { if (this.isPullDownStrategy) { this.setState(__state_argument => ({ contentTranslateTop: 0 })) } this.stateReleased(); this.onRelease() }, this.isSwipeDownStrategy ? 800 : 400) } scrollHeight() { return this.content().offsetHeight } scrollWidth() { return this.content().offsetWidth } scrollOffset() { return { top: this.scrollTop(), left: this.scrollLeft() } } scrollTop() { return this.containerRef.current.scrollTop } scrollLeft() { var containerEl = this.containerRef.current; var scrollLeftMax = getScrollLeftMax(containerEl); return normalizeOffsetLeft(containerEl.scrollLeft, scrollLeftMax, !!this.props.rtlEnabled) } clientHeight() { return this.containerRef.current.clientHeight } clientWidth() { return this.containerRef.current.clientWidth } validate(event) { if (this.isLocked()) { return false } return this.moveIsAllowed(event) } moveIsAllowed(event) { if (this.props.disabled || isDxMouseWheelEvent(event) && this.isScrollingOutOfBound(event)) { return false } return isDefined(this.tryGetAllowedDirection()) } updateHandler() { this.updateElementDimensions(); this.onUpdated() } scrollByLocation(location) { var containerEl = this.containerRef.current; if (this.direction.isVertical) { containerEl.scrollTop += location.top } if (this.direction.isHorizontal) { containerEl.scrollLeft += location.left } } componentWillUpdate(nextProps, nextState, context) { super.componentWillUpdate(); if (this.props.direction !== nextProps.direction) { this.__getterCache.direction = void 0 } if (this.props.forceGeneratePockets !== nextProps.forceGeneratePockets || this.props.refreshStrategy !== nextProps.refreshStrategy || this.state.contentTranslateTop !== nextState.contentTranslateTop) { this.__getterCache.contentStyles = void 0 } } render() { var props = this.props; return viewFunction({ props: _extends({}, props, { loadPanelTemplate: getTemplate(props.loadPanelTemplate) }), containerClientWidth: this.state.containerClientWidth, containerClientHeight: this.state.containerClientHeight, contentClientWidth: this.state.contentClientWidth, contentClientHeight: this.state.contentClientHeight, contentScrollWidth: this.state.contentScrollWidth, contentScrollHeight: this.state.contentScrollHeight, topPocketHeight: this.state.topPocketHeight, bottomPocketHeight: this.state.bottomPocketHeight, scrolling: this.state.scrolling, topPocketState: this.state.topPocketState, isLoadPanelVisible: this.state.isLoadPanelVisible, pullDownTranslateTop: this.state.pullDownTranslateTop, pullDownIconAngle: this.state.pullDownIconAngle, pullDownOpacity: this.state.pullDownOpacity, contentTranslateTop: this.state.contentTranslateTop, vScrollLocation: this.state.vScrollLocation, hScrollLocation: this.state.hScrollLocation, wrapperRef: this.wrapperRef, contentRef: this.contentRef, scrollViewContentRef: this.scrollViewContentRef, containerRef: this.containerRef, scrollableRef: this.scrollableRef, topPocketRef: this.topPocketRef, bottomPocketRef: this.bottomPocketRef, vScrollbarRef: this.vScrollbarRef, hScrollbarRef: this.hScrollbarRef, clearReleaseTimer: this.clearReleaseTimer, onRelease: this.onRelease, onUpdated: this.onUpdated, startLoading: this.startLoading, finishLoading: this.finishLoading, setPocketState: this.setPocketState, 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, updateElementDimensions: this.updateElementDimensions, setContainerDimensions: this.setContainerDimensions, setContentHeight: this.setContentHeight, setContentWidth: this.setContentWidth, syncScrollbarsWithContent: this.syncScrollbarsWithContent, getInitEventData: this.getInitEventData, handleInit: this.handleInit, handleMove: this.handleMove, handleEnd: this.handleEnd, handleStop: this.handleStop, pullDownComplete: this.pullDownComplete, clearRefreshTimer: this.clearRefreshTimer, pullDownRefreshing: this.pullDownRefreshing, movePullDown: this.movePullDown, getPullDownHeight: this.getPullDownHeight, getPullDownStartPosition: this.getPullDownStartPosition, complete: this.complete, releaseState: this.releaseState, isSwipeDownStrategy: this.isSwipeDownStrategy, isPullDownStrategy: this.isPullDownStrategy, isSwipeDown: this.isSwipeDown, pulledDown: this.pulledDown, isReachBottom: this.isReachBottom, tryGetAllowedDirection: this.tryGetAllowedDirection, isLocked: this.isLocked, isScrollingOutOfBound: this.isScrollingOutOfBound, cssClasses: this.cssClasses, direction: this.direction, pullDownEnabled: this.pullDownEnabled, contentStyles: this.contentStyles, contentHeight: this.contentHeight, contentWidth: this.contentWidth, hScrollOffsetMax: this.hScrollOffsetMax, vScrollOffsetMax: this.vScrollOffsetMax, restAttributes: this.restAttributes }) } } ScrollableNative.defaultProps = ScrollableNativeProps;