Actually the “something better” turned out to be super simple. I wrote a Ruby script, compile_assets that I use as follows:
./compile_assets assets/icons --prefix heroicons --inline > src/heroicon_assets.rez
The script automatically generates the @asset definitions for each file in the assets/icons folder, I just redirect the output to src/heroicons_assets.rez:
@asset heroicons_arrow_path_rounded_square {
$inline: true
file_name: "arrow-path-rounded-square.svg"
}
@asset heroicons_arrow_path {
$inline: true
file_name: "arrow-path.svg"
}
Now my heroicons.rez library is:
%(heroicon_assets.rez)
@styles {
.heroicon {
display: inline-block;
vertical-align: middle;
width: 1.5rem;
height: 1.5rem;
}
}
@component icon (bindings, assigns, content) => {
const icon_name = assigns["icon"];
const icon = $(`heroicon_${icon_name}`);
const event = assigns["event"];
if(event == undefined) {
return `<span class="heroicon">${icon.content}</span>`;
} else {
// When there is an event, process all other assigns as data attributes
let dataAttributes = '';
// Iterate through assigns and convert them to data attributes
// Skip the 'icon' and 'event' attributes as they're handled specially
for (const [key, value] of Object.entries(assigns)) {
if (key !== 'icon' && key !== 'event') {
dataAttributes += ` data-${key}="${value}"`;
}
}
// Create the anchor element with the event and all other data attributes
return `<span class="heroicon"><a data-event="${event}"${dataAttributes}>${icon.content}</a></span>`;
}
}
If I want to use another icon I copy its SVG file into the assets/icons folder and re-run the compile_assets script. Simples!
Here’s my script:
compile_assets.txt (2.1 KB)