@ai-matrx/canvas 0.2.2 → 0.4.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 +16 -0
- package/README.md +16 -0
- package/dist/index.cjs +42 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +42 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +73 -7
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +19 -2
- package/dist/react.d.ts +19 -2
- package/dist/react.js +73 -7
- package/dist/react.js.map +1 -1
- package/dist/styles.css +17 -0
- package/dist/{controller-Dv6J6XZm.d.cts → toggleKind-A9v45oSb.d.cts} +30 -1
- package/dist/{controller-Dv6J6XZm.d.ts → toggleKind-A9v45oSb.d.ts} +30 -1
- package/package.json +1 -1
package/dist/react.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ComponentType, ReactNode, CSSProperties, ButtonHTMLAttributes, HTMLAttributes, ReactElement } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { F as CanvasRect, d as CanvasPaneId, C as CanvasItemId, a as CanvasWindowId, b as CanvasJson, i as CanvasItem, h as CanvasController, I as CanvasSessionEvent, G as CanvasSessionAttachReason, H as CanvasSessionDetachReason, e as CanvasStoreBinding, E as CanvasPersistencePort, w as CanvasErrorSink, z as CanvasLayoutRules, T as ToggleKindInput, y as CanvasKindVisibility, f as CanvasState } from './toggleKind-A9v45oSb.cjs';
|
|
4
4
|
|
|
5
5
|
/** One floating thing. Plain data, so a host can draw it in another process. */
|
|
6
6
|
type CanvasFloating = {
|
|
@@ -133,6 +133,13 @@ interface CanvasKind<TData extends CanvasJson = CanvasJson> {
|
|
|
133
133
|
readonly HeaderLeading?: ComponentType<CanvasKindProps<TData>>;
|
|
134
134
|
/** The kind's own button, rendered left of the pane's "…" menu. */
|
|
135
135
|
readonly HeaderAction?: ComponentType<CanvasKindProps<TData>>;
|
|
136
|
+
/**
|
|
137
|
+
* A toolbar ROW between the pane header and the body, for the active item
|
|
138
|
+
* only (a browser's back / forward / reload / address / screenshot). Always
|
|
139
|
+
* DOM, never covered by a native view: a `body: "native"` frame is measured
|
|
140
|
+
* BELOW it.
|
|
141
|
+
*/
|
|
142
|
+
readonly Toolbar?: ComponentType<CanvasKindProps<TData>>;
|
|
136
143
|
/** Kind-specific entries for the pane's "…" menu. */
|
|
137
144
|
readonly menuItems?: (props: CanvasKindProps<TData>) => readonly CanvasMenuItem[];
|
|
138
145
|
}
|
|
@@ -230,6 +237,16 @@ declare function useCanvasState<T>(selector: (state: CanvasState) => T): T;
|
|
|
230
237
|
* embed). `fallback` must be referentially stable (a primitive or null).
|
|
231
238
|
*/
|
|
232
239
|
declare function useOptionalCanvasState<T>(selector: (state: CanvasState) => T, fallback: T): T;
|
|
240
|
+
/**
|
|
241
|
+
* A toolbar icon's view of one kind: "absent" | "background" | "visible"
|
|
242
|
+
* (a primitive, so it never loops), plus the click that toggles or focuses it.
|
|
243
|
+
*/
|
|
244
|
+
declare function useCanvasKindToggle(input: ToggleKindInput): {
|
|
245
|
+
readonly visibility: CanvasKindVisibility;
|
|
246
|
+
readonly isOpen: boolean;
|
|
247
|
+
readonly isVisible: boolean;
|
|
248
|
+
readonly toggle: () => CanvasKindVisibility;
|
|
249
|
+
};
|
|
233
250
|
/** Re-renders when kinds register, so late-registered kinds appear. */
|
|
234
251
|
declare function useCanvasKinds(): readonly AnyCanvasKind[];
|
|
235
252
|
declare function useCanvasKind(id: string): AnyCanvasKind | undefined;
|
|
@@ -372,4 +389,4 @@ interface BrowserBarProps {
|
|
|
372
389
|
/** A browser's back · forward · reload · address bar, for a kind's leading slot or its body. */
|
|
373
390
|
declare function BrowserBar({ url, canGoBack, canGoForward, onBack, onForward, onReload, onNavigate, trailing, className }: BrowserBarProps): react.JSX.Element;
|
|
374
391
|
|
|
375
|
-
export { type AnyCanvasKind, BrowserBar, type BrowserBarProps, type BrowserTab, BrowserTabs, type BrowserTabsProps, CanvasColumn, type CanvasColumnProps, type CanvasFloating, CanvasFrame, CanvasHeaderButton, type CanvasHeaderButtonProps, type CanvasHostPorts, type CanvasKind, type CanvasKindProps, type CanvasMenuEntry, type CanvasMenuItem, CanvasMenuTrigger, type CanvasNativeBodyFrame, type CanvasNativeBodyInfo, type CanvasNativeRect, type CanvasOverlayPort, CanvasPaneView, CanvasPanel, CanvasPanelEmpty, type CanvasPanelProps, CanvasProvider, type CanvasProviderProps, type CanvasShowMenu, CanvasTab, type CanvasTabProps, type CanvasTabStripMode, CanvasToggle, CanvasWindowScope, canvasSessionKey, defineCanvasKind, getCanvasKind, itemTitle, listCanvasKinds, registerCanvasKind, registerCanvasKinds, useCanvas, useCanvasColumnWidth, useCanvasHostPorts, useCanvasIsPresented, useCanvasKind, useCanvasKinds, useCanvasNativeBodies, useCanvasState, useCanvasWindowId, useOptionalCanvas, useOptionalCanvasState };
|
|
392
|
+
export { type AnyCanvasKind, BrowserBar, type BrowserBarProps, type BrowserTab, BrowserTabs, type BrowserTabsProps, CanvasColumn, type CanvasColumnProps, type CanvasFloating, CanvasFrame, CanvasHeaderButton, type CanvasHeaderButtonProps, type CanvasHostPorts, type CanvasKind, type CanvasKindProps, type CanvasMenuEntry, type CanvasMenuItem, CanvasMenuTrigger, type CanvasNativeBodyFrame, type CanvasNativeBodyInfo, type CanvasNativeRect, type CanvasOverlayPort, CanvasPaneView, CanvasPanel, CanvasPanelEmpty, type CanvasPanelProps, CanvasProvider, type CanvasProviderProps, type CanvasShowMenu, CanvasTab, type CanvasTabProps, type CanvasTabStripMode, CanvasToggle, CanvasWindowScope, canvasSessionKey, defineCanvasKind, getCanvasKind, itemTitle, listCanvasKinds, registerCanvasKind, registerCanvasKinds, useCanvas, useCanvasColumnWidth, useCanvasHostPorts, useCanvasIsPresented, useCanvasKind, useCanvasKindToggle, useCanvasKinds, useCanvasNativeBodies, useCanvasState, useCanvasWindowId, useOptionalCanvas, useOptionalCanvasState };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ComponentType, ReactNode, CSSProperties, ButtonHTMLAttributes, HTMLAttributes, ReactElement } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { F as CanvasRect, d as CanvasPaneId, C as CanvasItemId, a as CanvasWindowId, b as CanvasJson, i as CanvasItem, h as CanvasController, I as CanvasSessionEvent, G as CanvasSessionAttachReason, H as CanvasSessionDetachReason, e as CanvasStoreBinding, E as CanvasPersistencePort, w as CanvasErrorSink, z as CanvasLayoutRules, T as ToggleKindInput, y as CanvasKindVisibility, f as CanvasState } from './toggleKind-A9v45oSb.js';
|
|
4
4
|
|
|
5
5
|
/** One floating thing. Plain data, so a host can draw it in another process. */
|
|
6
6
|
type CanvasFloating = {
|
|
@@ -133,6 +133,13 @@ interface CanvasKind<TData extends CanvasJson = CanvasJson> {
|
|
|
133
133
|
readonly HeaderLeading?: ComponentType<CanvasKindProps<TData>>;
|
|
134
134
|
/** The kind's own button, rendered left of the pane's "…" menu. */
|
|
135
135
|
readonly HeaderAction?: ComponentType<CanvasKindProps<TData>>;
|
|
136
|
+
/**
|
|
137
|
+
* A toolbar ROW between the pane header and the body, for the active item
|
|
138
|
+
* only (a browser's back / forward / reload / address / screenshot). Always
|
|
139
|
+
* DOM, never covered by a native view: a `body: "native"` frame is measured
|
|
140
|
+
* BELOW it.
|
|
141
|
+
*/
|
|
142
|
+
readonly Toolbar?: ComponentType<CanvasKindProps<TData>>;
|
|
136
143
|
/** Kind-specific entries for the pane's "…" menu. */
|
|
137
144
|
readonly menuItems?: (props: CanvasKindProps<TData>) => readonly CanvasMenuItem[];
|
|
138
145
|
}
|
|
@@ -230,6 +237,16 @@ declare function useCanvasState<T>(selector: (state: CanvasState) => T): T;
|
|
|
230
237
|
* embed). `fallback` must be referentially stable (a primitive or null).
|
|
231
238
|
*/
|
|
232
239
|
declare function useOptionalCanvasState<T>(selector: (state: CanvasState) => T, fallback: T): T;
|
|
240
|
+
/**
|
|
241
|
+
* A toolbar icon's view of one kind: "absent" | "background" | "visible"
|
|
242
|
+
* (a primitive, so it never loops), plus the click that toggles or focuses it.
|
|
243
|
+
*/
|
|
244
|
+
declare function useCanvasKindToggle(input: ToggleKindInput): {
|
|
245
|
+
readonly visibility: CanvasKindVisibility;
|
|
246
|
+
readonly isOpen: boolean;
|
|
247
|
+
readonly isVisible: boolean;
|
|
248
|
+
readonly toggle: () => CanvasKindVisibility;
|
|
249
|
+
};
|
|
233
250
|
/** Re-renders when kinds register, so late-registered kinds appear. */
|
|
234
251
|
declare function useCanvasKinds(): readonly AnyCanvasKind[];
|
|
235
252
|
declare function useCanvasKind(id: string): AnyCanvasKind | undefined;
|
|
@@ -372,4 +389,4 @@ interface BrowserBarProps {
|
|
|
372
389
|
/** A browser's back · forward · reload · address bar, for a kind's leading slot or its body. */
|
|
373
390
|
declare function BrowserBar({ url, canGoBack, canGoForward, onBack, onForward, onReload, onNavigate, trailing, className }: BrowserBarProps): react.JSX.Element;
|
|
374
391
|
|
|
375
|
-
export { type AnyCanvasKind, BrowserBar, type BrowserBarProps, type BrowserTab, BrowserTabs, type BrowserTabsProps, CanvasColumn, type CanvasColumnProps, type CanvasFloating, CanvasFrame, CanvasHeaderButton, type CanvasHeaderButtonProps, type CanvasHostPorts, type CanvasKind, type CanvasKindProps, type CanvasMenuEntry, type CanvasMenuItem, CanvasMenuTrigger, type CanvasNativeBodyFrame, type CanvasNativeBodyInfo, type CanvasNativeRect, type CanvasOverlayPort, CanvasPaneView, CanvasPanel, CanvasPanelEmpty, type CanvasPanelProps, CanvasProvider, type CanvasProviderProps, type CanvasShowMenu, CanvasTab, type CanvasTabProps, type CanvasTabStripMode, CanvasToggle, CanvasWindowScope, canvasSessionKey, defineCanvasKind, getCanvasKind, itemTitle, listCanvasKinds, registerCanvasKind, registerCanvasKinds, useCanvas, useCanvasColumnWidth, useCanvasHostPorts, useCanvasIsPresented, useCanvasKind, useCanvasKinds, useCanvasNativeBodies, useCanvasState, useCanvasWindowId, useOptionalCanvas, useOptionalCanvasState };
|
|
392
|
+
export { type AnyCanvasKind, BrowserBar, type BrowserBarProps, type BrowserTab, BrowserTabs, type BrowserTabsProps, CanvasColumn, type CanvasColumnProps, type CanvasFloating, CanvasFrame, CanvasHeaderButton, type CanvasHeaderButtonProps, type CanvasHostPorts, type CanvasKind, type CanvasKindProps, type CanvasMenuEntry, type CanvasMenuItem, CanvasMenuTrigger, type CanvasNativeBodyFrame, type CanvasNativeBodyInfo, type CanvasNativeRect, type CanvasOverlayPort, CanvasPaneView, CanvasPanel, CanvasPanelEmpty, type CanvasPanelProps, CanvasProvider, type CanvasProviderProps, type CanvasShowMenu, CanvasTab, type CanvasTabProps, type CanvasTabStripMode, CanvasToggle, CanvasWindowScope, canvasSessionKey, defineCanvasKind, getCanvasKind, itemTitle, listCanvasKinds, registerCanvasKind, registerCanvasKinds, useCanvas, useCanvasColumnWidth, useCanvasHostPorts, useCanvasIsPresented, useCanvasKind, useCanvasKindToggle, useCanvasKinds, useCanvasNativeBodies, useCanvasState, useCanvasWindowId, useOptionalCanvas, useOptionalCanvasState };
|
package/dist/react.js
CHANGED
|
@@ -1220,6 +1220,44 @@ function selectCanvasWindowItemCount(s, windowId) {
|
|
|
1220
1220
|
}
|
|
1221
1221
|
var NO_WINDOWS = Object.freeze({});
|
|
1222
1222
|
|
|
1223
|
+
// src/core/toggleKind.ts
|
|
1224
|
+
var CANVAS_DEFAULT_KEY = "default";
|
|
1225
|
+
function selectCanvasKindVisibility(state, kind, key = CANVAS_DEFAULT_KEY) {
|
|
1226
|
+
const itemId = canvasItemId(kind, key);
|
|
1227
|
+
if (!state.items[itemId]) return "absent";
|
|
1228
|
+
const windowId = canvasWindowOfItem(state, itemId);
|
|
1229
|
+
if (!windowId) return "background";
|
|
1230
|
+
const isOpen = canvasWindowFrame(state, windowId)?.isOpen ?? false;
|
|
1231
|
+
const pane = Object.values(state.panes).find((p) => p.itemIds.includes(itemId));
|
|
1232
|
+
return isOpen && pane?.activeItemId === itemId ? "visible" : "background";
|
|
1233
|
+
}
|
|
1234
|
+
function toggleKind(controller, input) {
|
|
1235
|
+
const key = input.key ?? CANVAS_DEFAULT_KEY;
|
|
1236
|
+
const itemId = canvasItemId(input.kind, key);
|
|
1237
|
+
const before = selectCanvasKindVisibility(controller.getState(), input.kind, key);
|
|
1238
|
+
if (before === "visible") {
|
|
1239
|
+
if ((input.whenVisible ?? "close") === "close") {
|
|
1240
|
+
controller.close(itemId);
|
|
1241
|
+
} else {
|
|
1242
|
+
controller.hide(canvasWindowOfItem(controller.getState(), itemId) ?? void 0);
|
|
1243
|
+
}
|
|
1244
|
+
return selectCanvasKindVisibility(controller.getState(), input.kind, key);
|
|
1245
|
+
}
|
|
1246
|
+
if (before === "background") {
|
|
1247
|
+
controller.open({ kind: input.kind, key });
|
|
1248
|
+
const windowId = canvasWindowOfItem(controller.getState(), itemId);
|
|
1249
|
+
if (windowId) controller.show(windowId);
|
|
1250
|
+
return selectCanvasKindVisibility(controller.getState(), input.kind, key);
|
|
1251
|
+
}
|
|
1252
|
+
const opened = controller.open({
|
|
1253
|
+
kind: input.kind,
|
|
1254
|
+
key,
|
|
1255
|
+
...input.data !== void 0 ? { data: input.data } : {},
|
|
1256
|
+
...input.title !== void 0 ? { title: input.title } : {}
|
|
1257
|
+
});
|
|
1258
|
+
return opened ? selectCanvasKindVisibility(controller.getState(), input.kind, key) : "absent";
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1223
1261
|
// src/react/layer.tsx
|
|
1224
1262
|
import { useEffect, useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
1225
1263
|
import { createPortal } from "react-dom";
|
|
@@ -1519,6 +1557,17 @@ function useOptionalCanvasState(selector, fallback) {
|
|
|
1519
1557
|
const read = () => store ? selector(store.getState()) : fallback;
|
|
1520
1558
|
return useSyncExternalStore2(store ? store.subscribe : NO_SUBSCRIPTION, read, read);
|
|
1521
1559
|
}
|
|
1560
|
+
function useCanvasKindToggle(input) {
|
|
1561
|
+
const controller = useCanvasContext().controller;
|
|
1562
|
+
const key = input.key ?? CANVAS_DEFAULT_KEY;
|
|
1563
|
+
const visibility = useCanvasState((s) => selectCanvasKindVisibility(s, input.kind, key));
|
|
1564
|
+
return {
|
|
1565
|
+
visibility,
|
|
1566
|
+
isOpen: visibility !== "absent",
|
|
1567
|
+
isVisible: visibility === "visible",
|
|
1568
|
+
toggle: () => toggleKind(controller, input)
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1522
1571
|
function useCanvasKinds() {
|
|
1523
1572
|
useSyncExternalStore2(subscribeCanvasKinds, getCanvasKindsVersion, getCanvasKindsVersion);
|
|
1524
1573
|
return listCanvasKinds();
|
|
@@ -1959,6 +2008,7 @@ function CanvasPaneView({ paneId }) {
|
|
|
1959
2008
|
const kindProps = active && kind ? { item: active, data: active.data, paneId, isFocused: focused, canvas, windowId } : null;
|
|
1960
2009
|
const Leading = kind?.HeaderLeading;
|
|
1961
2010
|
const Action = kind?.HeaderAction;
|
|
2011
|
+
const Toolbar = kind?.Toolbar;
|
|
1962
2012
|
const single = tabStrip === "auto" && pane.itemIds.length === 1 && active;
|
|
1963
2013
|
const hideDrop = () => {
|
|
1964
2014
|
drop.current?.();
|
|
@@ -1985,7 +2035,7 @@ function CanvasPaneView({ paneId }) {
|
|
|
1985
2035
|
canvas.moveItem(itemId, paneId);
|
|
1986
2036
|
};
|
|
1987
2037
|
const closeLabel = role === "pop-out" && paneCount === 1 ? "Close window" : paneCount > 1 ? "Close pane" : "Close canvas";
|
|
1988
|
-
return /* @__PURE__ */
|
|
2038
|
+
return /* @__PURE__ */ jsxs4(
|
|
1989
2039
|
CanvasPanel,
|
|
1990
2040
|
{
|
|
1991
2041
|
ref: sectionRef,
|
|
@@ -2010,15 +2060,30 @@ function CanvasPaneView({ paneId }) {
|
|
|
2010
2060
|
onDragOver,
|
|
2011
2061
|
onDragLeave,
|
|
2012
2062
|
onDrop,
|
|
2013
|
-
children:
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2063
|
+
children: [
|
|
2064
|
+
Toolbar && kindProps ? /* @__PURE__ */ jsx5("div", { className: "mxc-item-toolbar", "data-kind": active?.kind, children: /* @__PURE__ */ jsx5(ToolbarBoundary, { kindId: kind?.id ?? "", children: /* @__PURE__ */ jsx5(Toolbar, { ...kindProps }) }) }) : null,
|
|
2065
|
+
pane.itemIds.length === 0 ? /* @__PURE__ */ jsx5(Launcher, { paneId }) : pane.itemIds.map((itemId) => {
|
|
2066
|
+
const item = items[itemId];
|
|
2067
|
+
if (!item) return null;
|
|
2068
|
+
const isActive = itemId === pane.activeItemId;
|
|
2069
|
+
return /* @__PURE__ */ jsx5(ItemBody, { item, paneId, windowId, isActive, isFocused: focused && isActive, hasNativePort: !!ports.onNativeBodyFrame }, itemId);
|
|
2070
|
+
})
|
|
2071
|
+
]
|
|
2019
2072
|
}
|
|
2020
2073
|
);
|
|
2021
2074
|
}
|
|
2075
|
+
var ToolbarBoundary = class extends Component {
|
|
2076
|
+
state = { failed: false };
|
|
2077
|
+
static getDerivedStateFromError() {
|
|
2078
|
+
return { failed: true };
|
|
2079
|
+
}
|
|
2080
|
+
componentDidCatch(error) {
|
|
2081
|
+
console.error(`[@ai-matrx/canvas] "${this.props.kindId}" Toolbar threw`, error);
|
|
2082
|
+
}
|
|
2083
|
+
render() {
|
|
2084
|
+
return this.state.failed ? null : this.props.children;
|
|
2085
|
+
}
|
|
2086
|
+
};
|
|
2022
2087
|
function SingleTitle({ item, kind }) {
|
|
2023
2088
|
const title = itemTitle(item, kind);
|
|
2024
2089
|
const drag = useTabDrag(item.id, title);
|
|
@@ -2534,6 +2599,7 @@ export {
|
|
|
2534
2599
|
useCanvasHostPorts,
|
|
2535
2600
|
useCanvasIsPresented,
|
|
2536
2601
|
useCanvasKind,
|
|
2602
|
+
useCanvasKindToggle,
|
|
2537
2603
|
useCanvasKinds,
|
|
2538
2604
|
useCanvasNativeBodies,
|
|
2539
2605
|
useCanvasState,
|