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

@ -9,7 +9,7 @@ export interface LoadingScreenProps {
export const LoadingScreen: React.FC<LoadingScreenProps> = ({ failedTitle }) => {
return (
<div className="loader middle">
<div className="loader middle text-white">
<div className="icon text-white">
<ForkAwesomeIcon icon="file-text" size="5x"
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 [content, setContent] = useState<string>('')
return (
<div style={{ backgroundColor: 'green' }}>
Hello, EditorWindow!
</div>
<ControlledCodeMirror
className="h-100 w-100"
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 { useSelector } from 'react-redux'
import { useParams } from 'react-router'
import { ApplicationState } from '../../redux'
import { ShowIf } from '../common/show-if/show-if'
import { EditorWindow } from './editor-window/editor-window'
@ -14,12 +13,10 @@ interface RouteParameters {
const Editor: React.FC = () => {
const editorMode: EditorMode = useSelector((state: ApplicationState) => state.editorConfig.editorMode)
const { id } = useParams<RouteParameters>()
return (
<div className={'d-flex flex-column vh-100'}>
<TaskBar/>
<h1>{id}</h1>
<div className={'flex-fill flex-row d-flex'}>
<ShowIf condition={editorMode === EditorMode.EDITOR || editorMode === EditorMode.BOTH}>
<EditorWindow/>

View file

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