Skip to content
This repository has been archived by the owner on Sep 7, 2022. It is now read-only.

Commit

Permalink
Created basic react wysiwyg
Browse files Browse the repository at this point in the history
  • Loading branch information
dominic-chang committed Jun 8, 2018
1 parent c6d5a2e commit ff15ace
Show file tree
Hide file tree
Showing 10 changed files with 924 additions and 147 deletions.
299 changes: 228 additions & 71 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,21 @@
"@fortawesome/react-fontawesome": "0.0.19",
"ajv": "^6.5.0",
"aws-sdk": "^2.224.1",
"babel-polyfill": "^6.26.0",
"body-parser": "^1.18.2",
"bootstrap": "^4.0.0",
"buttercms": "^1.1.1",
"draft-js": "^0.10.5",
"html-to-react": "^1.3.3",
"immutable": "^3.8.2",
"jquery": "^3.3.1",
"katex": "^0.5.1",
"mathjax": "^2.7.4",
"mathjax-node": "^2.0.1",
"mathjax-node": "^2.1.1",
"popper": "^1.0.1",
"popper.js": "^1.12.9",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-froala-wysiwyg": "^2.8.1",
"react-helmet": "^5.2.0",
"react-load-script": "0.0.6",
"react-mathjax2": "0.0.1",
Expand Down
28 changes: 0 additions & 28 deletions src/css/App.css

This file was deleted.

63 changes: 63 additions & 0 deletions src/css/Draft.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
.RichEditor-root {
background: #fff;
border: 1px solid #ddd;
font-family: 'Georgia', serif;
font-size: 14px;
padding: 15px;
}

.RichEditor-editor {
border-top: 1px solid #ddd;
cursor: text;
font-size: 16px;
margin-top: 10px;
}

.RichEditor-editor .public-DraftEditorPlaceholder-root,
.RichEditor-editor .public-DraftEditor-content {
margin: 0 -15px -15px;
padding: 15px;
}

.RichEditor-editor .public-DraftEditor-content {
min-height: 100px;
}

.RichEditor-hidePlaceholder .public-DraftEditorPlaceholder-root {
display: none;
}

.RichEditor-editor .RichEditor-blockquote {
border-left: 5px solid #eee;
color: #666;
font-family: 'Hoefler Text', 'Georgia', serif;
font-style: italic;
margin: 16px 0;
padding: 10px 20px;
}

.RichEditor-editor .public-DraftStyleDefault-pre {
background-color: rgba(0, 0, 0, 0.05);
font-family: 'Inconsolata', 'Menlo', 'Consolas', monospace;
font-size: 16px;
padding: 20px;
}

.RichEditor-controls {
font-family: 'Helvetica', sans-serif;
font-size: 14px;
margin-bottom: 5px;
user-select: none;
}

.RichEditor-styleButton {
color: #999;
cursor: pointer;
margin-right: 16px;
padding: 2px 0;
display: inline-block;
}

.RichEditor-activeButton {
color: #5890ff;
}
225 changes: 179 additions & 46 deletions src/scenes/Login/components/Login.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,184 @@
import React, { Component } from 'react';
// Require Editor JS files.
import 'froala-editor/js/froala_editor.pkgd.min.js';

// Require Editor CSS files.
import 'froala-editor/css/froala_style.min.css';
import 'froala-editor/css/froala_editor.pkgd.min.css';

// Require Font Awesome.
import 'font-awesome/css/font-awesome.css';

import FroalaEditor from 'react-froala-wysiwyg';
const $ = require('jquery');

