UNPKG

@openui5/sap.m

Version:

OpenUI5 UI Library sap.m

360 lines (323 loc) 9.67 kB
/*! * OpenUI5 * (c) Copyright 2026 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ sap.ui.define([ "sap/m/p13n/AbstractContainer", "sap/m/Bar", "sap/m/Button", "sap/m/Title", "sap/m/List", "sap/m/IconTabBar", "sap/m/IconTabFilter", "sap/m/p13n/AbstractContainerItem", "sap/ui/Device", "sap/m/library", "sap/m/StandardListItem", "sap/ui/core/library" ], ( AbstractContainer, Bar, Button, Title, List, IconTabBar, IconTabFilter, ContainerItem, Device, mLibrary, StandardListItem, coreLibrary ) => { "use strict"; // shortcut for sap.m.ButtonType const ButtonType = mLibrary.ButtonType; // shortcut for sap.ui.core.TitleLevel const TitleLevel = coreLibrary.TitleLevel; /** * Constructor for a new <code>Container</code>. * * @param {string} [sId] ID for the new control, generated automatically if no ID is given * @param {object} [mSettings] Initial settings for the new control * * @class * Constructor for a new <code>Container</code>. The <code>Container</code> class can be used to dynamically add personalization content to a switchable * layout container. The <code>Container</code> class provides an option for switching content by using an <code>IconTabBar</code> or a <code>List</code> control * respectively, depending on the desired layout mode. See also {@link sap.m.p13n.AbstractContainer}. * * @extends sap.m.p13n.AbstractContainer * * @author SAP SE * @version 1.146.0 * * @private * @ui5-restricted * @since 1.96 * @alias sap.m.p13n.Container */ const Container = AbstractContainer.extend("sap.m.p13n.Container", { metadata: { library: "sap.m", properties: { listLayout: { type: "boolean", defaultValue: false } } }, renderer: { apiVersion: 2 } }); Container.prototype.DEFAULT_KEY = "$default"; Container.prototype.init = function() { AbstractContainer.prototype.init.apply(this, arguments); this.addStyleClass("sapMP13nContainer"); this.setListLayout(Device.system.phone); }; /** * Determines whether a <code>List</code> control or code>IconTabBar</code> is used as the inner layout to display the different views. * * @param {boolean} bListLayout Defines which layout mode is used * @returns {sap.m.p13n.Container} The <code>Container</code> instance */ Container.prototype.setListLayout = function(bListLayout) { this.setProperty("listLayout", bListLayout); //clear existing navigation items this._getTabBar().removeAllItems(); this._getNavigationList().removeAllItems(); let oBackButton; let oHeaderText; let oHeaderContent; //update navigator control if (bListLayout) { this._getTabBar().setVisible(false); this._getNavigationList(); this.switchView(this.DEFAULT_KEY); oBackButton = this._getNavBackBtn(); oHeaderText = this._getHeaderText(); } else { this._getTabBar().setVisible(true); const aViews = this.getViews(); if (aViews.length > 1) { //0 is $default, use index 1 as the first "custom" added view this.switchView(aViews[1].getKey()); } oHeaderContent = this._getTabBar(); } const oHeader = this.getHeader(); if (!oHeader) { const oBar = new Bar({ contentLeft: oHeaderContent ? oHeaderContent : [oBackButton, oHeaderText] }); this.setHeader(oBar); } else { oHeader.removeAllContentLeft(); if (oHeaderContent) { oHeader.addContentLeft(oHeaderContent); } else { oHeader.addContentLeft(oBackButton); oHeader.addContentLeft(oHeaderText); } } this._updateToolbarArialLabelledBy(); //recreate the navigation items this.getViews().forEach((oView) => { this._addToNavigator(oView); }); return this; }; /** * @override */ Container.prototype.switchView = function(sKey) { AbstractContainer.prototype.switchView.apply(this, arguments); if (this._bPrevented) { return; } this.getLayout().setShowHeader(sKey !== this.DEFAULT_KEY); //Don't show header in default view this.getLayout().setShowFooter(sKey !== this.DEFAULT_KEY); //Don't show footer in default view this._getTabBar().setSelectedKey(sKey); this._getNavBackBtn().setVisible(sKey !== this.DEFAULT_KEY); const oTitle = this._getHeaderText(); oTitle.setText(this.getView(sKey)?.getText() || sKey); oTitle.setVisible(this._getNavBackBtn().getVisible()); this._updateToolbarArialLabelledBy(); }; Container.prototype._updateToolbarArialLabelledBy = function () { if (this.getListLayout()) { const oTitle = this._getHeaderText(); const oBar = this.getHeader(); if (oTitle && oBar?.getAriaLabelledBy().indexOf(oTitle.getId()) == -1) { oBar.addAriaLabelledBy(oTitle); } } }; /** * @override */ Container.prototype.addView = function(vContainerItem) { this._addToNavigator(typeof vContainerItem == "string" ? this.getView(vContainerItem) : vContainerItem); AbstractContainer.prototype.addView.apply(this, arguments); return this; }; /** * @override */ Container.prototype.removeView = function(vContainerItem) { this._removeFromNavigator(typeof vContainerItem == "string" ? this.getView(vContainerItem) : vContainerItem); AbstractContainer.prototype.removeView.apply(this, arguments); return this; }; /* * This method can be used to add a separator line to the last added item. * This will only take effect in the "list" mode. * * @returns {sap.m.p13n.Container} The Container instance */ Container.prototype.addSeparator = function() { if (!this.getProperty("listLayout")) { return; } const oItems = this._getNavigationList().getItems(); const oLastItem = oItems[oItems.length - 1]; oLastItem.addStyleClass("sapMMenuDivider"); return this; }; /** * Returns the layout object. * * @returns {sap.m.Page} The layout object * @ui5-restricted sap.m.table.columnmenu.Menu */ Container.prototype.getLayout = function() { return this.oLayout; }; Container.prototype._getTabBar = function() { if (!this._oTabBar) { this._oTabBar = new IconTabBar({ headerBackgroundDesign: "Transparent", applyContentPadding: false, expandable: false, select: (oEvt) => { this.switchView(oEvt.getParameter("key")); } }); this.addDependent(this._oTabBar); } return this._oTabBar; }; Container.prototype._getNavigationList = function() { if (!this._oNavigationList) { this._oNavigationList = new List({ itemPress: (oEvt) => { const oItem = oEvt.getParameter("listItem"); this.switchView(oItem._key); } }); this.addDependent(this._oNavigationList); } if (!this.getView(this.DEFAULT_KEY)) { const oListContainer = new ContainerItem({ key: this.DEFAULT_KEY, content: this._oNavigationList }); this.addView(oListContainer); } return this._oNavigationList; }; /** * Sets the <code>headerToolbar</code> aggregation of the navigation list. * * @param {sap.m.Toolbar} oToolbar The toolbar instance * @returns {sap.m.p13n.Container} The container instance for method chaining * @ui5-restricted sap.m.table.columnmenu.Menu */ Container.prototype.setListHeader = function(oToolbar) { return this._oNavigationList.setHeaderToolbar(oToolbar); }; Container.prototype._getNavBackBtn = function() { if (!this._oNavBackBtn) { this._oNavBackBtn = new Button({ type: ButtonType.Back, press: (oEvt) => { this.switchView(this.DEFAULT_KEY); } }); this.addDependent(this._oNavBackBtn); } return this._oNavBackBtn; }; Container.prototype._getHeaderText = function() { if (!this._oHeaderText) { this._oHeaderText = new Title({ level: Device.system.phone ? TitleLevel.H2 : TitleLevel.H1 }); this.addDependent(this._oHeaderText); } return this._oHeaderText; }; Container.prototype._addToNavigator = function(oContainerItem) { const sKey = oContainerItem.getKey(); const oContainerItemTextBindingInfo = oContainerItem.getBindingInfo("text"); let vText = oContainerItem.getText(); const sIcon = oContainerItem.getIcon(); const sType = oContainerItem.getType(); //In case the text of the Abstract container item is bound, the binding should be forwarded instead of the value if (oContainerItemTextBindingInfo && oContainerItemTextBindingInfo.parts) { vText = { parts: oContainerItemTextBindingInfo.parts }; } if (sKey == this.DEFAULT_KEY) { return; } if (this.getListLayout()) { this.getView(this.DEFAULT_KEY); const oItem = new StandardListItem({ type: sType, icon: sIcon, title: vText }); oItem._key = sKey; this._getNavigationList().addItem(oItem); } else { this._getTabBar().addItem(new IconTabFilter({ key: sKey, text: vText || sKey })); } }; Container.prototype._removeFromNavigator = function(oContainerItem) { const sKey = oContainerItem.getKey(); if (sKey == this.DEFAULT_KEY) { return; } if (this.getListLayout()) { const oItem = this._getNavigationList().getItems().find((oListItem) => { return oListItem._key === sKey; }); this._getNavigationList().removeItem(oItem); } else { const oTab = this._getTabBar().getItems().find((oTab) => { return oTab.getKey() === sKey; }); this._getTabBar().removeItem(oTab); } }; Container.prototype.exit = function() { AbstractContainer.prototype.exit.apply(this, arguments); if (this._oTabBar) { this._oTabBar.destroy(); this._oTabBar = null; } if (this._oNavigationList) { this._oNavigationList.destroy(); this._oNavigationList = null; } this._oNavBackBtn = null; this._oHeaderText = null; }; return Container; });