@dogsbay/icons 0.2.0-beta.13 → 0.2.0-beta.130

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 ADDED
@@ -0,0 +1,40 @@
1
+ # @dogsbay/icons
2
+
3
+ Resolves the icon names Dogsbay content uses (`rocket`, `compass`, `lucide:book-open`, `material:tune`, `mdi:home`, `simple-icons:github`) to inline SVG, or to a Unicode emoji for a shortcode such as `bulb` or `tada`.
4
+
5
+ A bare name is an emoji shortcode first, then a Lucide icon. A `pack:name` name picks the set: `lucide`, `material` (or `mdi`), `fontawesome` (or `fa6-solid`, `fa6-regular`, `fa6-brands`), `octicons` (or `octicon`), `simple` (or `simple-icons`). An unknown name resolves to `null`.
6
+
7
+ ## In Node
8
+
9
+ ```js
10
+ import { resolveIcon } from "@dogsbay/icons";
11
+
12
+ resolveIcon("compass"); // "<svg …>"
13
+ resolveIcon("bulb"); // "💡"
14
+ ```
15
+
16
+ The sets are read from the `@iconify-json/*` packages this one depends on, the first time each is needed.
17
+
18
+ ## In a browser or a Worker
19
+
20
+ `@dogsbay/icons/browser` has no Node built-in. The emoji shortcodes are built in; the Iconify sets are yours to supply, since all of them together are megabytes of JSON (`mdi` alone is about 3 MB):
21
+
22
+ ```js
23
+ import { createIconRegistry, resolveIcon } from "@dogsbay/icons/browser";
24
+ import lucide from "@iconify-json/lucide/icons.json";
25
+
26
+ const icons = createIconRegistry({ sets: { lucide } });
27
+ resolveIcon("compass", icons); // "<svg …>"
28
+
29
+ // Another set later, when a page asks for one:
30
+ icons.registerIconifySet("mdi", (await import("@iconify-json/mdi/icons.json")).default);
31
+ resolveIcon("material:tune", icons);
32
+ ```
33
+
34
+ A set you have not supplied is a miss (`null`), not an error. `createIconRegistry({ loadSet })` takes a function from a set prefix (`lucide`, `mdi`, …) to its JSON instead.
35
+
36
+ To use it with `@dogsbay/render-html`, pass it as the render context's `icons`:
37
+
38
+ ```js
39
+ createRenderContext({ icons: (name) => resolveIcon(name, icons) ?? undefined });
40
+ ```
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @dogsbay/icons with no Node built-in, for a page or a Worker. The emoji
3
+ * shortcodes are built in; Iconify sets are the caller's, since bundling them
4
+ * all would be megabytes (mdi alone is about 3 MB of JSON):
5
+ *
6
+ * import lucide from "@iconify-json/lucide/icons.json";
7
+ * const icons = createIconRegistry({ sets: { lucide } });
8
+ * icons.registerIconifySet("mdi", (await import("@iconify-json/mdi/icons.json")).default); // later, when wanted
9
+ * resolveIcon("compass", icons);
10
+ */
11
+ import { IconRegistry, type IconifySet, type IconRegistryOptions } from "./core.js";
12
+ export { IconRegistry } from "./core.js";
13
+ export type { IconResolver, IconifySet, IconRegistryOptions } from "./core.js";
14
+ export declare function createIconRegistry(options?: IconRegistryOptions & {
15
+ sets?: Record<string, IconifySet>;
16
+ }): IconRegistry;
17
+ /** As the Node entry's resolveIcon, with the registry required: there is no default one to read sets for it. */
18
+ export declare function resolveIcon(shorthand: string, registry: IconRegistry): string | null;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @dogsbay/icons with no Node built-in, for a page or a Worker. The emoji
3
+ * shortcodes are built in; Iconify sets are the caller's, since bundling them
4
+ * all would be megabytes (mdi alone is about 3 MB of JSON):
5
+ *
6
+ * import lucide from "@iconify-json/lucide/icons.json";
7
+ * const icons = createIconRegistry({ sets: { lucide } });
8
+ * icons.registerIconifySet("mdi", (await import("@iconify-json/mdi/icons.json")).default); // later, when wanted
9
+ * resolveIcon("compass", icons);
10
+ */
11
+ import { IconRegistry, resolveShorthand } from "./core.js";
12
+ export { IconRegistry } from "./core.js";
13
+ export function createIconRegistry(options = {}) {
14
+ const { sets, ...rest } = options;
15
+ const registry = new IconRegistry(rest);
16
+ for (const [prefix, set] of Object.entries(sets ?? {}))
17
+ registry.registerIconifySet(prefix, set);
18
+ return registry;
19
+ }
20
+ /** As the Node entry's resolveIcon, with the registry required: there is no default one to read sets for it. */
21
+ export function resolveIcon(shorthand, registry) {
22
+ return resolveShorthand(registry, shorthand);
23
+ }
package/dist/core.d.ts ADDED
@@ -0,0 +1,66 @@
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
+ * No Node built-in here: where an Iconify set comes from is the caller's
9
+ * (`loadSet`, `registerIconifySet`). registry.ts loads them with `require`
10
+ * for Node; browser.ts leaves it to the page.
11
+ */
12
+ /** An Iconify set as its `@iconify-json/<prefix>/icons.json` ships it. */
13
+ export interface IconifySet {
14
+ icons: Record<string, {
15
+ body: string;
16
+ width?: number;
17
+ height?: number;
18
+ }>;
19
+ width?: number;
20
+ height?: number;
21
+ }
22
+ export interface IconRegistryOptions {
23
+ /** Reads an Iconify set by prefix (`mdi`, `lucide`, …), or null when it is not available. */
24
+ loadSet?: (prefix: string) => IconifySet | null;
25
+ }
26
+ export interface IconResolver {
27
+ /** Resolve an icon name to an SVG string, or null if not found. */
28
+ resolve(name: string, variant?: string, size?: string): string | null;
29
+ }
30
+ export declare class IconRegistry {
31
+ private resolvers;
32
+ private emojiMap;
33
+ private iconifyCache;
34
+ private loadSet?;
35
+ constructor(options?: IconRegistryOptions);
36
+ /** Add an Iconify set by its prefix (`mdi`, `lucide`, …); it replaces one loaded or missed before. */
37
+ registerIconifySet(prefix: string, set: IconifySet): void;
38
+ /**
39
+ * Register a custom icon resolver for a library.
40
+ */
41
+ register(library: string, resolver: IconResolver): void;
42
+ /**
43
+ * Register custom emoji shortcodes.
44
+ */
45
+ registerEmoji(map: Record<string, string>): void;
46
+ /**
47
+ * Resolve a shortcode to an SVG string or Unicode emoji.
48
+ * Returns null if the icon is not found.
49
+ */
50
+ resolve(library: string, name: string, variant?: string, size?: string): string | null;
51
+ /**
52
+ * Resolve via @iconify/json icon data.
53
+ */
54
+ private resolveIconify;
55
+ /**
56
+ * Map our library/variant to @iconify/json prefix.
57
+ */
58
+ private getIconifyPrefix;
59
+ /** Load and cache an Iconify set: icon name → SVG string. */
60
+ private loadIconifySet;
61
+ }
62
+ /**
63
+ * The platform icon shorthand (`rocket`, `lucide:book-open`, `mdi:home`):
64
+ * a bare name is an emoji shortcode first, then Lucide. See resolve.ts.
65
+ */
66
+ export declare function resolveShorthand(reg: IconRegistry, shorthand: string): string | null;
package/dist/core.js ADDED
@@ -0,0 +1,201 @@
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
+ * No Node built-in here: where an Iconify set comes from is the caller's
9
+ * (`loadSet`, `registerIconifySet`). registry.ts loads them with `require`
10
+ * for Node; browser.ts leaves it to the page.
11
+ */
12
+ /**
13
+ * Map of known emoji shortcodes → Unicode characters.
14
+ * This is a subset of gemoji covering the most common shortcodes.
15
+ * Apps can extend via registry.registerEmoji().
16
+ */
17
+ const EMOJI_MAP = {
18
+ // Smileys
19
+ smile: "😄", grinning: "😀", laughing: "😆", rofl: "🤣",
20
+ joy: "😂", wink: "😉", blush: "😊", thinking: "🤔",
21
+ // Gestures
22
+ thumbsup: "👍", "+1": "👍", thumbsdown: "👎", "-1": "👎",
23
+ clap: "👏", wave: "👋", pray: "🙏", handshake: "🤝",
24
+ // Objects
25
+ rocket: "🚀", star: "⭐", fire: "🔥", sparkles: "✨",
26
+ bulb: "💡", wrench: "🔧", hammer: "🔨", gear: "⚙️",
27
+ lock: "🔒", key: "🔑", link: "🔗", paperclip: "📎",
28
+ bookmark: "🔖", pushpin: "📌", clipboard: "📋",
29
+ // Symbols
30
+ warning: "⚠️", x: "❌", white_check_mark: "✅",
31
+ heavy_check_mark: "✔️", question: "❓", exclamation: "❗",
32
+ heart: "❤️", broken_heart: "💔",
33
+ // Nature
34
+ sun: "☀️", moon: "🌙", cloud: "☁️", zap: "⚡",
35
+ snowflake: "❄️", rainbow: "🌈",
36
+ // Arrows
37
+ arrow_right: "➡️", arrow_left: "⬅️", arrow_up: "⬆️", arrow_down: "⬇️",
38
+ // Tech
39
+ computer: "💻", iphone: "📱", email: "📧", globe: "🌐",
40
+ // Misc
41
+ eyes: "👀", memo: "📝", books: "📚", package: "📦",
42
+ tada: "🎉", trophy: "🏆", medal: "🏅", crown: "👑",
43
+ image: "🖼️",
44
+ };
45
+ /** Iconify set prefixes → the library (and variant) names this registry uses. */
46
+ const ICONIFY_PREFIX_ALIASES = {
47
+ mdi: { library: "material" },
48
+ "simple-icons": { library: "simple" },
49
+ octicon: { library: "octicons" },
50
+ "fa6-solid": { library: "fontawesome", variant: "solid" },
51
+ "fa6-regular": { library: "fontawesome", variant: "regular" },
52
+ "fa6-brands": { library: "fontawesome", variant: "brands" },
53
+ };
54
+ export class IconRegistry {
55
+ resolvers = new Map();
56
+ emojiMap = new Map(Object.entries(EMOJI_MAP));
57
+ iconifyCache = new Map();
58
+ loadSet;
59
+ constructor(options = {}) {
60
+ this.loadSet = options.loadSet;
61
+ }
62
+ /** Add an Iconify set by its prefix (`mdi`, `lucide`, …); it replaces one loaded or missed before. */
63
+ registerIconifySet(prefix, set) {
64
+ this.iconifyCache.set(prefix, toSvgs(set));
65
+ }
66
+ /**
67
+ * Register a custom icon resolver for a library.
68
+ */
69
+ register(library, resolver) {
70
+ this.resolvers.set(library, resolver);
71
+ }
72
+ /**
73
+ * Register custom emoji shortcodes.
74
+ */
75
+ registerEmoji(map) {
76
+ for (const [k, v] of Object.entries(map)) {
77
+ this.emojiMap.set(k, v);
78
+ }
79
+ }
80
+ /**
81
+ * Resolve a shortcode to an SVG string or Unicode emoji.
82
+ * Returns null if the icon is not found.
83
+ */
84
+ resolve(library, name, variant, size) {
85
+ // Emoji shortcodes → Unicode character
86
+ if (library === "emoji") {
87
+ return this.emojiMap.get(name) || null;
88
+ }
89
+ // Check custom resolvers first
90
+ const customResolver = this.resolvers.get(library);
91
+ if (customResolver) {
92
+ return customResolver.resolve(name, variant, size);
93
+ }
94
+ // Fall back to @iconify/json. Iconify's own set prefixes (`mdi:home`, `simple-icons:github`,
95
+ // `fa6-solid:house`, `octicon:repo`) name the same packs as the library names.
96
+ const alias = ICONIFY_PREFIX_ALIASES[library];
97
+ if (alias)
98
+ return this.resolveIconify(alias.library, name, alias.variant ?? variant, size);
99
+ return this.resolveIconify(library, name, variant, size);
100
+ }
101
+ /**
102
+ * Resolve via @iconify/json icon data.
103
+ */
104
+ resolveIconify(library, name, variant, _size) {
105
+ const prefix = this.getIconifyPrefix(library, variant);
106
+ if (!prefix)
107
+ return null;
108
+ const icons = this.loadIconifySet(prefix);
109
+ if (!icons)
110
+ return null;
111
+ // Direct lookup
112
+ let svg = icons[name];
113
+ if (svg)
114
+ return svg;
115
+ // Octicons: iconify includes the size suffix in the name (e.g. "heart-fill-24")
116
+ if (library === "octicons" && _size) {
117
+ svg = icons[`${name}-${_size}`];
118
+ if (svg)
119
+ return svg;
120
+ }
121
+ // Try with common default sizes
122
+ if (library === "octicons") {
123
+ svg = icons[`${name}-16`] || icons[`${name}-24`];
124
+ if (svg)
125
+ return svg;
126
+ }
127
+ return null;
128
+ }
129
+ /**
130
+ * Map our library/variant to @iconify/json prefix.
131
+ */
132
+ getIconifyPrefix(library, variant) {
133
+ switch (library) {
134
+ case "material": return "mdi";
135
+ case "fontawesome":
136
+ switch (variant) {
137
+ case "brands": return "fa6-brands";
138
+ case "regular": return "fa6-regular";
139
+ case "solid":
140
+ default: return "fa6-solid";
141
+ }
142
+ case "octicons": return "octicon";
143
+ case "simple": return "simple-icons";
144
+ // Lucide is the platform default — used for `{icon=...}` props
145
+ // on cards, the inline `icon` TreeNode, and any `name="rocket"`
146
+ // (no namespace prefix) call. Iconify prefix is "lucide".
147
+ case "lucide": return "lucide";
148
+ default: return null;
149
+ }
150
+ }
151
+ /** Load and cache an Iconify set: icon name → SVG string. */
152
+ loadIconifySet(prefix) {
153
+ const cached = this.iconifyCache.get(prefix);
154
+ if (cached)
155
+ return Object.keys(cached).length ? cached : null;
156
+ let set = null;
157
+ try {
158
+ set = this.loadSet?.(prefix) ?? null;
159
+ }
160
+ catch {
161
+ set = null;
162
+ }
163
+ const result = set ? toSvgs(set) : {};
164
+ this.iconifyCache.set(prefix, result);
165
+ return set ? result : null;
166
+ }
167
+ }
168
+ function toSvgs({ icons, width, height }) {
169
+ const w = width || 24;
170
+ const h = height || 24;
171
+ const result = {};
172
+ for (const [iconName, data] of Object.entries(icons)) {
173
+ const iw = data.width || w;
174
+ const ih = data.height || h;
175
+ result[iconName] = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${iw} ${ih}" width="1em" height="1em" fill="currentColor">${data.body}</svg>`;
176
+ }
177
+ return result;
178
+ }
179
+ /**
180
+ * The platform icon shorthand (`rocket`, `lucide:book-open`, `mdi:home`):
181
+ * a bare name is an emoji shortcode first, then Lucide. See resolve.ts.
182
+ */
183
+ export function resolveShorthand(reg, shorthand) {
184
+ const trimmed = shorthand.trim();
185
+ if (trimmed.length === 0)
186
+ return null;
187
+ const colonIdx = trimmed.indexOf(":");
188
+ if (colonIdx > 0) {
189
+ const pack = trimmed.slice(0, colonIdx);
190
+ const name = trimmed.slice(colonIdx + 1);
191
+ return reg.resolve(pack, name);
192
+ }
193
+ // Bare name. Try the emoji map first (so `rocket` → 🚀
194
+ // matches existing behaviour). Fall through to Lucide so SVG
195
+ // names without an emoji equivalent (`book-open`, `settings`)
196
+ // still resolve.
197
+ const emoji = reg.resolve("emoji", trimmed);
198
+ if (emoji !== null)
199
+ return emoji;
200
+ return reg.resolve("lucide", trimmed);
201
+ }
@@ -1,44 +1,7 @@
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;
1
+ import { IconRegistry as CoreIconRegistry, type IconRegistryOptions } from "./core.js";
2
+ export type { IconResolver, IconifySet, IconRegistryOptions } from "./core.js";
3
+ export declare class IconRegistry extends CoreIconRegistry {
4
+ constructor(options?: IconRegistryOptions);
42
5
  }
