@atlaskit/smart-card 26.5.15 → 26.5.17
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/CHANGELOG.md +12 -0
- package/dist/cjs/version.json +1 -1
- package/dist/cjs/view/HoverCard/components/HoverCardComponent.js +55 -13
- package/dist/cjs/view/HoverCard/components/HoverCardContent.js +2 -7
- package/dist/es2019/version.json +1 -1
- package/dist/es2019/view/HoverCard/components/HoverCardComponent.js +57 -15
- package/dist/es2019/view/HoverCard/components/HoverCardContent.js +2 -7
- package/dist/esm/version.json +1 -1
- package/dist/esm/view/HoverCard/components/HoverCardComponent.js +56 -14
- package/dist/esm/view/HoverCard/components/HoverCardContent.js +2 -7
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atlaskit/smart-card
|
|
2
2
|
|
|
3
|
+
## 26.5.17
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`b3ed4f7f776`](https://bitbucket.org/atlassian/atlassian-frontend/commits/b3ed4f7f776) - [ux] Fix for Hover Card unmount - added a clean up function that will clearTimeouts. Additionally changed the trigger of HoverCard from onMouseEnter to onMouseOver and added a function that after 100ms of hover starts fetching the data for the url to reduce the loading state experienced on standalone HoverCards.
|
|
8
|
+
|
|
9
|
+
## 26.5.16
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
|
|
3
15
|
## 26.5.15
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/cjs/version.json
CHANGED
|
@@ -18,6 +18,8 @@ var _HoverCardContent = _interopRequireDefault(require("../components/HoverCardC
|
|
|
18
18
|
var _styled = require("../styled");
|
|
19
19
|
var _constants = require("../../../constants");
|
|
20
20
|
var _SmartLinkAnalyticsContext = require("../../../utils/analytics/SmartLinkAnalyticsContext");
|
|
21
|
+
var _actions = require("../../../state/actions");
|
|
22
|
+
var _analytics = require("../../../state/analytics");
|
|
21
23
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
22
24
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
23
25
|
/** @jsx jsx */
|
|
@@ -26,7 +28,8 @@ var HOVER_CARD_SOURCE = 'smartLinkPreviewHoverCard';
|
|
|
26
28
|
var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
27
29
|
var children = _ref.children,
|
|
28
30
|
url = _ref.url,
|
|
29
|
-
id = _ref.id,
|
|
31
|
+
_ref$id = _ref.id,
|
|
32
|
+
id = _ref$id === void 0 ? '' : _ref$id,
|
|
30
33
|
analyticsHandler = _ref.analyticsHandler,
|
|
31
34
|
_ref$canOpen = _ref.canOpen,
|
|
32
35
|
canOpen = _ref$canOpen === void 0 ? true : _ref$canOpen,
|
|
@@ -37,17 +40,22 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
37
40
|
_ref$showServerAction = _ref.showServerActions,
|
|
38
41
|
showServerActions = _ref$showServerAction === void 0 ? false : _ref$showServerAction;
|
|
39
42
|
var delay = 300;
|
|
43
|
+
var resolveDelay = 100;
|
|
40
44
|
var _React$useState = _react2.default.useState(false),
|
|
41
45
|
_React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
|
|
42
46
|
isOpen = _React$useState2[0],
|
|
43
47
|
setIsOpen = _React$useState2[1];
|
|
44
48
|
var fadeOutTimeoutId = (0, _react2.useRef)();
|
|
45
49
|
var fadeInTimeoutId = (0, _react2.useRef)();
|
|
50
|
+
var resolveTimeOutId = (0, _react2.useRef)();
|
|
46
51
|
var mousePos = (0, _react2.useRef)();
|
|
47
52
|
var popupOffset = (0, _react2.useRef)();
|
|
48
53
|
var parentSpan = (0, _react2.useRef)(null);
|
|
49
54
|
var renderers = (0, _renderers.useSmartLinkRenderers)();
|
|
50
55
|
var linkState = (0, _store.useSmartCardState)(url);
|
|
56
|
+
var analytics = (0, _analytics.useSmartLinkAnalytics)(url, undefined, id);
|
|
57
|
+
var _useSmartCardActions = (0, _actions.useSmartCardActions)(id, url, analytics),
|
|
58
|
+
loadMetadata = _useSmartCardActions.loadMetadata;
|
|
51
59
|
var setMousePosition = (0, _react2.useCallback)(function (event) {
|
|
52
60
|
if (isOpen) {
|
|
53
61
|
return;
|
|
@@ -64,27 +72,61 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
64
72
|
if (fadeInTimeoutId.current) {
|
|
65
73
|
clearTimeout(fadeInTimeoutId.current);
|
|
66
74
|
}
|
|
75
|
+
if (resolveTimeOutId.current) {
|
|
76
|
+
clearTimeout(resolveTimeOutId.current);
|
|
77
|
+
}
|
|
67
78
|
fadeOutTimeoutId.current = setTimeout(function () {
|
|
68
79
|
return hideCard();
|
|
69
80
|
}, delay);
|
|
70
81
|
}, [hideCard]);
|
|
82
|
+
|
|
83
|
+
// clearing out the timeouts in order to avoid memory leaks
|
|
84
|
+
// in case the component unmounts before they execute
|
|
85
|
+
(0, _react2.useEffect)(function () {
|
|
86
|
+
return function () {
|
|
87
|
+
if (fadeOutTimeoutId.current) {
|
|
88
|
+
clearTimeout(fadeOutTimeoutId.current);
|
|
89
|
+
}
|
|
90
|
+
if (fadeInTimeoutId.current) {
|
|
91
|
+
clearTimeout(fadeInTimeoutId.current);
|
|
92
|
+
}
|
|
93
|
+
if (resolveTimeOutId.current) {
|
|
94
|
+
clearTimeout(resolveTimeOutId.current);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}, []);
|
|
98
|
+
|
|
99
|
+
// we want to initiate resolve a bit earlier for standalone cards
|
|
100
|
+
// to minimize the loading state
|
|
101
|
+
var initResolve = (0, _react2.useCallback)(function () {
|
|
102
|
+
// this check covers both non-SSR (status) & SSR case (metadataStatus)
|
|
103
|
+
var isLinkUnresolved = linkState.status === 'pending' || !linkState.metadataStatus;
|
|
104
|
+
if (!resolveTimeOutId.current && isLinkUnresolved) {
|
|
105
|
+
resolveTimeOutId.current = setTimeout(function () {
|
|
106
|
+
loadMetadata();
|
|
107
|
+
}, resolveDelay);
|
|
108
|
+
}
|
|
109
|
+
}, [linkState, loadMetadata]);
|
|
71
110
|
var initShowCard = (0, _react2.useCallback)(function (event) {
|
|
72
111
|
if (fadeOutTimeoutId.current) {
|
|
73
112
|
clearTimeout(fadeOutTimeoutId.current);
|
|
74
113
|
}
|
|
114
|
+
initResolve();
|
|
75
115
|
//Set mouse position in the case it's not already set by onMouseMove, as in the case of scrolling
|
|
76
116
|
setMousePosition(event);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
117
|
+
if (!isOpen) {
|
|
118
|
+
fadeInTimeoutId.current = setTimeout(function () {
|
|
119
|
+
//If these are undefined then popupOffset is undefined and we fallback to default bottom-start placement
|
|
120
|
+
if (parentSpan.current && mousePos.current) {
|
|
121
|
+
var _parentSpan$current$g = parentSpan.current.getBoundingClientRect(),
|
|
122
|
+
bottom = _parentSpan$current$g.bottom,
|
|
123
|
+
left = _parentSpan$current$g.left;
|
|
124
|
+
popupOffset.current = [mousePos.current.x - left, mousePos.current.y - bottom + _styled.CARD_GAP_PX];
|
|
125
|
+
}
|
|
126
|
+
setIsOpen(true);
|
|
127
|
+
}, delay);
|
|
128
|
+
}
|
|
129
|
+
}, [initResolve, isOpen, setMousePosition]);
|
|
88
130
|
var linkActions = (0, _useSmartLinkActions.useSmartLinkActions)({
|
|
89
131
|
url: url,
|
|
90
132
|
appearance: _constants.CardDisplay.HoverCardPreview,
|
|
@@ -135,7 +177,7 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
135
177
|
return (0, _react.jsx)("span", {
|
|
136
178
|
ref: parentSpan
|
|
137
179
|
}, (0, _react.jsx)("span", (0, _extends2.default)({}, triggerProps, {
|
|
138
|
-
|
|
180
|
+
onMouseOver: initShowCard,
|
|
139
181
|
onMouseLeave: initHideCard,
|
|
140
182
|
onMouseMove: setMousePosition,
|
|
141
183
|
onClick: onChildClick,
|
|
@@ -25,7 +25,6 @@ var _unauthorised = _interopRequireDefault(require("./views/unauthorised"));
|
|
|
25
25
|
var _resolved = _interopRequireDefault(require("./views/resolved"));
|
|
26
26
|
var _reactIntlNext = require("react-intl-next");
|
|
27
27
|
var _messages = require("../../../messages");
|
|
28
|
-
var _actions = require("../../../state/actions");
|
|
29
28
|
var _click = require("../../../utils/analytics/click");
|
|
30
29
|
var _store = require("../../../state/store");
|
|
31
30
|
var _linkProvider = require("@atlaskit/link-provider");
|
|
@@ -91,7 +90,7 @@ var getCopyAction = function getCopyAction(url) {
|
|
|
91
90
|
};
|
|
92
91
|
exports.getCopyAction = getCopyAction;
|
|
93
92
|
var HoverCardContent = function HoverCardContent(_ref) {
|
|
94
|
-
var _cardState$details;
|
|
93
|
+
var _linkState$status, _cardState$details;
|
|
95
94
|
var _ref$id = _ref.id,
|
|
96
95
|
id = _ref$id === void 0 ? '' : _ref$id,
|
|
97
96
|
_analytics = _ref.analytics,
|
|
@@ -113,14 +112,10 @@ var HoverCardContent = function HoverCardContent(_ref) {
|
|
|
113
112
|
var extensionKey = (0, _react2.useMemo)(function () {
|
|
114
113
|
return (0, _helpers.getExtensionKey)(cardState.details);
|
|
115
114
|
}, [cardState.details]);
|
|
116
|
-
var actions = (0, _actions.useSmartCardActions)(id, url, analytics);
|
|
117
115
|
var linkState = (0, _store.useSmartCardState)(url);
|
|
118
|
-
var linkStatus = linkState.status;
|
|
116
|
+
var linkStatus = (_linkState$status = linkState.status) !== null && _linkState$status !== void 0 ? _linkState$status : 'pending';
|
|
119
117
|
var statusRef = (0, _react2.useRef)(linkStatus);
|
|
120
118
|
var analyticsRef = (0, _react2.useRef)(analytics);
|
|
121
|
-
(0, _react2.useEffect)(function () {
|
|
122
|
-
actions.loadMetadata();
|
|
123
|
-
}, [actions]);
|
|
124
119
|
(0, _react2.useEffect)(function () {
|
|
125
120
|
/**
|
|
126
121
|
* Must access current analytics object value via ref because its not stable
|
package/dist/es2019/version.json
CHANGED
|
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
|
|
|
2
2
|
/** @jsx jsx */
|
|
3
3
|
import Popup from '@atlaskit/popup';
|
|
4
4
|
import { jsx } from '@emotion/react';
|
|
5
|
-
import React, { useCallback, useMemo, useRef } from 'react';
|
|
5
|
+
import React, { useCallback, useMemo, useRef, useEffect } from 'react';
|
|
6
6
|
import { useSmartLinkActions } from '../../../state/hooks-external/useSmartLinkActions';
|
|
7
7
|
import { useSmartLinkRenderers } from '../../../state/renderers';
|
|
8
8
|
import { useSmartCardState as useLinkState } from '../../../state/store';
|
|
@@ -10,11 +10,13 @@ import HoverCardContent from '../components/HoverCardContent';
|
|
|
10
10
|
import { CARD_GAP_PX, HOVER_CARD_Z_INDEX } from '../styled';
|
|
11
11
|
import { CardDisplay } from '../../../constants';
|
|
12
12
|
import { SmartLinkAnalyticsContext } from '../../../utils/analytics/SmartLinkAnalyticsContext';
|
|
13
|
+
import { useSmartCardActions } from '../../../state/actions';
|
|
14
|
+
import { useSmartLinkAnalytics } from '../../../state/analytics';
|
|
13
15
|
const HOVER_CARD_SOURCE = 'smartLinkPreviewHoverCard';
|
|
14
16
|
export const HoverCardComponent = ({
|
|
15
17
|
children,
|
|
16
18
|
url,
|
|
17
|
-
id,
|
|
19
|
+
id = '',
|
|
18
20
|
analyticsHandler,
|
|
19
21
|
canOpen = true,
|
|
20
22
|
closeOnChildClick = false,
|
|
@@ -22,14 +24,20 @@ export const HoverCardComponent = ({
|
|
|
22
24
|
showServerActions = false
|
|
23
25
|
}) => {
|
|
24
26
|
const delay = 300;
|
|
27
|
+
const resolveDelay = 100;
|
|
25
28
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
26
29
|
const fadeOutTimeoutId = useRef();
|
|
27
30
|
const fadeInTimeoutId = useRef();
|
|
31
|
+
const resolveTimeOutId = useRef();
|
|
28
32
|
const mousePos = useRef();
|
|
29
33
|
const popupOffset = useRef();
|
|
30
34
|
const parentSpan = useRef(null);
|
|
31
35
|
const renderers = useSmartLinkRenderers();
|
|
32
36
|
const linkState = useLinkState(url);
|
|
37
|
+
const analytics = useSmartLinkAnalytics(url, undefined, id);
|
|
38
|
+
const {
|
|
39
|
+
loadMetadata
|
|
40
|
+
} = useSmartCardActions(id, url, analytics);
|
|
33
41
|
const setMousePosition = useCallback(event => {
|
|
34
42
|
if (isOpen) {
|
|
35
43
|
return;
|
|
@@ -46,26 +54,60 @@ export const HoverCardComponent = ({
|
|
|
46
54
|
if (fadeInTimeoutId.current) {
|
|
47
55
|
clearTimeout(fadeInTimeoutId.current);
|
|
48
56
|
}
|
|
57
|
+
if (resolveTimeOutId.current) {
|
|
58
|
+
clearTimeout(resolveTimeOutId.current);
|
|
59
|
+
}
|
|
49
60
|
fadeOutTimeoutId.current = setTimeout(() => hideCard(), delay);
|
|
50
61
|
}, [hideCard]);
|
|
62
|
+
|
|
63
|
+
// clearing out the timeouts in order to avoid memory leaks
|
|
64
|
+
// in case the component unmounts before they execute
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
return () => {
|
|
67
|
+
if (fadeOutTimeoutId.current) {
|
|
68
|
+
clearTimeout(fadeOutTimeoutId.current);
|
|
69
|
+
}
|
|
70
|
+
if (fadeInTimeoutId.current) {
|
|
71
|
+
clearTimeout(fadeInTimeoutId.current);
|
|
72
|
+
}
|
|
73
|
+
if (resolveTimeOutId.current) {
|
|
74
|
+
clearTimeout(resolveTimeOutId.current);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}, []);
|
|
78
|
+
|
|
79
|
+
// we want to initiate resolve a bit earlier for standalone cards
|
|
80
|
+
// to minimize the loading state
|
|
81
|
+
const initResolve = useCallback(() => {
|
|
82
|
+
// this check covers both non-SSR (status) & SSR case (metadataStatus)
|
|
83
|
+
const isLinkUnresolved = linkState.status === 'pending' || !linkState.metadataStatus;
|
|
84
|
+
if (!resolveTimeOutId.current && isLinkUnresolved) {
|
|
85
|
+
resolveTimeOutId.current = setTimeout(() => {
|
|
86
|
+
loadMetadata();
|
|
87
|
+
}, resolveDelay);
|
|
88
|
+
}
|
|
89
|
+
}, [linkState, loadMetadata]);
|
|
51
90
|
const initShowCard = useCallback(event => {
|
|
52
91
|
if (fadeOutTimeoutId.current) {
|
|
53
92
|
clearTimeout(fadeOutTimeoutId.current);
|
|
54
93
|
}
|
|
94
|
+
initResolve();
|
|
55
95
|
//Set mouse position in the case it's not already set by onMouseMove, as in the case of scrolling
|
|
56
96
|
setMousePosition(event);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
97
|
+
if (!isOpen) {
|
|
98
|
+
fadeInTimeoutId.current = setTimeout(() => {
|
|
99
|
+
//If these are undefined then popupOffset is undefined and we fallback to default bottom-start placement
|
|
100
|
+
if (parentSpan.current && mousePos.current) {
|
|
101
|
+
const {
|
|
102
|
+
bottom,
|
|
103
|
+
left
|
|
104
|
+
} = parentSpan.current.getBoundingClientRect();
|
|
105
|
+
popupOffset.current = [mousePos.current.x - left, mousePos.current.y - bottom + CARD_GAP_PX];
|
|
106
|
+
}
|
|
107
|
+
setIsOpen(true);
|
|
108
|
+
}, delay);
|
|
109
|
+
}
|
|
110
|
+
}, [initResolve, isOpen, setMousePosition]);
|
|
69
111
|
const linkActions = useSmartLinkActions({
|
|
70
112
|
url,
|
|
71
113
|
appearance: CardDisplay.HoverCardPreview,
|
|
@@ -114,7 +156,7 @@ export const HoverCardComponent = ({
|
|
|
114
156
|
const trigger = useCallback(triggerProps => jsx("span", {
|
|
115
157
|
ref: parentSpan
|
|
116
158
|
}, jsx("span", _extends({}, triggerProps, {
|
|
117
|
-
|
|
159
|
+
onMouseOver: initShowCard,
|
|
118
160
|
onMouseLeave: initHideCard,
|
|
119
161
|
onMouseMove: setMousePosition,
|
|
120
162
|
onClick: onChildClick,
|
|
@@ -16,7 +16,6 @@ import HoverCardUnauthorisedView from './views/unauthorised';
|
|
|
16
16
|
import HoverCardResolvedView from './views/resolved';
|
|
17
17
|
import { FormattedMessage } from 'react-intl-next';
|
|
18
18
|
import { messages } from '../../../messages';
|
|
19
|
-
import { useSmartCardActions } from '../../../state/actions';
|
|
20
19
|
import { fireLinkClickedEvent } from '../../../utils/analytics/click';
|
|
21
20
|
import { useSmartCardState } from '../../../state/store';
|
|
22
21
|
import { useFeatureFlag } from '@atlaskit/link-provider';
|
|
@@ -64,7 +63,7 @@ const HoverCardContent = ({
|
|
|
64
63
|
onMouseLeave,
|
|
65
64
|
showServerActions
|
|
66
65
|
}) => {
|
|
67
|
-
var _cardState$details;
|
|
66
|
+
var _linkState$status, _cardState$details;
|
|
68
67
|
const useLozengeAction = useFeatureFlag('useLozengeAction');
|
|
69
68
|
const {
|
|
70
69
|
createAnalyticsEvent
|
|
@@ -72,14 +71,10 @@ const HoverCardContent = ({
|
|
|
72
71
|
const defaultAnalytics = useSmartLinkAnalytics(url, undefined, id);
|
|
73
72
|
const analytics = _analytics !== null && _analytics !== void 0 ? _analytics : defaultAnalytics;
|
|
74
73
|
const extensionKey = useMemo(() => getExtensionKey(cardState.details), [cardState.details]);
|
|
75
|
-
const actions = useSmartCardActions(id, url, analytics);
|
|
76
74
|
const linkState = useSmartCardState(url);
|
|
77
|
-
const linkStatus = linkState.status;
|
|
75
|
+
const linkStatus = (_linkState$status = linkState.status) !== null && _linkState$status !== void 0 ? _linkState$status : 'pending';
|
|
78
76
|
const statusRef = useRef(linkStatus);
|
|
79
77
|
const analyticsRef = useRef(analytics);
|
|
80
|
-
useEffect(() => {
|
|
81
|
-
actions.loadMetadata();
|
|
82
|
-
}, [actions]);
|
|
83
78
|
useEffect(() => {
|
|
84
79
|
/**
|
|
85
80
|
* Must access current analytics object value via ref because its not stable
|
package/dist/esm/version.json
CHANGED
|
@@ -3,7 +3,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
|
3
3
|
/** @jsx jsx */
|
|
4
4
|
import Popup from '@atlaskit/popup';
|
|
5
5
|
import { jsx } from '@emotion/react';
|
|
6
|
-
import React, { useCallback, useMemo, useRef } from 'react';
|
|
6
|
+
import React, { useCallback, useMemo, useRef, useEffect } from 'react';
|
|
7
7
|
import { useSmartLinkActions } from '../../../state/hooks-external/useSmartLinkActions';
|
|
8
8
|
import { useSmartLinkRenderers } from '../../../state/renderers';
|
|
9
9
|
import { useSmartCardState as useLinkState } from '../../../state/store';
|
|
@@ -11,11 +11,14 @@ import HoverCardContent from '../components/HoverCardContent';
|
|
|
11
11
|
import { CARD_GAP_PX, HOVER_CARD_Z_INDEX } from '../styled';
|
|
12
12
|
import { CardDisplay } from '../../../constants';
|
|
13
13
|
import { SmartLinkAnalyticsContext } from '../../../utils/analytics/SmartLinkAnalyticsContext';
|
|
14
|
+
import { useSmartCardActions } from '../../../state/actions';
|
|
15
|
+
import { useSmartLinkAnalytics } from '../../../state/analytics';
|
|
14
16
|
var HOVER_CARD_SOURCE = 'smartLinkPreviewHoverCard';
|
|
15
17
|
export var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
16
18
|
var children = _ref.children,
|
|
17
19
|
url = _ref.url,
|
|
18
|
-
id = _ref.id,
|
|
20
|
+
_ref$id = _ref.id,
|
|
21
|
+
id = _ref$id === void 0 ? '' : _ref$id,
|
|
19
22
|
analyticsHandler = _ref.analyticsHandler,
|
|
20
23
|
_ref$canOpen = _ref.canOpen,
|
|
21
24
|
canOpen = _ref$canOpen === void 0 ? true : _ref$canOpen,
|
|
@@ -26,17 +29,22 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
26
29
|
_ref$showServerAction = _ref.showServerActions,
|
|
27
30
|
showServerActions = _ref$showServerAction === void 0 ? false : _ref$showServerAction;
|
|
28
31
|
var delay = 300;
|
|
32
|
+
var resolveDelay = 100;
|
|
29
33
|
var _React$useState = React.useState(false),
|
|
30
34
|
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
31
35
|
isOpen = _React$useState2[0],
|
|
32
36
|
setIsOpen = _React$useState2[1];
|
|
33
37
|
var fadeOutTimeoutId = useRef();
|
|
34
38
|
var fadeInTimeoutId = useRef();
|
|
39
|
+
var resolveTimeOutId = useRef();
|
|
35
40
|
var mousePos = useRef();
|
|
36
41
|
var popupOffset = useRef();
|
|
37
42
|
var parentSpan = useRef(null);
|
|
38
43
|
var renderers = useSmartLinkRenderers();
|
|
39
44
|
var linkState = useLinkState(url);
|
|
45
|
+
var analytics = useSmartLinkAnalytics(url, undefined, id);
|
|
46
|
+
var _useSmartCardActions = useSmartCardActions(id, url, analytics),
|
|
47
|
+
loadMetadata = _useSmartCardActions.loadMetadata;
|
|
40
48
|
var setMousePosition = useCallback(function (event) {
|
|
41
49
|
if (isOpen) {
|
|
42
50
|
return;
|
|
@@ -53,27 +61,61 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
53
61
|
if (fadeInTimeoutId.current) {
|
|
54
62
|
clearTimeout(fadeInTimeoutId.current);
|
|
55
63
|
}
|
|
64
|
+
if (resolveTimeOutId.current) {
|
|
65
|
+
clearTimeout(resolveTimeOutId.current);
|
|
66
|
+
}
|
|
56
67
|
fadeOutTimeoutId.current = setTimeout(function () {
|
|
57
68
|
return hideCard();
|
|
58
69
|
}, delay);
|
|
59
70
|
}, [hideCard]);
|
|
71
|
+
|
|
72
|
+
// clearing out the timeouts in order to avoid memory leaks
|
|
73
|
+
// in case the component unmounts before they execute
|
|
74
|
+
useEffect(function () {
|
|
75
|
+
return function () {
|
|
76
|
+
if (fadeOutTimeoutId.current) {
|
|
77
|
+
clearTimeout(fadeOutTimeoutId.current);
|
|
78
|
+
}
|
|
79
|
+
if (fadeInTimeoutId.current) {
|
|
80
|
+
clearTimeout(fadeInTimeoutId.current);
|
|
81
|
+
}
|
|
82
|
+
if (resolveTimeOutId.current) {
|
|
83
|
+
clearTimeout(resolveTimeOutId.current);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}, []);
|
|
87
|
+
|
|
88
|
+
// we want to initiate resolve a bit earlier for standalone cards
|
|
89
|
+
// to minimize the loading state
|
|
90
|
+
var initResolve = useCallback(function () {
|
|
91
|
+
// this check covers both non-SSR (status) & SSR case (metadataStatus)
|
|
92
|
+
var isLinkUnresolved = linkState.status === 'pending' || !linkState.metadataStatus;
|
|
93
|
+
if (!resolveTimeOutId.current && isLinkUnresolved) {
|
|
94
|
+
resolveTimeOutId.current = setTimeout(function () {
|
|
95
|
+
loadMetadata();
|
|
96
|
+
}, resolveDelay);
|
|
97
|
+
}
|
|
98
|
+
}, [linkState, loadMetadata]);
|
|
60
99
|
var initShowCard = useCallback(function (event) {
|
|
61
100
|
if (fadeOutTimeoutId.current) {
|
|
62
101
|
clearTimeout(fadeOutTimeoutId.current);
|
|
63
102
|
}
|
|
103
|
+
initResolve();
|
|
64
104
|
//Set mouse position in the case it's not already set by onMouseMove, as in the case of scrolling
|
|
65
105
|
setMousePosition(event);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
106
|
+
if (!isOpen) {
|
|
107
|
+
fadeInTimeoutId.current = setTimeout(function () {
|
|
108
|
+
//If these are undefined then popupOffset is undefined and we fallback to default bottom-start placement
|
|
109
|
+
if (parentSpan.current && mousePos.current) {
|
|
110
|
+
var _parentSpan$current$g = parentSpan.current.getBoundingClientRect(),
|
|
111
|
+
bottom = _parentSpan$current$g.bottom,
|
|
112
|
+
left = _parentSpan$current$g.left;
|
|
113
|
+
popupOffset.current = [mousePos.current.x - left, mousePos.current.y - bottom + CARD_GAP_PX];
|
|
114
|
+
}
|
|
115
|
+
setIsOpen(true);
|
|
116
|
+
}, delay);
|
|
117
|
+
}
|
|
118
|
+
}, [initResolve, isOpen, setMousePosition]);
|
|
77
119
|
var linkActions = useSmartLinkActions({
|
|
78
120
|
url: url,
|
|
79
121
|
appearance: CardDisplay.HoverCardPreview,
|
|
@@ -124,7 +166,7 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
124
166
|
return jsx("span", {
|
|
125
167
|
ref: parentSpan
|
|
126
168
|
}, jsx("span", _extends({}, triggerProps, {
|
|
127
|
-
|
|
169
|
+
onMouseOver: initShowCard,
|
|
128
170
|
onMouseLeave: initHideCard,
|
|
129
171
|
onMouseMove: setMousePosition,
|
|
130
172
|
onClick: onChildClick,
|
|
@@ -18,7 +18,6 @@ import HoverCardUnauthorisedView from './views/unauthorised';
|
|
|
18
18
|
import HoverCardResolvedView from './views/resolved';
|
|
19
19
|
import { FormattedMessage } from 'react-intl-next';
|
|
20
20
|
import { messages } from '../../../messages';
|
|
21
|
-
import { useSmartCardActions } from '../../../state/actions';
|
|
22
21
|
import { fireLinkClickedEvent } from '../../../utils/analytics/click';
|
|
23
22
|
import { useSmartCardState } from '../../../state/store';
|
|
24
23
|
import { useFeatureFlag } from '@atlaskit/link-provider';
|
|
@@ -77,7 +76,7 @@ export var getCopyAction = function getCopyAction(url) {
|
|
|
77
76
|
};
|
|
78
77
|
};
|
|
79
78
|
var HoverCardContent = function HoverCardContent(_ref) {
|
|
80
|
-
var _cardState$details;
|
|
79
|
+
var _linkState$status, _cardState$details;
|
|
81
80
|
var _ref$id = _ref.id,
|
|
82
81
|
id = _ref$id === void 0 ? '' : _ref$id,
|
|
83
82
|
_analytics = _ref.analytics,
|
|
@@ -99,14 +98,10 @@ var HoverCardContent = function HoverCardContent(_ref) {
|
|
|
99
98
|
var extensionKey = useMemo(function () {
|
|
100
99
|
return getExtensionKey(cardState.details);
|
|
101
100
|
}, [cardState.details]);
|
|
102
|
-
var actions = useSmartCardActions(id, url, analytics);
|
|
103
101
|
var linkState = useSmartCardState(url);
|
|
104
|
-
var linkStatus = linkState.status;
|
|
102
|
+
var linkStatus = (_linkState$status = linkState.status) !== null && _linkState$status !== void 0 ? _linkState$status : 'pending';
|
|
105
103
|
var statusRef = useRef(linkStatus);
|
|
106
104
|
var analyticsRef = useRef(analytics);
|
|
107
|
-
useEffect(function () {
|
|
108
|
-
actions.loadMetadata();
|
|
109
|
-
}, [actions]);
|
|
110
105
|
useEffect(function () {
|
|
111
106
|
/**
|
|
112
107
|
* Must access current analytics object value via ref because its not stable
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/smart-card",
|
|
3
|
-
"version": "26.5.
|
|
3
|
+
"version": "26.5.17",
|
|
4
4
|
"description": "Smart card component",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@atlaskit/avatar": "^21.3.0",
|
|
36
36
|
"@atlaskit/avatar-group": "^9.3.0",
|
|
37
37
|
"@atlaskit/button": "^16.8.0",
|
|
38
|
-
"@atlaskit/dropdown-menu": "^11.
|
|
38
|
+
"@atlaskit/dropdown-menu": "^11.10.0",
|
|
39
39
|
"@atlaskit/frontend-utilities": "^2.7.0",
|
|
40
40
|
"@atlaskit/icon": "^21.12.0",
|
|
41
41
|
"@atlaskit/icon-file-type": "^6.4.0",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@atlaskit/in-product-testing": "^0.2.0",
|
|
45
45
|
"@atlaskit/link-analytics": "^8.0.2",
|
|
46
46
|
"@atlaskit/link-client-extension": "^1.2.1",
|
|
47
|
-
"@atlaskit/linking-common": "^
|
|
47
|
+
"@atlaskit/linking-common": "^3.0.0",
|
|
48
48
|
"@atlaskit/linking-types": "^6.0.0",
|
|
49
49
|
"@atlaskit/logo": "^13.14.0",
|
|
50
50
|
"@atlaskit/lozenge": "^11.4.0",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@atlaskit/modal-dialog": "^12.6.0",
|
|
53
53
|
"@atlaskit/outbound-auth-flow-client": "^3.4.0",
|
|
54
54
|
"@atlaskit/platform-feature-flags": "^0.2.1",
|
|
55
|
-
"@atlaskit/popup": "^1.
|
|
55
|
+
"@atlaskit/popup": "^1.8.0",
|
|
56
56
|
"@atlaskit/spinner": "^15.5.0",
|
|
57
57
|
"@atlaskit/theme": "^12.5.0",
|
|
58
58
|
"@atlaskit/tokens": "^1.9.0",
|