@ai-matrx/summon 0.1.16 → 0.1.18

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/window.d.cts CHANGED
@@ -1,10 +1,12 @@
1
1
  import * as react from 'react';
2
2
  import react__default, { ComponentType, SVGAttributes, ReactNode } from 'react';
3
3
  import { WindowRect, WindowPersistenceRegistration, MobilePresentation } from '@ai-matrx/summon';
4
+ import { ResizeEdge as ResizeEdge$1 } from '@ai-matrx/design-system';
4
5
  import { TraySnapshotCapture } from '@ai-matrx/summon/window-host';
5
6
  export { DEFAULT_ESCAPE_YIELD_SELECTOR, DEFAULT_MOBILE_TOP_OFFSET, DEFAULT_WINDOW_CONFIG, PopoutContext, PopoutContextValue, PopoutMode, TrayPreviewContext, TrayPreviewEntry, TraySnapshotCapture, WindowConfig, WindowSelectionSurface, WindowSelectionSurfaceProps, WindowTraySync, WindowsProvider, WindowsProviderProps, getTrayPreviewEntry, registerTrayPreview, resetTrayPreviews, useOverlaySurfaceRenderAck, usePopout, usePopoutContainer, useWindowConfig } from '@ai-matrx/summon/window-host';
6
7
 
7
- type ResizeEdge = "e" | "s" | "se" | "w" | "sw" | "n" | "ne" | "nw";
8
+ /** The edge or corner a resize handle grabs (design-system window-drag). */
9
+ type ResizeEdge = ResizeEdge$1;
8
10
  /** Where to place the window when it first opens. */
9
11
  type WindowPosition = "center" | "top-right" | "top-left" | "bottom-right" | "bottom-left";
10
12
  declare function resetDefaultWindowCascade(): void;
package/dist/window.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import * as react from 'react';
2
2
  import react__default, { ComponentType, SVGAttributes, ReactNode } from 'react';
3
3
  import { WindowRect, WindowPersistenceRegistration, MobilePresentation } from '@ai-matrx/summon';
4
+ import { ResizeEdge as ResizeEdge$1 } from '@ai-matrx/design-system';
4
5
  import { TraySnapshotCapture } from '@ai-matrx/summon/window-host';
5
6
  export { DEFAULT_ESCAPE_YIELD_SELECTOR, DEFAULT_MOBILE_TOP_OFFSET, DEFAULT_WINDOW_CONFIG, PopoutContext, PopoutContextValue, PopoutMode, TrayPreviewContext, TrayPreviewEntry, TraySnapshotCapture, WindowConfig, WindowSelectionSurface, WindowSelectionSurfaceProps, WindowTraySync, WindowsProvider, WindowsProviderProps, getTrayPreviewEntry, registerTrayPreview, resetTrayPreviews, useOverlaySurfaceRenderAck, usePopout, usePopoutContainer, useWindowConfig } from '@ai-matrx/summon/window-host';
6
7
 
7
- type ResizeEdge = "e" | "s" | "se" | "w" | "sw" | "n" | "ne" | "nw";
8
+ /** The edge or corner a resize handle grabs (design-system window-drag). */
9
+ type ResizeEdge = ResizeEdge$1;
8
10
  /** Where to place the window when it first opens. */
9
11
  type WindowPosition = "center" | "top-right" | "top-left" | "bottom-right" | "bottom-left";
10
12
  declare function resetDefaultWindowCascade(): void;
package/dist/window.js CHANGED
@@ -396,21 +396,11 @@ function resolveAutoOpenPlacement(args) {
396
396
  }
397
397
 
398
398
  // src/window/useWindowPanel.ts
399
- import { holdDragCursor } from "@ai-matrx/design-system";
399
+ import { RESIZE_EDGE_CURSOR, resizeRect, startPointerDrag } from "@ai-matrx/design-system";
400
400
  var MIN_WIDTH = 180;
401
401
  var MIN_HEIGHT = 80;
402
402
  var DEFAULT_WIDTH = 320;
403
403
  var DEFAULT_HEIGHT = 400;
