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

Problem with Tailwind style complex class names? #1113

Open
tslocke opened this issue Mar 5, 2024 · 6 comments
Open

Problem with Tailwind style complex class names? #1113

tslocke opened this issue Mar 5, 2024 · 6 comments

Comments

@tslocke
Copy link

tslocke commented Mar 5, 2024

I recently switched to using snabbdom to efficiently update the page preview in a web builder I'm working on.

The HTML contains Tailwind classes, e.g.class='block my-2 rounded bg-[#A31F24] text-white px-3 py-1'

I sometimes get an error from my call to patch(oldVnode, newVnode):

DOMException: Failed to execute 'createElement' on 'Document': The tag name provided ('a.block.my-2.rounded.bg-[') is not a valid name.

My patch function looks like this

import * as sd from "snabbdom"

const patch = sd.init([
  sd.classModule,
  sd.attributesModule,
  sd.datasetModule,
  sd.styleModule,
  sd.eventListenersModule,
])

Is this expected? Is there a workaround?

p.s. as a newbie, I'm not sure if I've got the right modules there -- all I want is "make this dom exactly like this other dom" (and the dom does include data attributes and style attributes, and does have event listeners on it)

Thanks!

@tslocke
Copy link
Author

tslocke commented Mar 8, 2024

Still facing this issue. Is there any way to configure things so that class is just treated like a regular string attribute?

Thanks

@tslocke
Copy link
Author

tslocke commented Mar 8, 2024

I've worked around this. The problem was partially related to my use of toVNode.

I've worked around this with a fork of toVNode that removes the hash from the vnode's sel and includes the class in data.attributes.

As far as I can tell the sel is only used as a kind of key to target updates correctly, so it should be fine to strip '#' chars from class names.

The fix would be in this code in createElm (init.ts)

      // Parse selector
      const hashIdx = sel.indexOf("#");
      const dotIdx = sel.indexOf(".", hashIdx);

In searches for '.' only later in the string than '#' (if present). I think it needs to be the other way around. It should only consider a '#' to be the hashIdx if it is before the first '.' But not tested

@paldepind
Copy link
Member

I guess this bug is very old, but no one has encountered it since using # in a class name is not very common (at least prior to this Tailwind feature). Thanks for reporting it!

The bug about the selector parsing definitely needs fixing. If you're interested in making a PR for that you're very welcome to do so.

Another question is whether it is appropriate for toVnode to put classes in the selector compared to setting them with the attributes module. It's not clear to me if one is strictly better than the other. So that issue probably needs some more contemplating.

@paldepind
Copy link
Member

#1116 should address the selector parsing issue. Would be useful if you can confirm that this solves your original problem 😊

@kuraga
Copy link

kuraga commented Mar 20, 2024

fix parsing of selector with # in class names

Is . possible in ids? 🙂

@paldepind
Copy link
Member

Good point. According to MDN the id can in theory contain anything but whitespace. But they also note:

For example, . has a special meaning in CSS (it starts a class selector). While valid, unless you are careful to escape it when used as part of a CSS selector, it won't be recognized as part of the element's id.

So for a selector foo.bar#baz one could imagine parsing this as either an id foo.bar or class bar#baz and in a CSS selector string the latter will be the meaning.

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