Skip to content

Commit 03db9f7

Browse files
committed
feat(code-editor): enable label, tooltip, required field, and word wrap support
1 parent 9f9330b commit 03db9f7

File tree

3 files changed

+99
-6
lines changed

3 files changed

+99
-6
lines changed

client/packages/lowcoder/src/comps/comps/codeEditorComp/codeEditorComp.tsx

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,20 @@ import {
88
eventHandlerControl,
99
stringExposingStateControl,
1010
BoolControl,
11+
LabelControl,
12+
styleControl,
1113
dropdownControl,
1214
AutoHeightControl,
1315
} from "lowcoder-sdk";
16+
import { CodeEditorContainerStyle, LabelStyle } from "comps/controls/styleControlConstants";
1417
import { useResizeDetector } from "react-resize-detector";
1518
import Editor from "@monaco-editor/react";
1619
import { styled } from "styled-components";
1720
import { trans } from "i18n";
1821
import { useRef, useCallback, useLayoutEffect } from "react";
1922
import debounce from "lodash/debounce";
2023
import * as monacoEditor from "monaco-editor";
24+
import { formDataChildren, FormDataPropertyView } from "../../comps/formComp/formDataConstants";
2125

2226
const CodeEditorWrapper = styled.div`
2327
border: 1px solid #dddddd;
@@ -58,6 +62,7 @@ let CodeEditorTmpComp = (function () {
5862
language: "yaml",
5963
theme: "light",
6064
lineNumbers: "on",
65+
wordWrap: "on",
6166
lightbulb: monacoEditor.editor.ShowLightbulbIconMode.OnCode,
6267
enabled: true,
6368
disabled: false,
@@ -76,25 +81,45 @@ let CodeEditorTmpComp = (function () {
7681
{ label: trans("codeEditor.lineNumberOptions.relative"), value: "relative" },
7782
].sort((a, b) => a.label.localeCompare(b.label))
7883

84+
const wordWrapOptions = [
85+
{ label: trans("codeEditor.wordWrapOptions.on"), value: "on" },
86+
{ label: trans("codeEditor.wordWrapOptions.off"), value: "off" },
87+
{ label: trans("codeEditor.wordWrapOptions.wordWrapColumn"), value: "wordWrapColumn" },
88+
{ label: trans("codeEditor.wordWrapOptions.bounded"), value: "bounded" },
89+
].sort((a, b) => a.label.localeCompare(b.label))
90+
7991
const childrenMap = {
8092
autoHeight: withDefault(AutoHeightControl, "auto"),
8193
language: dropdownControl(languages, defaultValues.language),
8294
theme: dropdownControl(themes, defaultValues.theme),
8395
lineNumbers: dropdownControl(lineNumbersOptions, defaultValues.lineNumbers),
96+
wordWrap: dropdownControl(wordWrapOptions, defaultValues.wordWrap),
8497
minimap: withDefault(BoolControl, defaultValues.enabled),
8598
stickyScroll: withDefault(BoolControl, defaultValues.enabled),
8699
lightbulb: withDefault(BoolControl, defaultValues.enabled),
87100
hover: withDefault(BoolControl, defaultValues.enabled),
88101
folding: withDefault(BoolControl, defaultValues.enabled),
89102
readOnly: withDefault(BoolControl, defaultValues.disabled),
90103
value: stringExposingStateControl("text", defaultValues.value),
104+
required: withDefault(BoolControl, defaultValues.disabled),
105+
label: withDefault(LabelControl, {
106+
text: "Code Editor",
107+
tooltip: "",
108+
hidden: false,
109+
widthUnit: "%",
110+
position: "column",
111+
align: "left"
112+
}),
113+
style: styleControl(CodeEditorContainerStyle , "style"),
114+
labelStyle: styleControl(LabelStyle , 'labelStyle'),
91115
onEvent: eventHandlerControl([
92116
{
93117
label: "onChange",
94118
value: "change",
95119
description: "Triggers when data changes",
96120
},
97121
] as const),
122+
...formDataChildren,
98123
};
99124

100125
return new UICompBuilder(childrenMap, (props) => {
@@ -174,7 +199,10 @@ let CodeEditorTmpComp = (function () {
174199
}
175200
}, [props.value.value]);
176201

177-
return (
202+
return props.label({
203+
required: props.required,
204+
style: props.style,
205+
children: (
178206
<CodeEditorWrapper
179207
ref={conRef}
180208
style={{
@@ -210,6 +238,7 @@ let CodeEditorTmpComp = (function () {
210238
hover: {
211239
enabled: props.hover,
212240
},
241+
wordWrap: props.wordWrap as 'off' | 'on' | 'wordWrapColumn' | 'bounded',
213242
folding: props.folding,
214243
readOnly: props.readOnly,
215244
lineNumbers: props.lineNumbers as monacoEditor.editor.LineNumbersType,
@@ -219,7 +248,8 @@ let CodeEditorTmpComp = (function () {
219248
onChange={handleOnChange}
220249
/>
221250
</CodeEditorWrapper>
222-
);
251+
)
252+
})
223253
})
224254
.setPropertyViewFn((children: any) => {
225255
return (
@@ -229,19 +259,33 @@ let CodeEditorTmpComp = (function () {
229259
{children.language.propertyView({ label: trans("codeEditor.properties.language") })}
230260
{children.theme.propertyView({ label: trans("codeEditor.properties.theme") })}
231261
{children.lineNumbers.propertyView({ label: trans("codeEditor.properties.lineNumbers") })}
262+
{children.wordWrap.propertyView({ label: trans("codeEditor.properties.wordWrap") })}
232263
{children.minimap.propertyView({ label: trans("codeEditor.properties.minimap") })}
233264
{children.stickyScroll.propertyView({ label: trans("codeEditor.properties.stickyScroll")})}
234265
{children.lightbulb.propertyView({ label: trans("codeEditor.properties.lightbulb") })}
235266
{children.hover.propertyView({ label: trans("codeEditor.properties.hover") })}
236267
{children.folding.propertyView({ label: trans("codeEditor.properties.folding") })}
237-
{children.readOnly.propertyView({ label: trans("codeEditor.properties.readOnly") })}
238268
</Section>
269+
{children.label.getPropertyView()}
239270
<Section name="Interaction">
240271
{children.onEvent.propertyView()}
241272
</Section>
242-
<Section name="Styles">
273+
<Section name="Layout">
243274
{children.autoHeight.getPropertyView()}
244275
</Section>
276+
<Section name="Advanced">
277+
{children.readOnly.propertyView({ label: trans("codeEditor.properties.readOnly") })}
278+
</Section>
279+
<Section name="Validation">
280+
{children.required.propertyView({ label: trans("codeEditor.properties.required") })}
281+
</Section>
282+
<Section name="Style">
283+
{children.style.getPropertyView()}
284+
</Section>
285+
<Section name="Label Style">
286+
{children.labelStyle.getPropertyView()}
287+
</Section>
288+
<FormDataPropertyView {...children} />
245289
</>
246290
);
247291
})
@@ -427,6 +471,24 @@ CodeEditorTmpComp = withMethodExposing(CodeEditorTmpComp, [
427471
}
428472
}
429473
},
474+
{
475+
method: {
476+
name: "enableWordWrap",
477+
description: trans("codeEditor.methods.enableWordWrap"),
478+
params: [{
479+
name: "wordWrap",
480+
type: "boolean",
481+
description: "boolean"
482+
}],
483+
},
484+
execute: (comp: any, values: any[]) => {
485+
if(Array.isArray(values)) {
486+
comp.children.wordWrap.dispatchChangeValueAction(values[0]);
487+
} else {
488+
comp.children.wordWrap.dispatchChangeValueAction(values);
489+
}
490+
}
491+
},
430492
{
431493
method: {
432494
name: "setReadOnly",
@@ -445,17 +507,37 @@ CodeEditorTmpComp = withMethodExposing(CodeEditorTmpComp, [
445507
}
446508
}
447509
},
510+
{
511+
method: {
512+
name: "markAsRequired",
513+
description: trans("codeEditor.methods.markAsRequired"),
514+
params: [{
515+
name: "required",
516+
type: "boolean",
517+
description: "boolean"
518+
}],
519+
},
520+
execute: (comp: any, values: any[]) => {
521+
if(Array.isArray(values)) {
522+
comp.children.required.dispatchChangeValueAction(values[0]);
523+
} else {
524+
comp.children.required.dispatchChangeValueAction(values);
525+
}
526+
}
527+
},
448528
]);
449529

450530
export const CodeEditorComp = withExposingConfigs(CodeEditorTmpComp, [
451531
new NameConfig("value", trans("codeEditor.properties.value")),
452532
new NameConfig("language", trans("codeEditor.properties.language")),
453533
new NameConfig("theme", trans("codeEditor.properties.theme")),
454534
new NameConfig("lineNumbers", trans("codeEditor.properties.lineNumbers")),
535+
new NameConfig("wordWrap", trans("codeEditor.properties.wordWrap")),
455536
new NameConfig("minimap", trans("codeEditor.properties.minimap")),
456537
new NameConfig("stickyScroll", trans("codeEditor.properties.stickyScroll")),
457538
new NameConfig("lightbulb", trans("codeEditor.properties.lightbulb")),
458539
new NameConfig("hover", trans("codeEditor.properties.hover")),
459540
new NameConfig("folding", trans("codeEditor.properties.folding")),
460541
new NameConfig("readOnly", trans("codeEditor.properties.readOnly")),
542+
new NameConfig("required", trans("codeEditor.properties.required")),
461543
]);

client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,10 @@ export const SignatureContainerStyle = [
14461446
// ...STYLING_FIELDS_CONTAINER_SEQUENCE,
14471447
] as const;
14481448

1449+
export const CodeEditorContainerStyle = [
1450+
getStaticBorder(),
1451+
] as const;
1452+
14491453
export const RatingStyle = [
14501454
{
14511455
name: "checked",

client/packages/lowcoder/src/i18n/locales/en.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ export const en = {
6464
"lightbulb": "Lightbulb",
6565
"hover": "Hover",
6666
"folding": "Folding",
67+
"wordWrap": "Word Wrap",
6768
"readOnly": "Read Only",
68-
"resizable": "Resizable"
69+
"required": "Required",
6970
},
7071
"methods": {
7172
"setValue": "Update the editor's content.",
@@ -78,7 +79,7 @@ export const en = {
7879
"enableHover": "Enable or disable hover.",
7980
"enableFolding": "Enable or disable folding.",
8081
"setReadOnly": "Enable or disable read-only mode.",
81-
"setResizable": "Enable or disable the ability to resize the editor.",
82+
"markAsRequired": "Marks the field as required, preventing submission if left empty.",
8283
},
8384
"theme": {
8485
"light": "Light",
@@ -116,6 +117,12 @@ export const en = {
116117
"off": "Off",
117118
"relative": "Relative",
118119
"interval": "Interval"
120+
},
121+
"wordWrapOptions": {
122+
"on": "On",
123+
"off": "Off",
124+
"wordWrapColumn": "Column",
125+
"bounded": "Bounded"
119126
}
120127
},
121128
"exportMethod": {

0 commit comments

Comments
 (0)