export default class Login extends Component{
constructor(props){
super(props);
this.state={username:'admin', password:'admin'};
this.handleChangeUsername = this.handleChangeUsername.bind(this);
this.handleChangePassword = this.handleChangePassword.bind(this);
}
handleChangeUsername(event) {
this.setState({username: event.target.value})
}
handleChangePassword(event) {
this.setState({password: event.target.value})
/**
* Copyright (c) 2013-present, Facebook, Inc. All rights reserved.
*
* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

'use strict';

import Draft from 'draft-js';
import {Map} from 'immutable';
import React from 'react';

import TeXBlock from './TeXBlock';
import {content} from '../data/content';
import {insertTeXBlock} from '../modifiers/insertTeXBlock';
import {removeTeXBlock} from '../modifiers/removeTeXBlock';
import '../css/TeXEditor.css';
var {Editor, EditorState, RichUtils} = Draft;

class StyleButton extends React.Component {
constructor() {
super();

this.onToggle = (e) => {
e.preventDefault();
this.props.onToggle(this.props.style);
};
}

render() {
let className = "styleButton";

if (this.props.active) {
className += " active";
}

return (
<button className={className} onMouseDown={this.onToggle} >{this.props.label}</button>
);
}
}

const BLOCK_TYPES = [
{ label: "H1", style: "header-one" },
{ label: "H2", style: "header-two" },
{ label: '"', style: "blockquote" },
{ label: "UL", style: "unordered-list-item" },
{ label: "OL", style: "ordered-list-item" },
{ label: "</>", style: "code-block" }
];

const BlockStyleControls = (props) => {
const {editorState} = props;
const selection = editorState.getSelection();
const blockType = editorState.getCurrentContent()
.getBlockForKey(selection.getStartKey())
.getType();

return (
<div className="block controls">
{
BLOCK_TYPES.map((type) => (
<StyleButton
key={type.label}
active={type.style === blockType}
label={type.label}
onToggle={props.onToggle}
style={type.style}
/>
))
}
</div>
);
};

render() {
return(
<div>
<h1 style={{paddingTop:'2em'}}>
Login
</h1>
<form>
<div className="form-group">
<label htmlFor="username"> Username:</label>
<input type="text" className="form-control" id="username" placeholder="enter username" value={this.state.value} onChange={this.handleChangeUsername}/>
</div>
<div className="form-group">
<label htmlFor="password"> Password:</label>
<input type="text" className="form-control" id="password" placeholder="enter pasword" value={this.state.value} onChange={this.handleChangePassword}/>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<FroalaEditor tag='textarea'/>
</div>
);

export default class TeXEditorExample extends React.Component {
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createWithContent(content),
liveTeXEdits: Map(),
};

this._blockRenderer = (block) => {
if (block.getType() === 'atomic') {
return {
component: TeXBlock,
editable: false,
props: {
onStartEdit: (blockKey) => {
var {liveTeXEdits} = this.state;
this.setState({liveTeXEdits: liveTeXEdits.set(blockKey, true)});
},
onFinishEdit: (blockKey, newContentState) => {
var {liveTeXEdits} = this.state;
this.setState({
liveTeXEdits: liveTeXEdits.remove(blockKey),
editorState:EditorState.createWithContent(newContentState),
});
},
onRemove: (blockKey) => this._removeTeX(blockKey),
},
};
}
return null;
};

this._focus = () => this.refs.editor.focus();
this._onChange = (editorState) => this.setState({editorState});

this._handleKeyCommand = (command, editorState) => {
var newState = RichUtils.handleKeyCommand(editorState, command);
if (newState) {
this._onChange(newState);
return true;
}
return false;
};

this._removeTeX = (blockKey) => {
var {editorState, liveTeXEdits} = this.state;
this.setState({
liveTeXEdits: liveTeXEdits.remove(blockKey),
editorState: removeTeXBlock(editorState, blockKey),
});
};

this._insertTeX = () => {
this.setState({
liveTeXEdits: Map(),
editorState: insertTeXBlock(this.state.editorState),
});
};


this._toggleBlockType = (type) => {
const {editorState} = this.state;

this._onChange(RichUtils.toggleBlockType(editorState, type));
}
}

/**
* While editing TeX, set the Draft editor to read-only. This allows us to
* have a textarea within the DOM.
*/
render() {
return (
<div className="TexEditor-container">
<div className="TeXEditor-root">
<div className="TeXEditor-editor" onClick={this._focus}>
<BlockStyleControls
className="block"
editorState={this.state.editorState}
onToggle={this._toggleBlockType}
/>
<Editor
blockRendererFn={this._blockRenderer}
editorState={this.state.editorState}
handleKeyCommand={this._handleKeyCommand}
onChange={this._onChange}
placeholder="Start a document..."
readOnly={this.state.liveTeXEdits.count()}
ref="editor"
spellCheck={true}
/>
</div>
</div>
<button onClick={this._insertTeX} className="TeXEditor-insert">
{'Insert new TeX'}
</button>
</div>
);
}
}
Loading

0 comments on commit ff15ace

Please sign in to comment.