Compare commits

..

No commits in common. "master" and "react-docgen" have entirely different histories.

23 changed files with 96 additions and 17113 deletions

View file

@ -2,7 +2,7 @@ test/
cdn/
coverage/
docs/
sample-site/
docs-site/
server.js
webpack.sample.config.js
styleguide.config.js

View file

@ -29,8 +29,6 @@ const csvData =[
<CSVDownload data={csvData} target="_blank" />
```
And many examples are [here 👈🏼](http://elegance.abdennoor.com/react-csv)
# Install
```
@ -195,10 +193,3 @@ For non-node developers, they have to use CDN version :
- `npm docgen` generates documentation in HTML output.
- `npm cdn` generate a bundle to be used as CDN
# Donation
If this project help you reduce time to develop, you can give me a cup of coffee 🍵 :)
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.me/AbdennourT/2)

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -33,7 +33,6 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
var defaultProps = {
target: '_blank'
};
var CSVDownload = (_temp = _class = function (_React$Component) {
_inherits(CSVDownload, _React$Component);
@ -183,20 +182,17 @@ var jsonsHeaders = exports.jsonsHeaders = function jsonsHeaders(array) {
var jsons2arrays = exports.jsons2arrays = function jsons2arrays(jsons, headers) {
headers = headers || jsonsHeaders(jsons);
var data = jsons.map(function (object) {
return [headers].concat(_toConsumableArray(jsons.map(function (object) {
return headers.map(function (header) {
return header in object ? object[header] : '';
return object[header] ? object[header] : '';
});
});
return [headers].concat(_toConsumableArray(data));
})));
};
var joiner = exports.joiner = function joiner(data) {
var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ',';
return data.map(function (row, index) {
return row.map(function (element) {
return "\"" + element + "\"";
}).join(separator);
return row.join(separator);
}).join('\n');
};
@ -220,7 +216,7 @@ var toCSV = exports.toCSV = function toCSV(data, headers, separator) {
};
var buildURI = exports.buildURI = function buildURI(data, headers, separator) {
return encodeURI('data:text/csv;charset=utf-8,\uFEFF,' + toCSV(data, headers, separator));
return encodeURI('data:text/csv;charset=utf-8,' + toCSV(data, headers, separator));
};
},{}],5:[function(require,module,exports){
'use strict';
@ -861,17 +857,6 @@ var fourArgumentPooler = function (a1, a2, a3, a4) {
}
};
var fiveArgumentPooler = function (a1, a2, a3, a4, a5) {
var Klass = this;
if (Klass.instancePool.length) {
var instance = Klass.instancePool.pop();
Klass.call(instance, a1, a2, a3, a4, a5);
return instance;
} else {
return new Klass(a1, a2, a3, a4, a5);
}
};
var standardReleaser = function (instance) {
var Klass = this;
!(instance instanceof Klass) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : _prodInvariant('25') : void 0;
@ -911,8 +896,7 @@ var PooledClass = {
oneArgumentPooler: oneArgumentPooler,
twoArgumentPooler: twoArgumentPooler,
threeArgumentPooler: threeArgumentPooler,
fourArgumentPooler: fourArgumentPooler,
fiveArgumentPooler: fiveArgumentPooler
fourArgumentPooler: fourArgumentPooler
};
module.exports = PooledClass;
@ -3106,7 +3090,14 @@ var ReactElementValidator = {
// We warn in this case but don't throw. We expect the element creation to
// succeed and there will likely be errors in render.
if (!validType) {
process.env.NODE_ENV !== 'production' ? warning(false, 'React.createElement: type should not be null, undefined, boolean, or ' + 'number. It should be a string (for DOM elements) or a ReactClass ' + '(for composite components).%s', getDeclarationErrorAddendum()) : void 0;
if (typeof type !== 'function' && typeof type !== 'string') {
var info = '';
if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
info += ' You likely forgot to export your component from the file ' + 'it\'s defined in.';
}
info += getDeclarationErrorAddendum();
process.env.NODE_ENV !== 'production' ? warning(false, 'React.createElement: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', type == null ? type : typeof type, info) : void 0;
}
}
var element = ReactElement.createElement.apply(this, arguments);
@ -3802,7 +3793,7 @@ module.exports = ReactPureComponent;
'use strict';
module.exports = '15.4.1';
module.exports = '15.4.2';
},{}],31:[function(require,module,exports){
(function (process){
/**

File diff suppressed because one or more lines are too long

30
docs/build/bundle.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -4,13 +4,11 @@
<head>
<meta charset="utf-8">
<title>React CSV pattern library</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="build/bundle1234.js"></script>
<script type="text/javascript" src="build/bundle.js"></script>
<script type="text/javascript" src="forkme.js"></script>
</body>

View file

@ -1,6 +1,6 @@
{
"name": "react-csv",
"version": "1.0.6",
"version": "1.0.3",
"description": "Build CSV files on the fly basing on Array/literal object of data ",
"main": "index.js",
"jsnext:main": "src/index.js",
@ -59,7 +59,7 @@
"console-info": "0.0.4",
"coveralls": "^2.11.15",
"css-loader": "^0.26.1",
"enzyme": "^2.8.2",
"enzyme": "^2.6.0",
"expect": "^1.20.2",
"extract-text-webpack-plugin": "^1.0.1",
"isparta-loader": "^2.0.0",
@ -67,10 +67,10 @@
"jsdom-global": "2.1.0",
"mocha": "^3.2.0",
"mocha-lcov-reporter": "^1.2.0",
"react": "^15.5.4",
"react-test-renderer": "^15.5.4",
"react": "^15.4.1",
"react-addons-test-utils": "^15.4.1",
"react-docgen": "^2.13.0",
"react-dom": "^15.5.4",
"react-dom": "^15.4.1",
"react-styleguidist": "^4.6.3",
"sass-loader": "^4.0.2",
"sinon": "^1.17.6",

View file

@ -8,24 +8,8 @@ const data = [
];
<CSVDownload data={data} />
```
Another example of `CSVDownload`
```example
const headers = ['firstname', 'lastname', 'email'] ;
const data = [
['Ahmed', 'Tomi' , 'ah@smthing.co.com'] ,
['Raed', 'Labes' , 'rl@smthing.co.com'] ,
['Yezzi','Min l3b', 'ymin@cocococo.com']
];
const iWantToDownload = false; // <--- double click on "false", and change it to "true"
if (iWantToDownload) {
<CSVDownload data={data} headers={headers} />
} else {
<div>Click on "Show Code" below right, and try to change the value of "iWantToDownload" from "false" to true , then, a new window will be opened to trigger the download of CSV file</div>
}
```
## Note:
> This component triggers the download directly once it is mounted, So , be careful to choose the suitable time to mount it.
> We avoid to make live examples for `CSVDownload` component, since mounting
> this component triggers the download directly.
> Please, check the next component since you can test it directly.

View file

@ -1,4 +1,3 @@
Basic example
```

View file

@ -1,34 +0,0 @@
import React from 'react';
class Table extends React.Component {
state= {};
renderHeaders() {
return (<thead><tr>
{this.props.headers.map((header, i) => <th key={"th"+i}>{header}</th>)}
</tr></thead>);
}
renderRow(row, key) {
return (<tr key={'tbody-tr'+key}>
{row.map((cell, i) => <td key={'td-'+key+'-'+i}>{cell}</td>)}
</tr>);
}
renderData() {
return (
<tbody>
{this.props.data.map((row, k) => this.renderRow(row, k) )}
</tbody>
);
}
render(){
return (
<table >
{this.renderHeaders()}
{this.renderData()}
</table>
);
}
}
export default Table;

View file

@ -1,53 +1,30 @@
import React from 'react';
import {CSVLink, CSVDownload} from 'react-csv';
import Table from './Table.jsx';
const csvHeaders = [
"Company","جهة الإتصال ","王玉普"
]
const csvData =[
['Alfreds Futterkiste' ,'Maria Anders', 'Germany'] ,
['Rathath IT', 'Abdennour TM' , 'تونس'] ,
['Sinopec', '王玉普' , '中国'],
['Auto1', 'Petter' , 'Germany'] ,
['Estifeda', 'Yousri K' , 'تونس'] ,
['Nine 10ᵗʰ', 'Amjed Idris' , 'المملكة العربية السعودية '] ,
['Tamkeen', 'Mohamed Alshibi' , 'المملكة العربية السعودية'] ,
['Packet Publishing', 'David Become' , 'UK'] ,
['Software hourse', 'Soro' , 'Poland']
['firstname', 'lastname', 'email'] ,
['Ahmed', 'Tomi' , 'ah@smthing.co.com'] ,
['Raed', 'Labes' , 'rl@smthing.co.com'] ,
['Yezzi','Min l3b', 'ymin@cocococo.com']
];
class App extends React.Component {
state= {};
getFileName() {
if (!this.state.filename) return undefined;
if (!this.state.filename.endsWith('.csv')) return this.state.filename + '.csv';
return this.state.filename;
}
render() {
return (
<div style={{padding: 10}}>
<h3><code>react-csv/sample-site/src/app.jsx</code></h3>
<hr />
<div>
<div ><h1>Pretty Example "React-csv"</h1></div>
<div>
<Table headers={csvHeaders} data={csvData} />
</div>
<div className="row">
<div className="large-6 columns"></div>
<div className="large-4 columns">
<input
onKeyUp={(e) => this.setState({filename: e.target.value})}
type="text" placeholder="File name"/>
</div>
<div className="large-2 columns">
<CSVLink
headers={csvHeaders}
data={csvData}
filename={this.getFileName()}
className="btn">Export to CSV </CSVLink>
</div>
</div>
Download CSV <CSVLink data={csvData}> here </CSVLink>.
</div>
<hr />
<div>
Download CSV with <code>;</code> as separator : <CSVLink data={csvData} separator=";"> here </CSVLink>.
</div>
</div>
);
}

File diff suppressed because one or more lines are too long

View file

@ -13,12 +13,13 @@ export const jsonsHeaders = ((array) => Array.from(
export const jsons2arrays = (jsons, headers) => {
headers = headers || jsonsHeaders(jsons);
const data = jsons.map((object) => headers.map((header) => (header in object) ? object[header] : ''));
return [headers, ...data];
return [headers, ...jsons.map((object) =>
headers.map((header) =>
object[header] ? object[header] : ''))]
};
export const joiner = ((data,separator = ',') =>
data.map((row, index) => row.map((element) => "\"" + element + "\"").join(separator)).join(`\n`)
data.map((row, index) => row.join(separator)).join(`\n`)
);
export const arrays2csv = ((data, headers, separator) =>
@ -41,6 +42,6 @@ export const toCSV = (data, headers, separator) => {
};
export const buildURI = ((data, headers, separator) => encodeURI(
`data:text/csv;charset=utf-8,\uFEFF,${toCSV(data, headers, separator)}`
`data:text/csv;charset=utf-8,${toCSV(data, headers, separator)}`
)
);

View file

@ -100,7 +100,7 @@ describe(`core::jsons2arrays`, () => {
sport: '97'
}, {
maths: '77',
sport: 0
sport: '99'
}]
});
it(`converts an Array of literal objects to Array of arrays`, () => {
@ -109,7 +109,7 @@ describe(`core::jsons2arrays`, () => {
['maths', 'sport'],
['90', ''],
['', '97'],
['77', 0]
['77', '99']
];
expect(actual).toEqual(expected);
});
@ -117,7 +117,7 @@ describe(`core::jsons2arrays`, () => {
it(`converts to Array of arrays following the order of headers`, () => {
const actual = jsons2arrays(fixtures, ['sport', 'maths']);
const expected = [
['maths', 'sport'].reverse(), ['90', ''].reverse(), ['', '97'].reverse(), ['77', 0].reverse()
['maths', 'sport'].reverse(), ['90', ''].reverse(), ['', '97'].reverse(), ['77', '99'].reverse()
];
expect(actual).toEqual(expected);
});
@ -127,7 +127,7 @@ describe(`core::jsons2arrays`, () => {
const expected = [
headers, ['90', '', '', ''],
['', '97', '', ''],
['77', 0, '', '']
['77', '99', '', '']
];
expect(actual).toEqual(expected);
});
@ -146,13 +146,13 @@ describe(`core::arrays2csv`, () => {
it(`converts Array of arrays to string in CSV format`, () => {
const actual = arrays2csv(fixtures);
expect(actual).toBeA('string');
expect(actual.split(`\n`).join(`|`)).toEqual(`"a","b"|"c","d"`);
expect(actual.split(`\n`).join(`|`)).toEqual(`a,b|c,d`);
});
it(`renders CSV headers whenever it was given `, () => {
const headers = [`X`, `Y`];
const firstLineOfCSV = arrays2csv(fixtures, headers).split(`\n`)[0];
expect(firstLineOfCSV).toEqual(`"X","Y"`);
expect(firstLineOfCSV).toEqual(headers.join(`,`));
});
});
@ -173,7 +173,7 @@ describe(`core::jsons2csv`, () => {
const actual = jsons2csv(fixtures);
const expectedHeaders = ['X', 'Y'];
const expected = `"X","Y"|"88","97"|"77","99"`;
const expected = `${expectedHeaders.join(`,`)}|88,97|77,99`;
expect(actual).toBeA('string');
expect(actual.split(`\n`).join(`|`)).toEqual(expected);
});
@ -181,8 +181,8 @@ describe(`core::jsons2csv`, () => {
let fixtures =[{X:'12', Y:'bb'}, {Y:'ee', X:'55'}]
const headers = ['Y', 'X', 'Z'];
const actual = jsons2csv(fixtures, headers);
expect(actual.startsWith(`"Y","X","Z"`)).toBeTruthy();
expect(actual.endsWith(`"ee","55",""`)).toBeTruthy();
expect(actual.startsWith(headers.join(`,`))).toBeTruthy();
expect(actual.endsWith(`ee,55,`)).toBeTruthy();
});
@ -199,7 +199,7 @@ describe(`core::string2csv`, () =>{
it(`prepends headers at the top of input`, () => {
const headers =[`X`, `Y`];
expect(string2csv(fixtures, headers)).toEqual(`X,Y\n${fixtures}`);
expect(string2csv(fixtures, headers)).toEqual(`${headers.join(`,`)}\n${fixtures}`);
});
});
@ -241,7 +241,7 @@ describe(`core::buildURI`, () =>{
});
it(`generates CSV string according to "separator"`, () => {
const prefixCsvURI= `data:text/csv;charset=utf-8,\uFEFF,`;
const prefixCsvURI= `data:text/csv;charset=utf-8,`;
const expectedSepartorCount = fixtures.arrays.map(row => row.length -1).reduce((total, next) =>total + next, 0);
let separator = ';';
let fullURI = buildURI(fixtures.arrays,null , separator);
@ -250,10 +250,10 @@ describe(`core::buildURI`, () =>{
fullURI.slice(prefixCsvURI.length).match(/;/g).length
).toEqual(expectedSepartorCount);
separator = ':'; // any separator
separator = ',';
fullURI = buildURI(fixtures.arrays,null , separator);
expect(
fullURI.slice(prefixCsvURI.length).match(/:/g).length
fullURI.slice(prefixCsvURI.length).match(/,/g).length
).toEqual(expectedSepartorCount);
});