Skip to content

Release: Seven DS frontend migration (develop → master)#68

Merged
aabrius merged 30 commits into
masterfrom
develop
Jun 24, 2026
Merged

Release: Seven DS frontend migration (develop → master)#68
aabrius merged 30 commits into
masterfrom
develop

Conversation

@aabrius

@aabrius aabrius commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Release flow — developmaster

Promove a migração completa do frontend para o Seven Design System (shell + 11 telas) + o fix de tooling do create-bhono, acumulados no develop.

Destaques (25 commits não-merge)

  • Seven DS: @etus/ui@0.4.0-beta.10 / @etus/tokens@0.4.0-beta.8; shell fiel ao single-mode (surface, mode="single", topbar 48px, collapse na sidebar header); 11 telas (ações ligadas, decoração removida, landing component-based, tipografia, cores de status via token).
  • Auditoria: reports de fidelidade por tela em docs/ets/state/reports/screens/ + coverage-matrix.
  • Tooling: create-bhono@etus/bhono: workspace:^ (corrige o 404 de release; link-workspace-packages removido do .npmrc).

⚠️ Efeito do merge (IMPORTANTE)

Sem changesets pendentes, o release.yml no push pro master roda o publish idempotente → vai publicar pela primeira vez no npm:

  • @etus/bhono@0.4.0 (restricted)
  • @etus/create-bhono@0.3.1 (public)

Requer o OIDC Trusted Publisher configurado pra cada pacote no npmjs (org etusdigital, repo bhono, workflow release.yml) — senão o publish falha (sem dano, só não completa).

Verificação

typecheck 0 · ESLint limpo · 226/226 testes do cliente · build · CLI build/test · pnpm install limpo (workspace:).

aabrius and others added 30 commits June 16, 2026 21:51
Foundation: reconcile index.css so @etus/tokens wins (drop colliding
radius/shadow/breakpoint/text tokens, the 88 color palettes, and the
decorative utilities banned by DESIGN.md); load Inter + JetBrains Mono.

Shell: sidebar.tsx becomes AppSidebar built on Seven's Sidebar system
(single mode, collapsible icon, SidebarAvatar); _authenticated.tsx mounts
SidebarProvider + SidebarInset.

Screens: settings/account/team/integrations move to TextInput, Divider,
Switch and Checkbox; main.tsx uses Seven's Toaster; error-boundary uses
Button; loading-skeleton uses SkeletonLoader. The local input, separator,
skeleton and sonner components now have zero consumers.

Validated in the browser. Plan:
docs/plans/2026-06-16-001-migrate-frontend-seven-ds-plan.md
Delete the now-orphaned local UI primitives (input, separator, skeleton,
sonner) - all consumers moved to @etus/seven-react.

Add an ESLint guard-rail: raw button/input/select/textarea are banned in
src/client/routes and the sidebar, pointing to the Seven equivalents
(proven to trigger on a probe file).

Document the "UI = Seven" rule in CLAUDE.md (components, tokens, brand,
guard-rail, validate against seven.etus.io).
The user menu in the sidebar footer never opened: SidebarAvatar does not
forward props, so it could not act as a DropdownMenuTrigger. Use a
SidebarMenuButton (the canonical pattern) instead.

Restore the client test suite after the Seven migration: make the jsdom
ResizeObserver a real constructor and add Radix pointer-capture shims (the
suite errored without them), drop tests for the deleted local primitives,
and update the shell tests (sidebar, authenticated-layout, error-components,
dashboard, integrations) to the new structure. 230 tests pass, coverage 89%.
… components

These screens were already Seven-only but hand-rolled their layouts from Card.
Swap them for the design system's purpose-built components so derived products
compose from Seven rather than rebuilding it:

- dashboard: stat Cards -> DashboardCard (title/value/valueDescription/icon).
  KPICard was rejected: it hides all sub-text when no delta is given, and the
  template's placeholder metrics have no trend data to invent.
- login: centered Card -> split-screen matching Seven's curated /login (form in
  <main>, brand panel in <aside>, mint primary OAuth button). The landmarks also
  restore the <main> that root-layout asserts.
