@1doc/1ds-react 2.8.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/CHANGELOG.md +1106 -0
  2. package/dist/components/AILabel/AILabel.js +1 -1
  3. package/dist/components/Accordion/Accordion.d.ts +6 -2
  4. package/dist/components/AttachmentCard/AttachmentCard.css +16 -0
  5. package/dist/components/AttachmentCard/AttachmentCard.d.ts +19 -2
  6. package/dist/components/AttachmentCard/AttachmentCard.js +40 -3
  7. package/dist/components/Avatar/Avatar.css +7 -2
  8. package/dist/components/Avatar/AvatarGroup.d.ts +17 -0
  9. package/dist/components/Avatar/AvatarGroup.js +22 -8
  10. package/dist/components/Badge/Badge.css +54 -2
  11. package/dist/components/Badge/Badge.d.ts +14 -4
  12. package/dist/components/Badge/Badge.js +1 -0
  13. package/dist/components/Box/Box.css +83 -0
  14. package/dist/components/Box/Box.d.ts +82 -2
  15. package/dist/components/Box/Box.js +42 -2
  16. package/dist/components/Button/Button.css +29 -0
  17. package/dist/components/Button/Button.d.ts +4 -4
  18. package/dist/components/Button/Button.js +4 -1
  19. package/dist/components/Calendar/Calendar.css +245 -0
  20. package/dist/components/Calendar/Calendar.d.ts +125 -0
  21. package/dist/components/Calendar/Calendar.js +320 -0
  22. package/dist/components/Chips/Chips.css +38 -0
  23. package/dist/components/Chips/Chips.d.ts +5 -2
  24. package/dist/components/Chips/Chips.js +2 -1
  25. package/dist/components/Coachmark/Coachmark.css +118 -0
  26. package/dist/components/Coachmark/Coachmark.d.ts +75 -0
  27. package/dist/components/Coachmark/Coachmark.js +321 -0
  28. package/dist/components/CodeBlock/CodeBlock.css +96 -0
  29. package/dist/components/CodeBlock/CodeBlock.d.ts +47 -0
  30. package/dist/components/CodeBlock/CodeBlock.js +103 -0
  31. package/dist/components/ColorPicker/ColorPicker.css +133 -0
  32. package/dist/components/ColorPicker/ColorPicker.d.ts +73 -0
  33. package/dist/components/ColorPicker/ColorPicker.js +219 -0
  34. package/dist/components/Combobox/Combobox.css +8 -0
  35. package/dist/components/DataTable/DataTable.css +80 -0
  36. package/dist/components/DataTable/DataTable.d.ts +19 -4
  37. package/dist/components/DataTable/DataTable.js +59 -15
  38. package/dist/components/DatePicker/DatePicker.css +8 -0
  39. package/dist/components/DatePicker/DatePicker.js +10 -1
  40. package/dist/components/DescriptionList/DescriptionList.css +113 -0
  41. package/dist/components/DescriptionList/DescriptionList.d.ts +59 -0
  42. package/dist/components/DescriptionList/DescriptionList.js +51 -0
  43. package/dist/components/FileInput/FileInput.css +16 -0
  44. package/dist/components/FileInput/FileInput.d.ts +4 -2
  45. package/dist/components/FileInput/FileInput.js +8 -2
  46. package/dist/components/Grid/Grid.js +5 -5
  47. package/dist/components/IconPicker/IconPicker.css +107 -0
  48. package/dist/components/IconPicker/IconPicker.d.ts +74 -0
  49. package/dist/components/IconPicker/IconPicker.js +194 -0
  50. package/dist/components/Input/Input.css +38 -0
  51. package/dist/components/Input/Input.d.ts +10 -1
  52. package/dist/components/Input/Input.js +66 -5
  53. package/dist/components/Kanban/Kanban.css +4 -0
  54. package/dist/components/Kbd/Kbd.css +66 -0
  55. package/dist/components/Kbd/Kbd.d.ts +32 -0
  56. package/dist/components/Kbd/Kbd.js +40 -0
  57. package/dist/components/List/List.css +136 -0
  58. package/dist/components/List/List.d.ts +82 -0
  59. package/dist/components/List/List.js +53 -0
  60. package/dist/components/List/ListItem.d.ts +85 -0
  61. package/dist/components/List/ListItem.js +81 -0
  62. package/dist/components/Modal/Modal.css +80 -0
  63. package/dist/components/Modal/Modal.d.ts +33 -6
  64. package/dist/components/Modal/Modal.js +101 -6
  65. package/dist/components/MultiSelect/MultiSelect.css +8 -0
  66. package/dist/components/MultiSelect/MultiSelect.js +10 -1
  67. package/dist/components/OrgChart/OrgChart.css +149 -0
  68. package/dist/components/OrgChart/OrgChart.d.ts +83 -0
  69. package/dist/components/OrgChart/OrgChart.js +297 -0
  70. package/dist/components/OtpInput/OtpInput.css +93 -0
  71. package/dist/components/OtpInput/OtpInput.d.ts +60 -0
  72. package/dist/components/OtpInput/OtpInput.js +215 -0
  73. package/dist/components/PhoneInput/PhoneInput.css +8 -0
  74. package/dist/components/Popover/Popover.d.ts +7 -0
  75. package/dist/components/Popover/Popover.js +11 -1
  76. package/dist/components/RichTextEditor/RichTextEditor.css +203 -0
  77. package/dist/components/RichTextEditor/RichTextEditor.d.ts +83 -0
  78. package/dist/components/RichTextEditor/RichTextEditor.js +494 -0
  79. package/dist/components/SegmentedControl/SegmentedControl.js +7 -2
  80. package/dist/components/Select/Select.css +70 -0
  81. package/dist/components/Select/Select.d.ts +12 -0
  82. package/dist/components/Select/Select.js +59 -4
  83. package/dist/components/Stack/Stack.css +49 -0
  84. package/dist/components/Stack/Stack.d.ts +65 -7
  85. package/dist/components/Stack/Stack.js +30 -2
  86. package/dist/components/StatCard/StatCard.css +73 -0
  87. package/dist/components/StatCard/StatCard.d.ts +17 -0
  88. package/dist/components/StatCard/StatCard.js +4 -1
  89. package/dist/components/Tabs/Tab.d.ts +15 -0
  90. package/dist/components/Tabs/Tab.js +30 -1
  91. package/dist/components/Tabs/Tabs.css +132 -0
  92. package/dist/components/Tabs/Tabs.d.ts +7 -0
  93. package/dist/components/Tabs/Tabs.js +13 -2
  94. package/dist/components/Tag/Tag.css +85 -2
  95. package/dist/components/Tag/Tag.d.ts +13 -6
  96. package/dist/components/Tag/Tag.js +1 -0
  97. package/dist/components/Text/Text.js +2 -2
  98. package/dist/components/Textarea/Textarea.css +8 -0
  99. package/dist/components/TimePicker/TimePicker.css +8 -0
  100. package/dist/components/Tooltip/Tooltip.css +25 -0
  101. package/dist/components/Tooltip/Tooltip.d.ts +11 -0
  102. package/dist/components/Tooltip/Tooltip.js +18 -3
  103. package/dist/index.d.ts +25 -0
  104. package/dist/index.js +14 -0
  105. package/dist/teste/AILabel.test.d.ts +1 -0
  106. package/dist/teste/AILabel.test.js +33 -0
  107. package/dist/teste/AccordionConteudoLivre.test.d.ts +1 -0
  108. package/dist/teste/AccordionConteudoLivre.test.js +29 -0
  109. package/dist/teste/AtributosRepassados.test.d.ts +1 -0
  110. package/dist/teste/AtributosRepassados.test.js +52 -0
  111. package/dist/teste/AttachmentCardIA.test.d.ts +1 -0
  112. package/dist/teste/AttachmentCardIA.test.js +89 -0
  113. package/dist/teste/AvatarGroupOverlap.test.d.ts +1 -0
  114. package/dist/teste/AvatarGroupOverlap.test.js +56 -0
  115. package/dist/teste/BadgeTag.test.d.ts +1 -0
  116. package/dist/teste/BadgeTag.test.js +42 -0
  117. package/dist/teste/BoxItemFlex.test.d.ts +1 -0
  118. package/dist/teste/BoxItemFlex.test.js +54 -0
  119. package/dist/teste/BoxLayout.test.d.ts +1 -0
  120. package/dist/teste/BoxLayout.test.js +35 -0
  121. package/dist/teste/Button.test.d.ts +1 -0
  122. package/dist/teste/Button.test.js +27 -0
  123. package/dist/teste/Calendar.test.d.ts +1 -0
  124. package/dist/teste/Calendar.test.js +221 -0
  125. package/dist/teste/ChipsXs.test.d.ts +1 -0
  126. package/dist/teste/ChipsXs.test.js +31 -0
  127. package/dist/teste/Coachmark.test.d.ts +1 -0
  128. package/dist/teste/Coachmark.test.js +149 -0
  129. package/dist/teste/ColorPicker.test.d.ts +1 -0
  130. package/dist/teste/ColorPicker.test.js +132 -0
  131. package/dist/teste/DataTableCelulaLivre.test.d.ts +1 -0
  132. package/dist/teste/DataTableCelulaLivre.test.js +76 -0
  133. package/dist/teste/DataTableDocumento.test.d.ts +1 -0
  134. package/dist/teste/DataTableDocumento.test.js +92 -0
  135. package/dist/teste/DatePicker.test.js +23 -0
  136. package/dist/teste/FileInputTrigger.test.d.ts +1 -0
  137. package/dist/teste/FileInputTrigger.test.js +53 -0
  138. package/dist/teste/IconPicker.test.d.ts +1 -0
  139. package/dist/teste/IconPicker.test.js +130 -0
  140. package/dist/teste/InputMascaraEAfins.test.d.ts +1 -0
  141. package/dist/teste/InputMascaraEAfins.test.js +99 -0
  142. package/dist/teste/KbdCodeBlock.test.d.ts +1 -0
  143. package/dist/teste/KbdCodeBlock.test.js +95 -0
  144. package/dist/teste/List.test.d.ts +1 -0
  145. package/dist/teste/List.test.js +153 -0
  146. package/dist/teste/ModalVariantes.test.d.ts +1 -0
  147. package/dist/teste/ModalVariantes.test.js +151 -0
  148. package/dist/teste/NomeAcessivelSsr.test.d.ts +1 -0
  149. package/dist/teste/NomeAcessivelSsr.test.js +88 -0
  150. package/dist/teste/OrgChart.test.d.ts +1 -0
  151. package/dist/teste/OrgChart.test.js +162 -0
  152. package/dist/teste/OtpInput.test.d.ts +1 -0
  153. package/dist/teste/OtpInput.test.js +143 -0
  154. package/dist/teste/PopoverMaxHeight.test.d.ts +1 -0
  155. package/dist/teste/PopoverMaxHeight.test.js +38 -0
  156. package/dist/teste/RichTextEditor.test.d.ts +1 -0
  157. package/dist/teste/RichTextEditor.test.js +287 -0
  158. package/dist/teste/SelectPlacementFiltro.test.d.ts +1 -0
  159. package/dist/teste/SelectPlacementFiltro.test.js +88 -0
  160. package/dist/teste/Stack.test.d.ts +1 -0
  161. package/dist/teste/Stack.test.js +57 -0
  162. package/dist/teste/StatCardRotuloTopo.test.d.ts +1 -0
  163. package/dist/teste/StatCardRotuloTopo.test.js +34 -0
  164. package/dist/teste/TabsContadorFechavel.test.d.ts +1 -0
  165. package/dist/teste/TabsContadorFechavel.test.js +79 -0
  166. package/dist/teste/TooltipDark.test.d.ts +1 -0
  167. package/dist/teste/TooltipDark.test.js +31 -0
  168. package/dist/utils/calendario.d.ts +28 -0
  169. package/dist/utils/calendario.js +73 -0
  170. package/dist/utils/html-seguro.d.ts +27 -0
  171. package/dist/utils/html-seguro.js +97 -0
  172. package/dist/utils/paleta-de-cores.d.ts +26 -0
  173. package/dist/utils/paleta-de-cores.js +10 -0
  174. package/dist/utils/texto.d.ts +5 -0
  175. package/dist/utils/texto.js +5 -0
  176. package/package.json +3 -3
  177. package/src/index.ts +26 -0
  178. package/src/teste/AILabel.test.tsx +41 -0
  179. package/src/teste/AccordionConteudoLivre.test.tsx +39 -0
  180. package/src/teste/AtributosRepassados.test.tsx +73 -0
  181. package/src/teste/AttachmentCardIA.test.tsx +126 -0
  182. package/src/teste/AvatarGroupOverlap.test.tsx +74 -0
  183. package/src/teste/BadgeTag.test.tsx +64 -0
  184. package/src/teste/BoxItemFlex.test.tsx +81 -0
  185. package/src/teste/BoxLayout.test.tsx +50 -0
  186. package/src/teste/Button.test.tsx +39 -0
  187. package/src/teste/Calendar.test.tsx +282 -0
  188. package/src/teste/ChipsXs.test.tsx +41 -0
  189. package/src/teste/Coachmark.test.tsx +198 -0
  190. package/src/teste/ColorPicker.test.tsx +153 -0
  191. package/src/teste/DataTableCelulaLivre.test.tsx +103 -0
  192. package/src/teste/DataTableDocumento.test.tsx +102 -0
  193. package/src/teste/DatePicker.test.tsx +38 -0
  194. package/src/teste/FileInputTrigger.test.tsx +89 -0
  195. package/src/teste/IconPicker.test.tsx +145 -0
  196. package/src/teste/InputMascaraEAfins.test.tsx +124 -0
  197. package/src/teste/KbdCodeBlock.test.tsx +106 -0
  198. package/src/teste/List.test.tsx +269 -0
  199. package/src/teste/ModalVariantes.test.tsx +173 -0
  200. package/src/teste/NomeAcessivelSsr.test.tsx +110 -0
  201. package/src/teste/OrgChart.test.tsx +183 -0
  202. package/src/teste/OtpInput.test.tsx +163 -0
  203. package/src/teste/PopoverMaxHeight.test.tsx +47 -0
  204. package/src/teste/RichTextEditor.test.tsx +329 -0
  205. package/src/teste/SelectPlacementFiltro.test.tsx +110 -0
  206. package/src/teste/Stack.test.tsx +80 -0
  207. package/src/teste/StatCardRotuloTopo.test.tsx +44 -0
  208. package/src/teste/TabsContadorFechavel.test.tsx +144 -0
  209. package/src/teste/TooltipDark.test.tsx +51 -0
  210. package/src/utils/calendario.ts +78 -0
  211. package/src/utils/html-seguro.ts +94 -0
  212. package/src/utils/paleta-de-cores.ts +34 -0
  213. package/src/utils/texto.ts +5 -0
