@1doc/1ds-react 2.13.0 → 2.15.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 (66) hide show
  1. package/CHANGELOG.md +62 -59
  2. package/dist/components/AILabel/AILabel.css +1 -1
  3. package/dist/components/Alert/Alert.css +1 -1
  4. package/dist/components/AppShell/AppShell.css +4 -0
  5. package/dist/components/AttachmentCard/AttachmentCard.css +2 -2
  6. package/dist/components/Avatar/Avatar.d.ts +8 -3
  7. package/dist/components/Avatar/Avatar.js +28 -4
  8. package/dist/components/BottomNavigation/BottomNavigation.css +2 -2
  9. package/dist/components/BottomSheet/BottomSheet.css +2 -2
  10. package/dist/components/Box/Box.css +3 -3
  11. package/dist/components/Button/Button.css +6 -1
  12. package/dist/components/Button/Button.d.ts +11 -2
  13. package/dist/components/Button/Button.js +15 -3
  14. package/dist/components/Card/Card.css +5 -5
  15. package/dist/components/Chart/Chart.css +1 -1
  16. package/dist/components/Coachmark/Coachmark.css +1 -1
  17. package/dist/components/Combobox/Combobox.css +1 -1
  18. package/dist/components/ConfirmDialog/ConfirmDialog.css +1 -1
  19. package/dist/components/Counter/Counter.css +43 -0
  20. package/dist/components/Counter/Counter.d.ts +57 -0
  21. package/dist/components/Counter/Counter.js +99 -0
  22. package/dist/components/DatePicker/DatePicker.css +1 -1
  23. package/dist/components/Drawer/Drawer.css +2 -2
  24. package/dist/components/Dropdown/Dropdown.css +3 -1
  25. package/dist/components/Dropdown/Dropdown.d.ts +17 -0
  26. package/dist/components/Dropdown/Dropdown.js +22 -2
  27. package/dist/components/EmptyState/EmptyState.css +12 -0
  28. package/dist/components/EmptyState/EmptyState.d.ts +3 -0
  29. package/dist/components/EmptyState/EmptyState.js +1 -0
  30. package/dist/components/Kanban/Kanban.css +2 -2
  31. package/dist/components/Kanban/KanbanCard.css +2 -2
  32. package/dist/components/List/List.css +83 -0
  33. package/dist/components/List/List.d.ts +3 -0
  34. package/dist/components/List/List.js +6 -2
  35. package/dist/components/List/ListItem.d.ts +19 -0
  36. package/dist/components/List/ListItem.js +5 -1
  37. package/dist/components/Modal/Modal.css +3 -4
  38. package/dist/components/MultiSelect/MultiSelect.css +1 -1
  39. package/dist/components/OrgChart/OrgChart.css +2 -2
  40. package/dist/components/PhoneInput/PhoneInput.css +2 -2
  41. package/dist/components/Popover/Popover.css +1 -1
  42. package/dist/components/SegmentedControl/SegmentedControl.css +1 -1
  43. package/dist/components/Select/Select.css +1 -1
  44. package/dist/components/StatCard/StatCard.css +99 -5
  45. package/dist/components/StatCard/StatCard.d.ts +12 -6
  46. package/dist/components/StatCard/StatCard.js +6 -2
  47. package/dist/components/Switch/Switch.css +2 -2
  48. package/dist/components/Text/Text.d.ts +6 -0
  49. package/dist/components/TimePicker/TimePicker.css +1 -1
  50. package/dist/components/Toast/Toast.css +2 -2
  51. package/dist/components/Tooltip/Tooltip.css +23 -3
  52. package/dist/components/Tooltip/Tooltip.js +33 -2
  53. package/dist/index.d.ts +2 -0
  54. package/dist/index.js +1 -0
  55. package/dist/teste/PedidosMatheus.test.d.ts +1 -0
  56. package/dist/teste/PedidosMatheus.test.js +91 -0
  57. package/dist/teste/PedidosMatheus2.test.d.ts +1 -0
  58. package/dist/teste/PedidosMatheus2.test.js +82 -0
  59. package/dist/teste/SegmentedControlSuperficie.test.js +1 -1
  60. package/dist/teste/StatCardTamanhoSm.test.js +8 -0
  61. package/package.json +3 -3
  62. package/src/index.ts +2 -0
  63. package/src/teste/PedidosMatheus.test.tsx +129 -0
  64. package/src/teste/PedidosMatheus2.test.tsx +102 -0
  65. package/src/teste/SegmentedControlSuperficie.test.tsx +1 -1
  66. package/src/teste/StatCardTamanhoSm.test.tsx +9 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,67 @@
1
1
  # @1doc/1ds-react
2
2
 
