Skip to content

Commit c0e9d09

Browse files
authored
Editable argument name (#13014)
# Important Notes Fairly big code changes included: - Refactor of the widget update mechanism: `onUpdate` now returns an update result and can be async. That allows widgets to properly handle error states caused by their attempted updates. Injecting an update processor in the middle of the chain also allows for inesrting additional input validation by intermediate widgets (used by argument name editor to only accept `Ast.Expr` patterns). - Deduplicate fairly complicated setup code from widgets that used `codemirror`. Now there is a common `CodeMirrorWidgetBase` component that abstracts away most of the complexities of dealing with the editor, while allowing it to still be configurable (e.g. adding extra extensions). Only the final conversion of widget input data into text and emitting the final edit remains a responsibility of individual widgets. This common layer is now used by `WidgetText`, `WidgetFunctionName` and `WidgetEnsoExpression`, but more widgets with any form of text input can be later ported as needed. - Slightly cleaned up duplicated styling for common widget UI patterns, introduced `widgetPill` shared class.
1 parent 0f4c9ae commit c0e9d09

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+908
-652
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- [Type annotations are now visible in the graph editor][12751]
1010
- [Component Browser shows methods with respect to possible type casts][12751]
1111
- [Add option to browse cloud for secret values][12953]
12+
- [Allow editing grouped component argument names.][13014]
1213
- [Add ability to inspect column, row and value from right click on table
1314
viz][12986]
1415

@@ -18,6 +19,7 @@
1819
[12913]: https://github.com/enso-org/enso/pull/12913
1920
[12751]: https://github.com/enso-org/enso/pull/12751
2021
[12953]: https://github.com/enso-org/enso/pull/12953
22+
[13014]: https://github.com/enso-org/enso/pull/13014
2123
[12986]: https://github.com/enso-org/enso/pull/12986
2224

2325
#### Enso Standard Library

app/common/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
"@tanstack/vue-query": "5.59.20",
3333
"@types/node": "^20.11.21",
3434
"lib0": "^0.2.99",
35-
"react": "^18.3.1",
3635
"vitest": "3.0.5"
3736
}
3837
}

app/gui/.dev-env

