From 2b3f2e417c4cd3471e9f9bd4ba54b2d363aa2f72 Mon Sep 17 00:00:00 2001 From: Sidharth Rathi Date: Sat, 4 Jun 2022 19:18:13 +0530 Subject: [PATCH] feat: refactor ui to v2 --- .npmrc | 3 + components/playground/Console.tsx | 44 - components/playground/Editor.tsx | 124 - components/playground/Footer.tsx | 61 - components/playground/Header.tsx | 106 - components/playground/Preview.tsx | 166 - components/playground/Resizeable.tsx | 47 - components/playground/index.tsx | 21 - next-env.d.ts | 1 - next.config.js | 13 +- package.json | 98 +- pages/_app.tsx | 14 - pages/index.tsx | 18 - pnpm-lock.yaml | 3172 +++++++++++++ postcss.config.js | 6 - public/icons/css.svg | 1 + public/icons/document.svg | 1 + public/icons/folder-lib-open.svg | 1 + public/icons/folder-lib.svg | 1 + public/icons/folder-open.svg | 3 + public/icons/folder-src-open.svg | 1 + public/icons/folder-src.svg | 1 + public/icons/folder.svg | 3 + public/icons/html.svg | 1 + public/icons/javascript.svg | 1 + public/icons/markdown.svg | 1 + public/icons/typescript.svg | 1 + redux/actions/bundler.actions.ts | 26 - redux/actions/editor.actions.ts | 22 - redux/index.ts | 14 - redux/reducers/bundler.reducer.ts | 43 - redux/reducers/editor.reducer.ts | 87 - src/bundler/index.ts | 0 src/bundler/plugins/helpers.ts | 9 + src/bundler/plugins/resolve.plugin.ts | 2 + src/bundler/plugins/unpkg.plugin.ts | 0 src/components/editor/Editor.tsx | 122 + src/components/editor/index.ts | 1 + src/components/file-tree/file-system.ts | 129 + src/components/file-tree/file-tree-item.tsx | 137 + src/components/file-tree/file-tree.tsx | 40 + src/components/file-tree/index.ts | 2 + src/components/file-tree/use-file-tree.tsx | 97 + src/components/footer/Footer.tsx | 46 + src/components/footer/index.ts | 1 + src/components/header/Header.tsx | 60 + src/components/header/HeaderTabs.tsx | 84 + src/components/header/index.ts | 2 + src/components/playground/Console.tsx | 36 + .../components}/playground/SettingsModal.tsx | 0 src/components/playground/index.tsx | 16 + src/components/preview/Preview.tsx | 94 + src/components/preview/index.ts | 1 + src/components/split-layout/SplitLayout.tsx | 50 + src/components/split-layout/index.ts | 1 + src/hooks/use-dom-element.tsx | 15 + src/hooks/use-isomorphic-effect.tsx | 5 + src/hooks/use-window-dimensions.tsx | 44 + src/pages/_app.tsx | 14 + src/pages/index.tsx | 37 + src/store/editor.ts | 39 + src/store/helpers.ts | 25 + src/styles/global.css | 288 ++ {styles => src/styles}/syntax.css | 32 +- {utils => src/utils}/bundler/fetch.plugin.ts | 0 {utils => src/utils}/bundler/index.ts | 0 .../utils}/bundler/unpkg-path.plugin.ts | 0 {utils => src/utils}/hooks/use-actions.ts | 0 .../utils}/hooks/use-debounced-state.ts | 0 .../utils}/hooks/use-effect-aftermount.ts | 0 .../utils}/hooks/use-isomorphic-effect.ts | 0 {utils => src/utils}/hooks/use-resizeable.ts | 0 {utils => src/utils}/index.ts | 0 {utils => src/utils}/monaco/index.ts | 2 + {utils => src/utils}/monaco/register/index.ts | 25 +- .../utils}/monaco/register/register-emmet.ts | 0 .../utils}/monaco/register/register-jsx.ts | 0 .../monaco/register/register-prettier.ts | 0 .../monaco/register/register-typings.ts | 0 {utils => src/utils}/monaco/theme/dark.js | 0 .../utils}/monaco/theme/night-owl.json | 0 {utils => src/utils}/typings/interfaces.d.ts | 0 {utils => src/utils}/typings/types.d.ts | 69 +- .../workers}/fetch-types.worker.js | 2 +- {workers => src/workers}/index.js | 0 {workers => src/workers}/prettier.worker.js | 0 .../workers}/syntax-highlight.worker.js | 0 styles/tailwind.css | 189 - tailwind.config.js | 17 - tsconfig.json | 2 +- windi.config.ts | 44 + yarn.lock | 3967 ----------------- 92 files changed, 4782 insertions(+), 5066 deletions(-) create mode 100644 .npmrc delete mode 100644 components/playground/Console.tsx delete mode 100644 components/playground/Editor.tsx delete mode 100644 components/playground/Footer.tsx delete mode 100644 components/playground/Header.tsx delete mode 100644 components/playground/Preview.tsx delete mode 100644 components/playground/Resizeable.tsx delete mode 100644 components/playground/index.tsx delete mode 100644 pages/_app.tsx delete mode 100644 pages/index.tsx create mode 100644 pnpm-lock.yaml delete mode 100644 postcss.config.js create mode 100644 public/icons/css.svg create mode 100644 public/icons/document.svg create mode 100644 public/icons/folder-lib-open.svg create mode 100644 public/icons/folder-lib.svg create mode 100644 public/icons/folder-open.svg create mode 100644 public/icons/folder-src-open.svg create mode 100644 public/icons/folder-src.svg create mode 100644 public/icons/folder.svg create mode 100644 public/icons/html.svg create mode 100644 public/icons/javascript.svg create mode 100644 public/icons/markdown.svg create mode 100644 public/icons/typescript.svg delete mode 100644 redux/actions/bundler.actions.ts delete mode 100644 redux/actions/editor.actions.ts delete mode 100644 redux/index.ts delete mode 100644 redux/reducers/bundler.reducer.ts delete mode 100644 redux/reducers/editor.reducer.ts create mode 100644 src/bundler/index.ts create mode 100644 src/bundler/plugins/helpers.ts create mode 100644 src/bundler/plugins/resolve.plugin.ts create mode 100644 src/bundler/plugins/unpkg.plugin.ts create mode 100644 src/components/editor/Editor.tsx create mode 100644 src/components/editor/index.ts create mode 100644 src/components/file-tree/file-system.ts create mode 100644 src/components/file-tree/file-tree-item.tsx create mode 100644 src/components/file-tree/file-tree.tsx create mode 100644 src/components/file-tree/index.ts create mode 100644 src/components/file-tree/use-file-tree.tsx create mode 100644 src/components/footer/Footer.tsx create mode 100644 src/components/footer/index.ts create mode 100644 src/components/header/Header.tsx create mode 100644 src/components/header/HeaderTabs.tsx create mode 100644 src/components/header/index.ts create mode 100644 src/components/playground/Console.tsx rename {components => src/components}/playground/SettingsModal.tsx (100%) create mode 100644 src/components/playground/index.tsx create mode 100644 src/components/preview/Preview.tsx create mode 100644 src/components/preview/index.ts create mode 100644 src/components/split-layout/SplitLayout.tsx create mode 100644 src/components/split-layout/index.ts create mode 100644 src/hooks/use-dom-element.tsx create mode 100644 src/hooks/use-isomorphic-effect.tsx create mode 100644 src/hooks/use-window-dimensions.tsx create mode 100644 src/pages/_app.tsx create mode 100644 src/pages/index.tsx create mode 100644 src/store/editor.ts create mode 100644 src/store/helpers.ts create mode 100644 src/styles/global.css rename {styles => src/styles}/syntax.css (82%) rename {utils => src/utils}/bundler/fetch.plugin.ts (100%) rename {utils => src/utils}/bundler/index.ts (100%) rename {utils => src/utils}/bundler/unpkg-path.plugin.ts (100%) rename {utils => src/utils}/hooks/use-actions.ts (100%) rename {utils => src/utils}/hooks/use-debounced-state.ts (100%) rename {utils => src/utils}/hooks/use-effect-aftermount.ts (100%) rename {utils => src/utils}/hooks/use-isomorphic-effect.ts (100%) rename {utils => src/utils}/hooks/use-resizeable.ts (100%) rename {utils => src/utils}/index.ts (100%) rename {utils => src/utils}/monaco/index.ts (99%) rename {utils => src/utils}/monaco/register/index.ts (87%) rename {utils => src/utils}/monaco/register/register-emmet.ts (100%) rename {utils => src/utils}/monaco/register/register-jsx.ts (100%) rename {utils => src/utils}/monaco/register/register-prettier.ts (100%) rename {utils => src/utils}/monaco/register/register-typings.ts (100%) rename {utils => src/utils}/monaco/theme/dark.js (100%) rename {utils => src/utils}/monaco/theme/night-owl.json (100%) rename {utils => src/utils}/typings/interfaces.d.ts (100%) rename {utils => src/utils}/typings/types.d.ts (50%) rename {workers => src/workers}/fetch-types.worker.js (99%) rename {workers => src/workers}/index.js (100%) rename {workers => src/workers}/prettier.worker.js (100%) rename {workers => src/workers}/syntax-highlight.worker.js (100%) delete mode 100644 styles/tailwind.css delete mode 100644 tailwind.config.js create mode 100644 windi.config.ts delete mode 100644 yarn.lock diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..5ada990 --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +strict-peer-dependencies=false +auto-install-peers=true +registry=https://registry.npmjs.org/ diff --git a/components/playground/Console.tsx b/components/playground/Console.tsx deleted file mode 100644 index e365086..0000000 --- a/components/playground/Console.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import clsx from "clsx"; -import { Console } from "console-feed"; -import React, { MutableRefObject, useEffect, useRef } from "react"; -import { AlertCircle, HelpCircle, Trash2 } from "react-feather"; -import { useDispatch, useSelector } from "react-redux"; -import { RootState } from "../../redux"; -import { CLEAR_LOGS } from "../../redux/actions/editor.actions"; - -export const ConsoleComponent = () => { - const logs = useSelector((s) => s.editor.console); - const dispatch = useDispatch(); - - const handleClear = () => dispatch(CLEAR_LOGS()); - - return ( -
-
- - -
- - -
- -
-
- ); -}; diff --git a/components/playground/Editor.tsx b/components/playground/Editor.tsx deleted file mode 100644 index 1e4702f..0000000 --- a/components/playground/Editor.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import { Listbox } from "@headlessui/react"; -import MonacoEditor, { OnChange, OnMount } from "@monaco-editor/react"; -import React, { useCallback, useRef, useState } from "react"; -import { useDispatch } from "react-redux"; -import { CREATE_BUNDLE } from "../../redux/actions/bundler.actions"; -import { SWITCH_LANG, UPDATE_CODE } from "../../redux/actions/editor.actions"; -import { debounce } from "../../utils"; -import { useTypedSelector } from "../../utils/hooks/use-actions"; -import { useEffectAfterMount } from "../../utils/hooks/use-effect-aftermount"; -import { MonacoConfig } from "../../utils/monaco"; -import { initEditor, initMonaco } from "../../utils/monaco/register"; -import { ICodeEditor } from "../../utils/typings/types"; -import { HeaderPanel } from "./Header"; - -const Editor: React.FC = () => { - const instance = useRef<{ editor: ICodeEditor; format: any } | null>(null); - const activeModel = useRef(); - const dispatch = useDispatch(); - - const active_file = useTypedSelector((s) => s.editor.active_file); - - const code = useTypedSelector((s) => s.editor.files[active_file.type].value); - - useEffectAfterMount(() => { - if (active_file.type === "script") { - let timer: NodeJS.Timeout; - let promise; - timer = setTimeout(() => { - promise = dispatch(CREATE_BUNDLE()); - }, 800); - - return () => { - promise?.abort(); - clearTimeout(timer); - }; - } - }, [code]); - - const onEditorDidMount: OnMount = (editor: ICodeEditor, monaco) => { - const format = editor.getAction("editor.action.formatDocument"); - instance.current = { editor, format }; - - activeModel.current = editor.getModel(); - - initEditor(editor, monaco); - - editor.onDidChangeModelContent(() => debounce(() => editor.saveViewState(), 200)); - }; - - const onChangeHandler = debounce((code) => { - dispatch(UPDATE_CODE({ type: active_file.type, code: code || "" })); - }, 50); - - const formatCode = useCallback(() => instance.current?.format.run(), [instance.current]); - - return ( -
- - Booting Up...} - /> - {active_file.type === "script" && } -
- ); -}; - -const LangSwitcher = ({ file }: any) => { - const formats = [ - { id: 1, name: "Javascript", extension: ".jsx" }, - { id: 2, name: "Typescript", extension: ".tsx" }, - ]; - - const [selectedLang, setSelectedLang] = useState(() => - formats.find((e) => e.extension === "." + file.name.split(".")[1]) - ); - const dispatch = useDispatch(); - - const onLangChange = (e: any) => { - setSelectedLang(e); - dispatch(SWITCH_LANG({ ext: e.extension, lang: e.name.toLowerCase() })); - }; - return ( -
- - - {formats.map((lang) => ( - - {({ active, selected }) => ( - - {lang.name} - - )} - - ))} - - {selectedLang?.name} - -
- ); -}; - -export default Editor; diff --git a/components/playground/Footer.tsx b/components/playground/Footer.tsx deleted file mode 100644 index 12d7307..0000000 --- a/components/playground/Footer.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import clsx from "clsx"; -import { AlertOctagon, BatteryCharging, PhoneIncoming } from "react-feather"; -import { useSelector } from "react-redux"; -import { RootState } from "../../redux"; - -export const FooterPanel = () => { - const isBundling = useSelector((s) => s.bundler.isBundling); - const isInitialized = useSelector((s) => s.bundler.initialized); - const hasError = useSelector((s) => s.bundler.hasError); - - return ( -
-
- {isBundling || !isInitialized ? ( - - ) : hasError ? ( - - ) : ( - - )} - - Bundler state:{" "} - - {!hasError && !isInitialized - ? "Initializing..." - : hasError - ? "Bundling Error" - : isBundling - ? "Bundling..." - : "Idle"} - - -
-
- ); -}; - -const Loader = () => { - return ( - - - - - ); -}; diff --git a/components/playground/Header.tsx b/components/playground/Header.tsx deleted file mode 100644 index f6f01a7..0000000 --- a/components/playground/Header.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import clsx from "clsx"; -import { memo, useCallback, useState } from "react"; -import { AlignLeft, Settings, Zap } from "react-feather"; -import { useDispatch } from "react-redux"; -import { CREATE_BUNDLE } from "../../redux/actions/bundler.actions"; -import { SWITCH_FILE } from "../../redux/actions/editor.actions"; -import { useTypedSelector } from "../../utils/hooks/use-actions"; -import { SettingsModal } from "./SettingsModal"; - -export const HeaderPanel: React.FC<{ onFormat: any }> = memo(({ onFormat }) => { - const dispatch = useDispatch(); - - const active_file = useTypedSelector((s) => s.editor.active_file); - const [isOpen, setIsOpen] = useState(false); - - const runCode = useCallback(() => { - let timer = setTimeout(() => { - dispatch(CREATE_BUNDLE()); - }, 50); - - return () => clearTimeout(timer); - }, []); - - return ( - <> - -
- - -
- - -
-
- - ); -}); - -HeaderPanel.displayName = "HeaderPanel"; - -export const Tabs = ({ active_file }) => { - const filesObj = useTypedSelector((s) => s.editor.files); - const files = Object.keys(filesObj); - - return ( -
- {files.map((file: any) => ( - - ))} -
- ); -}; - -const Tab = ({ name, isActive, lang, type }: any) => { - const dispatch = useDispatch(); - - const handleClick = () => { - if (isActive) return; - dispatch(SWITCH_FILE({ lang, name, type })); - }; - - return ( - - ); -}; diff --git a/components/playground/Preview.tsx b/components/playground/Preview.tsx deleted file mode 100644 index 6c704e3..0000000 --- a/components/playground/Preview.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import { Transition } from "@headlessui/react"; -import clsx from "clsx"; -import { useCallback, useEffect, useRef } from "react"; -import Loader from "react-loader-spinner"; -import { useDispatch, useSelector } from "react-redux"; -import { RootState } from "../../redux"; -import { CREATE_BUNDLE } from "../../redux/actions/bundler.actions"; -import { PRINT_CONSOLE } from "../../redux/actions/editor.actions"; -import { ConsoleComponent } from "./Console"; -import { Resizeable } from "./Resizeable"; - -export const Preview: React.FC = () => { - const iFrameRef = useRef(null); - const dispatch = useDispatch(); - const javascript = useSelector((s) => s.bundler.bundle); - const isInit = useSelector((s) => s.bundler.initialized); - const html = useSelector((s) => s.editor.files.markup.value); - const css = useSelector((s) => s.editor.files.styles.value); - - const loadCode = useCallback( - (e: HTMLIFrameElement) => { - e.contentWindow!.postMessage({ html: html }, "*"); - e.contentWindow!.postMessage({ css: css }, "*"); - e.contentWindow!.postMessage({ javascript: javascript }, "*"); - }, - [html, css, javascript] - ); - - useEffect(() => { - if (iFrameRef.current) { - loadCode(iFrameRef.current); - } - }, [javascript, css, html]); - - useEffect(() => { - if (!javascript) { - dispatch(CREATE_BUNDLE()); - } - - const handler = (event: any) => { - if (event.data.type === "console") { - console[event.data.method](JSON.parse(event.data.data).join(" ")); - dispatch( - PRINT_CONSOLE({ - method: event.data.method, - data: JSON.parse(event.data.data), - }) - ); - } - }; - - window.addEventListener("message", handler); - - return () => window.removeEventListener("message", handler); - }, []); - - return ( - -
- - - -