icon icon indicating copy to clipboard operation
icon copied to clipboard

Rendering wrong icon using computed prop

Open josselinonduty opened this issue 10 months ago • 4 comments

Icons an not rendering correctly when using conditional or computed links.

I am creating a conditional horizontal navigation (using Nuxt UI v2.21.0 and Nuxt icon).

session is a ref provided by better auth. It is empty on first load, and is then hydrated.

const links = computed(() => {
  let _links = [
    [
      {
        label: "Home",
        icon: "tabler:home",
        to: "/",
      },
    ],
    [
      !session.value.data?.user && {
        label: "Register",
        icon: "tabler:user-plus",
        to: "/auth/register",
      },
      !session.value.data?.user && {
        label: "Login",
        icon: "tabler:user",
        to: "/auth/login",
      },
      session.value.data?.user && {
        label: "Logout",
        icon: "tabler:logout",
        to: "/auth/logout",
      },
    ],
  ];

  return _links.map((list) => list.filter(Boolean)) as Exclude<
    (typeof _links)[number][number],
    undefined | false
  >[][];
});

Screenshots:

Before login:

Image

After login:

Image

In fact, when I go into iconify css class definition, this is what I get:

:where(.i-tabler\:logout) {
    display: inline-block;
    width: 1em;
    height: 1em;
    background-color: currentColor;
    -webkit-mask-image: var(--svg);
    mask-image: var(--svg);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
    --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M8 7a4 4 0 1 0 8 0a4 4 0 0 0-8 0m8 12h6m-3-3v6M6 21v-2a4 4 0 0 1 4-4h4'/%3E%3C/svg%3E");
}

I let you check, but it is the wrong icon. There is some kind of rendering mismatch.

This first issue is not a very good one. I didn't really know what to provide. Please ask me questions if you need more context information.

josselinonduty avatar Feb 02 '25 21:02 josselinonduty

I just faced the same issue somewhere else:

<UInput
        v-model="input.email"
        :icon="
          session.data?.user.emailVerified
            ? 'tabler:rosette-discount-check'
            : 'tabler:rosette-discount-check-off'
        "
        :color="session.data?.user.emailVerified ? 'green' : 'red'"
        disabled
      />

It is always showing the first one: 'tabler:rosette-discount-check'

There is definitely a caching or rendering issue with nuxt icon

josselinonduty avatar Feb 03 '25 00:02 josselinonduty

Indeed, just came across this issue @josselinonduty

There is a cache directory.

Run ls -la .nuxt/cache/nuxt/icon and you'll notice every icon cached until now. You can remove the cache manually, I wonder if restarting the server discards the cache

noook avatar Feb 05 '25 16:02 noook

Did not work for me. I emptied the cache, reloaded the server, the issue is still there

josselinonduty avatar Feb 05 '25 17:02 josselinonduty

Fixed it (but seems more like a hack)

nuxt.config.ts

icon: {
    clientBundle: {
      icons: [
        "tabler:home",
        "tabler:list",
        "tabler:user-plus",
        "tabler:user",
        "tabler:logout",
        "tabler:rosette-discount-check",
        "tabler:rosette-discount-check-off",
      ],
    },
  },

I don't like this approach though. Also, the wrong icon flashes before the correct one appears.

josselinonduty avatar Feb 05 '25 18:02 josselinonduty