@surdeddd/wmkit 0.8.0 → 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 (52) hide show
  1. package/README.md +23 -1
  2. package/README.ru.md +23 -1
  3. package/dist/angular.cjs +3 -3
  4. package/dist/angular.d.cts +2 -2
  5. package/dist/angular.d.ts +2 -2
  6. package/dist/angular.js +1 -1
  7. package/dist/{binder-B625OrjD.d.cts → binder-DGoj0xG1.d.cts} +1 -1
  8. package/dist/{binder-CpGY8Wye.d.ts → binder-Lo13iTVB.d.ts} +1 -1
  9. package/dist/chrome.cjs +122 -0
  10. package/dist/chrome.cjs.map +1 -0
  11. package/dist/chrome.d.cts +25 -0
  12. package/dist/chrome.d.ts +25 -0
  13. package/dist/chrome.js +114 -0
  14. package/dist/chrome.js.map +1 -0
  15. package/dist/{chunk-MGWCKHTZ.js → chunk-TUGQX3CX.js} +179 -17
  16. package/dist/chunk-TUGQX3CX.js.map +1 -0
  17. package/dist/{chunk-DINVOL6Z.cjs → chunk-ZWUVWRUS.cjs} +179 -17
  18. package/dist/chunk-ZWUVWRUS.cjs.map +1 -0
  19. package/dist/gestures.d.cts +1 -1
  20. package/dist/gestures.d.ts +1 -1
  21. package/dist/index.cjs +10 -10
  22. package/dist/index.d.cts +3 -3
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.js +1 -1
  25. package/dist/react.cjs +3 -3
  26. package/dist/react.d.cts +2 -2
  27. package/dist/react.d.ts +2 -2
  28. package/dist/react.js +1 -1
  29. package/dist/{shared-BBXgEeIa.d.ts → shared-BoHXlPCu.d.ts} +34 -1
  30. package/dist/{shared-DU_87nY9.d.cts → shared-DdGFz3oy.d.cts} +34 -1
  31. package/dist/solid.cjs +3 -3
  32. package/dist/solid.d.cts +2 -2
  33. package/dist/solid.d.ts +2 -2
  34. package/dist/solid.js +1 -1
  35. package/dist/svelte.cjs +3 -3
  36. package/dist/svelte.d.cts +2 -2
  37. package/dist/svelte.d.ts +2 -2
  38. package/dist/svelte.js +1 -1
  39. package/dist/themes/retro.css +8 -0
  40. package/dist/themes.cjs +8747 -0
  41. package/dist/themes.cjs.map +1 -0
  42. package/dist/themes.d.cts +12 -0
  43. package/dist/themes.d.ts +12 -0
  44. package/dist/themes.js +8742 -0
  45. package/dist/themes.js.map +1 -0
  46. package/dist/vue.cjs +3 -3
  47. package/dist/vue.d.cts +2 -2
  48. package/dist/vue.d.ts +2 -2
  49. package/dist/vue.js +1 -1
  50. package/package.json +44 -7
  51. package/dist/chunk-DINVOL6Z.cjs.map +0 -1
  52. package/dist/chunk-MGWCKHTZ.js.map +0 -1
@@ -1367,6 +1367,22 @@ function createAnnouncer(wm, container, messages = {}) {
1367
1367
  };
1368
1368
  }
1369
1369
 
1370
+ // src/dom/actions.ts
1371
+ function createActions(wm, id) {
1372
+ return {
1373
+ focus: () => wm.focus(id),
1374
+ close: () => wm.close(id),
1375
+ minimize: () => wm.minimize(id),
1376
+ maximize: () => wm.maximize(id),
1377
+ toggleMaximize: () => wm.toggleMaximize(id),
1378
+ restore: () => wm.restore(id),
1379
+ center: () => wm.center(id),
1380
+ sendToBack: () => wm.sendToBack(id),
1381
+ snap: (zone) => wm.snap(id, zone),
1382
+ moveToWorkspace: (workspace) => wm.moveToWorkspace(id, workspace)
1383
+ };
1384
+ }
1385
+
1370
1386
  // src/dom/drag.ts
