@ai-matrx/design-system 0.21.3 → 0.21.5
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 +4 -0
- package/dist/data-table/copy-helpers.d.cts +1 -1
- package/dist/data-table/copy-helpers.d.ts +1 -1
- package/dist/data-table/data-row-inspector.cjs +3 -0
- package/dist/data-table/data-row-inspector.cjs.map +1 -1
- package/dist/data-table/data-row-inspector.js +3 -0
- package/dist/data-table/data-row-inspector.js.map +1 -1
- package/dist/data-table/data-row-window.cjs +3 -0
- package/dist/data-table/data-row-window.cjs.map +1 -1
- package/dist/data-table/data-row-window.js +3 -0
- package/dist/data-table/data-row-window.js.map +1 -1
- package/dist/data-table/filter-engine.d.cts +1 -1
- package/dist/data-table/filter-engine.d.ts +1 -1
- package/dist/data-table/host.cjs +12 -1
- package/dist/data-table/host.cjs.map +1 -1
- package/dist/data-table/host.d.cts +19 -3
- package/dist/data-table/host.d.ts +19 -3
- package/dist/data-table/host.js +12 -1
- package/dist/data-table/host.js.map +1 -1
- package/dist/data-table/index.cjs +173 -56
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.d.cts +12 -4
- package/dist/data-table/index.d.ts +12 -4
- package/dist/data-table/index.js +202 -85
- package/dist/data-table/index.js.map +1 -1
- package/dist/data-table/infer-filter.cjs +16 -0
- package/dist/data-table/infer-filter.cjs.map +1 -1
- package/dist/data-table/infer-filter.d.cts +1 -1
- package/dist/data-table/infer-filter.d.ts +1 -1
- package/dist/data-table/infer-filter.js +16 -0
- package/dist/data-table/infer-filter.js.map +1 -1
- package/dist/data-table/layered-filters.d.cts +1 -1
- package/dist/data-table/layered-filters.d.ts +1 -1
- package/dist/data-table/pagination.cjs +3 -0
- package/dist/data-table/pagination.cjs.map +1 -1
- package/dist/data-table/pagination.js +3 -0
- package/dist/data-table/pagination.js.map +1 -1
- package/dist/data-table/query-control.cjs +19 -0
- package/dist/data-table/query-control.cjs.map +1 -1
- package/dist/data-table/query-control.d.cts +1 -1
- package/dist/data-table/query-control.d.ts +1 -1
- package/dist/data-table/query-control.js +19 -0
- package/dist/data-table/query-control.js.map +1 -1
- package/dist/data-table/types.cjs.map +1 -1
- package/dist/data-table/types.d.cts +1 -1
- package/dist/data-table/types.d.ts +1 -1
- package/dist/data-table/url-state.d.cts +1 -1
- package/dist/data-table/url-state.d.ts +1 -1
- package/dist/data-table/uuid-cell.cjs +3 -0
- package/dist/data-table/uuid-cell.cjs.map +1 -1
- package/dist/data-table/uuid-cell.js +3 -0
- package/dist/data-table/uuid-cell.js.map +1 -1
- package/dist/data-table/xlsx.d.cts +1 -1
- package/dist/data-table/xlsx.d.ts +1 -1
- package/dist/{types-JFlsIv-0.d.ts → types-Dpl8OW_m.d.ts} +26 -1
- package/dist/{types-BarjBFyG.d.cts → types-DsmrqJHN.d.cts} +26 -1
- package/package.json +1 -1
|
@@ -48,6 +48,7 @@ __export(data_table_exports, {
|
|
|
48
48
|
downloadTableAsXlsx: () => downloadTableAsXlsx,
|
|
49
49
|
filterKindLabel: () => filterKindLabel,
|
|
50
50
|
parseTableViewSnapshot: () => parseTableViewSnapshot,
|
|
51
|
+
resolveColumnMarker: () => resolveColumnMarker,
|
|
51
52
|
resolveFilterKind: () => resolveFilterKind,
|
|
52
53
|
rowsToCsvFromColumns: () => rowsToCsvFromColumns,
|
|
53
54
|
rowsToMarkdownTable: () => rowsToMarkdownTable,
|
|
@@ -1925,6 +1926,12 @@ function MatrxTableRowAlchemyScope({ value, children }) {
|
|
|
1925
1926
|
function useMatrxTableRowAlchemy() {
|
|
1926
1927
|
return (0, import_react5.useContext)(RowAlchemyContext);
|
|
1927
1928
|
}
|
|
1929
|
+
var ROW_CONTROLS_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.design-system.table-row-controls-context");
|
|
1930
|
+
var rowControlsRegistry = globalThis;
|
|
1931
|
+
var RowControlsContext = rowControlsRegistry[ROW_CONTROLS_SLOT] ??= (0, import_react5.createContext)(null);
|
|
1932
|
+
function MatrxTableRowControlsScope({ value, children }) {
|
|
1933
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(RowControlsContext.Provider, { value, children });
|
|
1934
|
+
}
|
|
1928
1935
|
|
|
1929
1936
|
// src/data-table/useTableNotice.tsx
|
|
1930
1937
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
@@ -5588,7 +5595,7 @@ var import_url_state3 = require("@ai-matrx/kit/url-state");
|
|
|
5588
5595
|
// src/data-table/RowAlchemyLauncher.tsx
|
|
5589
5596
|
var import_react12 = require("react");
|
|
5590
5597
|
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
5591
|
-
function MatrxTableRowAlchemyProvider({ copy, placement, children }) {
|
|
5598
|
+
function MatrxTableRowAlchemyProvider({ copy, placement, controls, children }) {
|
|
5592
5599
|
const controller = (0, import_react12.useRef)(null);
|
|
5593
5600
|
const { CopyControls } = useMatrxDataTableHost();
|
|
5594
5601
|
const [active, setActive] = (0, import_react12.useState)(false);
|
|
@@ -5605,6 +5612,7 @@ function MatrxTableRowAlchemyProvider({ copy, placement, children }) {
|
|
|
5605
5612
|
}, [active, placement]);
|
|
5606
5613
|
const value = {
|
|
5607
5614
|
copy,
|
|
5615
|
+
controls,
|
|
5608
5616
|
placement,
|
|
5609
5617
|
ready: active,
|
|
5610
5618
|
activate: () => setActive(true),
|
|
@@ -5767,6 +5775,34 @@ var CommandShortcut = ({
|
|
|
5767
5775
|
};
|
|
5768
5776
|
CommandShortcut.displayName = "CommandShortcut";
|
|
5769
5777
|
|
|
5778
|
+
// src/data-table/column-marker.ts
|
|
5779
|
+
var MARKER_ACCESSORS = {
|
|
5780
|
+
favorite: "favorite",
|
|
5781
|
+
is_favorite: "favorite",
|
|
5782
|
+
favourite: "favorite",
|
|
5783
|
+
is_favourite: "favorite",
|
|
5784
|
+
pinned: "pin",
|
|
5785
|
+
is_pinned: "pin"
|
|
5786
|
+
};
|
|
5787
|
+
function resolveColumnMarker(column) {
|
|
5788
|
+
if (column.marker === false) return void 0;
|
|
5789
|
+
if (column.marker) return column.marker;
|
|
5790
|
+
return column.accessorKey ? MARKER_ACCESSORS[column.accessorKey] : void 0;
|
|
5791
|
+
}
|
|
5792
|
+
function markerCopy(marker) {
|
|
5793
|
+
return marker === "favorite" ? {
|
|
5794
|
+
label: "Favorites",
|
|
5795
|
+
lowerLabel: "favorites",
|
|
5796
|
+
onlyLabel: "Favorites only",
|
|
5797
|
+
notLabel: "Not favorites"
|
|
5798
|
+
} : {
|
|
5799
|
+
label: "Pins",
|
|
5800
|
+
lowerLabel: "pins",
|
|
5801
|
+
onlyLabel: "Pins only",
|
|
5802
|
+
notLabel: "Not pinned"
|
|
5803
|
+
};
|
|
5804
|
+
}
|
|
5805
|
+
|
|
5770
5806
|
// src/data-table/ColumnHeaderCell.tsx
|
|
5771
5807
|
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
5772
5808
|
var HeaderButton = (0, import_react13.forwardRef)(({ dragDescription, "aria-describedby": tooltipDescription, ...props }, ref) => {
|
|
@@ -5799,6 +5835,7 @@ function ColumnHeaderCell({
|
|
|
5799
5835
|
align = "left",
|
|
5800
5836
|
className,
|
|
5801
5837
|
compact = false,
|
|
5838
|
+
marker,
|
|
5802
5839
|
filterApplyLabel,
|
|
5803
5840
|
filterShowCancel = false,
|
|
5804
5841
|
filterFooterHint,
|
|
@@ -5850,7 +5887,9 @@ function ColumnHeaderCell({
|
|
|
5850
5887
|
if (deferredFilter) setDraftFilter(next);
|
|
5851
5888
|
else onFilterChange(next);
|
|
5852
5889
|
};
|
|
5853
|
-
const
|
|
5890
|
+
const markerLabels = marker ? markerCopy(marker) : void 0;
|
|
5891
|
+
const accessibleLabel = markerLabels?.label ?? labelText;
|
|
5892
|
+
const menuLabel = accessibleLabel ? `Sort or filter ${accessibleLabel}` : "Sort or filter column";
|
|
5854
5893
|
const menuContent = /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
5855
5894
|
PopoverContent,
|
|
5856
5895
|
{
|
|
@@ -5879,7 +5918,7 @@ function ColumnHeaderCell({
|
|
|
5879
5918
|
onClick: onSortAsc,
|
|
5880
5919
|
children: [
|
|
5881
5920
|
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ArrowUp, { className: "h-3.5 w-3.5" }),
|
|
5882
|
-
"Sort ascending"
|
|
5921
|
+
markerLabels ? `${markerLabels.label} last` : "Sort ascending"
|
|
5883
5922
|
]
|
|
5884
5923
|
}
|
|
5885
5924
|
),
|
|
@@ -5892,7 +5931,7 @@ function ColumnHeaderCell({
|
|
|
5892
5931
|
onClick: onSortDesc,
|
|
5893
5932
|
children: [
|
|
5894
5933
|
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ArrowDown, { className: "h-3.5 w-3.5" }),
|
|
5895
|
-
"Sort descending"
|
|
5934
|
+
markerLabels ? `${markerLabels.label} first` : "Sort descending"
|
|
5896
5935
|
]
|
|
5897
5936
|
}
|
|
5898
5937
|
),
|
|
@@ -5905,7 +5944,7 @@ function ColumnHeaderCell({
|
|
|
5905
5944
|
onClick: onClearSort,
|
|
5906
5945
|
children: [
|
|
5907
5946
|
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ListX, { className: "h-3.5 w-3.5" }),
|
|
5908
|
-
"Clear sort"
|
|
5947
|
+
markerLabels ? `Clear ${markerLabels.lowerLabel} sort` : "Clear sort"
|
|
5909
5948
|
]
|
|
5910
5949
|
}
|
|
5911
5950
|
) : null
|
|
@@ -5924,6 +5963,13 @@ function ColumnHeaderCell({
|
|
|
5924
5963
|
},
|
|
5925
5964
|
selectOptions,
|
|
5926
5965
|
selectSingle,
|
|
5966
|
+
...markerLabels ? {
|
|
5967
|
+
booleanLabels: {
|
|
5968
|
+
all: "All",
|
|
5969
|
+
true: markerLabels.onlyLabel,
|
|
5970
|
+
false: markerLabels.notLabel
|
|
5971
|
+
}
|
|
5972
|
+
} : {},
|
|
5927
5973
|
allowNullModes
|
|
5928
5974
|
}
|
|
5929
5975
|
) : null,
|
|
@@ -6139,7 +6185,8 @@ function FilterBody({
|
|
|
6139
6185
|
onChange,
|
|
6140
6186
|
selectOptions,
|
|
6141
6187
|
selectSingle = false,
|
|
6142
|
-
allowNullModes = false
|
|
6188
|
+
allowNullModes = false,
|
|
6189
|
+
booleanLabels
|
|
6143
6190
|
}) {
|
|
6144
6191
|
if (kind === "text") {
|
|
6145
6192
|
const text = value?.kind === "text" ? value.value : "";
|
|
@@ -6226,9 +6273,9 @@ function FilterBody({
|
|
|
6226
6273
|
children: [
|
|
6227
6274
|
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SelectValue, {}) }),
|
|
6228
6275
|
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(SelectContent, { children: [
|
|
6229
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SelectItem, { value: "__all__", children: "All" }),
|
|
6230
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SelectItem, { value: "true", children: "Yes" }),
|
|
6231
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SelectItem, { value: "false", children: "No" })
|
|
6276
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SelectItem, { value: "__all__", children: booleanLabels?.all ?? "All" }),
|
|
6277
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SelectItem, { value: "true", children: booleanLabels?.true ?? "Yes" }),
|
|
6278
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SelectItem, { value: "false", children: booleanLabels?.false ?? "No" })
|
|
6232
6279
|
] })
|
|
6233
6280
|
]
|
|
6234
6281
|
}
|
|
@@ -7471,9 +7518,13 @@ function EditableTableCell({
|
|
|
7471
7518
|
onCommit,
|
|
7472
7519
|
className,
|
|
7473
7520
|
href,
|
|
7474
|
-
editTrigger = "click"
|
|
7521
|
+
editTrigger = "click",
|
|
7522
|
+
editRequest
|
|
7475
7523
|
}) {
|
|
7476
7524
|
const [open, setOpen] = (0, import_react18.useState)(false);
|
|
7525
|
+
(0, import_react18.useEffect)(() => {
|
|
7526
|
+
if (editRequest !== void 0) setOpen(true);
|
|
7527
|
+
}, [editRequest]);
|
|
7477
7528
|
const usePencil = Boolean(href) || editTrigger === "pencil";
|
|
7478
7529
|
if (editType === "string") {
|
|
7479
7530
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
@@ -7485,7 +7536,8 @@ function EditableTableCell({
|
|
|
7485
7536
|
onCommit,
|
|
7486
7537
|
...className === void 0 ? {} : { className },
|
|
7487
7538
|
...href === void 0 ? {} : { href },
|
|
7488
|
-
usePencil
|
|
7539
|
+
usePencil,
|
|
7540
|
+
...editRequest === void 0 ? {} : { editRequest }
|
|
7489
7541
|
}
|
|
7490
7542
|
);
|
|
7491
7543
|
}
|
|
@@ -7560,10 +7612,18 @@ function InlineStringEditor({
|
|
|
7560
7612
|
onCommit,
|
|
7561
7613
|
className,
|
|
7562
7614
|
href,
|
|
7563
|
-
usePencil
|
|
7615
|
+
usePencil,
|
|
7616
|
+
editRequest
|
|
7564
7617
|
}) {
|
|
7565
7618
|
const [editing, setEditing] = (0, import_react18.useState)(false);
|
|
7566
7619
|
const [draft, setDraft] = (0, import_react18.useState)(value);
|
|
7620
|
+
const handledEditRequest = (0, import_react18.useRef)(void 0);
|
|
7621
|
+
(0, import_react18.useEffect)(() => {
|
|
7622
|
+
if (editRequest === void 0 || handledEditRequest.current === editRequest) return;
|
|
7623
|
+
handledEditRequest.current = editRequest;
|
|
7624
|
+
setDraft(value);
|
|
7625
|
+
setEditing(true);
|
|
7626
|
+
}, [editRequest, value]);
|
|
7567
7627
|
if (!editing) {
|
|
7568
7628
|
if (usePencil) {
|
|
7569
7629
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
@@ -8315,6 +8375,7 @@ var SELECT_CARDINALITY_CAP = 24;
|
|
|
8315
8375
|
function resolveFilterKind(col, sampleRows) {
|
|
8316
8376
|
if (col.filter === false) return null;
|
|
8317
8377
|
if (col.filter && col.filter !== "auto") return col.filter;
|
|
8378
|
+
if (resolveColumnMarker(col)) return "boolean";
|
|
8318
8379
|
const values = sampleRows.slice(0, 200).map((row) => getCellValue(row, col)).filter((v) => v != null);
|
|
8319
8380
|
if (values.length === 0) return "text";
|
|
8320
8381
|
if (values.every((v) => typeof v === "boolean")) return "boolean";
|
|
@@ -8380,6 +8441,9 @@ function resolveQueryFilterMeta(column, rows, controlled) {
|
|
|
8380
8441
|
};
|
|
8381
8442
|
}
|
|
8382
8443
|
if (column.filter === false) return { kind: null, options: [] };
|
|
8444
|
+
if (resolveColumnMarker(column) && (column.filter === void 0 || column.filter === "auto")) {
|
|
8445
|
+
return { kind: "boolean", options: [] };
|
|
8446
|
+
}
|
|
8383
8447
|
const declared = column.filter;
|
|
8384
8448
|
const kind = declared && declared !== "auto" ? declared : column.filterOptions?.length ? "select" : "text";
|
|
8385
8449
|
return {
|
|
@@ -8557,6 +8621,9 @@ function MatrxDataTableWithUrlState({
|
|
|
8557
8621
|
);
|
|
8558
8622
|
}
|
|
8559
8623
|
var COLUMN_REORDER_ACTIVATION_DISTANCE = 6;
|
|
8624
|
+
function TableContextPassthrough({ children }) {
|
|
8625
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_jsx_runtime41.Fragment, { children });
|
|
8626
|
+
}
|
|
8560
8627
|
function MatrxDataTableCore({
|
|
8561
8628
|
data: suppliedData,
|
|
8562
8629
|
columns,
|
|
@@ -8583,6 +8650,7 @@ function MatrxDataTableCore({
|
|
|
8583
8650
|
detail,
|
|
8584
8651
|
window: windowConfig,
|
|
8585
8652
|
copy,
|
|
8653
|
+
contextMenu,
|
|
8586
8654
|
rowCopyPlacement = "inline",
|
|
8587
8655
|
edit,
|
|
8588
8656
|
hierarchy,
|
|
@@ -8618,6 +8686,7 @@ function MatrxDataTableCore({
|
|
|
8618
8686
|
const isLoading = appendQuery ? appendQuery.pagination.loading : suppliedLoading;
|
|
8619
8687
|
const isFetching = appendQuery ? appendQuery.pagination.isFetchingNextPage : suppliedFetching;
|
|
8620
8688
|
const host = useMatrxDataTableHost();
|
|
8689
|
+
const ContextMenuBoundary = host.ContextMenuBoundary ?? TableContextPassthrough;
|
|
8621
8690
|
const resolvedDensity = density ?? host.defaultDensity ?? "normal";
|
|
8622
8691
|
const SavedViews = host.SavedViews;
|
|
8623
8692
|
const Link = host.Link ?? DefaultTableLink;
|
|
@@ -8766,6 +8835,8 @@ function MatrxDataTableCore({
|
|
|
8766
8835
|
const [editsByScope, setEditsByScope] = (0, import_react20.useState)({});
|
|
8767
8836
|
const editRevisionRef = (0, import_react20.useRef)({});
|
|
8768
8837
|
const [savingByScope, setSavingByScope] = (0, import_react20.useState)({});
|
|
8838
|
+
const savingScopesRef = (0, import_react20.useRef)(/* @__PURE__ */ new Set());
|
|
8839
|
+
const [editRequest, setEditRequest] = (0, import_react20.useState)(null);
|
|
8769
8840
|
const [confirmForeignDraftDiscard, setConfirmForeignDraftDiscard] = (0, import_react20.useState)(false);
|
|
8770
8841
|
const edits = editsByScope[editScopeKey]?.values ?? {};
|
|
8771
8842
|
const saving = (savingByScope[editScopeKey] ?? 0) > 0;
|
|
@@ -9187,6 +9258,7 @@ function MatrxDataTableCore({
|
|
|
9187
9258
|
[visibleColumns]
|
|
9188
9259
|
);
|
|
9189
9260
|
const tableCopySourceNamespace = (0, import_react20.useId)();
|
|
9261
|
+
const tableContextMenuInstanceId = (0, import_react20.useId)();
|
|
9190
9262
|
const tableDndContextId = (0, import_react20.useId)();
|
|
9191
9263
|
const defaultCopyTitle = toolbar?.title || "Table";
|
|
9192
9264
|
const defaultCopy = (0, import_react20.useMemo)(() => ({
|
|
@@ -9388,13 +9460,15 @@ function MatrxDataTableCore({
|
|
|
9388
9460
|
const showToolbarCopy = effectiveCopy !== void 0 && effectiveCopy.showToolbar !== false;
|
|
9389
9461
|
const renderRowActions = (row, controls) => {
|
|
9390
9462
|
const actions = rowActions?.(row, controls);
|
|
9391
|
-
|
|
9463
|
+
const scopedActions = /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(MatrxTableRowControlsScope, { value: controls, children: actions });
|
|
9464
|
+
if (!effectiveCopy || !showRowCopy) return scopedActions;
|
|
9392
9465
|
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
9393
9466
|
MatrxTableRowAlchemyProvider,
|
|
9394
9467
|
{
|
|
9395
9468
|
copy: tableRowCopyProps(effectiveCopy, row, `${tableCopySourceNamespace}:row:${getRowId(row)}`, copy === void 0 ? declaredVisibleCopyColumns : void 0),
|
|
9396
9469
|
placement: rowCopyInMenu ? "menu" : "inline",
|
|
9397
|
-
|
|
9470
|
+
controls,
|
|
9471
|
+
children: scopedActions
|
|
9398
9472
|
}
|
|
9399
9473
|
);
|
|
9400
9474
|
};
|
|
@@ -9511,6 +9585,37 @@ function MatrxDataTableCore({
|
|
|
9511
9585
|
return next;
|
|
9512
9586
|
});
|
|
9513
9587
|
};
|
|
9588
|
+
const beginRowEdit = (row) => {
|
|
9589
|
+
const column = visibleColumns.find(
|
|
9590
|
+
(candidate) => candidate.editable && (candidate.editableIf?.(row) ?? true)
|
|
9591
|
+
);
|
|
9592
|
+
if (!column) return;
|
|
9593
|
+
const field = column.accessorKey ? String(column.accessorKey) : columnId(column);
|
|
9594
|
+
setEditRequest((current) => ({
|
|
9595
|
+
rowId: getRowId(row),
|
|
9596
|
+
field,
|
|
9597
|
+
nonce: (current?.nonce ?? 0) + 1
|
|
9598
|
+
}));
|
|
9599
|
+
};
|
|
9600
|
+
const buildRecordControls = (row) => {
|
|
9601
|
+
const rowId = getRowId(row);
|
|
9602
|
+
const pending = edits[rowId];
|
|
9603
|
+
return {
|
|
9604
|
+
closeDetail: () => setSelectedId(null),
|
|
9605
|
+
openDetail: () => openDetail(row),
|
|
9606
|
+
openWindow: () => openWindow(row),
|
|
9607
|
+
closeWindow,
|
|
9608
|
+
hasPendingEdits: Boolean(pending),
|
|
9609
|
+
discardPendingEdits: () => discardRowEdits(rowId),
|
|
9610
|
+
...pending ? { cancelEdits: () => discardRowEdits(rowId) } : {},
|
|
9611
|
+
...pending && edit?.onSave && !edit.autoSave && !saving ? {
|
|
9612
|
+
saveEdits: () => handleSaveEdits(rowId)
|
|
9613
|
+
} : {},
|
|
9614
|
+
...editEnabled && visibleColumns.some(
|
|
9615
|
+
(column) => column.editable && (column.editableIf?.(row) ?? true)
|
|
9616
|
+
) ? { beginEdit: () => beginRowEdit(row) } : {}
|
|
9617
|
+
};
|
|
9618
|
+
};
|
|
9514
9619
|
const hierarchyRows = hierarchy?.rows ?? data;
|
|
9515
9620
|
const hierarchyGetParentId = hierarchy?.getParentId;
|
|
9516
9621
|
const hierarchyIndex = (0, import_react20.useMemo)(() => {
|
|
@@ -9682,15 +9787,18 @@ function MatrxDataTableCore({
|
|
|
9682
9787
|
}
|
|
9683
9788
|
setDraggedRowId(null);
|
|
9684
9789
|
};
|
|
9685
|
-
const handleSaveEdits = async () => {
|
|
9790
|
+
const handleSaveEdits = async (rowId) => {
|
|
9686
9791
|
if (!edit?.onSave || changeCount === 0) return;
|
|
9687
9792
|
const scope = editScopeKey;
|
|
9793
|
+
if (savingScopesRef.current.has(scope)) return;
|
|
9688
9794
|
const draft = editsByScope[scope];
|
|
9689
9795
|
if (!draft) return;
|
|
9690
|
-
const values = draft.values;
|
|
9691
|
-
|
|
9796
|
+
const values = rowId ? draft.values[rowId] ? { [rowId]: draft.values[rowId] } : {} : draft.values;
|
|
9797
|
+
if (Object.keys(values).length === 0) return;
|
|
9798
|
+
const revisions = rowId ? draft.revisions[rowId] ? { [rowId]: draft.revisions[rowId] } : {} : draft.revisions;
|
|
9692
9799
|
const rows = appendQueryKey === null ? data : draft.rows;
|
|
9693
9800
|
const save = edit.onSave;
|
|
9801
|
+
savingScopesRef.current.add(scope);
|
|
9694
9802
|
startSaving(scope);
|
|
9695
9803
|
try {
|
|
9696
9804
|
await Promise.resolve().then(() => save(values, rows));
|
|
@@ -9698,16 +9806,16 @@ function MatrxDataTableCore({
|
|
|
9698
9806
|
const currentDraft = current[scope];
|
|
9699
9807
|
if (!currentDraft) return current;
|
|
9700
9808
|
const nextValues = {};
|
|
9701
|
-
for (const [
|
|
9702
|
-
const savedRow = values[
|
|
9703
|
-
const savedRevisions = revisions[
|
|
9704
|
-
const currentRevisions = currentDraft.revisions[
|
|
9809
|
+
for (const [rowId2, rowValues] of Object.entries(currentDraft.values)) {
|
|
9810
|
+
const savedRow = values[rowId2];
|
|
9811
|
+
const savedRevisions = revisions[rowId2];
|
|
9812
|
+
const currentRevisions = currentDraft.revisions[rowId2];
|
|
9705
9813
|
const remaining = Object.fromEntries(
|
|
9706
9814
|
Object.entries(rowValues).filter(
|
|
9707
9815
|
([field]) => !Object.hasOwn(savedRow ?? {}, field) || currentRevisions?.[field] !== savedRevisions?.[field]
|
|
9708
9816
|
)
|
|
9709
9817
|
);
|
|
9710
|
-
if (Object.keys(remaining).length > 0) nextValues[
|
|
9818
|
+
if (Object.keys(remaining).length > 0) nextValues[rowId2] = remaining;
|
|
9711
9819
|
}
|
|
9712
9820
|
return { ...current, [scope]: { ...currentDraft, values: nextValues } };
|
|
9713
9821
|
});
|
|
@@ -9717,6 +9825,7 @@ function MatrxDataTableCore({
|
|
|
9717
9825
|
`Couldn't save: ${e instanceof Error ? e.message : String(e)}`
|
|
9718
9826
|
);
|
|
9719
9827
|
} finally {
|
|
9828
|
+
savingScopesRef.current.delete(scope);
|
|
9720
9829
|
finishSaving(scope);
|
|
9721
9830
|
}
|
|
9722
9831
|
};
|
|
@@ -9724,6 +9833,17 @@ function MatrxDataTableCore({
|
|
|
9724
9833
|
setEdits({});
|
|
9725
9834
|
edit?.onCancel?.();
|
|
9726
9835
|
};
|
|
9836
|
+
(0, import_react20.useEffect)(() => {
|
|
9837
|
+
if (!host.rowContextRegistry || !contextMenu && !host.createDefaultRowContext) return;
|
|
9838
|
+
return host.rowContextRegistry.register(tableContextMenuInstanceId, (rowId) => {
|
|
9839
|
+
const row = data.find((candidate) => getRowId(candidate) === rowId);
|
|
9840
|
+
if (!row) return null;
|
|
9841
|
+
const pending = edits[rowId];
|
|
9842
|
+
const displayRow = applyRowEdits(row, pending);
|
|
9843
|
+
const controls = buildRecordControls(displayRow);
|
|
9844
|
+
return contextMenu?.resolveRowContext(displayRow, controls) ?? host.createDefaultRowContext?.(displayRow, controls) ?? null;
|
|
9845
|
+
});
|
|
9846
|
+
}, [buildRecordControls, contextMenu, data, getRowId, host.createDefaultRowContext, host.rowContextRegistry, tableContextMenuInstanceId]);
|
|
9727
9847
|
const showActionsCol = windowEnabled || Boolean(rowActions) || showInlineRowCopy;
|
|
9728
9848
|
const selectedIdSet = (0, import_react20.useMemo)(
|
|
9729
9849
|
() => new Set(selection?.selectedIds ?? []),
|
|
@@ -9804,7 +9924,8 @@ function MatrxDataTableCore({
|
|
|
9804
9924
|
dirty: Boolean(rowEdits && field in rowEdits),
|
|
9805
9925
|
onCommit: (next) => commitCell(id, field, next),
|
|
9806
9926
|
...href === void 0 ? {} : { href },
|
|
9807
|
-
...col.editTrigger === void 0 ? {} : { editTrigger: col.editTrigger }
|
|
9927
|
+
...col.editTrigger === void 0 ? {} : { editTrigger: col.editTrigger },
|
|
9928
|
+
...editRequest?.rowId === id && editRequest.field === field ? { editRequest: editRequest.nonce } : {}
|
|
9808
9929
|
}
|
|
9809
9930
|
);
|
|
9810
9931
|
}
|
|
@@ -9914,7 +10035,7 @@ function MatrxDataTableCore({
|
|
|
9914
10035
|
},
|
|
9915
10036
|
[columns, commitColumnState, commitColumnWidths, controlledQuery, intelligentSearchEnabled, intelligentSearchScopes, toolbar]
|
|
9916
10037
|
);
|
|
9917
|
-
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
10038
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ContextMenuBoundary, { label: tableId ?? "Data table", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
9918
10039
|
import_core3.DndContext,
|
|
9919
10040
|
{
|
|
9920
10041
|
id: tableDndContextId,
|
|
@@ -10012,6 +10133,7 @@ function MatrxDataTableCore({
|
|
|
10012
10133
|
{
|
|
10013
10134
|
ref: rootRef,
|
|
10014
10135
|
"data-matrx-table": true,
|
|
10136
|
+
"data-matrx-table-id": tableContextMenuInstanceId,
|
|
10015
10137
|
"data-matrx-table-implementation": "@ai-matrx/design-system",
|
|
10016
10138
|
"data-matrx-table-density": resolvedDensity,
|
|
10017
10139
|
"data-url-state-table": urlState?.id,
|
|
@@ -10398,7 +10520,7 @@ function MatrxDataTableCore({
|
|
|
10398
10520
|
const id = getRowId(row);
|
|
10399
10521
|
const displayRow = applyRowEdits(row, edits[id]);
|
|
10400
10522
|
const selectable = selection?.isRowSelectable?.(row) ?? Boolean(selection);
|
|
10401
|
-
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
10523
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { "data-row-id": id, className: "contents", children: mobileCards(displayRow, index, {
|
|
10402
10524
|
renderCell: (columnKey) => {
|
|
10403
10525
|
const column = columns.find((candidate) => columnId(candidate) === columnKey);
|
|
10404
10526
|
return column ? renderRecordCell(row, column, index) : null;
|
|
@@ -10431,14 +10553,7 @@ function MatrxDataTableCore({
|
|
|
10431
10553
|
...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
|
|
10432
10554
|
}
|
|
10433
10555
|
) : null,
|
|
10434
|
-
renderRowActions(displayRow,
|
|
10435
|
-
closeDetail: () => setSelectedId(null),
|
|
10436
|
-
openDetail: () => openDetail(displayRow),
|
|
10437
|
-
openWindow: () => openWindow(displayRow),
|
|
10438
|
-
closeWindow,
|
|
10439
|
-
hasPendingEdits: Boolean(edits[id]),
|
|
10440
|
-
discardPendingEdits: () => discardRowEdits(id)
|
|
10441
|
-
})
|
|
10556
|
+
renderRowActions(displayRow, buildRecordControls(displayRow))
|
|
10442
10557
|
]
|
|
10443
10558
|
}
|
|
10444
10559
|
) : null
|
|
@@ -10570,6 +10685,10 @@ function MatrxDataTableCore({
|
|
|
10570
10685
|
const defaultSortDirection = col.defaultSortDirection ?? "asc";
|
|
10571
10686
|
const isColumnDragShadow = columnDragPreview?.draggedId === id && columnDragPreview.targetId !== null;
|
|
10572
10687
|
const columnResizable = resizableColumns && col.resizable !== false;
|
|
10688
|
+
const marker = resolveColumnMarker(col);
|
|
10689
|
+
const compact = col.compact || marker !== void 0;
|
|
10690
|
+
const width = marker && col.width === void 0 ? 40 : col.width;
|
|
10691
|
+
const minWidth = marker && col.minWidth === void 0 ? 40 : col.minWidth;
|
|
10573
10692
|
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
10574
10693
|
"th",
|
|
10575
10694
|
{
|
|
@@ -10581,7 +10700,7 @@ function MatrxDataTableCore({
|
|
|
10581
10700
|
// ICON COLUMN (MatrxColumnDef.compact): a 40px star
|
|
10582
10701
|
// column cannot honor `width: 40` while paying 16px of
|
|
10583
10702
|
// padding for a 14px glyph.
|
|
10584
|
-
|
|
10703
|
+
compact ? "px-1" : "px-2",
|
|
10585
10704
|
// An intentional mobile column set (see
|
|
10586
10705
|
// MatrxColumnDef.mobileHidden). CSS, not a JS
|
|
10587
10706
|
// breakpoint — no hydration mismatch, and the column
|
|
@@ -10592,13 +10711,13 @@ function MatrxDataTableCore({
|
|
|
10592
10711
|
// it, a crowded table crushes a declared 190px column to a
|
|
10593
10712
|
// few characters wide instead of using the canonical
|
|
10594
10713
|
// horizontal-scroll surface.
|
|
10595
|
-
(
|
|
10714
|
+
(width !== void 0 || columnResizable) && "sm:w-[var(--matrx-col-w)] sm:min-w-[var(--matrx-col-w)]",
|
|
10596
10715
|
col.headerClassName,
|
|
10597
10716
|
isColumnDragShadow && "bg-primary/10 shadow-[inset_2px_0_0_var(--primary),inset_-2px_0_0_var(--primary)]",
|
|
10598
10717
|
col.align === "center" && "text-center",
|
|
10599
10718
|
col.align === "right" && "text-right"
|
|
10600
10719
|
),
|
|
10601
|
-
style: columnWidthVar(
|
|
10720
|
+
style: columnWidthVar(width, effectiveColumnWidths[id], id, columnResizable),
|
|
10602
10721
|
children: [
|
|
10603
10722
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ColumnHeaderDropZone, { id, enabled: reorderableColumns, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
10604
10723
|
ColumnHeaderCell,
|
|
@@ -10633,7 +10752,8 @@ function MatrxDataTableCore({
|
|
|
10633
10752
|
allowNegation: filterUi?.allowNegation,
|
|
10634
10753
|
allowNullModes: filterUi?.allowNullModes,
|
|
10635
10754
|
align: col.align,
|
|
10636
|
-
compact
|
|
10755
|
+
compact,
|
|
10756
|
+
marker,
|
|
10637
10757
|
reorderColumn: reorderableColumns ? { id, label: headerLabel } : void 0
|
|
10638
10758
|
}
|
|
10639
10759
|
) }),
|
|
@@ -10643,12 +10763,12 @@ function MatrxDataTableCore({
|
|
|
10643
10763
|
columnId: id,
|
|
10644
10764
|
label: headerLabel,
|
|
10645
10765
|
tableRef,
|
|
10646
|
-
minWidth
|
|
10766
|
+
minWidth,
|
|
10647
10767
|
maxWidth: col.maxWidth,
|
|
10648
10768
|
onResizeStart: captureResizeGestureSnapshot,
|
|
10649
10769
|
onResizeCancel: clearResizeGestureSnapshot,
|
|
10650
|
-
onResizeCommit: (columnId2,
|
|
10651
|
-
{ ...effectiveColumnWidths, [columnId2]:
|
|
10770
|
+
onResizeCommit: (columnId2, width2) => commitColumnWidths(
|
|
10771
|
+
{ ...effectiveColumnWidths, [columnId2]: width2 },
|
|
10652
10772
|
true
|
|
10653
10773
|
)
|
|
10654
10774
|
}
|
|
@@ -10678,7 +10798,7 @@ function MatrxDataTableCore({
|
|
|
10678
10798
|
{
|
|
10679
10799
|
className: cn(
|
|
10680
10800
|
"py-2",
|
|
10681
|
-
col.compact ? "px-1" : "px-2",
|
|
10801
|
+
col.compact || resolveColumnMarker(col) !== void 0 ? "px-1" : "px-2",
|
|
10682
10802
|
col.mobileHidden && "max-sm:hidden"
|
|
10683
10803
|
),
|
|
10684
10804
|
children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Skeleton, { className: "h-5 w-full" })
|
|
@@ -10764,19 +10884,19 @@ function MatrxDataTableCore({
|
|
|
10764
10884
|
"data-matrx-column-drag-shadow": isColumnDragShadow ? "true" : void 0,
|
|
10765
10885
|
className: cn(
|
|
10766
10886
|
"py-1.5 align-middle lg:py-0.5",
|
|
10767
|
-
col.compact ? "px-1" : "px-2",
|
|
10887
|
+
col.compact || resolveColumnMarker(col) !== void 0 ? "px-1" : "px-2",
|
|
10768
10888
|
// nowrap (NOT truncate — truncate clips the cell and
|
|
10769
10889
|
// defeats w-max, killing the horizontal scroll).
|
|
10770
10890
|
"max-sm:whitespace-nowrap",
|
|
10771
10891
|
col.mobileHidden && "max-sm:hidden",
|
|
10772
|
-
(col.width !== void 0 || resizableColumns && col.resizable !== false) && "sm:w-[var(--matrx-col-w)] sm:min-w-[var(--matrx-col-w)] sm:max-w-[var(--matrx-col-w)]",
|
|
10892
|
+
((resolveColumnMarker(col) && col.width === void 0 ? 40 : col.width) !== void 0 || resizableColumns && col.resizable !== false) && "sm:w-[var(--matrx-col-w)] sm:min-w-[var(--matrx-col-w)] sm:max-w-[var(--matrx-col-w)]",
|
|
10773
10893
|
col.className,
|
|
10774
10894
|
isColumnDragShadow && "bg-primary/10 shadow-[inset_2px_0_0_var(--primary),inset_-2px_0_0_var(--primary)]",
|
|
10775
10895
|
col.align === "center" && "text-center",
|
|
10776
10896
|
col.align === "right" && "text-right"
|
|
10777
10897
|
),
|
|
10778
10898
|
style: columnWidthVar(
|
|
10779
|
-
col.width,
|
|
10899
|
+
resolveColumnMarker(col) && col.width === void 0 ? 40 : col.width,
|
|
10780
10900
|
effectiveColumnWidths[columnId(col)],
|
|
10781
10901
|
columnId(col),
|
|
10782
10902
|
resizableColumns && col.resizable !== false
|
|
@@ -10834,14 +10954,7 @@ function MatrxDataTableCore({
|
|
|
10834
10954
|
...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
|
|
10835
10955
|
}
|
|
10836
10956
|
) : null,
|
|
10837
|
-
renderRowActions(displayRow,
|
|
10838
|
-
closeDetail: () => setSelectedId(null),
|
|
10839
|
-
openDetail: () => openDetail(displayRow),
|
|
10840
|
-
openWindow: () => openWindow(displayRow),
|
|
10841
|
-
closeWindow,
|
|
10842
|
-
hasPendingEdits: Boolean(rowEdits),
|
|
10843
|
-
discardPendingEdits: () => discardRowEdits(id)
|
|
10844
|
-
}),
|
|
10957
|
+
renderRowActions(displayRow, buildRecordControls(displayRow)),
|
|
10845
10958
|
windowEnabled ? /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(Tooltip, { children: [
|
|
10846
10959
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
10847
10960
|
Button,
|
|
@@ -10915,13 +11028,13 @@ function MatrxDataTableCore({
|
|
|
10915
11028
|
{
|
|
10916
11029
|
className: cn(
|
|
10917
11030
|
"px-2 py-2 align-middle",
|
|
10918
|
-
column.compact && "px-1",
|
|
11031
|
+
(column.compact || resolveColumnMarker(column) !== void 0) && "px-1",
|
|
10919
11032
|
column.className,
|
|
10920
11033
|
column.align === "center" && "text-center",
|
|
10921
11034
|
column.align === "right" && "text-right"
|
|
10922
11035
|
),
|
|
10923
11036
|
style: columnWidthVar(
|
|
10924
|
-
column.width,
|
|
11037
|
+
resolveColumnMarker(column) && column.width === void 0 ? 40 : column.width,
|
|
10925
11038
|
effectiveColumnWidths[columnId(column)],
|
|
10926
11039
|
columnId(column),
|
|
10927
11040
|
resizableColumns && column.resizable !== false
|
|
@@ -11329,7 +11442,7 @@ function MatrxDataTableCore({
|
|
|
11329
11442
|
) : null })
|
|
11330
11443
|
]
|
|
11331
11444
|
}
|
|
11332
|
-
) });
|
|
11445
|
+
) }) });
|
|
11333
11446
|
}
|
|
11334
11447
|
function HierarchyDragHandle({
|
|
11335
11448
|
id,
|
|
@@ -11513,7 +11626,11 @@ function normalizeColumnWidthsForColumns(widths, columns) {
|
|
|
11513
11626
|
return Object.fromEntries(
|
|
11514
11627
|
Object.entries(normalized).map(([id, width]) => {
|
|
11515
11628
|
const column = byId.get(id);
|
|
11516
|
-
const
|
|
11629
|
+
const marker = column ? resolveColumnMarker(column) : void 0;
|
|
11630
|
+
const bounds = resolveColumnResizeBounds(
|
|
11631
|
+
marker && column?.minWidth === void 0 ? 40 : column?.minWidth,
|
|
11632
|
+
column?.maxWidth
|
|
11633
|
+
);
|
|
11517
11634
|
return [id, clampColumnWidth(width, bounds)];
|
|
11518
11635
|
})
|
|
11519
11636
|
);
|