@bit.rhplus/ui2.emoji-icons 0.0.1 → 0.0.2
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/dist/index.d.ts +5 -2
- package/dist/index.js +99 -56
- package/dist/index.js.map +1 -1
- package/index.jsx +109 -58
- package/package.json +4 -3
- /package/dist/{preview-1764590989376.js → preview-1764754437531.js} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -2,12 +2,15 @@ export function preloadIcons(iconNames: string[]): Promise<void>;
|
|
|
2
2
|
export function clearIconCache(): void;
|
|
3
3
|
export default EmojiIcon;
|
|
4
4
|
/**
|
|
5
|
-
* Komponenta pro zobrazení
|
|
5
|
+
* Komponenta pro zobrazení Iconify ikon s automatickým cachováním
|
|
6
6
|
*
|
|
7
|
-
* @param {string} name - Název ikony
|
|
7
|
+
* @param {string} name - Název ikony ve formátu "prefix:iconName" nebo jen "iconName"
|
|
8
|
+
* (např. 'airplane', 'fluent-color:receipt-16', 'mdi:home')
|
|
8
9
|
* @param {number} size - Velikost ikony v pixelech
|
|
9
10
|
*
|
|
10
11
|
* Příklad použití:
|
|
11
12
|
* <EmojiIcon name="airplane" size={20} />
|
|
13
|
+
* <EmojiIcon name="fluent-color:receipt-16" size={24} />
|
|
14
|
+
* <EmojiIcon name="mdi:home" size={32} />
|
|
12
15
|
*/
|
|
13
16
|
declare function EmojiIcon({ name, size }: string): import("react/jsx-runtime").JSX.Element;
|
package/dist/index.js
CHANGED
|
@@ -5,8 +5,9 @@ import React, { useState, useEffect } from 'react';
|
|
|
5
5
|
const iconCache = new Map();
|
|
6
6
|
const loadingIcons = new Set();
|
|
7
7
|
// Lokální storage klíč pro persistentní cache
|
|
8
|
-
const CACHE_KEY = '
|
|
9
|
-
const CACHE_VERSION = '
|
|
8
|
+
const CACHE_KEY = 'iconify-cache';
|
|
9
|
+
const CACHE_VERSION = '2.0'; // Zvýšena verze kvůli změně struktury cache
|
|
10
|
+
const DEFAULT_PREFIX = 'fluent-emoji-flat';
|
|
10
11
|
// Načtení cache z localStorage při inicializaci
|
|
11
12
|
const loadCacheFromStorage = () => {
|
|
12
13
|
try {
|
|
@@ -43,28 +44,56 @@ const saveCacheToStorage = () => {
|
|
|
43
44
|
// Inicializace cache při načtení modulu
|
|
44
45
|
loadCacheFromStorage();
|
|
45
46
|
/**
|
|
46
|
-
*
|
|
47
|
+
* Parsuje název ikony ve formátu "prefix:iconName"
|
|
48
|
+
* @param {string} name - Název ikony (např. 'airplane' nebo 'fluent-color:receipt-16')
|
|
49
|
+
* @returns {{ fullName: string, prefix: string, iconName: string }}
|
|
50
|
+
*/
|
|
51
|
+
const parseIconName = (name) => {
|
|
52
|
+
if (!name) {
|
|
53
|
+
return { fullName: '', prefix: DEFAULT_PREFIX, iconName: '' };
|
|
54
|
+
}
|
|
55
|
+
// Pokud obsahuje ":", rozdělíme na prefix a iconName
|
|
56
|
+
if (name.includes(':')) {
|
|
57
|
+
const [prefix, iconName] = name.split(':', 2);
|
|
58
|
+
return {
|
|
59
|
+
fullName: `${prefix}:${iconName}`,
|
|
60
|
+
prefix,
|
|
61
|
+
iconName
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// Pokud neobsahuje ":", použijeme default prefix
|
|
65
|
+
return {
|
|
66
|
+
fullName: `${DEFAULT_PREFIX}:${name}`,
|
|
67
|
+
prefix: DEFAULT_PREFIX,
|
|
68
|
+
iconName: name
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Komponenta pro zobrazení Iconify ikon s automatickým cachováním
|
|
47
73
|
*
|
|
48
|
-
* @param {string} name - Název ikony
|
|
74
|
+
* @param {string} name - Název ikony ve formátu "prefix:iconName" nebo jen "iconName"
|
|
75
|
+
* (např. 'airplane', 'fluent-color:receipt-16', 'mdi:home')
|
|
49
76
|
* @param {number} size - Velikost ikony v pixelech
|
|
50
77
|
*
|
|
51
78
|
* Příklad použití:
|
|
52
79
|
* <EmojiIcon name="airplane" size={20} />
|
|
80
|
+
* <EmojiIcon name="fluent-color:receipt-16" size={24} />
|
|
81
|
+
* <EmojiIcon name="mdi:home" size={32} />
|
|
53
82
|
*/
|
|
54
83
|
const EmojiIcon = ({ name, size = 20 }) => {
|
|
55
|
-
const iconName = name;
|
|
56
|
-
const [iconData, setIconData] = useState(iconCache.get(
|
|
84
|
+
const { fullName, prefix, iconName } = parseIconName(name);
|
|
85
|
+
const [iconData, setIconData] = useState(iconCache.get(fullName) || null);
|
|
57
86
|
useEffect(() => {
|
|
58
87
|
// Pokud už je ikona v cache, použijeme ji okamžitě
|
|
59
|
-
if (iconCache.has(
|
|
60
|
-
setIconData(iconCache.get(
|
|
88
|
+
if (iconCache.has(fullName)) {
|
|
89
|
+
setIconData(iconCache.get(fullName));
|
|
61
90
|
return;
|
|
62
91
|
}
|
|
63
92
|
// Pokud se ikona již načítá, počkáme
|
|
64
|
-
if (loadingIcons.has(
|
|
93
|
+
if (loadingIcons.has(fullName)) {
|
|
65
94
|
const checkInterval = setInterval(() => {
|
|
66
|
-
if (iconCache.has(
|
|
67
|
-
setIconData(iconCache.get(
|
|
95
|
+
if (iconCache.has(fullName)) {
|
|
96
|
+
setIconData(iconCache.get(fullName));
|
|
68
97
|
clearInterval(checkInterval);
|
|
69
98
|
}
|
|
70
99
|
}, 50);
|
|
@@ -77,9 +106,9 @@ const EmojiIcon = ({ name, size = 20 }) => {
|
|
|
77
106
|
};
|
|
78
107
|
}
|
|
79
108
|
// Označíme ikonu jako načítající se
|
|
80
|
-
loadingIcons.add(
|
|
81
|
-
// Načteme ikonu z Iconify API
|
|
82
|
-
fetch(`https://api.iconify.design
|
|
109
|
+
loadingIcons.add(fullName);
|
|
110
|
+
// Načteme ikonu z Iconify API s použitím správného prefixu
|
|
111
|
+
fetch(`https://api.iconify.design/${prefix}.json?icons=${iconName}`)
|
|
83
112
|
.then(res => res.json())
|
|
84
113
|
.then(data => {
|
|
85
114
|
if (data && data.icons && data.icons[iconName]) {
|
|
@@ -88,18 +117,18 @@ const EmojiIcon = ({ name, size = 20 }) => {
|
|
|
88
117
|
width: data.width || 32,
|
|
89
118
|
height: data.height || 32
|
|
90
119
|
};
|
|
91
|
-
// Uložíme do naší cache
|
|
92
|
-
iconCache.set(
|
|
120
|
+
// Uložíme do naší cache s plným názvem
|
|
121
|
+
iconCache.set(fullName, newIconData);
|
|
93
122
|
saveCacheToStorage();
|
|
94
123
|
setIconData(newIconData);
|
|
95
|
-
loadingIcons.delete(
|
|
124
|
+
loadingIcons.delete(fullName);
|
|
96
125
|
}
|
|
97
126
|
})
|
|
98
127
|
.catch(e => {
|
|
99
|
-
console.warn(`Failed to load icon ${
|
|
100
|
-
loadingIcons.delete(
|
|
128
|
+
console.warn(`Failed to load icon ${fullName}:`, e);
|
|
129
|
+
loadingIcons.delete(fullName);
|
|
101
130
|
});
|
|
102
|
-
}, [iconName]);
|
|
131
|
+
}, [fullName, prefix, iconName]);
|
|
103
132
|
// Pokud nemáme data, zobrazíme placeholder
|
|
104
133
|
if (!iconData) {
|
|
105
134
|
return (_jsx("span", { style: {
|
|
@@ -119,52 +148,66 @@ const EmojiIcon = ({ name, size = 20 }) => {
|
|
|
119
148
|
* Funkce pro předběžné načtení ikon do cache
|
|
120
149
|
* Volej před prvním renderem pro načtení důležitých ikon
|
|
121
150
|
*
|
|
122
|
-
* @param {string[]} iconNames - Pole názvů ikon k načtení
|
|
151
|
+
* @param {string[]} iconNames - Pole názvů ikon k načtení (podporuje formát "prefix:iconName")
|
|
123
152
|
*
|
|
124
153
|
* Příklad:
|
|
125
|
-
* preloadIcons(['airplane', 'warning', '
|
|
154
|
+
* preloadIcons(['airplane', 'warning', 'fluent-color:receipt-16']);
|
|
126
155
|
*/
|
|
127
156
|
export const preloadIcons = async (iconNames) => {
|
|
128
|
-
//
|
|
129
|
-
const
|
|
130
|
-
|
|
157
|
+
// Seskupíme ikony podle prefixu
|
|
158
|
+
const iconsByPrefix = new Map();
|
|
159
|
+
iconNames.forEach(name => {
|
|
160
|
+
const { fullName, prefix, iconName } = parseIconName(name);
|
|
161
|
+
// Přeskočíme ikony, které už jsou v cache nebo se načítají
|
|
162
|
+
if (iconCache.has(fullName) || loadingIcons.has(fullName)) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (!iconsByPrefix.has(prefix)) {
|
|
166
|
+
iconsByPrefix.set(prefix, []);
|
|
167
|
+
}
|
|
168
|
+
iconsByPrefix.get(prefix).push({ fullName, iconName });
|
|
131
169
|
});
|
|
132
|
-
if (
|
|
170
|
+
if (iconsByPrefix.size === 0) {
|
|
133
171
|
console.log('All icons already cached');
|
|
134
172
|
return;
|
|
135
173
|
}
|
|
136
|
-
//
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
174
|
+
// Načteme ikony pro každý prefix samostatně
|
|
175
|
+
const promises = Array.from(iconsByPrefix.entries()).map(async ([prefix, icons]) => {
|
|
176
|
+
// Označíme všechny jako načítající se
|
|
177
|
+
icons.forEach(({ fullName }) => {
|
|
178
|
+
loadingIcons.add(fullName);
|
|
179
|
+
});
|
|
180
|
+
try {
|
|
181
|
+
// Načteme všechny ikony daného prefixu najednou
|
|
182
|
+
const iconsParam = icons.map(i => i.iconName).join(',');
|
|
183
|
+
const response = await fetch(`https://api.iconify.design/${prefix}.json?icons=${iconsParam}`);
|
|
184
|
+
const data = await response.json();
|
|
185
|
+
if (data && data.icons) {
|
|
186
|
+
Object.entries(data.icons).forEach(([name, iconInfo]) => {
|
|
187
|
+
const fullName = `${prefix}:${name}`;
|
|
188
|
+
const iconData = {
|
|
189
|
+
body: iconInfo.body,
|
|
190
|
+
width: data.width || 32,
|
|
191
|
+
height: data.height || 32
|
|
192
|
+
};
|
|
193
|
+
// Uložíme do naší cache s plným názvem
|
|
194
|
+
iconCache.set(fullName, iconData);
|
|
195
|
+
loadingIcons.delete(fullName);
|
|
196
|
+
});
|
|
197
|
+
console.log(`Preloaded ${Object.keys(data.icons).length} icons from ${prefix}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch (e) {
|
|
201
|
+
console.warn(`Failed to preload icons from ${prefix}:`, e);
|
|
202
|
+
// Odstraníme z loading state
|
|
203
|
+
icons.forEach(({ fullName }) => {
|
|
204
|
+
loadingIcons.delete(fullName);
|
|
155
205
|
});
|
|
156
|
-
// Uložíme celou cache do localStorage
|
|
157
|
-
saveCacheToStorage();
|
|
158
|
-
console.log(`Preloaded ${Object.keys(data.icons).length} icons`);
|
|
159
206
|
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
iconsToLoad.forEach(name => {
|
|
165
|
-
loadingIcons.delete(name);
|
|
166
|
-
});
|
|
167
|
-
}
|
|
207
|
+
});
|
|
208
|
+
await Promise.all(promises);
|
|
209
|
+
// Uložíme celou cache do localStorage
|
|
210
|
+
saveCacheToStorage();
|
|
168
211
|
};
|
|
169
212
|
/**
|
|
170
213
|
* Vymazání cache ikon
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.jsx"],"names":[],"mappings":";AAAA,oBAAoB;AACpB,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEnD,sCAAsC;AACtC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;AAC5B,MAAM,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;AAE/B,8CAA8C;AAC9C,MAAM,SAAS,GAAG,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.jsx"],"names":[],"mappings":";AAAA,oBAAoB;AACpB,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEnD,sCAAsC;AACtC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;AAC5B,MAAM,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;AAE/B,8CAA8C;AAC9C,MAAM,SAAS,GAAG,eAAe,CAAC;AAClC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,4CAA4C;AACzE,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAE3C,gDAAgD;AAChD,MAAM,oBAAoB,GAAG,GAAG,EAAE;IAChC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC/C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,OAAO,KAAK,aAAa,IAAI,IAAI,EAAE,CAAC;gBACtC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE;oBACpD,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;wBAC7C,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;oBACpC,CAAC;gBACH,CAAC,CAAC,CAAC;gBACH,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,mBAAmB,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,8CAA8C,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC;AACH,CAAC,CAAC;AAEF,gCAAgC;AAChC,MAAM,kBAAkB,GAAG,GAAG,EAAE;IAC9B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAC3C,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC;YAC7C,OAAO,EAAE,aAAa;YACtB,IAAI;SACL,CAAC,CAAC,CAAC;IACN,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,4CAA4C,EAAE,CAAC,CAAC,CAAC;IAChE,CAAC;AACH,CAAC,CAAC;AAEF,wCAAwC;AACxC,oBAAoB,EAAE,CAAC;AAEvB;;;;GAIG;AACH,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,EAAE;IAC7B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAChE,CAAC;IAED,qDAAqD;IACrD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC9C,OAAO;YACL,QAAQ,EAAE,GAAG,MAAM,IAAI,QAAQ,EAAE;YACjC,MAAM;YACN,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,iDAAiD;IACjD,OAAO;QACL,QAAQ,EAAE,GAAG,cAAc,IAAI,IAAI,EAAE;QACrC,MAAM,EAAE,cAAc;QACtB,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,SAAS,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,EAAE;IACxC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC;IAE1E,SAAS,CAAC,GAAG,EAAE;QACb,mDAAmD;QACnD,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QAED,qCAAqC;QACrC,IAAI,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;gBACrC,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC5B,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACrC,aAAa,CAAC,aAAa,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC,EAAE,EAAE,CAAC,CAAC;YAEP,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC9B,aAAa,CAAC,aAAa,CAAC,CAAC;YAC/B,CAAC,EAAE,IAAI,CAAC,CAAC;YAET,OAAO,GAAG,EAAE;gBACV,aAAa,CAAC,aAAa,CAAC,CAAC;gBAC7B,YAAY,CAAC,OAAO,CAAC,CAAC;YACxB,CAAC,CAAC;QACJ,CAAC;QAED,oCAAoC;QACpC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE3B,2DAA2D;QAC3D,KAAK,CAAC,8BAA8B,MAAM,eAAe,QAAQ,EAAE,CAAC;aACjE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;aACvB,IAAI,CAAC,IAAI,CAAC,EAAE;YACX,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC/C,MAAM,WAAW,GAAG;oBAClB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI;oBAC/B,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE;oBACvB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;iBAC1B,CAAC;gBAEF,uCAAuC;gBACvC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;gBACrC,kBAAkB,EAAE,CAAC;gBACrB,WAAW,CAAC,WAAW,CAAC,CAAC;gBACzB,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAChC,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,CAAC,EAAE;YACT,OAAO,CAAC,IAAI,CAAC,uBAAuB,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC;YACpD,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACP,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEjC,2CAA2C;IAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CACL,eACE,KAAK,EAAE;gBACL,OAAO,EAAE,cAAc;gBACvB,KAAK,EAAE,IAAI;gBACX,MAAM,EAAE,IAAI;gBACZ,OAAO,EAAE,GAAG;aACb,GACD,CACH,CAAC;IACJ,CAAC;IAED,gCAAgC;IAChC,OAAO,CACL,cACE,KAAK,EAAC,4BAA4B,EAClC,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,IAAI,EACZ,OAAO,EAAE,OAAO,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,EACnD,KAAK,EAAE;YACL,OAAO,EAAE,cAAc;YACvB,aAAa,EAAE,QAAQ;SACxB,EACD,uBAAuB,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,GAClD,CACH,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,SAAS,EAAE,EAAE;IAC9C,gCAAgC;IAChC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC;IAEhC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACvB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAE3D,2DAA2D;QAC3D,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChC,CAAC;QACD,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,IAAI,aAAa,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,OAAO;IACT,CAAC;IAED,4CAA4C;IAC5C,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE;QACjF,sCAAsC;QACtC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;YAC7B,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,gDAAgD;YAChD,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,8BAA8B,MAAM,eAAe,UAAU,EAAE,CAAC,CAAC;YAC9F,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAEnC,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACvB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE;oBACtD,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC;oBACrC,MAAM,QAAQ,GAAG;wBACf,IAAI,EAAE,QAAQ,CAAC,IAAI;wBACnB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE;wBACvB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;qBAC1B,CAAC;oBAEF,uCAAuC;oBACvC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;oBAClC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAChC,CAAC,CAAC,CAAC;gBAEH,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,eAAe,MAAM,EAAE,CAAC,CAAC;YAClF,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,gCAAgC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;YAC3D,6BAA6B;YAC7B,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;gBAC7B,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAE5B,sCAAsC;IACtC,kBAAkB,EAAE,CAAC;AACvB,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IACjC,SAAS,CAAC,KAAK,EAAE,CAAC;IAClB,IAAI,CAAC;QACH,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,6BAA6B,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
package/index.jsx
CHANGED
|
@@ -6,8 +6,9 @@ const iconCache = new Map();
|
|
|
6
6
|
const loadingIcons = new Set();
|
|
7
7
|
|
|
8
8
|
// Lokální storage klíč pro persistentní cache
|
|
9
|
-
const CACHE_KEY = '
|
|
10
|
-
const CACHE_VERSION = '
|
|
9
|
+
const CACHE_KEY = 'iconify-cache';
|
|
10
|
+
const CACHE_VERSION = '2.0'; // Zvýšena verze kvůli změně struktury cache
|
|
11
|
+
const DEFAULT_PREFIX = 'fluent-emoji-flat';
|
|
11
12
|
|
|
12
13
|
// Načtení cache z localStorage při inicializaci
|
|
13
14
|
const loadCacheFromStorage = () => {
|
|
@@ -46,30 +47,61 @@ const saveCacheToStorage = () => {
|
|
|
46
47
|
loadCacheFromStorage();
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
|
-
*
|
|
50
|
+
* Parsuje název ikony ve formátu "prefix:iconName"
|
|
51
|
+
* @param {string} name - Název ikony (např. 'airplane' nebo 'fluent-color:receipt-16')
|
|
52
|
+
* @returns {{ fullName: string, prefix: string, iconName: string }}
|
|
53
|
+
*/
|
|
54
|
+
const parseIconName = (name) => {
|
|
55
|
+
if (!name) {
|
|
56
|
+
return { fullName: '', prefix: DEFAULT_PREFIX, iconName: '' };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Pokud obsahuje ":", rozdělíme na prefix a iconName
|
|
60
|
+
if (name.includes(':')) {
|
|
61
|
+
const [prefix, iconName] = name.split(':', 2);
|
|
62
|
+
return {
|
|
63
|
+
fullName: `${prefix}:${iconName}`,
|
|
64
|
+
prefix,
|
|
65
|
+
iconName
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Pokud neobsahuje ":", použijeme default prefix
|
|
70
|
+
return {
|
|
71
|
+
fullName: `${DEFAULT_PREFIX}:${name}`,
|
|
72
|
+
prefix: DEFAULT_PREFIX,
|
|
73
|
+
iconName: name
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Komponenta pro zobrazení Iconify ikon s automatickým cachováním
|
|
50
79
|
*
|
|
51
|
-
* @param {string} name - Název ikony
|
|
80
|
+
* @param {string} name - Název ikony ve formátu "prefix:iconName" nebo jen "iconName"
|
|
81
|
+
* (např. 'airplane', 'fluent-color:receipt-16', 'mdi:home')
|
|
52
82
|
* @param {number} size - Velikost ikony v pixelech
|
|
53
83
|
*
|
|
54
84
|
* Příklad použití:
|
|
55
85
|
* <EmojiIcon name="airplane" size={20} />
|
|
86
|
+
* <EmojiIcon name="fluent-color:receipt-16" size={24} />
|
|
87
|
+
* <EmojiIcon name="mdi:home" size={32} />
|
|
56
88
|
*/
|
|
57
89
|
const EmojiIcon = ({ name, size = 20 }) => {
|
|
58
|
-
const iconName = name;
|
|
59
|
-
const [iconData, setIconData] = useState(iconCache.get(
|
|
90
|
+
const { fullName, prefix, iconName } = parseIconName(name);
|
|
91
|
+
const [iconData, setIconData] = useState(iconCache.get(fullName) || null);
|
|
60
92
|
|
|
61
93
|
useEffect(() => {
|
|
62
94
|
// Pokud už je ikona v cache, použijeme ji okamžitě
|
|
63
|
-
if (iconCache.has(
|
|
64
|
-
setIconData(iconCache.get(
|
|
95
|
+
if (iconCache.has(fullName)) {
|
|
96
|
+
setIconData(iconCache.get(fullName));
|
|
65
97
|
return;
|
|
66
98
|
}
|
|
67
99
|
|
|
68
100
|
// Pokud se ikona již načítá, počkáme
|
|
69
|
-
if (loadingIcons.has(
|
|
101
|
+
if (loadingIcons.has(fullName)) {
|
|
70
102
|
const checkInterval = setInterval(() => {
|
|
71
|
-
if (iconCache.has(
|
|
72
|
-
setIconData(iconCache.get(
|
|
103
|
+
if (iconCache.has(fullName)) {
|
|
104
|
+
setIconData(iconCache.get(fullName));
|
|
73
105
|
clearInterval(checkInterval);
|
|
74
106
|
}
|
|
75
107
|
}, 50);
|
|
@@ -85,10 +117,10 @@ const EmojiIcon = ({ name, size = 20 }) => {
|
|
|
85
117
|
}
|
|
86
118
|
|
|
87
119
|
// Označíme ikonu jako načítající se
|
|
88
|
-
loadingIcons.add(
|
|
120
|
+
loadingIcons.add(fullName);
|
|
89
121
|
|
|
90
|
-
// Načteme ikonu z Iconify API
|
|
91
|
-
fetch(`https://api.iconify.design
|
|
122
|
+
// Načteme ikonu z Iconify API s použitím správného prefixu
|
|
123
|
+
fetch(`https://api.iconify.design/${prefix}.json?icons=${iconName}`)
|
|
92
124
|
.then(res => res.json())
|
|
93
125
|
.then(data => {
|
|
94
126
|
if (data && data.icons && data.icons[iconName]) {
|
|
@@ -98,18 +130,18 @@ const EmojiIcon = ({ name, size = 20 }) => {
|
|
|
98
130
|
height: data.height || 32
|
|
99
131
|
};
|
|
100
132
|
|
|
101
|
-
// Uložíme do naší cache
|
|
102
|
-
iconCache.set(
|
|
133
|
+
// Uložíme do naší cache s plným názvem
|
|
134
|
+
iconCache.set(fullName, newIconData);
|
|
103
135
|
saveCacheToStorage();
|
|
104
136
|
setIconData(newIconData);
|
|
105
|
-
loadingIcons.delete(
|
|
137
|
+
loadingIcons.delete(fullName);
|
|
106
138
|
}
|
|
107
139
|
})
|
|
108
140
|
.catch(e => {
|
|
109
|
-
console.warn(`Failed to load icon ${
|
|
110
|
-
loadingIcons.delete(
|
|
141
|
+
console.warn(`Failed to load icon ${fullName}:`, e);
|
|
142
|
+
loadingIcons.delete(fullName);
|
|
111
143
|
});
|
|
112
|
-
}, [iconName]);
|
|
144
|
+
}, [fullName, prefix, iconName]);
|
|
113
145
|
|
|
114
146
|
// Pokud nemáme data, zobrazíme placeholder
|
|
115
147
|
if (!iconData) {
|
|
@@ -145,57 +177,76 @@ const EmojiIcon = ({ name, size = 20 }) => {
|
|
|
145
177
|
* Funkce pro předběžné načtení ikon do cache
|
|
146
178
|
* Volej před prvním renderem pro načtení důležitých ikon
|
|
147
179
|
*
|
|
148
|
-
* @param {string[]} iconNames - Pole názvů ikon k načtení
|
|
180
|
+
* @param {string[]} iconNames - Pole názvů ikon k načtení (podporuje formát "prefix:iconName")
|
|
149
181
|
*
|
|
150
182
|
* Příklad:
|
|
151
|
-
* preloadIcons(['airplane', 'warning', '
|
|
183
|
+
* preloadIcons(['airplane', 'warning', 'fluent-color:receipt-16']);
|
|
152
184
|
*/
|
|
153
185
|
export const preloadIcons = async (iconNames) => {
|
|
154
|
-
//
|
|
155
|
-
const
|
|
156
|
-
|
|
186
|
+
// Seskupíme ikony podle prefixu
|
|
187
|
+
const iconsByPrefix = new Map();
|
|
188
|
+
|
|
189
|
+
iconNames.forEach(name => {
|
|
190
|
+
const { fullName, prefix, iconName } = parseIconName(name);
|
|
191
|
+
|
|
192
|
+
// Přeskočíme ikony, které už jsou v cache nebo se načítají
|
|
193
|
+
if (iconCache.has(fullName) || loadingIcons.has(fullName)) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!iconsByPrefix.has(prefix)) {
|
|
198
|
+
iconsByPrefix.set(prefix, []);
|
|
199
|
+
}
|
|
200
|
+
iconsByPrefix.get(prefix).push({ fullName, iconName });
|
|
157
201
|
});
|
|
158
202
|
|
|
159
|
-
if (
|
|
203
|
+
if (iconsByPrefix.size === 0) {
|
|
160
204
|
console.log('All icons already cached');
|
|
161
205
|
return;
|
|
162
206
|
}
|
|
163
207
|
|
|
164
|
-
//
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
208
|
+
// Načteme ikony pro každý prefix samostatně
|
|
209
|
+
const promises = Array.from(iconsByPrefix.entries()).map(async ([prefix, icons]) => {
|
|
210
|
+
// Označíme všechny jako načítající se
|
|
211
|
+
icons.forEach(({ fullName }) => {
|
|
212
|
+
loadingIcons.add(fullName);
|
|
213
|
+
});
|
|
168
214
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
215
|
+
try {
|
|
216
|
+
// Načteme všechny ikony daného prefixu najednou
|
|
217
|
+
const iconsParam = icons.map(i => i.iconName).join(',');
|
|
218
|
+
const response = await fetch(`https://api.iconify.design/${prefix}.json?icons=${iconsParam}`);
|
|
219
|
+
const data = await response.json();
|
|
220
|
+
|
|
221
|
+
if (data && data.icons) {
|
|
222
|
+
Object.entries(data.icons).forEach(([name, iconInfo]) => {
|
|
223
|
+
const fullName = `${prefix}:${name}`;
|
|
224
|
+
const iconData = {
|
|
225
|
+
body: iconInfo.body,
|
|
226
|
+
width: data.width || 32,
|
|
227
|
+
height: data.height || 32
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// Uložíme do naší cache s plným názvem
|
|
231
|
+
iconCache.set(fullName, iconData);
|
|
232
|
+
loadingIcons.delete(fullName);
|
|
233
|
+
});
|
|
187
234
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
235
|
+
console.log(`Preloaded ${Object.keys(data.icons).length} icons from ${prefix}`);
|
|
236
|
+
}
|
|
237
|
+
} catch (e) {
|
|
238
|
+
console.warn(`Failed to preload icons from ${prefix}:`, e);
|
|
239
|
+
// Odstraníme z loading state
|
|
240
|
+
icons.forEach(({ fullName }) => {
|
|
241
|
+
loadingIcons.delete(fullName);
|
|
242
|
+
});
|
|
191
243
|
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
await Promise.all(promises);
|
|
247
|
+
|
|
248
|
+
// Uložíme celou cache do localStorage
|
|
249
|
+
saveCacheToStorage();
|
|
199
250
|
};
|
|
200
251
|
|
|
201
252
|
/**
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bit.rhplus/ui2.emoji-icons",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"homepage": "https://bit.cloud/remote-scope/ui2/emoji-icons",
|
|
4
5
|
"main": "dist/index.js",
|
|
5
6
|
"componentId": {
|
|
7
|
+
"scope": "remote-scope",
|
|
6
8
|
"name": "ui2/emoji-icons",
|
|
7
|
-
"version": "0.0.
|
|
8
|
-
"scope": "remote-scope"
|
|
9
|
+
"version": "0.0.2"
|
|
9
10
|
},
|
|
10
11
|
"dependencies": {},
|
|
11
12
|
"devDependencies": {
|
|
File without changes
|