@featherk/icons 0.13.9 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/fontawesome/build.cjs +4 -0
- package/dist/fontawesome/build.d.ts +3 -0
- package/dist/fontawesome/build.mjs +4 -0
- package/dist/fontawesome/chunks/generate-Bobf_ghm.cjs +288 -0
- package/dist/fontawesome/chunks/generate-Bp92GTVi.mjs +289 -0
- package/dist/fontawesome/cli.cjs +66 -0
- package/dist/fontawesome/cli.d.ts +6 -0
- package/dist/fontawesome/cli.mjs +66 -0
- package/dist/fontawesome/cli.test.d.ts +1 -0
- package/dist/fontawesome/fontawesome-service.d.ts +5 -0
- package/dist/fontawesome/fontawesome-service.test.d.ts +1 -0
- package/dist/fontawesome/generate.d.ts +18 -0
- package/dist/fontawesome/generate.test.d.ts +1 -0
- package/dist/fontawesome/index.cjs +20 -0
- package/dist/fontawesome/index.d.ts +3 -0
- package/dist/fontawesome/index.mjs +20 -0
- package/dist/fontawesome/normalize.d.ts +3 -0
- package/dist/fontawesome/normalize.test.d.ts +1 -0
- package/dist/fontawesome/types.d.ts +21 -0
- package/dist/fontawesome/vite.cjs +72 -0
- package/dist/fontawesome/vite.d.ts +6 -0
- package/dist/fontawesome/vite.mjs +72 -0
- package/dist/fontawesome/vite.test.d.ts +1 -0
- package/docs/ICONS.md +1 -1
- package/docs/fontawesome/CreateFontAwesomeManifest.md +109 -0
- package/docs/fontawesome/FontAwesome.md +252 -0
- package/docs/fontawesome/FontAwesomeCLI.md +64 -0
- package/docs/fontawesome/LICENSING.md +140 -0
- package/package.json +40 -4
- package/scripts/fontawesome.mjs +4 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { parseArgs } from "node:util";
|
|
4
|
+
import { g as generateFaIcons } from "./chunks/generate-Bp92GTVi.mjs";
|
|
5
|
+
const usage = `Usage: featherk-fontawesome --manifest <icons.json> [--root <project>] [--source-root <installed-sources>] [--out <icons.mjs>] [--virtual-types <types.d.ts>]
|
|
6
|
+
|
|
7
|
+
The JSON manifest must contain { "icons": [...] } with exact installed selections.
|
|
8
|
+
Provide --out, --virtual-types, or both. Paths are relative to the project root.
|
|
9
|
+
This command does not download assets or authenticate; install licensed packages first.
|
|
10
|
+
Generated assets belong to the consuming project, never the @featherk/icons package.`;
|
|
11
|
+
async function runFontAwesomeCli(args, io = {}) {
|
|
12
|
+
const stdout = io.stdout ?? console.log;
|
|
13
|
+
const stderr = io.stderr ?? console.error;
|
|
14
|
+
try {
|
|
15
|
+
const { values } = parseArgs({
|
|
16
|
+
args: [...args],
|
|
17
|
+
options: {
|
|
18
|
+
manifest: { type: "string" },
|
|
19
|
+
root: { type: "string" },
|
|
20
|
+
"source-root": { type: "string" },
|
|
21
|
+
out: { type: "string" },
|
|
22
|
+
"virtual-types": { type: "string" },
|
|
23
|
+
help: { type: "boolean", short: "h" }
|
|
24
|
+
},
|
|
25
|
+
strict: true,
|
|
26
|
+
allowPositionals: false
|
|
27
|
+
});
|
|
28
|
+
if (values.help) {
|
|
29
|
+
stdout(usage);
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
if (!values.manifest?.trim() || !values.out?.trim() && !values["virtual-types"]?.trim()) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
"Provide --manifest and at least one of --out or --virtual-types. Use --help for usage."
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
const root = resolve(io.cwd ?? process.cwd(), values.root ?? ".");
|
|
38
|
+
const manifest = JSON.parse(
|
|
39
|
+
await readFile(resolve(root, values.manifest), "utf8")
|
|
40
|
+
);
|
|
41
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest) || !Array.isArray(manifest.icons)) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
'Font Awesome manifest must be a JSON object with an "icons" array'
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
const result = await generateFaIcons({
|
|
47
|
+
root,
|
|
48
|
+
sourceRoot: values["source-root"],
|
|
49
|
+
icons: manifest.icons,
|
|
50
|
+
outFile: values.out,
|
|
51
|
+
virtualTypesFile: values["virtual-types"]
|
|
52
|
+
});
|
|
53
|
+
stdout(
|
|
54
|
+
`Prepared ${result.provenance.length} selected Font Awesome icon(s). Preserve generated license notices in application distribution.`
|
|
55
|
+
);
|
|
56
|
+
return 0;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
stderr(
|
|
59
|
+
`Font Awesome generation failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
60
|
+
);
|
|
61
|
+
return 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
runFontAwesomeCli
|
|
66
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FontAwesomeIcon } from "./types";
|
|
2
|
+
export interface FontAwesomeService<Key extends string = string> {
|
|
3
|
+
getFaIcon(key: Key): FontAwesomeIcon;
|
|
4
|
+
}
|
|
5
|
+
export declare function createFontAwesomeService<Key extends string>(icons: Readonly<Record<Key, FontAwesomeIcon>>): FontAwesomeService<Key>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FontAwesomeOptions, FontAwesomeSelection } from "./types";
|
|
2
|
+
export interface GenerateFaIconsOptions extends FontAwesomeOptions {
|
|
3
|
+
outFile?: string;
|
|
4
|
+
virtualTypesFile?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface FontAwesomeProvenance extends FontAwesomeSelection {
|
|
7
|
+
sourcePackage: string;
|
|
8
|
+
exportName: string;
|
|
9
|
+
}
|
|
10
|
+
export interface GeneratedFaIcons {
|
|
11
|
+
moduleCode: string;
|
|
12
|
+
declarationCode: string;
|
|
13
|
+
virtualDeclarationCode: string;
|
|
14
|
+
notices: string;
|
|
15
|
+
provenance: readonly FontAwesomeProvenance[];
|
|
16
|
+
dependencies: readonly string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function generateFaIcons(options: GenerateFaIconsOptions): Promise<GeneratedFaIcons>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
function createFontAwesomeService(icons) {
|
|
4
|
+
const registry = /* @__PURE__ */ new Map();
|
|
5
|
+
for (const key of Object.keys(icons)) {
|
|
6
|
+
registry.set(key, { ...icons[key] });
|
|
7
|
+
}
|
|
8
|
+
return {
|
|
9
|
+
getFaIcon(key) {
|
|
10
|
+
const icon = registry.get(key);
|
|
11
|
+
if (!icon) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
`Font Awesome icon "${key}" is not in this project's selections`
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
return { ...icon };
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
exports.createFontAwesomeService = createFontAwesomeService;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
function createFontAwesomeService(icons) {
|
|
2
|
+
const registry = /* @__PURE__ */ new Map();
|
|
3
|
+
for (const key of Object.keys(icons)) {
|
|
4
|
+
registry.set(key, { ...icons[key] });
|
|
5
|
+
}
|
|
6
|
+
return {
|
|
7
|
+
getFaIcon(key) {
|
|
8
|
+
const icon = registry.get(key);
|
|
9
|
+
if (!icon) {
|
|
10
|
+
throw new Error(
|
|
11
|
+
`Font Awesome icon "${key}" is not in this project's selections`
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
return { ...icon };
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export {
|
|
19
|
+
createFontAwesomeService
|
|
20
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface FontAwesomeIcon {
|
|
2
|
+
name: string;
|
|
3
|
+
content: string;
|
|
4
|
+
viewBox: string;
|
|
5
|
+
}
|
|
6
|
+
export type FontAwesomeFamily = "classic" | "sharp" | "duotone" | "sharp-duotone";
|
|
7
|
+
export type FontAwesomeStyle = "solid" | "regular" | "light" | "thin" | "brands";
|
|
8
|
+
export interface FontAwesomeSelection {
|
|
9
|
+
key: string;
|
|
10
|
+
name: string;
|
|
11
|
+
version: string;
|
|
12
|
+
family: FontAwesomeFamily;
|
|
13
|
+
style: FontAwesomeStyle;
|
|
14
|
+
package: string;
|
|
15
|
+
exportName?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface FontAwesomeOptions {
|
|
18
|
+
icons: readonly FontAwesomeSelection[];
|
|
19
|
+
root?: string;
|
|
20
|
+
sourceRoot?: string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const node_path = require("node:path");
|
|
4
|
+
const promises = require("node:fs/promises");
|
|
5
|
+
const generate = require("./chunks/generate-Bobf_ghm.cjs");
|
|
6
|
+
const virtualId = "virtual:featherk/fontawesome";
|
|
7
|
+
const resolvedId = `\0${virtualId}`;
|
|
8
|
+
function dependencyKey(file) {
|
|
9
|
+
const path = node_path.resolve(file).replaceAll("\\", "/");
|
|
10
|
+
return process.platform === "win32" ? path.toLowerCase() : path;
|
|
11
|
+
}
|
|
12
|
+
function featherkFontAwesome(options) {
|
|
13
|
+
let root = node_path.resolve(options.root ?? process.cwd());
|
|
14
|
+
let generation;
|
|
15
|
+
let dependencies = /* @__PURE__ */ new Set();
|
|
16
|
+
function regenerate() {
|
|
17
|
+
generation = generate.generateFaIcons({
|
|
18
|
+
icons: options.icons,
|
|
19
|
+
root,
|
|
20
|
+
sourceRoot: options.sourceRoot,
|
|
21
|
+
virtualTypesFile: options.virtualTypesFile === false ? void 0 : options.virtualTypesFile ?? "src/featherk-fontawesome.d.ts"
|
|
22
|
+
}).then((result) => {
|
|
23
|
+
dependencies = new Set(result.dependencies.map(dependencyKey));
|
|
24
|
+
return result;
|
|
25
|
+
});
|
|
26
|
+
return generation;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
name: "featherk-fontawesome",
|
|
30
|
+
enforce: "pre",
|
|
31
|
+
async configResolved(config) {
|
|
32
|
+
root = node_path.resolve(config.root, options.root ?? ".");
|
|
33
|
+
await regenerate();
|
|
34
|
+
},
|
|
35
|
+
async buildStart() {
|
|
36
|
+
const result = await regenerate();
|
|
37
|
+
for (const file of result.dependencies) this.addWatchFile(file);
|
|
38
|
+
},
|
|
39
|
+
resolveId(id) {
|
|
40
|
+
return id === virtualId ? resolvedId : void 0;
|
|
41
|
+
},
|
|
42
|
+
async load(id) {
|
|
43
|
+
if (id !== resolvedId) return void 0;
|
|
44
|
+
return (await (generation ?? regenerate())).moduleCode;
|
|
45
|
+
},
|
|
46
|
+
async configureServer(server) {
|
|
47
|
+
const result = await (generation ?? regenerate());
|
|
48
|
+
server.watcher.add(result.dependencies);
|
|
49
|
+
},
|
|
50
|
+
async handleHotUpdate(context) {
|
|
51
|
+
const file = await promises.realpath(context.file).catch(() => context.file);
|
|
52
|
+
if (!dependencies.has(dependencyKey(file))) return void 0;
|
|
53
|
+
const result = await regenerate();
|
|
54
|
+
context.server.watcher.add(result.dependencies);
|
|
55
|
+
const module2 = context.server.moduleGraph.getModuleById(resolvedId);
|
|
56
|
+
if (module2) context.server.moduleGraph.invalidateModule(module2);
|
|
57
|
+
context.server.ws.send({ type: "full-reload" });
|
|
58
|
+
return [];
|
|
59
|
+
},
|
|
60
|
+
async generateBundle() {
|
|
61
|
+
const result = await (generation ?? regenerate());
|
|
62
|
+
if (result.notices) {
|
|
63
|
+
this.emitFile({
|
|
64
|
+
type: "asset",
|
|
65
|
+
fileName: "featherk-fontawesome.licenses.txt",
|
|
66
|
+
source: result.notices
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
exports.featherkFontAwesome = featherkFontAwesome;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
import type { FontAwesomeOptions } from "./types";
|
|
3
|
+
export interface FontAwesomeViteOptions extends FontAwesomeOptions {
|
|
4
|
+
virtualTypesFile?: string | false;
|
|
5
|
+
}
|
|
6
|
+
export declare function featherkFontAwesome(options: FontAwesomeViteOptions): Plugin;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { realpath } from "node:fs/promises";
|
|
3
|
+
import { g as generateFaIcons } from "./chunks/generate-Bp92GTVi.mjs";
|
|
4
|
+
const virtualId = "virtual:featherk/fontawesome";
|
|
5
|
+
const resolvedId = `\0${virtualId}`;
|
|
6
|
+
function dependencyKey(file) {
|
|
7
|
+
const path = resolve(file).replaceAll("\\", "/");
|
|
8
|
+
return process.platform === "win32" ? path.toLowerCase() : path;
|
|
9
|
+
}
|
|
10
|
+
function featherkFontAwesome(options) {
|
|
11
|
+
let root = resolve(options.root ?? process.cwd());
|
|
12
|
+
let generation;
|
|
13
|
+
let dependencies = /* @__PURE__ */ new Set();
|
|
14
|
+
function regenerate() {
|
|
15
|
+
generation = generateFaIcons({
|
|
16
|
+
icons: options.icons,
|
|
17
|
+
root,
|
|
18
|
+
sourceRoot: options.sourceRoot,
|
|
19
|
+
virtualTypesFile: options.virtualTypesFile === false ? void 0 : options.virtualTypesFile ?? "src/featherk-fontawesome.d.ts"
|
|
20
|
+
}).then((result) => {
|
|
21
|
+
dependencies = new Set(result.dependencies.map(dependencyKey));
|
|
22
|
+
return result;
|
|
23
|
+
});
|
|
24
|
+
return generation;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
name: "featherk-fontawesome",
|
|
28
|
+
enforce: "pre",
|
|
29
|
+
async configResolved(config) {
|
|
30
|
+
root = resolve(config.root, options.root ?? ".");
|
|
31
|
+
await regenerate();
|
|
32
|
+
},
|
|
33
|
+
async buildStart() {
|
|
34
|
+
const result = await regenerate();
|
|
35
|
+
for (const file of result.dependencies) this.addWatchFile(file);
|
|
36
|
+
},
|
|
37
|
+
resolveId(id) {
|
|
38
|
+
return id === virtualId ? resolvedId : void 0;
|
|
39
|
+
},
|
|
40
|
+
async load(id) {
|
|
41
|
+
if (id !== resolvedId) return void 0;
|
|
42
|
+
return (await (generation ?? regenerate())).moduleCode;
|
|
43
|
+
},
|
|
44
|
+
async configureServer(server) {
|
|
45
|
+
const result = await (generation ?? regenerate());
|
|
46
|
+
server.watcher.add(result.dependencies);
|
|
47
|
+
},
|
|
48
|
+
async handleHotUpdate(context) {
|
|
49
|
+
const file = await realpath(context.file).catch(() => context.file);
|
|
50
|
+
if (!dependencies.has(dependencyKey(file))) return void 0;
|
|
51
|
+
const result = await regenerate();
|
|
52
|
+
context.server.watcher.add(result.dependencies);
|
|
53
|
+
const module = context.server.moduleGraph.getModuleById(resolvedId);
|
|
54
|
+
if (module) context.server.moduleGraph.invalidateModule(module);
|
|
55
|
+
context.server.ws.send({ type: "full-reload" });
|
|
56
|
+
return [];
|
|
57
|
+
},
|
|
58
|
+
async generateBundle() {
|
|
59
|
+
const result = await (generation ?? regenerate());
|
|
60
|
+
if (result.notices) {
|
|
61
|
+
this.emitFile({
|
|
62
|
+
type: "asset",
|
|
63
|
+
fileName: "featherk-fontawesome.licenses.txt",
|
|
64
|
+
source: result.notices
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export {
|
|
71
|
+
featherkFontAwesome
|
|
72
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/docs/ICONS.md
CHANGED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Choose Font Awesome Icons and Create a Manifest
|
|
2
|
+
|
|
3
|
+
This is the UX/Design starting point for choosing the exact Font Awesome variants an application intends to use and recording them in its selection manifest. It covers icon selection, approval, naming, and manifest fields. For integration and build setup, continue to [Font Awesome Build Integration](FontAwesome.md); CLI and non-Vite workflows are in [the CLI supplement](FontAwesomeCLI.md).
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
1. Select the exact catalog icon, family, and style; note whether the variant is Free or Pro.
|
|
8
|
+
2. Agree on the exact release and obtain the required UX and license approvals.
|
|
9
|
+
3. Assign a unique application key and identify the package that supplies the variant and release.
|
|
10
|
+
4. Add or update the selection in the application's manifest and review the full selection set.
|
|
11
|
+
|
|
12
|
+
The steps below help UX/Design create a precise handoff. Do not assume every icon exists in every family, style, or release.
|
|
13
|
+
|
|
14
|
+
## Where Each Field Comes From
|
|
15
|
+
|
|
16
|
+
| Field | Who supplies it | Meaning |
|
|
17
|
+
| --------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
18
|
+
| `key` | UX/application convention | Unique application lookup identifier, such as `pro-house-light`; passed to `getFaIcon()` |
|
|
19
|
+
| `name` | Font Awesome catalog | Canonical icon name, such as `house`, without the `fa-` CSS prefix |
|
|
20
|
+
| `version` | Approved release policy | Exact source-package release, such as `7.0.0`, not `latest`, a range, or the first version that introduced the icon |
|
|
21
|
+
| `family` | Selected Font Awesome family | Supported family identifier, such as `classic` or `sharp` |
|
|
22
|
+
| `style` | Selected Font Awesome style | Supported style identifier, such as `solid`, `regular`, or `light` |
|
|
23
|
+
| `package` | Engineering confirms the source mapping | Exact installed package name or alias that supplies the selected family, style, and version |
|
|
24
|
+
|
|
25
|
+
The catalog identifies the canonical `name`, `family`, `style`, and Free/Pro availability. UX/Design proposes the application `key` and approved release. Engineering confirms the exact npm package or alias for `package`; Dev installs that package at the manifest's exact `version`. Do not guess package names. A catalog page alone does not establish historical release availability or license entitlement.
|
|
26
|
+
|
|
27
|
+
## Step 1: Select and Approve the Catalog Variant
|
|
28
|
+
|
|
29
|
+
Open the [Font Awesome catalog](https://fontawesome.com/search), select an icon, and open its details. Select the exact family/style rather than approving only the icon name. Confirm whether that variant is Free or Pro.
|
|
30
|
+
|
|
31
|
+
Copied markup can help identify the selection:
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<!-- Step 1: This identifies Classic Regular heart, not a package version. -->
|
|
35
|
+
<i class="fa-regular fa-heart"></i>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
For this example, the canonical name is `heart`, family is `classic`, and style is `regular`. Confirm those values for the desired release; old CSS names may be compatibility aliases rather than that release's canonical name.
|
|
39
|
+
|
|
40
|
+
UX should hand off the catalog link, canonical name, approved exact release, family, style, and approval record. Agree on an application key separately. Any package/download entitlement must also be confirmed for Pro.
|
|
41
|
+
|
|
42
|
+
Important distinctions:
|
|
43
|
+
|
|
44
|
+
- "Added in v5" describes first availability; it does not mean the installed package is version `5.0.0`.
|
|
45
|
+
- Regular is not Light. Classic Light is Pro-only, and not every Solid icon has a Free Regular counterpart.
|
|
46
|
+
- Outlined Regular artwork can still use filled SVG path shapes; do not replace its path fill with `none` or synthesize an outline with strokes.
|
|
47
|
+
- A current catalog page may describe newer artwork than an approved historical release.
|
|
48
|
+
- Exact v4 font artwork is not supported by the current installed SVG-definition generator.
|
|
49
|
+
|
|
50
|
+
## Step 2: Confirm the Package Mapping
|
|
51
|
+
|
|
52
|
+
Common Classic package mappings are:
|
|
53
|
+
|
|
54
|
+
| Availability | `family` | `style` | Source package |
|
|
55
|
+
| ---------------------------- | --------- | --------- | ------------------------------------- |
|
|
56
|
+
| Free | `classic` | `solid` | `@fortawesome/free-solid-svg-icons` |
|
|
57
|
+
| Free, where a variant exists | `classic` | `regular` | `@fortawesome/free-regular-svg-icons` |
|
|
58
|
+
| Free brands | `classic` | `brands` | `@fortawesome/free-brands-svg-icons` |
|
|
59
|
+
| Pro | `classic` | `solid` | `@fortawesome/pro-solid-svg-icons` |
|
|
60
|
+
| Pro | `classic` | `regular` | `@fortawesome/pro-regular-svg-icons` |
|
|
61
|
+
| Pro | `classic` | `light` | `@fortawesome/pro-light-svg-icons` |
|
|
62
|
+
| Pro | `classic` | `thin` | `@fortawesome/pro-thin-svg-icons` |
|
|
63
|
+
|
|
64
|
+
The `classic`/`brands` rows show common package mappings. Other families include `sharp`, `duotone`, and `sharp-duotone`; confirm their package names and release availability in the [official package documentation](https://docs.fontawesome.com/web/setup/packages). Do not construct package names by guesswork. Pro+ collections requiring Kits are outside this integration.
|
|
65
|
+
|
|
66
|
+
For Pro variants, confirm entitlement and release approval with the license owner before adding them. See [Pro licensing and setup](LICENSING.md). Engineering should confirm that the package recorded in the manifest is installed and supplies the requested variant.
|
|
67
|
+
|
|
68
|
+
## Step 3: Write the Complete Manifest Entry
|
|
69
|
+
|
|
70
|
+
Add the selection to an `icons` array. The filename is project-owned; this example uses a Free selection manifest:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"icons": [
|
|
75
|
+
{
|
|
76
|
+
"key": "heart-outline",
|
|
77
|
+
"name": "heart",
|
|
78
|
+
"version": "7.0.0",
|
|
79
|
+
"family": "classic",
|
|
80
|
+
"style": "regular",
|
|
81
|
+
"package": "@fortawesome/free-regular-svg-icons"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
This example records the selected Pro variant. In this repository, Free selections live in `demos/fontawesome.icons.json` and optional licensed selections in `demos/fontawesome.pro.icons.json`; other applications may choose their own manifest filenames.
|
|
88
|
+
|
|
89
|
+
The `key` is the application's identifier and does not need to match the canonical `name`. Use a unique key for each distinct selection. For example, the same canonical icon can be selected with different styles or versions as long as each entry has a different key.
|
|
90
|
+
|
|
91
|
+
## Naming and Uniqueness Rules
|
|
92
|
+
|
|
93
|
+
The generator only requires `key` to be a nonblank string; it does not enforce a casing or punctuation style. For readability, UX/Design should use lowercase kebab-case and choose a stable, descriptive key:
|
|
94
|
+
|
|
95
|
+
- Use the canonical icon name as the key when only one variant is selected, such as `rocket`.
|
|
96
|
+
- Add the style when the application needs multiple variants, such as `heart-regular` or `feather-light`.
|
|
97
|
+
- Add a version suffix only when multiple releases must coexist, such as `rocket-v5` and `rocket-v6`.
|
|
98
|
+
- Do not reuse a key for a different icon identity. If the selected variant changes, review the key and all application references with Engineering.
|
|
99
|
+
- Check keys across every manifest enabled together in a build, including combined Free and Pro selections. A key repeated in separate files is still a duplicate when those files are combined.
|
|
100
|
+
|
|
101
|
+
These are UX naming conventions; only blank and duplicate keys are rejected by the generator. The application uses the key for lookup, while `name`, `family`, `style`, `version`, and `package` identify the source artwork.
|
|
102
|
+
|
|
103
|
+
## UX/Design Handoff
|
|
104
|
+
|
|
105
|
+
For each selection, provide the catalog link, canonical name, family, style, exact approved version, application key, Free/Pro status, and package mapping. UX/Design owns the desired variants and manifest change; Engineering confirms that the exact package and release are available and implements the build integration.
|
|
106
|
+
|
|
107
|
+
Catalog approval and source availability are separate. If Engineering cannot resolve the requested package, version, or export, do not silently substitute another icon or release. Return to UX/Design and update the approval and manifest together.
|
|
108
|
+
|
|
109
|
+
After the manifest is ready, continue with [Vite build integration](FontAwesome.md). For Pro selections, review [Pro licensing and setup](LICENSING.md). Non-Vite or pre-typecheck CLI workflows are documented in [the CLI supplement](FontAwesomeCLI.md).
|