@jupyterlab/ui-components
Version:
JupyterLab - UI components written in React
161 lines • 4.7 kB
JavaScript
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
import { Signal } from '@lumino/signaling';
import { Panel, PanelLayout, Widget } from '@lumino/widgets';
import { caretDownIcon } from '../icon';
const COLLAPSE_CLASS = 'jp-Collapse';
const CONTENTS_CLASS = 'jp-Collapse-contents';
const HEADER_CLASS = 'jp-Collapse-header';
const HEADER_COLLAPSED_CLASS = 'jp-Collapse-header-collapsed';
const ICON_CLASS = 'jp-Collapser-icon';
const TITLE_CLASS = 'jp-Collapser-title';
/**
* A panel that supports a collapsible header made from the widget's title.
* Clicking on the title expands or contracts the widget.
*/
export class Collapser extends Widget {
constructor(options) {
super(options);
this._collapseChanged = new Signal(this);
const { widget, collapsed = true } = options;
this.addClass(COLLAPSE_CLASS);
this._header = new Widget();
this._header.addClass(HEADER_CLASS);
if (collapsed) {
this._header.addClass(HEADER_COLLAPSED_CLASS);
}
this._header.node.appendChild(caretDownIcon.element({
className: ICON_CLASS
}));
const titleSpan = document.createElement('span');
titleSpan.classList.add(TITLE_CLASS);
titleSpan.textContent = widget.title.label;
this._header.node.appendChild(titleSpan);
this._content = new Panel();
this._content.addClass(CONTENTS_CLASS);
const layout = new PanelLayout();
this.layout = layout;
layout.addWidget(this._header);
layout.addWidget(this._content);
this.widget = widget;
this.collapsed = collapsed;
}
/**
* The widget inside the collapse panel.
*/
get widget() {
return this._widget;
}
set widget(widget) {
const oldWidget = this._widget;
if (oldWidget) {
oldWidget.title.changed.disconnect(this._onTitleChanged, this);
oldWidget.parent = null;
}
this._widget = widget;
widget.title.changed.connect(this._onTitleChanged, this);
this._onTitleChanged(widget.title);
this._content.addWidget(widget);
}
/**
* The collapsed state of the panel.
*/
get collapsed() {
return this._collapsed;
}
set collapsed(value) {
if (value === this._collapsed) {
return;
}
if (value) {
this._collapse();
}
else {
this._uncollapse();
}
}
/**
* A signal for when the widget collapse state changes.
*/
get collapseChanged() {
return this._collapseChanged;
}
/**
* Toggle the collapse state of the panel.
*/
toggle() {
this.collapsed = !this.collapsed;
}
/**
* Dispose the widget.
*/
dispose() {
if (this.isDisposed) {
return;
}
// Delete references we explicitly hold to other widgets.
this._header = null;
this._widget = null;
this._content = null;
super.dispose();
}
/**
* Handle the DOM events for the Collapser widget.
*
* @param event - The DOM event sent to the panel.
*
* #### Notes
* This method implements the DOM `EventListener` interface and is
* called in response to events on the panel's DOM node. It should
* not be called directly by user code.
*/
handleEvent(event) {
switch (event.type) {
case 'click':
this._evtClick(event);
break;
default:
break;
}
}
onAfterAttach(msg) {
this._header.node.addEventListener('click', this);
}
onBeforeDetach(msg) {
this._header.node.removeEventListener('click', this);
}
_collapse() {
this._collapsed = true;
if (this._content) {
this._content.hide();
}
this._setHeader();
this._collapseChanged.emit(void 0);
}
_uncollapse() {
this._collapsed = false;
if (this._content) {
this._content.show();
}
this._setHeader();
this._collapseChanged.emit(void 0);
}
_evtClick(event) {
this.toggle();
}
/**
* Handle the `changed` signal of a title object.
*/
_onTitleChanged(sender) {
this._setHeader();
}
_setHeader() {
if (this._collapsed) {
this._header.addClass(HEADER_COLLAPSED_CLASS);
}
else {
this._header.removeClass(HEADER_COLLAPSED_CLASS);
}
}
}
//# sourceMappingURL=collapser.js.map