Tabs.tsx 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. /* eslint-disable jsx-a11y/anchor-is-valid */
  2. import React, { PropsWithChildren } from 'react';
  3. import classNames from 'classnames';
  4. interface TabsProps {
  5. tabs: string[];
  6. defaultSelectedIndex?: number;
  7. onChange?(index: number): void;
  8. }
  9. const Tabs: React.FC<PropsWithChildren<TabsProps>> = ({
  10. tabs,
  11. defaultSelectedIndex = 0,
  12. onChange,
  13. children,
  14. }) => {
  15. const [selectedIndex, setSelectedIndex] =
  16. React.useState(defaultSelectedIndex);
  17. React.useEffect(() => {
  18. setSelectedIndex(defaultSelectedIndex);
  19. }, [defaultSelectedIndex]);
  20. const handleChange = (index: number) => {
  21. setSelectedIndex(index);
  22. onChange?.(index);
  23. };
  24. return (
  25. <>
  26. <div className="tabs">
  27. <ul>
  28. {tabs.map((tab, index) => (
  29. <li
  30. key={tab}
  31. className={classNames({ 'is-active': index === selectedIndex })}
  32. >
  33. <a
  34. role="button"
  35. tabIndex={index}
  36. onClick={() => handleChange(index)}
  37. onKeyDown={() => handleChange(index)}
  38. >
  39. {tab}
  40. </a>
  41. </li>
  42. ))}
  43. </ul>
  44. </div>
  45. {React.Children.toArray(children)[selectedIndex]}
  46. </>
  47. );
  48. };
  49. export default Tabs;