app/gui/src/project-view/assets/base.css

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@
2020
--color-dim: rgb(0 0 0 / 0.25);
2121
--color-frame-bg: rgb(255 255 255 / 0.3);
2222
--color-frame-selected-bg: rgb(255 255 255 / 0.7);
23-
--color-widget-slight: rgb(255 255 255 / 0.06);
2423
--color-widget: rgb(255 255 255 / 0.12);
2524
--color-widget-focus: rgb(255 255 255 / 1);
26-
--color-widget-unfocus: rgb(255 255 255 / 0.6);
2725
--color-widget-selected: rgb(255 255 255 / 0.58);
2826
--color-widget-selection: rgba(0 0 0 / 0.2);
2927
--color-port-connected: rgb(255 255 255 / 0.15);
@@ -81,23 +79,9 @@
8179
.define-node-colors {
8280
--color-node-primary: var(--node-group-color);
8381
--color-node-text: white;
84-
--color-node-text-selected: color-mix(
85-
in oklab,
86-
var(--color-node-primary) 70%,
87-
black 30%
88-
);
82+
--color-node-background: var(--node-group-color);
83+
--color-node-primary: var(--node-group-color);
8984
--color-node-text-placeholder: rgba(255, 255, 255, 0.6);
90-
--color-node-text-placeholder-selected: color-mix(
91-
in oklab,
92-
var(--color-node-primary) 30%,
93-
oklab(0.75 0 0) 70%
94-
);
95-
--color-node-output-port: color-mix(
96-
in oklab,
97-
var(--color-node-primary) 85%,
98-
white 15%
99-
);
100-
--color-node-port: rgb(255 255 255 / 0.15);
10185
--color-node-error: color-mix(
10286
in oklab,
10387
var(--color-node-primary) 30%,
@@ -126,6 +110,7 @@
126110
}
127111

128112
&.selected {
113+
--color-widget: var(--color-widget-selected);
129114
--color-node-background: color-mix(
130115
in oklab,
131116
var(--color-node-primary),
@@ -136,9 +121,16 @@
136121
var(--color-node-primary),
137122
white 90%
138123
);
139-
--color-node-port: rgb(255 255 255 / 0.6);
140-
--color-node-text: var(--color-node-text-selected);
141-
--color-node-text-placeholder: var(--color-node-text-placeholder-selected);
124+
--color-node-text: color-mix(
125+
in oklab,
126+
var(--color-node-primary) 70%,
127+
black 30%
128+
);
129+
--color-node-text-placeholder: color-mix(
130+
in oklab,
131+
var(--color-node-primary) 30%,
132+
oklab(0.75 0 0) 70%
133+
);
142134
--color-edge-from-node: color-mix(
143135
in oklab,
144136
var(--color-node-primary),

app/gui/src/project-view/components/ActionButton.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ const descriptionWithShortcut = computed(() =>
2323
:disabled="toValue(action.disabled)"
2424
:title="descriptionWithShortcut"
2525
:label="label"
26-
@click.stop="action.action"
26+
@activate="action.action"
2727
/>
2828
</template>

app/gui/src/project-view/components/CodeEditor/CodeEditorImpl.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const { editorView, setExtraExtensions } = useCodeMirror(editorRoot, {
5050
ensoHoverTooltip(graphStore, suggestionDbStore, vueHost),
5151
],
5252
vueHost: () => vueHost,
53+
lineMode: 'multi',
5354
})
5455
;(window as any).__codeEditorApi = testSupport(editorView)
5556
useAutoBlur(editorView.dom)

app/gui/src/project-view/components/CodeEditor/ensoSyntax.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,7 @@ class EnsoParser extends Parser {
158158
}
159159
}
160160

161-
/** TODO: Add docs */
162-
export function ensoSyntax(moduleRoot: Readonly<Ref<Ast.BodyBlock | undefined>>): Extension {
163-
return new LanguageSupport(new Language(facet, new EnsoParser(moduleRoot)), [
164-
indentUnit.of(' '),
165-
])
161+
/** CodeMirror extension that adds support for parsing enso language. */
162+
export function ensoSyntax(astRoot: Readonly<Ref<Ast.BodyBlock | undefined>>): Extension {
163+
return new LanguageSupport(new Language(facet, new EnsoParser(astRoot)), [indentUnit.of(' ')])
166164
}

app/gui/src/project-view/components/CodeMirrorRoot.vue

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<script setup lang="ts">
22
import { useCssModule } from 'vue'
33
4-
defineExpose({ highlightClasses: useCssModule() })
4+
const highlightClasses = useCssModule()
5+
defineExpose({ highlightClasses })
56
</script>
67

78
<template>
@@ -11,11 +12,8 @@ defineExpose({ highlightClasses: useCssModule() })
1112
</template>
1213

1314
<style scoped>
14-
.CodeMirrorRoot {
15-
display: contents;
16-
& :deep(.cm-content) {
17-
cursor: text;
18-
}
15+
.CodeMirrorRoot :deep(.cm-content) {
16+
cursor: text;
1917
}
2018
</style>
2119

@@ -66,4 +64,29 @@ defineExpose({ highlightClasses: useCssModule() })
6664
.invalid {
6765
color: #f00;
6866
}
67+
68+
:global(.define-node-colors:not(.selected)) {
69+
.comment,
70+
.lineComment,
71+
.blockComment,
72+
.docComment,
73+
.name,
74+
.variableName,
75+
.definition-variableName,
76+
.literal,
77+
.string,
78+
.escape,
79+
.number,
80+
.keyword,
81+
.moduleKeyword,
82+
.modifier,
83+
.punctuation,
84+
.paren,
85+
.operator,
86+
.definitionOperator,
87+
.invalid {
88+
color: var(--color-node-text);
89+
transition: color 0.2s ease;
90+
}
91+
}
6992
</style>

app/gui/src/project-view/components/ComponentBrowser.vue

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -428,11 +428,7 @@ const listsHandler = listBindings.handler({
428428
v-if="input.mode.mode === 'codeEditing' && !isVisualizationVisible"
429429
class="show-visualization"
430430
>
431-
<SvgButton
432-
name="eye"
433-
title="Show visualization"
434-
@click.stop="isVisualizationVisible = true"
435-
/>
431+
<SvgButton name="eye" title="Show visualization" @activate="isVisualizationVisible = true" />
436432
</div>
437433
<ComponentList
438434
v-if="input.mode.mode === 'componentBrowsing'"

app/gui/src/project-view/components/ComponentBrowser/ComponentEditor.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ const rootStyle = computed(() => {
109109
margin: 0;
110110
isolation: isolate;
111111
&.port {
112-
background-color: var(--color-node-port);
112+
background-color: var(--color-edge-from-node);
113113
color: white;
114114
}
115115
}

app/gui/src/project-view/components/DockPanel.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ const tabStyle = {
6969
:class="{ activeTab: currentTab === tab }"
7070
:style="tabStyle"
7171
>
72-
<SvgButton :title="title" :name="icon" @click="currentTab = tab" />
72+
<SvgButton :title="title" :name="icon" @activate="currentTab = tab" />
7373
</div>
7474
</div>
7575
<ResizeHandles

app/gui/src/project-view/components/DocumentationEditor.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ const handler = documentationEditorBindings.handler({
8787
<FullscreenButton v-model="fullscreen" />
8888
</template>
8989
<template #toolbarRight>
90-
<SvgButton name="image" title="Insert image" @click.stop="tryUploadImageFile()" />
90+
<SvgButton name="image" title="Insert image" @activate="tryUploadImageFile()" />
9191
</template>
9292
<template #belowToolbar>
9393
<slot name="belowToolbar" />

app/gui/src/project-view/components/DocumentationPanel.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ function openDocs(url: string) {
152152
v-if="documentationUrl"
153153
name="open"
154154
title="Open in New Window"
155-
@click.stop="openDocs(documentationUrl)"
155+
@activate="openDocs(documentationUrl)"
156156
/>
157157
</div>
158158
<!-- todo panel -->

app/gui/src/project-view/components/DocumentationPanel/DocsBreadcrumbs.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ function shrinkFactor(index: number): number {
3131
<SvgButton
3232
name="navigate_back"
3333
:disabled="!props.canGoBackward"
34-
@click.stop="emit('backward')"
34+
@activate="emit('backward')"
3535
/>
3636
<SvgButton
3737
name="navigate_forward"
3838
:disabled="!props.canGoForward"
39-
@click.stop="emit('forward')"
39+
@activate="emit('forward')"
4040
/>
4141
</div>
4242
<TransitionGroup name="breadcrumbs">

app/gui/src/project-view/components/FullscreenButton.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ const fullscreen = defineModel<boolean>({ required: true })
1010
<SvgButton
1111
:name="fullscreen ? 'exit_fullscreen' : 'fullscreen'"
1212
:title="fullscreen ? 'Exit Fullscreen' : 'Fullscreen'"
13-
@click.stop="fullscreen = !fullscreen"
13+
@activate="fullscreen = !fullscreen"
1414
/>
1515
</template>

app/gui/src/project-view/components/FunctionSignatureEditor.vue

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import { injectProjectNames } from '@/stores/projectNames'
66
import { useSuggestionDbStore } from '@/stores/suggestionDatabase'
77
import { documentationData } from '@/stores/suggestionDatabase/documentation'
88
import { colorFromString } from '@/util/colors'
9+
import { Ok } from '@/util/data/result'
910
import { type MethodPointer } from '@/util/methodPointer'
11+
import { useFocusWithin } from '@vueuse/core'
1012
import { computed, ref, watchEffect } from 'vue'
1113
import { FunctionDef } from 'ydoc-shared/ast'
1214
import type * as Y from 'yjs'
@@ -49,13 +51,13 @@ const treeRootInput = computed((): WidgetInput => {
4951
})
5052
5153
const rootElement = ref<HTMLElement>()
54+
const { focused } = useFocusWithin(rootElement)
5255
5356
const graph = useGraphStore()
5457
5558
function handleWidgetUpdates(update: WidgetUpdate) {
5659
applyWidgetUpdates(update, graph)
57-
// This handler is guaranteed to be the last handler in the chain.
58-
return true
60+
return Ok()
5961
}
6062
6163
const groupBasedColor = computed(() => {
@@ -84,8 +86,14 @@ const primaryApplication = emptyPrimaryApplication()
8486
</script>
8587

8688
<template>
87-
<div ref="rootElement" :style="rootStyle" class="FunctionSignatureEditor define-node-colors">
89+
<div
90+
ref="rootElement"
91+
:style="rootStyle"
92+
class="FunctionSignatureEditor define-node-colors"
93+
:class="{ selected: focused }"
94+
>
8895
<WidgetTreeRoot
96+
:selected="focused"
8997
:externalId="functionAst.externalId"
9098
:input="treeRootInput"
9199
:primaryApplication="primaryApplication"

0 commit comments

Comments
 (0)