@gustavolmo/react-window-manager 0.4.1 → 0.4.2

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.
Files changed (35) hide show
  1. package/README.md +76 -130
  2. package/dist/index.js +345 -167
  3. package/dist/index.js.map +1 -1
  4. package/dist/window-manager/internal/features/cursor/cursor-move-listener.d.ts.map +1 -1
  5. package/dist/window-manager/internal/features/cursor/cursor-state.d.ts +5 -2
  6. package/dist/window-manager/internal/features/cursor/cursor-state.d.ts.map +1 -1
  7. package/dist/window-manager/internal/features/grid/grid-orchestrator.d.ts +3 -2
  8. package/dist/window-manager/internal/features/grid/grid-orchestrator.d.ts.map +1 -1
  9. package/dist/window-manager/internal/features/resizing/resizing-controls.d.ts.map +1 -1
  10. package/dist/window-manager/internal/features/window-layout.d.ts.map +1 -1
  11. package/dist/window-manager/internal/features/workspace/workspace-api.d.ts +2 -2
  12. package/dist/window-manager/internal/features/workspace/workspace-api.d.ts.map +1 -1
  13. package/dist/window-manager/internal/features/workspace/workspace-resize-listener.d.ts.map +1 -1
  14. package/dist/window-manager/internal/runtime/dock-resolver/dock-commands.d.ts +0 -3
  15. package/dist/window-manager/internal/runtime/dock-resolver/dock-commands.d.ts.map +1 -1
  16. package/dist/window-manager/internal/runtime/drag-resolver/drag-commands.d.ts +0 -1
  17. package/dist/window-manager/internal/runtime/drag-resolver/drag-commands.d.ts.map +1 -1
  18. package/dist/window-manager/internal/runtime/resize-resolver/resize-loop-rules.d.ts +3 -0
  19. package/dist/window-manager/internal/runtime/resize-resolver/resize-loop-rules.d.ts.map +1 -0
  20. package/dist/window-manager/internal/runtime/resize-resolver/resize-loop.d.ts.map +1 -1
  21. package/dist/window-manager/internal/runtime/rwm-runtime.d.ts +9 -6
  22. package/dist/window-manager/internal/runtime/rwm-runtime.d.ts.map +1 -1
  23. package/dist/window-manager/internal/runtime/workspace-resolver/workspace-commands.d.ts +4 -4
  24. package/dist/window-manager/internal/runtime/workspace-resolver/workspace-commands.d.ts.map +1 -1
  25. package/dist/window-manager/model/window-types.d.ts +5 -6
  26. package/dist/window-manager/model/window-types.d.ts.map +1 -1
  27. package/dist/window-manager/model/workspace-types.d.ts +1 -1
  28. package/dist/window-manager/model/workspace-types.d.ts.map +1 -1
  29. package/dist/window-manager/rwm.d.ts +4 -7
  30. package/dist/window-manager/rwm.d.ts.map +1 -1
  31. package/package.json +1 -1
  32. package/dist/window-manager/internal/features/stack/stack-api.d.ts +0 -4
  33. package/dist/window-manager/internal/features/stack/stack-api.d.ts.map +0 -1
  34. package/dist/window-manager/internal/runtime/stack-resolver/stack-commands.d.ts +0 -6
  35. package/dist/window-manager/internal/runtime/stack-resolver/stack-commands.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ var useWorkspaceState = create((set, get) => ({
7
7
  wsElement: null,
8
8
  setWsElement: (el) => set({ wsElement: el }),
9
9
  isGridEnabled: true,
10
- isDockPannelEnabled: true,
10
+ isDockPanelEnabled: true,
11
11
  responsiveBreak: "sm",
12
12
  isBelowBreakPoint: false,
13
13
  activeWindowId: "react-dynamic-window-instance0",
@@ -169,23 +169,21 @@ var dockCommandResolver = {
169
169
  ];
170
170
  }
171
171
  };
172
- var getDockDependencies = () => {
173
- const { wsRect } = useWorkspaceState.getState();
174
- return { wsRect };
175
- };
176
172
 
177
173
  // src/window-manager/internal/features/cursor/cursor-state.ts
178
- import { create as create2 } from "zustand";
179
- var useCursorState = create2((set) => ({
174
+ var cursorPosition = {
180
175
  x: 10,
181
- y: 10,
182
- setXY: (x, y) => set({ x, y })
183
- }));
176
+ y: 10
177
+ };
178
+ var setCursorPosition = ({ x, y }) => {
179
+ cursorPosition.x = x;
180
+ cursorPosition.y = y;
181
+ };
184
182
 
185
183
  // src/window-manager/internal/runtime/drag-resolver/drag-loop.ts
186
184
  var rafDragLoopResolver = {
187
185
  LOOP_DRAG: (targetWinId, commit) => {
188
- const { x, y } = useCursorState.getState();
186
+ const { x, y } = cursorPosition;
189
187
  const { winCoord, isDragging, windowId } = windowRegistry[targetWinId].getState();
190
188
  if (!isDragging)
191
189
  throw new Error(`LOOP_DRAG called with isDragging false for winId: ${windowId}`);
@@ -199,7 +197,7 @@ var rafDragLoopResolver = {
199
197
  var dragLoop = (targetWinId, pointerOffset, commit) => {
200
198
  const { winCoord, isDragging } = windowRegistry[targetWinId].getState();
201
199
  const { wsRect } = useWorkspaceState.getState();
202
- const { x, y } = useCursorState.getState();
200
+ const { x, y } = cursorPosition;
203
201
  if (!isDragging)
204
202
  return;
205
203
  let adjustedX = Math.round(x - pointerOffset.left);
@@ -249,9 +247,6 @@ var dragCommandResolver = {
249
247
  ];
250
248
  }
251
249
  };
252
- var isDragAllowed = () => {
253
- return !useWorkspaceState.getState().isBelowBreakPoint;
254
- };
255
250
 
256
251
  // src/window-manager/internal/runtime/focus-resolver/focus-commands.ts
257
252
  var focusCommandResolver = {
@@ -328,30 +323,12 @@ var focusCommandResolver = {
328
323
  }
329
324
  };
330
325
 
331
- // src/window-manager/internal/runtime/stack-resolver/stack-commands.ts
332
- var stackCommandResolver = {
333
- RESET_STACK: () => {
334
- const batchUpdate = [];
335
- for (const key of Object.keys(windowRegistry)) {
336
- const { resetFlag } = windowRegistry[key].getState();
337
- batchUpdate.push({
338
- winId: key,
339
- patch: {
340
- resetFlag: !resetFlag,
341
- // FIND ME: reset flag is anti-pattern
342
- isWindowClosed: true,
343
- isActive: false
344
- }
345
- });
346
- }
347
- return batchUpdate;
348
- }
349
- };
350
-
351
326
  // src/window-manager/internal/runtime/workspace-resolver/workspace-commands.ts
352
327
  var workspaceCommandResolver = {
353
- UPDATE_WORKSPACE_RECT: () => {
328
+ UPDATE_WORKSPACE_SIZE: () => {
329
+ const prevRect = useWorkspaceState.getState().wsRect;
354
330
  const rect = useWorkspaceState.getState().wsElement?.getBoundingClientRect();
331
+ const breakPoint = useWorkspaceState.getState().responsiveBreak;
355
332
  const top = rect?.top ?? 0;
356
333
  const left = rect?.left ?? 0;
357
334
  const innerHeight = rect?.height ?? 0;
@@ -360,10 +337,8 @@ var workspaceCommandResolver = {
360
337
  const right = left + innerWidth;
361
338
  const centerX = left + innerWidth / 2;
362
339
  const centerY = top + innerHeight / 2;
363
- const breakPoint = useWorkspaceState.getState().responsiveBreak;
364
- const isBelowBreakPoint = innerWidth < responsiveBreakInPx(breakPoint);
365
- return {
366
- isBelowBreakPoint,
340
+ const workspaceUpdate = {
341
+ isBelowBreakPoint: innerWidth < responsiveBreakInPx(breakPoint),
367
342
  wsRect: {
368
343
  top,
369
344
  left,
@@ -375,20 +350,50 @@ var workspaceCommandResolver = {
375
350
  centerY
376
351
  }
377
352
  };
353
+ const windowBatchUpdate = [];
354
+ const { innerHeight: prevWsHeight, innerWidth: prevWsWidth } = prevRect;
355
+ const currWsHeight = innerHeight;
356
+ const currWsWidth = innerWidth;
357
+ const widthChangeRatio = currWsWidth / prevWsWidth;
358
+ const heightChangeRatio = currWsHeight / prevWsHeight;
359
+ for (const key of Object.keys(windowRegistry)) {
360
+ const win = windowRegistry[key].getState();
361
+ windowBatchUpdate.push({
362
+ winId: key,
363
+ patch: {
364
+ winWidth: win.winWidth * widthChangeRatio,
365
+ winHeight: win.winHeight * heightChangeRatio,
366
+ winCoord: {
367
+ pointX: win.winCoord.pointX * widthChangeRatio,
368
+ pointY: win.winCoord.pointY * heightChangeRatio
369
+ }
370
+ }
371
+ });
372
+ }
373
+ return {
374
+ win: windowBatchUpdate,
375
+ ws: workspaceUpdate
376
+ };
378
377
  },
379
378
  SET_WORKSPACE_FEATURES: (_, ctx) => {
380
- if (ctx?.isGridEnabled === void 0 || ctx?.isDockPannelEnabled === void 0)
379
+ if (ctx?.isGridEnabled === void 0 || ctx?.isDockPanelEnabled === void 0)
381
380
  throw new Error(`SET_WORKSPACE_FEATURES called without a ctx value`);
382
381
  return {
383
- isGridEnabled: ctx.isGridEnabled,
384
- isDockPannelEnabled: ctx.isDockPannelEnabled
382
+ win: [],
383
+ ws: {
384
+ isGridEnabled: ctx.isGridEnabled,
385
+ isDockPanelEnabled: ctx.isDockPanelEnabled
386
+ }
385
387
  };
386
388
  },
387
389
  SET_RESPONSIVE_BREAK: (_, ctx) => {
388
390
  if (ctx?.responsiveBreak === void 0 || ctx?.responsiveBreak === null)
389
391
  throw new Error(`SET_RESPONSIVE_BREAK called without a ctx value`);
390
392
  return {
391
- responsiveBreak: ctx.responsiveBreak
393
+ win: [],
394
+ ws: {
395
+ responsiveBreak: ctx.responsiveBreak
396
+ }
392
397
  };
393
398
  }
394
399
  };
@@ -416,7 +421,7 @@ var resizeCommandResolver = {
416
421
  ENABLE_RESIZE: (targetWinId, direction) => {
417
422
  const currentResizeAction = windowRegistry[targetWinId].getState().resizeAction;
418
423
  if (currentResizeAction)
419
- throw new Error(`ENABLE_RESIZE called on a window that is already risizing`);
424
+ throw new Error(`ENABLE_RESIZE called on a window that is already resizing`);
420
425
  return [
421
426
  {
422
427
  winId: targetWinId,
@@ -440,6 +445,108 @@ var resizeCommandResolver = {
440
445
  }
441
446
  };
442
447
 
448
+ // src/window-manager/internal/runtime/resize-resolver/resize-loop-rules.ts
449
+ var resolveNeighbourResizeLimit = (activeWinId, direction) => {
450
+ switch (direction) {
451
+ case "e":
452
+ return neighbourResizeLimit.e(activeWinId);
453
+ case "w":
454
+ return neighbourResizeLimit.w(activeWinId);
455
+ case "n":
456
+ return neighbourResizeLimit.n(activeWinId);
457
+ case "s":
458
+ return neighbourResizeLimit.s(activeWinId);
459
+ default:
460
+ return void 0;
461
+ }
462
+ };
463
+ var neighbourResizeLimit = {
464
+ e: (activeWinId) => {
465
+ let leftMostXAtMinWidth = void 0;
466
+ for (const key of Object.keys(windowRegistry)) {
467
+ const neighbourWin = windowRegistry[key].getState();
468
+ if (key === activeWinId)
469
+ continue;
470
+ if (neighbourWin.resizeAction !== "w")
471
+ continue;
472
+ if (neighbourWin.isWindowClosed)
473
+ continue;
474
+ const winBox = neighbourWin.winElement?.getBoundingClientRect();
475
+ if (!winBox)
476
+ continue;
477
+ const xAtMinWidth = winBox.right - neighbourWin.WIN_MIN_WIDTH;
478
+ if (leftMostXAtMinWidth === void 0)
479
+ leftMostXAtMinWidth = xAtMinWidth;
480
+ if (leftMostXAtMinWidth > xAtMinWidth)
481
+ leftMostXAtMinWidth = xAtMinWidth;
482
+ }
483
+ return leftMostXAtMinWidth;
484
+ },
485
+ w: (activeWinId) => {
486
+ let rightMostXAtMinWidth = void 0;
487
+ for (const key of Object.keys(windowRegistry)) {
488
+ const neighbourWin = windowRegistry[key].getState();
489
+ if (key === activeWinId)
490
+ continue;
491
+ if (neighbourWin.resizeAction !== "e")
492
+ continue;
493
+ if (neighbourWin.isWindowClosed)
494
+ continue;
495
+ const winBox = neighbourWin.winElement?.getBoundingClientRect();
496
+ if (!winBox)
497
+ continue;
498
+ const xAtMinWidth = winBox.left + neighbourWin.WIN_MIN_WIDTH;
499
+ if (rightMostXAtMinWidth === void 0)
500
+ rightMostXAtMinWidth = xAtMinWidth;
501
+ if (rightMostXAtMinWidth < xAtMinWidth)
502
+ rightMostXAtMinWidth = xAtMinWidth;
503
+ }
504
+ return rightMostXAtMinWidth;
505
+ },
506
+ n: (currentWinId) => {
507
+ let bottomMostYAtMinWidth = void 0;
508
+ for (const key of Object.keys(windowRegistry)) {
509
+ const remoteWin = windowRegistry[key].getState();
510
+ if (key === currentWinId)
511
+ continue;
512
+ if (remoteWin.resizeAction !== "s")
513
+ continue;
514
+ if (remoteWin.isWindowClosed)
515
+ continue;
516
+ const winBox = remoteWin.winElement?.getBoundingClientRect();
517
+ if (!winBox)
518
+ continue;
519
+ const yAtMinWidth = winBox.top + remoteWin.WIN_MIN_HEIGHT;
520
+ if (bottomMostYAtMinWidth === void 0)
521
+ bottomMostYAtMinWidth = yAtMinWidth;
522
+ if (bottomMostYAtMinWidth < yAtMinWidth)
523
+ bottomMostYAtMinWidth = yAtMinWidth;
524
+ }
525
+ return bottomMostYAtMinWidth;
526
+ },
527
+ s: (currentWinId) => {
528
+ let topMostYAtMinWidth = void 0;
529
+ for (const key of Object.keys(windowRegistry)) {
530
+ const remoteWin = windowRegistry[key].getState();
531
+ if (key === currentWinId)
532
+ continue;
533
+ if (remoteWin.resizeAction !== "n")
534
+ continue;
535
+ if (remoteWin.isWindowClosed)
536
+ continue;
537
+ const winBox = remoteWin.winElement?.getBoundingClientRect();
538
+ if (!winBox)
539
+ continue;
540
+ const yAtMinWidth = winBox.bottom - remoteWin.WIN_MIN_HEIGHT;
541
+ if (topMostYAtMinWidth === void 0)
542
+ topMostYAtMinWidth = yAtMinWidth;
543
+ if (topMostYAtMinWidth > yAtMinWidth)
544
+ topMostYAtMinWidth = yAtMinWidth;
545
+ }
546
+ return topMostYAtMinWidth;
547
+ }
548
+ };
549
+
443
550
  // src/window-manager/internal/runtime/resize-resolver/resize-loop.ts
444
551
  var rafResizeLoopResolver = {
445
552
  LOOP_RESIZE: (targetWinId, commitCb) => {
@@ -450,95 +557,198 @@ var rafResizeLoopResolver = {
450
557
  const winElementBox = dep.winBox;
451
558
  if (!winElementBox)
452
559
  throw new Error(`LOOP_RESIZE called with null window element for winId: ${targetWinId}`);
453
- requestAnimationFrame(
454
- () => resizer[resizeDirection](getRafResizeDependencies(targetWinId), commitCb)
455
- );
560
+ requestAnimationFrame(() => {
561
+ const neighbourLimit = resolveNeighbourResizeLimit(dep.win.windowId, resizeDirection);
562
+ resizer[resizeDirection](getRafResizeDependencies(targetWinId), commitCb, neighbourLimit);
563
+ });
456
564
  }
457
565
  };
458
566
  var resizer = {
459
- e: (resizeDep, commit) => {
567
+ e: (resizeDep, commit, neighbourLimit) => {
460
568
  const { wsRect, win, winBox, x } = resizeDep;
461
569
  if (!win.resizeAction)
462
570
  return;
463
571
  if (!winBox)
464
572
  return;
465
573
  const cursorOutOfBounds = x > wsRect.right || x < wsRect.left;
466
- const minWinWidth = x - winBox.left < win.WIN_MIN_WIDTH;
467
574
  const sizeDiff = x - winBox.right;
468
- if (!minWinWidth && !cursorOutOfBounds && sizeDiff !== 0) {
575
+ const isResizeActive = !cursorOutOfBounds && sizeDiff !== 0;
576
+ const minWinWidth = x - winBox.left < win.WIN_MIN_WIDTH;
577
+ const leftMostXAtMinWidth = neighbourLimit;
578
+ const isNeighbourLimit = leftMostXAtMinWidth && x > leftMostXAtMinWidth;
579
+ if (isNeighbourLimit && isResizeActive) {
469
580
  commit([
470
581
  {
471
582
  winId: win.windowId,
472
- patch: { winWidth: Math.round(win.winWidth + sizeDiff) }
583
+ patch: { winWidth: leftMostXAtMinWidth - win.winCoord.pointX }
584
+ }
585
+ ]);
586
+ } else if (!minWinWidth && isResizeActive) {
587
+ commit([
588
+ {
589
+ winId: win.windowId,
590
+ patch: { winWidth: win.winWidth + sizeDiff }
591
+ }
592
+ ]);
593
+ } else if (minWinWidth && isResizeActive) {
594
+ commit([
595
+ {
596
+ winId: win.windowId,
597
+ patch: { winWidth: win.WIN_MIN_WIDTH }
473
598
  }
474
599
  ]);
475
600
  }
476
- requestAnimationFrame(() => resizer.e(getRafResizeDependencies(win.windowId), commit));
601
+ requestAnimationFrame(
602
+ () => resizer.e(getRafResizeDependencies(win.windowId), commit, neighbourLimit)
603
+ );
477
604
  },
478
- w: (resizeDep, commit) => {
605
+ w: (resizeDep, commit, neighbourLimit) => {
479
606
  const { wsRect, win, winBox, x } = resizeDep;
480
607
  if (!win.resizeAction)
481
608
  return;
482
609
  if (!winBox)
483
610
  return;
484
- const minWinWidth = winBox.right - x <= win.WIN_MIN_WIDTH;
485
611
  const cursorOutOfBounds = x > wsRect.right || x < wsRect.left;
486
612
  const sizeDiff = winBox.left - x;
487
- if (!minWinWidth && !cursorOutOfBounds && sizeDiff !== 0) {
613
+ const isResizeActive = !cursorOutOfBounds && sizeDiff !== 0;
614
+ const minWinWidth = winBox.right - x <= win.WIN_MIN_WIDTH;
615
+ const rightMostXAtMinWidth = neighbourLimit;
616
+ const isNeighbourLimit = rightMostXAtMinWidth && x < rightMostXAtMinWidth;
617
+ if (isNeighbourLimit) {
618
+ commit([
619
+ {
620
+ winId: win.windowId,
621
+ patch: {
622
+ winWidth: win.winCoord.pointX - rightMostXAtMinWidth + win.winWidth,
623
+ winCoord: {
624
+ pointX: rightMostXAtMinWidth,
625
+ pointY: win.winCoord.pointY
626
+ }
627
+ }
628
+ }
629
+ ]);
630
+ } else if (!minWinWidth && isResizeActive) {
488
631
  commit([
489
632
  {
490
633
  winId: win.windowId,
491
634
  patch: {
492
- winWidth: Math.round(win.winWidth + sizeDiff),
635
+ winWidth: win.winWidth + sizeDiff,
493
636
  winCoord: { pointX: x, pointY: win.winCoord.pointY }
494
637
  }
495
638
  }
496
639
  ]);
640
+ } else if (minWinWidth && isResizeActive) {
641
+ commit([
642
+ {
643
+ winId: win.windowId,
644
+ patch: {
645
+ winCoord: {
646
+ pointX: win.winCoord.pointX + win.winWidth - win.WIN_MIN_WIDTH,
647
+ pointY: win.winCoord.pointY
648
+ },
649
+ winWidth: win.WIN_MIN_WIDTH
650
+ }
651
+ }
652
+ ]);
497
653
  }
498
- requestAnimationFrame(() => resizer.w(getRafResizeDependencies(win.windowId), commit));
654
+ requestAnimationFrame(
655
+ () => resizer.w(getRafResizeDependencies(win.windowId), commit, neighbourLimit)
656
+ );
499
657
  },
500
- n: (resizeDep, commit) => {
658
+ n: (resizeDep, commit, neighbourLimit) => {
501
659
  const { wsRect, win, winBox, y } = resizeDep;
502
660
  if (!win.resizeAction)
503
661
  return;
504
662
  if (!winBox)
505
663
  return;
506
- const minWinHeight = winBox.bottom - y <= win.WIN_MIN_HEIGHT;
507
664
  const cursorOutOfBounds = y > wsRect.bottom || y < wsRect.top;
508
665
  const sizeDiff = winBox.top - y;
509
- if (!minWinHeight && !cursorOutOfBounds && sizeDiff !== 0) {
666
+ const isResizeActive = !cursorOutOfBounds && sizeDiff !== 0;
667
+ const minWinHeight = winBox.bottom - y <= win.WIN_MIN_HEIGHT;
668
+ const bottomMostYAtMinWidth = neighbourLimit;
669
+ const isNeighbourLimit = bottomMostYAtMinWidth && y < bottomMostYAtMinWidth;
670
+ if (isNeighbourLimit && isResizeActive) {
671
+ commit([
672
+ {
673
+ winId: win.windowId,
674
+ patch: {
675
+ winHeight: win.winCoord.pointY - bottomMostYAtMinWidth + win.winHeight,
676
+ winCoord: {
677
+ pointX: win.winCoord.pointX,
678
+ pointY: bottomMostYAtMinWidth
679
+ }
680
+ }
681
+ }
682
+ ]);
683
+ } else if (!minWinHeight && isResizeActive) {
510
684
  commit([
511
685
  {
512
686
  winId: win.windowId,
513
687
  patch: {
514
- winHeight: Math.round(win.winHeight + sizeDiff),
688
+ winHeight: win.winHeight + sizeDiff,
515
689
  winCoord: { pointX: win.winCoord.pointX, pointY: y }
516
690
  }
517
691
  }
518
692
  ]);
693
+ } else if (minWinHeight && isResizeActive) {
694
+ commit([
695
+ {
696
+ winId: win.windowId,
697
+ patch: {
698
+ winHeight: win.WIN_MIN_HEIGHT,
699
+ winCoord: {
700
+ pointX: win.winCoord.pointX,
701
+ pointY: win.winCoord.pointY + win.winHeight - win.WIN_MIN_HEIGHT
702
+ }
703
+ }
704
+ }
705
+ ]);
519
706
  }
520
- requestAnimationFrame(() => resizer.n(getRafResizeDependencies(win.windowId), commit));
707
+ requestAnimationFrame(
708
+ () => resizer.n(getRafResizeDependencies(win.windowId), commit, neighbourLimit)
709
+ );
521
710
  },
522
- s: (resizeDep, commit) => {
711
+ s: (resizeDep, commit, neighbourLimit) => {
523
712
  const { wsRect, win, winBox, y } = resizeDep;
524
713
  if (!win.resizeAction)
525
714
  return;
526
715
  if (!winBox)
527
716
  return;
528
- const minWinHeight = y - winBox.top < win.WIN_MIN_HEIGHT;
529
717
  const cursorOutOfBounds = y > wsRect.bottom || y < wsRect.top;
530
718
  const sizeDiff = y - winBox.bottom;
531
- if (!minWinHeight && !cursorOutOfBounds && sizeDiff !== 0) {
719
+ const isResizeActive = !cursorOutOfBounds && sizeDiff !== 0;
720
+ const minWinHeight = y - winBox.top < win.WIN_MIN_HEIGHT;
721
+ const topMostYAtMinWidth = neighbourLimit;
722
+ const isNeighbourLimit = topMostYAtMinWidth && y > topMostYAtMinWidth;
723
+ if (isNeighbourLimit && isResizeActive) {
532
724
  commit([
533
725
  {
534
726
  winId: win.windowId,
535
727
  patch: {
536
- winHeight: Math.round(win.winHeight + sizeDiff)
728
+ winHeight: topMostYAtMinWidth - win.winCoord.pointY
537
729
  }
538
730
  }
539
731
  ]);
732
+ } else if (!minWinHeight && isResizeActive) {
733
+ commit([
734
+ {
735
+ winId: win.windowId,
736
+ patch: {
737
+ winHeight: win.winHeight + sizeDiff
738
+ }
739
+ }
740
+ ]);
741
+ } else if (minWinHeight && isResizeActive) {
742
+ commit([
743
+ {
744
+ winId: win.windowId,
745
+ patch: { winHeight: win.WIN_MIN_HEIGHT }
746
+ }
747
+ ]);
540
748
  }
541
- requestAnimationFrame(() => resizer.s(getRafResizeDependencies(win.windowId), commit));
749
+ requestAnimationFrame(
750
+ () => resizer.s(getRafResizeDependencies(win.windowId), commit, neighbourLimit)
751
+ );
542
752
  },
543
753
  nw: (resizeDep, commit) => {
544
754
  const { wsRect, win, winBox, x, y } = resizeDep;
@@ -550,37 +760,27 @@ var resizer = {
550
760
  const cursorOutOfBoundsX = x > wsRect.right || x < wsRect.left;
551
761
  const isCursorOutOfBounds = cursorOutOfBoundsY || cursorOutOfBoundsX;
552
762
  if (isCursorOutOfBounds) {
553
- requestAnimationFrame(() => resizer.nw(getRafResizeDependencies(win.windowId), commit));
763
+ return;
554
764
  }
555
765
  const minWinHeight = winBox.bottom - y <= win.WIN_MIN_HEIGHT;
556
766
  const minWinWidth = winBox.right - x <= win.WIN_MIN_WIDTH;
557
767
  const sizeDiffY = winBox.top - y;
558
768
  const sizeDiffX = winBox.left - x;
559
- const stagedChagnes = [];
560
769
  if (sizeDiffY !== 0 || sizeDiffX !== 0) {
561
- stagedChagnes.push({
562
- winId: win.windowId,
563
- patch: {
564
- winCoord: {
565
- pointX: minWinWidth ? win.winCoord.pointX : x,
566
- pointY: minWinHeight ? win.winCoord.pointY : y
770
+ commit([
771
+ {
772
+ winId: win.windowId,
773
+ patch: {
774
+ winWidth: minWinWidth ? win.WIN_MIN_WIDTH : win.winWidth + sizeDiffX,
775
+ winHeight: minWinHeight ? win.WIN_MIN_HEIGHT : win.winHeight + sizeDiffY,
776
+ winCoord: {
777
+ pointX: minWinWidth ? win.winCoord.pointX + win.winWidth - win.WIN_MIN_WIDTH : x,
778
+ pointY: minWinHeight ? win.winCoord.pointY + win.winHeight - win.WIN_MIN_HEIGHT : y
779
+ }
567
780
  }
568
781
  }
569
- });
570
- }
571
- if (!minWinHeight && sizeDiffY !== 0) {
572
- stagedChagnes.push({
573
- winId: win.windowId,
574
- patch: { winHeight: Math.round(win.winHeight + sizeDiffY) }
575
- });
576
- }
577
- if (!minWinWidth && sizeDiffX !== 0) {
578
- stagedChagnes.push({
579
- winId: win.windowId,
580
- patch: { winWidth: Math.round(win.winWidth + sizeDiffX) }
581
- });
782
+ ]);
582
783
  }
583
- commit(stagedChagnes);
584
784
  requestAnimationFrame(() => resizer.nw(getRafResizeDependencies(win.windowId), commit));
585
785
  },
586
786
  se: (resizeDep, commit) => {
@@ -600,7 +800,7 @@ var getRafResizeDependencies = (winId) => {
600
800
  const win = windowRegistry[winId].getState();
601
801
  const winBox = win.winElement?.getBoundingClientRect();
602
802
  const wsRect = useWorkspaceState.getState().wsRect;
603
- const { x, y } = useCursorState.getState();
803
+ const { x, y } = cursorPosition;
604
804
  return { wsRect, win, winBox, x, y };
605
805
  };
606
806
 
@@ -610,18 +810,18 @@ var rwmRuntime = {
610
810
  switch (subsystem) {
611
811
  case "WORKSPACE": {
612
812
  const stagedChanges = workspaceCommandResolver[cmd](targetWinId, ctx);
613
- commitToWorkspace(stagedChanges);
813
+ commitBatch(stagedChanges);
614
814
  break;
615
815
  }
616
816
  case "DRAG": {
617
- if (!isDragAllowed())
817
+ if (useWorkspaceState.getState().isBelowBreakPoint)
618
818
  return;
619
819
  const stagedChanges = dragCommandResolver[cmd](targetWinId);
620
820
  commitToWindow(stagedChanges);
621
821
  break;
622
822
  }
623
823
  case "DOCK": {
624
- const { wsRect } = getDockDependencies();
824
+ const { wsRect } = useWorkspaceState.getState();
625
825
  const stagedChanges = dockCommandResolver[cmd](targetWinId, wsRect);
626
826
  commitToWindow(stagedChanges);
627
827
  break;
@@ -631,16 +831,15 @@ var rwmRuntime = {
631
831
  commitToWindow(stagedChanges);
632
832
  break;
633
833
  }
634
- case "STACK": {
635
- const stagedChanges = stackCommandResolver[cmd](targetWinId);
636
- commitToWindow(stagedChanges);
637
- break;
638
- }
639
834
  case "FOCUS": {
640
835
  const stagedChanges = focusCommandResolver[cmd](targetWinId);
641
836
  commitBatch(stagedChanges);
642
837
  break;
643
838
  }
839
+ default:
840
+ throw new Error(
841
+ `Unregistered rwmRuntime subsystem called: ${{ subsystem, cmd, targetWinId, ctx }}`
842
+ );
644
843
  }
645
844
  }
646
845
  };
@@ -648,7 +847,7 @@ var rafRuntime = {
648
847
  dispatch: ({ subsystem, cmd, targetWinId }) => {
649
848
  switch (subsystem) {
650
849
  case "RAF_DRAG": {
651
- if (!isDragAllowed())
850
+ if (useWorkspaceState.getState().isBelowBreakPoint)
652
851
  return;
653
852
  rafDragLoopResolver[cmd](targetWinId, commitToWindow);
654
853
  break;
@@ -657,6 +856,10 @@ var rafRuntime = {
657
856
  rafResizeLoopResolver[cmd](targetWinId, commitToWindow);
658
857
  break;
659
858
  }
859
+ default:
860
+ throw new Error(
861
+ `Unregistered rafRuntime subsystem called: ${{ subsystem, cmd, targetWinId }}`
862
+ );
660
863
  }
661
864
  }
662
865
  };
@@ -747,13 +950,6 @@ var focusApi = {
747
950
  }
748
951
  };
749
952
 
750
- // src/window-manager/internal/features/stack/stack-api.ts
751
- var stackApi = {
752
- resetStack: () => {
753
- rwmRuntime.dispatch({ subsystem: "STACK", cmd: "RESET_STACK" });
754
- }
755
- };
756
-
757
953
  // src/window-manager/internal/features/workspace/workspace-api.ts
758
954
  var wsApi = {
759
955
  /**
@@ -773,36 +969,35 @@ var wsApi = {
773
969
  ctx: { responsiveBreak: breakPoint }
774
970
  });
775
971
  },
776
- setWsFeatures: ({ isDockPannelEnabled = true, isGridEnabled = true }) => {
972
+ setWsFeatures: ({ isDockPanelEnabled = true, isGridEnabled = true }) => {
777
973
  rwmRuntime.dispatch({
778
974
  subsystem: "WORKSPACE",
779
975
  cmd: "SET_WORKSPACE_FEATURES",
780
- ctx: { isDockPannelEnabled, isGridEnabled }
976
+ ctx: { isDockPanelEnabled, isGridEnabled }
781
977
  });
782
978
  },
783
- updateWsRect: () => {
784
- rwmRuntime.dispatch({ subsystem: "WORKSPACE", cmd: "UPDATE_WORKSPACE_RECT" });
979
+ updateWsSize: () => {
980
+ rwmRuntime.dispatch({ subsystem: "WORKSPACE", cmd: "UPDATE_WORKSPACE_SIZE" });
785
981
  }
786
982
  };
787
983
 
788
984
  // src/window-manager/rwm.ts
789
- var { updateWsRect, ...publicWsApi } = wsApi;
985
+ var { updateWsSize, ...publicWsApi } = wsApi;
790
986
  var rwm = {
791
987
  dockApi,
792
988
  focusApi,
793
- stackApi,
794
989
  workspaceApi: publicWsApi,
795
990
  /**
796
991
  * @about
797
992
  * Zustand hook, can be used to access the current state of the workspace by either
798
- * calling `const { <someState> } = worskpaceState()` inside a component or by calling
799
- * `worskpaceState.getState()` anywhere.
993
+ * calling `const { <someState> } = workspaceState()` inside a component or by calling
994
+ * `workspaceState.getState()` anywhere.
800
995
  *
801
996
  * @note
802
997
  * The hook also exposes the `setState()` method, however, this is highly discouraged. Prefer calling
803
998
  * the exposed apis in rwm for state mutation.
804
999
  */
805
- worskpaceState: useWorkspaceState,
1000
+ workspaceState: useWorkspaceState,
806
1001
  /**
807
1002
  * @about
808
1003
  * use the syntax `const { <someState> } = windowRegistry[<winId>]()` inside a component to access
@@ -824,7 +1019,7 @@ import { useState } from "react";
824
1019
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
825
1020
  function DockingControls() {
826
1021
  const [isHovering, setIsHovering] = useState(false);
827
- const { activeWindowId, isDockPannelEnabled, isBelowBreakPoint } = useWorkspaceState();
1022
+ const { activeWindowId, isDockPanelEnabled, isBelowBreakPoint } = useWorkspaceState();
828
1023
  const { isDragging } = windowRegistry[activeWindowId]();
829
1024
  const cornerDockControl = /* @__PURE__ */ jsxs("div", { className: `flex xl:p-0 shrink-0 gap-0.5`, children: [
830
1025
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-center gap-0.5", children: [
@@ -892,7 +1087,7 @@ function DockingControls() {
892
1087
  }
893
1088
  )
894
1089
  ] });
895
- const windowDockPannel = /* @__PURE__ */ jsx(
1090
+ const windowDockPanel = /* @__PURE__ */ jsx(
896
1091
  "span",
897
1092
  {
898
1093
  className: "pointer-events-auto px-4 pb-3",
@@ -916,7 +1111,7 @@ function DockingControls() {
916
1111
  );
917
1112
  if (isBelowBreakPoint)
918
1113
  return;
919
- if (!isDockPannelEnabled)
1114
+ if (!isDockPanelEnabled)
920
1115
  return;
921
1116
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
922
1117
  "div",
@@ -926,7 +1121,7 @@ function DockingControls() {
926
1121
  transition-all duration-500
927
1122
  absolute z-50 flex items-center justify-center
928
1123
  w-full mx-auto pointer-events-none`,
929
- children: windowDockPannel
1124
+ children: windowDockPanel
930
1125
  }
931
1126
  ) });
932
1127
  }
@@ -956,15 +1151,14 @@ var resizeApi = {
956
1151
  import { useEffect } from "react";
957
1152
  import { Fragment as Fragment2, jsx as jsx2 } from "react/jsx-runtime";
958
1153
  function CursorMoveListener() {
959
- const { setXY } = useCursorState();
960
1154
  useEffect(() => {
961
1155
  const handlePointerMove = (e) => {
962
1156
  e.preventDefault();
963
- setXY(e.clientX, e.clientY);
1157
+ setCursorPosition({ x: e.clientX, y: e.clientY });
964
1158
  };
965
1159
  window.addEventListener("pointermove", handlePointerMove);
966
1160
  return () => window.removeEventListener("pointermove", handlePointerMove);
967
- }, [setXY]);
1161
+ }, []);
968
1162
  return /* @__PURE__ */ jsx2(Fragment2, {});
969
1163
  }
970
1164
 
@@ -977,8 +1171,7 @@ function WorkspaceResizeListener() {
977
1171
  if (!wsElement)
978
1172
  return;
979
1173
  const onResize = () => {
980
- wsApi.updateWsRect();
981
- stackApi.resetStack();
1174
+ wsApi.updateWsSize();
982
1175
  };
983
1176
  onResize();
984
1177
  const observer = new ResizeObserver(onResize);
@@ -1042,7 +1235,7 @@ function WorkspaceLayout({ children, className }) {
1042
1235
  }
1043
1236
 
1044
1237
  // src/window-manager/registration/window-store-factory.tsx
1045
- import { create as create3 } from "zustand";
1238
+ import { create as create2 } from "zustand";
1046
1239
 
1047
1240
  // src/window-manager/internal/features/window-layout.tsx
1048
1241
  import { useEffect as useEffect4, useRef as useRef2 } from "react";
@@ -1117,24 +1310,23 @@ function IconWinMinimize({ color }) {
1117
1310
 
1118
1311
  // src/window-manager/internal/features/grid/grid-orchestrator.ts
1119
1312
  var tolerance = 4;
1120
- var gridOrchestrator = {
1121
- attachAdjacentGridBehavior: (winId) => {
1313
+ var resizeOrchestrator = {
1314
+ initializeResize: (winId, direction) => {
1122
1315
  if (!useWorkspaceState.getState().isGridEnabled)
1123
1316
  return;
1124
1317
  if (getOpenWinCount() < 1)
1125
1318
  throw new Error(`gridOrchestrator initalized but all windows are closed`);
1126
- if (getDraggingWinCount() < 1)
1127
- throw new Error(`gridOrchestrator initalized but no window is currently resizing`);
1128
- attachAdjacentGridBehavior(winId);
1319
+ initNeighbourResizeBehavior(winId, /* @__PURE__ */ new Set(), direction);
1320
+ resizeApi.startResize(winId, direction);
1129
1321
  }
1130
1322
  };
1131
- var attachAdjacentGridBehavior = (winId, visited = /* @__PURE__ */ new Set()) => {
1323
+ var initNeighbourResizeBehavior = (winId, visited, direction) => {
1132
1324
  if (visited.has(winId))
1133
1325
  return;
1134
1326
  else
1135
1327
  visited.add(winId);
1136
1328
  const thisWin = windowRegistry[winId].getState();
1137
- const currentResize = thisWin.resizeAction;
1329
+ const currentResize = direction ? direction : thisWin.resizeAction;
1138
1330
  for (const key of Object.keys(windowRegistry)) {
1139
1331
  const remoteWin = windowRegistry[key].getState();
1140
1332
  if (remoteWin.windowId === thisWin.windowId)
@@ -1149,22 +1341,22 @@ var attachAdjacentGridBehavior = (winId, visited = /* @__PURE__ */ new Set()) =>
1149
1341
  if (currentResize === "e") {
1150
1342
  const isRemoteConneted = resizeCase.whenDraggingEast(dependencies);
1151
1343
  if (isRemoteConneted)
1152
- attachAdjacentGridBehavior(remoteWin.windowId, visited);
1344
+ initNeighbourResizeBehavior(remoteWin.windowId, visited);
1153
1345
  }
1154
1346
  if (currentResize === "w") {
1155
1347
  const isRemoteConneted = resizeCase.whenDragginWest(dependencies);
1156
1348
  if (isRemoteConneted)
1157
- attachAdjacentGridBehavior(remoteWin.windowId, visited);
1349
+ initNeighbourResizeBehavior(remoteWin.windowId, visited);
1158
1350
  }
1159
1351
  if (currentResize === "n") {
1160
1352
  const isRemoteConneted = resizeCase.whenDragginNorth(dependencies);
1161
1353
  if (isRemoteConneted)
1162
- attachAdjacentGridBehavior(remoteWin.windowId, visited);
1354
+ initNeighbourResizeBehavior(remoteWin.windowId, visited);
1163
1355
  }
1164
1356
  if (currentResize === "s") {
1165
1357
  const isRemoteConneted = resizeCase.whenDraggingSouth(dependencies);
1166
1358
  if (isRemoteConneted)
1167
- attachAdjacentGridBehavior(remoteWin.windowId, visited);
1359
+ initNeighbourResizeBehavior(remoteWin.windowId, visited);
1168
1360
  }
1169
1361
  }
1170
1362
  };
@@ -1261,13 +1453,6 @@ var buildDependencies = (thisWin, remoteWin) => {
1261
1453
  isRemoteOutside
1262
1454
  };
1263
1455
  };
1264
- var getDraggingWinCount = () => {
1265
- let isWindowResizingCount = 0;
1266
- for (const key of Object.keys(windowRegistry))
1267
- if (windowRegistry[key].getState().resizeAction)
1268
- isWindowResizingCount++;
1269
- return isWindowResizingCount;
1270
- };
1271
1456
  var getOpenWinCount = () => {
1272
1457
  let openWnidowCount = 0;
1273
1458
  for (const key of Object.keys(windowRegistry))
@@ -1281,8 +1466,7 @@ import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-run
1281
1466
  function ResizingControls({ winId }) {
1282
1467
  const { winCoord, winWidth, winHeight, resizeAction } = windowRegistry[winId]();
1283
1468
  const startResize = (direction) => {
1284
- resizeApi.startResize(winId, direction);
1285
- gridOrchestrator.attachAdjacentGridBehavior(winId);
1469
+ resizeOrchestrator.initializeResize(winId, direction);
1286
1470
  };
1287
1471
  const stopResize = () => {
1288
1472
  resizeApi.stopResize(winId);
@@ -1434,11 +1618,10 @@ function WindowLayout({
1434
1618
  const { wsElement, wsRect, isBelowBreakPoint } = useWorkspaceState();
1435
1619
  const windowRef = useRef2(null);
1436
1620
  const {
1621
+ setWinElement,
1437
1622
  windowId,
1438
1623
  zIndex,
1439
1624
  isActive,
1440
- setWinElement,
1441
- resetFlag,
1442
1625
  winVisualState,
1443
1626
  isWindowClosed,
1444
1627
  winCoord,
@@ -1447,15 +1630,11 @@ function WindowLayout({
1447
1630
  } = windowRegistry[winId]();
1448
1631
  useEffect4(() => {
1449
1632
  setWinElement(windowRef.current);
1450
- }, [setWinElement, windowRef.current]);
1633
+ }, [setWinElement]);
1451
1634
  useEffect4(() => {
1452
- if (isBelowBreakPoint) {
1453
- dockApi.maximizeWindow(winId);
1454
- } else {
1455
- dockingRoutes[defaultDock](winId);
1456
- }
1457
- }, [wsElement, resetFlag]);
1458
- const dockingRoutes = {
1635
+ dockingResolver[defaultDock](winId);
1636
+ }, [wsElement]);
1637
+ const dockingResolver = {
1459
1638
  right: dockApi.dockWindowRight,
1460
1639
  left: dockApi.dockWindowLeft,
1461
1640
  full: dockApi.maximizeWindow,
@@ -1500,10 +1679,10 @@ function WindowLayout({
1500
1679
  onPointerDown: () => focusApi.bringWindowToFocus(windowId),
1501
1680
  style: {
1502
1681
  backgroundColor: style?.windowBackgroundColor,
1503
- top: `${winCoord.pointY}px`,
1504
- left: `${winCoord.pointX}px`,
1505
- width: `${winWidth}px`,
1506
- height: `${winHeight}px`,
1682
+ top: isBelowBreakPoint ? wsRect.top : `${winCoord.pointY}px`,
1683
+ left: isBelowBreakPoint ? wsRect.left : `${winCoord.pointX}px`,
1684
+ width: isBelowBreakPoint ? wsRect.innerWidth : `${winWidth}px`,
1685
+ height: isBelowBreakPoint ? wsRect.innerHeight : `${winHeight}px`,
1507
1686
  zIndex: `${zIndex}`,
1508
1687
  /* MINIMIZE LOGIC */
1509
1688
  transition: "transform 0.2s ease-in-out, opacity 0.3s ease-in-out",
@@ -1530,7 +1709,7 @@ function WindowLayout({
1530
1709
  ]
1531
1710
  }
1532
1711
  ),
1533
- /* @__PURE__ */ jsx8(ResizingControls, { winId }),
1712
+ !isBelowBreakPoint && /* @__PURE__ */ jsx8(ResizingControls, { winId }),
1534
1713
  /* @__PURE__ */ jsx8("div", { className: `relative w-full h-[calc(100%-32px)] overflow-auto select-text`, children })
1535
1714
  ]
1536
1715
  }
@@ -1573,25 +1752,24 @@ function WindowButton({
1573
1752
 
1574
1753
  // src/window-manager/registration/window-store-factory.tsx
1575
1754
  import { jsx as jsx10 } from "react/jsx-runtime";
1576
- var defaultMinWidth = 232;
1577
- var defaultMinHeight = 128;
1755
+ var defaultMinWidth = 256;
1756
+ var defaultMinHeight = 64;
1578
1757
  var createWindowStore = () => {
1579
1758
  const zIndexAtLaunch = Object.keys(windowRegistry).length + 1;
1580
1759
  const windowInstanceId = `react-dynamic-window-instance${Object.keys(windowRegistry).length}`;
1581
- const storeInstance = create3((set, get) => ({
1760
+ const storeInstance = create2((set) => ({
1582
1761
  setWinElement: (ref) => set({ winElement: ref }),
1583
1762
  winElement: void 0,
1584
1763
  windowId: windowInstanceId,
1585
- resetFlag: false,
1586
1764
  zIndex: zIndexAtLaunch,
1587
1765
  winCoord: { pointX: 40, pointY: 40 },
1766
+ winWidth: defaultMinWidth,
1767
+ winHeight: defaultMinHeight,
1588
1768
  winVisualState: "demaximized",
1589
1769
  isActive: false,
1590
1770
  isDragging: false,
1591
1771
  isWindowClosed: true,
1592
1772
  resizeAction: false,
1593
- winWidth: defaultMinWidth,
1594
- winHeight: defaultMinHeight,
1595
1773
  WIN_MIN_WIDTH: defaultMinWidth,
1596
1774
  WIN_MIN_HEIGHT: defaultMinHeight
1597
1775
  }));