@1doc/1ds-react 2.13.0 → 2.15.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 +62 -59
- package/dist/components/AILabel/AILabel.css +1 -1
- package/dist/components/Alert/Alert.css +1 -1
- package/dist/components/AppShell/AppShell.css +4 -0
- package/dist/components/AttachmentCard/AttachmentCard.css +2 -2
- package/dist/components/Avatar/Avatar.d.ts +8 -3
- package/dist/components/Avatar/Avatar.js +28 -4
- package/dist/components/BottomNavigation/BottomNavigation.css +2 -2
- package/dist/components/BottomSheet/BottomSheet.css +2 -2
- package/dist/components/Box/Box.css +3 -3
- package/dist/components/Button/Button.css +6 -1
- package/dist/components/Button/Button.d.ts +11 -2
- package/dist/components/Button/Button.js +15 -3
- package/dist/components/Card/Card.css +5 -5
- package/dist/components/Chart/Chart.css +1 -1
- package/dist/components/Coachmark/Coachmark.css +1 -1
- package/dist/components/Combobox/Combobox.css +1 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.css +1 -1
- package/dist/components/Counter/Counter.css +43 -0
- package/dist/components/Counter/Counter.d.ts +57 -0
- package/dist/components/Counter/Counter.js +99 -0
- package/dist/components/DatePicker/DatePicker.css +1 -1
- package/dist/components/Drawer/Drawer.css +2 -2
- package/dist/components/Dropdown/Dropdown.css +3 -1
- package/dist/components/Dropdown/Dropdown.d.ts +17 -0
- package/dist/components/Dropdown/Dropdown.js +22 -2
- package/dist/components/EmptyState/EmptyState.css +12 -0
- package/dist/components/EmptyState/EmptyState.d.ts +3 -0
- package/dist/components/EmptyState/EmptyState.js +1 -0
- package/dist/components/Kanban/Kanban.css +2 -2
- package/dist/components/Kanban/KanbanCard.css +2 -2
- package/dist/components/List/List.css +83 -0
- package/dist/components/List/List.d.ts +3 -0
- package/dist/components/List/List.js +6 -2
- package/dist/components/List/ListItem.d.ts +19 -0
- package/dist/components/List/ListItem.js +5 -1
- package/dist/components/Modal/Modal.css +3 -4
- package/dist/components/MultiSelect/MultiSelect.css +1 -1
- package/dist/components/OrgChart/OrgChart.css +2 -2
- package/dist/components/PhoneInput/PhoneInput.css +2 -2
- package/dist/components/Popover/Popover.css +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.css +1 -1
- package/dist/components/Select/Select.css +1 -1
- package/dist/components/StatCard/StatCard.css +99 -5
- package/dist/components/StatCard/StatCard.d.ts +12 -6
- package/dist/components/StatCard/StatCard.js +6 -2
- package/dist/components/Switch/Switch.css +2 -2
- package/dist/components/Text/Text.d.ts +6 -0
- package/dist/components/TimePicker/TimePicker.css +1 -1
- package/dist/components/Toast/Toast.css +2 -2
- package/dist/components/Tooltip/Tooltip.css +23 -3
- package/dist/components/Tooltip/Tooltip.js +33 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/teste/PedidosMatheus.test.d.ts +1 -0
- package/dist/teste/PedidosMatheus.test.js +91 -0
- package/dist/teste/PedidosMatheus2.test.d.ts +1 -0
- package/dist/teste/PedidosMatheus2.test.js +82 -0
- package/dist/teste/SegmentedControlSuperficie.test.js +1 -1
- package/dist/teste/StatCardTamanhoSm.test.js +8 -0
- package/package.json +3 -3
- package/src/index.ts +2 -0
- package/src/teste/PedidosMatheus.test.tsx +129 -0
- package/src/teste/PedidosMatheus2.test.tsx +102 -0
- package/src/teste/SegmentedControlSuperficie.test.tsx +1 -1
- package/src/teste/StatCardTamanhoSm.test.tsx +9 -0
|
@@ -34,6 +34,15 @@ ol.umds-list {
|
|
|
34
34
|
justify-content: center;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/* emptyFill: a lista vazia ocupa o espaço do pai (coluna que rola, painel) e o
|
|
38
|
+
EmptyState (fill) fica no meio dele. */
|
|
39
|
+
.umds-list--empty-fill {
|
|
40
|
+
flex: 1 1 auto;
|
|
41
|
+
align-self: stretch;
|
|
42
|
+
width: 100%;
|
|
43
|
+
min-height: 100%;
|
|
44
|
+
}
|
|
45
|
+
|
|
37
46
|
/* ── <li> que envolve a linha ── */
|
|
38
47
|
.umds-list__item {
|
|
39
48
|
display: block;
|
|
@@ -134,3 +143,77 @@ ol.umds-list {
|
|
|
134
143
|
display: block;
|
|
135
144
|
color: var(--umds-semantic-color-neutral-dark-down);
|
|
136
145
|
}
|
|
146
|
+
|
|
147
|
+
/* ── Ações da linha (slot `actions`) ──
|
|
148
|
+
O controle fica no `li`, AO LADO do elemento clicável: clicar no ⋮ não
|
|
149
|
+
aciona a linha, e não há botão dentro de link. O `li` vira a linha visual
|
|
150
|
+
(flex), e o hover e a seleção passam do elemento para o `li`, para o fundo
|
|
151
|
+
cobrir as ações também. */
|
|
152
|
+
.umds-list__item:has(> .umds-list-item__actions) {
|
|
153
|
+
display: flex;
|
|
154
|
+
align-items: center;
|
|
155
|
+
gap: var(--umds-primitive-spacing-quarck); /* 4px */
|
|
156
|
+
padding-right: var(--umds-primitive-spacing-nano); /* 8px */
|
|
157
|
+
border-radius: var(--umds-primitive-border-radius-sm); /* 8px */
|
|
158
|
+
transition: background-color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.umds-list__item:has(> .umds-list-item__actions) > .umds-list-item {
|
|
162
|
+
flex: 1 1 auto;
|
|
163
|
+
width: auto;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.umds-list__item:has(> .umds-list-item__actions) > .umds-list-item,
|
|
167
|
+
.umds-list__item:has(> .umds-list-item__actions) > .umds-list-item.umds-list-item--interactive:hover {
|
|
168
|
+
background: transparent;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.umds-list__item:has(> .umds-list-item--interactive:not(.umds-list-item--disabled)):has(> .umds-list-item__actions):hover {
|
|
172
|
+
background: var(--umds-semantic-color-background-light);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.umds-list__item:has(> .umds-list-item--selected):has(> .umds-list-item__actions) {
|
|
176
|
+
background: var(--umds-semantic-color-primary-light);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.umds-list__item:has(> .umds-list-item--selected.umds-list-item--interactive):has(> .umds-list-item__actions):hover {
|
|
180
|
+
background: color-mix(
|
|
181
|
+
in srgb,
|
|
182
|
+
var(--umds-semantic-color-primary-light) 85%,
|
|
183
|
+
var(--umds-semantic-color-background-white)
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.umds-list-item__actions {
|
|
188
|
+
display: inline-flex;
|
|
189
|
+
flex-shrink: 0;
|
|
190
|
+
align-items: center;
|
|
191
|
+
gap: var(--umds-primitive-spacing-quarck); /* 4px */
|
|
192
|
+
}
|
|
193
|
+
/* ── variant="primary": o item em destaque (Central de Ações) ──
|
|
194
|
+
Fundo azul-claro e hover um tom acima, como o cartão da referência. Não é
|
|
195
|
+
seleção (sem aria-current). O fundo é o mesmo azul-claro da seleção; o que\n muda é o hover, que escurece em vez de clarear. */
|
|
196
|
+
.umds-list-item--primary {
|
|
197
|
+
background: var(--umds-semantic-color-primary-light);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.umds-list-item--primary.umds-list-item--interactive:hover {
|
|
201
|
+
background: color-mix(
|
|
202
|
+
in srgb,
|
|
203
|
+
var(--umds-semantic-color-primary-medium) 35%,
|
|
204
|
+
var(--umds-semantic-color-primary-light)
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/* Com ações, a superfície passa para o li (como a seleção). */
|
|
209
|
+
.umds-list__item:has(> .umds-list-item--primary):has(> .umds-list-item__actions) {
|
|
210
|
+
background: var(--umds-semantic-color-primary-light);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.umds-list__item:has(> .umds-list-item--primary.umds-list-item--interactive):has(> .umds-list-item__actions):hover {
|
|
214
|
+
background: color-mix(
|
|
215
|
+
in srgb,
|
|
216
|
+
var(--umds-semantic-color-primary-medium) 35%,
|
|
217
|
+
var(--umds-semantic-color-primary-light)
|
|
218
|
+
);
|
|
219
|
+
}
|
|
@@ -32,6 +32,7 @@ export type ListTag = "ul" | "ol";
|
|
|
32
32
|
* @property {string} emptyDescription - Texto de apoio do estado vazio
|
|
33
33
|
* @property {IconProp} emptyIcon - Ícone do estado vazio (objeto do Font Awesome)
|
|
34
34
|
* @property {string} emptySize - Tamanho do estado vazio: 'sm' (padrão, compacto) | 'md' | 'lg'
|
|
35
|
+
* @property {boolean} emptyFill - O estado vazio ocupa e centraliza no espaço disponível (coluna que rola, painel de altura fixa)
|
|
35
36
|
* @property {string} emptyActionLabel - Rótulo do botão do estado vazio (junto de onEmptyAction)
|
|
36
37
|
* @property {function} onEmptyAction - Callback do botão do estado vazio
|
|
37
38
|
* @property {any} empty - Slot `empty`: conteúdo próprio no lugar do EmptyState
|
|
@@ -61,6 +62,8 @@ export interface ListProps {
|
|
|
61
62
|
emptyIcon?: IconProp;
|
|
62
63
|
/** Tamanho do estado vazio. @default 'sm' */
|
|
63
64
|
emptySize?: "sm" | "md" | "lg";
|
|
65
|
+
/** O estado vazio ocupa e centraliza no espaço disponível. @default false */
|
|
66
|
+
emptyFill?: boolean;
|
|
64
67
|
/** Rótulo do botão do estado vazio (exibido junto de `onEmptyAction`). */
|
|
65
68
|
emptyActionLabel?: string;
|
|
66
69
|
/** Chamado no botão do estado vazio. */
|
|
@@ -21,7 +21,11 @@ function List(props) {
|
|
|
21
21
|
.join(" ");
|
|
22
22
|
}
|
|
23
23
|
function emptyClasses() {
|
|
24
|
-
return [
|
|
24
|
+
return [
|
|
25
|
+
"umds-list umds-list--empty",
|
|
26
|
+
props.emptyFill ? "umds-list--empty-fill" : "",
|
|
27
|
+
props.className,
|
|
28
|
+
]
|
|
25
29
|
.filter(Boolean)
|
|
26
30
|
.join(" ");
|
|
27
31
|
}
|
|
@@ -48,6 +52,6 @@ function List(props) {
|
|
|
48
52
|
}
|
|
49
53
|
return out;
|
|
50
54
|
}
|
|
51
|
-
return (_jsxs(_Fragment, { children: [showEmpty() ? (_jsx("div", { role: "status", id: props.id, ...htmlAttrs(), className: emptyClasses(), children: _jsx(_Fragment, { children: props.empty || (_jsx(EmptyState, { icon: props.emptyIcon, title: emptyTitleText(), description: props.emptyDescription, size: emptySizeValue(), ...emptyActionProps() })) }) })) : null, showItems() && elementTag() === "ul" ? (_jsx("ul", { role: "list", id: props.id, "aria-label": props.ariaLabel, "aria-labelledby": props.ariaLabelledby, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null, showItems() && elementTag() === "ol" ? (_jsx("ol", { role: "list", id: props.id, "aria-label": props.ariaLabel, "aria-labelledby": props.ariaLabelledby, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null] }));
|
|
55
|
+
return (_jsxs(_Fragment, { children: [showEmpty() ? (_jsx("div", { role: "status", id: props.id, ...htmlAttrs(), className: emptyClasses(), children: _jsx(_Fragment, { children: props.empty || (_jsx(EmptyState, { icon: props.emptyIcon, title: emptyTitleText(), description: props.emptyDescription, size: emptySizeValue(), fill: props.emptyFill, ...emptyActionProps() })) }) })) : null, showItems() && elementTag() === "ul" ? (_jsx("ul", { role: "list", id: props.id, "aria-label": props.ariaLabel, "aria-labelledby": props.ariaLabelledby, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null, showItems() && elementTag() === "ol" ? (_jsx("ol", { role: "list", id: props.id, "aria-label": props.ariaLabel, "aria-labelledby": props.ariaLabelledby, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null] }));
|
|
52
56
|
}
|
|
53
57
|
export default List;
|
|
@@ -27,6 +27,12 @@ export type ListItemTag = "button" | "a" | "div";
|
|
|
27
27
|
* HTML: é o título da linha. O atributo `title` (a dica nativa do navegador) é a
|
|
28
28
|
* prop `tooltip`.
|
|
29
29
|
*
|
|
30
|
+
* `actions` é o lugar de controles da linha (o ⋮ de um menu, um botão de
|
|
31
|
+
* excluir): fica no `li`, AO LADO do elemento clicável e não dentro dele, então
|
|
32
|
+
* o clique no controle não aciona a linha e o HTML continua válido. A linha toda
|
|
33
|
+
* (com as ações) ganha o fundo de hover e de seleção. Só existe com o `li`
|
|
34
|
+
* (sem `standalone`).
|
|
35
|
+
*
|
|
30
36
|
* `standalone` tira o `li`: o ListItem vira só o elemento interativo, para uso
|
|
31
37
|
* fora de um `List` (botão de número de página, item de carrossel, linha dentro
|
|
32
38
|
* de um `div`). Fora de `ul`/`ol`, o `li` é HTML inválido.
|
|
@@ -35,6 +41,9 @@ export type ListItemTag = "button" | "a" | "div";
|
|
|
35
41
|
* @property {string} target - Destino do link: '_blank' ganha rel="noopener noreferrer"
|
|
36
42
|
* @property {string} rel - Relação do link (sobrescreve o padrão do target)
|
|
37
43
|
* @property {boolean} selected - Item atual: fundo de seleção e aria-current
|
|
44
|
+
* @property {string} variant - Superfície da linha: 'default' (transparente) | 'primary' (fundo azul-claro com hover próprio, o item em destaque da Central de Ações). Não é seleção: não marca aria-current
|
|
45
|
+
* @property {string} liClassName - Classes CSS do `li` (a linha visual). Use para animação de entrada escalonada; não vale com `standalone`
|
|
46
|
+
* @property {object} liStyle - Estilo inline do `li` (ex.: `{ '--ordem': 3 }` ou `transitionDelay`). Não vale com `standalone`
|
|
38
47
|
* @property {boolean} disabled - Bloqueia clique e foco
|
|
39
48
|
* @property {string} tooltip - Dica nativa do navegador: vira o atributo HTML `title` do elemento interativo
|
|
40
49
|
* @property {boolean} standalone - Renderiza sem o `li`, só o elemento interativo (uso fora de `List`)
|
|
@@ -43,6 +52,7 @@ export type ListItemTag = "button" | "a" | "div";
|
|
|
43
52
|
* @property {any} meta - Terceira linha, menor (data, contexto): texto, ou slot `meta` (nó)
|
|
44
53
|
* @property {any} start - Slot `start`: conteúdo antes do texto (avatar, ícone)
|
|
45
54
|
* @property {any} end - Slot `end`: conteúdo no fim da linha (badge, seta, valor)
|
|
55
|
+
* @property {any} actions - Slot `actions`: controles da linha (menu ⋮, botão), fora do elemento clicável
|
|
46
56
|
* @property {function} onClick - Callback do clique (ou de Enter/Espaço no as="div")
|
|
47
57
|
* @property {string} className - Classes CSS adicionais, no elemento interativo
|
|
48
58
|
* @slot start - Conteúdo antes do texto.
|
|
@@ -50,6 +60,7 @@ export type ListItemTag = "button" | "a" | "div";
|
|
|
50
60
|
* @slot subtitle - Segunda linha (substitui a prop `subtitle`).
|
|
51
61
|
* @slot meta - Terceira linha (substitui a prop `meta`).
|
|
52
62
|
* @slot end - Conteúdo no fim da linha.
|
|
63
|
+
* @slot actions - Controles da linha, ao lado do elemento clicável (não dentro dele).
|
|
53
64
|
* @quandoUsar Itens de uma lista em que a linha toda é a ação: documentos não lidos, notificações, resultados de busca, opções de menu de filtro, itens de navegação secundária. Hover, foco visível e seleção já vêm resolvidos.
|
|
54
65
|
* @quandoNaoUsar Para dados comparados coluna a coluna, use `DataTable`. Para um cartão com título, ações e elevação própria, use `Card`. Para um botão solto fora de lista, use `Button`. Para a navegação principal do produto, use `SidePanelItem` ou `AppNavItem`.
|
|
55
66
|
*/
|
|
@@ -63,6 +74,12 @@ export interface ListItemProps {
|
|
|
63
74
|
target?: string;
|
|
64
75
|
/** Relação do link. Sobrescreve o padrão do `target`. */
|
|
65
76
|
rel?: string;
|
|
77
|
+
/** Superfície: `primary` é o item em destaque, azul-claro com hover próprio. Não é seleção. @default 'default' */
|
|
78
|
+
variant?: "default" | "primary";
|
|
79
|
+
/** Classes CSS do `li` (a linha visual), para animação de entrada. Sem efeito com `standalone`. */
|
|
80
|
+
liClassName?: string;
|
|
81
|
+
/** Estilo inline do `li` (variável CSS, transitionDelay). Sem efeito com `standalone`. */
|
|
82
|
+
liStyle?: any;
|
|
66
83
|
/** Item atual: fundo de seleção e `aria-current`. @default false */
|
|
67
84
|
selected?: boolean;
|
|
68
85
|
/** Bloqueia clique e foco. @default false */
|
|
@@ -81,6 +98,8 @@ export interface ListItemProps {
|
|
|
81
98
|
start?: any;
|
|
82
99
|
/** Conteúdo no fim da linha (badge, seta, valor). No Vue, slot `end`. */
|
|
83
100
|
end?: any;
|
|
101
|
+
/** Controles da linha (menu ⋮, botão), fora do elemento clicável. Só com o `li`. No Vue, slot `actions`. */
|
|
102
|
+
actions?: any;
|
|
84
103
|
/** Chamado no clique da linha (ou em Enter/Espaço no `as="div"`). */
|
|
85
104
|
onClick?: (event: any) => void;
|
|
86
105
|
/** Classes CSS adicionais, no elemento interativo. */
|
|
@@ -10,11 +10,15 @@ function ListItem(props) {
|
|
|
10
10
|
function isInteractive() {
|
|
11
11
|
return elementTag() !== "div" || !!props.onClick;
|
|
12
12
|
}
|
|
13
|
+
function liClasses() {
|
|
14
|
+
return ["umds-list__item", props.liClassName].filter(Boolean).join(" ");
|
|
15
|
+
}
|
|
13
16
|
function classes() {
|
|
14
17
|
return [
|
|
15
18
|
"umds-list-item",
|
|
16
19
|
isInteractive() ? "umds-list-item--interactive" : "",
|
|
17
20
|
props.selected ? "umds-list-item--selected" : "",
|
|
21
|
+
props.variant === "primary" ? "umds-list-item--primary" : "",
|
|
18
22
|
props.disabled ? "umds-list-item--disabled" : "",
|
|
19
23
|
props.className,
|
|
20
24
|
]
|
|
@@ -77,6 +81,6 @@ function ListItem(props) {
|
|
|
77
81
|
}
|
|
78
82
|
return out;
|
|
79
83
|
}
|
|
80
|
-
return (
|
|
84
|
+
return (_jsx(_Fragment, { children: !props.standalone ? (_jsx(_Fragment, { children: _jsxs("li", { style: props.liStyle, className: liClasses(), children: [elementTag() === "button" ? (_jsxs("button", { type: "button", id: props.id, title: props.tooltip, disabled: props.disabled, "aria-current": ariaCurrent(), onClick: (event) => handleClick(event), ...htmlAttrs(), className: classes(), children: [props.start ? (_jsx("span", { className: "umds-list-item__start", children: _jsx(_Fragment, { children: props.start }) })) : null, _jsxs("span", { className: "umds-list-item__body", children: [props.title ? (_jsx("span", { className: "umds-list-item__title", children: _jsx(Text, { variant: "body2", as: "span", weight: "semibold", color: "inherit", children: _jsx(_Fragment, { children: props.title }) }) })) : null, props.subtitle ? (_jsx("span", { className: "umds-list-item__subtitle", children: _jsx(Text, { variant: "body2", as: "span", color: "inherit", children: _jsx(_Fragment, { children: props.subtitle }) }) })) : null, props.meta ? (_jsx("span", { className: "umds-list-item__meta", children: _jsx(Text, { variant: "caption", as: "span", color: "inherit", children: _jsx(_Fragment, { children: props.meta }) }) })) : null, _jsx(_Fragment, { children: props.children })] }), props.end ? (_jsx("span", { className: "umds-list-item__end", children: _jsx(_Fragment, { children: props.end }) })) : null] })) : null, elementTag() === "a" ? (_jsxs("a", { id: props.id, title: props.tooltip, href: hrefValue(), target: props.target, rel: relValue(), "aria-current": ariaCurrent(), "aria-disabled": ariaDisabled(), onClick: (event) => handleClick(event), ...htmlAttrs(), className: classes(), children: [props.start ? (_jsx("span", { className: "umds-list-item__start", children: _jsx(_Fragment, { children: props.start }) })) : null, _jsxs("span", { className: "umds-list-item__body", children: [props.title ? (_jsx("span", { className: "umds-list-item__title", children: _jsx(Text, { variant: "body2", as: "span", weight: "semibold", color: "inherit", children: _jsx(_Fragment, { children: props.title }) }) })) : null, props.subtitle ? (_jsx("span", { className: "umds-list-item__subtitle", children: _jsx(Text, { variant: "body2", as: "span", color: "inherit", children: _jsx(_Fragment, { children: props.subtitle }) }) })) : null, props.meta ? (_jsx("span", { className: "umds-list-item__meta", children: _jsx(Text, { variant: "caption", as: "span", color: "inherit", children: _jsx(_Fragment, { children: props.meta }) }) })) : null, _jsx(_Fragment, { children: props.children })] }), props.end ? (_jsx("span", { className: "umds-list-item__end", children: _jsx(_Fragment, { children: props.end }) })) : null] })) : null, elementTag() === "div" ? (_jsxs("div", { id: props.id, title: props.tooltip, role: divRole(), tabIndex: divTabIndex(), "aria-current": ariaCurrent(), "aria-disabled": ariaDisabled(), onClick: (event) => handleClick(event), onKeyDown: (event) => handleKeyDown(event), ...htmlAttrs(), className: classes(), children: [props.start ? (_jsx("span", { className: "umds-list-item__start", children: _jsx(_Fragment, { children: props.start }) })) : null, _jsxs("span", { className: "umds-list-item__body", children: [props.title ? (_jsx("span", { className: "umds-list-item__title", children: _jsx(Text, { variant: "body2", as: "span", weight: "semibold", color: "inherit", children: _jsx(_Fragment, { children: props.title }) }) })) : null, props.subtitle ? (_jsx("span", { className: "umds-list-item__subtitle", children: _jsx(Text, { variant: "body2", as: "span", color: "inherit", children: _jsx(_Fragment, { children: props.subtitle }) }) })) : null, props.meta ? (_jsx("span", { className: "umds-list-item__meta", children: _jsx(Text, { variant: "caption", as: "span", color: "inherit", children: _jsx(_Fragment, { children: props.meta }) }) })) : null, _jsx(_Fragment, { children: props.children })] }), props.end ? (_jsx("span", { className: "umds-list-item__end", children: _jsx(_Fragment, { children: props.end }) })) : null] })) : null, props.actions ? (_jsx("div", { className: "umds-list-item__actions", children: _jsx(_Fragment, { children: props.actions }) })) : null] }) })) : (_jsx(_Fragment, { children: _jsxs(_Fragment, { children: [elementTag() === "button" ? (_jsxs("button", { type: "button", id: props.id, title: props.tooltip, disabled: props.disabled, "aria-current": ariaCurrent(), onClick: (event) => handleClick(event), ...htmlAttrs(), className: classes(), children: [props.start ? (_jsx("span", { className: "umds-list-item__start", children: _jsx(_Fragment, { children: props.start }) })) : null, _jsxs("span", { className: "umds-list-item__body", children: [props.title ? (_jsx("span", { className: "umds-list-item__title", children: _jsx(Text, { variant: "body2", as: "span", weight: "semibold", color: "inherit", children: _jsx(_Fragment, { children: props.title }) }) })) : null, props.subtitle ? (_jsx("span", { className: "umds-list-item__subtitle", children: _jsx(Text, { variant: "body2", as: "span", color: "inherit", children: _jsx(_Fragment, { children: props.subtitle }) }) })) : null, props.meta ? (_jsx("span", { className: "umds-list-item__meta", children: _jsx(Text, { variant: "caption", as: "span", color: "inherit", children: _jsx(_Fragment, { children: props.meta }) }) })) : null, _jsx(_Fragment, { children: props.children })] }), props.end ? (_jsx("span", { className: "umds-list-item__end", children: _jsx(_Fragment, { children: props.end }) })) : null] })) : null, elementTag() === "a" ? (_jsxs("a", { id: props.id, title: props.tooltip, href: hrefValue(), target: props.target, rel: relValue(), "aria-current": ariaCurrent(), "aria-disabled": ariaDisabled(), onClick: (event) => handleClick(event), ...htmlAttrs(), className: classes(), children: [props.start ? (_jsx("span", { className: "umds-list-item__start", children: _jsx(_Fragment, { children: props.start }) })) : null, _jsxs("span", { className: "umds-list-item__body", children: [props.title ? (_jsx("span", { className: "umds-list-item__title", children: _jsx(Text, { variant: "body2", as: "span", weight: "semibold", color: "inherit", children: _jsx(_Fragment, { children: props.title }) }) })) : null, props.subtitle ? (_jsx("span", { className: "umds-list-item__subtitle", children: _jsx(Text, { variant: "body2", as: "span", color: "inherit", children: _jsx(_Fragment, { children: props.subtitle }) }) })) : null, props.meta ? (_jsx("span", { className: "umds-list-item__meta", children: _jsx(Text, { variant: "caption", as: "span", color: "inherit", children: _jsx(_Fragment, { children: props.meta }) }) })) : null, _jsx(_Fragment, { children: props.children })] }), props.end ? (_jsx("span", { className: "umds-list-item__end", children: _jsx(_Fragment, { children: props.end }) })) : null] })) : null, elementTag() === "div" ? (_jsxs("div", { id: props.id, title: props.tooltip, role: divRole(), tabIndex: divTabIndex(), "aria-current": ariaCurrent(), "aria-disabled": ariaDisabled(), onClick: (event) => handleClick(event), onKeyDown: (event) => handleKeyDown(event), ...htmlAttrs(), className: classes(), children: [props.start ? (_jsx("span", { className: "umds-list-item__start", children: _jsx(_Fragment, { children: props.start }) })) : null, _jsxs("span", { className: "umds-list-item__body", children: [props.title ? (_jsx("span", { className: "umds-list-item__title", children: _jsx(Text, { variant: "body2", as: "span", weight: "semibold", color: "inherit", children: _jsx(_Fragment, { children: props.title }) }) })) : null, props.subtitle ? (_jsx("span", { className: "umds-list-item__subtitle", children: _jsx(Text, { variant: "body2", as: "span", color: "inherit", children: _jsx(_Fragment, { children: props.subtitle }) }) })) : null, props.meta ? (_jsx("span", { className: "umds-list-item__meta", children: _jsx(Text, { variant: "caption", as: "span", color: "inherit", children: _jsx(_Fragment, { children: props.meta }) }) })) : null, _jsx(_Fragment, { children: props.children })] }), props.end ? (_jsx("span", { className: "umds-list-item__end", children: _jsx(_Fragment, { children: props.end }) })) : null] })) : null] }) })) }));
|
|
81
85
|
}
|
|
82
86
|
export default ListItem;
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
z-index: 2;
|
|
42
42
|
background-color: var(--umds-semantic-color-background-elevated); /* superfície elevada: igual ao white no light; mais clara no dark (decisão 25/07) */
|
|
43
43
|
border-radius: var(--umds-primitive-border-radius-sm); /* 8px universal (rodada ago/2026) — a exceção "superfície grande → md" caiu */
|
|
44
|
-
box-shadow: var(--umds-semantic-shadow-
|
|
44
|
+
box-shadow: var(--umds-semantic-shadow-center-xl);
|
|
45
45
|
padding: var(--umds-primitive-spacing-xxs);
|
|
46
46
|
width: clamp(320px, 90%, 498px);
|
|
47
47
|
max-width: 498px;
|
|
@@ -337,9 +337,8 @@
|
|
|
337
337
|
padding: var(--umds-primitive-spacing-xxxs) var(--umds-primitive-spacing-xxs); /* 16px 24px (produto: 14px 22px) */
|
|
338
338
|
border-top: 1px solid var(--umds-semantic-color-neutral-light-medium);
|
|
339
339
|
background: var(--umds-semantic-color-neutral-light-pure);
|
|
340
|
-
/* Levanta o rodapé do conteúdo que passa por baixo dele ao rolar.
|
|
341
|
-
|
|
342
|
-
box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.08);
|
|
340
|
+
/* Levanta o rodapé do conteúdo que passa por baixo dele ao rolar. */
|
|
341
|
+
box-shadow: var(--umds-semantic-shadow-top-md);
|
|
343
342
|
flex-shrink: 0;
|
|
344
343
|
box-sizing: border-box;
|
|
345
344
|
}
|
|
@@ -195,7 +195,7 @@
|
|
|
195
195
|
background-color: var(--umds-semantic-color-background-elevated); /* superfície elevada: igual ao white no light; mais clara no dark (decisão 25/07) */
|
|
196
196
|
border: 1px solid var(--umds-semantic-color-neutral-light-down);
|
|
197
197
|
border-radius: var(--umds-primitive-border-radius-sm);
|
|
198
|
-
box-shadow: var(--umds-semantic-shadow-md); /* protótipo --shadow-md */
|
|
198
|
+
box-shadow: var(--umds-semantic-shadow-bottom-md); /* protótipo --shadow-md */
|
|
199
199
|
z-index: var(--umds-semantic-layer-popover); /* 1400 - acima de modal */
|
|
200
200
|
max-height: 320px;
|
|
201
201
|
display: flex;
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
color: var(--umds-semantic-color-primary-dark);
|
|
55
55
|
border: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-color-neutral-light-medium);
|
|
56
56
|
border-radius: var(--umds-primitive-border-radius-sm);
|
|
57
|
-
box-shadow: var(--umds-semantic-shadow-sm);
|
|
57
|
+
box-shadow: var(--umds-semantic-shadow-bottom-sm);
|
|
58
58
|
cursor: pointer;
|
|
59
59
|
transition:
|
|
60
60
|
box-shadow var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard),
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
.umds-org-chart__node:hover {
|
|
72
|
-
box-shadow: var(--umds-semantic-shadow-md);
|
|
72
|
+
box-shadow: var(--umds-semantic-shadow-bottom-md);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
.umds-org-chart__node--selected {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
/* 1px como os demais campos: 1,5px era do protótipo e engrossava só aqui. */
|
|
55
55
|
border: 1px solid var(--umds-semantic-field-border-default);
|
|
56
56
|
border-radius: var(--umds-primitive-border-radius-sm, 8px); /* era 12px (protótipo --radius-lg) — snap 14/07: controle de campo → sm, alinha com Input/Select */
|
|
57
|
-
box-shadow: var(--umds-semantic-shadow-sm); /* era 0 1px 2px 0.04, 0 1px 3px 0.02 (protótipo --shadow-sm) — mapeado 14/07 */
|
|
57
|
+
box-shadow: var(--umds-semantic-shadow-bottom-sm); /* era 0 1px 2px 0.04, 0 1px 3px 0.02 (protótipo --shadow-sm) — mapeado 14/07 */
|
|
58
58
|
transition:
|
|
59
59
|
border-color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard),
|
|
60
60
|
box-shadow var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard);
|
|
@@ -234,7 +234,7 @@
|
|
|
234
234
|
background: var(--umds-semantic-color-background-elevated); /* superfície elevada: igual ao white no light; mais clara no dark (decisão 25/07) */
|
|
235
235
|
border: 1px solid var(--umds-semantic-color-neutral-light-medium); /* #EBEBEB */
|
|
236
236
|
border-radius: var(--umds-primitive-border-radius-sm); /* 8px (protótipo --radius-md) */
|
|
237
|
-
box-shadow: var(--umds-semantic-shadow-md); /* era 0 4px 16px rgba(0,0,0,0.12) — mapeado para shadow-md 14/07 */
|
|
237
|
+
box-shadow: var(--umds-semantic-shadow-bottom-md); /* era 0 4px 16px rgba(0,0,0,0.12) — mapeado para shadow-md 14/07 */
|
|
238
238
|
overflow: hidden;
|
|
239
239
|
animation: umds-phone-dropdown-in var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard) both;
|
|
240
240
|
}
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
background: var(--umds-semantic-color-background-elevated); /* superfície elevada: igual ao white no claro, mais clara no escuro */
|
|
38
38
|
border: 1px solid var(--umds-semantic-color-neutral-light-down);
|
|
39
39
|
border-radius: var(--umds-primitive-border-radius-sm);
|
|
40
|
-
box-shadow: var(--umds-semantic-shadow-md);
|
|
40
|
+
box-shadow: var(--umds-semantic-shadow-bottom-md);
|
|
41
41
|
font-family: var(--umds-semantic-font-family-base);
|
|
42
42
|
transition: opacity var(--umds-semantic-motion-duration-fast)
|
|
43
43
|
var(--umds-semantic-motion-easing-standard);
|
|
@@ -234,7 +234,7 @@
|
|
|
234
234
|
background-color: var(--umds-semantic-color-background-white);
|
|
235
235
|
color: var(--umds-semantic-color-neutral-dark-pure);
|
|
236
236
|
font-weight: var(--umds-primitive-font-weight-bold);
|
|
237
|
-
box-shadow: var(--umds-semantic-shadow-md);
|
|
237
|
+
box-shadow: var(--umds-semantic-shadow-bottom-md);
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
.umds-segmented--surface .umds-segmented__input:disabled + .umds-segmented__item:hover {
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
background-color: var(--umds-semantic-color-background-elevated); /* superfície elevada: igual ao white no light; mais clara no dark (decisão 25/07) */
|
|
150
150
|
border: 1px solid var(--umds-semantic-color-neutral-light-down);
|
|
151
151
|
border-radius: var(--umds-primitive-border-radius-sm);
|
|
152
|
-
box-shadow: var(--umds-semantic-shadow-md); /* protótipo --shadow-md */
|
|
152
|
+
box-shadow: var(--umds-semantic-shadow-bottom-md); /* protótipo --shadow-md */
|
|
153
153
|
z-index: var(--umds-semantic-layer-popover); /* 1400 - acima de modal */
|
|
154
154
|
max-height: 300px;
|
|
155
155
|
display: flex;
|
|
@@ -11,9 +11,11 @@
|
|
|
11
11
|
align-items: flex-start;
|
|
12
12
|
gap: var(--umds-primitive-spacing-mini);
|
|
13
13
|
padding: var(--umds-primitive-spacing-xxxs);
|
|
14
|
-
|
|
14
|
+
/* Mesma borda e superfície do Card: lado a lado, os cartões têm o mesmo
|
|
15
|
+
contorno (#EBEBEB no claro), e no escuro o fundo é o elevado. */
|
|
16
|
+
border: 1px solid var(--umds-semantic-color-neutral-light-medium);
|
|
15
17
|
border-radius: var(--umds-primitive-border-radius-sm);
|
|
16
|
-
background-color: var(--umds-semantic-color-background-
|
|
18
|
+
background-color: var(--umds-semantic-color-background-elevated);
|
|
17
19
|
color: var(--umds-semantic-color-neutral-dark-pure);
|
|
18
20
|
font-family: var(--umds-semantic-font-family-base);
|
|
19
21
|
text-align: left;
|
|
@@ -38,7 +40,7 @@
|
|
|
38
40
|
|
|
39
41
|
.umds-stat-card--acionavel:hover {
|
|
40
42
|
border-color: var(--umds-semantic-color-primary-pure);
|
|
41
|
-
box-shadow: var(--umds-semantic-shadow-sm);
|
|
43
|
+
box-shadow: var(--umds-semantic-shadow-bottom-sm);
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
/* Foco canônico de não-campo. */
|
|
@@ -243,8 +245,25 @@
|
|
|
243
245
|
color: var(--umds-semantic-color-feedback-info-dark);
|
|
244
246
|
}
|
|
245
247
|
|
|
248
|
+
/* ── secondaryTone: cor da segunda medida (mesmas variantes do valueTone) ── */
|
|
249
|
+
.umds-stat-card--secundario-primary .umds-stat-card__valor-secundario {
|
|
250
|
+
color: var(--umds-semantic-color-primary-pure);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.umds-stat-card--secundario-positive .umds-stat-card__valor-secundario {
|
|
254
|
+
color: var(--umds-semantic-color-feedback-positive-dark);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.umds-stat-card--secundario-negative .umds-stat-card__valor-secundario {
|
|
258
|
+
color: var(--umds-semantic-color-feedback-negative-dark);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.umds-stat-card--secundario-info .umds-stat-card__valor-secundario {
|
|
262
|
+
color: var(--umds-semantic-color-feedback-info-dark);
|
|
263
|
+
}
|
|
264
|
+
|
|
246
265
|
/* ── Segunda medida (secondaryValue, secondaryLabel) ──
|
|
247
|
-
|
|
266
|
+
À direita da principal, separada por um filete. Vem depois do corpo no HTML. */
|
|
248
267
|
.umds-stat-card__secundaria {
|
|
249
268
|
display: flex;
|
|
250
269
|
flex-direction: column;
|
|
@@ -263,8 +282,9 @@
|
|
|
263
282
|
text-align: center;
|
|
264
283
|
}
|
|
265
284
|
|
|
285
|
+
/* Mesmo tamanho e peso do número principal: as duas medidas se comparam lado a lado. */
|
|
266
286
|
.umds-stat-card__valor-secundario {
|
|
267
|
-
font-size: var(--umds-primitive-font-size-
|
|
287
|
+
font-size: var(--umds-primitive-font-size-md);
|
|
268
288
|
font-weight: var(--umds-primitive-font-weight-bold);
|
|
269
289
|
line-height: 1.15;
|
|
270
290
|
font-variant-numeric: tabular-nums;
|
|
@@ -285,6 +305,30 @@
|
|
|
285
305
|
.umds-stat-card--rotulo-topo .umds-stat-card__secundaria {
|
|
286
306
|
grid-column: 3;
|
|
287
307
|
grid-row: 2;
|
|
308
|
+
/* A grade não tem vão entre colunas: o filete ganha o mesmo respiro dos dois lados. */
|
|
309
|
+
margin-left: var(--umds-primitive-spacing-xxxs);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.umds-stat-card--rotulo-topo .umds-stat-card__valor-secundario {
|
|
313
|
+
font-size: var(--umds-primitive-font-size-lg); /* 32px, como o principal */
|
|
314
|
+
font-weight: var(--umds-primitive-font-weight-extrabold);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/* Com rótulo na segunda medida, ela ocupa as linhas do número e da descrição
|
|
318
|
+
(subgrid): o rótulo dela fica na linha da descrição ("Geral" ao lado de
|
|
319
|
+
"Meu Setor") e o valor na linha do número principal. */
|
|
320
|
+
.umds-stat-card--rotulo-topo .umds-stat-card__secundaria:has(.umds-stat-card__rotulo-secundario) {
|
|
321
|
+
grid-row: 2 / span 2;
|
|
322
|
+
display: grid;
|
|
323
|
+
grid-template-rows: subgrid;
|
|
324
|
+
/* `normal` usa o vão da grade do cartão; o `micro` da regra base deslocaria a linha em 1,5px. */
|
|
325
|
+
row-gap: normal;
|
|
326
|
+
align-items: center;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.umds-stat-card--rotulo-topo.umds-stat-card--com-secundaria .umds-stat-card__descricao {
|
|
330
|
+
grid-column: 1 / 3;
|
|
331
|
+
grid-row: 3;
|
|
288
332
|
}
|
|
289
333
|
|
|
290
334
|
.umds-stat-card--rotulo-topo.umds-stat-card--com-secundaria:not(:has(.umds-stat-card__icone)) .umds-stat-card__valor {
|
|
@@ -298,3 +342,53 @@
|
|
|
298
342
|
font-size: 1.125rem; /* 18px */
|
|
299
343
|
font-weight: var(--umds-primitive-font-weight-extrabold);
|
|
300
344
|
}
|
|
345
|
+
|
|
346
|
+
/* A segunda medida acompanha o número principal. */
|
|
347
|
+
.umds-stat-card.umds-stat-card--sm .umds-stat-card__valor-secundario {
|
|
348
|
+
font-size: 1.125rem; /* 18px */
|
|
349
|
+
font-weight: var(--umds-primitive-font-weight-extrabold);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/* ── loading: o Skeleton ocupa a altura do número (1em da fonte dele) ── */
|
|
353
|
+
.umds-stat-card[aria-busy="true"] .umds-stat-card__valor,
|
|
354
|
+
.umds-stat-card[aria-busy="true"] .umds-stat-card__valor-secundario {
|
|
355
|
+
display: inline-flex;
|
|
356
|
+
align-items: center;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/* ── Segunda medida em largura pequena (container query) ──
|
|
360
|
+
Num cartão estreito (cabeçalho mobile, ~115px) as duas medidas lado a lado
|
|
361
|
+
se sobrepunham. O cartão com segunda medida vira container de largura e,
|
|
362
|
+
abaixo de 240px, a segunda medida desce para a linha de baixo, separada por
|
|
363
|
+
um filete em cima em vez do da esquerda.
|
|
364
|
+
`width: 100%`: um container de inline-size não mede o conteúdo, então num
|
|
365
|
+
pai flex com tamanho pelo conteúdo ele encolheria até sumir. Com 100%, numa
|
|
366
|
+
linha flex os cartões dividem o espaço; em grade e em bloco nada muda. */
|
|
367
|
+
.umds-stat-card--com-secundaria {
|
|
368
|
+
container-type: inline-size;
|
|
369
|
+
width: 100%;
|
|
370
|
+
flex-wrap: wrap;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* 240px: duas medidas de 24px com o filete e o respiro não cabem abaixo disso.
|
|
374
|
+
Container query não aceita var(), por isso o literal. */
|
|
375
|
+
@container (max-width: 240px) {
|
|
376
|
+
.umds-stat-card:not(.umds-stat-card--centro) .umds-stat-card__secundaria {
|
|
377
|
+
flex-basis: 100%;
|
|
378
|
+
margin-left: 0;
|
|
379
|
+
padding-left: 0;
|
|
380
|
+
padding-top: var(--umds-primitive-spacing-nano);
|
|
381
|
+
border-left: none;
|
|
382
|
+
border-top: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-color-neutral-light-medium);
|
|
383
|
+
align-items: flex-start;
|
|
384
|
+
text-align: left;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.umds-stat-card--rotulo-topo .umds-stat-card__secundaria,
|
|
388
|
+
.umds-stat-card--rotulo-topo .umds-stat-card__secundaria:has(.umds-stat-card__rotulo-secundario) {
|
|
389
|
+
grid-column: 1 / -1;
|
|
390
|
+
grid-row: auto;
|
|
391
|
+
display: flex;
|
|
392
|
+
margin-left: 0;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
@@ -14,7 +14,7 @@ import './StatCard.css';
|
|
|
14
14
|
* pessoa a segurar o rótulo na cabeça esperando o valor.
|
|
15
15
|
* - **A variação não depende só da cor.** Sobe e desce vêm com seta, porque
|
|
16
16
|
* verde e vermelho sozinhos não comunicam para quem não distingue cores.
|
|
17
|
-
* @property {
|
|
17
|
+
* @property {any} value - O número ou medida em destaque. Aceita um nó, como um `Counter` para o número contar até o valor (no Vue, slot `value`)
|
|
18
18
|
* @property {string} label - O que o número significa
|
|
19
19
|
* @property {IconProp} icon - Ícone Font Awesome como objeto importado
|
|
20
20
|
* @property {string} variant - Cor de apoio do ícone e da variação
|
|
@@ -24,20 +24,22 @@ import './StatCard.css';
|
|
|
24
24
|
* @property {string} description - Texto auxiliar abaixo do rótulo
|
|
25
25
|
* @property {string} size - 'md' (padrão) | 'sm': o `sm` leva o número a 18px/800, o tamanho dos KPIs da home do CrisDoc (fora da escala de fonte do DS, que vai de 16 a 20). Vale também com `labelPosition="top"`.
|
|
26
26
|
* @property {string} labelPosition - Onde o rótulo aparece: 'bottom' (padrão, embaixo do número) | 'top' (no topo do cartão, acima do ícone e do número, com o número em 32/800). No HTML o número continua vindo antes do rótulo, então o leitor de tela anuncia igual.
|
|
27
|
-
* @property {string|number} secondaryValue - Segunda medida do cartão,
|
|
27
|
+
* @property {string|number} secondaryValue - Segunda medida do cartão, no mesmo tamanho da principal, à direita dela ("22,31%" do setor e "14,11%" do geral). Com `labelPosition="top"`, o `secondaryLabel` fica na linha da `description`. Vem depois do resto no HTML. `0` aparece; vazio e ausente não.
|
|
28
28
|
* @property {string} secondaryLabel - O que a segunda medida significa ("Geral")
|
|
29
29
|
* @property {string} valueTone - Cor do número principal: 'default' (cor do texto) | 'primary' | 'positive' | 'negative' | 'info'. Usa as variantes escuras (contraste AA sobre o branco). Não confunda com `variant`, que pinta o ícone e a variação.
|
|
30
|
+
* @property {string} secondaryTone - Cor da segunda medida, com as mesmas opções de `valueTone` ("Meu Setor" em azul e "Geral" em verde, por exemplo).
|
|
31
|
+
* @property {boolean} loading - Carregando: os números viram Skeleton do tamanho deles (rótulos e ⓘ continuam), a variação some e o cartão ganha `aria-busy`. Dispensa montar o Skeleton por fora.
|
|
30
32
|
* @property {string} infoTooltip - Texto de ajuda: mostra um ⓘ ao lado do rótulo com um Tooltip escuro. É um botão dentro do cartão; com `onClick` no cartão, evite (botão dentro de botão).
|
|
31
33
|
* @property {string} infoLabel - Nome acessível do ⓘ. Troque para traduzir. Padrão: "Mais informações".
|
|
32
34
|
* @property {string} align - Alinhamento do conteúdo
|
|
33
35
|
* @property {string} className - Classes CSS adicionais
|
|
34
36
|
* @property {function} onClick - Torna o cartão acionável (vira botão)
|
|
35
37
|
* @quandoUsar Painel e visão geral: destacar UMA medida por cartão, em linha com outras. O número é o protagonista da leitura.
|
|
36
|
-
* @quandoNaoUsar Para listar dados comparáveis — use `DataTable`. Para um bloco com título e conteúdo livre, `Card`. Para um rótulo curto de estado, `Tag` ou `Badge`. Não empilhe vários números num StatCard só:
|
|
38
|
+
* @quandoNaoUsar Para listar dados comparáveis — use `DataTable`. Para um bloco com título e conteúdo livre, `Card`. Para um rótulo curto de estado, `Tag` ou `Badge`. Não empilhe vários números num StatCard só: uma medida, ou duas comparadas (`secondaryValue`).
|
|
37
39
|
*/
|
|
38
40
|
export interface StatCardProps {
|
|
39
|
-
/** O número ou medida em destaque. */
|
|
40
|
-
value?:
|
|
41
|
+
/** O número ou medida em destaque. Texto, número ou nó (um `Counter`); no Vue, slot `value`. */
|
|
42
|
+
value?: any;
|
|
41
43
|
/** O que o número significa. */
|
|
42
44
|
label?: string;
|
|
43
45
|
/** Ícone Font Awesome como objeto importado. */
|
|
@@ -70,7 +72,7 @@ export interface StatCardProps {
|
|
|
70
72
|
* @default 'bottom'
|
|
71
73
|
*/
|
|
72
74
|
labelPosition?: "bottom" | "top";
|
|
73
|
-
/** Segunda medida,
|
|
75
|
+
/** Segunda medida, no tamanho da principal, à direita dela. 0 aparece; vazio e ausente não. */
|
|
74
76
|
secondaryValue?: string | number;
|
|
75
77
|
/** O que a segunda medida significa. */
|
|
76
78
|
secondaryLabel?: string;
|
|
@@ -78,6 +80,10 @@ export interface StatCardProps {
|
|
|
78
80
|
size?: "md" | "sm";
|
|
79
81
|
/** Cor do número principal. @default 'default' */
|
|
80
82
|
valueTone?: "default" | "primary" | "positive" | "negative" | "info";
|
|
83
|
+
/** Cor da segunda medida. Mesmas opções de `valueTone`. @default 'default' */
|
|
84
|
+
secondaryTone?: "default" | "primary" | "positive" | "negative" | "info";
|
|
85
|
+
/** Carregando: números viram Skeleton, a variação some, `aria-busy` no cartão. @default false */
|
|
86
|
+
loading?: boolean;
|
|
81
87
|
/**
|
|
82
88
|
* Texto de ajuda: mostra o ⓘ ao lado do rótulo, com um Tooltip escuro. É um
|
|
83
89
|
* botão focável dentro do cartão; com `onClick` no cartão, evite.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import './StatCard.css';
|
|
4
4
|
import { faCircleInfo } from "@fortawesome/free-solid-svg-icons";
|
|
5
5
|
import Icon from "../Icon/Icon";
|
|
6
6
|
import Tooltip from "../Tooltip/Tooltip";
|
|
7
|
+
import Skeleton from "../Skeleton/Skeleton";
|
|
7
8
|
function StatCard(props) {
|
|
8
9
|
function classes() {
|
|
9
10
|
return [
|
|
@@ -16,6 +17,9 @@ function StatCard(props) {
|
|
|
16
17
|
props.valueTone && props.valueTone !== "default"
|
|
17
18
|
? "umds-stat-card--valor-" + props.valueTone
|
|
18
19
|
: "",
|
|
20
|
+
props.secondaryTone && props.secondaryTone !== "default"
|
|
21
|
+
? "umds-stat-card--secundario-" + props.secondaryTone
|
|
22
|
+
: "",
|
|
19
23
|
props.onClick ? "umds-stat-card--acionavel" : "",
|
|
20
24
|
props.className,
|
|
21
25
|
]
|
|
@@ -58,6 +62,6 @@ function StatCard(props) {
|
|
|
58
62
|
if (props.onClick)
|
|
59
63
|
props.onClick();
|
|
60
64
|
}
|
|
61
|
-
return (_jsxs("div", { className: classes(), onClick: (event) => aoClicar(), role: ehAcionavel() ? "button" : undefined, tabIndex: ehAcionavel() ? 0 : undefined, children: [props.icon ? (_jsx("span", { className: "umds-stat-card__icone", "aria-hidden": "true", children: _jsx(Icon, { size: "md", variant: "inherit", icon: props.icon }) })) : null, _jsxs("div", { className: "umds-stat-card__corpo", children: [
|
|
65
|
+
return (_jsxs("div", { className: classes(), onClick: (event) => aoClicar(), role: ehAcionavel() ? "button" : undefined, tabIndex: ehAcionavel() ? 0 : undefined, "aria-busy": props.loading ? "true" : undefined, children: [props.icon ? (_jsx("span", { className: "umds-stat-card__icone", "aria-hidden": "true", children: _jsx(Icon, { size: "md", variant: "inherit", icon: props.icon }) })) : null, _jsxs("div", { className: "umds-stat-card__corpo", children: [_jsxs("span", { className: "umds-stat-card__valor", children: [props.loading ? _jsx(Skeleton, { width: "3em", height: "1em" }) : null, !props.loading ? _jsx(_Fragment, { children: props.value }) : null] }), _jsxs("span", { className: "umds-stat-card__rotulo", children: [props.label, props.infoTooltip ? (_jsx(Tooltip, { variant: "dark", side: "top", content: props.infoTooltip, children: _jsx("button", { type: "button", className: "umds-stat-card__info", "aria-label": props.infoLabel || "Mais informações", children: _jsx(Icon, { variant: "inherit", customSize: "14px", icon: faCircleInfo }) }) })) : null] }), props.description ? (_jsx("span", { className: "umds-stat-card__descricao", children: props.description })) : null, props.trendLabel && !props.loading ? (_jsxs("span", { className: classesDaVariacao(), children: [_jsx("span", { "aria-hidden": "true", children: simboloDaVariacao() }), props.trendLabel] })) : null] }), temSecundaria() ? (_jsxs("div", { className: "umds-stat-card__secundaria", children: [_jsxs("span", { className: "umds-stat-card__valor-secundario", children: [props.loading ? _jsx(Skeleton, { width: "3em", height: "1em" }) : null, !props.loading ? _jsx(_Fragment, { children: props.secondaryValue }) : null] }), props.secondaryLabel ? (_jsx("span", { className: "umds-stat-card__rotulo-secundario", children: props.secondaryLabel })) : null] })) : null] }));
|
|
62
66
|
}
|
|
63
67
|
export default StatCard;
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
.umds-switch__thumb {
|
|
52
52
|
background-color: var(--umds-semantic-color-neutral-light-pure);
|
|
53
53
|
border-radius: var(--umds-primitive-border-radius-circular);
|
|
54
|
-
box-shadow: var(--umds-semantic-shadow-sm); /* era 0 1px 2px 0.1, 0 1px 1px 0.06 — mapeado para shadow-sm 14/07 (sombra do thumb fica mais sutil) */
|
|
54
|
+
box-shadow: var(--umds-semantic-shadow-bottom-sm); /* era 0 1px 2px 0.1, 0 1px 1px 0.06 — mapeado para shadow-sm 14/07 (sombra do thumb fica mais sutil) */
|
|
55
55
|
display: flex;
|
|
56
56
|
align-items: center;
|
|
57
57
|
justify-content: center;
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
background-color: var(--umds-semantic-color-neutral-light-pure);
|
|
145
145
|
padding: var(--umds-primitive-spacing-xxxs);
|
|
146
146
|
border-radius: var(--umds-primitive-border-radius-sm);
|
|
147
|
-
box-shadow: var(--umds-semantic-shadow-sm); /* era 0 4px 8px 0.06 — mapeado para shadow-sm 14/07 (card de fundo sutil) */
|
|
147
|
+
box-shadow: var(--umds-semantic-shadow-bottom-sm); /* era 0 4px 8px 0.06 — mapeado para shadow-sm 14/07 (card de fundo sutil) */
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
.umds-switch-text {
|
|
@@ -62,6 +62,12 @@ export interface TextProps {
|
|
|
62
62
|
/**
|
|
63
63
|
* Cor do texto usando tokens semânticos.
|
|
64
64
|
*
|
|
65
|
+
* SEM `color`, o texto HERDA a cor do pai (é o que deixa um Text dentro de um
|
|
66
|
+
* botão, alerta ou cartão colorido acompanhar a cor dele). Dentro do
|
|
67
|
+
* `AppShell` o pai já tem a cor de texto do tema. Fora dele, num título solto
|
|
68
|
+
* na página, passe `color="primary"` (`neutral-dark-pure`, o texto principal,
|
|
69
|
+
* não o azul) para o tema escuro funcionar.
|
|
70
|
+
*
|
|
65
71
|
* `disabled` (`neutral-dark-up`, #A3A3A3, 2,5:1 sobre branco) é SÓ para
|
|
66
72
|
* texto de controle desabilitado (rótulo, valor ou ajuda de um campo ou
|
|
67
73
|
* botão inativo), que o WCAG 1.4.3 isenta de contraste. Em qualquer outro
|