- workspaces: super-admin Card -> Callout variant="success"; empty-state Card ->
  Empty/EmptyMedia/EmptyTitle/EmptyDescription.

Validated each in the browser against the published showcase. 230 client tests
pass unchanged; coverage 89.7%/84.5%/94.3%.
…undle)

Production build measurement: route-splitting already works (/login chunk is
4.6 kB), but every route loads a shared 2.2 MB index chunk because @etus/ui
ships a monolithic 1.7 MB index.js that inlines all components + recharts.
sideEffects:false on the packages + a cleared vite cache produced a
byte-identical build, so consumer-side tree-shaking cannot help. The real fix
is upstream (Seven shipping per-component ESM). Experiments reverted.
The sidebar and login render the logo as a mint rounded-square plate with the
icon; the 404, invite, and landing pages used a bare icon, so the brand mark
looked different depending on the entry point. Use the same plate everywhere.
Includes the bhono-app template mirror.
Audit vs the published showcase: all 11 screens are faithful Seven. One cosmetic
drift was fixed (brand mark on 404/invite/landing). One upstream finding: the
sidebar active item renders mint-strong (the real SidebarMenuButton behavior)
instead of the Figma subtle gray, because Seven only exposes data-mode (which
gates the Figma styling) in dual mode. A data-mode fix was applied to the Seven
working tree; the active-bg cascade residual was handed to the Seven team. Full
writeup: seven/docs/audits/sidebar-single-mode-styling-bug.md.
Seven's app shells separate the header from the content via the content tuck
(rounded-tl border on the inset), not a header border-b. Drop the border-b so
the topbar floats like the Seven reference. Includes the bhono-app template mirror.
From the multi-reviewer pass on the Seven migration:
- test(sidebar): the theme-toggle test now asserts the persisted theme change
  instead of just rendering (was vacuous — Rule 6).
- chore(lint): widen the raw-control guard-rail from routes/** + sidebar.tsx to
  all of src/client/components/** (except icons.tsx) — closes the gap where a raw
  <button> in error-boundary.tsx would pass unguarded.
- refactor: drop the unused SidebarSkeleton (+ its tests) and the dead
  ?? 'dashboard' breadcrumb fallback (this layout never renders at /).
- test(toaster): extract AppToaster to its own module and cover that it forwards
  the resolved theme to Seven's Toaster.
- nits: the user-menu dropdown header shows the name (not a second copy of the
  email); narrow the error/pending layout assertions to the intent class.

typecheck + lint + 226 client tests green; coverage 89.7%/84.6%/94.3%.
feat(ui): adopt Seven design system across the frontend
…evelop

chore: back-merge master into develop (release #64 sync)
Auditoria só-código de cada tela vs @etus/ui@0.4.0-beta.4: componentes,
emitters, cores, espaçamento, tipografia, sizing, estados, superfície não
usada, ações do usuário e estilo classe-a-classe. Consolidado em
coverage-matrix.yaml + sumário executivo.

Fidelidade média ~70%; 53/93 ações ligadas; 4 padrões sistêmicos
(cores de status hardcoded, ações mortas, decoração arbitrária, HTML cru).
Troca a família emerald/amber hardcoded pelos tokens de status do Seven
(--success/--warning + variantes -subtle) em integrations, account,
settings, invite e error-fallback. Remove os overrides dark: (os tokens
-subtle já tratam dark mode). Alinha com os Badge color=success já usados.

Mata ~16 dos ~22 estilos off-system da auditoria; cumpre DESIGN.md
(status via token, não cor crua).
- topbar agora usa o componente <Topbar> (bg surface, =sidebar)
- remove a border-r órfã da sidebar via override unlayered (index.css)
- bump @etus/ui beta.4->beta.10, @etus/tokens beta.3->beta.8 (latest)

typecheck verde; topbar=sidebar=#fafafa verificado no browser.
Implementa fixes dos reports (P2 ações/scaffolding + tipografia + estados):
- scaffolding com handlers stub (toast + TODO): AlertDialog (excluir/remover/
  desconectar/revogar), DropdownMenu (menu de linha do team), Dialog (criar/
  editar webhook), FileUpload (trocar foto)
- tipografia: <h1>/<p> -> Heading/Text; Divider; ErrorPage type=404 (not-found,
  remove text-[12rem] + blobs decorativos)
- ações triviais ligadas: retry no invite, limpar busca (team), voltar (404),
  links mortos -> Link (login Terms/Privacy/Contact)
- login: Button loading/leftIcon/fullWidth; w-[350px] -> max-w-sm
- shell: brand <span> -> Text

lint + typecheck + build verdes; team/landing validados no browser.
Telas que os agentes deixaram incompletas, finalizadas pelo lead:
- dashboard: Heading/Text; CardFooter+Button (drill-down /team /settings
  /account); empty sem border-dashed
- account: 6 botões mortos -> handlers stub (toast); Sign out all + logout
  de sessão -> AlertDialog; h1/h2 -> Heading; descrições -> Text
- landing: remove decoração (backdrop-blur, bg-*/95, bg-muted/50); logo ->
  Link; h1/h2/h3/p -> Heading/Text; FeatureCard/TechBadge component-based

