From e2241eec628af5a930ac83d4b8577588b544b95d Mon Sep 17 00:00:00 2001 From: Garet McKinley Date: Mon, 17 Sep 2018 01:04:13 -0500 Subject: [PATCH 1/4] add LoadingState component --- src/components/LoadingState/Wrapper.js | 47 ++++++++++++++++++++++++++ src/components/LoadingState/index.js | 14 ++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/components/LoadingState/Wrapper.js create mode 100644 src/components/LoadingState/index.js diff --git a/src/components/LoadingState/Wrapper.js b/src/components/LoadingState/Wrapper.js new file mode 100644 index 0000000..f7eab68 --- /dev/null +++ b/src/components/LoadingState/Wrapper.js @@ -0,0 +1,47 @@ +import styled from "styled-components"; + +const Wrapper = styled.div` + position: absolute; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + background: ${props => props.theme.header_background}; + + div { + display: inline-block; + position: relative; + width: 64px; + height: 64px; + } + div span { + position: absolute; + border: 4px solid #fff; + opacity: 1; + border-radius: 50%; + animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite; + } + div span:nth-child(2) { + animation-delay: -0.5s; + } + + @keyframes lds-ripple { + 0% { + top: 28px; + left: 28px; + width: 0; + height: 0; + opacity: 1; + } + 100% { + top: -1px; + left: -1px; + width: 58px; + height: 58px; + opacity: 0; + } + } +`; + +export default Wrapper; diff --git a/src/components/LoadingState/index.js b/src/components/LoadingState/index.js new file mode 100644 index 0000000..98dcb02 --- /dev/null +++ b/src/components/LoadingState/index.js @@ -0,0 +1,14 @@ +import React from "react"; + +import Wrapper from "./Wrapper"; + +const LoadingState = () => ( + +
+ + +
+
+); + +export default LoadingState; From d1d8c4c56a254f5c81d25451aad7477e3085a8d1 Mon Sep 17 00:00:00 2001 From: Garet McKinley Date: Mon, 17 Sep 2018 01:04:27 -0500 Subject: [PATCH 2/4] add react-loadable and upgrade styled-components --- package.json | 3 ++- yarn.lock | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ecc866c..f68ec84 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,9 @@ "react-dom": "^16.5.0", "react-dropdown": "^1.6.2", "react-dropzone": "^5.0.1", + "react-loadable": "^5.5.0", "react-scripts": "1.1.5", - "styled-components": "^4.0.0-beta.0-2" + "styled-components": "^4.0.0-beta.5" }, "scripts": { "analyze": "source-map-explorer build/static/js/main.*", diff --git a/yarn.lock b/yarn.lock index d1aab64..d4ae70a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5511,7 +5511,7 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.2: +prop-types@^15.0.0, prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" dependencies: @@ -5702,6 +5702,12 @@ react-is@^16.3.1, react-is@^16.3.2, react-is@^16.5.0: version "16.5.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.5.0.tgz#2ec7c192709698591efe13722fab3ef56144ba55" +react-loadable@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/react-loadable/-/react-loadable-5.5.0.tgz#582251679d3da86c32aae2c8e689c59f1196d8c4" + dependencies: + prop-types "^15.5.0" + react-scripts@1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-1.1.5.tgz#3041610ab0826736b52197711a4c4e3756e97768" @@ -6558,9 +6564,9 @@ style-loader@0.19.0: loader-utils "^1.0.2" schema-utils "^0.3.0" -styled-components@^4.0.0-beta.0-2: - version "4.0.0-beta.0-2" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-4.0.0-beta.0-2.tgz#a9982c4f4593cd55b0c614176c3ab5625c846c9c" +styled-components@^4.0.0-beta.5: + version "4.0.0-beta.5" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-4.0.0-beta.5.tgz#b6092346e49720b0e6df8a1d2e42334ca298735a" dependencies: "@emotion/is-prop-valid" "^0.6.5" css-to-react-native "^2.0.3" From b0442b525305c3f89d705577a84f8932a2f553db Mon Sep 17 00:00:00 2001 From: Garet McKinley Date: Mon, 17 Sep 2018 01:04:58 -0500 Subject: [PATCH 3/4] lazy-load Editor container --- src/App.js | 11 ++++------- src/components/Preview/index.js | 1 + src/containers/Editor/Async.js | 11 +++++++++++ src/containers/Editor/index.js | 15 ++++++++++++--- src/styles/global.js | 6 ++++++ 5 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 src/containers/Editor/Async.js diff --git a/src/App.js b/src/App.js index 3235e58..40fa164 100644 --- a/src/App.js +++ b/src/App.js @@ -2,7 +2,7 @@ import React, { PureComponent } from "react"; import { ThemeProvider } from "styled-components"; import Grid from "hedron"; -import Editor from "./containers/Editor"; +import Editor from "./containers/Editor/Async"; import Header from "./components/Header"; import { downloadMarkdown } from "./utils"; @@ -32,16 +32,12 @@ export default class App extends PureComponent { markdown: "", theme, // TODO: implement a less ugly method to handle this require - theme_data: require(`./styles/themes/${theme}`).default, + theme_data: require(`./styles/themes/${theme}`).default }; // bind(this) allows `this` to be used from within our functions this.download = this.download.bind(this); this.editorChanged = this.editorChanged.bind(this); - - // Initialize all the themes - // TODO: figure out how to avoid loading themes until they're changed - config.themes.forEach(theme => require(`brace/theme/${theme.value}`)); } componentDidMount() { @@ -61,7 +57,7 @@ export default class App extends PureComponent { this.setState( { theme: theme.value, - theme_data: require(`./styles/themes/${theme.value}`).default, + theme_data: require(`./styles/themes/${theme.value}`).default }, () => localStorage.setItem("theme", theme.value) ); @@ -104,6 +100,7 @@ export default class App extends PureComponent { diff --git a/src/components/Preview/index.js b/src/components/Preview/index.js index bc78a43..e9e0c46 100644 --- a/src/components/Preview/index.js +++ b/src/components/Preview/index.js @@ -11,4 +11,5 @@ export default styled(Grid.Box)` overflow: auto; word-wrap: break-word; padding: 5px 25px; + background: white; `; diff --git a/src/containers/Editor/Async.js b/src/containers/Editor/Async.js new file mode 100644 index 0000000..e743274 --- /dev/null +++ b/src/containers/Editor/Async.js @@ -0,0 +1,11 @@ +import React from "react"; +import Loadable from "react-loadable"; + +import LoadingState from "../../components/LoadingState"; + +const EditorAsync = Loadable({ + loader: () => import("./"), + loading: LoadingState +}); + +export default EditorAsync; diff --git a/src/containers/Editor/index.js b/src/containers/Editor/index.js index 84cb29a..195e4f9 100644 --- a/src/containers/Editor/index.js +++ b/src/containers/Editor/index.js @@ -24,7 +24,7 @@ class Editor extends PureComponent { super(props); this.state = { - code: null, + code: null }; } componentWillMount() { @@ -32,6 +32,14 @@ class Editor extends PureComponent { this.onDrop = this.onDrop.bind(this); } + componentDidMount = () => { + if (typeof this.props.themes === "object") { + // Initialize all the themes + // TODO: figure out how to avoid loading themes until they're changed + this.props.themes.forEach(theme => require(`brace/theme/${theme.value}`)); + } + }; + setTheme = theme => { require(`brace/theme/${theme}`); }; @@ -57,7 +65,7 @@ class Editor extends PureComponent { let options = { fontFamily: "Monaco, monospace", showLineNumbers: false, - showGutter: false, + showGutter: false }; return ( @@ -65,6 +73,7 @@ class Editor extends PureComponent { {window && ( diff --git a/src/styles/global.js b/src/styles/global.js index f0ff352..66c524c 100644 --- a/src/styles/global.js +++ b/src/styles/global.js @@ -6,5 +6,11 @@ export default createGlobalStyle` padding: 0; font-family: 'Inter UI', sans-serif; font-weight: 300; + background: ${props => props.theme.header_background}; + } + + /* Prevent flicker when loading ace theme */ + .ace_scroller { + background: ${props => props.theme.header_background} !important; } `; From 5cd66b3aee26d97938acef050af4ad3870e1b531 Mon Sep 17 00:00:00 2001 From: Garet McKinley Date: Mon, 17 Sep 2018 01:24:23 -0500 Subject: [PATCH 4/4] position LoadingState to top of page --- src/components/LoadingState/Wrapper.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/LoadingState/Wrapper.js b/src/components/LoadingState/Wrapper.js index f7eab68..569129a 100644 --- a/src/components/LoadingState/Wrapper.js +++ b/src/components/LoadingState/Wrapper.js @@ -2,6 +2,7 @@ import styled from "styled-components"; const Wrapper = styled.div` position: absolute; + top: 0; width: 100%; height: 100%; display: flex;