- 📦 Small bundle-size
- Only 3.84 kB (Minified + Gzipped).
- 🌈 Code highlighting
- Atom-light and Atom-dark themes.
- 140 supported languages that can be configured via lowlight.
- 💁♂️ Handling special characters (
`
,'
,"
,[
,{
, and(
)- Adding the closing counterpart automatically.
- Wrapping selected text with them.
- ⏳ History
- 🎨 Appearance customizations
- Light and dark themes.
- Line numbers.
- 📃 Auto-scrolling
- Scrolls automatically to the position of the caret if it's out of the viewport.
npm install react-throwcode highlight.js lowlight hast-util-to-html
The component imported from the package is a controlled component, and you can use it without configurations.
import { useState } from 'react';
import CodeEditor from 'react-throwcode';
import { lowlight } from 'lowlight/lib/core';
import javascript from 'highlight.js/lib/languages/typescript';
lowlight.registerLanguage(javascript, 'javascript');
function App() {
const [code, setCode] = useState('');
return (
<div className="app">
<CodeEditor
language="javascript"
value={code}
onChange={text => setCode(text)}
/>
</div>
);
}
export default App;
The data type of the options
interface CodeEditorProps {
language: string;
value: string;
onChange: (content: string) => void;
theme?: 'light' | 'dark';
height?: number | 'auto' | string;
spellCheck?: boolean;
handleHistory?: boolean;
handleSpecialCharacters?: boolean;
highlight?: boolean;
lineNumbers?: boolean;
className?: string;
}
The default props
const defaultProps = {
theme: 'light',
height: 'auto',
spellCheck: false,
handleHistory: true,
handleSpecialCharacters: true,
highlight: true,
lineNumbers: true,
};
value
- Represents the code that is displayed.
- If you want to update the code you just have to rewrite with
setValue
.
onChange
- Takes a callback that receives
content
arg which is a string. - Is called whenever the content of the editor is changed whether it's changed by undoing/redoing or by the user typing.
- Takes a callback that receives
theme
- highlight.js is used as a peer dependency for highlighting.
- I just included two themes in the library becuase I wanted it to be easier to use and the reason mentioned in caveats section.
language
- I decided to use lowlight, which is built on highlight.js.
- The reason for that is giving you the ability to use lowlight in other parts of your application.
- If you want to use any language follow these steps.
// Note: You should import it from /lib/core
import { lowlight } from 'lowlight/lib/core';
// Import the language that you want from /lib/languages/$language-name
import typescript from 'highlight.js/lib/languages/typescript';
// Register the language
lowlight.registerLanguage('typescript', typescript);
// Add the language with the name that you registered it with
<CodeEditor
language="typescript"
value={code}
onChange={text => setCode(text)}
/>;
height
- You can either make it implicit by passing
auto
or explicit by passing a number or a string (a number with a unit).
- You can either make it implicit by passing
spellCheck
- Enables spell check.
handleHistory
- Enables undoing and redoing.
handleSpecialCharacters
- Closes quotes (```,
'
,`"`) and brackets (`[`,`{`,`(`) automatically. - Wraps selected text with them.
- Closes quotes (```,
highlight
- Enables code highlighting.
lineNumbers
- Enables line numbers.
className
- Applies styles to the wrapper of the editor.
lowlight is a peer depedency for this library, so you should be able to use it in your app.
Unfortunatelly, when lowlight is installed in a project you can't use hljs.highlightAll
function to highlight the other code blocks in your app.
I faced this problem while creating the home page of the library, so I had to come up with a solution.
// Register the language
import { lowlight } from 'lowlight/lib/core';
import typescript from 'highlight.js/lib/languages/typescript';
lowlight.registerLanguage('typescript', typescript);
// Import a theme from highlight.js themes
import 'highlight.js/styles/atom-one-light.css';
// Highlight all code blocks
document.querySelectorAll('pre > code').forEach(codeblock => {
const language = codeblock.className.split('-')[1];
const content = codeblock.innerText;
// toHtml is imported from hast-util-to-html which is also a peer depedency
codeblock.innerHTML = toHtml(lowlight.highlight(language, content));
codeblock.classList.add('hljs');
});
Due to the way this lib is implemented (a layer for highlighting and a layer for editing above it), You can only change the colors of the keywords, so I had to take to themes and modify them so that they don't change the style of the font.
If you want to contribute run these commands
# Clone the repo
git clone https://github.com/yosefbeder/react-throwcode.git
# Compile the library whenever any file is changed
npm run start
cd ./example
# Start the development server of the demo version
npm run dev
MIT License 2021 Yosef Beder