1- import React , { Component } from "react" ;
1+ import React , {
2+ Component ,
3+ createContext
4+ } from "react" ;
25import FaAutomobile from "react-icons/lib/fa/automobile" ;
36import FaBed from "react-icons/lib/fa/bed" ;
47import FaPlane from "react-icons/lib/fa/plane" ;
58import FaSpaceShuttle from "react-icons/lib/fa/space-shuttle" ;
69import * as text from "./lib/text" ;
710
11+ let TabsContext = createContext ( ) ;
12+
813class Tabs extends Component {
914 state = {
10- activeIndex : 0
11- } ;
12-
13- selectTabIndex = activeIndex => {
14- this . setState ( { activeIndex } ) ;
15+ activeIndex : 0 ,
16+ selectTabIndex : activeIndex => {
17+ this . setState ( { activeIndex } ) ;
18+ }
1519 } ;
1620
1721 render ( ) {
18- const children = React . Children . map ( this . props . children , child => {
19- return React . cloneElement ( child , {
20- activeIndex : this . state . activeIndex ,
21- onSelectTab : this . selectTabIndex
22- } ) ;
23- } ) ;
24- return < div className = "Tabs" > { children } </ div > ;
25- }
26- }
27-
28- class TabList extends Component {
29- render ( ) {
30- const { activeIndex } = this . props ;
31- const children = React . Children . map ( this . props . children , ( child , index ) => {
32- return React . cloneElement ( child , {
33- isActive : index === activeIndex ,
34- onSelect : ( ) => this . props . onSelectTab ( index )
35- } ) ;
36- } ) ;
37- return < div className = "tabs" > { children } </ div > ;
38- }
39- }
40-
41- class Tab extends Component {
42- render ( ) {
43- const { isActive, isDisabled, onSelect } = this . props ;
4422 return (
45- < div
46- className = {
47- isDisabled ? "tab disabled" : isActive ? "tab active" : "tab"
48- }
49- onClick = { isDisabled ? null : onSelect }
50- >
51- { this . props . children }
52- </ div >
23+ < TabsContext . Provider value = { this . state } >
24+ < div className = "Tabs" >
25+ { this . props . children }
26+ </ div >
27+ </ TabsContext . Provider >
5328 ) ;
5429 }
5530}
5631
57- class TabPanels extends Component {
58- render ( ) {
59- const { activeIndex, children } = this . props ;
60- return < div className = "panels" > { children [ activeIndex ] } </ div > ;
61- }
62- }
32+ let TabList = props => {
33+ return (
34+ < TabsContext . Consumer >
35+ { context => {
36+ let children = React . Children . map (
37+ props . children ,
38+ ( child , index ) => {
39+ return React . cloneElement ( child , {
40+ isActive : index === context . activeIndex ,
41+ onActivate : ( ) =>
42+ context . selectTabIndex ( index )
43+ } ) ;
44+ }
45+ ) ;
46+ return < div className = "tabs" > { children } </ div > ;
47+ } }
48+ </ TabsContext . Consumer >
49+ ) ;
50+ } ;
6351
64- class TabPanel extends Component {
65- render ( ) {
66- return this . props . children ;
67- }
68- }
52+ let Tab = props => {
53+ const isDisabled = props . isDisabled ;
54+ const isActive = props . isActive ;
55+ return (
56+ < div
57+ className = {
58+ isDisabled
59+ ? "tab disabled"
60+ : isActive ? "tab active" : "tab"
61+ }
62+ onClick = {
63+ isDisabled ? undefined : props . onActivate
64+ }
65+ >
66+ { props . children }
67+ </ div >
68+ ) ;
69+ } ;
6970
70- class DataTabs extends Component {
71- render ( ) {
72- const { data } = this . props ;
73- return (
74- < Tabs >
75- < TabList >
76- { data . map ( ( tab , index ) => < Tab key = { index } > { tab . label } </ Tab > ) }
77- </ TabList >
78- < TabPanels >
79- { data . map ( ( tab , index ) => (
80- < TabPanel key = { index } > { tab . content } </ TabPanel >
81- ) ) }
82- </ TabPanels >
83- </ Tabs >
84- ) ;
85- }
86- }
71+ let TabPanels = props => {
72+ return (
73+ < TabsContext . Consumer >
74+ { context => (
75+ < div className = "panels" >
76+ { props . children [ context . activeIndex ] }
77+ </ div >
78+ ) }
79+ </ TabsContext . Consumer >
80+ ) ;
81+ } ;
82+
83+ let TabPanel = props => props . children ;
8784
8885class App extends Component {
8986 render ( ) {
@@ -106,7 +103,30 @@ class App extends Component {
106103 </ TabList >
107104 < TabPanels >
108105 < TabPanel > { text . cars } </ TabPanel >
109- < TabPanel > { text . hotels } </ TabPanel >
106+ < TabPanel >
107+ < Tabs >
108+ < TabList >
109+ < Tab >
110+ < FaAutomobile />
111+ </ Tab >
112+ < Tab isDisabled >
113+ < FaBed />
114+ </ Tab >
115+ < Tab >
116+ < FaPlane />
117+ </ Tab >
118+ < Tab >
119+ < FaSpaceShuttle />
120+ </ Tab >
121+ </ TabList >
122+ < TabPanels >
123+ < TabPanel > { text . cars } </ TabPanel >
124+ < TabPanel > { text . hotels } </ TabPanel >
125+ < TabPanel > { text . flights } </ TabPanel >
126+ < TabPanel > { text . space } </ TabPanel >
127+ </ TabPanels >
128+ </ Tabs >
129+ </ TabPanel >
110130 < TabPanel > { text . flights } </ TabPanel >
111131 < TabPanel > { text . space } </ TabPanel >
112132 </ TabPanels >
0 commit comments