@sigx/lynx-icons-lucide 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 +21 -0
- package/README.md +68 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
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,68 @@
|
|
|
1
|
+
# @sigx/lynx-icons-lucide
|
|
2
|
+
|
|
3
|
+
[Lucide](https://lucide.dev/) adapter for [`@sigx/lynx-icons`](../lynx-icons). Reads icon data from the official `lucide` package and renders each glyph as a stroked SVG with the wrapper attributes (`fill="none"`, `stroke="currentColor"`, `stroke-width="2"`, rounded caps/joins) that match the Lucide design.
|
|
4
|
+
|
|
5
|
+
SVG-mode only — Lucide isn't distributed as a font.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @sigx/lynx-icons @sigx/lynx-icons-lucide lucide
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
// signalx.config.ts
|
|
15
|
+
import { defineLynxConfig } from '@sigx/lynx-cli/config';
|
|
16
|
+
|
|
17
|
+
export default defineLynxConfig({
|
|
18
|
+
iconSets: [
|
|
19
|
+
{ id: 'lucide', source: '@sigx/lynx-icons-lucide' },
|
|
20
|
+
],
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { Icon } from '@sigx/lynx-icons';
|
|
28
|
+
|
|
29
|
+
<Icon set="lucide" name="search" />
|
|
30
|
+
<Icon set="lucide" name="chevron-right" size={20} color="#0D9488" />
|
|
31
|
+
<Icon set="lucide" name="bell" size={24} />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Glyph names are kebab-case (`chevron-right`, not `ChevronRight`); the adapter converts to lucide's `ChevronRight` export internally.
|
|
35
|
+
|
|
36
|
+
## Notes
|
|
37
|
+
|
|
38
|
+
- Lucide icons are **stroked**, not filled. `color` is substituted into the `stroke` attribute, so passing dark/light colors works the same as it does for filled FA icons.
|
|
39
|
+
- The full Lucide catalog is reachable — every PascalCase export is mapped from a kebab-case name. If a name fails to resolve, check the [Lucide icon library](https://lucide.dev/icons/) for the canonical spelling.
|
|
40
|
+
- `mode: 'font'` is rejected at config-validation time when v1.1 ships — Lucide has no source TTF.
|
|
41
|
+
|
|
42
|
+
## Dynamic / JSON-driven icons
|
|
43
|
+
|
|
44
|
+
If the icon `name` comes from data the build-time scanner can't see, set `include: ['*']` on the iconSet to ship the entire Lucide catalog:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
iconSets: [
|
|
48
|
+
{ id: 'lucide', source: '@sigx/lynx-icons-lucide', include: ['*'] },
|
|
49
|
+
],
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This bundles all ~1 500 Lucide glyphs into the JS bundle. Use it per-set, only when needed.
|
|
53
|
+
|
|
54
|
+
## API
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import lucideAdapter from '@sigx/lynx-icons-lucide';
|
|
58
|
+
|
|
59
|
+
lucideAdapter.styles; // [''] (single empty-string style)
|
|
60
|
+
lucideAdapter.getGlyph('', 'user'); // { svg: '<svg viewBox="0 0 24 24" fill="none" stroke="__COLOR__"…>' }
|
|
61
|
+
lucideAdapter.getFontPath(''); // null (always)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The adapter is normally consumed by `@sigx/lynx-plugin`'s icons slice — these direct exports are useful for tests and custom tooling.
|
|
65
|
+
|
|
66
|
+
## Reference app
|
|
67
|
+
|
|
68
|
+
`examples/showcase/src/screens/Settings.tsx` renders `<Icon set="lucide" name="search" />` and `<Icon set="lucide" name="bell" />` alongside FA glyphs in a card.
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { createRequire as e } from "node:module";
|
|
2
|
+
//#region src/index.ts
|
|
3
|
+
var t = e(import.meta.url), n;
|
|
4
|
+
function r() {
|
|
5
|
+
if (n !== void 0) return n;
|
|
6
|
+
try {
|
|
7
|
+
n = t("lucide");
|
|
8
|
+
} catch {
|
|
9
|
+
n = null;
|
|
10
|
+
}
|
|
11
|
+
return n;
|
|
12
|
+
}
|
|
13
|
+
function i(e) {
|
|
14
|
+
return e.split("-").map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("");
|
|
15
|
+
}
|
|
16
|
+
function a(e) {
|
|
17
|
+
if (e.length === 0) return "";
|
|
18
|
+
let t = e.charAt(0).toLowerCase();
|
|
19
|
+
for (let n = 1; n < e.length; n++) {
|
|
20
|
+
let r = e.charAt(n);
|
|
21
|
+
r >= "A" && r <= "Z" ? t += "-" + r.toLowerCase() : t += r;
|
|
22
|
+
}
|
|
23
|
+
return t;
|
|
24
|
+
}
|
|
25
|
+
function o(e) {
|
|
26
|
+
return String(e).replace(/&/g, "&").replace(/"/g, """);
|
|
27
|
+
}
|
|
28
|
+
function s(e) {
|
|
29
|
+
let [t, n] = e, r = [];
|
|
30
|
+
for (let [e, t] of Object.entries(n)) r.push(`${e}="${o(t)}"`);
|
|
31
|
+
return `<${t} ${r.join(" ")}/>`;
|
|
32
|
+
}
|
|
33
|
+
var c = {
|
|
34
|
+
styles: [""],
|
|
35
|
+
getGlyph(e, t) {
|
|
36
|
+
let n = r();
|
|
37
|
+
if (!n) return null;
|
|
38
|
+
let a = n[i(t)];
|
|
39
|
+
return Array.isArray(a) ? { svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="__COLOR__" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${a.map(s).join("")}</svg>` } : null;
|
|
40
|
+
},
|
|
41
|
+
getFontPath() {
|
|
42
|
+
return null;
|
|
43
|
+
},
|
|
44
|
+
listGlyphs(e) {
|
|
45
|
+
let t = r();
|
|
46
|
+
if (!t) return [];
|
|
47
|
+
let n = [];
|
|
48
|
+
for (let [e, r] of Object.entries(t)) {
|
|
49
|
+
if (!Array.isArray(r)) continue;
|
|
50
|
+
let t = e.charAt(0);
|
|
51
|
+
t < "A" || t > "Z" || n.push(a(e));
|
|
52
|
+
}
|
|
53
|
+
return n;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
//#endregion
|
|
57
|
+
export { c as default };
|
|
58
|
+
|
|
59
|
+
//# 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 type { GlyphData, IconAdapter } from '@sigx/lynx-icons';\n\nconst require = createRequire(import.meta.url);\n\ntype LucideAttrs = Record<string, string | number>;\ntype LucideElement = [string, LucideAttrs];\ntype LucideIcon = LucideElement[];\n\nlet lucideModule: Record<string, LucideIcon> | null | undefined;\n\nfunction loadLucide(): Record<string, LucideIcon> | null {\n if (lucideModule !== undefined) return lucideModule;\n try {\n lucideModule = require('lucide') as Record<string, LucideIcon>;\n } catch {\n lucideModule = null;\n }\n return lucideModule;\n}\n\n/** Convert kebab-case → PascalCase (lucide's export naming). `a-arrow-down` → `AArrowDown`. */\nfunction exportNameFor(name: string): string {\n return name.split('-').map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1)).join('');\n}\n\n/**\n * Inverse of `exportNameFor`: insert `-` before every uppercase letter that\n * isn't the first character, then lowercase. Mirrors the way `exportNameFor`\n * builds names from kebab segments.\n *\n * - `User` → `user`\n * - `ChevronRight` → `chevron-right`\n * - `AArrowDown` → `a-arrow-down` (lucide really has names like this)\n */\nfunction kebabFromPascal(exportName: string): string {\n if (exportName.length === 0) return '';\n let out = exportName.charAt(0).toLowerCase();\n for (let i = 1; i < exportName.length; i++) {\n const ch = exportName.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 escapeAttr(value: string | number): string {\n return String(value).replace(/&/g, '&').replace(/\"/g, '"');\n}\n\nfunction renderElement(el: LucideElement): string {\n const [tag, attrs] = el;\n const parts: string[] = [];\n for (const [k, v] of Object.entries(attrs)) {\n parts.push(`${k}=\"${escapeAttr(v)}\"`);\n }\n return `<${tag} ${parts.join(' ')}/>`;\n}\n\nconst adapter: IconAdapter = {\n /** Lucide is a single-style set; we still expose one entry so iteration works. */\n styles: [''],\n\n getGlyph(_style: string, name: string): GlyphData | null {\n const lucide = loadLucide();\n if (!lucide) return null;\n const icon = lucide[exportNameFor(name)];\n if (!Array.isArray(icon)) return null;\n const inner = icon.map(renderElement).join('');\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"__COLOR__\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${inner}</svg>`;\n return { svg };\n },\n\n /** Lucide has no font distribution. Always null → forces SVG mode. */\n getFontPath(): string | null {\n return null;\n },\n\n listGlyphs(_style: string): string[] {\n const lucide = loadLucide();\n if (!lucide) return [];\n const out: string[] = [];\n for (const [key, value] of Object.entries(lucide)) {\n if (!Array.isArray(value)) continue;\n // Lucide also exports a `createLucideIcon` helper etc. — skip\n // anything that doesn't start with an uppercase letter (icon\n // names are PascalCase).\n const first = key.charAt(0);\n if (first < 'A' || first > 'Z') continue;\n out.push(kebabFromPascal(key));\n }\n return out;\n },\n};\n\nexport default adapter;\n"],"mappings":";;AAGA,IAAM,IAAU,EAAc,OAAO,KAAK,IAAI,EAM1C;AAEJ,SAAS,IAAgD;CACrD,IAAI,MAAiB,KAAA,GAAW,OAAO;CACvC,IAAI;EACA,IAAe,EAAQ,SAAS;SAC5B;EACJ,IAAe;;CAEnB,OAAO;;AAIX,SAAS,EAAc,GAAsB;CACzC,OAAO,EAAK,MAAM,IAAI,CAAC,KAAK,MAAQ,EAAI,OAAO,EAAE,CAAC,aAAa,GAAG,EAAI,MAAM,EAAE,CAAC,CAAC,KAAK,GAAG;;AAY5F,SAAS,EAAgB,GAA4B;CACjD,IAAI,EAAW,WAAW,GAAG,OAAO;CACpC,IAAI,IAAM,EAAW,OAAO,EAAE,CAAC,aAAa;CAC5C,KAAK,IAAI,IAAI,GAAG,IAAI,EAAW,QAAQ,KAAK;EACxC,IAAM,IAAK,EAAW,OAAO,EAAE;EAC/B,AAAI,KAAM,OAAO,KAAM,MACnB,KAAO,MAAM,EAAG,aAAa,GAE7B,KAAO;;CAGf,OAAO;;AAGX,SAAS,EAAW,GAAgC;CAChD,OAAO,OAAO,EAAM,CAAC,QAAQ,MAAM,QAAQ,CAAC,QAAQ,MAAM,SAAS;;AAGvE,SAAS,EAAc,GAA2B;CAC9C,IAAM,CAAC,GAAK,KAAS,GACf,IAAkB,EAAE;CAC1B,KAAK,IAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,EAAM,EACtC,EAAM,KAAK,GAAG,EAAE,IAAI,EAAW,EAAE,CAAC,GAAG;CAEzC,OAAO,IAAI,EAAI,GAAG,EAAM,KAAK,IAAI,CAAC;;AAGtC,IAAM,IAAuB;CAEzB,QAAQ,CAAC,GAAG;CAEZ,SAAS,GAAgB,GAAgC;EACrD,IAAM,IAAS,GAAY;EAC3B,IAAI,CAAC,GAAQ,OAAO;EACpB,IAAM,IAAO,EAAO,EAAc,EAAK;EAIvC,OAHK,MAAM,QAAQ,EAAK,GAGjB,EAAE,KAAA,8JAFK,EAAK,IAAI,EAAc,CAAC,KAAK,GAC+H,CAAM,SAClK,GAHmB;;CAOrC,cAA6B;EACzB,OAAO;;CAGX,WAAW,GAA0B;EACjC,IAAM,IAAS,GAAY;EAC3B,IAAI,CAAC,GAAQ,OAAO,EAAE;EACtB,IAAM,IAAgB,EAAE;EACxB,KAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,EAAO,EAAE;GAC/C,IAAI,CAAC,MAAM,QAAQ,EAAM,EAAE;GAI3B,IAAM,IAAQ,EAAI,OAAO,EAAE;GACvB,IAAQ,OAAO,IAAQ,OAC3B,EAAI,KAAK,EAAgB,EAAI,CAAC;;EAElC,OAAO;;CAEd"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sigx/lynx-icons-lucide",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Lucide adapter for @sigx/lynx-icons. SVG-mode only — lucide is not distributed as a font.",
|
|
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
|
+
"lucide": "^1.0.0",
|
|
23
|
+
"@sigx/lynx-icons": "^0.4.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@sigx/vite": "^0.4.3",
|
|
27
|
+
"@types/node": "^25.7.0",
|
|
28
|
+
"lucide": "^1.16.0",
|
|
29
|
+
"typescript": "^6.0.3",
|
|
30
|
+
"@sigx/lynx-icons": "^0.4.0"
|
|
31
|
+
},
|
|
32
|
+
"author": "Andreas Ekdahl",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/signalxjs/lynx.git",
|
|
37
|
+
"directory": "packages/lynx-icons-lucide"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/signalxjs/lynx/tree/main/packages/lynx-icons-lucide",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/signalxjs/lynx/issues"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
},
|
|
46
|
+
"keywords": [
|
|
47
|
+
"signalx",
|
|
48
|
+
"sigx",
|
|
49
|
+
"lynx",
|
|
50
|
+
"icon",
|
|
51
|
+
"lucide"
|
|
52
|
+
],
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "vite build && tsgo --emitDeclarationOnly",
|
|
55
|
+
"dev": "vite build --watch"
|
|
56
|
+
}
|
|
57
|
+
}
|