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

Lucide won't render data-lucide if inside <template> #2635

Open
6 of 30 tasks
dotfrag opened this issue Nov 22, 2024 · 2 comments
Open
6 of 30 tasks

Lucide won't render data-lucide if inside <template> #2635

dotfrag opened this issue Nov 22, 2024 · 2 comments
Labels
🐛 bug Something isn't working

Comments

@dotfrag
Copy link

dotfrag commented Nov 22, 2024

Package

  • lucide
  • lucide-angular
  • lucide-flutter
  • lucide-preact
  • lucide-react
  • lucide-react-native
  • lucide-solid
  • lucide-svelte
  • lucide-vue
  • lucide-vue-next
  • Figma plugin
  • source/main
  • other/not relevant

Version

0.460.0

Can you reproduce this in the latest version?

  • Yes
  • No

Browser

  • Chrome/Chromium
  • Firefox
  • Safari
  • Edge
  • iOS Safari
  • Opera
  • Other/not relevant

Operating system

  • Windows
  • Linux
  • macOS
  • ChromeOS
  • iOS
  • Android
  • Other/not relevant

Description

I'm using the Content Template element (<template>) to render parts of an HTML form that I use as a template (duh) within JavaScript. Elements with data-lucide inside the template tag do not render.

Steps to reproduce

  1. Minimal setup from guide (all icons)
  2. The following input HTML:
    <div>
       <template><i data-lucide="trash-2" class="size-6 stroke-red-600 mx-auto"></i></template>
       <i data-lucide="trash-2" class="size-6 stroke-red-600 mx-auto"></i>
    </div>
  3. Results in:
        <div>
          <template><i data-lucide="trash-2" class="size-6 stroke-red-600 mx-auto"></i></template>
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-lucide="trash-2" class="lucide lucide-trash-2 size-6 stroke-red-600 mx-auto"><path d="M3 6h18"></path><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path><line x1="10" x2="10" y1="11" y2="17"></line><line x1="14" x2="14" y1="11" y2="17"></line></svg>
    </div>

Checklist

  • I have searched if someone has submitted a similar issue before and there weren't any. (Please make sure to also search closed issues, as this issue might already have been resolved.)
@dotfrag dotfrag added the 🐛 bug Something isn't working label Nov 22, 2024
@dotfrag
Copy link
Author

dotfrag commented Nov 22, 2024

I had a quick look at the code. I am not experienced with JS, but I'll try to help:

It seems that lucide searches for elements using querySelectorAll:

const elementsToReplace = document.querySelectorAll(`[${nameAttr}]`);
Array.from(elementsToReplace).forEach((element) =>
replaceElement(element, { nameAttr, icons, attrs }),
);

querySelectorAll doesn't return <template> elements because they are not real elements. However, you can explicitly query them and their content with the following:

// Test to see if the browser supports the HTML template element by checking
// for the presence of the template element's content attribute.
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#examples
if ("content" in document.createElement("template")) {
  document.querySelectorAll('template').forEach((template) =>
    template.content.querySelectorAll('[data-lucide]').forEach((element) =>
      console.log(element)
    )
  );
}

@dotfrag
Copy link
Author

dotfrag commented Nov 22, 2024

As I said, I'm not experienced enough to contribute with a PR. For anyone who encounters this, you might be able to solve it like it did:

Use pnpm patch and edit the code as below:

diff --git a/dist/esm/lucide.js b/dist/esm/lucide.js
index xxx..xxx 100644
--- a/dist/esm/lucide.js
+++ b/dist/esm/lucide.js
@@ -1562,6 +1562,15 @@ const createIcons = ({ icons = {}, nameAttr = "data-lucide", attrs = {} } = {})
   Array.from(elementsToReplace).forEach(
     (element) => replaceElement(element, { nameAttr, icons, attrs })
   );
+  if ("content" in document.createElement("template")) {
+    const templateElements = document.querySelectorAll('template');
+    templateElements.forEach((template) => {
+      const templateContentElementsToReplace = template.content.querySelectorAll(`[${nameAttr}]`);
+      Array.from(templateContentElementsToReplace).forEach(
+        (element) => replaceElement(element, { nameAttr, icons, attrs })
+      );
+    })
+  }
   if (nameAttr === "data-lucide") {
     const deprecatedElements = document.querySelectorAll("[icon-name]");
     if (deprecatedElements.length > 0) {

If you are using Node with npm, there's patch-package.

If you are using bun, there's bun patch, if you are using Deno I have no idea, sorry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant