UNPKG

@digifi-los/reactapp

Version:
287 lines (267 loc) 10.2 kB
import React, { Component, PropTypes } from 'react'; import { Link, } from 'react-router'; import { getRenderedComponent, } from '../AppLayoutMap'; import { Accordion, Menu } from 'semantic-ui-react'; import ResponsiveButton from '../ResponsiveButton'; const propTypes = { activeLinkStyle: PropTypes.object, linkProps: PropTypes.object, navData: PropTypes.array, navSections: PropTypes.array, params: PropTypes.array, active: PropTypes.boolean, navType: PropTypes.string, customComponents: PropTypes.array, allActive: PropTypes.boolean, }; const defaultProps = { activeLinkStyle: {}, navData: [], navSections: [], params: [], linkProps: {}, toggleData: {}, customComponents: [], allActive: false, }; class ResponsiveNavBar extends Component { constructor(props) { super(props); let navData = props.navData || []; let navSections = props.navSections || []; let params = props.params || []; let linkProps = props.linkProps || {}; let toggleData = props.toggleData || {}; let navType = props.navType || ''; let allActive = props.allActive; this.state = { activeIndex: [0], activeSinglePageIndex: [ 0, 0 ], }; this.getSinglePageNav = this.getSinglePageNav.bind(this); this.updateSinglePageIndex = this.updateSinglePageIndex.bind(this); this.getMultipageNav = this.getMultipageNav.bind(this); this.handleClick = this.handleClick.bind(this); this.getPropsForOnClick = this.getPropsForOnClick.bind(this); this.getButtonLink = this.getButtonLink.bind(this); this.getBaseUrl = this.getBaseUrl.bind(this); this.getRenderedComponent = getRenderedComponent.bind(this); } componentWillMount() { let newActiveIndex = this.props.navSections.map((section, idx) => { if (this.props.navData && this.props.navData[idx]) { this.props.navData[idx].map((link, linkIdx) => { let linkURL = this.getBaseUrl(section.baseURL, this.props.params, this.props, linkIdx); link.linkURL = linkURL; }) } return idx; }); this.setState({ activeIndex: newActiveIndex, }) } getBaseUrl(baseurl, params, prop, index) { let returnLink = baseurl; if (params && params.length > 0) { params.forEach((param) => { if (param.key === ":index") { returnLink = returnLink.replace(":index", index); } else { returnLink = returnLink.replace(param.key, prop[ param.val ]); } }); } return returnLink } handleClick(e, titleProps) { const { index } = titleProps; const { activeIndex } = this.state; if (activeIndex.indexOf(index) === -1) { this.setState({ activeIndex: [...activeIndex, index] }); } else { let newIndexArray = activeIndex; newIndexArray.splice(newIndexArray.indexOf(index), 1); this.setState({ activeIndex: newIndexArray, }); } } updateSinglePageIndex(indexArr) { this.setState({ activeSinglePageIndex: indexArr }); } getPropsForOnClick(component) { return { clickprop: component.props.onClick, clickThisProp: component.props.onclickThisProp, clickAddPropObject: component.props.onclickAddProp, clickPropObject: component.props.onclickPropObject, clickBaseUrl: component.props.onclickBaseUrl, clickLinkParams: component.props.onclickLinkParams, clickPassProps: component.props.onclickProps, clickFetchProps: component.props.fetchProps, clickSuccessProps: component.props.successProps, thisDotProp: component.props, }; } getButtonLink(baseurl, params, prop) { let returnLink = baseurl; try { if (params && params.length > 0) { params.forEach((param) => { returnLink = returnLink.replace(param.key, prop[ param.val ]); }); } } catch (e) { console.debug(e, { baseurl, params, prop, }); } return returnLink; } getSinglePageNav(section, sectionIdx) { let onclickFunction = (data) => { console.debug('ResponsiveButton', { data, }); }; let itemProps = (this.props.linkProps && this.props.linkProps.className) ? this.props.linkProps.className : ''; let subMenu = this.props.navData[sectionIdx].map((link, linkIdx) => { let itemProps = (this.props.linkProps && this.props.linkProps.className) ? this.props.linkProps.className : ''; let activeClass = (this.state.activeSinglePageIndex[ 0 ] === sectionIdx && this.state.activeSinglePageIndex[ 1 ] === linkIdx) ? 'active-nav-link nav-link' + itemProps : 'nav-link' + itemProps; let navLink; let customComponents; if (link.navButton && link.navButton.component === 'ResponsiveButton') { let { thisDotProp, clickThisProp, clickPropObject, clickBaseUrl, clickLinkParams, clickPassProps, clickprop, clickFetchProps, clickSuccessProps, clickAddPropObject } = this.getPropsForOnClick(link.navButton); let linkSelectionProp = (clickThisProp) ? thisDotProp[clickThisProp] : clickPropObject || this.props; let onclickProp = (clickBaseUrl) ? this.getButtonLink(clickBaseUrl, clickLinkParams, linkSelectionProp) : clickPassProps || clickPropObject; if (clickAddPropObject && linkSelectionProp) { linkSelectionProp[clickAddPropObject] = this.props[clickAddPropObject]; } if (clickAddPropObject && onclickProp) { onclickProp[clickAddPropObject] = this.props[clickAddPropObject]; } if (typeof clickprop === 'string' && clickprop.indexOf('func:this.props.reduxRouter') !== -1) { onclickFunction = this.props.reduxRouter[clickprop.replace('func:this.props.reduxRouter.', '')]; } else if (typeof clickprop === 'string' && clickprop.indexOf('func:this.funcs') !== -1) { onclickFunction = this.funcs[clickprop.replace('func:this.funcs.', '')]; } else if (typeof clickprop === 'string' && clickprop.indexOf('func:window') !== -1) { onclickFunction = window[clickprop.replace('func:window.', '')].bind(this); } else if (typeof clickprop === 'string' && clickprop.indexOf('func:this.props') !== -1) { onclickFunction = this.props[clickprop.replace('func:this.props.', '')]; } else if (typeof clickprop === 'function') { onclickFunction = clickprop; } navLink = this.getRenderedComponent({ component: 'ResponsiveButton', children: link.navButton.children, props: Object.assign({}, { onClick: () => { this.updateSinglePageIndex([ sectionIdx, linkIdx ]); onclickFunction.call(this, onclickProp, clickFetchProps, clickSuccessProps); }, buttonProps: (link.navButton.props && link.navButton.props.buttonProps) ? link.navButton.props.buttonProps : undefined, style: link.navButton.style, className: link.navButton.className, }), }) } else if (link.navButton && link.navButton.component !== 'ResponsiveButton') { navLink = this.getRenderedComponent(link.navButton) } if (link.customComponents && Array.isArray(link.customComponents)) { customComponents = ( <div> {link.customComponents.map(component => { return this.getRenderedComponent(component) })} </div> ) } return ( <div {...this.props.itemProps} key={sectionIdx + '-' + linkIdx} className={activeClass}> {navLink} {customComponents} </div> ) }); return subMenu; } getMultipageNav(section, sectionIdx) { let subMenu = this.props.navData[ sectionIdx ].map((link, linkIdx) => { let itemProps = (this.props.linkProps && this.props.linkProps.className) ? this.props.linkProps.className : ''; let activeClass = (link.linkURL === this.props.location.pathname) ? 'active-nav-link nav-link' + itemProps : 'nav-link' + itemProps; return ( <div {...this.props.itemProps} key={sectionIdx + '-' + linkIdx} className={activeClass}> <Link to={link.linkURL} {...this.props.linkProps}> {link.name} </Link> {(section.buttons) ? section.buttons.map(button => { return this.getRenderedComponent(Object.assign({ component: 'ResponsiveButton', props: Object.assign({ buttonProps: {}, }, button.passProps, { onclickProps: this.getBaseUrl(button.passProps.onclickBaseUrl, button.passProps.onclickLinkParams, this.props, linkIdx), onclickBaseUrl: null, onclickLinkParams: null, } ), })) }) : null} </div> ) }); return subMenu; } render() { const { activeIndex, activeSinglePageIndex } = this.state; let navMenu = this.props.navSections.map((section, sectionIdx)=> { if (section.toggle && !this.props.toggleData[section.toggle]) { return; } let subMenu = (this.props.navType === 'singlePage') ? this.getSinglePageNav(section, sectionIdx) : this.getMultipageNav(section, sectionIdx); let activeStatus = (this.props.allActive) ? true : activeIndex.indexOf(sectionIdx) !== -1; return ( <Menu.Item {...this.props.sectionProps}> <Accordion.Title active={activeStatus} index={sectionIdx} onClick={this.handleClick} content={section.title} {...this.props.titleProps}> </Accordion.Title> <Accordion.Content active={activeStatus} {...this.props.contentProps}> {subMenu} </Accordion.Content> </Menu.Item> ) }) return ( <Accordion as={Menu} vertical {...this.props.accordionProps} > {navMenu} </Accordion> ); } } ResponsiveNavBar.propType = propTypes; ResponsiveNavBar.defaultProps = defaultProps; export default ResponsiveNavBar;