@nextelco/common-ui 2.1.105 → 2.1.107

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/dist/esm/index.js +201 -145
  2. package/dist/esm/index.js.map +1 -1
  3. package/dist/esm/legacy/components/atoms/InputData/InputData.js +2 -13
  4. package/dist/esm/legacy/components/atoms/InputData/InputData.js.map +1 -1
  5. package/dist/esm/legacy/components/charts/Charts.js +147 -57
  6. package/dist/esm/legacy/components/charts/Charts.js.map +1 -1
  7. package/dist/esm/legacy/components/layout/Layout/Layout.js +21 -82
  8. package/dist/esm/legacy/components/layout/Layout/Layout.js.map +1 -1
  9. package/dist/esm/legacy/components/layout/Sidebar/Sidebar.js +29 -218
  10. package/dist/esm/legacy/components/layout/Sidebar/Sidebar.js.map +1 -1
  11. package/dist/esm/legacy/components/molecules/ColumnPicker/ColumnPicker.js +77 -10
  12. package/dist/esm/legacy/components/molecules/ColumnPicker/ColumnPicker.js.map +1 -1
  13. package/dist/esm/legacy/components/molecules/DataTable/DataTable.js +445 -337
  14. package/dist/esm/legacy/components/molecules/DataTable/DataTable.js.map +1 -1
  15. package/dist/esm/legacy/components/molecules/UserAvatar/UserAvatar.js +15 -97
  16. package/dist/esm/legacy/components/molecules/UserAvatar/UserAvatar.js.map +1 -1
  17. package/dist/esm/legacy/components/organisms/MapaPontos/MapaPontos.js +3 -3
  18. package/dist/esm/legacy/components/organisms/MapaPontos/MapaPontos.js.map +1 -1
  19. package/dist/esm/legacy/components/organisms/PainelFiltros/PainelFiltros.js +15 -3
  20. package/dist/esm/legacy/components/organisms/PainelFiltros/PainelFiltros.js.map +1 -1
  21. package/dist/esm/legacy/components/organisms/Selector/Selector.js +4 -4
  22. package/dist/esm/legacy/components/organisms/Selector/Selector.js.map +1 -1
  23. package/dist/esm/legacy/components/ui/Avisos.js +23 -76
  24. package/dist/esm/legacy/components/ui/Avisos.js.map +1 -1
  25. package/dist/esm/legacy/components/ui/CabecalhoPagina.js +14 -27
  26. package/dist/esm/legacy/components/ui/CabecalhoPagina.js.map +1 -1
  27. package/dist/esm/legacy/components/ui/CaixaPesquisa.js +3 -51
  28. package/dist/esm/legacy/components/ui/CaixaPesquisa.js.map +1 -1
  29. package/dist/esm/legacy/components/ui/Confirmacao.js +13 -31
  30. package/dist/esm/legacy/components/ui/Confirmacao.js.map +1 -1
  31. package/dist/esm/legacy/components/ui/Escolha.js +21 -137
  32. package/dist/esm/legacy/components/ui/Escolha.js.map +1 -1
  33. package/dist/esm/legacy/components/ui/FaixaAviso.js +13 -11
  34. package/dist/esm/legacy/components/ui/FaixaAviso.js.map +1 -1
  35. package/dist/esm/legacy/components/ui/Separadores.js +11 -46
  36. package/dist/esm/legacy/components/ui/Separadores.js.map +1 -1
  37. package/dist/esm/legacy/components/ui/Ui.js +18 -115
  38. package/dist/esm/legacy/components/ui/Ui.js.map +1 -1
  39. package/dist/esm/legacy/components/ui/painelFlutuante.js +5 -44
  40. package/dist/esm/legacy/components/ui/painelFlutuante.js.map +1 -1
  41. package/dist/esm/v1/capabilities/overlay/useFloatingPanel.js +52 -0
  42. package/dist/esm/v1/capabilities/overlay/useFloatingPanel.js.map +1 -0
  43. package/dist/esm/v1/capabilities/theme/useIsDark.js +15 -0
  44. package/dist/esm/v1/capabilities/theme/useIsDark.js.map +1 -0
  45. package/dist/esm/v1/capabilities/theme/useTheme.js +66 -0
  46. package/dist/esm/v1/capabilities/theme/useTheme.js.map +1 -0
  47. package/dist/esm/v1/components/data/Pagination/Pagination.js +66 -0
  48. package/dist/esm/v1/components/data/Pagination/Pagination.js.map +1 -0
  49. package/dist/esm/v1/components/feedback/Toast/Toast.js +105 -0
  50. package/dist/esm/v1/components/feedback/Toast/Toast.js.map +1 -0
  51. package/dist/esm/v1/components/forms/FormField/FormField.js.map +1 -1
  52. package/dist/esm/v1/components/forms/FormGrid/FormGrid.js.map +1 -1
  53. package/dist/esm/v1/components/layout/AppShell/AppShell.js +89 -0
  54. package/dist/esm/v1/components/layout/AppShell/AppShell.js.map +1 -0
  55. package/dist/esm/v1/components/layout/Page/Page.js +16 -0
  56. package/dist/esm/v1/components/layout/Page/Page.js.map +1 -0
  57. package/dist/esm/v1/components/layout/PageHeader/PageHeader.js +26 -0
  58. package/dist/esm/v1/components/layout/PageHeader/PageHeader.js.map +1 -0
  59. package/dist/esm/v1/components/layout/SideNav/SideNav.js +277 -0
  60. package/dist/esm/v1/components/layout/SideNav/SideNav.js.map +1 -0
  61. package/dist/esm/v1/components/layout/navTrail.js +19 -0
  62. package/dist/esm/v1/components/layout/navTrail.js.map +1 -0
  63. package/dist/esm/v1/components/lists/ListFinder/ListFinder.js +4 -4
  64. package/dist/esm/v1/components/lists/ListFinder/ListFinder.js.map +1 -1
  65. package/dist/esm/v1/components/overlays/ConfirmDialog/ConfirmDialog.js +95 -0
  66. package/dist/esm/v1/components/overlays/ConfirmDialog/ConfirmDialog.js.map +1 -0
  67. package/dist/esm/v1/components/overlays/Dialog/Dialog.js.map +1 -1
  68. package/dist/esm/v1/components/overlays/Tooltip/Tooltip.js +98 -0
  69. package/dist/esm/v1/components/overlays/Tooltip/Tooltip.js.map +1 -0
  70. package/dist/esm/v1/components/overlays/Tooltip/TooltipLayer.js +84 -0
  71. package/dist/esm/v1/components/overlays/Tooltip/TooltipLayer.js.map +1 -0
  72. package/dist/esm/v1/components/overlays/Tooltip/TooltipPanel.js +33 -0
  73. package/dist/esm/v1/components/overlays/Tooltip/TooltipPanel.js.map +1 -0
  74. package/dist/esm/v1/components/overlays/topLayer.js +28 -0
  75. package/dist/esm/v1/components/overlays/topLayer.js.map +1 -0
  76. package/dist/esm/v1/components/tables/PaginatedTable/PaginatedTable.js.map +1 -1
  77. package/dist/esm/v1/components/tables/Table/Table.js.map +1 -1
  78. package/dist/esm/v1/foundations/icons/icons.js +61 -2
  79. package/dist/esm/v1/foundations/icons/icons.js.map +1 -1
  80. package/dist/esm/v1/primitives/buttons/Button/Button.js +18 -4
  81. package/dist/esm/v1/primitives/buttons/Button/Button.js.map +1 -1
  82. package/dist/esm/v1/primitives/buttons/SegmentedControl/SegmentedControl.js +65 -0
  83. package/dist/esm/v1/primitives/buttons/SegmentedControl/SegmentedControl.js.map +1 -0
  84. package/dist/esm/v1/primitives/buttons/SegmentedControl/segmentedStyles.js +10 -0
  85. package/dist/esm/v1/primitives/buttons/SegmentedControl/segmentedStyles.js.map +1 -0
  86. package/dist/esm/v1/primitives/display/Avatar/Avatar.js +120 -0
  87. package/dist/esm/v1/primitives/display/Avatar/Avatar.js.map +1 -0
  88. package/dist/esm/v1/primitives/display/Badge/Badge.js +23 -0
  89. package/dist/esm/v1/primitives/display/Badge/Badge.js.map +1 -0
  90. package/dist/esm/v1/primitives/display/Card/Card.js +22 -0
  91. package/dist/esm/v1/primitives/display/Card/Card.js.map +1 -0
  92. package/dist/esm/v1/primitives/display/FilterChips/FilterChips.js +45 -0
  93. package/dist/esm/v1/primitives/display/FilterChips/FilterChips.js.map +1 -0
  94. package/dist/esm/v1/primitives/display/Kpi/Kpi.js +103 -0
  95. package/dist/esm/v1/primitives/display/Kpi/Kpi.js.map +1 -0
  96. package/dist/esm/v1/primitives/display/Notice/Notice.js +71 -0
  97. package/dist/esm/v1/primitives/display/Notice/Notice.js.map +1 -0
  98. package/dist/esm/v1/primitives/display/Person/Person.js +14 -0
  99. package/dist/esm/v1/primitives/display/Person/Person.js.map +1 -0
  100. package/dist/esm/v1/primitives/forms/Checkbox/Checkbox.js +10 -5
  101. package/dist/esm/v1/primitives/forms/Checkbox/Checkbox.js.map +1 -1
  102. package/dist/esm/v1/primitives/forms/DateInput/DateInput.js +150 -0
  103. package/dist/esm/v1/primitives/forms/DateInput/DateInput.js.map +1 -0
  104. package/dist/esm/v1/primitives/forms/LookupInput/LookupInput.js.map +1 -1
  105. package/dist/esm/v1/primitives/forms/SearchInput/SearchInput.js +43 -0
  106. package/dist/esm/v1/primitives/forms/SearchInput/SearchInput.js.map +1 -0
  107. package/dist/esm/v1/primitives/forms/SelectInput/SelectInput.js +190 -12
  108. package/dist/esm/v1/primitives/forms/SelectInput/SelectInput.js.map +1 -1
  109. package/dist/esm/v1/primitives/forms/TextArea/TextArea.js.map +1 -1
  110. package/dist/esm/v1/primitives/forms/field.js +4 -2
  111. package/dist/esm/v1/primitives/forms/field.js.map +1 -1
  112. package/dist/esm/v1/primitives/lists/ListItem/ListItem.js +2 -2
  113. package/dist/esm/v1/primitives/lists/ListItem/ListItem.js.map +1 -1
  114. package/dist/esm/v1/primitives/navigation/Tabs/Tabs.js +96 -0
  115. package/dist/esm/v1/primitives/navigation/Tabs/Tabs.js.map +1 -0
  116. package/dist/style.components.css +1 -1
  117. package/dist/style.css +1 -1
  118. package/dist/style.layered.css +1 -1
  119. package/dist/tailwind.css +24 -0
  120. package/dist/theme-boot.js +1 -0
  121. package/dist/theme.css +10 -3
  122. package/dist/tokens.css +119 -0
  123. package/dist/types/legacy/components/atoms/InputData/InputData.d.ts +4 -1
  124. package/dist/types/legacy/components/charts/Charts.d.ts +58 -5
  125. package/dist/types/legacy/components/layout/Layout/Layout.d.ts +7 -20
  126. package/dist/types/legacy/components/layout/Sidebar/Sidebar.d.ts +13 -26
  127. package/dist/types/legacy/components/molecules/ColumnPicker/ColumnPicker.d.ts +56 -3
  128. package/dist/types/legacy/components/molecules/DataTable/DataTable.d.ts +72 -7
  129. package/dist/types/legacy/components/molecules/UserAvatar/UserAvatar.d.ts +4 -5
  130. package/dist/types/legacy/components/ui/Avisos.d.ts +6 -16
  131. package/dist/types/legacy/components/ui/CabecalhoPagina.d.ts +6 -20
  132. package/dist/types/legacy/components/ui/CaixaPesquisa.d.ts +2 -4
  133. package/dist/types/legacy/components/ui/Confirmacao.d.ts +3 -10
  134. package/dist/types/legacy/components/ui/Escolha.d.ts +5 -15
  135. package/dist/types/legacy/components/ui/FaixaAviso.d.ts +2 -6
  136. package/dist/types/legacy/components/ui/Separadores.d.ts +3 -10
  137. package/dist/types/legacy/components/ui/Ui.d.ts +12 -54
  138. package/dist/types/legacy/components/ui/painelFlutuante.d.ts +6 -10
  139. package/dist/types/legacy/exports/atoms.d.ts +1 -1
  140. package/dist/types/legacy/exports/charts.d.ts +2 -2
  141. package/dist/types/legacy/exports/hooks.d.ts +2 -2
  142. package/dist/types/legacy/exports/molecules.d.ts +2 -2
  143. package/dist/types/v1/capabilities/overlay/useFloatingPanel.d.ts +20 -0
  144. package/dist/types/v1/capabilities/theme/useIsDark.d.ts +10 -0
  145. package/dist/types/v1/capabilities/theme/useTheme.d.ts +29 -0
  146. package/dist/types/v1/components/data/Pagination/Pagination.d.ts +33 -0
  147. package/dist/types/v1/components/feedback/Toast/Toast.d.ts +51 -0
  148. package/dist/types/v1/components/forms/FormField/FormField.d.ts +3 -3
  149. package/dist/types/v1/components/forms/FormGrid/FormGrid.d.ts +2 -0
  150. package/dist/types/v1/components/layout/AppShell/AppShell.d.ts +35 -0
  151. package/dist/types/v1/components/layout/Page/Page.d.ts +23 -0
  152. package/dist/types/v1/components/layout/PageHeader/PageHeader.d.ts +35 -0
  153. package/dist/types/v1/components/layout/SideNav/SideNav.d.ts +92 -0
  154. package/dist/types/v1/components/layout/navTrail.d.ts +15 -0
  155. package/dist/types/v1/components/lists/ListFinder/ListFinder.d.ts +1 -1
  156. package/dist/types/v1/components/overlays/ConfirmDialog/ConfirmDialog.d.ts +59 -0
  157. package/dist/types/v1/components/overlays/Dialog/Dialog.d.ts +6 -3
  158. package/dist/types/v1/components/overlays/Tooltip/Tooltip.d.ts +34 -0
  159. package/dist/types/v1/components/overlays/Tooltip/TooltipLayer.d.ts +18 -0
  160. package/dist/types/v1/components/overlays/Tooltip/TooltipPanel.d.ts +23 -0
  161. package/dist/types/v1/components/overlays/topLayer.d.ts +23 -0
  162. package/dist/types/v1/components/tables/PaginatedTable/PaginatedTable.d.ts +1 -1
  163. package/dist/types/v1/components/tables/Table/Table.d.ts +1 -1
  164. package/dist/types/v1/foundations/icons/icons.d.ts +20 -0
  165. package/dist/types/v1/index.d.ts +43 -1
  166. package/dist/types/v1/primitives/buttons/Button/Button.d.ts +22 -5
  167. package/dist/types/v1/primitives/buttons/SegmentedControl/SegmentedControl.d.ts +28 -0
  168. package/dist/types/v1/primitives/buttons/SegmentedControl/segmentedStyles.d.ts +16 -0
  169. package/dist/types/v1/primitives/display/Avatar/Avatar.d.ts +30 -0
  170. package/dist/types/v1/primitives/display/Badge/Badge.d.ts +25 -0
  171. package/dist/types/v1/primitives/display/Card/Card.d.ts +22 -0
  172. package/dist/types/v1/primitives/display/FilterChips/FilterChips.d.ts +33 -0
  173. package/dist/types/v1/primitives/display/Kpi/Kpi.d.ts +68 -0
  174. package/dist/types/v1/primitives/display/Notice/Notice.d.ts +29 -0
  175. package/dist/types/v1/primitives/display/Person/Person.d.ts +15 -0
  176. package/dist/types/v1/primitives/forms/Checkbox/Checkbox.d.ts +7 -0
  177. package/dist/types/v1/primitives/forms/DateInput/DateInput.d.ts +43 -0
  178. package/dist/types/v1/primitives/forms/LookupInput/LookupInput.d.ts +3 -0
  179. package/dist/types/v1/primitives/forms/SearchInput/SearchInput.d.ts +23 -0
  180. package/dist/types/v1/primitives/forms/SelectInput/SelectInput.d.ts +61 -10
  181. package/dist/types/v1/primitives/forms/TextArea/TextArea.d.ts +3 -0
  182. package/dist/types/v1/primitives/forms/field.d.ts +2 -0
  183. package/dist/types/v1/primitives/lists/ListItem/ListItem.d.ts +2 -1
  184. package/dist/types/v1/primitives/navigation/Tabs/Tabs.d.ts +58 -0
  185. package/package.json +3 -3
  186. package/dist/esm/legacy/components/atoms/Tooltip/Tooltip.css +0 -17
  187. package/dist/esm/legacy/components/atoms/Tooltip/Tooltip.js +0 -41
  188. package/dist/esm/legacy/components/atoms/Tooltip/Tooltip.js.map +0 -1
  189. package/dist/esm/legacy/components/molecules/Search/Search.css +0 -18
  190. package/dist/esm/legacy/components/molecules/Search/Search.js +0 -30
  191. package/dist/esm/legacy/components/molecules/Search/Search.js.map +0 -1
  192. package/dist/esm/legacy/hooks/useTheme.js +0 -39
  193. package/dist/esm/legacy/hooks/useTheme.js.map +0 -1
  194. package/dist/esm/v1/primitives/lists/ListItem/ListCheckbox.js +0 -28
  195. package/dist/esm/v1/primitives/lists/ListItem/ListCheckbox.js.map +0 -1
  196. package/dist/types/legacy/components/atoms/Tooltip/Tooltip.d.ts +0 -13
  197. package/dist/types/legacy/components/molecules/Search/Search.d.ts +0 -7
  198. package/dist/types/legacy/hooks/useTheme.d.ts +0 -17
  199. package/dist/types/v1/primitives/lists/ListItem/ListCheckbox.d.ts +0 -14
