在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:otakustay/react-diff-view开源软件地址:https://github.com/otakustay/react-diff-view开源编程语言:JavaScript 92.1%开源软件介绍:react-diff-viewA git diff component to consume the git unified diff output. OverviewSplit viewUnified viewOptimized selectionFull features
Run I test the performance with a 2.2MB diff file with 375 files changed, 18721 insertions(+), 35671 deletions(-). In my laptop (MacBook Pro 15-inch 2016, 2.6 GHz Intel Core i7, 16 GB 2133 MHz LPDDR3) it performs quite slow but tolerable without lazy rendering:
Installnpm install --save react-diff-view Basic usageParse diff textFor best display effect, you should generate your diff text with The
The - // if someone has already defined a value bail and don't track value
- // will cause over reporting of changes, but it's better then a hard failure
- // (needed for certain tests that spyOn input values)
- if (node.hasOwnProperty(valueField)) {
+ // if someone has already defined a value or Safari, then bail
+ // and don't track value will cause over reporting of changes,
+ // but it's better then a hard failure
+ // (needed for certain tests that spyOn input values and Safari) This is the normal behavior, which will displayed as 3 lines of deletion, 1 line of modification and 3 lines of addition: When the value - // if someone has already defined a value bail and don't track value
+ // if someone has already defined a value or Safari, then bail
- // will cause over reporting of changes, but it's better then a hard failure
+ // and don't track value will cause over reporting of changes,
- // (needed for certain tests that spyOn input values)
+ // but it's better then a hard failure
- if (node.hasOwnProperty(valueField)) {
+ // (needed for certain tests that spyOn input values and Safari) and as a result rendered as: In most cases it can provide a better look in split view. Render diff hunksThe import {parseDiff, Diff, Hunk} from 'react-diff-view';
const App = ({diffText}) => {
const files = parseDiff(diffText);
const renderFile = ({oldRevision, newRevision, type, hunks}) => (
<Diff key={oldRevision + '-' + newRevision} viewType="split" diffType={type} hunks={hunks}>
{hunks => hunks.map(hunk => <Hunk key={hunk.content} hunk={hunk} />)}
</Diff>
);
return (
<div>
{files.map(renderFile)}
</div>
);
}; The children is optional if you only need all hunks to be displayed, however you can use this function children to add custom events or classes to hunks. As you can see, const filterOutNormalChanges = hunk => {
return {
...hunk,
changes: hunk.changes.filter(change => !change.isNormal);
};
};
const removeNormalChanges = ComponentIn => {
const ComponentOut = ({hunks, ...props}) => {
const purgedHunks = hunks.map(filterOutNormalChanges);
return <ComponentIn {...props} hunks={hunks} />;
};
ComponentOut.displayName = `removeNormalChanges(${ComponentIn.displayName})`;
return ComponentOut;
};
const MyDiff = removeNormalChanges(Diff); We can still pass original Here is the full list of its props:
Key of changeIn if (change.type === 'insert') {
return 'I' + change.lineNumber;
}
else if (change.type === 'delete') {
return 'D' + change.lineNumber;
}
else {
return 'N' + change.oldLineNumber;
} You are not required to compute this key yourself, the Add decoration around hunksA decoration is customized content rendered around
A very simple use case of import {flatMap} from 'lodash';
import {Diff, Hunk, Decoration} from 'react-diff-view';
const renderHunk = hunk => [
<Decoration key={'decoration-' + hunk.content}>
{hunk.content}
</Decoration>,
<Hunk key={'hunk-' + hunk.content}> hunk={hunk} />
];
const DiffFile = ({diffType, hunks}) => (
<Diff viewType="split" diffType={diffType}>
{flatMap(hunks, renderHunk)}
</Diff>
); We can also render more content by providing two elements to const renderHunk = hunk => [
<Decoration key={'decoration-' + hunk.content}>
<SmileFace />,
<span>{hunk.content}</span>
</Decoration>,
<Hunk key={'hunk-' + hunk.content}> hunk={hunk} />
] Add widgetsIn some cases we need functions like commenting on change, A widget is any react element bound to a change object, a widget is configured in an object with In split view a widget will be rendered to its corresponding side if change object is of type addition or deletion, otherwise the widget will be rendered across the entire row. Note although the Here is a very basic example which adds a warning text on long lines: import {parseDiff, getChangeKey, Diff} from 'react-diff-view';
const getWidgets = hunks => {
const changes = hunks.reduce((result, {changes}) => [...result, ...changes], []);
const longLines = changes.filter(({content}) => content.length > 120);
return longLines.reduce(
(widgets, change) => {
const changeKey = getChangeKey(change);
return {
...widgets,
[changeKey]: <span className="error">Line too long</span>
};
},
{}
);
};
const App = ({diffText}) => {
const files = parseDiff(diffText);
return (
<div>
{files.map(({hunks}, i) => <Diff key={i} hunks={hunks} widgets={getWidgets(hunks)} viewType="split" />)}
</div>
);
}; For a more complex case, you can reference the example in demo/File.js about implementing code comments with the Customize stylesThe basic theme of CSS variables
:root {
--diff-background-color: initial;
--diff-text-color: initial;
--diff-font-family: Consolas, Courier, monospace;
--diff-selection-background-color: #b3d7ff;
--diff-gutter-insert-background-color: #d6fedb;
--diff-gutter-delete-background-color: #fadde0;
--diff-gutter-selected-background-color: #fffce0;
--diff-code-insert-background-color: #eaffee;
--diff-code-delete-background-color: #fdeff0;
--diff-code-insert-edit-background-color: #c0dc91;
--diff-code-delete-edit-background-color: #f39ea2;
--diff-code-selected-background-color: #fffce0;
--diff-omit-gutter-line-color: #cb2a1d;
} For code highlight colors, we recommend prism-color-variables package which includes CSS variables of every refractor generated token type. Class namesYou can override styles on certain css classes to customize the appearance of
The // Less selector to disable the line number and add an icon in the gutter element when a change is hovered
.diff-line-hover-old.diff-gutter,
.diff-line-hover-new.diff-gutter,
.diff-unified .diff-line:hover .diff-gutter {
&::before {
font-family: "FontAwesome";
content: "\f4b2"; // comment-plus
}
} You can pass the The
Similarly
Customize eventsThe Both of the above prop is an object containing DOM events key/value pair. Each event callback receive an object with key One of the common cases is to add code selecting functionality. This can be archived simply by passing an import {PureComponent} from 'react';
import {bind} from 'lodash-decorators';
import {Diff} from 'react-diff-view';
class File extends PureComponent {
state = {
selectedChanges: [],
gutterEvents: {
onClick: this.selectChange
},
codeEvents: {
onClick: this.selectChange
}
};
@bind()
selectChange({change}) {
const {selectedChanges} = this.state;
const selected = selectedChanges.includes(change);
this.setState({selectedChanges: selected ? without(selectedChanges, change) : [...selectedChanges, change]});
}
render() {
const {hunks, diffType} = this.props;
const {gutterEvents, codeEvents} = this.state;
const hunkProps = {gutterEvents, codeEvents};
return (
<Diff viewType="split" diffType={diffType}>
{hunk.map(hunk => <Hunk key={hunk.content} hunk={hunk} {...hunkProps} />)}
</Diff>
);
}
} Token |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论