@eccenca/gui-elements 24.0.1 → 24.1.0-rc.1
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/CHANGELOG.md +15 -6
- package/dist/cjs/cmem/react-flow/StickyNoteModal/StickyNoteModal.js +3 -3
- package/dist/cjs/cmem/react-flow/StickyNoteModal/StickyNoteModal.js.map +1 -1
- package/dist/cjs/components/AutoSuggestion/ExtendedCodeEditor.js +3 -3
- package/dist/cjs/components/AutoSuggestion/ExtendedCodeEditor.js.map +1 -1
- package/dist/cjs/components/ContentGroup/ContentGroup.js +95 -0
- package/dist/cjs/components/ContentGroup/ContentGroup.js.map +1 -0
- package/dist/cjs/components/index.js +1 -0
- package/dist/cjs/components/index.js.map +1 -1
- package/dist/cjs/extensions/codemirror/CodeMirror.js +58 -6
- package/dist/cjs/extensions/codemirror/CodeMirror.js.map +1 -1
- package/dist/cjs/extensions/codemirror/debouncedLinter.js +18 -0
- package/dist/cjs/extensions/codemirror/debouncedLinter.js.map +1 -0
- package/dist/cjs/extensions/codemirror/hooks/useCodemirrorModeExtension.hooks.js +9 -18
- package/dist/cjs/extensions/codemirror/hooks/useCodemirrorModeExtension.hooks.js.map +1 -1
- package/dist/cjs/extensions/codemirror/linters/jsLinter.js +36 -0
- package/dist/cjs/extensions/codemirror/linters/jsLinter.js.map +1 -0
- package/dist/cjs/extensions/codemirror/linters/turtleLinter.js +81 -0
- package/dist/cjs/extensions/codemirror/linters/turtleLinter.js.map +1 -0
- package/dist/cjs/extensions/codemirror/types.js +3 -0
- package/dist/cjs/extensions/codemirror/types.js.map +1 -0
- package/dist/esm/cmem/react-flow/StickyNoteModal/StickyNoteModal.js +4 -4
- package/dist/esm/cmem/react-flow/StickyNoteModal/StickyNoteModal.js.map +1 -1
- package/dist/esm/components/AutoSuggestion/ExtendedCodeEditor.js +14 -3
- package/dist/esm/components/AutoSuggestion/ExtendedCodeEditor.js.map +1 -1
- package/dist/esm/components/ContentGroup/ContentGroup.js +100 -0
- package/dist/esm/components/ContentGroup/ContentGroup.js.map +1 -0
- package/dist/esm/components/index.js +1 -0
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/extensions/codemirror/CodeMirror.js +58 -7
- package/dist/esm/extensions/codemirror/CodeMirror.js.map +1 -1
- package/dist/esm/extensions/codemirror/debouncedLinter.js +15 -0
- package/dist/esm/extensions/codemirror/debouncedLinter.js.map +1 -0
- package/dist/esm/extensions/codemirror/hooks/useCodemirrorModeExtension.hooks.js +6 -15
- package/dist/esm/extensions/codemirror/hooks/useCodemirrorModeExtension.hooks.js.map +1 -1
- package/dist/esm/extensions/codemirror/linters/jsLinter.js +32 -0
- package/dist/esm/extensions/codemirror/linters/jsLinter.js.map +1 -0
- package/dist/esm/extensions/codemirror/linters/turtleLinter.js +77 -0
- package/dist/esm/extensions/codemirror/linters/turtleLinter.js.map +1 -0
- package/dist/esm/extensions/codemirror/types.js +2 -0
- package/dist/esm/extensions/codemirror/types.js.map +1 -0
- package/dist/types/cmem/react-flow/StickyNoteModal/StickyNoteModal.d.ts +5 -1
- package/dist/types/components/AutoSuggestion/ExtendedCodeEditor.d.ts +11 -6
- package/dist/types/components/ContentGroup/ContentGroup.d.ts +78 -0
- package/dist/types/components/index.d.ts +1 -0
- package/dist/types/extensions/codemirror/CodeMirror.d.ts +23 -5
- package/dist/types/extensions/codemirror/debouncedLinter.d.ts +4 -0
- package/dist/types/extensions/codemirror/hooks/useCodemirrorModeExtension.hooks.d.ts +3 -5
- package/dist/types/extensions/codemirror/linters/jsLinter.d.ts +5 -0
- package/dist/types/extensions/codemirror/linters/turtleLinter.d.ts +5 -0
- package/dist/types/extensions/codemirror/types.d.ts +5 -0
- package/package.json +7 -5
- package/src/cmem/react-flow/StickyNoteModal/StickyNoteModal.tsx +16 -2
- package/src/components/AutoSuggestion/ExtendedCodeEditor.tsx +29 -6
- package/src/components/ContentGroup/ContentGroup.stories.tsx +47 -0
- package/src/components/ContentGroup/ContentGroup.tsx +256 -0
- package/src/components/ContentGroup/_contentgroup.scss +56 -0
- package/src/components/TextField/stories/TextField.stories.tsx +2 -1
- package/src/components/index.scss +1 -0
- package/src/components/index.ts +1 -0
- package/src/extensions/codemirror/CodeMirror.stories.tsx +30 -0
- package/src/extensions/codemirror/CodeMirror.tsx +86 -9
- package/src/extensions/codemirror/_codemirror.scss +96 -0
- package/src/extensions/codemirror/debouncedLinter.ts +26 -0
- package/src/extensions/codemirror/hooks/useCodemirrorModeExtension.hooks.ts +6 -16
- package/src/extensions/codemirror/linters/jsLinter.ts +38 -0
- package/src/extensions/codemirror/linters/turtleLinter.ts +102 -0
- package/src/extensions/codemirror/types.ts +7 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@use "sass:color";
|
|
2
|
+
|
|
1
3
|
// own vars
|
|
2
4
|
$eccgui-color-codeeditor-background: $eccgui-color-textfield-background !default;
|
|
3
5
|
|
|
@@ -22,6 +24,63 @@ $eccgui-color-codeeditor-background: $eccgui-color-textfield-background !default
|
|
|
22
24
|
// get them a "border" like input boxes from blueprintjs
|
|
23
25
|
box-shadow: input-transition-shadow($input-shadow-color-focus), $pt-input-box-shadow;
|
|
24
26
|
|
|
27
|
+
&.#{eccgui}-disabled {
|
|
28
|
+
@extend .#{$ns}-input, .#{$ns}-disabled;
|
|
29
|
+
|
|
30
|
+
height: 290px;
|
|
31
|
+
padding: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&[class*="#{$eccgui}-intent--"] {
|
|
35
|
+
animation-duration: 1s;
|
|
36
|
+
animation-delay: 0.5s;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@each $each-intent, $each-bgcolor in $eccgui-map-intent-bgcolors {
|
|
40
|
+
&.#{eccgui}-intent--#{$each-intent} {
|
|
41
|
+
background-color: color.mix($each-bgcolor, $eccgui-color-textfield-background, 24%);
|
|
42
|
+
animation-name: intent-state-flash-#{$each-intent};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&.#{eccgui}-intent--warning {
|
|
47
|
+
@include pt-input-intent($eccgui-color-warning-text);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
&.#{eccgui}-intent--success {
|
|
51
|
+
@include pt-input-intent($eccgui-color-success-text);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&.#{eccgui}-intent--danger {
|
|
55
|
+
@include pt-input-intent($eccgui-color-danger-text);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&.#{eccgui}-intent--primary {
|
|
59
|
+
@include pt-input-intent($eccgui-color-info-text);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&.#{eccgui}-intent--info {
|
|
63
|
+
@include pt-input-intent($eccgui-color-info-text);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
&.#{eccgui}-intent--accent {
|
|
67
|
+
@include pt-input-intent($eccgui-color-primary);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
&.#{eccgui}-intent--neutral {
|
|
71
|
+
@include pt-input-intent($eccgui-color-workspace-text);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&.#{eccgui}-intent--edited {
|
|
75
|
+
@include pt-input-intent($eccgui-color-info-text);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
&.#{eccgui}-intent--removed {
|
|
79
|
+
@include pt-input-intent($eccgui-color-danger-text);
|
|
80
|
+
|
|
81
|
+
text-decoration: line-through $eccgui-color-danger-text 2px;
|
|
82
|
+
}
|
|
83
|
+
|
|
25
84
|
.cm-scroller {
|
|
26
85
|
width: calc(100% - 2px);
|
|
27
86
|
height: calc(100% - 2px);
|
|
@@ -34,6 +93,43 @@ $eccgui-color-codeeditor-background: $eccgui-color-textfield-background !default
|
|
|
34
93
|
&.cm-focused {
|
|
35
94
|
outline: none;
|
|
36
95
|
box-shadow: input-transition-shadow($input-shadow-color-focus, true), $input-box-shadow-focus;
|
|
96
|
+
|
|
97
|
+
&.#{eccgui}-intent--warning {
|
|
98
|
+
box-shadow: input-transition-shadow($eccgui-color-warning-text, true), $input-box-shadow-focus;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
&.#{eccgui}-intent--success {
|
|
102
|
+
box-shadow: input-transition-shadow($eccgui-color-success-text, true), $input-box-shadow-focus;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
&.#{eccgui}-intent--danger {
|
|
106
|
+
box-shadow: input-transition-shadow($eccgui-color-danger-text, true), $input-box-shadow-focus;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
&.#{eccgui}-intent--primary {
|
|
110
|
+
box-shadow: input-transition-shadow($eccgui-color-info-text, true), $input-box-shadow-focus;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
&.#{eccgui}-intent--info {
|
|
114
|
+
box-shadow: input-transition-shadow($eccgui-color-info-text, true), $input-box-shadow-focus;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
&.#{eccgui}-intent--accent {
|
|
118
|
+
box-shadow: input-transition-shadow($eccgui-color-warning-text, true), $input-box-shadow-focus;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
&.#{eccgui}-intent--neutral {
|
|
122
|
+
box-shadow: input-transition-shadow($eccgui-color-workspace-text, true), $input-box-shadow-focus;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
&.#{eccgui}-intent--edited {
|
|
126
|
+
box-shadow: input-transition-shadow($eccgui-color-info-text, true), $input-box-shadow-focus;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
&.#{eccgui}-intent--removed {
|
|
130
|
+
text-decoration: line-through $eccgui-color-danger-text 2px;
|
|
131
|
+
box-shadow: input-transition-shadow($eccgui-color-danger-text, true), $input-box-shadow-focus;
|
|
132
|
+
}
|
|
37
133
|
}
|
|
38
134
|
|
|
39
135
|
.CodeMirror-hscrollbar {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Diagnostic } from "@codemirror/lint";
|
|
2
|
+
import { EditorView } from "@codemirror/view";
|
|
3
|
+
import { debounce } from "lodash";
|
|
4
|
+
|
|
5
|
+
import { Linter } from "./types";
|
|
6
|
+
|
|
7
|
+
const DEBOUNCE_TIME = 500;
|
|
8
|
+
|
|
9
|
+
export const debouncedLinter = (lintFunction: Linter, time = DEBOUNCE_TIME) => {
|
|
10
|
+
const debouncedFn = debounce(
|
|
11
|
+
(
|
|
12
|
+
view: EditorView,
|
|
13
|
+
resolve: (diagnostics: ReadonlyArray<Diagnostic> | Promise<ReadonlyArray<Diagnostic>>) => void
|
|
14
|
+
) => {
|
|
15
|
+
const diagnostics = lintFunction(view);
|
|
16
|
+
resolve(diagnostics);
|
|
17
|
+
},
|
|
18
|
+
time
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
return (view: EditorView) => {
|
|
22
|
+
return new Promise<ReadonlyArray<Diagnostic>>((resolve) => {
|
|
23
|
+
debouncedFn(view, resolve);
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
//adapted v6 modes imports
|
|
2
|
-
import { javascript } from "@codemirror/lang-javascript";
|
|
3
1
|
import { json } from "@codemirror/lang-json";
|
|
2
|
+
//modes imports
|
|
4
3
|
import { markdown } from "@codemirror/lang-markdown";
|
|
5
|
-
import { sql } from "@codemirror/lang-sql";
|
|
6
4
|
import { xml } from "@codemirror/lang-xml";
|
|
7
|
-
import { yaml } from "@codemirror/lang-yaml";
|
|
8
5
|
import { defaultHighlightStyle, LanguageSupport, StreamLanguage, StreamParser } from "@codemirror/language";
|
|
9
|
-
|
|
6
|
+
import { javascript } from "@codemirror/legacy-modes/mode/javascript";
|
|
10
7
|
import { jinja2 } from "@codemirror/legacy-modes/mode/jinja2";
|
|
11
8
|
import { mathematica } from "@codemirror/legacy-modes/mode/mathematica";
|
|
12
9
|
import { ntriples } from "@codemirror/legacy-modes/mode/ntriples";
|
|
13
10
|
import { python } from "@codemirror/legacy-modes/mode/python";
|
|
14
11
|
import { sparql } from "@codemirror/legacy-modes/mode/sparql";
|
|
12
|
+
import { sql } from "@codemirror/legacy-modes/mode/sql";
|
|
15
13
|
import { turtle } from "@codemirror/legacy-modes/mode/turtle";
|
|
14
|
+
import { yaml } from "@codemirror/legacy-modes/mode/yaml";
|
|
16
15
|
|
|
17
16
|
//adaptations
|
|
18
17
|
import { adaptedSyntaxHighlighting } from "../tests/codemirrorTestHelper";
|
|
@@ -35,19 +34,10 @@ const supportedModes = {
|
|
|
35
34
|
export const supportedCodeEditorModes = Object.keys(supportedModes) as Array<keyof typeof supportedModes>;
|
|
36
35
|
export type SupportedCodeEditorModes = (typeof supportedCodeEditorModes)[number];
|
|
37
36
|
|
|
38
|
-
const v6AdaptedModes: ReadonlyMap<SupportedCodeEditorModes, boolean> = new Map([
|
|
39
|
-
["json", true],
|
|
40
|
-
["markdown", true],
|
|
41
|
-
["xml", true],
|
|
42
|
-
["sql", true],
|
|
43
|
-
["yaml", true],
|
|
44
|
-
["javascript", true],
|
|
45
|
-
]);
|
|
46
|
-
|
|
47
37
|
export const useCodeMirrorModeExtension = (mode?: SupportedCodeEditorModes) => {
|
|
48
38
|
return !mode
|
|
49
39
|
? adaptedSyntaxHighlighting(defaultHighlightStyle)
|
|
50
|
-
:
|
|
51
|
-
? ((typeof supportedModes[mode] === "function" ? supportedModes[mode] : () =>
|
|
40
|
+
: ["json", "markdown", "xml"].includes(mode)
|
|
41
|
+
? ((typeof supportedModes[mode] === "function" ? supportedModes[mode] : () => null) as () => LanguageSupport)()
|
|
52
42
|
: StreamLanguage?.define(supportedModes[mode] as StreamParser<unknown>);
|
|
53
43
|
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Diagnostic, linter } from "@codemirror/lint";
|
|
2
|
+
import { JSHINT as jshint } from "jshint";
|
|
3
|
+
|
|
4
|
+
import { ExtensionCreator } from "../types";
|
|
5
|
+
|
|
6
|
+
const lintOptions = {
|
|
7
|
+
esversion: 11,
|
|
8
|
+
browser: true,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Sets up the javascript linter. Documentation: https://codemirror.net/examples/lint/
|
|
13
|
+
*/
|
|
14
|
+
export const jsLinter: ExtensionCreator = () => {
|
|
15
|
+
return linter((view) => {
|
|
16
|
+
const diagnostics: Array<Diagnostic> = [];
|
|
17
|
+
const codeText = view.state.doc.toJSON();
|
|
18
|
+
jshint(codeText, lintOptions);
|
|
19
|
+
const errors = jshint?.data()?.errors;
|
|
20
|
+
|
|
21
|
+
if (errors && errors.length > 0) {
|
|
22
|
+
errors.forEach((error) => {
|
|
23
|
+
const selectedLine = view.state.doc.line(error.line);
|
|
24
|
+
|
|
25
|
+
const diagnostic: Diagnostic = {
|
|
26
|
+
from: selectedLine.from,
|
|
27
|
+
to: selectedLine.to,
|
|
28
|
+
severity: "error",
|
|
29
|
+
message: error.reason,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
diagnostics.push(diagnostic);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return diagnostics;
|
|
37
|
+
});
|
|
38
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Diagnostic, linter } from "@codemirror/lint";
|
|
2
|
+
import { EditorView } from "@codemirror/view";
|
|
3
|
+
import { Parser } from "n3";
|
|
4
|
+
|
|
5
|
+
import { debouncedLinter } from "../debouncedLinter";
|
|
6
|
+
import { ExtensionCreator, Linter } from "../types";
|
|
7
|
+
|
|
8
|
+
const parser = new Parser();
|
|
9
|
+
|
|
10
|
+
const EMPTY_RESOURCE = "<>";
|
|
11
|
+
|
|
12
|
+
const getError = (message: string, view: EditorView) => {
|
|
13
|
+
const lineMatch = message.match(/(?<=line )\d{1,}/);
|
|
14
|
+
const valueMatch = message.match(/"([^"]*)"/);
|
|
15
|
+
|
|
16
|
+
const lineNumber = lineMatch ? Number(lineMatch[0]) : 1;
|
|
17
|
+
// the [1] index is used to get the caputre group
|
|
18
|
+
const errorContent = valueMatch && valueMatch[1];
|
|
19
|
+
|
|
20
|
+
const line = view.state.doc.line(lineNumber);
|
|
21
|
+
const position = line.text.search(errorContent ?? /\S/);
|
|
22
|
+
|
|
23
|
+
const from = line.from + position;
|
|
24
|
+
const errorLength = errorContent?.length;
|
|
25
|
+
|
|
26
|
+
return { from, to: errorLength ? from + errorLength : line.to };
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const getQuadError = (view: EditorView) => {
|
|
30
|
+
const lines = view.state.doc.toJSON();
|
|
31
|
+
|
|
32
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
33
|
+
const input = lines[i].trim();
|
|
34
|
+
|
|
35
|
+
if (!input) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (input.includes(EMPTY_RESOURCE)) {
|
|
40
|
+
// i + 1 is used here because the codemirror uses 1-indexes
|
|
41
|
+
const line = view.state.doc.line(i + 1);
|
|
42
|
+
const position = line.text.search(EMPTY_RESOURCE);
|
|
43
|
+
|
|
44
|
+
const from = line.from + position;
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
from,
|
|
48
|
+
to: from + EMPTY_RESOURCE.length,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return { from: 0, to: view.state.doc.length };
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const n3Linter: Linter = (view) => {
|
|
57
|
+
const diagnostics: Array<Diagnostic> = [];
|
|
58
|
+
const value = view.state.doc.toString();
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const quads = parser.parse(value);
|
|
62
|
+
|
|
63
|
+
quads.forEach((quad) => {
|
|
64
|
+
if (!quad.subject || !quad.predicate || !quad.object) {
|
|
65
|
+
const { from, to } = getQuadError(view);
|
|
66
|
+
|
|
67
|
+
view.dispatch({
|
|
68
|
+
scrollIntoView: true,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
diagnostics.push({
|
|
72
|
+
from,
|
|
73
|
+
to,
|
|
74
|
+
severity: "error",
|
|
75
|
+
message: `Invalid RDF quad:\n\nsubject: ${quad.subject}\npredicate: ${quad.predicate}\nobject: ${quad.object}`,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
} catch (error) {
|
|
80
|
+
const { message } = error as Error;
|
|
81
|
+
|
|
82
|
+
const { from, to } = getError(message, view);
|
|
83
|
+
|
|
84
|
+
view.dispatch({
|
|
85
|
+
scrollIntoView: true,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
diagnostics.push({
|
|
89
|
+
from,
|
|
90
|
+
to,
|
|
91
|
+
severity: "error",
|
|
92
|
+
message: (error as Error).message,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return diagnostics;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Sets up the turtle linter. Documentation: https://codemirror.net/examples/lint/
|
|
101
|
+
*/
|
|
102
|
+
export const turtleLinter: ExtensionCreator = () => linter(debouncedLinter(n3Linter));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Diagnostic } from "@codemirror/lint";
|
|
2
|
+
import { Extension } from "@codemirror/state";
|
|
3
|
+
import { EditorView } from "@codemirror/view";
|
|
4
|
+
|
|
5
|
+
export type Linter = (view: EditorView) => ReadonlyArray<Diagnostic> | Promise<ReadonlyArray<Diagnostic>>;
|
|
6
|
+
|
|
7
|
+
export type ExtensionCreator<T = unknown> = (options?: T) => Extension;
|