Skip to content

Commit

Permalink
Merge pull request #3 from sergiocruz/placement
Browse files Browse the repository at this point in the history
Position placement
  • Loading branch information
sergiocruz committed Dec 7, 2016
2 parents 4d3aa84 + b4be0ca commit 337f435
Show file tree
Hide file tree
Showing 14 changed files with 258 additions and 80 deletions.
30 changes: 30 additions & 0 deletions src/SimpleTooltip/DynamicPositionTooltip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { Component, PropTypes } from 'react';

class DynamicPositionTooltip extends Component {

static propTypes = {
tooltip: PropTypes.node.isRequired,
top: PropTypes.number.isRequired,
left: PropTypes.number.isRequired,
position: PropTypes.string.isRequired
}

static defaultProps = {
position: 'top',
}

render() {
const { top, left, position } = this.props;
return React.cloneElement(this.props.tooltip, {
dynamicPositioning: true,
top,
left,
position
});
}
}

export {
DynamicPositionTooltip,
DynamicPositionTooltip as default
}
37 changes: 19 additions & 18 deletions src/SimpleTooltip/OnClickTooltip.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import React, { Component, PropTypes } from 'react';
import { findDOMNode } from 'react-dom';
import { topPosition, leftPosition } from './lib/positionCalc';
import DynamicPositionTooltip from './DynamicPositionTooltip';
import TooltipWrapper from './TooltipWrapper';
import { getCoordinates } from './lib/positionElement';

