🌎 🌍 🌏 initial commit
This commit is contained in:
commit
41d2cd8b9c
12 changed files with 181 additions and 0 deletions
21
src/components/CSVDownload.js
Normal file
21
src/components/CSVDownload.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from 'react';
|
||||
import {buildURI} from '../core';
|
||||
import {defaultProps, PropTypes, PropsNotForwarded} from '../metaProps';
|
||||
|
||||
class CSVDownload extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
componentDidMount(){
|
||||
window.open(buildURI(this.props.data));
|
||||
}
|
||||
|
||||
render(){
|
||||
return (null)
|
||||
}
|
||||
}
|
||||
|
||||
CSVDownload.defaultProps = defaultProps;
|
||||
CSVDownload.PropTypes = PropTypes;
|
||||
CSVDownload.PropsNotForwarded = PropsNotForwarded;
|
||||
export default CSVDownload;
|
||||
23
src/components/CSVLink.js
Normal file
23
src/components/CSVLink.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react';
|
||||
import {buildURI} from '../core';
|
||||
import {defaultProps, PropTypes, PropsNotForwarded} from '../metaProps';
|
||||
|
||||
class CSVLink extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
|
||||
render(){
|
||||
return (
|
||||
<a {...this.props} href={buildURI(this.props.data, this.props)}>
|
||||
{this.props.children}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
}
|
||||
CSVLink.defaultProps = defaultProps;
|
||||
CSVLink.PropTypes = PropTypes;
|
||||
CSVLink.PropsNotForwarded = PropsNotForwarded;
|
||||
|
||||
export default CSVLink;
|
||||
26
src/core.js
Normal file
26
src/core.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
const isJsons = (array) => array.every(row => (typeof row === 'object' && !(row instanceof Array)))
|
||||
const isArrays = (array) => array.every(row => Array.isArray(row))
|
||||
|
||||
const jsonsHeaders = (array) => Array.from(
|
||||
array.map(json => Object.keys(json))
|
||||
.reduce((a, b) => new Set([...a, ...b]), [])
|
||||
);
|
||||
const jsons2arrays = (jsons, headers) => {
|
||||
headers = headers || jsonsHeaders(jsons);
|
||||
return [headers, ...array.map((object) =>
|
||||
headers.map((header) =>
|
||||
object[header] ? object[header] : ''))]
|
||||
};
|
||||
|
||||
const joiner = (data) => data.map((row, index) => row.join(',')).join(`\n`);
|
||||
|
||||
const arrays2csv = (data, headers) => joiner(headers ? [headers, ...data] : data);
|
||||
const jsons2csv = (data, headers) => joiner(jsons2arrays(data, headers))
|
||||
const toCSV = (data, headers) => {
|
||||
if(isJsons(data)) return jsons2csv(data, headers);
|
||||
if(isArrays(data)) return jsons2csv(data, headers);
|
||||
throw new TypeError(`Data should be an array of arrays OR array of objects `);
|
||||
};
|
||||
export const buildURI = (data, headers) => encodeURI(
|
||||
`data:text/csv;charset=utf-8,${toCSV(data, headers)}`
|
||||
);
|
||||
5
src/index.js
Normal file
5
src/index.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import Download from './Download';
|
||||
import Link from './Link';
|
||||
|
||||
export const CSVDownload = Download;
|
||||
export const CSVLink = Link;
|
||||
13
src/metaProps.js
Normal file
13
src/metaProps.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import React from 'react';
|
||||
export const defaultProps = {
|
||||
|
||||
};
|
||||
|
||||
export const PropTypes = {
|
||||
data: React.PropTypes.array.isRequired,
|
||||
headers: React.PropTypes.array
|
||||
};
|
||||
|
||||
export const PropsNotForwarded = [
|
||||
`data`
|
||||
];
|
||||
Loading…
Add table
Add a link
Reference in a new issue