<div id="root"></div>
.tab-control-wrap {
  display: flex;
  flex: 0 0 auto;
  .tab-control {
    width: 100%;
    background: transparent;
    padding: 8px;
    font-size: 20px;
    border: none;
    &[aria-selected=true]{
      background: #333;
      color: #fff;
    }
  }
}

.tab-panel-wrap {
  background: #eee;
  .tab-panel {
    padding: 50px;
    font-size: 50px;
    text-align: center;
  }
}
View Compiled
import * as React from "https://cdn.skypack.dev/react@17.0.1";
import * as ReactDOM from "https://cdn.skypack.dev/react-dom@17.0.1";

const tabControlArray = [
  'Tab Control1',
  'Tab Control2',
  'Tab Control3'
]

const TabWrap = ({id, active, children}) => {
  const {cloneElement} = React;
  const tabChildren = children.map( (el, index) => {
    return cloneElement(el, {
      key: `tab-default0${index+1}`,
      id,
      active
    })
  })
   
  return (
    <div className="tab-wrap">
      {tabChildren}
    </div>
  )
}

const TabControlWrap = ({id, active, onClick, data}) => {
 
  return (
    <div className="tab-control-wrap">
      {
        data.map( (controlEl, index) => {
          return (
            <TabControl 
              key={`tab-control0${index}`} 
              id={`${id}-control-0${index+1}`}
              ariaControls={`${id}-panel-0${index+1}`}
              activeStatus={active === index} 
              tabControl={controlEl}
              onClick={() => onClick(index)}/>
          ) 
        })
      }
    </div>
  )
}

const TabControl = ({id, ariaControls, activeStatus, tabControl, onClick}) => {
  return (
    <button 
      type="button" 
      id={id} 
      role="tab"
      aria-selected={activeStatus}
      aria-controls={ariaControls}
      className="tab-control" 
      onClick={onClick}>
      {tabControl}
    </button>
  )
}

const TabPanelWrap = ({id, active, children}) => {
  const {cloneElement} = React;
  const panel = children.map( (el, index) => {
   
    return cloneElement(el, {
      key: index,
      id: `${id}-panel-0${index+1}`,
      label: `${id}-control-0${index+1}`,
      activeStatus: active === index,
      })
  })
  return (
    <div className="tab-panel-wrap">
      {panel}
    </div>
  )
}

const TabPanel = ({id, label, activeStatus, children}) => {
  return (
    <div className="tab-panel"
      role="tabpanel"
      id={id}
      aria-labelledby={label}
      hidden={!activeStatus}>
      {children} 
    </div>
  )
}

const App = () => {
  const {useState, useCallback} = React;
  const [activeIndex, setActiveIndex] = useState(0);
  const onClickTabControl = useCallback((changeIndex) => {
    setActiveIndex(changeIndex);
  }, [activeIndex]);
  return (
     <div>
    <TabWrap id="tab-default" active={activeIndex}>
      <TabControlWrap data={tabControlArray} onClick={onClickTabControl} />
      <TabPanelWrap>
        <TabPanel>
          tab Panel 1 content
        </TabPanel>
        <TabPanel>
          tab Panel 2 content
        </TabPanel>
        <TabPanel>
          tab Panel 3 content
        </TabPanel>
      </TabPanelWrap>
    </TabWrap>
  </div>
  )
};


ReactDOM.render(<App />, document.getElementById("root"));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.