@atlaskit/smart-card 21.1.4 → 22.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 (105) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/dist/cjs/extractors/block/index.js +3 -2
  3. package/dist/cjs/extractors/common/actions/extractPreviewAction.js +12 -2
  4. package/dist/cjs/state/actions/index.js +54 -10
  5. package/dist/cjs/state/analytics/types.js +5 -0
  6. package/dist/cjs/state/analytics/useSmartLinkAnalytics.js +386 -109
  7. package/dist/cjs/state/hooks-external/useSmartLinkActions.js +12 -2
  8. package/dist/cjs/utils/analytics/analytics.js +239 -72
  9. package/dist/cjs/utils/analytics/index.js +32 -5
  10. package/dist/cjs/version.json +1 -1
  11. package/dist/cjs/view/BlockCard/actions/PreviewAction.js +1 -1
  12. package/dist/cjs/view/BlockCard/index.js +10 -0
  13. package/dist/cjs/view/CardWithUrl/component.js +26 -4
  14. package/dist/cjs/view/CardWithUrl/loader.js +6 -1
  15. package/dist/cjs/view/EmbedModal/components/size-experiment/index.js +41 -0
  16. package/dist/cjs/view/EmbedModal/components/size-experiment/types.js +5 -0
  17. package/dist/cjs/view/EmbedModal/index.js +7 -3
  18. package/dist/cjs/view/FlexibleCard/components/blocks/block/index.js +17 -3
  19. package/dist/cjs/view/FlexibleCard/components/blocks/preview-block/index.js +5 -2
  20. package/dist/cjs/view/FlexibleCard/components/common/atlaskit-icon/index.js +20 -8
  21. package/dist/cjs/view/FlexibleCard/components/common/image-icon/index.js +4 -2
  22. package/dist/cjs/view/FlexibleCard/components/common/loading-skeleton/index.js +1 -2
  23. package/dist/cjs/view/FlexibleCard/components/elements/media/index.js +5 -2
  24. package/dist/cjs/view/HoverCard/components/HoverCardComponent.js +9 -2
  25. package/dist/cjs/view/HoverCard/components/HoverCardContent.js +36 -8
  26. package/dist/cjs/view/HoverCard/components/SnippetOrPreview.js +74 -0
  27. package/dist/cjs/view/HoverCard/index.js +6 -1
  28. package/dist/cjs/view/HoverCard/styled.js +11 -3
  29. package/dist/es2019/extractors/block/index.js +2 -1
  30. package/dist/es2019/extractors/common/actions/extractPreviewAction.js +12 -3
  31. package/dist/es2019/state/actions/index.js +54 -10
  32. package/dist/es2019/state/analytics/types.js +1 -0
  33. package/dist/es2019/state/analytics/useSmartLinkAnalytics.js +379 -39
  34. package/dist/es2019/state/hooks-external/useSmartLinkActions.js +11 -2
  35. package/dist/es2019/utils/analytics/analytics.js +253 -78
  36. package/dist/es2019/utils/analytics/index.js +32 -4
  37. package/dist/es2019/version.json +1 -1
  38. package/dist/es2019/view/BlockCard/actions/PreviewAction.js +1 -1
  39. package/dist/es2019/view/BlockCard/index.js +9 -0
  40. package/dist/es2019/view/CardWithUrl/component.js +26 -4
  41. package/dist/es2019/view/CardWithUrl/loader.js +6 -1
  42. package/dist/es2019/view/EmbedModal/components/size-experiment/index.js +28 -0
  43. package/dist/es2019/view/EmbedModal/components/size-experiment/types.js +1 -0
  44. package/dist/es2019/view/EmbedModal/index.js +5 -3
  45. package/dist/es2019/view/FlexibleCard/components/blocks/block/index.js +17 -7
  46. package/dist/es2019/view/FlexibleCard/components/blocks/preview-block/index.js +4 -1
  47. package/dist/es2019/view/FlexibleCard/components/common/atlaskit-icon/index.js +17 -6
  48. package/dist/es2019/view/FlexibleCard/components/common/image-icon/index.js +4 -2
  49. package/dist/es2019/view/FlexibleCard/components/common/loading-skeleton/index.js +2 -3
  50. package/dist/es2019/view/FlexibleCard/components/elements/media/index.js +5 -2
  51. package/dist/es2019/view/HoverCard/components/HoverCardComponent.js +9 -2
  52. package/dist/es2019/view/HoverCard/components/HoverCardContent.js +36 -10
  53. package/dist/es2019/view/HoverCard/components/SnippetOrPreview.js +42 -0
  54. package/dist/es2019/view/HoverCard/index.js +6 -1
  55. package/dist/es2019/view/HoverCard/styled.js +8 -0
  56. package/dist/esm/extractors/block/index.js +3 -2
  57. package/dist/esm/extractors/common/actions/extractPreviewAction.js +12 -2
  58. package/dist/esm/state/actions/index.js +54 -10
  59. package/dist/esm/state/analytics/types.js +1 -0
  60. package/dist/esm/state/analytics/useSmartLinkAnalytics.js +383 -109
  61. package/dist/esm/state/hooks-external/useSmartLinkActions.js +11 -2
  62. package/dist/esm/utils/analytics/analytics.js +239 -72
  63. package/dist/esm/utils/analytics/index.js +31 -4
  64. package/dist/esm/version.json +1 -1
  65. package/dist/esm/view/BlockCard/actions/PreviewAction.js +1 -1
  66. package/dist/esm/view/BlockCard/index.js +9 -0
  67. package/dist/esm/view/CardWithUrl/component.js +26 -4
  68. package/dist/esm/view/CardWithUrl/loader.js +6 -1
  69. package/dist/esm/view/EmbedModal/components/size-experiment/index.js +28 -0
  70. package/dist/esm/view/EmbedModal/components/size-experiment/types.js +1 -0
  71. package/dist/esm/view/EmbedModal/index.js +6 -3
  72. package/dist/esm/view/FlexibleCard/components/blocks/block/index.js +11 -3
  73. package/dist/esm/view/FlexibleCard/components/blocks/preview-block/index.js +5 -2
  74. package/dist/esm/view/FlexibleCard/components/common/atlaskit-icon/index.js +18 -8
  75. package/dist/esm/view/FlexibleCard/components/common/image-icon/index.js +4 -2
  76. package/dist/esm/view/FlexibleCard/components/common/loading-skeleton/index.js +1 -2
  77. package/dist/esm/view/FlexibleCard/components/elements/media/index.js +5 -2
  78. package/dist/esm/view/HoverCard/components/HoverCardComponent.js +9 -2
  79. package/dist/esm/view/HoverCard/components/HoverCardContent.js +36 -10
  80. package/dist/esm/view/HoverCard/components/SnippetOrPreview.js +53 -0
  81. package/dist/esm/view/HoverCard/index.js +6 -1
  82. package/dist/esm/view/HoverCard/styled.js +6 -2
  83. package/dist/types/extractors/block/types.d.ts +2 -0
  84. package/dist/types/extractors/common/actions/extractPreviewAction.d.ts +2 -1
  85. package/dist/types/state/analytics/types.d.ts +9 -0
  86. package/dist/types/state/analytics/useSmartLinkAnalytics.d.ts +18 -23
  87. package/dist/types/state/hooks/useSmartLink.d.ts +17 -18
  88. package/dist/types/utils/analytics/analytics.d.ts +19 -21
  89. package/dist/types/utils/analytics/index.d.ts +2 -2
  90. package/dist/types/utils/analytics/types.d.ts +91 -0
  91. package/dist/types/view/BlockCard/actions/PreviewAction.d.ts +4 -2
  92. package/dist/types/view/Card/index.d.ts +1 -1
  93. package/dist/types/view/EmbedModal/components/size-experiment/index.d.ts +6 -0
  94. package/dist/types/view/EmbedModal/components/size-experiment/types.d.ts +4 -0
  95. package/dist/types/view/EmbedModal/index.d.ts +1 -1
  96. package/dist/types/view/EmbedModal/types.d.ts +4 -0
  97. package/dist/types/view/FlexibleCard/components/blocks/preview-block/types.d.ts +7 -1
  98. package/dist/types/view/FlexibleCard/components/blocks/types.d.ts +15 -0
  99. package/dist/types/view/FlexibleCard/components/common/image-icon/types.d.ts +1 -0
  100. package/dist/types/view/FlexibleCard/components/elements/media/types.d.ts +5 -0
  101. package/dist/types/view/HoverCard/components/SnippetOrPreview.d.ts +4 -0
  102. package/dist/types/view/HoverCard/styled.d.ts +2 -0
  103. package/dist/types/view/HoverCard/types.d.ts +5 -0
  104. package/package.json +2 -2
  105. package/report.api.md +294 -110
