@atlaskit/smart-card 44.23.3 → 44.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/extractors/action/extract-invoke-view-action.js +11 -1
  3. package/dist/cjs/extractors/flexible/actions/index.js +5 -2
  4. package/dist/cjs/extractors/flexible/extract-state.js +8 -5
  5. package/dist/cjs/extractors/flexible/index.js +6 -3
  6. package/dist/cjs/state/hooks-external/useSmartLinkActions.js +17 -2
  7. package/dist/cjs/utils/analytics/analytics.js +1 -1
  8. package/dist/cjs/view/CardWithUrl/component.js +4 -3
  9. package/dist/cjs/view/FlexibleCard/index.js +12 -2
  10. package/dist/cjs/view/LinkUrl/index.js +1 -1
  11. package/dist/es2019/extractors/action/extract-invoke-view-action.js +10 -1
  12. package/dist/es2019/extractors/flexible/actions/index.js +5 -1
  13. package/dist/es2019/extractors/flexible/extract-state.js +8 -4
  14. package/dist/es2019/extractors/flexible/index.js +6 -2
  15. package/dist/es2019/state/hooks-external/useSmartLinkActions.js +13 -2
  16. package/dist/es2019/utils/analytics/analytics.js +1 -1
  17. package/dist/es2019/view/CardWithUrl/component.js +4 -3
  18. package/dist/es2019/view/FlexibleCard/index.js +10 -3
  19. package/dist/es2019/view/LinkUrl/index.js +1 -1
  20. package/dist/esm/extractors/action/extract-invoke-view-action.js +11 -1
  21. package/dist/esm/extractors/flexible/actions/index.js +5 -2
  22. package/dist/esm/extractors/flexible/extract-state.js +8 -5
  23. package/dist/esm/extractors/flexible/index.js +6 -3
  24. package/dist/esm/state/hooks-external/useSmartLinkActions.js +17 -2
  25. package/dist/esm/utils/analytics/analytics.js +1 -1
  26. package/dist/esm/view/CardWithUrl/component.js +4 -3
  27. package/dist/esm/view/FlexibleCard/index.js +13 -3
  28. package/dist/esm/view/LinkUrl/index.js +1 -1
  29. package/dist/types/entry-points/card-types.d.ts +1 -1
  30. package/dist/types/extractors/action/extract-invoke-preview-action.d.ts +2 -1
  31. package/dist/types/extractors/action/extract-invoke-view-action.d.ts +5 -2
  32. package/dist/types/extractors/action/types.d.ts +1 -0
  33. package/dist/types/extractors/flexible/actions/index.d.ts +3 -1
  34. package/dist/types/extractors/flexible/extract-state.d.ts +2 -1
  35. package/dist/types/extractors/flexible/index.d.ts +1 -1
  36. package/dist/types/view/Card/types.d.ts +79 -25
  37. package/dist/types/view/CardWithUrl/types.d.ts +2 -3
  38. package/dist/types/view/FlexibleCard/types.d.ts +2 -0
  39. package/dist/types/view/types.d.ts +12 -0
  40. package/dist/types-ts4.5/entry-points/card-types.d.ts +1 -1
  41. package/dist/types-ts4.5/extractors/action/extract-invoke-preview-action.d.ts +2 -1
  42. package/dist/types-ts4.5/extractors/action/extract-invoke-view-action.d.ts +5 -2
  43. package/dist/types-ts4.5/extractors/action/types.d.ts +1 -0
  44. package/dist/types-ts4.5/extractors/flexible/actions/index.d.ts +3 -1
  45. package/dist/types-ts4.5/extractors/flexible/extract-state.d.ts +2 -1
  46. package/dist/types-ts4.5/extractors/flexible/index.d.ts +1 -1
  47. package/dist/types-ts4.5/view/Card/types.d.ts +79 -25
  48. package/dist/types-ts4.5/view/CardWithUrl/types.d.ts +2 -3
  49. package/dist/types-ts4.5/view/FlexibleCard/types.d.ts +2 -0
  50. package/dist/types-ts4.5/view/types.d.ts +12 -0
  51. package/package.json +7 -7
@@ -2,6 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
4
  import { extractLink } from '@atlaskit/link-extractors';
5
+ import { fg } from '@atlaskit/platform-feature-flags';
5
6
  import { CardAction } from '../../constants';
6
7
  import { getExtensionKey } from '../../state/helpers';
7
8
  import { canShowAction } from '../../utils/actions/can-show-action';
@@ -21,7 +22,7 @@ var toInvokeRequest = function toInvokeRequest(extensionKey, resourceIdentifiers
21
22
  details: details
22
23
  };
23
24
  };
24
- var extractAction = function extractAction(response, id, actionOptions, appearance, origin, fireEvent, resolve, isPreviewPanelAvailable, openPreviewPanel) {
25
+ var extractAction = function extractAction(response, id, actionOptions, appearance, origin, fireEvent, resolve, isPreviewPanelAvailable, openPreviewPanel, transformUrl) {
25
26
  var _action$dataRetrieval, _extractInvokePreview, _action$dataUpdateAct;
26
27
  var extensionKey = getExtensionKey(response);
27
28
  var data = response === null || response === void 0 ? void 0 : response.data;
@@ -37,7 +38,7 @@ var extractAction = function extractAction(response, id, actionOptions, appearan
37
38
  }
38
39
  var read = toInvokeRequest(extensionKey, action.resourceIdentifiers, (_action$dataRetrieval = action.dataRetrievalAction) === null || _action$dataRetrieval === void 0 ? void 0 : _action$dataRetrieval.name);
39
40
  var url = extractLink(data);
40
- var invokePreviewAction = response ? (_extractInvokePreview = extractInvokePreviewAction({
41
+ var invokePreviewAction = response ? (_extractInvokePreview = extractInvokePreviewAction(_objectSpread({
41
42
  actionOptions: actionOptions,
42
43
  appearance: appearance,
43
44
  fireEvent: fireEvent,
@@ -49,7 +50,9 @@ var extractAction = function extractAction(response, id, actionOptions, appearan
49
50
  response: response,
50
51
  isPreviewPanelAvailable: isPreviewPanelAvailable,
51
52
  openPreviewPanel: openPreviewPanel
52
- })) === null || _extractInvokePreview === void 0 ? void 0 : _extractInvokePreview.invokeAction : undefined;
53
+ }, fg('platform_smartlink_xpc_url_wrapping') ? {
54
+ transformUrl: transformUrl
55
+ } : undefined))) === null || _extractInvokePreview === void 0 ? void 0 : _extractInvokePreview.invokeAction : undefined;
53
56
  var details = {
54
57
  id: id,
55
58
  url: url,
@@ -61,7 +64,7 @@ var extractAction = function extractAction(response, id, actionOptions, appearan
61
64
  update: update
62
65
  } : undefined;
63
66
  };
64
- var extractState = function extractState(response, actionOptions, id, appearance, origin, fireEvent, resolve, isPreviewPanelAvailable, openPreviewPanel) {
67
+ var extractState = function extractState(response, actionOptions, id, appearance, origin, fireEvent, resolve, isPreviewPanelAvailable, openPreviewPanel, transformUrl) {
65
68
  if (!response || !response.data) {
66
69
  return;
67
70
  }
@@ -72,7 +75,7 @@ var extractState = function extractState(response, actionOptions, id, appearance
72
75
  if (!canShowAction(CardAction.ChangeStatusAction, actionOptions)) {
73
76
  return lozenge;
74
77
  }
75
- var action = extractAction(response, id, actionOptions, appearance, origin, fireEvent, resolve, isPreviewPanelAvailable, openPreviewPanel);
78
+ var action = extractAction(response, id, actionOptions, appearance, origin, fireEvent, resolve, isPreviewPanelAvailable, openPreviewPanel, fg('platform_smartlink_xpc_url_wrapping') ? transformUrl : undefined);
76
79
  return _objectSpread(_objectSpread({}, lozenge), {}, {
77
80
  action: action
78
81
  });
@@ -1,6 +1,6 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
- var _excluded = ["appearance", "fireEvent", "id", "onClick", "onAuxClick", "onContextMenu", "origin", "product", "resolve", "rovoConfig", "actionOptions", "response", "status", "aiSummaryConfig", "isPreviewPanelAvailable", "openPreviewPanel"];
3
+ var _excluded = ["appearance", "fireEvent", "id", "onClick", "onAuxClick", "onContextMenu", "origin", "product", "resolve", "rovoConfig", "actionOptions", "response", "status", "aiSummaryConfig", "isPreviewPanelAvailable", "openPreviewPanel", "transformUrl"];
4
4
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5
5
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6
6
  import { extractPersonOwnedBy, extractSmartLinkAri, extractSmartLinkAuthorGroup, extractSmartLinkCreatedBy, extractSmartLinkCreatedOn, extractSmartLinkModifiedBy, extractSmartLinkModifiedOn, extractSmartLinkUrl, extractType } from '@atlaskit/link-extractors';
@@ -34,6 +34,7 @@ var extractFlexibleUiContext = function extractFlexibleUiContext() {
34
34
  aiSummaryConfig = _ref.aiSummaryConfig,
35
35
  isPreviewPanelAvailable = _ref.isPreviewPanelAvailable,
36
36
  openPreviewPanel = _ref.openPreviewPanel,
37
+ transformUrl = _ref.transformUrl,
37
38
  props = _objectWithoutProperties(_ref, _excluded);
38
39
  if (!response) {
39
40
  return undefined;
@@ -58,7 +59,9 @@ var extractFlexibleUiContext = function extractFlexibleUiContext() {
58
59
  // Use the original URL in edge cases, such as short links for AI summary and copy link actions.
59
60
  isPreviewPanelAvailable: isPreviewPanelAvailable,
60
61
  openPreviewPanel: openPreviewPanel
61
- })),
62
+ }, fg('platform_smartlink_xpc_url_wrapping') ? {
63
+ transformUrl: transformUrl
64
+ } : undefined)),
62
65
  appliedToComponentsCount: extractAppliedToComponentsCount(data),
63
66
  assignedToGroup: extractPersonAssignedToAsArray(data),
64
67
  attachmentCount: extractAttachmentCount(data),
@@ -90,7 +93,7 @@ var extractFlexibleUiContext = function extractFlexibleUiContext() {
90
93
  snippet: extractSmartLinkSummary(response) || undefined,
91
94
  // Explicitly set here to remove an empty string
92
95
  sourceBranch: extractSourceBranch(data),
93
- state: extractState(response, actionOptions, id, appearance, origin, fireEvent, resolve, isPreviewPanelAvailable, openPreviewPanel),
96
+ state: extractState(response, actionOptions, id, appearance, origin, fireEvent, resolve, isPreviewPanelAvailable, openPreviewPanel, fg('platform_smartlink_xpc_url_wrapping') ? transformUrl : undefined),
94
97
  subscriberCount: extractSubscriberCount(data),
95
98
  subTasksProgress: extractSubTasksProgress(data),
96
99
  storyPoints: extractStoryPoints(data),
@@ -6,6 +6,7 @@ import { useMemo } from 'react';
6
6
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
7
7
  import uuid from 'uuid';
8
8
  import { useSmartLinkContext } from '@atlaskit/link-provider';
9
+ import { fg } from '@atlaskit/platform-feature-flags';
9
10
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
10
11
  import { useAnalyticsEvents } from '../../common/analytics/generated/use-analytics-events';
11
12
  import { extractInvokeDownloadAction } from '../../extractors/action/extract-invoke-download-action';
@@ -15,6 +16,7 @@ import { messages } from '../../messages';
15
16
  import { toAction } from '../../utils/actions/to-action';
16
17
  import useInvokeClientAction from '../hooks/use-invoke-client-action';
17
18
  import useResolve from '../hooks/use-resolve';
19
+ import { useSmartLinkCrossProductUrlWrapperGated } from '../hooks/use-smart-link-cross-product-url-wrapper';
18
20
  import { useSmartCardState as useLinkState } from '../store';
19
21
  export function useSmartLinkActions(_ref) {
20
22
  var url = _ref.url,
@@ -36,6 +38,9 @@ export function useSmartLinkActions(_ref) {
36
38
  fireEvent: fireEvent
37
39
  });
38
40
  var resolve = useResolve();
41
+ var appendCrossProductAnalyticsParams = useSmartLinkCrossProductUrlWrapperGated({
42
+ details: linkState.details
43
+ });
39
44
  if (expValEquals('platform_hover_card_preview_panel', 'cohort', 'test') && prefetch && !linkState.details) {
40
45
  resolve(url);
41
46
  }
@@ -51,7 +56,12 @@ export function useSmartLinkActions(_ref) {
51
56
  if (downloadActionProps) {
52
57
  actions.push(toAction(downloadActionProps, invokeClientAction, messages.download, 'download-content'));
53
58
  }
54
- var viewActionProps = extractInvokeViewAction(invokeParam);
59
+ var viewActionProps = fg('platform_smartlink_xpc_url_wrapping') ? extractInvokeViewAction(_objectSpread(_objectSpread({}, invokeParam), {}, {
60
+ transformUrl: function transformUrl() {
61
+ var destinationUrl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : url;
62
+ return appendCrossProductAnalyticsParams(destinationUrl);
63
+ }
64
+ })) : extractInvokeViewAction(invokeParam);
55
65
  if (viewActionProps) {
56
66
  actions.push(toAction(viewActionProps, invokeClientAction, messages.view, 'view-content'));
57
67
  }
@@ -60,7 +70,12 @@ export function useSmartLinkActions(_ref) {
60
70
  origin: origin,
61
71
  isPreviewPanelAvailable: isPreviewPanelAvailable,
62
72
  openPreviewPanel: openPreviewPanel
63
- }));
73
+ }, fg('platform_smartlink_xpc_url_wrapping') ? {
74
+ transformUrl: function transformUrl() {
75
+ var destinationUrl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : url;
76
+ return appendCrossProductAnalyticsParams(destinationUrl);
77
+ }
78
+ } : undefined));
64
79
  if (previewActionProps) {
65
80
  actions.push(toAction(previewActionProps.invokeAction, invokeClientAction, messages.preview_improved, 'preview-content'));
66
81
  }