3
+ ## 2.15.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 7e46f1c: Avatar: volta sozinho para as iniciais quando a foto falha, e a prop `name` gera as iniciais ("Cris Lima" → "CL") e o nome acessível.
8
+ - 7e46f1c: Dropdown: `onSelect` em cada item, e campos próprios no item (`command`, `payload`...) que voltam no `onSelect` sem cast.
9
+ - 7e46f1c: EmptyState: `fill` para ocupar e centralizar no espaço disponível (o vazio de uma coluna que rola); no List, `emptyFill`.
10
+ - 7e46f1c: ListItem: `variant="primary"` (item em destaque, azul-claro com hover próprio) e `liClassName`/`liStyle` para o `li`, para entrada escalonada.
11
+ - 532cc7f: feat(tokens)!: sombras e tipografia espelham a biblioteca "Design tokens — Redesign" do Figma
12
+
13
+ QUEBRA a API dos tokens de sombra e de tipografia semântica. Como os tokens estão em 0.x, sai como minor.
14
+
15
+ **Sombras** — 18 tokens `--umds-semantic-shadow-{bottom,top,center}-{xs,sm,md,lg,xl,2xl}`, um para cada estilo
16
+ `Shadow/<Direção>/<Tamanho>` do Figma.
17
+ - Saem `--umds-semantic-shadow-xs|sm|md|lg`: troque por `--umds-semantic-shadow-bottom-xs|sm|md|lg` (mesmo valor).
18
+ - Saem os primitivos `--umds-primitive-shadow-level-1..4`, que não existem no Figma. Equivalência usada no core:
19
+ `level-1` → `bottom-md`, `level-2` → `bottom-lg`, `level-3` → `bottom-xl`, `level-4` → `bottom-2xl`.
20
+ Muda o visual de `Box` (`shadow="level1|2|3"`, a prop continua igual), `Tooltip`, `Chart` (tooltip) e `Coachmark`.
21
+ - Sombra por componente, decisão de design:
22
+ - `BottomSheet` (painel e rodapé) e `BottomNavigation` (barra `raised`): `shadow-top-sm`, a sombra sobe a partir da borda de baixo.
23
+ - `Modal` e `ConfirmDialog`: `shadow-center-xl`. O rodapé fixo do `Modal` troca o literal `0 -4px 16px rgba(0,0,0,.08)` por `shadow-top-md`.
24
+ - Listas dos campos de formulário (`Select`, `MultiSelect`, `Combobox`, `DatePicker`, `TimePicker`, `PhoneInput`): `shadow-bottom-md`.
25
+
26
+ **Tipografia** — os papéis semânticos passam a ser os do Figma, cada um com cinco pesos:
27
+ `--umds-semantic-typography-<papel>-{font-size,line-height,letter-spacing}` e
28
+ `--umds-semantic-typography-<papel>-font-weight-{light,regular,medium,semibold,bold}`, com `<papel>` em `giant`,
29
+ `display`, `heading-h1..h4`, `title-lg|md|sm`, `paragraph`, `label` e `caption`.
30
+ - Saem `display-giant`, `display-lg`, `heading-h5`, `heading-h6`, `body-*` e `label-lg|md|sm`, e o `font-weight` único
31
+ de cada papel. Equivalências: `display-giant` → `giant`, `display-lg` → `display`, `heading-h5` → `title-lg`,
32
+ `heading-h6` → `title-md`, `body-lg` → `title-md`, `body-md` → `title-sm`, `body-sm` → `paragraph`,
33
+ `label-md` → `label`, `label-sm` → `caption`, `label-lg` → `title-sm`.
34
+ - Valores alinhados ao Figma: `giant` e `display` com entrelinha 120% e espaçamento −0,01em (eram 100% e −0,02em);
35
+ `label` com entrelinha 133% e 0,02em; `caption` em 170%.
36
+ - Nenhum componente usava os tokens semânticos de tipografia; `Text` e os demais seguem nos primitivos, sem mudança.
37
+
38
+ Atualize `@1doc/1ds-tokens` para a 0.8.0 junto com o react ou o vue: o CSS dos componentes usa os nomes novos e, com os tokens antigos, as sombras somem. A faixa do peer segue `>=0.1.0` (o changesets exige que ela inclua a versão atual; ver `.agent/troubleshooting/tokens-peerdep-forca-major.md`).
39
+
40
+ ### Patch Changes
41
+
42
+ - 7e46f1c: AppShell: o conteúdo herda a cor de texto do tema. No tema escuro, um título sem `color` não fica mais preto.
43
+ - 7e46f1c: StatCard: borda e superfície do Card (`neutral-light-medium` e `background-elevated`). Lado a lado com um Card, o contorno é o mesmo, e no tema escuro o fundo é o elevado.
44
+ - 7e46f1c: StatCard: abaixo de 240px de largura a segunda medida desce para a linha de baixo, em vez de se sobrepor à principal. O cartão com segunda medida ocupa a largura do pai.
45
+ - 7e46f1c: Tooltip: no tema escuro o balão padrão usa a superfície elevada e ganha o traço do Card, e não some mais no fundo. Nos temas claros e no alto contraste nada muda.
46
+ - 7e46f1c: Vue: o `index.d.ts` não declara mais `GlobalComponents`, que colidia com o PrimeVue e quebrava o `vue-tsc` em telas que nem usam o 1DS. Quem registra o 1DS com `app.component` liga a declaração com `"types": ["@1doc/1ds-vue/global"]`.
47
+
48
+ ## 2.14.0
49
+
50
+ ### Minor Changes
51
+
52
+ - aca81ec: Counter (novo): número que conta até o valor, para KPI de painel e total de páginas. Formato do `Intl.NumberFormat` (pt-BR por padrão), `prefix`/`suffix`/`decimals`, largura do valor final reservada, leitor de tela ouvindo só o valor final e respeito a `prefers-reduced-motion`.
53
+ - aca81ec: ListItem: slot `actions`, renderizado no `li` ao lado do elemento clicável (o ⋮ de menu deixa de ficar dentro do link). No Vue, o ListItem com `li` passa a ter raiz única, então funciona dentro de `TransitionGroup`.
54
+ - aca81ec: Tooltip: a cópia escondida do texto não escapa mais de área com rolagem (o wrapper ganhou `position: relative`), e a seta acompanha o gatilho quando o balão é empurrado para caber perto da borda.
55
+ - aca81ec: Dropdown: `href`, `target` e `rel` no `DropdownItem`. Com `href`, o item é um `<a role="menuitem">` (Ctrl+clique e nova aba funcionam), e o `onSelect` continua sendo chamado.
56
+ - aca81ec: Button: `href`, `target` e `rel`. Com `href`, o Button é um `<a>` com a mesma aparência; desabilitado, volta a ser `<button disabled>`. O hover do `variant="icon"` virou uma camada translúcida da cor do ícone: no fundo claro o cinza é o mesmo de antes, e sobre fundo colorido não vira mais um quadrado branco.
57
+ - aca81ec: StatCard: `secondaryTone` (cor da segunda medida), `loading` (os números viram Skeleton e o cartão ganha `aria-busy`) e `value` aceitando um nó, como um `Counter` (slot `value` no Vue).
58
+
59
+ ## 2.13.1
60
+
61
+ ### Patch Changes
62
+
63
+ - 1a927c5: StatCard: a segunda medida (`secondaryValue`) passa a ter o mesmo tamanho e peso do número principal, em todas as combinações (`md`, `sm` e `labelPosition="top"`). Com o rótulo no topo, o `secondaryLabel` fica na mesma linha da `description` ("Geral" ao lado de "Meu Setor"), em vez de colado embaixo do número.
64
+
3
65
  ## 2.13.0
4
66
 
5
67
  ### Minor Changes
@@ -50,7 +112,6 @@
50
112
 
51
113
  REMOÇÃO de token, não acréscimo. O DS não cria token novo: a família monoespaçada (introduzida no 0.6.0) volta a não
52
114
  existir. Como estamos em 0.x, a remoção sai como minor nos tokens.
53
-
54
115
  - `Kbd` e `CodeBlock` passam a usar `--umds-semantic-font-family-base`: o texto da tecla e do código sai na fonte do DS,
55
116
  não mais monoespaçada (muda a largura dos caracteres; o espaço e as quebras de linha do `CodeBlock` seguem mantidos).
56
117
  - `RichTextEditor`: a opção "Monoespaçada" da ferramenta `fontFamily` sai (o label `fontFamilyMono` também). Fica só a