@@ -53,7 +53,7 @@ export function CardWithUrlContent(_ref) {
53
53
  var showHoverPreviewFlag = useFeatureFlag('showHoverPreview');
54
54
 
55
55
  if (showHoverPreview === undefined && showHoverPreviewFlag !== undefined) {
56
- showHoverPreview = showHoverPreviewFlag;
56
+ showHoverPreview = Boolean(showHoverPreviewFlag);
57
57
  } // Setup UI handlers.
58
58
 
59
59
 
@@ -63,7 +63,16 @@ export function CardWithUrlContent(_ref) {
63
63
  }, [state.details, url]);
64
64
  var handleClickWrapper = useCallback(function (event) {
65
65
  var isModifierKeyPressed = isSpecialEvent(event);
66
- analytics.ui.cardClickedEvent(id, isFlexibleUi ? 'flexible' : appearance, state.status, definitionId, extensionKey, isModifierKeyPressed, undefined, product, subproduct);
66
+ analytics.ui.cardClickedEvent({
67
+ id: id,
68
+ display: isFlexibleUi ? 'flexible' : appearance,
69
+ status: state.status,
70
+ definitionId: definitionId,
71
+ extensionKey: extensionKey,
72
+ isModifierKeyPressed: isModifierKeyPressed,
73
+ destinationProduct: product,
74
+ destinationSubproduct: subproduct
75
+ });
67
76
 
68
77
  if (onClick) {
69
78
  onClick(event);
@@ -87,7 +96,14 @@ export function CardWithUrlContent(_ref) {
87
96
 
88
97
  if (state.status !== 'pending') {
89
98
  measure.create(id, state.status);
90
- analytics.operational.instrument(id, state.status, definitionId, extensionKey, resourceType, state.error);
99
+ analytics.operational.instrument({
100
+ id: id,
101
+ status: state.status,
102
+ definitionId: definitionId,
103
+ extensionKey: extensionKey,
104
+ resourceType: resourceType,
105
+ error: state.error
106
+ });
91
107
  }
92
108
  }, [id, appearance, state.status, state.error, definitionId, extensionKey, resourceType, analytics.operational]); // NB: once the smart-card has rendered into an end state, we capture
93
109
  // this as a successful render. These can be one of:
@@ -96,7 +112,13 @@ export function CardWithUrlContent(_ref) {
96
112
 
97
113
  useEffect(function () {
98
114
  if (isFinalState(state.status)) {
99
- analytics.ui.renderSuccessEvent(appearance, state.status, id, definitionId, extensionKey);
115
+ analytics.ui.renderSuccessEvent({
116
+ display: appearance,
117
+ status: state.status,
118
+ id: id,
119
+ definitionId: definitionId,
120
+ extensionKey: extensionKey
121
+ });
100
122
  }
101
123
  }, [appearance, state.status, url, definitionId, extensionKey, analytics.ui, id]);
102
124
 
@@ -72,7 +72,12 @@ export function CardWithURLRenderer(props) {
72
72
  var errorInfo = {
73
73
  componentStack: componentStack
74
74
  };
75
- analytics.ui.renderFailedEvent(appearance, id, error, errorInfo);
75
+ analytics.ui.renderFailedEvent({
76
+ display: appearance,
77
+ id: id,
78
+ error: error,
79
+ errorInfo: errorInfo
80
+ });
76
81
  }
77
82
  }, [analytics.ui, appearance, id]);
78
83
 
@@ -0,0 +1,28 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React from 'react';
3
+ import Modal from '../../../common/Modal';
4
+ import { MAX_MODAL_SIZE, MIN_MODAL_SIZE } from '../../constants';
5
+
6
+ var withSizeExperiment = function withSizeExperiment(Component) {
7
+ return function (props) {
8
+ var _props$featureFlags = props.featureFlags,
9
+ featureFlags = _props$featureFlags === void 0 ? {} : _props$featureFlags,
10
+ _props$closeLabel = props.closeLabel,
11
+ closeLabel = _props$closeLabel === void 0 ? 'Close Preview' : _props$closeLabel;
12
+ var embedModalSize = featureFlags.embedModalSize; // Experiment
13
+
14
+ if (embedModalSize === 'large' || embedModalSize === 'small') {
15
+ var size = embedModalSize === 'large' ? MAX_MODAL_SIZE : MIN_MODAL_SIZE;
16
+ return /*#__PURE__*/React.createElement(Component, _extends({}, props, {
17
+ size: size
18
+ }));
19
+ } // Control
20
+
21
+
22
+ return /*#__PURE__*/React.createElement(Modal, _extends({}, props, {
23
+ closeLabel: closeLabel
24
+ }));
25
+ };
26
+ };
27
+
28
+ export default withSizeExperiment;
@@ -5,6 +5,7 @@ import LinkInfo from './components/link-info';
5
5
  import { MAX_MODAL_SIZE, MIN_MODAL_SIZE } from './constants';
6
6
  import EmbedContent from './components/embed-content';
7
7
  import withErrorBoundary from './components/error-boundary';
8
+ import withSizeExperiment from './components/size-experiment';
8
9
 
9
10
  var EmbedModal = function EmbedModal(_ref) {
10
11
  var downloadUrl = _ref.download,
@@ -18,9 +19,11 @@ var EmbedModal = function EmbedModal(_ref) {
18
19
  onViewActionClick = _ref.onViewActionClick,
19
20
  providerName = _ref.providerName,
20
21
  showModal = _ref.showModal,
22
+ _ref$size = _ref.size,
23
+ defaultSize = _ref$size === void 0 ? MIN_MODAL_SIZE : _ref$size,
21
24
  src = _ref.src,
22
25
  _ref$testId = _ref.testId,
23
- testId = _ref$testId === void 0 ? 'smart-links-preview-modal' : _ref$testId,
26
+ testId = _ref$testId === void 0 ? 'smart-embed-preview-modal' : _ref$testId,
24
27
  title = _ref.title,
25
28
  url = _ref.url;
26
29
 
@@ -29,7 +32,7 @@ var EmbedModal = function EmbedModal(_ref) {
29
32
  isOpen = _useState2[0],
30
33
  setIsOpen = _useState2[1];
31
34
 
32
- var _useState3 = useState(MIN_MODAL_SIZE),
35
+ var _useState3 = useState(defaultSize),
33
36
  _useState4 = _slicedToArray(_useState3, 2),
34
37
  size = _useState4[0],
35
38
  setSize = _useState4[1];
@@ -67,4 +70,4 @@ var EmbedModal = function EmbedModal(_ref) {
67
70
  }))));
