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
72 changes: 10 additions & 62 deletions editor/components/app-runner/react-app-runner.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { k } from "@designto/react";
import React from "react";
import { CodeSandBoxView } from "./code-sandbox-runner";

Expand All @@ -13,80 +14,27 @@ export function ReactAppRunner(props: {
sandbox={{
files: {
"App.tsx": {
content: props.source,
content: k.create_react_app_typescript_starter.app_tsx(
props.source
),
isBinary: false,
},
"index.tsx": {
content: `
import React from "react";
import { render } from "react-dom";

import ${props.componentName} from "./App";

const rootElement = document.getElementById("root");
render(<${props.componentName} />, rootElement);
`,
content: k.create_react_app_typescript_starter.index_tsx(
props.componentName
),
isBinary: false,
},
"tsconfig.json": {
content: `
{
"include": [
"./src/**/*"
],
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"lib": [
"dom",
"es2015"
],
"jsx": "react-jsx"
}
}`,
content: k.create_react_app_typescript_starter.tsconfig_json,
isBinary: false,
},
"package.json": {
content: `
{
"name": "react-typescript",
"version": "1.0.0",
"description": "React and TypeScript example starter project",
"keywords": [
"typescript",
"react",
"starter"
],
"main": "src/index.tsx",
"dependencies": {
"react": "17.0.2",
"react-dom": "17.0.2",
"react-scripts": "4.0.0",
"@emotion/react": "^11.1.5",
"@emotion/styled": "^11.1.5"
},
"devDependencies": {
"@types/react": "17.0.0",
"@types/react-dom": "17.0.0",
"typescript": "4.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}`,
content: k.create_react_app_typescript_starter.package_json,
isBinary: false,
},
},
template: "create-react-app-typescript",
template: k.create_react_app_typescript_starter.template as any,
}}
width={props.width}
height={props.height}
Expand Down
79 changes: 46 additions & 33 deletions editor/components/code-editor/code-editor.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,53 @@
//// dynamic code editor. supports codemirror & monaco
import React from "react";
import CodeMirror from "./code-mirror";
import { MonacoEditor } from "./monaco";
import React, { useState } from "react";
import { MonacoEditor, MonacoEditorProps as MonacoEditorProps } from "./monaco";
import { Tabs, Tab } from "@material-ui/core";

interface DynamicEdotorProps {
host?: _Host;
export interface CodeEditorProps
extends Omit<MonacoEditorProps, "defaultValue" | "defaultLanguage"> {}
export interface IFile {
name: string;
language: string;
raw: string;
}

type _Host = "codemirror" | "monaco" | "auto";
// uses monaco by default. when set auto or host not provided.
const fallbackAutoHost = "monaco";
export type Files = { [name: string]: IFile };

export function CodeEditor(props: DynamicEdotorProps) {
const _editorname = getTargetEditorName(props.host);
export function CodeEditor({
files,
...editor_props
}: {
files: Files;
} & CodeEditorProps) {
const keys = Object.keys(files);
const [filekey, setFilekey] = useState<string>(keys[0]);
const getfile = (key: string) => files[key];
const handleChange = (event, newValue) => {
setFilekey(newValue);
};

switch (_editorname) {
case "codemirror":
return <CodeMirror />;
case "monaco":
return <MonacoEditor />;
}
}

function getTargetEditorName(host?: _Host): "codemirror" | "monaco" {
if (!host) {
return fallbackAutoHost;
}

switch (host) {
case "auto":
return fallbackAutoHost;
case "codemirror":
return "codemirror";
case "monaco":
return "monaco";
}
const file = getfile(filekey);

throw `invalid host option provided - "${host}"`;
return (
<>
{keys.length >= 2 && (
<Tabs
value={filekey}
onChange={handleChange}
variant="scrollable"
scrollButtons="off"
aria-label="scrollable prevent tabs example"
>
{Object.keys(files).map((name) => {
return <Tab key={name} label={name} value={name} />;
})}
</Tabs>
)}
<MonacoEditor
key={filekey}
{...editor_props}
defaultLanguage={file.language}
defaultValue={file.raw}
/>
</>
);
}
58 changes: 31 additions & 27 deletions editor/components/code-editor/monaco.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,22 @@
import React, { useEffect } from "react";
import Editor, { useMonaco } from "@monaco-editor/react";
import Editor, { useMonaco, Monaco } from "@monaco-editor/react";
import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
import _react_type_def_txt from "./react.d.ts.txt";

interface EditorProps {
export interface MonacoEditorProps {
defaultValue?: string;
defaultLanguage?: string;
width?: number | string;
height?: number | string;
options?: monaco.editor.IStandaloneEditorConstructionOptions;
}

export function MonacoEditor(props: EditorProps) {
const monaco = useMonaco();
export function MonacoEditor(props: MonacoEditorProps) {
const monaco: Monaco = useMonaco();
useEffect(() => {
// adding jsx support - https://github.com/microsoft/monaco-editor/issues/264
if (monaco) {
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
target: monaco.languages.typescript.ScriptTarget.Latest,
allowNonTsExtensions: true,
moduleResolution:
monaco.languages.typescript.ModuleResolutionKind.NodeJs,
module: monaco.languages.typescript.ModuleKind.CommonJS,
noEmit: true,
esModuleInterop: true,
jsx: monaco.languages.typescript.JsxEmit.React,
reactNamespace: "React",
allowJs: true,
});

monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
noSemanticValidation: false,
noSyntaxValidation: false,
});

monaco.languages.typescript.typescriptDefaults.addExtraLib(
_react_type_def_txt
);
setup_react_support(monaco);
// monaco.mo
}
}, [monaco]);

Expand All @@ -49,7 +29,7 @@ export function MonacoEditor(props: EditorProps) {
}
defaultValue={props.defaultValue ?? "// no content"}
theme="vs-dark"
options={props.options}
options={{ ...props.options }}
/>
);
}
Expand All @@ -65,4 +45,28 @@ const pollyfill_language = (lang: string) => {
}
};

