@1doc/1ds-react 2.7.2 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1280 -0
- package/dist/components/AIContent/AIContent.d.ts +10 -0
- package/dist/components/AIContent/AIContent.js +1 -1
- package/dist/components/AILabel/AILabel.d.ts +4 -0
- package/dist/components/AILabel/AILabel.js +2 -2
- package/dist/components/Accordion/Accordion.d.ts +6 -2
- package/dist/components/Alert/Alert.css +2 -0
- package/dist/components/Alert/Alert.d.ts +3 -1
- package/dist/components/Alert/Alert.js +7 -1
- package/dist/components/AppHeader/AppHeader.css +82 -8
- package/dist/components/AppHeader/AppHeader.d.ts +12 -1
- package/dist/components/AppHeader/AppHeader.js +186 -1
- package/dist/components/AppNavItem/AppNavItem.css +11 -3
- package/dist/components/AppShell/AppShell.css +9 -0
- package/dist/components/AppShell/AppShell.d.ts +8 -0
- package/dist/components/AppShell/AppShell.js +4 -1
- package/dist/components/AppSidebar/AppSidebar.css +1 -1
- package/dist/components/AppSidebar/AppSidebar.d.ts +4 -0
- package/dist/components/AppSidebar/AppSidebar.js +3 -1
- package/dist/components/AttachmentCard/AttachmentCard.css +17 -1
- package/dist/components/AttachmentCard/AttachmentCard.d.ts +29 -2
- package/dist/components/AttachmentCard/AttachmentCard.js +88 -20
- package/dist/components/Avatar/Avatar.css +7 -2
- package/dist/components/Avatar/AvatarGroup.d.ts +27 -0
- package/dist/components/Avatar/AvatarGroup.js +28 -4
- package/dist/components/Badge/Badge.css +61 -3
- package/dist/components/Badge/Badge.d.ts +14 -4
- package/dist/components/Badge/Badge.js +1 -0
- package/dist/components/BottomSheet/BottomSheet.css +1 -0
- package/dist/components/BottomSheet/BottomSheet.d.ts +8 -0
- package/dist/components/BottomSheet/BottomSheet.js +14 -2
- package/dist/components/Box/Box.css +83 -0
- package/dist/components/Box/Box.d.ts +82 -2
- package/dist/components/Box/Box.js +42 -2
- package/dist/components/Button/Button.css +29 -0
- package/dist/components/Button/Button.d.ts +4 -4
- package/dist/components/Button/Button.js +4 -1
- package/dist/components/Calendar/Calendar.css +245 -0
- package/dist/components/Calendar/Calendar.d.ts +125 -0
- package/dist/components/Calendar/Calendar.js +320 -0
- package/dist/components/Chart/BarChart.d.ts +6 -0
- package/dist/components/Chart/BarChart.js +3 -1
- package/dist/components/Chart/LineChart.d.ts +6 -0
- package/dist/components/Chart/LineChart.js +3 -1
- package/dist/components/Checkbox/Checkbox.css +4 -1
- package/dist/components/Chips/Chips.css +39 -0
- package/dist/components/Chips/Chips.d.ts +7 -2
- package/dist/components/Chips/Chips.js +6 -2
- package/dist/components/Coachmark/Coachmark.css +118 -0
- package/dist/components/Coachmark/Coachmark.d.ts +75 -0
- package/dist/components/Coachmark/Coachmark.js +321 -0
- package/dist/components/CodeBlock/CodeBlock.css +96 -0
- package/dist/components/CodeBlock/CodeBlock.d.ts +47 -0
- package/dist/components/CodeBlock/CodeBlock.js +103 -0
- package/dist/components/ColorPicker/ColorPicker.css +133 -0
- package/dist/components/ColorPicker/ColorPicker.d.ts +73 -0
- package/dist/components/ColorPicker/ColorPicker.js +219 -0
- package/dist/components/Combobox/Combobox.css +11 -3
- package/dist/components/ConfirmAIAction/ConfirmAIAction.d.ts +11 -1
- package/dist/components/ConfirmAIAction/ConfirmAIAction.js +6 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.css +3 -0
- package/dist/components/ConfirmDialog/ConfirmDialog.d.ts +14 -0
- package/dist/components/ConfirmDialog/ConfirmDialog.js +2 -2
- package/dist/components/DataTable/DataTable.css +80 -0
- package/dist/components/DataTable/DataTable.d.ts +23 -4
- package/dist/components/DataTable/DataTable.js +61 -15
- package/dist/components/DatePicker/DatePicker.css +8 -0
- package/dist/components/DatePicker/DatePicker.d.ts +4 -0
- package/dist/components/DatePicker/DatePicker.js +14 -1
- package/dist/components/DescriptionList/DescriptionList.css +113 -0
- package/dist/components/DescriptionList/DescriptionList.d.ts +59 -0
- package/dist/components/DescriptionList/DescriptionList.js +51 -0
- package/dist/components/Drawer/Drawer.css +1 -0
- package/dist/components/Dropdown/Dropdown.js +47 -29
- package/dist/components/FileInput/FileInput.css +24 -4
- package/dist/components/FileInput/FileInput.d.ts +22 -2
- package/dist/components/FileInput/FileInput.js +23 -2
- package/dist/components/Grid/Grid.js +5 -5
- package/dist/components/IconPicker/IconPicker.css +107 -0
- package/dist/components/IconPicker/IconPicker.d.ts +74 -0
- package/dist/components/IconPicker/IconPicker.js +194 -0
- package/dist/components/Input/Input.css +41 -3
- package/dist/components/Input/Input.d.ts +14 -1
- package/dist/components/Input/Input.js +72 -6
- package/dist/components/Kanban/Kanban.css +5 -0
- package/dist/components/Kanban/Kanban.d.ts +41 -0
- package/dist/components/Kanban/Kanban.js +59 -27
- package/dist/components/Kanban/KanbanCard.d.ts +2 -0
- package/dist/components/Kanban/KanbanCard.js +1 -1
- package/dist/components/Kanban/KanbanColumn.d.ts +2 -0
- package/dist/components/Kanban/KanbanColumn.js +3 -0
- package/dist/components/Kbd/Kbd.css +66 -0
- package/dist/components/Kbd/Kbd.d.ts +32 -0
- package/dist/components/Kbd/Kbd.js +40 -0
- package/dist/components/Link/Link.css +1 -1
- package/dist/components/List/List.css +136 -0
- package/dist/components/List/List.d.ts +82 -0
- package/dist/components/List/List.js +53 -0
- package/dist/components/List/ListItem.d.ts +85 -0
- package/dist/components/List/ListItem.js +81 -0
- package/dist/components/Modal/Modal.css +93 -8
- package/dist/components/Modal/Modal.d.ts +45 -7
- package/dist/components/Modal/Modal.js +106 -6
- package/dist/components/MultiSelect/MultiSelect.css +9 -1
- package/dist/components/MultiSelect/MultiSelect.js +45 -8
- package/dist/components/OrgChart/OrgChart.css +149 -0
- package/dist/components/OrgChart/OrgChart.d.ts +83 -0
- package/dist/components/OrgChart/OrgChart.js +297 -0
- package/dist/components/OtpInput/OtpInput.css +93 -0
- package/dist/components/OtpInput/OtpInput.d.ts +60 -0
- package/dist/components/OtpInput/OtpInput.js +215 -0
- package/dist/components/Pagination/Pagination.d.ts +6 -0
- package/dist/components/Pagination/Pagination.js +9 -1
- package/dist/components/PhoneInput/PhoneInput.css +9 -1
- package/dist/components/PhoneInput/PhoneInput.d.ts +10 -0
- package/dist/components/PhoneInput/PhoneInput.js +20 -3
- package/dist/components/Popover/Popover.d.ts +7 -0
- package/dist/components/Popover/Popover.js +11 -1
- package/dist/components/RichTextEditor/RichTextEditor.css +203 -0
- package/dist/components/RichTextEditor/RichTextEditor.d.ts +83 -0
- package/dist/components/RichTextEditor/RichTextEditor.js +494 -0
- package/dist/components/SegmentedControl/SegmentedControl.d.ts +2 -0
- package/dist/components/SegmentedControl/SegmentedControl.js +21 -8
- package/dist/components/Select/Select.css +71 -1
- package/dist/components/Select/Select.d.ts +12 -0
- package/dist/components/Select/Select.js +93 -10
- package/dist/components/SidePanel/SidePanel.css +4 -4
- package/dist/components/SidePanelItem/SidePanelItem.css +7 -5
- package/dist/components/SidePanelSearch/SidePanelSearch.css +2 -2
- package/dist/components/SidePanelSection/SidePanelSection.css +7 -5
- package/dist/components/Stack/Stack.css +49 -0
- package/dist/components/Stack/Stack.d.ts +65 -7
- package/dist/components/Stack/Stack.js +30 -2
- package/dist/components/StatCard/StatCard.css +73 -0
- package/dist/components/StatCard/StatCard.d.ts +17 -0
- package/dist/components/StatCard/StatCard.js +4 -1
- package/dist/components/Stepper/Stepper.css +4 -1
- package/dist/components/Stepper/Stepper.d.ts +8 -0
- package/dist/components/Stepper/Stepper.js +4 -4
- package/dist/components/Switch/Switch.css +1 -0
- package/dist/components/Tabs/Tab.d.ts +15 -0
- package/dist/components/Tabs/Tab.js +30 -1
- package/dist/components/Tabs/Tabs.css +132 -0
- package/dist/components/Tabs/Tabs.d.ts +7 -0
- package/dist/components/Tabs/Tabs.js +13 -2
- package/dist/components/Tag/Tag.css +85 -2
- package/dist/components/Tag/Tag.d.ts +13 -6
- package/dist/components/Tag/Tag.js +1 -0
- package/dist/components/Text/Text.d.ts +9 -1
- package/dist/components/Text/Text.js +2 -2
- package/dist/components/Textarea/Textarea.css +11 -3
- package/dist/components/TimePicker/TimePicker.css +8 -0
- package/dist/components/TimePicker/TimePicker.d.ts +6 -0
- package/dist/components/TimePicker/TimePicker.js +1 -1
- package/dist/components/Tooltip/Tooltip.css +40 -0
- package/dist/components/Tooltip/Tooltip.d.ts +11 -0
- package/dist/components/Tooltip/Tooltip.js +114 -11
- package/dist/index.d.ts +25 -0
- package/dist/index.js +14 -0
- package/dist/teste/AILabel.test.d.ts +1 -0
- package/dist/teste/AILabel.test.js +33 -0
- package/dist/teste/AccordionConteudoLivre.test.d.ts +1 -0
- package/dist/teste/AccordionConteudoLivre.test.js +29 -0
- package/dist/teste/Alert.test.d.ts +1 -0
- package/dist/teste/Alert.test.js +27 -0
- package/dist/teste/AtributosRepassados.test.d.ts +1 -0
- package/dist/teste/AtributosRepassados.test.js +52 -0
- package/dist/teste/AttachmentCardIA.test.d.ts +1 -0
- package/dist/teste/AttachmentCardIA.test.js +89 -0
- package/dist/teste/AvatarGroupOverlap.test.d.ts +1 -0
- package/dist/teste/AvatarGroupOverlap.test.js +56 -0
- package/dist/teste/BadgeTag.test.d.ts +1 -0
- package/dist/teste/BadgeTag.test.js +42 -0
- package/dist/teste/BottomSheet.test.d.ts +1 -0
- package/dist/teste/BottomSheet.test.js +23 -0
- package/dist/teste/BoxItemFlex.test.d.ts +1 -0
- package/dist/teste/BoxItemFlex.test.js +54 -0
- package/dist/teste/BoxLayout.test.d.ts +1 -0
- package/dist/teste/BoxLayout.test.js +35 -0
- package/dist/teste/Button.test.d.ts +1 -0
- package/dist/teste/Button.test.js +27 -0
- package/dist/teste/Calendar.test.d.ts +1 -0
- package/dist/teste/Calendar.test.js +221 -0
- package/dist/teste/ChipsXs.test.d.ts +1 -0
- package/dist/teste/ChipsXs.test.js +31 -0
- package/dist/teste/Coachmark.test.d.ts +1 -0
- package/dist/teste/Coachmark.test.js +149 -0
- package/dist/teste/ColorPicker.test.d.ts +1 -0
- package/dist/teste/ColorPicker.test.js +132 -0
- package/dist/teste/ConfirmAIAction.test.d.ts +1 -0
- package/dist/teste/ConfirmAIAction.test.js +33 -0
- package/dist/teste/DataTableCelulaLivre.test.d.ts +1 -0
- package/dist/teste/DataTableCelulaLivre.test.js +76 -0
- package/dist/teste/DataTableDocumento.test.d.ts +1 -0
- package/dist/teste/DataTableDocumento.test.js +92 -0
- package/dist/teste/DatePicker.test.js +23 -0
- package/dist/teste/Dropdown.test.js +111 -0
- package/dist/teste/FileInputTrigger.test.d.ts +1 -0
- package/dist/teste/FileInputTrigger.test.js +53 -0
- package/dist/teste/IconPicker.test.d.ts +1 -0
- package/dist/teste/IconPicker.test.js +130 -0
- package/dist/teste/InputMascaraEAfins.test.d.ts +1 -0
- package/dist/teste/InputMascaraEAfins.test.js +99 -0
- package/dist/teste/KbdCodeBlock.test.d.ts +1 -0
- package/dist/teste/KbdCodeBlock.test.js +95 -0
- package/dist/teste/List.test.d.ts +1 -0
- package/dist/teste/List.test.js +153 -0
- package/dist/teste/Modal.test.d.ts +1 -0
- package/dist/teste/Modal.test.js +26 -0
- package/dist/teste/ModalVariantes.test.d.ts +1 -0
- package/dist/teste/ModalVariantes.test.js +151 -0
- package/dist/teste/MultiSelectErro.test.d.ts +1 -0
- package/dist/teste/MultiSelectErro.test.js +62 -0
- package/dist/teste/NomeAcessivelSsr.test.d.ts +1 -0
- package/dist/teste/NomeAcessivelSsr.test.js +88 -0
- package/dist/teste/OrgChart.test.d.ts +1 -0
- package/dist/teste/OrgChart.test.js +162 -0
- package/dist/teste/OtpInput.test.d.ts +1 -0
- package/dist/teste/OtpInput.test.js +143 -0
- package/dist/teste/PopoverMaxHeight.test.d.ts +1 -0
- package/dist/teste/PopoverMaxHeight.test.js +38 -0
- package/dist/teste/RichTextEditor.test.d.ts +1 -0
- package/dist/teste/RichTextEditor.test.js +287 -0
- package/dist/teste/RotulosTraduziveis.test.d.ts +1 -0
- package/dist/teste/RotulosTraduziveis.test.js +405 -0
- package/dist/teste/SegmentedControl.test.js +33 -0
- package/dist/teste/Select.test.d.ts +1 -0
- package/dist/teste/Select.test.js +62 -0
- package/dist/teste/SelectPlacementFiltro.test.d.ts +1 -0
- package/dist/teste/SelectPlacementFiltro.test.js +88 -0
- package/dist/teste/Stack.test.d.ts +1 -0
- package/dist/teste/Stack.test.js +57 -0
- package/dist/teste/StatCardRotuloTopo.test.d.ts +1 -0
- package/dist/teste/StatCardRotuloTopo.test.js +34 -0
- package/dist/teste/TabsContadorFechavel.test.d.ts +1 -0
- package/dist/teste/TabsContadorFechavel.test.js +79 -0
- package/dist/teste/Tooltip.test.d.ts +1 -0
- package/dist/teste/Tooltip.test.js +109 -0
- package/dist/teste/TooltipDark.test.d.ts +1 -0
- package/dist/teste/TooltipDark.test.js +31 -0
- package/dist/utils/calendario.d.ts +28 -0
- package/dist/utils/calendario.js +73 -0
- package/dist/utils/chart.d.ts +4 -0
- package/dist/utils/chart.js +3 -2
- package/dist/utils/html-seguro.d.ts +27 -0
- package/dist/utils/html-seguro.js +97 -0
- package/dist/utils/id.d.ts +2 -0
- package/dist/utils/id.js +23 -0
- package/dist/utils/paleta-de-cores.d.ts +26 -0
- package/dist/utils/paleta-de-cores.js +10 -0
- package/dist/utils/texto.d.ts +5 -0
- package/dist/utils/texto.js +5 -0
- package/package.json +3 -3
- package/src/index.ts +26 -0
- package/src/teste/AILabel.test.tsx +41 -0
- package/src/teste/AccordionConteudoLivre.test.tsx +39 -0
- package/src/teste/Alert.test.tsx +32 -0
- package/src/teste/AtributosRepassados.test.tsx +73 -0
- package/src/teste/AttachmentCardIA.test.tsx +126 -0
- package/src/teste/AvatarGroupOverlap.test.tsx +74 -0
- package/src/teste/BadgeTag.test.tsx +64 -0
- package/src/teste/BottomSheet.test.tsx +25 -0
- package/src/teste/BoxItemFlex.test.tsx +81 -0
- package/src/teste/BoxLayout.test.tsx +50 -0
- package/src/teste/Button.test.tsx +39 -0
- package/src/teste/Calendar.test.tsx +282 -0
- package/src/teste/ChipsXs.test.tsx +41 -0
- package/src/teste/Coachmark.test.tsx +198 -0
- package/src/teste/ColorPicker.test.tsx +153 -0
- package/src/teste/ConfirmAIAction.test.tsx +41 -0
- package/src/teste/DataTableCelulaLivre.test.tsx +103 -0
- package/src/teste/DataTableDocumento.test.tsx +102 -0
- package/src/teste/DatePicker.test.tsx +38 -0
- package/src/teste/Dropdown.test.tsx +146 -0
- package/src/teste/FileInputTrigger.test.tsx +89 -0
- package/src/teste/IconPicker.test.tsx +145 -0
- package/src/teste/InputMascaraEAfins.test.tsx +124 -0
- package/src/teste/KbdCodeBlock.test.tsx +106 -0
- package/src/teste/List.test.tsx +269 -0
- package/src/teste/Modal.test.tsx +28 -0
- package/src/teste/ModalVariantes.test.tsx +173 -0
- package/src/teste/MultiSelectErro.test.tsx +97 -0
- package/src/teste/NomeAcessivelSsr.test.tsx +110 -0
- package/src/teste/OrgChart.test.tsx +183 -0
- package/src/teste/OtpInput.test.tsx +163 -0
- package/src/teste/PopoverMaxHeight.test.tsx +47 -0
- package/src/teste/RichTextEditor.test.tsx +329 -0
- package/src/teste/RotulosTraduziveis.test.tsx +545 -0
- package/src/teste/SegmentedControl.test.tsx +57 -0
- package/src/teste/Select.test.tsx +97 -0
- package/src/teste/SelectPlacementFiltro.test.tsx +110 -0
- package/src/teste/Stack.test.tsx +80 -0
- package/src/teste/StatCardRotuloTopo.test.tsx +44 -0
- package/src/teste/TabsContadorFechavel.test.tsx +144 -0
- package/src/teste/Tooltip.test.tsx +219 -0
- package/src/teste/TooltipDark.test.tsx +51 -0
- package/src/utils/calendario.ts +78 -0
- package/src/utils/chart.ts +7 -2
- package/src/utils/html-seguro.ts +94 -0
- package/src/utils/id.ts +24 -0
- package/src/utils/paleta-de-cores.ts +34 -0
- package/src/utils/texto.ts +5 -0
|
@@ -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
|
|
219
|
+
function nextEnabledIndex(from, delta) {
|
|
220
220
|
const items = itemList();
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
|
|
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 =
|
|
257
|
-
? buttons[
|
|
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
|
-
|
|
267
|
-
focusActiveItem();
|
|
288
|
+
activateIndex(nextEnabledIndex(focusedIndex(), 1));
|
|
268
289
|
}
|
|
269
290
|
else if (key === "ArrowUp") {
|
|
270
291
|
event.preventDefault();
|
|
271
|
-
|
|
272
|
-
|
|
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
|
-
|
|
277
|
-
moveActive(1);
|
|
278
|
-
focusActiveItem();
|
|
298
|
+
activateIndex(nextEnabledIndex(-1, 1));
|
|
279
299
|
}
|
|
280
300
|
else if (key === "End") {
|
|
281
301
|
event.preventDefault();
|
|
282
|
-
|
|
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()[
|
|
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-
|
|
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
|
-
|
|
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-
|
|
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" }),
|
|
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
|
|
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
|
|
52
|
-
//
|
|
53
|
-
//
|
|
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:
|
|
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;
|