@tensor_1/react 2.11.0 → 2.13.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/README.md +26 -1
- package/dist/ChartCore-Bt1C84ty.d.cts +22 -0
- package/dist/calendar-model.d.ts +31 -0
- package/dist/calendar-model.js +89 -0
- package/dist/chart-preset.cjs +168 -0
- package/dist/chart-preset.d.cts +9 -0
- package/dist/chart-preset.d.ts +9 -0
- package/dist/chart-preset.js +35 -0
- package/dist/chart.cjs +58 -32
- package/dist/chart.d.cts +6 -21
- package/dist/chart.d.ts +2 -1
- package/dist/color-model.d.ts +20 -0
- package/dist/color-model.js +74 -0
- package/dist/components/BrandProfiles.d.ts +45 -0
- package/dist/components/BrandProfiles.js +150 -0
- package/dist/components/BuilderCanvas.d.ts +34 -0
- package/dist/components/BuilderCanvas.js +117 -0
- package/dist/components/Chart.d.ts +6 -21
- package/dist/components/Chart.js +5 -76
- package/dist/components/ChartCore.d.ts +33 -0
- package/dist/components/ChartCore.js +100 -0
- package/dist/components/ColorPicker.d.ts +17 -0
- package/dist/components/ColorPicker.js +158 -0
- package/dist/components/DateRangePicker.d.ts +23 -0
- package/dist/components/DateRangePicker.js +123 -0
- package/dist/components/DiffViewer.d.ts +18 -0
- package/dist/components/DiffViewer.js +93 -0
- package/dist/components/Inbox.js +0 -1
- package/dist/components/LicensePositionBar.d.ts +17 -0
- package/dist/components/LicensePositionBar.js +50 -0
- package/dist/components/MatchReview.d.ts +39 -0
- package/dist/components/MatchReview.js +120 -0
- package/dist/components/Meter.js +0 -1
- package/dist/components/MetricInput.d.ts +23 -0
- package/dist/components/MetricInput.js +92 -0
- package/dist/components/NavFavourites.js +35 -108
- package/dist/components/RelationshipGraph.d.ts +30 -0
- package/dist/components/RelationshipGraph.js +138 -0
- package/dist/components/RuleBuilder.d.ts +45 -0
- package/dist/components/RuleBuilder.js +163 -0
- package/dist/components/SchedulingCalendar.d.ts +42 -0
- package/dist/components/SchedulingCalendar.js +124 -0
- package/dist/components/Segmented.js +3 -2
- package/dist/components/Table.d.ts +1 -1
- package/dist/components/Table.js +4 -3
- package/dist/components/Tabs.js +3 -2
- package/dist/diff-model.d.ts +23 -0
- package/dist/diff-model.js +50 -0
- package/dist/hooks/useTable.js +11 -7
- package/dist/hooks/useVirtualRows.d.ts +27 -0
- package/dist/hooks/useVirtualRows.js +50 -0
- package/dist/index.cjs +1930 -194
- package/dist/index.d.cts +464 -2
- package/dist/index.d.ts +19 -0
- package/dist/index.js +93 -1
- package/dist/json-value.d.ts +10 -0
- package/dist/json-value.js +19 -0
- package/dist/metric-model.d.ts +9 -0
- package/dist/metric-model.js +25 -0
- package/dist/relationship-graph-model.d.ts +31 -0
- package/dist/relationship-graph-model.js +68 -0
- package/dist/rule-builder-model.d.ts +41 -0
- package/dist/rule-builder-model.js +101 -0
- package/dist/table-engine.js +8 -6
- package/package.json +16 -2
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
function isJsonObject(value) {
|
|
2
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
function jsonEqual(a, b) {
|
|
5
|
+
if (a === b) return true;
|
|
6
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
7
|
+
return a.length === b.length && a.every((value, index) => jsonEqual(value, b[index]));
|
|
8
|
+
}
|
|
9
|
+
if (isJsonObject(a) && isJsonObject(b)) {
|
|
10
|
+
const aKeys = Object.keys(a).sort();
|
|
11
|
+
const bKeys = Object.keys(b).sort();
|
|
12
|
+
return aKeys.length === bKeys.length && aKeys.every((key, index) => key === bKeys[index] && jsonEqual(a[key], b[key]));
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
function classify(base, current, incoming) {
|
|
17
|
+
if (base === void 0) return "added";
|
|
18
|
+
if (incoming === void 0) return "removed";
|
|
19
|
+
const currentChanged = !jsonEqual(base, current);
|
|
20
|
+
const incomingChanged = !jsonEqual(base, incoming);
|
|
21
|
+
if (currentChanged && incomingChanged && !jsonEqual(current, incoming)) return "conflicted";
|
|
22
|
+
return "changed";
|
|
23
|
+
}
|
|
24
|
+
function buildThreeWayDiff(base, current, incoming, path = "$") {
|
|
25
|
+
if (jsonEqual(current, incoming)) return [];
|
|
26
|
+
if (isJsonObject(base) || isJsonObject(current) || isJsonObject(incoming)) {
|
|
27
|
+
const objects = [base, current, incoming].filter(isJsonObject);
|
|
28
|
+
const keys = [...new Set(objects.flatMap((value) => Object.keys(value)))].sort();
|
|
29
|
+
return keys.flatMap((key) => buildThreeWayDiff(
|
|
30
|
+
isJsonObject(base) ? base[key] : void 0,
|
|
31
|
+
isJsonObject(current) ? current[key] : void 0,
|
|
32
|
+
isJsonObject(incoming) ? incoming[key] : void 0,
|
|
33
|
+
`${path}.${key}`
|
|
34
|
+
));
|
|
35
|
+
}
|
|
36
|
+
return [{ path, kind: classify(base, current, incoming), base, current, incoming }];
|
|
37
|
+
}
|
|
38
|
+
function summarizeDiff(entries, resolutions = {}) {
|
|
39
|
+
const summary = { added: 0, removed: 0, changed: 0, conflicted: 0, resolved: 0, pending: 0 };
|
|
40
|
+
entries.forEach((entry) => {
|
|
41
|
+
summary[entry.kind] += 1;
|
|
42
|
+
if ((resolutions[entry.path] ?? "pending") === "pending") summary.pending += 1;
|
|
43
|
+
else summary.resolved += 1;
|
|
44
|
+
});
|
|
45
|
+
return summary;
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
buildThreeWayDiff,
|
|
49
|
+
summarizeDiff
|
|
50
|
+
};
|
package/dist/hooks/useTable.js
CHANGED
|
@@ -19,18 +19,22 @@ function useTable(data, options = {}) {
|
|
|
19
19
|
const [query, setQuery] = useState(() => options.initialQuery ?? "");
|
|
20
20
|
const [selected, setSelected] = useState(() => /* @__PURE__ */ new Set());
|
|
21
21
|
const [pinned, setPinned] = useState(() => new Set(options.initialPinned ?? []));
|
|
22
|
-
const
|
|
23
|
-
const filtered = applyFilters(data, filters);
|
|
24
|
-
const searched = searchRows(filtered, query, searchFields);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
const visibleRows = useMemo(() => {
|
|
23
|
+
const filtered = filters.length ? applyFilters(data, filters) : data;
|
|
24
|
+
const searched = query.trim() ? searchRows(filtered, query, searchFields) : filtered;
|
|
25
|
+
return sort.length ? multiSort(searched, sort) : searched;
|
|
26
|
+
}, [data, filters, query, searchFields, sort]);
|
|
27
|
+
const rows = useMemo(
|
|
28
|
+
() => pinned.size ? mergePinned(data, visibleRows, pinned, idField) : visibleRows.slice(),
|
|
29
|
+
[data, visibleRows, pinned, idField]
|
|
30
|
+
);
|
|
28
31
|
const pageIds = useMemo(() => rows.map((r) => String(r[idField])), [rows, idField]);
|
|
29
32
|
const selectAll = selectAllState(selected, pageIds);
|
|
30
33
|
const doToggleSort = useCallback((field, additive = false) => {
|
|
31
34
|
setSort((keys) => toggleSort(keys, field, additive));
|
|
32
35
|
}, []);
|
|
33
36
|
const toggleRow = useCallback((id) => setSelected((s) => toggleId(s, id)), []);
|
|
37
|
+
const isSelected = useCallback((id) => selected.has(id), [selected]);
|
|
34
38
|
const toggleAllRows = useCallback(() => setSelected((s) => togglePage(s, pageIds)), [pageIds]);
|
|
35
39
|
const clearSelection = useCallback(() => setSelected(/* @__PURE__ */ new Set()), []);
|
|
36
40
|
const togglePin = useCallback((id) => setPinned((s) => toggleId(s, id)), []);
|
|
@@ -54,7 +58,7 @@ function useTable(data, options = {}) {
|
|
|
54
58
|
setSort,
|
|
55
59
|
setFilters,
|
|
56
60
|
setQuery,
|
|
57
|
-
isSelected
|
|
61
|
+
isSelected,
|
|
58
62
|
toggleRow,
|
|
59
63
|
toggleAllRows,
|
|
60
64
|
clearSelection,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
interface UseVirtualRowsOptions {
|
|
4
|
+
/** Fixed rendered row height in pixels. */
|
|
5
|
+
rowHeight: number;
|
|
6
|
+
/** Rows rendered beyond each viewport edge. Default: 6. */
|
|
7
|
+
overscan?: number;
|
|
8
|
+
/** Render all rows at or below this count. Default: 100. */
|
|
9
|
+
threshold?: number;
|
|
10
|
+
}
|
|
11
|
+
interface UseVirtualRowsResult<T> {
|
|
12
|
+
/** Attach to the scrolling TableWrap. */
|
|
13
|
+
containerRef: RefObject<HTMLDivElement>;
|
|
14
|
+
rows: readonly T[];
|
|
15
|
+
startIndex: number;
|
|
16
|
+
padTop: number;
|
|
17
|
+
padBottom: number;
|
|
18
|
+
totalHeight: number;
|
|
19
|
+
virtualized: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Owns scroll/resize observation and exposes the small visible row window.
|
|
23
|
+
* Consumers render padTop/padBottom spacer rows inside their existing tbody.
|
|
24
|
+
*/
|
|
25
|
+
declare function useVirtualRows<T>(rows: readonly T[], { rowHeight, overscan, threshold }: UseVirtualRowsOptions): UseVirtualRowsResult<T>;
|
|
26
|
+
|
|
27
|
+
export { type UseVirtualRowsOptions, type UseVirtualRowsResult, useVirtualRows };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { shouldVirtualize, virtualWindow } from "../table-engine.js";
|
|
4
|
+
function useVirtualRows(rows, { rowHeight, overscan = 6, threshold = 100 }) {
|
|
5
|
+
const containerRef = useRef(null);
|
|
6
|
+
const [viewport, setViewport] = useState({ scrollTop: 0, height: 0 });
|
|
7
|
+
useLayoutEffect(() => {
|
|
8
|
+
const element = containerRef.current;
|
|
9
|
+
if (!element) return;
|
|
10
|
+
let frame = 0;
|
|
11
|
+
const commitMeasurement = () => {
|
|
12
|
+
const next = { scrollTop: element.scrollTop, height: element.clientHeight };
|
|
13
|
+
setViewport((current) => current.scrollTop === next.scrollTop && current.height === next.height ? current : next);
|
|
14
|
+
};
|
|
15
|
+
const measure = () => {
|
|
16
|
+
if (frame) return;
|
|
17
|
+
frame = requestAnimationFrame(() => {
|
|
18
|
+
frame = 0;
|
|
19
|
+
commitMeasurement();
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
commitMeasurement();
|
|
23
|
+
element.addEventListener("scroll", measure, { passive: true });
|
|
24
|
+
const observer = new ResizeObserver(measure);
|
|
25
|
+
observer.observe(element);
|
|
26
|
+
return () => {
|
|
27
|
+
element.removeEventListener("scroll", measure);
|
|
28
|
+
observer.disconnect();
|
|
29
|
+
if (frame) cancelAnimationFrame(frame);
|
|
30
|
+
};
|
|
31
|
+
}, []);
|
|
32
|
+
const enabled = viewport.height > 0 && shouldVirtualize(rows.length, threshold);
|
|
33
|
+
const window = useMemo(
|
|
34
|
+
() => enabled ? virtualWindow(viewport.scrollTop, viewport.height, rowHeight, rows.length, overscan) : { start: 0, end: rows.length, padTop: 0, padBottom: 0, total: rows.length * rowHeight },
|
|
35
|
+
[enabled, overscan, rowHeight, rows.length, viewport.height, viewport.scrollTop]
|
|
36
|
+
);
|
|
37
|
+
const visibleRows = useMemo(() => rows.slice(window.start, window.end), [rows, window.start, window.end]);
|
|
38
|
+
return {
|
|
39
|
+
containerRef,
|
|
40
|
+
rows: visibleRows,
|
|
41
|
+
startIndex: window.start,
|
|
42
|
+
padTop: window.padTop,
|
|
43
|
+
padBottom: window.padBottom,
|
|
44
|
+
totalHeight: window.total,
|
|
45
|
+
virtualized: enabled
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
useVirtualRows
|
|
50
|
+
};
|