@@ -12,6 +12,7 @@ function Modal(props) {
12
12
  const escCleanupRef = useRef(null);
13
13
  const closeFnRef = useRef(null);
14
14
  const previousFocusRef = useRef(null);
15
+ const mediaCleanupRef = useRef(null);
15
16
  const [lastOpen, setLastOpen] = useState(() => false);
16
17
  const [uid, setUid] = useState(() => "umds-modal-" + Math.random().toString(36).slice(2, 9));
17
18
  function titleId() {
@@ -32,18 +33,83 @@ function Modal(props) {
32
33
  return props.description ? uid + "-description" : undefined;
33
34
  }
34
35
  function ehFeedback() {
35
- const temVariante = props.variant ? props.variant !== "default" : false;
36
+ // `primary` é só o cabeçalho cheio do modal base: não é feedback.
37
+ const temVariante = props.variant
38
+ ? props.variant !== "default" && props.variant !== "primary"
39
+ : false;
36
40
  return temVariante || props.layout === "dialog";
37
41
  }
38
42
  const [modoAtual, setModoAtual] = useState(() => "normal");
43
+ const [isCompact, setIsCompact] = useState(() => false);
44
+ function ehSheet() {
45
+ return !!props.responsive && isCompact;
46
+ }
47
+ function temNormal() {
48
+ if (props.responsive && isCompact)
49
+ return false;
50
+ if (props.windowControls === true)
51
+ return true;
52
+ return (Array.isArray(props.windowControls) &&
53
+ props.windowControls.includes("normal"));
54
+ }
55
+ function temExpandir() {
56
+ if (props.responsive && isCompact)
57
+ return false;
58
+ if (props.windowControls === true)
59
+ return true;
60
+ return (Array.isArray(props.windowControls) &&
61
+ props.windowControls.includes("expand"));
62
+ }
63
+ function temTelaCheia() {
64
+ if (props.responsive && isCompact)
65
+ return false;
66
+ if (props.windowControls === true)
67
+ return true;
68
+ return (Array.isArray(props.windowControls) &&
69
+ props.windowControls.includes("fullscreen"));
70
+ }
71
+ function temMinimizar() {
72
+ if (props.responsive && isCompact)
73
+ return false;
74
+ if (props.windowControls === true)
75
+ return true;
76
+ return (Array.isArray(props.windowControls) &&
77
+ props.windowControls.includes("minimize"));
78
+ }
79
+ function temControles() {
80
+ if (props.responsive && isCompact)
81
+ return false;
82
+ if (props.windowControls === true)
83
+ return true;
84
+ return (Array.isArray(props.windowControls) && props.windowControls.length > 0);
85
+ }
86
+ function janelaPorLista() {
87
+ return Array.isArray(props.windowControls);
88
+ }
89
+ function estiloDoDialogo() {
90
+ if (!props.width && !props.maxWidth)
91
+ return undefined;
92
+ if (props.responsive && isCompact)
93
+ return undefined;
94
+ if (props.windowControls && modoAtual !== "normal")
95
+ return undefined;
96
+ const estilo = {};
97
+ if (props.width)
98
+ estilo.width = props.width;
99
+ if (props.maxWidth)
100
+ estilo.maxWidth = props.maxWidth;
101
+ else
102
+ estilo.maxWidth = "100%";
103
+ return estilo;
104
+ }
39
105
  function irParaNormal() {
40
106
  setModoAtual("normal");
41
107
  }
42
108
  function irParaExpandido() {
43
- setModoAtual("expanded");
109
+ setModoAtual(modoAtual === "expanded" && !temNormal() ? "normal" : "expanded");
44
110
  }
45
111
  function irParaTelaCheia() {
46
- setModoAtual("fullscreen");
112
+ setModoAtual(modoAtual === "fullscreen" && !temNormal() ? "normal" : "fullscreen");
47
113
  }
48
114
  function classeDoControle(modo) {
49
115
  return modo === modoAtual
@@ -53,6 +119,12 @@ function Modal(props) {
53
119
  function classeDaJanela() {
54
120
  if (!props.windowControls)
55
121
  return "";
122
+ if (props.responsive && isCompact)
123
+ return "";
124
+ // Lista de controles: o normal é o tamanho do próprio modal.
125
+ if (Array.isArray(props.windowControls) && modoAtual === "normal") {
126
+ return "";
127
+ }
56
128
  return `umds-modal--janela-${modoAtual}`;
57
129
  }
58
130
  function temRodape() {
@@ -66,6 +138,7 @@ function Modal(props) {
66
138
  props.inline ? "umds-modal-root--inline" : "umds-modal-root",
67
139
  props.open ? "umds-modal-root--open" : "umds-modal-root--closed",
68
140
  props.size === "fullscreen" ? "umds-modal-root--fullscreen" : "",
141
+ props.responsive && isCompact ? "umds-modal-root--sheet" : "",
69
142
  ]
70
143
  .filter(Boolean)
71
144
  .join(" ");
@@ -77,6 +150,7 @@ function Modal(props) {
77
150
  props.size && props.size !== "md" ? `umds-modal--${props.size}` : "",
78
151
  ehFeedback() ? "umds-modal--feedback" : "umds-modal--base",
79
152
  classeDaJanela(),
153
+ props.responsive && isCompact ? "umds-modal--sheet" : "",
80
154
  props.className,
81
155
  ]
82
156
  .filter(Boolean)
@@ -108,6 +182,10 @@ function Modal(props) {
108
182
  function handleEscClose(event) {
109
183
  if (props.closeOnEsc === false)
110
184
  return;
185
+ // Quem já usou o Esc (Select, DatePicker, Popover aberto dentro do
186
+ // modal) chamou preventDefault: a tecla é dele, o modal não fecha.
187
+ if (event && event.defaultPrevented)
188
+ return;
111
189
  if (!isTopOverlay(uid))
112
190
  return;
113
191
  handleClose(event);
@@ -173,10 +251,23 @@ function Modal(props) {
173
251
  closeFnRef.current(event);
174
252
  }
175
253
  };
176
- document.addEventListener("keydown", watcher, true);
254
+ // No borbulho (false), não na captura: o ouvinte do document só vê a tecla
255
+ // depois que o componente aberto dentro do modal teve a vez de consumi-la.
256
+ document.addEventListener("keydown", watcher, false);
177
257
  escCleanupRef.current = () => {
178
- document.removeEventListener("keydown", watcher, true);
258
+ document.removeEventListener("keydown", watcher, false);
179
259
  };
260
+ if (typeof window !== "undefined" && window.matchMedia) {
261
+ const consulta = window.matchMedia("(max-width: " + (props.responsiveBreakpoint || 640) + "px)");
262
+ const aoMudar = (e) => {
263
+ setIsCompact(!!e.matches);
264
+ };
265
+ setIsCompact(!!consulta.matches);
266
+ consulta.addEventListener("change", aoMudar);
267
+ mediaCleanupRef.current = () => {
268
+ consulta.removeEventListener("change", aoMudar);
269
+ };
270
+ }
180
271
  syncOpenState();
181
272
  }, []);
182
273
  useEffect(() => {
@@ -190,9 +281,13 @@ function Modal(props) {
190
281
  escCleanupRef.current();
191
282
  escCleanupRef.current = null;
192
283
  }
284
+ if (mediaCleanupRef.current) {
285
+ mediaCleanupRef.current();
286
+ mediaCleanupRef.current = null;
287
+ }
193
288
  removeOverlay(uid);
194
289
  };
195
290
  }, []);
196
- return (_jsx(_Fragment, { children: props.open ? (_jsx(_Fragment, { children: _jsxs("div", { className: rootClasses(), children: [_jsx("div", { className: "umds-modal-overlay", onClick: (e) => handleOverlayClick(e) }), _jsxs("div", { role: "dialog", "aria-modal": "true", ref: dialogRef, "aria-label": nomeAcessivel(), "aria-labelledby": labelledBy(), "aria-describedby": describedBy(), tabIndex: -1, onKeyDown: (event) => handleTrapKeydown(event), className: modalClasses(), children: [!ehFeedback() ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "umds-modal__header", children: [_jsxs("div", { className: "umds-modal__text-group", children: [props.title ? (_jsx("span", { className: "umds-modal__title", id: titleId(), children: props.title })) : null, props.description ? (_jsx("span", { className: "umds-modal__subtitle", id: descriptionId(), children: props.description })) : null] }), _jsxs("div", { className: "umds-modal__header-actions", children: [props.windowControls ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", title: props.normalModeLabel || "Modo normal", "aria-label": props.normalModeLabel || "Modo normal", "aria-pressed": modoAtual === "normal", onClick: (event) => irParaNormal(), className: classeDoControle("normal"), children: _jsx(Icon, { customSize: "14px", icon: faWindowRestore }) }), _jsx("button", { type: "button", title: props.expandLabel || "Expandir", "aria-label": props.expandLabel || "Expandir", "aria-pressed": modoAtual === "expanded", onClick: (event) => irParaExpandido(), className: classeDoControle("expanded"), children: _jsx(Icon, { customSize: "14px", icon: faUpRightAndDownLeftFromCenter }) }), _jsx("button", { type: "button", title: props.fullscreenLabel || "Tela cheia", "aria-label": props.fullscreenLabel || "Tela cheia", "aria-pressed": modoAtual === "fullscreen", onClick: (event) => irParaTelaCheia(), className: classeDoControle("fullscreen"), children: _jsx(Icon, { customSize: "14px", icon: faExpand }) }), _jsx("button", { type: "button", className: "umds-modal__ctrl", title: props.minimizeLabel || "Minimizar", "aria-label": props.minimizeLabel || "Minimizar", onClick: (e) => props.onMinimize?.(e), children: _jsx(Icon, { customSize: "14px", icon: faMinus }) }), _jsx("span", { className: "umds-modal__ctrl-divider" })] })) : null, !props.hideCloseButton ? (_jsx("button", { type: "button", className: "umds-modal__ctrl umds-modal__ctrl--close", onClick: (e) => handleClose(e), title: props.closeLabel || "Fechar", "aria-label": props.closeLabel || "Fechar", children: _jsx(Icon, { customSize: "16px", icon: faXmark }) })) : null] })] }), _jsx("div", { className: "umds-modal__body", children: _jsx(_Fragment, { children: props.children }) }), temRodape() ? (_jsxs("div", { className: "umds-modal__footer", children: [_jsx("div", { className: "umds-modal__footer-start", children: props.footerStart ? _jsx(_Fragment, { children: props.footerStart }) : null }), _jsxs("div", { className: "umds-modal__footer-end", children: [props.footerSlot ? _jsx(_Fragment, { children: props.footerSlot }) : null, !props.footerSlot ? (_jsxs(_Fragment, { children: [props.cancelLabel ? (_jsx(Button, { variant: "text", onClick: (e) => props.onCancel?.(e), children: props.cancelLabel })) : null, props.confirmLabel ? (_jsx(Button, { variant: "primary", onClick: (e) => props.onConfirm?.(e), children: props.confirmLabel })) : null] })) : null] })] })) : null] })) : null, ehFeedback() ? (_jsxs(_Fragment, { children: [!props.hideCloseButton ? (_jsx("div", { className: "umds-modal__close-wrapper", children: _jsx("button", { className: "umds-modal__close-button", onClick: (e) => handleClose(e), "aria-label": props.closeLabel || "Fechar", children: _jsx(Icon, { size: "sm", icon: faXmark }) }) })) : null, _jsxs("div", { className: "umds-modal__content", children: [_jsxs("div", { className: "umds-modal__header umds-modal__header--feedback", children: [props.variant && props.variant !== "default" ? (_jsx("div", { className: `umds-modal__icon ${iconVariantClass()}`, children: _jsx(Icon, { customSize: "40px", icon: iconName() }) })) : null, _jsxs("div", { className: "umds-modal__text-group", children: [props.title ? (_jsx(Text, { variant: "h5", weight: "bold", id: titleId(), children: props.title })) : null, props.description ? (_jsx(Text, { variant: "body2", color: "secondary", id: descriptionId(), children: props.description })) : null] })] }), _jsx(_Fragment, { children: props.children }), _jsxs("div", { className: "umds-modal__footer umds-modal__footer--feedback", children: [props.footerSlot ? _jsx(_Fragment, { children: props.footerSlot }) : null, !props.footerSlot ? (_jsxs(_Fragment, { children: [props.cancelLabel ? (_jsx(Button, { variant: "text", onClick: (e) => props.onCancel?.(e), children: props.cancelLabel })) : null, props.confirmLabel ? (_jsx(Button, { variant: "primary", onClick: (e) => props.onConfirm?.(e), children: props.confirmLabel })) : null] })) : null] })] })] })) : null] })] }) })) : null }));
291
+ return (_jsx(_Fragment, { children: props.open ? (_jsx(_Fragment, { children: _jsxs("div", { className: rootClasses(), children: [_jsx("div", { className: "umds-modal-overlay", onClick: (e) => handleOverlayClick(e) }), _jsxs("div", { role: "dialog", "aria-modal": "true", ref: dialogRef, "aria-label": nomeAcessivel(), "aria-labelledby": labelledBy(), "aria-describedby": describedBy(), tabIndex: -1, style: estiloDoDialogo(), onKeyDown: (event) => handleTrapKeydown(event), className: modalClasses(), children: [!ehFeedback() ? (_jsxs(_Fragment, { children: [ehSheet() ? (_jsx("div", { "aria-hidden": "true", className: "umds-modal__grabber", children: _jsx("span", { className: "umds-modal__grabber-bar" }) })) : null, _jsxs("div", { className: "umds-modal__header", children: [_jsxs("div", { className: "umds-modal__text-group", children: [props.title ? (_jsx("span", { className: "umds-modal__title", id: titleId(), children: props.title })) : null, props.description ? (_jsx("span", { className: "umds-modal__subtitle", id: descriptionId(), children: props.description })) : null] }), _jsxs("div", { className: "umds-modal__header-actions", children: [temNormal() ? (_jsx("button", { type: "button", title: props.normalModeLabel || "Modo normal", "aria-label": props.normalModeLabel || "Modo normal", "aria-pressed": modoAtual === "normal", onClick: (event) => irParaNormal(), className: classeDoControle("normal"), children: _jsx(Icon, { customSize: "14px", icon: faWindowRestore }) })) : null, temExpandir() ? (_jsx("button", { type: "button", title: props.expandLabel || "Expandir", "aria-label": props.expandLabel || "Expandir", "aria-pressed": modoAtual === "expanded", onClick: (event) => irParaExpandido(), className: classeDoControle("expanded"), children: _jsx(Icon, { customSize: "14px", icon: faUpRightAndDownLeftFromCenter }) })) : null, temTelaCheia() ? (_jsx("button", { type: "button", title: props.fullscreenLabel || "Tela cheia", "aria-label": props.fullscreenLabel || "Tela cheia", "aria-pressed": modoAtual === "fullscreen", onClick: (event) => irParaTelaCheia(), className: classeDoControle("fullscreen"), children: _jsx(Icon, { customSize: "14px", icon: faExpand }) })) : null, temMinimizar() ? (_jsx("button", { type: "button", className: "umds-modal__ctrl", title: props.minimizeLabel || "Minimizar", "aria-label": props.minimizeLabel || "Minimizar", onClick: (e) => props.onMinimize?.(e), children: _jsx(Icon, { customSize: "14px", icon: faMinus }) })) : null, temControles() && !props.hideCloseButton ? (_jsx("span", { className: "umds-modal__ctrl-divider" })) : null, !props.hideCloseButton ? (_jsx("button", { type: "button", className: "umds-modal__ctrl umds-modal__ctrl--close", onClick: (e) => handleClose(e), title: props.closeLabel || "Fechar", "aria-label": props.closeLabel || "Fechar", children: _jsx(Icon, { customSize: "16px", icon: faXmark }) })) : null] })] }), _jsx("div", { className: "umds-modal__body", children: _jsx(_Fragment, { children: props.children }) }), temRodape() ? (_jsxs("div", { className: "umds-modal__footer", children: [_jsx("div", { className: "umds-modal__footer-start", children: props.footerStart ? _jsx(_Fragment, { children: props.footerStart }) : null }), _jsxs("div", { className: "umds-modal__footer-end", children: [props.footerSlot ? _jsx(_Fragment, { children: props.footerSlot }) : null, !props.footerSlot ? (_jsxs(_Fragment, { children: [props.cancelLabel ? (_jsx(Button, { variant: "text", onClick: (e) => props.onCancel?.(e), children: props.cancelLabel })) : null, props.confirmLabel ? (_jsx(Button, { variant: "primary", onClick: (e) => props.onConfirm?.(e), children: props.confirmLabel })) : null] })) : null] })] })) : null] })) : null, ehFeedback() ? (_jsxs(_Fragment, { children: [!props.hideCloseButton ? (_jsx("div", { className: "umds-modal__close-wrapper", children: _jsx("button", { className: "umds-modal__close-button", onClick: (e) => handleClose(e), "aria-label": props.closeLabel || "Fechar", children: _jsx(Icon, { size: "sm", icon: faXmark }) }) })) : null, _jsxs("div", { className: "umds-modal__content", children: [_jsxs("div", { className: "umds-modal__header umds-modal__header--feedback", children: [props.variant && props.variant !== "default" ? (_jsx("div", { className: `umds-modal__icon ${iconVariantClass()}`, children: _jsx(Icon, { customSize: "40px", icon: iconName() }) })) : null, _jsxs("div", { className: "umds-modal__text-group", children: [props.title ? (_jsx(Text, { variant: "h5", weight: "bold", id: titleId(), children: props.title })) : null, props.description ? (_jsx(Text, { variant: "body2", color: "secondary", id: descriptionId(), children: props.description })) : null] })] }), _jsx(_Fragment, { children: props.children }), _jsxs("div", { className: "umds-modal__footer umds-modal__footer--feedback", children: [props.footerSlot ? _jsx(_Fragment, { children: props.footerSlot }) : null, !props.footerSlot ? (_jsxs(_Fragment, { children: [props.cancelLabel ? (_jsx(Button, { variant: "text", onClick: (e) => props.onCancel?.(e), children: props.cancelLabel })) : null, props.confirmLabel ? (_jsx(Button, { variant: "primary", onClick: (e) => props.onConfirm?.(e), children: props.confirmLabel })) : null] })) : null] })] })] })) : null] })] }) })) : null }));
197
292
  }
198
293
  export default Modal;
@@ -378,6 +378,14 @@
378
378
  border-color: var(--umds-semantic-field-border-default);
379
379
  }
380
380
 
381
+ /* Somente leitura não é desabilitado: o texto segue lido e a WCAG 1.4.3 vale
382
+ sem isenção. O placeholder padrão foi calibrado para fundo branco e cai para
383
+ ~4,2:1 sobre o fundo de somente leitura; neutral-dark-down passa 4,5:1 em
384
+ todos os temas (1doc 6,78:1 · 1doc-dark 10,83:1 · alto contraste 16,48:1). */
385
+ .umds-multiselect--readonly .umds-multiselect__placeholder {
386
+ color: var(--umds-semantic-color-neutral-dark-down);
387
+ }
388
+
381
389
  /* O campo de busca precisa de indicador de foco — o painel foca ele ao abrir.
382
390
  Um outline no <input> desenhava um retângulo azul solto no meio do painel,
383
391
  porque o input não tem borda própria para o anel acompanhar.
@@ -56,6 +56,12 @@ function MultiSelect(props) {
56
56
  function labelIdText() {
57
57
  return baseId() ? baseId() + "-label" : undefined;
58
58
  }
59
+ function comboboxLabelledBy() {
60
+ return props.label && baseId() ? labelIdText() : undefined;
61
+ }
62
+ function comboboxAriaLabel() {
63
+ return props.label && !baseId() ? props.label : undefined;
64
+ }
59
65
  function errorIdText() {
60
66
  return baseId() ? baseId() + "-error" : undefined;
61
67
  }
@@ -162,6 +168,8 @@ function MultiSelect(props) {
162
168
  toggle();
163
169
  }
164
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();
165
173
  setIsOpen(false);
166
174
  setSearchTerm("");
167
175
  }
@@ -177,6 +185,7 @@ function MultiSelect(props) {
177
185
  }
178
186
  function handleSearchKeyDown(event) {
179
187
  if (event.key === "Escape") {
188
+ event.preventDefault();
180
189
  setIsOpen(false);
181
190
  setSearchTerm("");
182
191
  setActiveIndex(-1);
@@ -285,6 +294,6 @@ function MultiSelect(props) {
285
294
  }
286
295
  };
287
296
  }, []);
288
- 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": props.label ? labelIdText() : undefined, "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] }));
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] }));
289
298
  }
290
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;