CustomNavbar.jsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import React, { useEffect, useState } from 'react';
  2. import PropTypes from 'prop-types';
  3. import {
  4. Nav, NavItem, NavLink, TabContent, TabPane,
  5. } from 'reactstrap';
  6. import { withTranslation } from 'react-i18next';
  7. import { withUnstatedContainers } from './UnstatedUtils';
  8. import PageAccessoriesContainer from '../services/PageAccessoriesContainer';
  9. const CustomNavbar = (props) => {
  10. const { t, pageAccessoriesContainer } = props;
  11. const { switchActiveTab } = pageAccessoriesContainer;
  12. const { activeTab } = pageAccessoriesContainer.state;
  13. const [sliderWidth, setSliderWidth] = useState(null);
  14. const [sliderMarginLeft, setSliderMarginLeft] = useState(null);
  15. // Might make this dynamic for px, %, pt, em
  16. function getPercentage(min, max) {
  17. return min / max * 100;
  18. }
  19. useEffect(() => {
  20. if (activeTab === '') {
  21. return;
  22. }
  23. const navTitle = document.getElementById('nav-title');
  24. const navTabs = document.querySelectorAll('li.nav-link');
  25. if (navTitle == null || navTabs == null) {
  26. return;
  27. }
  28. let tempML = 0;
  29. const styles = [].map.call(navTabs, (el) => {
  30. const width = getPercentage(el.offsetWidth, navTitle.offsetWidth);
  31. const marginLeft = tempML;
  32. tempML += width;
  33. return { width, marginLeft };
  34. });
  35. const { width, marginLeft } = styles[props.navTabMapping[activeTab].index];
  36. setSliderWidth(width);
  37. setSliderMarginLeft(marginLeft);
  38. }, [activeTab]);
  39. return (
  40. <React.Fragment>
  41. <Nav className="nav-title" id="nav-title">
  42. {Object.entries(props.navTabMapping).map(([key, value]) => {
  43. return (
  44. <NavItem key={key} type="button" className={`p-0 nav-link ${activeTab === key && 'active'}`}>
  45. <NavLink onClick={() => { switchActiveTab(key) }}>
  46. {value.icon}
  47. {t(value.i18n)}
  48. </NavLink>
  49. </NavItem>
  50. );
  51. })}
  52. </Nav>
  53. <hr className="my-0 grw-nav-slide-hr border-none" style={{ width: `${sliderWidth}%`, marginLeft: `${sliderMarginLeft}%` }} />
  54. <TabContent activeTab={activeTab} className="p-5">
  55. {Object.entries(props.navTabMapping).map(([key, value]) => {
  56. return (
  57. <TabPane key={key} tabId={key}>
  58. {value.tabContent}
  59. </TabPane>
  60. );
  61. })}
  62. </TabContent>
  63. </React.Fragment>
  64. );
  65. };
  66. /**
  67. * Wrapper component for using unstated
  68. */
  69. const PageAccessoriesModalWrapper = withUnstatedContainers(CustomNavbar, [PageAccessoriesContainer]);
  70. CustomNavbar.propTypes = {
  71. t: PropTypes.func.isRequired, // i18next
  72. // pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
  73. pageAccessoriesContainer: PropTypes.instanceOf(PageAccessoriesContainer).isRequired,
  74. navTabMapping: PropTypes.object,
  75. };
  76. export default withTranslation()(PageAccessoriesModalWrapper);