UNPKG

react-radial

Version:

a radial component built with react and resonance

185 lines (158 loc) 7.41 kB
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } import React, { Component } from 'react'; import { NodeGroup } from 'resonance'; import PropTypes from 'prop-types'; import { describeArc, describeArcRegion } from './util/helper'; import Radial from './Radial'; import { arrayFill } from './util/helper'; var ReactRadial = function (_Component) { _inherits(ReactRadial, _Component); function ReactRadial(props) { _classCallCheck(this, ReactRadial); var _this = _possibleConstructorReturn(this, _Component.call(this, props)); _this._handleClick = function (event) { if (!_this.state.transitioning) { if (!_this.state.enabled) { var div = event.target; var cx = event.clientX - div.offsetLeft; var cy = event.clientY - div.offsetTop; _this.setState({ cx: cx, cy: cy, enabled: true, data: _this._getDataObject(0, 0, _extends({}, _this.props)) }); } else { _this.setState({ enabled: false }); } } }; _this.state = { transitioning: false, enabled: props.autoLoad }; if (props.autoLoad) { _this.state = _extends({}, _this.state, { cx: innerWidth * .625, cy: props.innerRadius + props.outerRadius + 80, data: _this._getDataObject(0, 0, _extends({}, props)), enabled: true }); } _this._updateData = _this._updateData.bind(_this); _this._handleClick = _this._handleClick.bind(_this); _this._transitionStart = _this._transitionStart.bind(_this); _this._transitionEnd = _this._transitionEnd.bind(_this); _this._buttonSelect = _this._buttonSelect.bind(_this); return _this; } ReactRadial.prototype._transitionStart = function _transitionStart() { this.setState({ transitioning: true }); }; ReactRadial.prototype._transitionEnd = function _transitionEnd() { this.setState({ transitioning: false }); }; ReactRadial.prototype._updateData = function _updateData() { if (!this.state.transitioning) { this._updateState(this._getDataObject(this.props.innerRadius, this.props.outerRadius, _extends({}, this.props))); } }; ReactRadial.prototype._buttonSelect = function _buttonSelect() { var _this2 = this; if (!this.state.transitioning) { this._updateState(this._getDataObject(0, 0, _extends({}, this.props))); // close menu setTimeout(function () { document.body.style.cursor = 'default'; _this2.setState({ enabled: false, transitioning: false }); }, this.props.duration + this.props.buttons.length * this.props.delay // wait until animation finishes ); } }; ReactRadial.prototype._getDataObject = function _getDataObject() { var radInner = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var _this3 = this; var radOuter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var propOb = arguments[2]; var numberOfTabs = propOb.buttons.length; var data = propOb.buttons.map(function (d, i) { return { key: d, text: d, stroke: arrayFill(propOb.stroke, numberOfTabs)[i], fill: arrayFill(propOb.fill, numberOfTabs)[i], strokeWidth: arrayFill(propOb.strokeWidth, numberOfTabs)[i], buttonFunctions: arrayFill(function (event) { _this3._buttonSelect(event); propOb.buttonFunctions[i](); }, numberOfTabs)[i], cx: propOb.innerRadius + propOb.outerRadius, cy: propOb.innerRadius + propOb.outerRadius, radiusDiff: radOuter - propOb.strokeWidth, radius: radInner, angleStart: i * 360 / numberOfTabs, angleEnd: (i + 1) * 360 / numberOfTabs }; }); return data; }; ReactRadial.prototype._updateState = function _updateState(data) { this.setState({ data: data }); }; ReactRadial.prototype.shouldComponentUpdate = function shouldComponentUpdate() { return !this.state.transitioning; }; ReactRadial.prototype.componentWillUpdate = function componentWillUpdate(nextProps) { if (!this.state.transitioning && (nextProps.innerRadius !== this.props.innerRadius || nextProps.outerRadius !== this.props.outerRadius || nextProps.buttons.length !== this.props.buttons.length || nextProps.strokeWidth !== this.props.strokeWidth)) { this._transitionStart(); this._updateState(this._getDataObject(nextProps.innerRadius, nextProps.outerRadius, _extends({}, nextProps))); setTimeout(this._transitionEnd, this.props.duration + this.props.buttons.length * this.props.delay); // wait until animation finishes // the transition functions needs to be used due to a bug in resonance 0.9.3. // they should otherwise live in the events objects of the update function } }; ReactRadial.prototype.render = function render() { var propOb = _extends({}, this.props, this.state); return React.createElement( 'div', { style: { width: '100%', height: '100%', position: 'absolute' }, onClick: this._handleClick }, this.state.enabled ? React.createElement(Radial, _extends({}, propOb, { updateData: this._updateData, start: this._transitionStart, end: this._transitionEnd })) : null ); }; return ReactRadial; }(Component); ReactRadial.propTypes = process.env.NODE_ENV !== "production" ? { delay: PropTypes.number, duration: PropTypes.number, innerRadius: PropTypes.number, outerRadius: PropTypes.number, buttons: PropTypes.array, buttonFunctions: PropTypes.array, strokeWidth: PropTypes.number, stroke: PropTypes.string, fill: PropTypes.string, autoLoad: PropTypes.bool } : {}; ReactRadial.defaultProps = { delay: 80, duration: 400, innerRadius: 20, outerRadius: 120, buttons: ["button1", "button2", "button3", "button4", "button5"], buttonFunctions: [function () { return console.log('clicked button 1'); }, function () { return console.log('clicked button 2'); }, function () { return console.log('clicked button 3'); }, function () { return console.log('clicked button 4'); }, function () { return console.log('clicked button 5'); }], strokeWidth: 2, stroke: 'rgba(255,255,255,1)', fill: 'rgba(0,0,0,.8)', autoLoad: false }; export default ReactRadial;