본문으로 건너뛰기

TextDiff

tsx
<TextDiff before={saved} after={draft} />
<TextDiff mode="editor" defaultBefore={saved} defaultAfter={draft} />
dart
TextDiff(before: saved, after: draft);
TextDiff(mode: DiffineMode.editor, defaultBefore: saved, defaultAfter: draft);

모드

prop타입기본값무엇을 정하는지
mode'viewer' | 'editor''viewer'두 문서를 읽을지 쓸지.
인자타입기본값무엇을 정하는지
modeDiffineModeDiffineMode.viewer두 문서를 읽을지 쓸지.

컴포넌트 하나가위젯 하나가 둘 다 그립니다. editor는 창마다 입력란을 한 겹 덮어서 글자를 칠 때마다 비교를 다시 계산하고, 나머지는 — 줄도, 깔리는 색도, 짚어 주는 단어도, 띠도, 버튼도, 찾기도 — 양쪽이 같습니다.

editor에서 무시되는 prop이 몇 있습니다. view, alignLines, collapse, context, renderGutter, renderWidget은 입력란이 한 열이 될 수도, 커서를 놓을 수 있는 빈 칸으로 채워질 수도, 줄을 감출 수도, 줄 사이에 다른 것을 끼울 수도 없어서 무시되고, result는 아직 아무도 손대지 않은 문서의 비교라서 무시됩니다. 반대로 readOnly, indentWithTab, spellCheck, defaultBefore, defaultAfter, onLanguageChangeviewer에서 하는 일이 없습니다.

DiffineMode.editor에서 무시되는 인자가 몇 있습니다. view, alignLines, collapse, context, renderGutter, renderWidget은 입력란이 한 열이 될 수도, 커서를 놓을 수 있는 빈 칸으로 채워질 수도, 줄을 감출 수도, 줄 사이에 다른 것을 끼울 수도 없어서 무시되고, result는 아직 아무도 손대지 않은 문서의 비교라서 무시됩니다. 반대로 readOnly, indentWithTab, defaultBefore, defaultAfter, onLanguageChangedDiffineMode.viewer에서 하는 일이 없습니다.

문서

prop타입기본값무엇인지
beforestring | DiffineSource''왼쪽 문서.
afterstring | DiffineSource''오른쪽 문서.
defaultBeforestring | DiffineSource''왼쪽 입력란이 처음 담을 내용. 에디터 전용.
defaultAfterstring | DiffineSource''오른쪽 입력란이 처음 담을 내용. 에디터 전용.
onBeforeChange(value: string) => void왼쪽 문서가 바뀌었을 때.
onAfterChange(value: string) => void오른쪽 문서가 바뀌었을 때.
onDiff(result: DiffResult) => void비교를 다시 계산할 때마다의 결과.
readOnlyboolean | 'before' | 'after'false고칠 수 없는 쪽. 에디터 전용.
resultDiffResult이미 계산된 비교 결과. 주면 beforeafter는 무시됩니다. 뷰어 전용.
diffDiffOptions비교 방식.

DiffineSource{ content: string; label?: string }입니다. label이 헤더에 표시되는 이름이고, 없으면 현재 로케일의 기본 낱말이 들어갑니다.

뷰어는 렌더할 때마다 prop에서 문서를 다시 읽습니다. 에디터는 제어 컴포넌트와 비제어 컴포넌트 양쪽을 지원합니다. beforeafter를 주면 그 문서는 애플리케이션이 관리하고, defaultBeforedefaultAfter를 주면 컴포넌트가 관리합니다. 어느 쪽인지는 첫 렌더에서 정해지고, onBeforeChangeonAfterChange는 누가 관리하든 호출됩니다.

인자타입기본값무엇인지
beforeString?왼쪽 문서.
afterString?오른쪽 문서.
beforeLabelString?헤더가 왼쪽을 부르는 이름.
afterLabelString?오른쪽을 부르는 이름.
defaultBeforeString?왼쪽 입력란이 처음 담을 내용. 에디터 전용.
defaultAfterString?오른쪽 입력란이 처음 담을 내용. 에디터 전용.
onBeforeChangedValueChanged<String>?왼쪽 문서가 바뀌었을 때.
onAfterChangedValueChanged<String>?오른쪽 문서가 바뀌었을 때.
onDiffValueChanged<DiffResult>?비교를 다시 계산할 때마다의 결과.
readOnlyDiffineSide?고칠 수 없는 쪽. 에디터 전용.
resultDiffResult?이미 계산된 비교 결과. 주면 beforeafter는 무시됩니다. 뷰어 전용.
diffDiffOptionskDiffineDefaults비교 방식.

문서와 이름이 한 값이 아니라 인자 둘인 이유는 String 자체가 이미 문서 전부이기 때문입니다. 이름을 주지 않으면 헤더에 현재 로케일의 기본 낱말이 들어갑니다.

뷰어는 빌드할 때마다 위젯에서 문서를 다시 읽습니다. 에디터는 beforeafter를 주면 그 문서를 애플리케이션이 관리하고, defaultBeforedefaultAfter를 주면 위젯이 관리합니다. 어느 쪽인지는 첫 빌드에서 정해지고, onBeforeChangedonAfterChanged는 누가 관리하든 호출됩니다.

화면

prop타입기본값무엇을 정하는지
view'split' | 'unified''split'좌우로 나눌지, 한 줄로 볼지.
lineNumbersbooleantrue각 줄에 번호를 붙일지.
markersbooleantrue바뀐 줄에 +, , ~를 붙일지.
wrapbooleanfalse긴 줄을 접을지 옆으로 흘릴지.
alignLinesbooleantrue맞은편 줄과 높이를 맞출지.
collapsebooleanfalse변경에서 먼 그대로인 줄을 접을지.
contextnumber3변경 앞뒤로 남길 그대로인 줄 수.
connectorsbooleantrue변경을 두 창 사이에 띠로 그릴지.
applyChangesbooleanfalse변경마다 반대편에 적용하는 버튼을 둘지.
syncScrollbooleantrue한쪽을 스크롤하면 다른 쪽도 따라갈지.
headerbooleantrue각 문서의 이름을 위에 쓸지.
navigationbooleantrue변경 사이를 오가는 버튼을 그릴지.
searchbooleantrue창 안에서 문서를 찾을 수 있게 할지.
summarybooleantrue아래쪽 상태 표시줄을 그릴지.
virtualizebooleantrue보이는 줄만 그릴지.
showInvisiblesbooleanfalse줄 안의 공백과 탭을 그릴지.
languagestring'plain'문서가 어떤 언어인지. 그 언어로 색을 입힙니다.
defaultLanguagestring'plain'컴포넌트가 직접 관리할 때의 처음 언어.
onLanguageChange(language: string) => void메뉴에서 언어를 골랐을 때. 에디터 전용.
languageLabelbooleanfalse그 언어를 위쪽 줄 오른쪽 끝에 그릴지.
tabSizenumber4탭을 몇 칸으로 그릴지.
colorScheme'system' | 'light' | 'dark''system'어떤 팔레트로 그릴지.
fontDiffineFont문서를 그리는 글꼴.
locale'en' | 'ko''en'컴포넌트 자신이 쓰는 말의 언어.
stringsPartial<DiffineTextStrings>로케일 대신 쓸 단어.
highlightDiffineHighlightlanguage 대신 쓸, 애플리케이션 자신의 강조기.
renderGutterDiffineRender줄 옆 여백에 넣을, 애플리케이션 자신의 내용.
renderWidgetDiffineRender줄 아래에 넣을, 애플리케이션 자신의 내용.

