@1doc/1ds-react 2.8.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1540 -0
- package/dist/components/AILabel/AILabel.js +1 -1
- package/dist/components/Accordion/Accordion.css +13 -0
- package/dist/components/Accordion/Accordion.d.ts +9 -2
- package/dist/components/Accordion/Accordion.js +1 -0
- package/dist/components/AppSubheader/AppSubheader.css +10 -1
- package/dist/components/AttachmentCard/AttachmentCard.css +26 -8
- package/dist/components/AttachmentCard/AttachmentCard.d.ts +22 -2
- package/dist/components/AttachmentCard/AttachmentCard.js +47 -3
- package/dist/components/Avatar/Avatar.css +7 -2
- package/dist/components/Avatar/AvatarGroup.d.ts +17 -0
- package/dist/components/Avatar/AvatarGroup.js +22 -8
- package/dist/components/Badge/Badge.css +67 -2
- package/dist/components/Badge/Badge.d.ts +23 -4
- package/dist/components/Badge/Badge.js +4 -0
- package/dist/components/Box/Box.css +83 -0
- package/dist/components/Box/Box.d.ts +82 -2
- package/dist/components/Box/Box.js +42 -2
- package/dist/components/Button/Button.css +29 -0
- package/dist/components/Button/Button.d.ts +4 -4
- package/dist/components/Button/Button.js +4 -1
- package/dist/components/Calendar/Calendar.css +245 -0
- package/dist/components/Calendar/Calendar.d.ts +126 -0
- package/dist/components/Calendar/Calendar.js +320 -0
- package/dist/components/Chips/Chips.css +38 -0
- package/dist/components/Chips/Chips.d.ts +5 -2
- package/dist/components/Chips/Chips.js +2 -1
- package/dist/components/Coachmark/Coachmark.css +128 -0
- package/dist/components/Coachmark/Coachmark.d.ts +87 -0
- package/dist/components/Coachmark/Coachmark.js +362 -0
- package/dist/components/CodeBlock/CodeBlock.css +96 -0
- package/dist/components/CodeBlock/CodeBlock.d.ts +47 -0
- package/dist/components/CodeBlock/CodeBlock.js +103 -0
- package/dist/components/ColorPicker/ColorPicker.css +140 -0
- package/dist/components/ColorPicker/ColorPicker.d.ts +73 -0
- package/dist/components/ColorPicker/ColorPicker.js +219 -0
- package/dist/components/Combobox/Combobox.css +8 -0
- package/dist/components/DataTable/DataTable.css +254 -0
- package/dist/components/DataTable/DataTable.d.ts +81 -5
- package/dist/components/DataTable/DataTable.js +335 -19
- package/dist/components/DatePicker/DatePicker.css +8 -0
- package/dist/components/DatePicker/DatePicker.js +10 -1
- package/dist/components/DescriptionList/DescriptionList.css +127 -0
- package/dist/components/DescriptionList/DescriptionList.d.ts +62 -0
- package/dist/components/DescriptionList/DescriptionList.js +52 -0
- package/dist/components/EmptyState/EmptyState.d.ts +4 -2
- package/dist/components/EmptyState/EmptyState.js +2 -2
- package/dist/components/FileInput/FileInput.css +16 -0
- package/dist/components/FileInput/FileInput.d.ts +4 -2
- package/dist/components/FileInput/FileInput.js +8 -2
- package/dist/components/Grid/Grid.js +5 -5
- package/dist/components/IconPicker/IconPicker.css +107 -0
- package/dist/components/IconPicker/IconPicker.d.ts +74 -0
- package/dist/components/IconPicker/IconPicker.js +194 -0
- package/dist/components/Input/Input.css +59 -0
- package/dist/components/Input/Input.d.ts +17 -1
- package/dist/components/Input/Input.js +67 -5
- package/dist/components/Kanban/Kanban.css +4 -0
- package/dist/components/Kbd/Kbd.css +66 -0
- package/dist/components/Kbd/Kbd.d.ts +32 -0
- package/dist/components/Kbd/Kbd.js +40 -0
- package/dist/components/List/List.css +136 -0
- package/dist/components/List/List.d.ts +82 -0
- package/dist/components/List/List.js +53 -0
- package/dist/components/List/ListItem.d.ts +97 -0
- package/dist/components/List/ListItem.js +82 -0
- package/dist/components/Modal/Modal.css +80 -0
- package/dist/components/Modal/Modal.d.ts +33 -6
- package/dist/components/Modal/Modal.js +101 -6
- package/dist/components/MultiSelect/MultiSelect.css +8 -0
- package/dist/components/MultiSelect/MultiSelect.js +10 -1
- package/dist/components/OrgChart/OrgChart.css +149 -0
- package/dist/components/OrgChart/OrgChart.d.ts +83 -0
- package/dist/components/OrgChart/OrgChart.js +297 -0
- package/dist/components/OtpInput/OtpInput.css +93 -0
- package/dist/components/OtpInput/OtpInput.d.ts +60 -0
- package/dist/components/OtpInput/OtpInput.js +215 -0
- package/dist/components/PhoneInput/PhoneInput.css +8 -0
- package/dist/components/Popover/Popover.d.ts +7 -0
- package/dist/components/Popover/Popover.js +11 -1
- package/dist/components/RichTextEditor/RichTextEditor.css +250 -0
- package/dist/components/RichTextEditor/RichTextEditor.d.ts +97 -0
- package/dist/components/RichTextEditor/RichTextEditor.js +951 -0
- package/dist/components/SegmentedControl/SegmentedControl.css +24 -0
- package/dist/components/SegmentedControl/SegmentedControl.d.ts +2 -0
- package/dist/components/SegmentedControl/SegmentedControl.js +10 -2
- package/dist/components/Select/Select.css +164 -0
- package/dist/components/Select/Select.d.ts +34 -0
- package/dist/components/Select/Select.js +258 -28
- package/dist/components/Stack/Stack.css +49 -0
- package/dist/components/Stack/Stack.d.ts +65 -7
- package/dist/components/Stack/Stack.js +30 -2
- package/dist/components/StatCard/StatCard.css +138 -0
- package/dist/components/StatCard/StatCard.d.ts +26 -0
- package/dist/components/StatCard/StatCard.js +13 -1
- package/dist/components/Tabs/Tab.d.ts +15 -0
- package/dist/components/Tabs/Tab.js +30 -1
- package/dist/components/Tabs/Tabs.css +132 -0
- package/dist/components/Tabs/Tabs.d.ts +7 -0
- package/dist/components/Tabs/Tabs.js +13 -2
- package/dist/components/Tag/Tag.css +85 -2
- package/dist/components/Tag/Tag.d.ts +13 -6
- package/dist/components/Tag/Tag.js +1 -0
- package/dist/components/Text/Text.js +2 -2
- package/dist/components/Textarea/Textarea.css +8 -0
- package/dist/components/TimePicker/TimePicker.css +8 -0
- package/dist/components/Toast/Toast.css +32 -0
- package/dist/components/Toast/Toast.d.ts +18 -0
- package/dist/components/Toast/Toast.js +14 -1
- package/dist/components/Toast/ToastStack.js +8 -1
- package/dist/components/Tooltip/Tooltip.css +25 -0
- package/dist/components/Tooltip/Tooltip.d.ts +11 -0
- package/dist/components/Tooltip/Tooltip.js +18 -3
- package/dist/index.d.ts +25 -0
- package/dist/index.js +14 -0
- package/dist/teste/AILabel.test.d.ts +1 -0
- package/dist/teste/AILabel.test.js +33 -0
- package/dist/teste/AccordionConteudoLivre.test.d.ts +1 -0
- package/dist/teste/AccordionConteudoLivre.test.js +29 -0
- package/dist/teste/AccordionTituloNeutro.test.d.ts +1 -0
- package/dist/teste/AccordionTituloNeutro.test.js +23 -0
- package/dist/teste/AppSubheaderRegiao.test.d.ts +1 -0
- package/dist/teste/AppSubheaderRegiao.test.js +13 -0
- package/dist/teste/AtributosRepassados.test.d.ts +1 -0
- package/dist/teste/AtributosRepassados.test.js +52 -0
- package/dist/teste/AttachmentCardIA.test.d.ts +1 -0
- package/dist/teste/AttachmentCardIA.test.js +89 -0
- package/dist/teste/AttachmentCardLista.test.d.ts +1 -0
- package/dist/teste/AttachmentCardLista.test.js +49 -0
- package/dist/teste/AttachmentCardSm.test.d.ts +1 -0
- package/dist/teste/AttachmentCardSm.test.js +26 -0
- package/dist/teste/AvatarGroupOverlap.test.d.ts +1 -0
- package/dist/teste/AvatarGroupOverlap.test.js +56 -0
- package/dist/teste/BadgeNeutroColado.test.d.ts +1 -0
- package/dist/teste/BadgeNeutroColado.test.js +11 -0
- package/dist/teste/BadgeTag.test.d.ts +1 -0
- package/dist/teste/BadgeTag.test.js +55 -0
- package/dist/teste/BoxItemFlex.test.d.ts +1 -0
- package/dist/teste/BoxItemFlex.test.js +54 -0
- package/dist/teste/BoxLayout.test.d.ts +1 -0
- package/dist/teste/BoxLayout.test.js +35 -0
- package/dist/teste/Button.test.d.ts +1 -0
- package/dist/teste/Button.test.js +27 -0
- package/dist/teste/Calendar.test.d.ts +1 -0
- package/dist/teste/Calendar.test.js +221 -0
- package/dist/teste/CalendarCabecalho.test.d.ts +1 -0
- package/dist/teste/CalendarCabecalho.test.js +11 -0
- package/dist/teste/ChipsXs.test.d.ts +1 -0
- package/dist/teste/ChipsXs.test.js +31 -0
- package/dist/teste/Coachmark.test.d.ts +1 -0
- package/dist/teste/Coachmark.test.js +149 -0
- package/dist/teste/CoachmarkSemVeu.test.d.ts +1 -0
- package/dist/teste/CoachmarkSemVeu.test.js +85 -0
- package/dist/teste/ColorPicker.test.d.ts +1 -0
- package/dist/teste/ColorPicker.test.js +132 -0
- package/dist/teste/ColorPickerXs.test.d.ts +1 -0
- package/dist/teste/ColorPickerXs.test.js +21 -0
- package/dist/teste/DataTableArvoreEVariantes.test.d.ts +1 -0
- package/dist/teste/DataTableArvoreEVariantes.test.js +190 -0
- package/dist/teste/DataTableCelulaLivre.test.d.ts +1 -0
- package/dist/teste/DataTableCelulaLivre.test.js +76 -0
- package/dist/teste/DataTableDocumento.test.d.ts +1 -0
- package/dist/teste/DataTableDocumento.test.js +92 -0
- package/dist/teste/DatePicker.test.js +23 -0
- package/dist/teste/DescriptionListCompacta.test.d.ts +1 -0
- package/dist/teste/DescriptionListCompacta.test.js +22 -0
- package/dist/teste/EmptyStateTituloRico.test.d.ts +1 -0
- package/dist/teste/EmptyStateTituloRico.test.js +23 -0
- package/dist/teste/FileInputTrigger.test.d.ts +1 -0
- package/dist/teste/FileInputTrigger.test.js +53 -0
- package/dist/teste/IconPicker.test.d.ts +1 -0
- package/dist/teste/IconPicker.test.js +130 -0
- package/dist/teste/InputAgrupado.test.d.ts +1 -0
- package/dist/teste/InputAgrupado.test.js +24 -0
- package/dist/teste/InputMascaraEAfins.test.d.ts +1 -0
- package/dist/teste/InputMascaraEAfins.test.js +99 -0
- package/dist/teste/KbdCodeBlock.test.d.ts +1 -0
- package/dist/teste/KbdCodeBlock.test.js +95 -0
- package/dist/teste/List.test.d.ts +1 -0
- package/dist/teste/List.test.js +153 -0
- package/dist/teste/ListItemTooltipStandalone.test.d.ts +1 -0
- package/dist/teste/ListItemTooltipStandalone.test.js +39 -0
- package/dist/teste/ModalVariantes.test.d.ts +1 -0
- package/dist/teste/ModalVariantes.test.js +151 -0
- package/dist/teste/NomeAcessivelSsr.test.d.ts +1 -0
- package/dist/teste/NomeAcessivelSsr.test.js +88 -0
- package/dist/teste/OrgChart.test.d.ts +1 -0
- package/dist/teste/OrgChart.test.js +162 -0
- package/dist/teste/OtpInput.test.d.ts +1 -0
- package/dist/teste/OtpInput.test.js +143 -0
- package/dist/teste/PopoverMaxHeight.test.d.ts +1 -0
- package/dist/teste/PopoverMaxHeight.test.js +38 -0
- package/dist/teste/RichTextEditor.test.d.ts +1 -0
- package/dist/teste/RichTextEditor.test.js +287 -0
- package/dist/teste/RichTextEditorAlinhaImagemTabela.test.d.ts +1 -0
- package/dist/teste/RichTextEditorAlinhaImagemTabela.test.js +212 -0
- package/dist/teste/RichTextEditorEstiloDeTexto.test.d.ts +1 -0
- package/dist/teste/RichTextEditorEstiloDeTexto.test.js +120 -0
- package/dist/teste/SegmentedControlContador.test.d.ts +1 -0
- package/dist/teste/SegmentedControlContador.test.js +39 -0
- package/dist/teste/SelectAbertoControladoEFlutuante.test.d.ts +1 -0
- package/dist/teste/SelectAbertoControladoEFlutuante.test.js +145 -0
- package/dist/teste/SelectFiltroCorETamanho.test.d.ts +1 -0
- package/dist/teste/SelectFiltroCorETamanho.test.js +77 -0
- package/dist/teste/SelectPlacementFiltro.test.d.ts +1 -0
- package/dist/teste/SelectPlacementFiltro.test.js +88 -0
- package/dist/teste/Stack.test.d.ts +1 -0
- package/dist/teste/Stack.test.js +57 -0
- package/dist/teste/StatCardRotuloTopo.test.d.ts +1 -0
- package/dist/teste/StatCardRotuloTopo.test.js +34 -0
- package/dist/teste/StatCardSecundariaETom.test.d.ts +1 -0
- package/dist/teste/StatCardSecundariaETom.test.js +45 -0
- package/dist/teste/TabsContadorFechavel.test.d.ts +1 -0
- package/dist/teste/TabsContadorFechavel.test.js +79 -0
- package/dist/teste/ToastAcaoEDetalhes.test.d.ts +1 -0
- package/dist/teste/ToastAcaoEDetalhes.test.js +94 -0
- package/dist/teste/TooltipDark.test.d.ts +1 -0
- package/dist/teste/TooltipDark.test.js +31 -0
- package/dist/utils/calendario.d.ts +28 -0
- package/dist/utils/calendario.js +73 -0
- package/dist/utils/html-seguro.d.ts +45 -0
- package/dist/utils/html-seguro.js +208 -0
- package/dist/utils/paleta-de-cores.d.ts +26 -0
- package/dist/utils/paleta-de-cores.js +10 -0
- package/dist/utils/texto.d.ts +5 -0
- package/dist/utils/texto.js +5 -0
- package/dist/utils/toast.d.ts +10 -1
- package/dist/utils/toast.js +2 -1
- package/package.json +3 -3
- package/src/index.ts +26 -0
- package/src/teste/AILabel.test.tsx +41 -0
- package/src/teste/AccordionConteudoLivre.test.tsx +39 -0
- package/src/teste/AccordionTituloNeutro.test.tsx +25 -0
- package/src/teste/AppSubheaderRegiao.test.tsx +17 -0
- package/src/teste/AtributosRepassados.test.tsx +73 -0
- package/src/teste/AttachmentCardIA.test.tsx +126 -0
- package/src/teste/AttachmentCardLista.test.tsx +53 -0
- package/src/teste/AttachmentCardSm.test.tsx +29 -0
- package/src/teste/AvatarGroupOverlap.test.tsx +74 -0
- package/src/teste/BadgeNeutroColado.test.tsx +15 -0
- package/src/teste/BadgeTag.test.tsx +85 -0
- package/src/teste/BoxItemFlex.test.tsx +81 -0
- package/src/teste/BoxLayout.test.tsx +50 -0
- package/src/teste/Button.test.tsx +39 -0
- package/src/teste/Calendar.test.tsx +282 -0
- package/src/teste/CalendarCabecalho.test.tsx +11 -0
- package/src/teste/ChipsXs.test.tsx +41 -0
- package/src/teste/Coachmark.test.tsx +198 -0
- package/src/teste/CoachmarkSemVeu.test.tsx +101 -0
- package/src/teste/ColorPicker.test.tsx +153 -0
- package/src/teste/ColorPickerXs.test.tsx +22 -0
- package/src/teste/DataTableArvoreEVariantes.test.tsx +240 -0
- package/src/teste/DataTableCelulaLivre.test.tsx +103 -0
- package/src/teste/DataTableDocumento.test.tsx +102 -0
- package/src/teste/DatePicker.test.tsx +38 -0
- package/src/teste/DescriptionListCompacta.test.tsx +24 -0
- package/src/teste/EmptyStateTituloRico.test.tsx +34 -0
- package/src/teste/FileInputTrigger.test.tsx +89 -0
- package/src/teste/IconPicker.test.tsx +145 -0
- package/src/teste/InputAgrupado.test.tsx +26 -0
- package/src/teste/InputMascaraEAfins.test.tsx +124 -0
- package/src/teste/KbdCodeBlock.test.tsx +106 -0
- package/src/teste/List.test.tsx +269 -0
- package/src/teste/ListItemTooltipStandalone.test.tsx +64 -0
- package/src/teste/ModalVariantes.test.tsx +173 -0
- package/src/teste/NomeAcessivelSsr.test.tsx +110 -0
- package/src/teste/OrgChart.test.tsx +183 -0
- package/src/teste/OtpInput.test.tsx +163 -0
- package/src/teste/PopoverMaxHeight.test.tsx +47 -0
- package/src/teste/RichTextEditor.test.tsx +329 -0
- package/src/teste/RichTextEditorAlinhaImagemTabela.test.tsx +238 -0
- package/src/teste/RichTextEditorEstiloDeTexto.test.tsx +137 -0
- package/src/teste/SegmentedControlContador.test.tsx +43 -0
- package/src/teste/SelectAbertoControladoEFlutuante.test.tsx +180 -0
- package/src/teste/SelectFiltroCorETamanho.test.tsx +90 -0
- package/src/teste/SelectPlacementFiltro.test.tsx +110 -0
- package/src/teste/Stack.test.tsx +80 -0
- package/src/teste/StatCardRotuloTopo.test.tsx +44 -0
- package/src/teste/StatCardSecundariaETom.test.tsx +51 -0
- package/src/teste/TabsContadorFechavel.test.tsx +144 -0
- package/src/teste/ToastAcaoEDetalhes.test.tsx +109 -0
- package/src/teste/TooltipDark.test.tsx +51 -0
- package/src/utils/calendario.ts +78 -0
- package/src/utils/html-seguro.ts +197 -0
- package/src/utils/paleta-de-cores.ts +34 -0
- package/src/utils/texto.ts +5 -0
- package/src/utils/toast.ts +12 -2
|
@@ -5,7 +5,7 @@ import { useState } from "react";
|
|
|
5
5
|
import { faWandMagicSparkles } from "@fortawesome/free-solid-svg-icons";
|
|
6
6
|
import Icon from "../Icon/Icon";
|
|
7
7
|
function AILabel(props) {
|
|
8
|
-
const [internalOpen, setInternalOpen] = useState(() =>
|
|
8
|
+
const [internalOpen, setInternalOpen] = useState(() => props.defaultOpen === true);
|
|
9
9
|
const [uid, setUid] = useState(() => `umds-ailabel-${Math.random().toString(36).slice(2, 9)}`);
|
|
10
10
|
function baseId() {
|
|
11
11
|
return props.id || uid;
|
|
@@ -99,6 +99,19 @@
|
|
|
99
99
|
opacity: 0.6; /* opacidade do protótipo sem token 1DS */
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
/* ── Título neutro (titleVariant="neutral") ──
|
|
103
|
+
14px na cor do texto, em peso médio, também no hover e no aberto: o título não
|
|
104
|
+
pega a cor de ação. O chevron aberto continua azul (é o sinal do estado). */
|
|
105
|
+
.umds-accordion--title-neutral .umds-accordion__title {
|
|
106
|
+
font-size: var(--umds-primitive-font-size-xxs); /* 14px */
|
|
107
|
+
font-weight: var(--umds-primitive-font-weight-medium);
|
|
108
|
+
color: var(--umds-semantic-color-neutral-dark-pure);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.umds-accordion--title-neutral .umds-accordion__trigger:disabled .umds-accordion__title {
|
|
112
|
+
color: inherit;
|
|
113
|
+
}
|
|
114
|
+
|
|
102
115
|
/* ── Chevron ──
|
|
103
116
|
Migrado de <svg> inline para o componente Icon (chevron-down).
|
|
104
117
|
O wrapper .umds-accordion__chevron recebe cor (via currentColor →
|
|
@@ -2,16 +2,21 @@ import './Accordion.css';
|
|
|
2
2
|
export interface AccordionItemData {
|
|
3
3
|
id: string;
|
|
4
4
|
title: string;
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* Conteúdo do painel. React: aceita qualquer nó. Vue: aqui vai só texto; para
|
|
7
|
+
* conteúdo livre (campos, botões) use o slot `#content-<id>` do item, que
|
|
8
|
+
* recebe `{ item }` e vale sobre este texto.
|
|
9
|
+
*/
|
|
6
10
|
content: any;
|
|
7
11
|
disabled?: boolean;
|
|
8
12
|
defaultOpen?: boolean;
|
|
9
13
|
}
|
|
10
14
|
/**
|
|
11
15
|
* Accordion component — lista de painéis expansíveis (sanfona).
|
|
12
|
-
* @property {AccordionItemData[]} items - Itens do accordion (id, title, content, disabled?, defaultOpen?)
|
|
16
|
+
* @property {AccordionItemData[]} items - Itens do accordion (id, title, content, disabled?, defaultOpen?). Conteúdo livre por item: no React, `content` aceita nó; no Vue, o slot `#content-<id>` (recebe `{ item }`).
|
|
13
17
|
* @property {boolean} multiple - Permite manter vários painéis abertos ao mesmo tempo
|
|
14
18
|
* @property {string} variant - Estilo visual: 'default' | 'bordered' | 'separated'
|
|
19
|
+
* @property {string} titleVariant - Título dos itens: 'default' | 'neutral'. O `neutral` é o título de texto, 14px na cor do texto, sem cor de ação (como um `Button text` neutro), para o accordion do CrisDoc.
|
|
15
20
|
* @property {string} className - Classes CSS adicionais
|
|
16
21
|
* @quandoUsar Conteúdo que fica RECOLHIDO até o usuário querer: FAQ, seções opcionais de formulário, detalhes secundários. Vários podem abrir juntos com `multiple`.
|
|
17
22
|
* @quandoNaoUsar Para alternar entre visões equivalentes sempre disponíveis — use `Tabs`. Se o conteúdo é essencial, não esconda atrás de acordeão.
|
|
@@ -20,6 +25,8 @@ export interface AccordionProps {
|
|
|
20
25
|
items: AccordionItemData[];
|
|
21
26
|
multiple?: boolean;
|
|
22
27
|
variant?: "default" | "bordered" | "separated";
|
|
28
|
+
/** Título dos itens. `neutral`: 14px na cor do texto, peso médio. @default 'default' */
|
|
29
|
+
titleVariant?: "default" | "neutral";
|
|
23
30
|
className?: string;
|
|
24
31
|
}
|
|
25
32
|
declare function Accordion(props: AccordionProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -21,14 +21,23 @@
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
/* O contexto cede espaço e rola sozinho: uma trilha longa não pode empurrar
|
|
24
|
-
a busca e as ações para fora da tela.
|
|
24
|
+
a busca e as ações para fora da tela.
|
|
25
|
+
Só rola na HORIZONTAL, e só quando a trilha estoura. `overflow-x: auto` sozinho
|
|
26
|
+
faz o `overflow-y` computar para `auto` também, e o `line-height` do item do
|
|
27
|
+
Breadcrumb (12px, numa linha de 12px) deixa o conteúdo 2px acima da caixa de 12px
|
|
28
|
+
(medido: scrollHeight 14, clientHeight 12): com a trilha só na página atual (sem
|
|
29
|
+
link para focar) o axe acusa `scrollable-region-focusable`. Por isso a região
|
|
30
|
+
ocupa a altura da barra (`align-self: stretch`, o conteúdo segue centralizado) e o
|
|
31
|
+
eixo vertical é cortado: não há o que rolar na vertical. */
|
|
25
32
|
.umds-app-subheader__contexto {
|
|
26
33
|
flex: 1;
|
|
34
|
+
align-self: stretch;
|
|
27
35
|
min-width: 0;
|
|
28
36
|
display: flex;
|
|
29
37
|
align-items: center;
|
|
30
38
|
gap: var(--umds-primitive-spacing-nano);
|
|
31
39
|
overflow-x: auto;
|
|
40
|
+
overflow-y: hidden;
|
|
32
41
|
scrollbar-width: none;
|
|
33
42
|
}
|
|
34
43
|
|
|
@@ -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);
|
|
@@ -167,18 +183,10 @@
|
|
|
167
183
|
}
|
|
168
184
|
|
|
169
185
|
.umds-attachment-card__campo {
|
|
170
|
-
display: flex;
|
|
171
|
-
align-items: center;
|
|
172
|
-
gap: var(--umds-primitive-spacing-nano);
|
|
173
186
|
padding: var(--umds-primitive-spacing-nano) 0;
|
|
174
187
|
border-top: 1px solid var(--umds-semantic-color-neutral-light-medium);
|
|
175
188
|
}
|
|
176
189
|
|
|
177
|
-
.umds-attachment-card__campo-texto {
|
|
178
|
-
flex: 1;
|
|
179
|
-
min-width: 0;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
190
|
.umds-attachment-card__campo-rotulo {
|
|
183
191
|
color: var(--umds-semantic-color-neutral-dark-down);
|
|
184
192
|
font-size: var(--umds-primitive-font-size-xxxs);
|
|
@@ -186,7 +194,12 @@
|
|
|
186
194
|
text-transform: uppercase;
|
|
187
195
|
}
|
|
188
196
|
|
|
197
|
+
/* O valor e o botão de copiar na mesma linha: o botão mora dentro do <dd> (o <dl> só aceita
|
|
198
|
+
<dt> e <dd> dentro do <div>). */
|
|
189
199
|
.umds-attachment-card__campo-valor {
|
|
200
|
+
display: flex;
|
|
201
|
+
align-items: center;
|
|
202
|
+
gap: var(--umds-primitive-spacing-nano);
|
|
190
203
|
margin: var(--umds-primitive-spacing-micro) 0 0; /* 2px: respiro rótulo→valor */
|
|
191
204
|
font-size: var(--umds-primitive-font-size-xxs);
|
|
192
205
|
font-weight: var(--umds-primitive-font-weight-bold);
|
|
@@ -194,6 +207,11 @@
|
|
|
194
207
|
overflow-wrap: anywhere;
|
|
195
208
|
}
|
|
196
209
|
|
|
210
|
+
.umds-attachment-card__campo-valor-texto {
|
|
211
|
+
flex: 1;
|
|
212
|
+
min-width: 0;
|
|
213
|
+
}
|
|
214
|
+
|
|
197
215
|
/* Alvo de toque WCAG 2.5.8: 32×32. */
|
|
198
216
|
.umds-attachment-card__copiar {
|
|
199
217
|
display: inline-flex;
|
|
@@ -6,12 +6,16 @@ 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.
|
|
18
|
+
* @property {string} size - Tamanho do cartão: 'md' (padrão) | 'sm'. O `sm` é o compacto do CrisDoc: ícone do preview de 40px (no `md`, 48px) e ícone do rodapé de 12px (no `md`, 16px). A largura e os selos não mudam.
|
|
15
19
|
* @property {Function} onOpen - Abre o anexo. Com ele o cartão inteiro vira alvo de clique, com um único ponto de foco.
|
|
16
20
|
* @property {string} openAriaLabel - Nome acessível da ação de abrir. Padrão: "Abrir <tipo>: <arquivo>".
|
|
17
21
|
* @property {string} className - Classes CSS adicionais
|
|
@@ -37,12 +41,28 @@ export interface AttachmentCardProps {
|
|
|
37
41
|
fileName: string;
|
|
38
42
|
documentType?: string;
|
|
39
43
|
required?: boolean;
|
|
40
|
-
status?: "positive" | "negative";
|
|
44
|
+
status?: "positive" | "negative" | "ai";
|
|
41
45
|
statusLabel?: string;
|
|
42
46
|
statusIcon?: IconProp;
|
|
43
47
|
statusDetails?: AttachmentCardStatusDetails;
|
|
48
|
+
/**
|
|
49
|
+
* Conteúdo livre do painel do selo, no lugar do resultado da conferência
|
|
50
|
+
* (`statusDetails`): ações, campos, texto. React: o elemento; Vue: o slot
|
|
51
|
+
* `panel`. Com ele o selo vira botão mesmo sem `statusDetails`.
|
|
52
|
+
*/
|
|
53
|
+
panel?: any;
|
|
54
|
+
/** Largura do painel, em px. @default 300 */
|
|
55
|
+
panelWidth?: number;
|
|
56
|
+
/**
|
|
57
|
+
* Fecha o painel e devolve o foco ao selo quando alguém aciona um botão ou
|
|
58
|
+
* link de dentro dele. O botão de copiar um campo não conta. Sem a prop, o
|
|
59
|
+
* painel fica aberto até Esc, clique fora ou o foco sair.
|
|
60
|
+
*/
|
|
61
|
+
closePanelOnAction?: boolean;
|
|
44
62
|
onCopyField?: (field: AttachmentCardField) => void;
|
|
45
63
|
icon?: IconProp;
|
|
64
|
+
/** Tamanho do cartão. `sm`: ícone do preview de 40px e ícone do rodapé de 12px. @default 'md' */
|
|
65
|
+
size?: "md" | "sm";
|
|
46
66
|
onOpen?: (event?: any) => void;
|
|
47
67
|
openAriaLabel?: string;
|
|
48
68
|
/** 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 */
|
|
@@ -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"])';
|
|
@@ -29,6 +29,7 @@ function AttachmentCard(props) {
|
|
|
29
29
|
return [
|
|
30
30
|
"umds-attachment-card",
|
|
31
31
|
props.onOpen ? "umds-attachment-card--interativo" : "",
|
|
32
|
+
props.size === "sm" ? "umds-attachment-card--sm" : "",
|
|
32
33
|
props.className,
|
|
33
34
|
]
|
|
34
35
|
.filter(Boolean)
|
|
@@ -47,7 +48,30 @@ function AttachmentCard(props) {
|
|
|
47
48
|
return Boolean(props.status && props.statusLabel);
|
|
48
49
|
}
|
|
49
50
|
function temDetalhe() {
|
|
50
|
-
return Boolean(temSelo() && props.statusDetails);
|
|
51
|
+
return Boolean(temSelo() && (props.statusDetails || props.panel));
|
|
52
|
+
}
|
|
53
|
+
function painelTemConteudoLivre() {
|
|
54
|
+
return Boolean(props.panel);
|
|
55
|
+
}
|
|
56
|
+
function seloIcone() {
|
|
57
|
+
if (props.statusIcon)
|
|
58
|
+
return props.statusIcon;
|
|
59
|
+
return props.status === "ai" ? faWandMagicSparkles : undefined;
|
|
60
|
+
}
|
|
61
|
+
function detalheEstilo() {
|
|
62
|
+
return props.panelWidth
|
|
63
|
+
? {
|
|
64
|
+
width: props.panelWidth + "px",
|
|
65
|
+
}
|
|
66
|
+
: undefined;
|
|
67
|
+
}
|
|
68
|
+
function painelNomeadoPor() {
|
|
69
|
+
return props.panel ? undefined : tituloId();
|
|
70
|
+
}
|
|
71
|
+
function painelRotulo() {
|
|
72
|
+
if (!props.panel)
|
|
73
|
+
return undefined;
|
|
74
|
+
return (props.statusLabel || "") + seloComplemento();
|
|
51
75
|
}
|
|
52
76
|
function painelId() {
|
|
53
77
|
return `${props.id || uid}-conferencia`;
|
|
@@ -85,6 +109,8 @@ function AttachmentCard(props) {
|
|
|
85
109
|
return (props.statusDetails && props.statusDetails.fields) || [];
|
|
86
110
|
}
|
|
87
111
|
function detalheIcone() {
|
|
112
|
+
if (props.status === "ai")
|
|
113
|
+
return faWandMagicSparkles;
|
|
88
114
|
return props.status === "negative" ? faCircleXmark : faCircleCheck;
|
|
89
115
|
}
|
|
90
116
|
function detalheIconeClasses() {
|
|
@@ -120,6 +146,12 @@ function AttachmentCard(props) {
|
|
|
120
146
|
return faFileExcel;
|
|
121
147
|
return faFile;
|
|
122
148
|
}
|
|
149
|
+
function tamanhoIconeCentral() {
|
|
150
|
+
return props.size === "sm" ? "40px" : "48px";
|
|
151
|
+
}
|
|
152
|
+
function tamanhoIconeRodape() {
|
|
153
|
+
return props.size === "sm" ? "12px" : undefined;
|
|
154
|
+
}
|
|
123
155
|
function iconeCentral() {
|
|
124
156
|
return props.icon || faFileLines;
|
|
125
157
|
}
|
|
@@ -283,6 +315,18 @@ function AttachmentCard(props) {
|
|
|
283
315
|
fechar(true);
|
|
284
316
|
}
|
|
285
317
|
}
|
|
318
|
+
function cliqueNoPainel(event) {
|
|
319
|
+
if (!props.closePanelOnAction)
|
|
320
|
+
return;
|
|
321
|
+
const alvo = event.target && event.target.closest
|
|
322
|
+
? event.target.closest("button, a[href]")
|
|
323
|
+
: null;
|
|
324
|
+
if (!alvo)
|
|
325
|
+
return;
|
|
326
|
+
if (alvo.classList.contains("umds-attachment-card__copiar"))
|
|
327
|
+
return;
|
|
328
|
+
fechar(true);
|
|
329
|
+
}
|
|
286
330
|
function teclaNoPainel(event) {
|
|
287
331
|
if (event.key === "Escape") {
|
|
288
332
|
event.preventDefault();
|
|
@@ -349,6 +393,6 @@ function AttachmentCard(props) {
|
|
|
349
393
|
desligarObservadores();
|
|
350
394
|
};
|
|
351
395
|
}, []);
|
|
352
|
-
return (_jsxs("div", { className: classes(), id: props.id, children: [_jsxs("div", { className: "umds-attachment-card__topo", children: [temSelo() && !temDetalhe() ? (_jsxs("span", { className: statusClasses(), children: [
|
|
396
|
+
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: [_jsx("dt", { className: "umds-attachment-card__campo-rotulo", children: campo.label }), _jsxs("dd", { className: "umds-attachment-card__campo-valor", children: [_jsx("span", { className: "umds-attachment-card__campo-valor-texto", 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, { variant: "inherit", icon: iconeCentral(), customSize: tamanhoIconeCentral() }) }), _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(), customSize: tamanhoIconeRodape() }) }), 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 }))] })] }));
|
|
353
397
|
}
|
|
354
398
|
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
|
*/
|
|
@@ -10,22 +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;
|
|
19
20
|
}
|
|
20
21
|
function overflowAriaLabelText() {
|
|
21
22
|
return props.overflowAriaLabel
|
|
22
|
-
? props.overflowAriaLabel(
|
|
23
|
-
: "Mais " +
|
|
23
|
+
? props.overflowAriaLabel(hiddenCount())
|
|
24
|
+
: "Mais " + hiddenCount() + " avatares";
|
|
24
25
|
}
|
|
25
26
|
function overflowTitleText() {
|
|
26
27
|
return props.overflowTitle
|
|
27
|
-
? props.overflowTitle(
|
|
28
|
-
:
|
|
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;
|
|
29
43
|
}
|
|
30
44
|
function size() {
|
|
31
45
|
return props.size || "md";
|
|
@@ -48,6 +62,6 @@ function AvatarGroup(props) {
|
|
|
48
62
|
const second = parts[1] ? parts[1][0] : "";
|
|
49
63
|
return (first + second).toUpperCase();
|
|
50
64
|
}
|
|
51
|
-
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: overflowTitleText(), ariaLabel: overflowAriaLabelText(), children: ["+",
|
|
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] }));
|
|
52
66
|
}
|
|
53
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), attachedSide left | right
|
|
6
7
|
============================================ */
|
|
7
8
|
|
|
8
9
|
.umds-badge {
|
|
@@ -59,6 +60,16 @@
|
|
|
59
60
|
|
|
60
61
|
/* ── Tamanhos — padding + gap por tamanho (sem height fixa) ── */
|
|
61
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
|
+
|
|
62
73
|
.umds-badge--lg {
|
|
63
74
|
font-size: var(--umds-primitive-font-size-xxs); /* 14px */
|
|
64
75
|
padding: var(--umds-primitive-spacing-quarck) var(--umds-primitive-spacing-mini); /* 10px: candidato a novo token */
|
|
@@ -116,6 +127,11 @@
|
|
|
116
127
|
height: 11px;
|
|
117
128
|
}
|
|
118
129
|
|
|
130
|
+
.umds-badge--2xs .umds-badge__icon {
|
|
131
|
+
width: 8px;
|
|
132
|
+
height: 8px;
|
|
133
|
+
}
|
|
134
|
+
|
|
119
135
|
/* ─────────────── SOLID ─────────────── */
|
|
120
136
|
|
|
121
137
|
.umds-badge--solid.umds-badge--neutral {
|
|
@@ -202,3 +218,52 @@
|
|
|
202
218
|
border-color: var(--umds-semantic-color-primary-pure);
|
|
203
219
|
color: var(--umds-semantic-color-primary-pure);
|
|
204
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
|
+
}
|
|
257
|
+
|
|
258
|
+
/* Canto direito (attachedSide="right"): o rótulo cola no canto superior direito. */
|
|
259
|
+
.umds-badge--attached.umds-badge--attached-right {
|
|
260
|
+
left: auto;
|
|
261
|
+
right: 0;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* Neutro colado: cinza claro com texto escuro (o "Tarefa manual" do CrisDoc).
|
|
265
|
+
O `solid` neutro é cinza escuro com texto branco, pesado demais para um rótulo de card. */
|
|
266
|
+
.umds-badge--attached.umds-badge--neutral.umds-badge--solid {
|
|
267
|
+
background-color: var(--umds-semantic-color-neutral-light-medium);
|
|
268
|
+
color: var(--umds-semantic-color-neutral-dark-pure);
|
|
269
|
+
}
|
|
@@ -7,15 +7,34 @@ 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 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). O canto é o esquerdo, ou o
|
|
26
|
+
* direito com `attachedSide="right"`. Com `variant="neutral"` e `appearance="solid"` o
|
|
27
|
+
* rótulo colado é o cinza claro com texto escuro (o "Tarefa manual" do CrisDoc), e não o
|
|
28
|
+
* cinza escuro do `solid`, pesado demais para um rótulo de card.
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
attached?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Em que canto do card o `attached` cola: `left` (padrão) ou `right`.
|
|
34
|
+
* Só vale com `attached`.
|
|
35
|
+
* @default 'left'
|
|
36
|
+
*/
|
|
37
|
+
attachedSide?: "left" | "right";
|
|
19
38
|
/**
|
|
20
39
|
* Estilo visual do badge.
|
|
21
40
|
* @default 'soft'
|
|
@@ -7,6 +7,10 @@ function Badge(props) {
|
|
|
7
7
|
`umds-badge--${props.variant || "neutral"}`,
|
|
8
8
|
`umds-badge--${props.size || "md"}`,
|
|
9
9
|
`umds-badge--${props.appearance || "soft"}`,
|
|
10
|
+
props.attached ? "umds-badge--attached" : "",
|
|
11
|
+
props.attached && props.attachedSide === "right"
|
|
12
|
+
? "umds-badge--attached-right"
|
|
13
|
+
: "",
|
|
10
14
|
props.className,
|
|
11
15
|
]
|
|
12
16
|
.filter(Boolean)
|