@siemens/ix-icons 0.0.0-pr-69-20250205144920 → 0.0.0-v3-preview-20250130095430
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 +17 -46
- package/components/icon.js +252 -0
- package/components/icon.js.map +1 -0
- package/components/index.js +2 -1
- package/components/index.js.map +1 -1
- package/components/ix-icon.js +1 -1
- package/dist/cjs/{icon-319056c0.js → icon-2c9dc943.js} +56 -62
- package/dist/cjs/icon-2c9dc943.js.map +1 -0
- package/dist/cjs/{index-f6043fa9.js → index-ea94711c.js} +70 -178
- package/dist/cjs/index-ea94711c.js.map +1 -0
- package/dist/cjs/index.cjs.js +2 -2
- package/dist/cjs/ix-icon.cjs.entry.js +2 -2
- package/dist/cjs/ix-icons.cjs.js +2 -2
- package/dist/cjs/ix-icons.cjs.js.map +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +2 -2
- package/dist/collection/components/icon/icon.js +19 -31
- package/dist/collection/components/icon/icon.js.map +1 -1
- package/dist/collection/components/icon/icons.js +1258 -0
- package/dist/collection/components/icon/icons.js.map +1 -0
- package/dist/collection/components/icon/resolveIcon.js +43 -26
- package/dist/collection/components/icon/resolveIcon.js.map +1 -1
- package/dist/esm/{icon-fc868c56.js → icon-e3f6595d.js} +56 -62
- package/dist/esm/icon-e3f6595d.js.map +1 -0
- package/dist/esm/{index-051cb4f1.js → index-050dd9d6.js} +70 -178
- package/dist/esm/index-050dd9d6.js.map +1 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/ix-icon.entry.js +2 -2
- package/dist/esm/ix-icons.js +3 -3
- package/dist/esm/ix-icons.js.map +1 -1
- package/dist/esm/loader.js +2 -2
- package/dist/ix-icons/index.esm.js +1 -1
- package/dist/ix-icons/ix-icons.esm.js +1 -1
- package/dist/ix-icons/ix-icons.esm.js.map +1 -1
- package/dist/ix-icons/p-0194ffaa.js +3 -0
- package/dist/ix-icons/p-0194ffaa.js.map +1 -0
- package/dist/ix-icons/p-196f504a.js +2 -0
- package/dist/ix-icons/p-196f504a.js.map +1 -0
- package/dist/ix-icons/p-45457b43.entry.js +2 -0
- package/dist/types/components/icon/icon.d.ts +2 -5
- package/dist/types/components/icon/icons.d.ts +1256 -0
- package/dist/types/components/icon/meta-tag.d.ts +1 -1
- package/dist/types/components/icon/resolveIcon.d.ts +2 -1
- package/dist/types/components.d.ts +2 -8
- package/dist/types/stencil-public-runtime.d.ts +0 -6
- package/icons/package.json +1 -1
- package/package.json +2 -2
- package/components/p-187634d0.js +0 -1363
- package/components/p-187634d0.js.map +0 -1
- package/dist/cjs/icon-319056c0.js.map +0 -1
- package/dist/cjs/index-f6043fa9.js.map +0 -1
- package/dist/collection/components/icon/parser.js +0 -22
- package/dist/collection/components/icon/parser.js.map +0 -1
- package/dist/esm/icon-fc868c56.js.map +0 -1
- package/dist/esm/index-051cb4f1.js.map +0 -1
- package/dist/ix-icons/p-423803cb.js +0 -2
- package/dist/ix-icons/p-423803cb.js.map +0 -1
- package/dist/ix-icons/p-48b5ebf2.js +0 -3
- package/dist/ix-icons/p-48b5ebf2.js.map +0 -1
- package/dist/ix-icons/p-ca4fc358.entry.js +0 -2
- package/dist/sample.json +0 -1259
- package/dist/types/components/icon/parser.d.ts +0 -2
- /package/dist/ix-icons/{p-ca4fc358.entry.js.map → p-45457b43.entry.js.map} +0 -0
package/README.md
CHANGED
|
@@ -12,67 +12,38 @@ SPDX-License-Identifier: MIT
|
|
|
12
12
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
15
|
-
###
|
|
16
|
-
|
|
17
|
-
If you are also using the library [Siemens Industrial Experience](https://github.com/siemens/ix/), no additional project setup will be neccessary. The packages `@siemens/ix-angular`, `@siemens/ix-react` or `@siemens/ix-vue` will take care of setting up the icon library for you.
|
|
18
|
-
|
|
19
|
-
### Without Siemens Industrial Experience design system
|
|
20
|
-
|
|
21
|
-
If you want to use `@siemens/ix-icons` without `@siemens/ix` you need to follow these steps:
|
|
22
|
-
|
|
23
|
-
#### Using CDN
|
|
24
|
-
|
|
25
|
-
Place the following `<script>` near the end of your page, right before the closing </body> tag.
|
|
26
|
-
|
|
27
|
-
```html
|
|
28
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/@siemens/ix-icons@%5E3.0.0/dist/ix-icons/ix-icons.esm.js"></script>
|
|
29
|
-
<script nomodule src="https://cdn.jsdelivr.net/npm/@siemens/ix-icons@%5E3.0.0/dist/ix-icons/ix-icons.js"></script>
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Now you can render icons in you applicaton:
|
|
33
|
-
|
|
34
|
-
```html
|
|
35
|
-
<ix-icon name="star"></ix-icon>
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Using a package manager like `npm`/`pnpm`/`yarn`
|
|
15
|
+
### Installation
|
|
39
16
|
|
|
40
|
-
First install the package `@siemens/ix-icons
|
|
17
|
+
First install the package `@siemens/ix-icons` in your project (e.g. `npm install --save @siemens/ix-icons`).
|
|
41
18
|
|
|
42
19
|
Then load the icon component:
|
|
43
20
|
|
|
44
21
|
```javascript
|
|
45
22
|
import { defineCustomElements } from '@siemens/ix-icons/loader';
|
|
46
23
|
|
|
47
|
-
|
|
48
|
-
defineCustomElements();
|
|
24
|
+
(async () => {
|
|
25
|
+
await defineCustomElements();
|
|
26
|
+
})();
|
|
49
27
|
```
|
|
50
28
|
|
|
51
|
-
###
|
|
52
|
-
|
|
53
|
-
1. **Copy SVG Files:**
|
|
54
|
-
Copy all SVG files located under `node_modules/@siemens/ix-icons/svg` to an asset folder in your project. This allows the `ix-icon` component to fetch the images.
|
|
29
|
+
### Angular / Web Components
|
|
55
30
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
```javascript
|
|
60
|
-
import { addIcons } from '@siemens/ix-icons';
|
|
61
|
-
import { iconStar } from '@siemens/ix-icons/icons';
|
|
31
|
+
```html
|
|
32
|
+
<ix-icon name="rocket"></ix-icon>
|
|
33
|
+
```
|
|
62
34
|
|
|
63
|
-
|
|
64
|
-
```
|
|
35
|
+
### React and Vue
|
|
65
36
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
```
|
|
37
|
+
```tsx
|
|
38
|
+
import { rocket } from '@siemens/ix-icons/icons';
|
|
69
39
|
|
|
70
|
-
|
|
40
|
+
<ix-icon name={rocket}></ix-icon>;
|
|
41
|
+
```
|
|
71
42
|
|
|
72
|
-
### Use
|
|
43
|
+
### Use `ix-icon` component with custom svg's
|
|
73
44
|
|
|
74
45
|
```tsx
|
|
75
|
-
<ix-icon name="/your/asset/path/my-icon.svg"></ix-icon
|
|
46
|
+
<ix-icon name="/your/asset/path/my-icon.svg"></ix-icon>;
|
|
76
47
|
```
|
|
77
48
|
|
|
78
49
|
## Development
|
|
@@ -95,6 +66,6 @@ Contributions, issues and feature requests are welcome!
|
|
|
95
66
|
|
|
96
67
|
## 📝 License
|
|
97
68
|
|
|
98
|
-
Copyright © 2019–
|
|
69
|
+
Copyright © 2019–2023 [Siemens AG](https://www.siemens.com/).
|
|
99
70
|
|
|
100
71
|
This project is MIT licensed.
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { getAssetPath, setAssetPath, proxyCustomElement, HTMLElement, Build, h, Host } from '@stencil/core/internal/client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Provide custom SVG path for icons
|
|
5
|
+
*
|
|
6
|
+
* <meta name="ix-icons:path" content="/build/svg" />
|
|
7
|
+
*/
|
|
8
|
+
function getCustomAssetUrl() {
|
|
9
|
+
const assetPath = document.querySelector("meta[name='ix-icons:path']");
|
|
10
|
+
if (assetPath) {
|
|
11
|
+
const path = assetPath.getAttribute('content');
|
|
12
|
+
return path;
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* SPDX-FileCopyrightText: 2023 Siemens AG
|
|
19
|
+
*
|
|
20
|
+
* SPDX-License-Identifier: MIT
|
|
21
|
+
*
|
|
22
|
+
* This source code is licensed under the MIT license found in the
|
|
23
|
+
* LICENSE file in the root directory of this source tree.
|
|
24
|
+
*/
|
|
25
|
+
let fetchCache;
|
|
26
|
+
const requests = new Map();
|
|
27
|
+
let parser = null;
|
|
28
|
+
const getIconCacheMap = () => {
|
|
29
|
+
if (typeof window === 'undefined') {
|
|
30
|
+
return new Map();
|
|
31
|
+
}
|
|
32
|
+
if (!fetchCache) {
|
|
33
|
+
window.IxIcons = window.IxIcons || {};
|
|
34
|
+
fetchCache = window.IxIcons.map = window.IxIcons.map || new Map();
|
|
35
|
+
}
|
|
36
|
+
return fetchCache;
|
|
37
|
+
};
|
|
38
|
+
const isSvgDataUrl = (url) => {
|
|
39
|
+
if (!url) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
if (typeof url !== 'string') {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return url.startsWith('data:image/svg+xml');
|
|
46
|
+
};
|
|
47
|
+
function parseSVGDataContent(content) {
|
|
48
|
+
if (typeof window['DOMParser'] === 'undefined') {
|
|
49
|
+
console.warn('DOMParser not supported by your browser.');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (parser === null) {
|
|
53
|
+
parser = new window['DOMParser']();
|
|
54
|
+
}
|
|
55
|
+
const svgDocument = parser.parseFromString(content, 'text/html');
|
|
56
|
+
const svgElement = svgDocument.querySelector('svg');
|
|
57
|
+
if (!svgElement) {
|
|
58
|
+
throw Error('No valid svg data provided');
|
|
59
|
+
}
|
|
60
|
+
return svgElement.outerHTML;
|
|
61
|
+
}
|
|
62
|
+
async function fetchSVG(url) {
|
|
63
|
+
const cache = getIconCacheMap();
|
|
64
|
+
if (cache.has(url)) {
|
|
65
|
+
return cache.get(url);
|
|
66
|
+
}
|
|
67
|
+
if (requests.has(url)) {
|
|
68
|
+
return requests.get(url);
|
|
69
|
+
}
|
|
70
|
+
const fetching = fetch(url).then(async (response) => {
|
|
71
|
+
const responseText = await response.text();
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
console.error(responseText);
|
|
74
|
+
throw Error(responseText);
|
|
75
|
+
}
|
|
76
|
+
const svgContent = parseSVGDataContent(responseText);
|
|
77
|
+
cache.set(url, svgContent);
|
|
78
|
+
requests.delete(url);
|
|
79
|
+
return svgContent;
|
|
80
|
+
});
|
|
81
|
+
requests.set(url, fetching);
|
|
82
|
+
return fetching;
|
|
83
|
+
}
|
|
84
|
+
const urlRegex = /^(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:www\.)?(?:\S+\.\S+)(?:\S*)$/i;
|
|
85
|
+
function isValidUrl(url) {
|
|
86
|
+
return urlRegex.test(url);
|
|
87
|
+
}
|
|
88
|
+
function getIconUrl(name) {
|
|
89
|
+
const customAssetUrl = getCustomAssetUrl();
|
|
90
|
+
if (customAssetUrl) {
|
|
91
|
+
return `${customAssetUrl}/${name}.svg`;
|
|
92
|
+
}
|
|
93
|
+
let url = `svg/${name}.svg`;
|
|
94
|
+
try {
|
|
95
|
+
url = getAssetPath(url);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
console.warn(error);
|
|
99
|
+
setAssetPath(`${window.location.origin}/`);
|
|
100
|
+
url = getAssetPath(url);
|
|
101
|
+
}
|
|
102
|
+
return url;
|
|
103
|
+
}
|
|
104
|
+
async function resolveIcon(iconName) {
|
|
105
|
+
if (!iconName) {
|
|
106
|
+
throw Error('No icon name provided');
|
|
107
|
+
}
|
|
108
|
+
if (isSvgDataUrl(iconName)) {
|
|
109
|
+
return parseSVGDataContent(iconName);
|
|
110
|
+
}
|
|
111
|
+
return await loadIcon(iconName);
|
|
112
|
+
}
|
|
113
|
+
async function loadIcon(iconName) {
|
|
114
|
+
const cache = getIconCacheMap();
|
|
115
|
+
if (cache.has(iconName)) {
|
|
116
|
+
return cache.get(iconName);
|
|
117
|
+
}
|
|
118
|
+
if (isValidUrl(iconName)) {
|
|
119
|
+
try {
|
|
120
|
+
return fetchSVG(iconName);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
return fetchSVG(getIconUrl(iconName));
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
throw Error(`Could not resolve ${iconName}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function removePrefix(name, prefix) {
|
|
134
|
+
if (name.startsWith(prefix)) {
|
|
135
|
+
name = name.slice(prefix.length);
|
|
136
|
+
return name.replace(/^(\w)/, (_match, p1) => p1.toLowerCase());
|
|
137
|
+
}
|
|
138
|
+
return name;
|
|
139
|
+
}
|
|
140
|
+
function addIcons(icons) {
|
|
141
|
+
Object.keys(icons).forEach(name => {
|
|
142
|
+
const icon = icons[name];
|
|
143
|
+
name = removePrefix(name, 'icon');
|
|
144
|
+
addIconToCache(name, icon);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function addIconToCache(name, icon) {
|
|
148
|
+
const cache = getIconCacheMap();
|
|
149
|
+
if (cache.has(name)) {
|
|
150
|
+
console.warn(`Icon name '${name}' already in cache. Overwritting with new icon data.`);
|
|
151
|
+
}
|
|
152
|
+
const svg = parseSVGDataContent(icon);
|
|
153
|
+
cache.set(name, svg);
|
|
154
|
+
const toKebabCase = name.replace(/([a-z0-9]|(?=[A-Z]))([A-Z0-9])/g, '$1-$2').toLowerCase();
|
|
155
|
+
if (name != toKebabCase) {
|
|
156
|
+
cache.set(toKebabCase, svg);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const iconCss = ":host{display:inline-flex;height:1.5rem;width:1.5rem;min-height:1.5rem;min-width:1.5rem;color:inherit}:host .svg-container{display:block;position:relative;width:100%;height:100%}:host .svg-container svg{display:block;position:relative;height:100%;width:100%}:host .svg-container svg,:host .svg-container svg[fill],:host .svg-container svg [fill]{fill:currentColor !important}:host(.size-12){height:0.75rem;width:0.75rem;min-height:0.75rem;min-width:0.75rem}:host(.size-16){height:1rem;width:1rem;min-height:1rem;min-width:1rem}:host(.size-32){height:2rem;width:2rem;min-height:2rem;min-width:2rem}";
|
|
161
|
+
const IxIconStyle0 = iconCss;
|
|
162
|
+
|
|
163
|
+
const iconMissingSymbol = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='512' height='512' viewBox='0 0 512 512'><path fill-rule='evenodd' d='M384,0 L384,384 L0,384 L0,0 L384,0 Z M192,207.085 L57.751,341.333 L326.248,341.333 L192,207.085 Z M42.666,57.751 L42.666,326.248 L176.915,192 L42.666,57.751 Z M341.333,57.751 L207.085,192 L341.333,326.248 L341.333,57.751 Z M326.248,42.666 L57.751,42.666 L192,176.915 L326.248,42.666 Z' transform='translate(64 64)'/></svg>";
|
|
164
|
+
const Icon = /*@__PURE__*/ proxyCustomElement(class Icon extends HTMLElement {
|
|
165
|
+
constructor() {
|
|
166
|
+
super();
|
|
167
|
+
this.__registerHost();
|
|
168
|
+
this.__attachShadow();
|
|
169
|
+
this.size = undefined;
|
|
170
|
+
this.color = undefined;
|
|
171
|
+
this.name = undefined;
|
|
172
|
+
this.lazyLoading = false;
|
|
173
|
+
this.svgContent = undefined;
|
|
174
|
+
this.isVisible = false;
|
|
175
|
+
}
|
|
176
|
+
componentWillLoad() {
|
|
177
|
+
this.waitForRendering(() => {
|
|
178
|
+
this.isVisible = true;
|
|
179
|
+
this.loadIconContent();
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
async loadIconContent() {
|
|
183
|
+
try {
|
|
184
|
+
this.svgContent = await resolveIcon(this.name);
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
this.svgContent = parseSVGDataContent(iconMissingSymbol);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
waitForRendering(onRender) {
|
|
191
|
+
if (Build.isBrowser && this.lazyLoading && typeof window !== 'undefined' && window.IntersectionObserver) {
|
|
192
|
+
const observer = new IntersectionObserver(entries => {
|
|
193
|
+
entries.forEach(entry => {
|
|
194
|
+
if (entry.isIntersecting) {
|
|
195
|
+
onRender();
|
|
196
|
+
observer.disconnect();
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}, {
|
|
200
|
+
rootMargin: '25px',
|
|
201
|
+
});
|
|
202
|
+
observer.observe(this.hostElement);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
onRender();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
render() {
|
|
209
|
+
const style = {};
|
|
210
|
+
if (this.color) {
|
|
211
|
+
style['color'] = `var(--theme-${this.color})`;
|
|
212
|
+
}
|
|
213
|
+
return (h(Host, { key: '8dc18bf3b1ab1e2a521bd0fee33fa91b856dc52b', style: style, class: {
|
|
214
|
+
['size-12']: this.size === '12',
|
|
215
|
+
['size-16']: this.size === '16',
|
|
216
|
+
['size-24']: this.size === '24',
|
|
217
|
+
['size-32']: this.size === '32',
|
|
218
|
+
} }, h("div", { key: '48c3e8ae8e0d36be5fa112dbd408756f56c19535', class: 'svg-container', innerHTML: this.svgContent })));
|
|
219
|
+
}
|
|
220
|
+
static get assetsDirs() { return ["svg"]; }
|
|
221
|
+
get hostElement() { return this; }
|
|
222
|
+
static get watchers() { return {
|
|
223
|
+
"name": ["loadIconContent"]
|
|
224
|
+
}; }
|
|
225
|
+
static get style() { return IxIconStyle0; }
|
|
226
|
+
}, [1, "ix-icon", {
|
|
227
|
+
"size": [1],
|
|
228
|
+
"color": [1],
|
|
229
|
+
"name": [1],
|
|
230
|
+
"lazyLoading": [4, "lazy-loading"],
|
|
231
|
+
"svgContent": [32],
|
|
232
|
+
"isVisible": [32]
|
|
233
|
+
}, undefined, {
|
|
234
|
+
"name": ["loadIconContent"]
|
|
235
|
+
}]);
|
|
236
|
+
function defineCustomElement() {
|
|
237
|
+
if (typeof customElements === "undefined") {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const components = ["ix-icon"];
|
|
241
|
+
components.forEach(tagName => { switch (tagName) {
|
|
242
|
+
case "ix-icon":
|
|
243
|
+
if (!customElements.get(tagName)) {
|
|
244
|
+
customElements.define(tagName, Icon);
|
|
245
|
+
}
|
|
246
|
+
break;
|
|
247
|
+
} });
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export { Icon as I, addIcons as a, addIconToCache as b, defineCustomElement as d };
|
|
251
|
+
|
|
252
|
+
//# sourceMappingURL=icon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"file":"icon.js","mappings":"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","names":[],"sources":["src/components/icon/meta-tag.ts","src/components/icon/resolveIcon.ts","src/components/icon/icon.scss?tag=ix-icon&encapsulation=shadow","src/components/icon/icon.tsx"],"sourcesContent":["/**\n * Provide custom SVG path for icons\n *\n * <meta name=\"ix-icons:path\" content=\"/build/svg\" />\n */\nexport function getCustomAssetUrl() {\n const assetPath = document.querySelector(\"meta[name='ix-icons:path']\");\n if (assetPath) {\n const path = assetPath.getAttribute('content');\n return path;\n }\n\n return false;\n}\n","/*\n * SPDX-FileCopyrightText: 2023 Siemens AG\n *\n * SPDX-License-Identifier: MIT\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport { getAssetPath, setAssetPath } from '@stencil/core';\nimport { getCustomAssetUrl } from './meta-tag';\n\ndeclare global {\n interface Window {\n IxIcons: any;\n }\n}\n\nlet fetchCache: Map<string, string>;\nconst requests = new Map<string, Promise<string>>();\nlet parser = null;\n\nexport const getIconCacheMap = (): Map<string, string> => {\n if (typeof window === 'undefined') {\n return new Map();\n }\n\n if (!fetchCache) {\n window.IxIcons = window.IxIcons || {};\n fetchCache = window.IxIcons.map = window.IxIcons.map || new Map();\n }\n\n return fetchCache;\n};\n\nexport const isSvgDataUrl = (url: string) => {\n if (!url) {\n return false;\n }\n\n if (typeof url !== 'string') {\n return false;\n }\n\n return url.startsWith('data:image/svg+xml');\n};\n\nexport function parseSVGDataContent(content: string) {\n if (typeof window['DOMParser'] === 'undefined') {\n console.warn('DOMParser not supported by your browser.');\n return;\n }\n\n if (parser === null) {\n parser = new window['DOMParser']();\n }\n\n const svgDocument = parser.parseFromString(content, 'text/html');\n const svgElement = svgDocument.querySelector('svg') as HTMLElement;\n\n if (!svgElement) {\n throw Error('No valid svg data provided');\n }\n\n return svgElement.outerHTML;\n}\n\nasync function fetchSVG(url: string) {\n const cache = getIconCacheMap();\n\n if (cache.has(url)) {\n return cache.get(url);\n }\n\n if (requests.has(url)) {\n return requests.get(url);\n }\n\n const fetching = fetch(url).then(async response => {\n const responseText = await response.text();\n\n if (!response.ok) {\n console.error(responseText);\n throw Error(responseText);\n }\n\n const svgContent = parseSVGDataContent(responseText);\n cache.set(url, svgContent);\n\n requests.delete(url);\n\n return svgContent;\n });\n\n requests.set(url, fetching);\n return fetching;\n}\n\nconst urlRegex = /^(?:(?:https?|ftp):\\/\\/)?(?:\\S+(?::\\S*)?@)?(?:www\\.)?(?:\\S+\\.\\S+)(?:\\S*)$/i;\n\nfunction isValidUrl(url: string) {\n return urlRegex.test(url);\n}\n\nexport function getIconUrl(name: string) {\n const customAssetUrl = getCustomAssetUrl();\n\n if (customAssetUrl) {\n return `${customAssetUrl}/${name}.svg`;\n }\n\n let url: string = `svg/${name}.svg`;\n\n try {\n url = getAssetPath(url);\n } catch (error) {\n console.warn(error);\n setAssetPath(`${window.location.origin}/`);\n url = getAssetPath(url);\n }\n\n return url;\n}\n\nexport async function resolveIcon(iconName: string) {\n if (!iconName) {\n throw Error('No icon name provided');\n }\n\n if (isSvgDataUrl(iconName)) {\n return parseSVGDataContent(iconName);\n }\n\n return await loadIcon(iconName);\n}\n\nasync function loadIcon(iconName: string) {\n const cache = getIconCacheMap();\n\n if (cache.has(iconName)) {\n return cache.get(iconName);\n }\n\n if (isValidUrl(iconName)) {\n try {\n return fetchSVG(iconName);\n } catch (error) {\n throw error;\n }\n }\n\n try {\n return fetchSVG(getIconUrl(iconName));\n } catch (error) {\n throw Error(`Could not resolve ${iconName}`);\n }\n}\n\nfunction removePrefix(name: string, prefix: string) {\n if (name.startsWith(prefix)) {\n name = name.slice(prefix.length);\n return name.replace(/^(\\w)/, (_match, p1) => p1.toLowerCase());\n }\n\n return name;\n}\n\nexport function addIcons(icons: { [name: string]: any }) {\n Object.keys(icons).forEach(name => {\n const icon = icons[name];\n name = removePrefix(name, 'icon');\n\n addIconToCache(name, icon);\n });\n}\n\nexport function addIconToCache(name: string, icon: string) {\n const cache = getIconCacheMap();\n\n if (cache.has(name)) {\n console.warn(`Icon name '${name}' already in cache. Overwritting with new icon data.`);\n }\n\n const svg = parseSVGDataContent(icon);\n\n cache.set(name, svg);\n\n const toKebabCase = name.replace(/([a-z0-9]|(?=[A-Z]))([A-Z0-9])/g, '$1-$2').toLowerCase();\n\n if (name != toKebabCase) {\n cache.set(toKebabCase, svg);\n }\n}\n","/*\n * SPDX-FileCopyrightText: 2023 Siemens AG\n *\n * SPDX-License-Identifier: MIT\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n@mixin size($size) {\n height: $size;\n width: $size;\n min-height: $size;\n min-width: $size;\n}\n\n:host {\n display: inline-flex;\n @include size(1.5rem);\n color: inherit;\n\n .svg-container {\n display: block;\n position: relative;\n width: 100%;\n height: 100%;\n\n svg {\n display: block;\n position: relative;\n height: 100%;\n width: 100%;\n }\n\n svg,\n svg[fill],\n svg [fill] {\n fill: currentColor !important;\n }\n }\n}\n\n:host(.size-12) {\n @include size(0.75rem);\n}\n\n:host(.size-16) {\n @include size(1rem);\n}\n\n:host(.size-32) {\n @include size(2rem);\n}\n","/*\n * SPDX-FileCopyrightText: 2023 Siemens AG\n *\n * SPDX-License-Identifier: MIT\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport { Component, h, Host, Prop, State, Watch, Element, Build } from '@stencil/core';\nimport { parseSVGDataContent, resolveIcon } from './resolveIcon';\n\nconst iconMissingSymbol =\n \"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='512' height='512' viewBox='0 0 512 512'><path fill-rule='evenodd' d='M384,0 L384,384 L0,384 L0,0 L384,0 Z M192,207.085 L57.751,341.333 L326.248,341.333 L192,207.085 Z M42.666,57.751 L42.666,326.248 L176.915,192 L42.666,57.751 Z M341.333,57.751 L207.085,192 L341.333,326.248 L341.333,57.751 Z M326.248,42.666 L57.751,42.666 L192,176.915 L326.248,42.666 Z' transform='translate(64 64)'/></svg>\";\n\n@Component({\n tag: 'ix-icon',\n styleUrl: 'icon.scss',\n shadow: true,\n assetsDirs: ['svg'],\n})\nexport class Icon {\n @Element() hostElement: HTMLIxIconElement;\n\n /**\n * Size of the icon\n */\n @Prop() size: '12' | '16' | '24' | '32';\n\n /**\n * Color of the icon\n */\n @Prop() color: string;\n\n /**\n * Use one of our defined icon names e.g. `copy`\n *\n * https://ix.siemens.io/docs/icon-library/icons\n *\n * or the import variant\n *\n * ```\n * import { rocket } from '@siemens/ix-icons/icons';\n *\n * <ix-icon name={rocket}></ix-icon>\n * ```\n */\n @Prop() name: string;\n\n @Prop() lazyLoading = false;\n\n @State() svgContent?: string;\n @State() isVisible = false;\n\n componentWillLoad() {\n this.waitForRendering(() => {\n this.isVisible = true;\n this.loadIconContent();\n });\n }\n\n @Watch('name')\n async loadIconContent() {\n try {\n this.svgContent = await resolveIcon(this.name);\n } catch (error) {\n this.svgContent = parseSVGDataContent(iconMissingSymbol);\n }\n }\n\n private waitForRendering(onRender: () => void) {\n if (Build.isBrowser && this.lazyLoading && typeof window !== 'undefined' && (window as any).IntersectionObserver) {\n const observer = new IntersectionObserver(\n entries => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n onRender();\n observer.disconnect();\n }\n });\n },\n {\n rootMargin: '25px',\n },\n );\n\n observer.observe(this.hostElement);\n } else {\n onRender();\n }\n }\n\n render() {\n const style: {\n [key: string]: string;\n } = {};\n\n if (this.color) {\n style['color'] = `var(--theme-${this.color})`;\n }\n\n return (\n <Host\n style={style}\n class={{\n ['size-12']: this.size === '12',\n ['size-16']: this.size === '16',\n ['size-24']: this.size === '24',\n ['size-32']: this.size === '32',\n }}\n >\n <div class={'svg-container'} innerHTML={this.svgContent}></div>\n </Host>\n );\n }\n}\n"],"version":3}
|
package/components/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { getAssetPath, setAssetPath, setNonce, setPlatformOptions } from '@stencil/core/internal/client';
|
|
2
|
+
export { I as Icon, b as addIconToCache, a as addIcons, d as defineCustomElement } from './icon.js';
|
|
2
3
|
|
|
3
4
|
//# sourceMappingURL=index.js.map
|
package/components/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"file":"index.js","mappings":"","names":[],"sources":[],"sourcesContent":[],"version":3}
|
|
1
|
+
{"file":"index.js","mappings":";","names":[],"sources":[],"sourcesContent":[],"version":3}
|
package/components/ix-icon.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const index = require('./index-
|
|
3
|
+
const index = require('./index-ea94711c.js');
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Provide custom SVG path for icons
|
|
@@ -16,28 +16,6 @@ function getCustomAssetUrl() {
|
|
|
16
16
|
return false;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
/*
|
|
20
|
-
* COPYRIGHT (c) Siemens AG 2018-2025 ALL RIGHTS RESERVED.
|
|
21
|
-
*/
|
|
22
|
-
let parser = null;
|
|
23
|
-
const errorSymbol = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='512' height='512' viewBox='0 0 512 512'><path fill-rule='evenodd' d='M384,0 L384,384 L0,384 L0,0 L384,0 Z M192,207.085 L57.751,341.333 L326.248,341.333 L192,207.085 Z M42.666,57.751 L42.666,326.248 L176.915,192 L42.666,57.751 Z M341.333,57.751 L207.085,192 L341.333,326.248 L341.333,57.751 Z M326.248,42.666 L57.751,42.666 L192,176.915 L326.248,42.666 Z' transform='translate(64 64)'/></svg>";
|
|
24
|
-
function parseSVGDataContent(content) {
|
|
25
|
-
if (typeof window['DOMParser'] === 'undefined') {
|
|
26
|
-
console.error('DOMParser not supported by your browser.');
|
|
27
|
-
return '';
|
|
28
|
-
}
|
|
29
|
-
if (parser === null) {
|
|
30
|
-
parser = new window['DOMParser']();
|
|
31
|
-
}
|
|
32
|
-
const svgDocument = parser.parseFromString(content, 'text/html');
|
|
33
|
-
const svgElement = svgDocument.querySelector('svg');
|
|
34
|
-
if (!svgElement) {
|
|
35
|
-
console.error('No valid svg data provided');
|
|
36
|
-
return '';
|
|
37
|
-
}
|
|
38
|
-
return svgElement.outerHTML;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
19
|
/*
|
|
42
20
|
* SPDX-FileCopyrightText: 2023 Siemens AG
|
|
43
21
|
*
|
|
@@ -48,6 +26,7 @@ function parseSVGDataContent(content) {
|
|
|
48
26
|
*/
|
|
49
27
|
let fetchCache;
|
|
50
28
|
const requests = new Map();
|
|
29
|
+
let parser = null;
|
|
51
30
|
const getIconCacheMap = () => {
|
|
52
31
|
if (typeof window === 'undefined') {
|
|
53
32
|
return new Map();
|
|
@@ -67,6 +46,21 @@ const isSvgDataUrl = (url) => {
|
|
|
67
46
|
}
|
|
68
47
|
return url.startsWith('data:image/svg+xml');
|
|
69
48
|
};
|
|
49
|
+
function parseSVGDataContent(content) {
|
|
50
|
+
if (typeof window['DOMParser'] === 'undefined') {
|
|
51
|
+
console.warn('DOMParser not supported by your browser.');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (parser === null) {
|
|
55
|
+
parser = new window['DOMParser']();
|
|
56
|
+
}
|
|
57
|
+
const svgDocument = parser.parseFromString(content, 'text/html');
|
|
58
|
+
const svgElement = svgDocument.querySelector('svg');
|
|
59
|
+
if (!svgElement) {
|
|
60
|
+
throw Error('No valid svg data provided');
|
|
61
|
+
}
|
|
62
|
+
return svgElement.outerHTML;
|
|
63
|
+
}
|
|
70
64
|
async function fetchSVG(url) {
|
|
71
65
|
const cache = getIconCacheMap();
|
|
72
66
|
if (cache.has(url)) {
|
|
@@ -75,27 +69,18 @@ async function fetchSVG(url) {
|
|
|
75
69
|
if (requests.has(url)) {
|
|
76
70
|
return requests.get(url);
|
|
77
71
|
}
|
|
78
|
-
const fetching = fetch(url)
|
|
79
|
-
.then(async (response) => {
|
|
72
|
+
const fetching = fetch(url).then(async (response) => {
|
|
80
73
|
const responseText = await response.text();
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
cache.set(url, svgContent);
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
console.error('Failed to request svg data from', url, 'with status code', response.status);
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
console.error(responseText);
|
|
76
|
+
throw Error(responseText);
|
|
88
77
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
.catch(() => {
|
|
92
|
-
console.error('Failed to fetch svg data:', url);
|
|
93
|
-
cache.set(url, '');
|
|
94
|
-
return '';
|
|
95
|
-
})
|
|
96
|
-
.finally(() => {
|
|
78
|
+
const svgContent = parseSVGDataContent(responseText);
|
|
79
|
+
cache.set(url, svgContent);
|
|
97
80
|
requests.delete(url);
|
|
81
|
+
return svgContent;
|
|
98
82
|
});
|
|
83
|
+
requests.set(url, fetching);
|
|
99
84
|
return fetching;
|
|
100
85
|
}
|
|
101
86
|
const urlRegex = /^(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:www\.)?(?:\S+\.\S+)(?:\S*)$/i;
|
|
@@ -112,19 +97,20 @@ function getIconUrl(name) {
|
|
|
112
97
|
url = index.getAssetPath(url);
|
|
113
98
|
}
|
|
114
99
|
catch (error) {
|
|
115
|
-
console.warn(
|
|
100
|
+
console.warn(error);
|
|
101
|
+
index.setAssetPath(`${window.location.origin}/`);
|
|
102
|
+
url = index.getAssetPath(url);
|
|
116
103
|
}
|
|
117
104
|
return url;
|
|
118
105
|
}
|
|
119
|
-
async function resolveIcon(
|
|
106
|
+
async function resolveIcon(iconName) {
|
|
120
107
|
if (!iconName) {
|
|
121
|
-
|
|
122
|
-
return '';
|
|
108
|
+
throw Error('No icon name provided');
|
|
123
109
|
}
|
|
124
110
|
if (isSvgDataUrl(iconName)) {
|
|
125
111
|
return parseSVGDataContent(iconName);
|
|
126
112
|
}
|
|
127
|
-
return loadIcon(iconName);
|
|
113
|
+
return await loadIcon(iconName);
|
|
128
114
|
}
|
|
129
115
|
async function loadIcon(iconName) {
|
|
130
116
|
const cache = getIconCacheMap();
|
|
@@ -132,9 +118,19 @@ async function loadIcon(iconName) {
|
|
|
132
118
|
return cache.get(iconName);
|
|
133
119
|
}
|
|
134
120
|
if (isValidUrl(iconName)) {
|
|
135
|
-
|
|
121
|
+
try {
|
|
122
|
+
return fetchSVG(iconName);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
return fetchSVG(getIconUrl(iconName));
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
throw Error(`Could not resolve ${iconName}`);
|
|
136
133
|
}
|
|
137
|
-
return fetchSVG(getIconUrl(iconName));
|
|
138
134
|
}
|
|
139
135
|
function removePrefix(name, prefix) {
|
|
140
136
|
if (name.startsWith(prefix)) {
|
|
@@ -166,17 +162,15 @@ function addIconToCache(name, icon) {
|
|
|
166
162
|
const iconCss = ":host{display:inline-flex;height:1.5rem;width:1.5rem;min-height:1.5rem;min-width:1.5rem;color:inherit}:host .svg-container{display:block;position:relative;width:100%;height:100%}:host .svg-container svg{display:block;position:relative;height:100%;width:100%}:host .svg-container svg,:host .svg-container svg[fill],:host .svg-container svg [fill]{fill:currentColor !important}:host(.size-12){height:0.75rem;width:0.75rem;min-height:0.75rem;min-width:0.75rem}:host(.size-16){height:1rem;width:1rem;min-height:1rem;min-width:1rem}:host(.size-32){height:2rem;width:2rem;min-height:2rem;min-width:2rem}";
|
|
167
163
|
const IxIconStyle0 = iconCss;
|
|
168
164
|
|
|
165
|
+
const iconMissingSymbol = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='512' height='512' viewBox='0 0 512 512'><path fill-rule='evenodd' d='M384,0 L384,384 L0,384 L0,0 L384,0 Z M192,207.085 L57.751,341.333 L326.248,341.333 L192,207.085 Z M42.666,57.751 L42.666,326.248 L176.915,192 L42.666,57.751 Z M341.333,57.751 L207.085,192 L341.333,326.248 L341.333,57.751 Z M326.248,42.666 L57.751,42.666 L192,176.915 L326.248,42.666 Z' transform='translate(64 64)'/></svg>";
|
|
169
166
|
const Icon = class {
|
|
170
167
|
constructor(hostRef) {
|
|
171
168
|
index.registerInstance(this, hostRef);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
this.size = '24';
|
|
176
|
-
/**
|
|
177
|
-
* Only fetch and parse svg data when icon is visible
|
|
178
|
-
*/
|
|
169
|
+
this.size = undefined;
|
|
170
|
+
this.color = undefined;
|
|
171
|
+
this.name = undefined;
|
|
179
172
|
this.lazyLoading = false;
|
|
173
|
+
this.svgContent = undefined;
|
|
180
174
|
this.isVisible = false;
|
|
181
175
|
}
|
|
182
176
|
componentWillLoad() {
|
|
@@ -186,12 +180,12 @@ const Icon = class {
|
|
|
186
180
|
});
|
|
187
181
|
}
|
|
188
182
|
async loadIconContent() {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
183
|
+
try {
|
|
184
|
+
this.svgContent = await resolveIcon(this.name);
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
this.svgContent = parseSVGDataContent(iconMissingSymbol);
|
|
193
188
|
}
|
|
194
|
-
this.svgContent = content;
|
|
195
189
|
}
|
|
196
190
|
waitForRendering(onRender) {
|
|
197
191
|
if (this.lazyLoading && typeof window !== 'undefined' && window.IntersectionObserver) {
|
|
@@ -216,12 +210,12 @@ const Icon = class {
|
|
|
216
210
|
if (this.color) {
|
|
217
211
|
style['color'] = `var(--theme-${this.color})`;
|
|
218
212
|
}
|
|
219
|
-
return (index.h(index.Host, { key: '
|
|
213
|
+
return (index.h(index.Host, { key: '8dc18bf3b1ab1e2a521bd0fee33fa91b856dc52b', style: style, class: {
|
|
220
214
|
['size-12']: this.size === '12',
|
|
221
215
|
['size-16']: this.size === '16',
|
|
222
216
|
['size-24']: this.size === '24',
|
|
223
217
|
['size-32']: this.size === '32',
|
|
224
|
-
} }, index.h("div", { key: '
|
|
218
|
+
} }, index.h("div", { key: '48c3e8ae8e0d36be5fa112dbd408756f56c19535', class: 'svg-container', innerHTML: this.svgContent })));
|
|
225
219
|
}
|
|
226
220
|
static get assetsDirs() { return ["svg"]; }
|
|
227
221
|
get hostElement() { return index.getElement(this); }
|
|
@@ -235,4 +229,4 @@ exports.Icon = Icon;
|
|
|
235
229
|
exports.addIconToCache = addIconToCache;
|
|
236
230
|
exports.addIcons = addIcons;
|
|
237
231
|
|
|
238
|
-
//# sourceMappingURL=icon-
|
|
232
|
+
//# sourceMappingURL=icon-2c9dc943.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"file":"icon-2c9dc943.js","mappings":"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","names":["getAssetPath","setAssetPath","h","Host"],"sources":["src/components/icon/meta-tag.ts","src/components/icon/resolveIcon.ts","src/components/icon/icon.scss?tag=ix-icon&encapsulation=shadow","src/components/icon/icon.tsx"],"sourcesContent":["/**\n * Provide custom SVG path for icons\n *\n * <meta name=\"ix-icons:path\" content=\"/build/svg\" />\n */\nexport function getCustomAssetUrl() {\n const assetPath = document.querySelector(\"meta[name='ix-icons:path']\");\n if (assetPath) {\n const path = assetPath.getAttribute('content');\n return path;\n }\n\n return false;\n}\n","/*\n * SPDX-FileCopyrightText: 2023 Siemens AG\n *\n * SPDX-License-Identifier: MIT\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport { getAssetPath, setAssetPath } from '@stencil/core';\nimport { getCustomAssetUrl } from './meta-tag';\n\ndeclare global {\n interface Window {\n IxIcons: any;\n }\n}\n\nlet fetchCache: Map<string, string>;\nconst requests = new Map<string, Promise<string>>();\nlet parser = null;\n\nexport const getIconCacheMap = (): Map<string, string> => {\n if (typeof window === 'undefined') {\n return new Map();\n }\n\n if (!fetchCache) {\n window.IxIcons = window.IxIcons || {};\n fetchCache = window.IxIcons.map = window.IxIcons.map || new Map();\n }\n\n return fetchCache;\n};\n\nexport const isSvgDataUrl = (url: string) => {\n if (!url) {\n return false;\n }\n\n if (typeof url !== 'string') {\n return false;\n }\n\n return url.startsWith('data:image/svg+xml');\n};\n\nexport function parseSVGDataContent(content: string) {\n if (typeof window['DOMParser'] === 'undefined') {\n console.warn('DOMParser not supported by your browser.');\n return;\n }\n\n if (parser === null) {\n parser = new window['DOMParser']();\n }\n\n const svgDocument = parser.parseFromString(content, 'text/html');\n const svgElement = svgDocument.querySelector('svg') as HTMLElement;\n\n if (!svgElement) {\n throw Error('No valid svg data provided');\n }\n\n return svgElement.outerHTML;\n}\n\nasync function fetchSVG(url: string) {\n const cache = getIconCacheMap();\n\n if (cache.has(url)) {\n return cache.get(url);\n }\n\n if (requests.has(url)) {\n return requests.get(url);\n }\n\n const fetching = fetch(url).then(async response => {\n const responseText = await response.text();\n\n if (!response.ok) {\n console.error(responseText);\n throw Error(responseText);\n }\n\n const svgContent = parseSVGDataContent(responseText);\n cache.set(url, svgContent);\n\n requests.delete(url);\n\n return svgContent;\n });\n\n requests.set(url, fetching);\n return fetching;\n}\n\nconst urlRegex = /^(?:(?:https?|ftp):\\/\\/)?(?:\\S+(?::\\S*)?@)?(?:www\\.)?(?:\\S+\\.\\S+)(?:\\S*)$/i;\n\nfunction isValidUrl(url: string) {\n return urlRegex.test(url);\n}\n\nexport function getIconUrl(name: string) {\n const customAssetUrl = getCustomAssetUrl();\n\n if (customAssetUrl) {\n return `${customAssetUrl}/${name}.svg`;\n }\n\n let url: string = `svg/${name}.svg`;\n\n try {\n url = getAssetPath(url);\n } catch (error) {\n console.warn(error);\n setAssetPath(`${window.location.origin}/`);\n url = getAssetPath(url);\n }\n\n return url;\n}\n\nexport async function resolveIcon(iconName: string) {\n if (!iconName) {\n throw Error('No icon name provided');\n }\n\n if (isSvgDataUrl(iconName)) {\n return parseSVGDataContent(iconName);\n }\n\n return await loadIcon(iconName);\n}\n\nasync function loadIcon(iconName: string) {\n const cache = getIconCacheMap();\n\n if (cache.has(iconName)) {\n return cache.get(iconName);\n }\n\n if (isValidUrl(iconName)) {\n try {\n return fetchSVG(iconName);\n } catch (error) {\n throw error;\n }\n }\n\n try {\n return fetchSVG(getIconUrl(iconName));\n } catch (error) {\n throw Error(`Could not resolve ${iconName}`);\n }\n}\n\nfunction removePrefix(name: string, prefix: string) {\n if (name.startsWith(prefix)) {\n name = name.slice(prefix.length);\n return name.replace(/^(\\w)/, (_match, p1) => p1.toLowerCase());\n }\n\n return name;\n}\n\nexport function addIcons(icons: { [name: string]: any }) {\n Object.keys(icons).forEach(name => {\n const icon = icons[name];\n name = removePrefix(name, 'icon');\n\n addIconToCache(name, icon);\n });\n}\n\nexport function addIconToCache(name: string, icon: string) {\n const cache = getIconCacheMap();\n\n if (cache.has(name)) {\n console.warn(`Icon name '${name}' already in cache. Overwritting with new icon data.`);\n }\n\n const svg = parseSVGDataContent(icon);\n\n cache.set(name, svg);\n\n const toKebabCase = name.replace(/([a-z0-9]|(?=[A-Z]))([A-Z0-9])/g, '$1-$2').toLowerCase();\n\n if (name != toKebabCase) {\n cache.set(toKebabCase, svg);\n }\n}\n","/*\n * SPDX-FileCopyrightText: 2023 Siemens AG\n *\n * SPDX-License-Identifier: MIT\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n@mixin size($size) {\n height: $size;\n width: $size;\n min-height: $size;\n min-width: $size;\n}\n\n:host {\n display: inline-flex;\n @include size(1.5rem);\n color: inherit;\n\n .svg-container {\n display: block;\n position: relative;\n width: 100%;\n height: 100%;\n\n svg {\n display: block;\n position: relative;\n height: 100%;\n width: 100%;\n }\n\n svg,\n svg[fill],\n svg [fill] {\n fill: currentColor !important;\n }\n }\n}\n\n:host(.size-12) {\n @include size(0.75rem);\n}\n\n:host(.size-16) {\n @include size(1rem);\n}\n\n:host(.size-32) {\n @include size(2rem);\n}\n","/*\n * SPDX-FileCopyrightText: 2023 Siemens AG\n *\n * SPDX-License-Identifier: MIT\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport { Component, h, Host, Prop, State, Watch, Element, Build } from '@stencil/core';\nimport { parseSVGDataContent, resolveIcon } from './resolveIcon';\n\nconst iconMissingSymbol =\n \"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='512' height='512' viewBox='0 0 512 512'><path fill-rule='evenodd' d='M384,0 L384,384 L0,384 L0,0 L384,0 Z M192,207.085 L57.751,341.333 L326.248,341.333 L192,207.085 Z M42.666,57.751 L42.666,326.248 L176.915,192 L42.666,57.751 Z M341.333,57.751 L207.085,192 L341.333,326.248 L341.333,57.751 Z M326.248,42.666 L57.751,42.666 L192,176.915 L326.248,42.666 Z' transform='translate(64 64)'/></svg>\";\n\n@Component({\n tag: 'ix-icon',\n styleUrl: 'icon.scss',\n shadow: true,\n assetsDirs: ['svg'],\n})\nexport class Icon {\n @Element() hostElement: HTMLIxIconElement;\n\n /**\n * Size of the icon\n */\n @Prop() size: '12' | '16' | '24' | '32';\n\n /**\n * Color of the icon\n */\n @Prop() color: string;\n\n /**\n * Use one of our defined icon names e.g. `copy`\n *\n * https://ix.siemens.io/docs/icon-library/icons\n *\n * or the import variant\n *\n * ```\n * import { rocket } from '@siemens/ix-icons/icons';\n *\n * <ix-icon name={rocket}></ix-icon>\n * ```\n */\n @Prop() name: string;\n\n @Prop() lazyLoading = false;\n\n @State() svgContent?: string;\n @State() isVisible = false;\n\n componentWillLoad() {\n this.waitForRendering(() => {\n this.isVisible = true;\n this.loadIconContent();\n });\n }\n\n @Watch('name')\n async loadIconContent() {\n try {\n this.svgContent = await resolveIcon(this.name);\n } catch (error) {\n this.svgContent = parseSVGDataContent(iconMissingSymbol);\n }\n }\n\n private waitForRendering(onRender: () => void) {\n if (Build.isBrowser && this.lazyLoading && typeof window !== 'undefined' && (window as any).IntersectionObserver) {\n const observer = new IntersectionObserver(\n entries => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n onRender();\n observer.disconnect();\n }\n });\n },\n {\n rootMargin: '25px',\n },\n );\n\n observer.observe(this.hostElement);\n } else {\n onRender();\n }\n }\n\n render() {\n const style: {\n [key: string]: string;\n } = {};\n\n if (this.color) {\n style['color'] = `var(--theme-${this.color})`;\n }\n\n return (\n <Host\n style={style}\n class={{\n ['size-12']: this.size === '12',\n ['size-16']: this.size === '16',\n ['size-24']: this.size === '24',\n ['size-32']: this.size === '32',\n }}\n >\n <div class={'svg-container'} innerHTML={this.svgContent}></div>\n </Host>\n );\n }\n}\n"],"version":3}
|