Home Reference Source

application/components/layout/root.js

import React from 'react';
import uuid from 'uuid';
import Immutable from 'immutable';

import Events from './../../util/events';

/**
 * The idea here is you generate a unique ID and a component
 * then emit an addRootComponent event with the id and component
 * and it is injected here.
 *
 * It's really quite hacky but it works. Something like:
 *
 * <code>
 *     const myComponent = <SomeThing />;
 *     events.emit('addRootComponent', myId, myComponent);
 *
 *     // then to remove
 *     events.emit('removeRootComponent', myId);
 * </code>
 */
class RootExtension extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            components: []
        }
    }

    componentWillMount() {
        Events.listen('addRootComponent', this.onAdd.bind(this));
        Events.listen('removeRootComponent', this.onRemove.bind(this));
    }

    componentWillUnmount() {
        Events.unlisten('addRootComponent', this.onAdd.bind(this));
        Events.unlisten('removeRootComponent', this.onRemove.bind(this));
    }

    onAdd(id, component, callback) {
        let components = this.state.components;

        for (let comp in components) {
            if (components[comp].uuid === id) {
                return;
            }
        }

        components.push({'component': component, 'uuid': id});

        this.setState({'components': components});

        if (callback) {
            callback(id);
        }
    }

    onRemove(id) {
        let components = this.state.components;
        let newComponents = [];

        for (let comp in components) {
            if (components[comp].uuid === id) {
                continue;
            }

            newComponents.push(components[comp]);
        }

        this.setState({'components': newComponents});
    }

    render() {
        return (
            <div>
                {this.state.components.map((child, i) => {
                    return <div key={child.uuid}>{child.component}</div>;
                })}
            </div>
        );
    }
}



export default RootExtension;