@vueye-table/vue 3.0.0-alpha.6 → 3.0.0-alpha.7
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/index.d.ts +30 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +290 -27
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
import { ComponentPublicInstance, ComputedRef, MaybeRefOrGetter } from "vue";
|
|
2
|
-
import { CellPosition, CellRange, ColumnDef, CopyOptions, DataTable, EditResult, GridBounds, GridDirection, GridKey, GridSelection, MoveOptions, RowKey, TableColumn, TableOptions, TableRenderItem, TableRow, TableSnapshot, TableStatePatch, TreeLoadSignal, VirtualAlign, VirtualItem, VirtualWindow } from "@vueye-table/core";
|
|
2
|
+
import { CellPosition, CellRange, ColumnDef, CopyOptions, DataTable, DeepKeys, EditResult, EditorSpec, ExpandedState, GridBounds, GridDirection, GridKey, GridSelection, MoveOptions, PathValue, PendingChanges, RowKey, TableColumn, TableIssue, TableOptions, TableRenderItem, TableRow, TableSnapshot, TableStatePatch, TreeLoadController, TreeLoadSignal, VirtualAlign, VirtualItem, VirtualWindow } from "@vueye-table/core";
|
|
3
|
+
//#region src/row-draft.d.ts
|
|
4
|
+
/** A column-value bag. Only configured columns are present; dotted paths stay dotted keys. */
|
|
5
|
+
type RowDraftValues<TRow> = { -readonly [P in DeepKeys<TRow>]?: PathValue<TRow, P>; };
|
|
6
|
+
interface RowDraft<TRow> {
|
|
7
|
+
readonly rowKey: RowKey;
|
|
8
|
+
readonly values: RowDraftValues<TRow>;
|
|
9
|
+
readonly issues: readonly TableIssue[];
|
|
10
|
+
readonly status: "editing" | "saving" | "saved" | "cancelled" | "stale";
|
|
11
|
+
readonly pending: boolean;
|
|
12
|
+
/** Supply raw text for the column parser, including numeric/date input. */
|
|
13
|
+
setInput(column: string, input: string): void;
|
|
14
|
+
/** Set a computed column whose id is not a path in the row type. */
|
|
15
|
+
setValue(column: string, value: unknown): void;
|
|
16
|
+
save(): Promise<EditResult<TRow>>;
|
|
17
|
+
/** Discard an unsubmitted draft. A submitted validation batch is owned by the engine. */
|
|
18
|
+
cancel(): boolean;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
3
21
|
//#region src/use-data-table.d.ts
|
|
4
22
|
/** Options accepted by {@link useDataTable}. Data, columns, and state may be refs or getters. */
|
|
5
|
-
interface UseDataTableOptions<TRow, TSignal extends TreeLoadSignal =
|
|
23
|
+
interface UseDataTableOptions<TRow, TSignal extends TreeLoadSignal = AbortSignal> extends Omit<TableOptions<TRow, TSignal>, "data" | "columns" | "rowCount"> {
|
|
6
24
|
readonly data: MaybeRefOrGetter<readonly TRow[]>;
|
|
7
25
|
readonly columns: MaybeRefOrGetter<readonly ColumnDef<TRow>[]>;
|
|
8
26
|
readonly rowCount?: MaybeRefOrGetter<number | undefined> | undefined;
|
|
@@ -23,6 +41,9 @@ type DataTableBinding<TRow> = TableSnapshot<TRow> & TableOperations<TRow> & {
|
|
|
23
41
|
readonly table: DataTable<TRow>;
|
|
24
42
|
/** The current snapshot, replaced on every change. */
|
|
25
43
|
readonly snapshot: TableSnapshot<TRow>;
|
|
44
|
+
readonly expanded: ExpandedState;
|
|
45
|
+
readonly pendingChanges: PendingChanges<TRow>;
|
|
46
|
+
editRow(key: RowKey): RowDraft<TRow>;
|
|
26
47
|
};
|
|
27
48
|
/**
|
|
28
49
|
* A binding for any row type, for components that accept every table. Row types make the binding
|
|
@@ -33,7 +54,10 @@ type AnyDataTableBinding = DataTableBinding<any>;
|
|
|
33
54
|
* Create a table bound to the current effect scope. The table follows its reactive data,
|
|
34
55
|
* columns, row count, and state, and stops listening when the scope ends.
|
|
35
56
|
*/
|
|
36
|
-
declare function useDataTable<TRow
|
|
57
|
+
declare function useDataTable<TRow>(options: UseDataTableOptions<TRow>): DataTableBinding<TRow>;
|
|
58
|
+
declare function useDataTable<TRow, TSignal extends TreeLoadSignal = AbortSignal>(options: UseDataTableOptions<TRow, TSignal> & (AbortSignal extends TSignal ? unknown : {
|
|
59
|
+
readonly createChildLoadController: () => TreeLoadController<TSignal>;
|
|
60
|
+
})): DataTableBinding<TRow>;
|
|
37
61
|
//#endregion
|
|
38
62
|
//#region src/use-data-grid.d.ts
|
|
39
63
|
/** The cell being edited and the text typed so far. */
|
|
@@ -53,6 +77,8 @@ interface DataGridBinding<TRow> {
|
|
|
53
77
|
readonly bounds: ComputedRef<GridBounds>;
|
|
54
78
|
/** The latest edit outcome, to show a rejected value. */
|
|
55
79
|
readonly lastResult: EditResult<TRow> | undefined;
|
|
80
|
+
/** Serializable editor metadata for an editable cell; no component resolution. */
|
|
81
|
+
editorFor(position: CellPosition): EditorSpec | undefined;
|
|
56
82
|
cellAt(position: CellPosition): {
|
|
57
83
|
row: TableRow<TRow>;
|
|
58
84
|
column: TableColumn<TRow>;
|
|
@@ -133,5 +159,5 @@ declare function useVirtualRows<TRow>(table: DataTableBinding<TRow>, options: Us
|
|
|
133
159
|
/** Virtualize visible columns and bring the active logical column into view. */
|
|
134
160
|
declare function useVirtualColumns<TRow>(grid: DataGridBinding<TRow>, options: UseVirtualColumnsOptions): VirtualBinding<VirtualColumnItem<TRow>>;
|
|
135
161
|
//#endregion
|
|
136
|
-
export { type AnyDataTableBinding, type DataGridBinding, type DataTableBinding, type GridEditor, type UseDataTableOptions, type UseVirtualColumnsOptions, type UseVirtualRowsOptions, type VirtualBinding, type VirtualColumnItem, type VirtualRowItem, type VirtualViewportOptions, injectDataGrid, injectDataTable, provideDataGrid, provideDataTable, useDataGrid, useDataTable, useVirtualColumns, useVirtualRows };
|
|
162
|
+
export { type AnyDataTableBinding, type DataGridBinding, type DataTableBinding, type GridEditor, type RowDraft, type RowDraftValues, type UseDataTableOptions, type UseVirtualColumnsOptions, type UseVirtualRowsOptions, type VirtualBinding, type VirtualColumnItem, type VirtualRowItem, type VirtualViewportOptions, injectDataGrid, injectDataTable, provideDataGrid, provideDataTable, useDataGrid, useDataTable, useVirtualColumns, useVirtualRows };
|
|
137
163
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/use-data-table.ts","../src/use-data-grid.ts","../src/injection.ts","../src/use-virtual.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/row-draft.ts","../src/use-data-table.ts","../src/use-data-grid.ts","../src/injection.ts","../src/use-virtual.ts"],"mappings":";;;;KAYY,eAAe,qBACd,KAAK,SAAS,SAAS,UAAU,MAAM;UAGnC,SAAS;WACf,QAAQ;WACR,QAAQ,eAAe;WACvB,iBAAiB;WACjB;WACA;;EAET,SAAS,gBAAgB;;EAEzB,SAAS,gBAAgB;EACzB,QAAQ,QAAQ,WAAW;;EAE3B;;;;;UCFe,oBACf,MACA,gBAAgB,iBAAiB,qBACzB,KAAK,aAAa,MAAM;WACvB,MAAM,0BAA0B;WAChC,SAAS,0BAA0B,UAAU;WAC7C,WAAW;;;;;WAKX,QAAQ,iBAAiB;;KAG/B,gBAAgB,QAAQ,KAAK,UAAU;;;;;;KAOhC,iBAAiB,QAAQ,cAAc,QACjD,gBAAgB;;WAEL,OAAO,UAAU;;WAEjB,UAAU,cAAc;WACxB,UAAU;WACV,gBAAgB,eAAe;EACxC,QAAQ,KAAK,SAAS,SAAS;;;;;;KAOvB,sBAAsB;;;;;iBAwDlB,aAAa,MAAM,SAAS,oBAAoB,QAAQ,iBAAiB;iBACzE,aAAa,MAAM,gBAAgB,iBAAiB,aAClE,SAAS,oBAAoB,MAAM,YAChC,oBAAoB;WAEN,iCAAiC,mBAAmB;KACpE,iBAAiB;;;;UChGH;WACN,UAAU;WACV;;;;;;UAOM,gBAAgB;WACtB,OAAO,iBAAiB;WACxB,WAAW;WACX,OAAO;WACP,QAAQ;WACR,QAAQ,YAAY;;WAEpB,YAAY,WAAW;;EAEhC,UAAU,UAAU,eAAe;EACnC,OAAO,UAAU;IAAiB,KAAK,SAAS;IAAO,QAAQ,YAAY;;EAC3E,UAAU,UAAU;EACpB,WAAW,UAAU;EACrB,UAAU,UAAU;EACpB,UAAU,UAAU,cAAc;aAAqB;;EACvD,KAAK,WAAW,eAAe,UAAU;EACzC;;EAEA,UAAU;EACV,YAAY;;EAEZ,WAAW,OAAO,gBAAgB,WAAW;EAC7C;;EAEA,KAAK,UAAU;;EAEf,MAAM,eAAe,WAAW;EAChC,SAAS,WAAW;;EAEpB,UAAU,OAAO;;iBAGH,YAAY,MAAM,OAAO,iBAAiB,QAAQ,gBAAgB;;;;iBC5DlE,iBAAiB,MAAM,OAAO,iBAAiB;;;;;iBAQ/C,gBAAgB,gBAC9B,oBACC,iBAAiB;iBAUJ,gBAAgB,MAAM,MAAM,gBAAgB;;iBAK5C,eAAe,mBAAmB,gBAAgB;;;UCNjD;WACN,eAAe,iBAAiB;WAChC;;WAEA;;WAEA,eAAe;;UAET,sBAAsB,cAAc;WAC1C,+BAA+B;;WAE/B,OAAO,gBAAgB;;UAEjB,iCAAiC;WACvC,iCAAiC;;UAE3B,eAAe,cAAc;WACnC,YAAY,gBAAgB;;UAEtB,kBAAkB,cAAc;WACtC,QAAQ,YAAY;;UAEd,eAAe,cAAc,qBAAqB,KAAK;WAC7D,gBAAgB;EACzB,QAAQ,gBAAgB;EACxB,cAAc,eAAe;aAAqB,QAAQ;;EAC1D,YAAY,KAAK,QAAQ;aAAqB,QAAQ;;;EAEtD,eAAe,SAAS,UAAU,gCAAgC,KAAK;;;iBA8OzD,eAAe,MAC7B,OAAO,iBAAiB,OACxB,SAAS,sBAAsB,QAC9B,eAAe,eAAe;;iBAsCjB,kBAAkB,MAChC,MAAM,gBAAgB,OACtB,SAAS,2BACR,eAAe,kBAAkB"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { computed, getCurrentInstance, getCurrentScope, inject, nextTick, onMounted, onScopeDispose, provide, shallowRef, toRaw, toValue, watch } from "vue";
|
|
2
|
-
import { clampPosition, createTable, createVirtualizer, getRowItemKey, gridCommand, moveSelection, rangeContains, selectCell, selectionRange } from "@vueye-table/core";
|
|
1
|
+
import { computed, getCurrentInstance, getCurrentScope, inject, nextTick, onMounted, onScopeDispose, provide, shallowReactive, shallowRef, toRaw, toValue, watch } from "vue";
|
|
2
|
+
import { clampPosition, createTable, createVirtualizer, getRowItemKey, gridCommand, moveSelection, rangeContains, selectCell, selectionRange, typeOf } from "@vueye-table/core";
|
|
3
3
|
|
|
4
4
|
//#region src/injection.ts
|
|
5
5
|
const tableKey = Symbol("vueye-table");
|
|
@@ -25,19 +25,191 @@ function injectDataGrid() {
|
|
|
25
25
|
return inject(gridKey, void 0);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/row-draft.ts
|
|
30
|
+
function rejectedDraft(rowKey, message) {
|
|
31
|
+
return refused([Object.freeze({
|
|
32
|
+
code: "stale_draft",
|
|
33
|
+
rowKey,
|
|
34
|
+
message
|
|
35
|
+
})]);
|
|
36
|
+
}
|
|
37
|
+
function refused(issues) {
|
|
38
|
+
return Object.freeze({
|
|
39
|
+
status: "rejected",
|
|
40
|
+
changes: Object.freeze([]),
|
|
41
|
+
rowChanges: Object.freeze([]),
|
|
42
|
+
pendingCells: Object.freeze([]),
|
|
43
|
+
issues: Object.freeze([...issues])
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function equal(left, right, seen = /* @__PURE__ */ new WeakMap()) {
|
|
47
|
+
if (Object.is(left, right)) return true;
|
|
48
|
+
if (!left || !right || typeof left !== "object" || typeof right !== "object") return false;
|
|
49
|
+
if (left instanceof Date || right instanceof Date) return left instanceof Date && right instanceof Date && Object.is(left.getTime(), right.getTime());
|
|
50
|
+
if (Array.isArray(left) && Array.isArray(right) && left.length !== right.length) return false;
|
|
51
|
+
if (Object.getPrototypeOf(left) !== Object.getPrototypeOf(right)) return false;
|
|
52
|
+
if (seen.has(left)) return seen.get(left) === right;
|
|
53
|
+
seen.set(left, right);
|
|
54
|
+
if (left instanceof Map && right instanceof Map) return equal([...left], [...right], seen);
|
|
55
|
+
if (left instanceof Set && right instanceof Set) return equal([...left], [...right], seen);
|
|
56
|
+
if (left instanceof RegExp && right instanceof RegExp) return left.source === right.source && left.flags === right.flags;
|
|
57
|
+
if (left instanceof ArrayBuffer && right instanceof ArrayBuffer) return equal([...new Uint8Array(left)], [...new Uint8Array(right)], seen);
|
|
58
|
+
if (ArrayBuffer.isView(left) && ArrayBuffer.isView(right)) return equal([...new Uint8Array(left.buffer, left.byteOffset, left.byteLength)], [...new Uint8Array(right.buffer, right.byteOffset, right.byteLength)], seen);
|
|
59
|
+
const keys = Object.keys(left);
|
|
60
|
+
return keys.length === Object.keys(right).length && keys.every((key) => Object.hasOwn(right, key) && equal(Reflect.get(left, key), Reflect.get(right, key), seen));
|
|
61
|
+
}
|
|
62
|
+
/** Internal factory; disposal is shared with the binding's single engine subscription. */
|
|
63
|
+
function createRowDraft(table, key, register) {
|
|
64
|
+
const snapshot = table.getSnapshot();
|
|
65
|
+
const original = snapshot.getRow(key)?.original;
|
|
66
|
+
const columns = snapshot.allColumns;
|
|
67
|
+
const values = shallowReactive(Object.create(null));
|
|
68
|
+
const initial = /* @__PURE__ */ new Map();
|
|
69
|
+
const inputs = /* @__PURE__ */ new Map();
|
|
70
|
+
const copyIssues = /* @__PURE__ */ new Map();
|
|
71
|
+
const issues = shallowRef([]);
|
|
72
|
+
const status = shallowRef("editing");
|
|
73
|
+
for (const column of columns) {
|
|
74
|
+
if (original === void 0) break;
|
|
75
|
+
try {
|
|
76
|
+
if (!column.isEditable(original)) continue;
|
|
77
|
+
const value = column.getValue(original);
|
|
78
|
+
initial.set(column.id, value);
|
|
79
|
+
values[column.id] = structuredClone(toRaw(value));
|
|
80
|
+
} catch {
|
|
81
|
+
copyIssues.set(column.id, Object.freeze({
|
|
82
|
+
code: "invalid_value",
|
|
83
|
+
rowKey: key,
|
|
84
|
+
column: column.id,
|
|
85
|
+
message: "This value cannot be copied into a row draft. Replace it explicitly before saving."
|
|
86
|
+
}));
|
|
87
|
+
issues.value = [...copyIssues.values()];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
let saving;
|
|
91
|
+
let disposePending;
|
|
92
|
+
let disposed = false;
|
|
93
|
+
const stale = () => rejectedDraft(key, "This draft is closed, or its row or columns changed. Open a new draft.");
|
|
94
|
+
const unregister = register(() => {
|
|
95
|
+
disposed = true;
|
|
96
|
+
const result = stale();
|
|
97
|
+
status.value = "stale";
|
|
98
|
+
issues.value = result.issues;
|
|
99
|
+
disposePending?.(result);
|
|
100
|
+
});
|
|
101
|
+
return Object.freeze({
|
|
102
|
+
rowKey: key,
|
|
103
|
+
values,
|
|
104
|
+
get issues() {
|
|
105
|
+
return issues.value;
|
|
106
|
+
},
|
|
107
|
+
get status() {
|
|
108
|
+
return status.value;
|
|
109
|
+
},
|
|
110
|
+
get pending() {
|
|
111
|
+
return status.value === "saving";
|
|
112
|
+
},
|
|
113
|
+
setInput(column, input) {
|
|
114
|
+
if (status.value === "editing") inputs.set(column, input);
|
|
115
|
+
},
|
|
116
|
+
setValue(column, value) {
|
|
117
|
+
if (status.value === "editing") {
|
|
118
|
+
values[column] = value;
|
|
119
|
+
inputs.delete(column);
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
save() {
|
|
123
|
+
if (saving) return saving;
|
|
124
|
+
if (status.value !== "editing" || disposed || original === void 0 || table.getSnapshot().getRow(key)?.original !== original || columns.some((column) => table.getSnapshot().getColumn(column.id)?.definition !== column.definition)) {
|
|
125
|
+
const result = stale();
|
|
126
|
+
issues.value = result.issues;
|
|
127
|
+
status.value = "stale";
|
|
128
|
+
unregister();
|
|
129
|
+
return Promise.resolve(result);
|
|
130
|
+
}
|
|
131
|
+
const edits = [];
|
|
132
|
+
const uncopied = [...copyIssues.values()].filter((problem) => !Object.hasOwn(values, problem.column) && !inputs.has(problem.column));
|
|
133
|
+
if (uncopied.length) {
|
|
134
|
+
issues.value = Object.freeze(uncopied);
|
|
135
|
+
return Promise.resolve(refused(issues.value));
|
|
136
|
+
}
|
|
137
|
+
for (const column of /* @__PURE__ */ new Set([...Object.keys(values), ...inputs.keys()])) try {
|
|
138
|
+
const value = toRaw(values[column]);
|
|
139
|
+
if (inputs.has(column)) edits.push({
|
|
140
|
+
rowKey: key,
|
|
141
|
+
column,
|
|
142
|
+
input: inputs.get(column)
|
|
143
|
+
});
|
|
144
|
+
else if (!initial.has(column) || !equal(value, initial.get(column))) edits.push(typeof value === "string" ? {
|
|
145
|
+
rowKey: key,
|
|
146
|
+
column,
|
|
147
|
+
input: value
|
|
148
|
+
} : {
|
|
149
|
+
rowKey: key,
|
|
150
|
+
column,
|
|
151
|
+
value: value !== null && typeof value === "object" ? structuredClone(value) : value
|
|
152
|
+
});
|
|
153
|
+
} catch {
|
|
154
|
+
issues.value = Object.freeze([Object.freeze({
|
|
155
|
+
code: "invalid_value",
|
|
156
|
+
rowKey: key,
|
|
157
|
+
column,
|
|
158
|
+
message: "This draft value cannot be copied for submission. Replace it before saving."
|
|
159
|
+
})]);
|
|
160
|
+
return Promise.resolve(refused(issues.value));
|
|
161
|
+
}
|
|
162
|
+
status.value = "saving";
|
|
163
|
+
const result = table.edit(edits, { expectedRows: /* @__PURE__ */ new Map([[key, original]]) });
|
|
164
|
+
if (disposed) return Promise.resolve(stale());
|
|
165
|
+
const cancelled = new Promise((resolve) => {
|
|
166
|
+
disposePending = resolve;
|
|
167
|
+
});
|
|
168
|
+
saving = Promise.race([result.completion ?? Promise.resolve(result), cancelled]).then((final) => {
|
|
169
|
+
issues.value = final.issues;
|
|
170
|
+
status.value = disposed || final.issues.some((problem) => problem.code === "stale_draft") ? "stale" : final.status === "rejected" ? "editing" : "saved";
|
|
171
|
+
if (status.value !== "editing") unregister();
|
|
172
|
+
saving = void 0;
|
|
173
|
+
disposePending = void 0;
|
|
174
|
+
return final;
|
|
175
|
+
});
|
|
176
|
+
return saving;
|
|
177
|
+
},
|
|
178
|
+
cancel() {
|
|
179
|
+
if (status.value !== "editing") return false;
|
|
180
|
+
status.value = "cancelled";
|
|
181
|
+
unregister();
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
28
187
|
//#endregion
|
|
29
188
|
//#region src/use-data-grid.ts
|
|
30
189
|
function useDataGrid(table) {
|
|
31
190
|
const selection = shallowRef();
|
|
32
191
|
const editor = shallowRef();
|
|
33
192
|
const lastResult = shallowRef();
|
|
193
|
+
let editing;
|
|
194
|
+
let resultToken;
|
|
195
|
+
const invalidEditors = /* @__PURE__ */ new WeakSet();
|
|
196
|
+
const record = (result) => {
|
|
197
|
+
const token = {};
|
|
198
|
+
resultToken = token;
|
|
199
|
+
lastResult.value = result;
|
|
200
|
+
result.completion?.then((final) => {
|
|
201
|
+
if (resultToken === token) lastResult.value = final;
|
|
202
|
+
});
|
|
203
|
+
return result;
|
|
204
|
+
};
|
|
34
205
|
const bounds = computed(() => ({
|
|
35
206
|
rows: table.rows.length,
|
|
36
207
|
columns: table.columns.length
|
|
37
208
|
}));
|
|
38
209
|
const range = computed(() => selection.value ? selectionRange(selection.value) : void 0);
|
|
39
210
|
const same = (left, right) => left !== void 0 && left.row === right.row && left.column === right.column;
|
|
40
|
-
watch(
|
|
211
|
+
watch(() => table.snapshot, () => {
|
|
212
|
+
const next = bounds.value;
|
|
41
213
|
const current = selection.value;
|
|
42
214
|
if (current && (next.rows === 0 || next.columns === 0)) selection.value = void 0;
|
|
43
215
|
else if (current) {
|
|
@@ -48,9 +220,32 @@ function useDataGrid(table) {
|
|
|
48
220
|
focus
|
|
49
221
|
};
|
|
50
222
|
}
|
|
51
|
-
const
|
|
52
|
-
if (
|
|
53
|
-
|
|
223
|
+
const active = editing;
|
|
224
|
+
if (active && editor.value) {
|
|
225
|
+
const row = table.rows.findIndex((candidate) => candidate.key === active.key);
|
|
226
|
+
const column = table.columns.findIndex((candidate) => candidate.id === active.column.id);
|
|
227
|
+
if (row < 0 || column < 0 || table.getRow(active.key)?.original !== active.original || table.getColumn(active.column.id)?.definition !== active.column.definition) {
|
|
228
|
+
editor.value = void 0;
|
|
229
|
+
editing = void 0;
|
|
230
|
+
record(rejectedDraft(active.key, "The edited cell changed or left the visible grid. Start a new edit."));
|
|
231
|
+
} else if (!same(editor.value.position, {
|
|
232
|
+
row,
|
|
233
|
+
column
|
|
234
|
+
})) {
|
|
235
|
+
editor.value = {
|
|
236
|
+
...editor.value,
|
|
237
|
+
position: {
|
|
238
|
+
row,
|
|
239
|
+
column
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
selection.value = selectCell({
|
|
243
|
+
row,
|
|
244
|
+
column
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}, { flush: "sync" });
|
|
54
249
|
const cellAt = (position) => {
|
|
55
250
|
const row = table.rows[position.row];
|
|
56
251
|
const column = table.columns[position.column];
|
|
@@ -83,6 +278,49 @@ function useDataGrid(table) {
|
|
|
83
278
|
},
|
|
84
279
|
bounds,
|
|
85
280
|
cellAt,
|
|
281
|
+
editorFor(position) {
|
|
282
|
+
const cell = cellAt(position);
|
|
283
|
+
if (!cell || !cell.column.isEditable(cell.row.original)) return void 0;
|
|
284
|
+
const spec = cell.column.definition.editor;
|
|
285
|
+
if (spec && [
|
|
286
|
+
"text",
|
|
287
|
+
"number",
|
|
288
|
+
"select",
|
|
289
|
+
"checkbox",
|
|
290
|
+
"date"
|
|
291
|
+
].includes(spec.kind) && (spec.options === void 0 || Array.isArray(spec.options) && spec.options.every((value) => value === null || [
|
|
292
|
+
"string",
|
|
293
|
+
"number",
|
|
294
|
+
"boolean"
|
|
295
|
+
].includes(typeof value)))) return Object.freeze({
|
|
296
|
+
kind: spec.kind,
|
|
297
|
+
...spec.options ? { options: Object.freeze([...spec.options]) } : {},
|
|
298
|
+
...spec.min !== void 0 ? { min: spec.min } : {},
|
|
299
|
+
...spec.max !== void 0 ? { max: spec.max } : {},
|
|
300
|
+
...spec.maxLength !== void 0 ? { maxLength: spec.maxLength } : {},
|
|
301
|
+
...spec.pattern !== void 0 ? { pattern: spec.pattern } : {}
|
|
302
|
+
});
|
|
303
|
+
if (spec) {
|
|
304
|
+
if (!invalidEditors.has(cell.column.definition)) {
|
|
305
|
+
invalidEditors.add(cell.column.definition);
|
|
306
|
+
record(Object.freeze({
|
|
307
|
+
status: "rejected",
|
|
308
|
+
changes: Object.freeze([]),
|
|
309
|
+
rowChanges: Object.freeze([]),
|
|
310
|
+
pendingCells: Object.freeze([]),
|
|
311
|
+
issues: Object.freeze([Object.freeze({
|
|
312
|
+
code: "invalid_value",
|
|
313
|
+
rowKey: cell.row.key,
|
|
314
|
+
column: cell.column.id,
|
|
315
|
+
message: "Invalid editor metadata; text metadata is used."
|
|
316
|
+
})])
|
|
317
|
+
}));
|
|
318
|
+
}
|
|
319
|
+
return Object.freeze({ kind: "text" });
|
|
320
|
+
}
|
|
321
|
+
const type = cell.column.definition.type ?? typeOf(cell.row.getValue(cell.column.id)) ?? "text";
|
|
322
|
+
return Object.freeze({ kind: type === "boolean" ? "checkbox" : type });
|
|
323
|
+
},
|
|
86
324
|
isFocused: (position) => same(selection.value?.focus, position),
|
|
87
325
|
isSelected: (position) => range.value ? rangeContains(range.value, position) : false,
|
|
88
326
|
isEditing: (position) => same(editor.value?.position, position),
|
|
@@ -118,6 +356,11 @@ function useDataGrid(table) {
|
|
|
118
356
|
position: focus,
|
|
119
357
|
draft: initial ?? cell.row.getDisplay(cell.column.id)
|
|
120
358
|
};
|
|
359
|
+
editing = {
|
|
360
|
+
key: cell.row.key,
|
|
361
|
+
column: cell.column,
|
|
362
|
+
original: cell.row.original
|
|
363
|
+
};
|
|
121
364
|
return true;
|
|
122
365
|
},
|
|
123
366
|
updateDraft(draft) {
|
|
@@ -129,38 +372,35 @@ function useDataGrid(table) {
|
|
|
129
372
|
commitEdit(then) {
|
|
130
373
|
const current = editor.value;
|
|
131
374
|
if (!current) return;
|
|
132
|
-
const
|
|
375
|
+
const active = editing;
|
|
133
376
|
editor.value = void 0;
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
377
|
+
editing = void 0;
|
|
378
|
+
if (!active) return;
|
|
379
|
+
const result = record(table.edit({
|
|
380
|
+
rowKey: active.key,
|
|
381
|
+
column: active.column.id,
|
|
138
382
|
input: current.draft
|
|
139
|
-
});
|
|
140
|
-
lastResult.value = result;
|
|
383
|
+
}, { expectedRows: /* @__PURE__ */ new Map([[active.key, active.original]]) }));
|
|
141
384
|
if (then) grid.move(then);
|
|
142
385
|
return result;
|
|
143
386
|
},
|
|
144
387
|
cancelEdit() {
|
|
145
388
|
editor.value = void 0;
|
|
389
|
+
editing = void 0;
|
|
146
390
|
},
|
|
147
391
|
copy(options) {
|
|
148
392
|
return range.value ? table.copy(range.value, options) : "";
|
|
149
393
|
},
|
|
150
394
|
paste(text) {
|
|
151
395
|
if (!range.value) return;
|
|
152
|
-
|
|
396
|
+
return record(table.paste({
|
|
153
397
|
row: range.value.top,
|
|
154
398
|
column: range.value.left
|
|
155
|
-
}, text);
|
|
156
|
-
lastResult.value = result;
|
|
157
|
-
return result;
|
|
399
|
+
}, text));
|
|
158
400
|
},
|
|
159
401
|
clear() {
|
|
160
402
|
if (!range.value) return;
|
|
161
|
-
|
|
162
|
-
lastResult.value = result;
|
|
163
|
-
return result;
|
|
403
|
+
return record(table.clear(range.value));
|
|
164
404
|
},
|
|
165
405
|
handleKey(event) {
|
|
166
406
|
if (editor.value) return false;
|
|
@@ -467,10 +707,6 @@ const OPERATIONS = [
|
|
|
467
707
|
function definedEntries(patch) {
|
|
468
708
|
return Object.fromEntries(Object.entries(patch ?? {}).filter(([, value]) => value !== void 0));
|
|
469
709
|
}
|
|
470
|
-
/**
|
|
471
|
-
* Create a table bound to the current effect scope. The table follows its reactive data,
|
|
472
|
-
* columns, row count, and state, and stops listening when the scope ends.
|
|
473
|
-
*/
|
|
474
710
|
function useDataTable(options) {
|
|
475
711
|
const table = createTable({
|
|
476
712
|
...options,
|
|
@@ -480,8 +716,11 @@ function useDataTable(options) {
|
|
|
480
716
|
initialState: {
|
|
481
717
|
...options.initialState,
|
|
482
718
|
...definedEntries(toValue(options.state))
|
|
483
|
-
}
|
|
719
|
+
},
|
|
720
|
+
createChildLoadController: options.createChildLoadController ?? (() => new AbortController())
|
|
484
721
|
});
|
|
722
|
+
const drafts = /* @__PURE__ */ new Set();
|
|
723
|
+
let disposed = false;
|
|
485
724
|
const snapshot = shallowRef(table.getSnapshot());
|
|
486
725
|
const unsubscribe = table.subscribe((next) => {
|
|
487
726
|
snapshot.value = next;
|
|
@@ -496,21 +735,45 @@ function useDataTable(options) {
|
|
|
496
735
|
if (state) table.setState(state);
|
|
497
736
|
}, { deep: true })
|
|
498
737
|
];
|
|
499
|
-
|
|
738
|
+
const dispose = () => {
|
|
739
|
+
if (disposed) return;
|
|
740
|
+
disposed = true;
|
|
741
|
+
for (const disposeDraft of drafts) disposeDraft();
|
|
742
|
+
drafts.clear();
|
|
500
743
|
for (const stop of stops) stop();
|
|
501
744
|
unsubscribe();
|
|
502
745
|
table.destroy();
|
|
503
|
-
}
|
|
746
|
+
};
|
|
747
|
+
if (getCurrentScope()) onScopeDispose(dispose);
|
|
504
748
|
const binding = { table };
|
|
505
749
|
Object.defineProperty(binding, "snapshot", {
|
|
506
750
|
enumerable: true,
|
|
507
751
|
get: () => snapshot.value
|
|
508
752
|
});
|
|
753
|
+
Object.defineProperty(binding, "expanded", {
|
|
754
|
+
enumerable: true,
|
|
755
|
+
get: () => snapshot.value.state.expanded
|
|
756
|
+
});
|
|
757
|
+
Object.defineProperty(binding, "pendingChanges", {
|
|
758
|
+
enumerable: true,
|
|
759
|
+
get: () => {
|
|
760
|
+
snapshot.value;
|
|
761
|
+
return table.getPendingChanges();
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
binding["editRow"] = (key) => createRowDraft(table, key, (disposeDraft) => {
|
|
765
|
+
if (disposed) disposeDraft();
|
|
766
|
+
else drafts.add(disposeDraft);
|
|
767
|
+
return () => {
|
|
768
|
+
drafts.delete(disposeDraft);
|
|
769
|
+
};
|
|
770
|
+
});
|
|
509
771
|
for (const key of Object.keys(snapshot.value)) Object.defineProperty(binding, key, {
|
|
510
772
|
enumerable: true,
|
|
511
773
|
get: () => snapshot.value[key]
|
|
512
774
|
});
|
|
513
775
|
for (const name of OPERATIONS) binding[name] = table[name];
|
|
776
|
+
binding["destroy"] = dispose;
|
|
514
777
|
return Object.freeze(binding);
|
|
515
778
|
}
|
|
516
779
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/injection.ts","../src/use-data-grid.ts","../src/use-virtual.ts","../src/use-data-table.ts"],"sourcesContent":["import { inject, provide, type InjectionKey } from \"vue\";\n\nimport type { DataGridBinding } from \"./use-data-grid\";\nimport type { DataTableBinding } from \"./use-data-table\";\n\nconst tableKey: InjectionKey<DataTableBinding<unknown>> = Symbol(\"vueye-table\");\nconst gridKey: InjectionKey<DataGridBinding<unknown>> = Symbol(\"vueye-table-grid\");\n\n/** Make a table available to every component below the current one. */\nexport function provideDataTable<TRow>(table: DataTableBinding<TRow>): void {\n provide(tableKey, table as DataTableBinding<unknown>);\n}\n\n/**\n * Read the table provided by an ancestor. Throws when there is none, naming the component that\n * provides one, rather than rendering an empty table.\n */\nexport function injectDataTable<TRow = unknown>(\n consumer = \"This component\",\n): DataTableBinding<TRow> {\n const table = inject(tableKey, undefined);\n if (!table) {\n throw new Error(\n `${consumer} needs a table. Render it inside <DataTableRoot :table=\"table\">, or call provideDataTable(useDataTable(...)) in an ancestor.`,\n );\n }\n return table as DataTableBinding<TRow>;\n}\n\nexport function provideDataGrid<TRow>(grid: DataGridBinding<TRow>): void {\n provide(gridKey, grid as DataGridBinding<unknown>);\n}\n\n/** Read the grid provided by an ancestor, or `undefined` outside a grid. */\nexport function injectDataGrid<TRow = unknown>(): DataGridBinding<TRow> | undefined {\n return inject(gridKey, undefined) as DataGridBinding<TRow> | undefined;\n}\n","import {\n clampPosition,\n gridCommand,\n moveSelection,\n rangeContains,\n selectCell,\n selectionRange,\n type CellPosition,\n type CellRange,\n type CopyOptions,\n type EditResult,\n type GridBounds,\n type GridDirection,\n type GridKey,\n type GridSelection,\n type MoveOptions,\n type TableColumn,\n type TableRow,\n} from \"@vueye-table/core\";\nimport { computed, shallowRef, watch, type ComputedRef } from \"vue\";\n\nimport type { DataTableBinding } from \"./use-data-table\";\n\n/** The cell being edited and the text typed so far. */\nexport interface GridEditor {\n readonly position: CellPosition;\n readonly draft: string;\n}\n\n/**\n * Spreadsheet interaction over a table: a selected range, keyboard navigation, in-cell editing,\n * copy, paste, and clearing. Positions refer to the current page and the visible columns.\n */\nexport interface DataGridBinding<TRow> {\n readonly table: DataTableBinding<TRow>;\n readonly selection: GridSelection | undefined;\n readonly range: CellRange | undefined;\n readonly editor: GridEditor | undefined;\n readonly bounds: ComputedRef<GridBounds>;\n /** The latest edit outcome, to show a rejected value. */\n readonly lastResult: EditResult<TRow> | undefined;\n cellAt(position: CellPosition): { row: TableRow<TRow>; column: TableColumn<TRow> } | undefined;\n isFocused(position: CellPosition): boolean;\n isSelected(position: CellPosition): boolean;\n isEditing(position: CellPosition): boolean;\n focusCell(position: CellPosition, options?: { readonly extend?: boolean | undefined }): void;\n move(direction: GridDirection, options?: MoveOptions): void;\n selectAll(): void;\n /** Start editing the focused cell, with its current text or with `initial`. */\n startEdit(initial?: string): boolean;\n updateDraft(draft: string): void;\n /** Write the draft through the table, then move the focus if asked. */\n commitEdit(then?: GridDirection): EditResult<TRow> | undefined;\n cancelEdit(): void;\n /** The selected range as tab-separated text. */\n copy(options?: CopyOptions): string;\n /** Paste tab-separated text at the top-left of the selection. */\n paste(text: string): EditResult<TRow> | undefined;\n clear(): EditResult<TRow> | undefined;\n /** Handle a key press. Returns `true` when the grid used it, so the caller can prevent the default. */\n handleKey(event: GridKey): boolean;\n}\n\nexport function useDataGrid<TRow>(table: DataTableBinding<TRow>): DataGridBinding<TRow> {\n const selection = shallowRef<GridSelection | undefined>();\n const editor = shallowRef<GridEditor | undefined>();\n const lastResult = shallowRef<EditResult<TRow> | undefined>();\n const bounds = computed<GridBounds>(() => ({\n rows: table.rows.length,\n columns: table.columns.length,\n }));\n const range = computed(() => (selection.value ? selectionRange(selection.value) : undefined));\n\n const same = (left: CellPosition | undefined, right: CellPosition): boolean =>\n left !== undefined && left.row === right.row && left.column === right.column;\n\n // Searching, filtering, paging, or hiding a column can shrink the grid under the selection.\n // Keep the selection on cells that exist, and drop an edit whose cell is gone.\n watch(bounds, (next) => {\n const current = selection.value;\n if (current && (next.rows === 0 || next.columns === 0)) {\n selection.value = undefined;\n } else if (current) {\n const anchor = clampPosition(current.anchor, next);\n const focus = clampPosition(current.focus, next);\n if (!same(current.anchor, anchor) || !same(current.focus, focus)) {\n selection.value = { anchor, focus };\n }\n }\n const position = editor.value?.position;\n if (position && (position.row >= next.rows || position.column >= next.columns)) {\n editor.value = undefined;\n }\n });\n\n const cellAt: DataGridBinding<TRow>[\"cellAt\"] = (position) => {\n const row = table.rows[position.row];\n const column = table.columns[position.column];\n return row && column ? { row, column } : undefined;\n };\n\n const ensureSelection = (): GridSelection | undefined => {\n if (bounds.value.rows === 0 || bounds.value.columns === 0) {\n return undefined;\n }\n selection.value ??= selectCell({ row: 0, column: 0 });\n return selection.value;\n };\n\n const grid: DataGridBinding<TRow> = {\n table,\n get selection() {\n return selection.value;\n },\n get range() {\n return range.value;\n },\n get editor() {\n return editor.value;\n },\n get lastResult() {\n return lastResult.value;\n },\n bounds,\n cellAt,\n isFocused: (position) => same(selection.value?.focus, position),\n isSelected: (position) => (range.value ? rangeContains(range.value, position) : false),\n isEditing: (position) => same(editor.value?.position, position),\n focusCell(position, { extend = false } = {}) {\n const target = clampPosition(position, bounds.value);\n if (editor.value && !same(editor.value.position, target)) {\n grid.commitEdit();\n }\n selection.value =\n extend && selection.value\n ? { anchor: selection.value.anchor, focus: target }\n : selectCell(target);\n },\n move(direction, options) {\n const current = ensureSelection();\n if (current) {\n selection.value = moveSelection(current, direction, bounds.value, options);\n }\n },\n selectAll() {\n if (bounds.value.rows > 0 && bounds.value.columns > 0) {\n selection.value = {\n anchor: { row: 0, column: 0 },\n focus: { row: bounds.value.rows - 1, column: bounds.value.columns - 1 },\n };\n }\n },\n startEdit(initial) {\n const focus = ensureSelection()?.focus;\n const cell = focus ? cellAt(focus) : undefined;\n if (!focus || !cell || !cell.column.isEditable(cell.row.original)) {\n return false;\n }\n editor.value = { position: focus, draft: initial ?? cell.row.getDisplay(cell.column.id) };\n return true;\n },\n updateDraft(draft) {\n if (editor.value) {\n editor.value = { position: editor.value.position, draft };\n }\n },\n commitEdit(then) {\n const current = editor.value;\n if (!current) {\n return undefined;\n }\n const cell = cellAt(current.position);\n editor.value = undefined;\n if (!cell) {\n return undefined;\n }\n const result = table.edit({\n rowKey: cell.row.key,\n column: cell.column.id,\n input: current.draft,\n });\n lastResult.value = result;\n if (then) {\n grid.move(then);\n }\n return result;\n },\n cancelEdit() {\n editor.value = undefined;\n },\n copy(options) {\n return range.value ? table.copy(range.value, options) : \"\";\n },\n paste(text) {\n if (!range.value) {\n return undefined;\n }\n const result = table.paste({ row: range.value.top, column: range.value.left }, text);\n lastResult.value = result;\n return result;\n },\n clear() {\n if (!range.value) {\n return undefined;\n }\n const result = table.clear(range.value);\n lastResult.value = result;\n return result;\n },\n handleKey(event) {\n if (editor.value) {\n return false;\n }\n const command = gridCommand(event);\n switch (command?.type) {\n case \"move\":\n grid.move(command.direction, command.options);\n return true;\n case \"edit\":\n return grid.startEdit(command.initial);\n case \"clear\":\n grid.clear();\n return true;\n case \"selectAll\":\n grid.selectAll();\n return true;\n case \"undo\":\n return table.undo();\n case \"redo\":\n return table.redo();\n case \"cancel\":\n if (selection.value) {\n selection.value = selectCell(selection.value.focus);\n }\n return true;\n default:\n return false;\n }\n },\n };\n return grid;\n}\n","import {\n createVirtualizer,\n getRowItemKey,\n type RowKey,\n type TableColumn,\n type TableRenderItem,\n type VirtualAlign,\n type VirtualItem,\n type VirtualWindow,\n type TableIssue,\n} from \"@vueye-table/core\";\nimport {\n computed,\n getCurrentInstance,\n getCurrentScope,\n nextTick,\n onMounted,\n onScopeDispose,\n shallowRef,\n toValue,\n watch,\n type ComponentPublicInstance,\n type MaybeRefOrGetter,\n} from \"vue\";\n\nimport type { DataGridBinding } from \"./use-data-grid\";\nimport type { DataTableBinding } from \"./use-data-table\";\n\nexport interface VirtualViewportOptions {\n readonly scrollElement: MaybeRefOrGetter<HTMLElement | null | undefined>;\n readonly overscan?: number | undefined;\n /** Number of items rendered before mount, without overscan. Defaults to 10. */\n readonly initialCount?: number | undefined;\n /** Space before the items, such as a sticky header or leading row-number column. */\n readonly scrollMargin?: MaybeRefOrGetter<number> | undefined;\n}\nexport interface UseVirtualRowsOptions<TRow> extends VirtualViewportOptions {\n readonly estimateRowHeight?: number | ((index: number) => number) | undefined;\n /** Connect logical grid focus to the rendered data row, skipping details. */\n readonly grid?: DataGridBinding<TRow> | undefined;\n}\nexport interface UseVirtualColumnsOptions extends VirtualViewportOptions {\n readonly estimateColumnWidth?: number | ((index: number) => number) | undefined;\n}\nexport interface VirtualRowItem<TRow> extends VirtualItem {\n readonly renderItem: TableRenderItem<TRow>;\n}\nexport interface VirtualColumnItem<TRow> extends VirtualItem {\n readonly column: TableColumn<TRow>;\n}\nexport interface VirtualBinding<TItem extends VirtualItem> extends Omit<VirtualWindow, \"items\"> {\n readonly items: readonly TItem[];\n getItem(index: number): TItem | undefined;\n scrollToIndex(index: number, options?: { readonly align?: VirtualAlign | undefined }): void;\n scrollToKey(key: RowKey, options?: { readonly align?: VirtualAlign | undefined }): void;\n /** Pass the virtual item key explicitly; null releases its previously observed element. */\n measureElement(element: Element | ComponentPublicInstance | null, key: RowKey): void;\n}\n\nfunction useVirtualAxis<TSource, TItem extends VirtualItem>(\n source: () => readonly TSource[],\n keyOf: (item: TSource) => RowKey,\n estimate: number | ((index: number) => number),\n options: VirtualViewportOptions,\n horizontal: boolean,\n project: (item: VirtualItem, source: TSource) => TItem,\n): VirtualBinding<TItem> {\n let items = source();\n let mounted = false;\n let disposed = false;\n let element: HTMLElement | null | undefined;\n let observer: ResizeObserver | undefined;\n let detach: (() => void) | undefined;\n const elements = new Map<RowKey, Element>();\n const keysByElement = new Map<Element, RowKey>();\n const requestedCount = options.initialCount ?? 10;\n const initialCount =\n Number.isSafeInteger(requestedCount) && requestedCount >= 0 ? requestedCount : 10;\n const initialIssue: TableIssue | undefined =\n initialCount === requestedCount\n ? undefined\n : Object.freeze({\n code: \"invalid_virtual_option\",\n message: \"Initial count must be a non-negative safe integer; 10 is used.\",\n });\n const layoutOptions = () => ({\n count: items.length,\n estimateSize: estimate,\n overscan: mounted ? options.overscan : 0,\n getKey: (index: number): RowKey => keyOf(items[index]!),\n });\n const virtual = createVirtualizer(layoutOptions());\n function seed(): void {\n let size = 0;\n for (let index = 0; index < Math.min(initialCount, items.length); index += 1) {\n const value = typeof estimate === \"number\" ? estimate : estimate(index);\n size += Number.isFinite(value) && value > 0 ? value : 40;\n }\n virtual.setViewport(0, size);\n }\n seed();\n const view = shallowRef(virtual.getWindow());\n const projected = computed(() =>\n Object.freeze(view.value.items.map((item) => Object.freeze(project(item, items[item.index]!)))),\n );\n const unsubscribe = virtual.subscribe((next) => {\n view.value = next;\n });\n const marginIssue = shallowRef<TableIssue>();\n\n function margin(): number {\n const value = toValue(options.scrollMargin) ?? 0;\n if (Number.isFinite(value) && value >= 0) {\n marginIssue.value = undefined;\n return value;\n }\n marginIssue.value ??= Object.freeze({\n code: \"invalid_virtual_option\",\n message: \"Scroll margin must be non-negative and finite; 0 is used.\",\n });\n return 0;\n }\n function viewportSize(): number {\n return element\n ? Math.max(0, (horizontal ? element.clientWidth : element.clientHeight) - margin())\n : virtual.getWindow().viewportSize;\n }\n function move(offset: number): void {\n if (element) {\n if (horizontal) element.scrollLeft = offset === 0 ? 0 : offset + margin();\n else element.scrollTop = offset === 0 ? 0 : offset + margin();\n }\n virtual.setViewport(offset, viewportSize());\n }\n function anchor(): { key: RowKey; inset: number } | undefined {\n const current = virtual.getWindow();\n const first = current.items.find((item) => item.start + item.size > current.offset);\n return first ? { key: first.key, inset: current.offset - first.start } : undefined;\n }\n function restore(saved: ReturnType<typeof anchor>, fallback: number): void {\n const index = saved ? items.findIndex((item) => keyOf(item) === saved.key) : -1;\n move(index >= 0 && saved ? virtual.getOffsetForIndex(index, \"start\") + saved.inset : fallback);\n // Reflect the clamp in the scroll element after shrink or removal.\n if (element) {\n const offset = virtual.getWindow().offset;\n if (horizontal) element.scrollLeft = offset === 0 ? 0 : offset + margin();\n else element.scrollTop = offset === 0 ? 0 : offset + margin();\n }\n }\n function measure(target: Element, key: RowKey): void {\n const saved = anchor();\n const offset = virtual.getWindow().offset;\n const box = target.getBoundingClientRect();\n const size = horizontal ? box.width : box.height;\n // Hidden and detached elements have no useful measurement; retain the estimate.\n if (size > 0 && Number.isFinite(size)) {\n const previous = virtual.getWindow();\n virtual.measure(key, size);\n if (virtual.getWindow() === previous) return;\n restore(saved, offset);\n }\n }\n function readViewport(): void {\n if (element)\n virtual.setViewport(\n Math.max(0, (horizontal ? element.scrollLeft : element.scrollTop) - margin()),\n viewportSize(),\n );\n }\n const stopSource = watch(\n source,\n (next) => {\n const saved = anchor();\n const offset = virtual.getWindow().offset;\n items = next;\n virtual.setOptions(layoutOptions());\n if (mounted) restore(saved, offset);\n else seed();\n },\n { flush: \"sync\" },\n );\n let stopElement: (() => void) | undefined;\n if (getCurrentInstance())\n onMounted(() => {\n mounted = true;\n virtual.setOptions(layoutOptions());\n stopElement = watch(\n () => toValue(options.scrollElement),\n (next) => {\n detach?.();\n observer?.disconnect();\n observer = undefined;\n element = next;\n if (!next) {\n seed();\n return;\n }\n const owner = next.ownerDocument.defaultView;\n const Observer = owner?.ResizeObserver;\n if (Observer) {\n observer = new Observer((entries) => {\n for (const entry of entries) {\n if (entry.target === element) readViewport();\n else {\n const key = keysByElement.get(entry.target);\n if (key !== undefined) measure(entry.target, key);\n }\n }\n });\n observer.observe(next);\n for (const target of elements.values()) observer.observe(target);\n } else owner?.addEventListener(\"resize\", readViewport);\n next.addEventListener(\"scroll\", readViewport, { passive: true });\n detach = () => {\n next.removeEventListener(\"scroll\", readViewport);\n owner?.removeEventListener(\"resize\", readViewport);\n };\n readViewport();\n for (const [key, target] of elements) measure(target, key);\n },\n { immediate: true, flush: \"post\" },\n );\n });\n if (getCurrentScope())\n onScopeDispose(() => {\n disposed = true;\n stopSource();\n stopElement?.();\n detach?.();\n observer?.disconnect();\n unsubscribe();\n elements.clear();\n keysByElement.clear();\n element = undefined;\n });\n margin();\n const binding = {\n getItem(index: number): TItem | undefined {\n // Reading the revision connects offscreen lookups to reactive measurements and layout.\n void view.value;\n const item = virtual.getItem(index);\n return item ? Object.freeze(project(item, items[index]!)) : undefined;\n },\n scrollToIndex(\n index: number,\n { align = \"auto\" }: { readonly align?: VirtualAlign | undefined } = {},\n ): void {\n move(virtual.getOffsetForIndex(index, align));\n },\n scrollToKey(key: RowKey, align?: { readonly align?: VirtualAlign | undefined }): void {\n const index = items.findIndex((item) => keyOf(item) === key);\n if (index >= 0) binding.scrollToIndex(index, align);\n },\n measureElement(target: Element | ComponentPublicInstance | null, key: RowKey): void {\n if (disposed) return;\n const previous = elements.get(key);\n if (previous === target) return;\n if (previous) {\n observer?.unobserve(previous);\n keysByElement.delete(previous);\n elements.delete(key);\n }\n if (!target || !(\"getBoundingClientRect\" in target)) return;\n elements.set(key, target);\n keysByElement.set(target, key);\n if (mounted) {\n observer?.observe(target);\n // A ref can run midway through a keyed row/spacer patch. Reading layout there can\n // clamp a pending scroll against a temporarily shortened content area.\n void nextTick(() => {\n if (!disposed && elements.get(key) === target) measure(target, key);\n });\n }\n },\n } as Record<string, unknown> &\n Pick<VirtualBinding<TItem>, \"getItem\" | \"scrollToIndex\" | \"scrollToKey\" | \"measureElement\">;\n for (const key of Object.keys(view.value))\n Object.defineProperty(binding, key, {\n enumerable: true,\n get: () =>\n key === \"items\"\n ? projected.value\n : key === \"issues\" && (initialIssue || marginIssue.value)\n ? Object.freeze([\n ...view.value.issues,\n ...(initialIssue ? [initialIssue] : []),\n ...(marginIssue.value ? [marginIssue.value] : []),\n ])\n : view.value[key as keyof VirtualWindow],\n });\n return Object.freeze(binding) as unknown as VirtualBinding<TItem>;\n}\n\n/** Virtualize data and detail render items. scrollToKey accepts the parent data-row key. */\nexport function useVirtualRows<TRow>(\n table: DataTableBinding<TRow>,\n options: UseVirtualRowsOptions<TRow>,\n): VirtualBinding<VirtualRowItem<TRow>> {\n const virtual = useVirtualAxis(\n () => table.renderItems,\n (item) => item.key,\n options.estimateRowHeight ?? 40,\n options,\n false,\n (item, renderItem) => ({ ...item, renderItem }),\n );\n const stopFocus = watch(\n () => options.grid?.selection?.focus.row,\n (row) => {\n if (row === undefined) return;\n const direct = table.renderItems[row];\n const index =\n direct?.kind === \"row\" && direct.rowIndex === row\n ? row\n : table.renderItems.findIndex((item) => item.kind === \"row\" && item.rowIndex === row);\n if (index >= 0) virtual.scrollToIndex(index);\n },\n { flush: \"sync\" },\n );\n if (getCurrentScope()) onScopeDispose(stopFocus);\n const binding = Object.defineProperties(\n {},\n {\n ...Object.getOwnPropertyDescriptors(virtual),\n scrollToKey: {\n enumerable: true,\n value: (key: RowKey, align?: { readonly align?: VirtualAlign | undefined }): void =>\n virtual.scrollToKey(getRowItemKey(key), align),\n },\n },\n );\n return Object.freeze(binding) as VirtualBinding<VirtualRowItem<TRow>>;\n}\n\n/** Virtualize visible columns and bring the active logical column into view. */\nexport function useVirtualColumns<TRow>(\n grid: DataGridBinding<TRow>,\n options: UseVirtualColumnsOptions,\n): VirtualBinding<VirtualColumnItem<TRow>> {\n const virtual = useVirtualAxis(\n () => grid.table.columns,\n (column) => column.id,\n options.estimateColumnWidth ?? 120,\n options,\n true,\n (item, column) => ({ ...item, column }),\n );\n const stopFocus = watch(\n () => grid.selection?.focus.column,\n (column) => {\n if (column !== undefined) virtual.scrollToIndex(column);\n },\n { flush: \"sync\" },\n );\n if (getCurrentScope()) onScopeDispose(stopFocus);\n return virtual;\n}\n","import {\n createTable,\n type ColumnDef,\n type DataTable,\n type TableOptions,\n type TableSnapshot,\n type TableStatePatch,\n type TreeLoadSignal,\n} from \"@vueye-table/core\";\nimport {\n getCurrentScope,\n onScopeDispose,\n shallowRef,\n toRaw,\n toValue,\n watch,\n type MaybeRefOrGetter,\n} from \"vue\";\n\n/** Options accepted by {@link useDataTable}. Data, columns, and state may be refs or getters. */\nexport interface UseDataTableOptions<\n TRow,\n TSignal extends TreeLoadSignal = TreeLoadSignal,\n> extends Omit<TableOptions<TRow, TSignal>, \"data\" | \"columns\" | \"rowCount\"> {\n readonly data: MaybeRefOrGetter<readonly TRow[]>;\n readonly columns: MaybeRefOrGetter<readonly ColumnDef<TRow>[]>;\n readonly rowCount?: MaybeRefOrGetter<number | undefined> | undefined;\n /**\n * State owned by the caller, for example `v-model` props or URL query values. Whenever it\n * changes it is applied with `setState`; the table's own changes still reach `onStateChange`.\n */\n readonly state?: MaybeRefOrGetter<TableStatePatch | undefined> | undefined;\n}\n\ntype TableOperations<TRow> = Omit<DataTable<TRow>, \"getSnapshot\" | \"getState\" | \"subscribe\">;\n\n/**\n * A reactive view of a table: every snapshot field is a plain reactive property, so templates read\n * `table.rows` and `table.pageCount` directly, and every change goes through a named operation.\n * Watching a field needs a getter: `watch(() => table.page, ...)`.\n */\nexport type DataTableBinding<TRow> = TableSnapshot<TRow> &\n TableOperations<TRow> & {\n /** The engine behind the binding. */\n readonly table: DataTable<TRow>;\n /** The current snapshot, replaced on every change. */\n readonly snapshot: TableSnapshot<TRow>;\n };\n\n/**\n * A binding for any row type, for components that accept every table. Row types make the binding\n * invariant, so `DataTableBinding<unknown>` would refuse `DataTableBinding<Person>`.\n */\nexport type AnyDataTableBinding = DataTableBinding<any>;\n\nconst OPERATIONS = [\n \"appendData\",\n \"upsertData\",\n \"removeData\",\n \"stream\",\n \"insertRows\",\n \"removeRows\",\n \"getPendingChanges\",\n \"markSaved\",\n \"revert\",\n \"setState\",\n \"setData\",\n \"setColumns\",\n \"setRowCount\",\n \"toggleSort\",\n \"sort\",\n \"clearSorting\",\n \"search\",\n \"filter\",\n \"clearFilters\",\n \"goToPage\",\n \"nextPage\",\n \"previousPage\",\n \"setPageSize\",\n \"select\",\n \"deselect\",\n \"toggleRow\",\n \"toggleAll\",\n \"clearSelection\",\n \"getSelectedRows\",\n \"toggleExpanded\",\n \"expandAll\",\n \"collapseAll\",\n \"toggleColumn\",\n \"moveColumn\",\n \"edit\",\n \"undo\",\n \"redo\",\n \"copy\",\n \"paste\",\n \"clear\",\n \"exportRows\",\n \"reset\",\n \"destroy\",\n] as const satisfies readonly (keyof TableOperations<unknown>)[];\n\nfunction definedEntries(patch: TableStatePatch | undefined): TableStatePatch {\n return Object.fromEntries(Object.entries(patch ?? {}).filter(([, value]) => value !== undefined));\n}\n\n/**\n * Create a table bound to the current effect scope. The table follows its reactive data,\n * columns, row count, and state, and stops listening when the scope ends.\n */\nexport function useDataTable<TRow, TSignal extends TreeLoadSignal = TreeLoadSignal>(\n options: UseDataTableOptions<TRow, TSignal>,\n): DataTableBinding<TRow> {\n const table = createTable<TRow, TSignal>({\n ...options,\n data: toRaw(toValue(options.data)),\n columns: toValue(options.columns),\n rowCount: toValue(options.rowCount),\n initialState: { ...options.initialState, ...definedEntries(toValue(options.state)) },\n });\n const snapshot = shallowRef(table.getSnapshot());\n const unsubscribe = table.subscribe((next) => {\n snapshot.value = next;\n });\n\n const stops = [\n watch(\n () => toValue(options.data),\n // Reactive arrays arrive as proxies; the engine works on, and compares, the raw array.\n (data) => table.setData(toRaw(data)),\n ),\n watch(\n () => toValue(options.columns),\n (columns) => table.setColumns(columns),\n ),\n watch(\n () => toValue(options.rowCount),\n (rowCount) => {\n if (rowCount !== undefined) {\n table.setRowCount(rowCount);\n }\n },\n ),\n watch(\n () => toValue(options.state),\n (state) => {\n if (state) {\n table.setState(state);\n }\n },\n { deep: true },\n ),\n ];\n\n if (getCurrentScope()) {\n onScopeDispose(() => {\n for (const stop of stops) {\n stop();\n }\n unsubscribe();\n table.destroy();\n });\n }\n\n const binding = { table } as Record<string, unknown>;\n Object.defineProperty(binding, \"snapshot\", { enumerable: true, get: () => snapshot.value });\n for (const key of Object.keys(snapshot.value)) {\n Object.defineProperty(binding, key, {\n enumerable: true,\n get: () => snapshot.value[key as keyof TableSnapshot<TRow>],\n });\n }\n for (const name of OPERATIONS) {\n binding[name] = table[name];\n }\n return Object.freeze(binding) as unknown as DataTableBinding<TRow>;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/injection.ts","../src/row-draft.ts","../src/use-data-grid.ts","../src/use-virtual.ts","../src/use-data-table.ts"],"sourcesContent":["import { inject, provide, type InjectionKey } from \"vue\";\n\nimport type { DataGridBinding } from \"./use-data-grid\";\nimport type { DataTableBinding } from \"./use-data-table\";\n\nconst tableKey: InjectionKey<DataTableBinding<unknown>> = Symbol(\"vueye-table\");\nconst gridKey: InjectionKey<DataGridBinding<unknown>> = Symbol(\"vueye-table-grid\");\n\n/** Make a table available to every component below the current one. */\nexport function provideDataTable<TRow>(table: DataTableBinding<TRow>): void {\n provide(tableKey, table as DataTableBinding<unknown>);\n}\n\n/**\n * Read the table provided by an ancestor. Throws when there is none, naming the component that\n * provides one, rather than rendering an empty table.\n */\nexport function injectDataTable<TRow = unknown>(\n consumer = \"This component\",\n): DataTableBinding<TRow> {\n const table = inject(tableKey, undefined);\n if (!table) {\n throw new Error(\n `${consumer} needs a table. Render it inside <DataTableRoot :table=\"table\">, or call provideDataTable(useDataTable(...)) in an ancestor.`,\n );\n }\n return table as DataTableBinding<TRow>;\n}\n\nexport function provideDataGrid<TRow>(grid: DataGridBinding<TRow>): void {\n provide(gridKey, grid as DataGridBinding<unknown>);\n}\n\n/** Read the grid provided by an ancestor, or `undefined` outside a grid. */\nexport function injectDataGrid<TRow = unknown>(): DataGridBinding<TRow> | undefined {\n return inject(gridKey, undefined) as DataGridBinding<TRow> | undefined;\n}\n","import type {\n CellEdit,\n DataTable,\n DeepKeys,\n EditResult,\n PathValue,\n RowKey,\n TableIssue,\n} from \"@vueye-table/core\";\nimport { shallowReactive, shallowRef, toRaw } from \"vue\";\n\n/** A column-value bag. Only configured columns are present; dotted paths stay dotted keys. */\nexport type RowDraftValues<TRow> = {\n -readonly [P in DeepKeys<TRow>]?: PathValue<TRow, P>;\n};\n\nexport interface RowDraft<TRow> {\n readonly rowKey: RowKey;\n readonly values: RowDraftValues<TRow>;\n readonly issues: readonly TableIssue[];\n readonly status: \"editing\" | \"saving\" | \"saved\" | \"cancelled\" | \"stale\";\n readonly pending: boolean;\n /** Supply raw text for the column parser, including numeric/date input. */\n setInput(column: string, input: string): void;\n /** Set a computed column whose id is not a path in the row type. */\n setValue(column: string, value: unknown): void;\n save(): Promise<EditResult<TRow>>;\n /** Discard an unsubmitted draft. A submitted validation batch is owned by the engine. */\n cancel(): boolean;\n}\n\nexport function rejectedDraft<TRow>(rowKey: RowKey, message: string): EditResult<TRow> {\n return refused([Object.freeze({ code: \"stale_draft\", rowKey, message })]);\n}\n\nfunction refused<TRow>(issues: readonly TableIssue[]): EditResult<TRow> {\n return Object.freeze({\n status: \"rejected\",\n changes: Object.freeze([]),\n rowChanges: Object.freeze([]),\n pendingCells: Object.freeze([]),\n issues: Object.freeze([...issues]),\n });\n}\n\n// Compare owned structured values without making nested values reactive. Cycles are allowed.\nfunction equal(left: unknown, right: unknown, seen = new WeakMap<object, object>()): boolean {\n if (Object.is(left, right)) return true;\n if (!left || !right || typeof left !== \"object\" || typeof right !== \"object\") return false;\n if (left instanceof Date || right instanceof Date)\n return (\n left instanceof Date && right instanceof Date && Object.is(left.getTime(), right.getTime())\n );\n if (Array.isArray(left) && Array.isArray(right) && left.length !== right.length) return false;\n if (Object.getPrototypeOf(left) !== Object.getPrototypeOf(right)) return false;\n if (seen.has(left)) return seen.get(left) === right;\n seen.set(left, right);\n if (left instanceof Map && right instanceof Map) return equal([...left], [...right], seen);\n if (left instanceof Set && right instanceof Set) return equal([...left], [...right], seen);\n if (left instanceof RegExp && right instanceof RegExp)\n return left.source === right.source && left.flags === right.flags;\n if (left instanceof ArrayBuffer && right instanceof ArrayBuffer)\n return equal([...new Uint8Array(left)], [...new Uint8Array(right)], seen);\n if (ArrayBuffer.isView(left) && ArrayBuffer.isView(right))\n return equal(\n [...new Uint8Array(left.buffer, left.byteOffset, left.byteLength)],\n [...new Uint8Array(right.buffer, right.byteOffset, right.byteLength)],\n seen,\n );\n const keys = Object.keys(left);\n return (\n keys.length === Object.keys(right).length &&\n keys.every(\n (key) =>\n Object.hasOwn(right, key) && equal(Reflect.get(left, key), Reflect.get(right, key), seen),\n )\n );\n}\n\n/** Internal factory; disposal is shared with the binding's single engine subscription. */\nexport function createRowDraft<TRow>(\n table: DataTable<TRow>,\n key: RowKey,\n register: (dispose: () => void) => () => void,\n): RowDraft<TRow> {\n const snapshot = table.getSnapshot();\n const original = snapshot.getRow(key)?.original;\n const columns = snapshot.allColumns;\n const values = shallowReactive<Record<string, unknown>>(Object.create(null));\n const initial = new Map<string, unknown>();\n const inputs = new Map<string, string>();\n const copyIssues = new Map<string, TableIssue>();\n const issues = shallowRef<readonly TableIssue[]>([]);\n const status = shallowRef<RowDraft<TRow>[\"status\"]>(\"editing\");\n for (const column of columns) {\n if (original === undefined) break;\n try {\n if (!column.isEditable(original)) continue;\n const value = column.getValue(original);\n initial.set(column.id, value);\n values[column.id] = structuredClone(toRaw(value));\n } catch {\n copyIssues.set(\n column.id,\n Object.freeze({\n code: \"invalid_value\",\n rowKey: key,\n column: column.id,\n message:\n \"This value cannot be copied into a row draft. Replace it explicitly before saving.\",\n }),\n );\n issues.value = [...copyIssues.values()];\n }\n }\n let saving: Promise<EditResult<TRow>> | undefined;\n let disposePending: ((result: EditResult<TRow>) => void) | undefined;\n let disposed = false;\n const stale = (): EditResult<TRow> =>\n rejectedDraft(key, \"This draft is closed, or its row or columns changed. Open a new draft.\");\n const unregister = register(() => {\n disposed = true;\n const result = stale();\n status.value = \"stale\";\n issues.value = result.issues;\n disposePending?.(result);\n });\n const draft: RowDraft<TRow> = {\n rowKey: key,\n values,\n get issues() {\n return issues.value;\n },\n get status() {\n return status.value;\n },\n get pending() {\n return status.value === \"saving\";\n },\n setInput(column, input) {\n if (status.value === \"editing\") inputs.set(column, input);\n },\n setValue(column, value) {\n if (status.value === \"editing\") {\n values[column] = value;\n inputs.delete(column);\n }\n },\n save() {\n if (saving) return saving;\n if (\n status.value !== \"editing\" ||\n disposed ||\n original === undefined ||\n table.getSnapshot().getRow(key)?.original !== original ||\n columns.some(\n (column) => table.getSnapshot().getColumn(column.id)?.definition !== column.definition,\n )\n ) {\n const result = stale();\n issues.value = result.issues;\n status.value = \"stale\";\n unregister();\n return Promise.resolve(result);\n }\n const edits: CellEdit[] = [];\n const uncopied = [...copyIssues.values()].filter(\n (problem) => !Object.hasOwn(values, problem.column!) && !inputs.has(problem.column!),\n );\n if (uncopied.length) {\n issues.value = Object.freeze(uncopied);\n return Promise.resolve(refused(issues.value));\n }\n for (const column of new Set([...Object.keys(values), ...inputs.keys()])) {\n try {\n const value = toRaw(values[column]);\n if (inputs.has(column)) edits.push({ rowKey: key, column, input: inputs.get(column)! });\n else if (!initial.has(column) || !equal(value, initial.get(column))) {\n edits.push(\n typeof value === \"string\"\n ? { rowKey: key, column, input: value }\n : {\n rowKey: key,\n column,\n value:\n value !== null && typeof value === \"object\" ? structuredClone(value) : value,\n },\n );\n }\n } catch {\n issues.value = Object.freeze([\n Object.freeze({\n code: \"invalid_value\",\n rowKey: key,\n column,\n message:\n \"This draft value cannot be copied for submission. Replace it before saving.\",\n }),\n ]);\n return Promise.resolve(refused(issues.value));\n }\n }\n status.value = \"saving\";\n const result = table.edit(edits, { expectedRows: new Map([[key, original]]) });\n if (disposed) return Promise.resolve(stale());\n const cancelled = new Promise<EditResult<TRow>>((resolve) => {\n disposePending = resolve;\n });\n saving = Promise.race([result.completion ?? Promise.resolve(result), cancelled]).then(\n (final) => {\n issues.value = final.issues;\n // Partial results close the draft too: accepted fields have already changed the row.\n status.value =\n disposed || final.issues.some((problem) => problem.code === \"stale_draft\")\n ? \"stale\"\n : final.status === \"rejected\"\n ? \"editing\"\n : \"saved\";\n if (status.value !== \"editing\") unregister();\n saving = undefined;\n disposePending = undefined;\n return final;\n },\n );\n return saving;\n },\n cancel() {\n if (status.value !== \"editing\") return false;\n status.value = \"cancelled\";\n unregister();\n return true;\n },\n };\n return Object.freeze(draft);\n}\n","import {\n clampPosition,\n gridCommand,\n moveSelection,\n rangeContains,\n selectCell,\n selectionRange,\n typeOf,\n type CellPosition,\n type CellRange,\n type CopyOptions,\n type EditResult,\n type GridBounds,\n type GridDirection,\n type GridKey,\n type GridSelection,\n type MoveOptions,\n type TableColumn,\n type TableRow,\n type EditorSpec,\n type RowKey,\n} from \"@vueye-table/core\";\nimport { computed, shallowRef, watch, type ComputedRef } from \"vue\";\n\nimport { rejectedDraft } from \"./row-draft\";\nimport type { DataTableBinding } from \"./use-data-table\";\n\n/** The cell being edited and the text typed so far. */\nexport interface GridEditor {\n readonly position: CellPosition;\n readonly draft: string;\n}\n\n/**\n * Spreadsheet interaction over a table: a selected range, keyboard navigation, in-cell editing,\n * copy, paste, and clearing. Positions refer to the current page and the visible columns.\n */\nexport interface DataGridBinding<TRow> {\n readonly table: DataTableBinding<TRow>;\n readonly selection: GridSelection | undefined;\n readonly range: CellRange | undefined;\n readonly editor: GridEditor | undefined;\n readonly bounds: ComputedRef<GridBounds>;\n /** The latest edit outcome, to show a rejected value. */\n readonly lastResult: EditResult<TRow> | undefined;\n /** Serializable editor metadata for an editable cell; no component resolution. */\n editorFor(position: CellPosition): EditorSpec | undefined;\n cellAt(position: CellPosition): { row: TableRow<TRow>; column: TableColumn<TRow> } | undefined;\n isFocused(position: CellPosition): boolean;\n isSelected(position: CellPosition): boolean;\n isEditing(position: CellPosition): boolean;\n focusCell(position: CellPosition, options?: { readonly extend?: boolean | undefined }): void;\n move(direction: GridDirection, options?: MoveOptions): void;\n selectAll(): void;\n /** Start editing the focused cell, with its current text or with `initial`. */\n startEdit(initial?: string): boolean;\n updateDraft(draft: string): void;\n /** Write the draft through the table, then move the focus if asked. */\n commitEdit(then?: GridDirection): EditResult<TRow> | undefined;\n cancelEdit(): void;\n /** The selected range as tab-separated text. */\n copy(options?: CopyOptions): string;\n /** Paste tab-separated text at the top-left of the selection. */\n paste(text: string): EditResult<TRow> | undefined;\n clear(): EditResult<TRow> | undefined;\n /** Handle a key press. Returns `true` when the grid used it, so the caller can prevent the default. */\n handleKey(event: GridKey): boolean;\n}\n\nexport function useDataGrid<TRow>(table: DataTableBinding<TRow>): DataGridBinding<TRow> {\n const selection = shallowRef<GridSelection | undefined>();\n const editor = shallowRef<GridEditor | undefined>();\n const lastResult = shallowRef<EditResult<TRow> | undefined>();\n let editing:\n | { readonly key: RowKey; readonly column: TableColumn<TRow>; readonly original: TRow }\n | undefined;\n let resultToken: object | undefined;\n const invalidEditors = new WeakSet<object>();\n const record = (result: EditResult<TRow>): EditResult<TRow> => {\n const token = {};\n resultToken = token;\n lastResult.value = result;\n void result.completion?.then((final) => {\n if (resultToken === token) lastResult.value = final;\n return undefined;\n });\n return result;\n };\n const bounds = computed<GridBounds>(() => ({\n rows: table.rows.length,\n columns: table.columns.length,\n }));\n const range = computed(() => (selection.value ? selectionRange(selection.value) : undefined));\n\n const same = (left: CellPosition | undefined, right: CellPosition): boolean =>\n left !== undefined && left.row === right.row && left.column === right.column;\n\n // Searching, filtering, paging, or hiding a column can shrink the grid under the selection.\n // Keep the selection on cells that exist, and drop an edit whose cell is gone.\n watch(\n () => table.snapshot,\n () => {\n const next = bounds.value;\n const current = selection.value;\n if (current && (next.rows === 0 || next.columns === 0)) {\n selection.value = undefined;\n } else if (current) {\n const anchor = clampPosition(current.anchor, next);\n const focus = clampPosition(current.focus, next);\n if (!same(current.anchor, anchor) || !same(current.focus, focus)) {\n selection.value = { anchor, focus };\n }\n }\n const active = editing;\n if (active && editor.value) {\n const row = table.rows.findIndex((candidate) => candidate.key === active.key);\n const column = table.columns.findIndex((candidate) => candidate.id === active.column.id);\n if (\n row < 0 ||\n column < 0 ||\n table.getRow(active.key)?.original !== active.original ||\n table.getColumn(active.column.id)?.definition !== active.column.definition\n ) {\n editor.value = undefined;\n editing = undefined;\n record(\n rejectedDraft(\n active.key,\n \"The edited cell changed or left the visible grid. Start a new edit.\",\n ),\n );\n } else if (!same(editor.value.position, { row, column })) {\n editor.value = { ...editor.value, position: { row, column } };\n selection.value = selectCell({ row, column });\n }\n }\n },\n { flush: \"sync\" },\n );\n\n const cellAt: DataGridBinding<TRow>[\"cellAt\"] = (position) => {\n const row = table.rows[position.row];\n const column = table.columns[position.column];\n return row && column ? { row, column } : undefined;\n };\n\n const ensureSelection = (): GridSelection | undefined => {\n if (bounds.value.rows === 0 || bounds.value.columns === 0) {\n return undefined;\n }\n selection.value ??= selectCell({ row: 0, column: 0 });\n return selection.value;\n };\n\n const grid: DataGridBinding<TRow> = {\n table,\n get selection() {\n return selection.value;\n },\n get range() {\n return range.value;\n },\n get editor() {\n return editor.value;\n },\n get lastResult() {\n return lastResult.value;\n },\n bounds,\n cellAt,\n editorFor(position) {\n const cell = cellAt(position);\n if (!cell || !cell.column.isEditable(cell.row.original)) return undefined;\n const spec = cell.column.definition.editor;\n if (\n spec &&\n [\"text\", \"number\", \"select\", \"checkbox\", \"date\"].includes(spec.kind) &&\n (spec.options === undefined ||\n (Array.isArray(spec.options) &&\n spec.options.every(\n (value) => value === null || [\"string\", \"number\", \"boolean\"].includes(typeof value),\n )))\n ) {\n return Object.freeze({\n kind: spec.kind,\n ...(spec.options ? { options: Object.freeze([...spec.options]) } : {}),\n ...(spec.min !== undefined ? { min: spec.min } : {}),\n ...(spec.max !== undefined ? { max: spec.max } : {}),\n ...(spec.maxLength !== undefined ? { maxLength: spec.maxLength } : {}),\n ...(spec.pattern !== undefined ? { pattern: spec.pattern } : {}),\n });\n }\n if (spec) {\n if (!invalidEditors.has(cell.column.definition)) {\n invalidEditors.add(cell.column.definition);\n record(\n Object.freeze({\n status: \"rejected\",\n changes: Object.freeze([]),\n rowChanges: Object.freeze([]),\n pendingCells: Object.freeze([]),\n issues: Object.freeze([\n Object.freeze({\n code: \"invalid_value\",\n rowKey: cell.row.key,\n column: cell.column.id,\n message: \"Invalid editor metadata; text metadata is used.\",\n }),\n ]),\n }),\n );\n }\n return Object.freeze({ kind: \"text\" });\n }\n const type =\n cell.column.definition.type ?? typeOf(cell.row.getValue(cell.column.id)) ?? \"text\";\n return Object.freeze({ kind: type === \"boolean\" ? \"checkbox\" : type });\n },\n isFocused: (position) => same(selection.value?.focus, position),\n isSelected: (position) => (range.value ? rangeContains(range.value, position) : false),\n isEditing: (position) => same(editor.value?.position, position),\n focusCell(position, { extend = false } = {}) {\n const target = clampPosition(position, bounds.value);\n if (editor.value && !same(editor.value.position, target)) {\n grid.commitEdit();\n }\n selection.value =\n extend && selection.value\n ? { anchor: selection.value.anchor, focus: target }\n : selectCell(target);\n },\n move(direction, options) {\n const current = ensureSelection();\n if (current) {\n selection.value = moveSelection(current, direction, bounds.value, options);\n }\n },\n selectAll() {\n if (bounds.value.rows > 0 && bounds.value.columns > 0) {\n selection.value = {\n anchor: { row: 0, column: 0 },\n focus: { row: bounds.value.rows - 1, column: bounds.value.columns - 1 },\n };\n }\n },\n startEdit(initial) {\n const focus = ensureSelection()?.focus;\n const cell = focus ? cellAt(focus) : undefined;\n if (!focus || !cell || !cell.column.isEditable(cell.row.original)) {\n return false;\n }\n editor.value = { position: focus, draft: initial ?? cell.row.getDisplay(cell.column.id) };\n editing = { key: cell.row.key, column: cell.column, original: cell.row.original };\n return true;\n },\n updateDraft(draft) {\n if (editor.value) {\n editor.value = { position: editor.value.position, draft };\n }\n },\n commitEdit(then) {\n const current = editor.value;\n if (!current) {\n return undefined;\n }\n const active = editing;\n editor.value = undefined;\n editing = undefined;\n if (!active) {\n return undefined;\n }\n const result = record(\n table.edit(\n {\n rowKey: active.key,\n column: active.column.id,\n input: current.draft,\n },\n { expectedRows: new Map([[active.key, active.original]]) },\n ),\n );\n if (then) {\n grid.move(then);\n }\n return result;\n },\n cancelEdit() {\n editor.value = undefined;\n editing = undefined;\n },\n copy(options) {\n return range.value ? table.copy(range.value, options) : \"\";\n },\n paste(text) {\n if (!range.value) {\n return undefined;\n }\n const result = record(table.paste({ row: range.value.top, column: range.value.left }, text));\n return result;\n },\n clear() {\n if (!range.value) {\n return undefined;\n }\n const result = record(table.clear(range.value));\n return result;\n },\n handleKey(event) {\n if (editor.value) {\n return false;\n }\n const command = gridCommand(event);\n switch (command?.type) {\n case \"move\":\n grid.move(command.direction, command.options);\n return true;\n case \"edit\":\n return grid.startEdit(command.initial);\n case \"clear\":\n grid.clear();\n return true;\n case \"selectAll\":\n grid.selectAll();\n return true;\n case \"undo\":\n return table.undo();\n case \"redo\":\n return table.redo();\n case \"cancel\":\n if (selection.value) {\n selection.value = selectCell(selection.value.focus);\n }\n return true;\n default:\n return false;\n }\n },\n };\n return grid;\n}\n","import {\n createVirtualizer,\n getRowItemKey,\n type RowKey,\n type TableColumn,\n type TableRenderItem,\n type VirtualAlign,\n type VirtualItem,\n type VirtualWindow,\n type TableIssue,\n} from \"@vueye-table/core\";\nimport {\n computed,\n getCurrentInstance,\n getCurrentScope,\n nextTick,\n onMounted,\n onScopeDispose,\n shallowRef,\n toValue,\n watch,\n type ComponentPublicInstance,\n type MaybeRefOrGetter,\n} from \"vue\";\n\nimport type { DataGridBinding } from \"./use-data-grid\";\nimport type { DataTableBinding } from \"./use-data-table\";\n\nexport interface VirtualViewportOptions {\n readonly scrollElement: MaybeRefOrGetter<HTMLElement | null | undefined>;\n readonly overscan?: number | undefined;\n /** Number of items rendered before mount, without overscan. Defaults to 10. */\n readonly initialCount?: number | undefined;\n /** Space before the items, such as a sticky header or leading row-number column. */\n readonly scrollMargin?: MaybeRefOrGetter<number> | undefined;\n}\nexport interface UseVirtualRowsOptions<TRow> extends VirtualViewportOptions {\n readonly estimateRowHeight?: number | ((index: number) => number) | undefined;\n /** Connect logical grid focus to the rendered data row, skipping details. */\n readonly grid?: DataGridBinding<TRow> | undefined;\n}\nexport interface UseVirtualColumnsOptions extends VirtualViewportOptions {\n readonly estimateColumnWidth?: number | ((index: number) => number) | undefined;\n}\nexport interface VirtualRowItem<TRow> extends VirtualItem {\n readonly renderItem: TableRenderItem<TRow>;\n}\nexport interface VirtualColumnItem<TRow> extends VirtualItem {\n readonly column: TableColumn<TRow>;\n}\nexport interface VirtualBinding<TItem extends VirtualItem> extends Omit<VirtualWindow, \"items\"> {\n readonly items: readonly TItem[];\n getItem(index: number): TItem | undefined;\n scrollToIndex(index: number, options?: { readonly align?: VirtualAlign | undefined }): void;\n scrollToKey(key: RowKey, options?: { readonly align?: VirtualAlign | undefined }): void;\n /** Pass the virtual item key explicitly; null releases its previously observed element. */\n measureElement(element: Element | ComponentPublicInstance | null, key: RowKey): void;\n}\n\nfunction useVirtualAxis<TSource, TItem extends VirtualItem>(\n source: () => readonly TSource[],\n keyOf: (item: TSource) => RowKey,\n estimate: number | ((index: number) => number),\n options: VirtualViewportOptions,\n horizontal: boolean,\n project: (item: VirtualItem, source: TSource) => TItem,\n): VirtualBinding<TItem> {\n let items = source();\n let mounted = false;\n let disposed = false;\n let element: HTMLElement | null | undefined;\n let observer: ResizeObserver | undefined;\n let detach: (() => void) | undefined;\n const elements = new Map<RowKey, Element>();\n const keysByElement = new Map<Element, RowKey>();\n const requestedCount = options.initialCount ?? 10;\n const initialCount =\n Number.isSafeInteger(requestedCount) && requestedCount >= 0 ? requestedCount : 10;\n const initialIssue: TableIssue | undefined =\n initialCount === requestedCount\n ? undefined\n : Object.freeze({\n code: \"invalid_virtual_option\",\n message: \"Initial count must be a non-negative safe integer; 10 is used.\",\n });\n const layoutOptions = () => ({\n count: items.length,\n estimateSize: estimate,\n overscan: mounted ? options.overscan : 0,\n getKey: (index: number): RowKey => keyOf(items[index]!),\n });\n const virtual = createVirtualizer(layoutOptions());\n function seed(): void {\n let size = 0;\n for (let index = 0; index < Math.min(initialCount, items.length); index += 1) {\n const value = typeof estimate === \"number\" ? estimate : estimate(index);\n size += Number.isFinite(value) && value > 0 ? value : 40;\n }\n virtual.setViewport(0, size);\n }\n seed();\n const view = shallowRef(virtual.getWindow());\n const projected = computed(() =>\n Object.freeze(view.value.items.map((item) => Object.freeze(project(item, items[item.index]!)))),\n );\n const unsubscribe = virtual.subscribe((next) => {\n view.value = next;\n });\n const marginIssue = shallowRef<TableIssue>();\n\n function margin(): number {\n const value = toValue(options.scrollMargin) ?? 0;\n if (Number.isFinite(value) && value >= 0) {\n marginIssue.value = undefined;\n return value;\n }\n marginIssue.value ??= Object.freeze({\n code: \"invalid_virtual_option\",\n message: \"Scroll margin must be non-negative and finite; 0 is used.\",\n });\n return 0;\n }\n function viewportSize(): number {\n return element\n ? Math.max(0, (horizontal ? element.clientWidth : element.clientHeight) - margin())\n : virtual.getWindow().viewportSize;\n }\n function move(offset: number): void {\n if (element) {\n if (horizontal) element.scrollLeft = offset === 0 ? 0 : offset + margin();\n else element.scrollTop = offset === 0 ? 0 : offset + margin();\n }\n virtual.setViewport(offset, viewportSize());\n }\n function anchor(): { key: RowKey; inset: number } | undefined {\n const current = virtual.getWindow();\n const first = current.items.find((item) => item.start + item.size > current.offset);\n return first ? { key: first.key, inset: current.offset - first.start } : undefined;\n }\n function restore(saved: ReturnType<typeof anchor>, fallback: number): void {\n const index = saved ? items.findIndex((item) => keyOf(item) === saved.key) : -1;\n move(index >= 0 && saved ? virtual.getOffsetForIndex(index, \"start\") + saved.inset : fallback);\n // Reflect the clamp in the scroll element after shrink or removal.\n if (element) {\n const offset = virtual.getWindow().offset;\n if (horizontal) element.scrollLeft = offset === 0 ? 0 : offset + margin();\n else element.scrollTop = offset === 0 ? 0 : offset + margin();\n }\n }\n function measure(target: Element, key: RowKey): void {\n const saved = anchor();\n const offset = virtual.getWindow().offset;\n const box = target.getBoundingClientRect();\n const size = horizontal ? box.width : box.height;\n // Hidden and detached elements have no useful measurement; retain the estimate.\n if (size > 0 && Number.isFinite(size)) {\n const previous = virtual.getWindow();\n virtual.measure(key, size);\n if (virtual.getWindow() === previous) return;\n restore(saved, offset);\n }\n }\n function readViewport(): void {\n if (element)\n virtual.setViewport(\n Math.max(0, (horizontal ? element.scrollLeft : element.scrollTop) - margin()),\n viewportSize(),\n );\n }\n const stopSource = watch(\n source,\n (next) => {\n const saved = anchor();\n const offset = virtual.getWindow().offset;\n items = next;\n virtual.setOptions(layoutOptions());\n if (mounted) restore(saved, offset);\n else seed();\n },\n { flush: \"sync\" },\n );\n let stopElement: (() => void) | undefined;\n if (getCurrentInstance())\n onMounted(() => {\n mounted = true;\n virtual.setOptions(layoutOptions());\n stopElement = watch(\n () => toValue(options.scrollElement),\n (next) => {\n detach?.();\n observer?.disconnect();\n observer = undefined;\n element = next;\n if (!next) {\n seed();\n return;\n }\n const owner = next.ownerDocument.defaultView;\n const Observer = owner?.ResizeObserver;\n if (Observer) {\n observer = new Observer((entries) => {\n for (const entry of entries) {\n if (entry.target === element) readViewport();\n else {\n const key = keysByElement.get(entry.target);\n if (key !== undefined) measure(entry.target, key);\n }\n }\n });\n observer.observe(next);\n for (const target of elements.values()) observer.observe(target);\n } else owner?.addEventListener(\"resize\", readViewport);\n next.addEventListener(\"scroll\", readViewport, { passive: true });\n detach = () => {\n next.removeEventListener(\"scroll\", readViewport);\n owner?.removeEventListener(\"resize\", readViewport);\n };\n readViewport();\n for (const [key, target] of elements) measure(target, key);\n },\n { immediate: true, flush: \"post\" },\n );\n });\n if (getCurrentScope())\n onScopeDispose(() => {\n disposed = true;\n stopSource();\n stopElement?.();\n detach?.();\n observer?.disconnect();\n unsubscribe();\n elements.clear();\n keysByElement.clear();\n element = undefined;\n });\n margin();\n const binding = {\n getItem(index: number): TItem | undefined {\n // Reading the revision connects offscreen lookups to reactive measurements and layout.\n void view.value;\n const item = virtual.getItem(index);\n return item ? Object.freeze(project(item, items[index]!)) : undefined;\n },\n scrollToIndex(\n index: number,\n { align = \"auto\" }: { readonly align?: VirtualAlign | undefined } = {},\n ): void {\n move(virtual.getOffsetForIndex(index, align));\n },\n scrollToKey(key: RowKey, align?: { readonly align?: VirtualAlign | undefined }): void {\n const index = items.findIndex((item) => keyOf(item) === key);\n if (index >= 0) binding.scrollToIndex(index, align);\n },\n measureElement(target: Element | ComponentPublicInstance | null, key: RowKey): void {\n if (disposed) return;\n const previous = elements.get(key);\n if (previous === target) return;\n if (previous) {\n observer?.unobserve(previous);\n keysByElement.delete(previous);\n elements.delete(key);\n }\n if (!target || !(\"getBoundingClientRect\" in target)) return;\n elements.set(key, target);\n keysByElement.set(target, key);\n if (mounted) {\n observer?.observe(target);\n // A ref can run midway through a keyed row/spacer patch. Reading layout there can\n // clamp a pending scroll against a temporarily shortened content area.\n void nextTick(() => {\n if (!disposed && elements.get(key) === target) measure(target, key);\n });\n }\n },\n } as Record<string, unknown> &\n Pick<VirtualBinding<TItem>, \"getItem\" | \"scrollToIndex\" | \"scrollToKey\" | \"measureElement\">;\n for (const key of Object.keys(view.value))\n Object.defineProperty(binding, key, {\n enumerable: true,\n get: () =>\n key === \"items\"\n ? projected.value\n : key === \"issues\" && (initialIssue || marginIssue.value)\n ? Object.freeze([\n ...view.value.issues,\n ...(initialIssue ? [initialIssue] : []),\n ...(marginIssue.value ? [marginIssue.value] : []),\n ])\n : view.value[key as keyof VirtualWindow],\n });\n return Object.freeze(binding) as unknown as VirtualBinding<TItem>;\n}\n\n/** Virtualize data and detail render items. scrollToKey accepts the parent data-row key. */\nexport function useVirtualRows<TRow>(\n table: DataTableBinding<TRow>,\n options: UseVirtualRowsOptions<TRow>,\n): VirtualBinding<VirtualRowItem<TRow>> {\n const virtual = useVirtualAxis(\n () => table.renderItems,\n (item) => item.key,\n options.estimateRowHeight ?? 40,\n options,\n false,\n (item, renderItem) => ({ ...item, renderItem }),\n );\n const stopFocus = watch(\n () => options.grid?.selection?.focus.row,\n (row) => {\n if (row === undefined) return;\n const direct = table.renderItems[row];\n const index =\n direct?.kind === \"row\" && direct.rowIndex === row\n ? row\n : table.renderItems.findIndex((item) => item.kind === \"row\" && item.rowIndex === row);\n if (index >= 0) virtual.scrollToIndex(index);\n },\n { flush: \"sync\" },\n );\n if (getCurrentScope()) onScopeDispose(stopFocus);\n const binding = Object.defineProperties(\n {},\n {\n ...Object.getOwnPropertyDescriptors(virtual),\n scrollToKey: {\n enumerable: true,\n value: (key: RowKey, align?: { readonly align?: VirtualAlign | undefined }): void =>\n virtual.scrollToKey(getRowItemKey(key), align),\n },\n },\n );\n return Object.freeze(binding) as VirtualBinding<VirtualRowItem<TRow>>;\n}\n\n/** Virtualize visible columns and bring the active logical column into view. */\nexport function useVirtualColumns<TRow>(\n grid: DataGridBinding<TRow>,\n options: UseVirtualColumnsOptions,\n): VirtualBinding<VirtualColumnItem<TRow>> {\n const virtual = useVirtualAxis(\n () => grid.table.columns,\n (column) => column.id,\n options.estimateColumnWidth ?? 120,\n options,\n true,\n (item, column) => ({ ...item, column }),\n );\n const stopFocus = watch(\n () => grid.selection?.focus.column,\n (column) => {\n if (column !== undefined) virtual.scrollToIndex(column);\n },\n { flush: \"sync\" },\n );\n if (getCurrentScope()) onScopeDispose(stopFocus);\n return virtual;\n}\n","import {\n createTable,\n type ColumnDef,\n type DataTable,\n type TableOptions,\n type TableSnapshot,\n type TableStatePatch,\n type TreeLoadSignal,\n type TreeLoadController,\n type ExpandedState,\n type PendingChanges,\n type RowKey,\n} from \"@vueye-table/core\";\nimport {\n getCurrentScope,\n onScopeDispose,\n shallowRef,\n toRaw,\n toValue,\n watch,\n type MaybeRefOrGetter,\n} from \"vue\";\n\nimport { createRowDraft, type RowDraft } from \"./row-draft\";\n\n/** Options accepted by {@link useDataTable}. Data, columns, and state may be refs or getters. */\nexport interface UseDataTableOptions<\n TRow,\n TSignal extends TreeLoadSignal = AbortSignal,\n> extends Omit<TableOptions<TRow, TSignal>, \"data\" | \"columns\" | \"rowCount\"> {\n readonly data: MaybeRefOrGetter<readonly TRow[]>;\n readonly columns: MaybeRefOrGetter<readonly ColumnDef<TRow>[]>;\n readonly rowCount?: MaybeRefOrGetter<number | undefined> | undefined;\n /**\n * State owned by the caller, for example `v-model` props or URL query values. Whenever it\n * changes it is applied with `setState`; the table's own changes still reach `onStateChange`.\n */\n readonly state?: MaybeRefOrGetter<TableStatePatch | undefined> | undefined;\n}\n\ntype TableOperations<TRow> = Omit<DataTable<TRow>, \"getSnapshot\" | \"getState\" | \"subscribe\">;\n\n/**\n * A reactive view of a table: every snapshot field is a plain reactive property, so templates read\n * `table.rows` and `table.pageCount` directly, and every change goes through a named operation.\n * Watching a field needs a getter: `watch(() => table.page, ...)`.\n */\nexport type DataTableBinding<TRow> = TableSnapshot<TRow> &\n TableOperations<TRow> & {\n /** The engine behind the binding. */\n readonly table: DataTable<TRow>;\n /** The current snapshot, replaced on every change. */\n readonly snapshot: TableSnapshot<TRow>;\n readonly expanded: ExpandedState;\n readonly pendingChanges: PendingChanges<TRow>;\n editRow(key: RowKey): RowDraft<TRow>;\n };\n\n/**\n * A binding for any row type, for components that accept every table. Row types make the binding\n * invariant, so `DataTableBinding<unknown>` would refuse `DataTableBinding<Person>`.\n */\nexport type AnyDataTableBinding = DataTableBinding<any>;\n\nconst OPERATIONS = [\n \"appendData\",\n \"upsertData\",\n \"removeData\",\n \"stream\",\n \"insertRows\",\n \"removeRows\",\n \"getPendingChanges\",\n \"markSaved\",\n \"revert\",\n \"setState\",\n \"setData\",\n \"setColumns\",\n \"setRowCount\",\n \"toggleSort\",\n \"sort\",\n \"clearSorting\",\n \"search\",\n \"filter\",\n \"clearFilters\",\n \"goToPage\",\n \"nextPage\",\n \"previousPage\",\n \"setPageSize\",\n \"select\",\n \"deselect\",\n \"toggleRow\",\n \"toggleAll\",\n \"clearSelection\",\n \"getSelectedRows\",\n \"toggleExpanded\",\n \"expandAll\",\n \"collapseAll\",\n \"toggleColumn\",\n \"moveColumn\",\n \"edit\",\n \"undo\",\n \"redo\",\n \"copy\",\n \"paste\",\n \"clear\",\n \"exportRows\",\n \"reset\",\n \"destroy\",\n] as const satisfies readonly (keyof TableOperations<unknown>)[];\n\nfunction definedEntries(patch: TableStatePatch | undefined): TableStatePatch {\n return Object.fromEntries(Object.entries(patch ?? {}).filter(([, value]) => value !== undefined));\n}\n\n/**\n * Create a table bound to the current effect scope. The table follows its reactive data,\n * columns, row count, and state, and stops listening when the scope ends.\n */\nexport function useDataTable<TRow>(options: UseDataTableOptions<TRow>): DataTableBinding<TRow>;\nexport function useDataTable<TRow, TSignal extends TreeLoadSignal = AbortSignal>(\n options: UseDataTableOptions<TRow, TSignal> &\n (AbortSignal extends TSignal\n ? unknown\n : { readonly createChildLoadController: () => TreeLoadController<TSignal> }),\n): DataTableBinding<TRow>;\nexport function useDataTable<TRow, TSignal extends TreeLoadSignal = AbortSignal>(\n options: UseDataTableOptions<TRow, TSignal>,\n): DataTableBinding<TRow> {\n const table = createTable<TRow, TSignal>({\n ...options,\n data: toRaw(toValue(options.data)),\n columns: toValue(options.columns),\n rowCount: toValue(options.rowCount),\n initialState: { ...options.initialState, ...definedEntries(toValue(options.state)) },\n // Public overloads require custom signals to provide their matching factory.\n createChildLoadController:\n options.createChildLoadController ??\n ((() => new AbortController()) as unknown as () => TreeLoadController<TSignal>),\n });\n const drafts = new Set<() => void>();\n let disposed = false;\n const snapshot = shallowRef(table.getSnapshot());\n const unsubscribe = table.subscribe((next) => {\n snapshot.value = next;\n });\n\n const stops = [\n watch(\n () => toValue(options.data),\n // Reactive arrays arrive as proxies; the engine works on, and compares, the raw array.\n (data) => table.setData(toRaw(data)),\n ),\n watch(\n () => toValue(options.columns),\n (columns) => table.setColumns(columns),\n ),\n watch(\n () => toValue(options.rowCount),\n (rowCount) => {\n if (rowCount !== undefined) {\n table.setRowCount(rowCount);\n }\n },\n ),\n watch(\n () => toValue(options.state),\n (state) => {\n if (state) {\n table.setState(state);\n }\n },\n { deep: true },\n ),\n ];\n\n const dispose = (): void => {\n if (disposed) return;\n disposed = true;\n for (const disposeDraft of drafts) disposeDraft();\n drafts.clear();\n for (const stop of stops) {\n stop();\n }\n unsubscribe();\n table.destroy();\n };\n if (getCurrentScope()) onScopeDispose(dispose);\n\n const binding = { table } as Record<string, unknown>;\n Object.defineProperty(binding, \"snapshot\", { enumerable: true, get: () => snapshot.value });\n Object.defineProperty(binding, \"expanded\", {\n enumerable: true,\n get: () => snapshot.value.state.expanded,\n });\n Object.defineProperty(binding, \"pendingChanges\", {\n enumerable: true,\n get: () => {\n void snapshot.value;\n return table.getPendingChanges();\n },\n });\n binding[\"editRow\"] = (key: RowKey): RowDraft<TRow> =>\n createRowDraft(table, key, (disposeDraft) => {\n if (disposed) disposeDraft();\n else drafts.add(disposeDraft);\n return () => {\n drafts.delete(disposeDraft);\n };\n });\n for (const key of Object.keys(snapshot.value)) {\n Object.defineProperty(binding, key, {\n enumerable: true,\n get: () => snapshot.value[key as keyof TableSnapshot<TRow>],\n });\n }\n for (const name of OPERATIONS) {\n binding[name] = table[name];\n }\n binding[\"destroy\"] = dispose;\n return Object.freeze(binding) as unknown as DataTableBinding<TRow>;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vueye-table/vue",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.7",
|
|
4
4
|
"description": "Vue composables that bind the vueye-table engine to reactive state.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"composables",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"provenance": true
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@vueye-table/core": "3.0.0-alpha.
|
|
41
|
+
"@vueye-table/core": "3.0.0-alpha.7"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"vue": "3.5.43",
|