@atlaskit/smart-card 20.1.0 → 20.1.3
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 +18 -0
- package/dist/cjs/version.json +1 -1
- package/dist/cjs/view/FlexibleCard/components/common/loading-skeleton/index.js +6 -4
- package/dist/cjs/view/HoverCard/components/HoverCardComponent.js +32 -4
- package/dist/cjs/view/HoverCard/components/HoverCardContent.js +23 -9
- package/dist/cjs/view/HoverCard/components/HoverCardLoadingView.js +46 -0
- package/dist/cjs/view/HoverCard/styled.js +13 -4
- package/dist/es2019/version.json +1 -1
- package/dist/es2019/view/FlexibleCard/components/common/loading-skeleton/index.js +38 -31
- package/dist/es2019/view/HoverCard/components/HoverCardComponent.js +33 -5
- package/dist/es2019/view/HoverCard/components/HoverCardContent.js +22 -9
- package/dist/es2019/view/HoverCard/components/HoverCardLoadingView.js +32 -0
- package/dist/es2019/view/HoverCard/styled.js +14 -1
- package/dist/esm/version.json +1 -1
- package/dist/esm/view/FlexibleCard/components/common/loading-skeleton/index.js +6 -3
- package/dist/esm/view/HoverCard/components/HoverCardComponent.js +33 -5
- package/dist/esm/view/HoverCard/components/HoverCardContent.js +22 -9
- package/dist/esm/view/HoverCard/components/HoverCardLoadingView.js +31 -0
- package/dist/esm/view/HoverCard/styled.js +8 -3
- package/dist/types/view/FlexibleCard/components/common/loading-skeleton/types.d.ts +8 -0
- package/dist/types/view/HoverCard/components/HoverCardLoadingView.d.ts +4 -0
- package/dist/types/view/HoverCard/styled.d.ts +4 -0
- package/dist/types/view/HoverCard/types.d.ts +6 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @atlaskit/smart-card
|
|
2
2
|
|
|
3
|
+
## 20.1.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`7c0644e5daf`](https://bitbucket.org/atlassian/atlassian-frontend/commits/7c0644e5daf) - fix on mouse hover functionality for hover cards
|
|
8
|
+
|
|
9
|
+
## 20.1.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`0fb4cccede9`](https://bitbucket.org/atlassian/atlassian-frontend/commits/0fb4cccede9) - add on mouse hover to hover card
|
|
14
|
+
|
|
15
|
+
## 20.1.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [`59469f2ed1c`](https://bitbucket.org/atlassian/atlassian-frontend/commits/59469f2ed1c) - Add loading state for hover previews
|
|
20
|
+
|
|
3
21
|
## 20.1.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
package/dist/cjs/version.json
CHANGED
|
@@ -17,11 +17,13 @@ var _tokens = require("@atlaskit/tokens");
|
|
|
17
17
|
|
|
18
18
|
var _templateObject, _templateObject2;
|
|
19
19
|
|
|
20
|
-
var animationNameStyles = (0, _core.keyframes)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n 0% { background-position: -20px 0; }\n 100% { background-position: 20px 0; }\n"])));
|
|
21
|
-
var styles = (0, _core.css)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\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"])), (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);
|
|
22
|
-
|
|
23
20
|
var LoadingSkeleton = function LoadingSkeleton(_ref) {
|
|
24
|
-
var testId = _ref.testId
|
|
21
|
+
var testId = _ref.testId,
|
|
22
|
+
width = _ref.width,
|
|
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);
|
|
26
|
+
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);
|
|
25
27
|
return (0, _core.jsx)("span", {
|
|
26
28
|
css: styles,
|
|
27
29
|
"data-testid": testId
|
|
@@ -54,6 +54,12 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
54
54
|
var fadeOutTimeoutId = (0, _react.useRef)();
|
|
55
55
|
var fadeInTimeoutId = (0, _react.useRef)();
|
|
56
56
|
var cardOpenTime = (0, _react.useRef)();
|
|
57
|
+
var mousePos = (0, _react.useRef)({
|
|
58
|
+
x: 0,
|
|
59
|
+
y: 0
|
|
60
|
+
});
|
|
61
|
+
var popupOffset = (0, _react.useRef)();
|
|
62
|
+
var parentSpan = (0, _react.useRef)(null);
|
|
57
63
|
var renderers = (0, _renderers.useSmartLinkRenderers)();
|
|
58
64
|
var linkState = (0, _store.useSmartCardState)(url);
|
|
59
65
|
var hoverDisplay = 'card';
|
|
@@ -88,6 +94,14 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
88
94
|
analytics.ui.hoverCardViewedEvent(hoverDisplay, invokeMethod);
|
|
89
95
|
}
|
|
90
96
|
|
|
97
|
+
if (parentSpan.current) {
|
|
98
|
+
var _parentSpan$current$g = parentSpan.current.getBoundingClientRect(),
|
|
99
|
+
bottom = _parentSpan$current$g.bottom,
|
|
100
|
+
left = _parentSpan$current$g.left;
|
|
101
|
+
|
|
102
|
+
popupOffset.current = [mousePos.current.x - left, mousePos.current.y - bottom + _styled.CARD_GAP_PX];
|
|
103
|
+
}
|
|
104
|
+
|
|
91
105
|
setIsOpen(true);
|
|
92
106
|
}, delay);
|
|
93
107
|
}, [delay, isOpen, analytics.ui]);
|
|
@@ -100,7 +114,17 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
100
114
|
if (actionId === 'preview-content') {
|
|
101
115
|
hideCard();
|
|
102
116
|
}
|
|
103
|
-
}, [hideCard]);
|
|
117
|
+
}, [hideCard]);
|
|
118
|
+
var setMousePosition = (0, _react.useCallback)(function (event) {
|
|
119
|
+
if (isOpen) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
mousePos.current = {
|
|
124
|
+
x: event.clientX,
|
|
125
|
+
y: event.clientY
|
|
126
|
+
};
|
|
127
|
+
}, [isOpen]); // Stop hover preview content to propagate event to parent.
|
|
104
128
|
|
|
105
129
|
var onClick = (0, _react.useCallback)(function (e) {
|
|
106
130
|
return e.stopPropagation();
|
|
@@ -110,6 +134,7 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
110
134
|
isOpen: isOpen,
|
|
111
135
|
onClose: hideCard,
|
|
112
136
|
placement: "bottom-start",
|
|
137
|
+
offset: popupOffset.current,
|
|
113
138
|
content: function content(_ref2) {
|
|
114
139
|
var update = _ref2.update;
|
|
115
140
|
return (0, _core.jsx)("div", {
|
|
@@ -130,10 +155,13 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
130
155
|
}));
|
|
131
156
|
},
|
|
132
157
|
trigger: function trigger(triggerProps) {
|
|
133
|
-
return (0, _core.jsx)("span",
|
|
158
|
+
return (0, _core.jsx)("span", {
|
|
159
|
+
ref: parentSpan
|
|
160
|
+
}, (0, _core.jsx)("span", (0, _extends2.default)({}, triggerProps, {
|
|
134
161
|
onMouseEnter: initShowCard,
|
|
135
|
-
onMouseLeave: initHideCard
|
|
136
|
-
|
|
162
|
+
onMouseLeave: initHideCard,
|
|
163
|
+
onMouseMove: setMousePosition
|
|
164
|
+
}), children));
|
|
137
165
|
},
|
|
138
166
|
zIndex: 511 // Temporary fix for Confluence inline comment on editor mod has z-index of 500, Jira issue view has z-index of 510
|
|
139
167
|
|
|
@@ -35,6 +35,8 @@ var _styled = require("../styled");
|
|
|
35
35
|
|
|
36
36
|
var _utils2 = require("../utils");
|
|
37
37
|
|
|
38
|
+
var _HoverCardLoadingView = _interopRequireDefault(require("./HoverCardLoadingView"));
|
|
39
|
+
|
|
38
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); }
|
|
39
41
|
|
|
40
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; }
|
|
@@ -125,21 +127,33 @@ var HoverCardContent = function HoverCardContent(_ref) {
|
|
|
125
127
|
|
|
126
128
|
var titleMaxLines = subtitle && subtitle.length > 0 ? 1 : 2;
|
|
127
129
|
var body = data && (0, _extractPreview.default)(data) ? /*#__PURE__*/_react.default.createElement(_blocks.PreviewBlock, null) : /*#__PURE__*/_react.default.createElement(_blocks.SnippetBlock, null);
|
|
128
|
-
|
|
129
|
-
cardState: cardState,
|
|
130
|
-
onClick: onClick,
|
|
131
|
-
onResolve: onResolve,
|
|
132
|
-
renderers: renderers,
|
|
133
|
-
ui: _styled.flexibleUiOptions,
|
|
134
|
-
url: url
|
|
135
|
-
}, /*#__PURE__*/_react.default.createElement(_blocks.TitleBlock, {
|
|
130
|
+
var titleBlockProps = {
|
|
136
131
|
actions: titleActions,
|
|
137
132
|
maxLines: titleMaxLines,
|
|
138
133
|
overrideCss: _styled.titleBlockCss,
|
|
139
134
|
size: _constants.SmartLinkSize.Large,
|
|
140
135
|
position: _constants.SmartLinkPosition.Center,
|
|
141
136
|
subtitle: subtitle
|
|
142
|
-
}
|
|
137
|
+
};
|
|
138
|
+
var flexibleCardProps = {
|
|
139
|
+
cardState: cardState,
|
|
140
|
+
onClick: onClick,
|
|
141
|
+
onResolve: onResolve,
|
|
142
|
+
renderers: renderers,
|
|
143
|
+
ui: _styled.flexibleUiOptions,
|
|
144
|
+
url: url,
|
|
145
|
+
children: {}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
if (cardState.metadataStatus === 'pending') {
|
|
149
|
+
return /*#__PURE__*/_react.default.createElement(_HoverCardLoadingView.default, {
|
|
150
|
+
flexibleCardProps: flexibleCardProps,
|
|
151
|
+
titleBlockProps: titleBlockProps
|
|
152
|
+
});
|
|
153
|
+
} // if metadataStatus is 'errored' simply render using data available (normal path)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
return /*#__PURE__*/_react.default.createElement(_FlexibleCard.default, flexibleCardProps, /*#__PURE__*/_react.default.createElement(_blocks.TitleBlock, titleBlockProps), /*#__PURE__*/_react.default.createElement(_blocks.MetadataBlock, {
|
|
143
157
|
primary: primary,
|
|
144
158
|
secondary: secondary,
|
|
145
159
|
size: _constants.SmartLinkSize.Large,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = void 0;
|
|
9
|
+
|
|
10
|
+
var _core = require("@emotion/core");
|
|
11
|
+
|
|
12
|
+
var _react = _interopRequireDefault(require("react"));
|
|
13
|
+
|
|
14
|
+
var _loadingSkeleton = _interopRequireDefault(require("../../FlexibleCard/components/common/loading-skeleton"));
|
|
15
|
+
|
|
16
|
+
var _FlexibleCard = _interopRequireDefault(require("../../FlexibleCard"));
|
|
17
|
+
|
|
18
|
+
var _blocks = require("../../FlexibleCard/components/blocks");
|
|
19
|
+
|
|
20
|
+
var _styled = require("../styled");
|
|
21
|
+
|
|
22
|
+
/** @jsx jsx */
|
|
23
|
+
var HoverCardLoadingView = function HoverCardLoadingView(_ref) {
|
|
24
|
+
var flexibleCardProps = _ref.flexibleCardProps,
|
|
25
|
+
titleBlockProps = _ref.titleBlockProps;
|
|
26
|
+
var lineHeightRem = 1.25;
|
|
27
|
+
var skeletonWidth = _styled.CARD_WIDTH_REM - 2;
|
|
28
|
+
return (0, _core.jsx)("div", {
|
|
29
|
+
css: _styled.loadingViewContainer,
|
|
30
|
+
"data-testid": "hover-card-loading-view"
|
|
31
|
+
}, (0, _core.jsx)(_FlexibleCard.default, flexibleCardProps, (0, _core.jsx)(_blocks.TitleBlock, titleBlockProps)), (0, _core.jsx)("div", {
|
|
32
|
+
css: _styled.skeletonContainer
|
|
33
|
+
}, (0, _core.jsx)("span", null), (0, _core.jsx)(_loadingSkeleton.default, {
|
|
34
|
+
width: skeletonWidth,
|
|
35
|
+
height: lineHeightRem
|
|
36
|
+
}), (0, _core.jsx)(_loadingSkeleton.default, {
|
|
37
|
+
width: skeletonWidth,
|
|
38
|
+
height: lineHeightRem * 3
|
|
39
|
+
}), (0, _core.jsx)(_loadingSkeleton.default, {
|
|
40
|
+
width: skeletonWidth,
|
|
41
|
+
height: lineHeightRem
|
|
42
|
+
})));
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
var _default = HoverCardLoadingView;
|
|
46
|
+
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.metadataBlockCss = exports.footerBlockCss = exports.flexibleUiOptions = exports.HoverCardContainer = void 0;
|
|
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;
|
|
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;
|
|
18
|
+
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
|
|
19
19
|
|
|
20
20
|
var flexibleUiOptions = {
|
|
21
21
|
hideElevation: true,
|
|
@@ -25,14 +25,23 @@ var flexibleUiOptions = {
|
|
|
25
25
|
hidePadding: true
|
|
26
26
|
};
|
|
27
27
|
exports.flexibleUiOptions = flexibleUiOptions;
|
|
28
|
+
var CARD_WIDTH_REM = 24; // gap between mouse cursor and hover card
|
|
29
|
+
|
|
30
|
+
exports.CARD_WIDTH_REM = CARD_WIDTH_REM;
|
|
31
|
+
var CARD_GAP_PX = 10;
|
|
32
|
+
exports.CARD_GAP_PX = CARD_GAP_PX;
|
|
28
33
|
var blockGap = '0.5rem';
|
|
29
34
|
var elementGap = '0.5rem';
|
|
30
35
|
var separatorCss = (0, _core.css)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n [data-separator] + [data-separator]:before {\n margin-right: ", ";\n }\n"])), elementGap);
|
|
31
|
-
var HoverCardContainer = (0, _core.css)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\n background: none;\n border-width: 0;\n box-sizing: border-box;\n width:
|
|
36
|
+
var HoverCardContainer = (0, _core.css)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\n background: none;\n border-width: 0;\n box-sizing: border-box;\n width: ", "rem;\n padding: 1rem;\n\n .", " {\n display: none;\n }\n"])), CARD_WIDTH_REM, _index.loadingPlaceholderClassName);
|
|
32
37
|
exports.HoverCardContainer = HoverCardContainer;
|
|
33
38
|
var titleBlockCss = (0, _core.css)(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2.default)(["\n gap: ", ";\n\n ", "\n\n // title and subtitle element group\n [data-smart-element-group] {\n // gap between title and subtitle\n gap: 0.06rem;\n\n /* subtitle element group */\n > [data-smart-element-group] {\n > span {\n margin-right: ", ";\n }\n }\n }\n"])), blockGap, separatorCss, elementGap);
|
|
34
39
|
exports.titleBlockCss = titleBlockCss;
|
|
35
40
|
var metadataBlockCss = (0, _core.css)(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2.default)(["\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);
|
|
36
41
|
exports.metadataBlockCss = metadataBlockCss;
|
|
37
42
|
var footerBlockCss = (0, _core.css)(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2.default)(["\n padding-top: 0.25rem;\n"])));
|
|
38
|
-
exports.footerBlockCss = footerBlockCss;
|
|
43
|
+
exports.footerBlockCss = footerBlockCss;
|
|
44
|
+
var loadingViewContainer = (0, _core.css)(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n flex-direction: column;\n"])));
|
|
45
|
+
exports.loadingViewContainer = loadingViewContainer;
|
|
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;
|
package/dist/es2019/version.json
CHANGED
|
@@ -2,38 +2,45 @@
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { css, jsx, keyframes } from '@emotion/core';
|
|
4
4
|
import { token } from '@atlaskit/tokens';
|
|
5
|
-
const animationNameStyles = keyframes`
|
|
6
|
-
0% { background-position: -20px 0; }
|
|
7
|
-
100% { background-position: 20px 0; }
|
|
8
|
-
`;
|
|
9
|
-
const styles = css`
|
|
10
|
-
border-radius: 2px;
|
|
11
|
-
user-select: none;
|
|
12
|
-
background: ${token('color.skeleton.subtle', '#f6f7f8')};
|
|
13
|
-
// TODO: https://product-fabric.atlassian.net/browse/DSP-4236
|
|
14
|
-
background-image: linear-gradient(
|
|
15
|
-
to right,
|
|
16
|
-
${token('color.skeleton.subtle', '#f6f7f8')} 0%,
|
|
17
|
-
${token('color.skeleton', '#edeef1')} 20%,
|
|
18
|
-
${token('color.skeleton.subtle', '#f6f7f8')} 40%,
|
|
19
|
-
${token('color.skeleton.subtle', '#f6f7f8')}100%
|
|
20
|
-
);
|
|
21
|
-
background-repeat: no-repeat;
|
|
22
|
-
background-size: 280% 100%;
|
|
23
|
-
display: inline-block;
|
|
24
|
-
|
|
25
|
-
animation-duration: 1s;
|
|
26
|
-
animation-fill-mode: forwards;
|
|
27
|
-
animation-iteration-count: infinite;
|
|
28
|
-
animation-name: ${animationNameStyles};
|
|
29
|
-
animation-timing-function: linear;
|
|
30
|
-
`;
|
|
31
5
|
|
|
32
6
|
const LoadingSkeleton = ({
|
|
33
|
-
testId
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
7
|
+
testId,
|
|
8
|
+
width,
|
|
9
|
+
height
|
|
10
|
+
}) => {
|
|
11
|
+
const animationWidth = width ? `${width}rem` : '20px';
|
|
12
|
+
const animationNameStyles = keyframes`
|
|
13
|
+
0% { background-position: -${animationWidth} 0; }
|
|
14
|
+
100% { background-position: ${animationWidth} 0; }
|
|
15
|
+
`;
|
|
16
|
+
const styles = css`
|
|
17
|
+
width: ${width}rem;
|
|
18
|
+
height: ${height}rem;
|
|
19
|
+
border-radius: 2px;
|
|
20
|
+
user-select: none;
|
|
21
|
+
background: ${token('color.skeleton.subtle', '#f6f7f8')};
|
|
22
|
+
// TODO: https://product-fabric.atlassian.net/browse/DSP-4236
|
|
23
|
+
background-image: linear-gradient(
|
|
24
|
+
to right,
|
|
25
|
+
${token('color.skeleton.subtle', '#f6f7f8')} 0%,
|
|
26
|
+
${token('color.skeleton', '#edeef1')} 20%,
|
|
27
|
+
${token('color.skeleton.subtle', '#f6f7f8')} 40%,
|
|
28
|
+
${token('color.skeleton.subtle', '#f6f7f8')}100%
|
|
29
|
+
);
|
|
30
|
+
background-repeat: no-repeat;
|
|
31
|
+
background-size: 280% 100%;
|
|
32
|
+
display: inline-block;
|
|
33
|
+
|
|
34
|
+
animation-duration: 1s;
|
|
35
|
+
animation-fill-mode: forwards;
|
|
36
|
+
animation-iteration-count: infinite;
|
|
37
|
+
animation-name: ${animationNameStyles};
|
|
38
|
+
animation-timing-function: linear;
|
|
39
|
+
`;
|
|
40
|
+
return jsx("span", {
|
|
41
|
+
css: styles,
|
|
42
|
+
"data-testid": testId
|
|
43
|
+
});
|
|
44
|
+
};
|
|
38
45
|
|
|
39
46
|
export default LoadingSkeleton;
|
|
@@ -8,7 +8,7 @@ import { useSmartLinkActions } from '../../../state/hooks-external/useSmartLinkA
|
|
|
8
8
|
import { useSmartLinkRenderers } from '../../../state/renderers';
|
|
9
9
|
import { useSmartCardState as useLinkState } from '../../../state/store';
|
|
10
10
|
import HoverCardContent from '../components/HoverCardContent';
|
|
11
|
-
import { HoverCardContainer } from '../styled';
|
|
11
|
+
import { HoverCardContainer, CARD_GAP_PX } from '../styled';
|
|
12
12
|
import { SMART_CARD_ANALYTICS_DISPLAY } from '../utils';
|
|
13
13
|
export const hoverCardClassName = 'smart-links-hover-preview';
|
|
14
14
|
export const HoverCardComponent = ({
|
|
@@ -22,6 +22,12 @@ export const HoverCardComponent = ({
|
|
|
22
22
|
const fadeOutTimeoutId = useRef();
|
|
23
23
|
const fadeInTimeoutId = useRef();
|
|
24
24
|
const cardOpenTime = useRef();
|
|
25
|
+
const mousePos = useRef({
|
|
26
|
+
x: 0,
|
|
27
|
+
y: 0
|
|
28
|
+
});
|
|
29
|
+
const popupOffset = useRef();
|
|
30
|
+
const parentSpan = useRef(null);
|
|
25
31
|
const renderers = useSmartLinkRenderers();
|
|
26
32
|
const linkState = useLinkState(url);
|
|
27
33
|
const hoverDisplay = 'card';
|
|
@@ -54,6 +60,14 @@ export const HoverCardComponent = ({
|
|
|
54
60
|
analytics.ui.hoverCardViewedEvent(hoverDisplay, invokeMethod);
|
|
55
61
|
}
|
|
56
62
|
|
|
63
|
+
if (parentSpan.current) {
|
|
64
|
+
const {
|
|
65
|
+
bottom,
|
|
66
|
+
left
|
|
67
|
+
} = parentSpan.current.getBoundingClientRect();
|
|
68
|
+
popupOffset.current = [mousePos.current.x - left, mousePos.current.y - bottom + CARD_GAP_PX];
|
|
69
|
+
}
|
|
70
|
+
|
|
57
71
|
setIsOpen(true);
|
|
58
72
|
}, delay);
|
|
59
73
|
}, [delay, isOpen, analytics.ui]);
|
|
@@ -66,7 +80,17 @@ export const HoverCardComponent = ({
|
|
|
66
80
|
if (actionId === 'preview-content') {
|
|
67
81
|
hideCard();
|
|
68
82
|
}
|
|
69
|
-
}, [hideCard]);
|
|
83
|
+
}, [hideCard]);
|
|
84
|
+
const setMousePosition = useCallback(event => {
|
|
85
|
+
if (isOpen) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
mousePos.current = {
|
|
90
|
+
x: event.clientX,
|
|
91
|
+
y: event.clientY
|
|
92
|
+
};
|
|
93
|
+
}, [isOpen]); // Stop hover preview content to propagate event to parent.
|
|
70
94
|
|
|
71
95
|
const onClick = useCallback(e => e.stopPropagation(), []);
|
|
72
96
|
return jsx(Popup, {
|
|
@@ -74,6 +98,7 @@ export const HoverCardComponent = ({
|
|
|
74
98
|
isOpen: isOpen,
|
|
75
99
|
onClose: hideCard,
|
|
76
100
|
placement: "bottom-start",
|
|
101
|
+
offset: popupOffset.current,
|
|
77
102
|
content: ({
|
|
78
103
|
update
|
|
79
104
|
}) => jsx("div", {
|
|
@@ -92,10 +117,13 @@ export const HoverCardComponent = ({
|
|
|
92
117
|
renderers: renderers,
|
|
93
118
|
url: url
|
|
94
119
|
})),
|
|
95
|
-
trigger: triggerProps => jsx("span",
|
|
120
|
+
trigger: triggerProps => jsx("span", {
|
|
121
|
+
ref: parentSpan
|
|
122
|
+
}, jsx("span", _extends({}, triggerProps, {
|
|
96
123
|
onMouseEnter: initShowCard,
|
|
97
|
-
onMouseLeave: initHideCard
|
|
98
|
-
|
|
124
|
+
onMouseLeave: initHideCard,
|
|
125
|
+
onMouseMove: setMousePosition
|
|
126
|
+
}), children)),
|
|
99
127
|
zIndex: 511 // Temporary fix for Confluence inline comment on editor mod has z-index of 500, Jira issue view has z-index of 510
|
|
100
128
|
|
|
101
129
|
});
|
|
@@ -11,6 +11,7 @@ import FlexibleCard from '../../FlexibleCard';
|
|
|
11
11
|
import { FooterBlock, MetadataBlock, PreviewBlock, SnippetBlock, TitleBlock } from '../../FlexibleCard/components/blocks';
|
|
12
12
|
import { flexibleUiOptions, footerBlockCss, metadataBlockCss, titleBlockCss } from '../styled';
|
|
13
13
|
import { getSimulatedMetadata, SMART_CARD_ANALYTICS_DISPLAY } from '../utils';
|
|
14
|
+
import HoverCardLoadingView from './HoverCardLoadingView';
|
|
14
15
|
export const getOpenAction = (url, analytics, onActionClick) => ({
|
|
15
16
|
name: ActionName.CustomAction,
|
|
16
17
|
icon: /*#__PURE__*/React.createElement(ShortcutIcon, {
|
|
@@ -79,21 +80,33 @@ const HoverCardContent = ({
|
|
|
79
80
|
} = extractMetadata(getSimulatedMetadata(extensionKey, types));
|
|
80
81
|
const titleMaxLines = subtitle && subtitle.length > 0 ? 1 : 2;
|
|
81
82
|
const body = data && extractPreview(data) ? /*#__PURE__*/React.createElement(PreviewBlock, null) : /*#__PURE__*/React.createElement(SnippetBlock, null);
|
|
82
|
-
|
|
83
|
-
cardState: cardState,
|
|
84
|
-
onClick: onClick,
|
|
85
|
-
onResolve: onResolve,
|
|
86
|
-
renderers: renderers,
|
|
87
|
-
ui: flexibleUiOptions,
|
|
88
|
-
url: url
|
|
89
|
-
}, /*#__PURE__*/React.createElement(TitleBlock, {
|
|
83
|
+
const titleBlockProps = {
|
|
90
84
|
actions: titleActions,
|
|
91
85
|
maxLines: titleMaxLines,
|
|
92
86
|
overrideCss: titleBlockCss,
|
|
93
87
|
size: SmartLinkSize.Large,
|
|
94
88
|
position: SmartLinkPosition.Center,
|
|
95
89
|
subtitle: subtitle
|
|
96
|
-
}
|
|
90
|
+
};
|
|
91
|
+
const flexibleCardProps = {
|
|
92
|
+
cardState: cardState,
|
|
93
|
+
onClick: onClick,
|
|
94
|
+
onResolve: onResolve,
|
|
95
|
+
renderers: renderers,
|
|
96
|
+
ui: flexibleUiOptions,
|
|
97
|
+
url: url,
|
|
98
|
+
children: {}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
if (cardState.metadataStatus === 'pending') {
|
|
102
|
+
return /*#__PURE__*/React.createElement(HoverCardLoadingView, {
|
|
103
|
+
flexibleCardProps: flexibleCardProps,
|
|
104
|
+
titleBlockProps: titleBlockProps
|
|
105
|
+
});
|
|
106
|
+
} // if metadataStatus is 'errored' simply render using data available (normal path)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
return /*#__PURE__*/React.createElement(FlexibleCard, flexibleCardProps, /*#__PURE__*/React.createElement(TitleBlock, titleBlockProps), /*#__PURE__*/React.createElement(MetadataBlock, {
|
|
97
110
|
primary: primary,
|
|
98
111
|
secondary: secondary,
|
|
99
112
|
size: SmartLinkSize.Large,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { jsx } from '@emotion/core';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import LoadingSkeleton from '../../FlexibleCard/components/common/loading-skeleton';
|
|
5
|
+
import FlexibleCard from '../../FlexibleCard';
|
|
6
|
+
import { TitleBlock } from '../../FlexibleCard/components/blocks';
|
|
7
|
+
import { CARD_WIDTH_REM, loadingViewContainer, skeletonContainer } from '../styled';
|
|
8
|
+
|
|
9
|
+
const HoverCardLoadingView = ({
|
|
10
|
+
flexibleCardProps,
|
|
11
|
+
titleBlockProps
|
|
12
|
+
}) => {
|
|
13
|
+
const lineHeightRem = 1.25;
|
|
14
|
+
const skeletonWidth = CARD_WIDTH_REM - 2;
|
|
15
|
+
return jsx("div", {
|
|
16
|
+
css: loadingViewContainer,
|
|
17
|
+
"data-testid": "hover-card-loading-view"
|
|
18
|
+
}, jsx(FlexibleCard, flexibleCardProps, jsx(TitleBlock, titleBlockProps)), jsx("div", {
|
|
19
|
+
css: skeletonContainer
|
|
20
|
+
}, jsx("span", null), jsx(LoadingSkeleton, {
|
|
21
|
+
width: skeletonWidth,
|
|
22
|
+
height: lineHeightRem
|
|
23
|
+
}), jsx(LoadingSkeleton, {
|
|
24
|
+
width: skeletonWidth,
|
|
25
|
+
height: lineHeightRem * 3
|
|
26
|
+
}), jsx(LoadingSkeleton, {
|
|
27
|
+
width: skeletonWidth,
|
|
28
|
+
height: lineHeightRem
|
|
29
|
+
})));
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default HoverCardLoadingView;
|
|
@@ -8,6 +8,9 @@ export const flexibleUiOptions = {
|
|
|
8
8
|
theme: SmartLinkTheme.Black,
|
|
9
9
|
hidePadding: true
|
|
10
10
|
};
|
|
11
|
+
export const CARD_WIDTH_REM = 24; // gap between mouse cursor and hover card
|
|
12
|
+
|
|
13
|
+
export const CARD_GAP_PX = 10;
|
|
11
14
|
const blockGap = '0.5rem';
|
|
12
15
|
const elementGap = '0.5rem';
|
|
13
16
|
const separatorCss = css`
|
|
@@ -19,7 +22,7 @@ export const HoverCardContainer = css`
|
|
|
19
22
|
background: none;
|
|
20
23
|
border-width: 0;
|
|
21
24
|
box-sizing: border-box;
|
|
22
|
-
width:
|
|
25
|
+
width: ${CARD_WIDTH_REM}rem;
|
|
23
26
|
padding: 1rem;
|
|
24
27
|
|
|
25
28
|
.${loadingPlaceholderClassName} {
|
|
@@ -70,4 +73,14 @@ export const metadataBlockCss = css`
|
|
|
70
73
|
`;
|
|
71
74
|
export const footerBlockCss = css`
|
|
72
75
|
padding-top: 0.25rem;
|
|
76
|
+
`;
|
|
77
|
+
export const loadingViewContainer = css`
|
|
78
|
+
display: flex;
|
|
79
|
+
flex-direction: column;
|
|
80
|
+
`;
|
|
81
|
+
export const skeletonContainer = css`
|
|
82
|
+
display: flex;
|
|
83
|
+
flex-direction: column;
|
|
84
|
+
gap: 0.625rem;
|
|
85
|
+
align-items: center;
|
|
73
86
|
`;
|
package/dist/esm/version.json
CHANGED
|
@@ -6,11 +6,14 @@ var _templateObject, _templateObject2;
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import { css, jsx, keyframes } from '@emotion/core';
|
|
8
8
|
import { token } from '@atlaskit/tokens';
|
|
9
|
-
var animationNameStyles = keyframes(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n 0% { background-position: -20px 0; }\n 100% { background-position: 20px 0; }\n"])));
|
|
10
|
-
var styles = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\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"])), 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);
|
|
11
9
|
|
|
12
10
|
var LoadingSkeleton = function LoadingSkeleton(_ref) {
|
|
13
|
-
var testId = _ref.testId
|
|
11
|
+
var testId = _ref.testId,
|
|
12
|
+
width = _ref.width,
|
|
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);
|
|
16
|
+
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);
|
|
14
17
|
return jsx("span", {
|
|
15
18
|
css: styles,
|
|
16
19
|
"data-testid": testId
|
|
@@ -9,7 +9,7 @@ import { useSmartLinkActions } from '../../../state/hooks-external/useSmartLinkA
|
|
|
9
9
|
import { useSmartLinkRenderers } from '../../../state/renderers';
|
|
10
10
|
import { useSmartCardState as useLinkState } from '../../../state/store';
|
|
11
11
|
import HoverCardContent from '../components/HoverCardContent';
|
|
12
|
-
import { HoverCardContainer } from '../styled';
|
|
12
|
+
import { HoverCardContainer, CARD_GAP_PX } from '../styled';
|
|
13
13
|
import { SMART_CARD_ANALYTICS_DISPLAY } from '../utils';
|
|
14
14
|
export var hoverCardClassName = 'smart-links-hover-preview';
|
|
15
15
|
export var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
@@ -27,6 +27,12 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
27
27
|
var fadeOutTimeoutId = useRef();
|
|
28
28
|
var fadeInTimeoutId = useRef();
|
|
29
29
|
var cardOpenTime = useRef();
|
|
30
|
+
var mousePos = useRef({
|
|
31
|
+
x: 0,
|
|
32
|
+
y: 0
|
|
33
|
+
});
|
|
34
|
+
var popupOffset = useRef();
|
|
35
|
+
var parentSpan = useRef(null);
|
|
30
36
|
var renderers = useSmartLinkRenderers();
|
|
31
37
|
var linkState = useLinkState(url);
|
|
32
38
|
var hoverDisplay = 'card';
|
|
@@ -61,6 +67,14 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
61
67
|
analytics.ui.hoverCardViewedEvent(hoverDisplay, invokeMethod);
|
|
62
68
|
}
|
|
63
69
|
|
|
70
|
+
if (parentSpan.current) {
|
|
71
|
+
var _parentSpan$current$g = parentSpan.current.getBoundingClientRect(),
|
|
72
|
+
bottom = _parentSpan$current$g.bottom,
|
|
73
|
+
left = _parentSpan$current$g.left;
|
|
74
|
+
|
|
75
|
+
popupOffset.current = [mousePos.current.x - left, mousePos.current.y - bottom + CARD_GAP_PX];
|
|
76
|
+
}
|
|
77
|
+
|
|
64
78
|
setIsOpen(true);
|
|
65
79
|
}, delay);
|
|
66
80
|
}, [delay, isOpen, analytics.ui]);
|
|
@@ -73,7 +87,17 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
73
87
|
if (actionId === 'preview-content') {
|
|
74
88
|
hideCard();
|
|
75
89
|
}
|
|
76
|
-
}, [hideCard]);
|
|
90
|
+
}, [hideCard]);
|
|
91
|
+
var setMousePosition = useCallback(function (event) {
|
|
92
|
+
if (isOpen) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
mousePos.current = {
|
|
97
|
+
x: event.clientX,
|
|
98
|
+
y: event.clientY
|
|
99
|
+
};
|
|
100
|
+
}, [isOpen]); // Stop hover preview content to propagate event to parent.
|
|
77
101
|
|
|
78
102
|
var onClick = useCallback(function (e) {
|
|
79
103
|
return e.stopPropagation();
|
|
@@ -83,6 +107,7 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
83
107
|
isOpen: isOpen,
|
|
84
108
|
onClose: hideCard,
|
|
85
109
|
placement: "bottom-start",
|
|
110
|
+
offset: popupOffset.current,
|
|
86
111
|
content: function content(_ref2) {
|
|
87
112
|
var update = _ref2.update;
|
|
88
113
|
return jsx("div", {
|
|
@@ -103,10 +128,13 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
|
|
|
103
128
|
}));
|
|
104
129
|
},
|
|
105
130
|
trigger: function trigger(triggerProps) {
|
|
106
|
-
return jsx("span",
|
|
131
|
+
return jsx("span", {
|
|
132
|
+
ref: parentSpan
|
|
133
|
+
}, jsx("span", _extends({}, triggerProps, {
|
|
107
134
|
onMouseEnter: initShowCard,
|
|
108
|
-
onMouseLeave: initHideCard
|
|
109
|
-
|
|
135
|
+
onMouseLeave: initHideCard,
|
|
136
|
+
onMouseMove: setMousePosition
|
|
137
|
+
}), children));
|
|
110
138
|
},
|
|
111
139
|
zIndex: 511 // Temporary fix for Confluence inline comment on editor mod has z-index of 500, Jira issue view has z-index of 510
|
|
112
140
|
|
|
@@ -11,6 +11,7 @@ import FlexibleCard from '../../FlexibleCard';
|
|
|
11
11
|
import { FooterBlock, MetadataBlock, PreviewBlock, SnippetBlock, TitleBlock } from '../../FlexibleCard/components/blocks';
|
|
12
12
|
import { flexibleUiOptions, footerBlockCss, metadataBlockCss, titleBlockCss } from '../styled';
|
|
13
13
|
import { getSimulatedMetadata, SMART_CARD_ANALYTICS_DISPLAY } from '../utils';
|
|
14
|
+
import HoverCardLoadingView from './HoverCardLoadingView';
|
|
14
15
|
export var getOpenAction = function getOpenAction(url, analytics, onActionClick) {
|
|
15
16
|
return {
|
|
16
17
|
name: ActionName.CustomAction,
|
|
@@ -92,21 +93,33 @@ var HoverCardContent = function HoverCardContent(_ref) {
|
|
|
92
93
|
|
|
93
94
|
var titleMaxLines = subtitle && subtitle.length > 0 ? 1 : 2;
|
|
94
95
|
var body = data && extractPreview(data) ? /*#__PURE__*/React.createElement(PreviewBlock, null) : /*#__PURE__*/React.createElement(SnippetBlock, null);
|
|
95
|
-
|
|
96
|
-
cardState: cardState,
|
|
97
|
-
onClick: onClick,
|
|
98
|
-
onResolve: onResolve,
|
|
99
|
-
renderers: renderers,
|
|
100
|
-
ui: flexibleUiOptions,
|
|
101
|
-
url: url
|
|
102
|
-
}, /*#__PURE__*/React.createElement(TitleBlock, {
|
|
96
|
+
var titleBlockProps = {
|
|
103
97
|
actions: titleActions,
|
|
104
98
|
maxLines: titleMaxLines,
|
|
105
99
|
overrideCss: titleBlockCss,
|
|
106
100
|
size: SmartLinkSize.Large,
|
|
107
101
|
position: SmartLinkPosition.Center,
|
|
108
102
|
subtitle: subtitle
|
|
109
|
-
}
|
|
103
|
+
};
|
|
104
|
+
var flexibleCardProps = {
|
|
105
|
+
cardState: cardState,
|
|
106
|
+
onClick: onClick,
|
|
107
|
+
onResolve: onResolve,
|
|
108
|
+
renderers: renderers,
|
|
109
|
+
ui: flexibleUiOptions,
|
|
110
|
+
url: url,
|
|
111
|
+
children: {}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
if (cardState.metadataStatus === 'pending') {
|
|
115
|
+
return /*#__PURE__*/React.createElement(HoverCardLoadingView, {
|
|
116
|
+
flexibleCardProps: flexibleCardProps,
|
|
117
|
+
titleBlockProps: titleBlockProps
|
|
118
|
+
});
|
|
119
|
+
} // if metadataStatus is 'errored' simply render using data available (normal path)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
return /*#__PURE__*/React.createElement(FlexibleCard, flexibleCardProps, /*#__PURE__*/React.createElement(TitleBlock, titleBlockProps), /*#__PURE__*/React.createElement(MetadataBlock, {
|
|
110
123
|
primary: primary,
|
|
111
124
|
secondary: secondary,
|
|
112
125
|
size: SmartLinkSize.Large,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { jsx } from '@emotion/core';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import LoadingSkeleton from '../../FlexibleCard/components/common/loading-skeleton';
|
|
5
|
+
import FlexibleCard from '../../FlexibleCard';
|
|
6
|
+
import { TitleBlock } from '../../FlexibleCard/components/blocks';
|
|
7
|
+
import { CARD_WIDTH_REM, loadingViewContainer, skeletonContainer } from '../styled';
|
|
8
|
+
|
|
9
|
+
var HoverCardLoadingView = function HoverCardLoadingView(_ref) {
|
|
10
|
+
var flexibleCardProps = _ref.flexibleCardProps,
|
|
11
|
+
titleBlockProps = _ref.titleBlockProps;
|
|
12
|
+
var lineHeightRem = 1.25;
|
|
13
|
+
var skeletonWidth = CARD_WIDTH_REM - 2;
|
|
14
|
+
return jsx("div", {
|
|
15
|
+
css: loadingViewContainer,
|
|
16
|
+
"data-testid": "hover-card-loading-view"
|
|
17
|
+
}, jsx(FlexibleCard, flexibleCardProps, jsx(TitleBlock, titleBlockProps)), jsx("div", {
|
|
18
|
+
css: skeletonContainer
|
|
19
|
+
}, jsx("span", null), jsx(LoadingSkeleton, {
|
|
20
|
+
width: skeletonWidth,
|
|
21
|
+
height: lineHeightRem
|
|
22
|
+
}), jsx(LoadingSkeleton, {
|
|
23
|
+
width: skeletonWidth,
|
|
24
|
+
height: lineHeightRem * 3
|
|
25
|
+
}), jsx(LoadingSkeleton, {
|
|
26
|
+
width: skeletonWidth,
|
|
27
|
+
height: lineHeightRem
|
|
28
|
+
})));
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default HoverCardLoadingView;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
|
|
2
2
|
|
|
3
|
-
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5;
|
|
3
|
+
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
|
|
4
4
|
|
|
5
5
|
import { css } from '@emotion/core';
|
|
6
6
|
import { loadingPlaceholderClassName } from '../../index';
|
|
@@ -12,10 +12,15 @@ export var flexibleUiOptions = {
|
|
|
12
12
|
theme: SmartLinkTheme.Black,
|
|
13
13
|
hidePadding: true
|
|
14
14
|
};
|
|
15
|
+
export var CARD_WIDTH_REM = 24; // gap between mouse cursor and hover card
|
|
16
|
+
|
|
17
|
+
export var CARD_GAP_PX = 10;
|
|
15
18
|
var blockGap = '0.5rem';
|
|
16
19
|
var elementGap = '0.5rem';
|
|
17
20
|
var separatorCss = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n [data-separator] + [data-separator]:before {\n margin-right: ", ";\n }\n"])), elementGap);
|
|
18
|
-
export var HoverCardContainer = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n background: none;\n border-width: 0;\n box-sizing: border-box;\n width:
|
|
21
|
+
export var HoverCardContainer = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n background: none;\n border-width: 0;\n box-sizing: border-box;\n width: ", "rem;\n padding: 1rem;\n\n .", " {\n display: none;\n }\n"])), CARD_WIDTH_REM, loadingPlaceholderClassName);
|
|
19
22
|
export var titleBlockCss = css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n gap: ", ";\n\n ", "\n\n // title and subtitle element group\n [data-smart-element-group] {\n // gap between title and subtitle\n gap: 0.06rem;\n\n /* subtitle element group */\n > [data-smart-element-group] {\n > span {\n margin-right: ", ";\n }\n }\n }\n"])), blockGap, separatorCss, elementGap);
|
|
20
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);
|
|
21
|
-
export var footerBlockCss = css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n padding-top: 0.25rem;\n"])));
|
|
24
|
+
export var footerBlockCss = css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n padding-top: 0.25rem;\n"])));
|
|
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"])));
|
|
@@ -5,4 +5,12 @@ export declare type LoadingSkeletonProps = {
|
|
|
5
5
|
* code, serving as a hook for automated tests
|
|
6
6
|
*/
|
|
7
7
|
testId?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Width of the loading skeleton, defaults to width of the parent element
|
|
10
|
+
*/
|
|
11
|
+
width?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Height of loading skeleton, defaults to height of the parent element
|
|
14
|
+
*/
|
|
15
|
+
height?: number;
|
|
8
16
|
};
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { FlexibleUiOptions } from '../FlexibleCard/types';
|
|
2
2
|
export declare const flexibleUiOptions: FlexibleUiOptions;
|
|
3
|
+
export declare const CARD_WIDTH_REM = 24;
|
|
4
|
+
export declare const CARD_GAP_PX = 10;
|
|
3
5
|
export declare const HoverCardContainer: import("@emotion/utils").SerializedStyles;
|
|
4
6
|
export declare const titleBlockCss: import("@emotion/utils").SerializedStyles;
|
|
5
7
|
export declare const metadataBlockCss: import("@emotion/utils").SerializedStyles;
|
|
6
8
|
export declare const footerBlockCss: import("@emotion/utils").SerializedStyles;
|
|
9
|
+
export declare const loadingViewContainer: import("@emotion/utils").SerializedStyles;
|
|
10
|
+
export declare const skeletonContainer: import("@emotion/utils").SerializedStyles;
|
|
@@ -6,6 +6,8 @@ import { CardState } from '@atlaskit/linking-common';
|
|
|
6
6
|
import { CardProviderRenderers } from '@atlaskit/link-provider';
|
|
7
7
|
import { AnalyticsHandler } from '../../utils/types';
|
|
8
8
|
import { ReactElement } from 'react';
|
|
9
|
+
import { TitleBlockProps } from '../FlexibleCard/components/blocks/title-block/types';
|
|
10
|
+
import { FlexibleCardProps } from '../FlexibleCard/types';
|
|
9
11
|
export interface HoverCardProps extends WithAnalyticsEventsProps {
|
|
10
12
|
id?: string;
|
|
11
13
|
url: string;
|
|
@@ -32,3 +34,7 @@ export declare type HoverCardContentProps = {
|
|
|
32
34
|
onResolve: () => void;
|
|
33
35
|
url: string;
|
|
34
36
|
};
|
|
37
|
+
export declare type HoverCardLoadingViewProps = {
|
|
38
|
+
flexibleCardProps: FlexibleCardProps;
|
|
39
|
+
titleBlockProps: TitleBlockProps;
|
|
40
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/smart-card",
|
|
3
|
-
"version": "20.1.
|
|
3
|
+
"version": "20.1.3",
|
|
4
4
|
"description": "Smart card component",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"@atlaskit/docs": "*",
|
|
71
71
|
"@atlaskit/field-base": "^15.0.6",
|
|
72
72
|
"@atlaskit/form": "^8.5.0",
|
|
73
|
-
"@atlaskit/inline-message": "^11.
|
|
73
|
+
"@atlaskit/inline-message": "^11.3.0",
|
|
74
74
|
"@atlaskit/lozenge": "^11.1.0",
|
|
75
75
|
"@atlaskit/media-integration-test-helpers": "^2.6.0",
|
|
76
76
|
"@atlaskit/media-test-helpers": "^30.0.0",
|