@sigx/lynx-icons-fa-free 0.4.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Andreas Ekdahl
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # @sigx/lynx-icons-fa-free
2
+
3
+ [Font Awesome Free](https://fontawesome.com/icons?d=gallery&p=2&m=free) adapter for [`@sigx/lynx-icons`](../lynx-icons). Reads glyph data from the official `@fortawesome/*` packages — no glyph data is re-bundled here, so adapter updates and FA releases stay decoupled.
4
+
5
+ Supports the three Free styles: **solid**, **regular**, **brands**.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @sigx/lynx-icons @sigx/lynx-icons-fa-free
11
+ pnpm add @fortawesome/fontawesome-free @fortawesome/free-solid-svg-icons
12
+ # add the others if you need them:
13
+ pnpm add @fortawesome/free-regular-svg-icons @fortawesome/free-brands-svg-icons
14
+ ```
15
+
16
+ ```ts
17
+ // signalx.config.ts
18
+ import { defineLynxConfig } from '@sigx/lynx-cli/config';
19
+
20
+ export default defineLynxConfig({
21
+ iconSets: [
22
+ { id: 'fa', source: '@sigx/lynx-icons-fa-free', styles: ['solid'] },
23
+ { id: 'fab', source: '@sigx/lynx-icons-fa-free', styles: ['brands'] },
24
+ ],
25
+ });
26
+ ```
27
+
28
+ Each `iconSets` entry maps to one runtime `set` id. Declare one per style you want to use — they're tree-shaken independently.
29
+
30
+ ## Usage
31
+
32
+ ```tsx
33
+ import { Icon } from '@sigx/lynx-icons';
34
+
35
+ <Icon set="fa" name="user" />
36
+ <Icon set="fa" name="chevron-right" size={20} color="#0D9488" />
37
+ <Icon set="fab" name="github" size={24} />
38
+ ```
39
+
40
+ Glyph names are kebab-case (`chevron-right`, not `chevronRight`). The adapter converts to FA's `faChevronRight` export internally.
41
+
42
+ ## Why FA v6, not v7?
43
+
44
+ This adapter pins peer FA packages to **`^6`**. Font Awesome v7 dropped TTF distribution — the `webfonts/` directory ships only WOFF2 now, and Lynx Android doesn't support WOFF2. v1 of `@sigx/lynx-icons` doesn't yet use the TTF (SVG mode only), but we keep the peer pinned to v6 so v1.1's font-mode work can land without breaking consumers.
45
+
46
+ The JS API shape (`{ prefix, iconName, icon: [w, h, _, unicode, path] }`) is stable across v6 and v7, so the glyph lookups themselves would work either way.
47
+
48
+ ## Optional styles
49
+
50
+ `regular` and `brands` are marked as **optional peerDeps**. If you only need solid, install just `@fortawesome/free-solid-svg-icons` — calls for unknown styles silently resolve to `null` and `<Icon>` renders the missing-glyph placeholder.
51
+
52
+ ## Dynamic / JSON-driven icons
53
+
54
+ If the icon `name` comes from data (a JSON UI tree, a CMS field) the build-time scanner can't see it. Set `include: ['*']` on the iconSet to ship every glyph the adapter knows about for the configured styles:
55
+
56
+ ```ts
57
+ iconSets: [
58
+ { id: 'fa', source: '@sigx/lynx-icons-fa-free', styles: ['solid'], include: ['*'] },
59
+ ],
60
+ ```
61
+
62
+ This bundles **all ~1 900 FA-solid glyphs** (~2 MB of JS). Use it only on sets that need it; mix with normally-tree-shaken sets for the rest. The build prints the exact glyph count:
63
+
64
+ ```
65
+ [@sigx/lynx-plugin] icons: fa bundling 1956 glyphs (include: ['*'])
66
+ ```
67
+
68
+ `@sigx/lynx-icons`'s upcoming font mode (v1.1) will swap SVG-per-glyph for a single subsetted TTF — dramatically smaller for full-catalog scenarios. Stay tuned.
69
+
70
+ ## API
71
+
72
+ ```ts
73
+ import faAdapter from '@sigx/lynx-icons-fa-free';
74
+
75
+ faAdapter.styles; // ['solid', 'regular', 'brands']
76
+ faAdapter.getGlyph('solid', 'user'); // { codepoint: 0xf007, svg: '<svg…>' }
77
+ faAdapter.getFontPath('solid'); // absolute path to fa-solid-900.ttf
78
+ faAdapter.getGlyph('solid', 'nope-nope'); // null
79
+ ```
80
+
81
+ The adapter is normally consumed by `@sigx/lynx-plugin`'s icons slice — these direct exports are useful for tests and custom tooling.
82
+
83
+ ## Reference app
84
+
85
+ `examples/showcase/src/screens/Settings.tsx` renders `<Icon set="fa" name="user" />`, `house`, `gear`, and `<Icon set="fab" name="github" />` in a card; the build-time scanner picks them up and writes their codepoints into `node_modules/.cache/sigx-lynx-icons/codepoints.mjs`.
@@ -0,0 +1,3 @@
1
+ import type { IconAdapter } from '@sigx/lynx-icons';
2
+ declare const adapter: IconAdapter;
3
+ export default adapter;
package/dist/index.js ADDED
@@ -0,0 +1,82 @@
1
+ import { createRequire as e } from "node:module";
2
+ import { dirname as t, join as n } from "node:path";
3
+ //#region src/index.ts
4
+ var r = e(import.meta.url), i = {
5
+ solid: "@fortawesome/free-solid-svg-icons",
6
+ regular: "@fortawesome/free-regular-svg-icons",
7
+ brands: "@fortawesome/free-brands-svg-icons"
8
+ }, a = {
9
+ solid: "fa-solid-900.ttf",
10
+ regular: "fa-regular-400.ttf",
11
+ brands: "fa-brands-400.ttf"
12
+ }, o = /* @__PURE__ */ new Map();
13
+ function s(e) {
14
+ if (o.has(e)) return o.get(e) ?? null;
15
+ let t = i[e];
16
+ if (!t) return o.set(e, null), null;
17
+ try {
18
+ let n = r(t);
19
+ return o.set(e, n), n;
20
+ } catch {
21
+ return o.set(e, null), null;
22
+ }
23
+ }
24
+ function c(e) {
25
+ return "fa" + e.split("-").map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("");
26
+ }
27
+ function l(e) {
28
+ let t = e.slice(2);
29
+ if (t.length === 0) return "";
30
+ let n = t.charAt(0).toLowerCase();
31
+ for (let e = 1; e < t.length; e++) {
32
+ let r = t.charAt(e);
33
+ r >= "A" && r <= "Z" ? n += "-" + r.toLowerCase() : n += r;
34
+ }
35
+ return n;
36
+ }
37
+ function u() {
38
+ try {
39
+ return n(t(r.resolve("@fortawesome/fontawesome-free/package.json")), "webfonts");
40
+ } catch {
41
+ return null;
42
+ }
43
+ }
44
+ var d = {
45
+ styles: [
46
+ "solid",
47
+ "regular",
48
+ "brands"
49
+ ],
50
+ getGlyph(e, t) {
51
+ let n = s(e);
52
+ if (!n) return null;
53
+ let r = n[c(t)];
54
+ if (!r || !Array.isArray(r.icon)) return null;
55
+ let [i, a, , o, l] = r.icon, u = parseInt(o, 16);
56
+ return Number.isFinite(u) ? {
57
+ codepoint: u,
58
+ svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${i} ${a}" fill="__COLOR__"><path d="${l}"/></svg>`
59
+ } : null;
60
+ },
61
+ getFontPath(e) {
62
+ let t = a[e];
63
+ if (!t) return null;
64
+ let r = u();
65
+ return r ? n(r, t) : null;
66
+ },
67
+ listGlyphs(e) {
68
+ let t = s(e);
69
+ if (!t) return [];
70
+ let n = [];
71
+ for (let [e, r] of Object.entries(t)) {
72
+ if (!e.startsWith("fa") || e.length < 3) continue;
73
+ let t = e.charAt(2);
74
+ t < "A" || t > "Z" || !r || typeof r != "object" || !Array.isArray(r.icon) || n.push(l(e));
75
+ }
76
+ return n;
77
+ }
78
+ };
79
+ //#endregion
80
+ export { d as default };
81
+
82
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport type { GlyphData, IconAdapter } from '@sigx/lynx-icons';\n\nconst require = createRequire(import.meta.url);\n\nconst STYLE_TO_PACKAGE: Record<string, string> = {\n solid: '@fortawesome/free-solid-svg-icons',\n regular: '@fortawesome/free-regular-svg-icons',\n brands: '@fortawesome/free-brands-svg-icons',\n};\n\nconst STYLE_TO_TTF: Record<string, string> = {\n solid: 'fa-solid-900.ttf',\n regular: 'fa-regular-400.ttf',\n brands: 'fa-brands-400.ttf',\n};\n\ninterface FaIconEntry {\n prefix: string;\n iconName: string;\n icon: [number, number, unknown[], string, string];\n}\n\nconst moduleCache = new Map<string, Record<string, FaIconEntry> | null>();\n\nfunction loadStyleModule(style: string): Record<string, FaIconEntry> | null {\n if (moduleCache.has(style)) return moduleCache.get(style) ?? null;\n const pkg = STYLE_TO_PACKAGE[style];\n if (!pkg) {\n moduleCache.set(style, null);\n return null;\n }\n try {\n const mod = require(pkg) as Record<string, FaIconEntry>;\n moduleCache.set(style, mod);\n return mod;\n } catch {\n moduleCache.set(style, null);\n return null;\n }\n}\n\n/** Convert kebab-case glyph name → FA's PascalCase export name (`faChevronRight`). */\nfunction exportNameFor(name: string): string {\n return 'fa' + name.split('-').map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1)).join('');\n}\n\n/**\n * Inverse of `exportNameFor`: `faChevronRight` → `chevron-right`.\n * Used by `listGlyphs` to walk `Object.keys(module)` and emit canonical names.\n */\nfunction kebabFromExportName(exportName: string): string {\n // Strip the leading `fa` prefix.\n const body = exportName.slice(2);\n if (body.length === 0) return '';\n // Split on each uppercase letter and join with `-`, lowercasing everything.\n let out = body.charAt(0).toLowerCase();\n for (let i = 1; i < body.length; i++) {\n const ch = body.charAt(i);\n if (ch >= 'A' && ch <= 'Z') {\n out += '-' + ch.toLowerCase();\n } else {\n out += ch;\n }\n }\n return out;\n}\n\nfunction webfontsDir(): string | null {\n try {\n const pkgJson = require.resolve('@fortawesome/fontawesome-free/package.json');\n return join(dirname(pkgJson), 'webfonts');\n } catch {\n return null;\n }\n}\n\nconst adapter: IconAdapter = {\n styles: ['solid', 'regular', 'brands'],\n\n getGlyph(style: string, name: string): GlyphData | null {\n const mod = loadStyleModule(style);\n if (!mod) return null;\n const entry = mod[exportNameFor(name)];\n if (!entry || !Array.isArray(entry.icon)) return null;\n const [w, h, , unicodeHex, path] = entry.icon;\n const codepoint = parseInt(unicodeHex, 16);\n if (!Number.isFinite(codepoint)) return null;\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" fill=\"__COLOR__\"><path d=\"${path}\"/></svg>`;\n return { codepoint, svg };\n },\n\n getFontPath(style: string): string | null {\n const filename = STYLE_TO_TTF[style];\n if (!filename) return null;\n const dir = webfontsDir();\n if (!dir) return null;\n return join(dir, filename);\n },\n\n listGlyphs(style: string): string[] {\n const mod = loadStyleModule(style);\n if (!mod) return [];\n const out: string[] = [];\n for (const [key, entry] of Object.entries(mod)) {\n // The FA modules also export `prefix` ('fas' / 'far' / 'fab') and a\n // single-letter alias matching the prefix. Filter to real icon\n // entries — objects with a numeric icon[0] and a string icon[4].\n if (!key.startsWith('fa') || key.length < 3) continue;\n const ch = key.charAt(2);\n if (ch < 'A' || ch > 'Z') continue; // skip `fas`, `far`, `fab`\n if (!entry || typeof entry !== 'object' || !Array.isArray((entry as FaIconEntry).icon)) continue;\n out.push(kebabFromExportName(key));\n }\n return out;\n },\n};\n\nexport default adapter;\n"],"mappings":";;;AAIA,IAAM,IAAU,EAAc,OAAO,KAAK,IAAI,EAExC,IAA2C;CAC7C,OAAO;CACP,SAAS;CACT,QAAQ;CACX,EAEK,IAAuC;CACzC,OAAO;CACP,SAAS;CACT,QAAQ;CACX,EAQK,oBAAc,IAAI,KAAiD;AAEzE,SAAS,EAAgB,GAAmD;CACxE,IAAI,EAAY,IAAI,EAAM,EAAE,OAAO,EAAY,IAAI,EAAM,IAAI;CAC7D,IAAM,IAAM,EAAiB;CAC7B,IAAI,CAAC,GAED,OADA,EAAY,IAAI,GAAO,KAAK,EACrB;CAEX,IAAI;EACA,IAAM,IAAM,EAAQ,EAAI;EAExB,OADA,EAAY,IAAI,GAAO,EAAI,EACpB;SACH;EAEJ,OADA,EAAY,IAAI,GAAO,KAAK,EACrB;;;AAKf,SAAS,EAAc,GAAsB;CACzC,OAAO,OAAO,EAAK,MAAM,IAAI,CAAC,KAAK,MAAQ,EAAI,OAAO,EAAE,CAAC,aAAa,GAAG,EAAI,MAAM,EAAE,CAAC,CAAC,KAAK,GAAG;;AAOnG,SAAS,EAAoB,GAA4B;CAErD,IAAM,IAAO,EAAW,MAAM,EAAE;CAChC,IAAI,EAAK,WAAW,GAAG,OAAO;CAE9B,IAAI,IAAM,EAAK,OAAO,EAAE,CAAC,aAAa;CACtC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK;EAClC,IAAM,IAAK,EAAK,OAAO,EAAE;EACzB,AAAI,KAAM,OAAO,KAAM,MACnB,KAAO,MAAM,EAAG,aAAa,GAE7B,KAAO;;CAGf,OAAO;;AAGX,SAAS,IAA6B;CAClC,IAAI;EAEA,OAAO,EAAK,EADI,EAAQ,QAAQ,6CACZ,CAAQ,EAAE,WAAW;SACrC;EACJ,OAAO;;;AAIf,IAAM,IAAuB;CACzB,QAAQ;EAAC;EAAS;EAAW;EAAS;CAEtC,SAAS,GAAe,GAAgC;EACpD,IAAM,IAAM,EAAgB,EAAM;EAClC,IAAI,CAAC,GAAK,OAAO;EACjB,IAAM,IAAQ,EAAI,EAAc,EAAK;EACrC,IAAI,CAAC,KAAS,CAAC,MAAM,QAAQ,EAAM,KAAK,EAAE,OAAO;EACjD,IAAM,CAAC,GAAG,KAAK,GAAY,KAAQ,EAAM,MACnC,IAAY,SAAS,GAAY,GAAG;EAG1C,OAFK,OAAO,SAAS,EAAU,GAExB;GAAE;GAAW,KAAA,wDADgD,EAAE,GAAG,EAAE,8BAA8B,EAAK;GACrF,GAFe;;CAK5C,YAAY,GAA8B;EACtC,IAAM,IAAW,EAAa;EAC9B,IAAI,CAAC,GAAU,OAAO;EACtB,IAAM,IAAM,GAAa;EAEzB,OADK,IACE,EAAK,GAAK,EAAS,GADT;;CAIrB,WAAW,GAAyB;EAChC,IAAM,IAAM,EAAgB,EAAM;EAClC,IAAI,CAAC,GAAK,OAAO,EAAE;EACnB,IAAM,IAAgB,EAAE;EACxB,KAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,EAAI,EAAE;GAI5C,IAAI,CAAC,EAAI,WAAW,KAAK,IAAI,EAAI,SAAS,GAAG;GAC7C,IAAM,IAAK,EAAI,OAAO,EAAE;GACpB,IAAK,OAAO,IAAK,OACjB,CAAC,KAAS,OAAO,KAAU,YAAY,CAAC,MAAM,QAAS,EAAsB,KAAK,IACtF,EAAI,KAAK,EAAoB,EAAI,CAAC;;EAEtC,OAAO;;CAEd"}
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@sigx/lynx-icons-fa-free",
3
+ "version": "0.4.0",
4
+ "description": "Font Awesome Free adapter for @sigx/lynx-icons. Provides solid/regular/brands styles via the official @fortawesome/* packages.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "./package.json": "./package.json"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md",
19
+ "LICENSE"
20
+ ],
21
+ "peerDependencies": {
22
+ "@fortawesome/fontawesome-free": "^6.0.0",
23
+ "@fortawesome/free-brands-svg-icons": "^6.0.0",
24
+ "@fortawesome/free-regular-svg-icons": "^6.0.0",
25
+ "@fortawesome/free-solid-svg-icons": "^6.0.0",
26
+ "@sigx/lynx-icons": "^0.4.0"
27
+ },
28
+ "peerDependenciesMeta": {
29
+ "@fortawesome/free-brands-svg-icons": {
30
+ "optional": true
31
+ },
32
+ "@fortawesome/free-regular-svg-icons": {
33
+ "optional": true
34
+ }
35
+ },
36
+ "devDependencies": {
37
+ "@fortawesome/fontawesome-free": "^6.7.2",
38
+ "@fortawesome/free-brands-svg-icons": "^6.7.2",
39
+ "@fortawesome/free-regular-svg-icons": "^6.7.2",
40
+ "@fortawesome/free-solid-svg-icons": "^6.7.2",
41
+ "@sigx/vite": "^0.4.3",
42
+ "@types/node": "^25.7.0",
43
+ "typescript": "^6.0.3",
44
+ "@sigx/lynx-icons": "^0.4.0"
45
+ },
46
+ "author": "Andreas Ekdahl",
47
+ "license": "MIT",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/signalxjs/lynx.git",
51
+ "directory": "packages/lynx-icons-fa-free"
52
+ },
53
+ "homepage": "https://github.com/signalxjs/lynx/tree/main/packages/lynx-icons-fa-free",
54
+ "bugs": {
55
+ "url": "https://github.com/signalxjs/lynx/issues"
56
+ },
57
+ "publishConfig": {
58
+ "access": "public"
59
+ },
60
+ "keywords": [
61
+ "signalx",
62
+ "sigx",
63
+ "lynx",
64
+ "icon",
65
+ "font-awesome",
66
+ "fontawesome"
67
+ ],
68
+ "scripts": {
69
+ "build": "vite build && tsgo --emitDeclarationOnly",
70
+ "dev": "vite build --watch"
71
+ }
72
+ }