@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
@@ -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
+ const withSizeExperiment = Component => props => {
7
+ const {
8
+ featureFlags = {},
9
+ closeLabel = 'Close Preview'
10
+ } = props;
11
+ const {
12
+ embedModalSize
13
+ } = featureFlags; // Experiment
14
+
15
+ if (embedModalSize === 'large' || embedModalSize === 'small') {
16
+ const size = embedModalSize === 'large' ? MAX_MODAL_SIZE : MIN_MODAL_SIZE;
17
+ return /*#__PURE__*/React.createElement(Component, _extends({}, props, {
18
+ size: size
19
+ }));
20
+ } // Control
21
+
22
+
23
+ return /*#__PURE__*/React.createElement(Modal, _extends({}, props, {
24
+ closeLabel: closeLabel
25
+ }));
26
+ };
27
+
28
+ export default withSizeExperiment;
@@ -4,6 +4,7 @@ import LinkInfo from './components/link-info';
4
4
  import { MAX_MODAL_SIZE, MIN_MODAL_SIZE } from './constants';
5
5
  import EmbedContent from './components/embed-content';
6
6
  import withErrorBoundary from './components/error-boundary';
7
+ import withSizeExperiment from './components/size-experiment';
7
8
 
8
9
  const EmbedModal = ({
9
10
  download: downloadUrl,
@@ -16,13 +17,14 @@ const EmbedModal = ({
16
17
  onViewActionClick,
17
18
  providerName,
18
19
  showModal,
20
+ size: defaultSize = MIN_MODAL_SIZE,
19
21
  src,
20
- testId = 'smart-links-preview-modal',
22
+ testId = 'smart-embed-preview-modal',
21
23
  title,
22
24
  url
23
25
  }) => {
24
26
  const [isOpen, setIsOpen] = useState(showModal);
25
- const [size, setSize] = useState(MIN_MODAL_SIZE);
27
+ const [size, setSize] = useState(defaultSize);
26
28
  const handleOnClose = useCallback(() => setIsOpen(false), []);
27
29
  const handleOnSizeClick = useCallback(() => {
28
30
  const newSize = size === MIN_MODAL_SIZE ? MAX_MODAL_SIZE : MIN_MODAL_SIZE;
@@ -54,4 +56,4 @@ const EmbedModal = ({
54
56
  }))));
55
57
  };
56
58
 
57
- export default withErrorBoundary(EmbedModal);
59
+ export default withSizeExperiment(withErrorBoundary(EmbedModal));
@@ -1,5 +1,5 @@
1
1
  /** @jsx jsx */
2
- import React from 'react';
2
+ import React, { useEffect } from 'react';
3
3
  import { css, jsx } from '@emotion/core';
4
4
  import { ElementName, SmartLinkDirection, SmartLinkSize } from '../../../../../constants';
5
5
  import { getBaseStyles, getGapSize, highlightRemoveStyles, renderChildren } from '../utils';
@@ -37,11 +37,21 @@ const Block = ({
37
37
  direction = SmartLinkDirection.Horizontal,
38
38
  size = SmartLinkSize.Medium,
39
39
  testId = 'smart-block',
40
- overrideCss
41
- }) => jsx("div", {
42
- css: [getBlockStyles(direction, size), overrideCss],
43
- "data-smart-block": true,
44
- "data-testid": testId
45
- }, renderChildren(children, size));
40
+ overrideCss,
41
+ blockRef,
42
+ onRender,
43
+ onTransitionEnd
44
+ }) => {
45
+ useEffect(() => {
46
+ onRender && onRender();
47
+ }, [onRender]);
48
+ return jsx("div", {
49
+ css: [getBlockStyles(direction, size), overrideCss],
50
+ "data-smart-block": true,
51
+ "data-testid": testId,
52
+ onTransitionEnd: onTransitionEnd,
53
+ ref: blockRef
54
+ }, renderChildren(children, size));
55
+ };
46
56
 
47
57
  export default Block;
