@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
|
@@ -80,6 +80,13 @@
|
|
|
80
80
|
color: var(--umds-semantic-color-feedback-negative-dark);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
/* Selo de recurso de IA: o roxo da IA (mesmos tokens do AILabel). */
|
|
84
|
+
.umds-attachment-card__status--ai {
|
|
85
|
+
border-color: color-mix(in srgb, var(--umds-semantic-color-ai-pure) 25%, transparent);
|
|
86
|
+
background-color: var(--umds-semantic-color-ai-light);
|
|
87
|
+
color: var(--umds-semantic-color-ai-dark);
|
|
88
|
+
}
|
|
89
|
+
|
|
83
90
|
/* Selo com painel de conferência: vira botão, e fica acima do `::after` do
|
|
84
91
|
"abrir" — senão o clique no selo abriria o arquivo. */
|
|
85
92
|
.umds-attachment-card__status--interativo {
|
|
@@ -101,6 +108,11 @@
|
|
|
101
108
|
border-color: var(--umds-semantic-color-feedback-negative-pure);
|
|
102
109
|
}
|
|
103
110
|
|
|
111
|
+
.umds-attachment-card__status--interativo.umds-attachment-card__status--ai:hover,
|
|
112
|
+
.umds-attachment-card__status--interativo.umds-attachment-card__status--ai[aria-expanded="true"] {
|
|
113
|
+
border-color: var(--umds-semantic-color-ai-pure);
|
|
114
|
+
}
|
|
115
|
+
|
|
104
116
|
.umds-attachment-card__status--interativo:focus-visible {
|
|
105
117
|
outline: 2px solid var(--umds-semantic-color-primary-pure);
|
|
106
118
|
outline-offset: 2px; /* anel de foco canônico: micro-espaçamento, candidato a token */
|
|
@@ -146,6 +158,10 @@
|
|
|
146
158
|
color: var(--umds-semantic-color-feedback-negative-pure);
|
|
147
159
|
}
|
|
148
160
|
|
|
161
|
+
.umds-attachment-card__detalhe-icone--ai {
|
|
162
|
+
color: var(--umds-semantic-color-ai-pure);
|
|
163
|
+
}
|
|
164
|
+
|
|
149
165
|
.umds-attachment-card__detalhe-titulo {
|
|
150
166
|
min-width: 0;
|
|
151
167
|
font-size: var(--umds-primitive-font-size-xxs);
|
|
@@ -187,7 +203,7 @@
|
|
|
187
203
|
}
|
|
188
204
|
|
|
189
205
|
.umds-attachment-card__campo-valor {
|
|
190
|
-
margin:
|
|
206
|
+
margin: var(--umds-primitive-spacing-micro) 0 0; /* 2px: respiro rótulo→valor */
|
|
191
207
|
font-size: var(--umds-primitive-font-size-xxs);
|
|
192
208
|
font-weight: var(--umds-primitive-font-weight-bold);
|
|
193
209
|
line-height: 1.4;
|
|
@@ -6,10 +6,13 @@ import './AttachmentCard.css';
|
|
|
6
6
|
* @property {string} fileName - Nome do arquivo, com extensão. A extensão escolhe o ícone do rodapé.
|
|
7
7
|
* @property {string} documentType - Tipo de documento que o arquivo cumpre ("CNH", "RG", "Título de Eleitor")
|
|
8
8
|
* @property {boolean} required - O tipo de documento é obrigatório (asterisco no selo)
|
|
9
|
-
* @property {string} status - Situação da conferência: 'positive' | 'negative'. Sem
|
|
9
|
+
* @property {string} status - Situação da conferência: 'positive' | 'negative' | 'ai'. O `ai` é o selo de recurso de IA (roxo da IA, com a varinha por padrão), para quando a IA propõe e a pessoa decide. Sem `status` o selo não aparece.
|
|
10
10
|
* @property {string} statusLabel - Texto do selo de situação ("Pré-aprovado", "Rejeitado")
|
|
11
11
|
* @property {IconProp} statusIcon - Ícone à esquerda do texto do selo
|
|
12
12
|
* @property {object} statusDetails - Resultado da conferência: `{ title?, description?, fields?: [{ label, value, copyable? }] }`. Com ele o selo vira botão e abre um painel no hover (sem tirar o foco de onde está) e no clique/teclado (levando o foco para dentro).
|
|
13
|
+
* @property {any} panel - Conteúdo livre do painel do selo, no lugar do resultado da conferência (ações, campos, texto). Passe o elemento (React) ou o slot `panel` (Vue). Com ele o selo vira botão mesmo sem `statusDetails`.
|
|
14
|
+
* @property {number} panelWidth - Largura do painel, em px. Padrão: 300.
|
|
15
|
+
* @property {boolean} closePanelOnAction - Fecha o painel e devolve o foco ao selo quando alguém aciona um botão ou link de dentro dele (o botão "Aplicar sugestão" do painel de IA). O botão de copiar um campo não conta.
|
|
13
16
|
* @property {Function} onCopyField - Avisa quando um campo do painel é copiado (recebe o campo)
|
|
14
17
|
* @property {IconProp} icon - Ícone central. Padrão: documento.
|
|
15
18
|
* @property {Function} onOpen - Abre o anexo. Com ele o cartão inteiro vira alvo de clique, com um único ponto de foco.
|
|
@@ -37,14 +40,38 @@ export interface AttachmentCardProps {
|
|
|
37
40
|
fileName: string;
|
|
38
41
|
documentType?: string;
|
|
39
42
|
required?: boolean;
|
|
40
|
-
status?: "positive" | "negative";
|
|
43
|
+
status?: "positive" | "negative" | "ai";
|
|
41
44
|
statusLabel?: string;
|
|
42
45
|
statusIcon?: IconProp;
|
|
43
46
|
statusDetails?: AttachmentCardStatusDetails;
|
|
47
|
+
/**
|
|
48
|
+
* Conteúdo livre do painel do selo, no lugar do resultado da conferência
|
|
49
|
+
* (`statusDetails`): ações, campos, texto. React: o elemento; Vue: o slot
|
|
50
|
+
* `panel`. Com ele o selo vira botão mesmo sem `statusDetails`.
|
|
51
|
+
*/
|
|
52
|
+
panel?: any;
|
|
53
|
+
/** Largura do painel, em px. @default 300 */
|
|
54
|
+
panelWidth?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Fecha o painel e devolve o foco ao selo quando alguém aciona um botão ou
|
|
57
|
+
* link de dentro dele. O botão de copiar um campo não conta. Sem a prop, o
|
|
58
|
+
* painel fica aberto até Esc, clique fora ou o foco sair.
|
|
59
|
+
*/
|
|
60
|
+
closePanelOnAction?: boolean;
|
|
44
61
|
onCopyField?: (field: AttachmentCardField) => void;
|
|
45
62
|
icon?: IconProp;
|
|
46
63
|
onOpen?: (event?: any) => void;
|
|
47
64
|
openAriaLabel?: string;
|
|
65
|
+
/** Complemento lido depois do selo, para dizer de qual documento ele é. Recebe o tipo de documento (ou o nome do arquivo). Troque para traduzir. @default (subject) => 'conferência de ' + subject */
|
|
66
|
+
statusContextLabel?: (subject: string) => string;
|
|
67
|
+
/** Texto lido depois do asterisco de obrigatório. Troque para traduzir. @default '(obrigatório)' */
|
|
68
|
+
requiredLabel?: string;
|
|
69
|
+
/** Nome acessível do botão de copiar um campo do painel. Recebe o rótulo do campo. Troque para traduzir. @default (field) => 'Copiar ' + field */
|
|
70
|
+
copyLabel?: (field: string) => string;
|
|
71
|
+
/** Nome acessível do botão e anúncio depois da cópia. Recebe o rótulo do campo. Troque para traduzir. @default (field) => field + ' copiado' */
|
|
72
|
+
copiedLabel?: (field: string) => string;
|
|
73
|
+
/** Anúncio quando a cópia falha. Recebe o rótulo do campo. Troque para traduzir. @default (field) => 'Não foi possível copiar ' + field */
|
|
74
|
+
copyErrorLabel?: (field: string) => string;
|
|
48
75
|
className?: string;
|
|
49
76
|
id?: string;
|
|
50
77
|
}
|
|
@@ -4,7 +4,7 @@ import './AttachmentCard.css';
|
|
|
4
4
|
import { useState, useRef, useEffect } from "react";
|
|
5
5
|
import { computePosition, autoUpdate, offset, flip, shift, } from "@floating-ui/dom";
|
|
6
6
|
import { faCopy, faFile, faFileLines, faFilePdf, faFileImage, faFileWord, faFileExcel, } from "@fortawesome/free-regular-svg-icons";
|
|
7
|
-
import { faCheck, faCircleCheck, faCircleXmark, } from "@fortawesome/free-solid-svg-icons";
|
|
7
|
+
import { faCheck, faCircleCheck, faCircleXmark, faWandMagicSparkles, } from "@fortawesome/free-solid-svg-icons";
|
|
8
8
|
import Icon from "../Icon/Icon";
|
|
9
9
|
import Portal from "../Portal/Portal";
|
|
10
10
|
const FOCAVEIS = 'button, a[href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
|
|
@@ -47,7 +47,30 @@ function AttachmentCard(props) {
|
|
|
47
47
|
return Boolean(props.status && props.statusLabel);
|
|
48
48
|
}
|
|
49
49
|
function temDetalhe() {
|
|
50
|
-
return Boolean(temSelo() && props.statusDetails);
|
|
50
|
+
return Boolean(temSelo() && (props.statusDetails || props.panel));
|
|
51
|
+
}
|
|
52
|
+
function painelTemConteudoLivre() {
|
|
53
|
+
return Boolean(props.panel);
|
|
54
|
+
}
|
|
55
|
+
function seloIcone() {
|
|
56
|
+
if (props.statusIcon)
|
|
57
|
+
return props.statusIcon;
|
|
58
|
+
return props.status === "ai" ? faWandMagicSparkles : undefined;
|
|
59
|
+
}
|
|
60
|
+
function detalheEstilo() {
|
|
61
|
+
return props.panelWidth
|
|
62
|
+
? {
|
|
63
|
+
width: props.panelWidth + "px",
|
|
64
|
+
}
|
|
65
|
+
: undefined;
|
|
66
|
+
}
|
|
67
|
+
function painelNomeadoPor() {
|
|
68
|
+
return props.panel ? undefined : tituloId();
|
|
69
|
+
}
|
|
70
|
+
function painelRotulo() {
|
|
71
|
+
if (!props.panel)
|
|
72
|
+
return undefined;
|
|
73
|
+
return (props.statusLabel || "") + seloComplemento();
|
|
51
74
|
}
|
|
52
75
|
function painelId() {
|
|
53
76
|
return `${props.id || uid}-conferencia`;
|
|
@@ -62,7 +85,18 @@ function AttachmentCard(props) {
|
|
|
62
85
|
return aberto ? painelId() : undefined;
|
|
63
86
|
}
|
|
64
87
|
function seloComplemento() {
|
|
65
|
-
|
|
88
|
+
const assunto = props.documentType || props.fileName;
|
|
89
|
+
if (props.statusContextLabel)
|
|
90
|
+
return ": " + props.statusContextLabel(assunto);
|
|
91
|
+
return `: conferência de ${assunto}`;
|
|
92
|
+
}
|
|
93
|
+
function textoCopiado(rotulo) {
|
|
94
|
+
return props.copiedLabel ? props.copiedLabel(rotulo) : `${rotulo} copiado`;
|
|
95
|
+
}
|
|
96
|
+
function textoFalhaCopia(rotulo) {
|
|
97
|
+
return props.copyErrorLabel
|
|
98
|
+
? props.copyErrorLabel(rotulo)
|
|
99
|
+
: `Não foi possível copiar ${rotulo}`;
|
|
66
100
|
}
|
|
67
101
|
function detalheTitulo() {
|
|
68
102
|
return (props.statusDetails && props.statusDetails.title) || props.fileName;
|
|
@@ -74,6 +108,8 @@ function AttachmentCard(props) {
|
|
|
74
108
|
return (props.statusDetails && props.statusDetails.fields) || [];
|
|
75
109
|
}
|
|
76
110
|
function detalheIcone() {
|
|
111
|
+
if (props.status === "ai")
|
|
112
|
+
return faWandMagicSparkles;
|
|
77
113
|
return props.status === "negative" ? faCircleXmark : faCircleCheck;
|
|
78
114
|
}
|
|
79
115
|
function detalheIconeClasses() {
|
|
@@ -137,8 +173,36 @@ function AttachmentCard(props) {
|
|
|
137
173
|
setPosX(Math.round(pos.x * dpr) / dpr);
|
|
138
174
|
setPosY(Math.round(pos.y * dpr) / dpr);
|
|
139
175
|
setPosicionado(true);
|
|
176
|
+
// No Vue o `onUpdate` NAO roda aqui: `posicionado` so e lido pelo
|
|
177
|
+
// estilo do flutuante, que mora no slot do Portal. Quem re-renderiza
|
|
178
|
+
// e o Portal (filho), e o `updated` do cartao nunca dispara, entao o
|
|
179
|
+
// foco nao entrava no painel. Um quadro depois o estilo ja foi
|
|
180
|
+
// aplicado nos dois frameworks; no React o `onUpdate` costuma chegar
|
|
181
|
+
// antes, e aqui vira no-op (`focarPainel` ja voltou a false).
|
|
182
|
+
if (focarPainel) {
|
|
183
|
+
if (typeof requestAnimationFrame !== "undefined") {
|
|
184
|
+
requestAnimationFrame(() => focarPainelSePreciso());
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
setTimeout(() => focarPainelSePreciso(), 0);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
140
190
|
});
|
|
141
191
|
}
|
|
192
|
+
function focarPainelSePreciso() {
|
|
193
|
+
if (!focarPainel || !aberto || !posicionado)
|
|
194
|
+
return;
|
|
195
|
+
if (!painelRef.current)
|
|
196
|
+
return;
|
|
197
|
+
const primeiro = painelRef.current.querySelector(FOCAVEIS);
|
|
198
|
+
if (primeiro) {
|
|
199
|
+
primeiro.focus();
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
painelRef.current.focus();
|
|
203
|
+
}
|
|
204
|
+
setFocarPainel(false);
|
|
205
|
+
}
|
|
142
206
|
function ligarObservadores() {
|
|
143
207
|
if (!autoUpdateRef.current && seloRef.current && flutuanteRef.current) {
|
|
144
208
|
autoUpdateRef.current = autoUpdate(seloRef.current, flutuanteRef.current, () => posicionar());
|
|
@@ -244,6 +308,18 @@ function AttachmentCard(props) {
|
|
|
244
308
|
fechar(true);
|
|
245
309
|
}
|
|
246
310
|
}
|
|
311
|
+
function cliqueNoPainel(event) {
|
|
312
|
+
if (!props.closePanelOnAction)
|
|
313
|
+
return;
|
|
314
|
+
const alvo = event.target && event.target.closest
|
|
315
|
+
? event.target.closest("button, a[href]")
|
|
316
|
+
: null;
|
|
317
|
+
if (!alvo)
|
|
318
|
+
return;
|
|
319
|
+
if (alvo.classList.contains("umds-attachment-card__copiar"))
|
|
320
|
+
return;
|
|
321
|
+
fechar(true);
|
|
322
|
+
}
|
|
247
323
|
function teclaNoPainel(event) {
|
|
248
324
|
if (event.key === "Escape") {
|
|
249
325
|
event.preventDefault();
|
|
@@ -266,12 +342,12 @@ function AttachmentCard(props) {
|
|
|
266
342
|
}
|
|
267
343
|
function copiarCampo(campo) {
|
|
268
344
|
if (typeof navigator === "undefined" || !navigator.clipboard) {
|
|
269
|
-
setAnuncio(
|
|
345
|
+
setAnuncio(textoFalhaCopia(campo.label));
|
|
270
346
|
return;
|
|
271
347
|
}
|
|
272
348
|
navigator.clipboard.writeText(campo.value).then(() => {
|
|
273
349
|
setCopiado(campo.label);
|
|
274
|
-
setAnuncio(
|
|
350
|
+
setAnuncio(textoCopiado(campo.label));
|
|
275
351
|
setTimeout(() => {
|
|
276
352
|
if (copiado === campo.label)
|
|
277
353
|
setCopiado("");
|
|
@@ -280,12 +356,14 @@ function AttachmentCard(props) {
|
|
|
280
356
|
props.onCopyField(campo);
|
|
281
357
|
}
|
|
282
358
|
}, () => {
|
|
283
|
-
setAnuncio(
|
|
359
|
+
setAnuncio(textoFalhaCopia(campo.label));
|
|
284
360
|
});
|
|
285
361
|
}
|
|
286
362
|
function rotuloCopiar(campo) {
|
|
287
|
-
|
|
288
|
-
|
|
363
|
+
if (copiado === campo.label)
|
|
364
|
+
return textoCopiado(campo.label);
|
|
365
|
+
return props.copyLabel
|
|
366
|
+
? props.copyLabel(campo.label)
|
|
289
367
|
: `Copiar ${campo.label}`;
|
|
290
368
|
}
|
|
291
369
|
function iconeCopiar(campo) {
|
|
@@ -300,17 +378,7 @@ function AttachmentCard(props) {
|
|
|
300
378
|
if (aberto) {
|
|
301
379
|
ligarObservadores();
|
|
302
380
|
}
|
|
303
|
-
|
|
304
|
-
if (focarPainel && aberto && posicionado && painelRef.current) {
|
|
305
|
-
const primeiro = painelRef.current.querySelector(FOCAVEIS);
|
|
306
|
-
if (primeiro) {
|
|
307
|
-
primeiro.focus();
|
|
308
|
-
}
|
|
309
|
-
else {
|
|
310
|
-
painelRef.current.focus();
|
|
311
|
-
}
|
|
312
|
-
setFocarPainel(false);
|
|
313
|
-
}
|
|
381
|
+
focarPainelSePreciso();
|
|
314
382
|
});
|
|
315
383
|
useEffect(() => {
|
|
316
384
|
return () => {
|
|
@@ -318,6 +386,6 @@ function AttachmentCard(props) {
|
|
|
318
386
|
desligarObservadores();
|
|
319
387
|
};
|
|
320
388
|
}, []);
|
|
321
|
-
return (_jsxs("div", { className: classes(), id: props.id, children: [_jsxs("div", { className: "umds-attachment-card__topo", children: [temSelo() && !temDetalhe() ? (_jsxs("span", { className: statusClasses(), children: [
|
|
389
|
+
return (_jsxs("div", { className: classes(), id: props.id, children: [_jsxs("div", { className: "umds-attachment-card__topo", children: [temSelo() && !temDetalhe() ? (_jsxs("span", { className: statusClasses(), children: [seloIcone() ? (_jsx(Icon, { size: "sm", variant: "inherit", icon: seloIcone() })) : null, _jsx("span", { className: "umds-attachment-card__status-texto", children: props.statusLabel })] })) : null, temDetalhe() ? (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", "aria-haspopup": "dialog", ref: seloRef, className: statusBotaoClasses(), "aria-expanded": ariaExpandidoTexto(), "aria-controls": ariaControlsTexto(), onMouseEnter: (event) => abrir(false), onMouseLeave: (event) => agendarFechar(), onClick: (event) => alternar(), onKeyDown: (event) => teclaNoSelo(event), onBlur: (event) => focoSaiu(event), children: [seloIcone() ? (_jsx(Icon, { size: "sm", variant: "inherit", icon: seloIcone() })) : null, _jsx("span", { className: "umds-attachment-card__status-texto", children: props.statusLabel }), _jsx("span", { className: "umds-attachment-card__sr", children: seloComplemento() })] }), _jsx(Portal, { children: aberto ? (_jsx("span", { className: "umds-attachment-card__flutuante", ref: flutuanteRef, style: flutuanteEstilo(), children: _jsxs("div", { className: "umds-attachment-card__detalhe", role: "dialog", "aria-modal": "false", ref: painelRef, id: painelId(), "aria-labelledby": painelNomeadoPor(), "aria-label": painelRotulo(), tabIndex: -1, style: detalheEstilo(), onClick: (event) => cliqueNoPainel(event), onMouseEnter: (event) => cancelarFechar(), onMouseLeave: (event) => agendarFechar(), onKeyDown: (event) => teclaNoPainel(event), children: [_jsx("span", { className: "umds-attachment-card__sr", role: "status", "aria-live": "polite", children: anuncio }), props.panel ? (_jsx(_Fragment, { children: props.panel })) : (_jsx(_Fragment, { children: _jsxs(_Fragment, { children: [_jsxs("div", { className: "umds-attachment-card__detalhe-topo", children: [_jsx("span", { "aria-hidden": "true", className: detalheIconeClasses(), children: _jsx(Icon, { size: "md", variant: "inherit", icon: detalheIcone() }) }), _jsx("span", { className: "umds-attachment-card__detalhe-titulo", id: tituloId(), children: detalheTitulo() })] }), detalheDescricao() ? (_jsx("p", { className: "umds-attachment-card__detalhe-descricao", children: detalheDescricao() })) : null, detalheCampos().length > 0 ? (_jsx("dl", { className: "umds-attachment-card__campos", children: detalheCampos()?.map((campo) => (_jsxs("div", { className: "umds-attachment-card__campo", children: [_jsxs("div", { className: "umds-attachment-card__campo-texto", children: [_jsx("dt", { className: "umds-attachment-card__campo-rotulo", children: campo.label }), _jsx("dd", { className: "umds-attachment-card__campo-valor", children: campo.value })] }), campo.copyable ? (_jsx("button", { type: "button", className: "umds-attachment-card__copiar", "aria-label": rotuloCopiar(campo), onClick: (event) => copiarCampo(campo), children: _jsx(Icon, { size: "sm", variant: "inherit", icon: iconeCopiar(campo) }) })) : null] }, campo.label))) })) : null] }) }))] }) })) : null })] })) : null] }), _jsx("div", { className: "umds-attachment-card__preview", "aria-hidden": "true", children: _jsx(Icon, { customSize: "48px", variant: "inherit", icon: iconeCentral() }) }), _jsx("div", { className: "umds-attachment-card__tipo-area", children: props.documentType ? (_jsxs("span", { className: "umds-attachment-card__tipo", children: [_jsx("span", { className: "umds-attachment-card__tipo-texto", children: props.documentType }), props.required ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "umds-attachment-card__obrigatorio", "aria-hidden": "true", children: "*" }), _jsx("span", { className: "umds-attachment-card__sr", children: props.requiredLabel || "(obrigatório)" })] })) : null] })) : null }), _jsxs("div", { className: "umds-attachment-card__rodape", title: props.fileName, children: [_jsx("span", { className: "umds-attachment-card__rodape-icone", "aria-hidden": "true", children: _jsx(Icon, { size: "sm", variant: "inherit", icon: iconeArquivo() }) }), props.onOpen ? (_jsx("button", { type: "button", className: "umds-attachment-card__nome umds-attachment-card__abrir", "aria-label": rotuloAbrir(), onClick: (event) => handleOpen(event), children: props.fileName })) : (_jsx("span", { className: "umds-attachment-card__nome", children: props.fileName }))] })] }));
|
|
322
390
|
}
|
|
323
391
|
export default AttachmentCard;
|
|
@@ -72,17 +72,22 @@
|
|
|
72
72
|
|
|
73
73
|
/* Avatar Group Styles */
|
|
74
74
|
.umds-avatar-group {
|
|
75
|
+
/* Sobreposição e anel do grupo: os padrões de sempre; as props `overlap` e
|
|
76
|
+
`ring` do AvatarGroup trocam estes dois valores por style inline. */
|
|
77
|
+
--umds-avatar-group-overlap: var(--umds-primitive-spacing-nano); /* 8px */
|
|
78
|
+
--umds-avatar-group-ring: 1.5px; /* a borda do Avatar base */
|
|
75
79
|
display: inline-flex;
|
|
76
80
|
flex-direction: row;
|
|
77
81
|
align-items: center;
|
|
78
82
|
/* compensa a sobreposição negativa do último item */
|
|
79
|
-
padding-right: var(--umds-
|
|
83
|
+
padding-right: var(--umds-avatar-group-overlap);
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
/* Sobreposição: cada avatar do grupo avança sobre o anterior (protótipo: -8px) */
|
|
83
87
|
.umds-avatar-group .umds-avatar {
|
|
84
88
|
/* Borda branca já definida no componente base Avatar */
|
|
85
|
-
margin-right: calc(-1 * var(--umds-
|
|
89
|
+
margin-right: calc(-1 * var(--umds-avatar-group-overlap));
|
|
90
|
+
border-width: var(--umds-avatar-group-ring);
|
|
86
91
|
position: relative;
|
|
87
92
|
z-index: 1;
|
|
88
93
|
transition: z-index var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard);
|
|
@@ -45,6 +45,23 @@ export interface AvatarGroupProps {
|
|
|
45
45
|
* @default 'md'
|
|
46
46
|
*/
|
|
47
47
|
size?: "sm" | "md" | "lg";
|
|
48
|
+
/**
|
|
49
|
+
* Quantas pessoas a mais existem além das que estão em `avatars`: entra na
|
|
50
|
+
* conta do "+N" sem precisar de itens-fantasma. Com 16 responsáveis, passe
|
|
51
|
+
* os 4 primeiros em `avatars` e `overflowCount={12}` para ver "+12". Soma com
|
|
52
|
+
* o que passar de `max` dentro de `avatars`.
|
|
53
|
+
* @default 0
|
|
54
|
+
*/
|
|
55
|
+
overflowCount?: number;
|
|
56
|
+
/**
|
|
57
|
+
* Quanto cada avatar avança sobre o anterior, em px. O padrão é 8
|
|
58
|
+
* (`spacing-nano`); 6 deixa as iniciais menos cortadas.
|
|
59
|
+
*/
|
|
60
|
+
overlap?: number;
|
|
61
|
+
/**
|
|
62
|
+
* Largura do anel (a borda da cor do fundo) de cada avatar, em px. O padrão é 1,5.
|
|
63
|
+
*/
|
|
64
|
+
ring?: number;
|
|
48
65
|
/**
|
|
49
66
|
* Classes adicionais.
|
|
50
67
|
*/
|
|
@@ -54,6 +71,16 @@ export interface AvatarGroupProps {
|
|
|
54
71
|
* Recebe o item correspondente.
|
|
55
72
|
*/
|
|
56
73
|
onError?: (item: AvatarGroupItem) => void;
|
|
74
|
+
/**
|
|
75
|
+
* Nome acessível do avatar de excedente. Recebe a quantidade escondida.
|
|
76
|
+
* Troque para traduzir. @default (count) => 'Mais ' + count + ' avatares'
|
|
77
|
+
*/
|
|
78
|
+
overflowAriaLabel?: (count: number) => string;
|
|
79
|
+
/**
|
|
80
|
+
* Dica (title) do avatar de excedente. Recebe a quantidade escondida.
|
|
81
|
+
* Troque para traduzir. @default (count) => count + ' outros'
|
|
82
|
+
*/
|
|
83
|
+
overflowTitle?: (count: number) => string;
|
|
57
84
|
}
|
|
58
85
|
declare function AvatarGroup(props: AvatarGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
59
86
|
export default AvatarGroup;
|
|
@@ -10,12 +10,36 @@ function AvatarGroup(props) {
|
|
|
10
10
|
function visibleAvatars() {
|
|
11
11
|
return avatarList().slice(0, maxCount());
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function hiddenCount() {
|
|
14
14
|
const total = avatarList().length;
|
|
15
|
-
|
|
15
|
+
const alem = total > maxCount() ? total - maxCount() : 0;
|
|
16
|
+
return alem + (props.overflowCount || 0);
|
|
16
17
|
}
|
|
17
18
|
function hasOverflow() {
|
|
18
|
-
return
|
|
19
|
+
return hiddenCount() > 0;
|
|
20
|
+
}
|
|
21
|
+
function overflowAriaLabelText() {
|
|
22
|
+
return props.overflowAriaLabel
|
|
23
|
+
? props.overflowAriaLabel(hiddenCount())
|
|
24
|
+
: "Mais " + hiddenCount() + " avatares";
|
|
25
|
+
}
|
|
26
|
+
function overflowTitleText() {
|
|
27
|
+
return props.overflowTitle
|
|
28
|
+
? props.overflowTitle(hiddenCount())
|
|
29
|
+
: hiddenCount() + " outros";
|
|
30
|
+
}
|
|
31
|
+
function groupStyle() {
|
|
32
|
+
if (props.overlap === undefined && props.ring === undefined) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
const estilo = {};
|
|
36
|
+
if (props.overlap !== undefined) {
|
|
37
|
+
estilo["--umds-avatar-group-overlap"] = props.overlap + "px";
|
|
38
|
+
}
|
|
39
|
+
if (props.ring !== undefined) {
|
|
40
|
+
estilo["--umds-avatar-group-ring"] = props.ring + "px";
|
|
41
|
+
}
|
|
42
|
+
return estilo;
|
|
19
43
|
}
|
|
20
44
|
function size() {
|
|
21
45
|
return props.size || "md";
|
|
@@ -38,6 +62,6 @@ function AvatarGroup(props) {
|
|
|
38
62
|
const second = parts[1] ? parts[1][0] : "";
|
|
39
63
|
return (first + second).toUpperCase();
|
|
40
64
|
}
|
|
41
|
-
return (_jsxs("div", { role: "group", "aria-label": props.ariaLabel || "Grupo de avatares", className: classes(), children: [visibleAvatars()?.map((avatar, index) => (_jsx(Avatar, { className: "umds-avatar-group__item", size: size(), type: avatar.src ? "photo" : "letter", src: avatar.src, alt: avatar.name, title: avatar.name, ariaLabel: avatar.name, onError: (event) => props.onError && props.onError(avatar), children: !avatar.src ? _jsx(_Fragment, { children: getInitials(avatar) }) : null }, avatar.name + "-" + index))), hasOverflow() ? (_jsxs(Avatar, { className: "umds-avatar-group__item umds-avatar-group__overflow", type: "number", size: size(), title:
|
|
65
|
+
return (_jsxs("div", { role: "group", style: groupStyle(), "aria-label": props.ariaLabel || "Grupo de avatares", className: classes(), children: [visibleAvatars()?.map((avatar, index) => (_jsx(Avatar, { className: "umds-avatar-group__item", size: size(), type: avatar.src ? "photo" : "letter", src: avatar.src, alt: avatar.name, title: avatar.name, ariaLabel: avatar.name, onError: (event) => props.onError && props.onError(avatar), children: !avatar.src ? _jsx(_Fragment, { children: getInitials(avatar) }) : null }, avatar.name + "-" + index))), hasOverflow() ? (_jsxs(Avatar, { className: "umds-avatar-group__item umds-avatar-group__overflow", type: "number", size: size(), title: overflowTitleText(), ariaLabel: overflowAriaLabelText(), children: ["+", hiddenCount()] })) : null] }));
|
|
42
66
|
}
|
|
43
67
|
export default AvatarGroup;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/* ============================================
|
|
2
2
|
Badge Component
|
|
3
|
-
Variantes: neutral, positive, negative, info, primary
|
|
3
|
+
Variantes: neutral, positive, negative, info, primary, new
|
|
4
4
|
Aparências (appearance): solid, soft, outlined
|
|
5
|
-
Tamanhos: xs, sm, md, lg, pill
|
|
5
|
+
Tamanhos: 2xs, xs, sm, md, lg, pill
|
|
6
|
+
Modificador: attached (rótulo colado no topo de um card)
|
|
6
7
|
============================================ */
|
|
7
8
|
|
|
8
9
|
.umds-badge {
|
|
@@ -41,7 +42,13 @@
|
|
|
41
42
|
display: block;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
/* Escopado em `.umds-badge` de propósito: `.umds-badge__icon svg` tinha a MESMA
|
|
46
|
+
especificidade de `.umds-icon svg` (0,1,1), e quem vencia era a ordem de
|
|
47
|
+
carga do CSS. No build do Storybook React o CSS do Icon chega depois do do
|
|
48
|
+
Badge, e o SVG voltava a 1em com `vertical-align: -0.125em` (ícone de 12px
|
|
49
|
+
deslocado). Com o bloco na frente (0,2,1) a regra vence em qualquer ordem
|
|
50
|
+
de carga, sem `!important`. */
|
|
51
|
+
.umds-badge .umds-badge__icon svg {
|
|
45
52
|
width: 100%;
|
|
46
53
|
height: 100%;
|
|
47
54
|
display: block;
|
|
@@ -53,6 +60,16 @@
|
|
|
53
60
|
|
|
54
61
|
/* ── Tamanhos — padding + gap por tamanho (sem height fixa) ── */
|
|
55
62
|
|
|
63
|
+
/* 2xs: 16px de altura (10 de fonte + 2 + 2 de padding + 2 de borda). A fonte de
|
|
64
|
+
10px não está na escala do DS (menor degrau: 12px); é o selo compacto do
|
|
65
|
+
CrisDoc, sem token equivalente. */
|
|
66
|
+
.umds-badge--2xs {
|
|
67
|
+
font-size: 0.625rem; /* 10px: fora da escala, selo compacto */
|
|
68
|
+
padding: var(--umds-primitive-spacing-micro) var(--umds-primitive-spacing-quarck);
|
|
69
|
+
gap: var(--umds-primitive-spacing-micro);
|
|
70
|
+
border-radius: var(--umds-primitive-border-radius-xs); /* 4px */
|
|
71
|
+
}
|
|
72
|
+
|
|
56
73
|
.umds-badge--lg {
|
|
57
74
|
font-size: var(--umds-primitive-font-size-xxs); /* 14px */
|
|
58
75
|
padding: var(--umds-primitive-spacing-quarck) var(--umds-primitive-spacing-mini); /* 10px: candidato a novo token */
|
|
@@ -110,6 +127,11 @@
|
|
|
110
127
|
height: 11px;
|
|
111
128
|
}
|
|
112
129
|
|
|
130
|
+
.umds-badge--2xs .umds-badge__icon {
|
|
131
|
+
width: 8px;
|
|
132
|
+
height: 8px;
|
|
133
|
+
}
|
|
134
|
+
|
|
113
135
|
/* ─────────────── SOLID ─────────────── */
|
|
114
136
|
|
|
115
137
|
.umds-badge--solid.umds-badge--neutral {
|
|
@@ -196,3 +218,39 @@
|
|
|
196
218
|
border-color: var(--umds-semantic-color-primary-pure);
|
|
197
219
|
color: var(--umds-semantic-color-primary-pure);
|
|
198
220
|
}
|
|
221
|
+
|
|
222
|
+
/* ─────────────── NEW (selo de novidade) ───────────────
|
|
223
|
+
O DS não tem token semântico de amarelo. Usa os primitivos de amarelo e o
|
|
224
|
+
cinza escuro, todos fixos nos temas, então o contraste (8:1 do texto sobre o
|
|
225
|
+
fundo) não depende do tema. Candidato a token semântico de destaque. */
|
|
226
|
+
|
|
227
|
+
.umds-badge--new {
|
|
228
|
+
font-weight: var(--umds-primitive-font-weight-extrabold);
|
|
229
|
+
text-transform: uppercase;
|
|
230
|
+
letter-spacing: var(--umds-primitive-font-letter-spacing-wider);
|
|
231
|
+
border-radius: var(--umds-primitive-border-radius-pill);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.umds-badge--solid.umds-badge--new,
|
|
235
|
+
.umds-badge--soft.umds-badge--new {
|
|
236
|
+
/* stylelint-disable-next-line 1ds/cor-por-token -- o DS não tem token semântico de amarelo (candidato a novo token) */
|
|
237
|
+
background-color: var(--umds-primitive-yellow-medium);
|
|
238
|
+
/* stylelint-disable-next-line 1ds/cor-por-token -- par fixo do amarelo: o semântico inverte no tema escuro e perderia o contraste */
|
|
239
|
+
color: var(--umds-primitive-gray-darkest);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.umds-badge--outlined.umds-badge--new {
|
|
243
|
+
/* stylelint-disable-next-line 1ds/cor-por-token -- o DS não tem token semântico de amarelo (candidato a novo token) */
|
|
244
|
+
border-color: var(--umds-primitive-yellow-pure);
|
|
245
|
+
/* stylelint-disable-next-line 1ds/cor-por-token -- o DS não tem token semântico de amarelo (candidato a novo token) */
|
|
246
|
+
color: var(--umds-primitive-yellow-dark);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/* ─────────────── ATTACHED (rótulo colado no topo do card) ─────────────── */
|
|
250
|
+
|
|
251
|
+
.umds-badge--attached {
|
|
252
|
+
position: absolute;
|
|
253
|
+
top: 0;
|
|
254
|
+
left: 0;
|
|
255
|
+
border-radius: 0 0 var(--umds-primitive-border-radius-sm) var(--umds-primitive-border-radius-sm);
|
|
256
|
+
}
|
|
@@ -7,15 +7,25 @@ import './Badge.css';
|
|
|
7
7
|
*/
|
|
8
8
|
export interface BadgeProps {
|
|
9
9
|
/**
|
|
10
|
-
* Variação de cor semântica.
|
|
10
|
+
* Variação de cor semântica. `new` é o selo de novidade: amarelo, em caixa
|
|
11
|
+
* alta e pílula, para destacar uma funcionalidade recém-chegada.
|
|
11
12
|
* @default 'neutral'
|
|
12
13
|
*/
|
|
13
|
-
variant?: "neutral" | "positive" | "negative" | "info" | "primary";
|
|
14
|
+
variant?: "neutral" | "positive" | "negative" | "info" | "primary" | "new";
|
|
14
15
|
/**
|
|
15
|
-
* Tamanho do badge.
|
|
16
|
+
* Tamanho do badge. `2xs` é o compacto (16px, fonte de 10px) para selo de
|
|
17
|
+
* setor e de contagem dentro de linha de lista e card.
|
|
16
18
|
* @default 'md'
|
|
17
19
|
*/
|
|
18
|
-
size?: "
|
|
20
|
+
size?: "2xs" | "xs" | "sm" | "md" | "lg" | "pill";
|
|
21
|
+
/**
|
|
22
|
+
* Cola o badge no canto superior esquerdo do card (rótulo de card, como
|
|
23
|
+
* "Tarefa pendente"): cantos de baixo arredondados, os de cima retos.
|
|
24
|
+
* Posiciona em `absolute`, então o pai precisa de `position: relative`
|
|
25
|
+
* (o `Card` e o `Box` com `position` já servem).
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
attached?: boolean;
|
|
19
29
|
/**
|
|
20
30
|
* Estilo visual do badge.
|
|
21
31
|
* @default 'soft'
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
.umds-bottomsheet__backdrop {
|
|
23
23
|
position: absolute;
|
|
24
24
|
inset: 0;
|
|
25
|
+
/* stylelint-disable-next-line 1ds/cor-por-token -- o DS não tem token de scrim/overlay (candidato a novo token) */
|
|
25
26
|
background-color: rgba(0, 0, 0, 0.4); /* overlay escuro — sem token 1DS: candidato a novo token (igual ao Modal) */
|
|
26
27
|
backdrop-filter: blur(4px);
|
|
27
28
|
z-index: 1;
|
|
@@ -34,8 +34,16 @@ export interface BottomSheetProps {
|
|
|
34
34
|
closable?: any;
|
|
35
35
|
closeOnEsc?: any;
|
|
36
36
|
closeOnBackdrop?: any;
|
|
37
|
+
/**
|
|
38
|
+
* Nome acessível do painel quando não há `title` (vira `aria-label`). Sem
|
|
39
|
+
* título, sem esta prop e sem `ariaLabelledby`, o componente usa "Painel"
|
|
40
|
+
* como último recurso, para o `role="dialog"` nunca sair anônimo.
|
|
41
|
+
*/
|
|
37
42
|
ariaLabel?: string;
|
|
43
|
+
/** Id de um elemento externo que nomeia o painel. Vence o `title`. */
|
|
38
44
|
ariaLabelledby?: string;
|
|
45
|
+
/** Nome acessível da alça de arrastar (slider), que só existe com mais de um encaixe. Troque para traduzir. @default 'Altura do painel' */
|
|
46
|
+
grabberLabel?: string;
|
|
39
47
|
className?: string;
|
|
40
48
|
id?: string;
|
|
41
49
|
children?: any;
|
|
@@ -20,6 +20,18 @@ function BottomSheet(props) {
|
|
|
20
20
|
function labelId() {
|
|
21
21
|
return uid + "-titulo";
|
|
22
22
|
}
|
|
23
|
+
function labelledByText() {
|
|
24
|
+
if (props.ariaLabelledby)
|
|
25
|
+
return props.ariaLabelledby;
|
|
26
|
+
return props.title ? labelId() : undefined;
|
|
27
|
+
}
|
|
28
|
+
function nomeAcessivel() {
|
|
29
|
+
if (props.ariaLabel)
|
|
30
|
+
return props.ariaLabel;
|
|
31
|
+
if (props.ariaLabelledby || props.title)
|
|
32
|
+
return undefined;
|
|
33
|
+
return "Painel";
|
|
34
|
+
}
|
|
23
35
|
function alturaDoPainel() {
|
|
24
36
|
const pontos = props.snapPoints || [];
|
|
25
37
|
if (!pontos.length)
|
|
@@ -31,7 +43,7 @@ function BottomSheet(props) {
|
|
|
31
43
|
return !!props.snapPoints && props.snapPoints.length > 1;
|
|
32
44
|
}
|
|
33
45
|
function grabberAriaLabel() {
|
|
34
|
-
return "Altura do painel";
|
|
46
|
+
return props.grabberLabel || "Altura do painel";
|
|
35
47
|
}
|
|
36
48
|
function handleClose(event) {
|
|
37
49
|
if (props.onClose)
|
|
@@ -158,7 +170,7 @@ function BottomSheet(props) {
|
|
|
158
170
|
removeOverlay(uid);
|
|
159
171
|
};
|
|
160
172
|
}, []);
|
|
161
|
-
return (_jsx(_Fragment, { children: props.open ? (_jsx(_Fragment, { children: _jsxs("div", { id: props.id, className: rootClasses(), children: [_jsx("div", { className: "umds-bottomsheet__backdrop", onClick: (event) => handleBackdropClick(event) }), _jsxs("div", { role: "dialog", "aria-modal": "true", className: "umds-bottomsheet", ref: sheetRef, "aria-label":
|
|
173
|
+
return (_jsx(_Fragment, { children: props.open ? (_jsx(_Fragment, { children: _jsxs("div", { id: props.id, className: rootClasses(), children: [_jsx("div", { className: "umds-bottomsheet__backdrop", onClick: (event) => handleBackdropClick(event) }), _jsxs("div", { role: "dialog", "aria-modal": "true", className: "umds-bottomsheet", ref: sheetRef, "aria-label": nomeAcessivel(), "aria-labelledby": labelledByText(), tabIndex: -1, style: {
|
|
162
174
|
height: alturaDoPainel(),
|
|
163
175
|
}, onKeyDown: (event) => handleTrapKeydown(event), children: [_jsxs("div", { className: "umds-bottomsheet__top", children: [props.grabber !== false ? (_jsx("div", { className: "umds-bottomsheet__grabber", role: temMaisDeUmEncaixe() ? "slider" : undefined, tabIndex: temMaisDeUmEncaixe() ? 0 : undefined, "aria-label": temMaisDeUmEncaixe() ? grabberAriaLabel() : undefined, "aria-valuenow": temMaisDeUmEncaixe() ? snapAtual : undefined, "aria-valuemin": temMaisDeUmEncaixe() ? 0 : undefined, "aria-valuemax": temMaisDeUmEncaixe()
|
|
164
176
|
? (props.snapPoints || []).length - 1
|