@atlaskit/smart-card 26.3.1 → 26.3.3

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 (26) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/utils/analytics/SmartLinkAnalyticsContext.js +3 -1
  3. package/dist/cjs/version.json +1 -1
  4. package/dist/cjs/view/HoverCard/components/HoverCardComponent.js +45 -39
  5. package/dist/cjs/view/HoverCard/components/HoverCardContent.js +44 -2
  6. package/dist/cjs/view/HoverCard/index.js +23 -6
  7. package/dist/es2019/utils/analytics/SmartLinkAnalyticsContext.js +3 -1
  8. package/dist/es2019/version.json +1 -1
  9. package/dist/es2019/view/HoverCard/components/HoverCardComponent.js +56 -48
  10. package/dist/es2019/view/HoverCard/components/HoverCardContent.js +45 -3
  11. package/dist/es2019/view/HoverCard/index.js +24 -7
  12. package/dist/esm/utils/analytics/SmartLinkAnalyticsContext.js +3 -1
  13. package/dist/esm/version.json +1 -1
  14. package/dist/esm/view/HoverCard/components/HoverCardComponent.js +45 -37
  15. package/dist/esm/view/HoverCard/components/HoverCardContent.js +45 -3
  16. package/dist/esm/view/HoverCard/index.js +24 -7
  17. package/dist/types/__fixtures__/jira-timeline.d.ts +35 -0
  18. package/dist/types/utils/analytics/SmartLinkAnalyticsContext.d.ts +1 -0
  19. package/dist/types/view/HoverCard/index.d.ts +2 -2
  20. package/dist/types/view/HoverCard/types.d.ts +4 -4
  21. package/dist/types-ts4.5/__fixtures__/jira-timeline.d.ts +35 -0
  22. package/dist/types-ts4.5/utils/analytics/SmartLinkAnalyticsContext.d.ts +1 -0
  23. package/dist/types-ts4.5/view/HoverCard/index.d.ts +2 -2
  24. package/dist/types-ts4.5/view/HoverCard/types.d.ts +4 -4
  25. package/package.json +7 -4
  26. package/report.api.md +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/smart-card
2
2
 
3
+ ## 26.3.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`6d9a4d28d94`](https://bitbucket.org/atlassian/atlassian-frontend/commits/6d9a4d28d94) - Fixes HoverCard component providing hover card analytics context to the wrapped trigger component.
8
+ - Updated dependencies
9
+
10
+ ## 26.3.2
11
+
12
+ ### Patch Changes
13
+
14
+ - [`f10ed88032c`](https://bitbucket.org/atlassian/atlassian-frontend/commits/f10ed88032c) - With the renaming of Jira Roadmaps to Timeline, we are updating the regex rules to match timeline in conjunction to roadmaps
15
+ - Updated dependencies
16
+
3
17
  ## 26.3.1
4
18
 
5
19
  ### Patch Changes
@@ -21,7 +21,8 @@ var SmartLinkAnalyticsContext = function SmartLinkAnalyticsContext(_ref) {
21
21
  var children = _ref.children,
22
22
  url = _ref.url,
23
23
  appearance = _ref.appearance,
24
- id = _ref.id;
24
+ id = _ref.id,
25
+ source = _ref.source;
25
26
  var _useSmartLinkState = (0, _store.useSmartCardState)(url),
26
27
  details = _useSmartLinkState.details,
27
28
  status = _useSmartLinkState.status;
@@ -36,6 +37,7 @@ var SmartLinkAnalyticsContext = function SmartLinkAnalyticsContext(_ref) {
36
37
  var display = isFlexibleUi ? _constants.CardDisplay.Flexible : appearance;
37
38
  return /*#__PURE__*/_react.default.createElement(_analyticsNext.AnalyticsContext, {
38
39
  data: {
40
+ source: source,
39
41
  attributes: _objectSpread(_objectSpread({}, resolvedAttributes), {}, {
40
42
  urlHash: urlHash,
41
43
  display: display,
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "26.3.1",
3
+ "version": "26.3.3",
4
4
  "sideEffects": false
5
5
  }
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.HoverCardComponent = void 0;
9
9
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
11
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
12
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
13
  var _popup = _interopRequireDefault(require("@atlaskit/popup"));
@@ -21,8 +22,9 @@ var _constants = require("../../../constants");
21
22
  var _SmartLinkAnalyticsContext = require("../../../utils/analytics/SmartLinkAnalyticsContext");
22
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); }
23
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; }
24
- /** @jsx jsx */
25
-
25
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
26
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } /** @jsx jsx */
27
+ var HOVER_CARD_SOURCE = 'smartLinkPreviewHoverCard';
26
28
  var HoverCardComponent = function HoverCardComponent(_ref) {
27
29
  var children = _ref.children,
28
30
  url = _ref.url,
@@ -63,18 +65,24 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
63
65
  };
64
66
  }, [isOpen]);
65
67
  var hideCard = (0, _react2.useCallback)(function () {
66
- //Check its previously open to avoid firing events when moving between the child and hover card components
67
- if (isOpen === true && cardOpenTime.current) {
68
- var hoverTime = Date.now() - cardOpenTime.current;
69
- analytics.ui.hoverCardDismissedEvent({
70
- previewDisplay: 'card',
71
- hoverTime: hoverTime,
72
- previewInvokeMethod: 'mouse_hover',
73
- status: linkStatus
74
- });
68
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-card.refactor-hover-card-analytics')) {
69
+ /**
70
+ * Defer to inner HoverCardContent to fire this event
71
+ */
72
+ } else {
73
+ //Check its previously open to avoid firing events when moving between the child and hover card components
74
+ if (isOpen === true && cardOpenTime.current) {
75
+ var hoverTime = Date.now() - cardOpenTime.current;
76
+ analytics === null || analytics === void 0 ? void 0 : analytics.ui.hoverCardDismissedEvent({
77
+ previewDisplay: 'card',
78
+ hoverTime: hoverTime,
79
+ previewInvokeMethod: 'mouse_hover',
80
+ status: linkStatus
81
+ });
82
+ }
75
83
  }
76
84
  setIsOpen(false);
77
- }, [analytics.ui, isOpen, linkStatus]);
85
+ }, [analytics, isOpen, linkStatus]);
78
86
  var initHideCard = (0, _react2.useCallback)(function () {
79
87
  if (fadeInTimeoutId.current) {
80
88
  clearTimeout(fadeInTimeoutId.current);
@@ -90,14 +98,20 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
90
98
  //Set mouse position in the case it's not already set by onMouseMove, as in the case of scrolling
91
99
  setMousePosition(event);
92
100
  fadeInTimeoutId.current = setTimeout(function () {
93
- //Check if its previously closed to avoid firing events when moving between the child and hover card components
94
- if (isOpen === false) {
95
- cardOpenTime.current = Date.now();
96
- analytics.ui.hoverCardViewedEvent({
97
- previewDisplay: hoverDisplay,
98
- previewInvokeMethod: invokeMethod,
99
- status: linkStatus
100
- });
101
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-card.refactor-hover-card-analytics')) {
102
+ /**
103
+ * Defer to inner HoverCardContent to fire this event
104
+ */
105
+ } else {
106
+ //Check if its previously closed to avoid firing events when moving between the child and hover card components
107
+ if (isOpen === false) {
108
+ cardOpenTime.current = Date.now();
109
+ analytics === null || analytics === void 0 ? void 0 : analytics.ui.hoverCardViewedEvent({
110
+ previewDisplay: hoverDisplay,
111
+ previewInvokeMethod: invokeMethod,
112
+ status: linkStatus
113
+ });
114
+ }
101
115
  }
102
116
  //If these are undefined then popupOffset is undefined and we fallback to default bottom-start placement
103
117
  if (parentSpan.current && mousePos.current) {
@@ -108,12 +122,12 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
108
122
  }
109
123
  setIsOpen(true);
110
124
  }, delay);
111
- }, [isOpen, setMousePosition, analytics.ui, linkStatus]);
125
+ }, [isOpen, setMousePosition, analytics, linkStatus]);
112
126
  var linkActions = (0, _useSmartLinkActions.useSmartLinkActions)({
113
127
  url: url,
114
128
  appearance: _constants.CardDisplay.HoverCardPreview,
115
129
  analyticsHandler: analyticsHandler,
116
- origin: 'smartLinkPreviewHoverCard'
130
+ origin: HOVER_CARD_SOURCE
117
131
  });
