UNPKG

backpack-ui

Version:

Lonely Planet's Components

538 lines (447 loc) 17.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require("react"); var _react2 = _interopRequireDefault(_react); var _radium = require("radium"); var _radium2 = _interopRequireDefault(_radium); var _moment = require("moment"); var _moment2 = _interopRequireDefault(_moment); var _reactTether = require("react-tether"); var _reactTether2 = _interopRequireDefault(_reactTether); var _settings = require("../../../settings.json"); var _select = require("./select"); var _select2 = _interopRequireDefault(_select); var _styles = require("./styles"); var _styles2 = _interopRequireDefault(_styles); var _calendar = require("../calendar"); var _calendar2 = _interopRequireDefault(_calendar); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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; } var DateInput = function (_React$Component) { _inherits(DateInput, _React$Component); function DateInput(props) { _classCallCheck(this, DateInput); var _this = _possibleConstructorReturn(this, (DateInput.__proto__ || Object.getPrototypeOf(DateInput)).call(this, props)); _this.state = { isCalendarOpen: false, startDate: props.startDate, endDate: props.endDate }; _this.timeOptionPresets = { default: ["12:00 AM", "1:00 AM", "2:00 AM", "3:00 AM", "4:00 AM", "5:00 AM", "6:00 AM", "7:00 AM", "8:00 AM", "9:00 AM", "10:00 AM", "11:00 AM", "12:00 PM", "1:00 PM", "2:00 PM", "3:00 PM", "4:00 PM", "5:00 PM", "6:00 PM", "7:00 PM", "8:00 PM", "9:00 PM", "10:00 PM", "11:00 PM"], openTable: ["1:30 PM", "2:00 PM", "2:30 PM", "3:00 PM", "3:30 PM", "4:00 PM", "4:30 PM", "5:00 PM", "5:30 PM", "6:00 PM", "6:30 PM", "7:00 PM", "7:30 PM", "8:00 PM", "8:30 PM", "9:00 PM", "9:30 PM", "10:00 PM", "10:30 PM", "11:00 PM", "11:30 PM"] }; _this.openCalendar = _this.openCalendar.bind(_this); _this.closeCalendar = _this.closeCalendar.bind(_this); _this.calendarOnChange = _this.calendarOnChange.bind(_this); _this.updateInputValue = _this.updateInputValue.bind(_this); _this.updateRangeValues = _this.updateRangeValues.bind(_this); _this.handleClickOutside = _this.handleClickOutside.bind(_this); _this.handleKeydown = _this.handleKeydown.bind(_this); _this.startRangeOnClick = _this.startRangeOnClick.bind(_this); _this.endRangeOnClick = _this.endRangeOnClick.bind(_this); return _this; } _createClass(DateInput, [{ key: "componentDidMount", value: function componentDidMount() { document.addEventListener("click", this.handleClickOutside); document.addEventListener("keydown", this.handleKeydown); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { document.removeEventListener("click", this.handleClickOutside); document.removeEventListener("keydown", this.handleKeydown); } }, { key: "openCalendar", value: function openCalendar() { if (!this.state.isCalendarOpen) { this.setState({ isCalendarOpen: true }); } } }, { key: "closeCalendar", value: function closeCalendar() { if (this.state.isCalendarOpen) { this.setState({ isCalendarOpen: false }); } } }, { key: "updateInputValue", value: function updateInputValue(date) { this.setState({ isCalendarOpen: false, startDate: date }); } }, { key: "updateRangeValues", value: function updateRangeValues(newDates) { var _state = this.state; var clicked = _state.clicked; var startDate = _state.startDate; var endDate = _state.endDate; var fromDateOpen = clicked === "start"; var toDateOpen = clicked === "end"; if (fromDateOpen) { if (newDates.startDate > endDate) { this.setState({ startDate: newDates.startDate, endDate: newDates.endDate }); } else { this.setState({ startDate: newDates.startDate }); } this.inputEnd.focus(); } if (toDateOpen) { if (startDate > newDates.endDate) { this.setState({ startDate: newDates.startDate, endDate: newDates.endDate }); } else { this.setState({ endDate: newDates.endDate }); } } } }, { key: "calendarOnChange", value: function calendarOnChange(date) { if (!this.props.range) { this.updateInputValue(date); } if (this.props.range) { this.updateRangeValues(date); } if (this.props.onClose) { this.props.onClose({ startDate: date.startDate, endDate: date.endDate }); } } }, { key: "handleClickOutside", value: function handleClickOutside(event) { var isCalendarOpen = this.state.isCalendarOpen; var input = this.input; var calendar = this.calendar; if (input.contains(event.target)) { return; } else if (calendar && !calendar.contains(event.target) && isCalendarOpen) { this.closeCalendar(); } } }, { key: "handleKeydown", value: function handleKeydown(event) { var isCalendarOpen = this.state.isCalendarOpen; if (event.keyCode === 27 && isCalendarOpen) { this.closeCalendar(); } } }, { key: "startRangeOnClick", value: function startRangeOnClick() { var clicked = this.state.clicked; this.openCalendar(); if (clicked !== "start") { this.setState({ clicked: "start" }); } } }, { key: "endRangeOnClick", value: function endRangeOnClick() { var clicked = this.state.clicked; this.openCalendar(); if (clicked !== "end") { this.setState({ clicked: "end" }); } } }, { key: "render", value: function render() { var _this2 = this; var _props = this.props; var id = _props.id; var label = _props.label; var name = _props.name; var format = _props.format; var placeholder = _props.placeholder; var required = _props.required; var size = _props.size; var theme = _props.theme; var fill = _props.fill; var noBorder = _props.noBorder; var range = _props.range; var time = _props.time; var timeOptions = _props.timeOptions; var defaultTime = _props.defaultTime; var _state2 = this.state; var isCalendarOpen = _state2.isCalendarOpen; var startDate = _state2.startDate; var endDate = _state2.endDate; var style = [_styles2.default.base, _styles2.default.element.input.base, _styles2.default.element.dateInput.base]; if (size) { style.push(_styles2.default.size[size]); style.push(_styles2.default.element.input.size[size]); } if (theme) { style.push(_styles2.default.theme[theme]); style.push(_styles2.default.element.input.theme[theme]); style.push(_styles2.default.element.dateInput.theme[theme]); } if (fill) { style.push(_styles2.default.fill); } if (noBorder) { style.push(_styles2.default.noBorder); } if (range || time) { style.push({ float: "left", width: "50%" }); } var tetherComponentStyles = { position: "relative", zIndex: _settings.zIndex.modal }; return _react2.default.createElement( _reactTether2.default, { className: "DateInput-calendar", style: tetherComponentStyles, attachment: "top left", targetAttachment: "bottom left", constraints: [{ to: "window", attachment: "together" }] }, _react2.default.createElement( "div", { ref: function ref(node) { _this2.input = node; } }, !range && !time && _react2.default.createElement("input", { id: id, name: name || id, style: [style], value: startDate.format(format), onClick: this.openCalendar, onFocus: this.openCalendar, onBlur: this.closeCalendar, placeholder: (typeof placeholder === "undefined" ? "undefined" : _typeof(placeholder)) === "object" ? placeholder[0] : placeholder, required: required, "aria-label": (typeof label === "undefined" ? "undefined" : _typeof(label)) === "object" ? label[0] : label, title: (typeof label === "undefined" ? "undefined" : _typeof(label)) === "object" ? label[0] : label, readOnly: true }), (range && time || !range && time) && _react2.default.createElement( "div", { style: { overflow: "hidden" } }, _react2.default.createElement("input", { id: id + "-date", name: (name || id) + "-date", style: [style], value: startDate.format(format), onClick: this.openCalendar, onFocus: this.openCalendar, onBlur: this.closeCalendar, placeholder: (typeof placeholder === "undefined" ? "undefined" : _typeof(placeholder)) === "object" ? placeholder[0] : placeholder, required: required, "aria-label": (typeof label === "undefined" ? "undefined" : _typeof(label)) === "object" ? label[0] : label, title: (typeof label === "undefined" ? "undefined" : _typeof(label)) === "object" ? label[0] : label, readOnly: true }), _react2.default.createElement(_select2.default, { id: id + "-time", defaultValue: defaultTime, options: typeof timeOptions === "string" ? this.timeOptionPresets[timeOptions] : timeOptions, size: size, theme: theme, label: (typeof label === "undefined" ? "undefined" : _typeof(label)) === "object" ? label[1] : label, style: { borderLeft: 0, float: "left", width: "50%" }, required: true }) ), range && !time && _react2.default.createElement( "div", { style: { overflow: "hidden" } }, _react2.default.createElement("input", { id: id + "-start", name: (name || id) + "-start", style: [style, noBorder && { width: "calc(50% - 1px)" }], value: startDate.format(format), onClick: this.startRangeOnClick, onFocus: this.startRangeOnClick, placeholder: (typeof placeholder === "undefined" ? "undefined" : _typeof(placeholder)) === "object" ? placeholder[0] : placeholder, required: required, "aria-label": (typeof label === "undefined" ? "undefined" : _typeof(label)) === "object" ? label[0] : label, title: (typeof label === "undefined" ? "undefined" : _typeof(label)) === "object" ? label[0] : label, ref: function ref(node) { _this2.inputStart = node; }, key: "inputStart", readOnly: true }), _react2.default.createElement("input", { id: id + "-end", name: (name || id) + "-end", style: [style, { borderLeft: 0 }, noBorder && { float: "right", width: "calc(50% - 1px)" }], value: endDate.format(format), onClick: this.endRangeOnClick, onFocus: this.endRangeOnClick, placeholder: (typeof placeholder === "undefined" ? "undefined" : _typeof(placeholder)) === "object" ? placeholder[1] : placeholder, required: required, "aria-label": (typeof label === "undefined" ? "undefined" : _typeof(label)) === "object" ? label[1] : label, title: (typeof label === "undefined" ? "undefined" : _typeof(label)) === "object" ? label[1] : label, ref: function ref(node) { _this2.inputEnd = node; }, key: "inputEnd", readOnly: true }) ) ), isCalendarOpen && _react2.default.createElement( "div", { ref: function ref(node) { _this2.calendar = node; } }, _react2.default.createElement(_calendar2.default, { startDate: startDate, endDate: endDate, format: format, minDate: (0, _moment2.default)(), onChange: this.calendarOnChange, useRange: range }) ) ); } }]); return DateInput; }(_react2.default.Component); DateInput.propTypes = { /** * ID of the input */ id: _react2.default.PropTypes.string.isRequired, /** * Label for the input; will not create a `label` element but instead add * `title` and `aria-label` attributes; this is a design decision to not * show labels */ label: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.array]).isRequired, /** * Name of the input */ name: _react2.default.PropTypes.string, /** * Start date value */ startDate: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.object, // Moment.js object _react2.default.PropTypes.func]), /** * End date value; range only */ endDate: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.object, // Moment.js object _react2.default.PropTypes.func]), /** * Moment.js date format */ format: _react2.default.PropTypes.string, /** * Placeholder text for the input */ placeholder: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.array]), /** * Whether or not the input is required */ required: _react2.default.PropTypes.bool, /** * Size of the input; sizes are defined in styles.js */ size: _react2.default.PropTypes.oneOf(["tiny", "small", "medium", "large", "huge"]), /** * Theme of the input; themes are defined in styles.js */ theme: _react2.default.PropTypes.oneOf(["base", "light", "dark", "inputGroup"]), /** * Fills the width of the parent */ fill: _react2.default.PropTypes.bool, /** * Remove border */ noBorder: _react2.default.PropTypes.bool, /** * Whether or not to use the range calendar */ range: _react2.default.PropTypes.bool, /** * Whether or not to show a "time" drop down */ time: _react2.default.PropTypes.bool, /** * An array of time options or a keyword to use a preset */ timeOptions: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.array, _react2.default.PropTypes.oneOf(["default", "openTable"])]), /** * A string to set the default value (time) */ defaultTime: _react2.default.PropTypes.string, onClose: _react2.default.PropTypes.func }; DateInput.defaultProps = { id: "", label: "", name: "", startDate: (0, _moment2.default)(), endDate: (0, _moment2.default)().add(1, "week"), format: "M/D/YYYY", placeholder: "", required: false, size: "medium", theme: "base", fill: false, noBorder: false, range: false, time: false, timeOptions: "default", defaultTime: "7:00 PM" }; DateInput.styles = _styles2.default; exports.default = (0, _radium2.default)(DateInput);