1371
1387
  function createDragStarter(ctx) {
1372
1388
  const { wm, doc, view } = ctx;
@@ -1728,7 +1744,7 @@ function createResizeHandles(doc, edge, corner) {
1728
1744
  }
1729
1745
 
1730
1746
  // src/dom/shared.ts
1731
- var INTERACTIVE_SELECTOR = "button, input, select, textarea, a[href], [contenteditable], [data-wm-close], [data-wm-minimize], [data-wm-maximize]";
1747
+ 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]";
1732
1748
  function windowOf(element) {
1733
1749
  const view = element.ownerDocument.defaultView;
1734
1750
  if (!view) throw new Error("wmkit: desktop element is not attached to a document");
@@ -1825,8 +1841,49 @@ var SNAP_SHORTCUTS = {
1825
1841
  ArrowLeft: "left",
1826
1842
  ArrowRight: "right"
1827
1843
  };
1844
+ var SNAP_ZONES = /* @__PURE__ */ new Set([
1845
+ "left",
1846
+ "right",
1847
+ "top",
1848
+ "bottom",
1849
+ "top-left",
1850
+ "top-right",
1851
+ "bottom-left",
1852
+ "bottom-right",
1853
+ "left-third",
1854
+ "center-third",
1855
+ "right-third"
1856
+ ]);
1828
1857
  var LANDMARK_TAGS = /* @__PURE__ */ new Set(["header", "footer", "aside", "nav"]);
1829
1858
  var FOCUSABLE_SELECTOR = 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
1859
+ function focusablesOf(el) {
1860
+ const root = el.shadowRoot;
1861
+ if (!root) return [...el.querySelectorAll(FOCUSABLE_SELECTOR)];
1862
+ const found = [];
1863
+ for (const node of root.querySelectorAll(`${FOCUSABLE_SELECTOR}, slot`)) {
1864
+ if (!(node instanceof HTMLSlotElement)) {
1865
+ found.push(node);
1866
+ continue;
1867
+ }
1868
+ for (const assigned of node.assignedElements()) {
1869
+ if (assigned.matches(FOCUSABLE_SELECTOR)) found.push(assigned);
1870
+ found.push(...assigned.querySelectorAll(FOCUSABLE_SELECTOR));
1871
+ }
1872
+ }
1873
+ return found;
1874
+ }
1875
+ function dragHandleAt(node, clientX, clientY) {
1876
+ const handle = node.closest?.("[data-wm-drag]");
1877
+ if (handle) return handle;
1878
+ const inner = node.shadowRoot?.elementFromPoint?.(clientX, clientY) ?? null;
1879
+ return inner === null || inner === node ? null : dragHandleAt(inner, clientX, clientY);
1880
+ }
1881
+ function windowElementOf(node) {
1882
+ const found = node.closest("[data-wm-window]");
1883
+ if (found) return found;
1884
+ const host = node.getRootNode().host;
1885
+ return host ? windowElementOf(host) : null;
1886
+ }
1830
1887
  function defaultVariant(win) {
1831
1888
  const variant = win.meta.variant;
1832
1889
  return typeof variant === "string" && variant !== "" ? variant : null;
@@ -1945,8 +2002,8 @@ function attachDesktop(wm, element, options = {}) {
1945
2002
  groupTarget(clientX, clientY, selfId) {
1946
2003
  if (!groupingEnabled || typeof doc.elementsFromPoint !== "function") return null;
1947
2004
  for (const node of doc.elementsFromPoint(clientX, clientY)) {
1948
- const handle = node.closest?.("[data-wm-drag]");
1949
- const host = handle?.closest("[data-wm-window]");
2005
+ const handle = dragHandleAt(node, clientX, clientY);
2006
+ const host = handle && windowElementOf(handle);
1950
2007
  const id = host?.dataset.wmWindow;
1951
2008
  if (id && id !== selfId && registry.get(id)?.element === host) return id;
1952
2009
  }
@@ -2023,6 +2080,9 @@ function attachDesktop(wm, element, options = {}) {
2023
2080
  }
2024
2081
  el.hidden = hide;
2025
2082
  el.setAttribute("aria-label", win.title);
2083
+ if (attached.title && attached.title.textContent !== win.title) {
2084
+ attached.title.textContent = win.title;
2085
+ }
2026
2086
  if (win.layer === "modal") el.setAttribute("aria-modal", "true");
2027
2087
  else el.removeAttribute("aria-modal");
2028
2088
  for (const handle of attached.handles) {
@@ -2060,15 +2120,30 @@ function attachDesktop(wm, element, options = {}) {
2060
2120
  function syncAll() {
2061
2121
  const state = wm.getState();
2062
2122
  const orderChanged = state.order !== lastOrder;
2123
+ let restyle = null;
2063
2124
  for (const id of state.order) {
2064
2125
  const attached = registry.get(id);
2065
2126
  const win = state.windows[id];
2066
2127
  if (!attached || !win) continue;
2128
+ const wanted2 = typeof win.meta.skin === "string" ? win.meta.skin : null;
2129
+ if (attached.skin !== null && wanted2 !== null && wanted2 !== attached.skin) {
2130
+ restyle = restyle ?? [];
2131
+ restyle.push([id, wanted2]);
2132
+ continue;
2133
+ }
2067
2134
  const activeTab = win.groupId === null || state.groups[win.groupId]?.activeId === win.id;
2068
2135
  if (attached.lastState !== win || attached.lastWorkspace !== state.workspace || attached.lastTab !== activeTab) {
2069
2136
  syncWindow(attached, win, state.workspace, activeTab);
2070
2137
  }
2071
2138
  }
2139
+ if (restyle !== null) {
2140
+ for (const [id, wanted2] of restyle) {
2141
+ const attached = registry.get(id);
2142
+ if (attached && attached.skin !== wanted2) buildSkin(id, wanted2, attached.mountOptions);
2143
+ }
2144
+ syncAll();
2145
+ return;
2146
+ }
2072
2147
  if (orderChanged) applyStacking(state.order);
2073
2148
  const wanted = state.focusedId ? registry.get(state.focusedId)?.element ?? null : null;
2074
2149
  if (wanted !== focusedEl) {
@@ -2166,6 +2241,11 @@ function attachDesktop(wm, element, options = {}) {
2166
2241
  const attached = {
2167
2242
  element: windowElement,
2168
2243
  handle: null,
2244
+ title: null,
2245
+ skin: null,
2246
+ mount: null,
2247
+ mountOptions: windowOptions,
2248
+ release: null,
2169
2249
  handles: [],
2170
2250
  lastState: null,
2171
2251
  lastZ: UNASSIGNED,
@@ -2179,10 +2259,11 @@ function attachDesktop(wm, element, options = {}) {
2179
2259
  windowElement.style.position = "absolute";
2180
2260
  windowElement.style.left = "0";
2181
2261
  windowElement.style.top = "0";
2182
- const titleEl = windowElement.querySelector("[data-wm-title]");
2183
- if (titleEl) {
2184
- if (!titleEl.id) titleEl.id = `wmkit-title-${id}`;
2185
- windowElement.setAttribute("aria-labelledby", titleEl.id);
2262
+ const lightTitle = windowElement.querySelector("[data-wm-title]");
2263
+ attached.title = lightTitle ?? windowElement.shadowRoot?.querySelector("[data-wm-title]") ?? null;
2264
+ if (lightTitle) {
2265
+ if (!lightTitle.id) lightTitle.id = `wmkit-title-${id}`;
2266
+ windowElement.setAttribute("aria-labelledby", lightTitle.id);
2186
2267
  }
2187
2268
  const handle = typeof windowOptions.handle === "string" ? windowElement.querySelector(windowOptions.handle) : windowOptions.handle ?? windowElement.querySelector("[data-wm-drag]");
2188
2269
  attached.handle = handle;
@@ -2203,10 +2284,38 @@ function attachDesktop(wm, element, options = {}) {
2203
2284
  if (!current) return;
2204
2285
  if (target.closest("[data-wm-close]")) {
2205
2286
  if (current.closable && options.beforeClose?.(current) !== false) wm.close(id);
2206
- } else if (target.closest("[data-wm-minimize]")) {
2287
+ return;
2288
+ }
2289
+ if (target.closest("[data-wm-minimize]")) {
2207
2290
  if (current.minimizable) wm.minimize(id);
2208
- } else if (target.closest("[data-wm-maximize]")) {
2291
+ return;
2292
+ }
2293
+ if (target.closest("[data-wm-maximize]")) {
2209
2294
  if (current.maximizable) wm.toggleMaximize(id);
2295
+ return;
2296
+ }
2297
+ const act = createActions(wm, id);
2298
+ const snapTarget = target.closest("[data-wm-snap]");
2299
+ if (snapTarget) {
2300
+ const zone = snapTarget.dataset.wmSnap ?? "";
2301
+ if (current.snappable && SNAP_ZONES.has(zone)) act.snap(zone);
2302
+ return;
2303
+ }
2304
+ if (target.closest("[data-wm-restore]")) {
2305
+ act.restore();
2306
+ return;
2307
+ }
2308
+ if (target.closest("[data-wm-center]")) {
2309
+ act.center();
2310
+ return;
2311
+ }
2312
+ if (target.closest("[data-wm-send-back]")) {
2313
+ act.sendToBack();
2314
+ return;
2315
+ }
2316
+ const workspaceTarget = target.closest("[data-wm-to-workspace]");
2317
+ if (workspaceTarget) {
2318
+ act.moveToWorkspace(Number.parseInt(workspaceTarget.dataset.wmToWorkspace ?? "", 10));
2210
2319
  }
2211
2320
  };
2212
2321
  windowElement.addEventListener("click", onClick);
@@ -2244,7 +2353,7 @@ function attachDesktop(wm, element, options = {}) {
2244
2353
  const onResizeDown = (event) => startResize(id, direction, event);
2245
2354
  resizeHandle.addEventListener("pointerdown", onResizeDown);
2246
2355
  attached.cleanup.push(() => resizeHandle.removeEventListener("pointerdown", onResizeDown));
2247
- windowElement.append(resizeHandle);
2356
+ (windowElement.shadowRoot ?? windowElement).append(resizeHandle);
2248
2357
  attached.handles.push(resizeHandle);
2249
2358
  }
2250
2359
  }
@@ -2282,9 +2391,10 @@ function attachDesktop(wm, element, options = {}) {
2282
2391
  if (event.key !== "Tab") return;
2283
2392
  const current = wm.get(id);
2284
2393
  if (current?.layer !== "modal") return;
2285
- const focusables = [
2286
- ...windowElement.querySelectorAll(FOCUSABLE_SELECTOR)
2287
- ].filter((node) => node.offsetParent !== null || node === doc.activeElement);
2394
+ const active = windowElement.shadowRoot?.activeElement ?? doc.activeElement;
2395
+ const focusables = focusablesOf(windowElement).filter(
2396
+ (node) => node.offsetParent !== null || node === active
2397
+ );
2288
2398
  if (focusables.length === 0) return;
2289
2399
  const first = focusables[0];
2290
2400
  const last = focusables[focusables.length - 1];
@@ -2294,10 +2404,10 @@ function attachDesktop(wm, element, options = {}) {
2294
2404
  (event.shiftKey ? last : first).focus();
2295
2405
  return;
2296
2406
  }
2297
- if (event.shiftKey && doc.activeElement === first) {
2407
+ if (event.shiftKey && active === first) {
2298
2408
  event.preventDefault();
2299
2409
  last.focus();
2300
- } else if (!event.shiftKey && doc.activeElement === last) {
2410
+ } else if (!event.shiftKey && active === last) {
2301
2411
  event.preventDefault();
2302
2412
  first.focus();
2303
2413
  }
@@ -2335,10 +2445,62 @@ function attachDesktop(wm, element, options = {}) {
2335
2445
  }
2336
2446
  return detach;
2337
2447
  }
2448
+ function resolveSkin(skin) {
2449
+ if (typeof skin !== "string") return skin;
2450
+ const found = options.skins?.[skin];
2451
+ if (!found) throw new Error(`wmkit: unknown skin "${skin}"`);
2452
+ return found;
2453
+ }
2454
+ function buildSkin(id, skin, windowOptions) {
2455
+ const win = wm.get(id);
2456
+ if (!win) throw new Error(`wmkit: cannot mount unknown window "${id}"`);
2457
+ const standing = registry.get(id);
2458
+ const previous = standing?.mount ?? null;
2459
+ const carried = previous === null ? [] : [...previous.content.childNodes];
2460
+ if (previous !== null) {
2461
+ registry.delete(id);
2462
+ standing?.release?.();
2463
+ previous.element.remove();
2464
+ }
2465
+ const mount = resolveSkin(skin)({ doc, id, window: win, actions: createActions(wm, id) });
2466
+ element.append(mount.element);
2467
+ const release = attachWindow(id, mount.element, windowOptions);
2468
+ const attached = registry.get(id);
2469
+ attached.skin = typeof skin === "string" ? skin : null;
2470
+ attached.mount = mount;
2471
+ attached.mountOptions = windowOptions;
2472
+ attached.release = release;
2473
+ mount.content.append(...carried);
2474
+ previous?.destroy?.();
2475
+ return mount;
2476
+ }
2477
+ function mountWindow(id, skin, windowOptions = {}) {
2478
+ let last = buildSkin(id, skin, windowOptions);
2479
+ const live = () => {
2480
+ last = registry.get(id)?.mount ?? last;
2481
+ return last;
2482
+ };
2483
+ return {
2484
+ get element() {
2485
+ return live().element;
2486
+ },
2487
+ get content() {
2488
+ return live().content;
2489
+ },
2490
+ detach() {
2491
+ const mount = live();
2492
+ registry.get(id)?.release?.();
2493
+ mount.element.remove();
2494
+ mount.destroy?.();
2495
+ }
2496
+ };
2497
+ }
2338
2498
  return {
2339
2499
  element,
2340
2500
  wm,
2341
2501
  attachWindow,
2502
+ mountWindow,
2503
+ actions: (id) => createActions(wm, id),
2342
2504
  destroy() {
2343
2505
  endDrag(true);
2344
2506
  for (const [, attached] of registry) {
@@ -2409,5 +2571,5 @@ function createDesktopBinder(wm, options = {}) {
2409
2571
  }
2410
2572
 
2411
2573
  export { attachDesktop, createAnnouncer, createDesktopBinder, createEmitter, createWindowManager, defaultMessages, flipFromTarget, flipToTarget, prefersReducedMotion };
2412
- //# sourceMappingURL=chunk-MGWCKHTZ.js.map
2413
- //# sourceMappingURL=chunk-MGWCKHTZ.js.map
2574
+ //# sourceMappingURL=chunk-TUGQX3CX.js.map
2575
+ //# sourceMappingURL=chunk-TUGQX3CX.js.map