UNPKG

12.4 kBJavaScriptView Raw
1"use strict";
2var __extends = (this && this.__extends) || (function () {
3 var extendStatics = function (d, b) {
4 extendStatics = Object.setPrototypeOf ||
5 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7 return extendStatics(d, b);
8 }
9 return function (d, b) {
10 extendStatics(d, b);
11 function __() { this.constructor = d; }
12 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13 };
14})();
15Object.defineProperty(exports, "__esModule", { value: true });
16/*-----------------------------------------------------------------------------
17| Copyright (c) 2014-2017, PhosphorJS Contributors
18|
19| Distributed under the terms of the BSD 3-Clause License.
20|
21| The full license is in the file LICENSE, distributed with this software.
22|----------------------------------------------------------------------------*/
23var domutils_1 = require("@phosphor/domutils");
24var messaging_1 = require("@phosphor/messaging");
25var signaling_1 = require("@phosphor/signaling");
26var boxlayout_1 = require("./boxlayout");
27var stackedpanel_1 = require("./stackedpanel");
28var tabbar_1 = require("./tabbar");
29var widget_1 = require("./widget");
30/**
31 * A widget which combines a `TabBar` and a `StackedPanel`.
32 *
33 * #### Notes
34 * This is a simple panel which handles the common case of a tab bar
35 * placed next to a content area. The selected tab controls the widget
36 * which is shown in the content area.
37 *
38 * For use cases which require more control than is provided by this
39 * panel, the `TabBar` widget may be used independently.
40 */
41var TabPanel = /** @class */ (function (_super) {
42 __extends(TabPanel, _super);
43 /**
44 * Construct a new tab panel.
45 *
46 * @param options - The options for initializing the tab panel.
47 */
48 function TabPanel(options) {
49 if (options === void 0) { options = {}; }
50 var _this = _super.call(this) || this;
51 _this._currentChanged = new signaling_1.Signal(_this);
52 _this.addClass('p-TabPanel');
53 // Create the tab bar and stacked panel.
54 _this.tabBar = new tabbar_1.TabBar(options);
55 _this.tabBar.addClass('p-TabPanel-tabBar');
56 _this.stackedPanel = new stackedpanel_1.StackedPanel();
57 _this.stackedPanel.addClass('p-TabPanel-stackedPanel');
58 // Connect the tab bar signal handlers.
59 _this.tabBar.tabMoved.connect(_this._onTabMoved, _this);
60 _this.tabBar.currentChanged.connect(_this._onCurrentChanged, _this);
61 _this.tabBar.tabCloseRequested.connect(_this._onTabCloseRequested, _this);
62 _this.tabBar.tabActivateRequested.connect(_this._onTabActivateRequested, _this);
63 // Connect the stacked panel signal handlers.
64 _this.stackedPanel.widgetRemoved.connect(_this._onWidgetRemoved, _this);
65 // Get the data related to the placement.
66 _this._tabPlacement = options.tabPlacement || 'top';
67 var direction = Private.directionFromPlacement(_this._tabPlacement);
68 var orientation = Private.orientationFromPlacement(_this._tabPlacement);
69 // Configure the tab bar for the placement.
70 _this.tabBar.orientation = orientation;
71 _this.tabBar.dataset['placement'] = _this._tabPlacement;
72 // Create the box layout.
73 var layout = new boxlayout_1.BoxLayout({ direction: direction, spacing: 0 });
74 // Set the stretch factors for the child widgets.
75 boxlayout_1.BoxLayout.setStretch(_this.tabBar, 0);
76 boxlayout_1.BoxLayout.setStretch(_this.stackedPanel, 1);
77 // Add the child widgets to the layout.
78 layout.addWidget(_this.tabBar);
79 layout.addWidget(_this.stackedPanel);
80 // Install the layout on the tab panel.
81 _this.layout = layout;
82 return _this;
83 }
84 Object.defineProperty(TabPanel.prototype, "currentChanged", {
85 /**
86 * A signal emitted when the current tab is changed.
87 *
88 * #### Notes
89 * This signal is emitted when the currently selected tab is changed
90 * either through user or programmatic interaction.
91 *
92 * Notably, this signal is not emitted when the index of the current
93 * tab changes due to tabs being inserted, removed, or moved. It is
94 * only emitted when the actual current tab node is changed.
95 */
96 get: function () {
97 return this._currentChanged;
98 },
99 enumerable: true,
100 configurable: true
101 });
102 Object.defineProperty(TabPanel.prototype, "currentIndex", {
103 /**
104 * Get the index of the currently selected tab.
105 *
106 * #### Notes
107 * This will be `-1` if no tab is selected.
108 */
109 get: function () {
110 return this.tabBar.currentIndex;
111 },
112 /**
113 * Set the index of the currently selected tab.
114 *
115 * #### Notes
116 * If the index is out of range, it will be set to `-1`.
117 */
118 set: function (value) {
119 this.tabBar.currentIndex = value;
120 },
121 enumerable: true,
122 configurable: true
123 });
124 Object.defineProperty(TabPanel.prototype, "currentWidget", {
125 /**
126 * Get the currently selected widget.
127 *
128 * #### Notes
129 * This will be `null` if there is no selected tab.
130 */
131 get: function () {
132 var title = this.tabBar.currentTitle;
133 return title ? title.owner : null;
134 },
135 /**
136 * Set the currently selected widget.
137 *
138 * #### Notes
139 * If the widget is not in the panel, it will be set to `null`.
140 */
141 set: function (value) {
142 this.tabBar.currentTitle = value ? value.title : null;
143 },
144 enumerable: true,
145 configurable: true
146 });
147 Object.defineProperty(TabPanel.prototype, "tabsMovable", {
148 /**
149 * Get the whether the tabs are movable by the user.
150 *
151 * #### Notes
152 * Tabs can always be moved programmatically.
153 */
154 get: function () {
155 return this.tabBar.tabsMovable;
156 },
157 /**
158 * Set the whether the tabs are movable by the user.
159 *
160 * #### Notes
161 * Tabs can always be moved programmatically.
162 */
163 set: function (value) {
164 this.tabBar.tabsMovable = value;
165 },
166 enumerable: true,
167 configurable: true
168 });
169 Object.defineProperty(TabPanel.prototype, "tabPlacement", {
170 /**
171 * Get the tab placement for the tab panel.
172 *
173 * #### Notes
174 * This controls the position of the tab bar relative to the content.
175 */
176 get: function () {
177 return this._tabPlacement;
178 },
179 /**
180 * Set the tab placement for the tab panel.
181 *
182 * #### Notes
183 * This controls the position of the tab bar relative to the content.
184 */
185 set: function (value) {
186 // Bail if the placement does not change.
187 if (this._tabPlacement === value) {
188 return;
189 }
190 // Update the internal value.
191 this._tabPlacement = value;
192 // Get the values related to the placement.
193 var direction = Private.directionFromPlacement(value);
194 var orientation = Private.orientationFromPlacement(value);
195 // Configure the tab bar for the placement.
196 this.tabBar.orientation = orientation;
197 this.tabBar.dataset['placement'] = value;
198 // Update the layout direction.
199 this.layout.direction = direction;
200 },
201 enumerable: true,
202 configurable: true
203 });
204 Object.defineProperty(TabPanel.prototype, "widgets", {
205 /**
206 * A read-only array of the widgets in the panel.
207 */
208 get: function () {
209 return this.stackedPanel.widgets;
210 },
211 enumerable: true,
212 configurable: true
213 });
214 /**
215 * Add a widget to the end of the tab panel.
216 *
217 * @param widget - The widget to add to the tab panel.
218 *
219 * #### Notes
220 * If the widget is already contained in the panel, it will be moved.
221 *
222 * The widget's `title` is used to populate the tab.
223 */
224 TabPanel.prototype.addWidget = function (widget) {
225 this.insertWidget(this.widgets.length, widget);
226 };
227 /**
228 * Insert a widget into the tab panel at a specified index.
229 *
230 * @param index - The index at which to insert the widget.
231 *
232 * @param widget - The widget to insert into to the tab panel.
233 *
234 * #### Notes
235 * If the widget is already contained in the panel, it will be moved.
236 *
237 * The widget's `title` is used to populate the tab.
238 */
239 TabPanel.prototype.insertWidget = function (index, widget) {
240 if (widget !== this.currentWidget) {
241 widget.hide();
242 }
243 this.stackedPanel.insertWidget(index, widget);
244 this.tabBar.insertTab(index, widget.title);
245 };
246 /**
247 * Handle the `currentChanged` signal from the tab bar.
248 */
249 TabPanel.prototype._onCurrentChanged = function (sender, args) {
250 // Extract the previous and current title from the args.
251 var previousIndex = args.previousIndex, previousTitle = args.previousTitle, currentIndex = args.currentIndex, currentTitle = args.currentTitle;
252 // Extract the widgets from the titles.
253 var previousWidget = previousTitle ? previousTitle.owner : null;
254 var currentWidget = currentTitle ? currentTitle.owner : null;
255 // Hide the previous widget.
256 if (previousWidget) {
257 previousWidget.hide();
258 }
259 // Show the current widget.
260 if (currentWidget) {
261 currentWidget.show();
262 }
263 // Emit the `currentChanged` signal for the tab panel.
264 this._currentChanged.emit({
265 previousIndex: previousIndex, previousWidget: previousWidget, currentIndex: currentIndex, currentWidget: currentWidget
266 });
267 // Flush the message loop on IE and Edge to prevent flicker.
268 if (domutils_1.Platform.IS_EDGE || domutils_1.Platform.IS_IE) {
269 messaging_1.MessageLoop.flush();
270 }
271 };
272 /**
273 * Handle the `tabActivateRequested` signal from the tab bar.
274 */
275 TabPanel.prototype._onTabActivateRequested = function (sender, args) {
276 args.title.owner.activate();
277 };
278 /**
279 * Handle the `tabCloseRequested` signal from the tab bar.
280 */
281 TabPanel.prototype._onTabCloseRequested = function (sender, args) {
282 args.title.owner.close();
283 };
284 /**
285 * Handle the `tabMoved` signal from the tab bar.
286 */
287 TabPanel.prototype._onTabMoved = function (sender, args) {
288 this.stackedPanel.insertWidget(args.toIndex, args.title.owner);
289 };
290 /**
291 * Handle the `widgetRemoved` signal from the stacked panel.
292 */
293 TabPanel.prototype._onWidgetRemoved = function (sender, widget) {
294 this.tabBar.removeTab(widget.title);
295 };
296 return TabPanel;
297}(widget_1.Widget));
298exports.TabPanel = TabPanel;
299/**
300 * The namespace for the module implementation details.
301 */
302var Private;
303(function (Private) {
304 /**
305 * Convert a tab placement to tab bar orientation.
306 */
307 function orientationFromPlacement(plc) {
308 return placementToOrientationMap[plc];
309 }
310 Private.orientationFromPlacement = orientationFromPlacement;
311 /**
312 * Convert a tab placement to a box layout direction.
313 */
314 function directionFromPlacement(plc) {
315 return placementToDirectionMap[plc];
316 }
317 Private.directionFromPlacement = directionFromPlacement;
318 /**
319 * A mapping of tab placement to tab bar orientation.
320 */
321 var placementToOrientationMap = {
322 'top': 'horizontal',
323 'left': 'vertical',
324 'right': 'vertical',
325 'bottom': 'horizontal'
326 };
327 /**
328 * A mapping of tab placement to box layout direction.
329 */
330 var placementToDirectionMap = {
331 'top': 'top-to-bottom',
332 'left': 'left-to-right',
333 'right': 'right-to-left',
334 'bottom': 'bottom-to-top'
335 };
336})(Private || (Private = {}));