make a edit text out of content editable

This commit is contained in:
Peter Cai 2020-02-18 10:13:42 +08:00
parent 3f9dea8467
commit 6ce35c509e
No known key found for this signature in database
GPG key ID: 71F5FB4E4F3FD54F
8 changed files with 134 additions and 7 deletions

View file

@ -1,5 +1,5 @@
import React from "react"
import "./styles/home.scss"
import Pastebin from "./pastebin"
class Home extends React.Component
constructor: (props) ->
@ -8,6 +8,7 @@ class Home extends React.Component
render: ->
<div className="content-wrapper">
<div className="content">
<Pastebin />
</div>
</div>

24
src/web/pastebin.coffee Normal file
View file

@ -0,0 +1,24 @@
import React from "react"
import ContentEditable from "./util/contentEditable"
class Pastebin extends React.Component
constructor: (props) ->
super props
@state =
text: ""
onEditTextUpdate: (ev) =>
console.log ev.target.value
@setState
text: ev.target.value
render: ->
<div className="content-pastebin">
<ContentEditable
className="content-pastebin-edit"
onUpdate={@onEditTextUpdate}
value={@state.text}
plainText/>
</div>
export default Pastebin

View file

@ -0,0 +1,15 @@
.editable {
display: block;
white-space: pre-wrap;
overflow-wrap: break-word;
word-wrap: break-word;
padding: 10px;
outline: none;
border: 1px solid $editable-color;
border-radius: $editable-radius;
transition: border-color 0.4s linear;
}
.editable:focus {
border-color: $editable-color-active;
}

View file

@ -1,8 +1,3 @@
$content-padding: 100px;
$content-width: 1000px;
$content-height: 600px;
$content-total-height: $content-height + 2 * $content-padding;
.content-wrapper {
width: 100vw;
padding-top: $content-padding;
@ -18,7 +13,8 @@ $content-total-height: $content-height + 2 * $content-padding;
width: $content-width;
height: $content-height;
box-shadow: 0 2px 5px 5px rgba(0, 0, 0, 0.15);
border-radius: 20px;
border-radius: $content-radius;
padding: $content-radius;
}
/*

View file

@ -1,3 +1,10 @@
// -- Prelude --
@import './vars.scss';
// -- Styles --
@import './contentEditable.scss';
@import './home.scss';
@import './pastebin.scss';
body, html {
margin: 0px;
padding: 0px;

View file

@ -0,0 +1,14 @@
.content-pastebin {
display: block;
height: 100%;
width: 100%;
}
.content-pastebin-edit {
display: block;
height: 100%;
width: 100%;
overflow-y: auto;
text-align: left;
box-sizing: border-box;
}

10
src/web/styles/vars.scss Normal file
View file

@ -0,0 +1,10 @@
// Configurations for contentEditable
$editable-color: rgba(0, 0, 0, 0.1);
$editable-color-active: rgba(0, 0, 0, 0.2);
$editable-radius: 5px;
// Dimensions of main content card
$content-padding: 100px;
$content-width: 1000px;
$content-height: 600px;
$content-total-height: $content-height + 2 * $content-padding;
$content-radius: 20px;

View file

@ -0,0 +1,60 @@
import React from "react"
import ReactDOM from "react-dom"
# Wrapper for a content-editable div
# <https://stackoverflow.com/questions/22677931/react-js-onchange-event-for-contenteditable>
class ContentEditable extends React.Component
constructor: (props) ->
super props
getText: ->
if @props.plainText then @domNode.innerText else @domNode.innerHTML
setText: (text) ->
if @props.plainText
@domNode.innerText = text
else
@domNode.innerHTML = text
componentDidMount: ->
@domNode = ReactDOM.findDOMNode @
componentWillUnmount: ->
@domNode = null
shouldComponentUpdate: (nextProps) ->
nextProps.value != @getText()
componentDidUpdate: ->
if @props.value != @getText()
@setText @props.value
emitUpdate: =>
if @props.onUpdate
# Note that the parent is expected to send the content back to us
# via `@props.value`
@props.onUpdate
target:
value: @getText()
onPaste: (ev) =>
return false if not @props.plainText
# <https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event>
paste = (event.clipboardData || window.clipboardData).getData 'text'
selection = window.getSelection()
return false if not selection.rangeCount
selection.deleteFromDocument()
selection.getRangeAt 0
.insertNode document.createTextNode paste
ev.preventDefault()
render: ->
<div
className={"#{@props.className} editable"}
onInput={@emitUpdate}
onBlur={@emitUpdate}
onPaste={@onPaste}
spellCheck={false}
contentEditable/>
export default ContentEditable