-
Notifications
You must be signed in to change notification settings - Fork 13.5k
/
Copy pathmd.enter.ts
108 lines (92 loc) · 3.14 KB
/
md.enter.ts
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
97
98
99
100
101
102
103
104
105
106
107
108
import { createAnimation } from '@utils/animation/animation';
import { getElementRoot } from '@utils/helpers';
import type { Animation } from '../../../interface';
import { calculateWindowAdjustment, getPopoverDimensions, getPopoverPosition } from '../utils';
const POPOVER_MD_BODY_PADDING = 12;
/**
* Md Popover Enter Animation
*/
// TODO(FW-2832): types
export const mdEnterAnimation = (baseEl: HTMLElement, opts?: any): Animation => {
const { event: ev, size, trigger, reference, side, align } = opts;
const doc = baseEl.ownerDocument as any;
const isRTL = doc.dir === 'rtl';
const bodyWidth = doc.defaultView.innerWidth;
const bodyHeight = doc.defaultView.innerHeight;
const root = getElementRoot(baseEl);
const contentEl = root.querySelector('.popover-content') as HTMLElement;
const referenceSizeEl = trigger || ev?.detail?.ionShadowTarget || ev?.target;
const { contentWidth, contentHeight } = getPopoverDimensions(size, contentEl, referenceSizeEl);
const defaultPosition = {
top: bodyHeight / 2 - contentHeight / 2,
left: bodyWidth / 2 - contentWidth / 2,
originX: isRTL ? 'right' : 'left',
originY: 'top',
};
const results = getPopoverPosition(
isRTL,
contentWidth,
contentHeight,
0,
0,
reference,
side,
align,
defaultPosition,
trigger,
ev
);
const padding = size === 'cover' ? 0 : POPOVER_MD_BODY_PADDING;
const { originX, originY, top, left, bottom } = calculateWindowAdjustment(
side,
results.top,
results.left,
padding,
bodyWidth,
bodyHeight,
contentWidth,
contentHeight,
results.originX,
results.originY,
results.referenceCoordinates
);
const baseAnimation = createAnimation();
const backdropAnimation = createAnimation();
const wrapperAnimation = createAnimation();
const contentAnimation = createAnimation();
const viewportAnimation = createAnimation();
backdropAnimation
.addElement(root.querySelector('ion-backdrop')!)
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
.beforeStyles({
'pointer-events': 'none',
})
.afterClearStyles(['pointer-events']);
wrapperAnimation.addElement(root.querySelector('.popover-wrapper')!).duration(150).fromTo('opacity', 0.01, 1);
contentAnimation
.addElement(contentEl)
.beforeStyles({
top: `calc(${top}px + var(--offset-y, 0px))`,
left: `calc(${left}px + var(--offset-x, 0px))`,
'transform-origin': `${originY} ${originX}`,
})
.beforeAddWrite(() => {
if (bottom !== undefined) {
contentEl.style.setProperty('bottom', `${bottom}px`);
}
})
.fromTo('transform', 'scale(0.8)', 'scale(1)');
viewportAnimation.addElement(root.querySelector('.popover-viewport')!).fromTo('opacity', 0.01, 1);
return baseAnimation
.easing('cubic-bezier(0.36,0.66,0.04,1)')
.duration(300)
.beforeAddWrite(() => {
if (size === 'cover') {
baseEl.style.setProperty('--width', `${contentWidth}px`);
}
if (originY === 'bottom') {
baseEl.classList.add('popover-bottom');
}
})
.addAnimation([backdropAnimation, wrapperAnimation, contentAnimation, viewportAnimation]);
};