68
71
  };
69
72
 
70
- export default withErrorBoundary(EmbedModal);
73
+ export default withSizeExperiment(withErrorBoundary(EmbedModal));
@@ -3,7 +3,7 @@ import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral
3
3
  var _templateObject;
4
4
 
5
5
  /** @jsx jsx */
6
- import React from 'react';
6
+ import React, { useEffect } from 'react';
7
7
  import { css, jsx } from '@emotion/core';
8
8
  import { ElementName, SmartLinkDirection, SmartLinkSize } from '../../../../../constants';
9
9
  import { getBaseStyles, getGapSize, highlightRemoveStyles, renderChildren } from '../utils';
@@ -28,11 +28,19 @@ var Block = function Block(_ref) {
28
28
  size = _ref$size === void 0 ? SmartLinkSize.Medium : _ref$size,
29
29
  _ref$testId = _ref.testId,
30
30
  testId = _ref$testId === void 0 ? 'smart-block' : _ref$testId,
31
- overrideCss = _ref.overrideCss;
31
+ overrideCss = _ref.overrideCss,
32
+ blockRef = _ref.blockRef,
33
+ onRender = _ref.onRender,
34
+ onTransitionEnd = _ref.onTransitionEnd;
35
+ useEffect(function () {
36
+ onRender && onRender();
37
+ }, [onRender]);
32
38
  return jsx("div", {
33
39
  css: [getBlockStyles(direction, size), overrideCss],
34
40
  "data-smart-block": true,
35
- "data-testid": testId
41
+ "data-testid": testId,
42
+ onTransitionEnd: onTransitionEnd,
43
+ ref: blockRef
36
44
  }, renderChildren(children, size));
37
45
  };
