adicionado detalhes

This commit is contained in:
Luiz Silva 2026-01-28 19:28:34 -03:00
parent 133f32e4f7
commit 5c587c9232
9 changed files with 496 additions and 50 deletions

View file

@ -1,75 +1,124 @@
<template>
<tbody class="eli-tabela__tbody">
<tr
v-for="(linha, i) in linhas"
:key="`tr-${i}`"
class="eli-tabela__tr"
:class="[i % 2 === 1 ? 'eli-tabela__tr--zebra' : undefined]"
>
<td
v-for="(coluna, j) in colunas"
:key="`td-${i}-${j}`"
class="eli-tabela__td"
:class="[
coluna.acao ? 'eli-tabela__td--clicavel' : undefined,
obterClasseAlinhamento(coluna.alinhamento),
]"
@click="coluna.acao ? () => coluna.acao?.() : undefined"
<template v-for="(linha, i) in linhas" :key="`grp-${i}`">
<tr
class="eli-tabela__tr"
:class="[i % 2 === 1 ? 'eli-tabela__tr--zebra' : undefined]"
>
<span
v-if="Boolean(coluna.truncar)"
class="eli-tabela__celula-conteudo"
:style="coluna.largura_maxima ? { maxWidth: obterMaxWidth(coluna.largura_maxima) } : undefined"
:title="obterTooltipCelula(coluna.celula(linha as never))"
>
<EliTabelaCelula :celula="(coluna.celula(linha as never) as never)" />
</span>
<EliTabelaCelula v-else :celula="(coluna.celula(linha as never) as never)" />
</td>
<td v-if="temAcoes" class="eli-tabela__td eli-tabela__td--acoes" :key="`td-${i}-acoes`">
<div
class="eli-tabela__acoes-container"
:class="[menuAberto === i ? 'eli-tabela__acoes-container--aberto' : undefined]"
>
<td v-if="temColunasInvisiveis" class="eli-tabela__td eli-tabela__td--expander" :key="`td-${i}-exp`">
<button
class="eli-tabela__acoes-toggle"
type="button"
:id="`eli-tabela-acoes-toggle-${i}`"
:disabled="!possuiAcoes(i)"
:aria-haspopup="'menu'"
:aria-expanded="menuAberto === i ? 'true' : 'false'"
:aria-controls="possuiAcoes(i) ? `eli-tabela-acoes-menu-${i}` : undefined"
:aria-label="possuiAcoes(i) ? 'Ações da linha' : 'Nenhuma ação disponível'"
:title="possuiAcoes(i) ? 'Ações' : 'Nenhuma ação disponível'"
@click.stop="toggleMenu(i, $event)"
class="eli-tabela__expander-botao"
:class="[linhasExpandidas?.[i] ? 'eli-tabela__expander-botao--ativo' : undefined]"
:aria-expanded="linhasExpandidas?.[i] ? 'true' : 'false'"
:aria-label="linhasExpandidas?.[i] ? 'Ocultar colunas ocultas' : 'Mostrar colunas ocultas'"
:title="linhasExpandidas?.[i] ? 'Ocultar detalhes' : 'Mostrar detalhes'"
@click.stop="alternarLinhaExpandida(i)"
>
<MoreVertical class="eli-tabela__acoes-toggle-icone" :size="18" :stroke-width="2" />
<component
:is="linhasExpandidas?.[i] ? ChevronDown : ChevronRight"
class="eli-tabela__expander-icone"
:size="16"
:stroke-width="2"
aria-hidden="true"
/>
</button>
</div>
</td>
</tr>
</td>
<td
v-for="(coluna, j) in colunas"
:key="`td-${i}-${j}`"
class="eli-tabela__td"
:class="[
coluna.acao ? 'eli-tabela__td--clicavel' : undefined,
obterClasseAlinhamento(coluna.alinhamento),
]"
@click="coluna.acao ? () => coluna.acao?.() : undefined"
>
<span
v-if="Boolean(coluna.truncar)"
class="eli-tabela__celula-conteudo"
:style="coluna.largura_maxima ? { maxWidth: obterMaxWidth(coluna.largura_maxima) } : undefined"
:title="obterTooltipCelula(coluna.celula(linha as never))"
>
<EliTabelaCelula :celula="(coluna.celula(linha as never) as never)" />
</span>
<EliTabelaCelula v-else :celula="(coluna.celula(linha as never) as never)" />
</td>
<td v-if="temAcoes" class="eli-tabela__td eli-tabela__td--acoes" :key="`td-${i}-acoes`">
<div
class="eli-tabela__acoes-container"
:class="[menuAberto === i ? 'eli-tabela__acoes-container--aberto' : undefined]"
>
<button
class="eli-tabela__acoes-toggle"
type="button"
:id="`eli-tabela-acoes-toggle-${i}`"
:disabled="!possuiAcoes(i)"
:aria-haspopup="'menu'"
:aria-expanded="menuAberto === i ? 'true' : 'false'"
:aria-controls="possuiAcoes(i) ? `eli-tabela-acoes-menu-${i}` : undefined"
:aria-label="possuiAcoes(i) ? 'Ações da linha' : 'Nenhuma ação disponível'"
:title="possuiAcoes(i) ? 'Ações' : 'Nenhuma ação disponível'"
@click.stop="toggleMenu(i, $event)"
>
<MoreVertical class="eli-tabela__acoes-toggle-icone" :size="18" :stroke-width="2" />
</button>
</div>
</td>
</tr>
<tr
v-if="temColunasInvisiveis && Boolean(linhasExpandidas?.[i])"
class="eli-tabela__tr eli-tabela__tr--detalhes"
:class="[i % 2 === 1 ? 'eli-tabela__tr--zebra' : undefined]"
>
<td
class="eli-tabela__td eli-tabela__td--detalhes"
:colspan="(temColunasInvisiveis ? 1 : 0) + colunas.length + (temAcoes ? 1 : 0)"
>
<EliTabelaDetalhesLinha :linha="linha" :colunasInvisiveis="colunasInvisiveis" />
</td>
</tr>
</template>
</tbody>
</template>
<script lang="ts">
import { defineComponent, PropType } from "vue";
import { MoreVertical } from "lucide-vue-next";
import { ChevronDown, ChevronRight, MoreVertical } from "lucide-vue-next";
import EliTabelaCelula from "./celulas/EliTabelaCelula.vue";
import EliTabelaDetalhesLinha from "./EliTabelaDetalhesLinha.vue";
import type { EliColuna } from "./types-eli-tabela";
export default defineComponent({
name: "EliTabelaBody",
components: {
EliTabelaCelula,
EliTabelaDetalhesLinha,
MoreVertical,
ChevronRight,
ChevronDown,
},
props: {
colunas: {
type: Array as PropType<Array<EliColuna<any>>>,
required: true,
},
colunasInvisiveis: {
type: Array as PropType<Array<EliColuna<any>>>,
required: true,
},
temColunasInvisiveis: {
type: Boolean,
required: true,
},
linhasExpandidas: {
type: Object as PropType<Record<number, boolean>>,
required: true,
},
linhas: {
type: Array as PropType<Array<unknown>>,
required: true,
@ -90,6 +139,10 @@ export default defineComponent({
type: Function as PropType<(indice: number, evento: MouseEvent) => void>,
required: true,
},
alternarLinhaExpandida: {
type: Function as PropType<(indice: number) => void>,
required: true,
},
},
setup() {
function obterClasseAlinhamento(alinhamento?: string) {
@ -121,6 +174,8 @@ export default defineComponent({
}
return {
ChevronRight,
ChevronDown,
obterClasseAlinhamento,
obterMaxWidth,
obterTooltipCelula,