@workbench-kit/shell-react 0.0.2-prototype.0.2.43 → 0.0.2-prototype.0.2.45
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 +39 -0
- package/package.json +10 -9
- package/src/editor/workspace-reconcile.tsx +12 -7
- package/src/field-remap/chrome-labels.ts +99 -0
- package/src/field-remap/convert-note-editor.tsx +115 -106
- package/src/field-remap/detail-panel.tsx +524 -456
- package/src/field-remap/document-io.tsx +299 -0
- package/src/field-remap/flow.tsx +188 -126
- package/src/field-remap/panel.tsx +60 -0
- package/src/field-remap/transform-options-editor.tsx +64 -48
- package/src/field-remap/view.css +46 -147
- package/src/keybinding-management-settings.ts +4 -0
- package/src/management/keybinding-settings-view.tsx +31 -0
- package/src/management/keybinding-settings.tsx +4 -21
- package/src/management/use-keybinding-management.ts +4 -4
- package/src/shell/provider.tsx +10 -1
|
@@ -10,12 +10,18 @@ import {
|
|
|
10
10
|
} from 'react';
|
|
11
11
|
import {
|
|
12
12
|
createBuiltinValueTransformRegistry,
|
|
13
|
+
createFieldRemapDocument,
|
|
14
|
+
deserializeFieldRemapImport,
|
|
15
|
+
FieldRemapImportAdmissionError,
|
|
13
16
|
findParentChildMappingConflicts,
|
|
14
17
|
projectSourceFields,
|
|
15
18
|
projectTargetSlots,
|
|
16
19
|
pruneMappingEdgesForShapes,
|
|
20
|
+
serializeFieldRemapDocument,
|
|
17
21
|
sourceFieldsFromPlainObject,
|
|
18
22
|
targetSlotsFromPlainObject,
|
|
23
|
+
UnsupportedFieldRemapDocumentVersionError,
|
|
24
|
+
type FieldRemapDocument,
|
|
19
25
|
type MappingEdge,
|
|
20
26
|
type MappingOperator,
|
|
21
27
|
type SourceField,
|
|
@@ -52,6 +58,7 @@ import {
|
|
|
52
58
|
import { createFieldRemapPreviewController } from './preview-controller.js';
|
|
53
59
|
import type { FieldRemapPreviewState } from './preview.js';
|
|
54
60
|
import { isFieldRemapEditableShortcutTarget } from './keyboard.js';
|
|
61
|
+
import { FieldRemapDocumentIo, type FieldRemapDocumentImportActionResult } from './document-io.js';
|
|
55
62
|
import './view.css';
|
|
56
63
|
|
|
57
64
|
export type { FieldRemapHistorySnapshot } from './history.js';
|
|
@@ -111,6 +118,11 @@ export interface FieldRemapPanelProps {
|
|
|
111
118
|
/** Optional controlled n→m operators (document v2). */
|
|
112
119
|
readonly operators?: readonly MappingOperator[] | undefined;
|
|
113
120
|
readonly onOperatorsChange?: ((operators: readonly MappingOperator[]) => void) | undefined;
|
|
121
|
+
/**
|
|
122
|
+
* Atomic whole-document replacement proposal for controlled or mixed-control imports.
|
|
123
|
+
* Incremental edge/operator callbacks remain unchanged.
|
|
124
|
+
*/
|
|
125
|
+
readonly onDocumentReplace?: ((document: FieldRemapDocument) => void) | undefined;
|
|
114
126
|
/**
|
|
115
127
|
* Composite history owner for controlled or mixed-control mapping state. When either durable
|
|
116
128
|
* channel is controlled, the Panel never creates a partial private history.
|
|
@@ -264,6 +276,7 @@ export function FieldRemapPanel({
|
|
|
264
276
|
onEdgesChange,
|
|
265
277
|
operators: operatorsProp,
|
|
266
278
|
onOperatorsChange,
|
|
279
|
+
onDocumentReplace,
|
|
267
280
|
historyOwner,
|
|
268
281
|
historyActionsRef,
|
|
269
282
|
onHistoryAvailabilityChange,
|
|
@@ -437,6 +450,40 @@ export function FieldRemapPanel({
|
|
|
437
450
|
applyHistorySnapshot(next);
|
|
438
451
|
};
|
|
439
452
|
|
|
453
|
+
const documentImportAvailable =
|
|
454
|
+
!readOnly && (historyOwnedByPanel || onDocumentReplace !== undefined);
|
|
455
|
+
|
|
456
|
+
const importDocumentText = (text: string): FieldRemapDocumentImportActionResult => {
|
|
457
|
+
let document: FieldRemapDocument;
|
|
458
|
+
try {
|
|
459
|
+
document = deserializeFieldRemapImport(text, {
|
|
460
|
+
sources: sourceFields,
|
|
461
|
+
targets: targetSlots,
|
|
462
|
+
transforms: registry,
|
|
463
|
+
});
|
|
464
|
+
} catch (error) {
|
|
465
|
+
if (error instanceof UnsupportedFieldRemapDocumentVersionError) {
|
|
466
|
+
return { status: 'rejected', code: 'unsupported-version' };
|
|
467
|
+
}
|
|
468
|
+
if (error instanceof FieldRemapImportAdmissionError) {
|
|
469
|
+
return { status: 'rejected', code: error.code };
|
|
470
|
+
}
|
|
471
|
+
return { status: 'rejected', code: 'invalid-document' };
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
if (historyOwnedByPanel) {
|
|
475
|
+
recordSemanticSnapshot(
|
|
476
|
+
createFieldRemapHistorySnapshot(document.edges, document.operators ?? []),
|
|
477
|
+
);
|
|
478
|
+
return { status: 'accepted' };
|
|
479
|
+
}
|
|
480
|
+
if (!onDocumentReplace) {
|
|
481
|
+
return { status: 'rejected', code: 'invalid-document' };
|
|
482
|
+
}
|
|
483
|
+
onDocumentReplace(document);
|
|
484
|
+
return { status: 'accepted' };
|
|
485
|
+
};
|
|
486
|
+
|
|
440
487
|
const commitFlowEdges = (next: readonly MappingEdge[]) => {
|
|
441
488
|
if (includeHidden) {
|
|
442
489
|
recordSemanticSnapshot(createFieldRemapHistorySnapshot(next, operators));
|
|
@@ -693,6 +740,19 @@ export function FieldRemapPanel({
|
|
|
693
740
|
<header className="workbench-field-remap-demo__header">
|
|
694
741
|
<h2 className="workbench-field-remap-demo__title">{sample.title}</h2>
|
|
695
742
|
<p className="workbench-field-remap-demo__intro">{sample.description}</p>
|
|
743
|
+
<FieldRemapDocumentIo
|
|
744
|
+
getDocumentJson={() =>
|
|
745
|
+
serializeFieldRemapDocument(
|
|
746
|
+
createFieldRemapDocument(edges, {
|
|
747
|
+
...(operators.length > 0 ? { operators } : {}),
|
|
748
|
+
}),
|
|
749
|
+
)
|
|
750
|
+
}
|
|
751
|
+
importAvailable={documentImportAvailable}
|
|
752
|
+
labels={labels}
|
|
753
|
+
t={t}
|
|
754
|
+
onImportText={importDocumentText}
|
|
755
|
+
/>
|
|
696
756
|
</header>
|
|
697
757
|
|
|
698
758
|
{ioChrome === 'edit' ? (
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { useEffect, useId, useState, type JSX } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Checkbox,
|
|
5
|
+
NumberInput,
|
|
6
|
+
TextInput,
|
|
7
|
+
WorkbenchPropertyRow,
|
|
8
|
+
WorkbenchPropertyStack,
|
|
9
|
+
} from '@workbench-kit/react/primitives';
|
|
3
10
|
import type { TransformOptionField } from '@workbench-kit/field-remap';
|
|
4
11
|
|
|
5
12
|
export interface TransformOptionsEditorProps {
|
|
@@ -128,12 +135,14 @@ function StringMapEditor({
|
|
|
128
135
|
}
|
|
129
136
|
|
|
130
137
|
function JsonOptionEditor({
|
|
138
|
+
controlId,
|
|
131
139
|
field,
|
|
132
140
|
value,
|
|
133
141
|
disabled,
|
|
134
142
|
onChange,
|
|
135
143
|
testId,
|
|
136
144
|
}: {
|
|
145
|
+
readonly controlId: string;
|
|
137
146
|
readonly field: TransformOptionField;
|
|
138
147
|
readonly value: unknown;
|
|
139
148
|
readonly disabled: boolean;
|
|
@@ -153,6 +162,7 @@ function JsonOptionEditor({
|
|
|
153
162
|
return (
|
|
154
163
|
<div className="workbench-field-remap-options__json">
|
|
155
164
|
<textarea
|
|
165
|
+
id={controlId}
|
|
156
166
|
aria-label={field.label}
|
|
157
167
|
data-testid={testId}
|
|
158
168
|
disabled={disabled}
|
|
@@ -225,69 +235,71 @@ export function TransformOptionsEditor({
|
|
|
225
235
|
};
|
|
226
236
|
|
|
227
237
|
return (
|
|
228
|
-
<
|
|
238
|
+
<WorkbenchPropertyStack
|
|
229
239
|
className="workbench-field-remap-options"
|
|
230
240
|
data-field-remap-shortcuts="ignore"
|
|
231
241
|
data-testid={`${testIdPrefix}-editor`}
|
|
242
|
+
gap="sm"
|
|
232
243
|
>
|
|
233
244
|
{fields.map((field) => {
|
|
234
245
|
const controlId = `${baseId}-${field.key}`;
|
|
235
246
|
const testId = `${testIdPrefix}-${field.key}`;
|
|
236
247
|
const current = value[field.key];
|
|
237
248
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
key={field.key}
|
|
241
|
-
|
|
242
|
-
htmlFor={field.kind === 'boolean' ? controlId : undefined}
|
|
243
|
-
>
|
|
244
|
-
<span className="workbench-field-remap-options__label">{field.label}</span>
|
|
245
|
-
{field.kind === 'string' ? (
|
|
246
|
-
<input
|
|
249
|
+
if (field.kind === 'string') {
|
|
250
|
+
return (
|
|
251
|
+
<WorkbenchPropertyRow key={field.key} htmlFor={controlId} label={field.label}>
|
|
252
|
+
<TextInput
|
|
247
253
|
id={controlId}
|
|
248
|
-
|
|
254
|
+
controlWidth="full"
|
|
249
255
|
data-testid={testId}
|
|
250
256
|
disabled={disabled}
|
|
251
257
|
aria-label={field.label}
|
|
252
258
|
value={
|
|
253
259
|
typeof current === 'string' ? current : current == null ? '' : String(current)
|
|
254
260
|
}
|
|
255
|
-
|
|
261
|
+
onValueChange={(next) => setKey(field.key, next)}
|
|
256
262
|
/>
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
263
|
+
</WorkbenchPropertyRow>
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (field.kind === 'number') {
|
|
268
|
+
return (
|
|
269
|
+
<WorkbenchPropertyRow key={field.key} htmlFor={controlId} label={field.label}>
|
|
270
|
+
<NumberInput
|
|
260
271
|
id={controlId}
|
|
261
|
-
|
|
272
|
+
controlWidth="full"
|
|
262
273
|
data-testid={testId}
|
|
263
274
|
disabled={disabled}
|
|
264
275
|
aria-label={field.label}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
setKey(field.key, undefined);
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
const parsed = Number(raw);
|
|
273
|
-
if (Number.isFinite(parsed)) {
|
|
274
|
-
setKey(field.key, parsed);
|
|
275
|
-
}
|
|
276
|
-
}}
|
|
276
|
+
nullable
|
|
277
|
+
value={typeof current === 'number' ? current : undefined}
|
|
278
|
+
onEmptyValue={() => setKey(field.key, undefined)}
|
|
279
|
+
onValueChange={(next) => setKey(field.key, next)}
|
|
277
280
|
/>
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
+
</WorkbenchPropertyRow>
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (field.kind === 'boolean') {
|
|
286
|
+
return (
|
|
287
|
+
<WorkbenchPropertyRow key={field.key} htmlFor={controlId} label={field.label}>
|
|
288
|
+
<Checkbox
|
|
281
289
|
id={controlId}
|
|
282
|
-
type="checkbox"
|
|
283
290
|
data-testid={testId}
|
|
284
291
|
disabled={disabled}
|
|
285
292
|
aria-label={field.label}
|
|
286
293
|
checked={Boolean(current)}
|
|
287
|
-
|
|
294
|
+
onCheckedChange={(next) => setKey(field.key, next)}
|
|
288
295
|
/>
|
|
289
|
-
|
|
290
|
-
|
|
296
|
+
</WorkbenchPropertyRow>
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (field.kind === 'stringMap') {
|
|
301
|
+
return (
|
|
302
|
+
<WorkbenchPropertyRow key={field.key} label={field.label}>
|
|
291
303
|
<StringMapEditor
|
|
292
304
|
field={field}
|
|
293
305
|
value={current}
|
|
@@ -297,19 +309,23 @@ export function TransformOptionsEditor({
|
|
|
297
309
|
setKey(field.key, Object.keys(next).length > 0 ? next : undefined)
|
|
298
310
|
}
|
|
299
311
|
/>
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
312
|
+
</WorkbenchPropertyRow>
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<WorkbenchPropertyRow key={field.key} htmlFor={controlId} label={field.label}>
|
|
318
|
+
<JsonOptionEditor
|
|
319
|
+
controlId={controlId}
|
|
320
|
+
field={field}
|
|
321
|
+
value={current}
|
|
322
|
+
disabled={disabled}
|
|
323
|
+
testId={testId}
|
|
324
|
+
onChange={(next) => setKey(field.key, next)}
|
|
325
|
+
/>
|
|
326
|
+
</WorkbenchPropertyRow>
|
|
311
327
|
);
|
|
312
328
|
})}
|
|
313
|
-
</
|
|
329
|
+
</WorkbenchPropertyStack>
|
|
314
330
|
);
|
|
315
331
|
}
|
package/src/field-remap/view.css
CHANGED
|
@@ -53,6 +53,50 @@
|
|
|
53
53
|
font-size: 0.8em;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
.workbench-field-remap-document-io {
|
|
57
|
+
display: flex;
|
|
58
|
+
flex-wrap: wrap;
|
|
59
|
+
align-items: center;
|
|
60
|
+
gap: 0.5rem 0.75rem;
|
|
61
|
+
margin-top: 0.25rem;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.workbench-field-remap-document-io__actions {
|
|
65
|
+
display: flex;
|
|
66
|
+
flex-wrap: wrap;
|
|
67
|
+
gap: 0.5rem;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.workbench-field-remap-document-io__availability,
|
|
71
|
+
.workbench-field-remap-document-io__status {
|
|
72
|
+
color: var(--vscode-descriptionForeground, var(--color-text-muted));
|
|
73
|
+
font-size: 0.8rem;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.workbench-field-remap-document-io__status[data-status='error'],
|
|
77
|
+
.workbench-field-remap-document-import__error {
|
|
78
|
+
color: var(--vscode-errorForeground, var(--color-danger));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.workbench-field-remap-document-export__description,
|
|
82
|
+
.workbench-field-remap-document-import__description,
|
|
83
|
+
.workbench-field-remap-document-import__error {
|
|
84
|
+
margin: 0;
|
|
85
|
+
font-size: 0.875rem;
|
|
86
|
+
line-height: 1.45;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.workbench-field-remap-document-export__label,
|
|
90
|
+
.workbench-field-remap-document-import__label {
|
|
91
|
+
font-size: 0.875rem;
|
|
92
|
+
font-weight: 600;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.workbench-field-remap-document-export__body textarea,
|
|
96
|
+
.workbench-field-remap-document-import__body textarea {
|
|
97
|
+
min-height: 14rem;
|
|
98
|
+
}
|
|
99
|
+
|
|
56
100
|
.workbench-field-remap-demo__error {
|
|
57
101
|
margin: 0;
|
|
58
102
|
color: var(--vscode-errorForeground, var(--color-danger));
|
|
@@ -486,22 +530,6 @@
|
|
|
486
530
|
gap: 0.35rem;
|
|
487
531
|
}
|
|
488
532
|
|
|
489
|
-
.workbench-field-remap-detail__draft-ports {
|
|
490
|
-
display: grid;
|
|
491
|
-
gap: 0.5rem;
|
|
492
|
-
margin: 0;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
.workbench-field-remap-detail__draft-ports dt {
|
|
496
|
-
font-size: 0.7rem;
|
|
497
|
-
text-transform: uppercase;
|
|
498
|
-
color: var(--vscode-descriptionForeground, var(--color-text-muted));
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
.workbench-field-remap-detail__draft-ports dd {
|
|
502
|
-
margin: 0;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
533
|
.workbench-field-remap-flow__canvas {
|
|
506
534
|
height: min(40rem, 70vh);
|
|
507
535
|
min-height: 26rem;
|
|
@@ -864,39 +892,6 @@
|
|
|
864
892
|
background: var(--vscode-editor-background, var(--color-bg));
|
|
865
893
|
}
|
|
866
894
|
|
|
867
|
-
.workbench-field-remap-convert-note__header {
|
|
868
|
-
display: flex;
|
|
869
|
-
align-items: flex-start;
|
|
870
|
-
justify-content: space-between;
|
|
871
|
-
gap: 0.5rem;
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
.workbench-field-remap-convert-note__eyebrow {
|
|
875
|
-
margin: 0 0 0.2rem;
|
|
876
|
-
font-size: 0.7rem;
|
|
877
|
-
font-weight: 600;
|
|
878
|
-
letter-spacing: 0.04em;
|
|
879
|
-
text-transform: uppercase;
|
|
880
|
-
color: var(--vscode-focusBorder, var(--color-accent, #3794ff));
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
.workbench-field-remap-convert-note__header h4,
|
|
884
|
-
.workbench-field-remap-convert-note__section h5 {
|
|
885
|
-
margin: 0 0 0.35rem;
|
|
886
|
-
font-size: 0.75rem;
|
|
887
|
-
font-weight: 600;
|
|
888
|
-
text-transform: uppercase;
|
|
889
|
-
letter-spacing: 0.03em;
|
|
890
|
-
color: var(--vscode-descriptionForeground, var(--color-text-muted));
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
.workbench-field-remap-convert-note__header h4 {
|
|
894
|
-
font-size: 1rem;
|
|
895
|
-
text-transform: none;
|
|
896
|
-
letter-spacing: normal;
|
|
897
|
-
color: var(--vscode-foreground, var(--color-text));
|
|
898
|
-
}
|
|
899
|
-
|
|
900
895
|
.workbench-field-remap-convert-note__binding,
|
|
901
896
|
.workbench-field-remap-convert-note__muted {
|
|
902
897
|
display: block;
|
|
@@ -912,68 +907,15 @@
|
|
|
912
907
|
gap: 0.35rem;
|
|
913
908
|
}
|
|
914
909
|
|
|
915
|
-
.workbench-field-remap-convert-note__section,
|
|
916
|
-
.workbench-field-remap-convert-note__field {
|
|
917
|
-
display: flex;
|
|
918
|
-
flex-direction: column;
|
|
919
|
-
gap: 0.5rem;
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
.workbench-field-remap-convert-note__field {
|
|
923
|
-
gap: 0.2rem;
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
.workbench-field-remap-convert-note select {
|
|
927
|
-
box-sizing: border-box;
|
|
928
|
-
width: 100%;
|
|
929
|
-
margin-top: 0.2rem;
|
|
930
|
-
padding: 0.3rem 0.4rem;
|
|
931
|
-
border: 1px solid var(--vscode-panel-border, var(--color-border));
|
|
932
|
-
border-radius: 0.25rem;
|
|
933
|
-
background: var(--vscode-input-background, var(--color-bg));
|
|
934
|
-
color: var(--vscode-input-foreground, var(--color-text));
|
|
935
|
-
font: inherit;
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
.workbench-field-remap-convert-note__footer {
|
|
939
|
-
margin-top: auto;
|
|
940
|
-
padding-top: 0.5rem;
|
|
941
|
-
border-top: 1px solid var(--vscode-panel-border, var(--color-border));
|
|
942
|
-
}
|
|
943
|
-
|
|
944
910
|
.workbench-field-remap-detail--empty {
|
|
945
911
|
color: var(--vscode-descriptionForeground, var(--color-text-muted));
|
|
946
912
|
}
|
|
947
913
|
|
|
948
|
-
.workbench-field-remap-detail__header {
|
|
949
|
-
display: flex;
|
|
950
|
-
align-items: flex-start;
|
|
951
|
-
justify-content: space-between;
|
|
952
|
-
gap: 0.5rem;
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
.workbench-field-remap-detail__header h4,
|
|
956
|
-
.workbench-field-remap-detail__section h5 {
|
|
957
|
-
margin: 0 0 0.35rem;
|
|
958
|
-
font-size: 0.75rem;
|
|
959
|
-
font-weight: 600;
|
|
960
|
-
text-transform: uppercase;
|
|
961
|
-
letter-spacing: 0.03em;
|
|
962
|
-
color: var(--vscode-descriptionForeground, var(--color-text-muted));
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
.workbench-field-remap-detail__header code,
|
|
966
914
|
.workbench-field-remap-detail__steps code {
|
|
967
915
|
font-size: 0.75rem;
|
|
968
916
|
word-break: break-all;
|
|
969
917
|
}
|
|
970
918
|
|
|
971
|
-
.workbench-field-remap-detail__section {
|
|
972
|
-
display: flex;
|
|
973
|
-
flex-direction: column;
|
|
974
|
-
gap: 0.5rem;
|
|
975
|
-
}
|
|
976
|
-
|
|
977
919
|
.workbench-field-remap-detail__muted {
|
|
978
920
|
margin: 0;
|
|
979
921
|
color: var(--vscode-descriptionForeground, var(--color-text-muted));
|
|
@@ -1020,31 +962,12 @@
|
|
|
1020
962
|
color: var(--vscode-descriptionForeground, var(--color-text-muted));
|
|
1021
963
|
}
|
|
1022
964
|
|
|
1023
|
-
.workbench-field-remap-detail__palette,
|
|
1024
|
-
.workbench-field-remap-detail__item-pickers,
|
|
1025
|
-
.workbench-field-remap-detail__field {
|
|
1026
|
-
display: flex;
|
|
1027
|
-
flex-direction: column;
|
|
1028
|
-
gap: 0.35rem;
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
965
|
.workbench-field-remap-detail__palette {
|
|
1032
|
-
flex-direction: row;
|
|
1033
966
|
flex-wrap: wrap;
|
|
1034
|
-
align-items: flex-end;
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
.workbench-field-remap-detail__palette label,
|
|
1038
|
-
.workbench-field-remap-detail__item-pickers label,
|
|
1039
|
-
.workbench-field-remap-detail__field {
|
|
1040
|
-
flex: 1 1 10rem;
|
|
1041
|
-
min-width: 0;
|
|
1042
967
|
}
|
|
1043
968
|
|
|
1044
|
-
.workbench-field-remap-
|
|
1045
|
-
.workbench-field-remap-
|
|
1046
|
-
.workbench-field-remap-options input[type='number'],
|
|
1047
|
-
.workbench-field-remap-options textarea {
|
|
969
|
+
.workbench-field-remap-options__string-map input[type='text'],
|
|
970
|
+
.workbench-field-remap-options__json textarea {
|
|
1048
971
|
box-sizing: border-box;
|
|
1049
972
|
width: 100%;
|
|
1050
973
|
margin-top: 0.2rem;
|
|
@@ -1056,13 +979,6 @@
|
|
|
1056
979
|
font: inherit;
|
|
1057
980
|
}
|
|
1058
981
|
|
|
1059
|
-
.workbench-field-remap-detail__list-context-bar {
|
|
1060
|
-
display: flex;
|
|
1061
|
-
align-items: center;
|
|
1062
|
-
justify-content: space-between;
|
|
1063
|
-
gap: 0.5rem;
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
982
|
.workbench-field-remap-detail__item-edges {
|
|
1067
983
|
list-style: none;
|
|
1068
984
|
margin: 0;
|
|
@@ -1079,23 +995,6 @@
|
|
|
1079
995
|
gap: 0.35rem;
|
|
1080
996
|
}
|
|
1081
997
|
|
|
1082
|
-
.workbench-field-remap-options {
|
|
1083
|
-
display: flex;
|
|
1084
|
-
flex-direction: column;
|
|
1085
|
-
gap: 0.55rem;
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
.workbench-field-remap-options__field {
|
|
1089
|
-
display: flex;
|
|
1090
|
-
flex-direction: column;
|
|
1091
|
-
gap: 0.2rem;
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
.workbench-field-remap-options__label {
|
|
1095
|
-
font-size: 0.75rem;
|
|
1096
|
-
color: var(--vscode-descriptionForeground, var(--color-text-muted));
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
998
|
.workbench-field-remap-options__empty,
|
|
1100
999
|
.workbench-field-remap-options__error {
|
|
1101
1000
|
margin: 0;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { KeybindingManagementEntry, WorkbenchShortcutPlatform } from '@workbench-kit/platform';
|
|
2
|
+
import { KeybindingManagementPanel } from '@workbench-kit/react/workbench/management';
|
|
3
|
+
|
|
4
|
+
export interface WorkbenchKeybindingManagementSettingsViewProps {
|
|
5
|
+
readonly editingDisabledReason?: string | undefined;
|
|
6
|
+
readonly entries: readonly KeybindingManagementEntry[];
|
|
7
|
+
readonly overrideCount: number;
|
|
8
|
+
readonly platform: WorkbenchShortcutPlatform;
|
|
9
|
+
readonly resetKeybinding: (commandId: string) => void;
|
|
10
|
+
readonly setKeybinding: (commandId: string, key: string | undefined) => void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function WorkbenchKeybindingManagementSettingsView({
|
|
14
|
+
editingDisabledReason,
|
|
15
|
+
entries,
|
|
16
|
+
overrideCount,
|
|
17
|
+
platform,
|
|
18
|
+
resetKeybinding,
|
|
19
|
+
setKeybinding,
|
|
20
|
+
}: WorkbenchKeybindingManagementSettingsViewProps) {
|
|
21
|
+
return (
|
|
22
|
+
<KeybindingManagementPanel
|
|
23
|
+
editingDisabledReason={editingDisabledReason}
|
|
24
|
+
entries={entries}
|
|
25
|
+
platform={platform}
|
|
26
|
+
summaryLabel={`${entries.length} command${entries.length === 1 ? '' : 's'} · ${overrideCount} user override${overrideCount === 1 ? '' : 's'}`}
|
|
27
|
+
onResetKeybinding={resetKeybinding}
|
|
28
|
+
onSetKeybinding={setKeybinding}
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
@@ -1,25 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { useKeybindingManagementModel } from './use-keybinding-management.js';
|
|
1
|
+
import { useWorkbenchKeybindingManagementBinding } from '../shell/provider.js';
|
|
2
|
+
import { WorkbenchKeybindingManagementSettingsView } from './keybinding-settings-view.js';
|
|
4
3
|
|
|
5
4
|
export function WorkbenchKeybindingManagementSettings() {
|
|
6
|
-
const
|
|
7
|
-
editingDisabledReason,
|
|
8
|
-
entries,
|
|
9
|
-
overrideCount,
|
|
10
|
-
platform,
|
|
11
|
-
resetKeybinding,
|
|
12
|
-
setKeybinding,
|
|
13
|
-
} = useKeybindingManagementModel();
|
|
5
|
+
const binding = useWorkbenchKeybindingManagementBinding();
|
|
14
6
|
|
|
15
|
-
return
|
|
16
|
-
<KeybindingManagementPanel
|
|
17
|
-
editingDisabledReason={editingDisabledReason}
|
|
18
|
-
entries={entries}
|
|
19
|
-
platform={platform}
|
|
20
|
-
summaryLabel={`${entries.length} command${entries.length === 1 ? '' : 's'} · ${overrideCount} user override${overrideCount === 1 ? '' : 's'}`}
|
|
21
|
-
onResetKeybinding={resetKeybinding}
|
|
22
|
-
onSetKeybinding={setKeybinding}
|
|
23
|
-
/>
|
|
24
|
-
);
|
|
7
|
+
return <WorkbenchKeybindingManagementSettingsView {...binding} />;
|
|
25
8
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { useLayoutEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { createKeybindingManagementModel } from '@workbench-kit/platform';
|
|
3
|
-
import { createWorkbenchShellCommands } from '@workbench-kit/react/workbench';
|
|
3
|
+
import { createWorkbenchShellCommands } from '@workbench-kit/react/workbench/commands';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import type { WorkbenchContextValue } from '../shell/provider.js';
|
|
6
6
|
import { resolveShellCommandActivities } from '../workbench/command-palette.js';
|
|
7
7
|
import { normalizeExtensionKeybindingCandidates } from '../workbench/keybinding-bridge.js';
|
|
8
8
|
|
|
9
|
-
export function useKeybindingManagementModel() {
|
|
9
|
+
export function useKeybindingManagementModel(context: WorkbenchContextValue) {
|
|
10
10
|
const {
|
|
11
11
|
activities,
|
|
12
12
|
commands,
|
|
@@ -19,7 +19,7 @@ export function useKeybindingManagementModel() {
|
|
|
19
19
|
resetCommandKeybindingOverride,
|
|
20
20
|
setCommandKeybindingOverride,
|
|
21
21
|
views,
|
|
22
|
-
} =
|
|
22
|
+
} = context;
|
|
23
23
|
|
|
24
24
|
const [keybindingRevision, setKeybindingRevision] = useState(() => keybindings.revision);
|
|
25
25
|
useLayoutEffect(() => {
|
package/src/shell/provider.tsx
CHANGED
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
useState,
|
|
10
10
|
type ReactNode,
|
|
11
11
|
} from 'react';
|
|
12
|
+
import type { WorkbenchKeybindingManagementSettingsViewProps } from '../management/keybinding-settings-view.js';
|
|
13
|
+
import { useKeybindingManagementModel } from '../management/use-keybinding-management.js';
|
|
12
14
|
import {
|
|
13
15
|
collectConfigurationDefaults,
|
|
14
16
|
createEditorService,
|
|
@@ -1048,7 +1050,10 @@ export function WorkbenchProvider({
|
|
|
1048
1050
|
<WorkbenchPersistenceDiagnosticContext.Provider value={onPersistenceDiagnostic}>
|
|
1049
1051
|
<WorkbenchContext.Provider value={value}>
|
|
1050
1052
|
<ExtensionEnablementContext.Provider value={services.extensionEnablement}>
|
|
1051
|
-
<EditorWorkspaceReconciler
|
|
1053
|
+
<EditorWorkspaceReconciler
|
|
1054
|
+
editorService={services.editorService}
|
|
1055
|
+
workspaceHostService={services.workspaceHostPort?.service}
|
|
1056
|
+
/>
|
|
1052
1057
|
{children}
|
|
1053
1058
|
</ExtensionEnablementContext.Provider>
|
|
1054
1059
|
</WorkbenchContext.Provider>
|
|
@@ -1064,3 +1069,7 @@ export function useWorkbench(): WorkbenchContextValue {
|
|
|
1064
1069
|
|
|
1065
1070
|
return value;
|
|
1066
1071
|
}
|
|
1072
|
+
|
|
1073
|
+
export function useWorkbenchKeybindingManagementBinding(): WorkbenchKeybindingManagementSettingsViewProps {
|
|
1074
|
+
return useKeybindingManagementModel(useWorkbench());
|
|
1075
|
+
}
|