@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.
Files changed (302) hide show
  1. package/CHANGELOG.md +1280 -0
  2. package/dist/components/AIContent/AIContent.d.ts +10 -0
  3. package/dist/components/AIContent/AIContent.js +1 -1
  4. package/dist/components/AILabel/AILabel.d.ts +4 -0
  5. package/dist/components/AILabel/AILabel.js +2 -2
  6. package/dist/components/Accordion/Accordion.d.ts +6 -2
  7. package/dist/components/Alert/Alert.css +2 -0
  8. package/dist/components/Alert/Alert.d.ts +3 -1
  9. package/dist/components/Alert/Alert.js +7 -1
  10. package/dist/components/AppHeader/AppHeader.css +82 -8
  11. package/dist/components/AppHeader/AppHeader.d.ts +12 -1
  12. package/dist/components/AppHeader/AppHeader.js +186 -1
  13. package/dist/components/AppNavItem/AppNavItem.css +11 -3
  14. package/dist/components/AppShell/AppShell.css +9 -0
  15. package/dist/components/AppShell/AppShell.d.ts +8 -0
  16. package/dist/components/AppShell/AppShell.js +4 -1
  17. package/dist/components/AppSidebar/AppSidebar.css +1 -1
  18. package/dist/components/AppSidebar/AppSidebar.d.ts +4 -0
  19. package/dist/components/AppSidebar/AppSidebar.js +3 -1
  20. package/dist/components/AttachmentCard/AttachmentCard.css +17 -1
  21. package/dist/components/AttachmentCard/AttachmentCard.d.ts +29 -2
  22. package/dist/components/AttachmentCard/AttachmentCard.js +88 -20
  23. package/dist/components/Avatar/Avatar.css +7 -2
  24. package/dist/components/Avatar/AvatarGroup.d.ts +27 -0
  25. package/dist/components/Avatar/AvatarGroup.js +28 -4
  26. package/dist/components/Badge/Badge.css +61 -3
  27. package/dist/components/Badge/Badge.d.ts +14 -4
  28. package/dist/components/Badge/Badge.js +1 -0
  29. package/dist/components/BottomSheet/BottomSheet.css +1 -0
  30. package/dist/components/BottomSheet/BottomSheet.d.ts +8 -0
  31. package/dist/components/BottomSheet/BottomSheet.js +14 -2
  32. package/dist/components/Box/Box.css +83 -0
  33. package/dist/components/Box/Box.d.ts +82 -2
  34. package/dist/components/Box/Box.js +42 -2
  35. package/dist/components/Button/Button.css +29 -0
  36. package/dist/components/Button/Button.d.ts +4 -4
  37. package/dist/components/Button/Button.js +4 -1
  38. package/dist/components/Calendar/Calendar.css +245 -0
  39. package/dist/components/Calendar/Calendar.d.ts +125 -0
  40. package/dist/components/Calendar/Calendar.js +320 -0
  41. package/dist/components/Chart/BarChart.d.ts +6 -0
  42. package/dist/components/Chart/BarChart.js +3 -1
  43. package/dist/components/Chart/LineChart.d.ts +6 -0
  44. package/dist/components/Chart/LineChart.js +3 -1
  45. package/dist/components/Checkbox/Checkbox.css +4 -1
  46. package/dist/components/Chips/Chips.css +39 -0
  47. package/dist/components/Chips/Chips.d.ts +7 -2
  48. package/dist/components/Chips/Chips.js +6 -2
  49. package/dist/components/Coachmark/Coachmark.css +118 -0
  50. package/dist/components/Coachmark/Coachmark.d.ts +75 -0
  51. package/dist/components/Coachmark/Coachmark.js +321 -0
  52. package/dist/components/CodeBlock/CodeBlock.css +96 -0
  53. package/dist/components/CodeBlock/CodeBlock.d.ts +47 -0
  54. package/dist/components/CodeBlock/CodeBlock.js +103 -0
  55. package/dist/components/ColorPicker/ColorPicker.css +133 -0
  56. package/dist/components/ColorPicker/ColorPicker.d.ts +73 -0
  57. package/dist/components/ColorPicker/ColorPicker.js +219 -0
  58. package/dist/components/Combobox/Combobox.css +11 -3
  59. package/dist/components/ConfirmAIAction/ConfirmAIAction.d.ts +11 -1
  60. package/dist/components/ConfirmAIAction/ConfirmAIAction.js +6 -1
  61. package/dist/components/ConfirmDialog/ConfirmDialog.css +3 -0
  62. package/dist/components/ConfirmDialog/ConfirmDialog.d.ts +14 -0
  63. package/dist/components/ConfirmDialog/ConfirmDialog.js +2 -2
  64. package/dist/components/DataTable/DataTable.css +80 -0
  65. package/dist/components/DataTable/DataTable.d.ts +23 -4
  66. package/dist/components/DataTable/DataTable.js +61 -15
  67. package/dist/components/DatePicker/DatePicker.css +8 -0
  68. package/dist/components/DatePicker/DatePicker.d.ts +4 -0
  69. package/dist/components/DatePicker/DatePicker.js +14 -1
  70. package/dist/components/DescriptionList/DescriptionList.css +113 -0
  71. package/dist/components/DescriptionList/DescriptionList.d.ts +59 -0
  72. package/dist/components/DescriptionList/DescriptionList.js +51 -0
  73. package/dist/components/Drawer/Drawer.css +1 -0
  74. package/dist/components/Dropdown/Dropdown.js +47 -29
  75. package/dist/components/FileInput/FileInput.css +24 -4
  76. package/dist/components/FileInput/FileInput.d.ts +22 -2
  77. package/dist/components/FileInput/FileInput.js +23 -2
  78. package/dist/components/Grid/Grid.js +5 -5
  79. package/dist/components/IconPicker/IconPicker.css +107 -0
  80. package/dist/components/IconPicker/IconPicker.d.ts +74 -0
  81. package/dist/components/IconPicker/IconPicker.js +194 -0
  82. package/dist/components/Input/Input.css +41 -3
  83. package/dist/components/Input/Input.d.ts +14 -1
  84. package/dist/components/Input/Input.js +72 -6
  85. package/dist/components/Kanban/Kanban.css +5 -0
  86. package/dist/components/Kanban/Kanban.d.ts +41 -0
  87. package/dist/components/Kanban/Kanban.js +59 -27
  88. package/dist/components/Kanban/KanbanCard.d.ts +2 -0
  89. package/dist/components/Kanban/KanbanCard.js +1 -1
  90. package/dist/components/Kanban/KanbanColumn.d.ts +2 -0
  91. package/dist/components/Kanban/KanbanColumn.js +3 -0
  92. package/dist/components/Kbd/Kbd.css +66 -0
  93. package/dist/components/Kbd/Kbd.d.ts +32 -0
  94. package/dist/components/Kbd/Kbd.js +40 -0
  95. package/dist/components/Link/Link.css +1 -1
  96. package/dist/components/List/List.css +136 -0
  97. package/dist/components/List/List.d.ts +82 -0
  98. package/dist/components/List/List.js +53 -0
  99. package/dist/components/List/ListItem.d.ts +85 -0
  100. package/dist/components/List/ListItem.js +81 -0
  101. package/dist/components/Modal/Modal.css +93 -8
  102. package/dist/components/Modal/Modal.d.ts +45 -7
  103. package/dist/components/Modal/Modal.js +106 -6
  104. package/dist/components/MultiSelect/MultiSelect.css +9 -1
  105. package/dist/components/MultiSelect/MultiSelect.js +45 -8
  106. package/dist/components/OrgChart/OrgChart.css +149 -0
  107. package/dist/components/OrgChart/OrgChart.d.ts +83 -0
  108. package/dist/components/OrgChart/OrgChart.js +297 -0
  109. package/dist/components/OtpInput/OtpInput.css +93 -0
  110. package/dist/components/OtpInput/OtpInput.d.ts +60 -0
  111. package/dist/components/OtpInput/OtpInput.js +215 -0
  112. package/dist/components/Pagination/Pagination.d.ts +6 -0
  113. package/dist/components/Pagination/Pagination.js +9 -1
  114. package/dist/components/PhoneInput/PhoneInput.css +9 -1
  115. package/dist/components/PhoneInput/PhoneInput.d.ts +10 -0
  116. package/dist/components/PhoneInput/PhoneInput.js +20 -3
  117. package/dist/components/Popover/Popover.d.ts +7 -0
  118. package/dist/components/Popover/Popover.js +11 -1
  119. package/dist/components/RichTextEditor/RichTextEditor.css +203 -0
  120. package/dist/components/RichTextEditor/RichTextEditor.d.ts +83 -0
  121. package/dist/components/RichTextEditor/RichTextEditor.js +494 -0
  122. package/dist/components/SegmentedControl/SegmentedControl.d.ts +2 -0
  123. package/dist/components/SegmentedControl/SegmentedControl.js +21 -8
  124. package/dist/components/Select/Select.css +71 -1
  125. package/dist/components/Select/Select.d.ts +12 -0
  126. package/dist/components/Select/Select.js +93 -10
  127. package/dist/components/SidePanel/SidePanel.css +4 -4
  128. package/dist/components/SidePanelItem/SidePanelItem.css +7 -5
  129. package/dist/components/SidePanelSearch/SidePanelSearch.css +2 -2
  130. package/dist/components/SidePanelSection/SidePanelSection.css +7 -5
  131. package/dist/components/Stack/Stack.css +49 -0
  132. package/dist/components/Stack/Stack.d.ts +65 -7
  133. package/dist/components/Stack/Stack.js +30 -2
  134. package/dist/components/StatCard/StatCard.css +73 -0
  135. package/dist/components/StatCard/StatCard.d.ts +17 -0
  136. package/dist/components/StatCard/StatCard.js +4 -1
  137. package/dist/components/Stepper/Stepper.css +4 -1
  138. package/dist/components/Stepper/Stepper.d.ts +8 -0
  139. package/dist/components/Stepper/Stepper.js +4 -4
  140. package/dist/components/Switch/Switch.css +1 -0
  141. package/dist/components/Tabs/Tab.d.ts +15 -0
  142. package/dist/components/Tabs/Tab.js +30 -1
  143. package/dist/components/Tabs/Tabs.css +132 -0
  144. package/dist/components/Tabs/Tabs.d.ts +7 -0
  145. package/dist/components/Tabs/Tabs.js +13 -2
  146. package/dist/components/Tag/Tag.css +85 -2
  147. package/dist/components/Tag/Tag.d.ts +13 -6
  148. package/dist/components/Tag/Tag.js +1 -0
  149. package/dist/components/Text/Text.d.ts +9 -1
  150. package/dist/components/Text/Text.js +2 -2
  151. package/dist/components/Textarea/Textarea.css +11 -3
  152. package/dist/components/TimePicker/TimePicker.css +8 -0
  153. package/dist/components/TimePicker/TimePicker.d.ts +6 -0
  154. package/dist/components/TimePicker/TimePicker.js +1 -1
  155. package/dist/components/Tooltip/Tooltip.css +40 -0
  156. package/dist/components/Tooltip/Tooltip.d.ts +11 -0
  157. package/dist/components/Tooltip/Tooltip.js +114 -11
  158. package/dist/index.d.ts +25 -0
  159. package/dist/index.js +14 -0
  160. package/dist/teste/AILabel.test.d.ts +1 -0
  161. package/dist/teste/AILabel.test.js +33 -0
  162. package/dist/teste/AccordionConteudoLivre.test.d.ts +1 -0
  163. package/dist/teste/AccordionConteudoLivre.test.js +29 -0
  164. package/dist/teste/Alert.test.d.ts +1 -0
  165. package/dist/teste/Alert.test.js +27 -0
  166. package/dist/teste/AtributosRepassados.test.d.ts +1 -0
  167. package/dist/teste/AtributosRepassados.test.js +52 -0
  168. package/dist/teste/AttachmentCardIA.test.d.ts +1 -0
  169. package/dist/teste/AttachmentCardIA.test.js +89 -0
  170. package/dist/teste/AvatarGroupOverlap.test.d.ts +1 -0
  171. package/dist/teste/AvatarGroupOverlap.test.js +56 -0
  172. package/dist/teste/BadgeTag.test.d.ts +1 -0
  173. package/dist/teste/BadgeTag.test.js +42 -0
  174. package/dist/teste/BottomSheet.test.d.ts +1 -0
  175. package/dist/teste/BottomSheet.test.js +23 -0
  176. package/dist/teste/BoxItemFlex.test.d.ts +1 -0
  177. package/dist/teste/BoxItemFlex.test.js +54 -0
  178. package/dist/teste/BoxLayout.test.d.ts +1 -0
  179. package/dist/teste/BoxLayout.test.js +35 -0
  180. package/dist/teste/Button.test.d.ts +1 -0
  181. package/dist/teste/Button.test.js +27 -0
  182. package/dist/teste/Calendar.test.d.ts +1 -0
  183. package/dist/teste/Calendar.test.js +221 -0
  184. package/dist/teste/ChipsXs.test.d.ts +1 -0
  185. package/dist/teste/ChipsXs.test.js +31 -0
  186. package/dist/teste/Coachmark.test.d.ts +1 -0
  187. package/dist/teste/Coachmark.test.js +149 -0
  188. package/dist/teste/ColorPicker.test.d.ts +1 -0
  189. package/dist/teste/ColorPicker.test.js +132 -0
  190. package/dist/teste/ConfirmAIAction.test.d.ts +1 -0
  191. package/dist/teste/ConfirmAIAction.test.js +33 -0
  192. package/dist/teste/DataTableCelulaLivre.test.d.ts +1 -0
  193. package/dist/teste/DataTableCelulaLivre.test.js +76 -0
  194. package/dist/teste/DataTableDocumento.test.d.ts +1 -0
  195. package/dist/teste/DataTableDocumento.test.js +92 -0
  196. package/dist/teste/DatePicker.test.js +23 -0
  197. package/dist/teste/Dropdown.test.js +111 -0
  198. package/dist/teste/FileInputTrigger.test.d.ts +1 -0
  199. package/dist/teste/FileInputTrigger.test.js +53 -0
  200. package/dist/teste/IconPicker.test.d.ts +1 -0
  201. package/dist/teste/IconPicker.test.js +130 -0
  202. package/dist/teste/InputMascaraEAfins.test.d.ts +1 -0
  203. package/dist/teste/InputMascaraEAfins.test.js +99 -0
  204. package/dist/teste/KbdCodeBlock.test.d.ts +1 -0
  205. package/dist/teste/KbdCodeBlock.test.js +95 -0
  206. package/dist/teste/List.test.d.ts +1 -0
  207. package/dist/teste/List.test.js +153 -0
  208. package/dist/teste/Modal.test.d.ts +1 -0
  209. package/dist/teste/Modal.test.js +26 -0
  210. package/dist/teste/ModalVariantes.test.d.ts +1 -0
  211. package/dist/teste/ModalVariantes.test.js +151 -0
  212. package/dist/teste/MultiSelectErro.test.d.ts +1 -0
  213. package/dist/teste/MultiSelectErro.test.js +62 -0
  214. package/dist/teste/NomeAcessivelSsr.test.d.ts +1 -0
  215. package/dist/teste/NomeAcessivelSsr.test.js +88 -0
  216. package/dist/teste/OrgChart.test.d.ts +1 -0
  217. package/dist/teste/OrgChart.test.js +162 -0
  218. package/dist/teste/OtpInput.test.d.ts +1 -0
  219. package/dist/teste/OtpInput.test.js +143 -0
  220. package/dist/teste/PopoverMaxHeight.test.d.ts +1 -0
  221. package/dist/teste/PopoverMaxHeight.test.js +38 -0
  222. package/dist/teste/RichTextEditor.test.d.ts +1 -0
  223. package/dist/teste/RichTextEditor.test.js +287 -0
  224. package/dist/teste/RotulosTraduziveis.test.d.ts +1 -0
  225. package/dist/teste/RotulosTraduziveis.test.js +405 -0
  226. package/dist/teste/SegmentedControl.test.js +33 -0
  227. package/dist/teste/Select.test.d.ts +1 -0
  228. package/dist/teste/Select.test.js +62 -0
  229. package/dist/teste/SelectPlacementFiltro.test.d.ts +1 -0
  230. package/dist/teste/SelectPlacementFiltro.test.js +88 -0
  231. package/dist/teste/Stack.test.d.ts +1 -0
  232. package/dist/teste/Stack.test.js +57 -0
  233. package/dist/teste/StatCardRotuloTopo.test.d.ts +1 -0
  234. package/dist/teste/StatCardRotuloTopo.test.js +34 -0
  235. package/dist/teste/TabsContadorFechavel.test.d.ts +1 -0
  236. package/dist/teste/TabsContadorFechavel.test.js +79 -0
  237. package/dist/teste/Tooltip.test.d.ts +1 -0
  238. package/dist/teste/Tooltip.test.js +109 -0
  239. package/dist/teste/TooltipDark.test.d.ts +1 -0
  240. package/dist/teste/TooltipDark.test.js +31 -0
  241. package/dist/utils/calendario.d.ts +28 -0
  242. package/dist/utils/calendario.js +73 -0
  243. package/dist/utils/chart.d.ts +4 -0
  244. package/dist/utils/chart.js +3 -2
  245. package/dist/utils/html-seguro.d.ts +27 -0
  246. package/dist/utils/html-seguro.js +97 -0
  247. package/dist/utils/id.d.ts +2 -0
  248. package/dist/utils/id.js +23 -0
  249. package/dist/utils/paleta-de-cores.d.ts +26 -0
  250. package/dist/utils/paleta-de-cores.js +10 -0
  251. package/dist/utils/texto.d.ts +5 -0
  252. package/dist/utils/texto.js +5 -0
  253. package/package.json +3 -3
  254. package/src/index.ts +26 -0
  255. package/src/teste/AILabel.test.tsx +41 -0
  256. package/src/teste/AccordionConteudoLivre.test.tsx +39 -0
  257. package/src/teste/Alert.test.tsx +32 -0
  258. package/src/teste/AtributosRepassados.test.tsx +73 -0
  259. package/src/teste/AttachmentCardIA.test.tsx +126 -0
  260. package/src/teste/AvatarGroupOverlap.test.tsx +74 -0
  261. package/src/teste/BadgeTag.test.tsx +64 -0
  262. package/src/teste/BottomSheet.test.tsx +25 -0
  263. package/src/teste/BoxItemFlex.test.tsx +81 -0
  264. package/src/teste/BoxLayout.test.tsx +50 -0
  265. package/src/teste/Button.test.tsx +39 -0
  266. package/src/teste/Calendar.test.tsx +282 -0
  267. package/src/teste/ChipsXs.test.tsx +41 -0
  268. package/src/teste/Coachmark.test.tsx +198 -0
  269. package/src/teste/ColorPicker.test.tsx +153 -0
  270. package/src/teste/ConfirmAIAction.test.tsx +41 -0
  271. package/src/teste/DataTableCelulaLivre.test.tsx +103 -0
  272. package/src/teste/DataTableDocumento.test.tsx +102 -0
  273. package/src/teste/DatePicker.test.tsx +38 -0
  274. package/src/teste/Dropdown.test.tsx +146 -0
  275. package/src/teste/FileInputTrigger.test.tsx +89 -0
  276. package/src/teste/IconPicker.test.tsx +145 -0
  277. package/src/teste/InputMascaraEAfins.test.tsx +124 -0
  278. package/src/teste/KbdCodeBlock.test.tsx +106 -0
  279. package/src/teste/List.test.tsx +269 -0
  280. package/src/teste/Modal.test.tsx +28 -0
  281. package/src/teste/ModalVariantes.test.tsx +173 -0
  282. package/src/teste/MultiSelectErro.test.tsx +97 -0
  283. package/src/teste/NomeAcessivelSsr.test.tsx +110 -0
  284. package/src/teste/OrgChart.test.tsx +183 -0
  285. package/src/teste/OtpInput.test.tsx +163 -0
  286. package/src/teste/PopoverMaxHeight.test.tsx +47 -0
  287. package/src/teste/RichTextEditor.test.tsx +329 -0
  288. package/src/teste/RotulosTraduziveis.test.tsx +545 -0
  289. package/src/teste/SegmentedControl.test.tsx +57 -0
  290. package/src/teste/Select.test.tsx +97 -0
  291. package/src/teste/SelectPlacementFiltro.test.tsx +110 -0
  292. package/src/teste/Stack.test.tsx +80 -0
  293. package/src/teste/StatCardRotuloTopo.test.tsx +44 -0
  294. package/src/teste/TabsContadorFechavel.test.tsx +144 -0
  295. package/src/teste/Tooltip.test.tsx +219 -0
  296. package/src/teste/TooltipDark.test.tsx +51 -0
  297. package/src/utils/calendario.ts +78 -0
  298. package/src/utils/chart.ts +7 -2
  299. package/src/utils/html-seguro.ts +94 -0
  300. package/src/utils/id.ts +24 -0
  301. package/src/utils/paleta-de-cores.ts +34 -0
  302. package/src/utils/texto.ts +5 -0
