iconly 1.4.2 → 1.4.4
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/.eslintignore +3 -0
- package/.eslintrc.json +26 -0
- package/README.md +24 -19
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -46
- package/dist/index.js.map +1 -1
- package/dist/index.module.js +42 -46
- package/dist/index.module.js.map +1 -1
- package/package.json +33 -17
- package/src/index.ts +124 -0
- package/tsconfig.json +6 -0
- package/src/index.js +0 -125
package/.eslintignore
ADDED
package/.eslintrc.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"env": {
|
|
3
|
+
"browser": true,
|
|
4
|
+
"es2022": true
|
|
5
|
+
},
|
|
6
|
+
"extends": [
|
|
7
|
+
"airbnb-base",
|
|
8
|
+
"plugin:@typescript-eslint/recommended"
|
|
9
|
+
],
|
|
10
|
+
"parser": "@typescript-eslint/parser",
|
|
11
|
+
"parserOptions": {
|
|
12
|
+
"ecmaVersion": "latest",
|
|
13
|
+
"sourceType": "module",
|
|
14
|
+
"project": "./tsconfig.json"
|
|
15
|
+
},
|
|
16
|
+
"plugins": ["@typescript-eslint"],
|
|
17
|
+
"rules": {
|
|
18
|
+
"max-len": [
|
|
19
|
+
"off",
|
|
20
|
+
{
|
|
21
|
+
"code": 100,
|
|
22
|
+
"ignoreUrls": true
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
package/README.md
CHANGED
|
@@ -3,24 +3,28 @@
|
|
|
3
3
|
|
|
4
4
|
<h1>iconly</h1>
|
|
5
5
|
|
|
6
|
+
<p><sup>Iconly is designed to load and cache SVG icons in the browser, using IndexedDB to store the data. It retrieves the icons from a given SVG file, stores them in IndexedDB, and inserts them into the DOM for easy access and use.</sup></p>
|
|
7
|
+
|
|
6
8
|
[](https://www.npmjs.com/package/iconly)
|
|
7
9
|
[](https://github.com/ux-ui-pro/iconly)
|
|
8
10
|
[](https://www.npmjs.org/package/iconly)
|
|
9
11
|
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
+
<sup>1kB gzipped</sup>
|
|
13
|
+
|
|
14
|
+
<a href="https://codepen.io/ux-ui/pen/zYmyqWR">Demo</a>
|
|
12
15
|
|
|
13
16
|
</div>
|
|
14
17
|
<br>
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
➤ **Installation**
|
|
20
|
+
|
|
21
|
+
```console
|
|
18
22
|
$ yarn add iconly
|
|
19
23
|
```
|
|
20
|
-
|
|
21
24
|
<br>
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
➤ **Import**
|
|
27
|
+
|
|
24
28
|
```javascript
|
|
25
29
|
import Iconly from 'iconly';
|
|
26
30
|
```
|
|
@@ -36,29 +40,30 @@ iconly.init().then(() => console.log('Iconly is initialized and icons are loaded
|
|
|
36
40
|
```
|
|
37
41
|
<br>
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
<sub>icons.svg</sub>
|
|
43
|
+
➤ **File with icons**
|
|
41
44
|
|
|
42
45
|
```HTML
|
|
43
46
|
<svg>
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
<symbol id="icon-one" viewBox="0 0 100 100">
|
|
48
|
+
<path ... />
|
|
49
|
+
</symbol>
|
|
50
|
+
<symbol id="icon-two" viewBox="0 0 100 100">
|
|
51
|
+
<path ... />
|
|
52
|
+
</symbol>
|
|
53
|
+
...
|
|
51
54
|
</svg>
|
|
52
55
|
```
|
|
53
56
|
<br>
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
➤ **Usage**
|
|
59
|
+
|
|
56
60
|
```HTML
|
|
57
61
|
<svg>
|
|
58
|
-
|
|
62
|
+
<use href="#icon-name"></use>
|
|
59
63
|
</svg>
|
|
60
64
|
```
|
|
61
65
|
<br>
|
|
62
66
|
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
➤ **License**
|
|
68
|
+
|
|
69
|
+
iconly is released under MIT license
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default class Iconly {
|
|
2
|
+
#private;
|
|
3
|
+
constructor(options?: {
|
|
4
|
+
file?: string;
|
|
5
|
+
version?: string;
|
|
6
|
+
debug?: boolean;
|
|
7
|
+
container?: string | HTMLElement;
|
|
8
|
+
});
|
|
9
|
+
init(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export default Iconly;
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"AAAA,qBAAM,MAAM;;gBAUE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;KAAO;IAiE1G,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CA8C5B;AAED,eAAe,MAAM,CAAC","sources":["src/src/index.ts","src/index.ts"],"sourcesContent":[null,"class Iconly {\n static #dbInstance: Promise<IDBDatabase> | null = null;\n\n #options: {\n file: string;\n version: string;\n debug: boolean;\n container: HTMLElement;\n };\n\n constructor(options: { file?: string; version?: string; debug?: boolean; container?: string | HTMLElement } = {}) {\n const defaultOptions = {\n file: './icons.svg',\n version: '1.0',\n debug: false,\n container: document.body ?? document.documentElement,\n };\n\n this.#options = {\n ...defaultOptions,\n ...options,\n container: typeof options.container === 'string'\n ? document.querySelector(options.container) ?? defaultOptions.container\n : options.container ?? defaultOptions.container,\n };\n\n if (!this.#options.container) {\n throw new Error('Invalid container element');\n }\n\n if (!Iconly.#dbInstance) {\n Iconly.#dbInstance = this.#openDB('iconlyDB', 1);\n }\n }\n\n async #openDB(name: string, version: number): Promise<IDBDatabase> {\n if (!('indexedDB' in window)) {\n this.#logError('This browser doesn\\'t support IndexedDB');\n throw new Error('IndexedDB not supported');\n }\n\n return new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(name, version);\n\n request.onerror = () => reject(new Error(`IndexedDB error: ${request.error}`));\n request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\n const db = (event.target as IDBOpenDBRequest).result;\n if (!db.objectStoreNames.contains('icons')) {\n db.createObjectStore('icons', { keyPath: 'version' });\n }\n };\n request.onsuccess = () => resolve(request.result);\n });\n }\n\n static async #fetchData(file: string): Promise<string> {\n const response = await fetch(file);\n if (!response.ok) throw new Error('Network response was not ok');\n return response.text();\n }\n\n #insert(data: string): void {\n let iconSetDiv = document.getElementById('iconset');\n\n if (!iconSetDiv) {\n iconSetDiv = document.createElement('div');\n iconSetDiv.id = 'iconset';\n iconSetDiv.setAttribute('aria-hidden', 'true');\n iconSetDiv.style.cssText = 'width: 0; height: 0; position: absolute; left: -9999px;';\n this.#options.container.appendChild(iconSetDiv);\n }\n\n iconSetDiv.innerHTML = data;\n }\n\n async init(): Promise<void> {\n const { file, version } = this.#options;\n\n try {\n let data = await Iconly.#fetchData(file);\n\n const db = await Iconly.#dbInstance;\n const tx = db.transaction('icons', 'readwrite');\n const store = tx.objectStore('icons');\n\n const dbVersion = await new Promise<{ version: string; data: string } | undefined>((resolve, reject) => {\n const request = store.get(version);\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n\n if (!(dbVersion && dbVersion.data)) {\n await new Promise<void>((resolve, reject) => {\n const request = store.put({ version, data });\n\n request.onsuccess = () => resolve();\n request.onerror = () => reject(request.error);\n });\n } else {\n data = dbVersion.data;\n }\n\n await new Promise<void>((resolve, reject) => {\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n tx.onabort = () => reject(tx.error);\n });\n\n this.#insert(data);\n } catch (error) {\n this.#logError('Error initializing Iconly:', error);\n }\n }\n\n #logError(...messages: unknown[]): void {\n if (this.#options.debug) {\n // eslint-disable-next-line no-console\n console.error(...messages);\n }\n }\n}\n\nexport default Iconly;\n"],"names":[],"version":3,"file":"index.d.ts.map"}
|
package/dist/index.js
CHANGED
|
@@ -9,72 +9,63 @@ function $parcel$export(e, n, v, s) {
|
|
|
9
9
|
|
|
10
10
|
$parcel$defineInteropFlag(module.exports);
|
|
11
11
|
|
|
12
|
-
$parcel$export(module.exports, "default", ()
|
|
13
|
-
class $
|
|
14
|
-
static #dbInstance;
|
|
12
|
+
$parcel$export(module.exports, "default", function () { return $a196c1ed25598f0e$export$2e2bcd8739ae039; });
|
|
13
|
+
class $a196c1ed25598f0e$var$Iconly {
|
|
14
|
+
static #dbInstance = null;
|
|
15
15
|
#options;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
this.#options = {
|
|
16
|
+
constructor(options = {}){
|
|
17
|
+
const defaultOptions = {
|
|
19
18
|
file: "./icons.svg",
|
|
20
19
|
version: "1.0",
|
|
21
20
|
debug: false,
|
|
22
|
-
container: document.body
|
|
23
|
-
|
|
21
|
+
container: document.body ?? document.documentElement
|
|
22
|
+
};
|
|
23
|
+
this.#options = {
|
|
24
|
+
...defaultOptions,
|
|
25
|
+
...options,
|
|
26
|
+
container: typeof options.container === "string" ? document.querySelector(options.container) ?? defaultOptions.container : options.container ?? defaultOptions.container
|
|
24
27
|
};
|
|
25
|
-
|
|
26
|
-
if (!$
|
|
28
|
+
if (!this.#options.container) throw new Error("Invalid container element");
|
|
29
|
+
if (!$a196c1ed25598f0e$var$Iconly.#dbInstance) $a196c1ed25598f0e$var$Iconly.#dbInstance = this.#openDB("iconlyDB", 1);
|
|
27
30
|
}
|
|
28
31
|
async #openDB(name, version) {
|
|
29
32
|
if (!("indexedDB" in window)) {
|
|
30
33
|
this.#logError("This browser doesn't support IndexedDB");
|
|
31
|
-
|
|
34
|
+
throw new Error("IndexedDB not supported");
|
|
32
35
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
request.onsuccess = ()=>resolve(request.result);
|
|
45
|
-
});
|
|
46
|
-
} catch (error) {
|
|
47
|
-
this.#logError(error);
|
|
48
|
-
throw error;
|
|
49
|
-
}
|
|
50
|
-
return db;
|
|
36
|
+
return new Promise((resolve, reject)=>{
|
|
37
|
+
const request = indexedDB.open(name, version);
|
|
38
|
+
request.onerror = ()=>reject(new Error(`IndexedDB error: ${request.error}`));
|
|
39
|
+
request.onupgradeneeded = (event)=>{
|
|
40
|
+
const db = event.target.result;
|
|
41
|
+
if (!db.objectStoreNames.contains("icons")) db.createObjectStore("icons", {
|
|
42
|
+
keyPath: "version"
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
request.onsuccess = ()=>resolve(request.result);
|
|
46
|
+
});
|
|
51
47
|
}
|
|
52
|
-
async #fetchData(file) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return response.text();
|
|
57
|
-
} catch (error) {
|
|
58
|
-
this.#logError(error);
|
|
59
|
-
throw error;
|
|
60
|
-
}
|
|
48
|
+
static async #fetchData(file) {
|
|
49
|
+
const response = await fetch(file);
|
|
50
|
+
if (!response.ok) throw new Error("Network response was not ok");
|
|
51
|
+
return response.text();
|
|
61
52
|
}
|
|
62
|
-
|
|
53
|
+
#insert(data) {
|
|
63
54
|
let iconSetDiv = document.getElementById("iconset");
|
|
64
55
|
if (!iconSetDiv) {
|
|
65
56
|
iconSetDiv = document.createElement("div");
|
|
66
57
|
iconSetDiv.id = "iconset";
|
|
67
58
|
iconSetDiv.setAttribute("aria-hidden", "true");
|
|
68
59
|
iconSetDiv.style.cssText = "width: 0; height: 0; position: absolute; left: -9999px;";
|
|
69
|
-
this.#container.appendChild(iconSetDiv);
|
|
60
|
+
this.#options.container.appendChild(iconSetDiv);
|
|
70
61
|
}
|
|
71
62
|
iconSetDiv.innerHTML = data;
|
|
72
63
|
}
|
|
73
64
|
async init() {
|
|
74
65
|
const { file: file, version: version } = this.#options;
|
|
75
66
|
try {
|
|
76
|
-
let data = await
|
|
77
|
-
const db = await $
|
|
67
|
+
let data = await $a196c1ed25598f0e$var$Iconly.#fetchData(file);
|
|
68
|
+
const db = await $a196c1ed25598f0e$var$Iconly.#dbInstance;
|
|
78
69
|
const tx = db.transaction("icons", "readwrite");
|
|
79
70
|
const store = tx.objectStore("icons");
|
|
80
71
|
const dbVersion = await new Promise((resolve, reject)=>{
|
|
@@ -91,17 +82,22 @@ class $4fa36e821943b400$var$Iconly {
|
|
|
91
82
|
request.onerror = ()=>reject(request.error);
|
|
92
83
|
});
|
|
93
84
|
else data = dbVersion.data;
|
|
94
|
-
await
|
|
95
|
-
|
|
85
|
+
await new Promise((resolve, reject)=>{
|
|
86
|
+
tx.oncomplete = ()=>resolve();
|
|
87
|
+
tx.onerror = ()=>reject(tx.error);
|
|
88
|
+
tx.onabort = ()=>reject(tx.error);
|
|
89
|
+
});
|
|
90
|
+
this.#insert(data);
|
|
96
91
|
} catch (error) {
|
|
97
92
|
this.#logError("Error initializing Iconly:", error);
|
|
98
93
|
}
|
|
99
94
|
}
|
|
100
95
|
#logError(...messages) {
|
|
101
|
-
if (this.#options.debug) console
|
|
96
|
+
if (this.#options.debug) // eslint-disable-next-line no-console
|
|
97
|
+
console.error(...messages);
|
|
102
98
|
}
|
|
103
99
|
}
|
|
104
|
-
var $
|
|
100
|
+
var $a196c1ed25598f0e$export$2e2bcd8739ae039 = $a196c1ed25598f0e$var$Iconly;
|
|
105
101
|
|
|
106
102
|
|
|
107
103
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;;;;;;;AAAA,MAAM;
|
|
1
|
+
{"mappings":"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","sources":["src/index.ts"],"sourcesContent":["class Iconly {\n static #dbInstance: Promise<IDBDatabase> | null = null;\n\n #options: {\n file: string;\n version: string;\n debug: boolean;\n container: HTMLElement;\n };\n\n constructor(options: { file?: string; version?: string; debug?: boolean; container?: string | HTMLElement } = {}) {\n const defaultOptions = {\n file: './icons.svg',\n version: '1.0',\n debug: false,\n container: document.body ?? document.documentElement,\n };\n\n this.#options = {\n ...defaultOptions,\n ...options,\n container: typeof options.container === 'string'\n ? document.querySelector(options.container) ?? defaultOptions.container\n : options.container ?? defaultOptions.container,\n };\n\n if (!this.#options.container) {\n throw new Error('Invalid container element');\n }\n\n if (!Iconly.#dbInstance) {\n Iconly.#dbInstance = this.#openDB('iconlyDB', 1);\n }\n }\n\n async #openDB(name: string, version: number): Promise<IDBDatabase> {\n if (!('indexedDB' in window)) {\n this.#logError('This browser doesn\\'t support IndexedDB');\n throw new Error('IndexedDB not supported');\n }\n\n return new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(name, version);\n\n request.onerror = () => reject(new Error(`IndexedDB error: ${request.error}`));\n request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\n const db = (event.target as IDBOpenDBRequest).result;\n if (!db.objectStoreNames.contains('icons')) {\n db.createObjectStore('icons', { keyPath: 'version' });\n }\n };\n request.onsuccess = () => resolve(request.result);\n });\n }\n\n static async #fetchData(file: string): Promise<string> {\n const response = await fetch(file);\n if (!response.ok) throw new Error('Network response was not ok');\n return response.text();\n }\n\n #insert(data: string): void {\n let iconSetDiv = document.getElementById('iconset');\n\n if (!iconSetDiv) {\n iconSetDiv = document.createElement('div');\n iconSetDiv.id = 'iconset';\n iconSetDiv.setAttribute('aria-hidden', 'true');\n iconSetDiv.style.cssText = 'width: 0; height: 0; position: absolute; left: -9999px;';\n this.#options.container.appendChild(iconSetDiv);\n }\n\n iconSetDiv.innerHTML = data;\n }\n\n async init(): Promise<void> {\n const { file, version } = this.#options;\n\n try {\n let data = await Iconly.#fetchData(file);\n\n const db = await Iconly.#dbInstance;\n const tx = db.transaction('icons', 'readwrite');\n const store = tx.objectStore('icons');\n\n const dbVersion = await new Promise<{ version: string; data: string } | undefined>((resolve, reject) => {\n const request = store.get(version);\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n\n if (!(dbVersion && dbVersion.data)) {\n await new Promise<void>((resolve, reject) => {\n const request = store.put({ version, data });\n\n request.onsuccess = () => resolve();\n request.onerror = () => reject(request.error);\n });\n } else {\n data = dbVersion.data;\n }\n\n await new Promise<void>((resolve, reject) => {\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n tx.onabort = () => reject(tx.error);\n });\n\n this.#insert(data);\n } catch (error) {\n this.#logError('Error initializing Iconly:', error);\n }\n }\n\n #logError(...messages: unknown[]): void {\n if (this.#options.debug) {\n // eslint-disable-next-line no-console\n console.error(...messages);\n }\n }\n}\n\nexport default Iconly;\n"],"names":[],"version":3,"file":"index.js.map"}
|
package/dist/index.module.js
CHANGED
|
@@ -1,68 +1,59 @@
|
|
|
1
|
-
class $
|
|
2
|
-
static #dbInstance;
|
|
1
|
+
class $643fcf18b2d2e76f$var$Iconly {
|
|
2
|
+
static #dbInstance = null;
|
|
3
3
|
#options;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
this.#options = {
|
|
4
|
+
constructor(options = {}){
|
|
5
|
+
const defaultOptions = {
|
|
7
6
|
file: "./icons.svg",
|
|
8
7
|
version: "1.0",
|
|
9
8
|
debug: false,
|
|
10
|
-
container: document.body
|
|
11
|
-
|
|
9
|
+
container: document.body ?? document.documentElement
|
|
10
|
+
};
|
|
11
|
+
this.#options = {
|
|
12
|
+
...defaultOptions,
|
|
13
|
+
...options,
|
|
14
|
+
container: typeof options.container === "string" ? document.querySelector(options.container) ?? defaultOptions.container : options.container ?? defaultOptions.container
|
|
12
15
|
};
|
|
13
|
-
|
|
14
|
-
if (!$
|
|
16
|
+
if (!this.#options.container) throw new Error("Invalid container element");
|
|
17
|
+
if (!$643fcf18b2d2e76f$var$Iconly.#dbInstance) $643fcf18b2d2e76f$var$Iconly.#dbInstance = this.#openDB("iconlyDB", 1);
|
|
15
18
|
}
|
|
16
19
|
async #openDB(name, version) {
|
|
17
20
|
if (!("indexedDB" in window)) {
|
|
18
21
|
this.#logError("This browser doesn't support IndexedDB");
|
|
19
|
-
|
|
22
|
+
throw new Error("IndexedDB not supported");
|
|
20
23
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
request.onsuccess = ()=>resolve(request.result);
|
|
33
|
-
});
|
|
34
|
-
} catch (error) {
|
|
35
|
-
this.#logError(error);
|
|
36
|
-
throw error;
|
|
37
|
-
}
|
|
38
|
-
return db;
|
|
24
|
+
return new Promise((resolve, reject)=>{
|
|
25
|
+
const request = indexedDB.open(name, version);
|
|
26
|
+
request.onerror = ()=>reject(new Error(`IndexedDB error: ${request.error}`));
|
|
27
|
+
request.onupgradeneeded = (event)=>{
|
|
28
|
+
const db = event.target.result;
|
|
29
|
+
if (!db.objectStoreNames.contains("icons")) db.createObjectStore("icons", {
|
|
30
|
+
keyPath: "version"
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
request.onsuccess = ()=>resolve(request.result);
|
|
34
|
+
});
|
|
39
35
|
}
|
|
40
|
-
async #fetchData(file) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return response.text();
|
|
45
|
-
} catch (error) {
|
|
46
|
-
this.#logError(error);
|
|
47
|
-
throw error;
|
|
48
|
-
}
|
|
36
|
+
static async #fetchData(file) {
|
|
37
|
+
const response = await fetch(file);
|
|
38
|
+
if (!response.ok) throw new Error("Network response was not ok");
|
|
39
|
+
return response.text();
|
|
49
40
|
}
|
|
50
|
-
|
|
41
|
+
#insert(data) {
|
|
51
42
|
let iconSetDiv = document.getElementById("iconset");
|
|
52
43
|
if (!iconSetDiv) {
|
|
53
44
|
iconSetDiv = document.createElement("div");
|
|
54
45
|
iconSetDiv.id = "iconset";
|
|
55
46
|
iconSetDiv.setAttribute("aria-hidden", "true");
|
|
56
47
|
iconSetDiv.style.cssText = "width: 0; height: 0; position: absolute; left: -9999px;";
|
|
57
|
-
this.#container.appendChild(iconSetDiv);
|
|
48
|
+
this.#options.container.appendChild(iconSetDiv);
|
|
58
49
|
}
|
|
59
50
|
iconSetDiv.innerHTML = data;
|
|
60
51
|
}
|
|
61
52
|
async init() {
|
|
62
53
|
const { file: file, version: version } = this.#options;
|
|
63
54
|
try {
|
|
64
|
-
let data = await
|
|
65
|
-
const db = await $
|
|
55
|
+
let data = await $643fcf18b2d2e76f$var$Iconly.#fetchData(file);
|
|
56
|
+
const db = await $643fcf18b2d2e76f$var$Iconly.#dbInstance;
|
|
66
57
|
const tx = db.transaction("icons", "readwrite");
|
|
67
58
|
const store = tx.objectStore("icons");
|
|
68
59
|
const dbVersion = await new Promise((resolve, reject)=>{
|
|
@@ -79,18 +70,23 @@ class $cf838c15c8b009ba$var$Iconly {
|
|
|
79
70
|
request.onerror = ()=>reject(request.error);
|
|
80
71
|
});
|
|
81
72
|
else data = dbVersion.data;
|
|
82
|
-
await
|
|
83
|
-
|
|
73
|
+
await new Promise((resolve, reject)=>{
|
|
74
|
+
tx.oncomplete = ()=>resolve();
|
|
75
|
+
tx.onerror = ()=>reject(tx.error);
|
|
76
|
+
tx.onabort = ()=>reject(tx.error);
|
|
77
|
+
});
|
|
78
|
+
this.#insert(data);
|
|
84
79
|
} catch (error) {
|
|
85
80
|
this.#logError("Error initializing Iconly:", error);
|
|
86
81
|
}
|
|
87
82
|
}
|
|
88
83
|
#logError(...messages) {
|
|
89
|
-
if (this.#options.debug) console
|
|
84
|
+
if (this.#options.debug) // eslint-disable-next-line no-console
|
|
85
|
+
console.error(...messages);
|
|
90
86
|
}
|
|
91
87
|
}
|
|
92
|
-
var $
|
|
88
|
+
var $643fcf18b2d2e76f$export$2e2bcd8739ae039 = $643fcf18b2d2e76f$var$Iconly;
|
|
93
89
|
|
|
94
90
|
|
|
95
|
-
export {$
|
|
91
|
+
export {$643fcf18b2d2e76f$export$2e2bcd8739ae039 as default};
|
|
96
92
|
//# sourceMappingURL=index.module.js.map
|
package/dist/index.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAAA,MAAM;
|
|
1
|
+
{"mappings":"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","sources":["src/index.ts"],"sourcesContent":["class Iconly {\n static #dbInstance: Promise<IDBDatabase> | null = null;\n\n #options: {\n file: string;\n version: string;\n debug: boolean;\n container: HTMLElement;\n };\n\n constructor(options: { file?: string; version?: string; debug?: boolean; container?: string | HTMLElement } = {}) {\n const defaultOptions = {\n file: './icons.svg',\n version: '1.0',\n debug: false,\n container: document.body ?? document.documentElement,\n };\n\n this.#options = {\n ...defaultOptions,\n ...options,\n container: typeof options.container === 'string'\n ? document.querySelector(options.container) ?? defaultOptions.container\n : options.container ?? defaultOptions.container,\n };\n\n if (!this.#options.container) {\n throw new Error('Invalid container element');\n }\n\n if (!Iconly.#dbInstance) {\n Iconly.#dbInstance = this.#openDB('iconlyDB', 1);\n }\n }\n\n async #openDB(name: string, version: number): Promise<IDBDatabase> {\n if (!('indexedDB' in window)) {\n this.#logError('This browser doesn\\'t support IndexedDB');\n throw new Error('IndexedDB not supported');\n }\n\n return new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(name, version);\n\n request.onerror = () => reject(new Error(`IndexedDB error: ${request.error}`));\n request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\n const db = (event.target as IDBOpenDBRequest).result;\n if (!db.objectStoreNames.contains('icons')) {\n db.createObjectStore('icons', { keyPath: 'version' });\n }\n };\n request.onsuccess = () => resolve(request.result);\n });\n }\n\n static async #fetchData(file: string): Promise<string> {\n const response = await fetch(file);\n if (!response.ok) throw new Error('Network response was not ok');\n return response.text();\n }\n\n #insert(data: string): void {\n let iconSetDiv = document.getElementById('iconset');\n\n if (!iconSetDiv) {\n iconSetDiv = document.createElement('div');\n iconSetDiv.id = 'iconset';\n iconSetDiv.setAttribute('aria-hidden', 'true');\n iconSetDiv.style.cssText = 'width: 0; height: 0; position: absolute; left: -9999px;';\n this.#options.container.appendChild(iconSetDiv);\n }\n\n iconSetDiv.innerHTML = data;\n }\n\n async init(): Promise<void> {\n const { file, version } = this.#options;\n\n try {\n let data = await Iconly.#fetchData(file);\n\n const db = await Iconly.#dbInstance;\n const tx = db.transaction('icons', 'readwrite');\n const store = tx.objectStore('icons');\n\n const dbVersion = await new Promise<{ version: string; data: string } | undefined>((resolve, reject) => {\n const request = store.get(version);\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n\n if (!(dbVersion && dbVersion.data)) {\n await new Promise<void>((resolve, reject) => {\n const request = store.put({ version, data });\n\n request.onsuccess = () => resolve();\n request.onerror = () => reject(request.error);\n });\n } else {\n data = dbVersion.data;\n }\n\n await new Promise<void>((resolve, reject) => {\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n tx.onabort = () => reject(tx.error);\n });\n\n this.#insert(data);\n } catch (error) {\n this.#logError('Error initializing Iconly:', error);\n }\n }\n\n #logError(...messages: unknown[]): void {\n if (this.#options.debug) {\n // eslint-disable-next-line no-console\n console.error(...messages);\n }\n }\n}\n\nexport default Iconly;\n"],"names":[],"version":3,"file":"index.module.js.map"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iconly",
|
|
3
|
-
"version": "1.4.
|
|
4
|
-
"description": "SVG
|
|
3
|
+
"version": "1.4.4",
|
|
4
|
+
"description": "Iconly is designed to load and cache SVG icons in the browser, using IndexedDB to store the data. It retrieves the icons from a given SVG file, stores them in IndexedDB, and inserts them into the DOM for easy access and use.",
|
|
5
5
|
"author": "ux-ui.pro",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -11,32 +11,48 @@
|
|
|
11
11
|
"bugs": {
|
|
12
12
|
"url": "https://github.com/ux-ui-pro/iconly/issues"
|
|
13
13
|
},
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"targets": {
|
|
17
|
-
"main": {
|
|
18
|
-
"source": "src/index.js"
|
|
19
|
-
},
|
|
20
|
-
"module": {
|
|
21
|
-
"source": "src/index.js"
|
|
22
|
-
}
|
|
23
|
-
},
|
|
14
|
+
"homepage": "https://github.com/ux-ui-pro/iconly",
|
|
15
|
+
"sideEffects": false,
|
|
24
16
|
"scripts": {
|
|
25
17
|
"clean": "rm -rf dist .parcel-cache",
|
|
26
18
|
"build": "yarn clean && parcel build",
|
|
27
|
-
"lint:js": "eslint
|
|
19
|
+
"lint:js": "eslint **/*.{ts,js}",
|
|
28
20
|
"lintfix": "yarn lint:js --fix"
|
|
29
21
|
},
|
|
22
|
+
"browserslist": "> 0.5%, last 2 versions, not dead",
|
|
23
|
+
"source": "src/index.ts",
|
|
24
|
+
"main": "dist/index.js",
|
|
25
|
+
"module": "dist/index.module.js",
|
|
26
|
+
"types": "dist/index.d.ts",
|
|
30
27
|
"devDependencies": {
|
|
31
|
-
"
|
|
28
|
+
"@parcel/packager-ts": "2.12.0",
|
|
29
|
+
"@parcel/transformer-typescript-types": "2.12.0",
|
|
30
|
+
"@typescript-eslint/eslint-plugin": "^7.11.0",
|
|
31
|
+
"@typescript-eslint/parser": "^7.11.0",
|
|
32
|
+
"eslint": "^7.32.0 || ^8.57.0",
|
|
32
33
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
33
|
-
"
|
|
34
|
+
"eslint-plugin-import": "^2.29.1",
|
|
35
|
+
"parcel": "^2.12.0",
|
|
36
|
+
"typescript": "^5.4.5"
|
|
34
37
|
},
|
|
35
38
|
"keywords": [
|
|
36
|
-
"svg",
|
|
37
39
|
"icon",
|
|
38
40
|
"icons",
|
|
41
|
+
"svg",
|
|
39
42
|
"sprite",
|
|
40
|
-
"
|
|
43
|
+
"vector",
|
|
44
|
+
"ui",
|
|
45
|
+
"icon-set",
|
|
46
|
+
"svg-icons",
|
|
47
|
+
"IndexedDB",
|
|
48
|
+
"loader",
|
|
49
|
+
"storage",
|
|
50
|
+
"fetch",
|
|
51
|
+
"component",
|
|
52
|
+
"sprites",
|
|
53
|
+
"typescript",
|
|
54
|
+
"utility",
|
|
55
|
+
"javascript",
|
|
56
|
+
"es6"
|
|
41
57
|
]
|
|
42
58
|
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
class Iconly {
|
|
2
|
+
static #dbInstance: Promise<IDBDatabase> | null = null;
|
|
3
|
+
|
|
4
|
+
#options: {
|
|
5
|
+
file: string;
|
|
6
|
+
version: string;
|
|
7
|
+
debug: boolean;
|
|
8
|
+
container: HTMLElement;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
constructor(options: { file?: string; version?: string; debug?: boolean; container?: string | HTMLElement } = {}) {
|
|
12
|
+
const defaultOptions = {
|
|
13
|
+
file: './icons.svg',
|
|
14
|
+
version: '1.0',
|
|
15
|
+
debug: false,
|
|
16
|
+
container: document.body ?? document.documentElement,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
this.#options = {
|
|
20
|
+
...defaultOptions,
|
|
21
|
+
...options,
|
|
22
|
+
container: typeof options.container === 'string'
|
|
23
|
+
? document.querySelector(options.container) ?? defaultOptions.container
|
|
24
|
+
: options.container ?? defaultOptions.container,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
if (!this.#options.container) {
|
|
28
|
+
throw new Error('Invalid container element');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!Iconly.#dbInstance) {
|
|
32
|
+
Iconly.#dbInstance = this.#openDB('iconlyDB', 1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async #openDB(name: string, version: number): Promise<IDBDatabase> {
|
|
37
|
+
if (!('indexedDB' in window)) {
|
|
38
|
+
this.#logError('This browser doesn\'t support IndexedDB');
|
|
39
|
+
throw new Error('IndexedDB not supported');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return new Promise<IDBDatabase>((resolve, reject) => {
|
|
43
|
+
const request = indexedDB.open(name, version);
|
|
44
|
+
|
|
45
|
+
request.onerror = () => reject(new Error(`IndexedDB error: ${request.error}`));
|
|
46
|
+
request.onupgradeneeded = (event: IDBVersionChangeEvent) => {
|
|
47
|
+
const db = (event.target as IDBOpenDBRequest).result;
|
|
48
|
+
if (!db.objectStoreNames.contains('icons')) {
|
|
49
|
+
db.createObjectStore('icons', { keyPath: 'version' });
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
request.onsuccess = () => resolve(request.result);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static async #fetchData(file: string): Promise<string> {
|
|
57
|
+
const response = await fetch(file);
|
|
58
|
+
if (!response.ok) throw new Error('Network response was not ok');
|
|
59
|
+
return response.text();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#insert(data: string): void {
|
|
63
|
+
let iconSetDiv = document.getElementById('iconset');
|
|
64
|
+
|
|
65
|
+
if (!iconSetDiv) {
|
|
66
|
+
iconSetDiv = document.createElement('div');
|
|
67
|
+
iconSetDiv.id = 'iconset';
|
|
68
|
+
iconSetDiv.setAttribute('aria-hidden', 'true');
|
|
69
|
+
iconSetDiv.style.cssText = 'width: 0; height: 0; position: absolute; left: -9999px;';
|
|
70
|
+
this.#options.container.appendChild(iconSetDiv);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
iconSetDiv.innerHTML = data;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async init(): Promise<void> {
|
|
77
|
+
const { file, version } = this.#options;
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
let data = await Iconly.#fetchData(file);
|
|
81
|
+
|
|
82
|
+
const db = await Iconly.#dbInstance;
|
|
83
|
+
const tx = db.transaction('icons', 'readwrite');
|
|
84
|
+
const store = tx.objectStore('icons');
|
|
85
|
+
|
|
86
|
+
const dbVersion = await new Promise<{ version: string; data: string } | undefined>((resolve, reject) => {
|
|
87
|
+
const request = store.get(version);
|
|
88
|
+
|
|
89
|
+
request.onsuccess = () => resolve(request.result);
|
|
90
|
+
request.onerror = () => reject(request.error);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (!(dbVersion && dbVersion.data)) {
|
|
94
|
+
await new Promise<void>((resolve, reject) => {
|
|
95
|
+
const request = store.put({ version, data });
|
|
96
|
+
|
|
97
|
+
request.onsuccess = () => resolve();
|
|
98
|
+
request.onerror = () => reject(request.error);
|
|
99
|
+
});
|
|
100
|
+
} else {
|
|
101
|
+
data = dbVersion.data;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
await new Promise<void>((resolve, reject) => {
|
|
105
|
+
tx.oncomplete = () => resolve();
|
|
106
|
+
tx.onerror = () => reject(tx.error);
|
|
107
|
+
tx.onabort = () => reject(tx.error);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
this.#insert(data);
|
|
111
|
+
} catch (error) {
|
|
112
|
+
this.#logError('Error initializing Iconly:', error);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
#logError(...messages: unknown[]): void {
|
|
117
|
+
if (this.#options.debug) {
|
|
118
|
+
// eslint-disable-next-line no-console
|
|
119
|
+
console.error(...messages);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export default Iconly;
|
package/tsconfig.json
ADDED
package/src/index.js
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
class Iconly {
|
|
2
|
-
static #dbInstance;
|
|
3
|
-
|
|
4
|
-
#options;
|
|
5
|
-
|
|
6
|
-
#container;
|
|
7
|
-
|
|
8
|
-
constructor(options) {
|
|
9
|
-
this.#options = {
|
|
10
|
-
file: './icons.svg',
|
|
11
|
-
version: '1.0',
|
|
12
|
-
debug: false,
|
|
13
|
-
container: document.body || document.documentElement,
|
|
14
|
-
...options
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
this.#container = typeof this.#options.container === 'string' ? document.querySelector(this.#options.container) : this.#options.container;
|
|
18
|
-
|
|
19
|
-
if (!Iconly.#dbInstance) {
|
|
20
|
-
Iconly.#dbInstance = this.#openDB('iconlyDB', 1);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async #openDB(name, version) {
|
|
25
|
-
if (!('indexedDB' in window)) {
|
|
26
|
-
this.#logError('This browser doesn\'t support IndexedDB');
|
|
27
|
-
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
let db;
|
|
32
|
-
|
|
33
|
-
try {
|
|
34
|
-
db = await new Promise((resolve, reject) => {
|
|
35
|
-
const request = indexedDB.open(name, version);
|
|
36
|
-
|
|
37
|
-
request.onerror = () => reject(`IndexedDB error: ${request.error}`);
|
|
38
|
-
request.onupgradeneeded = (event) => {
|
|
39
|
-
const db = event.target.result;
|
|
40
|
-
if (!db.objectStoreNames.contains('icons')) {
|
|
41
|
-
db.createObjectStore('icons', { keyPath: 'version' });
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
request.onsuccess = () => resolve(request.result);
|
|
45
|
-
});
|
|
46
|
-
} catch (error) {
|
|
47
|
-
this.#logError(error);
|
|
48
|
-
|
|
49
|
-
throw error;
|
|
50
|
-
}
|
|
51
|
-
return db;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async #fetchData(file) {
|
|
55
|
-
try {
|
|
56
|
-
const response = await fetch(file);
|
|
57
|
-
|
|
58
|
-
if (!response.ok) throw new Error('Network response was not ok');
|
|
59
|
-
|
|
60
|
-
return response.text();
|
|
61
|
-
} catch (error) {
|
|
62
|
-
this.#logError(error);
|
|
63
|
-
|
|
64
|
-
throw error;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async #insert(data) {
|
|
69
|
-
let iconSetDiv = document.getElementById('iconset');
|
|
70
|
-
|
|
71
|
-
if (!iconSetDiv) {
|
|
72
|
-
iconSetDiv = document.createElement('div');
|
|
73
|
-
iconSetDiv.id = 'iconset';
|
|
74
|
-
iconSetDiv.setAttribute('aria-hidden', 'true');
|
|
75
|
-
iconSetDiv.style.cssText = 'width: 0; height: 0; position: absolute; left: -9999px;';
|
|
76
|
-
|
|
77
|
-
this.#container.appendChild(iconSetDiv);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
iconSetDiv.innerHTML = data;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async init() {
|
|
84
|
-
const { file, version } = this.#options;
|
|
85
|
-
|
|
86
|
-
try {
|
|
87
|
-
let data = await this.#fetchData(file);
|
|
88
|
-
|
|
89
|
-
const db = await Iconly.#dbInstance;
|
|
90
|
-
const tx = db.transaction('icons', 'readwrite');
|
|
91
|
-
const store = tx.objectStore('icons');
|
|
92
|
-
|
|
93
|
-
const dbVersion = await new Promise((resolve, reject) => {
|
|
94
|
-
const request = store.get(version);
|
|
95
|
-
|
|
96
|
-
request.onsuccess = () => resolve(request.result);
|
|
97
|
-
request.onerror = () => reject(request.error);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
if (!(dbVersion && dbVersion.data)) {
|
|
101
|
-
await new Promise((resolve, reject) => {
|
|
102
|
-
const request = store.put({ version, data });
|
|
103
|
-
|
|
104
|
-
request.onsuccess = () => resolve();
|
|
105
|
-
request.onerror = () => reject(request.error);
|
|
106
|
-
});
|
|
107
|
-
} else {
|
|
108
|
-
data = dbVersion.data;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
await tx.complete;
|
|
112
|
-
await this.#insert(data);
|
|
113
|
-
} catch (error) {
|
|
114
|
-
this.#logError('Error initializing Iconly:', error);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
#logError(...messages) {
|
|
119
|
-
if (this.#options.debug) {
|
|
120
|
-
console.error(...messages);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export default Iconly;
|