|
1 | 1 | 'use strict';
|
2 | 2 |
|
| 3 | +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; |
| 4 | + |
| 5 | +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; |
| 6 | + |
3 | 7 | Object.defineProperty(exports, "__esModule", {
|
4 | 8 | value: true
|
5 | 9 | });
|
6 | 10 | exports.position = position;
|
7 | 11 | exports.placement = placement;
|
| 12 | +exports.opposite = opposite; |
| 13 | +exports.intersection = intersection; |
| 14 | +exports.strip = strip; |
| 15 | +exports.amend = amend; |
| 16 | +exports.overDirs = overDirs; |
| 17 | +exports.adjust = adjust; |
8 | 18 | exports.resolve = resolve;
|
| 19 | + |
| 20 | +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } |
| 21 | + |
9 | 22 | /**
|
10 | 23 | * Returns a position of given DOM element.
|
11 | 24 | *
|
@@ -42,14 +55,14 @@ function position(el) {
|
42 | 55 | * @param {string} place - 'top', 'right', 'bottom', or 'left'.
|
43 | 56 | * @param {Object} tooltip - DOM element.
|
44 | 57 | * @param {Object} origin - DOM element.
|
45 |
| - * @return {Object} contains 'top' and 'left' keys. |
| 58 | + * @return {Object} contains 'top', 'left', and extra keys. |
46 | 59 | */
|
47 | 60 | function placement(place, tooltip, origin) {
|
48 | 61 | var gap = 12;
|
49 | 62 | var tip = position(tooltip);
|
50 | 63 | var pos = position(origin);
|
51 | 64 |
|
52 |
| - var offset = {}; |
| 65 | + var offset = { width: tip.width, height: tip.height }; |
53 | 66 |
|
54 | 67 | switch (place) {
|
55 | 68 | case 'top':case 'bottom':
|
@@ -78,6 +91,174 @@ function placement(place, tooltip, origin) {
|
78 | 91 | return offset;
|
79 | 92 | }
|
80 | 93 |
|
| 94 | +/** |
| 95 | + * Returns an opposite direction based on the given. |
| 96 | + * |
| 97 | + * @param {string|Array} dir - 'top', 'right', 'bottom', or 'left'. |
| 98 | + * @return {string} an opposite direction. |
| 99 | + * @throw |
| 100 | + */ |
| 101 | +function opposite(dir) { |
| 102 | + var place = dir; |
| 103 | + |
| 104 | + // Alrays use first direction if Array is passed |
| 105 | + if ((typeof place === 'undefined' ? 'undefined' : _typeof(place)) === 'object' && typeof place.length === 'number' && 0 < place.length) { |
| 106 | + place = place[0]; |
| 107 | + } |
| 108 | + |
| 109 | + switch (place) { |
| 110 | + case 'top': |
| 111 | + return 'bottom'; |
| 112 | + case 'bottom': |
| 113 | + return 'top'; |
| 114 | + case 'right': |
| 115 | + return 'left'; |
| 116 | + case 'left': |
| 117 | + return 'right'; |
| 118 | + } |
| 119 | + |
| 120 | + throw new Error('Unknown direction: "' + dir + '"'); |
| 121 | +} |
| 122 | + |
| 123 | +/** |
| 124 | + * Calculates an intersection of two areas. |
| 125 | + * |
| 126 | + * @param {Object} area1 |
| 127 | + * @param {Object} area2 |
| 128 | + * @return {Object} an intersection. |
| 129 | + */ |
| 130 | +function intersection(area1, area2) { |
| 131 | + var area = {}; |
| 132 | + area.top = Math.max(area1.top, area2.top); |
| 133 | + area.right = Math.min(area1.left + area1.width, area2.left + area2.width); |
| 134 | + area.bottom = Math.min(area1.top + area1.height, area2.top + area2.height); |
| 135 | + area.left = Math.max(area1.left, area2.left); |
| 136 | + area.height = area.bottom - area.top; |
| 137 | + area.width = area.right - area.left; |
| 138 | + return area; |
| 139 | +} |
| 140 | + |
| 141 | +function scrollOffset() { |
| 142 | + var list = [document.documentElement, document.body.parentNode, document.body]; |
| 143 | + return { |
| 144 | + top: list.map(function (el) { |
| 145 | + return el.scrollTop; |
| 146 | + }).reduce(function (p, v) { |
| 147 | + return p || v; |
| 148 | + }), |
| 149 | + left: list.map(function (el) { |
| 150 | + return el.scrollLeft; |
| 151 | + }).reduce(function (p, v) { |
| 152 | + return p || v; |
| 153 | + }) |
| 154 | + }; |
| 155 | +} |
| 156 | + |
| 157 | +// Returns current content area |
| 158 | +function contentArea() { |
| 159 | + return _extends({}, scrollOffset(), { |
| 160 | + height: window.innerHeight, |
| 161 | + width: window.innerWidth |
| 162 | + }); |
| 163 | +} |
| 164 | + |
| 165 | +// Strip unit string from property values and convert to float |
| 166 | +var STRIP_FOR = ['top', 'left', 'right', 'bottom', 'width', 'height']; |
| 167 | +function strip(obj) { |
| 168 | + var data = _extends({}, obj); |
| 169 | + STRIP_FOR.forEach(function (prop) { |
| 170 | + if (typeof data[prop] === 'string') { |
| 171 | + data[prop] = parseFloat(data[prop].replace('px', '')); |
| 172 | + } |
| 173 | + }); |
| 174 | + return data; |
| 175 | +} |
| 176 | + |
| 177 | +// Make full area data from minimum data |
| 178 | +function amend(area) { |
| 179 | + var data = strip(area); |
| 180 | + if (typeof data.top !== 'number') { |
| 181 | + data.top = 0; |
| 182 | + } |
| 183 | + if (typeof data.left !== 'number') { |
| 184 | + data.left = 0; |
| 185 | + } |
| 186 | + if (typeof data.right !== 'number' && typeof data.width === 'number') { |
| 187 | + data.right = data.left + data.width; |
| 188 | + } |
| 189 | + if (typeof data.bottom !== 'number' && typeof data.height === 'number') { |
| 190 | + data.bottom = data.top + data.height; |
| 191 | + } |
| 192 | + return data; |
| 193 | +} |
| 194 | + |
| 195 | +// Returns directions which are not in target rectangle |
| 196 | +function overDirs(tip, el) { |
| 197 | + tip = amend(tip); |
| 198 | + var area = amend(contentArea()); |
| 199 | + if (el && (typeof el === 'undefined' ? 'undefined' : _typeof(el)) === 'object') { |
| 200 | + area = intersection(area, position(el)); |
| 201 | + } |
| 202 | + |
| 203 | + var dirs = []; |
| 204 | + if (tip.top < area.top) { |
| 205 | + dirs.push('top'); |
| 206 | + } |
| 207 | + if (area.right < tip.right) { |
| 208 | + dirs.push('right'); |
| 209 | + } |
| 210 | + if (area.bottom < tip.bottom) { |
| 211 | + dirs.push('bottom'); |
| 212 | + } |
| 213 | + if (tip.left < area.left) { |
| 214 | + dirs.push('left'); |
| 215 | + } |
| 216 | + |
| 217 | + return dirs; |
| 218 | +} |
| 219 | + |
| 220 | +/** |
| 221 | + * Places and adjusts a tooltip. |
| 222 | + * |
| 223 | + * @param {Object} tooltip - DOM element. |
| 224 | + * @param {string|Array} place |
| 225 | + * @param {Object} origin - DOM element. |
| 226 | + * @return {Object} 'offset': style data to locate, 'place': final direction of the tooltip |
| 227 | + */ |
| 228 | +function adjust(tooltip, props) { |
| 229 | + var origin = props.el; |
| 230 | + var auto = props.auto; |
| 231 | + var within = props.within; |
| 232 | + var place = props.place; |
| 233 | + |
| 234 | + if (auto && typeof place === 'string') { |
| 235 | + place = place.split(',').map(function (p) { |
| 236 | + return p.trim(); |
| 237 | + }); |
| 238 | + } |
| 239 | + if (place.length === 1) { |
| 240 | + place.push(opposite(place)); |
| 241 | + } |
| 242 | + |
| 243 | + var pos = undefined, |
| 244 | + dirs = undefined, |
| 245 | + current = undefined, |
| 246 | + first = undefined; |
| 247 | + var tries = [].concat(_toConsumableArray(place)); |
| 248 | + while (0 < tries.length) { |
| 249 | + current = tries.shift(); |
| 250 | + pos = placement(current, tooltip, origin); |
| 251 | + if (typeof first === 'undefined') { |
| 252 | + first = { offset: pos, place: current }; |
| 253 | + } |
| 254 | + dirs = overDirs(pos, within && within()); |
| 255 | + if (dirs.length === 0) { |
| 256 | + return { offset: pos, place: current }; |
| 257 | + } |
| 258 | + } |
| 259 | + return first; |
| 260 | +} |
| 261 | + |
81 | 262 | /**
|
82 | 263 | * Resolves names of target tooltip from action or props.
|
83 | 264 | *
|
|
0 commit comments