@1doc/1ds-react 0.0.2 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/CHANGELOG.md +659 -0
  2. package/README.md +137 -6
  3. package/package.json +43 -28
  4. package/src/index.ts +161 -16
  5. package/src/teste/AttachmentCard.test.tsx +161 -0
  6. package/src/teste/Chart.test.tsx +233 -0
  7. package/src/teste/Combobox.test.tsx +251 -0
  8. package/src/teste/DataTable.test.tsx +70 -0
  9. package/src/teste/DatePicker.test.tsx +86 -0
  10. package/src/teste/Drawer.test.tsx +265 -0
  11. package/src/teste/Dropdown.test.tsx +217 -0
  12. package/src/teste/Input.test.tsx +64 -0
  13. package/src/teste/Kanban.test.tsx +333 -0
  14. package/src/teste/MultiSelect.test.tsx +73 -0
  15. package/src/teste/Podium.test.tsx +107 -0
  16. package/src/teste/Popover.test.tsx +221 -0
  17. package/src/teste/SegmentedControl.test.tsx +183 -0
  18. package/src/teste/Timeline.test.tsx +100 -0
  19. package/src/teste/Tree.test.tsx +74 -0
  20. package/src/teste/setup.ts +7 -0
  21. package/src/utils/bandeiras.ts +22 -0
  22. package/src/utils/chart.ts +682 -0
  23. package/src/utils/density.ts +27 -0
  24. package/src/utils/overlay-stack.ts +26 -0
  25. package/src/utils/theme.ts +63 -47
  26. package/src/utils/toast.ts +89 -0
  27. package/vitest.config.ts +28 -0
  28. package/dist/components/Alert/Alert.css +0 -188
  29. package/dist/components/Alert/Alert.d.ts +0 -65
  30. package/dist/components/Alert/Alert.js +0 -56
  31. package/dist/components/Avatar/Avatar.css +0 -88
  32. package/dist/components/Avatar/Avatar.d.ts +0 -34
  33. package/dist/components/Avatar/Avatar.js +0 -16
  34. package/dist/components/Avatar/AvatarGroup.d.ts +0 -12
  35. package/dist/components/Avatar/AvatarGroup.js +0 -8
  36. package/dist/components/Badge/Badge.css +0 -155
  37. package/dist/components/Badge/Badge.d.ts +0 -46
  38. package/dist/components/Badge/Badge.js +0 -17
  39. package/dist/components/Button/Button.css +0 -199
  40. package/dist/components/Button/Button.d.ts +0 -23
  41. package/dist/components/Button/Button.js +0 -62
  42. package/dist/components/Checkbox/Checkbox.css +0 -122
  43. package/dist/components/Checkbox/Checkbox.d.ts +0 -21
  44. package/dist/components/Checkbox/Checkbox.js +0 -49
  45. package/dist/components/Divider/Divider.css +0 -81
  46. package/dist/components/Divider/Divider.d.ts +0 -18
  47. package/dist/components/Divider/Divider.js +0 -26
  48. package/dist/components/Grid/Grid.css +0 -154
  49. package/dist/components/Grid/Grid.d.ts +0 -21
  50. package/dist/components/Grid/Grid.js +0 -53
  51. package/dist/components/Icon/Icon.css +0 -55
  52. package/dist/components/Icon/Icon.d.ts +0 -13
  53. package/dist/components/Icon/Icon.js +0 -41
  54. package/dist/components/Input/Input.css +0 -190
  55. package/dist/components/Input/Input.d.ts +0 -32
  56. package/dist/components/Input/Input.js +0 -58
  57. package/dist/components/Link/Link.css +0 -76
  58. package/dist/components/Link/Link.d.ts +0 -15
  59. package/dist/components/Link/Link.js +0 -19
  60. package/dist/components/Logo/Logo.css +0 -32
  61. package/dist/components/Logo/Logo.d.ts +0 -10
  62. package/dist/components/Logo/Logo.js +0 -16
  63. package/dist/components/Modal/Modal.css +0 -155
  64. package/dist/components/Modal/Modal.d.ts +0 -36
  65. package/dist/components/Modal/Modal.js +0 -55
  66. package/dist/components/Radio/Radio.css +0 -114
  67. package/dist/components/Radio/Radio.d.ts +0 -19
  68. package/dist/components/Radio/Radio.js +0 -39
  69. package/dist/components/Select/Select.css +0 -291
  70. package/dist/components/Select/Select.d.ts +0 -38
  71. package/dist/components/Select/Select.js +0 -246
  72. package/dist/components/Spinner/Spinner.css +0 -60
  73. package/dist/components/Spinner/Spinner.d.ts +0 -16
  74. package/dist/components/Spinner/Spinner.js +0 -16
  75. package/dist/components/Switch/Switch.css +0 -127
  76. package/dist/components/Switch/Switch.d.ts +0 -18
  77. package/dist/components/Switch/Switch.js +0 -57
  78. package/dist/components/Tabs/Tab.d.ts +0 -19
  79. package/dist/components/Tabs/Tab.js +0 -76
  80. package/dist/components/Tabs/TabContent.d.ts +0 -15
  81. package/dist/components/Tabs/TabContent.js +0 -11
  82. package/dist/components/Tabs/Tabs.css +0 -124
  83. package/dist/components/Tabs/Tabs.d.ts +0 -20
  84. package/dist/components/Tabs/Tabs.js +0 -14
  85. package/dist/components/Tabs/TabsContent.d.ts +0 -16
  86. package/dist/components/Tabs/TabsContent.js +0 -12
  87. package/dist/components/Tabs/tabs.context.d.ts +0 -2
  88. package/dist/components/Tabs/tabs.context.js +0 -2
  89. package/dist/components/Tag/Tag.css +0 -140
  90. package/dist/components/Tag/Tag.d.ts +0 -63
  91. package/dist/components/Tag/Tag.js +0 -48
  92. package/dist/components/Text/Text.css +0 -1213
  93. package/dist/components/Text/Text.d.ts +0 -70
  94. package/dist/components/Text/Text.js +0 -89
  95. package/dist/components/Textarea/Textarea.css +0 -133
  96. package/dist/components/Textarea/Textarea.d.ts +0 -28
  97. package/dist/components/Textarea/Textarea.js +0 -72
  98. package/dist/index.d.ts +0 -25
  99. package/dist/index.js +0 -27
  100. package/dist/utils/theme.d.ts +0 -30
  101. package/dist/utils/theme.js +0 -106
package/CHANGELOG.md CHANGED
@@ -1,5 +1,664 @@
1
1
  # @1doc/1ds-react
2
2
 