@@ -79,7 +140,6 @@
79
140
  ```
80
141
 
81
142
  - 9c8baa3: feat(badge): `2xs` com 8px de padding lateral; `attached` com 22px e o tom escuro como opção (`attachedTone`)
82
-
83
143
  - `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.
84
144
  - `attached`: o rótulo colado tem altura mínima de 22px (24 - 2) de qualquer tamanho; o `md` (padrão) já media 22 e
85
145
  o `xs` e o `2xs` colados sobem a ele.
@@ -129,7 +189,6 @@
129
189
  continua valendo para os tours com mais passos. O botão do último passo segue sendo "Concluir" (`finishLabel`).
130
190
 
131
191
  - ad47648: feat(datatable): `density="compact"` com cabeçalho e linha de 44px, e tom por linha (`rowTone`)
132
-
133
192
  - `density="compact"`: `th` e `td` ganham `height` igual à altura de campo do DS (44px), no lugar dos 38 e 49 de
134
193
  antes. É mínimo: conteúdo mais alto (avatar, botão) estica a linha. A tabela de documento (`variant="document"`)
135
194
  continua justa.
@@ -200,7 +259,6 @@
200
259
  - bf81dfa: feat(select): a lista do filtro tem a largura do gatilho, com `listMinWidth` e sem passar da janela
201
260
 
202
261
  Regressão do 2.10 no `Select variant="filter"` (a lista do Marcadores da inbox media 556px e passava 17px da borda):
203
-
204
262
  - Causa: o wrapper do filtro tinha `width: auto` e é `display: flex` (bloco), então se esticava até a largura do pai;
205
263
  o `100%` da lista passava a ser a do pai e não a do gatilho. Agora é `fit-content`.
206
264
  - A lista tem a largura do gatilho (nunca menor), cresce até o conteúdo e fica dentro da janela: o campo de busca
@@ -223,7 +281,6 @@
223
281
  - cfe3687: feat(select): `item` com o escopo da opção, na lista e no gatilho
224
282
 
225
283
  O conteúdo de cada opção agora recebe a opção nos dois frameworks:
226
-
227
284
  - Vue: o slot `#item="{ optionData }"` (o Mitosis gerava `<slot name="item">` sem escopo e o `optionData` chegava `undefined`; o
228
285
  `postbuild.js` passa `optionData` e o apelido `option`).
229
286
  - React: `item` pode ser uma função `({ optionData }) => nó` (antes, a função virava filho inválido). O nó solto, sem escopo,
@@ -362,7 +419,6 @@
362
419
  - 82e85c5: feat(datatable): cabeçalho escuro, zebra, destaque de linha, vazio com ícone, `hideHeader` e linhas hierárquicas (`treeData`)
363
420
 
364
421
  Tudo opt-in; sem as props novas a tabela é a mesma.
365
-
366
422
  - `headerVariant="dark"`: cabeçalho navy com texto claro (`background-dark` e
367
423
  `neutral-light-pure`, então o tema acompanha). `headerUppercase`: caixa alta
368
424
  nos rótulos, vale para qualquer cabeçalho.
@@ -450,7 +506,6 @@
450
506
  ```
451
507
 
452
508
  - 76c0087: feat(listitem): `tooltip`, `standalone` e atributos HTML só no elemento interativo
453
-
454
509
  - `tooltip`: vira o atributo HTML `title` do `button`, `a` ou `div` (a dica nativa do
455
510
  navegador). `title` continua sendo o título da linha, não o atributo.
456
511
  - `standalone`: renderiza sem o `li`, só o elemento interativo, para usar fora de um
@@ -476,7 +531,6 @@
476
531
  - 3500910: feat(richtexteditor): alinhamento, imagem e tabela simples na `toolbar`
477
532
 
478
533
  Opt-in: a barra padrão não muda. Entram na `toolbar` por nome:
479
-
480
534
  - `alignLeft`, `alignCenter`, `alignRight`, `alignJustify`: botões de liga/desliga
481
535
  que seguem o cursor (`aria-pressed`). O valor guarda `text-align` nos blocos.
482
536
  - `image`: abre um painel (como o do link) com o endereço da imagem, o arquivo
@@ -522,7 +576,6 @@
522
576
 
523
577
  Opt-in na `toolbar`: `fontFamily`, `fontSize` e `textColor`. Cada um abre um painel abaixo da
524
578
  barra e aplica ao texto selecionado, embrulhando-o num `<span style="...">`:
525
-
526
579
  - `fontFamily`: padrão ou monoespaçada (`var(--umds-semantic-font-family-base|mono)`), num `Select`.
527
580
  - `fontSize`: 12, 14, 16, 20 e 24px, os degraus da escala do DS (`var(--umds-primitive-font-size-*)`).
528
581
  - `textColor`: a paleta do DS, num `ColorPicker` `xs`; o valor guarda o `var()` do token escolhido.
@@ -565,7 +618,6 @@
565
618
  - 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
566
619
 
567
620
  Tudo opt-in; o Select sem as props novas se comporta como antes, fora de diálogo.
568
-
569
621
  - `open` e `onOpenChange(open)`: a lista controlada de fora. O clique, o teclado,
570
622
  o clique fora, o Esc e a escolha de uma opção avisam o pai, que decide o novo
571
623
  `open`. Sem `open`, o Select abre e fecha sozinho e também avisa. É o que deixa o
@@ -605,7 +657,6 @@
605
657
  - f7fa5dd: feat(select): o filtro no tamanho do CrisDoc, com cor por opção (`option.color`)
606
658
 
607
659
  Para substituir o `FiltroSelect` do app:
608
-
609
660
  - As variantes de filtro (`filter`, `search`, `combo`) nascem no tamanho `sm` (32px, fonte de
610
661
  12px) quando `size` não é passado; `size="md"` continua valendo. O `Select` padrão não muda.
611
662
  - O gatilho do `filter` tem fundo branco com contorno azul. O azul-claro só vem depois de
@@ -635,7 +686,6 @@
635
686
  ```
636
687
 
637
688
  - b9f0813: feat(statcard): segunda medida (`secondaryValue`/`secondaryLabel`) e `valueTone`
638
-
639
689
  - `secondaryValue` e `secondaryLabel`: a segunda medida do cartão, menor (20px), à direita da
640
690
  principal, separada por um filete ("22,31% Meu Setor | 14,11% Geral"). No HTML vem depois do
641
691
  resto, então o leitor de tela lê a medida principal inteira antes. `0` aparece; vazio e
