@1doc/1ds-react 2.7.2 → 2.9.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 +1280 -0
- package/dist/components/AIContent/AIContent.d.ts +10 -0
- package/dist/components/AIContent/AIContent.js +1 -1
- package/dist/components/AILabel/AILabel.d.ts +4 -0
- package/dist/components/AILabel/AILabel.js +2 -2
- package/dist/components/Accordion/Accordion.d.ts +6 -2
- package/dist/components/Alert/Alert.css +2 -0
- package/dist/components/Alert/Alert.d.ts +3 -1
- package/dist/components/Alert/Alert.js +7 -1
- package/dist/components/AppHeader/AppHeader.css +82 -8
- package/dist/components/AppHeader/AppHeader.d.ts +12 -1
- package/dist/components/AppHeader/AppHeader.js +186 -1
- package/dist/components/AppNavItem/AppNavItem.css +11 -3
- package/dist/components/AppShell/AppShell.css +9 -0
- package/dist/components/AppShell/AppShell.d.ts +8 -0
- package/dist/components/AppShell/AppShell.js +4 -1
- package/dist/components/AppSidebar/AppSidebar.css +1 -1
- package/dist/components/AppSidebar/AppSidebar.d.ts +4 -0
- package/dist/components/AppSidebar/AppSidebar.js +3 -1
- package/dist/components/AttachmentCard/AttachmentCard.css +17 -1
- package/dist/components/AttachmentCard/AttachmentCard.d.ts +29 -2
- package/dist/components/AttachmentCard/AttachmentCard.js +88 -20
- package/dist/components/Avatar/Avatar.css +7 -2
- package/dist/components/Avatar/AvatarGroup.d.ts +27 -0
- package/dist/components/Avatar/AvatarGroup.js +28 -4
- package/dist/components/Badge/Badge.css +61 -3
- package/dist/components/Badge/Badge.d.ts +14 -4
- package/dist/components/Badge/Badge.js +1 -0
- package/dist/components/BottomSheet/BottomSheet.css +1 -0
- package/dist/components/BottomSheet/BottomSheet.d.ts +8 -0
- package/dist/components/BottomSheet/BottomSheet.js +14 -2
- 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 +125 -0
- package/dist/components/Calendar/Calendar.js +320 -0
- package/dist/components/Chart/BarChart.d.ts +6 -0
- package/dist/components/Chart/BarChart.js +3 -1
- package/dist/components/Chart/LineChart.d.ts +6 -0
- package/dist/components/Chart/LineChart.js +3 -1
- package/dist/components/Checkbox/Checkbox.css +4 -1
- package/dist/components/Chips/Chips.css +39 -0
- package/dist/components/Chips/Chips.d.ts +7 -2
- package/dist/components/Chips/Chips.js +6 -2
- package/dist/components/Coachmark/Coachmark.css +118 -0
- package/dist/components/Coachmark/Coachmark.d.ts +75 -0
- package/dist/components/Coachmark/Coachmark.js +321 -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 +133 -0
- package/dist/components/ColorPicker/ColorPicker.d.ts +73 -0
- package/dist/components/ColorPicker/ColorPicker.js +219 -0
- package/dist/components/Combobox/Combobox.css +11 -3
- package/dist/components/ConfirmAIAction/ConfirmAIAction.d.ts +11 -1
- package/dist/components/ConfirmAIAction/ConfirmAIAction.js +6 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.css +3 -0
- package/dist/components/ConfirmDialog/ConfirmDialog.d.ts +14 -0
- package/dist/components/ConfirmDialog/ConfirmDialog.js +2 -2
- package/dist/components/DataTable/DataTable.css +80 -0
- package/dist/components/DataTable/DataTable.d.ts +23 -4
- package/dist/components/DataTable/DataTable.js +61 -15
- package/dist/components/DatePicker/DatePicker.css +8 -0
- package/dist/components/DatePicker/DatePicker.d.ts +4 -0
- package/dist/components/DatePicker/DatePicker.js +14 -1
- package/dist/components/DescriptionList/DescriptionList.css +113 -0
- package/dist/components/DescriptionList/DescriptionList.d.ts +59 -0
- package/dist/components/DescriptionList/DescriptionList.js +51 -0
- package/dist/components/Drawer/Drawer.css +1 -0
- package/dist/components/Dropdown/Dropdown.js +47 -29
- package/dist/components/FileInput/FileInput.css +24 -4
- package/dist/components/FileInput/FileInput.d.ts +22 -2
- package/dist/components/FileInput/FileInput.js +23 -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 +41 -3
- package/dist/components/Input/Input.d.ts +14 -1
- package/dist/components/Input/Input.js +72 -6
- package/dist/components/Kanban/Kanban.css +5 -0
- package/dist/components/Kanban/Kanban.d.ts +41 -0
- package/dist/components/Kanban/Kanban.js +59 -27
- package/dist/components/Kanban/KanbanCard.d.ts +2 -0
- package/dist/components/Kanban/KanbanCard.js +1 -1
- package/dist/components/Kanban/KanbanColumn.d.ts +2 -0
- package/dist/components/Kanban/KanbanColumn.js +3 -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/Link/Link.css +1 -1
- 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 +85 -0
- package/dist/components/List/ListItem.js +81 -0
- package/dist/components/Modal/Modal.css +93 -8
- package/dist/components/Modal/Modal.d.ts +45 -7
- package/dist/components/Modal/Modal.js +106 -6
- package/dist/components/MultiSelect/MultiSelect.css +9 -1
- package/dist/components/MultiSelect/MultiSelect.js +45 -8
- 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/Pagination/Pagination.d.ts +6 -0
- package/dist/components/Pagination/Pagination.js +9 -1
- package/dist/components/PhoneInput/PhoneInput.css +9 -1
- package/dist/components/PhoneInput/PhoneInput.d.ts +10 -0
- package/dist/components/PhoneInput/PhoneInput.js +20 -3
- package/dist/components/Popover/Popover.d.ts +7 -0
- package/dist/components/Popover/Popover.js +11 -1
- package/dist/components/RichTextEditor/RichTextEditor.css +203 -0
- package/dist/components/RichTextEditor/RichTextEditor.d.ts +83 -0
- package/dist/components/RichTextEditor/RichTextEditor.js +494 -0
- package/dist/components/SegmentedControl/SegmentedControl.d.ts +2 -0
- package/dist/components/SegmentedControl/SegmentedControl.js +21 -8
- package/dist/components/Select/Select.css +71 -1
- package/dist/components/Select/Select.d.ts +12 -0
- package/dist/components/Select/Select.js +93 -10
- package/dist/components/SidePanel/SidePanel.css +4 -4
- package/dist/components/SidePanelItem/SidePanelItem.css +7 -5
- package/dist/components/SidePanelSearch/SidePanelSearch.css +2 -2
- package/dist/components/SidePanelSection/SidePanelSection.css +7 -5
- 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 +73 -0
- package/dist/components/StatCard/StatCard.d.ts +17 -0
- package/dist/components/StatCard/StatCard.js +4 -1
- package/dist/components/Stepper/Stepper.css +4 -1
- package/dist/components/Stepper/Stepper.d.ts +8 -0
- package/dist/components/Stepper/Stepper.js +4 -4
- package/dist/components/Switch/Switch.css +1 -0
- 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.d.ts +9 -1
- package/dist/components/Text/Text.js +2 -2
- package/dist/components/Textarea/Textarea.css +11 -3
- package/dist/components/TimePicker/TimePicker.css +8 -0
- package/dist/components/TimePicker/TimePicker.d.ts +6 -0
- package/dist/components/TimePicker/TimePicker.js +1 -1
- package/dist/components/Tooltip/Tooltip.css +40 -0
- package/dist/components/Tooltip/Tooltip.d.ts +11 -0
- package/dist/components/Tooltip/Tooltip.js +114 -11
- 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/Alert.test.d.ts +1 -0
- package/dist/teste/Alert.test.js +27 -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/AvatarGroupOverlap.test.d.ts +1 -0
- package/dist/teste/AvatarGroupOverlap.test.js +56 -0
- package/dist/teste/BadgeTag.test.d.ts +1 -0
- package/dist/teste/BadgeTag.test.js +42 -0
- package/dist/teste/BottomSheet.test.d.ts +1 -0
- package/dist/teste/BottomSheet.test.js +23 -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/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/ColorPicker.test.d.ts +1 -0
- package/dist/teste/ColorPicker.test.js +132 -0
- package/dist/teste/ConfirmAIAction.test.d.ts +1 -0
- package/dist/teste/ConfirmAIAction.test.js +33 -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/Dropdown.test.js +111 -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/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/Modal.test.d.ts +1 -0
- package/dist/teste/Modal.test.js +26 -0
- package/dist/teste/ModalVariantes.test.d.ts +1 -0
- package/dist/teste/ModalVariantes.test.js +151 -0
- package/dist/teste/MultiSelectErro.test.d.ts +1 -0
- package/dist/teste/MultiSelectErro.test.js +62 -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/RotulosTraduziveis.test.d.ts +1 -0
- package/dist/teste/RotulosTraduziveis.test.js +405 -0
- package/dist/teste/SegmentedControl.test.js +33 -0
- package/dist/teste/Select.test.d.ts +1 -0
- package/dist/teste/Select.test.js +62 -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/TabsContadorFechavel.test.d.ts +1 -0
- package/dist/teste/TabsContadorFechavel.test.js +79 -0
- package/dist/teste/Tooltip.test.d.ts +1 -0
- package/dist/teste/Tooltip.test.js +109 -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/chart.d.ts +4 -0
- package/dist/utils/chart.js +3 -2
- package/dist/utils/html-seguro.d.ts +27 -0
- package/dist/utils/html-seguro.js +97 -0
- package/dist/utils/id.d.ts +2 -0
- package/dist/utils/id.js +23 -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/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/Alert.test.tsx +32 -0
- package/src/teste/AtributosRepassados.test.tsx +73 -0
- package/src/teste/AttachmentCardIA.test.tsx +126 -0
- package/src/teste/AvatarGroupOverlap.test.tsx +74 -0
- package/src/teste/BadgeTag.test.tsx +64 -0
- package/src/teste/BottomSheet.test.tsx +25 -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/ChipsXs.test.tsx +41 -0
- package/src/teste/Coachmark.test.tsx +198 -0
- package/src/teste/ColorPicker.test.tsx +153 -0
- package/src/teste/ConfirmAIAction.test.tsx +41 -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/Dropdown.test.tsx +146 -0
- package/src/teste/FileInputTrigger.test.tsx +89 -0
- package/src/teste/IconPicker.test.tsx +145 -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/Modal.test.tsx +28 -0
- package/src/teste/ModalVariantes.test.tsx +173 -0
- package/src/teste/MultiSelectErro.test.tsx +97 -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/RotulosTraduziveis.test.tsx +545 -0
- package/src/teste/SegmentedControl.test.tsx +57 -0
- package/src/teste/Select.test.tsx +97 -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/TabsContadorFechavel.test.tsx +144 -0
- package/src/teste/Tooltip.test.tsx +219 -0
- package/src/teste/TooltipDark.test.tsx +51 -0
- package/src/utils/calendario.ts +78 -0
- package/src/utils/chart.ts +7 -2
- package/src/utils/html-seguro.ts +94 -0
- package/src/utils/id.ts +24 -0
- package/src/utils/paleta-de-cores.ts +34 -0
- package/src/utils/texto.ts +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,1285 @@
|
|
|
1
1
|
# @1doc/1ds-react
|
|
2
2
|
|
|
3
|
+
## 2.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 704af0c: feat(accordion): conteúdo livre por item no Vue (slot `content-<id>`)
|
|
8
|
+
|
|
9
|
+
No React o `content` do item já aceitava qualquer nó. No Vue ele era interpolado
|
|
10
|
+
como texto, então o painel só aceitava string. Agora, no Vue, cada item pode ter
|
|
11
|
+
um slot com o próprio conteúdo.
|
|
12
|
+
|
|
13
|
+
- `#content-<id>`: slot com escopo por item (`<id>` é o `id` do item), que recebe
|
|
14
|
+
`{ item }` e vale sobre o `content` de texto daquele item. Itens sem slot
|
|
15
|
+
continuam mostrando o texto. O `postbuild` liga o slot ao `Accordion.vue`
|
|
16
|
+
gerado, como já faz com o `DataTable`, e falha o build se o gerado mudar de
|
|
17
|
+
forma.
|
|
18
|
+
- Título: o título do item **já é neutro** no 1DS (14/600, `neutral-dark-pure`;
|
|
19
|
+
só o chevron fica azul quando abre), então não há opção de cor a acrescentar.
|
|
20
|
+
Se o CrisDoc mediu azul de 16px, era outra peça ou uma versão antiga.
|
|
21
|
+
|
|
22
|
+
```vue
|
|
23
|
+
<Accordion :items="[{ id: 'campos', title: 'Seção 01', content: '' }]">
|
|
24
|
+
<template #content-campos>
|
|
25
|
+
<Input label="Nome" fullWidth />
|
|
26
|
+
</template>
|
|
27
|
+
</Accordion>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- 3d9472d: feat(attachmentcard): `status="ai"`, painel livre (`panel`), `panelWidth` e `closePanelOnAction`
|
|
31
|
+
|
|
32
|
+
Opt-in; sem as props novas o cartão é o mesmo.
|
|
33
|
+
|
|
34
|
+
- `status="ai"`: selo de recurso de IA, no roxo da IA (`ai-light` / `ai-dark`, os
|
|
35
|
+
mesmos tokens do `AILabel`), com a varinha como ícone padrão (`statusIcon`
|
|
36
|
+
continua mandando). O ícone do painel também é a varinha.
|
|
37
|
+
- `panel`: conteúdo livre do painel do selo, no lugar do resultado da conferência
|
|
38
|
+
(ações, campos, texto). React: o elemento; Vue: o slot `panel`. Com ele o selo
|
|
39
|
+
vira botão mesmo sem `statusDetails`. Sem título interno, o painel é nomeado
|
|
40
|
+
pelo selo (o mesmo nome que o botão tem, "Recursos IA: conferência de ...").
|
|
41
|
+
- `panelWidth` (px): largura do painel; padrão 300.
|
|
42
|
+
- `closePanelOnAction`: ao acionar um botão ou link de dentro do painel (o
|
|
43
|
+
"Aplicar sugestão"), o painel fecha e o foco volta ao selo. A ação do app roda
|
|
44
|
+
antes. O botão de copiar um campo não conta. Sem a prop, o painel fica aberto
|
|
45
|
+
até Esc, clique fora ou o foco sair.
|
|
46
|
+
|
|
47
|
+
Por baixo, o `postbuild` ganhou `slotsNoScriptVue`: o Vue que recebe só o slot
|
|
48
|
+
enxergava `props.panel` como `undefined` no script e o selo não virava botão. O
|
|
49
|
+
gancho troca `props.<prop>` por `(props.<prop> || slots['<slot>'])` nos arquivos
|
|
50
|
+
listados e falha o build se o gerado não tiver o formato esperado.
|
|
51
|
+
|
|
52
|
+
```vue
|
|
53
|
+
<AttachmentCard
|
|
54
|
+
fileName="Protocolo 104-2026.pdf"
|
|
55
|
+
status="ai"
|
|
56
|
+
statusLabel="Recursos IA"
|
|
57
|
+
:panelWidth="280"
|
|
58
|
+
:closePanelOnAction="true"
|
|
59
|
+
>
|
|
60
|
+
<template #panel>
|
|
61
|
+
<Text>A IA sugere "Recurso Administrativo".</Text>
|
|
62
|
+
<Button size="sm" @click="aplicar">Aplicar sugestão</Button>
|
|
63
|
+
</template>
|
|
64
|
+
</AttachmentCard>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- 2c0dafb: feat(avatargroup): `overlap`, `ring` e `overflowCount`
|
|
68
|
+
|
|
69
|
+
Opt-in; sem as props novas o grupo é o mesmo.
|
|
70
|
+
|
|
71
|
+
- `overflowCount`: quantas pessoas existem além das de `avatars`. O "+N" deixa de
|
|
72
|
+
exigir N itens-fantasma: com 16 responsáveis, passe os 4 primeiros e
|
|
73
|
+
`overflowCount={12}`. Soma com o que passar de `max` dentro de `avatars`, e os
|
|
74
|
+
textos traduzíveis (`overflowTitle`, `overflowAriaLabel`) recebem o total.
|
|
75
|
+
- `overlap` (px): quanto cada avatar avança sobre o anterior. O padrão segue 8
|
|
76
|
+
(`spacing-nano`); 6 é o do CrisDoc e corta menos as iniciais. O recuo do
|
|
77
|
+
último item acompanha.
|
|
78
|
+
- `ring` (px): largura do anel (a borda da cor do fundo). O padrão segue 1,5; 1 é
|
|
79
|
+
o do CrisDoc.
|
|
80
|
+
|
|
81
|
+
As duas últimas escrevem `--umds-avatar-group-overlap` e `--umds-avatar-group-ring`
|
|
82
|
+
no próprio grupo (os padrões vivem no CSS), então só aparece `style` quando você
|
|
83
|
+
as usa.
|
|
84
|
+
|
|
85
|
+
```vue
|
|
86
|
+
<AvatarGroup
|
|
87
|
+
:avatars="primeiros4"
|
|
88
|
+
:max="4"
|
|
89
|
+
:overlap="6"
|
|
90
|
+
:ring="1"
|
|
91
|
+
:overflowCount="12"
|
|
92
|
+
/>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- 8ff3652: feat(badge, tag): tamanhos compactos, `Tag soft` e `pill`, variante `new` e `Badge attached`
|
|
96
|
+
|
|
97
|
+
Tudo opt-in: sem as props novas, o HTML e o visual são os mesmos.
|
|
98
|
+
|
|
99
|
+
**Badge**
|
|
100
|
+
|
|
101
|
+
- `size="2xs"`: 16px de altura, fonte de 10px, raio 4. A fonte de 10px não está
|
|
102
|
+
na escala do DS (o menor degrau é 12px), então é um literal comentado no CSS;
|
|
103
|
+
se o mínimo de 12px for decisão de acessibilidade, o 2xs é o que sai.
|
|
104
|
+
- `variant="new"` (a "novidade" do CrisDoc): amarelo, caixa alta, 800, pílula.
|
|
105
|
+
Solid e soft usam o fundo amarelo; outlined, o contorno. O DS não tem token
|
|
106
|
+
semântico de amarelo, então usa os primitivos `yellow-*` (com o `yellow-light`
|
|
107
|
+
já corrigido) e `gray-darkest` para o texto, que não mudam com o tema
|
|
108
|
+
(contraste 8:1). Candidato a token semântico de destaque.
|
|
109
|
+
- `attached`: rótulo colado no canto superior esquerdo de um card, com os cantos
|
|
110
|
+
de baixo arredondados e os de cima retos. Posiciona em `absolute`: o pai
|
|
111
|
+
precisa de `position: relative`.
|
|
112
|
+
|
|
113
|
+
**Tag**
|
|
114
|
+
|
|
115
|
+
- `size="xs"`: 18px (`line-height: 1`, padding 2 e 8, fonte 12, ícone 12). Foi
|
|
116
|
+
criado um tamanho novo em vez de mexer no `sm` (27px), para não encolher quem
|
|
117
|
+
já usa `sm`. O × e o ícone clicável mantêm o alvo de 24px com margem negativa.
|
|
118
|
+
- `appearance="soft"`: fundo claro da cor da variante, sem contorno.
|
|
119
|
+
- `pill`: cantos totalmente arredondados, em qualquer aparência e tamanho.
|
|
120
|
+
- `variant="new"`: amarelo, nas três aparências (soft = `yellow-light` com texto
|
|
121
|
+
`yellow-dark`).
|
|
122
|
+
|
|
123
|
+
```vue
|
|
124
|
+
<Badge size="2xs" appearance="solid">SOBR</Badge>
|
|
125
|
+
<Badge variant="new" size="xs">Novidade</Badge>
|
|
126
|
+
<div
|
|
127
|
+
style="position: relative"
|
|
128
|
+
><Badge attached variant="info" appearance="solid">Tarefa pendente</Badge></div>
|
|
129
|
+
<Tag size="xs" appearance="soft" variant="primary" pill label="SEFIN" />
|
|
130
|
+
<Tag size="xs" appearance="soft" variant="new" pill label="Dado simulado" />
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- dd0e159: feat(box): item flex (`grow`, `shrink`, `basis`...) e prop `as`
|
|
134
|
+
|
|
135
|
+
O `Box` ganha as props de item flex do `Stack` e a troca de elemento, com os
|
|
136
|
+
mesmos nomes e valores. Sem as props novas, o HTML e as classes são os mesmos.
|
|
137
|
+
|
|
138
|
+
- `as`: `div` (padrão), `span`, `ul`, `ol`, `li`, `section`, `nav`, `header`,
|
|
139
|
+
`footer`, `form`. `ul` e `ol` saem sem marcador, margem e recuo (o padding do
|
|
140
|
+
Box continua valendo) e com `role="list"`. Com `as="form"`, `onSubmit` recebe
|
|
141
|
+
o evento. Uma linha com borda e fundo dentro de uma lista é `<Box as="li">`.
|
|
142
|
+
- Item flex: `grow`, `shrink` (`"0"` | `"1"`), `basis` (`"auto"`, `"0"`, `"25"`,
|
|
143
|
+
`"33"`, `"50"`, `"66"`, `"75"`, `"100"`; os números são %), `minWidth` (`"0"`
|
|
144
|
+
| `"auto"`; o Box já nasce com `min-width: 0`), `overflow`, `overflowX`,
|
|
145
|
+
`overflowY` e `fullHeight` (o `fullWidth` já existia).
|
|
146
|
+
|
|
147
|
+
Vue: com `as`, o Box passa a ter raiz múltipla, e o Vue não repassa atributos
|
|
148
|
+
de fallthrough a esse tipo de componente. Por isso `class` entra no mesmo
|
|
149
|
+
repasse de `style`, `title`, `role`, `data-*` e `aria-*` (o `Stack` também). Ouvintes
|
|
150
|
+
(`@click`) não caem mais no raiz: ponha-os num filho.
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
<Box direction="horizontal" gap="xxxs" padding="md">
|
|
154
|
+
<Box shrink="0" basis="25">Filtros</Box>
|
|
155
|
+
<Box grow overflowY="auto" fullHeight>Resultados</Box>
|
|
156
|
+
</Box>
|
|
157
|
+
<Box as="ul" aria-label="Setores"><Box as="li" bordered padding="xxxs">SADM</Box></Box>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
- a6872d9: feat(box): `direction`, `gap`, `align`, `justify` e `wrap` (a caixa também é layout)
|
|
161
|
+
|
|
162
|
+
Uma linha, cartão ou região com borda, fundo e padding passa a ser UM componente,
|
|
163
|
+
sem `Stack` por dentro nem flex no CSS do produto. As cinco props têm os mesmos
|
|
164
|
+
nomes e valores do `Stack`; qualquer uma delas liga o `display: flex`. Sem
|
|
165
|
+
nenhuma, o `Box` segue sendo um bloco comum (API antiga intacta).
|
|
166
|
+
|
|
167
|
+
- `direction`: `"vertical"` (padrão quando o flex está ligado) | `"horizontal"`.
|
|
168
|
+
- `gap`: degraus da escala, mais `"none"`. Diferente do `Stack`, não tem valor
|
|
169
|
+
padrão: sem `gap` os filhos ficam colados.
|
|
170
|
+
- `align`, `justify`, `wrap`: como no `Stack`.
|
|
171
|
+
- Também passam a ir para o elemento raiz: `id`, `style`, `title`, `role`,
|
|
172
|
+
`tabIndex`, `data-*` e `aria-*` (uma região pede `role` e `aria-label`).
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
<Box
|
|
176
|
+
direction="horizontal"
|
|
177
|
+
gap="xxxs"
|
|
178
|
+
align="center"
|
|
179
|
+
justify="between"
|
|
180
|
+
padding="xs"
|
|
181
|
+
background="surface"
|
|
182
|
+
radius="sm"
|
|
183
|
+
bordered
|
|
184
|
+
>
|
|
185
|
+
<Text variant="body2">
|
|
186
|
+
Reforma da cobertura do Ginásio Poliesportivo Municipal
|
|
187
|
+
</Text>
|
|
188
|
+
<Button variant="secondary" size="sm">
|
|
189
|
+
Abrir
|
|
190
|
+
</Button>
|
|
191
|
+
</Box>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Para o elemento semântico (`ul`, `nav`, `section`), continue usando `Stack` com `as`.
|
|
195
|
+
|
|
196
|
+
- d466e57: feat(button): variante `neutral-text` e tamanho `xs`
|
|
197
|
+
|
|
198
|
+
Para barra de ações (editor, filtros, linha de card), onde nenhum botão é a
|
|
199
|
+
ação principal e o azul atrapalha. Sem as props novas, nada muda.
|
|
200
|
+
|
|
201
|
+
- `variant="neutral-text"`: texto cinza (`neutral-dark-down`), sem borda e sem
|
|
202
|
+
fundo; hover em `neutral-light-medium`. O `neutral` continua sendo o
|
|
203
|
+
contornado cinza, então "neutro" cobre os dois: contornado (`neutral`) e
|
|
204
|
+
texto (`neutral-text`). O nome segue o par `negative` / `negative-outlined`.
|
|
205
|
+
- `size="xs"`: 26px de altura, padding lateral 12, fonte 12 e ícone de 12px
|
|
206
|
+
(também no `variant="icon"`, que fica 26 x 26). Os 26px do CrisDoc não estão
|
|
207
|
+
na escala de espaço, então a altura é `calc(spacing-xxs + spacing-micro)`
|
|
208
|
+
(24 + 2), sem token novo.
|
|
209
|
+
|
|
210
|
+
```vue
|
|
211
|
+
<Button
|
|
212
|
+
variant="neutral-text"
|
|
213
|
+
size="xs"
|
|
214
|
+
:start-icon="faPlus"
|
|
215
|
+
>Nova linha</Button>
|
|
216
|
+
<Button variant="neutral" size="xs">Ordenar: mais recentes</Button>
|
|
217
|
+
<Button size="xs">Resolver</Button>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
- d278363: feat(calendar): novo `Calendar`, a agenda com eventos por dia
|
|
221
|
+
|
|
222
|
+
Peça nova: visão de mês e de semana, com eventos por dia, sem biblioteca de
|
|
223
|
+
datas (o `Intl` escreve os nomes de mês e de dia).
|
|
224
|
+
|
|
225
|
+
- `events`: lista plana `{ date, title, color?, time?, id? }`. `date` é
|
|
226
|
+
`YYYY-MM-DD`, data-hora ISO ou `Date`. A grade agrupa por dia e ordena por
|
|
227
|
+
`time`.
|
|
228
|
+
- Cor de DADO por token: `color="--umds-primitive-blue-pure"` (o mesmo valor do
|
|
229
|
+
`ColorPicker`), num chip de fundo suave (a cor a 16% sobre o branco) com barra
|
|
230
|
+
do lado. O texto é sempre escuro: a cor nunca é a única informação e o contraste
|
|
231
|
+
não depende do tom. Sem `color`, o primário.
|
|
232
|
+
- Mês: até `maxVisible` (3) eventos por dia e um "+N" (`onMoreClick(dia,
|
|
233
|
+
escondidos)`). O corte é por QUANTIDADE, não por altura. Semana: sete colunas
|
|
234
|
+
com todos os eventos.
|
|
235
|
+
- Grade acessível (`role="grid"`): um Tab entra no dia em foco (hoje, ou o
|
|
236
|
+
primeiro) e depois nos eventos dele; setas movem de dia (e trocam de mês ou de
|
|
237
|
+
semana na borda), Home e End vão às pontas da semana, PageUp e PageDown trocam
|
|
238
|
+
de mês (ou de semana), Enter e Espaço acionam `onDayClick`. Cada dia tem nome
|
|
239
|
+
("segunda-feira, 11 de maio de 2026, 2 eventos", `dayLabel` troca) e o de hoje
|
|
240
|
+
leva `aria-current="date"`.
|
|
241
|
+
- `date` e `view` controláveis (`onDateChange`, `onViewChange`) ou internos
|
|
242
|
+
(`defaultDate`, `defaultView`); `selectedDate` marca um dia; `today` fixa o
|
|
243
|
+
"hoje" (testes, demonstração); `weekStartsOn` 0 (domingo) ou 1.
|
|
244
|
+
- Cabeçalho com anterior, próximo, "Hoje" e o seletor Mês/Semana
|
|
245
|
+
(`hideViewSwitcher` esconde), mais dois slots: `headerStart` (filtro de escopo)
|
|
246
|
+
e `headerEnd` (legenda). No Vue são `#header-start` e `#header-end`.
|
|
247
|
+
- Textos por prop: `previousLabel`, `nextLabel`, `todayLabel`, `monthLabel`,
|
|
248
|
+
`weekLabel`, `viewLabel`, `moreLabel` (`{count}`), `moreAriaLabel` (`{count}` e
|
|
249
|
+
`{date}`); `locale` (padrão `pt-BR`).
|
|
250
|
+
|
|
251
|
+
Não faz: eixo de horas (é agenda por dia, não por hora), evento que atravessa
|
|
252
|
+
vários dias e arrastar para reagendar.
|
|
253
|
+
|
|
254
|
+
```vue
|
|
255
|
+
<Calendar
|
|
256
|
+
:events="[
|
|
257
|
+
{
|
|
258
|
+
date: '2026-05-04',
|
|
259
|
+
title: 'Proc. Administrativo 002/2020',
|
|
260
|
+
color: '--umds-primitive-blue-pure',
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
date: '2026-05-11',
|
|
264
|
+
title: 'Ofício 001/2020',
|
|
265
|
+
color: '--umds-primitive-red-pure',
|
|
266
|
+
time: '08:00',
|
|
267
|
+
},
|
|
268
|
+
]"
|
|
269
|
+
:onEventClick="abrir"
|
|
270
|
+
>
|
|
271
|
+
<template #header-start><Select … /></template>
|
|
272
|
+
<template #header-end><Button variant="secondary" size="sm">Legenda</Button></template>
|
|
273
|
+
</Calendar>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
- 33719b6: feat(chips): `size="xs"` e × com moldura circular (`circularRemove`)
|
|
277
|
+
|
|
278
|
+
Opt-in; sem as props novas o `Chips` é o mesmo.
|
|
279
|
+
|
|
280
|
+
- `size="xs"`: 20px de altura, padding lateral 8, fonte de 12px e × de 8px. A
|
|
281
|
+
altura é `calc(spacing-xxxs + spacing-quarck)` (16 + 4), sem token novo. O
|
|
282
|
+
CrisDoc usa fonte de 11px, que não está na escala do DS; fica o degrau de 12px.
|
|
283
|
+
- `circularRemove`: o × dos chips removíveis vai dentro de um círculo de 14px
|
|
284
|
+
tingido da cor do texto do chip (o `::before` usa `currentColor` com 15% de
|
|
285
|
+
opacidade, então acompanha todas as variantes e os temas). É o mesmo botão,
|
|
286
|
+
com o mesmo nome acessível ("Remover <rótulo>") e o mesmo clique; só vale com
|
|
287
|
+
`removable`.
|
|
288
|
+
|
|
289
|
+
```vue
|
|
290
|
+
<Chips
|
|
291
|
+
label="Processos Inteligentes"
|
|
292
|
+
size="xs"
|
|
293
|
+
variant="primary"
|
|
294
|
+
removable
|
|
295
|
+
circularRemove
|
|
296
|
+
:onRemove="remover"
|
|
297
|
+
/>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
- 80904af: feat(coachmark): novo `Coachmark`, o tour guiado
|
|
301
|
+
|
|
302
|
+
Peça nova: uma sequência de passos, cada um apontando um elemento da tela com
|
|
303
|
+
um cartão, enquanto o resto da página escurece e o alvo fica destacado num
|
|
304
|
+
recorte (uma caixa transparente cuja sombra escurece o resto, sem máscara nem
|
|
305
|
+
SVG).
|
|
306
|
+
|
|
307
|
+
- `steps`: `{ target?, title, content?, placement? }`. `target` é um seletor CSS
|
|
308
|
+
(`"#aba-fluxos"`), um elemento, uma ref do React (`{ current }`), uma ref do Vue
|
|
309
|
+
(`{ value }`) ou uma função que devolve um deles. Sem alvo (ou alvo que não
|
|
310
|
+
existe), o cartão fica no centro e a página inteira escurece.
|
|
311
|
+
- Posição por `@floating-ui/dom` (já era dependência): `placement` com inversão
|
|
312
|
+
automática, e o recorte e o cartão acompanham rolagem, redimensionamento e
|
|
313
|
+
mudança de tamanho do alvo. O alvo é trazido à tela se estiver fora dela.
|
|
314
|
+
- Controlado por `open`; `onClose(motivo)` com `"finish"` (Concluir no último
|
|
315
|
+
passo), `"skip"` (Sair do tour) ou `"escape"` (Esc). Passo atual interno
|
|
316
|
+
(`defaultStep`) ou controlado (`step` + `onStepChange`). Reabrir recomeça do
|
|
317
|
+
primeiro passo.
|
|
318
|
+
- Acessibilidade: cartão `role="dialog"` com `aria-modal`, nomeado pelo título e
|
|
319
|
+
descrito pelo texto. O foco entra no cartão, o Tab fica preso nele, Esc sai,
|
|
320
|
+
setas esquerda e direita voltam e avançam, e o foco volta ao elemento de antes
|
|
321
|
+
ao fechar. A cada passo o leitor de tela ouve "2 de 8: título" (`aria-live`).
|
|
322
|
+
- Textos por prop: `nextLabel`, `previousLabel`, `finishLabel`, `skipLabel`,
|
|
323
|
+
`counterLabel` ("{current} de {total}"). `hideSkip` esconde o Sair do tour.
|
|
324
|
+
- `padding` (px) é a folga do recorte em torno do alvo (padrão 8).
|
|
325
|
+
|
|
326
|
+
Limite: a página atrás fica inerte durante o tour (o véu captura o clique), então
|
|
327
|
+
o alvo não é clicável. O scrim usa o mesmo `rgba` do Modal, que ainda não tem
|
|
328
|
+
token (candidato a novo token).
|
|
329
|
+
|
|
330
|
+
```vue
|
|
331
|
+
<Coachmark
|
|
332
|
+
:open="tourAberto"
|
|
333
|
+
:steps="[
|
|
334
|
+
{
|
|
335
|
+
target: '#aba-fluxos',
|
|
336
|
+
title: 'Cada item aberto é uma aba',
|
|
337
|
+
content: 'Fluxos e formulários abrem em abas.',
|
|
338
|
+
},
|
|
339
|
+
{ title: 'Pronto', content: 'Sem alvo: o cartão fica no centro.' },
|
|
340
|
+
]"
|
|
341
|
+
:onClose="() => (tourAberto = false)"
|
|
342
|
+
/>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
- 390c707: feat(colorpicker): novo `ColorPicker`, as amostras da paleta do 1DS
|
|
346
|
+
|
|
347
|
+
Peça nova. Uma grade de amostras dos primitivos de cor (6 famílias de 4 tons e os
|
|
348
|
+
7 cinzas, 31 no total), uma linha por família. O valor é o NOME DO TOKEN
|
|
349
|
+
(`--umds-primitive-blue-pure`): guarde o nome e pinte com `var(${valor})`. Como
|
|
350
|
+
primitivo não muda com o tema, a cor escolhida é a mesma no claro e no escuro, o
|
|
351
|
+
que é o certo para cor de dado (marcador, tipo de documento, setor).
|
|
352
|
+
|
|
353
|
+
- `radiogroup`: Tab entra na amostra escolhida (ou na primeira), setas movem a
|
|
354
|
+
escolha, Home e End vão às pontas, amostra desabilitada é pulada. Cada amostra
|
|
355
|
+
tem nome acessível ("Azul escuro") e a escolhida ganha ícone de marcação e anel
|
|
356
|
+
duplo, então a seleção não depende só da cor.
|
|
357
|
+
- `value` / `defaultValue` / `onChange(valor)`; `label` ou `ariaLabel`.
|
|
358
|
+
- `allowCustom` (desligado por padrão): campo de cor livre em hexadecimal
|
|
359
|
+
`#RRGGBB`, que sai em maiúsculas. Textos por prop: `customLabel` e
|
|
360
|
+
`customErrorMessage`.
|
|
361
|
+
- `families` recorta a paleta (`["blue", "gray"]`); `swatches` troca a lista
|
|
362
|
+
inteira (nomes traduzidos, recorte livre). `COLOR_PALETTE` e `isHexColor` saem
|
|
363
|
+
exportados.
|
|
364
|
+
- `size` `sm` (24px) ou `md` (32px, padrão); raio 8px, anel de 1px na amostra.
|
|
365
|
+
|
|
366
|
+
Requer `@1doc/1ds-tokens` com `yellow-light` e `purple-pure` corrigidos (ver o
|
|
367
|
+
changeset `tokens-primitivos-amarelo-roxo`): a paleta lista os 31 primitivos, e
|
|
368
|
+
com o tokens 0.4.3 essas duas amostras saem na cor errada.
|
|
369
|
+
|
|
370
|
+
```vue
|
|
371
|
+
<ColorPicker
|
|
372
|
+
label="Cor do marcador"
|
|
373
|
+
:value="cor"
|
|
374
|
+
:onChange="(c) => (cor = c)"
|
|
375
|
+
allowCustom
|
|
376
|
+
/>
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
- e3d82fc: feat(datatable): célula livre por coluna, linha de grupo e tipos exportados no Vue
|
|
380
|
+
|
|
381
|
+
A `DataTable` passa a aceitar markup na célula nos dois frameworks. API antiga
|
|
382
|
+
intacta: sem as props e slots novos, o HTML e as classes são os mesmos.
|
|
383
|
+
|
|
384
|
+
- Célula livre. No React, `column.render(row, rowIndex)` já devolvia nó e
|
|
385
|
+
continua assim (o docblock agora diz). No Vue, o retorno do `render` continua
|
|
386
|
+
sendo tratado como texto, e a célula com markup vem do slot `#cell-<key>`,
|
|
387
|
+
que recebe `{ row, value, rowIndex }`. Com `render` e slot na mesma coluna, o
|
|
388
|
+
slot vale.
|
|
389
|
+
- Linha de grupo: `rowGroup` (nome do campo ou função `(row, rowIndex) =>
|
|
390
|
+
rótulo`) abre um `<th scope="rowgroup">` que atravessa a tabela antes de cada
|
|
391
|
+
sequência de linhas com o mesmo rótulo. A tabela não reordena: passe `data` já
|
|
392
|
+
ordenada pelo grupo. O conteúdo do grupo é o rótulo, ou `renderRowGroup(label,
|
|
393
|
+
row, rowIndex)` no React, ou o slot `#row-group` (`{ label, row, rowIndex }`)
|
|
394
|
+
no Vue. A linha de grupo não entra na seleção nem no `onRowClick`.
|
|
395
|
+
- Vue (tipos): o `index.d.ts` do pacote passa a trazer todo tipo exportado pelos
|
|
396
|
+
componentes. Antes só saíam as `*Props`, `*Action` e `*Option`, e a `DataTableProps`
|
|
397
|
+
apontava para um `DataTableColumn` que não existia no arquivo. Agora
|
|
398
|
+
`DataTableColumn`, `DropdownItem`, `AccordionItemData` (e os demais, como
|
|
399
|
+
`StackSpacing`, `BoxSpacing` e `ChartDatum`) podem ser importados de
|
|
400
|
+
`@1doc/1ds-vue`. No React eles já eram exportados.
|
|
401
|
+
|
|
402
|
+
```vue
|
|
403
|
+
<DataTable :columns="colunas" :data="usuarios" rowGroup="setor">
|
|
404
|
+
<template #cell-nome="{ row }">
|
|
405
|
+
<Avatar type="letter" size="sm">{{ row.nome[0] }}</Avatar> {{ row.nome }}
|
|
406
|
+
</template>
|
|
407
|
+
<template #cell-setores="{ value }">
|
|
408
|
+
<Tag v-for="setor in value" :key="setor" :label="setor" size="sm" />
|
|
409
|
+
</template>
|
|
410
|
+
<template #row-group="{ label }">Setor {{ label }}</template>
|
|
411
|
+
</DataTable>
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
- a5fe6fe: feat(datatable,descriptionlist): `DataTable variant="document"` e novo `DescriptionList`
|
|
415
|
+
|
|
416
|
+
Para o que é CONTEÚDO de documento (se lê e se imprime), não interface.
|
|
417
|
+
|
|
418
|
+
**`DataTable variant="document"`** (padrão `default`, nada muda sem a prop):
|
|
419
|
+
tabela sem interação, com grade de bordas finas em todas as células, sem hover,
|
|
420
|
+
sem cabeçalho grudado e sem raio. `sortable`, `selectable` e `onRowClick` são
|
|
421
|
+
ignorados: sem botão de ordenar, sem `aria-sort`, sem checkbox, linha fora da
|
|
422
|
+
ordem de Tab. Na impressão (`@media print`) o cabeçalho se repete a cada página,
|
|
423
|
+
uma linha nunca é cortada ao meio e as cores saem (`print-color-adjust`).
|
|
424
|
+
`columns`, `data`, `align`, `width`, `render`/`#cell-<key>` e `density` valem
|
|
425
|
+
como sempre.
|
|
426
|
+
|
|
427
|
+
**`DescriptionList`**, para os pares rótulo/valor (o `DocPares` do CrisDoc não
|
|
428
|
+
cabia na tabela: não tem cabeçalho de coluna). `<dl>` com `<dt>` e `<dd>`:
|
|
429
|
+
|
|
430
|
+
- `items`: `{ label, value, id? }`. Valor vazio mostra "—" (`emptyValue`).
|
|
431
|
+
- `layout="inline"` (padrão): grade de bordas finas, rótulo pintado e sem quebra
|
|
432
|
+
à esquerda, valor à direita; `fit` encolhe até o conteúdo.
|
|
433
|
+
- `layout="stacked"`: rótulo pequeno em cima, valor embaixo, `columns` de 1 a 4
|
|
434
|
+
(vira 1 em tela estreita); `bordered` põe o valor na caixa de um campo
|
|
435
|
+
somente leitura.
|
|
436
|
+
- `ariaLabel` ou `ariaLabelledby`. No Vue o `value` é texto (valor com marcação:
|
|
437
|
+
monte com `Stack` e `Text`).
|
|
438
|
+
|
|
439
|
+
```vue
|
|
440
|
+
<DataTable variant="document" :columns="colunas" :data="itens" />
|
|
441
|
+
<DescriptionList
|
|
442
|
+
ariaLabel="Dados de empenho"
|
|
443
|
+
:items="[
|
|
444
|
+
{ label: 'Empenho', value: '2026NE000184' },
|
|
445
|
+
{ label: 'Valor empenhado', value: 'R$ 51.840,00' },
|
|
446
|
+
]"
|
|
447
|
+
/>
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
- 801c5c2: feat(fileinput): `variant="trigger"`, o seletor aberto por outro controle
|
|
451
|
+
|
|
452
|
+
Para o "Anexar arquivo" de um botão ou o "Alterar foto" de um link, sem a caixa
|
|
453
|
+
de arrastar. Opt-in; `base` e `card` não mudam.
|
|
454
|
+
|
|
455
|
+
- `variant="trigger"`: o conteúdo que você passa (React: `children`; Vue: slot
|
|
456
|
+
padrão) é o gatilho. O clique nele abre o seletor (o clique sobe até o
|
|
457
|
+
envoltório, então o Enter num `Button` também funciona), e `accept`,
|
|
458
|
+
`multiple`, `name`, `files`, `onChange` e `onRemove` funcionam igual. O input
|
|
459
|
+
nativo fica oculto ao lado, fora do Tab (o gatilho é quem recebe o foco) e
|
|
460
|
+
com nome acessível (`label` ou `selectFileLabel`). `disabled` não abre.
|
|
461
|
+
- O `label` visível não aparece no `trigger`: o gatilho é o próprio conteúdo; o
|
|
462
|
+
`label` serve de nome acessível do input.
|
|
463
|
+
- Não há `open()` exposto: o Mitosis não tem como expor método imperativo nos
|
|
464
|
+
dois frameworks. O `trigger` cobre o caso (botão ou link que abre o seletor).
|
|
465
|
+
|
|
466
|
+
```vue
|
|
467
|
+
<FileInput
|
|
468
|
+
variant="trigger"
|
|
469
|
+
accept=".pdf,.docx"
|
|
470
|
+
:multiple="true"
|
|
471
|
+
:onChange="anexar"
|
|
472
|
+
>
|
|
473
|
+
<Button variant="secondary" startIcon="paperclip">Anexar arquivo</Button>
|
|
474
|
+
</FileInput>
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
- 0e89b88: feat(iconpicker): novo `IconPicker`, a grade de ícones com busca
|
|
478
|
+
|
|
479
|
+
Peça nova, sem dependência: os ícones vêm por prop.
|
|
480
|
+
|
|
481
|
+
- `icons`: objetos do Font Awesome importados (`faUser`, `faFolder`...), ou
|
|
482
|
+
`{ icon, label?, keywords? }` quando o nome ou a busca precisam de ajuda. O nome
|
|
483
|
+
de um ícone sem `label` é o `iconName` sem hífen ("file lines"); `iconLabel`
|
|
484
|
+
traduz.
|
|
485
|
+
- O valor é o NOME do ícone (`"user"`, `"file-lines"`): `value`/`defaultValue`,
|
|
486
|
+
`onChange(nome, item)`. Guarde o nome e resolva de volta para o objeto na hora de
|
|
487
|
+
desenhar.
|
|
488
|
+
- `radiogroup`: Tab entra no ícone escolhido (ou no primeiro); setas movem a
|
|
489
|
+
escolha (esquerda e direita um ícone, cima e baixo uma linha: `columns`, padrão
|
|
490
|
+
8), Home e End vão às pontas. O escolhido ganha fundo e borda do primário e
|
|
491
|
+
`aria-checked`.
|
|
492
|
+
- Busca (ligada; `hideSearch` esconde) por nome, rótulo e palavras-chave, sem
|
|
493
|
+
acento nem caixa. A seta para baixo no campo leva à grade, e o número de
|
|
494
|
+
resultados é anunciado (`role="status"`). Sem resultado, mostra `emptyText`.
|
|
495
|
+
- `maxHeight` (px) limita a grade e rola dentro dela; `size` `sm` ou `md`;
|
|
496
|
+
`disabled`.
|
|
497
|
+
- Textos por prop: `searchLabel`, `searchPlaceholder`, `emptyText`, `resultsLabel`
|
|
498
|
+
(`{count}`).
|
|
499
|
+
|
|
500
|
+
```vue
|
|
501
|
+
<IconPicker
|
|
502
|
+
label="Ícone da categoria"
|
|
503
|
+
:icons="[
|
|
504
|
+
faFolder,
|
|
505
|
+
faFileLines,
|
|
506
|
+
{ icon: faBuilding, label: 'Órgão', keywords: ['prefeitura'] },
|
|
507
|
+
]"
|
|
508
|
+
:value="icone"
|
|
509
|
+
:onChange="(nome) => (icone = nome)"
|
|
510
|
+
/>
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
- 4d0cb08: feat(input): `onChange` a cada tecla no Vue, `mask`, `iconRight` e `borderless`
|
|
514
|
+
|
|
515
|
+
- **`onChange` a cada tecla no Vue (paridade com o React).** O campo passa a
|
|
516
|
+
escutar `input` além de `change`. Antes, no Vue, `onChange` só disparava quando
|
|
517
|
+
o campo perdia o foco (o evento `change` nativo). Os dois eventos entram no
|
|
518
|
+
mesmo tratador, que descarta o repetido: no React os dois disparam para o
|
|
519
|
+
mesmo evento nativo, e no Vue o `change` do blur repete o valor que o `input`
|
|
520
|
+
da última tecla já entregou. O resultado é uma chamada por tecla nos dois
|
|
521
|
+
frameworks. Um `change` disparado à mão com valor novo (testes de quem
|
|
522
|
+
consome) também chega. `onBlur` segue sendo o evento de saída do campo.
|
|
523
|
+
Quem contornava o blur no Vue com `@input` por fora pode tirar o contorno.
|
|
524
|
+
- `mask`: `"cpf"`, `"cnpj"`, `"cep"` ou `"phone"` (10 ou 11 dígitos). O valor
|
|
525
|
+
exibido e o que chega em `onChange` já vêm formatados; para só os dígitos,
|
|
526
|
+
`valor.replace(/\D/g, "")`. Aceita só dígitos, limita o tamanho (`maxlength`) e
|
|
527
|
+
abre o teclado numérico no celular (`inputmode="numeric"`). Valor controlado
|
|
528
|
+
só com dígitos também aparece formatado. Cursor: reformatar no meio do texto
|
|
529
|
+
leva o cursor ao fim (suficiente para digitar do início ao fim).
|
|
530
|
+
- `iconRight`: ícone decorativo à direita, `aria-hidden`, sem clique. Para ação,
|
|
531
|
+
continua `iconsRight`.
|
|
532
|
+
- `borderless`: sem borda, fundo e raio, para o campo dentro de um grupo que já
|
|
533
|
+
tem a moldura (um `Select` e um `Input` lado a lado numa caixa). O foco não
|
|
534
|
+
some: vira contorno de 2px para dentro. Com erro, a borda vermelha fica.
|
|
535
|
+
|
|
536
|
+
```vue
|
|
537
|
+
<Input label="CPF" mask="cpf" :onChange="(v) => (cpf = v)" />
|
|
538
|
+
<Input
|
|
539
|
+
ariaLabel="Número"
|
|
540
|
+
placeholder="Número"
|
|
541
|
+
borderless
|
|
542
|
+
fullWidth
|
|
543
|
+
iconRight="search"
|
|
544
|
+
/>
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
- cfb8c4a: feat(kbd,codeblock): novos `Kbd` e `CodeBlock`, e o token de fonte monoespaçada
|
|
548
|
+
|
|
549
|
+
**Token novo** (`@1doc/1ds-tokens`): `--umds-primitive-font-family-mono` e o
|
|
550
|
+
semântico `--umds-semantic-font-family-mono` (`ui-monospace, SFMono-Regular,
|
|
551
|
+
Menlo, Consolas, 'Liberation Mono', monospace`). É a pilha de fontes do sistema:
|
|
552
|
+
nenhuma fonte baixada, então nenhum pedido de rede novo. O produto cita o
|
|
553
|
+
semântico; os dois componentes abaixo já o usam.
|
|
554
|
+
|
|
555
|
+
**`Kbd`**: uma tecla ou uma combinação, em `<kbd>`.
|
|
556
|
+
|
|
557
|
+
- Uma tecla vai como conteúdo (`<Kbd>Esc</Kbd>`); uma combinação em `keys`
|
|
558
|
+
(`["Ctrl", "Shift", "P"]`), com `separator` entre as teclas (padrão `+`). Cada
|
|
559
|
+
tecla é um `<kbd>` dentro do `<kbd>` do conjunto, que é como o HTML diz
|
|
560
|
+
"combinação". O leitor de tela lê "Ctrl + Shift + P".
|
|
561
|
+
- Caixa cinza com borda e base mais grossa, fonte monoespaçada; `size` `sm` ou
|
|
562
|
+
`md`. Raiz única: `title`, `data-*`, `aria-*` e ouvintes chegam ao elemento.
|
|
563
|
+
|
|
564
|
+
**`CodeBlock`**: trecho de código, JSON ou log, com borda, rolagem e cópia.
|
|
565
|
+
|
|
566
|
+
- O texto vem por `code` ou como conteúdo, com espaços e quebras mantidos. Linha
|
|
567
|
+
longa rola na horizontal, ou quebra com `wrap`; `maxHeight` (px) limita a
|
|
568
|
+
altura e rola na vertical.
|
|
569
|
+
- A área de rolagem é `role="region"` focável (Tab) e nomeada (`ariaLabel`, senão
|
|
570
|
+
a `language`, senão "Código"): quem usa o teclado consegue rolar.
|
|
571
|
+
- `copyable` mostra o botão de copiar no cabeçalho: copia o texto inteiro (não só
|
|
572
|
+
o que está à vista), troca para "Copiado" por dois segundos e anuncia ao leitor
|
|
573
|
+
de tela. Usa `navigator.clipboard`, e recorre a `execCommand("copy")` quando ele falha.
|
|
574
|
+
`onCopy(texto)` avisa. `copyLabel` e `copiedLabel` por prop.
|
|
575
|
+
- `language` é só rótulo no topo. Não colore sintaxe (pede uma biblioteca); fundo
|
|
576
|
+
claro e texto escuro nos dois temas.
|
|
577
|
+
|
|
578
|
+
```vue
|
|
579
|
+
<Kbd :keys="['Ctrl', 'K']" size="sm" />
|
|
580
|
+
<CodeBlock language="JSON" :code="envio" copyable />
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
- fcd9c32: feat(list): estado vazio dentro da lista (`isEmpty`)
|
|
584
|
+
|
|
585
|
+
O `List` passa a trazer o estado vazio. Com `isEmpty`, as linhas dão lugar a um
|
|
586
|
+
`EmptyState` DENTRO da lista: o título do cartão, a busca, os filtros e a
|
|
587
|
+
paginação ao redor continuam montados (e o foco no campo de busca não se perde),
|
|
588
|
+
porque só o miolo troca. A lista não conta filhos: `isEmpty` é a decisão de
|
|
589
|
+
quem a usa (`:is-empty="!itens.length"`).
|
|
590
|
+
|
|
591
|
+
- Texto: `emptyTitle` (padrão "Nenhum item encontrado"), `emptyDescription`,
|
|
592
|
+
`emptyIcon` (objeto do Font Awesome), `emptySize` (`sm` padrão, `md`, `lg`).
|
|
593
|
+
- Ação: `emptyActionLabel` com `onEmptyAction`. Sem o callback o botão não
|
|
594
|
+
aparece.
|
|
595
|
+
- Conteúdo próprio: slot `empty` (no React, a prop `empty`) no lugar do
|
|
596
|
+
`EmptyState`.
|
|
597
|
+
- Acessibilidade: o bloco vazio é `role="status"`, então a lista esvaziar é
|
|
598
|
+
anunciada. Sem itens não há `ul` vazia no DOM.
|
|
599
|
+
|
|
600
|
+
```vue
|
|
601
|
+
<List
|
|
602
|
+
ariaLabelledby="titulo"
|
|
603
|
+
:isEmpty="!docs.length"
|
|
604
|
+
emptyTitle="Nenhum documento"
|
|
605
|
+
emptyDescription="Tudo em dia."
|
|
606
|
+
:emptyIcon="faInbox"
|
|
607
|
+
emptyActionLabel="Atualizar"
|
|
608
|
+
@emptyAction="recarregar"
|
|
609
|
+
>
|
|
610
|
+
<ListItem v-for="d in docs" :key="d.id" :title="d.titulo" />
|
|
611
|
+
</List>
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
- 4b57ca7: feat(list): novos `ListItem` e `List`, a linha de lista inteira clicável
|
|
615
|
+
|
|
616
|
+
Peça nova. O `ListItem` é a linha cujo alvo de clique e de foco é a linha
|
|
617
|
+
toda, com conteúdo livre. Renderiza um `<li>` com UM `button`, `a` ou `div`
|
|
618
|
+
dentro, por isso vive num `List` (ou num `ul`/`ol`, como `Stack as="ul"`).
|
|
619
|
+
|
|
620
|
+
- `as`: `button` | `a` | `div`. Sem `as`, vira `a` quando há `href` e `button`
|
|
621
|
+
nos outros casos. `div` é a linha que só mostra; com `onClick` ganha
|
|
622
|
+
role="button", tabindex 0, Enter e Espaço. `target="_blank"` põe
|
|
623
|
+
`rel="noopener noreferrer"` sozinho.
|
|
624
|
+
- Conteúdo: `start`, `title`, `subtitle`, `meta`, `end` e o conteúdo padrão (abaixo
|
|
625
|
+
de `meta`). `title`, `subtitle` e `meta` aceitam texto por prop ou nó por slot.
|
|
626
|
+
No Vue os slots se chamam igual (`#start`, `#title`...); no React são as
|
|
627
|
+
props. Região vazia não desenha nada.
|
|
628
|
+
- Estados: hover e foco visível (anel interno), `selected` (fundo de seleção e
|
|
629
|
+
`aria-current="true"`), `disabled` (button desabilitado; link perde o `href` e
|
|
630
|
+
ganha `aria-disabled`).
|
|
631
|
+
- `id`, `style`, `role`, `tabIndex`, `data-*` e `aria-*` vão para o elemento
|
|
632
|
+
interativo (é nele que entra o `aria-label`). `title` é o título da linha, não
|
|
633
|
+
o atributo HTML.
|
|
634
|
+
- `List`: `ul` (padrão) ou `ol`, sempre com `role="list"` (o Safari tira a
|
|
635
|
+
semântica de `list-style: none`), `gap` na escala do DS (padrão `quarck`),
|
|
636
|
+
`ariaLabel` ou `ariaLabelledby`.
|
|
637
|
+
|
|
638
|
+
Medidas: padding 8 12 (o 10 12 do CrisDoc não existe na escala), raio 8, título
|
|
639
|
+
14/600, subtítulo 14 e meta 12, todos pelo `Text`.
|
|
640
|
+
|
|
641
|
+
```vue
|
|
642
|
+
<List ariaLabel="Documentos não lidos" gap="nano">
|
|
643
|
+
<ListItem selected title="Memorando 114/2025" subtitle="Novo contrato - Governo"
|
|
644
|
+
meta="23 de agosto de 2025" @click="abrir(doc)">
|
|
645
|
+
<template #start><Avatar type="letter" size="sm">I</Avatar></template>
|
|
646
|
+
<template #end><Badge variant="info" size="sm">novo</Badge></template>
|
|
647
|
+
</ListItem>
|
|
648
|
+
</List>
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
- eeb6a16: feat(modal): `variant="primary"`, `width`/`maxWidth`, `windowControls` em lista e `responsive`; o Esc respeita quem já o usou
|
|
652
|
+
|
|
653
|
+
Tudo opt-in; sem as props novas o modal é o mesmo.
|
|
654
|
+
|
|
655
|
+
- `variant="primary"`: cabeçalho cheio na cor primária (título, subtítulo e
|
|
656
|
+
controles em `neutral-light-pure`, hover em `primary-dark`). É o modal base com
|
|
657
|
+
as três faixas, não o diálogo de feedback.
|
|
658
|
+
- `width` e `maxWidth`: qualquer valor CSS. `width` sozinho solta o teto do
|
|
659
|
+
`size` (o 498px do `md` não segura mais) e passa a ser limitado pela tela.
|
|
660
|
+
Com `windowControls`, valem só no modo normal.
|
|
661
|
+
- `windowControls` aceita `true` (o conjunto inteiro, como antes) ou uma lista
|
|
662
|
+
com os controles que quiser: `["expand", "fullscreen"]`. Nomes: `normal`,
|
|
663
|
+
`expand`, `fullscreen`, `minimize`. Em lista, sem `normal`, clicar de novo no
|
|
664
|
+
modo ativo volta ao normal, e o modo normal usa o tamanho do próprio modal
|
|
665
|
+
(não os 780px do conjunto inteiro). O divisor só aparece com algum controle e
|
|
666
|
+
com o ×. `onMinimize` só existe se `minimize` estiver na lista.
|
|
667
|
+
- `responsive` e `responsiveBreakpoint` (padrão 640, lido na montagem): abaixo
|
|
668
|
+
da largura, o modal vira um painel que sobe pela borda de baixo (largura
|
|
669
|
+
total, cantos de cima arredondados, alça, entrada por baixo), como o
|
|
670
|
+
`BottomSheet`; acima, continua centralizado. É o mesmo componente reorganizado
|
|
671
|
+
(não monta um `BottomSheet` por dentro, porque o Mitosis não repassa slot de
|
|
672
|
+
um componente a outro), então não tem o gesto de arrastar. No painel os
|
|
673
|
+
controles de janela e a largura livre somem.
|
|
674
|
+
- Esc: o ouvinte do `document` passa a rodar no borbulho e a ignorar a tecla se
|
|
675
|
+
`defaultPrevented`. `Select`, `Combobox`, `Popover` e `Dropdown` já faziam
|
|
676
|
+
`preventDefault`; `DatePicker` e `MultiSelect` passaram a fazer. Resultado: um
|
|
677
|
+
`Select` ou `DatePicker` aberto dentro do modal fecha só a lista, e o modal
|
|
678
|
+
fica. Quem tinha contorno para isso pode tirá-lo.
|
|
679
|
+
|
|
680
|
+
```vue
|
|
681
|
+
<Modal
|
|
682
|
+
open
|
|
683
|
+
variant="primary"
|
|
684
|
+
width="600px"
|
|
685
|
+
:window-controls="['expand', 'fullscreen']"
|
|
686
|
+
title="Verificar rotas e quilometragem"
|
|
687
|
+
responsive
|
|
688
|
+
>
|
|
689
|
+
...
|
|
690
|
+
</Modal>
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
- 56229f0: feat(orgchart): novo `OrgChart`, o organograma com conectores
|
|
694
|
+
|
|
695
|
+
Peça nova: uma árvore desenhada de cima para baixo, com linhas ligando cada pai
|
|
696
|
+
aos filhos, em que os nós com filhos expandem e recolhem. Sem dependência.
|
|
697
|
+
|
|
698
|
+
- `nodes`: lista de nós raiz `{ id, title, subtitle?, children? }`. Mais de uma
|
|
699
|
+
raiz funciona (floresta).
|
|
700
|
+
- O desenho é calculado, não aninhado (o Mitosis não gera componente recursivo de
|
|
701
|
+
forma confiável): cada nó tem largura e altura fixas (`nodeWidth` 176,
|
|
702
|
+
`nodeHeight` 64, em px), os filhos se distribuem sob o pai (`gapX` 16) e o pai se
|
|
703
|
+
centra sobre eles; um nível desce `gapY` (40). Os conectores são um SVG de uma
|
|
704
|
+
linha por pai. O container rola quando o organograma passa da largura.
|
|
705
|
+
- Visual: a raiz cheia na cor primária, os demais em tom claro; `selectedId` marca
|
|
706
|
+
um nó. O título e o subtítulo cortam com reticências (o texto inteiro vai no
|
|
707
|
+
tooltip).
|
|
708
|
+
- Conteúdo livre do nó: no React `renderNode(nó, { level, expanded })`; no Vue o
|
|
709
|
+
slot `node` com escopo `{ node, level, expanded }` (ligado no `postbuild.js`,
|
|
710
|
+
como o do `DataTable`). O conteúdo precisa caber na caixa do nó.
|
|
711
|
+
- Expandir e recolher: tudo aberto por padrão; `defaultCollapsedIds` (ou
|
|
712
|
+
`collapsedIds` controlado) escolhe o que começa recolhido, e
|
|
713
|
+
`onCollapsedChange(ids)` avisa. O botão +/− no pé do nó é para o mouse.
|
|
714
|
+
- Acessibilidade: `role="tree"` com nós `treeitem` (`aria-level`,
|
|
715
|
+
`aria-posinset`, `aria-setsize`, `aria-expanded`, `aria-selected`). Um Tab entra
|
|
716
|
+
no nó em foco; Baixo vai ao primeiro filho (e abre o nó, se recolhido), Cima ao
|
|
717
|
+
pai, Esquerda e Direita aos irmãos, Home e End ao primeiro e ao último irmão,
|
|
718
|
+
Espaço expande ou recolhe, Enter aciona `onNodeClick`.
|
|
719
|
+
- Textos por prop: `ariaLabel` ("Organograma"), `expandLabel`, `collapseLabel`.
|
|
720
|
+
|
|
721
|
+
Limites do primeiro corte: só de cima para baixo; sem zoom nem arrastar; nó de
|
|
722
|
+
altura variável não cabe (use `nodeHeight` para o maior). Para navegar e escolher
|
|
723
|
+
em hierarquias grandes, o `Tree` é mais denso e acessível.
|
|
724
|
+
|
|
725
|
+
```vue
|
|
726
|
+
<OrgChart :nodes="setores" ariaLabel="Setores da COPIRN" :onNodeClick="abrir">
|
|
727
|
+
<template #node="{ node }"><Avatar size="sm">{{ node.title }}</Avatar></template>
|
|
728
|
+
</OrgChart>
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
- e8453bc: feat(otpinput): novo `OtpInput`, o código de verificação em caixas
|
|
732
|
+
|
|
733
|
+
Peça nova para códigos curtos recebidos por outro canal (autenticação em duas
|
|
734
|
+
etapas, confirmação de e-mail ou telefone).
|
|
735
|
+
|
|
736
|
+
- `length` caixas (6 por padrão). Digitar avança o foco; Backspace apaga e, em
|
|
737
|
+
caixa vazia, volta e apaga a anterior; setas, Home e End movem.
|
|
738
|
+
- Colar o código inteiro em qualquer caixa distribui os caracteres (um pedaço
|
|
739
|
+
entra a partir da caixa atual). O preenchimento automático do SMS também,
|
|
740
|
+
porque a primeira caixa leva `autocomplete="one-time-code"`.
|
|
741
|
+
- Sem buraco: focar uma caixa à frente da primeira vazia manda o foco de volta a
|
|
742
|
+
ela.
|
|
743
|
+
- Valor em string: `value`/`defaultValue`, `onChange(codigo)` a cada mudança e
|
|
744
|
+
`onComplete(codigo)` quando as caixas enchem (uma vez por código novo).
|
|
745
|
+
- `type="numeric"` (padrão, teclado numérico no celular) ou `"alphanumeric"`
|
|
746
|
+
(letras e dígitos, em maiúsculas).
|
|
747
|
+
- Acessibilidade: `role="group"` nomeado por `label` ou `ariaLabel`; cada caixa
|
|
748
|
+
tem nome próprio (`digitLabel`, padrão "Dígito {n} de {total}", traduzível);
|
|
749
|
+
`errorMessage`/`invalid` ligam `aria-invalid` e `aria-describedby`.
|
|
750
|
+
- `size` `sm` ou `md`; foco e erro seguem os tokens de campo.
|
|
751
|
+
|
|
752
|
+
```vue
|
|
753
|
+
<OtpInput
|
|
754
|
+
label="Código de verificação"
|
|
755
|
+
:length="6"
|
|
756
|
+
:onComplete="(codigo) => verificar(codigo)"
|
|
757
|
+
errorMessage="Código inválido ou expirado."
|
|
758
|
+
/>
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
- d89ebe3: feat(popover): `maxHeight` para o corpo do painel
|
|
762
|
+
|
|
763
|
+
- `maxHeight`: altura máxima do corpo, que rola além dela. Número vira px; texto
|
|
764
|
+
vai como CSS (`"60vh"`). `"none"` deixa o corpo crescer com o conteúdo, como
|
|
765
|
+
no painel "Colunas do card" do CrisDoc.
|
|
766
|
+
- Sem a prop, **o teto de 300px continua**: tirá-lo por padrão faria todo painel
|
|
767
|
+
existente com lista longa estourar a tela sem rolagem. Quem quer o corpo livre
|
|
768
|
+
passa `maxHeight="none"`. O cabeçalho e o × não rolam junto, como antes.
|
|
769
|
+
|
|
770
|
+
```vue
|
|
771
|
+
<Popover title="Colunas do card" maxHeight="none" :width="260">
|
|
772
|
+
<Button>Personalizar</Button>
|
|
773
|
+
<template #content>...</template>
|
|
774
|
+
</Popover>
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
- 3c482fa: feat(richtexteditor): novo `RichTextEditor`, texto rico leve sem biblioteca
|
|
778
|
+
|
|
779
|
+
Peça nova, sobre `contenteditable` e `document.execCommand`. Sem dependência
|
|
780
|
+
nova: o primeiro corte é o que as telas de despacho, resposta e descrição de
|
|
781
|
+
serviço pedem.
|
|
782
|
+
|
|
783
|
+
- Ferramentas: negrito, itálico, sublinhado, tachado, lista com marcadores, lista
|
|
784
|
+
numerada, link, desfazer, refazer e limpar formatação. A barra se escolhe por
|
|
785
|
+
`toolbar` (a ordem do array é a da tela, `"|"` é um separador): a padrão traz
|
|
786
|
+
negrito, itálico, sublinhado, listas, link, desfazer e refazer;
|
|
787
|
+
`["bold", "italic", "underline", "ul", "ol", "link"]` é a compacta e
|
|
788
|
+
`["bold", "italic"]` a mínima.
|
|
789
|
+
- `value`/`defaultValue`/`onChange` em HTML. O HTML é SEMPRE higienizado, tanto o
|
|
790
|
+
que entra por `value` quanto o que se cola: ficam só `a`, `b`/`strong`,
|
|
791
|
+
`i`/`em`, `u`, `s`/`strike`/`del`, `ul`, `ol`, `li`, `p`, `br`, `div`, `span`,
|
|
792
|
+
títulos e citação; `script`, `style`, `onerror`, `class` e `javascript:` saem.
|
|
793
|
+
Colar entra como texto puro. Link só aceita `http(s)`, `mailto`, `tel`, caminho
|
|
794
|
+
e âncora, e ganha `rel="noopener noreferrer"`. `sanitizarHtml`, `enderecoSeguro`
|
|
795
|
+
e `normalizarEndereco` vivem em `utils/html-seguro`.
|
|
796
|
+
- A barra é `role="toolbar"` (Tab numa parada só, setas, Home e End entre as
|
|
797
|
+
ferramentas). Negrito, itálico, sublinhado, tachado e as listas são botões de
|
|
798
|
+
liga/desliga (`aria-pressed`) que seguem o cursor. A área é `role="textbox"`
|
|
799
|
+
multilinha, com `label` ou `ariaLabel`, `aria-invalid` e `aria-describedby`
|
|
800
|
+
(`errorMessage`, `helperText`). Ctrl+K abre o link.
|
|
801
|
+
- Link sem modal: um campo logo abaixo da barra (endereço, Aplicar, Remover link,
|
|
802
|
+
Cancelar; Esc fecha). Sem texto escolhido, o endereço vira o texto do link.
|
|
803
|
+
Endereço sem esquema ganha `https://`; endereço perigoso mostra o erro e não
|
|
804
|
+
vira link.
|
|
805
|
+
- `footer` (slot): a assinatura do autor, dentro da moldura; `resizable` e
|
|
806
|
+
`minHeight` (px); `readOnly` (sem barra) e `disabled`; `invalid`.
|
|
807
|
+
- Textos por prop: `placeholder`, `toolbarLabel` e `labels` (parcial: `bold`,
|
|
808
|
+
`italic`, `underline`, `strike`, `ul`, `ol`, `link`, `undo`, `redo`, `clear`,
|
|
809
|
+
`linkAddress`, `linkApply`, `linkRemove`, `linkCancel`, `linkInvalid`).
|
|
810
|
+
|
|
811
|
+
Fora deste corte, por tamanho: tabela, imagem, cor, fonte, tamanho e
|
|
812
|
+
alinhamento. Limite técnico: `document.execCommand` é obsoleto no padrão, mas
|
|
813
|
+
todos os navegadores o mantêm; o histórico do desfazer varia um pouco entre eles.
|
|
814
|
+
|
|
815
|
+
```vue
|
|
816
|
+
<RichTextEditor
|
|
817
|
+
label="Despacho"
|
|
818
|
+
:value="html"
|
|
819
|
+
:onChange="(h) => (html = h)"
|
|
820
|
+
:toolbar="['bold', 'italic', 'underline', '|', 'ul', 'ol', '|', 'link']"
|
|
821
|
+
>
|
|
822
|
+
<template #footer>Ana Paula Souza, SADM</template>
|
|
823
|
+
</RichTextEditor>
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
- b02f4ff: feat(select): `placement` (a lista abre para cima) e variante `filter` com opção "sem filtro" e rodapé
|
|
827
|
+
|
|
828
|
+
Tudo opt-in; sem as props novas o `Select` é o mesmo.
|
|
829
|
+
|
|
830
|
+
- `placement`: `bottom` (padrão), `top` ou `auto`. O `auto` mede o espaço na hora
|
|
831
|
+
de abrir e abre para cima só se a lista (altura estimada, no máximo os 300px
|
|
832
|
+
do CSS) não cabe embaixo e há mais espaço em cima, como o campo no rodapé de
|
|
833
|
+
um modal numa janela baixa. A lista continua dentro do campo (posição
|
|
834
|
+
absoluta), então um contêiner com `overflow` ainda pode cortá-la, igual
|
|
835
|
+
antes.
|
|
836
|
+
- `variant="filter"`: botão de filtro de barra de ferramentas, contornado em
|
|
837
|
+
azul (`primary-pure` sobre `primary-light`), largura do conteúdo, lista de no
|
|
838
|
+
mínimo 240px, busca focada ao abrir. Combina com `searchable`.
|
|
839
|
+
- `emptyOptionLabel`: opção "sem filtro" no topo da lista (seleção única).
|
|
840
|
+
Aparece marcada enquanto nada está escolhido; escolhê-la chama `onChange("")` e
|
|
841
|
+
o campo volta a mostrar o `placeholder`, que é o nome do filtro.
|
|
842
|
+
- `footer`: rodapé fixo da lista, com ações ("Gerenciar marcadores"). React:
|
|
843
|
+
elemento; Vue: slot `footer`. Clicar nele não fecha a lista.
|
|
844
|
+
|
|
845
|
+
```vue
|
|
846
|
+
<Select
|
|
847
|
+
variant="filter"
|
|
848
|
+
size="sm"
|
|
849
|
+
placeholder="Marcadores"
|
|
850
|
+
:searchable="true"
|
|
851
|
+
emptyOptionLabel="Todos os marcadores"
|
|
852
|
+
:options="marcadores"
|
|
853
|
+
:value="filtro"
|
|
854
|
+
:onChange="(v) => (filtro = v)"
|
|
855
|
+
placement="auto"
|
|
856
|
+
>
|
|
857
|
+
<template #footer><Button variant="text" size="sm">Gerenciar marcadores</Button></template>
|
|
858
|
+
</Select>
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
- e45ce94: feat(stack): `gap="none"`, prop `as`, props de item flex e atributos HTML
|
|
862
|
+
|
|
863
|
+
O `Stack` passa a cobrir o que o produto ainda escrevia em CSS próprio. API
|
|
864
|
+
antiga intacta: sem as props novas, o HTML e as classes são os mesmos.
|
|
865
|
+
|
|
866
|
+
- `gap="none"` zera o espaço (antes só havia os degraus da escala).
|
|
867
|
+
- `as`: `div` (padrão), `span`, `ul`, `ol`, `li`, `section`, `nav`, `header`,
|
|
868
|
+
`footer`, `form`. `ul` e `ol` saem sem marcador, margem e recuo, com
|
|
869
|
+
`role="list"` (o Safari tira a semântica de lista de `list-style: none`).
|
|
870
|
+
Com `as="form"`, `onSubmit` recebe o evento.
|
|
871
|
+
- Atributos HTML (`id`, `style`, `title`, `role`, `tabIndex`, `data-*`,
|
|
872
|
+
`aria-*`) vão para o elemento raiz. Sem isso `as="nav"` não tinha como levar
|
|
873
|
+
`aria-label`.
|
|
874
|
+
- Props do próprio Stack como item de outro Stack/flex: `grow`, `shrink`
|
|
875
|
+
(`"0"` | `"1"`), `basis` (`"auto"`, `"0"`, `"25"`, `"33"`, `"50"`, `"66"`,
|
|
876
|
+
`"75"`, `"100"`; os números são %), `minWidth` (`"0"` | `"auto"`; o Stack
|
|
877
|
+
já nasce com `min-width: 0`), `overflow`, `overflowX`, `overflowY`,
|
|
878
|
+
`fullHeight` e `fullWidth`.
|
|
879
|
+
|
|
880
|
+
Decisão: não existe `Stack.Item`. Quem precisa crescer, encolher ou ocupar a
|
|
881
|
+
altura aninha um Stack com as mesmas props. Subcomponente por ponto não
|
|
882
|
+
sobrevive aos dois geradores do Mitosis, e o Stack aninhado já é um item flex.
|
|
883
|
+
|
|
884
|
+
```tsx
|
|
885
|
+
<Stack as="nav" aria-label="Atalhos" fullHeight>
|
|
886
|
+
<Stack as="ul" gap="none">
|
|
887
|
+
<Stack as="li">...</Stack>
|
|
888
|
+
</Stack>
|
|
889
|
+
<Stack grow overflowY="auto">
|
|
890
|
+
...
|
|
891
|
+
</Stack>
|
|
892
|
+
<Stack shrink="0">...</Stack>
|
|
893
|
+
</Stack>
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
- 1d59843: feat(statcard): `labelPosition="top"` e `infoTooltip`
|
|
897
|
+
|
|
898
|
+
Opt-in; sem as props novas o `StatCard` é o mesmo.
|
|
899
|
+
|
|
900
|
+
- `labelPosition="top"`: o rótulo vai para o topo do cartão, acima do ícone e do
|
|
901
|
+
número, e o número passa a 32/800 (o degrau `font-size-lg` do DS), como no
|
|
902
|
+
painel da 1Doc. Só a posição visual muda: no HTML o número continua antes do
|
|
903
|
+
rótulo, então o leitor de tela anuncia na mesma ordem. Por baixo, o corpo vira
|
|
904
|
+
`display: contents` e o cartão uma grade de duas colunas.
|
|
905
|
+
- `infoTooltip`: texto de ajuda; mostra um ⓘ ao lado do rótulo com o `Tooltip`
|
|
906
|
+
`dark`. É um botão focável (`infoLabel` traduz o nome, "Mais informações" por
|
|
907
|
+
padrão) e a ajuda chega ao leitor de tela como descrição do botão. Dentro de
|
|
908
|
+
um cartão com `onClick` seria botão dentro de botão: evite a combinação.
|
|
909
|
+
|
|
910
|
+
```vue
|
|
911
|
+
<StatCard
|
|
912
|
+
labelPosition="top"
|
|
913
|
+
:value="44"
|
|
914
|
+
label="Não lidos"
|
|
915
|
+
:icon="faEyeSlash"
|
|
916
|
+
variant="primary"
|
|
917
|
+
infoTooltip="Documentos que você ainda não abriu."
|
|
918
|
+
/>
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
- 3d6dd1d: feat(tabs): contador em pílula (`count`) e aba fechável (`closable`) com botão "+" (`onAdd`)
|
|
922
|
+
|
|
923
|
+
Tudo opt-in. Sem as props novas, a aba e a barra se comportam como antes (cada
|
|
924
|
+
`Tab` ganha um `<span role="presentation">` com `display: contents`, que não
|
|
925
|
+
muda o layout, e o `Tabs` ganha uma `div` de barra com o mesmo comportamento).
|
|
926
|
+
|
|
927
|
+
**Tab**
|
|
928
|
+
|
|
929
|
+
- `count` (número ou texto): pílula de 18px ao lado do texto, azul na aba ativa
|
|
930
|
+
(`primary-pure`) e cinza nas outras (`neutral-light-medium`). O `0` aparece. O
|
|
931
|
+
número entra no nome acessível da aba ("Todas 31").
|
|
932
|
+
- `closable`: × num botão próprio, irmão da aba (não dentro dela, para não
|
|
933
|
+
aninhar botão), círculo de 20px. A tecla Delete na aba focada faz o mesmo.
|
|
934
|
+
O × não é uma parada de Tab (a aba já tem o Delete); tem nome "Fechar <aba>".
|
|
935
|
+
- `onClose(index, event)`: quem remove a aba é o app. Clicar no × não troca de aba.
|
|
936
|
+
- `closeLabel`: prefixo do nome acessível do ×, para traduzir ("Close Doc 1").
|
|
937
|
+
|
|
938
|
+
**Tabs**
|
|
939
|
+
|
|
940
|
+
- `onAdd(event)`: mostra o "+" logo depois da última aba, **fora** do
|
|
941
|
+
`role="tablist"` (o tablist só pode ter abas). `addLabel` traduz o nome
|
|
942
|
+
("Adicionar aba" por padrão).
|
|
943
|
+
|
|
944
|
+
```vue
|
|
945
|
+
<Tabs
|
|
946
|
+
:value="atual"
|
|
947
|
+
:onChange="mudar"
|
|
948
|
+
:onAdd="adicionar"
|
|
949
|
+
addLabel="Adicionar aba"
|
|
950
|
+
>
|
|
951
|
+
<Tab label="Todas" index="0" :count="31" />
|
|
952
|
+
<Tab v-for="a in abas" :key="a.id" :label="a.nome" :index="a.id"
|
|
953
|
+
:closable="true" closeLabel="Fechar" :onClose="fechar" />
|
|
954
|
+
</Tabs>
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
Ficou de fora desta rodada: o ponto
|
|
958
|
+
de estado da aba (a bolinha ao lado do nome); a rolagem horizontal das abas já existia.
|
|
959
|
+
|
|
960
|
+
- 96e752b: feat(tooltip): `variant="dark"` compacto e `maxWidth`
|
|
961
|
+
|
|
962
|
+
Opt-in; sem as props novas o `Tooltip` é o mesmo.
|
|
963
|
+
|
|
964
|
+
- `variant="dark"`: balão escuro e compacto (padding 4/8, raio 4, teto de 220px)
|
|
965
|
+
para ícone, sigla e botão de barra de ferramentas. Fundo `background-dark` e
|
|
966
|
+
texto `neutral-light-pure`: o par invertido do tema, então o contraste vale nos
|
|
967
|
+
temas claros, no escuro e no alto contraste (sem cor fixa). A fonte é a de
|
|
968
|
+
12px do DS (o CrisDoc usa 11px, que não está na escala). A seta acompanha a cor.
|
|
969
|
+
- `maxWidth`: largura máxima do balão, qualquer valor CSS, vence o teto de cada
|
|
970
|
+
variante (280px no padrão, 220px no dark).
|
|
971
|
+
|
|
972
|
+
```vue
|
|
973
|
+
<Tooltip variant="dark" content="Atualizar" maxWidth="200px">
|
|
974
|
+
<Button variant="neutral-text" size="xs">Atualizar</Button>
|
|
975
|
+
</Tooltip>
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
### Patch Changes
|
|
979
|
+
|
|
980
|
+
- 2259459: fix(ailabel): `defaultOpen` passa a funcionar
|
|
981
|
+
|
|
982
|
+
A prop era declarada e documentada, mas nunca lida. Agora o painel nasce
|
|
983
|
+
aberto com `defaultOpen` (também no HTML do servidor) e o clique continua
|
|
984
|
+
abrindo e fechando. `open` controlado segue vencendo.
|
|
985
|
+
|
|
986
|
+
- e00b163: fix(combobox): placeholder do campo somente leitura passa 4,5:1
|
|
987
|
+
|
|
988
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
989
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
990
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
991
|
+
|
|
992
|
+
- 19ff160: fix(datepicker): placeholder do campo somente leitura passa 4,5:1
|
|
993
|
+
|
|
994
|
+
Sobre o fundo de somente leitura o placeholder dava 4,2:1 nos temas claros e
|
|
995
|
+
o axe reprovava (`color-contrast`). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
996
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
997
|
+
|
|
998
|
+
- 9315dd7: fix(datepicker): `value` e `defaultValue` chegam ao campo no modo single
|
|
999
|
+
|
|
1000
|
+
No modo single o componente só lia `range`: `value` e `defaultValue` eram
|
|
1001
|
+
ignorados e o campo mostrava o placeholder. Agora `value` controla o campo e
|
|
1002
|
+
`defaultValue` semeia o modo não-controlado. O modo range não muda.
|
|
1003
|
+
|
|
1004
|
+
- 2250bb4: fix(input): placeholder do campo somente leitura passa 4,5:1
|
|
1005
|
+
|
|
1006
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1007
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1008
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1009
|
+
|
|
1010
|
+
- ef321dc: fix(kanban): quadro não faz a página rolar na horizontal em tela estreita
|
|
1011
|
+
|
|
1012
|
+
O texto só para leitor de tela de cada coluna é `position: absolute` e, sem
|
|
1013
|
+
ancestral posicionado, escapava da rolagem do quadro: a 375px a página ganhava
|
|
1014
|
+
rolagem lateral. `.umds-kanban` passa a ser `position: relative`; o visual não
|
|
1015
|
+
muda.
|
|
1016
|
+
|
|
1017
|
+
- 978ad95: fix(multiselect): placeholder do campo somente leitura passa 4,5:1
|
|
1018
|
+
|
|
1019
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1020
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1021
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1022
|
+
|
|
1023
|
+
- 31d3005: fix(a11y): Select, MultiSelect e SegmentedControl com nome acessível no HTML do servidor
|
|
1024
|
+
|
|
1025
|
+
O id automático desses componentes só nasce no `onMount`, e o nome acessível
|
|
1026
|
+
vinha de `aria-labelledby` apontando para ele: no HTML do servidor, e até a
|
|
1027
|
+
hidratação, o combobox (e os radios do SegmentedControl) ficavam sem nome
|
|
1028
|
+
(axe `aria-input-field-name`). Enquanto não há id, o nome sai do texto do
|
|
1029
|
+
label via `aria-label`; depois do mount volta ao `aria-labelledby`. Servidor e
|
|
1030
|
+
primeira renderização do cliente continuam idênticos. Sem mudança visual.
|
|
1031
|
+
|
|
1032
|
+
- 7f58f04: fix(phoneinput): placeholder do campo somente leitura passa 4,5:1
|
|
1033
|
+
|
|
1034
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1035
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1036
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1037
|
+
|
|
1038
|
+
- 98e9bf0: fix(select): placeholder do campo somente leitura passa 4,5:1
|
|
1039
|
+
|
|
1040
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1041
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1042
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1043
|
+
|
|
1044
|
+
- c33298c: fix(stack,box): raiz única no Vue, repassa ouvintes e atributos
|
|
1045
|
+
|
|
1046
|
+
No Vue, `Stack` e `Box` saíam com raiz em FRAGMENTO: o Mitosis gera um
|
|
1047
|
+
`<template v-if="elementTag === ...">` por tag, e o Vue não repassa atributo nem
|
|
1048
|
+
ouvinte a um componente de raiz múltipla. Só sobrevivia uma lista fixa
|
|
1049
|
+
(`data-*`, `aria-*`, `style`, `class`, `title`, `role`, `tabIndex`). No 2.8.0
|
|
1050
|
+
publicado a raiz era um `<div>` único e o Vue repassava tudo, então foi uma
|
|
1051
|
+
regressão silenciosa das props novas (`as`, `gap="none"`...).
|
|
1052
|
+
|
|
1053
|
+
Descartados em silêncio, antes desta correção:
|
|
1054
|
+
|
|
1055
|
+
- ouvintes: `@click`, `@keydown`, `@dragstart`, `@drop`, `@paste`, `@mousedown`...
|
|
1056
|
+
- atributos fora da lista: `tabindex` (minúsculo), `draggable`...
|
|
1057
|
+
- `v-show` e o `$el` do `ref` do componente (apontavam para o nó de âncora do
|
|
1058
|
+
fragmento, não para o elemento).
|
|
1059
|
+
|
|
1060
|
+
Agora o template gerado é um `<component :is="elementTag">` só (ligado no
|
|
1061
|
+
`postbuild.js`, como o do `DataTable`), e o fallthrough do Vue leva ao elemento
|
|
1062
|
+
tudo o que o consumidor passa. Continuam como estavam: `as` com as 10 tags,
|
|
1063
|
+
`role="list"` em `ul`/`ol` (o `role` do consumidor vence), `onSubmit` do
|
|
1064
|
+
`as="form"`, `id`, `style` e `className`. O React não muda.
|
|
1065
|
+
|
|
1066
|
+
Novo teste do pacote Vue, `stack-box-raiz-unica.test.mjs`, que monta o
|
|
1067
|
+
componente num DOM (jsdom) e dispara os eventos. O helper `dom.mjs` serve para
|
|
1068
|
+
qualquer teste de comportamento no Vue; não adiciona dependência (usa o jsdom do
|
|
1069
|
+
pacote React e o `vue/compiler-sfc`).
|
|
1070
|
+
|
|
1071
|
+
Outros componentes do 1DS com raiz em fragmento têm o mesmo limite (ex.: `List`,
|
|
1072
|
+
quando troca entre vazio e `ul`/`ol`); este changeset trata só `Stack` e `Box`.
|
|
1073
|
+
|
|
1074
|
+
- 81cb08e: fix(textarea): placeholder do campo somente leitura passa 4,5:1
|
|
1075
|
+
|
|
1076
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1077
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1078
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1079
|
+
|
|
1080
|
+
- f7645bf: fix(timepicker): placeholder do campo somente leitura passa 4,5:1
|
|
1081
|
+
|
|
1082
|
+
Sobre o fundo de somente leitura o placeholder dava 4,20:1 no 1doc (e
|
|
1083
|
+
4,21–4,31:1 nos temas claros de cor). Agora usa `neutral-dark-down`: 6,78:1 no
|
|
1084
|
+
1doc, 10,83:1 no 1doc-dark e 16,48:1 no alto contraste.
|
|
1085
|
+
|
|
1086
|
+
- 0fc7a82: fix(vue): `Text`, `Grid` e `Logo` repassam `title`, `style` e `aria-*`; `Button` e `DataTable` param de sujar o DOM
|
|
1087
|
+
|
|
1088
|
+
Quatro defeitos que só existiam no Vue gerado (o React estava certo):
|
|
1089
|
+
|
|
1090
|
+
- `Text`, `Grid` e `Logo` descartavam `title`, `style`, `aria-*` e `data-*`. O
|
|
1091
|
+
laço `for (k in props)` do `htmlAttrs` compilava para `props.props`, que não
|
|
1092
|
+
existe. O passo `postbuild` do core passa a ler `props` e `useAttrs()` (o que
|
|
1093
|
+
não está declarado na interface chega por `attrs`, não por `props`). Nos
|
|
1094
|
+
`.lite.tsx` de `Text` e `Grid` o getter `style` virou `estiloInline`: o Mitosis
|
|
1095
|
+
trocava toda ocorrência da palavra por `style.value` e o estilo do
|
|
1096
|
+
consumidor deixava de passar.
|
|
1097
|
+
- `DataTable` escrevia a classe `umds-datatable__row--selected.value`. O getter
|
|
1098
|
+
`selected` colidia com a palavra dentro da string; virou `selectedIndexes`.
|
|
1099
|
+
- `Button` escrevia `autofocus="false"`. `autoFocus` só vai ao DOM quando
|
|
1100
|
+
verdadeiro.
|
|
1101
|
+
- Tipos do Vue: `setTheme`, `getTheme`, `initTheme`, `getAvailableThemes` e
|
|
1102
|
+
`onThemeChange` estavam tipados com `'light' | 'dark' | 'system'`. Agora
|
|
1103
|
+
`Theme` e `ThemeName` são lidos de `core/src/utils/theme.ts` (`'1doc'`,
|
|
1104
|
+
`'1doc-dark'`, `'1doc-high-contrast'`...), e `registerTheme` foi declarado.
|
|
1105
|
+
|
|
1106
|
+
Testes: `pnpm --filter @1doc/1ds-vue test` (novo, `node:test` com SSR, sem
|
|
1107
|
+
dependência nova) e `AtributosRepassados.test.tsx` no React.
|
|
1108
|
+
|
|
1109
|
+
## 2.8.0
|
|
1110
|
+
|
|
1111
|
+
### Minor Changes
|
|
1112
|
+
|
|
1113
|
+
- 450dfb6: feat(core): rótulos traduzíveis em 22 componentes
|
|
1114
|
+
|
|
1115
|
+
Todo texto em português que estava fixo no código — visível ou lido pelo
|
|
1116
|
+
leitor de tela — ganhou prop. Sem a prop, nada muda: o padrão é o português de
|
|
1117
|
+
antes, byte a byte. Com ela, um produto em outro idioma deixa de mostrar ou ler
|
|
1118
|
+
português.
|
|
1119
|
+
|
|
1120
|
+
- `AILabel`: `sourcesLabel`, `notIncludedLabel`.
|
|
1121
|
+
- `AIContent`: `label`, `ariaLabel`, `explanationTitle`, `sourcesLabel`,
|
|
1122
|
+
`notIncludedLabel` (repassados ao selo interno, que antes não recebia nenhum).
|
|
1123
|
+
- `AppSidebar`: `expandLabel`, `collapseLabel`.
|
|
1124
|
+
- `AttachmentCard`: `statusContextLabel`, `requiredLabel`, `copyLabel`,
|
|
1125
|
+
`copiedLabel`, `copyErrorLabel`.
|
|
1126
|
+
- `AvatarGroup`: `overflowAriaLabel`, `overflowTitle`.
|
|
1127
|
+
- `BottomSheet`: `grabberLabel`.
|
|
1128
|
+
- `BarChart` e `LineChart`: `categoryLabel`, `valuesListLabel`, `typeLabel`.
|
|
1129
|
+
- `Chips`: `removeAriaLabel`.
|
|
1130
|
+
- `ConfirmDialog`: `loadingLabel`.
|
|
1131
|
+
- `ConfirmAIAction`: `irreversibleLabel`, `typePhraseLabel`, `phraseMatchedLabel`,
|
|
1132
|
+
`phrasePendingLabel`, `loadingLabel`. O `impactLabel` agora também troca o
|
|
1133
|
+
título visível do bloco (antes só o nome acessível da lista).
|
|
1134
|
+
- `DataTable`: `selectAllLabel`, `selectRowLabel`.
|
|
1135
|
+
- `DatePicker`: `dialogLabel`, `dayLabel`.
|
|
1136
|
+
- `FileInput`: `selectFileLabel`, `triggerLabel`, `triggerHint`, `maxSizeLabel`,
|
|
1137
|
+
`dropLabel`, `orLabel`, `browseLabel`, `removeAriaLabel`, `uploadingAriaLabel`.
|
|
1138
|
+
- `Input`: `showPasswordLabel`, `hidePasswordLabel`.
|
|
1139
|
+
- `Kanban`: `announcements` (objeto com as frases do `aria-live`),
|
|
1140
|
+
`assigneeLabel`, `tagsLabel`, `cardRoleDescription`, `columnCountLabel`.
|
|
1141
|
+
- `KanbanCard`: `assigneeLabel`. `KanbanColumn`: `countLabel`.
|
|
1142
|
+
- `Pagination`: `ofLabel`, `itemRangeLabel`, `pageLabel`.
|
|
1143
|
+
- `PhoneInput`: `countryNames`, `copyLabel`, `copyTitle`, `copiedLabel`.
|
|
1144
|
+
- `Stepper`: `completedLabel`, `activeLabel`, `errorLabel`, `pendingLabel`.
|
|
1145
|
+
- `TimePicker`: `hourUnitLabel`, `minuteUnitLabel`, `secondUnitLabel`.
|
|
1146
|
+
|
|
1147
|
+
Texto com variável segue o que o DS já fazia: prefixo em string quando o texto
|
|
1148
|
+
é "verbo + nome" (como o `removeAriaLabel` do `MultiSelect`), função quando há
|
|
1149
|
+
número ou a ordem das palavras muda de idioma para idioma (como o
|
|
1150
|
+
`positionLabel` do `Podium`).
|
|
1151
|
+
|
|
1152
|
+
### Patch Changes
|
|
1153
|
+
|
|
1154
|
+
- 5f84c72: fix(alert): só `negative` interrompe o leitor de tela
|
|
1155
|
+
|
|
1156
|
+
O Alert usava `role="alert"` (assertivo) em toda variante, e um aviso
|
|
1157
|
+
informativo ou de sucesso cortava o que o leitor de tela estava lendo. Agora
|
|
1158
|
+
`negative` segue com `role="alert"` + `aria-live="assertive"`, e `positive`,
|
|
1159
|
+
`info` e `neutral` passam a `role="status"` + `aria-live="polite"` — a mesma
|
|
1160
|
+
regra do Toast. Sem mudança visual e sem mudança de API.
|
|
1161
|
+
|
|
1162
|
+
- 60a225c: fix(app-header): itens de navegação que não cabem vão para o menu "Mais" em vez de serem recortados. O último item cortado ficava com ~13px de alvo clicável (WCAG 2.5.8). O botão usa o `Dropdown` do DS (`aria-haspopup`, `aria-expanded`, setas, Esc devolve o foco), o item ativo continua na barra sempre que couber, e o rótulo é configurável por `moreLabel` (padrão "Mais"). A medição roda só no navegador, depois de montar (ResizeObserver + MutationObserver).
|
|
1163
|
+
- 1dd44c4: fix(app-nav-item): o item de navegação do cabeçalho ganha área clicável mínima de 24×24px (WCAG 2.5.8) sem padding nem fundo — só a caixa do botão cresce, centralizada.
|
|
1164
|
+
- ffd6692: fix(app-shell): a região de conteúdo (`<main>`) passa a receber foco por teclado (`tabindex="0"`) para rolar pelas setas, com nome acessível configurável na prop nova `contentLabel` (padrão "Conteúdo principal") e foco visível canônico. Resolve o `scrollable-region-focusable` do axe (WCAG 2.1.1).
|
|
1165
|
+
- 35e9f76: fix(attachment-card): no Vue, abrir o painel de conferência por clique ou teclado agora leva o foco para dentro dele, como no React. O foco esperava um `onUpdate` do cartão que o Vue não dispara (quem re-renderiza é o Portal), e passou a ser feito também um quadro depois do painel se posicionar.
|
|
1166
|
+
- 2e610fa: fix(badge): o ícone do Badge não depende mais da ordem de carga do CSS — a regra do SVG ganhou especificidade (`.umds-badge .umds-badge__icon svg`) e deixa de perder para `.umds-icon svg` quando o CSS do Icon chega depois (voltava a 12px, deslocado).
|
|
1167
|
+
- b17859f: fix(bottomsheet): painel nunca sai sem nome acessível
|
|
1168
|
+
|
|
1169
|
+
BottomSheet sem `title`, `ariaLabel` e `ariaLabelledby` saía com
|
|
1170
|
+
`role="dialog"` anônimo. Agora cai no genérico "Painel", como o Drawer, e as
|
|
1171
|
+
props `ariaLabel`/`ariaLabelledby` ganham JSDoc. Sem mudança visual nem de API.
|
|
1172
|
+
|
|
1173
|
+
- 75dde22: fix(confirm-dialog): prop `confirmDisabled`; ConfirmAIAction usa em risco alto
|
|
1174
|
+
|
|
1175
|
+
`ConfirmDialog` ganha `confirmDisabled?: boolean`, que desabilita o botão de
|
|
1176
|
+
confirmar sem o estado de carregamento do `confirmLoading`. O
|
|
1177
|
+
`ConfirmAIAction` passa a usá-la: em risco alto o botão fica desabilitado até
|
|
1178
|
+
a frase digitada conferir (antes continuava clicável e só o handler
|
|
1179
|
+
bloqueava). A mensagem `aria-live` passa a dizer que o botão foi liberado.
|
|
1180
|
+
|
|
1181
|
+
- 3a124aa: fix(core): o CSS do próprio core passa no `@1doc/1ds-lint`
|
|
1182
|
+
|
|
1183
|
+
Raio e espaço fora da escala viraram token: raio 6px/5px/4px → 8px canônico
|
|
1184
|
+
(AppHeader, SidePanel, SidePanelItem, SidePanelSearch, SidePanelSection), 100px
|
|
1185
|
+
e 12px de contador → pill, 2px → `border-radius-xxs`/`spacing-micro`; espaços
|
|
1186
|
+
20/18/14/10/9/6/3px → degrau mais próximo da escala (AppHeader, AppNavItem,
|
|
1187
|
+
Modal base, SidePanel e filhos). Há mudança de poucos pixels nesses componentes.
|
|
1188
|
+
Onde não existe token equivalente (overlays `rgba`, escurecimento com `black`,
|
|
1189
|
+
raio 3px da caixa do Checkbox, compensações de -5px/-3px/1.5px), o literal
|
|
1190
|
+
continua com `stylelint-disable-next-line` justificado.
|
|
1191
|
+
|
|
1192
|
+
- 4d50df8: fix(dropdown): teclado do menu igual no React e no Vue
|
|
1193
|
+
|
|
1194
|
+
No React, as setas levavam o foco para o item que estava ativo antes da tecla,
|
|
1195
|
+
e o End marcava o penúltimo item. A navegação lia o índice ativo logo depois de
|
|
1196
|
+
escrevê-lo: no Vue o valor muda na hora, no React gerado a leitura vinha do
|
|
1197
|
+
render anterior. Agora o próximo índice é calculado por uma função pura e o foco
|
|
1198
|
+
vai para o índice calculado, lido do item focado no DOM. Nos dois frameworks:
|
|
1199
|
+
ArrowDown/ArrowUp movem (com volta nas pontas e pulando item desabilitado),
|
|
1200
|
+
Home/End vão ao primeiro/último, Enter/Espaço ativam, Esc fecha e devolve o foco
|
|
1201
|
+
ao gatilho. Sem mudança visual e sem mudança de API.
|
|
1202
|
+
|
|
1203
|
+
- 11935a0: fix(field): borda do campo em repouso passa o WCAG 1.4.11
|
|
1204
|
+
|
|
1205
|
+
`--umds-semantic-field-border-default` deixa `neutral-light-down` (#D5D5D5,
|
|
1206
|
+
1,47:1 sobre branco) e passa a `neutral-dark-medium` (#7D7D7D no tema claro,
|
|
1207
|
+
4,12:1). Passa 3:1 nos 13 temas, sobre `background-white` e `background-light`.
|
|
1208
|
+
Input, Select, MultiSelect, Textarea, Combobox, FileInput e o somente-leitura
|
|
1209
|
+
de PhoneInput passam a ler o token (antes escreviam o primitivo semântico
|
|
1210
|
+
direto); DatePicker, TimePicker e PhoneInput já liam. Desabilitado continua em
|
|
1211
|
+
`neutral-light-down`. Mudança visual: a borda de todo campo fica mais escura.
|
|
1212
|
+
|
|
1213
|
+
- fc3a622: fix(file-input): o texto de ajuda (`helperText`) e o subtítulo do card do `FileInput` passam de `neutral-dark-medium` (#7D7D7D, 4,11:1) para `neutral-dark-down` (#565656, 7,34:1) — a mesma cor do texto de ajuda do `Input` — e atingem o contraste mínimo do WCAG 1.4.3.
|
|
1214
|
+
- 6754524: fix(modal): prop `ariaLabel` para modal sem título
|
|
1215
|
+
|
|
1216
|
+
Modal sem `title` saía com `role="dialog"` anônimo. Nova prop `ariaLabel`
|
|
1217
|
+
nomeia o diálogo quando não há título (`aria-label`); com título, segue o
|
|
1218
|
+
`aria-labelledby` apontando para ele e `ariaLabel` é ignorado. Sem nenhum dos
|
|
1219
|
+
dois, o diálogo cai no genérico "Diálogo" em vez de sair sem nome (axe
|
|
1220
|
+
aria-dialog-name), como o Drawer já faz com "Painel". Sem mudança visual.
|
|
1221
|
+
|
|
1222
|
+
- 0d31b59: fix(modal): a descrição do Modal base passa de `neutral-dark-medium` (#7D7D7D, 4,11:1) para `neutral-dark-down` (#565656, 7,34:1) e atinge o contraste mínimo do WCAG 1.4.3 em todos os temas.
|
|
1223
|
+
- e80374d: fix(multiselect): mensagem de erro e texto de apoio ligados ao campo
|
|
1224
|
+
|
|
1225
|
+
O foco do MultiSelect cai no trigger `role="combobox"`, e nada ligava a ele a
|
|
1226
|
+
mensagem de erro nem o `helperText`/`description`: o leitor de tela anunciava
|
|
1227
|
+
o campo e nunca o motivo do erro. Agora o combobox recebe `aria-describedby`
|
|
1228
|
+
(erro primeiro, apoio depois, como no Input) e `aria-invalid` quando há
|
|
1229
|
+
`invalid` ou `errorMessage`.
|
|
1230
|
+
|
|
1231
|
+
Os ids automáticos deixam de ser sorteados na inicialização do componente,
|
|
1232
|
+
o que fazia servidor e cliente gerarem ids diferentes e quebrava a hidratação
|
|
1233
|
+
SSR. O id automático nasce no `onMount`; quem precisa dos ids já no HTML do
|
|
1234
|
+
servidor passa a prop `id`, da qual todos derivam.
|
|
1235
|
+
|
|
1236
|
+
- c8d9356: fix(segmented-control): id estável entre servidor e cliente
|
|
1237
|
+
|
|
1238
|
+
O id automático era sorteado na inicialização do componente, então servidor
|
|
1239
|
+
e cliente geravam ids diferentes: a hidratação SSR divergia e o `for` dos
|
|
1240
|
+
rótulos, o `name` dos radios e o `aria-labelledby` do grupo saíam trocados.
|
|
1241
|
+
Nova prop `id`, da qual todos os ids internos derivam (e o `name`, quando não
|
|
1242
|
+
informado). Sem ela, o id automático nasce no `onMount`, só no navegador.
|
|
1243
|
+
|
|
1244
|
+
- b2da66f: fix(select): o gatilho do `Select` desabilitado passa a expor `aria-disabled="true"` — leitor de tela anuncia o estado, como já acontecia no `MultiSelect`.
|
|
1245
|
+
- 13c288c: fix(select): mensagem de erro e texto de apoio ligados ao campo
|
|
1246
|
+
|
|
1247
|
+
O foco do Select cai no trigger `role="combobox"`, e nada ligava a ele a
|
|
1248
|
+
mensagem de erro nem o `helperText`/`description`: o leitor de tela anunciava
|
|
1249
|
+
o campo e nunca o motivo do erro. Agora o combobox recebe `aria-describedby`
|
|
1250
|
+
(erro primeiro, apoio depois, como no Input) e `aria-invalid` também quando há
|
|
1251
|
+
`errorMessage`, não só com `invalid`.
|
|
1252
|
+
|
|
1253
|
+
Os ids automáticos deixam de ser sorteados na inicialização do componente,
|
|
1254
|
+
o que fazia servidor e cliente gerarem ids diferentes e quebrava a hidratação
|
|
1255
|
+
SSR. O id automático nasce no `onMount`; quem precisa dos ids já no HTML do
|
|
1256
|
+
servidor passa a prop `id`, da qual todos derivam.
|
|
1257
|
+
|
|
1258
|
+
- 954b332: fix(side-panel): o contador do `SidePanelItem` e o rótulo do `SidePanelSection` passam de `neutral-dark-medium` (#7D7D7D, 4,11:1) para `neutral-dark-down` (#565656, 7,34:1) e atingem o contraste mínimo do WCAG 1.4.3 em todos os temas.
|
|
1259
|
+
- e8cd29b: fix(stepper): o número da etapa pendente passa da cor de desabilitado (`neutral-dark-up`, #A3A3A3, 2,5:1) para `neutral-dark-down` (#565656, 7,34:1), a mesma do título pendente, e atinge o contraste mínimo do WCAG 1.4.3.
|
|
1260
|
+
- b622c03: docs(text): o JSDoc da prop `color` do `Text` passa a dizer que `color="disabled"` (#A3A3A3, 2,5:1) é só para texto de controle desabilitado — em qualquer outro texto reprova o WCAG 1.4.3; o indicado é `secondary`.
|
|
1261
|
+
- f04dc5a: fix(tooltip): texto anunciado pelo leitor de tela no elemento focável
|
|
1262
|
+
|
|
1263
|
+
O `aria-describedby` ficava no `<span>` que embrulha o gatilho, que nunca
|
|
1264
|
+
recebe foco: o texto do tooltip não era lido. Agora o Tooltip escreve o
|
|
1265
|
+
`aria-describedby` no filho focável (o botão, o link, o campo), somando ao
|
|
1266
|
+
que ele já tinha, e aponta para uma cópia do texto que fica sempre no DOM,
|
|
1267
|
+
visualmente escondida — a bolha só monta depois do foco, tarde demais para o
|
|
1268
|
+
leitor de tela.
|
|
1269
|
+
|
|
1270
|
+
O foco passa a ser escutado com `focusin`/`focusout` nativos: no Vue, o
|
|
1271
|
+
`@focus` no span não disparava quando o foco caía no filho, e o tooltip não
|
|
1272
|
+
abria pelo teclado. Esc continua fechando. Os ids automáticos nascem no
|
|
1273
|
+
`onMount`, sem divergência de hidratação SSR.
|
|
1274
|
+
|
|
1275
|
+
- 2b881aa: fix(tooltip): Esc com o tooltip aberto não fecha o Modal em volta
|
|
1276
|
+
|
|
1277
|
+
Um tooltip aberto dentro de Modal, Drawer ou BottomSheet fechava a dica e o
|
|
1278
|
+
overlay no mesmo Esc. Agora o Esc que fecha o tooltip é consumido
|
|
1279
|
+
(`stopPropagation`, escutando no `window` em captura, antes do `document` onde
|
|
1280
|
+
os overlays escutam). Com o tooltip fechado, o Esc segue normal para o overlay.
|
|
1281
|
+
Sem mudança visual e sem mudança de API.
|
|
1282
|
+
|
|
3
1283
|
## 2.7.2
|
|
4
1284
|
|
|
5
1285
|
### Patch Changes
|