UNPKG

@openui5/sap.m

Version:

OpenUI5 UI Library sap.m

422 lines (353 loc) 14.4 kB
/*! * UI development toolkit for HTML5 (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.m.Panel. sap.ui.define([ './library', 'sap/ui/core/Control', 'sap/ui/core/IconPool', './PanelRenderer' ], function(library, Control, IconPool, PanelRenderer) { "use strict"; // shortcut for sap.m.PanelAccessibleRole var PanelAccessibleRole = library.PanelAccessibleRole; // shortcut for sap.m.BackgroundDesign var BackgroundDesign = library.BackgroundDesign; /** * Constructor for a new Panel. * * @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 * A container control which has a header and content. * <h3>Overview</h3> * The panel is a container for grouping and displaying information. It can be collapsed to save space on the screen. * <h4>Guidelines:</h4> * <ul> * <li>Nesting two or more panels is not recommended.</li> * <li>Do not stack too many panels on one page.</li> * </ul> * <h3>Structure</h3> * A panel consists of a title bar with a header text or header toolbar, an info toolbar (optional), and a content area. * Using the <code>headerToolbar</code> aggregation, you can add a toolbar with any toolbar content (i.e. custom buttons, spacers, titles) inside the title bar. * * There are two types of panels: fixed and expandable. Expendable panels are enabled by the <code>expandable</code> property. * Furthermore you can define an expand animation with the property <code>expandAnimation</code>. * <h3>Usage</h3> * <h4>When to use:</h4> * <ul> * <li>You need to group or display information and want to give users the option of hiding this information.</li> * <li>You want to show additional information on demand (for example, a panel could show optional input fields for an advanced search).</li> * <li>You want to create a panel with controls that do not require user interaction and are not part of a form. Depending on the usage, change the <code>accessibleRole</code> property from the default <code>{@link sap.m.PanelAccessibleRole Form}</code> to <code>{@link sap.m.PanelAccessibleRole Region}</code> or <code>{@link sap.m.PanelAccessibleRole Complementary}</code>.</li> * </ul> * <h3>Responsive Behavior</h3> * <ul> * <li>If the width of the panel is set to 100% (default), the panel and its children are resized responsively, depending on its parent container.</li> * <li>If the panel has a fixed defined height, it will take up the space, even if the panel is collapsed.</li> * <li>When the panel is expandable, an arrow icon (pointing to the right) appears in front of the header.</li> * <li>When the animation is activated, expand/collapse uses a smooth animation to open or close the content area.</li> * <li>When the panel expands/collapses, the arrow icon rotates 90 degrees clockwise/counter-clockwise.</li> * <li>When the height uses the default property <code>auto</code>, the height of the content area is automatically adjusted to match the height of its content.</li> * <li>When the height of the panel is set to a fixed size, the content area can be scrolled through.</li> * </ul> * @extends sap.ui.core.Control * * @author SAP SE * @version 1.60.39 * * @constructor * @public * @since 1.16 * @alias sap.m.Panel * @see {@link fiori:https://experience.sap.com/fiori-design-web/panel/ Panel} * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel */ var Panel = Control.extend("sap.m.Panel", /** @lends sap.m.Panel.prototype */ { metadata: { library: "sap.m", properties: { /** * This property is used to set the header text of the Panel. * The "headerText" is visible in both expanded and collapsed state. * Note: This property is overwritten by the "headerToolbar" aggregation. */ headerText: {type: "string", group: "Data", defaultValue: ""}, /** * Determines the Panel width. */ width: {type: "sap.ui.core.CSSSize", group: "Appearance", defaultValue: "100%"}, /** * Determines the Panel height. */ height: {type: "sap.ui.core.CSSSize", group: "Appearance", defaultValue: "auto"}, /** * Specifies whether the control is expandable. * This allows for collapsing or expanding the infoToolbar (if available) and content of the Panel. * Note: If expandable is set to false, the Panel will always be rendered expanded. * @since 1.22 */ expandable: {type: "boolean", group: "Appearance", defaultValue: false}, /** * Indicates whether the Panel is expanded or not. * If expanded is set to true, then both the infoToolbar (if available) and the content are rendered. * If expanded is set to false, then only the headerText or headerToolbar is rendered. * @since 1.22 */ expanded: {type: "boolean", group: "Appearance", defaultValue: false}, /** * Indicates whether the transition between the expanded and the collapsed state of the control is animated. * By default the animation is enabled. * @since 1.26 */ expandAnimation: {type: "boolean", group: "Behavior", defaultValue: true}, /** * This property is used to set the background color of the Panel. * Depending on the theme you can change the state of the background from "Solid" over "Translucent" to "Transparent". * @since 1.30 */ backgroundDesign: {type: "sap.m.BackgroundDesign", group: "Appearance", defaultValue: BackgroundDesign.Translucent}, /** * This property is used to set the accessible aria role of the Panel. * Depending on the usage you can change the role from the default <code>Form</code> to <code>Region</code> or <code>Complementary</code>. * @since 1.46 */ accessibleRole: {type: "sap.m.PanelAccessibleRole", group: "Accessibility", defaultValue: PanelAccessibleRole.Form} }, defaultAggregation: "content", aggregations: { /** * Determines the content of the Panel. * The content will be visible only when the Panel is expanded. */ content: {type: "sap.ui.core.Control", multiple: true, singularName: "content"}, /** * This aggregation allows the use of a custom Toolbar as header for the Panel. * The "headerToolbar" is visible in both expanded and collapsed state. * Use it when you want to add extra controls for user interactions in the header. * Note: This aggregation overwrites "headerText" property. * @since 1.16 */ headerToolbar: {type: "sap.m.Toolbar", multiple: false}, /** * This aggregation allows the use of a custom Toolbar as information bar for the Panel. * The "infoToolbar" is placed below the header and is visible only in expanded state. * Use it when you want to show extra information to the user. * @since 1.16 */ infoToolbar: {type: "sap.m.Toolbar", multiple: false} }, events: { /** * Indicates that the panel will expand or collapse. * @since 1.22 */ expand: { parameters: { /** * If the panel will expand, this is true. * If the panel will collapse, this is false. */ expand: {type : "boolean"}, /** * Identifies whether the event is triggered by an user interaction or by calling setExpanded. * @since 1.50 */ triggeredByInteraction: {type: "boolean"} } } }, designtime: "sap/m/designtime/Panel.designtime" }}); Panel.prototype.init = function () { // identifies whether the last expand action is triggered by a user interaction or by calling setExpanded setter this._bInteractiveExpand = false; this.data("sap-ui-fastnavgroup", "true", true); // Define group for F6 handling }; /** * Sets the width of the panel. * @param {sap.ui.core.CSSSize} sWidth The width of the Panel as CSS size. * @returns {sap.m.Panel} Pointer to the control instance to allow method chaining. * @public */ Panel.prototype.setWidth = function (sWidth) { this.setProperty("width", sWidth, true); var oDomRef = this.getDomRef(); if (oDomRef) { oDomRef.style.width = sWidth; } return this; }; /** * Sets the height of the panel. * @param {sap.ui.core.CSSSize} sHeight The height of the panel as CSS size. * @returns {sap.m.Panel} Pointer to the control instance to allow method chaining. * @public */ Panel.prototype.setHeight = function (sHeight) { this.setProperty("height", sHeight, true); var oDomRef = this.getDomRef(); if (oDomRef) { oDomRef.style.height = sHeight; if (parseFloat(sHeight) != 0) { oDomRef.querySelector(".sapMPanelContent").style.height = sHeight; } this._setContentHeight(); } return this; }; Panel.prototype.onThemeChanged = function () { this._setContentHeight(); }; /** * Sets the expandable property of the control. * @param {boolean} bExpandable Defines whether the control is expandable or not. * @returns {sap.m.Panel} Pointer to the control instance to allow method chaining. * @public */ Panel.prototype.setExpandable = function (bExpandable) { this.setProperty("expandable", bExpandable, false); // rerender since we set certain css classes if (bExpandable && !this.oIconCollapsed) { this.oIconCollapsed = this._createIcon(); } return this; }; /** * Sets the expanded property of the control. * @param {boolean} bExpanded Defines whether control is expanded or not. * @returns {sap.m.Panel} Pointer to the control instance to allow method chaining. * @public */ Panel.prototype.setExpanded = function (bExpanded) { if (bExpanded === this.getExpanded()) { return this; } this.setProperty("expanded", bExpanded, true); if (!this.getExpandable()) { return this; } // ARIA this._getIcon().$().attr("aria-expanded", this.getExpanded()); this._toggleExpandCollapse(); this._toggleCssClasses(); this.fireExpand({ expand: bExpanded, triggeredByInteraction: this._bInteractiveExpand }); this._bInteractiveExpand = false; return this; }; /** * Sets the accessibleRole property of the control. * @param {sap.m.PanelAccessibleRole} sRole Defines the aria role of the control. * @returns {sap.m.Panel} Pointer to the control instance to allow method chaining. * @public */ Panel.prototype.setAccessibleRole = function (sRole) { if (sRole === this.getAccessibleRole()) { return this; } this.setProperty("accessibleRole", sRole, true); if (sap.ui.getCore().getConfiguration().getAccessibility()) { this.$().attr("role", this.getAccessibleRole().toLowerCase()); } return this; }; Panel.prototype.onBeforeRendering = function () { this._updateIconAriaLabelledBy(); }; Panel.prototype.onAfterRendering = function () { var $this = this.$(), $icon, oPanelContent = this.getDomRef("content"); this._setContentHeight(); if (this.getExpandable()) { $icon = this.oIconCollapsed.$(); oPanelContent && $icon.attr("aria-controls", oPanelContent.id); if (this.getExpanded()) { //ARIA $icon.attr("aria-expanded", "true"); } else { // hide those parts which are collapsible (w/o animation, otherwise initial loading doesn't look good ...) $this.children(".sapMPanelExpandablePart").hide(); //ARIA $icon.attr("aria-expanded", "false"); } } }; Panel.prototype.exit = function () { if (this.oIconCollapsed) { this.oIconCollapsed.destroy(); this.oIconCollapsed = null; } }; Panel.prototype._createIcon = function () { var that = this, sCollapsedIconURI = IconPool.getIconURI("navigation-right-arrow"), sTooltipBundleText = sap.ui.getCore().getLibraryResourceBundle("sap.m").getText("PANEL_ICON"); return IconPool.createControlByURI({ id: that.getId() + "-CollapsedImg", src: sCollapsedIconURI, decorative: false, press: function () { that._bInteractiveExpand = true; that.setExpanded(!that.getExpanded()); }, tooltip: sTooltipBundleText }).addStyleClass("sapMPanelExpandableIcon"); }; Panel.prototype._getIcon = function () { return this.oIconCollapsed; }; Panel.prototype._setContentHeight = function () { var sAdjustedContentHeight, thisDomRef = this.getDomRef(), oPanelContent = thisDomRef && thisDomRef.querySelector(".sapMPanelContent"); if (this.getHeight() === "auto" || !oPanelContent) { return; } // 'offsetTop' measures the vertical space occupied by siblings before this one // Earlier each previous sibling's height was calculated separately and then all height values were summed up sAdjustedContentHeight = 'calc(' + this.getHeight() + ' - ' + oPanelContent.offsetTop + 'px)'; oPanelContent.style.height = sAdjustedContentHeight; }; Panel.prototype._toggleExpandCollapse = function () { var oOptions = {}; if (!this.getExpandAnimation()) { oOptions.duration = 0; } this.$().children(".sapMPanelExpandablePart").slideToggle(oOptions); }; Panel.prototype._toggleCssClasses = function () { var $this = this.$(); // for controlling the visibility of the border $this.children(".sapMPanelWrappingDiv").toggleClass("sapMPanelWrappingDivExpanded"); $this.children(".sapMPanelWrappingDivTb").toggleClass("sapMPanelWrappingDivTbExpanded"); $this.find(".sapMPanelExpandableIcon").first().toggleClass("sapMPanelExpandableIconExpanded"); }; Panel.prototype._updateIconAriaLabelledBy = function () { var sLabelId, aAriaLabels, bFormRole; if (!this.oIconCollapsed) { return; } if (this.getAccessibleRole() === PanelAccessibleRole.Form) { bFormRole = true; } sLabelId = this._getLabellingElementId(); aAriaLabels = this.oIconCollapsed.getAriaLabelledBy(); // If the old label is different we should reinitialize the association, because we can have only one label if (aAriaLabels.indexOf(sLabelId) === -1) { this.oIconCollapsed.removeAllAssociation("ariaLabelledBy"); !bFormRole && this.oIconCollapsed.addAriaLabelledBy(sLabelId); } }; Panel.prototype._getLabellingElementId = function () { var headerToolbar = this.getHeaderToolbar(), id; if (headerToolbar) { id = headerToolbar.getTitleId(); } else { id = this.getId() + "-header"; } return id; }; return Panel; });