3
+ ## 2.7.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 89150e3: fix(alto-contraste): superfícies sobrepostas ganham borda no tema de alto contraste
8
+
9
+ No `1doc-high-contrast` a página e as superfícies flutuantes são pretas e a
10
+ sombra (preta) não aparece: Modal, ConfirmDialog, Drawer, BottomSheet e
11
+ Tooltip não tinham borda visível. Agora ganham um traço branco
12
+ (`--umds-semantic-color-neutral-light-down`, a borda de campo do tema), em
13
+ outline para dentro — não muda o tamanho de nenhuma superfície.
14
+
15
+ Quem já tinha traço, mas apagado neste tema, passa à mesma borda branca: o
16
+ tooltip do Chart e os painéis do TimePicker e do PhoneInput (#5A5A5A), o
17
+ painel do AILabel (`ai-light`, quase preto) e o Toast `neutral` (sem traço —
18
+ e que também ganha a cor de texto do tema: herdava a do body e saía preto
19
+ sobre preto).
20
+ As barras que flutuavam só com sombra — rodapé do Drawer e do BottomSheet e a
21
+ BottomNavigation `raised` — ganham uma linha no topo.
22
+
23
+ O fechar do Alert e do Toast deixa de nascer esmaecido neste tema, e o realce
24
+ de hover do fechar do Alert acompanha a cor do texto.
25
+
26
+ Tudo escopado em `[data-theme="1doc-high-contrast"]`: os outros 12 temas não
27
+ mudam. Nenhum token novo.
28
+
29
+ - fe1ba4f: **Chart:** a ponta da barra passa do raio de 4px (fora da escala) para o raio
30
+ canônico do DS, 8px (`--umds-primitive-border-radius-sm`), limitado a metade da
31
+ largura e da altura da barra — barra fina não vira pílula e barra curta não
32
+ estoura a linha de base. Continua arredondada só na ponta do dado, inclusive
33
+ nas negativas. A dica do gráfico troca o respiro de 12px por 8px/16px, da
34
+ escala oficial. Os literais de largura mínima que batiam com um token de
35
+ espaçamento passam a usá-lo (mesmo valor, sem mudança visual).
36
+ - 5fcde30: fix(kanban): borda da coluna acima do limite usa o token de negativo direto
37
+
38
+ A borda da coluna acima do limite de WIP passa de `color-mix(... negative-pure 40%, transparent)`
39
+ para `var(--umds-semantic-color-feedback-negative-pure)`, sem mistura. Contraste da borda contra
40
+ o fundo da coluna: 6.41:1 (1doc), 4.65:1 (1doc-dark), 6.62:1 (1doc-high-contrast) — antes
41
+ ficava entre 1.7:1 e 2.1:1, abaixo do mínimo de 3:1. O fundo da coluna destacada durante o
42
+ arrasto passa a usar `primary-light` direto. Comentários "candidato a novo token" reescritos:
43
+ o 1DS não cria tokens novos; os literais restantes são intencionais.
44
+
45
+ ## 2.7.0
46
+
47
+ ### Minor Changes
48
+
49
+ - 14108ac: feat(chart): BarChart, LineChart e DonutChart — gráficos em SVG puro
50
+
51
+ Família nova de gráficos, sem biblioteca externa: o Mitosis desenha o SVG e o
52
+ resultado é o mesmo no React e no Vue.
53
+
54
+ - `BarChart` — barras verticais, com séries agrupadas lado a lado e suporte a
55
+ valores negativos (a barra arredonda na ponta do dado, nunca na base).
56
+ - `LineChart` — uma ou mais séries; `null` interrompe a linha em vez de cair a
57
+ zero; pontos opcionais (`showPoints`) e, na categoria em foco, uma linha
58
+ vertical marcando o ponto.
59
+ - `DonutChart` — partes de um todo com o total no centro e legenda com valor e
60
+ percentual em texto. Mais de 5 partes: o excedente vira "Outros", em neutro.
61
+
62
+ API comum: `data` (`[{ label, value }]`) ou `series` + `labels`, `title`,
63
+ `ariaLabel`, `valueFormatter` ou `unit`, `showLegend`, `showGrid`, `height`,
64
+ `emptyText`.
65
+
66
+ Cores só de tokens semânticos, numa ordem fixa de até 5 séries — primary, info,
67
+ primary-dark, primary-medium, ai — escolhida com o validador de daltonismo nos
68
+ temas 1doc e 1doc-dark. O tema escuro vem dos próprios tokens. A largura
69
+ acompanha o contêiner, então o texto dos eixos fica sempre em 12px.
70
+
71
+ Acessibilidade: resumo no `role="img"`, tabela visualmente oculta com todos os
72
+ números, e cada categoria é focável — Tab entra, setas andam, Esc fecha o
73
+ tooltip. Respeita `prefers-reduced-motion`.
74
+
75
+ - eb9927c: feat(kanban): quadro de colunas com cartões que se movem por arrasto e por teclado
76
+
77
+ Três componentes novos: `Kanban` (o quadro), `KanbanColumn` (título, contagem,
78
+ limite de WIP, corpo que rola, rodapé com "Adicionar cartão") e `KanbanCard`
79
+ (etiquetas, título, descrição, metadado, responsável).
80
+
81
+ O `Kanban` é orientado a dados e controlado: recebe `columns` e chama
82
+ `onCardMove({ cardId, fromColumnId, fromIndex, toColumnId, toIndex })` — o
83
+ `toIndex` já desconta a saída do cartão da origem, é o índice de `splice`
84
+ direto. Move-se arrastando (HTML5 Drag and Drop nativo, com linha de soltura)
85
+ ou pelo teclado: Espaço pega, setas movem com prévia na tela, Espaço ou Enter
86
+ soltam, Esc cancela, e cada passo é anunciado numa região `aria-live`. O quadro
87
+ é uma parada só de Tab (roving tabindex).
88
+
89
+ - 8bff8c5: feat(podium): os três primeiros de um ranking num pódio
90
+
91
+ Componente novo. O 1º fica no centro, no degrau mais alto; o 2º à esquerda e o
92
+ 3º à direita. Com `showRest`, do 4º em diante vira uma lista numerada abaixo.
93
+
94
+ A ordem visual (2º, 1º, 3º) é posta pelo CSS Grid, por área: o DOM e o leitor
95
+ de tela seguem 1º, 2º, 3º, e cada lugar tem uma frase acessível completa
96
+ ("1º lugar: Ana Paula, 128 pontos"). Os itens chegam já ordenados.
97
+
98
+ O 1DS não tem ouro, prata e bronze: os degraus usam `feedback-info`, `neutral`
99
+ e `primary` até existir um token de medalha.
100
+
101
+ - 70dc082: feat(tokens): tema de alto contraste `1doc-high-contrast`
102
+
103
+ Novo `theme-1doc-high-contrast.css`, ativado com
104
+ `data-theme="1doc-high-contrast"`: fundo preto, texto branco e cor interativa
105
+ amarela (`#FFFF00`) — links, botões, foco e selecionado —, com texto preto
106
+ sobre o amarelo cheio. Define as mesmas 29 variáveis `--umds-theme-*` dos
107
+ outros temas, então nenhum token cai no valor do tema padrão.
108
+
109
+ Todo texto passa WCAG AAA (7:1) contra o fundo, e toda fronteira de componente
110
+ passa 3:1. A tabela de contraste está no README de `@1doc/1ds-tokens`.
111
+
112
+ `Theme` (core/react/vue) ganha `"1doc-high-contrast"`, e `setTheme`,
113
+ `getTheme` e `getAvailableThemes` passam a aceitá-lo. O DS não liga o tema
114
+ sozinho: o README mostra como o produto pode seguir
115
+ `prefers-contrast: more`. Os 12 temas existentes não mudam.
116
+
117
+ ### Patch Changes
118
+
119
+ - ffaa5c0: fix(dropdown): no Vue o menu não abria — e mais 9 componentes com a mesma causa
120
+
121
+ Clicar no gatilho do `Dropdown` no Vue não renderizava nada, `mounted` voltava a
122
+ `false`, e não havia erro nenhum no console. No React funcionava.
123
+
124
+ `open` era tipada `boolean`. O Vue aplica _boolean casting_: prop booleana
125
+ ausente chega como `false`, não como `undefined`. Com isso
126
+ `isControlled = props.open !== undefined` nascia **verdadeiro** mesmo sem
127
+ ninguém passar `open`, o `toggle()` montava o menu, e no `onUpdate` seguinte o
128
+ `syncOpenState()` via `!!props.open === false` contra `lastOpen === true` e
129
+ chamava `close()` — fechando o menu no mesmo tick em que ele abriu.
130
+
131
+ É o defeito de `.agent/troubleshooting/vue-boolean-prop-default.md`, o mesmo do
132
+ `SidePanel` e do `Popover`. Como já era a terceira reincidência, esta correção
133
+ varre a família inteira em vez de um componente por vez.
134
+
135
+ **Além de `!== false`, `=== false` é o mesmo defeito em espelho** — e era o mais
136
+ caro dos três: `if (props.closeOnEsc === false) return;` nasce verdadeiro no
137
+ Vue, e o Escape simplesmente parava de fechar `Modal`, `ConfirmDialog` e
138
+ `BottomSheet`. O grep original da dívida não pegava essa forma.
139
+
140
+ Passam a ser `any`, com o porquê comentado em cada `.lite.tsx`:
141
+ `Dropdown.open` · `AppHeader.bordered` · `AppSidebar.toggleable` ·
142
+ `BottomNavigation.fixed` ·
143
+ `BottomSheet.grabber`/`closable`/`closeOnEsc`/`closeOnBackdrop` ·
144
+ `ConfirmDialog.closeOnEsc` · `Modal.closeOnEsc`/`closeOnOverlayClick` ·
145
+ `Pagination.showPrevNext` · `ProgressBar.animated` · `Toast.closable`.
146
+
147
+ Ficam `boolean` de propósito os `open` de `Modal`, `ConfirmDialog`, `Toast` e
148
+ `BottomSheet`: são totalmente controlados, sem estado interno, e prop ausente
149
+ significando "fechado" é o comportamento certo.
150
+
151
+ `Dropdown.restoreFocus` e `Popover.restoreFocus`, que a dívida listava, eram
152
+ falso positivo — são parâmetro de função, não prop.
153
+
154
+ **A baseline visual do Vue estava gravada COM o bug**, e é a prova mais forte de
155
+ que a correção pega: a esteira reprovou 22 stories, todas de componentes desta
156
+ correção, e o que mudou foi o que passou a aparecer. A `Pagination/SinglePage`
157
+ era 80×80 com só o número "1"; agora é 302×84, com "Anterior" e "Próxima" de
158
+ volta. O rodapé do `AppSidebar` ganhou o botão de alternar. O `AppHeader`,
159
+ a borda. A `ProgressBar`, a listra.
160
+
161
+ O React não mexeu um pixel — 415/415 iguais, no Windows e no runner Linux —,
162
+ que é o esperado: lá nunca houve defeito. Só a baseline de `vue/linux` foi
163
+ regravada, e só as 22 imagens que de fato mudaram, para não sujar o MR com PNG
164
+ idêntico (o Chromium não é byte a byte determinístico).
165
+
166
+ O preço de tirar o `boolean` é que `<Dropdown open>` num template Vue passa a
167
+ entregar a string vazia, que é falsy. `Dropdown` e `Popover` passam a tratar o
168
+ `""`, como o `Drawer` já fazia.
169
+
170
+ E no `Dropdown`, dois defeitos de gatilho achados ao escrever o teste — mesma
171
+ raiz, o `<span>` wrapper não é o gatilho real:
172
+
173
+ - o **Escape fechava o menu e largava o foco no `<body>`**: quem recebia o
174
+ `focus()` era o wrapper, que fica sem `tabindex` quando o slot já traz um
175
+ `Button`, e `focus()` num span sem tabindex é no-op;
176
+ - o gatilho **não tinha `aria-haspopup` nem `aria-expanded` em lugar nenhum**
177
+ quando o slot trazia um `Button`. Os dois moravam no wrapper, e o wrapper só
178
+ os recebe quando ELE vira o botão — que é justamente o caso em que não há
179
+ botão dentro. Leitor de tela nunca anunciava que aquilo abre um menu.
180
+
181
+ Os dois têm o tratamento que o `Popover` já tinha: `alvoInterativo()` e
182
+ `sincronizarEstadoDoGatilho()` escrevem foco e `aria-` no elemento interativo
183
+ de dentro.
184
+
185
+ ## 2.6.0
186
+
187
+ ### Minor Changes
188
+
189
+ - 3d2977e: fix(app-header): menu do usuário fora do botão, ícones sem registro e barra que não estoura
190
+
191
+ - O bloco do usuário vira um `<button>` de verdade (Enter/Espaço nativos) e o
192
+ `userMenu` é renderizado ao lado dele, não dentro — clicar no menu não
193
+ dispara mais `onUserClick`. Prop nova `userMenuOpen` liga `aria-haspopup` e
194
+ `aria-expanded`. No Vue o slot é `#user-menu`.
195
+ - A lupa e a seta do usuário usam o objeto do ícone: aparecem sem
196
+ `library.add` no app.
197
+ - Em larguras apertadas a barra não passa mais do contêiner: a navegação é
198
+ cortada, a busca encolhe e o nome do usuário ganha reticências.
199
+
200
+ - 80b417c: feat(attachmentcard): cartão de anexo com tipo de documento e conferência
201
+
202
+ Componente novo. Substitui a miniatura de PDF solta dos despachos, que só
203
+ mostrava o nome do arquivo: o cartão diz que documento aquele arquivo cumpre
204
+ (CNH, RG…), se é obrigatório e qual foi a situação da conferência.
205
+
206
+ Com `statusDetails`, o selo de situação abre o painel de conferência — o que foi
207
+ concluído e os dados extraídos, com botão de copiar por campo. Abre no hover sem
208
+ tirar o foco de onde está; no clique ou no teclado, fixa e leva o foco para
209
+ dentro. Com `onOpen`, o cartão inteiro abre o arquivo, com um único ponto de foco.
210
+
211
+ - 93ad870: feat(combobox): campo de texto que filtra a lista enquanto se digita
212
+
213
+ Componente novo, extraído do autocomplete de usuários da 1Doc. A diferença para
214
+ o `Select` está em onde se digita: no `Select` o campo mostra o rótulo escolhido
215
+ e a busca mora dentro do dropdown; no `Combobox` o próprio campo é um `<input>`,
216
+ e a lista é sugestão do que está sendo digitado.
217
+
218
+ A caixa do campo é a do `Input` e a lista é a do `Select` — de propósito, para
219
+ não inventar anatomia nova. `allowCustomValue` aceita texto fora da lista;
220
+ `onInputChange` observa a digitação sem desligar o filtro local, que é o que a
221
+ presença de `onSearchChange` faz.
222
+
223
+ - 92bf640: feat(campos): contrato de validação único, `readOnly` de verdade e rótulos localizáveis
224
+
225
+ **Os dez campos passam a falar a mesma língua.** `helperText` é o nome canônico
226
+ do texto de apoio; `Select`, `MultiSelect`, `Checkbox` e `Radio` chamavam de
227
+ `description`, que continua funcionando como apelido. E a dica agora fica
228
+ visível **junto** com o erro nos dez — `Select` e `MultiSelect` escondiam.
229
+
230
+ **`Checkbox.readOnly` funciona.** Era pior que prop fantasma: chegava ao
231
+ `<input>`, mas `readonly` não existe para checkbox em HTML, então o navegador
232
+ ignorava e o valor alternava assim mesmo. Agora tem guarda e `aria-readonly`, e
233
+ continua focável e enviado no submit — o que o distingue de `disabled`.
234
+
235
+ **`Input.mask` foi removida.** Estava declarada e nenhum código a lia. Máscara
236
+ de verdade (cursor, colar, apagar) é componente próprio, não prop. Nenhum
237
+ produto passava.
238
+
239
+ **40 rótulos fixos em português viraram 29 props com default**, em 12
240
+ componentes — `aria-label={props.closeLabel || "Fechar"}`. Quem não passa nada
241
+ continua vendo português.
242
+
243
+ - 440201d: fix(drawer): a página de catálogo estava ilegível, e faltava o `inline`
244
+
245
+ Cada story do Drawer nascia aberta, e sem `inline` cada uma vira um overlay
246
+ `position: fixed` sobre a viewport inteira — várias na mesma página se
247
+ empilhavam e o catálogo virava um borrão de backdrops cortados.
248
+
249
+ O `Modal` já resolvia isso com uma prop `inline` ("renderiza sem fixed/overlay,
250
+ útil para documentação"). O Drawer não tinha. Agora tem, com o mesmo nome e o
251
+ mesmo motivo.
252
+
253
+ - 74a549f: feat(drawer): painel que entra por uma borda lateral, por cima do conteúdo
254
+
255
+ Componente novo, extraído da gaveta do assistente e do painel de tarefas da
256
+ 1Doc. É o irmão do `BottomSheet` em outra borda, de propósito: mesma pilha de
257
+ overlay, mesma camada, mesmo backdrop, mesmo trap de foco, mesmos nomes de prop.
258
+
259
+ Não confundir com o `SidePanel`, que é mobília de layout — vive na tela, contrai
260
+ para um trilho e não tem backdrop.
261
+
262
+ - 9143493: feat(grid): `equalHeight` deixa os cards de uma linha com a mesma altura
263
+
264
+ A célula do Grid já esticava, mas o card dentro dela não — cards lado a lado
265
+ ficavam com alturas diferentes. `<Grid container equalHeight>` faz o filho
266
+ único de cada item preencher a altura da linha. É opcional: ligado para todos,
267
+ um botão ou campo sozinho na célula esticaria junto.
268
+
269
+ - 48f140b: feat(input): limites e passo no campo numérico, e o girador nativo escondido
270
+
271
+ `min`, `max` e `step` viram props do `Input`, e o botão nativo de girar do
272
+ `type="number"` passa a vir escondido por padrão (`numberSpinner` traz de
273
+ volta).
274
+
275
+ É o que a auditoria chamava de "NumberInput ausente". O produto já usa
276
+ `<Input type="number" min max>` em três telas e escondia o girador à mão no CSS
277
+ de cada uma — o que faltava eram as props, não um componente novo com +/− que o
278
+ produto rejeitou.
279
+
280
+ - 73dc06f: feat(modal): o modal base da 1Doc vira o padrão — três faixas, controles de janela e rodapé com região de apoio
281
+
282
+ O `Modal` tinha uma anatomia só, a do diálogo de feedback: tudo centralizado
283
+ numa coluna com `overflow-y: auto` em volta do conjunto. Como a rolagem
284
+ envolvia o cabeçalho e o rodapé, com conteúdo alto **o título subia e sumia e
285
+ os botões desciam e sumiam junto**.
286
+
287
+ Agora, sem `variant`, o `Modal` é o modal base da 1Doc — o "Criar Novo
288
+ Documento", medido em `NovoDocumentoModal.css`:
289
+
290
+ - **cabeçalho fixo** com título (16/700), subtítulo (12px) e divisor;
291
+ - **corpo**, o único que rola;
292
+ - **rodapé fixo** com divisor, sombra que o levanta, região de apoio à esquerda
293
+ e ações à direita.
294
+
295
+ Props novas:
296
+
297
+ - `windowControls` — restaurar · expandir · tela cheia · minimizar, antes do ×.
298
+ É tudo ou nada: ou o modal tem só o ×, ou o conjunto inteiro. Ligado, o modal
299
+ muda de tamanho sozinho (780px · 1120px · tela cheia).
300
+ - `onMinimize` — o clique no minimizar; só existe com `windowControls`.
301
+ - `footerStart` — a região esquerda do rodapé (a caixa "Urgente", um
302
+ "Selecionado: 0"). No Vue, o slot chama `footer-start`.
303
+
304
+ Sem `footerStart`, `footerSlot`, `confirmLabel` nem `cancelLabel`, não há
305
+ rodapé nem divisor.
306
+
307
+ **Muda a aparência de quem usa `<Modal>` sem `variant`**: era centralizado, passa
308
+ a ser alinhado à esquerda e com faixas. Os três de feedback (`positive`,
309
+ `negative`, `info`) e quem passa `layout="dialog"` continuam idênticos.
310
+
311
+ - 6e917e6: feat(popover): painel flutuante ancorado, com conteúdo livre
312
+
313
+ Terceiro da família de flutuantes. A escolha entre os três é pelo que vai
314
+ dentro: o `Tooltip` carrega uma frase e abre no hover; o `Dropdown` carrega uma
315
+ lista de ações e é navegado por setas; o `Popover` carrega qualquer coisa — um
316
+ formulário de filtro, uma explicação com link — e por isso abre no clique e não
317
+ sequestra o teclado.
318
+
319
+ Usa a mesma máquina do `Dropdown` (Portal, `@floating-ui/dom`, `autoUpdate`) e a
320
+ mesma superfície do menu dele.
321
+
322
+ - ebc09c5: feat(progress-bar): `tone="on-color"` para usar sobre superfície colorida
323
+
324
+ O rótulo e o valor tinham cor escura fixa e sumiam sobre um hero azul. Com
325
+ `tone="on-color"`, texto, trilha e preenchimento passam para as cores de
326
+ conteúdo sobre cor. As variáveis `--umds-progress-label-color`,
327
+ `--umds-progress-value-color` e `--umds-progress-track-color` permitem ajuste
328
+ fino sem mexer em classe interna. Sem a prop, nada muda.
329
+
330
+ - a062984: feat(segmentedcontrol): escolha única entre poucas opções, lado a lado
331
+
332
+ Componente novo, extraído do seletor de itens por página da fila de tarefas da
333
+ 1Doc. É um `RadioGroup` com outra apresentação, e a API é a mesma de propósito.
334
+
335
+ Por baixo são `<input type="radio">` de verdade compartilhando `name` — as setas
336
+ do teclado, o submit de formulário e a semântica de grupo vêm do navegador, não
337
+ de código.
338
+
339
+ - f718568: feat(stat-card): `trendIntent` separa a cor da variação da direção da seta
340
+
341
+ Até aqui a cor da variação vinha da direção: `up` pintava de verde, `down` de
342
+ vermelho. Não havia como dizer "custo caiu 8%" (boa notícia, seta para baixo)
343
+ nem "dívida técnica subiu" (má notícia, seta para cima).
344
+
345
+ A prop nova `trendIntent` (`positive` | `negative` | `neutral`) define a cor;
346
+ `trend` continua definindo só a seta. Sem `trendIntent`, a cor segue a direção
347
+ exatamente como antes — nenhuma tela existente muda de pixel.
348
+
349
+ - 08c7dc1: fix(tag): ícone clicável tem nome acessível também quando é objeto
350
+
351
+ O `aria-label` do ícone clicável só existia quando o ícone vinha como texto;
352
+ com o objeto do Font Awesome o botão ficava sem nome. Agora o nome sai do
353
+ ícone em qualquer formato, e as props novas `iconStartAriaLabel` e
354
+ `iconEndAriaLabel` permitem um rótulo de verdade (ex.: "Editar filtro").
355
+
356
+ - afca360: feat(timeline): histórico de eventos numa trilha vertical
357
+
358
+ Componente novo, extraído do histórico de versões do processo e da timeline de
359
+ despachos da 1Doc.
360
+
361
+ A diferença para o `Stepper` é o tempo: o `Stepper` mostra um processo com
362
+ etapas futuras e existe para dizer quanto falta; a Timeline mostra o que já
363
+ aconteceu, cada evento com quando e por quem, e não tem etapa "pendente".
364
+
365
+ A geometria da trilha é a do `Stepper` vertical, não a do protótipo: os dois
366
+ componentes aparecem na mesma tela na 1Doc, e duas trilhas com medidas
367
+ diferentes lado a lado é a inconsistência que esta rodada existe para eliminar.
368
+
369
+ ### Patch Changes
370
+
371
+ - 02eef38: fix(app-shell): o shell mede a própria altura e não depende mais do CSS da raiz
372
+
373
+ `.umds-app-shell` usava `height: 100%`. Sem `height: 100%` em `html`, `body` e
374
+ `#root`/`#app`, o shell crescia com o conteúdo: quem rolava era o `<body>`, e o
375
+ cabeçalho, a barra lateral e o rodapé da `AppSidebar` (com o botão de recolher)
376
+ saíam da tela — o contrário do que o componente promete.
377
+
378
+ A altura agora vem da custom property `--umds-app-shell-height`, que por padrão
379
+ é `100dvh` (com `100vh` para navegador sem `dvh`). Para embutir o shell num
380
+ contêiner de altura própria, defina `--umds-app-shell-height: 100%` nele ou num
381
+ ancestral. Quem já tinha o contorno `html, body, #root { height: 100% }` não
382
+ precisa mudar nada — e pode removê-lo.
383
+
384
+ - 2364d02: fix(phoneinput): as bandeiras saem do `flagcdn.com` e passam a vir embutidas
385
+
386
+ O campo buscava a imagem da bandeira num serviço de terceiros em tempo de
387
+ execução. Se a rede corporativa bloqueia, a bandeira some; cada usuário que abre
388
+ o campo entrega o IP dele para fora; e não há contrato de disponibilidade.
389
+
390
+ As dez bandeiras agora vêm embutidas como data URI, 18 KB no total. Era a única
391
+ dependência externa em runtime que o DS tinha.
392
+
393
+ - 7e73deb: fix(button): `startIcon`/`endIcon` aceitam o objeto do Font Awesome
394
+
395
+ Passar o ícone importado (`startIcon={faPlus}`) derrubava a tela no React
396
+ (erro #31): só o nome em texto passava pelo `Icon`, e o objeto caía cru no
397
+ slot. Agora texto, par `[prefixo, nome]` e objeto passam pelo `Icon`. Quem
398
+ passava um nó pronto continua funcionando.
399
+
400
+ - 74244eb: fix(side-panel): o fechar e a busca aparecem sem registrar ícones no app
401
+
402
+ `SidePanel` (`xmark`) e `SidePanelSearch` (lupa) pediam o ícone pelo nome e
403
+ saíam vazios quando o app não chamava `library.add`. Agora usam o objeto.
404
+
405
+ - 9ab7adc: fix(sidepanel): no Vue, o painel sem `open` nascia fechado e sem botão de fechar
406
+
407
+ `open` e `closable` eram tipadas `boolean`. O Vue aplica _boolean casting_: prop
408
+ booleana ausente chega como `false`, não como `undefined` — então
409
+ `props.open !== false` dava falso e o mesmo código abria expandido no React e
410
+ contraído no Vue. As duas passam a ser `any`, que é o remédio já registrado em
411
+ `.agent/troubleshooting/vue-boolean-prop-default.md`.
412
+
413
+ Achado pela esteira de regressão visual, comparando as stories dos dois
414
+ frameworks.
415
+
416
+ E, no mesmo componente: contraído, o painel saía da vista mas o **Tab continuava
417
+ entrando nos botões de dentro** (`aria-hidden-focus`, gravidade séria no axe).
418
+ Agora ele também recebe `visibility: hidden`, com 200ms de atraso para a
419
+ animação de largura continuar a mesma.
420
+
421
+ ## 2.5.0
422
+
423
+ ### Minor Changes
424
+
425
+ - 5f916d7: **A moldura da 1Doc passa a ser a do produto, e não uma interpretação dela.**
426
+
427
+ O `AppHeader` e o `SidePanel` que saíram na 2.4.0 tinham sido desenhados a partir da ideia de "app shell". Comparados à 1Doc lado a lado, não tinham relação: faltavam o botão de ação principal, o campo de busca, o grupo de ações, o bloco do usuário com nome — e o painel lateral era uma lista de navegação, não os dois painéis que o produto tem.
428
+
429
+ Agora a anatomia e as medidas vêm do produto **rodando**, não do CSS lido.
430
+
431
+ **`AppHeader`** ganha a anatomia real: marca (via `Logo`), ação principal, navegação, busca, ações, assistente e bloco do usuário. **`AppHeaderAction`** (novo) é o botão de ícone do topo, com o contador sobreposto do sino — o contador some em `0`, porque "tem algo" sem número não ajuda a decidir se vale abrir.
432
+
433
+ **`SidePanel`** vira o que o produto tem: trilho de abas de 49px sempre visível, painel de 254px que anima a largura até zero, conteúdo trocando por aba. Acompanham **`SidePanelItem`** (linha contada), **`SidePanelSection`** (rótulo de grupo) e **`SidePanelSearch`** (busca do painel), que juntos montam tanto o painel da emissão quanto o da fila de tarefas.
434
+
435
+ **`Logo`**: a base das letras estava sendo recortada por ~1px. O `<svg>` tem `overflow: hidden` e o navegador arredonda a altura para 1/64px, deixando o desenho 0,01px maior que a caixa. Afetava todo lugar que usa o componente.
436
+
437
+ **Mudança visual esperada** em `AppHeader`, `AppNavItem` e `SidePanel`: eles passam a parecer a 1Doc. O `AppNavItem` perde o fundo no hover e o padding lateral que não existiam no produto.
438
+
439
+ Medida sem degrau na escala vai como literal comentado, com o valor do produto ao lado — é o que a regra 2 permite. Só **cor** continua sendo token obrigatório: as quatro do produto que o DS não tem (`#222222`, `#e1e3e6`, `#edf2ff`, `#0046b5`) ficam no vizinho mais próximo.
440
+
441
+ ## 2.4.0
442
+
443
+ ### Minor Changes
444
+
445
+ - fa15735: **App shell: `AppShell`, `AppHeader` e `AppSidebar`.**
446
+
447
+ Era a maior lacuna apontada pela auditoria interna — o padrão de layout da 1Doc estava escrito e mesmo assim cada produto o reconstruía do zero. Só no protótipo são ~1.000 linhas entre `App.tsx`, `Header.tsx`, `Subheader.tsx` e CSS.
448
+
449
+ - **`AppShell`** — a moldura. Cabeçalho e barra não rolam; só o conteúdo rola. Traz as duas linhas que faltam em quase toda implementação manual: `min-height: 0` (sem ela a rolagem escapa para o body e o header "fixo" sobe junto) e `min-width: 0` (sem ela uma tabela larga empurra o layout inteiro).
450
+ - **`AppHeader`** — barra de 56px com marca, navegação e ações. O que vai dentro é do produto.
451
+ - **`AppSidebar`** — 48px fechada, 248px aberta. Com a barra fechada o rótulo **continua no HTML**, só sai da vista: trocá-lo por um ícone solto deixaria a navegação muda para leitor de tela.
452
+
453
+ A geometria virou token (`--umds-semantic-shell-*`), então mudar o padrão de todos os produtos é editar um arquivo.
454
+
455
+ **Paridade com o protótipo: 16 de 22 medidas batem exatamente.** As 6 restantes não têm valor exato na escala do DS — nos casos de espaço e tamanho, os dois degraus vizinhos ficam à mesma distância do protótipo, e bater com ele exigiria inventar token. A regra aplicada foi cor e medida sempre 100% do design system, escolhendo o valor mais próximo. A conta é refeita com `node scripts/verifica-paridade-shell.mjs`.
456
+
457
+ - 2a86d8c: Três componentes novos na trilha **Preview**, para telas onde parte do conteúdo ou parte da decisão vem de um modelo:
458
+
459
+ - **`AILabel`** — selo de conteúdo gerado, com painel de explicabilidade que responde de onde veio, o que não entrou e o que fazer se estiver errado.
460
+ - **`AIContent`** — envolve conteúdo gerado. Quando o usuário edita, o tratamento de IA **sai**: a partir dali o texto é dele, e manter a marca atribuiria autoria errada. Mantém a ação de reverter para a sugestão.
461
+ - **`ConfirmAIAction`** — conteúdo para o `ConfirmDialog` quando a ação foi sugerida por IA. Escalona a confirmação pelo risco e lista o que será afetado. Cascata conta como risco alto mesmo com cada passo reversível.
462
+
463
+ Trilha Preview: a API pode mudar sem virar versão quebrada. O contrato de instabilidade está na página _Sobre o Preview_ do Storybook.
464
+
465
+ - ab2f457: Contrato único de validação na família de campos: invalid + errorMessage + helperText
466
+ - 2b78aca: Stack, Box e Container — as primitivas de layout que faltavam
467
+ - 7c44c6d: **As peças que faltavam para reproduzir a tela da 1Doc:** `AppSubheader`, `SidePanel`, `AppNavItem` e `StatCard`, somadas ao `AppShell`, `AppHeader` e `AppSidebar`.
468
+
469
+ Levantadas medindo o protótipo, não por suposição: o `SidePanel` tem 254px porque é o número do protótipo, o mesmo na Emissão e nas Tarefas; o `AppSubheader` tem 42px pelo mesmo motivo. Toda a geometria virou token `--umds-semantic-shell-*`.
470
+
471
+ - **`AppNavItem`** — o item da navegação horizontal do topo: rótulo, contador e seta. O contador aceita `badgeLabel`, porque "9" sozinho não diz nada a quem usa leitor de tela.
472
+ - **`AppSubheader`** — a barra de contexto: trilha à esquerda, setor e ações à direita.
473
+ - **`SidePanel`** — o painel lateral **da tela** (histórico, filtros), que fecha animando a largura até zero. Não confundir com `AppSidebar`: na 1Doc a navegação do app é horizontal, e o que fica à esquerda é sempre um destes.
474
+ - **`StatCard`** — cartão de indicador. A variação vem com seta, não só com cor.
475
+
476
+ **Correção junto:** `Input.iconLeft` e `InputAction.icon` renderizavam o valor cru quando não era string. Como as props são tipadas `IconProp`, passar o objeto importado do Font Awesome derrubava a tela no React (erro #31). Agora vão sempre pelo `Icon`, que resolve string, tupla e objeto.
477
+
478
+ ### Patch Changes
479
+
480
+ - 34decba: Alvos de toque de 24px e o X do Chips visível nas variantes negative e info
481
+ - 637c60c: **`DataTable`: a linha clicável deixa de se anunciar como botão.**
482
+
483
+ Com `onRowClick`, a linha recebia `role="button"`. Isso causava dois problemas: o role substituía `row` e derrubava a navegação de grade do leitor de tela — a pessoa deixava de percorrer a tabela célula a célula; e, junto com `selectable`, a linha "botão" passava a conter o checkbox de seleção, aninhando dois controles interativos.
484
+
485
+ O `tabIndex` continua: quem navega por teclado alcança a linha e Enter/Espaço acionam, igual a antes. O que muda é só o anúncio — que, dentro de uma tabela, já estava errado.
486
+
487
+ - 2bc13c1: Três falhas de comportamento apontadas pela auditoria interna, todas verificadas na tela:
488
+
489
+ - **`DataTable`** — com `selectable` e `onRowClick` juntos, o Espaço dentro do checkbox era engolido pelo `preventDefault` do handler da linha e acionava a linha inteira: marcar por teclado era impossível. O caminho do mouse já tinha a guarda equivalente; só o teclado ficou de fora.
490
+ - **`DatePicker`** — o foco nunca entrava no painel. `ArrowDown` abria o calendário e o teclado ficava inerte, porque o painel vive num Portal e o Tab a partir do gatilho ia para o resto da página. O alvo do foco passou a ser o dia marcado pelo roving tabindex, que é a verdade do DOM no instante em que o frame roda — o seletor anterior lia um valor de estado da closure do render anterior, que ao abrir ainda era o antigo.
491
+ - **`BottomSheet`** — o listener global de `keydown` era registrado a cada montagem e nunca removido, acumulando ao trocar de tela, em StrictMode e em navegação por rotas. Junto, o id da instância passou a ser gerado no inicializador: um painel que montasse já com `open=true` registrava id vazio na pilha de overlays e o Esc não fechava.
492
+
493
+ - 188db4a: Tag: conteúdo passado entre as tags (`children`) voltou a renderizar no Vue.
494
+
495
+ `{props.label || props.children}` funciona no React e não no Vue: o Mitosis traduz `props.children` para `$slots.default` e o template gerado vira `{{ label || $slots.default }}` — interpolação do objeto de slots em vez de renderização do slot. `<Tag>texto</Tag>` aparecia no React e sumia no Vue, sem erro.
496
+
497
+ Trocado por `Show`/`else` com `Slot`, que é o idioma que o Mitosis traduz corretamente nos dois alvos (mesmo padrão já usado no `Icon`).
498
+
499
+ ## 2.3.0
500
+
501
+ ### Minor Changes
502
+
503
+ - fe70f80: BottomNavigation: componente novo — Tabs não serve para bottom-nav sem sobrescrever classes internas (indicador
504
+ embaixo, sem ícone acima do label, itens sem flex:1). Componente próprio:
505
+ ícone acima do label, indicador no TOPO do item ativo, alvos >=44px, fixed
506
+ com safe-area do notch.
507
+ - 2940c64: Componente `BottomSheet`: painel inferior com alça, encaixes opcionais e arraste, consumindo a mesma pilha de overlays, camada e backdrop do `Modal`.
508
+ - 1edf7be: DataTable: componente novo — column.render(row, index) oficializa células ricas (antes só funcionava por contrato não documentado); rowKey + selectedKeys/onSelectKeys para seleção estável entre páginas e ordenações; density=compact; onRowClick; ícones de ordenação e vazio como objeto FA.
509
+ - ca794cc: DatePicker: componente novo — Ícones calendário/chevrons como objeto FA; anéis de foco/erro via color-mix (seguem a marca e o dark); modo touch.
510
+ - 6f72387: Empacotamento: `utils/toast` e `utils/density` passam a ser exportados pelo índice dos pacotes (antes o código existia mas não havia como importar). `sideEffects: ["**/*.css"]` para o bundler do consumidor não descartar os estilos, mapa de `exports` com subpath `./utils/*` e `@1doc/1ds-tokens` promovido a peerDependency.
511
+ - 3d69114: FileInput: componente novo — prop name: os File selecionados/arrastados ficam no input nativo (DataTransfer) e entram no FormData — era o único campo fora do submit; ícones como objeto FA.
512
+ - 4688b99: Input: errorMessage/helperText com ids estáveis e aria-describedby; anéis de foco/erro via color-mix; fonte >=16px em telas <=640px (evita o zoom automático do Safari iOS); ícones olho/ações como objeto FA; min-height 44px no modo touch.
513
+ - e8a8c93: Link: Paridade UX.
514
+ - 191d211: MCP e catálogo do Storybook passam a dizer QUANDO usar cada componente, não só o que ele faz
515
+ - 8390232: Modal: size sm|md|lg|fullscreen (era fixo em 498px); layout=content (texto à esquerda, footer à direita) para formulários e wizards; corpo rolável (overflow:clip cortava o wizard e escondia o footer); Esc integrado à pilha de overlays + closeOnEsc; superfície elevada; ícone info em feedback-info-dark.
516
+
517
+ Mantém `variant="success"|"error"|"warning"` como aliases depreciados de `positive`/`negative`/`info` — quem já usa os nomes antigos não quebra.
518
+
519
+ - 1dfb2c2: MultiSelect: componente novo — role=listbox só no container das options (busca e rodapé não são filhos válidos); checkbox das options decorativo; value/onChange tipados; hover do remover e anéis via color-mix; modo touch.
520
+ - 2992d54: PageHeader: componente novo — size=sm (título 24→18px) para headers compactos/mobile; chevron do breadcrumb como objeto FA.
521
+ - 1bd877e: Pagination: componente novo — Cinco variantes (default com campo de página, alternative, resumed, full-width, bordered); texto "de" com contraste AA; chevrons como objeto FA; alvos 44px no modo touch. BREAKING: o layout numerado antigo corresponde a variant="full-width".
522
+ - 81cdee5: PhoneInput: componente novo — errorMessage/helperText com aria-describedby (era o único campo sem); hidden input {name}\_ddi — o FormData levava só o número local e o país se perdia; painel portalado; fonte 16px em mobile; ícones como objeto FA.
523
+ - 965037b: Select: Label visível vira nome acessível do combobox (aria-labelledby); value/onChange tipados; anéis via color-mix; fonte 16px em mobile; ícones como objeto FA; modo touch.
524
+ - 972cb57: Stepper: componente novo — Título do passo pendente com contraste AA; ícones check/xmark como objeto FA.
525
+ - 10cc624: Switch: checked tipado como boolean; slots iconChecked/iconNotChecked declarados; glifos proporcionais; ícones como objeto FA.
526
+ - bc7873f: Tabs: A linha-guia do tablist virou background interno: o indicador da aba ativa a cobre por completo (com border no container, e tablist rolável, isso era impossível); overflow-x auto (labels nowrap transbordavam em 375px); Tab.icon documentado como Font Awesome.
527
+ - 9bb944b: Tag: variant semântico neutral|primary|positive|negative|info (paridade com o Badge) — tag de status sem trocar de componente; ícone de fechar como objeto FA.
528
+
529
+ Mantém `variant="outlined"|"solid"` aceito como aparência (era o significado antigo da prop) — quem já usa não quebra.
530
+
531
+ - 5287da5: Textarea: Anéis de foco/erro via color-mix; fonte >=16px em telas <=640px; autoSize e contador.
532
+ - b7bcdb5: TimePicker: componente novo — Anéis via color-mix; ícones relógio/chevrons como objeto FA; literais de handler movidos para métodos do store (aspas inline quebram a geração Vue); modo touch.
533
+ - 600a198: Toast: componente novo — ToastStack + fila imperativa (mensagens em sequência se atropelavam e cada app reinventava o host); prop portalContainer; description sem opacity (reprovava AA); ícones como objeto FA.
534
+ - cb4ce56: Tooltip: Seta estática nas 12 posições side×align, CSS próprio, content aceita ReactNode.
535
+ - acdbae1: Componente `Tree`: hierarquia com expansão, seleção (simples, múltipla e em cascata opcional), teclado APG com foco roving e conteúdo da linha por `renderItem`.
536
+
537
+ ## 2.2.0
538
+
539
+ ### Minor Changes
540
+
541
+ - e4a801b: Accordion: componente novo — Ícone chevron importado como objeto FA (renderizava vazio sem library.add no app do consumidor); content aceita ReactNode (era string, e rejeitava o JSX que já funcionava em runtime).
542
+ - 9ef86c4: Alert: Ícones de variante e fechar importados como objeto FA; hover do close revisado.
543
+
544
+ Mantém a prop `type` (success/error/warning) e `variant="soft"|"solid"` como aliases depreciados — a API antiga continua compilando.
545
+
546
+ - adb399c: Avatar: Paridade visual UX + AvatarGroup.
547
+ - 15401a6: Badge: Variantes solid/soft/outlined com contraste AA.
548
+
549
+ Atributos HTML (`style`, `data-*`, `aria-*`, `title`, `role`, `tabIndex`) voltam a chegar ao elemento raiz, agora por spread filtrado — props do componente nao vazam mais como atributo invalido no DOM.
550
+
551
+ - 4c21e5f: Breadcrumb: componente novo — Getter no store para o For (expressão binária quebra a geração Mitosis).
552
+ - 8b150de: Button: Interface de props alinhada aos demais componentes (aceita data-_/aria-_ declarados); spinner com faRefresh já importado como objeto; min-height 44px no modo touch.
553
+ - ac954b5: Card: componente novo — Implementação de referência do plano de porte (padrão-ouro): variantes, elevação e composição por slots.
554
+ - 2ef27b9: Checkbox: errorMessage com aria-describedby (antes só invalid, e a mensagem ficava fora do componente); modo decorative (sem input nativo) para indicadores dentro de widgets com semântica própria; readOnly/tabIndex declarados; label do success com contraste AA no variant background; ícones check/minus como objeto FA.
555
+ - 18b6c2a: Chips: componente novo — onClick + selected (filter chip com aria-pressed e botão real, sem nested-interactive); ícone xmark como objeto FA.
556
+ - 0d604b5: ConfirmDialog: componente novo — Camada acima do Modal (empatava em layer-modal e a ordem no DOM decidia quem aparecia); Esc via pilha de overlays + prop closeOnEsc; hover do botão info derivado por color-mix (era hex cru #7a3909, único do dist); ícone info em feedback-info-dark (o pure reprovava 3:1); superfície elevada.
557
+ - db42a2d: Core: utilitários novos — `registerTheme()` (aceita tema de marca própria, white-label), `setDensity()` (modo touch global com alvos ≥44px), pilha de overlays (só o diálogo do topo reage a Esc) e fila imperativa de toasts (`toast()`, `dismissToast()`, `subscribeToasts()`). Build: dedup dos blocos JSDoc que o gerador Mitosis re-emitia duplicados nos pacotes publicados.
558
+ - 08f82d3: Divider: Paridade UX.
559
+ - 8a201d5: Dropdown: componente novo — Wrapper do trigger só recebe role/tabindex/aria quando o conteúdo NÃO é interativo — passar um Button (caso típico) gerava botão dentro de botão; ícones dos itens como objeto FA.
560
+ - 9f62f77: EmptyState: componente novo — icon aceita IconProp (objeto FA) em vez de string de classes CSS — mecanismo unificado com o resto do DS.
561
+ - 03ceb61: Grid: spacing tipado como união dos sufixos de token (string crua gerava var() inválida silenciosa).
562
+
563
+ Atributos HTML (`style`, `data-*`, `aria-*`) voltam a ser repassados ao elemento raiz, como na versão anterior — a remoção do spread os tornava aceitos na tipagem e ignorados na renderização.
564
+
565
+ Atributos HTML (`style`, `data-*`, `aria-*`, `title`, `role`, `tabIndex`) voltam a chegar ao elemento raiz — a remoção do spread os tornava aceitos na tipagem e ignorados na renderização. O spread agora é filtrado, então props do componente não vazam mais como atributo inválido no DOM.
566
+
567
+ - 79175ba: Icon: Base do contrato: aceita objeto IconDefinition (recomendado), nome registrado ou par [prefix, name].
568
+ - 1c17f08: Logo: currentColor (sem cor inline).
569
+
570
+ Atributos HTML (`style`, `data-*`, `aria-*`) voltam a ser repassados ao elemento raiz, como na versão anterior — a remoção do spread os tornava aceitos na tipagem e ignorados na renderização.
571
+
572
+ Atributos HTML (`style`, `data-*`, `aria-*`, `title`, `role`, `tabIndex`) voltam a chegar ao elemento raiz — a remoção do spread os tornava aceitos na tipagem e ignorados na renderização. O spread agora é filtrado, então props do componente não vazam mais como atributo inválido no DOM.
573
+
574
+ - d308db9: Portal: prop container (shadow DOM, dialogs nativos, containers de scroll próprios).
575
+ - 27e6c41: ProgressBar: componente novo — Paridade UX.
576
+ - 47267c4: Radio: errorMessage com aria-describedby e aria-invalid; checked tipado como boolean.
577
+ - 518dc54: RadioGroup: componente novo — Montar grupo à mão exigia amarrar checked/onChange item a item e criar
578
+ role="radiogroup" manualmente — e o modo não-controlado de radios soltos é
579
+ terreno de bug conhecido. RadioGroup resolve: value/onChange (ou defaultValue),
580
+ name compartilhado (submit nativo + setas do navegador), direção, errorMessage
581
+ de grupo com aria-describedby.
582
+ - 8c3032f: Skeleton: Paridade UX.
583
+ - 59db0a5: Spinner: Reexcluído do bloco global de prefers-reduced-motion (o giro é a informação).
584
+
585
+ Atributos HTML (`style`, `data-*`, `aria-*`) voltam a ser repassados ao elemento raiz, como na versão anterior — a remoção do spread os tornava aceitos na tipagem e ignorados na renderização.
586
+
587
+ Atributos HTML (`style`, `data-*`, `aria-*`, `title`, `role`, `tabIndex`) voltam a chegar ao elemento raiz — a remoção do spread os tornava aceitos na tipagem e ignorados na renderização. O spread agora é filtrado, então props do componente não vazam mais como atributo inválido no DOM.
588
+
589
+ - b615cab: Text: Media queries alinhadas aos tokens de breakpoint (usava a escala Bootstrap, divergente do Grid: tipografia e colunas quebravam em larguras diferentes).
590
+
591
+ Mantém `color="error"` como alias depreciado de `"negative"`: Input, Select e
592
+ Textarea ainda passam o nome antigo, e o `tsc` do pacote gerado falha sem ele.
593
+
594
+ Atributos HTML (`style`, `data-*`, `aria-*`) voltam a ser repassados ao elemento raiz, como na versão anterior — a remoção do spread os tornava aceitos na tipagem e ignorados na renderização.
595
+
596
+ Atributos HTML (`style`, `data-*`, `aria-*`, `title`, `role`, `tabIndex`) voltam a chegar ao elemento raiz — a remoção do spread os tornava aceitos na tipagem e ignorados na renderização. O spread agora é filtrado, então props do componente não vazam mais como atributo inválido no DOM.
597
+
598
+ ### Patch Changes
599
+
600
+ - 6ae6955: Espaçamentos do `Badge` passam a usar os primitivos de espaço em vez de literais.
601
+ - ee4c39a: Foco canônico (outline em `primary-pure`) e espaçamentos em token no `Checkbox`.
602
+ - 009944f: Animação da `ProgressBar` passa de listras com branco fixo para varredura de gradiente que acompanha o tema.
603
+ - b132637: Geometria do `Radio` conforme o Figma (12/14/16px com `border-box`), foco canônico e token circular.
604
+ - 34a8405: O raio circular do `Skeleton` passa a usar o token em vez de `50%`.
605
+ - a65bf9a: O raio circular do `Spinner` passa a usar o token em vez de `50%`.
606
+ - Updated dependencies [eccc44b]
607
+ - Updated dependencies [6e16218]
608
+ - @1doc/1ds-tokens@0.2.0
609
+
610
+ ## 2.1.0
611
+
612
+ ### Minor Changes
613
+
614
+ - e51ee6f: ---
615
+
616
+ "@1doc/1ds-core": minor
617
+ "@1doc/1ds-react": minor
618
+ "@1doc/1ds-vue": minor
619
+
620
+ ***
621
+
622
+ Adiciona o componente `Portal` e corrige o Tooltip.
623
+
624
+ **Portal (novo):** componente que move seu conteúdo para `document.body`. No React/Solid/Svelte usa `appendChild`; no Vue é convertido para `<Teleport to="body">` no post-build. Serve de base para componentes flutuantes (tooltip, e futuros modal/dropdown).
625
+
626
+ **Tooltip (correção):** deixa de ser cortado por containers com `overflow: hidden` e elimina o erro `Cannot read properties of null (reading 'insertBefore')` no Vue ao fechar. O posicionamento passou a usar `@floating-ui/dom` (`offset`, `flip`, `shift`, `arrow`) e o conteúdo é renderizado via `Portal`. Também corrige o flicker no hover rápido.
627
+
628
+ ## 1.0.0
629
+
630
+ ### Major Changes
631
+
632
+ - 445de52: feat(icon): nova API dinâmica, remoção do Font Awesome Pro e tipagem extensível
633
+
634
+ **Breaking change** — a prop `name` foi removida do `<Icon>`. Use `icon` no lugar, que aceita três formatos:
635
+
636
+ - string: `<Icon icon="home" />`
637
+ - tupla `[prefix, iconName]`: `<Icon icon={["fas", "home"]} />`
638
+ - objeto `IconLookup` (ex.: `<Icon icon={faHome} />`)
639
+
640
+ **Novas props:**
641
+
642
+ - `transform`: aceita string (parseada via `faParse.transform`) ou objeto `Transform` do FA core.
643
+ - `mask` / `maskId`: ícone de máscara (suporta os mesmos formatos de `icon`).
644
+ - `symbol`: cria `<symbol>` reutilizável (`FaSymbol` do FA core).
645
+ - `customSize`: tamanho livre em CSS (`"32px"`, `"2rem"`) que sobrescreve `size`.
646
+
647
+ **Type augmentation:** o tipo `IconKit` é exportado vazio por padrão (fallback para `FaIconLookup`). Projetos consumidores podem restringir os ícones tipados via `declare module`:
648
+
649
+ ```ts
650
+ declare module "@1doc/1ds-react" {
651
+ interface IconKit {
652
+ prefix: "fas" | "far";
653
+ iconName: "user" | "home" | "gear";
654
+ }
655
+ }
656
+ ```
657
+
658
+ ### Minor Changes
659
+
660
+ - Adiciona o componente Tooltip para React e Vue, com suporte a título, conteúdo, ícone, posicionamento configurável (side: top/bottom/left/right, align: start/center/end), delay de abertura e estado desabilitado.
661
+
3
662
  ## 0.0.2
4
663
 
5
664
  ### Patch Changes