@@ -13,6 +13,7 @@ import { Preview } from '../../elements';
13
13
  const PreviewBlock = ({
14
14
  status = SmartLinkStatus.Fallback,
15
15
  testId = 'smart-block-preview',
16
+ onError,
16
17
  ...blockProps
17
18
  }) => {
18
19
  if (status !== SmartLinkStatus.Resolved) {
@@ -21,7 +22,9 @@ const PreviewBlock = ({
21
22
 
22
23
  return /*#__PURE__*/React.createElement(Block, _extends({}, blockProps, {
23
24
  testId: `${testId}-resolved-view`
24
- }), /*#__PURE__*/React.createElement(Preview, null));
25
+ }), /*#__PURE__*/React.createElement(Preview, {
26
+ onError: onError
27
+ }));
25
28
  };
26
29
 
27
30
  export default PreviewBlock;
@@ -1,6 +1,8 @@
1
1
  import React from 'react';
2
2
  import Loadable from 'react-loadable';
3
3
  import { B200, B400, N700, R400 } from '@atlaskit/theme/colors';
4
+ import DocumentIcon from '@atlaskit/icon-file-type/glyph/document/16';
5
+ import BlogIcon from '@atlaskit/icon-object/glyph/blog/16';
4
6
  import { IconType } from '../../../../../constants';
5
7
  import { token } from '@atlaskit/tokens'; // prettier-ignore
6
8
 
