Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 81 additions & 47 deletions compiler/apps/playground/components/Editor/ConfigEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,41 @@
*/

import MonacoEditor, {loader, type Monaco} from '@monaco-editor/react';
import {PluginOptions} from 'babel-plugin-react-compiler';
import type {editor} from 'monaco-editor';
import * as monaco from 'monaco-editor';
import React, {useState} from 'react';
import {Resizable} from 're-resizable';
import {useStore, useStoreDispatch} from '../StoreContext';
import {monacoOptions} from './monacoOptions';
import {IconChevron} from '../Icons/IconChevron';
import prettyFormat from 'pretty-format';

// @ts-expect-error - webpack asset/source loader handles .d.ts files as strings
import compilerTypeDefs from 'babel-plugin-react-compiler/dist/index.d.ts';

loader.config({monaco});

export default function ConfigEditor(): React.ReactElement {
export default function ConfigEditor({
appliedOptions,
}: {
appliedOptions: PluginOptions | null;
}): React.ReactElement {
const [isExpanded, setIsExpanded] = useState(false);

return (
<div className="flex flex-row relative">
{isExpanded ? (
<ExpandedEditor onToggle={setIsExpanded} />
) : (
<CollapsedEditor onToggle={setIsExpanded} />
)}
</div>
return isExpanded ? (
<ExpandedEditor onToggle={setIsExpanded} appliedOptions={appliedOptions} />
) : (
<CollapsedEditor onToggle={setIsExpanded} />
);
}

function ExpandedEditor({
onToggle,
appliedOptions,
}: {
onToggle: (expanded: boolean) => void;
appliedOptions: PluginOptions | null;
}): React.ReactElement {
const store = useStore();
const dispatchStore = useStoreDispatch();
Expand Down Expand Up @@ -81,22 +85,22 @@ function ExpandedEditor({
}
};

const formattedAppliedOptions = appliedOptions
? prettyFormat(appliedOptions, {
printFunctionName: false,
printBasicPrototype: false,
})
: 'Invalid configs';

return (
<Resizable
className="border-r"
minWidth={300}
maxWidth={600}
defaultSize={{width: 350, height: 'auto'}}
enable={{right: true, bottom: false}}
style={{position: 'relative', height: 'calc(100vh - 3.5rem)'}}>
<div className="bg-gray-700 p-2">
<div className="pb-2">
<h2 className="inline-block text-secondary-dark text-center outline-none py-1.5 px-1.5 xs:px-3 sm:px-4 rounded-full capitalize whitespace-nowrap text-sm">
Config Overrides
</h2>
</div>
defaultSize={{width: 350}}
enable={{right: true, bottom: false}}>
<div className="bg-blue-10 relative h-full flex flex-col !h-[calc(100vh_-_3.5rem)] border border-gray-300">
<div
className="absolute w-10 h-16 bg-gray-700 hover:translate-x-2 transition-transform rounded-r-full flex items-center justify-center z-[5] cursor-pointer"
className="absolute w-8 h-16 bg-blue-10 rounded-r-full flex items-center justify-center z-[2] cursor-pointer border border-l-0 border-gray-300"
title="Minimize config editor"
onClick={() => onToggle(false)}
style={{
Expand All @@ -106,30 +110,60 @@ function ExpandedEditor({
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
}}>
<IconChevron
displayDirection="left"
className="text-secondary-dark"
/>
<IconChevron displayDirection="left" className="text-blue-50" />
</div>

<div className="flex-1 flex flex-col m-2 mb-2">
<div className="pb-2">
<h2 className="inline-block text-blue-50 py-1.5 px-1.5 xs:px-3 sm:px-4 text-sm">
Config Overrides
</h2>
</div>
<div className="flex-1 rounded-lg overflow-hidden border border-gray-300">
<MonacoEditor
path={'config.ts'}
language={'typescript'}
value={store.config}
onMount={handleMount}
onChange={handleChange}
options={{
...monacoOptions,
lineNumbers: 'off',
renderLineHighlight: 'none',
overviewRulerBorder: false,
overviewRulerLanes: 0,
fontSize: 12,
scrollBeyondLastLine: false,
glyphMargin: false,
}}
/>
</div>
</div>
<div className="h-[calc(100vh_-_3.5rem_-_3.5rem)] rounded-lg overflow-hidden">
<MonacoEditor
path={'config.ts'}
language={'typescript'}
value={store.config}
onMount={handleMount}
onChange={handleChange}
options={{
...monacoOptions,
lineNumbers: 'off',
folding: false,
renderLineHighlight: 'none',
hideCursorInOverviewRuler: true,
overviewRulerBorder: false,
overviewRulerLanes: 0,
fontSize: 12,
scrollBeyondLastLine: false,
}}
/>

<div className="flex-1 flex flex-col m-2">
<div className="pb-2">
<h2 className="inline-block text-blue-50 py-1.5 px-1.5 xs:px-3 sm:px-4 text-sm">
Applied Configs
</h2>
</div>
<div className="flex-1 rounded-lg overflow-hidden border border-gray-300">
<MonacoEditor
path={'applied-config.js'}
language={'javascript'}
value={formattedAppliedOptions}
options={{
...monacoOptions,
lineNumbers: 'off',
renderLineHighlight: 'none',
overviewRulerBorder: false,
overviewRulerLanes: 0,
fontSize: 12,
scrollBeyondLastLine: false,
readOnly: true,
glyphMargin: false,
}}
/>
</div>
</div>
</div>
</Resizable>
Expand All @@ -143,10 +177,10 @@ function CollapsedEditor({
}): React.ReactElement {
return (
<div
className="w-4"
style={{height: 'calc(100vh - 3.5rem)', position: 'relative'}}>
className="w-4 !h-[calc(100vh_-_3.5rem)]"
style={{position: 'relative'}}>
<div
className="absolute w-10 h-16 bg-gray-700 hover:translate-x-2 transition-transform rounded-r-full flex items-center justify-center z-[5] cursor-pointer"
className="absolute w-10 h-16 bg-blue-10 hover:translate-x-2 transition-transform rounded-r-full flex items-center justify-center z-[2] cursor-pointer border border-gray-300"
title="Expand config editor"
onClick={() => onToggle(true)}
style={{
Expand All @@ -156,7 +190,7 @@ function CollapsedEditor({
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
}}>
<IconChevron displayDirection="right" className="text-secondary-dark" />
<IconChevron displayDirection="right" className="text-blue-50" />
</div>
</div>
);
Expand Down
11 changes: 6 additions & 5 deletions compiler/apps/playground/components/Editor/EditorImpl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ function compile(
source: string,
mode: 'compiler' | 'linter',
configOverrides: string,
): [CompilerOutput, 'flow' | 'typescript'] {
): [CompilerOutput, 'flow' | 'typescript', PluginOptions | null] {
const results = new Map<string, Array<PrintedCompilerPipelineValue>>();
const error = new CompilerError();
const otherErrors: Array<CompilerErrorDetail | CompilerDiagnostic> = [];
Expand Down Expand Up @@ -279,7 +279,7 @@ function compile(
...baseOpts,
logger: {
debugLogIRs: logIR,
logEvent: (_filename: string | null, event: LoggerEvent) => {
logEvent: (_filename: string | null, event: LoggerEvent): void => {
if (event.kind === 'CompileError') {
otherErrors.push(event.detail);
}
Expand Down Expand Up @@ -315,11 +315,12 @@ function compile(
otherErrors.forEach(e => error.details.push(e));
}
if (error.hasErrors()) {
return [{kind: 'err', results, error}, language];
return [{kind: 'err', results, error}, language, baseOpts];
}
return [
{kind: 'ok', results, transformOutput, errors: error.details},
language,
baseOpts,
];
}

Expand All @@ -328,7 +329,7 @@ export default function Editor(): JSX.Element {
const deferredStore = useDeferredValue(store);
const dispatchStore = useStoreDispatch();
const {enqueueSnackbar} = useSnackbar();
const [compilerOutput, language] = useMemo(
const [compilerOutput, language, appliedOptions] = useMemo(
() => compile(deferredStore.source, 'compiler', deferredStore.config),
[deferredStore.source, deferredStore.config],
);
Expand Down Expand Up @@ -379,7 +380,7 @@ export default function Editor(): JSX.Element {
<>
<div className="relative flex top-14">
<div className="flex-shrink-0">
<ConfigEditor />
<ConfigEditor appliedOptions={appliedOptions} />
</div>
<div className="flex flex-1 min-w-0">
<div className="flex-1 min-w-[550px] sm:min-w-0">
Expand Down
2 changes: 1 addition & 1 deletion compiler/apps/playground/components/TabbedWindow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function TabbedWindow({
key={tab}
onClick={() => onTabChange(tab)}
className={clsx(
'active:scale-95 transition-transform text-center outline-none py-1.5 px-1.5 xs:px-3 sm:px-4 rounded-full capitalize whitespace-nowrap text-sm',
'active:scale-95 transition-transform py-1.5 px-1.5 xs:px-3 sm:px-4 rounded-full text-sm',
!isActive && 'hover:bg-primary/5',
isActive && 'bg-highlight text-link',
)}>
Expand Down
4 changes: 1 addition & 3 deletions compiler/apps/playground/lib/defaultStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ export const defaultConfig = `\
import type { PluginOptions } from 'babel-plugin-react-compiler/dist';

({
environment: {
enableResetCacheOnSourceFileChanges: false
}
//compilationMode: "all"
} satisfies Partial<PluginOptions>);`;

export const defaultStore: Store = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const fetchFromPage = async (url, resolve, reject) => {
debugLog('[main] fetchFromPage()', url);

function onPortMessage({payload, source}) {
if (source === 'react-devtools-background') {
if (source === 'react-devtools-background' && payload?.url === url) {
switch (payload?.type) {
case 'fetch-file-with-cache-complete':
chrome.runtime.onMessage.removeListener(onPortMessage);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ test.describe('Components', () => {

const name = isEditable.name
? existingNameElements[0].value
: existingNameElements[0].innerText;
: existingNameElements[0].innerText
// remove trailing colon
.slice(0, -1);
const value = isEditable.value
? existingValueElements[0].value
: existingValueElements[0].innerText;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export function test(maybeStore) {
}

// print() is part of Jest's serializer API
export function print(store, serialize, indent) {
return printStore(store);
export function print(store, serialize, indent, includeSuspense = true) {
return printStore(store, false, null, includeSuspense);
}

// Used for Jest snapshot testing.
Expand Down
Loading
Loading