@ai-matrx/canvas 0.5.0 → 0.5.1
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 +13 -0
- package/dist/react.cjs +76 -41
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +79 -43
- package/dist/react.js.map +1 -1
- package/dist/styles.css +2 -0
- package/package.json +1 -1
package/dist/react.d.cts
CHANGED
|
@@ -249,7 +249,7 @@ interface CanvasProviderProps extends CanvasHostPorts {
|
|
|
249
249
|
/** "auto": a pane with one tab shows a title instead of a tab strip. Default "auto". */
|
|
250
250
|
readonly tabStrip?: CanvasTabStripMode;
|
|
251
251
|
}
|
|
252
|
-
declare function CanvasProvider({ children, store, persistence, onError, hotkeys, windowId: windowIdProp, layoutRules, regionWidth, tabStrip,
|
|
252
|
+
declare function CanvasProvider({ children, store, persistence, onError, hotkeys, windowId: windowIdProp, layoutRules, regionWidth, tabStrip, itemActions, popOut, dockBack, showMenu, overlay, onNativeBodyFrame, }: CanvasProviderProps): react.JSX.Element;
|
|
253
253
|
/**
|
|
254
254
|
* Renders a subtree as ANOTHER window of the same canvas — the web host's
|
|
255
255
|
* pop-out panel: `<CanvasWindowScope windowId={id}><CanvasColumn placement="fill"/></CanvasWindowScope>`.
|
package/dist/react.d.ts
CHANGED
|
@@ -249,7 +249,7 @@ interface CanvasProviderProps extends CanvasHostPorts {
|
|
|
249
249
|
/** "auto": a pane with one tab shows a title instead of a tab strip. Default "auto". */
|
|
250
250
|
readonly tabStrip?: CanvasTabStripMode;
|
|
251
251
|
}
|
|
252
|
-
declare function CanvasProvider({ children, store, persistence, onError, hotkeys, windowId: windowIdProp, layoutRules, regionWidth, tabStrip,
|
|
252
|
+
declare function CanvasProvider({ children, store, persistence, onError, hotkeys, windowId: windowIdProp, layoutRules, regionWidth, tabStrip, itemActions, popOut, dockBack, showMenu, overlay, onNativeBodyFrame, }: CanvasProviderProps): react.JSX.Element;
|
|
253
253
|
/**
|
|
254
254
|
* Renders a subtree as ANOTHER window of the same canvas — the web host's
|
|
255
255
|
* pop-out panel: `<CanvasWindowScope windowId={id}><CanvasColumn placement="fill"/></CanvasWindowScope>`.
|
package/dist/react.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
createContext,
|
|
7
7
|
useContext,
|
|
8
8
|
useEffect as useEffect2,
|
|
9
|
+
useMemo,
|
|
9
10
|
useRef as useRef2,
|
|
10
11
|
useState as useState2,
|
|
11
12
|
useSyncExternalStore as useSyncExternalStore2
|
|
@@ -1638,8 +1639,17 @@ function CanvasProvider({
|
|
|
1638
1639
|
layoutRules,
|
|
1639
1640
|
regionWidth = null,
|
|
1640
1641
|
tabStrip = "auto",
|
|
1641
|
-
|
|
1642
|
+
itemActions,
|
|
1643
|
+
popOut,
|
|
1644
|
+
dockBack,
|
|
1645
|
+
showMenu,
|
|
1646
|
+
overlay,
|
|
1647
|
+
onNativeBodyFrame
|
|
1642
1648
|
}) {
|
|
1649
|
+
const hostPorts = useMemo(
|
|
1650
|
+
() => ({ itemActions, popOut, dockBack, showMenu, overlay, onNativeBodyFrame }),
|
|
1651
|
+
[itemActions, popOut, dockBack, showMenu, overlay, onNativeBodyFrame]
|
|
1652
|
+
);
|
|
1643
1653
|
const portsRef = useRef2(hostPorts);
|
|
1644
1654
|
portsRef.current = hostPorts;
|
|
1645
1655
|
const [{ controller, layer, launcherEntries }] = useState2(() => ({
|
|
@@ -1681,7 +1691,10 @@ function CanvasProvider({
|
|
|
1681
1691
|
window.addEventListener("keydown", onKey);
|
|
1682
1692
|
return () => window.removeEventListener("keydown", onKey);
|
|
1683
1693
|
}, [controller, hotkeys, windowId]);
|
|
1684
|
-
const value =
|
|
1694
|
+
const value = useMemo(
|
|
1695
|
+
() => ({ controller, windowId, ports: hostPorts, layer, regionWidth, tabStrip, launcherEntries }),
|
|
1696
|
+
[controller, windowId, hostPorts, layer, regionWidth, tabStrip, launcherEntries]
|
|
1697
|
+
);
|
|
1685
1698
|
return /* @__PURE__ */ jsxs(CanvasContext.Provider, { value, children: [
|
|
1686
1699
|
children,
|
|
1687
1700
|
hostPorts.overlay ? null : /* @__PURE__ */ jsx2(CanvasDomOverlay, { layer })
|
|
@@ -1689,8 +1702,10 @@ function CanvasProvider({
|
|
|
1689
1702
|
}
|
|
1690
1703
|
function CanvasWindowScope({ windowId, children }) {
|
|
1691
1704
|
const parent = useCanvasContext();
|
|
1692
|
-
const
|
|
1693
|
-
|
|
1705
|
+
const value = useMemo(() => {
|
|
1706
|
+
const id = canvasWindowId(windowId);
|
|
1707
|
+
return { ...parent, windowId: id, controller: parent.controller.forWindow(id) };
|
|
1708
|
+
}, [parent, windowId]);
|
|
1694
1709
|
return /* @__PURE__ */ jsx2(CanvasContext.Provider, { value, children });
|
|
1695
1710
|
}
|
|
1696
1711
|
function useCanvasContext() {
|
|
@@ -1812,7 +1827,7 @@ import {
|
|
|
1812
1827
|
memo,
|
|
1813
1828
|
useEffect as useEffect5,
|
|
1814
1829
|
useLayoutEffect as useLayoutEffect2,
|
|
1815
|
-
useMemo,
|
|
1830
|
+
useMemo as useMemo2,
|
|
1816
1831
|
useRef as useRef5,
|
|
1817
1832
|
useState as useState4
|
|
1818
1833
|
} from "react";
|
|
@@ -2402,25 +2417,45 @@ function resetKindComponent(kind) {
|
|
|
2402
2417
|
}
|
|
2403
2418
|
function usePanePresentation(slots, paneId, isFullscreen, paneCount) {
|
|
2404
2419
|
const size = useSlotSize(slots, paneId);
|
|
2405
|
-
return
|
|
2420
|
+
return useMemo2(
|
|
2406
2421
|
() => canvasPresentation({ width: size.width, height: size.height, isFullscreen, paneCount }),
|
|
2407
2422
|
[size.width, size.height, isFullscreen, paneCount]
|
|
2408
2423
|
);
|
|
2409
2424
|
}
|
|
2410
|
-
|
|
2425
|
+
var hostKey = (item) => item.instance ?? item.id;
|
|
2426
|
+
var SEP2 = "";
|
|
2427
|
+
var ROW = "";
|
|
2428
|
+
function layerSignature(state, windowId, onlyPane) {
|
|
2411
2429
|
const frame2 = canvasWindowFrame(state, windowId);
|
|
2412
|
-
if (!frame2) return
|
|
2413
|
-
const
|
|
2414
|
-
|
|
2430
|
+
if (!frame2) return "";
|
|
2431
|
+
const rows = [];
|
|
2432
|
+
const paneIds = listPaneIds(frame2.layout);
|
|
2433
|
+
for (const paneId of onlyPane ? [onlyPane] : paneIds) {
|
|
2415
2434
|
const pane = state.panes[paneId];
|
|
2416
2435
|
for (const itemId of pane?.itemIds ?? []) {
|
|
2417
2436
|
const item = state.items[itemId];
|
|
2418
|
-
if (item)
|
|
2437
|
+
if (item) rows.push({ item, row: [hostKey(item), itemId, paneId, pane?.activeItemId === itemId ? "1" : "0"].join(SEP2) });
|
|
2419
2438
|
}
|
|
2420
2439
|
}
|
|
2421
|
-
|
|
2440
|
+
rows.sort((a, b) => a.item.openedAt - b.item.openedAt || hostKey(a.item).localeCompare(hostKey(b.item)));
|
|
2441
|
+
const head = [frame2.isOpen ? "1" : "0", frame2.isFullscreen ? "1" : "0", frame2.focusedPaneId, String(paneIds.length)].join(SEP2);
|
|
2442
|
+
return [head, ...rows.map((r) => r.row)].join(ROW);
|
|
2443
|
+
}
|
|
2444
|
+
function parseSignature(signature) {
|
|
2445
|
+
if (!signature) return null;
|
|
2446
|
+
const [head = "", ...rows] = signature.split(ROW);
|
|
2447
|
+
const [open, full, focusedPaneId = "", count = "1"] = head.split(SEP2);
|
|
2448
|
+
return {
|
|
2449
|
+
isOpen: open === "1",
|
|
2450
|
+
isFullscreen: full === "1",
|
|
2451
|
+
focusedPaneId,
|
|
2452
|
+
paneCount: Number(count) || 1,
|
|
2453
|
+
placed: rows.map((row) => {
|
|
2454
|
+
const [hostId = "", itemId = "", paneId = "", active] = row.split(SEP2);
|
|
2455
|
+
return { hostId, itemId, paneId, active: active === "1" };
|
|
2456
|
+
})
|
|
2457
|
+
};
|
|
2422
2458
|
}
|
|
2423
|
-
var hostKey = (item) => item.instance ?? item.id;
|
|
2424
2459
|
function createPlacement(getRoot, slots, afterPlace) {
|
|
2425
2460
|
const hosts = /* @__PURE__ */ new Map();
|
|
2426
2461
|
let placing = false;
|
|
@@ -2463,57 +2498,54 @@ function createPlacement(getRoot, slots, afterPlace) {
|
|
|
2463
2498
|
function CanvasBodyLayer() {
|
|
2464
2499
|
const { windowId, layer } = useCanvasInternals();
|
|
2465
2500
|
const slots = useCanvasSlots();
|
|
2466
|
-
const
|
|
2501
|
+
const signature = useCanvasState((s) => layerSignature(s, windowId));
|
|
2467
2502
|
const root = useRef5(null);
|
|
2468
2503
|
const [placement] = useState4(
|
|
2469
2504
|
() => slots ? createPlacement(() => root.current, slots, () => layer.native.remeasure()) : null
|
|
2470
2505
|
);
|
|
2471
2506
|
useIsoLayoutEffect(() => placement?.place());
|
|
2472
2507
|
useIsoLayoutEffect(() => slots && placement ? slots.subscribe(placement.place) : void 0, [slots, placement]);
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
const paneCount = listPaneIds(frame2.layout).length;
|
|
2477
|
-
return /* @__PURE__ */ jsx6("div", { ref: root, className: "mxc-bodies", "data-mxc-bodies": windowId, children: placedItems(state, windowId).map(({ item, paneId, active }) => /* @__PURE__ */ jsx6(
|
|
2508
|
+
const shape = parseSignature(signature);
|
|
2509
|
+
if (!slots || !placement || !shape) return null;
|
|
2510
|
+
return /* @__PURE__ */ jsx6("div", { ref: root, className: "mxc-bodies", "data-mxc-bodies": windowId, children: shape.placed.map(({ hostId, itemId, paneId, active }) => /* @__PURE__ */ jsx6(
|
|
2478
2511
|
BodyHost,
|
|
2479
2512
|
{
|
|
2480
|
-
hostId
|
|
2481
|
-
|
|
2513
|
+
hostId,
|
|
2514
|
+
itemId,
|
|
2482
2515
|
paneId,
|
|
2483
|
-
visible:
|
|
2484
|
-
focused: active &&
|
|
2485
|
-
isFullscreen:
|
|
2486
|
-
paneCount,
|
|
2516
|
+
visible: shape.isOpen && active,
|
|
2517
|
+
focused: active && shape.focusedPaneId === paneId,
|
|
2518
|
+
isFullscreen: shape.isFullscreen,
|
|
2519
|
+
paneCount: shape.paneCount,
|
|
2487
2520
|
slots,
|
|
2488
2521
|
placement
|
|
2489
2522
|
},
|
|
2490
|
-
|
|
2523
|
+
hostId
|
|
2491
2524
|
)) });
|
|
2492
2525
|
}
|
|
2493
2526
|
function CanvasPaneInlineBodies({ paneId, slots }) {
|
|
2494
2527
|
const { windowId } = useCanvasInternals();
|
|
2495
|
-
const
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
return /* @__PURE__ */ jsx6(Fragment, { children: placedItems(state, windowId, paneId).map(({ item, active }) => /* @__PURE__ */ jsx6(
|
|
2528
|
+
const shape = parseSignature(useCanvasState((s) => layerSignature(s, windowId, paneId)));
|
|
2529
|
+
if (!shape) return null;
|
|
2530
|
+
return /* @__PURE__ */ jsx6(Fragment, { children: shape.placed.map(({ hostId, itemId, active }) => /* @__PURE__ */ jsx6(
|
|
2499
2531
|
BodyHost,
|
|
2500
2532
|
{
|
|
2501
|
-
hostId
|
|
2502
|
-
|
|
2533
|
+
hostId,
|
|
2534
|
+
itemId,
|
|
2503
2535
|
paneId,
|
|
2504
2536
|
visible: active,
|
|
2505
|
-
focused: active &&
|
|
2506
|
-
isFullscreen:
|
|
2507
|
-
paneCount,
|
|
2537
|
+
focused: active && shape.focusedPaneId === paneId,
|
|
2538
|
+
isFullscreen: shape.isFullscreen,
|
|
2539
|
+
paneCount: shape.paneCount,
|
|
2508
2540
|
slots,
|
|
2509
2541
|
placement: null
|
|
2510
2542
|
},
|
|
2511
|
-
|
|
2543
|
+
hostId
|
|
2512
2544
|
)) });
|
|
2513
2545
|
}
|
|
2514
|
-
|
|
2546
|
+
var BodyHost = memo(function BodyHost2({
|
|
2515
2547
|
hostId,
|
|
2516
|
-
|
|
2548
|
+
itemId,
|
|
2517
2549
|
paneId,
|
|
2518
2550
|
visible,
|
|
2519
2551
|
focused,
|
|
@@ -2524,7 +2556,8 @@ function BodyHost({
|
|
|
2524
2556
|
}) {
|
|
2525
2557
|
const canvas = useCanvas();
|
|
2526
2558
|
const { windowId, ports } = useCanvasInternals();
|
|
2527
|
-
const
|
|
2559
|
+
const item = useCanvasState((s) => s.items[itemId]);
|
|
2560
|
+
const kind = useItemKind(item?.kind ?? "");
|
|
2528
2561
|
const element = useRef5(null);
|
|
2529
2562
|
const [everShown, setEverShown] = useState4(visible);
|
|
2530
2563
|
if (visible && !everShown) setEverShown(true);
|
|
@@ -2536,6 +2569,7 @@ function BodyHost({
|
|
|
2536
2569
|
if (!placement || !el) return void 0;
|
|
2537
2570
|
return placement.register(hostId, { element: el, paneId });
|
|
2538
2571
|
}, [placement, hostId, paneId]);
|
|
2572
|
+
if (!item) return null;
|
|
2539
2573
|
return /* @__PURE__ */ jsx6(
|
|
2540
2574
|
"div",
|
|
2541
2575
|
{
|
|
@@ -2569,7 +2603,7 @@ function BodyHost({
|
|
|
2569
2603
|
) }) }) : null
|
|
2570
2604
|
}
|
|
2571
2605
|
);
|
|
2572
|
-
}
|
|
2606
|
+
});
|
|
2573
2607
|
function ItemContent({
|
|
2574
2608
|
item,
|
|
2575
2609
|
kind,
|
|
@@ -2705,13 +2739,15 @@ function CanvasPaneView({ paneId }) {
|
|
|
2705
2739
|
const [ownSlots] = useState5(createCanvasSlots);
|
|
2706
2740
|
const slots = columnSlots ?? ownSlots;
|
|
2707
2741
|
const pane = useCanvasState((s) => s.panes[paneId]);
|
|
2708
|
-
const
|
|
2742
|
+
const active = useCanvasState((s) => {
|
|
2743
|
+
const activeId = s.panes[paneId]?.activeItemId;
|
|
2744
|
+
return activeId ? s.items[activeId] : void 0;
|
|
2745
|
+
});
|
|
2709
2746
|
const isFullscreen = useCanvasState((s) => selectCanvasIsFullscreen(s, windowId));
|
|
2710
2747
|
const isOpen = useCanvasState((s) => selectCanvasIsOpen(s, windowId));
|
|
2711
2748
|
const focused = useCanvasState((s) => selectCanvasFocusedPaneId(s, windowId) === paneId);
|
|
2712
2749
|
const paneCount = useCanvasState((s) => selectCanvasPaneCount(s, windowId));
|
|
2713
2750
|
const role = useCanvasState((s) => windowId === CANVAS_MAIN_WINDOW ? "main" : s.windows[windowId]?.role ?? "window");
|
|
2714
|
-
const active = pane?.activeItemId ? items[pane.activeItemId] : void 0;
|
|
2715
2751
|
const canGoBack = useCanvasState((s) => active ? selectCanvasCanGoBack(s, active.id) : false);
|
|
2716
2752
|
const kind = useItemKind(active?.kind ?? "");
|
|
2717
2753
|
const sectionRef = useRef6(null);
|
|
@@ -2800,7 +2836,7 @@ function TabStrip({ paneId, itemIds, activeItemId }) {
|
|
|
2800
2836
|
const reveal = () => {
|
|
2801
2837
|
const tab = el.querySelector('[role="tab"][aria-selected="true"]');
|
|
2802
2838
|
if (!tab) return;
|
|
2803
|
-
const left = tab.offsetLeft
|
|
2839
|
+
const left = tab.offsetLeft;
|
|
2804
2840
|
const right = left + tab.offsetWidth;
|
|
2805
2841
|
if (left < el.scrollLeft) el.scrollLeft = left;
|
|
2806
2842
|
else if (right > el.scrollLeft + el.clientWidth) el.scrollLeft = right - el.clientWidth;
|