@@ -4,7 +4,7 @@ export var ANALYTICS_CHANNEL = 'media';
4
4
  export var context = {
5
5
  componentName: 'smart-cards',
6
6
  packageName: "@atlaskit/smart-card" || '',
7
- packageVersion: "44.23.2" || ''
7
+ packageVersion: "44.23.4" || ''
8
8
  };
9
9
  export var TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
10
10
  TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
@@ -161,9 +161,10 @@ function Component(_ref) {
161
161
  // FIXME: preferredUrl should be rendered in the DOM anchor href instead of derived at click time
162
162
  var preferredUrl = getClickUrl(url, state.details);
163
163
  var destinationUrl = (_appendCrossProductAn = appendCrossProductAnalyticsParams(preferredUrl)) !== null && _appendCrossProductAn !== void 0 ? _appendCrossProductAn : preferredUrl;
164
-
165
- // FIXME: Consumer that handle click even themselves via callback won't have the decorated URL
166
- onClick === null || onClick === void 0 || onClick(event);
164
+ onClick === null || onClick === void 0 || onClick(event, {
165
+ url: url,
166
+ destinationUrl: destinationUrl
167
+ });
167
168
 
168
169
  // Check if the event is prevented via onClick callback
169
170
  var consumerPreventedNavigation = event.defaultPrevented && !isEventDefaultPrevented;
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
3
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
4
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
- import React, { useEffect, useMemo } from 'react';
5
+ import React, { useCallback, useEffect, useMemo } from 'react';
6
6
  import { useSmartLinkContext } from '@atlaskit/link-provider';
7
7
  import { fg } from '@atlaskit/platform-feature-flags';
8
8
  import UFOHoldLoad from '@atlaskit/react-ufo/load-hold';
@@ -13,6 +13,7 @@ import { FlexibleCardContext } from '../../state/flexible-ui-context';
13
13
  import { useAISummaryConfig } from '../../state/hooks/use-ai-summary-config';
14
14
  import useResolve from '../../state/hooks/use-resolve';
15
15
  import useRovoConfig from '../../state/hooks/use-rovo-config';
16
+ import { useSmartLinkCrossProductUrlWrapperGated } from '../../state/hooks/use-smart-link-cross-product-url-wrapper';
16
17
  import Container from './components/container';
17
18
  import { getContextByStatus } from './utils';
18
19
  var PENDING_LINK_STATUSES = [SmartLinkStatus.Pending, SmartLinkStatus.Resolving];
@@ -59,6 +60,14 @@ var FlexibleCard = function FlexibleCard(_ref) {
59
60
  var cardType = cardState.status,
60
61
  details = cardState.details;
61
62
  var status = cardType;
63
+ var appendCrossProductAnalyticsParams = useSmartLinkCrossProductUrlWrapperGated({
64
+ details: details
65
+ });
66
+ var transformUrlCallback = useCallback(function () {
67
+ var destinationUrl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : url;
68
+ return appendCrossProductAnalyticsParams(destinationUrl);
69
+ }, [appendCrossProductAnalyticsParams, url]);
70
+ var transformUrl = fg('platform_smartlink_xpc_url_wrapping') ? transformUrlCallback : undefined;
62
71
 
63
72
  // if we have placeholder state it means we can internally use it
64
73
  // as temporary resolved data until the actual data comes back as one of the final statuses
@@ -88,9 +97,10 @@ var FlexibleCard = function FlexibleCard(_ref) {
88
97
  status: placeholderCardState ? placeHolderStatus : status,
89
98
  url: url,
90
99
  isPreviewPanelAvailable: isPreviewPanelAvailable,
91
- openPreviewPanel: openPreviewPanel
100
+ openPreviewPanel: openPreviewPanel,
101
+ transformUrl: transformUrl
92
102
  }));
