@stillwind/plugin-iconify adds Iconify icons as Stillwind utilities. Only the
icons that you use reach your CSS.
Usage
Install the plugin and the icon sets that the project uses:
vp i -D @stillwind/plugin-iconify @iconify-json/mdinpm install -D @stillwind/plugin-iconify @iconify-json/mdipnpm add -D @stillwind/plugin-iconify @iconify-json/mdiyarn add -D @stillwind/plugin-iconify @iconify-json/mdibun add --dev @stillwind/plugin-iconify @iconify-json/mdiLoad the plugin in the project stylesheet:
@import "stillwind";
@plugin "@stillwind/plugin-iconify";Use icon-<set>--<icon> or icon-[<set>--<icon>] to select an icon. Variants apply as
usual. The prefer-canonical-utilities lint
suggests the form without brackets:
<span {...style("icon-mdi--close", "hover:icon-[mdi--close-circle]")} />Sizes
An icon is 1em high by default, and its width follows the icon’s aspect ratio. To change the
height, add a size utility to the same element:
| Utility | Height |
|---|---|
icon-<name> |
The value of the --icon-size-<name> token |
icon-full |
100% of the parent’s height |
icon-[<length>], icon-[<percentage>] |
The given value |
icon-(<custom-property>) |
The value of the given custom property |
To add a named size, define a --icon-size-<name> token in @theme. Its value must be a length
or a percentage. For example, this token adds the icon-lg utility:
@theme {
--icon-size-lg: 1.5rem;
}<span {...style("icon-mdi--close icon-lg")} />icon-full needs a parent with a definite height. In a parent whose height depends on its
content, the icon is 0 high. To size an icon by its width instead, override the height:
icon-mdi--close w-full h-auto fills the parent’s width and keeps the icon’s aspect ratio.
When other utilities, such as size-full or max-w-full, change the box, the SVG keeps its
aspect ratio and stays centered in the box.
A size utility changes only the icon on its own element. A size on a parent does not change the
icons of its children. An icon on ::before or ::after also needs its own size, so give the
size utility the same variant as the icon:
<span {...style("before:icon-mdi--close before:icon-lg")} />Size values follow lint policies configured for height. For example,
no-restricted-length-units with
properties: ["height"] checks their units, and
no-arbitrary-spacing with properties: ["height"]
reports arbitrary sizes, but not named sizes such as icon-lg.
Icon sets
The plugin finds a set in this order:
- The
collectionsoption of a configured instance. - The
@iconify-json/<set>package. - The
@iconify/jsonpackage, which contains every Iconify set.
Install icon set packages in the project that contains your stylesheet. Changes to a
set’s JSON file update its icons automatically. Editors complete the icons of configured sets
and of the @iconify-json/* packages listed in the project’s package.json dependencies.
When @iconify/json is installed, editors also complete its set names, such as icon-mdi--,
and list the icons of a set after the input names it.
License notices
The CSS output starts with a license notice for each icon set whose icons it contains, such as
/*! Material Design Icons | Pictogrammers | Apache 2.0 | ... */. The notice contains the set’s
name, author, and license from the set’s metadata. A @iconify-json/<set> package supplies the
metadata in its info.json file. The @iconify/json package and custom JSON sets supply it in
their info field.
A custom set without metadata adds no notice. It does not use the metadata of an installed set
with the same name. Pass the info option to svgDirectory() to add a notice for a set of SVG
files.
Options
The options block of the statement sets these options:
@plugin "@stillwind/plugin-iconify" {
prefix: i;
syntax: bracket;
scale: 1.2;
mode: mask;
hash-length: 4;
}prefix: utility prefix without the trailing hyphen, such asiconori. Defaults toicon. The--icon-size-*tokens keep their names, so withprefix: i,--icon-size-lgaddsi-lg.syntax: spellings that select an icon.namedacceptsicon-mdi--close,bracketacceptsicon-[mdi--close], andboth, the default, accepts both.scale: icon height inemwhen no size utility applies. Defaults to1.mode:maskpaints the text color through the icon’s shape, andbackgroundpaints the icon’s own colors.auto, the default, selectsmaskfor icons whose SVG usescurrentColor.hash-length: base36 hash length in generated CSS variable names. Accepts integers from1to7and defaults to4. Increase it when using many icons to reduce collisions.
Options in TypeScript
To set options in TypeScript, add iconify() to the plugins list of the project, and keep
@plugin "@stillwind/plugin-iconify"; in your stylesheet. The collections option adds custom
icon sets. A set can be data, an absolute JSON file path, a function that returns data, or an
SVG directory:
import { iconify } from "@stillwind/plugin-iconify";
import { defineConfig } from "stillwind/config";
export default defineConfig({
projects: [
{
css: "src/stillwind.css",
files: ["src/**/*.{ts,tsx}"],
plugins: [
iconify({
collections: {
brand: "/abs/path/brand.json",
},
}),
],
},
],
});iconify() accepts the options of the @plugin block, with hashLength in place of
hash-length. When both set the same option, the @plugin block wins.
Only iconify() can set collections and svgo.
Custom icon set format
A custom icon set uses the Iconify JSON format, which the IconifyJSON type of
@iconify/types describes. This is the same format as the icons.json file of an
@iconify-json/* package:
{
"prefix": "brand",
"width": 24,
"height": 24,
"icons": {
"logo": {
"body": "<path fill=\"currentColor\" d=\"M4 4h16v16H4z\"/>"
},
"badge": {
"body": "<circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"#e11d48\"/>",
"width": 32,
"height": 32
}
},
"aliases": {
"logo-flipped": {
"parent": "logo",
"hFlip": true
}
}
}iconsmaps each icon name to its SVG content.bodycontains the elements inside the<svg>element, without the<svg>element itself.left,top,width, andheightdefine the icon’sviewBox. An icon can set them, and the top level sets the default values for every icon. Missing values default to0,0,16, and16.aliasesmaps additional names to an existing icon inparent. An alias can override theviewBoxvalues and addrotate(quarter turns),hFlip, andvFliptransformations.- The key in
collectionssets the set name in utilities, such asicon-brand--logo. The plugin does not use theprefixfield to find the set.
Set names and icon names must consist of lowercase letters and digits, separated by single
hyphens. Utilities cannot select other names, such as Logo or logo_dark.
With the default mode: auto, an icon whose body contains currentColor paints the text
color, and the other icons keep their own colors. In the example, logo follows the text
color and badge stays red.
The plugin does not validate the data. A JSON file must contain valid JSON, but the plugin treats an icon that it cannot find in the data as an unknown utility.
Icon sets from SVG files
svgDirectory() creates an icon set from the SVG files in a directory. Each file becomes one
icon, and the file name without .svg becomes the icon name:
import { iconify, svgDirectory } from "@stillwind/plugin-iconify";
iconify({
collections: {
brand: svgDirectory("src/icons/brand"),
ui: svgDirectory("src/icons/ui", {
recursive: true,
transform: (svg) => svg.replaceAll('fill="#000"', 'fill="currentColor"'),
}),
},
});The directory can be an absolute path or a path relative to the project directory. Each file
must contain an <svg> element with a viewBox attribute, which sets the icon’s dimensions.
The plugin keeps the style attribute of the <svg> element and its attributes whose names
start with fill or stroke, such as fill-rule. It drops the other attributes of the
<svg> element.
recursive: reads subdirectories. The default icon name joins the path segments with-, such asarrows-leftforarrows/left.svg. Defaults tofalse.name: maps the file path relative to the directory, without.svgand with/separators, to an icon name. Returningundefinedskips the file.transform: rewrites the SVG text of each file before the plugin parses it.info: the set’s name, author, and license in the format of the Iconifyinfofield. The plugin uses it for the license notice.
Loading fails when an icon name is invalid, two files have the same icon name, or a file has
no viewBox. The error names the file. Adding, removing, or editing an SVG file reloads the
icons while a development server or build watcher runs.
A function in collections receives the set name and the host’s read, list, and watch
operations, so you can write similar loaders. Watch each file and directory that the function
reads, such as context.watch(file) and context.watch(directory, "directory").
SVG minification
The plugin minifies the SVG of each icon with SVGO before it embeds the
SVG in CSS. The svgo TypeScript option controls this:
true, the default, usespreset-defaultwithmultipassenabled.- An SVGO configuration object replaces that default configuration.
falseembeds the SVG without minification.
iconify({
svgo: {
multipass: true,
plugins: ["preset-default", "removeDimensions"],
},
});