export class OnClickTooltip extends Component {

static propTypes = {
tooltip: PropTypes.node.isRequired,
position: PropTypes.string.isRequired,
}

static defaultProps = {
position: 'top',
}

constructor() {
Expand All @@ -22,43 +29,37 @@ export class OnClickTooltip extends Component {

positionTooltip() {
const el = findDOMNode(this);
const coordinates = getCoordinates(el, this.props.position);

this.setState({
top: topPosition(el),
left: leftPosition(el),
top: coordinates.top,
left: coordinates.left,
});
}

toggleTooltip() {
this.setState(
{ isShowing: !this.state.isShowing },
() => this.positionTooltip()
() => this.state.isShowing && this.positionTooltip()
);
}

render() {

const tooltip = React.cloneElement(this.props.tooltip, {
dynamicPositioning: true,
top: this.state.top,
left: this.state.left,
isShowing: this.state.isShowing,
});

const clickable = React.cloneElement(this.props.children, {
const { top, left, isShowing } = this.state;
const clickableComponent = React.cloneElement(this.props.children, {
onClick: this.toggleTooltip,
});

return (
<span>
<TooltipWrapper>
{
this.state.isShowing
? tooltip
isShowing
? <DynamicPositionTooltip top={top} left={left} {...this.props} />
: null
}

{clickable}
</span>
{clickableComponent}
</TooltipWrapper>
);
}
}
30 changes: 15 additions & 15 deletions src/SimpleTooltip/OnMouseOverTooltip.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { Component, PropTypes } from 'react';
import DynamicPositionTooltip from './DynamicPositionTooltip';
import TooltipWrapper from './TooltipWrapper';
import { findDOMNode } from 'react-dom';
import { topPosition, leftPosition } from './lib/positionCalc';
import { getCoordinates } from './lib/positionElement';

let showTimer = null;
let hideTimer = null;
Expand All @@ -11,11 +13,13 @@ export class OnMouseOverTooltip extends Component {
tooltip: PropTypes.node.isRequired,
showDelay: PropTypes.number.isRequired,
hideDelay: PropTypes.number.isRequired,
position: PropTypes.string.isRequired,
}

static defaultProps = {
showDelay: 150,
hideDelay: 400,
position: 'top',
}

constructor() {
Expand All @@ -33,10 +37,11 @@ export class OnMouseOverTooltip extends Component {

positionTooltip() {
const el = findDOMNode(this);
const coordinates = getCoordinates(el, this.props.position);

this.setState({
top: topPosition(el),
left: leftPosition(el),
top: coordinates.top,
left: coordinates.left,
});
}

Expand Down Expand Up @@ -64,28 +69,23 @@ export class OnMouseOverTooltip extends Component {
}

render() {
const tooltip = React.cloneElement(this.props.tooltip, {
dynamicPositioning: true,
top: this.state.top,
left: this.state.left,
isShowing: this.state.isShowing,
});
const { top, left, isShowing } = this.state;

const overlayable = React.cloneElement(this.props.children, {
const overlayableComponent = React.cloneElement(this.props.children, {
onMouseEnter: this.onOverlay,
onMouseLeave: this.offOverlay,
});

return (
<span>
<TooltipWrapper>
{
this.state.isShowing
? tooltip
isShowing
? <DynamicPositionTooltip top={top} left={left} {...this.props} />
: null
}

{overlayable}
</span>
{overlayableComponent}
</TooltipWrapper>
);
}
}
46 changes: 28 additions & 18 deletions src/SimpleTooltip/Tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,57 @@ import React, { PropTypes } from 'react';
import Radium from 'radium';
import { getStyles } from './styles';

Tooltip.propTypes = {
dynamicPositioning: PropTypes.bool.isRequired,
styleOptions: PropTypes.object.isRequired,
position: PropTypes.string.isRequired,
};

Tooltip.defaultProps = {
dynamicPositioning: false,
position: 'top',

// Want to override tooltip colors? Simply pass in this prop:
styleOptions: {
bgColor: 'rgba(0, 0, 0, .8)',
textColor: '#FFFFFF',
textShadow: '1px 1px 1px black',
}
};

function Tooltip(props) {
const {
children,
dynamicPositioning,
styleOptions,
left,
top,
position,
} = props;

const cssClasses = `react-simpletooltip react-simpletooltip--${position}`;
const styles = getStyles(styleOptions);

const tooltipStyles = [
styles.tooltip,
dynamicPositioning
? { ...styles.tooltip.dynamicPositioning, top, left }
: null
];

const caretStyles = [
styles.caret,
styles.caret[`${position}Tooltip`]
];

return (
<div className="react-simpletooltip" style={tooltipStyles}>
<div className={cssClasses} style={tooltipStyles}>
{children}
<i style={styles.caret}></i>
<i style={caretStyles}></i>
</div>
);
}

Tooltip.propTypes = {
dynamicPositioning: PropTypes.bool.isRequired,
styleOptions: PropTypes.object.isRequired,
};

Tooltip.defaultProps = {
dynamicPositioning: false,

// Want to override tooltip colors? Simply pass in this prop:
styleOptions: {
bgColor: 'rgba(0, 0, 0, .8)',
textColor: '#FFFFFF',
textShadow: '1px 1px 1px black',
}
};

const StyledComponent = Radium(Tooltip);

export {
Expand Down
19 changes: 19 additions & 0 deletions src/SimpleTooltip/TooltipWrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React, { Component } from 'react';
import { getStyles } from './styles';

class TooltipWrapper extends Component {
render() {
const { tooltipWrapper } = getStyles();

return (
<div style={tooltipWrapper}>
{this.props.children}
</div>
)
}
}

export {
TooltipWrapper as default,
TooltipWrapper,
}
22 changes: 0 additions & 22 deletions src/SimpleTooltip/lib/positionCalc.js

This file was deleted.

21 changes: 21 additions & 0 deletions src/SimpleTooltip/lib/positionElement/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import positionTop from './positionTop';
import positionRight from './positionRight';
import positionBottom from './positionBottom';
import positionLeft from './positionLeft';

export function getCoordinates(el, position) {
switch(position) {
default:
case 'top':
return positionTop(el);

case 'right':
return positionRight(el);

case 'bottom':
return positionBottom(el);

case 'left':
return positionLeft(el);
}
}
19 changes: 19 additions & 0 deletions src/SimpleTooltip/lib/positionElement/positionBottom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { EXTRA_PAD } from './shared';

function topPosition(el) {
const tooltipEl = el.firstChild;
const top = el.offsetTop + tooltipEl.offsetHeight + EXTRA_PAD;
return top;
}

function leftPosition(el) {
const left = el.offsetLeft;
return left;
}

export default function position(el) {
return {
top: topPosition(el),
left: leftPosition(el),
};
}
19 changes: 19 additions & 0 deletions src/SimpleTooltip/lib/positionElement/positionLeft.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { EXTRA_PAD, centerVerticallyAlign } from './shared';

function topPosition(el) {
const tooltipEl = el.firstChild;
return centerVerticallyAlign(el, tooltipEl);
}

function leftPosition(el) {
const tooltipEl = el.firstChild;
const left = el.offsetLeft - tooltipEl.offsetWidth - EXTRA_PAD;
return left;
}

export default function position(el) {
return {
left: leftPosition(el),
top: topPosition(el),
}
}
20 changes: 20 additions & 0 deletions src/SimpleTooltip/lib/positionElement/positionRight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { EXTRA_PAD, centerVerticallyAlign } from './shared';

function topPosition(el) {
const tooltipEl = el.firstChild;
return centerVerticallyAlign(el, tooltipEl);
}

function leftPosition(el) {
const left = el.offsetLeft + el.offsetWidth + EXTRA_PAD;
return left;
}

export default function position(el) {
const coordinates = {
top: topPosition(el),
left: leftPosition(el),
}

return coordinates;
}

0 comments on commit 337f435

Please sign in to comment.