Draft.js가 간단한 테이블을 지원하도록 해보세요.
13944 단어 react
소개
내 요구 사항은 온라인 종이 조판 편집기를 구현하고 LaTeX에서 생성된 PDF를 내보내는 것입니다.
-- 업데이트됨 --
https://github.com/facebook/draft-js/pull/2590
-- 원본 --
프로젝트 링크: Eorg
관련 프로젝트는 Overleaf 및 Resumake입니다.
저는 React.js를 선호하기 때문에 역시 Facebook용으로 개발된 서식 있는 텍스트 편집기인 Draft.js를 선택했습니다. 종이 쓰기는 테이블 삽입에서 숨길 수 없지만 Draft.js에는 기성 테이블 플러그인이 없습니다. 테이블 생성을 위한 몇 가지 도구도 있습니다. 별도의 테이블 지원을 직접 작성할 필요는 전혀 없지만 사용자에게는 편리하고 테이블이 너무 복잡할 필요는 없습니다.
booktabs
와 같은 테이블을 내보낼 수 있으니 직접 테이블 지원을 구현해보려고 합니다.콘텐츠
아이디어:
A robust table은
new ContentBlock
를 사용하여 block
에 메타데이터를 쓰는 것입니다. 이는 Draft.js에 가까운 접근 방식입니다!상대적으로 말하자면, 제 구현은 offical TeX example에서 차용한 더 트릭입니다. ,
AtomicBlockUtils.insertAtomicBlock(newEditorState, entityKey, ' ')
API를 사용하여 React.js 소품에 메타데이터를 추가합니다.const contentStateWithEntity = contentState.createEntity(
'TABLE',
'IMMUTABLE',
{
row, column, caption, // data
},
)
// ...
const { row, column, caption } = props // Table Component
// createTable.js
/**
* cell = {
* 0: ["cell-0,0", "cell-0,1", ..., "cell-0,m"],
* 1: ["cell-1,0", "cell-1,1", ..., "cell-1,m"],
* ...,
* n: ["cell-n,0", "cell-n,1", ..., "cell-n,m"],
* }
*/
const cell = Object.fromEntries(Array.from(
{ length: row },
(_, i) => [
i,
Array.from({ length: column }, (_, j) => `cell-${i},${j}`)
])
)
const contentStateWithEntity = contentState.createEntity(
'TABLE',
'IMMUTABLE',
{
..., cell, // data
},
)
// ...
const { ..., cell } = props // Table Component
그리고 테이블 초기화:
// TableBlock.js
// tbody -- version 1
const coordinate = []
if (row > 1) {
for (let i = 1; i < row; i += 1) {
const cols = []
for (let j = 0; j < column; j += 1) {
cols.push(
<td key={i + j} >
{cell[i][j]}
</td>,
)
}
rows.push(<tr key={i}>{cols}</tr>)
}
}
store
row
,column
,caption
,cell
to React.jsprops
첫 번째 아이디어는 Dom 노드 위치를 계산하는 것입니다. 즉,
<tr>
에서 closest('td')
의 인덱스closest('table')
를 찾습니다.나중에 더 나은 접근 방식은
key
및 <tr>
에서 <td>
값을 검색하는 것이며 좌표는 (x1, y1)입니다.// TableBlock.js
// tbody -- version 2
const coordinate = []
if (row > 1) { // thead need to calculate separately
for (let i = 1; i < row; i += 1) {
const cols = []
for (let j = 0; j < column; j += 1) {
cols.push(
<td
key={i + j} // TODO key-1
onDoubleClick={() => coordinate.push([i, j])}
>
{cell[i][j]}
</td>,
)
}
rows.push(<tr key={i}>{cols}</tr>)
}
}
위의 키-1은 안정적이지 않습니다. nanoid 라이브러리로 작업할 수 있습니다.
key = {`i+j+${nanoid()}`}
이제 안정적이며 셀 값을 저장할 수 있습니다.
// find the coordinate of the node clicked
const x1 = coordinate[coordinate.length - 1][0]
const y1 = coordinate[coordinate.length - 1][1]
// update cell[i][j]
cell[x1][y1] = evt.target.innerHTML
cell-2,1 can be stored to props
요약
테이블은 아직 완료되지 않았습니다. 예를 들면 다음과 같습니다.
다음
셀 추가 및 삭제를 지원합니다.
Reference
이 문제에 관하여(Draft.js가 간단한 테이블을 지원하도록 해보세요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/zhyd007/try-to-make-draft-js-support-simple-table-2cc0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)