JSFiddle - React, Tailwind, and code Playground

by Allie Yu

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Babel + JSX

// forgive my js styles
let label = {
  font: "inherit",
  padding: "5px 10px",
  display: "inline-block",
  border: "none",
  borderBottom: "solid 2px #ccc",
  marginRight: "10px",
  cursor: "pointer"
};

let activeLabel = {
  ...label,
  borderColor: "red"
};

// This only demonstrates state management and rendering
// It's missing ARIA attributes and keyboard access, but I could
// show you that if you'd like in another sandbox
class Tabs extends React.Component {
  // This thing does 3 things

  // 1. manages the state
  state = {
    activeIndex: this.props.defaultIndex || 0
  };

  // 2. renders based on that state
  render() {
    let { activeIndex } = this.state;

    // this.props.children is just data™, so we can iterate our
    // children, map them to new children, even inspect their props
    let tabs = React.Children.map(this.props.children, (child, index) => {
      // which helps us decide which one is active
      let style = activeIndex === index ? activeLabel : label;
      return (
        <button
          style={style}
          // 3. provides a way to change that state
          onClick={() => this.setState({ activeIndex: index })}
        >
          {/* you can inspect and render the prop of a child*/}
          {child.props.label}
        </button>
      );
    });
    return (
      <div>
        <div>{tabs}</div>
        {/* Children is Just Data™ (it's an array) so we can
            access the the one we want based on state
            and render it here */}
        {this.props.children[this.state.activeIndex]}
      </div>
    );
  }
}

// Tab is actually inconsequential in this implementation, don't
// actually even need to use it inside of <Tabs>, pass any ol' element
// in with a "label" prop and you're good. But I'd keep it, it's good
// for semantics and future features you might need
const Tab = ({ children }) => <div>{children}</div>;

// I would do this but not worth the conversation for this demo :P
//const Tab = ({...