@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/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 { D as CanvasRect, d as CanvasPaneId, C as CanvasItemId, a as CanvasWindowId, b as CanvasJson, i as CanvasItem, h as CanvasController, G as CanvasSessionEvent, E as CanvasSessionAttachReason, F as CanvasSessionDetachReason, e as CanvasStoreBinding, B as CanvasPersistencePort, v as CanvasErrorSink, x as CanvasLayoutRules, f as CanvasState } from './controller-Dv6J6XZm.cjs';
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 = {
@@ -230,6 +230,16 @@ declare function useCanvasState<T>(selector: (state: CanvasState) => T): T;
230
230
  * embed). `fallback` must be referentially stable (a primitive or null).
231
231
  */
232
232
  declare function useOptionalCanvasState<T>(selector: (state: CanvasState) => T, fallback: T): T;
233
+ /**
234
+ * A toolbar icon's view of one kind: "absent" | "background" | "visible"
235
+ * (a primitive, so it never loops), plus the click that toggles or focuses it.
236
+ */
237
+ declare function useCanvasKindToggle(input: ToggleKindInput): {
238
+ readonly visibility: CanvasKindVisibility;
239
+ readonly isOpen: boolean;
240
+ readonly isVisible: boolean;
241
+ readonly toggle: () => CanvasKindVisibility;
242
+ };
233
243
  /** Re-renders when kinds register, so late-registered kinds appear. */
234
244
  declare function useCanvasKinds(): readonly AnyCanvasKind[];
235
245
  declare function useCanvasKind(id: string): AnyCanvasKind | undefined;
@@ -245,9 +255,17 @@ interface CanvasColumnProps {
245
255
  readonly placement?: "docked" | "fill";
246
256
  }
247
257
  declare function CanvasColumn({ className, style, onLiveWidth, placement }: CanvasColumnProps): react.JSX.Element | null;
