Shameem

June 8, 2023

A simple tab component using react.js tailwindcss react-transition-group

Tab nav component

import React from 'react';
const TabNavItem = ({ id, children, activeTab, setActiveTab, className, ...props }) => {
  const handleClick = () => {
    setActiveTab(id);
  };
  let classes = `text-sm leading-4 min-w-[128px] border border-[#241C32] hover:text-white p-2 transition-colors duration-200 capitalize noSelect`;
  if (activeTab === id) {
    classes += ` text-white bg-[#241C32]`;
  } else {
    classes += ` text-secondary-text bg-primary-bg`;
  }
  if (className) {
    classes += ` ${className}`;
  }
  return (
    <button onClick={handleClick} className={classes}>{children}</button>
  );
};
export default TabNavItem;

Tab content component

import { useRef } from 'react';
import { CSSTransition } from 'react-transition-group';

const TabContent = ({ id, activeTab, children }) => {
  const tabContent = useRef(null);
  return (
    <CSSTransition timeout={400} unmountOnExit classNames="tabs" nodeRef={tabContent} in={activeTab === id} appear={activeTab === id}>
      <div className={`transition-opacity duration-[.4s] hidden `} ref={tabContent}>
        {children}
      </div>
    </CSSTransition>
  );
};

export default TabContent;

Tab transition styles

.tabs-appear {
  opacity: 0;
  display: block;
}
.tabs-appear-active {
  opacity: 1;
  transition: opacity 400ms cubic-bezier(0.31, 0.56, 0.61, 0.95);
}
.tabs-appear-done {
  display: block;
}
.tabs-enter {
  opacity: 0;
  display: block;
}
.tabs-enter-active {
  opacity: 1;
  transition: opacity 400ms cubic-bezier(0.31, 0.56, 0.61, 0.95);
}
.tabs-enter-done {
  display: block;
}
.tabs-exit {
  opacity: 1;
}
.tabs-exit-active {
  opacity: 0;
  transition: opacity 400ms cubic-bezier(0.31, 0.56, 0.61, 0.95);
}
.tabs-exit-done {
  display: none;
}

Top comments
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments