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/ cdn/
coverage/ coverage/
docs/ docs/
sample-site/ docs-site/
server.js server.js
webpack.sample.config.js webpack.sample.config.js
styleguide.config.js styleguide.config.js

View file

@ -29,8 +29,6 @@ const csvData =[
<CSVDownload data={csvData} target="_blank" /> <CSVDownload data={csvData} target="_blank" />
``` ```
And many examples are [here 👈🏼](http://elegance.abdennoor.com/react-csv)
# Install # Install
``` ```
@ -195,10 +193,3 @@ For non-node developers, they have to use CDN version :
- `npm docgen` generates documentation in HTML output. - `npm docgen` generates documentation in HTML output.
- `npm cdn` generate a bundle to be used as CDN - `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 = { var defaultProps = {
target: '_blank' target: '_blank'
}; };
var CSVDownload = (_temp = _class = function (_React$Component) { var CSVDownload = (_temp = _class = function (_React$Component) {
_inherits(CSVDownload, _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) { var jsons2arrays = exports.jsons2arrays = function jsons2arrays(jsons, headers) {
headers = headers || jsonsHeaders(jsons); headers = headers || jsonsHeaders(jsons);
var data = jsons.map(function (object) { return [headers].concat(_toConsumableArray(jsons.map(function (object) {
return headers.map(function (header) { 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 joiner = exports.joiner = function joiner(data) {
var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ','; var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ',';
return data.map(function (row, index) { return data.map(function (row, index) {
return row.map(function (element) { return row.join(separator);
return "\"" + element + "\"";
}).join(separator);
}).join('\n'); }).join('\n');
}; };
@ -220,7 +216,7 @@ var toCSV = exports.toCSV = function toCSV(data, headers, separator) {
}; };
var buildURI = exports.buildURI = function buildURI(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){ },{}],5:[function(require,module,exports){
'use strict'; '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 standardReleaser = function (instance) {
var Klass = this; 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; !(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, oneArgumentPooler: oneArgumentPooler,
twoArgumentPooler: twoArgumentPooler, twoArgumentPooler: twoArgumentPooler,
threeArgumentPooler: threeArgumentPooler, threeArgumentPooler: threeArgumentPooler,
fourArgumentPooler: fourArgumentPooler, fourArgumentPooler: fourArgumentPooler
fiveArgumentPooler: fiveArgumentPooler
}; };
module.exports = PooledClass; module.exports = PooledClass;
@ -3106,7 +3090,14 @@ var ReactElementValidator = {
// We warn in this case but don't throw. We expect the element creation to // We warn in this case but don't throw. We expect the element creation to
// succeed and there will likely be errors in render. // succeed and there will likely be errors in render.
if (!validType) { 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); var element = ReactElement.createElement.apply(this, arguments);
@ -3802,7 +3793,7 @@ module.exports = ReactPureComponent;
'use strict'; 'use strict';
module.exports = '15.4.1'; module.exports = '15.4.2';
},{}],31:[function(require,module,exports){ },{}],31:[function(require,module,exports){
(function (process){ (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> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>React CSV pattern library</title> <title>React CSV pattern library</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
</head> </head>
<body> <body>
<div id="app"></div> <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> <script type="text/javascript" src="forkme.js"></script>
</body> </body>

View file

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

View file

@ -8,24 +8,8 @@ const data = [
]; ];
<CSVDownload data={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: ## 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 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 React from 'react';
import {CSVLink, CSVDownload} from 'react-csv'; import {CSVLink, CSVDownload} from 'react-csv';
import Table from './Table.jsx';
const csvHeaders = [
"Company","جهة الإتصال ","王玉普"
]
const csvData =[ const csvData =[
['Alfreds Futterkiste' ,'Maria Anders', 'Germany'] , ['firstname', 'lastname', 'email'] ,
['Rathath IT', 'Abdennour TM' , 'تونس'] , ['Ahmed', 'Tomi' , 'ah@smthing.co.com'] ,
['Sinopec', '王玉普' , '中国'], ['Raed', 'Labes' , 'rl@smthing.co.com'] ,
['Auto1', 'Petter' , 'Germany'] , ['Yezzi','Min l3b', 'ymin@cocococo.com']
['Estifeda', 'Yousri K' , 'تونس'] ,
['Nine 10ᵗʰ', 'Amjed Idris' , 'المملكة العربية السعودية '] ,
['Tamkeen', 'Mohamed Alshibi' , 'المملكة العربية السعودية'] ,
['Packet Publishing', 'David Become' , 'UK'] ,
['Software hourse', 'Soro' , 'Poland']
]; ];
class App extends React.Component { 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() { render() {
return ( return (
<div> <div style={{padding: 10}}>
<div ><h1>Pretty Example "React-csv"</h1></div> <h3><code>react-csv/sample-site/src/app.jsx</code></h3>
<div> <hr />
<Table headers={csvHeaders} data={csvData} /> <div>
</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> </div>
); );
} }

File diff suppressed because one or more lines are too long

View file

@ -12,13 +12,14 @@ export const jsonsHeaders = ((array) => Array.from(
)); ));
export const jsons2arrays = (jsons, headers) => { export const jsons2arrays = (jsons, headers) => {
headers = headers || jsonsHeaders(jsons); headers = headers || jsonsHeaders(jsons);
const data = jsons.map((object) => headers.map((header) => (header in object) ? object[header] : '')); return [headers, ...jsons.map((object) =>
return [headers, ...data]; headers.map((header) =>
object[header] ? object[header] : ''))]
}; };
export const joiner = ((data,separator = ',') => 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) => export const arrays2csv = ((data, headers, separator) =>
@ -41,6 +42,6 @@ export const toCSV = (data, headers, separator) => {
}; };
export const buildURI = ((data, headers, separator) => encodeURI( 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' sport: '97'
}, { }, {
maths: '77', maths: '77',
sport: 0 sport: '99'
}] }]
}); });
it(`converts an Array of literal objects to Array of arrays`, () => { it(`converts an Array of literal objects to Array of arrays`, () => {
@ -109,7 +109,7 @@ describe(`core::jsons2arrays`, () => {
['maths', 'sport'], ['maths', 'sport'],
['90', ''], ['90', ''],
['', '97'], ['', '97'],
['77', 0] ['77', '99']
]; ];
expect(actual).toEqual(expected); expect(actual).toEqual(expected);
}); });
@ -117,7 +117,7 @@ describe(`core::jsons2arrays`, () => {
it(`converts to Array of arrays following the order of headers`, () => { it(`converts to Array of arrays following the order of headers`, () => {
const actual = jsons2arrays(fixtures, ['sport', 'maths']); const actual = jsons2arrays(fixtures, ['sport', 'maths']);
const expected = [ 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); expect(actual).toEqual(expected);
}); });
@ -127,7 +127,7 @@ describe(`core::jsons2arrays`, () => {
const expected = [ const expected = [
headers, ['90', '', '', ''], headers, ['90', '', '', ''],
['', '97', '', ''], ['', '97', '', ''],
['77', 0, '', ''] ['77', '99', '', '']
]; ];
expect(actual).toEqual(expected); expect(actual).toEqual(expected);
}); });
@ -146,13 +146,13 @@ describe(`core::arrays2csv`, () => {
it(`converts Array of arrays to string in CSV format`, () => { it(`converts Array of arrays to string in CSV format`, () => {
const actual = arrays2csv(fixtures); const actual = arrays2csv(fixtures);
expect(actual).toBeA('string'); 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 `, () => { it(`renders CSV headers whenever it was given `, () => {
const headers = [`X`, `Y`]; const headers = [`X`, `Y`];
const firstLineOfCSV = arrays2csv(fixtures, headers).split(`\n`)[0]; 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 actual = jsons2csv(fixtures);
const expectedHeaders = ['X', 'Y']; 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).toBeA('string');
expect(actual.split(`\n`).join(`|`)).toEqual(expected); expect(actual.split(`\n`).join(`|`)).toEqual(expected);
}); });
@ -181,8 +181,8 @@ describe(`core::jsons2csv`, () => {
let fixtures =[{X:'12', Y:'bb'}, {Y:'ee', X:'55'}] let fixtures =[{X:'12', Y:'bb'}, {Y:'ee', X:'55'}]
const headers = ['Y', 'X', 'Z']; const headers = ['Y', 'X', 'Z'];
const actual = jsons2csv(fixtures, headers); const actual = jsons2csv(fixtures, headers);
expect(actual.startsWith(`"Y","X","Z"`)).toBeTruthy(); expect(actual.startsWith(headers.join(`,`))).toBeTruthy();
expect(actual.endsWith(`"ee","55",""`)).toBeTruthy(); expect(actual.endsWith(`ee,55,`)).toBeTruthy();
}); });
@ -199,7 +199,7 @@ describe(`core::string2csv`, () =>{
it(`prepends headers at the top of input`, () => { it(`prepends headers at the top of input`, () => {
const headers =[`X`, `Y`]; const headers =[`X`, `Y`];
expect(string2csv(fixtures, headers)).toEqual(`X,Y\n${fixtures}`); expect(string2csv(fixtures, headers)).toEqual(`${headers.join(`,`)}\n${fixtures}`);
}); });
}); });
@ -241,19 +241,19 @@ describe(`core::buildURI`, () =>{
}); });
it(`generates CSV string according to "separator"`, () => { 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); const expectedSepartorCount = fixtures.arrays.map(row => row.length -1).reduce((total, next) =>total + next, 0);
let separator = ';'; let separator = ';';
let fullURI = buildURI(fixtures.arrays, null , separator); let fullURI = buildURI(fixtures.arrays,null , separator);
expect( expect(
fullURI.slice(prefixCsvURI.length).match(/;/g).length fullURI.slice(prefixCsvURI.length).match(/;/g).length
).toEqual(expectedSepartorCount); ).toEqual(expectedSepartorCount);
separator = ':'; // any separator separator = ',';
fullURI = buildURI(fixtures.arrays, null , separator); fullURI = buildURI(fixtures.arrays,null , separator);
expect( expect(
fullURI.slice(prefixCsvURI.length).match(/:/g).length fullURI.slice(prefixCsvURI.length).match(/,/g).length
).toEqual(expectedSepartorCount); ).toEqual(expectedSepartorCount);
}); });