Skip to content

Commit

Permalink
feat(tools): update withChild with Component map support
Browse files Browse the repository at this point in the history
  • Loading branch information
thibautrey authored and davidbonnet committed Jan 24, 2019
1 parent 98b0b3d commit 8cfb547
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<Component {...childProps(props)(itemValue, itemIndex)}` and injects it as a `children` prop.
The prop is only updated if `shouldUpdateOrKeys` returns `true` or if a prop whose name is listed in it changes.

#### `withChild(Component, childProps?, shouldUpdateOrKeys?, valueName?)`
#### `withElement(Component || { key:Component }, childProps?, shouldUpdateOrKeys?, destination?)`

> ⬆️ `{ [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 }) => (
<div>
{children.header}
{children.body}
</div>
))

<Article value={{ value: { header: 'Title', body: 'Content' } }} />
```

### Type-oriented decorators

#### `object`
Expand Down
13 changes: 13 additions & 0 deletions demo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
withChild,
EMPTY_OBJECT,
logProps,
withElement,
} from '../src'

const Text = compose(
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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' } }),
)
})

Expand Down
12 changes: 11 additions & 1 deletion src/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
upperFirst,
map,
identity,
mapValues,
} from 'lodash'
import {
branch,
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 8cfb547

Please sign in to comment.