export default subscriptions => Component => component({ initialState ({props, actions, path}) { return map((sub, key) => sub.initialState ? sub.initialState(props, value => actions.update(key, value), path) : {}, subscriptions) }, * onCreate ({path, props, state, actions}) { yield mapValues((sub, key) => sub(props, state[key], value => actions.update(key, value), path), subscriptions) }, render ({props, state, children}) { return ( <Component {...props} {...state}> {children} </Component> ) }, * onUpdate (prev, {path, props, state, actions}) { yield mapValues((sub, key) => sub(props, state[key], value => actions.update(key, value), path), subscriptions) }, reducer: { update: (state, key, value) => ({ [key]: { ...(state[key] || {}), ...value } }) } })
sub(child) { if(this.isIdentity()) return child; if(child.isIdentity()) return this; const childMap = mapObj(target => substitutePointer(target, this.map), child.map); return new Transform(childMap); }
export function mapAttributes(node, f, deep = false) { if(isText(node) || isEmpty(node)) return node; const name = isThunk(node) ? 'props' : 'attributes'; const spec = {}; spec[ name ] = mapObj(f, node[ name ]); if(deep) spec.children = node.children.map(child => mapAttributes(child, f, deep)); return Object.assign({}, node, spec); }
function applySpec(spec, rawComponent) { const cacheEntry = spec.cache ? spec.cache.get(rawComponent) : null; if(cacheEntry) return cacheEntry; const component = normalize(rawComponent); const hooks = pick(['onCreate', 'onUpdate', 'onRemove'], spec); const componentSpec = mapObj(hook => model => hook(component, spec.model(component, model)), hooks); componentSpec.render = function(model) { const decoratedModel = spec.model(component, model); const node = spec.render(component, decoratedModel); return spec.deep ? decorateNode(spec, node) : node; }; const decorated = Object.assign({}, component, componentSpec); if(spec.cache) spec.cache.set(rawComponent, decorated); return decorated; }
/** * returns targets (target pointer as rfc string) * @returns {Object<string, string>} */ toTargets() { return mapObj(pointer => pointer.toRFC(), this.map); }
const parseTargets = desc => mapObj(JSONPointer.ofString, desc);
import Dropdown from './Dropdown' import Tooltip from './Tooltip' import Toggle from './Toggle' import Button from './Button' import map from '@f/map-obj' import Input from './Input' import wrap from './wrap' import form from './form' /** * Exports */ module.exports = { // Contained components ...map(wrap(CSSContainer), require('vdux-ui')), CSSContainer, Button, MenuItem, Dropdown, Tooltip, Toggle, Input, Textarea, // Higher-order component wrappers imageLoaded, subscribe, wrap, form }