blob: 906c57f6ee0c448e85609a72d8ff326d0e789ada [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2013 The Chromium Authors
[email protected]31e91842013-11-08 19:06:152// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
rbpotter5796b002021-03-10 18:49:215// Creates a simple object containing the tab head and body elements.
6class TabDom {
7 constructor(h, b) {
8 this.head = h;
9 this.body = b;
10 }
11}
12
[email protected]31e91842013-11-08 19:06:1513/**
14 * A TabView provides the ability to create tabs and switch between tabs. It's
15 * responsible for creating the DOM and managing the visibility of each tab.
16 * The first added tab is active by default and the others hidden.
17 */
rbpotter5796b002021-03-10 18:49:2118export class TabView {
[email protected]31e91842013-11-08 19:06:1519 /**
[email protected]31e91842013-11-08 19:06:1520 * @param {Element} root The root DOM element containing the tabs.
21 */
rbpotter5796b002021-03-10 18:49:2122 constructor(root) {
[email protected]31e91842013-11-08 19:06:1523 this.root_ = root;
24 this.ACTIVE_TAB_HEAD_CLASS_ = 'active-tab-head';
25 this.ACTIVE_TAB_BODY_CLASS_ = 'active-tab-body';
26 this.TAB_HEAD_CLASS_ = 'tab-head';
27 this.TAB_BODY_CLASS_ = 'tab-body';
28
29 /**
30 * A mapping for an id to the tab elements.
thestig7779e7d2015-05-30 07:48:3031 * @type {!Object<!TabDom>}
[email protected]31e91842013-11-08 19:06:1532 * @private
33 */
34 this.tabElements_ = {};
35
36 this.headBar_ = null;
37 this.activeTabId_ = null;
38 this.initializeHeadBar_();
39 }
40
rbpotter5796b002021-03-10 18:49:2141 /**
42 * Adds a tab with the specified id and title.
43 * @param {string} id
44 * @param {string} title
45 * @return {!Element} The tab body element.
46 */
47 addTab(id, title) {
48 if (this.tabElements_[id]) {
49 throw 'Tab already exists: ' + id;
50 }
51
Philipp Hancke0635d3142021-03-16 20:02:0952 const head = document.createElement('span');
rbpotter5796b002021-03-10 18:49:2153 head.className = this.TAB_HEAD_CLASS_;
54 head.textContent = title;
55 head.title = title;
56 this.headBar_.appendChild(head);
57 head.addEventListener('click', this.switchTab_.bind(this, id));
58
Philipp Hancke0635d3142021-03-16 20:02:0959 const body = document.createElement('div');
rbpotter5796b002021-03-10 18:49:2160 body.className = this.TAB_BODY_CLASS_;
61 body.id = id;
62 this.root_.appendChild(body);
63
64 this.tabElements_[id] = new TabDom(head, body);
65
66 if (!this.activeTabId_) {
67 this.switchTab_(id);
68 }
69 return this.tabElements_[id].body;
[email protected]31e91842013-11-08 19:06:1570 }
71
rbpotter5796b002021-03-10 18:49:2172 /** Removes the tab. @param {string} id */
73 removeTab(id) {
74 if (!this.tabElements_[id]) {
75 return;
76 }
77 this.tabElements_[id].head.parentNode.removeChild(
78 this.tabElements_[id].head);
79 this.tabElements_[id].body.parentNode.removeChild(
80 this.tabElements_[id].body);
[email protected]31e91842013-11-08 19:06:1581
rbpotter5796b002021-03-10 18:49:2182 delete this.tabElements_[id];
83 if (this.activeTabId_ === id) {
84 this.switchTab_(Object.keys(this.tabElements_)[0]);
85 }
86 }
[email protected]31e91842013-11-08 19:06:1587
rbpotter5796b002021-03-10 18:49:2188 /**
89 * Switches the specified tab into view.
90 *
91 * @param {string} activeId The id the of the tab that should be switched to
92 * active state.
93 * @private
94 */
95 switchTab_(activeId) {
96 if (this.activeTabId_ && this.tabElements_[this.activeTabId_]) {
97 this.tabElements_[this.activeTabId_].body.classList.remove(
98 this.ACTIVE_TAB_BODY_CLASS_);
99 this.tabElements_[this.activeTabId_].head.classList.remove(
100 this.ACTIVE_TAB_HEAD_CLASS_);
101 }
102 this.activeTabId_ = activeId;
103 if (this.tabElements_[activeId]) {
104 this.tabElements_[activeId].body.classList.add(
105 this.ACTIVE_TAB_BODY_CLASS_);
106 this.tabElements_[activeId].head.classList.add(
107 this.ACTIVE_TAB_HEAD_CLASS_);
108 }
109 }
[email protected]31e91842013-11-08 19:06:15110
rbpotter5796b002021-03-10 18:49:21111 /** Initializes the bar containing the tab heads. */
112 initializeHeadBar_() {
113 this.headBar_ = document.createElement('div');
114 this.root_.appendChild(this.headBar_);
115 this.headBar_.style.textAlign = 'center';
116 }
Philipp Hancke0635d3142021-03-16 20:02:09117}