@dogsbay/icons 0.2.0-beta.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.
@@ -0,0 +1,2 @@
1
+ export { IconRegistry, createIconRegistry } from "./registry.js";
2
+ export type { IconResolver } from "./registry.js";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { IconRegistry, createIconRegistry } from "./registry.js";
@@ -0,0 +1,46 @@
1
+ /**
2
+ * IconRegistry — resolves icon shortcodes to SVG strings.
3
+ *
4
+ * Supports multiple icon libraries via a pluggable resolver system.
5
+ * Built-in support for @iconify/json (material, fontawesome, octicons, simple)
6
+ * and gemoji-style emoji shortcodes (→ native Unicode).
7
+ */
8
+ export interface IconResolver {
9
+ /** Resolve an icon name to an SVG string, or null if not found. */
10
+ resolve(name: string, variant?: string, size?: string): string | null;
11
+ }
12
+ export declare class IconRegistry {
13
+ private resolvers;
14
+ private emojiMap;
15
+ private iconifyCache;
16
+ /**
17
+ * Register a custom icon resolver for a library.
18
+ */
19
+ register(library: string, resolver: IconResolver): void;
20
+ /**
21
+ * Register custom emoji shortcodes.
22
+ */
23
+ registerEmoji(map: Record<string, string>): void;
24
+ /**
25
+ * Resolve a shortcode to an SVG string or Unicode emoji.
26
+ * Returns null if the icon is not found.
27
+ */
28
+ resolve(library: string, name: string, variant?: string, size?: string): string | null;
29
+ /**
30
+ * Resolve via @iconify/json icon data.
31
+ */
32
+ private resolveIconify;
33
+ /**
34
+ * Map our library/variant to @iconify/json prefix.
35
+ */
36
+ private getIconifyPrefix;
37
+ /**
38
+ * Load and cache an @iconify/json icon set.
39
+ * Returns a map of icon name → SVG body string.
40
+ */
41
+ private loadIconifySet;
42
+ }
43
+ /**
44
+ * Create a pre-configured registry with all built-in icon libraries.
45
+ */
46
+ export declare function createIconRegistry(): IconRegistry;
@@ -0,0 +1,158 @@
1
+ /**
2
+ * IconRegistry — resolves icon shortcodes to SVG strings.
3
+ *
4
+ * Supports multiple icon libraries via a pluggable resolver system.
5
+ * Built-in support for @iconify/json (material, fontawesome, octicons, simple)
6
+ * and gemoji-style emoji shortcodes (→ native Unicode).
7
+ */
8
+ import { createRequire } from "node:module";
9
+ const require = createRequire(import.meta.url);
10
+ /**
11
+ * Map of known emoji shortcodes → Unicode characters.
12
+ * This is a subset of gemoji covering the most common shortcodes.
13
+ * Apps can extend via registry.registerEmoji().
14
+ */
15
+ const EMOJI_MAP = {
16
+ // Smileys
17
+ smile: "😄", grinning: "😀", laughing: "😆", rofl: "🤣",
18
+ joy: "😂", wink: "😉", blush: "😊", thinking: "🤔",
19
+ // Gestures
20
+ thumbsup: "👍", "+1": "👍", thumbsdown: "👎", "-1": "👎",
21
+ clap: "👏", wave: "👋", pray: "🙏", handshake: "🤝",
22
+ // Objects
23
+ rocket: "🚀", star: "⭐", fire: "🔥", sparkles: "✨",
24
+ bulb: "💡", wrench: "🔧", hammer: "🔨", gear: "⚙️",
25
+ lock: "🔒", key: "🔑", link: "🔗", paperclip: "📎",
26
+ bookmark: "🔖", pushpin: "📌", clipboard: "📋",
27
+ // Symbols
28
+ warning: "⚠️", x: "❌", white_check_mark: "✅",
29
+ heavy_check_mark: "✔️", question: "❓", exclamation: "❗",
30
+ heart: "❤️", broken_heart: "💔",
31
+ // Nature
32
+ sun: "☀️", moon: "🌙", cloud: "☁️", zap: "⚡",
33
+ snowflake: "❄️", rainbow: "🌈",
34
+ // Arrows
35
+ arrow_right: "➡️", arrow_left: "⬅️", arrow_up: "⬆️", arrow_down: "⬇️",
36
+ // Tech
37
+ computer: "💻", iphone: "📱", email: "📧", globe: "🌐",
38
+ // Misc
39
+ eyes: "👀", memo: "📝", books: "📚", package: "📦",
40
+ tada: "🎉", trophy: "🏆", medal: "🏅", crown: "👑",
41
+ image: "🖼️",
42
+ };
43
+ export class IconRegistry {
44
+ resolvers = new Map();
45
+ emojiMap = new Map(Object.entries(EMOJI_MAP));
46
+ iconifyCache = new Map();
47
+ /**
48
+ * Register a custom icon resolver for a library.
49
+ */
50
+ register(library, resolver) {
51
+ this.resolvers.set(library, resolver);
52
+ }
53
+ /**
54
+ * Register custom emoji shortcodes.
55
+ */
56
+ registerEmoji(map) {
57
+ for (const [k, v] of Object.entries(map)) {
58
+ this.emojiMap.set(k, v);
59
+ }
60
+ }
61
+ /**
62
+ * Resolve a shortcode to an SVG string or Unicode emoji.
63
+ * Returns null if the icon is not found.
64
+ */
65
+ resolve(library, name, variant, size) {
66
+ // Emoji shortcodes → Unicode character
67
+ if (library === "emoji") {
68
+ return this.emojiMap.get(name) || null;
69
+ }
70
+ // Check custom resolvers first
71
+ const customResolver = this.resolvers.get(library);
72
+ if (customResolver) {
73
+ return customResolver.resolve(name, variant, size);
74
+ }
75
+ // Fall back to @iconify/json
76
+ return this.resolveIconify(library, name, variant, size);
77
+ }
78
+ /**
79
+ * Resolve via @iconify/json icon data.
80
+ */
81
+ resolveIconify(library, name, variant, _size) {
82
+ const prefix = this.getIconifyPrefix(library, variant);
83
+ if (!prefix)
84
+ return null;
85
+ const icons = this.loadIconifySet(prefix);
86
+ if (!icons)
87
+ return null;
88
+ // Direct lookup
89
+ let svg = icons[name];
90
+ if (svg)
91
+ return svg;
92
+ // Octicons: iconify includes the size suffix in the name (e.g. "heart-fill-24")
93
+ if (library === "octicons" && _size) {
94
+ svg = icons[`${name}-${_size}`];
95
+ if (svg)
96
+ return svg;
97
+ }
98
+ // Try with common default sizes
99
+ if (library === "octicons") {
100
+ svg = icons[`${name}-16`] || icons[`${name}-24`];
101
+ if (svg)
102
+ return svg;
103
+ }
104
+ return null;
105
+ }
106
+ /**
107
+ * Map our library/variant to @iconify/json prefix.
108
+ */
109
+ getIconifyPrefix(library, variant) {
110
+ switch (library) {
111
+ case "material": return "mdi";
112
+ case "fontawesome":
113
+ switch (variant) {
114
+ case "brands": return "fa6-brands";
115
+ case "regular": return "fa6-regular";
116
+ case "solid":
117
+ default: return "fa6-solid";
118
+ }
119
+ case "octicons": return "octicon";
120
+ case "simple": return "simple-icons";
121
+ default: return null;
122
+ }
123
+ }
124
+ /**
125
+ * Load and cache an @iconify/json icon set.
126
+ * Returns a map of icon name → SVG body string.
127
+ */
128
+ loadIconifySet(prefix) {
129
+ if (this.iconifyCache.has(prefix)) {
130
+ return this.iconifyCache.get(prefix);
131
+ }
132
+ try {
133
+ // Dynamic require to load icon data
134
+ const { icons, width, height } = require(`@iconify/json/json/${prefix}.json`);
135
+ const w = width || 24;
136
+ const h = height || 24;
137
+ const result = {};
138
+ for (const [iconName, iconData] of Object.entries(icons)) {
139
+ const data = iconData;
140
+ const iw = data.width || w;
141
+ const ih = data.height || h;
142
+ result[iconName] = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${iw} ${ih}" width="1em" height="1em" fill="currentColor">${data.body}</svg>`;
143
+ }
144
+ this.iconifyCache.set(prefix, result);
145
+ return result;
146
+ }
147
+ catch {
148
+ this.iconifyCache.set(prefix, {});
149
+ return null;
150
+ }
151
+ }
152
+ }
153
+ /**
154
+ * Create a pre-configured registry with all built-in icon libraries.
155
+ */
156
+ export function createIconRegistry() {
157
+ return new IconRegistry();
158
+ }
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@dogsbay/icons",
3
+ "version": "0.2.0-beta.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": "./dist/index.js",
9
+ "./registry": "./dist/registry.js"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "dependencies": {
16
+ "@iconify/json": "^2.2.0"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^22.0.0",
20
+ "typescript": "^5.0.0"
21
+ },
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/dogsbay/dogsbay.git",
26
+ "directory": "packages/icons"
27
+ },
28
+ "homepage": "https://github.com/dogsbay/dogsbay/tree/main/packages/icons",
29
+ "bugs": {
30
+ "url": "https://github.com/dogsbay/dogsbay/issues"
31
+ },
32
+ "scripts": {
33
+ "build": "tsc"
34
+ }
35
+ }