@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.
- package/CHANGELOG.md +7 -0
- package/dist/cjs/version.json +1 -1
- 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/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/HoverCardContent.js +21 -4
- package/dist/cjs/view/HoverCard/components/SnippetOrPreview.js +74 -0
- package/dist/cjs/view/HoverCard/styled.js +11 -3
- package/dist/es2019/version.json +1 -1
- 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/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/HoverCardContent.js +21 -6
- package/dist/es2019/view/HoverCard/components/SnippetOrPreview.js +42 -0
- package/dist/es2019/view/HoverCard/styled.js +8 -0
- package/dist/esm/version.json +1 -1
- 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/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/HoverCardContent.js +21 -6
- package/dist/esm/view/HoverCard/components/SnippetOrPreview.js +53 -0
- package/dist/esm/view/HoverCard/styled.js +6 -2
- 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 +1 -1
- 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
|
package/dist/cjs/version.json
CHANGED
|
@@ -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 =
|
|
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,
|
|
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
|
|
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
|
-
|
|
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.
|
|
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;
|
package/dist/es2019/version.json
CHANGED
|
@@ -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;
|
|
@@ -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
|
|
|
@@ -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, {
|
|
@@ -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
|
|
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(
|
|
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
|
`;
|
package/dist/esm/version.json
CHANGED
|
@@ -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,
|
|
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
|
|
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,
|
|
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
|
|
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(
|
|
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,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.
|
|
@@ -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
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 =
|
|
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
|
|