@atlaskit/smart-card 17.7.6 → 17.7.9
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 +44 -0
- package/dist/cjs/hooks.js +13 -0
- package/dist/cjs/state/analytics/useSmartLinkAnalytics.js +2 -2
- package/dist/cjs/state/hooks-external/useSmartLinkActions.js +71 -0
- package/dist/cjs/utils/analytics/analytics.js +3 -2
- package/dist/cjs/utils/mocks.js +7 -1
- package/dist/cjs/version.json +1 -1
- package/dist/cjs/view/BlockCard/index.js +2 -2
- package/dist/cjs/view/CardWithUrl/component.js +12 -6
- package/dist/cjs/view/FlexibleCard/components/blocks/title-block/resolved/index.js +4 -2
- package/dist/cjs/view/FlexibleCard/components/container/index.js +5 -3
- package/dist/cjs/view/FlexibleCard/components/elements/link/index.js +3 -1
- package/dist/cjs/view/FlexibleCard/components/elements/media/index.js +12 -4
- package/dist/cjs/view/FlexibleCard/index.js +8 -3
- package/dist/es2019/hooks.js +1 -0
- package/dist/es2019/state/analytics/useSmartLinkAnalytics.js +1 -1
- package/dist/es2019/state/hooks-external/useSmartLinkActions.js +42 -0
- package/dist/es2019/utils/analytics/analytics.js +3 -2
- package/dist/es2019/utils/mocks.js +5 -0
- package/dist/es2019/version.json +1 -1
- package/dist/es2019/view/BlockCard/index.js +2 -2
- package/dist/es2019/view/CardWithUrl/component.js +11 -7
- package/dist/es2019/view/FlexibleCard/components/blocks/title-block/resolved/index.js +3 -1
- package/dist/es2019/view/FlexibleCard/components/container/index.js +5 -3
- package/dist/es2019/view/FlexibleCard/components/elements/link/index.js +3 -1
- package/dist/es2019/view/FlexibleCard/components/elements/media/index.js +37 -4
- package/dist/es2019/view/FlexibleCard/index.js +8 -3
- package/dist/esm/hooks.js +1 -0
- package/dist/esm/state/analytics/useSmartLinkAnalytics.js +2 -2
- package/dist/esm/state/hooks-external/useSmartLinkActions.js +54 -0
- package/dist/esm/utils/analytics/analytics.js +3 -2
- package/dist/esm/utils/mocks.js +5 -0
- package/dist/esm/version.json +1 -1
- package/dist/esm/view/BlockCard/index.js +2 -2
- package/dist/esm/view/CardWithUrl/component.js +13 -7
- package/dist/esm/view/FlexibleCard/components/blocks/title-block/resolved/index.js +4 -2
- package/dist/esm/view/FlexibleCard/components/container/index.js +5 -3
- package/dist/esm/view/FlexibleCard/components/elements/link/index.js +3 -1
- package/dist/esm/view/FlexibleCard/components/elements/media/index.js +12 -4
- package/dist/esm/view/FlexibleCard/index.js +8 -3
- package/dist/types/hooks.d.ts +1 -0
- package/dist/types/state/analytics/useSmartLinkAnalytics.d.ts +1 -1
- package/dist/types/state/hooks/useSmartLink.d.ts +1 -1
- package/dist/types/state/hooks-external/useSmartLinkActions.d.ts +45 -0
- package/dist/types/utils/analytics/analytics.d.ts +2 -2
- package/dist/types/utils/mocks.d.ts +5 -0
- package/dist/types/view/BlockCard/types.d.ts +1 -1
- package/dist/types/view/Card/types.d.ts +1 -1
- package/dist/types/view/FlexibleCard/components/blocks/title-block/types.d.ts +2 -0
- package/dist/types/view/FlexibleCard/components/container/types.d.ts +2 -0
- package/dist/types/view/FlexibleCard/components/elements/link/types.d.ts +2 -0
- package/dist/types/view/FlexibleCard/types.d.ts +1 -0
- package/hooks/package.json +7 -0
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# @atlaskit/smart-card
|
|
2
2
|
|
|
3
|
+
## 17.7.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`63d4f963f72`](https://bitbucket.org/atlassian/atlassian-frontend/commits/63d4f963f72) - Flexible UI: Set PreviewBlock image aspect ratio to 16:9
|
|
8
|
+
|
|
9
|
+
## 17.7.8
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`d75ce5b847d`](https://bitbucket.org/atlassian/atlassian-frontend/commits/d75ce5b847d) - Add link click analytics to flexible ui title block component
|
|
14
|
+
|
|
15
|
+
## 17.7.7
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [`c01f6404d0c`](https://bitbucket.org/atlassian/atlassian-frontend/commits/c01f6404d0c) - Add ability to trigger actions for a Smart Link from outside of the Smart Link card.
|
|
20
|
+
|
|
21
|
+
Example usage:
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { useSmartLinkActions } from '@atlaskit/smart-card/hooks';
|
|
25
|
+
|
|
26
|
+
const ExampleToolbar = () => {
|
|
27
|
+
const actions = useSmartLinkActions({
|
|
28
|
+
url,
|
|
29
|
+
appearance: 'block',
|
|
30
|
+
analyticsHandler: analytics,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<ExampleToolbarWrapper>
|
|
35
|
+
{actions.map((action) => (
|
|
36
|
+
<Tooltip content={action.text}>
|
|
37
|
+
<ExampleToolbarItem key={action.id} onClick={action.invoke}>
|
|
38
|
+
{idToIcon[action.id] ?? action.id}
|
|
39
|
+
</ExampleToolbarItem>
|
|
40
|
+
</Tooltip>
|
|
41
|
+
))}
|
|
42
|
+
</ExampleToolbarWrapper>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
```
|
|
46
|
+
|
|
3
47
|
## 17.7.6
|
|
4
48
|
|
|
5
49
|
### Patch Changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "useSmartLinkActions", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _useSmartLinkActions.useSmartLinkActions;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
var _useSmartLinkActions = require("./state/hooks-external/useSmartLinkActions");
|
|
@@ -20,8 +20,8 @@ var useSmartLinkAnalytics = function useSmartLinkAnalytics(dispatchAnalytics) {
|
|
|
20
20
|
authAlternateAccountEvent: function authAlternateAccountEvent(display, definitionId, extensionKey) {
|
|
21
21
|
return dispatchAnalytics((0, _analytics.uiAuthAlternateAccountEvent)(display, definitionId, extensionKey));
|
|
22
22
|
},
|
|
23
|
-
cardClickedEvent: function cardClickedEvent(display, definitionId, extensionKey) {
|
|
24
|
-
return dispatchAnalytics((0, _analytics.uiCardClickedEvent)(display, definitionId, extensionKey));
|
|
23
|
+
cardClickedEvent: function cardClickedEvent(display, definitionId, extensionKey, isModifierKeyPressed) {
|
|
24
|
+
return dispatchAnalytics((0, _analytics.uiCardClickedEvent)(display, definitionId, extensionKey, isModifierKeyPressed));
|
|
25
25
|
},
|
|
26
26
|
actionClickedEvent: function actionClickedEvent(id, extensionKey, actionType, display, invokeType) {
|
|
27
27
|
(0, _ufoExperiences.startUfoExperience)('smart-link-action-invocation', id, {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.useSmartLinkActions = useSmartLinkActions;
|
|
9
|
+
|
|
10
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
11
|
+
|
|
12
|
+
var _react = require("react");
|
|
13
|
+
|
|
14
|
+
var _uuid = _interopRequireDefault(require("uuid"));
|
|
15
|
+
|
|
16
|
+
var _block = require("../../extractors/block");
|
|
17
|
+
|
|
18
|
+
var _actions = require("../actions");
|
|
19
|
+
|
|
20
|
+
var _analytics = require("../analytics");
|
|
21
|
+
|
|
22
|
+
var _store = require("../store");
|
|
23
|
+
|
|
24
|
+
var _helpers = require("../helpers");
|
|
25
|
+
|
|
26
|
+
function useSmartLinkActions(_ref) {
|
|
27
|
+
var url = _ref.url,
|
|
28
|
+
appearance = _ref.appearance,
|
|
29
|
+
analyticsHandler = _ref.analyticsHandler,
|
|
30
|
+
_ref$platform = _ref.platform,
|
|
31
|
+
platform = _ref$platform === void 0 ? 'web' : _ref$platform;
|
|
32
|
+
var id = (0, _react.useMemo)(function () {
|
|
33
|
+
return (0, _uuid.default)();
|
|
34
|
+
}, []);
|
|
35
|
+
|
|
36
|
+
var _useState = (0, _react.useState)([]),
|
|
37
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
38
|
+
actions = _useState2[0],
|
|
39
|
+
setActions = _useState2[1];
|
|
40
|
+
|
|
41
|
+
var linkState = (0, _store.useSmartCardState)(url);
|
|
42
|
+
var linkAnalytics = (0, _analytics.useSmartLinkAnalytics)(analyticsHandler);
|
|
43
|
+
var linkActions = (0, _actions.useSmartCardActions)(id, url, linkAnalytics);
|
|
44
|
+
(0, _react.useEffect)(function () {
|
|
45
|
+
if (!linkState.details) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
var cardProperties = (0, _block.extractBlockProps)(linkState.details.data, linkState.details.meta, {
|
|
50
|
+
handleInvoke: function handleInvoke(opts) {
|
|
51
|
+
return linkActions.invoke(opts, appearance);
|
|
52
|
+
},
|
|
53
|
+
handleAnalytics: analyticsHandler,
|
|
54
|
+
extensionKey: (0, _helpers.getExtensionKey)(linkState.details)
|
|
55
|
+
}, undefined, platform);
|
|
56
|
+
|
|
57
|
+
if (!cardProperties.actions || cardProperties.actions.length === 0) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
var cardActions = cardProperties.actions.map(function (action) {
|
|
62
|
+
return {
|
|
63
|
+
id: action.id,
|
|
64
|
+
text: action.text,
|
|
65
|
+
invoke: action.promise
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
setActions(cardActions);
|
|
69
|
+
}, [linkState, linkActions, analyticsHandler, appearance, platform]);
|
|
70
|
+
return actions;
|
|
71
|
+
}
|
|
@@ -230,7 +230,7 @@ var uiAuthAlternateAccountEvent = function uiAuthAlternateAccountEvent(display,
|
|
|
230
230
|
|
|
231
231
|
exports.uiAuthAlternateAccountEvent = uiAuthAlternateAccountEvent;
|
|
232
232
|
|
|
233
|
-
var uiCardClickedEvent = function uiCardClickedEvent(display, definitionId, extensionKey) {
|
|
233
|
+
var uiCardClickedEvent = function uiCardClickedEvent(display, definitionId, extensionKey, isModifierKeyPressed) {
|
|
234
234
|
return {
|
|
235
235
|
action: 'clicked',
|
|
236
236
|
actionSubject: 'smartLink',
|
|
@@ -238,7 +238,8 @@ var uiCardClickedEvent = function uiCardClickedEvent(display, definitionId, exte
|
|
|
238
238
|
attributes: _objectSpread(_objectSpread({}, context), {}, {
|
|
239
239
|
definitionId: definitionId || '',
|
|
240
240
|
extensionKey: extensionKey || '',
|
|
241
|
-
display: display
|
|
241
|
+
display: display,
|
|
242
|
+
isModifierKeyPressed: isModifierKeyPressed
|
|
242
243
|
})
|
|
243
244
|
};
|
|
244
245
|
};
|
package/dist/cjs/utils/mocks.js
CHANGED
|
@@ -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.waitFor = exports.mocks = exports.fakeResponse = exports.fakeFactory = void 0;
|
|
8
|
+
exports.waitFor = exports.mocks = exports.mockContext = exports.fakeResponse = exports.fakeFactory = void 0;
|
|
9
9
|
|
|
10
10
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
11
11
|
|
|
@@ -27,6 +27,12 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
|
|
|
27
27
|
|
|
28
28
|
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
29
29
|
|
|
30
|
+
var mockContext = {
|
|
31
|
+
'@vocab': 'https://www.w3.org/ns/activitystreams#',
|
|
32
|
+
atlassian: 'https://schema.atlassian.com/ns/vocabulary#',
|
|
33
|
+
schema: 'http://schema.org/'
|
|
34
|
+
};
|
|
35
|
+
exports.mockContext = mockContext;
|
|
30
36
|
var mocks = {
|
|
31
37
|
success: {
|
|
32
38
|
meta: {
|
package/dist/cjs/version.json
CHANGED
|
@@ -104,7 +104,7 @@ var BlockCard = function BlockCard(_ref) {
|
|
|
104
104
|
handleAuthorize = _ref.handleAuthorize,
|
|
105
105
|
handleErrorRetry = _ref.handleErrorRetry,
|
|
106
106
|
handleFrameClick = _ref.handleFrameClick,
|
|
107
|
-
|
|
107
|
+
handleAnalytics = _ref.handleAnalytics,
|
|
108
108
|
handleInvoke = _ref.handleInvoke,
|
|
109
109
|
renderers = _ref.renderers,
|
|
110
110
|
isSelected = _ref.isSelected,
|
|
@@ -115,7 +115,7 @@ var BlockCard = function BlockCard(_ref) {
|
|
|
115
115
|
var data = details && details.data || (0, _jsonld.getEmptyJsonLd)();
|
|
116
116
|
var meta = details && details.meta;
|
|
117
117
|
var extractorOpts = {
|
|
118
|
-
handleAnalytics:
|
|
118
|
+
handleAnalytics: handleAnalytics,
|
|
119
119
|
handleInvoke: handleInvoke,
|
|
120
120
|
extensionKey: (0, _helpers.getExtensionKey)(details)
|
|
121
121
|
};
|
|
@@ -63,7 +63,10 @@ function CardWithUrlContent(_ref) {
|
|
|
63
63
|
var definitionId = (0, _helpers.getDefinitionId)(state.details);
|
|
64
64
|
var extensionKey = (0, _helpers.getExtensionKey)(state.details);
|
|
65
65
|
var resourceType = (0, _helpers.getResourceType)(state.details);
|
|
66
|
-
var services = (0, _helpers.getServices)(state.details);
|
|
66
|
+
var services = (0, _helpers.getServices)(state.details);
|
|
67
|
+
var isFlexibleUi = (0, _react.useMemo)(function () {
|
|
68
|
+
return (0, _flexible.isFlexibleUiCard)(children);
|
|
69
|
+
}, [children]); // Setup UI handlers.
|
|
67
70
|
|
|
68
71
|
var handleClick = (0, _react.useCallback)(function (event) {
|
|
69
72
|
var clickUrl = (0, _helpers.getClickUrl)(url, state.details);
|
|
@@ -71,11 +74,12 @@ function CardWithUrlContent(_ref) {
|
|
|
71
74
|
}, [state.details, url]);
|
|
72
75
|
var handleClickWrapper = (0, _react.useCallback)(function (event) {
|
|
73
76
|
if (state.status === 'resolved') {
|
|
74
|
-
|
|
77
|
+
var isModifierKeyPressed = (0, _utils.isSpecialEvent)(event);
|
|
78
|
+
analytics.ui.cardClickedEvent(isFlexibleUi ? 'flexible' : appearance, definitionId, extensionKey, isModifierKeyPressed);
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
onClick ? onClick(event) : handleClick(event);
|
|
78
|
-
}, [state.status, analytics.ui, appearance, definitionId, extensionKey, onClick, handleClick]);
|
|
82
|
+
}, [state.status, analytics.ui, appearance, definitionId, extensionKey, onClick, handleClick, isFlexibleUi]);
|
|
79
83
|
var handleAuthorize = (0, _react.useCallback)(function () {
|
|
80
84
|
return actions.authorize(appearance);
|
|
81
85
|
}, [actions, appearance]);
|
|
@@ -109,13 +113,15 @@ function CardWithUrlContent(_ref) {
|
|
|
109
113
|
throw error;
|
|
110
114
|
}
|
|
111
115
|
|
|
112
|
-
if (
|
|
116
|
+
if (isFlexibleUi) {
|
|
113
117
|
return /*#__PURE__*/_react.default.createElement(_FlexibleCard.default, {
|
|
114
118
|
cardState: state,
|
|
115
119
|
onAuthorize: services.length && handleAuthorize || undefined,
|
|
120
|
+
onClick: handleClickWrapper,
|
|
116
121
|
renderers: renderers,
|
|
117
122
|
ui: ui,
|
|
118
|
-
url: url
|
|
123
|
+
url: url,
|
|
124
|
+
testId: testId
|
|
119
125
|
}, children);
|
|
120
126
|
}
|
|
121
127
|
|
|
@@ -143,7 +149,7 @@ function CardWithUrlContent(_ref) {
|
|
|
143
149
|
handleErrorRetry: handleRetry,
|
|
144
150
|
handleInvoke: handleInvoke,
|
|
145
151
|
handleFrameClick: handleClickWrapper,
|
|
146
|
-
|
|
152
|
+
handleAnalytics: dispatchAnalytics,
|
|
147
153
|
isSelected: isSelected,
|
|
148
154
|
onResolve: onResolve,
|
|
149
155
|
testId: testId,
|
|
@@ -33,7 +33,7 @@ var _utils = require("../../utils");
|
|
|
33
33
|
|
|
34
34
|
var _actionGroup = _interopRequireDefault(require("../../action-group"));
|
|
35
35
|
|
|
36
|
-
var _excluded = ["maxLines", "metadata", "position", "subtitle", "actions", "testId", "theme", "text", "showActionOnHover"];
|
|
36
|
+
var _excluded = ["maxLines", "metadata", "position", "subtitle", "actions", "testId", "theme", "onClick", "text", "showActionOnHover"];
|
|
37
37
|
|
|
38
38
|
var _templateObject;
|
|
39
39
|
|
|
@@ -54,6 +54,7 @@ var TitleBlockResolvedView = function TitleBlockResolvedView(_ref) {
|
|
|
54
54
|
actions = _ref$actions === void 0 ? [] : _ref$actions,
|
|
55
55
|
testId = _ref.testId,
|
|
56
56
|
theme = _ref.theme,
|
|
57
|
+
onClick = _ref.onClick,
|
|
57
58
|
text = _ref.text,
|
|
58
59
|
showActionOnHover = _ref.showActionOnHover,
|
|
59
60
|
blockProps = (0, _objectWithoutProperties2.default)(_ref, _excluded);
|
|
@@ -79,7 +80,8 @@ var TitleBlockResolvedView = function TitleBlockResolvedView(_ref) {
|
|
|
79
80
|
width: _constants.SmartLinkWidth.Flexible
|
|
80
81
|
}, (0, _core.jsx)(_elements.Title, (0, _extends2.default)({
|
|
81
82
|
maxLines: maxLines,
|
|
82
|
-
theme: theme
|
|
83
|
+
theme: theme,
|
|
84
|
+
onClick: onClick
|
|
83
85
|
}, overrideText)), subtitleElements && (0, _core.jsx)(_elementGroup.default, {
|
|
84
86
|
direction: _constants.SmartLinkDirection.Horizontal
|
|
85
87
|
}, subtitleElements)), metadataElements && (0, _core.jsx)(_elementGroup.default, {
|
|
@@ -63,11 +63,12 @@ var getContainerStyles = function getContainerStyles(size, hideBackground, hideE
|
|
|
63
63
|
|
|
64
64
|
exports.getContainerStyles = getContainerStyles;
|
|
65
65
|
|
|
66
|
-
var renderChildren = function renderChildren(children, containerSize, containerTheme, status, retry) {
|
|
66
|
+
var renderChildren = function renderChildren(children, containerSize, containerTheme, status, retry, onClick) {
|
|
67
67
|
return _react.default.Children.map(children, function (child) {
|
|
68
68
|
if ( /*#__PURE__*/_react.default.isValidElement(child) && (0, _flexible.isFlexibleUiBlock)(child)) {
|
|
69
69
|
var blockSize = child.props.size;
|
|
70
70
|
return /*#__PURE__*/_react.default.cloneElement(child, {
|
|
71
|
+
onClick: onClick,
|
|
71
72
|
retry: (0, _flexible.isFlexibleUiTitleBlock)(child) ? retry : undefined,
|
|
72
73
|
size: blockSize || containerSize,
|
|
73
74
|
status: status,
|
|
@@ -92,12 +93,13 @@ var Container = function Container(_ref) {
|
|
|
92
93
|
_ref$testId = _ref.testId,
|
|
93
94
|
testId = _ref$testId === void 0 ? 'smart-links-container' : _ref$testId,
|
|
94
95
|
_ref$theme = _ref.theme,
|
|
95
|
-
theme = _ref$theme === void 0 ? _constants.SmartLinkTheme.Link : _ref$theme
|
|
96
|
+
theme = _ref$theme === void 0 ? _constants.SmartLinkTheme.Link : _ref$theme,
|
|
97
|
+
onClick = _ref.onClick;
|
|
96
98
|
return (0, _core.jsx)("div", {
|
|
97
99
|
css: getContainerStyles(size, hideBackground, hideElevation, hidePadding),
|
|
98
100
|
"data-smart-link-container": true,
|
|
99
101
|
"data-testid": testId
|
|
100
|
-
}, renderChildren(children, size, theme, status, retry));
|
|
102
|
+
}, renderChildren(children, size, theme, status, retry, onClick));
|
|
101
103
|
};
|
|
102
104
|
|
|
103
105
|
var _default = Container;
|
|
@@ -66,7 +66,8 @@ var Link = function Link(_ref) {
|
|
|
66
66
|
text = _ref.text,
|
|
67
67
|
_ref$theme = _ref.theme,
|
|
68
68
|
theme = _ref$theme === void 0 ? _constants.SmartLinkTheme.Link : _ref$theme,
|
|
69
|
-
url = _ref.url
|
|
69
|
+
url = _ref.url,
|
|
70
|
+
onClick = _ref.onClick;
|
|
70
71
|
return (0, _core.jsx)("span", {
|
|
71
72
|
css: containerStyles
|
|
72
73
|
}, (0, _core.jsx)(_tooltip.default, {
|
|
@@ -77,6 +78,7 @@ var Link = function Link(_ref) {
|
|
|
77
78
|
css: getAnchorStyles(size, theme, getMaxLines(maxLines)),
|
|
78
79
|
"data-smart-element-link": true,
|
|
79
80
|
"data-testid": testId,
|
|
81
|
+
onClick: onClick,
|
|
80
82
|
href: url
|
|
81
83
|
}, text)));
|
|
82
84
|
};
|
|
@@ -17,9 +17,17 @@ var _imageIcon = _interopRequireDefault(require("../../common/image-icon"));
|
|
|
17
17
|
|
|
18
18
|
var _templateObject;
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Media: Image
|
|
22
|
+
* [aspect-ratio: 16 / 9] The context box is fixed to aspect ratio of 16:9.
|
|
23
|
+
* [object-fit: cover] The replaced content is sized to maintain
|
|
24
|
+
* its aspect ratio while filling the element's entire content box.
|
|
25
|
+
* If the object's aspect ratio does not match the aspect ratio of its box,
|
|
26
|
+
* then the object will be clipped to fit.
|
|
27
|
+
* [object-position] Center alignment of the selected replaced element's
|
|
28
|
+
* contents within the element's box.
|
|
29
|
+
*/
|
|
30
|
+
var styles = (0, _core.css)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n aspect-ratio: 16 / 9;\n display: flex;\n width: 100%;\n\n // fallback\n @supports not (aspect-ratio: auto) {\n padding-top: 56.25%; // 16:9 ratio (9 / 16 = 0.5625)\n height: 0;\n position: relative;\n overflow: hidden;\n }\n\n > img {\n min-height: 100%;\n min-width: 100%;\n max-height: 100%;\n max-width: 100%;\n object-fit: cover;\n object-position: center center;\n\n // fallback\n @supports not (aspect-ratio: auto) {\n position: absolute;\n transform: translate(-50%, -50%);\n left: 50%;\n top: 50%;\n width: auto;\n height: auto;\n }\n }\n"])));
|
|
23
31
|
|
|
24
32
|
var Media = function Media(_ref) {
|
|
25
33
|
var _ref$testId = _ref.testId,
|
|
@@ -32,7 +40,7 @@ var Media = function Media(_ref) {
|
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
return (0, _core.jsx)("div", {
|
|
35
|
-
css: styles
|
|
43
|
+
css: styles,
|
|
36
44
|
"data-smart-element-media": true,
|
|
37
45
|
"data-testid": testId
|
|
38
46
|
}, (0, _core.jsx)(_imageIcon.default, {
|
|
@@ -23,7 +23,9 @@ var FlexibleCard = function FlexibleCard(_ref) {
|
|
|
23
23
|
onAuthorize = _ref.onAuthorize,
|
|
24
24
|
renderers = _ref.renderers,
|
|
25
25
|
ui = _ref.ui,
|
|
26
|
-
url = _ref.url
|
|
26
|
+
url = _ref.url,
|
|
27
|
+
onClick = _ref.onClick,
|
|
28
|
+
testId = _ref.testId;
|
|
27
29
|
var cardType = cardState.status,
|
|
28
30
|
details = cardState.details;
|
|
29
31
|
var status = cardType;
|
|
@@ -31,9 +33,12 @@ var FlexibleCard = function FlexibleCard(_ref) {
|
|
|
31
33
|
var retry = (0, _utils.getRetryOptions)(url, status, details, onAuthorize);
|
|
32
34
|
return /*#__PURE__*/_react.default.createElement(_flexibleUiContext.FlexibleUiContext.Provider, {
|
|
33
35
|
value: context
|
|
34
|
-
}, /*#__PURE__*/_react.default.createElement(_container.default, (0, _extends2.default)({
|
|
36
|
+
}, /*#__PURE__*/_react.default.createElement(_container.default, (0, _extends2.default)({
|
|
37
|
+
testId: testId
|
|
38
|
+
}, ui, {
|
|
35
39
|
retry: retry,
|
|
36
|
-
status: status
|
|
40
|
+
status: status,
|
|
41
|
+
onClick: onClick
|
|
37
42
|
}), children));
|
|
38
43
|
};
|
|
39
44
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useSmartLinkActions } from './state/hooks-external/useSmartLinkActions';
|
|
@@ -5,7 +5,7 @@ export const useSmartLinkAnalytics = dispatchAnalytics => {
|
|
|
5
5
|
const ui = useMemo(() => ({
|
|
6
6
|
authEvent: (display, definitionId, extensionKey) => dispatchAnalytics(uiAuthEvent(display, definitionId, extensionKey)),
|
|
7
7
|
authAlternateAccountEvent: (display, definitionId, extensionKey) => dispatchAnalytics(uiAuthAlternateAccountEvent(display, definitionId, extensionKey)),
|
|
8
|
-
cardClickedEvent: (display, definitionId, extensionKey) => dispatchAnalytics(uiCardClickedEvent(display, definitionId, extensionKey)),
|
|
8
|
+
cardClickedEvent: (display, definitionId, extensionKey, isModifierKeyPressed) => dispatchAnalytics(uiCardClickedEvent(display, definitionId, extensionKey, isModifierKeyPressed)),
|
|
9
9
|
actionClickedEvent: (id, extensionKey, actionType, display, invokeType) => {
|
|
10
10
|
startUfoExperience('smart-link-action-invocation', id, {
|
|
11
11
|
actionType,
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import uuid from 'uuid';
|
|
3
|
+
import { extractBlockProps as extractCardProps } from '../../extractors/block';
|
|
4
|
+
import { useSmartCardActions as useLinkActions } from '../actions';
|
|
5
|
+
import { useSmartLinkAnalytics as useLinkAnalytics } from '../analytics';
|
|
6
|
+
import { useSmartCardState as useLinkState } from '../store';
|
|
7
|
+
import { getExtensionKey } from '../helpers';
|
|
8
|
+
export function useSmartLinkActions({
|
|
9
|
+
url,
|
|
10
|
+
appearance,
|
|
11
|
+
analyticsHandler,
|
|
12
|
+
platform = 'web'
|
|
13
|
+
}) {
|
|
14
|
+
const id = useMemo(() => uuid(), []);
|
|
15
|
+
const [actions, setActions] = useState([]);
|
|
16
|
+
const linkState = useLinkState(url);
|
|
17
|
+
const linkAnalytics = useLinkAnalytics(analyticsHandler);
|
|
18
|
+
const linkActions = useLinkActions(id, url, linkAnalytics);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (!linkState.details) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const cardProperties = extractCardProps(linkState.details.data, linkState.details.meta, {
|
|
25
|
+
handleInvoke: opts => linkActions.invoke(opts, appearance),
|
|
26
|
+
handleAnalytics: analyticsHandler,
|
|
27
|
+
extensionKey: getExtensionKey(linkState.details)
|
|
28
|
+
}, undefined, platform);
|
|
29
|
+
|
|
30
|
+
if (!cardProperties.actions || cardProperties.actions.length === 0) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const cardActions = cardProperties.actions.map(action => ({
|
|
35
|
+
id: action.id,
|
|
36
|
+
text: action.text,
|
|
37
|
+
invoke: action.promise
|
|
38
|
+
}));
|
|
39
|
+
setActions(cardActions);
|
|
40
|
+
}, [linkState, linkActions, analyticsHandler, appearance, platform]);
|
|
41
|
+
return actions;
|
|
42
|
+
}
|
|
@@ -169,14 +169,15 @@ export const uiAuthAlternateAccountEvent = (display, definitionId, extensionKey)
|
|
|
169
169
|
display
|
|
170
170
|
}
|
|
171
171
|
});
|
|
172
|
-
export const uiCardClickedEvent = (display, definitionId, extensionKey) => ({
|
|
172
|
+
export const uiCardClickedEvent = (display, definitionId, extensionKey, isModifierKeyPressed) => ({
|
|
173
173
|
action: 'clicked',
|
|
174
174
|
actionSubject: 'smartLink',
|
|
175
175
|
eventType: 'ui',
|
|
176
176
|
attributes: { ...context,
|
|
177
177
|
definitionId: definitionId || '',
|
|
178
178
|
extensionKey: extensionKey || '',
|
|
179
|
-
display
|
|
179
|
+
display,
|
|
180
|
+
isModifierKeyPressed
|
|
180
181
|
}
|
|
181
182
|
});
|
|
182
183
|
export const uiActionClickedEvent = (extensionKey, actionType, display) => ({
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import CardClient from '../client';
|
|
2
|
+
export const mockContext = {
|
|
3
|
+
'@vocab': 'https://www.w3.org/ns/activitystreams#',
|
|
4
|
+
atlassian: 'https://schema.atlassian.com/ns/vocabulary#',
|
|
5
|
+
schema: 'http://schema.org/'
|
|
6
|
+
};
|
|
2
7
|
export const mocks = {
|
|
3
8
|
success: {
|
|
4
9
|
meta: {
|
package/dist/es2019/version.json
CHANGED
|
@@ -25,7 +25,7 @@ export const BlockCard = ({
|
|
|
25
25
|
handleAuthorize,
|
|
26
26
|
handleErrorRetry,
|
|
27
27
|
handleFrameClick,
|
|
28
|
-
|
|
28
|
+
handleAnalytics,
|
|
29
29
|
handleInvoke,
|
|
30
30
|
renderers,
|
|
31
31
|
isSelected,
|
|
@@ -39,7 +39,7 @@ export const BlockCard = ({
|
|
|
39
39
|
const data = details && details.data || getEmptyJsonLd();
|
|
40
40
|
const meta = details && details.meta;
|
|
41
41
|
const extractorOpts = {
|
|
42
|
-
handleAnalytics
|
|
42
|
+
handleAnalytics,
|
|
43
43
|
handleInvoke,
|
|
44
44
|
extensionKey: getExtensionKey(details)
|
|
45
45
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useCallback } from 'react';
|
|
1
|
+
import React, { useEffect, useCallback, useMemo } from 'react';
|
|
2
2
|
import { isSpecialEvent } from '../../utils';
|
|
3
3
|
import * as measure from '../../utils/performance';
|
|
4
4
|
import { getDefinitionId, getServices, isFinalState, getClickUrl, getResourceType, getExtensionKey } from '../../state/helpers';
|
|
@@ -38,7 +38,8 @@ export function CardWithUrlContent({
|
|
|
38
38
|
const definitionId = getDefinitionId(state.details);
|
|
39
39
|
const extensionKey = getExtensionKey(state.details);
|
|
40
40
|
const resourceType = getResourceType(state.details);
|
|
41
|
-
const services = getServices(state.details);
|
|
41
|
+
const services = getServices(state.details);
|
|
42
|
+
let isFlexibleUi = useMemo(() => isFlexibleUiCard(children), [children]); // Setup UI handlers.
|
|
42
43
|
|
|
43
44
|
const handleClick = useCallback(event => {
|
|
44
45
|
const clickUrl = getClickUrl(url, state.details);
|
|
@@ -46,11 +47,12 @@ export function CardWithUrlContent({
|
|
|
46
47
|
}, [state.details, url]);
|
|
47
48
|
const handleClickWrapper = useCallback(event => {
|
|
48
49
|
if (state.status === 'resolved') {
|
|
49
|
-
|
|
50
|
+
const isModifierKeyPressed = isSpecialEvent(event);
|
|
51
|
+
analytics.ui.cardClickedEvent(isFlexibleUi ? 'flexible' : appearance, definitionId, extensionKey, isModifierKeyPressed);
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
onClick ? onClick(event) : handleClick(event);
|
|
53
|
-
}, [state.status, analytics.ui, appearance, definitionId, extensionKey, onClick, handleClick]);
|
|
55
|
+
}, [state.status, analytics.ui, appearance, definitionId, extensionKey, onClick, handleClick, isFlexibleUi]);
|
|
54
56
|
const handleAuthorize = useCallback(() => actions.authorize(appearance), [actions, appearance]);
|
|
55
57
|
const handleRetry = useCallback(() => {
|
|
56
58
|
actions.reload();
|
|
@@ -80,13 +82,15 @@ export function CardWithUrlContent({
|
|
|
80
82
|
throw error;
|
|
81
83
|
}
|
|
82
84
|
|
|
83
|
-
if (
|
|
85
|
+
if (isFlexibleUi) {
|
|
84
86
|
return /*#__PURE__*/React.createElement(FlexibleCard, {
|
|
85
87
|
cardState: state,
|
|
86
88
|
onAuthorize: services.length && handleAuthorize || undefined,
|
|
89
|
+
onClick: handleClickWrapper,
|
|
87
90
|
renderers: renderers,
|
|
88
91
|
ui: ui,
|
|
89
|
-
url: url
|
|
92
|
+
url: url,
|
|
93
|
+
testId: testId
|
|
90
94
|
}, children);
|
|
91
95
|
}
|
|
92
96
|
|
|
@@ -114,7 +118,7 @@ export function CardWithUrlContent({
|
|
|
114
118
|
handleErrorRetry: handleRetry,
|
|
115
119
|
handleInvoke: handleInvoke,
|
|
116
120
|
handleFrameClick: handleClickWrapper,
|
|
117
|
-
|
|
121
|
+
handleAnalytics: dispatchAnalytics,
|
|
118
122
|
isSelected: isSelected,
|
|
119
123
|
onResolve: onResolve,
|
|
120
124
|
testId: testId,
|
|
@@ -29,6 +29,7 @@ const TitleBlockResolvedView = ({
|
|
|
29
29
|
actions = [],
|
|
30
30
|
testId,
|
|
31
31
|
theme,
|
|
32
|
+
onClick,
|
|
32
33
|
text,
|
|
33
34
|
showActionOnHover,
|
|
34
35
|
...blockProps
|
|
@@ -50,7 +51,8 @@ const TitleBlockResolvedView = ({
|
|
|
50
51
|
width: SmartLinkWidth.Flexible
|
|
51
52
|
}, jsx(Title, _extends({
|
|
52
53
|
maxLines: maxLines,
|
|
53
|
-
theme: theme
|
|
54
|
+
theme: theme,
|
|
55
|
+
onClick: onClick
|
|
54
56
|
}, overrideText)), subtitleElements && jsx(ElementGroup, {
|
|
55
57
|
direction: SmartLinkDirection.Horizontal
|
|
56
58
|
}, subtitleElements)), metadataElements && jsx(ElementGroup, {
|
|
@@ -56,12 +56,13 @@ export const getContainerStyles = (size, hideBackground, hideElevation, hidePadd
|
|
|
56
56
|
${hideElevation ? '' : elevationStyles}
|
|
57
57
|
`;
|
|
58
58
|
|
|
59
|
-
const renderChildren = (children, containerSize, containerTheme, status, retry) => React.Children.map(children, child => {
|
|
59
|
+
const renderChildren = (children, containerSize, containerTheme, status, retry, onClick) => React.Children.map(children, child => {
|
|
60
60
|
if ( /*#__PURE__*/React.isValidElement(child) && isFlexibleUiBlock(child)) {
|
|
61
61
|
const {
|
|
62
62
|
size: blockSize
|
|
63
63
|
} = child.props;
|
|
64
64
|
return /*#__PURE__*/React.cloneElement(child, {
|
|
65
|
+
onClick,
|
|
65
66
|
retry: isFlexibleUiTitleBlock(child) ? retry : undefined,
|
|
66
67
|
size: blockSize || containerSize,
|
|
67
68
|
status,
|
|
@@ -79,11 +80,12 @@ const Container = ({
|
|
|
79
80
|
size = SmartLinkSize.Medium,
|
|
80
81
|
status,
|
|
81
82
|
testId = 'smart-links-container',
|
|
82
|
-
theme = SmartLinkTheme.Link
|
|
83
|
+
theme = SmartLinkTheme.Link,
|
|
84
|
+
onClick
|
|
83
85
|
}) => jsx("div", {
|
|
84
86
|
css: getContainerStyles(size, hideBackground, hideElevation, hidePadding),
|
|
85
87
|
"data-smart-link-container": true,
|
|
86
88
|
"data-testid": testId
|
|
87
|
-
}, renderChildren(children, size, theme, status, retry));
|
|
89
|
+
}, renderChildren(children, size, theme, status, retry, onClick));
|
|
88
90
|
|
|
89
91
|
export default Container;
|
|
@@ -70,7 +70,8 @@ const Link = ({
|
|
|
70
70
|
testId = 'smart-element-link',
|
|
71
71
|
text,
|
|
72
72
|
theme = SmartLinkTheme.Link,
|
|
73
|
-
url
|
|
73
|
+
url,
|
|
74
|
+
onClick
|
|
74
75
|
}) => jsx("span", {
|
|
75
76
|
css: containerStyles
|
|
76
77
|
}, jsx(Tooltip, {
|
|
@@ -81,6 +82,7 @@ const Link = ({
|
|
|
81
82
|
css: getAnchorStyles(size, theme, getMaxLines(maxLines)),
|
|
82
83
|
"data-smart-element-link": true,
|
|
83
84
|
"data-testid": testId,
|
|
85
|
+
onClick: onClick,
|
|
84
86
|
href: url
|
|
85
87
|
}, text)));
|
|
86
88
|
|