UNPKG

@phosphor/widgets

Version:
337 lines (336 loc) 12.4 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); } return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); /*----------------------------------------------------------------------------- | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ var domutils_1 = require("@phosphor/domutils"); var messaging_1 = require("@phosphor/messaging"); var signaling_1 = require("@phosphor/signaling"); var boxlayout_1 = require("./boxlayout"); var stackedpanel_1 = require("./stackedpanel"); var tabbar_1 = require("./tabbar"); var widget_1 = require("./widget"); /** * A widget which combines a `TabBar` and a `StackedPanel`. * * #### Notes * This is a simple panel which handles the common case of a tab bar * placed next to a content area. The selected tab controls the widget * which is shown in the content area. * * For use cases which require more control than is provided by this * panel, the `TabBar` widget may be used independently. */ var TabPanel = /** @class */ (function (_super) { __extends(TabPanel, _super); /** * Construct a new tab panel. * * @param options - The options for initializing the tab panel. */ function TabPanel(options) { if (options === void 0) { options = {}; } var _this = _super.call(this) || this; _this._currentChanged = new signaling_1.Signal(_this); _this.addClass('p-TabPanel'); // Create the tab bar and stacked panel. _this.tabBar = new tabbar_1.TabBar(options); _this.tabBar.addClass('p-TabPanel-tabBar'); _this.stackedPanel = new stackedpanel_1.StackedPanel(); _this.stackedPanel.addClass('p-TabPanel-stackedPanel'); // Connect the tab bar signal handlers. _this.tabBar.tabMoved.connect(_this._onTabMoved, _this); _this.tabBar.currentChanged.connect(_this._onCurrentChanged, _this); _this.tabBar.tabCloseRequested.connect(_this._onTabCloseRequested, _this); _this.tabBar.tabActivateRequested.connect(_this._onTabActivateRequested, _this); // Connect the stacked panel signal handlers. _this.stackedPanel.widgetRemoved.connect(_this._onWidgetRemoved, _this); // Get the data related to the placement. _this._tabPlacement = options.tabPlacement || 'top'; var direction = Private.directionFromPlacement(_this._tabPlacement); var orientation = Private.orientationFromPlacement(_this._tabPlacement); // Configure the tab bar for the placement. _this.tabBar.orientation = orientation; _this.tabBar.dataset['placement'] = _this._tabPlacement; // Create the box layout. var layout = new boxlayout_1.BoxLayout({ direction: direction, spacing: 0 }); // Set the stretch factors for the child widgets. boxlayout_1.BoxLayout.setStretch(_this.tabBar, 0); boxlayout_1.BoxLayout.setStretch(_this.stackedPanel, 1); // Add the child widgets to the layout. layout.addWidget(_this.tabBar); layout.addWidget(_this.stackedPanel); // Install the layout on the tab panel. _this.layout = layout; return _this; } Object.defineProperty(TabPanel.prototype, "currentChanged", { /** * A signal emitted when the current tab is changed. * * #### Notes * This signal is emitted when the currently selected tab is changed * either through user or programmatic interaction. * * Notably, this signal is not emitted when the index of the current * tab changes due to tabs being inserted, removed, or moved. It is * only emitted when the actual current tab node is changed. */ get: function () { return this._currentChanged; }, enumerable: true, configurable: true }); Object.defineProperty(TabPanel.prototype, "currentIndex", { /** * Get the index of the currently selected tab. * * #### Notes * This will be `-1` if no tab is selected. */ get: function () { return this.tabBar.currentIndex; }, /** * Set the index of the currently selected tab. * * #### Notes * If the index is out of range, it will be set to `-1`. */ set: function (value) { this.tabBar.currentIndex = value; }, enumerable: true, configurable: true }); Object.defineProperty(TabPanel.prototype, "currentWidget", { /** * Get the currently selected widget. * * #### Notes * This will be `null` if there is no selected tab. */ get: function () { var title = this.tabBar.currentTitle; return title ? title.owner : null; }, /** * Set the currently selected widget. * * #### Notes * If the widget is not in the panel, it will be set to `null`. */ set: function (value) { this.tabBar.currentTitle = value ? value.title : null; }, enumerable: true, configurable: true }); Object.defineProperty(TabPanel.prototype, "tabsMovable", { /** * Get the whether the tabs are movable by the user. * * #### Notes * Tabs can always be moved programmatically. */ get: function () { return this.tabBar.tabsMovable; }, /** * Set the whether the tabs are movable by the user. * * #### Notes * Tabs can always be moved programmatically. */ set: function (value) { this.tabBar.tabsMovable = value; }, enumerable: true, configurable: true }); Object.defineProperty(TabPanel.prototype, "tabPlacement", { /** * Get the tab placement for the tab panel. * * #### Notes * This controls the position of the tab bar relative to the content. */ get: function () { return this._tabPlacement; }, /** * Set the tab placement for the tab panel. * * #### Notes * This controls the position of the tab bar relative to the content. */ set: function (value) { // Bail if the placement does not change. if (this._tabPlacement === value) { return; } // Update the internal value. this._tabPlacement = value; // Get the values related to the placement. var direction = Private.directionFromPlacement(value); var orientation = Private.orientationFromPlacement(value); // Configure the tab bar for the placement. this.tabBar.orientation = orientation; this.tabBar.dataset['placement'] = value; // Update the layout direction. this.layout.direction = direction; }, enumerable: true, configurable: true }); Object.defineProperty(TabPanel.prototype, "widgets", { /** * A read-only array of the widgets in the panel. */ get: function () { return this.stackedPanel.widgets; }, enumerable: true, configurable: true }); /** * Add a widget to the end of the tab panel. * * @param widget - The widget to add to the tab panel. * * #### Notes * If the widget is already contained in the panel, it will be moved. * * The widget's `title` is used to populate the tab. */ TabPanel.prototype.addWidget = function (widget) { this.insertWidget(this.widgets.length, widget); }; /** * Insert a widget into the tab panel at a specified index. * * @param index - The index at which to insert the widget. * * @param widget - The widget to insert into to the tab panel. * * #### Notes * If the widget is already contained in the panel, it will be moved. * * The widget's `title` is used to populate the tab. */ TabPanel.prototype.insertWidget = function (index, widget) { if (widget !== this.currentWidget) { widget.hide(); } this.stackedPanel.insertWidget(index, widget); this.tabBar.insertTab(index, widget.title); }; /** * Handle the `currentChanged` signal from the tab bar. */ TabPanel.prototype._onCurrentChanged = function (sender, args) { // Extract the previous and current title from the args. var previousIndex = args.previousIndex, previousTitle = args.previousTitle, currentIndex = args.currentIndex, currentTitle = args.currentTitle; // Extract the widgets from the titles. var previousWidget = previousTitle ? previousTitle.owner : null; var currentWidget = currentTitle ? currentTitle.owner : null; // Hide the previous widget. if (previousWidget) { previousWidget.hide(); } // Show the current widget. if (currentWidget) { currentWidget.show(); } // Emit the `currentChanged` signal for the tab panel. this._currentChanged.emit({ previousIndex: previousIndex, previousWidget: previousWidget, currentIndex: currentIndex, currentWidget: currentWidget }); // Flush the message loop on IE and Edge to prevent flicker. if (domutils_1.Platform.IS_EDGE || domutils_1.Platform.IS_IE) { messaging_1.MessageLoop.flush(); } }; /** * Handle the `tabActivateRequested` signal from the tab bar. */ TabPanel.prototype._onTabActivateRequested = function (sender, args) { args.title.owner.activate(); }; /** * Handle the `tabCloseRequested` signal from the tab bar. */ TabPanel.prototype._onTabCloseRequested = function (sender, args) { args.title.owner.close(); }; /** * Handle the `tabMoved` signal from the tab bar. */ TabPanel.prototype._onTabMoved = function (sender, args) { this.stackedPanel.insertWidget(args.toIndex, args.title.owner); }; /** * Handle the `widgetRemoved` signal from the stacked panel. */ TabPanel.prototype._onWidgetRemoved = function (sender, widget) { this.tabBar.removeTab(widget.title); }; return TabPanel; }(widget_1.Widget)); exports.TabPanel = TabPanel; /** * The namespace for the module implementation details. */ var Private; (function (Private) { /** * Convert a tab placement to tab bar orientation. */ function orientationFromPlacement(plc) { return placementToOrientationMap[plc]; } Private.orientationFromPlacement = orientationFromPlacement; /** * Convert a tab placement to a box layout direction. */ function directionFromPlacement(plc) { return placementToDirectionMap[plc]; } Private.directionFromPlacement = directionFromPlacement; /** * A mapping of tab placement to tab bar orientation. */ var placementToOrientationMap = { 'top': 'horizontal', 'left': 'vertical', 'right': 'vertical', 'bottom': 'horizontal' }; /** * A mapping of tab placement to box layout direction. */ var placementToDirectionMap = { 'top': 'top-to-bottom', 'left': 'left-to-right', 'right': 'right-to-left', 'bottom': 'bottom-to-top' }; })(Private || (Private = {}));