Icons
Drop SVG files into folders and the build turns them into a stylesheet of
icon-<name> classes — inlined, tintable with currentColor, and with a preview page
to browse them.
The source folder
Icons are plain .svg files grouped in folders, one folder per family. The file name becomes the
icon name:
icons/
├── actions/
│ ├── add.svg
│ └── delete.svg
└── social/
├── facebook.svg
└── x.svg
Registering an icon set
Point the builder at that directory and register one or more icon sets in a config file. A set has a name, the folders it pulls from, and where its stylesheet is written — so an app can ship one bundle for the admin and a smaller one for the public site:
use Framework\Core\Icons;
Icons::setSource("icons");
Icons::setPreview("public/icons.html");
Icons::setMapping("icons/icons.json");
Icons::register("admin", [ "actions", "social" ], "public/css/icons.css");
Icons::register("site", [ "social" ], "public/css/site-icons.css");| Method | Sets |
|---|---|
setSource(path) | The directory holding the icon folders. Required. |
register(name, folders, stylePath) | An icon set: which folders go into which stylesheet. |
setPreview(path) | Optional HTML page listing every icon. |
setMapping(path) | Optional JSON file describing where each icon came from. |
Generating
./framework icons
The command reads each folder, builds a stylesheet per registered set and writes the preview page, reporting what it found. Nothing is generated if no source directory or no set is registered.
The preview page
When you set a setPreview() path, the build also writes a self-contained HTML page — a small
browser for your whole icon library. It has no dependencies and inlines its own styles and script, so you can open
the file directly or serve it with the app:
Icons::setPreview("public/icons.html");
The page renders every icon grouped by folder, and is built for finding one quickly:
| It offers | So you can |
|---|---|
| A search box | Filter by name, source or Material Symbol name as you type. |
| Folder navigation | Jump to a folder, each showing its icon count. |
| Source filters | Show only the google, fontAwesome or custom icons. |
| Light & dark modes | Check the icons against both themes — the choice is remembered. |
| A card per icon | See the icon rendered large, with its class name and source badge. |
The extra detail comes from the mapping file: with it in place each card shows where the
icon came from, and a google icon links straight to its page on Google Fonts for re-exporting.
The generated CSS
Each icon is inlined as a data url on a custom property, and a single base rule renders it as a CSS mask — which is what lets an icon take its color from the surrounding text:
[class^="icon-"]:before,
[class*=" icon-"]:before {
content: "";
display: inline-block;
width: 1em;
height: 1em;
background-color: currentColor;
mask: var(--icon) no-repeat center / contain;
}
.icon-add:before { --icon: url("data:image/svg+xml,…"); }
.icon-delete:before { --icon: url("data:image/svg+xml,…"); }
Use it by class — the icon sizes with the font (1em) and inherits the text color, so no fill or
size attributes are needed:
<i class="icon-add"></i>
<button class="icon-delete">Delete</button>
The mapping file
The optional mapping records where each icon came from, so a set stays maintainable as it grows — you can tell at a glance which icons are Material Symbols, which are Font Awesome and which were drawn by hand. It is keyed by folder and icon name, and validated in your editor by the icons JSON schema:
{
"actions": {
"add": "google add_circle fill",
"delete": "google delete w300 s24"
},
"social": {
"facebook": "fontAwesome",
"x": "custom"
}
}A google entry names its Material Symbol and its modifiers, so the preview page can link straight
back to the icon on Google Fonts when you need to re-export it.