# EliBadge **Componente base de badge do design system** O `EliBadge` encapsula o `v-badge` do Vuetify para aplicar padrões visuais, tipagem e comportamento previsível em toda a aplicação. > ⚠️ **Nunca use `v-badge` diretamente fora do design system.** > Utilize sempre o `EliBadge` para manter consistência visual e compatibilidade entre versões do Vuetify. --- ## Visão geral O `EliBadge` foi projetado para: - Garantir consistência visual no uso de badges; - Fornecer uma API tipada (TypeScript) e com autocomplete; - Controlar corretamente a exibição do badge sem afetar o conteúdo principal; - Permitir presets semânticos de `border-radius` e valores CSS customizados; - Repassar atributos e listeners de forma transparente ao `v-badge`. ### Principais decisões de implementação - `inheritAttrs: false` — o componente faz `v-bind="$attrs"` manualmente no `v-badge`. - Uso de CSS Variable (`--eli-badge-radius`) para controlar o `border-radius`. - Presets tipados para `radius` + fallback para valores CSS livres. - O slot padrão **nunca é removido**: apenas o badge é condicional. --- ## Tipagem (TypeScript) ```ts type LocalBadge = | "top right" | "right center" | "bottom right" | "top center" | "bottom center" | "top left" | "left center" | "bottom left"; type Offset = "-20" | "-15" | "-10" | "-5" | "0" | "20" | "15" | "10" | "5"; type BadgeRadiusPreset = "suave" | "pill"; type CssLength = `${number}px` | `${number}rem` | `${number}%` | "0"; --- ## Props | Prop | Tipo | Default | Descrição | | ---------- | -------------------------------- | ------------- | ---------------------------------------------- | | `color` | `string` | `"primary"` | Cor visual do badge (Vuetify theme). | | `location` | `LocalBadge` | `"top right"` | Posição do badge em relação ao conteúdo. | | `offsetX` | `Offset` | `"0"` | Deslocamento horizontal. | | `offsetY` | `Offset` | `"0"` | Deslocamento vertical. | | `dot` | `boolean` | `false` | Exibe badge no formato de ponto. | | `visible` | `boolean` | `true` | Controla a exibição do badge (slot permanece). | | `badge` | `string \| number \| undefined` | `undefined` | Conteúdo textual ou numérico do badge. | | `radius` | `BadgeRadiusPreset \| CssLength` | `"suave"` | Preset ou valor CSS de `border-radius`. | Presets de radius { suave: "4px", // cantos levemente arredondados pill: "10px", // cantos bem arredondados } --- Repasso de atributos e listeners Como inheritAttrs: false e v-bind="$attrs" são usados: 1. Atributos HTML (ex.: type, aria-label, class, style) passados para serão aplicados ao v-badge filho. 2. Listeners (ex.: @click) também são repassados ao v-badge — use o componente como se estivesse escutando eventos diretamente no v-badge. Exemplo: mdi-bell --- Slot O EliBadge expõe um slot padrão para o conteúdo que será "badged" — normalmente um ícone, avatar ou texto. Exemplos: mdi-bell Se visible for false, o slot continua sendo renderizado (o badge some, mas o conteúdo permanece). --- Exemplos de uso Preset suave (padrão): mdi-email Preset pill (mais arredondado): mdi-chat Valor custom: mdi-alert mdi-star Esconder só o badge (manter conteúdo): Vistoria Mostrar dot (ponto): Usuário --- Acessibilidade (A11y) 1. Forneça aria-label quando o badge transmitir informação importante sem texto adicional. 2. Evite usar cor sozinha para transmitir significado — combine com texto ou atributos ARIA. 3. Para badges que comunicam contagem (ex.: notificações), adicione aria-live ou texto alternativo no componente pai conforme a necessidade do caso de uso. --- Boas práticas 1. Prefira presets (suave, pill) para consistência visual; use valores custom apenas quando necessário. 2. Não aplique estilos inline que conflitem com tokens do design system; prefira classes e variáveis do Vuetify. 3. Documente o uso do visible e badge nos locais onde o componente for amplamente adotado. 4. Evite usar visible=false se você espera apenas esconder zero/empty — prefira lógica que passe badge = undefined ou :visible="count > 0". --- Testes Recomenda-se testar: 1. Renderização com badge presente e badge === undefined. 2. Comportamento de visible (assegurar que o slot continua visível quando visible=false). 3. dot true/false. 4. Aplicação da variável CSS (--eli-badge-radius) e que o border-radius interno do Vuetify muda conforme o radius. 5. $attrs repassados para o v-badge (por exemplo: aria-label, class). Exemplo (pseudocódigo): const wrapper = mount(EliBadge, { props: { badge: '3' }, slots: { default: '' } }); expect(wrapper.html()).toContain('Inbox'); expect(wrapper.findComponent({ name: 'v-badge' }).exists()).toBe(true); --- Observações sobre Vuetify 1. O EliBadge usa seletor com `:deep(...)` para alterar o border-radius do elemento interno do `v-badge`. Se você atualizar o Vuetify, verifique os nomes de classe (`.v-badge__badge` / `.v-badge__content`) e ajuste o seletor se necessário. 2. Prop names do v-badge (ex.: location, offset-x, offset-y, content, dot) podem variar entre versões do Vuetify — reveja a docs da versão em uso se algo não for aplicado como esperado.