@@ -7,51 +7,71 @@ export default function (Alpine) {
7
7
return el . _x_anchor
8
8
} )
9
9
10
- Alpine . directive ( 'anchor' , ( el , { expression, modifiers, value } , { cleanup, evaluate } ) => {
10
+ Alpine . interceptClone ( ( from , to ) => {
11
+ if ( from && from . _x_anchor && ! to . _x_anchor ) {
12
+ to . _x_anchor = from . _x_anchor
13
+ }
14
+ } )
15
+
16
+ Alpine . directive ( 'anchor' , Alpine . skipDuringClone ( ( el , { expression, modifiers, value } , { cleanup, evaluate } ) => {
17
+ let { placement, offsetValue, unstyled } = getOptions ( modifiers )
18
+
11
19
el . _x_anchor = Alpine . reactive ( { x : 0 , y : 0 } )
12
20
13
21
let reference = evaluate ( expression )
14
22
15
23
if ( ! reference ) throw 'Alpine: no element provided to x-anchor...'
16
24
17
- let positions = [ 'top' , 'top-start' , 'top-end' , 'right' , 'right-start' , 'right-end' , 'bottom' , 'bottom-start' , 'bottom-end' , 'left' , 'left-start' , 'left-end' ]
18
- let placement = positions . find ( i => modifiers . includes ( i ) )
19
-
20
- let offsetValue = 0
21
-
22
- let unstyled = modifiers . includes ( 'no-style' )
23
-
24
- if ( modifiers . includes ( 'offset' ) ) {
25
- let idx = modifiers . findIndex ( i => i === 'offset' )
26
-
27
- offsetValue = modifiers [ idx + 1 ] !== undefined ? Number ( modifiers [ idx + 1 ] ) : offsetValue
28
- }
29
-
30
- let release = autoUpdate ( reference , el , ( ) => {
25
+ let compute = ( ) => {
31
26
let previousValue
32
27
33
28
computePosition ( reference , el , {
34
29
placement,
35
30
middleware : [ flip ( ) , shift ( { padding : 5 } ) , offset ( offsetValue ) ] ,
36
31
} ) . then ( ( { x, y } ) => {
32
+ unstyled || setStyles ( el , x , y )
33
+
37
34
// Only trigger Alpine reactivity when the value actually changes...
38
35
if ( JSON . stringify ( { x, y } ) !== previousValue ) {
39
- unstyled || setStyles ( el , x , y )
40
-
41
36
el . _x_anchor . x = x
42
37
el . _x_anchor . y = y
43
38
}
44
39
45
40
previousValue = JSON . stringify ( { x, y } )
46
41
} )
47
- } )
42
+ }
43
+
44
+ let release = autoUpdate ( reference , el , ( ) => compute ( ) )
48
45
49
46
cleanup ( ( ) => release ( ) )
50
- } )
47
+ } ,
48
+
49
+ // When cloning (or "morphing"), we will graft the style and position data from the live tree...
50
+ ( el , { expression, modifiers, value } , { cleanup, evaluate } ) => {
51
+ let { placement, offsetValue, unstyled } = getOptions ( modifiers )
52
+
53
+ if ( el . _x_anchor ) {
54
+ unstyled || setStyles ( el , el . _x_anchor . x , el . _x_anchor . y )
55
+ }
56
+ } ) )
51
57
}
52
58
53
59
function setStyles ( el , x , y ) {
54
60
Object . assign ( el . style , {
55
61
left : x + 'px' , top : y + 'px' , position : 'absolute' ,
56
62
} )
57
63
}
64
+
65
+ function getOptions ( modifiers ) {
66
+ let positions = [ 'top' , 'top-start' , 'top-end' , 'right' , 'right-start' , 'right-end' , 'bottom' , 'bottom-start' , 'bottom-end' , 'left' , 'left-start' , 'left-end' ]
67
+ let placement = positions . find ( i => modifiers . includes ( i ) )
68
+ let offsetValue = 0
69
+ if ( modifiers . includes ( 'offset' ) ) {
70
+ let idx = modifiers . findIndex ( i => i === 'offset' )
71
+
72
+ offsetValue = modifiers [ idx + 1 ] !== undefined ? Number ( modifiers [ idx + 1 ] ) : offsetValue
73
+ }
74
+ let unstyled = modifiers . includes ( 'no-style' )
75
+
76
+ return { placement, offsetValue, unstyled }
77
+ }
0 commit comments