Skip to content
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

Closed
joelnet opened this issue Feb 1, 2017 · 7 comments
Closed

Example with child (custom JSX) components? 馃嵓 #8

joelnet opened this issue Feb 1, 2017 · 7 comments
Labels
outdated Forgotten lore question How do I do that?

Comments

@joelnet
Copy link

joelnet commented Feb 1, 2017

Are child components possible? Are there any examples with child components?

@FlorianWendelborn
Copy link

FlorianWendelborn commented Feb 1, 2017

The routing example utilizes an anchor child, kind of. You can just use the code in that example with${anchor()} etc..

@PetrSnobelt
Copy link

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.

@jorgebucaran jorgebucaran added the docs You read it here first label Feb 2, 2017
@jorgebucaran
Copy link
Owner

jorgebucaran commented Feb 2, 2017

@joelnet @PetrSnobelt

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>`
})

CodePen

Also, check out the TodoMVC implementation.

@nichoth
Copy link

nichoth commented Feb 3, 2017

For reference here is using multiple stateful components, whereas in the above counter is a static function.

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
})

@jorgebucaran
Copy link
Owner

jorgebucaran commented Feb 11, 2017

@joelnet No examples in the README yet, but this is now also possible when using jsx via: #77.

<MyComponents props=...>children</MyComponents>

@jorgebucaran
Copy link
Owner

jorgebucaran commented Feb 12, 2017

@joelnet Are child components possible? re there any examples with child components?

Yes. Child components are possible.

CodePen

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)
        }
    }
})

screen shot 2017-02-12 at 15 27 53

@jorgebucaran jorgebucaran changed the title Example with child components? Example with child components? 馃嵓 Feb 12, 2017
@jorgebucaran
Copy link
Owner

jorgebucaran commented Feb 17, 2017

Going to close this now that an example has been provided and this is prominent in Hyperapp features.

Stateless components: Build complex user interfaces from micro-components. Stateless components are framework agnostic, reusable, predictable and easier to debug.

@jorgebucaran jorgebucaran changed the title Example with child components? 馃嵓 Example with child (custom JSX) components? 馃嵓 Aug 31, 2018
@jorgebucaran jorgebucaran added question How do I do that? outdated Forgotten lore and removed docs You read it here first labels Aug 31, 2018
Repository owner locked as resolved and limited conversation to collaborators Aug 31, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated Forgotten lore question How do I do that?
Projects
None yet
Development

No branches or pull requests

5 participants