quilt-vanilla 0.1.1 → 0.2.1

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 (96) hide show
  1. package/README.md +8 -2
  2. package/dist/action-icons.d.ts +2 -2
  3. package/dist/action-icons.d.ts.map +1 -1
  4. package/dist/action-icons.js.map +1 -1
  5. package/dist/close.d.ts +4 -0
  6. package/dist/close.d.ts.map +1 -0
  7. package/dist/close.js +95 -0
  8. package/dist/close.js.map +1 -0
  9. package/dist/corners.d.ts +2 -2
  10. package/dist/corners.d.ts.map +1 -1
  11. package/dist/corners.js +15 -7
  12. package/dist/corners.js.map +1 -1
  13. package/dist/index.d.ts +7 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +4 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/lifetime.d.ts.map +1 -1
  18. package/dist/lifetime.js +1 -0
  19. package/dist/lifetime.js.map +1 -1
  20. package/dist/menu.d.ts +2 -2
  21. package/dist/menu.d.ts.map +1 -1
  22. package/dist/menu.js +35 -28
  23. package/dist/menu.js.map +1 -1
  24. package/dist/messages.d.ts +62 -0
  25. package/dist/messages.d.ts.map +1 -0
  26. package/dist/messages.js +62 -0
  27. package/dist/messages.js.map +1 -0
  28. package/dist/panes.d.ts +2 -2
  29. package/dist/panes.d.ts.map +1 -1
  30. package/dist/panes.js +20 -4
  31. package/dist/panes.js.map +1 -1
  32. package/dist/picker.d.ts +2 -2
  33. package/dist/picker.d.ts.map +1 -1
  34. package/dist/picker.js +9 -6
  35. package/dist/picker.js.map +1 -1
  36. package/dist/registry.d.ts +21 -0
  37. package/dist/registry.d.ts.map +1 -1
  38. package/dist/registry.js +61 -0
  39. package/dist/registry.js.map +1 -1
  40. package/dist/renderer.d.ts +1 -1
  41. package/dist/renderer.d.ts.map +1 -1
  42. package/dist/renderer.js +169 -25
  43. package/dist/renderer.js.map +1 -1
  44. package/dist/shortcuts.d.ts +5 -3
  45. package/dist/shortcuts.d.ts.map +1 -1
  46. package/dist/shortcuts.js +57 -41
  47. package/dist/shortcuts.js.map +1 -1
  48. package/dist/styles.css +9 -9
  49. package/dist/tab-bar.d.ts +2 -1
  50. package/dist/tab-bar.d.ts.map +1 -1
  51. package/dist/tab-bar.js +25 -4
  52. package/dist/tab-bar.js.map +1 -1
  53. package/dist/tab-tooltip.d.ts +2 -1
  54. package/dist/tab-tooltip.d.ts.map +1 -1
  55. package/dist/tab-tooltip.js +5 -2
  56. package/dist/tab-tooltip.js.map +1 -1
  57. package/dist/tabs.d.ts +3 -2
  58. package/dist/tabs.d.ts.map +1 -1
  59. package/dist/tabs.js +3 -2
  60. package/dist/tabs.js.map +1 -1
  61. package/dist/theme.d.ts +3 -0
  62. package/dist/theme.d.ts.map +1 -1
  63. package/dist/theme.js +31 -0
  64. package/dist/theme.js.map +1 -1
  65. package/dist/types.d.ts +58 -11
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/types.js.map +1 -1
  68. package/dist/windows.d.ts +8 -4
  69. package/dist/windows.d.ts.map +1 -1
  70. package/dist/windows.js +118 -23
  71. package/dist/windows.js.map +1 -1
  72. package/dist/workspace.d.ts +14 -0
  73. package/dist/workspace.d.ts.map +1 -0
  74. package/dist/workspace.js +39 -0
  75. package/dist/workspace.js.map +1 -0
  76. package/package.json +2 -2
  77. package/src/action-icons.ts +2 -2
  78. package/src/close.ts +120 -0
  79. package/src/corners.ts +28 -9
  80. package/src/index.ts +7 -0
  81. package/src/lifetime.ts +1 -0
  82. package/src/menu.ts +52 -34
  83. package/src/messages.ts +71 -0
  84. package/src/panes.ts +20 -6
  85. package/src/picker.ts +11 -8
  86. package/src/registry.ts +71 -0
  87. package/src/renderer.ts +205 -38
  88. package/src/shortcuts.ts +63 -54
  89. package/src/styles.css +9 -9
  90. package/src/tab-bar.ts +30 -5
  91. package/src/tab-tooltip.ts +6 -1
  92. package/src/tabs.ts +6 -4
  93. package/src/theme.ts +30 -0
  94. package/src/types.ts +57 -11
  95. package/src/windows.ts +127 -23
  96. package/src/workspace.ts +44 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # quilt-vanilla
2
2
 
3
- Vanilla DOM pane layouts, tabs, themes, resizing, and same-origin browser popouts. Includes convenient core exports; does not install React. MIT licensed, ESM and TypeScript.
3
+ Vanilla DOM pane layouts, tabs, themes, resizing, and same-origin browser popouts. Re-exports the core API and does not install React. MIT licensed, ESM and TypeScript.
4
4
 
5
5
  ## Install
6
6
 
@@ -51,8 +51,14 @@ function disposeWorkspace() {
51
51
  }
