@fc-components/monaco-editor 0.3.1 → 0.3.3
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/dist/monaco-editor.cjs.development.js +68 -5
- package/dist/monaco-editor.cjs.development.js.map +1 -1
- package/dist/monaco-editor.cjs.production.min.js +1 -1
- package/dist/monaco-editor.cjs.production.min.js.map +1 -1
- package/dist/monaco-editor.esm.js +69 -6
- package/dist/monaco-editor.esm.js.map +1 -1
- package/dist/sql/format.d.ts +1 -0
- package/dist/sql/index.d.ts +9 -2
- package/package.json +2 -1
- package/src/sql/format.ts +13 -0
- package/src/sql/index.tsx +89 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatSql(sql: string): string;
|
package/dist/sql/index.d.ts
CHANGED
|
@@ -16,6 +16,13 @@ interface SqlEditorProps {
|
|
|
16
16
|
onBlur?: (value: string) => void;
|
|
17
17
|
onFocus?: (value: string) => void;
|
|
18
18
|
editorDidMount?: (editor: monacoTypes.editor.IStandaloneCodeEditor) => void;
|
|
19
|
+
/** Whether to show the format button. Default: false */
|
|
20
|
+
enableFormat?: boolean;
|
|
21
|
+
/** Custom format button renderer */
|
|
22
|
+
renderFormatButton?: (handleFormat: () => void) => React.ReactNode;
|
|
19
23
|
}
|
|
20
|
-
export
|
|
21
|
-
|
|
24
|
+
export interface SqlEditorHandle {
|
|
25
|
+
format: () => void;
|
|
26
|
+
}
|
|
27
|
+
declare const SqlEditor: React.ForwardRefExoticComponent<SqlEditorProps & React.RefAttributes<SqlEditorHandle>>;
|
|
28
|
+
export default SqlEditor;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.3.
|
|
6
|
+
"version": "0.3.3",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"module": "dist/monaco-editor.esm.js",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"monaco-promql": "^1.7.4",
|
|
59
59
|
"pluralize": "^8.0.0",
|
|
60
60
|
"react-monaco-editor": "^0.58.0",
|
|
61
|
+
"sql-formatter": "^15.8.0",
|
|
61
62
|
"uuidv4": "^6.2.13"
|
|
62
63
|
}
|
|
63
64
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { format } from 'sql-formatter';
|
|
2
|
+
|
|
3
|
+
export function formatSql(sql: string): string {
|
|
4
|
+
try {
|
|
5
|
+
return format(sql, {
|
|
6
|
+
tabWidth: 2,
|
|
7
|
+
keywordCase: 'upper',
|
|
8
|
+
});
|
|
9
|
+
} catch {
|
|
10
|
+
// If formatting fails, return the original SQL
|
|
11
|
+
return sql;
|
|
12
|
+
}
|
|
13
|
+
}
|
package/src/sql/index.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useRef } from 'react';
|
|
1
|
+
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from 'react';
|
|
2
2
|
import MonacoEditor from 'react-monaco-editor';
|
|
3
3
|
import * as monaco from 'monaco-editor';
|
|
4
4
|
import type * as monacoTypes from 'monaco-editor/esm/vs/editor/editor.api';
|
|
@@ -6,6 +6,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
6
6
|
import { css } from '@emotion/css';
|
|
7
7
|
import { language, languageConfiguration } from './sql';
|
|
8
8
|
import { getSqlCompletionProvider } from './completion/getCompletionProvider';
|
|
9
|
+
import { formatSql } from './format';
|
|
9
10
|
|
|
10
11
|
interface SqlEditorProps {
|
|
11
12
|
className?: string;
|
|
@@ -23,6 +24,14 @@ interface SqlEditorProps {
|
|
|
23
24
|
onBlur?: (value: string) => void;
|
|
24
25
|
onFocus?: (value: string) => void;
|
|
25
26
|
editorDidMount?: (editor: monacoTypes.editor.IStandaloneCodeEditor) => void;
|
|
27
|
+
/** Whether to show the format button. Default: false */
|
|
28
|
+
enableFormat?: boolean;
|
|
29
|
+
/** Custom format button renderer */
|
|
30
|
+
renderFormatButton?: (handleFormat: () => void) => React.ReactNode;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface SqlEditorHandle {
|
|
34
|
+
format: () => void;
|
|
26
35
|
}
|
|
27
36
|
|
|
28
37
|
const SQL_LANG_ID = 'sql';
|
|
@@ -73,7 +82,31 @@ const containerReadOnlyClassName = css`
|
|
|
73
82
|
}
|
|
74
83
|
`;
|
|
75
84
|
|
|
76
|
-
|
|
85
|
+
const formatBtnClassName = css`
|
|
86
|
+
position: absolute;
|
|
87
|
+
top: 4px;
|
|
88
|
+
right: 4px;
|
|
89
|
+
z-index: 10;
|
|
90
|
+
display: flex;
|
|
91
|
+
align-items: center;
|
|
92
|
+
justify-content: center;
|
|
93
|
+
width: 24px;
|
|
94
|
+
height: 24px;
|
|
95
|
+
padding: 0;
|
|
96
|
+
border: none;
|
|
97
|
+
background: transparent;
|
|
98
|
+
border-radius: 4px;
|
|
99
|
+
cursor: pointer;
|
|
100
|
+
color: inherit;
|
|
101
|
+
opacity: 1;
|
|
102
|
+
transition: opacity 0.15s;
|
|
103
|
+
|
|
104
|
+
&:hover {
|
|
105
|
+
background: var(--format-btn-hover-bg, rgba(128, 128, 128, 0.15));
|
|
106
|
+
}
|
|
107
|
+
`;
|
|
108
|
+
|
|
109
|
+
const SqlEditor = forwardRef<SqlEditorHandle, SqlEditorProps>((props, ref) => {
|
|
77
110
|
const id = uuidv4();
|
|
78
111
|
const {
|
|
79
112
|
className,
|
|
@@ -83,6 +116,7 @@ export default function SqlEditor(props: SqlEditorProps) {
|
|
|
83
116
|
theme = 'light',
|
|
84
117
|
value = '',
|
|
85
118
|
placeholder,
|
|
119
|
+
enableFormat = false,
|
|
86
120
|
enableAutocomplete = true,
|
|
87
121
|
readOnly = false,
|
|
88
122
|
disabled = false,
|
|
@@ -91,6 +125,7 @@ export default function SqlEditor(props: SqlEditorProps) {
|
|
|
91
125
|
onBlur,
|
|
92
126
|
onFocus,
|
|
93
127
|
editorDidMount,
|
|
128
|
+
renderFormatButton,
|
|
94
129
|
} = props;
|
|
95
130
|
|
|
96
131
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
@@ -223,6 +258,18 @@ export default function SqlEditor(props: SqlEditorProps) {
|
|
|
223
258
|
editorDidMount?.(editor);
|
|
224
259
|
};
|
|
225
260
|
|
|
261
|
+
const handleFormat = useCallback(() => {
|
|
262
|
+
const editor = editorRef.current;
|
|
263
|
+
if (!editor) return;
|
|
264
|
+
const currentValue = editor.getValue();
|
|
265
|
+
const formatted = formatSql(currentValue);
|
|
266
|
+
editor.setValue(formatted);
|
|
267
|
+
}, []);
|
|
268
|
+
|
|
269
|
+
useImperativeHandle(ref, () => ({
|
|
270
|
+
format: handleFormat,
|
|
271
|
+
}));
|
|
272
|
+
|
|
226
273
|
const themeValue = themeMap[theme];
|
|
227
274
|
|
|
228
275
|
return (
|
|
@@ -238,6 +285,7 @@ export default function SqlEditor(props: SqlEditorProps) {
|
|
|
238
285
|
display: 'block',
|
|
239
286
|
resize: 'vertical',
|
|
240
287
|
overflow: 'auto',
|
|
288
|
+
position: 'relative',
|
|
241
289
|
minHeight: SIZE_MAP[size].minHeight,
|
|
242
290
|
maxHeight,
|
|
243
291
|
}}
|
|
@@ -285,6 +333,44 @@ export default function SqlEditor(props: SqlEditorProps) {
|
|
|
285
333
|
}}
|
|
286
334
|
/>
|
|
287
335
|
</div>
|
|
336
|
+
{enableFormat &&
|
|
337
|
+
(renderFormatButton ? (
|
|
338
|
+
renderFormatButton(handleFormat)
|
|
339
|
+
) : (
|
|
340
|
+
<button
|
|
341
|
+
onClick={handleFormat}
|
|
342
|
+
className={formatBtnClassName}
|
|
343
|
+
title='Format SQL'
|
|
344
|
+
style={
|
|
345
|
+
{
|
|
346
|
+
'--format-btn-hover-bg': theme === 'dark' ? 'rgba(255,255,255,0.2)' : 'rgba(128,128,128,0.15)',
|
|
347
|
+
} as React.CSSProperties
|
|
348
|
+
}
|
|
349
|
+
>
|
|
350
|
+
<svg
|
|
351
|
+
xmlns='http://www.w3.org/2000/svg'
|
|
352
|
+
width='12'
|
|
353
|
+
height='12'
|
|
354
|
+
viewBox='0 0 24 24'
|
|
355
|
+
fill='none'
|
|
356
|
+
stroke='currentColor'
|
|
357
|
+
strokeWidth='1'
|
|
358
|
+
strokeLinecap='round'
|
|
359
|
+
strokeLinejoin='round'
|
|
360
|
+
>
|
|
361
|
+
<path d='m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72' />
|
|
362
|
+
<path d='m14 7 3 3' />
|
|
363
|
+
<path d='M5 6v4' />
|
|
364
|
+
<path d='M19 14v4' />
|
|
365
|
+
<path d='M10 2v2' />
|
|
366
|
+
<path d='M7 8H3' />
|
|
367
|
+
<path d='M21 16h-4' />
|
|
368
|
+
<path d='M11 3H9' />
|
|
369
|
+
</svg>
|
|
370
|
+
</button>
|
|
371
|
+
))}
|
|
288
372
|
</div>
|
|
289
373
|
);
|
|
290
|
-
}
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
export default SqlEditor;
|