1 |
|
2 |
|
3 | import { Signal } from '@lumino/signaling';
|
4 | import { Panel, PanelLayout, Widget } from '@lumino/widgets';
|
5 | import { caretDownIcon } from '../icon';
|
6 | const COLLAPSE_CLASS = 'jp-Collapse';
|
7 | const CONTENTS_CLASS = 'jp-Collapse-contents';
|
8 | const HEADER_CLASS = 'jp-Collapse-header';
|
9 | const HEADER_COLLAPSED_CLASS = 'jp-Collapse-header-collapsed';
|
10 | const ICON_CLASS = 'jp-Collapser-icon';
|
11 | const TITLE_CLASS = 'jp-Collapser-title';
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | export 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 |
|
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 |
|
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 |
|
79 |
|
80 | get collapseChanged() {
|
81 | return this._collapseChanged;
|
82 | }
|
83 | |
84 |
|
85 |
|
86 | toggle() {
|
87 | this.collapsed = !this.collapsed;
|
88 | }
|
89 | |
90 |
|
91 |
|
92 | dispose() {
|
93 | if (this.isDisposed) {
|
94 | return;
|
95 | }
|
96 |
|
97 | this._header = null;
|
98 | this._widget = null;
|
99 | this._content = null;
|
100 | super.dispose();
|
101 | }
|
102 | |
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
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 |
|
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 |
|
\ | No newline at end of file |