@ai-matrx/design-system 0.22.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +151 -0
- package/dist/data-table/cell-undo.cjs +98 -0
- package/dist/data-table/cell-undo.cjs.map +1 -0
- package/dist/data-table/cell-undo.d.cts +85 -0
- package/dist/data-table/cell-undo.d.ts +85 -0
- package/dist/data-table/cell-undo.js +78 -0
- package/dist/data-table/cell-undo.js.map +1 -0
- package/dist/data-table/copy-helpers.d.cts +6 -2
- package/dist/data-table/copy-helpers.d.ts +6 -2
- package/dist/data-table/coverage.cjs +116 -0
- package/dist/data-table/coverage.cjs.map +1 -0
- package/dist/data-table/coverage.d.cts +65 -0
- package/dist/data-table/coverage.d.ts +65 -0
- package/dist/data-table/coverage.js +96 -0
- package/dist/data-table/coverage.js.map +1 -0
- package/dist/data-table/fill.cjs +299 -0
- package/dist/data-table/fill.cjs.map +1 -0
- package/dist/data-table/fill.d.cts +129 -0
- package/dist/data-table/fill.d.ts +129 -0
- package/dist/data-table/fill.js +277 -0
- package/dist/data-table/fill.js.map +1 -0
- package/dist/data-table/filter-engine.d.cts +6 -2
- package/dist/data-table/filter-engine.d.ts +6 -2
- package/dist/data-table/grid-clipboard.cjs +165 -0
- package/dist/data-table/grid-clipboard.cjs.map +1 -0
- package/dist/data-table/grid-clipboard.d.cts +85 -0
- package/dist/data-table/grid-clipboard.d.ts +85 -0
- package/dist/data-table/grid-clipboard.js +145 -0
- package/dist/data-table/grid-clipboard.js.map +1 -0
- package/dist/data-table/grid-selection.cjs +258 -0
- package/dist/data-table/grid-selection.cjs.map +1 -0
- package/dist/data-table/grid-selection.d.cts +166 -0
- package/dist/data-table/grid-selection.d.ts +166 -0
- package/dist/data-table/grid-selection.js +238 -0
- package/dist/data-table/grid-selection.js.map +1 -0
- package/dist/data-table/grouping.cjs +302 -0
- package/dist/data-table/grouping.cjs.map +1 -0
- package/dist/data-table/grouping.d.cts +119 -0
- package/dist/data-table/grouping.d.ts +119 -0
- package/dist/data-table/grouping.js +282 -0
- package/dist/data-table/grouping.js.map +1 -0
- package/dist/data-table/host.d.cts +6 -2
- package/dist/data-table/host.d.ts +6 -2
- package/dist/data-table/index.cjs +2433 -246
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.d.cts +11 -3
- package/dist/data-table/index.d.ts +11 -3
- package/dist/data-table/index.js +2425 -238
- package/dist/data-table/index.js.map +1 -1
- package/dist/data-table/infer-filter.d.cts +6 -2
- package/dist/data-table/infer-filter.d.ts +6 -2
- package/dist/data-table/layered-filters.d.cts +6 -2
- package/dist/data-table/layered-filters.d.ts +6 -2
- package/dist/data-table/query-control.d.cts +6 -2
- package/dist/data-table/query-control.d.ts +6 -2
- package/dist/data-table/spreadsheet.cjs +1014 -0
- package/dist/data-table/spreadsheet.cjs.map +1 -0
- package/dist/data-table/spreadsheet.d.cts +118 -0
- package/dist/data-table/spreadsheet.d.ts +118 -0
- package/dist/data-table/spreadsheet.js +994 -0
- package/dist/data-table/spreadsheet.js.map +1 -0
- package/dist/data-table/types.cjs.map +1 -1
- package/dist/data-table/types.d.cts +6 -2
- package/dist/data-table/types.d.ts +6 -2
- package/dist/data-table/url-state.d.cts +6 -2
- package/dist/data-table/url-state.d.ts +6 -2
- package/dist/data-table/validation.cjs +229 -0
- package/dist/data-table/validation.cjs.map +1 -0
- package/dist/data-table/validation.d.cts +125 -0
- package/dist/data-table/validation.d.ts +125 -0
- package/dist/data-table/validation.js +209 -0
- package/dist/data-table/validation.js.map +1 -0
- package/dist/data-table/virtual-window.cjs +203 -0
- package/dist/data-table/virtual-window.cjs.map +1 -0
- package/dist/data-table/virtual-window.d.cts +84 -0
- package/dist/data-table/virtual-window.d.ts +84 -0
- package/dist/data-table/virtual-window.js +183 -0
- package/dist/data-table/virtual-window.js.map +1 -0
- package/dist/data-table/xlsx.d.cts +6 -2
- package/dist/data-table/xlsx.d.ts +6 -2
- package/dist/field-formats/index.d.cts +2 -2
- package/dist/field-formats/index.d.ts +2 -2
- package/dist/formulas/index.cjs +1041 -0
- package/dist/formulas/index.cjs.map +1 -0
- package/dist/formulas/index.d.cts +389 -0
- package/dist/formulas/index.d.ts +389 -0
- package/dist/formulas/index.js +1019 -0
- package/dist/formulas/index.js.map +1 -0
- package/dist/{types-BdbvlF9-.d.cts → types-CJWU1Gae.d.cts} +1 -1
- package/dist/{types-BdbvlF9-.d.ts → types-CJWU1Gae.d.ts} +1 -1
- package/dist/{types-Sn249eoy.d.cts → types-CmQrOz-T.d.cts} +154 -2
- package/dist/{types-D-flTpK0.d.ts → types-nlLCMiqd.d.ts} +154 -2
- package/package.json +109 -2
|
@@ -35,8 +35,11 @@ __export(data_table_exports, {
|
|
|
35
35
|
CELL_TINT_CLASS: () => CELL_TINT_CLASS,
|
|
36
36
|
COLOR_RULE_OPS: () => COLOR_RULE_OPS,
|
|
37
37
|
COLOR_RULE_OP_LABELS: () => COLOR_RULE_OP_LABELS,
|
|
38
|
+
DEFAULT_OVERSCAN: () => DEFAULT_OVERSCAN,
|
|
39
|
+
DEFAULT_UNDO_DEPTH: () => DEFAULT_UNDO_DEPTH,
|
|
38
40
|
DataRowInspector: () => DataRowInspector,
|
|
39
41
|
DataRowWindow: () => DataRowWindow,
|
|
42
|
+
EMPTY_GROUP_KEY: () => EMPTY_GROUP_KEY,
|
|
40
43
|
EMPTY_TABLE_STYLE: () => EMPTY_TABLE_STYLE,
|
|
41
44
|
FORMAT_MISMATCH_CLASS: () => FORMAT_MISMATCH_CLASS,
|
|
42
45
|
FormattedCell: () => FormattedCell,
|
|
@@ -47,6 +50,7 @@ __export(data_table_exports, {
|
|
|
47
50
|
MatrxUuidCell: () => MatrxUuidCell,
|
|
48
51
|
NO_FROZEN_COLUMNS: () => NO_FROZEN_COLUMNS,
|
|
49
52
|
OPS_WITH_VALUE: () => OPS_WITH_VALUE,
|
|
53
|
+
PARTIAL_BADGE: () => PARTIAL_BADGE,
|
|
50
54
|
ROW_TINT_CLASS: () => ROW_TINT_CLASS,
|
|
51
55
|
STYLE_COLORS: () => STYLE_COLORS,
|
|
52
56
|
STYLE_COLOR_LABELS: () => STYLE_COLOR_LABELS,
|
|
@@ -56,22 +60,62 @@ __export(data_table_exports, {
|
|
|
56
60
|
TABLE_STYLE_VERSION: () => TABLE_STYLE_VERSION,
|
|
57
61
|
TableTitleRow: () => TableTitleRow,
|
|
58
62
|
TableViewTabs: () => TableViewTabs,
|
|
63
|
+
UNKNOWN_TOTAL_BADGE: () => UNKNOWN_TOTAL_BADGE,
|
|
59
64
|
alignForFormat: () => alignForFormat,
|
|
65
|
+
allRange: () => allRange,
|
|
60
66
|
applyStylePath: () => applyStylePath,
|
|
67
|
+
boundsContain: () => boundsContain,
|
|
61
68
|
buildRowAgentInput: () => buildRowAgentInput,
|
|
62
69
|
buildViewAgentInput: () => buildViewAgentInput,
|
|
63
70
|
buildViewHuman: () => buildViewHuman,
|
|
71
|
+
canRedo: () => canRedo,
|
|
72
|
+
canUndo: () => canUndo,
|
|
73
|
+
cellClipboardText: () => cellClipboardText,
|
|
74
|
+
cellDomKey: () => cellDomKey,
|
|
75
|
+
cellsInRange: () => cellsInRange,
|
|
76
|
+
classifyGridKey: () => classifyGridKey,
|
|
77
|
+
coerceGroupNumber: () => coerceGroupNumber,
|
|
64
78
|
collectSelectOptions: () => collectSelectOptions,
|
|
65
79
|
colorForChoice: () => colorForChoice,
|
|
80
|
+
columnRange: () => columnRange,
|
|
81
|
+
computeVariableWindow: () => computeVariableWindow,
|
|
82
|
+
computeWindow: () => computeWindow,
|
|
83
|
+
createUndoStack: () => createUndoStack,
|
|
84
|
+
describeCoverage: () => describeCoverage,
|
|
85
|
+
detectSeries: () => detectSeries,
|
|
86
|
+
directClickKinds: () => directClickKinds,
|
|
66
87
|
downloadTableAsXlsx: () => downloadTableAsXlsx,
|
|
67
88
|
evaluateRule: () => evaluateRule,
|
|
89
|
+
fillDown: () => fillDown,
|
|
90
|
+
fillRange: () => fillRange,
|
|
91
|
+
fillTargetFor: () => fillTargetFor,
|
|
68
92
|
filterKindLabel: () => filterKindLabel,
|
|
93
|
+
flattenGroups: () => flattenGroups,
|
|
69
94
|
formatColumnValue: () => formatColumnValue,
|
|
95
|
+
formatGroupNumber: () => formatGroupNumber,
|
|
96
|
+
gridToTsv: () => gridToTsv,
|
|
97
|
+
groupKeyOf: () => groupKeyOf,
|
|
98
|
+
groupRows: () => groupRows,
|
|
99
|
+
groupSummary: () => groupSummary,
|
|
70
100
|
inferTableSearchRole: () => inferTableSearchRole,
|
|
101
|
+
isBlankGroupValue: () => isBlankGroupValue,
|
|
102
|
+
isDirectClickEditor: () => isDirectClickEditor,
|
|
103
|
+
isGroupCollapsed: () => isGroupCollapsed,
|
|
104
|
+
isSingleCell: () => isSingleCell,
|
|
105
|
+
isSingleCellRange: () => isSingleCellRange,
|
|
71
106
|
isStyleColor: () => isStyleColor,
|
|
107
|
+
moveSelection: () => moveSelection,
|
|
108
|
+
parseClipboardGrid: () => parseClipboardGrid,
|
|
72
109
|
parseTableStyle: () => parseTableStyle,
|
|
73
110
|
parseTableViewSnapshot: () => parseTableViewSnapshot,
|
|
74
111
|
pixelWidth: () => pixelWidth,
|
|
112
|
+
planPaste: () => planPaste,
|
|
113
|
+
popRedo: () => popRedo,
|
|
114
|
+
popUndo: () => popUndo,
|
|
115
|
+
pushUndo: () => pushUndo,
|
|
116
|
+
rangeBounds: () => rangeBounds,
|
|
117
|
+
rangeRows: () => rangeRows,
|
|
118
|
+
rangeSize: () => rangeSize,
|
|
75
119
|
rankTableSearchRows: () => rankTableSearchRows,
|
|
76
120
|
resolveCellColor: () => resolveCellColor,
|
|
77
121
|
resolveColumnMarker: () => resolveColumnMarker,
|
|
@@ -79,23 +123,31 @@ __export(data_table_exports, {
|
|
|
79
123
|
resolveFrozenColumns: () => resolveFrozenColumns,
|
|
80
124
|
resolveRowColor: () => resolveRowColor,
|
|
81
125
|
resolveTableSearchScopes: () => resolveTableSearchScopes,
|
|
126
|
+
rowRange: () => rowRange,
|
|
82
127
|
rowsToCsvFromColumns: () => rowsToCsvFromColumns,
|
|
83
128
|
rowsToMarkdownTable: () => rowsToMarkdownTable,
|
|
84
129
|
rowsToRecordsFromColumns: () => rowsToRecordsFromColumns,
|
|
130
|
+
sameCell: () => sameCell,
|
|
131
|
+
scrollOffsetForIndex: () => scrollOffsetForIndex,
|
|
85
132
|
shortUuid: () => shortUuid,
|
|
133
|
+
storedValuesEqual: () => storedValuesEqual,
|
|
86
134
|
stylePath: () => stylePath,
|
|
87
135
|
tableStyleFromMetadata: () => tableStyleFromMetadata,
|
|
88
136
|
tableStyleIsEmpty: () => tableStyleIsEmpty,
|
|
89
137
|
tableUrlParamPrefix: () => tableUrlParamPrefix,
|
|
138
|
+
tileIndex: () => tileIndex,
|
|
139
|
+
toggleGroupCollapsed: () => toggleGroupCollapsed,
|
|
140
|
+
undoEntryFor: () => undoEntryFor,
|
|
90
141
|
useMatrxDataTableHost: () => useMatrxDataTableHost,
|
|
91
142
|
useMatrxTableRowAlchemy: () => useMatrxTableRowAlchemy,
|
|
92
143
|
useScrollPagination: () => useScrollPagination,
|
|
144
|
+
useSpreadsheetGrid: () => useSpreadsheetGrid,
|
|
93
145
|
useTableUrlState: () => useTableUrlState
|
|
94
146
|
});
|
|
95
147
|
module.exports = __toCommonJS(data_table_exports);
|
|
96
148
|
|
|
97
149
|
// src/data-table/MatrxDataTable.tsx
|
|
98
|
-
var
|
|
150
|
+
var import_react21 = require("react");
|
|
99
151
|
var import_core3 = require("@dnd-kit/core");
|
|
100
152
|
|
|
101
153
|
// src/data-table/icons.tsx
|
|
@@ -5512,11 +5564,11 @@ var import_react11 = require("react");
|
|
|
5512
5564
|
var import_url_state = require("@ai-matrx/kit/url-state");
|
|
5513
5565
|
function parseSort(raw) {
|
|
5514
5566
|
if (!raw) return null;
|
|
5515
|
-
const
|
|
5516
|
-
if (
|
|
5517
|
-
const direction = raw.slice(
|
|
5567
|
+
const at2 = raw.lastIndexOf(".");
|
|
5568
|
+
if (at2 <= 0) return null;
|
|
5569
|
+
const direction = raw.slice(at2 + 1);
|
|
5518
5570
|
if (direction !== "asc" && direction !== "desc") return null;
|
|
5519
|
-
return { id: raw.slice(0,
|
|
5571
|
+
return { id: raw.slice(0, at2), direction };
|
|
5520
5572
|
}
|
|
5521
5573
|
function parseObject(raw, fallback) {
|
|
5522
5574
|
if (!raw) return fallback;
|
|
@@ -6790,6 +6842,1611 @@ function projectColumnDragOrder(orderedIds, preview2) {
|
|
|
6790
6842
|
return order;
|
|
6791
6843
|
}
|
|
6792
6844
|
|
|
6845
|
+
// src/data-table/grouping.ts
|
|
6846
|
+
var EMPTY_GROUP_KEY = "empty";
|
|
6847
|
+
var DEFAULT_EMPTY_LABEL = "(empty)";
|
|
6848
|
+
function isBlankGroupValue(value) {
|
|
6849
|
+
return value === null || value === void 0 || value === "";
|
|
6850
|
+
}
|
|
6851
|
+
function groupKeyOf(value) {
|
|
6852
|
+
if (isBlankGroupValue(value)) return EMPTY_GROUP_KEY;
|
|
6853
|
+
switch (typeof value) {
|
|
6854
|
+
case "string":
|
|
6855
|
+
return `s:${value}`;
|
|
6856
|
+
case "number":
|
|
6857
|
+
return `n:${String(value)}`;
|
|
6858
|
+
case "boolean":
|
|
6859
|
+
return `b:${value ? "true" : "false"}`;
|
|
6860
|
+
case "bigint":
|
|
6861
|
+
return `i:${String(value)}`;
|
|
6862
|
+
case "symbol":
|
|
6863
|
+
return `y:${String(value)}`;
|
|
6864
|
+
case "function":
|
|
6865
|
+
return `f:${safeString(value)}`;
|
|
6866
|
+
default:
|
|
6867
|
+
break;
|
|
6868
|
+
}
|
|
6869
|
+
if (value instanceof Date) {
|
|
6870
|
+
const time = value.getTime();
|
|
6871
|
+
return `d:${Number.isFinite(time) ? value.toISOString() : "invalid"}`;
|
|
6872
|
+
}
|
|
6873
|
+
return `o:${safeJson(value)}`;
|
|
6874
|
+
}
|
|
6875
|
+
function safeString(value) {
|
|
6876
|
+
try {
|
|
6877
|
+
return String(value);
|
|
6878
|
+
} catch {
|
|
6879
|
+
return "[unreadable]";
|
|
6880
|
+
}
|
|
6881
|
+
}
|
|
6882
|
+
function safeJson(value) {
|
|
6883
|
+
try {
|
|
6884
|
+
const json = JSON.stringify(value);
|
|
6885
|
+
return typeof json === "string" ? json : safeString(value);
|
|
6886
|
+
} catch {
|
|
6887
|
+
return safeString(value);
|
|
6888
|
+
}
|
|
6889
|
+
}
|
|
6890
|
+
var CURRENCY_AND_SPACE = /[\s,$£€¥]/g;
|
|
6891
|
+
function coerceGroupNumber(value) {
|
|
6892
|
+
if (isBlankGroupValue(value)) return null;
|
|
6893
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
6894
|
+
if (typeof value === "boolean") return value ? 1 : 0;
|
|
6895
|
+
if (typeof value === "bigint") {
|
|
6896
|
+
const asNumber = Number(value);
|
|
6897
|
+
return Number.isFinite(asNumber) ? asNumber : null;
|
|
6898
|
+
}
|
|
6899
|
+
if (typeof value !== "string") return null;
|
|
6900
|
+
const cleaned = value.replace(CURRENCY_AND_SPACE, "");
|
|
6901
|
+
if (cleaned === "" || cleaned === "-" || cleaned === "+") return null;
|
|
6902
|
+
const parsed = Number(cleaned);
|
|
6903
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
6904
|
+
}
|
|
6905
|
+
var NUMBER_FORMAT = new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 });
|
|
6906
|
+
function formatGroupNumber(value) {
|
|
6907
|
+
if (!Number.isFinite(value)) return "\u2014";
|
|
6908
|
+
try {
|
|
6909
|
+
return NUMBER_FORMAT.format(value);
|
|
6910
|
+
} catch {
|
|
6911
|
+
return String(value);
|
|
6912
|
+
}
|
|
6913
|
+
}
|
|
6914
|
+
function defaultLabelOf(value, emptyLabel) {
|
|
6915
|
+
if (isBlankGroupValue(value)) return emptyLabel;
|
|
6916
|
+
if (typeof value === "string") return value;
|
|
6917
|
+
if (typeof value === "number") return formatGroupNumber(value);
|
|
6918
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
6919
|
+
if (value instanceof Date) {
|
|
6920
|
+
const time = value.getTime();
|
|
6921
|
+
return Number.isFinite(time) ? value.toISOString() : "Invalid Date";
|
|
6922
|
+
}
|
|
6923
|
+
if (typeof value === "object") return safeJson(value);
|
|
6924
|
+
return safeString(value);
|
|
6925
|
+
}
|
|
6926
|
+
var AGGREGATE_NAMES = {
|
|
6927
|
+
count: { name: "Count", position: "before" },
|
|
6928
|
+
sum: { name: "Sum", position: "before" },
|
|
6929
|
+
average: { name: "Average", position: "before" },
|
|
6930
|
+
min: { name: "Min", position: "before" },
|
|
6931
|
+
max: { name: "Max", position: "before" },
|
|
6932
|
+
empty: { name: "empty", position: "after" },
|
|
6933
|
+
filled: { name: "filled", position: "after" },
|
|
6934
|
+
unique: { name: "unique", position: "after" },
|
|
6935
|
+
checked: { name: "checked", position: "after" },
|
|
6936
|
+
unchecked: { name: "unchecked", position: "after" },
|
|
6937
|
+
percentFilled: { name: "filled", position: "after" }
|
|
6938
|
+
};
|
|
6939
|
+
function aggregateLabel(kind, value, override) {
|
|
6940
|
+
const naming = AGGREGATE_NAMES[kind] ?? { name: kind, position: "before" };
|
|
6941
|
+
const name = override && override.trim() !== "" ? override : naming.name;
|
|
6942
|
+
const shown = value === null ? "\u2014" : kind === "percentFilled" ? `${formatGroupNumber(value)}%` : formatGroupNumber(value);
|
|
6943
|
+
return naming.position === "before" ? `${name} ${shown}` : `${shown} ${name}`;
|
|
6944
|
+
}
|
|
6945
|
+
function readValue(row, reader) {
|
|
6946
|
+
try {
|
|
6947
|
+
return reader(row);
|
|
6948
|
+
} catch {
|
|
6949
|
+
return null;
|
|
6950
|
+
}
|
|
6951
|
+
}
|
|
6952
|
+
function computeAggregate(rows, column) {
|
|
6953
|
+
const kind = column.spec.kind;
|
|
6954
|
+
const raw = rows.map((row) => readValue(row, column.readCell));
|
|
6955
|
+
const total = raw.length;
|
|
6956
|
+
const filled = raw.filter((value2) => !isBlankGroupValue(value2));
|
|
6957
|
+
const numbers = filled.map((value2) => coerceGroupNumber(value2)).filter((value2) => value2 !== null);
|
|
6958
|
+
let value;
|
|
6959
|
+
switch (kind) {
|
|
6960
|
+
case "count":
|
|
6961
|
+
value = total;
|
|
6962
|
+
break;
|
|
6963
|
+
case "sum":
|
|
6964
|
+
value = numbers.length === 0 ? null : numbers.reduce((acc, n) => acc + n, 0);
|
|
6965
|
+
break;
|
|
6966
|
+
case "average":
|
|
6967
|
+
value = numbers.length === 0 ? null : numbers.reduce((acc, n) => acc + n, 0) / numbers.length;
|
|
6968
|
+
break;
|
|
6969
|
+
case "min":
|
|
6970
|
+
value = numbers.length === 0 ? null : numbers.reduce((acc, n) => n < acc ? n : acc);
|
|
6971
|
+
break;
|
|
6972
|
+
case "max":
|
|
6973
|
+
value = numbers.length === 0 ? null : numbers.reduce((acc, n) => n > acc ? n : acc);
|
|
6974
|
+
break;
|
|
6975
|
+
case "empty":
|
|
6976
|
+
value = total - filled.length;
|
|
6977
|
+
break;
|
|
6978
|
+
case "filled":
|
|
6979
|
+
value = filled.length;
|
|
6980
|
+
break;
|
|
6981
|
+
case "unique": {
|
|
6982
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6983
|
+
for (const entry of filled) seen.add(groupKeyOf(entry));
|
|
6984
|
+
value = seen.size;
|
|
6985
|
+
break;
|
|
6986
|
+
}
|
|
6987
|
+
case "checked":
|
|
6988
|
+
value = filled.filter((entry) => entry === true).length;
|
|
6989
|
+
break;
|
|
6990
|
+
case "unchecked":
|
|
6991
|
+
value = filled.filter((entry) => entry === false).length;
|
|
6992
|
+
break;
|
|
6993
|
+
case "percentFilled":
|
|
6994
|
+
value = total === 0 ? null : filled.length / total * 100;
|
|
6995
|
+
break;
|
|
6996
|
+
default:
|
|
6997
|
+
value = null;
|
|
6998
|
+
break;
|
|
6999
|
+
}
|
|
7000
|
+
return { kind, value, label: aggregateLabel(kind, value, column.spec.label) };
|
|
7001
|
+
}
|
|
7002
|
+
function compareLabels(a, b) {
|
|
7003
|
+
if (a === b) return 0;
|
|
7004
|
+
return a < b ? -1 : 1;
|
|
7005
|
+
}
|
|
7006
|
+
function compareValues2(a, b) {
|
|
7007
|
+
const aNumber = typeof a.value === "number" ? a.value : null;
|
|
7008
|
+
const bNumber = typeof b.value === "number" ? b.value : null;
|
|
7009
|
+
if (aNumber !== null && bNumber !== null && aNumber !== bNumber) return aNumber < bNumber ? -1 : 1;
|
|
7010
|
+
if (typeof a.value === "boolean" && typeof b.value === "boolean" && a.value !== b.value) {
|
|
7011
|
+
return a.value ? 1 : -1;
|
|
7012
|
+
}
|
|
7013
|
+
return compareLabels(a.label, b.label);
|
|
7014
|
+
}
|
|
7015
|
+
function groupRows(options) {
|
|
7016
|
+
const rows = Array.isArray(options.rows) ? options.rows : [];
|
|
7017
|
+
const emptyLabel = options.emptyLabel ?? DEFAULT_EMPTY_LABEL;
|
|
7018
|
+
const order = options.order ?? "value-asc";
|
|
7019
|
+
const aggregates = options.aggregates ?? {};
|
|
7020
|
+
const labelFor = (value) => {
|
|
7021
|
+
if (!options.labelOf) return defaultLabelOf(value, emptyLabel);
|
|
7022
|
+
if (isBlankGroupValue(value)) {
|
|
7023
|
+
try {
|
|
7024
|
+
const custom = options.labelOf(value);
|
|
7025
|
+
return typeof custom === "string" && custom !== "" ? custom : emptyLabel;
|
|
7026
|
+
} catch {
|
|
7027
|
+
return emptyLabel;
|
|
7028
|
+
}
|
|
7029
|
+
}
|
|
7030
|
+
try {
|
|
7031
|
+
const custom = options.labelOf(value);
|
|
7032
|
+
return typeof custom === "string" ? custom : defaultLabelOf(value, emptyLabel);
|
|
7033
|
+
} catch {
|
|
7034
|
+
return defaultLabelOf(value, emptyLabel);
|
|
7035
|
+
}
|
|
7036
|
+
};
|
|
7037
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
7038
|
+
for (const row of rows) {
|
|
7039
|
+
const raw = readValue(row, options.readCell);
|
|
7040
|
+
const blank = isBlankGroupValue(raw);
|
|
7041
|
+
const value = blank ? null : raw;
|
|
7042
|
+
const key = groupKeyOf(value);
|
|
7043
|
+
let bucket = buckets.get(key);
|
|
7044
|
+
if (!bucket) {
|
|
7045
|
+
bucket = { key, value, label: labelFor(value), rows: [], seen: buckets.size };
|
|
7046
|
+
buckets.set(key, bucket);
|
|
7047
|
+
}
|
|
7048
|
+
bucket.rows.push(row);
|
|
7049
|
+
}
|
|
7050
|
+
const ordered = [...buckets.values()].sort((a, b) => {
|
|
7051
|
+
const aBlank = a.key === EMPTY_GROUP_KEY;
|
|
7052
|
+
const bBlank = b.key === EMPTY_GROUP_KEY;
|
|
7053
|
+
if (aBlank !== bBlank) return aBlank ? 1 : -1;
|
|
7054
|
+
if (aBlank && bBlank) return 0;
|
|
7055
|
+
switch (order) {
|
|
7056
|
+
case "value-asc":
|
|
7057
|
+
return compareValues2(a, b) || a.seen - b.seen;
|
|
7058
|
+
case "value-desc":
|
|
7059
|
+
return -compareValues2(a, b) || a.seen - b.seen;
|
|
7060
|
+
case "count-desc":
|
|
7061
|
+
return b.rows.length - a.rows.length || a.seen - b.seen;
|
|
7062
|
+
case "first-seen":
|
|
7063
|
+
default:
|
|
7064
|
+
return a.seen - b.seen;
|
|
7065
|
+
}
|
|
7066
|
+
});
|
|
7067
|
+
const aggregateEntries = Object.entries(aggregates);
|
|
7068
|
+
return ordered.map((bucket, index) => {
|
|
7069
|
+
const results = {};
|
|
7070
|
+
for (const [columnId2, column] of aggregateEntries) {
|
|
7071
|
+
if (!column || typeof column.readCell !== "function" || !column.spec) continue;
|
|
7072
|
+
results[columnId2] = computeAggregate(bucket.rows, column);
|
|
7073
|
+
}
|
|
7074
|
+
return {
|
|
7075
|
+
key: bucket.key,
|
|
7076
|
+
value: bucket.value,
|
|
7077
|
+
label: bucket.label,
|
|
7078
|
+
rows: bucket.rows,
|
|
7079
|
+
aggregates: results,
|
|
7080
|
+
index
|
|
7081
|
+
};
|
|
7082
|
+
});
|
|
7083
|
+
}
|
|
7084
|
+
function toggleGroupCollapsed(collapsed, key) {
|
|
7085
|
+
const list = Array.isArray(collapsed) ? collapsed : [];
|
|
7086
|
+
return list.includes(key) ? list.filter((entry) => entry !== key) : [...list, key];
|
|
7087
|
+
}
|
|
7088
|
+
function isGroupCollapsed(collapsed, key) {
|
|
7089
|
+
return Array.isArray(collapsed) ? collapsed.includes(key) : false;
|
|
7090
|
+
}
|
|
7091
|
+
function flattenGroups(groups, collapsed) {
|
|
7092
|
+
const out = [];
|
|
7093
|
+
let dataIndex = 0;
|
|
7094
|
+
for (const group of Array.isArray(groups) ? groups : []) {
|
|
7095
|
+
out.push({ kind: "group", group });
|
|
7096
|
+
if (isGroupCollapsed(collapsed, group.key)) continue;
|
|
7097
|
+
for (const row of group.rows) {
|
|
7098
|
+
out.push({ kind: "row", group, row, dataIndex });
|
|
7099
|
+
dataIndex += 1;
|
|
7100
|
+
}
|
|
7101
|
+
}
|
|
7102
|
+
return out;
|
|
7103
|
+
}
|
|
7104
|
+
function groupSummary(group, rowNoun = "row") {
|
|
7105
|
+
const count = group?.rows?.length ?? 0;
|
|
7106
|
+
const noun = count === 1 ? rowNoun : `${rowNoun}s`;
|
|
7107
|
+
const parts = [`${formatGroupNumber(count)} ${noun}`];
|
|
7108
|
+
for (const result of Object.values(group?.aggregates ?? {})) {
|
|
7109
|
+
if (result?.label) parts.push(result.label);
|
|
7110
|
+
}
|
|
7111
|
+
return parts.join(" \xB7 ");
|
|
7112
|
+
}
|
|
7113
|
+
|
|
7114
|
+
// src/data-table/virtual-window.ts
|
|
7115
|
+
var DEFAULT_OVERSCAN = 6;
|
|
7116
|
+
function isNum(value) {
|
|
7117
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
7118
|
+
}
|
|
7119
|
+
function toCount(value) {
|
|
7120
|
+
return isNum(value) && value > 0 ? Math.floor(value) : 0;
|
|
7121
|
+
}
|
|
7122
|
+
function toLength(value) {
|
|
7123
|
+
return isNum(value) && value > 0 ? value : 0;
|
|
7124
|
+
}
|
|
7125
|
+
function toOverscan(value) {
|
|
7126
|
+
if (!isNum(value)) return DEFAULT_OVERSCAN;
|
|
7127
|
+
return value > 0 ? Math.floor(value) : 0;
|
|
7128
|
+
}
|
|
7129
|
+
function toPinned(value, count) {
|
|
7130
|
+
if (!isNum(value) || value <= 0) return 0;
|
|
7131
|
+
return Math.min(Math.floor(value), count);
|
|
7132
|
+
}
|
|
7133
|
+
function assemble(args) {
|
|
7134
|
+
const { pinnedCount, start, end, padStart, body, total } = args;
|
|
7135
|
+
let padEnd = total - (padStart + body);
|
|
7136
|
+
if (!Number.isFinite(padEnd)) padEnd = 0;
|
|
7137
|
+
const sum = padStart + body + padEnd;
|
|
7138
|
+
if (sum !== total) padEnd = padEnd + (total - sum);
|
|
7139
|
+
const pinned = [];
|
|
7140
|
+
for (let i = 0; i < pinnedCount; i += 1) pinned.push(i);
|
|
7141
|
+
return { start, end, padStart, padEnd, total, pinned };
|
|
7142
|
+
}
|
|
7143
|
+
function emptyWindow(pinnedCount) {
|
|
7144
|
+
const pinned = [];
|
|
7145
|
+
for (let i = 0; i < pinnedCount; i += 1) pinned.push(i);
|
|
7146
|
+
return { start: pinnedCount, end: pinnedCount, padStart: 0, padEnd: 0, total: 0, pinned };
|
|
7147
|
+
}
|
|
7148
|
+
function band(firstVisible, lastVisible, scrollCount, overscan) {
|
|
7149
|
+
let first = firstVisible;
|
|
7150
|
+
if (first > scrollCount - 1) first = scrollCount - 1;
|
|
7151
|
+
if (first < 0) first = 0;
|
|
7152
|
+
let last = lastVisible;
|
|
7153
|
+
if (last < first + 1) last = first + 1;
|
|
7154
|
+
if (last > scrollCount) last = scrollCount;
|
|
7155
|
+
const start = Math.max(0, first - overscan);
|
|
7156
|
+
let end = Math.min(scrollCount, last + overscan);
|
|
7157
|
+
if (end < start) end = start;
|
|
7158
|
+
return { start, end };
|
|
7159
|
+
}
|
|
7160
|
+
function computeWindow(input) {
|
|
7161
|
+
const count = toCount(input?.count);
|
|
7162
|
+
const pinnedCount = toPinned(input?.pinnedStart, count);
|
|
7163
|
+
if (count <= 0) return emptyWindow(0);
|
|
7164
|
+
const itemSize = toLength(input?.itemSize);
|
|
7165
|
+
const viewport = toLength(input?.viewport);
|
|
7166
|
+
const overscan = toOverscan(input?.overscan);
|
|
7167
|
+
const scrollCount = count - pinnedCount;
|
|
7168
|
+
if (scrollCount <= 0) return emptyWindow(pinnedCount);
|
|
7169
|
+
if (itemSize <= 0) {
|
|
7170
|
+
return assemble({ pinnedCount, start: pinnedCount, end: count, padStart: 0, body: 0, total: 0 });
|
|
7171
|
+
}
|
|
7172
|
+
const total = scrollCount * itemSize;
|
|
7173
|
+
const maxOffset = Math.max(0, total - viewport);
|
|
7174
|
+
const offset = Math.min(toLength(input?.offset), maxOffset);
|
|
7175
|
+
const { start: relStart, end: relEnd } = band(
|
|
7176
|
+
Math.floor(offset / itemSize),
|
|
7177
|
+
Math.ceil((offset + viewport) / itemSize),
|
|
7178
|
+
scrollCount,
|
|
7179
|
+
overscan
|
|
7180
|
+
);
|
|
7181
|
+
return assemble({
|
|
7182
|
+
pinnedCount,
|
|
7183
|
+
start: pinnedCount + relStart,
|
|
7184
|
+
end: pinnedCount + relEnd,
|
|
7185
|
+
padStart: relStart * itemSize,
|
|
7186
|
+
body: (relEnd - relStart) * itemSize,
|
|
7187
|
+
total
|
|
7188
|
+
});
|
|
7189
|
+
}
|
|
7190
|
+
var PREFIX_CACHE = /* @__PURE__ */ new WeakMap();
|
|
7191
|
+
function prefixFor(sizeAt, count) {
|
|
7192
|
+
let byCount = PREFIX_CACHE.get(sizeAt);
|
|
7193
|
+
if (!byCount) {
|
|
7194
|
+
byCount = /* @__PURE__ */ new Map();
|
|
7195
|
+
PREFIX_CACHE.set(sizeAt, byCount);
|
|
7196
|
+
}
|
|
7197
|
+
const cached = byCount.get(count);
|
|
7198
|
+
if (cached) return cached;
|
|
7199
|
+
const prefix = new Float64Array(count + 1);
|
|
7200
|
+
let running = 0;
|
|
7201
|
+
for (let i = 0; i < count; i += 1) {
|
|
7202
|
+
let size = 0;
|
|
7203
|
+
try {
|
|
7204
|
+
size = sizeAt(i);
|
|
7205
|
+
} catch {
|
|
7206
|
+
size = 0;
|
|
7207
|
+
}
|
|
7208
|
+
running += isNum(size) && size > 0 ? size : 0;
|
|
7209
|
+
prefix[i + 1] = running;
|
|
7210
|
+
}
|
|
7211
|
+
byCount.set(count, prefix);
|
|
7212
|
+
return prefix;
|
|
7213
|
+
}
|
|
7214
|
+
function at(prefix, index) {
|
|
7215
|
+
return prefix[index] ?? 0;
|
|
7216
|
+
}
|
|
7217
|
+
function lastAtOrBefore(prefix, lo, hi, target) {
|
|
7218
|
+
let a = lo;
|
|
7219
|
+
let b = hi;
|
|
7220
|
+
while (a < b) {
|
|
7221
|
+
const mid = a + Math.ceil((b - a) / 2);
|
|
7222
|
+
if (at(prefix, mid) <= target) a = mid;
|
|
7223
|
+
else b = mid - 1;
|
|
7224
|
+
}
|
|
7225
|
+
return a;
|
|
7226
|
+
}
|
|
7227
|
+
function firstAtOrAfter(prefix, lo, hi, target) {
|
|
7228
|
+
let a = lo;
|
|
7229
|
+
let b = hi;
|
|
7230
|
+
while (a < b) {
|
|
7231
|
+
const mid = a + Math.floor((b - a) / 2);
|
|
7232
|
+
if (at(prefix, mid) >= target) b = mid;
|
|
7233
|
+
else a = mid + 1;
|
|
7234
|
+
}
|
|
7235
|
+
return a;
|
|
7236
|
+
}
|
|
7237
|
+
function computeVariableWindow(input) {
|
|
7238
|
+
const count = toCount(input?.count);
|
|
7239
|
+
const pinnedCount = toPinned(input?.pinnedStart, count);
|
|
7240
|
+
if (count <= 0) return emptyWindow(0);
|
|
7241
|
+
const sizeAt = typeof input?.sizeAt === "function" ? input.sizeAt : () => 0;
|
|
7242
|
+
const viewport = toLength(input?.viewport);
|
|
7243
|
+
const overscan = toOverscan(input?.overscan);
|
|
7244
|
+
const scrollCount = count - pinnedCount;
|
|
7245
|
+
if (scrollCount <= 0) return emptyWindow(pinnedCount);
|
|
7246
|
+
const prefix = prefixFor(sizeAt, count);
|
|
7247
|
+
const pinnedLength = at(prefix, pinnedCount);
|
|
7248
|
+
const total = at(prefix, count) - pinnedLength;
|
|
7249
|
+
if (total <= 0) {
|
|
7250
|
+
return assemble({ pinnedCount, start: pinnedCount, end: count, padStart: 0, body: 0, total: total > 0 ? total : 0 });
|
|
7251
|
+
}
|
|
7252
|
+
const maxOffset = Math.max(0, total - viewport);
|
|
7253
|
+
const offset = Math.min(toLength(input?.offset), maxOffset);
|
|
7254
|
+
const firstVisible = lastAtOrBefore(prefix, pinnedCount, count, pinnedLength + offset) - pinnedCount;
|
|
7255
|
+
const lastVisible = firstAtOrAfter(prefix, pinnedCount, count, pinnedLength + offset + viewport) - pinnedCount;
|
|
7256
|
+
const { start: relStart, end: relEnd } = band(firstVisible, lastVisible, scrollCount, overscan);
|
|
7257
|
+
const absStart = pinnedCount + relStart;
|
|
7258
|
+
const absEnd = pinnedCount + relEnd;
|
|
7259
|
+
return assemble({
|
|
7260
|
+
pinnedCount,
|
|
7261
|
+
start: absStart,
|
|
7262
|
+
end: absEnd,
|
|
7263
|
+
padStart: at(prefix, absStart) - pinnedLength,
|
|
7264
|
+
body: at(prefix, absEnd) - at(prefix, absStart),
|
|
7265
|
+
total
|
|
7266
|
+
});
|
|
7267
|
+
}
|
|
7268
|
+
function scrollOffsetForIndex(input) {
|
|
7269
|
+
const count = toCount(input?.count);
|
|
7270
|
+
if (count <= 0) return null;
|
|
7271
|
+
const pinnedCount = toPinned(input?.pinnedStart, count);
|
|
7272
|
+
const itemSize = toLength(input?.itemSize);
|
|
7273
|
+
const viewport = toLength(input?.viewport);
|
|
7274
|
+
const scrollCount = count - pinnedCount;
|
|
7275
|
+
if (scrollCount <= 0 || itemSize <= 0) return null;
|
|
7276
|
+
const rawIndex = isNum(input?.index) ? Math.floor(input.index) : 0;
|
|
7277
|
+
const index = Math.min(Math.max(rawIndex, 0), count - 1);
|
|
7278
|
+
if (index < pinnedCount) return null;
|
|
7279
|
+
const total = scrollCount * itemSize;
|
|
7280
|
+
const maxOffset = Math.max(0, total - viewport);
|
|
7281
|
+
const offset = Math.min(toLength(input?.offset), maxOffset);
|
|
7282
|
+
const itemStart = (index - pinnedCount) * itemSize;
|
|
7283
|
+
const itemEnd = itemStart + itemSize;
|
|
7284
|
+
if (itemStart >= offset && itemEnd <= offset + viewport) return null;
|
|
7285
|
+
const next = itemStart < offset ? itemStart : itemEnd - viewport;
|
|
7286
|
+
const clamped = Math.min(Math.max(next, 0), maxOffset);
|
|
7287
|
+
return clamped === offset ? null : clamped;
|
|
7288
|
+
}
|
|
7289
|
+
|
|
7290
|
+
// src/data-table/useSpreadsheetGrid.ts
|
|
7291
|
+
var import_react15 = require("react");
|
|
7292
|
+
|
|
7293
|
+
// src/data-table/grid-selection.ts
|
|
7294
|
+
function rangeBounds(range, rowIds, fieldNames) {
|
|
7295
|
+
const ra = rowIds.indexOf(range.anchor.rowId);
|
|
7296
|
+
const rf = rowIds.indexOf(range.focus.rowId);
|
|
7297
|
+
const ca = fieldNames.indexOf(range.anchor.fieldName);
|
|
7298
|
+
const cf = fieldNames.indexOf(range.focus.fieldName);
|
|
7299
|
+
if (ra === -1 || rf === -1 || ca === -1 || cf === -1) return null;
|
|
7300
|
+
return {
|
|
7301
|
+
r0: Math.min(ra, rf),
|
|
7302
|
+
r1: Math.max(ra, rf),
|
|
7303
|
+
c0: Math.min(ca, cf),
|
|
7304
|
+
c1: Math.max(ca, cf)
|
|
7305
|
+
};
|
|
7306
|
+
}
|
|
7307
|
+
function rangeSize(bounds) {
|
|
7308
|
+
const rows = bounds.r1 - bounds.r0 + 1;
|
|
7309
|
+
const cols = bounds.c1 - bounds.c0 + 1;
|
|
7310
|
+
return { rows, cols, cells: rows * cols };
|
|
7311
|
+
}
|
|
7312
|
+
function boundsContain(bounds, rowIndex, colIndex) {
|
|
7313
|
+
return rowIndex >= bounds.r0 && rowIndex <= bounds.r1 && colIndex >= bounds.c0 && colIndex <= bounds.c1;
|
|
7314
|
+
}
|
|
7315
|
+
function cellsInRange(range, rowIds, fieldNames) {
|
|
7316
|
+
const b = rangeBounds(range, rowIds, fieldNames);
|
|
7317
|
+
if (!b) return [];
|
|
7318
|
+
const out = [];
|
|
7319
|
+
for (let r = b.r0; r <= b.r1; r += 1) {
|
|
7320
|
+
const rowId = rowIds[r];
|
|
7321
|
+
if (rowId === void 0) continue;
|
|
7322
|
+
for (let c = b.c0; c <= b.c1; c += 1) {
|
|
7323
|
+
const fieldName = fieldNames[c];
|
|
7324
|
+
if (fieldName === void 0) continue;
|
|
7325
|
+
out.push({ rowId, fieldName });
|
|
7326
|
+
}
|
|
7327
|
+
}
|
|
7328
|
+
return out;
|
|
7329
|
+
}
|
|
7330
|
+
function rangeRows(range, rowIds, fieldNames) {
|
|
7331
|
+
const b = rangeBounds(range, rowIds, fieldNames);
|
|
7332
|
+
if (!b) return [];
|
|
7333
|
+
const rows = [];
|
|
7334
|
+
for (let r = b.r0; r <= b.r1; r += 1) {
|
|
7335
|
+
const rowId = rowIds[r];
|
|
7336
|
+
if (rowId === void 0) continue;
|
|
7337
|
+
const row = [];
|
|
7338
|
+
for (let c = b.c0; c <= b.c1; c += 1) {
|
|
7339
|
+
const fieldName = fieldNames[c];
|
|
7340
|
+
if (fieldName === void 0) continue;
|
|
7341
|
+
row.push({ rowId, fieldName });
|
|
7342
|
+
}
|
|
7343
|
+
rows.push(row);
|
|
7344
|
+
}
|
|
7345
|
+
return rows;
|
|
7346
|
+
}
|
|
7347
|
+
function isSingleCellRange(range) {
|
|
7348
|
+
return sameCell(range.anchor, range.focus);
|
|
7349
|
+
}
|
|
7350
|
+
function rowRange(rowId, fieldNames) {
|
|
7351
|
+
const firstField = fieldNames[0];
|
|
7352
|
+
const lastField = fieldNames[fieldNames.length - 1];
|
|
7353
|
+
if (firstField === void 0 || lastField === void 0) return null;
|
|
7354
|
+
return {
|
|
7355
|
+
anchor: { rowId, fieldName: firstField },
|
|
7356
|
+
focus: { rowId, fieldName: lastField }
|
|
7357
|
+
};
|
|
7358
|
+
}
|
|
7359
|
+
function columnRange(fieldName, rowIds) {
|
|
7360
|
+
const firstRow = rowIds[0];
|
|
7361
|
+
const lastRow = rowIds[rowIds.length - 1];
|
|
7362
|
+
if (firstRow === void 0 || lastRow === void 0) return null;
|
|
7363
|
+
return {
|
|
7364
|
+
anchor: { rowId: firstRow, fieldName },
|
|
7365
|
+
focus: { rowId: lastRow, fieldName }
|
|
7366
|
+
};
|
|
7367
|
+
}
|
|
7368
|
+
function allRange(rowIds, fieldNames) {
|
|
7369
|
+
const firstRow = rowIds[0];
|
|
7370
|
+
const lastRow = rowIds[rowIds.length - 1];
|
|
7371
|
+
const firstField = fieldNames[0];
|
|
7372
|
+
const lastField = fieldNames[fieldNames.length - 1];
|
|
7373
|
+
if (firstRow === void 0 || lastRow === void 0 || firstField === void 0 || lastField === void 0) {
|
|
7374
|
+
return null;
|
|
7375
|
+
}
|
|
7376
|
+
return {
|
|
7377
|
+
anchor: { rowId: firstRow, fieldName: firstField },
|
|
7378
|
+
focus: { rowId: lastRow, fieldName: lastField }
|
|
7379
|
+
};
|
|
7380
|
+
}
|
|
7381
|
+
function sameCell(a, b) {
|
|
7382
|
+
if (!a || !b) return a === b;
|
|
7383
|
+
return a.rowId === b.rowId && a.fieldName === b.fieldName;
|
|
7384
|
+
}
|
|
7385
|
+
function moveSelection(current, move, rowIds, fieldNames) {
|
|
7386
|
+
if (rowIds.length === 0 || fieldNames.length === 0) return null;
|
|
7387
|
+
const firstRowId = rowIds[0];
|
|
7388
|
+
const firstFieldName = fieldNames[0];
|
|
7389
|
+
if (firstRowId === void 0 || firstFieldName === void 0) return null;
|
|
7390
|
+
const first = { rowId: firstRowId, fieldName: firstFieldName };
|
|
7391
|
+
if (!current) return first;
|
|
7392
|
+
let r = rowIds.indexOf(current.rowId);
|
|
7393
|
+
let c = fieldNames.indexOf(current.fieldName);
|
|
7394
|
+
if (r === -1 || c === -1) return first;
|
|
7395
|
+
const lastRow = rowIds.length - 1;
|
|
7396
|
+
const lastCol = fieldNames.length - 1;
|
|
7397
|
+
const clamp = (n, max) => Math.min(Math.max(n, 0), max);
|
|
7398
|
+
switch (move) {
|
|
7399
|
+
case "up":
|
|
7400
|
+
r = clamp(r - 1, lastRow);
|
|
7401
|
+
break;
|
|
7402
|
+
case "down":
|
|
7403
|
+
r = clamp(r + 1, lastRow);
|
|
7404
|
+
break;
|
|
7405
|
+
case "left":
|
|
7406
|
+
c = clamp(c - 1, lastCol);
|
|
7407
|
+
break;
|
|
7408
|
+
case "right":
|
|
7409
|
+
c = clamp(c + 1, lastCol);
|
|
7410
|
+
break;
|
|
7411
|
+
case "rowStart":
|
|
7412
|
+
c = 0;
|
|
7413
|
+
break;
|
|
7414
|
+
case "rowEnd":
|
|
7415
|
+
c = lastCol;
|
|
7416
|
+
break;
|
|
7417
|
+
case "gridStart":
|
|
7418
|
+
r = 0;
|
|
7419
|
+
c = 0;
|
|
7420
|
+
break;
|
|
7421
|
+
case "gridEnd":
|
|
7422
|
+
r = lastRow;
|
|
7423
|
+
c = lastCol;
|
|
7424
|
+
break;
|
|
7425
|
+
case "nextCell":
|
|
7426
|
+
if (c < lastCol) c += 1;
|
|
7427
|
+
else if (r < lastRow) {
|
|
7428
|
+
r += 1;
|
|
7429
|
+
c = 0;
|
|
7430
|
+
}
|
|
7431
|
+
break;
|
|
7432
|
+
case "prevCell":
|
|
7433
|
+
if (c > 0) c -= 1;
|
|
7434
|
+
else if (r > 0) {
|
|
7435
|
+
r -= 1;
|
|
7436
|
+
c = lastCol;
|
|
7437
|
+
}
|
|
7438
|
+
break;
|
|
7439
|
+
}
|
|
7440
|
+
const rowId = rowIds[r];
|
|
7441
|
+
const fieldName = fieldNames[c];
|
|
7442
|
+
if (rowId === void 0 || fieldName === void 0) return first;
|
|
7443
|
+
return { rowId, fieldName };
|
|
7444
|
+
}
|
|
7445
|
+
function isTypingKey(e) {
|
|
7446
|
+
if (e.ctrlKey || e.metaKey || e.altKey) return false;
|
|
7447
|
+
return e.key.length === 1 && e.key !== " ";
|
|
7448
|
+
}
|
|
7449
|
+
function classifyGridKey(e) {
|
|
7450
|
+
const mod = e.ctrlKey || e.metaKey;
|
|
7451
|
+
const arrowMove = {
|
|
7452
|
+
ArrowUp: mod ? "gridStart" : "up",
|
|
7453
|
+
ArrowDown: mod ? "gridEnd" : "down",
|
|
7454
|
+
ArrowLeft: mod ? "rowStart" : "left",
|
|
7455
|
+
ArrowRight: mod ? "rowEnd" : "right",
|
|
7456
|
+
Home: mod ? "gridStart" : "rowStart",
|
|
7457
|
+
End: mod ? "gridEnd" : "rowEnd"
|
|
7458
|
+
};
|
|
7459
|
+
const arrow = arrowMove[e.key];
|
|
7460
|
+
if (arrow !== void 0) {
|
|
7461
|
+
return { kind: e.shiftKey ? "extend" : "move", move: arrow };
|
|
7462
|
+
}
|
|
7463
|
+
switch (e.key) {
|
|
7464
|
+
case "Tab":
|
|
7465
|
+
return { kind: "move", move: e.shiftKey ? "prevCell" : "nextCell" };
|
|
7466
|
+
case "Enter":
|
|
7467
|
+
case "F2":
|
|
7468
|
+
return { kind: "edit" };
|
|
7469
|
+
case " ":
|
|
7470
|
+
if (e.shiftKey) return { kind: "selectRow" };
|
|
7471
|
+
if (mod) return { kind: "selectColumn" };
|
|
7472
|
+
return { kind: "edit" };
|
|
7473
|
+
case "a":
|
|
7474
|
+
case "A":
|
|
7475
|
+
if (mod) return { kind: "selectAll" };
|
|
7476
|
+
break;
|
|
7477
|
+
case "d":
|
|
7478
|
+
case "D":
|
|
7479
|
+
if (mod) return { kind: "fillDown" };
|
|
7480
|
+
break;
|
|
7481
|
+
case "Escape":
|
|
7482
|
+
return { kind: "escape" };
|
|
7483
|
+
case "Delete":
|
|
7484
|
+
case "Backspace":
|
|
7485
|
+
return { kind: "clearCell" };
|
|
7486
|
+
case "c":
|
|
7487
|
+
case "C":
|
|
7488
|
+
if (mod) return { kind: "copy" };
|
|
7489
|
+
break;
|
|
7490
|
+
case "x":
|
|
7491
|
+
case "X":
|
|
7492
|
+
if (mod) return { kind: "cut" };
|
|
7493
|
+
break;
|
|
7494
|
+
case "v":
|
|
7495
|
+
case "V":
|
|
7496
|
+
if (mod) return { kind: "paste" };
|
|
7497
|
+
break;
|
|
7498
|
+
}
|
|
7499
|
+
if (isTypingKey(e)) return { kind: "editSeeded", seed: e.key };
|
|
7500
|
+
return null;
|
|
7501
|
+
}
|
|
7502
|
+
function directClickKinds() {
|
|
7503
|
+
return ["checkbox", "rating", "select", "multiselect"];
|
|
7504
|
+
}
|
|
7505
|
+
function isDirectClickEditor(editorKind) {
|
|
7506
|
+
return editorKind !== void 0 && directClickKinds().includes(editorKind);
|
|
7507
|
+
}
|
|
7508
|
+
function cellDomKey(address) {
|
|
7509
|
+
return `${address.rowId}::${address.fieldName}`;
|
|
7510
|
+
}
|
|
7511
|
+
|
|
7512
|
+
// src/data-table/grid-clipboard.ts
|
|
7513
|
+
function cellClipboardText(value) {
|
|
7514
|
+
if (value === null || value === void 0) return "";
|
|
7515
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
7516
|
+
return String(value);
|
|
7517
|
+
}
|
|
7518
|
+
function tsvCell(text) {
|
|
7519
|
+
return /[\t\r\n"]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text;
|
|
7520
|
+
}
|
|
7521
|
+
function gridToTsv(block) {
|
|
7522
|
+
return block.map((row) => row.map((cell) => tsvCell(cellClipboardText(cell))).join(" ")).join("\n");
|
|
7523
|
+
}
|
|
7524
|
+
function parseClipboardGrid(text) {
|
|
7525
|
+
const rows = [];
|
|
7526
|
+
let row = [];
|
|
7527
|
+
let cell = "";
|
|
7528
|
+
let i = 0;
|
|
7529
|
+
const n = text.length;
|
|
7530
|
+
while (i < n) {
|
|
7531
|
+
const ch = text[i];
|
|
7532
|
+
if (cell === "" && ch === '"') {
|
|
7533
|
+
let j = i + 1;
|
|
7534
|
+
let out = "";
|
|
7535
|
+
let closed = false;
|
|
7536
|
+
while (j < n) {
|
|
7537
|
+
const c = text[j];
|
|
7538
|
+
if (c === '"') {
|
|
7539
|
+
if (text[j + 1] === '"') {
|
|
7540
|
+
out += '"';
|
|
7541
|
+
j += 2;
|
|
7542
|
+
continue;
|
|
7543
|
+
}
|
|
7544
|
+
closed = true;
|
|
7545
|
+
j += 1;
|
|
7546
|
+
break;
|
|
7547
|
+
}
|
|
7548
|
+
out += c;
|
|
7549
|
+
j += 1;
|
|
7550
|
+
}
|
|
7551
|
+
if (closed && (j >= n || text[j] === " " || text[j] === "\n" || text[j] === "\r")) {
|
|
7552
|
+
cell = out;
|
|
7553
|
+
i = j;
|
|
7554
|
+
if (i >= n) break;
|
|
7555
|
+
const d = text[i];
|
|
7556
|
+
if (d === " ") {
|
|
7557
|
+
row.push(cell);
|
|
7558
|
+
cell = "";
|
|
7559
|
+
i += 1;
|
|
7560
|
+
continue;
|
|
7561
|
+
}
|
|
7562
|
+
row.push(cell);
|
|
7563
|
+
rows.push(row);
|
|
7564
|
+
row = [];
|
|
7565
|
+
cell = "";
|
|
7566
|
+
i += d === "\r" && text[i + 1] === "\n" ? 2 : 1;
|
|
7567
|
+
continue;
|
|
7568
|
+
}
|
|
7569
|
+
cell += ch;
|
|
7570
|
+
i += 1;
|
|
7571
|
+
continue;
|
|
7572
|
+
}
|
|
7573
|
+
if (ch === " ") {
|
|
7574
|
+
row.push(cell);
|
|
7575
|
+
cell = "";
|
|
7576
|
+
i += 1;
|
|
7577
|
+
continue;
|
|
7578
|
+
}
|
|
7579
|
+
if (ch === "\n" || ch === "\r") {
|
|
7580
|
+
row.push(cell);
|
|
7581
|
+
rows.push(row);
|
|
7582
|
+
row = [];
|
|
7583
|
+
cell = "";
|
|
7584
|
+
i += ch === "\r" && text[i + 1] === "\n" ? 2 : 1;
|
|
7585
|
+
continue;
|
|
7586
|
+
}
|
|
7587
|
+
cell += ch;
|
|
7588
|
+
i += 1;
|
|
7589
|
+
}
|
|
7590
|
+
const endedOnBreak = n > 0 && (text[n - 1] === "\n" || text[n - 1] === "\r");
|
|
7591
|
+
if (!endedOnBreak) {
|
|
7592
|
+
row.push(cell);
|
|
7593
|
+
rows.push(row);
|
|
7594
|
+
} else if (row.length > 0) {
|
|
7595
|
+
row.push(cell);
|
|
7596
|
+
rows.push(row);
|
|
7597
|
+
}
|
|
7598
|
+
return rows.length === 0 ? [[""]] : rows;
|
|
7599
|
+
}
|
|
7600
|
+
function planPaste(anchor, block, rowIds, fieldNames) {
|
|
7601
|
+
const r0 = rowIds.indexOf(anchor.rowId);
|
|
7602
|
+
const c0 = fieldNames.indexOf(anchor.fieldName);
|
|
7603
|
+
if (r0 === -1 || c0 === -1) return null;
|
|
7604
|
+
const width = block.reduce((w, row) => Math.max(w, row.length), 0);
|
|
7605
|
+
const colsAvailable = fieldNames.length - c0;
|
|
7606
|
+
const colsUsed = Math.min(width, colsAvailable);
|
|
7607
|
+
const targetFields = fieldNames.slice(c0, c0 + colsUsed);
|
|
7608
|
+
const cells = [];
|
|
7609
|
+
const overflowRows = [];
|
|
7610
|
+
block.forEach((blockRow, dr) => {
|
|
7611
|
+
const rowId = rowIds[r0 + dr];
|
|
7612
|
+
if (rowId === void 0) {
|
|
7613
|
+
overflowRows.push(targetFields.map((_, dc) => blockRow[dc] ?? ""));
|
|
7614
|
+
return;
|
|
7615
|
+
}
|
|
7616
|
+
targetFields.forEach((fieldName, dc) => {
|
|
7617
|
+
if (dc >= blockRow.length) return;
|
|
7618
|
+
const raw = blockRow[dc];
|
|
7619
|
+
if (raw === void 0) return;
|
|
7620
|
+
cells.push({ rowId, fieldName, raw });
|
|
7621
|
+
});
|
|
7622
|
+
});
|
|
7623
|
+
return {
|
|
7624
|
+
cells,
|
|
7625
|
+
overflowRows,
|
|
7626
|
+
clippedColumns: Math.max(0, width - colsAvailable),
|
|
7627
|
+
fieldNames: targetFields
|
|
7628
|
+
};
|
|
7629
|
+
}
|
|
7630
|
+
function isSingleCell(block) {
|
|
7631
|
+
return block.length === 1 && block[0]?.length === 1;
|
|
7632
|
+
}
|
|
7633
|
+
function storedValuesEqual(a, b) {
|
|
7634
|
+
if (a === b) return true;
|
|
7635
|
+
if (a === null || b === null || a === void 0 || b === void 0) {
|
|
7636
|
+
return (a ?? null) === (b ?? null);
|
|
7637
|
+
}
|
|
7638
|
+
if (typeof a === "object" || typeof b === "object") {
|
|
7639
|
+
try {
|
|
7640
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
7641
|
+
} catch {
|
|
7642
|
+
return false;
|
|
7643
|
+
}
|
|
7644
|
+
}
|
|
7645
|
+
return false;
|
|
7646
|
+
}
|
|
7647
|
+
|
|
7648
|
+
// src/data-table/fill.ts
|
|
7649
|
+
var NO_SERIES = { kind: "none", step: 0 };
|
|
7650
|
+
var MS_PER_DAY = 864e5;
|
|
7651
|
+
function plural(count, one, many) {
|
|
7652
|
+
return `${count} ${count === 1 ? one : many}`;
|
|
7653
|
+
}
|
|
7654
|
+
function isValidRect(rect) {
|
|
7655
|
+
return Number.isInteger(rect.top) && Number.isInteger(rect.left) && Number.isInteger(rect.bottom) && Number.isInteger(rect.right) && rect.top <= rect.bottom && rect.left <= rect.right;
|
|
7656
|
+
}
|
|
7657
|
+
function asBounds(rect) {
|
|
7658
|
+
return { r0: rect.top, r1: rect.bottom, c0: rect.left, c1: rect.right };
|
|
7659
|
+
}
|
|
7660
|
+
function directionOf(source, target) {
|
|
7661
|
+
if (!isValidRect(source) || !isValidRect(target)) return null;
|
|
7662
|
+
if (target.top === source.bottom + 1) return "down";
|
|
7663
|
+
if (target.bottom === source.top - 1) return "up";
|
|
7664
|
+
if (target.left === source.right + 1) return "right";
|
|
7665
|
+
if (target.right === source.left - 1) return "left";
|
|
7666
|
+
return null;
|
|
7667
|
+
}
|
|
7668
|
+
function tileIndex(i, a, b) {
|
|
7669
|
+
const n = b - a + 1;
|
|
7670
|
+
if (n <= 0) return a;
|
|
7671
|
+
if (i >= a && i <= b) return i;
|
|
7672
|
+
if (i > b) return a + (i - a) % n;
|
|
7673
|
+
return b - (a - 1 - i) % n;
|
|
7674
|
+
}
|
|
7675
|
+
function isFiniteNumber(v) {
|
|
7676
|
+
return typeof v === "number" && Number.isFinite(v);
|
|
7677
|
+
}
|
|
7678
|
+
var DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
|
|
7679
|
+
var DATE_ISH = /^\d{4}-\d{2}-\d{2}([T ]|$)/;
|
|
7680
|
+
function dateMs(v) {
|
|
7681
|
+
if (v instanceof Date) {
|
|
7682
|
+
const t = v.getTime();
|
|
7683
|
+
return Number.isFinite(t) ? t : null;
|
|
7684
|
+
}
|
|
7685
|
+
if (typeof v === "string" && DATE_ISH.test(v)) {
|
|
7686
|
+
const t = Date.parse(v);
|
|
7687
|
+
return Number.isFinite(t) ? t : null;
|
|
7688
|
+
}
|
|
7689
|
+
return null;
|
|
7690
|
+
}
|
|
7691
|
+
function detectSeries(values) {
|
|
7692
|
+
if (!Array.isArray(values) || values.length < 2) return NO_SERIES;
|
|
7693
|
+
if (values.every(isFiniteNumber)) {
|
|
7694
|
+
const nums = values;
|
|
7695
|
+
const first = nums[0];
|
|
7696
|
+
const second = nums[1];
|
|
7697
|
+
if (first === void 0 || second === void 0) return NO_SERIES;
|
|
7698
|
+
const step = second - first;
|
|
7699
|
+
for (let i = 1; i < nums.length; i += 1) {
|
|
7700
|
+
const prev = nums[i - 1];
|
|
7701
|
+
const cur = nums[i];
|
|
7702
|
+
if (prev === void 0 || cur === void 0) return NO_SERIES;
|
|
7703
|
+
if (cur - prev !== step) return NO_SERIES;
|
|
7704
|
+
}
|
|
7705
|
+
return { kind: "number", step };
|
|
7706
|
+
}
|
|
7707
|
+
const stamps = values.map(dateMs);
|
|
7708
|
+
if (stamps.every((t) => t !== null)) {
|
|
7709
|
+
const first = stamps[0];
|
|
7710
|
+
const second = stamps[1];
|
|
7711
|
+
if (first === void 0 || second === void 0) return NO_SERIES;
|
|
7712
|
+
const deltaMs = second - first;
|
|
7713
|
+
if (deltaMs % MS_PER_DAY !== 0) return NO_SERIES;
|
|
7714
|
+
for (let i = 1; i < stamps.length; i += 1) {
|
|
7715
|
+
const prev = stamps[i - 1];
|
|
7716
|
+
const cur = stamps[i];
|
|
7717
|
+
if (prev === void 0 || cur === void 0) return NO_SERIES;
|
|
7718
|
+
if (cur - prev !== deltaMs) return NO_SERIES;
|
|
7719
|
+
}
|
|
7720
|
+
return { kind: "date", step: deltaMs / MS_PER_DAY };
|
|
7721
|
+
}
|
|
7722
|
+
return NO_SERIES;
|
|
7723
|
+
}
|
|
7724
|
+
function formatDateLike(ms, sample) {
|
|
7725
|
+
const iso = new Date(ms).toISOString();
|
|
7726
|
+
if (typeof sample === "string" && DATE_ONLY.test(sample)) return iso.slice(0, 10);
|
|
7727
|
+
return iso;
|
|
7728
|
+
}
|
|
7729
|
+
function extrapolate(line, series, k) {
|
|
7730
|
+
const last = line[line.length - 1];
|
|
7731
|
+
if (series.kind === "number" && isFiniteNumber(last)) {
|
|
7732
|
+
return last + k * series.step;
|
|
7733
|
+
}
|
|
7734
|
+
if (series.kind === "date") {
|
|
7735
|
+
const base = dateMs(last);
|
|
7736
|
+
if (base === null) return jsonable(last);
|
|
7737
|
+
return formatDateLike(base + k * series.step * MS_PER_DAY, last);
|
|
7738
|
+
}
|
|
7739
|
+
return jsonable(last);
|
|
7740
|
+
}
|
|
7741
|
+
function jsonable(value) {
|
|
7742
|
+
if (value instanceof Date) {
|
|
7743
|
+
const t = value.getTime();
|
|
7744
|
+
return Number.isFinite(t) ? value.toISOString() : null;
|
|
7745
|
+
}
|
|
7746
|
+
if (value === void 0) return null;
|
|
7747
|
+
return value;
|
|
7748
|
+
}
|
|
7749
|
+
function emptyResult(summary) {
|
|
7750
|
+
return { patches: [], skipped: [], summary };
|
|
7751
|
+
}
|
|
7752
|
+
function fillRange(request) {
|
|
7753
|
+
const { source, target, columnIds, rowIds } = request;
|
|
7754
|
+
const mode = request.mode ?? "series";
|
|
7755
|
+
const isWritable = request.isColumnWritable ?? (() => true);
|
|
7756
|
+
const direction = directionOf(source, target);
|
|
7757
|
+
if (!direction) {
|
|
7758
|
+
return emptyResult(
|
|
7759
|
+
"Filled 0 cells because the fill area does not touch the selection."
|
|
7760
|
+
);
|
|
7761
|
+
}
|
|
7762
|
+
if (rowIds.length === 0 || columnIds.length === 0) {
|
|
7763
|
+
return emptyResult("Filled 0 cells because the table is empty.");
|
|
7764
|
+
}
|
|
7765
|
+
const read = (r, c) => {
|
|
7766
|
+
try {
|
|
7767
|
+
return { ok: true, value: request.valueAt(r, c) };
|
|
7768
|
+
} catch {
|
|
7769
|
+
return { ok: false, value: void 0 };
|
|
7770
|
+
}
|
|
7771
|
+
};
|
|
7772
|
+
const vertical = direction === "down" || direction === "up";
|
|
7773
|
+
const forward = direction === "down" || direction === "right";
|
|
7774
|
+
const fillStart = vertical ? source.top : source.left;
|
|
7775
|
+
const fillEnd = vertical ? source.bottom : source.right;
|
|
7776
|
+
const crossStart = vertical ? source.left : source.top;
|
|
7777
|
+
const crossEnd = vertical ? source.right : source.bottom;
|
|
7778
|
+
const maxFill = (vertical ? rowIds.length : columnIds.length) - 1;
|
|
7779
|
+
const maxCross = (vertical ? columnIds.length : rowIds.length) - 1;
|
|
7780
|
+
const rawFillFrom = vertical ? target.top : target.left;
|
|
7781
|
+
const rawFillTo = vertical ? target.bottom : target.right;
|
|
7782
|
+
const rawCrossFrom = vertical ? target.left : target.top;
|
|
7783
|
+
const rawCrossTo = vertical ? target.right : target.bottom;
|
|
7784
|
+
const fillFrom = Math.max(rawFillFrom, 0);
|
|
7785
|
+
const fillTo = Math.min(rawFillTo, maxFill);
|
|
7786
|
+
const crossFrom = Math.max(rawCrossFrom, 0);
|
|
7787
|
+
const crossTo = Math.min(rawCrossTo, maxCross);
|
|
7788
|
+
const requested = Math.max(rawFillTo - rawFillFrom + 1, 0) * Math.max(rawCrossTo - rawCrossFrom + 1, 0);
|
|
7789
|
+
const inside = Math.max(fillTo - fillFrom + 1, 0) * Math.max(crossTo - crossFrom + 1, 0);
|
|
7790
|
+
const outside = Math.max(requested - inside, 0);
|
|
7791
|
+
const sourceBounds = asBounds(source);
|
|
7792
|
+
const patches = [];
|
|
7793
|
+
const skipped = [];
|
|
7794
|
+
const touchedColumns = /* @__PURE__ */ new Set();
|
|
7795
|
+
const lines = /* @__PURE__ */ new Map();
|
|
7796
|
+
const lineFor = (crossIndex) => {
|
|
7797
|
+
const srcCross = tileIndex(crossIndex, crossStart, crossEnd);
|
|
7798
|
+
const cached = lines.get(srcCross);
|
|
7799
|
+
if (cached) return cached;
|
|
7800
|
+
const values = [];
|
|
7801
|
+
const reads = [];
|
|
7802
|
+
for (let f = fillStart; f <= fillEnd; f += 1) {
|
|
7803
|
+
const r = vertical ? f : srcCross;
|
|
7804
|
+
const c = vertical ? srcCross : f;
|
|
7805
|
+
const got = read(r, c);
|
|
7806
|
+
values.push(got.value);
|
|
7807
|
+
reads.push(got.ok);
|
|
7808
|
+
}
|
|
7809
|
+
const series = mode === "series" ? detectSeries(values) : NO_SERIES;
|
|
7810
|
+
const line = { values, reads, series };
|
|
7811
|
+
lines.set(srcCross, line);
|
|
7812
|
+
return line;
|
|
7813
|
+
};
|
|
7814
|
+
for (let f = fillFrom; f <= fillTo; f += 1) {
|
|
7815
|
+
for (let x = crossFrom; x <= crossTo; x += 1) {
|
|
7816
|
+
const rowIndex = vertical ? f : x;
|
|
7817
|
+
const colIndex = vertical ? x : f;
|
|
7818
|
+
const rowId = rowIds[rowIndex];
|
|
7819
|
+
const columnId2 = columnIds[colIndex];
|
|
7820
|
+
if (rowId === void 0 || columnId2 === void 0) continue;
|
|
7821
|
+
if (boundsContain(sourceBounds, rowIndex, colIndex)) continue;
|
|
7822
|
+
if (!isWritable(columnId2)) {
|
|
7823
|
+
skipped.push({
|
|
7824
|
+
rowId,
|
|
7825
|
+
columnId: columnId2,
|
|
7826
|
+
reason: `${columnId2} cannot be filled because that column is read-only.`
|
|
7827
|
+
});
|
|
7828
|
+
continue;
|
|
7829
|
+
}
|
|
7830
|
+
const line = lineFor(x);
|
|
7831
|
+
if (line.series.kind !== "none") {
|
|
7832
|
+
const k = forward ? f - fillEnd : fillStart - f;
|
|
7833
|
+
patches.push({ rowId, columnId: columnId2, value: jsonable(extrapolate(line.values, line.series, k)) });
|
|
7834
|
+
touchedColumns.add(columnId2);
|
|
7835
|
+
continue;
|
|
7836
|
+
}
|
|
7837
|
+
const srcFill = tileIndex(f, fillStart, fillEnd);
|
|
7838
|
+
const patternIndex = srcFill - fillStart;
|
|
7839
|
+
if (line.reads[patternIndex] !== true) {
|
|
7840
|
+
skipped.push({
|
|
7841
|
+
rowId,
|
|
7842
|
+
columnId: columnId2,
|
|
7843
|
+
reason: `The value to copy into ${columnId2} could not be read, so that cell was left alone.`
|
|
7844
|
+
});
|
|
7845
|
+
continue;
|
|
7846
|
+
}
|
|
7847
|
+
patches.push({ rowId, columnId: columnId2, value: jsonable(line.values[patternIndex]) });
|
|
7848
|
+
touchedColumns.add(columnId2);
|
|
7849
|
+
}
|
|
7850
|
+
}
|
|
7851
|
+
return { patches, skipped, summary: summarize(direction, patches, skipped, touchedColumns, outside) };
|
|
7852
|
+
}
|
|
7853
|
+
function summarize(direction, patches, skipped, touchedColumns, outside) {
|
|
7854
|
+
const parts = [];
|
|
7855
|
+
if (patches.length === 0) {
|
|
7856
|
+
parts.push("Filled 0 cells because there was nothing to fill.");
|
|
7857
|
+
} else if (direction === "down" || direction === "up") {
|
|
7858
|
+
const word = direction === "down" ? "down" : "up";
|
|
7859
|
+
parts.push(
|
|
7860
|
+
`Filled ${plural(patches.length, "cell", "cells")} ${word} ${plural(touchedColumns.size, "column", "columns")}.`
|
|
7861
|
+
);
|
|
7862
|
+
} else {
|
|
7863
|
+
const word = direction === "right" ? "right" : "left";
|
|
7864
|
+
parts.push(
|
|
7865
|
+
`Filled ${plural(patches.length, "cell", "cells")} ${word} across ${plural(touchedColumns.size, "column", "columns")}.`
|
|
7866
|
+
);
|
|
7867
|
+
}
|
|
7868
|
+
if (skipped.length > 0) {
|
|
7869
|
+
parts.push(`Skipped ${plural(skipped.length, "cell", "cells")} that could not be filled.`);
|
|
7870
|
+
}
|
|
7871
|
+
if (outside > 0) {
|
|
7872
|
+
parts.push(`Ignored ${plural(outside, "cell", "cells")} outside the table.`);
|
|
7873
|
+
}
|
|
7874
|
+
return parts.join(" ");
|
|
7875
|
+
}
|
|
7876
|
+
function fillDown(request) {
|
|
7877
|
+
const { range, ...rest } = request;
|
|
7878
|
+
if (!isValidRect(range)) {
|
|
7879
|
+
return emptyResult("Filled 0 cells because the selection is not a rectangle.");
|
|
7880
|
+
}
|
|
7881
|
+
if (range.top === range.bottom) {
|
|
7882
|
+
return emptyResult("Filled 0 cells because the selection is a single row.");
|
|
7883
|
+
}
|
|
7884
|
+
return fillRange({
|
|
7885
|
+
...rest,
|
|
7886
|
+
source: { top: range.top, left: range.left, bottom: range.top, right: range.right },
|
|
7887
|
+
target: { top: range.top + 1, left: range.left, bottom: range.bottom, right: range.right }
|
|
7888
|
+
});
|
|
7889
|
+
}
|
|
7890
|
+
function fillTargetFor(source, toRow, toColumn) {
|
|
7891
|
+
if (!isValidRect(source)) return null;
|
|
7892
|
+
if (!Number.isInteger(toRow) || !Number.isInteger(toColumn)) return null;
|
|
7893
|
+
const below = toRow - source.bottom;
|
|
7894
|
+
const above = source.top - toRow;
|
|
7895
|
+
const rightOf = toColumn - source.right;
|
|
7896
|
+
const leftOf = source.left - toColumn;
|
|
7897
|
+
const vertical = Math.max(below, above, 0);
|
|
7898
|
+
const horizontal = Math.max(rightOf, leftOf, 0);
|
|
7899
|
+
if (vertical === 0 && horizontal === 0) return null;
|
|
7900
|
+
if (vertical >= horizontal) {
|
|
7901
|
+
if (below > 0) {
|
|
7902
|
+
return { top: source.bottom + 1, bottom: toRow, left: source.left, right: source.right };
|
|
7903
|
+
}
|
|
7904
|
+
return { top: toRow, bottom: source.top - 1, left: source.left, right: source.right };
|
|
7905
|
+
}
|
|
7906
|
+
if (rightOf > 0) {
|
|
7907
|
+
return { top: source.top, bottom: source.bottom, left: source.right + 1, right: toColumn };
|
|
7908
|
+
}
|
|
7909
|
+
return { top: source.top, bottom: source.bottom, left: toColumn, right: source.left - 1 };
|
|
7910
|
+
}
|
|
7911
|
+
|
|
7912
|
+
// src/data-table/cell-undo.ts
|
|
7913
|
+
var DEFAULT_UNDO_DEPTH = 100;
|
|
7914
|
+
function createUndoStack(depth = DEFAULT_UNDO_DEPTH) {
|
|
7915
|
+
const bounded = Number.isFinite(depth) && depth > 0 ? Math.floor(depth) : 0;
|
|
7916
|
+
return { past: [], future: [], depth: bounded };
|
|
7917
|
+
}
|
|
7918
|
+
function pushUndo(stack, entry) {
|
|
7919
|
+
if (stack.depth <= 0) {
|
|
7920
|
+
return { past: [], future: [], depth: stack.depth };
|
|
7921
|
+
}
|
|
7922
|
+
const past = [...stack.past, entry];
|
|
7923
|
+
while (past.length > stack.depth) past.shift();
|
|
7924
|
+
return { past, future: [], depth: stack.depth };
|
|
7925
|
+
}
|
|
7926
|
+
function popUndo(stack) {
|
|
7927
|
+
const entry = stack.past[stack.past.length - 1];
|
|
7928
|
+
if (entry === void 0) return { stack, entry: null };
|
|
7929
|
+
return {
|
|
7930
|
+
stack: {
|
|
7931
|
+
past: stack.past.slice(0, -1),
|
|
7932
|
+
future: [...stack.future, entry],
|
|
7933
|
+
depth: stack.depth
|
|
7934
|
+
},
|
|
7935
|
+
entry
|
|
7936
|
+
};
|
|
7937
|
+
}
|
|
7938
|
+
function popRedo(stack) {
|
|
7939
|
+
const entry = stack.future[stack.future.length - 1];
|
|
7940
|
+
if (entry === void 0) return { stack, entry: null };
|
|
7941
|
+
const past = [...stack.past, entry];
|
|
7942
|
+
while (past.length > stack.depth) past.shift();
|
|
7943
|
+
return {
|
|
7944
|
+
stack: { past, future: stack.future.slice(0, -1), depth: stack.depth },
|
|
7945
|
+
entry
|
|
7946
|
+
};
|
|
7947
|
+
}
|
|
7948
|
+
function keyOf(patch) {
|
|
7949
|
+
return JSON.stringify([patch.rowId, patch.columnId]);
|
|
7950
|
+
}
|
|
7951
|
+
function undoEntryFor(before, after, label) {
|
|
7952
|
+
const priors = /* @__PURE__ */ new Map();
|
|
7953
|
+
for (const patch of before) priors.set(keyOf(patch), patch);
|
|
7954
|
+
const undo = after.map((patch) => {
|
|
7955
|
+
const prior = priors.get(keyOf(patch));
|
|
7956
|
+
return {
|
|
7957
|
+
rowId: patch.rowId,
|
|
7958
|
+
columnId: patch.columnId,
|
|
7959
|
+
value: prior ? prior.value : null
|
|
7960
|
+
};
|
|
7961
|
+
});
|
|
7962
|
+
return {
|
|
7963
|
+
label,
|
|
7964
|
+
undo,
|
|
7965
|
+
redo: after.map((patch) => ({
|
|
7966
|
+
rowId: patch.rowId,
|
|
7967
|
+
columnId: patch.columnId,
|
|
7968
|
+
value: patch.value
|
|
7969
|
+
}))
|
|
7970
|
+
};
|
|
7971
|
+
}
|
|
7972
|
+
function canUndo(stack) {
|
|
7973
|
+
return stack.depth > 0 && stack.past.length > 0;
|
|
7974
|
+
}
|
|
7975
|
+
function canRedo(stack) {
|
|
7976
|
+
return stack.depth > 0 && stack.future.length > 0;
|
|
7977
|
+
}
|
|
7978
|
+
|
|
7979
|
+
// src/data-table/useSpreadsheetGrid.ts
|
|
7980
|
+
function targetsAnEditor(target) {
|
|
7981
|
+
const element = target instanceof Element ? target : null;
|
|
7982
|
+
if (!element) return false;
|
|
7983
|
+
return element.closest("input, textarea, select, [contenteditable='true']") !== null;
|
|
7984
|
+
}
|
|
7985
|
+
function useSpreadsheetGrid(options) {
|
|
7986
|
+
const [range, setRange] = (0, import_react15.useState)(null);
|
|
7987
|
+
const [fillTarget, setFillTarget] = (0, import_react15.useState)(null);
|
|
7988
|
+
const [stack, setStack] = (0, import_react15.useState)(() => createUndoStack(options?.undoDepth ?? 100));
|
|
7989
|
+
const draggingRef = (0, import_react15.useRef)(null);
|
|
7990
|
+
const optionsRef = (0, import_react15.useRef)(options);
|
|
7991
|
+
optionsRef.current = options;
|
|
7992
|
+
const rowIds = options?.rowIds ?? [];
|
|
7993
|
+
const columnIds = (0, import_react15.useMemo)(
|
|
7994
|
+
() => options ? options.columnIds.filter((id) => id !== "") : [],
|
|
7995
|
+
[options]
|
|
7996
|
+
);
|
|
7997
|
+
(0, import_react15.useEffect)(() => {
|
|
7998
|
+
if (!range) return;
|
|
7999
|
+
const rowSet = new Set(rowIds);
|
|
8000
|
+
const colSet = new Set(columnIds);
|
|
8001
|
+
const alive = rowSet.has(range.anchor.rowId) && rowSet.has(range.focus.rowId) && colSet.has(range.anchor.fieldName) && colSet.has(range.focus.fieldName);
|
|
8002
|
+
if (!alive) setRange(null);
|
|
8003
|
+
}, [range, rowIds, columnIds]);
|
|
8004
|
+
const bounds = (0, import_react15.useMemo)(
|
|
8005
|
+
() => range ? rangeBounds(range, rowIds, columnIds) : null,
|
|
8006
|
+
[range, rowIds, columnIds]
|
|
8007
|
+
);
|
|
8008
|
+
const rowIndexById = (0, import_react15.useMemo)(() => {
|
|
8009
|
+
const map = /* @__PURE__ */ new Map();
|
|
8010
|
+
for (let i = 0; i < rowIds.length; i += 1) map.set(rowIds[i], i);
|
|
8011
|
+
return map;
|
|
8012
|
+
}, [rowIds]);
|
|
8013
|
+
const columnIndexById = (0, import_react15.useMemo)(() => {
|
|
8014
|
+
const map = /* @__PURE__ */ new Map();
|
|
8015
|
+
for (let i = 0; i < columnIds.length; i += 1) map.set(columnIds[i], i);
|
|
8016
|
+
return map;
|
|
8017
|
+
}, [columnIds]);
|
|
8018
|
+
const applyPatches = (0, import_react15.useCallback)(
|
|
8019
|
+
async (patches, intent, label) => {
|
|
8020
|
+
const current = optionsRef.current;
|
|
8021
|
+
if (!current || patches.length === 0) return;
|
|
8022
|
+
const depth = current.undoDepth ?? 100;
|
|
8023
|
+
if (depth > 0 && intent !== "undo" && intent !== "redo") {
|
|
8024
|
+
const before = patches.map((patch) => ({
|
|
8025
|
+
rowId: patch.rowId,
|
|
8026
|
+
columnId: patch.columnId,
|
|
8027
|
+
value: current.valueAt(patch.rowId, patch.columnId) ?? null
|
|
8028
|
+
}));
|
|
8029
|
+
setStack((previous) => pushUndo(previous, undoEntryFor(before, patches, label)));
|
|
8030
|
+
}
|
|
8031
|
+
await current.onPatch(patches, intent);
|
|
8032
|
+
},
|
|
8033
|
+
[]
|
|
8034
|
+
);
|
|
8035
|
+
const readValueAt = (0, import_react15.useCallback)((rowIndex, columnIndex) => {
|
|
8036
|
+
const current = optionsRef.current;
|
|
8037
|
+
const rowId = current?.rowIds[rowIndex];
|
|
8038
|
+
const columnId2 = current?.columnIds[columnIndex];
|
|
8039
|
+
if (!current || rowId === void 0 || columnId2 === void 0) return null;
|
|
8040
|
+
return current.valueAt(rowId, columnId2);
|
|
8041
|
+
}, []);
|
|
8042
|
+
const fillRequestBase = (0, import_react15.useCallback)(() => {
|
|
8043
|
+
const current = optionsRef.current;
|
|
8044
|
+
if (!current) return null;
|
|
8045
|
+
return {
|
|
8046
|
+
valueAt: readValueAt,
|
|
8047
|
+
columnIds: [...current.columnIds],
|
|
8048
|
+
rowIds: [...current.rowIds],
|
|
8049
|
+
isColumnWritable: current.isColumnWritable
|
|
8050
|
+
};
|
|
8051
|
+
}, [readValueAt]);
|
|
8052
|
+
const announceSkips = (0, import_react15.useCallback)(
|
|
8053
|
+
(skipped, summary) => {
|
|
8054
|
+
const current = optionsRef.current;
|
|
8055
|
+
if (!current?.notify) return;
|
|
8056
|
+
if (skipped.length === 0) {
|
|
8057
|
+
current.notify(summary);
|
|
8058
|
+
return;
|
|
8059
|
+
}
|
|
8060
|
+
const first = skipped[0];
|
|
8061
|
+
const reason = current.columnRefusal?.(first.columnId) ?? first.reason;
|
|
8062
|
+
const rest = skipped.length > 1 ? ` ${skipped.length - 1} more were left alone.` : "";
|
|
8063
|
+
current.notify(`${summary} ${reason}${rest}`);
|
|
8064
|
+
},
|
|
8065
|
+
[]
|
|
8066
|
+
);
|
|
8067
|
+
const doFillDown = (0, import_react15.useCallback)(async () => {
|
|
8068
|
+
const base = fillRequestBase();
|
|
8069
|
+
if (!base || !bounds) return;
|
|
8070
|
+
const result = fillDown({
|
|
8071
|
+
...base,
|
|
8072
|
+
range: { top: bounds.r0, left: bounds.c0, bottom: bounds.r1, right: bounds.c1 }
|
|
8073
|
+
});
|
|
8074
|
+
await applyPatches(result.patches, "fill-down", "Filled down");
|
|
8075
|
+
announceSkips(result.skipped, result.summary);
|
|
8076
|
+
}, [fillRequestBase, bounds, applyPatches, announceSkips]);
|
|
8077
|
+
const doClear = (0, import_react15.useCallback)(async () => {
|
|
8078
|
+
const current = optionsRef.current;
|
|
8079
|
+
if (!current || !bounds) return;
|
|
8080
|
+
const patches = [];
|
|
8081
|
+
const skipped = [];
|
|
8082
|
+
for (let r = bounds.r0; r <= bounds.r1; r += 1) {
|
|
8083
|
+
for (let c = bounds.c0; c <= bounds.c1; c += 1) {
|
|
8084
|
+
const rowId = current.rowIds[r];
|
|
8085
|
+
const columnId2 = current.columnIds[c];
|
|
8086
|
+
if (rowId === void 0 || columnId2 === void 0) continue;
|
|
8087
|
+
if (!current.isColumnWritable(columnId2)) {
|
|
8088
|
+
skipped.push({
|
|
8089
|
+
columnId: columnId2,
|
|
8090
|
+
reason: current.columnRefusal?.(columnId2) ?? `${columnId2} cannot be cleared.`
|
|
8091
|
+
});
|
|
8092
|
+
continue;
|
|
8093
|
+
}
|
|
8094
|
+
patches.push({ rowId, columnId: columnId2, value: null });
|
|
8095
|
+
}
|
|
8096
|
+
}
|
|
8097
|
+
await applyPatches(patches, "clear", "Cleared");
|
|
8098
|
+
announceSkips(skipped, `Cleared ${patches.length} cells.`);
|
|
8099
|
+
}, [bounds, applyPatches, announceSkips]);
|
|
8100
|
+
const doUndo = (0, import_react15.useCallback)(async () => {
|
|
8101
|
+
const taken = popUndo(stack);
|
|
8102
|
+
if (!taken.entry) return;
|
|
8103
|
+
setStack(taken.stack);
|
|
8104
|
+
await applyPatches(taken.entry.undo, "undo", taken.entry.label);
|
|
8105
|
+
optionsRef.current?.notify?.(taken.entry.label);
|
|
8106
|
+
}, [stack, applyPatches]);
|
|
8107
|
+
const doRedo = (0, import_react15.useCallback)(async () => {
|
|
8108
|
+
const taken = popRedo(stack);
|
|
8109
|
+
if (!taken.entry) return;
|
|
8110
|
+
setStack(taken.stack);
|
|
8111
|
+
await applyPatches(taken.entry.redo, "redo", taken.entry.label);
|
|
8112
|
+
}, [stack, applyPatches]);
|
|
8113
|
+
const move = (0, import_react15.useCallback)(
|
|
8114
|
+
(direction, extend) => {
|
|
8115
|
+
setRange((previous) => {
|
|
8116
|
+
const from = previous ? previous.focus : null;
|
|
8117
|
+
const next = moveSelection(from, direction, rowIds, columnIds);
|
|
8118
|
+
if (!next) return previous;
|
|
8119
|
+
if (extend && previous) return { anchor: previous.anchor, focus: next };
|
|
8120
|
+
return { anchor: next, focus: next };
|
|
8121
|
+
});
|
|
8122
|
+
},
|
|
8123
|
+
[rowIds, columnIds]
|
|
8124
|
+
);
|
|
8125
|
+
const onKeyDown = (0, import_react15.useCallback)(
|
|
8126
|
+
(event) => {
|
|
8127
|
+
const current = optionsRef.current;
|
|
8128
|
+
if (!current) return;
|
|
8129
|
+
if (targetsAnEditor(event.target)) return;
|
|
8130
|
+
const accel = event.metaKey || event.ctrlKey;
|
|
8131
|
+
if (accel && (event.key === "z" || event.key === "Z")) {
|
|
8132
|
+
event.preventDefault();
|
|
8133
|
+
if (event.shiftKey) void doRedo();
|
|
8134
|
+
else void doUndo();
|
|
8135
|
+
return;
|
|
8136
|
+
}
|
|
8137
|
+
if (accel && (event.key === "y" || event.key === "Y")) {
|
|
8138
|
+
event.preventDefault();
|
|
8139
|
+
void doRedo();
|
|
8140
|
+
return;
|
|
8141
|
+
}
|
|
8142
|
+
const action = classifyGridKey(event);
|
|
8143
|
+
if (!action) return;
|
|
8144
|
+
switch (action.kind) {
|
|
8145
|
+
case "move":
|
|
8146
|
+
event.preventDefault();
|
|
8147
|
+
move(action.move, false);
|
|
8148
|
+
return;
|
|
8149
|
+
case "extend":
|
|
8150
|
+
event.preventDefault();
|
|
8151
|
+
move(action.move, true);
|
|
8152
|
+
return;
|
|
8153
|
+
case "selectAll": {
|
|
8154
|
+
event.preventDefault();
|
|
8155
|
+
const all = allRange(rowIds, columnIds);
|
|
8156
|
+
if (all) setRange(all);
|
|
8157
|
+
return;
|
|
8158
|
+
}
|
|
8159
|
+
case "selectRow": {
|
|
8160
|
+
event.preventDefault();
|
|
8161
|
+
const focused = range?.focus;
|
|
8162
|
+
const next = focused ? rowRange(focused.rowId, columnIds) : null;
|
|
8163
|
+
if (next) setRange(next);
|
|
8164
|
+
return;
|
|
8165
|
+
}
|
|
8166
|
+
case "selectColumn": {
|
|
8167
|
+
event.preventDefault();
|
|
8168
|
+
const focused = range?.focus;
|
|
8169
|
+
const next = focused ? columnRange(focused.fieldName, rowIds) : null;
|
|
8170
|
+
if (next) setRange(next);
|
|
8171
|
+
return;
|
|
8172
|
+
}
|
|
8173
|
+
case "clearCell":
|
|
8174
|
+
event.preventDefault();
|
|
8175
|
+
void doClear();
|
|
8176
|
+
return;
|
|
8177
|
+
case "fillDown":
|
|
8178
|
+
event.preventDefault();
|
|
8179
|
+
void doFillDown();
|
|
8180
|
+
return;
|
|
8181
|
+
case "escape":
|
|
8182
|
+
setRange(null);
|
|
8183
|
+
return;
|
|
8184
|
+
default:
|
|
8185
|
+
return;
|
|
8186
|
+
}
|
|
8187
|
+
},
|
|
8188
|
+
[move, range, rowIds, columnIds, doClear, doFillDown, doUndo, doRedo]
|
|
8189
|
+
);
|
|
8190
|
+
const selectionAsTsv = (0, import_react15.useCallback)(() => {
|
|
8191
|
+
const current = optionsRef.current;
|
|
8192
|
+
if (!current || !range) return "";
|
|
8193
|
+
const grid = rangeRows(range, rowIds, columnIds).map(
|
|
8194
|
+
(row) => row.map((address) => current.valueAt(address.rowId, address.fieldName))
|
|
8195
|
+
);
|
|
8196
|
+
return gridToTsv(grid);
|
|
8197
|
+
}, [range, rowIds, columnIds]);
|
|
8198
|
+
const onCopy = (0, import_react15.useCallback)(
|
|
8199
|
+
(event) => {
|
|
8200
|
+
if (!optionsRef.current || !range || targetsAnEditor(event.target)) return;
|
|
8201
|
+
const text = selectionAsTsv();
|
|
8202
|
+
if (!text) return;
|
|
8203
|
+
event.preventDefault();
|
|
8204
|
+
event.clipboardData?.setData("text/plain", text);
|
|
8205
|
+
},
|
|
8206
|
+
[range, selectionAsTsv]
|
|
8207
|
+
);
|
|
8208
|
+
const onCut = (0, import_react15.useCallback)(
|
|
8209
|
+
(event) => {
|
|
8210
|
+
if (!optionsRef.current || !range || targetsAnEditor(event.target)) return;
|
|
8211
|
+
const text = selectionAsTsv();
|
|
8212
|
+
if (!text) return;
|
|
8213
|
+
event.preventDefault();
|
|
8214
|
+
event.clipboardData?.setData("text/plain", text);
|
|
8215
|
+
void doClear();
|
|
8216
|
+
},
|
|
8217
|
+
[range, selectionAsTsv, doClear]
|
|
8218
|
+
);
|
|
8219
|
+
const onPaste = (0, import_react15.useCallback)(
|
|
8220
|
+
(event) => {
|
|
8221
|
+
const current = optionsRef.current;
|
|
8222
|
+
if (!current || current.paste === false || !range || targetsAnEditor(event.target)) return;
|
|
8223
|
+
const text = event.clipboardData?.getData("text/plain") ?? "";
|
|
8224
|
+
if (!text) return;
|
|
8225
|
+
event.preventDefault();
|
|
8226
|
+
const block = parseClipboardGrid(text);
|
|
8227
|
+
const start = range.focus;
|
|
8228
|
+
const startRow = rowIds.indexOf(start.rowId);
|
|
8229
|
+
const startCol = columnIds.indexOf(start.fieldName);
|
|
8230
|
+
if (startRow === -1 || startCol === -1) return;
|
|
8231
|
+
const patches = [];
|
|
8232
|
+
const skipped = [];
|
|
8233
|
+
let outside = 0;
|
|
8234
|
+
for (let r = 0; r < block.length; r += 1) {
|
|
8235
|
+
const line = block[r] ?? [];
|
|
8236
|
+
for (let c = 0; c < line.length; c += 1) {
|
|
8237
|
+
const rowId = rowIds[startRow + r];
|
|
8238
|
+
const columnId2 = columnIds[startCol + c];
|
|
8239
|
+
if (rowId === void 0 || columnId2 === void 0) {
|
|
8240
|
+
outside += 1;
|
|
8241
|
+
continue;
|
|
8242
|
+
}
|
|
8243
|
+
if (!current.isColumnWritable(columnId2)) {
|
|
8244
|
+
skipped.push({
|
|
8245
|
+
columnId: columnId2,
|
|
8246
|
+
reason: current.columnRefusal?.(columnId2) ?? `${columnId2} cannot take a pasted value.`
|
|
8247
|
+
});
|
|
8248
|
+
continue;
|
|
8249
|
+
}
|
|
8250
|
+
patches.push({ rowId, columnId: columnId2, value: line[c] ?? null });
|
|
8251
|
+
}
|
|
8252
|
+
}
|
|
8253
|
+
void applyPatches(patches, "paste", "Pasted");
|
|
8254
|
+
const tail = outside > 0 ? ` ${outside} landed past the edge of the table and were ignored.` : "";
|
|
8255
|
+
announceSkips(skipped, `Pasted ${patches.length} cells.${tail}`);
|
|
8256
|
+
},
|
|
8257
|
+
[range, rowIds, columnIds, applyPatches, announceSkips]
|
|
8258
|
+
);
|
|
8259
|
+
const cellProps = (0, import_react15.useCallback)(
|
|
8260
|
+
(rowId, columnId2) => {
|
|
8261
|
+
const address = { rowId, fieldName: columnId2 };
|
|
8262
|
+
const rowIndex = rowIndexById.get(rowId) ?? -1;
|
|
8263
|
+
const colIndex = columnIndexById.get(columnId2) ?? -1;
|
|
8264
|
+
const selected = bounds !== null && rowIndex >= bounds.r0 && rowIndex <= bounds.r1 && colIndex >= bounds.c0 && colIndex <= bounds.c1;
|
|
8265
|
+
const active = range !== null && sameCell(range.focus, address);
|
|
8266
|
+
const inFillPreview = fillTarget !== null && rowIndex >= fillTarget.top && rowIndex <= fillTarget.bottom && colIndex >= fillTarget.left && colIndex <= fillTarget.right;
|
|
8267
|
+
return {
|
|
8268
|
+
"data-matrx-cell-row": rowId,
|
|
8269
|
+
"data-matrx-cell-col": columnId2,
|
|
8270
|
+
...selected ? { "data-matrx-cell-selected": "true" } : {},
|
|
8271
|
+
...active ? { "data-matrx-cell-active": "true" } : {},
|
|
8272
|
+
...inFillPreview ? { "data-matrx-cell-fill-preview": "true" } : {},
|
|
8273
|
+
onMouseDown: (event) => {
|
|
8274
|
+
if (event.button !== 0) return;
|
|
8275
|
+
event.preventDefault();
|
|
8276
|
+
setRange(
|
|
8277
|
+
(previous) => event.shiftKey && previous ? { anchor: previous.anchor, focus: address } : { anchor: address, focus: address }
|
|
8278
|
+
);
|
|
8279
|
+
draggingRef.current = "select";
|
|
8280
|
+
},
|
|
8281
|
+
onMouseEnter: () => {
|
|
8282
|
+
if (draggingRef.current === "select") {
|
|
8283
|
+
setRange((previous) => previous ? { anchor: previous.anchor, focus: address } : previous);
|
|
8284
|
+
return;
|
|
8285
|
+
}
|
|
8286
|
+
if (draggingRef.current === "fill" && bounds) {
|
|
8287
|
+
setFillTarget(
|
|
8288
|
+
fillTargetFor(
|
|
8289
|
+
{ top: bounds.r0, left: bounds.c0, bottom: bounds.r1, right: bounds.c1 },
|
|
8290
|
+
rowIndex,
|
|
8291
|
+
colIndex
|
|
8292
|
+
)
|
|
8293
|
+
);
|
|
8294
|
+
}
|
|
8295
|
+
}
|
|
8296
|
+
};
|
|
8297
|
+
},
|
|
8298
|
+
[rowIndexById, columnIndexById, bounds, range, fillTarget]
|
|
8299
|
+
);
|
|
8300
|
+
const isFillHandleCell = (0, import_react15.useCallback)(
|
|
8301
|
+
(rowId, columnId2) => {
|
|
8302
|
+
const current = optionsRef.current;
|
|
8303
|
+
if (!current || current.fillHandle === false || !bounds) return false;
|
|
8304
|
+
return rowIds[bounds.r1] === rowId && columnIds[bounds.c1] === columnId2;
|
|
8305
|
+
},
|
|
8306
|
+
[bounds, rowIds, columnIds]
|
|
8307
|
+
);
|
|
8308
|
+
const startFillDrag = (0, import_react15.useCallback)(
|
|
8309
|
+
(event) => {
|
|
8310
|
+
event.preventDefault();
|
|
8311
|
+
event.stopPropagation();
|
|
8312
|
+
draggingRef.current = "fill";
|
|
8313
|
+
},
|
|
8314
|
+
[]
|
|
8315
|
+
);
|
|
8316
|
+
const fillTargetRef = (0, import_react15.useRef)(null);
|
|
8317
|
+
fillTargetRef.current = fillTarget;
|
|
8318
|
+
const boundsRef = (0, import_react15.useRef)(null);
|
|
8319
|
+
boundsRef.current = bounds;
|
|
8320
|
+
(0, import_react15.useEffect)(() => {
|
|
8321
|
+
if (!options) return;
|
|
8322
|
+
const commit = () => {
|
|
8323
|
+
const wasDragging = draggingRef.current;
|
|
8324
|
+
draggingRef.current = null;
|
|
8325
|
+
if (wasDragging !== "fill") return;
|
|
8326
|
+
const target = fillTargetRef.current;
|
|
8327
|
+
const source = boundsRef.current;
|
|
8328
|
+
setFillTarget(null);
|
|
8329
|
+
if (!target || !source) return;
|
|
8330
|
+
const base = fillRequestBase();
|
|
8331
|
+
if (!base) return;
|
|
8332
|
+
const result = fillRange({
|
|
8333
|
+
...base,
|
|
8334
|
+
source: { top: source.r0, left: source.c0, bottom: source.r1, right: source.c1 },
|
|
8335
|
+
target
|
|
8336
|
+
});
|
|
8337
|
+
void applyPatches(result.patches, "fill", "Filled");
|
|
8338
|
+
announceSkips(result.skipped, result.summary);
|
|
8339
|
+
};
|
|
8340
|
+
window.addEventListener("mouseup", commit);
|
|
8341
|
+
return () => window.removeEventListener("mouseup", commit);
|
|
8342
|
+
}, [options, fillRequestBase, applyPatches, announceSkips]);
|
|
8343
|
+
return {
|
|
8344
|
+
range,
|
|
8345
|
+
bounds,
|
|
8346
|
+
enabled: options !== null,
|
|
8347
|
+
containerProps: {
|
|
8348
|
+
tabIndex: options ? 0 : -1,
|
|
8349
|
+
onKeyDown,
|
|
8350
|
+
onCopy,
|
|
8351
|
+
onCut,
|
|
8352
|
+
onPaste
|
|
8353
|
+
},
|
|
8354
|
+
cellProps,
|
|
8355
|
+
isFillHandleCell,
|
|
8356
|
+
startFillDrag,
|
|
8357
|
+
canUndo: stack.past.length > 0,
|
|
8358
|
+
canRedo: stack.future.length > 0
|
|
8359
|
+
};
|
|
8360
|
+
}
|
|
8361
|
+
|
|
8362
|
+
// src/data-table/coverage.ts
|
|
8363
|
+
var PARTIAL_BADGE = "Partial";
|
|
8364
|
+
var UNKNOWN_TOTAL_BADGE = "Unknown total";
|
|
8365
|
+
var NUMBERS = new Intl.NumberFormat("en-US");
|
|
8366
|
+
function formatNumber(value) {
|
|
8367
|
+
try {
|
|
8368
|
+
return NUMBERS.format(value);
|
|
8369
|
+
} catch {
|
|
8370
|
+
return String(value);
|
|
8371
|
+
}
|
|
8372
|
+
}
|
|
8373
|
+
function pluralize(noun) {
|
|
8374
|
+
const word = noun.trim();
|
|
8375
|
+
if (!word) return "rows";
|
|
8376
|
+
const lower = word.toLowerCase();
|
|
8377
|
+
if (/[^aeiou]y$/.test(lower)) return `${word.slice(0, -1)}ies`;
|
|
8378
|
+
if (/(s|x|z|ch|sh)$/.test(lower)) return `${word}es`;
|
|
8379
|
+
return `${word}s`;
|
|
8380
|
+
}
|
|
8381
|
+
function quantity(value, noun) {
|
|
8382
|
+
return `${formatNumber(value)} ${value === 1 ? noun.trim() || "row" : pluralize(noun)}`;
|
|
8383
|
+
}
|
|
8384
|
+
function toWhole(value) {
|
|
8385
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
|
|
8386
|
+
}
|
|
8387
|
+
function toOptionalWhole(value) {
|
|
8388
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return void 0;
|
|
8389
|
+
return Math.floor(value);
|
|
8390
|
+
}
|
|
8391
|
+
function describeCoverage(input) {
|
|
8392
|
+
const safe = input && typeof input === "object" ? input : { loaded: 0, answeredBy: "client" };
|
|
8393
|
+
const loaded = toWhole(safe.loaded);
|
|
8394
|
+
const matched = toOptionalWhole(safe.matched);
|
|
8395
|
+
const total = toOptionalWhole(safe.total);
|
|
8396
|
+
const cap = toOptionalWhole(safe.cap);
|
|
8397
|
+
const answeredBy = safe.answeredBy === "source" ? "source" : "client";
|
|
8398
|
+
const noun = typeof safe.noun === "string" && safe.noun.trim() ? safe.noun.trim() : "row";
|
|
8399
|
+
const reference = matched ?? total;
|
|
8400
|
+
const capReached = cap !== void 0 && cap > 0 && loaded >= cap;
|
|
8401
|
+
if (reference !== void 0 && loaded >= reference) {
|
|
8402
|
+
return {
|
|
8403
|
+
scope: "all",
|
|
8404
|
+
complete: true,
|
|
8405
|
+
count: { value: matched ?? reference, exact: true },
|
|
8406
|
+
notice: "",
|
|
8407
|
+
badge: ""
|
|
8408
|
+
};
|
|
8409
|
+
}
|
|
8410
|
+
if (answeredBy === "source" && matched !== void 0 && !capReached) {
|
|
8411
|
+
return { scope: "all", complete: true, count: { value: matched, exact: true }, notice: "", badge: "" };
|
|
8412
|
+
}
|
|
8413
|
+
if (capReached && cap !== void 0) {
|
|
8414
|
+
const rest = reference !== void 0 ? `${quantity(reference, noun)} in this table; the rest were not looked at.` : "Anything past that was not looked at.";
|
|
8415
|
+
return {
|
|
8416
|
+
scope: "capped",
|
|
8417
|
+
complete: false,
|
|
8418
|
+
count: { value: loaded, exact: false },
|
|
8419
|
+
notice: `This filter searched the first ${quantity(cap, noun)} only. ${rest}`,
|
|
8420
|
+
badge: PARTIAL_BADGE
|
|
8421
|
+
};
|
|
8422
|
+
}
|
|
8423
|
+
if (answeredBy === "client" && reference !== void 0) {
|
|
8424
|
+
return {
|
|
8425
|
+
scope: "loaded",
|
|
8426
|
+
complete: false,
|
|
8427
|
+
count: { value: loaded, exact: false },
|
|
8428
|
+
notice: `Filtering the ${quantity(loaded, noun)} loaded so far, not all ${quantity(reference, noun)} in this table.`,
|
|
8429
|
+
badge: PARTIAL_BADGE
|
|
8430
|
+
};
|
|
8431
|
+
}
|
|
8432
|
+
if (answeredBy === "source" && total !== void 0) {
|
|
8433
|
+
return {
|
|
8434
|
+
scope: "all",
|
|
8435
|
+
complete: false,
|
|
8436
|
+
count: { value: loaded, exact: false },
|
|
8437
|
+
notice: `Showing the ${quantity(loaded, noun)} loaded so far out of ${quantity(total, noun)} in this table.`,
|
|
8438
|
+
badge: PARTIAL_BADGE
|
|
8439
|
+
};
|
|
8440
|
+
}
|
|
8441
|
+
return {
|
|
8442
|
+
scope: answeredBy === "source" ? "all" : "loaded",
|
|
8443
|
+
complete: false,
|
|
8444
|
+
count: { value: loaded, exact: false },
|
|
8445
|
+
notice: `Showing the ${quantity(loaded, noun)} loaded so far. The total number of ${pluralize(noun)} in this table is not known.`,
|
|
8446
|
+
badge: UNKNOWN_TOTAL_BADGE
|
|
8447
|
+
};
|
|
8448
|
+
}
|
|
8449
|
+
|
|
6793
8450
|
// src/data-table/ranked-search.ts
|
|
6794
8451
|
function inferTableSearchRole(field) {
|
|
6795
8452
|
const key = field.replace(/([a-z])([A-Z])/g, "$1_$2").toLowerCase().replace(/[\s-]+/g, "_");
|
|
@@ -6850,7 +8507,7 @@ function rankTableSearchRows(rows, columns, query, options = {}, extraText) {
|
|
|
6850
8507
|
}
|
|
6851
8508
|
|
|
6852
8509
|
// src/data-table/ColumnManager.tsx
|
|
6853
|
-
var
|
|
8510
|
+
var import_react16 = require("react");
|
|
6854
8511
|
var import_core2 = require("@dnd-kit/core");
|
|
6855
8512
|
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
6856
8513
|
function ColumnManager({
|
|
@@ -6861,15 +8518,15 @@ function ColumnManager({
|
|
|
6861
8518
|
hidden,
|
|
6862
8519
|
onApply
|
|
6863
8520
|
}) {
|
|
6864
|
-
const byId = (0,
|
|
8521
|
+
const byId = (0, import_react16.useMemo)(
|
|
6865
8522
|
() => new Map(columns.map((column) => [columnId(column), column])),
|
|
6866
8523
|
[columns]
|
|
6867
8524
|
);
|
|
6868
|
-
const [draftOrder, setDraftOrder] = (0,
|
|
6869
|
-
const [draftHidden, setDraftHidden] = (0,
|
|
6870
|
-
const [draggedColumnId, setDraggedColumnId] = (0,
|
|
6871
|
-
const [dropTarget, setDropTarget] = (0,
|
|
6872
|
-
(0,
|
|
8525
|
+
const [draftOrder, setDraftOrder] = (0, import_react16.useState)(order);
|
|
8526
|
+
const [draftHidden, setDraftHidden] = (0, import_react16.useState)(() => new Set(hidden));
|
|
8527
|
+
const [draggedColumnId, setDraggedColumnId] = (0, import_react16.useState)(null);
|
|
8528
|
+
const [dropTarget, setDropTarget] = (0, import_react16.useState)(null);
|
|
8529
|
+
(0, import_react16.useEffect)(() => {
|
|
6873
8530
|
if (!open) return;
|
|
6874
8531
|
setDraftOrder(order);
|
|
6875
8532
|
setDraftHidden(new Set(hidden));
|
|
@@ -7399,7 +9056,7 @@ function parseTableViewSnapshot(raw) {
|
|
|
7399
9056
|
}
|
|
7400
9057
|
|
|
7401
9058
|
// src/data-table/MatrxUuidCell.tsx
|
|
7402
|
-
var
|
|
9059
|
+
var import_react17 = require("react");
|
|
7403
9060
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
7404
9061
|
var SHORT_LEN = 8;
|
|
7405
9062
|
function shortUuid(id, len = SHORT_LEN) {
|
|
@@ -7439,11 +9096,11 @@ function MatrxUuidCell({
|
|
|
7439
9096
|
}) {
|
|
7440
9097
|
const { resolveEntityDoors, ResourcePeek } = useMatrxDataTableHost();
|
|
7441
9098
|
const { notify, notice } = useTableNotice();
|
|
7442
|
-
const [copied, setCopied] = (0,
|
|
7443
|
-
const [opening, setOpening] = (0,
|
|
7444
|
-
const [peekOpen, setPeekOpen] = (0,
|
|
7445
|
-
const timer = (0,
|
|
7446
|
-
(0,
|
|
9099
|
+
const [copied, setCopied] = (0, import_react17.useState)(false);
|
|
9100
|
+
const [opening, setOpening] = (0, import_react17.useState)(false);
|
|
9101
|
+
const [peekOpen, setPeekOpen] = (0, import_react17.useState)(false);
|
|
9102
|
+
const timer = (0, import_react17.useRef)(null);
|
|
9103
|
+
(0, import_react17.useEffect)(
|
|
7447
9104
|
() => () => {
|
|
7448
9105
|
if (timer.current) clearTimeout(timer.current);
|
|
7449
9106
|
},
|
|
@@ -7738,7 +9395,7 @@ function DataRowInspector({
|
|
|
7738
9395
|
}
|
|
7739
9396
|
|
|
7740
9397
|
// src/data-table/DataRowWindow.tsx
|
|
7741
|
-
var
|
|
9398
|
+
var import_react18 = require("react");
|
|
7742
9399
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
7743
9400
|
function DataRowWindow({
|
|
7744
9401
|
isOpen,
|
|
@@ -7759,8 +9416,8 @@ function DataRowWindow({
|
|
|
7759
9416
|
const hasEdit = editContent != null;
|
|
7760
9417
|
const hasTabs = hasEdit && children == null;
|
|
7761
9418
|
const initialTab = defaultTab ?? (hasEdit ? "edit" : "view");
|
|
7762
|
-
const [tab, setTab] = (0,
|
|
7763
|
-
(0,
|
|
9419
|
+
const [tab, setTab] = (0, import_react18.useState)(initialTab);
|
|
9420
|
+
(0, import_react18.useEffect)(() => {
|
|
7764
9421
|
if (!isOpen) return;
|
|
7765
9422
|
setTab(defaultTab ?? (hasEdit ? "edit" : "view"));
|
|
7766
9423
|
}, [isOpen, windowId, hasEdit, defaultTab]);
|
|
@@ -8639,7 +10296,7 @@ function DirtySavePill({
|
|
|
8639
10296
|
}
|
|
8640
10297
|
|
|
8641
10298
|
// src/data-table/EditableTableCell.tsx
|
|
8642
|
-
var
|
|
10299
|
+
var import_react19 = require("react");
|
|
8643
10300
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
8644
10301
|
function CellEditShell({
|
|
8645
10302
|
href,
|
|
@@ -8689,8 +10346,8 @@ function EditableTableCell({
|
|
|
8689
10346
|
editTrigger = "click",
|
|
8690
10347
|
editRequest
|
|
8691
10348
|
}) {
|
|
8692
|
-
const [open, setOpen] = (0,
|
|
8693
|
-
(0,
|
|
10349
|
+
const [open, setOpen] = (0, import_react19.useState)(false);
|
|
10350
|
+
(0, import_react19.useEffect)(() => {
|
|
8694
10351
|
if (editRequest !== void 0) setOpen(true);
|
|
8695
10352
|
}, [editRequest]);
|
|
8696
10353
|
const usePencil = Boolean(href) || editTrigger === "pencil";
|
|
@@ -8783,10 +10440,10 @@ function InlineStringEditor({
|
|
|
8783
10440
|
usePencil,
|
|
8784
10441
|
editRequest
|
|
8785
10442
|
}) {
|
|
8786
|
-
const [editing, setEditing] = (0,
|
|
8787
|
-
const [draft, setDraft] = (0,
|
|
8788
|
-
const handledEditRequest = (0,
|
|
8789
|
-
(0,
|
|
10443
|
+
const [editing, setEditing] = (0, import_react19.useState)(false);
|
|
10444
|
+
const [draft, setDraft] = (0, import_react19.useState)(value);
|
|
10445
|
+
const handledEditRequest = (0, import_react19.useRef)(void 0);
|
|
10446
|
+
(0, import_react19.useEffect)(() => {
|
|
8790
10447
|
if (editRequest === void 0 || handledEditRequest.current === editRequest) return;
|
|
8791
10448
|
handledEditRequest.current = editRequest;
|
|
8792
10449
|
setDraft(value);
|
|
@@ -8942,8 +10599,8 @@ function TagsEditor({
|
|
|
8942
10599
|
onCommit,
|
|
8943
10600
|
onCancel
|
|
8944
10601
|
}) {
|
|
8945
|
-
const [tags, setTags] = (0,
|
|
8946
|
-
const [draft, setDraft] = (0,
|
|
10602
|
+
const [tags, setTags] = (0, import_react19.useState)(value);
|
|
10603
|
+
const [draft, setDraft] = (0, import_react19.useState)("");
|
|
8947
10604
|
const add = (raw) => {
|
|
8948
10605
|
const next = raw.trim();
|
|
8949
10606
|
if (!next || tags.includes(next)) return;
|
|
@@ -9040,7 +10697,7 @@ function NumberEditor({
|
|
|
9040
10697
|
onCommit,
|
|
9041
10698
|
onCancel
|
|
9042
10699
|
}) {
|
|
9043
|
-
const [draft, setDraft] = (0,
|
|
10700
|
+
const [draft, setDraft] = (0, import_react19.useState)(String(value));
|
|
9044
10701
|
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
9045
10702
|
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
9046
10703
|
Input,
|
|
@@ -9170,7 +10827,7 @@ function resetToolbarFacets(facets) {
|
|
|
9170
10827
|
}
|
|
9171
10828
|
|
|
9172
10829
|
// src/data-table/LayeredFilterBuilder.tsx
|
|
9173
|
-
var
|
|
10830
|
+
var import_react20 = require("react");
|
|
9174
10831
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
9175
10832
|
function moveRule(rules, from, to) {
|
|
9176
10833
|
if (from === to || to < 0 || to >= rules.length) return [...rules];
|
|
@@ -9187,8 +10844,8 @@ function LayeredFilterBuilder({
|
|
|
9187
10844
|
maxRules = 20,
|
|
9188
10845
|
label = "Advanced filters"
|
|
9189
10846
|
}) {
|
|
9190
|
-
const [open, setOpen] = (0,
|
|
9191
|
-
const [draggedIndex, setDraggedIndex] = (0,
|
|
10847
|
+
const [open, setOpen] = (0, import_react20.useState)(false);
|
|
10848
|
+
const [draggedIndex, setDraggedIndex] = (0, import_react20.useState)(null);
|
|
9192
10849
|
if (fields.length === 0) return null;
|
|
9193
10850
|
const updateRule = (index, patch) => {
|
|
9194
10851
|
onChange(
|
|
@@ -9669,7 +11326,7 @@ function TableToolbarAction({
|
|
|
9669
11326
|
"aria-busy": busy || void 0,
|
|
9670
11327
|
disabled,
|
|
9671
11328
|
onClick,
|
|
9672
|
-
children: (0,
|
|
11329
|
+
children: (0, import_react21.isValidElement)(children) ? (0, import_react21.cloneElement)(children, { className: cn("h-5 w-5", children.props.className) }) : children
|
|
9673
11330
|
}
|
|
9674
11331
|
) }) }),
|
|
9675
11332
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(TooltipContent, { children: tooltip ?? ariaLabel })
|
|
@@ -9732,7 +11389,7 @@ function MatrxDataTableWithUrlState({
|
|
|
9732
11389
|
...urlState.history === void 0 ? {} : { history: urlState.history },
|
|
9733
11390
|
...urlState.textHistory === void 0 ? {} : { textHistory: urlState.textHistory }
|
|
9734
11391
|
});
|
|
9735
|
-
(0,
|
|
11392
|
+
(0, import_react21.useEffect)(() => {
|
|
9736
11393
|
if (activeUrlTableIds.has(urlState.id)) {
|
|
9737
11394
|
throw new Error(
|
|
9738
11395
|
`Duplicate MatrxDataTable urlState.id "${urlState.id}" on one page. Give every table a unique stable id.`
|
|
@@ -9823,6 +11480,11 @@ function opensRowHref(event) {
|
|
|
9823
11480
|
function TableContextPassthrough({ children }) {
|
|
9824
11481
|
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_jsx_runtime42.Fragment, { children });
|
|
9825
11482
|
}
|
|
11483
|
+
function sameWindow(a, b) {
|
|
11484
|
+
if (a === null || b === null) return a === b;
|
|
11485
|
+
return a.start === b.start && a.end === b.end && a.padStart === b.padStart && a.padEnd === b.padEnd && a.total === b.total && a.pinned.length === b.pinned.length;
|
|
11486
|
+
}
|
|
11487
|
+
var NO_GROUPING_VALUE = "__matrx_no_grouping__";
|
|
9826
11488
|
function MatrxDataTableCore({
|
|
9827
11489
|
data: suppliedData,
|
|
9828
11490
|
columns,
|
|
@@ -9879,11 +11541,16 @@ function MatrxDataTableCore({
|
|
|
9879
11541
|
mobileCardsBreakpoint = "sm",
|
|
9880
11542
|
getRowHref,
|
|
9881
11543
|
onRowOpen,
|
|
9882
|
-
density
|
|
11544
|
+
density,
|
|
11545
|
+
grouping,
|
|
11546
|
+
virtualize,
|
|
11547
|
+
coverage,
|
|
11548
|
+
spreadsheet,
|
|
11549
|
+
rowHeight: explicitRowHeight
|
|
9883
11550
|
}) {
|
|
9884
11551
|
const appendQuery = query?.mode === "controlled-append" ? query : null;
|
|
9885
11552
|
const appendQueryKey = appendQuery?.pagination.queryKey ?? null;
|
|
9886
|
-
const committedAppendQueryKey = (0,
|
|
11553
|
+
const committedAppendQueryKey = (0, import_react21.useRef)(appendQueryKey);
|
|
9887
11554
|
const appendSourceChanged = appendQuery !== null && committedAppendQueryKey.current !== appendQueryKey;
|
|
9888
11555
|
const data = (appendQuery ? appendQuery.pagination.rows : suppliedData) ?? [];
|
|
9889
11556
|
const isLoading = appendQuery ? appendQuery.pagination.loading : suppliedLoading;
|
|
@@ -9895,10 +11562,10 @@ function MatrxDataTableCore({
|
|
|
9895
11562
|
const Link = host.Link ?? DefaultTableLink;
|
|
9896
11563
|
const SidePanelSurface = host.SidePanelSurface ?? DefaultTableSidePanel;
|
|
9897
11564
|
const { notify: toast, notice } = useTableNotice();
|
|
9898
|
-
const [savedViewError, setSavedViewError] = (0,
|
|
9899
|
-
const [toolbarActionError, setToolbarActionError] = (0,
|
|
9900
|
-
const [toolbarActionPending, setToolbarActionPending] = (0,
|
|
9901
|
-
const toolbarActionPendingRef = (0,
|
|
11565
|
+
const [savedViewError, setSavedViewError] = (0, import_react21.useState)(null);
|
|
11566
|
+
const [toolbarActionError, setToolbarActionError] = (0, import_react21.useState)(null);
|
|
11567
|
+
const [toolbarActionPending, setToolbarActionPending] = (0, import_react21.useState)({ refresh: false, add: false });
|
|
11568
|
+
const toolbarActionPendingRef = (0, import_react21.useRef)({ refresh: false, add: false });
|
|
9902
11569
|
const CHECKBOX_TAP_AREA = "h-4 w-4 touch-manipulation";
|
|
9903
11570
|
const mobileCardsClass = mobileCardsBreakpoint === "lg" ? "lg:hidden" : "sm:hidden";
|
|
9904
11571
|
const tableWithCardsClass = mobileCardsBreakpoint === "lg" ? "max-lg:hidden" : "max-sm:hidden";
|
|
@@ -9911,7 +11578,7 @@ function MatrxDataTableCore({
|
|
|
9911
11578
|
const sourceOwnsIntelligentSearch = sourceProcessing?.intelligentSearch === "source";
|
|
9912
11579
|
const sourceOwnsSearch = remoteQuery?.mode === "controlled" || appendQuery !== null && sourceProcessing === void 0 || sourceProcessing?.search === "source" || sourceOwnsIntelligentSearch;
|
|
9913
11580
|
const intelligentSearchEnabled = toolbar?.intelligentSearch !== void 0 && (sourceOwnsIntelligentSearch || remoteQuery === null && !sourceOwnsSearch);
|
|
9914
|
-
const emitControlledQueryChange = (0,
|
|
11581
|
+
const emitControlledQueryChange = (0, import_react21.useCallback)(
|
|
9915
11582
|
(patch, options) => {
|
|
9916
11583
|
if (!controlledQuery) return;
|
|
9917
11584
|
controlledQuery.onStateChange(
|
|
@@ -9920,8 +11587,8 @@ function MatrxDataTableCore({
|
|
|
9920
11587
|
},
|
|
9921
11588
|
[controlledQuery]
|
|
9922
11589
|
);
|
|
9923
|
-
const [internalSearch, setInternalSearch] = (0,
|
|
9924
|
-
const [draggedRowId, setDraggedRowId] = (0,
|
|
11590
|
+
const [internalSearch, setInternalSearch] = (0, import_react21.useState)("");
|
|
11591
|
+
const [draggedRowId, setDraggedRowId] = (0, import_react21.useState)(null);
|
|
9925
11592
|
const hierarchySensors = (0, import_core3.useSensors)(
|
|
9926
11593
|
(0, import_core3.useSensor)(import_core3.PointerSensor, {
|
|
9927
11594
|
activationConstraint: { distance: COLUMN_REORDER_ACTIVATION_DISTANCE }
|
|
@@ -9937,7 +11604,7 @@ function MatrxDataTableCore({
|
|
|
9937
11604
|
}
|
|
9938
11605
|
toolbar?.onSearchChange?.(v);
|
|
9939
11606
|
};
|
|
9940
|
-
const [internalSearchMatchMode, setInternalSearchMatchMode] = (0,
|
|
11607
|
+
const [internalSearchMatchMode, setInternalSearchMatchMode] = (0, import_react21.useState)(
|
|
9941
11608
|
toolbar?.searchMatch?.defaultMode ?? "contains"
|
|
9942
11609
|
);
|
|
9943
11610
|
const searchMatchMode = controlledQuery ? controlledQuery.state.searchMatchMode ?? toolbar?.searchMatch?.defaultMode ?? "contains" : internalSearchMatchMode;
|
|
@@ -9948,7 +11615,7 @@ function MatrxDataTableCore({
|
|
|
9948
11615
|
}
|
|
9949
11616
|
setInternalSearchMatchMode(mode);
|
|
9950
11617
|
};
|
|
9951
|
-
const [internalSearchScope, setInternalSearchScope] = (0,
|
|
11618
|
+
const [internalSearchScope, setInternalSearchScope] = (0, import_react21.useState)("all");
|
|
9952
11619
|
const searchScope = controlledQuery ? controlledQuery.state.searchScope ?? "all" : internalSearchScope;
|
|
9953
11620
|
const setSearchScope = (scope) => {
|
|
9954
11621
|
if (controlledQuery) {
|
|
@@ -9957,7 +11624,7 @@ function MatrxDataTableCore({
|
|
|
9957
11624
|
}
|
|
9958
11625
|
setInternalSearchScope(scope);
|
|
9959
11626
|
};
|
|
9960
|
-
const [internalAnyOf, setInternalAnyOf] = (0,
|
|
11627
|
+
const [internalAnyOf, setInternalAnyOf] = (0, import_react21.useState)("");
|
|
9961
11628
|
const toolbarAnyOfControlled = toolbar?.anyOf?.value !== void 0;
|
|
9962
11629
|
const anyOfValue = controlledQuery ? controlledQuery.state.anyOf : toolbarAnyOfControlled ? toolbar?.anyOf?.value ?? "" : internalAnyOf;
|
|
9963
11630
|
const setAnyOfValue = (v) => {
|
|
@@ -9968,7 +11635,7 @@ function MatrxDataTableCore({
|
|
|
9968
11635
|
}
|
|
9969
11636
|
toolbar?.anyOf?.onChange?.(v);
|
|
9970
11637
|
};
|
|
9971
|
-
const [internalLayeredFilters, setInternalLayeredFilters] = (0,
|
|
11638
|
+
const [internalLayeredFilters, setInternalLayeredFilters] = (0, import_react21.useState)([]);
|
|
9972
11639
|
const layeredFilters = controlledQuery ? controlledQuery.state.layeredFilters ?? [] : internalLayeredFilters;
|
|
9973
11640
|
const setLayeredFilters = (next) => {
|
|
9974
11641
|
if (controlledQuery) {
|
|
@@ -9977,7 +11644,7 @@ function MatrxDataTableCore({
|
|
|
9977
11644
|
}
|
|
9978
11645
|
setInternalLayeredFilters(next);
|
|
9979
11646
|
};
|
|
9980
|
-
const [internalColumnFilters, setInternalColumnFilters] = (0,
|
|
11647
|
+
const [internalColumnFilters, setInternalColumnFilters] = (0, import_react21.useState)({});
|
|
9981
11648
|
const columnFilters = controlledQuery ? controlledQuery.state.columnFilters : internalColumnFilters;
|
|
9982
11649
|
const setColumnFilter = (id, next) => {
|
|
9983
11650
|
const nextFilters = { ...columnFilters, [id]: next };
|
|
@@ -9990,7 +11657,7 @@ function MatrxDataTableCore({
|
|
|
9990
11657
|
}
|
|
9991
11658
|
setInternalColumnFilters(nextFilters);
|
|
9992
11659
|
};
|
|
9993
|
-
const [internalSort, setInternalSort] = (0,
|
|
11660
|
+
const [internalSort, setInternalSort] = (0, import_react21.useState)(defaultSort);
|
|
9994
11661
|
const sort = controlledQuery ? controlledQuery.state.sort : internalSort;
|
|
9995
11662
|
const setSort = (next) => {
|
|
9996
11663
|
if (controlledQuery) {
|
|
@@ -9999,7 +11666,7 @@ function MatrxDataTableCore({
|
|
|
9999
11666
|
}
|
|
10000
11667
|
setInternalSort(next);
|
|
10001
11668
|
};
|
|
10002
|
-
const [internalPage, setInternalPage] = (0,
|
|
11669
|
+
const [internalPage, setInternalPage] = (0, import_react21.useState)(1);
|
|
10003
11670
|
const page = controlledQuery ? controlledQuery.state.page : internalPage;
|
|
10004
11671
|
const setPage = (next) => {
|
|
10005
11672
|
if (controlledQuery) {
|
|
@@ -10008,7 +11675,7 @@ function MatrxDataTableCore({
|
|
|
10008
11675
|
}
|
|
10009
11676
|
setInternalPage(next);
|
|
10010
11677
|
};
|
|
10011
|
-
const [internalPageSize, setInternalPageSize] = (0,
|
|
11678
|
+
const [internalPageSize, setInternalPageSize] = (0, import_react21.useState)(
|
|
10012
11679
|
defaultPageSize
|
|
10013
11680
|
);
|
|
10014
11681
|
const pageSize = controlledQuery ? controlledQuery.state.pageSize : internalPageSize;
|
|
@@ -10019,28 +11686,28 @@ function MatrxDataTableCore({
|
|
|
10019
11686
|
}
|
|
10020
11687
|
setInternalPageSize(next);
|
|
10021
11688
|
};
|
|
10022
|
-
const [uncontrolledSelectedId, setUncontrolledSelectedId] = (0,
|
|
11689
|
+
const [uncontrolledSelectedId, setUncontrolledSelectedId] = (0, import_react21.useState)(null);
|
|
10023
11690
|
const rawSelectedId = controlledSelectedId !== void 0 ? controlledSelectedId : uncontrolledSelectedId;
|
|
10024
11691
|
const selectedId = appendSourceChanged ? null : rawSelectedId;
|
|
10025
11692
|
const setSelectedId = (id) => {
|
|
10026
11693
|
if (controlledSelectedId === void 0) setUncontrolledSelectedId(id);
|
|
10027
11694
|
onSelectedIdChange?.(id);
|
|
10028
11695
|
};
|
|
10029
|
-
const [uncontrolledWindowRowId, setUncontrolledWindowRowId] = (0,
|
|
11696
|
+
const [uncontrolledWindowRowId, setUncontrolledWindowRowId] = (0, import_react21.useState)(null);
|
|
10030
11697
|
const rawWindowRowId = controlledWindowRowId !== void 0 ? controlledWindowRowId : uncontrolledWindowRowId;
|
|
10031
11698
|
const windowRowId = appendSourceChanged ? null : rawWindowRowId;
|
|
10032
11699
|
const setWindowRowId = (id) => {
|
|
10033
11700
|
if (controlledWindowRowId === void 0) setUncontrolledWindowRowId(id);
|
|
10034
11701
|
onWindowRowIdChange?.(id);
|
|
10035
11702
|
};
|
|
10036
|
-
const [windowRowSnapshot, setWindowRowSnapshot] = (0,
|
|
11703
|
+
const [windowRowSnapshot, setWindowRowSnapshot] = (0, import_react21.useState)(null);
|
|
10037
11704
|
const editScopeKey = appendQueryKey === null ? "\0local" : `append:${appendQueryKey}`;
|
|
10038
|
-
const [editsByScope, setEditsByScope] = (0,
|
|
10039
|
-
const editRevisionRef = (0,
|
|
10040
|
-
const [savingByScope, setSavingByScope] = (0,
|
|
10041
|
-
const savingScopesRef = (0,
|
|
10042
|
-
const [editRequest, setEditRequest] = (0,
|
|
10043
|
-
const [confirmForeignDraftDiscard, setConfirmForeignDraftDiscard] = (0,
|
|
11705
|
+
const [editsByScope, setEditsByScope] = (0, import_react21.useState)({});
|
|
11706
|
+
const editRevisionRef = (0, import_react21.useRef)({});
|
|
11707
|
+
const [savingByScope, setSavingByScope] = (0, import_react21.useState)({});
|
|
11708
|
+
const savingScopesRef = (0, import_react21.useRef)(/* @__PURE__ */ new Set());
|
|
11709
|
+
const [editRequest, setEditRequest] = (0, import_react21.useState)(null);
|
|
11710
|
+
const [confirmForeignDraftDiscard, setConfirmForeignDraftDiscard] = (0, import_react21.useState)(false);
|
|
10044
11711
|
const edits = editsByScope[editScopeKey]?.values ?? {};
|
|
10045
11712
|
const saving = (savingByScope[editScopeKey] ?? 0) > 0;
|
|
10046
11713
|
const setEdits = (next) => {
|
|
@@ -10107,7 +11774,7 @@ function MatrxDataTableCore({
|
|
|
10107
11774
|
rows: Object.entries(draft.values).map(([rowId, columns2]) => ({ rowId, columns: columns2 }))
|
|
10108
11775
|
}));
|
|
10109
11776
|
const selection = appendSourceChanged && selectionConfig ? { ...selectionConfig, selectedIds: [] } : selectionConfig;
|
|
10110
|
-
(0,
|
|
11777
|
+
(0, import_react21.useEffect)(() => {
|
|
10111
11778
|
const previous = committedAppendQueryKey.current;
|
|
10112
11779
|
committedAppendQueryKey.current = appendQueryKey;
|
|
10113
11780
|
if (previous === null || appendQueryKey === null || previous === appendQueryKey) {
|
|
@@ -10125,14 +11792,14 @@ function MatrxDataTableCore({
|
|
|
10125
11792
|
onWindowRowIdChange,
|
|
10126
11793
|
selectionConfig
|
|
10127
11794
|
]);
|
|
10128
|
-
const scrollRef = (0,
|
|
10129
|
-
const tableRef = (0,
|
|
10130
|
-
const tableHeaderRef = (0,
|
|
10131
|
-
const cardsScrollRef = (0,
|
|
10132
|
-
const [documentStickyHeader, setDocumentStickyHeader] = (0,
|
|
10133
|
-
const documentStickyHeaderRef = (0,
|
|
10134
|
-
const previousAppendKeyForScrollReset = (0,
|
|
10135
|
-
(0,
|
|
11795
|
+
const scrollRef = (0, import_react21.useRef)(null);
|
|
11796
|
+
const tableRef = (0, import_react21.useRef)(null);
|
|
11797
|
+
const tableHeaderRef = (0, import_react21.useRef)(null);
|
|
11798
|
+
const cardsScrollRef = (0, import_react21.useRef)(null);
|
|
11799
|
+
const [documentStickyHeader, setDocumentStickyHeader] = (0, import_react21.useState)(false);
|
|
11800
|
+
const documentStickyHeaderRef = (0, import_react21.useRef)(false);
|
|
11801
|
+
const previousAppendKeyForScrollReset = (0, import_react21.useRef)(appendQueryKey);
|
|
11802
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
10136
11803
|
const previous = previousAppendKeyForScrollReset.current;
|
|
10137
11804
|
previousAppendKeyForScrollReset.current = appendQueryKey;
|
|
10138
11805
|
if (previous === null || appendQueryKey === null || previous === appendQueryKey) {
|
|
@@ -10157,13 +11824,13 @@ function MatrxDataTableCore({
|
|
|
10157
11824
|
...appendScrollPolicy?.mode === "scroll" && appendScrollPolicy.thresholdPx !== void 0 ? { thresholdPx: appendScrollPolicy.thresholdPx } : {},
|
|
10158
11825
|
...appendScrollPolicy?.mode === "scroll" && appendScrollPolicy.intentTimeoutMs !== void 0 ? { intentTimeoutMs: appendScrollPolicy.intentTimeoutMs } : {}
|
|
10159
11826
|
});
|
|
10160
|
-
const rootRef = (0,
|
|
11827
|
+
const rootRef = (0, import_react21.useRef)(null);
|
|
10161
11828
|
useClippedContentGuard(rootRef, {
|
|
10162
11829
|
label: typeof copy === "object" && copy.listLabel ? `Table: ${copy.listLabel}` : "MatrxDataTable"
|
|
10163
11830
|
});
|
|
10164
|
-
const [scrollHintRight, setScrollHintRight] = (0,
|
|
10165
|
-
const [scrollHintLeft, setScrollHintLeft] = (0,
|
|
10166
|
-
const updateScrollHint = (0,
|
|
11831
|
+
const [scrollHintRight, setScrollHintRight] = (0, import_react21.useState)(false);
|
|
11832
|
+
const [scrollHintLeft, setScrollHintLeft] = (0, import_react21.useState)(false);
|
|
11833
|
+
const updateScrollHint = (0, import_react21.useCallback)(() => {
|
|
10167
11834
|
const el = scrollRef.current;
|
|
10168
11835
|
if (!el) return;
|
|
10169
11836
|
setScrollHintRight(el.scrollLeft + el.clientWidth < el.scrollWidth - 2);
|
|
@@ -10177,7 +11844,7 @@ function MatrxDataTableCore({
|
|
|
10177
11844
|
behavior: "smooth"
|
|
10178
11845
|
});
|
|
10179
11846
|
};
|
|
10180
|
-
(0,
|
|
11847
|
+
(0, import_react21.useEffect)(() => {
|
|
10181
11848
|
updateScrollHint();
|
|
10182
11849
|
window.addEventListener("resize", updateScrollHint);
|
|
10183
11850
|
const el = scrollRef.current;
|
|
@@ -10192,7 +11859,7 @@ function MatrxDataTableCore({
|
|
|
10192
11859
|
observer?.disconnect();
|
|
10193
11860
|
};
|
|
10194
11861
|
}, [updateScrollHint, data, columns]);
|
|
10195
|
-
(0,
|
|
11862
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
10196
11863
|
const scroll = scrollRef.current;
|
|
10197
11864
|
const table = tableRef.current;
|
|
10198
11865
|
const header = tableHeaderRef.current;
|
|
@@ -10251,30 +11918,30 @@ function MatrxDataTableCore({
|
|
|
10251
11918
|
window.removeEventListener("resize", requestUpdate);
|
|
10252
11919
|
};
|
|
10253
11920
|
}, [stickyHeader, data, columns]);
|
|
10254
|
-
const [columnOrder, setColumnOrder] = (0,
|
|
10255
|
-
const [hiddenColumnIds, setHiddenColumnIds] = (0,
|
|
11921
|
+
const [columnOrder, setColumnOrder] = (0, import_react21.useState)(() => columnState?.order ?? columns.map(columnId));
|
|
11922
|
+
const [hiddenColumnIds, setHiddenColumnIds] = (0, import_react21.useState)(
|
|
10256
11923
|
() => new Set(columnState?.hidden ?? columns.filter((column) => column.hidden).map(columnId))
|
|
10257
11924
|
);
|
|
10258
|
-
const [columnWidths, setColumnWidths] = (0,
|
|
11925
|
+
const [columnWidths, setColumnWidths] = (0, import_react21.useState)(
|
|
10259
11926
|
() => normalizeColumnWidthsForColumns(columnState?.widths, columns)
|
|
10260
11927
|
);
|
|
10261
|
-
const [fixedTableGeometry, setFixedTableGeometry] = (0,
|
|
10262
|
-
const knownColumnIds = (0,
|
|
10263
|
-
const draggedColumnId = (0,
|
|
10264
|
-
const columnDragActive = (0,
|
|
10265
|
-
const columnDragRaf = (0,
|
|
10266
|
-
const columnDragScrollDirection = (0,
|
|
10267
|
-
const [columnDragPreview, setColumnDragPreview] = (0,
|
|
10268
|
-
const stopColumnDragScroll = (0,
|
|
11928
|
+
const [fixedTableGeometry, setFixedTableGeometry] = (0, import_react21.useState)(null);
|
|
11929
|
+
const knownColumnIds = (0, import_react21.useRef)(new Set(columns.map(columnId)));
|
|
11930
|
+
const draggedColumnId = (0, import_react21.useRef)(null);
|
|
11931
|
+
const columnDragActive = (0, import_react21.useRef)(false);
|
|
11932
|
+
const columnDragRaf = (0, import_react21.useRef)(null);
|
|
11933
|
+
const columnDragScrollDirection = (0, import_react21.useRef)(0);
|
|
11934
|
+
const [columnDragPreview, setColumnDragPreview] = (0, import_react21.useState)(null);
|
|
11935
|
+
const stopColumnDragScroll = (0, import_react21.useCallback)(() => {
|
|
10269
11936
|
if (columnDragRaf.current !== null) cancelAnimationFrame(columnDragRaf.current);
|
|
10270
11937
|
columnDragRaf.current = null;
|
|
10271
11938
|
columnDragScrollDirection.current = 0;
|
|
10272
11939
|
}, []);
|
|
10273
|
-
(0,
|
|
11940
|
+
(0, import_react21.useEffect)(() => () => {
|
|
10274
11941
|
columnDragActive.current = false;
|
|
10275
11942
|
stopColumnDragScroll();
|
|
10276
11943
|
}, [stopColumnDragScroll]);
|
|
10277
|
-
const startColumnDragScroll = (0,
|
|
11944
|
+
const startColumnDragScroll = (0, import_react21.useCallback)(() => {
|
|
10278
11945
|
if (!columnDragActive.current || columnDragRaf.current !== null) return;
|
|
10279
11946
|
const scrollStep = () => {
|
|
10280
11947
|
const scroll = scrollRef.current;
|
|
@@ -10301,25 +11968,25 @@ function MatrxDataTableCore({
|
|
|
10301
11968
|
};
|
|
10302
11969
|
columnDragRaf.current = requestAnimationFrame(scrollStep);
|
|
10303
11970
|
}, []);
|
|
10304
|
-
const commitColumnState = (0,
|
|
11971
|
+
const commitColumnState = (0, import_react21.useCallback)((order, hidden) => {
|
|
10305
11972
|
if (columnState) columnState.onChange({ order, hidden: [...hidden] });
|
|
10306
11973
|
else {
|
|
10307
11974
|
setColumnOrder(order);
|
|
10308
11975
|
setHiddenColumnIds(hidden);
|
|
10309
11976
|
}
|
|
10310
11977
|
}, [columnState]);
|
|
10311
|
-
const [internalColumnManagerOpen, setInternalColumnManagerOpen] = (0,
|
|
11978
|
+
const [internalColumnManagerOpen, setInternalColumnManagerOpen] = (0, import_react21.useState)(false);
|
|
10312
11979
|
const columnManagerOpen = controlledColumnManager?.open ?? internalColumnManagerOpen;
|
|
10313
11980
|
const setColumnManagerOpen = controlledColumnManager?.onOpenChange ?? setInternalColumnManagerOpen;
|
|
10314
|
-
const columnIds = (0,
|
|
10315
|
-
const effectiveColumnOrder = (0,
|
|
10316
|
-
const effectiveHiddenColumnIds = (0,
|
|
10317
|
-
const effectiveColumnWidths = (0,
|
|
11981
|
+
const columnIds = (0, import_react21.useMemo)(() => columns.map(columnId), [columns]);
|
|
11982
|
+
const effectiveColumnOrder = (0, import_react21.useMemo)(() => columnState ? [...columnState.order.filter((id, index, values) => columnIds.includes(id) && values.indexOf(id) === index), ...columnIds.filter((id) => !columnState.order.includes(id))] : columnOrder, [columnIds, columnOrder, columnState]);
|
|
11983
|
+
const effectiveHiddenColumnIds = (0, import_react21.useMemo)(() => columnState ? new Set(columnState.hidden.filter((id) => columnIds.includes(id))) : hiddenColumnIds, [columnIds, columnState, hiddenColumnIds]);
|
|
11984
|
+
const effectiveColumnWidths = (0, import_react21.useMemo)(
|
|
10318
11985
|
() => normalizeColumnWidthsForColumns(columnState?.widths ?? columnWidths, columns),
|
|
10319
11986
|
[columns, columnState?.widths, columnWidths]
|
|
10320
11987
|
);
|
|
10321
|
-
const resizeGestureSnapshotRef = (0,
|
|
10322
|
-
const measureVisibleColumnWidths = (0,
|
|
11988
|
+
const resizeGestureSnapshotRef = (0, import_react21.useRef)(null);
|
|
11989
|
+
const measureVisibleColumnWidths = (0, import_react21.useCallback)(() => {
|
|
10323
11990
|
const measured = {};
|
|
10324
11991
|
const headers = tableRef.current ? Array.from(tableRef.current.querySelectorAll(
|
|
10325
11992
|
"thead th[data-matrx-table-column-id]"
|
|
@@ -10333,7 +12000,7 @@ function MatrxDataTableCore({
|
|
|
10333
12000
|
}
|
|
10334
12001
|
return normalizeColumnWidthsForColumns(measured, columns);
|
|
10335
12002
|
}, [columns]);
|
|
10336
|
-
const measureFixedTableGeometry = (0,
|
|
12003
|
+
const measureFixedTableGeometry = (0, import_react21.useCallback)(() => {
|
|
10337
12004
|
const table = tableRef.current;
|
|
10338
12005
|
const headers = table ? Array.from(table.querySelectorAll("thead th")) : [];
|
|
10339
12006
|
const widthFor = (selector) => {
|
|
@@ -10368,16 +12035,16 @@ function MatrxDataTableCore({
|
|
|
10368
12035
|
...actionsWidth === void 0 ? {} : { actionsWidth }
|
|
10369
12036
|
};
|
|
10370
12037
|
}, [resolvedDensity]);
|
|
10371
|
-
const captureResizeGestureSnapshot = (0,
|
|
12038
|
+
const captureResizeGestureSnapshot = (0, import_react21.useCallback)(() => {
|
|
10372
12039
|
resizeGestureSnapshotRef.current = {
|
|
10373
12040
|
widths: measureVisibleColumnWidths(),
|
|
10374
12041
|
geometry: measureFixedTableGeometry()
|
|
10375
12042
|
};
|
|
10376
12043
|
}, [measureFixedTableGeometry, measureVisibleColumnWidths]);
|
|
10377
|
-
const clearResizeGestureSnapshot = (0,
|
|
12044
|
+
const clearResizeGestureSnapshot = (0, import_react21.useCallback)(() => {
|
|
10378
12045
|
resizeGestureSnapshotRef.current = null;
|
|
10379
12046
|
}, []);
|
|
10380
|
-
const commitColumnWidths = (0,
|
|
12047
|
+
const commitColumnWidths = (0, import_react21.useCallback)((next, captureInitialWidths = false) => {
|
|
10381
12048
|
const gestureSnapshot = captureInitialWidths ? resizeGestureSnapshotRef.current : null;
|
|
10382
12049
|
resizeGestureSnapshotRef.current = null;
|
|
10383
12050
|
const normalized = normalizeColumnWidthsForColumns(
|
|
@@ -10396,7 +12063,7 @@ function MatrxDataTableCore({
|
|
|
10396
12063
|
}
|
|
10397
12064
|
setColumnWidths(normalized);
|
|
10398
12065
|
}, [columnIds, columnState, columns, measureFixedTableGeometry, measureVisibleColumnWidths]);
|
|
10399
|
-
(0,
|
|
12066
|
+
(0, import_react21.useEffect)(() => {
|
|
10400
12067
|
const ids = columns.map(columnId);
|
|
10401
12068
|
if (columnState) return;
|
|
10402
12069
|
const previousIds = knownColumnIds.current;
|
|
@@ -10415,31 +12082,31 @@ function MatrxDataTableCore({
|
|
|
10415
12082
|
setColumnWidths((current) => normalizeColumnWidthsForColumns(current, columns));
|
|
10416
12083
|
knownColumnIds.current = new Set(ids);
|
|
10417
12084
|
}, [columns, columnState]);
|
|
10418
|
-
(0,
|
|
12085
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
10419
12086
|
for (const id of columnIds) {
|
|
10420
12087
|
tableRef.current?.style.removeProperty(columnResizeCssVar(id));
|
|
10421
12088
|
}
|
|
10422
12089
|
});
|
|
10423
|
-
const previewColumnOrder = (0,
|
|
12090
|
+
const previewColumnOrder = (0, import_react21.useMemo)(
|
|
10424
12091
|
() => projectColumnDragOrder(effectiveColumnOrder, columnDragPreview),
|
|
10425
12092
|
[columnDragPreview, effectiveColumnOrder]
|
|
10426
12093
|
);
|
|
10427
12094
|
useColumnReorderAnimation(tableRef, previewColumnOrder.join("\0"), columnDragPreview !== null);
|
|
10428
|
-
const visibleColumns = (0,
|
|
12095
|
+
const visibleColumns = (0, import_react21.useMemo)(() => {
|
|
10429
12096
|
const byId = new Map(columns.map((column) => [columnId(column), column]));
|
|
10430
12097
|
return previewColumnOrder.map((id) => byId.get(id)).filter(
|
|
10431
12098
|
(column) => column !== void 0 && !effectiveHiddenColumnIds.has(columnId(column))
|
|
10432
12099
|
);
|
|
10433
12100
|
}, [columns, effectiveHiddenColumnIds, previewColumnOrder]);
|
|
10434
12101
|
const usesMeasuredFixedLayout = visibleColumns.length > 0 && visibleColumns.every((column) => effectiveColumnWidths[columnId(column)] !== void 0);
|
|
10435
|
-
(0,
|
|
12102
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
10436
12103
|
if (!usesMeasuredFixedLayout) {
|
|
10437
12104
|
if (fixedTableGeometry !== null) setFixedTableGeometry(null);
|
|
10438
12105
|
return;
|
|
10439
12106
|
}
|
|
10440
12107
|
if (fixedTableGeometry === null) setFixedTableGeometry(measureFixedTableGeometry());
|
|
10441
12108
|
}, [fixedTableGeometry, measureFixedTableGeometry, usesMeasuredFixedLayout]);
|
|
10442
|
-
(0,
|
|
12109
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
10443
12110
|
if (!usesMeasuredFixedLayout) return;
|
|
10444
12111
|
const table = tableRef.current;
|
|
10445
12112
|
if (!table) return;
|
|
@@ -10461,7 +12128,7 @@ function MatrxDataTableCore({
|
|
|
10461
12128
|
setFixedTableGeometry(geometry);
|
|
10462
12129
|
}, [resolvedDensity, measureFixedTableGeometry, usesMeasuredFixedLayout]);
|
|
10463
12130
|
const fixedLayoutActive = usesMeasuredFixedLayout && fixedTableGeometry !== null;
|
|
10464
|
-
const frozenColumns = (0,
|
|
12131
|
+
const frozenColumns = (0, import_react21.useMemo)(() => {
|
|
10465
12132
|
if (!visibleColumns.some((column) => column.frozen)) return NO_FROZEN_COLUMNS;
|
|
10466
12133
|
const ids = visibleColumns.map(columnId);
|
|
10467
12134
|
const byId = new Map(visibleColumns.map((column) => [columnId(column), column]));
|
|
@@ -10503,15 +12170,15 @@ function MatrxDataTableCore({
|
|
|
10503
12170
|
);
|
|
10504
12171
|
return color ? CELL_TINT_CLASS[color] : void 0;
|
|
10505
12172
|
};
|
|
10506
|
-
const declaredVisibleCopyColumns = (0,
|
|
12173
|
+
const declaredVisibleCopyColumns = (0, import_react21.useMemo)(
|
|
10507
12174
|
() => visibleColumns.filter((column) => column.accessorFn !== void 0 || column.accessorKey !== void 0),
|
|
10508
12175
|
[visibleColumns]
|
|
10509
12176
|
);
|
|
10510
|
-
const tableCopySourceNamespace = (0,
|
|
10511
|
-
const tableContextMenuInstanceId = (0,
|
|
10512
|
-
const tableDndContextId = (0,
|
|
12177
|
+
const tableCopySourceNamespace = (0, import_react21.useId)();
|
|
12178
|
+
const tableContextMenuInstanceId = (0, import_react21.useId)();
|
|
12179
|
+
const tableDndContextId = (0, import_react21.useId)();
|
|
10513
12180
|
const defaultCopyTitle = toolbar?.title || "Table";
|
|
10514
|
-
const defaultCopy = (0,
|
|
12181
|
+
const defaultCopy = (0, import_react21.useMemo)(() => ({
|
|
10515
12182
|
label: defaultCopyTitle,
|
|
10516
12183
|
listLabel: defaultCopyTitle,
|
|
10517
12184
|
location: defaultCopyTitle,
|
|
@@ -10546,7 +12213,7 @@ function MatrxDataTableCore({
|
|
|
10546
12213
|
serializer: (shaped) => buildViewAgentInput(effectiveCopy, shaped, data, { scope: "custom" })
|
|
10547
12214
|
}))
|
|
10548
12215
|
] : [];
|
|
10549
|
-
const filterMeta = (0,
|
|
12216
|
+
const filterMeta = (0, import_react21.useMemo)(() => {
|
|
10550
12217
|
const meta = /* @__PURE__ */ new Map();
|
|
10551
12218
|
for (const col of visibleColumns) {
|
|
10552
12219
|
const id = columnId(col);
|
|
@@ -10554,14 +12221,14 @@ function MatrxDataTableCore({
|
|
|
10554
12221
|
}
|
|
10555
12222
|
return meta;
|
|
10556
12223
|
}, [visibleColumns, data, remoteQuery]);
|
|
10557
|
-
const intelligentSearchScopes = (0,
|
|
12224
|
+
const intelligentSearchScopes = (0, import_react21.useMemo)(
|
|
10558
12225
|
() => resolveTableSearchScopes(data, columns, {
|
|
10559
12226
|
...toolbar?.intelligentSearch?.roles === void 0 ? {} : { roles: toolbar.intelligentSearch.roles },
|
|
10560
12227
|
...toolbar?.intelligentSearch?.scopes === void 0 ? {} : { scopes: toolbar.intelligentSearch.scopes }
|
|
10561
12228
|
}),
|
|
10562
12229
|
[columns, data, toolbar?.intelligentSearch?.roles, toolbar?.intelligentSearch?.scopes]
|
|
10563
12230
|
);
|
|
10564
|
-
const processed = (0,
|
|
12231
|
+
const processed = (0, import_react21.useMemo)(() => {
|
|
10565
12232
|
if (remoteQuery && !appendUsesLocalProcessing) return data;
|
|
10566
12233
|
if (processLocalRows) {
|
|
10567
12234
|
return processLocalRows(data, {
|
|
@@ -10624,8 +12291,8 @@ function MatrxDataTableCore({
|
|
|
10624
12291
|
intelligentSearchEnabled,
|
|
10625
12292
|
searchScope
|
|
10626
12293
|
]);
|
|
10627
|
-
const lastNotifiedViewRows = (0,
|
|
10628
|
-
(0,
|
|
12294
|
+
const lastNotifiedViewRows = (0, import_react21.useRef)(null);
|
|
12295
|
+
(0, import_react21.useEffect)(() => {
|
|
10629
12296
|
if (!onViewChange) {
|
|
10630
12297
|
lastNotifiedViewRows.current = null;
|
|
10631
12298
|
return;
|
|
@@ -10634,7 +12301,7 @@ function MatrxDataTableCore({
|
|
|
10634
12301
|
lastNotifiedViewRows.current = processed;
|
|
10635
12302
|
if (changed) onViewChange(processed);
|
|
10636
12303
|
}, [processed, onViewChange]);
|
|
10637
|
-
(0,
|
|
12304
|
+
(0, import_react21.useEffect)(() => {
|
|
10638
12305
|
if (controlledQuery) return;
|
|
10639
12306
|
setInternalPage(1);
|
|
10640
12307
|
}, [
|
|
@@ -10678,7 +12345,7 @@ function MatrxDataTableCore({
|
|
|
10678
12345
|
numberedPageHasMore: !hidePagination && !isLoading && !isFetching && processed.length > 0 && safePage < pageCount && (remoteQuery?.mode === "controlled" || !remoteQuery && localPagination?.mode === "numbered"),
|
|
10679
12346
|
onPageAdvance: setPage
|
|
10680
12347
|
});
|
|
10681
|
-
const paginated = (0,
|
|
12348
|
+
const paginated = (0, import_react21.useMemo)(() => {
|
|
10682
12349
|
if (remoteQuery) return processed;
|
|
10683
12350
|
if (hidePagination) return processed;
|
|
10684
12351
|
if (localProgressiveEnabled) return [...progressiveRows.rows];
|
|
@@ -10686,15 +12353,268 @@ function MatrxDataTableCore({
|
|
|
10686
12353
|
const start = (safePage - 1) * effectivePageSize;
|
|
10687
12354
|
return processed.slice(start, start + effectivePageSize);
|
|
10688
12355
|
}, [processed, safePage, effectivePageSize, pageSize, remoteQuery, hidePagination, localProgressiveEnabled, progressiveRows.rows]);
|
|
10689
|
-
|
|
12356
|
+
const groupingColumnId = grouping?.columnId ?? null;
|
|
12357
|
+
const [uncontrolledCollapsed, setUncontrolledCollapsed] = (0, import_react21.useState)([]);
|
|
12358
|
+
const collapsedGroups = grouping?.collapsed ?? uncontrolledCollapsed;
|
|
12359
|
+
const setCollapsedGroups = (0, import_react21.useCallback)(
|
|
12360
|
+
(next) => {
|
|
12361
|
+
if (grouping?.onCollapsedChange) grouping.onCollapsedChange(next);
|
|
12362
|
+
else setUncontrolledCollapsed(next);
|
|
12363
|
+
},
|
|
12364
|
+
[grouping]
|
|
12365
|
+
);
|
|
12366
|
+
const groups = (0, import_react21.useMemo)(() => {
|
|
12367
|
+
if (!grouping || !groupingColumnId) return null;
|
|
12368
|
+
const groupColumn = columns.find((col) => columnId(col) === groupingColumnId);
|
|
12369
|
+
if (!groupColumn) return null;
|
|
12370
|
+
const aggregateColumns = {};
|
|
12371
|
+
for (const [aggColumnId, spec] of Object.entries(grouping.aggregates ?? {})) {
|
|
12372
|
+
const col = columns.find((c) => columnId(c) === aggColumnId);
|
|
12373
|
+
if (!col) continue;
|
|
12374
|
+
aggregateColumns[aggColumnId] = { spec, readCell: (row) => getCellValue(row, col) };
|
|
12375
|
+
}
|
|
12376
|
+
return groupRows({
|
|
12377
|
+
rows: paginated,
|
|
12378
|
+
columnId: groupingColumnId,
|
|
12379
|
+
readCell: (row) => grouping.readCell ? grouping.readCell(row, groupingColumnId) : getCellValue(row, groupColumn),
|
|
12380
|
+
aggregates: aggregateColumns,
|
|
12381
|
+
...grouping.order ? { order: grouping.order } : {},
|
|
12382
|
+
...grouping.emptyLabel ? { emptyLabel: grouping.emptyLabel } : {}
|
|
12383
|
+
});
|
|
12384
|
+
}, [grouping, groupingColumnId, columns, paginated]);
|
|
12385
|
+
const groupableColumns = (0, import_react21.useMemo)(() => {
|
|
12386
|
+
const allowed = grouping?.groupableColumnIds;
|
|
12387
|
+
return visibleColumns.filter((col) => {
|
|
12388
|
+
const id = columnId(col);
|
|
12389
|
+
if (allowed) return allowed.includes(id);
|
|
12390
|
+
return col.accessorKey !== void 0 || col.accessorFn !== void 0;
|
|
12391
|
+
});
|
|
12392
|
+
}, [visibleColumns, grouping?.groupableColumnIds]);
|
|
12393
|
+
const groupedRenderRows = (0, import_react21.useMemo)(
|
|
12394
|
+
() => groups ? flattenGroups(groups, collapsedGroups) : null,
|
|
12395
|
+
[groups, collapsedGroups]
|
|
12396
|
+
);
|
|
12397
|
+
const virtualizeConfig = virtualize === void 0 || virtualize === false ? null : virtualize === true ? {} : virtualize;
|
|
12398
|
+
const virtualRowHeight = explicitRowHeight ?? virtualizeConfig?.rowHeight ?? (resolvedDensity === "condensed" ? 32 : resolvedDensity === "spacious" ? 52 : 40);
|
|
12399
|
+
const virtualThreshold = virtualizeConfig?.threshold ?? 150;
|
|
12400
|
+
const bodyEntryCount = groupedRenderRows ? groupedRenderRows.length : paginated.length;
|
|
12401
|
+
const virtualizeActive = virtualizeConfig !== null && virtualizeConfig.enabled !== false && bodyEntryCount > virtualThreshold && !hierarchy && expandedDetail === void 0;
|
|
12402
|
+
const columnWindowWidth = virtualizeConfig?.columnWidth ?? 160;
|
|
12403
|
+
const frozenRunLength = (0, import_react21.useMemo)(() => {
|
|
12404
|
+
let run = 0;
|
|
12405
|
+
for (const col of visibleColumns) {
|
|
12406
|
+
if (frozenColumns.offsets[columnId(col)] === void 0) break;
|
|
12407
|
+
run += 1;
|
|
12408
|
+
}
|
|
12409
|
+
return run;
|
|
12410
|
+
}, [visibleColumns, frozenColumns]);
|
|
12411
|
+
const columnVirtualizeActive = virtualizeConfig !== null && virtualizeConfig.enabled !== false && virtualizeConfig.columns === true && visibleColumns.length - frozenRunLength > 30 && !hierarchy && mobileCards === void 0;
|
|
12412
|
+
const [rowWindow, setRowWindow] = (0, import_react21.useState)(null);
|
|
12413
|
+
const [columnWindow, setColumnWindow] = (0, import_react21.useState)(null);
|
|
12414
|
+
const windowInputs = (0, import_react21.useRef)({
|
|
12415
|
+
virtualizeActive: false,
|
|
12416
|
+
bodyEntryCount: 0,
|
|
12417
|
+
virtualRowHeight: 40,
|
|
12418
|
+
overscan: 8,
|
|
12419
|
+
columnVirtualizeActive: false,
|
|
12420
|
+
columnCount: 0,
|
|
12421
|
+
columnWindowWidth: 160,
|
|
12422
|
+
frozenRunLength: 0
|
|
12423
|
+
});
|
|
12424
|
+
windowInputs.current = {
|
|
12425
|
+
virtualizeActive,
|
|
12426
|
+
bodyEntryCount,
|
|
12427
|
+
virtualRowHeight,
|
|
12428
|
+
overscan: virtualizeConfig?.overscan ?? 8,
|
|
12429
|
+
columnVirtualizeActive,
|
|
12430
|
+
columnCount: visibleColumns.length,
|
|
12431
|
+
columnWindowWidth,
|
|
12432
|
+
frozenRunLength
|
|
12433
|
+
};
|
|
12434
|
+
const recomputeWindows = (0, import_react21.useCallback)(() => {
|
|
12435
|
+
const el = scrollRef.current;
|
|
12436
|
+
const input = windowInputs.current;
|
|
12437
|
+
const nextRow = input.virtualizeActive ? computeWindow({
|
|
12438
|
+
count: input.bodyEntryCount,
|
|
12439
|
+
itemSize: input.virtualRowHeight,
|
|
12440
|
+
viewport: el?.clientHeight || 600,
|
|
12441
|
+
offset: el?.scrollTop ?? 0,
|
|
12442
|
+
overscan: input.overscan
|
|
12443
|
+
}) : null;
|
|
12444
|
+
const nextColumn = input.columnVirtualizeActive ? computeWindow({
|
|
12445
|
+
count: input.columnCount,
|
|
12446
|
+
itemSize: input.columnWindowWidth,
|
|
12447
|
+
viewport: el?.clientWidth || 1200,
|
|
12448
|
+
offset: el?.scrollLeft ?? 0,
|
|
12449
|
+
overscan: Math.max(2, Math.round(input.overscan / 2)),
|
|
12450
|
+
pinnedStart: input.frozenRunLength
|
|
12451
|
+
}) : null;
|
|
12452
|
+
setRowWindow((prev) => sameWindow(prev, nextRow) ? prev : nextRow);
|
|
12453
|
+
setColumnWindow((prev) => sameWindow(prev, nextColumn) ? prev : nextColumn);
|
|
12454
|
+
}, []);
|
|
12455
|
+
const effectiveRowWindow = (0, import_react21.useMemo)(() => {
|
|
12456
|
+
if (!virtualizeActive) return null;
|
|
12457
|
+
if (rowWindow && rowWindow.end <= bodyEntryCount) return rowWindow;
|
|
12458
|
+
return computeWindow({
|
|
12459
|
+
count: bodyEntryCount,
|
|
12460
|
+
itemSize: virtualRowHeight,
|
|
12461
|
+
viewport: scrollRef.current?.clientHeight || 600,
|
|
12462
|
+
offset: scrollRef.current?.scrollTop ?? 0,
|
|
12463
|
+
overscan: virtualizeConfig?.overscan ?? 8
|
|
12464
|
+
});
|
|
12465
|
+
}, [virtualizeActive, rowWindow, bodyEntryCount, virtualRowHeight, virtualizeConfig?.overscan]);
|
|
12466
|
+
const effectiveColumnWindow = (0, import_react21.useMemo)(() => {
|
|
12467
|
+
if (!columnVirtualizeActive) return null;
|
|
12468
|
+
if (columnWindow && columnWindow.end <= visibleColumns.length) return columnWindow;
|
|
12469
|
+
return computeWindow({
|
|
12470
|
+
count: visibleColumns.length,
|
|
12471
|
+
itemSize: columnWindowWidth,
|
|
12472
|
+
viewport: scrollRef.current?.clientWidth || 1200,
|
|
12473
|
+
offset: scrollRef.current?.scrollLeft ?? 0,
|
|
12474
|
+
overscan: Math.max(2, Math.round((virtualizeConfig?.overscan ?? 8) / 2)),
|
|
12475
|
+
pinnedStart: frozenRunLength
|
|
12476
|
+
});
|
|
12477
|
+
}, [
|
|
12478
|
+
columnVirtualizeActive,
|
|
12479
|
+
columnWindow,
|
|
12480
|
+
visibleColumns.length,
|
|
12481
|
+
columnWindowWidth,
|
|
12482
|
+
virtualizeConfig?.overscan,
|
|
12483
|
+
frozenRunLength
|
|
12484
|
+
]);
|
|
12485
|
+
const metricsWanted = virtualizeActive || columnVirtualizeActive;
|
|
12486
|
+
(0, import_react21.useEffect)(() => {
|
|
12487
|
+
recomputeWindows();
|
|
12488
|
+
}, [
|
|
12489
|
+
recomputeWindows,
|
|
12490
|
+
virtualizeActive,
|
|
12491
|
+
bodyEntryCount,
|
|
12492
|
+
virtualRowHeight,
|
|
12493
|
+
columnVirtualizeActive,
|
|
12494
|
+
visibleColumns.length,
|
|
12495
|
+
columnWindowWidth,
|
|
12496
|
+
frozenRunLength
|
|
12497
|
+
]);
|
|
12498
|
+
(0, import_react21.useEffect)(() => {
|
|
12499
|
+
if (!metricsWanted) return;
|
|
12500
|
+
const el = scrollRef.current;
|
|
12501
|
+
if (!el) return;
|
|
12502
|
+
let frame = 0;
|
|
12503
|
+
const onScroll = () => {
|
|
12504
|
+
if (frame) return;
|
|
12505
|
+
frame = requestAnimationFrame(() => {
|
|
12506
|
+
frame = 0;
|
|
12507
|
+
recomputeWindows();
|
|
12508
|
+
});
|
|
12509
|
+
};
|
|
12510
|
+
el.addEventListener("scroll", onScroll, { passive: true });
|
|
12511
|
+
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(onScroll);
|
|
12512
|
+
observer?.observe(el);
|
|
12513
|
+
return () => {
|
|
12514
|
+
if (frame) cancelAnimationFrame(frame);
|
|
12515
|
+
el.removeEventListener("scroll", onScroll);
|
|
12516
|
+
observer?.disconnect();
|
|
12517
|
+
};
|
|
12518
|
+
}, [metricsWanted, recomputeWindows]);
|
|
12519
|
+
const renderedColumns = (0, import_react21.useMemo)(
|
|
12520
|
+
() => effectiveColumnWindow ? [
|
|
12521
|
+
...visibleColumns.slice(0, frozenRunLength),
|
|
12522
|
+
...visibleColumns.slice(effectiveColumnWindow.start, effectiveColumnWindow.end)
|
|
12523
|
+
] : visibleColumns,
|
|
12524
|
+
[effectiveColumnWindow, visibleColumns, frozenRunLength]
|
|
12525
|
+
);
|
|
12526
|
+
const columnSpacers = effectiveColumnWindow ? { start: effectiveColumnWindow.padStart, end: effectiveColumnWindow.padEnd } : null;
|
|
12527
|
+
const windowedWidthFor = (0, import_react21.useCallback)(
|
|
12528
|
+
(id, declared) => {
|
|
12529
|
+
const resized = effectiveColumnWidths[id];
|
|
12530
|
+
if (!effectiveColumnWindow) return resized;
|
|
12531
|
+
if (frozenColumns.offsets[id] !== void 0) return resized;
|
|
12532
|
+
return resized ?? (typeof declared === "number" ? declared : columnWindowWidth);
|
|
12533
|
+
},
|
|
12534
|
+
[effectiveColumnWindow, effectiveColumnWidths, frozenColumns, columnWindowWidth]
|
|
12535
|
+
);
|
|
12536
|
+
const coverageResult = (0, import_react21.useMemo)(() => {
|
|
12537
|
+
if (!coverage) return null;
|
|
12538
|
+
return describeCoverage({
|
|
12539
|
+
loaded: processed.length,
|
|
12540
|
+
...coverage.matched === void 0 ? {} : { matched: coverage.matched },
|
|
12541
|
+
...coverage.total === void 0 ? {} : { total: coverage.total },
|
|
12542
|
+
...coverage.cap === void 0 ? {} : { cap: coverage.cap },
|
|
12543
|
+
answeredBy: coverage.answeredBy ?? "client",
|
|
12544
|
+
...coverage.noun === void 0 ? {} : { noun: coverage.noun }
|
|
12545
|
+
});
|
|
12546
|
+
}, [coverage, processed.length]);
|
|
12547
|
+
const bodyEntries = (0, import_react21.useMemo)(() => {
|
|
12548
|
+
const from = effectiveRowWindow ? effectiveRowWindow.start : 0;
|
|
12549
|
+
const to = effectiveRowWindow ? effectiveRowWindow.end : void 0;
|
|
12550
|
+
const windowed = groupedRenderRows ? groupedRenderRows.slice(from, to).map(
|
|
12551
|
+
(entry) => entry.kind === "group" ? {
|
|
12552
|
+
kind: "group",
|
|
12553
|
+
group: entry.group,
|
|
12554
|
+
collapsed: isGroupCollapsed(collapsedGroups, entry.group.key)
|
|
12555
|
+
} : { kind: "row", row: entry.row, index: entry.dataIndex ?? 0 }
|
|
12556
|
+
) : paginated.slice(from, to).map((row, offset) => ({ kind: "row", row, index: from + offset }));
|
|
12557
|
+
if (!effectiveRowWindow) return windowed;
|
|
12558
|
+
if (effectiveRowWindow.padStart > 0)
|
|
12559
|
+
windowed.unshift({ kind: "spacer", height: effectiveRowWindow.padStart, place: "start" });
|
|
12560
|
+
if (effectiveRowWindow.padEnd > 0)
|
|
12561
|
+
windowed.push({ kind: "spacer", height: effectiveRowWindow.padEnd, place: "end" });
|
|
12562
|
+
return windowed;
|
|
12563
|
+
}, [groupedRenderRows, collapsedGroups, paginated, effectiveRowWindow]);
|
|
12564
|
+
const getRowIdRef = (0, import_react21.useRef)(getRowId);
|
|
12565
|
+
getRowIdRef.current = getRowId;
|
|
12566
|
+
const spreadsheetRowIds = (0, import_react21.useMemo)(
|
|
12567
|
+
() => paginated.map((row) => getRowIdRef.current(row)),
|
|
12568
|
+
[paginated]
|
|
12569
|
+
);
|
|
12570
|
+
const spreadsheetColumnIds = (0, import_react21.useMemo)(
|
|
12571
|
+
() => visibleColumns.map((col) => columnId(col)),
|
|
12572
|
+
[visibleColumns]
|
|
12573
|
+
);
|
|
12574
|
+
const spreadsheetRowById = (0, import_react21.useMemo)(() => {
|
|
12575
|
+
const map = /* @__PURE__ */ new Map();
|
|
12576
|
+
for (const row of paginated) map.set(getRowIdRef.current(row), row);
|
|
12577
|
+
return map;
|
|
12578
|
+
}, [paginated]);
|
|
12579
|
+
const spreadsheetColumnById = (0, import_react21.useMemo)(() => {
|
|
12580
|
+
const map = /* @__PURE__ */ new Map();
|
|
12581
|
+
for (const col of visibleColumns) map.set(columnId(col), col);
|
|
12582
|
+
return map;
|
|
12583
|
+
}, [visibleColumns]);
|
|
12584
|
+
const spreadsheetEnabled = Boolean(spreadsheet && spreadsheet.enabled !== false);
|
|
12585
|
+
const sheet = useSpreadsheetGrid(
|
|
12586
|
+
spreadsheetEnabled && spreadsheet ? {
|
|
12587
|
+
rowIds: spreadsheetRowIds,
|
|
12588
|
+
columnIds: spreadsheetColumnIds,
|
|
12589
|
+
valueAt: (rowId, colId) => {
|
|
12590
|
+
const row = spreadsheetRowById.get(rowId);
|
|
12591
|
+
const col = spreadsheetColumnById.get(colId);
|
|
12592
|
+
if (row === void 0 || col === void 0) return null;
|
|
12593
|
+
if (spreadsheet.readCell) return spreadsheet.readCell(row, colId);
|
|
12594
|
+
return getCellValue(applyRowEdits(row, edits[rowId]), col);
|
|
12595
|
+
},
|
|
12596
|
+
isColumnWritable: (colId) => {
|
|
12597
|
+
if (spreadsheet.writableColumnIds) return spreadsheet.writableColumnIds.includes(colId);
|
|
12598
|
+
const col = spreadsheetColumnById.get(colId);
|
|
12599
|
+
return Boolean(col && col.editable);
|
|
12600
|
+
},
|
|
12601
|
+
...spreadsheet.columnRefusal ? { columnRefusal: spreadsheet.columnRefusal } : {},
|
|
12602
|
+
onPatch: spreadsheet.onPatch,
|
|
12603
|
+
...spreadsheet.undoDepth === void 0 ? {} : { undoDepth: spreadsheet.undoDepth },
|
|
12604
|
+
...spreadsheet.fillHandle === void 0 ? {} : { fillHandle: spreadsheet.fillHandle },
|
|
12605
|
+
...spreadsheet.paste === void 0 ? {} : { paste: spreadsheet.paste },
|
|
12606
|
+
notify: spreadsheet.notify ?? ((message) => toast.success(message))
|
|
12607
|
+
} : null
|
|
12608
|
+
);
|
|
12609
|
+
(0, import_react21.useEffect)(() => {
|
|
10690
12610
|
if (!controlledQuery || controlledQuery.state.page === safePage) return;
|
|
10691
12611
|
emitControlledQueryChange({ page: safePage });
|
|
10692
12612
|
}, [controlledQuery, emitControlledQueryChange, safePage]);
|
|
10693
|
-
const selectedRow = (0,
|
|
12613
|
+
const selectedRow = (0, import_react21.useMemo)(() => {
|
|
10694
12614
|
if (!selectedId) return null;
|
|
10695
12615
|
return data.find((r) => getRowId(r) === selectedId) ?? null;
|
|
10696
12616
|
}, [data, selectedId, getRowId]);
|
|
10697
|
-
const windowRow = (0,
|
|
12617
|
+
const windowRow = (0, import_react21.useMemo)(() => {
|
|
10698
12618
|
if (!windowRowId) return null;
|
|
10699
12619
|
return data.find((r) => getRowId(r) === windowRowId) ?? (windowRowSnapshot && windowRowSnapshot.queryKey === appendQueryKey && getRowId(windowRowSnapshot.row) === windowRowId ? windowRowSnapshot.row : null);
|
|
10700
12620
|
}, [data, windowRowId, windowRowSnapshot, getRowId, appendQueryKey]);
|
|
@@ -10729,7 +12649,7 @@ function MatrxDataTableCore({
|
|
|
10729
12649
|
return def !== void 0 && f.value !== def;
|
|
10730
12650
|
});
|
|
10731
12651
|
const hasActiveFilters = activeFilterCount > 0 || Boolean(searchValue.trim()) || intelligentSearchEnabled && searchScope !== "all" || Boolean(anyOfValue.trim()) || completeLayeredFilterRules(layeredFilters).length > 0 || facetActive;
|
|
10732
|
-
const changeCount = (0,
|
|
12652
|
+
const changeCount = (0, import_react21.useMemo)(() => {
|
|
10733
12653
|
let n = 0;
|
|
10734
12654
|
for (const fields of Object.values(edits)) {
|
|
10735
12655
|
n += Object.keys(fields).length;
|
|
@@ -10885,7 +12805,7 @@ function MatrxDataTableCore({
|
|
|
10885
12805
|
};
|
|
10886
12806
|
const hierarchyRows = hierarchy?.rows ?? data;
|
|
10887
12807
|
const hierarchyGetParentId = hierarchy?.getParentId;
|
|
10888
|
-
const hierarchyIndex = (0,
|
|
12808
|
+
const hierarchyIndex = (0, import_react21.useMemo)(() => {
|
|
10889
12809
|
if (!hierarchyGetParentId) return null;
|
|
10890
12810
|
const byId = /* @__PURE__ */ new Map();
|
|
10891
12811
|
const parentById = /* @__PURE__ */ new Map();
|
|
@@ -10917,7 +12837,7 @@ function MatrxDataTableCore({
|
|
|
10917
12837
|
return { byId, parentById, depthById };
|
|
10918
12838
|
}, [hierarchyGetParentId, hierarchyRows, getRowId]);
|
|
10919
12839
|
const draggedRow = draggedRowId && hierarchyIndex ? hierarchyIndex.byId.get(draggedRowId) : void 0;
|
|
10920
|
-
const hierarchyBlockedIds = (0,
|
|
12840
|
+
const hierarchyBlockedIds = (0, import_react21.useMemo)(() => {
|
|
10921
12841
|
if (!draggedRowId || !hierarchyIndex) return null;
|
|
10922
12842
|
const childrenById = /* @__PURE__ */ new Map();
|
|
10923
12843
|
for (const [id, parentId] of hierarchyIndex.parentById) {
|
|
@@ -11100,7 +13020,7 @@ function MatrxDataTableCore({
|
|
|
11100
13020
|
setEdits({});
|
|
11101
13021
|
edit?.onCancel?.();
|
|
11102
13022
|
};
|
|
11103
|
-
(0,
|
|
13023
|
+
(0, import_react21.useEffect)(() => {
|
|
11104
13024
|
if (!host.rowContextRegistry || !contextMenu && !host.createDefaultRowContext) return;
|
|
11105
13025
|
return host.rowContextRegistry.register(tableContextMenuInstanceId, (rowId) => {
|
|
11106
13026
|
const row = data.find((candidate) => getRowId(candidate) === rowId);
|
|
@@ -11112,7 +13032,7 @@ function MatrxDataTableCore({
|
|
|
11112
13032
|
});
|
|
11113
13033
|
}, [buildRecordControls, contextMenu, data, getRowId, host.createDefaultRowContext, host.rowContextRegistry, tableContextMenuInstanceId]);
|
|
11114
13034
|
const showActionsCol = windowEnabled || Boolean(rowActions) || showInlineRowCopy;
|
|
11115
|
-
const selectedIdSet = (0,
|
|
13035
|
+
const selectedIdSet = (0, import_react21.useMemo)(
|
|
11116
13036
|
() => new Set(selection?.selectedIds ?? []),
|
|
11117
13037
|
[selection?.selectedIds]
|
|
11118
13038
|
);
|
|
@@ -11124,11 +13044,11 @@ function MatrxDataTableCore({
|
|
|
11124
13044
|
);
|
|
11125
13045
|
const allOnPageSelected = selectableRows.length > 0 && selectedOnPage.length === selectableRows.length;
|
|
11126
13046
|
const someOnPageSelected = selectedOnPage.length > 0 && !allOnPageSelected;
|
|
11127
|
-
const selectedRows = (0,
|
|
13047
|
+
const selectedRows = (0, import_react21.useMemo)(
|
|
11128
13048
|
() => data.filter((row) => selectedIdSet.has(getRowId(row))),
|
|
11129
13049
|
[data, selectedIdSet, getRowId]
|
|
11130
13050
|
);
|
|
11131
|
-
const lastToggledIndex = (0,
|
|
13051
|
+
const lastToggledIndex = (0, import_react21.useRef)(null);
|
|
11132
13052
|
const setSelectedIds = (next) => selection?.onSelectedIdsChange([...next]);
|
|
11133
13053
|
const toggleRowSelected = (index, shiftKey) => {
|
|
11134
13054
|
if (!selection) return;
|
|
@@ -11165,6 +13085,7 @@ function MatrxDataTableCore({
|
|
|
11165
13085
|
const selectionNoun = selection?.noun ?? "row";
|
|
11166
13086
|
const selectionCount = selection?.selectedIds.length ?? 0;
|
|
11167
13087
|
const leadingCols = selection ? 1 : 0;
|
|
13088
|
+
const renderedColSpan = renderedColumns.length + leadingCols + (showActionsCol ? 1 : 0) + (columnSpacers ? (columnSpacers.start > 0 ? 1 : 0) + (columnSpacers.end > 0 ? 1 : 0) : 0);
|
|
11168
13089
|
const renderedFacets = controlledQuery ? toolbar?.facets?.map(
|
|
11169
13090
|
(facet) => facet.type === "button-group" ? {
|
|
11170
13091
|
...facet,
|
|
@@ -11198,7 +13119,7 @@ function MatrxDataTableCore({
|
|
|
11198
13119
|
}
|
|
11199
13120
|
return href ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Link, { href, onClick: (event) => event.stopPropagation(), className: "block w-full min-w-0 rounded outline-none focus-visible:ring-2 focus-visible:ring-ring", children: display }) : display;
|
|
11200
13121
|
};
|
|
11201
|
-
const currentViewSnapshot = (0,
|
|
13122
|
+
const currentViewSnapshot = (0, import_react21.useMemo)(
|
|
11202
13123
|
() => ({
|
|
11203
13124
|
__kind: "matrx-table-view",
|
|
11204
13125
|
version: 1,
|
|
@@ -11233,7 +13154,7 @@ function MatrxDataTableCore({
|
|
|
11233
13154
|
sort
|
|
11234
13155
|
]
|
|
11235
13156
|
);
|
|
11236
|
-
const declaredDefaultViewSnapshot = (0,
|
|
13157
|
+
const declaredDefaultViewSnapshot = (0, import_react21.useMemo)(
|
|
11237
13158
|
() => defaultViewSnapshot ?? {
|
|
11238
13159
|
__kind: "matrx-table-view",
|
|
11239
13160
|
version: 1,
|
|
@@ -11252,7 +13173,7 @@ function MatrxDataTableCore({
|
|
|
11252
13173
|
},
|
|
11253
13174
|
[columns, defaultPageSize, defaultSort, defaultViewSnapshot]
|
|
11254
13175
|
);
|
|
11255
|
-
const applySavedView = (0,
|
|
13176
|
+
const applySavedView = (0, import_react21.useCallback)(
|
|
11256
13177
|
(rawSnapshot) => {
|
|
11257
13178
|
const snapshot = parseTableViewSnapshot(rawSnapshot);
|
|
11258
13179
|
if (!snapshot) {
|
|
@@ -11604,6 +13525,28 @@ function MatrxDataTableCore({
|
|
|
11604
13525
|
}
|
|
11605
13526
|
}
|
|
11606
13527
|
) : null,
|
|
13528
|
+
grouping?.onColumnIdChange ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
13529
|
+
Select,
|
|
13530
|
+
{
|
|
13531
|
+
value: groupingColumnId ?? NO_GROUPING_VALUE,
|
|
13532
|
+
onValueChange: (value) => grouping.onColumnIdChange?.(value === NO_GROUPING_VALUE ? null : value),
|
|
13533
|
+
children: [
|
|
13534
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
13535
|
+
SelectTrigger,
|
|
13536
|
+
{
|
|
13537
|
+
"data-matrx-table-group-by": true,
|
|
13538
|
+
"aria-label": "Group rows by a column",
|
|
13539
|
+
className: "h-8 w-auto min-w-[9rem] gap-1 text-xs",
|
|
13540
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SelectValue, { placeholder: "No groups" })
|
|
13541
|
+
}
|
|
13542
|
+
),
|
|
13543
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(SelectContent, { children: [
|
|
13544
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SelectItem, { value: NO_GROUPING_VALUE, children: "No groups" }),
|
|
13545
|
+
groupableColumns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SelectItem, { value: columnId(col), children: `Group by ${col.label ?? (typeof col.header === "string" ? col.header : columnId(col))}` }, columnId(col)))
|
|
13546
|
+
] })
|
|
13547
|
+
]
|
|
13548
|
+
}
|
|
13549
|
+
) : null,
|
|
11607
13550
|
columns.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
11608
13551
|
TableToolbarAction,
|
|
11609
13552
|
{
|
|
@@ -11671,65 +13614,6 @@ function MatrxDataTableCore({
|
|
|
11671
13614
|
]
|
|
11672
13615
|
}
|
|
11673
13616
|
),
|
|
11674
|
-
selection && selectionCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex shrink-0 flex-wrap items-center gap-2 rounded-md border border-primary/30 bg-primary/5 px-2 py-1.5", children: [
|
|
11675
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "text-xs font-medium text-foreground", children: [
|
|
11676
|
-
(0, import_format5.formatCount)(selectionCount),
|
|
11677
|
-
" ",
|
|
11678
|
-
selectionNoun,
|
|
11679
|
-
selectionCount === 1 ? "" : "s",
|
|
11680
|
-
" selected"
|
|
11681
|
-
] }),
|
|
11682
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
11683
|
-
Button,
|
|
11684
|
-
{
|
|
11685
|
-
type: "button",
|
|
11686
|
-
variant: "ghost",
|
|
11687
|
-
size: "sm",
|
|
11688
|
-
className: "h-7 gap-1 px-2 text-xs",
|
|
11689
|
-
onClick: () => {
|
|
11690
|
-
lastToggledIndex.current = null;
|
|
11691
|
-
selection.onSelectedIdsChange([]);
|
|
11692
|
-
},
|
|
11693
|
-
children: [
|
|
11694
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(X, { className: "h-3.5 w-3.5" }),
|
|
11695
|
-
"Clear"
|
|
11696
|
-
]
|
|
11697
|
-
}
|
|
11698
|
-
),
|
|
11699
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "ml-auto flex flex-wrap items-center gap-1.5", children: [
|
|
11700
|
-
effectiveCopy && selectedRows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
11701
|
-
CopyButtons,
|
|
11702
|
-
{
|
|
11703
|
-
size: "icon",
|
|
11704
|
-
"data-matrx-table-icon-action": true,
|
|
11705
|
-
sourceId: `${tableCopySourceNamespace}:selection`,
|
|
11706
|
-
...effectiveCopy.references ? { references: effectiveCopy.references(selectedRows, data) } : {},
|
|
11707
|
-
...effectiveCopy.triggerVariant ? { triggerVariant: effectiveCopy.triggerVariant } : {},
|
|
11708
|
-
label: `${selectedRows.length} selected ${selectionNoun}${selectedRows.length === 1 ? "" : "s"}`,
|
|
11709
|
-
...copy === void 0 ? {} : {
|
|
11710
|
-
human: () => buildViewHuman(effectiveCopy, selectedRows, effectiveCopyColumns),
|
|
11711
|
-
json: () => selectedRows.map((row) => effectiveCopy.agentRow ? effectiveCopy.agentRow(row) : row)
|
|
11712
|
-
},
|
|
11713
|
-
agent: () => copy === void 0 ? buildDefaultTableViewAgentInput(effectiveCopy, selectedRows, data, declaredVisibleCopyColumns, { scope: "selected" }) : buildViewAgentInput(effectiveCopy, selectedRows, data, { scope: "selected" }),
|
|
11714
|
-
aiVariants: copySubsetVariantFor(
|
|
11715
|
-
() => selectedRows,
|
|
11716
|
-
"selected"
|
|
11717
|
-
),
|
|
11718
|
-
export: {
|
|
11719
|
-
items: [],
|
|
11720
|
-
sheetRows: () => selectedRows.map(
|
|
11721
|
-
(row) => projectDefaultTableCopyRow(row, declaredVisibleCopyColumns)
|
|
11722
|
-
),
|
|
11723
|
-
sheetColumns: () => declaredVisibleCopyColumns.map((column) => ({
|
|
11724
|
-
id: columnId(column),
|
|
11725
|
-
label: column.label ?? (typeof column.header === "string" ? column.header : columnId(column))
|
|
11726
|
-
}))
|
|
11727
|
-
}
|
|
11728
|
-
}
|
|
11729
|
-
) : null,
|
|
11730
|
-
selection.actions?.(selectedRows, selection.selectedIds)
|
|
11731
|
-
] })
|
|
11732
|
-
] }) : null,
|
|
11733
13617
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { "data-matrx-table-body-region": true, className: "flex min-h-0 flex-1 flex-col gap-2", children: [
|
|
11734
13618
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "relative min-h-0 flex-1", children: [
|
|
11735
13619
|
mobileCards ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
@@ -11837,12 +13721,33 @@ function MatrxDataTableCore({
|
|
|
11837
13721
|
]
|
|
11838
13722
|
}
|
|
11839
13723
|
) : null,
|
|
13724
|
+
coverageResult && coverageResult.notice ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
13725
|
+
"div",
|
|
13726
|
+
{
|
|
13727
|
+
"data-matrx-table-coverage": true,
|
|
13728
|
+
"data-matrx-table-coverage-scope": coverageResult.scope,
|
|
13729
|
+
role: "status",
|
|
13730
|
+
className: "mb-1 flex items-start gap-2 rounded-md border border-amber-300/70 bg-amber-50 px-3 py-2 text-xs text-amber-900 dark:border-amber-500/40 dark:bg-amber-950/40 dark:text-amber-200",
|
|
13731
|
+
children: [
|
|
13732
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "font-semibold", children: coverageResult.badge }),
|
|
13733
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: coverageResult.notice })
|
|
13734
|
+
]
|
|
13735
|
+
}
|
|
13736
|
+
) : null,
|
|
11840
13737
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
11841
13738
|
"div",
|
|
11842
13739
|
{
|
|
11843
13740
|
ref: scrollRef,
|
|
11844
13741
|
"data-matrx-table-scroll": true,
|
|
11845
13742
|
onScroll: updateScrollHint,
|
|
13743
|
+
...spreadsheetEnabled ? {
|
|
13744
|
+
tabIndex: sheet.containerProps.tabIndex,
|
|
13745
|
+
onKeyDown: sheet.containerProps.onKeyDown,
|
|
13746
|
+
onCopy: sheet.containerProps.onCopy,
|
|
13747
|
+
onCut: sheet.containerProps.onCut,
|
|
13748
|
+
onPaste: sheet.containerProps.onPaste,
|
|
13749
|
+
"data-matrx-table-spreadsheet": "true"
|
|
13750
|
+
} : {},
|
|
11846
13751
|
"aria-busy": isLoading || isFetching,
|
|
11847
13752
|
style: { containerType: "inline-size" },
|
|
11848
13753
|
className: cn(
|
|
@@ -11900,7 +13805,14 @@ function MatrxDataTableCore({
|
|
|
11900
13805
|
ref: tableHeaderRef,
|
|
11901
13806
|
"data-matrx-table-sticky-header": stickyHeader ? "true" : void 0,
|
|
11902
13807
|
className: cn(
|
|
11903
|
-
|
|
13808
|
+
// 🚨 ABOVE THE FROZEN COLUMN, NOT UNDER IT. A frozen body
|
|
13809
|
+
// cell is `sm:z-20` so it can slide under the columns to
|
|
13810
|
+
// its right; the header was `z-10`, so the frozen column's
|
|
13811
|
+
// cells scrolled straight OVER the header they belong to
|
|
13812
|
+
// and the top data row printed through the column names.
|
|
13813
|
+
// Only a table long enough to scroll shows it, which is why
|
|
13814
|
+
// it survived until a hundred-thousand-row screenshot.
|
|
13815
|
+
"z-30 border-b border-border bg-muted/90 shadow-[0_1px_0_0_var(--border)] backdrop-blur-sm",
|
|
11904
13816
|
stickyHeader && (documentStickyHeader ? "relative translate-y-[var(--matrx-document-sticky-offset)]" : "sticky top-0")
|
|
11905
13817
|
),
|
|
11906
13818
|
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("tr", { children: [
|
|
@@ -11933,7 +13845,17 @@ function MatrxDataTableCore({
|
|
|
11933
13845
|
)
|
|
11934
13846
|
}
|
|
11935
13847
|
) : null,
|
|
11936
|
-
|
|
13848
|
+
columnSpacers && columnSpacers.start > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
13849
|
+
"th",
|
|
13850
|
+
{
|
|
13851
|
+
"aria-hidden": "true",
|
|
13852
|
+
"data-matrx-table-column-spacer": "start",
|
|
13853
|
+
className: "border-0 p-0",
|
|
13854
|
+
style: { width: `${columnSpacers.start}px`, minWidth: `${columnSpacers.start}px` }
|
|
13855
|
+
},
|
|
13856
|
+
"matrx-column-spacer-start"
|
|
13857
|
+
) : null,
|
|
13858
|
+
renderedColumns.map((col) => {
|
|
11937
13859
|
const id = columnId(col);
|
|
11938
13860
|
const meta = filterMeta.get(id);
|
|
11939
13861
|
const isSorted = sort?.id === id;
|
|
@@ -11976,7 +13898,7 @@ function MatrxDataTableCore({
|
|
|
11976
13898
|
frozenEdgeId === id && FROZEN_EDGE_CLASS
|
|
11977
13899
|
),
|
|
11978
13900
|
style: {
|
|
11979
|
-
...columnWidthVar(width,
|
|
13901
|
+
...columnWidthVar(width, windowedWidthFor(id, width), id, columnResizable),
|
|
11980
13902
|
...frozenStyle(id)
|
|
11981
13903
|
},
|
|
11982
13904
|
children: [
|
|
@@ -12040,6 +13962,16 @@ function MatrxDataTableCore({
|
|
|
12040
13962
|
id
|
|
12041
13963
|
);
|
|
12042
13964
|
}),
|
|
13965
|
+
columnSpacers && columnSpacers.end > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
13966
|
+
"th",
|
|
13967
|
+
{
|
|
13968
|
+
"aria-hidden": "true",
|
|
13969
|
+
"data-matrx-table-column-spacer": "end",
|
|
13970
|
+
className: "border-0 p-0",
|
|
13971
|
+
style: { width: `${columnSpacers.end}px`, minWidth: `${columnSpacers.end}px` }
|
|
13972
|
+
},
|
|
13973
|
+
"matrx-column-spacer-end"
|
|
13974
|
+
) : null,
|
|
12043
13975
|
showActionsCol && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
12044
13976
|
"th",
|
|
12045
13977
|
{
|
|
@@ -12055,7 +13987,17 @@ function MatrxDataTableCore({
|
|
|
12055
13987
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("tbody", { children: [
|
|
12056
13988
|
isLoading ? Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("tr", { className: "border-b border-border/60", children: [
|
|
12057
13989
|
selection ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("td", { className: "px-2 py-2", style: fixedUtilityWidth(fixedTableGeometry?.selectionWidth), children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Skeleton, { className: "h-3.5 w-3.5" }) }) : null,
|
|
12058
|
-
|
|
13990
|
+
columnSpacers && columnSpacers.start > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
13991
|
+
"td",
|
|
13992
|
+
{
|
|
13993
|
+
"aria-hidden": "true",
|
|
13994
|
+
"data-matrx-table-column-spacer": "start",
|
|
13995
|
+
className: "border-0 p-0",
|
|
13996
|
+
style: { width: `${columnSpacers.start}px`, minWidth: `${columnSpacers.start}px` }
|
|
13997
|
+
},
|
|
13998
|
+
"matrx-column-spacer-start"
|
|
13999
|
+
) : null,
|
|
14000
|
+
renderedColumns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
12059
14001
|
"td",
|
|
12060
14002
|
{
|
|
12061
14003
|
className: cn(
|
|
@@ -12067,11 +14009,21 @@ function MatrxDataTableCore({
|
|
|
12067
14009
|
},
|
|
12068
14010
|
columnId(col)
|
|
12069
14011
|
)),
|
|
12070
|
-
showActionsCol && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("td", { className: "text-right align-middle", style: fixedUtilityWidth(fixedTableGeometry?.actionsWidth), children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Skeleton, { className: "ml-auto h-5 w-10" }) })
|
|
14012
|
+
showActionsCol && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("td", { className: "text-right align-middle", style: fixedUtilityWidth(fixedTableGeometry?.actionsWidth), children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Skeleton, { className: "ml-auto h-5 w-10" }) }),
|
|
14013
|
+
columnSpacers && columnSpacers.end > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
14014
|
+
"td",
|
|
14015
|
+
{
|
|
14016
|
+
"aria-hidden": "true",
|
|
14017
|
+
"data-matrx-table-column-spacer": "end",
|
|
14018
|
+
className: "border-0 p-0",
|
|
14019
|
+
style: { width: `${columnSpacers.end}px`, minWidth: `${columnSpacers.end}px` }
|
|
14020
|
+
},
|
|
14021
|
+
"matrx-column-spacer-end"
|
|
14022
|
+
) : null
|
|
12071
14023
|
] }, `sk-${i}`)) : paginated.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
12072
14024
|
"td",
|
|
12073
14025
|
{
|
|
12074
|
-
colSpan:
|
|
14026
|
+
colSpan: renderedColSpan,
|
|
12075
14027
|
className: "px-0 py-12 text-center",
|
|
12076
14028
|
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { "data-matrx-table-empty-state": true, className: "sticky left-0 flex flex-col items-center gap-2 whitespace-normal px-4", style: { width: "100cqw", maxWidth: "100%" }, children: [
|
|
12077
14029
|
renderedEmptyState?.icon,
|
|
@@ -12080,7 +14032,43 @@ function MatrxDataTableCore({
|
|
|
12080
14032
|
renderedEmptyState?.action
|
|
12081
14033
|
] })
|
|
12082
14034
|
}
|
|
12083
|
-
) }) :
|
|
14035
|
+
) }) : bodyEntries.map((entry) => {
|
|
14036
|
+
if (entry.kind === "spacer") {
|
|
14037
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
14038
|
+
"tr",
|
|
14039
|
+
{
|
|
14040
|
+
"aria-hidden": "true",
|
|
14041
|
+
"data-matrx-table-virtual-spacer": entry.place,
|
|
14042
|
+
style: { height: `${entry.height}px` },
|
|
14043
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
14044
|
+
"td",
|
|
14045
|
+
{
|
|
14046
|
+
className: "border-0 p-0",
|
|
14047
|
+
colSpan: renderedColSpan
|
|
14048
|
+
}
|
|
14049
|
+
)
|
|
14050
|
+
},
|
|
14051
|
+
`matrx-virtual-spacer-${entry.place}`
|
|
14052
|
+
);
|
|
14053
|
+
}
|
|
14054
|
+
if (entry.kind === "group") {
|
|
14055
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
14056
|
+
TableGroupHeaderRow,
|
|
14057
|
+
{
|
|
14058
|
+
group: entry.group,
|
|
14059
|
+
collapsed: entry.collapsed,
|
|
14060
|
+
columns: renderedColumns,
|
|
14061
|
+
spacers: columnSpacers,
|
|
14062
|
+
leadingCols,
|
|
14063
|
+
showActionsCol,
|
|
14064
|
+
rowNoun: grouping?.rowNoun ?? "row",
|
|
14065
|
+
onToggle: () => setCollapsedGroups(toggleGroupCollapsed(collapsedGroups, entry.group.key))
|
|
14066
|
+
},
|
|
14067
|
+
`matrx-group-${entry.group.key}`
|
|
14068
|
+
);
|
|
14069
|
+
}
|
|
14070
|
+
const row = entry.row;
|
|
14071
|
+
const index = entry.index;
|
|
12084
14072
|
const id = getRowId(row);
|
|
12085
14073
|
const isSelected = selectedId === id;
|
|
12086
14074
|
const rowEdits = edits[id];
|
|
@@ -12091,6 +14079,7 @@ function MatrxDataTableCore({
|
|
|
12091
14079
|
"tr",
|
|
12092
14080
|
{
|
|
12093
14081
|
"data-row-id": id,
|
|
14082
|
+
style: explicitRowHeight !== void 0 ? { height: `${explicitRowHeight}px` } : virtualizeActive ? { height: `${virtualRowHeight}px` } : void 0,
|
|
12094
14083
|
"data-state": isSelected ? "selected" : void 0,
|
|
12095
14084
|
onClick: (e) => {
|
|
12096
14085
|
if (rowEventTargetsInteractiveDescendant(e.target)) return;
|
|
@@ -12163,15 +14152,40 @@ function MatrxDataTableCore({
|
|
|
12163
14152
|
) : null
|
|
12164
14153
|
}
|
|
12165
14154
|
) : null,
|
|
12166
|
-
|
|
14155
|
+
columnSpacers && columnSpacers.start > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
14156
|
+
"td",
|
|
14157
|
+
{
|
|
14158
|
+
"aria-hidden": "true",
|
|
14159
|
+
"data-matrx-table-column-spacer": "start",
|
|
14160
|
+
className: "border-0 p-0",
|
|
14161
|
+
style: { width: `${columnSpacers.start}px`, minWidth: `${columnSpacers.start}px` }
|
|
14162
|
+
},
|
|
14163
|
+
"matrx-column-spacer-start"
|
|
14164
|
+
) : null,
|
|
14165
|
+
renderedColumns.map((col, colIdx) => {
|
|
12167
14166
|
const isColumnDragShadow = columnDragPreview?.draggedId === columnId(col) && columnDragPreview.targetId !== null;
|
|
12168
|
-
|
|
14167
|
+
const sheetCell = spreadsheetEnabled ? sheet.cellProps(id, columnId(col)) : null;
|
|
14168
|
+
const carriesFillHandle = sheetCell !== null && sheet.isFillHandleCell(id, columnId(col));
|
|
14169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
12169
14170
|
"td",
|
|
12170
14171
|
{
|
|
12171
14172
|
"data-matrx-table-column-id": columnId(col),
|
|
12172
14173
|
"data-matrx-column-drag-shadow": isColumnDragShadow ? "true" : void 0,
|
|
14174
|
+
...sheetCell ? {
|
|
14175
|
+
"data-matrx-cell-row": sheetCell["data-matrx-cell-row"],
|
|
14176
|
+
"data-matrx-cell-col": sheetCell["data-matrx-cell-col"],
|
|
14177
|
+
...sheetCell["data-matrx-cell-selected"] ? { "data-matrx-cell-selected": "true" } : {},
|
|
14178
|
+
...sheetCell["data-matrx-cell-active"] ? { "data-matrx-cell-active": "true" } : {},
|
|
14179
|
+
...sheetCell["data-matrx-cell-fill-preview"] ? { "data-matrx-cell-fill-preview": "true" } : {},
|
|
14180
|
+
onMouseDown: sheetCell.onMouseDown,
|
|
14181
|
+
onMouseEnter: sheetCell.onMouseEnter
|
|
14182
|
+
} : {},
|
|
12173
14183
|
className: cn(
|
|
12174
14184
|
"py-1.5 align-middle lg:py-0.5",
|
|
14185
|
+
sheetCell?.["data-matrx-cell-selected"] && "bg-primary/10",
|
|
14186
|
+
sheetCell?.["data-matrx-cell-fill-preview"] && "ring-1 ring-inset ring-primary/40",
|
|
14187
|
+
sheetCell?.["data-matrx-cell-active"] && "relative z-10 ring-2 ring-inset ring-primary",
|
|
14188
|
+
carriesFillHandle && "relative",
|
|
12175
14189
|
col.compact || resolveColumnMarker(col) !== void 0 ? "px-1" : "px-2",
|
|
12176
14190
|
// nowrap (NOT truncate — truncate clips the cell and
|
|
12177
14191
|
// defeats w-max, killing the horizontal scroll).
|
|
@@ -12193,42 +14207,64 @@ function MatrxDataTableCore({
|
|
|
12193
14207
|
style: {
|
|
12194
14208
|
...columnWidthVar(
|
|
12195
14209
|
resolveColumnMarker(col) && col.width === void 0 ? 40 : col.width,
|
|
12196
|
-
|
|
14210
|
+
windowedWidthFor(columnId(col), col.width),
|
|
12197
14211
|
columnId(col),
|
|
12198
14212
|
resizableColumns && col.resizable !== false
|
|
12199
14213
|
),
|
|
12200
14214
|
...frozenStyle(columnId(col))
|
|
12201
14215
|
},
|
|
12202
|
-
children:
|
|
12203
|
-
|
|
12204
|
-
|
|
12205
|
-
|
|
12206
|
-
|
|
12207
|
-
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
|
|
12211
|
-
|
|
12212
|
-
|
|
12213
|
-
|
|
12214
|
-
|
|
12215
|
-
|
|
12216
|
-
|
|
12217
|
-
|
|
12218
|
-
|
|
12219
|
-
|
|
12220
|
-
|
|
12221
|
-
|
|
12222
|
-
|
|
12223
|
-
|
|
12224
|
-
|
|
12225
|
-
|
|
12226
|
-
|
|
12227
|
-
|
|
14216
|
+
children: [
|
|
14217
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
14218
|
+
"div",
|
|
14219
|
+
{
|
|
14220
|
+
className: cn(
|
|
14221
|
+
colIdx === 0 && hierarchy && "flex min-w-0 items-center"
|
|
14222
|
+
),
|
|
14223
|
+
children: [
|
|
14224
|
+
colIdx === 0 && hierarchy ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
14225
|
+
HierarchyDragHandle,
|
|
14226
|
+
{
|
|
14227
|
+
id,
|
|
14228
|
+
label: hierarchy.itemLabel?.(row) ?? "row",
|
|
14229
|
+
disabled: !(hierarchy.canReparent?.(row) ?? true)
|
|
14230
|
+
}
|
|
14231
|
+
) : null,
|
|
14232
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
14233
|
+
"div",
|
|
14234
|
+
{
|
|
14235
|
+
"data-matrx-cell-content": true,
|
|
14236
|
+
className: "min-w-0 max-w-full flex-1 whitespace-normal break-words [overflow-wrap:anywhere] sm:[&_*]:min-w-0 sm:[&_*]:whitespace-normal sm:[&_*]:[overflow-wrap:anywhere] sm:[&_.truncate]:whitespace-nowrap sm:[&_[data-slot=badge]]:whitespace-nowrap sm:[&_[data-slot=badge]]:[overflow-wrap:normal] sm:[&_[data-matrx-cell-control]]:w-max sm:[&_[data-matrx-cell-control]]:min-w-max sm:[&_[data-matrx-cell-control]]:max-w-none sm:[&_[data-matrx-cell-control]]:whitespace-nowrap sm:[&_[data-matrx-cell-control]]:[overflow-wrap:normal] sm:[&_[data-matrx-cell-control]_*]:whitespace-nowrap sm:[&_[data-matrx-cell-control]_*]:[overflow-wrap:normal]",
|
|
14237
|
+
children: renderRecordCell(row, col, index)
|
|
14238
|
+
}
|
|
14239
|
+
)
|
|
14240
|
+
]
|
|
14241
|
+
}
|
|
14242
|
+
),
|
|
14243
|
+
carriesFillHandle ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
14244
|
+
"button",
|
|
14245
|
+
{
|
|
14246
|
+
type: "button",
|
|
14247
|
+
"data-matrx-table-fill-handle": true,
|
|
14248
|
+
"aria-label": "Drag to fill the cells below or beside this selection",
|
|
14249
|
+
onMouseDown: sheet.startFillDrag,
|
|
14250
|
+
className: "absolute -bottom-[3px] -right-[3px] z-20 h-2 w-2 cursor-crosshair rounded-[1px] border border-background bg-primary"
|
|
14251
|
+
}
|
|
14252
|
+
) : null
|
|
14253
|
+
]
|
|
12228
14254
|
},
|
|
12229
14255
|
columnId(col)
|
|
12230
14256
|
);
|
|
12231
14257
|
}),
|
|
14258
|
+
columnSpacers && columnSpacers.end > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
14259
|
+
"td",
|
|
14260
|
+
{
|
|
14261
|
+
"aria-hidden": "true",
|
|
14262
|
+
"data-matrx-table-column-spacer": "end",
|
|
14263
|
+
className: "border-0 p-0",
|
|
14264
|
+
style: { width: `${columnSpacers.end}px`, minWidth: `${columnSpacers.end}px` }
|
|
14265
|
+
},
|
|
14266
|
+
"matrx-column-spacer-end"
|
|
14267
|
+
) : null,
|
|
12232
14268
|
showActionsCol && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
12233
14269
|
"td",
|
|
12234
14270
|
{
|
|
@@ -12291,7 +14327,7 @@ function MatrxDataTableCore({
|
|
|
12291
14327
|
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
12292
14328
|
"td",
|
|
12293
14329
|
{
|
|
12294
|
-
colSpan:
|
|
14330
|
+
colSpan: renderedColSpan,
|
|
12295
14331
|
className: "p-4",
|
|
12296
14332
|
children: expandedDetail.render(displayRow, controls)
|
|
12297
14333
|
}
|
|
@@ -12299,7 +14335,7 @@ function MatrxDataTableCore({
|
|
|
12299
14335
|
},
|
|
12300
14336
|
`${id}:expanded-detail`
|
|
12301
14337
|
) : null;
|
|
12302
|
-
return hierarchy ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
14338
|
+
return hierarchy ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react21.Fragment, { children: [
|
|
12303
14339
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
12304
14340
|
HierarchyDroppableRow,
|
|
12305
14341
|
{
|
|
@@ -12309,7 +14345,7 @@ function MatrxDataTableCore({
|
|
|
12309
14345
|
}
|
|
12310
14346
|
),
|
|
12311
14347
|
inlineDetail
|
|
12312
|
-
] }, id) : /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
14348
|
+
] }, id) : /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react21.Fragment, { children: [
|
|
12313
14349
|
wrappedRow,
|
|
12314
14350
|
inlineDetail
|
|
12315
14351
|
] }, id);
|
|
@@ -12317,7 +14353,7 @@ function MatrxDataTableCore({
|
|
|
12317
14353
|
appendQuery !== null && isFetching && !isLoading ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("tr", { "data-matrx-table-append-loading-row": true, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
12318
14354
|
"td",
|
|
12319
14355
|
{
|
|
12320
|
-
colSpan:
|
|
14356
|
+
colSpan: renderedColSpan,
|
|
12321
14357
|
className: "sticky bottom-0 z-20 h-16 border-y border-border bg-card/95 px-0 py-0 text-left shadow-sm backdrop-blur-sm",
|
|
12322
14358
|
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
12323
14359
|
"div",
|
|
@@ -12342,7 +14378,17 @@ function MatrxDataTableCore({
|
|
|
12342
14378
|
] }),
|
|
12343
14379
|
footerRows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("tfoot", { className: "border-t-2 border-border bg-muted/50 font-semibold", children: footerRows.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("tr", { children: [
|
|
12344
14380
|
selection ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("td", { className: "px-2 py-2" }) : null,
|
|
12345
|
-
|
|
14381
|
+
columnSpacers && columnSpacers.start > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
14382
|
+
"td",
|
|
14383
|
+
{
|
|
14384
|
+
"aria-hidden": "true",
|
|
14385
|
+
"data-matrx-table-column-spacer": "start",
|
|
14386
|
+
className: "border-0 p-0",
|
|
14387
|
+
style: { width: `${columnSpacers.start}px`, minWidth: `${columnSpacers.start}px` }
|
|
14388
|
+
},
|
|
14389
|
+
"matrx-column-spacer-start"
|
|
14390
|
+
) : null,
|
|
14391
|
+
renderedColumns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
12346
14392
|
"td",
|
|
12347
14393
|
{
|
|
12348
14394
|
className: cn(
|
|
@@ -12354,7 +14400,7 @@ function MatrxDataTableCore({
|
|
|
12354
14400
|
),
|
|
12355
14401
|
style: columnWidthVar(
|
|
12356
14402
|
resolveColumnMarker(column) && column.width === void 0 ? 40 : column.width,
|
|
12357
|
-
|
|
14403
|
+
windowedWidthFor(columnId(column), column.width),
|
|
12358
14404
|
columnId(column),
|
|
12359
14405
|
resizableColumns && column.resizable !== false
|
|
12360
14406
|
),
|
|
@@ -12362,6 +14408,16 @@ function MatrxDataTableCore({
|
|
|
12362
14408
|
},
|
|
12363
14409
|
columnId(column)
|
|
12364
14410
|
)),
|
|
14411
|
+
columnSpacers && columnSpacers.end > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
14412
|
+
"td",
|
|
14413
|
+
{
|
|
14414
|
+
"aria-hidden": "true",
|
|
14415
|
+
"data-matrx-table-column-spacer": "end",
|
|
14416
|
+
className: "border-0 p-0",
|
|
14417
|
+
style: { width: `${columnSpacers.end}px`, minWidth: `${columnSpacers.end}px` }
|
|
14418
|
+
},
|
|
14419
|
+
"matrx-column-spacer-end"
|
|
14420
|
+
) : null,
|
|
12365
14421
|
showActionsCol ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("td", {}) : null
|
|
12366
14422
|
] }, `footer-${index}`)) }) : null
|
|
12367
14423
|
]
|
|
@@ -12536,7 +14592,73 @@ function MatrxDataTableCore({
|
|
|
12536
14592
|
compact: true,
|
|
12537
14593
|
hideEntriesInfo: false
|
|
12538
14594
|
}
|
|
12539
|
-
) }) : null
|
|
14595
|
+
) }) : null,
|
|
14596
|
+
selection && selectionCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
14597
|
+
"div",
|
|
14598
|
+
{
|
|
14599
|
+
"data-matrx-table-bulk-bar": true,
|
|
14600
|
+
className: "mt-2 flex shrink-0 flex-wrap items-center gap-2 rounded-md border border-primary/30 bg-primary/5 px-2 py-1.5",
|
|
14601
|
+
children: [
|
|
14602
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "text-xs font-medium text-foreground", children: [
|
|
14603
|
+
(0, import_format5.formatCount)(selectionCount),
|
|
14604
|
+
" ",
|
|
14605
|
+
selectionNoun,
|
|
14606
|
+
selectionCount === 1 ? "" : "s",
|
|
14607
|
+
" selected"
|
|
14608
|
+
] }),
|
|
14609
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
14610
|
+
Button,
|
|
14611
|
+
{
|
|
14612
|
+
type: "button",
|
|
14613
|
+
variant: "ghost",
|
|
14614
|
+
size: "sm",
|
|
14615
|
+
className: "h-7 gap-1 px-2 text-xs",
|
|
14616
|
+
onClick: () => {
|
|
14617
|
+
lastToggledIndex.current = null;
|
|
14618
|
+
selection.onSelectedIdsChange([]);
|
|
14619
|
+
},
|
|
14620
|
+
children: [
|
|
14621
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(X, { className: "h-3.5 w-3.5" }),
|
|
14622
|
+
"Clear"
|
|
14623
|
+
]
|
|
14624
|
+
}
|
|
14625
|
+
),
|
|
14626
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "ml-auto flex flex-wrap items-center gap-1.5", children: [
|
|
14627
|
+
effectiveCopy && selectedRows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
14628
|
+
CopyButtons,
|
|
14629
|
+
{
|
|
14630
|
+
size: "icon",
|
|
14631
|
+
"data-matrx-table-icon-action": true,
|
|
14632
|
+
sourceId: `${tableCopySourceNamespace}:selection`,
|
|
14633
|
+
...effectiveCopy.references ? { references: effectiveCopy.references(selectedRows, data) } : {},
|
|
14634
|
+
...effectiveCopy.triggerVariant ? { triggerVariant: effectiveCopy.triggerVariant } : {},
|
|
14635
|
+
label: `${selectedRows.length} selected ${selectionNoun}${selectedRows.length === 1 ? "" : "s"}`,
|
|
14636
|
+
...copy === void 0 ? {} : {
|
|
14637
|
+
human: () => buildViewHuman(effectiveCopy, selectedRows, effectiveCopyColumns),
|
|
14638
|
+
json: () => selectedRows.map((row) => effectiveCopy.agentRow ? effectiveCopy.agentRow(row) : row)
|
|
14639
|
+
},
|
|
14640
|
+
agent: () => copy === void 0 ? buildDefaultTableViewAgentInput(effectiveCopy, selectedRows, data, declaredVisibleCopyColumns, { scope: "selected" }) : buildViewAgentInput(effectiveCopy, selectedRows, data, { scope: "selected" }),
|
|
14641
|
+
aiVariants: copySubsetVariantFor(
|
|
14642
|
+
() => selectedRows,
|
|
14643
|
+
"selected"
|
|
14644
|
+
),
|
|
14645
|
+
export: {
|
|
14646
|
+
items: [],
|
|
14647
|
+
sheetRows: () => selectedRows.map(
|
|
14648
|
+
(row) => projectDefaultTableCopyRow(row, declaredVisibleCopyColumns)
|
|
14649
|
+
),
|
|
14650
|
+
sheetColumns: () => declaredVisibleCopyColumns.map((column) => ({
|
|
14651
|
+
id: columnId(column),
|
|
14652
|
+
label: column.label ?? (typeof column.header === "string" ? column.header : columnId(column))
|
|
14653
|
+
}))
|
|
14654
|
+
}
|
|
14655
|
+
}
|
|
14656
|
+
) : null,
|
|
14657
|
+
selection.actions?.(selectedRows, selection.selectedIds)
|
|
14658
|
+
] })
|
|
14659
|
+
]
|
|
14660
|
+
}
|
|
14661
|
+
) : null
|
|
12540
14662
|
] }),
|
|
12541
14663
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
12542
14664
|
ColumnManager,
|
|
@@ -12818,7 +14940,7 @@ function HierarchyDragIndicatorLayer({
|
|
|
12818
14940
|
scrollRef,
|
|
12819
14941
|
resolve: resolve2
|
|
12820
14942
|
}) {
|
|
12821
|
-
const [indicator, setIndicator] = (0,
|
|
14943
|
+
const [indicator, setIndicator] = (0, import_react21.useState)(
|
|
12822
14944
|
null
|
|
12823
14945
|
);
|
|
12824
14946
|
(0, import_core3.useDndMonitor)({
|
|
@@ -12922,9 +15044,9 @@ function HierarchyDroppableRow({
|
|
|
12922
15044
|
children
|
|
12923
15045
|
}) {
|
|
12924
15046
|
const { setNodeRef } = (0, import_core3.useDroppable)({ id, disabled });
|
|
12925
|
-
if (!(0,
|
|
15047
|
+
if (!(0, import_react21.isValidElement)(children) || children.type !== "tr") return children;
|
|
12926
15048
|
const row = children;
|
|
12927
|
-
return (0,
|
|
15049
|
+
return (0, import_react21.cloneElement)(row, {
|
|
12928
15050
|
ref: setNodeRef,
|
|
12929
15051
|
className: row.props.className
|
|
12930
15052
|
});
|
|
@@ -12959,6 +15081,71 @@ function normalizeColumnWidthsForColumns(widths, columns) {
|
|
|
12959
15081
|
})
|
|
12960
15082
|
);
|
|
12961
15083
|
}
|
|
15084
|
+
function TableGroupHeaderRow({
|
|
15085
|
+
group,
|
|
15086
|
+
collapsed,
|
|
15087
|
+
columns,
|
|
15088
|
+
spacers,
|
|
15089
|
+
leadingCols,
|
|
15090
|
+
showActionsCol,
|
|
15091
|
+
rowNoun,
|
|
15092
|
+
onToggle
|
|
15093
|
+
}) {
|
|
15094
|
+
const count = group.rows.length;
|
|
15095
|
+
const summary = `${count.toLocaleString()} ${count === 1 ? rowNoun : `${rowNoun}s`}`;
|
|
15096
|
+
const firstId = columns[0] ? columnId(columns[0]) : null;
|
|
15097
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
15098
|
+
"tr",
|
|
15099
|
+
{
|
|
15100
|
+
"data-matrx-table-group-row": group.key,
|
|
15101
|
+
"data-matrx-table-group-collapsed": collapsed ? "true" : "false",
|
|
15102
|
+
className: "border-y border-border bg-muted/40",
|
|
15103
|
+
children: [
|
|
15104
|
+
Array.from({ length: leadingCols }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("td", { className: "px-2 py-1.5" }, `group-lead-${i}`)),
|
|
15105
|
+
spacers && spacers.start > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("td", { "aria-hidden": "true", className: "border-0 p-0", style: { width: `${spacers.start}px` } }) : null,
|
|
15106
|
+
columns.map((col) => {
|
|
15107
|
+
const id = columnId(col);
|
|
15108
|
+
const aggregate = group.aggregates[id];
|
|
15109
|
+
if (id === firstId) {
|
|
15110
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("td", { className: cn("px-2 py-1.5 align-middle", col.mobileHidden && "max-sm:hidden"), children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
15111
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
15112
|
+
"button",
|
|
15113
|
+
{
|
|
15114
|
+
type: "button",
|
|
15115
|
+
onClick: onToggle,
|
|
15116
|
+
"aria-expanded": !collapsed,
|
|
15117
|
+
"aria-label": `${collapsed ? "Show" : "Hide"} ${group.label}`,
|
|
15118
|
+
className: "inline-flex h-5 w-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
15119
|
+
children: collapsed ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ChevronRight, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ChevronDown, { className: "h-4 w-4" })
|
|
15120
|
+
}
|
|
15121
|
+
),
|
|
15122
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "truncate text-sm font-semibold text-foreground", children: group.label }),
|
|
15123
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "whitespace-nowrap text-xs text-muted-foreground", children: summary })
|
|
15124
|
+
] }) }, id);
|
|
15125
|
+
}
|
|
15126
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
15127
|
+
"td",
|
|
15128
|
+
{
|
|
15129
|
+
className: cn(
|
|
15130
|
+
"px-2 py-1.5 align-middle text-xs font-medium text-muted-foreground",
|
|
15131
|
+
// A subtotal lines up with the numbers it is a subtotal OF.
|
|
15132
|
+
// Left-aligned under a right-aligned money column it reads as a
|
|
15133
|
+
// different column's value.
|
|
15134
|
+
alignForFormat(col) === "center" && "text-center",
|
|
15135
|
+
alignForFormat(col) === "right" && "text-right",
|
|
15136
|
+
col.mobileHidden && "max-sm:hidden"
|
|
15137
|
+
),
|
|
15138
|
+
children: aggregate ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { "data-matrx-table-group-aggregate": id, className: "whitespace-nowrap", children: aggregate.label }) : null
|
|
15139
|
+
},
|
|
15140
|
+
id
|
|
15141
|
+
);
|
|
15142
|
+
}),
|
|
15143
|
+
spacers && spacers.end > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("td", { "aria-hidden": "true", className: "border-0 p-0", style: { width: `${spacers.end}px` } }) : null,
|
|
15144
|
+
showActionsCol ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("td", { className: "px-2 py-1.5" }) : null
|
|
15145
|
+
]
|
|
15146
|
+
}
|
|
15147
|
+
);
|
|
15148
|
+
}
|
|
12962
15149
|
function columnWidthVar(width, resizedWidth, id, resizable) {
|
|
12963
15150
|
if (width === void 0 && resizedWidth === void 0 && !resizable) return void 0;
|
|
12964
15151
|
const inferredWidth = resizable && inferTableSearchRole(id) === "name" ? "12rem" : "auto";
|
|
@@ -12968,7 +15155,7 @@ function columnWidthVar(width, resizedWidth, id, resizable) {
|
|
|
12968
15155
|
};
|
|
12969
15156
|
}
|
|
12970
15157
|
function DefaultJsonCell({ value }) {
|
|
12971
|
-
const [open, setOpen] = (0,
|
|
15158
|
+
const [open, setOpen] = (0, import_react21.useState)(false);
|
|
12972
15159
|
const host = useMatrxDataTableHost();
|
|
12973
15160
|
const Viewer = host.JsonViewer;
|
|
12974
15161
|
const text = JSON.stringify(value, null, 2);
|
|
@@ -13051,7 +15238,7 @@ function resolveStringTitle(title, fallback) {
|
|
|
13051
15238
|
}
|
|
13052
15239
|
|
|
13053
15240
|
// src/data-table/SavedViewsControl.tsx
|
|
13054
|
-
var
|
|
15241
|
+
var import_react22 = require("react");
|
|
13055
15242
|
|
|
13056
15243
|
// src/dropdown-menu.tsx
|
|
13057
15244
|
var DropdownMenuPrimitive = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
|
|
@@ -13194,11 +15381,11 @@ function SavedViewsControl({
|
|
|
13194
15381
|
onUpdate,
|
|
13195
15382
|
onReload
|
|
13196
15383
|
}) {
|
|
13197
|
-
const unsavedChangesId = (0,
|
|
13198
|
-
const [saveOpen, setSaveOpen] = (0,
|
|
13199
|
-
const [name, setName] = (0,
|
|
13200
|
-
const [saving, setSaving] = (0,
|
|
13201
|
-
const [actionError, setActionError] = (0,
|
|
15384
|
+
const unsavedChangesId = (0, import_react22.useId)();
|
|
15385
|
+
const [saveOpen, setSaveOpen] = (0, import_react22.useState)(false);
|
|
15386
|
+
const [name, setName] = (0, import_react22.useState)("");
|
|
15387
|
+
const [saving, setSaving] = (0, import_react22.useState)(false);
|
|
15388
|
+
const [actionError, setActionError] = (0, import_react22.useState)(null);
|
|
13202
15389
|
const visibleError = actionError ?? error;
|
|
13203
15390
|
const save = async () => {
|
|
13204
15391
|
const next = name.trim();
|