lint + typecheck + build (exit 0) verdes; landing validada no browser.
- 404 (ErrorPage): usa title/description/labels em inglês (consistente com o
  resto do app; o default pt-BR do ErrorPage destoava)
- integrations tests: 'View API Docs' agora é link (asChild>a); Configure abre
  Dialog (não desconecta — bug corrigido); seletor do delete do webhook
  desambiguado do novo botão Disconnect

client: 226/226 testes passando.
…ount/landing

Versões geradas pelos agentes (re-run em worktree isolado), mais fiéis ao DS
que o hand-fix pragmático anterior; team mantido (agente falhou 2x nele):
- dashboard: CardFooter+Button com stub/links; empty sem border
- account: tipografia completa (6 Heading + 23 Text, incl. p's de linha)
- landing: FeaturedIcon (logo+features), Badge pills (tech), Card ghost
  (feature cards); decoração removida

lint + typecheck + build + 226/226 testes verdes.
A versão do agente removeu text-4xl/font-bold do Heading do hero, deixando
só as classes responsivas — sem o tamanho base, o line-height não acompanhava
a fonte e as duas linhas se sobrepunham. Restaura text-4xl font-bold
tracking-tight (base) mantendo o ramp responsivo. Verificado no browser.
Adiciona o polish que a versão (perdida) do agente tinha, à minha versão do team:
- Invite/submit/revoke usam Button leftIcon + loading (em vez de ícone/spinner
  manual + disable)
- loading de membros usa Spinner + Text

lint + typecheck + build + 226/226 testes verdes; verificado no browser.
Sem mode=single o data-mode não era setado, então as classes
group-data-[mode]: do SidebarMenuButton não ativavam — os nav-items
caíam no spacing default do shadcn (gap 8px, radius 8px) em vez dos
tokens Figma (gap 12px, radius 4px) e o ativo ficava mint-forte em vez
do muted do Seven. Com beta.10 (PR #87) o mode=single propaga o
data-mode corretamente.

typecheck + 226/226 testes verdes; medido no browser (gap 12px/radius 4px).
…nt py-6)

O boilerplate estava mais espaçado que o demo de dashboard do Seven (a
referência do shell tucked): topbar 56px->48px (h-12, mantendo bg surface)
e card de conteúdo p-8->px-8 py-6 (24px vertical). Agora bate com o demo.

typecheck + 226 testes verdes; medido no browser (topbar 48px, content py 24px).
…mode)

No Seven single-mode o SidebarTrigger fica na sidebar header, à direita do
logo (não no topbar). Move o trigger do TopbarLeading para o SidebarHeader
(flex row: logo + trigger), escondido quando colapsado ao icon rail. Topbar
fica só com o breadcrumb, como o demo do Seven.

lint + typecheck + build + testes verdes; verificado no browser.
A integrations usava TextInput + ícone search absolute + pl-9 (padrão manual);
o team já usa o componente SearchInput do Seven. Alinha p/ SearchInput com
onClear/showClearButton. 33/33 testes da integrations passando.
feat(ui): full Seven DS migration of the frontend (shell + 11 screens)
@aabrius aabrius merged commit 51c2856 into master Jun 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants