compiler/apps/playground/components/Editor/Input.tsx TYPESCRIPT 181 lines View on github.com → Search inside
1/**2 * Copyright (c) Meta Platforms, Inc. and affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 */78import MonacoEditor, {loader, type Monaco} from '@monaco-editor/react';9import {10  CompilerErrorDetail,11  CompilerDiagnostic,12} from 'babel-plugin-react-compiler';13import invariant from 'invariant';14import type {editor} from 'monaco-editor';15import * as monaco from 'monaco-editor';16import {17  useEffect,18  useState,19  unstable_ViewTransition as ViewTransition,20} from 'react';21import {renderReactCompilerMarkers} from '../../lib/reactCompilerMonacoDiagnostics';22import {useStore, useStoreDispatch} from '../StoreContext';23import TabbedWindow from '../TabbedWindow';24import {monacoOptions} from './monacoOptions';25import {CONFIG_PANEL_TRANSITION} from '../../lib/transitionTypes';2627// @ts-expect-error TODO: Make TS recognize .d.ts files, in addition to loading them with webpack.28import React$Types from '../../node_modules/@types/react/index.d.ts';2930loader.config({monaco});3132type Props = {33  errors: Array<CompilerErrorDetail | CompilerDiagnostic>;34  language: 'flow' | 'typescript';35};3637export default function Input({errors, language}: Props): JSX.Element {38  const [monaco, setMonaco] = useState<Monaco | null>(null);39  const store = useStore();40  const dispatchStore = useStoreDispatch();4142  // Set tab width to 2 spaces for the selected input file.43  useEffect(() => {44    if (!monaco) return;45    const uri = monaco.Uri.parse(`file:///index.js`);46    const model = monaco.editor.getModel(uri);47    invariant(model, 'Model must exist for the selected input file.');48    renderReactCompilerMarkers({49      monaco,50      model,51      details: errors,52      source: store.source,53    });54  }, [monaco, errors, store.source]);5556  useEffect(() => {57    /**58     * Ignore "can only be used in TypeScript files." errors, since59     * we want to support syntax highlighting for Flow (*.js) files60     * and Flow is not a built-in language.61     */62    if (!monaco) return;63    monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({64      diagnosticCodesToIgnore: [65        8002,66        8003,67        8004,68        8005,69        8006,70        8008,71        8009,72        8010,73        8011,74        8012,75        8013,76        ...(language === 'flow'77          ? [7028 /* unused label */, 6133 /* var declared but not read */]78          : []),79      ],80      noSemanticValidation: true,81      // Monaco can't validate Flow component syntax82      noSyntaxValidation: language === 'flow',83    });84  }, [monaco, language]);8586  const handleChange: (value: string | undefined) => void = async value => {87    if (!value) return;8889    dispatchStore({90      type: 'updateSource',91      payload: {92        source: value,93      },94    });95  };9697  const handleMount: (98    _: editor.IStandaloneCodeEditor,99    monaco: Monaco,100  ) => void = (_, monaco) => {101    if (typeof window !== 'undefined') {102      window['__MONACO_LOADED__'] = true;103    }104    setMonaco(monaco);105106    const tscOptions = {107      allowNonTsExtensions: true,108      target: monaco.languages.typescript.ScriptTarget.ES2015,109      moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,110      jsx: monaco.languages.typescript.JsxEmit.Preserve,111      typeRoots: ['node_modules/@types'],112      allowSyntheticDefaultImports: true,113    };114    monaco.languages.typescript.javascriptDefaults.setCompilerOptions(115      tscOptions,116    );117    monaco.languages.typescript.typescriptDefaults.setCompilerOptions({118      ...tscOptions,119      checkJs: true,120      allowJs: true,121    });122123    // Add React type declarations to Monaco124    const reactLib = [125      React$Types,126      'file:///node_modules/@types/react/index.d.ts',127    ] as [any, string];128    monaco.languages.typescript.javascriptDefaults.addExtraLib(...reactLib);129    monaco.languages.typescript.typescriptDefaults.addExtraLib(...reactLib);130131    /**132     * Remeasure the font in case the custom font is loaded only after133     * Monaco Editor is mounted.134     * N.B. that this applies also to the output editor as it seems135     * Monaco Editor instances share the same font config.136     */137    document.fonts.ready.then(() => {138      monaco.editor.remeasureFonts();139    });140  };141142  const editorContent = (143    <MonacoEditor144      path={'index.js'}145      /**146       * .js and .jsx files are specified to be TS so that Monaco can actually147       * check their syntax using its TS language service. They are still JS files148       * due to their extensions, so TS language features don't work.149       */150      language={'javascript'}151      value={store.source}152      onMount={handleMount}153      onChange={handleChange}154      className="monaco-editor-input"155      options={monacoOptions}156      loading={''}157    />158  );159160  const tabs = new Map([['Input', editorContent]]);161  const [activeTab, setActiveTab] = useState('Input');162163  return (164    <ViewTransition165      update={{166        [CONFIG_PANEL_TRANSITION]: 'container',167        default: 'none',168      }}>169      <div className="flex-1 min-w-[550px] sm:min-w-0">170        <div className="flex flex-col h-full !h-[calc(100vh_-_3.5rem)] border-r border-gray-200">171          <TabbedWindow172            tabs={tabs}173            activeTab={activeTab}174            onTabChange={setActiveTab}175          />176        </div>177      </div>178    </ViewTransition>179  );180}

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.