UNPKG

@openui5/sap.m

Version:

OpenUI5 UI Library sap.m

330 lines (287 loc) 12.3 kB
/*! * OpenUI5 * (c) Copyright 2026 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ /** * OverflowToolbar / OverflowToolbarAssociativePopover helper * This class handles the changes done to controls with respect to the associative popover * For each control that must have a special handling before entering/leaving the popover, there must be 2 functions: * _preProcessCONTROL (called before moving the control to the popover) * _postProcessCONTROL (called before returning the control to the toolbar) * where CONTROL is a camel-cased version of the getMetadata().getName() value, f.e. "sap.m.Button" becomes "sapMButton" */ sap.ui.define([ 'sap/ui/base/Object', './OverflowToolbarButton', './OverflowToolbarMenuButton', './OverflowToolbarToggleButton', './ToggleButton', './Button', 'sap/m/library', "sap/base/Log" ], function( BaseObject, OverflowToolbarButton, OverflowToolbarMenuButton, OverflowToolbarToggleButton, ToggleButton, Button, library, Log ) { "use strict"; // shortcut for sap.m.ButtonType var ButtonType = library.ButtonType; var OverflowToolbarAssociativePopoverControls = BaseObject.extend("sap.m._overflowToolbarHelpers.OverflowToolbarAssociativePopoverControls", { /** * @private */ constructor: function() { this._mControlsCache = {}; }, getInterface: function() { return this; // no facade } }); // Button - modifications similar to action sheet OverflowToolbarAssociativePopoverControls.prototype._preProcessSapMButton = function(oControl) { var oButtonType = oControl.getType(); this._mControlsCache[oControl.getId()] = { buttonType: oButtonType }; if (oButtonType === ButtonType.Default) { oControl.setProperty("type", ButtonType.Transparent, true); } oControl.attachEvent("_change", this._onSapMButtonUpdated, this); }; OverflowToolbarAssociativePopoverControls.prototype._postProcessSapMButton = function(oControl) { var oPrevState = this._mControlsCache[oControl.getId()]; if (oControl.getType() === "Transparent" && oControl.getType() !== oPrevState.buttonType && oPrevState.buttonType === ButtonType.Default) { oControl.setProperty("type", oPrevState.buttonType, true); } oControl.detachEvent("_change", this._onSapMButtonUpdated, this); }; OverflowToolbarAssociativePopoverControls.prototype._onSapMButtonUpdated = function(oEvent) { var sParameterName = oEvent.getParameter("name"), oButton = oEvent.getSource(), sButtonId = oButton.getId(); if (typeof this._mControlsCache[sButtonId] === "undefined") { return; } if (sParameterName === "type") { this._mControlsCache[sButtonId]["buttonType"] = oButton.getType(); } }; // OverflowToolbarButton - same as Button, but also must add the _bInOverflow trigger OverflowToolbarAssociativePopoverControls.prototype._preProcessSapMOverflowToolbarButton = function(oControl) { this._preProcessSapMButton(oControl); oControl._bInOverflow = true; }; OverflowToolbarAssociativePopoverControls.prototype._postProcessSapMOverflowToolbarButton = function(oControl) { delete oControl._bInOverflow; this._postProcessSapMButton(oControl); }; // OverflowToolbarMenuButton - Same as button with the _bInOverflow trigger OverflowToolbarAssociativePopoverControls.prototype._preProcessSapMOverflowToolbarMenuButton = function(oControl) { this._preProcessSapMButton(oControl); oControl._bInOverflow = true; }; OverflowToolbarAssociativePopoverControls.prototype._postProcessSapMOverflowToolbarMenuButton = function(oControl) { delete oControl._bInOverflow; this._postProcessSapMButton(oControl); }; // ToggleButton - same as button OverflowToolbarAssociativePopoverControls.prototype._preProcessSapMToggleButton = function(oControl) { this._preProcessSapMButton(oControl); }; OverflowToolbarAssociativePopoverControls.prototype._postProcessSapMToggleButton = function(oControl) { this._postProcessSapMButton(oControl); }; // OverflowToolbarToggleButton - same as ToggleButton, but also must add the _bInOverflow trigger OverflowToolbarAssociativePopoverControls.prototype._preProcessSapMOverflowToolbarToggleButton = function(oControl) { this._preProcessSapMToggleButton(oControl); oControl._bInOverflow = true; }; OverflowToolbarAssociativePopoverControls.prototype._postProcessSapMOverflowToolbarToggleButton = function(oControl) { delete oControl._bInOverflow; this._postProcessSapMToggleButton(oControl); }; /****************************** STATIC properties and methods ****************************/ /** * A map of all controls that are commonly found in an overflow toolbar * canOverflow - tells if the control can go to the popover or is forced to always stay in the toolbar (f.e. labels, radio buttons can never overflow) * listenForEvents - all events that, when fired, suggest that the interaction with the control is over and the popup must be closed (f.e. button click, select change) * noInvalidationProps - all properties of a control that, when changed, do not affect the size of the control, thus don't require a re-rendering of the toolbar (f.e. input value) * @private */ OverflowToolbarAssociativePopoverControls._mSupportedControls = { "sap.m.Button": { canOverflow: true, listenForEvents: ["press"], noInvalidationProps: ["enabled", "accesskey"] }, "sap.m.MenuButton": { canOverflow: true, listenForEvents: ["defaultAction", "_menuItemSelected"], noInvalidationProps: ["enabled", "text", "icon"] }, "sap.m.OverflowToolbarMenuButton": { canOverflow: true, listenForEvents: ["defaultAction", "_menuItemSelected"], noInvalidationProps: ["enabled", "text", "icon"] }, "sap.m.OverflowToolbarToggleButton": { canOverflow: true, listenForEvents: ["press"], noInvalidationProps: ["enabled", "type", "pressed", "accesskey"] }, "sap.m.CheckBox": { canOverflow: true, listenForEvents: ["select"], noInvalidationProps: ["enabled", "selected", "accesskey"] }, "sap.m.ToggleButton": { canOverflow: true, listenForEvents: ["press"], noInvalidationProps: ["enabled", "pressed", "accesskey"] }, "sap.m.ComboBox": { canOverflow: true, listenForEvents: [], noInvalidationProps: ["enabled", "value", "selectedItemId", "selectedKey", "open", "_open", "effectiveShowClearIcon"] }, "sap.m.Input": { canOverflow: true, listenForEvents: [], noInvalidationProps: ["enabled", "value", "accesskey"] }, "sap.m.DateTimeInput": { canOverflow: true, listenForEvents: ["change"], noInvalidationProps: ["enabled", "value", "dateValue"] }, "sap.m.DatePicker": { canOverflow: true, listenForEvents: ["change"], noInvalidationProps: ["enabled", "value", "dateValue", "displayFormat", "valueFormat", "displayFormatType", "secondaryCalendarType", "minDate", "maxDate"] }, "sap.m.DateRangeSelection": { canOverflow: true, listenForEvents: ["change"], noInvalidationProps: ["enabled", "value", "dateValue", "secondDateValue", "displayFormat", "valueFormat", "displayFormatType", "secondaryCalendarType", "minDate", "maxDate", "delimiter"] }, "sap.m.DateTimePicker": { canOverflow: true, listenForEvents: ["change"], noInvalidationProps: ["enabled", "value", "dateValue", "displayFormat", "valueFormat", "displayFormatType", "secondaryCalendarType", "minDate", "maxDate"] }, "sap.m.TimePicker": { canOverflow: true, listenForEvents: ["change"], noInvalidationProps: ["enabled", "value", "dateValue", "displayFormat", "valueFormat"] }, "sap.m.RadioButton": { canOverflow: false, listenForEvents: [], noInvalidationProps: ["enabled", "selected"] }, "sap.m.Slider": { canOverflow: false, listenForEvents: [], noInvalidationProps: ["enabled", "value"] }, "sap.m.IconTabHeader": { canOverflow: false, listenForEvents: [], noInvalidationProps: ["selectedKey"] }, "sap.ui.comp.smartfield.SmartField": { canOverflow: true, listenForEvents: ["change"], noInvalidationProps: ["enabled", "value", "valueState", "showValueHelp", "contextEditable", "clientSideMandatoryCheck", "mandatory", "name", "placeholder", "showSuggestion", "tooltipLabel"] }, "sap.ui.comp.smartfield.SmartLabel": { canOverflow: true, listenForEvents: [], noInvalidationProps: ["enabled"] } }; /** * Returns the control configuration for a given control * @param oControl - control instance object * @returns {*} */ OverflowToolbarAssociativePopoverControls.getControlConfig = function(oControl) { var oConfig; // First check if the control's class implements the sap.m.IOverflowToolbarContent interface if (oControl.isA("sap.m.IOverflowToolbarContent")) { if (typeof oControl.getOverflowToolbarConfig !== "function") { Log.error("Required method getOverflowToolbarConfig not implemented by: " + oControl.getMetadata().getName()); return; } oConfig = oControl.getOverflowToolbarConfig(); if (typeof oConfig !== "object") { Log.error("Method getOverflowToolbarConfig implemented, but does not return an object in: " + oControl.getMetadata().getName()); return; } return { canOverflow: !!oConfig.canOverflow, listenForEvents: Array.isArray(oConfig.autoCloseEvents) ? oConfig.autoCloseEvents : [], noInvalidationProps: Array.isArray(oConfig.propsUnrelatedToSize) ? oConfig.propsUnrelatedToSize : [], preProcess: oConfig.onBeforeEnterOverflow, postProcess: oConfig.onAfterExitOverflow }; } // The interface is not implemented - check the _mSupportedControls array (legacy scenario) var sClassName = OverflowToolbarAssociativePopoverControls.getControlClass(oControl); oConfig = OverflowToolbarAssociativePopoverControls._mSupportedControls[sClassName]; if (oConfig === undefined) { return; } var sPreProcessFnName = "_preProcess" + sClassName.split(".").map(fnCapitalize).join(""); if (typeof OverflowToolbarAssociativePopoverControls.prototype[sPreProcessFnName] === "function") { oConfig.preProcess = OverflowToolbarAssociativePopoverControls.prototype[sPreProcessFnName]; } var sPostProcessFnName = "_postProcess" + sClassName.split(".").map(fnCapitalize).join(""); if (typeof OverflowToolbarAssociativePopoverControls.prototype[sPostProcessFnName] === "function") { oConfig.postProcess = OverflowToolbarAssociativePopoverControls.prototype[sPostProcessFnName]; } return oConfig; }; /** * Tells if a control is supported by the associative popover (i.e. can overflow to it) * @param oControl - control instance object * @returns {boolean} */ OverflowToolbarAssociativePopoverControls.supportsControl = function(oControl) { var oCtrlConfig = OverflowToolbarAssociativePopoverControls.getControlConfig(oControl); return typeof oCtrlConfig !== "undefined" && oCtrlConfig.canOverflow; }; /** * Returns the class of a control in terms of overflow behavior * This is needed so that for example a custom button, extending sap.m.Button, can overflow too * @param oControl */ OverflowToolbarAssociativePopoverControls.getControlClass = function(oControl) { // For now only custom classes, extending the sap.m.Button and its derivatives, are supported for overflow if (oControl instanceof OverflowToolbarButton) { return "sap.m.OverflowToolbarButton"; } else if (oControl instanceof OverflowToolbarMenuButton) { return "sap.m.OverflowToolbarMenuButton"; } else if (oControl instanceof OverflowToolbarToggleButton) { return "sap.m.OverflowToolbarToggleButton"; } else if (oControl instanceof ToggleButton) { return "sap.m.ToggleButton"; } else if (oControl instanceof Button) { return "sap.m.Button"; } // All other controls must be the standard sap.m class in order to overflow return oControl.getMetadata().getName(); }; function fnCapitalize(sName) { return sName.substring(0, 1).toUpperCase() + sName.substr(1); } return OverflowToolbarAssociativePopoverControls; });