quilt-vanilla 0.2.4 → 0.4.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 (74) hide show
  1. package/README.md +35 -39
  2. package/dist/actions.d.ts +14 -0
  3. package/dist/actions.d.ts.map +1 -0
  4. package/dist/actions.js +115 -0
  5. package/dist/actions.js.map +1 -0
  6. package/dist/chrome-size.d.ts +7 -0
  7. package/dist/chrome-size.d.ts.map +1 -0
  8. package/dist/chrome-size.js +86 -0
  9. package/dist/chrome-size.js.map +1 -0
  10. package/dist/close.d.ts.map +1 -1
  11. package/dist/close.js +3 -1
  12. package/dist/close.js.map +1 -1
  13. package/dist/corners.d.ts +2 -1
  14. package/dist/corners.d.ts.map +1 -1
  15. package/dist/corners.js +2 -2
  16. package/dist/corners.js.map +1 -1
  17. package/dist/index.d.ts +6 -4
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +3 -2
  20. package/dist/index.js.map +1 -1
  21. package/dist/menu.d.ts +9 -3
  22. package/dist/menu.d.ts.map +1 -1
  23. package/dist/menu.js +110 -37
  24. package/dist/menu.js.map +1 -1
  25. package/dist/panes.d.ts.map +1 -1
  26. package/dist/panes.js +84 -52
  27. package/dist/panes.js.map +1 -1
  28. package/dist/registry.d.ts +1 -0
  29. package/dist/registry.d.ts.map +1 -1
  30. package/dist/registry.js +4 -3
  31. package/dist/registry.js.map +1 -1
  32. package/dist/renderer.d.ts.map +1 -1
  33. package/dist/renderer.js +128 -36
  34. package/dist/renderer.js.map +1 -1
  35. package/dist/resize.d.ts +2 -1
  36. package/dist/resize.d.ts.map +1 -1
  37. package/dist/resize.js +2 -2
  38. package/dist/resize.js.map +1 -1
  39. package/dist/shortcut-registration.d.ts +9 -0
  40. package/dist/shortcut-registration.d.ts.map +1 -0
  41. package/dist/shortcut-registration.js +95 -0
  42. package/dist/shortcut-registration.js.map +1 -0
  43. package/dist/shortcuts.d.ts +7 -6
  44. package/dist/shortcuts.d.ts.map +1 -1
  45. package/dist/shortcuts.js +28 -50
  46. package/dist/shortcuts.js.map +1 -1
  47. package/dist/styles.css +74 -9
  48. package/dist/tabs.d.ts.map +1 -1
  49. package/dist/tabs.js +10 -12
  50. package/dist/tabs.js.map +1 -1
  51. package/dist/types.d.ts +50 -13
  52. package/dist/types.d.ts.map +1 -1
  53. package/dist/types.js.map +1 -1
  54. package/dist/workspace-api.d.ts +186 -0
  55. package/dist/workspace-api.d.ts.map +1 -0
  56. package/dist/workspace-api.js +409 -0
  57. package/dist/workspace-api.js.map +1 -0
  58. package/package.json +2 -2
  59. package/src/actions.ts +125 -0
  60. package/src/chrome-size.ts +99 -0
  61. package/src/close.ts +6 -1
  62. package/src/corners.ts +2 -1
  63. package/src/index.ts +31 -4
  64. package/src/menu.ts +123 -43
  65. package/src/panes.ts +82 -55
  66. package/src/registry.ts +6 -4
  67. package/src/renderer.ts +181 -54
  68. package/src/resize.ts +2 -1
  69. package/src/shortcut-registration.ts +106 -0
  70. package/src/shortcuts.ts +38 -63
  71. package/src/styles.css +74 -9
  72. package/src/tabs.ts +9 -11
  73. package/src/types.ts +67 -14
  74. package/src/workspace-api.ts +583 -0
package/dist/shortcuts.js CHANGED
@@ -1,15 +1,10 @@
1
- import { findNode } from 'quilt-core';
2
- const defaults = {
3
- maximize: [{ key: '`' }, { key: ' ', alt: true }],
4
- addTab: [{ key: 't' }],
5
- restoreClosedTab: [{ key: 'r' }],
6
- };
1
+ import { registeredShortcuts } from './shortcut-registration.js';
7
2
  export function shortcutEnabled(options, key) {
8
3
  return (options.shortcuts === true ||
9
4
  (typeof options.shortcuts === 'object' && !!options.shortcuts[key]));
10
5
  }
11
6
  const hovered = new WeakMap();
