Home Reference Source

application/components/common/dropdown.js

import React from 'react';
import {spring, Motion} from 'react-motion';
import Transition from 'react-motion-ui-pack'

/**
 * Pure React dropdown that doesn't rely on jQuery or Materialize at all.
 * Works similar to the React-Materialize dropdown component:
 * <code>
 *  <Dropdown trigger={
 *      <Button className='btn btn-block btn-small'><i className="fa fa-plus"></i></Button>
 *  }>
 *      <DropdownItem><Link to='/ceo/content/new'>Content</Link></DropdownItem>
 *      <DropdownItem><Link to='/ceo/assignment/new'>Assignment</Link></DropdownItem>
 * </Dropdown>
 * </code>
 */
class Dropdown extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            showDropdown: false
        };

        this.handleWindowKey = this.handleWindowKey.bind(this);
    }

    componentWillMount() {
        if (window) {
            window.addEventListener('keyup', this.handleWindowKey);
        }
    }

    componentWillUnmount() {
        if (window) {
            window.removeEventListener('keyup', this.handleWindowKey);
        }
    }

    handleWindowKey(e) {
        if (!this.state.showDropdown) {
            return;
        }

        if (e.keyCode == 27) {
            this.setState({'showDropdown': false});
        }
    }

    onUpdate(state) {
        this.setState(state);
    }

    handleClick() {
        const show = this.state.showDropdown;
        this.setState({'showDropdown': show ? false : true});
    }

    render() {
        return (
            <div className='dropdown-container'>
                <div className='dropdown-trigger' onClick={this.handleClick.bind(this)}>
                    {this.props.trigger}
                </div>
                <Transition
                    component={false}
                    enter={{
                        opacity: 1,
                        translateY: spring(0, {stiffness: 400, damping: 10})
                    }}
                    leave={{
                        opacity: 0,
                        translateY: -20
                    }}
                    >
                    {
                        this.state.showDropdown &&
                        <div key="dropdown" className='dropdown-items' onClick={this.handleClick.bind(this)}>
                            {this.props.children}
                        </div>
                    }
                </Transition>
            </div>
        );
    }
}

class DropdownItem extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div className='dropdown-item'>
                {this.props.children}
            </div>
        );
    }
}

export {Dropdown, DropdownItem};