UNPKG

@openui5/sap.tnt

Version:

OpenUI5 UI Library sap.tnt

499 lines (423 loc) 14 kB
/*! * OpenUI5 * (c) Copyright 2009-2022 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ // Provides control sap.t.SideNavigation. sap.ui.define([ './library', 'sap/ui/core/Control', 'sap/ui/core/ResizeHandler', "sap/ui/core/theming/Parameters", 'sap/ui/core/Icon', 'sap/ui/core/delegate/ScrollEnablement', "./SideNavigationRenderer" ], function( library, Control, ResizeHandler, Parameters, Icon, ScrollEnablement, SideNavigationRenderer ) { 'use strict'; /** * Constructor for a new SideNavigation. * * @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 * The SideNavigation control is a container, which consists of flexible and fixed parts on top of each other. * <h4>Responsive Behavior</h4> * <ul> * <li>The flexible part adapts its size to the fixed one.</li> * <li>The flexible part has a scrollbar when the content is larger than the available space.</li> * </ul> *<b>Note:</b> In order for the SideNavigation to stretch properly, its parent layout control should only be the sap.tnt.ToolPage. * @extends sap.ui.core.Control * * @author SAP SE * @version 1.102.10 * * @constructor * @public * @since 1.34 * @alias sap.tnt.SideNavigation * @see {@link fiori:https://experience.sap.com/fiori-design-web/side-navigation/ Side Navigation} * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel */ var SideNavigation = Control.extend('sap.tnt.SideNavigation', /** @lends sap.t.SideNavigation.prototype */ { metadata: { library: 'sap.tnt', properties: { /** * Specifies if the control is expanded. */ expanded: {type: 'boolean', group: 'Misc', defaultValue: true}, /** * Specifies the currently selected key. * * @since 1.62.0 */ selectedKey: {type: "string", group: "Data"}, /** * Specifies an optional aria-label that can be used by the screen readers. * @since 1.98 */ ariaLabel: {type : "string", group : "Accessibility", defaultValue : null} }, defaultAggregation: "item", aggregations: { /** * Defines the content inside the flexible part. */ item: {type: 'sap.tnt.NavigationList', multiple: false, bindable: "bindable"}, /** * Defines the content inside the fixed part. */ fixedItem: {type: 'sap.tnt.NavigationList', multiple: false}, /** * Defines the content inside the footer. */ footer: {type: 'sap.tnt.NavigationList', multiple: false}, /** * The top arrow, used for scrolling throw items when SideNavigation is collapsed. */ _topArrowControl: {type: "sap.ui.core.Icon", multiple: false, visibility: "hidden"}, /** * The bottom arrow, used for scrolling throw items when SideNavigation is collapsed. */ _bottomArrowControl: {type: "sap.ui.core.Icon", multiple: false, visibility: "hidden"} }, associations: { /** * The selected <code>NavigationListItem</code>. * * @since 1.52.0 */ selectedItem: {type: "sap.tnt.NavigationListItem", multiple: false} }, events: { /** * Fired when an item is selected. */ itemSelect: { parameters: { /** * The selected item. */ item: {type: 'sap.ui.core.Item'} } } } } }); SideNavigation.prototype.init = function () { this._scroller = new ScrollEnablement(this, this.getId() + "-Flexible-Content", { horizontal: false, vertical: true }); // Define group for F6 handling this.data('sap-ui-fastnavgroup', 'true', true); }; // event listener for theme changed SideNavigation.prototype.onThemeChanged = function() { this._mThemeParams = null; this._initThemeParams(); }; SideNavigation.prototype.setAggregation = function (aggregationName, object) { if (object && object.attachItemSelect) { object.attachItemSelect(this._itemSelectionHandler.bind(this)); } return Control.prototype.setAggregation.apply(this, arguments); }; /** * Sets if the control is in expanded or collapsed mode. * * @public * @param {boolean} isExpanded Indication if the SideNavigation is expanded. * @returns {this} this SideNavigation reference for chaining. */ SideNavigation.prototype.setExpanded = function (isExpanded) { if (this.getExpanded() === isExpanded) { return this; } var that = this, $this = this.$(), itemAggregation = that.getAggregation('item'), fixedItemAggregation = that.getAggregation('fixedItem'), themeParams, expandedWidth, collapsedWidth, width; if (!this.getDomRef()) { this.setProperty('expanded', isExpanded); if (itemAggregation) { itemAggregation.setExpanded(isExpanded); } if (fixedItemAggregation) { fixedItemAggregation.setExpanded(isExpanded); } return this; } this.setProperty('expanded', isExpanded, true); if (that._hasActiveAnimation) { that._finishAnimation(!isExpanded); $this.stop(); } if (isExpanded) { this.getDomRef().classList.toggle('sapTntSideNavigationNotExpanded', !isExpanded); if (itemAggregation) { itemAggregation.setExpanded(isExpanded); } if (fixedItemAggregation) { fixedItemAggregation.setExpanded(isExpanded); } } else { // hide scroller during collapsing animation this._scroller.setVertical(false); } that._hasActiveAnimation = true; themeParams = this._mThemeParams || {}; expandedWidth = themeParams['_sap_tnt_SideNavigation_Width'] || "15rem"; collapsedWidth = themeParams['_sap_tnt_SideNavigation_CollapsedWidth'] || "3rem"; width = isExpanded ? expandedWidth : collapsedWidth; $this.animate({ width: width }, { duration: 300, complete: function () { var isExpanded = that.getExpanded(); that._finishAnimation(isExpanded); } }); return this; }; /** * @private */ SideNavigation.prototype._finishAnimation = function (isExpanded) { if (!this._hasActiveAnimation || !this.getDomRef()) { return; } this.getDomRef().classList.toggle('sapTntSideNavigationNotExpandedWidth', !isExpanded); if (!isExpanded) { this.getDomRef().classList.toggle('sapTntSideNavigationNotExpanded', !isExpanded); if (this.getAggregation('item')) { this.getAggregation('item').setExpanded(isExpanded); } if (this.getAggregation('fixedItem')) { this.getAggregation('fixedItem').setExpanded(isExpanded); } // enable back the scroller after collapsing animation this._scroller.setVertical(true); } this.$().css('width', ''); this._hasActiveAnimation = false; // wait for any re-rendering after the animation, before calling toggle arrows setTimeout(this._toggleArrows.bind(this), 0); }; SideNavigation.prototype._initThemeParams = function() { this._mThemeParams = Parameters.get({ name: ["_sap_tnt_SideNavigation_Width", "_sap_tnt_SideNavigation_CollapsedWidth"], callback: function (mParams) { this._mThemeParams = mParams; }.bind(this) }); }; /** * @private */ SideNavigation.prototype.onBeforeRendering = function () { var selectedItem = this.getSelectedItem(), selectedKey = this.getSelectedKey(); if (selectedKey) { this.setSelectedKey(selectedKey); } else if (selectedItem) { this.setSelectedItem(selectedItem); } this._deregisterControl(); if (!this._mThemeParams) { this._initThemeParams(); } }; /** * @private */ SideNavigation.prototype.onAfterRendering = function () { this._ResizeHandler = ResizeHandler.register(this.getDomRef(), this._toggleArrows.bind(this)); this._toggleArrows(); }; /** * Sets the selected item based on a key. * @public * @param {string} selectedKey The key of the item to be selected * @return {this} this pointer for chaining */ SideNavigation.prototype.setSelectedKey = function (selectedKey) { var selectedItem, navigationList = this.getItem(), fixedNavigationList = this.getFixedItem(); if (selectedKey && navigationList) { selectedItem = navigationList._findItemByKey(selectedKey); if (!selectedItem && fixedNavigationList) { selectedItem = fixedNavigationList._findItemByKey(selectedKey); } } if (selectedItem) { this.setSelectedItem(selectedItem); } this.setProperty('selectedKey', selectedKey, true); return this; }; /** * Sets the association for selectedItem * @public * @param {string|sap.tnt.NavigationListItem} selectedItem The control to be set as selected * @return {sap.tnt.SideNavigation|null} The <code>selectedItem</code> association */ SideNavigation.prototype.setSelectedItem = function (selectedItem) { var navigationList = this.getAggregation('item'); var fixedNavigationList = this.getAggregation('fixedItem'); var listItemToSelect; var selectedKey; if (!selectedItem) { if (navigationList) { navigationList.setSelectedItem(null); } if (fixedNavigationList) { fixedNavigationList.setSelectedItem(null); } } if (typeof selectedItem === 'string') { listItemToSelect = sap.ui.getCore().byId(selectedItem); } else { listItemToSelect = selectedItem; } selectedKey = listItemToSelect ? listItemToSelect._getUniqueKey() : ''; this.setProperty('selectedKey', selectedKey, true); var selectedInFlexibleList = listItemToSelect && listItemToSelect.getNavigationList && listItemToSelect.getNavigationList() === navigationList; var selectedInFixedList = listItemToSelect && listItemToSelect.getNavigationList && listItemToSelect.getNavigationList() === fixedNavigationList; if (selectedInFlexibleList) { navigationList.setSelectedItem(listItemToSelect); if (fixedNavigationList) { fixedNavigationList.setSelectedKey(null); } } if (selectedInFixedList) { fixedNavigationList.setSelectedItem(listItemToSelect); if (navigationList) { navigationList.setSelectedKey(null); } } return Control.prototype.setAssociation.call(this, 'selectedItem', listItemToSelect, true); }; /** * @private */ SideNavigation.prototype.exit = function () { if (this._scroller) { this._scroller.destroy(); this._scroller = null; } this._mThemeParams = null; this._deregisterControl(); }; /** * * @param event * @private */ SideNavigation.prototype._itemSelectionHandler = function (event) { var item = event.getParameter('item'); this.setSelectedItem(item); this.fireItemSelect({ item: item }); }; /** * @private */ SideNavigation.prototype._deregisterControl = function () { if (this._ResizeHandler) { ResizeHandler.deregister(this._ResizeHandler); this._ResizeHandler = null; } }; /** * Returns the sap.ui.core.Icon control used to display the group icon. * @returns {sap.ui.core.Icon} * @private */ SideNavigation.prototype._getTopArrowControl = function () { var iconControl = this.getAggregation('_topArrowControl'); var that = this; if (!iconControl) { iconControl = new Icon({ src: 'sap-icon://navigation-up-arrow', noTabStop: true, useIconTooltip: false, tooltip: '', press: this._arrowPress.bind(that) }).addStyleClass('sapTntSideNavigationScrollIcon sapTntSideNavigationScrollIconUp'); this.setAggregation("_topArrowControl", iconControl, true); } return iconControl; }; /** * Returns the sap.ui.core.Icon control used to display the group icon. * @returns {sap.ui.core.Icon} * @private */ SideNavigation.prototype._getBottomArrowControl = function () { var iconControl = this.getAggregation('_bottomArrowControl'); var that = this; if (!iconControl) { iconControl = new Icon({ src: 'sap-icon://navigation-down-arrow', noTabStop: true, useIconTooltip: false, tooltip: '', press: this._arrowPress.bind(that) }).addStyleClass('sapTntSideNavigationScrollIcon sapTntSideNavigationScrollIconDown'); this.setAggregation("_bottomArrowControl", iconControl, true); } return iconControl; }; SideNavigation.prototype._toggleArrows = function () { var domRef = this.getDomRef(); if (!domRef) { return; } var scrollContainerWrapper = this.$('Flexible')[0]; var scrollContainerContent = this.$('Flexible-Content')[0]; var isAsideExpanded = this.getExpanded(); if (this._hasActiveAnimation) { domRef.querySelector('.sapTntSideNavigationScrollIconUp').style.display = 'none'; domRef.querySelector('.sapTntSideNavigationScrollIconDown').style.display = 'none'; return; } if ((scrollContainerContent.offsetHeight > scrollContainerWrapper.offsetHeight) && !isAsideExpanded) { domRef.querySelector('.sapTntSideNavigationScrollIconUp').style.display = 'block'; domRef.querySelector('.sapTntSideNavigationScrollIconDown').style.display = 'block'; domRef.querySelector('.sapTntSideNavigationScrollIconDown').classList.remove('sapTntSideNavigationScrollIconDisabled'); } else { domRef.querySelector('.sapTntSideNavigationScrollIconUp').style.display = 'none'; domRef.querySelector('.sapTntSideNavigationScrollIconDown').style.display = 'none'; } }; SideNavigation.prototype._arrowPress = function (event) { event.preventDefault(); var source = event.getSource().getDomRef(); var isDirectionForward = source.classList.contains('sapTntSideNavigationScrollIconDown') ? true : false; var $container = this.$('Flexible'); var step = isDirectionForward ? 40 : -40; $container[0].scrollTop += step; }; return SideNavigation; } );