@@ -1,9 +1,5 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { useMemo, useState, useRef, useEffect } from "react";
3
- import { createPortal } from "react-dom";
4
- import { usePainelFlutuante, CLS_PAINEL, clsItem } from "./painelFlutuante.js";
5
- const Chevron = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-3.5 w-3.5 shrink-0 text-slate-400", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" }) });
6
- const Visto = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-4 w-4 shrink-0 text-proef-blue dark:text-sky-300", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) });
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { SelectInput } from "../../../v1/primitives/forms/SelectInput/SelectInput.js";
7
3
  function Escolha({
8
4
  valor,
9
5
  opcoes,
@@ -16,140 +12,28 @@ function Escolha({
16
12
  className,
17
13
  tamanho = "barra",
18
14
  aspeto = "campo",
19
- corEtiqueta = "bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-200"
15
+ corEtiqueta
20
16
  }) {
21
17
  const etiqueta = aspeto === "etiqueta";
22
- const p = usePainelFlutuante("esquerda");
23
- const lista = useMemo(() => {
24
- const base = opcoes.map((o) => typeof o === "string" ? { valor: o, rotulo: o } : o);
25
- return opcaoVazia !== void 0 ? [{ valor: "", rotulo: opcaoVazia }, ...base] : base;
26
- }, [opcoes, opcaoVazia]);
27
- const [q, setQ] = useState("");
28
- const comPesquisa = pesquisa ?? lista.length > 10;
29
- const visiveis = useMemo(() => {
30
- const t = q.trim().toLowerCase();
31
- return t ? lista.filter((o) => o.rotulo.toLowerCase().includes(t) || o.descricao?.toLowerCase().includes(t)) : lista;
32
- }, [lista, q]);
33
- const [ativo, setAtivo] = useState(0);
34
- const refPesquisa = useRef(null);
35
- const escolhida = lista.find((o) => o.valor === valor);
36
- useEffect(() => {
37
- if (!p.aberto) return;
38
- setQ("");
39
- setAtivo(Math.max(0, lista.findIndex((o) => o.valor === valor)));
40
- if (comPesquisa) setTimeout(() => refPesquisa.current?.focus(), 0);
41
- }, [p.aberto]);
42
- useEffect(() => {
43
- if (p.aberto) p.refPainel.current?.querySelector(`[data-indice="${ativo}"]`)?.scrollIntoView?.({ block: "nearest" });
44
- }, [ativo, p.aberto, p.refPainel]);
45
- const escolher = (o) => {
46
- p.fechar();
47
- p.refBotao.current?.focus();
48
- if (o.valor !== valor) onMudar(o.valor);
49
- };
50
- const teclado = (e) => {
51
- if (!p.aberto) {
52
- if (["ArrowDown", "ArrowUp", "Enter", " "].includes(e.key)) {
53
- e.preventDefault();
54
- p.setAberto(true);
55
- }
56
- return;
18
+ return /* @__PURE__ */ jsx(
19
+ SelectInput,
20
+ {
21
+ "aria-label": rotulo,
22
+ value: valor,
23
+ onValueChange: onMudar,
24
+ options: opcoes.map((o) => typeof o === "string" ? o : { value: o.valor, label: o.rotulo, description: o.descricao }),
25
+ placeholder,
26
+ placeholderOption: false,
27
+ emptyOption: opcaoVazia,
28
+ disabled,
29
+ searchable: pesquisa,
30
+ variant: etiqueta ? "pill" : "field",
31
+ pillClassName: corEtiqueta,
32
+ tall: tamanho === "formulario",
33
+ labels: { search: "Pesquisar…", searchIn: "Pesquisar em {label}", noResults: "Sem resultados" },
34
+ className: `inline-block ${className ?? (etiqueta ? "" : "min-w-[10rem] max-w-[18rem]")}`
57
35
  }
58
- if (e.key === "Escape") {
59
- e.preventDefault();
60
- e.stopPropagation();
61
- p.fechar();
62
- p.refBotao.current?.focus();
63
- } else if (e.key === "ArrowDown") {
64
- e.preventDefault();
65
- setAtivo((i) => Math.min(visiveis.length - 1, i + 1));
66
- } else if (e.key === "ArrowUp") {
67
- e.preventDefault();
68
- setAtivo((i) => Math.max(0, i - 1));
69
- } else if (e.key === "Home") {
70
- e.preventDefault();
71
- setAtivo(0);
72
- } else if (e.key === "End") {
73
- e.preventDefault();
74
- setAtivo(visiveis.length - 1);
75
- } else if (e.key === "Enter") {
76
- e.preventDefault();
77
- const o = visiveis[ativo];
78
- if (o) escolher(o);
79
- } else if (e.key === "Tab") {
80
- p.fechar();
81
- } else if (!comPesquisa && e.key.length === 1) {
82
- const i = visiveis.findIndex((o) => o.rotulo.toLowerCase().startsWith(e.key.toLowerCase()));
83
- if (i >= 0) setAtivo(i);
84
- }
85
- };
86
- return /* @__PURE__ */ jsxs("div", { className: `relative inline-block ${className ?? (etiqueta ? "" : "min-w-[10rem] max-w-[18rem]")}`, onKeyDown: teclado, children: [
87
- /* @__PURE__ */ jsxs(
88
- "button",
89
- {
90
- ref: p.refBotao,
91
- type: "button",
92
- disabled,
93
- "aria-haspopup": "listbox",
94
- "aria-expanded": p.aberto,
95
- "aria-label": rotulo,
96
- onClick: (e) => {
97
- e.stopPropagation();
98
- p.setAberto((a) => !a);
99
- },
100
- className: etiqueta ? `appearance-none cursor-pointer border-0 inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-bold whitespace-nowrap transition hover:brightness-95 focus:outline-none focus-visible:ring-2 focus-visible:ring-proef-blue disabled:cursor-not-allowed disabled:opacity-50 ${corEtiqueta}` : `appearance-none cursor-pointer w-full ${tamanho === "formulario" ? "h-[38px] px-3" : "h-8 px-2.5"} inline-flex items-center justify-between gap-2 rounded-lg border border-slate-300 bg-white text-sm text-slate-800 transition hover:border-slate-400 focus:outline-none focus-visible:ring-2 focus-visible:ring-proef-blue disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100 dark:hover:border-slate-500`,
101
- children: [
102
- /* @__PURE__ */ jsx("span", { className: `truncate ${escolhida || etiqueta ? "" : "text-slate-400 dark:text-slate-500"}`, children: escolhida?.rotulo ?? placeholder }),
103
- etiqueta ? /* @__PURE__ */ jsx("span", { className: "opacity-60", children: /* @__PURE__ */ jsx(Chevron, {}) }) : /* @__PURE__ */ jsx(Chevron, {})
104
- ]
105
- }
106
- ),
107
- p.aberto && createPortal(
108
- /* @__PURE__ */ jsxs("div", { ref: p.refPainel, style: p.estilo, className: CLS_PAINEL, onClick: (e) => e.stopPropagation(), onKeyDown: teclado, children: [
109
- comPesquisa && /* @__PURE__ */ jsx("div", { className: "px-2 pb-1 pt-0.5", children: /* @__PURE__ */ jsx(
110
- "input",
111
- {
112
- ref: refPesquisa,
113
- type: "search",
114
- value: q,
115
- onChange: (e) => {
116
- setQ(e.target.value);
117
- setAtivo(0);
118
- },
119
- placeholder: "Pesquisar…",
120
- "aria-label": `Pesquisar em ${rotulo}`,
121
- 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"
122
- }
123
- ) }),
124
- /* @__PURE__ */ jsxs("ul", { role: "listbox", "aria-label": rotulo, children: [
125
- visiveis.length === 0 && /* @__PURE__ */ jsx("li", { className: "px-3 py-2 text-slate-400", children: "Sem resultados" }),
126
- visiveis.map((o, i) => {
127
- const sel = o.valor === valor;
128
- return /* @__PURE__ */ jsxs(
129
- "li",
130
- {
131
- role: "option",
132
- "aria-selected": sel,
133
- "data-indice": i,
134
- onMouseEnter: () => setAtivo(i),
135
- onClick: () => escolher(o),
136
- className: clsItem(i === ativo),
137
- children: [
138
- /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
139
- /* @__PURE__ */ jsx("span", { className: `block truncate ${sel ? "font-semibold" : ""} ${o.valor === "" && opcaoVazia !== void 0 ? "text-slate-500 dark:text-slate-400" : ""}`, children: o.rotulo }),
140
- o.descricao && /* @__PURE__ */ jsx("span", { className: "block truncate text-[11px] text-slate-500 dark:text-slate-400", children: o.descricao })
141
- ] }),
142
- /* @__PURE__ */ jsx("span", { className: "w-4 shrink-0", children: sel && /* @__PURE__ */ jsx(Visto, {}) })
143
- ]
144
- },
145
- o.valor || "__vazia"
146
- );
147
- })
148
- ] })
149
- ] }),
150
- document.body
151
- )
152
- ] });
36
+ );
153
37
  }
154
38
  export {
155
39
  Escolha as default
@@ -1 +1 @@
1
- {"version":3,"file":"Escolha.js","sources":["../../../../../src/legacy/components/ui/Escolha.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from 'react'\r\nimport { createPortal } from 'react-dom'\r\nimport { CLS_PAINEL, clsItem, usePainelFlutuante } from './painelFlutuante'\r\n\r\nexport interface OpcaoEscolha {\r\n valor: string\r\n rotulo: string\r\n /** Texto pequeno por baixo do rótulo, na lista. */\r\n descricao?: string\r\n}\r\n\r\nexport interface EscolhaProps {\r\n valor: string\r\n /** Opções: texto simples (valor = rótulo) ou { valor, rotulo, descricao }. */\r\n opcoes: readonly string[] | readonly OpcaoEscolha[]\r\n onMudar: (valor: string) => void\r\n /** Nome acessível (leitores de ecrã). */\r\n rotulo: string\r\n /** Texto do botão sem nada escolhido. */\r\n placeholder?: string\r\n /**\r\n * Primeira opção \"vazia\" (valor ''), para desfazer a escolha (ex.: \"Todas\"). Sem isto não há como voltar atrás\r\n * depois de escolher.\r\n */\r\n opcaoVazia?: string\r\n disabled?: boolean\r\n /** Caixa de pesquisa no topo da lista. Por omissão, só com mais de 10 opções. */\r\n pesquisa?: boolean\r\n /** Largura (classes tailwind). Por omissão a do conteúdo, entre 10rem e 18rem (etiqueta: a do texto). */\r\n className?: string\r\n /**\r\n * 'barra' (omissão): h-8, como os botões e filtros das barras. 'formulario': a altura dos campos de texto dos\r\n * formulários (px-3 py-2), para alinhar com eles.\r\n */\r\n tamanho?: 'barra' | 'formulario'\r\n /**\r\n * 'campo' (omissão) ou 'etiqueta': o botão é uma etiqueta arredondada (ex.: o estado numa linha de tabela), com\r\n * as cores de `corEtiqueta`. A lista é a mesma.\r\n */\r\n aspeto?: 'campo' | 'etiqueta'\r\n /** Classes de cor da etiqueta (fundo, texto e variante dark:), normalmente conforme o valor escolhido. */\r\n corEtiqueta?: string\r\n}\r\n\r\nconst Chevron = () => (\r\n <svg viewBox=\"0 0 24 24\" className=\"h-3.5 w-3.5 shrink-0 text-slate-400\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n)\r\nconst Visto = () => (\r\n <svg viewBox=\"0 0 24 24\" className=\"h-4 w-4 shrink-0 text-proef-blue dark:text-sky-300\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\r\n <path d=\"M20 6 9 17l-5-5\" />\r\n </svg>\r\n)\r\n\r\n/**\r\n * Lista suspensa para escolher um valor (substitui o `<select>` nativo, que abre com o aspeto do sistema e não\r\n * segue o tema). Mesma altura e cantos dos botões e campos (h-8, rounded-lg); a lista tem o mesmo aspeto do\r\n * MenuAcoes. Teclado: ↑/↓, Home/End, Enter escolhe, Esc fecha; ao escrever com a lista aberta salta para a opção.\r\n */\r\nexport default function Escolha({\r\n valor,\r\n opcoes,\r\n onMudar,\r\n rotulo,\r\n placeholder = 'Escolher…',\r\n opcaoVazia,\r\n disabled = false,\r\n pesquisa,\r\n className,\r\n tamanho = 'barra',\r\n aspeto = 'campo',\r\n corEtiqueta = 'bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-200',\r\n}: EscolhaProps) {\r\n const etiqueta = aspeto === 'etiqueta'\r\n const p = usePainelFlutuante('esquerda')\r\n const lista = useMemo<OpcaoEscolha[]>(() => {\r\n const base = opcoes.map((o) => (typeof o === 'string' ? { valor: o, rotulo: o } : o))\r\n return opcaoVazia !== undefined ? [{ valor: '', rotulo: opcaoVazia }, ...base] : base\r\n }, [opcoes, opcaoVazia])\r\n const [q, setQ] = useState('')\r\n const comPesquisa = pesquisa ?? lista.length > 10\r\n const visiveis = useMemo(() => {\r\n const t = q.trim().toLowerCase()\r\n return t ? lista.filter((o) => o.rotulo.toLowerCase().includes(t) || o.descricao?.toLowerCase().includes(t)) : lista\r\n }, [lista, q])\r\n const [ativo, setAtivo] = useState(0)\r\n const refPesquisa = useRef<HTMLInputElement>(null)\r\n const escolhida = lista.find((o) => o.valor === valor)\r\n\r\n // Ao abrir: limpa a pesquisa e põe o teclado na opção escolhida.\r\n useEffect(() => {\r\n if (!p.aberto) return\r\n setQ('')\r\n setAtivo(Math.max(0, lista.findIndex((o) => o.valor === valor)))\r\n if (comPesquisa) setTimeout(() => refPesquisa.current?.focus(), 0)\r\n }, [p.aberto]) // eslint-disable-line react-hooks/exhaustive-deps\r\n\r\n // O item ativo fica sempre à vista ao navegar com o teclado.\r\n useEffect(() => {\r\n if (p.aberto) p.refPainel.current?.querySelector<HTMLElement>(`[data-indice=\"${ativo}\"]`)?.scrollIntoView?.({ block: 'nearest' })\r\n }, [ativo, p.aberto, p.refPainel])\r\n\r\n const escolher = (o: OpcaoEscolha) => {\r\n p.fechar()\r\n p.refBotao.current?.focus()\r\n if (o.valor !== valor) onMudar(o.valor)\r\n }\r\n\r\n const teclado = (e: React.KeyboardEvent) => {\r\n if (!p.aberto) {\r\n if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(e.key)) {\r\n e.preventDefault()\r\n p.setAberto(true)\r\n }\r\n return\r\n }\r\n if (e.key === 'Escape') {\r\n e.preventDefault()\r\n e.stopPropagation()\r\n p.fechar()\r\n p.refBotao.current?.focus()\r\n } else if (e.key === 'ArrowDown') {\r\n e.preventDefault()\r\n setAtivo((i) => Math.min(visiveis.length - 1, i + 1))\r\n } else if (e.key === 'ArrowUp') {\r\n e.preventDefault()\r\n setAtivo((i) => Math.max(0, i - 1))\r\n } else if (e.key === 'Home') {\r\n e.preventDefault()\r\n setAtivo(0)\r\n } else if (e.key === 'End') {\r\n e.preventDefault()\r\n setAtivo(visiveis.length - 1)\r\n } else if (e.key === 'Enter') {\r\n e.preventDefault()\r\n const o = visiveis[ativo]\r\n if (o) escolher(o)\r\n } else if (e.key === 'Tab') {\r\n p.fechar()\r\n } else if (!comPesquisa && e.key.length === 1) {\r\n // Sem caixa de pesquisa: a letra salta para a primeira opção que começa por ela.\r\n const i = visiveis.findIndex((o) => o.rotulo.toLowerCase().startsWith(e.key.toLowerCase()))\r\n if (i >= 0) setAtivo(i)\r\n }\r\n }\r\n\r\n return (\r\n <div className={`relative inline-block ${className ?? (etiqueta ? '' : 'min-w-[10rem] max-w-[18rem]')}`} onKeyDown={teclado}>\r\n <button\r\n ref={p.refBotao}\r\n type=\"button\"\r\n disabled={disabled}\r\n aria-haspopup=\"listbox\"\r\n aria-expanded={p.aberto}\r\n aria-label={rotulo}\r\n onClick={(e) => {\r\n // Dentro de uma linha clicável (tabelas), abrir a lista não abre a linha.\r\n e.stopPropagation()\r\n p.setAberto((a) => !a)\r\n }}\r\n className={\r\n etiqueta\r\n ? `appearance-none cursor-pointer border-0 inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-bold whitespace-nowrap transition hover:brightness-95 focus:outline-none focus-visible:ring-2 focus-visible:ring-proef-blue disabled:cursor-not-allowed disabled:opacity-50 ${corEtiqueta}`\r\n : `appearance-none cursor-pointer w-full ${tamanho === 'formulario' ? 'h-[38px] px-3' : 'h-8 px-2.5'} inline-flex items-center justify-between gap-2 rounded-lg border border-slate-300 bg-white text-sm text-slate-800 transition hover:border-slate-400 focus:outline-none focus-visible:ring-2 focus-visible:ring-proef-blue disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100 dark:hover:border-slate-500`\r\n }\r\n >\r\n <span className={`truncate ${escolhida || etiqueta ? '' : 'text-slate-400 dark:text-slate-500'}`}>{escolhida?.rotulo ?? placeholder}</span>\r\n {etiqueta ? <span className=\"opacity-60\"><Chevron /></span> : <Chevron />}\r\n </button>\r\n {p.aberto &&\r\n createPortal(\r\n <div ref={p.refPainel} style={p.estilo} className={CLS_PAINEL} onClick={(e) => e.stopPropagation()} onKeyDown={teclado}>\r\n {comPesquisa && (\r\n <div className=\"px-2 pb-1 pt-0.5\">\r\n <input\r\n ref={refPesquisa}\r\n type=\"search\"\r\n value={q}\r\n onChange={(e) => {\r\n setQ(e.target.value)\r\n setAtivo(0)\r\n }}\r\n placeholder=\"Pesquisar…\"\r\n aria-label={`Pesquisar em ${rotulo}`}\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 <ul role=\"listbox\" aria-label={rotulo}>\r\n {visiveis.length === 0 && <li className=\"px-3 py-2 text-slate-400\">Sem resultados</li>}\r\n {visiveis.map((o, i) => {\r\n const sel = o.valor === valor\r\n return (\r\n <li\r\n key={o.valor || '__vazia'}\r\n role=\"option\"\r\n aria-selected={sel}\r\n data-indice={i}\r\n onMouseEnter={() => setAtivo(i)}\r\n onClick={() => escolher(o)}\r\n className={clsItem(i === ativo)}\r\n >\r\n <span className=\"min-w-0 flex-1\">\r\n <span className={`block truncate ${sel ? 'font-semibold' : ''} ${o.valor === '' && opcaoVazia !== undefined ? 'text-slate-500 dark:text-slate-400' : ''}`}>{o.rotulo}</span>\r\n {o.descricao && <span className=\"block truncate text-[11px] text-slate-500 dark:text-slate-400\">{o.descricao}</span>}\r\n </span>\r\n <span className=\"w-4 shrink-0\">{sel && <Visto />}</span>\r\n </li>\r\n )\r\n })}\r\n </ul>\r\n </div>,\r\n document.body\r\n )}\r\n </div>\r\n )\r\n}\r\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Escolha.js","sources":["../../../../../src/legacy/components/ui/Escolha.tsx"],"sourcesContent":["import React from 'react'\r\nimport SelectInput from '../../../v1/primitives/forms/SelectInput/SelectInput'\r\n\r\nexport interface OpcaoEscolha {\r\n valor: string\r\n rotulo: string\r\n /** Texto pequeno por baixo do rótulo, na lista. */\r\n descricao?: string\r\n}\r\n\r\nexport interface EscolhaProps {\r\n valor: string\r\n /** Opções: texto simples (valor = rótulo) ou { valor, rotulo, descricao }. */\r\n opcoes: readonly string[] | readonly OpcaoEscolha[]\r\n onMudar: (valor: string) => void\r\n /** Nome acessível (leitores de ecrã). */\r\n rotulo: string\r\n /** Texto do botão sem nada escolhido. */\r\n placeholder?: string\r\n /** Primeira opção \"vazia\" (valor ''), para desfazer a escolha (ex.: \"Todas\"). */\r\n opcaoVazia?: string\r\n disabled?: boolean\r\n /** Caixa de pesquisa no topo da lista. Por omissão, só com mais de 10 opções. */\r\n pesquisa?: boolean\r\n /** Largura (classes tailwind). Por omissão a do conteúdo, entre 10rem e 18rem (etiqueta: a do texto). */\r\n className?: string\r\n /** 'barra' (omissão): a altura dos botões e filtros. 'formulario': a altura dos campos dos formulários legacy (38px). */\r\n tamanho?: 'barra' | 'formulario'\r\n /** 'campo' (omissão) ou 'etiqueta': o botão é uma etiqueta arredondada, com as cores de `corEtiqueta`. */\r\n aspeto?: 'campo' | 'etiqueta'\r\n /** Classes de cor da etiqueta (fundo, texto e variante dark:), normalmente conforme o valor escolhido. */\r\n corEtiqueta?: string\r\n}\r\n\r\n/**\r\n * Migrado para o V1: adaptador do `SelectInput` (a mesma lista desenhada, nomes antigos e textos em português).\r\n * @deprecated Legacy — usar o `SelectInput` do V1. Ver Storybook › Legacy.\r\n */\r\nexport default function Escolha({\r\n valor,\r\n opcoes,\r\n onMudar,\r\n rotulo,\r\n placeholder = 'Escolher…',\r\n opcaoVazia,\r\n disabled = false,\r\n pesquisa,\r\n className,\r\n tamanho = 'barra',\r\n aspeto = 'campo',\r\n corEtiqueta,\r\n}: EscolhaProps) {\r\n const etiqueta = aspeto === 'etiqueta'\r\n return (\r\n <SelectInput\r\n aria-label={rotulo}\r\n value={valor}\r\n onValueChange={onMudar}\r\n options={opcoes.map((o) => (typeof o === 'string' ? o : { value: o.valor, label: o.rotulo, description: o.descricao }))}\r\n placeholder={placeholder}\r\n placeholderOption={false}\r\n emptyOption={opcaoVazia}\r\n disabled={disabled}\r\n searchable={pesquisa}\r\n variant={etiqueta ? 'pill' : 'field'}\r\n pillClassName={corEtiqueta}\r\n tall={tamanho === 'formulario'}\r\n labels={{ search: 'Pesquisar…', searchIn: 'Pesquisar em {label}', noResults: 'Sem resultados' }}\r\n className={`inline-block ${className ?? (etiqueta ? '' : 'min-w-[10rem] max-w-[18rem]')}`}\r\n />\r\n )\r\n}\r\n"],"names":[],"mappings":";;AAsCA,SAAwB,QAAQ;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,SAAS;AAAA,EACT;AACF,GAAiB;AACf,QAAM,WAAW,WAAW;AAC5B,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,cAAY;AAAA,MACZ,OAAO;AAAA,MACP,eAAe;AAAA,MACf,SAAS,OAAO,IAAI,CAAC,MAAO,OAAO,MAAM,WAAW,IAAI,EAAE,OAAO,EAAE,OAAO,OAAO,EAAE,QAAQ,aAAa,EAAE,WAAY;AAAA,MACtH;AAAA,MACA,mBAAmB;AAAA,MACnB,aAAa;AAAA,MACb;AAAA,MACA,YAAY;AAAA,MACZ,SAAS,WAAW,SAAS;AAAA,MAC7B,eAAe;AAAA,MACf,MAAM,YAAY;AAAA,MAClB,QAAQ,EAAE,QAAQ,cAAc,UAAU,wBAAwB,WAAW,iBAAA;AAAA,MAC7E,WAAW,gBAAgB,cAAc,WAAW,KAAK,8BAA8B;AAAA,IAAA;AAAA,EAAA;AAG7F;"}
@@ -1,15 +1,17 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Notice } from "../../../v1/primitives/display/Notice/Notice.js";
3
+ const TOM = { aviso: "warning", info: "info", erro: "error" };
2
4
  function FaixaAviso({ children, tom = "aviso", acao, icone }) {
3
- const cores = {
4
- aviso: "bg-amber-100 text-amber-950 border-amber-300",
5
- info: "bg-sky-50 text-sky-900 border-sky-200",
6
- erro: "bg-incumprido-bg text-incumprido border-incumprido/30"
7
- };
8
- return /* @__PURE__ */ jsxs("div", { role: tom === "erro" ? "alert" : "status", className: `flex flex-wrap items-center gap-x-3 gap-y-1 border-b px-4 py-2 text-xs font-bold ${cores[tom]}`, children: [
9
- icone && /* @__PURE__ */ jsx("span", { className: "shrink-0", children: icone }),
10
- /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", children }),
11
- acao && /* @__PURE__ */ jsx("button", { type: "button", onClick: acao.onClick, className: "shrink-0 rounded-md uppercase tracking-widest underline underline-offset-2 hover:no-underline", children: acao.rotulo })
12
- ] });
5
+ return /* @__PURE__ */ jsx(
6
+ Notice,
7
+ {
8
+ variant: "banner",
9
+ tone: TOM[tom],
10
+ icon: icone ?? null,
11
+ action: acao ? { label: acao.rotulo, onClick: acao.onClick } : void 0,
12
+ children
13
+ }
14
+ );
13
15
  }
14
16
  export {
15
17
  FaixaAviso as default
@@ -1 +1 @@
1
- {"version":3,"file":"FaixaAviso.js","sources":["../../../../../src/legacy/components/ui/FaixaAviso.tsx"],"sourcesContent":["import React, { type ReactNode } from 'react'\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport type TomFaixa = 'aviso' | 'info' | 'erro'\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport interface FaixaAvisoProps {\r\n children: ReactNode\r\n tom?: TomFaixa\r\n /** Ação à direita (ex: \"Voltar ao meu perfil\" no \"Ver como\"). */\r\n acao?: { rotulo: ReactNode; onClick: () => void }\r\n icone?: ReactNode\r\n}\r\n\r\n/**\r\n * Faixa no topo do conteúdo para um estado que afeta a página inteira: \"Ver\r\n * como\" outro perfil, um serviço externo em baixo, dados possivelmente\r\n * incompletos. Não é para resultados de ações — esses são avisos (`useAvisos`).\r\n *\r\n * Fica bem no slot `topBar` do Layout.\r\n * @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy.\r\n */\r\nexport default function FaixaAviso({ children, tom = 'aviso', acao, icone }: FaixaAvisoProps) {\r\n const cores: Record<TomFaixa, string> = {\r\n aviso: 'bg-amber-100 text-amber-950 border-amber-300',\r\n info: 'bg-sky-50 text-sky-900 border-sky-200',\r\n erro: 'bg-incumprido-bg text-incumprido border-incumprido/30',\r\n }\r\n return (\r\n <div role={tom === 'erro' ? 'alert' : 'status'} className={`flex flex-wrap items-center gap-x-3 gap-y-1 border-b px-4 py-2 text-xs font-bold ${cores[tom]}`}>\r\n {icone && <span className=\"shrink-0\">{icone}</span>}\r\n <span className=\"min-w-0 flex-1\">{children}</span>\r\n {acao && (\r\n <button type=\"button\" onClick={acao.onClick} className=\"shrink-0 rounded-md uppercase tracking-widest underline underline-offset-2 hover:no-underline\">\r\n {acao.rotulo}\r\n </button>\r\n )}\r\n </div>\r\n )\r\n}\r\n"],"names":[],"mappings":";AAsBA,SAAwB,WAAW,EAAE,UAAU,MAAM,SAAS,MAAM,SAA0B;AAC5F,QAAM,QAAkC;AAAA,IACtC,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,EAAA;AAER,SACE,qBAAC,OAAA,EAAI,MAAM,QAAQ,SAAS,UAAU,UAAU,WAAW,oFAAoF,MAAM,GAAG,CAAC,IACtJ,UAAA;AAAA,IAAA,SAAS,oBAAC,QAAA,EAAK,WAAU,YAAY,UAAA,OAAM;AAAA,IAC5C,oBAAC,QAAA,EAAK,WAAU,kBAAkB,SAAA,CAAS;AAAA,IAC1C,QACC,oBAAC,UAAA,EAAO,MAAK,UAAS,SAAS,KAAK,SAAS,WAAU,iGACpD,UAAA,KAAK,OAAA,CACR;AAAA,EAAA,GAEJ;AAEJ;"}
1
+ {"version":3,"file":"FaixaAviso.js","sources":["../../../../../src/legacy/components/ui/FaixaAviso.tsx"],"sourcesContent":["import React, { type ReactNode } from 'react'\r\nimport Notice from '../../../v1/primitives/display/Notice/Notice'\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport type TomFaixa = 'aviso' | 'info' | 'erro'\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport interface FaixaAvisoProps {\r\n children: ReactNode\r\n tom?: TomFaixa\r\n /** Ação à direita (ex: \"Voltar ao meu perfil\" no \"Ver como\"). */\r\n acao?: { rotulo: ReactNode; onClick: () => void }\r\n icone?: ReactNode\r\n}\r\n\r\nconst TOM: Record<TomFaixa, 'warning' | 'info' | 'error'> = { aviso: 'warning', info: 'info', erro: 'error' }\r\n\r\n/**\r\n * Migrado para o V1: adaptador do `Notice` com `variant=\"banner\"` (faixa no topo da página).\r\n * @deprecated Legacy — usar o `Notice` do V1. Ver Storybook › Legacy.\r\n */\r\nexport default function FaixaAviso({ children, tom = 'aviso', acao, icone }: FaixaAvisoProps) {\r\n return (\r\n <Notice\r\n variant=\"banner\"\r\n tone={TOM[tom]}\r\n icon={icone ?? null}\r\n action={acao ? { label: acao.rotulo, onClick: acao.onClick } : undefined}\r\n >\r\n {children}\r\n </Notice>\r\n )\r\n}\r\n"],"names":[],"mappings":";;AAeA,MAAM,MAAsD,EAAE,OAAO,WAAW,MAAM,QAAQ,MAAM,QAAA;AAMpG,SAAwB,WAAW,EAAE,UAAU,MAAM,SAAS,MAAM,SAA0B;AAC5F,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,SAAQ;AAAA,MACR,MAAM,IAAI,GAAG;AAAA,MACb,MAAM,SAAS;AAAA,MACf,QAAQ,OAAO,EAAE,OAAO,KAAK,QAAQ,SAAS,KAAK,QAAA,IAAY;AAAA,MAE9D;AAAA,IAAA;AAAA,EAAA;AAGP;"}
@@ -1,50 +1,15 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { useRef } from "react";
1
+ import { jsx } from "react/jsx-runtime";
2
+ import Tabs from "../../../v1/primitives/navigation/Tabs/Tabs.js";
3
3
  function Separadores({ itens, ativo, onMudar, rotulo }) {
4
- const refs = useRef([]);
5
- const ativos = itens.map((it, i) => ({ it, i })).filter((x) => !x.it.desativado);
6
- const teclas = (e, indice) => {
7
- const pos = ativos.findIndex((x) => x.i === indice);
8
- let destino = null;
9
- if (e.key === "ArrowRight") destino = ativos[(pos + 1) % ativos.length].i;
10
- else if (e.key === "ArrowLeft") destino = ativos[(pos - 1 + ativos.length) % ativos.length].i;
11
- else if (e.key === "Home") destino = ativos[0].i;
12
- else if (e.key === "End") destino = ativos[ativos.length - 1].i;
13
- if (destino === null) return;
14
- e.preventDefault();
15
- onMudar(itens[destino].id);
16
- refs.current[destino]?.focus();
17
- };
18
- return /* @__PURE__ */ jsx("div", { role: "tablist", "aria-label": rotulo, className: "flex flex-wrap border-b border-slate-200 dark:border-slate-700", children: itens.map((it, i) => {
19
- const sel = it.id === ativo;
20
- return /* @__PURE__ */ jsxs(
21
- "button",
22
- {
23
- ref: (el) => {
24
- refs.current[i] = el;
25
- },
26
- type: "button",
27
- role: "tab",
28
- "aria-selected": sel,
29
- tabIndex: sel ? 0 : -1,
30
- disabled: it.desativado,
31
- onClick: () => onMudar(it.id),
32
- onKeyDown: (e) => teclas(e, i),
33
- className: `-mb-px inline-flex items-center gap-2 border-b-[3px] px-4 py-3 text-xs font-black uppercase tracking-wider transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${sel ? "border-proef-navy text-proef-navy dark:border-slate-100 dark:text-slate-100" : "border-transparent text-slate-500 hover:text-proef-navy dark:text-slate-400 dark:hover:text-slate-100"}`,
34
- children: [
35
- it.rotulo,
36
- it.contagem != null && /* @__PURE__ */ jsx(
37
- "span",
38
- {
39
- className: `rounded-full px-2 py-px text-[11px] font-extrabold tracking-normal ${sel ? "bg-proef-navy text-white dark:bg-proef-blue" : "bg-slate-200 text-slate-700 dark:bg-slate-700 dark:text-slate-200"}`,
40
- children: it.contagem
41
- }
42
- )
43
- ]
44
- },
45
- it.id
46
- );
47
- }) });
4
+ return /* @__PURE__ */ jsx(
5
+ Tabs,
6
+ {
7
+ items: itens.map((it) => ({ id: it.id, label: it.rotulo, count: it.contagem ?? void 0, disabled: it.desativado })),
8
+ value: ativo,
9
+ onChange: onMudar,
10
+ label: rotulo
11
+ }
12
+ );
48
13
  }
49
14
  export {
50
15
  Separadores as default
@@ -1 +1 @@
1
- {"version":3,"file":"Separadores.js","sources":["../../../../../src/legacy/components/ui/Separadores.tsx"],"sourcesContent":["import React, { useRef, type ReactNode, type KeyboardEvent } from 'react'\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport interface Separador<T extends string> {\r\n id: T\r\n rotulo: ReactNode\r\n /** Número à frente do rótulo (ex: faturas por mapear). Omitir quando não interessa. */\r\n contagem?: number\r\n desativado?: boolean\r\n}\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport interface SeparadoresProps<T extends string> {\r\n itens: Separador<T>[]\r\n ativo: T\r\n onMudar: (id: T) => void\r\n /** Rótulo acessível do conjunto (ex: \"Estado das faturas\"). */\r\n rotulo?: string\r\n}\r\n\r\n/**\r\n * Separadores de uma página, iguais em todo o portal.\r\n *\r\n * O ativo fica a navy com sublinhado (não turquesa: turquesa sobre branco não\r\n * tem contraste para texto). Setas esquerda/direita, Home e End mudam de\r\n * separador, como num tablist normal.\r\n * @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy.\r\n */\r\nexport default function Separadores<T extends string>({ itens, ativo, onMudar, rotulo }: SeparadoresProps<T>) {\r\n const refs = useRef<(HTMLButtonElement | null)[]>([])\r\n const ativos = itens.map((it, i) => ({ it, i })).filter((x) => !x.it.desativado)\r\n\r\n const teclas = (e: KeyboardEvent<HTMLButtonElement>, indice: number): void => {\r\n const pos = ativos.findIndex((x) => x.i === indice)\r\n let destino: number | null = null\r\n if (e.key === 'ArrowRight') destino = ativos[(pos + 1) % ativos.length]!.i\r\n else if (e.key === 'ArrowLeft') destino = ativos[(pos - 1 + ativos.length) % ativos.length]!.i\r\n else if (e.key === 'Home') destino = ativos[0]!.i\r\n else if (e.key === 'End') destino = ativos[ativos.length - 1]!.i\r\n if (destino === null) return\r\n e.preventDefault()\r\n onMudar(itens[destino]!.id)\r\n refs.current[destino]?.focus()\r\n }\r\n\r\n return (\r\n <div role=\"tablist\" aria-label={rotulo} className=\"flex flex-wrap border-b border-slate-200 dark:border-slate-700\">\r\n {itens.map((it, i) => {\r\n const sel = it.id === ativo\r\n return (\r\n <button\r\n key={it.id}\r\n ref={(el) => {\r\n refs.current[i] = el\r\n }}\r\n type=\"button\"\r\n role=\"tab\"\r\n aria-selected={sel}\r\n tabIndex={sel ? 0 : -1}\r\n disabled={it.desativado}\r\n onClick={() => onMudar(it.id)}\r\n onKeyDown={(e) => teclas(e, i)}\r\n className={`-mb-px inline-flex items-center gap-2 border-b-[3px] px-4 py-3 text-xs font-black uppercase tracking-wider transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${\r\n sel\r\n ? 'border-proef-navy text-proef-navy dark:border-slate-100 dark:text-slate-100'\r\n : 'border-transparent text-slate-500 hover:text-proef-navy dark:text-slate-400 dark:hover:text-slate-100'\r\n }`}\r\n >\r\n {it.rotulo}\r\n {it.contagem != null && (\r\n <span\r\n className={`rounded-full px-2 py-px text-[11px] font-extrabold tracking-normal ${\r\n sel ? 'bg-proef-navy text-white dark:bg-proef-blue' : 'bg-slate-200 text-slate-700 dark:bg-slate-700 dark:text-slate-200'\r\n }`}\r\n >\r\n {it.contagem}\r\n </span>\r\n )}\r\n </button>\r\n )\r\n })}\r\n </div>\r\n )\r\n}\r\n"],"names":[],"mappings":";;AA4BA,SAAwB,YAA8B,EAAE,OAAO,OAAO,SAAS,UAA+B;AAC5G,QAAM,OAAO,OAAqC,EAAE;AACpD,QAAM,SAAS,MAAM,IAAI,CAAC,IAAI,OAAO,EAAE,IAAI,EAAA,EAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU;AAE/E,QAAM,SAAS,CAAC,GAAqC,WAAyB;AAC5E,UAAM,MAAM,OAAO,UAAU,CAAC,MAAM,EAAE,MAAM,MAAM;AAClD,QAAI,UAAyB;AAC7B,QAAI,EAAE,QAAQ,aAAc,WAAU,QAAQ,MAAM,KAAK,OAAO,MAAM,EAAG;AAAA,aAChE,EAAE,QAAQ,YAAa,WAAU,QAAQ,MAAM,IAAI,OAAO,UAAU,OAAO,MAAM,EAAG;AAAA,aACpF,EAAE,QAAQ,OAAQ,WAAU,OAAO,CAAC,EAAG;AAAA,aACvC,EAAE,QAAQ,MAAO,WAAU,OAAO,OAAO,SAAS,CAAC,EAAG;AAC/D,QAAI,YAAY,KAAM;AACtB,MAAE,eAAA;AACF,YAAQ,MAAM,OAAO,EAAG,EAAE;AAC1B,SAAK,QAAQ,OAAO,GAAG,MAAA;AAAA,EACzB;AAEA,SACE,oBAAC,OAAA,EAAI,MAAK,WAAU,cAAY,QAAQ,WAAU,kEAC/C,UAAA,MAAM,IAAI,CAAC,IAAI,MAAM;AACpB,UAAM,MAAM,GAAG,OAAO;AACtB,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,KAAK,CAAC,OAAO;AACX,eAAK,QAAQ,CAAC,IAAI;AAAA,QACpB;AAAA,QACA,MAAK;AAAA,QACL,MAAK;AAAA,QACL,iBAAe;AAAA,QACf,UAAU,MAAM,IAAI;AAAA,QACpB,UAAU,GAAG;AAAA,QACb,SAAS,MAAM,QAAQ,GAAG,EAAE;AAAA,QAC5B,WAAW,CAAC,MAAM,OAAO,GAAG,CAAC;AAAA,QAC7B,WAAW,gLACT,MACI,gFACA,uGACN;AAAA,QAEC,UAAA;AAAA,UAAA,GAAG;AAAA,UACH,GAAG,YAAY,QACd;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW,sEACT,MAAM,gDAAgD,mEACxD;AAAA,cAEC,UAAA,GAAG;AAAA,YAAA;AAAA,UAAA;AAAA,QACN;AAAA,MAAA;AAAA,MAzBG,GAAG;AAAA,IAAA;AAAA,EA6Bd,CAAC,EAAA,CACH;AAEJ;"}
1
+ {"version":3,"file":"Separadores.js","sources":["../../../../../src/legacy/components/ui/Separadores.tsx"],"sourcesContent":["import React, { type ReactNode } from 'react'\r\nimport Tabs from '../../../v1/primitives/navigation/Tabs/Tabs'\r\n\r\n/*\r\n * Migrado para o V1: os separadores são o `Tabs` do V1. Este ficheiro só\r\n * traduz a API antiga (em português) para a nova, para as apps que ainda a\r\n * usam continuarem a funcionar sem mudanças.\r\n */\r\n\r\n/** @deprecated Legacy — usar `TabItem` do V1. */\r\nexport interface Separador<T extends string> {\r\n id: T\r\n rotulo: ReactNode\r\n /** Número à frente do rótulo (ex: faturas por mapear). Omitir quando não interessa. */\r\n contagem?: number\r\n desativado?: boolean\r\n}\r\n\r\n/** @deprecated Legacy — usar `TabsProps` do V1. */\r\nexport interface SeparadoresProps<T extends string> {\r\n itens: Separador<T>[]\r\n ativo: T\r\n onMudar: (id: T) => void\r\n /** Rótulo acessível do conjunto (ex: \"Estado das faturas\"). */\r\n rotulo?: string\r\n}\r\n\r\n/** @deprecated Legacy — usar `Tabs` do V1. */\r\nexport default function Separadores<T extends string>({ itens, ativo, onMudar, rotulo }: SeparadoresProps<T>) {\r\n return (\r\n <Tabs<T>\r\n items={itens.map((it) => ({ id: it.id, label: it.rotulo, count: it.contagem ?? undefined, disabled: it.desativado }))}\r\n value={ativo}\r\n onChange={onMudar}\r\n label={rotulo}\r\n />\r\n )\r\n}\r\n"],"names":[],"mappings":";;AA4BA,SAAwB,YAA8B,EAAE,OAAO,OAAO,SAAS,UAA+B;AAC5G,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO,MAAM,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,OAAO,GAAG,QAAQ,OAAO,GAAG,YAAY,QAAW,UAAU,GAAG,aAAa;AAAA,MACpH,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO;AAAA,IAAA;AAAA,EAAA;AAGb;"}
@@ -1,5 +1,8 @@
1
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import Escolha from "./Escolha.js";
3
+ import SegmentedControl from "../../../v1/primitives/buttons/SegmentedControl/SegmentedControl.js";
4
+ import Button from "../../../v1/primitives/buttons/Button/Button.js";
5
+ import { Badge } from "../../../v1/primitives/display/Badge/Badge.js";
3
6
  function IconX({ className = "" }) {
4
7
  return /* @__PURE__ */ jsxs(
5
8
  "svg",
@@ -19,15 +22,6 @@ function IconX({ className = "" }) {
19
22
  }
20
23
  );
21
24
  }
22
- function Card({ title, extra, children, className = "" }) {
23
- return /* @__PURE__ */ jsxs("div", { className: `bg-white border border-slate-200 dark:bg-slate-900 dark:border-slate-700 rounded-xl p-4 sm:p-5 ${className}`, children: [
24
- (title || extra) && /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3 mb-3.5", children: [
25
- title && /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold dark:text-slate-100", children: title }),
26
- extra
27
- ] }),
28
- children
29
- ] });
30
- }
31
25
  function SectionGroup({
32
26
  title,
33
27
  tone = "accent",
@@ -47,97 +41,6 @@ function SectionGroup({
47
41
  children
48
42
  ] });
49
43
  }
