Skip to content

Commit

Permalink
Converted React Live codebase to TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
carloskelly13 committed Mar 29, 2023
1 parent 20d789a commit b3c8d00
Show file tree
Hide file tree
Showing 41 changed files with 657 additions and 422 deletions.
5 changes: 3 additions & 2 deletions .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"loose": true
}
],
"@babel/preset-react"
"@babel/preset-typescript",
["@babel/preset-react", { "runtime": "automatic" }]
],
"plugins": [
"add-module-exports",
Expand All @@ -21,4 +22,4 @@
}
]
]
}
}
5 changes: 5 additions & 0 deletions .changeset/ninety-boats-sit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-live": major
---

Migrated codebase to TypeScript.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"root": true,
"parser": "@babel/eslint-parser",
"plugins": ["prettier"],
"plugins": ["prettier", "@typescript-eslint"],
"settings": {
"react": {
"version": "detect"
}
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:import/recommended"
],
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/code-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ jobs:
- name: Test
run: yarn run test

- name: Type Check
run: yarn run typecheck

- name: Library Build
run: yarn run build

Expand Down
5 changes: 3 additions & 2 deletions .storybook/.babelrc
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
"@babel/preset-typescript",
["@babel/preset-react", { "runtime": "automatic" }]
],
"plugins": [
"add-module-exports",
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-proposal-class-properties"
]
}
}
2 changes: 1 addition & 1 deletion .storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
"stories": [
"../stories/**/*js"
"../src/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-controls",
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# React-Live Changelog

## 4.0.0

* Migrated codebase over to TypeScript
* Added support for TypeScript-based components in the React Live editor

## 3.2.0

### Minor Changes
Expand Down
18 changes: 13 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "3.2.0",
"description": "A production-focused playground for live editing React code",
"main": "dist/react-live.cjs.js",
"typings": "./typings/react-live.d.ts",
"types": "dist/index.d.ts",
"jsnext:main": "dist/react-live.es.js",
"module": "dist/react-live.es.js",
"license": "MIT",
Expand All @@ -16,6 +16,7 @@
"prepublishOnly": "npm run build",
"test": "jest",
"test:typings": "typings-tester --dir typings",
"typecheck": "tsc --noEmit",
"lint": "eslint --config .eslintrc \"./src/**/*.js\"",
"install:docs": "yarn --cwd website install",
"start:docs": "yarn --cwd website start",
Expand All @@ -37,17 +38,23 @@
"@babel/plugin-transform-runtime": "^7.15.0",
"@babel/preset-env": "^7.15.0",
"@babel/preset-react": "^7.14.5",
"@babel/preset-typescript": "^7.21.0",
"@changesets/cli": "^2.26.1",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-commonjs": "^20.0.0",
"@rollup/plugin-node-resolve": "^13.0.4",
"@rollup/plugin-replace": "^3.0.0",
"@rollup/plugin-typescript": "^11.0.0",
"@storybook/addon-controls": "^6.4.13",
"@storybook/builder-webpack5": "^6.5.16",
"@storybook/manager-webpack5": "^6.5.16",
"@storybook/react": "^6.4.13",
"@svitejs/changesets-changelog-github-compact": "^1.1.0",
"@types/react": "^17.0.38",
"@types/prismjs": "^1.26.0",
"@types/react": "^18.0.31",
"@types/styled-components": "^5.1.26",
"@typescript-eslint/eslint-plugin": "^5.57.0",
"@typescript-eslint/parser": "^5.57.0",
"babel-jest": "^27.0.6",
"babel-loader": "^8.2.2",
"babel-plugin-add-module-exports": "^1.0.4",
Expand All @@ -61,15 +68,16 @@
"prettier": "^2.5.1",
"prismjs": "^1.26.0",
"prop-types": "^15.7.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "^18.2.0",
"react-docgen-typescript": "^2.2.2",
"react-dom": "^18.2.0",
"react-test-renderer": "^17.0.2",
"rollup": "^2.55.1",
"rollup-plugin-filesize": "^9.1.1",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-visualizer": "^5.5.4",
"styled-components": "^4.0.0-beta.8",
"typescript": "^2.9.2",
"typescript": "^4.9",
"typings-tester": "^0.3.1",
"webpack": "^5.76.3"
},
Expand Down
7 changes: 6 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { babel } from "@rollup/plugin-babel";
import { terser } from "rollup-plugin-terser";
import filesize from "rollup-plugin-filesize";
import { visualizer } from "rollup-plugin-visualizer";
import typescript from "@rollup/plugin-typescript";

