@sanity/code-input 2.29.5-purple-unicorn.856 → 2.29.5-purple-unicorn-remix.873

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.
@@ -0,0 +1,893 @@
1
+ import React, { useRef, useImperativeHandle, useCallback, useEffect } from 'react';
2
+ import { ChangeIndicatorProvider, FormFieldSet, FormField } from '@sanity/base/_unstable';
3
+ import { PatchEvent, setIfMissing, set, unset } from '@sanity/base/form';
4
+ import { Card, Stack, Select, TextInput } from '@sanity/ui';
5
+ import * as PathUtils from '@sanity/util/paths';
6
+ import AceEditor from 'react-ace';
7
+ import styled, { css } from 'styled-components';
8
+ import { useId } from '@reach/auto-id';
9
+ import 'ace-builds/src-noconflict/mode-batchfile';
10
+ import 'ace-builds/src-noconflict/mode-csharp';
11
+ import 'ace-builds/src-noconflict/mode-css';
12
+ import 'ace-builds/src-noconflict/mode-golang';
13
+ import 'ace-builds/src-noconflict/mode-html';
14
+ import 'ace-builds/src-noconflict/mode-java';
15
+ import 'ace-builds/src-noconflict/mode-javascript';
16
+ import 'ace-builds/src-noconflict/mode-json';
17
+ import 'ace-builds/src-noconflict/mode-jsx';
18
+ import 'ace-builds/src-noconflict/mode-markdown';
19
+ import 'ace-builds/src-noconflict/mode-mysql';
20
+ import 'ace-builds/src-noconflict/mode-php';
21
+ import 'ace-builds/src-noconflict/mode-python';
22
+ import 'ace-builds/src-noconflict/mode-ruby';
23
+ import 'ace-builds/src-noconflict/mode-sass';
24
+ import 'ace-builds/src-noconflict/mode-scss';
25
+ import 'ace-builds/src-noconflict/mode-sh';
26
+ import 'ace-builds/src-noconflict/mode-text';
27
+ import 'ace-builds/src-noconflict/mode-tsx';
28
+ import 'ace-builds/src-noconflict/mode-typescript';
29
+ import 'ace-builds/src-noconflict/mode-xml';
30
+ import 'ace-builds/src-noconflict/mode-yaml';
31
+ import 'ace-builds/src-noconflict/theme-github';
32
+ import 'ace-builds/src-noconflict/theme-monokai';
33
+ import 'ace-builds/src-noconflict/theme-terminal';
34
+ import 'ace-builds/src-noconflict/theme-tomorrow';
35
+
36
+ const highlightMarkersCSS = css `
37
+ .ace_editor_markers_highlight {
38
+ position: absolute;
39
+ background-color: ${({ theme }) => theme.sanity.color.solid.primary.enabled.bg};
40
+ opacity: 0.2;
41
+ width: 100% !important;
42
+ border-radius: 0 !important;
43
+ }
44
+ `;
45
+ function createHighlightMarkers(rows) {
46
+ return rows.map((row) => ({
47
+ startRow: Number(row) - 1,
48
+ startCol: 0,
49
+ endRow: Number(row) - 1,
50
+ endCol: +Infinity,
51
+ className: 'ace_editor_markers_highlight',
52
+ type: 'screenLine',
53
+ inFront: true,
54
+ }));
55
+ }
56
+
57
+ /* eslint-disable no-undef */
58
+ // Grammar from https://github.com/sanity-io/vscode-sanity
59
+ const rules = {
60
+ start: [
61
+ {
62
+ include: '#query',
63
+ },
64
+ {
65
+ include: '#value',
66
+ },
67
+ {
68
+ include: '#pair',
69
+ },
70
+ ],
71
+ '#query': [
72
+ {
73
+ include: '#nullary-access-operator',
74
+ },
75
+ {
76
+ include: '#arraylike',
77
+ },
78
+ {
79
+ include: '#pipe',
80
+ },
81
+ {
82
+ include: '#sort-order',
83
+ },
84
+ {
85
+ include: '#filter',
86
+ },
87
+ ],
88
+ '#variable': [
89
+ {
90
+ token: 'variable.other.groq',
91
+ regex: /\$[_A-Za-z][_0-9A-Za-z]*/,
92
+ },
93
+ ],
94
+ '#keyword': [
95
+ {
96
+ token: 'keyword.other.groq',
97
+ regex: /\b(?:asc|desc|in|match)\b/,
98
+ },
99
+ ],
100
+ '#comparison': [
101
+ {
102
+ token: 'keyword.operator.comparison.groq',
103
+ // eslint-disable-next-line no-div-regex
104
+ regex: /==|!=|>=|<=|<!=>|<|>/,
105
+ },
106
+ ],
107
+ '#operator': [
108
+ {
109
+ token: 'keyword.operator.arithmetic.groq',
110
+ regex: /\+|-|\*{1,2}|\/|%/,
111
+ },
112
+ ],
113
+ '#pipe': [
114
+ {
115
+ token: 'keyword.operator.pipe.groq',
116
+ regex: /\|/,
117
+ },
118
+ ],
119
+ '#logical': [
120
+ {
121
+ token: 'keyword.operator.logical.groq',
122
+ regex: /!|&&|\|\|/,
123
+ },
124
+ ],
125
+ '#reference': [
126
+ {
127
+ token: 'keyword.operator.reference.groq',
128
+ regex: /->/,
129
+ },
130
+ ],
131
+ '#pair': [
132
+ {
133
+ include: '#identifier',
134
+ },
135
+ {
136
+ include: '#value',
137
+ },
138
+ {
139
+ include: '#filter',
140
+ },
141
+ {
142
+ token: 'keyword.operator.pair.groq',
143
+ regex: /[=]>/,
144
+ },
145
+ ],
146
+ '#arraylike': [
147
+ {
148
+ token: 'punctuation.definition.bracket.begin.groq',
149
+ regex: /\[/,
150
+ push: [
151
+ {
152
+ token: ['text', 'keyword.operator.descendant.groq'],
153
+ regex: /(\])((?:\s*\.)?)/,
154
+ next: 'pop',
155
+ },
156
+ {
157
+ include: '#range',
158
+ },
159
+ {
160
+ include: '#filter',
161
+ },
162
+ {
163
+ include: '#array-values',
164
+ },
165
+ ],
166
+ },
167
+ ],
168
+ '#array': [
169
+ {
170
+ token: 'punctuation.definition.bracket.begin.groq',
171
+ regex: /\[/,
172
+ push: [
173
+ {
174
+ token: 'punctuation.definition.bracket.end.groq',
175
+ regex: /\]/,
176
+ next: 'pop',
177
+ },
178
+ {
179
+ include: '#array-values',
180
+ },
181
+ {
182
+ defaultToken: 'meta.structure.array.groq',
183
+ },
184
+ ],
185
+ },
186
+ ],
187
+ '#range': [
188
+ {
189
+ token: [
190
+ 'meta.structure.range.groq',
191
+ 'constant.numeric.groq',
192
+ 'meta.structure.range.groq',
193
+ 'keyword.operator.range.groq',
194
+ 'meta.structure.range.groq',
195
+ 'constant.numeric.groq',
196
+ 'meta.structure.range.groq',
197
+ ],
198
+ regex: /(\s*)(\d+)(\s*)(\.{2,3})(\s*)(\d+)(\s*)/,
199
+ },
200
+ ],
201
+ '#spread': [
202
+ {
203
+ token: 'punctuation.definition.spread.begin.groq',
204
+ regex: /\.\.\./,
205
+ push: [
206
+ {
207
+ include: '#array',
208
+ },
209
+ {
210
+ include: '#function-call',
211
+ },
212
+ {
213
+ include: '#projection',
214
+ },
215
+ {
216
+ token: 'punctuation.definition.spread.end.groq',
217
+ regex: /(?=.)/,
218
+ next: 'pop',
219
+ },
220
+ {
221
+ defaultToken: 'meta.structure.spread.groq',
222
+ },
223
+ ],
224
+ },
225
+ ],
226
+ '#array-values': [
227
+ {
228
+ include: '#value',
229
+ },
230
+ {
231
+ include: '#spread',
232
+ },
233
+ {
234
+ token: 'punctuation.separator.array.groq',
235
+ regex: /,/,
236
+ },
237
+ {
238
+ token: 'invalid.illegal.expected-array-separator.groq',
239
+ regex: /[^\s\]]/,
240
+ },
241
+ ],
242
+ '#filter': [
243
+ {
244
+ include: '#function-call',
245
+ },
246
+ {
247
+ include: '#keyword',
248
+ },
249
+ {
250
+ include: '#constant',
251
+ },
252
+ {
253
+ include: '#identifier',
254
+ },
255
+ {
256
+ include: '#value',
257
+ },
258
+ {
259
+ include: '#comparison',
260
+ },
261
+ {
262
+ include: '#operator',
263
+ },
264
+ {
265
+ include: '#logical',
266
+ },
267
+ ],
268
+ '#comments': [
269
+ {
270
+ token: ['punctuation.definition.comment.groq', 'comment.line.double-slash.js'],
271
+ regex: /(\/\/)(.*$)/,
272
+ },
273
+ ],
274
+ '#nullary-access-operator': [
275
+ {
276
+ token: 'constant.language.groq',
277
+ regex: /[*@^]/,
278
+ },
279
+ ],
280
+ '#constant': [
281
+ {
282
+ token: 'constant.language.groq',
283
+ regex: /\b(?:true|false|null)\b/,
284
+ },
285
+ ],
286
+ '#number': [
287
+ {
288
+ token: 'constant.numeric.groq',
289
+ regex: /-?(?:0|[1-9]\d*)(?:(?:\.\d+)?(?:[eE][+-]?\d+)?)?/,
290
+ },
291
+ ],
292
+ '#named-projection': [
293
+ {
294
+ include: '#identifier',
295
+ },
296
+ {
297
+ include: '#objectkey',
298
+ },
299
+ {
300
+ include: '#projection',
301
+ },
302
+ ],
303
+ '#projection': [
304
+ {
305
+ token: 'punctuation.definition.projection.begin.groq',
306
+ regex: /\{/,
307
+ push: [
308
+ {
309
+ token: 'punctuation.definition.projection.end.groq',
310
+ regex: /\}/,
311
+ next: 'pop',
312
+ },
313
+ {
314
+ include: '#identifier',
315
+ },
316
+ {
317
+ include: '#objectkey',
318
+ },
319
+ {
320
+ include: '#named-projection',
321
+ },
322
+ {
323
+ include: '#comments',
324
+ },
325
+ {
326
+ include: '#spread',
327
+ },
328
+ {
329
+ include: '#pair',
330
+ },
331
+ {
332
+ token: 'punctuation.separator.projection.key-value.groq',
333
+ regex: /:/,
334
+ push: [
335
+ {
336
+ token: 'punctuation.separator.projection.pair.groq',
337
+ regex: /,|(?=\})/,
338
+ next: 'pop',
339
+ },
340
+ {
341
+ include: '#nullary-access-operator',
342
+ },
343
+ {
344
+ include: '#arraylike',
345
+ },
346
+ {
347
+ include: '#value',
348
+ },
349
+ {
350
+ include: '#spread',
351
+ },
352
+ {
353
+ include: '#identifier',
354
+ },
355
+ {
356
+ include: '#operator',
357
+ },
358
+ {
359
+ include: '#comparison',
360
+ },
361
+ {
362
+ include: '#pair',
363
+ },
364
+ {
365
+ token: 'invalid.illegal.expected-projection-separator.groq',
366
+ regex: /[^\s,]/,
367
+ },
368
+ {
369
+ defaultToken: 'meta.structure.projection.value.groq',
370
+ },
371
+ ],
372
+ },
373
+ {
374
+ token: 'invalid.illegal.expected-projection-separator.groq',
375
+ regex: /[^\s},]/,
376
+ },
377
+ {
378
+ defaultToken: 'meta.structure.projection.groq',
379
+ },
380
+ ],
381
+ },
382
+ ],
383
+ '#string': [
384
+ {
385
+ include: '#single-string',
386
+ },
387
+ {
388
+ include: '#double-string',
389
+ },
390
+ ],
391
+ '#double-string': [
392
+ {
393
+ token: 'punctuation.definition.string.begin.groq',
394
+ regex: /"/,
395
+ push: [
396
+ {
397
+ token: 'punctuation.definition.string.end.groq',
398
+ regex: /"/,
399
+ next: 'pop',
400
+ },
401
+ {
402
+ include: '#stringcontent',
403
+ },
404
+ {
405
+ defaultToken: 'string.quoted.double.groq',
406
+ },
407
+ ],
408
+ },
409
+ ],
410
+ '#single-string': [
411
+ {
412
+ token: 'punctuation.definition.string.single.begin.groq',
413
+ regex: /'/,
414
+ push: [
415
+ {
416
+ token: 'punctuation.definition.string.single.end.groq',
417
+ regex: /'/,
418
+ next: 'pop',
419
+ },
420
+ {
421
+ include: '#stringcontent',
422
+ },
423
+ {
424
+ defaultToken: 'string.quoted.single.groq',
425
+ },
426
+ ],
427
+ },
428
+ ],
429
+ '#objectkey': [
430
+ {
431
+ include: '#string',
432
+ },
433
+ ],
434
+ '#stringcontent': [
435
+ {
436
+ token: 'constant.character.escape.groq',
437
+ regex: /\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4})/,
438
+ },
439
+ {
440
+ token: 'invalid.illegal.unrecognized-string-escape.groq',
441
+ regex: /\\./,
442
+ },
443
+ ],
444
+ '#sort-pair': [
445
+ {
446
+ token: ['variable.other.readwrite.groq', 'text', 'keyword.other.groq'],
447
+ regex: /([_A-Za-z][_0-9A-Za-z]*)(?:(\s*)(asc|desc))?/,
448
+ },
449
+ {
450
+ token: ['constant.language.groq', 'punctuation.definition.bracket.begin.groq'],
451
+ regex: /(@)(\[)/,
452
+ push: [
453
+ {
454
+ token: ['punctuation.definition.bracket.begin.groq', 'text', 'keyword.other.groq'],
455
+ regex: /(\])(?:(\s*)(asc|desc))?/,
456
+ next: 'pop',
457
+ },
458
+ {
459
+ include: '#string',
460
+ },
461
+ ],
462
+ },
463
+ ],
464
+ '#sort-order': [
465
+ {
466
+ token: 'support.function.sortorder.begin.groq',
467
+ regex: /\border\s*\(/,
468
+ push: [
469
+ {
470
+ token: 'support.function.sortorder.end.groq',
471
+ regex: /\)/,
472
+ next: 'pop',
473
+ },
474
+ {
475
+ include: '#sort-pair',
476
+ },
477
+ {
478
+ token: 'punctuation.separator.array.groq',
479
+ regex: /,/,
480
+ },
481
+ {
482
+ token: 'invalid.illegal.expected-sort-separator.groq',
483
+ regex: /[^\s\]]/,
484
+ },
485
+ {
486
+ defaultToken: 'support.function.sortorder.groq',
487
+ },
488
+ ],
489
+ },
490
+ ],
491
+ '#function-call': [
492
+ {
493
+ include: '#function-var-arg',
494
+ },
495
+ {
496
+ include: '#function-single-arg',
497
+ },
498
+ {
499
+ include: '#function-round',
500
+ },
501
+ ],
502
+ '#function-var-arg': [
503
+ {
504
+ token: 'support.function.vararg.begin.groq',
505
+ regex: /\b(?:coalesce|select)\s*\(/,
506
+ push: [
507
+ {
508
+ token: 'support.function.vararg.end.groq',
509
+ regex: /\)/,
510
+ next: 'pop',
511
+ },
512
+ {
513
+ include: '#value',
514
+ },
515
+ {
516
+ include: '#identifier',
517
+ },
518
+ {
519
+ include: '#filter',
520
+ },
521
+ {
522
+ include: '#pair',
523
+ },
524
+ {
525
+ token: 'punctuation.separator.array.groq',
526
+ regex: /,/,
527
+ },
528
+ {
529
+ defaultToken: 'support.function.vararg.groq',
530
+ },
531
+ ],
532
+ },
533
+ ],
534
+ '#function-single-arg': [
535
+ {
536
+ token: 'support.function.singlearg.begin.groq',
537
+ regex: /\b(?:count|defined|length|path|references)\s*\(/,
538
+ push: [
539
+ {
540
+ token: 'support.function.singlearg.end.groq',
541
+ regex: /\)/,
542
+ next: 'pop',
543
+ },
544
+ {
545
+ include: '#query',
546
+ },
547
+ {
548
+ include: '#identifier',
549
+ },
550
+ {
551
+ include: '#value',
552
+ },
553
+ {
554
+ include: '#pair',
555
+ },
556
+ {
557
+ defaultToken: 'support.function.singlearg.groq',
558
+ },
559
+ ],
560
+ },
561
+ ],
562
+ '#identifier': [
563
+ {
564
+ token: [
565
+ 'variable.other.readwrite.groq',
566
+ 'text',
567
+ 'punctuation.definition.block.js',
568
+ 'text',
569
+ 'keyword.operator.reference.groq',
570
+ ],
571
+ regex: /([_A-Za-z][_0-9A-Za-z]*)(\s*)((?:\[\s*\])?)(\s*)(->)/,
572
+ },
573
+ {
574
+ token: [
575
+ 'variable.other.readwrite.groq',
576
+ 'constant.language.groq',
577
+ 'text',
578
+ 'punctuation.definition.block.js',
579
+ 'text',
580
+ 'keyword.operator.descendant.groq',
581
+ ],
582
+ regex: /(?:([_A-Za-z][_0-9A-Za-z]*)|([@^]))(\s*)((?:\[\s*\])?)(\s*)(\.)/,
583
+ },
584
+ {
585
+ token: 'variable.other.readwrite.groq',
586
+ regex: /[_A-Za-z][_0-9A-Za-z]*/,
587
+ },
588
+ ],
589
+ '#value': [
590
+ {
591
+ include: '#constant',
592
+ },
593
+ {
594
+ include: '#number',
595
+ },
596
+ {
597
+ include: '#string',
598
+ },
599
+ {
600
+ include: '#array',
601
+ },
602
+ {
603
+ include: '#variable',
604
+ },
605
+ {
606
+ include: '#projection',
607
+ },
608
+ {
609
+ include: '#comments',
610
+ },
611
+ {
612
+ include: '#function-call',
613
+ },
614
+ ],
615
+ };
616
+ ace.define('ace/mode/groq_highlight_rules', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/mode/text_highlight_rules'], (acequire, exports, _module) => {
617
+ const oop = acequire('../lib/oop');
618
+ const TextHighlightRules = acequire('./text_highlight_rules').TextHighlightRules;
619
+ const GroqHighlightRules = function () {
620
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
621
+ // @ts-ignore
622
+ this.$rules = rules;
623
+ // @ts-ignore
624
+ this.normalizeRules();
625
+ /* eslint-enable @typescript-eslint/ban-ts-comment */
626
+ };
627
+ oop.inherits(GroqHighlightRules, TextHighlightRules);
628
+ exports.GroqHighlightRules = GroqHighlightRules;
629
+ });
630
+ ace.define('ace/mode/groq', [
631
+ 'require',
632
+ 'exports',
633
+ 'module',
634
+ 'ace/lib/oop',
635
+ 'ace/mode/text',
636
+ 'ace/tokenizer',
637
+ 'ace/mode/groq_highlight_rules',
638
+ 'ace/mode/folding/cstyle',
639
+ ], (acequire, exports, _module) => {
640
+ const oop = acequire('../lib/oop');
641
+ const TextMode = acequire('./text').Mode;
642
+ const Tokenizer = acequire('../tokenizer').Tokenizer;
643
+ const GroqHighlightRules = acequire('./groq_highlight_rules').GroqHighlightRules;
644
+ const FoldMode = acequire('./folding/cstyle').FoldMode;
645
+ const Mode = function () {
646
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
647
+ const highlighter = new GroqHighlightRules();
648
+ // @ts-ignore
649
+ this.foldingRules = new FoldMode();
650
+ // @ts-ignore
651
+ this.$tokenizer = new Tokenizer(highlighter.getRules());
652
+ // @ts-ignore
653
+ this.$keywordList = highlighter.$keywordList;
654
+ /* eslint-enable @typescript-eslint/ban-ts-comment */
655
+ };
656
+ oop.inherits(Mode, TextMode);
657
+ (function () {
658
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
659
+ // @ts-ignore
660
+ this.lineCommentStart = "'";
661
+ /* eslint-enable @typescript-eslint/ban-ts-comment */
662
+ }.call(Mode.prototype));
663
+ exports.Mode = Mode;
664
+ });
665
+
666
+ // NOTE: MAKE SURE THESE ALIGN WITH IMPORTS IN ./editorSupport
667
+ const SUPPORTED_LANGUAGES = [
668
+ { title: 'Batch file', value: 'batchfile' },
669
+ { title: 'C#', value: 'csharp' },
670
+ { title: 'CSS', value: 'css' },
671
+ { title: 'Go', value: 'golang' },
672
+ { title: 'GROQ', value: 'groq' },
673
+ { title: 'HTML', value: 'html' },
674
+ { title: 'Java', value: 'java' },
675
+ { title: 'JavaScript', value: 'javascript' },
676
+ { title: 'JSON', value: 'json' },
677
+ { title: 'JSX', value: 'jsx' },
678
+ { title: 'Markdown', value: 'markdown' },
679
+ { title: 'MySQL', value: 'mysql' },
680
+ { title: 'PHP', value: 'php' },
681
+ { title: 'Plain text', value: 'text' },
682
+ { title: 'Python', value: 'python' },
683
+ { title: 'Ruby', value: 'ruby' },
684
+ { title: 'SASS', value: 'sass' },
685
+ { title: 'SCSS', value: 'scss' },
686
+ { title: 'sh', value: 'sh' },
687
+ { title: 'TSX', value: 'tsx' },
688
+ { title: 'TypeScript', value: 'typescript' },
689
+ { title: 'XML', value: 'xml' },
690
+ { title: 'YAML', value: 'yaml' },
691
+ ];
692
+ const LANGUAGE_ALIASES = { js: 'javascript' };
693
+ const SUPPORTED_THEMES = ['github', 'monokai', 'terminal', 'tomorrow'];
694
+ const DEFAULT_THEME = 'tomorrow';
695
+ const ACE_SET_OPTIONS = {
696
+ useSoftTabs: true,
697
+ navigateWithinSoftTabs: true /* note only supported by ace v1.2.7 or higher */,
698
+ };
699
+ const ACE_EDITOR_PROPS = { $blockScrolling: true };
700
+ const PATH_LANGUAGE = ['language'];
701
+ const PATH_CODE = ['code'];
702
+ const PATH_FILENAME = ['filename'];
703
+
704
+ const EditorContainer = styled(Card) `
705
+ position: relative;
706
+ box-sizing: border-box;
707
+ overflow: hidden;
708
+ z-index: 0;
709
+
710
+ .ace_editor {
711
+ font-family: ${({ theme }) => theme.sanity.fonts.code.family};
712
+ font-size: ${({ theme }) => theme.sanity.fonts.code.sizes[1]};
713
+ line-height: inherit;
714
+ }
715
+
716
+ ${highlightMarkersCSS}
717
+
718
+ &:not([disabled]):not([readonly]) {
719
+ &:focus,
720
+ &:focus-within {
721
+ box-shadow: 0 0 0 2px ${({ theme }) => theme.sanity.color.base.focusRing};
722
+ background-color: ${({ theme }) => theme.sanity.color.base.bg};
723
+ border-color: ${({ theme }) => theme.sanity.color.base.focusRing};
724
+ }
725
+ }
726
+ `;
727
+ // Returns a string with the mode name if supported (because aliases), otherwise false
728
+ function isSupportedLanguage(mode) {
729
+ const alias = LANGUAGE_ALIASES[mode];
730
+ if (alias) {
731
+ return alias;
732
+ }
733
+ const isSupported = SUPPORTED_LANGUAGES.find((lang) => lang.value === mode);
734
+ if (isSupported) {
735
+ return mode;
736
+ }
737
+ return false;
738
+ }
739
+ const CodeInput = React.forwardRef((props, ref) => {
740
+ const aceEditorRef = useRef();
741
+ const aceEditorId = useId();
742
+ const { onFocus, onChange, onBlur, compareValue, value, presence, type, level = 0, readOnly, focusPath, } = props;
743
+ useImperativeHandle(ref, () => ({
744
+ focus: () => {
745
+ aceEditorRef?.current?.editor?.focus();
746
+ },
747
+ }));
748
+ const handleLanguageFocus = useCallback(() => {
749
+ onFocus(PATH_LANGUAGE);
750
+ }, [onFocus]);
751
+ const handleCodeFocus = useCallback(() => {
752
+ onFocus(PATH_CODE);
753
+ }, [onFocus]);
754
+ const handleFilenameFocus = useCallback(() => {
755
+ onFocus(PATH_FILENAME);
756
+ }, [onFocus]);
757
+ const handleFilenameChange = useCallback((event) => {
758
+ const val = event.target.value;
759
+ const path = PATH_FILENAME;
760
+ onChange(PatchEvent.from([setIfMissing({ _type: type.name }), val ? set(val, path) : unset(path)]));
761
+ }, [onChange, type.name]);
762
+ const getTheme = useCallback(() => {
763
+ const preferredTheme = type.options?.theme;
764
+ return preferredTheme && SUPPORTED_THEMES.find((theme) => theme === preferredTheme)
765
+ ? preferredTheme
766
+ : DEFAULT_THEME;
767
+ }, [type]);
768
+ const handleToggleSelectLine = useCallback((lineNumber) => {
769
+ const editorSession = aceEditorRef.current?.editor?.getSession();
770
+ const backgroundMarkers = editorSession?.getMarkers(true);
771
+ const currentHighlightedLines = Object.keys(backgroundMarkers)
772
+ .filter((key) => backgroundMarkers[key].type === 'screenLine')
773
+ .map((key) => backgroundMarkers[key].range.start.row);
774
+ const currentIndex = currentHighlightedLines.indexOf(lineNumber);
775
+ if (currentIndex > -1) {
776
+ // toggle remove
777
+ currentHighlightedLines.splice(currentIndex, 1);
778
+ }
779
+ else {
780
+ // toggle add
781
+ currentHighlightedLines.push(lineNumber);
782
+ currentHighlightedLines.sort();
783
+ }
784
+ onChange(PatchEvent.from(set(currentHighlightedLines.map((line) =>
785
+ // ace starts at line (row) 0, but we store it starting at line 1
786
+ line + 1), ['highlightedLines'])));
787
+ }, [aceEditorRef, onChange]);
788
+ const handleGutterMouseDown = useCallback((event) => {
789
+ const target = event.domEvent.target;
790
+ if (target.classList.contains('ace_gutter-cell')) {
791
+ const row = event.getDocumentPosition().row;
792
+ handleToggleSelectLine(row);
793
+ }
794
+ }, [handleToggleSelectLine]);
795
+ useEffect(() => {
796
+ const editor = aceEditorRef?.current?.editor;
797
+ return () => {
798
+ editor?.session?.removeListener('guttermousedown', handleGutterMouseDown);
799
+ };
800
+ }, [aceEditorRef, handleGutterMouseDown]);
801
+ const handleEditorLoad = useCallback((editor) => {
802
+ editor?.on('guttermousedown', handleGutterMouseDown);
803
+ }, [handleGutterMouseDown]);
804
+ const getLanguageAlternatives = useCallback(() => {
805
+ const languageAlternatives = type.options?.languageAlternatives;
806
+ if (!languageAlternatives) {
807
+ return SUPPORTED_LANGUAGES;
808
+ }
809
+ if (!Array.isArray(languageAlternatives)) {
810
+ throw new Error(`'options.languageAlternatives' should be an array, got ${typeof languageAlternatives}`);
811
+ }
812
+ return languageAlternatives.reduce((acc, { title, value: val, mode }) => {
813
+ const alias = LANGUAGE_ALIASES[val];
814
+ if (alias) {
815
+ // eslint-disable-next-line no-console
816
+ console.warn(`'options.languageAlternatives' lists a language with value "%s", which is an alias of "%s" - please replace the value to read "%s"`, val, alias, alias);
817
+ return acc.concat({ title, value: alias, mode: mode });
818
+ }
819
+ if (!mode && !SUPPORTED_LANGUAGES.find((lang) => lang.value === val)) {
820
+ // eslint-disable-next-line no-console
821
+ console.warn(`'options.languageAlternatives' lists a language which is not supported: "%s", syntax highlighting will be disabled.`, val);
822
+ }
823
+ return acc.concat({ title, value: val, mode });
824
+ }, []);
825
+ }, [type]);
826
+ const handleCodeChange = useCallback((code) => {
827
+ const path = PATH_CODE;
828
+ const fixedLanguage = type.options?.language;
829
+ onChange(PatchEvent.from([
830
+ setIfMissing({ _type: type.name, language: fixedLanguage }),
831
+ code ? set(code, path) : unset(path),
832
+ ]));
833
+ }, [onChange, type]);
834
+ const handleLanguageChange = useCallback((event) => {
835
+ const val = event.currentTarget.value;
836
+ const path = PATH_LANGUAGE;
837
+ onChange(PatchEvent.from([setIfMissing({ _type: type.name }), val ? set(val, path) : unset(path)]));
838
+ }, [onChange, type.name]);
839
+ const languages = getLanguageAlternatives().slice();
840
+ const selectedLanguage = props?.value?.language
841
+ ? languages.find((item) => item.value === props?.value?.language)
842
+ : undefined;
843
+ const languageField = type.fields.find((field) => field.name === 'language');
844
+ const filenameField = type.fields.find((field) => field.name === 'filename');
845
+ const languageCompareValue = PathUtils.get(compareValue, PATH_LANGUAGE);
846
+ const codeCompareValue = PathUtils.get(compareValue, PATH_CODE);
847
+ const filenameCompareValue = PathUtils.get(compareValue, PATH_FILENAME);
848
+ const languagePresence = presence.filter((presenceItem) => PathUtils.startsWith(PATH_LANGUAGE, presenceItem.path));
849
+ const codePresence = presence.filter((presenceItem) => PathUtils.startsWith(PATH_CODE, presenceItem.path));
850
+ const filenamePresence = presence.filter((presenceItem) => PathUtils.startsWith(PATH_FILENAME, presenceItem.path));
851
+ const renderEditor = useCallback(() => {
852
+ const fixedLanguage = type.options?.language;
853
+ const language = value?.language || fixedLanguage;
854
+ // the language config from the schema
855
+ const configured = languages.find((entry) => entry.value === language);
856
+ // is the language officially supported (e.g. we import the mode by default)
857
+ const supported = language && isSupportedLanguage(language);
858
+ const mode = configured?.mode || (supported ? language : 'text');
859
+ return (React.createElement(EditorContainer, { radius: 1, shadow: 1, readOnly: readOnly },
860
+ React.createElement(AceEditor, { ref: aceEditorRef, mode: mode, theme: getTheme(), width: "100%", onChange: handleCodeChange, name: `editor-${aceEditorId}`, value: (value && value.code) || '', markers: value && value.highlightedLines
861
+ ? createHighlightMarkers(value.highlightedLines)
862
+ : undefined, onLoad: handleEditorLoad, readOnly: readOnly, tabSize: 2, wrapEnabled: true, setOptions: ACE_SET_OPTIONS, editorProps: ACE_EDITOR_PROPS, onFocus: handleCodeFocus, onBlur: onBlur })));
863
+ }, [
864
+ aceEditorId,
865
+ getTheme,
866
+ handleCodeChange,
867
+ handleCodeFocus,
868
+ handleEditorLoad,
869
+ languages,
870
+ onBlur,
871
+ readOnly,
872
+ type,
873
+ value,
874
+ ]);
875
+ if (type.options?.language) {
876
+ return (React.createElement(ChangeIndicatorProvider, { path: PATH_CODE, focusPath: focusPath, value: value?.code, compareValue: codeCompareValue },
877
+ React.createElement(FormFieldSet, { title: type.title, description: type.description, level: level }, renderEditor())));
878
+ }
879
+ return (React.createElement(FormFieldSet, { title: type.title, description: type.description, level: level, __unstable_changeIndicator: false },
880
+ React.createElement(Stack, { space: 3 },
881
+ React.createElement(ChangeIndicatorProvider, { path: PATH_LANGUAGE, focusPath: focusPath, value: selectedLanguage?.value, compareValue: languageCompareValue },
882
+ React.createElement(FormField, { level: level + 1, label: languageField?.type.title || 'Language', __unstable_presence: languagePresence },
883
+ React.createElement(Select, { onChange: handleLanguageChange, readOnly: readOnly, value: selectedLanguage?.value || '', onFocus: handleLanguageFocus, onBlur: onBlur }, languages.map((lang) => (React.createElement("option", { key: lang.value, value: lang.value }, lang.title)))))),
884
+ type.options?.withFilename && (React.createElement(ChangeIndicatorProvider, { path: PATH_FILENAME, focusPath: focusPath, value: value?.filename, compareValue: filenameCompareValue },
885
+ React.createElement(FormField, { label: filenameField?.type.title || 'Filename', level: level + 1, __unstable_presence: filenamePresence },
886
+ React.createElement(TextInput, { name: "filename", value: value?.filename || '', placeholder: filenameField?.type.placeholder, onChange: handleFilenameChange, onFocus: handleFilenameFocus, onBlur: onBlur })))),
887
+ React.createElement(ChangeIndicatorProvider, { path: PATH_CODE, focusPath: focusPath, value: value?.code, compareValue: codeCompareValue },
888
+ React.createElement(FormField, { label: "Code", level: level + 1, __unstable_presence: codePresence }, renderEditor())))));
889
+ });
890
+ CodeInput.displayName = 'CodeInput';
891
+
892
+ export { ACE_SET_OPTIONS as A, CodeInput as C, ACE_EDITOR_PROPS as a, createHighlightMarkers as c };
893
+ //# sourceMappingURL=_CodeInput-1b58302e.js.map