@aspprev/versi-ds 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  useBreakpoint
3
- } from "./chunk-CSQXTG32.js";
3
+ } from "./chunk-FTRF27XF.js";
4
4
  import {
5
5
  __objRest,
6
6
  __spreadProps,
@@ -1807,76 +1807,6 @@ function FilterBar(_a) {
1807
1807
  );
1808
1808
  }
1809
1809
 
1810
- // src/components/status-badge/StatusBadge.tsx
1811
- import classNames12 from "classnames";
1812
- import { jsx as jsx27 } from "react/jsx-runtime";
1813
- var TONE_STYLES2 = {
1814
- info: {
1815
- outline: "border-feedback-info-border text-feedback-info-content",
1816
- soft: "border-feedback-info-border bg-feedback-info-soft text-feedback-info-content",
1817
- solid: "border-feedback-info-strong bg-feedback-info-strong text-surface-subtle"
1818
- },
1819
- warning: {
1820
- outline: "border-feedback-warning-border text-feedback-warning-content",
1821
- soft: "border-feedback-warning-border bg-feedback-warning-soft text-feedback-warning-content",
1822
- solid: "border-feedback-warning-strong bg-feedback-warning-strong text-surface-subtle"
1823
- },
1824
- success: {
1825
- outline: "border-feedback-success-border text-feedback-success-content",
1826
- soft: "border-feedback-success-border bg-feedback-success-soft text-feedback-success-content",
1827
- solid: "border-feedback-success-strong bg-feedback-success-strong text-surface-subtle"
1828
- },
1829
- danger: {
1830
- outline: "border-feedback-danger-border text-feedback-danger-content",
1831
- soft: "border-feedback-danger-border bg-feedback-danger-soft text-feedback-danger-content",
1832
- solid: "border-feedback-danger-strong bg-feedback-danger-strong text-surface-subtle"
1833
- },
1834
- neutral: {
1835
- outline: "border-border-strong text-content-secondary",
1836
- soft: "border-border-default bg-surface-subtle text-content-secondary",
1837
- solid: "border-surface-action-neutral bg-surface-action-neutral text-surface-subtle"
1838
- }
1839
- };
1840
- var SIZE_STYLES = {
1841
- sm: "min-h-5 px-1 py-0.5 text-xs",
1842
- md: "min-h-6 px-2 py-0.5 text-sm"
1843
- };
1844
- function StatusBadge(_a) {
1845
- var _b = _a, {
1846
- children,
1847
- tone = "neutral",
1848
- appearance = "outline",
1849
- size = "md",
1850
- overflow = "wrap",
1851
- className,
1852
- title
1853
- } = _b, rest = __objRest(_b, [
1854
- "children",
1855
- "tone",
1856
- "appearance",
1857
- "size",
1858
- "overflow",
1859
- "className",
1860
- "title"
1861
- ]);
1862
- return /* @__PURE__ */ jsx27(
1863
- "span",
1864
- __spreadProps(__spreadValues({
1865
- className: classNames12(
1866
- "inline-flex w-fit max-w-full items-center justify-center rounded-sm border-2 text-center font-bold uppercase tracking-wide",
1867
- SIZE_STYLES[size],
1868
- TONE_STYLES2[tone][appearance],
1869
- overflow === "truncate" ? "overflow-hidden text-ellipsis whitespace-nowrap" : "whitespace-normal break-words",
1870
- className
1871
- ),
1872
- title: title != null ? title : typeof children === "string" ? children : void 0
1873
- }, rest), {
1874
- children
1875
- })
1876
- );
1877
- }
1878
- var getStatusBadgeClassName = (tone, appearance) => TONE_STYLES2[tone][appearance];
1879
-
1880
1810
  // src/utils/resolve-status-appearance.ts
1881
1811
  var NORMALIZED_STATUS = {
1882
1812
  infoOutline: /* @__PURE__ */ new Set(["ABERTO", "PAGO", "EM PAGAMENTO"]),
@@ -1932,9 +1862,16 @@ var resolveGenericStatus = (status) => {
1932
1862
  }
1933
1863
  return { tone: "neutral", appearance: "outline" };
1934
1864
  };
1935
- var resolveStatusAppearance = (status, domain = "generic") => {
1865
+ var resolveStatusAppearance = (status, domain = "generic", options) => {
1866
+ var _a, _b, _c;
1936
1867
  const normalized = normalizeStatus(status);
1937
- if (!normalized) return { tone: "neutral", appearance: "outline" };
1868
+ if (!normalized) {
1869
+ return (_a = options == null ? void 0 : options.fallback) != null ? _a : { tone: "neutral", appearance: "outline" };
1870
+ }
1871
+ const mappedAppearance = (options == null ? void 0 : options.map) ? (_b = Object.entries(options.map).find(
1872
+ ([key]) => normalizeStatus(key) === normalized
1873
+ )) == null ? void 0 : _b[1] : void 0;
1874
+ if (mappedAppearance) return mappedAppearance;
1938
1875
  if (domain === "beneficiary") {
1939
1876
  if (normalized === "VIGENTE") return { tone: "success", appearance: "solid" };
1940
1877
  if (normalized === "ENCERRADO") return { tone: "neutral", appearance: "solid" };
@@ -1960,8 +1897,106 @@ var resolveStatusAppearance = (status, domain = "generic") => {
1960
1897
  if (domain === "participation") {
1961
1898
  return { tone: "neutral", appearance: "solid" };
1962
1899
  }
1963
- return resolveGenericStatus(normalized);
1900
+ if (domain === "payment") {
1901
+ if (["PAGO", "QUITADO", "LIBERADO"].includes(normalized)) {
1902
+ return { tone: "success", appearance: "solid" };
1903
+ }
1904
+ if (["EM PAGAMENTO", "AGUARDANDO PAGAMENTO"].includes(normalized)) {
1905
+ return { tone: "info", appearance: "outline" };
1906
+ }
1907
+ if (["VENCIDO", "ESTORNADO", "FALHOU"].includes(normalized)) {
1908
+ return { tone: "danger", appearance: "solid" };
1909
+ }
1910
+ }
1911
+ if (domain === "claim" || domain === "request" || domain === "protocol") {
1912
+ if (["RECEBIDO", "PROTOCOLADO", "EMITIDO"].includes(normalized)) {
1913
+ return { tone: "info", appearance: "outline" };
1914
+ }
1915
+ if (["EM ANALISE", "AGUARDANDO DOCUMENTACAO", "AGUARDANDO ANALISE"].includes(normalized)) {
1916
+ return { tone: "warning", appearance: "soft" };
1917
+ }
1918
+ if (["APROVADO", "CONCEDIDO", "ATENDIDO"].includes(normalized)) {
1919
+ return { tone: "success", appearance: "solid" };
1920
+ }
1921
+ if (["NEGADO", "ARQUIVADO", "RECUSADO"].includes(normalized)) {
1922
+ return { tone: "danger", appearance: "solid" };
1923
+ }
1924
+ }
1925
+ return (_c = options == null ? void 0 : options.fallback) != null ? _c : resolveGenericStatus(normalized);
1926
+ };
1927
+
1928
+ // src/components/status-badge/StatusBadge.tsx
1929
+ import classNames12 from "classnames";
1930
+ import { jsx as jsx27 } from "react/jsx-runtime";
1931
+ var TONE_STYLES2 = {
1932
+ info: {
1933
+ outline: "border-feedback-info-border text-feedback-info-content",
1934
+ soft: "border-feedback-info-border bg-feedback-info-soft text-feedback-info-content",
1935
+ solid: "border-feedback-info-strong bg-feedback-info-strong text-surface-subtle"
1936
+ },
1937
+ warning: {
1938
+ outline: "border-feedback-warning-border text-feedback-warning-content",
1939
+ soft: "border-feedback-warning-border bg-feedback-warning-soft text-feedback-warning-content",
1940
+ solid: "border-feedback-warning-strong bg-feedback-warning-strong text-surface-subtle"
1941
+ },
1942
+ success: {
1943
+ outline: "border-feedback-success-border text-feedback-success-content",
1944
+ soft: "border-feedback-success-border bg-feedback-success-soft text-feedback-success-content",
1945
+ solid: "border-feedback-success-strong bg-feedback-success-strong text-surface-subtle"
1946
+ },
1947
+ danger: {
1948
+ outline: "border-feedback-danger-border text-feedback-danger-content",
1949
+ soft: "border-feedback-danger-border bg-feedback-danger-soft text-feedback-danger-content",
1950
+ solid: "border-feedback-danger-strong bg-feedback-danger-strong text-surface-subtle"
1951
+ },
1952
+ neutral: {
1953
+ outline: "border-border-strong text-content-secondary",
1954
+ soft: "border-border-default bg-surface-subtle text-content-secondary",
1955
+ solid: "border-surface-action-neutral bg-surface-action-neutral text-surface-subtle"
1956
+ }
1964
1957
  };
1958
+ var SIZE_STYLES = {
1959
+ sm: "min-h-5 px-1 py-0.5 text-xs",
1960
+ md: "min-h-6 px-2 py-0.5 text-sm"
1961
+ };
1962
+ function StatusBadge(_a) {
1963
+ var _b = _a, {
1964
+ children,
1965
+ tone = "neutral",
1966
+ appearance = "outline",
1967
+ size = "md",
1968
+ overflow = "wrap",
1969
+ statusLabel,
1970
+ className,
1971
+ title
1972
+ } = _b, rest = __objRest(_b, [
1973
+ "children",
1974
+ "tone",
1975
+ "appearance",
1976
+ "size",
1977
+ "overflow",
1978
+ "statusLabel",
1979
+ "className",
1980
+ "title"
1981
+ ]);
1982
+ return /* @__PURE__ */ jsx27(
1983
+ "span",
1984
+ __spreadProps(__spreadValues({
1985
+ className: classNames12(
1986
+ "inline-flex w-fit max-w-full items-center justify-center rounded-sm border-2 text-center font-bold uppercase tracking-wide",
1987
+ SIZE_STYLES[size],
1988
+ TONE_STYLES2[tone][appearance],
1989
+ overflow === "truncate" ? "overflow-hidden text-ellipsis whitespace-nowrap" : "whitespace-normal break-words",
1990
+ className
1991
+ ),
1992
+ title: title != null ? title : typeof children === "string" ? children : void 0,
1993
+ "aria-label": statusLabel
1994
+ }, rest), {
1995
+ children
1996
+ })
1997
+ );
1998
+ }
1999
+ var getStatusBadgeClassName = (tone, appearance) => TONE_STYLES2[tone][appearance];
1965
2000
 
1966
2001
  // src/components/status-badge/DomainStatusBadge.tsx
1967
2002
  import { jsx as jsx28 } from "react/jsx-runtime";
@@ -1970,16 +2005,18 @@ function DomainStatusBadge(_a) {
1970
2005
  status,
1971
2006
  domain = "generic",
1972
2007
  empty = "hide",
1973
- placeholder = "-"
2008
+ placeholder = "-",
2009
+ statusMap
1974
2010
  } = _b, rest = __objRest(_b, [
1975
2011
  "status",
1976
2012
  "domain",
1977
2013
  "empty",
1978
- "placeholder"
2014
+ "placeholder",
2015
+ "statusMap"
1979
2016
  ]);
1980
2017
  const label = status == null ? void 0 : status.trim();
1981
2018
  if (!label && empty === "hide") return null;
1982
- const resolved = resolveStatusAppearance(label, domain);
2019
+ const resolved = resolveStatusAppearance(label, domain, { map: statusMap });
1983
2020
  return /* @__PURE__ */ jsx28(
1984
2021
  StatusBadge,
1985
2022
  __spreadProps(__spreadValues({
@@ -2123,11 +2160,12 @@ function FormErrorNavigation() {
2123
2160
  }
2124
2161
 
2125
2162
  // src/components/table/Table.tsx
2126
- import React4, { useEffect as useEffect8, useId as useId2, useMemo as useMemo2, useState as useState4 } from "react";
2163
+ import React4, { useEffect as useEffect8, useId as useId3, useMemo as useMemo2, useState as useState4 } from "react";
2127
2164
 
2128
2165
  // src/components/table/TableView.tsx
2129
2166
  import {
2130
2167
  useEffect as useEffect7,
2168
+ useId as useId2,
2131
2169
  useRef as useRef4,
2132
2170
  useState as useState3
2133
2171
  } from "react";
@@ -2145,6 +2183,9 @@ import cs3 from "classnames";
2145
2183
  import { useEffect as useEffect6, useRef as useRef3 } from "react";
2146
2184
  import { jsx as jsx30, jsxs as jsxs17 } from "react/jsx-runtime";
2147
2185
  function FilterView({
2186
+ id,
2187
+ accessibleName,
2188
+ groupName,
2148
2189
  optionList,
2149
2190
  optionChecked,
2150
2191
  onChange,
@@ -2170,25 +2211,37 @@ function FilterView({
2170
2211
  "div",
2171
2212
  {
2172
2213
  ref: containerRef,
2214
+ id,
2215
+ role: "dialog",
2216
+ "aria-label": accessibleName != null ? accessibleName : "Filtros da tabela",
2173
2217
  className: "bg-surface-card rounded shadow-sm p-3 font-normal w-[calc(100vw-16px)] max-w-[320px] overflow-y-auto text-sm",
2174
2218
  children: /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-3", children: controls.map((control) => {
2175
- var _a, _b, _c;
2219
+ var _a, _b, _c, _d, _e;
2176
2220
  return /* @__PURE__ */ jsxs17(
2177
2221
  "div",
2178
2222
  {
2179
2223
  className: "flex flex-col gap-2 border-b border-border-default pb-3 last:border-b-0 last:pb-0",
2180
2224
  children: [
2181
- control.label && /* @__PURE__ */ jsx30("span", { className: "text-xs font-bold uppercase tracking-wide text-content-muted", children: control.label }),
2225
+ control.label && /* @__PURE__ */ jsx30(
2226
+ "span",
2227
+ {
2228
+ id: `${control.id}-label`,
2229
+ className: "text-xs font-bold uppercase tracking-wide text-content-muted",
2230
+ children: control.label
2231
+ }
2232
+ ),
2182
2233
  control.type === "search" ? /* @__PURE__ */ jsx30(
2183
2234
  "input",
2184
2235
  {
2185
2236
  type: "text",
2186
- value: (_a = control.value) != null ? _a : "",
2187
- placeholder: (_b = control.placeholder) != null ? _b : "Buscar",
2237
+ "aria-label": (_b = (_a = control.label) != null ? _a : control.placeholder) != null ? _b : "Buscar",
2238
+ "aria-describedby": control.label ? `${control.id}-label` : void 0,
2239
+ value: (_c = control.value) != null ? _c : "",
2240
+ placeholder: (_d = control.placeholder) != null ? _d : "Buscar",
2188
2241
  onChange: (event) => handleControlChange(control, event),
2189
- className: "field-keyboard-focus-ring h-10 rounded border border-field-border-default bg-field-surface px-3 text-sm text-field-content outline-none placeholder:text-field-placeholder focus:border-field-border-active"
2242
+ className: "field-keyboard-focus-ring h-10 rounded border border-field-border-default bg-field-surface px-3 text-sm text-field-content outline-none placeholder:text-field-placeholder focus:border-field-border-active focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring"
2190
2243
  }
2191
- ) : /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-1", children: (_c = control.optionList) == null ? void 0 : _c.map((option, index) => /* @__PURE__ */ jsxs17(
2244
+ ) : /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-1", children: (_e = control.optionList) == null ? void 0 : _e.map((option, index) => /* @__PURE__ */ jsxs17(
2192
2245
  "label",
2193
2246
  {
2194
2247
  className: cs3(
@@ -2203,7 +2256,7 @@ function FilterView({
2203
2256
  className: "peer sr-only",
2204
2257
  value: option.value,
2205
2258
  checked: control.value === option.value,
2206
- name: `table-filter-${control.id}`,
2259
+ name: `table-filter-${groupName != null ? groupName : "default"}-${control.id}`,
2207
2260
  onChange: (event) => handleControlChange(control, event)
2208
2261
  }
2209
2262
  ),
@@ -2211,7 +2264,7 @@ function FilterView({
2211
2264
  "span",
2212
2265
  {
2213
2266
  "aria-hidden": "true",
2214
- className: "radio-control-proxy mt-1"
2267
+ className: "radio-control-proxy mt-1 peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-focus-ring"
2215
2268
  }
2216
2269
  ),
2217
2270
  /* @__PURE__ */ jsx30("span", { className: "min-w-0 flex-1 mt-[4px]", children: option.label })
@@ -2231,6 +2284,9 @@ function FilterView({
2231
2284
  "div",
2232
2285
  {
2233
2286
  ref: containerRef,
2287
+ id,
2288
+ role: "dialog",
2289
+ "aria-label": accessibleName != null ? accessibleName : "Filtros da tabela",
2234
2290
  className: "bg-surface-card rounded shadow-sm p-2 font-normal w-[calc(100vw-16px)] max-w-[320px] overflow-y-auto",
2235
2291
  children: optionList && optionList.map((option, index) => /* @__PURE__ */ jsxs17(
2236
2292
  "label",
@@ -2247,7 +2303,7 @@ function FilterView({
2247
2303
  className: "peer sr-only",
2248
2304
  value: option.value,
2249
2305
  checked: optionChecked === option.value,
2250
- name: "table-filter",
2306
+ name: `table-filter-${groupName != null ? groupName : "default"}`,
2251
2307
  onChange: handleChangeCheckbox
2252
2308
  }
2253
2309
  ),
@@ -2255,7 +2311,7 @@ function FilterView({
2255
2311
  "span",
2256
2312
  {
2257
2313
  "aria-hidden": "true",
2258
- className: "radio-control-proxy mt-1"
2314
+ className: "radio-control-proxy mt-1 peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-focus-ring"
2259
2315
  }
2260
2316
  ),
2261
2317
  /* @__PURE__ */ jsx30("span", { className: "min-w-0 flex-1", children: option.label })
@@ -2283,6 +2339,9 @@ function Filter(props) {
2283
2339
  FilterView_default,
2284
2340
  {
2285
2341
  optionList,
2342
+ id: props.id,
2343
+ accessibleName: props.accessibleName,
2344
+ groupName: props.groupName,
2286
2345
  optionChecked,
2287
2346
  onChange,
2288
2347
  controls,
@@ -2331,8 +2390,7 @@ function TableView({
2331
2390
  density = "comfortable"
2332
2391
  }) {
2333
2392
  var _a, _b;
2334
- const breakpoint = useBreakpoint();
2335
- const isMobile = breakpoint === "mobile";
2393
+ const tableId = useId2();
2336
2394
  const [openFilter, setOpenFilter] = useState3(null);
2337
2395
  const [filterMaxHeight, setFilterMaxHeight] = useState3();
2338
2396
  const [filterCoords, setFilterCoords] = useState3(null);
@@ -2340,6 +2398,7 @@ function TableView({
2340
2398
  const scrollContainerRef = useRef4(null);
2341
2399
  const tableWrapperRef = useRef4(null);
2342
2400
  const headerCellRefs = useRef4([]);
2401
+ const filterTriggerRefs = useRef4([]);
2343
2402
  const filterRef = useRef4(null);
2344
2403
  useEffect7(() => {
2345
2404
  const wrapper = tableWrapperRef.current;
@@ -2355,6 +2414,21 @@ function TableView({
2355
2414
  updateWidth();
2356
2415
  return () => observer.disconnect();
2357
2416
  }, []);
2417
+ useEffect7(() => {
2418
+ if (openFilter === null) return;
2419
+ const handleKeyDown = (event) => {
2420
+ if (event.key !== "Escape") return;
2421
+ event.preventDefault();
2422
+ setOpenFilter(null);
2423
+ setFilterCoords(null);
2424
+ window.requestAnimationFrame(() => {
2425
+ var _a2;
2426
+ (_a2 = filterTriggerRefs.current[openFilter]) == null ? void 0 : _a2.focus();
2427
+ });
2428
+ };
2429
+ document.addEventListener("keydown", handleKeyDown);
2430
+ return () => document.removeEventListener("keydown", handleKeyDown);
2431
+ }, [openFilter]);
2358
2432
  useEffect7(() => {
2359
2433
  const updateFilterMaxHeight = () => {
2360
2434
  var _a2;
@@ -2372,6 +2446,7 @@ function TableView({
2372
2446
  const handleClickOutside = (event) => {
2373
2447
  if (tableWrapperRef.current && !tableWrapperRef.current.contains(event.target)) {
2374
2448
  setOpenFilter(null);
2449
+ setFilterCoords(null);
2375
2450
  }
2376
2451
  };
2377
2452
  document.addEventListener("mousedown", handleClickOutside);
@@ -2384,6 +2459,16 @@ function TableView({
2384
2459
  filterRef.current.style.top = `${filterCoords.top}px`;
2385
2460
  filterRef.current.style.left = typeof filterCoords.left === "number" ? `${filterCoords.left}px` : "";
2386
2461
  }, [filterCoords]);
2462
+ useEffect7(() => {
2463
+ if (openFilter === null) return;
2464
+ const frame = window.requestAnimationFrame(() => {
2465
+ var _a2, _b2;
2466
+ (_b2 = (_a2 = filterRef.current) == null ? void 0 : _a2.querySelector(
2467
+ "input, button, [tabindex]:not([tabindex='-1'])"
2468
+ )) == null ? void 0 : _b2.focus();
2469
+ });
2470
+ return () => window.cancelAnimationFrame(frame);
2471
+ }, [openFilter]);
2387
2472
  const handleOpenFilter = (index) => {
2388
2473
  var _a2, _b2;
2389
2474
  const next = openFilter === index ? null : index;
@@ -2410,6 +2495,17 @@ function TableView({
2410
2495
  setFilterCoords(null);
2411
2496
  }
2412
2497
  };
2498
+ const closeFilterAndRestoreFocus = () => {
2499
+ const activeFilter = openFilter;
2500
+ setOpenFilter(null);
2501
+ setFilterCoords(null);
2502
+ if (activeFilter !== null) {
2503
+ window.requestAnimationFrame(() => {
2504
+ var _a2;
2505
+ (_a2 = filterTriggerRefs.current[activeFilter]) == null ? void 0 : _a2.focus();
2506
+ });
2507
+ }
2508
+ };
2413
2509
  const hasFilterEnabled = (item) => {
2414
2510
  var _a2, _b2, _c, _d;
2415
2511
  return Boolean(((_b2 = (_a2 = item.filters) == null ? void 0 : _a2.optionList) == null ? void 0 : _b2.length) || ((_d = (_c = item.filters) == null ? void 0 : _c.controls) == null ? void 0 : _d.length));
@@ -2488,7 +2584,8 @@ function TableView({
2488
2584
  }
2489
2585
  return `${widthUnits / resolvedTotalWidthUnits * 100}%`;
2490
2586
  };
2491
- const paginationVariant = isMobile ? "arrows" : (_a = pagination == null ? void 0 : pagination.variant) != null ? _a : "default";
2587
+ const isNarrowContainer = tableWidth !== void 0 && tableWidth < 640;
2588
+ const paginationVariant = isNarrowContainer ? "arrows" : (_a = pagination == null ? void 0 : pagination.variant) != null ? _a : "default";
2492
2589
  const isAdaptiveCompact = overflowMode === "adaptive" && tableWidth !== void 0 && tableWidth < adaptiveBreakpoint;
2493
2590
  const overflowClass = overflowMode === "scroll" ? "overflow-x-auto" : "overflow-x-hidden";
2494
2591
  const resolvedScrollAreaMaxHeight = stickyHeader ? scrollAreaMaxHeight != null ? scrollAreaMaxHeight : "calc(100dvh - 240px)" : scrollAreaMaxHeight;
@@ -2507,6 +2604,7 @@ function TableView({
2507
2604
  "data-row-variant": rowVariant,
2508
2605
  "data-header-variant": headerVariant,
2509
2606
  "data-table-density": density,
2607
+ "data-responsive-mode": overflowMode,
2510
2608
  style: { maxHeight: resolvedScrollAreaMaxHeight },
2511
2609
  className: `min-h-0 min-w-0 flex-1 overflow-y-auto ${overflowClass}`,
2512
2610
  children: /* @__PURE__ */ jsxs18(
@@ -2536,8 +2634,12 @@ function TableView({
2536
2634
  {
2537
2635
  type: "button",
2538
2636
  "aria-expanded": openFilter === index,
2637
+ "aria-controls": openFilter === index ? `${tableId}-filter-${index}` : void 0,
2638
+ ref: (element) => {
2639
+ filterTriggerRefs.current[index] = element;
2640
+ },
2539
2641
  "aria-label": `Filtrar ou ordenar por ${item.title}`,
2540
- className: `flex w-full items-center gap-1.5 rounded-sm text-left focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ${headerFocusClass} ${((_b2 = item.className) == null ? void 0 : _b2.includes("text-right")) ? "justify-end" : ""}`,
2642
+ className: `flex min-h-11 w-full items-center gap-1.5 rounded-sm text-left focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ${headerFocusClass} ${((_b2 = item.className) == null ? void 0 : _b2.includes("text-right")) ? "justify-end" : ""}`,
2541
2643
  onClick: () => handleHeaderAction(item, index),
2542
2644
  children: [
2543
2645
  /* @__PURE__ */ jsx33("span", { className: "min-w-0 truncate", children: item.title }),
@@ -2564,11 +2666,20 @@ function TableView({
2564
2666
  openFilter !== null && filterCoords && ((_b = header[openFilter]) == null ? void 0 : _b.filters) && /* @__PURE__ */ jsx33("div", { ref: filterRef, className: "absolute z-popover", children: /* @__PURE__ */ jsx33(
2565
2667
  Filter_default,
2566
2668
  {
2669
+ id: `${tableId}-filter-${openFilter}`,
2670
+ accessibleName: `Filtros da coluna ${header[openFilter].title}`,
2671
+ groupName: `${tableId}-${openFilter}`,
2567
2672
  optionChecked: header[openFilter].filters.optionChecked,
2568
2673
  optionList: header[openFilter].filters.optionList,
2569
2674
  controls: header[openFilter].filters.controls,
2570
- onChange: (value) => handleFilterChange(header[openFilter], value),
2571
- onControlChange: (control, value) => handleFilterChange(header[openFilter], value, control),
2675
+ onChange: (value) => {
2676
+ handleFilterChange(header[openFilter], value);
2677
+ closeFilterAndRestoreFocus();
2678
+ },
2679
+ onControlChange: (control, value) => {
2680
+ handleFilterChange(header[openFilter], value, control);
2681
+ if (control.type !== "search") closeFilterAndRestoreFocus();
2682
+ },
2572
2683
  maxHeight: filterMaxHeight
2573
2684
  }
2574
2685
  ) }),
@@ -2600,7 +2711,7 @@ function TableView({
2600
2711
  onClick: pagination.onPrevious,
2601
2712
  disabled: pagination.currentPage === 1,
2602
2713
  "aria-label": "Ir para a p\xE1gina anterior",
2603
- className: `inline-flex h-6 items-center justify-center gap-1 rounded border border-border-default px-2 text-sm leading-none text-content-primary hover:border-border-strong disabled:cursor-not-allowed disabled:border-border-default disabled:opacity-50 tablet:h-7 ${paginationVariant === "arrows" ? "min-w-6 tablet:min-w-7" : ""}`,
2714
+ className: `inline-flex min-h-11 min-w-11 items-center justify-center gap-1 rounded border border-border-default px-2 text-sm leading-none text-content-primary hover:border-border-strong disabled:cursor-not-allowed disabled:border-border-default disabled:opacity-50 ${paginationVariant === "arrows" ? "min-w-6 tablet:min-w-7" : ""}`,
2604
2715
  children: [
2605
2716
  /* @__PURE__ */ jsx33(MdKeyboardArrowLeft, { className: "h-3 w-3 text-content-muted" }),
2606
2717
  paginationVariant !== "arrows" && "Anterior"
@@ -2623,7 +2734,7 @@ function TableView({
2623
2734
  onClick: pagination.onNext,
2624
2735
  disabled: pagination.currentPage === pagination.totalPages,
2625
2736
  "aria-label": "Ir para a pr\xF3xima p\xE1gina",
2626
- className: `inline-flex h-6 items-center justify-center gap-1 rounded border border-border-default px-2 text-sm leading-none text-content-primary hover:border-border-strong disabled:cursor-not-allowed disabled:border-border-default disabled:opacity-50 tablet:h-7 ${paginationVariant === "arrows" ? "min-w-6 tablet:min-w-7" : ""}`,
2737
+ className: `inline-flex min-h-11 min-w-11 items-center justify-center gap-1 rounded border border-border-default px-2 text-sm leading-none text-content-primary hover:border-border-strong disabled:cursor-not-allowed disabled:border-border-default disabled:opacity-50 ${paginationVariant === "arrows" ? "min-w-6 tablet:min-w-7" : ""}`,
2627
2738
  children: [
2628
2739
  paginationVariant !== "arrows" && "Pr\xF3xima",
2629
2740
  /* @__PURE__ */ jsx33(MdKeyboardArrowRight, { className: "h-3 w-3 text-content-muted" })
@@ -2654,6 +2765,7 @@ function Table(props) {
2654
2765
  data,
2655
2766
  itemsPerPage = 10,
2656
2767
  emptyMessage = "Nenhum item encontrado",
2768
+ errorMessage,
2657
2769
  totalWidthUnits,
2658
2770
  showRowDivider = false,
2659
2771
  enableRowHover = false,
@@ -2667,9 +2779,7 @@ function Table(props) {
2667
2779
  headerVariant = "default",
2668
2780
  density = "comfortable"
2669
2781
  } = props;
2670
- const breakpoint = useBreakpoint();
2671
- const tableId = useId2();
2672
- const isMobile = breakpoint === "mobile";
2782
+ const tableId = useId3();
2673
2783
  const resolvedOverflowMode = overflowMode != null ? overflowMode : data ? "adaptive" : "scroll";
2674
2784
  const resolvedAdaptiveBreakpoint = adaptiveBreakpoint != null ? adaptiveBreakpoint : Math.min(920, 320 + Math.max(header.length - 2, 0) * 120);
2675
2785
  const [currentPage, setCurrentPage] = useState4(1);
@@ -2678,6 +2788,7 @@ function Table(props) {
2678
2788
  () => (expandable == null ? void 0 : expandable.expandedRowId) !== null && (expandable == null ? void 0 : expandable.expandedRowId) !== void 0 ? String(expandable.expandedRowId) : null
2679
2789
  );
2680
2790
  const [closingExpandedRowId, setClosingExpandedRowId] = useState4(null);
2791
+ const safeItemsPerPage = Number.isFinite(itemsPerPage) ? Math.max(1, Math.floor(itemsPerPage)) : 10;
2681
2792
  const normalizedHeader = useMemo2(() => {
2682
2793
  return header.map((item) => {
2683
2794
  const typedItem = item;
@@ -2803,10 +2914,10 @@ function Table(props) {
2803
2914
  const internalPagination = useMemo2(() => {
2804
2915
  if (!data) return null;
2805
2916
  const totalItems = filteredAndSortedData.length;
2806
- const totalPages = Math.max(1, Math.ceil(totalItems / itemsPerPage));
2917
+ const totalPages = Math.max(1, Math.ceil(totalItems / safeItemsPerPage));
2807
2918
  const safeCurrentPage = Math.min(currentPage, totalPages);
2808
- const startIndex = (safeCurrentPage - 1) * itemsPerPage;
2809
- const endIndex = startIndex + itemsPerPage;
2919
+ const startIndex = (safeCurrentPage - 1) * safeItemsPerPage;
2920
+ const endIndex = startIndex + safeItemsPerPage;
2810
2921
  return {
2811
2922
  currentPage: safeCurrentPage,
2812
2923
  totalPages,
@@ -2815,7 +2926,7 @@ function Table(props) {
2815
2926
  endItem: Math.min(endIndex, totalItems),
2816
2927
  pageData: filteredAndSortedData.slice(startIndex, endIndex)
2817
2928
  };
2818
- }, [currentPage, data, filteredAndSortedData, itemsPerPage]);
2929
+ }, [currentPage, data, filteredAndSortedData, safeItemsPerPage]);
2819
2930
  const managedCellClassName = density === "compact" ? "px-3 py-1.5 text-sm text-content-primary" : "px-4 py-2 text-sm text-content-primary";
2820
2931
  const expandedContentClassName = density === "compact" ? "bg-surface-card px-3 py-3" : "bg-surface-card px-4 py-4";
2821
2932
  const emptyCellClassName = density === "compact" ? "px-3 py-4 text-center text-sm text-content-muted" : "px-4 py-6 text-center text-sm text-content-muted";
@@ -2844,9 +2955,7 @@ function Table(props) {
2844
2955
  /* @__PURE__ */ jsx34(
2845
2956
  "tr",
2846
2957
  {
2847
- tabIndex: 0,
2848
2958
  "aria-label": `Linha ${rowNumber} de ${internalPagination.totalItems}`,
2849
- "aria-describedby": rowContentIds.join(" "),
2850
2959
  "data-table-row-stripe": rowVariant === "striped" && index % 2 === 1 && !isExpanded ? "true" : void 0,
2851
2960
  className: [
2852
2961
  "focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-focus-ring",
@@ -2882,7 +2991,7 @@ function Table(props) {
2882
2991
  "aria-label": `Detalhes da linha ${rowNumber}`,
2883
2992
  "aria-describedby": expandedContentId,
2884
2993
  "aria-hidden": !isExpanded || isClosingExpandedRow || void 0,
2885
- className: `overflow-hidden transition-all duration-200 ease-out ${isExpanded && !isClosingExpandedRow ? "max-h-[1200px] opacity-100" : "max-h-0 opacity-0"}`,
2994
+ className: `overflow-hidden transition-all duration-200 ease-out motion-reduce:transition-none ${isExpanded && !isClosingExpandedRow ? "max-h-[1200px] opacity-100" : "max-h-0 opacity-0"}`,
2886
2995
  children: /* @__PURE__ */ jsx34("div", { id: expandedContentId, children: expandable.renderExpandedRow(item, index) })
2887
2996
  }
2888
2997
  )
@@ -2899,7 +3008,7 @@ function Table(props) {
2899
3008
  {
2900
3009
  colSpan: normalizedHeader.length,
2901
3010
  className: emptyCellClassName,
2902
- children: emptyMessage
3011
+ children: errorMessage ? /* @__PURE__ */ jsx34("span", { role: "alert", children: errorMessage }) : /* @__PURE__ */ jsx34("span", { role: "status", children: emptyMessage })
2903
3012
  }
2904
3013
  ) })
2905
3014
  ] });
@@ -2907,6 +3016,7 @@ function Table(props) {
2907
3016
  children,
2908
3017
  data,
2909
3018
  emptyMessage,
3019
+ errorMessage,
2910
3020
  emptyCellClassName,
2911
3021
  enableRowHover,
2912
3022
  expandable,
@@ -2926,16 +3036,16 @@ function Table(props) {
2926
3036
  totalItems: internalPagination.totalItems,
2927
3037
  startItem: internalPagination.startItem,
2928
3038
  endItem: internalPagination.endItem,
2929
- variant: isMobile ? "arrows" : paginationVariant,
3039
+ variant: paginationVariant,
2930
3040
  onPrevious: () => setCurrentPage((prev) => Math.max(prev - 1, 1)),
2931
3041
  onNext: () => setCurrentPage(
2932
3042
  (prev) => Math.min(prev + 1, internalPagination.totalPages)
2933
3043
  )
2934
3044
  } : pagination ? __spreadProps(__spreadValues({}, pagination), {
2935
- variant: isMobile ? "arrows" : (_a = pagination.variant) != null ? _a : "default"
3045
+ variant: (_a = pagination.variant) != null ? _a : "default"
2936
3046
  }) : pagination;
2937
3047
  const resolvedShowPagination = data ? Boolean(
2938
- internalPagination && internalPagination.totalItems > itemsPerPage
3048
+ internalPagination && internalPagination.totalItems > safeItemsPerPage
2939
3049
  ) : showPagination;
2940
3050
  const handleInternalFilterChange = (columnKey, controlId, value) => {
2941
3051
  setFilterValues((prev) => __spreadProps(__spreadValues({}, prev), {
@@ -2983,7 +3093,7 @@ function Table(props) {
2983
3093
  var Table_default = Table;
2984
3094
 
2985
3095
  // src/components/table/MobileCardTable.tsx
2986
- import { useEffect as useEffect9, useId as useId3, useMemo as useMemo3, useState as useState5 } from "react";
3096
+ import { useEffect as useEffect9, useId as useId4, useMemo as useMemo3, useState as useState5 } from "react";
2987
3097
  import { MdKeyboardArrowLeft as MdKeyboardArrowLeft2, MdKeyboardArrowRight as MdKeyboardArrowRight2 } from "react-icons/md";
2988
3098
  import { Fragment as Fragment4, jsx as jsx35, jsxs as jsxs20 } from "react/jsx-runtime";
2989
3099
  function MobileCardTable({
@@ -3000,7 +3110,7 @@ function MobileCardTable({
3000
3110
  showPagination = true,
3001
3111
  expandable
3002
3112
  }) {
3003
- const listId = useId3();
3113
+ const listId = useId4();
3004
3114
  const [currentPage, setCurrentPage] = useState5(1);
3005
3115
  const [visibleExpandedRowId, setVisibleExpandedRowId] = useState5(
3006
3116
  () => (expandable == null ? void 0 : expandable.expandedRowId) !== null && (expandable == null ? void 0 : expandable.expandedRowId) !== void 0 ? String(expandable.expandedRowId) : null
@@ -3012,12 +3122,13 @@ function MobileCardTable({
3012
3122
  () => Array.isArray(data) ? data : [],
3013
3123
  [data]
3014
3124
  );
3125
+ const safeItemsPerPage = Number.isFinite(itemsPerPage) ? Math.max(1, Math.floor(itemsPerPage)) : 10;
3015
3126
  const pagination = useMemo3(() => {
3016
3127
  const totalItems = normalizedData.length;
3017
- const totalPages = Math.max(1, Math.ceil(totalItems / itemsPerPage));
3128
+ const totalPages = Math.max(1, Math.ceil(totalItems / safeItemsPerPage));
3018
3129
  const safeCurrentPage = Math.min(currentPage, totalPages);
3019
- const startIndex = (safeCurrentPage - 1) * itemsPerPage;
3020
- const endIndex = startIndex + itemsPerPage;
3130
+ const startIndex = (safeCurrentPage - 1) * safeItemsPerPage;
3131
+ const endIndex = startIndex + safeItemsPerPage;
3021
3132
  return {
3022
3133
  currentPage: safeCurrentPage,
3023
3134
  totalPages,
@@ -3026,7 +3137,7 @@ function MobileCardTable({
3026
3137
  endItem: Math.min(endIndex, totalItems),
3027
3138
  pageData: normalizedData.slice(startIndex, endIndex)
3028
3139
  };
3029
- }, [currentPage, normalizedData, itemsPerPage]);
3140
+ }, [currentPage, normalizedData, safeItemsPerPage]);
3030
3141
  useEffect9(() => {
3031
3142
  setCurrentPage(1);
3032
3143
  }, [normalizedData]);
@@ -3081,7 +3192,6 @@ function MobileCardTable({
3081
3192
  "div",
3082
3193
  {
3083
3194
  role: "listitem",
3084
- tabIndex: 0,
3085
3195
  "aria-label": `Item ${itemNumber} de ${pagination.totalItems}`,
3086
3196
  "aria-describedby": cardContentId,
3087
3197
  className: "focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-focus-ring",
@@ -3106,7 +3216,7 @@ function MobileCardTable({
3106
3216
  "aria-label": `Detalhes do item ${itemNumber}`,
3107
3217
  "aria-describedby": expandedContentId,
3108
3218
  "aria-hidden": !isExpanded || isClosingExpandedRow || void 0,
3109
- className: `overflow-hidden transition-all duration-200 ease-out ${isExpanded && !isClosingExpandedRow ? "max-h-[1200px] opacity-100" : "max-h-0 opacity-0"}`,
3219
+ className: `overflow-hidden transition-all duration-200 ease-out motion-reduce:transition-none ${isExpanded && !isClosingExpandedRow ? "max-h-[1200px] opacity-100" : "max-h-0 opacity-0"}`,
3110
3220
  children: /* @__PURE__ */ jsx35("div", { id: expandedContentId, children: expandable.renderExpandedRow(item, index) })
3111
3221
  }
3112
3222
  )
@@ -3119,6 +3229,7 @@ function MobileCardTable({
3119
3229
  })()) }) : /* @__PURE__ */ jsx35(
3120
3230
  "div",
3121
3231
  {
3232
+ role: "status",
3122
3233
  className: `px-3 py-4 text-center text-md text-content-secondary ${emptyClassName}`.trim(),
3123
3234
  children: emptyMessage
3124
3235
  }
@@ -3126,7 +3237,7 @@ function MobileCardTable({
3126
3237
  ]
3127
3238
  }
3128
3239
  ),
3129
- showPagination && pagination.totalItems > itemsPerPage && /* @__PURE__ */ jsxs20("div", { className: "mt-4 flex flex-col items-center justify-center gap-3 text-center", children: [
3240
+ showPagination && pagination.totalItems > safeItemsPerPage && /* @__PURE__ */ jsxs20("div", { className: "mt-4 flex flex-col items-center justify-center gap-3 text-center", children: [
3130
3241
  /* @__PURE__ */ jsxs20(
3131
3242
  "p",
3132
3243
  {
@@ -3192,6 +3303,57 @@ function MobileCardTable({
3192
3303
  }
3193
3304
  var MobileCardTable_default = MobileCardTable;
3194
3305
 
3306
+ // src/hooks/useContainerBreakpoint.ts
3307
+ import { useEffect as useEffect10, useMemo as useMemo4, useState as useState6 } from "react";
3308
+ var defaultContainerBreakpoints = {
3309
+ mobile: 0,
3310
+ tablet: 640,
3311
+ desktop: 1024,
3312
+ wide: 1440
3313
+ };
3314
+ function resolveContainerBreakpoint(width, breakpoints = defaultContainerBreakpoints) {
3315
+ const entries = Object.entries(breakpoints).sort(
3316
+ ([, first], [, second]) => first === second ? 0 : first - second
3317
+ );
3318
+ return entries.reduce(
3319
+ (result, [name, threshold]) => width >= threshold ? name : result,
3320
+ void 0
3321
+ );
3322
+ }
3323
+ function getBreakpointMapKey(breakpoints) {
3324
+ return Object.entries(breakpoints).sort(([first], [second]) => first.localeCompare(second)).map(([name, threshold]) => `${name}:${threshold}`).join("|");
3325
+ }
3326
+ function useContainerBreakpoint(ref, options = {}) {
3327
+ var _a;
3328
+ const thresholds = (_a = options.breakpoints) != null ? _a : defaultContainerBreakpoints;
3329
+ const thresholdsKey = getBreakpointMapKey(thresholds);
3330
+ const sortedThresholds = useMemo4(
3331
+ () => Object.entries(thresholds).sort(
3332
+ ([, first], [, second]) => first === second ? 0 : first - second
3333
+ ),
3334
+ [thresholdsKey]
3335
+ );
3336
+ const [current, setCurrent] = useState6();
3337
+ useEffect10(() => {
3338
+ const element = ref.current;
3339
+ if (!element) return;
3340
+ const resolve = (width) => sortedThresholds.reduce(
3341
+ (result, [name, threshold]) => width >= threshold ? name : result,
3342
+ void 0
3343
+ );
3344
+ const update = () => setCurrent(resolve(element.getBoundingClientRect().width));
3345
+ if (typeof ResizeObserver === "undefined") {
3346
+ update();
3347
+ return void 0;
3348
+ }
3349
+ const observer = new ResizeObserver(update);
3350
+ observer.observe(element);
3351
+ update();
3352
+ return () => observer.disconnect();
3353
+ }, [ref, sortedThresholds]);
3354
+ return current;
3355
+ }
3356
+
3195
3357
  export {
3196
3358
  LoadingDotsView_default,
3197
3359
  Button_default,
@@ -3219,6 +3381,8 @@ export {
3219
3381
  InfoGrid,
3220
3382
  InfoItem,
3221
3383
  FilterBar,
3384
+ normalizeStatus,
3385
+ resolveStatusAppearance,
3222
3386
  StatusBadge,
3223
3387
  getStatusBadgeClassName,
3224
3388
  DomainStatusBadge,
@@ -3227,6 +3391,8 @@ export {
3227
3391
  findFirstInvalidField,
3228
3392
  FormErrorNavigation,
3229
3393
  Table_default,
3230
- MobileCardTable_default
3394
+ MobileCardTable_default,
3395
+ resolveContainerBreakpoint,
3396
+ useContainerBreakpoint
3231
3397
  };
3232
- //# sourceMappingURL=chunk-L5UMGEXV.js.map
3398
+ //# sourceMappingURL=chunk-EPV6UNUQ.js.map