🎴 Info Card - Guia Completo
Componente de Cards de Informação Versão: 1.0.0 Data: 2025-11-04 Baseado no Design System Figma - Gales
Status: Implementado no Design System 1.1 (05/11/2025)
Compatibilidade: Light/Dark, SSR (Laminas) e futuro front SPA
📋 Índice
🎯 Visão Geral
O componente Info Card é um card de informações com design moderno que apresenta dados de forma organizada e expansível. Ideal para exibir informações de propriedades, produtores, veículos, explorações e outros tipos de entidades.
Características:
- ✅ Header com título, ícone e código/identificador
- ✅ Badge de status (Ativo/Inativo/etc)
- ✅ Corpo expansível/colapsável
- ✅ Múltiplos tipos (Propriedade, Pessoa, Veículo, etc)
- ✅ Dark mode completo
- ✅ Acessibilidade WCAG 2.1 AA
- ✅ Responsivo (mobile-first)
- ✅ Animações suaves
- ✅ JavaScript API completa
📦 Instalação
CSS
Adicione o arquivo CSS no seu HTML:
<link rel="stylesheet" href="/css/design-system/components/info-card.css">JavaScript
Adicione o arquivo JavaScript antes do fechamento do </body>:
<script src="/js/design-system/components/info-card.js"></script>🚀 Uso Básico
Estrutura HTML Mínima
<div class="info-card" data-info-card>
<!-- Header -->
<div class="info-card__header">
<div class="info-card__header-content">
<h3 class="info-card__header-title">
<i class="ipe-casa-preenchida info-card__header-icon"></i>
<strong>Propriedade</strong>
</h3>
<p class="info-card__header-subtitle">Fazenda Santo Antônio</p>
<p class="info-card__header-code">14.00282.1122</p>
</div>
<div class="info-card__header-actions">
<span class="info-card__badge info-card__badge--active">Ativo</span>
<button class="info-card__toggle is-expanded"
aria-expanded="true"
aria-label="Expandir/Colapsar informações">
<i class="ipe-chevron-down info-card__toggle-icon"></i>
</button>
</div>
</div>
<!-- Body -->
<div class="info-card__body">
<ul class="info-card__body-list">
<li class="info-card__body-item">
<span class="info-card__body-label">Código Animal/I.E:</span>
<span class="info-card__body-value">14.00282</span>
</li>
<li class="info-card__body-item">
<span class="info-card__body-label">Área:</span>
<span class="info-card__body-value">1531.00ha</span>
</li>
<li class="info-card__body-item">
<span class="info-card__body-label">Endereço:</span>
<span class="info-card__body-value">Vicinal Serra da Prata</span>
</li>
<li class="info-card__body-item">
<span class="info-card__body-label">Município:</span>
<span class="info-card__body-value">Iracema</span>
</li>
</ul>
</div>
</div>🎨 Variantes
Tipos de Cards
1. Propriedade (Property)
<div class="info-card info-card--propriedade" data-info-card>
<div class="info-card__header">
<div class="info-card__header-content">
<h3 class="info-card__header-title">
<i class="ipe-casa-preenchida info-card__header-icon"></i>
<strong>Propriedade</strong>
</h3>
<p class="info-card__header-subtitle">Fazenda Santo Antônio</p>
<p class="info-card__header-code">14.00282.1122</p>
</div>
<div class="info-card__header-actions">
<span class="info-card__badge info-card__badge--active">Ativo</span>
<button class="info-card__toggle" aria-expanded="true">
<i class="ipe-chevron-down info-card__toggle-icon"></i>
</button>
</div>
</div>
<!-- Body... -->
</div>Cor do header: Azul primário (#3F68FB)
2. Pessoa/Produtor (Person/Producer)
<div class="info-card info-card--pessoa" data-info-card>
<div class="info-card__header">
<div class="info-card__header-content">
<h3 class="info-card__header-title">
<i class="ipe-pessoa-preenchida info-card__header-icon"></i>
<strong>Produtor</strong>
</h3>
<p class="info-card__header-subtitle">Arthur Macedo Belém</p>
<p class="info-card__header-code">846.597.246-85</p>
</div>
<div class="info-card__header-actions">
<span class="info-card__badge info-card__badge--active">Ativo</span>
<button class="info-card__toggle" aria-expanded="true">
<i class="ipe-chevron-down info-card__toggle-icon"></i>
</button>
</div>
</div>
<!-- Body... -->
</div>Cor do header: Cinza escuro (#394360)
3. Exploração (Farm)
<div class="info-card info-card--exploracao" data-info-card>
<!-- Header com ícone de exploração -->
</div>Cor do header: Verde (#47B881)
4. Veículo (Vehicle)
<div class="info-card info-card--veiculo" data-info-card>
<!-- Header com ícone de veículo -->
</div>Cor do header: Azul info (#3B82F6)
5. Empresa (Company)
<div class="info-card info-card--empresa" data-info-card>
<!-- Header com ícone de empresa -->
</div>Cor do header: Roxo (#8B5CF6)
6. Animal
<div class="info-card info-card--animal" data-info-card>
<!-- Header com ícone de animal -->
</div>Cor do header: Laranja (#F59E0B)
🎯 Estados
Badges de Status
Ativo
<span class="info-card__badge info-card__badge--active">Ativo</span>Cores: Background #DDE4D2 | Texto #1A2E00
Inativo
<span class="info-card__badge info-card__badge--inactive">Inativo</span>Cores: Background #FDDEDE | Texto #A52D1D
Aviso
<span class="info-card__badge info-card__badge--warning">Pendente</span>Cores: Background #FEF3C7 | Texto #92400E
Info
<span class="info-card__badge info-card__badge--info">Em análise</span>Cores: Background #DBEAFE | Texto #1E40AF
Expansão/Colapso
Expandido (padrão)
<div class="info-card" data-info-card data-info-card-expanded="true">
<!-- ... -->
<div class="info-card__body">
<!-- Conteúdo visível -->
</div>
</div>Colapsado
<div class="info-card" data-info-card data-info-card-expanded="false">
<!-- ... -->
<div class="info-card__body is-collapsed">
<!-- Conteúdo oculto -->
</div>
</div>⚡ JavaScript API
Inicialização Automática
O componente é inicializado automaticamente em elementos com data-info-card:
<div class="info-card" data-info-card>
<!-- Card será inicializado automaticamente -->
</div>Criação Manual
// Criar um novo InfoCard
const card = createInfoCard('#meu-card', {
expanded: true,
animated: true,
onToggle: (card, isExpanded) => {
console.log('Card foi alternado:', isExpanded);
}
});Métodos
expand()
Expande o card
const card = getInfoCard('#meu-card');
card.expand();collapse()
Colapsa o card
const card = getInfoCard('#meu-card');
card.collapse();toggleMethod()
Alterna entre expandido e colapsado
const card = getInfoCard('#meu-card');
card.toggleMethod();isExpandedMethod()
Retorna o estado atual
const card = getInfoCard('#meu-card');
if (card.isExpandedMethod()) {
console.log('Card está expandido');
}setExpanded(boolean)
Define o estado
const card = getInfoCard('#meu-card');
card.setExpanded(false); // Colapsa
card.setExpanded(true); // ExpandeEventos Customizados
infocard:init
Disparado quando o card é inicializado
document.addEventListener('infocard:init', (e) => {
console.log('Card inicializado:', e.detail.card);
});infocard:expand
Disparado quando o card é expandido
element.addEventListener('infocard:expand', (e) => {
console.log('Card expandido:', e.detail);
});infocard:collapse
Disparado quando o card é colapsado
element.addEventListener('infocard:collapse', (e) => {
console.log('Card colapsado:', e.detail);
});Callbacks
createInfoCard('#meu-card', {
onExpand: (card) => {
console.log('Card foi expandido');
},
onCollapse: (card) => {
console.log('Card foi colapsado');
},
onToggle: (card, isExpanded) => {
console.log('Card foi alternado:', isExpanded);
}
});Gerenciamento Global
// Expandir todos os cards
expandAllInfoCards();
// Colapsar todos os cards
collapseAllInfoCards();
// Obter uma instância
const card = getInfoCard('#meu-card');
// Criar uma instância
const newCard = createInfoCard('#outro-card', { expanded: false });Opções de Configuração
| Opção | Tipo | Padrão | Descrição |
|---|---|---|---|
expanded | boolean | true | Define se o card inicia expandido |
animated | boolean | true | Habilita animações |
clickableHeader | boolean | false | Permite clicar no header para expandir |
onExpand | function | null | Callback ao expandir |
onCollapse | function | null | Callback ao colapsar |
onToggle | function | null | Callback ao alternar |
♿ Acessibilidade
WCAG 2.1 Nível AA
Contraste de Cores
- ✅ Texto no header: 10.5:1 (AAA)
- ✅ Texto no body: 7.8:1 (AAA)
- ✅ Badge Ativo: 8.2:1 (AAA)
Navegação por Teclado
- ✅
Tab: Navega entre cards e botões - ✅
Enter/Space: Expande/colapsa - ✅ Focus visível em todos elementos interativos
ARIA Attributes
<button class="info-card__toggle"
aria-expanded="true"
aria-label="Expandir ou colapsar informações da propriedade">
<i class="ipe-chevron-down info-card__toggle-icon" aria-hidden="true"></i>
</button>Screen Readers
- Labels descritivos em botões
- Ícones marcados com
aria-hidden="true" - Estados comunicados via
aria-expanded
📱 Responsividade
Desktop (> 768px)
- Card com largura máxima de 852px
- Padding padrão: 16px
- Header altura: 116px
Tablet (≤ 768px)
- Card com largura 100%
- Header altura: 100px
- Padding reduzido: 16px 20px
Mobile (≤ 480px)
- Header em coluna (vertical)
- Actions ocupam 100% da largura
- Font-size reduzido
🎨 Customização
CSS Variables
.info-card {
--info-card-header-bg: #12151F;
--info-card-header-color: #F6F6F9;
--info-card-body-bg: #ECEDF2;
--info-card-body-color: #394360;
}Classes Utilitárias
Compacto
<div class="info-card info-card--compact">
<!-- Header e body com menos padding -->
</div>Largura Total
<div class="info-card info-card--full">
<!-- Card ocupa 100% da largura -->
</div>Sem Sombra
<div class="info-card info-card--flat">
<!-- Card sem box-shadow, com borda -->
</div>Sempre Expandido
<div class="info-card info-card--always-expanded">
<!-- Card sempre expandido, sem botão toggle -->
</div>🌙 Dark Mode
Ativação
<!-- Via classe no body -->
<body class="dark">
<!-- Ou via classe no componente -->
<div class="info-card info-card--dark">Cores no Dark Mode
| Elemento | Light Mode | Dark Mode |
|---|---|---|
| Background | #F6F6F9 | #12151F |
| Header | #12151F | #1A1D29 |
| Body | #ECEDF2 | #1E2130 |
| Texto Body | #394360 | #C8CDDB |
📋 Exemplos Práticos
Exemplo 1: Card de Propriedade com PHP
<?php
use Agrodefesa\Util\InfoCard;
// Antigo (legacy)
echo InfoCard::propriedade($idInscricaoEstadual, true);
// Novo (design-system) - Para migração futura
?>
<div class="info-card info-card--propriedade" data-info-card>
<div class="info-card__header">
<div class="info-card__header-content">
<h3 class="info-card__header-title">
<i class="ipe-casa-preenchida info-card__header-icon"></i>
<strong>Propriedade</strong>
</h3>
<p class="info-card__header-subtitle"><?= $dadosPropriedade->no_fantasia ?></p>
<p class="info-card__header-code"><?= $dadosPropriedade->nu_codigoanimal ?></p>
</div>
<div class="info-card__header-actions">
<span class="info-card__badge info-card__badge--<?= $dadosPropriedade->bo_ativo ? 'active' : 'inactive' ?>">
<?= $dadosPropriedade->bo_ativo ? 'Ativo' : 'Inativo' ?>
</span>
<button class="info-card__toggle is-expanded" aria-expanded="true">
<i class="ipe-chevron-down info-card__toggle-icon"></i>
</button>
</div>
</div>
<div class="info-card__body">
<ul class="info-card__body-list">
<li class="info-card__body-item">
<span class="info-card__body-label">Código Animal/I.E:</span>
<span class="info-card__body-value"><?= $dadosPropriedade->nu_codigoanimal ?>/<?= $dadosPropriedade->nu_inscricaoestadual ?></span>
</li>
<li class="info-card__body-item">
<span class="info-card__body-label">Área:</span>
<span class="info-card__body-value"><?= $dadosPropriedade->vl_area ?>ha</span>
</li>
<li class="info-card__body-item">
<span class="info-card__body-label">Endereço:</span>
<span class="info-card__body-value"><?= $dadosPropriedade->endereco_propriedade ?></span>
</li>
<li class="info-card__body-item">
<span class="info-card__body-label">Município:</span>
<span class="info-card__body-value"><?= $dadosPropriedade->municipio_propriedade ?></span>
</li>
</ul>
</div>
</div>Exemplo 2: Múltiplos Cards em Grid
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--6-col">
<!-- Card Propriedade -->
<div class="info-card info-card--propriedade" data-info-card>
<!-- ... -->
</div>
</div>
<div class="mdl-cell mdl-cell--6-col">
<!-- Card Produtor -->
<div class="info-card info-card--pessoa" data-info-card>
<!-- ... -->
</div>
</div>
</div>Exemplo 3: Card Controlado por JavaScript
<button onclick="toggleCard()">Toggle Card</button>
<div class="info-card" id="my-card" data-info-card data-info-card-expanded="false">
<!-- ... -->
</div>
<script>
function toggleCard() {
const card = getInfoCard('#my-card');
card.toggleMethod();
}
</script>🔧 Troubleshooting
Card não expande/colapsa
Problema: Clique no botão não funciona Solução: Verifique se o JavaScript foi carregado e se o atributo data-info-card está presente
Estilos não aplicados
Problema: Card sem visual correto Solução: Verifique se o CSS foi importado antes de outros estilos que possam sobrescrever
Animação não funciona
Problema: Card expande/colapsa sem animação Solução: Verifique se data-info-card-animated="true" está definido
📚 Recursos Adicionais
Arquivos
- CSS:
/css/design-system/components/info-card.css - JavaScript:
/js/design-system/components/info-card.js - Exemplos:
/css/design-system/exemplos-info-card.html
Links Úteis
📝 Changelog
Versão 1.0.0 (2025-11-04)
- ✅ Implementação inicial do componente
- ✅ Suporte a 6 tipos de cards
- ✅ JavaScript API completa
- ✅ Dark mode
- ✅ Acessibilidade WCAG 2.1 AA
- ✅ Documentação completa
- ✅ Baseado no design exportado do Figma
Desenvolvido com ❤️ para o SIDASPVersão: 1.0.0 Última atualização: 2025-11-04