diff --git a/README.md b/README.md index 893f2f88..c43649da 100644 --- a/README.md +++ b/README.md @@ -272,15 +272,31 @@ If a new promise is provided to `[name]`, the previously resolved `value` is kep Builds an array that maps every item from the `[valueName]` prop with the result of ` ⬆️ `{ [valueName]? }` > ⬇️ `{ children }` -Builds an element from the provided `Component` with the props from `childProps(props)` and injects it as a `children` prop. +Builds an element from the provided `Component` with the props from `childProps(props,name?)` and injects it as a `children` prop. + +If `Component` is an object like `{key:Component, key2: Component2...}`, an element will be built for every key of the object. The childProps will be called for each of the keys with the `name` parameter containing the key itself + The prop is only updated if `shouldUpdateOrKeys` returns `true` or if a prop whose name is listed in it changes. +```js +const Article = withElement({ header: 'h1', body: 'p' }, (props, name) => ({ + children: props.value[name], +}))(({ children = EMPTY_OBJECT }) => ( +
+ {children.header} + {children.body} +
+)) + +
+``` + ### Type-oriented decorators #### `object` diff --git a/demo/index.js b/demo/index.js index 3a1c3c74..60903f2f 100644 --- a/demo/index.js +++ b/demo/index.js @@ -35,6 +35,7 @@ import { withChild, EMPTY_OBJECT, logProps, + withElement, } from '../src' const Text = compose( @@ -303,6 +304,17 @@ export const Toggle = compose( ) }) +const Article = withElement({ header: 'h1', body: 'p' }, (props, name) => ({ + children: props.value[name], +}))(({ children = EMPTY_OBJECT }) => + $( + 'div', + null, + $('div', null, children.header), + $('div', null, children.body), + ), +) + export const App = compose( withProps({ value: { @@ -338,6 +350,7 @@ export const App = compose( $(Color, property('color')), $('h2', null, 'Delayed'), $(Toggle, { ...property('toggle'), delay: 2000 }), + $(Article, { value: { header: 'Title', body: 'Content' } }), ) }) diff --git a/src/tools.js b/src/tools.js index 3881216e..44d8ef45 100644 --- a/src/tools.js +++ b/src/tools.js @@ -14,6 +14,7 @@ import { upperFirst, map, identity, + mapValues, } from 'lodash' import { branch, @@ -427,11 +428,20 @@ export function withChild( Builds an element from the provided `Component` with the props from `childProps(props)` and injects it as a `[destination]` prop. The prop is only updated if `shouldUpdateOrKeys` returns `true` or if a prop whose name is listed in it changes. */ + if (typeof Component === 'function') { + return withPropsOnChange(shouldUpdateOrKeys, props => ({ + [destination]: $(Component, childProps(props, null)), + })) + } return withPropsOnChange(shouldUpdateOrKeys, props => ({ - [destination]: $(Component, childProps(props)), + [destination]: mapValues(Component, (Component, name) => + $(Component, childProps(props, name)), + ), })) } +export const withElement = withChild + export function lazyProperty(object, propertyName, valueBuilder) { /* Returns `object[propertyName]` if not `nil`, otherwise sets the result of `valueBuilder(object)` to it and returns it.