migração v2 para v3
Passo a passo para atualizar sua aplicação da v2 para a v3 do Design System.
índice
- Migração assistida por agente
- Resumo dos breaking changes
- 1. Imports de CSS obrigatórios
- 2. Configure o bundler para importar CSS
- 3. Theming via data-ds-theme
- 4. Aplicações com styled-components próprio
- 5. Deep imports pararam de funcionar
- 6. Chart movido para subpath
- 7. Objeto de tema
- 8. Testes
- 9. Alinhe as versões de todos os pacotes
- 10. Module Federation
- Checklist
A v3 remove as dependências de styled-components e @radix-ui. Os estilos
passam a ser distribuídos como arquivos CSS estáticos e o theming acontece via
CSS custom properties, aplicadas pelo atributo data-ds-theme.
Esta página cobre todos os breaking changes e o passo a passo da atualização. Para projetos novos, consulte direto a documentação dos componentes e dos tokens.
Migração assistida por agente
O repositório do Design System publica um plugin do Claude Code com uma skill que executa essa migração no seu projeto. Instale o marketplace do repositório e peça ao agente para migrar o projeto para a v3.
# via SSH
/plugin marketplace add [email protected]:frontend-platform/olist-design-system.git
# via HTTPS
/plugin marketplace add https://gitlab.olist.io/frontend-platform/olist-design-system.git
/plugin install migrate-olist-ds-v3A skill aplica as mudanças mecânicas (versões, imports de CSS, subpaths, deep
imports, ajustes de teste), roda typecheck e build, e reporta separadamente o
que exige decisão humana, como seletores afetados pelo wrapper do
ThemeProviderV2 e layouts responsivos em SSR.
Depois de instalado, peça a migração num prompt:
Migre este projeto do @olist/design-system da v2 para a v3.Ou apenas cite a skill:
/migrate-olist-ds-v3Resumo dos breaking changes
| Mudança | Impacto |
|---|---|
styled-components e @radix-ui removidos | Menos dependências transitivas; sem ThemeProvider do styled-components |
| Imports de CSS agora obrigatórios | Adicionar imports na entrada da aplicação |
Theming via data-ds-theme | Temas não-padrão exigem import de CSS adicional |
Brands alpha, beta, rebrand, fbo e vnda removidos | Migre para o brand base olist |
Brand tiny renomeado para erp | Trocar themes.tiny por themes.erp e o CSS do tema |
ThemeProviderV2 opcional no tema padrão | Com olist/base, os imports de CSS são suficientes |
ThemeProviderV2 renderiza um wrapper | Pode afetar seletores CSS e testes que dependem da árvore DOM |
Chart movido para @olist/design-system/chart | Ajustar import e instalar peers opcionais |
| Snapshots de testes mudam | CSS do styled-components não é mais serializado |
1. Imports de CSS obrigatórios
Os estilos não são mais injetados em runtime. É obrigatório importar os
arquivos CSS uma única vez na entrada da aplicação (_app.tsx, main.tsx,
index.tsx):
// tokens (variáveis CSS) — sempre obrigatório
import '@olist/design-system-tokens/css/index.css';
// estilos dos componentes — obrigatório se usa @olist/design-system
import '@olist/design-system/styles.css';
// estilos dos templates — obrigatório se usa @olist/templates
import '@olist/templates/dist/styles.css';O index.css inclui apenas os tokens primitivos e o tema olist/base. Se a
aplicação usa outro tema, importe também o CSS dele:
import '@olist/design-system-tokens/css/themes/erp/base.css';Sem esses imports os componentes renderizam sem estilo nenhum.
2. Configure o bundler para importar CSS
Importar CSS de node_modules não funciona por padrão em todo bundler, e até a
v2 o Design System nunca exigiu isso. Ajuste conforme a stack:
webpack (Module Federation, SPAs custom): sem loader de CSS o build quebra
com Module parse failed: Unexpected character no primeiro .css.
npm i -D style-loader css-loader// webpack.config.js — dentro de module.rules
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }Next.js: import de CSS global só é permitido em pages/_app.tsx ou no root
layout do App Router.
Vite e CRA: já suportam import de CSS sem configuração extra.
Para verificar, procure as variáveis --ds-* no bundle final
(grep -rl "ds-color" dist/). Se não aparecem, o CSS não está sendo incluído.
3. Theming via data-ds-theme
O tema padrão olist/base é declarado em :root, então com os imports de CSS
ele não exige provider. Para selecionar outro tema, o ThemeProviderV2 aplica o
atributo data-ds-theme="<brand>-<variation>":
import { ThemeProviderV2 } from '@olist/design-system';
import { themes } from '@olist/design-system-tokens';
const App = () => (
<ThemeProviderV2 theme={themes.erp.base} themeName="erp" variation="base">
...
</ThemeProviderV2>
);Brands disponíveis: olist, erp e erp-dark. Para qualquer brand diferente
de olist, importe o CSS do tema correspondente, como descrito na seção
anterior.
Os brands
alpha,beta,rebrand,fboevndaforam descontinuados nesta major e não existem mais nos pacotes de tokens: quem usava algum deles deve migrar para o brand baseolist. O brandtinyfoi renomeado paraerp(etiny-darkparaerp-dark), entãothemes.tinypassa a serthemes.erp,themes.tinyDarkpassa a serthemes.erpDarke o CSS sai decss/themes/tiny/base.cssparacss/themes/erp/base.css.
O ThemeProviderV2 agora renderiza um elemento div ao redor dos filhos para
carregar o atributo. Ele usa display: contents e não afeta o layout, mas existe
na árvore DOM: seletores CSS, queries de teste e snapshots que dependiam da
estrutura exata podem precisar de ajuste.
4. Aplicações com styled-components próprio
Este é o breaking change mais fácil de passar despercebido. Na v2 o
ThemeProviderV2 era, por baixo, o ThemeProvider do styled-components, e isso
tinha dois efeitos dos quais muitas aplicações dependiam sem saber: qualquer
styled.div da própria aplicação conseguia ler props.theme.olist.*, e o tipo
DefaultTheme era estendido para tipar theme.olist.
Na v3 nada disso acontece. Se a aplicação tem styled-components próprio lendo
theme.olist.*, o theme chega vazio em runtime e o typecheck acusa
Property 'olist' does not exist on type 'DefaultTheme'.
A correção é importar o ThemeProviderV2 do subpath de compatibilidade, que
injeta o tema no contexto do styled-components e repõe o augment de tipo:
// antes (v2)
import { ThemeProviderV2 } from '@olist/design-system';
import theme from '@olist/design-system-tokens/themes/olist/base';
export function AppProviders({ children }) {
return <ThemeProviderV2 theme={theme}>{children}</ThemeProviderV2>;
}
// depois (v3)
import { ThemeProviderV2 } from '@olist/design-system/styled-components';
import theme from '@olist/design-system-tokens/themes/olist/base';
export function AppProviders({ children }) {
return <ThemeProviderV2 theme={theme}>{children}</ThemeProviderV2>;
}Use o mesmo import no wrapper de testes para que os testes também recebam o
tema. styled-components é uma peer dependency opcional: o subpath só o
referencia quando importado, então quem não usa styled-components continua sem a
dependência.
Se a aplicação tinha styled-components apenas por causa do Design System, ela
pode ser removida:
yarn remove styled-components5. Deep imports pararam de funcionar
O @olist/design-system passou a declarar o campo exports no package.json.
Caminhos internos como @olist/design-system/dist/esm/components/.../Algo.js
agora são bloqueados pelo bundler
(Package path ./dist/esm/... is not exported), o layout interno do dist mudou
por causa dos CSS Modules e alguns símbolos deixaram de existir, como o
AccordionChevronIcon.
Migre para a API pública (import { X } from '@olist/design-system') ou, se
dependia de primitivas internas não exportadas, internalize uma cópia própria.
6. Chart movido para subpath
// antes (v2)
import { Chart } from '@olist/design-system';
// depois (v3)
import { Chart } from '@olist/design-system/chart';As dependências dele viraram peer dependencies opcionais, instaladas só por quem usa o componente:
yarn add @mui/x-charts @mui/material @emotion/react @emotion/styledQuem não usa o Chart deixa de carregar MUI e Emotion no bundle.
7. Objeto de tema
O hook useTheme() continua retornando o shape { olist: tokens }, então o
acesso a tokens em JavaScript segue funcionando. Os internals do objeto mudaram
(ele não é mais o objeto de tema do styled-components), então código que dependia
de propriedades internas ou da identidade do objeto pode precisar de ajuste. Para
metadados do tema atual, use o novo hook useDesignSystemTheme(), que expõe
{ themeName, variation, tokens, theme }.
Os tokens de tema borderRadius.circle e borderRadius.pill deixaram de
referenciar os tokens primitivos e passaram a ser os valores literais 50% e
9999px. Quem sobrescrevia esses primitivos esperando que o tema seguisse a
referência precisa sobrescrever o token de tema.
8. Testes
Snapshots que serializavam o CSS do styled-components vão mudar, já que os
componentes usam classes de CSS Modules e variáveis CSS. Atualize os snapshots e
remova serializers como o jest-styled-components.
O Design System trata a ausência de matchMedia no jsdom com fallback para o
valor base, então os testes não quebram por isso. Se os seus testes asserem
comportamento por breakpoint, mocke window.matchMedia:
// jest.setup.ts
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
addListener: jest.fn(),
removeListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});9. Alinhe as versões de todos os pacotes
Atualize todos os pacotes do Design System juntos para a v3
(@olist/design-system, -tokens, -icons, @olist/styled-system,
@olist/templates). Eles se referenciam entre si e misturar v2 com v3 causa
instâncias duplicadas no node_modules.
Atenção a pacotes olist de terceiros que dependem do Design System como peer
dependency, como o @olist/react-commons. Se eles ainda apontam para a v2, o
gerenciador pode instalar uma segunda cópia. O sintoma típico é um erro de tipos
que parece não fazer sentido, porque existem duas definições do mesmo tipo:
Type 'ResponsiveValue<SpacingValues>' is not assignable to type 'SpacingValues'.10. Module Federation
Se você compartilha os pacotes do Design System em shared, garanta que o
requiredVersion seja um semver publicado (^3.0.0) e que a versão seja
singleton entre host e remotes. Um requiredVersion inválido, como um caminho
file: usado em testes locais, faz o webpack tratar o próprio pacote como módulo
e o build quebra.
Checklist
- Atualize todos os pacotes
@olist/*para a v3 de uma vez e verifique que não há instância v2 duplicada. - Configure o bundler para importar CSS e adicione os imports na entrada da aplicação.
- Se a aplicação usa styled-components próprio, troque o import do
ThemeProviderV2pelo subpath de compatibilidade, inclusive nos testes. - Substitua deep imports de internals por API pública ou cópia internalizada.
- Remova
styled-componentsapenas se ele existia só por causa do Design System. - Ajuste o import do
Charte instale os peers opcionais, se usar o componente. - Rode
typecheckebuild: o build pega deep imports que o typecheck não pega. - Atualize snapshots de testes.
- Valide visualmente a aplicação, principalmente temas não-padrão.