Let's focus on #hpa-cart, or the cart icon.
Step 1 - Documentation instructions
First, go to the documentation page and follow the steps to add your own iconpack.svg
file.
About iconpack.svg
VTEX IO icon system is based on SVG Sprites. If you're not familiar, it's basically a big file where each SVG file is wrapped inside a Symbol (<symbol
) or Group (<g>
) element identified by an id
. With this ID you can instantiate your SVG element throughout the codebase with the <use />
element. One of the perks here is dealing with one single file download, that can even be optimized to an inline element at top level of your document. This CSS Tricks article is a good start point.
In VTEX IO context iconpack.svg
is the base file for the SVG Sprite system and contains all icons you'll see throughout native components.
Step 2 - Editing your icon
Now that you have your own version of iconpack.svg
you can start your updates.
SVG Sprites use IDs and identifier, so you first need the ID of the icon you want to modify. In order to grab this ID, inspect the element and look for the <use>
element href
.
For the cart icon, it would be hpa-cart
. Open your iconpack.svg
file and search for this ID. You'll replace the content of this group by the content of the SVG file of your icon.
Now starts the tricky part.
Step 3 - Prepare your SVG
In a nutshell, SVGs for VTEX IO icons need to follow at least these 3 requirements:
-
viewBox
of 16x16 - No strokes, only fill
- No text, unless outlined.
I'll give an example using an icon from Heroicons.
Heroicons offers a quick way to copy the SVG by hovering the icon on their landing page. Here's how it looks like:
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" />
</svg>
We have a few problems:
- The viewBox is 24x24 (
0 0 24 24
) -
<path>
usesstroke
Let's fix this on Figma. Steps will be very similar for any other modern UI software, like XD.
Fixing viewBox and SVGs styles for VTEXIO
Create a new file on your UI app or open your layout file, if you're already working with one.
In my example, I don't have a working layout file, so I'll create a new one and paste the SVG icon just to show how to set your icon.
For our working case, I'll start by converting stroke to fill using Outline stroke
.
Now, to fix viewBox, simply change the size of the element. Ideally, your icon should have a 1x1 aspect ration, but it might still work with a slightly different aspect ratio. In our case, I'll change the larger dimension (18, height) to 16, toggling proportional resizing.
Notice that just changing the viewBox attribute on the code will not work, since all the SVG coordinates will need to be recalculated.
That's it for editing. Now, copy your icon as SVG (most apps will have this option, if not just export it)
Adding the new icon to iconpack
Paste the copied SVG into your code editor. It will look like this:
Copy the inner content of the <svg>
(but not the svg
tag itself) and go back to iconpack.svg
. Replace the inner content of <g>
with the brand new code:
Save it and your UI should be updated with your new icon.
Changing the icon color
Notice above that our new icon has an attribute fill="black"
. That's not good and will cause troubles for theming. VTEX IO apply color on icons based on the parent element color, so in order to work as expected we need to change fill
to currentColor
. If your element do not have fill
attribute, add it.
Now your icon will respond as expected to color
attribute on the parent.
That's it.
FAQ
My iconpack is not updating
Since iconpack.svg
is an asset, it needs a hard-refresh to work, unlike other components that respond to hot reload. It might be the case to unlink
and link
again.
Can I add new icons?
Sure, you can create new icons. If you want to have custom icons for a Menu item, just add them to iconpack with an ID that you'll use to reference it. I'd suggest to prefix your icon id with custom-
or something that identify your theme. One benefit in using the icon for menu items is that menu-item
block has it's own viewBox
property, so it won't default to 16x16 like the rest of the icon system.
What if the viewBox is not 16x16?
As the example above show, it will still work if the viewBox is slightly different, since the largest dimension is not bigger than 16. But there's a caveat when it comes to not 1x1 aspect ratios. Notice on the screenshot result above our icon is aligned to the left. This happened because our icon is not a perfect 1x1. If that's not tolerable and you can't have your icon drawn within a 1x1 proportion, you'll have to fix it. One possible workaround is:
Create a 16x16 rectangle; place your icon on center of this rectangle; group them; copy the SVG code of the group.
The code will look like this. Copy all but the <rect />
element, which is the rectangle you just created.
Update your iconpack
with it and now your icon should have more even side space.
Technically, this could be solved with a more robust approach like SVG preserveAspectRatio, but it's not possible to pass down custom attributes to SVG elements in VTEXIO.
SVG can be sometimes confusing and there's plenty scenarios that will require special attention. Hope this can help you at least to get started and never use ::before
again!
Top comments (0)