@atlaskit/smart-card 17.7.5 → 17.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/dist/cjs/hooks.js +13 -0
  3. package/dist/cjs/state/analytics/useSmartLinkAnalytics.js +2 -2
  4. package/dist/cjs/state/hooks-external/useSmartLinkActions.js +71 -0
  5. package/dist/cjs/utils/analytics/analytics.js +3 -2
  6. package/dist/cjs/utils/mocks.js +7 -1
  7. package/dist/cjs/version.json +1 -1
  8. package/dist/cjs/view/BlockCard/index.js +2 -2
  9. package/dist/cjs/view/CardWithUrl/component.js +12 -6
  10. package/dist/cjs/view/FlexibleCard/components/blocks/title-block/resolved/index.js +4 -2
  11. package/dist/cjs/view/FlexibleCard/components/container/index.js +5 -3
  12. package/dist/cjs/view/FlexibleCard/components/elements/link/index.js +3 -1
  13. package/dist/cjs/view/FlexibleCard/index.js +8 -3
  14. package/dist/es2019/hooks.js +1 -0
  15. package/dist/es2019/state/analytics/useSmartLinkAnalytics.js +1 -1
  16. package/dist/es2019/state/hooks-external/useSmartLinkActions.js +42 -0
  17. package/dist/es2019/utils/analytics/analytics.js +3 -2
  18. package/dist/es2019/utils/mocks.js +5 -0
  19. package/dist/es2019/version.json +1 -1
  20. package/dist/es2019/view/BlockCard/index.js +2 -2
  21. package/dist/es2019/view/CardWithUrl/component.js +11 -7
  22. package/dist/es2019/view/FlexibleCard/components/blocks/title-block/resolved/index.js +3 -1
  23. package/dist/es2019/view/FlexibleCard/components/container/index.js +5 -3
  24. package/dist/es2019/view/FlexibleCard/components/elements/link/index.js +3 -1
  25. package/dist/es2019/view/FlexibleCard/index.js +8 -3
  26. package/dist/esm/hooks.js +1 -0
  27. package/dist/esm/state/analytics/useSmartLinkAnalytics.js +2 -2
  28. package/dist/esm/state/hooks-external/useSmartLinkActions.js +54 -0
  29. package/dist/esm/utils/analytics/analytics.js +3 -2
  30. package/dist/esm/utils/mocks.js +5 -0
  31. package/dist/esm/version.json +1 -1
  32. package/dist/esm/view/BlockCard/index.js +2 -2
  33. package/dist/esm/view/CardWithUrl/component.js +13 -7
  34. package/dist/esm/view/FlexibleCard/components/blocks/title-block/resolved/index.js +4 -2
  35. package/dist/esm/view/FlexibleCard/components/container/index.js +5 -3
  36. package/dist/esm/view/FlexibleCard/components/elements/link/index.js +3 -1
  37. package/dist/esm/view/FlexibleCard/index.js +8 -3
  38. package/dist/types/hooks.d.ts +1 -0
  39. package/dist/types/state/analytics/useSmartLinkAnalytics.d.ts +1 -1
  40. package/dist/types/state/hooks/useSmartLink.d.ts +1 -1
  41. package/dist/types/state/hooks-external/useSmartLinkActions.d.ts +45 -0
  42. package/dist/types/utils/analytics/analytics.d.ts +2 -2
  43. package/dist/types/utils/mocks.d.ts +5 -0
  44. package/dist/types/view/BlockCard/types.d.ts +1 -1
  45. package/dist/types/view/Card/types.d.ts +1 -1
  46. package/dist/types/view/FlexibleCard/components/blocks/title-block/types.d.ts +2 -0
  47. package/dist/types/view/FlexibleCard/components/container/types.d.ts +2 -0
  48. package/dist/types/view/FlexibleCard/components/elements/link/types.d.ts +2 -0
  49. package/dist/types/view/FlexibleCard/types.d.ts +1 -0
  50. package/hooks/package.json +7 -0
  51. package/package.json +3 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # @atlaskit/smart-card
2
2
 
