Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@atlaskit/tooltip

Package Overview
Dependencies
Maintainers
1
Versions
232
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@atlaskit/tooltip - npm Package Compare versions

Comparing version 9.0.0 to 9.1.0

4

CHANGELOG.md
# @atlaskit/tooltip
## 9.1.0
- [patch] Improve viewport edge collision detection. Tooltips will now shift along the secondary position axis (e.g. left/right when position is top/bottom) to show within viewport. Fix auto flip occurring incorrectly in these situations as well. [ebf331a](https://bitbucket.org/atlassian/atlaskit-mk-2/commits/ebf331a)
- [minor] Add new 'mouse' value for position prop and mousePosition prop to allow the tooltip to display relative to the mouse. [1d5577d](https://bitbucket.org/atlassian/atlaskit-mk-2/commits/1d5577d)
## 9.0.0

@@ -4,0 +8,0 @@ - [major] Bump to React 16.3. [4251858](https://bitbucket.org/atlassian/atlaskit-mk-2/commits/4251858)

8

dist/cjs/components/Animation.js

@@ -112,6 +112,8 @@ 'use strict';

position = _ref2.position,
props = (0, _objectWithoutProperties3.default)(_ref2, ['immediatelyHide', 'immediatelyShow', 'position']);
mousePosition = _ref2.mousePosition,
props = (0, _objectWithoutProperties3.default)(_ref2, ['immediatelyHide', 'immediatelyShow', 'position', 'mousePosition']);
var horizontalOffset = xPos[position];
var verticalOffset = yPos[position];
var truePosition = position === 'mouse' ? mousePosition : position;
var horizontalOffset = xPos[truePosition];
var verticalOffset = yPos[truePosition];

@@ -118,0 +120,0 @@ var restingTransform = 'translate3d(0, 0, 0)';

@@ -43,2 +43,7 @@ 'use strict';

(0, _createClass3.default)(TooltipMarshal, [{
key: 'immediatelySwitch',
value: function immediatelySwitch() {
return this.visibleTooltip && this.visibleTooltip.state.position !== 'mouse';
}
}, {
key: 'show',

@@ -66,3 +71,3 @@ value: function show(tooltip) {

// displayed, immediately switch them
if (this.visibleTooltip) {
if (this.immediatelySwitch()) {
// the visible tooltip may be queued to be hidden; prevent that

@@ -69,0 +74,0 @@ if (this.queuedForHide) {

@@ -7,10 +7,2 @@ 'use strict';

var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');

@@ -73,2 +65,3 @@

position: props.position,
mousePosition: props.mousePosition,
coordinates: null

@@ -79,2 +72,3 @@ };

/* eslint-disable react/sort-comp */
var Tooltip = function (_Component) {

@@ -94,3 +88,3 @@ (0, _inherits3.default)(Tooltip, _Component);

return _ret = (_temp = (_this = (0, _possibleConstructorReturn3.default)(this, (_ref = Tooltip.__proto__ || (0, _getPrototypeOf2.default)(Tooltip)).call.apply(_ref, [this].concat(args))), _this), _this.state = getInitialState(_this.props), _this.handleWrapperRef = function (ref) {
return _ret = (_temp = (_this = (0, _possibleConstructorReturn3.default)(this, (_ref = Tooltip.__proto__ || (0, _getPrototypeOf2.default)(Tooltip)).call.apply(_ref, [this].concat(args))), _this), _this.state = getInitialState(_this.props), _this.mouseCoordinates = null, _this.handleWrapperRef = function (ref) {
_this.wrapper = ref;

@@ -100,12 +94,18 @@ }, _this.handleMeasureRef = function (tooltip) {

var position = _this.props.position;
var _this$props = _this.props,
position = _this$props.position,
mousePosition = _this$props.mousePosition;
var _this2 = _this,
mouseCoordinates = _this2.mouseCoordinates;
var target = _this.wrapper.children.length ? _this.wrapper.children[0] : _this.wrapper;
// NOTE getPosition returns:
// position Enum(top | left | bottom | right)
// - adjusted for edge collision
// coordinates: Object(left: number, top: number)
// - coordinates passed to Transition
_this.setState((0, _utils.getPosition)({ position: position, target: target, tooltip: tooltip }));
var positionData = (0, _utils.getPosition)({
position: position,
target: target,
tooltip: tooltip,
mouseCoordinates: mouseCoordinates,
mousePosition: mousePosition
});
_this.setState(positionData);
}, _this.show = function (_ref2) {

@@ -129,3 +129,2 @@ var immediate = _ref2.immediate;

var onMouseOver = _this.props.onMouseOver;
// bail if over the wrapper, we only want to target the first child.

@@ -148,2 +147,7 @@

if (onMouseOut) onMouseOut(event);
}, _this.handleMouseMove = function (event) {
_this.mouseCoordinates = {
left: event.clientX,
top: event.clientY
};
}, _this.handleClick = function () {

@@ -161,8 +165,9 @@ var hideTooltipOnClick = _this.props.hideTooltipOnClick;

var position = nextProps.position,
truncate = nextProps.truncate;
truncate = nextProps.truncate,
mousePosition = nextProps.mousePosition;
// handle case where position is changed while visible
if (position !== this.props.position) {
this.setState({ position: position, coordinates: null });
if (position !== this.props.position || mousePosition !== this.props.mousePosition) {
this.setState({ position: position, mousePosition: mousePosition, coordinates: null });
}

@@ -186,2 +191,3 @@

isVisible = _state.isVisible,
mousePosition = _state.mousePosition,
position = _state.position,

@@ -216,2 +222,3 @@ coordinates = _state.coordinates;

immediatelyShow: immediatelyShow,
mousePosition: mousePosition,
position: position,

@@ -227,21 +234,17 @@ coordinates: coordinates,

}
// eslint-disable-next-line react/no-unused-prop-types
// Update mouse coordinates, used when position is 'mouse'.
// We are not debouncing/throttling this function because we aren't causing any
// re-renders or performaing any intensive calculations, we're just updating a value.
// React also doesn't play nice debounced DOM event handlers because they pool their
// SyntheticEvent objects. Need to use event.persist as a workaround - https://stackoverflow.com/a/24679479/893630
}, {
key: 'render',
value: function render() {
// NOTE removing props from rest:
// - `content` is a valid HTML attribute, but has a different semantic meaning
// - `component` is NOT valid and react will warn
// - `hideTooltipOnClick` is NOT valid and react will warn
// - `position` is NOT valid and react will warn
// - `truncate` is NOT valid and react will warn
// eslint-disable-next-line no-unused-vars
var _props2 = this.props,
children = _props2.children,
component = _props2.component,
content = _props2.content,
hideTooltipOnClick = _props2.hideTooltipOnClick,
position = _props2.position,
truncate = _props2.truncate,
Tag = _props2.tag,
rest = (0, _objectWithoutProperties3.default)(_props2, ['children', 'component', 'content', 'hideTooltipOnClick', 'position', 'truncate', 'tag']);
Tag = _props2.tag;

@@ -251,8 +254,9 @@

Tag,
(0, _extends3.default)({
{
onClick: this.handleClick,
onMouseMove: this.handleMouseMove,
onMouseOver: this.handleMouseOver,
onMouseOut: this.handleMouseOut,
ref: this.handleWrapperRef
}, rest),
},
_react.Children.only(children),

@@ -269,2 +273,3 @@ this.renderTooltip()

position: 'bottom',
mousePosition: 'bottom',
tag: 'div'

@@ -271,0 +276,0 @@ };

@@ -54,2 +54,3 @@ 'use strict';

immediatelyShow = _props.immediatelyShow,
mousePosition = _props.mousePosition,
position = _props.position,

@@ -69,2 +70,3 @@ truncate = _props.truncate;

'in': transitionIn,
mousePosition: mousePosition,
position: position,

@@ -71,0 +73,0 @@ style: coordinates,

@@ -6,8 +6,13 @@ 'use strict';

});
exports.default = getPosition;
var _inViewport = require('./inViewport');
var _assign = require('babel-runtime/core-js/object/assign');
var _inViewport2 = _interopRequireDefault(_inViewport);
var _assign2 = _interopRequireDefault(_assign);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
exports.default = getPosition;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -22,8 +27,98 @@

function getCoords(_ref) {
var targetRect = _ref.targetRect,
tooltipRect = _ref.tooltipRect,
gutter = _ref.gutter;
// Returns a top or left position that shifts the original coord to within viewport
function shiftCoord(coordName, coords, gutter) {
var shiftedCoord = {};
if (coordName === 'top' || coordName === 'left') {
shiftedCoord[coordName] = 0 + gutter;
}
var docEl = document.documentElement;
if (coordName === 'bottom') {
var viewportHeight = window.innerHeight || docEl && docEl.clientHeight || 0;
var amountClipped = coords.bottom - viewportHeight;
var shiftedTop = coords.top - amountClipped - gutter;
shiftedCoord.top = shiftedTop >= 0 ? shiftedTop : coords.top;
} else if (coordName === 'right') {
var viewportWidth = window.innerWidth || docEl && docEl.clientWidth || 0;
var _amountClipped = coords.right - viewportWidth;
var shiftedLeft = coords.left - _amountClipped - gutter;
shiftedCoord.left = shiftedLeft >= 0 ? shiftedLeft : coords.top;
}
return shiftedCoord;
}
// Returns a map of positions to whether they fit in viewport
function getViewportBounds(_ref, gutter) {
var top = _ref.top,
right = _ref.right,
bottom = _ref.bottom,
left = _ref.left;
var docEl = document.documentElement;
return {
top: top >= 0 + gutter,
left: left >= 0 + gutter,
bottom: bottom <= (window.innerHeight || docEl && docEl.clientHeight || 0) - gutter,
right: right <= (window.innerWidth || docEl && docEl.clientWidth || 0) - gutter
};
}
// Get the viewport bounds for each position coord
function getAllViewportBounds(allCoords, gutter) {
var viewportBounds = {};
(0, _keys2.default)(allCoords).forEach(function (position) {
var coords = allCoords[position];
viewportBounds[position] = getViewportBounds(coords, gutter);
});
return viewportBounds;
}
// Adjust the position and top/left coords to fit inside viewport
// Performs flipping on the primary axis and shifting on the secondary axis
function adjustPosition(originalPosition, positionCoords, gutter) {
var flippedPosition = FLIPPED_POSITION[originalPosition];
var viewportBounds = getAllViewportBounds(positionCoords, gutter);
// Should flip if the original position was not within bounds and the new position is
var shouldFlip = !viewportBounds[originalPosition][originalPosition] && viewportBounds[flippedPosition][originalPosition];
var adjustedPosition = shouldFlip ? flippedPosition : originalPosition;
// Check secondary axis, for positional shift
var shiftedCoords = {};
var secondaryPositions = (0, _keys2.default)(FLIPPED_POSITION).filter(function (position) {
return position !== originalPosition && position !== flippedPosition;
});
secondaryPositions.forEach(function (position) {
var inViewport = viewportBounds[adjustedPosition][position];
if (!inViewport) {
(0, _assign2.default)(shiftedCoords, shiftCoord(position, positionCoords[adjustedPosition], gutter));
}
});
// adjust positions with flipped position on main axis + shifted position on secondary axis
var left = shiftedCoords.left != null ? shiftedCoords.left : positionCoords[adjustedPosition].left;
var top = shiftedCoords.top != null ? shiftedCoords.top : positionCoords[adjustedPosition].top;
return { left: left, top: top, adjustedPosition: adjustedPosition };
}
function getCoords(_ref2) {
var targetRect = _ref2.targetRect,
tooltipRect = _ref2.tooltipRect,
gutter = _ref2.gutter;
return {
top: {

@@ -56,12 +151,93 @@ top: targetRect.top - (tooltipRect.height + gutter),

function getPosition(_ref2) {
var position = _ref2.position,
target = _ref2.target,
tooltip = _ref2.tooltip;
function getMouseCoords(_ref3) {
var mouseCoordinates = _ref3.mouseCoordinates,
tooltipRect = _ref3.tooltipRect,
gutter = _ref3.gutter;
var cursorPaddingRight = 8;
var cursorPaddingBottom = 16;
return {
top: {
top: mouseCoordinates.top - (tooltipRect.height + gutter),
right: mouseCoordinates.left + tooltipRect.width / 2,
bottom: mouseCoordinates.top - gutter,
left: mouseCoordinates.left - tooltipRect.width / 2
},
right: {
top: mouseCoordinates.top - tooltipRect.height / 2,
right: mouseCoordinates.left + cursorPaddingRight + gutter + tooltipRect.width,
bottom: mouseCoordinates.top + tooltipRect.height / 2,
left: mouseCoordinates.left + cursorPaddingRight + gutter
},
bottom: {
top: mouseCoordinates.top + cursorPaddingBottom + gutter,
right: mouseCoordinates.left + tooltipRect.width / 2,
bottom: mouseCoordinates.top + cursorPaddingBottom + gutter + tooltipRect.height,
left: mouseCoordinates.left - tooltipRect.width / 2
},
left: {
top: mouseCoordinates.top - tooltipRect.height / 2,
right: mouseCoordinates.left - gutter,
bottom: mouseCoordinates.top + tooltipRect.height / 2,
left: mouseCoordinates.left - (tooltipRect.width + gutter)
}
};
}
function getMousePosition(_ref4) {
var mousePosition = _ref4.mousePosition,
tooltip = _ref4.tooltip,
mouseCoordinates = _ref4.mouseCoordinates;
var noPosition = {
coordinates: { left: 0, top: 0 },
position: 'bottom'
position: 'mouse',
mousePosition: 'bottom'
};
if (!mousePosition) throw new Error('Property "mousePosition" is required.');
if (!tooltip) throw new Error('Property "tooltip" is required.');
if (!mouseCoordinates) return noPosition;
// get the original coordinates
var gutter = 8;
var tooltipRect = tooltip.getBoundingClientRect();
var POSITIONS = getMouseCoords({ mouseCoordinates: mouseCoordinates, tooltipRect: tooltipRect, gutter: gutter });
var _adjustPosition = adjustPosition(mousePosition, POSITIONS, gutter),
left = _adjustPosition.left,
top = _adjustPosition.top,
adjustedPosition = _adjustPosition.adjustedPosition;
return {
coordinates: { left: left, top: top },
position: 'mouse',
mousePosition: adjustedPosition
};
}
/**
* Gets the coordinates and adjusted position of a tooltip.
* Position will be flipped on the primary axis with respect to the initial position
* if there is not enough space in the viewport.
* Coordinates will be shifted along the secondary axis to render within viewport.
*/
function getPosition(_ref5) {
var position = _ref5.position,
target = _ref5.target,
tooltip = _ref5.tooltip,
mouseCoordinates = _ref5.mouseCoordinates,
mousePosition = _ref5.mousePosition;
if (position === 'mouse') {
return getMousePosition({ mousePosition: mousePosition, tooltip: tooltip, mouseCoordinates: mouseCoordinates });
}
var noPosition = {
coordinates: { left: 0, top: 0 },
position: 'bottom',
mousePosition: mousePosition
};
/* eslint-disable no-console */

@@ -81,16 +257,12 @@ if (!position) console.error('Property "position" is required.');

// set tooltip positions before viewport check
var attemptedPosition = POSITIONS[position];
var _adjustPosition2 = adjustPosition(position, POSITIONS, gutter),
left = _adjustPosition2.left,
top = _adjustPosition2.top,
adjustedPosition = _adjustPosition2.adjustedPosition;
// check if the tooltip is in view or must be flipped
var adjustedPosition = (0, _inViewport2.default)(attemptedPosition) ? position : FLIPPED_POSITION[position];
// adjust positions with (possibly) flipped position
var left = POSITIONS[adjustedPosition].left;
var top = POSITIONS[adjustedPosition].top;
return {
coordinates: { left: left, top: top },
position: adjustedPosition
position: adjustedPosition,
mousePosition: mousePosition
};
}

@@ -7,11 +7,2 @@ 'use strict';

var _inViewport = require('./inViewport');
Object.defineProperty(exports, 'inViewport', {
enumerable: true,
get: function get() {
return _interopRequireDefault(_inViewport).default;
}
});
var _getPosition = require('./getPosition');

@@ -18,0 +9,0 @@

@@ -96,6 +96,8 @@ import _extends from 'babel-runtime/helpers/extends';

position = _ref2.position,
props = _objectWithoutProperties(_ref2, ['immediatelyHide', 'immediatelyShow', 'position']);
mousePosition = _ref2.mousePosition,
props = _objectWithoutProperties(_ref2, ['immediatelyHide', 'immediatelyShow', 'position', 'mousePosition']);
var horizontalOffset = xPos[position];
var verticalOffset = yPos[position];
var truePosition = position === 'mouse' ? mousePosition : position;
var horizontalOffset = xPos[truePosition];
var verticalOffset = yPos[truePosition];

@@ -102,0 +104,0 @@ var restingTransform = 'translate3d(0, 0, 0)';

@@ -32,2 +32,7 @@ import _classCallCheck from 'babel-runtime/helpers/classCallCheck';

_createClass(TooltipMarshal, [{
key: 'immediatelySwitch',
value: function immediatelySwitch() {
return this.visibleTooltip && this.visibleTooltip.state.position !== 'mouse';
}
}, {
key: 'show',

@@ -55,3 +60,3 @@ value: function show(tooltip) {

// displayed, immediately switch them
if (this.visibleTooltip) {
if (this.immediatelySwitch()) {
// the visible tooltip may be queued to be hidden; prevent that

@@ -58,0 +63,0 @@ if (this.queuedForHide) {

@@ -1,3 +0,1 @@

import _extends from 'babel-runtime/helpers/extends';
import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';

@@ -31,2 +29,3 @@ import _classCallCheck from 'babel-runtime/helpers/classCallCheck';

position: props.position,
mousePosition: props.mousePosition,
coordinates: null

@@ -37,2 +36,3 @@ };

/* eslint-disable react/sort-comp */
var Tooltip = function (_Component) {

@@ -52,3 +52,3 @@ _inherits(Tooltip, _Component);

return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Tooltip.__proto__ || _Object$getPrototypeOf(Tooltip)).call.apply(_ref, [this].concat(args))), _this), _this.state = getInitialState(_this.props), _this.handleWrapperRef = function (ref) {
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Tooltip.__proto__ || _Object$getPrototypeOf(Tooltip)).call.apply(_ref, [this].concat(args))), _this), _this.state = getInitialState(_this.props), _this.mouseCoordinates = null, _this.handleWrapperRef = function (ref) {
_this.wrapper = ref;

@@ -58,12 +58,18 @@ }, _this.handleMeasureRef = function (tooltip) {

var position = _this.props.position;
var _this$props = _this.props,
position = _this$props.position,
mousePosition = _this$props.mousePosition;
var _this2 = _this,
mouseCoordinates = _this2.mouseCoordinates;
var target = _this.wrapper.children.length ? _this.wrapper.children[0] : _this.wrapper;
// NOTE getPosition returns:
// position Enum(top | left | bottom | right)
// - adjusted for edge collision
// coordinates: Object(left: number, top: number)
// - coordinates passed to Transition
_this.setState(getPosition({ position: position, target: target, tooltip: tooltip }));
var positionData = getPosition({
position: position,
target: target,
tooltip: tooltip,
mouseCoordinates: mouseCoordinates,
mousePosition: mousePosition
});
_this.setState(positionData);
}, _this.show = function (_ref2) {

@@ -87,3 +93,2 @@ var immediate = _ref2.immediate;

var onMouseOver = _this.props.onMouseOver;
// bail if over the wrapper, we only want to target the first child.

@@ -106,2 +111,7 @@

if (onMouseOut) onMouseOut(event);
}, _this.handleMouseMove = function (event) {
_this.mouseCoordinates = {
left: event.clientX,
top: event.clientY
};
}, _this.handleClick = function () {

@@ -119,8 +129,9 @@ var hideTooltipOnClick = _this.props.hideTooltipOnClick;

var position = nextProps.position,
truncate = nextProps.truncate;
truncate = nextProps.truncate,
mousePosition = nextProps.mousePosition;
// handle case where position is changed while visible
if (position !== this.props.position) {
this.setState({ position: position, coordinates: null });
if (position !== this.props.position || mousePosition !== this.props.mousePosition) {
this.setState({ position: position, mousePosition: mousePosition, coordinates: null });
}

@@ -144,2 +155,3 @@

isVisible = _state.isVisible,
mousePosition = _state.mousePosition,
position = _state.position,

@@ -174,2 +186,3 @@ coordinates = _state.coordinates;

immediatelyShow: immediatelyShow,
mousePosition: mousePosition,
position: position,

@@ -185,30 +198,28 @@ coordinates: coordinates,

}
// eslint-disable-next-line react/no-unused-prop-types
// Update mouse coordinates, used when position is 'mouse'.
// We are not debouncing/throttling this function because we aren't causing any
// re-renders or performaing any intensive calculations, we're just updating a value.
// React also doesn't play nice debounced DOM event handlers because they pool their
// SyntheticEvent objects. Need to use event.persist as a workaround - https://stackoverflow.com/a/24679479/893630
}, {
key: 'render',
value: function render() {
// NOTE removing props from rest:
// - `content` is a valid HTML attribute, but has a different semantic meaning
// - `component` is NOT valid and react will warn
// - `hideTooltipOnClick` is NOT valid and react will warn
// - `position` is NOT valid and react will warn
// - `truncate` is NOT valid and react will warn
// eslint-disable-next-line no-unused-vars
var _props2 = this.props,
children = _props2.children,
component = _props2.component,
content = _props2.content,
hideTooltipOnClick = _props2.hideTooltipOnClick,
position = _props2.position,
truncate = _props2.truncate,
Tag = _props2.tag,
rest = _objectWithoutProperties(_props2, ['children', 'component', 'content', 'hideTooltipOnClick', 'position', 'truncate', 'tag']);
Tag = _props2.tag;
return React.createElement(
Tag,
_extends({
{
onClick: this.handleClick,
onMouseMove: this.handleMouseMove,
onMouseOver: this.handleMouseOver,
onMouseOut: this.handleMouseOut,
ref: this.handleWrapperRef
}, rest),
},
Children.only(children),

@@ -226,2 +237,3 @@ this.renderTooltip()

position: 'bottom',
mousePosition: 'bottom',
tag: 'div'

@@ -228,0 +240,0 @@ };

@@ -31,2 +31,3 @@ import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';

immediatelyShow = _props.immediatelyShow,
mousePosition = _props.mousePosition,
position = _props.position,

@@ -46,2 +47,3 @@ truncate = _props.truncate;

'in': transitionIn,
mousePosition: mousePosition,
position: position,

@@ -48,0 +50,0 @@ style: coordinates,

@@ -1,3 +0,5 @@

import inViewport from './inViewport';
import _Object$assign from 'babel-runtime/core-js/object/assign';
import _Object$keys from 'babel-runtime/core-js/object/keys';
var FLIPPED_POSITION = {

@@ -10,8 +12,98 @@ top: 'bottom',

function getCoords(_ref) {
var targetRect = _ref.targetRect,
tooltipRect = _ref.tooltipRect,
gutter = _ref.gutter;
// Returns a top or left position that shifts the original coord to within viewport
function shiftCoord(coordName, coords, gutter) {
var shiftedCoord = {};
if (coordName === 'top' || coordName === 'left') {
shiftedCoord[coordName] = 0 + gutter;
}
var docEl = document.documentElement;
if (coordName === 'bottom') {
var viewportHeight = window.innerHeight || docEl && docEl.clientHeight || 0;
var amountClipped = coords.bottom - viewportHeight;
var shiftedTop = coords.top - amountClipped - gutter;
shiftedCoord.top = shiftedTop >= 0 ? shiftedTop : coords.top;
} else if (coordName === 'right') {
var viewportWidth = window.innerWidth || docEl && docEl.clientWidth || 0;
var _amountClipped = coords.right - viewportWidth;
var shiftedLeft = coords.left - _amountClipped - gutter;
shiftedCoord.left = shiftedLeft >= 0 ? shiftedLeft : coords.top;
}
return shiftedCoord;
}
// Returns a map of positions to whether they fit in viewport
function getViewportBounds(_ref, gutter) {
var top = _ref.top,
right = _ref.right,
bottom = _ref.bottom,
left = _ref.left;
var docEl = document.documentElement;
return {
top: top >= 0 + gutter,
left: left >= 0 + gutter,
bottom: bottom <= (window.innerHeight || docEl && docEl.clientHeight || 0) - gutter,
right: right <= (window.innerWidth || docEl && docEl.clientWidth || 0) - gutter
};
}
// Get the viewport bounds for each position coord
function getAllViewportBounds(allCoords, gutter) {
var viewportBounds = {};
_Object$keys(allCoords).forEach(function (position) {
var coords = allCoords[position];
viewportBounds[position] = getViewportBounds(coords, gutter);
});
return viewportBounds;
}
// Adjust the position and top/left coords to fit inside viewport
// Performs flipping on the primary axis and shifting on the secondary axis
function adjustPosition(originalPosition, positionCoords, gutter) {
var flippedPosition = FLIPPED_POSITION[originalPosition];
var viewportBounds = getAllViewportBounds(positionCoords, gutter);
// Should flip if the original position was not within bounds and the new position is
var shouldFlip = !viewportBounds[originalPosition][originalPosition] && viewportBounds[flippedPosition][originalPosition];
var adjustedPosition = shouldFlip ? flippedPosition : originalPosition;
// Check secondary axis, for positional shift
var shiftedCoords = {};
var secondaryPositions = _Object$keys(FLIPPED_POSITION).filter(function (position) {
return position !== originalPosition && position !== flippedPosition;
});
secondaryPositions.forEach(function (position) {
var inViewport = viewportBounds[adjustedPosition][position];
if (!inViewport) {
_Object$assign(shiftedCoords, shiftCoord(position, positionCoords[adjustedPosition], gutter));
}
});
// adjust positions with flipped position on main axis + shifted position on secondary axis
var left = shiftedCoords.left != null ? shiftedCoords.left : positionCoords[adjustedPosition].left;
var top = shiftedCoords.top != null ? shiftedCoords.top : positionCoords[adjustedPosition].top;
return { left: left, top: top, adjustedPosition: adjustedPosition };
}
function getCoords(_ref2) {
var targetRect = _ref2.targetRect,
tooltipRect = _ref2.tooltipRect,
gutter = _ref2.gutter;
return {
top: {

@@ -44,12 +136,93 @@ top: targetRect.top - (tooltipRect.height + gutter),

export default function getPosition(_ref2) {
var position = _ref2.position,
target = _ref2.target,
tooltip = _ref2.tooltip;
function getMouseCoords(_ref3) {
var mouseCoordinates = _ref3.mouseCoordinates,
tooltipRect = _ref3.tooltipRect,
gutter = _ref3.gutter;
var cursorPaddingRight = 8;
var cursorPaddingBottom = 16;
return {
top: {
top: mouseCoordinates.top - (tooltipRect.height + gutter),
right: mouseCoordinates.left + tooltipRect.width / 2,
bottom: mouseCoordinates.top - gutter,
left: mouseCoordinates.left - tooltipRect.width / 2
},
right: {
top: mouseCoordinates.top - tooltipRect.height / 2,
right: mouseCoordinates.left + cursorPaddingRight + gutter + tooltipRect.width,
bottom: mouseCoordinates.top + tooltipRect.height / 2,
left: mouseCoordinates.left + cursorPaddingRight + gutter
},
bottom: {
top: mouseCoordinates.top + cursorPaddingBottom + gutter,
right: mouseCoordinates.left + tooltipRect.width / 2,
bottom: mouseCoordinates.top + cursorPaddingBottom + gutter + tooltipRect.height,
left: mouseCoordinates.left - tooltipRect.width / 2
},
left: {
top: mouseCoordinates.top - tooltipRect.height / 2,
right: mouseCoordinates.left - gutter,
bottom: mouseCoordinates.top + tooltipRect.height / 2,
left: mouseCoordinates.left - (tooltipRect.width + gutter)
}
};
}
function getMousePosition(_ref4) {
var mousePosition = _ref4.mousePosition,
tooltip = _ref4.tooltip,
mouseCoordinates = _ref4.mouseCoordinates;
var noPosition = {
coordinates: { left: 0, top: 0 },
position: 'bottom'
position: 'mouse',
mousePosition: 'bottom'
};
if (!mousePosition) throw new Error('Property "mousePosition" is required.');
if (!tooltip) throw new Error('Property "tooltip" is required.');
if (!mouseCoordinates) return noPosition;
// get the original coordinates
var gutter = 8;
var tooltipRect = tooltip.getBoundingClientRect();
var POSITIONS = getMouseCoords({ mouseCoordinates: mouseCoordinates, tooltipRect: tooltipRect, gutter: gutter });
var _adjustPosition = adjustPosition(mousePosition, POSITIONS, gutter),
left = _adjustPosition.left,
top = _adjustPosition.top,
adjustedPosition = _adjustPosition.adjustedPosition;
return {
coordinates: { left: left, top: top },
position: 'mouse',
mousePosition: adjustedPosition
};
}
/**
* Gets the coordinates and adjusted position of a tooltip.
* Position will be flipped on the primary axis with respect to the initial position
* if there is not enough space in the viewport.
* Coordinates will be shifted along the secondary axis to render within viewport.
*/
export default function getPosition(_ref5) {
var position = _ref5.position,
target = _ref5.target,
tooltip = _ref5.tooltip,
mouseCoordinates = _ref5.mouseCoordinates,
mousePosition = _ref5.mousePosition;
if (position === 'mouse') {
return getMousePosition({ mousePosition: mousePosition, tooltip: tooltip, mouseCoordinates: mouseCoordinates });
}
var noPosition = {
coordinates: { left: 0, top: 0 },
position: 'bottom',
mousePosition: mousePosition
};
/* eslint-disable no-console */

@@ -69,16 +242,12 @@ if (!position) console.error('Property "position" is required.');

// set tooltip positions before viewport check
var attemptedPosition = POSITIONS[position];
var _adjustPosition2 = adjustPosition(position, POSITIONS, gutter),
left = _adjustPosition2.left,
top = _adjustPosition2.top,
adjustedPosition = _adjustPosition2.adjustedPosition;
// check if the tooltip is in view or must be flipped
var adjustedPosition = inViewport(attemptedPosition) ? position : FLIPPED_POSITION[position];
// adjust positions with (possibly) flipped position
var left = POSITIONS[adjustedPosition].left;
var top = POSITIONS[adjustedPosition].top;
return {
coordinates: { left: left, top: top },
position: adjustedPosition
position: adjustedPosition,
mousePosition: mousePosition
};
}

@@ -1,3 +0,2 @@

export { default as inViewport } from './inViewport';
export { default as getPosition } from './getPosition';
export { default as getStyle } from './getStyle';
{
"name": "@atlaskit/tooltip",
"version": "8.4.2"
"version": "9.0.0"
}
{
"name": "@atlaskit/tooltip",
"version": "9.0.0",
"version": "9.1.0",
"description": "A React Component for displaying Tooltips",

@@ -40,2 +40,2 @@ "license": "Apache-2.0",

]
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc