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.
- package/README.md +35 -39
- package/dist/actions.d.ts +14 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +115 -0
- package/dist/actions.js.map +1 -0
- package/dist/chrome-size.d.ts +7 -0
- package/dist/chrome-size.d.ts.map +1 -0
- package/dist/chrome-size.js +86 -0
- package/dist/chrome-size.js.map +1 -0
- package/dist/close.d.ts.map +1 -1
- package/dist/close.js +3 -1
- package/dist/close.js.map +1 -1
- package/dist/corners.d.ts +2 -1
- package/dist/corners.d.ts.map +1 -1
- package/dist/corners.js +2 -2
- package/dist/corners.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/menu.d.ts +9 -3
- package/dist/menu.d.ts.map +1 -1
- package/dist/menu.js +110 -37
- package/dist/menu.js.map +1 -1
- package/dist/panes.d.ts.map +1 -1
- package/dist/panes.js +84 -52
- package/dist/panes.js.map +1 -1
- package/dist/registry.d.ts +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +4 -3
- package/dist/registry.js.map +1 -1
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +128 -36
- package/dist/renderer.js.map +1 -1
- package/dist/resize.d.ts +2 -1
- package/dist/resize.d.ts.map +1 -1
- package/dist/resize.js +2 -2
- package/dist/resize.js.map +1 -1
- package/dist/shortcut-registration.d.ts +9 -0
- package/dist/shortcut-registration.d.ts.map +1 -0
- package/dist/shortcut-registration.js +95 -0
- package/dist/shortcut-registration.js.map +1 -0
- package/dist/shortcuts.d.ts +7 -6
- package/dist/shortcuts.d.ts.map +1 -1
- package/dist/shortcuts.js +28 -50
- package/dist/shortcuts.js.map +1 -1
- package/dist/styles.css +74 -9
- package/dist/tabs.d.ts.map +1 -1
- package/dist/tabs.js +10 -12
- package/dist/tabs.js.map +1 -1
- package/dist/types.d.ts +50 -13
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/workspace-api.d.ts +186 -0
- package/dist/workspace-api.d.ts.map +1 -0
- package/dist/workspace-api.js +409 -0
- package/dist/workspace-api.js.map +1 -0
- package/package.json +2 -2
- package/src/actions.ts +125 -0
- package/src/chrome-size.ts +99 -0
- package/src/close.ts +6 -1
- package/src/corners.ts +2 -1
- package/src/index.ts +31 -4
- package/src/menu.ts +123 -43
- package/src/panes.ts +82 -55
- package/src/registry.ts +6 -4
- package/src/renderer.ts +181 -54
- package/src/resize.ts +2 -1
- package/src/shortcut-registration.ts +106 -0
- package/src/shortcuts.ts +38 -63
- package/src/styles.css +74 -9
- package/src/tabs.ts +9 -11
- package/src/types.ts +67 -14
- package/src/workspace-api.ts +583 -0
package/dist/shortcuts.js
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import {
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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
|
|
38
|
-
e.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
76
|
-
|
|
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
|
package/dist/shortcuts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shortcuts.js","sourceRoot":"","sources":["../src/shortcuts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shortcuts.js","sourceRoot":"","sources":["../src/shortcuts.ts"],"names":[],"mappings":"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","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
|
+
}
|
package/dist/tabs.d.ts.map
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAWjD,oFAAoF;AACpF,MAAM,UAAU,QAAQ,CAAC,IAAiB,EAAE,KAAY,EAAE,KAAa,EAAE,IAAqB;IAC5F,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC;IAC/B,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,MAAM,CAAC;QACxC,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;QAC7C,GAAG,CAAC,IAAI,GAAG,QAAQ,CAAC;QACpB,GAAG,CAAC,YAAY,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAChC,GAAG,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,GAAG,CAAC,OAAO,CAAC,OAAO,GAAG,OAAO,IAAI,CAAC,EAAE,EAAE,CAAC;QACvC,GAAG,CAAC,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,CAAC,EAAE,EAAE,CAAC;QACpC,GAAG,CAAC,YAAY,CAAC,eAAe,EAAE,GAAG,MAAM,UAAU,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAChE,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC;QACjD,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACzC,IAAI,QAA6B,CAAC;QAClC,GAAG,CAAC,GAAG,EAAE;YACP,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1E,CAAC,CAAC,CAAC;QACH,IAAI,QAAQ;YAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;;YAC/B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;QAChE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,mBAAmB,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACnE,GAAG,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACzE,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACnD,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,EAAE;YACtB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACtB,CAAC,CAAC,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YAC/C,IAAI,CAAC,CAAC,YAAY;gBAAE,CAAC,CAAC,YAAY,CAAC,aAAa,GAAG,MAAM,CAAC;QAC5D,CAAC,CAAC;QACF,GAAG,CAAC,SAAS,GAAG,GAAG,EAAE;YACnB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACxB,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,CAAC,CAAC;QACF,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,KAAK,UAAU,CAAC;QAC5E,MAAM,KAAK,GAAG,CAAC,CAAY,EAAE,EAAE;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC1C,OAAO,QAAQ,EAAE;gBACf,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;gBACxC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QAC7C,CAAC,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,EAAE,EAAE;YACtB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC1B,IACE,CAAC,EAAE;gBACH,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC;gBAC9B,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;gBAEvD,OAAO;YACT,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,CAAC,CAAC,eAAe,EAAE,CAAC;YACpB,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;QACvD,CAAC,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,GAAG,EAAE;YACtB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QAC9B,CAAC,CAAC;QACF,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE;YAClB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC1B,IAAI,CAAC,EAAE;gBAAE,OAAO;YAChB,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,CAAC,CAAC,eAAe,EAAE,CAAC;YACpB,IAAI,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACvC,2EAA2E;YAC3E,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,GAAG,KAAK;gBAAE,KAAK,EAAE,CAAC;YAC3C,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACxB,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAChF,CAAC,CAAC;QACF,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,EAAE;YACpB,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;gBAAE,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;iBACnF,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;gBACvD,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;iBAC3C,IAAI,CAAC,CAAC,GAAG,KAAK,MAAM;gBAAE,KAAK,GAAG,CAAC,CAAC;iBAChC,IAAI,CAAC,CAAC,GAAG,KAAK,KAAK;gBAAE,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;;gBAC9C,OAAO;YACZ,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9D,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,GAAG,EAAE,CACjB,GAAG,CAAC,GAAG,EAAE;YACP,KAAK,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChC,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC,CAAC,CAAC;QACL,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjB,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC;YACxC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,kCAAkC,CAAC,CAAC;YAChE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;YACnC,CAAC,CAAC,IAAI,GAAG,QAAQ,CAAC;YAClB,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACnE,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC,CAAC,OAAO,CAAC,OAAO,GAAG,SAAS,IAAI,CAAC,EAAE,EAAE,CAAC;YACvC,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACf,IAAI,eAAe,CAAC,OAAO,EAAE,kBAAkB,CAAC,EAAE,CAAC;gBACjD,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,EAAE;oBACvB,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;wBAAE,CAAC,CAAC,cAAc,EAAE,CAAC;gBACzC,CAAC,CAAC;gBACF,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,EAAE,EAAE;oBACtB,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACnB,CAAC,CAAC,cAAc,EAAE,CAAC;wBACnB,KAAK,EAAE,CAAC;oBACV,CAAC;gBACH,CAAC,CAAC;YACJ,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;AACL,CAAC","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
|
-
|
|
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
|
-
|
|
60
|
-
|
|
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'> &
|
|
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;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
|
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"]}
|