Last active
August 19, 2018 21:21
-
-
Save ajitid/d16b6fcaf7a1dc14cb04f63215904ca1 to your computer and use it in GitHub Desktop.
React compound component example (start point: https://github.com/ryanflorence/advanced-react-workshop/blob/master/02/02-lecture/src/AppStart.js)
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 "./index.css" | |
import React, { Component } from "react" | |
import FaAutomobile from "react-icons/lib/fa/automobile" | |
import FaBed from "react-icons/lib/fa/bed" | |
import FaPlane from "react-icons/lib/fa/plane" | |
import FaSpaceShuttle from "react-icons/lib/fa/space-shuttle" | |
import * as text from "./text" | |
const TabHead = props => { | |
const { data, activeIndex, selectTabIndex } = props | |
const tabHead = data.map((tab, index) => { | |
const isActive = activeIndex === index | |
return ( | |
<div | |
key={index} | |
className={isActive ? 'tab active' : 'tab'} | |
onClick={() => selectTabIndex(index)} | |
> | |
{tab.label} | |
</div> | |
) | |
}) | |
return ( | |
<div className="tabs"> | |
{tabHead} | |
</div> | |
); | |
} | |
const TabPanel = props => { | |
const { data, activeIndex } = props | |
return ( | |
<div className="panels"> | |
<div>{data[activeIndex].content}</div> | |
</div> | |
) | |
} | |
class Tabs extends Component { | |
state = { | |
activeIndex: 0 | |
} | |
static Head = props => <TabHead {...props} /> | |
static Panel = props => <TabPanel {...props} /> | |
selectTabIndex = (activeIndex) => { | |
this.setState({ activeIndex }); | |
} | |
render() { | |
const {data} = this.props | |
const {activeIndex} = this.state | |
const passedProps = { | |
data, | |
activeIndex, | |
selectTabIndex: this.selectTabIndex | |
} | |
const children = React.Children.map(this.props.children, child => ( | |
React.cloneElement(child, { | |
...passedProps | |
}) | |
)) | |
return ( | |
<div className="Tabs"> | |
{children} | |
</div> | |
) | |
} | |
} | |
class App extends Component { | |
render() { | |
const tabData = [ | |
{ | |
label: <FaAutomobile />, | |
content: text.cars | |
}, | |
{ | |
label: <FaBed />, | |
content: text.hotels | |
}, | |
{ | |
label: <FaPlane />, | |
content: text.flights | |
}, | |
{ | |
label: <FaSpaceShuttle />, | |
content: text.space | |
} | |
] | |
return ( | |
<div className="App"> | |
<Tabs data={tabData}> | |
<Tabs.Head /> | |
<Tabs.Panel /> | |
</Tabs> | |
</div> | |
) | |
} | |
} | |
export default App |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment