@atlaskit/smart-card 21.2.0 → 21.3.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 (37) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cjs/version.json +1 -1
  3. package/dist/cjs/view/FlexibleCard/components/blocks/block/index.js +17 -3
  4. package/dist/cjs/view/FlexibleCard/components/blocks/preview-block/index.js +5 -2
  5. package/dist/cjs/view/FlexibleCard/components/common/image-icon/index.js +4 -2
  6. package/dist/cjs/view/FlexibleCard/components/common/loading-skeleton/index.js +1 -2
  7. package/dist/cjs/view/FlexibleCard/components/elements/media/index.js +5 -2
  8. package/dist/cjs/view/HoverCard/components/HoverCardContent.js +21 -4
  9. package/dist/cjs/view/HoverCard/components/SnippetOrPreview.js +74 -0
  10. package/dist/cjs/view/HoverCard/styled.js +11 -3
  11. package/dist/es2019/version.json +1 -1
  12. package/dist/es2019/view/FlexibleCard/components/blocks/block/index.js +17 -7
  13. package/dist/es2019/view/FlexibleCard/components/blocks/preview-block/index.js +4 -1
  14. package/dist/es2019/view/FlexibleCard/components/common/image-icon/index.js +4 -2
  15. package/dist/es2019/view/FlexibleCard/components/common/loading-skeleton/index.js +2 -3
  16. package/dist/es2019/view/FlexibleCard/components/elements/media/index.js +5 -2
  17. package/dist/es2019/view/HoverCard/components/HoverCardContent.js +21 -6
  18. package/dist/es2019/view/HoverCard/components/SnippetOrPreview.js +42 -0
  19. package/dist/es2019/view/HoverCard/styled.js +8 -0
  20. package/dist/esm/version.json +1 -1
  21. package/dist/esm/view/FlexibleCard/components/blocks/block/index.js +11 -3
  22. package/dist/esm/view/FlexibleCard/components/blocks/preview-block/index.js +5 -2
  23. package/dist/esm/view/FlexibleCard/components/common/image-icon/index.js +4 -2
  24. package/dist/esm/view/FlexibleCard/components/common/loading-skeleton/index.js +1 -2
  25. package/dist/esm/view/FlexibleCard/components/elements/media/index.js +5 -2
  26. package/dist/esm/view/HoverCard/components/HoverCardContent.js +21 -6
  27. package/dist/esm/view/HoverCard/components/SnippetOrPreview.js +53 -0
  28. package/dist/esm/view/HoverCard/styled.js +6 -2
  29. package/dist/types/view/FlexibleCard/components/blocks/preview-block/types.d.ts +7 -1
  30. package/dist/types/view/FlexibleCard/components/blocks/types.d.ts +15 -0
  31. package/dist/types/view/FlexibleCard/components/common/image-icon/types.d.ts +1 -0
  32. package/dist/types/view/FlexibleCard/components/elements/media/types.d.ts +5 -0
  33. package/dist/types/view/HoverCard/components/SnippetOrPreview.d.ts +4 -0
  34. package/dist/types/view/HoverCard/styled.d.ts +2 -0
  35. package/dist/types/view/HoverCard/types.d.ts +5 -0
  36. package/package.json +1 -1
  37. package/report.api.md +22 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @atlaskit/smart-card
2
2
 
3
+ ## 21.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`1c76ddcd2f3`](https://bitbucket.org/atlassian/atlassian-frontend/commits/1c76ddcd2f3) - [ux] Flex-UI: - Add props to generic block: - onRender - onTransitionEnd - blockRef
8
+ HoverCard: - use the above properties in Hover Card to apply transition to preview block and fallback to snippet
9
+
3
10
  ## 21.2.0
4
11
 
5
12
  ### Minor Changes
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "21.2.0",
3
+ "version": "21.3.0",
4
4
  "sideEffects": false
5
5
  }
@@ -2,6 +2,8 @@
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
4
 
5
+ var _typeof = require("@babel/runtime/helpers/typeof");
6
+
5
7
  Object.defineProperty(exports, "__esModule", {
6
8
  value: true
7
9
  });
@@ -9,7 +11,7 @@ exports.default = void 0;
9
11
 
10
12
  var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
11
13
 
12
- var _react = _interopRequireDefault(require("react"));
14
+ var _react = _interopRequireWildcard(require("react"));
13
15
 
14
16
  var _core = require("@emotion/core");
15
17
 
@@ -19,6 +21,10 @@ var _utils = require("../utils");
19
21
 
20
22
  var _templateObject;
21
23
 
24
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
25
+
26
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
27
+
22
28
  var getBlockStyles = function getBlockStyles(direction, size) {
23
29
  return (0, _core.css)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n ", "\n ", "\n justify-content: flex-start;\n [data-separator] + [data-separator]:before {\n content: '\u2022';\n margin-right: ", "rem;\n }\n // Pull request elements: source branch \u2192 target branch\n [data-smart-element='", "']\n + [data-smart-element='", "']:before {\n content: '\u2192';\n }\n // Pull request elements: target branch \u2190 source branch\n [data-smart-element='", "']\n + [data-smart-element='", "']:before {\n content: '\u2190';\n }\n"])), (0, _utils.getBaseStyles)(direction, size), _utils.highlightRemoveStyles, (0, _utils.getGapSize)(size), _constants.ElementName.SourceBranch, _constants.ElementName.TargetBranch, _constants.ElementName.TargetBranch, _constants.ElementName.SourceBranch);
24
30
  };
@@ -39,11 +45,19 @@ var Block = function Block(_ref) {
39
45
  size = _ref$size === void 0 ? _constants.SmartLinkSize.Medium : _ref$size,
40
46
  _ref$testId = _ref.testId,
41
47
  testId = _ref$testId === void 0 ? 'smart-block' : _ref$testId,
42
- overrideCss = _ref.overrideCss;
48
+ overrideCss = _ref.overrideCss,
49
+ blockRef = _ref.blockRef,
50
+ onRender = _ref.onRender,
51
+ onTransitionEnd = _ref.onTransitionEnd;
52
+ (0, _react.useEffect)(function () {
53
+ onRender && onRender();
54
+ }, [onRender]);
43
55
  return (0, _core.jsx)("div", {
44
56
  css: [getBlockStyles(direction, size), overrideCss],
45
57
  "data-smart-block": true,
46
- "data-testid": testId
58
+ "data-testid": testId,
59
+ onTransitionEnd: onTransitionEnd,
60
+ ref: blockRef
47
61
  }, (0, _utils.renderChildren)(children, size));
48
62
  };
49
63
 
@@ -19,7 +19,7 @@ var _block = _interopRequireDefault(require("../block"));
19
19
 
20
20
  var _elements = require("../../elements");
21
21
 
22
- var _excluded = ["status", "testId"];
22
+ var _excluded = ["status", "testId", "onError"];
23
23
 
24
24
  /**
25
25
  * Represents a PreviewBlock, which typically contains media or other large format content.
@@ -32,6 +32,7 @@ var PreviewBlock = function PreviewBlock(_ref) {
32
32
  status = _ref$status === void 0 ? _constants.SmartLinkStatus.Fallback : _ref$status,
33
33
  _ref$testId = _ref.testId,
34
34
  testId = _ref$testId === void 0 ? 'smart-block-preview' : _ref$testId,
35
+ onError = _ref.onError,
35
36
  blockProps = (0, _objectWithoutProperties2.default)(_ref, _excluded);
36
37
 
37
38
  if (status !== _constants.SmartLinkStatus.Resolved) {
@@ -40,7 +41,9 @@ var PreviewBlock = function PreviewBlock(_ref) {
40
41
 
41
42
  return /*#__PURE__*/_react.default.createElement(_block.default, (0, _extends2.default)({}, blockProps, {
42
43
  testId: "".concat(testId, "-resolved-view")
43
- }), /*#__PURE__*/_react.default.createElement(_elements.Preview, null));
44
+ }), /*#__PURE__*/_react.default.createElement(_elements.Preview, {
45
+ onError: onError
46
+ }));
44
47
  };
45
48
 
46
49
  var _default = PreviewBlock;
