Skip to content

Commit

Permalink
fix(Tooltip single target):Support for multiple target elements using…
Browse files Browse the repository at this point in the history
… css selector reactstrap#1185
  • Loading branch information
akhlesh committed Apr 21, 2019
1 parent 3df7c03 commit 295aee1
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 23 deletions.
4 changes: 2 additions & 2 deletions src/PopperContent.js
Expand Up @@ -73,7 +73,7 @@ class PopperContent extends React.Component {
}

setTargetNode(node) {
this.targetNode = node;
this.targetNode = typeof node === 'string' ? getTarget(node) : node;
}

getTargetNode() {
Expand Down Expand Up @@ -177,7 +177,7 @@ class PopperContent extends React.Component {
}

render() {
this.setTargetNode(getTarget(this.props.target));
this.setTargetNode(this.props.target);

if (this.state.isOpen) {
return this.props.container === 'inline' ?
Expand Down
58 changes: 39 additions & 19 deletions src/TooltipPopoverWrapper.js
Expand Up @@ -61,11 +61,16 @@ function isInDOMSubtree(element, subtreeRoot) {
return subtreeRoot && (element === subtreeRoot || subtreeRoot.contains(element));
}

function isInDOMSubtrees(element, subtreeRoots = []) {
return subtreeRoots && subtreeRoots.length && subtreeRoots.find(subTreeRoot=> isInDOMSubtree(element, subTreeRoot));
}

class TooltipPopoverWrapper extends React.Component {
constructor(props) {
super(props);

this._target = null;
this._targets = [];
this.currentTargetElement = null;
this.addTargetEvents = this.addTargetEvents.bind(this);
this.handleDocumentClick = this.handleDocumentClick.bind(this);
this.removeTargetEvents = this.removeTargetEvents.bind(this);
Expand All @@ -90,6 +95,7 @@ class TooltipPopoverWrapper extends React.Component {

componentWillUnmount() {
this.removeTargetEvents();
this._targets = null;
}

static getDerivedStateFromProps(props, state) {
Expand Down Expand Up @@ -152,6 +158,7 @@ class TooltipPopoverWrapper extends React.Component {
show(e) {
if (!this.props.isOpen) {
this.clearShowTimeout();
this.currentTargetElement = e && e.target;
this.toggle(e);
}
}
Expand All @@ -168,6 +175,7 @@ class TooltipPopoverWrapper extends React.Component {
hide(e) {
if (this.props.isOpen) {
this.clearHideTimeout();
this.currentTargetElement = null;
this.toggle(e);
}
}
Expand Down Expand Up @@ -196,7 +204,7 @@ class TooltipPopoverWrapper extends React.Component {
handleDocumentClick(e) {
const triggers = this.props.trigger.split(' ');

if (triggers.indexOf('legacy') > -1 && (this.props.isOpen || isInDOMSubtree(e.target, this._target))) {
if (triggers.indexOf('legacy') > -1 && (this.props.isOpen || isInDOMSubtrees(e.target, this._targets))) {
if (this._hideTimeout) {
this.clearHideTimeout();
}
Expand All @@ -205,7 +213,7 @@ class TooltipPopoverWrapper extends React.Component {
} else if (!this.props.isOpen) {
this.showWithDelay(e);
}
} else if (triggers.indexOf('click') > -1 && isInDOMSubtree(e.target, this._target)) {
} else if (triggers.indexOf('click') > -1 && isInDOMSubtrees(e.target, this._targets)) {
if (this._hideTimeout) {
this.clearHideTimeout();
}
Expand All @@ -218,6 +226,18 @@ class TooltipPopoverWrapper extends React.Component {
}
}

addEventOnTargets(type, handler, isBubble) {
this._targets.forEach(target=> {
target.addEventListener(type, handler, isBubble);
});
}

removeEventOnTargets(type, handler, isBubble) {
this._targets.forEach(target=> {
target.removeEventListener(type, handler, isBubble);
});
}

addTargetEvents() {
if (this.props.trigger) {
let triggers = this.props.trigger.split(' ');
Expand All @@ -226,54 +246,54 @@ class TooltipPopoverWrapper extends React.Component {
document.addEventListener('click', this.handleDocumentClick, true);
}

if (this._target) {
if (this._targets && this._targets.length) {
if (triggers.indexOf('hover') > -1) {
this._target.addEventListener(
this.addEventOnTargets(
'mouseover',
this.showWithDelay,
true
);
this._target.addEventListener(
this.addEventOnTargets(
'mouseout',
this.hideWithDelay,
true
);
}
if (triggers.indexOf('focus') > -1) {
this._target.addEventListener('focusin', this.show, true);
this._target.addEventListener('focusout', this.hide, true);
this.addEventOnTargets('focusin', this.show, true);
this.addEventOnTargets('focusout', this.hide, true);
}
this._target.addEventListener('keydown', this.onEscKeyDown, true);
this.addEventOnTargets('keydown', this.onEscKeyDown, true);
}
}
}
}

removeTargetEvents() {
if (this._target) {
this._target.removeEventListener(
if (this._targets) {
this.removeEventOnTargets(
'mouseover',
this.showWithDelay,
true
);
this._target.removeEventListener(
this.removeEventOnTargets(
'mouseout',
this.hideWithDelay,
true
);
this._target.removeEventListener('keydown', this.onEscKeyDown, true);
this._target.removeEventListener('focusin', this.show, true);
this._target.removeEventListener('focusout', this.hide, true);
this.removeEventOnTargets('keydown', this.onEscKeyDown, true);
this.removeEventOnTargets('focusin', this.show, true);
this.removeEventOnTargets('focusout', this.hide, true);
}

document.removeEventListener('click', this.handleDocumentClick, true)
}

updateTarget() {
const newTarget = getTarget(this.props.target);
if (newTarget !== this._target) {
const newTarget = getTarget(this.props.target, true);
if (newTarget !== this._targets) {
this.removeTargetEvents();
this._target = newTarget;
this._targets = newTarget ? Array.from(newTarget) : [];
this.addTargetEvents();
}
}
Expand Down Expand Up @@ -325,7 +345,7 @@ class TooltipPopoverWrapper extends React.Component {
return (
<PopperContent
className={className}
target={target}
target={this.currentTargetElement}
isOpen={isOpen}
hideArrow={hideArrow}
boundariesElement={boundariesElement}
Expand Down
4 changes: 2 additions & 2 deletions src/utils.js
Expand Up @@ -255,9 +255,9 @@ export function isArrayOrNodeList(els) {
return Array.isArray(els) || (canUseDOM && typeof els.length === 'number');
}

export function getTarget(target) {
export function getTarget(target, allElements) {
const els = findDOMElements(target);
if (isArrayOrNodeList(els)) {
if (isArrayOrNodeList(els) && !allElements) {
return els[0];
}
return els;
Expand Down

0 comments on commit 295aee1

Please sign in to comment.