PronounsPage/components/ExpandableList.vue
2024-04-30 19:41:40 +02:00

98 lines
2.8 KiB
Vue

<template>
<ul>
<li v-for="(el, i) in visibleValues" :key="i" :class="itemClass">
<slot :el="el" :i="i">
{{ el }}
</slot>
</li>
<li v-show="!allShown && hiddenCount > 0" :class="[itemClass, 'small']">
<span v-if="isStatic">
<Icon v="plus-circle" />
<T :params="{ count: hiddenCount }">profile.expendableList.more</T>
</span>
<a v-else href="#" @click.prevent="allShown = true">
<Icon v="plus-circle" />
<T :params="{ count: hiddenCount }">profile.expendableList.more</T>
<template v-if="!(itemClass || '').includes('list-inline-item')">
<br>
<Icon v="spacer" />
</template>
<T>profile.expendableList.show</T>
</a>
</li>
</ul>
</template>
<script lang="ts">
import Vue from 'vue';
import type { PropType } from 'vue';
interface Data {
allShown: boolean;
showLimit: number;
hiddenCount: number;
}
export default Vue.extend({
props: {
values: { required: true, type: Array as PropType<string[]> },
limit: { required: true, type: Number },
reducedLimit: { default: 4, type: Number },
isStatic: { type: Boolean },
expand: { type: Boolean },
itemClass: { default: undefined, type: String as PropType<string | undefined> },
},
data(): Data {
return {
allShown: false,
showLimit: this.values.length,
hiddenCount: 0,
};
},
computed: {
reducedItems() {
return this.$store.state.reducedItems;
},
visibleValues(): string[] {
if (this.allShown) {
return this.values;
}
return this.values.slice(0, this.showLimit);
},
},
watch: {
expand(v) {
if (v) {
this.allShown = true;
}
},
reducedItems() {
this.updateData();
},
},
created() {
this.updateData();
},
methods: {
updateData(): void {
let showLimit = this.values.length;
let hiddenCount = 0;
const limit = this.reducedItems === undefined || this.reducedItems ? this.reducedLimit : this.limit;
if (this.values.length > limit) {
showLimit = limit;
hiddenCount = this.values.length - limit;
}
if (hiddenCount === 1) {
showLimit--;
hiddenCount++;
}
this.allShown = this.expand;
this.showLimit = showLimit;
this.hiddenCount = hiddenCount;
},
},
});
</script>