93
- }, [aiSummaryConfig, appearance, actionOptions, details, id, isPreviewPanelAvailable, onAuthorize, onClick, onAuxClick, onContextMenu, openPreviewPanel, origin, placeholderCardState, placeHolderStatus, product, renderers, resolve, rovoConfig, status, url, fireEvent]);
103
+ }, [aiSummaryConfig, appearance, actionOptions, details, id, isPreviewPanelAvailable, onAuthorize, onClick, onAuxClick, onContextMenu, openPreviewPanel, origin, placeholderCardState, placeHolderStatus, product, renderers, resolve, rovoConfig, status, transformUrl, url, fireEvent]);
94
104
  var flexibleCardContext = useMemo(function () {
95
105
  return {
96
106
  data: context,
@@ -12,7 +12,7 @@ import LinkWarningModal from './LinkWarningModal';
12
12
  import { useLinkWarningModal } from './LinkWarningModal/hooks/use-link-warning-modal';
13
13
  var PACKAGE_DATA = {
14
14
  packageName: "@atlaskit/smart-card",
15
- packageVersion: "44.23.2",
15
+ packageVersion: "44.23.4",
16
16
  componentName: 'linkUrl'
17
17
  };
18
18
  var LinkUrl = function LinkUrl(_ref) {
@@ -1 +1 @@
1
- export type { CardProps, CardAppearance, CardPlatform } from '../view/Card/types';
1
+ export type { CardProps, CardAppearance, CardPlatform, OnClickCallback } from '../view/Card/types';
@@ -2,7 +2,7 @@ import { type FireEventFunction } from '../../common/analytics/types';
2
2
  import { type InvokeClientActionProps } from '../../state/hooks/use-invoke-client-action/types';
3
3
  import { type AnalyticsOrigin } from '../../utils/types';
4
4
  import { type EmbedModalProps } from '../../view/EmbedModal/types';
5
- import { type ExtractClientActionsParam } from './types';
5
+ import { type ExtractClientActionsParam, type TransformUrlFn } from './types';
6
6
  export type ExtractInvokePreviewActionParam = ExtractClientActionsParam & {
7
7
  fireEvent?: FireEventFunction;
8
8
  isPreviewPanelAvailable?: (params: {
@@ -19,6 +19,7 @@ export type ExtractInvokePreviewActionParam = ExtractClientActionsParam & {
19
19
  url: string;
20
20
  }) => void;
21
21
  origin?: AnalyticsOrigin;
22
+ transformUrl?: TransformUrlFn;
22
23
  };
23
24
  type ExtractInvokePreviewActionReturn = {
24
25
  hasPreviewPanel?: boolean;
@@ -1,3 +1,6 @@
1
1
  import { type InvokeClientActionProps } from '../../state/hooks/use-invoke-client-action/types';
2
- import { type ExtractClientActionsParam } from './types';
3
- export declare const extractInvokeViewAction: ({ actionOptions, appearance, id, response }: ExtractClientActionsParam, force?: boolean) => InvokeClientActionProps | undefined;
2
+ import { type ExtractClientActionsParam, type TransformUrlFn } from './types';
3
+ export type ExtractInvokeViewActionParam = ExtractClientActionsParam & {
4
+ transformUrl?: TransformUrlFn;
5
+ };
6
+ export declare const extractInvokeViewAction: ({ actionOptions, appearance, transformUrl, id, response }: ExtractInvokeViewActionParam, force?: boolean) => InvokeClientActionProps | undefined;
@@ -1,6 +1,7 @@
1
1
  import type { JsonLd } from '@atlaskit/json-ld-types';
2
2
  import type { InternalCardActionOptions as CardActionOptions } from '../../view/Card/types';
3
3
  import type { FlexibleCardProps } from '../../view/FlexibleCard/types';
4
+ export type TransformUrlFn = (url?: string) => string | undefined;
4
5
  export type ExtractClientActionsParam = {
5
6
  actionOptions?: CardActionOptions;
6
7
  appearance?: FlexibleCardProps['appearance'];
@@ -6,6 +6,7 @@ import { type AISummaryConfig } from '../../../state/hooks/use-ai-summary-config
6
6
  import type { RovoConfig } from '../../../state/hooks/use-rovo-config';
7
7
  import { type AnalyticsOrigin } from '../../../utils/types';
8
8
  import { type InternalCardActionOptions as CardActionOptions, type CardInnerAppearance } from '../../../view/Card/types';
9
+ import { type TransformUrlFn } from '../../action/types';
9
10
  export type ExtractActionsParam = {
10
11
  actionOptions?: CardActionOptions;
11
12
  aiSummaryConfig?: AISummaryConfig;
@@ -28,6 +29,7 @@ export type ExtractActionsParam = {
28
29
  product?: ProductType;
29
30
  response: JsonLd.Response;
30
31
  rovoConfig?: RovoConfig;
32
+ transformUrl?: TransformUrlFn;
31
33
  url?: string;
32
34
  };
33
- export declare const extractFlexibleCardActions: ({ actionOptions, aiSummaryConfig, appearance, fireEvent, id, origin, product, response, rovoConfig, url, isPreviewPanelAvailable, openPreviewPanel, }: ExtractActionsParam) => FlexibleUiActions | undefined;
35
+ export declare const extractFlexibleCardActions: ({ actionOptions, aiSummaryConfig, appearance, fireEvent, id, origin, product, response, rovoConfig, transformUrl, url, isPreviewPanelAvailable, openPreviewPanel, }: ExtractActionsParam) => FlexibleUiActions | undefined;
@@ -3,6 +3,7 @@ import { type FireEventFunction } from '../../common/analytics/types';
3
3
  import { type ResolveFunction } from '../../state/hooks/use-resolve';
4
4
  import { type AnalyticsOrigin } from '../../utils/types';
5
5
  import { type InternalCardActionOptions as CardActionOptions, type CardInnerAppearance } from '../../view/Card/types';
6
+ import { type TransformUrlFn } from '../action/types';
6
7
  import { type LinkLozenge } from '../common/lozenge/types';
7
8
  declare const extractState: (response?: JsonLd.Response, actionOptions?: CardActionOptions, id?: string, appearance?: CardInnerAppearance, origin?: AnalyticsOrigin, fireEvent?: FireEventFunction, resolve?: ResolveFunction, isPreviewPanelAvailable?: (params: {
8
9
  ari: string;
@@ -14,5 +15,5 @@ declare const extractState: (response?: JsonLd.Response, actionOptions?: CardAct
14
15
  embedUrl?: string;
15
16
  };
16
17
  url: string;
17
- }) => void) => LinkLozenge | undefined;
18
+ }) => void, transformUrl?: TransformUrlFn) => LinkLozenge | undefined;
18
19
  export default extractState;
@@ -1,4 +1,4 @@
1
1
  import { type FlexibleUiDataContext } from '../../state/flexible-ui-context/types';
2
2
  import { type ExtractFlexibleUiDataContextParams } from '../../view/FlexibleCard/types';
3
- declare const extractFlexibleUiContext: ({ appearance, fireEvent, id, onClick, onAuxClick, onContextMenu, origin, product, resolve, rovoConfig, actionOptions, response, status, aiSummaryConfig, isPreviewPanelAvailable, openPreviewPanel, ...props }?: Partial<ExtractFlexibleUiDataContextParams>) => FlexibleUiDataContext | undefined;
3
+ declare const extractFlexibleUiContext: ({ appearance, fireEvent, id, onClick, onAuxClick, onContextMenu, origin, product, resolve, rovoConfig, actionOptions, response, status, aiSummaryConfig, isPreviewPanelAvailable, openPreviewPanel, transformUrl, ...props }?: Partial<ExtractFlexibleUiDataContextParams>) => FlexibleUiDataContext | undefined;
4
4
  export default extractFlexibleUiContext;
@@ -6,7 +6,7 @@ import { type FrameStyle } from '../EmbedCard/types';
6
6
  import type { EmbedModalSize } from '../EmbedModal/types';
7
7
  import { type FlexibleUiOptions } from '../FlexibleCard/types';
8
8
  import { type HoverPreviewOptions } from '../HoverCard/types';
9
- import { type InlinePreloaderStyle, type OnErrorCallback } from '../types';
9
+ import { type EventHandlerWithData, type InlinePreloaderStyle, type OnErrorCallback } from '../types';
10
10
  export type { CardAppearance, CardPlatform };
11
11
  export type CardInnerAppearance = CardAppearance | 'embedPreview' | 'flexible' | 'hoverCardPreview' | 'url';
12
12
  export type EmbedIframeUrlType = 'href' | 'interactiveHref';
@@ -77,6 +77,83 @@ interface HoverPreviewProps extends ActionProps {
77
77
  */
78
78
  showHoverPreview?: boolean;
79
79
  }
80
+ export type OnClickData = {
81
+ /**
82
+ * The destination URL that Smart Link resolved and will navigate to.
83
+ * This may differ from the original `url` prop if Smart Link applied
84
+ * cross-product analytics parameters or resolved a preferred URL from metadata.
85
+ */
86
+ destinationUrl?: string;
87
+ /**
88
+ * The original `url` prop given to the component
89
+ * and the key to access link metadata in SmartCardProvider.
90
+ */
91
+ url?: string;
92
+ };
93
+ /**
94
+ * Callback type for click events on Smart Links.
95
+ *
96
+ * Equivalent to:
97
+ * (event: React.MouseEvent | React.KeyboardEvent, data?: OnClickData) => void
98
+ *
99
+ * Uses `EventHandlerWithData` (a bivariant method type) so that consumers can pass
100
+ * callbacks with narrower event types (e.g. `React.MouseEvent<HTMLElement>`) without
101
+ * TypeScript errors — the same technique React uses internally for `React.EventHandler`.
102
+ *
103
+ * The optional `data` argument provides additional context:
104
+ * - `data.destinationUrl` — the URL Smart Link resolved and will navigate to.
105
+ * - `data.url` — the original `url` prop passed to the component.
106
+ *
107
+ * Use this type when typing your own click handler variable or function outside JSX:
108
+ * @example
109
+ * const handleClick: OnClickCallback = (event, data) => {
110
+ * event.preventDefault();
111
+ * navigate(data?.destinationUrl ?? fallbackUrl);
112
+ * };
113
+ */
114
+ export type OnClickCallback = EventHandlerWithData<React.MouseEvent | React.KeyboardEvent, OnClickData>;
115
+ interface CardEventProps {
116
+ /**
117
+ * A React component responsible for returning a fallback UI when smart link fails to render because of uncaught errors.
118
+ */
119
+ fallbackComponent?: React.ComponentType;
120
+ /**
121
+ * A callback function triggered when a Smart Link is clicked.
122
+ *
123
+ * When defined, the default browser navigation is prevented and your handler
124
+ * is responsible for navigation — except for Flexible Card, which always opens
125
+ * the link and then calls the callback.
126
+ *
127
+ * The optional second argument `data` provides additional context about the click:
128
+ * - `data.destinationUrl` — the resolved URL Smart Link will navigate to.
129
+ * This may differ from the original `url` prop if Smart Link resolved a
130
+ * preferred URL from metadata or appended analytics parameters.
131
+ * - `data.url` — the original `url` prop passed to the component.
132
+ *
133
+ * @example
134
+ * // Basic usage
135
+ * onClick={(e) => { e.preventDefault(); window.location.href = myUrl; }}
136
+ *
137
+ * // With destination URL
138
+ * onClick={(e, data) => { navigate(data?.destinationUrl ?? url); }}
139
+ */
140
+ onClick?: OnClickCallback;
141
+ /**
142
+ * A callback function currently invoked in two cases:
143
+ * 1. When the `CardState.status` is one of `ErrorCardType`. "err" property in argument will be undefined in this case
144
+ * This does not mean that smart card failed to render.
145
+ * 2. When there is any unhandled error inside smart card while rendering, resulting in failure to render smart card successfully.
146
+ * "err" property in argument will be provided in this case.
147
+ * Presence of an err property indicates that the client should either render their own fallback
148
+ * or provide a fallbackComponent prop which will be rendered instead smart card component.
149
+ * If fallbackComponent is not provided, smart card will render null
150
+ */
151
+ onError?: OnErrorCallback;
152
+ /**
153
+ * A callback function after the url is resolved into smart card.
154
+ */
155
+ onResolve?: OnResolveCallback;
156
+ }
80
157
  export interface BaseCardProps {
81
158
  /**
82
159
  * Define smart card default appearance.
@@ -100,10 +177,6 @@ export interface BaseCardProps {
100
177
  * This prop allows smartlinks inside of editor to bypass that as they have other ways to open Preview panel.
101
178
  */
102
179
  disablePreviewPanel?: boolean;
103
- /**
104
- * A React component responsible for returning a fallback UI when smart link fails to render because of uncaught errors.
105
- */
106
- fallbackComponent?: React.ComponentType;
107
180
  /**
108
181
  * Unique id for smart link used in analytics.
109
182
  */
@@ -112,25 +185,6 @@ export interface BaseCardProps {
112
185
  * Show selected state of smart link.
113
186
  */
114
187
  isSelected?: boolean;
115
- /**
116
- * A callback function after a link is clicked.
117
- */
118
- onClick?: React.EventHandler<React.MouseEvent | React.KeyboardEvent>;
119
- /**
120
- * A callback function currently invoked in two cases:
121
- * 1. When the `CardState.status` is one of `ErrorCardType`. "err" property in argument will be undefined in this case
122
- * This does not mean that smart card failed to render.
123
- * 2. When there is any unhandled error inside smart card while rendering, resulting in failure to render smart card successfully.
124
- * "err" property in argument will be provided in this case.
125
- * Presence of an err property indicates that the client should either render their own fallback
126
- * or provide a fallbackComponent prop which will be rendered instead smart card component.
127
- * If fallbackComponent is not provided, smart card will render null
128
- */
129
- onError?: OnErrorCallback;
130
- /**
131
- * A callback function after the url is resolved into smart card.
132
- */
133
- onResolve?: OnResolveCallback;
134
188
  /**
135
189
  * String to be displayed while the Card component is (lazy)loading.
136
190
  */
@@ -211,5 +265,5 @@ export interface FlexibleProps extends ActionProps, HoverPreviewProps {
211
265
  children?: React.ReactNode;
212
266
  ui?: FlexibleUiOptions;
213
267
  }
214
- export interface CardProps extends BaseCardProps, InlineProps, BlockProps, EmbedProps, FlexibleProps, WithAnalyticsEventsProps {
268
+ export interface CardProps extends BaseCardProps, CardEventProps, InlineProps, BlockProps, EmbedProps, FlexibleProps, WithAnalyticsEventsProps {
215
269
  }
@@ -1,6 +1,5 @@
1
- import { type EventHandler, type KeyboardEvent, type MouseEvent } from 'react';
2
1
  import type { SmartLinkResponse } from '@atlaskit/linking-types';
3
- import type { CardAppearance, CardPlatform, EmbedIframeUrlType, InternalCardActionOptions, OnResolveCallback } from '../Card/types';
2
+ import type { CardAppearance, CardPlatform, EmbedIframeUrlType, InternalCardActionOptions, OnClickCallback, OnResolveCallback } from '../Card/types';
4
3
  import { type FrameStyle } from '../EmbedCard/types';
5
4
  import { type FlexibleUiOptions } from '../FlexibleCard/types';
6
5
  import { type HoverPreviewOptions } from '../HoverCard/types';
@@ -25,7 +24,7 @@ export type CardWithUrlContentProps = {
25
24
  inlinePreloaderStyle?: InlinePreloaderStyle;
26
25
  isHovered?: boolean;
27
26
  isSelected?: boolean;
28
- onClick?: EventHandler<MouseEvent | KeyboardEvent>;
27
+ onClick?: OnClickCallback;
29
28
  onError?: OnErrorCallback;
30
29
  onResolve?: OnResolveCallback;
31
30
  placeholder?: string;
@@ -4,6 +4,7 @@ import { type CardState, type ProductType } from '@atlaskit/linking-common';
4
4
  import { type SmartLinkResponse } from '@atlaskit/linking-types';
5
5
  import { type FireEventFunction } from '../../common/analytics/types';
6
6
  import { type SmartLinkSize, type SmartLinkStatus, type SmartLinkTheme } from '../../constants';
7
+ import type { TransformUrlFn } from '../../extractors/action/types';
7
8
  import { type AISummaryConfig } from '../../state/hooks/use-ai-summary-config/types';
8
9
  import { type ResolveFunction } from '../../state/hooks/use-resolve';
9
10
  import type { RovoConfig } from '../../state/hooks/use-rovo-config';
@@ -197,6 +198,7 @@ export type ExtractFlexibleUiDataContextParams = Pick<FlexibleCardProps, 'appear
197
198
  response?: SmartLinkResponse;
198
199
  rovoConfig?: RovoConfig;
199
200
  status?: SmartLinkStatus;
201
+ transformUrl?: TransformUrlFn;
200
202
  };
201
203
  /**
202
204
  * Mark a specific props in the type as optional.
@@ -32,3 +32,15 @@ export type OnErrorCallback = (data: {
32
32
  status: Extract<CardType, ErrorCardType>;
33
33
  url: string;
34
34
  }) => void;
35
+ /**
36
+ * The method-in-object pattern (extracting `handler` via indexed access) is used intentionally
37
+ * to replicate TypeScript's bivariant method parameter checking — the same technique React uses
38
+ * internally for `React.EventHandler`. This allows consumers to pass callbacks with narrower
39
+ * event types (e.g. `React.MouseEvent<HTMLElement>`) without TypeScript errors, while still
40
+ * enabling callers inside Smart Links to pass the optional `data` second argument.
41
+ *
42
+ * See: https://www.typescriptlang.org/docs/handbook/2/functions.html#function-compatibility
43
+ */
44
+ export type EventHandlerWithData<TEvent extends React.SyntheticEvent<any>, TData extends object> = {
45
+ bivarianceHack(event: TEvent, data?: TData): void;
46
+ }['bivarianceHack'];
@@ -1 +1 @@
1
- export type { CardProps, CardAppearance, CardPlatform } from '../view/Card/types';
1
+ export type { CardProps, CardAppearance, CardPlatform, OnClickCallback } from '../view/Card/types';
@@ -2,7 +2,7 @@ import { type FireEventFunction } from '../../common/analytics/types';
2
2
  import { type InvokeClientActionProps } from '../../state/hooks/use-invoke-client-action/types';
3
3
  import { type AnalyticsOrigin } from '../../utils/types';
4
4
  import { type EmbedModalProps } from '../../view/EmbedModal/types';
5
- import { type ExtractClientActionsParam } from './types';
5
+ import { type ExtractClientActionsParam, type TransformUrlFn } from './types';
6
6
  export type ExtractInvokePreviewActionParam = ExtractClientActionsParam & {
7
7
  fireEvent?: FireEventFunction;
8
8
  isPreviewPanelAvailable?: (params: {
@@ -19,6 +19,7 @@ export type ExtractInvokePreviewActionParam = ExtractClientActionsParam & {
19
19
  url: string;
20
20
  }) => void;
21
21
  origin?: AnalyticsOrigin;
22
+ transformUrl?: TransformUrlFn;
22
23
  };
23
24
  type ExtractInvokePreviewActionReturn = {
24
25
  hasPreviewPanel?: boolean;
@@ -1,3 +1,6 @@
1
1
  import { type InvokeClientActionProps } from '../../state/hooks/use-invoke-client-action/types';
2
- import { type ExtractClientActionsParam } from './types';
3
- export declare const extractInvokeViewAction: ({ actionOptions, appearance, id, response }: ExtractClientActionsParam, force?: boolean) => InvokeClientActionProps | undefined;
2
+ import { type ExtractClientActionsParam, type TransformUrlFn } from './types';
3
+ export type ExtractInvokeViewActionParam = ExtractClientActionsParam & {
4
+ transformUrl?: TransformUrlFn;
5
+ };
6
+ export declare const extractInvokeViewAction: ({ actionOptions, appearance, transformUrl, id, response }: ExtractInvokeViewActionParam, force?: boolean) => InvokeClientActionProps | undefined;
@@ -1,6 +1,7 @@
1
1
  import type { JsonLd } from '@atlaskit/json-ld-types';
2
2
  import type { InternalCardActionOptions as CardActionOptions } from '../../view/Card/types';
3
3
  import type { FlexibleCardProps } from '../../view/FlexibleCard/types';
4
+ export type TransformUrlFn = (url?: string) => string | undefined;
4
5
  export type ExtractClientActionsParam = {
5
6
  actionOptions?: CardActionOptions;
6
7
  appearance?: FlexibleCardProps['appearance'];
@@ -6,6 +6,7 @@ import { type AISummaryConfig } from '../../../state/hooks/use-ai-summary-config
6
6
  import type { RovoConfig } from '../../../state/hooks/use-rovo-config';
7
7
  import { type AnalyticsOrigin } from '../../../utils/types';
8
8
  import { type InternalCardActionOptions as CardActionOptions, type CardInnerAppearance } from '../../../view/Card/types';
9
+ import { type TransformUrlFn } from '../../action/types';
9
10
  export type ExtractActionsParam = {
10
11
  actionOptions?: CardActionOptions;
11
12
  aiSummaryConfig?: AISummaryConfig;
@@ -28,6 +29,7 @@ export type ExtractActionsParam = {
28
29
  product?: ProductType;
29
30
  response: JsonLd.Response;
30
31
  rovoConfig?: RovoConfig;
32
+ transformUrl?: TransformUrlFn;
31
33
  url?: string;
32
34
  };
33
- export declare const extractFlexibleCardActions: ({ actionOptions, aiSummaryConfig, appearance, fireEvent, id, origin, product, response, rovoConfig, url, isPreviewPanelAvailable, openPreviewPanel, }: ExtractActionsParam) => FlexibleUiActions | undefined;
35
+ export declare const extractFlexibleCardActions: ({ actionOptions, aiSummaryConfig, appearance, fireEvent, id, origin, product, response, rovoConfig, transformUrl, url, isPreviewPanelAvailable, openPreviewPanel, }: ExtractActionsParam) => FlexibleUiActions | undefined;
@@ -3,6 +3,7 @@ import { type FireEventFunction } from '../../common/analytics/types';
3
3
  import { type ResolveFunction } from '../../state/hooks/use-resolve';
4
4
  import { type AnalyticsOrigin } from '../../utils/types';
5
5
  import { type InternalCardActionOptions as CardActionOptions, type CardInnerAppearance } from '../../view/Card/types';
6
+ import { type TransformUrlFn } from '../action/types';
6
7
  import { type LinkLozenge } from '../common/lozenge/types';
7
8
  declare const extractState: (response?: JsonLd.Response, actionOptions?: CardActionOptions, id?: string, appearance?: CardInnerAppearance, origin?: AnalyticsOrigin, fireEvent?: FireEventFunction, resolve?: ResolveFunction, isPreviewPanelAvailable?: (params: {
8
9
  ari: string;
@@ -14,5 +15,5 @@ declare const extractState: (response?: JsonLd.Response, actionOptions?: CardAct
14
15
  embedUrl?: string;
15
16
  };
16
17
  url: string;
17
- }) => void) => LinkLozenge | undefined;
18
+ }) => void, transformUrl?: TransformUrlFn) => LinkLozenge | undefined;
18
19
  export default extractState;
@@ -1,4 +1,4 @@
1
1
  import { type FlexibleUiDataContext } from '../../state/flexible-ui-context/types';
2
2
  import { type ExtractFlexibleUiDataContextParams } from '../../view/FlexibleCard/types';
3
- declare const extractFlexibleUiContext: ({ appearance, fireEvent, id, onClick, onAuxClick, onContextMenu, origin, product, resolve, rovoConfig, actionOptions, response, status, aiSummaryConfig, isPreviewPanelAvailable, openPreviewPanel, ...props }?: Partial<ExtractFlexibleUiDataContextParams>) => FlexibleUiDataContext | undefined;
3
+ declare const extractFlexibleUiContext: ({ appearance, fireEvent, id, onClick, onAuxClick, onContextMenu, origin, product, resolve, rovoConfig, actionOptions, response, status, aiSummaryConfig, isPreviewPanelAvailable, openPreviewPanel, transformUrl, ...props }?: Partial<ExtractFlexibleUiDataContextParams>) => FlexibleUiDataContext | undefined;
4
4
  export default extractFlexibleUiContext;