@workbench-kit/shell-react 0.0.2-prototype.0.2.40 → 0.0.2-prototype.0.2.43
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 +42 -2
- package/package.json +13 -10
- package/src/extensions/extension-enablement-controller.ts +40 -9
- package/src/extensions/theme-selection-protection.ts +80 -55
- package/src/field-remap/chrome-labels.ts +18 -0
- package/src/field-remap/convert-note-editor.tsx +30 -24
- package/src/field-remap/convert-palette.tsx +6 -0
- package/src/field-remap/demo.tsx +8 -2
- package/src/field-remap/detail-panel.tsx +225 -192
- package/src/field-remap/drag-payload.ts +48 -0
- package/src/field-remap/flow-adapter.ts +216 -88
- package/src/field-remap/flow-ops.ts +150 -0
- package/src/field-remap/flow.tsx +1055 -162
- package/src/field-remap/index.ts +2 -0
- package/src/field-remap/io-class-browse.tsx +34 -22
- package/src/field-remap/keyboard.ts +16 -0
- package/src/field-remap/modal-detail.tsx +34 -0
- package/src/field-remap/panel.tsx +50 -14
- package/src/field-remap/transform-options-editor.tsx +5 -1
- package/src/field-remap/view.css +61 -42
- package/src/index.ts +7 -0
- package/src/management/keybinding-overrides-storage.ts +48 -23
- package/src/management/keybinding-settings.tsx +10 -1
- package/src/management/use-keybinding-management.ts +69 -19
- package/src/shell/appearance-catalog.ts +453 -0
- package/src/shell/appearance-controller.ts +331 -0
- package/src/shell/appearance-presentation.ts +269 -0
- package/src/shell/provider.tsx +147 -18
- package/src/shell/settings.tsx +282 -153
- package/src/shell/shell.tsx +88 -18
- package/src/workbench/appearance-storage.ts +2 -2
- package/src/workbench/command-host-controller.tsx +223 -0
- package/src/workbench/command-host.tsx +100 -150
- package/src/workbench/keybinding-bridge.ts +84 -38
- package/src/workbench/shell-command-registration.ts +27 -2
package/src/field-remap/index.ts
CHANGED
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
type SourceField,
|
|
6
6
|
type TargetSlot,
|
|
7
7
|
} from '@workbench-kit/field-remap';
|
|
8
|
+
import { SideBarRow } from '@workbench-kit/react/layout';
|
|
9
|
+
import { Badge } from '@workbench-kit/react/primitives';
|
|
8
10
|
|
|
9
11
|
export type FieldRemapIoChrome = 'browse' | 'edit' | 'none';
|
|
10
12
|
|
|
@@ -56,25 +58,30 @@ function FieldTree({
|
|
|
56
58
|
<ul className="workbench-field-remap-io-browse__fields">
|
|
57
59
|
{nodes.map((node) => (
|
|
58
60
|
<li key={node.id}>
|
|
59
|
-
<
|
|
61
|
+
<SideBarRow className="workbench-field-remap-io-browse__row" data-static="true">
|
|
60
62
|
<code className="workbench-field-remap-io-browse__path">{node.path ?? node.label}</code>
|
|
61
63
|
<span className="workbench-field-remap-io-browse__meta">
|
|
62
64
|
{node.dataType ? <span>{node.dataType}</span> : null}
|
|
63
65
|
{node.classRef ? (
|
|
64
|
-
<
|
|
66
|
+
<Badge
|
|
65
67
|
className="workbench-field-remap-io-browse__badge"
|
|
66
68
|
title={labels?.classRefTitle ?? 'classRef'}
|
|
69
|
+
variant="muted"
|
|
67
70
|
>
|
|
68
71
|
{formatClassRef(node.classRef)}
|
|
69
|
-
</
|
|
72
|
+
</Badge>
|
|
70
73
|
) : null}
|
|
71
74
|
{node.hidden === true ? (
|
|
72
|
-
<
|
|
75
|
+
<Badge
|
|
76
|
+
className="workbench-field-remap-io-browse__badge"
|
|
77
|
+
title="hidden"
|
|
78
|
+
variant="muted"
|
|
79
|
+
>
|
|
73
80
|
{labels?.hiddenBadge ?? 'Hidden'}
|
|
74
|
-
</
|
|
81
|
+
</Badge>
|
|
75
82
|
) : null}
|
|
76
83
|
</span>
|
|
77
|
-
</
|
|
84
|
+
</SideBarRow>
|
|
78
85
|
{node.children?.length ? (
|
|
79
86
|
<FieldTree emptyLabel={emptyLabel} labels={labels} nodes={node.children} />
|
|
80
87
|
) : null}
|
|
@@ -101,22 +108,27 @@ function PortSection({
|
|
|
101
108
|
{nodes.length === 0 ? (
|
|
102
109
|
<p className="workbench-field-remap-io-browse__empty">{emptyLabel}</p>
|
|
103
110
|
) : (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
<
|
|
107
|
-
<
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
111
|
+
<ul className="workbench-field-remap-io-browse__ports">
|
|
112
|
+
{nodes.map((node) => (
|
|
113
|
+
<li className="workbench-field-remap-io-browse__port" key={node.id}>
|
|
114
|
+
<SideBarRow
|
|
115
|
+
className="workbench-field-remap-io-browse__port-title"
|
|
116
|
+
data-static="true"
|
|
117
|
+
>
|
|
118
|
+
<span className="workbench-field-remap-io-browse__port-id">{node.label}</span>
|
|
119
|
+
<span className="workbench-field-remap-io-browse__port-meta">
|
|
120
|
+
{node.classRef ? formatClassRef(node.classRef) : node.id}
|
|
121
|
+
{node.hidden === true ? ` · ${labels?.hiddenBadge ?? 'Hidden'}` : ''}
|
|
122
|
+
</span>
|
|
123
|
+
</SideBarRow>
|
|
124
|
+
<FieldTree
|
|
125
|
+
emptyLabel={emptyLabel}
|
|
126
|
+
labels={labels}
|
|
127
|
+
nodes={node.children?.length ? node.children : [node]}
|
|
128
|
+
/>
|
|
129
|
+
</li>
|
|
130
|
+
))}
|
|
131
|
+
</ul>
|
|
120
132
|
)}
|
|
121
133
|
</section>
|
|
122
134
|
);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const EDITABLE_SHORTCUT_TARGET = [
|
|
2
|
+
'input',
|
|
3
|
+
'textarea',
|
|
4
|
+
'select',
|
|
5
|
+
'[contenteditable]:not([contenteditable="false"])',
|
|
6
|
+
'[role="textbox"]',
|
|
7
|
+
'[data-field-remap-shortcuts="ignore"]',
|
|
8
|
+
].join(', ');
|
|
9
|
+
|
|
10
|
+
export function isFieldRemapEditableShortcutTarget(target: EventTarget | null): boolean {
|
|
11
|
+
return (
|
|
12
|
+
typeof Element !== 'undefined' &&
|
|
13
|
+
target instanceof Element &&
|
|
14
|
+
target.closest(EDITABLE_SHORTCUT_TARGET) !== null
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { JSX, ReactNode } from 'react';
|
|
2
|
+
import { Modal } from '@workbench-kit/react/modal';
|
|
3
|
+
import { WorkbenchModalPortal } from '@workbench-kit/react/workbench/modal-portal';
|
|
4
|
+
|
|
5
|
+
export interface FieldRemapModalDetailProps {
|
|
6
|
+
readonly children: ReactNode;
|
|
7
|
+
readonly closeLabel: string;
|
|
8
|
+
readonly onClose: () => void;
|
|
9
|
+
readonly title: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function FieldRemapModalDetail({
|
|
13
|
+
children,
|
|
14
|
+
closeLabel,
|
|
15
|
+
onClose,
|
|
16
|
+
title,
|
|
17
|
+
}: FieldRemapModalDetailProps): JSX.Element {
|
|
18
|
+
return (
|
|
19
|
+
<WorkbenchModalPortal>
|
|
20
|
+
<Modal
|
|
21
|
+
bodyClassName="workbench-field-remap-detail-modal__body"
|
|
22
|
+
bodyPadding="none"
|
|
23
|
+
bodyScroll="auto"
|
|
24
|
+
className="workbench-field-remap-detail-modal"
|
|
25
|
+
closeLabel={closeLabel}
|
|
26
|
+
closeOnEscape={false}
|
|
27
|
+
title={title}
|
|
28
|
+
onClose={onClose}
|
|
29
|
+
>
|
|
30
|
+
{children}
|
|
31
|
+
</Modal>
|
|
32
|
+
</WorkbenchModalPortal>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
useRef,
|
|
6
6
|
useState,
|
|
7
7
|
type JSX,
|
|
8
|
+
type KeyboardEvent,
|
|
8
9
|
type Ref,
|
|
9
10
|
} from 'react';
|
|
10
11
|
import {
|
|
@@ -50,6 +51,7 @@ import {
|
|
|
50
51
|
} from './shape-io-editor.js';
|
|
51
52
|
import { createFieldRemapPreviewController } from './preview-controller.js';
|
|
52
53
|
import type { FieldRemapPreviewState } from './preview.js';
|
|
54
|
+
import { isFieldRemapEditableShortcutTarget } from './keyboard.js';
|
|
53
55
|
import './view.css';
|
|
54
56
|
|
|
55
57
|
export type { FieldRemapHistorySnapshot } from './history.js';
|
|
@@ -80,6 +82,8 @@ export interface FieldRemapPanelProps {
|
|
|
80
82
|
readonly sample?: FieldRemapSampleId | FieldRemapSampleDefinition | undefined;
|
|
81
83
|
/** Optional host-owned transform registry (defaults to builtins + JSONata). */
|
|
82
84
|
readonly transforms?: ValueTransformRegistry | undefined;
|
|
85
|
+
/** View-only authoring guard forwarded to Flow; this is not an authorization boundary. */
|
|
86
|
+
readonly readOnly?: boolean | undefined;
|
|
83
87
|
/**
|
|
84
88
|
* When true (default), show paste-JSON / type editors for host-owned shapes.
|
|
85
89
|
* Prefer {@link FieldRemapPanelProps.ioChrome} for browse-first hosts; when
|
|
@@ -112,7 +116,7 @@ export interface FieldRemapPanelProps {
|
|
|
112
116
|
* channel is controlled, the Panel never creates a partial private history.
|
|
113
117
|
*/
|
|
114
118
|
readonly historyOwner?: FieldRemapHistoryOwner | undefined;
|
|
115
|
-
/** Imperative semantic undo/redo actions for host chrome.
|
|
119
|
+
/** Imperative semantic undo/redo actions for host chrome. */
|
|
116
120
|
readonly historyActionsRef?: Ref<FieldRemapHistoryActions | null> | undefined;
|
|
117
121
|
/** Reports the active history owner's current undo/redo availability. */
|
|
118
122
|
readonly onHistoryAvailabilityChange?:
|
|
@@ -136,6 +140,7 @@ export interface FieldRemapPanelProps {
|
|
|
136
140
|
readonly showBindingsList?: FieldRemapFlowMapperProps['showBindingsList'];
|
|
137
141
|
readonly showConvertPalette?: FieldRemapFlowMapperProps['showConvertPalette'];
|
|
138
142
|
readonly emptyDetail?: FieldRemapFlowMapperProps['emptyDetail'];
|
|
143
|
+
readonly detailPresentation?: FieldRemapFlowMapperProps['detailPresentation'];
|
|
139
144
|
/** Show the controller-owned preview snapshot in the nested Flow rail. */
|
|
140
145
|
readonly showFlowPreview?: boolean;
|
|
141
146
|
/** Forwarded to {@link FieldRemapFlowMapper} Controls MiniMap toggle. */
|
|
@@ -249,6 +254,7 @@ function createFieldRemapPreviewSignature(): (value: unknown) => string {
|
|
|
249
254
|
export function FieldRemapPanel({
|
|
250
255
|
sample: sampleProp,
|
|
251
256
|
transforms: transformsProp,
|
|
257
|
+
readOnly = false,
|
|
252
258
|
editableShapes = true,
|
|
253
259
|
ioChrome: ioChromeProp,
|
|
254
260
|
includeHidden: includeHiddenProp,
|
|
@@ -273,6 +279,7 @@ export function FieldRemapPanel({
|
|
|
273
279
|
showBindingsList,
|
|
274
280
|
showConvertPalette,
|
|
275
281
|
emptyDetail,
|
|
282
|
+
detailPresentation,
|
|
276
283
|
showFlowPreview,
|
|
277
284
|
onShowMinimapChange,
|
|
278
285
|
onPaneContextMenu,
|
|
@@ -282,7 +289,8 @@ export function FieldRemapPanel({
|
|
|
282
289
|
labels,
|
|
283
290
|
t,
|
|
284
291
|
}: FieldRemapPanelProps): JSX.Element {
|
|
285
|
-
const
|
|
292
|
+
const configuredIoChrome = resolveFieldRemapIoChrome(ioChromeProp, editableShapes);
|
|
293
|
+
const ioChrome = readOnly && configuredIoChrome === 'edit' ? 'browse' : configuredIoChrome;
|
|
286
294
|
const [uncontrolledIncludeHidden, setUncontrolledIncludeHidden] = useState(false);
|
|
287
295
|
const includeHiddenControlled = includeHiddenProp !== undefined;
|
|
288
296
|
const includeHidden = includeHiddenControlled ? includeHiddenProp : uncontrolledIncludeHidden;
|
|
@@ -503,6 +511,41 @@ export function FieldRemapPanel({
|
|
|
503
511
|
: (historyOwner?.canRedo ?? false),
|
|
504
512
|
};
|
|
505
513
|
|
|
514
|
+
const handleHistoryKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {
|
|
515
|
+
if (readOnly) {
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
if (
|
|
519
|
+
event.defaultPrevented ||
|
|
520
|
+
event.altKey ||
|
|
521
|
+
(!event.ctrlKey && !event.metaKey) ||
|
|
522
|
+
isFieldRemapEditableShortcutTarget(event.target)
|
|
523
|
+
) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const key = event.key.toLowerCase();
|
|
528
|
+
const requestsUndo = key === 'z' && !event.shiftKey;
|
|
529
|
+
const requestsRedo =
|
|
530
|
+
(key === 'z' && event.shiftKey) ||
|
|
531
|
+
(key === 'y' && event.ctrlKey && !event.metaKey && !event.shiftKey);
|
|
532
|
+
if (
|
|
533
|
+
(!requestsUndo && !requestsRedo) ||
|
|
534
|
+
(requestsUndo && !historyAvailability.canUndo) ||
|
|
535
|
+
(requestsRedo && !historyAvailability.canRedo)
|
|
536
|
+
) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
event.preventDefault();
|
|
541
|
+
event.stopPropagation();
|
|
542
|
+
if (requestsUndo) {
|
|
543
|
+
undo();
|
|
544
|
+
} else {
|
|
545
|
+
redo();
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
|
|
506
549
|
useImperativeHandle(historyActionsRef, () => ({ ...historyAvailability, undo, redo }), [
|
|
507
550
|
historyAvailability.canRedo,
|
|
508
551
|
historyAvailability.canUndo,
|
|
@@ -644,6 +687,8 @@ export function FieldRemapPanel({
|
|
|
644
687
|
data-testid="field-remap-demo"
|
|
645
688
|
data-sample-id={sample.id}
|
|
646
689
|
data-edges-mode={edgesControlled ? 'controlled' : 'uncontrolled'}
|
|
690
|
+
data-read-only={readOnly ? 'true' : 'false'}
|
|
691
|
+
onKeyDown={handleHistoryKeyDown}
|
|
647
692
|
>
|
|
648
693
|
<header className="workbench-field-remap-demo__header">
|
|
649
694
|
<h2 className="workbench-field-remap-demo__title">{sample.title}</h2>
|
|
@@ -691,9 +736,11 @@ export function FieldRemapPanel({
|
|
|
691
736
|
) : null}
|
|
692
737
|
|
|
693
738
|
<FieldRemapFlowMapper
|
|
739
|
+
readOnly={readOnly}
|
|
694
740
|
sources={flowSources}
|
|
695
741
|
targets={flowTargets}
|
|
696
742
|
edges={flowEdges}
|
|
743
|
+
parentChildConflicts={conflicts}
|
|
697
744
|
transforms={registry}
|
|
698
745
|
onEdgesChange={commitFlowEdges}
|
|
699
746
|
operators={operators}
|
|
@@ -708,6 +755,7 @@ export function FieldRemapPanel({
|
|
|
708
755
|
showBindingsList={showBindingsList}
|
|
709
756
|
showConvertPalette={showConvertPalette}
|
|
710
757
|
emptyDetail={emptyDetail}
|
|
758
|
+
detailPresentation={detailPresentation}
|
|
711
759
|
{...(showFlowPreview ? { preview, showPreview: true } : {})}
|
|
712
760
|
onShowMinimapChange={onShowMinimapChange}
|
|
713
761
|
includeHidden={includeHidden}
|
|
@@ -720,18 +768,6 @@ export function FieldRemapPanel({
|
|
|
720
768
|
t={t}
|
|
721
769
|
/>
|
|
722
770
|
|
|
723
|
-
{conflicts.length > 0 ? (
|
|
724
|
-
<p
|
|
725
|
-
className="workbench-field-remap-demo__warn"
|
|
726
|
-
role="status"
|
|
727
|
-
data-testid="field-remap-conflicts"
|
|
728
|
-
>
|
|
729
|
-
Warning: parent and child fields are both mapped (
|
|
730
|
-
{conflicts.map((item) => `${item.parentId} / ${item.childId}`).join('; ')}). Prefer one
|
|
731
|
-
level.
|
|
732
|
-
</p>
|
|
733
|
-
) : null}
|
|
734
|
-
|
|
735
771
|
{preview.status === 'error' ? (
|
|
736
772
|
<p className="workbench-field-remap-demo__error" role="alert">
|
|
737
773
|
{preview.message}
|
|
@@ -225,7 +225,11 @@ export function TransformOptionsEditor({
|
|
|
225
225
|
};
|
|
226
226
|
|
|
227
227
|
return (
|
|
228
|
-
<div
|
|
228
|
+
<div
|
|
229
|
+
className="workbench-field-remap-options"
|
|
230
|
+
data-field-remap-shortcuts="ignore"
|
|
231
|
+
data-testid={`${testIdPrefix}-editor`}
|
|
232
|
+
>
|
|
229
233
|
{fields.map((field) => {
|
|
230
234
|
const controlId = `${baseId}-${field.key}`;
|
|
231
235
|
const testId = `${testIdPrefix}-${field.key}`;
|
package/src/field-remap/view.css
CHANGED
|
@@ -772,6 +772,11 @@
|
|
|
772
772
|
font: inherit;
|
|
773
773
|
}
|
|
774
774
|
|
|
775
|
+
.workbench-field-remap-flow__binding-select.is-selected {
|
|
776
|
+
color: var(--vscode-textLink-foreground, var(--color-accent, #3794ff));
|
|
777
|
+
font-weight: 600;
|
|
778
|
+
}
|
|
779
|
+
|
|
775
780
|
.workbench-field-remap-detail,
|
|
776
781
|
.workbench-field-remap-convert-note {
|
|
777
782
|
display: flex;
|
|
@@ -797,6 +802,15 @@
|
|
|
797
802
|
overflow: auto;
|
|
798
803
|
}
|
|
799
804
|
|
|
805
|
+
.workbench-field-remap-detail-modal .workbench-field-remap-detail,
|
|
806
|
+
.workbench-field-remap-detail-modal .workbench-field-remap-convert-note {
|
|
807
|
+
min-height: 0;
|
|
808
|
+
max-height: none;
|
|
809
|
+
border: 0;
|
|
810
|
+
border-radius: 0;
|
|
811
|
+
background: transparent;
|
|
812
|
+
}
|
|
813
|
+
|
|
800
814
|
.workbench-field-remap-preview {
|
|
801
815
|
display: flex;
|
|
802
816
|
flex-direction: column;
|
|
@@ -1418,18 +1432,15 @@
|
|
|
1418
1432
|
}
|
|
1419
1433
|
|
|
1420
1434
|
.workbench-field-remap-io-browse {
|
|
1435
|
+
--ui-sidebar-inline-padding: var(--shell-spacing-side-bar-inline);
|
|
1436
|
+
--ui-sidebar-row-block-padding: var(--shell-spacing-side-bar-block);
|
|
1437
|
+
--ui-sidebar-tree-indent-step: 10px;
|
|
1421
1438
|
display: grid;
|
|
1422
|
-
grid-template-columns: repeat(
|
|
1423
|
-
gap:
|
|
1439
|
+
grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
|
|
1440
|
+
gap: var(--shell-spacing-block);
|
|
1424
1441
|
width: 100%;
|
|
1425
1442
|
}
|
|
1426
1443
|
|
|
1427
|
-
@media (max-width: 800px) {
|
|
1428
|
-
.workbench-field-remap-io-browse {
|
|
1429
|
-
grid-template-columns: 1fr;
|
|
1430
|
-
}
|
|
1431
|
-
}
|
|
1432
|
-
|
|
1433
1444
|
.workbench-field-remap-io-browse__toggle {
|
|
1434
1445
|
display: inline-flex;
|
|
1435
1446
|
align-items: center;
|
|
@@ -1442,31 +1453,36 @@
|
|
|
1442
1453
|
.workbench-field-remap-io-browse__section {
|
|
1443
1454
|
display: flex;
|
|
1444
1455
|
flex-direction: column;
|
|
1445
|
-
gap:
|
|
1456
|
+
gap: var(--shell-spacing-block);
|
|
1446
1457
|
min-width: 0;
|
|
1447
1458
|
}
|
|
1448
1459
|
|
|
1449
1460
|
.workbench-field-remap-io-browse__section-title {
|
|
1450
1461
|
margin: 0;
|
|
1451
|
-
|
|
1462
|
+
padding: 0 var(--ui-sidebar-inline-padding);
|
|
1463
|
+
color: var(--color-text-muted);
|
|
1464
|
+
font-size: var(--font-size-sm);
|
|
1452
1465
|
font-weight: 600;
|
|
1453
1466
|
}
|
|
1454
1467
|
|
|
1468
|
+
.workbench-field-remap-io-browse__ports,
|
|
1469
|
+
.workbench-field-remap-io-browse__fields {
|
|
1470
|
+
margin: 0;
|
|
1471
|
+
padding: 0;
|
|
1472
|
+
list-style: none;
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1455
1475
|
.workbench-field-remap-io-browse__port {
|
|
1456
|
-
|
|
1457
|
-
flex-direction: column;
|
|
1458
|
-
gap: 0.35rem;
|
|
1459
|
-
padding: 0.5rem 0.65rem;
|
|
1460
|
-
border: 1px solid var(--vscode-widget-border, var(--color-border, #3c3c3c));
|
|
1461
|
-
border-radius: 4px;
|
|
1476
|
+
border-block-start: 1px solid var(--color-border);
|
|
1462
1477
|
}
|
|
1463
1478
|
|
|
1464
1479
|
.workbench-field-remap-io-browse__port-title {
|
|
1465
|
-
display: flex;
|
|
1466
1480
|
flex-wrap: wrap;
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1481
|
+
min-height: 26px;
|
|
1482
|
+
gap: 5px;
|
|
1483
|
+
padding: var(--ui-sidebar-row-block-padding) var(--ui-sidebar-inline-padding);
|
|
1484
|
+
color: var(--color-text);
|
|
1485
|
+
font-size: var(--font-size-sm);
|
|
1470
1486
|
}
|
|
1471
1487
|
|
|
1472
1488
|
.workbench-field-remap-io-browse__port-id {
|
|
@@ -1474,49 +1490,52 @@
|
|
|
1474
1490
|
}
|
|
1475
1491
|
|
|
1476
1492
|
.workbench-field-remap-io-browse__port-meta {
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
.workbench-field-remap-io-browse__fields {
|
|
1482
|
-
margin: 0;
|
|
1483
|
-
padding-left: 1rem;
|
|
1484
|
-
list-style: disc;
|
|
1493
|
+
margin-inline-start: auto;
|
|
1494
|
+
color: var(--color-text-muted);
|
|
1495
|
+
font-size: var(--font-size-xs);
|
|
1485
1496
|
}
|
|
1486
1497
|
|
|
1487
1498
|
.workbench-field-remap-io-browse__fields .workbench-field-remap-io-browse__fields {
|
|
1488
|
-
|
|
1499
|
+
padding-inline-start: var(--ui-sidebar-tree-indent-step);
|
|
1489
1500
|
}
|
|
1490
1501
|
|
|
1491
1502
|
.workbench-field-remap-io-browse__row {
|
|
1492
|
-
display: flex;
|
|
1493
1503
|
flex-wrap: wrap;
|
|
1494
|
-
|
|
1495
|
-
|
|
1504
|
+
min-height: 26px;
|
|
1505
|
+
gap: 5px;
|
|
1506
|
+
padding: var(--ui-sidebar-row-block-padding) var(--ui-sidebar-inline-padding);
|
|
1507
|
+
color: var(--color-text-muted);
|
|
1508
|
+
font-size: var(--font-size-sm);
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
.workbench-field-remap-io-browse__port-title:hover,
|
|
1512
|
+
.workbench-field-remap-io-browse__row:hover {
|
|
1513
|
+
background: transparent;
|
|
1496
1514
|
}
|
|
1497
1515
|
|
|
1498
1516
|
.workbench-field-remap-io-browse__path {
|
|
1499
|
-
|
|
1517
|
+
color: var(--color-text);
|
|
1518
|
+
font-size: inherit;
|
|
1500
1519
|
word-break: break-all;
|
|
1501
1520
|
}
|
|
1502
1521
|
|
|
1503
1522
|
.workbench-field-remap-io-browse__meta {
|
|
1504
1523
|
display: inline-flex;
|
|
1505
1524
|
flex-wrap: wrap;
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1525
|
+
align-items: center;
|
|
1526
|
+
gap: 5px;
|
|
1527
|
+
margin-inline-start: auto;
|
|
1528
|
+
color: var(--color-text-muted);
|
|
1529
|
+
font-size: var(--font-size-xs);
|
|
1509
1530
|
}
|
|
1510
1531
|
|
|
1511
1532
|
.workbench-field-remap-io-browse__badge {
|
|
1512
|
-
|
|
1513
|
-
border-radius: 3px;
|
|
1514
|
-
background: var(--vscode-badge-background, rgba(127, 127, 127, 0.25));
|
|
1515
|
-
color: var(--vscode-badge-foreground, inherit);
|
|
1533
|
+
flex: none;
|
|
1516
1534
|
}
|
|
1517
1535
|
|
|
1518
1536
|
.workbench-field-remap-io-browse__empty {
|
|
1519
1537
|
margin: 0;
|
|
1520
|
-
|
|
1521
|
-
|
|
1538
|
+
padding: var(--ui-sidebar-row-block-padding) var(--ui-sidebar-inline-padding);
|
|
1539
|
+
color: var(--color-text-muted);
|
|
1540
|
+
font-size: var(--font-size-sm);
|
|
1522
1541
|
}
|
package/src/index.ts
CHANGED
|
@@ -114,6 +114,8 @@ export {
|
|
|
114
114
|
} from './field-remap/panel.js';
|
|
115
115
|
export {
|
|
116
116
|
FieldRemapFlowMapper,
|
|
117
|
+
type FieldRemapConnectionFeedback,
|
|
118
|
+
type FieldRemapConnectionFeedbackReason,
|
|
117
119
|
type FieldRemapFlowActions,
|
|
118
120
|
type FieldRemapFlowMapperProps,
|
|
119
121
|
} from './field-remap/flow.js';
|
|
@@ -230,6 +232,11 @@ export {
|
|
|
230
232
|
resolveShellCommandActivities,
|
|
231
233
|
} from './workbench/command-palette.js';
|
|
232
234
|
export { WorkbenchCommandHost, type WorkbenchCommandHostProps } from './workbench/command-host.js';
|
|
235
|
+
export {
|
|
236
|
+
WorkbenchCommandHostController,
|
|
237
|
+
type WorkbenchCommandHostControllerProps,
|
|
238
|
+
type WorkbenchCommandHostExecutor,
|
|
239
|
+
} from './workbench/command-host-controller.js';
|
|
233
240
|
export { WorkbenchStartupGate, type WorkbenchStartupGateProps } from './workbench/startup-gate.js';
|
|
234
241
|
export {
|
|
235
242
|
normalizeKeybindingKeyFromEvent,
|
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
parseWorkbenchKeybindingsConfig,
|
|
3
|
-
type WorkbenchKeybindingDefinition,
|
|
4
|
-
} from '@workbench-kit/workbench-config';
|
|
1
|
+
import { type WorkbenchKeybindingDefinition } from '@workbench-kit/workbench-config';
|
|
5
2
|
import {
|
|
6
3
|
type WorkbenchPersistenceDiagnosticOptions,
|
|
7
|
-
type WorkbenchPersistenceReadResult,
|
|
8
4
|
type WorkbenchPersistenceWriteResult,
|
|
9
5
|
type WorkbenchStorageReader,
|
|
10
6
|
type WorkbenchStorageWriter,
|
|
11
7
|
} from '@workbench-kit/workbench-core';
|
|
12
|
-
|
|
13
8
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
readWorkbenchKeybindingOverridesStorageResult,
|
|
10
|
+
writeWorkbenchKeybindingOverridesStorageResult,
|
|
11
|
+
type WorkbenchKeybindingOverridesStorageReadResult,
|
|
12
|
+
} from '@workbench-kit/workbench-core/keybinding-overrides-storage';
|
|
13
|
+
import {
|
|
14
|
+
resolveWorkbenchShortcutPlatform,
|
|
15
|
+
type WorkbenchShortcutPlatform,
|
|
16
|
+
} from '@workbench-kit/platform';
|
|
17
|
+
|
|
18
|
+
import { resolveLocalWorkbenchStorage } from '../storage/local-json-storage.js';
|
|
20
19
|
|
|
21
20
|
export const DEFAULT_WORKBENCH_KEYBINDING_STORAGE_KEY = 'workbench-kit/.workbench/keybindings';
|
|
22
21
|
|
|
@@ -27,22 +26,35 @@ export function isWorkbenchKeybindingPersistenceAvailable(): boolean {
|
|
|
27
26
|
export function readPersistedKeybindingOverrides(
|
|
28
27
|
storageKey = DEFAULT_WORKBENCH_KEYBINDING_STORAGE_KEY,
|
|
29
28
|
storage?: WorkbenchStorageReader,
|
|
29
|
+
options: ReadPersistedKeybindingOverridesOptions = {},
|
|
30
30
|
): readonly WorkbenchKeybindingDefinition[] {
|
|
31
|
-
return
|
|
31
|
+
return readPersistedKeybindingOverridesResult(storageKey, storage, options).value;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface ReadPersistedKeybindingOverridesOptions extends WorkbenchPersistenceDiagnosticOptions {
|
|
35
|
+
readonly platform?: WorkbenchShortcutPlatform | undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface PersistedKeybindingOverridesReadResult extends WorkbenchKeybindingOverridesStorageReadResult {
|
|
39
|
+
readonly value: readonly WorkbenchKeybindingDefinition[];
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
export function readPersistedKeybindingOverridesResult(
|
|
35
43
|
storageKey = DEFAULT_WORKBENCH_KEYBINDING_STORAGE_KEY,
|
|
36
44
|
storage?: WorkbenchStorageReader,
|
|
37
|
-
options:
|
|
38
|
-
):
|
|
39
|
-
|
|
40
|
-
storageKey,
|
|
41
|
-
parseWorkbenchKeybindingsConfig,
|
|
42
|
-
() => [],
|
|
43
|
-
storage,
|
|
45
|
+
options: ReadPersistedKeybindingOverridesOptions = {},
|
|
46
|
+
): PersistedKeybindingOverridesReadResult {
|
|
47
|
+
const result = readWorkbenchKeybindingOverridesStorageResult({
|
|
44
48
|
options,
|
|
45
|
-
|
|
49
|
+
platform: options.platform ?? resolveWorkbenchShortcutPlatform(),
|
|
50
|
+
storage: resolveLocalWorkbenchStorage(storage),
|
|
51
|
+
storageKey,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
...result,
|
|
56
|
+
value: result.entries,
|
|
57
|
+
};
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
export function writePersistedKeybindingOverrides(
|
|
@@ -50,7 +62,15 @@ export function writePersistedKeybindingOverrides(
|
|
|
50
62
|
storageKey = DEFAULT_WORKBENCH_KEYBINDING_STORAGE_KEY,
|
|
51
63
|
storage?: WorkbenchStorageWriter,
|
|
52
64
|
): void {
|
|
53
|
-
|
|
65
|
+
const resolvedStorage = resolveLocalWorkbenchStorage(storage);
|
|
66
|
+
if (!resolvedStorage) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const result = writePersistedKeybindingOverridesResult(overrides, storageKey, resolvedStorage);
|
|
71
|
+
if (!result.committed) {
|
|
72
|
+
throw new Error(result.diagnostic.message);
|
|
73
|
+
}
|
|
54
74
|
}
|
|
55
75
|
|
|
56
76
|
export function writePersistedKeybindingOverridesResult(
|
|
@@ -59,5 +79,10 @@ export function writePersistedKeybindingOverridesResult(
|
|
|
59
79
|
storage?: WorkbenchStorageWriter,
|
|
60
80
|
options: WorkbenchPersistenceDiagnosticOptions = {},
|
|
61
81
|
): WorkbenchPersistenceWriteResult {
|
|
62
|
-
return
|
|
82
|
+
return writeWorkbenchKeybindingOverridesStorageResult({
|
|
83
|
+
entries: overrides,
|
|
84
|
+
options,
|
|
85
|
+
storage: resolveLocalWorkbenchStorage(storage),
|
|
86
|
+
storageKey,
|
|
87
|
+
});
|
|
63
88
|
}
|
|
@@ -3,11 +3,20 @@ import { KeybindingManagementPanel } from '@workbench-kit/react/workbench/manage
|
|
|
3
3
|
import { useKeybindingManagementModel } from './use-keybinding-management.js';
|
|
4
4
|
|
|
5
5
|
export function WorkbenchKeybindingManagementSettings() {
|
|
6
|
-
const {
|
|
6
|
+
const {
|
|
7
|
+
editingDisabledReason,
|
|
8
|
+
entries,
|
|
9
|
+
overrideCount,
|
|
10
|
+
platform,
|
|
11
|
+
resetKeybinding,
|
|
12
|
+
setKeybinding,
|
|
13
|
+
} = useKeybindingManagementModel();
|
|
7
14
|
|
|
8
15
|
return (
|
|
9
16
|
<KeybindingManagementPanel
|
|
17
|
+
editingDisabledReason={editingDisabledReason}
|
|
10
18
|
entries={entries}
|
|
19
|
+
platform={platform}
|
|
11
20
|
summaryLabel={`${entries.length} command${entries.length === 1 ? '' : 's'} · ${overrideCount} user override${overrideCount === 1 ? '' : 's'}`}
|
|
12
21
|
onResetKeybinding={resetKeybinding}
|
|
13
22
|
onSetKeybinding={setKeybinding}
|