UNPKG

@jupyterlab/ui-components

Version:

JupyterLab - UI components written in React

161 lines 4.7 kB
// 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