Skip to content

Commit

Permalink
#25: Add support for tooltip autopositioning
Browse files Browse the repository at this point in the history
  • Loading branch information
slmgc committed May 13, 2018
1 parent 186706a commit 8cdbe13
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 8 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Options
| ReactHint Property | Type | Default Value | Description
| :----------------- | :---------------------------------------------------------- | :------------ | :----------
| attribute | String | "data-rh" | Allows setting a custom tooltip attribute instead of the default one.
| autoPosition | Boolean | false | Autopositions tooltips based on closeness to window borders.
| className | String | "react-hint" | You can override the tooltip style by passing the `className` property.
| delay | Number | 0 | The default delay before showing/hiding the tooltip.
| events | Boolean or {click: Boolean, focus: Boolean, hover: Boolean} | false | Enables/disables all events or a subset of events.
Expand Down Expand Up @@ -82,7 +83,7 @@ class App extends React.Component {

render() {
return <div>
<ReactHint events delay={100} />
<ReactHint autoPosition events delay={100} />
<ReactHint persist
attribute="data-custom"
className="custom-hint"
Expand Down
2 changes: 1 addition & 1 deletion demo/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class App extends React.Component {

render() {
return <div>
<ReactHint events delay={100} />
<ReactHint autoPosition events delay={100} />
<ReactHint persist
attribute="data-custom"
className="custom-hint"
Expand Down
45 changes: 45 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ exports.default = function (_ref) {
}, _this.getHintData = function (_ref4, _ref5) {
var target = _ref4.target;
var attribute = _ref5.attribute,
autoPosition = _ref5.autoPosition,
position = _ref5.position;

var content = target.getAttribute(attribute) || '';
Expand All @@ -87,6 +88,49 @@ exports.default = function (_ref) {
targetWidth = _target$getBoundingCl.width,
targetHeight = _target$getBoundingCl.height;

if (autoPosition) {
var isHoriz = ['left', 'right'].includes(at);

var _document$documentEle = document.documentElement,
clientHeight = _document$documentEle.clientHeight,
clientWidth = _document$documentEle.clientWidth;


var directions = {
left: (isHoriz ? targetLeft - hintWidth : targetLeft + (targetWidth - hintWidth >> 1)) > 0,
right: (isHoriz ? targetLeft + targetWidth + hintWidth : targetLeft + (targetWidth + hintWidth >> 1)) < clientWidth,
bottom: (isHoriz ? targetTop + (targetHeight + hintHeight >> 1) : targetTop + targetHeight + hintHeight) < clientHeight,
top: (isHoriz ? targetTop - (hintHeight >> 1) : targetTop - hintHeight) > 0
};

switch (at) {
case 'left':
if (!directions.left) at = 'right';
if (!directions.top) at = 'bottom';
if (!directions.bottom) at = 'top';
break;

case 'right':
if (!directions.right) at = 'left';
if (!directions.top) at = 'bottom';
if (!directions.bottom) at = 'top';
break;

case 'bottom':
if (!directions.bottom) at = 'top';
if (!directions.left) at = 'right';
if (!directions.right) at = 'left';
break;

case 'top':
default:
if (!directions.top) at = 'bottom';
if (!directions.left) at = 'right';
if (!directions.right) at = 'left';
break;
}
}

var top = void 0,
left = void 0;
switch (at) {
Expand Down Expand Up @@ -175,6 +219,7 @@ exports.default = function (_ref) {
return ReactHint;
}(Component), _class.defaultProps = {
attribute: 'data-rh',
autoPosition: false,
className: 'react-hint',
delay: 0,
events: false,
Expand Down
56 changes: 54 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export default ({Component, createElement}) =>
class ReactHint extends Component {
static defaultProps = {
attribute: 'data-rh',
autoPosition: false,
className: 'react-hint',
delay: 0,
events: false,
Expand Down Expand Up @@ -69,9 +70,9 @@ export default ({Component, createElement}) =>
if (this.state.target) this.setState(this.getHintData)
}

getHintData = ({target}, {attribute, position}) => {
getHintData = ({target}, {attribute, autoPosition, position}) => {
const content = target.getAttribute(attribute) || ''
const at = target.getAttribute(`${attribute}-at`) || position
let at = target.getAttribute(`${attribute}-at`) || position

const {
top: containerTop,
Expand All @@ -90,6 +91,57 @@ export default ({Component, createElement}) =>
height: targetHeight
} = target.getBoundingClientRect()

if (autoPosition) {
const isHoriz = ['left', 'right'].includes(at)

const {
clientHeight,
clientWidth
} = document.documentElement

const directions = {
left: (isHoriz
? targetLeft - hintWidth
: targetLeft + (targetWidth - hintWidth >> 1)) > 0,
right: (isHoriz
? targetLeft + targetWidth + hintWidth
: targetLeft + (targetWidth + hintWidth >> 1)) < clientWidth,
bottom: (isHoriz
? targetTop + (targetHeight + hintHeight >> 1)
: targetTop + targetHeight + hintHeight) < clientHeight,
top: (isHoriz
? targetTop - (hintHeight >> 1)
: targetTop - hintHeight) > 0
}

switch (at) {
case 'left':
if (!directions.left) at = 'right'
if (!directions.top) at = 'bottom'
if (!directions.bottom) at = 'top'
break

case 'right':
if (!directions.right) at = 'left'
if (!directions.top) at = 'bottom'
if (!directions.bottom) at = 'top'
break

case 'bottom':
if (!directions.bottom) at = 'top'
if (!directions.left) at = 'right'
if (!directions.right) at = 'left'
break

case 'top':
default:
if (!directions.top) at = 'bottom'
if (!directions.left) at = 'right'
if (!directions.right) at = 'left'
break
}
}

let top, left
switch (at) {
case 'left':
Expand Down
47 changes: 46 additions & 1 deletion umd/react-hint.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
* react-hint v3.0.1 - https://react-hint.js.org
* react-hint v3.1.0 - https://react-hint.js.org
* MIT Licensed
*/
(function webpackUniversalModuleDefinition(root, factory) {
Expand Down Expand Up @@ -156,6 +156,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
}, _this.getHintData = function (_ref4, _ref5) {
var target = _ref4.target;
var attribute = _ref5.attribute,
autoPosition = _ref5.autoPosition,
position = _ref5.position;

var content = target.getAttribute(attribute) || '';
Expand All @@ -175,6 +176,49 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
targetWidth = _target$getBoundingCl.width,
targetHeight = _target$getBoundingCl.height;

if (autoPosition) {
var isHoriz = ['left', 'right'].includes(at);

var _document$documentEle = document.documentElement,
clientHeight = _document$documentEle.clientHeight,
clientWidth = _document$documentEle.clientWidth;


var directions = {
left: (isHoriz ? targetLeft - hintWidth : targetLeft + (targetWidth - hintWidth >> 1)) > 0,
right: (isHoriz ? targetLeft + targetWidth + hintWidth : targetLeft + (targetWidth + hintWidth >> 1)) < clientWidth,
bottom: (isHoriz ? targetTop + (targetHeight + hintHeight >> 1) : targetTop + targetHeight + hintHeight) < clientHeight,
top: (isHoriz ? targetTop - (hintHeight >> 1) : targetTop - hintHeight) > 0
};

switch (at) {
case 'left':
if (!directions.left) at = 'right';
if (!directions.top) at = 'bottom';
if (!directions.bottom) at = 'top';
break;

case 'right':
if (!directions.right) at = 'left';
if (!directions.top) at = 'bottom';
if (!directions.bottom) at = 'top';
break;

case 'bottom':
if (!directions.bottom) at = 'top';
if (!directions.left) at = 'right';
if (!directions.right) at = 'left';
break;

case 'top':
default:
if (!directions.top) at = 'bottom';
if (!directions.left) at = 'right';
if (!directions.right) at = 'left';
break;
}
}

var top = void 0,
left = void 0;
switch (at) {
Expand Down Expand Up @@ -263,6 +307,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
return ReactHint;
}(Component), _class.defaultProps = {
attribute: 'data-rh',
autoPosition: false,
className: 'react-hint',
delay: 0,
events: false,
Expand Down
4 changes: 2 additions & 2 deletions umd/react-hint.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8cdbe13

Please sign in to comment.