Kanban Board
Board drag-and-drop com colunas configuraveis, cards com progresso/labels/responsaveis, views Minimal/Classic e reordenacao entre colunas. Componente React Island.
Uso
Quando e como utilizar o board Kanban para gerenciar tarefas e processos com colunas de status.
- JSON data — Carrega colunas e cards de um endpoint JSON via atributo
data-propsno container. O componente faz fetch automatico ao montar. - Inline data — Dados passados diretamente no atributo
data-propscomo JSON serializado, sem fetch externo. - Programmatic — Monta a ilha manualmente via
ArenitoIslands.mount()passando o elemento container e as props como objeto JavaScript.
Exemplos
Veja abaixo os exemplos interativos do board Kanban, incluindo views Minimal e Classic, drag-and-drop e cards com progresso.
Anatomia
Estrutura interna do componente e seus elementos.
| Parte | Elemento | Descricao |
|---|---|---|
| Container | .kanban-board | Wrapper principal com overflow-x auto e width 100% |
| Header | .kanban-board__header | Cabecalho com titulo e controles de view |
| Titulo | .kanban-board__title | Heading do board, Space Grotesk 18px w600 |
| View Toggle | .kanban-board__view-toggle | Grupo de botoes para alternar views |
| View Btn | .kanban-board__view-btn | Botao de view, Inter 13px w500 |
| Columns | .kanban-board__columns | Flex row com gap 16px e scroll horizontal |
| Column | .kanban-board__column | Coluna individual, min-width 280px, border-radius 8px |
| Column Header | .kanban-board__column-header | Cabecalho da coluna com titulo e contador |
| Column Title | .kanban-board__column-title | Titulo da coluna, Inter 14px w600 |
| Column Count | .kanban-board__column-count | Badge numerico com total de cards |
| Column Color | .kanban-board__column-color | Barra de cor 4px no topo da coluna |
| Column Body | .kanban-board__column-body | Drop zone dos cards com min-height 120px |
| Card | .kanban-board__card | Card arrastavel com padding 12px e shadow |
| Card Title | .kanban-board__card-title | Titulo do card, Inter 13px w600 |
| Card Desc | .kanban-board__card-description | Descricao, Inter 12px, max 2 linhas com ellipsis |
| Card Labels | .kanban-board__card-labels | Flex wrap de labels coloridos |
| Card Progress | .kanban-board__card-progress | Barra de progresso 4px com border-radius |
| Card Assignees | .kanban-board__card-assignees | Avatares empilhados no rodape do card |
| Vazio | .kanban-board__empty | Estado sem dados, borda dashed e padding 48px |
Views
O board suporta duas views que controlam a densidade de informacao dos cards.
O usuario pode alternar entre as views Minimal e Classic clicando nos botoes do toggle no cabecalho do board. A view ativa e persistida no localStorage do navegador.
| Aspecto | Minimal | Classic |
|---|---|---|
| Card height | Compacto, apenas titulo e labels | Expandido com descricao, progresso e assignees |
| Descricao | Oculta | Visivel, max 2 linhas com text-overflow |
| Progresso | Oculto | Barra de progresso horizontal visivel |
| Assignees | Ocultos | Avatares empilhados no rodape |
| Labels | Dots coloridos 8x8 sem texto | Badges com texto e cor de fundo |
| Density | Mais cards visiveis por coluna | Menos cards visiveis, mais informacao por card |
A alternancia entre views e animada com transition: all 200ms ease nos elementos que mudam de visibilidade.
Drag and Drop
O sistema de drag-and-drop usa a HTML5 Drag API nativa para reordenar cards entre colunas.
O Kanban Board utiliza a HTML5 Drag API (draggable, ondragstart, ondragover, ondrop) ao inves de bibliotecas externas para minimizar o tamanho do bundle. O fluxo funciona da seguinte forma:
- O card recebe
draggable="true"e nodragstartarmazena ocardIdesourceColumnIdnodataTransfer. - As colunas escutam
dragover(compreventDefault()para permitir o drop) e adicionam o modificador--drag-overpara feedback visual. - No
drop, o componente le os dados dodataTransfer, move o card no state interno e dispara o CustomEventarenito:kanban:card-moved. - O card em arraste recebe o modificador
--draggingcomopacity: 0.5e sombra elevada.
A reordenacao dentro da mesma coluna tambem e suportada: o card e inserido na posicao mais proxima do ponto de drop baseado no clientY do evento.
Eventos
CustomEvents disparados pelo componente para integracao com o monolito PHP.
O Kanban Board emite CustomEvents no elemento container para que o codigo do monolito possa reagir a acoes do usuario sem acoplar-se ao React.
| Evento | detail | Quando dispara |
|---|---|---|
arenito:kanban:card-moved | { cardId: string, fromColumn: string, toColumn: string, position: number } | Card e solto em uma coluna (mesma ou diferente) |
arenito:kanban:card-clicked | { cardId: string, columnId: string, data: object } | Usuario clica em um card do board |
document.querySelector('[data-island="KanbanBoard"]')
.addEventListener('arenito:kanban:card-moved', (e) => {
console.log('Card:', e.detail.cardId);
console.log('De:', e.detail.fromColumn, '→ Para:', e.detail.toColumn);
});Propriedades
Classes CSS disponiveis para configurar o board Kanban.
| Propriedade | Tipo | Default | Descrição |
|---|---|---|---|
.kanban-board | classe | — | Container principal do board com overflow-x auto. |
.kanban-board__header | classe | — | Cabecalho do board com titulo e controles de view. |
.kanban-board__title | classe | — | Titulo do board (18px w600, font-heading). |
.kanban-board__view-toggle | classe | — | Grupo de botoes para alternar entre views Minimal e Classic. |
.kanban-board__view-btn | classe | — | Botao individual de view (13px w500). |
.kanban-board__view-btn--active | classe | — | Modificador para view ativa (background brand, texto branco). |
.kanban-board__columns | classe | — | Flex row das colunas com gap 16px e scroll horizontal. |
.kanban-board__column | classe | — | Coluna individual com min-width 280px e border radius 8px. |
.kanban-board__column-header | classe | — | Cabecalho da coluna com titulo, contador e cor indicadora. |
.kanban-board__column-title | classe | — | Titulo da coluna (14px w600). |
.kanban-board__column-count | classe | — | Badge com contagem de cards na coluna. |
.kanban-board__column-color | classe | — | Barra de cor 4px no topo da coluna. |
.kanban-board__column-body | classe | — | Area de drop dos cards com min-height 120px. |
.kanban-board__column-body--drag-over | classe | — | Modificador visual quando um card e arrastado sobre a coluna. |
.kanban-board__card | classe | — | Card individual arrastavel com padding 12px e shadow. |
.kanban-board__card--dragging | classe | — | Modificador para card sendo arrastado (opacity 0.5, shadow elevado). |
.kanban-board__card-title | classe | — | Titulo do card (13px w600). |
.kanban-board__card-description | classe | — | Descricao do card (12px, texto secundario, max 2 linhas). |
.kanban-board__card-labels | classe | — | Flex wrap de labels coloridos no card. |
.kanban-board__card-label | classe | — | Label individual (badge pequeno com cor de fundo). |
.kanban-board__card-progress | classe | — | Barra de progresso horizontal no card (height 4px). |
.kanban-board__card-progress-fill | classe | — | Fill da barra de progresso com largura percentual. |
.kanban-board__card-assignees | classe | — | Grupo de avatares empilhados no rodape do card. |
.kanban-board__card-assignee | classe | — | Avatar individual 24x24 com margin-left negativo para sobreposicao. |
.kanban-board__empty | classe | — | Estado vazio com borda tracejada e texto centralizado. |
Codigo
Snippets prontos para copiar e usar no seu projeto.
HTML com data-island e data-props
<div data-island="KanbanBoard"
data-props='{
"title": "Processos de Fiscalizacao",
"view": "classic",
"columns": [
{
"id": "backlog",
"title": "Backlog",
"color": "#6B7280",
"cards": [
{
"id": "card-1",
"title": "Vistoria Lote 42",
"description": "Inspecao de conformidade ambiental",
"labels": [{ "text": "Urgente", "color": "#EF4444" }],
"progress": 0,
"assignees": [{ "name": "Ana", "avatar": "/avatars/ana.jpg" }]
}
]
},
{
"id": "in-progress",
"title": "Em Andamento",
"color": "#3B82F6",
"cards": []
},
{
"id": "done",
"title": "Concluido",
"color": "#10B981",
"cards": []
}
]
}'>
</div>Montagem programatica via ArenitoIslands.mount()
const container = document.getElementById('kanban-container');
ArenitoIslands.mount(container, 'KanbanBoard', {
title: 'Sprint 14 — Equipe Alpha',
view: 'minimal',
columns: [
{
id: 'todo',
title: 'A Fazer',
color: '#6B7280',
cards: [
{ id: '1', title: 'Implementar filtro de data', labels: [{ text: 'Feature', color: '#3B82F6' }], progress: 0 },
{ id: '2', title: 'Corrigir paginacao da listagem', labels: [{ text: 'Bug', color: '#EF4444' }], progress: 30 }
]
},
{
id: 'doing',
title: 'Fazendo',
color: '#F59E0B',
cards: [
{ id: '3', title: 'Refatorar componente de upload', progress: 60, assignees: [{ name: 'Carlos' }] }
]
},
{
id: 'done',
title: 'Pronto',
color: '#10B981',
cards: []
}
]
});Integracao com Factory (PHP)
<div id="kanban-fiscalizacao"
data-island="KanbanBoard"
data-endpoint="/api/kanban/fiscalizacao/<?= $equipe_id ?>">
</div>
<script src="/assets/arenito-islands.js"></script>Fonte de Dados
O componente aceita dados em JSON com arrays de columns contendo cards.
JSON (formato recomendado)
O objeto JSON raiz contem um array columns, onde cada coluna possui um array cards com os itens do board.
{
"title": "Processos de Fiscalizacao",
"view": "classic",
"columns": [
{
"id": "backlog",
"title": "Backlog",
"color": "#6B7280",
"cards": [
{
"id": "card-1",
"title": "Vistoria Lote 42",
"description": "Inspecao de conformidade ambiental do lote",
"labels": [
{ "text": "Urgente", "color": "#EF4444" },
{ "text": "Ambiental", "color": "#10B981" }
],
"progress": 25,
"assignees": [
{ "name": "Ana Silva", "avatar": "/avatars/ana.jpg" }
]
}
]
},
{
"id": "in-progress",
"title": "Em Andamento",
"color": "#3B82F6",
"cards": []
},
{
"id": "review",
"title": "Revisao",
"color": "#8B5CF6",
"cards": []
},
{
"id": "done",
"title": "Concluido",
"color": "#10B981",
"cards": []
}
]
}Mapeamento de campos
| Campo | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
id | string | Sim | Identificador unico da coluna ou card |
title | string | Sim | Titulo da coluna ou card |
color | string | Sim (col) | Cor hexadecimal da barra indicadora da coluna |
cards | array | Sim (col) | Array de cards pertencentes a coluna |
description | string | Nao | Descricao do card (visivel apenas na view Classic) |
labels | array | Nao | Array de objetos { text, color } para badges |
progress | number | Nao | Percentual de progresso do card (0 a 100) |
assignees | array | Nao | Array de objetos { name, avatar } responsaveis |
Dark Mode
O board Kanban adapta automaticamente ao tema escuro via classe .dark.
No dark mode, as colunas e cards ajustam seus fundos e sombras para manter legibilidade e hierarquia visual em fundos escuros.
| Propriedade | Light | Dark |
|---|---|---|
| Board background | --surface-base-neutral-container-default | --surface-base-neutral-container-default |
| Column background | --surface-base-neutral-container-emphasis | --surface-base-neutral-container-emphasis |
| Card background | --surface-base-neutral-container-default | --surface-base-neutral-container-default |
| Card shadow | rgba(0,0,0,0.08) | rgba(0,0,0,0.24) |
| Card dragging shadow | rgba(0,0,0,0.16) | rgba(0,0,0,0.40) |
| Card title color | --text-base-neutral-default | --text-base-neutral-default |
| Card description color | --text-base-neutral-secondary | --text-base-neutral-secondary |
| Column title color | --text-base-neutral-default | --text-base-neutral-default |
| Drag-over background | rgba(59,130,246,0.08) | rgba(59,130,246,0.12) |
| Progress bar track | --border-base-neutral-default | --border-base-neutral-default |
Os tokens semanticos de superficie e texto herdam automaticamente os valores do dark mode. Os labels dos cards mantam suas cores originais em ambos os temas para preservar a identificacao visual.