UI Kit (Core*)
Os componentes de interface do OonCore — status com vocabulário único, KPIs, tabela de dados responsiva, drawer de detalhe, confirmação, seções de formulário, estados e mais.
Os componentes ficam em @oondemand/oon-core-front e @oondemand/oon-core-front/ui. Use-os em páginas próprias para manter a experiência padrão da Plataforma. Veja-os ao vivo na vitrine de componentes.
import {
CorePageHeader, CoreKpiGrid, CoreDataTable, CoreStatusBadge, CoreDetailDrawer,
CoreConfirmDialog, CoreEmpty, CoreFormSection, CoreTechnicalDetails,
} from "@oondemand/oon-core-front/ui";
Status
<CoreStatusBadge kind="contract" status="vigente" /> {/* "Ativo" · success */}
<CoreStatusBadge kind="charge" status="overdue" /> {/* "Vencida" · danger */}
<CoreStatusBadge label="Personalizado" tone="info" />
coreStatus(kind, status) traduz um estado interno para { label, tone }. Estados internos nunca aparecem como rótulo; desconhecidos ficam neutros.
kind |
Estados reconhecidos → rótulo |
|---|---|
contract |
vigente/ativa → Ativo · pendente → Pendente de ativação · suspensa/bloqueado → Bloqueado · encerrada/expirada/cancelada/revogada → Encerrado |
charge |
aberta → Em aberto · vencida → Vencida · paga → Paga · cancelada → Cancelada |
publication |
publicada → Publicada · cancelada → Cancelada · recovery_required → Em recuperação |
environment |
active → Ativo · provisioning → Em andamento · never_published → Não utilizado · deleted → Excluído |
entity |
ativo → Ativo · pendente/rascunho → Pendente · inativo/arquivado → Inativo |
Tons: success, warning, danger, info, neutral.
KPIs
<CoreKpiGrid
loading={isLoading}
items={[
{ id: "pedidos", label: "Pedidos", value: 128, hint: "últimos 30 dias" },
{ id: "atraso", label: "Em atraso", value: 4, tone: "danger", href: "/pedidos?status=atrasado" },
]}
/>
Tabela de dados
<CoreDataTable<Pedido>
label="Pedidos"
rows={rows}
rowKey={(row) => row._id}
columns={[
{ key: "numero", header: "Número" },
{ key: "fornecedor", header: "Fornecedor", hideOnMobile: true },
{ key: "status", header: "Status", render: (row) => <CoreStatusBadge kind="entity" status={row.status} /> },
]}
search={{ value: busca, onChange: setBusca, placeholder: "Buscar pedido" }}
paging={{ page, pageSize: 20, total, onPage: setPage }}
onRowClick={(row) => setSelecionado(row)}
selectedKey={selecionado?._id}
loading={isLoading}
error={error ? "Não foi possível carregar." : undefined}
empty={<CoreEmpty title="Nenhum pedido" description="Crie o primeiro pedido." />}
/>
Busca, filtros, paginação, linha clicável por mouse e teclado, cartões no celular e estados vazio/carregando/erro.
Drawer de detalhe
<CoreDetailDrawer
open={Boolean(selecionado)}
onClose={() => setSelecionado(null)}
title={selecionado?.numero}
status={<CoreStatusBadge kind="entity" status={selecionado?.status} />}
tabs={[
{ id: "resumo", label: "Resumo", content: <Resumo pedido={selecionado} /> },
{ id: "historico", label: "Histórico", content: <CoreTimeline items={historico} /> },
]}
actions={<OonButton onClick={aprovar}>Aprovar</OonButton>}
/>
Confirmação
<CoreConfirmDialog
open={confirmando}
title="Cancelar pedido?"
effect="O fornecedor será notificado e o pedido não poderá ser reaberto."
confirmLabel="Cancelar pedido"
tone="danger"
busy={salvando}
onConfirm={cancelar}
onClose={() => setConfirmando(false)}
/>
Escreva em effect o efeito real da ação.
Formulário em seções
<CoreFormSection title="Dados de faturamento" description="Usados na emissão da nota." onSave={salvar} saving={salvando}>
<CoreField label="CNPJ"><OonInput value={cnpj} onChange={(e) => setCnpj(e.target.value)} /></CoreField>
</CoreFormSection>
Abas
// Não controlado: o componente guarda a aba selecionada
<CoreTabs items={[
{ id: "geral", label: "Geral", content: <Geral /> },
{ id: "parcelas", label: "Parcelas", content: <Parcelas /> },
]} />
// Controlado: a aba exibida segue `value`
<CoreTabs items={items} value={aba} onChange={setAba} />
Desde a 0.7.36, a aba ativa é marcada por sublinhado brand.solid (só tokens semânticos, legível no tema escuro), o componente funciona sem value/onChange e expõe tablist/tab/tabpanel com navegação por setas, Home e End.
Detalhes técnicos
<CoreTechnicalDetails items={[{ label: "Código", value: error.code }, { label: "Protocolo", value: error.requestId }]} />
Recolhido por padrão, com botão de copiar — ideal para erros com requestId.
Catálogo completo
| Componente | Uso |
|---|---|
CorePageHeader |
Título, descrição e ações da página |
CoreToolbar, CoreActions |
Barras de ação |
CoreKpiGrid |
Grade de indicadores |
CoreSummaryCards |
Cards de resumo com tom |
CoreStatusPanel |
Painel de status com título e ações |
CoreStatusBadge, coreStatus |
Vocabulário único de status |
CoreDataTable |
Tabela responsiva para dados próprios |
CoreDataGrid, CoreCards |
Grid/cards de uma model (via CoreCollection) |
CoreDetailDrawer |
Painel lateral com abas e ações |
CoreConfirmDialog, CoreConfirmAction |
Confirmação de ação |
CoreTabs, CoreStepper, CoreTimeline, CoreActivityLog |
Navegação e histórico |
CoreForm, CoreField, CoreRelationField, CoreFormSection |
Formulários próprios |
CoreEmpty, CoreEmptyState, CoreLoadingState, CoreErrorState |
Estados |
CoreTechnicalDetails |
Detalhes técnicos recolhidos |
CoreOrganizationSwitcher, coreInitials |
Cabeçalho |
OonButton, OonInput, OonSelect, OonCard, OonBadge, OonGrid, OonStack, OonModal, OonDrawer |
Primitives (Chakra UI v3) |