@@ -0,0 +1,51 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import './DescriptionList.css';
3
+ function DescriptionList(props) {
4
+ function itemList() {
5
+ return props.items || [];
6
+ }
7
+ function isStacked() {
8
+ return props.layout === "stacked";
9
+ }
10
+ function classes() {
11
+ const colunas = props.columns || 2;
12
+ return [
13
+ "umds-description-list",
14
+ props.layout === "stacked"
15
+ ? "umds-description-list--stacked"
16
+ : "umds-description-list--inline",
17
+ props.layout === "stacked"
18
+ ? `umds-description-list--cols-${colunas}`
19
+ : "",
20
+ props.layout === "stacked" && props.bordered
21
+ ? "umds-description-list--bordered"
22
+ : "",
23
+ props.layout !== "stacked" && props.fit
24
+ ? "umds-description-list--fit"
25
+ : "",
26
+ props.className,
27
+ ]
28
+ .filter(Boolean)
29
+ .join(" ");
30
+ }
31
+ function valueText(item) {
32
+ const valor = item.value;
33
+ if (valor === undefined || valor === null || valor === "")
34
+ return props.emptyValue || "—";
35
+ return valor;
36
+ }
37
+ function itemKey(item) {
38
+ return item.id || item.label;
39
+ }
40
+ function htmlAttrs() {
41
+ const out = {};
42
+ for (const chave in props) {
43
+ if (chave.indexOf("data-") === 0 || chave === "style") {
44
+ out[chave] = props[chave];
45
+ }
46
+ }
47
+ return out;
48
+ }
49
+ return (_jsx("dl", { id: props.id, "aria-label": props.ariaLabel, "aria-labelledby": props.ariaLabelledby, ...htmlAttrs(), className: classes(), children: itemList()?.map((item) => (_jsxs("div", { className: "umds-description-list__item", children: [_jsx("dt", { className: "umds-description-list__term", children: item.label }), _jsx("dd", { className: "umds-description-list__description", children: valueText(item) })] }, itemKey(item)))) }));
50
+ }
51
+ export default DescriptionList;
@@ -49,6 +49,7 @@
49
49
  .umds-drawer__backdrop {
50
50
  position: absolute;
51
51
  inset: 0;
52
+ /* stylelint-disable-next-line 1ds/cor-por-token -- o DS não tem token de scrim/overlay (candidato a novo token) */
52
53
  background-color: rgba(0, 0, 0, 0.4); /* overlay escuro — sem token 1DS: candidato a novo token (igual ao Modal e ao BottomSheet) */
53
54
  backdrop-filter: blur(4px);
54
55
  z-index: 1;
@@ -216,18 +216,34 @@ function Dropdown(props) {
216
216
  }
217
217
  close();
218
218
  }