@@ -657,7 +707,6 @@
657
707
  ```
658
708
 
659
709
  - a4b6bb7: feat(toast): ação (`actionLabel`/`onAction`) e lista de detalhes (`details`)
660
-
661
710
  - `actionLabel` + `onAction`: um botão depois do texto ("Desfazer", "Ver processo").
662
711
  Acionar chama `onAction` e depois fecha o toast (`onClose`). O botão só aparece com os
663
712
  dois. O botão de fechar continua ao lado.
@@ -720,7 +769,6 @@
720
769
  No React o `content` do item já aceitava qualquer nó. No Vue ele era interpolado
721
770
  como texto, então o painel só aceitava string. Agora, no Vue, cada item pode ter
722
771
  um slot com o próprio conteúdo.
723
-
724
772
  - `#content-<id>`: slot com escopo por item (`<id>` é o `id` do item), que recebe
725
773
  `{ item }` e vale sobre o `content` de texto daquele item. Itens sem slot
726
774
  continuam mostrando o texto. O `postbuild` liga o slot ao `Accordion.vue`
@@ -741,7 +789,6 @@
741
789
  - 3d9472d: feat(attachmentcard): `status="ai"`, painel livre (`panel`), `panelWidth` e `closePanelOnAction`
742
790
 
743
791
  Opt-in; sem as props novas o cartão é o mesmo.
744
-
745
792
  - `status="ai"`: selo de recurso de IA, no roxo da IA (`ai-light` / `ai-dark`, os
746
793
  mesmos tokens do `AILabel`), com a varinha como ícone padrão (`statusIcon`
747
794
  continua mandando). O ícone do painel também é a varinha.
@@ -778,7 +825,6 @@
778
825
  - 2c0dafb: feat(avatargroup): `overlap`, `ring` e `overflowCount`
779
826
 
780
827
  Opt-in; sem as props novas o grupo é o mesmo.
781
-
782
828
  - `overflowCount`: quantas pessoas existem além das de `avatars`. O "+N" deixa de
783
829
  exigir N itens-fantasma: com 16 responsáveis, passe os 4 primeiros e
784
830
  `overflowCount={12}`. Soma com o que passar de `max` dentro de `avatars`, e os
@@ -808,7 +854,6 @@
808
854
  Tudo opt-in: sem as props novas, o HTML e o visual são os mesmos.
809
855
 
810
856
  **Badge**
811
-
812
857
  - `size="2xs"`: 16px de altura, fonte de 10px, raio 4. A fonte de 10px não está
813
858
  na escala do DS (o menor degrau é 12px), então é um literal comentado no CSS;
814
859
  se o mínimo de 12px for decisão de acessibilidade, o 2xs é o que sai.
@@ -822,7 +867,6 @@
822
867
  precisa de `position: relative`.
823
868
 
824
869
  **Tag**
825
-
826
870
  - `size="xs"`: 18px (`line-height: 1`, padding 2 e 8, fonte 12, ícone 12). Foi
827
871
  criado um tamanho novo em vez de mexer no `sm` (27px), para não encolher quem
828
872
  já usa `sm`. O × e o ícone clicável mantêm o alvo de 24px com margem negativa.
@@ -845,7 +889,6 @@
845
889
 
846
890
  O `Box` ganha as props de item flex do `Stack` e a troca de elemento, com os
847
891
  mesmos nomes e valores. Sem as props novas, o HTML e as classes são os mesmos.
848
-
849
892
  - `as`: `div` (padrão), `span`, `ul`, `ol`, `li`, `section`, `nav`, `header`,
850
893
  `footer`, `form`. `ul` e `ol` saem sem marcador, margem e recuo (o padding do
851
894
  Box continua valendo) e com `role="list"`. Com `as="form"`, `onSubmit` recebe
@@ -874,7 +917,6 @@
874
917
  sem `Stack` por dentro nem flex no CSS do produto. As cinco props têm os mesmos
875
918
  nomes e valores do `Stack`; qualquer uma delas liga o `display: flex`. Sem
876
919
  nenhuma, o `Box` segue sendo um bloco comum (API antiga intacta).
877
-
878
920
  - `direction`: `"vertical"` (padrão quando o flex está ligado) | `"horizontal"`.
879
921
  - `gap`: degraus da escala, mais `"none"`. Diferente do `Stack`, não tem valor
880
922
  padrão: sem `gap` os filhos ficam colados.
@@ -908,7 +950,6 @@
908
950
 
909
951
  Para barra de ações (editor, filtros, linha de card), onde nenhum botão é a
910
952
  ação principal e o azul atrapalha. Sem as props novas, nada muda.
911
-
912
953
  - `variant="neutral-text"`: texto cinza (`neutral-dark-down`), sem borda e sem
913
954
  fundo; hover em `neutral-light-medium`. O `neutral` continua sendo o
914
955
  contornado cinza, então "neutro" cobre os dois: contornado (`neutral`) e
@@ -932,7 +973,6 @@
932
973
 
933
974
  Peça nova: visão de mês e de semana, com eventos por dia, sem biblioteca de
934
975
  datas (o `Intl` escreve os nomes de mês e de dia).
935
-
936
976
  - `events`: lista plana `{ date, title, color?, time?, id? }`. `date` é
937
977
  `YYYY-MM-DD`, data-hora ISO ou `Date`. A grade agrupa por dia e ordena por
938
978
  `time`.
@@ -987,7 +1027,6 @@ escondidos)`). O corte é por QUANTIDADE, não por altura. Semana: sete colunas
987
1027
  - 33719b6: feat(chips): `size="xs"` e × com moldura circular (`circularRemove`)
988
1028
 
989
1029
  Opt-in; sem as props novas o `Chips` é o mesmo.
990
-
991
1030
  - `size="xs"`: 20px de altura, padding lateral 8, fonte de 12px e × de 8px. A
992
1031
  altura é `calc(spacing-xxxs + spacing-quarck)` (16 + 4), sem token novo. O
993
1032
  CrisDoc usa fonte de 11px, que não está na escala do DS; fica o degrau de 12px.
@@ -1014,7 +1053,6 @@ escondidos)`). O corte é por QUANTIDADE, não por altura. Semana: sete colunas
1014
1053
  um cartão, enquanto o resto da página escurece e o alvo fica destacado num
1015
1054
  recorte (uma caixa transparente cuja sombra escurece o resto, sem máscara nem
1016
1055
  SVG).
1017
-
1018
1056
  - `steps`: `{ target?, title, content?, placement? }`. `target` é um seletor CSS
1019
1057
  (`"#aba-fluxos"`), um elemento, uma ref do React (`{ current }`), uma ref do Vue
