Nancy Moore
Nancy Moore

Reputation: 2470

How to create vertical tab using reactjs and css

Am trying to bulid vertical tab that will function exactly like in the demo link below sample links from w3schools

here is the screenshot of what am trying to achieve as per the demo sample above demo sample screenshot

To this effect tried solution found here at but it does not give me what I want as per demo sample above Stackoverflow link

Now I have decided to go my own way in trying it out.

I have succeeded in displaying the content from an array via reactjs. when user click on each country, the content of that country gets displayed.

My Problem:

My issue is that I cannot get it to display the content in a vertical tab div as can be seen in the screenshot

screenshot

Here is the coding so far

import React, { Component, Fragment } from "react";
import { render } from "react-dom";

class Country extends React.Component {
  state = { open: false };
  toggleOpen = id => {
    alert(id);

    this.setState(prevState => ({
      open: !prevState.open
    }));
  };

  render() {
    return (
      <React.Fragment>
        <div key={this.props.data.id}>
          <button onClick={() => this.toggleOpen(this.props.data.id)}>
            {this.props.data.name}
          </button>
        </div>

        <div>
          {this.state.open && (
            <div>
              <div>
                <b>id: </b>
                {this.props.data.id}
              </div>
              <div>
                <b>Info: </b>
                {this.props.data.info}
              </div>
              <div>
                <b>Country name:</b> {this.props.data.name}
              </div>
              content for <b> {this.props.data.name}</b> will appear here..
            </div>
          )}
        </div>
      </React.Fragment>
    );
  }
}

class VerticalTab extends React.Component {
  constructor() {
    super();

    this.state = {
      data: [
        { id: "1", name: "London", info: "London is the capital city of England." },
        { id: "2", name: "Paris", info: "Paris is the capital of France." },
        { id: "3", name: "Tokyo", info: "Tokyo is the capital of Japan." }
      ]
    };
  }

  render() {
    return (
      <div>
        <div>
          {this.state.data.map(country => (
            <Country key={country.id} data={country} />
          ))}
        </div>
      </div>
    );
  }
}

Upvotes: 5

Views: 4656

Answers (2)

Abu Sayed
Abu Sayed

Reputation: 187

Codepen of React Tabs with Hooks

JS :

import React from "https://cdn.skypack.dev/[email protected]";
import ReactDOM from "https://cdn.skypack.dev/[email protected]";

function App() {
  const types = ["tab-1", "tab-2", "tab-3", "tab-4"];
  const [active, setActive] = React.useState(types[0]);

  return (
    <div className="App">
      <div className="tabs">
        <div className="tabs-nav">
          {types.map((type) => (
            <div
              className={`${active === type ? "nav-item active" : "nav-item"}`}
              id={type}
              key={type}
              onClick={() => setActive(type)}
            >
              {type}
            </div>
          ))}
        </div>
        <div className="tabs-content">
          {active === "tab-1" && <div className="tab-1"> Tab 1 content </div>}
          {active === "tab-2" && <div className="tab-2"> Tab 2 content </div>}
          {active === "tab-3" && <div className="tab-3"> Tab 3 content </div>}
          {active === "tab-4" && <div className="tab-4"> Tab 4 content </div>}
        </div>
      </div>
    </div>
  );
}

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

CSS:

@import url("https://fonts.googleapis.com/css2?family=Merienda&display=swap");

* {
  margin: 0;
  padding: 0;
}

body {
  font-family: "Merienda", cursive;
}

.tabs {
    padding: 10px;
    .tabs-nav {
      display: flex;
      align-items: center;

      .nav-item {
        color: #000000;
        cursor: pointer;
        padding: 5px 10px;
        text-transform: capitalize;
        transition: color 0.5s linear;
        -webkit-transition: color 0.5s linear;
        -o-transition: color 0.5s linear;
        -moz-transition: color 0.5s linear;
      }
      .active {
        border-bottom: 2px solid #00d0ab;
        color: #00d0ab;
        transition: color 0.5s linear;
        -webkit-transition: color 0.5s linear;
        -o-transition: color 0.5s linear;
        -moz-transition: color 0.5s linear;
      }
    }
    .tabs-content {
      margin-top: 20px;
    }
  }

Upvotes: 1

Hamed
Hamed

Reputation: 1381

Is this what you are looking for?

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
          currentTab: -1,
          data: [
            { id: "1", name: "London" ,info: "London is the capital city of England."},
            { id: "2", name: "Paris" ,info: "Paris is the capital of France." },
            { id: "3", name: "Tokyo"  ,info: "Tokyo is the capital of Japan."}
          ]
  };
  this.handleClick = this.handleClick.bind(this);
  }
  
  handleClick(currentTab) {
    this.setState({ currentTab });
  }
    
  render() {
    return (

<div>
  <h2>Vertical Tabs</h2>
  <p>Click on the buttons inside the tabbed menu:</p>
  <div className="tab">
  {this.state.data.map((button, i) => (
    <button key={button.name} className="tablinks" onClick={() => this.handleClick(i)}>{button.name}</button>
    )
    )
  }
  </div>

  <div className="tabcontent">
    {this.state.currentTab !== -1 &&
      <React.Fragment>
        <h3>{this.state.data[this.state.currentTab].name}</h3>
        <p>{this.state.data[this.state.currentTab].info}</p>
      </React.Fragment>
    }
  </div>
</div>
  )
  }
}

ReactDOM.render( < App / > ,
  document.getElementById('root')
);
* {box-sizing: border-box}
body {font-family: "Lato", sans-serif;}

/* Style the tab */
.tab {
  float: left;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
  width: 30%;
  height: 300px;
}

/* Style the buttons inside the tab */
.tab button {
  display: block;
  background-color: inherit;
  color: black;
  padding: 22px 16px;
  width: 100%;
  border: none;
  outline: none;
  text-align: left;
  cursor: pointer;
  transition: 0.3s;
  font-size: 17px;
}

/* Change background color of buttons on hover */
.tab button:hover {
  background-color: #ddd;
}

/* Create an active/current "tab button" class */
.tab button.active {
  background-color: #ccc;
}

/* Style the tab content */
.tabcontent {
  float: left;
  padding: 0px 12px;
  border: 1px solid #ccc;
  width: 70%;
  border-left: none;
  height: 300px;
}
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<div id="root" />

Upvotes: 6

Related Questions