404
- var RESIZE_CURSOR = {
405
- e: "ew-resize",
406
- w: "ew-resize",
407
- n: "ns-resize",
408
- s: "ns-resize",
409
- se: "nwse-resize",
410
- nw: "nwse-resize",
411
- ne: "nesw-resize",
412
- sw: "nesw-resize"
413
- };
414
404
  function resolveSize(value, fallback) {
415
405
  if (value === void 0) return fallback;
416
406
  if (typeof value === "number") return value;
@@ -608,86 +598,53 @@ function useWindowPanel(opts = {}) {
608
598
  dispatch(updateWindowTitle({ id, title: opts.title }));
609
599
  }
610
600
  }, [id, opts.title, dispatch]);
611
- const dragStart = useRef(null);
612
601
  const onTriggerPopout = opts.onTriggerPopout;
613
602
  const onTriggerPopoutRef = useRef(onTriggerPopout);
614
603
  useEffect(() => {
615
604
  onTriggerPopoutRef.current = onTriggerPopout;
616
605
  }, [onTriggerPopout]);
606
+ const gestureRef = useRef(null);
607
+ useEffect(() => () => gestureRef.current?.cancel(), []);
617
608
  const onDragStart = useCallback(
618
609
  (e) => {
619
610
  e.preventDefault();
620
611
  dispatch(focusWindow(id));
621
612
  if (!entry || entry.state === "maximized") return;
622
- dragStart.current = {
623
- mx: e.clientX,
624
- my: e.clientY,
625
- wx: entry.windowed.x,
626
- wy: entry.windowed.y
627
- };
628
- setIsInteracting(true);
629
- const releaseCursor = holdDragCursor();
613
+ const origin = { x: entry.windowed.x, y: entry.windowed.y };
630
614
  let dragOutState = INITIAL_DRAG_OUT_STATE;
631
- let lastClientX = e.clientX;
632
- let lastClientY = e.clientY;
633
615
  const popoutEnabled = onTriggerPopoutRef.current !== void 0;
634
- const onMove = (ev) => {
635
- if (!dragStart.current) return;
636
- const nx = dragStart.current.wx + (ev.clientX - dragStart.current.mx);
637
- const ny = dragStart.current.wy + (ev.clientY - dragStart.current.my);
638
- dispatch(updateWindowRect({ id, rect: { x: nx, y: ny } }));
639
- lastClientX = ev.clientX;
640
- lastClientY = ev.clientY;
641
- if (!popoutEnabled) return;
642
- const result = evaluateDragOut(
643
- { clientX: ev.clientX, clientY: ev.clientY },
644
- dragOutState,
645
- DEFAULT_DRAG_OUT_CONFIG,
646
- window.innerWidth,
647
- window.innerHeight,
648
- performance.now()
649
- );
650
- if (result.state.isCandidate !== dragOutState.isCandidate) {
651
- dispatch(
652
- setPopoutCandidate({ id: result.state.isCandidate ? id : null })
616
+ gestureRef.current?.cancel();
617
+ gestureRef.current = startPointerDrag(e, {
618
+ onStart: () => setIsInteracting(true),
619
+ onMove: ({ dx, dy }, ev) => {
620
+ dispatch(updateWindowRect({ id, rect: { x: origin.x + dx, y: origin.y + dy } }));
621
+ if (!popoutEnabled) return;
622
+ const result = evaluateDragOut(
623
+ { clientX: ev.clientX, clientY: ev.clientY },
624
+ dragOutState,
625
+ DEFAULT_DRAG_OUT_CONFIG,
626
+ window.innerWidth,
627
+ window.innerHeight,
628
+ performance.now()
653
629
  );
654
- }
655
- dragOutState = result.state;
656
- };
657
- const onUp = () => {
658
- const wasCandidate = dragOutState.isCandidate;
659
- const dragOrigin = dragStart.current;
660
- dragStart.current = null;
661
- setIsInteracting(false);
662
- releaseCursor();
663
- document.removeEventListener("pointermove", onMove);
664
- document.removeEventListener("pointerup", onUp);
665
- document.removeEventListener("pointercancel", onUp);
666
- if (popoutEnabled && dragOutState.isCandidate) {
667
- dispatch(setPopoutCandidate({ id: null }));
668
- }
669
- if (wasCandidate && onTriggerPopoutRef.current && entry) {
670
- const lastRect = {
671
- x: dragOrigin?.wx ?? entry.windowed.x,
672
- y: dragOrigin?.wy ?? entry.windowed.y,
673
- width: entry.windowed.width,
674
- height: entry.windowed.height
675
- };
676
- onTriggerPopoutRef.current(lastRect);
677
- } else {
678
- const { vw, vh, degenerate } = safeViewportDims();
679
- if (!degenerate) {
680
- dispatch(
681
- clampWindowRect({ id, viewportWidth: vw, viewportHeight: vh })
682
- );
630
+ if (result.state.isCandidate !== dragOutState.isCandidate) {
631
+ dispatch(setPopoutCandidate({ id: result.state.isCandidate ? id : null }));
683
632
  }
633
+ dragOutState = result.state;
634
+ },
635
+ onEnd: () => {
636
+ gestureRef.current = null;
637
+ const wasCandidate = dragOutState.isCandidate;
638
+ setIsInteracting(false);
639
+ if (popoutEnabled && wasCandidate) dispatch(setPopoutCandidate({ id: null }));
640
+ if (wasCandidate && onTriggerPopoutRef.current) {
641
+ onTriggerPopoutRef.current({ x: origin.x, y: origin.y, width: entry.windowed.width, height: entry.windowed.height });
642
+ return;
643
+ }
644
+ const { vw, vh, degenerate } = safeViewportDims();
645
+ if (!degenerate) dispatch(clampWindowRect({ id, viewportWidth: vw, viewportHeight: vh }));
684
646
  }
685
- void lastClientX;
686
- void lastClientY;
687
- };
688
- document.addEventListener("pointermove", onMove);
689
- document.addEventListener("pointerup", onUp);
690
- document.addEventListener("pointercancel", onUp);
647
+ });
691
648
  },
692
649
  [dispatch, id, entry]
693
650
  );
@@ -697,44 +654,21 @@ function useWindowPanel(opts = {}) {
697
654
  e.stopPropagation();
698
655
  dispatch(focusWindow(id));
699
656
  if (!entry || entry.state !== "windowed") return;
700
- const startMx = e.clientX;
701
- const startMy = e.clientY;
702
- const { x, y, width, height } = entry.windowed;
703
- setIsInteracting(true);
704
- const releaseCursor = holdDragCursor(RESIZE_CURSOR[edge]);
705
- const onMove = (ev) => {
706
- const dx = ev.clientX - startMx;
707
- const dy = ev.clientY - startMy;
708
- let nx = x, ny = y, nw = width, nh = height;
709
- if (edge.includes("e"))
710
- nw = Math.min(maxWidth, Math.max(minWidth, width + dx));
711
- if (edge.includes("s"))
712
- nh = Math.min(maxHeight, Math.max(minHeight, height + dy));
713
- if (edge.includes("w")) {
714
- nw = Math.min(maxWidth, Math.max(minWidth, width - dx));
715
- nx = x + (width - nw);
716
- }
717
- if (edge.includes("n")) {
718
- nh = Math.min(maxHeight, Math.max(minHeight, height - dy));
719
- ny = y + (height - nh);
657
+ const origin = { ...entry.windowed };
658
+ gestureRef.current?.cancel();
659
+ gestureRef.current = startPointerDrag(e, {
660
+ // THE CURSOR LAW: the edge's resize cursor holds on <html> until release.
661
+ cursor: RESIZE_EDGE_CURSOR[edge],
662
+ onStart: () => setIsInteracting(true),
663
+ onMove: ({ dx, dy }) => {
664
+ const rect2 = resizeRect(origin, edge, dx, dy, { minWidth, minHeight, maxWidth, maxHeight });
665
+ dispatch(updateWindowRect({ id, rect: { x: rect2.x, y: rect2.y, width: rect2.width, height: rect2.height } }));
666
+ },
667
+ onEnd: () => {
668
+ gestureRef.current = null;
669
+ setIsInteracting(false);
720
670
  }
721
- dispatch(
722
- updateWindowRect({
723
- id,
724
- rect: { x: nx, y: ny, width: nw, height: nh }
725
- })
726
- );
727
- };
728
- const onUp = () => {
729
- setIsInteracting(false);
730
- releaseCursor();
731
- document.removeEventListener("pointermove", onMove);
732
- document.removeEventListener("pointerup", onUp);
733
- document.removeEventListener("pointercancel", onUp);
734
- };
735
- document.addEventListener("pointermove", onMove);
736
- document.addEventListener("pointerup", onUp);
737
- document.addEventListener("pointercancel", onUp);
671
+ });
738
672
  },
739
673
  [dispatch, id, entry, minWidth, minHeight, maxWidth, maxHeight]
740
674
  );
@@ -779,20 +713,15 @@ function useWindowPanel(opts = {}) {
779
713
  };
780
714
  }
781
715
 
782
- // src/window/utils/useIsClient.ts
783
- import { useSyncExternalStore } from "react";
784
- var subscribe = () => () => {
785
- };
786
- function useIsClient() {
787
- return useSyncExternalStore(subscribe, () => true, () => false);
788
- }
716
+ // src/window/WindowPanel.tsx
717
+ import { useIsClient } from "@ai-matrx/kit/client-lazy";
789
718
 
790
719
  // src/window/utils/useDebugFlag.ts
791
- import { useSyncExternalStore as useSyncExternalStore2 } from "react";
720
+ import { useSyncExternalStore } from "react";
792
721
  var noSubscribe = () => () => {
793
722
  };
794
723
  function useDebugFlag(debug) {
795
- return useSyncExternalStore2(
724
+ return useSyncExternalStore(
796
725
  debug.subscribe ? (listener) => debug.subscribe?.(listener) ?? (() => {
797
726
  }) : noSubscribe,
798
727
  () => debug.enabled(),
@@ -1379,7 +1308,7 @@ import {
1379
1308
  } from "@ai-matrx/summon";
1380
1309
 
1381
1310
  // src/window/popout/popoutWindowMap.ts
1382
- import { useSyncExternalStore as useSyncExternalStore3 } from "react";
1311
+ import { useSyncExternalStore as useSyncExternalStore2 } from "react";
1383
1312
  import { globalSlot as globalSlot3 } from "@ai-matrx/kit/global-slot";
1384
1313
  var slot = () => globalSlot3("ai-matrx.summon.window.popoutWindows", () => ({ map: /* @__PURE__ */ new Map(), listeners: /* @__PURE__ */ new Set() }));
1385
1314
  function notify() {
@@ -1412,7 +1341,7 @@ function subscribePopoutWindowMap(listener) {
1412
1341
  };
1413
1342
  }
1414
1343
  function usePopoutWindowRef(id) {
1415
- return useSyncExternalStore3(
1344
+ return useSyncExternalStore2(
1416
1345
  subscribePopoutWindowMap,
1417
1346
  () => getPopoutWindow(id),
1418
1347
  // SSR snapshot — popouts are never present during SSR.
@@ -2001,7 +1930,7 @@ async function isFlatImage(blob) {
2001
1930
  import { getOverlayMeta as getOverlayMeta2 } from "@ai-matrx/summon";
2002
1931
 
2003
1932
  // src/window/tray/TrayChipPreview.tsx
2004
- import { Component, memo, useSyncExternalStore as useSyncExternalStore4 } from "react";
1933
+ import { Component, memo, useSyncExternalStore as useSyncExternalStore3 } from "react";
2005
1934
  import { cn as cn8 } from "@ai-matrx/design-system/cn";
2006
1935
  import { getOverlayMeta, selectOverlayData, DEFAULT_INSTANCE_ID } from "@ai-matrx/summon";
2007
1936
  import { useSummonPorts as useSummonPorts2, useSummonSelector as useSummonSelector4 } from "@ai-matrx/summon/react";
@@ -2082,7 +2011,7 @@ var TraySnapshotImage = memo(function TraySnapshotImage2({
2082
2011
  registryLabel,
2083
2012
  title
2084
2013
  }) {
2085
- const snapshot = useSyncExternalStore4(
2014
+ const snapshot = useSyncExternalStore3(
2086
2015
  subscribeTraySnapshotMap,
2087
2016
  () => getTraySnapshot(snapshotKey),
2088
2017
  () => null