@caspeco/casper-ui-library 7.7.4 → 7.8.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,14 +1,14 @@
1
1
  import { jsxs as f, jsx as i } from "react/jsx-runtime";
2
- import { useStyleConfig as L, Flex as c, Box as u, Input as N } from "@chakra-ui/react";
3
- import { Fragment as X } from "react";
4
- import { ComboboxItem as _ } from "./combobox-item.js";
5
- import { Tag as $ } from "../tag/tag.js";
6
- import { Icon as K } from "../icon/icon.js";
7
- import { Icons as T } from "../icon/types.js";
8
- import { ThemeColorVariable as r, ThemeSpaceVariable as d, ThemeRadiusVariable as U, ThemeIconSizeVariable as q } from "../../theme/theme-types.js";
9
- function E() {
2
+ import { useStyleConfig as N, Flex as c, Box as d, Input as X } from "@chakra-ui/react";
3
+ import { Fragment as $ } from "react";
4
+ import { ComboboxItem as E } from "./combobox-item.js";
5
+ import { Tag as K } from "../tag/tag.js";
6
+ import { Icon as U } from "../icon/icon.js";
7
+ import { Icons as q } from "../icon/types.js";
8
+ import { ThemeColorVariable as r, ThemeSpaceVariable as u, ThemeRadiusVariable as G, ThemeIconSizeVariable as J } from "../../theme/theme-types.js";
9
+ function j() {
10
10
  return /* @__PURE__ */ i(
11
- u,
11
+ d,
12
12
  {
13
13
  backgroundColor: r.NeutralContainer,
14
14
  width: "8px",
@@ -26,51 +26,51 @@ function E() {
26
26
  }
27
27
  );
28
28
  }
29
- function I({
30
- id: j,
29
+ function oo({
30
+ id: B,
31
31
  asPlainText: e,
32
- inputValue: b,
32
+ inputValue: h,
33
33
  selectedItems: n,
34
- displayItems: B,
34
+ displayItems: R,
35
35
  toggleItem: C,
36
36
  highlightState: l,
37
37
  openState: a,
38
- parentStrings: R,
39
- size: V,
40
- variant: W,
38
+ parentStrings: V,
39
+ size: W,
40
+ variant: v,
41
41
  label: S,
42
- placeHolderText: v,
43
- isDisabled: h,
42
+ placeHolderText: s,
43
+ isDisabled: b,
44
44
  isReadOnly: m,
45
- isInvalid: t,
46
- collapsed: s,
47
- hasPendingDelete: w,
45
+ isInvalid: w,
46
+ collapsed: k,
47
+ hasPendingDelete: t,
48
48
  setHasPendingDelete: g,
49
- setInputValue: k,
50
- onSearch: O,
49
+ setInputValue: O,
50
+ onSearch: y,
51
51
  isSingleSelect: z
52
52
  }) {
53
- const A = L("Combobox", { size: V, variant: W }), D = (o) => {
54
- if (o.key === "Enter" && (o.preventDefault(), o.stopPropagation(), a.isOpen ? C(B[l.index]) : a.open()), o.key === "Escape") {
53
+ const A = N("Combobox", { size: W, variant: v }), D = (o) => {
54
+ if (o.key === "Enter" && (o.preventDefault(), o.stopPropagation(), a.isOpen ? C(R[l.index]) : a.open()), o.key === "Escape") {
55
55
  if (!a.isOpen) return;
56
- o.preventDefault(), o.stopPropagation(), a.close(), e || (k(""), O?.(""));
56
+ o.preventDefault(), o.stopPropagation(), a.close(), e || (O(""), y?.(""));
57
57
  }
58
- o.key === "Backspace" ? b.length === 0 && n.length > 0 && !e && (w ? (C(n[n.length - 1]), g(!1)) : g(!0)) : g(!1), o.key === "ArrowDown" && (a.isOpen ? l.next() : a.open()), o.key === "ArrowUp" && (a.isOpen ? l.previous() : a.open());
58
+ o.key === "Backspace" ? h.length === 0 && n.length > 0 && !e && (t ? (C(n[n.length - 1]), g(!1)) : g(!0)) : g(!1), o.key === "ArrowDown" && (a.isOpen ? l.next() : a.open()), o.key === "ArrowUp" && (a.isOpen ? l.previous() : a.open());
59
59
  }, F = (o) => {
60
60
  o.preventDefault(), o.stopPropagation();
61
61
  const p = o.target.value;
62
- k(p), O?.(p), l.set(0), a.open();
63
- }, x = n[0], y = n[n.length - 1];
62
+ O(p), y?.(p), l.set(0), a.open();
63
+ }, x = n[0], _ = n[n.length - 1], L = a.isOpen || e || s;
64
64
  return /* @__PURE__ */ f(
65
65
  c,
66
66
  {
67
67
  __css: A,
68
- "aria-disabled": h,
68
+ "aria-disabled": b,
69
69
  "aria-readonly": m,
70
- "aria-invalid": t,
71
- borderRadius: U.Small,
72
- padding: d.Small,
73
- _focusWithin: t ? {
70
+ "aria-invalid": w,
71
+ borderRadius: G.Small,
72
+ padding: u.Small,
73
+ _focusWithin: w ? {
74
74
  borderColor: r.Error,
75
75
  boxShadow: `0 0 0 4px ${r.ErrorContainer}`,
76
76
  backgroundColor: r.Surface
@@ -87,45 +87,45 @@ function I({
87
87
  /* @__PURE__ */ f(
88
88
  c,
89
89
  {
90
- flexWrap: s || z ? "nowrap" : "wrap",
91
- gap: d.Small,
90
+ flexWrap: k || z ? "nowrap" : "wrap",
91
+ gap: u.Small,
92
92
  overflow: "hidden",
93
93
  children: [
94
- S && /* @__PURE__ */ i(u, { whiteSpace: "nowrap", children: S }),
95
- !e && (s ? n.length > 0 && y && /* @__PURE__ */ f(
94
+ S && /* @__PURE__ */ i(d, { whiteSpace: "nowrap", children: S }),
95
+ !e && (k ? n.length > 0 && _ && /* @__PURE__ */ f(
96
96
  c,
97
97
  {
98
- gap: d.XSmall,
98
+ gap: u.XSmall,
99
99
  flexShrink: "1",
100
100
  overflow: "hidden",
101
101
  whiteSpace: "nowrap",
102
102
  textOverflow: "ellipsis",
103
103
  children: [
104
- n.length > 3 && /* @__PURE__ */ i(E, {}),
105
- n.length > 2 && /* @__PURE__ */ i(E, {}),
106
- n.length > 1 && /* @__PURE__ */ i($, { children: n.length - 1 }),
104
+ n.length > 3 && /* @__PURE__ */ i(j, {}),
105
+ n.length > 2 && /* @__PURE__ */ i(j, {}),
106
+ n.length > 1 && /* @__PURE__ */ i(K, { children: n.length - 1 }),
107
107
  /* @__PURE__ */ i(
108
- _,
108
+ E,
109
109
  {
110
- isDeleting: w,
111
- item: y,
110
+ isDeleting: t,
111
+ item: _,
112
112
  asPlainText: e
113
113
  }
114
114
  )
115
115
  ]
116
116
  }
117
117
  ) : n.map((o, p) => /* @__PURE__ */ i(
118
- _,
118
+ E,
119
119
  {
120
120
  item: o,
121
121
  asPlainText: e,
122
- isDeleting: p === n.length - 1 && w
122
+ isDeleting: p === n.length - 1 && t
123
123
  },
124
124
  o.id
125
125
  ))),
126
- e && n.length > 0 && x && b === x.label && R[x.id]?.map((o) => /* @__PURE__ */ f(X, { children: [
126
+ e && n.length > 0 && x && h === x.label && V[x.id]?.map((o) => /* @__PURE__ */ f($, { children: [
127
127
  /* @__PURE__ */ i(
128
- u,
128
+ d,
129
129
  {
130
130
  color: r.OnSurfaceSubdued,
131
131
  textOverflow: "ellipsis",
@@ -134,22 +134,22 @@ function I({
134
134
  children: o
135
135
  }
136
136
  ),
137
- /* @__PURE__ */ i(u, { color: r.OnSurfaceSubdued, children: "/" })
137
+ /* @__PURE__ */ i(d, { color: r.OnSurfaceSubdued, children: "/" })
138
138
  ] }, o)),
139
139
  /* @__PURE__ */ i(
140
- N,
140
+ X,
141
141
  {
142
- id: j,
143
- isDisabled: h,
142
+ id: B,
143
+ isDisabled: b,
144
144
  isReadOnly: m,
145
- isInvalid: t,
145
+ isInvalid: w,
146
146
  onKeyDown: D,
147
147
  variant: "unstyled",
148
- value: b,
148
+ value: h,
149
149
  autoComplete: "off",
150
- minWidth: d.XLarge,
150
+ minWidth: u.XLarge,
151
151
  onChange: F,
152
- placeholder: v,
152
+ placeholder: s,
153
153
  border: "none",
154
154
  flex: 1,
155
155
  color: r.OnSurface,
@@ -161,7 +161,7 @@ function I({
161
161
  cursor: "not-allowed",
162
162
  color: r.OnSurfaceSubdued
163
163
  },
164
- sx: a.isOpen ? {} : {
164
+ sx: L ? {} : {
165
165
  position: "absolute",
166
166
  width: "1px",
167
167
  height: "1px",
@@ -178,11 +178,11 @@ function I({
178
178
  }
179
179
  ),
180
180
  /* @__PURE__ */ i(c, { className: "combobox-dropdown-icon", justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ i(
181
- K,
181
+ U,
182
182
  {
183
- icon: T.TreeViewCollapse,
184
- size: q.Small,
185
- color: h || m ? r.OnSurfaceSubdued : r.OnSurface
183
+ icon: q.TreeViewCollapse,
184
+ size: J.Small,
185
+ color: b || m ? r.OnSurfaceSubdued : r.OnSurface
186
186
  }
187
187
  ) })
188
188
  ]
@@ -190,5 +190,5 @@ function I({
190
190
  );
191
191
  }
192
192
  export {
193
- I as ComboboxButton
193
+ oo as ComboboxButton
194
194
  };
@@ -1,5 +1,22 @@
1
1
  import { ThemeStyleProps } from '../../theme/index.js';
2
2
  import { TableData, TableRow as TableRowType } from './types.js';
3
+ interface VirtualizationOptions {
4
+ /**
5
+ * Estimated row height in pixels for virtualization calculations.
6
+ * @default 40
7
+ */
8
+ estimateRowHeight?: number;
9
+ /**
10
+ * Number of items to render outside the visible area for smoother scrolling.
11
+ * @default 5
12
+ */
13
+ overscan?: number;
14
+ /**
15
+ * Height of the scroll container. Can be a number (pixels) or string (e.g., "600px", "100vh").
16
+ * @default "600px"
17
+ */
18
+ height?: number | string;
19
+ }
3
20
  export interface TableContentProps<TData extends TableData = TableData> {
4
21
  /**
5
22
  * Returns the data of clicked row. Not applicable to header row.
@@ -22,8 +39,12 @@ export interface TableContentProps<TData extends TableData = TableData> {
22
39
  * When true, makes table headers (th) sticky
23
40
  */
24
41
  stickyHeaders?: boolean;
42
+ /**
43
+ * Enables virtualization for the table rows to improve performance with large datasets.
44
+ */
45
+ virtualization?: VirtualizationOptions;
25
46
  }
26
- declare const TableContentInner: <TData extends TableData>({ onClickRow, onRowClickIndication, hideTableHeaderDropdown, showRowHoverStyle, stickyHeaders, ...props }: TableContentProps<TData> & ThemeStyleProps) => import("react/jsx-runtime").JSX.Element;
47
+ declare const TableContentInner: <TData extends TableData>({ onClickRow, onRowClickIndication, hideTableHeaderDropdown, showRowHoverStyle, stickyHeaders, virtualization, ...props }: TableContentProps<TData> & ThemeStyleProps) => import("react/jsx-runtime").JSX.Element;
27
48
  export declare const TableContent: typeof TableContentInner;
28
49
  export {};
29
50
  //# sourceMappingURL=table-content.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"table-content.d.ts","sourceRoot":"","sources":["../../../lib/components/table/table-content.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAM/C,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,SAAS,CAAC;AAEnE,MAAM,WAAW,iBAAiB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS;IACrE;;OAEG;IACH,UAAU,CAAC,EAAE,CACZ,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,EACxB,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,KACnF,IAAI,CAAC;IAEV;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,QAAA,MAAM,iBAAiB,GAAI,KAAK,SAAS,SAAS,EAAE,2GAOjD,iBAAiB,CAAC,KAAK,CAAC,GAAG,eAAe,4CAuD5C,CAAC;AAEF,eAAO,MAAM,YAAY,EAA8B,OAAO,iBAAiB,CAAC"}
1
+ {"version":3,"file":"table-content.d.ts","sourceRoot":"","sources":["../../../lib/components/table/table-content.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAO/C,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,SAAS,CAAC;AAEnE,UAAU,qBAAqB;IAC9B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS;IACrE;;OAEG;IACH,UAAU,CAAC,EAAE,CACZ,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,EACxB,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,KACnF,IAAI,CAAC;IAEV;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,cAAc,CAAC,EAAE,qBAAqB,CAAC;CACvC;AAED,QAAA,MAAM,iBAAiB,GAAI,KAAK,SAAS,SAAS,EAAE,2HAQjD,iBAAiB,CAAC,KAAK,CAAC,GAAG,eAAe,4CAqI5C,CAAC;AAEF,eAAO,MAAM,YAAY,EAA8B,OAAO,iBAAiB,CAAC"}
@@ -1,58 +1,93 @@
1
- import { jsxs as c, jsx as o } from "react/jsx-runtime";
2
- import { Table as u, Thead as T, Tbody as f } from "@chakra-ui/react";
3
- import { memo as g, useMemo as r } from "react";
4
- import { useTableContext as x } from "./table-context.js";
5
- import { TableHeaderRow as C } from "./table-header-row.js";
6
- import { TableRow as y } from "./table-row.js";
7
- const R = ({
8
- onClickRow: i,
9
- onRowClickIndication: l,
10
- hideTableHeaderDropdown: s,
11
- showRowHoverStyle: a = !0,
12
- stickyHeaders: n,
13
- ...m
1
+ import { jsxs as y, jsx as e } from "react/jsx-runtime";
2
+ import { Table as M, Thead as $, Box as D, Tbody as S } from "@chakra-ui/react";
3
+ import { useVirtualizer as E } from "../../node_modules/@tanstack/react-virtual/dist/esm/index.js";
4
+ import { memo as L, useRef as O, useMemo as c } from "react";
5
+ import { useTableContext as Y } from "./table-context.js";
6
+ import { TableHeaderRow as k } from "./table-header-row.js";
7
+ import { TableRow as v } from "./table-row.js";
8
+ const q = ({
9
+ onClickRow: d,
10
+ onRowClickIndication: m,
11
+ hideTableHeaderDropdown: R,
12
+ showRowHoverStyle: g = !0,
13
+ stickyHeaders: u,
14
+ virtualization: s,
15
+ ...w
14
16
  }) => {
15
- const e = x(), b = r(() => n ? {
17
+ const t = Y(), b = O(null), z = c(() => u ? {
16
18
  position: "sticky",
17
19
  top: 0,
18
20
  zIndex: 1
19
- } : {}, [n]), d = r(
20
- () => e.table.getRowModel().rows,
21
+ } : {}, [u]), a = c(
22
+ () => t.table.getRowModel().rows,
21
23
  // The dependencies are needed to ensure that the rows are recalculated when any of these change
22
24
  // eslint-disable-next-line react-hooks/exhaustive-deps
23
25
  [
24
- e.expanded,
25
- e.breakingContentState,
26
- e.columnVisibility,
27
- e.sorting,
28
- e.data
26
+ t.expanded,
27
+ t.breakingContentState,
28
+ t.columnVisibility,
29
+ t.sorting,
30
+ t.data
29
31
  ]
30
- );
31
- return /* @__PURE__ */ c(u, { ...m, id: e.id, children: [
32
- /* @__PURE__ */ o(T, { style: b, children: e.table.getHeaderGroups().map((t) => /* @__PURE__ */ o(
33
- C,
32
+ ), h = a.length, r = !!s, p = s?.estimateRowHeight ?? 40, f = s?.overscan ?? 5, B = s?.height ?? "600px", H = c(
33
+ () => ({
34
+ count: h,
35
+ getScrollElement: () => b.current,
36
+ estimateSize: () => p,
37
+ overscan: f,
38
+ enabled: r
39
+ }),
40
+ [r, p, f, h]
41
+ ), x = E(H), n = r ? x.getVirtualItems() : [], I = () => {
42
+ if (!r)
43
+ return /* @__PURE__ */ e(S, { children: a.map((l) => {
44
+ const o = l.getVisibleCells();
45
+ return /* @__PURE__ */ e(
46
+ v,
47
+ {
48
+ row: l,
49
+ visibleCells: o,
50
+ onClickRow: d,
51
+ onRowClickIndication: m,
52
+ showRowHoverStyle: g
53
+ },
54
+ l.id
55
+ );
56
+ }) });
57
+ const i = n.length > 0 ? n[0]?.start ?? 0 : 0, T = n.length > 0 ? x.getTotalSize() - (n[n.length - 1]?.end ?? 0) : 0, V = a[0]?.getVisibleCells().length ?? t.table.getVisibleLeafColumns().length;
58
+ return /* @__PURE__ */ y(S, { children: [
59
+ i > 0 && /* @__PURE__ */ e("tr", { style: { height: `${i}px` }, "aria-hidden": "true", children: /* @__PURE__ */ e("td", { colSpan: V }) }),
60
+ n.map((l) => {
61
+ const o = a[l.index];
62
+ if (!o) return null;
63
+ const j = o.getVisibleCells();
64
+ return /* @__PURE__ */ e(
65
+ v,
66
+ {
67
+ row: o,
68
+ visibleCells: j,
69
+ onClickRow: d,
70
+ onRowClickIndication: m,
71
+ showRowHoverStyle: g
72
+ },
73
+ o.id
74
+ );
75
+ }),
76
+ T > 0 && /* @__PURE__ */ e("tr", { style: { height: `${T}px` }, "aria-hidden": "true", children: /* @__PURE__ */ e("td", { colSpan: V }) })
77
+ ] });
78
+ }, C = /* @__PURE__ */ y(M, { ...w, id: t.id, children: [
79
+ /* @__PURE__ */ e($, { style: z, children: t.table.getHeaderGroups().map((i) => /* @__PURE__ */ e(
80
+ k,
34
81
  {
35
- headerGroup: t,
36
- hideTableHeaderDropdown: s
82
+ headerGroup: i,
83
+ hideTableHeaderDropdown: R
37
84
  },
38
- t.id
85
+ i.id
39
86
  )) }),
40
- /* @__PURE__ */ o(f, { children: d.map((t) => {
41
- const p = t.getVisibleCells();
42
- return /* @__PURE__ */ o(
43
- y,
44
- {
45
- row: t,
46
- visibleCells: p,
47
- onClickRow: i,
48
- onRowClickIndication: l,
49
- showRowHoverStyle: a
50
- },
51
- t.id
52
- );
53
- }) })
87
+ I()
54
88
  ] });
55
- }, I = g(R);
89
+ return r ? /* @__PURE__ */ e(D, { ref: b, overflowY: "auto", height: B, position: "relative", children: C }) : C;
90
+ }, Q = L(q);
56
91
  export {
57
- I as TableContent
92
+ Q as TableContent
58
93
  };
@@ -0,0 +1,35 @@
1
+ import * as r from "react";
2
+ import { flushSync as c } from "react-dom";
3
+ import { Virtualizer as f, elementScroll as i, observeElementOffset as m, observeElementRect as d } from "../../../virtual-core/dist/esm/index.js";
4
+ import { defaultKeyExtractor as R, defaultRangeExtractor as g, measureElement as z } from "../../../virtual-core/dist/esm/index.js";
5
+ const a = typeof document < "u" ? r.useLayoutEffect : r.useEffect;
6
+ function p(e) {
7
+ const n = r.useReducer(() => ({}), {})[1], o = {
8
+ ...e,
9
+ onChange: (l, u) => {
10
+ var s;
11
+ u ? c(n) : n(), (s = e.onChange) == null || s.call(e, l, u);
12
+ }
13
+ }, [t] = r.useState(
14
+ () => new f(o)
15
+ );
16
+ return t.setOptions(o), a(() => t._didMount(), []), a(() => t._willUpdate()), t;
17
+ }
18
+ function h(e) {
19
+ return p({
20
+ observeElementRect: d,
21
+ observeElementOffset: m,
22
+ scrollToFn: i,
23
+ ...e
24
+ });
25
+ }
26
+ export {
27
+ f as Virtualizer,
28
+ R as defaultKeyExtractor,
29
+ g as defaultRangeExtractor,
30
+ i as elementScroll,
31
+ z as measureElement,
32
+ m as observeElementOffset,
33
+ d as observeElementRect,
34
+ h as useVirtualizer
35
+ };
@@ -0,0 +1,497 @@
1
+ import { memo as f, notUndefined as v, approxEqual as M, debounce as z } from "./utils.js";
2
+ const b = (r) => {
3
+ const { offsetWidth: a, offsetHeight: e } = r;
4
+ return { width: a, height: e };
5
+ }, w = (r) => r, I = (r) => {
6
+ const a = Math.max(r.startIndex - r.overscan, 0), e = Math.min(r.endIndex + r.overscan, r.count - 1), s = [];
7
+ for (let t = a; t <= e; t++)
8
+ s.push(t);
9
+ return s;
10
+ }, A = (r, a) => {
11
+ const e = r.scrollElement;
12
+ if (!e)
13
+ return;
14
+ const s = r.targetWindow;
15
+ if (!s)
16
+ return;
17
+ const t = (n) => {
18
+ const { width: o, height: h } = n;
19
+ a({ width: Math.round(o), height: Math.round(h) });
20
+ };
21
+ if (t(b(e)), !s.ResizeObserver)
22
+ return () => {
23
+ };
24
+ const i = new s.ResizeObserver((n) => {
25
+ const o = () => {
26
+ const h = n[0];
27
+ if (h?.borderBoxSize) {
28
+ const c = h.borderBoxSize[0];
29
+ if (c) {
30
+ t({ width: c.inlineSize, height: c.blockSize });
31
+ return;
32
+ }
33
+ }
34
+ t(b(e));
35
+ };
36
+ r.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(o) : o();
37
+ });
38
+ return i.observe(e, { box: "border-box" }), () => {
39
+ i.unobserve(e);
40
+ };
41
+ }, E = {
42
+ passive: !0
43
+ }, S = typeof window > "u" ? !0 : "onscrollend" in window, F = (r, a) => {
44
+ const e = r.scrollElement;
45
+ if (!e)
46
+ return;
47
+ const s = r.targetWindow;
48
+ if (!s)
49
+ return;
50
+ let t = 0;
51
+ const i = r.options.useScrollendEvent && S ? () => {
52
+ } : z(
53
+ s,
54
+ () => {
55
+ a(t, !1);
56
+ },
57
+ r.options.isScrollingResetDelay
58
+ ), n = (l) => () => {
59
+ const { horizontal: d, isRtl: u } = r.options;
60
+ t = d ? e.scrollLeft * (u && -1 || 1) : e.scrollTop, i(), a(t, l);
61
+ }, o = n(!0), h = n(!1);
62
+ h(), e.addEventListener("scroll", o, E);
63
+ const c = r.options.useScrollendEvent && S;
64
+ return c && e.addEventListener("scrollend", h, E), () => {
65
+ e.removeEventListener("scroll", o), c && e.removeEventListener("scrollend", h);
66
+ };
67
+ }, C = (r, a, e) => {
68
+ if (a?.borderBoxSize) {
69
+ const s = a.borderBoxSize[0];
70
+ if (s)
71
+ return Math.round(
72
+ s[e.options.horizontal ? "inlineSize" : "blockSize"]
73
+ );
74
+ }
75
+ return r[e.options.horizontal ? "offsetWidth" : "offsetHeight"];
76
+ }, N = (r, {
77
+ adjustments: a = 0,
78
+ behavior: e
79
+ }, s) => {
80
+ var t, i;
81
+ const n = r + a;
82
+ (i = (t = s.scrollElement) == null ? void 0 : t.scrollTo) == null || i.call(t, {
83
+ [s.options.horizontal ? "left" : "top"]: n,
84
+ behavior: e
85
+ });
86
+ };
87
+ class W {
88
+ constructor(a) {
89
+ this.unsubs = [], this.scrollElement = null, this.targetWindow = null, this.isScrolling = !1, this.measurementsCache = [], this.itemSizeCache = /* @__PURE__ */ new Map(), this.pendingMeasuredCacheIndexes = [], this.scrollRect = null, this.scrollOffset = null, this.scrollDirection = null, this.scrollAdjustments = 0, this.elementsCache = /* @__PURE__ */ new Map(), this.observer = /* @__PURE__ */ (() => {
90
+ let e = null;
91
+ const s = () => e || (!this.targetWindow || !this.targetWindow.ResizeObserver ? null : e = new this.targetWindow.ResizeObserver((t) => {
92
+ t.forEach((i) => {
93
+ const n = () => {
94
+ this._measureElement(i.target, i);
95
+ };
96
+ this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(n) : n();
97
+ });
98
+ }));
99
+ return {
100
+ disconnect: () => {
101
+ var t;
102
+ (t = s()) == null || t.disconnect(), e = null;
103
+ },
104
+ observe: (t) => {
105
+ var i;
106
+ return (i = s()) == null ? void 0 : i.observe(t, { box: "border-box" });
107
+ },
108
+ unobserve: (t) => {
109
+ var i;
110
+ return (i = s()) == null ? void 0 : i.unobserve(t);
111
+ }
112
+ };
113
+ })(), this.range = null, this.setOptions = (e) => {
114
+ Object.entries(e).forEach(([s, t]) => {
115
+ typeof t > "u" && delete e[s];
116
+ }), this.options = {
117
+ debug: !1,
118
+ initialOffset: 0,
119
+ overscan: 1,
120
+ paddingStart: 0,
121
+ paddingEnd: 0,
122
+ scrollPaddingStart: 0,
123
+ scrollPaddingEnd: 0,
124
+ horizontal: !1,
125
+ getItemKey: w,
126
+ rangeExtractor: I,
127
+ onChange: () => {
128
+ },
129
+ measureElement: C,
130
+ initialRect: { width: 0, height: 0 },
131
+ scrollMargin: 0,
132
+ gap: 0,
133
+ indexAttribute: "data-index",
134
+ initialMeasurementsCache: [],
135
+ lanes: 1,
136
+ isScrollingResetDelay: 150,
137
+ enabled: !0,
138
+ isRtl: !1,
139
+ useScrollendEvent: !1,
140
+ useAnimationFrameWithResizeObserver: !1,
141
+ ...e
142
+ };
143
+ }, this.notify = (e) => {
144
+ var s, t;
145
+ (t = (s = this.options).onChange) == null || t.call(s, this, e);
146
+ }, this.maybeNotify = f(
147
+ () => (this.calculateRange(), [
148
+ this.isScrolling,
149
+ this.range ? this.range.startIndex : null,
150
+ this.range ? this.range.endIndex : null
151
+ ]),
152
+ (e) => {
153
+ this.notify(e);
154
+ },
155
+ {
156
+ key: process.env.NODE_ENV !== "production" && "maybeNotify",
157
+ debug: () => this.options.debug,
158
+ initialDeps: [
159
+ this.isScrolling,
160
+ this.range ? this.range.startIndex : null,
161
+ this.range ? this.range.endIndex : null
162
+ ]
163
+ }
164
+ ), this.cleanup = () => {
165
+ this.unsubs.filter(Boolean).forEach((e) => e()), this.unsubs = [], this.observer.disconnect(), this.scrollElement = null, this.targetWindow = null;
166
+ }, this._didMount = () => () => {
167
+ this.cleanup();
168
+ }, this._willUpdate = () => {
169
+ var e;
170
+ const s = this.options.enabled ? this.options.getScrollElement() : null;
171
+ if (this.scrollElement !== s) {
172
+ if (this.cleanup(), !s) {
173
+ this.maybeNotify();
174
+ return;
175
+ }
176
+ this.scrollElement = s, this.scrollElement && "ownerDocument" in this.scrollElement ? this.targetWindow = this.scrollElement.ownerDocument.defaultView : this.targetWindow = ((e = this.scrollElement) == null ? void 0 : e.window) ?? null, this.elementsCache.forEach((t) => {
177
+ this.observer.observe(t);
178
+ }), this._scrollToOffset(this.getScrollOffset(), {
179
+ adjustments: void 0,
180
+ behavior: void 0
181
+ }), this.unsubs.push(
182
+ this.options.observeElementRect(this, (t) => {
183
+ this.scrollRect = t, this.maybeNotify();
184
+ })
185
+ ), this.unsubs.push(
186
+ this.options.observeElementOffset(this, (t, i) => {
187
+ this.scrollAdjustments = 0, this.scrollDirection = i ? this.getScrollOffset() < t ? "forward" : "backward" : null, this.scrollOffset = t, this.isScrolling = i, this.maybeNotify();
188
+ })
189
+ );
190
+ }
191
+ }, this.getSize = () => this.options.enabled ? (this.scrollRect = this.scrollRect ?? this.options.initialRect, this.scrollRect[this.options.horizontal ? "width" : "height"]) : (this.scrollRect = null, 0), this.getScrollOffset = () => this.options.enabled ? (this.scrollOffset = this.scrollOffset ?? (typeof this.options.initialOffset == "function" ? this.options.initialOffset() : this.options.initialOffset), this.scrollOffset) : (this.scrollOffset = null, 0), this.getFurthestMeasurement = (e, s) => {
192
+ const t = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
193
+ for (let n = s - 1; n >= 0; n--) {
194
+ const o = e[n];
195
+ if (t.has(o.lane))
196
+ continue;
197
+ const h = i.get(
198
+ o.lane
199
+ );
200
+ if (h == null || o.end > h.end ? i.set(o.lane, o) : o.end < h.end && t.set(o.lane, !0), t.size === this.options.lanes)
201
+ break;
202
+ }
203
+ return i.size === this.options.lanes ? Array.from(i.values()).sort((n, o) => n.end === o.end ? n.index - o.index : n.end - o.end)[0] : void 0;
204
+ }, this.getMeasurementOptions = f(
205
+ () => [
206
+ this.options.count,
207
+ this.options.paddingStart,
208
+ this.options.scrollMargin,
209
+ this.options.getItemKey,
210
+ this.options.enabled
211
+ ],
212
+ (e, s, t, i, n) => (this.pendingMeasuredCacheIndexes = [], {
213
+ count: e,
214
+ paddingStart: s,
215
+ scrollMargin: t,
216
+ getItemKey: i,
217
+ enabled: n
218
+ }),
219
+ {
220
+ key: !1
221
+ }
222
+ ), this.getMeasurements = f(
223
+ () => [this.getMeasurementOptions(), this.itemSizeCache],
224
+ ({ count: e, paddingStart: s, scrollMargin: t, getItemKey: i, enabled: n }, o) => {
225
+ if (!n)
226
+ return this.measurementsCache = [], this.itemSizeCache.clear(), [];
227
+ this.measurementsCache.length === 0 && (this.measurementsCache = this.options.initialMeasurementsCache, this.measurementsCache.forEach((l) => {
228
+ this.itemSizeCache.set(l.key, l.size);
229
+ }));
230
+ const h = this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;
231
+ this.pendingMeasuredCacheIndexes = [];
232
+ const c = this.measurementsCache.slice(0, h);
233
+ for (let l = h; l < e; l++) {
234
+ const d = i(l), u = this.options.lanes === 1 ? c[l - 1] : this.getFurthestMeasurement(c, l), g = u ? u.end + this.options.gap : s + t, m = o.get(d), p = typeof m == "number" ? m : this.options.estimateSize(l), O = g + p, y = u ? u.lane : l % this.options.lanes;
235
+ c[l] = {
236
+ index: l,
237
+ start: g,
238
+ size: p,
239
+ end: O,
240
+ key: d,
241
+ lane: y
242
+ };
243
+ }
244
+ return this.measurementsCache = c, c;
245
+ },
246
+ {
247
+ key: process.env.NODE_ENV !== "production" && "getMeasurements",
248
+ debug: () => this.options.debug
249
+ }
250
+ ), this.calculateRange = f(
251
+ () => [
252
+ this.getMeasurements(),
253
+ this.getSize(),
254
+ this.getScrollOffset(),
255
+ this.options.lanes
256
+ ],
257
+ (e, s, t, i) => this.range = e.length > 0 && s > 0 ? R({
258
+ measurements: e,
259
+ outerSize: s,
260
+ scrollOffset: t,
261
+ lanes: i
262
+ }) : null,
263
+ {
264
+ key: process.env.NODE_ENV !== "production" && "calculateRange",
265
+ debug: () => this.options.debug
266
+ }
267
+ ), this.getVirtualIndexes = f(
268
+ () => {
269
+ let e = null, s = null;
270
+ const t = this.calculateRange();
271
+ return t && (e = t.startIndex, s = t.endIndex), this.maybeNotify.updateDeps([this.isScrolling, e, s]), [
272
+ this.options.rangeExtractor,
273
+ this.options.overscan,
274
+ this.options.count,
275
+ e,
276
+ s
277
+ ];
278
+ },
279
+ (e, s, t, i, n) => i === null || n === null ? [] : e({
280
+ startIndex: i,
281
+ endIndex: n,
282
+ overscan: s,
283
+ count: t
284
+ }),
285
+ {
286
+ key: process.env.NODE_ENV !== "production" && "getVirtualIndexes",
287
+ debug: () => this.options.debug
288
+ }
289
+ ), this.indexFromElement = (e) => {
290
+ const s = this.options.indexAttribute, t = e.getAttribute(s);
291
+ return t ? parseInt(t, 10) : (console.warn(
292
+ `Missing attribute name '${s}={index}' on measured element.`
293
+ ), -1);
294
+ }, this._measureElement = (e, s) => {
295
+ const t = this.indexFromElement(e), i = this.measurementsCache[t];
296
+ if (!i)
297
+ return;
298
+ const n = i.key, o = this.elementsCache.get(n);
299
+ o !== e && (o && this.observer.unobserve(o), this.observer.observe(e), this.elementsCache.set(n, e)), e.isConnected && this.resizeItem(t, this.options.measureElement(e, s, this));
300
+ }, this.resizeItem = (e, s) => {
301
+ const t = this.measurementsCache[e];
302
+ if (!t)
303
+ return;
304
+ const i = this.itemSizeCache.get(t.key) ?? t.size, n = s - i;
305
+ n !== 0 && ((this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(t, n, this) : t.start < this.getScrollOffset() + this.scrollAdjustments) && (process.env.NODE_ENV !== "production" && this.options.debug && console.info("correction", n), this._scrollToOffset(this.getScrollOffset(), {
306
+ adjustments: this.scrollAdjustments += n,
307
+ behavior: void 0
308
+ })), this.pendingMeasuredCacheIndexes.push(t.index), this.itemSizeCache = new Map(this.itemSizeCache.set(t.key, s)), this.notify(!1));
309
+ }, this.measureElement = (e) => {
310
+ if (!e) {
311
+ this.elementsCache.forEach((s, t) => {
312
+ s.isConnected || (this.observer.unobserve(s), this.elementsCache.delete(t));
313
+ });
314
+ return;
315
+ }
316
+ this._measureElement(e, void 0);
317
+ }, this.getVirtualItems = f(
318
+ () => [this.getVirtualIndexes(), this.getMeasurements()],
319
+ (e, s) => {
320
+ const t = [];
321
+ for (let i = 0, n = e.length; i < n; i++) {
322
+ const o = e[i], h = s[o];
323
+ t.push(h);
324
+ }
325
+ return t;
326
+ },
327
+ {
328
+ key: process.env.NODE_ENV !== "production" && "getVirtualItems",
329
+ debug: () => this.options.debug
330
+ }
331
+ ), this.getVirtualItemForOffset = (e) => {
332
+ const s = this.getMeasurements();
333
+ if (s.length !== 0)
334
+ return v(
335
+ s[x(
336
+ 0,
337
+ s.length - 1,
338
+ (t) => v(s[t]).start,
339
+ e
340
+ )]
341
+ );
342
+ }, this.getOffsetForAlignment = (e, s, t = 0) => {
343
+ const i = this.getSize(), n = this.getScrollOffset();
344
+ s === "auto" && (s = e >= n + i ? "end" : "start"), s === "center" ? e += (t - i) / 2 : s === "end" && (e -= i);
345
+ const o = this.getTotalSize() + this.options.scrollMargin - i;
346
+ return Math.max(Math.min(o, e), 0);
347
+ }, this.getOffsetForIndex = (e, s = "auto") => {
348
+ e = Math.max(0, Math.min(e, this.options.count - 1));
349
+ const t = this.measurementsCache[e];
350
+ if (!t)
351
+ return;
352
+ const i = this.getSize(), n = this.getScrollOffset();
353
+ if (s === "auto")
354
+ if (t.end >= n + i - this.options.scrollPaddingEnd)
355
+ s = "end";
356
+ else if (t.start <= n + this.options.scrollPaddingStart)
357
+ s = "start";
358
+ else
359
+ return [n, s];
360
+ const o = s === "end" ? t.end + this.options.scrollPaddingEnd : t.start - this.options.scrollPaddingStart;
361
+ return [
362
+ this.getOffsetForAlignment(o, s, t.size),
363
+ s
364
+ ];
365
+ }, this.isDynamicMode = () => this.elementsCache.size > 0, this.scrollToOffset = (e, { align: s = "start", behavior: t } = {}) => {
366
+ t === "smooth" && this.isDynamicMode() && console.warn(
367
+ "The `smooth` scroll behavior is not fully supported with dynamic size."
368
+ ), this._scrollToOffset(this.getOffsetForAlignment(e, s), {
369
+ adjustments: void 0,
370
+ behavior: t
371
+ });
372
+ }, this.scrollToIndex = (e, { align: s = "auto", behavior: t } = {}) => {
373
+ t === "smooth" && this.isDynamicMode() && console.warn(
374
+ "The `smooth` scroll behavior is not fully supported with dynamic size."
375
+ ), e = Math.max(0, Math.min(e, this.options.count - 1));
376
+ let i = 0;
377
+ const n = 10, o = (c) => {
378
+ if (!this.targetWindow) return;
379
+ const l = this.getOffsetForIndex(e, c);
380
+ if (!l) {
381
+ console.warn("Failed to get offset for index:", e);
382
+ return;
383
+ }
384
+ const [d, u] = l;
385
+ this._scrollToOffset(d, { adjustments: void 0, behavior: t }), this.targetWindow.requestAnimationFrame(() => {
386
+ const g = this.getScrollOffset(), m = this.getOffsetForIndex(e, u);
387
+ if (!m) {
388
+ console.warn("Failed to get offset for index:", e);
389
+ return;
390
+ }
391
+ M(m[0], g) || h(u);
392
+ });
393
+ }, h = (c) => {
394
+ this.targetWindow && (i++, i < n ? (process.env.NODE_ENV !== "production" && this.options.debug && console.info("Schedule retry", i, n), this.targetWindow.requestAnimationFrame(() => o(c))) : console.warn(
395
+ `Failed to scroll to index ${e} after ${n} attempts.`
396
+ ));
397
+ };
398
+ o(s);
399
+ }, this.scrollBy = (e, { behavior: s } = {}) => {
400
+ s === "smooth" && this.isDynamicMode() && console.warn(
401
+ "The `smooth` scroll behavior is not fully supported with dynamic size."
402
+ ), this._scrollToOffset(this.getScrollOffset() + e, {
403
+ adjustments: void 0,
404
+ behavior: s
405
+ });
406
+ }, this.getTotalSize = () => {
407
+ var e;
408
+ const s = this.getMeasurements();
409
+ let t;
410
+ if (s.length === 0)
411
+ t = this.options.paddingStart;
412
+ else if (this.options.lanes === 1)
413
+ t = ((e = s[s.length - 1]) == null ? void 0 : e.end) ?? 0;
414
+ else {
415
+ const i = Array(this.options.lanes).fill(null);
416
+ let n = s.length - 1;
417
+ for (; n >= 0 && i.some((o) => o === null); ) {
418
+ const o = s[n];
419
+ i[o.lane] === null && (i[o.lane] = o.end), n--;
420
+ }
421
+ t = Math.max(...i.filter((o) => o !== null));
422
+ }
423
+ return Math.max(
424
+ t - this.options.scrollMargin + this.options.paddingEnd,
425
+ 0
426
+ );
427
+ }, this._scrollToOffset = (e, {
428
+ adjustments: s,
429
+ behavior: t
430
+ }) => {
431
+ this.options.scrollToFn(e, { behavior: t, adjustments: s }, this);
432
+ }, this.measure = () => {
433
+ this.itemSizeCache = /* @__PURE__ */ new Map(), this.notify(!1);
434
+ }, this.setOptions(a);
435
+ }
436
+ }
437
+ const x = (r, a, e, s) => {
438
+ for (; r <= a; ) {
439
+ const t = (r + a) / 2 | 0, i = e(t);
440
+ if (i < s)
441
+ r = t + 1;
442
+ else if (i > s)
443
+ a = t - 1;
444
+ else
445
+ return t;
446
+ }
447
+ return r > 0 ? r - 1 : 0;
448
+ };
449
+ function R({
450
+ measurements: r,
451
+ outerSize: a,
452
+ scrollOffset: e,
453
+ lanes: s
454
+ }) {
455
+ const t = r.length - 1, i = (h) => r[h].start;
456
+ if (r.length <= s)
457
+ return {
458
+ startIndex: 0,
459
+ endIndex: t
460
+ };
461
+ let n = x(
462
+ 0,
463
+ t,
464
+ i,
465
+ e
466
+ ), o = n;
467
+ if (s === 1)
468
+ for (; o < t && r[o].end < e + a; )
469
+ o++;
470
+ else if (s > 1) {
471
+ const h = Array(s).fill(0);
472
+ for (; o < t && h.some((l) => l < e + a); ) {
473
+ const l = r[o];
474
+ h[l.lane] = l.end, o++;
475
+ }
476
+ const c = Array(s).fill(e + a);
477
+ for (; n >= 0 && c.some((l) => l >= e); ) {
478
+ const l = r[n];
479
+ c[l.lane] = l.start, n--;
480
+ }
481
+ n = Math.max(0, n - n % s), o = Math.min(t, o + (s - 1 - o % s));
482
+ }
483
+ return { startIndex: n, endIndex: o };
484
+ }
485
+ export {
486
+ W as Virtualizer,
487
+ M as approxEqual,
488
+ z as debounce,
489
+ w as defaultKeyExtractor,
490
+ I as defaultRangeExtractor,
491
+ N as elementScroll,
492
+ C as measureElement,
493
+ f as memo,
494
+ v as notUndefined,
495
+ F as observeElementOffset,
496
+ A as observeElementRect
497
+ };
@@ -0,0 +1,52 @@
1
+ function T(n, i, e) {
2
+ let l = e.initialDeps ?? [], t;
3
+ function r() {
4
+ var o, m, h, f;
5
+ let g;
6
+ e.key && ((o = e.debug) != null && o.call(e)) && (g = Date.now());
7
+ const u = n();
8
+ if (!(u.length !== l.length || u.some((c, a) => l[a] !== c)))
9
+ return t;
10
+ l = u;
11
+ let s;
12
+ if (e.key && ((m = e.debug) != null && m.call(e)) && (s = Date.now()), t = i(...u), e.key && ((h = e.debug) != null && h.call(e))) {
13
+ const c = Math.round((Date.now() - g) * 100) / 100, a = Math.round((Date.now() - s) * 100) / 100, b = a / 16, w = (d, v) => {
14
+ for (d = String(d); d.length < v; )
15
+ d = " " + d;
16
+ return d;
17
+ };
18
+ console.info(
19
+ `%c⏱ ${w(a, 5)} /${w(c, 5)} ms`,
20
+ `
21
+ font-size: .6rem;
22
+ font-weight: bold;
23
+ color: hsl(${Math.max(
24
+ 0,
25
+ Math.min(120 - 120 * b, 120)
26
+ )}deg 100% 31%);`,
27
+ e?.key
28
+ );
29
+ }
30
+ return (f = e?.onChange) == null || f.call(e, t), t;
31
+ }
32
+ return r.updateDeps = (o) => {
33
+ l = o;
34
+ }, r;
35
+ }
36
+ function y(n, i) {
37
+ if (n === void 0)
38
+ throw new Error("Unexpected undefined");
39
+ return n;
40
+ }
41
+ const M = (n, i) => Math.abs(n - i) < 1.01, k = (n, i, e) => {
42
+ let l;
43
+ return function(...t) {
44
+ n.clearTimeout(l), l = n.setTimeout(() => i.apply(this, t), e);
45
+ };
46
+ };
47
+ export {
48
+ M as approxEqual,
49
+ k as debounce,
50
+ T as memo,
51
+ y as notUndefined
52
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caspeco/casper-ui-library",
3
- "version": "7.7.4",
3
+ "version": "7.8.0",
4
4
  "prettier": "@caspeco/prettier-config",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -46,11 +46,11 @@
46
46
  "jsdom": "^27.2.0",
47
47
  "tsc-alias": "^1.8.16",
48
48
  "typescript": "~5.9.3",
49
- "typescript-eslint": "^8.48.0",
50
- "vite": "^7.2.4",
49
+ "typescript-eslint": "^8.48.1",
50
+ "vite": "^7.2.6",
51
51
  "vite-plugin-dts": "^4.5.4",
52
52
  "vite-tsconfig-paths": "^5.1.4",
53
- "vitest": "^4.0.14"
53
+ "vitest": "^4.0.15"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "@chakra-ui/react": "^2.8.2",
@@ -62,6 +62,7 @@
62
62
  "@chakra-ui/anatomy": "^2.3.4",
63
63
  "@floating-ui/dom": "^1.7.4",
64
64
  "@tanstack/react-table": "^8.21.3",
65
+ "@tanstack/react-virtual": "^3.13.12",
65
66
  "csstype": "^3.2.3",
66
67
  "date-fns": "^4.1.0"
67
68
  }