@@ -12,6 +12,7 @@ import { ArrowPosition } from '../types';
12
12
type ArrowOptions = {
13
13
size ?: string ;
14
14
inset ?: string ;
15
+ shift ?: string ;
15
16
animationModifier ?: string ;
16
17
} ;
17
18
@@ -34,7 +35,7 @@ const animationStyles = (position: ArrowPosition, modifier: string) => {
34
35
` ;
35
36
} ;
36
37
37
- const positionStyles = ( position : ArrowPosition , size : number , inset : number ) => {
38
+ const positionStyles = ( position : ArrowPosition , size : number , inset : number , shift : number ) => {
38
39
/** Overlap the arrow with the base element's border.
39
40
* This value + rounding have been found to work well regardless of monitor pixel density and browser.
40
41
*/
@@ -44,7 +45,7 @@ const positionStyles = (position: ArrowPosition, size: number, inset: number) =>
44
45
45
46
const marginPx = `${ margin } px` ;
46
47
const placementPx = `${ placement } px` ;
47
- const sizePx = `${ size } px` ;
48
+ const offsetPx = `${ size + shift } px` ;
48
49
49
50
let positionCss ;
50
51
let transform ;
@@ -53,31 +54,31 @@ const positionStyles = (position: ArrowPosition, size: number, inset: number) =>
53
54
transform = 'rotate(-135deg)' ;
54
55
positionCss = css `
55
56
top : ${ placementPx } ;
56
- right : ${ position === 'top-right' && sizePx } ;
57
- left : ${ position === 'top' ? '50%' : position === 'top-left' && sizePx } ;
57
+ right : ${ position === 'top-right' && offsetPx } ;
58
+ left : ${ position === 'top' ? '50%' : position === 'top-left' && offsetPx } ;
58
59
margin-left : ${ position === 'top' && marginPx } ;
59
60
` ;
60
61
} else if ( position . startsWith ( 'right' ) ) {
61
62
transform = 'rotate(-45deg)' ;
62
63
positionCss = css `
63
- top : ${ position === 'right' ? '50%' : position === 'right-top' && sizePx } ;
64
+ top : ${ position === 'right' ? '50%' : position === 'right-top' && offsetPx } ;
64
65
right : ${ placementPx } ;
65
- bottom : ${ position === 'right-bottom' && sizePx } ;
66
+ bottom : ${ position === 'right-bottom' && offsetPx } ;
66
67
margin-top : ${ position === 'right' && marginPx } ;
67
68
` ;
68
69
} else if ( position . startsWith ( 'bottom' ) ) {
69
70
transform = 'rotate(45deg)' ;
70
71
positionCss = css `
71
- right : ${ position === 'bottom-right' && sizePx } ;
72
+ right : ${ position === 'bottom-right' && offsetPx } ;
72
73
bottom : ${ placementPx } ;
73
- left : ${ position === 'bottom' ? '50%' : position === 'bottom-left' && sizePx } ;
74
+ left : ${ position === 'bottom' ? '50%' : position === 'bottom-left' && offsetPx } ;
74
75
margin-left : ${ position === 'bottom' && marginPx } ;
75
76
` ;
76
77
} else if ( position . startsWith ( 'left' ) ) {
77
78
transform = 'rotate(135deg)' ;
78
79
positionCss = css `
79
- top : ${ position === 'left' ? '50%' : position === 'left-top' && sizePx } ;
80
- bottom : ${ size } ;
80
+ top : ${ position === 'left' ? '50%' : position === 'left-top' && offsetPx } ;
81
+ bottom : ${ offsetPx } ;
81
82
left : ${ placementPx } ;
82
83
margin-top : ${ position === 'left' && marginPx } ;
83
84
` ;
@@ -123,6 +124,8 @@ const positionStyles = (position: ArrowPosition, size: number, inset: number) =>
123
124
* (right angle) of the arrow expressed as a CSS dimension.
124
125
* @param {string } [options.inset='0'] Tweak arrow positioning by adjusting with
125
126
* either a positive (push the arrow in) or negative (pull the arrow out) value.
127
+ * @param {string } [options.shift='0'] Shifts arrow positioning along
128
+ * the edge of the parent container.
126
129
* @param {string } [options.animationModifier] A CSS class or attribute selector
127
130
* which, when applied, animates the arrow's appearance.
128
131
*
@@ -131,6 +134,7 @@ const positionStyles = (position: ArrowPosition, size: number, inset: number) =>
131
134
export default function arrowStyles ( position : ArrowPosition , options : ArrowOptions = { } ) {
132
135
const inset = stripUnit ( options . inset || '0' ) as number ;
133
136
const size = stripUnit ( options . size || '6' ) as number ;
137
+ const shift = stripUnit ( options . shift || '0' ) as number ;
134
138
135
139
/**
136
140
* Adjusts the size to account for the overlap between the arrow and the base element.
@@ -181,7 +185,7 @@ export default function arrowStyles(position: ArrowPosition, options: ArrowOptio
181
185
clip-path : polygon (100% ${ afterOffset } px, ${ afterOffset } px 100% , 100% 100% ); /* [5] */
182
186
}
183
187
184
- ${ positionStyles ( position , squareSizeRounded , inset ) } ;
188
+ ${ positionStyles ( position , squareSizeRounded , inset , shift ) } ;
185
189
${ options . animationModifier && animationStyles ( position , options . animationModifier ) } ;
186
190
` ;
187
191
}
0 commit comments