| 1 | /** |
| 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. |
| 3 | * |
| 4 | * This source code is licensed under the MIT license found in the |
| 5 | * LICENSE file in the root directory of this source tree. |
| 6 | */ |
| 7 | |
| 8 | import { |
| 9 | CompilerErrorDetail, |
| 10 | CompilerDiagnostic, |
| 11 | } from 'babel-plugin-react-compiler'; |
| 12 | import {useDeferredValue, useMemo, useState} from 'react'; |
| 13 | import {useStore} from '../StoreContext'; |
| 14 | import ConfigEditor from './ConfigEditor'; |
| 15 | import Input from './Input'; |
| 16 | import {CompilerOutput, default as Output} from './Output'; |
| 17 | import {compile} from '../../lib/compilation'; |
| 18 | import prettyFormat from 'pretty-format'; |
| 19 | |
| 20 | export default function Editor(): JSX.Element { |
| 21 | const store = useStore(); |
| 22 | const deferredStore = useDeferredValue(store); |
| 23 | const [compilerOutput, language, appliedOptions] = useMemo( |
| 24 | () => compile(deferredStore.source, 'compiler', deferredStore.config), |
| 25 | [deferredStore.source, deferredStore.config], |
| 26 | ); |
| 27 | const [linterOutput] = useMemo( |
| 28 | () => compile(deferredStore.source, 'linter', deferredStore.config), |
| 29 | [deferredStore.source, deferredStore.config], |
| 30 | ); |
| 31 | const [formattedAppliedConfig, setFormattedAppliedConfig] = useState(''); |
| 32 | |
| 33 | let mergedOutput: CompilerOutput; |
| 34 | let errors: Array<CompilerErrorDetail | CompilerDiagnostic>; |
| 35 | if (compilerOutput.kind === 'ok') { |
| 36 | errors = linterOutput.kind === 'ok' ? [] : linterOutput.error.details; |
| 37 | mergedOutput = { |
| 38 | ...compilerOutput, |
| 39 | errors, |
| 40 | }; |
| 41 | } else { |
| 42 | mergedOutput = compilerOutput; |
| 43 | errors = compilerOutput.error.details; |
| 44 | } |
| 45 | |
| 46 | if (appliedOptions) { |
| 47 | const formatted = prettyFormat(appliedOptions, { |
| 48 | printFunctionName: false, |
| 49 | printBasicPrototype: false, |
| 50 | }); |
| 51 | if (formatted !== formattedAppliedConfig) { |
| 52 | setFormattedAppliedConfig(formatted); |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | return ( |
| 57 | <> |
| 58 | <div className="relative flex top-14"> |
| 59 | <div className="flex-shrink-0"> |
| 60 | <ConfigEditor formattedAppliedConfig={formattedAppliedConfig} /> |
| 61 | </div> |
| 62 | <div className="flex flex-1 min-w-0"> |
| 63 | <Input language={language} errors={errors} /> |
| 64 | <Output store={deferredStore} compilerOutput={mergedOutput} /> |
| 65 | </div> |
| 66 | </div> |
| 67 | </> |
| 68 | ); |
| 69 | } |