@fc-components/monaco-editor 0.1.27 → 0.3.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.
Files changed (36) hide show
  1. package/dist/expr/__tests__/__mocks__/monaco-editor.d.ts +28 -0
  2. package/dist/expr/completion/getCompletionProvider.d.ts +4 -0
  3. package/dist/expr/expr.d.ts +83 -0
  4. package/dist/expr/index.d.ts +3 -0
  5. package/dist/expr/parser/index.d.ts +3 -0
  6. package/dist/expr/parser/lexer.d.ts +27 -0
  7. package/dist/expr/parser/parser.d.ts +66 -0
  8. package/dist/expr/parser/types.d.ts +32 -0
  9. package/dist/expr/types.d.ts +17 -0
  10. package/dist/expr/validation.d.ts +12 -0
  11. package/dist/index.d.ts +2 -0
  12. package/dist/monaco-editor.cjs.development.js +1986 -3
  13. package/dist/monaco-editor.cjs.development.js.map +1 -1
  14. package/dist/monaco-editor.cjs.production.min.js +1 -1
  15. package/dist/monaco-editor.cjs.production.min.js.map +1 -1
  16. package/dist/monaco-editor.esm.js +1989 -7
  17. package/dist/monaco-editor.esm.js.map +1 -1
  18. package/dist/promql/completion/situation.d.ts +2 -0
  19. package/package.json +6 -2
  20. package/src/expr/__tests__/__mocks__/monaco-editor.ts +34 -0
  21. package/src/expr/__tests__/expr.test.tsx +339 -0
  22. package/src/expr/completion/getCompletionProvider.ts +133 -0
  23. package/src/expr/expr.ts +229 -0
  24. package/src/expr/index.tsx +322 -0
  25. package/src/expr/parser/index.ts +3 -0
  26. package/src/expr/parser/lexer.ts +377 -0
  27. package/src/expr/parser/parser.ts +581 -0
  28. package/src/expr/parser/types.ts +77 -0
  29. package/src/expr/types.ts +17 -0
  30. package/src/expr/validation.ts +209 -0
  31. package/src/index.tsx +2 -0
  32. package/src/promql/__tests__/completions.test.ts +72 -0
  33. package/src/promql/__tests__/situation.test.ts +85 -0
  34. package/src/promql/completion/completions.ts +11 -2
  35. package/src/promql/completion/situation.ts +65 -1
  36. package/src/promql/promql.ts +3 -1
@@ -0,0 +1,581 @@
1
+ /**
2
+ * Expr-lang recursive descent parser
3
+ * Ported from Go's expr-lang parser with precedence climbing algorithm
4
+ */
5
+
6
+ import { Lexer } from './lexer';
7
+ import { Token, TokenKind, ParseError, EOF_TOKEN, OPERATOR_PRECEDENCE, UNARY_OPERATORS, COMPARISON_OPERATORS } from './types';
8
+
9
+ export class ExprParser {
10
+ private lexer: Lexer;
11
+ private current: Token = { ...EOF_TOKEN };
12
+ private errors: ParseError[] = [];
13
+
14
+ constructor() {
15
+ this.lexer = new Lexer();
16
+ }
17
+
18
+ /**
19
+ * Parse an expr-lang expression and return any syntax errors.
20
+ * Returns empty array if the expression is valid.
21
+ */
22
+ parse(input: string): ParseError[] {
23
+ this.errors = [];
24
+ this.lexer.reset(input);
25
+ this.advance();
26
+
27
+ if (input.trim().length === 0) {
28
+ return [];
29
+ }
30
+
31
+ this.parseSequenceExpression();
32
+
33
+ // Check for unexpected tokens at the end
34
+ if (this.curKind() !== TokenKind.EOF && this.errors.length === 0) {
35
+ this.error(`unexpected token "${this.curVal()}"`);
36
+ }
37
+
38
+ return this.errors;
39
+ }
40
+
41
+ private advance(): void {
42
+ this.current = this.lexer.next();
43
+ }
44
+
45
+ private curKind(): TokenKind {
46
+ return this.current.kind;
47
+ }
48
+
49
+ private curVal(): string {
50
+ return this.current.value;
51
+ }
52
+
53
+ private expect(kind: TokenKind, value?: string): boolean {
54
+ if (this.curKind() === kind && (value === undefined || this.curVal() === value)) {
55
+ this.advance();
56
+ return true;
57
+ }
58
+ if (value) {
59
+ this.error(`expected "${value}" but got "${this.curVal()}"`);
60
+ } else {
61
+ this.error(`unexpected token "${this.curVal()}"`);
62
+ }
63
+ return false;
64
+ }
65
+
66
+ private error(message: string): void {
67
+ if (this.errors.length === 0) {
68
+ // Calculate end position — approximate
69
+ const endLine = this.current.line;
70
+ const endColumn = this.current.column + this.curVal().length;
71
+
72
+ this.errors.push({
73
+ message,
74
+ startLine: this.current.line,
75
+ startColumn: this.current.column,
76
+ endLine,
77
+ endColumn,
78
+ });
79
+ }
80
+ }
81
+
82
+ private errorAt(token: Token, message: string): void {
83
+ if (this.errors.length === 0) {
84
+ const endColumn = token.column + token.value.length;
85
+ this.errors.push({
86
+ message,
87
+ startLine: token.line,
88
+ startColumn: token.column,
89
+ endLine: token.line,
90
+ endColumn,
91
+ });
92
+ }
93
+ }
94
+
95
+ // ========== Parsing Functions ==========
96
+
97
+ /**
98
+ * parseSequenceExpression parses multiple expressions separated by semicolons.
99
+ */
100
+ private parseSequenceExpression(): void {
101
+ if (this.errors.length > 0) return;
102
+ this.parseExpression(0);
103
+
104
+ while (this.curVal() === ';' && this.errors.length === 0) {
105
+ this.advance();
106
+ if (this.curKind() === TokenKind.EOF) break;
107
+ this.parseExpression(0);
108
+ }
109
+ }
110
+
111
+ /**
112
+ * parseExpression uses precedence climbing to parse binary expressions.
113
+ */
114
+ private parseExpression(precedence: number): void {
115
+ if (this.errors.length > 0) return;
116
+
117
+ // Handle "let" at precedence 0
118
+ if (precedence === 0 && this.curVal() === 'let') {
119
+ this.parseVariableDeclaration();
120
+ return;
121
+ }
122
+
123
+ // Handle "if" at precedence 0
124
+ if (precedence === 0 && this.curVal() === 'if') {
125
+ this.parseConditionalIf();
126
+ return;
127
+ }
128
+
129
+ // Handle unary operators
130
+ if (UNARY_OPERATORS.has(this.curVal()) && this.curKind() === TokenKind.Operator) {
131
+ const unaryToken = this.current;
132
+ this.advance();
133
+ if (this.curKind() === TokenKind.EOF) {
134
+ this.errorAt(unaryToken, 'unexpected token EOF');
135
+ return;
136
+ }
137
+ if (this.errors.length > 0) return;
138
+ this.parsePrimary();
139
+ if (this.errors.length > 0) return;
140
+ this.parsePostfixExpression();
141
+ return;
142
+ }
143
+
144
+ this.parsePrimary();
145
+ if (this.errors.length > 0) return;
146
+ this.parsePostfixExpression();
147
+ if (this.errors.length > 0) return;
148
+
149
+ // Handle binary operators with precedence climbing
150
+ while (this.curKind() === TokenKind.Operator && this.errors.length === 0) {
151
+ const op = this.curVal();
152
+ const opToken = this.current;
153
+
154
+ // Handle pipe operator |
155
+ if (op === '|') {
156
+ this.advance(); // skip |
157
+ if (this.curKind() === TokenKind.EOF) {
158
+ this.errorAt(opToken, 'unexpected token EOF');
159
+ return;
160
+ }
161
+ if (this.curKind() === TokenKind.Identifier) {
162
+ this.advance(); // skip identifier
163
+ this.parseArguments();
164
+ if (this.curVal() === ';') break;
165
+ continue;
166
+ }
167
+ this.error(`expected identifier after pipe "|" but got "${this.curVal()}"`);
168
+ return;
169
+ }
170
+
171
+ // Handle semicolon — end of this expression
172
+ if (op === ';') break;
173
+
174
+ // Check precedence
175
+ const opPrec = OPERATOR_PRECEDENCE[op];
176
+ if (opPrec === undefined || opPrec < precedence) break;
177
+
178
+ // Handle "not" prefix for "not in", "not contains", etc.
179
+ if (op === 'not') {
180
+ this.advance();
181
+ const nextOp = this.curVal();
182
+ const negatedPrec = OPERATOR_PRECEDENCE[nextOp];
183
+ if (negatedPrec !== undefined && negatedPrec >= precedence) {
184
+ this.advance();
185
+ this.parseExpression(negatedPrec + 1);
186
+ continue;
187
+ }
188
+ this.error(`unexpected token "${nextOp}" after "not"`);
189
+ return;
190
+ }
191
+
192
+ // Handle chained comparisons: a < b < c => (a < b) && (b < c)
193
+ if (COMPARISON_OPERATORS.has(op)) {
194
+ this.advance();
195
+ if (this.curKind() === TokenKind.EOF) {
196
+ this.errorAt(opToken, 'unexpected token EOF');
197
+ return;
198
+ }
199
+ this.parseExpression(opPrec + 1);
200
+ // Keep parsing chained comparisons
201
+ while (this.curKind() === TokenKind.Operator && COMPARISON_OPERATORS.has(this.curVal()) && this.errors.length === 0) {
202
+ const chainOpToken = this.current;
203
+ this.advance();
204
+ if (this.curKind() === TokenKind.EOF) {
205
+ this.errorAt(chainOpToken, 'unexpected token EOF');
206
+ return;
207
+ }
208
+ this.parseExpression((OPERATOR_PRECEDENCE[this.curVal()] || 0) + 1);
209
+ }
210
+ continue;
211
+ }
212
+
213
+ this.advance();
214
+
215
+ if (this.curKind() === TokenKind.EOF) {
216
+ this.errorAt(opToken, 'unexpected token EOF');
217
+ return;
218
+ }
219
+
220
+ // Right-associative operators bind to the right
221
+ // For simplicity, parse with same precedence for right-assoc
222
+ this.parseExpression(opPrec + 1);
223
+
224
+ // Handle ternary ? :
225
+ if (precedence === 0 && this.curVal() === '?') {
226
+ this.parseConditional();
227
+ }
228
+ }
229
+
230
+ // Handle ternary ? : at precedence 0
231
+ if (precedence === 0 && this.curVal() === '?') {
232
+ this.parseConditional();
233
+ }
234
+ }
235
+
236
+ /**
237
+ * parsePrimary handles unary operators, parentheses, and the #/. pointer prefix.
238
+ */
239
+ private parsePrimary(): void {
240
+ if (this.errors.length > 0) return;
241
+
242
+ // Unary operators are handled in parseExpression
243
+
244
+ // Parenthesized expression
245
+ if (this.curKind() === TokenKind.Bracket && this.curVal() === '(') {
246
+ this.advance(); // skip (
247
+ this.parseSequenceExpression();
248
+ if (!this.expect(TokenKind.Bracket, ')')) {
249
+ return;
250
+ }
251
+ return;
252
+ }
253
+
254
+ // Handle # or . prefix (in predicates)
255
+ if ((this.curVal() === '#' || this.curVal() === '.') && this.curKind() === TokenKind.Operator) {
256
+ this.advance();
257
+ if (this.curKind() === TokenKind.Identifier) {
258
+ this.advance();
259
+ }
260
+ this.parsePostfixExpression();
261
+ return;
262
+ }
263
+
264
+ this.parseSecondary();
265
+ }
266
+
267
+ /**
268
+ * parseSecondary handles identifiers, literals, arrays, and maps.
269
+ */
270
+ private parseSecondary(): void {
271
+ if (this.errors.length > 0) return;
272
+
273
+ const token = this.current;
274
+
275
+ switch (token.kind) {
276
+ case TokenKind.Identifier: {
277
+ this.advance();
278
+ // Check for function call
279
+ if (this.curKind() === TokenKind.Bracket && this.curVal() === '(') {
280
+ this.parseArguments();
281
+ }
282
+ break;
283
+ }
284
+
285
+ case TokenKind.Number: {
286
+ this.advance();
287
+ break;
288
+ }
289
+
290
+ case TokenKind.String: {
291
+ this.advance();
292
+ break;
293
+ }
294
+
295
+ case TokenKind.Bracket: {
296
+ if (token.value === '[') {
297
+ this.parseArrayExpression();
298
+ } else if (token.value === '{') {
299
+ this.parseMapExpression();
300
+ } else {
301
+ this.error(`unexpected token "${token.value}"`);
302
+ }
303
+ break;
304
+ }
305
+
306
+ default:
307
+ this.error(`unexpected token "${token.value}"`);
308
+ break;
309
+ }
310
+ }
311
+
312
+ /**
313
+ * parsePostfixExpression handles .member, ?.member, [index], [from:to], and calls after the primary.
314
+ */
315
+ private parsePostfixExpression(): void {
316
+ while (this.errors.length === 0) {
317
+ const token = this.current;
318
+
319
+ // .member or ?.member
320
+ if (token.kind === TokenKind.Operator && (token.value === '.' || token.value === '?.')) {
321
+ this.advance();
322
+ // After . or ?., expect an identifier (or operator like "not" that can be a method name)
323
+ if (this.curKind() === TokenKind.Identifier || this.curKind() === TokenKind.Operator) {
324
+ this.advance();
325
+ // Check for method call: obj.method()
326
+ if (this.curKind() === TokenKind.Bracket && this.curVal() === '(') {
327
+ this.parseArguments();
328
+ }
329
+ } else if (this.curKind() === TokenKind.Bracket && this.curVal() === '[' && token.value === '?.') {
330
+ // obj?[index] — handle bracket after ?.
331
+ this.advance();
332
+ this.parseExpression(0);
333
+ this.expect(TokenKind.Bracket, ']');
334
+ } else {
335
+ this.error(`expected property name after "${token.value}" but got "${this.curVal()}"`);
336
+ return;
337
+ }
338
+ continue;
339
+ }
340
+
341
+ // [index] or [from:to]
342
+ if (token.kind === TokenKind.Bracket && token.value === '[') {
343
+ this.advance();
344
+
345
+ // Check for slice: [:] or [:to]
346
+ if (this.curKind() === TokenKind.Operator && this.curVal() === ':') {
347
+ this.advance();
348
+ if (this.curKind() !== TokenKind.Bracket || this.curVal() !== ']') {
349
+ this.parseExpression(0);
350
+ }
351
+ this.expect(TokenKind.Bracket, ']');
352
+ } else {
353
+ // Index expression
354
+ this.parseExpression(0);
355
+
356
+ // Check for slice: [from:]
357
+ if (this.curKind() === TokenKind.Operator && this.curVal() === ':') {
358
+ this.advance();
359
+ if (this.curKind() !== TokenKind.Bracket || this.curVal() !== ']') {
360
+ this.parseExpression(0);
361
+ }
362
+ }
363
+ this.expect(TokenKind.Bracket, ']');
364
+ }
365
+ continue;
366
+ }
367
+
368
+ // Function call after member access
369
+ if (token.kind === TokenKind.Bracket && token.value === '(') {
370
+ this.parseArguments();
371
+ continue;
372
+ }
373
+
374
+ break;
375
+ }
376
+ }
377
+
378
+ /**
379
+ * parseVariableDeclaration parses "let name = value; rest"
380
+ */
381
+ private parseVariableDeclaration(): void {
382
+ this.expect(TokenKind.Operator, 'let');
383
+ if (this.errors.length > 0) return;
384
+
385
+ if (this.curKind() !== TokenKind.Identifier) {
386
+ this.error(`expected variable name after "let" but got "${this.curVal()}"`);
387
+ return;
388
+ }
389
+ this.advance(); // skip variable name
390
+
391
+ if (!this.expect(TokenKind.Operator, '=')) return;
392
+
393
+ this.parseExpression(0);
394
+ if (this.errors.length > 0) return;
395
+
396
+ // Optional semicolon after value
397
+ if (this.curVal() === ';') {
398
+ this.advance();
399
+ if (this.curKind() !== TokenKind.EOF) {
400
+ this.parseSequenceExpression();
401
+ }
402
+ }
403
+ }
404
+
405
+ /**
406
+ * parseConditionalIf parses "if expr { expr1 } else { expr2 }" or "if expr { expr1 } else if ..."
407
+ */
408
+ private parseConditionalIf(): void {
409
+ this.advance(); // skip 'if'
410
+ if (this.errors.length > 0) return;
411
+
412
+ this.parseExpression(0);
413
+ if (this.errors.length > 0) return;
414
+
415
+ if (!this.expect(TokenKind.Bracket, '{')) return;
416
+
417
+ this.parseSequenceExpression();
418
+ if (this.errors.length > 0) return;
419
+
420
+ if (!this.expect(TokenKind.Bracket, '}')) return;
421
+
422
+ if (!this.expect(TokenKind.Operator, 'else')) return;
423
+
424
+ // Nested if
425
+ if (this.curVal() === 'if') {
426
+ this.parseConditionalIf();
427
+ return;
428
+ }
429
+
430
+ if (!this.expect(TokenKind.Bracket, '{')) return;
431
+ this.parseSequenceExpression();
432
+ if (this.errors.length > 0) return;
433
+ this.expect(TokenKind.Bracket, '}');
434
+ }
435
+
436
+ /**
437
+ * parseConditional parses "expr ? expr1 : expr2" or "expr ?: expr2"
438
+ */
439
+ private parseConditional(): void {
440
+ if (this.curVal() !== '?') return;
441
+ this.advance(); // skip ?
442
+
443
+ // Elvis operator ?:
444
+ if (this.curVal() === ':') {
445
+ this.advance();
446
+ this.parseExpression(0);
447
+ return;
448
+ }
449
+
450
+ this.parseExpression(0);
451
+ if (this.errors.length > 0) return;
452
+
453
+ if (!this.expect(TokenKind.Operator, ':')) return;
454
+ this.parseExpression(0);
455
+ }
456
+
457
+ /**
458
+ * parseArguments parses function call arguments: (arg1, arg2, ...)
459
+ */
460
+ private parseArguments(): void {
461
+ if (!this.expect(TokenKind.Bracket, '(')) return;
462
+
463
+ while (this.curKind() !== TokenKind.Bracket || this.curVal() !== ')') {
464
+ if (this.curKind() === TokenKind.EOF) {
465
+ this.error('unexpected end of expression, expected ")"');
466
+ return;
467
+ }
468
+
469
+ if (this.curVal() === ',') {
470
+ this.advance();
471
+ continue;
472
+ }
473
+
474
+ // Check for predicate { ... } argument
475
+ if (this.curKind() === TokenKind.Bracket && this.curVal() === '{') {
476
+ this.advance();
477
+ this.parseSequenceExpression();
478
+ this.expect(TokenKind.Bracket, '}');
479
+ } else {
480
+ this.parseExpression(0);
481
+ }
482
+
483
+ if (this.errors.length > 0) return;
484
+
485
+ if (this.curVal() === ',') {
486
+ this.advance();
487
+ // Allow trailing comma
488
+ if (this.curKind() === TokenKind.Bracket && this.curVal() === ')') {
489
+ break;
490
+ }
491
+ }
492
+ }
493
+
494
+ this.expect(TokenKind.Bracket, ')');
495
+ }
496
+
497
+ /**
498
+ * parseArrayExpression parses "[elem1, elem2, ...]"
499
+ */
500
+ private parseArrayExpression(): void {
501
+ this.expect(TokenKind.Bracket, '[');
502
+ if (this.errors.length > 0) return;
503
+
504
+ if (this.curKind() === TokenKind.Bracket && this.curVal() === ']') {
505
+ this.advance();
506
+ return;
507
+ }
508
+
509
+ while (this.errors.length === 0) {
510
+ this.parseExpression(0);
511
+ if (this.errors.length > 0) return;
512
+
513
+ if (this.curKind() === TokenKind.Bracket && this.curVal() === ']') {
514
+ break;
515
+ }
516
+
517
+ if (this.curVal() === ',') {
518
+ this.advance();
519
+ // Allow trailing comma
520
+ if (this.curKind() === TokenKind.Bracket && this.curVal() === ']') {
521
+ break;
522
+ }
523
+ continue;
524
+ }
525
+
526
+ this.error(`expected "," or "]" but got "${this.curVal()}"`);
527
+ return;
528
+ }
529
+
530
+ this.expect(TokenKind.Bracket, ']');
531
+ }
532
+
533
+ /**
534
+ * parseMapExpression parses "{key: value, ...}"
535
+ */
536
+ private parseMapExpression(): void {
537
+ this.expect(TokenKind.Bracket, '{');
538
+ if (this.errors.length > 0) return;
539
+
540
+ if (this.curKind() === TokenKind.Bracket && this.curVal() === '}') {
541
+ this.advance();
542
+ return;
543
+ }
544
+
545
+ while (this.errors.length === 0) {
546
+ // Key: identifier, string, number, or parenthesized expression
547
+ if (this.curKind() === TokenKind.Identifier || this.curKind() === TokenKind.String || this.curKind() === TokenKind.Number) {
548
+ this.advance();
549
+ } else if (this.curKind() === TokenKind.Bracket && this.curVal() === '(') {
550
+ this.advance();
551
+ this.parseExpression(0);
552
+ this.expect(TokenKind.Bracket, ')');
553
+ } else {
554
+ this.error(`map key must be a string, number, identifier, or parenthesized expression, got "${this.curVal()}"`);
555
+ return;
556
+ }
557
+
558
+ if (!this.expect(TokenKind.Operator, ':')) return;
559
+
560
+ this.parseExpression(0);
561
+ if (this.errors.length > 0) return;
562
+
563
+ if (this.curKind() === TokenKind.Bracket && this.curVal() === '}') {
564
+ break;
565
+ }
566
+
567
+ if (this.curVal() === ',') {
568
+ this.advance();
569
+ if (this.curKind() === TokenKind.Bracket && this.curVal() === '}') {
570
+ break;
571
+ }
572
+ continue;
573
+ }
574
+
575
+ this.error(`expected "," or "}" but got "${this.curVal()}"`);
576
+ return;
577
+ }
578
+
579
+ this.expect(TokenKind.Bracket, '}');
580
+ }
581
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Expr-lang token types and AST definitions
3
+ */
4
+
5
+ export enum TokenKind {
6
+ Identifier = 'Identifier',
7
+ Number = 'Number',
8
+ String = 'String',
9
+ Operator = 'Operator',
10
+ Bracket = 'Bracket',
11
+ EOF = 'EOF',
12
+ }
13
+
14
+ export interface Token {
15
+ kind: TokenKind;
16
+ value: string;
17
+ start: number;
18
+ end: number;
19
+ line: number;
20
+ column: number;
21
+ }
22
+
23
+ export interface ParseError {
24
+ message: string;
25
+ startLine: number;
26
+ startColumn: number;
27
+ endLine: number;
28
+ endColumn: number;
29
+ }
30
+
31
+ export const EOF_TOKEN: Token = {
32
+ kind: TokenKind.EOF,
33
+ value: '',
34
+ start: 0,
35
+ end: 0,
36
+ line: 0,
37
+ column: 0,
38
+ };
39
+
40
+ // Operator precedence (higher = binds tighter)
41
+ export const OPERATOR_PRECEDENCE: Record<string, number> = {
42
+ '??': 1,
43
+ '||': 2,
44
+ or: 2,
45
+ '&&': 3,
46
+ and: 3,
47
+ '==': 4,
48
+ '!=': 4,
49
+ '<': 5,
50
+ '>': 5,
51
+ '<=': 5,
52
+ '>=': 5,
53
+ in: 5,
54
+ matches: 5,
55
+ contains: 5,
56
+ startsWith: 5,
57
+ endsWith: 5,
58
+ '+': 6,
59
+ '-': 6,
60
+ '*': 7,
61
+ '/': 7,
62
+ '%': 7,
63
+ '^': 8,
64
+ '**': 8,
65
+ };
66
+
67
+ // Unary operators
68
+ export const UNARY_OPERATORS = new Set(['!', 'not', '-']);
69
+
70
+ // Right-associative operators
71
+ export const RIGHT_ASSOCIATIVE = new Set(['**', '^']);
72
+
73
+ // Comparison operators (for chained comparisons)
74
+ export const COMPARISON_OPERATORS = new Set(['<', '>', '<=', '>=', '==', '!=']);
75
+
76
+ // Keywords
77
+ export const KEYWORDS = new Set(['let', 'true', 'false', 'nil', 'in', 'not', 'and', 'or', 'if', 'else']);
@@ -0,0 +1,17 @@
1
+ export interface ExprEditorProps {
2
+ className?: string;
3
+ maxHeight?: number | string;
4
+ fontSize?: number;
5
+ size?: 'small' | 'middle' | 'large';
6
+ theme?: 'light' | 'dark';
7
+ value?: string;
8
+ placeholder?: string;
9
+ enableAutocomplete?: boolean;
10
+ readOnly?: boolean;
11
+ disabled?: boolean;
12
+ onChange?: (value: string) => void;
13
+ onEnter?: (value: string) => void;
14
+ onBlur?: (value: string) => void;
15
+ onFocus?: (value: string) => void;
16
+ editorDidMount?: (editor: any) => void;
17
+ }