Skip to content

[Bug?]: Dynamically generated class names are not picked up by UnoCSS #2028

@jceb

Description

@jceb

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Current behavior 😯

I ran into an issue with dynamically generated class names that are used inside Show or For components. The unocss template ships with a dynamically applied class name (https://github.com/solidjs/templates/blob/main/solid-start/with-unocss/src/components/Nav.tsx#L15), which works well. However, when class name are generated dynamically, UnoCSS is not able to detect the class names anymore.

Example modified Counter component with Show and For components:

// @ts-types="solid-js"
import { Show } from "solid-js";
import { createSignal } from "solid-js";

export default function Counter() {
  const [count, setCount] = createSignal(0);
  const extra_class1 = "bg-yellow-700";
  const extra_class2 = "bg-red-700";
  const extra_class3 = "bg-green-700";
  const extra_class4 = "bg-blue-400";
  return (
    <>
      <button
        class="w-[200px] rounded-full bg-gray-100 ${extra_class} border-2 border-gray-300 focus:border-gray-400 active:border-gray-400 px-[2rem] py-[1rem]"
        onClick={() => setCount(count() + 1)}
      >
        Clicks: {count()}
      </button>
      <Show when={count() > 3}>
        {" "}
        <For each={[1, 2, 3]}>
          {(item) => (
            <div class={`border size-${item * 4} ${extra_class3}`}>{item}</div>
          )}
        </For>
        <div class={`border size-15 ${extra_class2}`}>test2</div>
      </Show>
      <For each={[1, 2, 3]}>
        {(item) => (
          <div class={`border size-${item * 5} ${extra_class4}`}>{item}</div>
        )}
      </For>
      <div class={`border size-${8 * 5} ${extra_class1}`}>test</div>
    </>
  );
}

This is what's rendered when I click the counter 4x:

Image

Expected behavior 🤔

  • The statically assigned classes like border are picked up properly 👍
  • The injected class names are picked up properly 👍
  • The dynamically computed sizes are not picked up 👎
    • Due to size-15 being statically used inside the show component, the dynamically computed size size-${3 * 5) works by coincidence.
  • When dynamic class names are used inside Show and For components the behavior is consistent with non-wrapped elements 👍

Steps to reproduce 🕹

Steps:

  1. Create app with unocss template
  2. Replace counter component
  3. Click the button 4x
  4. Observe the result

Context 🔦

As a workaround, adding dynamically generated class names to UnoCSS' safelist solves the issue.

Your environment 🌎

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions