AFASSoftware / maquette

Pure and simple virtual DOM library

Home Page:https://maquettejs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Make the class attribute updateable

johan-gorter opened this issue · comments

We got some questions to make the class attribute updatable so we want to implement this feature.

This is one of our ideas for maquette 3

As discussed in #100, I think that it would seem more consistent, especially when re-using or inheriting DOM, that those classes explicitly defined are reflected in the node. From an efficiency perspective this would only need to be addressed when the node is fresh to the projector. If Maquette 3 included this concept of dealing with a node as fresh slightly differently than something that is already managed, it could ensure that the fresh node accurately reflects the VNode.

Following the principle of least astonishment, I really would like that all the ways of settings classes to be equivalent in terms of node updates. I mean that h('div.myclass') or h('div', { class: 'myclass' }) or h('div', { classes: { 'myclass': true } }) should do the exact same thing: add the myclass class to the DOM node (if it doesn't have it yet) and remove the other classes the DOM node has.

I think that the class removal was not implemented before because of the performance penalty when comparing the list of classes of the VNode against the list of classes of the DOM node to find the differences. Just wondering why you don't just replace the className property value when it has changed.

If the performance penalty argument still holds, I would suggest providing a way to extend/replace the node class update implementation, like snabbdom does, so that the app developer can should between performance or developer-friendliness.

I also understand that the selector syntax allow the matching of nodes when comparing the rendered tree to the existing tree. I think that my suggestion has no impact on the matching process if you keep the selector syntax for that purpose.

I also think there's no need to have both class and classes properties. In terms of API, the classnames library is really handy as it accepts virtually anything as input and do the right thing to convert it to a valid class string. I would advocate that we need either:

  • a single class property accepting strings, arrays, objects, arrays with nested objects, like classnames does
  • or a single class property accepting only strings; and let the user use whatever library they want to generate this string

Hope this helps ;)

I created the fix that allows a class attribute to be only a string. Magically, this is only 3 bytes extra gzipped. We are trying to keep maquettes filesize to a minimum, so if you want to have all the magic that the classnames library provides, you should use h('div', {class: classNames('foo', 'bar');})