import React, {
useEffect, useState, useRef, useMemo, useCallback,
} from 'react';
import PropTypes from 'prop-types';
import {
Nav, NavItem, NavLink,
} from 'reactstrap';
function getBreakpointOneLevelLarger(breakpoint) {
switch (breakpoint) {
case 'sm':
return 'md';
case 'md':
return 'lg';
case 'lg':
return 'xl';
case 'xl':
default:
return '2xl';
}
}
export const CustomNavDropdown = (props) => {
const {
activeTab, navTabMapping, onNavSelected,
} = props;
const activeObj = navTabMapping[activeTab];
const menuItemClickHandler = useCallback((key) => {
if (onNavSelected != null) {
onNavSelected(key);
}
}, [onNavSelected]);
return (
{Object.entries(navTabMapping).map(([key, value]) => {
const isActive = activeTab === key;
const isLinkEnabled = value.isLinkEnabled != null ? value.isLinkEnabled(value) : true;
const { Icon, i18n } = value;
return (
);
})}
);
};
CustomNavDropdown.propTypes = {
activeTab: PropTypes.string.isRequired,
navTabMapping: PropTypes.object.isRequired,
onNavSelected: PropTypes.func,
};
export const CustomNavTab = (props) => {
const navContainer = useRef();
const [sliderWidth, setSliderWidth] = useState(0);
const [sliderMarginLeft, setSliderMarginLeft] = useState(0);
const {
activeTab, navTabMapping, onNavSelected, hideBorderBottom, breakpointToHideInactiveTabsDown, navRightElement,
} = props;
const navTabRefs = useMemo(() => {
const obj = {};
Object.keys(navTabMapping).forEach((key) => {
obj[key] = React.createRef();
});
return obj;
}, [navTabMapping]);
const navLinkClickHandler = useCallback((key) => {
if (onNavSelected != null) {
onNavSelected(key);
}
}, [onNavSelected]);
function registerNavLink(key, elm) {
if (elm != null) {
navTabRefs[key] = elm;
}
}
// Might make this dynamic for px, %, pt, em
function getPercentage(min, max) {
return min / max * 100;
}
useEffect(() => {
if (activeTab === '') {
return;
}
if (navContainer == null) {
return;
}
let tempML = 0;
const styles = Object.entries(navTabRefs).map((el) => {
const width = getPercentage(el[1].offsetWidth, navContainer.current.offsetWidth);
const marginLeft = tempML;
tempML += width;
return { width, marginLeft };
});
const { width, marginLeft } = styles[navTabMapping[activeTab].index];
setSliderWidth(width);
setSliderMarginLeft(marginLeft);
}, [activeTab, navTabRefs, navTabMapping]);
// determine inactive classes to hide NavItem
const inactiveClassnames = [];
if (breakpointToHideInactiveTabsDown != null) {
const breakpointOneLevelLarger = getBreakpointOneLevelLarger(breakpointToHideInactiveTabsDown);
inactiveClassnames.push('d-none');
inactiveClassnames.push(`d-${breakpointOneLevelLarger}-block`);
}
return (
{navRightElement}
{ !hideBorderBottom &&
}
);
};
CustomNavTab.propTypes = {
activeTab: PropTypes.string.isRequired,
navTabMapping: PropTypes.object.isRequired,
onNavSelected: PropTypes.func,
hideBorderBottom: PropTypes.bool,
breakpointToHideInactiveTabsDown: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
navRightElement: PropTypes.node,
};
CustomNavTab.defaultProps = {
hideBorderBottom: false,
};
const CustomNav = (props) => {
const tabClassnames = ['d-none'];
const dropdownClassnames = ['d-block'];
// determine classes to show/hide
const breakpointOneLevelLarger = getBreakpointOneLevelLarger(props.breakpointToSwitchDropdownDown);
tabClassnames.push(`d-${breakpointOneLevelLarger}-block`);
dropdownClassnames.push(`d-${breakpointOneLevelLarger}-none`);
return (
);
};
CustomNav.propTypes = {
activeTab: PropTypes.string.isRequired,
navTabMapping: PropTypes.object.isRequired,
onNavSelected: PropTypes.func,
hideBorderBottom: PropTypes.bool,
breakpointToHideInactiveTabsDown: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
breakpointToSwitchDropdownDown: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
};
CustomNav.defaultProps = {
hideBorderBottom: false,
breakpointToSwitchDropdownDown: 'sm',
};
export default CustomNav;