/** * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal * @author Alexander Rose */ import * as React from 'react'; import { Observable, Subscription } from 'rxjs'; import { PluginContext } from '../mol-plugin/context'; export const PluginReactContext = React.createContext(void 0 as any as PluginContext); export abstract class PluginUIComponent

extends React.Component { static contextType = PluginReactContext; readonly plugin: PluginContext; private subs: Subscription[] | undefined = void 0; protected subscribe(obs: Observable, action: (v: T) => void) { if (typeof this.subs === 'undefined') this.subs = [] this.subs.push(obs.subscribe(action)); } componentWillUnmount() { if (!this.subs) return; for (const s of this.subs) s.unsubscribe(); this.subs = []; } protected init?(): void; constructor(props: P, context?: any) { super(props, context); this.plugin = context; if (this.init) this.init(); } } export abstract class PurePluginUIComponent

extends React.PureComponent { static contextType = PluginReactContext; readonly plugin: PluginContext; private subs: Subscription[] | undefined = void 0; protected subscribe(obs: Observable, action: (v: T) => void) { if (typeof this.subs === 'undefined') this.subs = [] this.subs.push(obs.subscribe(action)); } componentWillUnmount() { if (!this.subs) return; for (const s of this.subs) s.unsubscribe(); } protected init?(): void; constructor(props: P, context?: any) { super(props, context); this.plugin = context; if (this.init) this.init(); } } export type _Props = C extends React.Component ? P : never export type _State = C extends React.Component ? S : never // export type CollapsableProps = { initiallyCollapsed?: boolean, header?: string } export type CollapsableState = { isCollapsed: boolean, header: string } export abstract class CollapsableControls

extends PluginUIComponent

{ toggleCollapsed = () => { this.setState({ isCollapsed: !this.state.isCollapsed } as (S & CollapsableState)) } protected abstract defaultState(): (S & CollapsableState) protected abstract renderControls(): JSX.Element | null render() { const wrapClass = this.state.isCollapsed ? 'msp-transform-wrapper msp-transform-wrapper-collapsed' : 'msp-transform-wrapper'; return

{!this.state.isCollapsed && this.renderControls()}
} constructor(props: P & CollapsableProps, context?: any) { super(props, context) const state = this.defaultState() if (props.initiallyCollapsed !== undefined) state.isCollapsed = props.initiallyCollapsed if (props.header !== undefined) state.header = props.header this.state = state } }