@finos/legend-lego 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +3 -0
  3. package/lib/code-editor/CodeEditor.d.ts +28 -0
  4. package/lib/code-editor/CodeEditor.d.ts.map +1 -0
  5. package/lib/code-editor/CodeEditor.js +109 -0
  6. package/lib/code-editor/CodeEditor.js.map +1 -0
  7. package/lib/code-editor/CodeEditorUtils.d.ts +61 -0
  8. package/lib/code-editor/CodeEditorUtils.d.ts.map +1 -0
  9. package/lib/code-editor/CodeEditorUtils.js +134 -0
  10. package/lib/code-editor/CodeEditorUtils.js.map +1 -0
  11. package/lib/code-editor/index.d.ts +18 -0
  12. package/lib/code-editor/index.d.ts.map +1 -0
  13. package/lib/code-editor/index.js +18 -0
  14. package/lib/code-editor/index.js.map +1 -0
  15. package/lib/code-editor/testing/MockedMonacoEditor.d.ts +17 -0
  16. package/lib/code-editor/testing/MockedMonacoEditor.d.ts.map +1 -0
  17. package/lib/code-editor/testing/MockedMonacoEditor.js +17 -0
  18. package/lib/code-editor/testing/MockedMonacoEditor.js.map +1 -0
  19. package/lib/code-editor/testing/MonacoEditorMockUtils.d.ts +99 -0
  20. package/lib/code-editor/testing/MonacoEditorMockUtils.d.ts.map +1 -0
  21. package/lib/code-editor/testing/MonacoEditorMockUtils.js +105 -0
  22. package/lib/code-editor/testing/MonacoEditorMockUtils.js.map +1 -0
  23. package/lib/code-editor/testing/index.d.ts +17 -0
  24. package/lib/code-editor/testing/index.d.ts.map +1 -0
  25. package/lib/code-editor/testing/index.js +17 -0
  26. package/lib/code-editor/testing/index.js.map +1 -0
  27. package/lib/data-grid/DataGrid.d.ts +22 -0
  28. package/lib/data-grid/DataGrid.d.ts.map +1 -0
  29. package/lib/data-grid/DataGrid.js +26 -0
  30. package/lib/data-grid/DataGrid.js.map +1 -0
  31. package/lib/data-grid/index.d.ts +17 -0
  32. package/lib/data-grid/index.d.ts.map +1 -0
  33. package/lib/data-grid/index.js +17 -0
  34. package/lib/data-grid/index.js.map +1 -0
  35. package/lib/index.css +17 -0
  36. package/lib/index.css.map +1 -0
  37. package/package.json +80 -0
  38. package/src/code-editor/CodeEditor.tsx +157 -0
  39. package/src/code-editor/CodeEditorUtils.ts +201 -0
  40. package/src/code-editor/index.ts +18 -0
  41. package/src/code-editor/testing/MockedMonacoEditor.ts +24 -0
  42. package/src/code-editor/testing/MonacoEditorMockUtils.tsx +111 -0
  43. package/src/code-editor/testing/index.ts +17 -0
  44. package/src/data-grid/DataGrid.tsx +42 -0
  45. package/src/data-grid/index.ts +17 -0
  46. package/tsconfig.json +48 -0
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { editor as monacoEditorAPI, MarkerSeverity } from 'monaco-editor';
18
+
19
+ export type CodeEditorPosition = {
20
+ lineNumber: number;
21
+ column: number;
22
+ };
23
+
24
+ /**
25
+ * Normally `monaco-editor` worker disposes after 5 minutes staying idle, but we fasten
26
+ * this pace just in case the usage of the editor causes memory-leak somehow
27
+ */
28
+ export const disposeCodeEditor = (
29
+ editor: monacoEditorAPI.IStandaloneCodeEditor,
30
+ ): void => {
31
+ editor.dispose();
32
+ // NOTE: just to be sure, we dispose the model after disposing the editor
33
+ editor.getModel()?.dispose();
34
+ };
35
+
36
+ export const disposeDiffCodeEditor = (
37
+ editor: monacoEditorAPI.IStandaloneDiffEditor,
38
+ ): void => {
39
+ editor.dispose();
40
+ editor.getOriginalEditor().getModel()?.dispose();
41
+ editor.getModifiedEditor().getModel()?.dispose();
42
+ };
43
+
44
+ /**
45
+ * Get the text value with LF line ending.
46
+ * This is needed since if there are CR `\r` characters in the text input
47
+ * (e.g. users of Windows doing copy/paste)
48
+ * the default mode of `monaco-editor` is `TextDefined` which means if the text
49
+ * contains CR character(s), it will automatically be treated as CRLF. As such, we want
50
+ * an utility method to extract the text value with line ending option LF
51
+ * to force omission of CR characters
52
+ * See https://github.com/finos/legend-studio/issues/608
53
+ */
54
+ export const getCodeEditorValue = (
55
+ editor: monacoEditorAPI.IStandaloneCodeEditor,
56
+ ): string =>
57
+ editor.getModel()?.getValue(monacoEditorAPI.EndOfLinePreference.LF) ?? '';
58
+
59
+ export const getBaseCodeEditorOptions =
60
+ (): monacoEditorAPI.IStandaloneEditorConstructionOptions =>
61
+ ({
62
+ contextmenu: false,
63
+ copyWithSyntaxHighlighting: false,
64
+ // NOTE: These following font options are needed (and CSS font-size option `.monaco-editor * { font-size: ... }` as well)
65
+ // in order to make the editor appear properly on multiple platform, the ligatures option is needed for Mac to display properly
66
+ // otherwise the cursor position relatively to text would be off
67
+ // Another potential cause for this misaligment is that the fonts are being lazy-loaded and made available after `monaco-editor`
68
+ // calculated the font-width, for this, we can use `remeasureFonts`, but our case here, `fontLigatures: true` seems
69
+ // to do the trick
70
+ // See https://github.com/microsoft/monaco-editor/issues/392
71
+ fontSize: 14,
72
+ // Enforce a fixed font-family to make cross platform display consistent (i.e. Mac defaults to use `Menlo` which is bigger than
73
+ // `Consolas` on Windows, etc.)
74
+ fontFamily: 'Roboto Mono',
75
+ // Enable font ligature: glyphs which combine the shapes of certain sequences of characters into a new form that makes for
76
+ // a more harmonious reading experience.
77
+ fontLigatures: true,
78
+ // Make sure hover or widget shown near boundary are not truncated by setting their position to `fixed`
79
+ fixedOverflowWidgets: true,
80
+ detectIndentation: false, // i.e. so we can force tab-size
81
+ tabSize: 2,
82
+ // The typing is currently not correct for `bracketPairColorization`, until this is fixed, we will remove the cast
83
+ // See https://github.com/microsoft/monaco-editor/issues/3013
84
+ 'bracketPairColorization.enabled': false,
85
+ } as monacoEditorAPI.IStandaloneEditorConstructionOptions);
86
+
87
+ export const getBaseConsoleOptions =
88
+ (): monacoEditorAPI.IStandaloneEditorConstructionOptions => ({
89
+ ...getBaseCodeEditorOptions(),
90
+ fontSize: 12,
91
+ extraEditorClassName: 'monaco-editor--small-font',
92
+ readOnly: true,
93
+ glyphMargin: false,
94
+ folding: false,
95
+ lineNumbers: 'off',
96
+ lineDecorationsWidth: 10,
97
+ lineNumbersMinChars: 0,
98
+ minimap: {
99
+ enabled: false,
100
+ },
101
+ guides: {
102
+ bracketPairs: false,
103
+ bracketPairsHorizontal: false,
104
+ highlightActiveBracketPair: false,
105
+ indentation: false,
106
+ highlightActiveIndentation: false,
107
+ },
108
+ renderLineHighlight: 'none',
109
+ });
110
+
111
+ export const moveCursorToPosition = (
112
+ editor: monacoEditorAPI.ICodeEditor,
113
+ position: CodeEditorPosition,
114
+ ): void => {
115
+ if (!editor.hasTextFocus()) {
116
+ editor.focus();
117
+ } // focus the editor first so that it can shows the cursor
118
+ editor.revealPositionInCenter(position, 0);
119
+ editor.setPosition(position);
120
+ };
121
+
122
+ const INTERNAL__DUMMY_PROBLEM_MARKER_OWNER = 'dummy_problem_marker_owner';
123
+
124
+ export const setErrorMarkers = (
125
+ editorModel: monacoEditorAPI.ITextModel,
126
+ errors: {
127
+ message: string;
128
+ startLineNumber: number;
129
+ startColumn: number;
130
+ endLineNumber: number;
131
+ endColumn: number;
132
+ }[],
133
+ ownerId?: string,
134
+ ): void => {
135
+ monacoEditorAPI.setModelMarkers(
136
+ editorModel,
137
+ ownerId ?? INTERNAL__DUMMY_PROBLEM_MARKER_OWNER,
138
+ errors.map((error) => ({
139
+ startLineNumber: error.startLineNumber,
140
+ startColumn: error.startColumn,
141
+ endLineNumber: error.endLineNumber,
142
+ endColumn: error.endColumn + 1, // add a 1 to endColumn as monaco editor range is not inclusive
143
+ // NOTE: when the message is empty, no error tooltip is shown, we want to avoid this
144
+ message: error.message === '' ? '(no error message)' : error.message,
145
+ severity: MarkerSeverity.Error,
146
+ })),
147
+ );
148
+ };
149
+
150
+ export const setWarningMarkers = (
151
+ editorModel: monacoEditorAPI.ITextModel,
152
+ warnings: {
153
+ message: string;
154
+ startLineNumber: number;
155
+ startColumn: number;
156
+ endLineNumber: number;
157
+ endColumn: number;
158
+ }[],
159
+ ownerId?: string,
160
+ ): void => {
161
+ monacoEditorAPI.setModelMarkers(
162
+ editorModel,
163
+ ownerId ?? INTERNAL__DUMMY_PROBLEM_MARKER_OWNER,
164
+ warnings.map((warning) => ({
165
+ startLineNumber: warning.startLineNumber,
166
+ startColumn: warning.startColumn,
167
+ endColumn: warning.endColumn,
168
+ endLineNumber: warning.endLineNumber,
169
+ message:
170
+ warning.message === '' ? '(no warning message)' : warning.message,
171
+ severity: MarkerSeverity.Warning,
172
+ })),
173
+ );
174
+ };
175
+
176
+ export const clearMarkers = (ownerId?: string): void => {
177
+ monacoEditorAPI.removeAllMarkers(
178
+ ownerId ?? INTERNAL__DUMMY_PROBLEM_MARKER_OWNER,
179
+ );
180
+ };
181
+
182
+ /**
183
+ * This method eliminates CR '\r' character(s) in the provided text value.
184
+ */
185
+ export const normalizeLineEnding = (val: string): string =>
186
+ val.replace(/\r/g, '');
187
+
188
+ // We need to dynamically adjust the width of the line number gutter, otherwise as the document gets
189
+ // larger, the left margin will start to shrink
190
+ // See https://github.com/microsoft/monaco-editor/issues/2206
191
+ export const resetLineNumberGutterWidth = (
192
+ editor: monacoEditorAPI.ICodeEditor,
193
+ ): void => {
194
+ const currentValue = editor.getValue();
195
+ editor.updateOptions({
196
+ lineNumbersMinChars: Math.max(
197
+ Math.floor(Math.log10(currentValue.split(/\r\n|\r|\n/g).length)) + 3,
198
+ 5,
199
+ ),
200
+ });
201
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ export * from './CodeEditor.js';
18
+ export * from './CodeEditorUtils.js';
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ export {
18
+ MockedMonacoEditorKeyCode as KeyCode,
19
+ MockedMonacoEditorMarkerSeverity as MarkerSeverity,
20
+ MockedMonacoEditorModel as MOCK__MonacoEditorModel,
21
+ MockedMonacoEditorInstance as MOCK__MonacoEditorInstance,
22
+ MockedMonacoEditorAPI as editor,
23
+ MockedMonacoEditorLanguagesAPI as languages,
24
+ } from './MonacoEditorMockUtils.js';
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { createMock } from '@finos/legend-shared';
18
+
19
+ /**
20
+ * NOTE: we have tried different ways to mock `monaco-editor`. But those ways often involve
21
+ * trying to load `monaco-editor` from `node_modules` and that takes a long time, so we'd better just mock
22
+ * it completely like in this file.
23
+ * See https://gitlab.com/gitlab-org/gitlab/-/issues/119194
24
+ * See https://stackoverflow.com/questions/57731857/cannot-test-jest-with-monaco-editor-unexpected-token
25
+ */
26
+ export enum MockedMonacoEditorKeyCode {
27
+ F1 = 59,
28
+ F8 = 66,
29
+ F9 = 67,
30
+ F10 = 68,
31
+ }
32
+
33
+ export enum MockedMonacoEditorMarkerSeverity {
34
+ Hint = 1,
35
+ Info = 2,
36
+ Warning = 4,
37
+ Error = 8,
38
+ }
39
+
40
+ export enum MockedMonacoEditorEndOfLinePreference {
41
+ LF = 1,
42
+ }
43
+
44
+ export const MockedMonacoEditorModel = {
45
+ dispose: createMock(),
46
+ updateOptions: createMock(),
47
+ getValue: createMock(),
48
+ getLineCount: createMock(),
49
+ getLineMaxColumn: createMock(),
50
+ pushStackElement: createMock(),
51
+ pushEditOperations: createMock(),
52
+ findMatches: createMock(),
53
+ };
54
+
55
+ export const MockedMonacoEditorInstance = {
56
+ dispose: createMock(),
57
+ addCommand: createMock(),
58
+ getValue: createMock(),
59
+ getPosition: createMock(),
60
+ getRawOptions: createMock(),
61
+ getModel: (): typeof MockedMonacoEditorModel => MockedMonacoEditorModel,
62
+ hasTextFocus: createMock(),
63
+ updateOptions: createMock(),
64
+ setValue: createMock(),
65
+ revealPosition: createMock(),
66
+ setPosition: createMock(),
67
+ onKeyDown: createMock(),
68
+ createDecorationsCollection: createMock(),
69
+ onDidChangeModelContent: createMock(),
70
+ onDidChangeCursorPosition: createMock(),
71
+ onDidFocusEditorText: createMock(),
72
+ onDidBlurEditorText: createMock(),
73
+ onDidFocusEditorWidget: createMock(),
74
+ };
75
+
76
+ export const MockedMonacoEditorAPI = {
77
+ create: (): typeof MockedMonacoEditorInstance => MockedMonacoEditorInstance,
78
+ focus: createMock(),
79
+ createModel: createMock(),
80
+ createDiffEditor: () => ({
81
+ getOriginalEditor: (): typeof MockedMonacoEditorInstance =>
82
+ MockedMonacoEditorInstance,
83
+ getModifiedEditor: (): typeof MockedMonacoEditorInstance =>
84
+ MockedMonacoEditorInstance,
85
+ }),
86
+ setModelMarkers: createMock(),
87
+ setModelLanguage: createMock(),
88
+ defineTheme: createMock(),
89
+ EndOfLinePreference: MockedMonacoEditorEndOfLinePreference,
90
+ removeAllMarkers: createMock(),
91
+ };
92
+
93
+ export enum MockedMonacoLanguageCompletionItemKind {
94
+ Keyword = 17,
95
+ Snippet = 27,
96
+ }
97
+
98
+ export enum MockedMonacoLanguageCompletionItemInsertTextRule {
99
+ InsertAsSnippet = 4,
100
+ }
101
+
102
+ export const MockedMonacoEditorLanguagesAPI = {
103
+ register: createMock(),
104
+ setLanguageConfiguration: createMock(),
105
+ setMonarchTokensProvider: createMock(),
106
+ registerCodeLensProvider: createMock(),
107
+ registerHoverProvider: createMock(),
108
+ registerCompletionItemProvider: createMock(),
109
+ CompletionItemKind: MockedMonacoLanguageCompletionItemKind,
110
+ CompletionItemInsertTextRule: MockedMonacoLanguageCompletionItemKind,
111
+ };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ export * from './MonacoEditorMockUtils.js';
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import {
18
+ AgGridReact,
19
+ type AgReactUiProps,
20
+ type AgGridReactProps,
21
+ } from '@ag-grid-community/react';
22
+ import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
23
+ import {
24
+ type CellMouseOverEvent,
25
+ type ICellRendererParams,
26
+ ModuleRegistry,
27
+ } from '@ag-grid-community/core';
28
+
29
+ export function DataGrid<TData = unknown>(
30
+ props: AgGridReactProps<TData> | AgReactUiProps<TData>,
31
+ ): JSX.Element {
32
+ return <AgGridReact {...props} modules={[ClientSideRowModelModule]} />;
33
+ }
34
+
35
+ export const configureDataGridComponent = (): void => {
36
+ ModuleRegistry.registerModules([ClientSideRowModelModule]);
37
+ };
38
+
39
+ export type {
40
+ CellMouseOverEvent as DataGridCellMouseOverEvent,
41
+ ICellRendererParams as DataGridCellRendererParams,
42
+ };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ export * from './DataGrid.js';
package/tsconfig.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": [
4
+ "dom",
5
+ "dom.iterable",
6
+ "esnext",
7
+ "webworker",
8
+ "scripthost"
9
+ ],
10
+ "composite": true,
11
+ "declaration": true,
12
+ "declarationMap": true,
13
+ "sourceMap": true,
14
+ "target": "esnext",
15
+ "module": "nodenext",
16
+ "skipLibCheck": true,
17
+ "resolveJsonModule": true,
18
+ "verbatimModuleSyntax": true,
19
+ "strict": true,
20
+ "noImplicitOverride": true,
21
+ "noUncheckedIndexedAccess": true,
22
+ "exactOptionalPropertyTypes": true,
23
+ "forceConsistentCasingInFileNames": true,
24
+ "outDir": "./lib",
25
+ "tsBuildInfoFile": "./build/prod.tsbuildinfo",
26
+ "rootDir": "./src",
27
+ "jsx": "react-jsx"
28
+ },
29
+ "files": [
30
+ "./src/code-editor/CodeEditorUtils.ts",
31
+ "./src/code-editor/index.ts",
32
+ "./src/code-editor/testing/MockedMonacoEditor.ts",
33
+ "./src/code-editor/testing/index.ts",
34
+ "./src/data-grid/index.ts",
35
+ "./src/code-editor/CodeEditor.tsx",
36
+ "./src/code-editor/testing/MonacoEditorMockUtils.tsx",
37
+ "./src/data-grid/DataGrid.tsx"
38
+ ],
39
+ "include": [
40
+ "src/**/*.ts",
41
+ "src/**/*.tsx",
42
+ "src/**/*.json"
43
+ ],
44
+ "exclude": [
45
+ "src/**/__tests__/**/*.*",
46
+ "src/**/__mocks__/**/*.*"
47
+ ]
48
+ }