UNPKG

armo-breadboard

Version:

Edit a live React component's source in real time.

82 lines (70 loc) 2.73 kB
import PropTypes from 'prop-types' import { Controller, instantiateController } from 'react-controllers' import { noop } from 'armo-util' import BreadboardBuilder from './BreadboardBuilder' import ConsoleController from './ConsoleController' export default class BreadboardController extends Controller { static propTypes = { modes: PropTypes.shape({ transformedSource: PropTypes.bool, browser: PropTypes.bool, console: PropTypes.bool, }).isRequired, sources: PropTypes.shape({ bus: PropTypes.object.isRequired, model: PropTypes.shape({ value: PropTypes.objectOf(PropTypes.string).isRequired, onChange: PropTypes.func.isRequired, }), }).isRequired, transforms: PropTypes.arrayOf(PropTypes.array).isRequired, // TODO: if we have transformedSource but not browser/console, only // transform appropriate source selected: PropTypes.object, } static actions = { } constructor(props) { super(props) const transformedSources = this.setTransformsAndBuild(props.transforms, props.sources.model.value) this.state = { transformedSources: transformedSources, sourcesChangedSinceLastBuild: false, firstTransformError: findFirstError(transformedSources), consoleController: instantiateController(ConsoleController), } } controllerWillReceiveProps(nextProps) { const nextModes = nextProps.modes const nextModeRequiresBuild = nextModes.browser || nextModes.console || nextModes.transformedSource const sourcesDidChange = nextProps.sources !== this.props.sources let rebuild = false if (nextProps.transforms !== this.props.transforms) { const transformedSources = this.setTransformsAndBuild(nextProps.transforms, nextProps.sources.model.value) this.setState({ transformedSources: transformedSources, firstTransformError: findFirstError(transformedSources), }) } else if (nextModeRequiresBuild && sourcesDidChange || this.state.sourcesChangedSinceLastBuild) { const transformedSources = this.builder.buildAll(nextProps.sources.model.value) this.setState({ transformedSources: transformedSources, sourcesChangedSinceLastBuild: false, firstTransformError: findFirstError(transformedSources), }) } else if (sourcesDidChange && !this.state.sourcesChangedSinceLastBuild) { this.setState({ sourcesChangedSinceLastBuild: true, }) } } setTransformsAndBuild(transforms, sources) { this.builder = new BreadboardBuilder(transforms) return this.builder.buildAll(sources) } } function findFirstError(obj) { return Object.values(obj).find(x => x instanceof Error) }