52
52
  ```
53
53
 
54
- The host needs an explicit height. Supply a `TabRegistry` through `tabs` to offer new content; registration factories return fresh pane IDs. `themes`, `themeFamilies`, `LayoutTheme`, and `MountedLayout` are public exports. The layout JSON type is `LayoutSnapshot` from this entry point.
54
+ The host needs an explicit height. Use a unified `PaneRegistry` to register creation metadata and renderers together, or supply a `TabRegistry` through `tabs` to offer new content; Quilt generates omitted pane IDs and preserves explicit IDs. `themes`, `themeFamilies`, `LayoutTheme`, and `MountedLayout` are public exports. The layout JSON type is `LayoutSnapshot` from this entry point.
55
55
 
56
56
  Call `mounted.popout(id)` from a user action. Companions are same-origin and owned by the main session. Use the supplied document/window inside renderers and release every view-owned resource in `dispose`. Keep app data outside view lifetimes.
57
57
 
58
58
  See [API](https://github.com/niko-dellic/quilt/blob/main/docs/api.md), [lifecycle](https://github.com/niko-dellic/quilt/blob/main/docs/lifecycle.md), and [migration](https://github.com/niko-dellic/quilt/blob/main/docs/migration.md).
59
+
60
+ Use `mounted.exportWorkspace()` and `mounted.loadWorkspace(input)` to round-trip
61
+ layout and appearance as JSON. Popouts export docked copies without closing live
62
+ windows. `popout` returns `Promise<boolean>` and must be called from a user gesture.
63
+ See [web integration](https://github.com/niko-dellic/quilt/blob/main/docs/integration.md)
64
+ for unified registration, custom themes, close confirmation, and storage examples.
@@ -1,4 +1,4 @@
1
- import type { LayoutOptions } from './types.js';
1
+ import type { ResolvedLayoutOptions } from './types.js';
2
2
  declare const paths: {
3
3
  readonly 'add-tab': readonly ['M12 5v14M5 12h14'];
4
4
  readonly 'split-right': readonly ['M3 4h18v16H3z', 'M12 4v16'];
@@ -13,6 +13,6 @@ declare const paths: {
13
13
  };
14
14
  export type ActionIcon = keyof typeof paths;
15
15
  /** Small built-in chrome icons; applications may override the namespaced keys. */
16
- export declare function actionIcon(doc: Document, name: ActionIcon, options: Pick<LayoutOptions, 'renderIcon'>): Element;
16
+ export declare function actionIcon(doc: Document, name: ActionIcon, options: Pick<ResolvedLayoutOptions, 'renderIcon'>): Element;
17
17
  export {};
18
18
  //# sourceMappingURL=action-icons.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"action-icons.d.ts","sourceRoot":"","sources":["../src/action-icons.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,QAAA,MAAM,KAAK;aACT,SAAS,YAAG,kBAAkB;aAC9B,aAAa,YAAG,eAAe,EAAE,UAAU;aAC3C,aAAa,YAAG,eAAe,EAAE,UAAU;aAC3C,iBAAiB,YAAG,eAAe,EAAE,SAAS,EAAE,SAAS;aACzD,IAAI,YAAG,eAAe,EAAE,2BAA2B;aACnD,QAAQ,YAAG,sCAAsC;aACjD,OAAO,YAAG,wCAAwC;aAClD,MAAM,YAAG,qBAAqB,EAAE,kBAAkB;aAClD,KAAK,YAAG,sBAAsB;aAC9B,MAAM,YAAG,sCAAsC;CACvC,CAAC;AACX,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,KAAK,CAAC;AAC5C,kFAAkF;AAClF,wBAAgB,UAAU,CACxB,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,GACzC,OAAO,CAoBT"}
1
+ {"version":3,"file":"action-icons.d.ts","sourceRoot":"","sources":["../src/action-icons.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,QAAA,MAAM,KAAK;aACT,SAAS,YAAG,kBAAkB;aAC9B,aAAa,YAAG,eAAe,EAAE,UAAU;aAC3C,aAAa,YAAG,eAAe,EAAE,UAAU;aAC3C,iBAAiB,YAAG,eAAe,EAAE,SAAS,EAAE,SAAS;aACzD,IAAI,YAAG,eAAe,EAAE,2BAA2B;aACnD,QAAQ,YAAG,sCAAsC;aACjD,OAAO,YAAG,wCAAwC;aAClD,MAAM,YAAG,qBAAqB,EAAE,kBAAkB;aAClD,KAAK,YAAG,sBAAsB;aAC9B,MAAM,YAAG,sCAAsC;CACvC,CAAC;AACX,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,KAAK,CAAC;AAC5C,kFAAkF;AAClF,wBAAgB,UAAU,CACxB,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,YAAY,CAAC,GACjD,OAAO,CAoBT"}
@@ -1 +1 @@
1
- {"version":3,"file":"action-icons.js","sourceRoot":"","sources":["../src/action-icons.ts"],"names":[],"mappings":"AACA,MAAM,KAAK,GAAG;IACZ,SAAS,EAAE,CAAC,kBAAkB,CAAC;IAC/B,aAAa,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IAC5C,aAAa,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IAC5C,iBAAiB,EAAE,CAAC,eAAe,EAAE,SAAS,EAAE,SAAS,CAAC;IAC1D,IAAI,EAAE,CAAC,eAAe,EAAE,2BAA2B,CAAC;IACpD,QAAQ,EAAE,CAAC,sCAAsC,CAAC;IAClD,OAAO,EAAE,CAAC,wCAAwC,CAAC;IACnD,MAAM,EAAE,CAAC,qBAAqB,EAAE,kBAAkB,CAAC;IACnD,KAAK,EAAE,CAAC,sBAAsB,CAAC;IAC/B,MAAM,EAAE,CAAC,sCAAsC,CAAC;CACxC,CAAC;AAEX,kFAAkF;AAClF,MAAM,UAAU,UAAU,CACxB,GAAa,EACb,IAAgB,EAChB,OAA0C;IAE1C,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,WAAW,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;IAC5D,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;IACrE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC;QACxC,OAAO,EAAE,WAAW;QACpB,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,cAAc;QACtB,cAAc,EAAE,KAAK;QACrB,gBAAgB,EAAE,OAAO;QACzB,iBAAiB,EAAE,OAAO;QAC1B,SAAS,EAAE,OAAO;KACnB,CAAC;QACA,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC3D,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC1B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import type { LayoutOptions } from './types.js';\nconst paths = {\n 'add-tab': ['M12 5v14M5 12h14'],\n 'split-right': ['M3 4h18v16H3z', 'M12 4v16'],\n 'split-below': ['M3 4h18v16H3z', 'M3 12h18'],\n 'tab-orientation': ['M3 4h18v16H3z', 'M3 9h18', 'M8 9v11'],\n join: ['M3 4h18v16H3z', 'm7 9 3 3-3 3m10-6-3 3 3 3'],\n maximize: ['M8 3H3v5m13-5h5v5M3 16v5h5m13-5v5h-5'],\n restore: ['M3 8h5V3m13 5h-5V3M8 21v-5H3m13 5v-5h5'],\n popout: ['M14 3h7v7m0-7L11 13', 'M10 3H3v18h18v-7'],\n close: ['m6 6 12 12M6 18 18 6'],\n cancel: ['M9 5 2 12l7 7M2 12h14a5 5 0 0 0 0-10'],\n} as const;\nexport type ActionIcon = keyof typeof paths;\n/** Small built-in chrome icons; applications may override the namespaced keys. */\nexport function actionIcon(\n doc: Document,\n name: ActionIcon,\n options: Pick<LayoutOptions, 'renderIcon'>,\n): Element {\n const custom = options.renderIcon?.(`layouts:${name}`, doc);\n if (custom) return custom;\n const svg = doc.createElementNS('http://www.w3.org/2000/svg', 'svg');\n for (const [key, value] of Object.entries({\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n 'stroke-width': '1.7',\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n focusable: 'false',\n }))\n svg.setAttribute(key, value);\n for (const d of paths[name]) {\n const path = doc.createElementNS(svg.namespaceURI, 'path');\n path.setAttribute('d', d);\n svg.append(path);\n }\n return svg;\n}\n"]}
1
+ {"version":3,"file":"action-icons.js","sourceRoot":"","sources":["../src/action-icons.ts"],"names":[],"mappings":"AACA,MAAM,KAAK,GAAG;IACZ,SAAS,EAAE,CAAC,kBAAkB,CAAC;IAC/B,aAAa,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IAC5C,aAAa,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IAC5C,iBAAiB,EAAE,CAAC,eAAe,EAAE,SAAS,EAAE,SAAS,CAAC;IAC1D,IAAI,EAAE,CAAC,eAAe,EAAE,2BAA2B,CAAC;IACpD,QAAQ,EAAE,CAAC,sCAAsC,CAAC;IAClD,OAAO,EAAE,CAAC,wCAAwC,CAAC;IACnD,MAAM,EAAE,CAAC,qBAAqB,EAAE,kBAAkB,CAAC;IACnD,KAAK,EAAE,CAAC,sBAAsB,CAAC;IAC/B,MAAM,EAAE,CAAC,sCAAsC,CAAC;CACxC,CAAC;AAEX,kFAAkF;AAClF,MAAM,UAAU,UAAU,CACxB,GAAa,EACb,IAAgB,EAChB,OAAkD;IAElD,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,WAAW,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;IAC5D,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;IACrE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC;QACxC,OAAO,EAAE,WAAW;QACpB,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,cAAc;QACtB,cAAc,EAAE,KAAK;QACrB,gBAAgB,EAAE,OAAO;QACzB,iBAAiB,EAAE,OAAO;QAC1B,SAAS,EAAE,OAAO;KACnB,CAAC;QACA,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC3D,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC1B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import type { ResolvedLayoutOptions } from './types.js';\nconst paths = {\n 'add-tab': ['M12 5v14M5 12h14'],\n 'split-right': ['M3 4h18v16H3z', 'M12 4v16'],\n 'split-below': ['M3 4h18v16H3z', 'M3 12h18'],\n 'tab-orientation': ['M3 4h18v16H3z', 'M3 9h18', 'M8 9v11'],\n join: ['M3 4h18v16H3z', 'm7 9 3 3-3 3m10-6-3 3 3 3'],\n maximize: ['M8 3H3v5m13-5h5v5M3 16v5h5m13-5v5h-5'],\n restore: ['M3 8h5V3m13 5h-5V3M8 21v-5H3m13 5v-5h5'],\n popout: ['M14 3h7v7m0-7L11 13', 'M10 3H3v18h18v-7'],\n close: ['m6 6 12 12M6 18 18 6'],\n cancel: ['M9 5 2 12l7 7M2 12h14a5 5 0 0 0 0-10'],\n} as const;\nexport type ActionIcon = keyof typeof paths;\n/** Small built-in chrome icons; applications may override the namespaced keys. */\nexport function actionIcon(\n doc: Document,\n name: ActionIcon,\n options: Pick<ResolvedLayoutOptions, 'renderIcon'>,\n): Element {\n const custom = options.renderIcon?.(`layouts:${name}`, doc);\n if (custom) return custom;\n const svg = doc.createElementNS('http://www.w3.org/2000/svg', 'svg');\n for (const [key, value] of Object.entries({\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n 'stroke-width': '1.7',\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n focusable: 'false',\n }))\n svg.setAttribute(key, value);\n for (const d of paths[name]) {\n const path = doc.createElementNS(svg.namespaceURI, 'path');\n path.setAttribute('d', d);\n svg.append(path);\n }\n return svg;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { ResolvedLayoutOptions } from './types.js';
2
+ import { Scope } from './lifetime.js';
3
+ export declare function closeRequests(root: HTMLElement, options: ResolvedLayoutOptions, scope: Scope, report: (error: unknown) => void): (id: string, kind?: 'pane' | 'group') => Promise<boolean>;
4
+ //# sourceMappingURL=close.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"close.d.ts","sourceRoot":"","sources":["../src/close.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAM,KAAK,EAAE,MAAM,eAAe,CAAC;AAE1C,wBAAgB,aAAa,CAC3B,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,qBAAqB,EAC9B,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,QASd,MAAM,SAAQ,MAAM,GAAG,OAAO,KAAY,OAAO,CAAC,OAAO,CAAC,CAqG7E"}
package/dist/close.js ADDED
@@ -0,0 +1,95 @@
1
+ import { findNode } from 'quilt-core';
2
+ import { el, Scope } from './lifetime.js';
3
+ import { message } from './messages.js';
4
+ export function closeRequests(root, options, scope, report) {
5
+ let pending;
6
+ let disposed = false;
7
+ scope.add(() => {
8
+ disposed = true;
9
+ pending?.abort();
10
+ });
11
+ const signature = (panes) => JSON.stringify(panes);
12
+ return async (id, kind = 'pane') => {
13
+ if (pending || disposed)
14
+ return false;
15
+ const controller = new AbortController();
16
+ pending = controller;
17
+ const collect = () => {
18
+ const snapshot = options.store.getSnapshot();
19
+ const node = kind === 'group' ? findNode(snapshot.root, id) : undefined;
20
+ const ids = kind === 'group' ? (node?.kind === 'group' ? node.panes : []) : [id];
21
+ return ids.map((key) => snapshot.panes[key]).filter((pane) => !!pane);
22
+ };
23
+ const panes = collect();
24
+ const requiringConfirmation = panes.filter((pane) => pane.confirmClose ??
25
+ options.registry?.list().find((entry) => entry.type === pane.type)?.confirmClose ??
26
+ false);
27
+ const request = {
28
+ panes,
29
+ requiringConfirmation,
30
+ signal: controller.signal,
31
+ ...(kind === 'group' ? { groupId: id } : {}),
32
+ };
33
+ let cleanup = () => { };
34
+ try {
35
+ if (!panes.length || panes.some((pane) => !options.store.can(pane.id, 'close')))
36
+ return false;
37
+ if (requiringConfirmation.length) {
38
+ const decision = options.confirmClose
39
+ ? Promise.resolve(options.confirmClose(request))
40
+ : new Promise((resolve) => {
41
+ const dialog = el(root.ownerDocument, 'dialog', 'layouts-menu layouts-confirm');
42
+ dialog.setAttribute('aria-label', message(options, 'Close selected panes?'));
43
+ const title = el(root.ownerDocument, 'h2', '', message(options, 'Close selected panes?'));
44
+ const list = el(root.ownerDocument, 'p', '', requiringConfirmation.map((pane) => pane.title).join(', '));
45
+ const cancel = el(root.ownerDocument, 'button', 'layouts-button', message(options, 'Cancel'));
46
+ const close = el(root.ownerDocument, 'button', 'layouts-button', message(options, 'Close'));
47
+ cancel.type = close.type = 'button';
48
+ cancel.onclick = () => resolve(false);
49
+ close.onclick = () => resolve(true);
50
+ dialog.oncancel = (event) => {
51
+ event.preventDefault();
52
+ resolve(false);
53
+ };
54
+ dialog.append(title, list, cancel, close);
55
+ root.append(dialog);
56
+ cleanup = () => dialog.remove();
57
+ dialog.showModal();
58
+ cancel.focus();
59
+ });
60
+ const aborted = new Promise((resolve) => controller.signal.addEventListener('abort', () => resolve(false), { once: true }));
61
+ const unsubscribe = options.store.subscribe((event) => {
62
+ if (event.action === 'load' || signature(collect()) !== signature(panes))
63
+ controller.abort();
64
+ });
65
+ const previousCleanup = cleanup;
66
+ cleanup = () => {
67
+ unsubscribe();
68
+ previousCleanup();
69
+ };
70
+ if (!(await Promise.race([decision, aborted])))
71
+ return false;
72
+ }
73
+ if (controller.signal.aborted ||
74
+ signature(collect()) !== signature(panes) ||
75
+ panes.some((pane) => !options.store.can(pane.id, 'close')))
76
+ return false;
77
+ if (kind === 'group')
78
+ options.store.closeGroup(id, { source: 'user' });
79
+ else
80
+ options.store.close(id, { source: 'user' });
81
+ return true;
82
+ }
83
+ catch (error) {
84
+ report(error);
85
+ return false;
86
+ }
87
+ finally {
88
+ cleanup();
89
+ controller.abort();
90
+ if (pending === controller)
91
+ pending = undefined;
92
+ }
93
+ };
94
+ }
95
+ //# sourceMappingURL=close.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"close.js","sourceRoot":"","sources":["../src/close.ts"],"names":[],"mappings":"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","sourcesContent":["import { findNode } from 'quilt-core';\nimport type { Pane } from 'quilt-core';\nimport type { CloseRequest, ResolvedLayoutOptions } from './types.js';\nimport { el, Scope } from './lifetime.js';\nimport { message } from './messages.js';\nexport function closeRequests(\n root: HTMLElement,\n options: ResolvedLayoutOptions,\n scope: Scope,\n report: (error: unknown) => void,\n) {\n let pending: AbortController | undefined;\n let disposed = false;\n scope.add(() => {\n disposed = true;\n pending?.abort();\n });\n const signature = (panes: readonly Pane[]) => JSON.stringify(panes);\n return async (id: string, kind: 'pane' | 'group' = 'pane'): Promise<boolean> => {\n if (pending || disposed) return false;\n const controller = new AbortController();\n pending = controller;\n const collect = (): Pane[] => {\n const snapshot = options.store.getSnapshot();\n const node = kind === 'group' ? findNode(snapshot.root, id) : undefined;\n const ids = kind === 'group' ? (node?.kind === 'group' ? node.panes : []) : [id];\n return ids.map((key) => snapshot.panes[key]).filter((pane): pane is Pane => !!pane);\n };\n const panes = collect();\n const requiringConfirmation = panes.filter(\n (pane) =>\n pane.confirmClose ??\n options.registry?.list().find((entry) => entry.type === pane.type)?.confirmClose ??\n false,\n );\n const request: CloseRequest = {\n panes,\n requiringConfirmation,\n signal: controller.signal,\n ...(kind === 'group' ? { groupId: id } : {}),\n };\n let cleanup = () => {};\n try {\n if (!panes.length || panes.some((pane) => !options.store.can(pane.id, 'close'))) return false;\n if (requiringConfirmation.length) {\n const decision = options.confirmClose\n ? Promise.resolve(options.confirmClose(request))\n : new Promise<boolean>((resolve) => {\n const dialog = el(root.ownerDocument, 'dialog', 'layouts-menu layouts-confirm');\n dialog.setAttribute('aria-label', message(options, 'Close selected panes?'));\n const title = el(\n root.ownerDocument,\n 'h2',\n '',\n message(options, 'Close selected panes?'),\n );\n const list = el(\n root.ownerDocument,\n 'p',\n '',\n requiringConfirmation.map((pane) => pane.title).join(', '),\n );\n const cancel = el(\n root.ownerDocument,\n 'button',\n 'layouts-button',\n message(options, 'Cancel'),\n );\n const close = el(\n root.ownerDocument,\n 'button',\n 'layouts-button',\n message(options, 'Close'),\n );\n cancel.type = close.type = 'button';\n cancel.onclick = () => resolve(false);\n close.onclick = () => resolve(true);\n dialog.oncancel = (event) => {\n event.preventDefault();\n resolve(false);\n };\n dialog.append(title, list, cancel, close);\n root.append(dialog);\n cleanup = () => dialog.remove();\n dialog.showModal();\n cancel.focus();\n });\n const aborted = new Promise<boolean>((resolve) =>\n controller.signal.addEventListener('abort', () => resolve(false), { once: true }),\n );\n const unsubscribe = options.store.subscribe((event) => {\n if (event.action === 'load' || signature(collect()) !== signature(panes))\n controller.abort();\n });\n const previousCleanup = cleanup;\n cleanup = () => {\n unsubscribe();\n previousCleanup();\n };\n if (!(await Promise.race([decision, aborted]))) return false;\n }\n if (\n controller.signal.aborted ||\n signature(collect()) !== signature(panes) ||\n panes.some((pane) => !options.store.can(pane.id, 'close'))\n )\n return false;\n if (kind === 'group') options.store.closeGroup(id, { source: 'user' });\n else options.store.close(id, { source: 'user' });\n return true;\n } catch (error) {\n report(error);\n return false;\n } finally {\n cleanup();\n controller.abort();\n if (pending === controller) pending = undefined;\n }\n };\n}\n"]}
package/dist/corners.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import type { Group, Pane } from 'quilt-core';
2
- import type { LayoutOptions } from './types.js';
2
+ import type { ResolvedLayoutOptions } from './types.js';
3
3
  import { Scope } from './lifetime.js';
4
4
  type Direction = 'left' | 'right' | 'top' | 'bottom';
5
5
  /** Commit once on release; cancellation never changes the layout or pane ownership. */
6
- export declare function bindCorners(host: HTMLElement, id: string, options: LayoutOptions, scope: Scope, split: (pane: Pane | undefined, group: Group, direction: Direction, ratio: number) => void, report: (error: unknown) => void): void;
6
+ export declare function bindCorners(host: HTMLElement, id: string, options: ResolvedLayoutOptions, scope: Scope, split: (pane: Pane | undefined, group: Group, direction: Direction, ratio: number) => void, report: (error: unknown) => void): void;
7
7
  export {};
8
8
  //# sourceMappingURL=corners.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"corners.d.ts","sourceRoot":"","sources":["../src/corners.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAM,KAAK,EAAE,MAAM,eAAe,CAAC;AAC1C,KAAK,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;AACrD,uFAAuF;AACvF,wBAAgB,WAAW,CACzB,IAAI,EAAE,WAAW,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,EAC1F,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,QAsPjC"}
1
+ {"version":3,"file":"corners.d.ts","sourceRoot":"","sources":["../src/corners.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAM,KAAK,EAAE,MAAM,eAAe,CAAC;AAC1C,KAAK,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;AACrD,uFAAuF;AACvF,wBAAgB,WAAW,CACzB,IAAI,EAAE,WAAW,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,qBAAqB,EAC9B,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,EAC1F,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,QAwQjC"}
package/dist/corners.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { message } from './messages.js';
1
2
  import { allocate, bounds, DIVIDER, findNode, joinRange } from 'quilt-core';
2
3
  import { el, Scope } from './lifetime.js';
3
4
  /** Commit once on release; cancellation never changes the layout or pane ownership. */
@@ -11,8 +12,8 @@ export function bindCorners(host, id, options, scope, split, report) {
11
12
  for (const corner of ['tl', 'tr', 'bl', 'br']) {
12
13
  const handle = el(doc, 'button', 'layouts-corner');
13
14
  handle.dataset.corner = corner;
14
- handle.title = 'Drag inward to split; drag across adjacent regions to join. Escape cancels.';
15
- handle.setAttribute('aria-label', 'Split or join region from ' + corner + ' corner');
15
+ handle.title = message(options, 'Drag inward to split; drag across adjacent regions to join. Escape cancels.');
16
+ handle.setAttribute('aria-label', message(options, 'Split or join region from {corner} corner', { corner }));
16
17
  handle.tabIndex = -1; // Equivalent keyboard operations live in the pane menu.
17
18
  host.append(handle);
18
19
  scope.add(() => handle.remove());
@@ -120,7 +121,7 @@ export function bindCorners(host, id, options, scope, split, report) {
120
121
  width: rect.width,
121
122
  height: before ? first : second,
122
123
  };
123
- mark(newRect, 'split', 'New pane');
124
+ mark(newRect, 'split', message(options, 'New pane'));
124
125
  }
125
126
  else {
126
127
  const layout = options.store.getSnapshot();
@@ -156,14 +157,21 @@ export function bindCorners(host, id, options, scope, split, report) {
156
157
  return;
157
158
  const extents = Object.fromEntries([...boxes].map(([nodeId, box]) => [nodeId, horizontal ? box.width : box.height]));
158
159
  target = { kind: 'join', id: receiverId, extents };
159
- const targetTitle = layout.panes[receiver.active ?? '']?.title ?? 'Empty region';
160
+ const targetTitle = layout.panes[receiver.active ?? '']?.title ?? message(options, 'Empty region');
160
161
  const sources = range.selected.filter((g) => g.id !== receiverId);
161
162
  const sourceLabel = sources.every((g) => g.panes.length === 0)
162
- ? `${sources.length} empty ${sources.length === 1 ? 'region' : 'regions'}`
163
- : sources.map((g) => layout.panes[g.active ?? '']?.title ?? 'Empty region').join(', ');
163
+ ? message(options, sources.length === 1 ? '{count} empty region' : '{count} empty regions', { count: sources.length })
164
+ : sources
165
+ .map((g) => layout.panes[g.active ?? '']?.title ?? message(options, 'Empty region'))
166
+ .join(', ');
164
167
  for (const group of range.selected) {
165
168
  const receiving = group.id === receiverId;
166
- mark(boxes.get(group.id), receiving ? 'join-target' : 'join-source', receiving ? `${targetTitle} absorbs ${sourceLabel}` : `Joins ${targetTitle}`);
169
+ mark(boxes.get(group.id), receiving ? 'join-target' : 'join-source', receiving
170
+ ? message(options, '{target} absorbs {source}', {
171
+ target: targetTitle,
172
+ source: sourceLabel,
173
+ })
174
+ : message(options, 'Joins {target}', { target: targetTitle }));
167
175
  }
168
176
  const left = Math.min(...selectedBoxes.map((box) => box.left));
169
177
  const top = Math.min(...selectedBoxes.map((box) => box.top));
@@ -1 +1 @@
1
- {"version":3,"file":"corners.js","sourceRoot":"","sources":["../src/corners.ts"],"names":[],"mappings":"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","sourcesContent":["import { allocate, bounds, DIVIDER, findNode, joinRange } from 'quilt-core';\nimport type { Group, Pane } from 'quilt-core';\nimport type { LayoutOptions } from './types.js';\nimport { el, Scope } from './lifetime.js';\ntype Direction = 'left' | 'right' | 'top' | 'bottom';\n/** Commit once on release; cancellation never changes the layout or pane ownership. */\nexport function bindCorners(\n host: HTMLElement,\n id: string,\n options: LayoutOptions,\n scope: Scope,\n split: (pane: Pane | undefined, group: Group, direction: Direction, ratio: number) => void,\n report: (error: unknown) => void,\n) {\n const doc = host.ownerDocument;\n let drag: Scope | undefined;\n scope.add(() => drag?.dispose());\n const initial = findNode(options.store.getSnapshot().root, id);\n if (initial?.kind !== 'group' || !initial.panes.every((p) => options.store.can(p, 'split')))\n return;\n for (const corner of ['tl', 'tr', 'bl', 'br']) {\n const handle = el(doc, 'button', 'layouts-corner');\n handle.dataset.corner = corner;\n handle.title = 'Drag inward to split; drag across adjacent regions to join. Escape cancels.';\n handle.setAttribute('aria-label', 'Split or join region from ' + corner + ' corner');\n handle.tabIndex = -1; // Equivalent keyboard operations live in the pane menu.\n host.append(handle);\n scope.add(() => handle.remove());\n scope.listen(handle, 'pointerdown', (event) => {\n const start = event as PointerEvent;\n if (start.button !== 0) return;\n const node = findNode(options.store.getSnapshot().root, id);\n if (node?.kind !== 'group' || !node.panes.every((p) => options.store.can(p, 'split'))) return;\n event.preventDefault();\n event.stopPropagation();\n drag?.dispose();\n const local = new Scope();\n drag = local;\n local.add(options.store.subscribe(() => local.dispose()));\n handle.setPointerCapture(start.pointerId);\n let target:\n | { kind: 'split'; direction: Direction; ratio: number }\n | { kind: 'join'; id: string; extents: Record<string, number> }\n | undefined;\n const overlay = el(doc, 'div', 'layouts-corner-overlay');\n overlay.setAttribute('aria-hidden', 'true');\n host.closest('.layouts')!.append(overlay);\n local.add(() => overlay.remove());\n const mark = (\n rect: { left: number; top: number; width: number; height: number },\n kind: string,\n label: string,\n ) => {\n const box = el(doc, 'div', 'layouts-corner-preview');\n box.dataset.cornerPreview = kind;\n Object.assign(box.style, {\n left: `${rect.left}px`,\n top: `${rect.top}px`,\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n });\n box.append(el(doc, 'span', 'layouts-corner-label', label));\n overlay.append(box);\n };\n const clear = () => {\n overlay.replaceChildren();\n target = undefined;\n };\n local.add(() => {\n clear();\n try {\n handle.releasePointerCapture(start.pointerId);\n } catch {}\n });\n local.listen(handle, 'pointermove', (e) => {\n const move = e as PointerEvent;\n clear();\n if (Math.hypot(move.clientX - start.clientX, move.clientY - start.clientY) < 24) return;\n const rect = host.getBoundingClientRect();\n const inside =\n move.clientX > rect.left &&\n move.clientX < rect.right &&\n move.clientY > rect.top &&\n move.clientY < rect.bottom;\n if (inside) {\n const horizontal =\n Math.abs(move.clientX - start.clientX) > Math.abs(move.clientY - start.clientY);\n const direction: Direction = horizontal\n ? corner.endsWith('l')\n ? 'left'\n : 'right'\n : corner.startsWith('t')\n ? 'top'\n : 'bottom';\n target = {\n kind: 'split',\n direction,\n ratio: Math.max(\n 0.1,\n Math.min(\n 0.9,\n horizontal\n ? (move.clientX - rect.left) / rect.width\n : (move.clientY - rect.top) / rect.height,\n ),\n ),\n };\n const before = direction === 'left' || direction === 'top';\n const layout = options.store.getSnapshot();\n const current = findNode(layout.root, id);\n if (!current) return;\n const constraints = bounds(current, layout);\n const min = horizontal ? constraints.minWidth : constraints.minHeight;\n const max = horizontal ? constraints.maxWidth : constraints.maxHeight;\n const total = horizontal ? rect.width : rect.height;\n const disabled =\n current.kind === 'group' &&\n (!current.panes.every((p) => options.store.can(p, 'resize')) || min === max);\n const configuredGap = parseFloat(\n doc\n .defaultView!.getComputedStyle(host.closest('.layouts')!)\n .getPropertyValue(\n disabled\n ? '--layouts-disabled-resize-handle-width'\n : '--layouts-resize-handle-width',\n ),\n );\n const gap =\n Number.isFinite(configuredGap) && configuredGap >= 0\n ? configuredGap\n : disabled\n ? 0\n : DIVIDER;\n const [first, second] = allocate(\n total,\n target.ratio,\n before ? 0 : min,\n before ? Infinity : max,\n before ? min : 0,\n before ? max : Infinity,\n gap,\n );\n // Store uses content extents (excluding the divider), matching this preview exactly.\n const newRect = horizontal\n ? {\n left: rect.left + (before ? 0 : first + gap),\n top: rect.top,\n width: before ? first : second,\n height: rect.height,\n }\n : {\n left: rect.left,\n top: rect.top + (before ? 0 : first + gap),\n width: rect.width,\n height: before ? first : second,\n };\n mark(newRect, 'split', 'New pane');\n } else {\n const layout = options.store.getSnapshot();\n const elements = Array.from(\n host.closest('.layouts')!.querySelectorAll<HTMLElement>('[data-node-id]'),\n ).filter((element) => element.closest('.layouts') === host.closest('.layouts'));\n const boxes = new Map(\n elements.map((element) => [element.dataset.nodeId!, element.getBoundingClientRect()]),\n );\n const hovered = elements.find((element) => {\n const candidate = findNode(layout.root, element.dataset.nodeId!);\n const box = boxes.get(element.dataset.nodeId!)!;\n return (\n candidate?.kind === 'group' &&\n move.clientX >= box.left &&\n move.clientX <= box.right &&\n move.clientY >= box.top &&\n move.clientY <= box.bottom\n );\n });\n if (!hovered) return;\n const receiverId = hovered.dataset.nodeId!;\n const range = joinRange(layout.root, id, receiverId);\n if (\n !range ||\n !range.selected.every((g) => g.panes.every((p) => options.store.can(p, 'join')))\n )\n return;\n const receiver = findNode(layout.root, receiverId);\n if (receiver?.kind !== 'group') return;\n const selectedBoxes = range.selected.map((g) => boxes.get(g.id));\n if (selectedBoxes.some((box) => !box)) return;\n // Require full-edge alignment in the rendered layout too (constraints can leave slack).\n const horizontal = range.row.axis === 'horizontal';\n if (\n selectedBoxes.some((box) =>\n horizontal\n ? Math.abs(box!.top - rect.top) > 1 || Math.abs(box!.bottom - rect.bottom) > 1\n : Math.abs(box!.left - rect.left) > 1 || Math.abs(box!.right - rect.right) > 1,\n )\n )\n return;\n const extents = Object.fromEntries(\n [...boxes].map(([nodeId, box]) => [nodeId, horizontal ? box.width : box.height]),\n );\n target = { kind: 'join', id: receiverId, extents };\n const targetTitle = layout.panes[receiver.active ?? '']?.title ?? 'Empty region';\n const sources = range.selected.filter((g) => g.id !== receiverId);\n const sourceLabel = sources.every((g) => g.panes.length === 0)\n ? `${sources.length} empty ${sources.length === 1 ? 'region' : 'regions'}`\n : sources.map((g) => layout.panes[g.active ?? '']?.title ?? 'Empty region').join(', ');\n for (const group of range.selected) {\n const receiving = group.id === receiverId;\n mark(\n boxes.get(group.id)!,\n receiving ? 'join-target' : 'join-source',\n receiving ? `${targetTitle} absorbs ${sourceLabel}` : `Joins ${targetTitle}`,\n );\n }\n const left = Math.min(...selectedBoxes.map((box) => box!.left));\n const top = Math.min(...selectedBoxes.map((box) => box!.top));\n mark(\n {\n left,\n top,\n width: Math.max(...selectedBoxes.map((box) => box!.right)) - left,\n height: Math.max(...selectedBoxes.map((box) => box!.bottom)) - top,\n },\n 'join',\n '',\n );\n }\n });\n local.listen(handle, 'pointerup', () => {\n const action = target;\n local.dispose();\n if (!action) return;\n try {\n if (action.kind === 'join')\n options.store.joinRegions(action.id, id, { source: 'user', extents: action.extents });\n else {\n const layout = options.store.getSnapshot(),\n group = findNode(layout.root, id);\n if (group?.kind === 'group')\n split(\n group.active ? layout.panes[group.active] : undefined,\n group,\n action.direction,\n action.ratio,\n );\n }\n } catch (error) {\n report(error);\n }\n });\n local.listen(handle, 'pointercancel', () => local.dispose());\n local.listen(handle, 'lostpointercapture', () => local.dispose());\n local.listen(doc, 'keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Escape') local.dispose();\n });\n });\n }\n}\n"]}
1
+ {"version":3,"file":"corners.js","sourceRoot":"","sources":["../src/corners.ts"],"names":[],"mappings":"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","sourcesContent":["import { message } from './messages.js';\nimport { allocate, bounds, DIVIDER, findNode, joinRange } from 'quilt-core';\nimport type { Group, Pane } from 'quilt-core';\nimport type { ResolvedLayoutOptions } from './types.js';\nimport { el, Scope } from './lifetime.js';\ntype Direction = 'left' | 'right' | 'top' | 'bottom';\n/** Commit once on release; cancellation never changes the layout or pane ownership. */\nexport function bindCorners(\n host: HTMLElement,\n id: string,\n options: ResolvedLayoutOptions,\n scope: Scope,\n split: (pane: Pane | undefined, group: Group, direction: Direction, ratio: number) => void,\n report: (error: unknown) => void,\n) {\n const doc = host.ownerDocument;\n let drag: Scope | undefined;\n scope.add(() => drag?.dispose());\n const initial = findNode(options.store.getSnapshot().root, id);\n if (initial?.kind !== 'group' || !initial.panes.every((p) => options.store.can(p, 'split')))\n return;\n for (const corner of ['tl', 'tr', 'bl', 'br']) {\n const handle = el(doc, 'button', 'layouts-corner');\n handle.dataset.corner = corner;\n handle.title = message(\n options,\n 'Drag inward to split; drag across adjacent regions to join. Escape cancels.',\n );\n handle.setAttribute(\n 'aria-label',\n message(options, 'Split or join region from {corner} corner', { corner }),\n );\n handle.tabIndex = -1; // Equivalent keyboard operations live in the pane menu.\n host.append(handle);\n scope.add(() => handle.remove());\n scope.listen(handle, 'pointerdown', (event) => {\n const start = event as PointerEvent;\n if (start.button !== 0) return;\n const node = findNode(options.store.getSnapshot().root, id);\n if (node?.kind !== 'group' || !node.panes.every((p) => options.store.can(p, 'split'))) return;\n event.preventDefault();\n event.stopPropagation();\n drag?.dispose();\n const local = new Scope();\n drag = local;\n local.add(options.store.subscribe(() => local.dispose()));\n handle.setPointerCapture(start.pointerId);\n let target:\n | { kind: 'split'; direction: Direction; ratio: number }\n | { kind: 'join'; id: string; extents: Record<string, number> }\n | undefined;\n const overlay = el(doc, 'div', 'layouts-corner-overlay');\n overlay.setAttribute('aria-hidden', 'true');\n host.closest('.layouts')!.append(overlay);\n local.add(() => overlay.remove());\n const mark = (\n rect: { left: number; top: number; width: number; height: number },\n kind: string,\n label: string,\n ) => {\n const box = el(doc, 'div', 'layouts-corner-preview');\n box.dataset.cornerPreview = kind;\n Object.assign(box.style, {\n left: `${rect.left}px`,\n top: `${rect.top}px`,\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n });\n box.append(el(doc, 'span', 'layouts-corner-label', label));\n overlay.append(box);\n };\n const clear = () => {\n overlay.replaceChildren();\n target = undefined;\n };\n local.add(() => {\n clear();\n try {\n handle.releasePointerCapture(start.pointerId);\n } catch {}\n });\n local.listen(handle, 'pointermove', (e) => {\n const move = e as PointerEvent;\n clear();\n if (Math.hypot(move.clientX - start.clientX, move.clientY - start.clientY) < 24) return;\n const rect = host.getBoundingClientRect();\n const inside =\n move.clientX > rect.left &&\n move.clientX < rect.right &&\n move.clientY > rect.top &&\n move.clientY < rect.bottom;\n if (inside) {\n const horizontal =\n Math.abs(move.clientX - start.clientX) > Math.abs(move.clientY - start.clientY);\n const direction: Direction = horizontal\n ? corner.endsWith('l')\n ? 'left'\n : 'right'\n : corner.startsWith('t')\n ? 'top'\n : 'bottom';\n target = {\n kind: 'split',\n direction,\n ratio: Math.max(\n 0.1,\n Math.min(\n 0.9,\n horizontal\n ? (move.clientX - rect.left) / rect.width\n : (move.clientY - rect.top) / rect.height,\n ),\n ),\n };\n const before = direction === 'left' || direction === 'top';\n const layout = options.store.getSnapshot();\n const current = findNode(layout.root, id);\n if (!current) return;\n const constraints = bounds(current, layout);\n const min = horizontal ? constraints.minWidth : constraints.minHeight;\n const max = horizontal ? constraints.maxWidth : constraints.maxHeight;\n const total = horizontal ? rect.width : rect.height;\n const disabled =\n current.kind === 'group' &&\n (!current.panes.every((p) => options.store.can(p, 'resize')) || min === max);\n const configuredGap = parseFloat(\n doc\n .defaultView!.getComputedStyle(host.closest('.layouts')!)\n .getPropertyValue(\n disabled\n ? '--layouts-disabled-resize-handle-width'\n : '--layouts-resize-handle-width',\n ),\n );\n const gap =\n Number.isFinite(configuredGap) && configuredGap >= 0\n ? configuredGap\n : disabled\n ? 0\n : DIVIDER;\n const [first, second] = allocate(\n total,\n target.ratio,\n before ? 0 : min,\n before ? Infinity : max,\n before ? min : 0,\n before ? max : Infinity,\n gap,\n );\n // Store uses content extents (excluding the divider), matching this preview exactly.\n const newRect = horizontal\n ? {\n left: rect.left + (before ? 0 : first + gap),\n top: rect.top,\n width: before ? first : second,\n height: rect.height,\n }\n : {\n left: rect.left,\n top: rect.top + (before ? 0 : first + gap),\n width: rect.width,\n height: before ? first : second,\n };\n mark(newRect, 'split', message(options, 'New pane'));\n } else {\n const layout = options.store.getSnapshot();\n const elements = Array.from(\n host.closest('.layouts')!.querySelectorAll<HTMLElement>('[data-node-id]'),\n ).filter((element) => element.closest('.layouts') === host.closest('.layouts'));\n const boxes = new Map(\n elements.map((element) => [element.dataset.nodeId!, element.getBoundingClientRect()]),\n );\n const hovered = elements.find((element) => {\n const candidate = findNode(layout.root, element.dataset.nodeId!);\n const box = boxes.get(element.dataset.nodeId!)!;\n return (\n candidate?.kind === 'group' &&\n move.clientX >= box.left &&\n move.clientX <= box.right &&\n move.clientY >= box.top &&\n move.clientY <= box.bottom\n );\n });\n if (!hovered) return;\n const receiverId = hovered.dataset.nodeId!;\n const range = joinRange(layout.root, id, receiverId);\n if (\n !range ||\n !range.selected.every((g) => g.panes.every((p) => options.store.can(p, 'join')))\n )\n return;\n const receiver = findNode(layout.root, receiverId);\n if (receiver?.kind !== 'group') return;\n const selectedBoxes = range.selected.map((g) => boxes.get(g.id));\n if (selectedBoxes.some((box) => !box)) return;\n // Require full-edge alignment in the rendered layout too (constraints can leave slack).\n const horizontal = range.row.axis === 'horizontal';\n if (\n selectedBoxes.some((box) =>\n horizontal\n ? Math.abs(box!.top - rect.top) > 1 || Math.abs(box!.bottom - rect.bottom) > 1\n : Math.abs(box!.left - rect.left) > 1 || Math.abs(box!.right - rect.right) > 1,\n )\n )\n return;\n const extents = Object.fromEntries(\n [...boxes].map(([nodeId, box]) => [nodeId, horizontal ? box.width : box.height]),\n );\n target = { kind: 'join', id: receiverId, extents };\n const targetTitle =\n layout.panes[receiver.active ?? '']?.title ?? message(options, 'Empty region');\n const sources = range.selected.filter((g) => g.id !== receiverId);\n const sourceLabel = sources.every((g) => g.panes.length === 0)\n ? message(\n options,\n sources.length === 1 ? '{count} empty region' : '{count} empty regions',\n { count: sources.length },\n )\n : sources\n .map((g) => layout.panes[g.active ?? '']?.title ?? message(options, 'Empty region'))\n .join(', ');\n for (const group of range.selected) {\n const receiving = group.id === receiverId;\n mark(\n boxes.get(group.id)!,\n receiving ? 'join-target' : 'join-source',\n receiving\n ? message(options, '{target} absorbs {source}', {\n target: targetTitle,\n source: sourceLabel,\n })\n : message(options, 'Joins {target}', { target: targetTitle }),\n );\n }\n const left = Math.min(...selectedBoxes.map((box) => box!.left));\n const top = Math.min(...selectedBoxes.map((box) => box!.top));\n mark(\n {\n left,\n top,\n width: Math.max(...selectedBoxes.map((box) => box!.right)) - left,\n height: Math.max(...selectedBoxes.map((box) => box!.bottom)) - top,\n },\n 'join',\n '',\n );\n }\n });\n local.listen(handle, 'pointerup', () => {\n const action = target;\n local.dispose();\n if (!action) return;\n try {\n if (action.kind === 'join')\n options.store.joinRegions(action.id, id, { source: 'user', extents: action.extents });\n else {\n const layout = options.store.getSnapshot(),\n group = findNode(layout.root, id);\n if (group?.kind === 'group')\n split(\n group.active ? layout.panes[group.active] : undefined,\n group,\n action.direction,\n action.ratio,\n );\n }\n } catch (error) {\n report(error);\n }\n });\n local.listen(handle, 'pointercancel', () => local.dispose());\n local.listen(handle, 'lostpointercapture', () => local.dispose());\n local.listen(doc, 'keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Escape') local.dispose();\n });\n });\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -6,4 +6,11 @@ export { themes, themeFamilies } from './theme.js';
6
6
  export type { LayoutTheme } from './theme.js';
7
7
  export { LayoutStore, LayoutError, createLayout, parseLayout, validate } from 'quilt-core';
8
8
  export type { AutoCollapse, LayoutStoreOptions, Json, Capability, Axis, Pane, Group, Split, Node, WindowPlacement, Popout, Layout as LayoutSnapshot, Issue, CommandOptions, Change, Bounds, JoinOptions, } from 'quilt-core';
9
+ export { PaneRegistry } from './registry.js';
10
+ export type { PaneRegistration } from './registry.js';
11
+ export { parseWorkspace, dockLayout } from './workspace.js';
12
+ export type { WorkspacePreset } from './workspace.js';
13
+ export { themeProperties } from './theme.js';
14
+ export { defaultMessages } from './messages.js';
15
+ export type { Messages } from './messages.js';
9
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,mBAAmB,YAAY,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3F,YAAY,EACV,YAAY,EACZ,kBAAkB,EAClB,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,KAAK,EACL,IAAI,EACJ,eAAe,EACf,MAAM,EACN,MAAM,IAAI,cAAc,EACxB,KAAK,EACL,cAAc,EACd,MAAM,EACN,MAAM,EACN,WAAW,GACZ,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,mBAAmB,YAAY,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3F,YAAY,EACV,YAAY,EACZ,kBAAkB,EAClB,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,KAAK,EACL,IAAI,EACJ,eAAe,EACf,MAAM,EACN,MAAM,IAAI,cAAc,EACxB,KAAK,EACL,cAAc,EACd,MAAM,EACN,MAAM,EACN,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5D,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -2,4 +2,8 @@ export { mountLayout } from './renderer.js';
2
2
  export { TabRegistry } from './registry.js';
3
3
  export { themes, themeFamilies } from './theme.js';
4
4
  export { LayoutStore, LayoutError, createLayout, parseLayout, validate } from 'quilt-core';
5
+ export { PaneRegistry } from './registry.js';
6
+ export { parseWorkspace, dockLayout } from './workspace.js';
7
+ export { themeProperties } from './theme.js';
8
+ export { defaultMessages } from './messages.js';
5
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC","sourcesContent":["export { mountLayout } from './renderer.js';\nexport type * from './types.js';\n\nexport { TabRegistry } from './registry.js';\nexport type { TabRegistration } from './registry.js';\nexport { themes, themeFamilies } from './theme.js';\nexport type { LayoutTheme } from './theme.js';\nexport { LayoutStore, LayoutError, createLayout, parseLayout, validate } from 'quilt-core';\nexport type {\n AutoCollapse,\n LayoutStoreOptions,\n Json,\n Capability,\n Axis,\n Pane,\n Group,\n Split,\n Node,\n WindowPlacement,\n Popout,\n Layout as LayoutSnapshot,\n Issue,\n CommandOptions,\n Change,\n Bounds,\n JoinOptions,\n} from 'quilt-core';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAoB3F,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5D,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC","sourcesContent":["export { mountLayout } from './renderer.js';\nexport type * from './types.js';\n\nexport { TabRegistry } from './registry.js';\nexport type { TabRegistration } from './registry.js';\nexport { themes, themeFamilies } from './theme.js';\nexport type { LayoutTheme } from './theme.js';\nexport { LayoutStore, LayoutError, createLayout, parseLayout, validate } from 'quilt-core';\nexport type {\n AutoCollapse,\n LayoutStoreOptions,\n Json,\n Capability,\n Axis,\n Pane,\n Group,\n Split,\n Node,\n WindowPlacement,\n Popout,\n Layout as LayoutSnapshot,\n Issue,\n CommandOptions,\n Change,\n Bounds,\n JoinOptions,\n} from 'quilt-core';\nexport { PaneRegistry } from './registry.js';\nexport type { PaneRegistration } from './registry.js';\nexport { parseWorkspace, dockLayout } from './workspace.js';\nexport type { WorkspacePreset } from './workspace.js';\nexport { themeProperties } from './theme.js';\nexport { defaultMessages } from './messages.js';\nexport type { Messages } from './messages.js';\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"lifetime.d.ts","sourceRoot":"","sources":["../src/lifetime.ts"],"names":[],"mappings":"AAAA,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,KAAK,CAAS;IACtB,GAAG,CAAC,OAAO,EAAE,MAAM,IAAI,QAGtB;IACD,MAAM,CACJ,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,uBAAuB,QAIlC;IACD,OAAO,SAUN;CACF;AACD,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,QAMxE;AACD,wBAAgB,EAAE,CAAC,CAAC,SAAS,MAAM,qBAAqB,EACtD,GAAG,EAAE,QAAQ,EACb,GAAG,EAAE,CAAC,EACN,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,qBAAqB,CAAC,CAAC,CAAC,CAK1B"}
1
+ {"version":3,"file":"lifetime.d.ts","sourceRoot":"","sources":["../src/lifetime.ts"],"names":[],"mappings":"AAAA,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,KAAK,CAAS;IACtB,GAAG,CAAC,OAAO,EAAE,MAAM,IAAI,QAGtB;IACD,MAAM,CACJ,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,uBAAuB,QAIlC;IACD,OAAO,SAUN;CACF;AACD,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,QAMxE;AACD,wBAAgB,EAAE,CAAC,CAAC,SAAS,MAAM,qBAAqB,EACtD,GAAG,EAAE,QAAQ,EACb,GAAG,EAAE,CAAC,EACN,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,qBAAqB,CAAC,CAAC,CAAC,CAM1B"}
package/dist/lifetime.js CHANGED
@@ -37,6 +37,7 @@ export function syncChildren(parent, children) {
37
37
  export function el(doc, tag, className, text) {
38
38
  const node = doc.createElement(tag);
39
39
  node.className = className;
40
+ node.dataset.layoutsChrome = '';
40
41
  if (text !== undefined)
41
42
  node.textContent = text;
42
43
  return node;
@@ -1 +1 @@
1
- {"version":3,"file":"lifetime.js","sourceRoot":"","sources":["../src/lifetime.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,KAAK;IACR,KAAK,GAAmB,EAAE,CAAC;IAC3B,KAAK,GAAG,KAAK,CAAC;IACtB,GAAG,CAAC,OAAmB;QACrB,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;;YACrB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,CACJ,MAAmB,EACnB,IAAY,EACZ,QAAuB,EACvB,OAAiC;QAEjC,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,OAAO;QACL,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO;QACvB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YAClD,IAAI,CAAC;gBACH,IAAI,EAAE,CAAC;YACT,CAAC;YAAC,MAAM,CAAC;gBACP,8DAA8D;YAChE,CAAC;QACH,CAAC;IACH,CAAC;CACF;AACD,MAAM,UAAU,YAAY,CAAC,MAAmB,EAAE,QAAuB;IACvE,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC5B,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,KAAK;YAAE,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IACH,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC7C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAoB,CAAC;YAAE,KAAK,CAAC,MAAM,EAAE,CAAC;AACjE,CAAC;AACD,MAAM,UAAU,EAAE,CAChB,GAAa,EACb,GAAM,EACN,SAAiB,EACjB,IAAa;IAEb,MAAM,IAAI,GAAG,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC3B,IAAI,IAAI,KAAK,SAAS;QAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAChD,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["export class Scope {\n private tasks: (() => void)[] = [];\n private ended = false;\n add(cleanup: () => void) {\n if (this.ended) cleanup();\n else this.tasks.push(cleanup);\n }\n listen(\n target: EventTarget,\n type: string,\n listener: EventListener,\n options?: AddEventListenerOptions,\n ) {\n target.addEventListener(type, listener, options);\n this.add(() => target.removeEventListener(type, listener, options));\n }\n dispose() {\n if (this.ended) return;\n this.ended = true;\n for (const task of this.tasks.splice(0).reverse()) {\n try {\n task();\n } catch {\n /* Complete the remaining cleanup even if a consumer fails. */\n }\n }\n }\n}\nexport function syncChildren(parent: HTMLElement, children: HTMLElement[]) {\n children.forEach((child, i) => {\n if (parent.children[i] !== child) parent.insertBefore(child, parent.children[i] ?? null);\n });\n for (const child of Array.from(parent.children))\n if (!children.includes(child as HTMLElement)) child.remove();\n}\nexport function el<K extends keyof HTMLElementTagNameMap>(\n doc: Document,\n tag: K,\n className: string,\n text?: string,\n): HTMLElementTagNameMap[K] {\n const node = doc.createElement(tag);\n node.className = className;\n if (text !== undefined) node.textContent = text;\n return node;\n}\n"]}
1
+ {"version":3,"file":"lifetime.js","sourceRoot":"","sources":["../src/lifetime.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,KAAK;IACR,KAAK,GAAmB,EAAE,CAAC;IAC3B,KAAK,GAAG,KAAK,CAAC;IACtB,GAAG,CAAC,OAAmB;QACrB,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;;YACrB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,CACJ,MAAmB,EACnB,IAAY,EACZ,QAAuB,EACvB,OAAiC;QAEjC,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,OAAO;QACL,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO;QACvB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YAClD,IAAI,CAAC;gBACH,IAAI,EAAE,CAAC;YACT,CAAC;YAAC,MAAM,CAAC;gBACP,8DAA8D;YAChE,CAAC;QACH,CAAC;IACH,CAAC;CACF;AACD,MAAM,UAAU,YAAY,CAAC,MAAmB,EAAE,QAAuB;IACvE,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC5B,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,KAAK;YAAE,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IACH,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC7C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAoB,CAAC;YAAE,KAAK,CAAC,MAAM,EAAE,CAAC;AACjE,CAAC;AACD,MAAM,UAAU,EAAE,CAChB,GAAa,EACb,GAAM,EACN,SAAiB,EACjB,IAAa;IAEb,MAAM,IAAI,GAAG,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC3B,IAAI,CAAC,OAAO,CAAC,aAAa,GAAG,EAAE,CAAC;IAChC,IAAI,IAAI,KAAK,SAAS;QAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAChD,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["export class Scope {\n private tasks: (() => void)[] = [];\n private ended = false;\n add(cleanup: () => void) {\n if (this.ended) cleanup();\n else this.tasks.push(cleanup);\n }\n listen(\n target: EventTarget,\n type: string,\n listener: EventListener,\n options?: AddEventListenerOptions,\n ) {\n target.addEventListener(type, listener, options);\n this.add(() => target.removeEventListener(type, listener, options));\n }\n dispose() {\n if (this.ended) return;\n this.ended = true;\n for (const task of this.tasks.splice(0).reverse()) {\n try {\n task();\n } catch {\n /* Complete the remaining cleanup even if a consumer fails. */\n }\n }\n }\n}\nexport function syncChildren(parent: HTMLElement, children: HTMLElement[]) {\n children.forEach((child, i) => {\n if (parent.children[i] !== child) parent.insertBefore(child, parent.children[i] ?? null);\n });\n for (const child of Array.from(parent.children))\n if (!children.includes(child as HTMLElement)) child.remove();\n}\nexport function el<K extends keyof HTMLElementTagNameMap>(\n doc: Document,\n tag: K,\n className: string,\n text?: string,\n): HTMLElementTagNameMap[K] {\n const node = doc.createElement(tag);\n node.className = className;\n node.dataset.layoutsChrome = '';\n if (text !== undefined) node.textContent = text;\n return node;\n}\n"]}
package/dist/menu.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { Group, Pane } from 'quilt-core';
2
- import type { LayoutOptions } from './types.js';
2
+ import type { ResolvedLayoutOptions } from './types.js';
3
3
  import type { Windows } from './windows.js';
4
- export declare function createPaneMenu(root: HTMLElement, options: LayoutOptions, windows: Pick<Windows, 'pending' | 'open'>, refresh: () => void, report: (e: unknown) => void): {
4
+ export declare function createPaneMenu(root: HTMLElement, options: ResolvedLayoutOptions, windows: Pick<Windows, 'open'>, refresh: () => void, report: (e: unknown) => void, requestClose: (id: string, kind?: 'pane' | 'group') => Promise<boolean>): {
5
5
  open: (anchor: HTMLElement, pane: Pane | undefined, group: Group, direction?: 'left' | 'right' | 'top' | 'bottom', ratio?: number, groupActions?: boolean, addTab?: boolean) => void;
6
6
  addTab(anchor: HTMLElement, group: Group): void;
7
7
  openEmpty(anchor: HTMLElement, group: Group): void;
@@ -1 +1 @@
1
- {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../src/menu.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,CAAC,EAC1C,OAAO,EAAE,MAAM,IAAI,EACnB,MAAM,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI;mBAsBlB,WAAW,QACb,IAAI,GAAG,SAAS,SACf,KAAK,cACA,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ;mBAyahC,WAAW,SAAS,KAAK;sBAYtB,WAAW,SAAS,KAAK;;EAW9C"}
1
+ {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../src/menu.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAC9B,OAAO,EAAE,MAAM,IAAI,EACnB,MAAM,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,EAC5B,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC;mBAsB7D,WAAW,QACb,IAAI,GAAG,SAAS,SACf,KAAK,cACA,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ;mBAybhC,WAAW,SAAS,KAAK;sBAYtB,WAAW,SAAS,KAAK;;EAW9C"}