Last active
January 5, 2018 10:21
-
-
Save jasonphillips/d475fdcc25557065fadc26f38fa78c10 to your computer and use it in GitHub Desktop.
React table elements with automatic pivoting to list-style view for mobile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
/* context helpers from: | |
* https://gist.github.com/ryanflorence/1e1290571337ebcea1c5a748e8f5b37d | |
*/ | |
import provideContext from './provideContext'; | |
import withContext from './withContext'; | |
const contextShape = React.PropTypes.shape({ | |
headers: React.PropTypes.object | |
}); | |
const TableContext = provideContext('responsiveTable', contextShape); | |
const withTableContext = withContext('responsiveTable', contextShape); | |
export class Table extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { headers: {} } | |
} | |
render() { | |
const {headers} = this.state; | |
const classes = (this.props.className || '') + ' responsiveTable'; | |
return ( | |
<TableContext headers={headers}> | |
<table {...this.props} className={classes}/> | |
</TableContext> | |
); | |
} | |
} | |
export const Thead = (props) => ( | |
<thead {...props}> | |
{React.cloneElement(props.children, {inHeader: true})} | |
</thead> | |
); | |
class TrInner extends React.Component { | |
constructor(props) { | |
super(props); | |
const {headers} = props.responsiveTable; | |
if (headers && props.inHeader) { | |
props.children.map((child, i) => { | |
headers[i] = child.props.children; | |
}); | |
} | |
} | |
render() { | |
const {children} = this.props; | |
return ( | |
<tr {...this.props}> | |
{children && React.Children.map(children, (child, i) => | |
React.cloneElement(child, {key: i, columnKey: i}) | |
)} | |
</tr> | |
); | |
} | |
} | |
export const Tr = withTableContext(TrInner); | |
export const Th = (props) => <th {...props}/>; | |
export const Tbody = (props) => <tbody {...props}/>; | |
class TdInner extends React.Component { | |
render() { | |
if (this.props.colSpan) return <td {...this.props}/>; | |
const {responsiveTable: {headers}, children, columnKey} = this.props; | |
return ( | |
<td className="pivoted"> | |
<div className="tdBefore">{headers[columnKey]}</div> | |
{(children!==undefined) ? children : <div> </div>} | |
</td> | |
); | |
} | |
} | |
export const Td = withTableContext(TdInner); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* inspired by: https://css-tricks.com/responsive-data-tables/ */ | |
.responsiveTable { | |
td .tdBefore { | |
display: none; | |
} | |
/* use your our own breakpoint, ideally */ | |
@media only screen and (max-width: 768px) { | |
/* Force table elements to not behave like tables anymore */ | |
table, thead, tbody, th, td, tr { | |
display: block; | |
} | |
/* Hide table headers (but not display: none;, for accessibility) */ | |
thead tr { | |
position: absolute; | |
top: -9999px; | |
left: -9999px; | |
border-bottom: 2px solid #333; | |
} | |
tbody tr { | |
border: 1px solid #eee; | |
} | |
td.pivoted { | |
/* Behave like a "row" */ | |
border: none !important; | |
border-bottom: 1px solid #eee; | |
position: relative; | |
padding-left: 50% !important; | |
text-align: left !important; | |
} | |
td .tdBefore { | |
/* Now like a table header */ | |
position: absolute; | |
display: block; | |
/* Top/left values mimic padding */ | |
left: 1rem; | |
width: 45%; | |
padding-right: 10px; | |
white-space: nowrap; | |
text-align: left !important; | |
font-weight: 600; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* excerpted usage example */ | |
import React from 'react'; | |
import {Table, Thead, Tbody, Tr, Th, Td} from './responsiveTable.js'; | |
export const myComponent = (props) => ( | |
<Table> | |
<Thead> | |
<Tr> | |
<Th>Alpha</Th> | |
<Th>Beta</Th> | |
<Th>Omega</Th> | |
</Tr> | |
</Thead> | |
<Tbody> | |
<Tr> | |
<Td>Lorem</Td> | |
<Td>299310</Td> | |
<Td>1.1388</Td> | |
</Tr> | |
<Tr> | |
<Td>Ipsum</Td> | |
<Td>262424</Td> | |
<Td>1.888</Td> | |
</Tr> | |
<Tr> | |
<Td>Dolor</Td> | |
<Td>131325</Td> | |
<Td>1.633</Td> | |
</Tr> | |
<Tr> | |
<Td>Amet</Td> | |
<Td>9000</Td> | |
<Td>1.1388</Td> | |
</Tr> | |
</Tbody> | |
</Table> | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment