@1doc/1ds-react 2.9.0 → 2.11.0

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 (172) hide show
  1. package/CHANGELOG.md +653 -0
  2. package/dist/components/Accordion/Accordion.css +13 -0
  3. package/dist/components/Accordion/Accordion.d.ts +9 -0
  4. package/dist/components/Accordion/Accordion.js +18 -5
  5. package/dist/components/AppSubheader/AppSubheader.css +10 -1
  6. package/dist/components/AttachmentCard/AttachmentCard.css +10 -8
  7. package/dist/components/AttachmentCard/AttachmentCard.d.ts +3 -0
  8. package/dist/components/AttachmentCard/AttachmentCard.js +8 -1
  9. package/dist/components/Badge/Badge.css +27 -5
  10. package/dist/components/Badge/Badge.d.ts +20 -4
  11. package/dist/components/Badge/Badge.js +6 -0
  12. package/dist/components/Button/Button.css +5 -0
  13. package/dist/components/Button/Button.d.ts +3 -0
  14. package/dist/components/Button/Button.js +1 -0
  15. package/dist/components/Calendar/Calendar.css +10 -0
  16. package/dist/components/Calendar/Calendar.d.ts +10 -6
  17. package/dist/components/Calendar/Calendar.js +6 -1
  18. package/dist/components/Coachmark/Coachmark.css +10 -0
  19. package/dist/components/Coachmark/Coachmark.d.ts +14 -1
  20. package/dist/components/Coachmark/Coachmark.js +51 -5
  21. package/dist/components/ColorPicker/ColorPicker.css +8 -1
  22. package/dist/components/ColorPicker/ColorPicker.d.ts +2 -2
  23. package/dist/components/DataTable/DataTable.css +216 -0
  24. package/dist/components/DataTable/DataTable.d.ts +70 -2
  25. package/dist/components/DataTable/DataTable.js +293 -6
  26. package/dist/components/DescriptionList/DescriptionList.css +14 -0
  27. package/dist/components/DescriptionList/DescriptionList.d.ts +3 -0
  28. package/dist/components/DescriptionList/DescriptionList.js +1 -0
  29. package/dist/components/EmptyState/EmptyState.d.ts +4 -2
  30. package/dist/components/EmptyState/EmptyState.js +2 -2
  31. package/dist/components/Input/Input.css +30 -0
  32. package/dist/components/Input/Input.d.ts +10 -0
  33. package/dist/components/Input/Input.js +3 -1
  34. package/dist/components/List/ListItem.d.ts +14 -2
  35. package/dist/components/List/ListItem.js +3 -2
  36. package/dist/components/Modal/Modal.css +19 -0
  37. package/dist/components/Modal/Modal.d.ts +7 -0
  38. package/dist/components/Modal/Modal.js +1 -0
  39. package/dist/components/RichTextEditor/RichTextEditor.css +47 -0
  40. package/dist/components/RichTextEditor/RichTextEditor.d.ts +22 -8
  41. package/dist/components/RichTextEditor/RichTextEditor.js +460 -3
  42. package/dist/components/SegmentedControl/SegmentedControl.css +70 -0
  43. package/dist/components/SegmentedControl/SegmentedControl.d.ts +5 -0
  44. package/dist/components/SegmentedControl/SegmentedControl.js +5 -1
  45. package/dist/components/Select/Select.css +122 -2
  46. package/dist/components/Select/Select.d.ts +33 -4
  47. package/dist/components/Select/Select.js +256 -35
  48. package/dist/components/StatCard/StatCard.css +73 -0
  49. package/dist/components/StatCard/StatCard.d.ts +12 -0
  50. package/dist/components/StatCard/StatCard.js +11 -1
  51. package/dist/components/Tabs/Tabs.css +11 -0
  52. package/dist/components/Tabs/Tabs.d.ts +7 -0
  53. package/dist/components/Tabs/Tabs.js +7 -1
  54. package/dist/components/Tag/Tag.css +3 -1
  55. package/dist/components/Toast/Toast.css +32 -0
  56. package/dist/components/Toast/Toast.d.ts +18 -0
  57. package/dist/components/Toast/Toast.js +14 -1
  58. package/dist/components/Toast/ToastStack.js +8 -1
  59. package/dist/teste/AccordionControlado.test.d.ts +1 -0
  60. package/dist/teste/AccordionControlado.test.js +73 -0
  61. package/dist/teste/AccordionTituloNeutro.test.d.ts +1 -0
  62. package/dist/teste/AccordionTituloNeutro.test.js +23 -0
  63. package/dist/teste/AppSubheaderRegiao.test.d.ts +1 -0
  64. package/dist/teste/AppSubheaderRegiao.test.js +13 -0
  65. package/dist/teste/AttachmentCardLista.test.d.ts +1 -0
  66. package/dist/teste/AttachmentCardLista.test.js +49 -0
  67. package/dist/teste/AttachmentCardSm.test.d.ts +1 -0
  68. package/dist/teste/AttachmentCardSm.test.js +26 -0
  69. package/dist/teste/BadgeAttachedTomEPadding.test.d.ts +1 -0
  70. package/dist/teste/BadgeAttachedTomEPadding.test.js +43 -0
  71. package/dist/teste/BadgeNeutroColado.test.d.ts +1 -0
  72. package/dist/teste/BadgeNeutroColado.test.js +11 -0
  73. package/dist/teste/BadgeTag.test.js +13 -0
  74. package/dist/teste/ButtonDensidade.test.d.ts +1 -0
  75. package/dist/teste/ButtonDensidade.test.js +28 -0
  76. package/dist/teste/CalendarCabecalho.test.d.ts +1 -0
  77. package/dist/teste/CalendarCabecalho.test.js +11 -0
  78. package/dist/teste/CalendarCompacto.test.d.ts +1 -0
  79. package/dist/teste/CalendarCompacto.test.js +29 -0
  80. package/dist/teste/CoachmarkSemVeu.test.d.ts +1 -0
  81. package/dist/teste/CoachmarkSemVeu.test.js +85 -0
  82. package/dist/teste/CoachmarkUmPasso.test.d.ts +1 -0
  83. package/dist/teste/CoachmarkUmPasso.test.js +34 -0
  84. package/dist/teste/ColorPickerXs.test.d.ts +1 -0
  85. package/dist/teste/ColorPickerXs.test.js +21 -0
  86. package/dist/teste/DataTableArvoreEVariantes.test.d.ts +1 -0
  87. package/dist/teste/DataTableArvoreEVariantes.test.js +190 -0
  88. package/dist/teste/DataTableCompactaETom.test.d.ts +1 -0
  89. package/dist/teste/DataTableCompactaETom.test.js +69 -0
  90. package/dist/teste/DescriptionListCompacta.test.d.ts +1 -0
  91. package/dist/teste/DescriptionListCompacta.test.js +22 -0
  92. package/dist/teste/EmptyStateTituloRico.test.d.ts +1 -0
  93. package/dist/teste/EmptyStateTituloRico.test.js +23 -0
  94. package/dist/teste/InputAgrupado.test.d.ts +1 -0
  95. package/dist/teste/InputAgrupado.test.js +24 -0
  96. package/dist/teste/InputGhost.test.d.ts +1 -0
  97. package/dist/teste/InputGhost.test.js +32 -0
  98. package/dist/teste/ListItemTooltipStandalone.test.d.ts +1 -0
  99. package/dist/teste/ListItemTooltipStandalone.test.js +39 -0
  100. package/dist/teste/ModalProporcoes1Doc.test.d.ts +1 -0
  101. package/dist/teste/ModalProporcoes1Doc.test.js +32 -0
  102. package/dist/teste/RichTextEditorAlinhaImagemTabela.test.d.ts +1 -0
  103. package/dist/teste/RichTextEditorAlinhaImagemTabela.test.js +212 -0
  104. package/dist/teste/RichTextEditorEstiloDeTexto.test.d.ts +1 -0
  105. package/dist/teste/RichTextEditorEstiloDeTexto.test.js +120 -0
  106. package/dist/teste/SegmentedControlContador.test.d.ts +1 -0
  107. package/dist/teste/SegmentedControlContador.test.js +39 -0
  108. package/dist/teste/SegmentedControlSuperficie.test.d.ts +1 -0
  109. package/dist/teste/SegmentedControlSuperficie.test.js +39 -0
  110. package/dist/teste/SelectAbertoControladoEFlutuante.test.d.ts +1 -0
  111. package/dist/teste/SelectAbertoControladoEFlutuante.test.js +145 -0
  112. package/dist/teste/SelectFiltroCorETamanho.test.d.ts +1 -0
  113. package/dist/teste/SelectFiltroCorETamanho.test.js +77 -0
  114. package/dist/teste/SelectItemComEscopo.test.d.ts +1 -0
  115. package/dist/teste/SelectItemComEscopo.test.js +54 -0
  116. package/dist/teste/SelectListaFiltro.test.d.ts +1 -0
  117. package/dist/teste/SelectListaFiltro.test.js +102 -0
  118. package/dist/teste/StatCardSecundariaETom.test.d.ts +1 -0
  119. package/dist/teste/StatCardSecundariaETom.test.js +45 -0
  120. package/dist/teste/StatCardTamanhoSm.test.d.ts +1 -0
  121. package/dist/teste/StatCardTamanhoSm.test.js +32 -0
  122. package/dist/teste/TabsCompacta.test.d.ts +1 -0
  123. package/dist/teste/TabsCompacta.test.js +35 -0
  124. package/dist/teste/TagPositivoTingido.test.d.ts +1 -0
  125. package/dist/teste/TagPositivoTingido.test.js +54 -0
  126. package/dist/teste/ToastAcaoEDetalhes.test.d.ts +1 -0
  127. package/dist/teste/ToastAcaoEDetalhes.test.js +94 -0
  128. package/dist/teste/lerArquivo.d.ts +1 -0
  129. package/dist/teste/lerArquivo.js +12 -0
  130. package/dist/utils/html-seguro.d.ts +19 -1
  131. package/dist/utils/html-seguro.js +113 -2
  132. package/dist/utils/toast.d.ts +10 -1
  133. package/dist/utils/toast.js +2 -1
  134. package/package.json +3 -3
  135. package/src/teste/AccordionControlado.test.tsx +87 -0
  136. package/src/teste/AccordionTituloNeutro.test.tsx +25 -0
  137. package/src/teste/AppSubheaderRegiao.test.tsx +17 -0
  138. package/src/teste/AttachmentCardLista.test.tsx +53 -0
  139. package/src/teste/AttachmentCardSm.test.tsx +29 -0
  140. package/src/teste/BadgeAttachedTomEPadding.test.tsx +60 -0
  141. package/src/teste/BadgeNeutroColado.test.tsx +15 -0
  142. package/src/teste/BadgeTag.test.tsx +21 -0
  143. package/src/teste/ButtonDensidade.test.tsx +40 -0
  144. package/src/teste/CalendarCabecalho.test.tsx +11 -0
  145. package/src/teste/CalendarCompacto.test.tsx +37 -0
  146. package/src/teste/CoachmarkSemVeu.test.tsx +101 -0
  147. package/src/teste/CoachmarkUmPasso.test.tsx +45 -0
  148. package/src/teste/ColorPickerXs.test.tsx +22 -0
  149. package/src/teste/DataTableArvoreEVariantes.test.tsx +240 -0
  150. package/src/teste/DataTableCompactaETom.test.tsx +85 -0
  151. package/src/teste/DescriptionListCompacta.test.tsx +24 -0
  152. package/src/teste/EmptyStateTituloRico.test.tsx +34 -0
  153. package/src/teste/InputAgrupado.test.tsx +26 -0
  154. package/src/teste/InputGhost.test.tsx +42 -0
  155. package/src/teste/ListItemTooltipStandalone.test.tsx +64 -0
  156. package/src/teste/ModalProporcoes1Doc.test.tsx +36 -0
  157. package/src/teste/RichTextEditorAlinhaImagemTabela.test.tsx +238 -0
  158. package/src/teste/RichTextEditorEstiloDeTexto.test.tsx +137 -0
  159. package/src/teste/SegmentedControlContador.test.tsx +43 -0
  160. package/src/teste/SegmentedControlSuperficie.test.tsx +52 -0
  161. package/src/teste/SelectAbertoControladoEFlutuante.test.tsx +180 -0
  162. package/src/teste/SelectFiltroCorETamanho.test.tsx +90 -0
  163. package/src/teste/SelectItemComEscopo.test.tsx +69 -0
  164. package/src/teste/SelectListaFiltro.test.tsx +120 -0
  165. package/src/teste/StatCardSecundariaETom.test.tsx +51 -0
  166. package/src/teste/StatCardTamanhoSm.test.tsx +42 -0
  167. package/src/teste/TabsCompacta.test.tsx +45 -0
  168. package/src/teste/TagPositivoTingido.test.tsx +60 -0
  169. package/src/teste/ToastAcaoEDetalhes.test.tsx +109 -0
  170. package/src/teste/lerArquivo.ts +13 -0
  171. package/src/utils/html-seguro.ts +105 -2
  172. package/src/utils/toast.ts +12 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,658 @@
1
1
  # @1doc/1ds-react
2
2
 
3
+ ## 2.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - bf2cfdc: feat(accordion): `open` e `onOpenChange`, abertura controlada
8
+
9
+ `open` (lista de ids dos itens abertos) e `onOpenChange` (recebe a nova lista a cada abrir ou fechar). Com `open`, quem manda é o
10
+ app: o clique só pede e o painel muda quando `open` muda, para lembrar a escolha entre visitas (as seções do CrisDoc). Sem `open`, o
11
+ Accordion guarda o próprio estado, como antes (começando pelos `defaultOpen`), e `onOpenChange` também avisa. `open=[]` é controlado
12
+ (tudo fechado), não ausência. Item desabilitado não pede nada.
13
+
14
+ ```vue
15
+ <Accordion
16
+ :items="secoes"
17
+ multiple
18
+ :open="abertos"
19
+ :onOpenChange="(ids) => (abertos = ids)"
20
+ />
21
+ ```
22
+
23
+ - 9c8baa3: feat(badge): `2xs` com 8px de padding lateral; `attached` com 22px e o tom escuro como opção (`attachedTone`)
24
+
25
+ - `size="2xs"`: o padding lateral passa de 4px a 8px, como o selo do CrisDoc. A altura segue em 16px e a fonte em 10px.
26
+ - `attached`: o rótulo colado tem altura mínima de 22px (24 - 2) de qualquer tamanho; o `md` (padrão) já media 22 e
27
+ o `xs` e o `2xs` colados sobem a ele.
28
+ - `attachedTone="dark"` (novo; padrão `light`): o neutro sólido colado em cinza escuro (`neutral-dark-down`) com texto
29
+ branco, o rótulo escuro do CrisDoc. O ardósia do CrisDoc dá 2,9:1 com texto branco, então o DS usa o token que passa
30
+ (7,3:1 e inverte sozinho nos temas escuros). Só vale com `attached`, `variant="neutral"` e `appearance="solid"`.
31
+
32
+ ```vue
33
+ <Badge
34
+ attached
35
+ size="xs"
36
+ variant="neutral"
37
+ appearance="solid"
38
+ attachedTone="dark"
39
+ >Tarefa manual</Badge>
40
+ ```
41
+
42
+ - 7883c6b: feat(button): `density="comfortable"`, o `sm` com 12px de padding lateral
43
+
44
+ O botão pequeno do CrisDoc tem 12px de padding lateral e o `sm` do DS tem 8px. Mudar o `sm` alargaria todo botão que já o
45
+ usa, então a diferença virou uma densidade: `density="comfortable"` leva o `sm` a 12px (a altura de 32px, a fonte e o raio
46
+ não mudam). Sem a prop, nenhum botão muda. Nos outros tamanhos a prop não faz diferença (`xs` já usa 12px, `md` 16px e
47
+ `lg` 24px), e o botão só de ícone, de largura fixa, fica de fora.
48
+
49
+ ```vue
50
+ <Button
51
+ variant="secondary"
52
+ size="sm"
53
+ density="comfortable"
54
+ >Personalizar</Button>
55
+ ```
56
+
57
+ - c101901: feat(calendar): `density="compact"`, evento de 20px
58
+
59
+ `density` (`default` | `compact`). O `compact` leva o evento a 20px de altura (16 + 4, o degrau do DS mais perto dos 20,5 do CrisDoc;
60
+ o padrão dá 25) com 4px de padding lateral (o padrão tem 8) e linha de 16px. Com menos padding o título cabe inteiro onde antes
61
+ cortava; ele só é cortado, com reticências, quando passa da largura da célula. O padrão não muda.
62
+
63
+ ```vue
64
+ <Calendar :events="eventos" density="compact" />
65
+ ```
66
+
67
+ - c9c05cc: feat(coachmark): com um passo só, sem o contador "1 de 1"
68
+
69
+ O contador ("2 de 8") só aparece com mais de um passo, no cartão e na região `aria-live`: com um passo o leitor de
70
+ tela ouve só o título. É o caso da dica pontual (`modal={false}`) e de qualquer tour de um passo. `counterLabel`
71
+ continua valendo para os tours com mais passos. O botão do último passo segue sendo "Concluir" (`finishLabel`).
72
+
73
+ - ad47648: feat(datatable): `density="compact"` com cabeçalho e linha de 44px, e tom por linha (`rowTone`)
74
+
75
+ - `density="compact"`: `th` e `td` ganham `height` igual à altura de campo do DS (44px), no lugar dos 38 e 49 de
76
+ antes. É mínimo: conteúdo mais alto (avatar, botão) estica a linha. A tabela de documento (`variant="document"`)
77
+ continua justa.
78
+ - `rowTone`: o nome do campo da linha com o tom, ou uma função `(row, rowIndex) => tom`. Tons: `negative`,
79
+ `positive`, `info` (fundo claro da cor semântica) e `muted` (texto esmaecido). A linha selecionada ou destacada
80
+ vence o tom e o tom vence a zebra. Tom desconhecido é ignorado. O tom é decoração: o estado também vai em texto.
81
+
82
+ ```vue
83
+ <DataTable
84
+ density="compact"
85
+ :columns="colunas"
86
+ :data="usuarios"
87
+ :rowTone="
88
+ (u) => (u.bloqueado ? 'negative' : u.desligado ? 'muted' : undefined)
89
+ "
90
+ />
91
+ ```
92
+
93
+ - a1de816: feat(input): `variant="ghost"`, a busca dentro de um painel
94
+
95
+ `variant` (`default` | `ghost`). O `ghost` tira a borda escura do repouso: fundo cinza claro (`background-light`) e borda clara
96
+ (`neutral-light-medium`). Só o repouso muda: hover (borda mais escura), foco (borda azul e anel), erro, desabilitado e somente leitura
97
+ são os do campo padrão, e o ícone, o placeholder e o cursor seguem dizendo que é um campo. Sem a prop, nada muda.
98
+
99
+ ```vue
100
+ <Input
101
+ variant="ghost"
102
+ size="sm"
103
+ fullWidth
104
+ ariaLabel="Buscar filtros"
105
+ placeholder="Buscar filtros"
106
+ />
107
+ ```
108
+
109
+ - 9e41dc1: feat(modal): `density="1doc"`, as proporções do modal do CrisDoc
110
+
111
+ `density` (`default` | `1doc`) leva o cabeçalho a 67px (o padrão dá 61), o rodapé a 65px (o padrão dá 73, com o padding de 12px 24px)
112
+ e o raio a 12px (o padrão é 8px). As alturas são mínimas: título com subtítulo ou botão mais alto continua crescendo. Combina com
113
+ `variant="primary"`. A tela cheia e o painel (`responsive`) mantêm os cantos deles. Sem a prop, o modal não muda. Sem token para
114
+ essas medidas: literais comentados no CSS.
115
+
116
+ ```vue
117
+ <Modal
118
+ :open="aberto"
119
+ density="1doc"
120
+ variant="primary"
121
+ title="Resolver tarefa"
122
+ width="600px"
123
+ />
124
+ ```
125
+
126
+ - 7d9e687: feat(segmentedcontrol): `variant="surface"`, o escolhido em superfície branca
127
+
128
+ `variant` (`default` | `surface`). No `surface` o trilho é cinza claro, sem divisores, e o segmento escolhido é uma peça branca com
129
+ sombra, texto escuro e negrito (o seletor do CrisDoc). A seleção não depende só do tom: o peso e a sombra a dizem. O contador do
130
+ escolhido fica cinza sobre o branco e o dos outros, branco sobre o trilho. O padrão (azul cheio) não muda.
131
+
132
+ ```vue
133
+ <SegmentedControl
134
+ label="Modo"
135
+ variant="surface"
136
+ :options="opcoes"
137
+ :value="modo"
138
+ :onChange="trocar"
139
+ />
140
+ ```
141
+
142
+ - bf81dfa: feat(select): a lista do filtro tem a largura do gatilho, com `listMinWidth` e sem passar da janela
143
+
144
+ Regressão do 2.10 no `Select variant="filter"` (a lista do Marcadores da inbox media 556px e passava 17px da borda):
145
+
146
+ - Causa: o wrapper do filtro tinha `width: auto` e é `display: flex` (bloco), então se esticava até a largura do pai;
147
+ o `100%` da lista passava a ser a do pai e não a do gatilho. Agora é `fit-content`.
148
+ - A lista tem a largura do gatilho (nunca menor), cresce até o conteúdo e fica dentro da janela: o campo de busca
149
+ não entra mais na conta da largura (`contain: inline-size`) e acompanha a lista.
150
+ - Perto da borda direita a lista se alinha ao fim do gatilho (medido ao abrir). Na lista flutuante dentro de
151
+ diálogo, o floating-ui ganhou `shift` com 8px de respiro.
152
+ - `listMinWidth` (número em px ou medida CSS) troca o mínimo de 240px: o CrisDoc usa 220.
153
+
154
+ ```vue
155
+ <Select
156
+ variant="filter"
157
+ ariaLabel="Marcadores"
158
+ placeholder="Marcadores"
159
+ searchable
160
+ :listMinWidth="220"
161
+ :options="marcadores"
162
+ />
163
+ ```
164
+
165
+ - cfe3687: feat(select): `item` com o escopo da opção, na lista e no gatilho
166
+
167
+ O conteúdo de cada opção agora recebe a opção nos dois frameworks:
168
+
169
+ - Vue: o slot `#item="{ optionData }"` (o Mitosis gerava `<slot name="item">` sem escopo e o `optionData` chegava `undefined`; o
170
+ `postbuild.js` passa `optionData` e o apelido `option`).
171
+ - React: `item` pode ser uma função `({ optionData }) => nó` (antes, a função virava filho inválido). O nó solto, sem escopo,
172
+ continua valendo na lista.
173
+ - Com a opção escolhida (seleção única), o gatilho mostra o conteúdo do `item` no lugar do texto: o "SeletorComEtiqueta" do
174
+ CrisDoc, com nome e etiqueta, aparece igual na lista e no campo. Sem valor (placeholder), na seleção múltipla e com o nó solto do
175
+ React, o gatilho segue com o texto.
176
+
177
+ ```vue
178
+ <Select label="Prioridade" :options="opcoes" :value="valor" :onChange="mudar">
179
+ <template #item="{ optionData }"><strong>{{ optionData.label }}</strong> {{ optionData.etiqueta }}</template>
180
+ </Select>
181
+ ```
182
+
183
+ - 53dfebe: feat(statcard): `size="sm"`, o KPI com o número a 18px/800
184
+
185
+ Os KPIs da home do CrisDoc têm o número a 18px/800. `size="sm"` leva o número a esse tamanho (o `md`, padrão, segue
186
+ em 24/700). Vale também com `labelPosition="top"`, que tem o número em 32/800: o `sm` vence. O 18px não está na escala
187
+ de fonte do DS (que vai de 16 a 20) e fica como literal comentado, como o 10px do `Badge` 2xs. O número continua antes
188
+ do rótulo no HTML.
189
+
190
+ ```vue
191
+ <StatCard
192
+ size="sm"
193
+ label="Minhas tarefas"
194
+ :value="12"
195
+ :icon="faClock"
196
+ variant="primary"
197
+ />
198
+ ```
199
+
200
+ - 4471b90: feat(tabs): `density="compact"`, abas de 40px
201
+
202
+ O `Tabs` ganha `density` (`default` | `compact`). O `compact` leva a altura mínima das abas de 48px a 40px (o degrau `sm` do DS) com
203
+ padding vertical de 8px, para barras de abas dentro de uma tela (o CrisDoc usa 40). A pílula do contador (`count`) não muda e já
204
+ era o que o CrisDoc pede: cinza (`neutral-light-medium`) na aba inativa e azul só na ativa, nas duas densidades. Sem a prop, nenhuma
205
+ aba muda.
206
+
207
+ ```vue
208
+ <Tabs :value="aba" :onChange="trocar" density="compact" ariaLabel="Processos">
209
+ <Tab label="Fluxos" index="1" :count="56" />
210
+ </Tabs>
211
+ ```
212
+
213
+ ### Patch Changes
214
+
215
+ - 7ccb05c: fix(tag): `variant="positive"` outlined com o texto em `positive-dark`
216
+
217
+ O contorno da tag outlined é transparente, então o texto cai sobre o fundo de quem está atrás, que muitas vezes é
218
+ tingido (o azul-claro de um card). `positive-pure` sobre `primary-light` dá 3,6:1 e reprova o WCAG 1.4.3;
219
+ `positive-dark` dá 7,9:1 e é o mesmo par de texto da tag `soft`. Nos temas escuro e de alto contraste o `dark` também
220
+ passa de 4,5:1. O contorno continua em `positive-pure`. As outras variantes não mudam.
221
+
222
+ ## 2.10.0
223
+
224
+ ### Minor Changes
225
+
226
+ - 12c65e9: feat(accordion): `titleVariant="neutral"`, o título de texto
227
+
228
+ `titleVariant` aceita `default` (o título como era) e `neutral`: 14px na cor do texto
229
+ (`neutral-dark-pure`), peso médio, também no hover e no aberto, sem cor de ação. O chevron
230
+ aberto continua azul (é o sinal do estado). Combina com qualquer `variant`.
231
+
232
+ ```vue
233
+ <Accordion :items="itens" variant="separated" titleVariant="neutral" />
234
+ ```
235
+
236
+ - 6df8835: feat(attachmentcard): `size="sm"`, o cartão compacto do CrisDoc
237
+
238
+ `size="sm"` leva o ícone do preview a 40px (no `md`, 48px) e o ícone do rodapé a
239
+ 12px (no `md`, o `sm` do `Icon`). A largura do cartão, os selos e o painel não
240
+ mudam. Sem `size`, ou com `md`, o cartão é o mesmo.
241
+
242
+ ```vue
243
+ <AttachmentCard
244
+ fileName="Protocolo 104-2026.pdf"
245
+ documentType="Parecer"
246
+ size="sm"
247
+ :onOpen="abrir"
248
+ />
249
+ ```
250
+
251
+ - 4ab330c: feat(badge): `attachedSide="left" | "right"` no `Badge attached`
252
+
253
+ O rótulo colado no topo do card pode ir para o canto direito. Sem a prop, ou com
254
+ `left`, continua no esquerdo. Só vale com `attached`.
255
+
256
+ ```vue
257
+ <Badge
258
+ :attached="true"
259
+ attachedSide="right"
260
+ size="sm"
261
+ appearance="solid"
262
+ variant="primary"
263
+ >Prazo hoje</Badge>
264
+ ```
265
+
266
+ - 1f805cd: feat(coachmark): `modal={false}`, o cartão sem véu nem foco preso, para dica pontual
267
+
268
+ Com `modal={false}` não há véu, recorte nem foco preso: o cartão é um popover
269
+ ancorado no alvo (`role="dialog"` com `aria-modal="false"`). A página segue
270
+ clicável, o foco entra no cartão ao abrir mas o Tab pode sair dele, e o Esc fecha de
271
+ qualquer lugar da página (uma vez só, com o motivo `escape`). Ao fechar, o foco só
272
+ volta ao elemento de antes se a pessoa não foi a outro lugar. Sem a prop, o tour é
273
+ modal como sempre (no Vue, `modal` é `any` para a ausência não virar `false`).
274
+
275
+ Corrige também o elemento de antes guardado duas vezes no React (o segundo
276
+ `sincronizar`, antes de o `active` valer, guardava o próprio cartão e o foco não voltava).
277
+
278
+ ```vue
279
+ <Coachmark
280
+ :open="aberto"
281
+ :modal="false"
282
+ :hideSkip="true"
283
+ finishLabel="Entendi"
284
+ :steps="[{ target: '#salvar', title: 'Novo: salvar com Ctrl+S' }]"
285
+ :onClose="() => (aberto = false)"
286
+ />
287
+ ```
288
+
289
+ - 46b3b42: feat(colorpicker): `size="xs"`, a amostra de 20px do CrisDoc
290
+
291
+ `size` ganha `xs` (20px), além de `sm` (24px) e `md` (32px). O anel de seleção (o anel duplo)
292
+ e o roving tabindex são os mesmos nos três tamanhos. O `sm` segue em 24px: o `xs` é o 20px do
293
+ CrisDoc.
294
+
295
+ ```vue
296
+ <ColorPicker
297
+ ariaLabel="Marcador"
298
+ size="xs"
299
+ :families="['blue', 'red']"
300
+ defaultValue="--umds-primitive-red-pure"
301
+ />
302
+ ```
303
+
304
+ - 82e85c5: feat(datatable): cabeçalho escuro, zebra, destaque de linha, vazio com ícone, `hideHeader` e linhas hierárquicas (`treeData`)
305
+
306
+ Tudo opt-in; sem as props novas a tabela é a mesma.
307
+
308
+ - `headerVariant="dark"`: cabeçalho navy com texto claro (`background-dark` e
309
+ `neutral-light-pure`, então o tema acompanha). `headerUppercase`: caixa alta
310
+ nos rótulos, vale para qualquer cabeçalho.
311
+ - `striped`: zebra nas linhas ímpares.
312
+ - `selectedRowKeys` (com `rowKey`) e `isRowSelected(row, index)`: destacam a linha
313
+ sem checkbox (fundo, barra de 4px à esquerda e `aria-selected`). Serve à linha
314
+ "aberta" de uma lista mestre-detalhe. `selectedKeys` segue sendo o checkbox.
315
+ - `emptyIcon` (objeto Font Awesome, padrão `faInbox`) e `emptyDescription`.
316
+ - `hideHeader`: o cabeçalho some da tela e as colunas continuam nomeadas para o
317
+ leitor de tela (a linha fica visualmente oculta, não removida).
318
+ - `density="compact"` + `variant="document"`: fonte de 12px e célula de 4px × 8px.
319
+ A escala do DS não tem 13px, então o compacto da tabela de interface segue em 14.
320
+ - `treeData` + `childrenKey`: linhas hierárquicas. A tabela vira `role="treegrid"`,
321
+ as linhas ganham `aria-level`, `aria-posinset`, `aria-setsize` e `aria-expanded`,
322
+ e a primeira coluna leva recuo por nível, fios (tee, cotovelo e linha contínua) e o
323
+ botão de expandir/recolher. Teclado: ↓ ↑ andam, → expande (ou desce à primeira
324
+ filha), ← recolhe (ou sobe ao pai), Home e End. Uma linha por vez na ordem de Tab.
325
+ Estado: `expandedKeys` (controlado), `defaultExpandedKeys`, `defaultExpandAll` e
326
+ `onExpand(chaves, linha, expandida)`. A chave é o `rowKey`; sem ele, o caminho de
327
+ índices. `expandLabel` e `collapseLabel` traduzem o botão. Com `treeData`, os índices
328
+ dos callbacks contam as linhas visíveis.
329
+
330
+ O slot `#cell-<key>` do Vue segue valendo na coluna da árvore (o `postbuild` agora
331
+ liga as duas ocorrências da célula).
332
+
333
+ ```vue
334
+ <DataTable
335
+ :columns="colunas"
336
+ :data="setores"
337
+ rowKey="id"
338
+ :treeData="true"
339
+ headerVariant="dark"
340
+ :headerUppercase="true"
341
+ :striped="true"
342
+ :defaultExpandedKeys="['gab']"
343
+ :onExpand="aoExpandir"
344
+ >
345
+ <template #cell-nome="{ row }"><strong>{{ row.sigla }}</strong> {{ row.nome }}</template>
346
+ </DataTable>
347
+ ```
348
+
349
+ - 1c9f7cb: feat(descriptionlist): `density="compact"`, a fonte de 12px do CrisDoc
350
+
351
+ `density="compact"` leva a fonte da lista de 14 para 12px (nos dois desenhos), aperta o
352
+ espaço entre os pares do `stacked` (de 16 para 12px) e o padding do valor com `bordered`.
353
+ Sem a prop, ou com `default`, a lista é a mesma.
354
+
355
+ ```vue
356
+ <DescriptionList
357
+ :items="dados"
358
+ layout="stacked"
359
+ :bordered="true"
360
+ density="compact"
361
+ />
362
+ ```
363
+
364
+ - d062029: feat(emptystate): título com conteúdo rico (elemento no React, slot `title` no Vue)
365
+
366
+ O `title` do `EmptyState` aceita conteúdo (negrito, link, ícone). No React é um
367
+ elemento na própria prop; no Vue é o slot `title`, com a prop como texto de reserva.
368
+ O título passa a ser um `div` (antes um `p`), com a mesma classe e o mesmo visual,
369
+ para o conteúdo de bloco não virar HTML inválido. `title` deixou de ser obrigatório
370
+ na tipagem: no Vue o slot basta.
371
+
372
+ ```vue
373
+ <EmptyState :icon="faMagnifyingGlass" description="Ajuste o filtro de setor.">
374
+ <template #title>Nenhum processo para <strong>SOBR</strong></template>
375
+ </EmptyState>
376
+ ```
377
+
378
+ - 29955dd: feat(input): `grouped`, o campo dentro de um contêiner que já tem moldura e foco (campo de chips)
379
+
380
+ Opt-in. `grouped` implica `borderless` e tira a altura de campo, o padding e o anel
381
+ de foco próprio do `Input`: a altura vem do conteúdo (a linha cresce com as tags), o
382
+ campo ocupa o espaço que sobra (`flex: 1 1 80px`, sem `fullWidth`) e quem mostra o foco é
383
+ o contêiner, com `:focus-within`. O `borderless` sozinho continua como era: com altura de
384
+ campo e o contorno de foco para dentro. Sem o foco no contêiner, quem usa teclado perde o
385
+ indicador (WCAG 2.4.7): a doc da prop avisa.
386
+
387
+ ```vue
388
+ <div class="chips-campo"> <!-- a moldura e o :focus-within são seus -->
389
+ <Tag label="SADM" size="sm" />
390
+ <Input ariaLabel="Adicionar setor" :grouped="true" size="sm" />
391
+ </div>
392
+ ```
393
+
394
+ - 76c0087: feat(listitem): `tooltip`, `standalone` e atributos HTML só no elemento interativo
395
+
396
+ - `tooltip`: vira o atributo HTML `title` do `button`, `a` ou `div` (a dica nativa do
397
+ navegador). `title` continua sendo o título da linha, não o atributo.
398
+ - `standalone`: renderiza sem o `li`, só o elemento interativo, para usar fora de um
399
+ `List` (botão de número de página, item de carrossel). `class` (Vue) ou `className`
400
+ vai ao elemento.
401
+ - Correção no Vue: `aria-*`, `role`, `data-*` e `style` iam ao `li` além do elemento
402
+ interativo (o `aria-label` aparecia duas vezes e o `li` ganhava um `role` que não era
403
+ dele). Agora o `inheritAttrs` está desligado e esses atributos vão só ao elemento
404
+ interativo, como no React. O `class` do Vue continua no `li`, como sempre. Por baixo,
405
+ o ListItem passa a ter duas raízes (com `li` e `standalone`), então o HTML do servidor
406
+ abre com marcador de fragmento.
407
+
408
+ ```vue
409
+ <ListItem
410
+ :standalone="true"
411
+ title="12"
412
+ tooltip="Página 12"
413
+ :selected="pagina === 12"
414
+ :onClick="irPara"
415
+ />
416
+ ```
417
+
418
+ - 3500910: feat(richtexteditor): alinhamento, imagem e tabela simples na `toolbar`
419
+
420
+ Opt-in: a barra padrão não muda. Entram na `toolbar` por nome:
421
+
422
+ - `alignLeft`, `alignCenter`, `alignRight`, `alignJustify`: botões de liga/desliga
423
+ que seguem o cursor (`aria-pressed`). O valor guarda `text-align` nos blocos.
424
+ - `image`: abre um painel (como o do link) com o endereço da imagem, o arquivo
425
+ (PNG, JPEG, GIF ou WebP até 2 MB, que entra como `data:` URL) e o texto
426
+ alternativo. Endereço e arquivo inválidos mostram o erro e o painel continua aberto.
427
+ - `table`: abre um painel com linhas e colunas (1 a 20 e 1 a 10, padrão 3 × 3) e
428
+ insere a tabela. Com o cursor numa célula aparece a barra de adicionar e remover
429
+ linha e coluna e remover a tabela (mexe no DOM, então fica fora do desfazer).
430
+
431
+ A higienização do valor passou a aceitar `text-align` nos blocos (também pelo
432
+ atributo `align`), `img` e a tabela (`table`, `thead`, `tbody`, `tr`, `th`, `td`
433
+ com `colspan` e `rowspan`). Imagem só vale com `http(s)`, caminho (`/x`, `./x`,
434
+ `../x`) ou `data:image` em base64 de PNG, JPEG, GIF e WebP; SVG, `javascript:`,
435
+ `//host` e o resto saem inteiros. Colar continua entrando como texto puro.
436
+
437
+ Todos os textos novos vêm por `labels` (`imageUrl`, `imageAlt`, `imageFile`,
438
+ `imageApply`, `imageCancel`, `imageInvalid`, `imageType`, `imageTooLarge`,
439
+ `tableRows`, `tableCols`, `tableApply`, `tableCancel`, `tableInvalid`,
440
+ `tableActions`, `tableAddRow`, `tableRemoveRow`, `tableAddCol`, `tableRemoveCol`,
441
+ `tableRemove` e o nome de cada ferramenta nova).
442
+
443
+ ```vue
444
+ <RichTextEditor
445
+ label="Parecer"
446
+ :defaultValue="html"
447
+ :toolbar="[
448
+ 'bold',
449
+ 'italic',
450
+ '|',
451
+ 'alignLeft',
452
+ 'alignCenter',
453
+ 'alignRight',
454
+ 'alignJustify',
455
+ '|',
456
+ 'link',
457
+ 'image',
458
+ 'table',
459
+ ]"
460
+ />
461
+ ```
462
+
463
+ - af0d976: feat(richtexteditor): família, tamanho de fonte e cor do texto, por token do DS
464
+
465
+ Opt-in na `toolbar`: `fontFamily`, `fontSize` e `textColor`. Cada um abre um painel abaixo da
466
+ barra e aplica ao texto selecionado, embrulhando-o num `<span style="...">`:
467
+
468
+ - `fontFamily`: padrão ou monoespaçada (`var(--umds-semantic-font-family-base|mono)`), num `Select`.
469
+ - `fontSize`: 12, 14, 16, 20 e 24px, os degraus da escala do DS (`var(--umds-primitive-font-size-*)`).
470
+ - `textColor`: a paleta do DS, num `ColorPicker` `xs`; o valor guarda o `var()` do token escolhido.
471
+
472
+ Sem texto selecionado o painel pede a seleção e não aplica nada. Esc fecha só a lista do `Select`
473
+ aberta; o seguinte fecha o painel. Para voltar ao padrão, use `clear`.
474
+
475
+ A higienização aceita `color`, `font-size` e `font-family` só em `<span>` e só com token do DS: cor
476
+ em hex, `rgb()` ou nome, tamanho em px e fonte por nome saem, e o resto do `style` também.
477
+
478
+ Textos novos por `labels`: `fontFamily`, `fontSize`, `textColor`, `fontFamilyBase`,
479
+ `fontFamilyMono`, `styleClose` e `styleNeedsSelection`.
480
+
481
+ ```vue
482
+ <RichTextEditor
483
+ label="Parecer"
484
+ :toolbar="['bold', 'italic', '|', 'fontFamily', 'fontSize', 'textColor']"
485
+ />
486
+ ```
487
+
488
+ - 992f59a: feat(segmentedcontrol): `count` por item, a pílula do contador como a do `Tab`
489
+
490
+ Cada opção aceita `count` (número ou texto): uma pílula de 18px depois do rótulo,
491
+ cinza no segmento solto e branca sobre o azul do escolhido (o mesmo desenho do
492
+ contador do `Tab`). `0` aparece; vazio e ausente não. O contador entra no nome
493
+ acessível do segmento ("Todas 31"). Sem `count`, o segmento é o mesmo.
494
+
495
+ ```vue
496
+ <SegmentedControl
497
+ label="Fila"
498
+ :value="fila"
499
+ :onChange="(v) => (fila = v)"
500
+ :options="[
501
+ { label: 'Todas', value: 'todas', count: 31 },
502
+ { label: 'Minhas', value: 'minhas', count: 12 },
503
+ ]"
504
+ />
505
+ ```
506
+
507
+ - 22a79d8: feat(select): `open`/`onOpenChange`, gatilho com ícone e amostra de cor, variantes `search` e `combo`, lista por cima de diálogo e `placement="auto"` que mede o ancestral
508
+
509
+ Tudo opt-in; o Select sem as props novas se comporta como antes, fora de diálogo.
510
+
511
+ - `open` e `onOpenChange(open)`: a lista controlada de fora. O clique, o teclado,
512
+ o clique fora, o Esc e a escolha de uma opção avisam o pai, que decide o novo
513
+ `open`. Sem `open`, o Select abre e fecha sozinho e também avisa. É o que deixa o
514
+ filtro com ação no rodapé fechar a lista antes de abrir um modal.
515
+ - `triggerIcon` (objeto Font Awesome) e `triggerSwatch` (um token de cor): ícone e
516
+ amostra de cor à esquerda do texto do gatilho, decorativos.
517
+ - `variant="search"` (o filtro numa barra de busca: altura de campo e contorno neutro)
518
+ e `variant="combo"` (colado a outro controle, sem borda nem raio próprios). Os dois
519
+ são filtro: busca focada ao abrir, `emptyOptionLabel` e o rodapé valem.
520
+ - Dentro de um diálogo (`role="dialog"` ou `aria-modal`), a lista abre por cima dele:
521
+ `position: fixed` ancorada no gatilho pelo `@floating-ui/dom`, com a largura do
522
+ gatilho e a altura limitada ao espaço da janela. O `overflow` do corpo do modal
523
+ não corta mais a lista.
524
+ - `placement="auto"` agora mede também cada ancestral que rola ou corta (um corpo de
525
+ modal, um painel com `overflow`), não só a janela, e limita a altura da lista ao
526
+ espaço que sobra (mínimo de 96px).
527
+ - `required` repassa `aria-required` ao combobox.
528
+
529
+ ```vue
530
+ <Select
531
+ variant="filter"
532
+ ariaLabel="Marcadores"
533
+ placeholder="Marcadores"
534
+ :triggerIcon="faTag"
535
+ :open="aberto"
536
+ :onOpenChange="(v) => (aberto = v)"
537
+ :options="marcadores"
538
+ :value="valor"
539
+ :onChange="(v) => (valor = v)"
540
+ >
541
+ <template #footer>
542
+ <Button variant="text" size="sm" @click="abrirGerenciador">Gerenciar marcadores</Button>
543
+ </template>
544
+ </Select>
545
+ ```
546
+
547
+ - f7fa5dd: feat(select): o filtro no tamanho do CrisDoc, com cor por opção (`option.color`)
548
+
549
+ Para substituir o `FiltroSelect` do app:
550
+
551
+ - As variantes de filtro (`filter`, `search`, `combo`) nascem no tamanho `sm` (32px, fonte de
552
+ 12px) quando `size` não é passado; `size="md"` continua valendo. O `Select` padrão não muda.
553
+ - O gatilho do `filter` tem fundo branco com contorno azul. O azul-claro só vem depois de
554
+ escolhido um valor (a classe `umds-select--has-value`), que é quando o filtro está
555
+ recortando a lista. `search` e `combo` mantêm o fundo deles.
556
+ - `option.color` (um token, `var(--umds-semantic-color-...)`): uma amostra de 12px antes do
557
+ texto de cada opção na lista e, com a opção escolhida (seleção única), no gatilho.
558
+ `triggerSwatch` explícito manda sobre ela. A cor é decorativa: o nome da opção continua
559
+ sendo o texto.
560
+ - O `useStore` do `Select` passou a checar o gatilho antes do `autoUpdate` (o `tsc` do React
561
+ acusava o `null`).
562
+
563
+ ```vue
564
+ <Select
565
+ variant="filter"
566
+ ariaLabel="Marcadores"
567
+ placeholder="Marcadores"
568
+ :triggerIcon="faFilter"
569
+ :options="[
570
+ {
571
+ label: 'Urgente',
572
+ value: 'urgente',
573
+ color: 'var(--umds-semantic-color-feedback-negative-pure)',
574
+ },
575
+ ]"
576
+ />
577
+ ```
578
+
579
+ - b9f0813: feat(statcard): segunda medida (`secondaryValue`/`secondaryLabel`) e `valueTone`
580
+
581
+ - `secondaryValue` e `secondaryLabel`: a segunda medida do cartão, menor (20px), à direita da
582
+ principal, separada por um filete ("22,31% Meu Setor | 14,11% Geral"). No HTML vem depois do
583
+ resto, então o leitor de tela lê a medida principal inteira antes. `0` aparece; vazio e
584
+ ausente não. Com `labelPosition="top"` a grade ganha uma terceira coluna.
585
+ - `valueTone`: cor do número principal, `default` | `primary` | `positive` | `negative` |
586
+ `info`, pelas variantes escuras (contraste AA no branco). Não mexe na `variant`, que segue
587
+ pintando o ícone e a variação.
588
+
589
+ ```vue
590
+ <StatCard
591
+ labelPosition="top"
592
+ label="Eficiência"
593
+ value="22,31%"
594
+ description="Meu Setor"
595
+ secondaryValue="14,11%"
596
+ secondaryLabel="Geral"
597
+ valueTone="primary"
598
+ />
599
+ ```
600
+
601
+ - a4b6bb7: feat(toast): ação (`actionLabel`/`onAction`) e lista de detalhes (`details`)
602
+
603
+ - `actionLabel` + `onAction`: um botão depois do texto ("Desfazer", "Ver processo").
604
+ Acionar chama `onAction` e depois fecha o toast (`onClose`). O botão só aparece com os
605
+ dois. O botão de fechar continua ao lado.
606
+ - `details`: lista de linhas curtas abaixo da descrição ("Anexo 1 acima de 10 MB").
607
+ - No `toast()` imperativo e no `ToastStack`, as três opções passam adiante. Toast com ação
608
+ tem `duration: 0` por padrão (não some antes de dar tempo de agir, WCAG 2.2.1); sem ação
609
+ continua em 5000, e um `duration` explícito vale sempre.
610
+
611
+ ```ts
612
+ toast({
613
+ message: "Despacho enviado",
614
+ variant: "positive",
615
+ actionLabel: "Desfazer",
616
+ onAction: desfazer,
617
+ });
618
+ ```
619
+
620
+ ### Patch Changes
621
+
622
+ - 6c12a37: fix(appsubheader): a região do contexto ocupa a altura da barra e só rola na horizontal
623
+
624
+ Com a trilha só na página atual (um `Breadcrumb` sem link), o axe acusava
625
+ `scrollable-region-focusable`. Medido no navegador: a região do contexto tinha 12px de
626
+ altura (a do item do Breadcrumb, `line-height: 1` em 12px) e `scrollHeight` de 14, e como
627
+ `overflow-x: auto` faz o `overflow-y` computar para `auto`, ela virava uma região rolável
628
+ sem nenhum elemento focável dentro. Agora a região ocupa a altura da barra
629
+ (`align-self: stretch`, 41px, com o conteúdo centralizado) e corta o eixo vertical
630
+ (`overflow-y: hidden`): não há o que rolar na vertical. A rolagem horizontal da trilha longa
631
+ continua igual. Story nova "Só a página atual" confere `scrollHeight` e `scrollWidth`.
632
+
633
+ - e8f1894: fix(attachmentcard): o `dl` do painel de conferência passa no axe (`definition-list`)
634
+
635
+ Cada campo do painel era `div > (div > dt + dd) + button`: o `dl` só aceita `div` com `dt` e
636
+ `dd` direto dentro, então o axe acusava `definition-list`. Agora é `div > dt + dd`, e o
637
+ botão de copiar mora dentro do `dd`, ao lado do valor (o valor passou a ter o próprio
638
+ `span`, `umds-attachment-card__campo-valor-texto`). O visual muda só no detalhe: o botão
639
+ de copiar fica alinhado à linha do valor, não ao centro das duas linhas do campo.
640
+
641
+ - 04d5a43: fix(badge): o neutro colado é o cinza claro com texto escuro
642
+
643
+ `<Badge attached variant="neutral" appearance="solid">` ficava no cinza escuro do `solid`
644
+ neutro, pesado demais para o rótulo de um card. Agora o neutro colado e sólido é o cinza claro
645
+ com texto escuro (o "Tarefa manual" do CrisDoc). O `solid` neutro fora do `attached` não muda.
646
+
647
+ - e5896d9: docs(calendar): os slots do cabeçalho no Vue são `#header-start` e `#header-end`
648
+
649
+ O `index.d.ts` e a documentação diziam `headerStart` e `headerEnd` para os dois
650
+ frameworks, mas no Vue só os nomes com hífen chegam ao cabeçalho (o Vue lê o nome do
651
+ slot como está: `#headerStart` é descartado em silêncio). A doc do componente, o
652
+ comentário das props e os `argTypes` dos Storybooks agora dizem: no React, as props
653
+ `headerStart` e `headerEnd` (um nó); no Vue, os slots `#header-start` e `#header-end`.
654
+ Sem mudança de comportamento.
655
+
3
656
  ## 2.9.0
4
657
 
5
658
  ### Minor Changes
@@ -99,6 +99,19 @@
99
99
  opacity: 0.6; /* opacidade do protótipo sem token 1DS */
100
100
  }
101
101
 
102
+ /* ── Título neutro (titleVariant="neutral") ──
103
+ 14px na cor do texto, em peso médio, também no hover e no aberto: o título não
104
+ pega a cor de ação. O chevron aberto continua azul (é o sinal do estado). */
105
+ .umds-accordion--title-neutral .umds-accordion__title {
106
+ font-size: var(--umds-primitive-font-size-xxs); /* 14px */
107
+ font-weight: var(--umds-primitive-font-weight-medium);
108
+ color: var(--umds-semantic-color-neutral-dark-pure);
109
+ }
110
+
111
+ .umds-accordion--title-neutral .umds-accordion__trigger:disabled .umds-accordion__title {
112
+ color: inherit;
113
+ }
114
+
102
115
  /* ── Chevron ──
103
116
  Migrado de <svg> inline para o componente Icon (chevron-down).
104
117
  O wrapper .umds-accordion__chevron recebe cor (via currentColor →