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