{"_id":"@components-1812/svg-isolate","_rev":"6-3ea313fcbb2ea874a73f4d7e2ab24d47","name":"@components-1812/svg-isolate","dist-tags":{"latest":"0.0.2","alpha":"0.0.2-alpha.4"},"versions":{"0.0.1":{"name":"@components-1812/svg-isolate","version":"0.0.1","keywords":["web-components","web-components-library","svg","svg-isolate","custom-svg-isolate"],"author":{"name":"Franco Javier Gadea"},"license":"MIT","_id":"@components-1812/svg-isolate@0.0.1","maintainers":[{"name":"_1812_","email":"francogadea1812@gmail.com"}],"homepage":"https://github.com/FrancoJavierGadea/Components-1812#readme","bugs":{"url":"https://github.com/FrancoJavierGadea/Components-1812/issues"},"dist":{"shasum":"abbb65addd7c2bc3943624cb15046d4f54f2c8c2","tarball":"https://registry.npmjs.org/@components-1812/svg-isolate/-/svg-isolate-0.0.1.tgz","fileCount":6,"integrity":"sha512-LtB7H3Ou1BQynI9E3OvRMnXEm1MUrk6jhM33kG2olb7E1Kp8x2Lbms0iyIRlAeNt4CkIT57l54SQ81W9muiscA==","signatures":[{"sig":"MEQCIB0UkmGZ4OitI7zs2KE0j1QtKPH6rqcnwnDFq1emEpQ0AiB3Z7tDul5336hloMbpW+BTbEEB/m+RpzQoBfJUOhR0dw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":6975},"main":"./src/SVGIsolate.js","type":"module","style":"./src/SVGIsolate.css","exports":{".":"./src/index.js","./index":"./src/index.js","./define":"./src/define.js","./assets/*":"./src/assets/*","./index.js":"./src/index.js","./define.js":"./src/define.js","./SVGIsolate":"./src/SVGIsolate.js","./SVGIsolate.js":"./src/SVGIsolate.js","./SVGIsolate.css":"./src/SVGIsolate.css"},"gitHead":"d1c0dc4e452ad11906a85e7923c3f5454b8c6ec5","_npmUser":{"name":"_1812_","actor":{"name":"_1812_","type":"user","email":"francogadea1812@gmail.com"},"email":"francogadea1812@gmail.com"},"repository":{"url":"git+https://github.com/FrancoJavierGadea/Components-1812.git","type":"git","directory":"src/SVG/SVGIsolate"},"_npmVersion":"11.3.0","description":"Custom SVG Isolate element","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/svg-isolate_0.0.1_1751902155909_0.7904686131093819","host":"s3://npm-registry-packages-npm-production"}},"0.0.2-alpha.1":{"name":"@components-1812/svg-isolate","version":"0.0.2-alpha.1","keywords":["svg","web-component","custom-element","svg-loader","svg-component","svg-isolate","svg-srcset","responsive-svg","lazy-loading","defer-loading","idle-loading","svg-cache","shadow-dom","frontend","ui"],"author":{"name":"Franco Javier Gadea"},"license":"MIT","_id":"@components-1812/svg-isolate@0.0.2-alpha.1","maintainers":[{"name":"_1812_","email":"francogadea1812@gmail.com"}],"homepage":"https://github.com/components-1812/svg-isolate#readme","bugs":{"url":"https://github.com/components-1812/svg-isolate/issues"},"dist":{"shasum":"bce95435f73676beb49434975309e9b9661eb565","tarball":"https://registry.npmjs.org/@components-1812/svg-isolate/-/svg-isolate-0.0.2-alpha.1.tgz","fileCount":9,"integrity":"sha512-2K2NO7qLmrF8kV+EOK8nJcMpeB6P0QZ63FnZko0tS3RKZ68WnuM6b/H/t/PA2SNu25cNIfTtx3sdnDySdIOFaw==","signatures":[{"sig":"MEYCIQCJWW9xIoi1c931j2gj1LLmKLv+XDF+vov5g0a99t51egIhAKBVslb5/04IRV+yH6jZTcGijCTJOEC+MAC5e70yE/z3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88024},"main":"./dist/SVGIsolate.js","type":"module","style":"./dist/SVGIsolate.css","exports":{".":"./dist/index.bundle.js","./dist/*":"./dist/*","./bundle.js":"./dist/index.bundle.js","./SVGIsolate.js":"./dist/SVGIsolate.js","./bundle.min.js":"./dist/index.bundle.min.js","./SVGIsolate.css":"./dist/SVGIsolate.css","./SVGIsolate.min.js":"./dist/SVGIsolate.min.js","./SVGIsolate.min.css":"./dist/SVGIsolate.min.css"},"gitHead":"e5b94449aecb795fd38de6df81feb7be3c011a38","scripts":{"build":"node build.js"},"_npmUser":{"name":"_1812_","email":"francogadea1812@gmail.com"},"repository":{"url":"git+https://github.com/components-1812/svg-isolate.git","type":"git"},"_npmVersion":"11.3.0","description":"Web Component for isolated SVG rendering with ID conflict prevention, responsive srcset, smart caching, and lazy/defer/idle loading strategies.","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"readmeFilename":"readme.md","devDependencies":{"esbuild":"^0.25.9"},"_npmOperationalInternal":{"tmp":"tmp/svg-isolate_0.0.2-alpha.1_1778963544976_0.010474025496686412","host":"s3://npm-registry-packages-npm-production"}},"0.0.2-alpha.2":{"name":"@components-1812/svg-isolate","version":"0.0.2-alpha.2","keywords":["svg","web-component","custom-element","svg-loader","svg-component","svg-isolate","svg-srcset","responsive-svg","lazy-loading","defer-loading","idle-loading","svg-cache","shadow-dom","frontend","ui"],"author":{"name":"Franco Javier Gadea"},"license":"MIT","_id":"@components-1812/svg-isolate@0.0.2-alpha.2","maintainers":[{"name":"_1812_","email":"francogadea1812@gmail.com"}],"homepage":"https://github.com/components-1812/svg-isolate#readme","bugs":{"url":"https://github.com/components-1812/svg-isolate/issues"},"dist":{"shasum":"dd862b256453186bbf8a0a1fd6f2d86db65a29b3","tarball":"https://registry.npmjs.org/@components-1812/svg-isolate/-/svg-isolate-0.0.2-alpha.2.tgz","fileCount":8,"integrity":"sha512-I64sLyjLbVfiPwBXbqoB+yh0RzZHCBm3XrfDoUv1gkjn8nNSKNQzJogs8SL34xikQEkjPKd4moHqVG+2XvYx3w==","signatures":[{"sig":"MEUCIDcLQET/wtsRbxwyd7qN9MzjH4dMGvkSkg4oD/jphEcxAiEA6A8offzngVUOZ1LaSK5v/yxPZndHm5hknIitxlrez8w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86357},"main":"./dist/SVGIsolate.js","type":"module","style":"./dist/SVGIsolate.css","exports":{".":"./dist/index.bundle.js","./dist/*":"./dist/*","./bundle.js":"./dist/index.bundle.js","./SVGIsolate.js":"./dist/SVGIsolate.js","./bundle.min.js":"./dist/index.bundle.min.js","./SVGIsolate.css":"./dist/SVGIsolate.css","./SVGIsolate.min.js":"./dist/SVGIsolate.min.js","./SVGIsolate.min.css":"./dist/SVGIsolate.min.css"},"gitHead":"fc4eb69ad27d048c94308c81cb22cbe50bbd6f71","scripts":{"build":"node build.js"},"_npmUser":{"name":"_1812_","email":"francogadea1812@gmail.com"},"repository":{"url":"git+https://github.com/components-1812/svg-isolate.git","type":"git"},"_npmVersion":"11.3.0","description":"Web Component for isolated SVG rendering with ID conflict prevention, responsive srcset, smart caching, and lazy/defer/idle loading strategies.","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"readmeFilename":"readme.md","devDependencies":{"esbuild":"^0.25.9"},"_npmOperationalInternal":{"tmp":"tmp/svg-isolate_0.0.2-alpha.2_1779038545506_0.787582184256922","host":"s3://npm-registry-packages-npm-production"}},"0.0.2-alpha.3":{"name":"@components-1812/svg-isolate","version":"0.0.2-alpha.3","keywords":["svg","web-component","custom-element","svg-loader","svg-component","svg-isolate","svg-srcset","responsive-svg","lazy-loading","defer-loading","idle-loading","svg-cache","shadow-dom","frontend","ui"],"author":{"name":"Franco Javier Gadea"},"license":"MIT","_id":"@components-1812/svg-isolate@0.0.2-alpha.3","maintainers":[{"name":"_1812_","email":"francogadea1812@gmail.com"}],"homepage":"https://github.com/components-1812/svg-isolate#readme","bugs":{"url":"https://github.com/components-1812/svg-isolate/issues"},"dist":{"shasum":"87063c136b4de6ab07b9da9789dbff4ddbf95e18","tarball":"https://registry.npmjs.org/@components-1812/svg-isolate/-/svg-isolate-0.0.2-alpha.3.tgz","fileCount":8,"integrity":"sha512-OFUYPfHMNUz800ShXeT1nfqX6k+cXANtCsuZk15osO0GFnp9apqYyY8Cpx22Eq8fl1jhLHgtaZcr9QJ5k/+gpg==","signatures":[{"sig":"MEUCIDUlpgWotZHjGzlgxzCUrhxytOyexBULweqJl3EDgVAgAiEAoOFBraMTplU5cm72KJw1PvqyB110fnc0bu/mGQXe7xc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86357},"main":"./dist/SVGIsolate.js","type":"module","style":"./dist/SVGIsolate.css","exports":{".":"./dist/index.bundle.js","./dist/*":"./dist/*","./bundle.js":"./dist/index.bundle.js","./SVGIsolate.js":"./dist/SVGIsolate.js","./bundle.min.js":"./dist/index.bundle.min.js","./SVGIsolate.css":"./dist/SVGIsolate.css","./SVGIsolate.min.js":"./dist/SVGIsolate.min.js","./SVGIsolate.min.css":"./dist/SVGIsolate.min.css"},"gitHead":"ffcb645edf1ec1b570504cbc5c5a30d7272ef1a3","scripts":{"build":"node build.js"},"_npmUser":{"name":"_1812_","email":"francogadea1812@gmail.com"},"repository":{"url":"git+https://github.com/components-1812/svg-isolate.git","type":"git"},"_npmVersion":"11.3.0","description":"Web Component for isolated SVG rendering with ID conflict prevention, responsive srcset, smart caching, and lazy/defer/idle loading strategies.","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"readmeFilename":"readme.md","devDependencies":{"esbuild":"^0.25.9"},"_npmOperationalInternal":{"tmp":"tmp/svg-isolate_0.0.2-alpha.3_1779039641250_0.6177127768147743","host":"s3://npm-registry-packages-npm-production"}},"0.0.2-alpha.4":{"name":"@components-1812/svg-isolate","version":"0.0.2-alpha.4","keywords":["svg","web-component","custom-element","svg-loader","svg-component","svg-isolate","svg-srcset","responsive-svg","lazy-loading","defer-loading","idle-loading","svg-cache","shadow-dom","frontend","ui"],"author":{"name":"Franco Javier Gadea"},"license":"MIT","_id":"@components-1812/svg-isolate@0.0.2-alpha.4","maintainers":[{"name":"_1812_","email":"francogadea1812@gmail.com"}],"homepage":"https://github.com/components-1812/svg-isolate#readme","bugs":{"url":"https://github.com/components-1812/svg-isolate/issues"},"dist":{"shasum":"8c7dc25c960dd3eb78e2c0bb1f65e8bf0eac4c6f","tarball":"https://registry.npmjs.org/@components-1812/svg-isolate/-/svg-isolate-0.0.2-alpha.4.tgz","fileCount":8,"integrity":"sha512-r5pkMJjTC+9w206kmO/wnaYyXy80ky3to0TxrSf/xOZ9JohcsN7a3+3I/yNHIG+sONmJWg8SdCzVVLDasbXGnw==","signatures":[{"sig":"MEUCIGimTbOXTqPaC9DES+GKiugyFiv/PZtnxOZkP/hKCM90AiEA2RWLYDMQAJL90Nkw6hicOnJ6My4nmoUvZoXFJl+819Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":99975},"main":"./dist/SVGIsolate.js","type":"module","style":"./dist/SVGIsolate.css","exports":{".":"./dist/index.bundle.js","./dist/*":"./dist/*","./bundle.js":"./dist/index.bundle.js","./SVGIsolate.js":"./dist/SVGIsolate.js","./bundle.min.js":"./dist/index.bundle.min.js","./SVGIsolate.css":"./dist/SVGIsolate.css","./SVGIsolate.min.js":"./dist/SVGIsolate.min.js","./SVGIsolate.min.css":"./dist/SVGIsolate.min.css"},"gitHead":"5224f6c6ca20602662865f5b2387a3ffc94f9df5","scripts":{"build":"node build.js"},"_npmUser":{"name":"_1812_","email":"francogadea1812@gmail.com"},"repository":{"url":"git+https://github.com/components-1812/svg-isolate.git","type":"git"},"_npmVersion":"11.3.0","description":"Web Component for isolated SVG rendering with ID conflict prevention, responsive srcset, smart caching, and lazy/defer/idle loading strategies.","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"readmeFilename":"readme.md","devDependencies":{"esbuild":"^0.28.0"},"_npmOperationalInternal":{"tmp":"tmp/svg-isolate_0.0.2-alpha.4_1779246231957_0.647048740416247","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@components-1812/svg-isolate","description":"Web Component for isolated SVG rendering with ID conflict prevention, responsive srcset, smart caching, and lazy/defer/idle loading strategies.","keywords":["svg","web-component","custom-element","svg-loader","svg-component","svg-isolate","svg-srcset","responsive-svg","lazy-loading","defer-loading","idle-loading","svg-cache","shadow-dom","frontend","ui"],"author":{"name":"Franco Javier Gadea"},"license":"MIT","version":"0.0.2","repository":{"type":"git","url":"git+https://github.com/components-1812/svg-isolate.git"},"type":"module","exports":{".":"./dist/index.bundle.js","./bundle.js":"./dist/index.bundle.js","./bundle.min.js":"./dist/index.bundle.min.js","./SVGIsolate.js":"./dist/SVGIsolate.js","./SVGIsolate.css":"./dist/SVGIsolate.css","./SVGIsolate.min.js":"./dist/SVGIsolate.min.js","./SVGIsolate.min.css":"./dist/SVGIsolate.min.css","./dist/*":"./dist/*"},"main":"./dist/SVGIsolate.js","style":"./dist/SVGIsolate.css","devDependencies":{"esbuild":"^0.28.0"},"scripts":{"build":"node build.js"},"_id":"@components-1812/svg-isolate@0.0.2","gitHead":"7e8a9505554d65350848bf303ebbe0f5b4f244e7","bugs":{"url":"https://github.com/components-1812/svg-isolate/issues"},"homepage":"https://github.com/components-1812/svg-isolate#readme","_nodeVersion":"22.14.0","_npmVersion":"11.3.0","dist":{"integrity":"sha512-EQ/JXCTS/MnrC+hV0z64B9BED2NiH8VhoCJijjqjo8qo7bTqAuzji9+7kcb2+b1dGUtLafW3wZGx6aXISuHliw==","shasum":"59f4a7147f669580848948e3249a519f262b1d9c","tarball":"https://registry.npmjs.org/@components-1812/svg-isolate/-/svg-isolate-0.0.2.tgz","fileCount":8,"unpackedSize":126950,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICjuHwwIkkbe8WmoUsseheW/5VaacD7azun/3bwN/AmQAiBmo4pWX1yb43iI36k1ZXbq/WGxPdKvKERqaHtReeVkKQ=="}]},"_npmUser":{"name":"_1812_","email":"francogadea1812@gmail.com"},"directories":{},"maintainers":[{"name":"_1812_","email":"francogadea1812@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/svg-isolate_0.0.2_1780028832468_0.24115781071286224"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-07T15:29:15.796Z","modified":"2026-05-29T04:27:12.724Z","0.0.1":"2025-07-07T15:29:16.092Z","0.0.2-alpha.1":"2026-05-16T20:32:25.129Z","0.0.2-alpha.2":"2026-05-17T17:22:25.645Z","0.0.2-alpha.3":"2026-05-17T17:40:41.411Z","0.0.2-alpha.4":"2026-05-20T03:03:52.100Z","0.0.2":"2026-05-29T04:27:12.602Z"},"bugs":{"url":"https://github.com/components-1812/svg-isolate/issues"},"author":{"name":"Franco Javier Gadea"},"license":"MIT","homepage":"https://github.com/components-1812/svg-isolate#readme","keywords":["svg","web-component","custom-element","svg-loader","svg-component","svg-isolate","svg-srcset","responsive-svg","lazy-loading","defer-loading","idle-loading","svg-cache","shadow-dom","frontend","ui"],"repository":{"type":"git","url":"git+https://github.com/components-1812/svg-isolate.git"},"description":"Web Component for isolated SVG rendering with ID conflict prevention, responsive srcset, smart caching, and lazy/defer/idle loading strategies.","maintainers":[{"name":"_1812_","email":"francogadea1812@gmail.com"}],"readme":"![NPM Version](https://img.shields.io/npm/v/@components-1812/svg-isolate)\r\n[![Custom Elements](https://img.shields.io/badge/custom--elements-standard-orange.svg?style=flat-flat)](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements)\r\n[![gzipped size](https://img.shields.io/bundlephobia/minzip/@components-1812/svg-isolate)](https://bundlephobia.com/package/@components-1812/svg-isolate)\r\n[![GitHub stars](https://img.shields.io/github/stars/components-1812/svg-isolate?style=social)](https://github.com/components-1812/svg-isolate/stargazers)\r\n\r\n\r\n# SVG Isolate Custom Element\r\n\r\n![Id collision example](./assets/id-collision.webp)\r\n\r\n## Features\r\n\r\n- 🔒 **Shadow DOM isolation** — SVG styles and IDs are scoped to the component. No conflicts with the rest of the page.\r\n- 📦 **Smart caching** — LRU in-memory cache with deduplication. Same URL fetched once, shared across all instances. Configurable by item count and byte size limit.\r\n- 🖼️ **srcset support** — serve different SVG files based on the component's rendered width, just like native `<img srcset>`.\r\n- ⚡ **Loading strategies** — `eager`, `defer`, `idle`, and `lazy` (via `IntersectionObserver`).\r\n- 🔗 **Base URL** — resolve src against a configurable base path or CDN URL. Set per-element or globally via defaults.\r\n- 🎨 **Flexible styling** — inject CSS into the shadow DOM globally via `define()` or per-instance via `componentStyles`.\r\n- 🧹 **Optional sanitization** — plug in any sanitizer (e.g. DOMPurify) to clean SVG nodes before rendering.\r\n- 📐 **Responsive** — automatic candidate swapping on resize via `ResizeObserver`.\r\n- 🧩 **Extensible** — designed to be subclassed. Override fetching, sanitization, rendering, or defaults.\r\n\r\n## Examples\r\n\r\n- [**Examples**](https://components-1812.github.io/svg-isolate/)\r\n- [**Codepen Examples**](https://codepen.io/collection/YwZMEz)\r\n\t- [id collision](https://codepen.io/FrancoJavierGadea/pen/zxoPqwK)\r\n\t- [loading strategies](https://codepen.io/FrancoJavierGadea/pen/ogYoxWG)\r\n\t- [base](https://codepen.io/FrancoJavierGadea/pen/VYmrapr)\r\n\t- [cache visualization](https://codepen.io/FrancoJavierGadea/pen/jEVaqBj)\r\n\t- [no cache](https://codepen.io/FrancoJavierGadea/pen/ByQmKRv)\r\n\t- [sanitize](https://codepen.io/FrancoJavierGadea/pen/jEVaqmg)\r\n\t- [state attributes](https://codepen.io/FrancoJavierGadea/pen/dPOZMRZ)\r\n\t- [srcset and responsive](https://codepen.io/FrancoJavierGadea/pen/PwbONjy)\r\n\r\n\r\n## Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#usage)\r\n- [Custom definition](#custom-definition)\r\n- [Instance styles](#instance-styles)\r\n- [Default styles](#default-styles-bundle)\r\n- [`width` and `height`](#width-and-height)\r\n- [Base URL](#base-url)\r\n- [Cache](#cache)\r\n- [Loading Strategies](#loading-strategies)\r\n- [srcset & Responsive](#srcset--responsive)\r\n- [Sanitize](#sanitize)\r\n- [Styling the inner SVG](#styling-the-inner-svg)\r\n- [Attributes](#attributes)\r\n- [Events](#events)\r\n\r\n\r\n<br>\r\n\r\n<!--MARK: Installation -->\r\n\r\n## Installation\r\n\r\n### NPM\r\n\r\n```bash\r\nnpm install @components-1812/svg-isolate\r\n```\r\n\r\n### CDN\r\n\r\n#### Auto-define (recommended)\r\n\r\nLoads the bundle and registers `<svg-isolate>` automatically with default styles included.\r\n\r\n```html\r\n<script type=\"module\">\r\n\timport \"https://cdn.jsdelivr.net/npm/@components-1812/svg-isolate/dist/index.bundle.min.js\";\r\n</script>\r\n```\r\n\r\n#### Manual definition\r\n\r\nUse this if you need a custom tag name or want to provide your own styles.\r\n\r\n```html\r\n<script type=\"module\">\r\n\timport SVGIsolate from \"https://cdn.jsdelivr.net/npm/@components-1812/svg-isolate/dist/SVGIsolate.min.js\";\r\n\r\n\tSVGIsolate.define(\"custom-svg-isolate\", {\r\n\t\tlinks: [\r\n\t\t\t\"https://cdn.jsdelivr.net/npm/@components-1812/svg-isolate/dist/SVGIsolate.min.css\",\r\n\t\t],\r\n\t});\r\n</script>\r\n```\r\n\r\n### Available files\r\n\r\n| File                 | jsdelivr                                                                                  | unpkg                                                                          |\r\n| -------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |\r\n| Bundle (recommended) | [link](https://cdn.jsdelivr.net/npm/@components-1812/svg-isolate/dist/index.bundle.min.js)      | [link](https://unpkg.com/@components-1812/svg-isolate/dist/index.bundle.min.js)      |\r\n| SVGIsolate.js        | [link](https://cdn.jsdelivr.net/npm/@components-1812/svg-isolate/dist/SVGIsolate.min.js)  | [link](https://unpkg.com/@components-1812/svg-isolate/dist/SVGIsolate.min.js)  |\r\n| SVGIsolate.css       | [link](https://cdn.jsdelivr.net/npm/@components-1812/svg-isolate/dist/SVGIsolate.min.css) | [link](https://unpkg.com/@components-1812/svg-isolate/dist/SVGIsolate.min.css) |\r\n\r\n<br>\r\n\r\n<!-- MARK: Usage -->\r\n\r\n## Usage\r\n\r\nImport the component in a client-side script file:\r\n\r\n```js\r\nimport \"@components-1812/svg-isolate\";\r\n```\r\n\r\n> This loads the bundle, auto-defines the custom element as `<svg-isolate>`, and applies the default styles via `adoptedStyleSheets`.\r\n\r\n```html\r\n<!-- inline SVG -->\r\n<svg-isolate>\r\n\t<svg width=\"200\" height=\"200\"><!-- SVG content --></svg>\r\n</svg-isolate>\r\n\r\n<!-- load from file -->\r\n<svg-isolate src=\"path/to/circle.svg\" />\r\n\r\n<svg-isolate src=\"path/to/hexagon.svg\" loading=\"lazy\" />\r\n\r\n<svg-isolate srcset=\"icon-300.svg 300w, icon-600.svg 600w\" />\r\n```\r\n\r\n<br>\r\n\r\n<!--MARK: Custom Definition-->\r\n## Custom definition\r\n\r\nIf you need to register the element under a different tag name or inject custom styles into its shadow DOM, use `SVGIsolate.define()` directly instead of the auto-import.\r\n\r\n#### Via `adoptedStyleSheets`\r\n\r\nBest for programmatically constructed styles or when working with a build system that produces `CSSStyleSheet` objects.\r\n\r\n```js\r\nimport SVGIsolate from \"@components-1812/svg-isolate/SVGIsolate.js\";\r\n\r\nconst sheet = new CSSStyleSheet();\r\nsheet.replaceSync(`:host { display: inline-block; }`);\r\n\r\nSVGIsolate.define(\"custom-svg-isolate\", { adopted: [sheet] });\r\n```\r\n\r\n#### Via raw CSS string\r\n\r\nBest for inlining styles directly without an external file.\r\n\r\n```js\r\nimport SVGIsolate from \"@components-1812/svg-isolate/SVGIsolate.js\";\r\n\r\nSVGIsolate.define(\"custom-svg-isolate\", {\r\n\traw: [`:host { display: inline-block; }`],\r\n});\r\n```\r\n\r\n#### Via external stylesheet\r\n\r\nBest for loading styles from a CSS file at runtime. URLs are resolved against `document.baseURI`, so relative paths are accepted.\r\n\r\n```js\r\nimport SVGIsolate from \"@components-1812/svg-isolate/SVGIsolate.js\";\r\n\r\nSVGIsolate.define(null, { links: [\"/path/to/styles.css\"] });\r\n```\r\n\r\nAll three options can be combined in a single `define()` call:\r\n\r\n```js\r\nSVGIsolate.define(\"custom-svg-isolate\", {\r\n\tadopted: [sheet],\r\n\traw: [\":host { display: block; }\"],\r\n\tlinks: [\"/path/to/styles.css\"],\r\n});\r\n```\r\n\r\nDuplicate entries are ignored automatically — adding the same URL or `CSSStyleSheet` object twice has no effect.\r\n\r\n<!--MARK: Instance styles-->\r\n\r\n## Instance styles\r\n\r\nEvery `<svg-isolate>` element exposes a `componentStyles` property — a `ComponentStyles` instance that controls the styles injected into its shadow DOM. You can add or replace styles on a specific element at any time without affecting other instances.\r\n\r\n### Adding styles\r\n\r\n`componentStyles.add()` accepts the same `{ links, adopted, raw }` shape as `define()`. Chain `.apply()` to re-render the shadow DOM styles immediately.\r\n\r\n```js\r\nconst el = document.querySelector(\"svg-isolate\");\r\n\r\nel.componentStyles\r\n    .add({ raw: [`:host { outline: 2px solid red; }`] })\r\n    .apply();\r\n```\r\n\r\nDuplicate entries are ignored — adding the same URL or raw string twice has no effect.\r\n\r\n### Targeting SVG internals\r\n\r\nCSS injected this way lives inside the shadow root, so it can reach the SVG elements directly:\r\n\r\n```js\r\ndocument.querySelector('svg-isolate[sanitize]')\r\n    .componentStyles\r\n    .add({\r\n        raw: `\r\n            circle { fill: #5f000d; }\r\n            rect   { fill: #070070; }\r\n            text   { fill: #c5b800; font-family: serif; }\r\n        `,\r\n\t})\r\n\t.apply();\r\n```\r\n\r\n### Working with the collections directly\r\n\r\nEach style type is a `StyleCollection` instance and can be manipulated directly before calling `.apply()`:\r\n\r\n```js\r\nconst { raw, links, adopted } = el.componentStyles;\r\n\r\n// check what's already registered\r\nconsole.log(raw.size); // number of raw CSS strings\r\nconsole.log(links.size); // number of external stylesheets\r\n\r\n// check if a specific entry exists\r\nlinks.has(\"https://example.com/theme.css\");\r\n\r\n// iterate over current entries\r\nfor (const url of links) {\r\n\tconsole.log(url);\r\n}\r\n\r\n// remove everything from one collection and replace it\r\nraw.clear();\r\nraw.add([`circle { fill: hotpink; }`]);\r\n\r\nel.componentStyles.apply();\r\n```\r\n\r\n### Adding an external stylesheet to one instance\r\n\r\n```js\r\nel.componentStyles.add({ links: [\"/themes/dark.css\"] }).apply();\r\n```\r\n\r\nThe `ready-links` event fires once the stylesheet has loaded.\r\n\r\n### Replacing all styles\r\n\r\nCall `.clear()` before `.add()` to discard everything and start fresh:\r\n\r\n```js\r\nel.componentStyles\r\n\t.clear()\r\n\t.add({ raw: [`:host { background: #000; }`] })\r\n\t.apply();\r\n```\r\n\r\n> **Note:** `componentStyles` is per-instance. Changes made to one element do not affect other `<svg-isolate>` elements on the page, even if they share the same `src`.\r\n\r\n<br>\r\n\r\n<!--MARK: Default styles -->\r\n## Default styles (bundle)\r\n\r\nWhen loaded via the auto-import bundle, <svg-isolate> ships with these default host styles:\r\n\r\n```css\r\n:host {\r\n\tposition: relative;\r\n\tdisplay: inline-block;\r\n\r\n\tmargin: 0;\r\n\tpadding: 0;\r\n\twidth: 100%;\r\n\theight: 100%;\r\n\r\n\tcontain: size;\r\n\r\n\toverflow: hidden;\r\n}\r\n:host svg {\r\n\tdisplay: block;\r\n\twidth: 100%;\r\n\theight: 100%;\r\n}\r\n```\r\n\r\nFrom: [/src/SVGIsolate.css](/src/SVGIsolate.css)\r\nThe most important of these is `contain: size` — it prevents the component from triggering\r\nlayout recalculations in its parent (particularly relevant inside `flex` and `grid` containers,\r\nwhere an unsized inline element can cause repeated reflows).\r\n\r\nIf you register the component manually via `SVGIsolate.define()`, none of these styles are applied automatically.\r\nYou can inject them (or a modified version) via the `adopted`, `raw`, or `links` options — see [Custom definition](#custom-definition).\r\n\r\nNote that `width: 100%; height: 100%` means the component sizes itself to its container —\r\nif the container has no explicit dimensions, the component collapses to zero.\r\nUse the [`width` and `height` attributes](#width-and-height) or size the container from CSS.\r\n\r\nTo override the defaults on a specific instance without touching others, use `componentStyles` directly:\r\n\r\n```js\r\nel.componentStyles\r\n\t.clear()\r\n\t.add({ raw: [`:host { display: block; width: 300px; height: 300px; }`] })\r\n\t.apply();\r\n```\r\n\r\nSee [Instance styles](#instance-styles) for the full API.\r\n\r\n<br>\r\n\r\n<!--MARK: width and height-->\r\n\r\n## `width` and `height`\r\n\r\nSets `style.width` and `style.height` on the `<svg-isolate>` host element directly.\r\n\r\n```html\r\n<svg-isolate src=\"icon.svg\" width=\"200px\" height=\"200px\" />\r\n<svg-isolate src=\"banner.svg\" width=\"100%\" height=\"4rem\" />\r\n```\r\n\r\n```js\r\nel.width = \"50%\";\r\nel.height = \"120px\";\r\n```\r\n\r\nAccepts any valid CSS length value. Equivalent to setting `style.width` / `style.height` inline — useful when you want to control dimensions declaratively via HTML rather than in your stylesheet.\r\n\r\n<br>\r\n\r\n<!--MARK: Base URL -->\r\n## Base URL\r\n\r\nYou can provide a `base` attribute to resolve the `src` URL against a specific base path rather than the document's base URI.\r\n\r\nThe `base` is always a fixed URL to which the `src` is concatenated. If `base` is relative, it is resolved against `document.baseURI`. Then, if `src` is also relative, its resolved path is appended to the `base`.\r\n\r\nThe resulting URL follows this structure:\r\n\r\n```txt\r\n<base origin>/<base path>/<src path>?<src query>#<src hash>\r\n```\r\n\r\n- The default value of `base` is `\"/\"`.\r\n- If `src` is an absolute URL, `base` is ignored entirely and `src` is used as-is.\r\n- The resolution logic is handled internally by the static method `SVGIsolate.resolveSource(src, base)`\r\n\r\n### Usage\r\n\r\n```html\r\n<svg-isolate src=\"/icons/circle.svg\" base=\"/assets\"></svg-isolate>\r\n<svg-isolate src=\"circle.svg\" base=\"https://cdn.example.com\"></svg-isolate>\r\n```\r\n\r\n```js\r\nel.base = \"/assets\";\r\n```\r\n\r\n### Setting a default base\r\n\r\nTo apply a fixed `base` to all instances of a custom element, set it in `SVGIsolate.defaults.base` before calling `define()`:\r\n\r\n```js\r\nclass BootstrapIcon extends SVGIsolate {\r\n\tstatic defaults = {\r\n\t\t...super.defaults,\r\n\t\tbase: \"https://raw.githubusercontent.com/twbs/icons/refs/heads/main/icons\",\r\n\t};\r\n}\r\n\r\nBootstrapIcon.define(\"bootstrap-icon\", {\r\n\tlinks: [\r\n\t\t\"https://cdn.jsdelivr.net/npm/@components-1812/svg-isolate@0.0.2/dist/SVGIsolate.min.css\",\r\n\t],\r\n});\r\n```\r\n\r\nNow every `<bootstrap-icon>` resolves `src` against that CDN path without needing `base` on each element:\r\n\r\n```html\r\n<bootstrap-icon src=\"circle.svg\"></bootstrap-icon>\r\n<!-- → https://raw.githubusercontent.com/twbs/icons/refs/heads/main/icons/circle.svg -->\r\n```\r\n\r\n### Examples\r\n\r\nHere are a few representative examples of how different inputs are resolved (assuming a document URI of `http://127.0.0.1:3000/docs/examples/base-test/`):\r\n\r\n| `src`                                | `base`                    | Resolved URL                                                                 | Description                                         |\r\n| :----------------------------------- | :------------------------ | :--------------------------------------------------------------------------- | :-------------------------------------------------- |\r\n| `https://raw.example.com/circle.svg` | `/docs`                   | `https://raw.example.com/circle.svg`                                         | Absolute URL `src`, `base` is ignored               |\r\n| `/assets/circle.svg`                 | `/docs`                   | `http://127.0.0.1:3000/docs/assets/circle.svg`                               | Root-relative `src` treated relative to `base` path |\r\n| `../../../assets/circle.svg`         | `/docs`                   | `http://127.0.0.1:3000/docs/assets/circle.svg`                               | Root-relative nested `src` with path `base`         |\r\n| `/0-circle.svg`                      | `https://raw.example.com` | `https://raw.example.com/0-circle.svg`                                       | Root-relative `src` with absolute domain `base`     |\r\n| `circle.svg`                         | `/`                       | `http://127.0.0.1:3000/docs/examples/base-test/circle.svg`                   | Relative `src` with default `base`                  |\r\n| `assets/circle?w=150#svg`            | `/docs`                   | `http://127.0.0.1:3000/docs/docs/examples/base-test/assets/circle?w=150#svg` | With query params and hash                          |\r\n\r\n<br>\r\n\r\n<!--MARK: Cache -->\r\n## Cache\r\n\r\nBy default, `<svg-isolate>` caches every SVG source **in memory** after the first fetch, so subsequent requests for the same URL are served instantly without hitting the network.\r\n\r\n### Disabling per instance\r\n\r\nUse the `no-cache` attribute:\r\n\r\n```html\r\n<svg-isolate src=\"path/to/file.svg\" no-cache />\r\n```\r\n\r\nOr via the `.useCache` property:\r\n\r\n```js\r\nconst svg = document.querySelector(\"svg-isolate\");\r\nsvg.useCache = false;\r\n```\r\n\r\n### Disabling by default\r\n\r\nTo disable caching for all instances:\r\n\r\n```js\r\nSVGIsolate.defaults.useCache = false;\r\n```\r\n\r\n### Disabling cache entirely\r\n\r\nTo disable the cache system completely — no cache is created at `define()` time, `.useCache` always returns `false` and cannot be set to `true`:\r\n\r\n```js\r\nSVGIsolate.CACHE_ENABLED = false;\r\n```\r\n\r\nMust be set **before** calling `SVGIsolate.define()`.\r\n\r\n### Limits & Eviction\r\n\r\nBy default, the cache holds up to `100` entries with no maximum cumulative byte size limit (`Infinity`). When limits are reached, the least recently used entry is evicted before adding the new one (LRU):\r\n\r\n```js\r\n// Evict after 50 items\r\nSVGIsolate.CACHE_MAX_ENTRIES = 50;\r\n\r\n// Evict after 10 Megabytes of accumulated SVG strings\r\nSVGIsolate.CACHE_MAX_SIZE = '10mb'; // Also accepts '500kb', '1.5g', or raw bytes like 5000000\r\n```\r\n\r\nBoth must be set **before** calling `SVGIsolate.define()`.\r\n\r\n> [!NOTE]\r\n> The size values are parsed **case-insensitively** (e.g., `'1mb'` is identical to `'1MB'`) and represent sizes in **bytes** rather than bits (e.g., `'1MB'` or `'1mb'` is parsed as exactly $1,024^2$ bytes, representing 1 Megabyte, not a Megabit).\r\n\r\n### Shared cache\r\n\r\nThe cache is shared across all instances of the same component class. Two `<svg-isolate>` elements pointing to the same `src` will only trigger one fetch — the second reuses the cached result.\r\n\r\n### Accessing the cache directly\r\n\r\n```js\r\nSVGIsolate.CACHE.clear(); // clear all entries\r\nSVGIsolate.CACHE.delete(src); // remove a specific entry\r\nSVGIsolate.CACHE.has(src); // check if a src is cached\r\nSVGIsolate.CACHE.values; // Map with all cached entries\r\n```\r\n\r\n#### Preloading\r\n\r\nYou can manually populate the cache before any component renders:\r\n\r\n```js\r\nawait SVGIsolate.CACHE.fetchSVG(\"/assets/icon.svg\");\r\n```\r\n\r\nThis is useful for preloading critical SVGs during app initialization so the first render is instant.\r\n\r\n<br>\r\n\r\n<!-- MARK: Loading -->\r\n\r\n## Loading Strategies\r\n\r\n`<svg-isolate>` supports four loading strategies controlled by the `loading` attribute.\r\n\r\n### Eager (default)\r\n\r\nFetches the SVG immediately when the element connects to the DOM.\r\n\r\n```html\r\n<svg-isolate src=\"icon.svg\" loading=\"eager\" />\r\n```\r\n\r\n### Defer\r\n\r\nWaits for the `DOMContentLoaded` event before fetching. Useful when the SVG is not critical for the initial render.\r\n\r\n```html\r\n<svg-isolate src=\"icon.svg\" loading=\"defer\" />\r\n```\r\n\r\n### Idle\r\n\r\nFetches during the browser's idle time using `requestIdleCallback`. Falls back to `defer` if the browser does not support it.\r\n\r\n```html\r\n<svg-isolate src=\"icon.svg\" loading=\"idle\" />\r\n```\r\n\r\n> **Note:** `requestIdleCallback` is not supported in Safari stable (May 2026). The component automatically falls back to `defer` in that case.\r\n\r\n### Lazy\r\n\r\nFetches the SVG only when the element enters the viewport, using `IntersectionObserver`. Ideal for SVGs below the fold.\r\n\r\n```html\r\n<svg-isolate src=\"icon.svg\" loading=\"lazy\" />\r\n```\r\n\r\nYou can control when the load is triggered with `lazy-margin` and `lazy-threshold`:\r\n\r\n```html\r\n<svg-isolate\r\n\tsrc=\"icon.svg\"\r\n\tloading=\"lazy\"\r\n\tlazy-margin=\"200px\"\r\n\tlazy-threshold=\"0.5\"\r\n/>\r\n```\r\n\r\n- **`lazy-margin`** — extends the viewport boundary before triggering the load. Accepts any valid CSS margin value (e.g. `200px`, `10%`).\r\n- **`lazy-threshold`** — percentage of the element that must be visible before triggering (0 to 1). Default is `0`.\r\n\r\n### Setting a default strategy\r\n\r\n```js\r\nSVGIsolate.defaults.loading = \"lazy\";\r\n```\r\n\r\n<br>\r\n\r\n<!--MARK: Responsive -->\r\n\r\n## srcset & Responsive\r\n\r\n`<svg-isolate>` supports `srcset` to serve different SVG files depending on the component's rendered **width**, similar to how native `<img srcset>` works.\r\n\r\n### Basic usage\r\n\r\nEach candidate requires a width descriptor (`w`) representing the intrinsic width the SVG was designed for.\r\n\r\nIf no descriptor is provided, the candidate defaults to `0w`.\r\n\r\n```html\r\n<svg-isolate srcset=\"icon-300.svg 300w, icon-600.svg 600w, icon-900.svg 900w\" />\r\n```\r\n\r\n### src and srcset\r\n\r\n`src` and `srcset` are mutually exclusive. If `srcset` is present, `src` is ignored entirely — `srcset` always takes priority.\r\n\r\n```html\r\n<!-- only srcset is used, src is ignored -->\r\n<svg-isolate src=\"icon.svg\" srcset=\"icon-300.svg 300w, icon-600.svg 600w\" />\r\n```\r\n\r\nThis also applies when attributes change dynamically — if `srcset` is set at any point, `src` stops being considered until `srcset` is removed.\r\n\r\n```js\r\nconst el = document.querySelector(\"svg-isolate\");\r\n\r\nel.srcset = \"icon-300.svg 300w, icon-600.svg 600w\"; // src ignored from now on\r\nel.srcset = null; // src is considered again\r\n```\r\n\r\n### Candidate selection algorithm\r\n\r\nThe component measures its own rendered width and picks the smallest candidate whose intrinsic width covers it:\r\n\r\n```\r\ncomponent width: 450px\r\ncandidates: 300w, 600w, 900w\r\n\r\n→ 300w < 450 — does not cover\r\n→ 600w ≥ 450 — covers ✓ → selected\r\n```\r\n\r\nIf the component is wider than all candidates, the **largest** is used as a fallback.\r\n\r\nThe selection runs once on connect, and again on every resize if `responsive` is enabled.\r\n\r\n### Responsive\r\n\r\nBy default the component resolves the candidate once on connect. Add the `responsive` attribute to keep listening for size changes and swap the SVG automatically on resize:\r\n\r\n```html\r\n<svg-isolate\r\n\tsrcset=\"icon-300.svg 300w, icon-600.svg 600w, icon-900.svg 900w\"\r\n\tresponsive\r\n/>\r\n```\r\n\r\nSwaps are debounced to avoid excessive fetches during resize. Previously loaded candidates are served from the in-memory cache instantly.\r\n\r\n### Setting defaults\r\n\r\n```js\r\nSVGIsolate.defaults.responsive = true;\r\n```\r\n\r\n<br>\r\n\r\n<!--MARK: Sanitize -->\r\n\r\n## Sanitize\r\n\r\n> [!WARNING]\r\n> **XSS Risk on Untrusted SVGs:**\r\n> If you are loading SVGs from untrusted user uploads or external user-generated sources, **always enable the `sanitize` attribute** and configure a secure sanitizer like `DOMPurify`.\r\n>\r\n> While static `<script>` tags are blocked by `DOMParser`, **inline event attributes (e.g., `onload`, `onmouseover`, `onclick`) will still execute** inside the Shadow DOM when triggered by interaction or page cycles, opening viable XSS vectors (including dynamic code execution via `import()`).\r\n\r\n`<svg-isolate>` renders SVG files inside a shadow DOM using `DOMParser` and `appendChild`. When rendering raw SVG, the browser enforces the following security and encapsulation behaviors:\r\n\r\n### 1. Static Scripts (`<script>`) — Blocked 🔒\r\n- `<script>` tags are **never executed** — the browser does not evaluate scripts inserted via `DOMParser` + `appendChild`.\r\n\r\n### 2. Inline Event Handlers (`on*` attributes) — Vulnerable ⚠️\r\n- Inline HTML event attributes (such as `onload`, `onmouseover`, `onclick`) **will execute** inside the Shadow DOM when the respective user interaction or lifecycle event triggers them.\r\n- This represents a viable XSS vector, as malicious actors can inject payloads that execute arbitrary JavaScript or even dynamically import external scripts:\r\n  ```html\r\n  <rect onmouseover=\"import('./hack.js').then(mod => mod.hacking())\" ... />\r\n  ```\r\n- To safely purge these attributes, you must use the `sanitize` feature.\r\n\r\n### 3. CSS Encapsulation (`<style>`) — Secure 🔒\r\n- CSS inside `<style>` tags is **fully encapsulated** by the shadow DOM — selectors like `body`, `p`, or `div` cannot escape and affect the rest of the parent page.\r\n\r\n---\r\n\r\n### `SVGIsolate.sanitizer` — static function\r\n\r\nSet a static sanitizer function before any component renders. It receives the raw SVG string and returns the cleaned string. If not set, sanitization is skipped even when the `sanitize` attribute is present.\r\n\r\n```js\r\nimport DOMPurify from \"https://cdn.jsdelivr.net/npm/dompurify@3/dist/purify.es.mjs\";\r\n\r\nSVGIsolate.sanitizer = (raw) => {\r\n\treturn DOMPurify.sanitize(raw, {\r\n\t\tUSE_PROFILES: { svg: true },\r\n\t\tFORBID_TAGS: [\"style\", \"script\"],\r\n\t\tFORBID_ATTR: [\"style\"],\r\n\t});\r\n};\r\n```\r\n\r\nThe sanitizer runs after the fetch and before `renderSVG`, so the cache always stores the raw unsanitized string.\r\n\r\n---\r\n\r\n### `sanitize` — instance attribute and property\r\n\r\nControls whether the sanitizer is applied to a specific instance. Has no effect if `SVGIsolate.sanitizer` is not set.\r\n\r\n```html\r\n<!-- sanitize this instance -->\r\n<svg-isolate src=\"icon.svg\" sanitize />\r\n\r\n<!-- leave this one unsanitized -->\r\n<svg-isolate src=\"icon.svg\" />\r\n```\r\n\r\n```js\r\nel.sanitize = true;\r\nel.sanitize = false;\r\n```\r\n\r\n### Enabling by default\r\n\r\nTo sanitize all instances without adding the attribute to each one:\r\n\r\n```js\r\nSVGIsolate.defaults.sanitize = true;\r\n```\r\n\r\n<br>\r\n\r\n<!-- MARK: Styling the inner SVG -->\r\n\r\n## Styling the inner SVG\r\n\r\nThe SVG rendered inside `<svg-isolate>` lives in a shadow DOM, so external CSS cannot reach it directly. The component provides a few ways to interact with it.\r\n\r\n---\r\n\r\n### `viewBox`\r\n\r\nSets the `viewBox` attribute on the inner `<svg>` element. Useful for cropping or reframing the SVG coordinate system without modifying the source file.\r\n\r\n```html\r\n<svg-isolate src=\"icon.svg\" viewBox=\"0 0 100 100\" />\r\n```\r\n\r\n```js\r\nel.viewBox = \"0 0 50 50\";\r\n```\r\n\r\nChanging this attribute dynamically updates the rendered SVG immediately without triggering a reload.\r\n\r\n---\r\n\r\n### `preserveAspectRatio`\r\n\r\nSets the `preserveAspectRatio` attribute on the inner `<svg>` element. Controls how the SVG scales within its viewport.\r\n\r\n```html\r\n<svg-isolate src=\"icon.svg\" preserveAspectRatio=\"xMidYMid meet\" />\r\n```\r\n\r\n```js\r\nel.preserveAspectRatio = \"xMinYMin slice\";\r\n```\r\n\r\nChanging this attribute dynamically updates the rendered SVG immediately without triggering a reload.\r\n\r\n---\r\n\r\n### `expose-svg`\r\n\r\nAdds a `part` attribute to the inner `<svg>` element, making it accessible via `::part()` from external CSS.\r\n\r\n```html\r\n<!-- expose with default part name \"svg\" -->\r\n<svg-isolate src=\"icon.svg\" expose-svg />\r\n\r\n<!-- expose with a custom part name -->\r\n<svg-isolate src=\"icon.svg\" expose-svg=\"my-icon\" />\r\n```\r\n\r\n```css\r\n/* default name */\r\nsvg-isolate::part(svg) {\r\n\tfill: red;\r\n\ttransform: rotate(45deg);\r\n}\r\n\r\n/* custom name */\r\nsvg-isolate::part(my-icon) {\r\n\tfill: red;\r\n}\r\n```\r\n\r\n> **Note:** `::part()` gives access to the `<svg>` tag itself. Its children (`path`, `circle`, etc.) remain encapsulated and cannot be targeted from outside. Use [CSS custom properties](#css-custom-properties) to style internals.\r\n\r\n#### Enable for all instances\r\n\r\n```js\r\nSVGIsolate.defaults.exposeSVG = true; // exposes with default part name 'svg'\r\nSVGIsolate.defaults.exposeSVG = \"custom-name\"; // exposes with a custom part name\r\n```\r\n\r\n---\r\n\r\n### CSS custom properties\r\n\r\nCSS custom properties penetrate the shadow DOM boundary, making them the most flexible way to style SVG internals.\r\n\r\nDefine the custom property on the component and consume it inside the shadow DOM styles:\r\n\r\n```css\r\nsvg-isolate {\r\n\t--svg-fill: red;\r\n\t--svg-stroke: blue;\r\n}\r\n```\r\n\r\n```js\r\n// when defining the component, inject a style that consumes the custom properties\r\nSVGIsolate.define(\"svg-isolate\", {\r\n\traw: `\r\n        svg * {\r\n            fill: var(--svg-fill, currentColor);\r\n            stroke: var(--svg-stroke, none);\r\n        }\r\n    `,\r\n});\r\n```\r\n\r\nThis approach works for any CSS property regardless of shadow DOM encapsulation.\r\n\r\n<br>\r\n\r\n<!--MARK: Attributes -->\r\n\r\n## Attributes\r\n\r\n### Reactive\r\n\r\n| Attribute             | Description                                                                                         |\r\n| --------------------- | --------------------------------------------------------------------------------------------------- |\r\n| `src`                 | Path to the SVG file. Triggers a reload when changed. Ignored if `srcset` is present                |\r\n| `srcset`              | Comma-separated srcset candidates. Takes priority over `src`. Triggers a reload when changed        |\r\n| `preserveAspectRatio` | Forwarded directly to the inner `<svg>` without triggering a reload                                 |\r\n| `viewBox`             | Forwarded directly to the inner `<svg>` without triggering a reload                                 |\r\n| `width`               | Sets `style.width` on the host element. Accepts any valid CSS length (e.g. `200px`, `50%`, `10rem`) |\r\n| `height`              | Sets `style.height` on the host element. Accepts any valid CSS length                               |\r\n\r\n### Behavioral\r\n\r\n| Attribute        | Default | Description                                                                    |\r\n| ---------------- | ------- | ------------------------------------------------------------------------------ |\r\n| `base`           | `/`     | Base path or URL to prepend to the `src`.                                      |\r\n| `loading`        | `eager` | Loading strategy. One of `eager`, `defer`, `idle`, `lazy`                      |\r\n| `responsive`     | `false` | Enables automatic candidate swapping on resize                                 |\r\n| `no-cache`       | `false` | Disables in-memory caching for this instance                                   |\r\n| `sanitize`       | `false` | Enables sanitization before rendering                                          |\r\n| `lazy-margin`    | `0px`   | Viewport margin before triggering lazy load                                    |\r\n| `lazy-threshold` | `0`     | Visibility ratio before triggering lazy load (0 to 1)                          |\r\n| `expose-svg`     | —       | Exposes the inner `<svg>` via `::part()`. Accepts an optional custom part name |\r\n\r\n### State (read-only)\r\n\r\n| Attribute     | Description                                                                   |\r\n| ------------- | ----------------------------------------------------------------------------- |\r\n| `fetching`    | Present while the SVG is being fetched. Removed once the fetch completes      |\r\n| `ready`       | Present when the SVG has been successfully rendered                           |\r\n| `ready-links` | Present when all external stylesheets have finished loading                   |\r\n\r\nUse these attributes to drive CSS transitions or show loading states while the component initializes.\r\n\r\n```css\r\n/* show a spinner while fetching */\r\nsvg-isolate[fetching] {\r\n\tbackground: url('spinner.svg') center / 24px no-repeat;\r\n}\r\n```\r\n\r\n```css\r\nsvg-isolate {\r\n\topacity: 0;\r\n\ttransition: opacity 0.3s;\r\n}\r\nsvg-isolate[ready] {\r\n\topacity: 1;\r\n}\r\n```\r\n\r\n```css\r\nsvg-isolate:not([ready-links]) {\r\n\topacity: 0;\r\n}\r\nsvg-isolate[ready-links] {\r\n\topacity: 1;\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Events\r\n\r\n| Event         | Description                                                                                                          |\r\n| ------------- | -------------------------------------------------------------------------------------------------------------------- |\r\n| `fetching`    | Fired every time a fetch is about to start — on load, on `src`/`srcset` changes, and on srcset candidate swaps       |\r\n| `ready`       | Fired every time an SVG is successfully rendered — on load, on `src`/`srcset` changes, and on srcset candidate swaps |\r\n| `ready-links` | Fired once when all external stylesheets injected via `links` have finished loading                                  |\r\n\r\n<br>\r\n\r\n### Event detail\r\n\r\n#### `fetching`\r\n\r\n```js\r\nel.addEventListener(\"fetching\", (e) => {\r\n\tconst { src, resolved } = e.detail;\r\n\t// src      — the raw value from the src/srcset attribute\r\n\t// resolved — URL object with the fully resolved href\r\n});\r\n```\r\n\r\n#### `ready`\r\n\r\nNo `detail`. The SVG is already in the shadow root when the event fires.\r\n\r\n```js\r\nel.addEventListener(\"ready\", (e) => {\r\n\tconst svg = e.target.shadowRoot.querySelector(\"svg\");\r\n});\r\n```\r\n\r\n#### `ready-links`\r\n\r\n```js\r\nel.addEventListener(\"ready-links\", (e) => {\r\n\tconst { results } = e.detail;\r\n\t// results — array of settled outcomes, one per <link> injected via `links`\r\n\t// each entry: { link: HTMLLinkElement, href: string, status: \"loaded\" | \"error\" }\r\n});\r\n```\r\n\r\n<br>\r\n\r\n> For full API documentation including properties, methods, return types and parameters, see [docs/api.md](./docs/api.md).\r\n\r\n\r\n<br>\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"readme.md"}