feat(cartao): adicionar cards com status e playground tipo trello
This commit is contained in:
parent
ab15c51a1b
commit
5bb6732b81
8 changed files with 438 additions and 2 deletions
148
src/componentes/cartao/EliCartao.vue
Normal file
148
src/componentes/cartao/EliCartao.vue
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
<template>
|
||||
<v-card
|
||||
class="eli-cartao"
|
||||
:variant="variant"
|
||||
:class="classeStatus"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<v-card-title class="eli-cartao__titulo">
|
||||
<div class="eli-cartao__titulo-texto">
|
||||
<slot name="titulo">
|
||||
{{ titulo }}
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<!-- Indicador de status (badge) padronizado pelo design system -->
|
||||
<div class="eli-cartao__status">
|
||||
<EliBadge
|
||||
:badge="rotuloStatus"
|
||||
radius="pill"
|
||||
:color="corStatus"
|
||||
>
|
||||
<span />
|
||||
</EliBadge>
|
||||
</div>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text class="eli-cartao__conteudo">
|
||||
<slot />
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions v-if="$slots.acoes" class="eli-cartao__acoes">
|
||||
<slot name="acoes" />
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, PropType } from "vue";
|
||||
import type { CartaoStatus } from "../../tipos";
|
||||
import { EliBadge } from "../indicador";
|
||||
|
||||
type CartaoVariante = "outlined" | "flat" | "elevated" | "tonal";
|
||||
|
||||
/**
|
||||
* EliCartao
|
||||
*
|
||||
* Um cartão de domínio para listas/pipelines (ex.: oportunidades/propostas) com:
|
||||
* - título
|
||||
* - status padronizado (novo/rascunho/vendido/cancelado)
|
||||
* - slot padrão para conteúdo
|
||||
* - slot opcional para ações
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: "EliCartao",
|
||||
components: { EliBadge },
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
/** Título de fallback caso o slot `titulo` não seja usado. */
|
||||
titulo: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
|
||||
/**
|
||||
* Status semântico do cartão.
|
||||
* Usado para cor/label e para permitir filtros por status.
|
||||
*/
|
||||
status: {
|
||||
type: String as PropType<CartaoStatus>,
|
||||
required: true,
|
||||
},
|
||||
|
||||
/** Variante visual do v-card (Vuetify). */
|
||||
variant: {
|
||||
type: String as PropType<CartaoVariante>,
|
||||
default: "outlined",
|
||||
},
|
||||
},
|
||||
emits: {
|
||||
/** Emit opcional para padronizar clique no cartão. */
|
||||
clicar: (_status: CartaoStatus) => true,
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const rotuloStatus = computed(() => {
|
||||
// Mantém label em PT-BR (não abreviar)
|
||||
return props.status;
|
||||
});
|
||||
|
||||
const corStatus = computed(() => {
|
||||
// Cor neutra por padrão e semântica por status
|
||||
switch (props.status) {
|
||||
case "novo":
|
||||
return "primary";
|
||||
case "rascunho":
|
||||
return "secondary";
|
||||
case "vendido":
|
||||
return "success";
|
||||
case "cancelado":
|
||||
return "error";
|
||||
}
|
||||
});
|
||||
|
||||
const classeStatus = computed(() => `eli-cartao--${props.status}`);
|
||||
|
||||
function onClick() {
|
||||
emit("clicar", props.status);
|
||||
}
|
||||
|
||||
return {
|
||||
rotuloStatus,
|
||||
corStatus,
|
||||
classeStatus,
|
||||
onClick,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.eli-cartao {
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.eli-cartao__titulo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.eli-cartao__titulo-texto {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.eli-cartao__conteudo {
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.eli-cartao__acoes {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
/* Hooks visuais por status (sem forçar cor, deixa o tema do Vuetify fazer o trabalho) */
|
||||
.eli-cartao--cancelado {
|
||||
opacity: 0.85;
|
||||
}
|
||||
</style>
|
||||
|
||||
71
src/componentes/cartao/README.md
Normal file
71
src/componentes/cartao/README.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# EliCartao
|
||||
|
||||
O `EliCartao` é um componente de cartão focado em **listas/pipelines** (ex.: oportunidades e propostas comerciais), com um **status semântico** padronizado.
|
||||
|
||||
Ele encapsula o `v-card` (Vuetify) e adiciona:
|
||||
|
||||
- Área de **título**
|
||||
- **Badge de status** padronizado (`novo`, `rascunho`, `vendido`, `cancelado`)
|
||||
- Slot de **conteúdo**
|
||||
- Slot opcional de **ações**
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
| Prop | Tipo | Padrão | Descrição |
|
||||
|----------|--------------------------------------------------|--------------|-----------|
|
||||
| `titulo` | `string` | `""` | Título de fallback (se o slot `titulo` não for usado). |
|
||||
| `status` | `"novo" \| "rascunho" \| "vendido" \| "cancelado"` | *(obrigatório)* | Status semântico do cartão. Controla label/cor do badge e classes. |
|
||||
| `variant`| `"outlined" \| "flat" \| "elevated" \| "tonal"` | `"outlined"` | Variante do `v-card` (Vuetify). |
|
||||
|
||||
### Emits
|
||||
|
||||
| Evento | Payload | Quando dispara |
|
||||
|----------|-------------------------|----------------|
|
||||
| `clicar` | `(status: CartaoStatus)`| Quando o cartão for clicado (opcional; útil para padronizar navegação). |
|
||||
|
||||
> Observação: o componente deixa `v-bind="$attrs"` para você passar `class`, `style`, `to`, `href`, etc.
|
||||
|
||||
## Slots
|
||||
|
||||
| Slot | Objetivo |
|
||||
|----------|----------|
|
||||
| `titulo` | Conteúdo customizado do título (override do `titulo`). |
|
||||
| `default`| Corpo do cartão. |
|
||||
| `acoes` | Rodapé de ações (botões/links). |
|
||||
|
||||
## Exemplos
|
||||
|
||||
### 1) Cartão simples
|
||||
|
||||
```vue
|
||||
<EliCartao titulo="Proposta #1024" status="novo">
|
||||
<div><strong>Cliente:</strong> ACME Ltda</div>
|
||||
<div><strong>Valor:</strong> R$ 12.500,00</div>
|
||||
</EliCartao>
|
||||
```
|
||||
|
||||
### 2) Título via slot + ações
|
||||
|
||||
```vue
|
||||
<EliCartao status="vendido">
|
||||
<template #titulo>
|
||||
<span>Oportunidade #204</span>
|
||||
</template>
|
||||
|
||||
<div>Cliente: Empresa X</div>
|
||||
|
||||
<template #acoes>
|
||||
<EliBotao variant="text">Abrir</EliBotao>
|
||||
<EliBotao variant="text" color="secondary">Editar</EliBotao>
|
||||
</template>
|
||||
</EliCartao>
|
||||
```
|
||||
|
||||
## Casos de borda / comportamento esperado
|
||||
|
||||
- `status` é obrigatório e sempre deve ser um valor suportado.
|
||||
- Status `cancelado` aplica leve redução de opacidade via classe CSS.
|
||||
- A renderização de ações só ocorre se o slot `acoes` existir.
|
||||
|
||||
2
src/componentes/cartao/index.ts
Normal file
2
src/componentes/cartao/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export { default as EliCartao } from "./EliCartao.vue";
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue