Hyperapp: Using yo-yo elements (or other native DOM) in a Hyperapp view

Created on 3 Mar 2017  路  11Comments  路  Source: jorgebucaran/hyperapp

Hi! Thanks for your work, great project, got me very excited (couldn鈥檛 sleep when I first read the wiki).

Out of curiosity re-wrote my tiny markdown editing app from choo to hyperapp. Stepped into an issue: if I convert all components to hyperx/jsx, all is peachy. However when I tried to use a yo-yo (native HTML elements / real DOM) component, I鈥檓 not sure I understand the right approach. I鈥檝e looked at the CodeMirror example, but still.

Here鈥檚 my editor: https://github.com/arturi/tent/blob/4cca75742b0bd3e8d880c2b42df374a78cf959fb/index.js#L184-L189.
And here I鈥檓 trying to use it in a view: https://github.com/arturi/tent/blob/4cca75742b0bd3e8d880c2b42df374a78cf959fb/index.js#L209-L213.

The original editor component used just return a DOM element (textarea) and fire a callback (onkeyup), whenever something was typed, so I could update state/model. Now I鈥檝e changed it to return both the element an update method, so I could update it with hyperapp, but not sure that鈥檚 a thing to do, and it doesnt really work.

Thank you!

Discussion

All 11 comments

@arturi As you already know, HyperApp uses a custom virtual DOM engine, so you need to grab an an element and append your editor or other native element to it.

See this CodePen that uses Quill.js and let me know if it helps.

EDIT: If you can create a simple example I can help you debug it!

I'd like to point out that one of the many reasons that drove me to create this library was integrating CodeMirror with yo-yo/choo was too difficult.

I then found the official? example https://github.com/trainyard/choo-codemirror and was terrified. It involves the creation of a portal and it all seems harder than integrating CodeMirror with Elm, also not a piece of cake.

Thanks! I鈥檒l try to make a live example. Where would you append native element to a vdom element? oncreate or onupdate?

I'd use oncreate to append native elements to the DOM and onupdate to update props/options.

import { h } from "hyperapp"
import CodeMirror from "codemirror"

const node = document.createElement("div")
const editor = CodeMirror(node)

export const Editor = props => {
    const setOptions = props =>
        Object.keys(options).forEach(key => editor.setOption(key, props[key]))

    const oncreate = e => setOptions(props) && e.appendChild(node)
    const onupdate = _ => setOptions(props)

    return  <div oncreate={oncreate} onupdate={onupdate}></div>
}

Source.

So, here鈥檚 a simplified live example: http://www.webpackbin.com/V1-mmbQcf. It鈥檚 supposed to update both editor and preview in 5 seconds, but only the preview gets updated, because preview component is written with hyperapp vdom.

I got it working after a lot of fiddling, turns out, you have to pass an element from onupdate to an update function too. In my example that means changing update in simple-editor.js to use the passed elem:

function update (doc, elem) {
  console.log('update editor:', doc)
  const newEl = render(doc)
  html.update(elem, newEl)
}

yo-yo can鈥檛 html.update previous element for some reason, it loses the reference. Works in choo/yo-yo apps though.

Let me know if the example is confusing and thanks for taking the time to help out. What I liked about elements created with yo-yo is you could use them like document.body.appendChild(myElement(props)) and it just works. To make them compatible with vdom, it seems like an internal update method should be implemented, so they can鈥檛 be just dumb components.

I got it working after a lot of fiddling, turns out, you have to pass an element from onupdate to an update function too.

It always seems impossible until it's done ;)

And, yup. That's what I tried to say with I'd use "...onupdate to update props/options."

@arturi From what you are saying it seems that choo/yo-yo actually works well with these "dumb" components.

CodeMirror was notoriously difficult to get working, though, but I guess CodeMirror is the exception rather than the norm.

Like in everything, there's a trade-off here. See benchmarks.

Here's another example manipulating real DOM elements via onupdate using a <canvas> element.

Thanks! Should we add more examples to the docs, of how to integrate yo-yo elements, like https://www.npmjs.com/package/dom-notifications with hyperapp?

@arturi Absolutely! The wiki is public, so feel free to edit and add stuff! 馃槃

@arturi I think we're good here?

Yes, thank you! I鈥檒l try to maybe add some examples to the wiki if I can nail it down.

Was this page helpful?
0 / 5 - 0 ratings