1. 실행 결과
2. 원리
먼저 highlight.js는 텍스트에 style을 입혀주는 기능을 할 뿐이다.
즉 엘리먼트들을 사용한다는 것인데, textarea나 MUI의 TextField에서는 적용이 불가능하다.
예로 들어 C언어에서 "int num = 5;"라는 code는 "<span class="hljs-type">int</span> num = <span class="hljs-number">5</span>"라는 html코드로 되어있다.
int는 type이니까 hljs-type의 class이름으로 css를 입힌다... 이런 식인데
textarea와 같은 컴포넌트들은 HTML 코드가 아니니 innerHTML도 불가능하고, css도 입히지 못하는 것이다.
그러면 어떻게 TextEditor를 만드냐면
textarea와 pre&code를 겹치는 것이다. (여기서 pre&code는 hightlight.js 적용방법이다)
둘을 겹치되, textarea는 z-index를 높여 앞으로 나오게 하고, text color와 background color를 tansparent로 설정한다.
혹여나 teatarea 전체를 opacity: 0으로 설정하면 안 되냐? 할 수 있지만 그러면 cursor까지 안 보인다.
그러니 textarea와 pre&code를 font설정도 같이, padding, margin 등도 똑같이 설정해줘야 한다.
이렇게 되면 입력창은 살아있되 보여지는 텍스트는 highlight.js의 style을 먹은 pre&code가 보여지는 것이다.
3. 코드
먼저 code를 입력하는 form부터.
참고로 React용 highlight.js가 있었으나, 무슨 이유인지 설치가 안되어서 native js로...
javascript
(handleKeyDown은 Tab을 눌렀을 때 \t를 주려고 만들었으나, 아직 구현하진 않음)
<div className="code-editor-wrapper">
<textarea
value={code}
onChange={(e)=>{setCode(e.target.value)}}
// onKeyDown={handleKeyDown}
className="code-input"
spellCheck={false}
/>
<pre className="code-output">
<code ref={codeRef} className={`language-${language}`} />
</pre>
</div>
css
.code-editor-wrapper {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
position: relative;
width: 100%;
height: 100%;
font-family: 'Courier New', monospace;
}
.code-input,
.code-output {
grid-column: 1 / 2;
grid-row: 1 / 2;
width: calc(100% - 20px);
height: 100%;
padding: 10px;
margin: 0;
font-family: inherit;
font-size: 16px;
line-height: 1.5;
letter-spacing: 0px;
tab-size: 4;
}
.code-input {
color: transparent;
background-color: transparent;
border: none;
resize: none;
caret-color: black;
white-space: pre-wrap;
overflow: hidden;
z-index: 1;
}
.code-output {
background-color: #f5f5f5;
border: 1px solid #000000;
pointer-events: none;
white-space: pre-wrap;
word-wrap: break-word;
z-index: 0;
overflow: auto;
}
이러면 입력창은 완료하였고, 다음은 highlight.js를 입히는 코드
javascript
// 라이브러리 import
import hljs from 'highlight.js';
import 'highlight.js/styles/docco.min.css';
import cLang from 'highlight.js/lib/languages/c';
// c언어 등록
hljs.registerLanguage('language-c', cLang);
// textarea가 변경될 때 마다 highligh.js 를 적용하여 pre&code에 innerHTML로 입력
React.useEffect(() => {
if ( codeRef.current ) {
codeRef.current.innerHTML = hljs.highlight(`language-c`, code).value;
}
}, [code]);
새로운 언어에 대한 code style을 바꾸고 싶다면 아래 링크로...
2024.08.24 - [프로그래밍/Javascript] - [ReactJS] highlight.js 커스텀 language 추가
'프로그래밍 > Javascript' 카테고리의 다른 글
[React] MUI: Warning Failed props type error (0) | 2024.10.07 |
---|---|
[ReactJS] highlight.js 커스텀 language 추가 (0) | 2024.08.24 |
[Javascript] 2. Toast UI Grid 셀 합치기(+ header 합치기) (0) | 2024.03.19 |
[javascript] 1. Toast UI Grid 기초(+API 사용법) (0) | 2024.03.14 |
[JS] Drag&Drop 구현 예제(feat. SortableJS) (0) | 2024.02.02 |
댓글