CustomNavigation.jsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import React, { useEffect, useState, useRef } from 'react';
  2. import PropTypes from 'prop-types';
  3. import {
  4. Nav, NavItem, NavLink, TabContent, TabPane,
  5. } from 'reactstrap';
  6. const CustomNavigation = (props) => {
  7. const { navTabMapping } = props;
  8. const [activeTab, setActiveTab] = useState(Object.keys(props.navTabMapping)[0]);
  9. const [sliderWidth, setSliderWidth] = useState(0);
  10. const [sliderMarginLeft, setSliderMarginLeft] = useState(0);
  11. const navBar = useRef();
  12. const navTabs = {};
  13. Object.keys(props.navTabMapping).forEach((key) => {
  14. navTabs[key] = React.createRef();
  15. });
  16. function switchActiveTab(activeTab) {
  17. setActiveTab(activeTab);
  18. }
  19. // Might make this dynamic for px, %, pt, em
  20. function getPercentage(min, max) {
  21. return min / max * 100;
  22. }
  23. function registerNavLink(key, elm) {
  24. if (elm != null) {
  25. navTabs[key] = elm;
  26. }
  27. }
  28. useEffect(() => {
  29. if (activeTab === '') {
  30. return;
  31. }
  32. if (navBar == null || navTabs == null) {
  33. return;
  34. }
  35. let tempML = 0;
  36. const styles = Object.entries(navTabs).map((el) => {
  37. const width = getPercentage(el[1].offsetWidth, navBar.current.offsetWidth);
  38. const marginLeft = tempML;
  39. tempML += width;
  40. return { width, marginLeft };
  41. });
  42. const { width, marginLeft } = styles[navTabMapping[activeTab].index];
  43. setSliderWidth(width);
  44. setSliderMarginLeft(marginLeft);
  45. }, [activeTab, navTabMapping]);
  46. return (
  47. <React.Fragment>
  48. <div ref={navBar}>
  49. <Nav className="nav-title grw-custom-navbar" id="grw-custom-navbar">
  50. {Object.entries(props.navTabMapping).map(([key, value]) => {
  51. return (
  52. <NavItem
  53. key={key}
  54. type="button"
  55. className={`p-0 grw-custom-navtab ${activeTab === key && 'active'}}`}
  56. >
  57. <NavLink key={key} innerRef={elm => registerNavLink(key, elm)} onClick={() => { switchActiveTab(key) }}>
  58. {value.icon}
  59. {value.i18n}
  60. </NavLink>
  61. </NavItem>
  62. );
  63. })}
  64. </Nav>
  65. </div>
  66. <hr className="my-0 grw-nav-slide-hr border-none" style={{ width: `${sliderWidth}%`, marginLeft: `${sliderMarginLeft}%` }} />
  67. <TabContent activeTab={activeTab} className="p-4">
  68. {Object.entries(props.navTabMapping).map(([key, value]) => {
  69. return (
  70. <TabPane key={key} tabId={key}>
  71. {value.tabContent}
  72. </TabPane>
  73. );
  74. })}
  75. </TabContent>
  76. </React.Fragment>
  77. );
  78. };
  79. CustomNavigation.propTypes = {
  80. navTabMapping: PropTypes.object,
  81. };
  82. export default CustomNavigation;