@aspprev/versi-ds 0.2.0 → 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-ET2BGHTO.js";
3
+ } from "./chunk-FTRF27XF.js";
4
4
  import {
5
5
  __objRest,
6
6
  __spreadProps,
@@ -1807,79 +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
- statusLabel,
1852
- className,
1853
- title
1854
- } = _b, rest = __objRest(_b, [
1855
- "children",
1856
- "tone",
1857
- "appearance",
1858
- "size",
1859
- "overflow",
1860
- "statusLabel",
1861
- "className",
1862
- "title"
1863
- ]);
1864
- return /* @__PURE__ */ jsx27(
1865
- "span",
1866
- __spreadProps(__spreadValues({
1867
- className: classNames12(
1868
- "inline-flex w-fit max-w-full items-center justify-center rounded-sm border-2 text-center font-bold uppercase tracking-wide",
1869
- SIZE_STYLES[size],
1870
- TONE_STYLES2[tone][appearance],
1871
- overflow === "truncate" ? "overflow-hidden text-ellipsis whitespace-nowrap" : "whitespace-normal break-words",
1872
- className
1873
- ),
1874
- title: title != null ? title : typeof children === "string" ? children : void 0,
1875
- "aria-label": statusLabel
1876
- }, rest), {
1877
- children
1878
- })
1879
- );
1880
- }
1881
- var getStatusBadgeClassName = (tone, appearance) => TONE_STYLES2[tone][appearance];
1882
-
1883
1810
  // src/utils/resolve-status-appearance.ts
1884
1811
  var NORMALIZED_STATUS = {
1885
1812
  infoOutline: /* @__PURE__ */ new Set(["ABERTO", "PAGO", "EM PAGAMENTO"]),
@@ -1935,9 +1862,16 @@ var resolveGenericStatus = (status) => {
1935
1862
  }
1936
1863
  return { tone: "neutral", appearance: "outline" };
1937
1864
  };
1938
- var resolveStatusAppearance = (status, domain = "generic") => {
1865
+ var resolveStatusAppearance = (status, domain = "generic", options) => {
1866
+ var _a, _b, _c;
1939
1867
  const normalized = normalizeStatus(status);
1940
- 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;
1941
1875
  if (domain === "beneficiary") {
1942
1876
  if (normalized === "VIGENTE") return { tone: "success", appearance: "solid" };
1943
1877
  if (normalized === "ENCERRADO") return { tone: "neutral", appearance: "solid" };
@@ -1988,9 +1922,82 @@ var resolveStatusAppearance = (status, domain = "generic") => {
1988
1922
  return { tone: "danger", appearance: "solid" };
1989
1923
  }
1990
1924
  }
1991
- return resolveGenericStatus(normalized);
1925
+ return (_c = options == null ? void 0 : options.fallback) != null ? _c : resolveGenericStatus(normalized);
1992
1926
  };
1993
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
+ }
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];
2000
+
1994
2001
  // src/components/status-badge/DomainStatusBadge.tsx
1995
2002
  import { jsx as jsx28 } from "react/jsx-runtime";
1996
2003
  function DomainStatusBadge(_a) {
@@ -1998,16 +2005,18 @@ function DomainStatusBadge(_a) {
1998
2005
  status,
1999
2006
  domain = "generic",
2000
2007
  empty = "hide",
2001
- placeholder = "-"
2008
+ placeholder = "-",
2009
+ statusMap
2002
2010
  } = _b, rest = __objRest(_b, [
2003
2011
  "status",
2004
2012
  "domain",
2005
2013
  "empty",
2006
- "placeholder"
2014
+ "placeholder",
2015
+ "statusMap"
2007
2016
  ]);
2008
2017
  const label = status == null ? void 0 : status.trim();
2009
2018
  if (!label && empty === "hide") return null;
2010
- const resolved = resolveStatusAppearance(label, domain);
2019
+ const resolved = resolveStatusAppearance(label, domain, { map: statusMap });
2011
2020
  return /* @__PURE__ */ jsx28(
2012
2021
  StatusBadge,
2013
2022
  __spreadProps(__spreadValues({
@@ -2151,11 +2160,12 @@ function FormErrorNavigation() {
2151
2160
  }
2152
2161
 
2153
2162
  // src/components/table/Table.tsx
2154
- 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";
2155
2164
 
2156
2165
  // src/components/table/TableView.tsx
2157
2166
  import {
2158
2167
  useEffect as useEffect7,
2168
+ useId as useId2,
2159
2169
  useRef as useRef4,
2160
2170
  useState as useState3
2161
2171
  } from "react";
@@ -2173,6 +2183,9 @@ import cs3 from "classnames";
2173
2183
  import { useEffect as useEffect6, useRef as useRef3 } from "react";
2174
2184
  import { jsx as jsx30, jsxs as jsxs17 } from "react/jsx-runtime";
2175
2185
  function FilterView({
2186
+ id,
2187
+ accessibleName,
2188
+ groupName,
2176
2189
  optionList,
2177
2190
  optionChecked,
2178
2191
  onChange,
@@ -2198,25 +2211,37 @@ function FilterView({
2198
2211
  "div",
2199
2212
  {
2200
2213
  ref: containerRef,
2214
+ id,
2215
+ role: "dialog",
2216
+ "aria-label": accessibleName != null ? accessibleName : "Filtros da tabela",
2201
2217
  className: "bg-surface-card rounded shadow-sm p-3 font-normal w-[calc(100vw-16px)] max-w-[320px] overflow-y-auto text-sm",
2202
2218
  children: /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-3", children: controls.map((control) => {
2203
- var _a, _b, _c;
2219
+ var _a, _b, _c, _d, _e;
2204
2220
  return /* @__PURE__ */ jsxs17(
2205
2221
  "div",
2206
2222
  {
2207
2223
  className: "flex flex-col gap-2 border-b border-border-default pb-3 last:border-b-0 last:pb-0",
2208
2224
  children: [
2209
- 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
+ ),
2210
2233
  control.type === "search" ? /* @__PURE__ */ jsx30(
2211
2234
  "input",
2212
2235
  {
2213
2236
  type: "text",
2214
- value: (_a = control.value) != null ? _a : "",
2215
- 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",
2216
2241
  onChange: (event) => handleControlChange(control, event),
2217
- 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"
2218
2243
  }
2219
- ) : /* @__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(
2220
2245
  "label",
2221
2246
  {
2222
2247
  className: cs3(
@@ -2231,7 +2256,7 @@ function FilterView({
2231
2256
  className: "peer sr-only",
2232
2257
  value: option.value,
2233
2258
  checked: control.value === option.value,
2234
- name: `table-filter-${control.id}`,
2259
+ name: `table-filter-${groupName != null ? groupName : "default"}-${control.id}`,
2235
2260
  onChange: (event) => handleControlChange(control, event)
2236
2261
  }
2237
2262
  ),
@@ -2239,7 +2264,7 @@ function FilterView({
2239
2264
  "span",
2240
2265
  {
2241
2266
  "aria-hidden": "true",
2242
- 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"
2243
2268
  }
2244
2269
  ),
2245
2270
  /* @__PURE__ */ jsx30("span", { className: "min-w-0 flex-1 mt-[4px]", children: option.label })
@@ -2259,6 +2284,9 @@ function FilterView({
2259
2284
  "div",
2260
2285
  {
2261
2286
  ref: containerRef,
2287
+ id,
2288
+ role: "dialog",
2289
+ "aria-label": accessibleName != null ? accessibleName : "Filtros da tabela",
2262
2290
  className: "bg-surface-card rounded shadow-sm p-2 font-normal w-[calc(100vw-16px)] max-w-[320px] overflow-y-auto",
2263
2291
  children: optionList && optionList.map((option, index) => /* @__PURE__ */ jsxs17(
2264
2292
  "label",
@@ -2275,7 +2303,7 @@ function FilterView({
2275
2303
  className: "peer sr-only",
2276
2304
  value: option.value,
2277
2305
  checked: optionChecked === option.value,
2278
- name: "table-filter",
2306
+ name: `table-filter-${groupName != null ? groupName : "default"}`,
2279
2307
  onChange: handleChangeCheckbox
2280
2308
  }
2281
2309
  ),
@@ -2283,7 +2311,7 @@ function FilterView({
2283
2311
  "span",
2284
2312
  {
2285
2313
  "aria-hidden": "true",
2286
- 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"
2287
2315
  }
2288
2316
  ),
2289
2317
  /* @__PURE__ */ jsx30("span", { className: "min-w-0 flex-1", children: option.label })
@@ -2311,6 +2339,9 @@ function Filter(props) {
2311
2339
  FilterView_default,
2312
2340
  {
2313
2341
  optionList,
2342
+ id: props.id,
2343
+ accessibleName: props.accessibleName,
2344
+ groupName: props.groupName,
2314
2345
  optionChecked,
2315
2346
  onChange,
2316
2347
  controls,
@@ -2359,8 +2390,7 @@ function TableView({
2359
2390
  density = "comfortable"
2360
2391
  }) {
2361
2392
  var _a, _b;
2362
- const breakpoint = useBreakpoint();
2363
- const isMobile = breakpoint === "mobile";
2393
+ const tableId = useId2();
2364
2394
  const [openFilter, setOpenFilter] = useState3(null);
2365
2395
  const [filterMaxHeight, setFilterMaxHeight] = useState3();
2366
2396
  const [filterCoords, setFilterCoords] = useState3(null);
@@ -2368,6 +2398,7 @@ function TableView({
2368
2398
  const scrollContainerRef = useRef4(null);
2369
2399
  const tableWrapperRef = useRef4(null);
2370
2400
  const headerCellRefs = useRef4([]);
2401
+ const filterTriggerRefs = useRef4([]);
2371
2402
  const filterRef = useRef4(null);
2372
2403
  useEffect7(() => {
2373
2404
  const wrapper = tableWrapperRef.current;
@@ -2383,6 +2414,21 @@ function TableView({
2383
2414
  updateWidth();
2384
2415
  return () => observer.disconnect();
2385
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]);
2386
2432
  useEffect7(() => {
2387
2433
  const updateFilterMaxHeight = () => {
2388
2434
  var _a2;
@@ -2400,6 +2446,7 @@ function TableView({
2400
2446
  const handleClickOutside = (event) => {
2401
2447
  if (tableWrapperRef.current && !tableWrapperRef.current.contains(event.target)) {
2402
2448
  setOpenFilter(null);
2449
+ setFilterCoords(null);
2403
2450
  }
2404
2451
  };
2405
2452
  document.addEventListener("mousedown", handleClickOutside);
@@ -2412,6 +2459,16 @@ function TableView({
2412
2459
  filterRef.current.style.top = `${filterCoords.top}px`;
2413
2460
  filterRef.current.style.left = typeof filterCoords.left === "number" ? `${filterCoords.left}px` : "";
2414
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]);
2415
2472
  const handleOpenFilter = (index) => {
2416
2473
  var _a2, _b2;
2417
2474
  const next = openFilter === index ? null : index;
@@ -2438,6 +2495,17 @@ function TableView({
2438
2495
  setFilterCoords(null);
2439
2496
  }
2440
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
+ };
2441
2509
  const hasFilterEnabled = (item) => {
2442
2510
  var _a2, _b2, _c, _d;
2443
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));
@@ -2517,7 +2585,7 @@ function TableView({
2517
2585
  return `${widthUnits / resolvedTotalWidthUnits * 100}%`;
2518
2586
  };
2519
2587
  const isNarrowContainer = tableWidth !== void 0 && tableWidth < 640;
2520
- const paginationVariant = isMobile || isNarrowContainer ? "arrows" : (_a = pagination == null ? void 0 : pagination.variant) != null ? _a : "default";
2588
+ const paginationVariant = isNarrowContainer ? "arrows" : (_a = pagination == null ? void 0 : pagination.variant) != null ? _a : "default";
2521
2589
  const isAdaptiveCompact = overflowMode === "adaptive" && tableWidth !== void 0 && tableWidth < adaptiveBreakpoint;
2522
2590
  const overflowClass = overflowMode === "scroll" ? "overflow-x-auto" : "overflow-x-hidden";
2523
2591
  const resolvedScrollAreaMaxHeight = stickyHeader ? scrollAreaMaxHeight != null ? scrollAreaMaxHeight : "calc(100dvh - 240px)" : scrollAreaMaxHeight;
@@ -2536,6 +2604,7 @@ function TableView({
2536
2604
  "data-row-variant": rowVariant,
2537
2605
  "data-header-variant": headerVariant,
2538
2606
  "data-table-density": density,
2607
+ "data-responsive-mode": overflowMode,
2539
2608
  style: { maxHeight: resolvedScrollAreaMaxHeight },
2540
2609
  className: `min-h-0 min-w-0 flex-1 overflow-y-auto ${overflowClass}`,
2541
2610
  children: /* @__PURE__ */ jsxs18(
@@ -2565,6 +2634,10 @@ function TableView({
2565
2634
  {
2566
2635
  type: "button",
2567
2636
  "aria-expanded": openFilter === index,
2637
+ "aria-controls": openFilter === index ? `${tableId}-filter-${index}` : void 0,
2638
+ ref: (element) => {
2639
+ filterTriggerRefs.current[index] = element;
2640
+ },
2568
2641
  "aria-label": `Filtrar ou ordenar por ${item.title}`,
2569
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" : ""}`,
2570
2643
  onClick: () => handleHeaderAction(item, index),
@@ -2593,11 +2666,20 @@ function TableView({
2593
2666
  openFilter !== null && filterCoords && ((_b = header[openFilter]) == null ? void 0 : _b.filters) && /* @__PURE__ */ jsx33("div", { ref: filterRef, className: "absolute z-popover", children: /* @__PURE__ */ jsx33(
2594
2667
  Filter_default,
2595
2668
  {
2669
+ id: `${tableId}-filter-${openFilter}`,
2670
+ accessibleName: `Filtros da coluna ${header[openFilter].title}`,
2671
+ groupName: `${tableId}-${openFilter}`,
2596
2672
  optionChecked: header[openFilter].filters.optionChecked,
2597
2673
  optionList: header[openFilter].filters.optionList,
2598
2674
  controls: header[openFilter].filters.controls,
2599
- onChange: (value) => handleFilterChange(header[openFilter], value),
2600
- 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
+ },
2601
2683
  maxHeight: filterMaxHeight
2602
2684
  }
2603
2685
  ) }),
@@ -2697,9 +2779,7 @@ function Table(props) {
2697
2779
  headerVariant = "default",
2698
2780
  density = "comfortable"
2699
2781
  } = props;
2700
- const breakpoint = useBreakpoint();
2701
- const tableId = useId2();
2702
- const isMobile = breakpoint === "mobile";
2782
+ const tableId = useId3();
2703
2783
  const resolvedOverflowMode = overflowMode != null ? overflowMode : data ? "adaptive" : "scroll";
2704
2784
  const resolvedAdaptiveBreakpoint = adaptiveBreakpoint != null ? adaptiveBreakpoint : Math.min(920, 320 + Math.max(header.length - 2, 0) * 120);
2705
2785
  const [currentPage, setCurrentPage] = useState4(1);
@@ -2708,6 +2788,7 @@ function Table(props) {
2708
2788
  () => (expandable == null ? void 0 : expandable.expandedRowId) !== null && (expandable == null ? void 0 : expandable.expandedRowId) !== void 0 ? String(expandable.expandedRowId) : null
2709
2789
  );
2710
2790
  const [closingExpandedRowId, setClosingExpandedRowId] = useState4(null);
2791
+ const safeItemsPerPage = Number.isFinite(itemsPerPage) ? Math.max(1, Math.floor(itemsPerPage)) : 10;
2711
2792
  const normalizedHeader = useMemo2(() => {
2712
2793
  return header.map((item) => {
2713
2794
  const typedItem = item;
@@ -2833,10 +2914,10 @@ function Table(props) {
2833
2914
  const internalPagination = useMemo2(() => {
2834
2915
  if (!data) return null;
2835
2916
  const totalItems = filteredAndSortedData.length;
2836
- const totalPages = Math.max(1, Math.ceil(totalItems / itemsPerPage));
2917
+ const totalPages = Math.max(1, Math.ceil(totalItems / safeItemsPerPage));
2837
2918
  const safeCurrentPage = Math.min(currentPage, totalPages);
2838
- const startIndex = (safeCurrentPage - 1) * itemsPerPage;
2839
- const endIndex = startIndex + itemsPerPage;
2919
+ const startIndex = (safeCurrentPage - 1) * safeItemsPerPage;
2920
+ const endIndex = startIndex + safeItemsPerPage;
2840
2921
  return {
2841
2922
  currentPage: safeCurrentPage,
2842
2923
  totalPages,
@@ -2845,7 +2926,7 @@ function Table(props) {
2845
2926
  endItem: Math.min(endIndex, totalItems),
2846
2927
  pageData: filteredAndSortedData.slice(startIndex, endIndex)
2847
2928
  };
2848
- }, [currentPage, data, filteredAndSortedData, itemsPerPage]);
2929
+ }, [currentPage, data, filteredAndSortedData, safeItemsPerPage]);
2849
2930
  const managedCellClassName = density === "compact" ? "px-3 py-1.5 text-sm text-content-primary" : "px-4 py-2 text-sm text-content-primary";
2850
2931
  const expandedContentClassName = density === "compact" ? "bg-surface-card px-3 py-3" : "bg-surface-card px-4 py-4";
2851
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";
@@ -2874,9 +2955,7 @@ function Table(props) {
2874
2955
  /* @__PURE__ */ jsx34(
2875
2956
  "tr",
2876
2957
  {
2877
- tabIndex: 0,
2878
2958
  "aria-label": `Linha ${rowNumber} de ${internalPagination.totalItems}`,
2879
- "aria-describedby": rowContentIds.join(" "),
2880
2959
  "data-table-row-stripe": rowVariant === "striped" && index % 2 === 1 && !isExpanded ? "true" : void 0,
2881
2960
  className: [
2882
2961
  "focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-focus-ring",
@@ -2912,7 +2991,7 @@ function Table(props) {
2912
2991
  "aria-label": `Detalhes da linha ${rowNumber}`,
2913
2992
  "aria-describedby": expandedContentId,
2914
2993
  "aria-hidden": !isExpanded || isClosingExpandedRow || void 0,
2915
- 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"}`,
2916
2995
  children: /* @__PURE__ */ jsx34("div", { id: expandedContentId, children: expandable.renderExpandedRow(item, index) })
2917
2996
  }
2918
2997
  )
@@ -2957,16 +3036,16 @@ function Table(props) {
2957
3036
  totalItems: internalPagination.totalItems,
2958
3037
  startItem: internalPagination.startItem,
2959
3038
  endItem: internalPagination.endItem,
2960
- variant: isMobile ? "arrows" : paginationVariant,
3039
+ variant: paginationVariant,
2961
3040
  onPrevious: () => setCurrentPage((prev) => Math.max(prev - 1, 1)),
2962
3041
  onNext: () => setCurrentPage(
2963
3042
  (prev) => Math.min(prev + 1, internalPagination.totalPages)
2964
3043
  )
2965
3044
  } : pagination ? __spreadProps(__spreadValues({}, pagination), {
2966
- variant: isMobile ? "arrows" : (_a = pagination.variant) != null ? _a : "default"
3045
+ variant: (_a = pagination.variant) != null ? _a : "default"
2967
3046
  }) : pagination;
2968
3047
  const resolvedShowPagination = data ? Boolean(
2969
- internalPagination && internalPagination.totalItems > itemsPerPage
3048
+ internalPagination && internalPagination.totalItems > safeItemsPerPage
2970
3049
  ) : showPagination;
2971
3050
  const handleInternalFilterChange = (columnKey, controlId, value) => {
2972
3051
  setFilterValues((prev) => __spreadProps(__spreadValues({}, prev), {
@@ -3014,7 +3093,7 @@ function Table(props) {
3014
3093
  var Table_default = Table;
3015
3094
 
3016
3095
  // src/components/table/MobileCardTable.tsx
3017
- 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";
3018
3097
  import { MdKeyboardArrowLeft as MdKeyboardArrowLeft2, MdKeyboardArrowRight as MdKeyboardArrowRight2 } from "react-icons/md";
3019
3098
  import { Fragment as Fragment4, jsx as jsx35, jsxs as jsxs20 } from "react/jsx-runtime";
3020
3099
  function MobileCardTable({
@@ -3031,7 +3110,7 @@ function MobileCardTable({
3031
3110
  showPagination = true,
3032
3111
  expandable
3033
3112
  }) {
3034
- const listId = useId3();
3113
+ const listId = useId4();
3035
3114
  const [currentPage, setCurrentPage] = useState5(1);
3036
3115
  const [visibleExpandedRowId, setVisibleExpandedRowId] = useState5(
3037
3116
  () => (expandable == null ? void 0 : expandable.expandedRowId) !== null && (expandable == null ? void 0 : expandable.expandedRowId) !== void 0 ? String(expandable.expandedRowId) : null
@@ -3043,12 +3122,13 @@ function MobileCardTable({
3043
3122
  () => Array.isArray(data) ? data : [],
3044
3123
  [data]
3045
3124
  );
3125
+ const safeItemsPerPage = Number.isFinite(itemsPerPage) ? Math.max(1, Math.floor(itemsPerPage)) : 10;
3046
3126
  const pagination = useMemo3(() => {
3047
3127
  const totalItems = normalizedData.length;
3048
- const totalPages = Math.max(1, Math.ceil(totalItems / itemsPerPage));
3128
+ const totalPages = Math.max(1, Math.ceil(totalItems / safeItemsPerPage));
3049
3129
  const safeCurrentPage = Math.min(currentPage, totalPages);
3050
- const startIndex = (safeCurrentPage - 1) * itemsPerPage;
3051
- const endIndex = startIndex + itemsPerPage;
3130
+ const startIndex = (safeCurrentPage - 1) * safeItemsPerPage;
3131
+ const endIndex = startIndex + safeItemsPerPage;
3052
3132
  return {
3053
3133
  currentPage: safeCurrentPage,
3054
3134
  totalPages,
@@ -3057,7 +3137,7 @@ function MobileCardTable({
3057
3137
  endItem: Math.min(endIndex, totalItems),
3058
3138
  pageData: normalizedData.slice(startIndex, endIndex)
3059
3139
  };
3060
- }, [currentPage, normalizedData, itemsPerPage]);
3140
+ }, [currentPage, normalizedData, safeItemsPerPage]);
3061
3141
  useEffect9(() => {
3062
3142
  setCurrentPage(1);
3063
3143
  }, [normalizedData]);
@@ -3112,7 +3192,6 @@ function MobileCardTable({
3112
3192
  "div",
3113
3193
  {
3114
3194
  role: "listitem",
3115
- tabIndex: 0,
3116
3195
  "aria-label": `Item ${itemNumber} de ${pagination.totalItems}`,
3117
3196
  "aria-describedby": cardContentId,
3118
3197
  className: "focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-focus-ring",
@@ -3137,7 +3216,7 @@ function MobileCardTable({
3137
3216
  "aria-label": `Detalhes do item ${itemNumber}`,
3138
3217
  "aria-describedby": expandedContentId,
3139
3218
  "aria-hidden": !isExpanded || isClosingExpandedRow || void 0,
3140
- 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"}`,
3141
3220
  children: /* @__PURE__ */ jsx35("div", { id: expandedContentId, children: expandable.renderExpandedRow(item, index) })
3142
3221
  }
3143
3222
  )
@@ -3158,7 +3237,7 @@ function MobileCardTable({
3158
3237
  ]
3159
3238
  }
3160
3239
  ),
3161
- 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: [
3162
3241
  /* @__PURE__ */ jsxs20(
3163
3242
  "p",
3164
3243
  {
@@ -3225,27 +3304,43 @@ function MobileCardTable({
3225
3304
  var MobileCardTable_default = MobileCardTable;
3226
3305
 
3227
3306
  // src/hooks/useContainerBreakpoint.ts
3228
- import { useEffect as useEffect10, useState as useState6 } from "react";
3307
+ import { useEffect as useEffect10, useMemo as useMemo4, useState as useState6 } from "react";
3229
3308
  var defaultContainerBreakpoints = {
3230
3309
  mobile: 0,
3231
3310
  tablet: 640,
3232
3311
  desktop: 1024,
3233
3312
  wide: 1440
3234
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
+ }
3235
3326
  function useContainerBreakpoint(ref, options = {}) {
3236
3327
  var _a;
3237
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
+ );
3238
3336
  const [current, setCurrent] = useState6();
3239
3337
  useEffect10(() => {
3240
3338
  const element = ref.current;
3241
3339
  if (!element) return;
3242
- const resolve = (width) => {
3243
- const entries = Object.entries(thresholds).sort(([, a], [, b]) => a - b);
3244
- return entries.reduce(
3245
- (result, [name, threshold]) => width >= threshold ? name : result,
3246
- void 0
3247
- );
3248
- };
3340
+ const resolve = (width) => sortedThresholds.reduce(
3341
+ (result, [name, threshold]) => width >= threshold ? name : result,
3342
+ void 0
3343
+ );
3249
3344
  const update = () => setCurrent(resolve(element.getBoundingClientRect().width));
3250
3345
  if (typeof ResizeObserver === "undefined") {
3251
3346
  update();
@@ -3255,7 +3350,7 @@ function useContainerBreakpoint(ref, options = {}) {
3255
3350
  observer.observe(element);
3256
3351
  update();
3257
3352
  return () => observer.disconnect();
3258
- }, [ref, thresholds]);
3353
+ }, [ref, sortedThresholds]);
3259
3354
  return current;
3260
3355
  }
3261
3356
 
@@ -3286,6 +3381,8 @@ export {
3286
3381
  InfoGrid,
3287
3382
  InfoItem,
3288
3383
  FilterBar,
3384
+ normalizeStatus,
3385
+ resolveStatusAppearance,
3289
3386
  StatusBadge,
3290
3387
  getStatusBadgeClassName,
3291
3388
  DomainStatusBadge,
@@ -3295,6 +3392,7 @@ export {
3295
3392
  FormErrorNavigation,
3296
3393
  Table_default,
3297
3394
  MobileCardTable_default,
3395
+ resolveContainerBreakpoint,
3298
3396
  useContainerBreakpoint
3299
3397
  };
3300
- //# sourceMappingURL=chunk-PIXRKI25.js.map
3398
+ //# sourceMappingURL=chunk-EPV6UNUQ.js.map