From ad7d0d963e73cd3905412a4de2e9f64a882b6102 Mon Sep 17 00:00:00 2001 From: Martin Acosta Date: Fri, 7 Apr 2017 11:24:21 -0300 Subject: [PATCH] added support for children render inside of a component --- example/components/list.js | 5 +++-- example/index.js | 4 +++- index.js | 17 +++++++++++++++-- lib/component/component.js | 6 +++--- lib/component/instance.js | 12 +++++++----- lib/patch/renderer.js | 6 +++--- 6 files changed, 34 insertions(+), 16 deletions(-) diff --git a/example/components/list.js b/example/components/list.js index 0e2b399..4c386db 100644 --- a/example/components/list.js +++ b/example/components/list.js @@ -29,11 +29,12 @@ module.exports = function List({ emitter, props }) { emitter.emit('item:remove'); } - function view({ state }) { + function view({ state, children }) { return h('div.list', { id: 'test' }, [ h('button', { on: { click: add } }, 'add'), h('button', { on: { click: remove } }, 'remove'), - h('ul', state.items.map((value, key) => component(Li, { value, key }))) + h('ul', state.items.map((value, key) => component(Li, { value, key }))), + h('div.others', children) ]); } diff --git a/example/index.js b/example/index.js index 16d5ccd..87735d0 100644 --- a/example/index.js +++ b/example/index.js @@ -27,7 +27,9 @@ function App({ emitter }) { function view({ state }) { return h('div', { id: 'app' }, [ h('h1', { on: { click: change } }, state.time), - component(List, { items: ['test 1', 'test 2'] }) + component(List, { items: ['test 1', 'test 2'] }, [ + component(List, { items: ['test 3', 'test 4'] }) + ]) ]); } diff --git a/index.js b/index.js index 36e6b30..8495204 100644 --- a/index.js +++ b/index.js @@ -22,8 +22,21 @@ function snabbmitt(opts) { const instance = instanceComponent(patch, container, factory, props); return instance.render({ usePatch: true, props }); }, - component(factory, props = {}) { - return component(patch, factory, props); + component(factory, ...args) { + let props = {}; + let children = []; + + if (args.length === 2) { + [ props, children ] = args; + } else if (args.length === 1) { + if (Array.isArray(args[0])) { + children = args[0]; + } else { + props = args[0]; + } + } + + return component(patch, factory, props, children); } }; } diff --git a/lib/component/component.js b/lib/component/component.js index 6ab5dd8..363735d 100644 --- a/lib/component/component.js +++ b/lib/component/component.js @@ -9,7 +9,7 @@ function copyToVnode(vnode, nextVnode) { vnode.sel = nextVnode.sel; } -module.exports = function component(patch, factory, props = {}) { +module.exports = function component(patch, factory, props = {}, children = []) { if (!factory.sel) { factory.sel = 'component'; } @@ -21,7 +21,7 @@ module.exports = function component(patch, factory, props = {}) { hook: { init(vnode) { const instance = instanceComponent(patch, null, factory, props); - const cvnode = instance.render({ props }); + const cvnode = instance.render({ props, children }); if (factory.sel === 'component') { // from now we know the indentity of this type of components @@ -37,7 +37,7 @@ module.exports = function component(patch, factory, props = {}) { copyToVnode(vnode, cvnode); }, prepatch(oldVnode, vnode) { - const cvnode = oldVnode.data[_snabbmitt].instance.render({ props }); + const cvnode = oldVnode.data[_snabbmitt].instance.render({ props, children }); cvnode.data[_snabbmitt] = oldVnode.data[_snabbmitt]; cvnode.data[_snabbmitt].rvnode = vnode; cvnode.elm = oldVnode.elm; diff --git a/lib/component/instance.js b/lib/component/instance.js index 2446a46..ecf82d1 100644 --- a/lib/component/instance.js +++ b/lib/component/instance.js @@ -5,6 +5,7 @@ const createRenderer = require('../patch/renderer'); module.exports = function instanceComponent(patch, container, factory, userProps = {}) { const render = createRenderer(patch, container); let props = userProps; + let children = []; let vnode; let userView; let store; @@ -12,7 +13,7 @@ module.exports = function instanceComponent(patch, container, factory, userProps const emitter = mitt(); emitter.on('render', () => { - vnode = render({ usePatch: true, view, state, props }); + vnode = render({ usePatch: true, view, state, props, children }); }); const instance = factory({ emitter, props }); @@ -25,8 +26,8 @@ module.exports = function instanceComponent(patch, container, factory, userProps hook = instance.hook; } - const view = ({ state, props }) => { - return applyHook(userView({ state, props }), hook); + const view = ({ state, props, children }) => { + return applyHook(userView({ state, props, children }), hook); }; const state = typeof store === 'function' ? store() : {}; @@ -36,9 +37,10 @@ module.exports = function instanceComponent(patch, container, factory, userProps vnode() { return vnode; }, - render({ usePatch = false, props: userProps = {} }) { + render({ usePatch = false, props: userProps = {}, children: userChildren = [] }) { props = userProps; - vnode = render({ usePatch, view, state, props }); + children = userChildren; + vnode = render({ usePatch, view, state, props, children }); return vnode; }, state, diff --git a/lib/patch/renderer.js b/lib/patch/renderer.js index dc83e04..f6e3b24 100644 --- a/lib/patch/renderer.js +++ b/lib/patch/renderer.js @@ -1,11 +1,11 @@ module.exports = function createRenderer(patch, container) { let vnode = container; - function render({ usePatch, view, state, props }) { + function render({ usePatch, view, state, props, children }) { if (usePatch && vnode && (vnode.elm || vnode.parentNode)) { - vnode = patch(vnode, view({ state, props })); + vnode = patch(vnode, view({ state, props, children })); } else { - vnode = view({ state, props }); + vnode = view({ state, props, children }); } return vnode;