react-radial
Version:
a radial component built with react and resonance
185 lines (158 loc) • 7.41 kB
JavaScript
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;