38
46
 
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
- var _excluded = ["status", "testId"];
3
+ var _excluded = ["status", "testId", "onError"];
4
4
  import React from 'react';
5
5
  import { SmartLinkStatus } from '../../../../../constants';
6
6
  import Block from '../block';
@@ -17,6 +17,7 @@ var PreviewBlock = function PreviewBlock(_ref) {
17
17
  status = _ref$status === void 0 ? SmartLinkStatus.Fallback : _ref$status,
18
18
  _ref$testId = _ref.testId,
19
19
  testId = _ref$testId === void 0 ? 'smart-block-preview' : _ref$testId,
20
+ onError = _ref.onError,
20
21
  blockProps = _objectWithoutProperties(_ref, _excluded);
21
22
 
22
23
  if (status !== SmartLinkStatus.Resolved) {
@@ -25,7 +26,9 @@ var PreviewBlock = function PreviewBlock(_ref) {
25
26
 
26
27
  return /*#__PURE__*/React.createElement(Block, _extends({}, blockProps, {
27
28
  testId: "".concat(testId, "-resolved-view")
28
- }), /*#__PURE__*/React.createElement(Preview, null));
29
+ }), /*#__PURE__*/React.createElement(Preview, {
30
+ onError: onError
31
+ }));
29
32
  };
30
33
 
31
34
  export default PreviewBlock;
@@ -5,6 +5,8 @@ var _importIconMapper;
5
5
  import React from 'react';
6
6
  import Loadable from 'react-loadable';
7
7
  import { B200, B400, N700, R400 } from '@atlaskit/theme/colors';
8
+ import DocumentIcon from '@atlaskit/icon-file-type/glyph/document/16';
9
+ import BlogIcon from '@atlaskit/icon-object/glyph/blog/16';
8
10
  import { IconType } from '../../../../../constants';
9
11
  import { token } from '@atlaskit/tokens'; // prettier-ignore
10
12
 
