parsley/app/javascript/components/AppIconicIcon.vue

156 lines
3.9 KiB
Vue
Raw Normal View History

2018-09-10 17:25:36 -05:00
<template>
2024-09-29 13:35:49 -05:00
<svg ref="svg" v-bind="svgAttributes" v-html="svgContent" :class="calculatedClasses"></svg>
2018-09-10 17:25:36 -05:00
</template>
<script>
2024-10-01 09:32:09 -05:00
import { computed, nextTick, onMounted, onUpdated, useTemplateRef } from "vue";
2024-09-29 13:35:49 -05:00
2018-09-10 17:25:36 -05:00
import Caret from "../iconic/svg/smart/caret";
import Check from "../iconic/svg/smart/check";
import CircleCheck from "../iconic/svg/smart/circle-check";
import Link from "../iconic/svg/smart/link";
import Lock from "../iconic/svg/smart/lock";
import Menu from "../iconic/svg/smart/menu";
2020-08-30 17:43:47 -05:00
import QuestionMark from "../iconic/svg/smart/question-mark.svg"
2018-09-10 17:25:36 -05:00
import Person from "../iconic/svg/smart/person";
import Pencil from "../iconic/svg/smart/pencil";
import Star from "../iconic/svg/smart/star";
import StarEmpty from "../iconic/svg/smart/star-empty";
2018-09-13 14:51:41 -05:00
import Warning from "../iconic/svg/smart/warning";
2018-09-10 17:25:36 -05:00
import X from "../iconic/svg/smart/x";
const APIS = {};
const LOADED_APIS = {};
window._Iconic = {
smartIconApis: APIS
};
let globalIdCounter = 0;
const iconMap = {
caret: Caret,
check: Check,
'circle-check': CircleCheck,
link: Link,
lock: Lock,
menu: Menu,
pencil: Pencil,
person: Person,
2020-08-30 17:43:47 -05:00
'question-mark': QuestionMark,
2018-09-10 17:25:36 -05:00
star: Star,
'star-empty': StarEmpty,
2018-09-13 14:51:41 -05:00
warning: Warning,
2018-09-10 17:25:36 -05:00
x: X
};
export default {
props: {
icon: {
type: String,
required: true,
validator: (i) => iconMap[i] !== undefined
},
size: {
type: String,
default: "lg",
validator: (s) => ["sm", "md", "lg"].indexOf(s) >= 0
},
iconSizeOverride: {
type: String,
validator: (s) => ["sm", "md", "lg", null].indexOf(s) >= 0
},
displaySizeOverride: {
type: String,
validator: (s) => ["sm", "md", "lg", null].indexOf(s) >= 0
}
},
2024-09-29 13:35:49 -05:00
setup(props) {
const svgElement = useTemplateRef("svg");
const svgData = computed(() => iconMap[props.icon]);
const svgAttributes = computed(() => svgData.value.attributes);
const svgName = computed(() => svgAttributes.value['data-icon']);
const svgContent = computed(() => {
let content = String(svgData.value.content);
2018-09-10 17:25:36 -05:00
2024-09-29 13:35:49 -05:00
for (let idRep of svgData.value.idReplacements) {
2018-09-10 17:25:36 -05:00
let newId = `__new_id_${globalIdCounter}`;
globalIdCounter += 1;
content = content.replace(new RegExp(idRep, "g"), newId);
}
return content;
2024-09-29 13:35:49 -05:00
});
2018-09-10 17:25:36 -05:00
2024-09-29 13:35:49 -05:00
const calculatedClasses = computed(() => {
const classes = (svgAttributes.value.class || "").split(" ");
2018-09-10 17:25:36 -05:00
2024-09-29 13:35:49 -05:00
classes.push(`iconic-${props.size}`);
2018-09-10 17:25:36 -05:00
2024-09-29 13:35:49 -05:00
if (props.iconSizeOverride) {
classes.push(`iconic-icon-${props.iconSizeOverride}`);
2018-09-10 17:25:36 -05:00
}
2024-09-29 13:35:49 -05:00
if (props.displaySizeOverride) {
classes.push(`iconic-size-${props.displaySizeOverride}`);
2018-09-10 17:25:36 -05:00
}
2024-09-29 13:35:49 -05:00
return classes;
});
function ensureSvgApi(name, scripts) {
if (!name) { return; }
if (LOADED_APIS[name] !== true) {
for (let sb of scripts) {
try {
new Function(sb)(window);
} catch (e) {
console.log(sb);
console.log(e);
}
}
LOADED_APIS[name] = true;
2018-09-10 17:25:36 -05:00
}
}
2024-09-29 13:35:49 -05:00
function setupSvgApi(name) {
const apis = APIS;
if (apis && apis[name]) {
const iconApi = apis[name](svgElement.value);
for (let func in iconApi) svgElement.value[func] = iconApi[func]
} else {
svgElement.value.update = function() {}
2018-09-10 17:25:36 -05:00
}
2024-09-29 13:35:49 -05:00
svgElement.value.update();
2018-09-10 17:25:36 -05:00
}
2024-10-01 09:32:09 -05:00
function updateScripts() {
ensureSvgApi(svgName.value, svgData.value.scriptBlocks);
setupSvgApi(svgName.value);
}
onMounted(() => {
updateScripts();
});
onUpdated(() => {
updateScripts();
});
2024-09-29 13:35:49 -05:00
return {
svgData,
svgAttributes,
svgName,
svgContent,
calculatedClasses
};
2018-09-10 17:25:36 -05:00
}
}
</script>