1020
1058
  (`{ value }`) ou uma função que devolve um deles. Sem alvo (ou alvo que não
@@ -1060,7 +1098,6 @@ escondidos)`). O corte é por QUANTIDADE, não por altura. Semana: sete colunas
1060
1098
  (`--umds-primitive-blue-pure`): guarde o nome e pinte com `var(${valor})`. Como
1061
1099
  primitivo não muda com o tema, a cor escolhida é a mesma no claro e no escuro, o
1062
1100
  que é o certo para cor de dado (marcador, tipo de documento, setor).
1063
-
1064
1101
  - `radiogroup`: Tab entra na amostra escolhida (ou na primeira), setas movem a
1065
1102
  escolha, Home e End vão às pontas, amostra desabilitada é pulada. Cada amostra
1066
1103
  tem nome acessível ("Azul escuro") e a escolhida ganha ícone de marcação e anel
@@ -1091,7 +1128,6 @@ escondidos)`). O corte é por QUANTIDADE, não por altura. Semana: sete colunas
1091
1128
 
1092
1129
  A `DataTable` passa a aceitar markup na célula nos dois frameworks. API antiga
1093
1130
  intacta: sem as props e slots novos, o HTML e as classes são os mesmos.
1094
-
1095
1131
  - Célula livre. No React, `column.render(row, rowIndex)` já devolvia nó e
1096
1132
  continua assim (o docblock agora diz). No Vue, o retorno do `render` continua
1097
1133
  sendo tratado como texto, e a célula com markup vem do slot `#cell-<key>`,
@@ -1137,7 +1173,6 @@ row, rowIndex)` no React, ou o slot `#row-group` (`{ label, row, rowIndex }`)
1137
1173
 
1138
1174
  **`DescriptionList`**, para os pares rótulo/valor (o `DocPares` do CrisDoc não
1139
1175
  cabia na tabela: não tem cabeçalho de coluna). `<dl>` com `<dt>` e `<dd>`:
1140
-
1141
1176
  - `items`: `{ label, value, id? }`. Valor vazio mostra "—" (`emptyValue`).
1142
1177
  - `layout="inline"` (padrão): grade de bordas finas, rótulo pintado e sem quebra
1143
1178
  à esquerda, valor à direita; `fit` encolhe até o conteúdo.
@@ -1162,7 +1197,6 @@ row, rowIndex)` no React, ou o slot `#row-group` (`{ label, row, rowIndex }`)
1162
1197
 
1163
1198
  Para o "Anexar arquivo" de um botão ou o "Alterar foto" de um link, sem a caixa
1164
1199
  de arrastar. Opt-in; `base` e `card` não mudam.
1165
-
1166
1200
  - `variant="trigger"`: o conteúdo que você passa (React: `children`; Vue: slot
1167
1201
  padrão) é o gatilho. O clique nele abre o seletor (o clique sobe até o
1168
1202
  envoltório, então o Enter num `Button` também funciona), e `accept`,
@@ -1188,7 +1222,6 @@ row, rowIndex)` no React, ou o slot `#row-group` (`{ label, row, rowIndex }`)
1188
1222
  - 0e89b88: feat(iconpicker): novo `IconPicker`, a grade de ícones com busca
1189
1223
 
1190
1224
  Peça nova, sem dependência: os ícones vêm por prop.
1191
-
1192
1225
  - `icons`: objetos do Font Awesome importados (`faUser`, `faFolder`...), ou
1193
1226
  `{ icon, label?, keywords? }` quando o nome ou a busca precisam de ajuda. O nome
1194
1227
  de um ícone sem `label` é o `iconName` sem hífen ("file lines"); `iconLabel`
@@ -1222,7 +1255,6 @@ row, rowIndex)` no React, ou o slot `#row-group` (`{ label, row, rowIndex }`)
1222
1255
  ```
1223
1256
 
1224
1257
  - 4d0cb08: feat(input): `onChange` a cada tecla no Vue, `mask`, `iconRight` e `borderless`
1225
-
1226
1258
  - **`onChange` a cada tecla no Vue (paridade com o React).** O campo passa a
1227
1259
  escutar `input` além de `change`. Antes, no Vue, `onChange` só disparava quando
1228
1260
  o campo perdia o foco (o evento `change` nativo). Os dois eventos entram no
@@ -1264,7 +1296,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1264
1296
  semântico; os dois componentes abaixo já o usam.
1265
1297
 
1266
1298
  **`Kbd`**: uma tecla ou uma combinação, em `<kbd>`.
1267
-
1268
1299
  - Uma tecla vai como conteúdo (`<Kbd>Esc</Kbd>`); uma combinação em `keys`
1269
1300
  (`["Ctrl", "Shift", "P"]`), com `separator` entre as teclas (padrão `+`). Cada
1270
1301
  tecla é um `<kbd>` dentro do `<kbd>` do conjunto, que é como o HTML diz
@@ -1273,7 +1304,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1273
1304
  `md`. Raiz única: `title`, `data-*`, `aria-*` e ouvintes chegam ao elemento.
1274
1305
 
1275
1306
  **`CodeBlock`**: trecho de código, JSON ou log, com borda, rolagem e cópia.
1276
-
1277
1307
  - O texto vem por `code` ou como conteúdo, com espaços e quebras mantidos. Linha
1278
1308
  longa rola na horizontal, ou quebra com `wrap`; `maxHeight` (px) limita a
1279
1309
  altura e rola na vertical.
@@ -1298,7 +1328,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1298
1328
  paginação ao redor continuam montados (e o foco no campo de busca não se perde),
1299
1329
  porque só o miolo troca. A lista não conta filhos: `isEmpty` é a decisão de
1300
1330
  quem a usa (`:is-empty="!itens.length"`).
1301
-
1302
1331
  - Texto: `emptyTitle` (padrão "Nenhum item encontrado"), `emptyDescription`,
1303
1332
  `emptyIcon` (objeto do Font Awesome), `emptySize` (`sm` padrão, `md`, `lg`).
1304
1333
  - Ação: `emptyActionLabel` com `onEmptyAction`. Sem o callback o botão não
@@ -1327,7 +1356,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1327
1356
  Peça nova. O `ListItem` é a linha cujo alvo de clique e de foco é a linha
1328
1357
  toda, com conteúdo livre. Renderiza um `<li>` com UM `button`, `a` ou `div`
1329
1358
  dentro, por isso vive num `List` (ou num `ul`/`ol`, como `Stack as="ul"`).
1330
-
1331
1359
  - `as`: `button` | `a` | `div`. Sem `as`, vira `a` quando há `href` e `button`
1332
1360
  nos outros casos. `div` é a linha que só mostra; com `onClick` ganha
1333
1361
  role="button", tabindex 0, Enter e Espaço. `target="_blank"` põe
@@ -1362,7 +1390,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1362
1390
  - eeb6a16: feat(modal): `variant="primary"`, `width`/`maxWidth`, `windowControls` em lista e `responsive`; o Esc respeita quem já o usou
1363
1391
 
1364
1392
  Tudo opt-in; sem as props novas o modal é o mesmo.
1365
-
1366
1393
  - `variant="primary"`: cabeçalho cheio na cor primária (título, subtítulo e
1367
1394
  controles em `neutral-light-pure`, hover em `primary-dark`). É o modal base com
1368
1395
  as três faixas, não o diálogo de feedback.
@@ -1405,7 +1432,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1405
1432
 
1406
1433
  Peça nova: uma árvore desenhada de cima para baixo, com linhas ligando cada pai
1407
1434
  aos filhos, em que os nós com filhos expandem e recolhem. Sem dependência.
1408
-
1409
1435
  - `nodes`: lista de nós raiz `{ id, title, subtitle?, children? }`. Mais de uma
1410
1436
  raiz funciona (floresta).
1411
1437
  - O desenho é calculado, não aninhado (o Mitosis não gera componente recursivo de
@@ -1443,7 +1469,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1443
1469
 
1444
1470
  Peça nova para códigos curtos recebidos por outro canal (autenticação em duas
1445
1471
  etapas, confirmação de e-mail ou telefone).
1446
-
1447
1472
  - `length` caixas (6 por padrão). Digitar avança o foco; Backspace apaga e, em
1448
1473
  caixa vazia, volta e apaga a anterior; setas, Home e End movem.
1449
1474
  - Colar o código inteiro em qualquer caixa distribui os caracteres (um pedaço
@@ -1470,7 +1495,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1470
1495
  ```