43
6
  /**
44
7
  * Create a pre-configured registry with all built-in icon libraries.
package/dist/registry.js CHANGED
@@ -1,157 +1,17 @@
1
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).
2
+ * The registry for Node: Iconify sets are read from the per-set packages
3
+ * (@iconify-json/mdi, …/lucide, etc.) with `require`, not the monolithic
4
+ * @iconify/json (399 MB, the whole catalog), so a consuming site only pulls the
5
+ * ~7 sets we map. The prefix equals the package suffix, and each set ships
6
+ * `icons.json` at its root. In a browser use `@dogsbay/icons/browser`.
7
7
  */
8
8
  import { createRequire } from "node:module";
9
+ import { IconRegistry as CoreIconRegistry } from "./core.js";
9
10
  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
- // Lucide is the platform default — used for `{icon=...}` props
122
- // on cards, the inline `icon` TreeNode, and any `name="rocket"`
123
- // (no namespace prefix) call. Iconify prefix is "lucide".
124
- case "lucide": return "lucide";
125
- default: return null;
126
- }
127
- }
128
- /**
129
- * Load and cache an @iconify/json icon set.
130
- * Returns a map of icon name → SVG body string.
131
- */
132
- loadIconifySet(prefix) {
133
- if (this.iconifyCache.has(prefix)) {
134
- return this.iconifyCache.get(prefix);
135
- }
136
- try {
137
- // Dynamic require to load icon data
138
- const { icons, width, height } = require(`@iconify/json/json/${prefix}.json`);
139
- const w = width || 24;
140
- const h = height || 24;
141
- const result = {};
142
- for (const [iconName, iconData] of Object.entries(icons)) {
143
- const data = iconData;
144
- const iw = data.width || w;
145
- const ih = data.height || h;
146
- result[iconName] = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${iw} ${ih}" width="1em" height="1em" fill="currentColor">${data.body}</svg>`;
147
- }
148
- this.iconifyCache.set(prefix, result);
149
- return result;
150
- }
151
- catch {
152
- this.iconifyCache.set(prefix, {});
153
- return null;
154
- }
11
+ const requireSet = (prefix) => require(`@iconify-json/${prefix}/icons.json`);
12
+ export class IconRegistry extends CoreIconRegistry {
13
+ constructor(options = {}) {
14
+ super({ loadSet: requireSet, ...options });
155
15
  }
156
16
  }
157
17
  /**
package/dist/resolve.js CHANGED
@@ -20,6 +20,7 @@
20
20
  * resolver → Iconify pack.
21
21
  */
22
22
  import { createIconRegistry } from "./registry.js";
23
+ import { resolveShorthand } from "./core.js";
23
24
  /**
24
25
  * Lazily-instantiated registry shared by every consumer that
25
26
  * doesn't bring its own. The first `resolveIcon` call constructs
@@ -50,22 +51,5 @@ export function defaultRegistry() {
50
51
  * process-wide shared instance.
51
52
  */
52
53
  export function resolveIcon(shorthand, registry) {
53
- const reg = registry ?? defaultRegistry();
54
- const trimmed = shorthand.trim();
55
- if (trimmed.length === 0)
56
- return null;
57
- const colonIdx = trimmed.indexOf(":");
58
- if (colonIdx > 0) {
59
- const pack = trimmed.slice(0, colonIdx);
60
- const name = trimmed.slice(colonIdx + 1);
61
- return reg.resolve(pack, name);
62
- }
63
- // Bare name. Try the emoji map first (so `rocket` → 🚀
64
- // matches existing behaviour). Fall through to Lucide so SVG
65
- // names without an emoji equivalent (`book-open`, `settings`)
66
- // still resolve.
67
- const emoji = reg.resolve("emoji", trimmed);
68
- if (emoji !== null)
69
- return emoji;
70
- return reg.resolve("lucide", trimmed);
54
+ return resolveShorthand(registry ?? defaultRegistry(), shorthand);
71
55
  }
package/package.json CHANGED
@@ -1,23 +1,35 @@
1
1
  {
2
2
  "name": "@dogsbay/icons",
3
- "version": "0.2.0-beta.13",
3
+ "version": "0.2.0-beta.130",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "exports": {
8
8
  ".": "./dist/index.js",
9
- "./registry": "./dist/registry.js"
9
+ "./registry": "./dist/registry.js",
10
+ "./browser": {
11
+ "types": "./dist/browser.d.ts",
12
+ "import": "./dist/browser.js"
13
+ }
10
14
  },
11
15
  "files": [
12
16
  "dist",
13
17
  "README.md"
14
18
  ],
15
19
  "dependencies": {
16
- "@iconify/json": "^2.2.0"
20
+ "@iconify-json/fa6-brands": "^1.2.6",
21
+ "@iconify-json/fa6-regular": "^1.2.4",
22
+ "@iconify-json/fa6-solid": "^1.2.4",
23
+ "@iconify-json/lucide": "^1.2.117",
24
+ "@iconify-json/mdi": "^1.2.3",
25
+ "@iconify-json/octicon": "^1.2.29",
26
+ "@iconify-json/simple-icons": "^1.2.90"
17
27
  },
18
28
  "devDependencies": {
19
- "@types/node": "^22.0.0",
20
- "typescript": "^5.0.0"
29
+ "@types/node": "^22.20.1",
30
+ "typescript": "^5.9.3",
31
+ "vitest": "^4.1.10",
32
+ "esbuild": "0.28.1"
21
33
  },
22
34
  "license": "MIT",
23
35
  "repository": {
@@ -30,6 +42,7 @@
30
42
  "url": "https://github.com/dogsbay/dogsbay/issues"
31
43
  },
32
44
  "scripts": {
33
- "build": "tsc"
45
+ "build": "tsc",
46
+ "test": "vitest run"
34
47
  }
35
48
  }