248
- /** THE one button that opens and puts away the canvas (this window's). */
249
- declare function CanvasToggle({ className }: {
258
+ /**
259
+ * THE one button that opens and puts away the canvas (this window's).
260
+ *
261
+ * `variant` follows the tap-target PLACEMENT RULES (all glass or none): a host
262
+ * whose header row is glass (a bar floating over scrolling content) passes
263
+ * `"glass"` so the toggle matches its neighbours; on a solid bar keep the
264
+ * default `"transparent"`.
265
+ */
266
+ declare function CanvasToggle({ className, variant, }: {
250
267
  className?: string;
268
+ variant?: "glass" | "transparent";
251
269
  }): react.JSX.Element;
252
270
  /**
253
271
  * For hosts without their own shell (a Vite app, an Electron window): the app
@@ -364,4 +382,4 @@ interface BrowserBarProps {
364
382
  /** A browser's back · forward · reload · address bar, for a kind's leading slot or its body. */
365
383
  declare function BrowserBar({ url, canGoBack, canGoForward, onBack, onForward, onReload, onNavigate, trailing, className }: BrowserBarProps): react.JSX.Element;
366
384
 
367
- 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 };
385
+ 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 { D as CanvasRect, d as CanvasPaneId, C as CanvasItemId, a as CanvasWindowId, b as CanvasJson, i as CanvasItem, h as CanvasController, G as CanvasSessionEvent, E as CanvasSessionAttachReason, F as CanvasSessionDetachReason, e as CanvasStoreBinding, B as CanvasPersistencePort, v as CanvasErrorSink, x as CanvasLayoutRules, f as CanvasState } from './controller-Dv6J6XZm.js';
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 = {
@@ -230,6 +230,16 @@ declare function useCanvasState<T>(selector: (state: CanvasState) => T): T;
230
230
  * embed). `fallback` must be referentially stable (a primitive or null).
231
231
  */
232
232
  declare function useOptionalCanvasState<T>(selector: (state: CanvasState) => T, fallback: T): T;
233
+ /**
234
+ * A toolbar icon's view of one kind: "absent" | "background" | "visible"
235
+ * (a primitive, so it never loops), plus the click that toggles or focuses it.
236
+ */
237
+ declare function useCanvasKindToggle(input: ToggleKindInput): {
238
+ readonly visibility: CanvasKindVisibility;
239
+ readonly isOpen: boolean;
240
+ readonly isVisible: boolean;
241
+ readonly toggle: () => CanvasKindVisibility;
242
+ };
233
243
  /** Re-renders when kinds register, so late-registered kinds appear. */
234
244
  declare function useCanvasKinds(): readonly AnyCanvasKind[];
235
245
  declare function useCanvasKind(id: string): AnyCanvasKind | undefined;
@@ -245,9 +255,17 @@ interface CanvasColumnProps {
245
255
  readonly placement?: "docked" | "fill";
246
256
  }
247
257
  declare function CanvasColumn({ className, style, onLiveWidth, placement }: CanvasColumnProps): react.JSX.Element | null;
248
- /** THE one button that opens and puts away the canvas (this window's). */
249
- declare function CanvasToggle({ className }: {
258
+ /**
259
+ * THE one button that opens and puts away the canvas (this window's).
260
+ *
261
+ * `variant` follows the tap-target PLACEMENT RULES (all glass or none): a host
262
+ * whose header row is glass (a bar floating over scrolling content) passes
263
+ * `"glass"` so the toggle matches its neighbours; on a solid bar keep the
264
+ * default `"transparent"`.
265
+ */
266
+ declare function CanvasToggle({ className, variant, }: {
250
267
  className?: string;
268
+ variant?: "glass" | "transparent";
251
269
  }): react.JSX.Element;
252
270
  /**
253
271
  * For hosts without their own shell (a Vite app, an Electron window): the app
@@ -364,4 +382,4 @@ interface BrowserBarProps {
364
382
  /** A browser's back · forward · reload · address bar, for a kind's leading slot or its body. */
365
383
  declare function BrowserBar({ url, canGoBack, canGoForward, onBack, onForward, onReload, onNavigate, trailing, className }: BrowserBarProps): react.JSX.Element;
366
384
 
367
- 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 };
385
+ 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();
@@ -1536,7 +1585,7 @@ import {
1536
1585
  useState as useState4,
1537
1586
  useSyncExternalStore as useSyncExternalStore3
1538
1587
  } from "react";
1539
- import { TapTargetButtonTransparent } from "@ai-matrx/tap-target";
1588
+ import { TapTargetButton, TapTargetButtonTransparent } from "@ai-matrx/tap-target";
1540
1589
 
1541
1590
  // src/react/CanvasPane.tsx
1542
1591
  import {
@@ -2477,14 +2526,18 @@ function SplitChild({ size, handle, children }) {
2477
2526
  ] });
2478
2527
  }
2479
2528
  var isMac2 = () => typeof navigator !== "undefined" && /mac|iphone|ipad/i.test(navigator.platform ?? "");
2480
- function CanvasToggle({ className }) {
2529
+ function CanvasToggle({
2530
+ className,
2531
+ variant = "transparent"
2532
+ }) {
2481
2533
  const { controller, windowId } = useCanvasInternals();
2482
2534
  const isOpen = useCanvasState((s) => selectCanvasIsOpen(s, windowId));
2483
2535
  const count = useCanvasState((s) => selectCanvasWindowItemCount(s, windowId));
2484
2536
  const hint = canvasShortcutHint("canvas.toggle", isMac2());
2537
+ const Button = variant === "glass" ? TapTargetButton : TapTargetButtonTransparent;
2485
2538
  return /* @__PURE__ */ jsxs5("span", { className: ["mxc-toggle", className].filter(Boolean).join(" "), "data-open": isOpen ? "" : void 0, children: [
2486
2539
  /* @__PURE__ */ jsx6(
2487
- TapTargetButtonTransparent,
2540
+ Button,
2488
2541
  {
2489
2542
  ariaLabel: isOpen ? "Hide canvas" : "Show canvas",
2490
2543
  tooltip: `${isOpen ? "Hide canvas" : "Show canvas"}${hint ? ` (${hint})` : ""}`,
@@ -2530,6 +2583,7 @@ export {
2530
2583
  useCanvasHostPorts,
2531
2584
  useCanvasIsPresented,
2532
2585
  useCanvasKind,
2586
+ useCanvasKindToggle,
2533
2587
  useCanvasKinds,
2534
2588
  useCanvasNativeBodies,
2535
2589
  useCanvasState,