@finos/legend-lego 0.1.0

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.
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
+ }