collapsecontextviewer의 것입니다. 에디터는 입력란이 문서 전체를 들고 있어서 아무것도 접지 않습니다. applyChangeseditor의 것입니다. 변경을 적용한다는 것은 문서를 쓴다는 뜻이고, 버튼은 connectors가 그리는 열에 놓입니다. connectorssyncScroll은 두 창 사이의 이야기라서 unified에서는 무시됩니다. languageLabelviewer에서 언어 이름을, editor에서 그 이름을 고르는 메뉴를 그립니다. 그 선택을 누가 관리하는지는 language, defaultLanguage, onLanguageChange가 정합니다.

그 밖에 넘긴 것은 전부 엘리먼트로 그대로 갑니다. id, className, style, aria-*<div>에서와 똑같이 동작합니다.

인자타입기본값무엇을 정하는지
viewDiffineViewDiffineView.split좌우로 나눌지, 한 줄로 볼지.
lineNumbersbooltrue각 줄에 번호를 붙일지.
markersbooltrue바뀐 줄에 +, , ~를 붙일지.
wrapboolfalse긴 줄을 접을지 옆으로 흘릴지.
alignLinesbooltrue맞은편 줄과 높이를 맞출지.
collapseboolfalse변경에서 먼 그대로인 줄을 접을지.
contextint3변경 앞뒤로 남길 그대로인 줄 수.
connectorsbooltrue변경을 두 창 사이에 띠로 그릴지.
applyChangesboolfalse변경마다 반대편에 적용하는 버튼을 둘지.
syncScrollbooltrue한쪽을 스크롤하면 다른 쪽도 따라갈지.
headerbooltrue각 문서의 이름을 위에 쓸지.
navigationbooltrue변경 사이를 오가는 버튼을 그릴지.
searchbooltrue창 안에서 문서를 찾을 수 있게 할지.
summarybooltrue아래쪽 상태 표시줄을 그릴지.
showInvisiblesboolfalse줄 안의 공백과 탭을 그릴지.
languageString?문서가 어떤 언어인지. 그 언어로 색을 입힙니다.
defaultLanguageString'plain'위젯이 직접 관리할 때의 처음 언어.
onLanguageChangedValueChanged<String>?메뉴에서 언어를 골랐을 때. 에디터 전용.
languageLabelbooltrue그 언어를 위쪽 줄 오른쪽 끝에 그릴지.
colorSchemeDiffineColorScheme.system어떤 팔레트로 그릴지.
themeDiffineTheme?팔레트 전체와 치수.
fontDiffineFont?문서를 그리는 글꼴.
heightdouble?비교 전체의 높이. double.infinity면 감싼 위젯을 채웁니다.
localeDiffineLocaleDiffineLocale.en위젯 자신이 쓰는 말의 언어.
stringsDiffineStrings?로케일 대신 쓸 낱말.
highlightDiffineHighlight?language 대신 쓸, 애플리케이션 자신의 강조기.
renderGutterDiffineRender?줄 옆 여백에 넣을, 애플리케이션 자신의 내용.
renderWidgetDiffineRender?줄 아래에 넣을, 애플리케이션 자신의 내용.

collapsecontext는 뷰어의 것입니다. 에디터는 입력란이 문서 전체를 들고 있어서 아무것도 접지 않습니다. applyChanges는 에디터의 것입니다. 변경을 적용한다는 것은 문서를 쓴다는 뜻이고, 버튼은 connectors가 그리는 열에 놓입니다. connectorssyncScroll은 두 창 사이의 이야기라서 DiffineView.unified에서는 무시됩니다. languageLabel은 뷰어에서 언어 이름을, 에디터에서 그 이름을 고르는 메뉴를 그립니다. 그 선택을 누가 관리하는지는 language, defaultLanguage, onLanguageChanged가 정합니다.

virtualize는 없습니다. 행은 언제나 닿는 대로 만들어집니다. ListView가 원래 그런 것이기 때문입니다. 그것을 끄는 것은 renderWidget이고, 인자 없이 스스로 끕니다. 애플리케이션이 줄 아래에 그린 것은 언제든 커질 수 있어서, 그런 행을 대신 세워 두면 엉뚱한 자리에 서기 때문입니다.

