UNPKG

4.7 kBJavaScriptView Raw
1// Copyright (c) Jupyter Development Team.
2// Distributed under the terms of the Modified BSD License.
3import { Signal } from '@lumino/signaling';
4import { Panel, PanelLayout, Widget } from '@lumino/widgets';
5import { caretDownIcon } from '../icon';
6const COLLAPSE_CLASS = 'jp-Collapse';
7const CONTENTS_CLASS = 'jp-Collapse-contents';
8const HEADER_CLASS = 'jp-Collapse-header';
9const HEADER_COLLAPSED_CLASS = 'jp-Collapse-header-collapsed';
10const ICON_CLASS = 'jp-Collapser-icon';
11const TITLE_CLASS = 'jp-Collapser-title';
12/**
13 * A panel that supports a collapsible header made from the widget's title.
14 * Clicking on the title expands or contracts the widget.
15 */
16export class Collapser extends Widget {
17 constructor(options) {
18 super(options);
19 this._collapseChanged = new Signal(this);
20 const { widget, collapsed = true } = options;
21 this.addClass(COLLAPSE_CLASS);
22 this._header = new Widget();
23 this._header.addClass(HEADER_CLASS);
24 if (collapsed) {
25 this._header.addClass(HEADER_COLLAPSED_CLASS);
26 }
27 this._header.node.appendChild(caretDownIcon.element({
28 className: ICON_CLASS
29 }));
30 const titleSpan = document.createElement('span');
31 titleSpan.classList.add(TITLE_CLASS);
32 titleSpan.textContent = widget.title.label;
33 this._header.node.appendChild(titleSpan);
34 this._content = new Panel();
35 this._content.addClass(CONTENTS_CLASS);
36 const layout = new PanelLayout();
37 this.layout = layout;
38 layout.addWidget(this._header);
39 layout.addWidget(this._content);
40 this.widget = widget;
41 this.collapsed = collapsed;
42 }
43 /**
44 * The widget inside the collapse panel.
45 */
46 get widget() {
47 return this._widget;
48 }
49 set widget(widget) {
50 const oldWidget = this._widget;
51 if (oldWidget) {
52 oldWidget.title.changed.disconnect(this._onTitleChanged, this);
53 oldWidget.parent = null;
54 }
55 this._widget = widget;
56 widget.title.changed.connect(this._onTitleChanged, this);
57 this._onTitleChanged(widget.title);
58 this._content.addWidget(widget);
59 }
60 /**
61 * The collapsed state of the panel.
62 */
63 get collapsed() {
64 return this._collapsed;
65 }
66 set collapsed(value) {
67 if (value === this._collapsed) {
68 return;
69 }
70 if (value) {
71 this._collapse();
72 }
73 else {
74 this._uncollapse();
75 }
76 }
77 /**
78 * A signal for when the widget collapse state changes.
79 */
80 get collapseChanged() {
81 return this._collapseChanged;
82 }
83 /**
84 * Toggle the collapse state of the panel.
85 */
86 toggle() {
87 this.collapsed = !this.collapsed;
88 }
89 /**
90 * Dispose the widget.
91 */
92 dispose() {
93 if (this.isDisposed) {
94 return;
95 }
96 // Delete references we explicitly hold to other widgets.
97 this._header = null;
98 this._widget = null;
99 this._content = null;
100 super.dispose();
101 }
102 /**
103 * Handle the DOM events for the Collapser widget.
104 *
105 * @param event - The DOM event sent to the panel.
106 *
107 * #### Notes
108 * This method implements the DOM `EventListener` interface and is
109 * called in response to events on the panel's DOM node. It should
110 * not be called directly by user code.
111 */
112 handleEvent(event) {
113 switch (event.type) {
114 case 'click':
115 this._evtClick(event);
116 break;
117 default:
118 break;
119 }
120 }
121 onAfterAttach(msg) {
122 this._header.node.addEventListener('click', this);
123 }
124 onBeforeDetach(msg) {
125 this._header.node.removeEventListener('click', this);
126 }
127 _collapse() {
128 this._collapsed = true;
129 if (this._content) {
130 this._content.hide();
131 }
132 this._setHeader();
133 this._collapseChanged.emit(void 0);
134 }
135 _uncollapse() {
136 this._collapsed = false;
137 if (this._content) {
138 this._content.show();
139 }
140 this._setHeader();
141 this._collapseChanged.emit(void 0);
142 }
143 _evtClick(event) {
144 this.toggle();
145 }
146 /**
147 * Handle the `changed` signal of a title object.
148 */
149 _onTitleChanged(sender) {
150 this._setHeader();
151 }
152 _setHeader() {
153 if (this._collapsed) {
154 this._header.addClass(HEADER_COLLAPSED_CLASS);
155 }
156 else {
157 this._header.removeClass(HEADER_COLLAPSED_CLASS);
158 }
159 }
160}
161//# sourceMappingURL=collapser.js.map
\No newline at end of file