New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create widget
function for creating widgets
#6
Comments
I'm thinking about something along this lines: var open = require("dom-reduce/event")
var writer = require("reflex/writer")
var map = require("reducers/map")
var channel = require("reducers/channel")
var emit = require("reducers/emit")
var reduce = require("reducers/reduce")
function widget(read, write) {
return function make(input, options) {
// Create / hook an instance using options passed
var instance = write(input, null, options)
var output = read(instance)
output.view = instance
return output
}
}
var rangeWriter = writer(function swap(output, data) {
output.querySelector(".caption").textContent = data.value
}, function close(output) {
var parent = output.parentElement
if (parent) parent.removeChild(output)
}, function open(options) {
options = options || {}
var root = document.createElement("div")
root.className = "widget"
var range = document.createElement("input")
range.className = "input range"
range.type = "range"
range.max = options.max || 100
range.min = options.min || 0
range.value = options.value === void(0) ? range.max / 2
: options.value
root.appendChild(range)
var caption = document.createElement("label")
caption.className = "caption"
root.appendChild(caption)
return root
})
var slider = widget(function(instance) {
var changes = open(instance, "change")
return map(changes, function(event) {
return event.target.value
})
}, rangeWriter)
var state = channel()
var s = slider(state, { max: 100, min: 0, value: 50 })
document.body.appendChild(s.view) |
How would it work with collectionWriter. You would want to call read for each one. |
Draft for the implementation of function component(read, write) {
/**
Component takes read / write functions for each of the nested component
and returns `react` function that can take `input` stream of application state
changes and returns `input` of user events
**/
return function react(state, options) {
var hash = {} // hash of items that are already known
var inputs = channel() // sequence of streams where each one is update per nested component.
reduce(state, function(current, state) {
var delta = diff(current, state)
Object.keys(delta).forEach(function(id) {
if (delta[id] === null) hash[id] = null
else if (!hash[id]) {
hash[id] = true
// filter each input to only updates for component with this id.
var fork = filter(state, function(data) { return id in data })
// Map it to actual update deltas.
var updates = map(fork, function(state) { return state[id] })
// Create an output where updates are written
var output = write(updates, options)
// and read inputs from that output
var input = read(output, options)
// create stream of deltas by mapping each update back to id
var deltas = map(output, function(update) {
var value = {}
value[id] = update
return value
})
// emit deltas stream to the stream of all inputs
emit(inputs, deltas)
}
})
})
// return joined stream of all inputs from all nested components.
flatten(inputs)
}
} |
Draft for the implementation of compound component that me and @Raynos have outlined: function compoundComponent(mapping) {
/**
Takes mapping of JSON paths for a state snapshot and `react`-or function
to which scoped updates are forwarded. In return it returns `input` stream
of user events all all the nested components joined in the state model
structure.
**/
return function react(state) {
var inputs = Object.keys(mapping).map(function(id) {
// Filter updates to the component with the given `id`.
var fork = filter(state, function(data) { return id in data })
// Selects a deltas for the given item.
var updates = map(fork, function(state) { return state[id] })
// Get an user input for the component by passing scope updates to
// the reactor function associated with an `id`.
var input = mapping[id](updates)
// Join back user input into same state structure.
return map(input, function(update) {
var value = {}
value[id] = update
return value
})
})
// Merge updates from all components together into stream of deltas
// for the application state.
return flatten(inputs)
}
} |
This now is now duplicate of #16 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
reflex should have a function for defining interactive, self contained widgets, that take
input
source and produce stream of changes. Probably we need some way of creating nested widgets too!The text was updated successfully, but these errors were encountered: