UNPKG

react-transclusion

Version:

Render arbitrary components into outlets for use in dynamic layouts.

95 lines (76 loc) 2.56 kB
'use strict'; var invariant = require('invariant'); /** * This is the underlying module that allows you to register elements for * [[Outlet | outlets]] and define them. */ module.exports = function OutletManager() { var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var exports = {}; var outlets = {}; var strict = config.strict !== false; /** * Define a new outlet in the layout. An outlet must be defined through this * API before attempting to inject into it or even render it. * * @param {String} name * The outlet name. * * @throws {InvariantError} * If a similar outlet with this name had already been defined. */ exports.define = function (name) { invariant(!getOutletByName(name), 'Outlet ' + name + ' has already been defined.'); if (process.env.NODE_ENV !== 'production' && config.verbose) { console.log('Outlet defined: "%s"', name); } outlets[name] = []; }; /** * Register an element to be rendered inside an [Outlet outlet](). * * @param {String} name * The outlet ID. * * @param {Object} element * A description of the element. * * @param {String} element.key * **REQUIRED** - a unique identifier for the component (within that * outlet.) * * @param {React.Class} element.component * **REQUIRED** - the component to render inside the outlet. */ exports.add = function (name, element) { var outlet = getOutletByName(name); if (!outlet) { if (strict) { invariant(false, 'Unknown outlet "' + name + '".'); } exports.define(name); return exports.add(name, element); } var key = element.key || element.component && (element.component.displayName || element.component.constructor.name); invariant(typeof key === 'string', 'Missing @key for outlet occupant of "' + name + '"'); invariant(typeof element.component === 'function', "You must specify a React.Class as @component for the outlet component."); outlet.push(Object.assign({}, element, { key: key })); }; exports.getElements = function (name) { return getOutletByName(name) || []; }; exports.isDefined = function (name) { return !!getOutletByName(name); }; exports.reset = function (name) { if (name) { outlets[name] = null; } else { Object.keys(outlets).forEach(exports.reset); } }; return exports; function getOutletByName(name) { return outlets[name]; } };