Add basic codemirror (#96)

* started work on codemirror integration
This commit is contained in:
mrdrogdrog 2020-06-11 20:14:40 +02:00 committed by GitHub
parent e9c16872d4
commit 46d68c3ab5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 322 additions and 10 deletions

View file

@ -6,6 +6,7 @@
"@testing-library/jest-dom": "5.10.0", "@testing-library/jest-dom": "5.10.0",
"@testing-library/react": "10.2.1", "@testing-library/react": "10.2.1",
"@testing-library/user-event": "11.4.1", "@testing-library/user-event": "11.4.1",
"@types/codemirror": "^0.0.95",
"@types/jest": "26.0.0", "@types/jest": "26.0.0",
"@types/node": "12.12.47", "@types/node": "12.12.47",
"@types/node-sass": "4.11.1", "@types/node-sass": "4.11.1",
@ -20,6 +21,7 @@
"@typescript-eslint/eslint-plugin": "3.2.0", "@typescript-eslint/eslint-plugin": "3.2.0",
"@typescript-eslint/parser": "3.2.0", "@typescript-eslint/parser": "3.2.0",
"bootstrap": "4.5.0", "bootstrap": "4.5.0",
"codemirror": "^5.54.0",
"eslint-config-react-app": "5.2.1", "eslint-config-react-app": "5.2.1",
"eslint-config-standard": "14.1.1", "eslint-config-standard": "14.1.1",
"eslint-plugin-flowtype": "5.1.3", "eslint-plugin-flowtype": "5.1.3",
@ -37,6 +39,7 @@
"react": "16.13.1", "react": "16.13.1",
"react-bootstrap": "1.0.1", "react-bootstrap": "1.0.1",
"react-bootstrap-typeahead": "5.0.0-rc.3", "react-bootstrap-typeahead": "5.0.0-rc.3",
"react-codemirror2": "^7.2.0",
"react-dom": "16.13.1", "react-dom": "16.13.1",
"react-i18next": "11.5.0", "react-i18next": "11.5.0",
"react-redux": "7.2.0", "react-redux": "7.2.0",

View file

@ -9,7 +9,7 @@ export interface LoadingScreenProps {
export const LoadingScreen: React.FC<LoadingScreenProps> = ({ failedTitle }) => { export const LoadingScreen: React.FC<LoadingScreenProps> = ({ failedTitle }) => {
return ( return (
<div className="loader middle"> <div className="loader middle text-white">
<div className="icon text-white"> <div className="icon text-white">
<ForkAwesomeIcon icon="file-text" size="5x" <ForkAwesomeIcon icon="file-text" size="5x"
className={failedTitle ? 'animation-shake' : 'animation-pulse'}/> className={failedTitle ? 'animation-shake' : 'animation-pulse'}/>

View file

@ -0,0 +1,6 @@
@import '../../../../node_modules/codemirror/lib/codemirror.css';
@import './one-dark.css';
.CodeMirror {
height: 100%;
}

View file

@ -1,10 +1,66 @@
import React from 'react' import 'codemirror/addon/comment/comment'
import 'codemirror/addon/display/placeholder'
import 'codemirror/addon/edit/closebrackets'
import 'codemirror/addon/edit/closetag'
import 'codemirror/addon/edit/continuelist'
import 'codemirror/addon/edit/matchbrackets'
import 'codemirror/addon/edit/matchtags'
import 'codemirror/addon/fold/foldcode'
import 'codemirror/addon/fold/foldgutter'
import 'codemirror/addon/search/match-highlighter'
import 'codemirror/addon/selection/active-line'
import 'codemirror/keymap/sublime.js'
import 'codemirror/mode/gfm/gfm.js'
import React, { useState } from 'react'
import { Controlled as ControlledCodeMirror } from 'react-codemirror2'
import './editor-window.scss'
const EditorWindow: React.FC = () => { const EditorWindow: React.FC = () => {
const [content, setContent] = useState<string>('')
return ( return (
<div style={{ backgroundColor: 'green' }}> <ControlledCodeMirror
Hello, EditorWindow! className="h-100 w-100"
</div> value={content}
options={{
mode: 'gfm',
theme: 'one-dark',
keyMap: 'sublime',
viewportMargin: 20,
styleActiveLine: true,
lineNumbers: true,
lineWrapping: true,
showCursorWhenSelecting: true,
highlightSelectionMatches: true,
indentUnit: 4,
// continueComments: 'Enter',
inputStyle: 'textarea',
matchBrackets: true,
autoCloseBrackets: true,
matchTags: {
bothTags: true
},
autoCloseTags: true,
foldGutter: true,
gutters: [
'CodeMirror-linenumbers',
'authorship-gutters',
'CodeMirror-foldgutter'
],
// extraKeys: this.defaultExtraKeys,
flattenSpans: true,
addModeClass: true,
// autoRefresh: true,
// otherCursors: true
placeholder: "← Start by entering a title here\n===\nVisit /features if you don't know what to do.\nHappy hacking :)"
}
}
onBeforeChange={(editor, data, value) => {
setContent(value)
}}
onChange={(editor, data, value) => {
console.log('change!')
}}
/>
) )
} }

View file

@ -0,0 +1,221 @@
/**
* Atom One Dark Theme
*
* Copyright (c) 2015 Hikio - twitter.com/hik_io
*
* 06/26/2015
*
* Licensed under MIT
* GitHub https://github.com/hikio/brackets-one-dark
*/
/*
Modified by jackycute 2015
borrow some color from tomorrow-night-eighties
*/
/* Editor */
.dark .panel,
.dark #main-toolbar {
background: #1d222a;
}
.dark #working-set-list-container,
.dark #editor-holder .pane-header {
background: #15181e;
}
.dark .working-set-header,
.dark #project-files-header .btn-alt-quiet {
background: rgba(204, 217, 255, 0.05);
}
.dark .working-set-header > span {
background: transparent;
}
.dark .sidebar-selection,
.dark .filetree-selection,
.dark .sidebar-selection-extension,
.dark .filetree-selection-extension {
background: #282c34;
}
.dark #status-bar,
.dark #status-indicators {
background: #15181e;
border-top-color: #1d222a;
}
.dark a,
.dark .open-files-container li.selected a {
color: #528bff;
}
/* Code Styling */
.cm-s-one-dark.CodeMirror,
.cm-s-one-dark .CodeMirror-scroll {
/* background-color: #282c34;*/
background-color: #1e2126;
color: #abb2bf;
}
.cm-s-one-dark .CodeMirror-activeline-background {
background: transparent;
}
.cm-s-one-dark.CodeMirror-focused .CodeMirror-activeline-background {
background: rgba(204, 217, 255, 0.05);
}
.show-line-padding .cm-s-one-dark.CodeMirror-focused .CodeMirror-activeline-background {
box-shadow: inset 15px 0 0 0 #000;
}
.cm-s-one-dark.CodeMirror-focused .CodeMirror-activeline .CodeMirror-gutter-elt {
background: transparent;
color: #5c6370;
}
.cm-s-one-dark.CodeMirror-focused .CodeMirror-activeline .inline-widget .CodeMirror-gutter-elt {
color: red;
}
.cm-s-one-dark .cm-string-2,
.cm-s-one-dark .cm-hr {
color: #56b6c2;
}
.cm-s-one-dark .cm-number,
.cm-s-one-dark .cm-attribute,
.cm-s-one-dark .cm-qualifier,
.cm-s-one-dark .cm-plus,
.cm-s-one-dark .cm-atom {
color: #eda35e;
}
.cm-s-one-dark .cm-def {
color: #c678dd;
}
.cm-s-one-dark .cm-property,
.cm-s-one-dark .cm-variable,
.cm-s-one-dark .cm-variable-2,
.cm-s-one-dark .cm-variable-3,
.cm-s-one-dark .cm-operator,
/*.cm-meta,*/
.cm-s-one-dark .cm-bracket {
color: #f76e79;
}
/*borrow from tomorrow-night-eighties*/
.cm-s-one-dark .cm-variable {
color: #99cc99;
}
.cm-s-one-dark .cm-variable-2 {
color: #6699cc;
}
.cm-s-one-dark .cm-comment {
color: #5c6370;
font-style: italic;
}
.cm-s-one-dark .cm-error,
.cm-s-one-dark .cm-minus {
color: #be5046;
}
.cm-s-one-dark .cm-header {
color: #eda35e;
}
.cm-s-one-dark .cm-link {
color: #98c379;
text-decoration: none;
}
.cm-s-one-dark .cm-rangeinfo {
color: #c678dd;
}
.cm-s-one-dark .cm-keyword,
.cm-s-one-dark .cm-builtin,
.cm-s-one-dark .cm-tag {
color: #e06c75;
}
.cm-s-one-dark .cm-m-markdown.cm-keyword,
.cm-s-one-dark .cm-m-markdown.cm-builtin,
.cm-s-one-dark .cm-m-markdown.cm-tag {
color: #98c379;
}
.cm-s-one-dark .cm-string {
/* color: #98c379;*/
color: #6699cc;
}
/* Extra CSS */
.cm-s-one-dark .CodeMirror-searching {
color: #fff !important;
border: 1px solid #528bff;
margin: 0 -1px;
background-color: rgba(204, 217, 255, 0.09);
box-shadow: 0px 0px 6px rgba(66, 133, 244, 0.4);
}
.cm-s-one-dark .CodeMirror-searching.searching-current-match {
color: #fff;
background-color: #528bff;
box-shadow: 0px 0px 6px rgba(66, 133, 244, 0.8);
}
.cm-s-one-dark .CodeMirror-cursor {
border-left: 2px solid #528bff !important;
}
.cm-fat-cursor .CodeMirror-cursor {
border-left: 2px solid #3C5B9E !important;
background: #3C5B9E;
}
.cm-s-one-dark .CodeMirror-gutters {
/* background-color: #282c34;*/
background-color: #1e2126;
border-right: 1px solid rgba(204, 217, 255, 0.05);
}
.cm-s-one-dark .CodeMirror-linenumber {
color: #393e46;
}
.cm-s-one-dark.CodeMirror .CodeMirror-selected {
background: rgba(204, 217, 255, 0.05);
}
.cm-s-one-dark.CodeMirror-focused .CodeMirror-selected {
background: rgba(204, 217, 255, 0.09);
}
.cm-s-one-dark .CodeMirror-matchingbracket,
.cm-s-one-dark .CodeMirror-matchingtag {
/* Ensure visibility against gray inline editor background */
background-color: rgba(204, 217, 255, 0.09);
color: #abb2bf !important;
border-bottom: 1px solid #528bff;
}
.cm-s-one-dark .CodeMirror-overwrite .CodeMirror-cursor {
border-left: none !important;
border-bottom: 1px solid #fff;
width: 0.5em;
}
.cm-s-one-dark.CodeMirror .CodeMirror {
background: transparent;
}
.cm-s-one-dark.CodeMirror .CodeMirror .CodeMirror-gutters {
background: transparent;
border-right: none;
}
.cm-s-one-dark.CodeMirror .CodeMirror .CodeMirror-activeline-background {
background: transparent;
}
.cm-s-one-dark.CodeMirror .CodeMirror .CodeMirror-activeline .CodeMirror-gutter-elt {
background: transparent;
color: #5c6370;
}
.cm-s-one-dark.CodeMirror .CodeMirror-focused .CodeMirror-activeline-background {
background: #000;
}
.cm-s-one-dark.CodeMirror .CodeMirror-focused .CodeMirror-activeline .CodeMirror-gutter-elt {
background: rgba(204, 217, 255, 0.05);
color: #fff;
}
.cm-s-one-dark .CodeMirror-foldgutter-open:after {
color: #393e46;
}
.cm-s-one-dark .CodeMirror-foldgutter-folded:after {
color: #5c6370;
}
.cm-s-one-dark .CodeMirror.over-gutter .CodeMirror-foldgutter-open:after,
.cm-s-one-dark.CodeMirror-focused .CodeMirror-activeline .CodeMirror-foldgutter-open:after {
color: #5c6370;
}
.cm-s-one-dark .CodeMirror-foldmarker {
border-color: #393e46;
color: #abb2bf;
background: rgba(204, 217, 255, 0.05);
}
/* Non-editor styling */
.image-view,
.not-editor {
background-color: #282c34;
}
.view-pane .image-view {
color: #abb2bf;
}

View file

@ -1,6 +1,5 @@
import React from 'react' import React from 'react'
import { useSelector } from 'react-redux' import { useSelector } from 'react-redux'
import { useParams } from 'react-router'
import { ApplicationState } from '../../redux' import { ApplicationState } from '../../redux'
import { ShowIf } from '../common/show-if/show-if' import { ShowIf } from '../common/show-if/show-if'
import { EditorWindow } from './editor-window/editor-window' import { EditorWindow } from './editor-window/editor-window'
@ -14,12 +13,10 @@ interface RouteParameters {
const Editor: React.FC = () => { const Editor: React.FC = () => {
const editorMode: EditorMode = useSelector((state: ApplicationState) => state.editorConfig.editorMode) const editorMode: EditorMode = useSelector((state: ApplicationState) => state.editorConfig.editorMode)
const { id } = useParams<RouteParameters>()
return ( return (
<div className={'d-flex flex-column vh-100'}> <div className={'d-flex flex-column vh-100'}>
<TaskBar/> <TaskBar/>
<h1>{id}</h1>
<div className={'flex-fill flex-row d-flex'}> <div className={'flex-fill flex-row d-flex'}>
<ShowIf condition={editorMode === EditorMode.EDITOR || editorMode === EditorMode.BOTH}> <ShowIf condition={editorMode === EditorMode.EDITOR || editorMode === EditorMode.BOTH}>
<EditorWindow/> <EditorWindow/>

View file

@ -5,7 +5,7 @@ import { Footer } from './layout/footer/footer'
export const LandingLayout: React.FC = ({ children }) => { export const LandingLayout: React.FC = ({ children }) => {
return ( return (
<Container className="text-center text-white"> <Container className="text-white text-center">
<HeaderBar/> <HeaderBar/>
{children} {children}
<Footer/> <Footer/>

View file

@ -3,7 +3,7 @@ import { EditorMode } from '../../components/editor/task-bar/editor-view-mode'
import { EditorConfig, EditorConfigActions, EditorConfigActionType, SetEditorConfigAction } from './types' import { EditorConfig, EditorConfigActions, EditorConfigActionType, SetEditorConfigAction } from './types'
export const initialState: EditorConfig = { export const initialState: EditorConfig = {
editorMode: EditorMode.PREVIEW editorMode: EditorMode.EDITOR
} }
export const EditorConfigReducer: Reducer<EditorConfig, EditorConfigActions> = (state: EditorConfig = initialState, action: EditorConfigActions) => { export const EditorConfigReducer: Reducer<EditorConfig, EditorConfigActions> = (state: EditorConfig = initialState, action: EditorConfigActions) => {

View file

@ -1458,6 +1458,13 @@
dependencies: dependencies:
"@babel/types" "^7.3.0" "@babel/types" "^7.3.0"
"@types/codemirror@^0.0.95":
version "0.0.95"
resolved "https://registry.yarnpkg.com/@types/codemirror/-/codemirror-0.0.95.tgz#8fe424989cd5a6d7848f124774d42ef34d91adb8"
integrity sha512-E7w4HS8/rR7Rxkga6j68n3/Mi4BJ870/OJJKRqytyWiM659KnbviSng/NPfM/FOjg7YL+5ruFF69FqoLChnPBw==
dependencies:
"@types/tern" "*"
"@types/color-name@^1.1.1": "@types/color-name@^1.1.1":
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
@ -1468,6 +1475,11 @@
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
"@types/estree@*":
version "0.0.44"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.44.tgz#980cc5a29a3ef3bea6ff1f7d021047d7ea575e21"
integrity sha512-iaIVzr+w2ZJ5HkidlZ3EJM8VTZb2MJLCjw3V+505yVts0gRC4UMvjw0d1HPtGqI/HQC/KdsYtayfzl+AXY2R8g==
"@types/events@*": "@types/events@*":
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
@ -1668,6 +1680,13 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
"@types/tern@*":
version "0.23.3"
resolved "https://registry.yarnpkg.com/@types/tern/-/tern-0.23.3.tgz#4b54538f04a88c9ff79de1f6f94f575a7f339460"
integrity sha512-imDtS4TAoTcXk0g7u4kkWqedB3E4qpjXzCpD2LU5M5NAXHzCDsypyvXSaG7mM8DKYkCRa7tFp4tS/lp/Wo7Q3w==
dependencies:
"@types/estree" "*"
"@types/testing-library__jest-dom@^5.9.1": "@types/testing-library__jest-dom@^5.9.1":
version "5.9.1" version "5.9.1"
resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.9.1.tgz#aba5ee062b7880f69c212ef769389f30752806e5" resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.9.1.tgz#aba5ee062b7880f69c212ef769389f30752806e5"
@ -3137,6 +3156,11 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codemirror@^5.54.0:
version "5.54.0"
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.54.0.tgz#82b6adf662b29eeb7b867fe7839d49e25e4a0b38"
integrity sha512-Pgf3surv4zvw+KaW3doUU7pGjF0BPU8/sj7eglWJjzni46U/DDW8pu3nZY0QgQKUcICDXRkq8jZmq0y6KhxM3Q==
collection-visit@^1.0.0: collection-visit@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
@ -9261,6 +9285,11 @@ react-bootstrap@1.0.1:
uncontrollable "^7.0.0" uncontrollable "^7.0.0"
warning "^4.0.3" warning "^4.0.3"
react-codemirror2@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/react-codemirror2/-/react-codemirror2-7.2.0.tgz#2f292f31b8ad1c4068220029b5099bf5fe5c7421"
integrity sha512-m2o9qugS83DqDowrRQ1OHoELek80LJZtgAkjQ2ociaj15eLQ5Fa7bPlKIbAtNhqOAxKkVkQ0oG3Y82wbNI2ptw==
react-dev-utils@^10.2.1: react-dev-utils@^10.2.1:
version "10.2.1" version "10.2.1"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19"