diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..fe8cd1d
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,3 @@
+{
+ "presets": ["es2015", "react"]
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 26a3afe..7963c35 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,92 @@
-# react-diff
+# react-stylable-diff
-Highlights differences between two strings, uses the [diff](https://www.npmjs.com/package/diff) module
+Output differences between two strings in a stylable form.
+
+Based on [react-diff](https://www.npmjs.com/package/react-diff). Uses the [diff](https://www.npmjs.com/package/diff) module
## Installation
```
-npm install react-diff
+npm install react-stylable-diff
+```
+
+## Usage
+
+Pass text to compare as `props.inputA` and `props.inputB`:
+
+```javascript
+var React = require('react');
+var Diff = require('react-stylable-diff');
+
+var MyComponent = React.createClass({
+ render: function() {
+ return (
+
+ );
+ }
+});
+```
+
+You can also specify different values in `props.type`
+to compare in different ways. Valid values are `'chars'`, `'words'`, `'wordsWit Space'`, `'lines'`, `'trimmedLines'`, `'sentences'`, `'css'`, and `'json'`. You can also use options (check it in [diff](https://github.com/kpdecker/jsdiff) module):
+
+
+```javascript
+var React = require('react');
+var Diff = require('react-stylable-diff');
+
+var MyComponent = React.createClass({
+ render: function() {
+ return (
+
+ );
+ }
+});
```
-## Demo
+### Styling
+
+Outputs standard `` and `` tags so you will at least
+have the browser default styling for these. On my browser they
+appear crossed-out or underlined.
+
+You will probably want to add your own styles to look all fancy.
+
+The output is wrapped in a div with class `'Difference'` so you can
+attach all your style rules to that. You can override this class with
+`props.className` if you like.
-http://cezary.github.io/react-diff/
+Here are some styles that might work:
+
+```css
+.Difference {
+ font-family: monospace;
+}
+
+.Difference > del {
+ background-color: rgb(255, 224, 224);
+ text-decoration: none;
+}
+
+.Difference > ins {
+ background-color: rgb(201, 238, 211);
+ text-decoration: none;
+}
+```
## Example
```javascript
var React = require('react');
-var Diff = require('react-diff');
+var Diff = require('react-stylable-diff');
var Component = React.createClass({
render: function() {
return (
-
+
);
}
});
diff --git a/dist/react-diff.js b/dist/react-diff.js
index 947b6db..c57bf92 100644
--- a/dist/react-diff.js
+++ b/dist/react-diff.js
@@ -1,48 +1,113 @@
'use strict';
-var React = require('react');
-var jsdiff = require('diff');
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _diff = require('diff');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var fnMap = {
- chars: jsdiff.diffChars,
- words: jsdiff.diffWords,
- sentences: jsdiff.diffSentences,
- json: jsdiff.diffJson
+ 'chars': _diff.diffChars,
+ 'words': _diff.diffWords,
+ 'wordsWithSpace': _diff.diffWrodsWithSpace,
+ 'lines': _diff.diffLines,
+ 'trimmedLines': _diff.diffTrimmedLines,
+ 'sentences': _diff.diffSentences,
+ 'css': _diff.diffCss,
+ 'json': _diff.diffJson
};
-module.exports = React.createClass({
- displayName: 'Diff',
+/**
+ * Display diff in a stylable form.
+ *
+ * Default is character diff. Change with props.type. Valid values
+ * are 'chars', 'words', 'sentences', 'json'.
+ *
+ * - Wrapping div has class 'Difference', override with props.className
+ * - added parts are in
+ * - removed parts are in
+ * - unchanged parts are in
+ */
+
+var ReactDiff = function (_React$Component) {
+ _inherits(ReactDiff, _React$Component);
+
+ function ReactDiff() {
+ _classCallCheck(this, ReactDiff);
- getDefaultProps: function getDefaultProps() {
- return {
+ var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ReactDiff).call(this));
+
+ _this.displayName = 'Diff';
+
+ _this.defaultProps = {
inputA: '',
inputB: '',
- type: 'chars'
+ type: 'chars',
+ options: null,
+ className: 'difference'
};
- },
-
- propTypes: {
- inputA: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.object]),
- inputB: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.object]),
- type: React.PropTypes.oneOf(['chars', 'words', 'sentences', 'json'])
- },
-
- render: function render() {
- var diff = fnMap[this.props.type](this.props.inputA, this.props.inputB);
- var result = diff.map(function (part) {
- var spanStyle = {
- backgroundColor: part.added ? 'lightgreen' : part.removed ? 'salmon' : 'lightgrey'
- };
- return React.createElement(
- 'span',
- { style: spanStyle },
- part.value
+
+ _this.propTypes = {
+ inputA: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.object]),
+ inputB: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.object]),
+ type: _react2.default.PropTypes.oneOf(['chars', 'words', 'wordsWithSpace', 'lines', 'trimmedLines', 'sentences', 'css', 'json']),
+ options: _react2.default.PropTypes.object
+ };
+ return _this;
+ }
+
+ _createClass(ReactDiff, [{
+ key: 'render',
+ value: function render() {
+ var diff = fnMap[this.props.type](this.props.inputA, this.props.inputB, this.props.options);
+
+ var result = diff.map(function (part, index) {
+ if (part.added) {
+ return _react2.default.createElement(
+ 'ins',
+ { key: index },
+ part.value
+ );
+ }
+ if (part.removed) {
+ return _react2.default.createElement(
+ 'del',
+ { key: index },
+ part.value
+ );
+ }
+ return _react2.default.createElement(
+ 'span',
+ { key: index },
+ part.value
+ );
+ });
+
+ return _react2.default.createElement(
+ 'div',
+ this.props,
+ result
);
- });
- return React.createElement(
- 'pre',
- { className: 'diff-result' },
- result
- );
- } });
+ }
+ }]);
+
+ return ReactDiff;
+}(_react2.default.Component);
+
+exports.default = ReactDiff;
+;
diff --git a/lib/react-diff.js b/lib/react-diff.js
deleted file mode 100644
index 24dad04..0000000
--- a/lib/react-diff.js
+++ /dev/null
@@ -1,53 +0,0 @@
-var React = require('react');
-var jsdiff = require('diff');
-
-var fnMap = {
- 'chars': jsdiff.diffChars,
- 'words': jsdiff.diffWords,
- 'sentences': jsdiff.diffSentences,
- 'json': jsdiff.diffJson
-};
-
-module.exports = React.createClass({
- displayName: 'Diff',
-
- getDefaultProps: function() {
- return {
- inputA: '',
- inputB: '',
- type: 'chars'
- };
- },
-
- propTypes: {
- inputA: React.PropTypes.oneOfType([
- React.PropTypes.string,
- React.PropTypes.object
- ]),
- inputB: React.PropTypes.oneOfType([
- React.PropTypes.string,
- React.PropTypes.object
- ]),
- type: React.PropTypes.oneOf([
- 'chars',
- 'words',
- 'sentences',
- 'json'
- ])
- },
-
- render: function () {
- var diff = fnMap[this.props.type](this.props.inputA, this.props.inputB);
- var result = diff.map(function(part, index) {
- var spanStyle = {
- backgroundColor: part.added ? 'lightgreen' : part.removed ? 'salmon' : 'lightgrey'
- }
- return {part.value}
- });
- return (
-
- {result}
-
- );
- },
-});
diff --git a/lib/react-diff.jsx b/lib/react-diff.jsx
new file mode 100644
index 0000000..858799e
--- /dev/null
+++ b/lib/react-diff.jsx
@@ -0,0 +1,81 @@
+import React from 'react';
+import {diffChars, diffWords, diffWrodsWithSpace, diffLines, diffTrimmedLines, diffSentences, diffCss, diffJson} from 'diff';
+
+var fnMap = {
+ 'chars': diffChars,
+ 'words': diffWords,
+ 'wordsWithSpace': diffWrodsWithSpace,
+ 'lines': diffLines,
+ 'trimmedLines': diffTrimmedLines,
+ 'sentences': diffSentences,
+ 'css': diffCss,
+ 'json': diffJson
+};
+
+/**
+ * Display diff in a stylable form.
+ *
+ * Default is character diff. Change with props.type. Valid values
+ * are 'chars', 'words', 'sentences', 'json'.
+ *
+ * - Wrapping div has class 'Difference', override with props.className
+ * - added parts are in
+ * - removed parts are in
+ * - unchanged parts are in
+ */
+export default class ReactDiff extends React.Component {
+ constructor() {
+ super();
+ this.displayName = 'Diff';
+
+ this.defaultProps = {
+ inputA: '',
+ inputB: '',
+ type: 'chars',
+ options: null,
+ className: 'difference'
+ };
+
+ this.propTypes = {
+ inputA: React.PropTypes.oneOfType([
+ React.PropTypes.string,
+ React.PropTypes.object
+ ]),
+ inputB: React.PropTypes.oneOfType([
+ React.PropTypes.string,
+ React.PropTypes.object
+ ]),
+ type: React.PropTypes.oneOf([
+ 'chars',
+ 'words',
+ 'wordsWithSpace',
+ 'lines',
+ 'trimmedLines',
+ 'sentences',
+ 'css',
+ 'json'
+ ]),
+ options: React.PropTypes.object
+ }
+ }
+
+ render() {
+ var diff = fnMap[this.props.type](this.props.inputA, this.props.inputB, this.props.options);
+
+ var result = diff.map(function(part, index) {
+ if (part.added) {
+ return {part.value};
+ }
+ if (part.removed) {
+ return {part.value};
+ }
+ return {part.value};
+ });
+
+ return (
+
+ {result}
+
+ );
+ }
+};
diff --git a/package.json b/package.json
index 80d8ade..18bc6d5 100644
--- a/package.json
+++ b/package.json
@@ -1,32 +1,39 @@
{
- "name": "react-diff",
- "version": "0.0.6",
- "description": "Highlight differences between inputs",
+ "name": "react-stylable-diff",
+ "version": "1.0.1",
+ "description": "Output differences between inputs, ready for css styling",
"main": "dist/react-diff.js",
"scripts": {
- "build": "./node_modules/.bin/babel lib/react-diff.js > dist/react-diff.js"
+ "build": "babel lib --out-dir dist"
},
"repository": {
"type": "git",
- "url": "https://github.com/cezary/react-diff.git"
+ "url": "https://github.com/davidmason/react-stylable-diff.git"
},
"keywords": [
"react",
- "diff"
+ "diff",
+ "css"
+ ],
+ "author": "David Mason ",
+ "contributors": [
+ "Cezary Wojtkowski ",
+ "Felix Hao "
],
- "author": "Cezary Wojtkowski ",
"license": "MIT",
"bugs": {
- "url": "https://github.com/cezary/react-diff/issues"
+ "url": "https://github.com/davidmason/react-stylable-diff/issues"
},
- "homepage": "https://github.com/cezary/react-diff",
+ "homepage": "https://github.com/davidmason/react-stylable-diff",
"peerDependencies": {
"react": ">=0.12.0"
},
"dependencies": {
- "diff": "^1.2.0"
+ "diff": "^2.2.1"
},
"devDependencies": {
- "babel": "^5.1.10"
+ "babel": "^6.3.26",
+ "babel-preset-es2015": "^6.3.13",
+ "babel-preset-react": "^6.3.13"
}
}