import React from 'react'; import FocusTrap from 'focus-trap-react'; import { STRINGS, MAX_EXPLORER_PAGES } from '../../config/wagtailConfig'; import Button from '../Button/Button'; import LoadingSpinner from '../LoadingSpinner/LoadingSpinner'; import Transition, { PUSH, POP, FADE } from '../Transition/Transition'; import ExplorerHeader from './ExplorerHeader'; import ExplorerItem from './ExplorerItem'; import PageCount from './PageCount'; export default class ExplorerPanel extends React.Component { constructor(props) { super(props); this.state = { transition: PUSH, paused: false, }; this.onItemClick = this.onItemClick.bind(this); this.onHeaderClick = this.onHeaderClick.bind(this); this.clickOutside = this.clickOutside.bind(this); } componentWillReceiveProps(newProps) { const { path } = this.props; const isPush = newProps.path.length > path.length; this.setState({ transition: isPush ? PUSH : POP, }); } componentDidMount() { document.querySelector('[data-explorer-menu-item]').classList.add('submenu-active'); document.body.classList.add('explorer-open'); document.addEventListener('mousedown', this.clickOutside); document.addEventListener('touchstart', this.clickOutside); } componentWillUnmount() { document.querySelector('[data-explorer-menu-item]').classList.remove('submenu-active'); document.body.classList.remove('explorer-open'); document.removeEventListener('mousedown', this.clickOutside); document.removeEventListener('touchstart', this.clickOutside); } clickOutside(e) { const { onClose } = this.props; const explorer = document.querySelector('[data-explorer-menu]'); const toggle = document.querySelector('[data-explorer-menu-item]'); const isInside = explorer.contains(e.target) || toggle.contains(e.target); if (!isInside) { onClose(); } if (toggle.contains(e.target)) { this.setState({ paused: true, }); } } onItemClick(id, e) { const { pushPage } = this.props; e.preventDefault(); e.stopPropagation(); pushPage(id); } onHeaderClick(e) { const { path, popPage } = this.props; const hasBack = path.length > 1; if (hasBack) { e.preventDefault(); e.stopPropagation(); popPage(); } } renderChildren() { const { page, nodes } = this.props; let children; if (!page.isFetching && !page.children.items) { children = (
{STRINGS.NO_RESULTS}
); } else { children = (
{page.children.items.map((id) => ( ))}
); } return (
{children} {page.isFetching ? (
) : null} {page.isError ? (
{STRINGS.SERVER_ERROR}
) : null}
); } render() { const { page, onClose, path } = this.props; const { transition, paused } = this.state; return (
{this.renderChildren()} {page.isError || page.children.items && page.children.count > MAX_EXPLORER_PAGES ? ( ) : null}
); } } ExplorerPanel.propTypes = { nodes: React.PropTypes.object.isRequired, path: React.PropTypes.array, page: React.PropTypes.shape({ isFetching: React.PropTypes.bool, children: React.PropTypes.shape({ items: React.PropTypes.array, }), }), onClose: React.PropTypes.func.isRequired, popPage: React.PropTypes.func.isRequired, pushPage: React.PropTypes.func.isRequired, };