Skip to content

Instantly share code, notes, and snippets.

@schabluk
Last active March 31, 2023 15:45
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save schabluk/0e5e938bc30a7833201b605cee4efb4a to your computer and use it in GitHub Desktop.
Save schabluk/0e5e938bc30a7833201b605cee4efb4a to your computer and use it in GitHub Desktop.
Display line numbers is Draft-JS Editor
// Required Draf-js version: 0.10.
// Live example: https://jsfiddle.net/schabluk/gh2gt22n/
import React from 'react'
import ReactDOM from 'react-dom'
import {Editor, EditorState, EditorBlock} from 'draft-js'
class Line extends React.Component {
render () {
const blockMap = this.props.contentState.getBlockMap().toArray()
const blockKey = this.props.block.key
const lineNumber = blockMap.findIndex(block => blockKey === block.key) + 1
return <div style={{display: 'flex'}}>
<span style={{marginRight: '5px'}}>{lineNumber}</span>
<div style={{flex: '1'}}><EditorBlock {...this.props} /></div>
</div>
}
}
const blockRendererFn = function(contentBlock) {
const type = contentBlock.getType()
switch (type) {
default:
return {component: Line, editable: true}
}
}
class App extends React.Component {
constructor (props) {
super(props)
const editorState = EditorState.createEmpty()
this.state = {editorState}
this.onChange = this.onChange.bind(this)
}
onChange (editorState) {
this.setState({editorState})
}
render () {
return <div style={{backgroundColor: '#fff'}}>
<Editor
editorState={this.state.editorState}
onChange={this.onChange}
blockRendererFn={blockRendererFn}
/>
</div>
}
}
ReactDOM.render(
<App />,
document.getElementById('react-root')
)
@bummzack
Copy link

Found this via google. Thanks!
Have you found a solution to disable caret movement to the line-number? When I use up- and down-arrows on the keyboard, the text-cursor moves to the line-number.

@lixiaoyan
Copy link

@bummzack
https://gist.github.com/lixiaoyan/79b5740f213b8526d967682f6cd329c0
I made an example with ::before and it works fine in modern browsers. (I tested it in Chrome, Firefox, Edge and Safari)

@alvelig
Copy link

alvelig commented Apr 22, 2020

@bummzack

      <span style={{marginRight: '5px'}} contentEditable="false">{lineNumber}</span>

@ianmcgregor
Copy link

Thanks, this pointed me in the right direction. In case it helps anyone I ended up finding a CSS-only way that worked for my use case:

div[data-contents] {
    list-style-type: none;
    counter-reset: css-counter 0;
}

div[data-block="true"] {
    position: relative;
    counter-increment: css-counter 1;
}

div[data-block="true"]:before {
    content: counter(css-counter) " ";
    color: #889096;
    font-family: monospace;
    font-size: 1rem;
    position: absolute;
    margin-left: -1.5rem;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment