@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.
- package/CHANGELOG.md +61 -0
- package/dist/cjs/extractors/block/index.js +3 -2
- package/dist/cjs/extractors/common/actions/extractPreviewAction.js +12 -2
- package/dist/cjs/state/actions/index.js +54 -10
- package/dist/cjs/state/analytics/types.js +5 -0
- package/dist/cjs/state/analytics/useSmartLinkAnalytics.js +386 -109
- package/dist/cjs/state/hooks-external/useSmartLinkActions.js +12 -2
- package/dist/cjs/utils/analytics/analytics.js +239 -72
- package/dist/cjs/utils/analytics/index.js +32 -5
- package/dist/cjs/version.json +1 -1
- package/dist/cjs/view/BlockCard/actions/PreviewAction.js +1 -1
- package/dist/cjs/view/BlockCard/index.js +10 -0
- package/dist/cjs/view/CardWithUrl/component.js +26 -4
- package/dist/cjs/view/CardWithUrl/loader.js +6 -1
- package/dist/cjs/view/EmbedModal/components/size-experiment/index.js +41 -0
- package/dist/cjs/view/EmbedModal/components/size-experiment/types.js +5 -0
- package/dist/cjs/view/EmbedModal/index.js +7 -3
- package/dist/cjs/view/FlexibleCard/components/blocks/block/index.js +17 -3
- package/dist/cjs/view/FlexibleCard/components/blocks/preview-block/index.js +5 -2
- package/dist/cjs/view/FlexibleCard/components/common/atlaskit-icon/index.js +20 -8
- package/dist/cjs/view/FlexibleCard/components/common/image-icon/index.js +4 -2
- package/dist/cjs/view/FlexibleCard/components/common/loading-skeleton/index.js +1 -2
- package/dist/cjs/view/FlexibleCard/components/elements/media/index.js +5 -2
- package/dist/cjs/view/HoverCard/components/HoverCardComponent.js +9 -2
- package/dist/cjs/view/HoverCard/components/HoverCardContent.js +36 -8
- package/dist/cjs/view/HoverCard/components/SnippetOrPreview.js +74 -0
- package/dist/cjs/view/HoverCard/index.js +6 -1
- package/dist/cjs/view/HoverCard/styled.js +11 -3
- package/dist/es2019/extractors/block/index.js +2 -1
- package/dist/es2019/extractors/common/actions/extractPreviewAction.js +12 -3
- package/dist/es2019/state/actions/index.js +54 -10
- package/dist/es2019/state/analytics/types.js +1 -0
- package/dist/es2019/state/analytics/useSmartLinkAnalytics.js +379 -39
- package/dist/es2019/state/hooks-external/useSmartLinkActions.js +11 -2
- package/dist/es2019/utils/analytics/analytics.js +253 -78
- package/dist/es2019/utils/analytics/index.js +32 -4
- package/dist/es2019/version.json +1 -1
- package/dist/es2019/view/BlockCard/actions/PreviewAction.js +1 -1
- package/dist/es2019/view/BlockCard/index.js +9 -0
- package/dist/es2019/view/CardWithUrl/component.js +26 -4
- package/dist/es2019/view/CardWithUrl/loader.js +6 -1
- package/dist/es2019/view/EmbedModal/components/size-experiment/index.js +28 -0
- package/dist/es2019/view/EmbedModal/components/size-experiment/types.js +1 -0
- package/dist/es2019/view/EmbedModal/index.js +5 -3
- package/dist/es2019/view/FlexibleCard/components/blocks/block/index.js +17 -7
- package/dist/es2019/view/FlexibleCard/components/blocks/preview-block/index.js +4 -1
- package/dist/es2019/view/FlexibleCard/components/common/atlaskit-icon/index.js +17 -6
- package/dist/es2019/view/FlexibleCard/components/common/image-icon/index.js +4 -2
- package/dist/es2019/view/FlexibleCard/components/common/loading-skeleton/index.js +2 -3
- package/dist/es2019/view/FlexibleCard/components/elements/media/index.js +5 -2
- package/dist/es2019/view/HoverCard/components/HoverCardComponent.js +9 -2
- package/dist/es2019/view/HoverCard/components/HoverCardContent.js +36 -10
- package/dist/es2019/view/HoverCard/components/SnippetOrPreview.js +42 -0
- package/dist/es2019/view/HoverCard/index.js +6 -1
- package/dist/es2019/view/HoverCard/styled.js +8 -0
- package/dist/esm/extractors/block/index.js +3 -2
- package/dist/esm/extractors/common/actions/extractPreviewAction.js +12 -2
- package/dist/esm/state/actions/index.js +54 -10
- package/dist/esm/state/analytics/types.js +1 -0
- package/dist/esm/state/analytics/useSmartLinkAnalytics.js +383 -109
- package/dist/esm/state/hooks-external/useSmartLinkActions.js +11 -2
- package/dist/esm/utils/analytics/analytics.js +239 -72
- package/dist/esm/utils/analytics/index.js +31 -4
- package/dist/esm/version.json +1 -1
- package/dist/esm/view/BlockCard/actions/PreviewAction.js +1 -1
- package/dist/esm/view/BlockCard/index.js +9 -0
- package/dist/esm/view/CardWithUrl/component.js +26 -4
- package/dist/esm/view/CardWithUrl/loader.js +6 -1
- package/dist/esm/view/EmbedModal/components/size-experiment/index.js +28 -0
- package/dist/esm/view/EmbedModal/components/size-experiment/types.js +1 -0
- package/dist/esm/view/EmbedModal/index.js +6 -3
- package/dist/esm/view/FlexibleCard/components/blocks/block/index.js +11 -3
- package/dist/esm/view/FlexibleCard/components/blocks/preview-block/index.js +5 -2
- package/dist/esm/view/FlexibleCard/components/common/atlaskit-icon/index.js +18 -8
- package/dist/esm/view/FlexibleCard/components/common/image-icon/index.js +4 -2
- package/dist/esm/view/FlexibleCard/components/common/loading-skeleton/index.js +1 -2
- package/dist/esm/view/FlexibleCard/components/elements/media/index.js +5 -2
- package/dist/esm/view/HoverCard/components/HoverCardComponent.js +9 -2
- package/dist/esm/view/HoverCard/components/HoverCardContent.js +36 -10
- package/dist/esm/view/HoverCard/components/SnippetOrPreview.js +53 -0
- package/dist/esm/view/HoverCard/index.js +6 -1
- package/dist/esm/view/HoverCard/styled.js +6 -2
- package/dist/types/extractors/block/types.d.ts +2 -0
- package/dist/types/extractors/common/actions/extractPreviewAction.d.ts +2 -1
- package/dist/types/state/analytics/types.d.ts +9 -0
- package/dist/types/state/analytics/useSmartLinkAnalytics.d.ts +18 -23
- package/dist/types/state/hooks/useSmartLink.d.ts +17 -18
- package/dist/types/utils/analytics/analytics.d.ts +19 -21
- package/dist/types/utils/analytics/index.d.ts +2 -2
- package/dist/types/utils/analytics/types.d.ts +91 -0
- package/dist/types/view/BlockCard/actions/PreviewAction.d.ts +4 -2
- package/dist/types/view/Card/index.d.ts +1 -1
- package/dist/types/view/EmbedModal/components/size-experiment/index.d.ts +6 -0
- package/dist/types/view/EmbedModal/components/size-experiment/types.d.ts +4 -0
- package/dist/types/view/EmbedModal/index.d.ts +1 -1
- package/dist/types/view/EmbedModal/types.d.ts +4 -0
- package/dist/types/view/FlexibleCard/components/blocks/preview-block/types.d.ts +7 -1
- package/dist/types/view/FlexibleCard/components/blocks/types.d.ts +15 -0
- package/dist/types/view/FlexibleCard/components/common/image-icon/types.d.ts +1 -0
- package/dist/types/view/FlexibleCard/components/elements/media/types.d.ts +5 -0
- package/dist/types/view/HoverCard/components/SnippetOrPreview.d.ts +4 -0
- package/dist/types/view/HoverCard/styled.d.ts +2 -0
- package/dist/types/view/HoverCard/types.d.ts +5 -0
- package/package.json +2 -2
- 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;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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-
|
|
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(
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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,
|
|
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:
|
|
14
|
-
100% { background-position:
|
|
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(
|
|
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(
|
|
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,
|
|
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(
|
|
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(
|
|
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(
|
|
70
|
-
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
203
|
+
analytics.screen.authPopupEvent({
|
|
204
|
+
definitionId: definitionId,
|
|
205
|
+
extensionKey: extensionKey
|
|
206
|
+
});
|
|
196
207
|
auth(services[0].url).then(function () {
|
|
197
|
-
analytics.track.appAccountConnected(
|
|
198
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 {};
|