1471
1496
 
1472
1497
  - d89ebe3: feat(popover): `maxHeight` para o corpo do painel
1473
-
1474
1498
  - `maxHeight`: altura máxima do corpo, que rola além dela. Número vira px; texto
1475
1499
  vai como CSS (`"60vh"`). `"none"` deixa o corpo crescer com o conteúdo, como
1476
1500
  no painel "Colunas do card" do CrisDoc.
@@ -1490,7 +1514,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1490
1514
  Peça nova, sobre `contenteditable` e `document.execCommand`. Sem dependência
1491
1515
  nova: o primeiro corte é o que as telas de despacho, resposta e descrição de
1492
1516
  serviço pedem.
1493
-
1494
1517
  - Ferramentas: negrito, itálico, sublinhado, tachado, lista com marcadores, lista
1495
1518
  numerada, link, desfazer, refazer e limpar formatação. A barra se escolhe por
1496
1519
  `toolbar` (a ordem do array é a da tela, `"|"` é um separador): a padrão traz
@@ -1537,7 +1560,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1537
1560
  - b02f4ff: feat(select): `placement` (a lista abre para cima) e variante `filter` com opção "sem filtro" e rodapé
1538
1561
 
1539
1562
  Tudo opt-in; sem as props novas o `Select` é o mesmo.
1540
-
1541
1563
  - `placement`: `bottom` (padrão), `top` ou `auto`. O `auto` mede o espaço na hora
1542
1564
  de abrir e abre para cima só se a lista (altura estimada, no máximo os 300px
1543
1565
  do CSS) não cabe embaixo e há mais espaço em cima, como o campo no rodapé de
@@ -1573,7 +1595,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1573
1595
 
1574
1596
  O `Stack` passa a cobrir o que o produto ainda escrevia em CSS próprio. API
1575
1597
  antiga intacta: sem as props novas, o HTML e as classes são os mesmos.
1576
-
1577
1598
  - `gap="none"` zera o espaço (antes só havia os degraus da escala).
1578
1599
  - `as`: `div` (padrão), `span`, `ul`, `ol`, `li`, `section`, `nav`, `header`,
1579
1600
  `footer`, `form`. `ul` e `ol` saem sem marcador, margem e recuo, com
@@ -1607,7 +1628,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1607
1628
  - 1d59843: feat(statcard): `labelPosition="top"` e `infoTooltip`
1608
1629
 
1609
1630
  Opt-in; sem as props novas o `StatCard` é o mesmo.
1610
-
1611
1631
  - `labelPosition="top"`: o rótulo vai para o topo do cartão, acima do ícone e do
1612
1632
  número, e o número passa a 32/800 (o degrau `font-size-lg` do DS), como no
1613
1633
  painel da 1Doc. Só a posição visual muda: no HTML o número continua antes do
@@ -1636,7 +1656,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1636
1656
  muda o layout, e o `Tabs` ganha uma `div` de barra com o mesmo comportamento).
1637
1657
 
1638
1658
  **Tab**
1639
-
1640
1659
  - `count` (número ou texto): pílula de 18px ao lado do texto, azul na aba ativa
1641
1660
  (`primary-pure`) e cinza nas outras (`neutral-light-medium`). O `0` aparece. O
1642
1661
  número entra no nome acessível da aba ("Todas 31").
@@ -1647,7 +1666,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1647
1666
  - `closeLabel`: prefixo do nome acessível do ×, para traduzir ("Close Doc 1").
1648
1667
 
1649
1668
  **Tabs**
1650
-
1651
1669
  - `onAdd(event)`: mostra o "+" logo depois da última aba, **fora** do
1652
1670
  `role="tablist"` (o tablist só pode ter abas). `addLabel` traduz o nome
1653
1671
  ("Adicionar aba" por padrão).
@@ -1671,7 +1689,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1671
1689
  - 96e752b: feat(tooltip): `variant="dark"` compacto e `maxWidth`
1672
1690
 
1673
1691
  Opt-in; sem as props novas o `Tooltip` é o mesmo.
1674
-
1675
1692
  - `variant="dark"`: balão escuro e compacto (padding 4/8, raio 4, teto de 220px)
1676
1693
  para ícone, sigla e botão de barra de ferramentas. Fundo `background-dark` e
1677
1694
  texto `neutral-light-pure`: o par invertido do tema, então o contraste vale nos
@@ -1762,7 +1779,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1762
1779
  regressão silenciosa das props novas (`as`, `gap="none"`...).
1763
1780
 
1764
1781
  Descartados em silêncio, antes desta correção:
1765
-
1766
1782
  - ouvintes: `@click`, `@keydown`, `@dragstart`, `@drop`, `@paste`, `@mousedown`...
1767
1783
  - atributos fora da lista: `tabindex` (minúsculo), `draggable`...
1768
1784
  - `v-show` e o `$el` do `ref` do componente (apontavam para o nó de âncora do
@@ -1797,7 +1813,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1797
1813
  - 0fc7a82: fix(vue): `Text`, `Grid` e `Logo` repassam `title`, `style` e `aria-*`; `Button` e `DataTable` param de sujar o DOM
1798
1814
 
1799
1815
  Quatro defeitos que só existiam no Vue gerado (o React estava certo):
1800
-
1801
1816
  - `Text`, `Grid` e `Logo` descartavam `title`, `style`, `aria-*` e `data-*`. O
1802
1817
  laço `for (k in props)` do `htmlAttrs` compilava para `props.props`, que não
1803
1818
  existe. O passo `postbuild` do core passa a ler `props` e `useAttrs()` (o que
@@ -1827,7 +1842,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
1827
1842
  leitor de tela — ganhou prop. Sem a prop, nada muda: o padrão é o português de
1828
1843
  antes, byte a byte. Com ela, um produto em outro idioma deixa de mostrar ou ler
1829
1844
  português.
1830
-
1831
1845
  - `AILabel`: `sourcesLabel`, `notIncludedLabel`.
1832
1846
  - `AIContent`: `label`, `ariaLabel`, `explanationTitle`, `sourcesLabel`,
1833
1847
  `notIncludedLabel` (repassados ao selo interno, que antes não recebia nenhum).
@@ -2052,7 +2066,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
2052
2066
 
2053
2067
  Família nova de gráficos, sem biblioteca externa: o Mitosis desenha o SVG e o
2054
2068
  resultado é o mesmo no React e no Vue.
2055
-
2056
2069
  - `BarChart` — barras verticais, com séries agrupadas lado a lado e suporte a
2057
2070
  valores negativos (a barra arredonda na ponta do dado, nunca na base).
2058
2071
  - `LineChart` — uma ou mais séries; `null` interrompe a linha em vez de cair a
@@ -2171,7 +2184,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
2171
2184
 
2172
2185
  E no `Dropdown`, dois defeitos de gatilho achados ao escrever o teste — mesma
2173
2186
  raiz, o `<span>` wrapper não é o gatilho real:
2174
-
2175
2187
  - o **Escape fechava o menu e largava o foco no `<body>`**: quem recebia o
2176
2188
  `focus()` era o wrapper, que fica sem `tabindex` quando o slot já traz um
2177
2189
  `Button`, e `focus()` num span sem tabindex é no-op;
@@ -2189,7 +2201,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
2189
2201
  ### Minor Changes
2190
2202
 
2191
2203
  - 3d2977e: fix(app-header): menu do usuário fora do botão, ícones sem registro e barra que não estoura
2192
-
2193
2204
  - O bloco do usuário vira um `<button>` de verdade (Enter/Espaço nativos) e o
2194
2205
  `userMenu` é renderizado ao lado dele, não dentro — clicar no menu não
2195
2206
  dispara mais `onUserClick`. Prop nova `userMenuOpen` liga `aria-haspopup` e
@@ -2288,14 +2299,12 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
2288
2299
 
2289
2300
  Agora, sem `variant`, o `Modal` é o modal base da 1Doc — o "Criar Novo
2290
2301
  Documento", medido em `NovoDocumentoModal.css`:
2291
-
2292
2302
  - **cabeçalho fixo** com título (16/700), subtítulo (12px) e divisor;
2293
2303
  - **corpo**, o único que rola;
2294
2304
  - **rodapé fixo** com divisor, sombra que o levanta, região de apoio à esquerda
2295
2305
  e ações à direita.
2296
2306
 
2297
2307
  Props novas:
2298
-
2299
2308
  - `windowControls` — restaurar · expandir · tela cheia · minimizar, antes do ×.
2300
2309
  É tudo ou nada: ou o modal tem só o ×, ou o conjunto inteiro. Ligado, o modal
2301
2310
  muda de tamanho sozinho (780px · 1120px · tela cheia).
@@ -2447,7 +2456,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
2447
2456
  - fa15735: **App shell: `AppShell`, `AppHeader` e `AppSidebar`.**
2448
2457
 
2449
2458
  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.
2450
-
2451
2459
  - **`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).
2452
2460
  - **`AppHeader`** — barra de 56px com marca, navegação e ações. O que vai dentro é do produto.
2453
2461
  - **`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.
@@ -2457,7 +2465,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
2457
2465
  **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`.
2458
2466
 
2459
2467
  - 2a86d8c: Três componentes novos na trilha **Preview**, para telas onde parte do conteúdo ou parte da decisão vem de um modelo:
2460
-
2461
2468
  - **`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.
2462
2469
  - **`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.
2463
2470
  - **`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.
@@ -2469,7 +2476,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
2469
2476
  - 7c44c6d: **As peças que faltavam para reproduzir a tela da 1Doc:** `AppSubheader`, `SidePanel`, `AppNavItem` e `StatCard`, somadas ao `AppShell`, `AppHeader` e `AppSidebar`.
2470
2477
 
2471
2478
  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-*`.
2472
-
2473
2479
  - **`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.
2474
2480
  - **`AppSubheader`** — a barra de contexto: trilha à esquerda, setor e ações à direita.
2475
2481
  - **`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.
@@ -2487,7 +2493,6 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
2487
2493
  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.
2488
2494
 
2489
2495
  - 2bc13c1: Três falhas de comportamento apontadas pela auditoria interna, todas verificadas na tela:
2490
-
2491
2496
  - **`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.
2492
2497
  - **`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.
2493
2498
  - **`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.
@@ -2634,13 +2639,11 @@ Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema
2634
2639
  - 445de52: feat(icon): nova API dinâmica, remoção do Font Awesome Pro e tipagem extensível
2635
2640
 
2636
2641
  **Breaking change** — a prop `name` foi removida do `<Icon>`. Use `icon` no lugar, que aceita três formatos:
2637
-
2638
2642
  - string: `<Icon icon="home" />`
2639
2643
  - tupla `[prefix, iconName]`: `<Icon icon={["fas", "home"]} />`
2640
2644
  - objeto `IconLookup` (ex.: `<Icon icon={faHome} />`)
2641
2645
 
2642
2646
  **Novas props:**
2643
-
2644
2647
  - `transform`: aceita string (parseada via `faParse.transform`) ou objeto `Transform` do FA core.
2645
2648
  - `mask` / `maskId`: ícone de máscara (suporta os mesmos formatos de `icon`).
2646
2649
  - `symbol`: cria `<symbol>` reutilizável (`FaSymbol` do FA core).
@@ -105,7 +105,7 @@
105
105
  border: 1px solid var(--umds-semantic-color-ai-light);
106
106
  border-radius: var(--umds-primitive-border-radius-sm);
107
107
  background-color: var(--umds-semantic-color-neutral-light-pure);
108
- box-shadow: var(--umds-semantic-shadow-sm);
108
+ box-shadow: var(--umds-semantic-shadow-bottom-sm);
109
109
  color: var(--umds-semantic-color-neutral-dark-pure);
110
110
  font-size: var(--umds-primitive-font-size-xxs);
111
111
  line-height: 1.5;
@@ -38,7 +38,7 @@
38
38
  z-index: var(--umds-semantic-layer-toast); /* 1500 - camada de notificação */
39
39
  width: 420px;
40
40
  max-width: calc(100vw - 32px);
41
- box-shadow: var(--umds-semantic-shadow-md); /* protótipo --shadow-md */
41
+ box-shadow: var(--umds-semantic-shadow-bottom-md); /* protótipo --shadow-md */
42
42
  }
43
43
 
44
44
  .umds-alert--top-right {
@@ -31,6 +31,10 @@
31
31
  display: flex;
32
32
  flex-direction: column;
33
33
  background-color: var(--umds-semantic-color-background-light);
34
+ /* Cor de texto do tema para tudo o que herda (um Text sem `color`, um título
35
+ solto num Stack). Sem ela o conteúdo herdava o preto padrão do navegador,
36
+ e no tema escuro o texto sumia no fundo escuro. */
37
+ color: var(--umds-semantic-color-neutral-dark-pure);
34
38
  font-family: var(--umds-semantic-font-family-base);
35
39
  }
36
40
 
@@ -36,7 +36,7 @@
36
36
  /* Mesmo hover do `Card hoverable`: realce de borda + sombra. */
37
37
  .umds-attachment-card--interativo:hover {
38
38
  border-color: var(--umds-semantic-color-primary-medium);
39
- box-shadow: var(--umds-semantic-shadow-md);
39
+ box-shadow: var(--umds-semantic-shadow-bottom-md);
40
40
  }
41
41
 
42
42
  /* ── selo de situação ──────────────────────────────────────────────────── */
@@ -129,7 +129,7 @@
129
129
  border: 1px solid var(--umds-semantic-color-neutral-light-medium);
130
130
  border-radius: var(--umds-primitive-border-radius-sm);
131
131
  background-color: var(--umds-semantic-color-background-elevated);
132
- box-shadow: var(--umds-semantic-shadow-md);
132
+ box-shadow: var(--umds-semantic-shadow-bottom-md);
133
133
  font-family: var(--umds-semantic-font-family-base);
134
134
  color: var(--umds-semantic-color-neutral-dark-pure);
135
135
  }