const plugins = [
nodeResolve({
Expand Down Expand Up @@ -33,13 +34,15 @@ const plugins = [
];

const devPlugins = plugins.concat([
typescript(),
replace({
"process.env.NODE_ENV": JSON.stringify("development"),
preventAssignment: true,
}),
]);

const prodPlugins = plugins.concat([
typescript(),
replace({
"process.env.NODE_ENV": JSON.stringify("production"),
preventAssignment: true,
Expand All @@ -50,19 +53,21 @@ const prodPlugins = plugins.concat([
]);

const base = {
input: "src/index.js",
input: "src/index.ts",
external: [
"react",
"react-dom",
"prop-types",
"prism-react-renderer",
"sucrase",
"react/jsx-runtime",
],
};

const output = {
exports: "named",
globals: {
"react/jsx-runtime": "jsx-runtime",
"prism-react-renderer": "Prism",
react: "React",
sucrase: "Sucrase",
Expand Down
36 changes: 18 additions & 18 deletions src/components/Editor/index.js → src/components/Editor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
import Highlight, { Prism } from "prism-react-renderer";
import PropTypes from "prop-types";
import React, { useCallback, useEffect, useRef, useState } from "react";
import Highlight, { Language, Prism, PrismTheme } from "prism-react-renderer";
import { CSSProperties, useCallback, useEffect, useRef, useState } from "react";
import { useEditable } from "use-editable";
import { theme as liveTheme } from "../../constants/theme";

const CodeEditor = (props) => {
export type Props = {
className?: string;
code: string;
disabled?: boolean;
language: Language;
prism?: typeof Prism;
style?: CSSProperties;
tabMode?: "focus" | "indentation";
theme?: PrismTheme;
onChange?(value: string): void;
};

const CodeEditor = (props: Props) => {
const editorRef = useRef(null);
const [code, setCode] = useState(props.code || "");

useEffect(() => {
setCode(props.code);
}, [props.code]);

const onEditableChange = useCallback((_code) => {
const onEditableChange = useCallback((_code: string) => {
setCode(_code.slice(0, -1));
}, []);

Expand Down Expand Up @@ -41,6 +52,7 @@ const CodeEditor = (props) => {
getLineProps,
getTokenProps,
style: _style,
/* @ts-ignore — this property exists but the lib's types are incorrect */
theme: _theme,
}) => (
<pre
Expand Down Expand Up @@ -79,20 +91,8 @@ const CodeEditor = (props) => {
);
};

CodeEditor.propTypes = {
className: PropTypes.string,
code: PropTypes.string,
disabled: PropTypes.bool,
language: PropTypes.string,
onChange: PropTypes.func,
prism: PropTypes.object,
style: PropTypes.object,
tabMode: PropTypes.oneOf(["focus", "indentation"]),
theme: PropTypes.object,
};

CodeEditor.defaultProps = {
tabMode: "indentation",
};
} as Pick<Props, "tabMode">;

export default CodeEditor;
5 changes: 0 additions & 5 deletions src/components/Live/LiveContext.js

This file was deleted.

17 changes: 17 additions & 0 deletions src/components/Live/LiveContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Language, PrismTheme } from "prism-react-renderer";
import { ComponentType, createContext } from "react";

type ContextValue = {
error?: string;
element?: ComponentType | null;
code: string;
disabled: boolean;
language: Language;
theme?: PrismTheme;
onError(error: Error): void;
onChange(value: string): void;
}

const LiveContext = createContext<ContextValue>({} as ContextValue);

export default LiveContext;
16 changes: 10 additions & 6 deletions stories/Editor.js → src/components/Live/LiveEditor.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import React from "react";
import Prism from "prismjs";
import { Editor } from "../src/index";
import { Editor } from "../../index";
import type { Story } from "@storybook/react";

export default {
title: "Editor",
component: Editor,
};

const Template = (args) => <Editor {...args} />;
const Template = (args: any) => <Editor {...args} />;

const defaultArgs = {
language: "js",
code: "const x = 'Hello World!';",
};

export const Default = Template.bind({});
export const Default: Story = Template.bind({});
Default.args = defaultArgs;

export const FontFamilyExample = Template.bind({});
export const FontFamilyExample: Story = Template.bind({});
FontFamilyExample.args = {
...defaultArgs,
style: {
Expand All @@ -27,5 +27,9 @@ FontFamilyExample.args = {

// Can't pass Prism as an arg since it is not JSON-serializable
export const PrismFromNpm = () => (
<Editor language="js" prism={Prism} code="const x = 'Hello World!';" />
<Editor
language="javascript"
prism={Prism as any}
code="const x = 'Hello World!';"
/>
);
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useContext } from "react";
import LiveContext from "./LiveContext";
import Editor from "../Editor";
import Editor, { Props as EditorProps } from "../Editor";

export default function LiveEditor(props) {
export default function LiveEditor(props: Partial<EditorProps>) {
const { code, language, theme, disabled, onChange } = useContext(LiveContext);

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useContext } from "react";
import LiveContext from "./LiveContext";

export default function LiveError(props) {
export default function LiveError<T extends Record<string, unknown>>(props: T) {
const { error } = useContext(LiveContext);
return error ? <pre {...props}>{error}</pre> : null;
}
18 changes: 0 additions & 18 deletions src/components/Live/LivePreview.js

This file was deleted.

16 changes: 16 additions & 0 deletions src/components/Live/LivePreview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React, { PropsWithChildren, useContext } from "react";
import LiveContext from "./LiveContext";

type Props = {
Component?: React.ComponentType<PropsWithChildren<Record<string, unknown>>>;
};

const fallbackComponent = (
props: PropsWithChildren<Record<string, unknown>>
) => <div {...props} />;

function LivePreview({ Component = fallbackComponent, ...rest }: Props) {
const { element: Element } = useContext(LiveContext);
return <Component {...rest}>{Element ? <Element /> : null}</Component>;
}
export default LivePreview;
Loading

0 comments on commit b3c8d00

Please sign in to comment.