@surdeddd/wmkit 0.7.2 → 0.9.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.
Files changed (91) hide show
  1. package/README.md +60 -3
  2. package/README.ru.md +60 -3
  3. package/dist/angular.cjs +4 -3
  4. package/dist/angular.cjs.map +1 -1
  5. package/dist/angular.d.cts +2 -1
  6. package/dist/angular.d.ts +2 -1
  7. package/dist/angular.js +2 -1
  8. package/dist/angular.js.map +1 -1
  9. package/dist/binder-DGoj0xG1.d.cts +13 -0
  10. package/dist/binder-Lo13iTVB.d.ts +13 -0
  11. package/dist/chrome.cjs +122 -0
  12. package/dist/chrome.cjs.map +1 -0
  13. package/dist/chrome.d.cts +25 -0
  14. package/dist/chrome.d.ts +25 -0
  15. package/dist/chrome.js +114 -0
  16. package/dist/chrome.js.map +1 -0
  17. package/dist/chunk-5XVIC5LH.js +140 -0
  18. package/dist/chunk-5XVIC5LH.js.map +1 -0
  19. package/dist/chunk-BDHFXEJN.cjs +149 -0
  20. package/dist/chunk-BDHFXEJN.cjs.map +1 -0
  21. package/dist/{chunk-NJAI5R4J.cjs → chunk-TUGQX3CX.js} +205 -175
  22. package/dist/chunk-TUGQX3CX.js.map +1 -0
  23. package/dist/{chunk-FOWW4LXS.js → chunk-ZWUVWRUS.cjs} +236 -178
  24. package/dist/chunk-ZWUVWRUS.cjs.map +1 -0
  25. package/dist/devtools.cjs +330 -0
  26. package/dist/devtools.cjs.map +1 -0
  27. package/dist/devtools.d.cts +43 -0
  28. package/dist/devtools.d.ts +43 -0
  29. package/dist/devtools.js +326 -0
  30. package/dist/devtools.js.map +1 -0
  31. package/dist/gestures.cjs +219 -0
  32. package/dist/gestures.cjs.map +1 -0
  33. package/dist/gestures.d.cts +19 -0
  34. package/dist/gestures.d.ts +19 -0
  35. package/dist/gestures.js +215 -0
  36. package/dist/gestures.js.map +1 -0
  37. package/dist/index.cjs +35 -34
  38. package/dist/index.d.cts +3 -2
  39. package/dist/index.d.ts +3 -2
  40. package/dist/index.js +2 -1
  41. package/dist/react.cjs +4 -3
  42. package/dist/react.cjs.map +1 -1
  43. package/dist/react.d.cts +2 -1
  44. package/dist/react.d.ts +2 -1
  45. package/dist/react.js +2 -1
  46. package/dist/react.js.map +1 -1
  47. package/dist/{binder-DvQFmO3K.d.ts → shared-BoHXlPCu.d.ts} +55 -8
  48. package/dist/{binder-_L3Iww0u.d.cts → shared-DdGFz3oy.d.cts} +55 -8
  49. package/dist/solid.cjs +4 -3
  50. package/dist/solid.cjs.map +1 -1
  51. package/dist/solid.d.cts +2 -1
  52. package/dist/solid.d.ts +2 -1
  53. package/dist/solid.js +2 -1
  54. package/dist/solid.js.map +1 -1
  55. package/dist/svelte.cjs +4 -3
  56. package/dist/svelte.cjs.map +1 -1
  57. package/dist/svelte.d.cts +2 -1
  58. package/dist/svelte.d.ts +2 -1
  59. package/dist/svelte.js +2 -1
  60. package/dist/svelte.js.map +1 -1
  61. package/dist/themes/amber.css +316 -0
  62. package/dist/themes/aqua.css +285 -0
  63. package/dist/themes/blueprint.css +303 -0
  64. package/dist/themes/brutalist.css +307 -0
  65. package/dist/themes/candy.css +277 -0
  66. package/dist/themes/carbon.css +297 -0
  67. package/dist/themes/forest.css +278 -0
  68. package/dist/themes/frost.css +279 -0
  69. package/dist/themes/glass.css +2 -1
  70. package/dist/themes/light.css +2 -1
  71. package/dist/themes/neon.css +289 -0
  72. package/dist/themes/noir.css +282 -0
  73. package/dist/themes/paper.css +258 -0
  74. package/dist/themes/retro.css +8 -0
  75. package/dist/themes/synth.css +283 -0
  76. package/dist/themes/terminal.css +273 -0
  77. package/dist/themes.cjs +8747 -0
  78. package/dist/themes.cjs.map +1 -0
  79. package/dist/themes.d.cts +12 -0
  80. package/dist/themes.d.ts +12 -0
  81. package/dist/themes.js +8742 -0
  82. package/dist/themes.js.map +1 -0
  83. package/dist/vue.cjs +4 -3
  84. package/dist/vue.cjs.map +1 -1
  85. package/dist/vue.d.cts +2 -1
  86. package/dist/vue.d.ts +2 -1
  87. package/dist/vue.js +2 -1
  88. package/dist/vue.js.map +1 -1
  89. package/package.json +80 -7
  90. package/dist/chunk-FOWW4LXS.js.map +0 -1
  91. package/dist/chunk-NJAI5R4J.cjs.map +0 -1
