-
Notifications
You must be signed in to change notification settings - Fork 780
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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Example with child (custom JSX) components? 馃嵓 #8
Comments
The routing example utilizes an |
It will be great if there is more advanced example - something like dynamic list of counters - it can show how to use child components, how to dynamically add elements and how to model updates. |
Here is a dynamic list of counters. const counter = (count, add, sub) => html`
<div>
<h1>${count}</h1>
<button onclick=${add}>+</button>
<button onclick=${sub} disabled=${count <= 0}>-</button>
</div>`
const counterReduce = (model, index, reduce) =>
model.map((item, i) => index === i ? reduce(item) : item)
app({
model: [],
update: {
create: model => model.concat(0),
remove: model => model.slice(0, -1),
add: (model, index) => counterReduce(model, index, count => count + 1),
sub: (model, index) => counterReduce(model, index, count => count - 1),
},
view: (model, msg) => html`
<div>
<button onclick=${msg.create}>Add Counter</button>
<button onclick=${msg.remove}>Remove Counter</button>
${model.map((item, i) => counter(item, _ => msg.add(i), _ => msg.sub(i)))}
</div>`
}) Also, check out the TodoMVC implementation. |
For reference here is using multiple stateful components, whereas in the above https://github.com/nichoth/hyperapp/tree/master/examples var hyperapp = require('../')
var app = hyperapp.app
var html = hyperapp.html
function CounterList () {
return [Counter()]
}
CounterList.update = {
addCounter: model => model.concat([Counter()]),
removeCounter: (model, i) => {
var newState = [].concat(model)
newState.splice(i, 1)
return newState
},
counter: function (model, ev) {
var newState = [].concat(model)
var c = newState[ev.index]
newState[ev.index] = Counter.update[ev.type](c)
return newState
}
}
CounterList.view = function (model, msg) {
var counters = model.map(function (counter, i) {
var counterView = Counter.view(counter, {
add: () => msg.counter({ type: 'add', index: i }),
sub: () => msg.counter({ type: 'sub', index: i })
})
return html`
<div>
${counterView}
<button onclick=${msg.removeCounter.bind(null, i)}>
remove this counter
</button>
</div>
`
})
return html`
<div>
<button onclick=${msg.addCounter}>new counter</button>
${counters}
</div>
`
}
function Counter () {
return 0
}
Counter.update = {
add: model => model + 1,
sub: model => model - 1
}
Counter.view = function (model, msg) {
return html`
<div>
<button onclick=${msg.add}>+</button>
<h1>${model}</h1>
<button onclick=${msg.sub} disabled=${model <= 0}>-</button>
</div>`
}
app({
model: CounterList(),
update: CounterList.update,
view: CounterList.view
}) |
Yes. Child components are possible. const Slider = ({ color, value, update }) =>
<div>
<input
type="range" min="0" max="255"
value={value}
oninput={e => update({
color: color,
value: e.target.value
})}
/>
</div>
app({
model: { red: 255, green: 255, blue: 255 },
view: (model, actions) =>
<div>
<p>Use sliders to change the background color.</p>
{Object.keys(model).map(color =>
<Slider
color={color}
value={model[color]}
update={actions.updateBgColor}
></Slider>)}
</div>
,
update: {
changeColor: (model, { color, value }) => ({ [color]: value })
},
effects: {
updateBgColor: (model, actions, data) => {
document.body.style.backgroundColor = `rgb(${model.red}, ${model.green}, ${model.blue})`
actions.changeColor(data)
}
}
}) |
Going to close this now that an example has been provided and this is prominent in Hyperapp features.
|
Are child components possible? Are there any examples with child components?
The text was updated successfully, but these errors were encountered: