mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-10-18 11:21:37 -04:00
104 lines
2.8 KiB
Vue
104 lines
2.8 KiB
Vue
<template>
|
|
<img
|
|
v-if="iconSource"
|
|
:src="iconSource"
|
|
:style="`height: ${size}em; width: ${size}em; display: inline;`"
|
|
alt=""
|
|
class="icon"
|
|
@error="fallBack"
|
|
>
|
|
<span v-else :class="[`fa${iconSet}`, `fa-${icon}`, 'fa-fw', hover ? 'fa-hover' : '']" :style="style"></span>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import Vue from 'vue';
|
|
import type { PropType } from 'vue';
|
|
|
|
const buildQueue = (v: string | string[]): { value: string, fallbacks: string[] } => {
|
|
let values = Array.isArray(v) ? v : [v];
|
|
values = values.filter((x) => !!x);
|
|
|
|
if (!values.length) {
|
|
values = ['spacer'];
|
|
}
|
|
|
|
return {
|
|
value: values.shift()!,
|
|
fallbacks: values,
|
|
};
|
|
};
|
|
|
|
export default Vue.extend({
|
|
props: {
|
|
v: { required: true, type: [String, Array] as PropType<string | string[]> },
|
|
set: { default: 'l', type: String as PropType<'l' | 's' | 'b'> },
|
|
size: { default: 1, type: Number },
|
|
inverse: { type: Boolean },
|
|
hover: { type: Boolean },
|
|
},
|
|
data() {
|
|
return buildQueue(this.v);
|
|
},
|
|
computed: {
|
|
valueParts(): string[] {
|
|
return this.value.split(':');
|
|
},
|
|
icon(): string {
|
|
const icon = this.valueParts[this.valueParts.length - 1];
|
|
if (icon === 'neutrum') {
|
|
return 'neuter';
|
|
}
|
|
return icon;
|
|
},
|
|
iconSet(): string {
|
|
return this.valueParts.length > 1 ? this.valueParts[0] : this.set;
|
|
},
|
|
iconSource(): string | null {
|
|
if (this.value.startsWith('https://')) {
|
|
return this.value;
|
|
}
|
|
if (this.value.endsWith('.svg')) {
|
|
return `/img/${this.inverse ? this.value.replace('.svg', '-inverse.svg') : this.value}`;
|
|
}
|
|
if (this.value.endsWith('.png')) {
|
|
return `/img/${this.inverse ? this.value.replace('.png', '-inverse.png') : this.value}`;
|
|
}
|
|
return null;
|
|
},
|
|
style(): string {
|
|
const properties = [];
|
|
if (this.size !== 1) {
|
|
properties.push(`font-size: ${this.size}em`);
|
|
}
|
|
if (this.v === 'neutrum') {
|
|
properties.push('transform: rotate(225deg)');
|
|
}
|
|
return properties.join(';');
|
|
},
|
|
},
|
|
watch: {
|
|
v(v) {
|
|
const { value, fallbacks } = buildQueue(v);
|
|
|
|
this.value = value;
|
|
this.fallbacks = fallbacks;
|
|
},
|
|
},
|
|
methods: {
|
|
fallBack() {
|
|
if (!this.fallbacks.length) {
|
|
return;
|
|
}
|
|
|
|
this.value = this.fallbacks.shift()!;
|
|
},
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.fa-hover:hover {
|
|
font-weight: 900;
|
|
}
|
|
</style>
|