Compare commits
No commits in common. "master" and "react-docgen" have entirely different histories.
master
...
react-docg
23 changed files with 96 additions and 17113 deletions
|
|
@ -2,7 +2,7 @@ test/
|
|||
cdn/
|
||||
coverage/
|
||||
docs/
|
||||
sample-site/
|
||||
docs-site/
|
||||
server.js
|
||||
webpack.sample.config.js
|
||||
styleguide.config.js
|
||||
|
|
|
|||
|
|
@ -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 🍵 :)
|
||||
|
||||
[](https://www.paypal.me/AbdennourT/2)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
3
cdn/react-csv-1.0.3-RC1.min.js
vendored
3
cdn/react-csv-1.0.3-RC1.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
3
cdn/react-csv-1.0.4.min.js
vendored
3
cdn/react-csv-1.0.4.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
3
cdn/react-csv-1.0.5.min.js
vendored
3
cdn/react-csv-1.0.5.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
3
cdn/react-csv-1.0.6.min.js
vendored
3
cdn/react-csv-1.0.6.min.js
vendored
File diff suppressed because one or more lines are too long
39
cdn/react-csv-latest.js
vendored
39
cdn/react-csv-latest.js
vendored
|
|
@ -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){
|
||||
/**
|
||||
|
|
|
|||
6
cdn/react-csv-latest.min.js
vendored
6
cdn/react-csv-latest.min.js
vendored
File diff suppressed because one or more lines are too long
30
docs/build/bundle.js
vendored
Normal file
30
docs/build/bundle.js
vendored
Normal file
File diff suppressed because one or more lines are too long
30
docs/build/bundle1234.js
vendored
30
docs/build/bundle1234.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
10
package.json
10
package.json
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
Basic example
|
||||
|
||||
```
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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
|
|
@ -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)}`
|
||||
)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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,19 +241,19 @@ 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);
|
||||
let fullURI = buildURI(fixtures.arrays,null , separator);
|
||||
|
||||
expect(
|
||||
fullURI.slice(prefixCsvURI.length).match(/;/g).length
|
||||
).toEqual(expectedSepartorCount);
|
||||
|
||||
separator = ':'; // any separator
|
||||
fullURI = buildURI(fixtures.arrays, null , 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);
|
||||
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue