123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- /**
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
- 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<P = {}, S = {}, SS = {}> extends React.Component<P, S, SS> {
- static contextType = PluginReactContext;
- readonly plugin: PluginContext;
- private subs: Subscription[] | undefined = void 0;
- protected subscribe<T>(obs: Observable<T>, 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<P = {}, S = {}, SS = {}> extends React.PureComponent<P, S, SS> {
- static contextType = PluginReactContext;
- readonly plugin: PluginContext;
- private subs: Subscription[] | undefined = void 0;
- protected subscribe<T>(obs: Observable<T>, 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> = C extends React.Component<infer P> ? P : never
- export type _State<C extends React.Component> = C extends React.Component<any, infer S> ? S : never
- //
- export type CollapsableProps = { initiallyCollapsed?: boolean, header?: string }
- export type CollapsableState = { isCollapsed: boolean, header: string }
- export abstract class CollapsableControls<P = {}, S = {}, SS = {}> extends PluginUIComponent<P & CollapsableProps, S & CollapsableState, SS> {
- 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 <div className={wrapClass}>
- <div className='msp-transform-header'>
- <button className='msp-btn msp-btn-block msp-btn-collapse' onClick={this.toggleCollapsed}>
- <span className={`msp-icon msp-icon-${this.state.isCollapsed ? 'expand' : 'collapse'}`} />
- {this.state.header}
- </button>
- </div>
- {!this.state.isCollapsed && this.renderControls()}
- </div>
- }
- 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
- }
- }
|