@rc-component/trigger 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +321 -0
- package/assets/index/Mask.less +63 -0
- package/assets/index/Mobile.less +25 -0
- package/assets/index.css +133 -0
- package/assets/index.less +79 -0
- package/es/Popup/Arrow.d.ts +9 -0
- package/es/Popup/Arrow.js +47 -0
- package/es/Popup/Mask.d.ts +10 -0
- package/es/Popup/Mask.js +26 -0
- package/es/Popup/index.d.ts +39 -0
- package/es/Popup/index.js +149 -0
- package/es/TriggerWrapper.d.ts +8 -0
- package/es/TriggerWrapper.js +19 -0
- package/es/context.d.ts +6 -0
- package/es/context.js +3 -0
- package/es/hooks/useAction.d.ts +4 -0
- package/es/hooks/useAction.js +8 -0
- package/es/hooks/useAlign.d.ts +12 -0
- package/es/hooks/useAlign.js +275 -0
- package/es/hooks/useWatch.d.ts +1 -0
- package/es/hooks/useWatch.js +50 -0
- package/es/index.d.ts +61 -0
- package/es/index.js +448 -0
- package/es/interface.d.ts +122 -0
- package/es/interface.js +1 -0
- package/es/util.d.ts +7 -0
- package/es/util.js +47 -0
- package/lib/Popup/Arrow.d.ts +9 -0
- package/lib/Popup/Arrow.js +54 -0
- package/lib/Popup/Mask.d.ts +10 -0
- package/lib/Popup/Mask.js +33 -0
- package/lib/Popup/index.d.ts +39 -0
- package/lib/Popup/index.js +158 -0
- package/lib/TriggerWrapper.d.ts +8 -0
- package/lib/TriggerWrapper.js +27 -0
- package/lib/context.d.ts +6 -0
- package/lib/context.js +11 -0
- package/lib/hooks/useAction.d.ts +4 -0
- package/lib/hooks/useAction.js +14 -0
- package/lib/hooks/useAlign.d.ts +12 -0
- package/lib/hooks/useAlign.js +283 -0
- package/lib/hooks/useWatch.d.ts +1 -0
- package/lib/hooks/useWatch.js +57 -0
- package/lib/index.d.ts +61 -0
- package/lib/index.js +457 -0
- package/lib/interface.d.ts +122 -0
- package/lib/interface.js +5 -0
- package/lib/util.d.ts +7 -0
- package/lib/util.js +57 -0
- package/package.json +79 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { CSSMotionProps } from 'rc-motion';
|
|
3
|
+
export interface MaskProps {
|
|
4
|
+
prefixCls: string;
|
|
5
|
+
open?: boolean;
|
|
6
|
+
zIndex?: number;
|
|
7
|
+
mask?: boolean;
|
|
8
|
+
motion?: CSSMotionProps;
|
|
9
|
+
}
|
|
10
|
+
export default function Mask(props: MaskProps): JSX.Element;
|
package/es/Popup/Mask.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import CSSMotion from 'rc-motion';
|
|
4
|
+
export default function Mask(props) {
|
|
5
|
+
var prefixCls = props.prefixCls,
|
|
6
|
+
open = props.open,
|
|
7
|
+
zIndex = props.zIndex,
|
|
8
|
+
mask = props.mask,
|
|
9
|
+
motion = props.motion;
|
|
10
|
+
if (!mask) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return /*#__PURE__*/React.createElement(CSSMotion, _extends({}, motion, {
|
|
14
|
+
motionAppear: true,
|
|
15
|
+
visible: open,
|
|
16
|
+
removeOnLeave: true
|
|
17
|
+
}), function (_ref) {
|
|
18
|
+
var className = _ref.className;
|
|
19
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
20
|
+
style: {
|
|
21
|
+
zIndex: zIndex
|
|
22
|
+
},
|
|
23
|
+
className: classNames("".concat(prefixCls, "-mask"), className)
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { CSSMotionProps } from 'rc-motion';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import type { TriggerProps } from '../';
|
|
4
|
+
import type { AlignType } from '../interface';
|
|
5
|
+
export interface PopupProps {
|
|
6
|
+
prefixCls: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
style?: React.CSSProperties;
|
|
9
|
+
popup?: TriggerProps['popup'];
|
|
10
|
+
target: HTMLElement;
|
|
11
|
+
onMouseEnter?: React.MouseEventHandler<HTMLDivElement>;
|
|
12
|
+
onMouseLeave?: React.MouseEventHandler<HTMLDivElement>;
|
|
13
|
+
zIndex?: number;
|
|
14
|
+
mask?: boolean;
|
|
15
|
+
onVisibleChanged: (visible: boolean) => void;
|
|
16
|
+
align?: AlignType;
|
|
17
|
+
arrow?: boolean;
|
|
18
|
+
arrowX?: number;
|
|
19
|
+
arrowY?: number;
|
|
20
|
+
open: boolean;
|
|
21
|
+
/** Tell Portal that should keep in screen. e.g. should wait all motion end */
|
|
22
|
+
keepDom: boolean;
|
|
23
|
+
onClick?: React.MouseEventHandler<HTMLDivElement>;
|
|
24
|
+
motion?: CSSMotionProps;
|
|
25
|
+
maskMotion?: CSSMotionProps;
|
|
26
|
+
forceRender?: boolean;
|
|
27
|
+
getPopupContainer?: TriggerProps['getPopupContainer'];
|
|
28
|
+
autoDestroy?: boolean;
|
|
29
|
+
ready: boolean;
|
|
30
|
+
offsetX: number;
|
|
31
|
+
offsetY: number;
|
|
32
|
+
onAlign: VoidFunction;
|
|
33
|
+
onPrepare: () => Promise<void>;
|
|
34
|
+
stretch?: string;
|
|
35
|
+
targetWidth?: number;
|
|
36
|
+
targetHeight?: number;
|
|
37
|
+
}
|
|
38
|
+
declare const Popup: React.ForwardRefExoticComponent<PopupProps & React.RefAttributes<HTMLDivElement>>;
|
|
39
|
+
export default Popup;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
3
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
4
|
+
import Portal from '@rc-component/portal';
|
|
5
|
+
import classNames from 'classnames';
|
|
6
|
+
import CSSMotion from 'rc-motion';
|
|
7
|
+
import ResizeObserver from 'rc-resize-observer';
|
|
8
|
+
import useLayoutEffect from "rc-util/es/hooks/useLayoutEffect";
|
|
9
|
+
import * as React from 'react';
|
|
10
|
+
import Arrow from "./Arrow";
|
|
11
|
+
import Mask from "./Mask";
|
|
12
|
+
var Popup = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
13
|
+
var popup = props.popup,
|
|
14
|
+
className = props.className,
|
|
15
|
+
prefixCls = props.prefixCls,
|
|
16
|
+
style = props.style,
|
|
17
|
+
target = props.target,
|
|
18
|
+
_onVisibleChanged = props.onVisibleChanged,
|
|
19
|
+
open = props.open,
|
|
20
|
+
keepDom = props.keepDom,
|
|
21
|
+
onClick = props.onClick,
|
|
22
|
+
mask = props.mask,
|
|
23
|
+
arrow = props.arrow,
|
|
24
|
+
align = props.align,
|
|
25
|
+
arrowX = props.arrowX,
|
|
26
|
+
arrowY = props.arrowY,
|
|
27
|
+
motion = props.motion,
|
|
28
|
+
maskMotion = props.maskMotion,
|
|
29
|
+
forceRender = props.forceRender,
|
|
30
|
+
getPopupContainer = props.getPopupContainer,
|
|
31
|
+
autoDestroy = props.autoDestroy,
|
|
32
|
+
zIndex = props.zIndex,
|
|
33
|
+
onMouseEnter = props.onMouseEnter,
|
|
34
|
+
onMouseLeave = props.onMouseLeave,
|
|
35
|
+
ready = props.ready,
|
|
36
|
+
offsetX = props.offsetX,
|
|
37
|
+
offsetY = props.offsetY,
|
|
38
|
+
onAlign = props.onAlign,
|
|
39
|
+
onPrepare = props.onPrepare,
|
|
40
|
+
stretch = props.stretch,
|
|
41
|
+
targetWidth = props.targetWidth,
|
|
42
|
+
targetHeight = props.targetHeight;
|
|
43
|
+
var childNode = typeof popup === 'function' ? popup() : popup;
|
|
44
|
+
|
|
45
|
+
// We can not remove holder only when motion finished.
|
|
46
|
+
var isNodeVisible = open || keepDom;
|
|
47
|
+
|
|
48
|
+
// ======================= Container ========================
|
|
49
|
+
var getPopupContainerNeedParams = (getPopupContainer === null || getPopupContainer === void 0 ? void 0 : getPopupContainer.length) > 0;
|
|
50
|
+
var _React$useState = React.useState(!getPopupContainer || !getPopupContainerNeedParams),
|
|
51
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
52
|
+
show = _React$useState2[0],
|
|
53
|
+
setShow = _React$useState2[1];
|
|
54
|
+
|
|
55
|
+
// Delay to show since `getPopupContainer` need target element
|
|
56
|
+
useLayoutEffect(function () {
|
|
57
|
+
if (!show && getPopupContainerNeedParams && target) {
|
|
58
|
+
setShow(true);
|
|
59
|
+
}
|
|
60
|
+
}, [show, getPopupContainerNeedParams, target]);
|
|
61
|
+
|
|
62
|
+
// ========================= Render =========================
|
|
63
|
+
if (!show) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// >>>>> Offset
|
|
68
|
+
var offsetStyle = ready || !open ? {
|
|
69
|
+
left: offsetX,
|
|
70
|
+
top: offsetY
|
|
71
|
+
} : {
|
|
72
|
+
left: '-1000vw',
|
|
73
|
+
top: '-1000vh'
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// >>>>> Misc
|
|
77
|
+
var miscStyle = {};
|
|
78
|
+
if (stretch) {
|
|
79
|
+
if (stretch.includes('height') && targetHeight) {
|
|
80
|
+
miscStyle.height = targetHeight;
|
|
81
|
+
} else if (stretch.includes('minHeight') && targetHeight) {
|
|
82
|
+
miscStyle.minHeight = targetHeight;
|
|
83
|
+
}
|
|
84
|
+
if (stretch.includes('width') && targetWidth) {
|
|
85
|
+
miscStyle.width = targetWidth;
|
|
86
|
+
} else if (stretch.includes('minWidth') && targetWidth) {
|
|
87
|
+
miscStyle.minWidth = targetWidth;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (!open) {
|
|
91
|
+
miscStyle.pointerEvents = 'none';
|
|
92
|
+
}
|
|
93
|
+
return /*#__PURE__*/React.createElement(Portal, {
|
|
94
|
+
open: forceRender || isNodeVisible,
|
|
95
|
+
getContainer: getPopupContainer && function () {
|
|
96
|
+
return getPopupContainer(target);
|
|
97
|
+
},
|
|
98
|
+
autoDestroy: autoDestroy
|
|
99
|
+
}, /*#__PURE__*/React.createElement(Mask, {
|
|
100
|
+
prefixCls: prefixCls,
|
|
101
|
+
open: open,
|
|
102
|
+
zIndex: zIndex,
|
|
103
|
+
mask: mask,
|
|
104
|
+
motion: maskMotion
|
|
105
|
+
}), /*#__PURE__*/React.createElement(ResizeObserver, {
|
|
106
|
+
onResize: onAlign,
|
|
107
|
+
disabled: !open
|
|
108
|
+
}, /*#__PURE__*/React.createElement(CSSMotion, _extends({
|
|
109
|
+
motionAppear: true,
|
|
110
|
+
motionEnter: true,
|
|
111
|
+
motionLeave: true,
|
|
112
|
+
removeOnLeave: false,
|
|
113
|
+
forceRender: forceRender,
|
|
114
|
+
leavedClassName: "".concat(prefixCls, "-hidden")
|
|
115
|
+
}, motion, {
|
|
116
|
+
onAppearPrepare: onPrepare,
|
|
117
|
+
onEnterPrepare: onPrepare,
|
|
118
|
+
visible: open,
|
|
119
|
+
onVisibleChanged: function onVisibleChanged(nextVisible) {
|
|
120
|
+
var _motion$onVisibleChan;
|
|
121
|
+
motion === null || motion === void 0 ? void 0 : (_motion$onVisibleChan = motion.onVisibleChanged) === null || _motion$onVisibleChan === void 0 ? void 0 : _motion$onVisibleChan.call(motion, nextVisible);
|
|
122
|
+
_onVisibleChanged(nextVisible);
|
|
123
|
+
}
|
|
124
|
+
}), function (_ref) {
|
|
125
|
+
var motionClassName = _ref.className,
|
|
126
|
+
motionStyle = _ref.style;
|
|
127
|
+
var cls = classNames(prefixCls, motionClassName, className);
|
|
128
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
129
|
+
ref: ref,
|
|
130
|
+
className: cls,
|
|
131
|
+
style: _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, offsetStyle), miscStyle), motionStyle), {}, {
|
|
132
|
+
boxSizing: 'border-box',
|
|
133
|
+
zIndex: zIndex
|
|
134
|
+
}, style),
|
|
135
|
+
onMouseEnter: onMouseEnter,
|
|
136
|
+
onMouseLeave: onMouseLeave,
|
|
137
|
+
onClick: onClick
|
|
138
|
+
}, arrow && /*#__PURE__*/React.createElement(Arrow, {
|
|
139
|
+
prefixCls: prefixCls,
|
|
140
|
+
align: align,
|
|
141
|
+
arrowX: arrowX,
|
|
142
|
+
arrowY: arrowY
|
|
143
|
+
}), childNode);
|
|
144
|
+
})));
|
|
145
|
+
});
|
|
146
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
147
|
+
Popup.displayName = 'Popup';
|
|
148
|
+
}
|
|
149
|
+
export default Popup;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { TriggerProps } from '.';
|
|
3
|
+
export interface TriggerWrapperProps {
|
|
4
|
+
getTriggerDOMNode?: TriggerProps['getTriggerDOMNode'];
|
|
5
|
+
children: React.ReactElement;
|
|
6
|
+
}
|
|
7
|
+
declare const TriggerWrapper: React.ForwardRefExoticComponent<TriggerWrapperProps & React.RefAttributes<HTMLElement>>;
|
|
8
|
+
export default TriggerWrapper;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { fillRef, useComposeRef } from "rc-util/es/ref";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
var TriggerWrapper = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
4
|
+
var children = props.children,
|
|
5
|
+
getTriggerDOMNode = props.getTriggerDOMNode;
|
|
6
|
+
|
|
7
|
+
// When use `getTriggerDOMNode`, we should do additional work to get the real dom
|
|
8
|
+
var setRef = React.useCallback(function (node) {
|
|
9
|
+
fillRef(ref, getTriggerDOMNode ? getTriggerDOMNode(node) : node);
|
|
10
|
+
}, [getTriggerDOMNode]);
|
|
11
|
+
var mergedRef = useComposeRef(setRef, children.ref);
|
|
12
|
+
return /*#__PURE__*/React.cloneElement(children, {
|
|
13
|
+
ref: mergedRef
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
17
|
+
TriggerWrapper.displayName = 'TriggerWrapper';
|
|
18
|
+
}
|
|
19
|
+
export default TriggerWrapper;
|
package/es/context.d.ts
ADDED
package/es/context.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ActionType } from '../interface';
|
|
2
|
+
declare type ActionTypes = ActionType | ActionType[];
|
|
3
|
+
export default function useAction(action: ActionTypes, showAction?: ActionTypes, hideAction?: ActionTypes): [showAction: Set<ActionType>, hideAction: Set<ActionType>];
|
|
4
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
function toArray(val) {
|
|
2
|
+
return val ? Array.isArray(val) ? val : [val] : [];
|
|
3
|
+
}
|
|
4
|
+
export default function useAction(action, showAction, hideAction) {
|
|
5
|
+
var mergedShowAction = toArray(showAction !== null && showAction !== void 0 ? showAction : action);
|
|
6
|
+
var mergedHideAction = toArray(hideAction !== null && hideAction !== void 0 ? hideAction : action);
|
|
7
|
+
return [new Set(mergedShowAction), new Set(mergedHideAction)];
|
|
8
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AlignType } from '../interface';
|
|
2
|
+
export default function useAlign(open: boolean, popupEle: HTMLElement, target: HTMLElement | [x: number, y: number], placement: string, builtinPlacements: any, popupAlign?: AlignType): [
|
|
3
|
+
ready: boolean,
|
|
4
|
+
offsetX: number,
|
|
5
|
+
offsetY: number,
|
|
6
|
+
arrowX: number,
|
|
7
|
+
arrowY: number,
|
|
8
|
+
scaleX: number,
|
|
9
|
+
scaleY: number,
|
|
10
|
+
align: AlignType,
|
|
11
|
+
onAlign: VoidFunction
|
|
12
|
+
];
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
3
|
+
import useEvent from "rc-util/es/hooks/useEvent";
|
|
4
|
+
import useLayoutEffect from "rc-util/es/hooks/useLayoutEffect";
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import { getWin } from "../util";
|
|
7
|
+
function toNum(num) {
|
|
8
|
+
return Number.isNaN(num) ? 1 : num;
|
|
9
|
+
}
|
|
10
|
+
function splitPoints() {
|
|
11
|
+
var points = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
12
|
+
return [points[0], points[1]];
|
|
13
|
+
}
|
|
14
|
+
function getAlignPoint(rect, points) {
|
|
15
|
+
var topBottom = points[0];
|
|
16
|
+
var leftRight = points[1];
|
|
17
|
+
var x;
|
|
18
|
+
var y;
|
|
19
|
+
|
|
20
|
+
// Top & Bottom
|
|
21
|
+
if (topBottom === 't') {
|
|
22
|
+
y = rect.y;
|
|
23
|
+
} else if (topBottom === 'b') {
|
|
24
|
+
y = rect.y + rect.height;
|
|
25
|
+
} else {
|
|
26
|
+
y = rect.y + rect.height / 2;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Left & Right
|
|
30
|
+
if (leftRight === 'l') {
|
|
31
|
+
x = rect.x;
|
|
32
|
+
} else if (leftRight === 'r') {
|
|
33
|
+
x = rect.x + rect.width;
|
|
34
|
+
} else {
|
|
35
|
+
x = rect.x + rect.width / 2;
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
x: x,
|
|
39
|
+
y: y
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function reversePoints(points, index) {
|
|
43
|
+
var reverseMap = {
|
|
44
|
+
t: 'b',
|
|
45
|
+
b: 't',
|
|
46
|
+
l: 'r',
|
|
47
|
+
r: 'l'
|
|
48
|
+
};
|
|
49
|
+
return points.map(function (point, i) {
|
|
50
|
+
if (i === index) {
|
|
51
|
+
return reverseMap[point] || 'c';
|
|
52
|
+
}
|
|
53
|
+
return point;
|
|
54
|
+
}).join('');
|
|
55
|
+
}
|
|
56
|
+
export default function useAlign(open, popupEle, target, placement, builtinPlacements, popupAlign) {
|
|
57
|
+
var _React$useState = React.useState({
|
|
58
|
+
ready: false,
|
|
59
|
+
offsetX: 0,
|
|
60
|
+
offsetY: 0,
|
|
61
|
+
arrowX: 0,
|
|
62
|
+
arrowY: 0,
|
|
63
|
+
scaleX: 1,
|
|
64
|
+
scaleY: 1,
|
|
65
|
+
align: builtinPlacements[placement] || {}
|
|
66
|
+
}),
|
|
67
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
68
|
+
offsetInfo = _React$useState2[0],
|
|
69
|
+
setOffsetInfo = _React$useState2[1];
|
|
70
|
+
var alignCountRef = React.useRef(0);
|
|
71
|
+
var onAlign = useEvent(function () {
|
|
72
|
+
if (popupEle && target && open) {
|
|
73
|
+
var popupElement = popupEle;
|
|
74
|
+
var originLeft = popupElement.style.left;
|
|
75
|
+
var originTop = popupElement.style.top;
|
|
76
|
+
var doc = popupElement.ownerDocument;
|
|
77
|
+
var win = getWin(popupElement);
|
|
78
|
+
|
|
79
|
+
// Reset first
|
|
80
|
+
popupElement.style.left = '0';
|
|
81
|
+
popupElement.style.top = '0';
|
|
82
|
+
|
|
83
|
+
// Calculate align style, we should consider `transform` case
|
|
84
|
+
var targetRect = Array.isArray(target) ? {
|
|
85
|
+
x: target[0],
|
|
86
|
+
y: target[1],
|
|
87
|
+
width: 0,
|
|
88
|
+
height: 0
|
|
89
|
+
} : target.getBoundingClientRect();
|
|
90
|
+
var popupRect = popupElement.getBoundingClientRect();
|
|
91
|
+
var _win$getComputedStyle = win.getComputedStyle(popupElement),
|
|
92
|
+
width = _win$getComputedStyle.width,
|
|
93
|
+
height = _win$getComputedStyle.height;
|
|
94
|
+
var _doc$documentElement = doc.documentElement,
|
|
95
|
+
clientWidth = _doc$documentElement.clientWidth,
|
|
96
|
+
clientHeight = _doc$documentElement.clientHeight;
|
|
97
|
+
var popupHeight = popupRect.height;
|
|
98
|
+
var popupWidth = popupRect.width;
|
|
99
|
+
|
|
100
|
+
// Reset back
|
|
101
|
+
popupElement.style.left = originLeft;
|
|
102
|
+
popupElement.style.top = originTop;
|
|
103
|
+
|
|
104
|
+
// Calculate scale
|
|
105
|
+
var _scaleX = toNum(Math.round(popupWidth / parseFloat(width) * 1000) / 1000);
|
|
106
|
+
var _scaleY = toNum(Math.round(popupHeight / parseFloat(height) * 1000) / 1000);
|
|
107
|
+
|
|
108
|
+
// Placement
|
|
109
|
+
var placementInfo = builtinPlacements[placement] || popupAlign || {};
|
|
110
|
+
var _ref = placementInfo.points || [],
|
|
111
|
+
_ref2 = _slicedToArray(_ref, 2),
|
|
112
|
+
popupPoint = _ref2[0],
|
|
113
|
+
targetPoint = _ref2[1];
|
|
114
|
+
var targetPoints = splitPoints(targetPoint);
|
|
115
|
+
var popupPoints = splitPoints(popupPoint);
|
|
116
|
+
var targetAlignPoint = getAlignPoint(targetRect, targetPoints);
|
|
117
|
+
var popupAlignPoint = getAlignPoint(popupRect, popupPoints);
|
|
118
|
+
|
|
119
|
+
// Real align info may not same as origin one
|
|
120
|
+
var nextAlignInfo = _objectSpread({}, placementInfo);
|
|
121
|
+
|
|
122
|
+
// Offset
|
|
123
|
+
var offset = placementInfo.offset;
|
|
124
|
+
var _ref3 = offset || [],
|
|
125
|
+
_ref4 = _slicedToArray(_ref3, 2),
|
|
126
|
+
_ref4$ = _ref4[0],
|
|
127
|
+
popupOffsetX = _ref4$ === void 0 ? 0 : _ref4$,
|
|
128
|
+
_ref4$2 = _ref4[1],
|
|
129
|
+
popupOffsetY = _ref4$2 === void 0 ? 0 : _ref4$2;
|
|
130
|
+
|
|
131
|
+
// Placement
|
|
132
|
+
var nextOffsetX = targetAlignPoint.x - popupAlignPoint.x + popupOffsetX;
|
|
133
|
+
var nextOffsetY = targetAlignPoint.y - popupAlignPoint.y + popupOffsetY;
|
|
134
|
+
|
|
135
|
+
// ================ Overflow =================
|
|
136
|
+
var targetAlignPointTL = getAlignPoint(targetRect, ['t', 'l']);
|
|
137
|
+
var popupAlignPointTL = getAlignPoint(popupRect, ['t', 'l']);
|
|
138
|
+
var targetAlignPointBR = getAlignPoint(targetRect, ['b', 'r']);
|
|
139
|
+
var popupAlignPointBR = getAlignPoint(popupRect, ['b', 'r']);
|
|
140
|
+
var overflow = placementInfo.overflow || {};
|
|
141
|
+
var adjustX = overflow.adjustX,
|
|
142
|
+
adjustY = overflow.adjustY,
|
|
143
|
+
shiftX = overflow.shiftX,
|
|
144
|
+
shiftY = overflow.shiftY;
|
|
145
|
+
|
|
146
|
+
// >>>>>>>>>> Top & Bottom
|
|
147
|
+
var nextPopupY = popupRect.y + nextOffsetY;
|
|
148
|
+
var nextPopupBottom = nextPopupY + popupHeight;
|
|
149
|
+
var needAdjustY = adjustY === true || adjustY >= 0;
|
|
150
|
+
|
|
151
|
+
// Bottom to Top
|
|
152
|
+
if (needAdjustY && popupPoints[0] === 't' && nextPopupBottom > clientHeight) {
|
|
153
|
+
nextOffsetY = targetAlignPointTL.y - popupAlignPointBR.y - popupOffsetY;
|
|
154
|
+
nextAlignInfo.points = [reversePoints(popupPoints, 0), reversePoints(targetPoints, 0)];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Top to Bottom
|
|
158
|
+
if (needAdjustY && popupPoints[0] === 'b' && nextPopupY < 0) {
|
|
159
|
+
nextOffsetY = targetAlignPointBR.y - popupAlignPointTL.y - popupOffsetY;
|
|
160
|
+
nextAlignInfo.points = [reversePoints(popupPoints, 0), reversePoints(targetPoints, 0)];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// >>>>>>>>>> Left & Right
|
|
164
|
+
var nextPopupX = popupRect.x + nextOffsetX;
|
|
165
|
+
var nextPopupRight = nextPopupX + popupWidth;
|
|
166
|
+
var needAdjustX = adjustX === true || adjustX >= 0;
|
|
167
|
+
|
|
168
|
+
// >>>>> Flip
|
|
169
|
+
// Right to Left
|
|
170
|
+
if (needAdjustX && popupPoints[1] === 'l' && nextPopupRight > clientWidth) {
|
|
171
|
+
nextOffsetX = targetAlignPointTL.x - popupAlignPointBR.x - popupOffsetX;
|
|
172
|
+
nextAlignInfo.points = [reversePoints(popupPoints, 1), reversePoints(targetPoints, 1)];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Left to Right
|
|
176
|
+
if (needAdjustX && popupPoints[1] === 'r' && nextPopupX < 0) {
|
|
177
|
+
nextOffsetX = targetAlignPointBR.x - popupAlignPointTL.x - popupOffsetX;
|
|
178
|
+
nextAlignInfo.points = [reversePoints(popupPoints, 1), reversePoints(targetPoints, 1)];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// >>>>> Shift
|
|
182
|
+
var numShiftX = shiftX === true ? 0 : shiftX;
|
|
183
|
+
if (typeof numShiftX === 'number') {
|
|
184
|
+
// Left
|
|
185
|
+
if (nextPopupX < 0) {
|
|
186
|
+
nextOffsetX -= nextPopupX;
|
|
187
|
+
if (targetRect.x + targetRect.width < numShiftX) {
|
|
188
|
+
nextOffsetX += targetRect.x + targetRect.width - numShiftX;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Right
|
|
193
|
+
if (nextPopupRight > clientWidth) {
|
|
194
|
+
nextOffsetX -= nextPopupRight - clientWidth;
|
|
195
|
+
if (targetRect.x > clientWidth - numShiftX) {
|
|
196
|
+
nextOffsetX += targetRect.x - clientWidth + numShiftX;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
var numShiftY = shiftY === true ? 0 : shiftY;
|
|
201
|
+
if (typeof numShiftY === 'number') {
|
|
202
|
+
// Top
|
|
203
|
+
if (nextPopupY < 0) {
|
|
204
|
+
nextOffsetY -= nextPopupY;
|
|
205
|
+
if (targetRect.y + targetRect.height < numShiftY) {
|
|
206
|
+
nextOffsetY += targetRect.y + targetRect.height - numShiftY;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Bottom
|
|
211
|
+
if (nextPopupBottom > clientHeight) {
|
|
212
|
+
nextOffsetY -= nextPopupBottom - clientHeight;
|
|
213
|
+
if (targetRect.y > clientHeight - numShiftY) {
|
|
214
|
+
nextOffsetY += targetRect.y - clientHeight + numShiftY;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Arrow center align
|
|
220
|
+
var popupLeft = popupRect.x + nextOffsetX;
|
|
221
|
+
var popupRight = popupLeft + popupWidth;
|
|
222
|
+
var popupTop = popupRect.y + nextOffsetY;
|
|
223
|
+
var popupBottom = popupTop + popupHeight;
|
|
224
|
+
var targetLeft = targetRect.x;
|
|
225
|
+
var targetRight = targetLeft + targetRect.width;
|
|
226
|
+
var targetTop = targetRect.y;
|
|
227
|
+
var targetBottom = targetTop + targetRect.height;
|
|
228
|
+
var maxLeft = Math.max(popupLeft, targetLeft);
|
|
229
|
+
var minRight = Math.min(popupRight, targetRight);
|
|
230
|
+
var xCenter = (maxLeft + minRight) / 2;
|
|
231
|
+
var nextArrowX = xCenter - popupLeft;
|
|
232
|
+
var maxTop = Math.max(popupTop, targetTop);
|
|
233
|
+
var minBottom = Math.min(popupBottom, targetBottom);
|
|
234
|
+
var yCenter = (maxTop + minBottom) / 2;
|
|
235
|
+
var nextArrowY = yCenter - popupTop;
|
|
236
|
+
setOffsetInfo({
|
|
237
|
+
ready: true,
|
|
238
|
+
offsetX: nextOffsetX / _scaleX,
|
|
239
|
+
offsetY: nextOffsetY / _scaleY,
|
|
240
|
+
arrowX: nextArrowX / _scaleX,
|
|
241
|
+
arrowY: nextArrowY / _scaleY,
|
|
242
|
+
scaleX: _scaleX,
|
|
243
|
+
scaleY: _scaleY,
|
|
244
|
+
align: nextAlignInfo
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
var triggerAlign = function triggerAlign() {
|
|
249
|
+
alignCountRef.current += 1;
|
|
250
|
+
var id = alignCountRef.current;
|
|
251
|
+
|
|
252
|
+
// Merge all align requirement into one frame
|
|
253
|
+
Promise.resolve().then(function () {
|
|
254
|
+
if (alignCountRef.current === id) {
|
|
255
|
+
onAlign();
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// Reset ready status when placement & open changed
|
|
261
|
+
var resetReady = function resetReady() {
|
|
262
|
+
setOffsetInfo(function (ori) {
|
|
263
|
+
return _objectSpread(_objectSpread({}, ori), {}, {
|
|
264
|
+
ready: false
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
};
|
|
268
|
+
useLayoutEffect(resetReady, [placement]);
|
|
269
|
+
useLayoutEffect(function () {
|
|
270
|
+
if (!open) {
|
|
271
|
+
resetReady();
|
|
272
|
+
}
|
|
273
|
+
}, [open]);
|
|
274
|
+
return [offsetInfo.ready, offsetInfo.offsetX, offsetInfo.offsetY, offsetInfo.arrowX, offsetInfo.arrowY, offsetInfo.scaleX, offsetInfo.scaleY, offsetInfo.align, triggerAlign];
|
|
275
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function useWatch(open: boolean, target: HTMLElement, popup: HTMLElement, onAlign: VoidFunction): void;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
2
|
+
import useLayoutEffect from "rc-util/es/hooks/useLayoutEffect";
|
|
3
|
+
import { getWin } from "../util";
|
|
4
|
+
function collectScroller(ele) {
|
|
5
|
+
var scrollerList = [];
|
|
6
|
+
var current = ele === null || ele === void 0 ? void 0 : ele.parentElement;
|
|
7
|
+
var scrollStyle = ['hidden', 'scroll', 'auto'];
|
|
8
|
+
while (current) {
|
|
9
|
+
var _getWin$getComputedSt = getWin(current).getComputedStyle(current),
|
|
10
|
+
overflowX = _getWin$getComputedSt.overflowX,
|
|
11
|
+
overflowY = _getWin$getComputedSt.overflowY;
|
|
12
|
+
if (scrollStyle.includes(overflowX) || scrollStyle.includes(overflowY)) {
|
|
13
|
+
scrollerList.push(current);
|
|
14
|
+
}
|
|
15
|
+
current = current.parentElement;
|
|
16
|
+
}
|
|
17
|
+
return scrollerList;
|
|
18
|
+
}
|
|
19
|
+
export default function useWatch(open, target, popup, onAlign) {
|
|
20
|
+
useLayoutEffect(function () {
|
|
21
|
+
if (open && target && popup) {
|
|
22
|
+
var targetElement = target;
|
|
23
|
+
var popupElement = popup;
|
|
24
|
+
var targetScrollList = collectScroller(targetElement);
|
|
25
|
+
var popupScrollList = collectScroller(popupElement);
|
|
26
|
+
var win = getWin(popupElement);
|
|
27
|
+
var mergedList = new Set([win].concat(_toConsumableArray(targetScrollList), _toConsumableArray(popupScrollList)));
|
|
28
|
+
function notifyScroll() {
|
|
29
|
+
onAlign();
|
|
30
|
+
}
|
|
31
|
+
mergedList.forEach(function (scroller) {
|
|
32
|
+
scroller.addEventListener('scroll', notifyScroll, {
|
|
33
|
+
passive: true
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
win.addEventListener('resize', notifyScroll, {
|
|
37
|
+
passive: true
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// First time always do align
|
|
41
|
+
onAlign();
|
|
42
|
+
return function () {
|
|
43
|
+
mergedList.forEach(function (scroller) {
|
|
44
|
+
scroller.removeEventListener('scroll', notifyScroll);
|
|
45
|
+
win.removeEventListener('resize', notifyScroll);
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}, [open, target, popup]);
|
|
50
|
+
}
|