@workbench-kit/shell-react 0.0.2-prototype.0.2.41 → 0.0.2-prototype.0.2.44
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 +81 -2
- package/package.json +14 -10
- package/src/editor/workspace-reconcile.tsx +12 -7
- 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 +117 -0
- package/src/field-remap/convert-note-editor.tsx +119 -104
- package/src/field-remap/convert-palette.tsx +6 -0
- package/src/field-remap/demo.tsx +8 -2
- package/src/field-remap/detail-panel.tsx +535 -434
- package/src/field-remap/document-io.tsx +299 -0
- 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 +1227 -272
- 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 +110 -14
- package/src/field-remap/transform-options-editor.tsx +68 -48
- package/src/field-remap/view.css +107 -189
- package/src/index.ts +7 -0
- package/src/keybinding-management-settings.ts +4 -0
- package/src/management/keybinding-overrides-storage.ts +48 -23
- package/src/management/keybinding-settings-view.tsx +31 -0
- package/src/management/keybinding-settings.tsx +4 -12
- package/src/management/use-keybinding-management.ts +72 -22
- 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 +157 -19
- 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
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import { useMemo, type JSX } from 'react';
|
|
2
|
-
import {
|
|
1
|
+
import { useId, useMemo, type JSX } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Select,
|
|
5
|
+
WorkbenchPropertyHint,
|
|
6
|
+
WorkbenchPropertyRow,
|
|
7
|
+
WorkbenchPropertySection,
|
|
8
|
+
WorkbenchPropertyStack,
|
|
9
|
+
} from '@workbench-kit/react/primitives';
|
|
3
10
|
import {
|
|
4
11
|
optionFieldsForStep,
|
|
5
12
|
resolveOptionSteps,
|
|
@@ -28,6 +35,7 @@ export interface ConvertNoteEditorProps {
|
|
|
28
35
|
readonly onEdgesChange: (edges: readonly MappingEdge[]) => void;
|
|
29
36
|
readonly edges: readonly MappingEdge[];
|
|
30
37
|
readonly onSelectionChange: (next: FieldRemapSelection) => void;
|
|
38
|
+
readonly readOnly?: boolean | undefined;
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
/**
|
|
@@ -43,7 +51,9 @@ export function ConvertNoteEditor({
|
|
|
43
51
|
edges,
|
|
44
52
|
onEdgesChange,
|
|
45
53
|
onSelectionChange,
|
|
54
|
+
readOnly = false,
|
|
46
55
|
}: ConvertNoteEditorProps): JSX.Element | null {
|
|
56
|
+
const transformSelectId = useId();
|
|
47
57
|
const chain = edge.transformIds ?? [];
|
|
48
58
|
const transformId = chain[stepIndex];
|
|
49
59
|
|
|
@@ -77,7 +87,7 @@ export function ConvertNoteEditor({
|
|
|
77
87
|
const stepLabel = definition?.label ?? transformId;
|
|
78
88
|
|
|
79
89
|
const applyEdge = (next: MappingEdge | null) => {
|
|
80
|
-
if (!next) {
|
|
90
|
+
if (readOnly || !next) {
|
|
81
91
|
return;
|
|
82
92
|
}
|
|
83
93
|
onEdgesChange(edges.map((item) => (item.id === edge.id ? next : item)));
|
|
@@ -89,111 +99,116 @@ export function ConvertNoteEditor({
|
|
|
89
99
|
data-testid="field-remap-convert-note"
|
|
90
100
|
aria-label="Convert note editor"
|
|
91
101
|
>
|
|
92
|
-
<
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
<WorkbenchPropertyStack gap="sm">
|
|
103
|
+
<WorkbenchPropertySection
|
|
104
|
+
title="Convert"
|
|
105
|
+
actions={
|
|
106
|
+
<div className="workbench-field-remap-convert-note__actions">
|
|
107
|
+
<Button
|
|
108
|
+
compact
|
|
109
|
+
type="button"
|
|
110
|
+
data-testid="field-remap-convert-note-back"
|
|
111
|
+
onClick={() => onSelectionChange({ kind: 'edge', edgeId: edge.id })}
|
|
112
|
+
>
|
|
113
|
+
Binding
|
|
114
|
+
</Button>
|
|
115
|
+
<Button
|
|
116
|
+
compact
|
|
117
|
+
type="button"
|
|
118
|
+
data-testid="field-remap-convert-note-clear"
|
|
119
|
+
onClick={() => onSelectionChange(null)}
|
|
120
|
+
>
|
|
121
|
+
Close
|
|
122
|
+
</Button>
|
|
123
|
+
</div>
|
|
124
|
+
}
|
|
125
|
+
>
|
|
126
|
+
<WorkbenchPropertyRow label="Transform">
|
|
127
|
+
<strong data-testid="field-remap-convert-note-title">{stepLabel}</strong>
|
|
128
|
+
</WorkbenchPropertyRow>
|
|
129
|
+
<WorkbenchPropertyRow label="Binding">
|
|
130
|
+
<code
|
|
131
|
+
className="workbench-field-remap-convert-note__binding"
|
|
132
|
+
data-testid="field-remap-convert-note-binding"
|
|
133
|
+
>
|
|
134
|
+
{edge.sourceFieldId} → {edge.targetSlotId}
|
|
135
|
+
</code>
|
|
136
|
+
</WorkbenchPropertyRow>
|
|
137
|
+
<WorkbenchPropertyHint className="workbench-field-remap-convert-note__muted">
|
|
103
138
|
Step {stepIndex + 1} of {chain.length} on this binding
|
|
104
|
-
</
|
|
105
|
-
</
|
|
106
|
-
<div className="workbench-field-remap-convert-note__actions">
|
|
107
|
-
<Button
|
|
108
|
-
compact
|
|
109
|
-
type="button"
|
|
110
|
-
data-testid="field-remap-convert-note-back"
|
|
111
|
-
onClick={() => onSelectionChange({ kind: 'edge', edgeId: edge.id })}
|
|
112
|
-
>
|
|
113
|
-
Binding
|
|
114
|
-
</Button>
|
|
115
|
-
<Button
|
|
116
|
-
compact
|
|
117
|
-
type="button"
|
|
118
|
-
data-testid="field-remap-convert-note-clear"
|
|
119
|
-
onClick={() => onSelectionChange(null)}
|
|
120
|
-
>
|
|
121
|
-
Close
|
|
122
|
-
</Button>
|
|
123
|
-
</div>
|
|
124
|
-
</div>
|
|
139
|
+
</WorkbenchPropertyHint>
|
|
140
|
+
</WorkbenchPropertySection>
|
|
125
141
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
</select>
|
|
157
|
-
</label>
|
|
158
|
-
</section>
|
|
142
|
+
<WorkbenchPropertySection title="Transform" data-testid="field-remap-step-settings">
|
|
143
|
+
<WorkbenchPropertyRow htmlFor={transformSelectId} label="Registry id">
|
|
144
|
+
<Select
|
|
145
|
+
id={transformSelectId}
|
|
146
|
+
aria-label="Convert transform id"
|
|
147
|
+
controlWidth="full"
|
|
148
|
+
data-testid="field-remap-step-id"
|
|
149
|
+
value={transformId}
|
|
150
|
+
disabled={readOnly}
|
|
151
|
+
onValueChange={(nextTransformId) => {
|
|
152
|
+
applyEdge(
|
|
153
|
+
setTransformStepIdOnEdge(edge, stepIndex, nextTransformId, {
|
|
154
|
+
registry: transforms,
|
|
155
|
+
sourceType: portTypes.sourceType,
|
|
156
|
+
targetType: portTypes.targetType,
|
|
157
|
+
}),
|
|
158
|
+
);
|
|
159
|
+
}}
|
|
160
|
+
>
|
|
161
|
+
{!replaceCatalog.some((item) => item.id === transformId) ? (
|
|
162
|
+
<option value={transformId}>{transformId}</option>
|
|
163
|
+
) : null}
|
|
164
|
+
{replaceCatalog.map((item) => (
|
|
165
|
+
<option key={item.id} value={item.id}>
|
|
166
|
+
{item.label}
|
|
167
|
+
</option>
|
|
168
|
+
))}
|
|
169
|
+
</Select>
|
|
170
|
+
</WorkbenchPropertyRow>
|
|
171
|
+
</WorkbenchPropertySection>
|
|
159
172
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}}
|
|
171
|
-
/>
|
|
172
|
-
</section>
|
|
173
|
+
<WorkbenchPropertySection title="Options">
|
|
174
|
+
<TransformOptionsEditor
|
|
175
|
+
fields={optionFields}
|
|
176
|
+
value={optionValue}
|
|
177
|
+
disabled={readOnly}
|
|
178
|
+
onChange={(nextOptions) => {
|
|
179
|
+
applyEdge(replaceTransformStepOptionsOnEdge(edge, stepIndex, nextOptions));
|
|
180
|
+
}}
|
|
181
|
+
/>
|
|
182
|
+
</WorkbenchPropertySection>
|
|
173
183
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
184
|
+
{!readOnly ? (
|
|
185
|
+
<WorkbenchPropertySection title="Actions">
|
|
186
|
+
<WorkbenchPropertyRow label="Convert step">
|
|
187
|
+
<Button
|
|
188
|
+
compact
|
|
189
|
+
type="button"
|
|
190
|
+
data-testid="field-remap-convert-note-remove"
|
|
191
|
+
onClick={() => {
|
|
192
|
+
const next = removeTransformStepFromEdge(edge, stepIndex);
|
|
193
|
+
applyEdge(next);
|
|
194
|
+
const nextLen = next.transformIds?.length ?? 0;
|
|
195
|
+
if (nextLen === 0) {
|
|
196
|
+
onSelectionChange({ kind: 'edge', edgeId: edge.id });
|
|
197
|
+
} else {
|
|
198
|
+
onSelectionChange({
|
|
199
|
+
kind: 'transformStep',
|
|
200
|
+
edgeId: edge.id,
|
|
201
|
+
stepIndex: Math.min(stepIndex, nextLen - 1),
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}}
|
|
205
|
+
>
|
|
206
|
+
Remove convert
|
|
207
|
+
</Button>
|
|
208
|
+
</WorkbenchPropertyRow>
|
|
209
|
+
</WorkbenchPropertySection>
|
|
210
|
+
) : null}
|
|
211
|
+
</WorkbenchPropertyStack>
|
|
197
212
|
</aside>
|
|
198
213
|
);
|
|
199
214
|
}
|
|
@@ -4,6 +4,7 @@ import { ClearableTextInput, IconButton } from '@workbench-kit/react/primitives'
|
|
|
4
4
|
import type { ValueTransformRegistry } from '@workbench-kit/field-remap';
|
|
5
5
|
|
|
6
6
|
import { defaultFieldRemapChromeLabels, type FieldRemapChromeLabels } from './chrome-labels.js';
|
|
7
|
+
import { writeFieldRemapTransformDragData } from './drag-payload.js';
|
|
7
8
|
|
|
8
9
|
export interface FieldRemapConvertPaletteProps {
|
|
9
10
|
readonly transforms: ValueTransformRegistry;
|
|
@@ -207,6 +208,7 @@ export function FieldRemapConvertPalette({
|
|
|
207
208
|
key={definition.id}
|
|
208
209
|
aria-selected={selected}
|
|
209
210
|
data-testid={`field-remap-palette-item-${definition.id}`}
|
|
211
|
+
draggable
|
|
210
212
|
role="option"
|
|
211
213
|
selected={selected}
|
|
212
214
|
tabIndex={definition.id === rovingTransformId ? 0 : -1}
|
|
@@ -217,6 +219,10 @@ export function FieldRemapConvertPalette({
|
|
|
217
219
|
onSelectedTransformIdChange(definition.id);
|
|
218
220
|
}}
|
|
219
221
|
onDoubleClick={() => onPlaceDraft(definition.id)}
|
|
222
|
+
onDragStart={(event) => {
|
|
223
|
+
event.dataTransfer.effectAllowed = 'copy';
|
|
224
|
+
writeFieldRemapTransformDragData(event.dataTransfer, definition.id);
|
|
225
|
+
}}
|
|
220
226
|
onFocus={() => setRequestedRovingTransformId(definition.id)}
|
|
221
227
|
onKeyDown={(event) => handleOptionKeyDown(event, definition.id)}
|
|
222
228
|
>
|
package/src/field-remap/demo.tsx
CHANGED
|
@@ -25,6 +25,8 @@ export interface SampleFieldRemapDemoProps {
|
|
|
25
25
|
readonly showBindingsList?: FieldRemapFlowMapperProps['showBindingsList'];
|
|
26
26
|
readonly showConvertPalette?: FieldRemapFlowMapperProps['showConvertPalette'];
|
|
27
27
|
readonly emptyDetail?: FieldRemapFlowMapperProps['emptyDetail'];
|
|
28
|
+
readonly detailPresentation?: FieldRemapFlowMapperProps['detailPresentation'];
|
|
29
|
+
readonly readOnly?: FieldRemapFlowMapperProps['readOnly'];
|
|
28
30
|
/** When true, show host-chrome demo controls (history + fit view). */
|
|
29
31
|
readonly showHostChromeDemo?: boolean | undefined;
|
|
30
32
|
/** Prefer `browse` for I/O class/field inspection demos. */
|
|
@@ -46,6 +48,8 @@ export function SampleFieldRemapDemo({
|
|
|
46
48
|
showBindingsList,
|
|
47
49
|
showConvertPalette,
|
|
48
50
|
emptyDetail,
|
|
51
|
+
detailPresentation,
|
|
52
|
+
readOnly,
|
|
49
53
|
showHostChromeDemo = false,
|
|
50
54
|
ioChrome,
|
|
51
55
|
browseSeedShapes = false,
|
|
@@ -89,7 +93,7 @@ export function SampleFieldRemapDemo({
|
|
|
89
93
|
compact
|
|
90
94
|
type="button"
|
|
91
95
|
data-testid="field-remap-undo"
|
|
92
|
-
disabled={!historyAvailability.canUndo}
|
|
96
|
+
disabled={readOnly || !historyAvailability.canUndo}
|
|
93
97
|
onClick={() => historyActionsRef.current?.undo()}
|
|
94
98
|
>
|
|
95
99
|
Undo
|
|
@@ -98,7 +102,7 @@ export function SampleFieldRemapDemo({
|
|
|
98
102
|
compact
|
|
99
103
|
type="button"
|
|
100
104
|
data-testid="field-remap-redo"
|
|
101
|
-
disabled={!historyAvailability.canRedo}
|
|
105
|
+
disabled={readOnly || !historyAvailability.canRedo}
|
|
102
106
|
onClick={() => historyActionsRef.current?.redo()}
|
|
103
107
|
>
|
|
104
108
|
Redo
|
|
@@ -119,6 +123,8 @@ export function SampleFieldRemapDemo({
|
|
|
119
123
|
showBindingsList={showBindingsList}
|
|
120
124
|
showConvertPalette={showConvertPalette}
|
|
121
125
|
emptyDetail={emptyDetail}
|
|
126
|
+
detailPresentation={detailPresentation}
|
|
127
|
+
readOnly={readOnly}
|
|
122
128
|
onShowMinimapChange={setShowMinimap}
|
|
123
129
|
ioChrome={ioChrome}
|
|
124
130
|
editableShapes={ioChrome === 'browse' ? false : undefined}
|