@proef/common-ui 2.6.5 → 2.6.6
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/dist/esm/index.js +8 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/v1/components/overlays/DropdownMenu/DropdownMenu.js +222 -0
- package/dist/esm/v1/components/overlays/DropdownMenu/DropdownMenu.js.map +1 -0
- package/dist/esm/v1/foundations/icons/icons.js +8 -0
- package/dist/esm/v1/foundations/icons/icons.js.map +1 -1
- package/dist/esm/v1/primitives/navigation/Steps/Steps.js +68 -0
- package/dist/esm/v1/primitives/navigation/Steps/Steps.js.map +1 -0
- package/dist/style.components.css +1 -1
- package/dist/style.css +1 -1
- package/dist/style.layered.css +1 -1
- package/dist/types/v1/components/overlays/DropdownMenu/DropdownMenu.d.ts +92 -0
- package/dist/types/v1/foundations/icons/icons.d.ts +2 -0
- package/dist/types/v1/index.d.ts +5 -1
- package/dist/types/v1/primitives/navigation/Steps/Steps.d.ts +49 -0
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -19,6 +19,7 @@ import { default as default19, timestampDeData } from "./legacy/components/molec
|
|
|
19
19
|
import { DateInput } from "./v1/primitives/forms/DateInput/DateInput.js";
|
|
20
20
|
import { default as default20, useDialogContainer } from "./v1/components/overlays/Dialog/Dialog.js";
|
|
21
21
|
import { default as default21, accepts } from "./v1/components/documents/DocumentDropzone/DocumentDropzone.js";
|
|
22
|
+
import { DEFAULT_DROPDOWN_MENU_LABELS, DropdownMenu } from "./v1/components/overlays/DropdownMenu/DropdownMenu.js";
|
|
22
23
|
import { default as default22 } from "./legacy/components/layout/Error/Error.js";
|
|
23
24
|
import { default as default23 } from "./legacy/pages/Error/ErrorPage.js";
|
|
24
25
|
import { default as default24 } from "./legacy/components/ui/Escolha.js";
|
|
@@ -73,6 +74,7 @@ import { default as default69 } from "./legacy/components/molecules/Sidebar/Side
|
|
|
73
74
|
import { default as default70 } from "./legacy/components/layout/Spinner/Spinner.js";
|
|
74
75
|
import { default as default71 } from "./legacy/components/atoms/Stack/Stack.js";
|
|
75
76
|
import { default as default72 } from "./legacy/components/organisms/StatusMatrix/StatusMatrix.js";
|
|
77
|
+
import { DEFAULT_STEPS_LABELS, Steps } from "./v1/primitives/navigation/Steps/Steps.js";
|
|
76
78
|
import { default as default73 } from "./v1/primitives/forms/Switch/Switch.js";
|
|
77
79
|
import { default as default74 } from "./legacy/components/atoms/Button/variants/TabButton.js";
|
|
78
80
|
import { default as default75 } from "./v1/components/tables/Table/Table.js";
|
|
@@ -95,7 +97,7 @@ import { AvisosProvider, useAvisos } from "./legacy/components/ui/Avisos.js";
|
|
|
95
97
|
import { Badge } from "./v1/primitives/display/Badge/Badge.js";
|
|
96
98
|
import { BadgeSla, BarraFiltros, Btn, BtnGroup, Campo, CampoInterruptor, CampoPesquisa, CampoSelect, ChipEstadoInterno, Estado, LinhaAlerta, ListaCampos, Modal, SectionGroup } from "./legacy/components/ui/Ui.js";
|
|
97
99
|
import { BarChart, DonutChart, LineChart, shortDateLabel, useChartPalette } from "./v1/components/data/Charts/Charts.js";
|
|
98
|
-
import { BoldIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsUpDownIcon, CloseIcon, ErrorIcon, ExternalLinkIcon, FilterIcon, GlobeIcon, ImageIcon, InfoIcon, ItalicIcon, LayersIcon, ListBulletIcon, ListIcon, ListNumberedIcon, LockIcon, LogOutIcon, MaximizeIcon, MenuIcon, MinimizeIcon, MonitorIcon, MoonIcon, PanelOpenIcon, PrefilledIcon, QrCodeIcon, QuoteIcon, SearchIcon, SlidersIcon, SparklesIcon, StrikethroughIcon, SunIcon, UnderlineIcon, WarningIcon } from "./v1/foundations/icons/icons.js";
|
|
100
|
+
import { BoldIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsUpDownIcon, CloseIcon, ErrorIcon, ExternalLinkIcon, FilterIcon, GlobeIcon, ImageIcon, InfoIcon, ItalicIcon, LayersIcon, ListBulletIcon, ListIcon, ListNumberedIcon, LockIcon, LogOutIcon, MaximizeIcon, MenuIcon, MinimizeIcon, MonitorIcon, MoonIcon, MoreIcon, PanelOpenIcon, PrefilledIcon, QrCodeIcon, QuoteIcon, SearchIcon, SlidersIcon, SparklesIcon, StrikethroughIcon, SunIcon, UnderlineIcon, WarningIcon } from "./v1/foundations/icons/icons.js";
|
|
99
101
|
import { Card } from "./v1/primitives/display/Card/Card.js";
|
|
100
102
|
import { DEFAULT_LIST_FINDER_LABELS } from "./v1/components/lists/ListFinder/labels.js";
|
|
101
103
|
import { DEFAULT_TABLE_LABELS } from "./v1/components/tables/Table/labels.js";
|
|
@@ -166,13 +168,16 @@ export {
|
|
|
166
168
|
ConfirmProvider,
|
|
167
169
|
default17 as Confirmacao,
|
|
168
170
|
default18 as CustomSwitch,
|
|
171
|
+
DEFAULT_DROPDOWN_MENU_LABELS,
|
|
169
172
|
DEFAULT_LIST_FINDER_LABELS,
|
|
173
|
+
DEFAULT_STEPS_LABELS,
|
|
170
174
|
DEFAULT_TABLE_LABELS,
|
|
171
175
|
default19 as DataTable,
|
|
172
176
|
DateInput,
|
|
173
177
|
default20 as Dialog,
|
|
174
178
|
default21 as DocumentDropzone,
|
|
175
179
|
DonutChart,
|
|
180
|
+
DropdownMenu,
|
|
176
181
|
default22 as Error,
|
|
177
182
|
ErrorIcon,
|
|
178
183
|
default23 as ErrorPage,
|
|
@@ -235,6 +240,7 @@ export {
|
|
|
235
240
|
default50 as Modal,
|
|
236
241
|
MonitorIcon,
|
|
237
242
|
MoonIcon,
|
|
243
|
+
MoreIcon,
|
|
238
244
|
default51 as MultiTagPicker,
|
|
239
245
|
default52 as NotFoundPage,
|
|
240
246
|
Notice,
|
|
@@ -277,6 +283,7 @@ export {
|
|
|
277
283
|
default70 as Spinner,
|
|
278
284
|
default71 as Stack,
|
|
279
285
|
default72 as StatusMatrix,
|
|
286
|
+
Steps,
|
|
280
287
|
StrikethroughIcon,
|
|
281
288
|
SunIcon,
|
|
282
289
|
default73 as Switch,
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React, { useId, useRef, useMemo, useState, useEffect } from "react";
|
|
3
|
+
import { createPortal } from "react-dom";
|
|
4
|
+
import Button from "../../../primitives/buttons/Button/Button.js";
|
|
5
|
+
import { ChevronDownIcon, MoreIcon, CheckIcon } from "../../../foundations/icons/icons.js";
|
|
6
|
+
import { useFloatingPanel, PANEL_CLASS, itemClass } from "../../../capabilities/overlay/useFloatingPanel.js";
|
|
7
|
+
import { useDialogContainer } from "../Dialog/Dialog.js";
|
|
8
|
+
const DEFAULT_DROPDOWN_MENU_LABELS = {
|
|
9
|
+
more: "More actions",
|
|
10
|
+
search: "Search…",
|
|
11
|
+
noResults: "No results",
|
|
12
|
+
empty: "Nothing here yet"
|
|
13
|
+
};
|
|
14
|
+
const textOf = (item) => item.searchText ?? (typeof item.label === "string" || typeof item.label === "number" ? String(item.label) : "");
|
|
15
|
+
const isTyping = (el) => el instanceof HTMLElement && (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.isContentEditable);
|
|
16
|
+
function DropdownMenu({
|
|
17
|
+
items,
|
|
18
|
+
label,
|
|
19
|
+
icon,
|
|
20
|
+
"aria-label": ariaLabel,
|
|
21
|
+
variant,
|
|
22
|
+
size = "md",
|
|
23
|
+
active,
|
|
24
|
+
align,
|
|
25
|
+
disabled = false,
|
|
26
|
+
header,
|
|
27
|
+
searchable,
|
|
28
|
+
labels,
|
|
29
|
+
panelClassName = "",
|
|
30
|
+
className = "",
|
|
31
|
+
onOpenChange
|
|
32
|
+
}) {
|
|
33
|
+
const L = { ...DEFAULT_DROPDOWN_MENU_LABELS, ...labels };
|
|
34
|
+
const hasText = label !== void 0 && label !== null && label !== false;
|
|
35
|
+
const p = useFloatingPanel(align ?? (hasText ? "left" : "right"));
|
|
36
|
+
const dialogContainer = useDialogContainer();
|
|
37
|
+
const menuId = useId();
|
|
38
|
+
const searchRef = useRef(null);
|
|
39
|
+
const list = useMemo(() => items.filter((i) => !!i), [items]);
|
|
40
|
+
const withSearch = searchable ?? list.length > 10;
|
|
41
|
+
const [query, setQuery] = useState("");
|
|
42
|
+
const visible = useMemo(() => {
|
|
43
|
+
const q = query.trim().toLowerCase();
|
|
44
|
+
return q ? list.filter((i) => textOf(i).toLowerCase().includes(q)) : list;
|
|
45
|
+
}, [list, query]);
|
|
46
|
+
const enabled = visible.map((i, n) => i.disabled ? -1 : n).filter((n) => n >= 0);
|
|
47
|
+
const [activeIndex, setActiveIndex] = useState(-1);
|
|
48
|
+
const changed = useRef(onOpenChange);
|
|
49
|
+
changed.current = onOpenChange;
|
|
50
|
+
const first = useRef(true);
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (first.current) {
|
|
53
|
+
first.current = false;
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
changed.current?.(p.open);
|
|
57
|
+
}, [p.open]);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (!p.open) return;
|
|
60
|
+
setQuery("");
|
|
61
|
+
setActiveIndex(-1);
|
|
62
|
+
if (withSearch) setTimeout(() => searchRef.current?.focus(), 0);
|
|
63
|
+
}, [p.open]);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (p.open && activeIndex >= 0) p.panelRef.current?.querySelector(`[data-index="${activeIndex}"]`)?.scrollIntoView?.({ block: "nearest" });
|
|
66
|
+
}, [activeIndex, p.open, p.panelRef]);
|
|
67
|
+
if (list.length === 0 && !header) return null;
|
|
68
|
+
const close = () => {
|
|
69
|
+
p.close();
|
|
70
|
+
p.triggerRef.current?.focus();
|
|
71
|
+
};
|
|
72
|
+
const choose = (item) => {
|
|
73
|
+
if (item.disabled) return;
|
|
74
|
+
if (item.checked === void 0) close();
|
|
75
|
+
item.onSelect?.();
|
|
76
|
+
};
|
|
77
|
+
const move = (step) => {
|
|
78
|
+
if (enabled.length === 0) return;
|
|
79
|
+
const at = enabled.indexOf(activeIndex);
|
|
80
|
+
const next = step === "first" ? enabled[0] : step === "last" ? enabled[enabled.length - 1] : at === -1 ? step === 1 ? enabled[0] : enabled[enabled.length - 1] : enabled[Math.min(enabled.length - 1, Math.max(0, at + step))];
|
|
81
|
+
setActiveIndex(next);
|
|
82
|
+
};
|
|
83
|
+
const keys = (e) => {
|
|
84
|
+
if (!p.open) {
|
|
85
|
+
if (["ArrowDown", "ArrowUp"].includes(e.key)) {
|
|
86
|
+
e.preventDefault();
|
|
87
|
+
p.setOpen(true);
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (e.key === "Escape") {
|
|
92
|
+
e.preventDefault();
|
|
93
|
+
e.stopPropagation();
|
|
94
|
+
close();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (e.key === "Tab") {
|
|
98
|
+
p.close();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (isTyping(e.target) && e.target !== searchRef.current) return;
|
|
102
|
+
if (e.key === "ArrowDown") {
|
|
103
|
+
e.preventDefault();
|
|
104
|
+
move(1);
|
|
105
|
+
} else if (e.key === "ArrowUp") {
|
|
106
|
+
e.preventDefault();
|
|
107
|
+
move(-1);
|
|
108
|
+
} else if (e.key === "Home" && e.target !== searchRef.current) {
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
move("first");
|
|
111
|
+
} else if (e.key === "End" && e.target !== searchRef.current) {
|
|
112
|
+
e.preventDefault();
|
|
113
|
+
move("last");
|
|
114
|
+
} else if (e.key === "Enter" || e.key === " " && e.target !== searchRef.current) {
|
|
115
|
+
const item = visible[activeIndex];
|
|
116
|
+
if (item) {
|
|
117
|
+
e.preventDefault();
|
|
118
|
+
choose(item);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const name = ariaLabel ?? (hasText ? void 0 : L.more);
|
|
123
|
+
return /* @__PURE__ */ jsxs("div", { className: `relative inline-flex ${className}`, onKeyDown: keys, children: [
|
|
124
|
+
/* @__PURE__ */ jsx(
|
|
125
|
+
Button,
|
|
126
|
+
{
|
|
127
|
+
ref: p.triggerRef,
|
|
128
|
+
variant: variant ?? (hasText ? "secondary" : "ghost"),
|
|
129
|
+
size,
|
|
130
|
+
active,
|
|
131
|
+
disabled,
|
|
132
|
+
icon: hasText ? icon : icon ?? /* @__PURE__ */ jsx(MoreIcon, { size: size === "sm" ? 14 : 16 }),
|
|
133
|
+
"aria-label": name,
|
|
134
|
+
"data-tip": hasText ? void 0 : name,
|
|
135
|
+
"aria-haspopup": "menu",
|
|
136
|
+
"aria-expanded": p.open,
|
|
137
|
+
"aria-controls": p.open ? menuId : void 0,
|
|
138
|
+
onClick: (e) => {
|
|
139
|
+
e.stopPropagation();
|
|
140
|
+
p.setOpen((o) => !o);
|
|
141
|
+
},
|
|
142
|
+
children: hasText ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
143
|
+
label,
|
|
144
|
+
/* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: `shrink-0 transition-transform ${p.open ? "rotate-180" : ""}` })
|
|
145
|
+
] }) : void 0
|
|
146
|
+
}
|
|
147
|
+
),
|
|
148
|
+
p.open && createPortal(
|
|
149
|
+
/* @__PURE__ */ jsxs("div", { ref: p.panelRef, style: p.style, className: `${PANEL_CLASS} ${panelClassName}`, onClick: (e) => e.stopPropagation(), children: [
|
|
150
|
+
header && /* @__PURE__ */ jsx("div", { className: "border-b border-slate-100 px-2 pt-1 pb-2 dark:border-slate-800", children: header }),
|
|
151
|
+
withSearch && /* @__PURE__ */ jsx("div", { className: "px-2 pt-1 pb-1", children: /* @__PURE__ */ jsx(
|
|
152
|
+
"input",
|
|
153
|
+
{
|
|
154
|
+
ref: searchRef,
|
|
155
|
+
type: "search",
|
|
156
|
+
value: query,
|
|
157
|
+
onChange: (e) => {
|
|
158
|
+
setQuery(e.target.value);
|
|
159
|
+
setActiveIndex(-1);
|
|
160
|
+
},
|
|
161
|
+
placeholder: L.search,
|
|
162
|
+
"aria-label": L.search,
|
|
163
|
+
className: "h-8 w-full rounded-lg border border-slate-300 bg-white px-2.5 text-sm outline-none focus:border-proef-blue dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100"
|
|
164
|
+
}
|
|
165
|
+
) }),
|
|
166
|
+
/* @__PURE__ */ jsxs("div", { id: menuId, role: "menu", "aria-label": typeof label === "string" ? label : name, children: [
|
|
167
|
+
visible.length === 0 && /* @__PURE__ */ jsx("p", { className: "m-0 px-3 py-2 text-slate-400", children: list.length === 0 ? L.empty : L.noResults }),
|
|
168
|
+
visible.map((item, i) => {
|
|
169
|
+
const checkable = item.checked !== void 0;
|
|
170
|
+
const mark = checkable ? item.checked : item.selected;
|
|
171
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
172
|
+
item.separator && i > 0 && /* @__PURE__ */ jsx("div", { role: "separator", className: "my-1 border-t border-slate-100 dark:border-slate-800" }),
|
|
173
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center", "data-index": i, children: [
|
|
174
|
+
/* @__PURE__ */ jsxs(
|
|
175
|
+
"button",
|
|
176
|
+
{
|
|
177
|
+
type: "button",
|
|
178
|
+
role: checkable ? "menuitemcheckbox" : item.selected !== void 0 ? "menuitemradio" : "menuitem",
|
|
179
|
+
"aria-checked": checkable ? item.checked : item.selected !== void 0 ? item.selected : void 0,
|
|
180
|
+
disabled: item.disabled,
|
|
181
|
+
tabIndex: -1,
|
|
182
|
+
onMouseEnter: () => !item.disabled && setActiveIndex(i),
|
|
183
|
+
onClick: () => choose(item),
|
|
184
|
+
className: `min-w-0 flex-1 appearance-none border-0 ${itemClass(i === activeIndex, item.danger)} disabled:cursor-not-allowed disabled:opacity-40`,
|
|
185
|
+
children: [
|
|
186
|
+
item.icon && /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center", children: item.icon }),
|
|
187
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
188
|
+
/* @__PURE__ */ jsx("span", { className: `block truncate ${mark ? "font-semibold" : ""}`, children: item.label }),
|
|
189
|
+
item.description && /* @__PURE__ */ jsx("span", { className: "block truncate text-[11px] text-slate-500 dark:text-slate-400", children: item.description })
|
|
190
|
+
] }),
|
|
191
|
+
(checkable || item.selected !== void 0) && /* @__PURE__ */ jsx("span", { className: "w-4 shrink-0", children: mark && /* @__PURE__ */ jsx(CheckIcon, { size: 16, strokeWidth: 2.5, className: "text-proef-blue dark:text-sky-300" }) })
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
),
|
|
195
|
+
item.action && /* @__PURE__ */ jsx(
|
|
196
|
+
Button,
|
|
197
|
+
{
|
|
198
|
+
variant: "ghost",
|
|
199
|
+
size: "sm",
|
|
200
|
+
icon: item.action.icon,
|
|
201
|
+
"aria-label": item.action.label,
|
|
202
|
+
"data-tip": item.action.label,
|
|
203
|
+
tabIndex: -1,
|
|
204
|
+
onClick: item.action.onSelect,
|
|
205
|
+
className: "mr-1 shrink-0"
|
|
206
|
+
}
|
|
207
|
+
)
|
|
208
|
+
] })
|
|
209
|
+
] }, i);
|
|
210
|
+
})
|
|
211
|
+
] })
|
|
212
|
+
] }),
|
|
213
|
+
dialogContainer ?? document.body
|
|
214
|
+
)
|
|
215
|
+
] });
|
|
216
|
+
}
|
|
217
|
+
export {
|
|
218
|
+
DEFAULT_DROPDOWN_MENU_LABELS,
|
|
219
|
+
DropdownMenu,
|
|
220
|
+
DropdownMenu as default
|
|
221
|
+
};
|
|
222
|
+
//# sourceMappingURL=DropdownMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DropdownMenu.js","sources":["../../../../../../src/v1/components/overlays/DropdownMenu/DropdownMenu.tsx"],"sourcesContent":["import React, { useEffect, useId, useMemo, useRef, useState } from 'react'\r\nimport { createPortal } from 'react-dom'\r\nimport Button, { type ButtonProps } from '../../../primitives/buttons/Button/Button'\r\nimport { CheckIcon, ChevronDownIcon, MoreIcon } from '../../../foundations/icons/icons'\r\nimport { PANEL_CLASS, itemClass, useFloatingPanel } from '../../../capabilities/overlay/useFloatingPanel'\r\nimport { useDialogContainer } from '../Dialog/Dialog'\r\n\r\nexport interface DropdownMenuItemAction {\r\n /** Ícone do botão pequeno (ex: um caixote do lixo). */\r\n icon: React.ReactNode\r\n /** Nome do botão, para o tooltip e leitores de ecrã (ex: \"Apagar vista\"). */\r\n label: string\r\n onSelect: () => void\r\n}\r\n\r\nexport interface DropdownMenuItem {\r\n /** Normalmente texto; aceita JSX. */\r\n label: React.ReactNode\r\n /** Linha pequena por baixo do texto. */\r\n description?: React.ReactNode\r\n /** Ícone à esquerda (ex: um ícone do lucide com `size={14}`). */\r\n icon?: React.ReactNode\r\n /** O que o item faz. Um item normal fecha o menu ao ser escolhido. */\r\n onSelect?: () => void\r\n /**\r\n * Item de marcar (✓ quando `true`). O menu fica aberto para se marcarem\r\n * vários (ex: filtrar por tipos). `false` = por marcar, `undefined` = não é de marcar.\r\n */\r\n checked?: boolean\r\n /** A opção atual numa escolha de uma só (ex: a vista aplicada): ✓, e escolher fecha o menu como uma ação. */\r\n selected?: boolean\r\n /** Apaga ou não se pode desfazer: a vermelho. */\r\n danger?: boolean\r\n disabled?: boolean\r\n /** Linha a separar este item do anterior. */\r\n separator?: boolean\r\n /** Texto para a pesquisa quando o `label` não é texto. */\r\n searchText?: string\r\n /** Botão pequeno à direita do item (ex: apagar uma vista guardada). Não fecha o menu. */\r\n action?: DropdownMenuItemAction\r\n}\r\n\r\nexport interface DropdownMenuLabels {\r\n /** Nome do botão sem texto (⋯). */\r\n more: string\r\n /** Texto da caixa de pesquisa. */\r\n search: string\r\n /** Pesquisa sem resultados. */\r\n noResults: string\r\n /** DropdownMenu sem itens (só aparece com `header`; sem `header` o menu nem se mostra). */\r\n empty: string\r\n}\r\n\r\nexport const DEFAULT_DROPDOWN_MENU_LABELS: DropdownMenuLabels = {\r\n more: 'More actions',\r\n search: 'Search…',\r\n noResults: 'No results',\r\n empty: 'Nothing here yet',\r\n}\r\n\r\nexport interface DropdownMenuProps {\r\n /** Os itens; `false`, `null` e `undefined` são ignorados (para `cond && {...}`). */\r\n items: (DropdownMenuItem | false | null | undefined)[]\r\n /** Texto do botão (com uma seta). Sem texto, o botão é o ⋯ (ações de uma linha ou de um cartão). */\r\n label?: React.ReactNode\r\n /** Ícone antes do texto do botão. Sem `label`, substitui o ⋯. */\r\n icon?: React.ReactNode\r\n /** Nome do botão para leitores de ecrã e tooltip. Sem `label`, por omissão `labels.more`. */\r\n 'aria-label'?: string\r\n /** Aspeto do botão, como no Button. Por omissão `secondary` (com texto) ou `ghost` (⋯). */\r\n variant?: ButtonProps['variant']\r\n size?: ButtonProps['size']\r\n /** Botão ligado (ex: há uma vista ou filtro aplicado). */\r\n active?: boolean\r\n /** Para que lado abre a lista, a partir do botão. Por omissão `left` (com texto) ou `right` (⋯). */\r\n align?: 'left' | 'right'\r\n disabled?: boolean\r\n /** Conteúdo no topo da lista, antes dos itens (ex: campo \"Guardar vista atual\", filtros). */\r\n header?: React.ReactNode\r\n /** Caixa de pesquisa no topo da lista. Por omissão, só com mais de 10 itens. */\r\n searchable?: boolean\r\n labels?: Partial<DropdownMenuLabels>\r\n /** Classes da lista (ex: a largura, `w-64`). */\r\n panelClassName?: string\r\n /** Classes da caixa à volta do botão. */\r\n className?: string\r\n /** Avisa quando a lista abre ou fecha (ex: para limpar um campo do `header`). */\r\n onOpenChange?: (open: boolean) => void\r\n}\r\n\r\nconst textOf = (item: DropdownMenuItem) => item.searchText ?? (typeof item.label === 'string' || typeof item.label === 'number' ? String(item.label) : '')\r\n\r\nconst isTyping = (el: EventTarget | null) =>\r\n el instanceof HTMLElement && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.isContentEditable)\r\n\r\n/**\r\n * Botão que abre uma lista de ações ou opções: o ⋯ de uma linha, \"Ações em massa\", \"Vistas guardadas\",\r\n * um filtro de escolha múltipla. A mesma lista do [SelectInput](?path=/docs/v1-primitives-forms-selectinput--docs).\r\n *\r\n * - **Ações**: escolher executa e fecha.\r\n * - **Marcar** (`checked`): o item leva ✓ e a lista fica aberta para marcar vários.\r\n * - **Escolher um** (`selected`): ✓ na opção atual; escolher fecha.\r\n * - **Ação no item** (`action`): um botão pequeno à direita (ex: apagar uma vista).\r\n * - **Topo livre** (`header`): ex: um campo para guardar a vista atual.\r\n *\r\n * Teclado: ↑/↓, Home/End, Enter escolhe, Esc fecha. Abre por cima de um\r\n * [Dialog](?path=/docs/v1-components-overlays-dialog--docs) e os cliques não chegam a uma linha clicável por baixo.\r\n *\r\n * Substitui o `MenuAcoes` legacy.\r\n */\r\nexport default function DropdownMenu({\r\n items,\r\n label,\r\n icon,\r\n 'aria-label': ariaLabel,\r\n variant,\r\n size = 'md',\r\n active,\r\n align,\r\n disabled = false,\r\n header,\r\n searchable,\r\n labels,\r\n panelClassName = '',\r\n className = '',\r\n onOpenChange,\r\n}: DropdownMenuProps) {\r\n const L = { ...DEFAULT_DROPDOWN_MENU_LABELS, ...labels }\r\n const hasText = label !== undefined && label !== null && label !== false\r\n const p = useFloatingPanel(align ?? (hasText ? 'left' : 'right'))\r\n // Dentro de um Dialog a lista abre na janela (como no SelectInput): no body ficava por baixo dela.\r\n const dialogContainer = useDialogContainer()\r\n const menuId = useId()\r\n const searchRef = useRef<HTMLInputElement>(null)\r\n\r\n const list = useMemo(() => items.filter((i): i is DropdownMenuItem => !!i), [items])\r\n const withSearch = searchable ?? list.length > 10\r\n const [query, setQuery] = useState('')\r\n const visible = useMemo(() => {\r\n const q = query.trim().toLowerCase()\r\n return q ? list.filter((i) => textOf(i).toLowerCase().includes(q)) : list\r\n }, [list, query])\r\n const enabled = visible.map((i, n) => (i.disabled ? -1 : n)).filter((n) => n >= 0)\r\n const [activeIndex, setActiveIndex] = useState(-1)\r\n\r\n const changed = useRef(onOpenChange)\r\n changed.current = onOpenChange\r\n const first = useRef(true)\r\n useEffect(() => {\r\n if (first.current) {\r\n first.current = false\r\n return\r\n }\r\n changed.current?.(p.open)\r\n }, [p.open])\r\n\r\n // Ao abrir: limpa a pesquisa e põe o teclado no primeiro item.\r\n useEffect(() => {\r\n if (!p.open) return\r\n setQuery('')\r\n setActiveIndex(-1)\r\n if (withSearch) setTimeout(() => searchRef.current?.focus(), 0)\r\n }, [p.open]) // eslint-disable-line react-hooks/exhaustive-deps\r\n\r\n useEffect(() => {\r\n if (p.open && activeIndex >= 0) p.panelRef.current?.querySelector<HTMLElement>(`[data-index=\"${activeIndex}\"]`)?.scrollIntoView?.({ block: 'nearest' })\r\n }, [activeIndex, p.open, p.panelRef])\r\n\r\n if (list.length === 0 && !header) return null\r\n\r\n const close = () => {\r\n p.close()\r\n p.triggerRef.current?.focus()\r\n }\r\n\r\n const choose = (item: DropdownMenuItem) => {\r\n if (item.disabled) return\r\n // De marcar: fica aberto para se marcarem vários.\r\n if (item.checked === undefined) close()\r\n item.onSelect?.()\r\n }\r\n\r\n const move = (step: 1 | -1 | 'first' | 'last') => {\r\n if (enabled.length === 0) return\r\n const at = enabled.indexOf(activeIndex)\r\n const next =\r\n step === 'first' ? enabled[0]\r\n : step === 'last' ? enabled[enabled.length - 1]\r\n : at === -1 ? (step === 1 ? enabled[0] : enabled[enabled.length - 1])\r\n : enabled[Math.min(enabled.length - 1, Math.max(0, at + step))]\r\n setActiveIndex(next)\r\n }\r\n\r\n // Um só sítio para o teclado: os eventos da lista (portal) também sobem até aqui.\r\n const keys = (e: React.KeyboardEvent) => {\r\n if (!p.open) {\r\n if (['ArrowDown', 'ArrowUp'].includes(e.key)) {\r\n e.preventDefault()\r\n p.setOpen(true)\r\n }\r\n return\r\n }\r\n if (e.key === 'Escape') {\r\n e.preventDefault()\r\n e.stopPropagation()\r\n close()\r\n return\r\n }\r\n if (e.key === 'Tab') {\r\n p.close()\r\n return\r\n }\r\n // A escrever num campo do topo: as teclas são do campo (a pesquisa deixa passar as setas e o Enter).\r\n if (isTyping(e.target) && e.target !== searchRef.current) return\r\n if (e.key === 'ArrowDown') {\r\n e.preventDefault()\r\n move(1)\r\n } else if (e.key === 'ArrowUp') {\r\n e.preventDefault()\r\n move(-1)\r\n } else if (e.key === 'Home' && e.target !== searchRef.current) {\r\n e.preventDefault()\r\n move('first')\r\n } else if (e.key === 'End' && e.target !== searchRef.current) {\r\n e.preventDefault()\r\n move('last')\r\n } else if (e.key === 'Enter' || (e.key === ' ' && e.target !== searchRef.current)) {\r\n const item = visible[activeIndex]\r\n if (item) {\r\n e.preventDefault()\r\n choose(item)\r\n }\r\n }\r\n }\r\n\r\n const name = ariaLabel ?? (hasText ? undefined : L.more)\r\n\r\n return (\r\n <div className={`relative inline-flex ${className}`} onKeyDown={keys}>\r\n <Button\r\n ref={p.triggerRef}\r\n variant={variant ?? (hasText ? 'secondary' : 'ghost')}\r\n size={size}\r\n active={active}\r\n disabled={disabled}\r\n icon={hasText ? icon : (icon ?? <MoreIcon size={size === 'sm' ? 14 : 16} />)}\r\n aria-label={name}\r\n data-tip={hasText ? undefined : name}\r\n aria-haspopup=\"menu\"\r\n aria-expanded={p.open}\r\n aria-controls={p.open ? menuId : undefined}\r\n onClick={(e) => {\r\n // Dentro de uma linha clicável (tabelas, cartões), abrir o menu não abre a linha.\r\n e.stopPropagation()\r\n p.setOpen((o) => !o)\r\n }}\r\n >\r\n {hasText ? (\r\n <>\r\n {label}\r\n <ChevronDownIcon size={12} className={`shrink-0 transition-transform ${p.open ? 'rotate-180' : ''}`} />\r\n </>\r\n ) : undefined}\r\n </Button>\r\n {p.open &&\r\n createPortal(\r\n <div ref={p.panelRef} style={p.style} className={`${PANEL_CLASS} ${panelClassName}`} onClick={(e) => e.stopPropagation()}>\r\n {header && <div className=\"border-b border-slate-100 px-2 pt-1 pb-2 dark:border-slate-800\">{header}</div>}\r\n {withSearch && (\r\n <div className=\"px-2 pt-1 pb-1\">\r\n <input\r\n ref={searchRef}\r\n type=\"search\"\r\n value={query}\r\n onChange={(e) => {\r\n setQuery(e.target.value)\r\n setActiveIndex(-1)\r\n }}\r\n placeholder={L.search}\r\n aria-label={L.search}\r\n className=\"h-8 w-full rounded-lg border border-slate-300 bg-white px-2.5 text-sm outline-none focus:border-proef-blue dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100\"\r\n />\r\n </div>\r\n )}\r\n <div id={menuId} role=\"menu\" aria-label={typeof label === 'string' ? label : name}>\r\n {visible.length === 0 && (\r\n <p className=\"m-0 px-3 py-2 text-slate-400\">{list.length === 0 ? L.empty : L.noResults}</p>\r\n )}\r\n {visible.map((item, i) => {\r\n const checkable = item.checked !== undefined\r\n const mark = checkable ? item.checked : item.selected\r\n return (\r\n <React.Fragment key={i}>\r\n {item.separator && i > 0 && <div role=\"separator\" className=\"my-1 border-t border-slate-100 dark:border-slate-800\" />}\r\n <div className=\"flex items-center\" data-index={i}>\r\n <button\r\n type=\"button\"\r\n role={checkable ? 'menuitemcheckbox' : item.selected !== undefined ? 'menuitemradio' : 'menuitem'}\r\n aria-checked={checkable ? item.checked : item.selected !== undefined ? item.selected : undefined}\r\n disabled={item.disabled}\r\n tabIndex={-1}\r\n onMouseEnter={() => !item.disabled && setActiveIndex(i)}\r\n onClick={() => choose(item)}\r\n className={`min-w-0 flex-1 appearance-none border-0 ${itemClass(i === activeIndex, item.danger)} disabled:cursor-not-allowed disabled:opacity-40`}\r\n >\r\n {item.icon && <span className=\"flex shrink-0 items-center\">{item.icon}</span>}\r\n <span className=\"min-w-0 flex-1\">\r\n <span className={`block truncate ${mark ? 'font-semibold' : ''}`}>{item.label}</span>\r\n {item.description && <span className=\"block truncate text-[11px] text-slate-500 dark:text-slate-400\">{item.description}</span>}\r\n </span>\r\n {(checkable || item.selected !== undefined) && (\r\n <span className=\"w-4 shrink-0\">\r\n {mark && <CheckIcon size={16} strokeWidth={2.5} className=\"text-proef-blue dark:text-sky-300\" />}\r\n </span>\r\n )}\r\n </button>\r\n {item.action && (\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n icon={item.action.icon}\r\n aria-label={item.action.label}\r\n data-tip={item.action.label}\r\n tabIndex={-1}\r\n onClick={item.action.onSelect}\r\n className=\"mr-1 shrink-0\"\r\n />\r\n )}\r\n </div>\r\n </React.Fragment>\r\n )\r\n })}\r\n </div>\r\n </div>,\r\n dialogContainer ?? document.body,\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\nexport { DropdownMenu }\r\n"],"names":[],"mappings":"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"}
|
|
@@ -185,6 +185,13 @@ function SlidersIcon(props) {
|
|
|
185
185
|
/* @__PURE__ */ jsx("circle", { cx: "8", cy: "17", r: "2" })
|
|
186
186
|
] });
|
|
187
187
|
}
|
|
188
|
+
function MoreIcon(props) {
|
|
189
|
+
return /* @__PURE__ */ jsxs(Svg, { ...props, fill: "currentColor", children: [
|
|
190
|
+
/* @__PURE__ */ jsx("circle", { cx: "5", cy: "12", r: "1.8" }),
|
|
191
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1.8" }),
|
|
192
|
+
/* @__PURE__ */ jsx("circle", { cx: "19", cy: "12", r: "1.8" })
|
|
193
|
+
] });
|
|
194
|
+
}
|
|
188
195
|
export {
|
|
189
196
|
BoldIcon,
|
|
190
197
|
CheckIcon,
|
|
@@ -212,6 +219,7 @@ export {
|
|
|
212
219
|
MinimizeIcon,
|
|
213
220
|
MonitorIcon,
|
|
214
221
|
MoonIcon,
|
|
222
|
+
MoreIcon,
|
|
215
223
|
PanelOpenIcon,
|
|
216
224
|
PrefilledIcon,
|
|
217
225
|
QrCodeIcon,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.js","sources":["../../../../../src/v1/foundations/icons/icons.tsx"],"sourcesContent":["import React from 'react'\r\n\r\n/**\r\n * Conjunto de ícones do V1: traço de 1,7 a 1,9 em grelha de 24, cor do texto\r\n * (`currentColor`), sem preenchimento. Decorativos por omissão (`aria-hidden`):\r\n * quem os usa dá o nome acessível ao botão ou etiqueta à volta.\r\n */\r\nexport interface IconProps {\r\n /** Lado em px. */\r\n size?: number\r\n className?: string\r\n /** Espessura do traço. Por omissão 1,8; mais grosso em ícones muito pequenos (ex: o visto de uma caixa). */\r\n strokeWidth?: number\r\n}\r\n\r\nfunction Svg({ size = 16, className, strokeWidth = 1.8, children, fill = 'none' }: IconProps & { children: React.ReactNode; fill?: string }) {\r\n return (\r\n <svg\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill={fill}\r\n stroke={fill === 'none' ? 'currentColor' : 'none'}\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n className={className}\r\n aria-hidden\r\n >\r\n {children}\r\n </svg>\r\n )\r\n}\r\n\r\n/** Lido de um QR code. */\r\nexport function QrCodeIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <rect x=\"3.5\" y=\"3.5\" width=\"6.5\" height=\"6.5\" rx=\"1.3\" />\r\n <rect x=\"14\" y=\"3.5\" width=\"6.5\" height=\"6.5\" rx=\"1.3\" />\r\n <rect x=\"3.5\" y=\"14\" width=\"6.5\" height=\"6.5\" rx=\"1.3\" />\r\n <path d=\"M14 14h3.3v3.3M20.5 14v.01M14 20.5h.01M17.3 20.5h3.2v-3.2\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Identificado automaticamente (IA). */\r\nexport function SparklesIcon(props: IconProps) {\r\n return (\r\n <Svg {...props} fill=\"currentColor\">\r\n <path d=\"M12 2.5l1.7 4.6 4.6 1.7-4.6 1.7L12 15.1l-1.7-4.6L5.7 8.8l4.6-1.7z\" />\r\n <path d=\"M18.5 13.5l.85 2.35 2.35.85-2.35.85-.85 2.35-.85-2.35-2.35-.85 2.35-.85z\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Pré-preenchido a partir de outro registo (ex: linha de um extrato). */\r\nexport function PrefilledIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <rect x=\"4\" y=\"3.5\" width=\"16\" height=\"17\" rx=\"2\" />\r\n <path d=\"M7.5 8.5h9M7.5 12h9M7.5 15.5h5.5\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Bloqueado: o valor não se pode alterar. */\r\nexport function LockIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <rect x=\"5\" y=\"10.5\" width=\"14\" height=\"10\" rx=\"2\" />\r\n <path d=\"M8.5 10.5V7.5a3.5 3.5 0 0 1 7 0v3\" />\r\n <circle cx=\"12\" cy=\"15.5\" r=\"1.1\" fill=\"currentColor\" stroke=\"none\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Mais informação. */\r\nexport function InfoIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <circle cx=\"12\" cy=\"12\" r=\"9.5\" />\r\n <path d=\"M12 11v5.5\" />\r\n <circle cx=\"12\" cy=\"7.8\" r=\"1.1\" fill=\"currentColor\" stroke=\"none\" />\r\n </Svg>\r\n )\r\n}\r\n\r\nexport function SearchIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <circle cx=\"10.5\" cy=\"10.5\" r=\"6.5\" />\r\n <path d=\"M15.5 15.5L20 20\" />\r\n </Svg>\r\n )\r\n}\r\n\r\nexport function CheckIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M4.5 12.5l5 5 10-11\" />\r\n </Svg>\r\n )\r\n}\r\n\r\nexport function ChevronDownIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M6 9.5l6 6 6-6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\nexport function ChevronUpIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M6 14.5l6-6 6 6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\nexport function ChevronLeftIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M14.5 6l-6 6 6 6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\nexport function ChevronRightIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M9.5 6l6 6-6 6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Ordenável: ainda sem ordem escolhida. */\r\nexport function ChevronsUpDownIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M7.5 9.5L12 5l4.5 4.5M7.5 14.5L12 19l4.5-4.5\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Filtro (funil). */\r\nexport function FilterIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M4 5h16l-6.2 7.6v5.6l-3.6 1.8v-7.4z\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Fechar, remover (×). */\r\nexport function CloseIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M6.5 6.5l11 11M17.5 6.5l-11 11\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Abrir o menu (gaveta em ecrãs pequenos). */\r\nexport function MenuIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M4 7h16M4 12h16M4 17h16\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Agrupar (camadas). */\r\nexport function LayersIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M12 3.5l8.5 4.5-8.5 4.5L3.5 8z\" />\r\n <path d=\"M3.5 12l8.5 4.5 8.5-4.5M3.5 16l8.5 4.5 8.5-4.5\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Expandir o menu lateral recolhido. */\r\nexport function PanelOpenIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <rect x=\"3.5\" y=\"4\" width=\"17\" height=\"16\" rx=\"2\" />\r\n <path d=\"M9 4v16M13 10l2 2-2 2\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Lista de valores. */\r\nexport function ListIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M9 6.5h11M9 12h11M9 17.5h11M4.5 6.5h.01M4.5 12h.01M4.5 17.5h.01\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Texto: negrito. */\r\nexport function BoldIcon(props: IconProps) {\r\n return (\r\n <Svg strokeWidth={2.2} {...props}>\r\n <path d=\"M7 5h6a3.5 3.5 0 0 1 0 7H7zM7 12h7a3.5 3.5 0 0 1 0 7H7z\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Texto: itálico. */\r\nexport function ItalicIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M10 5h8M6 19h8M14.5 5l-5 14\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Texto: sublinhado. */\r\nexport function UnderlineIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M7 4.5v6a5 5 0 0 0 10 0v-6M5.5 20h13\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Texto: riscado. */\r\nexport function StrikethroughIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M4.5 12h15M16.5 6.5A4.5 3.5 0 0 0 12 5c-2.5 0-4.5 1.3-4.5 3.2 0 1.4 1 2.4 2.7 2.9M8 17.3A5 3.6 0 0 0 12 19c2.6 0 4.6-1.4 4.6-3.3 0-.8-.3-1.5-.9-2\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Lista com marcas (no texto). */\r\nexport function ListBulletIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M9.5 6.5h10M9.5 12h10M9.5 17.5h10\" />\r\n <circle cx=\"5\" cy=\"6.5\" r=\"1\" fill=\"currentColor\" />\r\n <circle cx=\"5\" cy=\"12\" r=\"1\" fill=\"currentColor\" />\r\n <circle cx=\"5\" cy=\"17.5\" r=\"1\" fill=\"currentColor\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Lista numerada (no texto). */\r\nexport function ListNumberedIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M10 6.5h10M10 12h10M10 17.5h10M4 5.5l1.3-.8v4M3.8 15.2c.3-.6.9-.9 1.5-.9.8 0 1.4.5 1.4 1.2 0 1-1.6 1.6-2.9 2.8h3\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Citação. */\r\nexport function QuoteIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M5 18V12.5C5 9 6.5 7 9.5 6M14 18v-5.5C14 9 15.5 7 18.5 6M5 12.5h4.5V18H5M14 12.5h4.5V18H14\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Imagem. */\r\nexport function ImageIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <rect x=\"3.5\" y=\"4.5\" width=\"17\" height=\"15\" rx=\"2\" />\r\n <circle cx=\"9\" cy=\"10\" r=\"1.6\" />\r\n <path d=\"M20.5 15.5l-4.5-4.5-8.5 8.5\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Abrir em ecrã quase inteiro. */\r\nexport function MaximizeIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M14 4.5h5.5V10M10 19.5H4.5V14M19.5 4.5L13.5 10.5M4.5 19.5l6-6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Voltar ao tamanho normal. */\r\nexport function MinimizeIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M19.5 10H14V4.5M4.5 14H10v5.5M14 10l6-6M4 20l6-6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Tema claro. */\r\nexport function SunIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\r\n <path d=\"M12 2.5v2M12 19.5v2M4.6 4.6L6 6M18 18l1.4 1.4M2.5 12h2M19.5 12h2M4.6 19.4L6 18M18 6l1.4-1.4\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Tema escuro. */\r\nexport function MoonIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M20 14.5A8 8 0 0 1 9.5 4a8 8 0 1 0 10.5 10.5z\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Tema do sistema. */\r\nexport function MonitorIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"12.5\" rx=\"2\" />\r\n <path d=\"M8.5 20.5h7M12 16.5v4\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Idioma. */\r\nexport function GlobeIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\r\n <path d=\"M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Terminar sessão. */\r\nexport function LogOutIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M9.5 20.5H6a2 2 0 0 1-2-2v-13a2 2 0 0 1 2-2h3.5M15.5 16.5L20 12l-4.5-4.5M20 12H9.5\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Abre fora da aplicação (separador novo). */\r\nexport function ExternalLinkIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M14 4h6v6M20 4l-9 9M18 13.5V18a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4.5\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Atenção (avisos, confirmações perigosas). */\r\nexport function WarningIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M10.3 4.3L2.8 17.5A2 2 0 0 0 4.5 20.5h15a2 2 0 0 0 1.7-3L13.7 4.3a2 2 0 0 0-3.4 0z\" />\r\n <path d=\"M12 9.5v4.5\" />\r\n <circle cx=\"12\" cy=\"17\" r=\"1.1\" fill=\"currentColor\" stroke=\"none\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Erro. */\r\nexport function ErrorIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <circle cx=\"12\" cy=\"12\" r=\"9.5\" />\r\n <path d=\"M9 9l6 6M15 9l-6 6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Intervalo (mínimo e máximo). */\r\nexport function SlidersIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M4 7h10M18 7h2M4 17h2M10 17h10\" />\r\n <circle cx=\"16\" cy=\"7\" r=\"2\" />\r\n <circle cx=\"8\" cy=\"17\" r=\"2\" />\r\n </Svg>\r\n )\r\n}\r\n"],"names":[],"mappings":";AAeA,SAAS,IAAI,EAAE,OAAO,IAAI,WAAW,cAAc,KAAK,UAAU,OAAO,UAAoE;AAC3I,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAQ;AAAA,MACR;AAAA,MACA,QAAQ,SAAS,SAAS,iBAAiB;AAAA,MAC3C;AAAA,MACA,eAAc;AAAA,MACd,gBAAe;AAAA,MACf;AAAA,MACA,eAAW;AAAA,MAEV;AAAA,IAAA;AAAA,EAAA;AAGP;AAGO,SAAS,WAAW,OAAkB;AAC3C,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,GAAE,OAAM,GAAE,OAAM,OAAM,OAAM,QAAO,OAAM,IAAG,MAAA,CAAM;AAAA,IACxD,oBAAC,QAAA,EAAK,GAAE,MAAK,GAAE,OAAM,OAAM,OAAM,QAAO,OAAM,IAAG,MAAA,CAAM;AAAA,IACvD,oBAAC,QAAA,EAAK,GAAE,OAAM,GAAE,MAAK,OAAM,OAAM,QAAO,OAAM,IAAG,MAAA,CAAM;AAAA,IACvD,oBAAC,QAAA,EAAK,GAAE,4DAAA,CAA4D;AAAA,EAAA,GACtE;AAEJ;AAGO,SAAS,aAAa,OAAkB;AAC7C,SACE,qBAAC,KAAA,EAAK,GAAG,OAAO,MAAK,gBACnB,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,GAAE,oEAAA,CAAoE;AAAA,IAC5E,oBAAC,QAAA,EAAK,GAAE,2EAAA,CAA2E;AAAA,EAAA,GACrF;AAEJ;AAGO,SAAS,cAAc,OAAkB;AAC9C,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,GAAE,KAAI,GAAE,OAAM,OAAM,MAAK,QAAO,MAAK,IAAG,IAAA,CAAI;AAAA,IAClD,oBAAC,QAAA,EAAK,GAAE,mCAAA,CAAmC;AAAA,EAAA,GAC7C;AAEJ;AAGO,SAAS,SAAS,OAAkB;AACzC,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,GAAE,KAAI,GAAE,QAAO,OAAM,MAAK,QAAO,MAAK,IAAG,IAAA,CAAI;AAAA,IACnD,oBAAC,QAAA,EAAK,GAAE,oCAAA,CAAoC;AAAA,IAC5C,oBAAC,UAAA,EAAO,IAAG,MAAK,IAAG,QAAO,GAAE,OAAM,MAAK,gBAAe,QAAO,OAAA,CAAO;AAAA,EAAA,GACtE;AAEJ;AAGO,SAAS,SAAS,OAAkB;AACzC,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,OAAM;AAAA,IAChC,oBAAC,QAAA,EAAK,GAAE,aAAA,CAAa;AAAA,IACrB,oBAAC,UAAA,EAAO,IAAG,MAAK,IAAG,OAAM,GAAE,OAAM,MAAK,gBAAe,QAAO,OAAA,CAAO;AAAA,EAAA,GACrE;AAEJ;AAEO,SAAS,WAAW,OAAkB;AAC3C,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,YAAO,IAAG,QAAO,IAAG,QAAO,GAAE,OAAM;AAAA,IACpC,oBAAC,QAAA,EAAK,GAAE,mBAAA,CAAmB;AAAA,EAAA,GAC7B;AAEJ;AAEO,SAAS,UAAU,OAAkB;AAC1C,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,uBAAsB,EAAA,CAChC;AAEJ;AAEO,SAAS,gBAAgB,OAAkB;AAChD,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,kBAAiB,EAAA,CAC3B;AAEJ;AAEO,SAAS,cAAc,OAAkB;AAC9C,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,mBAAkB,EAAA,CAC5B;AAEJ;AAEO,SAAS,gBAAgB,OAAkB;AAChD,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,oBAAmB,EAAA,CAC7B;AAEJ;AAEO,SAAS,iBAAiB,OAAkB;AACjD,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,kBAAiB,EAAA,CAC3B;AAEJ;AAGO,SAAS,mBAAmB,OAAkB;AACnD,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,gDAA+C,EAAA,CACzD;AAEJ;AAGO,SAAS,WAAW,OAAkB;AAC3C,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,uCAAsC,EAAA,CAChD;AAEJ;AAGO,SAAS,UAAU,OAAkB;AAC1C,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,kCAAiC,EAAA,CAC3C;AAEJ;AAGO,SAAS,SAAS,OAAkB;AACzC,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,2BAA0B,EAAA,CACpC;AAEJ;AAGO,SAAS,WAAW,OAAkB;AAC3C,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,GAAE,iCAAA,CAAiC;AAAA,IACzC,oBAAC,QAAA,EAAK,GAAE,iDAAA,CAAiD;AAAA,EAAA,GAC3D;AAEJ;AAGO,SAAS,cAAc,OAAkB;AAC9C,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,GAAE,OAAM,GAAE,KAAI,OAAM,MAAK,QAAO,MAAK,IAAG,IAAA,CAAI;AAAA,IAClD,oBAAC,QAAA,EAAK,GAAE,wBAAA,CAAwB;AAAA,EAAA,GAClC;AAEJ;AAGO,SAAS,SAAS,OAAkB;AACzC,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,mEAAkE,EAAA,CAC5E;AAEJ;AAGO,SAAS,SAAS,OAAkB;AACzC,SACE,oBAAC,KAAA,EAAI,aAAa,KAAM,GAAG,OACzB,UAAA,oBAAC,QAAA,EAAK,GAAE,0DAAA,CAA0D,EAAA,CACpE;AAEJ;AAGO,SAAS,WAAW,OAAkB;AAC3C,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,+BAA8B,EAAA,CACxC;AAEJ;AAGO,SAAS,cAAc,OAAkB;AAC9C,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,wCAAuC,EAAA,CACjD;AAEJ;AAGO,SAAS,kBAAkB,OAAkB;AAClD,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,qJAAoJ,EAAA,CAC9J;AAEJ;AAGO,SAAS,eAAe,OAAkB;AAC/C,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,GAAE,oCAAA,CAAoC;AAAA,IAC5C,oBAAC,YAAO,IAAG,KAAI,IAAG,OAAM,GAAE,KAAI,MAAK,eAAA,CAAe;AAAA,IAClD,oBAAC,YAAO,IAAG,KAAI,IAAG,MAAK,GAAE,KAAI,MAAK,eAAA,CAAe;AAAA,IACjD,oBAAC,YAAO,IAAG,KAAI,IAAG,QAAO,GAAE,KAAI,MAAK,eAAA,CAAe;AAAA,EAAA,GACrD;AAEJ;AAGO,SAAS,iBAAiB,OAAkB;AACjD,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,oHAAmH,EAAA,CAC7H;AAEJ;AAGO,SAAS,UAAU,OAAkB;AAC1C,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,8FAA6F,EAAA,CACvG;AAEJ;AAGO,SAAS,UAAU,OAAkB;AAC1C,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,GAAE,OAAM,GAAE,OAAM,OAAM,MAAK,QAAO,MAAK,IAAG,IAAA,CAAI;AAAA,wBACnD,UAAA,EAAO,IAAG,KAAI,IAAG,MAAK,GAAE,OAAM;AAAA,IAC/B,oBAAC,QAAA,EAAK,GAAE,8BAAA,CAA8B;AAAA,EAAA,GACxC;AAEJ;AAGO,SAAS,aAAa,OAAkB;AAC7C,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,iEAAgE,EAAA,CAC1E;AAEJ;AAGO,SAAS,aAAa,OAAkB;AAC7C,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,oDAAmD,EAAA,CAC7D;AAEJ;AAGO,SAAS,QAAQ,OAAkB;AACxC,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,IAC9B,oBAAC,QAAA,EAAK,GAAE,8FAAA,CAA8F;AAAA,EAAA,GACxG;AAEJ;AAGO,SAAS,SAAS,OAAkB;AACzC,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,iDAAgD,EAAA,CAC1D;AAEJ;AAGO,SAAS,YAAY,OAAkB;AAC5C,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,GAAE,KAAI,GAAE,KAAI,OAAM,MAAK,QAAO,QAAO,IAAG,IAAA,CAAI;AAAA,IAClD,oBAAC,QAAA,EAAK,GAAE,wBAAA,CAAwB;AAAA,EAAA,GAClC;AAEJ;AAGO,SAAS,UAAU,OAAkB;AAC1C,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,IAC9B,oBAAC,QAAA,EAAK,GAAE,uDAAA,CAAuD;AAAA,EAAA,GACjE;AAEJ;AAGO,SAAS,WAAW,OAAkB;AAC3C,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,sFAAqF,EAAA,CAC/F;AAEJ;AAGO,SAAS,iBAAiB,OAAkB;AACjD,SACE,oBAAC,OAAK,GAAG,OACP,8BAAC,QAAA,EAAK,GAAE,oFAAmF,EAAA,CAC7F;AAEJ;AAGO,SAAS,YAAY,OAAkB;AAC5C,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,GAAE,qFAAA,CAAqF;AAAA,IAC7F,oBAAC,QAAA,EAAK,GAAE,cAAA,CAAc;AAAA,IACtB,oBAAC,UAAA,EAAO,IAAG,MAAK,IAAG,MAAK,GAAE,OAAM,MAAK,gBAAe,QAAO,OAAA,CAAO;AAAA,EAAA,GACpE;AAEJ;AAGO,SAAS,UAAU,OAAkB;AAC1C,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,OAAM;AAAA,IAChC,oBAAC,QAAA,EAAK,GAAE,qBAAA,CAAqB;AAAA,EAAA,GAC/B;AAEJ;AAGO,SAAS,YAAY,OAAkB;AAC5C,SACE,qBAAC,KAAA,EAAK,GAAG,OACP,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,GAAE,iCAAA,CAAiC;AAAA,wBACxC,UAAA,EAAO,IAAG,MAAK,IAAG,KAAI,GAAE,KAAI;AAAA,wBAC5B,UAAA,EAAO,IAAG,KAAI,IAAG,MAAK,GAAE,IAAA,CAAI;AAAA,EAAA,GAC/B;AAEJ;"}
|
|
1
|
+
{"version":3,"file":"icons.js","sources":["../../../../../src/v1/foundations/icons/icons.tsx"],"sourcesContent":["import React from 'react'\r\n\r\n/**\r\n * Conjunto de ícones do V1: traço de 1,7 a 1,9 em grelha de 24, cor do texto\r\n * (`currentColor`), sem preenchimento. Decorativos por omissão (`aria-hidden`):\r\n * quem os usa dá o nome acessível ao botão ou etiqueta à volta.\r\n */\r\nexport interface IconProps {\r\n /** Lado em px. */\r\n size?: number\r\n className?: string\r\n /** Espessura do traço. Por omissão 1,8; mais grosso em ícones muito pequenos (ex: o visto de uma caixa). */\r\n strokeWidth?: number\r\n}\r\n\r\nfunction Svg({ size = 16, className, strokeWidth = 1.8, children, fill = 'none' }: IconProps & { children: React.ReactNode; fill?: string }) {\r\n return (\r\n <svg\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill={fill}\r\n stroke={fill === 'none' ? 'currentColor' : 'none'}\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n className={className}\r\n aria-hidden\r\n >\r\n {children}\r\n </svg>\r\n )\r\n}\r\n\r\n/** Lido de um QR code. */\r\nexport function QrCodeIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <rect x=\"3.5\" y=\"3.5\" width=\"6.5\" height=\"6.5\" rx=\"1.3\" />\r\n <rect x=\"14\" y=\"3.5\" width=\"6.5\" height=\"6.5\" rx=\"1.3\" />\r\n <rect x=\"3.5\" y=\"14\" width=\"6.5\" height=\"6.5\" rx=\"1.3\" />\r\n <path d=\"M14 14h3.3v3.3M20.5 14v.01M14 20.5h.01M17.3 20.5h3.2v-3.2\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Identificado automaticamente (IA). */\r\nexport function SparklesIcon(props: IconProps) {\r\n return (\r\n <Svg {...props} fill=\"currentColor\">\r\n <path d=\"M12 2.5l1.7 4.6 4.6 1.7-4.6 1.7L12 15.1l-1.7-4.6L5.7 8.8l4.6-1.7z\" />\r\n <path d=\"M18.5 13.5l.85 2.35 2.35.85-2.35.85-.85 2.35-.85-2.35-2.35-.85 2.35-.85z\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Pré-preenchido a partir de outro registo (ex: linha de um extrato). */\r\nexport function PrefilledIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <rect x=\"4\" y=\"3.5\" width=\"16\" height=\"17\" rx=\"2\" />\r\n <path d=\"M7.5 8.5h9M7.5 12h9M7.5 15.5h5.5\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Bloqueado: o valor não se pode alterar. */\r\nexport function LockIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <rect x=\"5\" y=\"10.5\" width=\"14\" height=\"10\" rx=\"2\" />\r\n <path d=\"M8.5 10.5V7.5a3.5 3.5 0 0 1 7 0v3\" />\r\n <circle cx=\"12\" cy=\"15.5\" r=\"1.1\" fill=\"currentColor\" stroke=\"none\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Mais informação. */\r\nexport function InfoIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <circle cx=\"12\" cy=\"12\" r=\"9.5\" />\r\n <path d=\"M12 11v5.5\" />\r\n <circle cx=\"12\" cy=\"7.8\" r=\"1.1\" fill=\"currentColor\" stroke=\"none\" />\r\n </Svg>\r\n )\r\n}\r\n\r\nexport function SearchIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <circle cx=\"10.5\" cy=\"10.5\" r=\"6.5\" />\r\n <path d=\"M15.5 15.5L20 20\" />\r\n </Svg>\r\n )\r\n}\r\n\r\nexport function CheckIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M4.5 12.5l5 5 10-11\" />\r\n </Svg>\r\n )\r\n}\r\n\r\nexport function ChevronDownIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M6 9.5l6 6 6-6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\nexport function ChevronUpIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M6 14.5l6-6 6 6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\nexport function ChevronLeftIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M14.5 6l-6 6 6 6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\nexport function ChevronRightIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M9.5 6l6 6-6 6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Ordenável: ainda sem ordem escolhida. */\r\nexport function ChevronsUpDownIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M7.5 9.5L12 5l4.5 4.5M7.5 14.5L12 19l4.5-4.5\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Filtro (funil). */\r\nexport function FilterIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M4 5h16l-6.2 7.6v5.6l-3.6 1.8v-7.4z\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Fechar, remover (×). */\r\nexport function CloseIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M6.5 6.5l11 11M17.5 6.5l-11 11\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Abrir o menu (gaveta em ecrãs pequenos). */\r\nexport function MenuIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M4 7h16M4 12h16M4 17h16\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Agrupar (camadas). */\r\nexport function LayersIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M12 3.5l8.5 4.5-8.5 4.5L3.5 8z\" />\r\n <path d=\"M3.5 12l8.5 4.5 8.5-4.5M3.5 16l8.5 4.5 8.5-4.5\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Expandir o menu lateral recolhido. */\r\nexport function PanelOpenIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <rect x=\"3.5\" y=\"4\" width=\"17\" height=\"16\" rx=\"2\" />\r\n <path d=\"M9 4v16M13 10l2 2-2 2\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Lista de valores. */\r\nexport function ListIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M9 6.5h11M9 12h11M9 17.5h11M4.5 6.5h.01M4.5 12h.01M4.5 17.5h.01\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Texto: negrito. */\r\nexport function BoldIcon(props: IconProps) {\r\n return (\r\n <Svg strokeWidth={2.2} {...props}>\r\n <path d=\"M7 5h6a3.5 3.5 0 0 1 0 7H7zM7 12h7a3.5 3.5 0 0 1 0 7H7z\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Texto: itálico. */\r\nexport function ItalicIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M10 5h8M6 19h8M14.5 5l-5 14\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Texto: sublinhado. */\r\nexport function UnderlineIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M7 4.5v6a5 5 0 0 0 10 0v-6M5.5 20h13\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Texto: riscado. */\r\nexport function StrikethroughIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M4.5 12h15M16.5 6.5A4.5 3.5 0 0 0 12 5c-2.5 0-4.5 1.3-4.5 3.2 0 1.4 1 2.4 2.7 2.9M8 17.3A5 3.6 0 0 0 12 19c2.6 0 4.6-1.4 4.6-3.3 0-.8-.3-1.5-.9-2\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Lista com marcas (no texto). */\r\nexport function ListBulletIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M9.5 6.5h10M9.5 12h10M9.5 17.5h10\" />\r\n <circle cx=\"5\" cy=\"6.5\" r=\"1\" fill=\"currentColor\" />\r\n <circle cx=\"5\" cy=\"12\" r=\"1\" fill=\"currentColor\" />\r\n <circle cx=\"5\" cy=\"17.5\" r=\"1\" fill=\"currentColor\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Lista numerada (no texto). */\r\nexport function ListNumberedIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M10 6.5h10M10 12h10M10 17.5h10M4 5.5l1.3-.8v4M3.8 15.2c.3-.6.9-.9 1.5-.9.8 0 1.4.5 1.4 1.2 0 1-1.6 1.6-2.9 2.8h3\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Citação. */\r\nexport function QuoteIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M5 18V12.5C5 9 6.5 7 9.5 6M14 18v-5.5C14 9 15.5 7 18.5 6M5 12.5h4.5V18H5M14 12.5h4.5V18H14\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Imagem. */\r\nexport function ImageIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <rect x=\"3.5\" y=\"4.5\" width=\"17\" height=\"15\" rx=\"2\" />\r\n <circle cx=\"9\" cy=\"10\" r=\"1.6\" />\r\n <path d=\"M20.5 15.5l-4.5-4.5-8.5 8.5\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Abrir em ecrã quase inteiro. */\r\nexport function MaximizeIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M14 4.5h5.5V10M10 19.5H4.5V14M19.5 4.5L13.5 10.5M4.5 19.5l6-6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Voltar ao tamanho normal. */\r\nexport function MinimizeIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M19.5 10H14V4.5M4.5 14H10v5.5M14 10l6-6M4 20l6-6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Tema claro. */\r\nexport function SunIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\r\n <path d=\"M12 2.5v2M12 19.5v2M4.6 4.6L6 6M18 18l1.4 1.4M2.5 12h2M19.5 12h2M4.6 19.4L6 18M18 6l1.4-1.4\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Tema escuro. */\r\nexport function MoonIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M20 14.5A8 8 0 0 1 9.5 4a8 8 0 1 0 10.5 10.5z\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Tema do sistema. */\r\nexport function MonitorIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"12.5\" rx=\"2\" />\r\n <path d=\"M8.5 20.5h7M12 16.5v4\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Idioma. */\r\nexport function GlobeIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\r\n <path d=\"M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Terminar sessão. */\r\nexport function LogOutIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M9.5 20.5H6a2 2 0 0 1-2-2v-13a2 2 0 0 1 2-2h3.5M15.5 16.5L20 12l-4.5-4.5M20 12H9.5\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Abre fora da aplicação (separador novo). */\r\nexport function ExternalLinkIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M14 4h6v6M20 4l-9 9M18 13.5V18a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4.5\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Atenção (avisos, confirmações perigosas). */\r\nexport function WarningIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M10.3 4.3L2.8 17.5A2 2 0 0 0 4.5 20.5h15a2 2 0 0 0 1.7-3L13.7 4.3a2 2 0 0 0-3.4 0z\" />\r\n <path d=\"M12 9.5v4.5\" />\r\n <circle cx=\"12\" cy=\"17\" r=\"1.1\" fill=\"currentColor\" stroke=\"none\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Erro. */\r\nexport function ErrorIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <circle cx=\"12\" cy=\"12\" r=\"9.5\" />\r\n <path d=\"M9 9l6 6M15 9l-6 6\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Intervalo (mínimo e máximo). */\r\nexport function SlidersIcon(props: IconProps) {\r\n return (\r\n <Svg {...props}>\r\n <path d=\"M4 7h10M18 7h2M4 17h2M10 17h10\" />\r\n <circle cx=\"16\" cy=\"7\" r=\"2\" />\r\n <circle cx=\"8\" cy=\"17\" r=\"2\" />\r\n </Svg>\r\n )\r\n}\r\n\r\n/** Mais ações (⋯), ex: o botão do Menu sem texto. */\r\nexport function MoreIcon(props: IconProps) {\r\n return (\r\n <Svg {...props} fill=\"currentColor\">\r\n <circle cx=\"5\" cy=\"12\" r=\"1.8\" />\r\n <circle cx=\"12\" cy=\"12\" r=\"1.8\" />\r\n <circle cx=\"19\" cy=\"12\" r=\"1.8\" />\r\n </Svg>\r\n )\r\n}\r\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { CheckIcon } from "../../../foundations/icons/icons.js";
|
|
3
|
+
const DEFAULT_STEPS_LABELS = {
|
|
4
|
+
done: "done",
|
|
5
|
+
error: "needs attention",
|
|
6
|
+
progress: "Step {current} of {total}"
|
|
7
|
+
};
|
|
8
|
+
function Steps({
|
|
9
|
+
items,
|
|
10
|
+
value,
|
|
11
|
+
onChange,
|
|
12
|
+
free = false,
|
|
13
|
+
label = "Steps",
|
|
14
|
+
labels,
|
|
15
|
+
className = ""
|
|
16
|
+
}) {
|
|
17
|
+
const L = { ...DEFAULT_STEPS_LABELS, ...labels };
|
|
18
|
+
const current = items.findIndex((s) => s.id === value);
|
|
19
|
+
const progress = L.progress.replace("{current}", String(current + 1)).replace("{total}", String(items.length));
|
|
20
|
+
return /* @__PURE__ */ jsxs("nav", { "aria-label": label, className, children: [
|
|
21
|
+
/* @__PURE__ */ jsx("p", { className: "m-0 mb-2 text-[10px] font-bold tracking-widest text-muted-foreground uppercase sm:hidden", "aria-hidden": true, children: progress }),
|
|
22
|
+
/* @__PURE__ */ jsx("ol", { className: "m-0 flex list-none items-center gap-2 p-0", children: items.map((s, i) => {
|
|
23
|
+
const isCurrent = i === current;
|
|
24
|
+
const clickable = !!onChange && !isCurrent && (free || !!s.done);
|
|
25
|
+
const circle = s.error ? "border-incumprido bg-incumprido text-white" : isCurrent ? "border-primary bg-primary text-primary-foreground dark:border-proef-blue dark:bg-proef-blue" : s.done ? "border-proef-turquoise bg-proef-turquoise text-proef-navy" : "border-border bg-card text-muted-foreground";
|
|
26
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
27
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: `inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full border-2 text-xs font-extrabold ${circle}`, children: s.error ? "!" : s.done && !isCurrent ? /* @__PURE__ */ jsx(CheckIcon, { size: 14, strokeWidth: 2.6 }) : i + 1 }),
|
|
28
|
+
/* @__PURE__ */ jsxs(
|
|
29
|
+
"span",
|
|
30
|
+
{
|
|
31
|
+
className: `text-xs font-bold whitespace-nowrap ${isCurrent ? "text-primary dark:text-foreground" : "text-muted-foreground max-sm:sr-only"}`,
|
|
32
|
+
children: [
|
|
33
|
+
s.label,
|
|
34
|
+
s.error && /* @__PURE__ */ jsxs("span", { className: "sr-only", children: [
|
|
35
|
+
" (",
|
|
36
|
+
L.error,
|
|
37
|
+
")"
|
|
38
|
+
] }),
|
|
39
|
+
s.done && !s.error && /* @__PURE__ */ jsxs("span", { className: "sr-only", children: [
|
|
40
|
+
" (",
|
|
41
|
+
L.done,
|
|
42
|
+
")"
|
|
43
|
+
] })
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
] });
|
|
48
|
+
return /* @__PURE__ */ jsxs("li", { className: `flex min-w-0 items-center gap-2 ${i < items.length - 1 ? "flex-1" : ""}`, "aria-current": isCurrent ? "step" : void 0, children: [
|
|
49
|
+
clickable ? /* @__PURE__ */ jsx(
|
|
50
|
+
"button",
|
|
51
|
+
{
|
|
52
|
+
type: "button",
|
|
53
|
+
onClick: () => onChange(s.id),
|
|
54
|
+
className: "flex cursor-pointer items-center gap-2 rounded-md border-0 bg-transparent p-0 hover:underline focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:outline-none",
|
|
55
|
+
children: content
|
|
56
|
+
}
|
|
57
|
+
) : /* @__PURE__ */ jsx("span", { className: "flex items-center gap-2", children: content }),
|
|
58
|
+
i < items.length - 1 && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: `h-0.5 min-w-3 flex-1 rounded-full ${s.done ? "bg-proef-turquoise" : "bg-border"}` })
|
|
59
|
+
] }, s.id);
|
|
60
|
+
}) })
|
|
61
|
+
] });
|
|
62
|
+
}
|
|
63
|
+
export {
|
|
64
|
+
DEFAULT_STEPS_LABELS,
|
|
65
|
+
Steps,
|
|
66
|
+
Steps as default
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=Steps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Steps.js","sources":["../../../../../../src/v1/primitives/navigation/Steps/Steps.tsx"],"sourcesContent":["import React from 'react'\r\nimport { CheckIcon } from '../../../foundations/icons/icons'\r\n\r\nexport interface StepItem<K extends string = string> {\r\n id: K\r\n /** Normalmente texto; aceita JSX. */\r\n label: React.ReactNode\r\n /** Passo já feito e válido (✓). */\r\n done?: boolean\r\n /** Passo com alguma coisa por corrigir (!). */\r\n error?: boolean\r\n}\r\n\r\nexport interface StepsLabels {\r\n /** Acrescentado ao nome de um passo feito, para leitores de ecrã. */\r\n done: string\r\n /** Acrescentado ao nome de um passo com erros, para leitores de ecrã. */\r\n error: string\r\n /** No telemóvel, por cima do passo atual: \"{current}\" e \"{total}\" são os números. */\r\n progress: string\r\n}\r\n\r\nexport const DEFAULT_STEPS_LABELS: StepsLabels = {\r\n done: 'done',\r\n error: 'needs attention',\r\n progress: 'Step {current} of {total}',\r\n}\r\n\r\nexport interface StepsProps<K extends string = string> {\r\n items: StepItem<K>[]\r\n /** O passo atual. A app guarda este estado. */\r\n value: K\r\n /** Sem isto, a barra só mostra onde se está (não se clica). */\r\n onChange?: (id: K) => void\r\n /**\r\n * Todos os passos clicáveis. Por omissão só os já feitos (para voltar atrás); num\r\n * registo que já existe (editar, consultar) pode fazer sentido saltar para qualquer um.\r\n */\r\n free?: boolean\r\n /** Nome da barra, para leitores de ecrã (ex: \"Atribuição de equipamento\"). */\r\n label?: string\r\n labels?: Partial<StepsLabels>\r\n className?: string\r\n}\r\n\r\n/**\r\n * Barra de passos de um fluxo em várias etapas (ex: Equipamentos → Colaborador →\r\n * Termo → Concluído): onde se está, o que já está feito e o que tem erros.\r\n *\r\n * Fica por cima do conteúdo do passo, numa página ou num\r\n * [Dialog](?path=/docs/v1-components-overlays-dialog--docs). Os botões Seguinte e\r\n * Anterior são da app (normalmente no fundo do passo).\r\n *\r\n * No telemóvel mostra os números e só o nome do passo atual.\r\n *\r\n * Substitui os `Passos` legacy.\r\n */\r\nexport default function Steps<K extends string = string>({\r\n items,\r\n value,\r\n onChange,\r\n free = false,\r\n label = 'Steps',\r\n labels,\r\n className = '',\r\n}: StepsProps<K>) {\r\n const L = { ...DEFAULT_STEPS_LABELS, ...labels }\r\n const current = items.findIndex((s) => s.id === value)\r\n const progress = L.progress.replace('{current}', String(current + 1)).replace('{total}', String(items.length))\r\n\r\n return (\r\n <nav aria-label={label} className={className}>\r\n <p className=\"m-0 mb-2 text-[10px] font-bold tracking-widest text-muted-foreground uppercase sm:hidden\" aria-hidden>\r\n {progress}\r\n </p>\r\n <ol className=\"m-0 flex list-none items-center gap-2 p-0\">\r\n {items.map((s, i) => {\r\n const isCurrent = i === current\r\n const clickable = !!onChange && !isCurrent && (free || !!s.done)\r\n const circle = s.error\r\n ? 'border-incumprido bg-incumprido text-white'\r\n : isCurrent\r\n ? 'border-primary bg-primary text-primary-foreground dark:border-proef-blue dark:bg-proef-blue'\r\n : s.done\r\n ? 'border-proef-turquoise bg-proef-turquoise text-proef-navy'\r\n : 'border-border bg-card text-muted-foreground'\r\n const content = (\r\n <>\r\n <span aria-hidden className={`inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full border-2 text-xs font-extrabold ${circle}`}>\r\n {s.error ? '!' : s.done && !isCurrent ? <CheckIcon size={14} strokeWidth={2.6} /> : i + 1}\r\n </span>\r\n <span\r\n className={`text-xs font-bold whitespace-nowrap ${isCurrent ? 'text-primary dark:text-foreground' : 'text-muted-foreground max-sm:sr-only'}`}\r\n >\r\n {s.label}\r\n {s.error && <span className=\"sr-only\"> ({L.error})</span>}\r\n {s.done && !s.error && <span className=\"sr-only\"> ({L.done})</span>}\r\n </span>\r\n </>\r\n )\r\n return (\r\n <li key={s.id} className={`flex min-w-0 items-center gap-2 ${i < items.length - 1 ? 'flex-1' : ''}`} aria-current={isCurrent ? 'step' : undefined}>\r\n {clickable ? (\r\n <button\r\n type=\"button\"\r\n onClick={() => onChange!(s.id)}\r\n className=\"flex cursor-pointer items-center gap-2 rounded-md border-0 bg-transparent p-0 hover:underline focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:outline-none\"\r\n >\r\n {content}\r\n </button>\r\n ) : (\r\n <span className=\"flex items-center gap-2\">{content}</span>\r\n )}\r\n {i < items.length - 1 && (\r\n <span aria-hidden className={`h-0.5 min-w-3 flex-1 rounded-full ${s.done ? 'bg-proef-turquoise' : 'bg-border'}`} />\r\n )}\r\n </li>\r\n )\r\n })}\r\n </ol>\r\n </nav>\r\n )\r\n}\r\n\r\nexport { Steps }\r\n"],"names":[],"mappings":";;AAsBO,MAAM,uBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AACZ;AA+BA,SAAwB,MAAiC;AAAA,EACvD;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AAAA,EACR;AAAA,EACA,YAAY;AACd,GAAkB;AAChB,QAAM,IAAI,EAAE,GAAG,sBAAsB,GAAG,OAAA;AACxC,QAAM,UAAU,MAAM,UAAU,CAAC,MAAM,EAAE,OAAO,KAAK;AACrD,QAAM,WAAW,EAAE,SAAS,QAAQ,aAAa,OAAO,UAAU,CAAC,CAAC,EAAE,QAAQ,WAAW,OAAO,MAAM,MAAM,CAAC;AAE7G,SACE,qBAAC,OAAA,EAAI,cAAY,OAAO,WACtB,UAAA;AAAA,IAAA,oBAAC,KAAA,EAAE,WAAU,4FAA2F,eAAW,MAChH,UAAA,UACH;AAAA,IACA,oBAAC,QAAG,WAAU,6CACX,gBAAM,IAAI,CAAC,GAAG,MAAM;AACnB,YAAM,YAAY,MAAM;AACxB,YAAM,YAAY,CAAC,CAAC,YAAY,CAAC,cAAc,QAAQ,CAAC,CAAC,EAAE;AAC3D,YAAM,SAAS,EAAE,QACb,+CACA,YACE,gGACA,EAAE,OACA,8DACA;AACR,YAAM,UACJ,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,eAAW,MAAC,WAAW,yGAAyG,MAAM,IACzI,UAAA,EAAE,QAAQ,MAAM,EAAE,QAAQ,CAAC,gCAAa,WAAA,EAAU,MAAM,IAAI,aAAa,IAAA,CAAK,IAAK,IAAI,EAAA,CAC1F;AAAA,QACA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAW,uCAAuC,YAAY,sCAAsC,sCAAsC;AAAA,YAEzI,UAAA;AAAA,cAAA,EAAE;AAAA,cACF,EAAE,SAAS,qBAAC,QAAA,EAAK,WAAU,WAAU,UAAA;AAAA,gBAAA;AAAA,gBAAG,EAAE;AAAA,gBAAM;AAAA,cAAA,GAAC;AAAA,cACjD,EAAE,QAAQ,CAAC,EAAE,SAAS,qBAAC,QAAA,EAAK,WAAU,WAAU,UAAA;AAAA,gBAAA;AAAA,gBAAG,EAAE;AAAA,gBAAK;AAAA,cAAA,EAAA,CAAC;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAC9D,GACF;AAEF,aACE,qBAAC,MAAA,EAAc,WAAW,mCAAmC,IAAI,MAAM,SAAS,IAAI,WAAW,EAAE,IAAI,gBAAc,YAAY,SAAS,QACrI,UAAA;AAAA,QAAA,YACC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,SAAU,EAAE,EAAE;AAAA,YAC7B,WAAU;AAAA,YAET,UAAA;AAAA,UAAA;AAAA,QAAA,IAGH,oBAAC,QAAA,EAAK,WAAU,2BAA2B,UAAA,SAAQ;AAAA,QAEpD,IAAI,MAAM,SAAS,yBACjB,QAAA,EAAK,eAAW,MAAC,WAAW,qCAAqC,EAAE,OAAO,uBAAuB,WAAW,GAAA,CAAI;AAAA,MAAA,EAAA,GAb5G,EAAE,EAeX;AAAA,IAEJ,CAAC,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;"}
|