@ai-matrx/canvas 0.2.1 → 0.3.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 CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0
4
+
5
+ - **Toggle or focus a kind** — what a toolbar icon or a quick-tool launcher does. `toggleKind(controller, { kind, key?, data?, title?, whenVisible? })`: absent → open and reveal; behind another tab or canvas put away → bring it forward; in front → close it (default) or put the canvas away (`whenVisible: "hide"`). `data` seeds only a new item. `selectCanvasKindVisibility(state, kind, key?)` returns `"absent" | "background" | "visible"` (a primitive — safe in useSyncExternalStore / useSelector), and the React hook `useCanvasKindToggle(input)` gives `{ visibility, isOpen, isVisible, toggle }` for an icon button's active state. Key defaults to `CANVAS_DEFAULT_KEY` ("default").
6
+
7
+ ### Consumer action
8
+
9
+ - Replace any host-side "open or focus this panel" helper with `toggleKind` / `useCanvasKindToggle` (desktop toolbar icons; web quick-tool launchers).
10
+
11
+ ## 0.2.2
12
+
13
+ - `CanvasToggle` takes `variant` (`"transparent"` default, or `"glass"`). The tap-target placement rules forbid one plain icon in a glass row; a host whose header buttons are glass passes `variant="glass"` so the toggle matches them.
14
+
15
+ ### Consumer action
16
+
17
+ - None. A host with a glass header row should pass `variant="glass"`.
18
+
3
19
  ## 0.2.1
4
20
 
5
21
  - `BrowserBar` keeps its own 40px height in a panel body. 0.2.0 gave it `flex: 1 1 auto`, so in a column body it grew and sat in the middle of the panel (seen in the desktop browser panel). It still fills the width in a header's leading slot.
package/README.md CHANGED
@@ -38,6 +38,17 @@ defineCanvasKind<{ sessionKey: string }>({
38
38
 
39
39
  `body: "native"` makes the body a placeholder whose frame the host receives (below).
40
40
 
41
+ ## Toolbar icons: toggle or focus a kind
42
+
43
+ ```tsx
44
+ const terminal = useCanvasKindToggle({ kind: "terminal" });
45
+ <button aria-pressed={terminal.isVisible} onClick={terminal.toggle}>…</button>
46
+ // outside React (Electron main, a menu handler):
47
+ toggleKind(controller, { kind: "terminal" }); // absent → open · behind → focus · in front → close
48
+ ```
49
+
50
+ `whenVisible: "hide"` puts the canvas away instead of closing the tab.
51
+
41
52
  ## Chrome for panels a host frames itself
42
53
 
43
54
  `CanvasPanel` (title or `header`, `leading`, `actions`, `renderMenu`, `onToggleExpand`, `onClose`), `CanvasPanelEmpty`, `CanvasHeaderButton`, `CanvasTab`, `BrowserTabs`, `BrowserBar` — the same components every canvas pane draws with. They render outside a provider too.
package/dist/index.cjs CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
+ CANVAS_DEFAULT_KEY: () => CANVAS_DEFAULT_KEY,
23
24
  CANVAS_DEFAULT_WIDTH: () => CANVAS_DEFAULT_WIDTH,
24
25
  CANVAS_DESKTOP_LAYOUT_RULES: () => CANVAS_DESKTOP_LAYOUT_RULES,
25
26
  CANVAS_MAIN_WINDOW: () => CANVAS_MAIN_WINDOW,
@@ -67,6 +68,7 @@ __export(src_exports, {
67
68
  selectCanvasIsOpen: () => selectCanvasIsOpen,
68
69
  selectCanvasItem: () => selectCanvasItem,
69
70
  selectCanvasItemCount: () => selectCanvasItemCount,
71
+ selectCanvasKindVisibility: () => selectCanvasKindVisibility,
70
72
  selectCanvasLayout: () => selectCanvasLayout,
71
73
  selectCanvasPane: () => selectCanvasPane,
72
74
  selectCanvasPaneCount: () => selectCanvasPaneCount,
@@ -76,7 +78,8 @@ __export(src_exports, {
76
78
  selectCanvasWindows: () => selectCanvasWindows,
77
79
  shareStructure: () => shareStructure,
78
80
  shouldStackSplit: () => shouldStackSplit,
79
- toPersistableSnapshot: () => toPersistableSnapshot
81
+ toPersistableSnapshot: () => toPersistableSnapshot,
82
+ toggleKind: () => toggleKind
80
83
  });
81
84
  module.exports = __toCommonJS(src_exports);
82
85
 
@@ -1394,4 +1397,42 @@ function selectCanvasWindows(s) {
1394
1397
  }
1395
1398
  var selectCanvasExtraWindow = (s, windowId) => s.windows?.[windowId];
1396
1399
  var selectCanvasWindowOfItem = canvasWindowOfItem;
1400
+
1401
+ // src/core/toggleKind.ts
1402
+ var CANVAS_DEFAULT_KEY = "default";
1403
+ function selectCanvasKindVisibility(state, kind, key = CANVAS_DEFAULT_KEY) {
1404
+ const itemId = canvasItemId(kind, key);
1405
+ if (!state.items[itemId]) return "absent";
1406
+ const windowId = canvasWindowOfItem(state, itemId);
1407
+ if (!windowId) return "background";
1408
+ const isOpen = canvasWindowFrame(state, windowId)?.isOpen ?? false;
1409
+ const pane = Object.values(state.panes).find((p) => p.itemIds.includes(itemId));
1410
+ return isOpen && pane?.activeItemId === itemId ? "visible" : "background";
1411
+ }
1412
+ function toggleKind(controller, input) {
1413
+ const key = input.key ?? CANVAS_DEFAULT_KEY;
1414
+ const itemId = canvasItemId(input.kind, key);
1415
+ const before = selectCanvasKindVisibility(controller.getState(), input.kind, key);
1416
+ if (before === "visible") {
1417
+ if ((input.whenVisible ?? "close") === "close") {
1418
+ controller.close(itemId);
1419
+ } else {
1420
+ controller.hide(canvasWindowOfItem(controller.getState(), itemId) ?? void 0);
1421
+ }
1422
+ return selectCanvasKindVisibility(controller.getState(), input.kind, key);
1423
+ }
1424
+ if (before === "background") {
1425
+ controller.open({ kind: input.kind, key });
1426
+ const windowId = canvasWindowOfItem(controller.getState(), itemId);
1427
+ if (windowId) controller.show(windowId);
1428
+ return selectCanvasKindVisibility(controller.getState(), input.kind, key);
1429
+ }
1430
+ const opened = controller.open({
1431
+ kind: input.kind,
1432
+ key,
1433
+ ...input.data !== void 0 ? { data: input.data } : {},
1434
+ ...input.title !== void 0 ? { title: input.title } : {}
1435
+ });
1436
+ return opened ? selectCanvasKindVisibility(controller.getState(), input.kind, key) : "absent";
1437
+ }
1397
1438
  //# sourceMappingURL=index.cjs.map