react-styledtexteditable

1.0.34 • Public • Published

react-styledtexteditable

React component for styled text contenteditable element. The output is json. Currently bold, italic, code, and normal styles are supported

Install

npm install react-styledtexteditable

Usage

import React, { useState } from 'react'
import ReactDOM from 'react-dom'
import StyledTextEditable, {n, b, i, c, l, INLINE_NORMAL, INLINE_BOLD, INLINE_ITALIC, INLINE_CODE, INLINE_LINK} from 'react-styledtexteditable'
 
function Note() {
    const [content, setContent] = useState([n('Hello, '), i(''), b('World!'), i(' Welcome to '), c('react-styledtexteditable'), n(' '), l('google', 'https://www.google.com')])
    const [selection, setSelection] = useState(null)
    const [useInlineStyle, setUseInlineStyle] = useState(null)
    const [select, setSelect] = useState(null)
    const [active, setActive] = useState(false)
    const ref = React.createRef()
 
    const onClick = (e) => {
        if (e.target === ref.current) {
            setSelect({anchor: 1000000, focus: 1000000}) // end of the text
        }
    }
 
    const normalClick = () => {
        if (useInlineStyle && useInlineStyle.style === INLINE_NORMAL) {
            setUseInlineStyle(null)
        } else {
            setUseInlineStyle({style: INLINE_NORMAL})
        }
    }
 
    const boldClick = () => {
        if (useInlineStyle && useInlineStyle.style === INLINE_BOLD) {
            setUseInlineStyle(null)
        } else {
            setUseInlineStyle({style: INLINE_BOLD})
        }
    }
 
    const italicClick = () => {
        if (useInlineStyle && useInlineStyle.style === INLINE_ITALIC) {
            setUseInlineStyle(null)
        } else {
            setUseInlineStyle({style: INLINE_ITALIC})
        }
    }
 
    const codeClick = () => {
        if (useInlineStyle && useInlineStyle.style === INLINE_CODE) {
            setUseInlineStyle(null)
        } else {
            setUseInlineStyle({style: INLINE_CODE})
        }
    }
 
    const linkClick = () => {
        if (useInlineStyle && useInlineStyle.style === INLINE_LINK) {
            setUseInlineStyle(null)
        } else {
            setUseInlineStyle({style: INLINE_LINK})
        }
    }
 
    const onChange = (val) => {
        setContent(val)
        console.log(JSON.stringify(val))
    }
 
    const onNavigate = (type, position, e) => {
        // type: MovePrev, MoveNext, MoveUp, MoveDown, MergePrev, Enter
 
        console.log(type, position)
    }
 
    const onSelection = (val) => {
        setSelection(val)
    }
 
    const editable = <StyledTextEditable 
        style={ {caretColor: '#323500'} } 
 
        content={ content } 
        selection={ selection } 
        useInlineStyle={ useInlineStyle }
        select={ select }
 
        onUseInlineStyleDone={ () => { setUseInlineStyle(null) } }
        onChange={ onChange } 
        onNavigate={ onNavigate }
        onSelection={ onSelection } 
        onSelectDone={ () => { setSelect (null) } }
        onActive={ (val) => { setActive(val) } }
        />
    const normalBtn = <div onClick={ normalClick } className={ (useInlineStyle && useInlineStyle.style == INLINE_NORMAL) ? 'btn btn-select' : 'btn'}>Normal</div>
    const boldBtn = <div onClick={ boldClick } className={ (useInlineStyle && useInlineStyle.style == INLINE_BOLD) ? 'btn btn-select' : 'btn' }><b>Bold</b></div>
    const italicBtn = <div onClick={ italicClick } className={ (useInlineStyle && useInlineStyle.style == INLINE_ITALIC) ? 'btn btn-select' : 'btn' }><i>Italic</i></div>
    const codeBtn = <div onClick={ codeClick } className={ (useInlineStyle && useInlineStyle.style == INLINE_CODE) ? 'btn btn-select' : 'btn' }><code style={ {backgroundColor: 'inherit', padding: '0'} }>Code</code></div>
    const linkBtn = <div onClick={ linkClick } className={ (useInlineStyle && useInlineStyle.style == INLINE_LINK) ? 'btn btn-select' : 'btn' }><a href='#'>Link</a></div>
 
    return <>
    <div className='line' ref={ ref } onClick={ onClick }>
        { editable }
        { active && 
        <div className='toolbar'>
            { normalBtn } { boldBtn } { italicBtn } { codeBtn } { linkBtn }
        </div>
        }
    </div>
    </>
}
 
ReactDOM.render(<Note />, document.getElementById('note'))

onChange will be called as you type. The output of the initial content above would be as follows:

[
    {"type":"normal","text":"Hello, "},
    {"type":"bold","text":"World!"},
    {"type":"italic","text":" Welcome to "},
    {"type":"code","text":"react-styledtexteditable"}
]

Dependencies (1)

Dev Dependencies (4)

Package Sidebar

Install

npm i react-styledtexteditable

Weekly Downloads

8

Version

1.0.34

License

ISC

Unpacked Size

110 kB

Total Files

15

Last publish

Collaborators

  • andybau