Skip to content

Instantly share code, notes, and snippets.

@rotexhawk
Created April 28, 2018 21:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rotexhawk/5c74b8fea5dc1725c70006b6de47da64 to your computer and use it in GitHub Desktop.
Save rotexhawk/5c74b8fea5dc1725c70006b6de47da64 to your computer and use it in GitHub Desktop.
import React from 'react';
import PropTypes from 'prop-types';
import { black90, gray15, gray50, gray30 } from 'components/styles/colors';
import styled from 'styled-components';
import media from 'components/styles/media';
import { margin, fontWeight } from 'components/styles/scales';
import RankingsTable from 'containers/molecules/RankingsTable';
import cheerio from 'cheerio';
const TableContainer = styled.div`
table {
width: 100%;
border-collapse: collapse;
border-top: 3px solid ${black90};
thead tr,
tbody tr {
border-bottom: 1px solid ${gray15};
}
thead tr th {
vertical-align: bottom;
}
thead tr th,
tbody tr td {
margin: 0;
padding: 1rem;
padding-left: 0;
padding-right: 0;
}
tr {
* {
font-family: Roboto, 'Helvetica Neue', Helvetica, sans-serif !important;
font-size: 1.125rem !important;
line-height: 1.5 !important;
font-weight: 700 !important;
margin: 0px !important;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
a {
color: ${black90};
text-decoration: none;
&:hover {
color: ${gray50};
}
}
td {
#name {
margin: 0 !important;
float: none !important;
}
#badge {
padding-bottom: 0 !important;
}
&:nth-of-type(n + 1) {
${media.toMedium`
text-align: center;
`};
}
&:first-of-type {
text-align: left;
}
&:last-of-type {
text-align: right;
${media.toMedium`
max-width: 80px;
`};
}
span.tied {
color: ${gray30};
margin: 0 0 0 ${margin(3)} !important;
font-weight: ${fontWeight(4)} !important;
${media.toMedium`
margin: 0 5px 0 0 !important;
`};
}
}
}
tr:first-of-type {
td {
${media.medium`
min-width: 128px;
`};
}
* {
font-size: 0.875rem !important;
line-height: 1.42 !important;
text-transform: uppercase !important;
letter-spacing: 1.25px !important;
font-family: Montserrat, 'Helvetica Neue', Helvetica, sans-serif !important;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
}
}
`;
export default class ArticleBodyRawTable extends React.Component {
constructor(props) {
super(props);
this.$ = cheerio.load(props.markup);
this.componentize(props);
}
componentize({ markup }) {
if (this.$(markup).is('table')) {
try {
this.setHeadings(markup);
this.setRows(markup);
this.setAlignments(markup);
this.table = (
<RankingsTable
headings={this.getHeadings()}
rows={this.getRows()}
alignments={this.getAlignments()}
/>
);
} catch (e) {
console.log('e', e);
let tableMarkup = markup.replace(
/\(tie\)/g,
'<span class="tied">(tie)</span>'
);
this.table = (
<TableContainer
dangerouslySetInnerHTML={{ __html: tableMarkup }}
/>
);
}
}
}
setHeadings(markup) {
const tr = this.$(markup)
.find('tr')
.first();
if (tr.length > 0 && this.$(tr).children().length > 0) {
let columns = Array.from(this.$(tr).children());
this.headings = columns.map(col => {
return this.$(col).text();
});
} else {
throw `Couldn't find table headers.`;
}
}
getHeadings() {
return this.headings;
}
setRows(markup) {
let headings = this.getHeadings();
let firstRowIsRank = headings[0].toLowerCase() === 'rank';
let rows = Array.from(
this.$(markup)
.find('tr')
.slice(1)
);
this.rows = rows.map(row => {
return Array.from(this.$(row).find('td')).map((col, index) => {
if (firstRowIsRank && index % headings.length === 0) {
// first column
let text = this.$(col).text();
let num = parseInt(text.match(/\d+/)); // get num from str and parsetoInt
if (!isNaN(num)) {
return {
text: num,
subText: text.includes('tie') ? '(tie)' : '',
badge: 'color',
};
} else {
return {
text: text,
};
}
} else if (this.$(col).find('a').length) {
let link = this.$(col).find('a');
return {
text: this.$(link).text(),
url: this.$(link).attr('href'),
};
} else {
return {
text: this.$(col).text(),
};
}
});
});
}
getRows() {
return this.rows;
}
setAlignments() {
this.alignments = this.getHeadings().map(
(heading, index) =>
index === this.getHeadings().length - 1 ? 'right' : 'left'
);
}
getAlignments() {
return this.alignments;
}
render() {
return this.props.markup;
}
}
ArticleBodyRawTable.propTypes = {
markup: PropTypes.string,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment