1 | // @flow
|
---|
2 | import getBasePlacement from './getBasePlacement';
|
---|
3 | import getVariation from './getVariation';
|
---|
4 | import getMainAxisFromPlacement from './getMainAxisFromPlacement';
|
---|
5 | import type {
|
---|
6 | Rect,
|
---|
7 | PositioningStrategy,
|
---|
8 | Offsets,
|
---|
9 | ClientRectObject,
|
---|
10 | } from '../types';
|
---|
11 | import { top, right, bottom, left, start, end, type Placement } from '../enums';
|
---|
12 |
|
---|
13 | export default function computeOffsets({
|
---|
14 | reference,
|
---|
15 | element,
|
---|
16 | placement,
|
---|
17 | }: {
|
---|
18 | reference: Rect | ClientRectObject,
|
---|
19 | element: Rect | ClientRectObject,
|
---|
20 | strategy: PositioningStrategy,
|
---|
21 | placement?: Placement,
|
---|
22 | }): Offsets {
|
---|
23 | const basePlacement = placement ? getBasePlacement(placement) : null;
|
---|
24 | const variation = placement ? getVariation(placement) : null;
|
---|
25 | const commonX = reference.x + reference.width / 2 - element.width / 2;
|
---|
26 | const commonY = reference.y + reference.height / 2 - element.height / 2;
|
---|
27 |
|
---|
28 | let offsets;
|
---|
29 | switch (basePlacement) {
|
---|
30 | case top:
|
---|
31 | offsets = {
|
---|
32 | x: commonX,
|
---|
33 | y: reference.y - element.height,
|
---|
34 | };
|
---|
35 | break;
|
---|
36 | case bottom:
|
---|
37 | offsets = {
|
---|
38 | x: commonX,
|
---|
39 | y: reference.y + reference.height,
|
---|
40 | };
|
---|
41 | break;
|
---|
42 | case right:
|
---|
43 | offsets = {
|
---|
44 | x: reference.x + reference.width,
|
---|
45 | y: commonY,
|
---|
46 | };
|
---|
47 | break;
|
---|
48 | case left:
|
---|
49 | offsets = {
|
---|
50 | x: reference.x - element.width,
|
---|
51 | y: commonY,
|
---|
52 | };
|
---|
53 | break;
|
---|
54 | default:
|
---|
55 | offsets = {
|
---|
56 | x: reference.x,
|
---|
57 | y: reference.y,
|
---|
58 | };
|
---|
59 | }
|
---|
60 |
|
---|
61 | const mainAxis = basePlacement
|
---|
62 | ? getMainAxisFromPlacement(basePlacement)
|
---|
63 | : null;
|
---|
64 |
|
---|
65 | if (mainAxis != null) {
|
---|
66 | const len = mainAxis === 'y' ? 'height' : 'width';
|
---|
67 |
|
---|
68 | switch (variation) {
|
---|
69 | case start:
|
---|
70 | offsets[mainAxis] =
|
---|
71 | offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);
|
---|
72 | break;
|
---|
73 | case end:
|
---|
74 | offsets[mainAxis] =
|
---|
75 | offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);
|
---|
76 | break;
|
---|
77 | default:
|
---|
78 | }
|
---|
79 | }
|
---|
80 |
|
---|
81 | return offsets;
|
---|
82 | }
|
---|