UNPKG

pdbe-molstar

Version:
79 lines (78 loc) 3.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LayoutSpecComponent = LayoutSpecComponent; exports.createPluginSplitUI = createPluginSplitUI; exports.resolveHTMLElement = resolveHTMLElement; const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const base_1 = require("molstar/lib/mol-plugin-ui/base"); const context_1 = require("molstar/lib/mol-plugin-ui/context"); const react18_1 = require("molstar/lib/mol-plugin-ui/react18"); const react_1 = require("react"); const spec_1 = require("../../spec"); function LayoutSpecComponent(target, component, props) { return { target, component, props }; } function createPluginSplitUI(options) { return tslib_1.__awaiter(this, void 0, void 0, function* () { var _a; const { spec, layout, onBeforeUIRender } = options; const render = (_a = options.render) !== null && _a !== void 0 ? _a : react18_1.renderReact18; const ctx = new context_1.PluginUIContext(spec || (0, spec_1.DefaultPluginUISpec)()); yield ctx.init(); if (onBeforeUIRender) { yield onBeforeUIRender(ctx); } for (const { target, component, props } of layout) { let targetElement = undefined; try { targetElement = resolveHTMLElement(target); } catch (err) { console.warn('Skipping rendering a UI component because its target HTML element was not found.', err); } if (targetElement) { render((0, jsx_runtime_1.jsx)(PluginPanelWrapper, { plugin: ctx, component: component, props: props !== null && props !== void 0 ? props : {} }), targetElement); } // TODO in future: consider adding a listener that re-renders the React component when the div is removed and re-added to DOM } try { yield ctx.canvas3dInitialized; } catch (_b) { // Error reported in UI/console elsewhere. } return ctx; }); } function resolveHTMLElement(element) { if (typeof element === 'string') { const result = document.getElementById(element); if (!result) throw new Error(`Element #${element} not found in DOM`); return result; } else { return element; } } function PluginPanelWrapper({ plugin, component, props }) { const [state, setState] = (0, react_1.useState)({ kind: 'pending' }); (0, react_1.useEffect)(() => { setState(plugin.isInitialized ? { kind: 'initialized' } : { kind: 'pending' }); let mounted = true; plugin.initialized.then(() => { if (mounted) setState({ kind: 'initialized' }); }).catch(err => { if (mounted) setState({ kind: 'error', message: `${err}` }); }); return () => { mounted = false; }; }, [plugin]); if (state.kind !== 'initialized') { const message = state.kind === 'error' ? `Initialization error: ${state.message}` : 'Waiting for plugin initialization'; return (0, jsx_runtime_1.jsx)("div", { className: 'msp-plugin', style: { position: 'relative', width: '100%', height: '100%' }, children: (0, jsx_runtime_1.jsx)("div", { className: 'msp-plugin-init-error', children: message }) }); } return (0, jsx_runtime_1.jsx)(base_1.PluginReactContext.Provider, { value: plugin, children: (0, jsx_runtime_1.jsx)("div", { className: 'msp-plugin', style: { position: 'relative', width: '100%', height: '100%' }, children: (0, jsx_runtime_1.jsx)("div", { className: 'msp-plugin-content msp-layout-standard msp-layout-static', style: { position: 'relative', width: '100%', height: '100%' }, children: (0, react_1.createElement)(component, props) }) }) }); }