@spotware/react-tether
Version:
Drop content anywhere on the page.
655 lines (544 loc) • 21.1 kB
JavaScript
/*!
* @spotware/react-tether 0.6.1
* https://github.com/danreeves/react-tether
* Copyright (c) 2018 @spotware/react-tether authors
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("tether"), require("react-dom"), require("react"));
else if(typeof define === 'function' && define.amd)
define(["tether", "react-dom", "react"], factory);
else if(typeof exports === 'object')
exports["TetherComponent"] = factory(require("tether"), require("react-dom"), require("react"));
else
root["TetherComponent"] = factory(root["Tether"], root["ReactDOM"], root["React"]);
})(window, function(__WEBPACK_EXTERNAL_MODULE__0__, __WEBPACK_EXTERNAL_MODULE__1__, __WEBPACK_EXTERNAL_MODULE__7__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 9);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__0__;
/***/ }),
/* 1 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__1__;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
;
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
module.exports = ReactPropTypesSecret;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
;
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* Use invariant() to assert state which your program assumes to be true.
*
* Provide sprintf-style format (only %s is supported) and arguments
* to provide information about what broke and what you were
* expecting.
*
* The invariant message will be stripped in production, but the invariant
* will remain to ensure logic does not differ in production.
*/
var validateFormat = function validateFormat(format) {};
if (false) {}
function invariant(condition, format, a, b, c, d, e, f) {
validateFormat(format);
if (!condition) {
var error;
if (format === undefined) {
error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
} else {
var args = [a, b, c, d, e, f];
var argIndex = 0;
error = new Error(format.replace(/%s/g, function () {
return args[argIndex++];
}));
error.name = 'Invariant Violation';
}
error.framesToPop = 1; // we don't care about invariant's own frame
throw error;
}
}
module.exports = invariant;
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
;
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
function makeEmptyFunction(arg) {
return function () {
return arg;
};
}
/**
* This function accepts and discards inputs; it has no side effects. This is
* primarily useful idiomatically for overridable function endpoints which
* always need to be callable, since JS lacks a null-call idiom ala Cocoa.
*/
var emptyFunction = function emptyFunction() {};
emptyFunction.thatReturns = makeEmptyFunction;
emptyFunction.thatReturnsFalse = makeEmptyFunction(false);
emptyFunction.thatReturnsTrue = makeEmptyFunction(true);
emptyFunction.thatReturnsNull = makeEmptyFunction(null);
emptyFunction.thatReturnsThis = function () {
return this;
};
emptyFunction.thatReturnsArgument = function (arg) {
return arg;
};
module.exports = emptyFunction;
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
;
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var emptyFunction = __webpack_require__(4);
var invariant = __webpack_require__(3);
var ReactPropTypesSecret = __webpack_require__(2);
module.exports = function () {
function shim(props, propName, componentName, location, propFullName, secret) {
if (secret === ReactPropTypesSecret) {
// It is still safe when called from React.
return;
}
invariant(false, 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + 'Use PropTypes.checkPropTypes() to call them. ' + 'Read more at http://fb.me/use-check-prop-types');
};
shim.isRequired = shim;
function getShim() {
return shim;
};
// Important!
// Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.
var ReactPropTypes = {
array: shim,
bool: shim,
func: shim,
number: shim,
object: shim,
string: shim,
symbol: shim,
any: shim,
arrayOf: getShim,
element: shim,
instanceOf: getShim,
node: shim,
objectOf: getShim,
oneOf: getShim,
oneOfType: getShim,
shape: getShim,
exact: getShim
};
ReactPropTypes.checkPropTypes = emptyFunction;
ReactPropTypes.PropTypes = ReactPropTypes;
return ReactPropTypes;
};
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
if (false) { var throwOnDirectAccess, isValidElement, REACT_ELEMENT_TYPE; } else {
// By explicitly using `prop-types` you are opting into new production behavior.
// http://fb.me/prop-types-in-prod
module.exports = __webpack_require__(5)();
}
/***/ }),
/* 7 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__7__;
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
;
Object.defineProperty(exports, "__esModule", {
value: true
});
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; };
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 = __webpack_require__(7);
var _propTypes = __webpack_require__(6);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _reactDom = __webpack_require__(1);
var _reactDom2 = _interopRequireDefault(_reactDom);
var _tether = __webpack_require__(0);
var _tether2 = _interopRequireDefault(_tether);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } 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; }
if (!_tether2.default) {
console.error('It looks like Tether has not been included. Please load this dependency first https://github.com/HubSpot/tether');
}
var hasCreatePortal = _reactDom2.default.createPortal !== undefined;
var renderElementToPropTypes = [_propTypes2.default.string, _propTypes2.default.shape({
appendChild: _propTypes2.default.func.isRequired
})];
var childrenPropType = function childrenPropType(_ref, propName, componentName) {
var children = _ref.children;
var childCount = _react.Children.count(children);
if (childCount <= 0) {
return new Error(componentName + ' expects at least one child to use as the target element.');
}
if (childCount > 2) {
return new Error('Only a max of two children allowed in ' + componentName + '.');
}
};
var attachmentPositions = ['auto auto', 'top left', 'top center', 'top right', 'middle left', 'middle center', 'middle right', 'bottom left', 'bottom center', 'bottom right'];
var TetherComponent = function (_Component) {
_inherits(TetherComponent, _Component);
function TetherComponent(props) {
_classCallCheck(this, TetherComponent);
var _this = _possibleConstructorReturn(this, (TetherComponent.__proto__ || Object.getPrototypeOf(TetherComponent)).call(this, props));
_this._targetNode = null;
_this._elementParentNode = null;
_this._tether = null;
var elementComponent = _react.Children.toArray(props.children)[1];
if (elementComponent) {
_this._createContainer();
}
return _this;
}
_createClass(TetherComponent, [{
key: 'componentWillUpdate',
value: function componentWillUpdate(_ref2) {
var children = _ref2.children;
var elementComponent = _react.Children.toArray(children)[1];
if (elementComponent) {
this._createContainer();
}
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
this._targetNode = _reactDom2.default.findDOMNode(this);
this._update();
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate() {
this._targetNode = _reactDom2.default.findDOMNode(this);
this._update();
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this._destroy();
}
}, {
key: 'getTetherInstance',
value: function getTetherInstance() {
return this._tether;
}
}, {
key: 'disable',
value: function disable() {
this._tether.disable();
}
}, {
key: 'enable',
value: function enable() {
this._tether.enable();
}
}, {
key: 'on',
value: function on(event, handler, ctx) {
this._tether.on(event, handler, ctx);
}
}, {
key: 'once',
value: function once(event, handler, ctx) {
this._tether.once(event, handler, ctx);
}
}, {
key: 'off',
value: function off(event, handler) {
this._tether.off(event, handler);
}
}, {
key: 'position',
value: function position() {
this._tether.position();
}
}, {
key: '_registerEventListeners',
value: function _registerEventListeners() {
var _this2 = this,
_arguments = arguments;
this.on('update', function () {
return _this2.props.onUpdate && _this2.props.onUpdate.apply(_this2, _arguments);
});
this.on('repositioned', function () {
return _this2.props.onRepositioned && _this2.props.onRepositioned.apply(_this2, _arguments);
});
}
}, {
key: '_destroy',
value: function _destroy() {
if (this._elementParentNode) {
if (!hasCreatePortal) {
_reactDom2.default.unmountComponentAtNode(this._elementParentNode);
}
this._elementParentNode.parentNode.removeChild(this._elementParentNode);
}
if (this._tether) {
this._tether.destroy();
}
this._elementParentNode = null;
this._tether = null;
}
}, {
key: '_createContainer',
value: function _createContainer() {
var renderElementTag = this.props.renderElementTag;
// Create element node container if it hasn't been yet
if (!this._elementParentNode) {
// Create a node that we can stick our content Component in
this._elementParentNode = document.createElement(renderElementTag);
// Append node to the render node
this._renderNode.appendChild(this._elementParentNode);
}
}
}, {
key: '_update',
value: function _update() {
var _this3 = this;
var children = this.props.children;
var elementComponent = _react.Children.toArray(children)[1];
// If no element component provided, bail out
if (!elementComponent) {
// Destroy Tether element if it has been created
if (this._tether) {
this._destroy();
}
return;
}
if (hasCreatePortal) {
this._updateTether();
} else {
// Render element component into the DOM
_reactDom2.default.unstable_renderSubtreeIntoContainer(this, elementComponent, this._elementParentNode, function () {
// If we're not destroyed, update Tether once the subtree has finished rendering
if (_this3._elementParentNode) {
_this3._updateTether();
}
});
}
}
}, {
key: '_updateTether',
value: function _updateTether() {
var _this4 = this;
var _props = this.props,
children = _props.children,
renderElementTag = _props.renderElementTag,
renderElementTo = _props.renderElementTo,
id = _props.id,
className = _props.className,
style = _props.style,
options = _objectWithoutProperties(_props, ['children', 'renderElementTag', 'renderElementTo', 'id', 'className', 'style']);
var tetherOptions = _extends({
target: this._targetNode,
element: this._elementParentNode
}, options);
if (id) {
this._elementParentNode.id = id;
}
if (className) {
this._elementParentNode.className = className;
}
if (style) {
Object.keys(style).forEach(function (key) {
_this4._elementParentNode.style[key] = style[key];
});
}
if (this._tether) {
this._tether.setOptions(tetherOptions);
} else {
this._tether = new _tether2.default(tetherOptions);
this._registerEventListeners();
}
this._tether.position();
}
}, {
key: 'render',
value: function render() {
var children = this.props.children;
var elementComponent = _react.Children.toArray(children)[1];
if (!hasCreatePortal || !elementComponent) {
return _react.Children.toArray(children)[0];
}
return [_react.Children.toArray(children)[0], _reactDom2.default.createPortal(elementComponent, this._elementParentNode)];
}
}, {
key: '_renderNode',
get: function get() {
var renderElementTo = this.props.renderElementTo;
if (typeof renderElementTo === 'string') {
return document.querySelector(renderElementTo);
}
return renderElementTo || document.body;
}
}]);
return TetherComponent;
}(_react.Component);
TetherComponent.propTypes = {
renderElementTag: _propTypes2.default.string,
renderElementTo: _propTypes2.default.oneOfType(renderElementToPropTypes),
attachment: _propTypes2.default.oneOf(attachmentPositions).isRequired,
targetAttachment: _propTypes2.default.oneOf(attachmentPositions),
offset: _propTypes2.default.string,
targetOffset: _propTypes2.default.string,
targetModifier: _propTypes2.default.string,
enabled: _propTypes2.default.bool,
classes: _propTypes2.default.object,
classPrefix: _propTypes2.default.string,
optimizations: _propTypes2.default.object,
constraints: _propTypes2.default.array,
id: _propTypes2.default.string,
className: _propTypes2.default.string,
style: _propTypes2.default.object,
onUpdate: _propTypes2.default.func,
onRepositioned: _propTypes2.default.func,
children: childrenPropType
};
TetherComponent.defaultProps = {
renderElementTag: 'div',
renderElementTo: null
};
exports.default = TetherComponent;
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
var _TetherComponent = __webpack_require__(8);
var _TetherComponent2 = _interopRequireDefault(_TetherComponent);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = _TetherComponent2.default;
/***/ })
/******/ ]);
});
//# sourceMappingURL=react-tether.js.map