반응형
참고
- https://github.com/aeolun/react-diff-viewer-continued
아래 결과는 링크에서 확인할 수 있다.
위의 뷰어를 만들기 위해 react-diff-viewer-continued를 설치하자.
npm install react-diff-viewer-continued
예제 코드는 다음과 같다.
import React from "react";
import Box from "@mui/material/Box";
import ReactDiffViewer, { DiffMethod } from "react-diff-viewer-continued";
const oldCode = `
const a = 10
const b = 10
const c = () => console.log('foo')
if(a > 10) {
console.log('bar')
}
console.log('done')
`;
const newCode = `
const a = 10
const boo = 10
if(a === 10) {
console.log('bar')
}
`;
const MyDiffViewer = () => {
return (
<Box sx={{ m: 2 }}>
<ReactDiffViewer
oldValue={oldCode}
newValue={newCode}
compareMethod={DiffMethod.WORDS}
splitView={true}
/>
</Box>
);
};
export default MyDiffViewer;
splitView 옵션
splitView 옵션이 true인 경우 양 옆으로 text를 비교할 수 있고, false인 경우는 줄 단위로 텍스트를 비교한다.
토글 버튼을 추가해서 코드를 수정해 보자.
const MyDiffViewer = () => {
const [splitView, setSplitView] = useState(true);
return (
<Box sx={{ m: 2 }}>
<ToggleButton
...
>
<CheckIcon size="small"/> split
</ToggleButton>
<ReactDiffViewer
...
splitView={splitView}
/>
</Box>
);
};
버튼을 누르면 split 모드가 변경된다.
전체 코드는 다음과 같다.
import React, { useState } from "react";
import Box from "@mui/material/Box";
import CheckIcon from "@mui/icons-material/Check";
import ToggleButton from "@mui/material/ToggleButton";
import ReactDiffViewer, { DiffMethod } from "react-diff-viewer-continued";
const oldCode = `
const a = 10
const b = 10
const c = () => console.log('foo')
if(a > 10) {
console.log('bar')
}
console.log('done')
`;
const newCode = `
const a = 10
const boo = 10
if(a === 10) {
console.log('bar')
}
`;
const MyDiffViewer = () => {
const [splitView, setSplitView] = useState(true);
return (
<Box sx={{ m: 2 }}>
<ToggleButton
sx={{marginBottom : 2}}
value="check"
selected={splitView}
onChange={() => {
setSplitView(!splitView);
}}
>
<CheckIcon size="small"/> split
</ToggleButton>
<ReactDiffViewer
oldValue={oldCode}
newValue={newCode}
compareMethod={DiffMethod.WORDS}
splitView={splitView}
/>
</Box>
);
};
export default MyDiffViewer;
Diff Method
react-diff-viewer-continued에는 다양한 비교 방법을 제공한다.
compareMethod={DiffMethod.WORDS}
총 7개의 방법을 제공하고 있다.
export declare enum DiffMethod {
CHARS = "diffChars",
WORDS = "diffWords",
WORDS_WITH_SPACE = "diffWordsWithSpace",
LINES = "diffLines",
TRIMMED_LINES = "diffTrimmedLines",
SENTENCES = "diffSentences",
CSS = "diffCss"
}
DropDown 박스를 추가하여 diff 방법을 변경해 보자.
<FormControl sx={{m : 2, width : "500px"}}>
<InputLabel id="demo-simple-select-label">Age</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={diffMethod}
label="Diff Method"
onChange={(e) => setDiffMethod(e.target.value)}
>
<MenuItem value="diffChars">CHARS</MenuItem>
<MenuItem value="diffWords">WORDS</MenuItem>
<MenuItem value="diffWordsWithSpace">WORDS_WITH_SPACE</MenuItem>
<MenuItem value="diffLines">LINES </MenuItem>
<MenuItem value="diffTrimmedLines">TRIMMED_LINES </MenuItem>
<MenuItem value="diffSentences">SENTENCES </MenuItem>
<MenuItem value="diffCss">CSS </MenuItem>
</Select>
</FormControl>
space, trim, line, word 단위로 약간의 차이가 있는 것을 알 수 있다.
전체 코드는 다음과 같다.
import React, { useState } from "react";
import Box from "@mui/material/Box";
import CheckIcon from "@mui/icons-material/Check";
import ToggleButton from "@mui/material/ToggleButton";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";
import ReactDiffViewer, { DiffMethod } from "react-diff-viewer-continued";
const oldCode = `
import ToggleButton from "@mui/material/ToggleButton";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
const a = 10
const b = 10
const c = () => console.log('foo')
if(a > 10) {
console.log('bar')
}
console.log('done')
`;
const newCode = `
import React, { useState } from "react";
import ToggleButton from "@mui/material/ToggleButton";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
const a = 10
const boo = 10
if(a === 10) {
console.log('bar')
}
`;
const MyDiffViewer = () => {
const [splitView, setSplitView] = useState(true);
const [diffMethod, setDiffMethod] = useState(DiffMethod.CHARS);
return (
<Box sx={{ m: 2 }}>
<ToggleButton
sx={{ marginBottom: 2 }}
value="check"
selected={splitView}
onChange={() => {
setSplitView(!splitView);
}}
>
<CheckIcon size="small" /> split
</ToggleButton>
<ReactDiffViewer
oldValue={oldCode}
newValue={newCode}
compareMethod={diffMethod}
splitView={splitView}
/>
<FormControl sx={{m : 2, width : "500px"}}>
<InputLabel id="demo-simple-select-label">Age</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={diffMethod}
label="Diff Method"
onChange={(e) => setDiffMethod(e.target.value)}
>
<MenuItem value="diffChars">CHARS</MenuItem>
<MenuItem value="diffWords">WORDS</MenuItem>
<MenuItem value="diffWordsWithSpace">WORDS_WITH_SPACE</MenuItem>
<MenuItem value="diffLines">LINES </MenuItem>
<MenuItem value="diffTrimmedLines">TRIMMED_LINES </MenuItem>
<MenuItem value="diffSentences">SENTENCES </MenuItem>
<MenuItem value="diffCss">CSS </MenuItem>
</Select>
</FormControl>
</Box>
);
};
export default MyDiffViewer;
Mui Textarea로 실시간 텍스트 비교하기
textarea를 양 옆에 추가하여 실시간으로 텍스트를 비교하도록 코드를 수정해 보자.
Textarea 2개를 Box 컴포넌트 안에 넣고 양 옆으로 나오도록 설정하고,
value와 onChange를 각각 oldCode / newCode로 관리하도록 한다.
<Box
sx={{
m: 1,
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Textarea
style={{
width: "50%",
margin: "1px",
}}
name="Left"
placeholder="Old Text..."
variant="outlined"
color="primary"
minRows={15}
maxRows={15}
value={oldCode}
onChange={(e) => setOldCode(e.target.value)}
/>
<Textarea
...
/>
</Box>
전체 코드는 다음과 같다.
import React, { useState } from "react";
import Box from "@mui/material/Box";
import CheckIcon from "@mui/icons-material/Check";
import ToggleButton from "@mui/material/ToggleButton";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";
import Textarea from "@mui/joy/Textarea";
import ReactDiffViewer, { DiffMethod } from "react-diff-viewer-continued";
const MyDiffViewer = () => {
const [oldCode, setOldCode] = useState("");
const [newCode, setNewCode] = useState("");
const [splitView, setSplitView] = useState(true);
const [diffMethod, setDiffMethod] = useState(DiffMethod.CHARS);
return (
<Box sx={{ m: 2 }}>
<ToggleButton
sx={{ marginBottom: 2 }}
value="check"
selected={splitView}
onChange={() => {
setSplitView(!splitView);
}}
>
<CheckIcon size="small" /> split
</ToggleButton>
<Box
sx={{
m: 1,
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Textarea
style={{
width: "50%",
margin: "1px",
}}
name="Left"
placeholder="Old Text..."
variant="outlined"
color="primary"
minRows={15}
maxRows={15}
value={oldCode}
onChange={(e) => setOldCode(e.target.value)}
/>
<Textarea
style={{
width: "50%",
margin: "1px",
}}
name="Right"
placeholder="New Text..."
variant="outlined"
color="warning"
minRows={15}
maxRows={15}
value={newCode}
onChange={(e) => setNewCode(e.target.value)}
/>
</Box>
<ReactDiffViewer
oldValue={oldCode}
newValue={newCode}
compareMethod={diffMethod}
splitView={splitView}
/>
<FormControl sx={{ m: 2, width: "500px" }}>
<InputLabel id="demo-simple-select-label">Age</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={diffMethod}
label="Diff Method"
onChange={(e) => setDiffMethod(e.target.value)}
>
<MenuItem value="diffChars">CHARS</MenuItem>
<MenuItem value="diffWords">WORDS</MenuItem>
<MenuItem value="diffWordsWithSpace">WORDS_WITH_SPACE</MenuItem>
<MenuItem value="diffLines">LINES </MenuItem>
<MenuItem value="diffTrimmedLines">TRIMMED_LINES </MenuItem>
<MenuItem value="diffSentences">SENTENCES </MenuItem>
<MenuItem value="diffCss">CSS </MenuItem>
</Select>
</FormControl>
</Box>
);
};
export default MyDiffViewer;
반응형
'개발 > React' 카테고리의 다른 글
리액트 Material - Alert로 플로팅 메시지 만들기 (Floating / Toast Message with Mui Alert) (0) | 2024.02.03 |
---|---|
리액트 Material - 런타임에 Tab 추가, 삭제하기 (Mui Dynamic Tabs) (0) | 2024.02.03 |
리액트 - html2pdf로 PDF 다운로드하기 (0) | 2024.01.28 |
React Material - Stepper로 워크 플로우 관리하기 (Managing Workflows with Mui Stepper) (0) | 2024.01.24 |
리액트 - 리덕스로 로그인 상태 관리하기 (Managing Login State with Redux) (0) | 2024.01.22 |
댓글