React :: Tab

Renders a tabbed menu and view component.

Define a TabItem component, pass it to the Tab and remove unnecessary nodes expect for TabItem by identifying the function’s name in props.children. Use the React.useState() hook to initialize the value of the bindIndex state variable to props.defaultIndex. Use Array.prototype.map on the collected nodes to render the tab-menu and tab-view. Define changeTab, which will be executed when clicking a <button> from the tab-menuchangeTab executes the passed callback, onTabClick and updates bindIndex, which in turn causes a re-render, evaluating the style and className of the tab-view items and tab-menu buttons according to their index.

.tab-menu > button {
  cursor: pointer;
  padding: 8px 16px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
}
.tab-menu > button.focus {
  border-bottom: 2px solid #007BEF;
}
.tab-menu > button:hover {
  border-bottom: 2px solid #007BEF;
}
function TabItem(props) {
  return <div {...props} />;
}

function Tabs(props) {
  const [bindIndex, setBindIndex] = React.useState(props.defaultIndex);
  const changeTab = newIndex => {
    if (typeof props.onTabClick === "function") props.onTabClick(newIndex);
    setBindIndex(newIndex);
  };
  const items = props.children.filter(item => item.type.name === "TabItem");

  return (
    <div className="wrapper">
      <div className="tab-menu">
        {items.map(({ props: { index, label } }) => (
          <button
            onClick={() => changeTab(index)}
            className={bindIndex === index ? "focus" : ""}
          >
            {label}
          </button>
        ))}
      </div>
      <div className="tab-view">
        {items.map(({ props }) => (
          <div
            {...props}
            className="tab-view_item"
            key={props.index}
            style={{ display: bindIndex === props.index ? "block" : "none" }}
          />
        ))}
      </div>
    </div>
  );
}
ReactDOM.render(
  <Tabs defaultIndex="1" onTabClick={console.log}>
    <TabItem label="A" index="1">
      Lorem ipsum
    </TabItem>
    <TabItem label="B" index="2">
      Dolor sit amet
    </TabItem>
  </Tabs>,
  document.getElementById("root")
);

Leave a Reply

Your email address will not be published. Required fields are marked *

*