@chrono-os/admin-ui
v0.42.0
Published
Primitivas de UI de admin neutras (tema light/dark/black OLED + accent escolhível por CSS vars, modos de visualização cards/lista/compacta com preview, átomos tokenizados) com injeção de dependências por context. Consumível por qualquer painel admin — das
Maintainers
Readme
@chrono-os/admin-ui
Primitivas de UI de admin neutras — consumidas por qualquer painel (dashboard unificado, admins individuais, forks white-label) pra que a MESMA tela exista nos dois lados e editar uma reflita na outra (paridade sem-drift).
- Tema por CSS vars: claro/escuro/black OLED (
mode) + accent escolhível (accent) — runtime-switchable, sem rebuild. Cada app injeta o seu preset. - Modos de visualização:
cards/list/compact, com preview da página no tamanho do modo. - CSS próprio (não utilities do Tailwind) → zero purge/
contentno consumer, e o tema troca em runtime.
Setup
// 1. uma vez no app (layout):
import "@chrono-os/admin-ui/styles.css";
// 2. envolva o admin:
import { AdminThemeProvider, ADMIN_THEME_DASHBOARD_DARK } from "@chrono-os/admin-ui";
<AdminThemeProvider {...ADMIN_THEME_DASHBOARD_DARK} storageKey="dash-theme">
{children}
</AdminThemeProvider>O admin individual injeta ADMIN_THEME_NAIRIO_LIGHT (claro); o dashboard, ADMIN_THEME_DASHBOARD_DARK (escuro). Mesmo componente, cores por app.
Seletor de tema + seletor de accent (já suportado)
A UI é só um botão chamando o contexto:
import { useAdminTheme } from "@chrono-os/admin-ui";
const { mode, dark, oled, setMode, accent, setAccent } = useAdminTheme();
// setMode('light' | 'dark' | 'oled' | 'system'); setAccent('#556FFF');<ThemeControls /> já entrega esse seletor pronto (segmented control com os quatro botões: sol, lua, lua-com-estrela, monitor).
São três temas, e o black OLED soma à classe dark — o escopo fica .admin-ui-scope.dark.oled — porque todo o CSS escuro (o daqui e as variantes dark: do seu app) pendura nela. system é preferência de origem, não um quarto tema: resolve por prefers-color-scheme para claro ou escuro, nunca para OLED. Modo desconhecido cai no claro sem lançar.
Se o seu app já mantém o tema na classe do <html>, use useHtmlThemeMode() para ligar os dois (useHtmlDark() continua existindo, mas booleano não distingue escuro de OLED).
Com storageKey, o accent persiste em localStorage. O modo não é persistido pelo provider — de propósito: quem é dono desse estado é o app (todo consumidor de hoje já tem o próprio toggle).
View-mode
import { ViewModeProvider, ViewModeSwitch, useViewMode, PreviewFrame } from "@chrono-os/admin-ui";
<ViewModeProvider storageKey="proposals" defaultMode="cards">
<ViewModeSwitch />
{/* a listagem lê useViewMode().mode e renderiza cards/lista/compacta */}
</ViewModeProvider>Confirmação, paleta de comandos, paginação e ordenação (0.41.0)
import { ConfirmDialog, CommandPalette, useCommandPaletteHotkey, type CommandItem } from "@chrono-os/admin-ui";
<ConfirmDialog open={aberto} title="Remover o link?" confirmLabel="Remover" busy={salvando}
onConfirm={remover} onCancel={() => setAberto(false)}>
<p>Os cliques registrados somem junto.</p>
</ConfirmDialog>
const itens: CommandItem[] = [{ id: "pedidos", label: "Pedidos", hint: "Loja", keywords: "vendas", href: "/admin/orders" }];
useCommandPaletteHotkey(() => setPaleta((v) => !v));
<CommandPalette open={paleta} onClose={() => setPaleta(false)} items={itens} onNavigate={(href) => router.push(href)} />Pagination e SortableTh saem também de @chrono-os/admin-ui/table, entry
sem "use client": num Server Component, importe de lá e passe href como
função e o Link do app em linkComponent.
import Link from "next/link";
import { Pagination, SortableTh } from "@chrono-os/admin-ui/table";
<SortableTh label="Criado em" col="createdAt" sort={{ col: "createdAt", dir: "desc" }}
href={(col, dir) => `?sort=${col}&order=${dir}`} linkComponent={Link} linkProps={{ scroll: false }} />
<Pagination page={2} total={203} pageSize={20} what="pedidos" href={(p) => `?page=${p}`} linkComponent={Link} />Textos têm default pt-BR e trocam por labels. As cores vêm dos --au-* com
fallback; para casar com a marca sem mexer no resto do admin, defina os tokens
no próprio componente (ex.: .au-dialog { --au-accent: …; --au-danger: …; }).
Tokens opcionais: --au-heading, --au-accent-text, --au-accent-hover,
--au-option-active, --au-font-display, --au-radius-lg.
O Modal prende o foco (Tab dá a volta, foco volta à origem ao fechar) e tem ✕
circular desde a 0.41.0.
Estado
0.0.0 — fundação (tema + view-modes). Componentes de domínio (ProposalList/Detail/Form, RedirectList/…, StatsPanel, HistoryTimeline) entram nas próximas fases. Ver Naírio/Plan/03-modulos/2026-06-01_admin-ui-unificado.md.
