Skip to content
Extensões

Kanban Board

Board drag-and-drop com colunas configuraveis, cards com progresso/labels/responsaveis, views Minimal/Classic e reordenacao entre colunas. Componente React Island.

components/kanban-board.cssislands/src/islands/KanbanBoard/Abrir no Figma

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-props no container. O componente faz fetch automatico ao montar.
  • Inline data — Dados passados diretamente no atributo data-props como JSON serializado, sem fetch externo.
  • Programmatic — Monta a ilha manualmente via ArenitoIslands.mount() passando o elemento container e as props como objeto JavaScript.
Este e um React Island que requer o script arenito-islands.js carregado na pagina. Sem o script, o container permanece vazio. O bundle inclui o sistema de drag-and-drop baseado na HTML5 Drag API.

Exemplos

Veja abaixo os exemplos interativos do board Kanban, incluindo views Minimal e Classic, drag-and-drop e cards com progresso.

Carregando exemplo...

Anatomia

Estrutura interna do componente e seus elementos.

ParteElementoDescricao
Container.kanban-boardWrapper principal com overflow-x auto e width 100%
Header.kanban-board__headerCabecalho com titulo e controles de view
Titulo.kanban-board__titleHeading do board, Space Grotesk 18px w600
View Toggle.kanban-board__view-toggleGrupo de botoes para alternar views
View Btn.kanban-board__view-btnBotao de view, Inter 13px w500
Columns.kanban-board__columnsFlex row com gap 16px e scroll horizontal
Column.kanban-board__columnColuna individual, min-width 280px, border-radius 8px
Column Header.kanban-board__column-headerCabecalho da coluna com titulo e contador
Column Title.kanban-board__column-titleTitulo da coluna, Inter 14px w600
Column Count.kanban-board__column-countBadge numerico com total de cards
Column Color.kanban-board__column-colorBarra de cor 4px no topo da coluna
Column Body.kanban-board__column-bodyDrop zone dos cards com min-height 120px
Card.kanban-board__cardCard arrastavel com padding 12px e shadow
Card Title.kanban-board__card-titleTitulo do card, Inter 13px w600
Card Desc.kanban-board__card-descriptionDescricao, Inter 12px, max 2 linhas com ellipsis
Card Labels.kanban-board__card-labelsFlex wrap de labels coloridos
Card Progress.kanban-board__card-progressBarra de progresso 4px com border-radius
Card Assignees.kanban-board__card-assigneesAvatares empilhados no rodape do card
Vazio.kanban-board__emptyEstado 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.

AspectoMinimalClassic
Card heightCompacto, apenas titulo e labelsExpandido com descricao, progresso e assignees
DescricaoOcultaVisivel, max 2 linhas com text-overflow
ProgressoOcultoBarra de progresso horizontal visivel
AssigneesOcultosAvatares empilhados no rodape
LabelsDots coloridos 8x8 sem textoBadges com texto e cor de fundo
DensityMais cards visiveis por colunaMenos 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:

  1. O card recebe draggable="true" e no dragstart armazena o cardId e sourceColumnId no dataTransfer.
  2. As colunas escutam dragover (com preventDefault() para permitir o drop) e adicionam o modificador --drag-over para feedback visual.
  3. No drop, o componente le os dados do dataTransfer, move o card no state interno e dispara o CustomEvent arenito:kanban:card-moved.
  4. O card em arraste recebe o modificador --dragging com opacity: 0.5 e 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.

EventodetailQuando 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
js
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.

PropriedadeTipoDefaultDescrição
.kanban-boardclasseContainer principal do board com overflow-x auto.
.kanban-board__headerclasseCabecalho do board com titulo e controles de view.
.kanban-board__titleclasseTitulo do board (18px w600, font-heading).
.kanban-board__view-toggleclasseGrupo de botoes para alternar entre views Minimal e Classic.
.kanban-board__view-btnclasseBotao individual de view (13px w500).
.kanban-board__view-btn--activeclasseModificador para view ativa (background brand, texto branco).
.kanban-board__columnsclasseFlex row das colunas com gap 16px e scroll horizontal.
.kanban-board__columnclasseColuna individual com min-width 280px e border radius 8px.
.kanban-board__column-headerclasseCabecalho da coluna com titulo, contador e cor indicadora.
.kanban-board__column-titleclasseTitulo da coluna (14px w600).
.kanban-board__column-countclasseBadge com contagem de cards na coluna.
.kanban-board__column-colorclasseBarra de cor 4px no topo da coluna.
.kanban-board__column-bodyclasseArea de drop dos cards com min-height 120px.
.kanban-board__column-body--drag-overclasseModificador visual quando um card e arrastado sobre a coluna.
.kanban-board__cardclasseCard individual arrastavel com padding 12px e shadow.
.kanban-board__card--draggingclasseModificador para card sendo arrastado (opacity 0.5, shadow elevado).
.kanban-board__card-titleclasseTitulo do card (13px w600).
.kanban-board__card-descriptionclasseDescricao do card (12px, texto secundario, max 2 linhas).
.kanban-board__card-labelsclasseFlex wrap de labels coloridos no card.
.kanban-board__card-labelclasseLabel individual (badge pequeno com cor de fundo).
.kanban-board__card-progressclasseBarra de progresso horizontal no card (height 4px).
.kanban-board__card-progress-fillclasseFill da barra de progresso com largura percentual.
.kanban-board__card-assigneesclasseGrupo de avatares empilhados no rodape do card.
.kanban-board__card-assigneeclasseAvatar individual 24x24 com margin-left negativo para sobreposicao.
.kanban-board__emptyclasseEstado vazio com borda tracejada e texto centralizado.

Codigo

Snippets prontos para copiar e usar no seu projeto.

HTML com data-island e data-props

html
<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()

js
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)

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.

json
{
  "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

CampoTipoObrigatorioDescricao
idstringSimIdentificador unico da coluna ou card
titlestringSimTitulo da coluna ou card
colorstringSim (col)Cor hexadecimal da barra indicadora da coluna
cardsarraySim (col)Array de cards pertencentes a coluna
descriptionstringNaoDescricao do card (visivel apenas na view Classic)
labelsarrayNaoArray de objetos { text, color } para badges
progressnumberNaoPercentual de progresso do card (0 a 100)
assigneesarrayNaoArray 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.

PropriedadeLightDark
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 shadowrgba(0,0,0,0.08)rgba(0,0,0,0.24)
Card dragging shadowrgba(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 backgroundrgba(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.

Design System interno do GALES