react-selectfield
Version:
A React Select and MultiSelect component (in progress).
261 lines (228 loc) • 8.21 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var events = {
pauseEvent: function pauseEvent(event) {
event.stopPropagation();
event.preventDefault();
},
addEventsToDocument: function addEventsToDocument(eventMap) {
(0, _keys2.default)(eventMap).forEach(function (key) {
document.addEventListener(key, eventMap[key], false);
});
},
removeEventsFromDocument: function removeEventsFromDocument(eventMap) {
(0, _keys2.default)(eventMap).forEach(function (key) {
document.removeEventListener(key, eventMap[key], false);
});
},
targetIsDescendant: function targetIsDescendant(event, parent) {
var node = event.target;
while (node !== null) {
if (node === parent) return true;
node = node.parentNode;
}
return false;
}
};
var SelectField = function (_React$Component) {
(0, _inherits3.default)(SelectField, _React$Component);
function SelectField() {
(0, _classCallCheck3.default)(this, SelectField);
var _this = (0, _possibleConstructorReturn3.default)(this, (SelectField.__proto__ || (0, _getPrototypeOf2.default)(SelectField)).call(this));
_this.state = {
isOpened: false,
selected: ''
};
_this.toggle = _this.toggle.bind(_this);
_this.close = _this.close.bind(_this);
_this.clear = _this.clear.bind(_this);
_this.handleDocumentClick = _this.handleDocumentClick.bind(_this);
_this.getDocumentEvents = _this.getDocumentEvents.bind(_this);
_this.getLabel = _this.getLabel.bind(_this);
return _this;
}
(0, _createClass3.default)(SelectField, [{
key: 'toggle',
value: function toggle() {
this.setState({ isOpened: !this.state.isOpened });
}
}, {
key: 'close',
value: function close() {
this.setState({ isOpened: false });
}
}, {
key: 'clear',
value: function clear() {
this.setState({ selected: '' }, this.handleOptionSelected.bind(this, ''));
}
}, {
key: 'handleOptionClick',
value: function handleOptionClick(item) {
this.setState({ selected: item }, this.handleOptionSelected.bind(this, item.value));
}
}, {
key: 'handleOptionSelected',
value: function handleOptionSelected(value) {
this.props.onChange(value);
this.close();
}
}, {
key: 'getLabel',
value: function getLabel() {
if (this.state.selected) {
return this.state.selected.label;
}
}
}, {
key: 'handleDocumentClick',
value: function handleDocumentClick(event) {
if (this.state.isOpened && !events.targetIsDescendant(event, _reactDom2.default.findDOMNode(this))) {
this.setState({ isOpened: false });
}
}
}, {
key: 'getDocumentEvents',
value: function getDocumentEvents() {
return {
click: this.handleDocumentClick,
touchend: this.handleDocumentClick
};
}
}, {
key: 'componentWillUpdate',
value: function componentWillUpdate(nextProps, nextState) {
if (!this.state.isOpened && nextState.isOpened) {
events.addEventsToDocument(this.getDocumentEvents());
}
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps, prevState) {
if (prevState.isOpened && !this.state.isOpened) {
events.removeEventsFromDocument(this.getDocumentEvents());
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
if (this.state.isOpened) {
events.removeEventsFromDocument(this.getDocumentEvents());
}
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _props = this.props,
className = _props.className,
source = _props.source,
value = _props.value,
placeholder = _props.placeholder;
className = className ? className + ' select-field' : 'select-field';
className += this.state.isOpened ? ' is-opened' : '';
className += this.state.selected ? ' is-selected' : '';
var caretDown = _react2.default.createElement(
'svg',
{
className: 'select-field__display-caret',
fill: '#383838',
height: '24',
viewBox: '0 0 24 24',
width: '24',
xmlns: 'http://www.w3.org/2000/svg' },
_react2.default.createElement('path', { d: 'M7.41 7.84L12 12.42l4.59-4.58L18 9.25l-6 6-6-6z' }),
_react2.default.createElement('path', { d: 'M0-.75h24v24H0z', fill: 'none' })
);
var clearButton = _react2.default.createElement(
'svg',
{
className: 'select-field__display-clear',
onClick: this.clear,
fill: '#383838',
height: '18',
viewBox: '0 0 24 24',
width: '18',
xmlns: 'http://www.w3.org/2000/svg' },
_react2.default.createElement('path', { d: 'M0 0h24v24H0z', fill: 'none' }),
_react2.default.createElement('path', { d: 'M14.59 8L12 10.59 9.41 8 8 9.41 10.59 12 8 14.59 9.41 16 12 13.41 14.59 16 16 14.59 13.41 12 16 9.41 14.59 8zM12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z' })
);
return _react2.default.createElement(
'div',
{ className: className },
_react2.default.createElement(
'div',
{
className: 'select-field__display',
onClick: this.toggle,
tabIndex: '-1',
ref: function ref(display) {
_this2.display = display;
} },
_react2.default.createElement(
'div',
{ className: 'select-field__display-placeholder' },
placeholder
),
_react2.default.createElement(
'div',
{ className: 'select-field__display-label' },
this.getLabel()
),
_react2.default.createElement(
'div',
{ className: 'select-field__display-input' },
_react2.default.createElement('input', {
readOnly: true,
type: 'text',
value: this.state.selected,
ref: function ref(input) {
_this2.input = input;
}
})
),
!this.state.selected && caretDown,
this.state.selected && clearButton
),
_react2.default.createElement(
'ul',
{ className: 'select-field__options' },
source.map(function (item) {
var classNameItem = void 0;
classNameItem = 'select-field__option';
classNameItem += item.value === value ? ' is-selected' : '';
return _react2.default.createElement(
'li',
{
key: item.value,
className: classNameItem,
onClick: _this2.handleOptionClick.bind(_this2, item) },
item.label
);
})
)
);
}
}]);
return SelectField;
}(_react2.default.Component);
exports.default = SelectField;