function setup_react_support(monaco: Monaco) {
// adding jsx support - https://github.com/microsoft/monaco-editor/issues/264
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
target: monaco.languages.typescript.ScriptTarget.Latest,
allowNonTsExtensions: true,
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
module: monaco.languages.typescript.ModuleKind.CommonJS,
noEmit: true,
esModuleInterop: true,
jsx: monaco.languages.typescript.JsxEmit.React,
reactNamespace: "React",
allowJs: true,
});

monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
noSemanticValidation: false,
noSyntaxValidation: false,
});

monaco.languages.typescript.typescriptDefaults.addExtraLib(
_react_type_def_txt
);
}

export { useMonaco } from "@monaco-editor/react";
4 changes: 2 additions & 2 deletions editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
"@emotion/core": "^11.0.0",
"@emotion/react": "^11.1.5",
"@emotion/styled": "^11.1.5",
"@material-ui/core": "^4.11.4",
"@material-ui/core": "^4.12.3",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^4.0.0-alpha.58",
"@material-ui/lab": "^4.0.0-alpha.60",
"@monaco-editor/react": "^4.1.3",
"@reflect-blocks/figma-embed": "^0.0.5",
"@reflect-ui/editor-ui": "0.0.1",
Expand Down
19 changes: 19 additions & 0 deletions editor/pages/_development/code-editor/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from "react";
import { CodeEditor, Files } from "../../../components/code-editor";

export default function CodeEditorDevPage() {
const files: Files = {
"index.ts": {
name: "index.ts",
language: "typescript",
raw: `export * from "./components"`,
},
"components/index.ts": {
name: "index.ts",
language: "typescript",
raw: `export * from "./app-bar"`,
},
};

return <CodeEditor height="100vh" files={files} />;
}
21 changes: 12 additions & 9 deletions editor/pages/figma/to-flutter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from "../../layout/panel";
import { PreviewAndRunPanel } from "../../components/preview-and-run";
import { useDesign } from "../../query-hooks";
import { MonacoEditor } from "../../components/code-editor";
import { CodeEditor, MonacoEditor } from "../../components/code-editor";
import LoadingLayout from "../../layout/loading-overlay";

export default function FigmaToFlutterPage() {
Expand Down Expand Up @@ -81,18 +81,21 @@ export default function FigmaToFlutterPage() {
</WorkspaceContentPanel>
<WorkspaceContentPanel>
<InspectionPanelContentWrap>
<MonacoEditor
key={widgetCode}
<CodeEditor
// key={widgetCode}
height="100vh"
options={{
automaticLayout: true,
}}
defaultLanguage="dart"
defaultValue={
widgetCode
? widgetCode
: "// No input design provided to be converted.."
}
files={{
"index.tsx": {
raw: widgetCode
? widgetCode
: "// No input design provided to be converted..",
language: "dart",
name: "index.tsx",
},
}}
/>
</InspectionPanelContentWrap>
</WorkspaceContentPanel>
Expand Down
18 changes: 11 additions & 7 deletions editor/pages/figma/to-react.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from "../../layout/panel";
import { WorkspaceBottomPanelDockLayout } from "../../layout/panel/workspace-bottom-panel-dock-layout";
import { WidgetTree } from "../../components/visualization/json-visualization/json-tree";
import { MonacoEditor } from "../../components/code-editor";
import { CodeEditor } from "../../components/code-editor";
import { tokenize } from "@designto/token";
import * as react from "@designto/react";
import { mapGrandchildren } from "@design-sdk/core/utils";
Expand Down Expand Up @@ -78,17 +78,21 @@ export default function FigmaToReactDemoPage() {
</WorkspaceContentPanel>
<WorkspaceContentPanel key={targetNodeConfig?.node}>
<InspectionPanelContentWrap>
<MonacoEditor
<CodeEditor
key={reactComponent?.code.raw}
height="100vh"
options={{
automaticLayout: true,
}}
defaultValue={
reactComponent?.code
? reactComponent?.code.raw
: "// No input design provided to be converted.."
}
files={{
"index.tsx": {
raw: reactComponent?.code
? reactComponent?.code.raw
: "// No input design provided to be converted..",
language: "typescript",
name: "index.tsx",
},
}}
/>
</InspectionPanelContentWrap>
</WorkspaceContentPanel>
Expand Down
Loading