@@ -16,18 +18,10 @@ var importIconMapper = (_importIconMapper = {}, _defineProperty(_importIconMappe
16
18
  return import(
17
19
  /* webpackChunkName: "glyphAudio" */
18
20
  '@atlaskit/icon-file-type/glyph/audio/16');
19
- }), _defineProperty(_importIconMapper, IconType.Blog, function () {
20
- return import(
21
- /* webpackChunkName: "glyphBlog" */
22
- '@atlaskit/icon-object/glyph/blog/16');
23
21
  }), _defineProperty(_importIconMapper, IconType.Code, function () {
24
22
  return import(
25
23
  /* webpackChunkName: "glyphCode" */
26
24
  '@atlaskit/icon-file-type/glyph/source-code/16');
27
- }), _defineProperty(_importIconMapper, IconType.Document, function () {
28
- return import(
29
- /* webpackChunkName: "glyphDocument" */
30
- '@atlaskit/icon-file-type/glyph/document/16');
31
25
  }), _defineProperty(_importIconMapper, IconType.Executable, function () {
32
26
  return import(
33
27
  /* webpackChunkName: "glyphExecutable" */
@@ -281,6 +275,22 @@ var AtlaskitIcon = function AtlaskitIcon(_ref3) {
281
275
  var icon = _ref3.icon,
282
276
  label = _ref3.label,
283
277
  testId = _ref3.testId;
278
+
279
+ // Check for synchonously loaded icons first for SSR purposes
280
+ switch (icon) {
281
+ case IconType.Document:
282
+ return /*#__PURE__*/React.createElement(DocumentIcon, {
283
+ label: label || 'document',
284
+ testId: testId
285
+ });
286
+
287
+ case IconType.Blog:
288
+ return /*#__PURE__*/React.createElement(BlogIcon, {
289
+ label: label || 'blog',
290
+ testId: testId
291
+ });
292
+ }
293
+
284
294
  var importFn = getIconImportFn(icon);
285
295
 
286
296
  if (!importFn) {
@@ -7,7 +7,8 @@ import LoadingSkeleton from '../loading-skeleton';
7
7
  var ImageIcon = function ImageIcon(_ref) {
8
8
  var defaultIcon = _ref.defaultIcon,
9
9
  testId = _ref.testId,
10
- url = _ref.url;
10
+ url = _ref.url,
11
+ onError = _ref.onError;
11
12
  return jsx(ImageLoader, {
12
13
  src: url,
13
14
  loading: jsx(LoadingSkeleton, {
@@ -17,7 +18,8 @@ var ImageIcon = function ImageIcon(_ref) {
17
18
  src: url,
18
19
  "data-testid": "".concat(testId, "-image")
19
20
  }),
20
- errored: defaultIcon
21
+ errored: defaultIcon,
22
+ onError: onError
21
23
  });
22
24
  };
23
25
 
@@ -11,8 +11,7 @@ var LoadingSkeleton = function LoadingSkeleton(_ref) {
11
11
  var testId = _ref.testId,
12
12
  width = _ref.width,
13
13
  height = _ref.height;
14
- var animationWidth = width ? "".concat(width, "rem") : '20px';
15
- var animationNameStyles = keyframes(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n 0% { background-position: -", " 0; }\n 100% { background-position: ", " 0; }\n "])), animationWidth, animationWidth);
14
+ var animationNameStyles = keyframes(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n 0% { background-position: 50% 0; }\n 100% { background-position: -50% 0; }\n "])));
16
15
  var styles = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n width: ", "rem;\n height: ", "rem;\n border-radius: 2px;\n user-select: none;\n background: ", ";\n // TODO: https://product-fabric.atlassian.net/browse/DSP-4236\n background-image: linear-gradient(\n to right,\n ", " 0%,\n ", " 20%,\n ", " 40%,\n ", "100%\n );\n background-repeat: no-repeat;\n background-size: 280% 100%;\n display: inline-block;\n\n animation-duration: 1s;\n animation-fill-mode: forwards;\n animation-iteration-count: infinite;\n animation-name: ", ";\n animation-timing-function: linear;\n "])), width, height, token('color.skeleton.subtle', '#f6f7f8'), token('color.skeleton.subtle', '#f6f7f8'), token('color.skeleton', '#edeef1'), token('color.skeleton.subtle', '#f6f7f8'), token('color.skeleton.subtle', '#f6f7f8'), animationNameStyles);
17
16
  return jsx("span", {
18
17
  css: styles,
@@ -31,7 +31,8 @@ var Media = function Media(_ref) {
31
31
  _ref$testId = _ref.testId,
32
32
  testId = _ref$testId === void 0 ? 'smart-element-media' : _ref$testId,
33
33
  type = _ref.type,
34
- url = _ref.url;
34
+ url = _ref.url,
35
+ onError = _ref.onError;
35
36
 
36
37
  if (!type || !url) {
37
38
  return null;
@@ -44,7 +45,9 @@ var Media = function Media(_ref) {
44
45
  "data-testid": testId
45
46
  }, jsx(ImageIcon, {
46
47
  testId: "".concat(testId, "-image"),
47
- url: url
48
+ url: url,
49
+ onError: onError,
50
+ defaultIcon: null
48
51
  }));
49
52
  };
50
53
 
@@ -48,7 +48,11 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
48
48
  //Check its previously open to avoid firing events when moving between the child and hover card components
49
49
  if (isOpen === true && cardOpenTime.current) {
50
50
  var hoverTime = Date.now() - cardOpenTime.current;
51
- analytics.ui.hoverCardDismissedEvent('card', hoverTime, 'mouse_hover');
51
+ analytics.ui.hoverCardDismissedEvent({
52
+ previewDisplay: 'card',
53
+ hoverTime: hoverTime,
54
+ previewInvokeMethod: 'mouse_hover'
55
+ });
52
56
  }
53
57
 
54
58
  setIsOpen(false);
@@ -73,7 +77,10 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
73
77
  //Check if its previously closed to avoid firing events when moving between the child and hover card components
74
78
  if (isOpen === false) {
75
79
  cardOpenTime.current = Date.now();
76
- analytics.ui.hoverCardViewedEvent(hoverDisplay, invokeMethod);
80
+ analytics.ui.hoverCardViewedEvent({
81
+ previewDisplay: hoverDisplay,
82
+ previewInvokeMethod: invokeMethod
83
+ });
77
84
  } //If these are undefined then popupOffset is undefined and we fallback to default bottom-start placement
78
85
 
79
86
 
@@ -1,17 +1,17 @@
1
1
  import ShortcutIcon from '@atlaskit/icon/glyph/shortcut';
2
2
  import { extractType } from '@atlaskit/linking-common/extractors';
3
- import React, { useCallback, useEffect, useMemo } from 'react';
3
+ import React, { useCallback, useEffect, useMemo, useRef } from 'react';
4
4
  import { ActionName, SmartLinkPosition, SmartLinkSize } from '../../../constants';
5
- import extractPreview from '../../../extractors/flexible/extract-preview';
6
5
  import { extractMetadata } from '../../../extractors/hover/extractMetadata';
7
6
  import { useSmartCardActions } from '../../../state/actions';
8
7
  import { getExtensionKey } from '../../../state/helpers';
9
8
  import { isSpecialEvent } from '../../../utils';
10
9
  import FlexibleCard from '../../FlexibleCard';
11
- import { FooterBlock, MetadataBlock, PreviewBlock, SnippetBlock, TitleBlock } from '../../FlexibleCard/components/blocks';
12
- import { flexibleUiOptions, footerBlockCss, metadataBlockCss, titleBlockCss } from '../styled';
10
+ import { FooterBlock, MetadataBlock, SnippetBlock, TitleBlock } from '../../FlexibleCard/components/blocks';
11
+ import { flexibleUiOptions, footerBlockCss, metadataBlockCss, titleBlockCss, hiddenSnippetStyles } from '../styled';
13
12
  import { getSimulatedMetadata, SMART_CARD_ANALYTICS_DISPLAY } from '../utils';
14
13
  import HoverCardLoadingView from './HoverCardLoadingView';
14
+ import SnippetOrPreview from './SnippetOrPreview';
15
15
  export var getOpenAction = function getOpenAction(url, analytics, onActionClick) {
16
16
  return {
17
17
  name: ActionName.CustomAction,
@@ -26,7 +26,9 @@ export var getOpenAction = function getOpenAction(url, analytics, onActionClick)
26
26
  }
27
27
 
28
28
  window.open(url, '_blank');
29
- analytics.ui.hoverCardOpenLinkClickedEvent('card');
29
+ analytics.ui.hoverCardOpenLinkClickedEvent({
30
+ previewDisplay: 'card'
31
+ });
30
32
  },
31
33
  testId: 'hover-card-open-button'
32
34
  };
@@ -68,15 +70,24 @@ var HoverCardContent = function HoverCardContent(_ref) {
68
70
  useEffect(function () {
69
71
  // Since hover preview only render on resolved status,
70
72
  // there is no need to check for statuses.
71
- analytics.ui.renderSuccessEvent(SMART_CARD_ANALYTICS_DISPLAY, cardState.status);
73
+ analytics.ui.renderSuccessEvent({
74
+ display: SMART_CARD_ANALYTICS_DISPLAY,
75
+ status: cardState.status
76
+ });
72
77
  }, [analytics.ui, cardState.status]);
73
78
  var extensionKey = useMemo(function () {
74
79
  return getExtensionKey(cardState.details);
75
80
  }, [cardState.details]);
76
81
  var onClick = useCallback(function (event) {
77
82
  var isModifierKeyPressed = isSpecialEvent(event);
78
- analytics.ui.cardClickedEvent(undefined, SMART_CARD_ANALYTICS_DISPLAY, cardState.status, undefined, undefined, isModifierKeyPressed, undefined, undefined, undefined, 'titleGoToLink');
79
- }, [cardState.status, analytics.ui]);
83
+ analytics.ui.cardClickedEvent({
84
+ id: id,
85
+ display: SMART_CARD_ANALYTICS_DISPLAY,
86
+ status: cardState.status,
87
+ isModifierKeyPressed: isModifierKeyPressed,
88
+ actionSubjectId: 'titleGoToLink'
89
+ });
90
+ }, [cardState.status, analytics.ui, id]);
80
91
  var titleActions = useMemo(function () {
81
92
  return [getOpenAction(url, analytics, onActionClick)];
82
93
  }, [url, analytics, onActionClick]);
@@ -92,7 +103,17 @@ var HoverCardContent = function HoverCardContent(_ref) {
92
103
  subtitle = _extractMetadata.subtitle;
93
104
 
94
105
  var titleMaxLines = subtitle && subtitle.length > 0 ? 1 : 2;
95
- var body = data && extractPreview(data) ? /*#__PURE__*/React.createElement(PreviewBlock, null) : /*#__PURE__*/React.createElement(SnippetBlock, null);
106
+ var snippetHeight = React.useRef(0);
107
+ var snippetBlockRef = useRef(null);
108
+ var onSnippetRender = useCallback(function () {
109
+ var _snippetBlockRef$curr, _snippetBlockRef$curr2;
110
+
111
+ snippetHeight.current = (_snippetBlockRef$curr = (_snippetBlockRef$curr2 = snippetBlockRef.current) === null || _snippetBlockRef$curr2 === void 0 ? void 0 : _snippetBlockRef$curr2.getBoundingClientRect().height) !== null && _snippetBlockRef$curr !== void 0 ? _snippetBlockRef$curr : 0;
112
+ }, []);
113
+ var body = SnippetOrPreview({
114
+ data: data,
115
+ snippetHeight: snippetHeight.current
116
+ });
96
117
  var titleBlockProps = {
97
118
  actions: titleActions,
98
119
  maxLines: titleMaxLines,
@@ -125,7 +146,12 @@ var HoverCardContent = function HoverCardContent(_ref) {
125
146
  size: SmartLinkSize.Large,
126
147
  overrideCss: metadataBlockCss,
127
148
  maxLines: 1
128
- }), body, /*#__PURE__*/React.createElement(FooterBlock, {
149
+ }), body, /*#__PURE__*/React.createElement(SnippetBlock, {
150
+ testId: 'hidden-snippet',
151
+ onRender: onSnippetRender,
152
+ blockRef: snippetBlockRef,
153
+ overrideCss: hiddenSnippetStyles
154
+ }), /*#__PURE__*/React.createElement(FooterBlock, {
129
155
  actions: footerActions,
130
156
  size: SmartLinkSize.Large,
131
157
  overrideCss: footerBlockCss
@@ -0,0 +1,53 @@
1
+ import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+
4
+ var _templateObject;
5
+
6
+ import React, { useCallback, useState, useRef } from 'react';
7
+ import { css } from '@emotion/core';
8
+ import extractPreview from '../../../extractors/flexible/extract-preview';
9
+ import { PreviewBlock, SnippetBlock } from '../../FlexibleCard/components/blocks';
10
+ import { getTransitionStyles } from '../styled';
11
+
12
+ var SnippetOrPreview = function SnippetOrPreview(_ref) {
13
+ var data = _ref.data,
14
+ snippetHeight = _ref.snippetHeight;
15
+ var transitionStarted = useRef(false);
16
+ var previewBlockRef = useRef(null);
17
+
18
+ var _useState = useState(false),
19
+ _useState2 = _slicedToArray(_useState, 2),
20
+ showSnippet = _useState2[0],
21
+ setShowSnippet = _useState2[1];
22
+
23
+ var _useState3 = useState(),
24
+ _useState4 = _slicedToArray(_useState3, 2),
25
+ previewCss = _useState4[0],
26
+ setPreviewCss = _useState4[1]; // Set Preview to a fixed height to enable transitions
27
+
28
+
29
+ var onPreviewRender = useCallback(function () {
30
+ var _previewBlockRef$curr;
31
+
32
+ previewBlockRef.current && setPreviewCss(css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n height: ", "px;\n "])), (_previewBlockRef$curr = previewBlockRef.current) === null || _previewBlockRef$curr === void 0 ? void 0 : _previewBlockRef$curr.getBoundingClientRect().height));
33
+ }, []); // On error set Preview to Snippet height with transition
34
+
35
+ var onPreviewError = useCallback(function () {
36
+ if (transitionStarted.current === false) {
37
+ setPreviewCss(getTransitionStyles(snippetHeight));
38
+ transitionStarted.current = true;
39
+ }
40
+ }, [snippetHeight]);
41
+ var onPreviewTransitionEnd = useCallback(function () {
42
+ setShowSnippet(true);
43
+ }, []);
44
+ return !showSnippet && data && extractPreview(data) ? /*#__PURE__*/React.createElement(PreviewBlock, {
45
+ onError: onPreviewError,
46
+ overrideCss: previewCss,
47
+ onTransitionEnd: onPreviewTransitionEnd,
48
+ blockRef: previewBlockRef,
49
+ onRender: onPreviewRender
50
+ }) : /*#__PURE__*/React.createElement(SnippetBlock, null);
51
+ };
52
+
53
+ export default SnippetOrPreview;
@@ -20,7 +20,12 @@ var HoverCardWithErrorBoundary = function HoverCardWithErrorBoundary(props) {
20
20
  }, [createAnalyticsEvent]);
21
21
  var analytics = useSmartLinkAnalytics(url, analyticsHandler, id);
22
22
  var onError = useCallback(function (error, info) {
23
- analytics.ui.renderFailedEvent(SMART_CARD_ANALYTICS_DISPLAY, id, error, info);
23
+ analytics.ui.renderFailedEvent({
24
+ display: SMART_CARD_ANALYTICS_DISPLAY,
25
+ id: id,
26
+ error: error,
27
+ errorInfo: info
28
+ });
24
29
  }, [analytics.ui, id]);
25
30
  return jsx(ErrorBoundary, {
26
31
  fallback: children,
@@ -1,6 +1,6 @@
1
1
  import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
2
 
3
- var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
3
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9;
4
4
 
5
5
  import { css } from '@emotion/core';
6
6
  import { loadingPlaceholderClassName } from '../../index';
@@ -23,4 +23,8 @@ export var titleBlockCss = css(_templateObject3 || (_templateObject3 = _taggedTe
23
23
  export var metadataBlockCss = css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n gap: 0px;\n\n /* primary element group */\n [data-smart-element-group]:nth-of-type(1) {\n flex-grow: 7;\n\n // a separator between text-based element\n ", "\n\n /* horizontal spacing between elements in group */\n > span {\n margin-right: ", ";\n }\n }\n /* secondary element group */\n [data-smart-element-group]:nth-of-type(2) {\n flex-grow: 3;\n /* horizontal spacing between elements in group */\n > span {\n margin-left: ", ";\n }\n }\n"])), separatorCss, elementGap, elementGap);
24
24
  export var footerBlockCss = css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n padding-top: 0.25rem;\n"])));
25
25
  export var loadingViewContainer = css(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n"])));
26
- export var skeletonContainer = css(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n gap: 0.625rem;\n align-items: center;\n"])));
26
+ export var skeletonContainer = css(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n gap: 0.625rem;\n align-items: center;\n"])));
27
+ export var hiddenSnippetStyles = css(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["\n visibility: hidden;\n position: absolute;\n"])));
28
+ export var getTransitionStyles = function getTransitionStyles(snippetHeight) {
29
+ return css(_templateObject9 || (_templateObject9 = _taggedTemplateLiteral(["\n transition: height 300ms ease-in-out;\n height: ", "px;\n"])), snippetHeight);
30
+ };
@@ -1,3 +1,4 @@
1
+ import { LinkingPlatformFeatureFlags } from '@atlaskit/linking-common';
1
2
  import { InvokeHandler } from '../../model/invoke-handler';
2
3
  import { AnalyticsHandler } from '../../utils/types';
3
4
  import { CardInnerAppearance } from '../../view/Card/types';
@@ -5,6 +6,7 @@ export interface ExtractBlockOpts {
5
6
  handleInvoke: InvokeHandler;
6
7
  handleAnalytics: AnalyticsHandler;
7
8
  extensionKey?: string;
9
+ featureFlags?: Partial<LinkingPlatformFeatureFlags>;
8
10
  source?: CardInnerAppearance;
9
11
  testId?: string;
10
12
  }
@@ -1,6 +1,7 @@
1
1
  import { JsonLd } from 'json-ld-types';
2
+ import { LinkingPlatformFeatureFlags } from '@atlaskit/linking-common';
2
3
  import { InvokeHandler } from '../../../model/invoke-handler';
3
4
  import { CardInnerAppearance } from '../../../view/Card/types';
4
5
  import { AnalyticsHandler } from '../../../utils/types';
5
6
  import { BlockCardResolvedViewProps } from '../../../view/BlockCard';
6
- export declare const extractPreviewAction: (extensionKey: string | undefined, viewProps: BlockCardResolvedViewProps, jsonLd: JsonLd.Data.BaseData, handleInvoke: InvokeHandler, handleAnalytics: AnalyticsHandler, testId?: string | undefined, platform?: JsonLd.Primitives.Platforms | undefined, source?: CardInnerAppearance | undefined) => import("../../../view/BlockCard/components/Action").ActionProps | undefined;
7
+ export declare const extractPreviewAction: (extensionKey: string | undefined, viewProps: BlockCardResolvedViewProps, jsonLd: JsonLd.Data.BaseData, handleInvoke: InvokeHandler, handleAnalytics: AnalyticsHandler, testId?: string | undefined, platform?: JsonLd.Primitives.Platforms | undefined, source?: CardInnerAppearance | undefined, featureFlags?: Partial<LinkingPlatformFeatureFlags> | undefined) => import("../../../view/BlockCard/components/Action").ActionProps | undefined;
@@ -0,0 +1,9 @@
1
+ import { DestinationSubproduct, DestinationProduct } from '../../utils/analytics/types';
2
+ export interface CommonEventProps {
3
+ definitionId?: string;
4
+ extensionKey?: string;
5
+ resourceType?: string;
6
+ destinationSubproduct?: DestinationSubproduct | string;
7
+ destinationProduct?: DestinationProduct | string;
8
+ location?: string;
9
+ }