12
- export function bindShortcuts(root, options, scope, act, addTab) {
7
+ export function bindShortcuts(root, options, scope, canExecute, execute, menuTarget) {
13
8
  const doc = root.ownerDocument;
14
9
  let hoveredGroup;
15
10
  scope.listen(root, 'pointerover', (event) => {
@@ -25,56 +20,39 @@ export function bindShortcuts(root, options, scope, act, addTab) {
25
20
  if (hovered.get(doc) === root)
26
21
  hovered.delete(doc);
27
22
  });
23
+ const ownsFocus = () => (doc.activeElement?.closest('.layouts') ?? hovered.get(doc)) === root;
24
+ const context = () => {
25
+ if (!ownsFocus())
26
+ return {};
27
+ const menu = menuTarget();
28
+ if (menu)
29
+ return menu.context;
30
+ const focusedGroup = doc.activeElement?.closest('.layouts-group')?.dataset.nodeId;
31
+ const groupId = (hovered.get(doc) === root ? hoveredGroup : undefined) ?? focusedGroup;
32
+ return groupId ? { groupId } : {};
33
+ };
28
34
  scope.listen(doc, 'keydown', (event) => {
29
35
  const e = event;
30
36
  const target = e.target;
31
- const focused = doc.activeElement?.closest('.layouts');
32
- if ((focused ?? hovered.get(doc)) !== root || e.defaultPrevented || e.repeat || e.isComposing)
37
+ if (!ownsFocus() || e.defaultPrevented || e.repeat || e.isComposing)
33
38
  return;
34
- if (target?.closest('input, textarea, select, [contenteditable]:not([contenteditable="false"]), dialog') ||
35
- doc.querySelector('dialog[open]'))
39
+ const menu = menuTarget();
40
+ if (target?.closest('input, textarea, select, [contenteditable]:not([contenteditable="false"])') ||
41
+ Array.from(doc.querySelectorAll('dialog[open]')).some((dialog) => dialog !== menu?.dialog))
36
42
  return;
37
- const matches = (binding) => e.key.toLowerCase() === binding.key.toLowerCase() &&
38
- e.ctrlKey === !!binding.ctrl &&
39
- e.altKey === !!binding.alt &&
40
- e.shiftKey === !!binding.shift &&
41
- e.metaKey === !!binding.meta;
42
- const action = Object.keys(defaults).find((key) => {
43
- const configured = options.shortcuts === true
44
- ? true
45
- : typeof options.shortcuts === 'object'
46
- ? options.shortcuts[key]
47
- : false;
48
- if (!configured)
49
- return false;
50
- const bindings = configured === true
51
- ? defaults[key]
52
- : Array.isArray(configured)
53
- ? configured
54
- : [configured];
55
- return bindings.some(matches);
56
- });
57
- if (!action)
58
- return;
59
- if (action === 'restoreClosedTab') {
60
- if (!options.store.canRestoreClosedTab())
61
- return;
62
- e.preventDefault();
63
- act(() => options.store.restoreClosedTab());
64
- return;
65
- }
66
- const focusedGroup = focused === root ? target?.closest('.layouts-group')?.dataset.nodeId : undefined;
67
- const id = (hovered.get(doc) === root ? hoveredGroup : undefined) ?? focusedGroup;
68
- const group = id ? findNode(options.store.getSnapshot().root, id) : undefined;
69
- if (group?.kind !== 'group')
70
- return;
71
- if (action === 'addTab' &&
72
- (!options.tabs?.list().length || !group.panes.every((id) => options.store.can(id, 'move'))))
43
+ const entry = registeredShortcuts(options).find((entry) => entry.handling === 'quilt' &&
44
+ entry.bindings.some((binding) => e.key.toLowerCase() === binding.key.toLowerCase() &&
45
+ e.ctrlKey === !!binding.ctrl &&
46
+ e.altKey === !!binding.alt &&
47
+ e.shiftKey === !!binding.shift &&
48
+ e.metaKey === !!binding.meta));
49
+ const actionContext = context();
50
+ if (!entry || !canExecute(entry.action, actionContext))
73
51
  return;
74
52
  e.preventDefault();
75
- act(() => action === 'addTab'
76
- ? addTab(group)
77
- : options.store.maximize(options.store.getSnapshot().maximized === group.id ? null : group.id));
53
+ menu?.close();
54
+ void execute(entry.action, actionContext);
78
55
  });
56
+ return context;
79
57
  }
80
58
  //# sourceMappingURL=shortcuts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shortcuts.js","sourceRoot":"","sources":["../src/shortcuts.ts"],"names":[],"mappings":"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","sourcesContent":["import { findNode } from 'quilt-core';\nimport type { Group } from 'quilt-core';\nimport type { ResolvedLayoutOptions, KeyBinding } from './types.js';\nimport type { Scope } from './lifetime.js';\ntype Action = 'maximize' | 'addTab' | 'restoreClosedTab';\nconst defaults: Record<Action, readonly KeyBinding[]> = {\n maximize: [{ key: '`' }, { key: ' ', alt: true }],\n addTab: [{ key: 't' }],\n restoreClosedTab: [{ key: 'r' }],\n};\nexport function shortcutEnabled(options: ResolvedLayoutOptions, key: Action | 'middleClickClose') {\n return (\n options.shortcuts === true ||\n (typeof options.shortcuts === 'object' && !!options.shortcuts[key])\n );\n}\nconst hovered = new WeakMap<Document, HTMLElement>();\nexport function bindShortcuts(\n root: HTMLElement,\n options: ResolvedLayoutOptions,\n scope: Scope,\n act: (fn: () => void) => void,\n addTab: (group: Group) => void,\n) {\n const doc = root.ownerDocument;\n let hoveredGroup: string | undefined;\n scope.listen(root, 'pointerover', (event) => {\n hovered.set(doc, root);\n hoveredGroup = (event.target as Element).closest<HTMLElement>('.layouts-group')?.dataset.nodeId;\n });\n scope.listen(root, 'pointerleave', () => {\n if (hovered.get(doc) === root) hovered.delete(doc);\n hoveredGroup = undefined;\n });\n scope.add(() => {\n if (hovered.get(doc) === root) hovered.delete(doc);\n });\n scope.listen(doc, 'keydown', (event) => {\n const e = event as KeyboardEvent;\n const target = e.target as HTMLElement | null;\n const focused = doc.activeElement?.closest<HTMLElement>('.layouts');\n if ((focused ?? hovered.get(doc)) !== root || e.defaultPrevented || e.repeat || e.isComposing)\n return;\n if (\n target?.closest(\n 'input, textarea, select, [contenteditable]:not([contenteditable=\"false\"]), dialog',\n ) ||\n doc.querySelector('dialog[open]')\n )\n return;\n const matches = (binding: KeyBinding) =>\n e.key.toLowerCase() === binding.key.toLowerCase() &&\n e.ctrlKey === !!binding.ctrl &&\n e.altKey === !!binding.alt &&\n e.shiftKey === !!binding.shift &&\n e.metaKey === !!binding.meta;\n const action = (Object.keys(defaults) as Action[]).find((key) => {\n const configured =\n options.shortcuts === true\n ? true\n : typeof options.shortcuts === 'object'\n ? options.shortcuts[key]\n : false;\n if (!configured) return false;\n const bindings =\n configured === true\n ? defaults[key]\n : Array.isArray(configured)\n ? configured\n : [configured as KeyBinding];\n return bindings.some(matches);\n });\n if (!action) return;\n if (action === 'restoreClosedTab') {\n if (!options.store.canRestoreClosedTab()) return;\n e.preventDefault();\n act(() => options.store.restoreClosedTab());\n return;\n }\n const focusedGroup =\n focused === root ? target?.closest<HTMLElement>('.layouts-group')?.dataset.nodeId : undefined;\n const id = (hovered.get(doc) === root ? hoveredGroup : undefined) ?? focusedGroup;\n const group = id ? findNode(options.store.getSnapshot().root, id) : undefined;\n if (group?.kind !== 'group') return;\n if (\n action === 'addTab' &&\n (!options.tabs?.list().length || !group.panes.every((id) => options.store.can(id, 'move')))\n )\n return;\n e.preventDefault();\n act(() =>\n action === 'addTab'\n ? addTab(group)\n : options.store.maximize(\n options.store.getSnapshot().maximized === group.id ? null : group.id,\n ),\n );\n });\n}\n"]}
1
+ {"version":3,"file":"shortcuts.js","sourceRoot":"","sources":["../src/shortcuts.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,MAAM,UAAU,eAAe,CAAC,OAA8B,EAAE,GAAuB;IACrF,OAAO,CACL,OAAO,CAAC,SAAS,KAAK,IAAI;QAC1B,CAAC,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CACpE,CAAC;AACJ,CAAC;AACD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAyB,CAAC;AACrD,MAAM,UAAU,aAAa,CAC3B,IAAiB,EACjB,OAA8B,EAC9B,KAAY,EACZ,UAAyE,EACzE,OAA+E,EAC/E,UACkF;IAElF,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC;IAC/B,IAAI,YAAgC,CAAC;IACrC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;QAC1C,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACvB,YAAY,GAAI,KAAK,CAAC,MAAkB,CAAC,OAAO,CAAc,gBAAgB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC;IAClG,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE;QACtC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;YAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACnD,YAAY,GAAG,SAAS,CAAC;IAC3B,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;YAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,GAAG,EAAE,CACrB,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAc,UAAU,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC;IACrF,MAAM,OAAO,GAAG,GAAkB,EAAE;QAClC,IAAI,CAAC,SAAS,EAAE;YAAE,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC;QAC9B,MAAM,YAAY,GAAG,GAAG,CAAC,aAAa,EAAE,OAAO,CAAc,gBAAgB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC;QAC/F,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,YAAY,CAAC;QACvF,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpC,CAAC,CAAC;IACF,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;QACrC,MAAM,CAAC,GAAG,KAAsB,CAAC;QACjC,MAAM,MAAM,GAAG,CAAC,CAAC,MAA4B,CAAC;QAC9C,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,WAAW;YAAE,OAAO;QAC5E,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,IACE,MAAM,EAAE,OAAO,CACb,2EAA2E,CAC5E;YACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,IAAI,EAAE,MAAM,CAAC;YAE1F,OAAO;QACT,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC,IAAI,CAC7C,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,QAAQ,KAAK,OAAO;YAC1B,KAAK,CAAC,QAAQ,CAAC,IAAI,CACjB,CAAC,OAAO,EAAE,EAAE,CACV,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE;gBACjD,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI;gBAC5B,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG;gBAC1B,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK;gBAC9B,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAC/B,CACJ,CAAC;QACF,MAAM,aAAa,GAAG,OAAO,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,aAAa,CAAC;YAAE,OAAO;QAC/D,CAAC,CAAC,cAAc,EAAE,CAAC;QACnB,IAAI,EAAE,KAAK,EAAE,CAAC;QACd,KAAK,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import type { ActionContext, ResolvedLayoutOptions, WorkspaceAction } from './types.js';\nimport type { Scope } from './lifetime.js';\nimport { registeredShortcuts } from './shortcut-registration.js';\nexport function shortcutEnabled(options: ResolvedLayoutOptions, key: 'middleClickClose') {\n return (\n options.shortcuts === true ||\n (typeof options.shortcuts === 'object' && !!options.shortcuts[key])\n );\n}\nconst hovered = new WeakMap<Document, HTMLElement>();\nexport function bindShortcuts(\n root: HTMLElement,\n options: ResolvedLayoutOptions,\n scope: Scope,\n canExecute: (action: WorkspaceAction, context?: ActionContext) => boolean,\n execute: (action: WorkspaceAction, context?: ActionContext) => Promise<boolean>,\n menuTarget: () =>\n { dialog: HTMLDialogElement; context: ActionContext; close(): void } | undefined,\n) {\n const doc = root.ownerDocument;\n let hoveredGroup: string | undefined;\n scope.listen(root, 'pointerover', (event) => {\n hovered.set(doc, root);\n hoveredGroup = (event.target as Element).closest<HTMLElement>('.layouts-group')?.dataset.nodeId;\n });\n scope.listen(root, 'pointerleave', () => {\n if (hovered.get(doc) === root) hovered.delete(doc);\n hoveredGroup = undefined;\n });\n scope.add(() => {\n if (hovered.get(doc) === root) hovered.delete(doc);\n });\n const ownsFocus = () =>\n (doc.activeElement?.closest<HTMLElement>('.layouts') ?? hovered.get(doc)) === root;\n const context = (): ActionContext => {\n if (!ownsFocus()) return {};\n const menu = menuTarget();\n if (menu) return menu.context;\n const focusedGroup = doc.activeElement?.closest<HTMLElement>('.layouts-group')?.dataset.nodeId;\n const groupId = (hovered.get(doc) === root ? hoveredGroup : undefined) ?? focusedGroup;\n return groupId ? { groupId } : {};\n };\n scope.listen(doc, 'keydown', (event) => {\n const e = event as KeyboardEvent;\n const target = e.target as HTMLElement | null;\n if (!ownsFocus() || e.defaultPrevented || e.repeat || e.isComposing) return;\n const menu = menuTarget();\n if (\n target?.closest(\n 'input, textarea, select, [contenteditable]:not([contenteditable=\"false\"])',\n ) ||\n Array.from(doc.querySelectorAll('dialog[open]')).some((dialog) => dialog !== menu?.dialog)\n )\n return;\n const entry = registeredShortcuts(options).find(\n (entry) =>\n entry.handling === 'quilt' &&\n entry.bindings.some(\n (binding) =>\n e.key.toLowerCase() === binding.key.toLowerCase() &&\n e.ctrlKey === !!binding.ctrl &&\n e.altKey === !!binding.alt &&\n e.shiftKey === !!binding.shift &&\n e.metaKey === !!binding.meta,\n ),\n );\n const actionContext = context();\n if (!entry || !canExecute(entry.action, actionContext)) return;\n e.preventDefault();\n menu?.close();\n void execute(entry.action, actionContext);\n });\n return context;\n}\n"]}
package/dist/styles.css CHANGED
@@ -162,10 +162,13 @@
162
162
  .layouts-menu {
163
163
  position: fixed;
164
164
  margin: 0;
165
- padding: 5px;
166
165
  width: 240px;
167
166
  max-height: min(520px, 70vh);
168
167
  overflow: auto;
168
+ }
169
+ .layouts-menu,
170
+ .layouts-submenu-content {
171
+ padding: var(--layouts-spacing, 5px);
169
172
  background: var(--layouts-header, #242a34);
170
173
  color: var(--layouts-text, #e5e9f0);
171
174
  border: 1px solid var(--layouts-line, #39414e);
@@ -374,9 +377,6 @@
374
377
  .layouts-submenu-content {
375
378
  display: flex;
376
379
  flex-direction: column;
377
- padding: 4px;
378
- border: 1px solid var(--layouts-line);
379
- background: var(--layouts-panel);
380
380
  }
381
381
  .layouts-corner {
382
382
  position: absolute;
@@ -437,8 +437,6 @@
437
437
  box-sizing: border-box;
438
438
  overflow: auto;
439
439
  width: 200px;
440
- box-shadow: 0 8px 24px #0005;
441
- border-radius: var(--layouts-radius, 5px);
442
440
  }
443
441
 
444
442
  .layouts-corner-overlay {
@@ -482,9 +480,6 @@
482
480
  .layouts-picker button {
483
481
  min-height: var(--layouts-control-height, 28px);
484
482
  }
485
- .layouts-menu {
486
- padding: var(--layouts-spacing, 5px);
487
- }
488
483
 
489
484
  /* Tapered chrome overlays the pane; only its painted footprint intercepts input. */
490
485
  .layouts-group[data-tab-bar='tapered'] > .layouts-header {
@@ -831,3 +826,73 @@
831
826
  flex: 0 0 calc(var(--layouts-icon-size, 16px) + 16px);
832
827
  min-width: calc(var(--layouts-icon-size, 16px) + 16px);
833
828
  }
829
+
830
+ /* Chrome remains usable at the renderer's minimum region size, even with larger icons. */
831
+ .layouts-group[data-tab-placement='top'] > .layouts-header {
832
+ min-height: calc(var(--layouts-icon-size, 16px) + 9px);
833
+ }
834
+ .layouts-group[data-tab-placement='top'][data-tab-display='automatic'] .layouts-tab-item {
835
+ min-width: max(32px, calc(var(--layouts-icon-size, 16px) + 8px));
836
+ }
837
+ .layouts-group[data-tab-placement='top'][data-tab-display='automatic']
838
+ .layouts-tab-item[data-active='true']:has(> .layouts-tab-close) {
839
+ min-width: max(
840
+ 56px,
841
+ calc(var(--layouts-icon-size, 16px) + 11px + max(22px, var(--layouts-icon-size, 16px)))
842
+ );
843
+ }
844
+ .layouts-group[data-tab-placement='left'] > .layouts-header {
845
+ min-width: max(32px, calc(var(--layouts-icon-size, 16px) + 10px));
846
+ }
847
+ .layouts-group[data-tab-placement='left'] .layouts-tab-item,
848
+ .layouts-group[data-tab-placement='left'] > .layouts-header > .layouts-button {
849
+ flex-basis: max(30px, calc(var(--layouts-icon-size, 16px) + 8px));
850
+ height: max(30px, calc(var(--layouts-icon-size, 16px) + 8px));
851
+ }
852
+ .layouts-group[data-tab-placement='left'][data-tab-display='automatic']
853
+ .layouts-tab-item[data-active='true']:has(> .layouts-tab-close) {
854
+ flex-basis: calc(
855
+ max(30px, var(--layouts-icon-size, 16px) + 8px) + max(22px, var(--layouts-icon-size, 16px))
856
+ );
857
+ height: calc(
858
+ max(30px, var(--layouts-icon-size, 16px) + 8px) + max(22px, var(--layouts-icon-size, 16px))
859
+ );
860
+ }
861
+ .layouts-group[data-tab-placement='left'][data-tab-display='automatic']
862
+ .layouts-tab-item[data-active='true']:has(> .layouts-tab-close)
863
+ > .layouts-tab {
864
+ flex-basis: max(30px, calc(var(--layouts-icon-size, 16px) + 8px));
865
+ }
866
+
867
+ .layouts-tab-item .layouts-tab-close {
868
+ flex-basis: max(22px, var(--layouts-icon-size, 16px));
869
+ width: max(22px, var(--layouts-icon-size, 16px));
870
+ max-height: max(24px, var(--layouts-icon-size, 16px));
871
+ }
872
+ .layouts-group[data-tab-placement='left'][data-tab-display='automatic']
873
+ .layouts-tab-item[data-active='true']
874
+ > .layouts-tab-close {
875
+ flex-basis: max(22px, var(--layouts-icon-size, 16px));
876
+ height: max(22px, var(--layouts-icon-size, 16px));
877
+ }
878
+
879
+ .layouts-shortcut {
880
+ display: inline-flex;
881
+ align-items: center;
882
+ justify-content: center;
883
+ margin-left: auto;
884
+ min-width: 1.8em;
885
+ min-height: 1.8em;
886
+ padding: 0.15em 0.45em;
887
+ flex-shrink: 0;
888
+ border: 1px solid color-mix(in srgb, var(--layouts-text, #e5e9f0) 22%, transparent);
889
+ border-radius: 0.5em;
890
+ background: color-mix(in srgb, var(--layouts-text, #e5e9f0) 4%, transparent);
891
+ font: inherit;
892
+ font-size: 0.9em;
893
+ font-weight: 500;
894
+ line-height: 1.2;
895
+ color: var(--layouts-text, #e5e9f0);
896
+ white-space: nowrap;
897
+ pointer-events: none;
898
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../src/tabs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGxD,UAAU,eAAe;IACvB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAClC,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC1C,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AACD,oFAAoF;AACpF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,eAAe,QAiH7F"}
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../src/tabs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGxD,UAAU,eAAe;IACvB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAClC,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC1C,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AACD,oFAAoF;AACpF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,eAAe,QA+G7F"}
package/dist/tabs.js CHANGED
@@ -108,18 +108,16 @@ export function fillTabs(tabs, group, panes, deps) {
108
108
  x.dataset.focusId = `close-${pane.id}`;
109
109
  x.onclick = close;
110
110
  item.append(x);
111
- if (shortcutEnabled(options, 'middleClickClose')) {
112
- item.onmousedown = (e) => {
113
- if (e.button === 1)
114
- e.preventDefault();
115
- };
116
- item.onauxclick = (e) => {
117
- if (e.button === 1) {
118
- e.preventDefault();
119
- close();
120
- }
121
- };
122
- }
111
+ item.onmousedown = (e) => {
112
+ if (e.button === 1 && shortcutEnabled(options, 'middleClickClose'))
113
+ e.preventDefault();
114
+ };
115
+ item.onauxclick = (e) => {
116
+ if (e.button === 1 && shortcutEnabled(options, 'middleClickClose')) {
117
+ e.preventDefault();
118
+ close();
119
+ }
120
+ };
123
121
  }
124
122
  tabs.append(item);
125
123
  });
package/dist/tabs.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../src/tabs.ts"],"names":[],"mappings":"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","sourcesContent":["import { message } from './messages.js';\nimport { chromeIcon } from './chrome-icons.js';\nimport type { Group, Pane } from 'quilt-core';\nimport type { ResolvedLayoutOptions } from './types.js';\nimport { el } from './lifetime.js';\nimport { shortcutEnabled } from './shortcuts.js';\ninterface TabDependencies {\n options: ResolvedLayoutOptions;\n requestClose: (id: string) => Promise<boolean>;\n prefix: string;\n act: (fn: () => void) => void;\n getDrag: () => string | undefined;\n setDrag: (id: string | undefined) => void;\n clearDrop: () => void;\n focusActive: () => void;\n}\n/** Header nodes are disposable; pane views are owned separately by the renderer. */\nexport function fillTabs(tabs: HTMLElement, group: Group, panes: Pane[], deps: TabDependencies) {\n const { options, prefix, act } = deps;\n const doc = tabs.ownerDocument;\n panes.forEach((pane, i) => {\n const active = pane.id === group.active;\n const item = el(doc, 'div', 'layouts-tab-item');\n item.dataset.active = String(active);\n const tab = el(doc, 'button', 'layouts-tab');\n tab.type = 'button';\n tab.setAttribute('aria-label', pane.title);\n tab.setAttribute('role', 'tab');\n tab.setAttribute('aria-selected', String(active));\n tab.tabIndex = active ? 0 : -1;\n tab.dataset.focusId = `tab-${pane.id}`;\n tab.id = `${prefix}-tab-${pane.id}`;\n tab.setAttribute('aria-controls', `${prefix}-panel-${pane.id}`);\n const icon = el(doc, 'span', 'layouts-tab-icon');\n icon.setAttribute('aria-hidden', 'true');\n let resolved: Element | undefined;\n act(() => {\n resolved = pane.icon ? options.renderIcon?.(pane.icon, doc) : undefined;\n });\n if (resolved) icon.append(resolved);\n else icon.textContent = Array.from(pane.title.trim())[0] || '•';\n tab.append(icon, el(doc, 'span', 'layouts-tab-label', pane.title));\n tab.onclick = () => act(() => options.store.activate(group.id, pane.id));\n tab.draggable = options.store.can(pane.id, 'move');\n tab.ondragstart = (e) => {\n deps.setDrag(pane.id);\n e.dataTransfer?.setData('text/plain', pane.id);\n if (e.dataTransfer) e.dataTransfer.effectAllowed = 'move';\n };\n tab.ondragend = () => {\n deps.setDrag(undefined);\n deps.clearDrop();\n };\n const vertical = () => tabs.getAttribute('aria-orientation') === 'vertical';\n const after = (e: DragEvent) => {\n const rect = item.getBoundingClientRect();\n return vertical()\n ? e.clientY > rect.top + rect.height / 2\n : e.clientX > rect.left + rect.width / 2;\n };\n item.ondragover = (e) => {\n const id = deps.getDrag();\n if (\n !id ||\n !options.store.can(id, 'move') ||\n !group.panes.every((p) => options.store.can(p, 'move'))\n )\n return;\n e.preventDefault();\n e.stopPropagation();\n deps.clearDrop();\n item.dataset.tabDrop = after(e) ? 'after' : 'before';\n };\n item.ondragleave = () => {\n delete item.dataset.tabDrop;\n };\n item.ondrop = (e) => {\n const id = deps.getDrag();\n if (!id) return;\n e.preventDefault();\n e.stopPropagation();\n let index = i + (after(e) ? 1 : 0);\n const source = group.panes.indexOf(id);\n // The controller accepts an insertion index after removing the source tab.\n if (source >= 0 && source < index) index--;\n deps.setDrag(undefined);\n deps.clearDrop();\n act(() => options.store.move(id, group.id, 'tab', index, { source: 'user' }));\n };\n tab.onkeydown = (e) => {\n let index = i;\n if (e.key === (vertical() ? 'ArrowDown' : 'ArrowRight')) index = (i + 1) % panes.length;\n else if (e.key === (vertical() ? 'ArrowUp' : 'ArrowLeft'))\n index = (i + panes.length - 1) % panes.length;\n else if (e.key === 'Home') index = 0;\n else if (e.key === 'End') index = panes.length - 1;\n else return;\n e.preventDefault();\n act(() => options.store.activate(group.id, panes[index]!.id));\n deps.focusActive();\n };\n const close = () =>\n act(() => {\n void deps.requestClose(pane.id);\n deps.focusActive();\n });\n item.append(tab);\n if (options.store.can(pane.id, 'close')) {\n const x = el(doc, 'button', 'layouts-button layouts-tab-close');\n x.append(chromeIcon(doc, 'close'));\n x.type = 'button';\n x.title = message(options, 'Close {title}', { title: pane.title });\n x.setAttribute('aria-label', x.title);\n x.dataset.focusId = `close-${pane.id}`;\n x.onclick = close;\n item.append(x);\n if (shortcutEnabled(options, 'middleClickClose')) {\n item.onmousedown = (e) => {\n if (e.button === 1) e.preventDefault();\n };\n item.onauxclick = (e) => {\n if (e.button === 1) {\n e.preventDefault();\n close();\n }\n };\n }\n }\n tabs.append(item);\n });\n}\n"]}
1
+ {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../src/tabs.ts"],"names":[],"mappings":"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","sourcesContent":["import { message } from './messages.js';\nimport { chromeIcon } from './chrome-icons.js';\nimport type { Group, Pane } from 'quilt-core';\nimport type { ResolvedLayoutOptions } from './types.js';\nimport { el } from './lifetime.js';\nimport { shortcutEnabled } from './shortcuts.js';\ninterface TabDependencies {\n options: ResolvedLayoutOptions;\n requestClose: (id: string) => Promise<boolean>;\n prefix: string;\n act: (fn: () => void) => void;\n getDrag: () => string | undefined;\n setDrag: (id: string | undefined) => void;\n clearDrop: () => void;\n focusActive: () => void;\n}\n/** Header nodes are disposable; pane views are owned separately by the renderer. */\nexport function fillTabs(tabs: HTMLElement, group: Group, panes: Pane[], deps: TabDependencies) {\n const { options, prefix, act } = deps;\n const doc = tabs.ownerDocument;\n panes.forEach((pane, i) => {\n const active = pane.id === group.active;\n const item = el(doc, 'div', 'layouts-tab-item');\n item.dataset.active = String(active);\n const tab = el(doc, 'button', 'layouts-tab');\n tab.type = 'button';\n tab.setAttribute('aria-label', pane.title);\n tab.setAttribute('role', 'tab');\n tab.setAttribute('aria-selected', String(active));\n tab.tabIndex = active ? 0 : -1;\n tab.dataset.focusId = `tab-${pane.id}`;\n tab.id = `${prefix}-tab-${pane.id}`;\n tab.setAttribute('aria-controls', `${prefix}-panel-${pane.id}`);\n const icon = el(doc, 'span', 'layouts-tab-icon');\n icon.setAttribute('aria-hidden', 'true');\n let resolved: Element | undefined;\n act(() => {\n resolved = pane.icon ? options.renderIcon?.(pane.icon, doc) : undefined;\n });\n if (resolved) icon.append(resolved);\n else icon.textContent = Array.from(pane.title.trim())[0] || '•';\n tab.append(icon, el(doc, 'span', 'layouts-tab-label', pane.title));\n tab.onclick = () => act(() => options.store.activate(group.id, pane.id));\n tab.draggable = options.store.can(pane.id, 'move');\n tab.ondragstart = (e) => {\n deps.setDrag(pane.id);\n e.dataTransfer?.setData('text/plain', pane.id);\n if (e.dataTransfer) e.dataTransfer.effectAllowed = 'move';\n };\n tab.ondragend = () => {\n deps.setDrag(undefined);\n deps.clearDrop();\n };\n const vertical = () => tabs.getAttribute('aria-orientation') === 'vertical';\n const after = (e: DragEvent) => {\n const rect = item.getBoundingClientRect();\n return vertical()\n ? e.clientY > rect.top + rect.height / 2\n : e.clientX > rect.left + rect.width / 2;\n };\n item.ondragover = (e) => {\n const id = deps.getDrag();\n if (\n !id ||\n !options.store.can(id, 'move') ||\n !group.panes.every((p) => options.store.can(p, 'move'))\n )\n return;\n e.preventDefault();\n e.stopPropagation();\n deps.clearDrop();\n item.dataset.tabDrop = after(e) ? 'after' : 'before';\n };\n item.ondragleave = () => {\n delete item.dataset.tabDrop;\n };\n item.ondrop = (e) => {\n const id = deps.getDrag();\n if (!id) return;\n e.preventDefault();\n e.stopPropagation();\n let index = i + (after(e) ? 1 : 0);\n const source = group.panes.indexOf(id);\n // The controller accepts an insertion index after removing the source tab.\n if (source >= 0 && source < index) index--;\n deps.setDrag(undefined);\n deps.clearDrop();\n act(() => options.store.move(id, group.id, 'tab', index, { source: 'user' }));\n };\n tab.onkeydown = (e) => {\n let index = i;\n if (e.key === (vertical() ? 'ArrowDown' : 'ArrowRight')) index = (i + 1) % panes.length;\n else if (e.key === (vertical() ? 'ArrowUp' : 'ArrowLeft'))\n index = (i + panes.length - 1) % panes.length;\n else if (e.key === 'Home') index = 0;\n else if (e.key === 'End') index = panes.length - 1;\n else return;\n e.preventDefault();\n act(() => options.store.activate(group.id, panes[index]!.id));\n deps.focusActive();\n };\n const close = () =>\n act(() => {\n void deps.requestClose(pane.id);\n deps.focusActive();\n });\n item.append(tab);\n if (options.store.can(pane.id, 'close')) {\n const x = el(doc, 'button', 'layouts-button layouts-tab-close');\n x.append(chromeIcon(doc, 'close'));\n x.type = 'button';\n x.title = message(options, 'Close {title}', { title: pane.title });\n x.setAttribute('aria-label', x.title);\n x.dataset.focusId = `close-${pane.id}`;\n x.onclick = close;\n item.append(x);\n item.onmousedown = (e) => {\n if (e.button === 1 && shortcutEnabled(options, 'middleClickClose')) e.preventDefault();\n };\n item.onauxclick = (e) => {\n if (e.button === 1 && shortcutEnabled(options, 'middleClickClose')) {\n e.preventDefault();\n close();\n }\n };\n }\n tabs.append(item);\n });\n}\n"]}
package/dist/types.d.ts CHANGED
@@ -3,9 +3,13 @@ import type { WorkspacePreset } from './workspace.js';
3
3
  import type { Messages } from './messages.js';
4
4
  import type { TabRegistry } from './registry.js';
5
5
  import type { LayoutTheme } from './theme.js';
6
- import type { LayoutStore, Pane, WindowPlacement } from 'quilt-core';
6
+ import type { LayoutStore, Layout, Pane, WindowPlacement } from 'quilt-core';
7
7
  export interface PaneContext<State = unknown> {
8
8
  element: HTMLElement;
9
+ /** Aborted when this view is torn down, including a failed mount. */
10
+ signal: AbortSignal;
11
+ /** Register view-owned cleanup; callbacks run once in reverse order. */
12
+ onCleanup(callback: () => void): void;
9
13
  reportError(error: unknown): void;
10
14
  document: Document;
11
15
  window: Window;
@@ -21,7 +25,7 @@ export interface PaneView {
21
25
  resize?(width: number, height: number): void;
22
26
  update?(pane: Pane): void;
23
27
  }
24
- export type PaneRenderer<State = unknown> = (context: PaneContext<State>) => PaneView;
28
+ export type PaneRenderer<State = unknown> = (context: PaneContext<State>) => PaneView | void;
25
29
  export interface TabBarStyle {
26
30
  /** Left placement uses an icon-only rail; mode and shape apply in either placement. */
27
31
  placement?: 'top' | 'left';
@@ -40,25 +44,21 @@ export interface TabBarOptions extends TabBarStyle {
40
44
  /** Partial overrides keyed by stable group ID; not serialized in Layout JSON. */
41
45
  regions?: Record<string, TabBarStyle>;
42
46
  }
43
- export interface ResolvedLayoutOptions<State = unknown> {
47
+ /** Live appearance, interactions, and application integration callbacks. */
48
+ export interface WorkspaceSettings<State = unknown> {
44
49
  tabBar?: TabBarOptions;
45
- store: LayoutStore;
46
- tabs?: TabRegistry;
47
50
  theme?: LayoutTheme;
48
- renderers?: Record<string, PaneRenderer<State>>;
49
- registry?: PaneRegistry<PaneRenderer<State>>;
50
51
  messages?: Messages;
51
52
  popouts?: boolean;
52
53
  confirmClose?: (request: CloseRequest) => boolean | Promise<boolean>;
53
54
  /** Return a fresh decorative icon element. Unknown keys use a title initial. */
54
55
  renderIcon?: (key: string, document: Document) => Element | undefined;
55
56
  /** Opt-in conveniences; omitted and false disable all. */
56
- shortcuts?: boolean | {
57
- maximize?: boolean | KeyBinding | readonly KeyBinding[];
57
+ shortcuts?: boolean | (Partial<Record<WorkspaceAction, ShortcutRegistration>> & {
58
58
  middleClickClose?: boolean;
59
- addTab?: boolean | KeyBinding | readonly KeyBinding[];
60
- restoreClosedTab?: boolean | KeyBinding | readonly KeyBinding[];
61
- };
59
+ });
60
+ /** Customize presentation only; matching and accessibility encoding use the binding. */
61
+ formatShortcut?: (binding: Readonly<KeyBinding>) => string;
62
62
  getPaneState?: (paneId: string) => State;
63
63
  onError?: (error: unknown) => void;
64
64
  /** Copy additional app styles/assets into a same-origin companion document. */
@@ -66,8 +66,27 @@ export interface ResolvedLayoutOptions<State = unknown> {
66
66
  /** Override window creation for applications with a managed same-origin host. Must return synchronously. */
67
67
  openWindow?: (pane: Pane, placement: WindowPlacement) => Window | null;
68
68
  }
69
+ /** Internal renderer configuration; mounted workspaces create this model themselves. */
70
+ export interface ResolvedLayoutOptions<State = unknown> extends WorkspaceSettings<State> {
71
+ store: LayoutStore;
72
+ tabs?: TabRegistry;
73
+ renderers?: Record<string, PaneRenderer<State>>;
74
+ registry?: PaneRegistry<PaneRenderer<State>>;
75
+ }
76
+ /** Initial configuration is consumed once. Use workspace commands for later changes. */
77
+ export type InitialConfiguration = {
78
+ initialLayout?: Layout;
79
+ initialWorkspace?: never;
80
+ } | {
81
+ initialLayout?: never;
82
+ initialWorkspace: WorkspacePreset;
83
+ };
84
+ /** Commands and subscriptions for a workspace-owned store. */
85
+ export type WorkspaceStore = Omit<LayoutStore, 'dispose'>;
69
86
  /** Choose a unified registry OR the low-level renderer and creation maps. */
70
- export type LayoutOptions<State = unknown> = Omit<ResolvedLayoutOptions<State>, 'registry' | 'renderers' | 'tabs' | 'getPaneState'> & (unknown extends State ? {
87
+ export type LayoutOptions<State = unknown> = Omit<ResolvedLayoutOptions<State>, 'store' | 'registry' | 'renderers' | 'tabs' | 'getPaneState'> & InitialConfiguration & {
88
+ store?: never;
89
+ } & (unknown extends State ? {
71
90
  getPaneState?: (paneId: string) => State;
72
91
  } : {
73
92
  getPaneState: (paneId: string) => State;
@@ -84,6 +103,20 @@ export type LayoutOptions<State = unknown> = Omit<ResolvedLayoutOptions<State>,
84
103
  export type LayoutOptionUpdates<State = unknown> = {
85
104
  [Key in keyof Omit<ResolvedLayoutOptions<State>, 'store'>]?: ResolvedLayoutOptions<State>[Key] | undefined;
86
105
  };
106
+ export type WorkspaceAction = 'maximize' | 'addTab' | 'restoreClosedTab' | 'closeActiveTab' | 'closePane' | 'closeEmptyPane' | 'popout' | 'joinSiblingRegion' | 'splitLeft' | 'splitRight' | 'splitUp' | 'splitDown' | 'tabOrientationDefault' | 'tabOrientationHorizontal' | 'tabOrientationVertical' | 'tabDisplayDefault' | 'tabDisplayAutomatic' | 'tabDisplayCompact';
107
+ export interface ActionContext {
108
+ groupId?: string;
109
+ paneId?: string;
110
+ }
111
+ export type ShortcutRegistration = boolean | KeyBinding | readonly KeyBinding[] | {
112
+ bindings: true | KeyBinding | readonly KeyBinding[];
113
+ handling?: 'quilt' | 'external';
114
+ };
115
+ export interface RegisteredShortcut {
116
+ readonly action: WorkspaceAction;
117
+ readonly bindings: readonly Readonly<KeyBinding>[];
118
+ readonly handling: 'quilt' | 'external';
119
+ }
87
120
  export interface KeyBinding {
88
121
  key: string;
89
122
  ctrl?: boolean;
@@ -98,6 +131,10 @@ export interface CloseRequest {
98
131
  signal: AbortSignal;
99
132
  }
100
133
  export interface MountedLayout<State = unknown> {
134
+ readonly store: WorkspaceStore;
135
+ canExecuteAction(action: WorkspaceAction, context?: ActionContext): boolean;
136
+ executeAction(action: WorkspaceAction, context?: ActionContext): Promise<boolean>;
137
+ getShortcuts(): readonly RegisteredShortcut[];
101
138
  updateOptions(options: LayoutOptionUpdates<State>): void;
102
139
  exportWorkspace(): WorkspacePreset;
103
140
  loadWorkspace(input: unknown): void;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACrE,MAAM,WAAW,WAAW,CAAC,KAAK,GAAG,OAAO;IAC1C,OAAO,EAAE,WAAW,CAAC;IACrB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IACX,qFAAqF;IACrF,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC7B;AACD,MAAM,WAAW,QAAQ;IACvB,sFAAsF;IACtF,KAAK,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;CAC3B;AACD,MAAM,MAAM,YAAY,CAAC,KAAK,GAAG,OAAO,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC;AACtF,MAAM,WAAW,WAAW;IAC1B,uFAAuF;IACvF,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC3B,+EAA+E;IAC/E,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;IAC7D,4EAA4E;IAC5E,UAAU,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACrC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAC3C,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AACD,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACvC;AACD,MAAM,WAAW,qBAAqB,CAAC,KAAK,GAAG,OAAO;IACpD,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrE,gFAAgF;IAChF,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,OAAO,GAAG,SAAS,CAAC;IACtE,0DAA0D;IAC1D,SAAS,CAAC,EACN,OAAO,GACP;QACE,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,UAAU,EAAE,CAAC;QACxD,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,MAAM,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,UAAU,EAAE,CAAC;QACtD,gBAAgB,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,UAAU,EAAE,CAAC;KACjE,CAAC;IACN,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,KAAK,CAAC;IACzC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,+EAA+E;IAC/E,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACrD,4GAA4G;IAC5G,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,KAAK,MAAM,GAAG,IAAI,CAAC;CACxE;AACD,6EAA6E;AAC7E,MAAM,MAAM,aAAa,CAAC,KAAK,GAAG,OAAO,IAAI,IAAI,CAC/C,qBAAqB,CAAC,KAAK,CAAC,EAC5B,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,cAAc,CACnD,GACC,CAAC,OAAO,SAAS,KAAK,GAClB;IAAE,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,KAAK,CAAA;CAAE,GAC5C;IAAE,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,KAAK,CAAA;CAAE,CAAC,GAChD,CACI;IAAE,QAAQ,EAAE,YAAY,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,KAAK,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAA;CAAE,GAChF;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,CAAA;CAAE,CAChG,CAAC;AACJ,gFAAgF;AAChF,MAAM,MAAM,mBAAmB,CAAC,KAAK,GAAG,OAAO,IAAI;KAChD,GAAG,IAAI,MAAM,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EACzD,qBAAqB,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS;CAChD,CAAC;AACF,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AACD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IACvB,qBAAqB,EAAE,SAAS,IAAI,EAAE,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;CACrB;AACD,MAAM,WAAW,aAAa,CAAC,KAAK,GAAG,OAAO;IAC5C,aAAa,CAAC,OAAO,EAAE,mBAAmB,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IACzD,eAAe,IAAI,eAAe,CAAC;IACnC,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACpC,YAAY,IAAI,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpE,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtE,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,OAAO,IAAI,IAAI,CAAC;CACjB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { PaneRegistry } from './registry.js';\nimport type { WorkspacePreset } from './workspace.js';\nimport type { Messages } from './messages.js';\nimport type { TabRegistry } from './registry.js';\nimport type { LayoutTheme } from './theme.js';\nimport type { LayoutStore, Pane, WindowPlacement } from 'quilt-core';\nexport interface PaneContext<State = unknown> {\n element: HTMLElement;\n reportError(error: unknown): void;\n document: Document;\n window: Window;\n pane: Pane;\n /** Stable application-owned reference. The library does not serialize this value. */\n state: State;\n location: 'main' | 'popout';\n}\nexport interface PaneView {\n /** Resolves once destination content has committed; rejection rolls back a popout. */\n ready?: Promise<void>;\n dispose(): void;\n resize?(width: number, height: number): void;\n update?(pane: Pane): void;\n}\nexport type PaneRenderer<State = unknown> = (context: PaneContext<State>) => PaneView;\nexport interface TabBarStyle {\n /** Left placement uses an icon-only rail; mode and shape apply in either placement. */\n placement?: 'top' | 'left';\n /** Automatic shows labels as width permits; compact always uses icons only. */\n display?: 'automatic' | 'compact';\n mode?: 'full' | 'tapered';\n shape?: 'angle' | 'round' | 'scoop' | 'vertical' | 'rounded';\n /** Anchored by default; floating bars overlay content with an 8px inset. */\n attachment?: 'anchored' | 'floating';\n fit?: 'full' | 'fit';\n corners?: 'fitted' | 'rounded' | 'capsule';\n /** Positive finite CSS pixels. Omit to match header height. */\n taperWidth?: number;\n}\nexport interface TabBarOptions extends TabBarStyle {\n /** Partial overrides keyed by stable group ID; not serialized in Layout JSON. */\n regions?: Record<string, TabBarStyle>;\n}\nexport interface ResolvedLayoutOptions<State = unknown> {\n tabBar?: TabBarOptions;\n store: LayoutStore;\n tabs?: TabRegistry;\n theme?: LayoutTheme;\n renderers?: Record<string, PaneRenderer<State>>;\n registry?: PaneRegistry<PaneRenderer<State>>;\n messages?: Messages;\n popouts?: boolean;\n confirmClose?: (request: CloseRequest) => boolean | Promise<boolean>;\n /** Return a fresh decorative icon element. Unknown keys use a title initial. */\n renderIcon?: (key: string, document: Document) => Element | undefined;\n /** Opt-in conveniences; omitted and false disable all. */\n shortcuts?:\n | boolean\n | {\n maximize?: boolean | KeyBinding | readonly KeyBinding[];\n middleClickClose?: boolean;\n addTab?: boolean | KeyBinding | readonly KeyBinding[];\n restoreClosedTab?: boolean | KeyBinding | readonly KeyBinding[];\n };\n getPaneState?: (paneId: string) => State;\n onError?: (error: unknown) => void;\n /** Copy additional app styles/assets into a same-origin companion document. */\n prepareWindow?: (window: Window, pane: Pane) => void;\n /** Override window creation for applications with a managed same-origin host. Must return synchronously. */\n openWindow?: (pane: Pane, placement: WindowPlacement) => Window | null;\n}\n/** Choose a unified registry OR the low-level renderer and creation maps. */\nexport type LayoutOptions<State = unknown> = Omit<\n ResolvedLayoutOptions<State>,\n 'registry' | 'renderers' | 'tabs' | 'getPaneState'\n> &\n (unknown extends State\n ? { getPaneState?: (paneId: string) => State }\n : { getPaneState: (paneId: string) => State }) &\n (\n | { registry: PaneRegistry<PaneRenderer<State>>; renderers?: never; tabs?: never }\n | { registry?: undefined; renderers?: Record<string, PaneRenderer<State>>; tabs?: TabRegistry }\n );\n/** Omitted keys retain their value; explicit undefined restores the default. */\nexport type LayoutOptionUpdates<State = unknown> = {\n [Key in keyof Omit<ResolvedLayoutOptions<State>, 'store'>]?:\n ResolvedLayoutOptions<State>[Key] | undefined;\n};\nexport interface KeyBinding {\n key: string;\n ctrl?: boolean;\n alt?: boolean;\n shift?: boolean;\n meta?: boolean;\n}\nexport interface CloseRequest {\n panes: readonly Pane[];\n requiringConfirmation: readonly Pane[];\n groupId?: string;\n signal: AbortSignal;\n}\nexport interface MountedLayout<State = unknown> {\n updateOptions(options: LayoutOptionUpdates<State>): void;\n exportWorkspace(): WorkspacePreset;\n loadWorkspace(input: unknown): void;\n refreshTheme(): void;\n retryPane(id: string): void;\n requestClose(id: string, kind?: 'pane' | 'group'): Promise<boolean>;\n setTabBar(options: TabBarOptions): void;\n setTheme(theme: LayoutTheme): void;\n popout(paneId: string, placement?: WindowPlacement): Promise<boolean>;\n returnPane(paneId: string): void;\n dispose(): void;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { PaneRegistry } from './registry.js';\nimport type { WorkspacePreset } from './workspace.js';\nimport type { Messages } from './messages.js';\nimport type { TabRegistry } from './registry.js';\nimport type { LayoutTheme } from './theme.js';\nimport type { LayoutStore, Layout, Pane, WindowPlacement } from 'quilt-core';\nexport interface PaneContext<State = unknown> {\n element: HTMLElement;\n /** Aborted when this view is torn down, including a failed mount. */\n signal: AbortSignal;\n /** Register view-owned cleanup; callbacks run once in reverse order. */\n onCleanup(callback: () => void): void;\n reportError(error: unknown): void;\n document: Document;\n window: Window;\n pane: Pane;\n /** Stable application-owned reference. The library does not serialize this value. */\n state: State;\n location: 'main' | 'popout';\n}\nexport interface PaneView {\n /** Resolves once destination content has committed; rejection rolls back a popout. */\n ready?: Promise<void>;\n dispose(): void;\n resize?(width: number, height: number): void;\n update?(pane: Pane): void;\n}\nexport type PaneRenderer<State = unknown> = (context: PaneContext<State>) => PaneView | void;\nexport interface TabBarStyle {\n /** Left placement uses an icon-only rail; mode and shape apply in either placement. */\n placement?: 'top' | 'left';\n /** Automatic shows labels as width permits; compact always uses icons only. */\n display?: 'automatic' | 'compact';\n mode?: 'full' | 'tapered';\n shape?: 'angle' | 'round' | 'scoop' | 'vertical' | 'rounded';\n /** Anchored by default; floating bars overlay content with an 8px inset. */\n attachment?: 'anchored' | 'floating';\n fit?: 'full' | 'fit';\n corners?: 'fitted' | 'rounded' | 'capsule';\n /** Positive finite CSS pixels. Omit to match header height. */\n taperWidth?: number;\n}\nexport interface TabBarOptions extends TabBarStyle {\n /** Partial overrides keyed by stable group ID; not serialized in Layout JSON. */\n regions?: Record<string, TabBarStyle>;\n}\n/** Live appearance, interactions, and application integration callbacks. */\nexport interface WorkspaceSettings<State = unknown> {\n tabBar?: TabBarOptions;\n theme?: LayoutTheme;\n messages?: Messages;\n popouts?: boolean;\n confirmClose?: (request: CloseRequest) => boolean | Promise<boolean>;\n /** Return a fresh decorative icon element. Unknown keys use a title initial. */\n renderIcon?: (key: string, document: Document) => Element | undefined;\n /** Opt-in conveniences; omitted and false disable all. */\n shortcuts?:\n | boolean\n | (Partial<Record<WorkspaceAction, ShortcutRegistration>> & {\n middleClickClose?: boolean;\n });\n /** Customize presentation only; matching and accessibility encoding use the binding. */\n formatShortcut?: (binding: Readonly<KeyBinding>) => string;\n getPaneState?: (paneId: string) => State;\n onError?: (error: unknown) => void;\n /** Copy additional app styles/assets into a same-origin companion document. */\n prepareWindow?: (window: Window, pane: Pane) => void;\n /** Override window creation for applications with a managed same-origin host. Must return synchronously. */\n openWindow?: (pane: Pane, placement: WindowPlacement) => Window | null;\n}\n/** Internal renderer configuration; mounted workspaces create this model themselves. */\nexport interface ResolvedLayoutOptions<State = unknown> extends WorkspaceSettings<State> {\n store: LayoutStore;\n tabs?: TabRegistry;\n renderers?: Record<string, PaneRenderer<State>>;\n registry?: PaneRegistry<PaneRenderer<State>>;\n}\n/** Initial configuration is consumed once. Use workspace commands for later changes. */\nexport type InitialConfiguration =\n | { initialLayout?: Layout; initialWorkspace?: never }\n | { initialLayout?: never; initialWorkspace: WorkspacePreset };\n/** Commands and subscriptions for a workspace-owned store. */\nexport type WorkspaceStore = Omit<LayoutStore, 'dispose'>;\n/** Choose a unified registry OR the low-level renderer and creation maps. */\nexport type LayoutOptions<State = unknown> = Omit<\n ResolvedLayoutOptions<State>,\n 'store' | 'registry' | 'renderers' | 'tabs' | 'getPaneState'\n> &\n InitialConfiguration & { store?: never } & (unknown extends State\n ? { getPaneState?: (paneId: string) => State }\n : { getPaneState: (paneId: string) => State }) &\n (\n | { registry: PaneRegistry<PaneRenderer<State>>; renderers?: never; tabs?: never }\n | { registry?: undefined; renderers?: Record<string, PaneRenderer<State>>; tabs?: TabRegistry }\n );\n/** Omitted keys retain their value; explicit undefined restores the default. */\nexport type LayoutOptionUpdates<State = unknown> = {\n [Key in keyof Omit<ResolvedLayoutOptions<State>, 'store'>]?:\n ResolvedLayoutOptions<State>[Key] | undefined;\n};\nexport type WorkspaceAction =\n | 'maximize'\n | 'addTab'\n | 'restoreClosedTab'\n | 'closeActiveTab'\n | 'closePane'\n | 'closeEmptyPane'\n | 'popout'\n | 'joinSiblingRegion'\n | 'splitLeft'\n | 'splitRight'\n | 'splitUp'\n | 'splitDown'\n | 'tabOrientationDefault'\n | 'tabOrientationHorizontal'\n | 'tabOrientationVertical'\n | 'tabDisplayDefault'\n | 'tabDisplayAutomatic'\n | 'tabDisplayCompact';\nexport interface ActionContext {\n groupId?: string;\n paneId?: string;\n}\nexport type ShortcutRegistration =\n | boolean\n | KeyBinding\n | readonly KeyBinding[]\n | {\n bindings: true | KeyBinding | readonly KeyBinding[];\n handling?: 'quilt' | 'external';\n };\nexport interface RegisteredShortcut {\n readonly action: WorkspaceAction;\n readonly bindings: readonly Readonly<KeyBinding>[];\n readonly handling: 'quilt' | 'external';\n}\nexport interface KeyBinding {\n key: string;\n ctrl?: boolean;\n alt?: boolean;\n shift?: boolean;\n meta?: boolean;\n}\nexport interface CloseRequest {\n panes: readonly Pane[];\n requiringConfirmation: readonly Pane[];\n groupId?: string;\n signal: AbortSignal;\n}\nexport interface MountedLayout<State = unknown> {\n readonly store: WorkspaceStore;\n canExecuteAction(action: WorkspaceAction, context?: ActionContext): boolean;\n executeAction(action: WorkspaceAction, context?: ActionContext): Promise<boolean>;\n getShortcuts(): readonly RegisteredShortcut[];\n updateOptions(options: LayoutOptionUpdates<State>): void;\n exportWorkspace(): WorkspacePreset;\n loadWorkspace(input: unknown): void;\n refreshTheme(): void;\n retryPane(id: string): void;\n requestClose(id: string, kind?: 'pane' | 'group'): Promise<boolean>;\n setTabBar(options: TabBarOptions): void;\n setTheme(theme: LayoutTheme): void;\n popout(paneId: string, placement?: WindowPlacement): Promise<boolean>;\n returnPane(paneId: string): void;\n dispose(): void;\n}\n"]}