tabSize는 여기가 아니라 테마에 있습니다. 탭을 몇 칸으로 그리는지는 치수이고, 치수는 한곳에 모여 있습니다.

입력

prop타입기본값무엇을 정하는지
indentWithTabbooleanfalseTab이 탭 문자를 넣을지, 다음 컨트롤로 갈지.
spellCheckbooleanfalse브라우저가 맞춤법 표시를 할지.

둘 다 editor의 것입니다. indentWithTab을 켜도 Shift+Tab은 이전 컨트롤로 가고 Escape는 다음 Tab을 브라우저에 넘깁니다. 키보드로 빠져나올 수 없는 입력란은 되지 않습니다.

인자타입기본값무엇을 정하는지
indentWithTabboolfalseTab이 탭 문자를 넣을지, 다음 컨트롤로 갈지.

에디터 전용입니다. 켜도 Shift+Tab은 이전 컨트롤로 가고 Escape는 다음 Tab을 프레임워크에 넘깁니다. 키보드로 빠져나올 수 없는 입력란은 되지 않습니다.

spellCheck는 없습니다. 맞춤법은 그것을 가진 플랫폼에서는 플랫폼의 몫이고 나머지에서는 아예 없는 기능이라, 절반에서만 동작하는 인자는 위젯이 지킬 수 없는 약속이 됩니다.

지금 보고 있는 변경

prop타입기본값무엇인지
selectednumber보고 있는 변경, 없으면 -1.
defaultSelectednumber-1처음에 선택할 변경.
onSelectedChange(selected: number, change: DiffChange | null) => void다른 변경으로 이동했을 때.

selectedchanges의 인덱스입니다. 값을 주면 애플리케이션이 관리하는 것이 되고, 값을 바꾸면 버튼을 눌렀을 때와 똑같이 화면이 이동합니다. onSelectedChange는 누가 관리하든 호출됩니다.

인자타입기본값무엇인지
selectedint?보고 있는 변경, 없으면 -1.
defaultSelectedint-1처음에 선택할 변경.
onSelectedChangedvoid Function(int, DiffChange?)?다른 변경으로 이동했을 때.

selectedchanges의 인덱스입니다. 값을 주면 애플리케이션이 관리하는 것이 되고, 값을 바꾸면 버튼을 눌렀을 때와 똑같이 화면이 이동합니다. onSelectedChanged는 누가 관리하든 호출됩니다.

창 안에서 찾기

창은 각자 찾습니다. 위쪽 막대의 버튼이 그 창 아래에 막대를 열고, Ctrl+F(맥에서는 Cmd+F)는 키보드가 놓인 창의 막대를 엽니다. 양쪽은 질의도 개수도 막대도 각자여서, 한쪽을 닫아도 다른 쪽은 그대로입니다.

입력하는 동안 찾은 자리가 표시되고 창은 지금 보고 있는 자리로 이동합니다. EnterShift+Enter로 다음과 이전을 오갑니다. 입력란 안의 스위치 세 개는 각각 대소문자 구분, 단어 단위, 정규식입니다. Escape는 막대를 닫습니다.

에디터에는 바꾸기 줄이 하나 더 붙고 Ctrl+H가 막대와 함께 그 줄을 엽니다. 바꿀 내용은 적은 글자 그대로 들어갑니다. $1은 달러 기호와 숫자 1입니다. 브라우저 자신의 편집 명령으로 넣기 때문에 Ctrl+Z로 되돌립니다.입력란 자신의 컨트롤러로 넣기 때문에 플랫폼의 되돌리기로 되돌립니다. readOnly인 쪽은 찾기만 되고 바꾸기는 되지 않습니다.

찾기를 연 창도 보이는 줄만 그립니다. 9000번째 줄에서 찾은 자리는 그리로 스크롤한 다음 그려집니다. search={false}search: false는 버튼과 단축키를 함께 끕니다. 그 키를 페이지화면의 다른 기능이 쓰고 있다면 이 값을 쓰세요.

Released under the MIT License