vite-awesome-svg-loader
Version:
A universal Vite SVG loader. Imports SVGs as source code, base64 and data URI. Preserves stroke width. Replaces colors with currentColor or custom colors. Creates SVG sprites. Optimizes SVGs.
246 lines (245 loc) • 8.58 kB
JavaScript
import { l as v, c as h, u as A, s as g } from "../common-utils/index-YJ0rTXLH.js";
import { N as C, T as E, z as y, A as w } from "../integration-utils/index-Bs_mjsj3.js";
const c = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), _ = class extends HTMLElement {
// Initialization logic
constructor() {
super(), this._state = "uninitialized", this._initialValues = {};
let t = this._getMeta();
t || (this._ctor()._initClass(), t = this._getMeta());
for (const e in t.props) {
if (!Object.hasOwn(this, e))
continue;
const s = this[e];
typeof s == "string" && (this._initialValues[e] = s);
}
queueMicrotask(this._init.bind(this));
}
/**
* Initializes component state.
*
* Custom elements may not add attributes or children in a constructor, so separate initialization is required.
* Thus, this method is called whenever an attribute is accessed or in a microtask after component's constructor
* has run.
*
* Initialization is performed only once.
*/
_init() {
if (this._state !== "uninitialized")
return;
this._state = "initialization";
const { props: t, attrs: e } = this._getMeta();
for (const s in t)
delete this[s], this[s] = this._initialValues[s] ?? super.getAttribute(g(s)) ?? t[s].default;
if (delete this._initialValues, this._state = "attrs-first-change", this.attributeChangedCallback) {
const s = (i) => this.attributeChangedCallback(i, null, this.getAttribute(i));
for (const i in e)
s(i);
for (const { name: i } of this.attributes)
i in e || s(i);
}
this._state = "normal";
}
/**
* Called when the element is added to a document.
*
* If overridden, `super.connectedCallback()` must be the first statement.
*/
connectedCallback() {
this._init();
}
// Make attribute getter return default value
getAttribute(t) {
return this._init(), super.getAttribute(t) ?? this._getMeta().attrs[t]?.default ?? null;
}
// Make all attributes setters track changes through a common setter
setAttribute(t, e) {
this._setAttr(t, e);
}
removeAttribute(t) {
this._setAttr(t, null);
}
toggleAttribute(t, e) {
return this._setAttr(t, e || typeof this.getAttribute(t) == "string" ? null : ""), !!this.getAttribute(t);
}
/**
* A common attribute setter called by attributes manipulation methods (`setAttribute`, `removeAttribute`, etc)
* and property setters
*
* @param name Attribute name
* @param value Attribute value
*/
_setAttr(t, e) {
this._init();
const s = this._getMeta().attrs[t], i = this._state !== "initialization", n = this.getAttribute(t);
e ??= s?.default ?? null, !(i && // @ts-expect-error
!this._isFirstObserverCall && e === n) && (typeof e == "string" ? super.setAttribute.call(this, t, e) : super.removeAttribute.call(this, t), i && this.attributeChangedCallback && this.attributeChangedCallback(t, n, e));
}
// Rest of the logic
/**
* Returns a constructor of this class
*
* If you need to refer to your own class, type it like so:
*
* ```ts
* class MyClass extends WebComponent {
* declare protected _ctor: () => typeof MyClass
* }
* ```
*
* @returns constructor of this class
*/
_ctor() {
return Object.getPrototypeOf(this).constructor;
}
/** @returns Current web component's metadata */
_getMeta() {
return c.get(this._ctor());
}
/**
* Defines a custom element for this web component.
*
* Won't throw an error if called multiple times with the same tag.
*
* Will throw an error (unless suppressed via {@link BasicWebComponentDefinitionOptions.noRedefinitionError})
* if defined under a different tag.
*
* @param options Definition options
*/
static define(t) {
const { tag: e, registry: s = customElements, noRedefinitionError: i } = t;
s.get(e) !== this && (i && a.get(s)?.has(this) || (this._initClass(), s.define(e, this)));
}
/** Initializes class itself. Called by {@link define} and by the constructor. Initialization happens only once. */
static _initClass() {
if (c.has(this))
return;
this.props = Object.getPrototypeOf(this).props.concat(this.props);
const t = { props: {}, attrs: {} };
c.set(this, t);
for (const e of this.props) {
const { name: s, ...i } = typeof e == "string" ? { name: e } : e;
if (t.props[s])
continue;
const n = g(s);
t.props[s] = i, t.attrs[n] = i, Object.defineProperty(this.prototype, s, {
get() {
return this.getAttribute(n) ?? i.default;
},
set(m) {
this._setAttr(n, m ?? null);
}
});
}
}
};
_.props = [];
let l = _;
const u = l.prototype, S = ["innerHTML", "innerText", "outerHTML", "attributes"];
for (const r of S) {
const t = Object.getOwnPropertyDescriptor(Element.prototype, r);
if (!t || !t.get && !t.set)
continue;
const e = {};
t.get && (e.get = function() {
return this._init(), t.get.call(this);
}), t.set && (e.set = function(s) {
this._init(), t.set.call(this, s);
}), Object.defineProperty(u, r, e);
}
const O = ["hasAttribute", "hasAttributes", "getAttributeNames"];
for (const r of O) {
const t = u[r];
u[r] = function(...e) {
return this._init(), t.call(this, ...e);
};
}
const k = CustomElementRegistry.prototype.define;
CustomElementRegistry.prototype.define = function(r, t, ...e) {
const s = () => k.call(this, r, t, ...e);
return t.prototype instanceof l && (a.has(this) || a.set(this, /* @__PURE__ */ new Set()), a.get(this).add(t), delete t.observedAttributes), s();
};
const R = "svg-image{display:inline-block}svg-image svg{display:block}", d = {
viewBox: !0,
width: !0,
height: !0
}, f = '<svg viewBox="0 0 0 0" width="0" height="0"></svg>', b = class extends l {
constructor() {
super(), this._updateSrcRes = {}, this._svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"), this._useEl = document.createElementNS("http://www.w3.org/2000/svg", "use"), this._svgEl.appendChild(this.useEl);
}
/**
* `<use>` element
*/
get useEl() {
return this._useEl;
}
/**
* `<svg>` element
*/
get svgEl() {
return this._svgEl;
}
connectedCallback() {
super.connectedCallback(), v(this.getStyleId(), R.replaceAll("svg-image", this.localName)), this.childElementCount || this.appendChild(this._svgEl);
}
disconnectedCallback() {
E(this._updateSrcRes.id);
}
attributeChangedCallback(t, e, s) {
if (!d[t]) {
if (t === "src") {
this._handleSrcUpdate(e, s);
return;
}
if (t.startsWith("use-")) {
this._handleUseAttrUpdate(t.substring(4), s);
return;
}
t.startsWith("svg-") && this._handleSvgAttrUpdate(t.substring(4), s);
}
}
/** @returns ID of a `<style>` element that styles this component */
getStyleId() {
return "svg-image-web-component__" + this.localName;
}
_handleSrcUpdate(t, e) {
this._updateSrcRes = y(t ?? void 0, e || f), this._updateSrcRes.id && h(this.useEl, "href", "#" + this._updateSrcRes.id), this._updateSrcRes.attrs && A(this.svgEl, this._updateSrcRes.attrs);
}
_handleSvgAttrUpdate(t, e) {
d[t] || h(this._svgEl, t, e);
}
_handleUseAttrUpdate(t, e) {
t !== "href" && h(this.useEl, t, e);
}
static define(t = {}) {
const e = t.tag || "svg-image";
super.define({ ...t, tag: e });
}
};
b.props = [
// Web components may be used in unpredicted contexts, so it's safer to differ from the other integrations
// and render empty SVG when there's no source code
{ name: "src", default: f }
];
let p = b;
const T = { size: !0, color: !0, "color-transition": !0 }, o = class extends l {
constructor() {
super(), C(), p.define({ noRedefinitionError: !0 }), this._svgImage = new p(), this._svgImage.setAttribute("svg-aria-hidden", "true");
}
connectedCallback() {
super.connectedCallback(), this.childElementCount || (this.classList.add("vite-awesome-svg-loader-icon"), this.appendChild(this._svgImage));
}
attributeChangedCallback(t, e, s) {
t === "src" ? this._svgImage.src = s || "" : T[t] && this.style.setProperty("--" + t, s || "");
}
static define(t = {}) {
super.define({ ...t, tag: t.tag || "svg-icon" });
}
};
o.DEFAULT_COLOR_TRANSITION = w, o.props = ["src", "size", "color", { name: "colorTransition", default: o.DEFAULT_COLOR_TRANSITION }];
let x = o;
export {
x as C,
l as a,
p as c
};
//# sourceMappingURL=index-BwNDjFB6.js.map