| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416 |
- /**
- * DevExtreme (ui/drop_down_menu.js)
- * Version: 19.1.16
- * Build date: Tue Oct 18 2022
- *
- * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
- * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
- */
- "use strict";
- var $ = require("../core/renderer");
- var window = require("../core/utils/window").getWindow();
- var devices = require("../core/devices");
- var registerComponent = require("../core/component_registrator");
- var extend = require("../core/utils/extend").extend;
- var Widget = require("./widget/ui.widget");
- var Button = require("./button");
- var Popover = require("./popover");
- var DataHelperMixin = require("../data_helper");
- var List = require("./list");
- var themes = require("./themes");
- var ChildDefaultTemplate = require("./widget/child_default_template");
- var DROP_DOWN_MENU_CLASS = "dx-dropdownmenu";
- var DROP_DOWN_MENU_POPUP_CLASS = "dx-dropdownmenu-popup";
- var DROP_DOWN_MENU_POPUP_WRAPPER_CLASS = "dx-dropdownmenu-popup-wrapper";
- var DROP_DOWN_MENU_LIST_CLASS = "dx-dropdownmenu-list";
- var DROP_DOWN_MENU_BUTTON_CLASS = "dx-dropdownmenu-button";
- var POPUP_OPTION_MAP = {
- popupWidth: "width",
- popupHeight: "height",
- popupMaxHeight: "maxHeight",
- popupAutoResizeEnabled: "autoResizeEnabled"
- };
- var BUTTON_OPTION_MAP = {
- buttonIcon: "icon",
- buttonText: "text",
- buttonWidth: "width",
- buttonHeight: "height",
- buttonTemplate: "template"
- };
- var DropDownMenu = Widget.inherit({
- _supportedKeys: function() {
- var extension = {};
- if (!this.option("opened") || !this._list.option("focusedElement")) {
- extension = this._button._supportedKeys()
- }
- return extend(this.callBase(), extension, {
- tab: function() {
- this._popup && this._popup.hide()
- }
- })
- },
- _getDefaultOptions: function() {
- return extend(this.callBase(), {
- items: [],
- onItemClick: null,
- dataSource: null,
- itemTemplate: "item",
- buttonText: "",
- buttonIcon: "overflow",
- buttonWidth: void 0,
- buttonHeight: void 0,
- buttonTemplate: "content",
- onButtonClick: null,
- usePopover: false,
- popupWidth: "auto",
- popupHeight: "auto",
- activeStateEnabled: true,
- hoverStateEnabled: true,
- opened: false,
- deferRendering: false,
- popupPosition: {
- my: "top center",
- at: "bottom center",
- collision: "fit flip",
- offset: {
- v: 1
- }
- },
- popupAnimation: void 0,
- onItemRendered: null,
- menuWidget: List,
- popupMaxHeight: void 0,
- closeOnClick: true,
- useInkRipple: false,
- container: void 0,
- popupAutoResizeEnabled: false
- })
- },
- _defaultOptionsRules: function() {
- return this.callBase().concat([{
- device: {
- platform: "ios"
- },
- options: {
- usePopover: true
- }
- }, {
- device: {
- platform: "generic"
- },
- options: {
- popupPosition: {
- offset: {
- v: 4
- }
- }
- }
- }, {
- device: function() {
- return "desktop" === devices.real().deviceType && !devices.isSimulator()
- },
- options: {
- focusStateEnabled: true
- }
- }, {
- device: {
- platform: "android"
- },
- options: {
- popupPosition: {
- my: "top " + (this.option("rtlEnabled") ? "left" : "right"),
- at: "top " + (this.option("rtlEnabled") ? "left" : "right"),
- collision: "flipfit"
- },
- popupAnimation: {
- show: {
- type: "pop",
- duration: 200,
- from: {
- scale: 0
- },
- to: {
- scale: 1
- }
- },
- hide: {
- type: "pop",
- duration: 200,
- from: {
- scale: 1
- },
- to: {
- scale: 0
- }
- }
- }
- }
- }, {
- device: function() {
- return themes.isMaterial()
- },
- options: {
- useInkRipple: true
- }
- }])
- },
- _initOptions: function(options) {
- if ("android" === devices.current().platform) {
- if (!options.popupPosition) {
- options.popupPosition = {
- at: (options.usePopover ? "bottom " : "top ") + (options.rtlEnabled ? "left" : "right")
- }
- }
- }
- this.callBase(options)
- },
- _dataSourceOptions: function() {
- return {
- paginate: false
- }
- },
- _init: function() {
- this.callBase();
- this.$element().addClass(DROP_DOWN_MENU_CLASS);
- this._initDataSource();
- this._initItemClickAction();
- this._initButtonClickAction()
- },
- _initItemClickAction: function() {
- this._itemClickAction = this._createActionByOption("onItemClick")
- },
- _initButtonClickAction: function() {
- this._buttonClickAction = this._createActionByOption("onButtonClick")
- },
- _initTemplates: function() {
- this.callBase();
- this._defaultTemplates.content = new ChildDefaultTemplate("content", this)
- },
- _initMarkup: function() {
- this._renderButton();
- this.callBase()
- },
- _render: function() {
- this.callBase();
- this.setAria({
- role: "menubar",
- haspopup: true,
- expanded: this.option("opened")
- })
- },
- _renderContentImpl: function() {
- if (this.option("opened")) {
- this._renderPopup()
- }
- },
- _clean: function() {
- this._cleanFocusState();
- if (this._popup) {
- this._popup.$element().remove();
- delete this._$popup
- }
- },
- _renderButton: function() {
- var $button = this.$element().addClass(DROP_DOWN_MENU_BUTTON_CLASS);
- var config = this._buttonOptions();
- this._button = this._createComponent($button, Button, config)
- },
- _toggleActiveState: function($element, value, e) {
- this._button._toggleActiveState($element, value, e)
- },
- _buttonOptions: function() {
- return {
- text: this.option("buttonText"),
- icon: this.option("buttonIcon"),
- width: this.option("buttonWidth"),
- height: this.option("buttonHeight"),
- useInkRipple: this.option("useInkRipple"),
- template: this.option("buttonTemplate"),
- focusStateEnabled: false,
- onClick: function(e) {
- this.option("opened", !this.option("opened"));
- this._buttonClickAction(e)
- }.bind(this)
- }
- },
- _toggleMenuVisibility: function(opened) {
- var state = void 0 === opened ? !this._popup.option("visible") : opened;
- if (opened) {
- this._renderPopup()
- }
- this._popup.toggle(state);
- this.setAria("expanded", state)
- },
- _renderPopup: function() {
- if (this._$popup) {
- return
- }
- var $popup = this._$popup = $("<div>").appendTo(this.$element());
- var config = this._popupOptions();
- this._popup = this._createComponent($popup, Popover, config)
- },
- _popupOptions: function() {
- var usePopup = !this.option("usePopover");
- return {
- onInitialized: function(args) {
- args.component._wrapper().addClass(DROP_DOWN_MENU_POPUP_WRAPPER_CLASS).toggleClass(DROP_DOWN_MENU_POPUP_CLASS, usePopup)
- },
- visible: this.option("opened"),
- deferRendering: false,
- contentTemplate: function(contentElement) {
- this._renderList(contentElement)
- }.bind(this),
- position: this.option("popupPosition"),
- animation: this.option("popupAnimation"),
- onOptionChanged: function(args) {
- if ("visible" === args.name) {
- this.option("opened", args.value)
- }
- }.bind(this),
- target: this.$element(),
- height: this.option("popupHeight"),
- width: this.option("popupWidth"),
- maxHeight: this.option("popupMaxHeight"),
- container: this.option("container"),
- autoResizeEnabled: this.option("popupAutoResizeEnabled")
- }
- },
- _renderList: function(contentElement) {
- var $content = $(contentElement);
- var listConfig = this._listOptions();
- $content.addClass(DROP_DOWN_MENU_LIST_CLASS);
- this._list = this._createComponent($content, this.option("menuWidget"), listConfig);
- this._list._getAriaTarget = function() {
- return this.$element()
- }.bind(this);
- this._setListDataSource();
- var listMaxHeight = .5 * $(window).height();
- if ($content.height() > listMaxHeight) {
- $content.height(listMaxHeight)
- }
- },
- _listOptions: function() {
- return {
- _keyboardProcessor: this._listProcessor,
- pageLoadMode: "scrollBottom",
- indicateLoading: false,
- noDataText: "",
- itemTemplate: this.option("itemTemplate"),
- onItemClick: function(e) {
- if (this.option("closeOnClick")) {
- this.option("opened", false)
- }
- this._itemClickAction(e)
- }.bind(this),
- tabIndex: -1,
- focusStateEnabled: this.option("focusStateEnabled"),
- activeStateEnabled: this.option("activeStateEnabled"),
- onItemRendered: this.option("onItemRendered"),
- _itemAttributes: {
- role: "menuitem"
- }
- }
- },
- _setListDataSource: function() {
- if (this._list) {
- this._list.option("dataSource", this._dataSource || this.option("items"))
- }
- delete this._deferRendering
- },
- _attachKeyboardEvents: function() {
- this.callBase.apply(this, arguments);
- this._listProcessor = this._keyboardProcessor && this._keyboardProcessor.attachChildProcessor();
- if (this._list) {
- this._list.option("_keyboardProcessor", this._listProcessor)
- }
- },
- _cleanFocusState: function() {
- this.callBase.apply(this, arguments);
- delete this._listProcessor
- },
- _toggleVisibility: function(visible) {
- this.callBase(visible);
- this._button.option("visible", visible)
- },
- _optionChanged: function(args) {
- var name = args.name;
- var value = args.value;
- switch (name) {
- case "items":
- case "dataSource":
- if (this.option("deferRendering") && !this.option("opened")) {
- this._deferRendering = true
- } else {
- this._refreshDataSource();
- this._setListDataSource()
- }
- break;
- case "itemTemplate":
- if (this._list) {
- this._list.option(name, this._getTemplate(value))
- }
- break;
- case "onItemClick":
- this._initItemClickAction();
- break;
- case "onButtonClick":
- this._buttonClickAction();
- break;
- case "buttonIcon":
- case "buttonText":
- case "buttonWidth":
- case "buttonHeight":
- case "buttonTemplate":
- this._button.option(BUTTON_OPTION_MAP[name], value);
- this._renderPopup();
- break;
- case "popupWidth":
- case "popupHeight":
- case "popupMaxHeight":
- case "popupAutoResizeEnabled":
- this._popup.option(POPUP_OPTION_MAP[name], value);
- break;
- case "usePopover":
- case "menuWidget":
- case "useInkRipple":
- this._invalidate();
- break;
- case "focusStateEnabled":
- case "activeStateEnabled":
- if (this._list) {
- this._list.option(name, value)
- }
- this.callBase(args);
- break;
- case "onItemRendered":
- if (this._list) {
- this._list.option(name, value)
- }
- break;
- case "opened":
- if (this._deferRendering) {
- this._refreshDataSource();
- this._setListDataSource()
- }
- this._toggleMenuVisibility(value);
- break;
- case "deferRendering":
- case "popupPosition":
- case "closeOnClick":
- break;
- case "container":
- this._popup && this._popup.option(args.name, args.value);
- break;
- default:
- this.callBase(args)
- }
- },
- open: function() {
- this.option("opened", true)
- },
- close: function() {
- this.option("opened", false)
- }
- }).include(DataHelperMixin);
- registerComponent("dxDropDownMenu", DropDownMenu);
- module.exports = DropDownMenu;
|