forked from patternfly/patternfly-react
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(component): Creating a DiffView Component (patternfly#1019)
- Loading branch information
1 parent
4ad14bc
commit f38c10a
Showing
13 changed files
with
433 additions
and
2 deletions.
There are no files selected for viewing
47 changes: 47 additions & 0 deletions
47
packages/patternfly-3/patternfly-react-extensions/less/diffview.less
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
@import '~react-diff-view/index.css'; | ||
|
||
@diff-light-green-200: #cdffd8; | ||
@diff-light-green-100: #e6ffed; | ||
@diff-green: #acf2bd; | ||
@diff-light-red: #ffeef0; | ||
@diff-red: #fdb8c0; | ||
|
||
.diff-pf.diff { | ||
border: 1px solid @color-pf-black-300; | ||
max-height: 400px; | ||
overflow: auto; | ||
clear: both; | ||
|
||
.diff-line { | ||
line-height: 1.7; | ||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace; | ||
} | ||
|
||
.diff-gutter { | ||
border-left: 1px solid @color-pf-black-300; | ||
} | ||
|
||
.diff-gutter.diff-gutter-insert { | ||
background-color: @diff-light-green-200; | ||
} | ||
|
||
.diff-hunk-header { | ||
border: 1px solid @color-pf-black-300; | ||
} | ||
|
||
.diff-code-insert { | ||
background-color: @diff-light-green-100; | ||
|
||
mark.diff-code-edit { | ||
background-color: @diff-green; | ||
} | ||
} | ||
|
||
.diff-code-delete { | ||
background-color: @diff-light-red; | ||
|
||
mark.diff-code-edit { | ||
background-color: @diff-red; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,4 @@ | |
@import 'properties-side-panel'; | ||
@import 'table-grid'; | ||
@import 'vertical-tabs'; | ||
@import 'diff-view'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
.../patternfly-3/patternfly-react-extensions/sass/patternfly-react-extensions/_diffview.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
@import '~react-diff-view/index.css'; | ||
|
||
$diff-light-green-200: #cdffd8; | ||
$diff-light-green-100: #e6ffed; | ||
$diff-green: #acf2bd; | ||
$diff-light-red: #ffeef0; | ||
$diff-red: #fdb8c0; | ||
|
||
.diff-pf.diff { | ||
border: 1px solid $color-pf-black-300; | ||
max-height: 400px; | ||
overflow: auto; | ||
clear: both; | ||
|
||
.diff-line { | ||
line-height: 1.7; | ||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace; | ||
} | ||
|
||
.diff-gutter { | ||
border-left: 1px solid $color-pf-black-300; | ||
} | ||
|
||
.diff-gutter.diff-gutter-insert { | ||
background-color: $diff-light-green-200; | ||
} | ||
|
||
.diff-hunk-header { | ||
border: 1px solid $color-pf-black-300; | ||
} | ||
|
||
.diff-code-insert { | ||
background-color: $diff-light-green-100; | ||
|
||
mark.diff-code-edit { | ||
background-color: $diff-green; | ||
} | ||
} | ||
|
||
.diff-code-delete { | ||
background-color: $diff-light-red; | ||
|
||
mark.diff-code-edit { | ||
background-color: $diff-red; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,4 @@ | |
@import 'properties-side-panel'; | ||
@import 'table-grid'; | ||
@import 'vertical-tabs'; | ||
@import 'diffview'; |
91 changes: 91 additions & 0 deletions
91
packages/patternfly-3/patternfly-react-extensions/src/components/DiffView/DiffView.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import classNames from 'classnames'; | ||
|
||
import { parseDiff, Diff, markCharacterEdits, markWordEdits } from 'react-diff-view'; | ||
import { formatLines, diffLines } from 'unidiff'; | ||
|
||
const getDiff = (oldText, newText) => { | ||
const diffText = formatLines(diffLines(oldText, newText)); | ||
// these two lines are faked to mock git diff output | ||
const header = ['diff --git a/a b/b', 'index 0000000..1111111 100644']; | ||
return `${header.join('\n')}\n${diffText}`; | ||
}; | ||
|
||
const DiffView = ({ | ||
oldText, | ||
newText, | ||
className, | ||
viewType, | ||
patch, | ||
markEditsByWord, | ||
emptyState, | ||
markThreshold, | ||
markLongDistanceDiff, | ||
...props | ||
}) => { | ||
const markEditProps = { markThreshold, markLongDistanceDiff }; | ||
const markEdits = markEditsByWord ? markWordEdits(markEditProps) : markCharacterEdits(markEditProps); | ||
const classes = classNames('diff-pf', className); | ||
|
||
// Old, New Text | ||
if (!patch) { | ||
const gitDiff = getDiff(oldText, newText); | ||
const files = parseDiff(gitDiff); | ||
const hunk = files[0].hunks; | ||
|
||
if (hunk.length === 0) return emptyState; | ||
return hunk && <Diff className={classes} hunks={hunk} markEdits={markEdits} viewType={viewType} {...props} />; | ||
} | ||
|
||
// Patch | ||
const files = parseDiff(patch); | ||
// eslint-disable-next-line react/prop-types | ||
const renderFile = ({ oldRevision, newRevision, type, hunks }) => ( | ||
<Diff | ||
className={classes} | ||
key={`${oldRevision}-${newRevision}`} | ||
viewType={viewType} | ||
diffType={type} | ||
hunks={hunks} | ||
markEdits={markEdits} | ||
{...props} | ||
/> | ||
); | ||
|
||
if (patch === '') return emptyState; | ||
return <div>{files.map(renderFile)}</div>; | ||
}; | ||
|
||
DiffView.propTypes = { | ||
/** className */ | ||
className: PropTypes.string, | ||
/** oldText to compare */ | ||
oldText: PropTypes.string, | ||
/** newText to compare */ | ||
newText: PropTypes.string, | ||
/** viewType of the DiffView (Unified, Split) */ | ||
viewType: PropTypes.string.isRequired, | ||
/** git diff output */ | ||
patch: PropTypes.string, | ||
/** mark Diff by Words instead of Characters */ | ||
markEditsByWord: PropTypes.bool, | ||
/** emptyState node when there is no diff */ | ||
emptyState: PropTypes.node.isRequired, | ||
/** The maximum string distance when this function should try to mark edits */ | ||
markThreshold: PropTypes.number, | ||
/** If true, two strings with distance greater than threshold will create an edit containing the whole string */ | ||
markLongDistanceDiff: PropTypes.bool | ||
}; | ||
|
||
DiffView.defaultProps = { | ||
oldText: null, | ||
newText: null, | ||
patch: null, | ||
markEditsByWord: false, | ||
markThreshold: 30, | ||
markLongDistanceDiff: true, | ||
className: '' | ||
}; | ||
|
||
export default DiffView; |
49 changes: 49 additions & 0 deletions
49
...ages/patternfly-3/patternfly-react-extensions/src/components/DiffView/DiffView.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import React from 'react'; | ||
import { storiesOf } from '@storybook/react'; | ||
import { withInfo } from '@storybook/addon-info/dist/index'; | ||
import { defaultTemplate } from 'storybook/decorators/storyTemplates'; | ||
import { storybookPackageName, STORYBOOK_CATEGORY } from 'storybook/constants/siteConstants'; | ||
|
||
import { DiffView } from './index'; | ||
|
||
import { name } from '../../../package.json'; | ||
import { boolean, text, select, withKnobs } from '@storybook/addon-knobs'; | ||
|
||
const stories = storiesOf(`${storybookPackageName(name)}/${STORYBOOK_CATEGORY.CONTENT_VIEWS}/DiffView`, module); | ||
const emptyState = <h1>No Diff</h1>; | ||
|
||
stories.addDecorator( | ||
defaultTemplate({ | ||
title: 'Diff View', | ||
description: ( | ||
<div> | ||
The Diff View is based on the <a href="https://www.npmjs.com/package/react-diff-view">react-diff-view</a>{' '} | ||
package. This Component supports both git diff Patch and Old/New text inputs and displays the diff in Unified or | ||
Split View. | ||
</div> | ||
) | ||
}) | ||
); | ||
|
||
stories.addDecorator(withKnobs); | ||
stories.add( | ||
'DiffView', | ||
withInfo({ | ||
source: true, | ||
propTables: [DiffView] | ||
})(() => { | ||
const viewType = select('View Type', { split: 'split', unified: 'unified' }, 'split'); | ||
|
||
return ( | ||
<div style={{ width: '600px', padding: '30' }}> | ||
<DiffView | ||
oldText={text('Old Text', 'Old Text')} | ||
newText={text('New Text', 'New Text')} | ||
viewType={viewType} | ||
emptyState={emptyState} | ||
markEditsByWord={boolean('Mark by Word', false)} | ||
/> | ||
</div> | ||
); | ||
}) | ||
); |
21 changes: 21 additions & 0 deletions
21
packages/patternfly-3/patternfly-react-extensions/src/components/DiffView/DiffView.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from 'react'; | ||
import { shallow } from 'enzyme'; | ||
import toJson from 'enzyme-to-json'; | ||
|
||
import { DiffView } from './index'; | ||
import { diffMock, patchMock, emptyState } from './_mocks_/DiffViewMocks'; | ||
|
||
test('Diff View renders w/Patch properly', () => { | ||
const component = shallow(<DiffView {...patchMock} />); | ||
expect(toJson(component.render())).toMatchSnapshot(); | ||
}); | ||
|
||
test('Diff View renders w/Text properly', () => { | ||
const component = shallow(<DiffView {...diffMock} />); | ||
expect(toJson(component.render())).toMatchSnapshot(); | ||
}); | ||
|
||
test('Diff View renders emptyState', () => { | ||
const component = shallow(<DiffView {...emptyState} />); | ||
expect(toJson(component.render())).toMatchSnapshot(); | ||
}); |
95 changes: 95 additions & 0 deletions
95
...3/patternfly-react-extensions/src/components/DiffView/__snapshots__/DiffView.test.js.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`Diff View renders emptyState 1`] = ` | ||
<div> | ||
empty | ||
</div> | ||
`; | ||
|
||
exports[`Diff View renders w/Patch properly 1`] = ` | ||
<div> | ||
<table | ||
class="diff diff-pf" | ||
> | ||
<colgroup> | ||
<col | ||
class="diff-gutter-col" | ||
/> | ||
<col | ||
class="diff-gutter-col" | ||
/> | ||
<col /> | ||
</colgroup> | ||
</table> | ||
</div> | ||
`; | ||
|
||
exports[`Diff View renders w/Text properly 1`] = ` | ||
<table | ||
class="diff diff-pf" | ||
> | ||
<colgroup> | ||
<col | ||
class="diff-gutter-col" | ||
/> | ||
<col /> | ||
<col | ||
class="diff-gutter-col" | ||
/> | ||
<col /> | ||
</colgroup> | ||
<tbody | ||
class="diff-hunk" | ||
> | ||
<tr | ||
class="diff-hunk-header" | ||
> | ||
<td | ||
class="diff-hunk-header-gutter" | ||
/> | ||
<td | ||
class="diff-hunk-header-content" | ||
colspan="3" | ||
> | ||
@@ -1 +1 @@ | ||
</td> | ||
</tr> | ||
<tr | ||
class="diff-line diff-line-compare" | ||
> | ||
<td | ||
class="diff-gutter diff-gutter-delete" | ||
data-line-number="1" | ||
/> | ||
<td | ||
class="diff-code diff-code-delete" | ||
> | ||
<span | ||
class="diff-code-text" | ||
> | ||
hello friend | ||
</span> | ||
</td> | ||
<td | ||
class="diff-gutter diff-gutter-insert" | ||
data-line-number="1" | ||
/> | ||
<td | ||
class="diff-code diff-code-insert" | ||
> | ||
<span | ||
class="diff-code-text" | ||
> | ||
hello | ||
<mark | ||
class="diff-code-edit" | ||
> | ||
there | ||
</mark> | ||
friend | ||
</span> | ||
</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
`; |
21 changes: 21 additions & 0 deletions
21
...patternfly-3/patternfly-react-extensions/src/components/DiffView/_mocks_/DiffViewMocks.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from 'react'; | ||
|
||
export const diffMock = { | ||
oldText: 'hello friend', | ||
newText: 'hello there friend', | ||
viewType: 'split', | ||
emptyState: <div>empty</div> | ||
}; | ||
|
||
export const patchMock = { | ||
viewType: 'unified', | ||
patch: '---', | ||
emptyState: <div>empty</div> | ||
}; | ||
|
||
export const emptyState = { | ||
oldText: 'hello friend', | ||
newText: 'hello friend', | ||
viewType: 'split', | ||
emptyState: <div>empty</div> | ||
}; |
Oops, something went wrong.