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

Best integration strategy with CSS lib? #807

Closed
cluelessjoe opened this issue May 3, 2018 · 4 comments
Closed

Best integration strategy with CSS lib? #807

cluelessjoe opened this issue May 3, 2018 · 4 comments

Comments

@cluelessjoe
Copy link

Hello

I would like to have a website with material design. However, both Material Components for the Web or
Bootstrap material design require some JS code (with possible integration in Material Components for the Web).

It feels like quite some work and for a POC that's a bit overkill, and an hurdle for some real projects.

What's the best course to follow in these cases?

The options I see are:

  • to skip the JS behavior and re code through Cyclejs what's needed
  • to do some minimal integration (on a per needed basis again)
  • to work with the default JS put in place in these libs

Am I missing something? What would you suggest?

I feel like a wiki page on "integration with other technologies" would be helpful. If you agree I'll gladly start it :)

Thanks in advance

thanks for cyclejs :)

best!
cluelessjoe

@fuunnx
Copy link
Contributor

fuunnx commented May 3, 2018

Hello,

According to your link https://material.io/components/web/docs/framework-integration/ the components provide some initialization and .destroy() methods.

With snabbdom you can use snabbdom hooks to run some code at insertion and destruction of your components.
Which you can abstract into a vnode factory for re-use :

function ripple(className = '', attributes = {}, children = []) {
  div(className,
    {
      ...attributes,
      hook: {
        insert: (vnode) => {
          let root = vnode.elm
          root.ripple = new MDCRipple(root)
        },
        destroy: (vnode) => {
          let root = vnode.elm
          root.ripple.destroy()
        },
      }
    },
    children,
  )
}
// somewhere else

main() {
 return {
  DOM: xs.of(
    ripple('.myRipple', {}, ['hello'])
  )
 }
}

An other option is to roll your on custom element (which I find good for more complex lifecycle). For that I'll recommend http://skatejs.netlify.com/ which I find as close to the metal as possible (innerHTML is often good enough) with a handul of nice abstractions on top.

import {withComponent, shadown, prop, props} from 'skatejs'

class MdcRipple extends withComponent() {
  connected() {
    super.connected && super.connected(...arguments)
    this.ripple = new MDCRipple(this)
    // if needed :
    // this.innerHTML = '<div>blah</div>'
    // shadow(this).innerHTML = '<div>blah<slot></slot></div>'
    // etc.
  }
  disconnected() {
    super.disconnected && super.disconnected(...arguments)
    this.ripple.destroy()
  }
  // define watched props
  static get props () {
    return {
        unbounded: prop({...props.boolean, default: false})
    }
  }
  // handle props update
  updated ({unbounded}) {
    this.ripple.unbounded = unbounded
  }
}
window.customElements.register('mdc-ripple', MdcRipple)

// somewhere else

import {h} from '@cycle/dom'
main() {
 return {
  DOM: xs.of(
    h('mdc-ripple', {props: {unbounded: true}}, ['Hello'])
  )
 }
}

I you find yourself writing a lot of boilerplate to create functions returning vNodes I wrote a few helper functions in this gist:
https://gist.github.com/fuunnx/e81c86cc46a485786f8193563d550680

Have a nice day

@cluelessjoe
Copy link
Author

Thanks a lot @fuunnx. It's pretty dense for me though, thus I'm digging in right row. Actually I never had to use snabbdom directly so far, interesting :)

@jvanbruegge
Copy link
Member

@fuunnx answer is correct, using snabbdom hooks would be the way to do it

@cluelessjoe
Copy link
Author

cluelessjoe commented May 6, 2018

thx again :)

I managed to put it all in action in 2 ways:

Overall this rocks :)

For this second option I had to copy/paste/extend the modules array, to have the same as cyclejs's default (defined in @cycle/dom modules.js).

Did I miss a way to reuse the default array?
If not could this modules array somehow be made accessible (exported I guess) from the outside?

BTW, @jvanbruegge, if the above code is worthy of being in the FAQ (cf #809), or not too far from it, I would gladly do the extra mile to help making these FAQ. Just let me know what/how. :)

@fuunnx: I didn't try the skatejs way so far. It feels like these snadddom hooks should be enough :$

thanks again a lot :)

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

3 participants