@@ -19,7 +19,8 @@ var _loadingSkeleton = _interopRequireDefault(require("../loading-skeleton"));
19
19
  var ImageIcon = function ImageIcon(_ref) {
20
20
  var defaultIcon = _ref.defaultIcon,
21
21
  testId = _ref.testId,
22
- url = _ref.url;
22
+ url = _ref.url,
23
+ onError = _ref.onError;
23
24
  return (0, _core.jsx)(_reactRenderImage.default, {
24
25
  src: url,
25
26
  loading: (0, _core.jsx)(_loadingSkeleton.default, {
@@ -29,7 +30,8 @@ var ImageIcon = function ImageIcon(_ref) {
29
30
  src: url,
30
31
  "data-testid": "".concat(testId, "-image")
31
32
  }),
32
- errored: defaultIcon
33
+ errored: defaultIcon,
34
+ onError: onError
33
35
  });
34
36
  };
35
37
 
@@ -21,8 +21,7 @@ var LoadingSkeleton = function LoadingSkeleton(_ref) {
21
21
  var testId = _ref.testId,
22
22
  width = _ref.width,
23
23
  height = _ref.height;
24
- var animationWidth = width ? "".concat(width, "rem") : '20px';
25
- var animationNameStyles = (0, _core.keyframes)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n 0% { background-position: -", " 0; }\n 100% { background-position: ", " 0; }\n "])), animationWidth, animationWidth);
24
+ var animationNameStyles = (0, _core.keyframes)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n 0% { background-position: 50% 0; }\n 100% { background-position: -50% 0; }\n "])));
26
25
  var styles = (0, _core.css)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\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, (0, _tokens.token)('color.skeleton.subtle', '#f6f7f8'), (0, _tokens.token)('color.skeleton.subtle', '#f6f7f8'), (0, _tokens.token)('color.skeleton', '#edeef1'), (0, _tokens.token)('color.skeleton.subtle', '#f6f7f8'), (0, _tokens.token)('color.skeleton.subtle', '#f6f7f8'), animationNameStyles);
27
26
  return (0, _core.jsx)("span", {
28
27
  css: styles,
@@ -41,7 +41,8 @@ var Media = function Media(_ref) {
41
41
  _ref$testId = _ref.testId,
42
42
  testId = _ref$testId === void 0 ? 'smart-element-media' : _ref$testId,
43
43
  type = _ref.type,
44
- url = _ref.url;
44
+ url = _ref.url,
45
+ onError = _ref.onError;
45
46
 
46
47
  if (!type || !url) {
47
48
  return null;
@@ -54,7 +55,9 @@ var Media = function Media(_ref) {
54
55
  "data-testid": testId
55
56
  }, (0, _core.jsx)(_imageIcon.default, {
56
57
  testId: "".concat(testId, "-image"),
57
- url: url
58
+ url: url,
59
+ onError: onError,
60
+ defaultIcon: null
58
61
  }));
59
62
  };
60
63
 
@@ -17,8 +17,6 @@ var _react = _interopRequireWildcard(require("react"));
17
17
 
18
18
  var _constants = require("../../../constants");
19
19
 
20
- var _extractPreview = _interopRequireDefault(require("../../../extractors/flexible/extract-preview"));
21
-
22
20
  var _extractMetadata2 = require("../../../extractors/hover/extractMetadata");
23
21
 
24
22
  var _actions = require("../../../state/actions");
@@ -37,6 +35,8 @@ var _utils2 = require("../utils");
37
35
 
38
36
  var _HoverCardLoadingView = _interopRequireDefault(require("./HoverCardLoadingView"));
39
37
 
38
+ var _SnippetOrPreview = _interopRequireDefault(require("./SnippetOrPreview"));
39
+
40
40
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
41
41
 
42
42
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -126,7 +126,19 @@ var HoverCardContent = function HoverCardContent(_ref) {
126
126
  subtitle = _extractMetadata.subtitle;
127
127
 
128
128
  var titleMaxLines = subtitle && subtitle.length > 0 ? 1 : 2;
129
- var body = data && (0, _extractPreview.default)(data) ? /*#__PURE__*/_react.default.createElement(_blocks.PreviewBlock, null) : /*#__PURE__*/_react.default.createElement(_blocks.SnippetBlock, null);
129
+
130
+ var snippetHeight = _react.default.useRef(0);
131
+
132
+ var snippetBlockRef = (0, _react.useRef)(null);
133
+ var onSnippetRender = (0, _react.useCallback)(function () {
134
+ var _snippetBlockRef$curr, _snippetBlockRef$curr2;
135
+
136
+ 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;
137
+ }, []);
138
+ var body = (0, _SnippetOrPreview.default)({
139
+ data: data,
140
+ snippetHeight: snippetHeight.current
141
+ });
130
142
  var titleBlockProps = {
131
143
  actions: titleActions,
132
144
  maxLines: titleMaxLines,
@@ -159,7 +171,12 @@ var HoverCardContent = function HoverCardContent(_ref) {
159
171
  size: _constants.SmartLinkSize.Large,
160
172
  overrideCss: _styled.metadataBlockCss,
161
173
  maxLines: 1
162
- }), body, /*#__PURE__*/_react.default.createElement(_blocks.FooterBlock, {
174
+ }), body, /*#__PURE__*/_react.default.createElement(_blocks.SnippetBlock, {
175
+ testId: 'hidden-snippet',
176
+ onRender: onSnippetRender,
177
+ blockRef: snippetBlockRef,
178
+ overrideCss: _styled.hiddenSnippetStyles
179
+ }), /*#__PURE__*/_react.default.createElement(_blocks.FooterBlock, {
163
180
  actions: footerActions,
164
181
  size: _constants.SmartLinkSize.Large,
165
182
  overrideCss: _styled.footerBlockCss
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ var _typeof = require("@babel/runtime/helpers/typeof");
6
+
7
+ Object.defineProperty(exports, "__esModule", {
8
+ value: true
9
+ });
10
+ exports.default = void 0;
11
+
12
+ var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
13
+
14
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
15
+
16
+ var _react = _interopRequireWildcard(require("react"));
17
+
18
+ var _core = require("@emotion/core");
19
+
20
+ var _extractPreview = _interopRequireDefault(require("../../../extractors/flexible/extract-preview"));
21
+
22
+ var _blocks = require("../../FlexibleCard/components/blocks");
23
+
24
+ var _styled = require("../styled");
25
+
26
+ var _templateObject;
27
+
28
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
29
+
30
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
31
+
32
+ var SnippetOrPreview = function SnippetOrPreview(_ref) {
33
+ var data = _ref.data,
34
+ snippetHeight = _ref.snippetHeight;
35
+ var transitionStarted = (0, _react.useRef)(false);
36
+ var previewBlockRef = (0, _react.useRef)(null);
37
+
38
+ var _useState = (0, _react.useState)(false),
39
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
40
+ showSnippet = _useState2[0],
41
+ setShowSnippet = _useState2[1];
42
+
43
+ var _useState3 = (0, _react.useState)(),
44
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
45
+ previewCss = _useState4[0],
46
+ setPreviewCss = _useState4[1]; // Set Preview to a fixed height to enable transitions
47
+
48
+
49
+ var onPreviewRender = (0, _react.useCallback)(function () {
50
+ var _previewBlockRef$curr;
51
+
52
+ previewBlockRef.current && setPreviewCss((0, _core.css)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n height: ", "px;\n "])), (_previewBlockRef$curr = previewBlockRef.current) === null || _previewBlockRef$curr === void 0 ? void 0 : _previewBlockRef$curr.getBoundingClientRect().height));
53
+ }, []); // On error set Preview to Snippet height with transition
54
+
55
+ var onPreviewError = (0, _react.useCallback)(function () {
56
+ if (transitionStarted.current === false) {
57
+ setPreviewCss((0, _styled.getTransitionStyles)(snippetHeight));
58
+ transitionStarted.current = true;
59
+ }
60
+ }, [snippetHeight]);
61
+ var onPreviewTransitionEnd = (0, _react.useCallback)(function () {
62
+ setShowSnippet(true);
63
+ }, []);
64
+ return !showSnippet && data && (0, _extractPreview.default)(data) ? /*#__PURE__*/_react.default.createElement(_blocks.PreviewBlock, {
65
+ onError: onPreviewError,
66
+ overrideCss: previewCss,
67
+ onTransitionEnd: onPreviewTransitionEnd,
68
+ blockRef: previewBlockRef,
69
+ onRender: onPreviewRender
70
+ }) : /*#__PURE__*/_react.default.createElement(_blocks.SnippetBlock, null);
71
+ };
72
+
73
+ var _default = SnippetOrPreview;
74
+ exports.default = _default;
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.titleBlockCss = exports.skeletonContainer = exports.metadataBlockCss = exports.loadingViewContainer = exports.footerBlockCss = exports.flexibleUiOptions = exports.HoverCardContainer = exports.CARD_WIDTH_REM = exports.CARD_GAP_PX = void 0;
8
+ exports.titleBlockCss = exports.skeletonContainer = exports.metadataBlockCss = exports.loadingViewContainer = exports.hiddenSnippetStyles = exports.getTransitionStyles = exports.footerBlockCss = exports.flexibleUiOptions = exports.HoverCardContainer = exports.CARD_WIDTH_REM = exports.CARD_GAP_PX = void 0;
9
9
 
10
10
  var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
11
11
 
@@ -15,7 +15,7 @@ var _index = require("../../index");
15
15
 
16
16
  var _constants = require("../../constants");
17
17
 
18
- var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
18
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9;
19
19
 
20
20
  var flexibleUiOptions = {
21
21
  hideElevation: true,
@@ -44,4 +44,12 @@ exports.footerBlockCss = footerBlockCss;
44
44
  var loadingViewContainer = (0, _core.css)(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n flex-direction: column;\n"])));
45
45
  exports.loadingViewContainer = loadingViewContainer;
46
46
  var skeletonContainer = (0, _core.css)(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n flex-direction: column;\n gap: 0.625rem;\n align-items: center;\n"])));
47
- exports.skeletonContainer = skeletonContainer;
47
+ exports.skeletonContainer = skeletonContainer;
48
+ var hiddenSnippetStyles = (0, _core.css)(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2.default)(["\n visibility: hidden;\n position: absolute;\n"])));
49
+ exports.hiddenSnippetStyles = hiddenSnippetStyles;
50
+
51
+ var getTransitionStyles = function getTransitionStyles(snippetHeight) {
52
+ return (0, _core.css)(_templateObject9 || (_templateObject9 = (0, _taggedTemplateLiteral2.default)(["\n transition: height 300ms ease-in-out;\n height: ", "px;\n"])), snippetHeight);
53
+ };
54
+
55
+ exports.getTransitionStyles = getTransitionStyles;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "21.2.0",
3
+ "version": "21.3.0",
4
4
  "sideEffects": false
5
5
  }
@@ -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;
@@ -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
 
@@ -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, {
@@ -79,7 +79,17 @@ const HoverCardContent = ({
79
79
  subtitle
80
80
  } = extractMetadata(getSimulatedMetadata(extensionKey, types));
81
81
  const titleMaxLines = subtitle && subtitle.length > 0 ? 1 : 2;
82
- const body = data && extractPreview(data) ? /*#__PURE__*/React.createElement(PreviewBlock, null) : /*#__PURE__*/React.createElement(SnippetBlock, null);
82
+ const snippetHeight = React.useRef(0);
83
+ const snippetBlockRef = useRef(null);
84
+ const onSnippetRender = useCallback(() => {
85
+ var _snippetBlockRef$curr, _snippetBlockRef$curr2;
86
+
87
+ 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;
88
+ }, []);
89
+ const body = SnippetOrPreview({
90
+ data: data,
91
+ snippetHeight: snippetHeight.current
92
+ });
83
93
  const titleBlockProps = {
84
94
  actions: titleActions,
85
95
  maxLines: titleMaxLines,
@@ -112,7 +122,12 @@ const HoverCardContent = ({
112
122
  size: SmartLinkSize.Large,
113
123
  overrideCss: metadataBlockCss,
114
124
  maxLines: 1
115
- }), body, /*#__PURE__*/React.createElement(FooterBlock, {
125
+ }), body, /*#__PURE__*/React.createElement(SnippetBlock, {
126
+ testId: 'hidden-snippet',
127
+ onRender: onSnippetRender,
128
+ blockRef: snippetBlockRef,
129
+ overrideCss: hiddenSnippetStyles
130
+ }), /*#__PURE__*/React.createElement(FooterBlock, {
116
131
  actions: footerActions,
117
132
  size: SmartLinkSize.Large,
118
133
  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;
@@ -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
  `;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "21.2.0",
3
+ "version": "21.3.0",
4
4
  "sideEffects": false
5
5
  }
@@ -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;
@@ -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
 
@@ -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,
@@ -92,7 +92,17 @@ var HoverCardContent = function HoverCardContent(_ref) {
92
92
  subtitle = _extractMetadata.subtitle;
93
93
 
94
94
  var titleMaxLines = subtitle && subtitle.length > 0 ? 1 : 2;
95
- var body = data && extractPreview(data) ? /*#__PURE__*/React.createElement(PreviewBlock, null) : /*#__PURE__*/React.createElement(SnippetBlock, null);
95
+ var snippetHeight = React.useRef(0);
96
+ var snippetBlockRef = useRef(null);
97
+ var onSnippetRender = useCallback(function () {
98
+ var _snippetBlockRef$curr, _snippetBlockRef$curr2;
99
+
100
+ 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;
101
+ }, []);
102
+ var body = SnippetOrPreview({
103
+ data: data,
104
+ snippetHeight: snippetHeight.current
105
+ });
96
106
  var titleBlockProps = {
97
107
  actions: titleActions,
98
108
  maxLines: titleMaxLines,
@@ -125,7 +135,12 @@ var HoverCardContent = function HoverCardContent(_ref) {
125
135
  size: SmartLinkSize.Large,
126
136
  overrideCss: metadataBlockCss,
127
137
  maxLines: 1
128
- }), body, /*#__PURE__*/React.createElement(FooterBlock, {
138
+ }), body, /*#__PURE__*/React.createElement(SnippetBlock, {
139
+ testId: 'hidden-snippet',
140
+ onRender: onSnippetRender,
141
+ blockRef: snippetBlockRef,
142
+ overrideCss: hiddenSnippetStyles
143
+ }), /*#__PURE__*/React.createElement(FooterBlock, {
129
144
  actions: footerActions,
130
145
  size: SmartLinkSize.Large,
131
146
  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;
@@ -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,2 +1,8 @@
1
1
  import { BlockProps } from '../types';
2
- export declare type PreviewBlockProps = BlockProps;
2
+ export declare type PreviewBlockProps = {
3
+ /**
4
+ * Function to be called on error loading media.
5
+ * @internal
6
+ */
7
+ onError?: () => void;
8
+ } & BlockProps;
@@ -1,6 +1,7 @@
1
1
  import { ActionName, ElementName, SmartLinkDirection, SmartLinkSize, SmartLinkStatus } from '../../../../constants';
2
2
  import { SerializedStyles } from '@emotion/core';
3
3
  import { ActionProps } from '../actions/action/types';
4
+ import { Ref } from 'react';
4
5
  export declare type BlockProps = {
5
6
  /**
6
7
  * The direction that the block should arrange it's elements. Can be vertical
@@ -29,6 +30,20 @@ export declare type BlockProps = {
29
30
  * serving as a hook for automated tests
30
31
  */
31
32
  testId?: string;
33
+ /**
34
+ * Ref to block wrapper div.
35
+ */
36
+ blockRef?: Ref<HTMLDivElement>;
37
+ /**
38
+ * Function to be called on render of block.
39
+ * @internal
40
+ */
41
+ onRender?: () => void;
42
+ /**
43
+ * Function to be called on transition end of block.
44
+ * @internal
45
+ */
46
+ onTransitionEnd?: () => void;
32
47
  };
33
48
  /**
34
49
  * Used to represent a metadata element to be rendered.
@@ -3,4 +3,5 @@ export declare type ImageIconProps = {
3
3
  defaultIcon?: React.ReactNode;
4
4
  testId?: string;
5
5
  url: string;
6
+ onError?: () => void;
6
7
  };
@@ -9,4 +9,9 @@ export declare type MediaProps = ElementProps & {
9
9
  * The URL of the associated media to display.
10
10
  */
11
11
  url?: string;
12
+ /**
13
+ * Function to be called on error loading media.
14
+ * @internal
15
+ */
16
+ onError?: () => void;
12
17
  };
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { SnippetOrPreviewProps } from '../types';
3
+ declare const SnippetOrPreview: React.FC<SnippetOrPreviewProps>;
4
+ export default SnippetOrPreview;
@@ -8,3 +8,5 @@ export declare const metadataBlockCss: import("@emotion/utils").SerializedStyles
8
8
  export declare const footerBlockCss: import("@emotion/utils").SerializedStyles;
9
9
  export declare const loadingViewContainer: import("@emotion/utils").SerializedStyles;
10
10
  export declare const skeletonContainer: import("@emotion/utils").SerializedStyles;
11
+ export declare const hiddenSnippetStyles: import("@emotion/utils").SerializedStyles;
12
+ export declare const getTransitionStyles: (snippetHeight: number) => import("@emotion/utils").SerializedStyles;
@@ -8,6 +8,7 @@ import { AnalyticsHandler } from '../../utils/types';
8
8
  import { ReactElement } from 'react';
9
9
  import { TitleBlockProps } from '../FlexibleCard/components/blocks/title-block/types';
10
10
  import { FlexibleCardProps } from '../FlexibleCard/types';
11
+ import { JsonLd } from 'json-ld-types';
11
12
  export interface HoverCardProps extends WithAnalyticsEventsProps {
12
13
  id?: string;
13
14
  url: string;
@@ -38,3 +39,7 @@ export declare type HoverCardLoadingViewProps = {
38
39
  flexibleCardProps: FlexibleCardProps;
39
40
  titleBlockProps: TitleBlockProps;
40
41
  };
42
+ export declare type SnippetOrPreviewProps = {
43
+ data: JsonLd.Data.BaseData;
44
+ snippetHeight: number;
45
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "21.2.0",
3
+ "version": "21.3.0",
4
4
  "description": "Smart card component",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
package/report.api.md CHANGED
@@ -29,6 +29,7 @@ import { SmartCardProvider as Provider } from '@atlaskit/link-provider';
29
29
  import { ProviderProps } from '@atlaskit/link-provider';
30
30
  import { default as React_2 } from 'react';
31
31
  import { ReactChild } from 'react';
32
+ import { Ref } from 'react';
32
33
  import { SerializedStyles } from '@emotion/core';
33
34
  import { SmartCardContext } from '@atlaskit/link-provider';
34
35
  import { WithAnalyticsEventsProps } from '@atlaskit/analytics-next';
@@ -237,6 +238,20 @@ declare type BlockProps = {
237
238
  * serving as a hook for automated tests
238
239
  */
239
240
  testId?: string;
241
+ /**
242
+ * Ref to block wrapper div.
243
+ */
244
+ blockRef?: Ref<HTMLDivElement>;
245
+ /**
246
+ * Function to be called on render of block.
247
+ * @internal
248
+ */
249
+ onRender?: () => void;
250
+ /**
251
+ * Function to be called on transition end of block.
252
+ * @internal
253
+ */
254
+ onTransitionEnd?: () => void;
240
255
  };
241
256
 
242
257
  export declare const Card: React_2.ForwardRefExoticComponent<
@@ -672,7 +687,13 @@ declare type Preview = {
672
687
  */
673
688
  export declare const PreviewBlock: React_2.FC<PreviewBlockProps>;
674
689
 
675
- declare type PreviewBlockProps = BlockProps;
690
+ declare type PreviewBlockProps = {
691
+ /**
692
+ * Function to be called on error loading media.
693
+ * @internal
694
+ */
695
+ onError?: () => void;
696
+ } & BlockProps;
676
697
 
677
698
  declare type PreviewDisplay = 'card' | 'embed';
678
699