@@ -11,15 +13,9 @@ const importIconMapper = {
11
13
  [IconType.Audio]: () => import(
12
14
  /* webpackChunkName: "glyphAudio" */
13
15
  '@atlaskit/icon-file-type/glyph/audio/16'),
14
- [IconType.Blog]: () => import(
15
- /* webpackChunkName: "glyphBlog" */
16
- '@atlaskit/icon-object/glyph/blog/16'),
17
16
  [IconType.Code]: () => import(
18
17
  /* webpackChunkName: "glyphCode" */
19
18
  '@atlaskit/icon-file-type/glyph/source-code/16'),
20
- [IconType.Document]: () => import(
21
- /* webpackChunkName: "glyphDocument" */
22
- '@atlaskit/icon-file-type/glyph/document/16'),
23
19
  [IconType.Executable]: () => import(
24
20
  /* webpackChunkName: "glyphExecutable" */
25
21
  '@atlaskit/icon-file-type/glyph/executable/16'),
@@ -214,6 +210,21 @@ const AtlaskitIcon = ({
214
210
  label,
215
211
  testId
216
212
  }) => {
213
+ // Check for synchonously loaded icons first for SSR purposes
214
+ switch (icon) {
215
+ case IconType.Document:
216
+ return /*#__PURE__*/React.createElement(DocumentIcon, {
217
+ label: label || 'document',
218
+ testId: testId
219
+ });
220
+
221
+ case IconType.Blog:
222
+ return /*#__PURE__*/React.createElement(BlogIcon, {
223
+ label: label || 'blog',
224
+ testId: testId
225
+ });
226
+ }
227
+
217
228
  const importFn = getIconImportFn(icon);
218
229
 
219
230
  if (!importFn) {
@@ -7,7 +7,8 @@ import LoadingSkeleton from '../loading-skeleton';
7
7
  const ImageIcon = ({
8
8
  defaultIcon,
9
9
  testId,
10
- url
10
+ url,
11
+ onError
11
12
  }) => jsx(ImageLoader, {
12
13
  src: url,
13
14
  loading: jsx(LoadingSkeleton, {
@@ -17,7 +18,8 @@ const ImageIcon = ({
17
18
  src: url,
18
19
  "data-testid": `${testId}-image`
19
20
  }),
20
- errored: defaultIcon
21
+ errored: defaultIcon,
22
+ onError: onError
21
23
  });
22
24
 
23
25
  export default ImageIcon;
@@ -8,10 +8,9 @@ const LoadingSkeleton = ({
8
8
  width,
9
9
  height
10
10
  }) => {
11
- const animationWidth = width ? `${width}rem` : '20px';
12
11
  const animationNameStyles = keyframes`
13
- 0% { background-position: -${animationWidth} 0; }
14
- 100% { background-position: ${animationWidth} 0; }
12
+ 0% { background-position: 50% 0; }
13
+ 100% { background-position: -50% 0; }
15
14
  `;
16
15
  const styles = css`
17
16
  width: ${width}rem;
@@ -59,7 +59,8 @@ const Media = ({
59
59
  overrideCss,
60
60
  testId = 'smart-element-media',
61
61
  type,
62
- url
62
+ url,
63
+ onError
63
64
  }) => {
64
65
  if (!type || !url) {
65
66
  return null;
@@ -72,7 +73,9 @@ const Media = ({
72
73
  "data-testid": testId
73
74
  }, jsx(ImageIcon, {
74
75
  testId: `${testId}-image`,
75
- url: url
76
+ url: url,
77
+ onError: onError,
78
+ defaultIcon: null
76
79
  }));
77
80
  };
78
81
 
@@ -43,7 +43,11 @@ export const HoverCardComponent = ({
43
43
  //Check its previously open to avoid firing events when moving between the child and hover card components
44
44
  if (isOpen === true && cardOpenTime.current) {
45
45
  const hoverTime = Date.now() - cardOpenTime.current;
46
- analytics.ui.hoverCardDismissedEvent('card', hoverTime, 'mouse_hover');
46
+ analytics.ui.hoverCardDismissedEvent({
47
+ previewDisplay: 'card',
48
+ hoverTime,
49
+ previewInvokeMethod: 'mouse_hover'
50
+ });
47
51
  }
48
52
 
49
53
  setIsOpen(false);
@@ -66,7 +70,10 @@ export const HoverCardComponent = ({
66
70
  //Check if its previously closed to avoid firing events when moving between the child and hover card components
67
71
  if (isOpen === false) {
68
72
  cardOpenTime.current = Date.now();
69
- analytics.ui.hoverCardViewedEvent(hoverDisplay, invokeMethod);
73
+ analytics.ui.hoverCardViewedEvent({
74
+ previewDisplay: hoverDisplay,
75
+ previewInvokeMethod: invokeMethod
76
+ });
70
77
  } //If these are undefined then popupOffset is undefined and we fallback to default bottom-start placement
71
78
 
72
79
 
@@ -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 const getOpenAction = (url, analytics, onActionClick) => ({
16
16
  name: ActionName.CustomAction,
17
17
  icon: /*#__PURE__*/React.createElement(ShortcutIcon, {
@@ -25,7 +25,9 @@ export const getOpenAction = (url, analytics, onActionClick) => ({
25
25
  }
26
26
 
27
27
  window.open(url, '_blank');
28
- analytics.ui.hoverCardOpenLinkClickedEvent('card');
28
+ analytics.ui.hoverCardOpenLinkClickedEvent({
29
+ previewDisplay: 'card'
30
+ });
29
31
  },
30
32
  testId: 'hover-card-open-button'
31
33
  });
@@ -61,13 +63,22 @@ const HoverCardContent = ({
61
63
  useEffect(() => {
62
64
  // Since hover preview only render on resolved status,
63
65
  // there is no need to check for statuses.
64
- analytics.ui.renderSuccessEvent(SMART_CARD_ANALYTICS_DISPLAY, cardState.status);
66
+ analytics.ui.renderSuccessEvent({
67
+ display: SMART_CARD_ANALYTICS_DISPLAY,
68
+ status: cardState.status
69
+ });
65
70
  }, [analytics.ui, cardState.status]);
66
71
  const extensionKey = useMemo(() => getExtensionKey(cardState.details), [cardState.details]);
67
72
  const onClick = useCallback(event => {
68
73
  const isModifierKeyPressed = isSpecialEvent(event);
69
- analytics.ui.cardClickedEvent(undefined, SMART_CARD_ANALYTICS_DISPLAY, cardState.status, undefined, undefined, isModifierKeyPressed, undefined, undefined, undefined, 'titleGoToLink');
70
- }, [cardState.status, analytics.ui]);
74
+ analytics.ui.cardClickedEvent({
75
+ id,
76
+ display: SMART_CARD_ANALYTICS_DISPLAY,
77
+ status: cardState.status,
78
+ isModifierKeyPressed,
79
+ actionSubjectId: 'titleGoToLink'
80
+ });
81
+ }, [cardState.status, analytics.ui, id]);
71
82
  const titleActions = useMemo(() => [getOpenAction(url, analytics, onActionClick)], [url, analytics, onActionClick]);
72
83
  const footerActions = useMemo(() => toFooterActions(cardActions, onActionClick), [cardActions, onActionClick]);
73
84
  const data = (_cardState$details = cardState.details) === null || _cardState$details === void 0 ? void 0 : _cardState$details.data;
@@ -79,7 +90,17 @@ const HoverCardContent = ({
79
90
  subtitle
80
91
  } = extractMetadata(getSimulatedMetadata(extensionKey, types));
81
92
  const titleMaxLines = subtitle && subtitle.length > 0 ? 1 : 2;
82
- const body = data && extractPreview(data) ? /*#__PURE__*/React.createElement(PreviewBlock, null) : /*#__PURE__*/React.createElement(SnippetBlock, null);
93
+ const snippetHeight = React.useRef(0);
94
+ const snippetBlockRef = useRef(null);
95
+ const onSnippetRender = useCallback(() => {
96
+ var _snippetBlockRef$curr, _snippetBlockRef$curr2;
97
+
98
+ 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;
99
+ }, []);
100
+ const body = SnippetOrPreview({
101
+ data: data,
102
+ snippetHeight: snippetHeight.current
103
+ });
83
104
  const titleBlockProps = {
84
105
  actions: titleActions,
85
106
  maxLines: titleMaxLines,
@@ -112,7 +133,12 @@ const HoverCardContent = ({
112
133
  size: SmartLinkSize.Large,
113
134
  overrideCss: metadataBlockCss,
114
135
  maxLines: 1
115
- }), body, /*#__PURE__*/React.createElement(FooterBlock, {
136
+ }), body, /*#__PURE__*/React.createElement(SnippetBlock, {
137
+ testId: 'hidden-snippet',
138
+ onRender: onSnippetRender,
139
+ blockRef: snippetBlockRef,
140
+ overrideCss: hiddenSnippetStyles
141
+ }), /*#__PURE__*/React.createElement(FooterBlock, {
116
142
  actions: footerActions,
117
143
  size: SmartLinkSize.Large,
118
144
  overrideCss: footerBlockCss
@@ -0,0 +1,42 @@
1
+ import React, { useCallback, useState, useRef } from 'react';
2
+ import { css } from '@emotion/core';
3
+ import extractPreview from '../../../extractors/flexible/extract-preview';
4
+ import { PreviewBlock, SnippetBlock } from '../../FlexibleCard/components/blocks';
5
+ import { getTransitionStyles } from '../styled';
6
+
7
+ const SnippetOrPreview = ({
8
+ data,
9
+ snippetHeight
10
+ }) => {
11
+ const transitionStarted = useRef(false);
12
+ const previewBlockRef = useRef(null);
13
+ const [showSnippet, setShowSnippet] = useState(false);
14
+ const [previewCss, setPreviewCss] = useState(); // Set Preview to a fixed height to enable transitions
15
+
16
+ const onPreviewRender = useCallback(() => {
17
+ var _previewBlockRef$curr;
18
+
19
+ previewBlockRef.current && setPreviewCss(css`
20
+ height: ${(_previewBlockRef$curr = previewBlockRef.current) === null || _previewBlockRef$curr === void 0 ? void 0 : _previewBlockRef$curr.getBoundingClientRect().height}px;
21
+ `);
22
+ }, []); // On error set Preview to Snippet height with transition
23
+
24
+ const onPreviewError = useCallback(() => {
25
+ if (transitionStarted.current === false) {
26
+ setPreviewCss(getTransitionStyles(snippetHeight));
27
+ transitionStarted.current = true;
28
+ }
29
+ }, [snippetHeight]);
30
+ const onPreviewTransitionEnd = useCallback(() => {
31
+ setShowSnippet(true);
32
+ }, []);
33
+ return !showSnippet && data && extractPreview(data) ? /*#__PURE__*/React.createElement(PreviewBlock, {
34
+ onError: onPreviewError,
35
+ overrideCss: previewCss,
36
+ onTransitionEnd: onPreviewTransitionEnd,
37
+ blockRef: previewBlockRef,
38
+ onRender: onPreviewRender
39
+ }) : /*#__PURE__*/React.createElement(SnippetBlock, null);
40
+ };
41
+
42
+ export default SnippetOrPreview;
@@ -22,7 +22,12 @@ const HoverCardWithErrorBoundary = props => {
22
22
  }, [createAnalyticsEvent]);
23
23
  const analytics = useSmartLinkAnalytics(url, analyticsHandler, id);
24
24
  const onError = useCallback((error, info) => {
25
- analytics.ui.renderFailedEvent(SMART_CARD_ANALYTICS_DISPLAY, id, error, info);
25
+ analytics.ui.renderFailedEvent({
26
+ display: SMART_CARD_ANALYTICS_DISPLAY,
27
+ id,
28
+ error,
29
+ errorInfo: info
30
+ });
26
31
  }, [analytics.ui, id]);
27
32
  return jsx(ErrorBoundary, {
28
33
  fallback: children,
@@ -83,4 +83,12 @@ export const skeletonContainer = css`
83
83
  flex-direction: column;
84
84
  gap: 0.625rem;
85
85
  align-items: center;
86
+ `;
87
+ export const hiddenSnippetStyles = css`
88
+ visibility: hidden;
89
+ position: absolute;
90
+ `;
91
+ export const getTransitionStyles = snippetHeight => css`
92
+ transition: height 300ms ease-in-out;
93
+ height: ${snippetHeight}px;
86
94
  `;
@@ -37,13 +37,14 @@ var extractBlockDetails = function extractBlockDetails(jsonLd) {
37
37
 
38
38
  export var extractBlockActions = function extractBlockActions(props, jsonLd, opts, platform) {
39
39
  if (opts) {
40
- var handleInvoke = opts.handleInvoke,
40
+ var featureFlags = opts.featureFlags,
41
+ handleInvoke = opts.handleInvoke,
41
42
  handleAnalytics = opts.handleAnalytics,
42
43
  extensionKey = opts.extensionKey,
43
44
  source = opts.source,
44
45
  testId = opts.testId;
45
46
  var actions = extractActions(jsonLd, handleInvoke);
46
- var previewAction = extractPreviewAction(extensionKey, props, jsonLd, handleInvoke, handleAnalytics, testId, platform, source); // The previewAction should always be the last action
47
+ var previewAction = extractPreviewAction(extensionKey, props, jsonLd, handleInvoke, handleAnalytics, testId, platform, source, featureFlags); // The previewAction should always be the last action
47
48
 
48
49
  if (previewAction) {
49
50
  actions.push(previewAction);
@@ -60,6 +60,7 @@ export var extractPreviewAction = function extractPreviewAction() {
60
60
  var testId = arguments.length > 5 ? arguments[5] : undefined;
61
61
  var platform = arguments.length > 6 ? arguments[6] : undefined;
62
62
  var source = arguments.length > 7 ? arguments[7] : undefined;
63
+ var featureFlags = arguments.length > 8 ? arguments[8] : undefined;
63
64
  // Extract metadata from view props & raw JSON-LD.
64
65
  var metadataFromJsonLd = getMetadataFromJsonLd(jsonLd, platform);
65
66
  var metadataFromViewProps = getMetadataFromResolvedProps(viewProps);
@@ -71,12 +72,21 @@ export var extractPreviewAction = function extractPreviewAction() {
71
72
  // Build action using instrumentation hooks.
72
73
  var key = extensionKey;
73
74
  var previewAction = PreviewAction(_objectSpread(_objectSpread({}, metadata), {}, {
75
+ featureFlags: featureFlags,
74
76
  testId: testId,
75
77
  onOpen: function onOpen() {
76
- handleAnalytics(uiRenderSuccessEvent('preview', 'resolved', key));
78
+ handleAnalytics(uiRenderSuccessEvent({
79
+ display: 'preview',
80
+ status: 'resolved',
81
+ extensionKey: key
82
+ }));
77
83
  },
78
84
  onOpenFailed: function onOpenFailed(error, errorInfo) {
79
- handleAnalytics(uiRenderFailedEvent('preview', error, errorInfo));
85
+ handleAnalytics(uiRenderFailedEvent({
86
+ display: 'preview',
87
+ error: error,
88
+ errorInfo: errorInfo
89
+ }));
80
90
  },
81
91
  onDownloadActionClick: function onDownloadActionClick() {
82
92
  handleInvoke(getInvokeOpts(key, 'DownloadAction'));
@@ -184,24 +184,51 @@ export var useSmartCardActions = function useSmartCardActions(id, url, analytics
184
184
  var services = getServices(details); // When authentication is triggered, let GAS know!
185
185
 
186
186
  if (status === 'unauthorized') {
187
- analytics.ui.authEvent(appearance, definitionId, extensionKey);
187
+ analytics.ui.authEvent({
188
+ display: appearance,
189
+ definitionId: definitionId,
190
+ extensionKey: extensionKey
191
+ });
188
192
  }
189
193
 
190
194
  if (status === 'forbidden') {
191
- analytics.ui.authAlternateAccountEvent(appearance, definitionId, extensionKey);
195
+ analytics.ui.authAlternateAccountEvent({
196
+ display: appearance,
197
+ definitionId: definitionId,
198
+ extensionKey: extensionKey
199
+ });
192
200
  }
193
201
 
194
202
  if (services.length > 0) {
195
- analytics.screen.authPopupEvent(definitionId, extensionKey);
203
+ analytics.screen.authPopupEvent({
204
+ definitionId: definitionId,
205
+ extensionKey: extensionKey
206
+ });
196
207
  auth(services[0].url).then(function () {
197
- analytics.track.appAccountConnected(definitionId, extensionKey);
198
- analytics.operational.connectSucceededEvent(id, definitionId, extensionKey);
208
+ analytics.track.appAccountConnected({
209
+ definitionId: definitionId,
210
+ extensionKey: extensionKey
211
+ });
212
+ analytics.operational.connectSucceededEvent({
213
+ id: id,
214
+ definitionId: definitionId,
215
+ extensionKey: extensionKey
216
+ });
199
217
  reload();
200
218
  }, function (err) {
201
- analytics.operational.connectFailedEvent(id, definitionId, extensionKey, err.type);
219
+ analytics.operational.connectFailedEvent({
220
+ id: id,
221
+ definitionId: definitionId,
222
+ extensionKey: extensionKey,
223
+ reason: err.type
224
+ });
202
225
 
203
226
  if (err.type === 'auth_window_closed') {
204
- analytics.ui.closedAuthEvent(appearance, definitionId, extensionKey);
227
+ analytics.ui.closedAuthEvent({
228
+ display: appearance,
229
+ definitionId: definitionId,
230
+ extensionKey: extensionKey
231
+ });
205
232
  }
206
233
 
207
234
  reload();
@@ -222,7 +249,13 @@ export var useSmartCardActions = function useSmartCardActions(id, url, analytics
222
249
  measure.mark(markName, 'pending');
223
250
  _context2.prev = 4;
224
251
  // Begin analytics instrumentation.
225
- analytics.ui.actionClickedEvent(id, key, action.type, source, opts.type); // Invoke action - either client-side or server-side.
252
+ analytics.ui.actionClickedEvent({
253
+ id: id,
254
+ extensionKey: key,
255
+ actionType: action.type,
256
+ display: source,
257
+ invokeType: opts.type
258
+ }); // Invoke action - either client-side or server-side.
226
259
 
227
260
  if (!(opts.type === 'client')) {
228
261
  _context2.next = 12;
@@ -246,14 +279,25 @@ export var useSmartCardActions = function useSmartCardActions(id, url, analytics
246
279
 
247
280
  case 15:
248
281
  measure.mark(markName, 'resolved');
249
- analytics.operational.invokeSucceededEvent(id, key, action.type, source);
282
+ analytics.operational.invokeSucceededEvent({
283
+ id: id,
284
+ extensionKey: key,
285
+ actionType: action.type,
286
+ display: source
287
+ });
250
288
  return _context2.abrupt("return", response);
251
289
 
252
290
  case 20:
253
291
  _context2.prev = 20;
254
292
  _context2.t0 = _context2["catch"](4);
255
293
  measure.mark(markName, 'errored');
256
- analytics.operational.invokeFailedEvent(id, key, action.type, source, _context2.t0.message);
294
+ analytics.operational.invokeFailedEvent({
295
+ id: id,
296
+ extensionKey: key,
297
+ actionType: action.type,
298
+ display: source,
299
+ reason: _context2.t0.message
300
+ });
257
301
  throw _context2.t0;
258
302
 
259
303
  case 25:
@@ -0,0 +1 @@
1
+ export {};