devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
329 lines (328 loc) • 11.5 kB
JavaScript
/**
* DevExtreme (esm/__internal/ui/action_sheet.js)
* Version: 25.2.3
* Build date: Fri Dec 12 2025
*
* Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
import messageLocalization from "../../common/core/localization/message";
import registerComponent from "../../core/component_registrator";
import $ from "../../core/renderer";
import {
BindableTemplate
} from "../../core/templates/bindable_template";
import {
noop
} from "../../core/utils/common";
import {
Deferred
} from "../../core/utils/deferred";
import {
extend
} from "../../core/utils/extend";
import {
getWindow
} from "../../core/utils/window";
import Button from "../ui/button/wrapper";
import CollectionWidget from "../ui/collection/collection_widget.edit";
import Popover from "../ui/popover/m_popover";
import Popup from "../ui/popup/m_popup";
const window = getWindow();
const ACTION_SHEET_CLASS = "dx-actionsheet";
const ACTION_SHEET_CONTAINER_CLASS = "dx-actionsheet-container";
const ACTION_SHEET_POPUP_WRAPPER_CLASS = "dx-actionsheet-popup-wrapper";
const ACTION_SHEET_POPOVER_WRAPPER_CLASS = "dx-actionsheet-popover-wrapper";
const ACTION_SHEET_CANCEL_BUTTON_CLASS = "dx-actionsheet-cancel";
const ACTION_SHEET_ITEM_CLASS = "dx-actionsheet-item";
const ACTION_SHEET_ITEM_DATA_KEY = "dxActionSheetItemData";
const ACTION_SHEET_WITHOUT_TITLE_CLASS = "dx-actionsheet-without-title";
const ACTION_SHEET_BUTTON_DEFAULT_STYLING_MODE = "outlined";
class ActionSheet extends CollectionWidget {
_getDefaultOptions() {
return Object.assign({}, super._getDefaultOptions(), {
usePopover: false,
target: null,
title: "",
showTitle: true,
showCancelButton: true,
cancelText: messageLocalization.format("Cancel"),
onCancelClick: null,
visible: false,
noDataText: "",
focusStateEnabled: false,
selectByClick: false
})
}
_defaultOptionsRules() {
return super._defaultOptionsRules().concat([{
device: {
platform: "ios",
tablet: true
},
options: {
usePopover: true
}
}])
}
_initTemplates() {
super._initTemplates();
this._templateManager.addDefaultTemplates({
item: new BindableTemplate((($container, data) => {
const button = new Button($("<div>"), extend({
onClick: null === data || void 0 === data ? void 0 : data.click,
stylingMode: (null === data || void 0 === data ? void 0 : data.stylingMode) || "outlined"
}, data));
$container.append(button.$element())
}), ["disabled", "icon", "text", "type", "onClick", "click", "stylingMode"], this.option("integrationOptions.watchMethod"))
})
}
_itemContainer() {
return this._$itemContainer
}
_itemClass() {
return "dx-actionsheet-item"
}
_itemDataKey() {
return "dxActionSheetItemData"
}
_toggleVisibility() {}
_renderDimensions() {}
_initMarkup() {
super._initMarkup();
this.$element().addClass("dx-actionsheet");
this._createItemContainer()
}
_render() {
this._renderPopup()
}
_createItemContainer() {
this._$itemContainer = $("<div>").addClass("dx-actionsheet-container");
this._renderDisabled()
}
_renderDisabled() {
const {
disabled: disabled
} = this.option();
this._$itemContainer.toggleClass("dx-state-disabled", disabled)
}
_renderPopup() {
this._$popup = $("<div>").appendTo(this.$element());
if (this._isPopoverMode()) {
this._createPopover()
} else {
this._createPopup()
}
this._renderPopupTitle();
this._mapPopupOption("visible")
}
_mapPopupOption(optionName) {
var _this$_popup;
null === (_this$_popup = this._popup) || void 0 === _this$_popup || _this$_popup.option(optionName, this.option(optionName))
}
_isPopoverMode() {
const {
usePopover: usePopover,
target: target
} = this.option();
return !!(usePopover && target)
}
_renderPopupTitle() {
var _this$_popup2;
this._mapPopupOption("showTitle");
null === (_this$_popup2 = this._popup) || void 0 === _this$_popup2 || null === (_this$_popup2 = _this$_popup2.$wrapper()) || void 0 === _this$_popup2 || _this$_popup2.toggleClass("dx-actionsheet-without-title", !this.option("showTitle"))
}
_clean() {
if (this._$popup) {
this._$popup.remove()
}
super._clean()
}
_overlayConfig() {
const {
title: title
} = this.option();
return {
onInitialized: args => {
this._popup = args.component
},
disabled: false,
showTitle: true,
title: title,
deferRendering: true,
onContentReady: this._popupContentReadyAction.bind(this),
onHidden: () => {
this.hide()
}
}
}
_createPopover() {
var _this$_popup$$wrapper;
this._createComponent(this._$popup, Popover, extend(this._overlayConfig(), {
width: this.option("width") || 200,
height: this.option("height") || "auto",
target: this.option("target")
}));
this._popup.$overlayContent().attr("role", "dialog");
null === (_this$_popup$$wrapper = this._popup.$wrapper()) || void 0 === _this$_popup$$wrapper || _this$_popup$$wrapper.addClass("dx-actionsheet-popover-wrapper")
}
_createPopup() {
var _this$_popup$$wrapper2;
this._createComponent(this._$popup, Popup, extend(this._overlayConfig(), {
dragEnabled: false,
width: this.option("width") || "100%",
height: this.option("height") || "auto",
showCloseButton: false,
position: {
my: "bottom",
at: "bottom",
of: window
},
animation: {
show: {
type: "slide",
duration: 400,
from: {
position: {
my: "top",
at: "bottom",
of: window
}
},
to: {
position: {
my: "bottom",
at: "bottom",
of: window
}
}
},
hide: {
type: "slide",
duration: 400,
from: {
position: {
my: "bottom",
at: "bottom",
of: window
}
},
to: {
position: {
my: "top",
at: "bottom",
of: window
}
}
}
}
}));
null === (_this$_popup$$wrapper2 = this._popup.$wrapper()) || void 0 === _this$_popup$$wrapper2 || _this$_popup$$wrapper2.addClass("dx-actionsheet-popup-wrapper")
}
_popupContentReadyAction() {
var _this$_popup$$content;
null === (_this$_popup$$content = this._popup.$content()) || void 0 === _this$_popup$$content || _this$_popup$$content.append(this._$itemContainer);
this._attachClickEvent();
this._attachHoldEvent();
this._prepareContent();
this._renderContent();
this._renderCancelButton()
}
_renderCancelButton() {
if (this._isPopoverMode()) {
return
}
if (this._$cancelButton) {
this._$cancelButton.remove()
}
const {
showCancelButton: showCancelButton,
cancelText: cancelText
} = this.option();
if (showCancelButton) {
var _this$_popup3;
const cancelClickAction = this._createActionByOption("onCancelClick") || noop;
const $content = null === (_this$_popup3 = this._popup) || void 0 === _this$_popup3 ? void 0 : _this$_popup3.$content();
if (!$content) {
return
}
this._$cancelButton = $("<div>").addClass("dx-actionsheet-cancel").appendTo($content);
this._createComponent(this._$cancelButton, Button, {
disabled: false,
stylingMode: "outlined",
text: cancelText,
onClick: e => {
const hidingArgs = {
event: e,
cancel: false
};
cancelClickAction(hidingArgs);
if (!hidingArgs.cancel) {
this.hide()
}
},
integrationOptions: {}
})
}
}
_attachItemClickEvent() {}
_itemClickHandler(e) {
super._itemClickHandler(e);
if (!$(e.target).is(".dx-state-disabled, .dx-state-disabled *")) {
this.hide()
}
}
_itemHoldHandler(e) {
super._itemHoldHandler(e);
if (!$(e.target).is(".dx-state-disabled, .dx-state-disabled *")) {
this.hide()
}
}
_optionChanged(args) {
const {
name: name
} = args;
switch (name) {
case "width":
case "height":
case "visible":
case "title":
this._mapPopupOption(name);
break;
case "disabled":
this._renderDisabled();
break;
case "showTitle":
this._renderPopupTitle();
break;
case "showCancelButton":
case "onCancelClick":
case "cancelText":
this._renderCancelButton();
break;
case "target":
case "usePopover":
case "items":
this._invalidate();
break;
default:
super._optionChanged(args)
}
}
toggle(showing) {
const d = Deferred();
this._popup.toggle(showing).done((() => {
this.option("visible", showing);
d.resolveWith(this)
}));
return d.promise()
}
show() {
return this.toggle(true)
}
hide() {
return this.toggle(false)
}
}
registerComponent("dxActionSheet", ActionSheet);
export default ActionSheet;