This repository was archived by the owner on Mar 4, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathpositioningHelper.ts
More file actions
96 lines (85 loc) · 2.95 KB
/
positioningHelper.ts
File metadata and controls
96 lines (85 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { Placement } from '@popperjs/core'
import { Alignment, Position } from './types'
enum PlacementParts {
top = 'top',
bottom = 'bottom',
start = 'start',
end = 'end',
left = 'left',
right = 'right',
center = '',
}
const getPositionMap = (rtl: boolean): Record<Position, PlacementParts> => ({
above: PlacementParts.top,
below: PlacementParts.bottom,
before: rtl ? PlacementParts.right : PlacementParts.left,
after: rtl ? PlacementParts.left : PlacementParts.right,
})
const getAlignmentMap = (rtl: boolean): Record<Alignment, PlacementParts> => ({
start: rtl ? PlacementParts.end : PlacementParts.start,
end: rtl ? PlacementParts.start : PlacementParts.end,
top: PlacementParts.start,
bottom: PlacementParts.end,
center: PlacementParts.center,
})
const shouldAlignToCenter = (p: Position, a: Alignment) => {
const positionedVertically = p === 'above' || p === 'below'
const alignedVertically = a === 'top' || a === 'bottom'
return (
(positionedVertically && alignedVertically) || (!positionedVertically && !alignedVertically)
)
}
/**
* | position | alignment | placement | placement RTL
* -----------------------------------------------------------------
* | above | start | top-start | top-end
* | above | center | top | top
* | above | end | top-end | top-start
* | below | start | bottom-start | bottom-end
* | below | center | bottom | bottom
* | below | end | bottom-end | bottom-start
* | before | top | left-start | right-start
* | before | center | left | right
* | before | bottom | left-end | right-end
* | after | top | right-start | left-start
* | after | center | right | left
* | after | bottom | right-end | left-end
*/
export const getPlacement = ({
align,
position,
rtl,
}: {
align: Alignment
position: Position
rtl: boolean
}): Placement => {
const alignment: Alignment = shouldAlignToCenter(position, align) ? 'center' : align
const computedPosition = getPositionMap(rtl)[position]
const computedAlignmnent = getAlignmentMap(rtl)[alignment]
const stringifiedAlignment = computedAlignmnent && `-${computedAlignmnent}`
return `${computedPosition}${stringifiedAlignment}` as Placement
}
//
// OFFSET VALUES ADJUSTMENT
//
const flipPlusMinusSigns = (offset: string): string => {
return offset
.replace(/\-/g, '<plus>')
.replace(/^(\s*)(?=\d)/, '<minus>')
.replace(/\+/g, '<minus>')
.replace(/<plus>/g, '+')
.replace(/<minus>/g, '-')
.trimLeft()
.replace(/^\+/, '')
}
export const applyRtlToOffset = (offset: string, position: Position): string => {
if (position === 'above' || position === 'below') {
const [horizontal, vertical] = offset.split(',')
return [flipPlusMinusSigns(horizontal), vertical]
.join(', ')
.replace(/, $/, '')
.trim()
}
return offset
}