@@ -7,11 +7,16 @@ import './Avatar.css';
7
7
  export interface AvatarProps {
8
8
  /**
9
9
  * URL da imagem. Se fornecida, o tipo será automaticamente 'Photo' visualmente.
10
- * O componente NÃO faz fallback automático quando a imagem falha ao
11
- * carregar: ele emite `onError` e o consumidor decide (ex.: limpar o
12
- * `src` para exibir as iniciais via `children`).
10
+ * Se a imagem falhar ao carregar, o avatar volta sozinho para as iniciais
11
+ * (`name` ou `children`) e emite `onError`. Um `src` novo tenta de novo.
13
12
  */
14
13
  src?: string;
14
+ /**
15
+ * Nome da pessoa: gera as iniciais (primeira letra do primeiro e do último
16
+ * nome, "Cris Lima" → "CL") e vira o nome acessível quando não há
17
+ * `ariaLabel`. Com `name`, as iniciais vêm dele, no lugar de `children`.
18
+ */
19
+ name?: string;
15
20
  /**
16
21
  * Texto alternativo para a imagem (acessibilidade).
17
22
  */
@@ -1,23 +1,47 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import './Avatar.css';
4
+ import { useState, useEffect } from "react";
4
5
  function Avatar(props) {
6
+ const [imagemFalhou, setImagemFalhou] = useState(() => false);
7
+ function mostraFoto() {
8
+ return !!props.src && !imagemFalhou;
9
+ }
10
+ function iniciais() {
11
+ const partes = (props.name || "").trim().split(/\s+/).filter(Boolean);
12
+ if (partes.length === 0)
13
+ return "";
14
+ const primeira = partes[0].charAt(0);
15
+ const ultima = partes.length > 1 ? partes[partes.length - 1].charAt(0) : "";
16
+ return (primeira + ultima).toUpperCase();
17
+ }
18
+ function aoFalhar(event) {
19
+ setImagemFalhou(true);
20
+ if (props.onError)
21
+ props.onError(event);
22
+ }
5
23
  function classes() {
6
24
  return [
7
25
  "umds-avatar",
8
26
  `umds-avatar--${props.size || "md"}`,
9
- `umds-avatar--${props.type || (props.src ? "photo" : "letter")}`,
27
+ `umds-avatar--${props.type || (props.src && !imagemFalhou ? "photo" : "letter")}`,
10
28
  props.className,
11
29
  ]
12
30
  .filter(Boolean)
13
31
  .join(" ");
14
32
  }
15
33
  function computedRole() {
16
- return props.ariaLabel || props.src ? "img" : undefined;
34
+ return props.ariaLabel || props.src || props.name ? "img" : undefined;
17
35
  }
18
36
  function computedAriaLabel() {
19
- return props.ariaLabel || (props.src && props.alt ? props.alt : undefined);
37
+ return (props.ariaLabel ||
38
+ (props.src && props.alt ? props.alt : undefined) ||
39
+ props.name ||
40
+ undefined);
20
41
  }
21
- return (_jsxs("div", { title: props.title, role: computedRole(), "aria-label": computedAriaLabel(), className: classes(), children: [props.src ? (_jsx("img", { className: "umds-avatar__image", src: props.src, alt: props.alt || "", onError: (event) => props.onError && props.onError() })) : null, !props.src ? _jsx(_Fragment, { children: props.children }) : null] }));
42
+ useEffect(() => {
43
+ setImagemFalhou(false);
44
+ }, [props.src]);
45
+ return (_jsxs("div", { title: props.title, role: computedRole(), "aria-label": computedAriaLabel(), className: classes(), children: [mostraFoto() ? (_jsx("img", { className: "umds-avatar__image", src: props.src, alt: props.alt || "", onError: (event) => aoFalhar(event) })) : null, !mostraFoto() ? (_jsx(_Fragment, { children: props.name ? _jsx(_Fragment, { children: iniciais() }) : _jsx(_Fragment, { children: props.children }) })) : null] }));
22
46
  }
23
47
  export default Avatar;