@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
|
@@ -7,6 +7,7 @@ import Text from "../Text/Text";
|
|
|
7
7
|
import Checkbox from "../Checkbox/Checkbox";
|
|
8
8
|
import Tag from "../Tag/Tag";
|
|
9
9
|
import Icon from "../Icon/Icon";
|
|
10
|
+
import { gerarId } from "../../utils/id";
|
|
10
11
|
function MultiSelect(props) {
|
|
11
12
|
const containerRef = useRef(null);
|
|
12
13
|
const searchInputRef = useRef(null);
|
|
@@ -42,15 +43,46 @@ function MultiSelect(props) {
|
|
|
42
43
|
const [activeIndex, setActiveIndex] = useState(() => -1);
|
|
43
44
|
const [internalSelected, setInternalSelected] = useState(() => props.defaultValue || Array());
|
|
44
45
|
const [shouldFocusSearch, setShouldFocusSearch] = useState(() => false);
|
|
45
|
-
const [uid, setUid] = useState(() => "
|
|
46
|
+
const [uid, setUid] = useState(() => "");
|
|
47
|
+
function baseId() {
|
|
48
|
+
return props.id || uid;
|
|
49
|
+
}
|
|
46
50
|
function comboboxIdText() {
|
|
47
|
-
return (
|
|
51
|
+
return baseId() ? baseId() + "-combobox" : undefined;
|
|
48
52
|
}
|
|
49
53
|
function listboxIdText() {
|
|
50
|
-
return (
|
|
54
|
+
return baseId() ? baseId() + "-listbox" : undefined;
|
|
51
55
|
}
|
|
52
56
|
function labelIdText() {
|
|
53
|
-
return (
|
|
57
|
+
return baseId() ? baseId() + "-label" : undefined;
|
|
58
|
+
}
|
|
59
|
+
function comboboxLabelledBy() {
|
|
60
|
+
return props.label && baseId() ? labelIdText() : undefined;
|
|
61
|
+
}
|
|
62
|
+
function comboboxAriaLabel() {
|
|
63
|
+
return props.label && !baseId() ? props.label : undefined;
|
|
64
|
+
}
|
|
65
|
+
function errorIdText() {
|
|
66
|
+
return baseId() ? baseId() + "-error" : undefined;
|
|
67
|
+
}
|
|
68
|
+
function helperIdText() {
|
|
69
|
+
return baseId() ? baseId() + "-helper" : undefined;
|
|
70
|
+
}
|
|
71
|
+
function isInvalid() {
|
|
72
|
+
return !!props.invalid || !!props.errorMessage;
|
|
73
|
+
}
|
|
74
|
+
function ariaInvalidText() {
|
|
75
|
+
return isInvalid() ? "true" : undefined;
|
|
76
|
+
}
|
|
77
|
+
function describedByText() {
|
|
78
|
+
if (!baseId())
|
|
79
|
+
return undefined;
|
|
80
|
+
const partes = Array();
|
|
81
|
+
if (props.errorMessage)
|
|
82
|
+
partes.push(baseId() + "-error");
|
|
83
|
+
if (mostraApoio())
|
|
84
|
+
partes.push(baseId() + "-helper");
|
|
85
|
+
return partes.length > 0 ? partes.join(" ") : undefined;
|
|
54
86
|
}
|
|
55
87
|
function currentValue() {
|
|
56
88
|
return props.value !== undefined
|
|
@@ -136,6 +168,8 @@ function MultiSelect(props) {
|
|
|
136
168
|
toggle();
|
|
137
169
|
}
|
|
138
170
|
else if (event.key === "Escape" && isOpen) {
|
|
171
|
+
// O Esc é da lista (fecha só ela): o Modal em volta não reage.
|
|
172
|
+
event.preventDefault();
|
|
139
173
|
setIsOpen(false);
|
|
140
174
|
setSearchTerm("");
|
|
141
175
|
}
|
|
@@ -151,6 +185,7 @@ function MultiSelect(props) {
|
|
|
151
185
|
}
|
|
152
186
|
function handleSearchKeyDown(event) {
|
|
153
187
|
if (event.key === "Escape") {
|
|
188
|
+
event.preventDefault();
|
|
154
189
|
setIsOpen(false);
|
|
155
190
|
setSearchTerm("");
|
|
156
191
|
setActiveIndex(-1);
|
|
@@ -185,12 +220,12 @@ function MultiSelect(props) {
|
|
|
185
220
|
}
|
|
186
221
|
}
|
|
187
222
|
function activeOptionId() {
|
|
188
|
-
if (!isOpen || activeIndex < 0)
|
|
223
|
+
if (!isOpen || activeIndex < 0 || !baseId())
|
|
189
224
|
return undefined;
|
|
190
|
-
return
|
|
225
|
+
return baseId() + "-listbox-option-" + activeIndex;
|
|
191
226
|
}
|
|
192
227
|
function optionIdText(index) {
|
|
193
|
-
return
|
|
228
|
+
return baseId() ? baseId() + "-listbox-option-" + index : undefined;
|
|
194
229
|
}
|
|
195
230
|
function clearSearchTerm() {
|
|
196
231
|
setSearchTerm("");
|
|
@@ -229,6 +264,8 @@ function MultiSelect(props) {
|
|
|
229
264
|
props.onChange([]);
|
|
230
265
|
}
|
|
231
266
|
useEffect(() => {
|
|
267
|
+
if (!props.id)
|
|
268
|
+
setUid(gerarId("umds-multiselect"));
|
|
232
269
|
if (typeof document !== "undefined") {
|
|
233
270
|
const handleClickOutside = (event) => {
|
|
234
271
|
if (containerRef.current &&
|
|
@@ -257,6 +294,6 @@ function MultiSelect(props) {
|
|
|
257
294
|
}
|
|
258
295
|
};
|
|
259
296
|
}, []);
|
|
260
|
-
return (_jsxs("div", { ref: containerRef, className: wrapperClasses(), children: [props.label ? (_jsxs(Text, { as: "label", variant: "label", className: "umds-multiselect__label", id: labelIdText(), children: [props.label, props.required ? (_jsx("span", { className: "umds-multiselect__required", children: " *" })) : null] })) : null, _jsxs("div", { className: "umds-multiselect__container", children: [_jsxs("div", { role: "combobox", "aria-haspopup": "listbox", className: "umds-multiselect__trigger", id: comboboxIdText(), onClick: (event) => toggle(), onKeyDown: (event) => handleTriggerKeyDown(event), "aria-readonly": ariaReadonly(), "aria-expanded": isOpen, "aria-controls": listboxIdText(), "aria-labelledby":
|
|
297
|
+
return (_jsxs("div", { ref: containerRef, className: wrapperClasses(), children: [props.label ? (_jsxs(Text, { as: "label", variant: "label", className: "umds-multiselect__label", id: labelIdText(), children: [props.label, props.required ? (_jsx("span", { className: "umds-multiselect__required", children: " *" })) : null] })) : null, _jsxs("div", { className: "umds-multiselect__container", children: [_jsxs("div", { role: "combobox", "aria-haspopup": "listbox", className: "umds-multiselect__trigger", id: comboboxIdText(), onClick: (event) => toggle(), onKeyDown: (event) => handleTriggerKeyDown(event), "aria-readonly": ariaReadonly(), "aria-expanded": isOpen, "aria-controls": listboxIdText(), "aria-labelledby": comboboxLabelledBy(), "aria-label": comboboxAriaLabel(), "aria-disabled": props.disabled, "aria-invalid": ariaInvalidText(), "aria-describedby": describedByText(), tabIndex: props.disabled ? -1 : 0, children: [_jsxs("div", { className: "umds-multiselect__tags-area", children: [selectedOptions().length === 0 ? (_jsx("span", { className: "umds-multiselect__placeholder", children: props.placeholder || "Selecione..." })) : null, selectedOptions().length > 0 ? (_jsx(_Fragment, { children: selectedOptions()?.map((opt) => (_jsx(Tag, { size: "sm", label: opt.label, closable: true, closeAriaLabel: removeTagAriaLabelText(opt.label), onClose: (event) => removeTag(opt.value, event) }, opt.value))) })) : null] }), _jsxs("div", { className: "umds-multiselect__actions", children: [selectedOptions().length > 0 && !props.disabled ? (_jsx("span", { role: "button", className: "umds-multiselect__clear", onClick: (event) => clearAll(event), onKeyDown: (event) => aoTeclarLimparTudo(event), tabIndex: 0, "aria-label": clearSelectionText(), title: clearSelectionText(), children: _jsx(Icon, { variant: "inherit", customSize: "10px", icon: faXmark }) })) : null, _jsx("div", { className: "umds-multiselect__arrow", children: _jsx(Icon, { variant: "inherit", customSize: "12px", icon: faChevronDown }) })] })] }), isOpen ? (_jsxs("div", { className: "umds-multiselect__dropdown", children: [_jsxs("div", { className: "umds-multiselect__search", children: [_jsx("div", { className: "umds-multiselect__search-icon", children: _jsx(Icon, { variant: "inherit", customSize: "14px", icon: faMagnifyingGlass }) }), _jsx("input", { type: "text", role: "combobox", className: "umds-multiselect__search-input", ref: searchInputRef, "aria-label": props.searchAriaLabel || "Buscar", placeholder: props.searchPlaceholder || "Buscar...", value: searchTerm, onInput: (event) => handleSearch(event), onChange: (event) => handleSearch(event), onKeyDown: (event) => handleSearchKeyDown(event), onClick: (event) => event.stopPropagation(), "aria-expanded": isOpen, "aria-controls": listboxIdText(), "aria-activedescendant": activeOptionId() }), !!searchTerm ? (_jsx("span", { role: "button", className: "umds-multiselect__search-clear", onClick: (event) => clearSearchTerm(), onKeyDown: (event) => aoTeclarLimparBusca(event), tabIndex: 0, "aria-label": props.clearSearchAriaLabel || "Limpar busca", children: _jsx(Icon, { variant: "inherit", customSize: "10px", icon: faXmark }) })) : null] }), _jsxs("div", { role: "listbox", "aria-multiselectable": "true", className: "umds-multiselect__options", id: listboxIdText(), children: [filteredOptions().length === 0 ? (_jsx("div", { className: "umds-multiselect__empty", children: _jsx(Text, { variant: "body2", color: "secondary", children: props.emptyLabel || "Nenhum item encontrado" }) })) : null, filteredOptions()?.map((option, indice) => (_jsxs("div", { role: "option", id: optionIdText(indice), onClick: (event) => selectOption(option.value), "aria-selected": isSelected(option.value), className: optionClasses(option.value, indice), children: [_jsx("div", { "aria-hidden": "true", className: "umds-multiselect__option-checkbox", children: _jsx(Checkbox, { size: "sm", checked: isSelected(option.value), decorative: true }) }), _jsx("span", { className: "umds-multiselect__option-label", children: option.label })] }, option.value)))] }), selectedOptions().length > 0 ? (_jsxs("div", { className: "umds-multiselect__footer", children: [_jsx(Text, { variant: "caption", color: "secondary", children: selectedCountText() }), _jsx("span", { role: "button", className: "umds-multiselect__footer-clear", onClick: (event) => clearAll(event), onKeyDown: (event) => aoTeclarLimparTudo(event), tabIndex: 0, children: props.clearAllLabel || "Limpar tudo" })] })) : null] })) : null] }), props.name ? (_jsx(_Fragment, { children: currentValue()?.map((val) => (_jsx("input", { type: "hidden", name: props.name, value: String(val) }, String(val)))) })) : null, props.errorMessage ? (_jsx(Text, { variant: "caption", color: "negative", className: "umds-multiselect__error-message", id: errorIdText(), children: props.errorMessage })) : null, mostraApoio() ? (_jsx(Text, { variant: "caption", color: "secondary", className: "umds-multiselect__description", id: helperIdText(), children: textoDeApoio() })) : null] }));
|
|
261
298
|
}
|
|
262
299
|
export default MultiSelect;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/* ─────────────────────────────────────────────
|
|
2
|
+
ORG CHART
|
|
3
|
+
Organograma de cima para baixo, com conectores.
|
|
4
|
+
|
|
5
|
+
O desenho é calculado em JS (posições absolutas numa superfície do tamanho do
|
|
6
|
+
organograma); este CSS dá a cara dos nós e das linhas. A raiz sai cheia na
|
|
7
|
+
cor primária, os demais em tom claro. O texto do nó corta com reticências.
|
|
8
|
+
|
|
9
|
+
Cores: semânticos · Medidas: primitivos
|
|
10
|
+
───────────────────────────────────────────── */
|
|
11
|
+
|
|
12
|
+
.umds-org-chart {
|
|
13
|
+
font-family: var(--umds-semantic-font-family-base);
|
|
14
|
+
color: var(--umds-semantic-color-neutral-dark-pure);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.umds-org-chart__scroller {
|
|
18
|
+
overflow: auto;
|
|
19
|
+
/* Folga para o foco e a sombra dos nós não serem cortados pelo overflow. */
|
|
20
|
+
padding: var(--umds-primitive-spacing-nano);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.umds-org-chart__surface {
|
|
24
|
+
position: relative;
|
|
25
|
+
margin: 0 auto;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.umds-org-chart__lines {
|
|
29
|
+
position: absolute;
|
|
30
|
+
top: 0;
|
|
31
|
+
left: 0;
|
|
32
|
+
overflow: visible;
|
|
33
|
+
pointer-events: none;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.umds-org-chart__line {
|
|
37
|
+
fill: none;
|
|
38
|
+
stroke: var(--umds-semantic-color-neutral-light-down);
|
|
39
|
+
stroke-width: var(--umds-primitive-border-width-hairline);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ── Nó ── */
|
|
43
|
+
.umds-org-chart__node {
|
|
44
|
+
position: absolute;
|
|
45
|
+
box-sizing: border-box;
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-direction: column;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
gap: var(--umds-primitive-spacing-micro); /* 2px */
|
|
51
|
+
padding: var(--umds-primitive-spacing-nano); /* 8px */
|
|
52
|
+
text-align: center;
|
|
53
|
+
background: var(--umds-semantic-color-primary-light);
|
|
54
|
+
color: var(--umds-semantic-color-primary-dark);
|
|
55
|
+
border: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-color-neutral-light-medium);
|
|
56
|
+
border-radius: var(--umds-primitive-border-radius-sm);
|
|
57
|
+
box-shadow: var(--umds-semantic-shadow-sm);
|
|
58
|
+
cursor: pointer;
|
|
59
|
+
transition:
|
|
60
|
+
box-shadow var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard),
|
|
61
|
+
border-color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.umds-org-chart__node--root {
|
|
65
|
+
background: var(--umds-semantic-color-primary-pure);
|
|
66
|
+
/* Texto claro sobre o primário cheio. */
|
|
67
|
+
color: var(--umds-semantic-color-background-white);
|
|
68
|
+
border-color: var(--umds-semantic-color-primary-pure);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.umds-org-chart__node:hover {
|
|
72
|
+
box-shadow: var(--umds-semantic-shadow-md);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.umds-org-chart__node--selected {
|
|
76
|
+
border-color: var(--umds-semantic-color-primary-pure);
|
|
77
|
+
box-shadow: 0 0 0 var(--umds-primitive-border-width-thin) var(--umds-semantic-color-primary-pure);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.umds-org-chart__node:focus-visible {
|
|
81
|
+
outline: var(--umds-primitive-border-width-thin) solid var(--umds-semantic-color-primary-pure);
|
|
82
|
+
outline-offset: var(--umds-primitive-border-width-thin);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.umds-org-chart__title,
|
|
86
|
+
.umds-org-chart__subtitle {
|
|
87
|
+
display: block;
|
|
88
|
+
max-width: 100%;
|
|
89
|
+
overflow: hidden;
|
|
90
|
+
text-overflow: ellipsis;
|
|
91
|
+
white-space: nowrap;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.umds-org-chart__title {
|
|
95
|
+
font-size: var(--umds-primitive-font-size-xs); /* 16px */
|
|
96
|
+
font-weight: var(--umds-primitive-font-weight-bold);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.umds-org-chart__subtitle {
|
|
100
|
+
font-size: var(--umds-primitive-font-size-xxxs); /* 12px */
|
|
101
|
+
font-weight: var(--umds-primitive-font-weight-regular);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.umds-org-chart__custom {
|
|
105
|
+
width: 100%;
|
|
106
|
+
min-width: 0;
|
|
107
|
+
overflow: hidden;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* ── Expandir e recolher (mouse; o teclado usa Espaço no nó) ── */
|
|
111
|
+
.umds-org-chart__toggle {
|
|
112
|
+
position: absolute;
|
|
113
|
+
display: inline-flex;
|
|
114
|
+
align-items: center;
|
|
115
|
+
justify-content: center;
|
|
116
|
+
box-sizing: border-box;
|
|
117
|
+
width: var(--umds-primitive-spacing-xxs); /* 24px */
|
|
118
|
+
height: var(--umds-primitive-spacing-xxs);
|
|
119
|
+
margin: 0;
|
|
120
|
+
padding: 0;
|
|
121
|
+
transform: translate(-50%, -50%);
|
|
122
|
+
border: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-color-neutral-light-down);
|
|
123
|
+
border-radius: var(--umds-primitive-border-radius-circular);
|
|
124
|
+
background: var(--umds-semantic-color-background-white);
|
|
125
|
+
color: var(--umds-semantic-color-neutral-dark-down);
|
|
126
|
+
font: inherit;
|
|
127
|
+
font-size: var(--umds-primitive-font-size-xs); /* 16px */
|
|
128
|
+
line-height: 1;
|
|
129
|
+
cursor: pointer;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.umds-org-chart__toggle:hover {
|
|
133
|
+
background: var(--umds-semantic-color-background-light);
|
|
134
|
+
color: var(--umds-semantic-color-neutral-dark-pure);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@media (forced-colors: active) {
|
|
138
|
+
.umds-org-chart__node {
|
|
139
|
+
border: var(--umds-primitive-border-width-hairline) solid CanvasText;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.umds-org-chart__node--selected {
|
|
143
|
+
outline: var(--umds-primitive-border-width-thin) solid Highlight;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.umds-org-chart__line {
|
|
147
|
+
stroke: CanvasText;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import './OrgChart.css';
|
|
2
|
+
/**
|
|
3
|
+
* Nó do organograma.
|
|
4
|
+
* @property {string} id - Identidade do nó (única no organograma)
|
|
5
|
+
* @property {string} title - Título do nó (a sigla, por exemplo)
|
|
6
|
+
* @property {string} subtitle - Segunda linha (o nome por extenso)
|
|
7
|
+
* @property {OrgChartNode[]} children - Nós filhos
|
|
8
|
+
*/
|
|
9
|
+
export interface OrgChartNode {
|
|
10
|
+
id: string;
|
|
11
|
+
title: string;
|
|
12
|
+
subtitle?: string;
|
|
13
|
+
children?: OrgChartNode[];
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* OrgChart — organograma: uma árvore hierárquica desenhada de cima para baixo,
|
|
18
|
+
* com conectores, em que cada nó mostra título e subtítulo (ou o conteúdo que
|
|
19
|
+
* você der) e os que têm filhos expandem e recolhem.
|
|
20
|
+
*
|
|
21
|
+
* O desenho é calculado, não aninhado: cada nó tem largura e altura fixas
|
|
22
|
+
* (`nodeWidth`, `nodeHeight`), os filhos se distribuem sob o pai e o pai se
|
|
23
|
+
* centra sobre eles. Por isso o texto do nó corta com reticências (o `title`
|
|
24
|
+
* completo vai no tooltip) e o conteúdo livre precisa caber na caixa. Se o
|
|
25
|
+
* organograma passar da largura do container, o container rola.
|
|
26
|
+
*
|
|
27
|
+
* O primeiro nível (a raiz) sai cheio na cor primária e os demais em tom claro;
|
|
28
|
+
* `selectedId` marca um nó. O conteúdo do nó é livre: no React, `renderNode(nó,
|
|
29
|
+
* { level, expanded })`; no Vue, o slot `node` com `{ node, level, expanded }`.
|
|
30
|
+
*
|
|
31
|
+
* Acessibilidade: é uma `role="tree"` com nós `treeitem` (`aria-level`,
|
|
32
|
+
* `aria-posinset`, `aria-setsize`, `aria-expanded`). Um Tab entra no nó em foco;
|
|
33
|
+
* Cima vai ao pai, Baixo ao primeiro filho (abrindo o nó, se estiver recolhido),
|
|
34
|
+
* Esquerda e Direita aos irmãos, Home e End ao primeiro e ao último irmão, Espaço
|
|
35
|
+
* expande ou recolhe, Enter aciona o nó (`onNodeClick`). O botão de expandir
|
|
36
|
+
* desenhado no nó é para o mouse (a mesma ação do teclado já existe).
|
|
37
|
+
*
|
|
38
|
+
* Tudo expandido por padrão: `collapsedIds` (controlado) ou `defaultCollapsedIds`
|
|
39
|
+
* escolhem o que começa recolhido, e `onCollapsedChange` avisa a lista nova.
|
|
40
|
+
*
|
|
41
|
+
* Limites: só de cima para baixo; sem zoom nem arrastar (a rolagem é a do
|
|
42
|
+
* container); nó de altura variável não cabe: use `nodeHeight` para o maior.
|
|
43
|
+
* @property {OrgChartNode[]} nodes - A árvore: lista de nós raiz, cada um com `children`
|
|
44
|
+
* @property {string[]} collapsedIds - Ids recolhidos (controlado)
|
|
45
|
+
* @property {string[]} defaultCollapsedIds - Ids que começam recolhidos (não controlado)
|
|
46
|
+
* @property {string} selectedId - Id do nó marcado
|
|
47
|
+
* @property {number} nodeWidth - Largura de cada nó, em px (padrão 176)
|
|
48
|
+
* @property {number} nodeHeight - Altura de cada nó, em px (padrão 64)
|
|
49
|
+
* @property {number} gapX - Espaço entre nós irmãos, em px (padrão 16)
|
|
50
|
+
* @property {number} gapY - Espaço entre um nível e o seguinte, em px (padrão 40)
|
|
51
|
+
* @property {string} ariaLabel - Nome acessível da árvore (padrão "Organograma")
|
|
52
|
+
* @property {string} expandLabel - Nome do botão de expandir (padrão "Expandir")
|
|
53
|
+
* @property {string} collapseLabel - Nome do botão de recolher (padrão "Recolher")
|
|
54
|
+
* @property {string} className - Classes CSS adicionais
|
|
55
|
+
* @property {function} renderNode - Só no React: conteúdo do nó, `(nó, { level, expanded }) => nó`. No Vue, o slot `node`.
|
|
56
|
+
* @property {function} onNodeClick - Clique ou Enter num nó: recebe o nó
|
|
57
|
+
* @property {function} onCollapsedChange - Mudou o que está recolhido: recebe a lista de ids
|
|
58
|
+
* @slot node - Só no Vue. Conteúdo do nó: `{ node, level, expanded }`.
|
|
59
|
+
* @quandoUsar Mostrar a estrutura de setores ou de cargos de um órgão como um desenho, com a hierarquia à vista.
|
|
60
|
+
* @quandoNaoUsar Para navegar e escolher em hierarquias grandes, use `Tree` (lista indentada, mais densa e acessível). Para um fluxo de processo, use o editor de processos. Para uma lista plana, use `List`.
|
|
61
|
+
*/
|
|
62
|
+
export interface OrgChartProps {
|
|
63
|
+
nodes?: OrgChartNode[];
|
|
64
|
+
collapsedIds?: string[];
|
|
65
|
+
defaultCollapsedIds?: string[];
|
|
66
|
+
selectedId?: string;
|
|
67
|
+
nodeWidth?: number;
|
|
68
|
+
nodeHeight?: number;
|
|
69
|
+
gapX?: number;
|
|
70
|
+
gapY?: number;
|
|
71
|
+
ariaLabel?: string;
|
|
72
|
+
expandLabel?: string;
|
|
73
|
+
collapseLabel?: string;
|
|
74
|
+
className?: string;
|
|
75
|
+
renderNode?: (node: OrgChartNode, meta: {
|
|
76
|
+
level: number;
|
|
77
|
+
expanded: boolean;
|
|
78
|
+
}) => any;
|
|
79
|
+
onNodeClick?: (node: OrgChartNode) => void;
|
|
80
|
+
onCollapsedChange?: (ids: string[]) => void;
|
|
81
|
+
}
|
|
82
|
+
declare function OrgChart(props: OrgChartProps): import("react/jsx-runtime").JSX.Element;
|
|
83
|
+
export default OrgChart;
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import './OrgChart.css';
|
|
4
|
+
import { useState, useRef, useEffect } from "react";
|
|
5
|
+
function OrgChart(props) {
|
|
6
|
+
const rootRef = useRef(null);
|
|
7
|
+
const focoPendenteRef = useRef("");
|
|
8
|
+
const [internalCollapsed, setInternalCollapsed] = useState(() => props.defaultCollapsedIds || []);
|
|
9
|
+
const [focusId, setFocusId] = useState(() => "");
|
|
10
|
+
function widthPx() {
|
|
11
|
+
return props.nodeWidth && props.nodeWidth > 0 ? props.nodeWidth : 176;
|
|
12
|
+
}
|
|
13
|
+
function heightPx() {
|
|
14
|
+
return props.nodeHeight && props.nodeHeight > 0 ? props.nodeHeight : 64;
|
|
15
|
+
}
|
|
16
|
+
function gapXPx() {
|
|
17
|
+
return props.gapX !== undefined && props.gapX >= 0 ? props.gapX : 16;
|
|
18
|
+
}
|
|
19
|
+
function gapYPx() {
|
|
20
|
+
return props.gapY !== undefined && props.gapY >= 0 ? props.gapY : 40;
|
|
21
|
+
}
|
|
22
|
+
function collapsed() {
|
|
23
|
+
return props.collapsedIds !== undefined
|
|
24
|
+
? props.collapsedIds
|
|
25
|
+
: internalCollapsed;
|
|
26
|
+
}
|
|
27
|
+
function treeName() {
|
|
28
|
+
return props.ariaLabel || "Organograma";
|
|
29
|
+
}
|
|
30
|
+
function classes() {
|
|
31
|
+
return ["umds-org-chart", props.className].filter(Boolean).join(" ");
|
|
32
|
+
}
|
|
33
|
+
function layout() {
|
|
34
|
+
const raizes = props.nodes || [];
|
|
35
|
+
const larg = widthPx();
|
|
36
|
+
const alt = heightPx();
|
|
37
|
+
const passoX = larg + gapXPx();
|
|
38
|
+
const passoY = alt + gapYPx();
|
|
39
|
+
const fechados = collapsed();
|
|
40
|
+
const lista = [];
|
|
41
|
+
const caminhos = [];
|
|
42
|
+
let folha = 0;
|
|
43
|
+
let maxNivel = 0;
|
|
44
|
+
const visitar = (no, nivel, paiId, pos, total) => {
|
|
45
|
+
const filhos = no.children || [];
|
|
46
|
+
const temFilhos = filhos.length > 0;
|
|
47
|
+
const aberto = temFilhos && fechados.indexOf(no.id) === -1;
|
|
48
|
+
const item = {
|
|
49
|
+
id: no.id,
|
|
50
|
+
node: no,
|
|
51
|
+
level: nivel,
|
|
52
|
+
parentId: paiId,
|
|
53
|
+
position: pos,
|
|
54
|
+
setSize: total,
|
|
55
|
+
hasChildren: temFilhos,
|
|
56
|
+
expanded: aberto,
|
|
57
|
+
childIds: [],
|
|
58
|
+
x: 0,
|
|
59
|
+
y: nivel * passoY,
|
|
60
|
+
};
|
|
61
|
+
if (nivel > maxNivel)
|
|
62
|
+
maxNivel = nivel;
|
|
63
|
+
lista.push(item);
|
|
64
|
+
if (aberto) {
|
|
65
|
+
const acima = [];
|
|
66
|
+
for (let i = 0; i < filhos.length; i++) {
|
|
67
|
+
const filho = visitar(filhos[i], nivel + 1, no.id, i + 1, filhos.length);
|
|
68
|
+
acima.push(filho);
|
|
69
|
+
item.childIds.push(filho.id);
|
|
70
|
+
}
|
|
71
|
+
item.x = (acima[0].x + acima[acima.length - 1].x) / 2;
|
|
72
|
+
// Conector: desce do pai até o meio do espaço, corre na horizontal e desce a cada filho.
|
|
73
|
+
const paiCentro = item.x + larg / 2;
|
|
74
|
+
const baseDoPai = item.y + alt;
|
|
75
|
+
const meio = baseDoPai + gapYPx() / 2;
|
|
76
|
+
let d = "M" + paiCentro + " " + baseDoPai + " V" + meio;
|
|
77
|
+
const primeiro = acima[0].x + larg / 2;
|
|
78
|
+
const ultimo = acima[acima.length - 1].x + larg / 2;
|
|
79
|
+
if (acima.length > 1)
|
|
80
|
+
d += " M" + primeiro + " " + meio + " H" + ultimo;
|
|
81
|
+
for (let j = 0; j < acima.length; j++) {
|
|
82
|
+
const cx = acima[j].x + larg / 2;
|
|
83
|
+
d += " M" + cx + " " + meio + " V" + acima[j].y;
|
|
84
|
+
}
|
|
85
|
+
caminhos.push(d);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
item.x = folha * passoX;
|
|
89
|
+
folha = folha + 1;
|
|
90
|
+
}
|
|
91
|
+
return item;
|
|
92
|
+
};
|
|
93
|
+
for (let r = 0; r < raizes.length; r++) {
|
|
94
|
+
visitar(raizes[r], 0, "", r + 1, raizes.length);
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
items: lista,
|
|
98
|
+
paths: caminhos,
|
|
99
|
+
width: Math.max(folha * passoX - gapXPx(), larg),
|
|
100
|
+
height: (maxNivel + 1) * passoY - gapYPx(),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function itemList() {
|
|
104
|
+
return layout().items;
|
|
105
|
+
}
|
|
106
|
+
function toggleList() {
|
|
107
|
+
return itemList().filter((item) => item.hasChildren);
|
|
108
|
+
}
|
|
109
|
+
function pathList() {
|
|
110
|
+
return layout().paths;
|
|
111
|
+
}
|
|
112
|
+
function surfaceStyle() {
|
|
113
|
+
return {
|
|
114
|
+
width: layout().width + "px",
|
|
115
|
+
height: layout().height + "px",
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function hasNodes() {
|
|
119
|
+
return itemList().length > 0;
|
|
120
|
+
}
|
|
121
|
+
function tabId() {
|
|
122
|
+
const lista = itemList();
|
|
123
|
+
for (let i = 0; i < lista.length; i++) {
|
|
124
|
+
if (lista[i].id === focusId)
|
|
125
|
+
return focusId;
|
|
126
|
+
}
|
|
127
|
+
return lista.length ? lista[0].id : "";
|
|
128
|
+
}
|
|
129
|
+
function nodeClasses(item) {
|
|
130
|
+
return [
|
|
131
|
+
"umds-org-chart__node",
|
|
132
|
+
item.level === 0 ? "umds-org-chart__node--root" : "",
|
|
133
|
+
item.id === props.selectedId ? "umds-org-chart__node--selected" : "",
|
|
134
|
+
]
|
|
135
|
+
.filter(Boolean)
|
|
136
|
+
.join(" ");
|
|
137
|
+
}
|
|
138
|
+
function nodeStyle(item) {
|
|
139
|
+
return {
|
|
140
|
+
left: item.x + "px",
|
|
141
|
+
top: item.y + "px",
|
|
142
|
+
width: widthPx() + "px",
|
|
143
|
+
height: heightPx() + "px",
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function toggleStyle(item) {
|
|
147
|
+
return {
|
|
148
|
+
left: item.x + widthPx() / 2 + "px",
|
|
149
|
+
top: item.y + heightPx() + "px",
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function expandedText(item) {
|
|
153
|
+
return item.hasChildren ? (item.expanded ? "true" : "false") : undefined;
|
|
154
|
+
}
|
|
155
|
+
function selectedText(item) {
|
|
156
|
+
return item.id === props.selectedId ? "true" : undefined;
|
|
157
|
+
}
|
|
158
|
+
function toggleGlyph(item) {
|
|
159
|
+
return item.expanded ? "−" : "+";
|
|
160
|
+
}
|
|
161
|
+
function toggleName(item) {
|
|
162
|
+
return item.expanded
|
|
163
|
+
? props.collapseLabel || "Recolher"
|
|
164
|
+
: props.expandLabel || "Expandir";
|
|
165
|
+
}
|
|
166
|
+
function subtitleOf(item) {
|
|
167
|
+
return item.node.subtitle || "";
|
|
168
|
+
}
|
|
169
|
+
function customContent(item) {
|
|
170
|
+
if (props.renderNode)
|
|
171
|
+
return props.renderNode(item.node, {
|
|
172
|
+
level: item.level,
|
|
173
|
+
expanded: item.expanded,
|
|
174
|
+
});
|
|
175
|
+
return "";
|
|
176
|
+
}
|
|
177
|
+
function hasCustomContent() {
|
|
178
|
+
return !!props.renderNode;
|
|
179
|
+
}
|
|
180
|
+
function plainContent() {
|
|
181
|
+
return !props.renderNode;
|
|
182
|
+
}
|
|
183
|
+
function mudarRecolhidos(proximos) {
|
|
184
|
+
setInternalCollapsed(proximos);
|
|
185
|
+
if (props.onCollapsedChange)
|
|
186
|
+
props.onCollapsedChange(proximos);
|
|
187
|
+
}
|
|
188
|
+
function alternar(item) {
|
|
189
|
+
if (!item.hasChildren)
|
|
190
|
+
return;
|
|
191
|
+
const atuais = collapsed();
|
|
192
|
+
mudarRecolhidos(item.expanded
|
|
193
|
+
? atuais.concat([item.id])
|
|
194
|
+
: atuais.filter((id) => id !== item.id));
|
|
195
|
+
}
|
|
196
|
+
function acharItem(id) {
|
|
197
|
+
const lista = itemList();
|
|
198
|
+
for (let i = 0; i < lista.length; i++) {
|
|
199
|
+
if (lista[i].id === id)
|
|
200
|
+
return lista[i];
|
|
201
|
+
}
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
function irPara(id) {
|
|
205
|
+
if (!id)
|
|
206
|
+
return;
|
|
207
|
+
setFocusId(id);
|
|
208
|
+
focoPendenteRef.current = id;
|
|
209
|
+
}
|
|
210
|
+
function focarNo(id) {
|
|
211
|
+
if (!rootRef.current)
|
|
212
|
+
return;
|
|
213
|
+
const alvo = rootRef.current.querySelector('[data-node-id="' + id + '"]');
|
|
214
|
+
if (alvo)
|
|
215
|
+
alvo.focus();
|
|
216
|
+
}
|
|
217
|
+
function handleNodeClick(item) {
|
|
218
|
+
setFocusId(item.id);
|
|
219
|
+
if (props.onNodeClick)
|
|
220
|
+
props.onNodeClick(item.node);
|
|
221
|
+
}
|
|
222
|
+
function handleToggleClick(event, item) {
|
|
223
|
+
if (event && event.stopPropagation)
|
|
224
|
+
event.stopPropagation();
|
|
225
|
+
alternar(item);
|
|
226
|
+
}
|
|
227
|
+
function irmaosDe(item) {
|
|
228
|
+
return itemList().filter((outro) => outro.parentId === item.parentId);
|
|
229
|
+
}
|
|
230
|
+
function handleKeyDown(event, item) {
|
|
231
|
+
if (!event || event.altKey || event.ctrlKey || event.metaKey)
|
|
232
|
+
return;
|
|
233
|
+
if (event.target !== event.currentTarget)
|
|
234
|
+
return;
|
|
235
|
+
const tecla = event.key;
|
|
236
|
+
const irmaos = irmaosDe(item);
|
|
237
|
+
// Por id: o desenho é recalculado a cada leitura, então os objetos mudam e a identidade não vale.
|
|
238
|
+
let indice = -1;
|
|
239
|
+
for (let i = 0; i < irmaos.length; i++) {
|
|
240
|
+
if (irmaos[i].id === item.id)
|
|
241
|
+
indice = i;
|
|
242
|
+
}
|
|
243
|
+
if (tecla === "ArrowLeft" || tecla === "ArrowRight") {
|
|
244
|
+
event.preventDefault();
|
|
245
|
+
const alvo = irmaos[indice + (tecla === "ArrowRight" ? 1 : -1)];
|
|
246
|
+
if (alvo)
|
|
247
|
+
irPara(alvo.id);
|
|
248
|
+
}
|
|
249
|
+
else if (tecla === "Home") {
|
|
250
|
+
event.preventDefault();
|
|
251
|
+
irPara(irmaos[0].id);
|
|
252
|
+
}
|
|
253
|
+
else if (tecla === "End") {
|
|
254
|
+
event.preventDefault();
|
|
255
|
+
irPara(irmaos[irmaos.length - 1].id);
|
|
256
|
+
}
|
|
257
|
+
else if (tecla === "ArrowUp") {
|
|
258
|
+
event.preventDefault();
|
|
259
|
+
if (item.parentId)
|
|
260
|
+
irPara(item.parentId);
|
|
261
|
+
}
|
|
262
|
+
else if (tecla === "ArrowDown") {
|
|
263
|
+
event.preventDefault();
|
|
264
|
+
if (!item.hasChildren)
|
|
265
|
+
return;
|
|
266
|
+
if (!item.expanded) {
|
|
267
|
+
// Recolhido: o primeiro Baixo abre; o foco desce no seguinte.
|
|
268
|
+
alternar(item);
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
irPara(item.childIds[0]);
|
|
272
|
+
}
|
|
273
|
+
else if (tecla === " ") {
|
|
274
|
+
event.preventDefault();
|
|
275
|
+
alternar(item);
|
|
276
|
+
}
|
|
277
|
+
else if (tecla === "Enter") {
|
|
278
|
+
event.preventDefault();
|
|
279
|
+
handleNodeClick(item);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
function handleFocus(event, item) {
|
|
283
|
+
if (event && event.target !== event.currentTarget)
|
|
284
|
+
return;
|
|
285
|
+
if (focusId !== item.id)
|
|
286
|
+
setFocusId(item.id);
|
|
287
|
+
}
|
|
288
|
+
useEffect(() => {
|
|
289
|
+
if (focoPendenteRef.current) {
|
|
290
|
+
const alvo = focoPendenteRef.current;
|
|
291
|
+
focoPendenteRef.current = "";
|
|
292
|
+
focarNo(alvo);
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
return (_jsx("div", { ref: rootRef, className: classes(), children: hasNodes() ? (_jsx("div", { role: "tree", className: "umds-org-chart__scroller", "aria-label": treeName(), children: _jsxs("div", { className: "umds-org-chart__surface", style: surfaceStyle(), children: [_jsx("svg", { "aria-hidden": "true", focusable: "false", className: "umds-org-chart__lines", width: layout().width, height: layout().height, children: pathList()?.map((caminho, posicao) => (_jsx("path", { className: "umds-org-chart__line", d: caminho }, posicao))) }), itemList()?.map((item) => (_jsxs("div", { role: "treeitem", style: nodeStyle(item), "data-node-id": item.id, "aria-level": item.level + 1, "aria-posinset": item.position, "aria-setsize": item.setSize, "aria-expanded": expandedText(item), "aria-selected": selectedText(item), tabIndex: item.id === tabId() ? 0 : -1, onClick: (event) => handleNodeClick(item), onKeyDown: (event) => handleKeyDown(event, item), onFocus: (event) => handleFocus(event, item), className: nodeClasses(item), children: [hasCustomContent() ? (_jsx("div", { className: "umds-org-chart__custom", children: customContent(item) })) : null, plainContent() ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "umds-org-chart__title", title: item.node.title, children: item.node.title }), item.node.subtitle ? (_jsx("span", { className: "umds-org-chart__subtitle", title: subtitleOf(item), children: item.node.subtitle })) : null] })) : null] }, item.id))), toggleList()?.map((item) => (_jsx("button", { type: "button", "aria-hidden": "true", className: "umds-org-chart__toggle", style: toggleStyle(item), tabIndex: -1, title: toggleName(item), onClick: (event) => handleToggleClick(event, item), children: toggleGlyph(item) }, item.id)))] }) })) : null }));
|
|
296
|
+
}
|
|
297
|
+
export default OrgChart;
|