118
132
  var filteredActions = (0, _react2.useMemo)(function () {
119
133
  return hidePreviewButton ? linkActions.filter(function (action) {
@@ -136,14 +150,9 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
136
150
  }, [closeOnChildClick, hideCard]);
137
151
  var content = (0, _react2.useCallback)(function (_ref2) {
138
152
  var update = _ref2.update;
139
- return (0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-card.enable-analytics-context') ? (0, _react.jsx)(_SmartLinkAnalyticsContext.SmartLinkAnalyticsContext, {
140
- url: url,
141
- appearance: _constants.CardDisplay.HoverCardPreview,
142
- id: id
143
- }, (0, _react.jsx)(_HoverCardContent.default, {
153
+ var hoverCardContentProps = _objectSpread({
144
154
  onMouseEnter: initShowCard,
145
155
  onMouseLeave: initHideCard,
146
- analytics: analytics,
147
156
  cardActions: filteredActions,
148
157
  cardState: linkState,
149
158
  onActionClick: onActionClick,
@@ -152,18 +161,15 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
152
161
  showServerActions: showServerActions,
153
162
  url: url,
154
163
  id: id
155
- })) : (0, _react.jsx)(_HoverCardContent.default, {
156
- onMouseEnter: initShowCard,
157
- onMouseLeave: initHideCard,
158
- analytics: analytics,
159
- cardActions: filteredActions,
160
- cardState: linkState,
161
- onActionClick: onActionClick,
162
- onResolve: update,
163
- renderers: renderers,
164
- showServerActions: showServerActions,
165
- url: url
164
+ }, (0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-card.refactor-hover-card-analytics') ? {} : {
165
+ analytics: analytics
166
166
  });
167
+ return (0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-card.enable-analytics-context') ? (0, _react.jsx)(_SmartLinkAnalyticsContext.SmartLinkAnalyticsContext, {
168
+ url: url,
169
+ appearance: _constants.CardDisplay.HoverCardPreview,
170
+ id: id,
171
+ source: HOVER_CARD_SOURCE
172
+ }, (0, _react.jsx)(_HoverCardContent.default, hoverCardContentProps)) : (0, _react.jsx)(_HoverCardContent.default, hoverCardContentProps);
167
173
  }, [analytics, initHideCard, initShowCard, filteredActions, linkState, onActionClick, renderers, showServerActions, url, id]);
168
174
  var trigger = (0, _react2.useCallback)(function (triggerProps) {
169
175
  return (0, _react.jsx)("span", {
@@ -9,12 +9,14 @@ exports.hoverCardClassName = exports.getOpenAction = exports.getCopyAction = exp
9
9
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
10
10
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
11
11
  var _react = require("@emotion/react");
12
+ var _analyticsNext = require("@atlaskit/analytics-next");
13
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
14
  var _shortcut = _interopRequireDefault(require("@atlaskit/icon/glyph/shortcut"));
13
15
  var _copy = _interopRequireDefault(require("@atlaskit/icon/glyph/copy"));
14
- var _analyticsNext = require("@atlaskit/analytics-next");
15
16
  var _react2 = _interopRequireWildcard(require("react"));
16
17
  var _constants = require("../../../constants");
17
18
  var _extractMetadata2 = require("../../../extractors/hover/extractMetadata");
19
+ var _analytics2 = require("../../../state/analytics");
18
20
  var _helpers = require("../../../state/helpers");
19
21
  var _utils = require("../../../utils");
20
22
  var _styled = require("../styled");
@@ -26,6 +28,7 @@ var _reactIntlNext = require("react-intl-next");
26
28
  var _messages = require("../../../messages");
27
29
  var _actions = require("../../../state/actions");
28
30
  var _click = require("../../../utils/analytics/click");
31
+ var _store = require("../../../state/store");
29
32
  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); }
30
33
  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; }
31
34
  /** @jsx jsx */
@@ -91,7 +94,7 @@ var HoverCardContent = function HoverCardContent(_ref) {
91
94
  var _cardState$details;
92
95
  var _ref$id = _ref.id,
93
96
  id = _ref$id === void 0 ? '' : _ref$id,
94
- analytics = _ref.analytics,
97
+ _analytics = _ref.analytics,
95
98
  _ref$cardActions = _ref.cardActions,
96
99
  cardActions = _ref$cardActions === void 0 ? [] : _ref$cardActions,
97
100
  cardState = _ref.cardState,
@@ -104,13 +107,52 @@ var HoverCardContent = function HoverCardContent(_ref) {
104
107
  showServerActions = _ref.showServerActions;
105
108
  var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(),
106
109
  createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
110
+ var defaultAnalytics = (0, _analytics2.useSmartLinkAnalytics)(url, undefined, id);
111
+ var analytics = _analytics !== null && _analytics !== void 0 ? _analytics : defaultAnalytics;
107
112
  var extensionKey = (0, _react2.useMemo)(function () {
108
113
  return (0, _helpers.getExtensionKey)(cardState.details);
109
114
  }, [cardState.details]);
110
115
  var actions = (0, _actions.useSmartCardActions)(id, url, analytics);
116
+ var linkState = (0, _store.useSmartCardState)(url);
117
+ var linkStatus = linkState.status;
118
+ var statusRef = (0, _react2.useRef)(linkStatus);
119
+ var analyticsRef = (0, _react2.useRef)(analytics);
111
120
  (0, _react2.useEffect)(function () {
112
121
  actions.loadMetadata();
113
122
  }, [actions]);
123
+ (0, _react2.useEffect)(function () {
124
+ /**
125
+ * Must access current analytics object value via ref because its not stable
126
+ * and it can trigger useEffect to re-run below
127
+ */
128
+ if (analyticsRef.current !== analytics) {
129
+ analyticsRef.current = analytics;
130
+ }
131
+ if (statusRef.current !== linkStatus) {
132
+ statusRef.current = linkStatus;
133
+ }
134
+ }, [analytics, linkStatus]);
135
+ (0, _react2.useEffect)(function () {
136
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-card.refactor-hover-card-analytics')) {
137
+ var previewDisplay = 'card';
138
+ var previewInvokeMethod = 'mouse_hover';
139
+ var cardOpenTime = Date.now();
140
+ analyticsRef.current.ui.hoverCardViewedEvent({
141
+ previewDisplay: previewDisplay,
142
+ previewInvokeMethod: previewInvokeMethod,
143
+ status: statusRef.current
144
+ });
145
+ return function () {
146
+ var hoverTime = Date.now() - cardOpenTime;
147
+ analyticsRef.current.ui.hoverCardDismissedEvent({
148
+ previewDisplay: previewDisplay,
149
+ previewInvokeMethod: previewInvokeMethod,
150
+ hoverTime: hoverTime,
151
+ status: statusRef.current
152
+ });
153
+ };
154
+ }
155
+ }, []);
114
156
  var onClick = (0, _react2.useCallback)(function (event) {
115
157
  var isModifierKeyPressed = (0, _utils.isSpecialEvent)(event);
116
158
  analytics.ui.cardClickedEvent({
@@ -10,6 +10,7 @@ var _analyticsNext = require("@atlaskit/analytics-next");
10
10
  var _react = require("@emotion/react");
11
11
  var _react2 = require("react");
12
12
  var _reactErrorBoundary = require("react-error-boundary");
13
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
13
14
  var _analytics = require("../../state/analytics");
14
15
  var _analytics2 = require("../../utils/analytics");
15
16
  var _HoverCardComponent = require("./components/HoverCardComponent");
@@ -24,7 +25,11 @@ var HoverCardWithErrorBoundary = function HoverCardWithErrorBoundary(props) {
24
25
  var analyticsHandler = (0, _react2.useCallback)(function (analyticsPayload) {
25
26
  (0, _analytics2.fireSmartLinkEvent)(analyticsPayload, createAnalyticsEvent);
26
27
  }, [createAnalyticsEvent]);
27
- var analytics = (0, _analytics.useSmartLinkAnalytics)(url, analyticsHandler, id);
28
+
29
+ /**
30
+ * Feature flag disables prop drilling of analytics handlers
31
+ */
32
+ var analytics = (0, _analytics.useSmartLinkAnalytics)(url, (0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-card.refactor-hover-card-analytics') ? undefined : analyticsHandler, id);
28
33
  var onError = (0, _react2.useCallback)(function (error, info) {
29
34
  analytics.ui.renderFailedEvent({
30
35
  display: _constants.CardDisplay.HoverCardPreview,
@@ -33,18 +38,30 @@ var HoverCardWithErrorBoundary = function HoverCardWithErrorBoundary(props) {
33
38
  errorInfo: info
34
39
  });
35
40
  }, [analytics.ui, id]);
41
+
42
+ /**
43
+ * Feature flag disables the prop drilling of analytics handlers to hover card component
44
+ */
45
+ var analyticsProps = (0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-card.refactor-hover-card-analytics') ? {} : {
46
+ analyticsHandler: analyticsHandler,
47
+ analytics: analytics
48
+ };
36
49
  return (0, _react.jsx)(_reactErrorBoundary.ErrorBoundary, {
37
50
  fallback: children,
38
51
  onError: onError
39
- }, (0, _react.jsx)(_HoverCardComponent.HoverCardComponent, (0, _extends2.default)({}, props, {
40
- analyticsHandler: analyticsHandler,
41
- analytics: analytics
42
- }), children));
52
+ }, (0, _react.jsx)(_HoverCardComponent.HoverCardComponent, (0, _extends2.default)({}, props, analyticsProps), children));
43
53
  };
44
- var HoverCard = (0, _analyticsNext.withAnalyticsContext)({
54
+ var HoverCardWithAnalyticsContext = (0, _analyticsNext.withAnalyticsContext)({
45
55
  source: 'smartLinkPreviewHoverCard',
46
56
  attributes: {
47
57
  display: _constants.CardDisplay.HoverCardPreview
48
58
  }
49
59
  })((0, _analyticsNext.withAnalyticsEvents)()(HoverCardWithErrorBoundary));
60
+ var HoverCardWithoutAnalyticsContext = (0, _analyticsNext.withAnalyticsEvents)()(HoverCardWithErrorBoundary);
61
+ var HoverCard = function HoverCard(props) {
62
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-card.refactor-hover-card-analytics')) {
63
+ return (0, _react.jsx)(HoverCardWithoutAnalyticsContext, props);
64
+ }
65
+ return (0, _react.jsx)(HoverCardWithAnalyticsContext, props);
66
+ };
50
67
  exports.HoverCard = HoverCard;
@@ -8,7 +8,8 @@ export const SmartLinkAnalyticsContext = ({
8
8
  children,
9
9
  url,
10
10
  appearance,
11
- id
11
+ id,
12
+ source
12
13
  }) => {
13
14
  const {
14
15
  details,
@@ -24,6 +25,7 @@ export const SmartLinkAnalyticsContext = ({
24
25
  const display = isFlexibleUi ? CardDisplay.Flexible : appearance;
25
26
  return /*#__PURE__*/React.createElement(AnalyticsContext, {
26
27
  data: {
28
+ source,
27
29
  attributes: {
28
30
  ...resolvedAttributes,
29
31
  urlHash,
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "26.3.1",
3
+ "version": "26.3.3",
4
4
  "sideEffects": false
5
5
  }
@@ -11,6 +11,7 @@ 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
+ const HOVER_CARD_SOURCE = 'smartLinkPreviewHoverCard';
14
15
  export const HoverCardComponent = ({
15
16
  children,
16
17
  url,
@@ -45,18 +46,24 @@ export const HoverCardComponent = ({
45
46
  };
46
47
  }, [isOpen]);
47
48
  const hideCard = useCallback(() => {
48
- //Check its previously open to avoid firing events when moving between the child and hover card components
49
- if (isOpen === true && cardOpenTime.current) {
50
- const hoverTime = Date.now() - cardOpenTime.current;
51
- analytics.ui.hoverCardDismissedEvent({
52
- previewDisplay: 'card',
53
- hoverTime,
54
- previewInvokeMethod: 'mouse_hover',
55
- status: linkStatus
56
- });
49
+ if (getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics')) {
50
+ /**
51
+ * Defer to inner HoverCardContent to fire this event
52
+ */
53
+ } else {
54
+ //Check its previously open to avoid firing events when moving between the child and hover card components
55
+ if (isOpen === true && cardOpenTime.current) {
56
+ const hoverTime = Date.now() - cardOpenTime.current;
57
+ analytics === null || analytics === void 0 ? void 0 : analytics.ui.hoverCardDismissedEvent({
58
+ previewDisplay: 'card',
59
+ hoverTime,
60
+ previewInvokeMethod: 'mouse_hover',
61
+ status: linkStatus
62
+ });
63
+ }
57
64
  }
58
65
  setIsOpen(false);
59
- }, [analytics.ui, isOpen, linkStatus]);
66
+ }, [analytics, isOpen, linkStatus]);
60
67
  const initHideCard = useCallback(() => {
61
68
  if (fadeInTimeoutId.current) {
62
69
  clearTimeout(fadeInTimeoutId.current);
@@ -70,14 +77,20 @@ export const HoverCardComponent = ({
70
77
  //Set mouse position in the case it's not already set by onMouseMove, as in the case of scrolling
71
78
  setMousePosition(event);
72
79
  fadeInTimeoutId.current = setTimeout(() => {
73
- //Check if its previously closed to avoid firing events when moving between the child and hover card components
74
- if (isOpen === false) {
75
- cardOpenTime.current = Date.now();
76
- analytics.ui.hoverCardViewedEvent({
77
- previewDisplay: hoverDisplay,
78
- previewInvokeMethod: invokeMethod,
79
- status: linkStatus
80
- });
80
+ if (getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics')) {
81
+ /**
82
+ * Defer to inner HoverCardContent to fire this event
83
+ */
84
+ } else {
85
+ //Check if its previously closed to avoid firing events when moving between the child and hover card components
86
+ if (isOpen === false) {
87
+ cardOpenTime.current = Date.now();
88
+ analytics === null || analytics === void 0 ? void 0 : analytics.ui.hoverCardViewedEvent({
89
+ previewDisplay: hoverDisplay,
90
+ previewInvokeMethod: invokeMethod,
91
+ status: linkStatus
92
+ });
93
+ }
81
94
  }
82
95
  //If these are undefined then popupOffset is undefined and we fallback to default bottom-start placement
83
96
  if (parentSpan.current && mousePos.current) {
@@ -89,12 +102,12 @@ export const HoverCardComponent = ({
89
102
  }
90
103
  setIsOpen(true);
91
104
  }, delay);
92
- }, [isOpen, setMousePosition, analytics.ui, linkStatus]);
105
+ }, [isOpen, setMousePosition, analytics, linkStatus]);
93
106
  const linkActions = useSmartLinkActions({
94
107
  url,
95
108
  appearance: CardDisplay.HoverCardPreview,
96
109
  analyticsHandler,
97
- origin: 'smartLinkPreviewHoverCard'
110
+ origin: HOVER_CARD_SOURCE
98
111
  });
99
112
  const filteredActions = useMemo(() => {
100
113
  return hidePreviewButton ? linkActions.filter(action => action.id !== 'preview-content') : linkActions;
@@ -115,34 +128,29 @@ export const HoverCardComponent = ({
115
128
  }, [closeOnChildClick, hideCard]);
116
129
  const content = useCallback(({
117
130
  update
118
- }) => getBooleanFF('platform.linking-platform.smart-card.enable-analytics-context') ? jsx(SmartLinkAnalyticsContext, {
119
- url: url,
120
- appearance: CardDisplay.HoverCardPreview,
121
- id: id
122
- }, jsx(HoverCardContent, {
123
- onMouseEnter: initShowCard,
124
- onMouseLeave: initHideCard,
125
- analytics: analytics,
126
- cardActions: filteredActions,
127
- cardState: linkState,
128
- onActionClick: onActionClick,
129
- onResolve: update,
130
- renderers: renderers,
131
- showServerActions: showServerActions,
132
- url: url,
133
- id: id
134
- })) : jsx(HoverCardContent, {
135
- onMouseEnter: initShowCard,
136
- onMouseLeave: initHideCard,
137
- analytics: analytics,
138
- cardActions: filteredActions,
139
- cardState: linkState,
140
- onActionClick: onActionClick,
141
- onResolve: update,
142
- renderers: renderers,
143
- showServerActions: showServerActions,
144
- url: url
145
- }), [analytics, initHideCard, initShowCard, filteredActions, linkState, onActionClick, renderers, showServerActions, url, id]);
131
+ }) => {
132
+ const hoverCardContentProps = {
133
+ onMouseEnter: initShowCard,
134
+ onMouseLeave: initHideCard,
135
+ cardActions: filteredActions,
136
+ cardState: linkState,
137
+ onActionClick,
138
+ onResolve: update,
139
+ renderers,
140
+ showServerActions,
141
+ url,
142
+ id,
143
+ ...(getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics') ? {} : {
144
+ analytics
145
+ })
146
+ };
147
+ return getBooleanFF('platform.linking-platform.smart-card.enable-analytics-context') ? jsx(SmartLinkAnalyticsContext, {
148
+ url: url,
149
+ appearance: CardDisplay.HoverCardPreview,
150
+ id: id,
151
+ source: HOVER_CARD_SOURCE
152
+ }, jsx(HoverCardContent, hoverCardContentProps)) : jsx(HoverCardContent, hoverCardContentProps);
153
+ }, [analytics, initHideCard, initShowCard, filteredActions, linkState, onActionClick, renderers, showServerActions, url, id]);
146
154
  const trigger = useCallback(triggerProps => jsx("span", {
147
155
  ref: parentSpan
148
156
  }, jsx("span", _extends({}, triggerProps, {
@@ -1,11 +1,13 @@
1
1
  /** @jsx jsx */
2
2
  import { jsx } from '@emotion/react';
3
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
4
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
3
5
  import ShortcutIcon from '@atlaskit/icon/glyph/shortcut';
4
6
  import CopyIcon from '@atlaskit/icon/glyph/copy';
5
- import { useAnalyticsEvents } from '@atlaskit/analytics-next';
6
- import React, { useCallback, useEffect, useMemo } from 'react';
7
+ import React, { useCallback, useEffect, useMemo, useRef } from 'react';
7
8
  import { ActionName, CardDisplay, SmartLinkPosition, SmartLinkSize } from '../../../constants';
8
9
  import { extractMetadata } from '../../../extractors/hover/extractMetadata';
10
+ import { useSmartLinkAnalytics } from '../../../state/analytics';
9
11
  import { getExtensionKey } from '../../../state/helpers';
10
12
  import { isSpecialEvent } from '../../../utils';
11
13
  import { HoverCardContainer, flexibleUiOptions, titleBlockCss } from '../styled';
@@ -17,6 +19,7 @@ import { FormattedMessage } from 'react-intl-next';
17
19
  import { messages } from '../../../messages';
18
20
  import { useSmartCardActions } from '../../../state/actions';
19
21
  import { fireLinkClickedEvent } from '../../../utils/analytics/click';
22
+ import { useSmartCardState } from '../../../state/store';
20
23
  export const hoverCardClassName = 'smart-links-hover-preview';
21
24
  export const getOpenAction = (url, analytics, onActionClick) => ({
22
25
  name: ActionName.CustomAction,
@@ -50,7 +53,7 @@ export const getCopyAction = url => ({
50
53
  });
51
54
  const HoverCardContent = ({
52
55
  id = '',
53
- analytics,
56
+ analytics: _analytics,
54
57
  cardActions = [],
55
58
  cardState,
56
59
  onActionClick,
@@ -65,11 +68,50 @@ const HoverCardContent = ({
65
68
  const {
66
69
  createAnalyticsEvent
67
70
  } = useAnalyticsEvents();
71
+ const defaultAnalytics = useSmartLinkAnalytics(url, undefined, id);
72
+ const analytics = _analytics !== null && _analytics !== void 0 ? _analytics : defaultAnalytics;
68
73
  const extensionKey = useMemo(() => getExtensionKey(cardState.details), [cardState.details]);
69
74
  const actions = useSmartCardActions(id, url, analytics);
75
+ const linkState = useSmartCardState(url);
76
+ const linkStatus = linkState.status;
77
+ const statusRef = useRef(linkStatus);
78
+ const analyticsRef = useRef(analytics);
70
79
  useEffect(() => {
71
80
  actions.loadMetadata();
72
81
  }, [actions]);
82
+ useEffect(() => {
83
+ /**
84
+ * Must access current analytics object value via ref because its not stable
85
+ * and it can trigger useEffect to re-run below
86
+ */
87
+ if (analyticsRef.current !== analytics) {
88
+ analyticsRef.current = analytics;
89
+ }
90
+ if (statusRef.current !== linkStatus) {
91
+ statusRef.current = linkStatus;
92
+ }
93
+ }, [analytics, linkStatus]);
94
+ useEffect(() => {
95
+ if (getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics')) {
96
+ const previewDisplay = 'card';
97
+ const previewInvokeMethod = 'mouse_hover';
98
+ const cardOpenTime = Date.now();
99
+ analyticsRef.current.ui.hoverCardViewedEvent({
100
+ previewDisplay,
101
+ previewInvokeMethod,
102
+ status: statusRef.current
103
+ });
104
+ return () => {
105
+ const hoverTime = Date.now() - cardOpenTime;
106
+ analyticsRef.current.ui.hoverCardDismissedEvent({
107
+ previewDisplay,
108
+ previewInvokeMethod,
109
+ hoverTime,
110
+ status: statusRef.current
111
+ });
112
+ };
113
+ }
114
+ }, []);
73
115
  const onClick = useCallback(event => {
74
116
  const isModifierKeyPressed = isSpecialEvent(event);
75
117
  analytics.ui.cardClickedEvent({
@@ -4,6 +4,7 @@ import { withAnalyticsContext, withAnalyticsEvents } from '@atlaskit/analytics-n
4
4
  import { jsx } from '@emotion/react';
5
5
  import { useCallback } from 'react';
6
6
  import { ErrorBoundary } from 'react-error-boundary';
7
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
7
8
  import { useSmartLinkAnalytics } from '../../state/analytics';
8
9
  import { fireSmartLinkEvent } from '../../utils/analytics';
9
10
  import { HoverCardComponent } from './components/HoverCardComponent';
@@ -18,7 +19,11 @@ const HoverCardWithErrorBoundary = props => {
18
19
  const analyticsHandler = useCallback(analyticsPayload => {
19
20
  fireSmartLinkEvent(analyticsPayload, createAnalyticsEvent);
20
21
  }, [createAnalyticsEvent]);
21
- const analytics = useSmartLinkAnalytics(url, analyticsHandler, id);
22
+
23
+ /**
24
+ * Feature flag disables prop drilling of analytics handlers
25
+ */
26
+ const analytics = useSmartLinkAnalytics(url, getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics') ? undefined : analyticsHandler, id);
22
27
  const onError = useCallback((error, info) => {
23
28
  analytics.ui.renderFailedEvent({
24
29
  display: CardDisplay.HoverCardPreview,
@@ -27,17 +32,29 @@ const HoverCardWithErrorBoundary = props => {
27
32
  errorInfo: info
28
33
  });
29
34
  }, [analytics.ui, id]);
35
+
36
+ /**
37
+ * Feature flag disables the prop drilling of analytics handlers to hover card component
38
+ */
39
+ const analyticsProps = getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics') ? {} : {
40
+ analyticsHandler,
41
+ analytics
42
+ };
30
43
  return jsx(ErrorBoundary, {
31
44
  fallback: children,
32
45
  onError: onError
33
- }, jsx(HoverCardComponent, _extends({}, props, {
34
- analyticsHandler: analyticsHandler,
35
- analytics: analytics
36
- }), children));
46
+ }, jsx(HoverCardComponent, _extends({}, props, analyticsProps), children));
37
47
  };
38
- export const HoverCard = withAnalyticsContext({
48
+ const HoverCardWithAnalyticsContext = withAnalyticsContext({
39
49
  source: 'smartLinkPreviewHoverCard',
40
50
  attributes: {
41
51
  display: CardDisplay.HoverCardPreview
42
52
  }
43
- })(withAnalyticsEvents()(HoverCardWithErrorBoundary));
53
+ })(withAnalyticsEvents()(HoverCardWithErrorBoundary));
54
+ const HoverCardWithoutAnalyticsContext = withAnalyticsEvents()(HoverCardWithErrorBoundary);
55
+ export const HoverCard = props => {
56
+ if (getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics')) {
57
+ return jsx(HoverCardWithoutAnalyticsContext, props);
58
+ }
59
+ return jsx(HoverCardWithAnalyticsContext, props);
60
+ };
@@ -11,7 +11,8 @@ export var SmartLinkAnalyticsContext = function SmartLinkAnalyticsContext(_ref)
11
11
  var children = _ref.children,
12
12
  url = _ref.url,
13
13
  appearance = _ref.appearance,
14
- id = _ref.id;
14
+ id = _ref.id,
15
+ source = _ref.source;
15
16
  var _useSmartLinkState = useSmartLinkState(url),
16
17
  details = _useSmartLinkState.details,
17
18
  status = _useSmartLinkState.status;
@@ -26,6 +27,7 @@ export var SmartLinkAnalyticsContext = function SmartLinkAnalyticsContext(_ref)
26
27
  var display = isFlexibleUi ? CardDisplay.Flexible : appearance;
27
28
  return /*#__PURE__*/React.createElement(AnalyticsContext, {
28
29
  data: {
30
+ source: source,
29
31
  attributes: _objectSpread(_objectSpread({}, resolvedAttributes), {}, {
30
32
  urlHash: urlHash,
31
33
  display: display,
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "26.3.1",
3
+ "version": "26.3.3",
4
4
  "sideEffects": false
5
5
  }
@@ -1,5 +1,8 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
3
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
5
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
3
6
  /** @jsx jsx */
4
7
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
5
8
  import Popup from '@atlaskit/popup';
@@ -12,6 +15,7 @@ import HoverCardContent from '../components/HoverCardContent';
12
15
  import { CARD_GAP_PX, HOVER_CARD_Z_INDEX } from '../styled';
13
16
  import { CardDisplay } from '../../../constants';
14
17
  import { SmartLinkAnalyticsContext } from '../../../utils/analytics/SmartLinkAnalyticsContext';
18
+ var HOVER_CARD_SOURCE = 'smartLinkPreviewHoverCard';
15
19
  export var HoverCardComponent = function HoverCardComponent(_ref) {
16
20
  var children = _ref.children,
17
21
  url = _ref.url,
@@ -52,18 +56,24 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
52
56
  };
53
57
  }, [isOpen]);
54
58
  var hideCard = useCallback(function () {
55
- //Check its previously open to avoid firing events when moving between the child and hover card components
56
- if (isOpen === true && cardOpenTime.current) {
57
- var hoverTime = Date.now() - cardOpenTime.current;
58
- analytics.ui.hoverCardDismissedEvent({
59
- previewDisplay: 'card',
60
- hoverTime: hoverTime,
61
- previewInvokeMethod: 'mouse_hover',
62
- status: linkStatus
63
- });
59
+ if (getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics')) {
60
+ /**
61
+ * Defer to inner HoverCardContent to fire this event
62
+ */
63
+ } else {
64
+ //Check its previously open to avoid firing events when moving between the child and hover card components
65
+ if (isOpen === true && cardOpenTime.current) {
66
+ var hoverTime = Date.now() - cardOpenTime.current;
67
+ analytics === null || analytics === void 0 ? void 0 : analytics.ui.hoverCardDismissedEvent({
68
+ previewDisplay: 'card',
69
+ hoverTime: hoverTime,
70
+ previewInvokeMethod: 'mouse_hover',
71
+ status: linkStatus
72
+ });
73
+ }
64
74
  }
65
75
  setIsOpen(false);
66
- }, [analytics.ui, isOpen, linkStatus]);
76
+ }, [analytics, isOpen, linkStatus]);
67
77
  var initHideCard = useCallback(function () {
68
78
  if (fadeInTimeoutId.current) {
69
79
  clearTimeout(fadeInTimeoutId.current);
@@ -79,14 +89,20 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
79
89
  //Set mouse position in the case it's not already set by onMouseMove, as in the case of scrolling
80
90
  setMousePosition(event);
81
91
  fadeInTimeoutId.current = setTimeout(function () {
82
- //Check if its previously closed to avoid firing events when moving between the child and hover card components
83
- if (isOpen === false) {
84
- cardOpenTime.current = Date.now();
85
- analytics.ui.hoverCardViewedEvent({
86
- previewDisplay: hoverDisplay,
87
- previewInvokeMethod: invokeMethod,
88
- status: linkStatus
89
- });
92
+ if (getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics')) {
93
+ /**
94
+ * Defer to inner HoverCardContent to fire this event
95
+ */
96
+ } else {
97
+ //Check if its previously closed to avoid firing events when moving between the child and hover card components
98
+ if (isOpen === false) {
99
+ cardOpenTime.current = Date.now();
100
+ analytics === null || analytics === void 0 ? void 0 : analytics.ui.hoverCardViewedEvent({
101
+ previewDisplay: hoverDisplay,
102
+ previewInvokeMethod: invokeMethod,
103
+ status: linkStatus
104
+ });
105
+ }
90
106
  }
91
107
  //If these are undefined then popupOffset is undefined and we fallback to default bottom-start placement
92
108
  if (parentSpan.current && mousePos.current) {
@@ -97,12 +113,12 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
97
113
  }
98
114
  setIsOpen(true);
99
115
  }, delay);
100
- }, [isOpen, setMousePosition, analytics.ui, linkStatus]);
116
+ }, [isOpen, setMousePosition, analytics, linkStatus]);
101
117
  var linkActions = useSmartLinkActions({
102
118
  url: url,
103
119
  appearance: CardDisplay.HoverCardPreview,
104
120
  analyticsHandler: analyticsHandler,
105
- origin: 'smartLinkPreviewHoverCard'
121
+ origin: HOVER_CARD_SOURCE
106
122
  });
107
123
  var filteredActions = useMemo(function () {
108
124
  return hidePreviewButton ? linkActions.filter(function (action) {
@@ -125,14 +141,9 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
125
141
  }, [closeOnChildClick, hideCard]);
126
142
  var content = useCallback(function (_ref2) {
127
143
  var update = _ref2.update;
128
- return getBooleanFF('platform.linking-platform.smart-card.enable-analytics-context') ? jsx(SmartLinkAnalyticsContext, {
129
- url: url,
130
- appearance: CardDisplay.HoverCardPreview,
131
- id: id
132
- }, jsx(HoverCardContent, {
144
+ var hoverCardContentProps = _objectSpread({
133
145
  onMouseEnter: initShowCard,
134
146
  onMouseLeave: initHideCard,
135
- analytics: analytics,
136
147
  cardActions: filteredActions,
137
148
  cardState: linkState,
138
149
  onActionClick: onActionClick,
@@ -141,18 +152,15 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
141
152
  showServerActions: showServerActions,
142
153
  url: url,
143
154
  id: id
144
- })) : jsx(HoverCardContent, {
145
- onMouseEnter: initShowCard,
146
- onMouseLeave: initHideCard,
147
- analytics: analytics,
148
- cardActions: filteredActions,
149
- cardState: linkState,
150
- onActionClick: onActionClick,
151
- onResolve: update,
152
- renderers: renderers,
153
- showServerActions: showServerActions,
154
- url: url
155
+ }, getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics') ? {} : {
156
+ analytics: analytics
155
157
  });
158
+ return getBooleanFF('platform.linking-platform.smart-card.enable-analytics-context') ? jsx(SmartLinkAnalyticsContext, {
159
+ url: url,
160
+ appearance: CardDisplay.HoverCardPreview,
161
+ id: id,
162
+ source: HOVER_CARD_SOURCE
163
+ }, jsx(HoverCardContent, hoverCardContentProps)) : jsx(HoverCardContent, hoverCardContentProps);
156
164
  }, [analytics, initHideCard, initShowCard, filteredActions, linkState, onActionClick, renderers, showServerActions, url, id]);
157
165
  var trigger = useCallback(function (triggerProps) {
158
166
  return jsx("span", {
@@ -2,12 +2,14 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
2
  import _regeneratorRuntime from "@babel/runtime/regenerator";
3
3
  /** @jsx jsx */
4
4
  import { jsx } from '@emotion/react';
5
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
6
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
5
7
  import ShortcutIcon from '@atlaskit/icon/glyph/shortcut';
6
8
  import CopyIcon from '@atlaskit/icon/glyph/copy';
7
- import { useAnalyticsEvents } from '@atlaskit/analytics-next';
8
- import React, { useCallback, useEffect, useMemo } from 'react';
9
+ import React, { useCallback, useEffect, useMemo, useRef } from 'react';
9
10
  import { ActionName, CardDisplay, SmartLinkPosition, SmartLinkSize } from '../../../constants';
10
11
  import { extractMetadata } from '../../../extractors/hover/extractMetadata';
12
+ import { useSmartLinkAnalytics } from '../../../state/analytics';
11
13
  import { getExtensionKey } from '../../../state/helpers';
12
14
  import { isSpecialEvent } from '../../../utils';
13
15
  import { HoverCardContainer, flexibleUiOptions, titleBlockCss } from '../styled';
@@ -19,6 +21,7 @@ import { FormattedMessage } from 'react-intl-next';
19
21
  import { messages } from '../../../messages';
20
22
  import { useSmartCardActions } from '../../../state/actions';
21
23
  import { fireLinkClickedEvent } from '../../../utils/analytics/click';
24
+ import { useSmartCardState } from '../../../state/store';
22
25
  export var hoverCardClassName = 'smart-links-hover-preview';
23
26
  export var getOpenAction = function getOpenAction(url, analytics, onActionClick) {
24
27
  return {
@@ -77,7 +80,7 @@ var HoverCardContent = function HoverCardContent(_ref) {
77
80
  var _cardState$details;
78
81
  var _ref$id = _ref.id,
79
82
  id = _ref$id === void 0 ? '' : _ref$id,
80
- analytics = _ref.analytics,
83
+ _analytics = _ref.analytics,
81
84
  _ref$cardActions = _ref.cardActions,
82
85
  cardActions = _ref$cardActions === void 0 ? [] : _ref$cardActions,
83
86
  cardState = _ref.cardState,
@@ -90,13 +93,52 @@ var HoverCardContent = function HoverCardContent(_ref) {
90
93
  showServerActions = _ref.showServerActions;
91
94
  var _useAnalyticsEvents = useAnalyticsEvents(),
92
95
  createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
96
+ var defaultAnalytics = useSmartLinkAnalytics(url, undefined, id);
97
+ var analytics = _analytics !== null && _analytics !== void 0 ? _analytics : defaultAnalytics;
93
98
  var extensionKey = useMemo(function () {
94
99
  return getExtensionKey(cardState.details);
95
100
  }, [cardState.details]);
96
101
  var actions = useSmartCardActions(id, url, analytics);
102
+ var linkState = useSmartCardState(url);
103
+ var linkStatus = linkState.status;
104
+ var statusRef = useRef(linkStatus);
105
+ var analyticsRef = useRef(analytics);
97
106
  useEffect(function () {
98
107
  actions.loadMetadata();
99
108
  }, [actions]);
109
+ useEffect(function () {
110
+ /**
111
+ * Must access current analytics object value via ref because its not stable
112
+ * and it can trigger useEffect to re-run below
113
+ */
114
+ if (analyticsRef.current !== analytics) {
115
+ analyticsRef.current = analytics;
116
+ }
117
+ if (statusRef.current !== linkStatus) {
118
+ statusRef.current = linkStatus;
119
+ }
120
+ }, [analytics, linkStatus]);
121
+ useEffect(function () {
122
+ if (getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics')) {
123
+ var previewDisplay = 'card';
124
+ var previewInvokeMethod = 'mouse_hover';
125
+ var cardOpenTime = Date.now();
126
+ analyticsRef.current.ui.hoverCardViewedEvent({
127
+ previewDisplay: previewDisplay,
128
+ previewInvokeMethod: previewInvokeMethod,
129
+ status: statusRef.current
130
+ });
131
+ return function () {
132
+ var hoverTime = Date.now() - cardOpenTime;
133
+ analyticsRef.current.ui.hoverCardDismissedEvent({
134
+ previewDisplay: previewDisplay,
135
+ previewInvokeMethod: previewInvokeMethod,
136
+ hoverTime: hoverTime,
137
+ status: statusRef.current
138
+ });
139
+ };
140
+ }
141
+ }, []);
100
142
  var onClick = useCallback(function (event) {
101
143
  var isModifierKeyPressed = isSpecialEvent(event);
102
144
  analytics.ui.cardClickedEvent({
@@ -4,6 +4,7 @@ import { withAnalyticsContext, withAnalyticsEvents } from '@atlaskit/analytics-n
4
4
  import { jsx } from '@emotion/react';
5
5
  import { useCallback } from 'react';
6
6
  import { ErrorBoundary } from 'react-error-boundary';
7
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
7
8
  import { useSmartLinkAnalytics } from '../../state/analytics';
8
9
  import { fireSmartLinkEvent } from '../../utils/analytics';
9
10
  import { HoverCardComponent } from './components/HoverCardComponent';
@@ -16,7 +17,11 @@ var HoverCardWithErrorBoundary = function HoverCardWithErrorBoundary(props) {
16
17
  var analyticsHandler = useCallback(function (analyticsPayload) {
17
18
  fireSmartLinkEvent(analyticsPayload, createAnalyticsEvent);
18
19
  }, [createAnalyticsEvent]);
19
- var analytics = useSmartLinkAnalytics(url, analyticsHandler, id);
20
+
21
+ /**
22
+ * Feature flag disables prop drilling of analytics handlers
23
+ */
24
+ var analytics = useSmartLinkAnalytics(url, getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics') ? undefined : analyticsHandler, id);
20
25
  var onError = useCallback(function (error, info) {
21
26
  analytics.ui.renderFailedEvent({
22
27
  display: CardDisplay.HoverCardPreview,
@@ -25,17 +30,29 @@ var HoverCardWithErrorBoundary = function HoverCardWithErrorBoundary(props) {
25
30
  errorInfo: info
26
31
  });
27
32
  }, [analytics.ui, id]);
33
+
34
+ /**
35
+ * Feature flag disables the prop drilling of analytics handlers to hover card component
36
+ */
37
+ var analyticsProps = getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics') ? {} : {
38
+ analyticsHandler: analyticsHandler,
39
+ analytics: analytics
40
+ };
28
41
  return jsx(ErrorBoundary, {
29
42
  fallback: children,
30
43
  onError: onError
31
- }, jsx(HoverCardComponent, _extends({}, props, {
32
- analyticsHandler: analyticsHandler,
33
- analytics: analytics
34
- }), children));
44
+ }, jsx(HoverCardComponent, _extends({}, props, analyticsProps), children));
35
45
  };
36
- export var HoverCard = withAnalyticsContext({
46
+ var HoverCardWithAnalyticsContext = withAnalyticsContext({
37
47
  source: 'smartLinkPreviewHoverCard',
38
48
  attributes: {
39
49
  display: CardDisplay.HoverCardPreview
40
50
  }
41
- })(withAnalyticsEvents()(HoverCardWithErrorBoundary));
51
+ })(withAnalyticsEvents()(HoverCardWithErrorBoundary));
52
+ var HoverCardWithoutAnalyticsContext = withAnalyticsEvents()(HoverCardWithErrorBoundary);
53
+ export var HoverCard = function HoverCard(props) {
54
+ if (getBooleanFF('platform.linking-platform.smart-card.refactor-hover-card-analytics')) {
55
+ return jsx(HoverCardWithoutAnalyticsContext, props);
56
+ }
57
+ return jsx(HoverCardWithAnalyticsContext, props);
58
+ };
@@ -0,0 +1,35 @@
1
+ declare const _default: {
2
+ meta: {
3
+ auth: never[];
4
+ definitionId: string;
5
+ visibility: string;
6
+ access: string;
7
+ resourceType: string;
8
+ key: string;
9
+ };
10
+ data: {
11
+ '@context': {
12
+ '@vocab': string;
13
+ atlassian: string;
14
+ schema: string;
15
+ };
16
+ generator: {
17
+ '@type': string;
18
+ '@id': string;
19
+ name: string;
20
+ };
21
+ '@type': string[];
22
+ url: string;
23
+ name: string;
24
+ summary: string;
25
+ icon: {
26
+ '@type': string;
27
+ url: string;
28
+ };
29
+ preview: {
30
+ href: string;
31
+ 'atlassian:supportedPlatforms': string[];
32
+ };
33
+ };
34
+ };
35
+ export default _default;
@@ -4,6 +4,7 @@ type SmartLinkAnalyticsContextProps = {
4
4
  url: string;
5
5
  appearance: CardInnerAppearance;
6
6
  id: string | undefined;
7
+ source?: string;
7
8
  };
8
9
  export declare const SmartLinkAnalyticsContext: FC<SmartLinkAnalyticsContextProps>;
9
10
  export {};
@@ -1,3 +1,3 @@
1
- /// <reference types="react" />
1
+ import { jsx } from '@emotion/react';
2
2
  import { HoverCardProps } from './types';
3
- export declare const HoverCard: import("react").ForwardRefExoticComponent<Pick<Omit<import("react").PropsWithChildren<HoverCardProps>, keyof import("@atlaskit/analytics-next").WithAnalyticsEventsProps> & import("react").RefAttributes<any> & import("@atlaskit/analytics-next").WithContextProps, "url" | "children" | "key" | "id" | "analyticsContext" | "showServerActions" | "onAuthorize" | "canOpen" | "closeOnChildClick" | "hidePreviewButton"> & import("react").RefAttributes<any>>;
3
+ export declare const HoverCard: (props: HoverCardProps) => jsx.JSX.Element;
@@ -3,8 +3,8 @@ import { ElementItem } from '../FlexibleCard/components/blocks/types';
3
3
  import { AnalyticsFacade } from '../../state/analytics';
4
4
  import { LinkAction } from '../../state/hooks-external/useSmartLinkActions';
5
5
  import { CardState } from '@atlaskit/linking-common';
6
- import { CardProviderRenderers } from '@atlaskit/link-provider';
7
6
  import { AnalyticsHandler } from '../../utils/types';
7
+ import { CardProviderRenderers } from '@atlaskit/link-provider';
8
8
  import { ReactElement, MouseEventHandler } from 'react';
9
9
  import { JsonLd } from 'json-ld-types';
10
10
  export interface HoverCardProps extends WithAnalyticsEventsProps {
@@ -44,8 +44,8 @@ export interface HoverCardProps extends WithAnalyticsEventsProps {
44
44
  showServerActions?: boolean;
45
45
  }
46
46
  export interface HoverCardComponentProps extends HoverCardProps {
47
- analyticsHandler: AnalyticsHandler;
48
- analytics: AnalyticsFacade;
47
+ analyticsHandler?: AnalyticsHandler;
48
+ analytics?: AnalyticsFacade;
49
49
  canOpen?: boolean;
50
50
  closeOnChildClick?: boolean;
51
51
  }
@@ -58,7 +58,7 @@ export interface MetadataOptions {
58
58
  }
59
59
  export type HoverCardContentProps = {
60
60
  id?: string;
61
- analytics: AnalyticsFacade;
61
+ analytics?: AnalyticsFacade;
62
62
  cardActions?: LinkAction[];
63
63
  cardState: CardState;
64
64
  renderers?: CardProviderRenderers;
@@ -0,0 +1,35 @@
1
+ declare const _default: {
2
+ meta: {
3
+ auth: never[];
4
+ definitionId: string;
5
+ visibility: string;
6
+ access: string;
7
+ resourceType: string;
8
+ key: string;
9
+ };
10
+ data: {
11
+ '@context': {
12
+ '@vocab': string;
13
+ atlassian: string;
14
+ schema: string;
15
+ };
16
+ generator: {
17
+ '@type': string;
18
+ '@id': string;
19
+ name: string;
20
+ };
21
+ '@type': string[];
22
+ url: string;
23
+ name: string;
24
+ summary: string;
25
+ icon: {
26
+ '@type': string;
27
+ url: string;
28
+ };
29
+ preview: {
30
+ href: string;
31
+ 'atlassian:supportedPlatforms': string[];
32
+ };
33
+ };
34
+ };
35
+ export default _default;
@@ -4,6 +4,7 @@ type SmartLinkAnalyticsContextProps = {
4
4
  url: string;
5
5
  appearance: CardInnerAppearance;
6
6
  id: string | undefined;
7
+ source?: string;
7
8
  };
8
9
  export declare const SmartLinkAnalyticsContext: FC<SmartLinkAnalyticsContextProps>;
9
10
  export {};
@@ -1,3 +1,3 @@
1
- /// <reference types="react" />
1
+ import { jsx } from '@emotion/react';
2
2
  import { HoverCardProps } from './types';
3
- export declare const HoverCard: import("react").ForwardRefExoticComponent<Pick<Omit<import("react").PropsWithChildren<HoverCardProps>, keyof import("@atlaskit/analytics-next").WithAnalyticsEventsProps> & import("react").RefAttributes<any> & import("@atlaskit/analytics-next").WithContextProps, "url" | "children" | "key" | "id" | "analyticsContext" | "showServerActions" | "onAuthorize" | "canOpen" | "closeOnChildClick" | "hidePreviewButton"> & import("react").RefAttributes<any>>;
3
+ export declare const HoverCard: (props: HoverCardProps) => jsx.JSX.Element;
@@ -3,8 +3,8 @@ import { ElementItem } from '../FlexibleCard/components/blocks/types';
3
3
  import { AnalyticsFacade } from '../../state/analytics';
4
4
  import { LinkAction } from '../../state/hooks-external/useSmartLinkActions';
5
5
  import { CardState } from '@atlaskit/linking-common';
6
- import { CardProviderRenderers } from '@atlaskit/link-provider';
7
6
  import { AnalyticsHandler } from '../../utils/types';
7
+ import { CardProviderRenderers } from '@atlaskit/link-provider';
8
8
  import { ReactElement, MouseEventHandler } from 'react';
9
9
  import { JsonLd } from 'json-ld-types';
10
10
  export interface HoverCardProps extends WithAnalyticsEventsProps {
@@ -44,8 +44,8 @@ export interface HoverCardProps extends WithAnalyticsEventsProps {
44
44
  showServerActions?: boolean;
45
45
  }
46
46
  export interface HoverCardComponentProps extends HoverCardProps {
47
- analyticsHandler: AnalyticsHandler;
48
- analytics: AnalyticsFacade;
47
+ analyticsHandler?: AnalyticsHandler;
48
+ analytics?: AnalyticsFacade;
49
49
  canOpen?: boolean;
50
50
  closeOnChildClick?: boolean;
51
51
  }
@@ -58,7 +58,7 @@ export interface MetadataOptions {
58
58
  }
59
59
  export type HoverCardContentProps = {
60
60
  id?: string;
61
- analytics: AnalyticsFacade;
61
+ analytics?: AnalyticsFacade;
62
62
  cardActions?: LinkAction[];
63
63
  cardState: CardState;
64
64
  renderers?: CardProviderRenderers;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "26.3.1",
3
+ "version": "26.3.3",
4
4
  "description": "Smart card component",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -44,7 +44,7 @@
44
44
  "@atlaskit/link-analytics": "^8.0.2",
45
45
  "@atlaskit/link-client-extension": "^1.1.0",
46
46
  "@atlaskit/linking-common": "^2.12.0",
47
- "@atlaskit/linking-types": "^2.0.0",
47
+ "@atlaskit/linking-types": "^3.0.0",
48
48
  "@atlaskit/logo": "^13.14.0",
49
49
  "@atlaskit/lozenge": "^11.4.0",
50
50
  "@atlaskit/media-common": "^4.1.0",
@@ -71,7 +71,7 @@
71
71
  "uuid": "^3.1.0"
72
72
  },
73
73
  "peerDependencies": {
74
- "@atlaskit/link-provider": "^1.6.2",
74
+ "@atlaskit/link-provider": "^1.6.3",
75
75
  "react": "^16.8.0",
76
76
  "react-dom": "^16.8.0",
77
77
  "react-intl-next": "npm:react-intl@^5.18.1"
@@ -85,7 +85,7 @@
85
85
  "@atlaskit/field-base": "^15.2.0",
86
86
  "@atlaskit/form": "^8.11.0",
87
87
  "@atlaskit/inline-message": "^11.5.0",
88
- "@atlaskit/link-test-helpers": "^3.0.0",
88
+ "@atlaskit/link-test-helpers": "^4.0.0",
89
89
  "@atlaskit/lozenge": "^11.4.0",
90
90
  "@atlaskit/media-integration-test-helpers": "^2.6.0",
91
91
  "@atlaskit/media-test-helpers": "^33.0.0",
@@ -141,6 +141,9 @@
141
141
  "platform-feature-flags": {
142
142
  "platform.linking-platform.smart-card.enable-analytics-context": {
143
143
  "type": "boolean"
144
+ },
145
+ "platform.linking-platform.smart-card.refactor-hover-card-analytics": {
146
+ "type": "boolean"
144
147
  }
145
148
  },
146
149
  "prettier": "@atlassian/atlassian-frontend-prettier-config-1.0.1",
package/report.api.md CHANGED
@@ -1282,7 +1282,7 @@ type VoteCount = {
1282
1282
 
1283
1283
  ```json
1284
1284
  {
1285
- "@atlaskit/link-provider": "^1.6.2",
1285
+ "@atlaskit/link-provider": "^1.6.3",
1286
1286
  "react": "^16.8.0",
1287
1287
  "react-dom": "^16.8.0",
1288
1288
  "react-intl-next": "npm:react-intl@^5.18.1"