PronounsPage/components/pronouns/PronounsGrammarTable.vue
2024-10-19 17:40:47 +02:00

114 lines
4.9 KiB
Vue

<script setup lang="ts">
import type { Pronoun } from '~/src/classes.ts';
import type { GrammarTable, PronounVariant, SectionDefinition } from '~/src/pronouns/grammarTables.ts';
const props = defineProps<{
grammarTable: GrammarTable;
expandVariantsForSection: (sectionVariants: SectionDefinition['variants']) => PronounVariant[];
pronoun: Pronoun;
counter: number;
}>();
const buildVariantsForSection = (
sectionVariants: SectionDefinition['variants'],
pronoun: Pronoun,
counter: number,
): PronounVariant[] => {
return props.expandVariantsForSection(sectionVariants).filter((variant) => {
return variant.morphemeCells.some((morphemeCell) => {
return pronoun.getMorpheme(morphemeCell.morpheme, counter) !== null;
});
});
};
const sections = computed(() => {
return props.grammarTable.sections.map((section) => {
const variants = buildVariantsForSection(section.variants, props.pronoun, props.counter);
return { header: section.header, variants };
}).filter((section) => {
return section.variants.length > 0;
});
});
const rowHeaderCount = computed(() => {
return Math.max(...sections.value.map((section) => {
if (!section.header) {
// no row headers at all
return 0;
} else if (!section.variants.some((variant) => variant.name)) {
// all row headers have no variants
return 1;
} else {
// some row headers have variants, needing a column for the icons and for the text
return 3;
}
}));
});
</script>
<template>
<div v-if="sections.length > 0" class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th v-if="rowHeaderCount" :colspan="rowHeaderCount"></th>
<th v-for="header in grammarTable.columnHeader" :key="header.name">
<Spelling class="d-none d-md-inline" :text="header.name" />
<Tooltip class="d-md-none" :text="header.name">
<Spelling :text="header.short" />
</Tooltip>
</th>
</tr>
</thead>
<tbody>
<template v-for="section in sections">
<tr
v-for="[i, variant] in section.variants.entries()"
:key="`${section.header?.name}-${variant.name}`"
>
<th v-if="i === 0 && rowHeaderCount >= 1" :rowspan="section.variants.length">
<template v-if="section.header">
<Spelling class="d-none d-md-inline" :text="section.header.name" />
<Tooltip class="d-md-none" :text="section.header.name">
<Spelling :text="section.header.short" />
</Tooltip>
</template>
</th>
<template v-if="rowHeaderCount >= 2">
<template v-if="variant.numerus || variant.icon">
<th class="pe-0">
<Tooltip v-if="variant.name" class="text-nowrap" :text="variant.name">
{{ variant.numerus === 'singular' ? '' : '' }}
<Icon v-if="variant.icon" :v="variant.icon" />
</Tooltip>
</th>
<th class="ps-0">
<Spelling class="d-none d-md-inline" :text="variant.name" />
</th>
</template>
<template v-else>
<th colspan="2">
<Spelling :text="variant.name" />
</th>
</template>
</template>
<td v-for="morphemeCell in variant.morphemeCells" :key="morphemeCell.morpheme">
<MorphemeWithPronunciation
:pronoun="pronoun"
:morpheme="morphemeCell.morpheme"
:highlights-morphemes="morphemeCell.highlightsMorphemes"
:prepend="morphemeCell.prepend"
:counter="counter"
/>
</td>
<td
v-if="grammarTable.columnHeader.length > variant.morphemeCells.length"
:colspan="grammarTable.columnHeader.length - variant.morphemeCells.length"
></td>
</tr>
</template>
</tbody>
</table>
</div>
</template>