mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-08-05 12:07:22 -04:00
90 lines
2.3 KiB
Vue
90 lines
2.3 KiB
Vue
<script setup lang="ts" generic="T">
|
|
import { useMainStore } from '~/store/index.ts';
|
|
|
|
const props = withDefaults(defineProps<{
|
|
values: T[];
|
|
limit: number;
|
|
reducedLimit?: number;
|
|
isStatic?: boolean;
|
|
expand?: boolean;
|
|
itemClass?: string;
|
|
}>(), {
|
|
reducedLimit: 4,
|
|
});
|
|
|
|
const store = useMainStore();
|
|
|
|
const allShown = ref(false);
|
|
const showLimit = ref(props.values.length);
|
|
const hiddenCount = ref(0);
|
|
|
|
const reducedItems = computed(() => {
|
|
return store.reducedItems;
|
|
});
|
|
|
|
const visibleValues = computed((): T[] => {
|
|
if (allShown.value) {
|
|
return props.values;
|
|
}
|
|
return props.values.slice(0, showLimit.value);
|
|
});
|
|
|
|
watch(() => props.expand, () => {
|
|
if (props.expand) {
|
|
allShown.value = true;
|
|
}
|
|
});
|
|
|
|
watch(reducedItems, () => {
|
|
updateData();
|
|
});
|
|
|
|
onMounted(() => {
|
|
updateData();
|
|
});
|
|
|
|
const updateData = (): void => {
|
|
let newShowLimit = props.values.length;
|
|
let newHiddenCount = 0;
|
|
const limit = reducedItems.value === undefined || reducedItems.value ? props.reducedLimit : props.limit;
|
|
|
|
if (props.values.length > limit) {
|
|
newShowLimit = limit;
|
|
newHiddenCount = props.values.length - limit;
|
|
}
|
|
if (newHiddenCount === 1) {
|
|
newShowLimit++;
|
|
newHiddenCount--;
|
|
}
|
|
|
|
allShown.value = props.expand;
|
|
showLimit.value = newShowLimit;
|
|
hiddenCount.value = newHiddenCount;
|
|
};
|
|
</script>
|
|
|
|
<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>
|