Framework
Features

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:

config/Icons.config.php
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");
MethodSets
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 offersSo you can
A search boxFilter by name, source or Material Symbol name as you type.
Folder navigationJump to a folder, each showing its icon count.
Source filtersShow only the google, fontAwesome or custom icons.
Light & dark modesCheck the icons against both themes — the choice is remembered.
A card per iconSee 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:

icons/icons.json
{
    "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.