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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Widgets with choo #250

Closed
callum opened this issue Sep 8, 2016 · 8 comments
Closed

Widgets with choo #250

callum opened this issue Sep 8, 2016 · 8 comments

Comments

@callum
Copy link
Contributor

callum commented Sep 8, 2016

I'm trying to create a reusable element that implements Quill but I can't figure out how to do it. The issue I'm having is that on re-render the Quill editor gets wiped; I don't know how to maintain the state of it.

The most basic example:

const html = require('choo/html')
const onload = require('on-load')
const Quill = require('quill')

module.exports = richtext

function richtext (state, prev, send) {
  const div = html`<div></div>`
  onload(div, (el) => {
    const quill = new Quill(el)
    quill.on('text-change', () => {
      send() // triggers re-render and DOM state is lost
    })
  })
  return div
}

I used virtual-widget a while back - something like that would be ideal for this.

@reminyborg
Copy link
Contributor

If you only need a single instance of quill then i would do domething like this

The gist is that you create an element that you hook the Quill instance to. And then you can easily just drop it into your choo dom tree.

If you need multiple instances running try tenants
Still needs some work but it works really well for my usecases.

@callum
Copy link
Contributor Author

callum commented Sep 8, 2016

Excellent @reminyborg - I will give that a try. Thanks

@callum
Copy link
Contributor Author

callum commented Sep 8, 2016

Just seen the D3 example and it's not clear to me how you would create multiple instances in my case. Can you give an example?

@reminyborg
Copy link
Contributor

reminyborg commented Sep 8, 2016

I created a short little gist with quill for you. Its a really nice editor.

You still need to hook up send ++ but it should get you started.

Edit: You have to add: <link href="http://cdn.quilljs.com/1.0.0/quill.snow.css" rel="stylesheet"> to the head. Requirebin doesnt save it for some reason...

@timwis
Copy link
Member

timwis commented Sep 8, 2016

Wow, interesting approach @reminyborg, i'm surprised that works. We talked about this in patrick-steele-idem/morphdom#77, and the latest PR on morphdom should make memoizing possible. Though it looks like that's what you're doing... have you played around with onload with your approach?

@reminyborg
Copy link
Contributor

@timwis thanks. I have used this approach quite a lot in other frameworks and while it might seem a bit strange at first it gives you a lot of control.

Ive used the onload on my little leaflet gist. It is used to invalidate the leaflet size so it rerenders the map once it knows its size in the dom. In that gist you can also se the awesomeness of getting the state and prev values to do diffing based "mutations" of the leaflet map.

@yoshuawuyts
Copy link
Member

yoshuawuyts commented Sep 10, 2016

waiting on patrick-steele-idem/morphdom#77 to be published; made a demo on how to create widgets with the isSameNode() API here: shama/on-load#10 (comment) (e.g. thunking!)

This should provide exactly the experience we intended to have from the start 🎉

@yoshuawuyts
Copy link
Member

Yay, all the PRs have been merged and it should all be working. As per #1 we're now building out cache-element/widget which should allow for super clean widgetization of elements ✨ The API looks like this:

const widget = require('cache-element/widget')
const html = require('bel')

const renderEl = widget(function (update) {
  let name = null
  let age = null

  update(onupdate)

  return html`
    <p onload=${onload} onunload=${onunload}>
      Name is ${name} and age is ${age}
    </p>
  `

  function onupdate (newName, newAge) {
    name = newName
    age = newAge
  }

  function onload () {
    console.log('added to DOM')
  }

  function onunload () {
    name = null
    age = null
    console.log('removed from DOM')
  }
})

let el = renderEl('Tubi', 12) // creates new element
let el = renderEl('Tubi', 12) // returns cached element (proxy)
let el = renderEl('Babs', 25) // returns cached element (proxy)

I think this should answer your question; consider watching / contributing to cache-element to get this out faster, but in essence all the lower level components now work and exist 😁

@roobie roobie mentioned this issue Oct 13, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants