@pure-ds/core 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CSS-INTELLISENSE-LIMITATION.md +98 -0
- package/CSS-INTELLISENSE-QUICK-REF.md +238 -0
- package/INTELLISENSE.md +384 -0
- package/LICENSE +15 -0
- package/custom-elements-manifest.config.js +30 -0
- package/custom-elements.json +2003 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/packages/pds-configurator/src/figma-export.d.ts +13 -0
- package/dist/types/packages/pds-configurator/src/figma-export.d.ts.map +1 -0
- package/dist/types/packages/pds-configurator/src/pds-config-form.d.ts +2 -0
- package/dist/types/packages/pds-configurator/src/pds-config-form.d.ts.map +1 -0
- package/dist/types/packages/pds-configurator/src/pds-configurator.d.ts +2 -0
- package/dist/types/packages/pds-configurator/src/pds-configurator.d.ts.map +1 -0
- package/dist/types/packages/pds-configurator/src/pds-demo.d.ts +2 -0
- package/dist/types/packages/pds-configurator/src/pds-demo.d.ts.map +1 -0
- package/dist/types/pds.config.d.ts +13 -0
- package/dist/types/pds.config.d.ts.map +1 -0
- package/dist/types/pds.d.ts +408 -0
- package/dist/types/public/assets/js/app.d.ts +2 -0
- package/dist/types/public/assets/js/app.d.ts.map +1 -0
- package/dist/types/public/assets/js/pds.d.ts +23 -0
- package/dist/types/public/assets/js/pds.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-calendar.d.ts +23 -0
- package/dist/types/public/assets/pds/components/pds-calendar.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-drawer.d.ts +2 -0
- package/dist/types/public/assets/pds/components/pds-drawer.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-icon.d.ts +53 -0
- package/dist/types/public/assets/pds/components/pds-icon.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-jsonform.d.ts +104 -0
- package/dist/types/public/assets/pds/components/pds-jsonform.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-richtext.d.ts +121 -0
- package/dist/types/public/assets/pds/components/pds-richtext.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-scrollrow.d.ts +61 -0
- package/dist/types/public/assets/pds/components/pds-scrollrow.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-splitpanel.d.ts +1 -0
- package/dist/types/public/assets/pds/components/pds-splitpanel.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-tabstrip.d.ts +39 -0
- package/dist/types/public/assets/pds/components/pds-tabstrip.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-toaster.d.ts +111 -0
- package/dist/types/public/assets/pds/components/pds-toaster.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-upload.d.ts +83 -0
- package/dist/types/public/assets/pds/components/pds-upload.d.ts.map +1 -0
- package/dist/types/src/js/app.d.ts +2 -0
- package/dist/types/src/js/app.d.ts.map +1 -0
- package/dist/types/src/js/common/ask.d.ts +22 -0
- package/dist/types/src/js/common/ask.d.ts.map +1 -0
- package/dist/types/src/js/common/common.d.ts +3 -0
- package/dist/types/src/js/common/common.d.ts.map +1 -0
- package/dist/types/src/js/common/font-loader.d.ts +24 -0
- package/dist/types/src/js/common/font-loader.d.ts.map +1 -0
- package/dist/types/src/js/common/msg.d.ts +3 -0
- package/dist/types/src/js/common/msg.d.ts.map +1 -0
- package/dist/types/src/js/lit.d.ts +25 -0
- package/dist/types/src/js/lit.d.ts.map +1 -0
- package/dist/types/src/js/pds-configurator/figma-export.d.ts +13 -0
- package/dist/types/src/js/pds-configurator/figma-export.d.ts.map +1 -0
- package/dist/types/src/js/pds-configurator/pds-config-form.d.ts +2 -0
- package/dist/types/src/js/pds-configurator/pds-config-form.d.ts.map +1 -0
- package/dist/types/src/js/pds-configurator/pds-configurator.d.ts +2 -0
- package/dist/types/src/js/pds-configurator/pds-configurator.d.ts.map +1 -0
- package/dist/types/src/js/pds-configurator/pds-demo.d.ts +2 -0
- package/dist/types/src/js/pds-configurator/pds-demo.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-config.d.ts +758 -0
- package/dist/types/src/js/pds-core/pds-config.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-enhancer-metadata.d.ts +6 -0
- package/dist/types/src/js/pds-core/pds-enhancer-metadata.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-enhancers.d.ts +14 -0
- package/dist/types/src/js/pds-core/pds-enhancers.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-enums.d.ts +87 -0
- package/dist/types/src/js/pds-core/pds-enums.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-generator.d.ts +741 -0
- package/dist/types/src/js/pds-core/pds-generator.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-ontology.d.ts +48 -0
- package/dist/types/src/js/pds-core/pds-ontology.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-paths.d.ts +37 -0
- package/dist/types/src/js/pds-core/pds-paths.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-query.d.ts +102 -0
- package/dist/types/src/js/pds-core/pds-query.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-registry.d.ts +40 -0
- package/dist/types/src/js/pds-core/pds-registry.d.ts.map +1 -0
- package/dist/types/src/js/pds.d.ts +109 -0
- package/dist/types/src/js/pds.d.ts.map +1 -0
- package/dist/types/src/pds-core/pds-api.d.ts +31 -0
- package/dist/types/src/pds-core/pds-api.d.ts.map +1 -0
- package/package.json +104 -0
- package/packages/pds-cli/README.md +15 -0
- package/packages/pds-cli/bin/generate-css-data.js +565 -0
- package/packages/pds-cli/bin/generate-manifest.js +352 -0
- package/packages/pds-cli/bin/pds-build-icons.js +152 -0
- package/packages/pds-cli/bin/pds-dx.js +114 -0
- package/packages/pds-cli/bin/pds-static.js +556 -0
- package/packages/pds-cli/bin/pds.js +127 -0
- package/packages/pds-cli/bin/postinstall.js +380 -0
- package/packages/pds-cli/bin/sync-assets.js +252 -0
- package/packages/pds-cli/lib/asset-roots.js +47 -0
- package/packages/pds-cli/lib/fs-writer.js +75 -0
- package/pds.css-data.json +5 -0
- package/pds.html-data.json +5 -0
- package/public/assets/js/app.js +5719 -0
- package/public/assets/js/lit.js +131 -0
- package/public/assets/js/pds.js +3423 -0
- package/public/assets/pds/components/pds-calendar.js +837 -0
- package/public/assets/pds/components/pds-drawer.js +857 -0
- package/public/assets/pds/components/pds-icon.js +338 -0
- package/public/assets/pds/components/pds-jsonform.js +1775 -0
- package/public/assets/pds/components/pds-richtext.js +1035 -0
- package/public/assets/pds/components/pds-scrollrow.js +331 -0
- package/public/assets/pds/components/pds-splitpanel.js +401 -0
- package/public/assets/pds/components/pds-tabstrip.js +251 -0
- package/public/assets/pds/components/pds-toaster.js +446 -0
- package/public/assets/pds/components/pds-upload.js +657 -0
- package/public/assets/pds/custom-elements.json +2003 -0
- package/public/assets/pds/icons/pds-icons.svg +498 -0
- package/public/assets/pds/pds-css-complete.json +1861 -0
- package/public/assets/pds/pds.css-data.json +2152 -0
- package/public/assets/pds/vscode-custom-data.json +824 -0
- package/readme.md +1870 -0
- package/src/js/pds-core/pds-config.js +1162 -0
- package/src/js/pds-core/pds-enhancer-metadata.js +75 -0
- package/src/js/pds-core/pds-enhancers.js +357 -0
- package/src/js/pds-core/pds-enums.js +86 -0
- package/src/js/pds-core/pds-generator.js +5317 -0
- package/src/js/pds-core/pds-ontology.js +256 -0
- package/src/js/pds-core/pds-paths.js +109 -0
- package/src/js/pds-core/pds-query.js +571 -0
- package/src/js/pds-core/pds-registry.js +129 -0
- package/src/js/pds-core/pds.d.ts +129 -0
- package/src/js/pds.d.ts +408 -0
- package/src/js/pds.js +1579 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG Icon Web Component
|
|
3
|
+
*
|
|
4
|
+
* @element pds-icon
|
|
5
|
+
*
|
|
6
|
+
* @attr {string} icon - Icon name from the sprite sheet
|
|
7
|
+
* @attr {string|number} size - Icon size in pixels or named size (xs, sm, md, lg, xl, 2xl)
|
|
8
|
+
* @attr {string} color - Icon color (CSS color value, default: currentColor)
|
|
9
|
+
* @attr {string} label - Accessible label for the icon (adds role="img")
|
|
10
|
+
* @attr {string} sprite - Override sprite sheet path
|
|
11
|
+
* @attr {number} rotate - Rotation angle in degrees
|
|
12
|
+
* @attr {boolean} no-sprite - Force fallback icon rendering
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* <pds-icon icon="house"></pds-icon>
|
|
16
|
+
* <pds-icon icon="gear" size="32"></pds-icon>
|
|
17
|
+
* <pds-icon icon="heart" color="red" label="Favorite"></pds-icon>
|
|
18
|
+
* <pds-icon icon="list" size="lg"></pds-icon>
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export class SvgIcon extends HTMLElement {
|
|
22
|
+
static observedAttributes = ['icon', 'size', 'color', 'label', 'rotate'];
|
|
23
|
+
|
|
24
|
+
// Inline fallback icons for critical UI elements (when sprite fails to load)
|
|
25
|
+
static #fallbackIcons = {
|
|
26
|
+
'x': '<path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z" fill="currentColor"/>',
|
|
27
|
+
|
|
28
|
+
'house': '<path d="M218.83,103.77l-80-75.48a1.14,1.14,0,0,1-.11-.11,16,16,0,0,0-21.53,0l-.11.11L37.17,103.77A16,16,0,0,0,32,115.55V208a16,16,0,0,0,16,16H96a16,16,0,0,0,16-16V160h32v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V115.55A16,16,0,0,0,218.83,103.77ZM208,208H160V160a16,16,0,0,0-16-16H112a16,16,0,0,0-16,16v48H48V115.55l.11-.1L128,40l79.9,75.43.11.1Z" fill="currentColor"/>',
|
|
29
|
+
|
|
30
|
+
'list': '<path d="M224,128a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,128ZM40,72H216a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16ZM216,184H40a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16Z" fill="currentColor"/>',
|
|
31
|
+
|
|
32
|
+
'gear': '<path d="M128,80a48,48,0,1,0,48,48A48.05,48.05,0,0,0,128,80Zm0,80a32,32,0,1,1,32-32A32,32,0,0,1,128,160Zm88-29.84q.06-2.16,0-4.32l14.92-18.64a8,8,0,0,0,1.48-7.06,107.21,107.21,0,0,0-10.88-26.25,8,8,0,0,0-6-3.93l-23.72-2.64q-1.48-1.56-3-3L186,40.54a8,8,0,0,0-3.94-6,107.71,107.71,0,0,0-26.25-10.87,8,8,0,0,0-7.06,1.49L130.16,40Q128,40,125.84,40L107.2,25.11a8,8,0,0,0-7.06-1.48A107.6,107.6,0,0,0,73.89,34.51a8,8,0,0,0-3.93,6L67.32,64.27q-1.56,1.49-3,3L40.54,70a8,8,0,0,0-6,3.94,107.71,107.71,0,0,0-10.87,26.25,8,8,0,0,0,1.49,7.06L40,125.84Q40,128,40,130.16L25.11,148.8a8,8,0,0,0-1.48,7.06,107.21,107.21,0,0,0,10.88,26.25,8,8,0,0,0,6,3.93l23.72,2.64q1.49,1.56,3,3L70,215.46a8,8,0,0,0,3.94,6,107.71,107.71,0,0,0,26.25,10.87,8,8,0,0,0,7.06-1.49L125.84,216q2.16.06,4.32,0l18.64,14.92a8,8,0,0,0,7.06,1.48,107.21,107.21,0,0,0,26.25-10.88,8,8,0,0,0,3.93-6l2.64-23.72q1.56-1.48,3-3L215.46,186a8,8,0,0,0,6-3.94,107.71,107.71,0,0,0,10.87-26.25,8,8,0,0,0-1.49-7.06Zm-16.1-6.5a73.93,73.93,0,0,1,0,8.68,8,8,0,0,0,1.74,5.48l14.19,17.73a91.57,91.57,0,0,1-6.23,15L187,173.11a8,8,0,0,0-5.1,2.64,74.11,74.11,0,0,1-6.14,6.14,8,8,0,0,0-2.64,5.1l-2.51,22.58a91.32,91.32,0,0,1-15,6.23l-17.74-14.19a8,8,0,0,0-5-1.75h-.48a73.93,73.93,0,0,1-8.68,0,8,8,0,0,0-5.48,1.74L100.45,215.8a91.57,91.57,0,0,1-15-6.23L82.89,187a8,8,0,0,0-2.64-5.1,74.11,74.11,0,0,1-6.14-6.14,8,8,0,0,0-5.1-2.64L46.43,170.6a91.32,91.32,0,0,1-6.23-15l14.19-17.74a8,8,0,0,0,1.74-5.48,73.93,73.93,0,0,1,0-8.68,8,8,0,0,0-1.74-5.48L40.2,100.45a91.57,91.57,0,0,1,6.23-15L69,82.89a8,8,0,0,0,5.1-2.64,74.11,74.11,0,0,1,6.14-6.14A8,8,0,0,0,82.89,69L85.4,46.43a91.32,91.32,0,0,1,15-6.23l17.74,14.19a8,8,0,0,0,5.48,1.74,73.93,73.93,0,0,1,8.68,0,8,8,0,0,0,5.48-1.74L155.55,40.2a91.57,91.57,0,0,1,15,6.23L173.11,69a8,8,0,0,0,2.64,5.1,74.11,74.11,0,0,1,6.14,6.14,8,8,0,0,0,5.1,2.64l22.58,2.51a91.32,91.32,0,0,1,6.23,15l-14.19,17.74A8,8,0,0,0,199.87,123.66Z" fill="currentColor"/>',
|
|
33
|
+
|
|
34
|
+
'magnifying-glass': '<path d="M229.66,218.34l-50.07-50.06a88.11,88.11,0,1,0-11.31,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z" fill="currentColor"/>',
|
|
35
|
+
|
|
36
|
+
'info': '<path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z" fill="currentColor"/>',
|
|
37
|
+
|
|
38
|
+
'check-circle': '<path d="M173.66,98.34a8,8,0,0,1,0,11.32l-56,56a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35A8,8,0,0,1,173.66,98.34ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z" fill="currentColor"/>',
|
|
39
|
+
|
|
40
|
+
'warning': '<path d="M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM222.93,203.8a8.5,8.5,0,0,1-7.48,4.2H40.55a8.5,8.5,0,0,1-7.48-4.2,7.59,7.59,0,0,1,0-7.72L120.52,44.21a8.75,8.75,0,0,1,15,0l87.45,151.87A7.59,7.59,0,0,1,222.93,203.8ZM120,144V104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,180Z" fill="currentColor"/>',
|
|
41
|
+
|
|
42
|
+
'missing': '<circle cx="128" cy="128" r="96" stroke="currentColor" fill="none" stroke-width="16"/>',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
static spritePromises = new Map();
|
|
46
|
+
static inlineSprites = new Map();
|
|
47
|
+
|
|
48
|
+
static instances = new Set();
|
|
49
|
+
|
|
50
|
+
static #spriteSupport = false;
|
|
51
|
+
|
|
52
|
+
static {
|
|
53
|
+
// Precompute sprite support once during class definition to avoid per-instance work.
|
|
54
|
+
SvgIcon.#spriteSupport = SvgIcon.#detectSpriteSupport();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static #detectSpriteSupport() {
|
|
58
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!document.createElementNS || typeof window.SVGSVGElement === 'undefined') {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const docEl = document.documentElement;
|
|
67
|
+
const hasNoSpriteFlag = Boolean(docEl && docEl.dataset && Object.prototype.hasOwnProperty.call(docEl.dataset, 'pdsNoSprite'));
|
|
68
|
+
const globalDisable = Boolean(
|
|
69
|
+
window.__PDS_DISABLE_SVG_SPRITES === true ||
|
|
70
|
+
window.PDS_DISABLE_SVG_SPRITES === true ||
|
|
71
|
+
hasNoSpriteFlag
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (globalDisable) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
const svgNS = 'http://www.w3.org/2000/svg';
|
|
80
|
+
const xlinkNS = 'http://www.w3.org/1999/xlink';
|
|
81
|
+
|
|
82
|
+
const svg = document.createElementNS(svgNS, 'svg');
|
|
83
|
+
const use = document.createElementNS(svgNS, 'use');
|
|
84
|
+
svg.appendChild(use);
|
|
85
|
+
|
|
86
|
+
use.setAttribute('href', '#__pds_sprite_test__');
|
|
87
|
+
use.setAttributeNS(xlinkNS, 'xlink:href', '#__pds_sprite_test__');
|
|
88
|
+
|
|
89
|
+
const hasUseInterface = typeof window.SVGUseElement !== 'undefined' && use instanceof SVGUseElement;
|
|
90
|
+
const hrefProperty = Boolean(use.href && typeof use.href.baseVal === 'string');
|
|
91
|
+
const hrefAttribute =
|
|
92
|
+
use.getAttribute('href') === '#__pds_sprite_test__' ||
|
|
93
|
+
use.getAttributeNS(xlinkNS, 'href') === '#__pds_sprite_test__' ||
|
|
94
|
+
use.getAttribute('xlink:href') === '#__pds_sprite_test__';
|
|
95
|
+
|
|
96
|
+
return Boolean(hasUseInterface && (hrefProperty || hrefAttribute));
|
|
97
|
+
} catch (error) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
constructor() {
|
|
103
|
+
super();
|
|
104
|
+
this.attachShadow({ mode: 'open' });
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
connectedCallback() {
|
|
108
|
+
SvgIcon.instances.add(this);
|
|
109
|
+
this.render();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
disconnectedCallback() {
|
|
113
|
+
SvgIcon.instances.delete(this);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
117
|
+
if (oldValue !== newValue) {
|
|
118
|
+
this.render();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
render() {
|
|
123
|
+
const icon = this.getAttribute('icon') || 'missing';
|
|
124
|
+
const sizeAttr = this.getAttribute('size') || '24';
|
|
125
|
+
const color = this.getAttribute('color') || 'currentColor';
|
|
126
|
+
const label = this.getAttribute('label');
|
|
127
|
+
const spriteOverride = this.getAttribute('sprite');
|
|
128
|
+
const rotate = this.getAttribute('rotate') || '0';
|
|
129
|
+
|
|
130
|
+
// Parse size - can be number (px) or named size (xs, sm, md, lg, xl, 2xl)
|
|
131
|
+
const namedSizes = {
|
|
132
|
+
'xs': '16',
|
|
133
|
+
'sm': '20',
|
|
134
|
+
'md': '24',
|
|
135
|
+
'lg': '32',
|
|
136
|
+
'xl': '48',
|
|
137
|
+
'2xl': '64',
|
|
138
|
+
};
|
|
139
|
+
const size = namedSizes[sizeAttr] || sizeAttr;
|
|
140
|
+
|
|
141
|
+
// Compute sprite href: prefer relative to this module (../pds-icons.svg), allow override via `sprite` attr
|
|
142
|
+
let spriteHref;
|
|
143
|
+
try {
|
|
144
|
+
const url = new URL('../icons/pds-icons.svg', import.meta.url);
|
|
145
|
+
spriteHref = url.href;
|
|
146
|
+
} catch (e) {
|
|
147
|
+
// Fallback (should rarely happen)
|
|
148
|
+
const origin = typeof window !== 'undefined' && window.location ? window.location.origin : '';
|
|
149
|
+
spriteHref = `${origin}/icons/pds-icons.svg`;
|
|
150
|
+
}
|
|
151
|
+
if (spriteOverride) spriteHref = spriteOverride;
|
|
152
|
+
|
|
153
|
+
// Normalize overrides to absolute URLs when possible
|
|
154
|
+
try {
|
|
155
|
+
if (typeof spriteHref === 'string') {
|
|
156
|
+
const normalized = new URL(spriteHref, typeof window !== 'undefined' ? window.location.href : undefined);
|
|
157
|
+
spriteHref = normalized.href;
|
|
158
|
+
}
|
|
159
|
+
} catch (e) {
|
|
160
|
+
// leave spriteHref as-is if URL construction fails
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Determine if we should use sprite or fallback
|
|
164
|
+
let useFallback = this.hasAttribute('no-sprite') || !this.spriteAvailable();
|
|
165
|
+
|
|
166
|
+
let effectiveHref = spriteHref ? `${spriteHref}#${icon}` : `#${icon}`;
|
|
167
|
+
let inlineSymbolContent = null;
|
|
168
|
+
let inlineSymbolViewBox = null;
|
|
169
|
+
let inlineSymbolPreserveAspectRatio = null;
|
|
170
|
+
|
|
171
|
+
if (!useFallback && typeof window !== 'undefined' && spriteHref) {
|
|
172
|
+
try {
|
|
173
|
+
const spriteURL = new URL(spriteHref, window.location.href);
|
|
174
|
+
const sameOrigin = spriteURL.origin === window.location.origin;
|
|
175
|
+
|
|
176
|
+
if (!sameOrigin) {
|
|
177
|
+
const spriteKey = spriteURL.href;
|
|
178
|
+
const inlineSpriteData = SvgIcon.inlineSprites.get(spriteKey);
|
|
179
|
+
|
|
180
|
+
if (inlineSpriteData && inlineSpriteData.loaded) {
|
|
181
|
+
const symbolData = inlineSpriteData.symbols.get(icon);
|
|
182
|
+
if (symbolData) {
|
|
183
|
+
inlineSymbolContent = symbolData.content;
|
|
184
|
+
inlineSymbolViewBox = symbolData.viewBox;
|
|
185
|
+
inlineSymbolPreserveAspectRatio = symbolData.preserveAspectRatio;
|
|
186
|
+
} else {
|
|
187
|
+
useFallback = true;
|
|
188
|
+
}
|
|
189
|
+
} else if (inlineSpriteData && inlineSpriteData.error) {
|
|
190
|
+
useFallback = true;
|
|
191
|
+
} else {
|
|
192
|
+
SvgIcon.ensureInlineSprite(spriteKey);
|
|
193
|
+
useFallback = true;
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
inlineSymbolContent = null;
|
|
197
|
+
}
|
|
198
|
+
} catch (e) {
|
|
199
|
+
// Ignore URL errors and fall back to default behaviour
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Build transform string for rotation
|
|
204
|
+
const transform = rotate !== '0' ? `rotate(${rotate} 128 128)` : '';
|
|
205
|
+
const defaultViewBox = '0 0 256 256';
|
|
206
|
+
const viewBox = inlineSymbolViewBox || defaultViewBox;
|
|
207
|
+
const preserveAspectRatioAttr = inlineSymbolPreserveAspectRatio
|
|
208
|
+
? ` preserveAspectRatio="${inlineSymbolPreserveAspectRatio}"`
|
|
209
|
+
: '';
|
|
210
|
+
const hasInlineSymbol = inlineSymbolContent !== null;
|
|
211
|
+
const symbolMarkup = useFallback
|
|
212
|
+
? this.#getFallbackIcon(icon)
|
|
213
|
+
: (hasInlineSymbol ? inlineSymbolContent : `<use href="${effectiveHref}"></use>`);
|
|
214
|
+
|
|
215
|
+
this.shadowRoot.innerHTML = `
|
|
216
|
+
<svg
|
|
217
|
+
width="${size}"
|
|
218
|
+
height="${size}"
|
|
219
|
+
fill="${color}"
|
|
220
|
+
aria-hidden="${!label}"
|
|
221
|
+
${label ? `role="img" aria-label="${label}"` : ''}
|
|
222
|
+
style="display: inline-block; vertical-align: middle; flex-shrink: 0;"
|
|
223
|
+
viewBox="${viewBox}"
|
|
224
|
+
${preserveAspectRatioAttr}
|
|
225
|
+
>
|
|
226
|
+
<g transform="${transform}">
|
|
227
|
+
${symbolMarkup}
|
|
228
|
+
</g>
|
|
229
|
+
</svg>
|
|
230
|
+
`;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
#getFallbackIcon(name) {
|
|
234
|
+
return SvgIcon.#fallbackIcons[name] || SvgIcon.#fallbackIcons['missing'];
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Check if sprite sheet is available
|
|
239
|
+
* @method spriteAvailable
|
|
240
|
+
* @public
|
|
241
|
+
* @returns {boolean} True if sprite sheet should be used
|
|
242
|
+
*/
|
|
243
|
+
spriteAvailable() {
|
|
244
|
+
return SvgIcon.#spriteSupport;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
static async ensureInlineSprite(spriteURL) {
|
|
248
|
+
if (!spriteURL || typeof document === 'undefined') {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const existingInline = SvgIcon.inlineSprites.get(spriteURL);
|
|
253
|
+
if (existingInline) {
|
|
254
|
+
if (existingInline.loaded) {
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
if (existingInline.error) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (SvgIcon.spritePromises.has(spriteURL)) {
|
|
263
|
+
return SvgIcon.spritePromises.get(spriteURL);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const promise = fetch(spriteURL, { mode: 'cors' })
|
|
267
|
+
.then(async (response) => {
|
|
268
|
+
if (!response.ok) {
|
|
269
|
+
throw new Error(`Failed to load sprite: ${response.status} ${response.statusText}`);
|
|
270
|
+
}
|
|
271
|
+
const svgText = await response.text();
|
|
272
|
+
const parser = new DOMParser();
|
|
273
|
+
const doc = parser.parseFromString(svgText, 'image/svg+xml');
|
|
274
|
+
const symbols = doc.querySelectorAll('symbol[id]');
|
|
275
|
+
|
|
276
|
+
if (!symbols.length) {
|
|
277
|
+
throw new Error('Sprite does not contain any <symbol> definitions');
|
|
278
|
+
}
|
|
279
|
+
const serializer = new XMLSerializer();
|
|
280
|
+
const symbolMap = new Map();
|
|
281
|
+
|
|
282
|
+
symbols.forEach((symbol) => {
|
|
283
|
+
const originalId = symbol.getAttribute('id');
|
|
284
|
+
if (!originalId) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const clone = symbol.cloneNode(true);
|
|
289
|
+
clone.removeAttribute('id');
|
|
290
|
+
|
|
291
|
+
const childMarkup = Array.from(clone.childNodes)
|
|
292
|
+
.map((node) => serializer.serializeToString(node))
|
|
293
|
+
.join('');
|
|
294
|
+
|
|
295
|
+
const viewBox = symbol.getAttribute('viewBox');
|
|
296
|
+
const preserveAspectRatio = symbol.getAttribute('preserveAspectRatio');
|
|
297
|
+
|
|
298
|
+
symbolMap.set(originalId, {
|
|
299
|
+
content: childMarkup,
|
|
300
|
+
viewBox,
|
|
301
|
+
preserveAspectRatio,
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
if (!symbolMap.size) {
|
|
306
|
+
throw new Error('Sprite does not contain any <symbol> definitions with valid ids');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
SvgIcon.inlineSprites.set(spriteURL, { loaded: true, error: false, symbols: symbolMap });
|
|
310
|
+
SvgIcon.notifyInstances();
|
|
311
|
+
return true;
|
|
312
|
+
})
|
|
313
|
+
.catch((error) => {
|
|
314
|
+
console.warn('[pds-icon] Unable to inline sprite:', error);
|
|
315
|
+
SvgIcon.inlineSprites.set(spriteURL, { loaded: false, error: true, symbols: new Map() });
|
|
316
|
+
SvgIcon.notifyInstances();
|
|
317
|
+
return false;
|
|
318
|
+
})
|
|
319
|
+
.finally(() => {
|
|
320
|
+
SvgIcon.spritePromises.delete(spriteURL);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
SvgIcon.spritePromises.set(spriteURL, promise);
|
|
324
|
+
return promise;
|
|
325
|
+
}
|
|
326
|
+
static notifyInstances() {
|
|
327
|
+
SvgIcon.instances.forEach((instance) => {
|
|
328
|
+
if (instance && instance.isConnected) {
|
|
329
|
+
instance.render();
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Auto-register the component
|
|
336
|
+
if (!customElements.get('pds-icon')) {
|
|
337
|
+
customElements.define('pds-icon', SvgIcon);
|
|
338
|
+
}
|