switch img icons to svg to fix issues with user selected themes
This commit is contained in:
+45
-47
@@ -1,4 +1,4 @@
|
||||
import { requestPVE, requestAPI, goToPage, getURIData, resourcesConfig, setTitleAndHeader, bootConfig, setAppearance } from "./utils.js";
|
||||
import { requestPVE, requestAPI, goToPage, getURIData, resourcesConfig, setTitleAndHeader, bootConfig, setAppearance, setSVGSrc, setSVGAlt } from "./utils.js";
|
||||
import { alert, dialog } from "./dialog.js";
|
||||
|
||||
window.addEventListener("DOMContentLoaded", init); // do the dumb thing where the disk config refreshes every second
|
||||
@@ -88,9 +88,9 @@ async function populateResources () {
|
||||
function addResourceLine (fieldset, iconHref, type, labelText, id, attributes, unitText = null) {
|
||||
const field = document.querySelector(`#${fieldset}`);
|
||||
|
||||
const icon = document.createElement("img");
|
||||
icon.src = iconHref;
|
||||
icon.alt = labelText;
|
||||
const icon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
setSVGSrc(icon, iconHref);
|
||||
setSVGAlt(icon, labelText);
|
||||
field.append(icon);
|
||||
|
||||
const label = document.createElement("label");
|
||||
@@ -168,9 +168,9 @@ function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
|
||||
const diskID = `${busPrefix}${device}`;
|
||||
|
||||
// Set the disk icon, either drive.svg or disk.svg
|
||||
const icon = document.createElement("img");
|
||||
icon.src = diskMetaData[type][busPrefix].icon;
|
||||
icon.alt = diskName;
|
||||
const icon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
setSVGSrc(icon, diskMetaData[type][busPrefix].icon);
|
||||
setSVGAlt(icon, diskName);
|
||||
icon.dataset.disk = diskID;
|
||||
field.append(icon);
|
||||
|
||||
@@ -190,23 +190,24 @@ function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
|
||||
|
||||
const actionDiv = document.createElement("div");
|
||||
diskMetaData.actionBarOrder.forEach((element) => {
|
||||
const action = document.createElement("img");
|
||||
const action = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
if (element === "detach_attach" && diskMetaData[type][busPrefix].actions.includes("attach")) { // attach
|
||||
action.src = "images/actions/disk/attach.svg";
|
||||
setSVGSrc(action, diskMetaData.actions.attach.src);
|
||||
setSVGAlt(action, diskMetaData.actions.attach.title);
|
||||
action.title = "Attach Disk";
|
||||
action.addEventListener("click", handleDiskAttach);
|
||||
action.classList.add("clickable");
|
||||
}
|
||||
else if (element === "detach_attach" && diskMetaData[type][busPrefix].actions.includes("detach")) { // detach
|
||||
action.src = "images/actions/disk/detach.svg";
|
||||
action.title = "Detach Disk";
|
||||
setSVGSrc(action, diskMetaData.actions.detach.src);
|
||||
setSVGAlt(action, diskMetaData.actions.detach.title);
|
||||
action.addEventListener("click", handleDiskDetach);
|
||||
action.classList.add("clickable");
|
||||
}
|
||||
else if (element === "delete") {
|
||||
const active = diskMetaData[type][busPrefix].actions.includes(element) ? "active" : "inactive"; // resize
|
||||
action.src = `images/actions/delete-${active}.svg`;
|
||||
action.title = "Delete Disk";
|
||||
setSVGSrc(action, `images/actions/delete-${active}.svg`);
|
||||
setSVGAlt(action, "Delete Disk");
|
||||
if (active === "active") {
|
||||
action.addEventListener("click", handleDiskDelete);
|
||||
action.classList.add("clickable");
|
||||
@@ -214,9 +215,9 @@ function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
|
||||
}
|
||||
else {
|
||||
const active = diskMetaData[type][busPrefix].actions.includes(element) ? "active" : "inactive"; // resize
|
||||
action.src = `images/actions/disk/${element}-${active}.svg`;
|
||||
setSVGSrc(action, `images/actions/disk/${element}-${active}.svg`);
|
||||
if (active === "active") {
|
||||
action.title = `${element.charAt(0).toUpperCase()}${element.slice(1)} Disk`;
|
||||
setSVGAlt(action, `${element.charAt(0).toUpperCase()}${element.slice(1)} Disk`);
|
||||
if (element === "move") {
|
||||
action.addEventListener("click", handleDiskMove);
|
||||
}
|
||||
@@ -227,7 +228,6 @@ function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
|
||||
}
|
||||
}
|
||||
action.dataset.disk = diskID;
|
||||
action.alt = action.title;
|
||||
actionDiv.append(action);
|
||||
});
|
||||
field.append(actionDiv);
|
||||
@@ -239,7 +239,7 @@ async function handleDiskDetach () {
|
||||
const body = `<p>Are you sure you want to detach disk ${disk}</p>`;
|
||||
dialog(header, body, async (result, form) => {
|
||||
if (result === "confirm") {
|
||||
document.querySelector(`img[data-disk="${disk}"]`).src = "images/status/loading.svg";
|
||||
setSVGSrc(document.querySelector(`svg[data-disk="${disk}"]`), "images/status/loading.svg");
|
||||
const result = await requestAPI(`/cluster/${node}/${type}/${vmid}/disk/${disk}/detach`, "POST");
|
||||
if (result.status !== 200) {
|
||||
alert(result.error);
|
||||
@@ -263,7 +263,7 @@ async function handleDiskAttach () {
|
||||
dialog(header, body, async (result, form) => {
|
||||
if (result === "confirm") {
|
||||
const device = form.get("device");
|
||||
document.querySelector(`img[data-disk="${this.dataset.disk}"]`).src = "images/status/loading.svg";
|
||||
setSVGSrc(document.querySelector(`svg[data-disk="${this.dataset.disk}"]`), "images/status/loading.svg");
|
||||
const body = {
|
||||
source: this.dataset.disk.replace("unused", "")
|
||||
};
|
||||
@@ -292,7 +292,7 @@ async function handleDiskResize () {
|
||||
dialog(header, body, async (result, form) => {
|
||||
if (result === "confirm") {
|
||||
const disk = this.dataset.disk;
|
||||
document.querySelector(`img[data-disk="${disk}"]`).src = "images/status/loading.svg";
|
||||
setSVGSrc(document.querySelector(`svg[data-disk="${disk}"]`), "images/status/loading.svg");
|
||||
const body = {
|
||||
size: form.get("size-increment")
|
||||
};
|
||||
@@ -332,7 +332,7 @@ async function handleDiskMove () {
|
||||
dialog(header, body, async (result, form) => {
|
||||
if (result === "confirm") {
|
||||
const disk = this.dataset.disk;
|
||||
document.querySelector(`img[data-disk="${disk}"]`).src = "images/status/loading.svg";
|
||||
setSVGSrc(document.querySelector(`svg[data-disk="${disk}"]`), "images/status/loading.svg");
|
||||
const body = {
|
||||
storage: form.get("storage-select"),
|
||||
delete: form.get("delete-check") === "on" ? "1" : "0"
|
||||
@@ -355,7 +355,7 @@ async function handleDiskDelete () {
|
||||
const body = `<p>Are you sure you want to <strong>delete</strong> disk${disk}</p>`;
|
||||
dialog(header, body, async (result, form) => {
|
||||
if (result === "confirm") {
|
||||
document.querySelector(`img[data-disk="${disk}"]`).src = "images/status/loading.svg";
|
||||
setSVGSrc(document.querySelector(`svg[data-disk="${disk}"]`), "images/status/loading.svg");
|
||||
const result = await requestAPI(`/cluster/${node}/${type}/${vmid}/disk/${disk}/delete`, "DELETE");
|
||||
if (result.status !== 200) {
|
||||
alert(result.error);
|
||||
@@ -465,9 +465,9 @@ async function populateNetworks () {
|
||||
function addNetworkLine (fieldset, prefix, netID, netDetails) {
|
||||
const field = document.querySelector(`#${fieldset}`);
|
||||
|
||||
const icon = document.createElement("img");
|
||||
icon.src = "images/resources/network.svg";
|
||||
icon.alt = `${prefix}${netID}`;
|
||||
const icon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
setSVGSrc(icon, "images/resources/network.svg");
|
||||
setSVGAlt(icon, `${prefix}${netID}`);
|
||||
icon.dataset.network = netID;
|
||||
icon.dataset.values = netDetails;
|
||||
field.appendChild(icon);
|
||||
@@ -488,19 +488,19 @@ function addNetworkLine (fieldset, prefix, netID, netDetails) {
|
||||
|
||||
const actionDiv = document.createElement("div");
|
||||
|
||||
const configBtn = document.createElement("img");
|
||||
const configBtn = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
configBtn.classList.add("clickable");
|
||||
configBtn.src = "images/actions/network/config.svg";
|
||||
configBtn.title = "Config Interface";
|
||||
setSVGSrc(configBtn, "images/actions/network/config.svg");
|
||||
setSVGAlt(configBtn, "Config Interface");
|
||||
configBtn.addEventListener("click", handleNetworkConfig);
|
||||
configBtn.dataset.network = netID;
|
||||
configBtn.dataset.values = netDetails;
|
||||
actionDiv.appendChild(configBtn);
|
||||
|
||||
const deleteBtn = document.createElement("img");
|
||||
const deleteBtn = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
deleteBtn.classList.add("clickable");
|
||||
deleteBtn.src = "images/actions/delete-active.svg";
|
||||
deleteBtn.title = "Delete Interface";
|
||||
setSVGSrc(deleteBtn, "images/actions/delete-active.svg");
|
||||
setSVGAlt(deleteBtn, "Delete Interface");
|
||||
deleteBtn.addEventListener("click", handleNetworkDelete);
|
||||
deleteBtn.dataset.network = netID;
|
||||
deleteBtn.dataset.values = netDetails;
|
||||
@@ -521,7 +521,7 @@ async function handleNetworkConfig () {
|
||||
|
||||
const d = dialog(header, body, async (result, form) => {
|
||||
if (result === "confirm") {
|
||||
document.querySelector(`img[data-network="${netID}"]`).src = "images/status/loading.svg";
|
||||
setSVGSrc(document.querySelector(`svg[data-network="${netID}"]`), "images/status/loading.svg");
|
||||
const body = {
|
||||
rate: form.get("rate")
|
||||
};
|
||||
@@ -546,7 +546,7 @@ async function handleNetworkDelete () {
|
||||
|
||||
dialog(header, body, async (result, form) => {
|
||||
if (result === "confirm") {
|
||||
document.querySelector(`img[data-network="${netID}"]`).src = "images/status/loading.svg";
|
||||
setSVGSrc(document.querySelector(`svg[data-network="${netID}"]`), "images/status/loading.svg");
|
||||
const result = await requestAPI(`/cluster/${node}/${type}/${vmid}/net/net${netID}/delete`, "DELETE");
|
||||
if (result.status !== 200) {
|
||||
alert(result.error);
|
||||
@@ -615,9 +615,9 @@ async function populateDevices () {
|
||||
function addDeviceLine (fieldset, prefix, deviceID, deviceDetails, deviceName) {
|
||||
const field = document.querySelector(`#${fieldset}`);
|
||||
|
||||
const icon = document.createElement("img");
|
||||
icon.src = "images/resources/device.svg";
|
||||
icon.alt = `${prefix}${deviceID}`;
|
||||
const icon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
setSVGSrc(icon, "images/resources/device.svg");
|
||||
setSVGAlt(icon, `${prefix}${deviceID}`);
|
||||
icon.dataset.device = deviceID;
|
||||
icon.dataset.values = deviceDetails;
|
||||
icon.dataset.name = deviceName;
|
||||
@@ -634,20 +634,20 @@ function addDeviceLine (fieldset, prefix, deviceID, deviceDetails, deviceName) {
|
||||
|
||||
const actionDiv = document.createElement("div");
|
||||
|
||||
const configBtn = document.createElement("img");
|
||||
const configBtn = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
configBtn.classList.add("clickable");
|
||||
configBtn.src = "images/actions/device/config.svg";
|
||||
configBtn.title = "Config Device";
|
||||
setSVGSrc(configBtn, "images/actions/device/config.svg");
|
||||
setSVGAlt(configBtn, "Config Device");
|
||||
configBtn.addEventListener("click", handleDeviceConfig);
|
||||
configBtn.dataset.device = deviceID;
|
||||
configBtn.dataset.values = deviceDetails;
|
||||
configBtn.dataset.name = deviceName;
|
||||
actionDiv.appendChild(configBtn);
|
||||
|
||||
const deleteBtn = document.createElement("img");
|
||||
const deleteBtn = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
deleteBtn.classList.add("clickable");
|
||||
deleteBtn.src = "images/actions/delete-active.svg";
|
||||
deleteBtn.title = "Delete Device";
|
||||
setSVGSrc(deleteBtn, "images/actions/delete-active.svg");
|
||||
setSVGAlt(deleteBtn, "Delete Device");
|
||||
deleteBtn.addEventListener("click", handleDeviceDelete);
|
||||
deleteBtn.dataset.device = deviceID;
|
||||
deleteBtn.dataset.values = deviceDetails;
|
||||
@@ -670,7 +670,7 @@ async function handleDeviceConfig () {
|
||||
|
||||
const d = dialog(header, body, async (result, form) => {
|
||||
if (result === "confirm") {
|
||||
document.querySelector(`img[data-device="${deviceID}"]`).src = "images/status/loading.svg";
|
||||
setSVGSrc(document.querySelector(`svg[data-device="${deviceID}"]`), "images/status/loading.svg");
|
||||
const body = {
|
||||
device: form.get("device"),
|
||||
pcie: form.get("pcie") ? 1 : 0
|
||||
@@ -699,7 +699,7 @@ async function handleDeviceDelete () {
|
||||
|
||||
dialog(header, body, async (result, form) => {
|
||||
if (result === "confirm") {
|
||||
document.querySelector(`img[data-device="${deviceID}"]`).src = "images/status/loading.svg";
|
||||
setSVGSrc(document.querySelector(`svg[data-device="${deviceID}"]`), "images/status/loading.svg");
|
||||
const result = await requestAPI(`/cluster/${node}/${type}/${vmid}/pci/hostpci${deviceID}/delete`, "DELETE");
|
||||
if (result.status !== 200) {
|
||||
alert(result.error);
|
||||
@@ -783,14 +783,12 @@ function addBootLine (container, data, before = null) {
|
||||
item.data = data;
|
||||
item.innerHTML = `
|
||||
<div style="display: grid; grid-template-columns: auto auto 8ch 1fr; column-gap: 10px; align-items: center;">
|
||||
<img src="images/actions/drag.svg" id="drag" alt="drag icon">
|
||||
<img src="${bootMetaData[data.prefix].icon}" alt="${bootMetaData[data.prefix].alt}">
|
||||
<svg id="drag" role="application" aria-label="drag icon"><title>drag icon</title><use xlink:href="images/actions/drag.svg#symb"></use></svg>
|
||||
<svg role="application" aria-label="${bootMetaData[data.prefix].alt}"><title>${bootMetaData[data.prefix].alt}</title><use xlink:href="${bootMetaData[data.prefix].icon}#symb"></use></svg>
|
||||
<p style="margin: 0px;">${data.id}</p>
|
||||
<p style="margin: 0px; overflow-x: hidden; white-space: nowrap;">${data.detail}</p>
|
||||
</div>
|
||||
`;
|
||||
item.draggable = true;
|
||||
item.classList.add("drop-target");
|
||||
item.id = `boot-${data.id}`;
|
||||
if (before) {
|
||||
document.querySelector(`#${container}`).insertBefore(item, before);
|
||||
|
||||
@@ -11,6 +11,9 @@ class DraggableContainer extends HTMLElement {
|
||||
border-radius: 5px;
|
||||
margin: -1px;
|
||||
}
|
||||
draggable-item::part(wrapper) {
|
||||
cursor: grab;
|
||||
}
|
||||
</style>
|
||||
<label id="title"></label>
|
||||
<div id="wrapper" style="padding-bottom: 1em;"></div>
|
||||
@@ -78,7 +81,7 @@ class DraggableItem extends HTMLElement {
|
||||
// for whatever reason, only grid layout seems to respect the parent's content bounds
|
||||
this.shadowRoot.innerHTML = `
|
||||
<style>
|
||||
img {
|
||||
img, svg {
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
+19
-23
@@ -1,4 +1,4 @@
|
||||
import { requestPVE, requestAPI, goToPage, goToURL, instancesConfig, nodesConfig } from "./utils.js";
|
||||
import { requestPVE, requestAPI, goToPage, goToURL, instancesConfig, nodesConfig, setSVGSrc, setSVGAlt } from "./utils.js";
|
||||
import { PVE } from "../vars.js";
|
||||
import { dialog } from "./dialog.js";
|
||||
|
||||
@@ -27,21 +27,21 @@ class InstanceCard extends HTMLElement {
|
||||
<p id="instance-type"></p>
|
||||
</div>
|
||||
<div class="w3-col l2 m3 s6 flex row nowrap">
|
||||
<img id="instance-status-icon">
|
||||
<svg id="instance-status-icon"></svg>
|
||||
<p id="instance-status"></p>
|
||||
</div>
|
||||
<div class="w3-col l2 w3-hide-medium w3-hide-small">
|
||||
<p id="node-name"></p>
|
||||
</div>
|
||||
<div class="w3-col l2 w3-hide-medium w3-hide-small flex row nowrap">
|
||||
<img id="node-status-icon">
|
||||
<svg id="node-status-icon"></svg>
|
||||
<p id="node-status"></p>
|
||||
</div>
|
||||
<div class="w3-col l2 m2 s6 flex row nowrap" style="height: 1lh;">
|
||||
<img id="power-btn" tabindex="0" role="button">
|
||||
<img id="console-btn" tabindex="0" role="button">
|
||||
<img id="configure-btn" tabindex="0" role="button">
|
||||
<img id="delete-btn" tabindex="0" role="button">
|
||||
<svg id="power-btn" tabindex="0" role="button"></svg>
|
||||
<svg id="console-btn" tabindex="0" role="button"></svg>
|
||||
<svg id="configure-btn" tabindex="0" role="button"></svg>
|
||||
<svg id="delete-btn" tabindex="0" role="button"></svg>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -102,8 +102,8 @@ class InstanceCard extends HTMLElement {
|
||||
statusParagraph.innerText = this.status;
|
||||
|
||||
const statusIcon = this.shadowRoot.querySelector("#instance-status-icon");
|
||||
statusIcon.src = instancesConfig[this.status].status.src;
|
||||
statusIcon.alt = instancesConfig[this.status].status.alt;
|
||||
setSVGSrc(statusIcon, instancesConfig[this.status].status.src);
|
||||
setSVGAlt(statusIcon, instancesConfig[this.status].status.alt);
|
||||
|
||||
const nodeNameParagraph = this.shadowRoot.querySelector("#node-name");
|
||||
nodeNameParagraph.innerText = this.node.name;
|
||||
@@ -112,40 +112,36 @@ class InstanceCard extends HTMLElement {
|
||||
nodeStatusParagraph.innerText = this.node.status;
|
||||
|
||||
const nodeStatusIcon = this.shadowRoot.querySelector("#node-status-icon");
|
||||
nodeStatusIcon.src = nodesConfig[this.node.status].status.src;
|
||||
nodeStatusIcon.alt = nodesConfig[this.node.status].status.src;
|
||||
setSVGSrc(nodeStatusIcon, nodesConfig[this.node.status].status.src);
|
||||
setSVGAlt(nodeStatusIcon, nodesConfig[this.node.status].status.alt);
|
||||
|
||||
const powerButton = this.shadowRoot.querySelector("#power-btn");
|
||||
powerButton.src = instancesConfig[this.status].power.src;
|
||||
powerButton.alt = instancesConfig[this.status].power.alt;
|
||||
powerButton.title = instancesConfig[this.status].power.alt;
|
||||
setSVGSrc(powerButton, instancesConfig[this.status].power.src);
|
||||
setSVGAlt(powerButton, instancesConfig[this.status].power.alt);
|
||||
if (instancesConfig[this.status].power.clickable) {
|
||||
powerButton.classList.add("clickable");
|
||||
powerButton.onclick = this.handlePowerButton.bind(this);
|
||||
}
|
||||
|
||||
const configButton = this.shadowRoot.querySelector("#configure-btn");
|
||||
configButton.src = instancesConfig[this.status].config.src;
|
||||
configButton.alt = instancesConfig[this.status].config.alt;
|
||||
configButton.title = instancesConfig[this.status].config.alt;
|
||||
setSVGSrc(configButton, instancesConfig[this.status].config.src);
|
||||
setSVGAlt(configButton, instancesConfig[this.status].config.alt);
|
||||
if (instancesConfig[this.status].config.clickable) {
|
||||
configButton.classList.add("clickable");
|
||||
configButton.onclick = this.handleConfigButton.bind(this);
|
||||
}
|
||||
|
||||
const consoleButton = this.shadowRoot.querySelector("#console-btn");
|
||||
consoleButton.src = instancesConfig[this.status].console.src;
|
||||
consoleButton.alt = instancesConfig[this.status].console.alt;
|
||||
consoleButton.title = instancesConfig[this.status].console.alt;
|
||||
setSVGSrc(consoleButton, instancesConfig[this.status].console.src);
|
||||
setSVGAlt(consoleButton, instancesConfig[this.status].console.alt);
|
||||
if (instancesConfig[this.status].console.clickable) {
|
||||
consoleButton.classList.add("clickable");
|
||||
consoleButton.onclick = this.handleConsoleButton.bind(this);
|
||||
}
|
||||
|
||||
const deleteButton = this.shadowRoot.querySelector("#delete-btn");
|
||||
deleteButton.src = instancesConfig[this.status].delete.src;
|
||||
deleteButton.alt = instancesConfig[this.status].delete.alt;
|
||||
deleteButton.title = instancesConfig[this.status].delete.alt;
|
||||
setSVGSrc(deleteButton, instancesConfig[this.status].delete.src);
|
||||
setSVGAlt(deleteButton, instancesConfig[this.status].delete.alt);
|
||||
if (instancesConfig[this.status].delete.clickable) {
|
||||
deleteButton.classList.add("clickable");
|
||||
deleteButton.onclick = this.handleDeleteButton.bind(this);
|
||||
|
||||
@@ -14,6 +14,17 @@ export const resourcesConfig = {
|
||||
ide: { name: "IDE", icon: "images/resources/disk.svg", actions: ["delete"] },
|
||||
sata: { name: "SATA", icon: "images/resources/drive.svg", actions: ["detach", "move", "reassign", "resize"] },
|
||||
unused: { name: "UNUSED", icon: "images/resources/drive.svg", actions: ["attach", "delete", "reassign"] }
|
||||
},
|
||||
actions: {
|
||||
attach: {
|
||||
src: "images/actions/disk/attach.svg",
|
||||
title: "Attach Disk"
|
||||
},
|
||||
detach: {
|
||||
src: "images/actions/disk/detach.svg",
|
||||
title: "Detach Disk"
|
||||
},
|
||||
delete: null
|
||||
}
|
||||
},
|
||||
network: {
|
||||
@@ -317,3 +328,17 @@ export function setAppearance () {
|
||||
document.querySelector(":root").classList.remove("dark-theme");
|
||||
}
|
||||
}
|
||||
|
||||
// assumes href is path to svg, and id to grab is #symb
|
||||
export function setSVGSrc (svgElem, href) {
|
||||
let useElem = svgElem.querySelector("use");
|
||||
if (!useElem) {
|
||||
useElem = document.createElementNS("http://www.w3.org/2000/svg", "use");
|
||||
}
|
||||
useElem.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", `${href}#symb`);
|
||||
svgElem.append(useElem);
|
||||
}
|
||||
|
||||
export function setSVGAlt (svgElem, alt) {
|
||||
svgElem.setAttribute("aria-label", alt);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user