50
- function Kpi({
51
- label,
52
- value,
53
- tone = "default",
54
- delta,
55
- onClick,
56
- bgTint = false,
57
- active = false,
58
- hint,
59
- dot,
60
- barra,
61
- rodape,
62
- denso = false
63
- }) {
64
- const cores = {
65
- default: "text-slate-800 dark:text-slate-100",
66
- brand: "text-proef-blue dark:text-sky-300",
67
- ok: "text-ok",
68
- risco: "text-risco",
69
- incumprido: "text-incumprido"
70
- };
71
- const fundos = {
72
- default: "bg-white border-slate-200 dark:bg-slate-900 dark:border-slate-700",
73
- brand: "bg-proef-blue/10 border-transparent dark:bg-sky-500/15",
74
- ok: "bg-ok-bg border-transparent",
75
- risco: "bg-risco-bg border-transparent",
76
- incumprido: "bg-incumprido-bg border-transparent"
77
- };
78
- const base = denso ? `relative border rounded-lg px-2.5 py-1.5 flex flex-col justify-center text-left gap-0.5 ${bgTint ? fundos[tone] : "bg-white border-slate-200 dark:bg-slate-900 dark:border-slate-700"}` : `relative border rounded-xl px-4 py-3 min-h-[88px] flex flex-col items-center justify-center text-center gap-1.5 ${bgTint ? fundos[tone] : "bg-white border-slate-200 dark:bg-slate-900 dark:border-slate-700"}`;
79
- const totalBarra = Array.isArray(barra) ? barra.reduce((s, x) => s + x.peso, 0) : 0;
80
- const conteudo = /* @__PURE__ */ jsxs(Fragment, { children: [
81
- /* @__PURE__ */ jsxs("div", { className: `${denso ? "text-[10px] uppercase tracking-wide" : "text-xs"} text-slate-500 dark:text-slate-400 flex items-center gap-1.5`, children: [
82
- dot && /* @__PURE__ */ jsx("i", { className: "w-2 h-2 rounded-full inline-block shrink-0", style: { background: dot } }),
83
- /* @__PURE__ */ jsx("span", { className: "truncate", children: label })
84
- ] }),
85
- /* @__PURE__ */ jsxs("div", { className: denso ? "flex items-baseline gap-1.5" : "", children: [
86
- /* @__PURE__ */ jsx("span", { className: `${denso ? "text-xl" : "text-2xl"} font-semibold ${cores[tone]}`, children: value }),
87
- delta && /* @__PURE__ */ jsx("span", { className: `${denso ? "text-[11px]" : "hidden"} text-slate-400 truncate`, children: delta })
88
- ] }),
89
- delta && !denso && /* @__PURE__ */ jsx("div", { className: "text-[11.5px] text-slate-400", children: delta }),
90
- barra != null && /* @__PURE__ */ jsx("div", { className: "w-full h-1 bg-slate-100 dark:bg-slate-800 rounded overflow-hidden flex", children: Array.isArray(barra) ? barra.map((x, i) => /* @__PURE__ */ jsx(
91
- "i",
92
- {
93
- style: { width: totalBarra ? `${x.peso / totalBarra * 100}%` : 0, background: x.cor }
94
- },
95
- i
96
- )) : /* @__PURE__ */ jsx("i", { style: { width: `${Math.min(100, Math.max(0, barra))}%`, background: "currentColor" }, className: cores[tone] }) }),
97
- rodape && /* @__PURE__ */ jsx("div", { className: "text-[11px] text-slate-400", children: rodape })
98
- ] });
99
- if (!onClick) return /* @__PURE__ */ jsx("div", { className: base, children: conteudo });
100
- return /* @__PURE__ */ jsxs(
101
- "button",
102
- {
103
- type: "button",
104
- onClick,
105
- title: hint,
106
- "aria-pressed": active,
107
- className: `${base} w-full cursor-pointer shadow-sm transition hover:-translate-y-0.5 hover:border-proef-blue dark:hover:border-sky-400 hover:shadow-md focus:outline-none focus-visible:ring-2 focus-visible:ring-proef-blue ${active ? "ring-2 ring-proef-blue border-proef-blue" : ""}`,
108
- children: [
109
- /* @__PURE__ */ jsx(
110
- "svg",
111
- {
112
- "aria-hidden": true,
113
- viewBox: "0 0 24 24",
114
- className: `absolute right-2.5 top-2.5 h-3.5 w-3.5 ${active ? "text-proef-blue dark:text-sky-300" : "text-slate-300 dark:text-slate-600"}`,
115
- fill: "none",
116
- stroke: "currentColor",
117
- strokeWidth: 2,
118
- strokeLinecap: "round",
119
- strokeLinejoin: "round",
120
- children: /* @__PURE__ */ jsx("path", { d: "M3 4h18l-7 8.5V19l-4 2v-8.5L3 4z" })
121
- }
122
- ),
123
- conteudo
124
- ]
125
- }
126
- );
127
- }
128
- function Badge({ tone = "neutral", children }) {
129
- const cores = {
130
- ok: "bg-ok-bg text-ok",
131
- risco: "bg-risco-bg text-risco",
132
- incumprido: "bg-incumprido-bg text-incumprido",
133
- neutral: "bg-neutral-bg text-neutral",
134
- accent: "bg-proef-blue/10 text-proef-navy dark:bg-sky-500/15 dark:text-sky-300"
135
- };
136
- return /* @__PURE__ */ jsxs("span", { className: `inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium whitespace-nowrap ${cores[tone]}`, children: [
137
- /* @__PURE__ */ jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-current" }),
138
- children
139
- ] });
140
- }
141
44
  function BadgeSla({ status, labels }) {
142
45
  const tone = status === "ok" ? "ok" : status === "risco" ? "risco" : "incumprido";
143
46
  const defaults = { ok: "On time", risco: "At risk", incumprido: "Breached" };
@@ -161,6 +64,7 @@ function ChipEstadoInterno({ estado }) {
161
64
  if (!cor) return /* @__PURE__ */ jsx("span", { children: estado });
162
65
  return /* @__PURE__ */ jsx("span", { className: "px-2 py-0.5 rounded text-[11px] font-medium inline-block", style: { color: cor[0], background: cor[1] }, children: estado });
163
66
  }
67
+ const VARIANTE_V1 = { default: "secondary", accent: "primary", danger: "danger", ghost: "ghost" };
164
68
  function Btn({
165
69
  children,
166
70
  onClick,
@@ -170,14 +74,18 @@ function Btn({
170
74
  title,
171
75
  type = "button"
172
76
  }) {
173
- const base = "inline-flex items-center justify-center gap-1.5 h-8 px-3.5 rounded-lg text-[11px] font-black uppercase tracking-widest transition-colors disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap";
174
- const variantes = {
175
- default: active ? "bg-proef-navy text-white border border-proef-navy dark:bg-proef-blue dark:border-proef-blue" : "bg-white text-slate-500 border border-slate-200 hover:border-proef-navy hover:text-proef-navy dark:bg-slate-800 dark:text-slate-300 dark:border-slate-700 dark:hover:border-slate-400 dark:hover:text-white",
176
- accent: "bg-proef-navy text-white border border-proef-navy hover:bg-proef-blue dark:bg-proef-blue dark:border-proef-blue dark:hover:bg-sky-500",
177
- danger: "bg-incumprido text-white border border-incumprido hover:opacity-90 dark:bg-red-600 dark:border-red-600",
178
- ghost: "text-slate-500 hover:text-proef-navy dark:text-slate-400 dark:hover:text-white"
179
- };
180
- return /* @__PURE__ */ jsx("button", { type, onClick, disabled, title, className: `${base} ${variantes[variant]}`, children });
77
+ return /* @__PURE__ */ jsx(
78
+ Button,
79
+ {
80
+ type,
81
+ onClick,
82
+ disabled,
83
+ title,
84
+ variant: VARIANTE_V1[variant],
85
+ active: variant === "default" && active ? true : void 0,
86
+ children
87
+ }
88
+ );
181
89
  }
182
90
  function BtnGroup({
183
91
  value,
@@ -185,10 +93,7 @@ function BtnGroup({
185
93
  onChange,
186
94
  label
187
95
  }) {
188
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-wrap", children: [
189
- label && /* @__PURE__ */ jsx("span", { className: "text-[10px] font-black uppercase tracking-wider text-slate-400 shrink-0 whitespace-nowrap leading-normal", children: label }),
190
- /* @__PURE__ */ jsx("div", { className: "flex gap-1.5 flex-wrap", children: options.map((o) => /* @__PURE__ */ jsx(Btn, { active: value === o.value, onClick: () => onChange(o.value), children: o.label }, o.value)) })
191
- ] });
96
+ return /* @__PURE__ */ jsx(SegmentedControl, { value, options, onChange, label });
192
97
  }
193
98
  function Estado({
194
99
  carregando,
@@ -348,10 +253,8 @@ export {
348
253
  CampoInterruptor,
349
254
  CampoPesquisa,
350
255
  CampoSelect,
351
- Card,
352
256
  ChipEstadoInterno,
353
257
  Estado,
354
- Kpi,
355
258
  LinhaAlerta,
356
259
  ListaCampos,
357
260
  Modal,