@1doc/1ds-react 2.8.0 → 2.10.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.
- package/CHANGELOG.md +1540 -0
- package/dist/components/AILabel/AILabel.js +1 -1
- package/dist/components/Accordion/Accordion.css +13 -0
- package/dist/components/Accordion/Accordion.d.ts +9 -2
- package/dist/components/Accordion/Accordion.js +1 -0
- package/dist/components/AppSubheader/AppSubheader.css +10 -1
- package/dist/components/AttachmentCard/AttachmentCard.css +26 -8
- package/dist/components/AttachmentCard/AttachmentCard.d.ts +22 -2
- package/dist/components/AttachmentCard/AttachmentCard.js +47 -3
- package/dist/components/Avatar/Avatar.css +7 -2
- package/dist/components/Avatar/AvatarGroup.d.ts +17 -0
- package/dist/components/Avatar/AvatarGroup.js +22 -8
- package/dist/components/Badge/Badge.css +67 -2
- package/dist/components/Badge/Badge.d.ts +23 -4
- package/dist/components/Badge/Badge.js +4 -0
- package/dist/components/Box/Box.css +83 -0
- package/dist/components/Box/Box.d.ts +82 -2
- package/dist/components/Box/Box.js +42 -2
- package/dist/components/Button/Button.css +29 -0
- package/dist/components/Button/Button.d.ts +4 -4
- package/dist/components/Button/Button.js +4 -1
- package/dist/components/Calendar/Calendar.css +245 -0
- package/dist/components/Calendar/Calendar.d.ts +126 -0
- package/dist/components/Calendar/Calendar.js +320 -0
- package/dist/components/Chips/Chips.css +38 -0
- package/dist/components/Chips/Chips.d.ts +5 -2
- package/dist/components/Chips/Chips.js +2 -1
- package/dist/components/Coachmark/Coachmark.css +128 -0
- package/dist/components/Coachmark/Coachmark.d.ts +87 -0
- package/dist/components/Coachmark/Coachmark.js +362 -0
- package/dist/components/CodeBlock/CodeBlock.css +96 -0
- package/dist/components/CodeBlock/CodeBlock.d.ts +47 -0
- package/dist/components/CodeBlock/CodeBlock.js +103 -0
- package/dist/components/ColorPicker/ColorPicker.css +140 -0
- package/dist/components/ColorPicker/ColorPicker.d.ts +73 -0
- package/dist/components/ColorPicker/ColorPicker.js +219 -0
- package/dist/components/Combobox/Combobox.css +8 -0
- package/dist/components/DataTable/DataTable.css +254 -0
- package/dist/components/DataTable/DataTable.d.ts +81 -5
- package/dist/components/DataTable/DataTable.js +335 -19
- package/dist/components/DatePicker/DatePicker.css +8 -0
- package/dist/components/DatePicker/DatePicker.js +10 -1
- package/dist/components/DescriptionList/DescriptionList.css +127 -0
- package/dist/components/DescriptionList/DescriptionList.d.ts +62 -0
- package/dist/components/DescriptionList/DescriptionList.js +52 -0
- package/dist/components/EmptyState/EmptyState.d.ts +4 -2
- package/dist/components/EmptyState/EmptyState.js +2 -2
- package/dist/components/FileInput/FileInput.css +16 -0
- package/dist/components/FileInput/FileInput.d.ts +4 -2
- package/dist/components/FileInput/FileInput.js +8 -2
- package/dist/components/Grid/Grid.js +5 -5
- package/dist/components/IconPicker/IconPicker.css +107 -0
- package/dist/components/IconPicker/IconPicker.d.ts +74 -0
- package/dist/components/IconPicker/IconPicker.js +194 -0
- package/dist/components/Input/Input.css +59 -0
- package/dist/components/Input/Input.d.ts +17 -1
- package/dist/components/Input/Input.js +67 -5
- package/dist/components/Kanban/Kanban.css +4 -0
- package/dist/components/Kbd/Kbd.css +66 -0
- package/dist/components/Kbd/Kbd.d.ts +32 -0
- package/dist/components/Kbd/Kbd.js +40 -0
- package/dist/components/List/List.css +136 -0
- package/dist/components/List/List.d.ts +82 -0
- package/dist/components/List/List.js +53 -0
- package/dist/components/List/ListItem.d.ts +97 -0
- package/dist/components/List/ListItem.js +82 -0
- package/dist/components/Modal/Modal.css +80 -0
- package/dist/components/Modal/Modal.d.ts +33 -6
- package/dist/components/Modal/Modal.js +101 -6
- package/dist/components/MultiSelect/MultiSelect.css +8 -0
- package/dist/components/MultiSelect/MultiSelect.js +10 -1
- package/dist/components/OrgChart/OrgChart.css +149 -0
- package/dist/components/OrgChart/OrgChart.d.ts +83 -0
- package/dist/components/OrgChart/OrgChart.js +297 -0
- package/dist/components/OtpInput/OtpInput.css +93 -0
- package/dist/components/OtpInput/OtpInput.d.ts +60 -0
- package/dist/components/OtpInput/OtpInput.js +215 -0
- package/dist/components/PhoneInput/PhoneInput.css +8 -0
- package/dist/components/Popover/Popover.d.ts +7 -0
- package/dist/components/Popover/Popover.js +11 -1
- package/dist/components/RichTextEditor/RichTextEditor.css +250 -0
- package/dist/components/RichTextEditor/RichTextEditor.d.ts +97 -0
- package/dist/components/RichTextEditor/RichTextEditor.js +951 -0
- package/dist/components/SegmentedControl/SegmentedControl.css +24 -0
- package/dist/components/SegmentedControl/SegmentedControl.d.ts +2 -0
- package/dist/components/SegmentedControl/SegmentedControl.js +10 -2
- package/dist/components/Select/Select.css +164 -0
- package/dist/components/Select/Select.d.ts +34 -0
- package/dist/components/Select/Select.js +258 -28
- package/dist/components/Stack/Stack.css +49 -0
- package/dist/components/Stack/Stack.d.ts +65 -7
- package/dist/components/Stack/Stack.js +30 -2
- package/dist/components/StatCard/StatCard.css +138 -0
- package/dist/components/StatCard/StatCard.d.ts +26 -0
- package/dist/components/StatCard/StatCard.js +13 -1
- package/dist/components/Tabs/Tab.d.ts +15 -0
- package/dist/components/Tabs/Tab.js +30 -1
- package/dist/components/Tabs/Tabs.css +132 -0
- package/dist/components/Tabs/Tabs.d.ts +7 -0
- package/dist/components/Tabs/Tabs.js +13 -2
- package/dist/components/Tag/Tag.css +85 -2
- package/dist/components/Tag/Tag.d.ts +13 -6
- package/dist/components/Tag/Tag.js +1 -0
- package/dist/components/Text/Text.js +2 -2
- package/dist/components/Textarea/Textarea.css +8 -0
- package/dist/components/TimePicker/TimePicker.css +8 -0
- package/dist/components/Toast/Toast.css +32 -0
- package/dist/components/Toast/Toast.d.ts +18 -0
- package/dist/components/Toast/Toast.js +14 -1
- package/dist/components/Toast/ToastStack.js +8 -1
- package/dist/components/Tooltip/Tooltip.css +25 -0
- package/dist/components/Tooltip/Tooltip.d.ts +11 -0
- package/dist/components/Tooltip/Tooltip.js +18 -3
- package/dist/index.d.ts +25 -0
- package/dist/index.js +14 -0
- package/dist/teste/AILabel.test.d.ts +1 -0
- package/dist/teste/AILabel.test.js +33 -0
- package/dist/teste/AccordionConteudoLivre.test.d.ts +1 -0
- package/dist/teste/AccordionConteudoLivre.test.js +29 -0
- package/dist/teste/AccordionTituloNeutro.test.d.ts +1 -0
- package/dist/teste/AccordionTituloNeutro.test.js +23 -0
- package/dist/teste/AppSubheaderRegiao.test.d.ts +1 -0
- package/dist/teste/AppSubheaderRegiao.test.js +13 -0
- package/dist/teste/AtributosRepassados.test.d.ts +1 -0
- package/dist/teste/AtributosRepassados.test.js +52 -0
- package/dist/teste/AttachmentCardIA.test.d.ts +1 -0
- package/dist/teste/AttachmentCardIA.test.js +89 -0
- package/dist/teste/AttachmentCardLista.test.d.ts +1 -0
- package/dist/teste/AttachmentCardLista.test.js +49 -0
- package/dist/teste/AttachmentCardSm.test.d.ts +1 -0
- package/dist/teste/AttachmentCardSm.test.js +26 -0
- package/dist/teste/AvatarGroupOverlap.test.d.ts +1 -0
- package/dist/teste/AvatarGroupOverlap.test.js +56 -0
- package/dist/teste/BadgeNeutroColado.test.d.ts +1 -0
- package/dist/teste/BadgeNeutroColado.test.js +11 -0
- package/dist/teste/BadgeTag.test.d.ts +1 -0
- package/dist/teste/BadgeTag.test.js +55 -0
- package/dist/teste/BoxItemFlex.test.d.ts +1 -0
- package/dist/teste/BoxItemFlex.test.js +54 -0
- package/dist/teste/BoxLayout.test.d.ts +1 -0
- package/dist/teste/BoxLayout.test.js +35 -0
- package/dist/teste/Button.test.d.ts +1 -0
- package/dist/teste/Button.test.js +27 -0
- package/dist/teste/Calendar.test.d.ts +1 -0
- package/dist/teste/Calendar.test.js +221 -0
- package/dist/teste/CalendarCabecalho.test.d.ts +1 -0
- package/dist/teste/CalendarCabecalho.test.js +11 -0
- package/dist/teste/ChipsXs.test.d.ts +1 -0
- package/dist/teste/ChipsXs.test.js +31 -0
- package/dist/teste/Coachmark.test.d.ts +1 -0
- package/dist/teste/Coachmark.test.js +149 -0
- package/dist/teste/CoachmarkSemVeu.test.d.ts +1 -0
- package/dist/teste/CoachmarkSemVeu.test.js +85 -0
- package/dist/teste/ColorPicker.test.d.ts +1 -0
- package/dist/teste/ColorPicker.test.js +132 -0
- package/dist/teste/ColorPickerXs.test.d.ts +1 -0
- package/dist/teste/ColorPickerXs.test.js +21 -0
- package/dist/teste/DataTableArvoreEVariantes.test.d.ts +1 -0
- package/dist/teste/DataTableArvoreEVariantes.test.js +190 -0
- package/dist/teste/DataTableCelulaLivre.test.d.ts +1 -0
- package/dist/teste/DataTableCelulaLivre.test.js +76 -0
- package/dist/teste/DataTableDocumento.test.d.ts +1 -0
- package/dist/teste/DataTableDocumento.test.js +92 -0
- package/dist/teste/DatePicker.test.js +23 -0
- package/dist/teste/DescriptionListCompacta.test.d.ts +1 -0
- package/dist/teste/DescriptionListCompacta.test.js +22 -0
- package/dist/teste/EmptyStateTituloRico.test.d.ts +1 -0
- package/dist/teste/EmptyStateTituloRico.test.js +23 -0
- package/dist/teste/FileInputTrigger.test.d.ts +1 -0
- package/dist/teste/FileInputTrigger.test.js +53 -0
- package/dist/teste/IconPicker.test.d.ts +1 -0
- package/dist/teste/IconPicker.test.js +130 -0
- package/dist/teste/InputAgrupado.test.d.ts +1 -0
- package/dist/teste/InputAgrupado.test.js +24 -0
- package/dist/teste/InputMascaraEAfins.test.d.ts +1 -0
- package/dist/teste/InputMascaraEAfins.test.js +99 -0
- package/dist/teste/KbdCodeBlock.test.d.ts +1 -0
- package/dist/teste/KbdCodeBlock.test.js +95 -0
- package/dist/teste/List.test.d.ts +1 -0
- package/dist/teste/List.test.js +153 -0
- package/dist/teste/ListItemTooltipStandalone.test.d.ts +1 -0
- package/dist/teste/ListItemTooltipStandalone.test.js +39 -0
- package/dist/teste/ModalVariantes.test.d.ts +1 -0
- package/dist/teste/ModalVariantes.test.js +151 -0
- package/dist/teste/NomeAcessivelSsr.test.d.ts +1 -0
- package/dist/teste/NomeAcessivelSsr.test.js +88 -0
- package/dist/teste/OrgChart.test.d.ts +1 -0
- package/dist/teste/OrgChart.test.js +162 -0
- package/dist/teste/OtpInput.test.d.ts +1 -0
- package/dist/teste/OtpInput.test.js +143 -0
- package/dist/teste/PopoverMaxHeight.test.d.ts +1 -0
- package/dist/teste/PopoverMaxHeight.test.js +38 -0
- package/dist/teste/RichTextEditor.test.d.ts +1 -0
- package/dist/teste/RichTextEditor.test.js +287 -0
- package/dist/teste/RichTextEditorAlinhaImagemTabela.test.d.ts +1 -0
- package/dist/teste/RichTextEditorAlinhaImagemTabela.test.js +212 -0
- package/dist/teste/RichTextEditorEstiloDeTexto.test.d.ts +1 -0
- package/dist/teste/RichTextEditorEstiloDeTexto.test.js +120 -0
- package/dist/teste/SegmentedControlContador.test.d.ts +1 -0
- package/dist/teste/SegmentedControlContador.test.js +39 -0
- package/dist/teste/SelectAbertoControladoEFlutuante.test.d.ts +1 -0
- package/dist/teste/SelectAbertoControladoEFlutuante.test.js +145 -0
- package/dist/teste/SelectFiltroCorETamanho.test.d.ts +1 -0
- package/dist/teste/SelectFiltroCorETamanho.test.js +77 -0
- package/dist/teste/SelectPlacementFiltro.test.d.ts +1 -0
- package/dist/teste/SelectPlacementFiltro.test.js +88 -0
- package/dist/teste/Stack.test.d.ts +1 -0
- package/dist/teste/Stack.test.js +57 -0
- package/dist/teste/StatCardRotuloTopo.test.d.ts +1 -0
- package/dist/teste/StatCardRotuloTopo.test.js +34 -0
- package/dist/teste/StatCardSecundariaETom.test.d.ts +1 -0
- package/dist/teste/StatCardSecundariaETom.test.js +45 -0
- package/dist/teste/TabsContadorFechavel.test.d.ts +1 -0
- package/dist/teste/TabsContadorFechavel.test.js +79 -0
- package/dist/teste/ToastAcaoEDetalhes.test.d.ts +1 -0
- package/dist/teste/ToastAcaoEDetalhes.test.js +94 -0
- package/dist/teste/TooltipDark.test.d.ts +1 -0
- package/dist/teste/TooltipDark.test.js +31 -0
- package/dist/utils/calendario.d.ts +28 -0
- package/dist/utils/calendario.js +73 -0
- package/dist/utils/html-seguro.d.ts +45 -0
- package/dist/utils/html-seguro.js +208 -0
- package/dist/utils/paleta-de-cores.d.ts +26 -0
- package/dist/utils/paleta-de-cores.js +10 -0
- package/dist/utils/texto.d.ts +5 -0
- package/dist/utils/texto.js +5 -0
- package/dist/utils/toast.d.ts +10 -1
- package/dist/utils/toast.js +2 -1
- package/package.json +3 -3
- package/src/index.ts +26 -0
- package/src/teste/AILabel.test.tsx +41 -0
- package/src/teste/AccordionConteudoLivre.test.tsx +39 -0
- package/src/teste/AccordionTituloNeutro.test.tsx +25 -0
- package/src/teste/AppSubheaderRegiao.test.tsx +17 -0
- package/src/teste/AtributosRepassados.test.tsx +73 -0
- package/src/teste/AttachmentCardIA.test.tsx +126 -0
- package/src/teste/AttachmentCardLista.test.tsx +53 -0
- package/src/teste/AttachmentCardSm.test.tsx +29 -0
- package/src/teste/AvatarGroupOverlap.test.tsx +74 -0
- package/src/teste/BadgeNeutroColado.test.tsx +15 -0
- package/src/teste/BadgeTag.test.tsx +85 -0
- package/src/teste/BoxItemFlex.test.tsx +81 -0
- package/src/teste/BoxLayout.test.tsx +50 -0
- package/src/teste/Button.test.tsx +39 -0
- package/src/teste/Calendar.test.tsx +282 -0
- package/src/teste/CalendarCabecalho.test.tsx +11 -0
- package/src/teste/ChipsXs.test.tsx +41 -0
- package/src/teste/Coachmark.test.tsx +198 -0
- package/src/teste/CoachmarkSemVeu.test.tsx +101 -0
- package/src/teste/ColorPicker.test.tsx +153 -0
- package/src/teste/ColorPickerXs.test.tsx +22 -0
- package/src/teste/DataTableArvoreEVariantes.test.tsx +240 -0
- package/src/teste/DataTableCelulaLivre.test.tsx +103 -0
- package/src/teste/DataTableDocumento.test.tsx +102 -0
- package/src/teste/DatePicker.test.tsx +38 -0
- package/src/teste/DescriptionListCompacta.test.tsx +24 -0
- package/src/teste/EmptyStateTituloRico.test.tsx +34 -0
- package/src/teste/FileInputTrigger.test.tsx +89 -0
- package/src/teste/IconPicker.test.tsx +145 -0
- package/src/teste/InputAgrupado.test.tsx +26 -0
- package/src/teste/InputMascaraEAfins.test.tsx +124 -0
- package/src/teste/KbdCodeBlock.test.tsx +106 -0
- package/src/teste/List.test.tsx +269 -0
- package/src/teste/ListItemTooltipStandalone.test.tsx +64 -0
- package/src/teste/ModalVariantes.test.tsx +173 -0
- package/src/teste/NomeAcessivelSsr.test.tsx +110 -0
- package/src/teste/OrgChart.test.tsx +183 -0
- package/src/teste/OtpInput.test.tsx +163 -0
- package/src/teste/PopoverMaxHeight.test.tsx +47 -0
- package/src/teste/RichTextEditor.test.tsx +329 -0
- package/src/teste/RichTextEditorAlinhaImagemTabela.test.tsx +238 -0
- package/src/teste/RichTextEditorEstiloDeTexto.test.tsx +137 -0
- package/src/teste/SegmentedControlContador.test.tsx +43 -0
- package/src/teste/SelectAbertoControladoEFlutuante.test.tsx +180 -0
- package/src/teste/SelectFiltroCorETamanho.test.tsx +90 -0
- package/src/teste/SelectPlacementFiltro.test.tsx +110 -0
- package/src/teste/Stack.test.tsx +80 -0
- package/src/teste/StatCardRotuloTopo.test.tsx +44 -0
- package/src/teste/StatCardSecundariaETom.test.tsx +51 -0
- package/src/teste/TabsContadorFechavel.test.tsx +144 -0
- package/src/teste/ToastAcaoEDetalhes.test.tsx +109 -0
- package/src/teste/TooltipDark.test.tsx +51 -0
- package/src/utils/calendario.ts +78 -0
- package/src/utils/html-seguro.ts +197 -0
- package/src/utils/paleta-de-cores.ts +34 -0
- package/src/utils/texto.ts +5 -0
- package/src/utils/toast.ts +12 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,1545 @@
|
|
|
1
1
|
# @1doc/1ds-react
|
|
2
2
|
|
|
3
|
+
## 2.10.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 12c65e9: feat(accordion): `titleVariant="neutral"`, o título de texto
|
|
8
|
+
|
|
9
|
+
`titleVariant` aceita `default` (o título como era) e `neutral`: 14px na cor do texto
|
|
10
|
+
(`neutral-dark-pure`), peso médio, também no hover e no aberto, sem cor de ação. O chevron
|
|
11
|
+
aberto continua azul (é o sinal do estado). Combina com qualquer `variant`.
|
|
12
|
+
|
|
13
|
+
```vue
|
|
14
|
+
<Accordion :items="itens" variant="separated" titleVariant="neutral" />
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- 6df8835: feat(attachmentcard): `size="sm"`, o cartão compacto do CrisDoc
|
|
18
|
+
|
|
19
|
+
`size="sm"` leva o ícone do preview a 40px (no `md`, 48px) e o ícone do rodapé a
|
|
20
|
+
12px (no `md`, o `sm` do `Icon`). A largura do cartão, os selos e o painel não
|
|
21
|
+
mudam. Sem `size`, ou com `md`, o cartão é o mesmo.
|
|
22
|
+
|
|
23
|
+
```vue
|
|
24
|
+
<AttachmentCard
|
|
25
|
+
fileName="Protocolo 104-2026.pdf"
|
|
26
|
+
documentType="Parecer"
|
|
27
|
+
size="sm"
|
|
28
|
+
:onOpen="abrir"
|
|
29
|
+
/>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- 4ab330c: feat(badge): `attachedSide="left" | "right"` no `Badge attached`
|
|
33
|
+
|
|
34
|
+
O rótulo colado no topo do card pode ir para o canto direito. Sem a prop, ou com
|
|
35
|
+
`left`, continua no esquerdo. Só vale com `attached`.
|
|
36
|
+
|
|
37
|
+
```vue
|
|
38
|
+
<Badge
|
|
39
|
+
:attached="true"
|
|
40
|
+
attachedSide="right"
|
|
41
|
+
size="sm"
|
|
42
|
+
appearance="solid"
|
|
43
|
+
variant="primary"
|
|
44
|
+
>Prazo hoje</Badge>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- 1f805cd: feat(coachmark): `modal={false}`, o cartão sem véu nem foco preso, para dica pontual
|
|
48
|
+
|
|
49
|
+
Com `modal={false}` não há véu, recorte nem foco preso: o cartão é um popover
|
|
50
|
+
ancorado no alvo (`role="dialog"` com `aria-modal="false"`). A página segue
|
|
51
|
+
clicável, o foco entra no cartão ao abrir mas o Tab pode sair dele, e o Esc fecha de
|
|
52
|
+
qualquer lugar da página (uma vez só, com o motivo `escape`). Ao fechar, o foco só
|
|
53
|
+
volta ao elemento de antes se a pessoa não foi a outro lugar. Sem a prop, o tour é
|
|
54
|
+
modal como sempre (no Vue, `modal` é `any` para a ausência não virar `false`).
|
|
55
|
+
|
|
56
|
+
Corrige também o elemento de antes guardado duas vezes no React (o segundo
|
|
57
|
+
`sincronizar`, antes de o `active` valer, guardava o próprio cartão e o foco não voltava).
|
|
58
|
+
|
|
59
|
+
```vue
|
|
60
|
+
<Coachmark
|
|
61
|
+
:open="aberto"
|
|
62
|
+
:modal="false"
|
|
63
|
+
:hideSkip="true"
|
|
64
|
+
finishLabel="Entendi"
|
|
65
|
+
:steps="[{ target: '#salvar', title: 'Novo: salvar com Ctrl+S' }]"
|
|
66
|
+
:onClose="() => (aberto = false)"
|
|
67
|
+
/>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- 46b3b42: feat(colorpicker): `size="xs"`, a amostra de 20px do CrisDoc
|
|
71
|
+
|
|
72
|
+
`size` ganha `xs` (20px), além de `sm` (24px) e `md` (32px). O anel de seleção (o anel duplo)
|
|
73
|
+
e o roving tabindex são os mesmos nos três tamanhos. O `sm` segue em 24px: o `xs` é o 20px do
|
|
74
|
+
CrisDoc.
|
|
75
|
+
|
|
76
|
+
```vue
|
|
77
|
+
<ColorPicker
|
|
78
|
+
ariaLabel="Marcador"
|
|
79
|
+
size="xs"
|
|
80
|
+
:families="['blue', 'red']"
|
|
81
|
+
defaultValue="--umds-primitive-red-pure"
|
|
82
|
+
/>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- 82e85c5: feat(datatable): cabeçalho escuro, zebra, destaque de linha, vazio com ícone, `hideHeader` e linhas hierárquicas (`treeData`)
|
|
86
|
+
|
|
87
|
+
Tudo opt-in; sem as props novas a tabela é a mesma.
|
|
88
|
+
|
|
89
|
+
- `headerVariant="dark"`: cabeçalho navy com texto claro (`background-dark` e
|
|
90
|
+
`neutral-light-pure`, então o tema acompanha). `headerUppercase`: caixa alta
|
|
91
|
+
nos rótulos, vale para qualquer cabeçalho.
|
|
92
|
+
- `striped`: zebra nas linhas ímpares.
|
|
93
|
+
- `selectedRowKeys` (com `rowKey`) e `isRowSelected(row, index)`: destacam a linha
|
|
94
|
+
sem checkbox (fundo, barra de 4px à esquerda e `aria-selected`). Serve à linha
|
|
95
|
+
"aberta" de uma lista mestre-detalhe. `selectedKeys` segue sendo o checkbox.
|
|
96
|
+
- `emptyIcon` (objeto Font Awesome, padrão `faInbox`) e `emptyDescription`.
|
|
97
|
+
- `hideHeader`: o cabeçalho some da tela e as colunas continuam nomeadas para o
|
|
98
|
+
leitor de tela (a linha fica visualmente oculta, não removida).
|
|
99
|
+
- `density="compact"` + `variant="document"`: fonte de 12px e célula de 4px × 8px.
|
|
100
|
+
A escala do DS não tem 13px, então o compacto da tabela de interface segue em 14.
|
|
101
|
+
- `treeData` + `childrenKey`: linhas hierárquicas. A tabela vira `role="treegrid"`,
|
|
102
|
+
as linhas ganham `aria-level`, `aria-posinset`, `aria-setsize` e `aria-expanded`,
|
|
103
|
+
e a primeira coluna leva recuo por nível, fios (tee, cotovelo e linha contínua) e o
|
|
104
|
+
botão de expandir/recolher. Teclado: ↓ ↑ andam, → expande (ou desce à primeira
|
|
105
|
+
filha), ← recolhe (ou sobe ao pai), Home e End. Uma linha por vez na ordem de Tab.
|
|
106
|
+
Estado: `expandedKeys` (controlado), `defaultExpandedKeys`, `defaultExpandAll` e
|
|
107
|
+
`onExpand(chaves, linha, expandida)`. A chave é o `rowKey`; sem ele, o caminho de
|
|
108
|
+
índices. `expandLabel` e `collapseLabel` traduzem o botão. Com `treeData`, os índices
|
|
109
|
+
dos callbacks contam as linhas visíveis.
|
|
110
|
+
|
|
111
|
+
O slot `#cell-<key>` do Vue segue valendo na coluna da árvore (o `postbuild` agora
|
|
112
|
+
liga as duas ocorrências da célula).
|
|
113
|
+
|
|
114
|
+
```vue
|
|
115
|
+
<DataTable
|
|
116
|
+
:columns="colunas"
|
|
117
|
+
:data="setores"
|
|
118
|
+
rowKey="id"
|
|
119
|
+
:treeData="true"
|
|
120
|
+
headerVariant="dark"
|
|
121
|
+
:headerUppercase="true"
|
|
122
|
+
:striped="true"
|
|
123
|
+
:defaultExpandedKeys="['gab']"
|
|
124
|
+
:onExpand="aoExpandir"
|
|
125
|
+
>
|
|
126
|
+
<template #cell-nome="{ row }"><strong>{{ row.sigla }}</strong> {{ row.nome }}</template>
|
|
127
|
+
</DataTable>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
- 1c9f7cb: feat(descriptionlist): `density="compact"`, a fonte de 12px do CrisDoc
|
|
131
|
+
|
|
132
|
+
`density="compact"` leva a fonte da lista de 14 para 12px (nos dois desenhos), aperta o
|
|
133
|
+
espaço entre os pares do `stacked` (de 16 para 12px) e o padding do valor com `bordered`.
|
|
134
|
+
Sem a prop, ou com `default`, a lista é a mesma.
|
|
135
|
+
|
|
136
|
+
```vue
|
|
137
|
+
<DescriptionList
|
|
138
|
+
:items="dados"
|
|
139
|
+
layout="stacked"
|
|
140
|
+
:bordered="true"
|
|
141
|
+
density="compact"
|
|
142
|
+
/>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
- d062029: feat(emptystate): título com conteúdo rico (elemento no React, slot `title` no Vue)
|
|
146
|
+
|
|
147
|
+
O `title` do `EmptyState` aceita conteúdo (negrito, link, ícone). No React é um
|
|
148
|
+
elemento na própria prop; no Vue é o slot `title`, com a prop como texto de reserva.
|
|
149
|
+
O título passa a ser um `div` (antes um `p`), com a mesma classe e o mesmo visual,
|
|
150
|
+
para o conteúdo de bloco não virar HTML inválido. `title` deixou de ser obrigatório
|
|
151
|
+
na tipagem: no Vue o slot basta.
|
|
152
|
+
|
|
153
|
+
```vue
|
|
154
|
+
<EmptyState :icon="faMagnifyingGlass" description="Ajuste o filtro de setor.">
|
|
155
|
+
<template #title>Nenhum processo para <strong>SOBR</strong></template>
|
|
156
|
+
</EmptyState>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
- 29955dd: feat(input): `grouped`, o campo dentro de um contêiner que já tem moldura e foco (campo de chips)
|
|
160
|
+
|
|
161
|
+
Opt-in. `grouped` implica `borderless` e tira a altura de campo, o padding e o anel
|
|
162
|
+
de foco próprio do `Input`: a altura vem do conteúdo (a linha cresce com as tags), o
|
|
163
|
+
campo ocupa o espaço que sobra (`flex: 1 1 80px`, sem `fullWidth`) e quem mostra o foco é
|
|
164
|
+
o contêiner, com `:focus-within`. O `borderless` sozinho continua como era: com altura de
|
|
165
|
+
campo e o contorno de foco para dentro. Sem o foco no contêiner, quem usa teclado perde o
|
|
166
|
+
indicador (WCAG 2.4.7): a doc da prop avisa.
|
|
167
|
+
|
|
168
|
+
```vue
|
|
169
|
+
<div class="chips-campo"> <!-- a moldura e o :focus-within são seus -->
|
|
170
|
+
<Tag label="SADM" size="sm" />
|
|
171
|
+
<Input ariaLabel="Adicionar setor" :grouped="true" size="sm" />
|
|
172
|
+
</div>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
- 76c0087: feat(listitem): `tooltip`, `standalone` e atributos HTML só no elemento interativo
|
|
176
|
+
|
|
177
|
+
- `tooltip`: vira o atributo HTML `title` do `button`, `a` ou `div` (a dica nativa do
|
|
178
|
+
navegador). `title` continua sendo o título da linha, não o atributo.
|
|
179
|
+
- `standalone`: renderiza sem o `li`, só o elemento interativo, para usar fora de um
|
|
180
|
+
`List` (botão de número de página, item de carrossel). `class` (Vue) ou `className`
|
|
181
|
+
vai ao elemento.
|
|
182
|
+
- Correção no Vue: `aria-*`, `role`, `data-*` e `style` iam ao `li` além do elemento
|
|
183
|
+
interativo (o `aria-label` aparecia duas vezes e o `li` ganhava um `role` que não era
|
|
184
|
+
dele). Agora o `inheritAttrs` está desligado e esses atributos vão só ao elemento
|
|
185
|
+
interativo, como no React. O `class` do Vue continua no `li`, como sempre. Por baixo,
|
|
186
|
+
o ListItem passa a ter duas raízes (com `li` e `standalone`), então o HTML do servidor
|
|
187
|
+
abre com marcador de fragmento.
|
|
188
|
+
|
|
189
|
+
```vue
|
|
190
|
+
<ListItem
|
|
191
|
+
:standalone="true"
|
|
192
|
+
title="12"
|
|
193
|
+
tooltip="Página 12"
|
|
194
|
+
:selected="pagina === 12"
|
|
195
|
+
:onClick="irPara"
|
|
196
|
+
/>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
- 3500910: feat(richtexteditor): alinhamento, imagem e tabela simples na `toolbar`
|
|
200
|
+
|
|
201
|
+
Opt-in: a barra padrão não muda. Entram na `toolbar` por nome:
|
|
202
|
+
|
|
203
|
+
- `alignLeft`, `alignCenter`, `alignRight`, `alignJustify`: botões de liga/desliga
|
|
204
|
+
que seguem o cursor (`aria-pressed`). O valor guarda `text-align` nos blocos.
|
|
205
|
+
- `image`: abre um painel (como o do link) com o endereço da imagem, o arquivo
|
|
206
|
+
(PNG, JPEG, GIF ou WebP até 2 MB, que entra como `data:` URL) e o texto
|
|
207
|
+
alternativo. Endereço e arquivo inválidos mostram o erro e o painel continua aberto.
|
|
208
|
+
- `table`: abre um painel com linhas e colunas (1 a 20 e 1 a 10, padrão 3 × 3) e
|
|
209
|
+
insere a tabela. Com o cursor numa célula aparece a barra de adicionar e remover
|
|
210
|
+
linha e coluna e remover a tabela (mexe no DOM, então fica fora do desfazer).
|
|
211
|
+
|
|
212
|
+
A higienização do valor passou a aceitar `text-align` nos blocos (também pelo
|
|
213
|
+
atributo `align`), `img` e a tabela (`table`, `thead`, `tbody`, `tr`, `th`, `td`
|
|
214
|
+
com `colspan` e `rowspan`). Imagem só vale com `http(s)`, caminho (`/x`, `./x`,
|
|
215
|
+
`../x`) ou `data:image` em base64 de PNG, JPEG, GIF e WebP; SVG, `javascript:`,
|
|
216
|
+
`//host` e o resto saem inteiros. Colar continua entrando como texto puro.
|
|
217
|
+
|
|
218
|
+
Todos os textos novos vêm por `labels` (`imageUrl`, `imageAlt`, `imageFile`,
|
|
219
|
+
`imageApply`, `imageCancel`, `imageInvalid`, `imageType`, `imageTooLarge`,
|
|
220
|
+
`tableRows`, `tableCols`, `tableApply`, `tableCancel`, `tableInvalid`,
|
|
221
|
+
`tableActions`, `tableAddRow`, `tableRemoveRow`, `tableAddCol`, `tableRemoveCol`,
|
|
222
|
+
`tableRemove` e o nome de cada ferramenta nova).
|
|
223
|
+
|
|
224
|
+
```vue
|
|
225
|
+
<RichTextEditor
|
|
226
|
+
label="Parecer"
|
|
227
|
+
:defaultValue="html"
|
|
228
|
+
:toolbar="[
|
|
229
|
+
'bold',
|
|
230
|
+
'italic',
|
|
231
|
+
'|',
|
|
232
|
+
'alignLeft',
|
|
233
|
+
'alignCenter',
|
|
234
|
+
'alignRight',
|
|
235
|
+
'alignJustify',
|
|
236
|
+
'|',
|
|
237
|
+
'link',
|
|
238
|
+
'image',
|
|
239
|
+
'table',
|
|
240
|
+
]"
|
|
241
|
+
/>
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
- af0d976: feat(richtexteditor): família, tamanho de fonte e cor do texto, por token do DS
|
|
245
|
+
|
|
246
|
+
Opt-in na `toolbar`: `fontFamily`, `fontSize` e `textColor`. Cada um abre um painel abaixo da
|
|
247
|
+
barra e aplica ao texto selecionado, embrulhando-o num `<span style="...">`:
|
|
248
|
+
|
|
249
|
+
- `fontFamily`: padrão ou monoespaçada (`var(--umds-semantic-font-family-base|mono)`), num `Select`.
|
|
250
|
+
- `fontSize`: 12, 14, 16, 20 e 24px, os degraus da escala do DS (`var(--umds-primitive-font-size-*)`).
|
|
251
|
+
- `textColor`: a paleta do DS, num `ColorPicker` `xs`; o valor guarda o `var()` do token escolhido.
|
|
252
|
+
|
|
253
|
+
Sem texto selecionado o painel pede a seleção e não aplica nada. Esc fecha só a lista do `Select`
|
|
254
|
+
aberta; o seguinte fecha o painel. Para voltar ao padrão, use `clear`.
|
|
255
|
+
|
|
256
|
+
A higienização aceita `color`, `font-size` e `font-family` só em `<span>` e só com token do DS: cor
|
|
257
|
+
em hex, `rgb()` ou nome, tamanho em px e fonte por nome saem, e o resto do `style` também.
|
|
258
|
+
|
|
259
|
+
Textos novos por `labels`: `fontFamily`, `fontSize`, `textColor`, `fontFamilyBase`,
|
|
260
|
+
`fontFamilyMono`, `styleClose` e `styleNeedsSelection`.
|
|
261
|
+
|
|
262
|
+
```vue
|
|
263
|
+
<RichTextEditor
|
|
264
|
+
label="Parecer"
|
|
265
|
+
:toolbar="['bold', 'italic', '|', 'fontFamily', 'fontSize', 'textColor']"
|
|
266
|
+
/>
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
- 992f59a: feat(segmentedcontrol): `count` por item, a pílula do contador como a do `Tab`
|
|
270
|
+
|
|
271
|
+
Cada opção aceita `count` (número ou texto): uma pílula de 18px depois do rótulo,
|
|
272
|
+
cinza no segmento solto e branca sobre o azul do escolhido (o mesmo desenho do
|
|
273
|
+
contador do `Tab`). `0` aparece; vazio e ausente não. O contador entra no nome
|
|
274
|
+
acessível do segmento ("Todas 31"). Sem `count`, o segmento é o mesmo.
|
|
275
|
+
|
|
276
|
+
```vue
|
|
277
|
+
<SegmentedControl
|
|
278
|
+
label="Fila"
|
|
279
|
+
:value="fila"
|
|
280
|
+
:onChange="(v) => (fila = v)"
|
|
281
|
+
:options="[
|
|
282
|
+
{ label: 'Todas', value: 'todas', count: 31 },
|
|
283
|
+
{ label: 'Minhas', value: 'minhas', count: 12 },
|
|
284
|
+
]"
|
|
285
|
+
/>
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
- 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
|
|
289
|
+
|
|
290
|
+
Tudo opt-in; o Select sem as props novas se comporta como antes, fora de diálogo.
|
|
291
|
+
|
|
292
|
+
- `open` e `onOpenChange(open)`: a lista controlada de fora. O clique, o teclado,
|
|
293
|
+
o clique fora, o Esc e a escolha de uma opção avisam o pai, que decide o novo
|
|
294
|
+
`open`. Sem `open`, o Select abre e fecha sozinho e também avisa. É o que deixa o
|
|
295
|
+
filtro com ação no rodapé fechar a lista antes de abrir um modal.
|
|
296
|
+
- `triggerIcon` (objeto Font Awesome) e `triggerSwatch` (um token de cor): ícone e
|
|
297
|
+
amostra de cor à esquerda do texto do gatilho, decorativos.
|
|
298
|
+
- `variant="search"` (o filtro numa barra de busca: altura de campo e contorno neutro)
|
|
299
|
+
e `variant="combo"` (colado a outro controle, sem borda nem raio próprios). Os dois
|
|
300
|
+
são filtro: busca focada ao abrir, `emptyOptionLabel` e o rodapé valem.
|
|
301
|
+
- Dentro de um diálogo (`role="dialog"` ou `aria-modal`), a lista abre por cima dele:
|
|
302
|
+
`position: fixed` ancorada no gatilho pelo `@floating-ui/dom`, com a largura do
|
|
303
|
+
gatilho e a altura limitada ao espaço da janela. O `overflow` do corpo do modal
|
|
304
|
+
não corta mais a lista.
|
|
305
|
+
- `placement="auto"` agora mede também cada ancestral que rola ou corta (um corpo de
|
|
306
|
+
modal, um painel com `overflow`), não só a janela, e limita a altura da lista ao
|
|
307
|
+
espaço que sobra (mínimo de 96px).
|
|
308
|
+
- `required` repassa `aria-required` ao combobox.
|
|
309
|
+
|
|
310
|
+
```vue
|
|
311
|
+
<Select
|
|
312
|
+
variant="filter"
|
|
313
|
+
ariaLabel="Marcadores"
|
|
314
|
+
placeholder="Marcadores"
|
|
315
|
+
:triggerIcon="faTag"
|
|
316
|
+
:open="aberto"
|
|
317
|
+
:onOpenChange="(v) => (aberto = v)"
|
|
318
|
+
:options="marcadores"
|
|
319
|
+
:value="valor"
|
|
320
|
+
:onChange="(v) => (valor = v)"
|
|
321
|
+
>
|
|
322
|
+
<template #footer>
|
|
323
|
+
<Button variant="text" size="sm" @click="abrirGerenciador">Gerenciar marcadores</Button>
|
|
324
|
+
</template>
|
|
325
|
+
</Select>
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
- f7fa5dd: feat(select): o filtro no tamanho do CrisDoc, com cor por opção (`option.color`)
|
|
329
|
+
|
|
330
|
+
Para substituir o `FiltroSelect` do app:
|
|
331
|
+
|
|
332
|
+
- As variantes de filtro (`filter`, `search`, `combo`) nascem no tamanho `sm` (32px, fonte de
|
|
333
|
+
12px) quando `size` não é passado; `size="md"` continua valendo. O `Select` padrão não muda.
|
|
334
|
+
- O gatilho do `filter` tem fundo branco com contorno azul. O azul-claro só vem depois de
|
|
335
|
+
escolhido um valor (a classe `umds-select--has-value`), que é quando o filtro está
|
|
336
|
+
recortando a lista. `search` e `combo` mantêm o fundo deles.
|
|
337
|
+
- `option.color` (um token, `var(--umds-semantic-color-...)`): uma amostra de 12px antes do
|
|
338
|
+
texto de cada opção na lista e, com a opção escolhida (seleção única), no gatilho.
|
|
339
|
+
`triggerSwatch` explícito manda sobre ela. A cor é decorativa: o nome da opção continua
|
|
340
|
+
sendo o texto.
|
|
341
|
+
- O `useStore` do `Select` passou a checar o gatilho antes do `autoUpdate` (o `tsc` do React
|
|
342
|
+
acusava o `null`).
|
|
343
|
+
|
|
344
|
+
```vue
|
|
345
|
+
<Select
|
|
346
|
+
variant="filter"
|
|
347
|
+
ariaLabel="Marcadores"
|
|
348
|
+
placeholder="Marcadores"
|
|
349
|
+
:triggerIcon="faFilter"
|
|
350
|
+
:options="[
|
|
351
|
+
{
|
|
352
|
+
label: 'Urgente',
|
|
353
|
+
value: 'urgente',
|
|
354
|
+
color: 'var(--umds-semantic-color-feedback-negative-pure)',
|
|
355
|
+
},
|
|
356
|
+
]"
|
|
357
|
+
/>
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
- b9f0813: feat(statcard): segunda medida (`secondaryValue`/`secondaryLabel`) e `valueTone`
|
|
361
|
+
|
|
362
|
+
- `secondaryValue` e `secondaryLabel`: a segunda medida do cartão, menor (20px), à direita da
|
|
363
|
+
principal, separada por um filete ("22,31% Meu Setor | 14,11% Geral"). No HTML vem depois do
|
|
364
|
+
resto, então o leitor de tela lê a medida principal inteira antes. `0` aparece; vazio e
|
|
365
|
+
ausente não. Com `labelPosition="top"` a grade ganha uma terceira coluna.
|
|
366
|
+
- `valueTone`: cor do número principal, `default` | `primary` | `positive` | `negative` |
|
|
367
|
+
`info`, pelas variantes escuras (contraste AA no branco). Não mexe na `variant`, que segue
|
|
368
|
+
pintando o ícone e a variação.
|
|
369
|
+
|
|
370
|
+
```vue
|
|
371
|
+
<StatCard
|
|
372
|
+
labelPosition="top"
|
|
373
|
+
label="Eficiência"
|
|
374
|
+
value="22,31%"
|
|
375
|
+
description="Meu Setor"
|
|
376
|
+
secondaryValue="14,11%"
|
|
377
|
+
secondaryLabel="Geral"
|
|
378
|
+
valueTone="primary"
|
|
379
|
+
/>
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
- a4b6bb7: feat(toast): ação (`actionLabel`/`onAction`) e lista de detalhes (`details`)
|
|
383
|
+
|
|
384
|
+
- `actionLabel` + `onAction`: um botão depois do texto ("Desfazer", "Ver processo").
|
|
385
|
+
Acionar chama `onAction` e depois fecha o toast (`onClose`). O botão só aparece com os
|
|
386
|
+
dois. O botão de fechar continua ao lado.
|
|
387
|
+
- `details`: lista de linhas curtas abaixo da descrição ("Anexo 1 acima de 10 MB").
|
|
388
|
+
- No `toast()` imperativo e no `ToastStack`, as três opções passam adiante. Toast com ação
|
|
389
|
+
tem `duration: 0` por padrão (não some antes de dar tempo de agir, WCAG 2.2.1); sem ação
|
|
390
|
+
continua em 5000, e um `duration` explícito vale sempre.
|
|
391
|
+
|
|
392
|
+
```ts
|
|
393
|
+
toast({
|
|
394
|
+
message: "Despacho enviado",
|
|
395
|
+
variant: "positive",
|
|
396
|
+
actionLabel: "Desfazer",
|
|
397
|
+
onAction: desfazer,
|
|
398
|
+
});
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### Patch Changes
|
|
402
|
+
|
|
403
|
+
- 6c12a37: fix(appsubheader): a região do contexto ocupa a altura da barra e só rola na horizontal
|
|
404
|
+
|
|
405
|
+
Com a trilha só na página atual (um `Breadcrumb` sem link), o axe acusava
|
|
406
|
+
`scrollable-region-focusable`. Medido no navegador: a região do contexto tinha 12px de
|
|
407
|
+
altura (a do item do Breadcrumb, `line-height: 1` em 12px) e `scrollHeight` de 14, e como
|
|
408
|
+
`overflow-x: auto` faz o `overflow-y` computar para `auto`, ela virava uma região rolável
|
|
409
|
+
sem nenhum elemento focável dentro. Agora a região ocupa a altura da barra
|
|
410
|
+
(`align-self: stretch`, 41px, com o conteúdo centralizado) e corta o eixo vertical
|
|
411
|
+
(`overflow-y: hidden`): não há o que rolar na vertical. A rolagem horizontal da trilha longa
|
|
412
|
+
continua igual. Story nova "Só a página atual" confere `scrollHeight` e `scrollWidth`.
|
|
413
|
+
|
|
414
|
+
- e8f1894: fix(attachmentcard): o `dl` do painel de conferência passa no axe (`definition-list`)
|
|
415
|
+
|
|
416
|
+
Cada campo do painel era `div > (div > dt + dd) + button`: o `dl` só aceita `div` com `dt` e
|
|
417
|
+
`dd` direto dentro, então o axe acusava `definition-list`. Agora é `div > dt + dd`, e o
|
|
418
|
+
botão de copiar mora dentro do `dd`, ao lado do valor (o valor passou a ter o próprio
|
|
419
|
+
`span`, `umds-attachment-card__campo-valor-texto`). O visual muda só no detalhe: o botão
|
|
420
|
+
de copiar fica alinhado à linha do valor, não ao centro das duas linhas do campo.
|
|
421
|
+
|
|
422
|
+
- 04d5a43: fix(badge): o neutro colado é o cinza claro com texto escuro
|
|
423
|
+
|
|
424
|
+
`<Badge attached variant="neutral" appearance="solid">` ficava no cinza escuro do `solid`
|
|
425
|
+
neutro, pesado demais para o rótulo de um card. Agora o neutro colado e sólido é o cinza claro
|
|
426
|
+
com texto escuro (o "Tarefa manual" do CrisDoc). O `solid` neutro fora do `attached` não muda.
|
|
427
|
+
|
|
428
|
+
- e5896d9: docs(calendar): os slots do cabeçalho no Vue são `#header-start` e `#header-end`
|
|
429
|
+
|
|
430
|
+
O `index.d.ts` e a documentação diziam `headerStart` e `headerEnd` para os dois
|
|
431
|
+
frameworks, mas no Vue só os nomes com hífen chegam ao cabeçalho (o Vue lê o nome do
|
|
432
|
+
slot como está: `#headerStart` é descartado em silêncio). A doc do componente, o
|
|
433
|
+
comentário das props e os `argTypes` dos Storybooks agora dizem: no React, as props
|
|
434
|
+
`headerStart` e `headerEnd` (um nó); no Vue, os slots `#header-start` e `#header-end`.
|
|
435
|
+
Sem mudança de comportamento.
|
|
436
|
+
|
|
437
|
+
## 2.9.0
|
|
438
|
+
|
|
439
|
+
### Minor Changes
|
|
440
|
+
|
|
441
|
+
- 704af0c: feat(accordion): conteúdo livre por item no Vue (slot `content-<id>`)
|
|
442
|
+
|
|
443
|
+
No React o `content` do item já aceitava qualquer nó. No Vue ele era interpolado
|
|
444
|
+
como texto, então o painel só aceitava string. Agora, no Vue, cada item pode ter
|
|
445
|
+
um slot com o próprio conteúdo.
|
|
446
|
+
|
|
447
|
+
- `#content-<id>`: slot com escopo por item (`<id>` é o `id` do item), que recebe
|
|
448
|
+
`{ item }` e vale sobre o `content` de texto daquele item. Itens sem slot
|
|
449
|
+
continuam mostrando o texto. O `postbuild` liga o slot ao `Accordion.vue`
|
|
450
|
+
gerado, como já faz com o `DataTable`, e falha o build se o gerado mudar de
|
|
451
|
+
forma.
|
|
452
|
+
- Título: o título do item **já é neutro** no 1DS (14/600, `neutral-dark-pure`;
|
|
453
|
+
só o chevron fica azul quando abre), então não há opção de cor a acrescentar.
|
|
454
|
+
Se o CrisDoc mediu azul de 16px, era outra peça ou uma versão antiga.
|
|
455
|
+
|
|
456
|
+
```vue
|
|
457
|
+
<Accordion :items="[{ id: 'campos', title: 'Seção 01', content: '' }]">
|
|
458
|
+
<template #content-campos>
|
|
459
|
+
<Input label="Nome" fullWidth />
|
|
460
|
+
</template>
|
|
461
|
+
</Accordion>
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
- 3d9472d: feat(attachmentcard): `status="ai"`, painel livre (`panel`), `panelWidth` e `closePanelOnAction`
|
|
465
|
+
|
|
466
|
+
Opt-in; sem as props novas o cartão é o mesmo.
|
|
467
|
+
|
|
468
|
+
- `status="ai"`: selo de recurso de IA, no roxo da IA (`ai-light` / `ai-dark`, os
|
|
469
|
+
mesmos tokens do `AILabel`), com a varinha como ícone padrão (`statusIcon`
|
|
470
|
+
continua mandando). O ícone do painel também é a varinha.
|
|
471
|
+
- `panel`: conteúdo livre do painel do selo, no lugar do resultado da conferência
|
|
472
|
+
(ações, campos, texto). React: o elemento; Vue: o slot `panel`. Com ele o selo
|
|
473
|
+
vira botão mesmo sem `statusDetails`. Sem título interno, o painel é nomeado
|
|
474
|
+
pelo selo (o mesmo nome que o botão tem, "Recursos IA: conferência de ...").
|
|
475
|
+
- `panelWidth` (px): largura do painel; padrão 300.
|
|
476
|
+
- `closePanelOnAction`: ao acionar um botão ou link de dentro do painel (o
|
|
477
|
+
"Aplicar sugestão"), o painel fecha e o foco volta ao selo. A ação do app roda
|
|
478
|
+
antes. O botão de copiar um campo não conta. Sem a prop, o painel fica aberto
|
|
479
|
+
até Esc, clique fora ou o foco sair.
|
|
480
|
+
|
|
481
|
+
Por baixo, o `postbuild` ganhou `slotsNoScriptVue`: o Vue que recebe só o slot
|
|
482
|
+
enxergava `props.panel` como `undefined` no script e o selo não virava botão. O
|
|
483
|
+
gancho troca `props.<prop>` por `(props.<prop> || slots['<slot>'])` nos arquivos
|
|
484
|
+
listados e falha o build se o gerado não tiver o formato esperado.
|
|
485
|
+
|
|
486
|
+
```vue
|
|
487
|
+
<AttachmentCard
|
|
488
|
+
fileName="Protocolo 104-2026.pdf"
|
|
489
|
+
status="ai"
|
|
490
|
+
statusLabel="Recursos IA"
|
|
491
|
+
:panelWidth="280"
|
|
492
|
+
:closePanelOnAction="true"
|
|
493
|
+
>
|
|
494
|
+
<template #panel>
|
|
495
|
+
<Text>A IA sugere "Recurso Administrativo".</Text>
|
|
496
|
+
<Button size="sm" @click="aplicar">Aplicar sugestão</Button>
|
|
497
|
+
</template>
|
|
498
|
+
</AttachmentCard>
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
- 2c0dafb: feat(avatargroup): `overlap`, `ring` e `overflowCount`
|
|
502
|
+
|
|
503
|
+
Opt-in; sem as props novas o grupo é o mesmo.
|
|
504
|
+
|
|
505
|
+
- `overflowCount`: quantas pessoas existem além das de `avatars`. O "+N" deixa de
|
|
506
|
+
exigir N itens-fantasma: com 16 responsáveis, passe os 4 primeiros e
|
|
507
|
+
`overflowCount={12}`. Soma com o que passar de `max` dentro de `avatars`, e os
|
|
508
|
+
textos traduzíveis (`overflowTitle`, `overflowAriaLabel`) recebem o total.
|
|
509
|
+
- `overlap` (px): quanto cada avatar avança sobre o anterior. O padrão segue 8
|
|
510
|
+
(`spacing-nano`); 6 é o do CrisDoc e corta menos as iniciais. O recuo do
|
|
511
|
+
último item acompanha.
|
|
512
|
+
- `ring` (px): largura do anel (a borda da cor do fundo). O padrão segue 1,5; 1 é
|
|
513
|
+
o do CrisDoc.
|
|
514
|
+
|
|
515
|
+
As duas últimas escrevem `--umds-avatar-group-overlap` e `--umds-avatar-group-ring`
|
|
516
|
+
no próprio grupo (os padrões vivem no CSS), então só aparece `style` quando você
|
|
517
|
+
as usa.
|
|
518
|
+
|
|
519
|
+
```vue
|
|
520
|
+
<AvatarGroup
|
|
521
|
+
:avatars="primeiros4"
|
|
522
|
+
:max="4"
|
|
523
|
+
:overlap="6"
|
|
524
|
+
:ring="1"
|
|
525
|
+
:overflowCount="12"
|
|
526
|
+
/>
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
- 8ff3652: feat(badge, tag): tamanhos compactos, `Tag soft` e `pill`, variante `new` e `Badge attached`
|
|
530
|
+
|
|
531
|
+
Tudo opt-in: sem as props novas, o HTML e o visual são os mesmos.
|
|
532
|
+
|
|
533
|
+
**Badge**
|
|
534
|
+
|
|
535
|
+
- `size="2xs"`: 16px de altura, fonte de 10px, raio 4. A fonte de 10px não está
|
|
536
|
+
na escala do DS (o menor degrau é 12px), então é um literal comentado no CSS;
|
|
537
|
+
se o mínimo de 12px for decisão de acessibilidade, o 2xs é o que sai.
|
|
538
|
+
- `variant="new"` (a "novidade" do CrisDoc): amarelo, caixa alta, 800, pílula.
|
|
539
|
+
Solid e soft usam o fundo amarelo; outlined, o contorno. O DS não tem token
|
|
540
|
+
semântico de amarelo, então usa os primitivos `yellow-*` (com o `yellow-light`
|
|
541
|
+
já corrigido) e `gray-darkest` para o texto, que não mudam com o tema
|
|
542
|
+
(contraste 8:1). Candidato a token semântico de destaque.
|
|
543
|
+
- `attached`: rótulo colado no canto superior esquerdo de um card, com os cantos
|
|
544
|
+
de baixo arredondados e os de cima retos. Posiciona em `absolute`: o pai
|
|
545
|
+
precisa de `position: relative`.
|
|
546
|
+
|
|
547
|
+
**Tag**
|
|
548
|
+
|
|
549
|
+
- `size="xs"`: 18px (`line-height: 1`, padding 2 e 8, fonte 12, ícone 12). Foi
|
|
550
|
+
criado um tamanho novo em vez de mexer no `sm` (27px), para não encolher quem
|
|
551
|
+
já usa `sm`. O × e o ícone clicável mantêm o alvo de 24px com margem negativa.
|
|
552
|
+
- `appearance="soft"`: fundo claro da cor da variante, sem contorno.
|
|
553
|
+
- `pill`: cantos totalmente arredondados, em qualquer aparência e tamanho.
|
|
554
|
+
- `variant="new"`: amarelo, nas três aparências (soft = `yellow-light` com texto
|
|
555
|
+
`yellow-dark`).
|
|
556
|
+
|
|
557
|
+
```vue
|
|
558
|
+
<Badge size="2xs" appearance="solid">SOBR</Badge>
|
|
559
|
+
<Badge variant="new" size="xs">Novidade</Badge>
|
|
560
|
+
<div
|
|
561
|
+
style="position: relative"
|
|
562
|
+
><Badge attached variant="info" appearance="solid">Tarefa pendente</Badge></div>
|
|
563
|
+
<Tag size="xs" appearance="soft" variant="primary" pill label="SEFIN" />
|
|
564
|
+
<Tag size="xs" appearance="soft" variant="new" pill label="Dado simulado" />
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
- dd0e159: feat(box): item flex (`grow`, `shrink`, `basis`...) e prop `as`
|
|
568
|
+
|
|
569
|
+
O `Box` ganha as props de item flex do `Stack` e a troca de elemento, com os
|
|
570
|
+
mesmos nomes e valores. Sem as props novas, o HTML e as classes são os mesmos.
|
|
571
|
+
|
|
572
|
+
- `as`: `div` (padrão), `span`, `ul`, `ol`, `li`, `section`, `nav`, `header`,
|
|
573
|
+
`footer`, `form`. `ul` e `ol` saem sem marcador, margem e recuo (o padding do
|
|
574
|
+
Box continua valendo) e com `role="list"`. Com `as="form"`, `onSubmit` recebe
|
|
575
|
+
o evento. Uma linha com borda e fundo dentro de uma lista é `<Box as="li">`.
|
|
576
|
+
- Item flex: `grow`, `shrink` (`"0"` | `"1"`), `basis` (`"auto"`, `"0"`, `"25"`,
|
|
577
|
+
`"33"`, `"50"`, `"66"`, `"75"`, `"100"`; os números são %), `minWidth` (`"0"`
|
|
578
|
+
| `"auto"`; o Box já nasce com `min-width: 0`), `overflow`, `overflowX`,
|
|
579
|
+
`overflowY` e `fullHeight` (o `fullWidth` já existia).
|
|
580
|
+
|
|
581
|
+
Vue: com `as`, o Box passa a ter raiz múltipla, e o Vue não repassa atributos
|
|
582
|
+
de fallthrough a esse tipo de componente. Por isso `class` entra no mesmo
|
|
583
|
+
repasse de `style`, `title`, `role`, `data-*` e `aria-*` (o `Stack` também). Ouvintes
|
|
584
|
+
(`@click`) não caem mais no raiz: ponha-os num filho.
|
|
585
|
+
|
|
586
|
+
```tsx
|
|
587
|
+
<Box direction="horizontal" gap="xxxs" padding="md">
|
|
588
|
+
<Box shrink="0" basis="25">Filtros</Box>
|
|
589
|
+
<Box grow overflowY="auto" fullHeight>Resultados</Box>
|
|
590
|
+
</Box>
|
|
591
|
+
<Box as="ul" aria-label="Setores"><Box as="li" bordered padding="xxxs">SADM</Box></Box>
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
- a6872d9: feat(box): `direction`, `gap`, `align`, `justify` e `wrap` (a caixa também é layout)
|
|
595
|
+
|
|
596
|
+
Uma linha, cartão ou região com borda, fundo e padding passa a ser UM componente,
|
|
597
|
+
sem `Stack` por dentro nem flex no CSS do produto. As cinco props têm os mesmos
|
|
598
|
+
nomes e valores do `Stack`; qualquer uma delas liga o `display: flex`. Sem
|
|
599
|
+
nenhuma, o `Box` segue sendo um bloco comum (API antiga intacta).
|
|
600
|
+
|
|
601
|
+
- `direction`: `"vertical"` (padrão quando o flex está ligado) | `"horizontal"`.
|
|
602
|
+
- `gap`: degraus da escala, mais `"none"`. Diferente do `Stack`, não tem valor
|
|
603
|
+
padrão: sem `gap` os filhos ficam colados.
|
|
604
|
+
- `align`, `justify`, `wrap`: como no `Stack`.
|
|
605
|
+
- Também passam a ir para o elemento raiz: `id`, `style`, `title`, `role`,
|
|
606
|
+
`tabIndex`, `data-*` e `aria-*` (uma região pede `role` e `aria-label`).
|
|
607
|
+
|
|
608
|
+
```tsx
|
|
609
|
+
<Box
|
|
610
|
+
direction="horizontal"
|
|
611
|
+
gap="xxxs"
|
|
612
|
+
align="center"
|
|
613
|
+
justify="between"
|
|
614
|
+
padding="xs"
|
|
615
|
+
background="surface"
|
|
616
|
+
radius="sm"
|
|
617
|
+
bordered
|
|
618
|
+
>
|
|
619
|
+
<Text variant="body2">
|
|
620
|
+
Reforma da cobertura do Ginásio Poliesportivo Municipal
|
|
621
|
+
</Text>
|
|
622
|
+
<Button variant="secondary" size="sm">
|
|
623
|
+
Abrir
|
|
624
|
+
</Button>
|
|
625
|
+
</Box>
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
Para o elemento semântico (`ul`, `nav`, `section`), continue usando `Stack` com `as`.
|
|
629
|
+
|
|
630
|
+
- d466e57: feat(button): variante `neutral-text` e tamanho `xs`
|
|
631
|
+
|
|
632
|
+
Para barra de ações (editor, filtros, linha de card), onde nenhum botão é a
|
|
633
|
+
ação principal e o azul atrapalha. Sem as props novas, nada muda.
|
|
634
|
+
|
|
635
|
+
- `variant="neutral-text"`: texto cinza (`neutral-dark-down`), sem borda e sem
|
|
636
|
+
fundo; hover em `neutral-light-medium`. O `neutral` continua sendo o
|
|
637
|
+
contornado cinza, então "neutro" cobre os dois: contornado (`neutral`) e
|
|
638
|
+
texto (`neutral-text`). O nome segue o par `negative` / `negative-outlined`.
|
|
639
|
+
- `size="xs"`: 26px de altura, padding lateral 12, fonte 12 e ícone de 12px
|
|
640
|
+
(também no `variant="icon"`, que fica 26 x 26). Os 26px do CrisDoc não estão
|
|
641
|
+
na escala de espaço, então a altura é `calc(spacing-xxs + spacing-micro)`
|
|
642
|
+
(24 + 2), sem token novo.
|
|
643
|
+
|
|
644
|
+
```vue
|
|
645
|
+
<Button
|
|
646
|
+
variant="neutral-text"
|
|
647
|
+
size="xs"
|
|
648
|
+
:start-icon="faPlus"
|
|
649
|
+
>Nova linha</Button>
|
|
650
|
+
<Button variant="neutral" size="xs">Ordenar: mais recentes</Button>
|
|
651
|
+
<Button size="xs">Resolver</Button>
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
- d278363: feat(calendar): novo `Calendar`, a agenda com eventos por dia
|
|
655
|
+
|
|
656
|
+
Peça nova: visão de mês e de semana, com eventos por dia, sem biblioteca de
|
|
657
|
+
datas (o `Intl` escreve os nomes de mês e de dia).
|
|
658
|
+
|
|
659
|
+
- `events`: lista plana `{ date, title, color?, time?, id? }`. `date` é
|
|
660
|
+
`YYYY-MM-DD`, data-hora ISO ou `Date`. A grade agrupa por dia e ordena por
|
|
661
|
+
`time`.
|
|
662
|
+
- Cor de DADO por token: `color="--umds-primitive-blue-pure"` (o mesmo valor do
|
|
663
|
+
`ColorPicker`), num chip de fundo suave (a cor a 16% sobre o branco) com barra
|
|
664
|
+
do lado. O texto é sempre escuro: a cor nunca é a única informação e o contraste
|
|
665
|
+
não depende do tom. Sem `color`, o primário.
|
|
666
|
+
- Mês: até `maxVisible` (3) eventos por dia e um "+N" (`onMoreClick(dia,
|
|
667
|
+
escondidos)`). O corte é por QUANTIDADE, não por altura. Semana: sete colunas
|
|
668
|
+
com todos os eventos.
|
|
669
|
+
- Grade acessível (`role="grid"`): um Tab entra no dia em foco (hoje, ou o
|
|
670
|
+
primeiro) e depois nos eventos dele; setas movem de dia (e trocam de mês ou de
|
|
671
|
+
semana na borda), Home e End vão às pontas da semana, PageUp e PageDown trocam
|
|
672
|
+
de mês (ou de semana), Enter e Espaço acionam `onDayClick`. Cada dia tem nome
|
|
673
|
+
("segunda-feira, 11 de maio de 2026, 2 eventos", `dayLabel` troca) e o de hoje
|
|
674
|
+
leva `aria-current="date"`.
|
|
675
|
+
- `date` e `view` controláveis (`onDateChange`, `onViewChange`) ou internos
|
|
676
|
+
(`defaultDate`, `defaultView`); `selectedDate` marca um dia; `today` fixa o
|
|
677
|
+
"hoje" (testes, demonstração); `weekStartsOn` 0 (domingo) ou 1.
|
|
678
|
+
- Cabeçalho com anterior, próximo, "Hoje" e o seletor Mês/Semana
|
|
679
|
+
(`hideViewSwitcher` esconde), mais dois slots: `headerStart` (filtro de escopo)
|
|
680
|
+
e `headerEnd` (legenda). No Vue são `#header-start` e `#header-end`.
|
|
681
|
+
- Textos por prop: `previousLabel`, `nextLabel`, `todayLabel`, `monthLabel`,
|
|
682
|
+
`weekLabel`, `viewLabel`, `moreLabel` (`{count}`), `moreAriaLabel` (`{count}` e
|
|
683
|
+
`{date}`); `locale` (padrão `pt-BR`).
|
|
684
|
+
|
|
685
|
+
Não faz: eixo de horas (é agenda por dia, não por hora), evento que atravessa
|
|
686
|
+
vários dias e arrastar para reagendar.
|
|
687
|
+
|
|
688
|
+
```vue
|
|
689
|
+
<Calendar
|
|
690
|
+
:events="[
|
|
691
|
+
{
|
|
692
|
+
date: '2026-05-04',
|
|
693
|
+
title: 'Proc. Administrativo 002/2020',
|
|
694
|
+
color: '--umds-primitive-blue-pure',
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
date: '2026-05-11',
|
|
698
|
+
title: 'Ofício 001/2020',
|
|
699
|
+
color: '--umds-primitive-red-pure',
|
|
700
|
+
time: '08:00',
|
|
701
|
+
},
|
|
702
|
+
]"
|
|
703
|
+
:onEventClick="abrir"
|
|
704
|
+
>
|
|
705
|
+
<template #header-start><Select … /></template>
|
|
706
|
+
<template #header-end><Button variant="secondary" size="sm">Legenda</Button></template>
|
|
707
|
+
</Calendar>
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
- 33719b6: feat(chips): `size="xs"` e × com moldura circular (`circularRemove`)
|
|
711
|
+
|
|
712
|
+
Opt-in; sem as props novas o `Chips` é o mesmo.
|
|
713
|
+
|
|
714
|
+
- `size="xs"`: 20px de altura, padding lateral 8, fonte de 12px e × de 8px. A
|
|
715
|
+
altura é `calc(spacing-xxxs + spacing-quarck)` (16 + 4), sem token novo. O
|
|
716
|
+
CrisDoc usa fonte de 11px, que não está na escala do DS; fica o degrau de 12px.
|
|
717
|
+
- `circularRemove`: o × dos chips removíveis vai dentro de um círculo de 14px
|
|
718
|
+
tingido da cor do texto do chip (o `::before` usa `currentColor` com 15% de
|
|
719
|
+
opacidade, então acompanha todas as variantes e os temas). É o mesmo botão,
|
|
720
|
+
com o mesmo nome acessível ("Remover <rótulo>") e o mesmo clique; só vale com
|
|
721
|
+
`removable`.
|
|
722
|
+
|
|
723
|
+
```vue
|
|
724
|
+
<Chips
|
|
725
|
+
label="Processos Inteligentes"
|
|
726
|
+
size="xs"
|
|
727
|
+
variant="primary"
|
|
728
|
+
removable
|
|
729
|
+
circularRemove
|
|
730
|
+
:onRemove="remover"
|
|
731
|
+
/>
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
- 80904af: feat(coachmark): novo `Coachmark`, o tour guiado
|
|
735
|
+
|
|
736
|
+
Peça nova: uma sequência de passos, cada um apontando um elemento da tela com
|
|
737
|
+
um cartão, enquanto o resto da página escurece e o alvo fica destacado num
|
|
738
|
+
recorte (uma caixa transparente cuja sombra escurece o resto, sem máscara nem
|
|
739
|
+
SVG).
|
|
740
|
+
|
|
741
|
+
- `steps`: `{ target?, title, content?, placement? }`. `target` é um seletor CSS
|
|
742
|
+
(`"#aba-fluxos"`), um elemento, uma ref do React (`{ current }`), uma ref do Vue
|
|
743
|
+
(`{ value }`) ou uma função que devolve um deles. Sem alvo (ou alvo que não
|
|
744
|
+
existe), o cartão fica no centro e a página inteira escurece.
|
|
745
|
+
- Posição por `@floating-ui/dom` (já era dependência): `placement` com inversão
|
|
746
|
+
automática, e o recorte e o cartão acompanham rolagem, redimensionamento e
|
|
747
|
+
mudança de tamanho do alvo. O alvo é trazido à tela se estiver fora dela.
|
|
748
|
+
- Controlado por `open`; `onClose(motivo)` com `"finish"` (Concluir no último
|
|
749
|
+
passo), `"skip"` (Sair do tour) ou `"escape"` (Esc). Passo atual interno
|
|
750
|
+
(`defaultStep`) ou controlado (`step` + `onStepChange`). Reabrir recomeça do
|
|
751
|
+
primeiro passo.
|
|
752
|
+
- Acessibilidade: cartão `role="dialog"` com `aria-modal`, nomeado pelo título e
|
|
753
|
+
descrito pelo texto. O foco entra no cartão, o Tab fica preso nele, Esc sai,
|
|
754
|
+
setas esquerda e direita voltam e avançam, e o foco volta ao elemento de antes
|
|
755
|
+
ao fechar. A cada passo o leitor de tela ouve "2 de 8: título" (`aria-live`).
|
|
756
|
+
- Textos por prop: `nextLabel`, `previousLabel`, `finishLabel`, `skipLabel`,
|
|
757
|
+
`counterLabel` ("{current} de {total}"). `hideSkip` esconde o Sair do tour.
|
|
758
|
+
- `padding` (px) é a folga do recorte em torno do alvo (padrão 8).
|
|
759
|
+
|
|
760
|
+
Limite: a página atrás fica inerte durante o tour (o véu captura o clique), então
|
|
761
|
+
o alvo não é clicável. O scrim usa o mesmo `rgba` do Modal, que ainda não tem
|
|
762
|
+
token (candidato a novo token).
|
|
763
|
+
|
|
764
|
+
```vue
|
|
765
|
+
<Coachmark
|
|
766
|
+
:open="tourAberto"
|
|
767
|
+
:steps="[
|
|
768
|
+
{
|
|
769
|
+
target: '#aba-fluxos',
|
|
770
|
+
title: 'Cada item aberto é uma aba',
|
|
771
|
+
content: 'Fluxos e formulários abrem em abas.',
|
|
772
|
+
},
|
|
773
|
+
{ title: 'Pronto', content: 'Sem alvo: o cartão fica no centro.' },
|
|
774
|
+
]"
|
|
775
|
+
:onClose="() => (tourAberto = false)"
|
|
776
|
+
/>
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
- 390c707: feat(colorpicker): novo `ColorPicker`, as amostras da paleta do 1DS
|
|
780
|
+
|
|
781
|
+
Peça nova. Uma grade de amostras dos primitivos de cor (6 famílias de 4 tons e os
|
|
782
|
+
7 cinzas, 31 no total), uma linha por família. O valor é o NOME DO TOKEN
|
|
783
|
+
(`--umds-primitive-blue-pure`): guarde o nome e pinte com `var(${valor})`. Como
|
|
784
|
+
primitivo não muda com o tema, a cor escolhida é a mesma no claro e no escuro, o
|
|
785
|
+
que é o certo para cor de dado (marcador, tipo de documento, setor).
|
|
786
|
+
|
|
787
|
+
- `radiogroup`: Tab entra na amostra escolhida (ou na primeira), setas movem a
|
|
788
|
+
escolha, Home e End vão às pontas, amostra desabilitada é pulada. Cada amostra
|
|
789
|
+
tem nome acessível ("Azul escuro") e a escolhida ganha ícone de marcação e anel
|
|
790
|
+
duplo, então a seleção não depende só da cor.
|
|
791
|
+
- `value` / `defaultValue` / `onChange(valor)`; `label` ou `ariaLabel`.
|
|
792
|
+
- `allowCustom` (desligado por padrão): campo de cor livre em hexadecimal
|
|
793
|
+
`#RRGGBB`, que sai em maiúsculas. Textos por prop: `customLabel` e
|
|
794
|
+
`customErrorMessage`.
|
|
795
|
+
- `families` recorta a paleta (`["blue", "gray"]`); `swatches` troca a lista
|
|
796
|
+
inteira (nomes traduzidos, recorte livre). `COLOR_PALETTE` e `isHexColor` saem
|
|
797
|
+
exportados.
|
|
798
|
+
- `size` `sm` (24px) ou `md` (32px, padrão); raio 8px, anel de 1px na amostra.
|
|
799
|
+
|
|
800
|
+
Requer `@1doc/1ds-tokens` com `yellow-light` e `purple-pure` corrigidos (ver o
|
|
801
|
+
changeset `tokens-primitivos-amarelo-roxo`): a paleta lista os 31 primitivos, e
|
|
802
|
+
com o tokens 0.4.3 essas duas amostras saem na cor errada.
|
|
803
|
+
|
|
804
|
+
```vue
|
|
805
|
+
<ColorPicker
|
|
806
|
+
label="Cor do marcador"
|
|
807
|
+
:value="cor"
|
|
808
|
+
:onChange="(c) => (cor = c)"
|
|
809
|
+
allowCustom
|
|
810
|
+
/>
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
- e3d82fc: feat(datatable): célula livre por coluna, linha de grupo e tipos exportados no Vue
|
|
814
|
+
|
|
815
|
+
A `DataTable` passa a aceitar markup na célula nos dois frameworks. API antiga
|
|
816
|
+
intacta: sem as props e slots novos, o HTML e as classes são os mesmos.
|
|
817
|
+
|
|
818
|
+
- Célula livre. No React, `column.render(row, rowIndex)` já devolvia nó e
|
|
819
|
+
continua assim (o docblock agora diz). No Vue, o retorno do `render` continua
|
|
820
|
+
sendo tratado como texto, e a célula com markup vem do slot `#cell-<key>`,
|
|
821
|
+
que recebe `{ row, value, rowIndex }`. Com `render` e slot na mesma coluna, o
|
|
822
|
+
slot vale.
|
|
823
|
+
- Linha de grupo: `rowGroup` (nome do campo ou função `(row, rowIndex) =>
|
|
824
|
+
rótulo`) abre um `<th scope="rowgroup">` que atravessa a tabela antes de cada
|
|
825
|
+
sequência de linhas com o mesmo rótulo. A tabela não reordena: passe `data` já
|
|
826
|
+
ordenada pelo grupo. O conteúdo do grupo é o rótulo, ou `renderRowGroup(label,
|
|
827
|
+
row, rowIndex)` no React, ou o slot `#row-group` (`{ label, row, rowIndex }`)
|
|
828
|
+
no Vue. A linha de grupo não entra na seleção nem no `onRowClick`.
|
|
829
|
+
- Vue (tipos): o `index.d.ts` do pacote passa a trazer todo tipo exportado pelos
|
|
830
|
+
componentes. Antes só saíam as `*Props`, `*Action` e `*Option`, e a `DataTableProps`
|
|
831
|
+
apontava para um `DataTableColumn` que não existia no arquivo. Agora
|
|
832
|
+
`DataTableColumn`, `DropdownItem`, `AccordionItemData` (e os demais, como
|
|
833
|
+
`StackSpacing`, `BoxSpacing` e `ChartDatum`) podem ser importados de
|
|
834
|
+
`@1doc/1ds-vue`. No React eles já eram exportados.
|
|
835
|
+
|
|
836
|
+
```vue
|
|
837
|
+
<DataTable :columns="colunas" :data="usuarios" rowGroup="setor">
|
|
838
|
+
<template #cell-nome="{ row }">
|
|
839
|
+
<Avatar type="letter" size="sm">{{ row.nome[0] }}</Avatar> {{ row.nome }}
|
|
840
|
+
</template>
|
|
841
|
+
<template #cell-setores="{ value }">
|
|
842
|
+
<Tag v-for="setor in value" :key="setor" :label="setor" size="sm" />
|
|
843
|
+
</template>
|
|
844
|
+
<template #row-group="{ label }">Setor {{ label }}</template>
|
|
845
|
+
</DataTable>
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
- a5fe6fe: feat(datatable,descriptionlist): `DataTable variant="document"` e novo `DescriptionList`
|
|
849
|
+
|
|
850
|
+
Para o que é CONTEÚDO de documento (se lê e se imprime), não interface.
|
|
851
|
+
|
|
852
|
+
**`DataTable variant="document"`** (padrão `default`, nada muda sem a prop):
|
|
853
|
+
tabela sem interação, com grade de bordas finas em todas as células, sem hover,
|
|
854
|
+
sem cabeçalho grudado e sem raio. `sortable`, `selectable` e `onRowClick` são
|
|
855
|
+
ignorados: sem botão de ordenar, sem `aria-sort`, sem checkbox, linha fora da
|
|
856
|
+
ordem de Tab. Na impressão (`@media print`) o cabeçalho se repete a cada página,
|
|
857
|
+
uma linha nunca é cortada ao meio e as cores saem (`print-color-adjust`).
|
|
858
|
+
`columns`, `data`, `align`, `width`, `render`/`#cell-<key>` e `density` valem
|
|
859
|
+
como sempre.
|
|
860
|
+
|
|
861
|
+
**`DescriptionList`**, para os pares rótulo/valor (o `DocPares` do CrisDoc não
|
|
862
|
+
cabia na tabela: não tem cabeçalho de coluna). `<dl>` com `<dt>` e `<dd>`:
|
|
863
|
+
|
|
864
|
+
- `items`: `{ label, value, id? }`. Valor vazio mostra "—" (`emptyValue`).
|
|
865
|
+
- `layout="inline"` (padrão): grade de bordas finas, rótulo pintado e sem quebra
|
|
866
|
+
à esquerda, valor à direita; `fit` encolhe até o conteúdo.
|
|
867
|
+
- `layout="stacked"`: rótulo pequeno em cima, valor embaixo, `columns` de 1 a 4
|
|
868
|
+
(vira 1 em tela estreita); `bordered` põe o valor na caixa de um campo
|
|
869
|
+
somente leitura.
|
|
870
|
+
- `ariaLabel` ou `ariaLabelledby`. No Vue o `value` é texto (valor com marcação:
|
|
871
|
+
monte com `Stack` e `Text`).
|
|
872
|
+
|
|
873
|
+
```vue
|
|
874
|
+
<DataTable variant="document" :columns="colunas" :data="itens" />
|
|
875
|
+
<DescriptionList
|
|
876
|
+
ariaLabel="Dados de empenho"
|
|
877
|
+
:items="[
|
|
878
|
+
{ label: 'Empenho', value: '2026NE000184' },
|
|
879
|
+
{ label: 'Valor empenhado', value: 'R$ 51.840,00' },
|
|
880
|
+
]"
|
|
881
|
+
/>
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
- 801c5c2: feat(fileinput): `variant="trigger"`, o seletor aberto por outro controle
|
|
885
|
+
|
|
886
|
+
Para o "Anexar arquivo" de um botão ou o "Alterar foto" de um link, sem a caixa
|
|
887
|
+
de arrastar. Opt-in; `base` e `card` não mudam.
|
|
888
|
+
|
|
889
|
+
- `variant="trigger"`: o conteúdo que você passa (React: `children`; Vue: slot
|
|
890
|
+
padrão) é o gatilho. O clique nele abre o seletor (o clique sobe até o
|
|
891
|
+
envoltório, então o Enter num `Button` também funciona), e `accept`,
|
|
892
|
+
`multiple`, `name`, `files`, `onChange` e `onRemove` funcionam igual. O input
|
|
893
|
+
nativo fica oculto ao lado, fora do Tab (o gatilho é quem recebe o foco) e
|
|
894
|
+
com nome acessível (`label` ou `selectFileLabel`). `disabled` não abre.
|
|
895
|
+
- O `label` visível não aparece no `trigger`: o gatilho é o próprio conteúdo; o
|
|
896
|
+
`label` serve de nome acessível do input.
|
|
897
|
+
- Não há `open()` exposto: o Mitosis não tem como expor método imperativo nos
|
|
898
|
+
dois frameworks. O `trigger` cobre o caso (botão ou link que abre o seletor).
|
|
899
|
+
|
|
900
|
+
```vue
|
|
901
|
+
<FileInput
|
|
902
|
+
variant="trigger"
|
|
903
|
+
accept=".pdf,.docx"
|
|
904
|
+
:multiple="true"
|
|
905
|
+
:onChange="anexar"
|
|
906
|
+
>
|
|
907
|
+
<Button variant="secondary" startIcon="paperclip">Anexar arquivo</Button>
|
|
908
|
+
</FileInput>
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
- 0e89b88: feat(iconpicker): novo `IconPicker`, a grade de ícones com busca
|
|
912
|
+
|
|
913
|
+
Peça nova, sem dependência: os ícones vêm por prop.
|
|
914
|
+
|
|
915
|
+
- `icons`: objetos do Font Awesome importados (`faUser`, `faFolder`...), ou
|
|
916
|
+
`{ icon, label?, keywords? }` quando o nome ou a busca precisam de ajuda. O nome
|
|
917
|
+
de um ícone sem `label` é o `iconName` sem hífen ("file lines"); `iconLabel`
|
|
918
|
+
traduz.
|
|
919
|
+
- O valor é o NOME do ícone (`"user"`, `"file-lines"`): `value`/`defaultValue`,
|
|
920
|
+
`onChange(nome, item)`. Guarde o nome e resolva de volta para o objeto na hora de
|
|
921
|
+
desenhar.
|
|
922
|
+
- `radiogroup`: Tab entra no ícone escolhido (ou no primeiro); setas movem a
|
|
923
|
+
escolha (esquerda e direita um ícone, cima e baixo uma linha: `columns`, padrão
|
|
924
|
+
8), Home e End vão às pontas. O escolhido ganha fundo e borda do primário e
|
|
925
|
+
`aria-checked`.
|
|
926
|
+
- Busca (ligada; `hideSearch` esconde) por nome, rótulo e palavras-chave, sem
|
|
927
|
+
acento nem caixa. A seta para baixo no campo leva à grade, e o número de
|
|
928
|
+
resultados é anunciado (`role="status"`). Sem resultado, mostra `emptyText`.
|
|
929
|
+
- `maxHeight` (px) limita a grade e rola dentro dela; `size` `sm` ou `md`;
|
|
930
|
+
`disabled`.
|
|
931
|
+
- Textos por prop: `searchLabel`, `searchPlaceholder`, `emptyText`, `resultsLabel`
|
|
932
|
+
(`{count}`).
|
|
933
|
+
|
|
934
|
+
```vue
|
|
935
|
+
<IconPicker
|
|
936
|
+
label="Ícone da categoria"
|
|
937
|
+
:icons="[
|
|
938
|
+
faFolder,
|
|
939
|
+
faFileLines,
|
|
940
|
+
{ icon: faBuilding, label: 'Órgão', keywords: ['prefeitura'] },
|
|
941
|
+
]"
|
|
942
|
+
:value="icone"
|
|
943
|
+
:onChange="(nome) => (icone = nome)"
|
|
944
|
+
/>
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
- 4d0cb08: feat(input): `onChange` a cada tecla no Vue, `mask`, `iconRight` e `borderless`
|
|
948
|
+
|
|
949
|
+
- **`onChange` a cada tecla no Vue (paridade com o React).** O campo passa a
|
|
950
|
+
escutar `input` além de `change`. Antes, no Vue, `onChange` só disparava quando
|
|
951
|
+
o campo perdia o foco (o evento `change` nativo). Os dois eventos entram no
|
|
952
|
+
mesmo tratador, que descarta o repetido: no React os dois disparam para o
|
|
953
|
+
mesmo evento nativo, e no Vue o `change` do blur repete o valor que o `input`
|
|
954
|
+
da última tecla já entregou. O resultado é uma chamada por tecla nos dois
|
|
955
|
+
frameworks. Um `change` disparado à mão com valor novo (testes de quem
|
|
956
|
+
consome) também chega. `onBlur` segue sendo o evento de saída do campo.
|
|
957
|
+
Quem contornava o blur no Vue com `@input` por fora pode tirar o contorno.
|
|
958
|
+
- `mask`: `"cpf"`, `"cnpj"`, `"cep"` ou `"phone"` (10 ou 11 dígitos). O valor
|
|
959
|
+
exibido e o que chega em `onChange` já vêm formatados; para só os dígitos,
|
|
960
|
+
`valor.replace(/\D/g, "")`. Aceita só dígitos, limita o tamanho (`maxlength`) e
|
|
961
|
+
abre o teclado numérico no celular (`inputmode="numeric"`). Valor controlado
|
|
962
|
+
só com dígitos também aparece formatado. Cursor: reformatar no meio do texto
|
|
963
|
+
leva o cursor ao fim (suficiente para digitar do início ao fim).
|
|
964
|
+
- `iconRight`: ícone decorativo à direita, `aria-hidden`, sem clique. Para ação,
|
|
965
|
+
continua `iconsRight`.
|
|
966
|
+
- `borderless`: sem borda, fundo e raio, para o campo dentro de um grupo que já
|
|
967
|
+
tem a moldura (um `Select` e um `Input` lado a lado numa caixa). O foco não
|
|
968
|
+
some: vira contorno de 2px para dentro. Com erro, a borda vermelha fica.
|
|
969
|
+
|
|
970
|
+
```vue
|
|
971
|
+
<Input label="CPF" mask="cpf" :onChange="(v) => (cpf = v)" />
|
|
972
|
+
<Input
|
|
973
|
+
ariaLabel="Número"
|
|
974
|
+
placeholder="Número"
|
|
975
|
+
borderless
|
|
976
|
+
fullWidth
|
|
977
|
+
iconRight="search"
|
|
978
|
+
/>
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
- cfb8c4a: feat(kbd,codeblock): novos `Kbd` e `CodeBlock`, e o token de fonte monoespaçada
|
|
982
|
+
|
|
983
|
+
**Token novo** (`@1doc/1ds-tokens`): `--umds-primitive-font-family-mono` e o
|
|
984
|
+
semântico `--umds-semantic-font-family-mono` (`ui-monospace, SFMono-Regular,
|
|
985
|
+
Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema:
|
|
986
|
+
nenhuma fonte baixada, então nenhum pedido de rede novo. O produto cita o
|
|
987
|
+
semântico; os dois componentes abaixo já o usam.
|
|
988
|
+
|
|
989
|
+
**`Kbd`**: uma tecla ou uma combinação, em `<kbd>`.
|
|
990
|
+
|
|
991
|
+
- Uma tecla vai como conteúdo (`<Kbd>Esc</Kbd>`); uma combinação em `keys`
|
|
992
|
+
(`["Ctrl", "Shift", "P"]`), com `separator` entre as teclas (padrão `+`). Cada
|
|
993
|
+
tecla é um `<kbd>` dentro do `<kbd>` do conjunto, que é como o HTML diz
|
|
994
|
+
"combinação". O leitor de tela lê "Ctrl + Shift + P".
|
|
995
|
+
- Caixa cinza com borda e base mais grossa, fonte monoespaçada; `size` `sm` ou
|
|
996
|
+
`md`. Raiz única: `title`, `data-*`, `aria-*` e ouvintes chegam ao elemento.
|
|
997
|
+
|
|
998
|
+
**`CodeBlock`**: trecho de código, JSON ou log, com borda, rolagem e cópia.
|
|
999
|
+
|
|
1000
|
+
- O texto vem por `code` ou como conteúdo, com espaços e quebras mantidos. Linha
|
|
1001
|
+
longa rola na horizontal, ou quebra com `wrap`; `maxHeight` (px) limita a
|
|
1002
|
+
altura e rola na vertical.
|
|
1003
|
+
- A área de rolagem é `role="region"` focável (Tab) e nomeada (`ariaLabel`, senão
|
|
1004
|
+
a `language`, senão "Código"): quem usa o teclado consegue rolar.
|
|
1005
|
+
- `copyable` mostra o botão de copiar no cabeçalho: copia o texto inteiro (não só
|
|
1006
|
+
o que está à vista), troca para "Copiado" por dois segundos e anuncia ao leitor
|
|
1007
|
+
de tela. Usa `navigator.clipboard`, e recorre a `execCommand("copy")` quando ele falha.
|
|
1008
|
+
`onCopy(texto)` avisa. `copyLabel` e `copiedLabel` por prop.
|
|
1009
|
+
- `language` é só rótulo no topo. Não colore sintaxe (pede uma biblioteca); fundo
|
|
1010
|
+
claro e texto escuro nos dois temas.
|
|
1011
|
+
|
|
1012
|
+
```vue
|
|
1013
|
+
<Kbd :keys="['Ctrl', 'K']" size="sm" />
|
|
1014
|
+
<CodeBlock language="JSON" :code="envio" copyable />
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
- fcd9c32: feat(list): estado vazio dentro da lista (`isEmpty`)
|
|
1018
|
+
|
|
1019
|
+
O `List` passa a trazer o estado vazio. Com `isEmpty`, as linhas dão lugar a um
|
|
1020
|
+
`EmptyState` DENTRO da lista: o título do cartão, a busca, os filtros e a
|
|
1021
|
+
paginação ao redor continuam montados (e o foco no campo de busca não se perde),
|
|
1022
|
+
porque só o miolo troca. A lista não conta filhos: `isEmpty` é a decisão de
|
|
1023
|
+
quem a usa (`:is-empty="!itens.length"`).
|
|
1024
|
+
|
|
1025
|
+
- Texto: `emptyTitle` (padrão "Nenhum item encontrado"), `emptyDescription`,
|
|
1026
|
+
`emptyIcon` (objeto do Font Awesome), `emptySize` (`sm` padrão, `md`, `lg`).
|
|
1027
|
+
- Ação: `emptyActionLabel` com `onEmptyAction`. Sem o callback o botão não
|
|
1028
|
+
aparece.
|
|
1029
|
+
- Conteúdo próprio: slot `empty` (no React, a prop `empty`) no lugar do
|
|
1030
|
+
`EmptyState`.
|
|
1031
|
+
- Acessibilidade: o bloco vazio é `role="status"`, então a lista esvaziar é
|
|
1032
|
+
anunciada. Sem itens não há `ul` vazia no DOM.
|
|
1033
|
+
|
|
1034
|
+
```vue
|
|
1035
|
+
<List
|
|
1036
|
+
ariaLabelledby="titulo"
|
|
1037
|
+
:isEmpty="!docs.length"
|
|
1038
|
+
emptyTitle="Nenhum documento"
|
|
1039
|
+
emptyDescription="Tudo em dia."
|
|
1040
|
+
:emptyIcon="faInbox"
|
|
1041
|
+
emptyActionLabel="Atualizar"
|
|
1042
|
+
@emptyAction="recarregar"
|
|
1043
|
+
>
|
|
1044
|
+
<ListItem v-for="d in docs" :key="d.id" :title="d.titulo" />
|
|
1045
|
+
</List>
|
|
1046
|
+
```
|
|
1047
|
+
|
|
1048
|
+
- 4b57ca7: feat(list): novos `ListItem` e `List`, a linha de lista inteira clicável
|
|
1049
|
+
|
|
1050
|
+
Peça nova. O `ListItem` é a linha cujo alvo de clique e de foco é a linha
|
|
1051
|
+
toda, com conteúdo livre. Renderiza um `<li>` com UM `button`, `a` ou `div`
|
|
1052
|
+
dentro, por isso vive num `List` (ou num `ul`/`ol`, como `Stack as="ul"`).
|
|
1053
|
+
|
|
1054
|
+
- `as`: `button` | `a` | `div`. Sem `as`, vira `a` quando há `href` e `button`
|
|
1055
|
+
nos outros casos. `div` é a linha que só mostra; com `onClick` ganha
|
|
1056
|
+
role="button", tabindex 0, Enter e Espaço. `target="_blank"` põe
|
|
1057
|
+
`rel="noopener noreferrer"` sozinho.
|
|
1058
|
+
- Conteúdo: `start`, `title`, `subtitle`, `meta`, `end` e o conteúdo padrão (abaixo
|
|
1059
|
+
de `meta`). `title`, `subtitle` e `meta` aceitam texto por prop ou nó por slot.
|
|
1060
|
+
No Vue os slots se chamam igual (`#start`, `#title`...); no React são as
|
|
1061
|
+
props. Região vazia não desenha nada.
|
|
1062
|
+
- Estados: hover e foco visível (anel interno), `selected` (fundo de seleção e
|
|
1063
|
+
`aria-current="true"`), `disabled` (button desabilitado; link perde o `href` e
|
|
1064
|
+
ganha `aria-disabled`).
|
|
1065
|
+
- `id`, `style`, `role`, `tabIndex`, `data-*` e `aria-*` vão para o elemento
|
|
1066
|
+
interativo (é nele que entra o `aria-label`). `title` é o título da linha, não
|
|
1067
|
+
o atributo HTML.
|
|
1068
|
+
- `List`: `ul` (padrão) ou `ol`, sempre com `role="list"` (o Safari tira a
|
|
1069
|
+
semântica de `list-style: none`), `gap` na escala do DS (padrão `quarck`),
|
|
1070
|
+
`ariaLabel` ou `ariaLabelledby`.
|
|
1071
|
+
|
|
1072
|
+
Medidas: padding 8 12 (o 10 12 do CrisDoc não existe na escala), raio 8, título
|
|
1073
|
+
14/600, subtítulo 14 e meta 12, todos pelo `Text`.
|
|
1074
|
+
|
|
1075
|
+
```vue
|
|
1076
|
+
<List ariaLabel="Documentos não lidos" gap="nano">
|
|
1077
|
+
<ListItem selected title="Memorando 114/2025" subtitle="Novo contrato - Governo"
|
|
1078
|
+
meta="23 de agosto de 2025" @click="abrir(doc)">
|
|
1079
|
+
<template #start><Avatar type="letter" size="sm">I</Avatar></template>
|
|
1080
|
+
<template #end><Badge variant="info" size="sm">novo</Badge></template>
|
|
1081
|
+
</ListItem>
|
|
1082
|
+
</List>
|
|
1083
|
+
```
|
|
1084
|
+
|
|
1085
|
+
- eeb6a16: feat(modal): `variant="primary"`, `width`/`maxWidth`, `windowControls` em lista e `responsive`; o Esc respeita quem já o usou
|
|
1086
|
+
|
|
1087
|
+
Tudo opt-in; sem as props novas o modal é o mesmo.
|
|
1088
|
+
|
|
1089
|
+
- `variant="primary"`: cabeçalho cheio na cor primária (título, subtítulo e
|
|
1090
|
+
controles em `neutral-light-pure`, hover em `primary-dark`). É o modal base com
|
|
1091
|
+
as três faixas, não o diálogo de feedback.
|
|
1092
|
+
- `width` e `maxWidth`: qualquer valor CSS. `width` sozinho solta o teto do
|
|
1093
|
+
`size` (o 498px do `md` não segura mais) e passa a ser limitado pela tela.
|
|
1094
|
+
Com `windowControls`, valem só no modo normal.
|
|
1095
|
+
- `windowControls` aceita `true` (o conjunto inteiro, como antes) ou uma lista
|
|
1096
|
+
com os controles que quiser: `["expand", "fullscreen"]`. Nomes: `normal`,
|
|
1097
|
+
`expand`, `fullscreen`, `minimize`. Em lista, sem `normal`, clicar de novo no
|
|
1098
|
+
modo ativo volta ao normal, e o modo normal usa o tamanho do próprio modal
|
|
1099
|
+
(não os 780px do conjunto inteiro). O divisor só aparece com algum controle e
|
|
1100
|
+
com o ×. `onMinimize` só existe se `minimize` estiver na lista.
|
|
1101
|
+
- `responsive` e `responsiveBreakpoint` (padrão 640, lido na montagem): abaixo
|
|
1102
|
+
da largura, o modal vira um painel que sobe pela borda de baixo (largura
|
|
1103
|
+
total, cantos de cima arredondados, alça, entrada por baixo), como o
|
|
1104
|
+
`BottomSheet`; acima, continua centralizado. É o mesmo componente reorganizado
|
|
1105
|
+
(não monta um `BottomSheet` por dentro, porque o Mitosis não repassa slot de
|
|
1106
|
+
um componente a outro), então não tem o gesto de arrastar. No painel os
|
|
1107
|
+
controles de janela e a largura livre somem.
|
|
1108
|
+
- Esc: o ouvinte do `document` passa a rodar no borbulho e a ignorar a tecla se
|
|
1109
|
+
`defaultPrevented`. `Select`, `Combobox`, `Popover` e `Dropdown` já faziam
|
|
1110
|
+
`preventDefault`; `DatePicker` e `MultiSelect` passaram a fazer. Resultado: um
|
|
1111
|
+
`Select` ou `DatePicker` aberto dentro do modal fecha só a lista, e o modal
|
|
1112
|
+
fica. Quem tinha contorno para isso pode tirá-lo.
|
|
1113
|
+
|
|
1114
|
+
```vue
|
|
1115
|
+
<Modal
|
|
1116
|
+
open
|
|
1117
|
+
variant="primary"
|
|
1118
|
+
width="600px"
|
|
1119
|
+
:window-controls="['expand', 'fullscreen']"
|
|
1120
|
+
title="Verificar rotas e quilometragem"
|
|
1121
|
+
responsive
|
|
1122
|
+
>
|
|
1123
|
+
...
|
|
1124
|
+
</Modal>
|
|
1125
|
+
```
|
|
1126
|
+
|
|
1127
|
+
- 56229f0: feat(orgchart): novo `OrgChart`, o organograma com conectores
|
|
1128
|
+
|
|
1129
|
+
Peça nova: uma árvore desenhada de cima para baixo, com linhas ligando cada pai
|
|
1130
|
+
aos filhos, em que os nós com filhos expandem e recolhem. Sem dependência.
|
|
1131
|
+
|
|
1132
|
+
- `nodes`: lista de nós raiz `{ id, title, subtitle?, children? }`. Mais de uma
|
|
1133
|
+
raiz funciona (floresta).
|
|
1134
|
+
- O desenho é calculado, não aninhado (o Mitosis não gera componente recursivo de
|
|
1135
|
+
forma confiável): cada nó tem largura e altura fixas (`nodeWidth` 176,
|
|
1136
|
+
`nodeHeight` 64, em px), os filhos se distribuem sob o pai (`gapX` 16) e o pai se
|
|
1137
|
+
centra sobre eles; um nível desce `gapY` (40). Os conectores são um SVG de uma
|
|
1138
|
+
linha por pai. O container rola quando o organograma passa da largura.
|
|
1139
|
+
- Visual: a raiz cheia na cor primária, os demais em tom claro; `selectedId` marca
|
|
1140
|
+
um nó. O título e o subtítulo cortam com reticências (o texto inteiro vai no
|
|
1141
|
+
tooltip).
|
|
1142
|
+
- Conteúdo livre do nó: no React `renderNode(nó, { level, expanded })`; no Vue o
|
|
1143
|
+
slot `node` com escopo `{ node, level, expanded }` (ligado no `postbuild.js`,
|
|
1144
|
+
como o do `DataTable`). O conteúdo precisa caber na caixa do nó.
|
|
1145
|
+
- Expandir e recolher: tudo aberto por padrão; `defaultCollapsedIds` (ou
|
|
1146
|
+
`collapsedIds` controlado) escolhe o que começa recolhido, e
|
|
1147
|
+
`onCollapsedChange(ids)` avisa. O botão +/− no pé do nó é para o mouse.
|
|
1148
|
+
- Acessibilidade: `role="tree"` com nós `treeitem` (`aria-level`,
|
|
1149
|
+
`aria-posinset`, `aria-setsize`, `aria-expanded`, `aria-selected`). Um Tab entra
|
|
1150
|
+
no nó em foco; Baixo vai ao primeiro filho (e abre o nó, se recolhido), Cima ao
|
|
1151
|
+
pai, Esquerda e Direita aos irmãos, Home e End ao primeiro e ao último irmão,
|
|
1152
|
+
Espaço expande ou recolhe, Enter aciona `onNodeClick`.
|
|
1153
|
+
- Textos por prop: `ariaLabel` ("Organograma"), `expandLabel`, `collapseLabel`.
|
|
1154
|
+
|
|
1155
|
+
Limites do primeiro corte: só de cima para baixo; sem zoom nem arrastar; nó de
|
|
1156
|
+
altura variável não cabe (use `nodeHeight` para o maior). Para navegar e escolher
|
|
1157
|
+
em hierarquias grandes, o `Tree` é mais denso e acessível.
|
|
1158
|
+
|
|
1159
|
+
```vue
|
|
1160
|
+
<OrgChart :nodes="setores" ariaLabel="Setores da COPIRN" :onNodeClick="abrir">
|
|
1161
|
+
<template #node="{ node }"><Avatar size="sm">{{ node.title }}</Avatar></template>
|
|
1162
|
+
</OrgChart>
|
|
1163
|
+
```
|
|
1164
|
+
|
|
1165
|
+
- e8453bc: feat(otpinput): novo `OtpInput`, o código de verificação em caixas
|
|
1166
|
+
|
|
1167
|
+
Peça nova para códigos curtos recebidos por outro canal (autenticação em duas
|
|
1168
|
+
etapas, confirmação de e-mail ou telefone).
|
|
1169
|
+
|
|
1170
|
+
- `length` caixas (6 por padrão). Digitar avança o foco; Backspace apaga e, em
|
|
1171
|
+
caixa vazia, volta e apaga a anterior; setas, Home e End movem.
|
|
1172
|
+
- Colar o código inteiro em qualquer caixa distribui os caracteres (um pedaço
|
|
1173
|
+
entra a partir da caixa atual). O preenchimento automático do SMS também,
|
|
1174
|
+
porque a primeira caixa leva `autocomplete="one-time-code"`.
|
|
1175
|
+
- Sem buraco: focar uma caixa à frente da primeira vazia manda o foco de volta a
|
|
1176
|
+
ela.
|
|
1177
|
+
- Valor em string: `value`/`defaultValue`, `onChange(codigo)` a cada mudança e
|
|
1178
|
+
`onComplete(codigo)` quando as caixas enchem (uma vez por código novo).
|
|
1179
|
+
- `type="numeric"` (padrão, teclado numérico no celular) ou `"alphanumeric"`
|
|
1180
|
+
(letras e dígitos, em maiúsculas).
|
|
1181
|
+
- Acessibilidade: `role="group"` nomeado por `label` ou `ariaLabel`; cada caixa
|
|
1182
|
+
tem nome próprio (`digitLabel`, padrão "Dígito {n} de {total}", traduzível);
|
|
1183
|
+
`errorMessage`/`invalid` ligam `aria-invalid` e `aria-describedby`.
|
|
1184
|
+
- `size` `sm` ou `md`; foco e erro seguem os tokens de campo.
|
|
1185
|
+
|
|
1186
|
+
```vue
|
|
1187
|
+
<OtpInput
|
|
1188
|
+
label="Código de verificação"
|
|
1189
|
+
:length="6"
|
|
1190
|
+
:onComplete="(codigo) => verificar(codigo)"
|
|
1191
|
+
errorMessage="Código inválido ou expirado."
|
|
1192
|
+
/>
|
|
1193
|
+
```
|
|
1194
|
+
|
|
1195
|
+
- d89ebe3: feat(popover): `maxHeight` para o corpo do painel
|
|
1196
|
+
|
|
1197
|
+
- `maxHeight`: altura máxima do corpo, que rola além dela. Número vira px; texto
|
|
1198
|
+
vai como CSS (`"60vh"`). `"none"` deixa o corpo crescer com o conteúdo, como
|
|
1199
|
+
no painel "Colunas do card" do CrisDoc.
|
|
1200
|
+
- Sem a prop, **o teto de 300px continua**: tirá-lo por padrão faria todo painel
|
|
1201
|
+
existente com lista longa estourar a tela sem rolagem. Quem quer o corpo livre
|
|
1202
|
+
passa `maxHeight="none"`. O cabeçalho e o × não rolam junto, como antes.
|
|
1203
|
+
|
|
1204
|
+
```vue
|
|
1205
|
+
<Popover title="Colunas do card" maxHeight="none" :width="260">
|
|
1206
|
+
<Button>Personalizar</Button>
|
|
1207
|
+
<template #content>...</template>
|
|
1208
|
+
</Popover>
|
|
1209
|
+
```
|
|
1210
|
+
|
|
1211
|
+
- 3c482fa: feat(richtexteditor): novo `RichTextEditor`, texto rico leve sem biblioteca
|
|
1212
|
+
|
|
1213
|
+
Peça nova, sobre `contenteditable` e `document.execCommand`. Sem dependência
|
|
1214
|
+
nova: o primeiro corte é o que as telas de despacho, resposta e descrição de
|
|
1215
|
+
serviço pedem.
|
|
1216
|
+
|
|
1217
|
+
- Ferramentas: negrito, itálico, sublinhado, tachado, lista com marcadores, lista
|
|
1218
|
+
numerada, link, desfazer, refazer e limpar formatação. A barra se escolhe por
|
|
1219
|
+
`toolbar` (a ordem do array é a da tela, `"|"` é um separador): a padrão traz
|
|
1220
|
+
negrito, itálico, sublinhado, listas, link, desfazer e refazer;
|
|
1221
|
+
`["bold", "italic", "underline", "ul", "ol", "link"]` é a compacta e
|
|
1222
|
+
`["bold", "italic"]` a mínima.
|
|
1223
|
+
- `value`/`defaultValue`/`onChange` em HTML. O HTML é SEMPRE higienizado, tanto o
|
|
1224
|
+
que entra por `value` quanto o que se cola: ficam só `a`, `b`/`strong`,
|
|
1225
|
+
`i`/`em`, `u`, `s`/`strike`/`del`, `ul`, `ol`, `li`, `p`, `br`, `div`, `span`,
|
|
1226
|
+
títulos e citação; `script`, `style`, `onerror`, `class` e `javascript:` saem.
|
|
1227
|
+
Colar entra como texto puro. Link só aceita `http(s)`, `mailto`, `tel`, caminho
|
|
1228
|
+
e âncora, e ganha `rel="noopener noreferrer"`. `sanitizarHtml`, `enderecoSeguro`
|
|
1229
|
+
e `normalizarEndereco` vivem em `utils/html-seguro`.
|
|
1230
|
+
- A barra é `role="toolbar"` (Tab numa parada só, setas, Home e End entre as
|
|
1231
|
+
ferramentas). Negrito, itálico, sublinhado, tachado e as listas são botões de
|
|
1232
|
+
liga/desliga (`aria-pressed`) que seguem o cursor. A área é `role="textbox"`
|
|
1233
|
+
multilinha, com `label` ou `ariaLabel`, `aria-invalid` e `aria-describedby`
|
|
1234
|
+
(`errorMessage`, `helperText`). Ctrl+K abre o link.
|
|
1235
|
+
- Link sem modal: um campo logo abaixo da barra (endereço, Aplicar, Remover link,
|
|
1236
|
+
Cancelar; Esc fecha). Sem texto escolhido, o endereço vira o texto do link.
|
|
1237
|
+
Endereço sem esquema ganha `https://`; endereço perigoso mostra o erro e não
|
|
1238
|
+
vira link.
|
|
1239
|
+
- `footer` (slot): a assinatura do autor, dentro da moldura; `resizable` e
|
|
1240
|
+
`minHeight` (px); `readOnly` (sem barra) e `disabled`; `invalid`.
|
|
1241
|
+
- Textos por prop: `placeholder`, `toolbarLabel` e `labels` (parcial: `bold`,
|
|
1242
|
+
`italic`, `underline`, `strike`, `ul`, `ol`, `link`, `undo`, `redo`, `clear`,
|
|
1243
|
+
`linkAddress`, `linkApply`, `linkRemove`, `linkCancel`, `linkInvalid`).
|
|
1244
|
+
|
|
1245
|
+
Fora deste corte, por tamanho: tabela, imagem, cor, fonte, tamanho e
|
|
1246
|
+
alinhamento. Limite técnico: `document.execCommand` é obsoleto no padrão, mas
|
|
1247
|
+
todos os navegadores o mantêm; o histórico do desfazer varia um pouco entre eles.
|
|
1248
|
+
|
|
1249
|
+
```vue
|
|
1250
|
+
<RichTextEditor
|
|
1251
|
+
label="Despacho"
|
|
1252
|
+
:value="html"
|
|
1253
|
+
:onChange="(h) => (html = h)"
|
|
1254
|
+
:toolbar="['bold', 'italic', 'underline', '|', 'ul', 'ol', '|', 'link']"
|
|
1255
|
+
>
|
|
1256
|
+
<template #footer>Ana Paula Souza, SADM</template>
|
|
1257
|
+
</RichTextEditor>
|
|
1258
|
+
```
|
|
1259
|
+
|
|
1260
|
+
- b02f4ff: feat(select): `placement` (a lista abre para cima) e variante `filter` com opção "sem filtro" e rodapé
|
|
1261
|
+
|
|
1262
|
+
Tudo opt-in; sem as props novas o `Select` é o mesmo.
|
|
1263
|
+
|
|
1264
|
+
- `placement`: `bottom` (padrão), `top` ou `auto`. O `auto` mede o espaço na hora
|
|
1265
|
+
de abrir e abre para cima só se a lista (altura estimada, no máximo os 300px
|
|
1266
|
+
do CSS) não cabe embaixo e há mais espaço em cima, como o campo no rodapé de
|
|
1267
|
+
um modal numa janela baixa. A lista continua dentro do campo (posição
|
|
1268
|
+
absoluta), então um contêiner com `overflow` ainda pode cortá-la, igual
|
|
1269
|
+
antes.
|
|
1270
|
+
- `variant="filter"`: botão de filtro de barra de ferramentas, contornado em
|
|
1271
|
+
azul (`primary-pure` sobre `primary-light`), largura do conteúdo, lista de no
|
|
1272
|
+
mínimo 240px, busca focada ao abrir. Combina com `searchable`.
|
|
1273
|
+
- `emptyOptionLabel`: opção "sem filtro" no topo da lista (seleção única).
|
|
1274
|
+
Aparece marcada enquanto nada está escolhido; escolhê-la chama `onChange("")` e
|
|
1275
|
+
o campo volta a mostrar o `placeholder`, que é o nome do filtro.
|
|
1276
|
+
- `footer`: rodapé fixo da lista, com ações ("Gerenciar marcadores"). React:
|
|
1277
|
+
elemento; Vue: slot `footer`. Clicar nele não fecha a lista.
|
|
1278
|
+
|
|
1279
|
+
```vue
|
|
1280
|
+
<Select
|
|
1281
|
+
variant="filter"
|
|
1282
|
+
size="sm"
|
|
1283
|
+
placeholder="Marcadores"
|
|
1284
|
+
:searchable="true"
|
|
1285
|
+
emptyOptionLabel="Todos os marcadores"
|
|
1286
|
+
:options="marcadores"
|
|
1287
|
+
:value="filtro"
|
|
1288
|
+
:onChange="(v) => (filtro = v)"
|
|
1289
|
+
placement="auto"
|
|
1290
|
+
>
|
|
1291
|
+
<template #footer><Button variant="text" size="sm">Gerenciar marcadores</Button></template>
|
|
1292
|
+
</Select>
|
|
1293
|
+
```
|
|
1294
|
+
|
|
1295
|
+
- e45ce94: feat(stack): `gap="none"`, prop `as`, props de item flex e atributos HTML
|
|
1296
|
+
|
|
1297
|
+
O `Stack` passa a cobrir o que o produto ainda escrevia em CSS próprio. API
|
|
1298
|
+
antiga intacta: sem as props novas, o HTML e as classes são os mesmos.
|
|
1299
|
+
|
|
1300
|
+
- `gap="none"` zera o espaço (antes só havia os degraus da escala).
|
|
1301
|
+
- `as`: `div` (padrão), `span`, `ul`, `ol`, `li`, `section`, `nav`, `header`,
|
|
1302
|
+
`footer`, `form`. `ul` e `ol` saem sem marcador, margem e recuo, com
|
|
1303
|
+
`role="list"` (o Safari tira a semântica de lista de `list-style: none`).
|
|
1304
|
+
Com `as="form"`, `onSubmit` recebe o evento.
|
|
1305
|
+
- Atributos HTML (`id`, `style`, `title`, `role`, `tabIndex`, `data-*`,
|
|
1306
|
+
`aria-*`) vão para o elemento raiz. Sem isso `as="nav"` não tinha como levar
|
|
1307
|
+
`aria-label`.
|
|
1308
|
+
- Props do próprio Stack como item de outro Stack/flex: `grow`, `shrink`
|
|
1309
|
+
(`"0"` | `"1"`), `basis` (`"auto"`, `"0"`, `"25"`, `"33"`, `"50"`, `"66"`,
|
|
1310
|
+
`"75"`, `"100"`; os números são %), `minWidth` (`"0"` | `"auto"`; o Stack
|
|
1311
|
+
já nasce com `min-width: 0`), `overflow`, `overflowX`, `overflowY`,
|
|
1312
|
+
`fullHeight` e `fullWidth`.
|
|
1313
|
+
|
|
1314
|
+
Decisão: não existe `Stack.Item`. Quem precisa crescer, encolher ou ocupar a
|
|
1315
|
+
altura aninha um Stack com as mesmas props. Subcomponente por ponto não
|
|
1316
|
+
sobrevive aos dois geradores do Mitosis, e o Stack aninhado já é um item flex.
|
|
1317
|
+
|
|
1318
|
+
```tsx
|
|
1319
|
+
<Stack as="nav" aria-label="Atalhos" fullHeight>
|
|
1320
|
+
<Stack as="ul" gap="none">
|
|
1321
|
+
<Stack as="li">...</Stack>
|
|
1322
|
+
</Stack>
|
|
1323
|
+
<Stack grow overflowY="auto">
|
|
1324
|
+
...
|
|
1325
|
+
</Stack>
|
|
1326
|
+
<Stack shrink="0">...</Stack>
|
|
1327
|
+
</Stack>
|
|
1328
|
+
```
|
|
1329
|
+
|
|
1330
|
+
- 1d59843: feat(statcard): `labelPosition="top"` e `infoTooltip`
|
|
1331
|
+
|
|
1332
|
+
Opt-in; sem as props novas o `StatCard` é o mesmo.
|
|
1333
|
+
|
|
1334
|
+
- `labelPosition="top"`: o rótulo vai para o topo do cartão, acima do ícone e do
|
|
1335
|
+
número, e o número passa a 32/800 (o degrau `font-size-lg` do DS), como no
|
|
1336
|
+
painel da 1Doc. Só a posição visual muda: no HTML o número continua antes do
|
|
1337
|
+
rótulo, então o leitor de tela anuncia na mesma ordem. Por baixo, o corpo vira
|
|
1338
|
+
`display: contents` e o cartão uma grade de duas colunas.
|
|
1339
|
+
- `infoTooltip`: texto de ajuda; mostra um ⓘ ao lado do rótulo com o `Tooltip`
|
|
1340
|
+
`dark`. É um botão focável (`infoLabel` traduz o nome, "Mais informações" por
|
|
1341
|
+
padrão) e a ajuda chega ao leitor de tela como descrição do botão. Dentro de
|
|
1342
|
+
um cartão com `onClick` seria botão dentro de botão: evite a combinação.
|
|
1343
|
+
|
|
1344
|
+
```vue
|
|
1345
|
+
<StatCard
|
|
1346
|
+
labelPosition="top"
|
|
1347
|
+
:value="44"
|
|
1348
|
+
label="Não lidos"
|
|
1349
|
+
:icon="faEyeSlash"
|
|
1350
|
+
variant="primary"
|
|
1351
|
+
infoTooltip="Documentos que você ainda não abriu."
|
|
1352
|
+
/>
|
|
1353
|
+
```
|
|
1354
|
+
|
|
1355
|
+
- 3d6dd1d: feat(tabs): contador em pílula (`count`) e aba fechável (`closable`) com botão "+" (`onAdd`)
|
|
1356
|
+
|
|
1357
|
+
Tudo opt-in. Sem as props novas, a aba e a barra se comportam como antes (cada
|
|
1358
|
+
`Tab` ganha um `<span role="presentation">` com `display: contents`, que não
|
|
1359
|
+
muda o layout, e o `Tabs` ganha uma `div` de barra com o mesmo comportamento).
|
|
1360
|
+
|
|
1361
|
+
**Tab**
|
|
1362
|
+
|
|
1363
|
+
- `count` (número ou texto): pílula de 18px ao lado do texto, azul na aba ativa
|
|
1364
|
+
(`primary-pure`) e cinza nas outras (`neutral-light-medium`). O `0` aparece. O
|
|
1365
|
+
número entra no nome acessível da aba ("Todas 31").
|
|
1366
|
+
- `closable`: × num botão próprio, irmão da aba (não dentro dela, para não
|
|
1367
|
+
aninhar botão), círculo de 20px. A tecla Delete na aba focada faz o mesmo.
|
|
1368
|
+
O × não é uma parada de Tab (a aba já tem o Delete); tem nome "Fechar <aba>".
|
|
1369
|
+
- `onClose(index, event)`: quem remove a aba é o app. Clicar no × não troca de aba.
|
|
1370
|
+
- `closeLabel`: prefixo do nome acessível do ×, para traduzir ("Close Doc 1").
|
|
1371
|
+
|
|
1372
|
+
**Tabs**
|
|
1373
|
+
|
|
1374
|
+
- `onAdd(event)`: mostra o "+" logo depois da última aba, **fora** do
|
|
1375
|
+
`role="tablist"` (o tablist só pode ter abas). `addLabel` traduz o nome
|
|
1376
|
+
("Adicionar aba" por padrão).
|
|
1377
|
+
|
|
1378
|
+
```vue
|
|
1379
|
+
<Tabs
|
|
1380
|
+
:value="atual"
|
|
1381
|
+
:onChange="mudar"
|
|
1382
|
+
:onAdd="adicionar"
|
|
1383
|
+
addLabel="Adicionar aba"
|
|
1384
|
+
>
|
|
1385
|
+
<Tab label="Todas" index="0" :count="31" />
|
|
1386
|
+
<Tab v-for="a in abas" :key="a.id" :label="a.nome" :index="a.id"
|
|
1387
|
+
:closable="true" closeLabel="Fechar" :onClose="fechar" />
|
|
1388
|
+
</Tabs>
|
|
1389
|
+
```
|
|
1390
|
+
|
|
1391
|
+
Ficou de fora desta rodada: o ponto
|
|
1392
|
+
de estado da aba (a bolinha ao lado do nome); a rolagem horizontal das abas já existia.
|
|
1393
|
+
|
|
1394
|
+
- 96e752b: feat(tooltip): `variant="dark"` compacto e `maxWidth`
|
|
1395
|
+
|
|
1396
|
+
Opt-in; sem as props novas o `Tooltip` é o mesmo.
|
|
1397
|
+
|
|
1398
|
+
- `variant="dark"`: balão escuro e compacto (padding 4/8, raio 4, teto de 220px)
|
|
1399
|
+
para ícone, sigla e botão de barra de ferramentas. Fundo `background-dark` e
|
|
1400
|
+
texto `neutral-light-pure`: o par invertido do tema, então o contraste vale nos
|
|
1401
|
+
temas claros, no escuro e no alto contraste (sem cor fixa). A fonte é a de
|
|
1402
|
+
12px do DS (o CrisDoc usa 11px, que não está na escala). A seta acompanha a cor.
|
|
1403
|
+
- `maxWidth`: largura máxima do balão, qualquer valor CSS, vence o teto de cada
|
|
1404
|
+
variante (280px no padrão, 220px no dark).
|
|
1405
|
+
|
|
1406
|
+
```vue
|
|
1407
|
+
<Tooltip variant="dark" content="Atualizar" maxWidth="200px">
|
|
1408
|
+
<Button variant="neutral-text" size="xs">Atualizar</Button>
|
|
1409
|
+
</Tooltip>
|
|
1410
|
+
```
|
|
1411
|
+
|
|
1412
|
+
### Patch Changes
|
|
1413
|
+
|
|
1414
|
+
- 2259459: fix(ailabel): `defaultOpen` passa a funcionar
|
|
1415
|
+
|
|
1416
|
+
A prop era declarada e documentada, mas nunca lida. Agora o painel nasce
|
|
1417
|
+
aberto com `defaultOpen` (também no HTML do servidor) e o clique continua
|
|
1418
|
+
abrindo e fechando. `open` controlado segue vencendo.
|
|
1419
|
+
|
|
1420
|
+
- e00b163: fix(combobox): placeholder do campo somente leitura passa 4,5:1
|
|
1421
|
+
|
|
1422
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1423
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1424
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1425
|
+
|
|
1426
|
+
- 19ff160: fix(datepicker): placeholder do campo somente leitura passa 4,5:1
|
|
1427
|
+
|
|
1428
|
+
Sobre o fundo de somente leitura o placeholder dava 4,2:1 nos temas claros e
|
|
1429
|
+
o axe reprovava (`color-contrast`). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1430
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1431
|
+
|
|
1432
|
+
- 9315dd7: fix(datepicker): `value` e `defaultValue` chegam ao campo no modo single
|
|
1433
|
+
|
|
1434
|
+
No modo single o componente só lia `range`: `value` e `defaultValue` eram
|
|
1435
|
+
ignorados e o campo mostrava o placeholder. Agora `value` controla o campo e
|
|
1436
|
+
`defaultValue` semeia o modo não-controlado. O modo range não muda.
|
|
1437
|
+
|
|
1438
|
+
- 2250bb4: fix(input): placeholder do campo somente leitura passa 4,5:1
|
|
1439
|
+
|
|
1440
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1441
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1442
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1443
|
+
|
|
1444
|
+
- ef321dc: fix(kanban): quadro não faz a página rolar na horizontal em tela estreita
|
|
1445
|
+
|
|
1446
|
+
O texto só para leitor de tela de cada coluna é `position: absolute` e, sem
|
|
1447
|
+
ancestral posicionado, escapava da rolagem do quadro: a 375px a página ganhava
|
|
1448
|
+
rolagem lateral. `.umds-kanban` passa a ser `position: relative`; o visual não
|
|
1449
|
+
muda.
|
|
1450
|
+
|
|
1451
|
+
- 978ad95: fix(multiselect): placeholder do campo somente leitura passa 4,5:1
|
|
1452
|
+
|
|
1453
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1454
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1455
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1456
|
+
|
|
1457
|
+
- 31d3005: fix(a11y): Select, MultiSelect e SegmentedControl com nome acessível no HTML do servidor
|
|
1458
|
+
|
|
1459
|
+
O id automático desses componentes só nasce no `onMount`, e o nome acessível
|
|
1460
|
+
vinha de `aria-labelledby` apontando para ele: no HTML do servidor, e até a
|
|
1461
|
+
hidratação, o combobox (e os radios do SegmentedControl) ficavam sem nome
|
|
1462
|
+
(axe `aria-input-field-name`). Enquanto não há id, o nome sai do texto do
|
|
1463
|
+
label via `aria-label`; depois do mount volta ao `aria-labelledby`. Servidor e
|
|
1464
|
+
primeira renderização do cliente continuam idênticos. Sem mudança visual.
|
|
1465
|
+
|
|
1466
|
+
- 7f58f04: fix(phoneinput): placeholder do campo somente leitura passa 4,5:1
|
|
1467
|
+
|
|
1468
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1469
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1470
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1471
|
+
|
|
1472
|
+
- 98e9bf0: fix(select): placeholder do campo somente leitura passa 4,5:1
|
|
1473
|
+
|
|
1474
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1475
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1476
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1477
|
+
|
|
1478
|
+
- c33298c: fix(stack,box): raiz única no Vue, repassa ouvintes e atributos
|
|
1479
|
+
|
|
1480
|
+
No Vue, `Stack` e `Box` saíam com raiz em FRAGMENTO: o Mitosis gera um
|
|
1481
|
+
`<template v-if="elementTag === ...">` por tag, e o Vue não repassa atributo nem
|
|
1482
|
+
ouvinte a um componente de raiz múltipla. Só sobrevivia uma lista fixa
|
|
1483
|
+
(`data-*`, `aria-*`, `style`, `class`, `title`, `role`, `tabIndex`). No 2.8.0
|
|
1484
|
+
publicado a raiz era um `<div>` único e o Vue repassava tudo, então foi uma
|
|
1485
|
+
regressão silenciosa das props novas (`as`, `gap="none"`...).
|
|
1486
|
+
|
|
1487
|
+
Descartados em silêncio, antes desta correção:
|
|
1488
|
+
|
|
1489
|
+
- ouvintes: `@click`, `@keydown`, `@dragstart`, `@drop`, `@paste`, `@mousedown`...
|
|
1490
|
+
- atributos fora da lista: `tabindex` (minúsculo), `draggable`...
|
|
1491
|
+
- `v-show` e o `$el` do `ref` do componente (apontavam para o nó de âncora do
|
|
1492
|
+
fragmento, não para o elemento).
|
|
1493
|
+
|
|
1494
|
+
Agora o template gerado é um `<component :is="elementTag">` só (ligado no
|
|
1495
|
+
`postbuild.js`, como o do `DataTable`), e o fallthrough do Vue leva ao elemento
|
|
1496
|
+
tudo o que o consumidor passa. Continuam como estavam: `as` com as 10 tags,
|
|
1497
|
+
`role="list"` em `ul`/`ol` (o `role` do consumidor vence), `onSubmit` do
|
|
1498
|
+
`as="form"`, `id`, `style` e `className`. O React não muda.
|
|
1499
|
+
|
|
1500
|
+
Novo teste do pacote Vue, `stack-box-raiz-unica.test.mjs`, que monta o
|
|
1501
|
+
componente num DOM (jsdom) e dispara os eventos. O helper `dom.mjs` serve para
|
|
1502
|
+
qualquer teste de comportamento no Vue; não adiciona dependência (usa o jsdom do
|
|
1503
|
+
pacote React e o `vue/compiler-sfc`).
|
|
1504
|
+
|
|
1505
|
+
Outros componentes do 1DS com raiz em fragmento têm o mesmo limite (ex.: `List`,
|
|
1506
|
+
quando troca entre vazio e `ul`/`ol`); este changeset trata só `Stack` e `Box`.
|
|
1507
|
+
|
|
1508
|
+
- 81cb08e: fix(textarea): placeholder do campo somente leitura passa 4,5:1
|
|
1509
|
+
|
|
1510
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1511
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1512
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1513
|
+
|
|
1514
|
+
- f7645bf: fix(timepicker): placeholder do campo somente leitura passa 4,5:1
|
|
1515
|
+
|
|
1516
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1517
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1518
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1519
|
+
|
|
1520
|
+
- 0fc7a82: fix(vue): `Text`, `Grid` e `Logo` repassam `title`, `style` e `aria-*`; `Button` e `DataTable` param de sujar o DOM
|
|
1521
|
+
|
|
1522
|
+
Quatro defeitos que só existiam no Vue gerado (o React estava certo):
|
|
1523
|
+
|
|
1524
|
+
- `Text`, `Grid` e `Logo` descartavam `title`, `style`, `aria-*` e `data-*`. O
|
|
1525
|
+
laço `for (k in props)` do `htmlAttrs` compilava para `props.props`, que não
|
|
1526
|
+
existe. O passo `postbuild` do core passa a ler `props` e `useAttrs()` (o que
|
|
1527
|
+
não está declarado na interface chega por `attrs`, não por `props`). Nos
|
|
1528
|
+
`.lite.tsx` de `Text` e `Grid` o getter `style` virou `estiloInline`: o Mitosis
|
|
1529
|
+
trocava toda ocorrência da palavra por `style.value` e o estilo do
|
|
1530
|
+
consumidor deixava de passar.
|
|
1531
|
+
- `DataTable` escrevia a classe `umds-datatable__row--selected.value`. O getter
|
|
1532
|
+
`selected` colidia com a palavra dentro da string; virou `selectedIndexes`.
|
|
1533
|
+
- `Button` escrevia `autofocus="false"`. `autoFocus` só vai ao DOM quando
|
|
1534
|
+
verdadeiro.
|
|
1535
|
+
- Tipos do Vue: `setTheme`, `getTheme`, `initTheme`, `getAvailableThemes` e
|
|
1536
|
+
`onThemeChange` estavam tipados com `'light' | 'dark' | 'system'`. Agora
|
|
1537
|
+
`Theme` e `ThemeName` são lidos de `core/src/utils/theme.ts` (`'1doc'`,
|
|
1538
|
+
`'1doc-dark'`, `'1doc-high-contrast'`...), e `registerTheme` foi declarado.
|
|
1539
|
+
|
|
1540
|
+
Testes: `pnpm --filter @1doc/1ds-vue test` (novo, `node:test` com SSR, sem
|
|
1541
|
+
dependência nova) e `AtributosRepassados.test.tsx` no React.
|
|
1542
|
+
|
|
3
1543
|
## 2.8.0
|
|
4
1544
|
|
|
5
1545
|
### Minor Changes
|