import { ArrayExt } from '@lumino/algorithm' ; import { ISignal , Signal } from '@lumino/signaling' ; import { Panel , PanelLayout , Widget , Title } from '@lumino/widgets' ; import { Selection } from './currentselection' ; /**
 * The class name added to Collapse instances.
 */ const COLLAPSE_CLASS = 'p-Collapse' ; /**
 * The class name added to a Collapse's header.
 */ const COLLAPSE_HEADER_CLASS = 'p-Collapse-header' ; /**
 * The class name added to a Collapse's contents.
 */ const COLLAPSE_CONTENTS_CLASS = 'p-Collapse-contents' ; /**
 * The class name added to a Collapse when it is opened
 */ const COLLAPSE_CLASS_OPEN = 'p-Collapse-open' ; /**
 * A panel that supports a collapsible header, made from the widget's title.
 * Clicking on the title expands or contracts the widget.
 */ export class Collapse extends Widget { constructor ( options ) { super ( options ) ; this . addClass ( COLLAPSE_CLASS ) ; this . _header = new Widget ( ) ; this . _header . addClass ( COLLAPSE_HEADER_CLASS ) ; this . _header . node . addEventListener ( 'click' , this ) ; const icon = document . createElement ( 'i' ) ; icon . classList . add ( 'fa' , 'fa-fw' , 'fa-caret-right' ) ; this . _header . node . appendChild ( icon ) ; this . _header . node . appendChild ( document . createElement ( 'span' ) ) ; this . _content = new Panel ( ) ; this . _content . addClass ( COLLAPSE_CONTENTS_CLASS ) ; const layout = new PanelLayout ( ) ; this . layout = layout ; layout . addWidget ( this . _header ) ; layout . addWidget ( this . _content ) ; if ( options . widget ) { this . widget = options . widget ; } this . collapsed = false ; } dispose ( ) { if ( this . isDisposed ) { return ; } super . dispose ( ) ; this . _header = null ! ; this . _widget = null ! ; this . _content = null ! ; } get widget ( ) : Widget { return this . _widget ; } set widget ( widget ) { const oldWidget = this . _widget ; if ( oldWidget ) { oldWidget . disposed . disconnect ( this . _onChildDisposed , this ) ; oldWidget . title . changed . disconnect ( this . _onTitleChanged , this ) ; oldWidget . parent = null ; } this . _widget = widget ; widget . disposed . connect ( this . _onChildDisposed , this ) ; widget . title . changed . connect ( this . _onTitleChanged , this ) ; this . _onTitleChanged ( widget . title ) ; this . _content . addWidget ( widget ) ; } get collapsed ( ) : boolean { return this . _collapsed ; } set collapsed ( value ) { if ( value === this . _collapsed ) { return ; } if ( value ) { this . _collapse ( ) ; } else { this . _uncollapse ( ) ; } } toggle ( ) { this . collapsed = ! this . collapsed ; } get collapseChanged ( ) : ISignal < Collapse , void > { return this . _collapseChanged ; } private _collapse ( ) { this . _collapsed = true ; if ( this . _content ) { this . _content . hide ( ) ; } this . removeClass ( COLLAPSE_CLASS_OPEN ) ; this . _header . node . children [ 0 ] . classList . add ( 'fa-caret-right' ) ; this . _header . node . children [ 0 ] . classList . remove ( 'fa-caret-down' ) ; this . _collapseChanged . emit ( void 0 ) ; } private _uncollapse ( ) { this . _collapsed = false ; if ( this . _content ) { this . _content . show ( ) ; } this . addClass ( COLLAPSE_CLASS_OPEN ) ; this . _header . node . children [ 0 ] . classList . add ( 'fa-caret-down' ) ; this . _header . node . children [ 0 ] . classList . remove ( 'fa-caret-right' ) ; this . _collapseChanged . emit ( void 0 ) ; } param event handleEvent ( event ) { switch ( event . type ) { case 'click' : this . _evtClick ( event as MouseEvent ) ; break ; default : break ; } } private _evtClick ( event ) { this . toggle ( ) ; } /**
     * Handle the `changed` signal of a title object.
     */ private _onTitleChanged ( sender ) { this . _header . node . children [ 1 ] . textContent = this . _widget . title . label ; } private _onChildDisposed ( sender ) { this . dispose ( ) ; } private _collapseChanged = new Signal < Collapse , void > ( this ) ; _collapsed : boolean ; _content : Panel ; _widget : Widget ; _header : Widget ; } export namespace Collapse { export interface IOptions extends Widget . IOptions { widget : Widget ; } } /**
 * The class name added to Accordion instances.
 */ const ACCORDION_CLASS = 'p-Accordion' ; /**
 * The class name added to an Accordion child.
 */ const ACCORDION_CHILD_CLASS = 'p-Accordion-child' ; const ACCORDION_CHILD_ACTIVE_CLASS = 'p-Accordion-child-active' ; /**
 * A panel that supports a collapsible header, made from the widget's title.
 * Clicking on the title expands or contracts the widget.
 */ export class Accordion extends Panel { constructor ( options ? ) { super ( options ) ; this . _selection = new Selection ( this . widgets as ReadonlyArray < Collapse > ) ; this . _selection . selectionChanged . connect ( this . _onSelectionChanged , this ) ; this . addClass ( ACCORDION_CLASS ) ; } /**
     * A read-only sequence of the widgets in the panel.
     *
     * #### Notes
     * This is a read-only property.
     */ get collapseWidgets ( ) : ReadonlyArray < Collapse > { return ( this . layout as PanelLayout ) . widgets as ReadonlyArray < Collapse > ; } get selection ( ) : Selection < Collapse > { return this . _selection ; } indexOf ( widget ) { return ArrayExt . findFirstIndex ( this . collapseWidgets , ( w ) => w . widget === widget ) ; } param widget returns addWidget ( widget ) { const collapse = this . _wrapWidget ( widget ) ; collapse . collapsed = true ; super . addWidget ( collapse ) ; this . _selection . adjustSelectionForInsert ( this . widgets . length - 1 , collapse ) ; return collapse ; } param index param widget insertWidget ( index , widget ) { const collapse = this . _wrapWidget ( widget ) ; collapse . collapsed = true ; super . insertWidget ( index , collapse ) ; this . _selection . adjustSelectionForInsert ( index , collapse ) ; } removeWidget ( widget ) { const index = this . indexOf ( widget ) ; if ( index >= 0 ) { const collapse = this . collapseWidgets [ index ] as Collapse ; widget . parent = null ; collapse . dispose ( ) ; this . _selection . adjustSelectionForRemove ( index , null ) ; } } private _wrapWidget ( widget ) { const collapse = new Collapse ( { widget } ) ; collapse . addClass ( ACCORDION_CHILD_CLASS ) ; collapse . collapseChanged . connect ( this . _onCollapseChange , this ) ; return collapse ; } private _onCollapseChange ( sender ) { if ( ! sender . collapsed ) { this . _selection . value = sender ; } else if ( this . _selection . value === sender && sender . collapsed ) { this . _selection . value = null ; } } private _onSelectionChanged ( sender , change ) { const pv = change . previousValue ; const cv = change . currentValue ; if ( pv ) { pv . collapsed = true ; pv . removeClass ( ACCORDION_CHILD_ACTIVE_CLASS ) ; } if ( cv ) { cv . collapsed = false ; cv . addClass ( ACCORDION_CHILD_ACTIVE_CLASS ) ; } } private _selection : Selection < Collapse > ; } export namespace Accordion { export type IOptions = Panel . IOptions ; }