Add files
This commit is contained in:
commit
bb80829159
18195 changed files with 2122994 additions and 0 deletions
317
509bba0_unpacked_with_node_modules/~/react-onclickoutside/index.js
generated
vendored
Executable file
317
509bba0_unpacked_with_node_modules/~/react-onclickoutside/index.js
generated
vendored
Executable file
|
@ -0,0 +1,317 @@
|
|||
/**
|
||||
* A higher-order-component for handling onClickOutside for React components.
|
||||
*/
|
||||
(function(root) {
|
||||
|
||||
// administrative
|
||||
var registeredComponents = [];
|
||||
var handlers = [];
|
||||
var IGNORE_CLASS = 'ignore-react-onclickoutside';
|
||||
var DEFAULT_EVENTS = ['mousedown', 'touchstart'];
|
||||
|
||||
/**
|
||||
* Check whether some DOM node is our Component's node.
|
||||
*/
|
||||
var isNodeFound = function(current, componentNode, ignoreClass) {
|
||||
if (current === componentNode) {
|
||||
return true;
|
||||
}
|
||||
// SVG <use/> elements do not technically reside in the rendered DOM, so
|
||||
// they do not have classList directly, but they offer a link to their
|
||||
// corresponding element, which can have classList. This extra check is for
|
||||
// that case.
|
||||
// See: http://www.w3.org/TR/SVG11/struct.html#InterfaceSVGUseElement
|
||||
// Discussion: https://github.com/Pomax/react-onclickoutside/pull/17
|
||||
if (current.correspondingElement) {
|
||||
return current.correspondingElement.classList.contains(ignoreClass);
|
||||
}
|
||||
return current.classList.contains(ignoreClass);
|
||||
};
|
||||
|
||||
/**
|
||||
* Try to find our node in a hierarchy of nodes, returning the document
|
||||
* node as highest noode if our node is not found in the path up.
|
||||
*/
|
||||
var findHighest = function(current, componentNode, ignoreClass) {
|
||||
if (current === componentNode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If source=local then this event came from 'somewhere'
|
||||
// inside and should be ignored. We could handle this with
|
||||
// a layered approach, too, but that requires going back to
|
||||
// thinking in terms of Dom node nesting, running counter
|
||||
// to React's 'you shouldn't care about the DOM' philosophy.
|
||||
while(current.parentNode) {
|
||||
if (isNodeFound(current, componentNode, ignoreClass)) {
|
||||
return true;
|
||||
}
|
||||
current = current.parentNode;
|
||||
}
|
||||
return current;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the browser scrollbar was clicked
|
||||
*/
|
||||
var clickedScrollbar = function(evt) {
|
||||
return document.documentElement.clientWidth <= evt.clientX || document.documentElement.clientHeight <= evt.clientY;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate the event handler that checks whether a clicked DOM node
|
||||
* is inside of, or lives outside of, our Component's node tree.
|
||||
*/
|
||||
var generateOutsideCheck = function(componentNode, componentInstance, eventHandler, ignoreClass, excludeScrollbar, preventDefault, stopPropagation) {
|
||||
return function(evt) {
|
||||
if (preventDefault) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
if (stopPropagation) {
|
||||
evt.stopPropagation();
|
||||
}
|
||||
var current = evt.target;
|
||||
if((excludeScrollbar && clickedScrollbar(evt)) || (findHighest(current, componentNode, ignoreClass) !== document)) {
|
||||
return;
|
||||
}
|
||||
eventHandler(evt);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* This function generates the HOC function that you'll use
|
||||
* in order to impart onOutsideClick listening to an
|
||||
* arbitrary component. It gets called at the end of the
|
||||
* bootstrapping code to yield an instance of the
|
||||
* onClickOutsideHOC function defined inside setupHOC().
|
||||
*/
|
||||
function setupHOC(root, React, ReactDOM, createReactClass) {
|
||||
|
||||
// The actual Component-wrapping HOC:
|
||||
return function onClickOutsideHOC(Component, config) {
|
||||
var wrapComponentWithOnClickOutsideHandling = createReactClass({
|
||||
statics: {
|
||||
/**
|
||||
* Access the wrapped Component's class.
|
||||
*/
|
||||
getClass: function() {
|
||||
if (Component.getClass) {
|
||||
return Component.getClass();
|
||||
}
|
||||
return Component;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Access the wrapped Component's instance.
|
||||
*/
|
||||
getInstance: function() {
|
||||
return Component.prototype.isReactComponent ? this.refs.instance : this;
|
||||
},
|
||||
|
||||
// this is given meaning in componentDidMount
|
||||
__outsideClickHandler: function() {},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
excludeScrollbar: config && config.excludeScrollbar
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Add click listeners to the current document,
|
||||
* linked to this component's state.
|
||||
*/
|
||||
componentDidMount: function() {
|
||||
// If we are in an environment without a DOM such
|
||||
// as shallow rendering or snapshots then we exit
|
||||
// early to prevent any unhandled errors being thrown.
|
||||
if (typeof document === 'undefined' || !document.createElement){
|
||||
return;
|
||||
}
|
||||
|
||||
var instance = this.getInstance();
|
||||
var clickOutsideHandler;
|
||||
|
||||
if(config && typeof config.handleClickOutside === 'function') {
|
||||
clickOutsideHandler = config.handleClickOutside(instance);
|
||||
if(typeof clickOutsideHandler !== 'function') {
|
||||
throw new Error('Component lacks a function for processing outside click events specified by the handleClickOutside config option.');
|
||||
}
|
||||
} else if(typeof instance.handleClickOutside === 'function') {
|
||||
if (React.Component.prototype.isPrototypeOf(instance)) {
|
||||
clickOutsideHandler = instance.handleClickOutside.bind(instance);
|
||||
} else {
|
||||
clickOutsideHandler = instance.handleClickOutside;
|
||||
}
|
||||
} else if(typeof instance.props.handleClickOutside === 'function') {
|
||||
clickOutsideHandler = instance.props.handleClickOutside;
|
||||
} else {
|
||||
throw new Error('Component lacks a handleClickOutside(event) function for processing outside click events.');
|
||||
}
|
||||
|
||||
var componentNode = ReactDOM.findDOMNode(instance);
|
||||
if (componentNode === null) {
|
||||
console.warn('Antipattern warning: there was no DOM node associated with the component that is being wrapped by outsideClick.');
|
||||
console.warn([
|
||||
'This is typically caused by having a component that starts life with a render function that',
|
||||
'returns `null` (due to a state or props value), so that the component \'exist\' in the React',
|
||||
'chain of components, but not in the DOM.\n\nInstead, you need to refactor your code so that the',
|
||||
'decision of whether or not to show your component is handled by the parent, in their render()',
|
||||
'function.\n\nIn code, rather than:\n\n A{render(){return check? <.../> : null;}\n B{render(){<A check=... />}\n\nmake sure that you',
|
||||
'use:\n\n A{render(){return <.../>}\n B{render(){return <...>{ check ? <A/> : null }<...>}}\n\nThat is:',
|
||||
'the parent is always responsible for deciding whether or not to render any of its children.',
|
||||
'It is not the child\'s responsibility to decide whether a render instruction from above should',
|
||||
'get ignored or not by returning `null`.\n\nWhen any component gets its render() function called,',
|
||||
'that is the signal that it should be rendering its part of the UI. It may in turn decide not to',
|
||||
'render all of *its* children, but it should never return `null` for itself. It is not responsible',
|
||||
'for that decision.'
|
||||
].join(' '));
|
||||
}
|
||||
|
||||
var fn = this.__outsideClickHandler = generateOutsideCheck(
|
||||
componentNode,
|
||||
instance,
|
||||
clickOutsideHandler,
|
||||
this.props.outsideClickIgnoreClass || IGNORE_CLASS,
|
||||
this.props.excludeScrollbar, // fallback not needed, prop always exists because of getDefaultProps
|
||||
this.props.preventDefault || false,
|
||||
this.props.stopPropagation || false
|
||||
);
|
||||
|
||||
var pos = registeredComponents.length;
|
||||
registeredComponents.push(this);
|
||||
handlers[pos] = fn;
|
||||
|
||||
// If there is a truthy disableOnClickOutside property for this
|
||||
// component, don't immediately start listening for outside events.
|
||||
if (!this.props.disableOnClickOutside) {
|
||||
this.enableOnClickOutside();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Track for disableOnClickOutside props changes and enable/disable click outside
|
||||
*/
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
if (this.props.disableOnClickOutside && !nextProps.disableOnClickOutside) {
|
||||
this.enableOnClickOutside();
|
||||
} else if (!this.props.disableOnClickOutside && nextProps.disableOnClickOutside) {
|
||||
this.disableOnClickOutside();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the document's event listeners
|
||||
*/
|
||||
componentWillUnmount: function() {
|
||||
this.disableOnClickOutside();
|
||||
this.__outsideClickHandler = false;
|
||||
var pos = registeredComponents.indexOf(this);
|
||||
if( pos>-1) {
|
||||
// clean up so we don't leak memory
|
||||
if (handlers[pos]) { handlers.splice(pos, 1); }
|
||||
registeredComponents.splice(pos, 1);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Can be called to explicitly enable event listening
|
||||
* for clicks and touches outside of this element.
|
||||
*/
|
||||
enableOnClickOutside: function() {
|
||||
var fn = this.__outsideClickHandler;
|
||||
if (typeof document !== 'undefined') {
|
||||
var events = this.props.eventTypes || DEFAULT_EVENTS;
|
||||
if (!events.forEach) {
|
||||
events = [events];
|
||||
}
|
||||
events.forEach(function (eventName) {
|
||||
document.addEventListener(eventName, fn);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Can be called to explicitly disable event listening
|
||||
* for clicks and touches outside of this element.
|
||||
*/
|
||||
disableOnClickOutside: function() {
|
||||
var fn = this.__outsideClickHandler;
|
||||
if (typeof document !== 'undefined') {
|
||||
var events = this.props.eventTypes || DEFAULT_EVENTS;
|
||||
if (!events.forEach) {
|
||||
events = [events];
|
||||
}
|
||||
events.forEach(function (eventName) {
|
||||
document.removeEventListener(eventName, fn);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Pass-through render
|
||||
*/
|
||||
render: function() {
|
||||
var passedProps = this.props;
|
||||
var props = {};
|
||||
Object.keys(this.props).forEach(function(key) {
|
||||
if (key !== 'excludeScrollbar') {
|
||||
props[key] = passedProps[key];
|
||||
}
|
||||
});
|
||||
if (Component.prototype.isReactComponent) {
|
||||
props.ref = 'instance';
|
||||
}
|
||||
props.disableOnClickOutside = this.disableOnClickOutside;
|
||||
props.enableOnClickOutside = this.enableOnClickOutside;
|
||||
return React.createElement(Component, props);
|
||||
}
|
||||
});
|
||||
|
||||
// Add display name for React devtools
|
||||
(function bindWrappedComponentName(c, wrapper) {
|
||||
var componentName = c.displayName || c.name || 'Component';
|
||||
wrapper.displayName = 'OnClickOutside(' + componentName + ')';
|
||||
}(Component, wrapComponentWithOnClickOutsideHandling));
|
||||
|
||||
return wrapComponentWithOnClickOutsideHandling;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sets up the library in ways that
|
||||
* work with the various modulde loading solutions
|
||||
* used in JavaScript land today.
|
||||
*/
|
||||
function setupBinding(root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['react','react-dom','create-react-class'], function(React, ReactDom, createReactClass) {
|
||||
if (!createReactClass) createReactClass = React.createClass;
|
||||
return factory(root, React, ReactDom, createReactClass);
|
||||
});
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node. Note that this does not work with strict
|
||||
// CommonJS, but only CommonJS-like environments
|
||||
// that support module.exports
|
||||
module.exports = factory(root, require('react'), require('react-dom'), require('create-react-class'));
|
||||
} else {
|
||||
// Browser globals (root is window)
|
||||
var createReactClass = React.createClass ? React.createClass : window.createReactClass;
|
||||
root.onClickOutside = factory(root, React, ReactDOM, createReactClass);
|
||||
}
|
||||
}
|
||||
|
||||
// Make it all happen
|
||||
setupBinding(root, setupHOC);
|
||||
|
||||
}(this));
|
||||
|
||||
|
||||
|
||||
//////////////////
|
||||
// WEBPACK FOOTER
|
||||
// ./~/react-onclickoutside/index.js
|
||||
// module id = 2769
|
||||
// module chunks = 4
|
Loading…
Add table
Add a link
Reference in a new issue