UNPKG

@openui5/sap.m

Version:

OpenUI5 UI Library sap.m

312 lines (259 loc) 10.3 kB
/*! * OpenUI5 * (c) Copyright 2026 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ // Provides control sap.m.OverflowToolbarTokenizer sap.ui.define([ 'sap/m/Tokenizer', 'sap/m/OverflowToolbarTokenizerRenderer', 'sap/m/Button', 'sap/m/Label', 'sap/ui/core/IconPool', './library', 'sap/ui/core/library' ], function( Tokenizer, OverflowToolbarTokenizerRenderer, Button, Label, IconPool, library, coreLibrary ) { "use strict"; const RenderMode = library.OverflowToolbarTokenizerRenderMode; const PlacementType = library.PlacementType; const ButtonAccessibleRole = library.ButtonAccessibleRole; const AriaHasPopup = coreLibrary.aria.HasPopup; const CSS_CLASS_OVERFLOWTOOLBAR_TOKENIZER_POPUP = "sapMOverflowToolbarTokenizerTokensPopup"; /** * Constructor for a new <code>OverflowToolbarTokenizer</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 * Represents an {@link sap.m.Button} that shows its text only when in the overflow area of an {@link sap.m.OverflowToolbar}. * * <b>Note:</b> This control is intended to be used exclusively in the context of <code>sap.m.Toolbar</code> and <code>sap.m.OverflowToolbar</code>. * Using more than one tokenizer in the same toolbar is not recomended, as it may lead to unexpected behavior. * Do not use tokenizers within a toolbar if its active property is set to <code>true</code>. * @extends sap.m.Button * * @implements sap.m.IOverflowToolbarContent * @implements sap.m.IToolbarInteractiveControl * @implements sap.m.IOverflowToolbarFlexibleContent * * @author SAP SE * @version 1.146.0 * * @constructor * @public * @experimental since 1.139 * @since 1.139 * @alias sap.m.OverflowToolbarTokenizer */ const OverflowToolbarTokenizer = Tokenizer.extend("sap.m.OverflowToolbarTokenizer", /** @lends sap.m.OverflowToolbarTokenizer.prototype */ { metadata: { library : "sap.m", properties : { /** * Property for the text of a sap.m.Label displayed with sap.m.OverflowToolbarTokenizer. It is also displayed as an n-More button text when used inside a <code>sap.m.OverflowToolbar</code>. */ labelText : {type : "string", group : "Misc", defaultValue : null}, /** * Defines the mode that the OverflowToolbarTokenizer will use: * <ul> * <li><code>sap.m.OverflowToolbarTokenizerRenderMode.Loose</code> mode shows all tokens, no matter the width of the Tokenizer</li> * <li><code>sap.m.OverflowToolbarTokenizerRenderMode.Narrow</code> mode restricts the tokenizer to display only the maximum number of tokens that fit within its width, adding an n-More indicator for the remaining tokens</li> * <li><code>sap.m.OverflowToolbarTokenizerRenderMode.Overflow</code> mode forces the tokenizer to show only <code>sap.m.Button</code> as an n-More indicator without visible tokens. It is used when <code>sap.m.OverflowToolbarTokenizer</code> is within the <code>sap.m.OverflowToolbar</code> overflow area</li> * </ul> * * <b>Note</b>: Have in mind that the <code>renderMode</code> property is used internally by the OverflowToolbarTokenizer and controls that use the OverflowToolbarTokenizer. Therefore, modifying this property may alter the expected behavior of the control. */ renderMode: {type : "string", group : "Misc", defaultValue : RenderMode.Narrow} }, interfaces: [ "sap.m.IOverflowToolbarContent", "sap.m.IToolbarInteractiveControl", "sap.m.IOverflowToolbarFlexibleContent" ], aggregations: { /** * The n-More button showed in the bar's overflow area which opens the tokens popup */ moreItemsButton: {type: "sap.m.Button", multiple: false, visibility: "hidden"}, /** * Label for <code>sap.m.Tokenizer</code>. It is also displayed as an n-More button text when used inside a <code>sap.m.OverflowToolbar</code>. */ label : {type : "sap.m.Label", multiple : false, visibility : "hidden"} } }, renderer: OverflowToolbarTokenizerRenderer }); IconPool.insertFontFaceStyle(); OverflowToolbarTokenizer.prototype.onBeforeRendering = function() { const sLabelText = this.getLabelText(); const sLabelAggregationText = this.getAggregation("label")?.getText(); const sMoreItemsButtonText = this.getAggregation("moreItemsButton")?.getText(); Tokenizer.prototype.onBeforeRendering.call(this); if (sLabelText !== sLabelAggregationText) { this._updateLabel(); } if (sLabelText !== sMoreItemsButtonText) { this._updateButton(); } // Store initial width props to restore them to reset them if the control is // re-rendered from the overflow area to the the visible area of the toolbar if (this.getRenderMode() !== RenderMode.Overflow) { this._sOriginalWidth = this.getWidth(); this._originalMaxWidth = this.getMaxWidth(); } }; /** * Creates and updates an instance of <code>sap.m.Button</code> for the n-More indicator in the overflow area of <code>sap.m.OverflowToolbar</code>. * * @private */ OverflowToolbarTokenizer.prototype._updateButton = function () { const sLabelText = this.getLabelText(); const oNMoreButton = this.getAggregation("moreItemsButton"); if (!oNMoreButton) { this.setAggregation("moreItemsButton", new Button({ text: sLabelText, accessibleRole: ButtonAccessibleRole.Link, ariaHasPopup: AriaHasPopup.Dialog, width: "100%", icon: IconPool.getIconURI("slim-arrow-left"), press: this._handleNMoreIndicatorPress.bind(this) }).addStyleClass("sapMTokenizerIndicator sapMBarChild")); return; } oNMoreButton.setText(sLabelText); }; /** * Creates, removes and updates an instance of <code>sap.m.Label</code> for <code>sap.m.OverflowToolbarTokenizer</code> depending on whether the <code>labelText</code> property is set, removed or updated. * * @private */ OverflowToolbarTokenizer.prototype._updateLabel = function () { const sLabelText = this.getLabelText(); if (!sLabelText) { this.removeAllAggregation("label"); return; } if (!this.getAggregation("label")) { this.setAggregation( "label", new Label({ text : sLabelText, tooltip: sLabelText }) ); return; } this.getAggregation("label").setText(sLabelText); this.getAggregation("label").setTooltip(sLabelText); }; OverflowToolbarTokenizer.prototype._useCollapsedMode = function () { if (this.getRenderMode() === RenderMode.Overflow) { this._getVisibleTokens().forEach((oToken) => oToken.addStyleClass("sapMHiddenToken")); return; } Tokenizer.prototype._useCollapsedMode.call(this, this.getRenderMode()); }; /** * Sets the mode of the tokenizer to 'Overflow' (collapsed) when the tokenizer is inside the overflow area or 'Narrow' when it is not overflown. * @param {boolean} bOverflowMode true if the tokenizer should be displayed as a button in the overflow popup of the sap.m.OverflowToolbar * @returns {this} this instance for method chaining */ OverflowToolbarTokenizer.prototype.setOverflowMode = function(bOverflowMode) { const oLabelText = this.getLabelText(); const oMoreItemsButton = this.getAggregation("moreItemsButton"); this.setRenderMode(bOverflowMode ? RenderMode.Overflow : RenderMode.Narrow); if (bOverflowMode) { oMoreItemsButton?.setText(oLabelText || this._oIndicator.html()); this.setWidth(`auto`); this.setMaxWidth(`auto`); return this; } this._adjustTokensVisibility(); this.setWidth(this._sOriginalWidth); this.setMaxWidth(this._originalMaxWidth); return this; }; OverflowToolbarTokenizer.prototype._setPopoverMode = function () { const oPopup = Tokenizer.prototype.getTokensPopup.call(this); if (this.getRenderMode() !== RenderMode.Overflow) { oPopup.setPlacement(PlacementType.VerticalPreferredBottom); oPopup.setShowArrow(true); return; } oPopup.setShowArrow(false); oPopup.setPlacement(PlacementType.HorizontalPreferredRight); oPopup.setOffsetX(-10); // Avoid the Tokenizer popover ovarlap with the OverflowToolbar popover return; }; OverflowToolbarTokenizer.prototype.addPopupClasses = function(oPopup) { Tokenizer.prototype.addPopupClasses.call(this, oPopup); oPopup.addStyleClass(CSS_CLASS_OVERFLOWTOOLBAR_TOKENIZER_POPUP); }; OverflowToolbarTokenizer.prototype._getLabelWidth = function() { return this.getAggregation("label")?.getDomRef()?.offsetWidth || 0; }; OverflowToolbarTokenizer.prototype.onfocusin = function (oEvent) { if (this.getRenderMode() === RenderMode.Overflow) { return; } Tokenizer.prototype.onfocusin.call(this, oEvent); }; /** * Renders the n-More label. * @private * * @param {number} iHiddenTokensCount The number of hidden tokens */ OverflowToolbarTokenizer.prototype._handleNMoreIndicator = function (iHiddenTokensCount) { const oLabelText = this.getLabelText(); if (this.getRenderMode() !== RenderMode.Overflow) { Tokenizer.prototype._handleNMoreIndicator.call(this, iHiddenTokensCount); } if (this.getRenderMode() === RenderMode.Overflow && oLabelText) { this.getAggregation("moreItemsButton").setText(oLabelText); } }; OverflowToolbarTokenizer.prototype._handleTokenizerAfterOpen = function (oEvent) { if (this.getRenderMode() === RenderMode.Overflow) { return; } Tokenizer.prototype._handleTokenizerAfterOpen.call(this, oEvent); }; OverflowToolbarTokenizer.prototype.getOverflowToolbarConfig = function() { const oConfig = { canOverflow: true, propsUnrelatedToSize: ["hiddenTokensCount"], onBeforeEnterOverflow: function(oTokenizer) { oTokenizer.setOverflowMode(true); }, onAfterExitOverflow: function(oTokenizer) { oTokenizer.setOverflowMode(false); } }; return oConfig; }; /** * Required by the {@link sap.m.IToolbarInteractiveControl} interface. * Determines if the Control is interactive. * * @returns {boolean} If it is an interactive control * * @private * @ui5-restricted sap.m.OverflowToolbar, sap.m.Toolbar */ OverflowToolbarTokenizer.prototype._getToolbarInteractive = function () { return true; }; return OverflowToolbarTokenizer; });