UNPKG

decca

Version:

Render interfaces using pure functions and virtual DOM, kinda

59 lines (58 loc) 1.96 kB
/** * @module decca/string */ "use strict"; var id_1 = require('./id'); var assign = require('object-assign'); /** * Renders an element into a string without using the DOM. * * @param {Element} el The Element to render * @param {*=} context The context to be passed onto components * @returns {string} the rendered HTML string */ function render(el, context) { if (typeof el === 'string') return el; if (typeof el === 'number') return '' + el; if (Array.isArray(el)) return el.map(function (_el) { return render(_el, context); }); if (typeof el === 'undefined' || el === null) return ''; var tag = el.tag, props = el.props, children = el.children; if (typeof tag === 'string') { var open_1 = '<' + tag + toProps(props) + '>'; var close_1 = '</' + tag + '>'; return open_1 + (children || []).map(function (_el) { return render(_el, context); }).join('') + close_1; } if (typeof tag === 'object') { if (!tag.render) throw new Error('component has no render()'); return render(tag.render({ props: assign({}, props, { children: children }), path: id_1["default"](), context: context }), context); } if (typeof tag === 'function') { // Pure components return render(tag({ props: assign({}, props, { children: children }), path: id_1["default"](), context: context }), context); } } exports.render = render; /* * { class: 'foo', id: 'box' } => ' class="foo" id="box"' */ function toProps(props) { if (!props) return ''; var result = []; Object.keys(props).forEach(function (attr) { if (/^on[A-Za-z]/.test(attr)) return; var val = props[attr]; if (typeof val === 'undefined' || val === null) return; result.push(attr + "=" + JSON.stringify(val)); }); return result.length ? ' ' + result.join(' ') : ''; }