@@ -1,3 +1,7 @@
1
+ 'use strict';
2
+
3
+ var chunkBDHFXEJN_cjs = require('./chunk-BDHFXEJN.cjs');
4
+
1
5
  // src/core/emitter.ts
2
6
  function createEmitter() {
3
7
  const listeners = /* @__PURE__ */ new Map();
@@ -26,143 +30,6 @@ function createEmitter() {
26
30
  };
27
31
  }
28
32
 
29
- // src/core/geometry.ts
30
- function clamp(value, min, max) {
31
- return Math.min(Math.max(value, min), max);
32
- }
33
- function clampSize(size, min, max) {
34
- return {
35
- width: clamp(size.width, min.width, max ? max.width : Number.POSITIVE_INFINITY),
36
- height: clamp(size.height, min.height, max ? max.height : Number.POSITIVE_INFINITY)
37
- };
38
- }
39
- function clampToViewport(bounds, viewport, minVisible) {
40
- if (viewport.width <= 0 || viewport.height <= 0) return bounds;
41
- const visibleX = Math.min(minVisible, bounds.width);
42
- const visibleY = Math.min(minVisible, bounds.height);
43
- const x = clamp(bounds.x, visibleX - bounds.width, Math.max(0, viewport.width - visibleX));
44
- const y = clamp(bounds.y, 0, Math.max(0, viewport.height - visibleY));
45
- return x === bounds.x && y === bounds.y ? bounds : { ...bounds, x, y };
46
- }
47
- function boundsEqual(a, b) {
48
- return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
49
- }
50
- function applyAspect(size, ratio, min, max, drive) {
51
- if (!Number.isFinite(ratio) || ratio <= 0) return clampSize(size, min, max);
52
- const maxWidth = max ? max.width : Number.POSITIVE_INFINITY;
53
- const maxHeight = max ? max.height : Number.POSITIVE_INFINITY;
54
- if (drive === "height") {
55
- const height = clamp(
56
- size.height,
57
- Math.max(min.height, min.width / ratio),
58
- Math.min(maxHeight, maxWidth / ratio)
59
- );
60
- return { width: height * ratio, height };
61
- }
62
- const width = clamp(
63
- size.width,
64
- Math.max(min.width, min.height * ratio),
65
- Math.min(maxWidth, maxHeight * ratio)
66
- );
67
- return { width, height: width / ratio };
68
- }
69
- function zoneBounds(zone, viewport) {
70
- const w = viewport.width;
71
- const h = viewport.height;
72
- const halfW = Math.round(w / 2);
73
- const halfH = Math.round(h / 2);
74
- const oneThird = Math.round(w / 3);
75
- const twoThirds = Math.round(w * 2 / 3);
76
- switch (zone) {
77
- case "left-third":
78
- return { x: 0, y: 0, width: oneThird, height: h };
79
- case "center-third":
80
- return { x: oneThird, y: 0, width: twoThirds - oneThird, height: h };
81
- case "right-third":
82
- return { x: twoThirds, y: 0, width: w - twoThirds, height: h };
83
- case "left":
84
- return { x: 0, y: 0, width: halfW, height: h };
85
- case "right":
86
- return { x: halfW, y: 0, width: w - halfW, height: h };
87
- case "top":
88
- return { x: 0, y: 0, width: w, height: halfH };
89
- case "bottom":
90
- return { x: 0, y: halfH, width: w, height: h - halfH };
91
- case "top-left":
92
- return { x: 0, y: 0, width: halfW, height: halfH };
93
- case "top-right":
94
- return { x: halfW, y: 0, width: w - halfW, height: halfH };
95
- case "bottom-left":
96
- return { x: 0, y: halfH, width: halfW, height: h - halfH };
97
- case "bottom-right":
98
- return { x: halfW, y: halfH, width: w - halfW, height: h - halfH };
99
- }
100
- }
101
- function detectSnapZone(x, y, viewport, options = {}) {
102
- const threshold = options.threshold ?? 12;
103
- const cornerSize = options.cornerSize ?? 64;
104
- const w = viewport.width;
105
- const h = viewport.height;
106
- if (w <= 0 || h <= 0) return null;
107
- const nearLeft = x <= threshold;
108
- const nearRight = x >= w - threshold;
109
- const nearTop = y <= threshold;
110
- const nearBottom = y >= h - threshold;
111
- if (nearLeft || nearRight) {
112
- const side = nearLeft ? "left" : "right";
113
- if (y <= cornerSize) return `top-${side}`;
114
- if (y >= h - cornerSize) return `bottom-${side}`;
115
- return side;
116
- }
117
- if (nearTop) {
118
- if (x <= cornerSize) return "top-left";
119
- if (x >= w - cornerSize) return "top-right";
120
- return "top";
121
- }
122
- if (nearBottom) {
123
- if (x <= cornerSize) return "bottom-left";
124
- if (x >= w - cornerSize) return "bottom-right";
125
- return "bottom";
126
- }
127
- return null;
128
- }
129
- function nearestEdge(low, high, targetLow, targetHigh) {
130
- return [targetLow - low, targetHigh - low, targetLow - high, targetHigh - high];
131
- }
132
- function magnetize(bounds, targets, threshold) {
133
- const result = { x: bounds.x, y: bounds.y, snappedX: false, snappedY: false };
134
- if (threshold <= 0 || targets.length === 0) return result;
135
- let bestX = threshold + 1;
136
- let bestY = threshold + 1;
137
- for (const target of targets) {
138
- for (const delta of nearestEdge(
139
- bounds.x,
140
- bounds.x + bounds.width,
141
- target.x,
142
- target.x + target.width
143
- )) {
144
- if (Math.abs(delta) <= threshold && Math.abs(delta) < Math.abs(bestX)) bestX = delta;
145
- }
146
- for (const delta of nearestEdge(
147
- bounds.y,
148
- bounds.y + bounds.height,
149
- target.y,
150
- target.y + target.height
151
- )) {
152
- if (Math.abs(delta) <= threshold && Math.abs(delta) < Math.abs(bestY)) bestY = delta;
153
- }
154
- }
155
- if (Math.abs(bestX) <= threshold) {
156
- result.x = bounds.x + bestX;
157
- result.snappedX = true;
158
- }
159
- if (Math.abs(bestY) <= threshold) {
160
- result.y = bounds.y + bestY;
161
- result.snappedY = true;
162
- }
163
- return result;
164
- }
165
-
166
33
  // src/core/manager.ts
