feeles-ide
Version:
The hackable and serializable IDE to make learning material
260 lines (237 loc) • 8.56 kB
JavaScript
import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import IconButton from 'material-ui/IconButton';
import NavigationClose from 'material-ui/svg-icons/navigation/close';
import EditorModeEdit from 'material-ui/svg-icons/editor/mode-edit';
import { transparent, redA200 } from 'material-ui/styles/colors';
import { emphasize, fade } from 'material-ui/utils/colorManipulator';
var MaxTabWidth = 160;
var MinTabWidth = 0;
var TabHeight = 32;
var TabSkewX = 24;
var getStyles = function getStyles(props, context, state) {
var containerWidth = props.containerWidth,
isSelected = props.isSelected;
var _context$muiTheme = context.muiTheme,
palette = _context$muiTheme.palette,
spacing = _context$muiTheme.spacing,
fontFamily = _context$muiTheme.fontFamily;
var closerMouseOver = state.closerMouseOver;
var tabHeight = TabHeight + (isSelected ? 1 : 0);
var tabWidth = Math.min(MaxTabWidth, Math.max(MinTabWidth, containerWidth / props.tabs.length));
var blank = tabHeight / Math.tan((90 - TabSkewX) / 180 * Math.PI);
var backgroundColor = fade(isSelected ? palette.canvasColor : emphasize(palette.canvasColor), 1);
var blade = function blade(left) {
return {
position: 'absolute',
boxSizing: 'border-box',
width: tabWidth - blank,
height: tabHeight,
left: left ? 0 : 'auto',
right: left ? 'auto' : 0,
borderTopWidth: left ? 0 : 1,
borderRightWidth: left ? 0 : 1,
borderBottomWidth: 0,
borderLeftWidth: left ? 1 : 0,
borderStyle: 'solid',
borderColor: palette.primary1Color,
transform: 'skewX(' + (left ? -1 : 1) * TabSkewX + 'deg)',
backgroundColor: backgroundColor,
zIndex: left ? 1 : 2
};
};
return {
root: {
flex: '1 1 auto',
position: 'relative',
boxSizing: 'border-box',
maxWidth: MaxTabWidth,
height: tabHeight,
marginBottom: isSelected ? -1 : 0,
zIndex: isSelected ? 2 : 1,
fontFamily: fontFamily
},
left: blade(true),
center: {
position: 'absolute',
width: tabWidth - blank,
height: tabHeight,
paddingLeft: blank / 2,
paddingRight: blank / 2,
zIndex: 3
},
right: blade(false),
innerItem: {
display: 'flex',
alignItems: 'center',
height: tabHeight
},
label: {
flex: '1 1 auto',
color: palette.textColor,
textDecoration: 'none',
overflowX: 'hidden',
whiteSpace: 'nowrap',
fontSize: '.8em',
cursor: 'default'
},
rightButton: {
flex: '0 0 auto',
padding: 0,
width: spacing.iconSize,
height: spacing.iconSize,
margin: '0 -4px',
transform: 'scale(0.55)',
borderRadius: '50%',
backgroundColor: closerMouseOver ? redA200 : transparent
}
};
};
var ChromeTabs = function (_PureComponent) {
_inherits(ChromeTabs, _PureComponent);
function ChromeTabs() {
var _ref;
var _temp, _this, _ret;
_classCallCheck(this, ChromeTabs);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = ChromeTabs.__proto__ || _Object$getPrototypeOf(ChromeTabs)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
doc: null,
closerMouseOver: false,
hasChanged: false
}, _this.setDocIfNeeded = function (doc) {
if (_this.state.doc !== doc && doc) {
doc.on('change', _this.handleChange);
_this.handleChange(doc);
if (_this.state.doc) {
_this.state.doc.off('change', _this.handleChange);
}
_this.setState({ doc: doc });
}
}, _this.handleChange = function (doc) {
var hasChanged = doc.getValue() !== _this.props.file.text;
_this.setState({ hasChanged: hasChanged });
}, _temp), _possibleConstructorReturn(_this, _ret);
}
_createClass(ChromeTabs, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.setDocIfNeeded(this.props.doc);
}
}, {
key: 'componentWillUnount',
value: function componentWillUnount() {
if (this.state.doc) {
this.state.doc.off('change', this.handleChange);
}
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps) {
if (prevProps.file !== this.props.file && this.props.doc) {
this.handleChange(this.props.doc);
}
if (prevProps.doc !== this.props.doc) {
this.setDocIfNeeded(this.props.doc);
}
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _props = this.props,
file = _props.file,
tab = _props.tab,
handleSelect = _props.handleSelect,
handleClose = _props.handleClose,
localization = _props.localization;
var _context$muiTheme2 = this.context.muiTheme,
_context$muiTheme2$pa = _context$muiTheme2.palette,
secondaryTextColor = _context$muiTheme2$pa.secondaryTextColor,
alternateTextColor = _context$muiTheme2$pa.alternateTextColor,
prepareStyles = _context$muiTheme2.prepareStyles;
var doc = this.state.doc;
var styles = getStyles(this.props, this.context, this.state);
var handleRightTouchTap = function handleRightTouchTap(e) {
e.stopPropagation();
if (!_this2.state.hasChanged || confirm(localization.editorCard.notice)) {
// タブがとじられるので Save されていない変更はリセットされる
if (doc) {
doc.setValue(file.text);
doc.clearHistory();
}
handleClose(tab);
}
};
var handleRightMouseEnter = function handleRightMouseEnter() {
_this2.setState({ closerMouseOver: true });
};
var handleRightMouseLeave = function handleRightMouseLeave() {
_this2.setState({ closerMouseOver: false });
};
var label = this.props.tabs.some(function (item) {
return item !== tab && item.label === tab.label;
}) ? tab.file.name : tab.label;
return React.createElement(
'div',
{ style: prepareStyles(styles.root), ref: this.handleRef },
React.createElement('div', { style: prepareStyles(styles.left) }),
React.createElement(
'div',
{ style: prepareStyles(styles.center) },
React.createElement(
'div',
{
style: prepareStyles(styles.innerItem),
onClick: function onClick() {
return handleSelect(tab);
}
},
React.createElement(
'a',
{
href: '#',
style: prepareStyles(styles.label),
title: this.props.file.name
},
label
),
React.createElement(
IconButton,
{
style: styles.rightButton,
onClick: handleRightTouchTap,
onMouseEnter: handleRightMouseEnter,
onMouseLeave: handleRightMouseLeave
},
this.state.closerMouseOver ? React.createElement(NavigationClose, { color: alternateTextColor }) : this.state.hasChanged ? React.createElement(EditorModeEdit, { color: secondaryTextColor }) : React.createElement(NavigationClose, { color: secondaryTextColor })
)
)
),
React.createElement('div', { style: prepareStyles(styles.right) })
);
}
}]);
return ChromeTabs;
}(PureComponent);
ChromeTabs.propTypes = {
tab: PropTypes.object.isRequired,
file: PropTypes.object.isRequired,
tabs: PropTypes.array.isRequired,
isSelected: PropTypes.bool.isRequired,
handleSelect: PropTypes.func.isRequired,
handleClose: PropTypes.func.isRequired,
containerWidth: PropTypes.number.isRequired,
localization: PropTypes.object.isRequired,
doc: PropTypes.object
};
ChromeTabs.contextTypes = {
muiTheme: PropTypes.object.isRequired
};
export default ChromeTabs;