UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

537 lines (534 loc) • 21.1 kB
/** * DevExtreme (cjs/__internal/ui/drawer/m_drawer.js) * Version: 24.2.6 * Build date: Mon Mar 17 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _animation = require("../../../common/core/animation"); var _click = require("../../../common/core/events/click"); var _events_engine = _interopRequireDefault(require("../../../common/core/events/core/events_engine")); var _visibility_change = require("../../../common/core/events/visibility_change"); var _component_registrator = _interopRequireDefault(require("../../../core/component_registrator")); var _element = require("../../../core/element"); var _renderer = _interopRequireDefault(require("../../../core/renderer")); var _empty_template = require("../../../core/templates/empty_template"); var _deferred = require("../../../core/utils/deferred"); var _position = require("../../../core/utils/position"); var _type = require("../../../core/utils/type"); var _window = require("../../../core/utils/window"); var _widget = _interopRequireDefault(require("../../core/widget/widget")); var _m_drawer = require("../../ui/drawer/m_drawer.animation"); var _m_drawerRenderingStrategy = _interopRequireDefault(require("../../ui/drawer/m_drawer.rendering.strategy.overlap")); var _m_drawerRenderingStrategy2 = _interopRequireDefault(require("../../ui/drawer/m_drawer.rendering.strategy.push")); var _m_drawerRenderingStrategy3 = _interopRequireDefault(require("../../ui/drawer/m_drawer.rendering.strategy.shrink")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function(n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]) } } return n }, _extends.apply(null, arguments) } const DRAWER_CLASS = "dx-drawer"; const DRAWER_WRAPPER_CLASS = "dx-drawer-wrapper"; const DRAWER_PANEL_CONTENT_CLASS = "dx-drawer-panel-content"; const DRAWER_PANEL_CONTENT_HIDDEN_CLASS = "dx-drawer-panel-content-hidden"; const DRAWER_VIEW_CONTENT_CLASS = "dx-drawer-content"; const DRAWER_SHADER_CLASS = "dx-drawer-shader"; const INVISIBLE_STATE_CLASS = "dx-state-invisible"; const OPENED_STATE_CLASS = "dx-drawer-opened"; const ANONYMOUS_TEMPLATE_NAME = "content"; const PANEL_TEMPLATE_NAME = "panel"; class Drawer extends _widget.default { _getDefaultOptions() { return _extends({}, super._getDefaultOptions(), { position: "left", opened: false, minSize: null, maxSize: null, shading: false, template: "panel", openedStateMode: "shrink", revealMode: "slide", animationEnabled: true, animationDuration: 400, closeOnOutsideClick: false, contentTemplate: "content" }) } _init() { super._init(); this._initStrategy(); this.$element().addClass("dx-drawer"); this._whenAnimationCompleted = void 0; this._whenPanelContentRendered = void 0; this._whenPanelContentRefreshed = void 0; this._$wrapper = (0, _renderer.default)("<div>").addClass("dx-drawer-wrapper"); this._$viewContentWrapper = (0, _renderer.default)("<div>").addClass("dx-drawer-content"); this._$wrapper.append(this._$viewContentWrapper); this.$element().append(this._$wrapper) } _initStrategy() { const { openedStateMode: openedStateMode } = this.option(); switch (openedStateMode) { case "push": default: this._strategy = new _m_drawerRenderingStrategy2.default(this); break; case "shrink": this._strategy = new _m_drawerRenderingStrategy3.default(this); break; case "overlap": this._strategy = new _m_drawerRenderingStrategy.default(this) } } _getAnonymousTemplateName() { return "content" } _initTemplates() { const defaultTemplates = {}; defaultTemplates.panel = new _empty_template.EmptyTemplate; defaultTemplates.content = new _empty_template.EmptyTemplate; this._templateManager.addDefaultTemplates(defaultTemplates); super._initTemplates() } _viewContentWrapperClickHandler(e) { let closeOnOutsideClick = this.option("closeOnOutsideClick"); if ((0, _type.isFunction)(closeOnOutsideClick)) { closeOnOutsideClick = closeOnOutsideClick(e) } if (closeOnOutsideClick && this.option("opened")) { this.stopAnimations(); if (this.option("shading")) { e.preventDefault() } this.hide() } } _initMarkup() { super._initMarkup(); const { opened: opened } = this.option(); this._toggleOpenedStateClass(opened); this._renderPanelContentWrapper(); this._refreshOpenedStateModeClass(); this._refreshRevealModeClass(); this._renderShader(); this._refreshPositionClass(); this._whenPanelContentRendered = (0, _deferred.Deferred)(); this._strategy.renderPanelContent(this._whenPanelContentRendered); this._strategy.onPanelContentRendered(); this._renderViewContent(); _events_engine.default.off(this._$viewContentWrapper, _click.name); _events_engine.default.on(this._$viewContentWrapper, _click.name, this._viewContentWrapperClickHandler.bind(this)); this._refreshWrapperChildrenOrder() } _render() { var _this$_whenPanelConte; this._initMinMaxSize(); super._render(); null === (_this$_whenPanelConte = this._whenPanelContentRendered) || void 0 === _this$_whenPanelConte || _this$_whenPanelConte.always((() => { this._initMinMaxSize(); const { revealMode: revealMode, opened: opened } = this.option(); this._strategy.refreshPanelElementSize("slide" === revealMode); this._renderPosition(opened, true); this._removePanelManualPosition() })) } _removePanelManualPosition() { if (this._$panelContentWrapper.attr("manualposition")) { this._$panelContentWrapper.removeAttr("manualPosition"); this._$panelContentWrapper.css({ position: "", top: "", left: "", right: "", bottom: "" }) } } _togglePanelContentHiddenClass() { const callback = () => { const { minSize: minSize, opened: opened } = this.option(); const shouldBeSet = minSize ? false : !opened; this._$panelContentWrapper.toggleClass("dx-drawer-panel-content-hidden", shouldBeSet) }; if (this._whenAnimationCompleted && !this.option("opened")) { (0, _deferred.when)(this._whenAnimationCompleted).done(callback) } else { callback() } } _renderPanelContentWrapper() { const { openedStateMode: openedStateMode, opened: opened, minSize: minSize } = this.option(); this._$panelContentWrapper = (0, _renderer.default)("<div>").addClass("dx-drawer-panel-content"); this._togglePanelContentHiddenClass(); const position = this.calcTargetPosition(); if ("push" === openedStateMode && ["top", "bottom"].includes(position)) { this._$panelContentWrapper.addClass("dx-drawer-panel-content-push-top-or-bottom") } if ("overlap" !== openedStateMode && !opened && !minSize) { this._$panelContentWrapper.attr("manualposition", true); this._$panelContentWrapper.css({ position: "absolute", top: "-10000px", left: "-10000px", right: "auto", bottom: "auto" }) } this._$wrapper.append(this._$panelContentWrapper) } _refreshOpenedStateModeClass(prevOpenedStateMode) { if (prevOpenedStateMode) { this.$element().removeClass(`dx-drawer-${prevOpenedStateMode}`) } const { openedStateMode: openedStateMode } = this.option(); this.$element().addClass(`dx-drawer-${openedStateMode}`) } _refreshPositionClass() { this.$element().removeClass(["left", "right", "top", "bottom"].map((position => `dx-drawer-${position}`)).join(" ")).addClass(`dx-drawer-${this.calcTargetPosition()}`) } _refreshWrapperChildrenOrder() { const position = this.calcTargetPosition(); if (this._strategy.isViewContentFirst(position, this.option("rtlEnabled"))) { this._$wrapper.prepend(this._$viewContentWrapper) } else { this._$wrapper.prepend(this._$panelContentWrapper) } } _refreshRevealModeClass(prevRevealMode) { if (prevRevealMode) { this.$element().removeClass(`dx-drawer-${prevRevealMode}`) } const { revealMode: revealMode } = this.option(); this.$element().addClass(`dx-drawer-${revealMode}`) } _renderViewContent() { const contentTemplateOption = this.option("contentTemplate"); const contentTemplate = this._getTemplate(contentTemplateOption); if (contentTemplate) { const $viewTemplate = contentTemplate.render({ container: this.viewContent(), noModel: true, transclude: this._templateManager.anonymousTemplateName === contentTemplateOption }); if ($viewTemplate.hasClass("ng-scope")) { (0, _renderer.default)(this._$viewContentWrapper).children().not(".dx-drawer-shader").replaceWith($viewTemplate) } } } _renderShader() { this._$shader = this._$shader || (0, _renderer.default)("<div>").addClass("dx-drawer-shader"); this._$shader.appendTo(this.viewContent()); const { opened: opened } = this.option(); this._toggleShaderVisibility(opened) } _initSize() { this._initMinMaxSize() } _initMinMaxSize() { const realPanelSize = this.isHorizontalDirection() ? this.getRealPanelWidth() : this.getRealPanelHeight(); const { maxSize: maxSize, minSize: minSize } = this.option(); this._maxSize = maxSize || realPanelSize; this._minSize = minSize || 0 } calcTargetPosition() { const { position: position, rtlEnabled: rtlEnabled } = this.option(); if ("before" === position) { return rtlEnabled ? "right" : "left" } if ("after" === position) { return rtlEnabled ? "left" : "right" } return position } getOverlayTarget() { return this._$wrapper } getOverlay() { return this._overlay } getMaxSize() { return this._maxSize } getMinSize() { return this._minSize } getRealPanelWidth() { if ((0, _window.hasWindow)()) { const { templateSize: templateSize } = this.option(); if ((0, _type.isDefined)(templateSize)) { return templateSize } return (0, _position.getBoundingRect)(this._getPanelTemplateElement()).width } return 0 } getRealPanelHeight() { if ((0, _window.hasWindow)()) { const { templateSize: templateSize } = this.option(); if ((0, _type.isDefined)(templateSize)) { return templateSize } return (0, _position.getBoundingRect)(this._getPanelTemplateElement()).height } return 0 } _getPanelTemplateElement() { const $panelContent = this._strategy.getPanelContent(); let $result = $panelContent; if ($panelContent.children().length) { $result = $panelContent.children().eq(0); if ($panelContent.hasClass("dx-overlay-content") && $result.hasClass("dx-template-wrapper") && $result.children().length) { $result = $result.children().eq(0) } } return $result.get(0) } getElementHeight($element) { const $children = $element.children(); return $children.length ? (0, _position.getBoundingRect)($children.eq(0).get(0)).height : (0, _position.getBoundingRect)($element.get(0)).height } isHorizontalDirection() { const position = this.calcTargetPosition(); return "left" === position || "right" === position } stopAnimations(jumpToEnd) { _animation.fx.stop(this._$shader, jumpToEnd); _animation.fx.stop((0, _renderer.default)(this.content()), jumpToEnd); _animation.fx.stop((0, _renderer.default)(this.viewContent()), jumpToEnd); const overlay = this.getOverlay(); if (overlay) { _animation.fx.stop((0, _renderer.default)(overlay.$content()), jumpToEnd) } } setZIndex(zIndex) { this._$shader.css("zIndex", zIndex - 1); this._$panelContentWrapper.css("zIndex", zIndex) } resizeContent() { this.resizeViewContent } resizeViewContent() { (0, _visibility_change.triggerResizeEvent)(this.viewContent()) } _isInvertedPosition() { const position = this.calcTargetPosition(); return "right" === position || "bottom" === position } _renderPosition(isDrawerOpened, disableAnimation, jumpToEnd) { this.stopAnimations(jumpToEnd); this._whenAnimationCompleted = (0, _deferred.Deferred)(); let { animationEnabled: animationEnabled } = this.option(); if (true === disableAnimation) { animationEnabled = false } if (!animationEnabled) { this._whenAnimationCompleted.resolve() } if (!(0, _window.hasWindow)()) { return }(0, _renderer.default)(this.viewContent()).css("paddingLeft", 0); (0, _renderer.default)(this.viewContent()).css("paddingRight", 0); (0, _renderer.default)(this.viewContent()).css("paddingTop", 0); (0, _renderer.default)(this.viewContent()).css("paddingBottom", 0); if (isDrawerOpened) { this._toggleShaderVisibility(isDrawerOpened) } this._strategy.renderPosition(animationEnabled, this.option("animationDuration")) } _animationCompleteHandler() { var _this$_whenAnimationC; this.resizeViewContent(); null === (_this$_whenAnimationC = this._whenAnimationCompleted) || void 0 === _this$_whenAnimationC || _this$_whenAnimationC.resolve() } _getPositionCorrection() { return this._isInvertedPosition() ? -1 : 1 } _dispose() { _m_drawer.animation.complete((0, _renderer.default)(this.viewContent())); super._dispose() } _visibilityChanged(visible) { if (visible) { this._dimensionChanged() } } _dimensionChanged() { this._initMinMaxSize(); const { revealMode: revealMode } = this.option(); this._strategy.refreshPanelElementSize("slide" === revealMode); this._renderPosition(this.option("opened"), true) } _toggleShaderVisibility(visible) { if (this.option("shading")) { this._$shader.toggleClass("dx-state-invisible", !visible); this._$shader.css("visibility", visible ? "visible" : "hidden") } else { this._$shader.toggleClass("dx-state-invisible", true) } } _toggleOpenedStateClass(opened) { this.$element().toggleClass("dx-drawer-opened", opened) } _refreshPanel() { (0, _renderer.default)(this.viewContent()).css("left", 0); (0, _renderer.default)(this.viewContent()).css("transform", "translate(0px, 0px)"); (0, _renderer.default)(this.viewContent()).removeClass("dx-theme-background-color"); this._removePanelContentWrapper(); this._removeOverlay(); this._renderPanelContentWrapper(); this._refreshWrapperChildrenOrder(); this._whenPanelContentRefreshed = (0, _deferred.Deferred)(); this._strategy.renderPanelContent(this._whenPanelContentRefreshed); this._strategy.onPanelContentRendered(); if ((0, _window.hasWindow)()) { this._whenPanelContentRefreshed.always((() => { const { revealMode: revealMode } = this.option(); this._strategy.refreshPanelElementSize("slide" === revealMode); this._renderPosition(this.option("opened"), true, true); this._removePanelManualPosition() })) } } _clean() { this._cleanFocusState(); this._removePanelContentWrapper(); this._removeOverlay() } _removePanelContentWrapper() { if (this._$panelContentWrapper) { this._$panelContentWrapper.remove() } } _removeOverlay() { if (this._overlay) { this._overlay.dispose(); delete this._overlay; delete this._$panelContentWrapper } } _optionChanged(args) { switch (args.name) { case "width": super._optionChanged(args); this._dimensionChanged(); break; case "opened": this._renderPosition(this.option("opened")); this._toggleOpenedStateClass(args.value); this._togglePanelContentHiddenClass(); break; case "position": this._refreshPositionClass(); this._refreshWrapperChildrenOrder(); this._invalidate(); break; case "contentTemplate": case "template": this._invalidate(); break; case "openedStateMode": this._initStrategy(); this._refreshOpenedStateModeClass(args.previousValue); this._refreshPanel(); break; case "minSize": this._initMinMaxSize(); this._renderPosition(this.option("opened"), true); this._togglePanelContentHiddenClass(); break; case "maxSize": this._initMinMaxSize(); this._renderPosition(this.option("opened"), true); break; case "revealMode": this._refreshRevealModeClass(args.previousValue); this._refreshPanel(); break; case "shading": { const { opened: opened } = this.option(); this._toggleShaderVisibility(opened); break } case "animationEnabled": case "animationDuration": case "closeOnOutsideClick": break; default: super._optionChanged(args) } } content() { return (0, _element.getPublicElement)(this._$panelContentWrapper) } viewContent() { return (0, _element.getPublicElement)(this._$viewContentWrapper) } show() { return this.toggle(true) } hide() { return this.toggle(false) } toggle(opened) { var _this$_whenAnimationC2; const targetOpened = void 0 === opened ? !this.option("opened") : opened; this.option("opened", targetOpened); return null === (_this$_whenAnimationC2 = this._whenAnimationCompleted) || void 0 === _this$_whenAnimationC2 ? void 0 : _this$_whenAnimationC2.promise() } }(0, _component_registrator.default)("dxDrawer", Drawer); var _default = exports.default = Drawer;