@1doc/1ds-react 2.7.2 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1280 -0
- package/dist/components/AIContent/AIContent.d.ts +10 -0
- package/dist/components/AIContent/AIContent.js +1 -1
- package/dist/components/AILabel/AILabel.d.ts +4 -0
- package/dist/components/AILabel/AILabel.js +2 -2
- package/dist/components/Accordion/Accordion.d.ts +6 -2
- package/dist/components/Alert/Alert.css +2 -0
- package/dist/components/Alert/Alert.d.ts +3 -1
- package/dist/components/Alert/Alert.js +7 -1
- package/dist/components/AppHeader/AppHeader.css +82 -8
- package/dist/components/AppHeader/AppHeader.d.ts +12 -1
- package/dist/components/AppHeader/AppHeader.js +186 -1
- package/dist/components/AppNavItem/AppNavItem.css +11 -3
- package/dist/components/AppShell/AppShell.css +9 -0
- package/dist/components/AppShell/AppShell.d.ts +8 -0
- package/dist/components/AppShell/AppShell.js +4 -1
- package/dist/components/AppSidebar/AppSidebar.css +1 -1
- package/dist/components/AppSidebar/AppSidebar.d.ts +4 -0
- package/dist/components/AppSidebar/AppSidebar.js +3 -1
- package/dist/components/AttachmentCard/AttachmentCard.css +17 -1
- package/dist/components/AttachmentCard/AttachmentCard.d.ts +29 -2
- package/dist/components/AttachmentCard/AttachmentCard.js +88 -20
- package/dist/components/Avatar/Avatar.css +7 -2
- package/dist/components/Avatar/AvatarGroup.d.ts +27 -0
- package/dist/components/Avatar/AvatarGroup.js +28 -4
- package/dist/components/Badge/Badge.css +61 -3
- package/dist/components/Badge/Badge.d.ts +14 -4
- package/dist/components/Badge/Badge.js +1 -0
- package/dist/components/BottomSheet/BottomSheet.css +1 -0
- package/dist/components/BottomSheet/BottomSheet.d.ts +8 -0
- package/dist/components/BottomSheet/BottomSheet.js +14 -2
- package/dist/components/Box/Box.css +83 -0
- package/dist/components/Box/Box.d.ts +82 -2
- package/dist/components/Box/Box.js +42 -2
- package/dist/components/Button/Button.css +29 -0
- package/dist/components/Button/Button.d.ts +4 -4
- package/dist/components/Button/Button.js +4 -1
- package/dist/components/Calendar/Calendar.css +245 -0
- package/dist/components/Calendar/Calendar.d.ts +125 -0
- package/dist/components/Calendar/Calendar.js +320 -0
- package/dist/components/Chart/BarChart.d.ts +6 -0
- package/dist/components/Chart/BarChart.js +3 -1
- package/dist/components/Chart/LineChart.d.ts +6 -0
- package/dist/components/Chart/LineChart.js +3 -1
- package/dist/components/Checkbox/Checkbox.css +4 -1
- package/dist/components/Chips/Chips.css +39 -0
- package/dist/components/Chips/Chips.d.ts +7 -2
- package/dist/components/Chips/Chips.js +6 -2
- package/dist/components/Coachmark/Coachmark.css +118 -0
- package/dist/components/Coachmark/Coachmark.d.ts +75 -0
- package/dist/components/Coachmark/Coachmark.js +321 -0
- package/dist/components/CodeBlock/CodeBlock.css +96 -0
- package/dist/components/CodeBlock/CodeBlock.d.ts +47 -0
- package/dist/components/CodeBlock/CodeBlock.js +103 -0
- package/dist/components/ColorPicker/ColorPicker.css +133 -0
- package/dist/components/ColorPicker/ColorPicker.d.ts +73 -0
- package/dist/components/ColorPicker/ColorPicker.js +219 -0
- package/dist/components/Combobox/Combobox.css +11 -3
- package/dist/components/ConfirmAIAction/ConfirmAIAction.d.ts +11 -1
- package/dist/components/ConfirmAIAction/ConfirmAIAction.js +6 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.css +3 -0
- package/dist/components/ConfirmDialog/ConfirmDialog.d.ts +14 -0
- package/dist/components/ConfirmDialog/ConfirmDialog.js +2 -2
- package/dist/components/DataTable/DataTable.css +80 -0
- package/dist/components/DataTable/DataTable.d.ts +23 -4
- package/dist/components/DataTable/DataTable.js +61 -15
- package/dist/components/DatePicker/DatePicker.css +8 -0
- package/dist/components/DatePicker/DatePicker.d.ts +4 -0
- package/dist/components/DatePicker/DatePicker.js +14 -1
- package/dist/components/DescriptionList/DescriptionList.css +113 -0
- package/dist/components/DescriptionList/DescriptionList.d.ts +59 -0
- package/dist/components/DescriptionList/DescriptionList.js +51 -0
- package/dist/components/Drawer/Drawer.css +1 -0
- package/dist/components/Dropdown/Dropdown.js +47 -29
- package/dist/components/FileInput/FileInput.css +24 -4
- package/dist/components/FileInput/FileInput.d.ts +22 -2
- package/dist/components/FileInput/FileInput.js +23 -2
- package/dist/components/Grid/Grid.js +5 -5
- package/dist/components/IconPicker/IconPicker.css +107 -0
- package/dist/components/IconPicker/IconPicker.d.ts +74 -0
- package/dist/components/IconPicker/IconPicker.js +194 -0
- package/dist/components/Input/Input.css +41 -3
- package/dist/components/Input/Input.d.ts +14 -1
- package/dist/components/Input/Input.js +72 -6
- package/dist/components/Kanban/Kanban.css +5 -0
- package/dist/components/Kanban/Kanban.d.ts +41 -0
- package/dist/components/Kanban/Kanban.js +59 -27
- package/dist/components/Kanban/KanbanCard.d.ts +2 -0
- package/dist/components/Kanban/KanbanCard.js +1 -1
- package/dist/components/Kanban/KanbanColumn.d.ts +2 -0
- package/dist/components/Kanban/KanbanColumn.js +3 -0
- package/dist/components/Kbd/Kbd.css +66 -0
- package/dist/components/Kbd/Kbd.d.ts +32 -0
- package/dist/components/Kbd/Kbd.js +40 -0
- package/dist/components/Link/Link.css +1 -1
- package/dist/components/List/List.css +136 -0
- package/dist/components/List/List.d.ts +82 -0
- package/dist/components/List/List.js +53 -0
- package/dist/components/List/ListItem.d.ts +85 -0
- package/dist/components/List/ListItem.js +81 -0
- package/dist/components/Modal/Modal.css +93 -8
- package/dist/components/Modal/Modal.d.ts +45 -7
- package/dist/components/Modal/Modal.js +106 -6
- package/dist/components/MultiSelect/MultiSelect.css +9 -1
- package/dist/components/MultiSelect/MultiSelect.js +45 -8
- package/dist/components/OrgChart/OrgChart.css +149 -0
- package/dist/components/OrgChart/OrgChart.d.ts +83 -0
- package/dist/components/OrgChart/OrgChart.js +297 -0
- package/dist/components/OtpInput/OtpInput.css +93 -0
- package/dist/components/OtpInput/OtpInput.d.ts +60 -0
- package/dist/components/OtpInput/OtpInput.js +215 -0
- package/dist/components/Pagination/Pagination.d.ts +6 -0
- package/dist/components/Pagination/Pagination.js +9 -1
- package/dist/components/PhoneInput/PhoneInput.css +9 -1
- package/dist/components/PhoneInput/PhoneInput.d.ts +10 -0
- package/dist/components/PhoneInput/PhoneInput.js +20 -3
- package/dist/components/Popover/Popover.d.ts +7 -0
- package/dist/components/Popover/Popover.js +11 -1
- package/dist/components/RichTextEditor/RichTextEditor.css +203 -0
- package/dist/components/RichTextEditor/RichTextEditor.d.ts +83 -0
- package/dist/components/RichTextEditor/RichTextEditor.js +494 -0
- package/dist/components/SegmentedControl/SegmentedControl.d.ts +2 -0
- package/dist/components/SegmentedControl/SegmentedControl.js +21 -8
- package/dist/components/Select/Select.css +71 -1
- package/dist/components/Select/Select.d.ts +12 -0
- package/dist/components/Select/Select.js +93 -10
- package/dist/components/SidePanel/SidePanel.css +4 -4
- package/dist/components/SidePanelItem/SidePanelItem.css +7 -5
- package/dist/components/SidePanelSearch/SidePanelSearch.css +2 -2
- package/dist/components/SidePanelSection/SidePanelSection.css +7 -5
- package/dist/components/Stack/Stack.css +49 -0
- package/dist/components/Stack/Stack.d.ts +65 -7
- package/dist/components/Stack/Stack.js +30 -2
- package/dist/components/StatCard/StatCard.css +73 -0
- package/dist/components/StatCard/StatCard.d.ts +17 -0
- package/dist/components/StatCard/StatCard.js +4 -1
- package/dist/components/Stepper/Stepper.css +4 -1
- package/dist/components/Stepper/Stepper.d.ts +8 -0
- package/dist/components/Stepper/Stepper.js +4 -4
- package/dist/components/Switch/Switch.css +1 -0
- package/dist/components/Tabs/Tab.d.ts +15 -0
- package/dist/components/Tabs/Tab.js +30 -1
- package/dist/components/Tabs/Tabs.css +132 -0
- package/dist/components/Tabs/Tabs.d.ts +7 -0
- package/dist/components/Tabs/Tabs.js +13 -2
- package/dist/components/Tag/Tag.css +85 -2
- package/dist/components/Tag/Tag.d.ts +13 -6
- package/dist/components/Tag/Tag.js +1 -0
- package/dist/components/Text/Text.d.ts +9 -1
- package/dist/components/Text/Text.js +2 -2
- package/dist/components/Textarea/Textarea.css +11 -3
- package/dist/components/TimePicker/TimePicker.css +8 -0
- package/dist/components/TimePicker/TimePicker.d.ts +6 -0
- package/dist/components/TimePicker/TimePicker.js +1 -1
- package/dist/components/Tooltip/Tooltip.css +40 -0
- package/dist/components/Tooltip/Tooltip.d.ts +11 -0
- package/dist/components/Tooltip/Tooltip.js +114 -11
- package/dist/index.d.ts +25 -0
- package/dist/index.js +14 -0
- package/dist/teste/AILabel.test.d.ts +1 -0
- package/dist/teste/AILabel.test.js +33 -0
- package/dist/teste/AccordionConteudoLivre.test.d.ts +1 -0
- package/dist/teste/AccordionConteudoLivre.test.js +29 -0
- package/dist/teste/Alert.test.d.ts +1 -0
- package/dist/teste/Alert.test.js +27 -0
- package/dist/teste/AtributosRepassados.test.d.ts +1 -0
- package/dist/teste/AtributosRepassados.test.js +52 -0
- package/dist/teste/AttachmentCardIA.test.d.ts +1 -0
- package/dist/teste/AttachmentCardIA.test.js +89 -0
- package/dist/teste/AvatarGroupOverlap.test.d.ts +1 -0
- package/dist/teste/AvatarGroupOverlap.test.js +56 -0
- package/dist/teste/BadgeTag.test.d.ts +1 -0
- package/dist/teste/BadgeTag.test.js +42 -0
- package/dist/teste/BottomSheet.test.d.ts +1 -0
- package/dist/teste/BottomSheet.test.js +23 -0
- package/dist/teste/BoxItemFlex.test.d.ts +1 -0
- package/dist/teste/BoxItemFlex.test.js +54 -0
- package/dist/teste/BoxLayout.test.d.ts +1 -0
- package/dist/teste/BoxLayout.test.js +35 -0
- package/dist/teste/Button.test.d.ts +1 -0
- package/dist/teste/Button.test.js +27 -0
- package/dist/teste/Calendar.test.d.ts +1 -0
- package/dist/teste/Calendar.test.js +221 -0
- package/dist/teste/ChipsXs.test.d.ts +1 -0
- package/dist/teste/ChipsXs.test.js +31 -0
- package/dist/teste/Coachmark.test.d.ts +1 -0
- package/dist/teste/Coachmark.test.js +149 -0
- package/dist/teste/ColorPicker.test.d.ts +1 -0
- package/dist/teste/ColorPicker.test.js +132 -0
- package/dist/teste/ConfirmAIAction.test.d.ts +1 -0
- package/dist/teste/ConfirmAIAction.test.js +33 -0
- package/dist/teste/DataTableCelulaLivre.test.d.ts +1 -0
- package/dist/teste/DataTableCelulaLivre.test.js +76 -0
- package/dist/teste/DataTableDocumento.test.d.ts +1 -0
- package/dist/teste/DataTableDocumento.test.js +92 -0
- package/dist/teste/DatePicker.test.js +23 -0
- package/dist/teste/Dropdown.test.js +111 -0
- package/dist/teste/FileInputTrigger.test.d.ts +1 -0
- package/dist/teste/FileInputTrigger.test.js +53 -0
- package/dist/teste/IconPicker.test.d.ts +1 -0
- package/dist/teste/IconPicker.test.js +130 -0
- package/dist/teste/InputMascaraEAfins.test.d.ts +1 -0
- package/dist/teste/InputMascaraEAfins.test.js +99 -0
- package/dist/teste/KbdCodeBlock.test.d.ts +1 -0
- package/dist/teste/KbdCodeBlock.test.js +95 -0
- package/dist/teste/List.test.d.ts +1 -0
- package/dist/teste/List.test.js +153 -0
- package/dist/teste/Modal.test.d.ts +1 -0
- package/dist/teste/Modal.test.js +26 -0
- package/dist/teste/ModalVariantes.test.d.ts +1 -0
- package/dist/teste/ModalVariantes.test.js +151 -0
- package/dist/teste/MultiSelectErro.test.d.ts +1 -0
- package/dist/teste/MultiSelectErro.test.js +62 -0
- package/dist/teste/NomeAcessivelSsr.test.d.ts +1 -0
- package/dist/teste/NomeAcessivelSsr.test.js +88 -0
- package/dist/teste/OrgChart.test.d.ts +1 -0
- package/dist/teste/OrgChart.test.js +162 -0
- package/dist/teste/OtpInput.test.d.ts +1 -0
- package/dist/teste/OtpInput.test.js +143 -0
- package/dist/teste/PopoverMaxHeight.test.d.ts +1 -0
- package/dist/teste/PopoverMaxHeight.test.js +38 -0
- package/dist/teste/RichTextEditor.test.d.ts +1 -0
- package/dist/teste/RichTextEditor.test.js +287 -0
- package/dist/teste/RotulosTraduziveis.test.d.ts +1 -0
- package/dist/teste/RotulosTraduziveis.test.js +405 -0
- package/dist/teste/SegmentedControl.test.js +33 -0
- package/dist/teste/Select.test.d.ts +1 -0
- package/dist/teste/Select.test.js +62 -0
- package/dist/teste/SelectPlacementFiltro.test.d.ts +1 -0
- package/dist/teste/SelectPlacementFiltro.test.js +88 -0
- package/dist/teste/Stack.test.d.ts +1 -0
- package/dist/teste/Stack.test.js +57 -0
- package/dist/teste/StatCardRotuloTopo.test.d.ts +1 -0
- package/dist/teste/StatCardRotuloTopo.test.js +34 -0
- package/dist/teste/TabsContadorFechavel.test.d.ts +1 -0
- package/dist/teste/TabsContadorFechavel.test.js +79 -0
- package/dist/teste/Tooltip.test.d.ts +1 -0
- package/dist/teste/Tooltip.test.js +109 -0
- package/dist/teste/TooltipDark.test.d.ts +1 -0
- package/dist/teste/TooltipDark.test.js +31 -0
- package/dist/utils/calendario.d.ts +28 -0
- package/dist/utils/calendario.js +73 -0
- package/dist/utils/chart.d.ts +4 -0
- package/dist/utils/chart.js +3 -2
- package/dist/utils/html-seguro.d.ts +27 -0
- package/dist/utils/html-seguro.js +97 -0
- package/dist/utils/id.d.ts +2 -0
- package/dist/utils/id.js +23 -0
- package/dist/utils/paleta-de-cores.d.ts +26 -0
- package/dist/utils/paleta-de-cores.js +10 -0
- package/dist/utils/texto.d.ts +5 -0
- package/dist/utils/texto.js +5 -0
- package/package.json +3 -3
- package/src/index.ts +26 -0
- package/src/teste/AILabel.test.tsx +41 -0
- package/src/teste/AccordionConteudoLivre.test.tsx +39 -0
- package/src/teste/Alert.test.tsx +32 -0
- package/src/teste/AtributosRepassados.test.tsx +73 -0
- package/src/teste/AttachmentCardIA.test.tsx +126 -0
- package/src/teste/AvatarGroupOverlap.test.tsx +74 -0
- package/src/teste/BadgeTag.test.tsx +64 -0
- package/src/teste/BottomSheet.test.tsx +25 -0
- package/src/teste/BoxItemFlex.test.tsx +81 -0
- package/src/teste/BoxLayout.test.tsx +50 -0
- package/src/teste/Button.test.tsx +39 -0
- package/src/teste/Calendar.test.tsx +282 -0
- package/src/teste/ChipsXs.test.tsx +41 -0
- package/src/teste/Coachmark.test.tsx +198 -0
- package/src/teste/ColorPicker.test.tsx +153 -0
- package/src/teste/ConfirmAIAction.test.tsx +41 -0
- package/src/teste/DataTableCelulaLivre.test.tsx +103 -0
- package/src/teste/DataTableDocumento.test.tsx +102 -0
- package/src/teste/DatePicker.test.tsx +38 -0
- package/src/teste/Dropdown.test.tsx +146 -0
- package/src/teste/FileInputTrigger.test.tsx +89 -0
- package/src/teste/IconPicker.test.tsx +145 -0
- package/src/teste/InputMascaraEAfins.test.tsx +124 -0
- package/src/teste/KbdCodeBlock.test.tsx +106 -0
- package/src/teste/List.test.tsx +269 -0
- package/src/teste/Modal.test.tsx +28 -0
- package/src/teste/ModalVariantes.test.tsx +173 -0
- package/src/teste/MultiSelectErro.test.tsx +97 -0
- package/src/teste/NomeAcessivelSsr.test.tsx +110 -0
- package/src/teste/OrgChart.test.tsx +183 -0
- package/src/teste/OtpInput.test.tsx +163 -0
- package/src/teste/PopoverMaxHeight.test.tsx +47 -0
- package/src/teste/RichTextEditor.test.tsx +329 -0
- package/src/teste/RotulosTraduziveis.test.tsx +545 -0
- package/src/teste/SegmentedControl.test.tsx +57 -0
- package/src/teste/Select.test.tsx +97 -0
- package/src/teste/SelectPlacementFiltro.test.tsx +110 -0
- package/src/teste/Stack.test.tsx +80 -0
- package/src/teste/StatCardRotuloTopo.test.tsx +44 -0
- package/src/teste/TabsContadorFechavel.test.tsx +144 -0
- package/src/teste/Tooltip.test.tsx +219 -0
- package/src/teste/TooltipDark.test.tsx +51 -0
- package/src/utils/calendario.ts +78 -0
- package/src/utils/chart.ts +7 -2
- package/src/utils/html-seguro.ts +94 -0
- package/src/utils/id.ts +24 -0
- package/src/utils/paleta-de-cores.ts +34 -0
- package/src/utils/texto.ts +5 -0
|
@@ -40,6 +40,10 @@ export interface SelectOption {
|
|
|
40
40
|
* @property {string} ariaLabel - Nome acessível quando não há label visível.
|
|
41
41
|
* @property {string} id - ID base dos elementos internos. Gerado automaticamente se omitido.
|
|
42
42
|
* @property {function} onChange - Callback com o(s) valor(es) selecionado(s).
|
|
43
|
+
* @property {string} placement - Onde a lista abre: 'bottom' (padrão) | 'top' | 'auto'. O `auto` abre para cima quando falta espaço embaixo da tela e há mais em cima (lista dentro do rodapé de um modal).
|
|
44
|
+
* @property {string} variant - 'default' | 'filter'. O `filter` é o botão de filtro de barra de ferramentas: contornado em azul, largura do conteúdo, lista mais larga que o botão, busca focada ao abrir. Combine com `searchable`, `emptyOptionLabel` e o slot `footer`.
|
|
45
|
+
* @property {string} emptyOptionLabel - Opção "sem filtro" no topo da lista (seleção única): marcada quando nada está escolhido; ao escolher, `onChange` recebe `""` e o campo volta a mostrar o `placeholder` (o nome do filtro).
|
|
46
|
+
* @property {any} footer - Rodapé fixo da lista, com ações ("Gerenciar marcadores"). Passe o elemento correspondente (React node ou Vue slot `footer`).
|
|
43
47
|
* @quandoUsar Escolher UM valor de uma lista fechada. O valor selecionado fica visível no campo.
|
|
44
48
|
* @quandoNaoUsar Para escolher VÁRIOS valores — use `MultiSelect`. Para um menu de AÇÕES (editar, excluir, duplicar) em vez de valores, use `Dropdown`. Para 2 a 4 opções mutuamente exclusivas sempre visíveis, use `Radio`.
|
|
45
49
|
*/
|
|
@@ -77,6 +81,14 @@ export interface SelectProps {
|
|
|
77
81
|
errorMessage?: string;
|
|
78
82
|
fullWidth?: boolean;
|
|
79
83
|
size?: "sm" | "md" | "lg";
|
|
84
|
+
/** Onde a lista abre. @default 'bottom' */
|
|
85
|
+
placement?: "bottom" | "top" | "auto";
|
|
86
|
+
/** Variante visual. @default 'default' */
|
|
87
|
+
variant?: "default" | "filter";
|
|
88
|
+
/** Opção "sem filtro" no topo da lista (seleção única). Escolhê-la chama `onChange("")`. */
|
|
89
|
+
emptyOptionLabel?: string;
|
|
90
|
+
/** Rodapé fixo da lista (ações). React node ou slot `footer` no Vue. */
|
|
91
|
+
footer?: any;
|
|
80
92
|
pagination?: boolean;
|
|
81
93
|
hasMore?: boolean;
|
|
82
94
|
onLoadMore?: () => void;
|
|
@@ -8,6 +8,7 @@ import Icon from "../Icon/Icon";
|
|
|
8
8
|
import Spinner from "../Spinner/Spinner";
|
|
9
9
|
import Checkbox from "../Checkbox/Checkbox";
|
|
10
10
|
import Tag from "../Tag/Tag";
|
|
11
|
+
import { gerarId } from "../../utils/id";
|
|
11
12
|
function Select(props) {
|
|
12
13
|
const selectRef = useRef(null);
|
|
13
14
|
const triggerRef = useRef(null);
|
|
@@ -30,10 +31,36 @@ function Select(props) {
|
|
|
30
31
|
: props.defaultValue !== undefined && props.defaultValue !== null
|
|
31
32
|
? [props.defaultValue]
|
|
32
33
|
: Array());
|
|
34
|
+
const [opensUp, setOpensUp] = useState(() => false);
|
|
33
35
|
const [shouldFocusSearch, setShouldFocusSearch] = useState(() => false);
|
|
34
36
|
const [shouldFocusTrigger, setShouldFocusTrigger] = useState(() => false);
|
|
35
37
|
const [activeIndex, setActiveIndex] = useState(() => -1);
|
|
36
|
-
const [uid, setUid] = useState(() => "
|
|
38
|
+
const [uid, setUid] = useState(() => "");
|
|
39
|
+
function baseId() {
|
|
40
|
+
return props.id || uid;
|
|
41
|
+
}
|
|
42
|
+
function errorIdText() {
|
|
43
|
+
return baseId() ? baseId() + "-error" : undefined;
|
|
44
|
+
}
|
|
45
|
+
function helperIdText() {
|
|
46
|
+
return baseId() ? baseId() + "-helper" : undefined;
|
|
47
|
+
}
|
|
48
|
+
function isInvalid() {
|
|
49
|
+
return !!props.invalid || !!props.errorMessage;
|
|
50
|
+
}
|
|
51
|
+
function ariaInvalidText() {
|
|
52
|
+
return isInvalid() ? "true" : undefined;
|
|
53
|
+
}
|
|
54
|
+
function describedByText() {
|
|
55
|
+
if (!baseId())
|
|
56
|
+
return undefined;
|
|
57
|
+
const partes = Array();
|
|
58
|
+
if (props.errorMessage)
|
|
59
|
+
partes.push(baseId() + "-error");
|
|
60
|
+
if (mostraApoio())
|
|
61
|
+
partes.push(baseId() + "-helper");
|
|
62
|
+
return partes.length > 0 ? partes.join(" ") : undefined;
|
|
63
|
+
}
|
|
37
64
|
function selectedOptionsList() {
|
|
38
65
|
const currentVal = props.value !== undefined
|
|
39
66
|
? Array.isArray(props.value)
|
|
@@ -66,6 +93,12 @@ function Select(props) {
|
|
|
66
93
|
: internalSelected || [];
|
|
67
94
|
if (currentVal.length === 0)
|
|
68
95
|
return props.placeholder || "Selecione...";
|
|
96
|
+
// Opção "sem filtro" escolhida: volta a mostrar o nome do filtro.
|
|
97
|
+
if (props.emptyOptionLabel &&
|
|
98
|
+
!props.multiple &&
|
|
99
|
+
currentVal.length === 1 &&
|
|
100
|
+
currentVal[0] === "")
|
|
101
|
+
return props.placeholder || "Selecione...";
|
|
69
102
|
if (props.multiple) {
|
|
70
103
|
if (props.selectionDisplay === "tags")
|
|
71
104
|
return "";
|
|
@@ -91,6 +124,11 @@ function Select(props) {
|
|
|
91
124
|
? []
|
|
92
125
|
: [props.value]
|
|
93
126
|
: internalSelected || [];
|
|
127
|
+
if (props.emptyOptionLabel &&
|
|
128
|
+
!props.multiple &&
|
|
129
|
+
currentVal.length === 1 &&
|
|
130
|
+
currentVal[0] === "")
|
|
131
|
+
return true;
|
|
94
132
|
return currentVal.length === 0;
|
|
95
133
|
}
|
|
96
134
|
function formValue() {
|
|
@@ -106,9 +144,18 @@ function Select(props) {
|
|
|
106
144
|
function filteredOptionsList() {
|
|
107
145
|
if (!props.options)
|
|
108
146
|
return [];
|
|
147
|
+
// Opção "sem filtro" no topo (seleção única), sempre visível sem busca.
|
|
148
|
+
const vazia = props.emptyOptionLabel && !props.multiple && !searchTerm
|
|
149
|
+
? [
|
|
150
|
+
{
|
|
151
|
+
label: props.emptyOptionLabel,
|
|
152
|
+
value: "",
|
|
153
|
+
},
|
|
154
|
+
]
|
|
155
|
+
: [];
|
|
109
156
|
// If it's remote search (onSearchChange provided), we don't filter locally
|
|
110
157
|
if (!props.searchable || !searchTerm || props.onSearchChange)
|
|
111
|
-
return props.options;
|
|
158
|
+
return vazia.concat(props.options);
|
|
112
159
|
const term = searchTerm.toLowerCase();
|
|
113
160
|
return props.options.filter((opt) => opt.label.toLowerCase().includes(term));
|
|
114
161
|
}
|
|
@@ -122,6 +169,10 @@ function Select(props) {
|
|
|
122
169
|
props.invalid ? "umds-select--invalid" : "",
|
|
123
170
|
isOpen ? "umds-select--open" : "",
|
|
124
171
|
props.searchVariant === "inline" ? "umds-select--search-inline" : "",
|
|
172
|
+
props.variant === "filter" ? "umds-select--filter" : "",
|
|
173
|
+
opensUp && props.searchVariant !== "inline"
|
|
174
|
+
? "umds-select--placement-top"
|
|
175
|
+
: "",
|
|
125
176
|
props.multiple &&
|
|
126
177
|
props.selectionDisplay === "tags" &&
|
|
127
178
|
selectedOptionsList().length > 0
|
|
@@ -133,22 +184,45 @@ function Select(props) {
|
|
|
133
184
|
.join(" ");
|
|
134
185
|
}
|
|
135
186
|
function listboxIdText() {
|
|
136
|
-
return (
|
|
187
|
+
return baseId() ? baseId() + "-listbox" : undefined;
|
|
137
188
|
}
|
|
138
189
|
function labelIdText() {
|
|
139
|
-
return (
|
|
190
|
+
return baseId() ? baseId() + "-label" : undefined;
|
|
191
|
+
}
|
|
192
|
+
function comboboxLabelledBy() {
|
|
193
|
+
return props.label && baseId() ? labelIdText() : undefined;
|
|
194
|
+
}
|
|
195
|
+
function comboboxAriaLabel() {
|
|
196
|
+
if (props.ariaLabel)
|
|
197
|
+
return props.ariaLabel;
|
|
198
|
+
return props.label && !baseId() ? props.label : undefined;
|
|
140
199
|
}
|
|
141
200
|
function activeDescendantText() {
|
|
142
|
-
if (!isOpen || activeIndex < 0)
|
|
201
|
+
if (!isOpen || activeIndex < 0 || !baseId())
|
|
143
202
|
return undefined;
|
|
144
|
-
return (
|
|
203
|
+
return baseId() + "-option-" + activeIndex;
|
|
145
204
|
}
|
|
146
205
|
function optionIdText(index) {
|
|
147
|
-
return (
|
|
206
|
+
return baseId() ? baseId() + "-option-" + index : undefined;
|
|
148
207
|
}
|
|
149
208
|
function removeItemAriaLabelText(label) {
|
|
150
209
|
return (props.removeAriaLabel || "Remover") + " " + label;
|
|
151
210
|
}
|
|
211
|
+
function shouldOpenUp() {
|
|
212
|
+
const pedido = props.placement || "bottom";
|
|
213
|
+
if (pedido === "top")
|
|
214
|
+
return true;
|
|
215
|
+
if (pedido !== "auto")
|
|
216
|
+
return false;
|
|
217
|
+
if (typeof window === "undefined" || !triggerRef.current)
|
|
218
|
+
return false;
|
|
219
|
+
const caixa = triggerRef.current.getBoundingClientRect();
|
|
220
|
+
const abaixo = window.innerHeight - caixa.bottom;
|
|
221
|
+
const acima = caixa.top;
|
|
222
|
+
const opcoes = filteredOptionsList().length;
|
|
223
|
+
const estimada = Math.min(300, opcoes * 36 + 8 + (props.searchable ? 44 : 0) + (props.footer ? 44 : 0));
|
|
224
|
+
return abaixo < estimada && acima > abaixo;
|
|
225
|
+
}
|
|
152
226
|
function toggle() {
|
|
153
227
|
if (props.disabled || props.readOnly)
|
|
154
228
|
return;
|
|
@@ -158,10 +232,13 @@ function Select(props) {
|
|
|
158
232
|
const next = !isOpen;
|
|
159
233
|
setIsOpen(next);
|
|
160
234
|
if (next) {
|
|
235
|
+
setOpensUp(shouldOpenUp());
|
|
161
236
|
// Abre com a opção já selecionada ativa (padrão combobox).
|
|
162
237
|
setActiveIndex(filteredOptionsList().findIndex((opt) => isOptionSelected(opt.value)));
|
|
163
238
|
if (props.searchable &&
|
|
164
|
-
(props.autoFocusSearch ||
|
|
239
|
+
(props.autoFocusSearch ||
|
|
240
|
+
props.searchVariant === "inline" ||
|
|
241
|
+
props.variant === "filter")) {
|
|
165
242
|
setShouldFocusSearch(true);
|
|
166
243
|
}
|
|
167
244
|
}
|
|
@@ -342,9 +419,15 @@ function Select(props) {
|
|
|
342
419
|
? []
|
|
343
420
|
: [props.value]
|
|
344
421
|
: internalSelected || [];
|
|
422
|
+
// "Sem filtro" aparece marcada enquanto nada está escolhido.
|
|
423
|
+
if (props.emptyOptionLabel && !props.multiple && val === "") {
|
|
424
|
+
return currentVal.length === 0 || currentVal.includes("");
|
|
425
|
+
}
|
|
345
426
|
return currentVal.includes(val);
|
|
346
427
|
}
|
|
347
428
|
useEffect(() => {
|
|
429
|
+
if (!props.id)
|
|
430
|
+
setUid(gerarId("umds-select"));
|
|
348
431
|
if (typeof document === "undefined")
|
|
349
432
|
return;
|
|
350
433
|
const handleClickOutside = (event) => {
|
|
@@ -389,7 +472,7 @@ function Select(props) {
|
|
|
389
472
|
}
|
|
390
473
|
};
|
|
391
474
|
}, []);
|
|
392
|
-
return (_jsxs("div", { ref: selectRef, className: wrapperClassesList(), children: [props.label ? (_jsxs(Text, { as: "label", variant: "label", className: "umds-select__label", id: labelIdText(), children: [props.label, props.required ? (_jsx("span", { className: "umds-select__required", children: " *" })) : null] })) : null, _jsxs("div", { className: "umds-select__container", children: [!(isOpen && props.searchVariant === "inline") ? (_jsxs("div", { role: "combobox", "aria-haspopup": "listbox", className: "umds-select__trigger", ref: triggerRef, onClick: (event) => toggle(), onKeyDown: (event) => handleTriggerKeyDown(event), "aria-readonly": ariaReadonly(), "aria-expanded": isOpen, "aria-controls": listboxIdText(), "aria-activedescendant": activeDescendantText(), "aria-labelledby":
|
|
475
|
+
return (_jsxs("div", { ref: selectRef, className: wrapperClassesList(), children: [props.label ? (_jsxs(Text, { as: "label", variant: "label", className: "umds-select__label", id: labelIdText(), children: [props.label, props.required ? (_jsx("span", { className: "umds-select__required", children: " *" })) : null] })) : null, _jsxs("div", { className: "umds-select__container", children: [!(isOpen && props.searchVariant === "inline") ? (_jsxs("div", { role: "combobox", "aria-haspopup": "listbox", className: "umds-select__trigger", ref: triggerRef, onClick: (event) => toggle(), onKeyDown: (event) => handleTriggerKeyDown(event), "aria-readonly": ariaReadonly(), "aria-expanded": isOpen, "aria-controls": listboxIdText(), "aria-activedescendant": activeDescendantText(), "aria-labelledby": comboboxLabelledBy(), "aria-label": comboboxAriaLabel(), "aria-invalid": ariaInvalidText(), "aria-describedby": describedByText(), "aria-disabled": props.disabled ? "true" : undefined, tabIndex: props.disabled ? -1 : 0, children: [_jsxs("div", { className: "umds-select__values", children: [displayLabelText() ? (_jsx(Text, { as: "span", variant: "body2", className: isPlaceholder() ? "umds-select__placeholder" : "", children: displayLabelText() })) : null, props.multiple &&
|
|
393
476
|
props.selectionDisplay === "tags" &&
|
|
394
477
|
selectedOptionsList().length > 0 ? (_jsx("div", { className: "umds-select__tags", children: selectedOptionsList()?.map((opt) => (_jsx(Tag, { size: "sm", label: opt.label, closable: true, disabled: props.disabled, onClose: (e) => removeValue(opt.value, e) }, opt.value))) })) : null] }), _jsxs("div", { className: "umds-select__actions", children: [props.loading ? _jsx(Spinner, { size: "sm", variant: "secondary" }) : null, _jsx("div", { className: "umds-select__arrow", children: _jsx(Icon, { size: "sm", icon: isOpen ? faChevronUp : faChevronDown }) })] })] })) : null, isOpen ? (_jsxs("div", { className: "umds-select__dropdown", style: props.searchVariant === "inline"
|
|
395
478
|
? {
|
|
@@ -403,7 +486,7 @@ function Select(props) {
|
|
|
403
486
|
index === activeIndex ? "umds-select__option--active" : "",
|
|
404
487
|
]
|
|
405
488
|
.filter(Boolean)
|
|
406
|
-
.join(" "), children: [props.multiple ? (_jsx("div", { className: "umds-select__option-checkbox", children: _jsx(Checkbox, { checked: isOptionSelected(option.value), decorative: true }) })) : null, _jsx("div", { className: "umds-select__option-content", children: _jsx(_Fragment, { children: props.item || (_jsx(Text, { variant: "body2", children: option.label })) }) }), !props.multiple && isOptionSelected(option.value) ? (_jsx("div", { className: "umds-select__option-check", children: _jsx(Icon, { size: "sm", icon: faCheck }) })) : null] }, option.value))), props.loading && props.pagination ? (_jsxs("div", { className: "umds-select__loading-more", children: [_jsx(Spinner, { size: "sm" }), _jsx(Text, { variant: "caption", children: props.loadingLabel || "Carregando mais..." })] })) : null] })] })) : null] }), props.name ? (_jsx("input", { type: "hidden", name: props.name, value: formValue() || "" })) : null, props.errorMessage ? (_jsx(Text, { variant: "caption", color: "negative", className: "umds-select__error-message", children: props.errorMessage })) : null, mostraApoio() ? (_jsx(Text, { variant: "caption", color: "secondary", className: "umds-select__description", children: textoDeApoio() })) : null, props.multiple &&
|
|
489
|
+
.join(" "), children: [props.multiple ? (_jsx("div", { className: "umds-select__option-checkbox", children: _jsx(Checkbox, { checked: isOptionSelected(option.value), decorative: true }) })) : null, _jsx("div", { className: "umds-select__option-content", children: _jsx(_Fragment, { children: props.item || (_jsx(Text, { variant: "body2", children: option.label })) }) }), !props.multiple && isOptionSelected(option.value) ? (_jsx("div", { className: "umds-select__option-check", children: _jsx(Icon, { size: "sm", icon: faCheck }) })) : null] }, option.value))), props.loading && props.pagination ? (_jsxs("div", { className: "umds-select__loading-more", children: [_jsx(Spinner, { size: "sm" }), _jsx(Text, { variant: "caption", children: props.loadingLabel || "Carregando mais..." })] })) : null] }), props.footer ? (_jsx("div", { className: "umds-select__footer", children: _jsx(_Fragment, { children: props.footer }) })) : null] })) : null] }), props.name ? (_jsx("input", { type: "hidden", name: props.name, value: formValue() || "" })) : null, props.errorMessage ? (_jsx(Text, { variant: "caption", color: "negative", className: "umds-select__error-message", id: errorIdText(), children: props.errorMessage })) : null, mostraApoio() ? (_jsx(Text, { variant: "caption", color: "secondary", className: "umds-select__description", id: helperIdText(), children: textoDeApoio() })) : null, props.multiple &&
|
|
407
490
|
props.selectionDisplay === "list" &&
|
|
408
491
|
selectedOptionsList().length > 0 ? (_jsx("div", { className: "umds-select__selected-list", children: selectedOptionsList()?.map((opt) => (_jsxs("div", { className: "umds-select__selected-list-item", children: [_jsx(Text, { variant: "body2", children: opt.label }), _jsx("button", { type: "button", className: "umds-select__list-remove", "aria-label": removeItemAriaLabelText(opt.label), onClick: (e) => removeValue(opt.value, e), children: _jsx(Icon, { size: "sm", icon: faTrash }) })] }, opt.value))) })) : null] }));
|
|
409
492
|
}
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
.umds-side-panel__topo {
|
|
105
|
-
padding: var(--umds-primitive-spacing-xxxs)
|
|
105
|
+
padding: var(--umds-primitive-spacing-xxxs) var(--umds-primitive-spacing-nano) var(--umds-primitive-spacing-nano); /* 16px 8px 8px (produto: 16px 10px 10px) */
|
|
106
106
|
flex-shrink: 0;
|
|
107
107
|
box-sizing: border-box;
|
|
108
108
|
}
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
display: flex;
|
|
112
112
|
align-items: center;
|
|
113
113
|
justify-content: space-between;
|
|
114
|
-
margin-bottom:
|
|
114
|
+
margin-bottom: var(--umds-primitive-spacing-nano); /* 8px (produto: 10px) */
|
|
115
115
|
min-height: var(--umds-primitive-spacing-xxs); /* 24px */
|
|
116
116
|
}
|
|
117
117
|
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
padding: 0;
|
|
132
132
|
margin: 0;
|
|
133
133
|
border: none;
|
|
134
|
-
border-radius:
|
|
134
|
+
border-radius: var(--umds-primitive-border-radius-sm); /* 8px — raio canônico (produto: 6px) */
|
|
135
135
|
background: none;
|
|
136
136
|
color: var(--umds-semantic-color-neutral-dark-medium);
|
|
137
137
|
cursor: pointer;
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
.umds-side-panel__corpo {
|
|
154
|
-
padding: 0
|
|
154
|
+
padding: 0 var(--umds-primitive-spacing-nano) var(--umds-primitive-spacing-xxxs); /* 0 8px 16px (produto: 0 10px 16px) */
|
|
155
155
|
overflow-y: auto;
|
|
156
156
|
min-height: 0;
|
|
157
157
|
flex: 1;
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
.umds-side-panel-item {
|
|
13
13
|
display: flex;
|
|
14
14
|
align-items: center;
|
|
15
|
-
gap:
|
|
15
|
+
gap: var(--umds-primitive-spacing-nano); /* 8px (produto: 9px) */
|
|
16
16
|
width: 100%;
|
|
17
17
|
height: 34px; /* produto: 34px */
|
|
18
18
|
margin: 0;
|
|
19
|
-
padding: 0 var(--umds-primitive-spacing-nano) 0
|
|
19
|
+
padding: 0 var(--umds-primitive-spacing-nano); /* 0 8px (produto: 0 8px 0 9px) */
|
|
20
20
|
border: none;
|
|
21
|
-
border-radius:
|
|
21
|
+
border-radius: var(--umds-primitive-border-radius-sm); /* 8px — raio canônico (produto: 6px) */
|
|
22
22
|
background: none;
|
|
23
23
|
color: var(--umds-semantic-color-neutral-dark-down);
|
|
24
24
|
font-family: inherit;
|
|
@@ -71,12 +71,14 @@
|
|
|
71
71
|
white-space: nowrap;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
/*
|
|
74
|
+
/* O contador é texto: `neutral-dark-down` (#565656, 7,34:1), a mesma cor do
|
|
75
|
+
nome. O produto o deixava mais claro (#7D7D7D), mas isso dá 4,11:1 sobre
|
|
76
|
+
branco e reprova o WCAG 1.4.3 — a hierarquia fica com o tamanho e o peso. */
|
|
75
77
|
.umds-side-panel-item__num {
|
|
76
78
|
flex-shrink: 0;
|
|
77
79
|
font-size: 11px; /* produto: 11px */
|
|
78
80
|
font-weight: var(--umds-primitive-font-weight-bold);
|
|
79
|
-
color: var(--umds-semantic-color-neutral-dark-
|
|
81
|
+
color: var(--umds-semantic-color-neutral-dark-down);
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
.umds-side-panel-item--ativo .umds-side-panel-item__num {
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
.umds-side-panel-search__campo {
|
|
18
18
|
width: 100%;
|
|
19
19
|
height: 30px; /* produto: 30px — entre os degraus 24 e 32 */
|
|
20
|
-
padding: 0 var(--umds-primitive-spacing-nano) 0
|
|
20
|
+
padding: 0 var(--umds-primitive-spacing-nano) 0 var(--umds-primitive-spacing-xs); /* 0 8px 0 32px — 24px encostaria o texto na lupa (produto: 28px) */
|
|
21
21
|
border: 1px solid var(--umds-semantic-color-neutral-light-down);
|
|
22
|
-
border-radius:
|
|
22
|
+
border-radius: var(--umds-primitive-border-radius-sm); /* 8px — raio canônico (produto: 6px) */
|
|
23
23
|
background: var(--umds-semantic-color-neutral-light-up);
|
|
24
24
|
color: var(--umds-semantic-color-neutral-dark-pure);
|
|
25
25
|
font-family: inherit;
|
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
align-items: center;
|
|
10
10
|
justify-content: space-between;
|
|
11
11
|
gap: var(--umds-primitive-spacing-nano); /* 8px */
|
|
12
|
-
padding: var(--umds-primitive-spacing-nano)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
padding: var(--umds-primitive-spacing-nano); /* 8px (produto: 8px 8px 6px) */
|
|
13
|
+
margin-top: var(--umds-primitive-spacing-mini); /* 12px (produto: 14px) */
|
|
14
|
+
/* neutral-dark-down: o rótulo é texto de 10px e o #7D7D7D do produto dá
|
|
15
|
+
4,11:1 sobre branco (WCAG 1.4.3 pede 4,5:1). */
|
|
16
|
+
color: var(--umds-semantic-color-neutral-dark-down);
|
|
16
17
|
font-size: 10px; /* produto: 10px — abaixo do menor degrau (12) */
|
|
17
18
|
font-weight: var(--umds-primitive-font-weight-bold);
|
|
18
19
|
line-height: 15px; /* produto: 15px */
|
|
@@ -27,9 +28,10 @@
|
|
|
27
28
|
width: 23px; /* produto: 23px */
|
|
28
29
|
height: 20px; /* produto: 20px */
|
|
29
30
|
padding: 0 var(--umds-primitive-spacing-micro) 0 0; /* produto: 0 2px 0 0 */
|
|
31
|
+
/* stylelint-disable-next-line 1ds/espaco-da-escala -- ajuste óptico: alinha o glifo com a borda do grupo, não é degrau de espaço */
|
|
30
32
|
margin-right: -3px; /* produto: -3px — alinha o glifo com a borda do grupo */
|
|
31
33
|
border: 1px solid transparent;
|
|
32
|
-
border-radius:
|
|
34
|
+
border-radius: var(--umds-primitive-border-radius-sm); /* 8px — raio canônico (produto: 5px) */
|
|
33
35
|
background: none;
|
|
34
36
|
color: inherit;
|
|
35
37
|
cursor: pointer;
|
|
@@ -55,3 +55,52 @@
|
|
|
55
55
|
.umds-stack--justify-between { justify-content: space-between; }
|
|
56
56
|
.umds-stack--justify-around { justify-content: space-around; }
|
|
57
57
|
.umds-stack--justify-evenly { justify-content: space-evenly; }
|
|
58
|
+
|
|
59
|
+
/* ── Sem espaço ── */
|
|
60
|
+
.umds-stack--gap-none { gap: 0; }
|
|
61
|
+
|
|
62
|
+
/* ── Lista: ul/ol sem marcador, margem nem recuo do navegador ── */
|
|
63
|
+
ul.umds-stack,
|
|
64
|
+
ol.umds-stack {
|
|
65
|
+
list-style: none;
|
|
66
|
+
margin: 0;
|
|
67
|
+
padding: 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* ── Como item de outro Stack/flex ── */
|
|
71
|
+
.umds-stack--grow { flex-grow: 1; }
|
|
72
|
+
.umds-stack--shrink-0 { flex-shrink: 0; }
|
|
73
|
+
.umds-stack--shrink-1 { flex-shrink: 1; }
|
|
74
|
+
|
|
75
|
+
.umds-stack--basis-auto { flex-basis: auto; }
|
|
76
|
+
.umds-stack--basis-0 { flex-basis: 0; }
|
|
77
|
+
.umds-stack--basis-25 { flex-basis: 25%; }
|
|
78
|
+
.umds-stack--basis-33 { flex-basis: 33.3333%; }
|
|
79
|
+
.umds-stack--basis-50 { flex-basis: 50%; }
|
|
80
|
+
.umds-stack--basis-66 { flex-basis: 66.6667%; }
|
|
81
|
+
.umds-stack--basis-75 { flex-basis: 75%; }
|
|
82
|
+
.umds-stack--basis-100 { flex-basis: 100%; }
|
|
83
|
+
|
|
84
|
+
/* O padrão do Stack já é min-width: 0; estas duas só tornam a escolha explícita. */
|
|
85
|
+
.umds-stack--min-w-0 { min-width: 0; }
|
|
86
|
+
.umds-stack--min-w-auto { min-width: auto; }
|
|
87
|
+
|
|
88
|
+
/* ── Overflow: o eixo vem depois do geral, então vence por ordem de cascata ── */
|
|
89
|
+
.umds-stack--overflow-visible { overflow: visible; }
|
|
90
|
+
.umds-stack--overflow-hidden { overflow: hidden; }
|
|
91
|
+
.umds-stack--overflow-auto { overflow: auto; }
|
|
92
|
+
.umds-stack--overflow-scroll { overflow: scroll; }
|
|
93
|
+
|
|
94
|
+
.umds-stack--overflow-x-visible { overflow-x: visible; }
|
|
95
|
+
.umds-stack--overflow-x-hidden { overflow-x: hidden; }
|
|
96
|
+
.umds-stack--overflow-x-auto { overflow-x: auto; }
|
|
97
|
+
.umds-stack--overflow-x-scroll { overflow-x: scroll; }
|
|
98
|
+
|
|
99
|
+
.umds-stack--overflow-y-visible { overflow-y: visible; }
|
|
100
|
+
.umds-stack--overflow-y-hidden { overflow-y: hidden; }
|
|
101
|
+
.umds-stack--overflow-y-auto { overflow-y: auto; }
|
|
102
|
+
.umds-stack--overflow-y-scroll { overflow-y: scroll; }
|
|
103
|
+
|
|
104
|
+
/* ── Dimensão ── */
|
|
105
|
+
.umds-stack--full-height { height: 100%; }
|
|
106
|
+
.umds-stack--full-width { width: 100%; }
|
|
@@ -1,27 +1,60 @@
|
|
|
1
1
|
import './Stack.css';
|
|
2
|
-
/** Degraus da escala oficial de espaçamento do 1DS. */
|
|
3
|
-
export type StackSpacing = "quarck" | "nano" | "micro" | "mini" | "xxxs" | "xxs" | "xs" | "sm" | "md" | "lg" | "xl" | "xxl" | "xxxl";
|
|
2
|
+
/** Degraus da escala oficial de espaçamento do 1DS. `none` zera o espaço. */
|
|
3
|
+
export type StackSpacing = "none" | "quarck" | "nano" | "micro" | "mini" | "xxxs" | "xxs" | "xs" | "sm" | "md" | "lg" | "xl" | "xxl" | "xxxl";
|
|
4
|
+
/** Elemento HTML que o Stack renderiza. */
|
|
5
|
+
/** Degraus da escala oficial de espaçamento do 1DS. `none` zera o espaço. */
|
|
6
|
+
/** Elemento HTML que o Stack renderiza. */
|
|
7
|
+
export type StackTag = "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. `none` zera o espaço. */
|
|
10
|
+
/** Elemento HTML que o Stack renderiza. */
|
|
11
|
+
/** Valores de `overflow` aceitos (por eixo ou nos dois). */
|
|
12
|
+
export type StackOverflow = "visible" | "hidden" | "auto" | "scroll";
|
|
4
13
|
/**
|
|
5
14
|
* Stack — empilha os filhos com espaçamento da escala do DS.
|
|
6
15
|
*
|
|
7
16
|
* Existe para eliminar o `style={{ display: "flex", gap: 16 }}` escrito à mão,
|
|
8
17
|
* que é por onde o design system vaza: o 16 sai da cabeça de quem escreve, não
|
|
9
18
|
* do token. Aqui o `gap` só aceita degraus da escala oficial.
|
|
19
|
+
*
|
|
20
|
+
* Também é o item de outro Stack: quem precisa crescer, encolher ou ocupar a
|
|
21
|
+
* altura toda dentro de um Stack pai aninha um Stack com `grow`, `shrink`,
|
|
22
|
+
* `basis`, `fullHeight`... (não existe `Stack.Item`: subcomponente por ponto
|
|
23
|
+
* não sobrevive aos dois geradores, e o Stack aninhado já é um item flex).
|
|
24
|
+
*
|
|
25
|
+
* Atributos HTML (`id`, `style`, `title`, `role`, `tabIndex`, `data-*`,
|
|
26
|
+
* `aria-*`) vão para o elemento raiz. Com `as="nav"`, `section` ou `form`,
|
|
27
|
+
* passe `aria-label` ou `aria-labelledby`: a região só é anunciada se tiver nome.
|
|
28
|
+
* @property {string} as - Elemento HTML: 'div' (padrão) | 'span' | 'ul' | 'ol' | 'li' | 'section' | 'nav' | 'header' | 'footer' | 'form'
|
|
10
29
|
* @property {string} direction - Eixo do empilhamento: 'vertical' (padrão) | 'horizontal'
|
|
11
|
-
* @property {string} gap - Espaço entre os filhos, na escala do DS
|
|
30
|
+
* @property {string} gap - Espaço entre os filhos, na escala do DS ('none' zera)
|
|
12
31
|
* @property {string} align - Alinhamento no eixo transversal
|
|
13
32
|
* @property {string} justify - Distribuição no eixo principal
|
|
14
33
|
* @property {boolean} wrap - Permite quebrar em várias linhas
|
|
15
34
|
* @property {boolean} inline - Usa display inline-flex em vez de flex
|
|
35
|
+
* @property {boolean} grow - Como item de outro Stack/flex: cresce para ocupar o espaço livre
|
|
36
|
+
* @property {string} shrink - Como item flex: '0' não encolhe, '1' encolhe
|
|
37
|
+
* @property {string} basis - Como item flex: tamanho base ('auto', '0', '25', '33', '50', '66', '75', '100'; os números são %)
|
|
38
|
+
* @property {string} minWidth - '0' (padrão do Stack) deixa o conteúdo longo encolher; 'auto' devolve o mínimo do conteúdo
|
|
39
|
+
* @property {string} overflow - Overflow nos dois eixos
|
|
40
|
+
* @property {string} overflowX - Overflow horizontal
|
|
41
|
+
* @property {string} overflowY - Overflow vertical
|
|
42
|
+
* @property {boolean} fullHeight - Ocupa 100% da altura do pai
|
|
43
|
+
* @property {boolean} fullWidth - Ocupa 100% da largura do pai
|
|
16
44
|
* @property {string} className - Classes CSS adicionais
|
|
17
|
-
* @
|
|
18
|
-
* @
|
|
45
|
+
* @property {function} onSubmit - Só com as="form": callback do envio
|
|
46
|
+
* @quandoUsar Empilhar elementos com espaçamento consistente: campos de um formulário, botões de uma barra de ações, itens de uma lista (`as="ul"` com filhos `as="li"`). É o jeito certo de dar respiro sem escrever CSS, e de fazer uma região crescer ou rolar dentro de outra.
|
|
47
|
+
* @quandoNaoUsar Para layout em COLUNAS que se alinham entre si — use `Grid`. Para uma caixa com padding e fundo, use `Box` (que também aceita direction e gap quando a superfície é a própria linha ou região). Stack só distribui no eixo, não desenha nada.
|
|
19
48
|
*/
|
|
20
|
-
/** Degraus da escala oficial de espaçamento do 1DS. */
|
|
49
|
+
/** Degraus da escala oficial de espaçamento do 1DS. `none` zera o espaço. */
|
|
50
|
+
/** Elemento HTML que o Stack renderiza. */
|
|
51
|
+
/** Valores de `overflow` aceitos (por eixo ou nos dois). */
|
|
21
52
|
export interface StackProps {
|
|
53
|
+
/** Elemento HTML renderizado. @default 'div' */
|
|
54
|
+
as?: StackTag;
|
|
22
55
|
/** Eixo do empilhamento. @default 'vertical' */
|
|
23
56
|
direction?: "vertical" | "horizontal";
|
|
24
|
-
/** Espaço entre os filhos, na escala oficial (xxxs = 16px). @default 'xxxs' */
|
|
57
|
+
/** Espaço entre os filhos, na escala oficial (xxxs = 16px; `none` = 0). @default 'xxxs' */
|
|
25
58
|
gap?: StackSpacing;
|
|
26
59
|
/** Alinhamento no eixo transversal. */
|
|
27
60
|
align?: "start" | "center" | "end" | "stretch" | "baseline";
|
|
@@ -31,8 +64,33 @@ export interface StackProps {
|
|
|
31
64
|
wrap?: boolean;
|
|
32
65
|
/** Usa `inline-flex` em vez de `flex`. */
|
|
33
66
|
inline?: boolean;
|
|
67
|
+
/** Como item de outro Stack/flex: cresce para ocupar o espaço livre. */
|
|
68
|
+
grow?: boolean;
|
|
69
|
+
/** Como item flex: `"0"` não encolhe; `"1"` encolhe. */
|
|
70
|
+
shrink?: "0" | "1";
|
|
71
|
+
/** Como item flex: tamanho base. Os números são porcentagem do pai. */
|
|
72
|
+
basis?: "auto" | "0" | "25" | "33" | "50" | "66" | "75" | "100";
|
|
73
|
+
/** `"0"` (já é o padrão do Stack) deixa o conteúdo encolher; `"auto"` volta ao mínimo do conteúdo. */
|
|
74
|
+
minWidth?: "0" | "auto";
|
|
75
|
+
/** Overflow nos dois eixos. */
|
|
76
|
+
overflow?: StackOverflow;
|
|
77
|
+
/** Overflow horizontal (vence `overflow` no eixo X). */
|
|
78
|
+
overflowX?: StackOverflow;
|
|
79
|
+
/** Overflow vertical (vence `overflow` no eixo Y). */
|
|
80
|
+
overflowY?: StackOverflow;
|
|
81
|
+
/** Ocupa 100% da altura do pai. */
|
|
82
|
+
fullHeight?: boolean;
|
|
83
|
+
/** Ocupa 100% da largura do pai. */
|
|
84
|
+
fullWidth?: boolean;
|
|
34
85
|
/** Classes CSS adicionais. */
|
|
35
86
|
className?: string;
|
|
87
|
+
/** Só com `as="form"`: chamado no envio do formulário. */
|
|
88
|
+
onSubmit?: (event: any) => void;
|
|
89
|
+
/** ID HTML do elemento raiz. */
|
|
90
|
+
id?: string;
|
|
91
|
+
/** Atributos HTML repassados ao elemento raiz (style, data-*, aria-*…). */
|
|
92
|
+
style?: any;
|
|
93
|
+
[key: string]: any;
|
|
36
94
|
/** Conteúdo empilhado. */
|
|
37
95
|
children?: any;
|
|
38
96
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import './Stack.css';
|
|
3
4
|
function Stack(props) {
|
|
5
|
+
function elementTag() {
|
|
6
|
+
return props.as || "div";
|
|
7
|
+
}
|
|
4
8
|
function classes() {
|
|
5
9
|
return [
|
|
6
10
|
"umds-stack",
|
|
@@ -10,11 +14,35 @@ function Stack(props) {
|
|
|
10
14
|
props.justify ? `umds-stack--justify-${props.justify}` : "",
|
|
11
15
|
props.wrap ? "umds-stack--wrap" : "",
|
|
12
16
|
props.inline ? "umds-stack--inline" : "",
|
|
17
|
+
props.grow ? "umds-stack--grow" : "",
|
|
18
|
+
props.shrink ? `umds-stack--shrink-${props.shrink}` : "",
|
|
19
|
+
props.basis ? `umds-stack--basis-${props.basis}` : "",
|
|
20
|
+
props.minWidth ? `umds-stack--min-w-${props.minWidth}` : "",
|
|
21
|
+
props.overflow ? `umds-stack--overflow-${props.overflow}` : "",
|
|
22
|
+
props.overflowX ? `umds-stack--overflow-x-${props.overflowX}` : "",
|
|
23
|
+
props.overflowY ? `umds-stack--overflow-y-${props.overflowY}` : "",
|
|
24
|
+
props.fullHeight ? "umds-stack--full-height" : "",
|
|
25
|
+
props.fullWidth ? "umds-stack--full-width" : "",
|
|
13
26
|
props.className,
|
|
14
27
|
]
|
|
15
28
|
.filter(Boolean)
|
|
16
29
|
.join(" ");
|
|
17
30
|
}
|
|
18
|
-
|
|
31
|
+
function htmlAttrs() {
|
|
32
|
+
const out = {};
|
|
33
|
+
for (const chave in props) {
|
|
34
|
+
if (chave.indexOf("data-") === 0 ||
|
|
35
|
+
chave.indexOf("aria-") === 0 ||
|
|
36
|
+
chave === "style" ||
|
|
37
|
+
chave === "class" ||
|
|
38
|
+
chave === "title" ||
|
|
39
|
+
chave === "role" ||
|
|
40
|
+
chave === "tabIndex") {
|
|
41
|
+
out[chave] = props[chave];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
return (_jsxs(_Fragment, { children: [elementTag() === "div" ? (_jsx("div", { id: props.id, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null, elementTag() === "span" ? (_jsx("span", { id: props.id, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null, elementTag() === "ul" ? (_jsx("ul", { role: "list", id: props.id, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null, elementTag() === "ol" ? (_jsx("ol", { role: "list", id: props.id, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null, elementTag() === "li" ? (_jsx("li", { id: props.id, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null, elementTag() === "section" ? (_jsx("section", { id: props.id, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null, elementTag() === "nav" ? (_jsx("nav", { id: props.id, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null, elementTag() === "header" ? (_jsx("header", { id: props.id, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null, elementTag() === "footer" ? (_jsx("footer", { id: props.id, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null, elementTag() === "form" ? (_jsx("form", { id: props.id, onSubmit: (event) => props.onSubmit && props.onSubmit(event), ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null] }));
|
|
19
47
|
}
|
|
20
48
|
export default Stack;
|
|
@@ -152,3 +152,76 @@
|
|
|
152
152
|
.umds-stat-card__variacao--neutral {
|
|
153
153
|
color: var(--umds-semantic-color-neutral-dark-down);
|
|
154
154
|
}
|
|
155
|
+
|
|
156
|
+
/* ── ⓘ de ajuda ao lado do rótulo (infoTooltip) ── */
|
|
157
|
+
.umds-stat-card__rotulo {
|
|
158
|
+
display: inline-flex;
|
|
159
|
+
align-items: center;
|
|
160
|
+
gap: var(--umds-primitive-spacing-nano);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.umds-stat-card__info {
|
|
164
|
+
display: inline-flex;
|
|
165
|
+
align-items: center;
|
|
166
|
+
justify-content: center;
|
|
167
|
+
padding: 0;
|
|
168
|
+
border: none;
|
|
169
|
+
background: transparent;
|
|
170
|
+
color: var(--umds-semantic-color-neutral-dark-medium);
|
|
171
|
+
cursor: help;
|
|
172
|
+
border-radius: var(--umds-primitive-border-radius-circular);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.umds-stat-card__info:hover {
|
|
176
|
+
color: var(--umds-semantic-color-neutral-dark-pure);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.umds-stat-card__info:focus-visible {
|
|
180
|
+
outline: 2px solid var(--umds-semantic-color-primary-pure);
|
|
181
|
+
outline-offset: 2px;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* ── labelPosition="top": rótulo no topo, ícone e número embaixo ──
|
|
185
|
+
O HTML segue com o número antes do rótulo (a ordem do leitor de tela); só a
|
|
186
|
+
grade muda a ordem visual. O corpo vira `display: contents` para o rótulo,
|
|
187
|
+
o número e o resto virarem itens da própria grade do cartão. */
|
|
188
|
+
.umds-stat-card--rotulo-topo {
|
|
189
|
+
display: grid;
|
|
190
|
+
grid-template-columns: auto 1fr;
|
|
191
|
+
align-items: center;
|
|
192
|
+
column-gap: 0;
|
|
193
|
+
row-gap: var(--umds-primitive-spacing-nano);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.umds-stat-card--rotulo-topo .umds-stat-card__corpo {
|
|
197
|
+
display: contents;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.umds-stat-card--rotulo-topo .umds-stat-card__rotulo {
|
|
201
|
+
grid-column: 1 / -1;
|
|
202
|
+
grid-row: 1;
|
|
203
|
+
font-weight: var(--umds-primitive-font-weight-semibold);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.umds-stat-card--rotulo-topo .umds-stat-card__icone {
|
|
207
|
+
grid-column: 1;
|
|
208
|
+
grid-row: 2;
|
|
209
|
+
margin-right: var(--umds-primitive-spacing-mini);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.umds-stat-card--rotulo-topo .umds-stat-card__valor {
|
|
213
|
+
grid-column: 2;
|
|
214
|
+
grid-row: 2;
|
|
215
|
+
font-size: var(--umds-primitive-font-size-lg); /* 32px */
|
|
216
|
+
font-weight: var(--umds-primitive-font-weight-extrabold);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.umds-stat-card--rotulo-topo .umds-stat-card__descricao,
|
|
220
|
+
.umds-stat-card--rotulo-topo .umds-stat-card__variacao {
|
|
221
|
+
grid-column: 1 / -1;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* Sem ícone, o número ocupa a linha toda. */
|
|
225
|
+
.umds-stat-card--rotulo-topo:not(:has(.umds-stat-card__icone)) .umds-stat-card__valor {
|
|
226
|
+
grid-column: 1 / -1;
|
|
227
|
+
}
|