3
+ ## 17.7.8
4
+
5
+ ### Patch Changes
6
+
7
+ - [`d75ce5b847d`](https://bitbucket.org/atlassian/atlassian-frontend/commits/d75ce5b847d) - Add link click analytics to flexible ui title block component
8
+
9
+ ## 17.7.7
10
+
11
+ ### Patch Changes
12
+
13
+ - [`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.
14
+
15
+ Example usage:
16
+
17
+ ```tsx
18
+ import { useSmartLinkActions } from '@atlaskit/smart-card/hooks';
19
+
20
+ const ExampleToolbar = () => {
21
+ const actions = useSmartLinkActions({
22
+ url,
23
+ appearance: 'block',
24
+ analyticsHandler: analytics,
25
+ });
26
+
27
+ return (
28
+ <ExampleToolbarWrapper>
29
+ {actions.map((action) => (
30
+ <Tooltip content={action.text}>
31
+ <ExampleToolbarItem key={action.id} onClick={action.invoke}>
32
+ {idToIcon[action.id] ?? action.id}
33
+ </ExampleToolbarItem>
34
+ </Tooltip>
35
+ ))}
36
+ </ExampleToolbarWrapper>
37
+ );
38
+ };
39
+ ```
40
+
41
+ ## 17.7.6
42
+
43
+ ### Patch Changes
44
+
45
+ - [`0e5c8b501d6`](https://bitbucket.org/atlassian/atlassian-frontend/commits/0e5c8b501d6) - add test for when hover preview prop is not provided to inline card
46
+
3
47
  ## 17.7.5
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
  };
@@ -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: {
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "17.7.5",
3
+ "version": "17.7.8",
4
4
  "sideEffects": false
5
5
  }
@@ -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
- handlePreviewAnalytics = _ref.handlePreviewAnalytics,
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: handlePreviewAnalytics,
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); // Setup UI handlers.
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
- analytics.ui.cardClickedEvent(appearance, definitionId, extensionKey);
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 ((0, _flexible.isFlexibleUiCard)(children)) {
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
- handlePreviewAnalytics: dispatchAnalytics,
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
  };
@@ -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)({}, ui, {
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: {
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "17.7.5",
3
+ "version": "17.7.8",
4
4
  "sideEffects": false
5
5
  }
@@ -25,7 +25,7 @@ export const BlockCard = ({
25
25
  handleAuthorize,
26
26
  handleErrorRetry,
27
27
  handleFrameClick,
28
- handlePreviewAnalytics,
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: handlePreviewAnalytics,
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); // Setup UI handlers.
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
- analytics.ui.cardClickedEvent(appearance, definitionId, extensionKey);
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 (isFlexibleUiCard(children)) {
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
- handlePreviewAnalytics: dispatchAnalytics,
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
 
@@ -10,7 +10,9 @@ const FlexibleCard = ({
10
10
  onAuthorize,
11
11
  renderers,
12
12
  ui,
13
- url
13
+ url,
14
+ onClick,
15
+ testId
14
16
  }) => {
15
17
  const {
16
18
  status: cardType,
@@ -21,9 +23,12 @@ const FlexibleCard = ({
21
23
  const retry = getRetryOptions(url, status, details, onAuthorize);
22
24
  return /*#__PURE__*/React.createElement(FlexibleUiContext.Provider, {
23
25
  value: context
24
- }, /*#__PURE__*/React.createElement(Container, _extends({}, ui, {
26
+ }, /*#__PURE__*/React.createElement(Container, _extends({
27
+ testId: testId
28
+ }, ui, {
25
29
  retry: retry,
26
- status: status
30
+ status: status,
31
+ onClick: onClick
27
32
  }), children));
28
33
  };
29
34
 
@@ -0,0 +1 @@
1
+ export { useSmartLinkActions } from './state/hooks-external/useSmartLinkActions';
@@ -10,8 +10,8 @@ export var useSmartLinkAnalytics = function useSmartLinkAnalytics(dispatchAnalyt
10
10
  authAlternateAccountEvent: function authAlternateAccountEvent(display, definitionId, extensionKey) {
11
11
  return dispatchAnalytics(uiAuthAlternateAccountEvent(display, definitionId, extensionKey));
12
12
  },
13
- cardClickedEvent: function cardClickedEvent(display, definitionId, extensionKey) {
14
- return dispatchAnalytics(uiCardClickedEvent(display, definitionId, extensionKey));
13
+ cardClickedEvent: function cardClickedEvent(display, definitionId, extensionKey, isModifierKeyPressed) {
14
+ return dispatchAnalytics(uiCardClickedEvent(display, definitionId, extensionKey, isModifierKeyPressed));
15
15
  },
16
16
  actionClickedEvent: function actionClickedEvent(id, extensionKey, actionType, display, invokeType) {
17
17
  startUfoExperience('smart-link-action-invocation', id, {
@@ -0,0 +1,54 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import uuid from 'uuid';
4
+ import { extractBlockProps as extractCardProps } from '../../extractors/block';
5
+ import { useSmartCardActions as useLinkActions } from '../actions';
6
+ import { useSmartLinkAnalytics as useLinkAnalytics } from '../analytics';
7
+ import { useSmartCardState as useLinkState } from '../store';
8
+ import { getExtensionKey } from '../helpers';
9
+ export function useSmartLinkActions(_ref) {
10
+ var url = _ref.url,
11
+ appearance = _ref.appearance,
12
+ analyticsHandler = _ref.analyticsHandler,
13
+ _ref$platform = _ref.platform,
14
+ platform = _ref$platform === void 0 ? 'web' : _ref$platform;
15
+ var id = useMemo(function () {
16
+ return uuid();
17
+ }, []);
18
+
19
+ var _useState = useState([]),
20
+ _useState2 = _slicedToArray(_useState, 2),
21
+ actions = _useState2[0],
22
+ setActions = _useState2[1];
23
+
24
+ var linkState = useLinkState(url);
25
+ var linkAnalytics = useLinkAnalytics(analyticsHandler);
26
+ var linkActions = useLinkActions(id, url, linkAnalytics);
27
+ useEffect(function () {
28
+ if (!linkState.details) {
29
+ return;
30
+ }
31
+
32
+ var cardProperties = extractCardProps(linkState.details.data, linkState.details.meta, {
33
+ handleInvoke: function handleInvoke(opts) {
34
+ return linkActions.invoke(opts, appearance);
35
+ },
36
+ handleAnalytics: analyticsHandler,
37
+ extensionKey: getExtensionKey(linkState.details)
38
+ }, undefined, platform);
39
+
40
+ if (!cardProperties.actions || cardProperties.actions.length === 0) {
41
+ return;
42
+ }
43
+
44
+ var cardActions = cardProperties.actions.map(function (action) {
45
+ return {
46
+ id: action.id,
47
+ text: action.text,
48
+ invoke: action.promise
49
+ };
50
+ });
51
+ setActions(cardActions);
52
+ }, [linkState, linkActions, analyticsHandler, appearance, platform]);
53
+ return actions;
54
+ }
@@ -182,7 +182,7 @@ export var uiAuthAlternateAccountEvent = function uiAuthAlternateAccountEvent(di
182
182
  })
183
183
  };
184
184
  };
185
- export var uiCardClickedEvent = function uiCardClickedEvent(display, definitionId, extensionKey) {
185
+ export var uiCardClickedEvent = function uiCardClickedEvent(display, definitionId, extensionKey, isModifierKeyPressed) {
186
186
  return {
187
187
  action: 'clicked',
188
188
  actionSubject: 'smartLink',
@@ -190,7 +190,8 @@ export var uiCardClickedEvent = function uiCardClickedEvent(display, definitionI
190
190
  attributes: _objectSpread(_objectSpread({}, context), {}, {
191
191
  definitionId: definitionId || '',
192
192
  extensionKey: extensionKey || '',
193
- display: display
193
+ display: display,
194
+ isModifierKeyPressed: isModifierKeyPressed
194
195
  })
195
196
  };
196
197
  };
@@ -11,6 +11,11 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
11
11
  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; } }
12
12
 
13
13
  import CardClient from '../client';
14
+ export var mockContext = {
15
+ '@vocab': 'https://www.w3.org/ns/activitystreams#',
16
+ atlassian: 'https://schema.atlassian.com/ns/vocabulary#',
17
+ schema: 'http://schema.org/'
18
+ };
14
19
  export var mocks = {
15
20
  success: {
16
21
  meta: {
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "17.7.5",
3
+ "version": "17.7.8",
4
4
  "sideEffects": false
5
5
  }
@@ -26,7 +26,7 @@ export var BlockCard = function BlockCard(_ref) {
26
26
  handleAuthorize = _ref.handleAuthorize,
27
27
  handleErrorRetry = _ref.handleErrorRetry,
28
28
  handleFrameClick = _ref.handleFrameClick,
29
- handlePreviewAnalytics = _ref.handlePreviewAnalytics,
29
+ handleAnalytics = _ref.handleAnalytics,
30
30
  handleInvoke = _ref.handleInvoke,
31
31
  renderers = _ref.renderers,
32
32
  isSelected = _ref.isSelected,
@@ -37,7 +37,7 @@ export var BlockCard = function BlockCard(_ref) {
37
37
  var data = details && details.data || getEmptyJsonLd();
38
38
  var meta = details && details.meta;
39
39
  var extractorOpts = {
40
- handleAnalytics: handlePreviewAnalytics,
40
+ handleAnalytics: handleAnalytics,
41
41
  handleInvoke: handleInvoke,
42
42
  extensionKey: getExtensionKey(details)
43
43
  };
@@ -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,10 @@ export function CardWithUrlContent(_ref) {
38
38
  var definitionId = getDefinitionId(state.details);
39
39
  var extensionKey = getExtensionKey(state.details);
40
40
  var resourceType = getResourceType(state.details);
41
- var services = getServices(state.details); // Setup UI handlers.
41
+ var services = getServices(state.details);
42
+ var isFlexibleUi = useMemo(function () {
43
+ return isFlexibleUiCard(children);
44
+ }, [children]); // Setup UI handlers.
42
45
 
43
46
  var handleClick = useCallback(function (event) {
44
47
  var clickUrl = getClickUrl(url, state.details);
@@ -46,11 +49,12 @@ export function CardWithUrlContent(_ref) {
46
49
  }, [state.details, url]);
47
50
  var handleClickWrapper = useCallback(function (event) {
48
51
  if (state.status === 'resolved') {
49
- analytics.ui.cardClickedEvent(appearance, definitionId, extensionKey);
52
+ var isModifierKeyPressed = isSpecialEvent(event);
53
+ analytics.ui.cardClickedEvent(isFlexibleUi ? 'flexible' : appearance, definitionId, extensionKey, isModifierKeyPressed);
50
54
  }
51
55
 
52
56
  onClick ? onClick(event) : handleClick(event);
53
- }, [state.status, analytics.ui, appearance, definitionId, extensionKey, onClick, handleClick]);
57
+ }, [state.status, analytics.ui, appearance, definitionId, extensionKey, onClick, handleClick, isFlexibleUi]);
54
58
  var handleAuthorize = useCallback(function () {
55
59
  return actions.authorize(appearance);
56
60
  }, [actions, appearance]);
@@ -84,13 +88,15 @@ export function CardWithUrlContent(_ref) {
84
88
  throw error;
85
89
  }
86
90
 
87
- if (isFlexibleUiCard(children)) {
91
+ if (isFlexibleUi) {
88
92
  return /*#__PURE__*/React.createElement(FlexibleCard, {
89
93
  cardState: state,
90
94
  onAuthorize: services.length && handleAuthorize || undefined,
95
+ onClick: handleClickWrapper,
91
96
  renderers: renderers,
92
97
  ui: ui,
93
- url: url
98
+ url: url,
99
+ testId: testId
94
100
  }, children);
95
101
  }
96
102
 
@@ -118,7 +124,7 @@ export function CardWithUrlContent(_ref) {
118
124
  handleErrorRetry: handleRetry,
119
125
  handleInvoke: handleInvoke,
120
126
  handleFrameClick: handleClickWrapper,
121
- handlePreviewAnalytics: dispatchAnalytics,
127
+ handleAnalytics: dispatchAnalytics,
122
128
  isSelected: isSelected,
123
129
  onResolve: onResolve,
124
130
  testId: testId,
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
4
4
  import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
5
- var _excluded = ["maxLines", "metadata", "position", "subtitle", "actions", "testId", "theme", "text", "showActionOnHover"];
5
+ var _excluded = ["maxLines", "metadata", "position", "subtitle", "actions", "testId", "theme", "onClick", "text", "showActionOnHover"];
6
6
 
7
7
  var _templateObject;
8
8
 
@@ -28,6 +28,7 @@ var TitleBlockResolvedView = function TitleBlockResolvedView(_ref) {
28
28
  actions = _ref$actions === void 0 ? [] : _ref$actions,
29
29
  testId = _ref.testId,
30
30
  theme = _ref.theme,
31
+ onClick = _ref.onClick,
31
32
  text = _ref.text,
32
33
  showActionOnHover = _ref.showActionOnHover,
33
34
  blockProps = _objectWithoutProperties(_ref, _excluded);
@@ -53,7 +54,8 @@ var TitleBlockResolvedView = function TitleBlockResolvedView(_ref) {
53
54
  width: SmartLinkWidth.Flexible
54
55
  }, jsx(Title, _extends({
55
56
  maxLines: maxLines,
56
- theme: theme
57
+ theme: theme,
58
+ onClick: onClick
57
59
  }, overrideText)), subtitleElements && jsx(ElementGroup, {
58
60
  direction: SmartLinkDirection.Horizontal
59
61
  }, subtitleElements)), metadataElements && jsx(ElementGroup, {
@@ -48,11 +48,12 @@ export var getContainerStyles = function getContainerStyles(size, hideBackground
48
48
  return css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n display: flex;\n gap: ", " 0;\n flex-direction: column;\n min-width: 0;\n overflow: hidden;\n ", "\n ", "\n ", "\n"])), getGap(size), hideBackground ? '' : "background-color: ".concat(tokens.background, ";"), hidePadding ? '' : "padding: ".concat(getPadding(size), ";"), hideElevation ? '' : elevationStyles);
49
49
  };
50
50
 
51
- var renderChildren = function renderChildren(children, containerSize, containerTheme, status, retry) {
51
+ var renderChildren = function renderChildren(children, containerSize, containerTheme, status, retry, onClick) {
52
52
  return React.Children.map(children, function (child) {
53
53
  if ( /*#__PURE__*/React.isValidElement(child) && isFlexibleUiBlock(child)) {
54
54
  var blockSize = child.props.size;
55
55
  return /*#__PURE__*/React.cloneElement(child, {
56
+ onClick: onClick,
56
57
  retry: isFlexibleUiTitleBlock(child) ? retry : undefined,
57
58
  size: blockSize || containerSize,
58
59
  status: status,
@@ -77,12 +78,13 @@ var Container = function Container(_ref) {
77
78
  _ref$testId = _ref.testId,
78
79
  testId = _ref$testId === void 0 ? 'smart-links-container' : _ref$testId,
79
80
  _ref$theme = _ref.theme,
80
- theme = _ref$theme === void 0 ? SmartLinkTheme.Link : _ref$theme;
81
+ theme = _ref$theme === void 0 ? SmartLinkTheme.Link : _ref$theme,
82
+ onClick = _ref.onClick;
81
83
  return jsx("div", {
82
84
  css: getContainerStyles(size, hideBackground, hideElevation, hidePadding),
83
85
  "data-smart-link-container": true,
84
86
  "data-testid": testId
85
- }, renderChildren(children, size, theme, status, retry));
87
+ }, renderChildren(children, size, theme, status, retry, onClick));
86
88
  };
87
89
 
88
90
  export default Container;
@@ -52,7 +52,8 @@ var Link = function Link(_ref) {
52
52
  text = _ref.text,
53
53
  _ref$theme = _ref.theme,
54
54
  theme = _ref$theme === void 0 ? SmartLinkTheme.Link : _ref$theme,
55
- url = _ref.url;
55
+ url = _ref.url,
56
+ onClick = _ref.onClick;
56
57
  return jsx("span", {
57
58
  css: containerStyles
58
59
  }, jsx(Tooltip, {
@@ -63,6 +64,7 @@ var Link = function Link(_ref) {
63
64
  css: getAnchorStyles(size, theme, getMaxLines(maxLines)),
64
65
  "data-smart-element-link": true,
65
66
  "data-testid": testId,
67
+ onClick: onClick,
66
68
  href: url
67
69
  }, text)));
68
70
  };
@@ -10,7 +10,9 @@ var FlexibleCard = function FlexibleCard(_ref) {
10
10
  onAuthorize = _ref.onAuthorize,
11
11
  renderers = _ref.renderers,
12
12
  ui = _ref.ui,
13
- url = _ref.url;
13
+ url = _ref.url,
14
+ onClick = _ref.onClick,
15
+ testId = _ref.testId;
14
16
  var cardType = cardState.status,
15
17
  details = cardState.details;
16
18
  var status = cardType;
@@ -18,9 +20,12 @@ var FlexibleCard = function FlexibleCard(_ref) {
18
20
  var retry = getRetryOptions(url, status, details, onAuthorize);
19
21
  return /*#__PURE__*/React.createElement(FlexibleUiContext.Provider, {
20
22
  value: context
21
- }, /*#__PURE__*/React.createElement(Container, _extends({}, ui, {
23
+ }, /*#__PURE__*/React.createElement(Container, _extends({
24
+ testId: testId
25
+ }, ui, {
22
26
  retry: retry,
23
- status: status
27
+ status: status,
28
+ onClick: onClick
24
29
  }), children));
25
30
  };
26
31
 
@@ -0,0 +1 @@
1
+ export { useSmartLinkActions } from './state/hooks-external/useSmartLinkActions';
@@ -7,7 +7,7 @@ export declare const useSmartLinkAnalytics: (dispatchAnalytics: AnalyticsHandler
7
7
  ui: {
8
8
  authEvent: (display: CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => void;
9
9
  authAlternateAccountEvent: (display: CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => void;
10
- cardClickedEvent: (display: CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => void;
10
+ cardClickedEvent: (display: CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined, isModifierKeyPressed?: boolean | undefined) => void;
11
11
  actionClickedEvent: (id: string, extensionKey: string, actionType: string, display: CardInnerAppearance, invokeType: InvokeType) => void;
12
12
  closedAuthEvent: (display: CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => void;
13
13
  renderSuccessEvent: (display: CardInnerAppearance, id: string, definitionId?: string | undefined, extensionKey?: string | undefined) => void;
@@ -12,7 +12,7 @@ export declare function useSmartLink(id: string, url: string, dispatchAnalytics:
12
12
  ui: {
13
13
  authEvent: (display: import("../../view/Card/types").CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => void;
14
14
  authAlternateAccountEvent: (display: import("../../view/Card/types").CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => void;
15
- cardClickedEvent: (display: import("../../view/Card/types").CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => void;
15
+ cardClickedEvent: (display: import("../../view/Card/types").CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined, isModifierKeyPressed?: boolean | undefined) => void;
16
16
  actionClickedEvent: (id: string, extensionKey: string, actionType: string, display: import("../../view/Card/types").CardInnerAppearance, invokeType: import("../../model/invoke-opts").InvokeType) => void;
17
17
  closedAuthEvent: (display: import("../../view/Card/types").CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => void;
18
18
  renderSuccessEvent: (display: import("../../view/Card/types").CardInnerAppearance, id: string, definitionId?: string | undefined, extensionKey?: string | undefined) => void;
@@ -0,0 +1,45 @@
1
+ /// <reference types="react" />
2
+ import { JsonLd } from 'json-ld-types';
3
+ import type { AnalyticsHandler } from '../../utils/types';
4
+ import type { CardAppearance } from '../../view/Card/types';
5
+ export interface LinkAction {
6
+ /**
7
+ * Unique ID for the action.
8
+ * @example `delete-action`
9
+ */
10
+ id: string;
11
+ /**
12
+ * Text to render for the action.
13
+ * @description Use this in tooltips and UI.
14
+ * @example `Delete`.
15
+ */
16
+ text: React.ReactNode;
17
+ /**
18
+ * Promise to invoke on triggering this action.
19
+ * @example Clicking on `Delete` leading to deletion of content.
20
+ */
21
+ invoke: () => Promise<any>;
22
+ }
23
+ export interface UseSmartLinkActionsOpts {
24
+ /**
25
+ * Smart Link URL for which actions will be invoked.
26
+ * @example https://start.atlassian.com
27
+ */
28
+ url: string;
29
+ /**
30
+ * Appearance under which these actions will be invoked.
31
+ * @example `block` for card views.
32
+ */
33
+ appearance: CardAppearance;
34
+ /**
35
+ * Callback for sending analytics events.
36
+ * @description Accepts an analytics payload and fires it to a system.
37
+ */
38
+ analyticsHandler: AnalyticsHandler;
39
+ /**
40
+ * Platform on which actions are being invoked.
41
+ * @default 'web'
42
+ */
43
+ platform?: JsonLd.Primitives.Platforms;
44
+ }
45
+ export declare function useSmartLinkActions({ url, appearance, analyticsHandler, platform, }: UseSmartLinkActionsOpts): LinkAction[];
@@ -22,8 +22,8 @@ export declare const connectFailedEvent: (definitionId?: string | undefined, ext
22
22
  export declare const trackAppAccountConnected: (definitionId?: string | undefined, extensionKey?: string | undefined) => AnalyticsPayload;
23
23
  export declare const uiAuthEvent: (display: CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => AnalyticsPayload;
24
24
  export declare const uiAuthAlternateAccountEvent: (display: CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => AnalyticsPayload;
25
- export declare const uiCardClickedEvent: (display: CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => AnalyticsPayload;
26
- export declare const uiActionClickedEvent: (extensionKey: string, actionType: string, display?: "embed" | "block" | "inline" | "preview" | undefined) => AnalyticsPayload;
25
+ export declare const uiCardClickedEvent: (display: CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined, isModifierKeyPressed?: boolean | undefined) => AnalyticsPayload;
26
+ export declare const uiActionClickedEvent: (extensionKey: string, actionType: string, display?: "embed" | "block" | "inline" | "preview" | "flexible" | undefined) => AnalyticsPayload;
27
27
  export declare const uiClosedAuthEvent: (display: CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => AnalyticsPayload;
28
28
  export declare const screenAuthPopupEvent: (definitionId?: string | undefined, extensionKey?: string | undefined) => AnalyticsPayload;
29
29
  export declare const uiRenderSuccessEvent: (display: CardInnerAppearance, definitionId?: string | undefined, extensionKey?: string | undefined) => AnalyticsPayload;
@@ -1,4 +1,9 @@
1
1
  import { JsonLd } from 'json-ld-types';
2
+ export declare const mockContext: {
3
+ readonly '@vocab': "https://www.w3.org/ns/activitystreams#";
4
+ readonly atlassian: "https://schema.atlassian.com/ns/vocabulary#";
5
+ readonly schema: "http://schema.org/";
6
+ };
2
7
  export declare const mocks: {
3
8
  success: JsonLd.Response<JsonLd.Data.BaseData>;
4
9
  notFound: JsonLd.Response<JsonLd.Data.BaseData>;
@@ -10,7 +10,7 @@ export declare type BlockCardProps = {
10
10
  authFlow?: CardAuthFlowOpts['authFlow'];
11
11
  handleAuthorize: (() => void) | undefined;
12
12
  handleErrorRetry: () => void;
13
- handlePreviewAnalytics: AnalyticsHandler;
13
+ handleAnalytics: AnalyticsHandler;
14
14
  handleInvoke: InvokeHandler;
15
15
  handleFrameClick: React.EventHandler<React.MouseEvent | React.KeyboardEvent>;
16
16
  isSelected?: boolean;
@@ -4,7 +4,7 @@ import { JsonLd } from 'json-ld-types';
4
4
  import { FlexibleUiOptions } from '../FlexibleCard/types';
5
5
  import { InlinePreloaderStyle } from '../types';
6
6
  export declare type CardAppearance = 'inline' | 'block' | 'embed';
7
- export declare type CardInnerAppearance = CardAppearance | 'preview';
7
+ export declare type CardInnerAppearance = CardAppearance | 'preview' | 'flexible';
8
8
  export declare type CardPlatform = JsonLd.Primitives.Platforms;
9
9
  export declare type OnResolveCallback = (data: {
10
10
  url?: string;
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import { BlockProps, ElementItem, ActionItem } from '../types';
2
3
  import { SmartLinkPosition, SmartLinkTheme } from '../../../../../constants';
3
4
  import { RetryOptions } from '../../../types';
@@ -11,4 +12,5 @@ export declare type TitleBlockProps = BlockProps & {
11
12
  theme?: SmartLinkTheme;
12
13
  text?: string;
13
14
  showActionOnHover?: boolean;
15
+ onClick?: React.EventHandler<React.MouseEvent | React.KeyboardEvent>;
14
16
  };
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import { SmartLinkSize, SmartLinkStatus, SmartLinkTheme } from '../../../../constants';
2
3
  import { RetryOptions } from '../../types';
3
4
  export declare type ContainerProps = {
@@ -9,4 +10,5 @@ export declare type ContainerProps = {
9
10
  status?: SmartLinkStatus;
10
11
  testId?: string;
11
12
  theme?: SmartLinkTheme;
13
+ onClick?: React.EventHandler<React.MouseEvent | React.KeyboardEvent>;
12
14
  };
@@ -1,6 +1,8 @@
1
+ /// <reference types="react" />
1
2
  import { ElementProps } from '../types';
2
3
  import { SmartLinkTheme } from '../../../../../constants';
3
4
  export declare type LinkProps = ElementProps & {
5
+ onClick?: React.EventHandler<React.MouseEvent | React.KeyboardEvent>;
4
6
  maxLines?: number;
5
7
  text?: string;
6
8
  theme?: SmartLinkTheme;
@@ -12,6 +12,7 @@ export declare type FlexibleCardProps = {
12
12
  testId?: string;
13
13
  ui?: FlexibleUiOptions;
14
14
  url: string;
15
+ onClick?: React.EventHandler<React.MouseEvent | React.KeyboardEvent>;
15
16
  };
16
17
  export declare type FlexibleUiOptions = {
17
18
  hideElevation?: boolean;
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@atlaskit/smart-card/hooks",
3
+ "main": "../dist/cjs/hooks.js",
4
+ "module": "../dist/esm/hooks.js",
5
+ "module:es2019": "../dist/es2019/hooks.js",
6
+ "types": "../dist/types/hooks.d.ts"
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "17.7.5",
3
+ "version": "17.7.8",
4
4
  "description": "Smart card component",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -111,6 +111,7 @@
111
111
  "react-dom": "^16.8.0",
112
112
  "react-intl-next": "npm:react-intl@^5.18.1",
113
113
  "react-test-renderer": "^16.8.0",
114
+ "ts-jest": "24.3.0",
114
115
  "typescript": "3.9.6",
115
116
  "xhr-mock": "^2.4.0"
116
117
  },
@@ -119,6 +120,7 @@
119
120
  "./in-product": "./src/in-product.ts",
120
121
  "./client": "./src/client/index.ts",
121
122
  "./types": "./src/types.ts",
123
+ "./hooks": "./src/hooks.ts",
122
124
  ".": "./src/index.ts"
123
125
  },
124
126
  "prettier": "@atlassian/atlassian-frontend-prettier-config-1.0.1"