219
- function moveActive(delta) {
219
+ function nextEnabledIndex(from, delta) {
220
220
  const items = itemList();
221
- if (items.length === 0)
222
- return;
223
- let next = activeIndex;
224
- for (let step = 0; step < items.length; step++) {
225
- next = (next + delta + items.length) % items.length;
226
- if (!items[next].disabled) {
227
- setActiveIndex(next);
228
- return;
229
- }
221
+ const total = items.length;
222
+ if (total === 0)
223
+ return -1;
224
+ let next = from;
225
+ for (let step = 0; step < total; step++) {
226
+ next = (next + delta + total) % total;
227
+ if (!items[next].disabled)
228
+ return next;
230
229
  }
230
+ return -1;
231
+ }
232
+ function focusedIndex() {
233
+ if (!menuRef.current || typeof document === "undefined")
234
+ return activeIndex;
235
+ const buttons = menuRef.current.querySelectorAll('[role="menuitem"]');
236
+ for (let i = 0; i < buttons.length; i++) {
237
+ if (buttons[i] === document.activeElement)
238
+ return i;
239
+ }
240
+ return activeIndex;
241
+ }
242
+ function activateIndex(index) {
243
+ if (index < 0)
244
+ return;
245
+ setActiveIndex(index);
246
+ focusIndex(index);
231
247
  }
232
248
  function handleTriggerKeydown(event) {
233
249
  const key = event.key;
@@ -236,56 +252,58 @@ function Dropdown(props) {
236
252
  key === "Enter" ||
237
253
  key === " ") {
238
254
  event.preventDefault();
255
+ const total = itemList().length;
256
+ const target = key === "ArrowUp"
257
+ ? nextEnabledIndex(total, -1)
258
+ : nextEnabledIndex(-1, 1);
259
+ setActiveIndex(target);
239
260
  if (!isOpen()) {
261
+ // O foco entra no menu pelo onUpdate, depois que o painel estiver
262
+ // posicionado; lá o activeIndex já é o do render novo.
240
263
  open();
241
264
  }
242
- if (key === "ArrowUp") {
243
- setActiveIndex(itemList().length - 1);
244
- moveActive(0);
245
- }
246
265
  else {
247
- setActiveIndex(-1);
248
- moveActive(1);
266
+ focusIndex(target);
249
267
  }
250
268
  }
251
269
  }
252
270
  function focusActiveItem() {
271
+ focusIndex(activeIndex);
272
+ }
273
+ function focusIndex(index) {
253
274
  if (!menuRef.current)
254
275
  return;
255
276
  const buttons = menuRef.current.querySelectorAll('[role="menuitem"]');
256
- const target = activeIndex >= 0 && activeIndex < buttons.length
257
- ? buttons[activeIndex]
277
+ const target = index >= 0 && index < buttons.length
278
+ ? buttons[index]
258
279
  : menuRef.current;
259
280
  if (target)
260
281
  target.focus();
261
282
  }
262
283
  function handleMenuKeydown(event) {
263
284
  const key = event.key;
285
+ const total = itemList().length;
264
286
  if (key === "ArrowDown") {
265
287
  event.preventDefault();
266
- moveActive(1);
267
- focusActiveItem();
288
+ activateIndex(nextEnabledIndex(focusedIndex(), 1));
268
289
  }
269
290
  else if (key === "ArrowUp") {
270
291
  event.preventDefault();
271
- moveActive(-1);
272
- focusActiveItem();
292
+ const current = focusedIndex();
293
+ // Sem item ativo (foco no próprio <ul>), a seta para cima vai ao último.
294
+ activateIndex(nextEnabledIndex(current < 0 ? total : current, -1));
273
295
  }
274
296
  else if (key === "Home") {
275
297
  event.preventDefault();
276
- setActiveIndex(-1);
277
- moveActive(1);
278
- focusActiveItem();
298
+ activateIndex(nextEnabledIndex(-1, 1));
279
299
  }
280
300
  else if (key === "End") {
281
301
  event.preventDefault();
282
- setActiveIndex(itemList().length);
283
- moveActive(-1);
284
- focusActiveItem();
302
+ activateIndex(nextEnabledIndex(total, -1));
285
303
  }
286
304
  else if (key === "Enter" || key === " ") {
287
305
  event.preventDefault();
288
- const item = itemList()[activeIndex];
306
+ const item = itemList()[focusedIndex()];
289
307
  if (item)
290
308
  handleSelect(item);
291
309
  }
@@ -29,6 +29,22 @@
29
29
  pointer-events: none;
30
30
  }
31
31
 
32
+ /* ── Variante trigger: sem caixa; o conteúdo passado é o gatilho ── */
33
+ .umds-file-input--trigger {
34
+ display: inline-flex;
35
+ flex-direction: column;
36
+ align-items: flex-start;
37
+ }
38
+
39
+ .umds-file-input__trigger-wrap {
40
+ display: inline-flex;
41
+ }
42
+
43
+ /* O input não entra no Tab: o gatilho (o botão) é quem recebe o foco. */
44
+ .umds-file-input--trigger .umds-file-input__native {
45
+ position: absolute;
46
+ }
47
+
32
48
  /* ── Drop zone ── */
33
49
  .umds-file-input__drop-zone {
34
50
  cursor: pointer;
@@ -56,7 +72,7 @@
56
72
  align-items: center;
57
73
  gap: var(--umds-primitive-spacing-xxxs); /* era 12px (protótipo --space-3) — snap 14/07 */
58
74
  padding: var(--umds-primitive-spacing-xxxs); /* era 12px 16px (protótipo --space-3/--space-4) — snap 14/07 */
59
- border: 1.5px dashed var(--umds-semantic-color-neutral-light-down); /* #D5D5D5 */
75
+ border: 1.5px dashed var(--umds-semantic-field-border-default); /* neutral-dark-medium: 3:1 do WCAG 1.4.11 */
60
76
  border-radius: var(--umds-primitive-border-radius-sm); /* 8px */
61
77
  background: var(--umds-semantic-color-background-white);
62
78
  transition:
@@ -149,14 +165,16 @@
149
165
 
150
166
  .umds-file-input__card-text {
151
167
  /* Figma: título 14px em primary-pure; o subtítulo, quando existir, é 12px em
152
- neutral-dark-medium. */
168
+ neutral-dark-medium — aqui neutral-dark-down, ver `__card-subtext`. */
153
169
  font-size: var(--umds-primitive-font-size-xxs); /* 14px */
154
170
  color: var(--umds-semantic-color-primary-pure);
155
171
  }
156
172
 
157
173
  .umds-file-input__card-subtext {
158
174
  font-size: var(--umds-primitive-font-size-xxxs); /* 12px — Figma: subtittle */
159
- color: var(--umds-semantic-color-neutral-dark-medium); /* #7D7D7D */
175
+ /* O Figma pede #7D7D7D (neutral-dark-medium), que dá 4,11:1 sobre branco e
176
+ reprova o WCAG 1.4.3 para texto. neutral-dark-down: #565656, 7,34:1. */
177
+ color: var(--umds-semantic-color-neutral-dark-down);
160
178
  }
161
179
 
162
180
  .umds-file-input__card-link {
@@ -334,6 +352,8 @@
334
352
  color: var(--umds-semantic-color-feedback-negative-pure);
335
353
  }
336
354
 
355
+ /* Mesma cor do helperText do Input (Text color="secondary"): o #7D7D7D de
356
+ antes dava 4,11:1 e reprovava o contraste de texto (WCAG 1.4.3). */
337
357
  .umds-file-input__helper {
338
- color: var(--umds-semantic-color-neutral-dark-medium);
358
+ color: var(--umds-semantic-color-neutral-dark-down);
339
359
  }
@@ -20,7 +20,7 @@ export interface FileInputFile {
20
20
  * @property {boolean} multiple - Permite selecionar múltiplos arquivos
21
21
  * @property {number} maxSize - Tamanho máximo em bytes (exibido como dica na variante base)
22
22
  * @property {boolean} disabled - Desabilita a seleção de arquivos
23
- * @property {string} variant - Variante visual: 'base' (linha) | 'card' (preview visual)
23
+ * @property {string} variant - Variante visual: 'base' (linha) | 'card' (preview visual) | 'trigger' (sem caixa: o seletor é aberto por outro controle, o conteúdo que você passa, como um `Button` "Anexar arquivo" ou um link "Alterar foto"; o clique nele abre o seletor e o resto (`accept`, `multiple`, `files`, `onChange`) funciona igual)
24
24
  * @property {string} label - Rótulo exibido acima do campo
25
25
  * @property {FileInputFile[]} files - Arquivos atualmente listados (controlado)
26
26
  * @property {string} name - Nome do campo no submit de form nativo. Com name, os File
@@ -41,7 +41,7 @@ export interface FileInputProps {
41
41
  multiple?: boolean;
42
42
  maxSize?: number;
43
43
  disabled?: boolean;
44
- variant?: "base" | "card";
44
+ variant?: "base" | "card" | "trigger";
45
45
  label?: string;
46
46
  files?: FileInputFile[];
47
47
  name?: string;
@@ -52,6 +52,26 @@ export interface FileInputProps {
52
52
  /** Texto de ajuda exibido abaixo do campo. */
53
53
  helperText?: string;
54
54
  className?: string;
55
+ /** Nome acessível do input de arquivo quando não há `label`. Troque para traduzir. @default 'Selecionar arquivo' */
56
+ selectFileLabel?: string;
57
+ /** Chamada em negrito da variante `base`. Troque para traduzir. @default 'Clique para selecionar' */
58
+ triggerLabel?: string;
59
+ /** Complemento da chamada na variante `base`, depois do negrito. Troque para traduzir. @default 'ou arraste aqui' */
60
+ triggerHint?: string;
61
+ /** Prefixo da dica de tamanho máximo (recebe o tamanho formatado depois de um espaço). Troque para traduzir. @default 'Máximo' */
62
+ maxSizeLabel?: string;
63
+ /** Chamada em negrito da variante `card`. Troque para traduzir. @default 'Arraste e solte' */
64
+ dropLabel?: string;
65
+ /** Conector entre as duas chamadas da variante `card`. Troque para traduzir. @default 'ou' */
66
+ orLabel?: string;
67
+ /** Link de escolher arquivo na variante `card`. Troque para traduzir. @default 'clique para escolher' */
68
+ browseLabel?: string;
69
+ /** Prefixo do nome acessível do botão de remover um arquivo (recebe o nome do arquivo depois de um espaço), como no MultiSelect. Troque para traduzir. @default 'Remover' */
70
+ removeAriaLabel?: string;
71
+ /** Prefixo do nome acessível da barra de progresso de um arquivo (recebe o nome do arquivo depois de um espaço). Troque para traduzir. @default 'Enviando' */
72
+ uploadingAriaLabel?: string;
73
+ /** Gatilho da variante `trigger` (o `Button` ou link que abre o seletor). React: filhos; Vue: slot padrão. */
74
+ children?: any;
55
75
  onChange?: (files?: File[]) => void;
56
76
  onRemove?: (index?: number) => void;
57
77
  }
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import './FileInput.css';
4
4
  import { useState, useRef } from "react";
5
5
  import { faArrowUpFromBracket, faCloudArrowUp, faFile, faXmark, } from "@fortawesome/free-solid-svg-icons";
@@ -8,6 +8,21 @@ function FileInput(props) {
8
8
  const inputRef = useRef(null);
9
9
  const [dragOver, setDragOver] = useState(() => false);
10
10
  const [nativeFiles, setNativeFiles] = useState(() => Array());
11
+ function triggerHintText() {
12
+ return " " + (props.triggerHint || "ou arraste aqui");
13
+ }
14
+ function orText() {
15
+ return " " + (props.orLabel || "ou") + "\u00A0";
16
+ }
17
+ function maxSizeText() {
18
+ return ((props.maxSizeLabel || "Máximo") + " " + formatSize(props.maxSize || 0));
19
+ }
20
+ function removeFileLabel(fileName) {
21
+ return (props.removeAriaLabel || "Remover") + " " + fileName;
22
+ }
23
+ function uploadingFileLabel(fileName) {
24
+ return (props.uploadingAriaLabel || "Enviando") + " " + fileName;
25
+ }
11
26
  function wrapperClasses() {
12
27
  return [
13
28
  "umds-file-input",
@@ -54,6 +69,12 @@ function FileInput(props) {
54
69
  setNativeFiles(props.multiple ? [...nativeFiles, ...files] : files);
55
70
  applyNativeFiles();
56
71
  }
72
+ function openDialog() {
73
+ if (props.disabled)
74
+ return;
75
+ if (inputRef.current)
76
+ inputRef.current.click();
77
+ }
57
78
  function handleChange(event) {
58
79
  if (props.disabled)
59
80
  return;
@@ -100,7 +121,7 @@ function FileInput(props) {
100
121
  applyNativeFiles();
101
122
  }
102
123
  }
103
- return (_jsxs("div", { className: wrapperClasses(), children: [props.label ? (_jsx("label", { className: "umds-file-input__label", children: props.label })) : null, _jsxs("label", { className: "umds-file-input__drop-zone", onDragOver: (event) => handleDragOver(event), onDragLeave: (event) => handleDragLeave(), onDrop: (event) => handleDrop(event), children: [_jsx("input", { type: "file", className: "umds-file-input__native", ref: inputRef, name: props.name, accept: props.accept, multiple: props.multiple, disabled: props.disabled, onChange: (event) => handleChange(event), "aria-label": props.label || "Selecionar arquivo", "aria-invalid": props.invalid }), props.variant !== "card" ? (_jsxs("div", { className: "umds-file-input__trigger", children: [_jsx("span", { "aria-hidden": "true", className: "umds-file-input__upload-icon", children: _jsx(Icon, { variant: "inherit", customSize: "20px", icon: faArrowUpFromBracket }) }), _jsxs("span", { className: "umds-file-input__trigger-text", children: [_jsx("strong", { children: "Clique para selecionar" }), " ou arraste aqui"] }), props.accept ? (_jsx("span", { className: "umds-file-input__hint", children: props.accept })) : null, props.maxSize ? (_jsxs("span", { className: "umds-file-input__hint", children: ["M\u00E1ximo ", formatSize(props.maxSize)] })) : null] })) : null, props.variant === "card" ? (_jsxs("div", { className: "umds-file-input__card-zone", children: [_jsx("span", { "aria-hidden": "true", className: "umds-file-input__card-icon", children: _jsx(Icon, { variant: "inherit", customSize: "32px", icon: faCloudArrowUp }) }), _jsxs("span", { className: "umds-file-input__card-text", children: [_jsx("strong", { children: "Arraste e solte" }), " ou\u00A0", _jsx("span", { className: "umds-file-input__card-link", children: "clique para escolher" })] })] })) : null] }), hasFiles() ? (_jsx("ul", { className: "umds-file-input__list", children: filesList()?.map((file, idx) => (_jsxs("li", { className: fileClasses(file), children: [_jsxs("div", { className: "umds-file-input__file-row", children: [_jsx("span", { "aria-hidden": "true", className: "umds-file-input__file-avatar", children: _jsx(Icon, { variant: "inherit", customSize: "16px", icon: faFile }) }), _jsxs("div", { className: "umds-file-input__file-info", children: [_jsx("span", { className: "umds-file-input__file-name", children: file.name }), file.status !== "uploading" ? (_jsx("span", { className: "umds-file-input__file-size", children: formatSize(file.size) })) : null, file.error ? (_jsx("span", { className: "umds-file-input__file-error", children: file.error })) : null] }), _jsx("button", { type: "button", className: "umds-file-input__file-remove", onClick: (event) => handleRemove(idx), "aria-label": `Remover ${file.name}`, children: _jsx(Icon, { variant: "inherit", customSize: "10px", icon: faXmark }) })] }), file.status === "uploading" && file.progress !== undefined ? (_jsx("div", { role: "progressbar", className: "umds-file-input__progress-bar", "aria-valuenow": file.progress, "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": `Enviando ${file.name}`, children: _jsx("div", { className: "umds-file-input__progress-fill", style: {
124
+ return (_jsxs("div", { className: wrapperClasses(), children: [props.label && props.variant !== "trigger" ? (_jsx("label", { className: "umds-file-input__label", children: props.label })) : null, props.variant === "trigger" ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "umds-file-input__trigger-wrap", onClick: (event) => openDialog(), children: _jsx(_Fragment, { children: props.children }) }), _jsx("input", { type: "file", className: "umds-file-input__native", ref: inputRef, name: props.name, accept: props.accept, multiple: props.multiple, disabled: props.disabled, onChange: (event) => handleChange(event), "aria-label": props.label || props.selectFileLabel || "Selecionar arquivo", "aria-invalid": props.invalid, tabIndex: -1 })] })) : null, props.variant !== "trigger" ? (_jsxs("label", { className: "umds-file-input__drop-zone", onDragOver: (event) => handleDragOver(event), onDragLeave: (event) => handleDragLeave(), onDrop: (event) => handleDrop(event), children: [_jsx("input", { type: "file", className: "umds-file-input__native", ref: inputRef, name: props.name, accept: props.accept, multiple: props.multiple, disabled: props.disabled, onChange: (event) => handleChange(event), "aria-label": props.label || props.selectFileLabel || "Selecionar arquivo", "aria-invalid": props.invalid }), props.variant !== "card" ? (_jsxs("div", { className: "umds-file-input__trigger", children: [_jsx("span", { "aria-hidden": "true", className: "umds-file-input__upload-icon", children: _jsx(Icon, { variant: "inherit", customSize: "20px", icon: faArrowUpFromBracket }) }), _jsxs("span", { className: "umds-file-input__trigger-text", children: [_jsx("strong", { children: props.triggerLabel || "Clique para selecionar" }), triggerHintText()] }), props.accept ? (_jsx("span", { className: "umds-file-input__hint", children: props.accept })) : null, props.maxSize ? (_jsx("span", { className: "umds-file-input__hint", children: maxSizeText() })) : null] })) : null, props.variant === "card" ? (_jsxs("div", { className: "umds-file-input__card-zone", children: [_jsx("span", { "aria-hidden": "true", className: "umds-file-input__card-icon", children: _jsx(Icon, { variant: "inherit", customSize: "32px", icon: faCloudArrowUp }) }), _jsxs("span", { className: "umds-file-input__card-text", children: [_jsx("strong", { children: props.dropLabel || "Arraste e solte" }), orText(), _jsx("span", { className: "umds-file-input__card-link", children: props.browseLabel || "clique para escolher" })] })] })) : null] })) : null, hasFiles() ? (_jsx("ul", { className: "umds-file-input__list", children: filesList()?.map((file, idx) => (_jsxs("li", { className: fileClasses(file), children: [_jsxs("div", { className: "umds-file-input__file-row", children: [_jsx("span", { "aria-hidden": "true", className: "umds-file-input__file-avatar", children: _jsx(Icon, { variant: "inherit", customSize: "16px", icon: faFile }) }), _jsxs("div", { className: "umds-file-input__file-info", children: [_jsx("span", { className: "umds-file-input__file-name", children: file.name }), file.status !== "uploading" ? (_jsx("span", { className: "umds-file-input__file-size", children: formatSize(file.size) })) : null, file.error ? (_jsx("span", { className: "umds-file-input__file-error", children: file.error })) : null] }), _jsx("button", { type: "button", className: "umds-file-input__file-remove", onClick: (event) => handleRemove(idx), "aria-label": removeFileLabel(file.name), children: _jsx(Icon, { variant: "inherit", customSize: "10px", icon: faXmark }) })] }), file.status === "uploading" && file.progress !== undefined ? (_jsx("div", { role: "progressbar", className: "umds-file-input__progress-bar", "aria-valuenow": file.progress, "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": uploadingFileLabel(file.name), children: _jsx("div", { className: "umds-file-input__progress-fill", style: {
104
125
  width: `${file.progress}%`,
105
126
  } }) })) : null] }, idx))) })) : null, props.invalid && props.errorMessage ? (_jsx("span", { role: "alert", className: "umds-file-input__error", children: props.errorMessage })) : null, !props.invalid && props.helperText ? (_jsx("span", { className: "umds-file-input__helper", children: props.helperText })) : null] }));
106
127
  }
@@ -41,16 +41,16 @@ function Grid(props) {
41
41
  }
42
42
  return classList.filter(Boolean).join(" ");
43
43
  }
44
- function style() {
44
+ function estiloInline() {
45
45
  const styleObj = {};
46
46
  if (props.container && props.spacing) {
47
47
  const gapValue = `var(--umds-primitive-spacing-${props.spacing})`;
48
48
  styleObj.gap = gapValue;
49
49
  styleObj["--umds-grid-gap"] = gapValue;
50
50
  }
51
- // O gerador Vue do Mitosis proíbe "style" como prop declarada/lida
52
- // (getProps lança "avoid using JavaScript keyword"); estilo inline do
53
- // consumidor fica por conta do fallthrough nativo de attrs no Vue.
51
+ // O getter NÃO se chama `style`: o gerador Vue do Mitosis troca toda
52
+ // ocorrência da palavra (até a string "style" e comentário) por
53
+ // `style.value`, e o estilo do consumidor deixava de passar.
54
54
  return styleObj;
55
55
  }
56
56
  function htmlAttrs() {
@@ -67,6 +67,6 @@ function Grid(props) {
67
67
  }
68
68
  return out;
69
69
  }
70
- return (_jsx("div", { id: props.id, style: style(), ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) }));
70
+ return (_jsx("div", { id: props.id, style: estiloInline(), ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) }));
71
71
  }
72
72
  export default Grid;
@@ -0,0 +1,107 @@
1
+ /* ─────────────────────────────────────────────
2
+ ICON PICKER
3
+ Grade de ícones com busca. O escolhido ganha o fundo e a borda do primário.
4
+
5
+ Cores: semânticos · Medidas: primitivos
6
+ ───────────────────────────────────────────── */
7
+
8
+ .umds-icon-picker {
9
+ display: flex;
10
+ flex-direction: column;
11
+ gap: var(--umds-primitive-spacing-nano); /* 8px */
12
+ font-family: var(--umds-semantic-font-family-base);
13
+ }
14
+
15
+ .umds-icon-picker__label {
16
+ font-size: var(--umds-semantic-field-label-size);
17
+ font-weight: var(--umds-semantic-field-label-weight);
18
+ color: var(--umds-semantic-field-label-color);
19
+ }
20
+
21
+ /* Só para leitor de tela: "12 ícones", a cada busca. */
22
+ .umds-icon-picker__sr {
23
+ position: absolute;
24
+ width: 1px;
25
+ height: 1px;
26
+ padding: 0;
27
+ margin: -1px;
28
+ overflow: hidden;
29
+ clip: rect(0, 0, 0, 0);
30
+ clip-path: inset(50%);
31
+ white-space: nowrap;
32
+ border: 0;
33
+ }
34
+
35
+ /* ── Grade ── */
36
+ /* Tamanho do ladrilho: o ícone escolhe, a grade só repete (nada estica quando o container é largo). */
37
+ .umds-icon-picker--md {
38
+ --umds-icon-picker-tile: var(--umds-primitive-spacing-sm); /* 40px */
39
+ }
40
+
41
+ .umds-icon-picker--sm {
42
+ --umds-icon-picker-tile: var(--umds-primitive-spacing-xs); /* 32px */
43
+ }
44
+
45
+ .umds-icon-picker__grid {
46
+ display: grid;
47
+ justify-content: start;
48
+ gap: var(--umds-primitive-spacing-quarck); /* 4px */
49
+ /* Folga para o anel de foco não ser cortado pelo overflow da grade. */
50
+ padding: var(--umds-primitive-spacing-quarck);
51
+ overflow-y: auto;
52
+ }
53
+
54
+ .umds-icon-picker__item {
55
+ display: inline-flex;
56
+ align-items: center;
57
+ justify-content: center;
58
+ box-sizing: border-box;
59
+ min-width: 0;
60
+ margin: 0;
61
+ padding: 0;
62
+ width: var(--umds-icon-picker-tile);
63
+ height: var(--umds-icon-picker-tile);
64
+ border: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-color-neutral-light-medium);
65
+ border-radius: var(--umds-primitive-border-radius-sm);
66
+ background: var(--umds-semantic-color-background-white);
67
+ color: var(--umds-semantic-color-neutral-dark-down);
68
+ cursor: pointer;
69
+ transition:
70
+ background-color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard),
71
+ border-color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard),
72
+ color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard);
73
+ }
74
+
75
+ .umds-icon-picker__item:hover:not(:disabled) {
76
+ background: var(--umds-semantic-color-background-light);
77
+ border-color: var(--umds-semantic-color-neutral-light-down);
78
+ color: var(--umds-semantic-color-neutral-dark-pure);
79
+ }
80
+
81
+ .umds-icon-picker__item--selected,
82
+ .umds-icon-picker__item--selected:hover:not(:disabled) {
83
+ background: var(--umds-semantic-color-primary-light);
84
+ border-color: var(--umds-semantic-color-primary-pure);
85
+ color: var(--umds-semantic-color-primary-dark);
86
+ }
87
+
88
+ .umds-icon-picker__item:focus-visible {
89
+ outline: var(--umds-primitive-border-width-thin) solid var(--umds-semantic-color-primary-pure);
90
+ outline-offset: var(--umds-primitive-border-width-thin);
91
+ }
92
+
93
+ .umds-icon-picker__item:disabled {
94
+ cursor: not-allowed;
95
+ opacity: var(--umds-semantic-field-disabled-opacity);
96
+ }
97
+
98
+ .umds-icon-picker__empty {
99
+ padding: var(--umds-primitive-spacing-xxxs) 0; /* 16px */
100
+ text-align: center;
101
+ }
102
+
103
+ @media (forced-colors: active) {
104
+ .umds-icon-picker__item--selected {
105
+ outline: var(--umds-primitive-border-width-thin) solid Highlight;
106
+ }
107
+ }
@@ -0,0 +1,74 @@
1
+ import './IconPicker.css';
2
+ /**
3
+ * Ícone do IconPicker, quando precisa de nome ou palavras de busca próprios.
4
+ * @property {any} icon - O ícone: o objeto importado do Font Awesome (`faUser`).
5
+ * @property {string} label - Nome para leitor de tela, tooltip e busca (padrão: o nome do ícone, sem hífen).
6
+ * @property {string[]} keywords - Palavras que também acham o ícone na busca (ex.: ["pessoa", "usuário"]).
7
+ */
8
+ export interface IconPickerItem {
9
+ icon: any;
10
+ label?: string;
11
+ keywords?: string[];
12
+ [key: string]: any;
13
+ }
14
+ /**
15
+ * IconPicker — escolha de UM ícone numa grade, com busca.
16
+ *
17
+ * Os ícones vêm por prop (`icons`): objetos do Font Awesome importados
18
+ * (`faUser`, `faFolder`...), puros ou embrulhados em `{ icon, label, keywords }`
19
+ * quando o nome ou a busca precisam de ajuda. O valor é o NOME do ícone
20
+ * (`"user"`, `"file-lines"`), o `iconName` do Font Awesome: guarde o nome e
21
+ * resolva de volta para o objeto na hora de desenhar.
22
+ *
23
+ * É um `radiogroup`: um Tab entra na grade (no ícone escolhido, ou no primeiro)
24
+ * e as setas movem a escolha (esquerda e direita um ícone, cima e baixo uma
25
+ * linha), com Home e End nas pontas. A busca (campo acima da grade, ligada por
26
+ * padrão) filtra por nome e palavras-chave sem acento nem caixa; a seta para
27
+ * baixo no campo leva à grade, e o número de resultados é anunciado.
28
+ *
29
+ * O ícone escolhido ganha fundo e borda do primário, e o resultado vazio mostra
30
+ * `emptyText`. A altura da grade pode ser limitada (`maxHeight`) para listas com
31
+ * dezenas de ícones.
32
+ * @property {any[]} icons - Os ícones: objetos do Font Awesome, ou `{ icon, label?, keywords? }`
33
+ * @property {string} value - Nome do ícone escolhido (controlado)
34
+ * @property {string} defaultValue - Nome inicial (não controlado)
35
+ * @property {string} label - Rótulo visível do grupo
36
+ * @property {string} ariaLabel - Nome acessível quando não há `label` visível
37
+ * @property {number} columns - Colunas da grade (padrão 8)
38
+ * @property {string} size - Tamanho do ícone: 'sm' | 'md' (padrão)
39
+ * @property {number} maxHeight - Altura máxima da grade, em px (rola dentro dela)
40
+ * @property {boolean} hideSearch - Esconde o campo de busca
41
+ * @property {string} searchLabel - Nome do campo de busca (padrão "Buscar ícone")
42
+ * @property {string} searchPlaceholder - Placeholder da busca (padrão "Buscar ícone...")
43
+ * @property {string} emptyText - Texto sem resultados (padrão "Nenhum ícone encontrado")
44
+ * @property {string} resultsLabel - Anúncio da quantidade de resultados; `{count}` vira o número (padrão "{count} ícones")
45
+ * @property {function} iconLabel - Nome de um ícone sem `label`: `(nome) => texto` (padrão: o nome sem hífen)
46
+ * @property {boolean} disabled - Desabilita o grupo inteiro
47
+ * @property {string} id - Base dos ids internos; passe em SSR para os ids já saírem no HTML do servidor
48
+ * @property {string} className - Classes CSS adicionais
49
+ * @property {function} onChange - Chamado com o nome do ícone e o item escolhido
50
+ * @quandoUsar Escolher o ícone de uma categoria, de um tipo de documento, de um perfil, de um atalho.
51
+ * @quandoNaoUsar Para escolher entre poucas opções que o texto descreve melhor, use `SegmentedControl` ou `Select`. Para escolher uma cor, use `ColorPicker`.
52
+ */
53
+ export interface IconPickerProps {
54
+ icons?: any[];
55
+ value?: string;
56
+ defaultValue?: string;
57
+ label?: string;
58
+ ariaLabel?: string;
59
+ columns?: number;
60
+ size?: "sm" | "md";
61
+ maxHeight?: number;
62
+ hideSearch?: boolean;
63
+ searchLabel?: string;
64
+ searchPlaceholder?: string;
65
+ emptyText?: string;
66
+ resultsLabel?: string;
67
+ iconLabel?: (name: string) => string;
68
+ disabled?: boolean;
69
+ id?: string;
70
+ className?: string;
71
+ onChange?: (name: string, item: any) => void;
72
+ }
73
+ declare function IconPicker(props: IconPickerProps): import("react/jsx-runtime").JSX.Element;
74
+ export default IconPicker;