@ai-matrx/design-system 0.18.2 → 0.18.4
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 +24 -0
- package/README.md +22 -0
- package/dist/content-transfer.cjs +127 -30
- package/dist/content-transfer.cjs.map +1 -1
- package/dist/content-transfer.d.cts +2 -0
- package/dist/content-transfer.d.ts +2 -0
- package/dist/content-transfer.js +127 -30
- package/dist/content-transfer.js.map +1 -1
- 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 +127 -30
- package/dist/data-table/data-row-inspector.cjs.map +1 -1
- package/dist/data-table/data-row-inspector.js +127 -30
- package/dist/data-table/data-row-inspector.js.map +1 -1
- package/dist/data-table/data-row-window.cjs +127 -30
- package/dist/data-table/data-row-window.cjs.map +1 -1
- package/dist/data-table/data-row-window.js +127 -30
- 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/index.cjs +1158 -956
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.d.cts +23 -3
- package/dist/data-table/index.d.ts +23 -3
- package/dist/data-table/index.js +1158 -956
- package/dist/data-table/index.js.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/layered-filters.d.cts +1 -1
- package/dist/data-table/layered-filters.d.ts +1 -1
- package/dist/data-table/pagination.cjs +2 -2
- package/dist/data-table/pagination.cjs.map +1 -1
- package/dist/data-table/pagination.js +2 -2
- package/dist/data-table/pagination.js.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/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/xlsx.d.cts +1 -1
- package/dist/data-table/xlsx.d.ts +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/{types-CD4xGL5Z.d.cts → types-Bx9SfdJM.d.cts} +2 -0
- package/dist/{types-BhSkeZQ_.d.ts → types-DyByb6tW.d.ts} +2 -0
- package/package.json +1 -1
|
@@ -708,6 +708,10 @@ function materialIdentity(material) {
|
|
|
708
708
|
}
|
|
709
709
|
return `payload:${id}`;
|
|
710
710
|
}
|
|
711
|
+
function snapshotContent(snapshot) {
|
|
712
|
+
const { sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits } = snapshot;
|
|
713
|
+
return JSON.stringify({ sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits });
|
|
714
|
+
}
|
|
711
715
|
function useFence() {
|
|
712
716
|
const mounted = React7.useRef(true);
|
|
713
717
|
const nextId = React7.useRef(0);
|
|
@@ -810,7 +814,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
810
814
|
const captured = await material.capture(signal);
|
|
811
815
|
sourceMaterial = { id: captured.snapshot.sourceId, label: captured.snapshot.label, capture: async () => captured };
|
|
812
816
|
} else if ("kind" in material) {
|
|
813
|
-
sourceMaterial =
|
|
817
|
+
sourceMaterial = { id: materialIdentity(material), label: sourceLabel, capture: async () => (0, import_content_transfer.directSource)(material, { sourceId: materialIdentity(material), label: sourceLabel, ...applyMenuProjection && projection ? { projection } : {}, ...applyMenuProjection && sections ? { sections } : {} }) };
|
|
814
818
|
} else if (applyMenuProjection && (projection || sections)) {
|
|
815
819
|
sourceMaterial = {
|
|
816
820
|
id: material.id,
|
|
@@ -827,7 +831,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
827
831
|
} else {
|
|
828
832
|
sourceMaterial = material;
|
|
829
833
|
}
|
|
830
|
-
const raw =
|
|
834
|
+
const raw = await sourceMaterial.capture({ scope, signal });
|
|
831
835
|
const constrained = (0, import_content_transfer.resolveTransferPreferences)(providerPreferences, preferences, raw.snapshot.limits);
|
|
832
836
|
const result = await (0, import_content_transfer.capture)({ id: raw.snapshot.sourceId, label: raw.snapshot.label, capture: async () => ({ ...raw, snapshot: { ...raw.snapshot, limits: constrained.limits } }) }, signal, scope);
|
|
833
837
|
if (scope !== "all-matching" || !collectPages) return result;
|
|
@@ -887,31 +891,117 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
887
891
|
fence.finish(controller);
|
|
888
892
|
}
|
|
889
893
|
}, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
|
|
890
|
-
const openWorkspace = React7.useCallback(
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
const
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
894
|
+
const openWorkspace = React7.useCallback(
|
|
895
|
+
async (key = primaryWorkspaceKey, variant) => {
|
|
896
|
+
const variantMaterial = variant && "kind" in variant.source ? {
|
|
897
|
+
id: `variant:${key}`,
|
|
898
|
+
label: variant.label,
|
|
899
|
+
capture: async () => (0, import_content_transfer.directSource)(variant.source, {
|
|
900
|
+
sourceId: `variant:${key}`,
|
|
901
|
+
label: variant.label
|
|
902
|
+
})
|
|
903
|
+
} : variant?.source;
|
|
904
|
+
const captureWorkspace = (scope, signal, collectPages = true) => captureOne(variantMaterial ?? primary, scope, signal, true, collectPages);
|
|
905
|
+
workspaceCaptures.current.set(key, captureWorkspace);
|
|
906
|
+
const existing = workspaces[key];
|
|
907
|
+
const { controller, id } = fence.begin();
|
|
908
|
+
if (existing) {
|
|
909
|
+
try {
|
|
910
|
+
const allMatching = existing.scope === "all-matching";
|
|
911
|
+
const fresh = await captureWorkspace(
|
|
912
|
+
existing.scope,
|
|
913
|
+
controller.signal,
|
|
914
|
+
!allMatching
|
|
915
|
+
);
|
|
916
|
+
if (!fence.valid(id, controller) || !workspaceCaptures.current.has(key))
|
|
917
|
+
return;
|
|
918
|
+
if (allMatching && (!existing.allMatching || !fresh.allMatching))
|
|
919
|
+
throw new Error(
|
|
920
|
+
"This source can no longer provide an all-matching snapshot."
|
|
921
|
+
);
|
|
922
|
+
const collectionIdentity = (value) => value && {
|
|
923
|
+
query: value.source.query,
|
|
924
|
+
projection: value.projection,
|
|
925
|
+
columns: value.columns,
|
|
926
|
+
limits: value.limits
|
|
927
|
+
};
|
|
928
|
+
const changed = allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot);
|
|
929
|
+
setWorkspaces((current) => {
|
|
930
|
+
const retained = current[key];
|
|
931
|
+
if (!retained) return current;
|
|
932
|
+
return {
|
|
933
|
+
...current,
|
|
934
|
+
[key]: {
|
|
935
|
+
...retained,
|
|
936
|
+
error: fresh.collectionError,
|
|
937
|
+
...allMatching ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope: retained.scope } } : { pending: void 0 }
|
|
938
|
+
}
|
|
939
|
+
};
|
|
940
|
+
});
|
|
941
|
+
setWorkspaceKey(key);
|
|
942
|
+
setWorkspaceOpen(true);
|
|
943
|
+
} catch (error) {
|
|
944
|
+
if (fence.valid(id, controller) && workspaceCaptures.current.has(key)) {
|
|
945
|
+
setWorkspaces(
|
|
946
|
+
(current) => current[key] ? {
|
|
947
|
+
...current,
|
|
948
|
+
[key]: {
|
|
949
|
+
...current[key],
|
|
950
|
+
error: errorMessage(error, "Could not refresh source")
|
|
951
|
+
}
|
|
952
|
+
} : current
|
|
953
|
+
);
|
|
954
|
+
setWorkspaceKey(key);
|
|
955
|
+
setWorkspaceOpen(true);
|
|
956
|
+
}
|
|
957
|
+
} finally {
|
|
958
|
+
fence.finish(controller);
|
|
959
|
+
}
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
try {
|
|
963
|
+
const result = await captureWorkspace(initialScope, controller.signal);
|
|
964
|
+
if (!fence.valid(id, controller)) return;
|
|
965
|
+
const resolved = (0, import_content_transfer.resolveTransferPreferences)(
|
|
966
|
+
providerPreferences,
|
|
967
|
+
preferences,
|
|
968
|
+
result.snapshot.limits
|
|
969
|
+
);
|
|
970
|
+
const original = (0, import_content_transfer.createDraft)(result.snapshot);
|
|
971
|
+
const base = {
|
|
972
|
+
...result,
|
|
973
|
+
key,
|
|
974
|
+
original,
|
|
975
|
+
draft: original,
|
|
976
|
+
scope: initialScope,
|
|
977
|
+
preferences: resolved,
|
|
978
|
+
...result.collectionError ? { error: result.collectionError } : {}
|
|
979
|
+
};
|
|
980
|
+
setWorkspaces((current) => ({
|
|
981
|
+
...current,
|
|
982
|
+
[key]: { ...base, draft: rebuild(base, initialControls(base)) }
|
|
983
|
+
}));
|
|
984
|
+
setWorkspaceKey(key);
|
|
985
|
+
setWorkspaceOpen(true);
|
|
986
|
+
} catch (error) {
|
|
987
|
+
if (fence.valid(id, controller))
|
|
988
|
+
setNotice(errorMessage(error, "Could not capture content"));
|
|
989
|
+
} finally {
|
|
990
|
+
fence.finish(controller);
|
|
991
|
+
}
|
|
992
|
+
},
|
|
993
|
+
[
|
|
994
|
+
captureOne,
|
|
995
|
+
capturePrimary,
|
|
996
|
+
fence,
|
|
997
|
+
initialScope,
|
|
998
|
+
preferences,
|
|
999
|
+
primaryWorkspaceKey,
|
|
1000
|
+
primary,
|
|
1001
|
+
providerPreferences,
|
|
1002
|
+
workspaces
|
|
1003
|
+
]
|
|
1004
|
+
);
|
|
915
1005
|
React7.useImperativeHandle(controllerRef, () => ({
|
|
916
1006
|
focusTrigger: () => triggerRef.current?.focus(),
|
|
917
1007
|
prepare: async (requestedSource, options) => {
|
|
@@ -1134,7 +1224,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1134
1224
|
setBusy("capture");
|
|
1135
1225
|
try {
|
|
1136
1226
|
const result = await captureScope(scope, controller.signal);
|
|
1137
|
-
if (fence.valid(id, controller) && latest.current.draft.revision === revision) onChange({ ...latest.current, pending: { ...result, scope }, error: result.collectionError });
|
|
1227
|
+
if (fence.valid(id, controller) && latest.current.draft.revision === revision) onChange({ ...latest.current, pending: { ...result, scope }, sourceStale: false, error: result.collectionError });
|
|
1138
1228
|
} catch (error) {
|
|
1139
1229
|
if (fence.valid(id, controller)) onChange({ ...latest.current, error: errorMessage(error, "Refresh failed") });
|
|
1140
1230
|
} finally {
|
|
@@ -1377,6 +1467,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1377
1467
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
|
|
1378
1468
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
|
|
1379
1469
|
] }) : null,
|
|
1470
|
+
state.sourceStale ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
|
|
1380
1471
|
state.pending ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
1381
1472
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "A fresh source snapshot is ready." }),
|
|
1382
1473
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
|
|
@@ -1483,6 +1574,7 @@ var actionDone = (message) => ({
|
|
|
1483
1574
|
mimeTypes: [],
|
|
1484
1575
|
message
|
|
1485
1576
|
});
|
|
1577
|
+
var isSafeFilename = (filename) => filename === filename.trim() && filename.length > 0 && !/^\.+$/.test(filename) && !/[\\/\x00-\x1F\x7F]/.test(filename);
|
|
1486
1578
|
var sourceFor = (id, label, build) => ({
|
|
1487
1579
|
id,
|
|
1488
1580
|
label,
|
|
@@ -1631,7 +1723,8 @@ function MatrxCopyMenuSession(props) {
|
|
|
1631
1723
|
value: {
|
|
1632
1724
|
bytes: Array.from(bytes),
|
|
1633
1725
|
mime: file.mime,
|
|
1634
|
-
extension: file.extension
|
|
1726
|
+
extension: file.extension,
|
|
1727
|
+
...file.filename !== void 0 ? { filename: file.filename } : {}
|
|
1635
1728
|
}
|
|
1636
1729
|
};
|
|
1637
1730
|
},
|
|
@@ -1648,12 +1741,16 @@ function MatrxCopyMenuSession(props) {
|
|
|
1648
1741
|
(byte) => typeof byte !== "number" || !Number.isInteger(byte) || byte < 0 || byte > 255
|
|
1649
1742
|
))
|
|
1650
1743
|
throw new Error(`${item.label} did not capture a valid file.`);
|
|
1744
|
+
if (value.filename !== void 0 && (typeof value.filename !== "string" || !isSafeFilename(value.filename)))
|
|
1745
|
+
throw new Error(
|
|
1746
|
+
`${item.label} has an unsafe filename. Use a nonempty basename without leading or trailing whitespace, dots only, path separators, or control characters.`
|
|
1747
|
+
);
|
|
1651
1748
|
if (draft.omissions.some((omission) => omission.reason !== "duplicate"))
|
|
1652
1749
|
throw new Error(
|
|
1653
1750
|
"This custom file exceeds the configured export limits or contains excluded content. Use a standard format or revise the source options."
|
|
1654
1751
|
);
|
|
1655
1752
|
const bytes = new Uint8Array(value.bytes);
|
|
1656
|
-
const filename = `${props.label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "export"}.${value.extension.replace(/[^a-zA-Z0-9.-]/g, "") || "bin"}`;
|
|
1753
|
+
const filename = typeof value.filename === "string" ? value.filename : `${props.label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "export"}.${value.extension.replace(/[^a-zA-Z0-9.-]/g, "") || "bin"}`;
|
|
1657
1754
|
return transport.download(
|
|
1658
1755
|
(0, import_content_transfer2.sealTransferArtifact)({
|
|
1659
1756
|
snapshotId: snapshot.id,
|