@illinois-grad/grad-vue 2.3.2 → 2.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/GTable.vue.d.ts +1 -1
- package/dist/components/table/TableColumn.d.ts +3 -1
- package/dist/compose/useTableChanges.d.ts +45 -25
- package/dist/grad-vue.css +1 -1
- package/dist/grad-vue.d.ts +1 -1
- package/dist/grad-vue.js +167 -146
- package/dist/grad-vue.js.map +1 -1
- package/dist/{main-BKw4zajF.js → main-8xPutD6u.js} +117 -116
- package/dist/{main-BKw4zajF.js.map → main-8xPutD6u.js.map} +1 -1
- package/dist/plugin.js +1 -1
- package/package.json +1 -1
package/dist/grad-vue.js
CHANGED
|
@@ -1,218 +1,239 @@
|
|
|
1
|
-
import { e as
|
|
2
|
-
import { unrefElement as
|
|
3
|
-
import { ref as
|
|
4
|
-
function
|
|
5
|
-
const
|
|
6
|
-
Array.from(
|
|
1
|
+
import { e as W, G as _, _ as j, j as q, x as J, z as Y, A as X, s as Z, t as ee, y as te, B as ne, r as re, k as se, p as oe, q as ae, b as ue, d as ce, g as ie, f as le, c as ge, h as he, i as de, C as me, m as fe, n as ve, o as pe, u as Ee, v as Ge, a as we, l as Ce, w as ye, V as be, P as Ie, D as Me, Q as Te, O as Se, N as Ve, M as ke, L as xe, J as Le, K as Be, E as De, F as Oe, H as Ae, I as Fe } from "./main-8xPutD6u.js";
|
|
2
|
+
import { unrefElement as T, useMutationObserver as x, useIntersectionObserver as L, useMediaQuery as B, createEventHook as D } from "@vueuse/core";
|
|
3
|
+
import { ref as V, useId as O, onMounted as A, watch as F, onBeforeUnmount as P, shallowReactive as S, computed as w } from "vue";
|
|
4
|
+
function N(r, i, o) {
|
|
5
|
+
const h = [0, 0.25, 0.5, 0.75, 1], f = `${-i}px 0px 0px 0px`, l = /* @__PURE__ */ new Map(), a = V(
|
|
6
|
+
Array.from(T(r)?.children || [])
|
|
7
7
|
);
|
|
8
|
-
|
|
8
|
+
x(
|
|
9
9
|
r,
|
|
10
10
|
() => {
|
|
11
11
|
a.value = Array.from(
|
|
12
|
-
|
|
12
|
+
T(r)?.children || []
|
|
13
13
|
);
|
|
14
14
|
},
|
|
15
15
|
{ childList: !0 }
|
|
16
16
|
);
|
|
17
|
-
const { stop:
|
|
17
|
+
const { stop: m } = L(
|
|
18
18
|
a,
|
|
19
|
-
(
|
|
19
|
+
(d) => {
|
|
20
20
|
const v = a.value[a.value.length - 1];
|
|
21
|
-
for (const u of
|
|
22
|
-
|
|
21
|
+
for (const u of d)
|
|
22
|
+
l.set(
|
|
23
23
|
u.target,
|
|
24
24
|
u.isIntersecting ? Math.ceil(100 * u.intersectionRatio) / 100 : 0
|
|
25
|
-
), u.target === v && u.intersectionRatio === 1 &&
|
|
25
|
+
), u.target === v && u.intersectionRatio === 1 && l.set(u.target, Number.POSITIVE_INFINITY);
|
|
26
26
|
let p = null, E = 0;
|
|
27
|
-
for (const u of
|
|
28
|
-
const G =
|
|
27
|
+
for (const u of l.keys()) {
|
|
28
|
+
const G = l.get(u) || 0;
|
|
29
29
|
G <= E || (u.getBoundingClientRect(), p = u, E = G);
|
|
30
30
|
}
|
|
31
31
|
p instanceof HTMLElement ? o.value = p.id : o.value = "";
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
|
-
threshold:
|
|
34
|
+
threshold: h,
|
|
35
35
|
root: null,
|
|
36
|
-
rootMargin:
|
|
36
|
+
rootMargin: f,
|
|
37
37
|
immediate: !0
|
|
38
38
|
}
|
|
39
39
|
);
|
|
40
|
-
return { stop:
|
|
40
|
+
return { stop: m };
|
|
41
41
|
}
|
|
42
|
-
function
|
|
43
|
-
const i =
|
|
42
|
+
function Q(r = "(max-width: 800px)") {
|
|
43
|
+
const i = O(), o = V(!1), h = B(r, {
|
|
44
44
|
ssrWidth: 1e3
|
|
45
45
|
});
|
|
46
|
-
function
|
|
47
|
-
if (!
|
|
46
|
+
function f(a) {
|
|
47
|
+
if (!h.value || !o.value)
|
|
48
48
|
return;
|
|
49
|
-
const
|
|
50
|
-
|
|
49
|
+
const m = a.target, d = document.getElementById(`${i}-sidebar`);
|
|
50
|
+
d && (d.contains(m) || setTimeout(() => {
|
|
51
51
|
o.value = !1;
|
|
52
52
|
}, 5));
|
|
53
53
|
}
|
|
54
|
-
function
|
|
55
|
-
if (!
|
|
54
|
+
function l(a) {
|
|
55
|
+
if (!h.value || !o.value)
|
|
56
56
|
return;
|
|
57
|
-
const
|
|
58
|
-
|
|
57
|
+
const m = a.target, d = document.getElementById(`${i}-sidebar`), v = document.getElementById(`${i}-hamburger`);
|
|
58
|
+
d && (d.contains(m) || v?.contains(m) || setTimeout(() => {
|
|
59
59
|
o.value = !1;
|
|
60
60
|
}, 5));
|
|
61
61
|
}
|
|
62
|
-
return
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
return A(() => {
|
|
63
|
+
F(
|
|
64
|
+
h,
|
|
65
65
|
(a) => {
|
|
66
|
-
a ? (document.addEventListener("mousedown",
|
|
66
|
+
a ? (document.addEventListener("mousedown", f), document.addEventListener("focusin", l)) : (document.removeEventListener("mousedown", f), document.removeEventListener("focusin", l));
|
|
67
67
|
},
|
|
68
68
|
{ immediate: !0 }
|
|
69
69
|
);
|
|
70
|
-
}),
|
|
71
|
-
document.removeEventListener("mousedown",
|
|
70
|
+
}), P(() => {
|
|
71
|
+
document.removeEventListener("mousedown", f), document.removeEventListener("focusin", l);
|
|
72
72
|
}), {
|
|
73
73
|
id: i,
|
|
74
74
|
open: o,
|
|
75
|
-
isCollapsible:
|
|
75
|
+
isCollapsible: h,
|
|
76
76
|
toggle: () => o.value = !o.value
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
|
-
function
|
|
80
|
-
const r =
|
|
81
|
-
const n =
|
|
82
|
-
r.has(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
function $() {
|
|
80
|
+
const r = S(/* @__PURE__ */ new Map()), i = D(), o = (e) => {
|
|
81
|
+
const n = e.column.key, t = e.row.key, s = e.value, c = e.previousValue;
|
|
82
|
+
r.has(t) || r.set(
|
|
83
|
+
t,
|
|
84
|
+
S(/* @__PURE__ */ new Map())
|
|
85
|
+
);
|
|
86
|
+
const g = r.get(
|
|
87
|
+
t
|
|
88
|
+
), C = g.get(n), y = C ? C.previousValue : c, M = C?.error;
|
|
89
|
+
if (s === y)
|
|
90
|
+
g.delete(n), g.size === 0 && r.delete(t), i.trigger({
|
|
91
|
+
rowKey: t,
|
|
92
|
+
columnKey: n,
|
|
93
|
+
row: e.row,
|
|
94
|
+
previousValue: y,
|
|
95
|
+
newValue: null
|
|
96
|
+
});
|
|
86
97
|
else {
|
|
87
|
-
const
|
|
88
|
-
rowKey:
|
|
98
|
+
const b = {
|
|
99
|
+
rowKey: t,
|
|
89
100
|
columnKey: n,
|
|
90
|
-
|
|
101
|
+
row: e.row,
|
|
102
|
+
previousValue: y,
|
|
91
103
|
newValue: s
|
|
92
104
|
};
|
|
93
|
-
|
|
105
|
+
M !== void 0 && (b.error = M), g.set(n, b), i.trigger(b);
|
|
94
106
|
}
|
|
95
|
-
},
|
|
96
|
-
const
|
|
107
|
+
}, h = w(() => {
|
|
108
|
+
const e = [];
|
|
97
109
|
return r.forEach((n) => {
|
|
98
|
-
n.forEach((
|
|
99
|
-
|
|
110
|
+
n.forEach((t) => {
|
|
111
|
+
e.push({ ...t });
|
|
100
112
|
});
|
|
101
|
-
}),
|
|
113
|
+
}), e;
|
|
114
|
+
}), f = () => {
|
|
115
|
+
const e = /* @__PURE__ */ new Map();
|
|
116
|
+
return r.forEach((n, t) => {
|
|
117
|
+
const s = { key: t };
|
|
118
|
+
n.forEach((c, g) => {
|
|
119
|
+
s[g] = c.newValue;
|
|
120
|
+
}), e.set(t, s);
|
|
121
|
+
}), e;
|
|
122
|
+
}, l = w(() => r.size > 0), a = (e, n) => {
|
|
123
|
+
const t = r.get(e);
|
|
124
|
+
return t ? t.has(n) : !1;
|
|
125
|
+
}, m = (e, n) => {
|
|
126
|
+
const t = r.get(e);
|
|
127
|
+
return t ? t.get(n)?.newValue : void 0;
|
|
102
128
|
}, d = () => {
|
|
103
|
-
const t = /* @__PURE__ */ new Map();
|
|
104
|
-
return r.forEach((n, e) => {
|
|
105
|
-
const s = { key: e };
|
|
106
|
-
n.forEach((m, f) => {
|
|
107
|
-
s[f] = m.newValue;
|
|
108
|
-
}), t.set(e, s);
|
|
109
|
-
}), t;
|
|
110
|
-
}, c = () => r.size > 0, a = (t, n) => {
|
|
111
|
-
const e = r.get(t);
|
|
112
|
-
return e ? e.has(String(n)) : !1;
|
|
113
|
-
}, h = (t, n) => {
|
|
114
|
-
const e = r.get(t);
|
|
115
|
-
return e ? e.get(String(n))?.newValue : void 0;
|
|
116
|
-
}, l = () => {
|
|
117
129
|
r.clear();
|
|
118
|
-
}, v = (
|
|
119
|
-
r.delete(
|
|
120
|
-
}, p = (
|
|
121
|
-
const
|
|
122
|
-
if (!
|
|
130
|
+
}, v = (e) => {
|
|
131
|
+
r.delete(e);
|
|
132
|
+
}, p = (e) => e.map((n) => {
|
|
133
|
+
const t = r.get(n.key);
|
|
134
|
+
if (!t || t.size === 0)
|
|
123
135
|
return n;
|
|
124
136
|
const s = { ...n };
|
|
125
|
-
return
|
|
126
|
-
s[
|
|
137
|
+
return t.forEach((c, g) => {
|
|
138
|
+
s[g] = c.newValue;
|
|
127
139
|
}), s;
|
|
128
|
-
}), E = () => {
|
|
129
|
-
let
|
|
140
|
+
}), E = w(() => {
|
|
141
|
+
let e = 0;
|
|
130
142
|
return r.forEach((n) => {
|
|
131
|
-
|
|
132
|
-
}),
|
|
133
|
-
}, u = (
|
|
134
|
-
|
|
143
|
+
e += n.size;
|
|
144
|
+
}), e;
|
|
145
|
+
}), u = w(
|
|
146
|
+
() => h.value.some(
|
|
147
|
+
(e) => e.error !== void 0 && e.error !== ""
|
|
148
|
+
)
|
|
149
|
+
), G = (e, n, t) => {
|
|
150
|
+
const s = r.get(e);
|
|
151
|
+
if (!s) return;
|
|
152
|
+
const c = s.get(n);
|
|
153
|
+
if (!c) return;
|
|
154
|
+
const g = { ...c, error: t };
|
|
155
|
+
s.set(n, g);
|
|
156
|
+
}, k = (e, n) => {
|
|
157
|
+
const t = r.get(e);
|
|
158
|
+
if (!t) return;
|
|
159
|
+
const s = t.get(n);
|
|
135
160
|
if (!s) return;
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
},
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
const s = e.get(String(n));
|
|
142
|
-
s && delete s.error;
|
|
143
|
-
}, b = (t, n) => {
|
|
144
|
-
const e = r.get(t);
|
|
145
|
-
return e ? e.get(String(n))?.error : void 0;
|
|
161
|
+
const c = { ...s };
|
|
162
|
+
delete c.error, t.set(n, c);
|
|
163
|
+
}, I = (e, n) => {
|
|
164
|
+
const t = r.get(e);
|
|
165
|
+
return t ? t.get(n)?.error : void 0;
|
|
146
166
|
};
|
|
147
167
|
return {
|
|
148
168
|
trackChange: o,
|
|
149
|
-
|
|
150
|
-
getChangesByRow:
|
|
151
|
-
hasChanges:
|
|
169
|
+
changes: h,
|
|
170
|
+
getChangesByRow: f,
|
|
171
|
+
hasChanges: l,
|
|
152
172
|
hasChange: a,
|
|
153
|
-
getChange:
|
|
154
|
-
clearChanges:
|
|
173
|
+
getChange: m,
|
|
174
|
+
clearChanges: d,
|
|
155
175
|
clearRowChanges: v,
|
|
156
176
|
applyChangesToData: p,
|
|
157
177
|
changeCount: E,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
178
|
+
hasErrors: u,
|
|
179
|
+
setError: G,
|
|
180
|
+
clearError: k,
|
|
181
|
+
getError: I,
|
|
182
|
+
hasError: (e, n) => {
|
|
183
|
+
const t = I(e, n);
|
|
184
|
+
return t !== void 0 && t !== "";
|
|
164
185
|
},
|
|
165
186
|
onChange: i.on
|
|
166
187
|
};
|
|
167
188
|
}
|
|
168
189
|
export {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
190
|
+
W as GAlertDialog,
|
|
191
|
+
_ as GAppHeader,
|
|
192
|
+
j as GButton,
|
|
193
|
+
q as GClipboard,
|
|
194
|
+
J as GCurrencyInput,
|
|
195
|
+
Y as GDateInput,
|
|
196
|
+
X as GDateRangeInput,
|
|
197
|
+
Z as GDetailList,
|
|
198
|
+
ee as GDetailListItem,
|
|
199
|
+
te as GEmailInput,
|
|
200
|
+
ne as GForm,
|
|
201
|
+
re as GHamburgerMenu,
|
|
202
|
+
se as GHistoryScroller,
|
|
203
|
+
oe as GModal,
|
|
204
|
+
ae as GOverlay,
|
|
205
|
+
ue as GPopover,
|
|
206
|
+
ce as GProgress,
|
|
207
|
+
ie as GSearch,
|
|
208
|
+
le as GSelect,
|
|
209
|
+
ge as GSelectButton,
|
|
210
|
+
he as GSidebar,
|
|
211
|
+
de as GSidebarMenu,
|
|
212
|
+
me as GSubmitButton,
|
|
213
|
+
fe as GTable,
|
|
214
|
+
ve as GTableBody,
|
|
215
|
+
pe as GTablePagination,
|
|
216
|
+
Ee as GTermSelector,
|
|
217
|
+
Ge as GTermSelectorControl,
|
|
218
|
+
we as GTextInput,
|
|
219
|
+
Ce as GThreeWayToggle,
|
|
199
220
|
ye as GUserMenu,
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
221
|
+
be as VGtooltip,
|
|
222
|
+
Ie as asArray,
|
|
223
|
+
Me as calculatePopoverPosition,
|
|
224
|
+
Te as emptyAsUndefined,
|
|
225
|
+
Se as filterAsQuery,
|
|
226
|
+
Ve as filterOmitEmpty,
|
|
227
|
+
ke as filtersToQueryParams,
|
|
228
|
+
N as useActiveLinkContent,
|
|
229
|
+
xe as useFiltering,
|
|
230
|
+
Le as useForm,
|
|
231
|
+
Be as useFormField,
|
|
232
|
+
De as useOverlayEscape,
|
|
233
|
+
Oe as useOverlayFocus,
|
|
234
|
+
Ae as useOverlayStack,
|
|
235
|
+
Fe as useOverlayStackState,
|
|
236
|
+
Q as useSidebar,
|
|
237
|
+
$ as useTableChanges
|
|
217
238
|
};
|
|
218
239
|
//# sourceMappingURL=grad-vue.js.map
|
package/dist/grad-vue.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grad-vue.js","sources":["../src/compose/useActiveLink.ts","../src/compose/useSidebar.ts","../src/compose/useTableChanges.ts"],"sourcesContent":["import { unrefElement, useIntersectionObserver, useMutationObserver } from \"@vueuse/core\";\nimport { ref, Ref } from \"vue\";\n\n/**\n * Monitor a list of elements' intersection with the viewport to update active links.\n *\n * This updates the activeLink store with the active content's ID for use in menus.\n *\n * @param element Children of this element will be observed\n * @param topOffset Offset from the top of the window to consider not visible\n * @param activeId Ref to store the active element ID\n */\nexport function useActiveLinkContent(\n element: Ref<HTMLElement | null>,\n topOffset: number,\n activeId: Ref<string>,\n) {\n const thresholds = [0, 0.25, 0.5, 0.75, 1];\n const rootMargin = `${-topOffset}px 0px 0px 0px`;\n // Track most visible section in viewport\n const visibility = new Map<Element, number>();\n\n // Get the children elements to observe\n const elements = ref<HTMLElement[]>(\n Array.from(unrefElement(element)?.children || []) as HTMLElement[],\n );\n\n // To maintain reactivity, observe for changes in child elements.\n // This works better with Nuxt's rendering than passing an array of refs.\n useMutationObserver(\n element,\n () => {\n elements.value = Array.from(\n unrefElement(element)?.children || [],\n ) as HTMLElement[];\n },\n { childList: true },\n );\n\n const { stop } = useIntersectionObserver(\n elements,\n (entries) => {\n const lastElement = elements.value[elements.value.length - 1];\n\n for (const entry of entries) {\n // Use intersection ratio as visibility score\n // Round up to 2 decimal places since it can sometimes be 0.99x\n // when jumping to it with anchor links.\n visibility.set(\n entry.target,\n entry.isIntersecting ? Math.ceil(100 * entry.intersectionRatio)/100 : 0,\n );\n if (\n entry.target === lastElement &&\n entry.intersectionRatio === 1\n ) {\n // If last element is fully visible, prioritize that\n visibility.set(entry.target, Number.POSITIVE_INFINITY);\n }\n }\n // Pick the element with highest visibility\n let bestEl: Element | null = null;\n let bestScore = 0;\n for (const el of visibility.keys()) {\n const score = visibility.get(el) || 0;\n if (score <= bestScore) {\n continue;\n }\n const rect = (el as HTMLElement).getBoundingClientRect();\n bestEl = el;\n bestScore = score;\n }\n if (bestEl instanceof HTMLElement) {\n activeId.value = bestEl.id;\n } else {\n activeId.value = \"\";\n }\n },\n {\n threshold: thresholds,\n root: null,\n rootMargin,\n immediate: true,\n },\n );\n\n return { stop };\n}\n","import { onBeforeUnmount, onMounted, Ref, ref, useId, watch } from \"vue\";\nimport { useMediaQuery } from \"@vueuse/core\";\n\n/**\n * Composable to manage sidebar state and link components together.\n *\n * @param breakpoint Media query string for when the sidebar should be collapsible\n */\nexport function useSidebar(\n breakpoint: Ref<string> | string = \"(max-width: 800px)\",\n) {\n const id = useId();\n const open = ref(false);\n const isCollapsible: Ref<boolean> = useMediaQuery(breakpoint, {\n ssrWidth: 1000\n });\n\n function onDocumentClick(e: MouseEvent) {\n if (!isCollapsible.value || !open.value) {\n return;\n }\n const target = e.target as HTMLElement;\n const sidebarEl = document.getElementById(`${id}-sidebar`);\n if (!sidebarEl) {\n return;\n }\n if (sidebarEl.contains(target)) {\n return;\n }\n // Very slight delay means if they click the menu button to close it,\n // it won't re-open\n setTimeout(() => {\n open.value = false;\n }, 5);\n }\n function onDocumentFocus(e: FocusEvent) {\n if (!isCollapsible.value || !open.value) {\n return;\n }\n const target = e.target as HTMLElement;\n const sidebarEl = document.getElementById(`${id}-sidebar`);\n const hamburgerEl = document.getElementById(`${id}-hamburger`);\n if (!sidebarEl) {\n return;\n }\n if (sidebarEl.contains(target) || hamburgerEl?.contains(target)) {\n return;\n }\n // Very slight delay means if they click the menu button to close it,\n // it won't re-open\n setTimeout(() => {\n open.value = false;\n }, 5);\n }\n\n onMounted(() => {\n watch(\n isCollapsible,\n (val) => {\n if (val) {\n document.addEventListener(\"mousedown\", onDocumentClick);\n document.addEventListener(\"focusin\", onDocumentFocus);\n } else {\n document.removeEventListener(\"mousedown\", onDocumentClick);\n document.removeEventListener(\"focusin\", onDocumentFocus);\n }\n },\n { immediate: true },\n );\n });\n\n onBeforeUnmount(() => {\n document.removeEventListener(\"mousedown\", onDocumentClick);\n document.removeEventListener(\"focusin\", onDocumentFocus);\n });\n\n return {\n id,\n open,\n isCollapsible,\n toggle: () => (open.value = !open.value),\n };\n}\n","import { reactive} from \"vue\";\nimport { TableColumn, TableRow } from \"../components/table/TableColumn.ts\";\nimport { createEventHook, EventHook, EventHookOn } from \"@vueuse/core\";\n\n/**\n * Represents a single cell change in the table\n */\nexport interface CellChange<T = any, K extends TableRow = TableRow> {\n rowKey: string;\n columnKey: keyof K;\n /**\n * Represents the original value before user changes.\n */\n previousValue: T;\n /**\n * New value from the change. This will be null in events\n * if the new value is the same as the original.\n */\n newValue: T;\n error?: string;\n}\n\n/**\n * Payload for the `trackChange` function\n */\nexport interface CellChangePayload<T extends TableRow = TableRow> {\n row: T;\n column: TableColumn<T>;\n value: any;\n previousValue: any;\n}\n\n/**\n * Map of changes organized by row key and column key\n */\nexport type ChangeMap = Map<string, Map<string, CellChange>>;\n\n/**\n * Return type for the useTableChanges composable\n */\nexport interface UseTableChangesReturn<T extends TableRow> {\n /**\n * Track a change to a cell\n */\n trackChange: (payload: CellChangePayload<any>) => void;\n \n /**\n * Get all changes as an array\n */\n getChanges: () => CellChange[];\n \n /**\n * Get changes organized by row\n */\n getChangesByRow: () => Map<string, Partial<T>>;\n \n /**\n * Check if there are any changes\n */\n hasChanges: () => boolean;\n \n /**\n * Check if a specific cell has changes\n */\n hasChange: (rowKey: string, columnKey: keyof T) => boolean;\n \n /**\n * Get the changed value for a specific cell, or undefined if no change\n */\n getChange: (rowKey: string, columnKey: keyof T) => any | undefined;\n \n /**\n * Clear all tracked changes\n */\n clearChanges: () => void;\n \n /**\n * Clear changes for a specific row\n */\n clearRowChanges: (rowKey: string) => void;\n \n /**\n * Apply tracked changes to a new dataset (for merging with updated data)\n */\n applyChangesToData: (data: T[]) => T[];\n \n /**\n * Get count of changed cells\n */\n changeCount: () => number;\n \n /**\n * Set an error message for a specific cell\n */\n setError: (rowKey: string, columnKey: keyof T, error: string) => void;\n \n /**\n * Clear the error for a specific cell\n */\n clearError: (rowKey: string, columnKey: keyof T) => void;\n \n /**\n * Get the error message for a specific cell, or undefined if no error\n */\n getError: (rowKey: string, columnKey: keyof T) => string | undefined;\n \n /**\n * Check if a specific cell has an error\n */\n hasError: (rowKey: string, columnKey: keyof T) => boolean;\n\n /**\n * Event emitted when a cell changes.\n *\n * `newValue` will be null if the cell's value is the same as the original.\n */\n onChange: EventHookOn<CellChange<any, T>>;\n}\n\n/**\n * Composable for tracking changes to table data\n * \n * This composable helps manage user edits to table data by:\n * - Tracking which cells have been modified\n * - Storing both old and new values\n * - Providing methods to retrieve just the changes (not full data)\n * - Allowing changes to be applied to updated data for real-time syncing\n * \n * @example\n * ```typescript\n * const changes = useTableChanges<ProductRow>();\n * \n * // Track a change when user edits a cell\n * function handleCellChange(row, column, newValue) {\n * changes.trackChange(row.key, column.key, newValue, row[column.key]);\n * }\n * \n * // Get all changes to submit\n * const changedData = changes.getChanges();\n * await api.updateProducts(changedData);\n * \n * // Apply user changes to fresh data from server\n * const freshData = await api.getProducts();\n * const mergedData = changes.applyChangesToData(freshData);\n * ```\n */\nexport function useTableChanges<T extends TableRow>(): UseTableChangesReturn<T> {\n // Store changes in a reactive map: rowKey -> columnKey -> CellChange\n const changes = reactive<ChangeMap>(new Map());\n\n const changeEvent = createEventHook<CellChange<any, T>>();\n \n /**\n * Track a change to a specific cell\n */\n const trackChange = (payload: CellChangePayload) => {\n const colKey = payload.column.key as string;\n const rowKey = payload.row.key;\n const newValue = payload.value;\n const previousValue = payload.previousValue;\n\n if (!changes.has(rowKey)) {\n changes.set(rowKey, new Map());\n }\n \n const rowChanges = changes.get(rowKey)!;\n \n // If there's already a change for this cell, preserve the original previousValue\n const existingChange = rowChanges.get(colKey);\n const originalpreviousValue = existingChange ? existingChange.previousValue : previousValue;\n const existingError = existingChange?.error;\n \n // If the new value equals the original value, remove the change\n if (newValue === originalpreviousValue) {\n rowChanges.delete(colKey);\n // Clean up empty row maps\n if (rowChanges.size === 0) {\n changes.delete(rowKey);\n }\n // null newValue means the value was reverted to the original\n changeEvent.trigger({ rowKey, columnKey: colKey, previousValue: originalpreviousValue, newValue: null });\n } else {\n // Store or update the change, preserving error if it exists\n const updatedChange: CellChange = {\n rowKey,\n columnKey: colKey,\n previousValue: originalpreviousValue,\n newValue,\n };\n \n // Preserve error if it exists\n if (existingError !== undefined) {\n updatedChange.error = existingError;\n }\n \n rowChanges.set(colKey, updatedChange);\n changeEvent.trigger(updatedChange);\n }\n };\n \n /**\n * Get all changes as a flat array\n */\n const getChanges = (): CellChange[] => {\n const result: CellChange[] = [];\n changes.forEach((rowChanges) => {\n rowChanges.forEach((change) => {\n result.push({ ...change });\n });\n });\n return result;\n };\n \n /**\n * Get changes organized by row key\n * Returns a map of rowKey -> object with changed fields\n */\n const getChangesByRow = (): Map<string, Partial<T>> => {\n const result = new Map<string, Partial<T>>();\n changes.forEach((rowChanges, rowKey) => {\n const rowData: Partial<T> = { key: rowKey } as any;\n rowChanges.forEach((change, columnKey) => {\n rowData[columnKey as keyof T] = change.newValue;\n });\n result.set(rowKey, rowData);\n });\n return result;\n };\n \n /**\n * Check if there are any changes\n */\n const hasChanges = (): boolean => {\n return changes.size > 0;\n };\n \n /**\n * Check if a specific cell has changes\n */\n const hasChange = (rowKey: string, columnKey: keyof T): boolean => {\n const rowChanges = changes.get(rowKey);\n if (!rowChanges) return false;\n return rowChanges.has(String(columnKey));\n };\n \n /**\n * Get the changed value for a specific cell\n */\n const getChange = (rowKey: string, columnKey: keyof T): any | undefined => {\n const rowChanges = changes.get(rowKey);\n if (!rowChanges) return undefined;\n const change = rowChanges.get(String(columnKey));\n return change?.newValue;\n };\n \n /**\n * Clear all tracked changes\n */\n const clearChanges = () => {\n changes.clear();\n };\n \n /**\n * Clear changes for a specific row\n */\n const clearRowChanges = (rowKey: string) => {\n changes.delete(rowKey);\n };\n \n /**\n * Apply tracked changes to a new dataset\n * This is useful when you have fresh data from the server but want to preserve user edits\n */\n const applyChangesToData = (data: T[]): T[] => {\n return data.map((row) => {\n const rowChanges = changes.get(row.key);\n if (!rowChanges || rowChanges.size === 0) {\n return row;\n }\n \n // Create a new object with the row data and apply changes\n const updatedRow = { ...row };\n rowChanges.forEach((change, columnKey) => {\n updatedRow[columnKey as keyof T] = change.newValue;\n });\n \n return updatedRow;\n });\n };\n \n /**\n * Get count of changed cells\n */\n const changeCount = (): number => {\n let count = 0;\n changes.forEach((rowChanges) => {\n count += rowChanges.size;\n });\n return count;\n };\n \n /**\n * Set an error message for a specific cell\n */\n const setError = (rowKey: string, columnKey: keyof T, error: string) => {\n const rowChanges = changes.get(rowKey);\n if (!rowChanges) return;\n \n const change = rowChanges.get(String(columnKey));\n if (!change) return;\n \n change.error = error;\n };\n \n /**\n * Clear the error for a specific cell\n */\n const clearError = (rowKey: string, columnKey: keyof T) => {\n const rowChanges = changes.get(rowKey);\n if (!rowChanges) return;\n \n const change = rowChanges.get(String(columnKey));\n if (!change) return;\n \n delete change.error;\n };\n \n /**\n * Get the error message for a specific cell\n */\n const getError = (rowKey: string, columnKey: keyof T): string | undefined => {\n const rowChanges = changes.get(rowKey);\n if (!rowChanges) return undefined;\n \n const change = rowChanges.get(String(columnKey));\n return change?.error;\n };\n \n /**\n * Check if a specific cell has an error\n */\n const hasError = (rowKey: string, columnKey: keyof T): boolean => {\n const error = getError(rowKey, columnKey);\n return error !== undefined && error !== '';\n };\n \n return {\n trackChange,\n getChanges,\n getChangesByRow,\n hasChanges,\n hasChange,\n getChange,\n clearChanges,\n clearRowChanges,\n applyChangesToData,\n changeCount,\n setError,\n clearError,\n getError,\n hasError,\n onChange: changeEvent.on\n };\n}\n"],"names":["useActiveLinkContent","element","topOffset","activeId","thresholds","rootMargin","visibility","elements","ref","unrefElement","useMutationObserver","stop","useIntersectionObserver","entries","lastElement","entry","bestEl","bestScore","el","score","useSidebar","breakpoint","id","useId","open","isCollapsible","useMediaQuery","onDocumentClick","e","target","sidebarEl","onDocumentFocus","hamburgerEl","onMounted","watch","val","onBeforeUnmount","useTableChanges","changes","reactive","changeEvent","createEventHook","trackChange","payload","colKey","rowKey","newValue","previousValue","rowChanges","existingChange","originalpreviousValue","existingError","updatedChange","getChanges","result","change","getChangesByRow","rowData","columnKey","hasChanges","hasChange","getChange","clearChanges","clearRowChanges","applyChangesToData","data","row","updatedRow","changeCount","count","setError","error","clearError","getError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"grad-vue.js","sources":["../src/compose/useActiveLink.ts","../src/compose/useSidebar.ts","../src/compose/useTableChanges.ts"],"sourcesContent":["import { unrefElement, useIntersectionObserver, useMutationObserver } from \"@vueuse/core\";\nimport { ref, Ref } from \"vue\";\n\n/**\n * Monitor a list of elements' intersection with the viewport to update active links.\n *\n * This updates the activeLink store with the active content's ID for use in menus.\n *\n * @param element Children of this element will be observed\n * @param topOffset Offset from the top of the window to consider not visible\n * @param activeId Ref to store the active element ID\n */\nexport function useActiveLinkContent(\n element: Ref<HTMLElement | null>,\n topOffset: number,\n activeId: Ref<string>,\n) {\n const thresholds = [0, 0.25, 0.5, 0.75, 1];\n const rootMargin = `${-topOffset}px 0px 0px 0px`;\n // Track most visible section in viewport\n const visibility = new Map<Element, number>();\n\n // Get the children elements to observe\n const elements = ref<HTMLElement[]>(\n Array.from(unrefElement(element)?.children || []) as HTMLElement[],\n );\n\n // To maintain reactivity, observe for changes in child elements.\n // This works better with Nuxt's rendering than passing an array of refs.\n useMutationObserver(\n element,\n () => {\n elements.value = Array.from(\n unrefElement(element)?.children || [],\n ) as HTMLElement[];\n },\n { childList: true },\n );\n\n const { stop } = useIntersectionObserver(\n elements,\n (entries) => {\n const lastElement = elements.value[elements.value.length - 1];\n\n for (const entry of entries) {\n // Use intersection ratio as visibility score\n // Round up to 2 decimal places since it can sometimes be 0.99x\n // when jumping to it with anchor links.\n visibility.set(\n entry.target,\n entry.isIntersecting ? Math.ceil(100 * entry.intersectionRatio)/100 : 0,\n );\n if (\n entry.target === lastElement &&\n entry.intersectionRatio === 1\n ) {\n // If last element is fully visible, prioritize that\n visibility.set(entry.target, Number.POSITIVE_INFINITY);\n }\n }\n // Pick the element with highest visibility\n let bestEl: Element | null = null;\n let bestScore = 0;\n for (const el of visibility.keys()) {\n const score = visibility.get(el) || 0;\n if (score <= bestScore) {\n continue;\n }\n const rect = (el as HTMLElement).getBoundingClientRect();\n bestEl = el;\n bestScore = score;\n }\n if (bestEl instanceof HTMLElement) {\n activeId.value = bestEl.id;\n } else {\n activeId.value = \"\";\n }\n },\n {\n threshold: thresholds,\n root: null,\n rootMargin,\n immediate: true,\n },\n );\n\n return { stop };\n}\n","import { onBeforeUnmount, onMounted, Ref, ref, useId, watch } from \"vue\";\nimport { useMediaQuery } from \"@vueuse/core\";\n\n/**\n * Composable to manage sidebar state and link components together.\n *\n * @param breakpoint Media query string for when the sidebar should be collapsible\n */\nexport function useSidebar(\n breakpoint: Ref<string> | string = \"(max-width: 800px)\",\n) {\n const id = useId();\n const open = ref(false);\n const isCollapsible: Ref<boolean> = useMediaQuery(breakpoint, {\n ssrWidth: 1000\n });\n\n function onDocumentClick(e: MouseEvent) {\n if (!isCollapsible.value || !open.value) {\n return;\n }\n const target = e.target as HTMLElement;\n const sidebarEl = document.getElementById(`${id}-sidebar`);\n if (!sidebarEl) {\n return;\n }\n if (sidebarEl.contains(target)) {\n return;\n }\n // Very slight delay means if they click the menu button to close it,\n // it won't re-open\n setTimeout(() => {\n open.value = false;\n }, 5);\n }\n function onDocumentFocus(e: FocusEvent) {\n if (!isCollapsible.value || !open.value) {\n return;\n }\n const target = e.target as HTMLElement;\n const sidebarEl = document.getElementById(`${id}-sidebar`);\n const hamburgerEl = document.getElementById(`${id}-hamburger`);\n if (!sidebarEl) {\n return;\n }\n if (sidebarEl.contains(target) || hamburgerEl?.contains(target)) {\n return;\n }\n // Very slight delay means if they click the menu button to close it,\n // it won't re-open\n setTimeout(() => {\n open.value = false;\n }, 5);\n }\n\n onMounted(() => {\n watch(\n isCollapsible,\n (val) => {\n if (val) {\n document.addEventListener(\"mousedown\", onDocumentClick);\n document.addEventListener(\"focusin\", onDocumentFocus);\n } else {\n document.removeEventListener(\"mousedown\", onDocumentClick);\n document.removeEventListener(\"focusin\", onDocumentFocus);\n }\n },\n { immediate: true },\n );\n });\n\n onBeforeUnmount(() => {\n document.removeEventListener(\"mousedown\", onDocumentClick);\n document.removeEventListener(\"focusin\", onDocumentFocus);\n });\n\n return {\n id,\n open,\n isCollapsible,\n toggle: () => (open.value = !open.value),\n };\n}\n","import { computed, ComputedRef, shallowReactive } from \"vue\";\nimport { TableColumn, TableRow } from \"../components/table/TableColumn.ts\";\nimport { createEventHook, EventHook, EventHookOn } from \"@vueuse/core\";\n\nexport type ColumnKey<R extends TableRow> = Extract<keyof R, string>;\n\n/**\n * Represents a single cell change in the table\n */\nexport interface CellChange<\n R extends TableRow = TableRow,\n K extends ColumnKey<R> = ColumnKey<R>,\n> {\n rowKey: string;\n columnKey: K;\n row: R;\n /**\n * Represents the original value before user changes.\n */\n previousValue: R[K];\n /**\n * New value from the change. This will be null in events\n * if the new value is the same as the original.\n */\n newValue: R[K];\n error?: string;\n}\n\nexport interface CellChangeEvent<\n R extends TableRow = TableRow,\n K extends ColumnKey<R> = ColumnKey<R>,\n> {\n rowKey: string;\n columnKey: K;\n row: R;\n previousValue: R[K];\n newValue: R[K] | null;\n error?: string;\n}\n\n/**\n * Payload for the `trackChange` function\n */\nexport interface CellChangePayload<\n T extends TableRow = TableRow,\n K extends ColumnKey<T> = ColumnKey<T>,\n> {\n row: T;\n column: TableColumn<T, K>;\n value: T[K];\n previousValue: T[K];\n}\n\n/**\n * Map of changes organized by row key and column key\n */\nexport type ChangeMap<T extends TableRow> = Map<\n string,\n Map<ColumnKey<T>, CellChange<T>>\n>;\n\n/**\n * Return type for the useTableChanges composable\n */\nexport interface UseTableChangesReturn<T extends TableRow> {\n /**\n * Track a change to a cell\n */\n trackChange: <K extends ColumnKey<T>>(payload: CellChangePayload<T, K>) => void;\n\n /**\n * Reactive array of all current changes\n */\n changes: ComputedRef<CellChange<T>[]>;\n\n /**\n * Get changes organized by row\n */\n getChangesByRow: () => Map<string, Partial<T>>;\n\n /**\n * Reactive flag indicating whether there are any changes\n */\n hasChanges: ComputedRef<boolean>;\n\n /**\n * Check if a specific cell has changes\n */\n hasChange: <K extends ColumnKey<T>>(rowKey: string, columnKey: K) => boolean;\n\n /**\n * Get the changed value for a specific cell, or undefined if no change\n */\n getChange: <K extends ColumnKey<T>>(\n rowKey: string,\n columnKey: K,\n ) => T[K] | undefined;\n\n /**\n * Clear all tracked changes\n */\n clearChanges: () => void;\n\n /**\n * Clear changes for a specific row\n */\n clearRowChanges: (rowKey: string) => void;\n\n /**\n * Apply tracked changes to a new dataset (for merging with updated data)\n */\n applyChangesToData: (data: T[]) => T[];\n\n /**\n * Reactive count of changed cells\n */\n changeCount: ComputedRef<number>;\n\n /**\n * Reactive flag indicating whether any cell has an error\n */\n hasErrors: ComputedRef<boolean>;\n\n /**\n * Set an error message for a specific cell\n */\n setError: <K extends ColumnKey<T>>(\n rowKey: string,\n columnKey: K,\n error: string,\n ) => void;\n\n /**\n * Clear the error for a specific cell\n */\n clearError: <K extends ColumnKey<T>>(rowKey: string, columnKey: K) => void;\n\n /**\n * Get the error message for a specific cell, or undefined if no error\n */\n getError: <K extends ColumnKey<T>>(\n rowKey: string,\n columnKey: K,\n ) => string | undefined;\n\n /**\n * Check if a specific cell has an error\n */\n hasError: <K extends ColumnKey<T>>(rowKey: string, columnKey: K) => boolean;\n\n /**\n * Event emitted when a cell changes.\n *\n * `newValue` will be null if the cell's value is the same as the original.\n */\n onChange: EventHookOn<CellChangeEvent<T>>;\n}\n\n/**\n * Composable for tracking changes to table data\n *\n * This composable helps manage user edits to table data by:\n * - Tracking which cells have been modified\n * - Storing both old and new values\n * - Providing methods to retrieve just the changes (not full data)\n * - Allowing changes to be applied to updated data for real-time syncing\n *\n * @example\n * ```typescript\n * const changes = useTableChanges<ProductRow>();\n *\n * // Track a change when user edits a cell\n * function handleCellChange(row, column, newValue) {\n * changes.trackChange({\n * row,\n * column,\n * value: newValue,\n * previousValue: row[column.key],\n * });\n * }\n *\n * // Get all changes to submit\n * const changedData = changes.changes.value;\n * await api.updateProducts(changedData);\n *\n * // Apply user changes to fresh data from server\n * const freshData = await api.getProducts();\n * const mergedData = changes.applyChangesToData(freshData);\n * ```\n */\nexport function useTableChanges<\n T extends TableRow,\n>(): UseTableChangesReturn<T> {\n // Store changes in a reactive map: rowKey -> columnKey -> CellChange\n const changeMap = shallowReactive<ChangeMap<T>>(new Map());\n\n const changeEvent = createEventHook<CellChangeEvent<T>>();\n\n /**\n * Track a change to a specific cell\n */\n const trackChange = <K extends ColumnKey<T>>(\n payload: CellChangePayload<T, K>,\n ) => {\n const colKey: K = payload.column.key;\n const rowKey = payload.row.key;\n const newValue: T[K] = payload.value;\n const previousValue: T[K] = payload.previousValue;\n\n if (!changeMap.has(rowKey)) {\n changeMap.set(\n rowKey,\n shallowReactive(new Map<ColumnKey<T>, CellChange<T>>()),\n );\n }\n\n const rowChanges = changeMap.get(\n rowKey,\n )!;\n\n // If there's already a change for this cell, preserve the original previousValue\n const existingChange = rowChanges.get(colKey);\n const originalpreviousValue: T[K] = (existingChange\n ? existingChange.previousValue\n : previousValue) as T[K];\n const existingError = existingChange?.error;\n\n // If the new value equals the original value, remove the change\n if (newValue === originalpreviousValue) {\n rowChanges.delete(colKey);\n // Clean up empty row maps\n if (rowChanges.size === 0) {\n changeMap.delete(rowKey);\n }\n // null newValue means the value was reverted to the original\n changeEvent.trigger({\n rowKey,\n columnKey: colKey,\n row: payload.row,\n previousValue: originalpreviousValue,\n newValue: null,\n });\n } else {\n // Store or update the change, preserving error if it exists\n const updatedChange: CellChange<T, K> = {\n rowKey,\n columnKey: colKey,\n row: payload.row,\n previousValue: originalpreviousValue,\n newValue,\n };\n\n // Preserve error if it exists\n if (existingError !== undefined) {\n updatedChange.error = existingError;\n }\n\n rowChanges.set(colKey, updatedChange);\n changeEvent.trigger(updatedChange);\n }\n };\n\n const changes = computed(() => {\n const result: CellChange<T>[] = [];\n changeMap.forEach((rowChanges) => {\n rowChanges.forEach((change) => {\n result.push({ ...change });\n });\n });\n return result;\n });\n\n /**\n * Get changes organized by row key\n * Returns a map of rowKey -> object with changed fields\n */\n const getChangesByRow = (): Map<string, Partial<T>> => {\n const result = new Map<string, Partial<T>>();\n changeMap.forEach((rowChanges, rowKey) => {\n const rowData: Partial<T> = { key: rowKey } as Partial<T>;\n rowChanges.forEach((change, columnKey) => {\n rowData[columnKey] = change.newValue;\n });\n result.set(rowKey, rowData);\n });\n return result;\n };\n\n const hasChanges = computed<boolean>(() => changeMap.size > 0);\n\n /**\n * Check if a specific cell has changes\n */\n const hasChange = <K extends ColumnKey<T>>(\n rowKey: string,\n columnKey: K,\n ): boolean => {\n const rowChanges = changeMap.get(rowKey);\n if (!rowChanges) return false;\n return rowChanges.has(columnKey);\n };\n\n /**\n * Get the changed value for a specific cell\n */\n const getChange = <K extends ColumnKey<T>>(\n rowKey: string,\n columnKey: K,\n ): T[K] | undefined => {\n const rowChanges = changeMap.get(rowKey);\n if (!rowChanges) return undefined;\n const change = rowChanges.get(columnKey);\n return change?.newValue as T[K] | undefined;\n };\n\n /**\n * Clear all tracked changes\n */\n const clearChanges = () => {\n changeMap.clear();\n };\n\n /**\n * Clear changes for a specific row\n */\n const clearRowChanges = (rowKey: string) => {\n changeMap.delete(rowKey);\n };\n\n /**\n * Apply tracked changes to a new dataset\n * This is useful when you have fresh data from the server but want to preserve user edits\n */\n const applyChangesToData = (data: T[]): T[] => {\n return data.map((row) => {\n const rowChanges = changeMap.get(row.key);\n if (!rowChanges || rowChanges.size === 0) {\n return row;\n }\n\n // Create a new object with the row data and apply changes\n const updatedRow = { ...row };\n rowChanges.forEach((change, columnKey) => {\n updatedRow[columnKey] = change.newValue;\n });\n\n return updatedRow;\n });\n };\n\n const changeCount = computed<number>(() => {\n let count = 0;\n changeMap.forEach((rowChanges) => {\n count += rowChanges.size;\n });\n return count;\n });\n\n const hasErrors = computed<boolean>(() =>\n changes.value.some(\n (change) => change.error !== undefined && change.error !== \"\",\n ),\n );\n\n /**\n * Set an error message for a specific cell\n */\n const setError = <K extends ColumnKey<T>>(\n rowKey: string,\n columnKey: K,\n error: string,\n ) => {\n const rowChanges = changeMap.get(rowKey);\n if (!rowChanges) return;\n\n const change = rowChanges.get(columnKey);\n if (!change) return;\n\n // With shallowReactive(Map), mutating nested objects won't trigger updates.\n // Replace the map entry so Vue can observe the change.\n const updatedChange: CellChange<T> = { ...change, error };\n rowChanges.set(columnKey, updatedChange);\n };\n\n /**\n * Clear the error for a specific cell\n */\n const clearError = <K extends ColumnKey<T>>(\n rowKey: string,\n columnKey: K,\n ) => {\n const rowChanges = changeMap.get(rowKey);\n if (!rowChanges) return;\n\n const change = rowChanges.get(columnKey);\n if (!change) return;\n\n // Replace the map entry so Vue can observe the change.\n const updatedChange: CellChange<T> = { ...change };\n delete updatedChange.error;\n rowChanges.set(columnKey, updatedChange);\n };\n\n /**\n * Get the error message for a specific cell\n */\n const getError = <K extends ColumnKey<T>>(\n rowKey: string,\n columnKey: K,\n ): string | undefined => {\n const rowChanges = changeMap.get(rowKey);\n if (!rowChanges) return undefined;\n\n const change = rowChanges.get(columnKey);\n return change?.error;\n };\n\n /**\n * Check if a specific cell has an error\n */\n const hasError = <K extends ColumnKey<T>>(\n rowKey: string,\n columnKey: K,\n ): boolean => {\n const error = getError(rowKey, columnKey);\n return error !== undefined && error !== \"\";\n };\n\n return {\n trackChange,\n changes,\n getChangesByRow,\n hasChanges,\n hasChange,\n getChange,\n clearChanges,\n clearRowChanges,\n applyChangesToData,\n changeCount,\n hasErrors,\n setError,\n clearError,\n getError,\n hasError,\n onChange: changeEvent.on,\n };\n}\n"],"names":["useActiveLinkContent","element","topOffset","activeId","thresholds","rootMargin","visibility","elements","ref","unrefElement","useMutationObserver","stop","useIntersectionObserver","entries","lastElement","entry","bestEl","bestScore","el","score","useSidebar","breakpoint","id","useId","open","isCollapsible","useMediaQuery","onDocumentClick","e","target","sidebarEl","onDocumentFocus","hamburgerEl","onMounted","watch","val","onBeforeUnmount","useTableChanges","changeMap","shallowReactive","changeEvent","createEventHook","trackChange","payload","colKey","rowKey","newValue","previousValue","rowChanges","existingChange","originalpreviousValue","existingError","updatedChange","changes","computed","result","change","getChangesByRow","rowData","columnKey","hasChanges","hasChange","getChange","clearChanges","clearRowChanges","applyChangesToData","data","row","updatedRow","changeCount","count","hasErrors","setError","error","clearError","getError"],"mappings":";;;AAYO,SAASA,EACZC,GACAC,GACAC,GACF;AACE,QAAMC,IAAa,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,GACnCC,IAAa,GAAG,CAACH,CAAS,kBAE1BI,wBAAiB,IAAA,GAGjBC,IAAWC;AAAA,IACb,MAAM,KAAKC,EAAaR,CAAO,GAAG,YAAY,CAAA,CAAE;AAAA,EAAA;AAKpD,EAAAS;AAAA,IACIT;AAAA,IACA,MAAM;AACF,MAAAM,EAAS,QAAQ,MAAM;AAAA,QACnBE,EAAaR,CAAO,GAAG,YAAY,CAAA;AAAA,MAAC;AAAA,IAE5C;AAAA,IACA,EAAE,WAAW,GAAA;AAAA,EAAK;AAGtB,QAAM,EAAE,MAAAU,MAASC;AAAA,IACbL;AAAA,IACA,CAACM,MAAY;AACT,YAAMC,IAAcP,EAAS,MAAMA,EAAS,MAAM,SAAS,CAAC;AAE5D,iBAAWQ,KAASF;AAIhB,QAAAP,EAAW;AAAA,UACPS,EAAM;AAAA,UACNA,EAAM,iBAAiB,KAAK,KAAK,MAAMA,EAAM,iBAAiB,IAAE,MAAM;AAAA,QAAA,GAGtEA,EAAM,WAAWD,KACjBC,EAAM,sBAAsB,KAG5BT,EAAW,IAAIS,EAAM,QAAQ,OAAO,iBAAiB;AAI7D,UAAIC,IAAyB,MACzBC,IAAY;AAChB,iBAAWC,KAAMZ,EAAW,QAAQ;AAChC,cAAMa,IAAQb,EAAW,IAAIY,CAAE,KAAK;AACpC,QAAIC,KAASF,MAGCC,EAAmB,sBAAA,GACjCF,IAASE,GACTD,IAAYE;AAAA,MAChB;AACA,MAAIH,aAAkB,cAClBb,EAAS,QAAQa,EAAO,KAExBb,EAAS,QAAQ;AAAA,IAEzB;AAAA,IACA;AAAA,MACI,WAAWC;AAAA,MACX,MAAM;AAAA,MACN,YAAAC;AAAA,MACA,WAAW;AAAA,IAAA;AAAA,EACf;AAGJ,SAAO,EAAE,MAAAM,EAAA;AACb;AC/EO,SAASS,EACZC,IAAmC,sBACrC;AACE,QAAMC,IAAKC,EAAA,GACLC,IAAOhB,EAAI,EAAK,GAChBiB,IAA8BC,EAAcL,GAAY;AAAA,IAC1D,UAAU;AAAA,EAAA,CACb;AAED,WAASM,EAAgBC,GAAe;AACpC,QAAI,CAACH,EAAc,SAAS,CAACD,EAAK;AAC9B;AAEJ,UAAMK,IAASD,EAAE,QACXE,IAAY,SAAS,eAAe,GAAGR,CAAE,UAAU;AACzD,IAAKQ,MAGDA,EAAU,SAASD,CAAM,KAK7B,WAAW,MAAM;AACb,MAAAL,EAAK,QAAQ;AAAA,IACjB,GAAG,CAAC;AAAA,EACR;AACA,WAASO,EAAgBH,GAAe;AACpC,QAAI,CAACH,EAAc,SAAS,CAACD,EAAK;AAC9B;AAEJ,UAAMK,IAASD,EAAE,QACXE,IAAY,SAAS,eAAe,GAAGR,CAAE,UAAU,GACnDU,IAAc,SAAS,eAAe,GAAGV,CAAE,YAAY;AAC7D,IAAKQ,MAGDA,EAAU,SAASD,CAAM,KAAKG,GAAa,SAASH,CAAM,KAK9D,WAAW,MAAM;AACb,MAAAL,EAAK,QAAQ;AAAA,IACjB,GAAG,CAAC;AAAA,EACR;AAEA,SAAAS,EAAU,MAAM;AACZ,IAAAC;AAAA,MACIT;AAAA,MACA,CAACU,MAAQ;AACL,QAAIA,KACA,SAAS,iBAAiB,aAAaR,CAAe,GACtD,SAAS,iBAAiB,WAAWI,CAAe,MAEpD,SAAS,oBAAoB,aAAaJ,CAAe,GACzD,SAAS,oBAAoB,WAAWI,CAAe;AAAA,MAE/D;AAAA,MACA,EAAE,WAAW,GAAA;AAAA,IAAK;AAAA,EAE1B,CAAC,GAEDK,EAAgB,MAAM;AAClB,aAAS,oBAAoB,aAAaT,CAAe,GACzD,SAAS,oBAAoB,WAAWI,CAAe;AAAA,EAC3D,CAAC,GAEM;AAAA,IACH,IAAAT;AAAA,IACA,MAAAE;AAAA,IACA,eAAAC;AAAA,IACA,QAAQ,MAAOD,EAAK,QAAQ,CAACA,EAAK;AAAA,EAAA;AAE1C;AC4GO,SAASa,IAEc;AAE1B,QAAMC,IAAYC,EAA8B,oBAAI,KAAK,GAEnDC,IAAcC,EAAA,GAKdC,IAAc,CAChBC,MACC;AACD,UAAMC,IAAYD,EAAQ,OAAO,KAC3BE,IAASF,EAAQ,IAAI,KACrBG,IAAiBH,EAAQ,OACzBI,IAAsBJ,EAAQ;AAEpC,IAAKL,EAAU,IAAIO,CAAM,KACrBP,EAAU;AAAA,MACNO;AAAA,MACAN,EAAgB,oBAAI,IAAA,CAAkC;AAAA,IAAA;AAI9D,UAAMS,IAAaV,EAAU;AAAA,MACzBO;AAAA,IAAA,GAIEI,IAAiBD,EAAW,IAAIJ,CAAM,GACtCM,IAA+BD,IAC/BA,EAAe,gBACfF,GACAI,IAAgBF,GAAgB;AAGtC,QAAIH,MAAaI;AACb,MAAAF,EAAW,OAAOJ,CAAM,GAEpBI,EAAW,SAAS,KACpBV,EAAU,OAAOO,CAAM,GAG3BL,EAAY,QAAQ;AAAA,QAChB,QAAAK;AAAA,QACA,WAAWD;AAAA,QACX,KAAKD,EAAQ;AAAA,QACb,eAAeO;AAAA,QACf,UAAU;AAAA,MAAA,CACb;AAAA,SACE;AAEH,YAAME,IAAkC;AAAA,QACpC,QAAAP;AAAA,QACA,WAAWD;AAAA,QACX,KAAKD,EAAQ;AAAA,QACb,eAAeO;AAAA,QACf,UAAAJ;AAAA,MAAA;AAIJ,MAAIK,MAAkB,WAClBC,EAAc,QAAQD,IAG1BH,EAAW,IAAIJ,GAAQQ,CAAa,GACpCZ,EAAY,QAAQY,CAAa;AAAA,IACrC;AAAA,EACJ,GAEMC,IAAUC,EAAS,MAAM;AAC3B,UAAMC,IAA0B,CAAA;AAChC,WAAAjB,EAAU,QAAQ,CAACU,MAAe;AAC9B,MAAAA,EAAW,QAAQ,CAACQ,MAAW;AAC3B,QAAAD,EAAO,KAAK,EAAE,GAAGC,GAAQ;AAAA,MAC7B,CAAC;AAAA,IACL,CAAC,GACMD;AAAA,EACX,CAAC,GAMKE,IAAkB,MAA+B;AACnD,UAAMF,wBAAa,IAAA;AACnB,WAAAjB,EAAU,QAAQ,CAACU,GAAYH,MAAW;AACtC,YAAMa,IAAsB,EAAE,KAAKb,EAAA;AACnC,MAAAG,EAAW,QAAQ,CAACQ,GAAQG,MAAc;AACtC,QAAAD,EAAQC,CAAS,IAAIH,EAAO;AAAA,MAChC,CAAC,GACDD,EAAO,IAAIV,GAAQa,CAAO;AAAA,IAC9B,CAAC,GACMH;AAAA,EACX,GAEMK,IAAaN,EAAkB,MAAMhB,EAAU,OAAO,CAAC,GAKvDuB,IAAY,CACdhB,GACAc,MACU;AACV,UAAMX,IAAaV,EAAU,IAAIO,CAAM;AACvC,WAAKG,IACEA,EAAW,IAAIW,CAAS,IADP;AAAA,EAE5B,GAKMG,IAAY,CACdjB,GACAc,MACmB;AACnB,UAAMX,IAAaV,EAAU,IAAIO,CAAM;AACvC,WAAKG,IACUA,EAAW,IAAIW,CAAS,GACxB,WAFE;AAAA,EAGrB,GAKMI,IAAe,MAAM;AACvB,IAAAzB,EAAU,MAAA;AAAA,EACd,GAKM0B,IAAkB,CAACnB,MAAmB;AACxC,IAAAP,EAAU,OAAOO,CAAM;AAAA,EAC3B,GAMMoB,IAAqB,CAACC,MACjBA,EAAK,IAAI,CAACC,MAAQ;AACrB,UAAMnB,IAAaV,EAAU,IAAI6B,EAAI,GAAG;AACxC,QAAI,CAACnB,KAAcA,EAAW,SAAS;AACnC,aAAOmB;AAIX,UAAMC,IAAa,EAAE,GAAGD,EAAA;AACxB,WAAAnB,EAAW,QAAQ,CAACQ,GAAQG,MAAc;AACtC,MAAAS,EAAWT,CAAS,IAAIH,EAAO;AAAA,IACnC,CAAC,GAEMY;AAAA,EACX,CAAC,GAGCC,IAAcf,EAAiB,MAAM;AACvC,QAAIgB,IAAQ;AACZ,WAAAhC,EAAU,QAAQ,CAACU,MAAe;AAC9B,MAAAsB,KAAStB,EAAW;AAAA,IACxB,CAAC,GACMsB;AAAA,EACX,CAAC,GAEKC,IAAYjB;AAAA,IAAkB,MAChCD,EAAQ,MAAM;AAAA,MACV,CAACG,MAAWA,EAAO,UAAU,UAAaA,EAAO,UAAU;AAAA,IAAA;AAAA,EAC/D,GAMEgB,IAAW,CACb3B,GACAc,GACAc,MACC;AACD,UAAMzB,IAAaV,EAAU,IAAIO,CAAM;AACvC,QAAI,CAACG,EAAY;AAEjB,UAAMQ,IAASR,EAAW,IAAIW,CAAS;AACvC,QAAI,CAACH,EAAQ;AAIb,UAAMJ,IAA+B,EAAE,GAAGI,GAAQ,OAAAiB,EAAA;AAClD,IAAAzB,EAAW,IAAIW,GAAWP,CAAa;AAAA,EAC3C,GAKMsB,IAAa,CACf7B,GACAc,MACC;AACD,UAAMX,IAAaV,EAAU,IAAIO,CAAM;AACvC,QAAI,CAACG,EAAY;AAEjB,UAAMQ,IAASR,EAAW,IAAIW,CAAS;AACvC,QAAI,CAACH,EAAQ;AAGb,UAAMJ,IAA+B,EAAE,GAAGI,EAAA;AAC1C,WAAOJ,EAAc,OACrBJ,EAAW,IAAIW,GAAWP,CAAa;AAAA,EAC3C,GAKMuB,IAAW,CACb9B,GACAc,MACqB;AACrB,UAAMX,IAAaV,EAAU,IAAIO,CAAM;AACvC,WAAKG,IAEUA,EAAW,IAAIW,CAAS,GACxB,QAHE;AAAA,EAIrB;AAaA,SAAO;AAAA,IACH,aAAAjB;AAAA,IACA,SAAAW;AAAA,IACA,iBAAAI;AAAA,IACA,YAAAG;AAAA,IACA,WAAAC;AAAA,IACA,WAAAC;AAAA,IACA,cAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,oBAAAC;AAAA,IACA,aAAAI;AAAA,IACA,WAAAE;AAAA,IACA,UAAAC;AAAA,IACA,YAAAE;AAAA,IACA,UAAAC;AAAA,IACA,UAvBa,CACb9B,GACAc,MACU;AACV,YAAMc,IAAQE,EAAS9B,GAAQc,CAAS;AACxC,aAAOc,MAAU,UAAaA,MAAU;AAAA,IAC5C;AAAA,IAkBI,UAAUjC,EAAY;AAAA,EAAA;AAE9B;"}
|