167
34
  var LAYER_RANK = { normal: 0, floating: 1, modal: 2 };
168
35
  var STAGES = ["normal", "minimized", "maximized", "snapped"];
@@ -346,7 +213,7 @@ function createWindowManager(options = {}) {
346
213
  for (const id of members) {
347
214
  if (id === effective.id) continue;
348
215
  const member = windows[id];
349
- if (boundsEqual(member.bounds, effective.bounds) && member.stage === effective.stage && member.snapZone === effective.snapZone && member.layer === effective.layer && member.workspace === effective.workspace) {
216
+ if (chunkBDHFXEJN_cjs.boundsEqual(member.bounds, effective.bounds) && member.stage === effective.stage && member.snapZone === effective.snapZone && member.layer === effective.layer && member.workspace === effective.workspace) {
350
217
  continue;
351
218
  }
352
219
  setWindow({
@@ -411,8 +278,8 @@ function createWindowManager(options = {}) {
411
278
  queueEvent(() => emitter.emit("focus", { window: win, previous }));
412
279
  }
413
280
  function normalizeSize(size, win, drive = "width") {
414
- if (win.aspectRatio === null) return clampSize(size, win.minSize, win.maxSize);
415
- return applyAspect(size, win.aspectRatio, win.minSize, win.maxSize, drive);
281
+ if (win.aspectRatio === null) return chunkBDHFXEJN_cjs.clampSize(size, win.minSize, win.maxSize);
282
+ return chunkBDHFXEJN_cjs.applyAspect(size, win.aspectRatio, win.minSize, win.maxSize, drive);
416
283
  }
417
284
  function positionForOpen(init) {
418
285
  if (init.x !== void 0 && init.y !== void 0) return { x: init.x, y: init.y };
@@ -439,7 +306,7 @@ function createWindowManager(options = {}) {
439
306
  width: init.width ?? defaultSize.width,
440
307
  height: init.height ?? defaultSize.height
441
308
  };
442
- const size = aspectRatio === null ? clampSize(requested, minSize, maxSize) : applyAspect(
309
+ const size = aspectRatio === null ? chunkBDHFXEJN_cjs.clampSize(requested, minSize, maxSize) : chunkBDHFXEJN_cjs.applyAspect(
443
310
  requested,
444
311
  aspectRatio,
445
312
  minSize,
@@ -448,7 +315,7 @@ function createWindowManager(options = {}) {
448
315
  );
449
316
  const position = positionForOpen(init);
450
317
  let bounds = { ...position, ...size };
451
- if (keepInViewport) bounds = clampToViewport(bounds, viewport, minVisible);
318
+ if (keepInViewport) bounds = chunkBDHFXEJN_cjs.clampToViewport(bounds, viewport, minVisible);
452
319
  const requestedStage = init.stage ?? "normal";
453
320
  const stage = requestedStage === "snapped" ? "normal" : requestedStage;
454
321
  let win = {
@@ -569,7 +436,7 @@ function createWindowManager(options = {}) {
569
436
  return { x: 0, y: 0, width: viewport.width, height: viewport.height };
570
437
  }
571
438
  function snapBounds(win, zone) {
572
- const rect = zoneBounds(zone, viewport);
439
+ const rect = chunkBDHFXEJN_cjs.zoneBounds(zone, viewport);
573
440
  const byWidth = normalizeSize(rect, win);
574
441
  const size = byWidth.height > rect.height ? normalizeSize(rect, win, "height") : byWidth;
575
442
  return {
@@ -654,7 +521,7 @@ function createWindowManager(options = {}) {
654
521
  snapZone: null,
655
522
  restoreBounds: null,
656
523
  restoreStage: null,
657
- bounds: keepInViewport ? clampToViewport(bounds, viewport, minVisible) : bounds
524
+ bounds: keepInViewport ? chunkBDHFXEJN_cjs.clampToViewport(bounds, viewport, minVisible) : bounds
658
525
  };
659
526
  });
660
527
  if (result) focusUnlessBlocked(id);
@@ -670,7 +537,7 @@ function createWindowManager(options = {}) {
670
537
  snapZone: null,
671
538
  restoreBounds: null,
672
539
  restoreStage: null,
673
- bounds: keepInViewport ? clampToViewport(next, viewport, minVisible) : next
540
+ bounds: keepInViewport ? chunkBDHFXEJN_cjs.clampToViewport(next, viewport, minVisible) : next
674
541
  };
675
542
  });
676
543
  if (result) focusUnlessBlocked(id);
@@ -695,8 +562,8 @@ function createWindowManager(options = {}) {
695
562
  const win = windows[id];
696
563
  if (win?.stage !== "normal") return false;
697
564
  let bounds = { ...win.bounds, x, y };
698
- if (keepInViewport) bounds = clampToViewport(bounds, viewport, minVisible);
699
- if (boundsEqual(bounds, win.bounds)) return true;
565
+ if (keepInViewport) bounds = chunkBDHFXEJN_cjs.clampToViewport(bounds, viewport, minVisible);
566
+ if (chunkBDHFXEJN_cjs.boundsEqual(bounds, win.bounds)) return true;
700
567
  const next = { ...win, bounds };
701
568
  setWindow(next);
702
569
  syncGroup(next);
@@ -716,9 +583,9 @@ function createWindowManager(options = {}) {
716
583
  const drive = Math.abs(merged.height - win.bounds.height) > Math.abs(merged.width - win.bounds.width) ? "height" : "width";
717
584
  const size = normalizeSize(merged, win, drive);
718
585
  let bounds = { x: merged.x, y: merged.y, ...size };
719
- if (keepInViewport) bounds = clampToViewport(bounds, viewport, minVisible);
586
+ if (keepInViewport) bounds = chunkBDHFXEJN_cjs.clampToViewport(bounds, viewport, minVisible);
720
587
  const becameNormal = win.stage === "snapped";
721
- if (boundsEqual(bounds, win.bounds) && !becameNormal) return true;
588
+ if (chunkBDHFXEJN_cjs.boundsEqual(bounds, win.bounds) && !becameNormal) return true;
722
589
  const next = becameNormal ? { ...win, stage: "normal", snapZone: null, restoreBounds: null, bounds } : { ...win, bounds };
723
590
  setWindow(next);
724
591
  const synced = syncGroup(next);
@@ -1014,8 +881,8 @@ function createWindowManager(options = {}) {
1014
881
  const synced = syncGroup(updated);
1015
882
  queueEvent(() => emitter.emit("resize", { window: synced }));
1016
883
  } else if (win.stage === "normal" && keepInViewport) {
1017
- const bounds = clampToViewport(win.bounds, viewport, minVisible);
1018
- if (!boundsEqual(bounds, win.bounds)) {
884
+ const bounds = chunkBDHFXEJN_cjs.clampToViewport(win.bounds, viewport, minVisible);
885
+ if (!chunkBDHFXEJN_cjs.boundsEqual(bounds, win.bounds)) {
1019
886
  const updated = { ...win, bounds };
1020
887
  setWindow(updated);
1021
888
  syncGroup(updated);
@@ -1502,6 +1369,22 @@ function createAnnouncer(wm, container, messages = {}) {
1502
1369
  };
1503
1370
  }
1504
1371
 
1372
+ // src/dom/actions.ts
1373
+ function createActions(wm, id) {
1374
+ return {
1375
+ focus: () => wm.focus(id),
1376
+ close: () => wm.close(id),
1377
+ minimize: () => wm.minimize(id),
1378
+ maximize: () => wm.maximize(id),
1379
+ toggleMaximize: () => wm.toggleMaximize(id),
1380
+ restore: () => wm.restore(id),
1381
+ center: () => wm.center(id),
1382
+ sendToBack: () => wm.sendToBack(id),
1383
+ snap: (zone) => wm.snap(id, zone),
1384
+ moveToWorkspace: (workspace) => wm.moveToWorkspace(id, workspace)
1385
+ };
1386
+ }
1387
+
1505
1388
  // src/dom/drag.ts
1506
1389
  function createDragStarter(ctx) {
1507
1390
  const { wm, doc, view } = ctx;
@@ -1519,7 +1402,7 @@ function createDragStarter(ctx) {
1519
1402
  pointerId: event.pointerId,
1520
1403
  grabDX: point.x - startBounds.x,
1521
1404
  grabDY: point.y - startBounds.y,
1522
- grabRatio: clamp((point.x - startBounds.x) / startBounds.width, 0.05, 0.95),
1405
+ grabRatio: chunkBDHFXEJN_cjs.clamp((point.x - startBounds.x) / startBounds.width, 0.05, 0.95),
1523
1406
  startBounds,
1524
1407
  startStage: win.stage,
1525
1408
  startZone: win.snapZone,
@@ -1536,8 +1419,7 @@ function createDragStarter(ctx) {
1536
1419
  pendingX: 0,
1537
1420
  pendingY: 0,
1538
1421
  hasPending: false,
1539
- finish: () => {
1540
- }
1422
+ finish: (cancelled) => finish(cancelled)
1541
1423
  };
1542
1424
  const el = ctx.windowElement(id);
1543
1425
  function armGroup(target2) {
@@ -1592,7 +1474,7 @@ function createDragStarter(ctx) {
1592
1474
  if (other.groupId !== null && state.groups[other.groupId]?.activeId !== otherId) continue;
1593
1475
  targets.push(other.bounds);
1594
1476
  }
1595
- const magnet = magnetize(
1477
+ const magnet = chunkBDHFXEJN_cjs.magnetize(
1596
1478
  { x: nextX, y: nextY, width: current.bounds.width, height: current.bounds.height },
1597
1479
  targets,
1598
1480
  ctx.magnetThreshold
@@ -1617,7 +1499,7 @@ function createDragStarter(ctx) {
1617
1499
  }
1618
1500
  if (ctx.snapEnabled && current.snappable) {
1619
1501
  const viewport = wm.getState().viewport;
1620
- const rawZone = detectSnapZone(session.pendingX, session.pendingY, viewport, ctx.snapDetect);
1502
+ const rawZone = chunkBDHFXEJN_cjs.detectSnapZone(session.pendingX, session.pendingY, viewport, ctx.snapDetect);
1621
1503
  let zone = rawZone;
1622
1504
  if (rawZone === "top") {
1623
1505
  if (ctx.topEdge === "maximize") zone = current.maximizable ? "maximize" : null;
@@ -1626,7 +1508,7 @@ function createDragStarter(ctx) {
1626
1508
  session.zone = zone;
1627
1509
  if (zone) {
1628
1510
  ctx.showPreview(
1629
- zone === "maximize" ? { x: 0, y: 0, width: viewport.width, height: viewport.height } : zoneBounds(zone, viewport)
1511
+ zone === "maximize" ? { x: 0, y: 0, width: viewport.width, height: viewport.height } : chunkBDHFXEJN_cjs.zoneBounds(zone, viewport)
1630
1512
  );
1631
1513
  } else {
1632
1514
  ctx.hidePreview();
@@ -1710,7 +1592,6 @@ function createDragStarter(ctx) {
1710
1592
  else wm.endInteraction();
1711
1593
  }
1712
1594
  }
1713
- session.finish = finish;
1714
1595
  wm.beginInteraction();
1715
1596
  ctx.claimDrag(session);
1716
1597
  handle.setPointerCapture(event.pointerId);
@@ -1773,10 +1654,10 @@ function createResizeStarter(ctx) {
1773
1654
  width: direction.includes("e") ? start.width + dx : direction.includes("w") ? start.width - dx : start.width,
1774
1655
  height: direction.includes("s") ? start.height + dy : direction.includes("n") ? start.y + start.height - top : start.height
1775
1656
  };
1776
- let size = aspect === null ? clampSize(raw, minSize, maxSize) : applyAspect(raw, aspect, minSize, maxSize, drive);
1657
+ let size = aspect === null ? chunkBDHFXEJN_cjs.clampSize(raw, minSize, maxSize) : chunkBDHFXEJN_cjs.applyAspect(raw, aspect, minSize, maxSize, drive);
1777
1658
  const available = start.y + start.height - floor;
1778
1659
  if (direction.includes("n") && size.height > available) {
1779
- size = applyAspect({ ...size, height: available }, aspect ?? 0, minSize, maxSize, "height");
1660
+ size = chunkBDHFXEJN_cjs.applyAspect({ ...size, height: available }, aspect ?? 0, minSize, maxSize, "height");
1780
1661
  }
1781
1662
  const next = {
1782
1663
  x: direction.includes("w") ? start.x + start.width - size.width : start.x,
@@ -1865,7 +1746,7 @@ function createResizeHandles(doc, edge, corner) {
1865
1746
  }
1866
1747
 
1867
1748
  // src/dom/shared.ts
1868
- var INTERACTIVE_SELECTOR = "button, input, select, textarea, a[href], [contenteditable], [data-wm-close], [data-wm-minimize], [data-wm-maximize]";
1749
+ var INTERACTIVE_SELECTOR = "button, input, select, textarea, a[href], [contenteditable], [data-wm-close], [data-wm-minimize], [data-wm-maximize], [data-wm-snap], [data-wm-restore], [data-wm-center], [data-wm-send-back], [data-wm-to-workspace]";
1869
1750
  function windowOf(element) {
1870
1751
  const view = element.ownerDocument.defaultView;
1871
1752
  if (!view) throw new Error("wmkit: desktop element is not attached to a document");
@@ -1962,8 +1843,53 @@ var SNAP_SHORTCUTS = {
1962
1843
  ArrowLeft: "left",
1963
1844
  ArrowRight: "right"
1964
1845
  };
1846
+ var SNAP_ZONES = /* @__PURE__ */ new Set([
1847
+ "left",
1848
+ "right",
1849
+ "top",
1850
+ "bottom",
1851
+ "top-left",
1852
+ "top-right",
1853
+ "bottom-left",
1854
+ "bottom-right",
1855
+ "left-third",
1856
+ "center-third",
1857
+ "right-third"
1858
+ ]);
1965
1859
  var LANDMARK_TAGS = /* @__PURE__ */ new Set(["header", "footer", "aside", "nav"]);
1966
1860
  var FOCUSABLE_SELECTOR = 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
1861
+ function focusablesOf(el) {
1862
+ const root = el.shadowRoot;
1863
+ if (!root) return [...el.querySelectorAll(FOCUSABLE_SELECTOR)];
1864
+ const found = [];
1865
+ for (const node of root.querySelectorAll(`${FOCUSABLE_SELECTOR}, slot`)) {
1866
+ if (!(node instanceof HTMLSlotElement)) {
1867
+ found.push(node);
1868
+ continue;
1869
+ }
1870
+ for (const assigned of node.assignedElements()) {
1871
+ if (assigned.matches(FOCUSABLE_SELECTOR)) found.push(assigned);
1872
+ found.push(...assigned.querySelectorAll(FOCUSABLE_SELECTOR));
1873
+ }
1874
+ }
1875
+ return found;
1876
+ }
1877
+ function dragHandleAt(node, clientX, clientY) {
1878
+ const handle = node.closest?.("[data-wm-drag]");
1879
+ if (handle) return handle;
1880
+ const inner = node.shadowRoot?.elementFromPoint?.(clientX, clientY) ?? null;
1881
+ return inner === null || inner === node ? null : dragHandleAt(inner, clientX, clientY);
1882
+ }
1883
+ function windowElementOf(node) {
1884
+ const found = node.closest("[data-wm-window]");
1885
+ if (found) return found;
1886
+ const host = node.getRootNode().host;
1887
+ return host ? windowElementOf(host) : null;
1888
+ }
1889
+ function defaultVariant(win) {
1890
+ const variant = win.meta.variant;
1891
+ return typeof variant === "string" && variant !== "" ? variant : null;
1892
+ }
1967
1893
  function attachDesktop(wm, element, options = {}) {
1968
1894
  const doc = element.ownerDocument;
1969
1895
  const view = windowOf(element);
@@ -1988,6 +1914,7 @@ function attachDesktop(wm, element, options = {}) {
1988
1914
  const interactiveSelector = options.interactiveSelector ?? INTERACTIVE_SELECTOR;
1989
1915
  const animationEnabled = options.animation !== false;
1990
1916
  const animationOptions = typeof options.animation === "object" ? options.animation : {};
1917
+ const windowVariant = options.windowVariant ?? defaultVariant;
1991
1918
  element.dataset.wmDesktop = "";
1992
1919
  element.tabIndex = -1;
1993
1920
  if (view.getComputedStyle(element).position === "static") {
@@ -2077,8 +2004,8 @@ function attachDesktop(wm, element, options = {}) {
2077
2004
  groupTarget(clientX, clientY, selfId) {
2078
2005
  if (!groupingEnabled || typeof doc.elementsFromPoint !== "function") return null;
2079
2006
  for (const node of doc.elementsFromPoint(clientX, clientY)) {
2080
- const handle = node.closest?.("[data-wm-drag]");
2081
- const host = handle?.closest("[data-wm-window]");
2007
+ const handle = dragHandleAt(node, clientX, clientY);
2008
+ const host = handle && windowElementOf(handle);
2082
2009
  const id = host?.dataset.wmWindow;
2083
2010
  if (id && id !== selfId && registry.get(id)?.element === host) return id;
2084
2011
  }
@@ -2101,6 +2028,21 @@ function attachDesktop(wm, element, options = {}) {
2101
2028
  };
2102
2029
  const startDrag = createDragStarter(ctx);
2103
2030
  const startResize = createResizeStarter(ctx);
2031
+ if (options.gestures) {
2032
+ const gestureContext = {
2033
+ wm,
2034
+ doc,
2035
+ view,
2036
+ desktop: element,
2037
+ toLocal: (event) => ctx.toLocal(event),
2038
+ trackRect: () => ctx.trackRect(),
2039
+ windowElement: (id) => ctx.windowElement(id),
2040
+ busy: () => drag !== null,
2041
+ claim: (gesture) => ctx.claimDrag(gesture),
2042
+ release: (gesture) => ctx.releaseDrag(gesture)
2043
+ };
2044
+ for (const gesture of options.gestures) cleanup.push(gesture(gestureContext));
2045
+ }
2104
2046
  if (options.autoViewport !== false) {
2105
2047
  const applyViewport = () => wm.setViewport({ width: element.clientWidth, height: element.clientHeight });
2106
2048
  applyViewport();
@@ -2119,6 +2061,9 @@ function attachDesktop(wm, element, options = {}) {
2119
2061
  el.dataset.wmStage = win.stage;
2120
2062
  el.dataset.wmLayer = win.layer;
2121
2063
  el.dataset.wmWorkspace = String(win.workspace);
2064
+ const variant = windowVariant(win);
2065
+ if (variant === null) delete el.dataset.wmVariant;
2066
+ else el.dataset.wmVariant = variant;
2122
2067
  if (win.groupId === null) {
2123
2068
  delete el.dataset.wmGroup;
2124
2069
  delete el.dataset.wmTab;
@@ -2137,6 +2082,9 @@ function attachDesktop(wm, element, options = {}) {
2137
2082
  }
2138
2083
  el.hidden = hide;
2139
2084
  el.setAttribute("aria-label", win.title);
2085
+ if (attached.title && attached.title.textContent !== win.title) {
2086
+ attached.title.textContent = win.title;
2087
+ }
2140
2088
  if (win.layer === "modal") el.setAttribute("aria-modal", "true");
2141
2089
  else el.removeAttribute("aria-modal");
2142
2090
  for (const handle of attached.handles) {
@@ -2174,15 +2122,30 @@ function attachDesktop(wm, element, options = {}) {
2174
2122
  function syncAll() {
2175
2123
  const state = wm.getState();
2176
2124
  const orderChanged = state.order !== lastOrder;
2125
+ let restyle = null;
2177
2126
  for (const id of state.order) {
2178
2127
  const attached = registry.get(id);
2179
2128
  const win = state.windows[id];
2180
2129
  if (!attached || !win) continue;
2130
+ const wanted2 = typeof win.meta.skin === "string" ? win.meta.skin : null;
2131
+ if (attached.skin !== null && wanted2 !== null && wanted2 !== attached.skin) {
2132
+ restyle = restyle ?? [];
2133
+ restyle.push([id, wanted2]);
2134
+ continue;
2135
+ }
2181
2136
  const activeTab = win.groupId === null || state.groups[win.groupId]?.activeId === win.id;
2182
2137
  if (attached.lastState !== win || attached.lastWorkspace !== state.workspace || attached.lastTab !== activeTab) {
2183
2138
  syncWindow(attached, win, state.workspace, activeTab);
2184
2139
  }
2185
2140
  }
2141
+ if (restyle !== null) {
2142
+ for (const [id, wanted2] of restyle) {
2143
+ const attached = registry.get(id);
2144
+ if (attached && attached.skin !== wanted2) buildSkin(id, wanted2, attached.mountOptions);
2145
+ }
2146
+ syncAll();
2147
+ return;
2148
+ }
2186
2149
  if (orderChanged) applyStacking(state.order);
2187
2150
  const wanted = state.focusedId ? registry.get(state.focusedId)?.element ?? null : null;
2188
2151
  if (wanted !== focusedEl) {
@@ -2280,6 +2243,11 @@ function attachDesktop(wm, element, options = {}) {
2280
2243
  const attached = {
2281
2244
  element: windowElement,
2282
2245
  handle: null,
2246
+ title: null,
2247
+ skin: null,
2248
+ mount: null,
2249
+ mountOptions: windowOptions,
2250
+ release: null,
2283
2251
  handles: [],
2284
2252
  lastState: null,
2285
2253
  lastZ: UNASSIGNED,
@@ -2293,10 +2261,11 @@ function attachDesktop(wm, element, options = {}) {
2293
2261
  windowElement.style.position = "absolute";
2294
2262
  windowElement.style.left = "0";
2295
2263
  windowElement.style.top = "0";
2296
- const titleEl = windowElement.querySelector("[data-wm-title]");
2297
- if (titleEl) {
2298
- if (!titleEl.id) titleEl.id = `wmkit-title-${id}`;
2299
- windowElement.setAttribute("aria-labelledby", titleEl.id);
2264
+ const lightTitle = windowElement.querySelector("[data-wm-title]");
2265
+ attached.title = lightTitle ?? windowElement.shadowRoot?.querySelector("[data-wm-title]") ?? null;
2266
+ if (lightTitle) {
2267
+ if (!lightTitle.id) lightTitle.id = `wmkit-title-${id}`;
2268
+ windowElement.setAttribute("aria-labelledby", lightTitle.id);
2300
2269
  }
2301
2270
  const handle = typeof windowOptions.handle === "string" ? windowElement.querySelector(windowOptions.handle) : windowOptions.handle ?? windowElement.querySelector("[data-wm-drag]");
2302
2271
  attached.handle = handle;
@@ -2317,10 +2286,38 @@ function attachDesktop(wm, element, options = {}) {
2317
2286
  if (!current) return;
2318
2287
  if (target.closest("[data-wm-close]")) {
2319
2288
  if (current.closable && options.beforeClose?.(current) !== false) wm.close(id);
2320
- } else if (target.closest("[data-wm-minimize]")) {
2289
+ return;
2290
+ }
2291
+ if (target.closest("[data-wm-minimize]")) {
2321
2292
  if (current.minimizable) wm.minimize(id);
2322
- } else if (target.closest("[data-wm-maximize]")) {
2293
+ return;
2294
+ }
2295
+ if (target.closest("[data-wm-maximize]")) {
2323
2296
  if (current.maximizable) wm.toggleMaximize(id);
2297
+ return;
2298
+ }
2299
+ const act = createActions(wm, id);
2300
+ const snapTarget = target.closest("[data-wm-snap]");
2301
+ if (snapTarget) {
2302
+ const zone = snapTarget.dataset.wmSnap ?? "";
2303
+ if (current.snappable && SNAP_ZONES.has(zone)) act.snap(zone);
2304
+ return;
2305
+ }
2306
+ if (target.closest("[data-wm-restore]")) {
2307
+ act.restore();
2308
+ return;
2309
+ }
2310
+ if (target.closest("[data-wm-center]")) {
2311
+ act.center();
2312
+ return;
2313
+ }
2314
+ if (target.closest("[data-wm-send-back]")) {
2315
+ act.sendToBack();
2316
+ return;
2317
+ }
2318
+ const workspaceTarget = target.closest("[data-wm-to-workspace]");
2319
+ if (workspaceTarget) {
2320
+ act.moveToWorkspace(Number.parseInt(workspaceTarget.dataset.wmToWorkspace ?? "", 10));
2324
2321
  }
2325
2322
  };
2326
2323
  windowElement.addEventListener("click", onClick);
@@ -2358,7 +2355,7 @@ function attachDesktop(wm, element, options = {}) {
2358
2355
  const onResizeDown = (event) => startResize(id, direction, event);
2359
2356
  resizeHandle.addEventListener("pointerdown", onResizeDown);
2360
2357
  attached.cleanup.push(() => resizeHandle.removeEventListener("pointerdown", onResizeDown));
2361
- windowElement.append(resizeHandle);
2358
+ (windowElement.shadowRoot ?? windowElement).append(resizeHandle);
2362
2359
  attached.handles.push(resizeHandle);
2363
2360
  }
2364
2361
  }
@@ -2396,9 +2393,10 @@ function attachDesktop(wm, element, options = {}) {
2396
2393
  if (event.key !== "Tab") return;
2397
2394
  const current = wm.get(id);
2398
2395
  if (current?.layer !== "modal") return;
2399
- const focusables = [
2400
- ...windowElement.querySelectorAll(FOCUSABLE_SELECTOR)
2401
- ].filter((node) => node.offsetParent !== null || node === doc.activeElement);
2396
+ const active = windowElement.shadowRoot?.activeElement ?? doc.activeElement;
2397
+ const focusables = focusablesOf(windowElement).filter(
2398
+ (node) => node.offsetParent !== null || node === active
2399
+ );
2402
2400
  if (focusables.length === 0) return;
2403
2401
  const first = focusables[0];
2404
2402
  const last = focusables[focusables.length - 1];
@@ -2408,10 +2406,10 @@ function attachDesktop(wm, element, options = {}) {
2408
2406
  (event.shiftKey ? last : first).focus();
2409
2407
  return;
2410
2408
  }
2411
- if (event.shiftKey && doc.activeElement === first) {
2409
+ if (event.shiftKey && active === first) {
2412
2410
  event.preventDefault();
2413
2411
  last.focus();
2414
- } else if (!event.shiftKey && doc.activeElement === last) {
2412
+ } else if (!event.shiftKey && active === last) {
2415
2413
  event.preventDefault();
2416
2414
  first.focus();
2417
2415
  }
@@ -2449,10 +2447,62 @@ function attachDesktop(wm, element, options = {}) {
2449
2447
  }
2450
2448
  return detach;
2451
2449
  }
2450
+ function resolveSkin(skin) {
2451
+ if (typeof skin !== "string") return skin;
2452
+ const found = options.skins?.[skin];
2453
+ if (!found) throw new Error(`wmkit: unknown skin "${skin}"`);
2454
+ return found;
2455
+ }
2456
+ function buildSkin(id, skin, windowOptions) {
2457
+ const win = wm.get(id);
2458
+ if (!win) throw new Error(`wmkit: cannot mount unknown window "${id}"`);
2459
+ const standing = registry.get(id);
2460
+ const previous = standing?.mount ?? null;
2461
+ const carried = previous === null ? [] : [...previous.content.childNodes];
2462
+ if (previous !== null) {
2463
+ registry.delete(id);
2464
+ standing?.release?.();
2465
+ previous.element.remove();
2466
+ }
2467
+ const mount = resolveSkin(skin)({ doc, id, window: win, actions: createActions(wm, id) });
2468
+ element.append(mount.element);
2469
+ const release = attachWindow(id, mount.element, windowOptions);
2470
+ const attached = registry.get(id);
2471
+ attached.skin = typeof skin === "string" ? skin : null;
2472
+ attached.mount = mount;
2473
+ attached.mountOptions = windowOptions;
2474
+ attached.release = release;
2475
+ mount.content.append(...carried);
2476
+ previous?.destroy?.();
2477
+ return mount;
2478
+ }
2479
+ function mountWindow(id, skin, windowOptions = {}) {
2480
+ let last = buildSkin(id, skin, windowOptions);
2481
+ const live = () => {
2482
+ last = registry.get(id)?.mount ?? last;
2483
+ return last;
2484
+ };
2485
+ return {
2486
+ get element() {
2487
+ return live().element;
2488
+ },
2489
+ get content() {
2490
+ return live().content;
2491
+ },
2492
+ detach() {
2493
+ const mount = live();
2494
+ registry.get(id)?.release?.();
2495
+ mount.element.remove();
2496
+ mount.destroy?.();
2497
+ }
2498
+ };
2499
+ }
2452
2500
  return {
2453
2501
  element,
2454
2502
  wm,
2455
2503
  attachWindow,
2504
+ mountWindow,
2505
+ actions: (id) => createActions(wm, id),
2456
2506
  destroy() {
2457
2507
  endDrag(true);
2458
2508
  for (const [, attached] of registry) {
@@ -2522,6 +2572,14 @@ function createDesktopBinder(wm, options = {}) {
2522
2572
  };
2523
2573
  }
2524
2574
 
2525
- export { applyAspect, attachDesktop, boundsEqual, clamp, clampSize, clampToViewport, createAnnouncer, createDesktopBinder, createEmitter, createWindowManager, defaultMessages, detectSnapZone, flipFromTarget, flipToTarget, magnetize, prefersReducedMotion, zoneBounds };
2526
- //# sourceMappingURL=chunk-FOWW4LXS.js.map
2527
- //# sourceMappingURL=chunk-FOWW4LXS.js.map
2575
+ exports.attachDesktop = attachDesktop;
2576
+ exports.createAnnouncer = createAnnouncer;
2577
+ exports.createDesktopBinder = createDesktopBinder;
2578
+ exports.createEmitter = createEmitter;
2579
+ exports.createWindowManager = createWindowManager;
2580
+ exports.defaultMessages = defaultMessages;
2581
+ exports.flipFromTarget = flipFromTarget;
2582
+ exports.flipToTarget = flipToTarget;
2583
+ exports.prefersReducedMotion = prefersReducedMotion;
2584
+ //# sourceMappingURL=chunk-ZWUVWRUS.cjs.map
2585
+ //# sourceMappingURL=chunk-ZWUVWRUS.cjs.map