@1doc/1ds-react 2.8.0 → 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 +1106 -0
- package/dist/components/AILabel/AILabel.js +1 -1
- package/dist/components/Accordion/Accordion.d.ts +6 -2
- package/dist/components/AttachmentCard/AttachmentCard.css +16 -0
- package/dist/components/AttachmentCard/AttachmentCard.d.ts +19 -2
- package/dist/components/AttachmentCard/AttachmentCard.js +40 -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 +54 -2
- package/dist/components/Badge/Badge.d.ts +14 -4
- package/dist/components/Badge/Badge.js +1 -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 +125 -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 +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 +8 -0
- package/dist/components/DataTable/DataTable.css +80 -0
- package/dist/components/DataTable/DataTable.d.ts +19 -4
- package/dist/components/DataTable/DataTable.js +59 -15
- package/dist/components/DatePicker/DatePicker.css +8 -0
- package/dist/components/DatePicker/DatePicker.js +10 -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/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 +38 -0
- package/dist/components/Input/Input.d.ts +10 -1
- package/dist/components/Input/Input.js +66 -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 +85 -0
- package/dist/components/List/ListItem.js +81 -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 +203 -0
- package/dist/components/RichTextEditor/RichTextEditor.d.ts +83 -0
- package/dist/components/RichTextEditor/RichTextEditor.js +494 -0
- package/dist/components/SegmentedControl/SegmentedControl.js +7 -2
- package/dist/components/Select/Select.css +70 -0
- package/dist/components/Select/Select.d.ts +12 -0
- package/dist/components/Select/Select.js +59 -4
- 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/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/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/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/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/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/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/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/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/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 +27 -0
- package/dist/utils/html-seguro.js +97 -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/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/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/DataTableCelulaLivre.test.tsx +103 -0
- package/src/teste/DataTableDocumento.test.tsx +102 -0
- package/src/teste/DatePicker.test.tsx +38 -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/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/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/TooltipDark.test.tsx +51 -0
- package/src/utils/calendario.ts +78 -0
- package/src/utils/html-seguro.ts +94 -0
- package/src/utils/paleta-de-cores.ts +34 -0
- package/src/utils/texto.ts +5 -0
|
@@ -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;
|
|
@@ -2,14 +2,18 @@ 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'
|
|
15
19
|
* @property {string} className - Classes CSS adicionais
|
|
@@ -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);
|
|
@@ -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,10 +40,24 @@ 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;
|
|
@@ -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`;
|
|
@@ -85,6 +108,8 @@ function AttachmentCard(props) {
|
|
|
85
108
|
return (props.statusDetails && props.statusDetails.fields) || [];
|
|
86
109
|
}
|
|
87
110
|
function detalheIcone() {
|
|
111
|
+
if (props.status === "ai")
|
|
112
|
+
return faWandMagicSparkles;
|
|
88
113
|
return props.status === "negative" ? faCircleXmark : faCircleCheck;
|
|
89
114
|
}
|
|
90
115
|
function detalheIconeClasses() {
|
|
@@ -283,6 +308,18 @@ function AttachmentCard(props) {
|
|
|
283
308
|
fechar(true);
|
|
284
309
|
}
|
|
285
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
|
+
}
|
|
286
323
|
function teclaNoPainel(event) {
|
|
287
324
|
if (event.key === "Escape") {
|
|
288
325
|
event.preventDefault();
|
|
@@ -349,6 +386,6 @@ function AttachmentCard(props) {
|
|
|
349
386
|
desligarObservadores();
|
|
350
387
|
};
|
|
351
388
|
}, []);
|
|
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: [
|
|
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 }))] })] }));
|
|
353
390
|
}
|
|
354
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
|
*/
|
|
@@ -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)
|
|
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,39 @@
|
|
|
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
|
+
}
|
|
@@ -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'
|
|
@@ -99,3 +99,86 @@
|
|
|
99
99
|
.umds-box--shadow-level1 { box-shadow: var(--umds-primitive-shadow-level-1); }
|
|
100
100
|
.umds-box--shadow-level2 { box-shadow: var(--umds-primitive-shadow-level-2); }
|
|
101
101
|
.umds-box--shadow-level3 { box-shadow: var(--umds-primitive-shadow-level-3); }
|
|
102
|
+
|
|
103
|
+
/* ── Layout flex (direction, gap, align, justify, wrap) ──
|
|
104
|
+
Liga quando qualquer uma das props é passada; mesmos nomes e valores do Stack. */
|
|
105
|
+
.umds-box--flex {
|
|
106
|
+
display: flex;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.umds-box--vertical { flex-direction: column; }
|
|
110
|
+
.umds-box--horizontal { flex-direction: row; }
|
|
111
|
+
.umds-box--wrap { flex-wrap: wrap; }
|
|
112
|
+
|
|
113
|
+
.umds-box--gap-none { gap: 0; }
|
|
114
|
+
.umds-box--gap-quarck { gap: var(--umds-primitive-spacing-quarck); }
|
|
115
|
+
.umds-box--gap-nano { gap: var(--umds-primitive-spacing-nano); }
|
|
116
|
+
.umds-box--gap-micro { gap: var(--umds-primitive-spacing-micro); }
|
|
117
|
+
.umds-box--gap-mini { gap: var(--umds-primitive-spacing-mini); }
|
|
118
|
+
.umds-box--gap-xxxs { gap: var(--umds-primitive-spacing-xxxs); }
|
|
119
|
+
.umds-box--gap-xxs { gap: var(--umds-primitive-spacing-xxs); }
|
|
120
|
+
.umds-box--gap-xs { gap: var(--umds-primitive-spacing-xs); }
|
|
121
|
+
.umds-box--gap-sm { gap: var(--umds-primitive-spacing-sm); }
|
|
122
|
+
.umds-box--gap-md { gap: var(--umds-primitive-spacing-md); }
|
|
123
|
+
.umds-box--gap-lg { gap: var(--umds-primitive-spacing-lg); }
|
|
124
|
+
.umds-box--gap-xl { gap: var(--umds-primitive-spacing-xl); }
|
|
125
|
+
.umds-box--gap-xxl { gap: var(--umds-primitive-spacing-xxl); }
|
|
126
|
+
.umds-box--gap-xxxl { gap: var(--umds-primitive-spacing-xxxl); }
|
|
127
|
+
|
|
128
|
+
.umds-box--align-start { align-items: flex-start; }
|
|
129
|
+
.umds-box--align-center { align-items: center; }
|
|
130
|
+
.umds-box--align-end { align-items: flex-end; }
|
|
131
|
+
.umds-box--align-stretch { align-items: stretch; }
|
|
132
|
+
.umds-box--align-baseline { align-items: baseline; }
|
|
133
|
+
|
|
134
|
+
.umds-box--justify-start { justify-content: flex-start; }
|
|
135
|
+
.umds-box--justify-center { justify-content: center; }
|
|
136
|
+
.umds-box--justify-end { justify-content: flex-end; }
|
|
137
|
+
.umds-box--justify-between { justify-content: space-between; }
|
|
138
|
+
.umds-box--justify-around { justify-content: space-around; }
|
|
139
|
+
.umds-box--justify-evenly { justify-content: space-evenly; }
|
|
140
|
+
|
|
141
|
+
/* ── Lista: ul/ol sem marcador, margem nem recuo do navegador ──
|
|
142
|
+
:where() zera a especificidade, para o padding do Box (p, px, py) vencer. */
|
|
143
|
+
:where(ul.umds-box, ol.umds-box) {
|
|
144
|
+
list-style: none;
|
|
145
|
+
margin: 0;
|
|
146
|
+
padding: 0;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/* ── Como item de Stack/Box flex ── */
|
|
150
|
+
.umds-box--grow { flex-grow: 1; }
|
|
151
|
+
.umds-box--shrink-0 { flex-shrink: 0; }
|
|
152
|
+
.umds-box--shrink-1 { flex-shrink: 1; }
|
|
153
|
+
|
|
154
|
+
.umds-box--basis-auto { flex-basis: auto; }
|
|
155
|
+
.umds-box--basis-0 { flex-basis: 0; }
|
|
156
|
+
.umds-box--basis-25 { flex-basis: 25%; }
|
|
157
|
+
.umds-box--basis-33 { flex-basis: 33.3333%; }
|
|
158
|
+
.umds-box--basis-50 { flex-basis: 50%; }
|
|
159
|
+
.umds-box--basis-66 { flex-basis: 66.6667%; }
|
|
160
|
+
.umds-box--basis-75 { flex-basis: 75%; }
|
|
161
|
+
.umds-box--basis-100 { flex-basis: 100%; }
|
|
162
|
+
|
|
163
|
+
/* O padrão do Box já é min-width: 0; estas duas só tornam a escolha explícita. */
|
|
164
|
+
.umds-box--min-w-0 { min-width: 0; }
|
|
165
|
+
.umds-box--min-w-auto { min-width: auto; }
|
|
166
|
+
|
|
167
|
+
/* ── Overflow: o eixo vem depois do geral, então vence por ordem de cascata ── */
|
|
168
|
+
.umds-box--overflow-visible { overflow: visible; }
|
|
169
|
+
.umds-box--overflow-hidden { overflow: hidden; }
|
|
170
|
+
.umds-box--overflow-auto { overflow: auto; }
|
|
171
|
+
.umds-box--overflow-scroll { overflow: scroll; }
|
|
172
|
+
|
|
173
|
+
.umds-box--overflow-x-visible { overflow-x: visible; }
|
|
174
|
+
.umds-box--overflow-x-hidden { overflow-x: hidden; }
|
|
175
|
+
.umds-box--overflow-x-auto { overflow-x: auto; }
|
|
176
|
+
.umds-box--overflow-x-scroll { overflow-x: scroll; }
|
|
177
|
+
|
|
178
|
+
.umds-box--overflow-y-visible { overflow-y: visible; }
|
|
179
|
+
.umds-box--overflow-y-hidden { overflow-y: hidden; }
|
|
180
|
+
.umds-box--overflow-y-auto { overflow-y: auto; }
|
|
181
|
+
.umds-box--overflow-y-scroll { overflow-y: scroll; }
|
|
182
|
+
|
|
183
|
+
/* ── Dimensão ── */
|
|
184
|
+
.umds-box--full-height { height: 100%; }
|
|
@@ -1,12 +1,55 @@
|
|
|
1
1
|
import './Box.css';
|
|
2
2
|
/** Degraus da escala oficial de espaçamento do 1DS. */
|
|
3
3
|
export type BoxSpacing = "none" | "quarck" | "nano" | "micro" | "mini" | "xxxs" | "xxs" | "xs" | "sm" | "md" | "lg" | "xl" | "xxl" | "xxxl";
|
|
4
|
+
/** Elemento HTML que o Box renderiza (mesma lista do Stack). */
|
|
5
|
+
/** Degraus da escala oficial de espaçamento do 1DS. */
|
|
6
|
+
/** Elemento HTML que o Box renderiza (mesma lista do Stack). */
|
|
7
|
+
export type BoxTag = "div" | "span" | "ul" | "ol" | "li" | "section" | "nav" | "header" | "footer" | "form";
|
|
8
|
+
/** Valores de `overflow` aceitos (por eixo ou nos dois). */
|
|
9
|
+
/** Degraus da escala oficial de espaçamento do 1DS. */
|
|
10
|
+
/** Elemento HTML que o Box renderiza (mesma lista do Stack). */
|
|
11
|
+
/** Valores de `overflow` aceitos (por eixo ou nos dois). */
|
|
12
|
+
export type BoxOverflow = "visible" | "hidden" | "auto" | "scroll";
|
|
4
13
|
/**
|
|
5
14
|
* Box — superfície com padding, fundo, borda e raio vindos dos tokens.
|
|
6
15
|
*
|
|
7
16
|
* É a caixa genérica do DS. Existe para evitar o `<div style={{ padding: 16,
|
|
8
17
|
* background: "#fff", borderRadius: 8 }}>` escrito à mão: cada valor sai da
|
|
9
18
|
* escala oficial, não da memória de quem escreve.
|
|
19
|
+
*
|
|
20
|
+
* Também é layout: com `direction`, `gap`, `align`, `justify` ou `wrap` (os
|
|
21
|
+
* mesmos nomes e valores do `Stack`) a caixa vira um flex, e uma linha, um
|
|
22
|
+
* cartão ou uma região com borda, fundo e padding é UM componente só, sem
|
|
23
|
+
* `Stack` por dentro nem flex no CSS do produto. Sem nenhuma dessas props, o
|
|
24
|
+
* Box continua sendo um bloco comum. Diferente do `Stack`, o `gap` do Box
|
|
25
|
+
* não tem valor padrão: sem `gap`, os filhos ficam colados.
|
|
26
|
+
*
|
|
27
|
+
* Também é item de flex: dentro de um `Stack` ou de outro `Box` flex, `grow`,
|
|
28
|
+
* `shrink`, `basis`, `minWidth`, `fullHeight`, `fullWidth` e `overflow*` (os
|
|
29
|
+
* mesmos nomes e valores do `Stack`) fazem a superfície crescer, encolher ou
|
|
30
|
+
* rolar no lugar certo, sem CSS do produto.
|
|
31
|
+
*
|
|
32
|
+
* `as` troca o elemento (`div` por padrão; `section`, `nav`, `li`, `ul`...):
|
|
33
|
+
* uma linha com borda e fundo dentro de uma lista é `<Box as="li">`. Com `nav`,
|
|
34
|
+
* `section` ou `form`, passe `aria-label` ou `aria-labelledby`.
|
|
35
|
+
*
|
|
36
|
+
* Atributos HTML (`id`, `style`, `title`, `role`, `tabIndex`, `data-*`,
|
|
37
|
+
* `aria-*`) vão para o elemento raiz.
|
|
38
|
+
* @property {string} as - Elemento HTML: 'div' (padrão) | 'span' | 'ul' | 'ol' | 'li' | 'section' | 'nav' | 'header' | 'footer' | 'form'
|
|
39
|
+
* @property {boolean} grow - Como item de Stack/Box flex: cresce para ocupar o espaço livre
|
|
40
|
+
* @property {string} shrink - Como item flex: '0' não encolhe, '1' encolhe
|
|
41
|
+
* @property {string} basis - Como item flex: tamanho base ('auto', '0', '25', '33', '50', '66', '75', '100'; os números são %)
|
|
42
|
+
* @property {string} minWidth - '0' (padrão do Box) deixa o conteúdo longo encolher; 'auto' devolve o mínimo do conteúdo
|
|
43
|
+
* @property {string} overflow - Overflow nos dois eixos
|
|
44
|
+
* @property {string} overflowX - Overflow horizontal
|
|
45
|
+
* @property {string} overflowY - Overflow vertical
|
|
46
|
+
* @property {boolean} fullHeight - Ocupa 100% da altura do pai
|
|
47
|
+
* @property {function} onSubmit - Só com as="form": callback do envio
|
|
48
|
+
* @property {string} direction - Liga o layout flex: 'vertical' | 'horizontal'
|
|
49
|
+
* @property {string} gap - Liga o layout flex: espaço entre os filhos, na escala do DS
|
|
50
|
+
* @property {string} align - Liga o layout flex: alinhamento no eixo transversal
|
|
51
|
+
* @property {string} justify - Liga o layout flex: distribuição no eixo principal
|
|
52
|
+
* @property {boolean} wrap - Liga o layout flex: permite quebrar em várias linhas
|
|
10
53
|
* @property {string} padding - Padding em todos os lados, na escala do DS
|
|
11
54
|
* @property {string} paddingX - Padding horizontal (sobrescreve padding)
|
|
12
55
|
* @property {string} paddingY - Padding vertical (sobrescreve padding)
|
|
@@ -16,11 +59,25 @@ export type BoxSpacing = "none" | "quarck" | "nano" | "micro" | "mini" | "xxxs"
|
|
|
16
59
|
* @property {string} shadow - Elevação
|
|
17
60
|
* @property {boolean} fullWidth - Ocupa 100% da largura disponível
|
|
18
61
|
* @property {string} className - Classes CSS adicionais
|
|
19
|
-
* @quandoUsar Agrupar conteúdo numa superfície com respiro e fundo: painel de filtros, bloco de resumo, área destacada dentro de uma tela.
|
|
20
|
-
* @quandoNaoUsar Para um item de listagem com título, ações e elevação própria — use `Card`, que já tem essa anatomia. Para só distribuir filhos no eixo sem desenhar nada, use `Stack`.
|
|
62
|
+
* @quandoUsar Agrupar conteúdo numa superfície com respiro e fundo: painel de filtros, bloco de resumo, área destacada dentro de uma tela. Uma linha de resultado ou um cartão simples cujo conteúdo precisa alinhar em linha (`direction="horizontal"`, `align="center"`, `gap="xxxs"`) com borda, fundo e padding.
|
|
63
|
+
* @quandoNaoUsar Para um item de listagem com título, ações e elevação própria — use `Card`, que já tem essa anatomia. Para uma linha de lista clicável (hover, foco, selecionado), use `ListItem`. Para só distribuir filhos no eixo sem desenhar nada (sem fundo, borda nem padding), use `Stack`.
|
|
21
64
|
*/
|
|
22
65
|
/** Degraus da escala oficial de espaçamento do 1DS. */
|
|
66
|
+
/** Elemento HTML que o Box renderiza (mesma lista do Stack). */
|
|
67
|
+
/** Valores de `overflow` aceitos (por eixo ou nos dois). */
|
|
23
68
|
export interface BoxProps {
|
|
69
|
+
/** Elemento HTML renderizado. @default 'div' */
|
|
70
|
+
as?: BoxTag;
|
|
71
|
+
/** Liga o layout flex. Eixo do empilhamento. @default 'vertical' (quando o flex está ligado) */
|
|
72
|
+
direction?: "vertical" | "horizontal";
|
|
73
|
+
/** Liga o layout flex. Espaço entre os filhos, na escala oficial (`none` = 0). Sem valor, não há espaço. */
|
|
74
|
+
gap?: BoxSpacing;
|
|
75
|
+
/** Liga o layout flex. Alinhamento no eixo transversal. */
|
|
76
|
+
align?: "start" | "center" | "end" | "stretch" | "baseline";
|
|
77
|
+
/** Liga o layout flex. Distribuição no eixo principal. */
|
|
78
|
+
justify?: "start" | "center" | "end" | "between" | "around" | "evenly";
|
|
79
|
+
/** Liga o layout flex. Permite quebrar em várias linhas. */
|
|
80
|
+
wrap?: boolean;
|
|
24
81
|
/** Padding em todos os lados. @default 'none' */
|
|
25
82
|
padding?: BoxSpacing;
|
|
26
83
|
/** Padding horizontal. Sobrescreve `padding` no eixo X. */
|
|
@@ -37,8 +94,31 @@ export interface BoxProps {
|
|
|
37
94
|
shadow?: "none" | "level1" | "level2" | "level3";
|
|
38
95
|
/** Ocupa 100% da largura disponível. */
|
|
39
96
|
fullWidth?: boolean;
|
|
97
|
+
/** Ocupa 100% da altura do pai. */
|
|
98
|
+
fullHeight?: boolean;
|
|
99
|
+
/** Como item de Stack/Box flex: cresce para ocupar o espaço livre. */
|
|
100
|
+
grow?: boolean;
|
|
101
|
+
/** Como item flex: `"0"` não encolhe; `"1"` encolhe. */
|
|
102
|
+
shrink?: "0" | "1";
|
|
103
|
+
/** Como item flex: tamanho base. Os números são porcentagem do pai. */
|
|
104
|
+
basis?: "auto" | "0" | "25" | "33" | "50" | "66" | "75" | "100";
|
|
105
|
+
/** `"0"` (já é o padrão do Box) deixa o conteúdo encolher; `"auto"` volta ao mínimo do conteúdo. */
|
|
106
|
+
minWidth?: "0" | "auto";
|
|
107
|
+
/** Overflow nos dois eixos. */
|
|
108
|
+
overflow?: BoxOverflow;
|
|
109
|
+
/** Overflow horizontal (vence `overflow` no eixo X). */
|
|
110
|
+
overflowX?: BoxOverflow;
|
|
111
|
+
/** Overflow vertical (vence `overflow` no eixo Y). */
|
|
112
|
+
overflowY?: BoxOverflow;
|
|
113
|
+
/** Só com `as="form"`: chamado no envio do formulário. */
|
|
114
|
+
onSubmit?: (event: any) => void;
|
|
40
115
|
/** Classes CSS adicionais. */
|
|
41
116
|
className?: string;
|
|
117
|
+
/** ID HTML do elemento raiz. */
|
|
118
|
+
id?: string;
|
|
119
|
+
/** Atributos HTML repassados ao elemento raiz (style, data-*, aria-*…). */
|
|
120
|
+
style?: any;
|
|
121
|
+
[key: string]: any;
|
|
42
122
|
/** Conteúdo da caixa. */
|
|
43
123
|
children?: any;
|
|
44
124
|
}
|