Last active
February 3, 2017 16:59
-
-
Save jayrbolton/a763a3a8744fecf42842da18c1445cd5 to your computer and use it in GitHub Desktop.
Snabbdom transformer idea
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// this is how you could create composable functions that modify and extend VNodes | |
// - append or prepend children | |
// - add surrounding VNode wrappers | |
// - compose hook and event functions | |
// - merge props, attrs, style, and class | |
// snabbdom-transform objects can have these properties | |
// - wrapper: function that takes the vnode and allows you to add surrounding elements | |
// - class, style, and attrs: these will merge with existing data using R.merge | |
// - on, hook: these functions will merge and get composed with existing on/hook functions without overwriting any | |
// - appendChildren, prependChildren: child vnodes to append and prepend | |
// You can wrap the transform in a function to 'configure' it | |
const wordCount = (limit, total$) => { | |
// This allows you to wrap the vnode in surrounding parent elements and siblings | |
// If another snabbdom-transformer has already applied a wrapper function, then this wrapper function will get applied | |
wrapper: vnode => h('div', [ | |
vnode | |
, h('p', limit - total$() + ' words') | |
]) | |
// If the vnode already has other event listeners functions, then snabbTransform will compose them together so none are overwritten | |
, on: { | |
keyup: ev => { total$(ev.currentTarget.value.split(' ').length } | |
} | |
// Any classes added here will merge with any other classes already on the vnode | |
, class: { | |
invalid: total$() > limit | |
} | |
, appendChildren: [x, y, z] // These elements will append to any existing children nodes | |
, prependChildren: [x, y, z] // These elements will prepend to existing children nodes | |
} | |
// Use these transforms with the snabbdom-transform module | |
const patch = snabbdom.init([/* .. other modules .. */, require('snabbdom-transform')]) | |
// Then when you create VNodes, you can pass transforms into the 'transforms' property of the vnode's data: | |
const view = state => { | |
return h('textarea', { | |
props: {name: 'summary', placeholder: 'Briefly describe blah blah blah'} | |
, on: {keyup$: handleSummaryKeyup} // This will get composed with other keyup functions inside the transforms | |
, transforms: [ | |
wordCount(10, state.summaryWordCount$) | |
, resizableTextbox | |
, validate(state.form, {required: true, minWords: 5, maxWords: 11}) | |
] | |
}) | |
} | |
// In the above we are applying three separate transforms that get composed together. | |
// Each one adds a "keyup" function handler and each one adds their own wrapper content. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment