@atlaskit/smart-card 44.25.1 → 44.26.1

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 (48) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/cjs/__tests__/vr-tests/__snapshots__/inline-card/inline-card-unauthorised-with-social-proof-in-narrow-container--default--platform-lp-social-proof-inline-overflow-bug-false.png +3 -0
  3. package/dist/cjs/__tests__/vr-tests/__snapshots__/inline-card/inline-card-unauthorised-with-social-proof-in-narrow-container--default--platform-lp-social-proof-inline-overflow-bug-true.png +3 -0
  4. package/dist/cjs/entry-points/hook-use-smart-link-destination-url.js +12 -0
  5. package/dist/cjs/state/hooks/use-destination-url/index.js +39 -0
  6. package/dist/cjs/state/hooks/use-smart-link-cross-product-url-wrapper/index.js +2 -2
  7. package/dist/cjs/utils/analytics/analytics.js +1 -1
  8. package/dist/cjs/view/CardWithUrl/component.js +30 -9
  9. package/dist/cjs/view/HoverCard/components/HoverCardComponent.js +2 -1
  10. package/dist/cjs/view/InlineCard/UnauthorisedView/index.compiled.css +6 -1
  11. package/dist/cjs/view/InlineCard/UnauthorisedView/index.js +11 -5
  12. package/dist/cjs/view/InlineCard/common/action-button/index.compiled.css +2 -0
  13. package/dist/cjs/view/InlineCard/common/action-button/index.js +2 -1
  14. package/dist/cjs/view/LinkUrl/index.js +1 -1
  15. package/dist/es2019/__tests__/vr-tests/__snapshots__/inline-card/inline-card-unauthorised-with-social-proof-in-narrow-container--default--platform-lp-social-proof-inline-overflow-bug-false.png +3 -0
  16. package/dist/es2019/__tests__/vr-tests/__snapshots__/inline-card/inline-card-unauthorised-with-social-proof-in-narrow-container--default--platform-lp-social-proof-inline-overflow-bug-true.png +3 -0
  17. package/dist/es2019/entry-points/hook-use-smart-link-destination-url.js +1 -0
  18. package/dist/es2019/state/hooks/use-destination-url/index.js +32 -0
  19. package/dist/es2019/state/hooks/use-smart-link-cross-product-url-wrapper/index.js +1 -1
  20. package/dist/es2019/utils/analytics/analytics.js +1 -1
  21. package/dist/es2019/view/CardWithUrl/component.js +30 -9
  22. package/dist/es2019/view/HoverCard/components/HoverCardComponent.js +6 -0
  23. package/dist/es2019/view/InlineCard/UnauthorisedView/index.compiled.css +6 -1
  24. package/dist/es2019/view/InlineCard/UnauthorisedView/index.js +11 -5
  25. package/dist/es2019/view/InlineCard/common/action-button/index.compiled.css +2 -0
  26. package/dist/es2019/view/InlineCard/common/action-button/index.js +2 -1
  27. package/dist/es2019/view/LinkUrl/index.js +1 -1
  28. package/dist/esm/__tests__/vr-tests/__snapshots__/inline-card/inline-card-unauthorised-with-social-proof-in-narrow-container--default--platform-lp-social-proof-inline-overflow-bug-false.png +3 -0
  29. package/dist/esm/__tests__/vr-tests/__snapshots__/inline-card/inline-card-unauthorised-with-social-proof-in-narrow-container--default--platform-lp-social-proof-inline-overflow-bug-true.png +3 -0
  30. package/dist/esm/entry-points/hook-use-smart-link-destination-url.js +1 -0
  31. package/dist/esm/state/hooks/use-destination-url/index.js +34 -0
  32. package/dist/esm/state/hooks/use-smart-link-cross-product-url-wrapper/index.js +1 -1
  33. package/dist/esm/utils/analytics/analytics.js +1 -1
  34. package/dist/esm/view/CardWithUrl/component.js +30 -9
  35. package/dist/esm/view/HoverCard/components/HoverCardComponent.js +2 -1
  36. package/dist/esm/view/InlineCard/UnauthorisedView/index.compiled.css +6 -1
  37. package/dist/esm/view/InlineCard/UnauthorisedView/index.js +11 -5
  38. package/dist/esm/view/InlineCard/common/action-button/index.compiled.css +2 -0
  39. package/dist/esm/view/InlineCard/common/action-button/index.js +2 -1
  40. package/dist/esm/view/LinkUrl/index.js +1 -1
  41. package/dist/types/entry-points/hook-use-smart-link-destination-url.d.ts +1 -0
  42. package/dist/types/state/hooks/use-destination-url/index.d.ts +1 -0
  43. package/dist/types/state/hooks/use-smart-link-cross-product-url-wrapper/index.d.ts +1 -1
  44. package/dist/types-ts4.5/entry-points/hook-use-smart-link-destination-url.d.ts +1 -0
  45. package/dist/types-ts4.5/state/hooks/use-destination-url/index.d.ts +1 -0
  46. package/dist/types-ts4.5/state/hooks/use-smart-link-cross-product-url-wrapper/index.d.ts +1 -1
  47. package/hook/use-smart-link-destination-url/package.json +17 -0
  48. package/package.json +6 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @atlaskit/smart-card
2
2
 
3
+ ## 44.26.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`299e30381fd33`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/299e30381fd33) -
8
+ Update anchor href with cross-product analytics
9
+ - [`6d0485dce81c4`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/6d0485dce81c4) -
10
+ Internal: updated to the new `@atlaskit/top-layer` `Popover`/`Dialog` behaviour where the host
11
+ element unmounts after the exit animation completes. No consumer action required.
12
+ - Updated dependencies
13
+
14
+ ## 44.26.0
15
+
16
+ ### Minor Changes
17
+
18
+ - [`92da883bae00d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/92da883bae00d) -
19
+ Add `useSmartLinkDestinationUrl` hook via new entry point
20
+ `@atlaskit/smart-card/hook/use-smart-link-destination-url`.
21
+
22
+ The hook resolves the XPC-wrapped destination URL for a given Smart Link URL behind the
23
+ `platform_smartlink_xpc_url_wrapping` feature gate. When the gate is off or the link has not yet
24
+ resolved, it falls back gracefully to the original URL. This enables consumers (e.g. editor
25
+ toolbar and overlays) to open the cross-product-parameter-enriched URL without re-implementing
26
+ SmartCard's internal URL resolution logic.
27
+
28
+ ### Patch Changes
29
+
30
+ - [`9b6eb080bfa56`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9b6eb080bfa56) -
31
+ Keep inline Smart Link social proof CTAs together in narrow containers.
32
+
33
+ All changes behind feature gate: platform_lp_social_proof_inline_overflow_bug. No public API
34
+ change.
35
+
3
36
  ## 44.25.1
4
37
 
5
38
  ### Patch Changes
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7e92f235ef67cfff425c2768c61c1501f8d5daa6e0418075997c0de015ea18b2
3
+ size 35855
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1ee2641306bded4b5e90d1b509fa83e697a55b5eddb2bda5480fc7c50b0ddcf2
3
+ size 36106
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "useSmartLinkDestinationUrl", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _useDestinationUrl.useDestinationUrl;
10
+ }
11
+ });
12
+ var _useDestinationUrl = require("../state/hooks/use-destination-url");
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useDestinationUrl = void 0;
7
+ var _platformFeatureFlagsReact = require("@atlaskit/platform-feature-flags-react");
8
+ var _helpers = require("../../helpers");
9
+ var _store = require("../../store");
10
+ var _useSmartLinkCrossProductUrlWrapper = require("../use-smart-link-cross-product-url-wrapper");
11
+ /**
12
+ * Returns the resolved destination URL for a Smart Link, with cross-product analytics
13
+ * parameters appended when the `platform_smartlink_xpc_url_wrapping` feature gate is enabled.
14
+ *
15
+ * This is the same URL that SmartCard would navigate to when clicked. Use this as an `href`
16
+ * wherever you render a link to a Smart Link URL outside of the SmartCard component itself
17
+ * (e.g. toolbar buttons, overlays).
18
+ *
19
+ * Falls back to the raw `url` when:
20
+ * - The link has not yet resolved
21
+ * - The feature gate is disabled
22
+ * - The link is not a first-party Atlassian link
23
+ *
24
+ * @example
25
+ * const href = useSmartLinkDestinationUrl(url);
26
+ *
27
+ * Use as <a href={href} target="_blank">Open link</a>
28
+ */
29
+ var useDestinationUrlImplementation = function useDestinationUrlImplementation(url) {
30
+ var state = (0, _store.useSmartCardState)(url);
31
+ var appendCrossProductAnalyticsParams = (0, _useSmartLinkCrossProductUrlWrapper.useSmartLinkCrossProductUrlWrapper)({
32
+ details: state.details
33
+ });
34
+ var resolvedUrl = (0, _helpers.getClickUrl)(url, state.details);
35
+ return appendCrossProductAnalyticsParams(resolvedUrl);
36
+ };
37
+ var useDestinationUrl = exports.useDestinationUrl = (0, _platformFeatureFlagsReact.functionWithFG)('platform_smartlink_xpc_url_wrapping', useDestinationUrlImplementation, function (url) {
38
+ return url;
39
+ });
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.useSmartLinkCrossProductUrlWrapperGated = exports.getIsFirstPartyLink = void 0;
7
+ exports.useSmartLinkCrossProductUrlWrapperGated = exports.useSmartLinkCrossProductUrlWrapper = exports.getIsFirstPartyLink = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _react = require("react");
10
10
  var _useCrossProductUrlWrapper = require("@atlaskit/analytics-cross-product/useCrossProductUrlWrapper");
@@ -24,7 +24,7 @@ var identityUrlWrapper = function identityUrlWrapper(url) {
24
24
  var useSmartLinkCrossProductUrlWrapperFallback = function useSmartLinkCrossProductUrlWrapperFallback(_args) {
25
25
  return identityUrlWrapper;
26
26
  };
27
- var useSmartLinkCrossProductUrlWrapper = function useSmartLinkCrossProductUrlWrapper(_ref) {
27
+ var useSmartLinkCrossProductUrlWrapper = exports.useSmartLinkCrossProductUrlWrapper = function useSmartLinkCrossProductUrlWrapper(_ref) {
28
28
  var _effectiveProduct$toL;
29
29
  var details = _ref.details;
30
30
  var _useSmartLinkContext = (0, _linkProvider.useSmartLinkContext)(),
@@ -11,7 +11,7 @@ var ANALYTICS_CHANNEL = exports.ANALYTICS_CHANNEL = 'media';
11
11
  var context = exports.context = {
12
12
  componentName: 'smart-cards',
13
13
  packageName: "@atlaskit/smart-card" || '',
14
- packageVersion: "44.25.0" || ''
14
+ packageVersion: "44.26.0" || ''
15
15
  };
16
16
  var TrackQuickActionType = exports.TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
17
17
  TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
@@ -112,6 +112,21 @@ function Component(_ref) {
112
112
 
113
113
  // Shared scope guard for all 3P-click handlers.
114
114
  var shouldFire3PClickEvent = thirdPartyARI && thirdPartyARI.startsWith(thirdPartyARIPrefix) && (0, _helpers.getClickUrl)(url, state.details) === url && fire3PClickEvent && (0, _platformFeatureFlags.fg)('platform_smartlink_3pclick_analytics');
115
+ var getDestinationUrl = (0, _react.useCallback)(function () {
116
+ var _getClickUrl, _appendCrossProductAn;
117
+ var preferredUrl = (_getClickUrl = (0, _helpers.getClickUrl)(url, state.details)) !== null && _getClickUrl !== void 0 ? _getClickUrl : url;
118
+ return (_appendCrossProductAn = appendCrossProductAnalyticsParams(preferredUrl)) !== null && _appendCrossProductAn !== void 0 ? _appendCrossProductAn : preferredUrl;
119
+ }, [appendCrossProductAnalyticsParams, state.details, url]);
120
+ var updateAnchorHref = (0, _react.useCallback)(function (event, destinationUrl) {
121
+ if (!(event.currentTarget instanceof HTMLAnchorElement)) {
122
+ return;
123
+ }
124
+
125
+ // FIXME: destinationUrl should be rendered in the DOM anchor href instead of derived at click time
126
+ // href is only defined when currentTarget is an anchor element.
127
+ // Update the anchor href so the browser context menu uses the decorated URL.
128
+ event.currentTarget.href = destinationUrl;
129
+ }, []);
115
130
 
116
131
  // Setup UI handlers.
117
132
  var handleClickWrapper = (0, _react.useCallback)(function (event) {
@@ -131,7 +146,6 @@ function Component(_ref) {
131
146
  exposure: true
132
147
  });
133
148
  if ((0, _platformFeatureFlags.fg)('platform_smartlink_xpc_url_wrapping')) {
134
- var _appendCrossProductAn;
135
149
  // FIXME: InlineCard, BlockCard and EmbedCard call event.preventDefault() internally
136
150
  // before the event bubbles up to this handler. This forces us to snapshot
137
151
  // event.defaultPrevented before calling onClick to detect whether the consumer
@@ -163,16 +177,14 @@ function Component(_ref) {
163
177
  });
164
178
  return;
165
179
  }
180
+ var destinationUrl = getDestinationUrl();
181
+ updateAnchorHref(event, destinationUrl);
166
182
 
167
183
  // For FlexibleCard, read target from the clicked anchor element (e.g. _blank for links
168
184
  // rendered with explicit target). For classic cards, default to _self
169
185
  var _getAnchorAttributesF = (0, _clickHelpers.getAnchorAttributesFromEvent)(event),
170
186
  anchorTarget = _getAnchorAttributesF.target;
171
187
  var target = (0, _utils.isSpecialEvent)(event) ? '_blank' : isFlexibleUi ? anchorTarget : '_self';
172
-
173
- // FIXME: preferredUrl should be rendered in the DOM anchor href instead of derived at click time
174
- var preferredUrl = (0, _helpers.getClickUrl)(url, state.details);
175
- var destinationUrl = (_appendCrossProductAn = appendCrossProductAnalyticsParams(preferredUrl)) !== null && _appendCrossProductAn !== void 0 ? _appendCrossProductAn : preferredUrl;
176
188
  onClick === null || onClick === void 0 || onClick(event, {
177
189
  url: url,
178
190
  destinationUrl: destinationUrl
@@ -244,7 +256,7 @@ function Component(_ref) {
244
256
  (0, _click.fireLinkClickedEvent)(createAnalyticsEvent)(event);
245
257
  }
246
258
  }
247
- }, [fireEvent, id, isFlexibleUi, appearance, definitionId, onClick, url, appendCrossProductAnalyticsParams, state.details, ari, name, fire3PClickEvent, shouldFire3PClickEvent, isPreviewPanelAvailable, openPreviewPanel, createAnalyticsEvent, disablePreviewPanel]);
259
+ }, [fireEvent, id, isFlexibleUi, appearance, definitionId, getDestinationUrl, onClick, url, updateAnchorHref, state.details, ari, name, fire3PClickEvent, shouldFire3PClickEvent, isPreviewPanelAvailable, openPreviewPanel, createAnalyticsEvent, disablePreviewPanel]);
248
260
 
249
261
  // Exposure fires once per eligible mount; click-time reads use no-exposure variant.
250
262
  (0, _react.useEffect)(function () {
@@ -256,23 +268,32 @@ function Component(_ref) {
256
268
  // Middle-click handler to trigger fire3PClickEvent on middle-clicks.
257
269
  // Scope is limited to 3P click analytics to keep the experiment focused.
258
270
  var handleFrameAuxClick = (0, _react.useCallback)(function (event) {
271
+ if ((0, _platformFeatureFlags.fg)('platform_smartlink_xpc_url_wrapping')) {
272
+ var destinationUrl = getDestinationUrl();
273
+ updateAnchorHref(event, destinationUrl);
274
+ }
275
+
259
276
  // isAuxClick filters Windows right-clicks (button === 2) that also fire onAuxClick.
260
277
  if ((0, _clickHelpers.isAuxClick)(event) && shouldFire3PClickEvent && (0, _expValEqualsNoExposure.expValEqualsNoExposure)(TRACK_NON_PRIMARY_3P_CLICKS_EXPERIMENT, 'isEnabled', true)) {
261
278
  fire3PClickEvent === null || fire3PClickEvent === void 0 || fire3PClickEvent({
262
279
  isAuxClick: true
263
280
  });
264
281
  }
265
- }, [fire3PClickEvent, shouldFire3PClickEvent]);
282
+ }, [fire3PClickEvent, getDestinationUrl, shouldFire3PClickEvent, updateAnchorHref]);
266
283
 
267
284
  // Right-click handler to trigger fire3PClickEvent on right-clicks.
268
285
  // Scope is limited to 3P click analytics to keep the experiment focused.
269
- var handleFrameContextMenu = (0, _react.useCallback)(function (_event) {
286
+ var handleFrameContextMenu = (0, _react.useCallback)(function (event) {
287
+ if ((0, _platformFeatureFlags.fg)('platform_smartlink_xpc_url_wrapping')) {
288
+ var destinationUrl = getDestinationUrl();
289
+ updateAnchorHref(event, destinationUrl);
290
+ }
270
291
  if (shouldFire3PClickEvent && (0, _expValEqualsNoExposure.expValEqualsNoExposure)(TRACK_NON_PRIMARY_3P_CLICKS_EXPERIMENT, 'isEnabled', true)) {
271
292
  fire3PClickEvent === null || fire3PClickEvent === void 0 || fire3PClickEvent({
272
293
  isContextMenu: true
273
294
  });
274
295
  }
275
- }, [fire3PClickEvent, shouldFire3PClickEvent]);
296
+ }, [fire3PClickEvent, getDestinationUrl, shouldFire3PClickEvent, updateAnchorHref]);
276
297
  var reload = actions.reload;
277
298
  var handleAuthorize = (0, _react.useCallback)(function () {
278
299
  return actions.authorize(appearance);
@@ -22,7 +22,7 @@ var _SmartLinkAnalyticsContext = require("../../../utils/analytics/SmartLinkAnal
22
22
  var _CustomPopupContainer = require("../components/CustomPopupContainer");
23
23
  var _HoverCardContent = _interopRequireDefault(require("../components/HoverCardContent"));
24
24
  var _styled = require("../styled");
25
- var _excluded = ["aria-haspopup", "aria-expanded"];
25
+ var _excluded = ["aria-haspopup", "aria-expanded", "aria-controls"];
26
26
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
27
27
  var HOVER_CARD_SOURCE = exports.HOVER_CARD_SOURCE = 'smartLinkPreviewHoverCard';
28
28
  var HOVER_CARD_TRIGGER_WRAPPER = 'hover-card-trigger-wrapper';
@@ -240,6 +240,7 @@ var HoverCardComponent = exports.HoverCardComponent = function HoverCardComponen
240
240
  var trigger = (0, _react.useCallback)(function (_ref3) {
241
241
  var _ariaHasPopup = _ref3['aria-haspopup'],
242
242
  _ariaExpanded = _ref3['aria-expanded'],
243
+ _ariaControls = _ref3['aria-controls'],
243
244
  triggerProps = (0, _objectWithoutProperties2.default)(_ref3, _excluded);
244
245
  return /*#__PURE__*/_react.default.createElement("span", {
245
246
  ref: parentSpan
@@ -1,11 +1,15 @@
1
1
 
2
2
  ._2rko12b0{border-radius:var(--ds-radius-small,4px)}._18m915vq{overflow-y:hidden}
3
+ ._18m9ewfl{overflow-y:visible}
3
4
  ._19bv12x7{padding-left:var(--ds-space-075,6px)}
4
5
  ._19bvze3t{padding-left:var(--ds-space-0,0)}
5
6
  ._1bto1l2s{text-overflow:ellipsis}
6
- ._1e0c116y{display:inline-flex}
7
+ ._1btozryt{text-overflow:clip}
8
+ ._1e0c1bgi{display:contents}
7
9
  ._1e0c1nu9{display:inline}
10
+ ._1nmz9jpi{word-break:break-all}
8
11
  ._1reo15vq{overflow-x:hidden}
12
+ ._1reoewfl{overflow-x:visible}
9
13
  ._1wybtjj4{font-size:.8em}
10
14
  ._2hwx1b66{margin-right:var(--ds-space-050,4px)}
11
15
  ._4cvr1h6o{align-items:center}
@@ -16,6 +20,7 @@
16
20
  ._k48pwu06{font-weight:var(--ds-font-weight-bold,653)}
17
21
  ._n3tdv77o{padding-bottom:var(--ds-space-025,2px)}
18
22
  ._n3tdze3t{padding-bottom:var(--ds-space-0,0)}
23
+ ._o5721btx{white-space:break-spaces}
19
24
  ._o5721q9c{white-space:nowrap}
20
25
  ._p12f1osq{max-width:100%}
21
26
  ._s7n4t94y{vertical-align:1px}
@@ -12,6 +12,7 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
12
12
  var _react = _interopRequireDefault(require("react"));
13
13
  var _reactIntl = require("react-intl");
14
14
  var _reactMagneticDi = require("react-magnetic-di");
15
+ var _css = require("@atlaskit/css");
15
16
  var _lockLocked = _interopRequireDefault(require("@atlaskit/icon/core/lock-locked"));
16
17
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
17
18
  var _compiled = require("@atlaskit/primitives/compiled");
@@ -38,10 +39,12 @@ var SOCIAL_PROOF_TEAM_PREVIEW_THRESHOLD = 30;
38
39
  var SOCIAL_PROOF_TRAIT_NAME = 'sl_3p_connected_providers_site_pct';
39
40
  var socialProofPillStyles = {
40
41
  strong: "_k48pwu06",
41
- inlineContainer: "_1e0c116y _4cvr1h6o",
42
42
  root: "_2rko12b0 _1e0c1nu9 _4cvr1h6o _vchhusvi _p12f1osq _bfhk1dpa _syazazsu _y3gn18uv _1wybtjj4 _s7n4t94y _ca0qv77o _n3tdv77o _u5f312x7 _19bv12x7 _2hwx1b66 _irr3plhp _1di61gdz",
43
43
  label: "_1reo15vq _18m915vq _1bto1l2s _o5721q9c",
44
- button: "_bfhk1j28 _u5f3ze3t _19bvze3t _ca0qze3t _n3tdze3t"
44
+ wrappingLabel: "_1reoewfl _18m9ewfl _1btozryt _o5721btx _1nmz9jpi",
45
+ button: "_bfhk1j28 _u5f3ze3t _19bvze3t _ca0qze3t _n3tdze3t",
46
+ pressableContents: "_1e0c1bgi",
47
+ inlineGroup: "_1e0c1nu9"
45
48
  };
46
49
 
47
50
  /**
@@ -110,7 +113,7 @@ var UnauthorisedConnectWithSocialProof = function UnauthorisedConnectWithSocialP
110
113
  testId: "".concat(testId, "-social-proof-tag")
111
114
  }, /*#__PURE__*/_react.default.createElement(_compiled.Box, {
112
115
  as: "span",
113
- xcss: socialProofPillStyles.label
116
+ xcss: (0, _css.cx)(socialProofPillStyles.label, (0, _platformFeatureFlags.fg)('platform_lp_social_proof_inline_overflow_bug') && socialProofPillStyles.wrappingLabel)
114
117
  }, socialProofPillContent)) : null, /*#__PURE__*/_react.default.createElement(_actionButton.ActionButton, {
115
118
  onClick: onConnectClick,
116
119
  viewType: "unauthorised",
@@ -126,8 +129,11 @@ var UnauthorisedConnectWithSocialProof = function UnauthorisedConnectWithSocialP
126
129
  style: {
127
130
  font: "inherit"
128
131
  },
129
- xcss: socialProofPillStyles.button
130
- }, buttonContent) : buttonContent;
132
+ xcss: (0, _css.cx)(socialProofPillStyles.button, (0, _platformFeatureFlags.fg)('platform_lp_social_proof_inline_overflow_bug') && socialProofPillStyles.pressableContents)
133
+ }, (0, _platformFeatureFlags.fg)('platform_lp_social_proof_inline_overflow_bug') ? /*#__PURE__*/_react.default.createElement(_compiled.Box, {
134
+ as: "span",
135
+ xcss: socialProofPillStyles.inlineGroup
136
+ }, buttonContent) : buttonContent) : buttonContent;
131
137
  };
132
138
  var InlineCardUnauthorizedView = exports.InlineCardUnauthorizedView = function InlineCardUnauthorizedView(_ref2) {
133
139
  var url = _ref2.url,
@@ -4,6 +4,7 @@
4
4
  ._19bv12x7{padding-left:var(--ds-space-075,6px)}
5
5
  ._1e0c1bgi{display:contents}
6
6
  ._1e0c1nu9{display:inline}
7
+ ._1nmz4jg8{word-break:normal}
7
8
  ._1nmz9jpi{word-break:break-all}
8
9
  ._1o0zlb4i{border-bottom-right-radius:var(--ds-radius-xsmall,2px)}
9
10
  ._1wybtjj4{font-size:.8em}
@@ -24,6 +25,7 @@
24
25
  ._n3tdt94y{padding-bottom:1px}
25
26
  ._n3tdv77o{padding-bottom:var(--ds-space-025,2px)}
26
27
  ._o5721btx{white-space:break-spaces}
28
+ ._o5721q9c{white-space:nowrap}
27
29
  ._qrwqlb4i{border-top-right-radius:var(--ds-radius-xsmall,2px)}
28
30
  ._s7n4t94y{vertical-align:1px}
29
31
  ._syaz15cr{color:var(--ds-text-inverse,#fff)}
@@ -22,6 +22,7 @@ var styles = {
22
22
  button: "_1e0c1bgi",
23
23
  innerContainer: "_1e0c1nu9 _1y1m1u8q _16d9qvcn _k48p1wq8 _19bv12x7 _ca0qv77o _n3tdv77o _u5f312x7 _y3gn18uv _o5721btx _1nmz9jpi",
24
24
  innerContainerSocialProofConnect: "_2rko12b0 _syaz15cr _80omtlke _bfhkjmqp _2hwxv77o _1e0c1nu9 _4cvr1h6o _1wybtjj4 _1y1m1u8q _16d9qvcn _19bv12x7 _ca0qv77o _n3tdv77o _u5f312x7 _y3gn18uv _s7n4t94y _o5721btx _1nmz9jpi _irr31q28 _1di612kk",
25
+ innerContainerNoWrap: "_o5721q9c _1nmz4jg8",
25
26
  enabled: "_syazi7uo _80omtlke _bfhki8nm _irr3plhp _1di61gdz",
26
27
  disabled: "_syaz1gmx _80om13gf _bfhk187o",
27
28
  unauthorised: "_syaz15cr _80omtlke _bfhkjmqp _qrwqlb4i _1o0zlb4i _13lilb4i _mrkblb4i _ca0qt94y _n3tdt94y _2hwxt94y _k48pi7a9 _irr31q28 _1di612kk"
@@ -51,7 +52,7 @@ var ActionButton = exports.ActionButton = /*#__PURE__*/(0, _react.forwardRef)(fu
51
52
  },
52
53
  xcss: styles.button
53
54
  }), /*#__PURE__*/React.createElement("span", {
54
- className: (0, _runtime.ax)([styles.innerContainerSocialProofConnect])
55
+ className: (0, _runtime.ax)([styles.innerContainerSocialProofConnect, (0, _platformFeatureFlags.fg)('platform_lp_social_proof_inline_overflow_bug') && ""])
55
56
  }, children));
56
57
  }
57
58
  return /*#__PURE__*/React.createElement(_compiled.Pressable, (0, _extends2.default)({}, props, {
@@ -19,7 +19,7 @@ var _excluded = ["href", "children", "checkSafety", "onClick", "testId", "isLink
19
19
  _excluded2 = ["isLinkSafe", "showSafetyWarningModal"];
20
20
  var PACKAGE_DATA = {
21
21
  packageName: "@atlaskit/smart-card",
22
- packageVersion: "44.25.0",
22
+ packageVersion: "44.26.0",
23
23
  componentName: 'linkUrl'
24
24
  };
25
25
  var LinkUrl = function LinkUrl(_ref) {
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7e92f235ef67cfff425c2768c61c1501f8d5daa6e0418075997c0de015ea18b2
3
+ size 35855
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1ee2641306bded4b5e90d1b509fa83e697a55b5eddb2bda5480fc7c50b0ddcf2
3
+ size 36106
@@ -0,0 +1 @@
1
+ export { useDestinationUrl as useSmartLinkDestinationUrl } from '../state/hooks/use-destination-url';
@@ -0,0 +1,32 @@
1
+ import { functionWithFG } from '@atlaskit/platform-feature-flags-react';
2
+ import { getClickUrl } from '../../helpers';
3
+ import { useSmartCardState } from '../../store';
4
+ import { useSmartLinkCrossProductUrlWrapper } from '../use-smart-link-cross-product-url-wrapper';
5
+
6
+ /**
7
+ * Returns the resolved destination URL for a Smart Link, with cross-product analytics
8
+ * parameters appended when the `platform_smartlink_xpc_url_wrapping` feature gate is enabled.
9
+ *
10
+ * This is the same URL that SmartCard would navigate to when clicked. Use this as an `href`
11
+ * wherever you render a link to a Smart Link URL outside of the SmartCard component itself
12
+ * (e.g. toolbar buttons, overlays).
13
+ *
14
+ * Falls back to the raw `url` when:
15
+ * - The link has not yet resolved
16
+ * - The feature gate is disabled
17
+ * - The link is not a first-party Atlassian link
18
+ *
19
+ * @example
20
+ * const href = useSmartLinkDestinationUrl(url);
21
+ *
22
+ * Use as <a href={href} target="_blank">Open link</a>
23
+ */
24
+ const useDestinationUrlImplementation = url => {
25
+ const state = useSmartCardState(url);
26
+ const appendCrossProductAnalyticsParams = useSmartLinkCrossProductUrlWrapper({
27
+ details: state.details
28
+ });
29
+ const resolvedUrl = getClickUrl(url, state.details);
30
+ return appendCrossProductAnalyticsParams(resolvedUrl);
31
+ };
32
+ export const useDestinationUrl = functionWithFG('platform_smartlink_xpc_url_wrapping', useDestinationUrlImplementation, url => url);
@@ -10,7 +10,7 @@ export const getIsFirstPartyLink = details => {
10
10
  };
11
11
  const identityUrlWrapper = url => url;
12
12
  const useSmartLinkCrossProductUrlWrapperFallback = _args => identityUrlWrapper;
13
- const useSmartLinkCrossProductUrlWrapper = ({
13
+ export const useSmartLinkCrossProductUrlWrapper = ({
14
14
  details
15
15
  }) => {
16
16
  var _effectiveProduct$toL;
@@ -2,7 +2,7 @@ export const ANALYTICS_CHANNEL = 'media';
2
2
  export const context = {
3
3
  componentName: 'smart-cards',
4
4
  packageName: "@atlaskit/smart-card" || '',
5
- packageVersion: "44.25.0" || ''
5
+ packageVersion: "44.26.0" || ''
6
6
  };
7
7
  export let TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
8
8
  TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
@@ -102,6 +102,21 @@ function Component({
102
102
 
103
103
  // Shared scope guard for all 3P-click handlers.
104
104
  const shouldFire3PClickEvent = thirdPartyARI && thirdPartyARI.startsWith(thirdPartyARIPrefix) && getClickUrl(url, state.details) === url && fire3PClickEvent && fg('platform_smartlink_3pclick_analytics');
105
+ const getDestinationUrl = useCallback(() => {
106
+ var _getClickUrl, _appendCrossProductAn;
107
+ const preferredUrl = (_getClickUrl = getClickUrl(url, state.details)) !== null && _getClickUrl !== void 0 ? _getClickUrl : url;
108
+ return (_appendCrossProductAn = appendCrossProductAnalyticsParams(preferredUrl)) !== null && _appendCrossProductAn !== void 0 ? _appendCrossProductAn : preferredUrl;
109
+ }, [appendCrossProductAnalyticsParams, state.details, url]);
110
+ const updateAnchorHref = useCallback((event, destinationUrl) => {
111
+ if (!(event.currentTarget instanceof HTMLAnchorElement)) {
112
+ return;
113
+ }
114
+
115
+ // FIXME: destinationUrl should be rendered in the DOM anchor href instead of derived at click time
116
+ // href is only defined when currentTarget is an anchor element.
117
+ // Update the anchor href so the browser context menu uses the decorated URL.
118
+ event.currentTarget.href = destinationUrl;
119
+ }, []);
105
120
 
106
121
  // Setup UI handlers.
107
122
  const handleClickWrapper = useCallback(event => {
@@ -121,7 +136,6 @@ function Component({
121
136
  exposure: true
122
137
  });
123
138
  if (fg('platform_smartlink_xpc_url_wrapping')) {
124
- var _appendCrossProductAn;
125
139
  // FIXME: InlineCard, BlockCard and EmbedCard call event.preventDefault() internally
126
140
  // before the event bubbles up to this handler. This forces us to snapshot
127
141
  // event.defaultPrevented before calling onClick to detect whether the consumer
@@ -153,6 +167,8 @@ function Component({
153
167
  });
154
168
  return;
155
169
  }
170
+ const destinationUrl = getDestinationUrl();
171
+ updateAnchorHref(event, destinationUrl);
156
172
 
157
173
  // For FlexibleCard, read target from the clicked anchor element (e.g. _blank for links
158
174
  // rendered with explicit target). For classic cards, default to _self
@@ -160,10 +176,6 @@ function Component({
160
176
  target: anchorTarget
161
177
  } = getAnchorAttributesFromEvent(event);
162
178
  const target = isSpecialEvent(event) ? '_blank' : isFlexibleUi ? anchorTarget : '_self';
163
-
164
- // FIXME: preferredUrl should be rendered in the DOM anchor href instead of derived at click time
165
- const preferredUrl = getClickUrl(url, state.details);
166
- const destinationUrl = (_appendCrossProductAn = appendCrossProductAnalyticsParams(preferredUrl)) !== null && _appendCrossProductAn !== void 0 ? _appendCrossProductAn : preferredUrl;
167
179
  onClick === null || onClick === void 0 ? void 0 : onClick(event, {
168
180
  url,
169
181
  destinationUrl
@@ -235,7 +247,7 @@ function Component({
235
247
  fireLinkClickedEvent(createAnalyticsEvent)(event);
236
248
  }
237
249
  }
238
- }, [fireEvent, id, isFlexibleUi, appearance, definitionId, onClick, url, appendCrossProductAnalyticsParams, state.details, ari, name, fire3PClickEvent, shouldFire3PClickEvent, isPreviewPanelAvailable, openPreviewPanel, createAnalyticsEvent, disablePreviewPanel]);
250
+ }, [fireEvent, id, isFlexibleUi, appearance, definitionId, getDestinationUrl, onClick, url, updateAnchorHref, state.details, ari, name, fire3PClickEvent, shouldFire3PClickEvent, isPreviewPanelAvailable, openPreviewPanel, createAnalyticsEvent, disablePreviewPanel]);
239
251
 
240
252
  // Exposure fires once per eligible mount; click-time reads use no-exposure variant.
241
253
  useEffect(() => {
@@ -247,23 +259,32 @@ function Component({
247
259
  // Middle-click handler to trigger fire3PClickEvent on middle-clicks.
248
260
  // Scope is limited to 3P click analytics to keep the experiment focused.
249
261
  const handleFrameAuxClick = useCallback(event => {
262
+ if (fg('platform_smartlink_xpc_url_wrapping')) {
263
+ const destinationUrl = getDestinationUrl();
264
+ updateAnchorHref(event, destinationUrl);
265
+ }
266
+
250
267
  // isAuxClick filters Windows right-clicks (button === 2) that also fire onAuxClick.
251
268
  if (isAuxClick(event) && shouldFire3PClickEvent && expValEqualsNoExposure(TRACK_NON_PRIMARY_3P_CLICKS_EXPERIMENT, 'isEnabled', true)) {
252
269
  fire3PClickEvent === null || fire3PClickEvent === void 0 ? void 0 : fire3PClickEvent({
253
270
  isAuxClick: true
254
271
  });
255
272
  }
256
- }, [fire3PClickEvent, shouldFire3PClickEvent]);
273
+ }, [fire3PClickEvent, getDestinationUrl, shouldFire3PClickEvent, updateAnchorHref]);
257
274
 
258
275
  // Right-click handler to trigger fire3PClickEvent on right-clicks.
259
276
  // Scope is limited to 3P click analytics to keep the experiment focused.
260
- const handleFrameContextMenu = useCallback(_event => {
277
+ const handleFrameContextMenu = useCallback(event => {
278
+ if (fg('platform_smartlink_xpc_url_wrapping')) {
279
+ const destinationUrl = getDestinationUrl();
280
+ updateAnchorHref(event, destinationUrl);
281
+ }
261
282
  if (shouldFire3PClickEvent && expValEqualsNoExposure(TRACK_NON_PRIMARY_3P_CLICKS_EXPERIMENT, 'isEnabled', true)) {
262
283
  fire3PClickEvent === null || fire3PClickEvent === void 0 ? void 0 : fire3PClickEvent({
263
284
  isContextMenu: true
264
285
  });
265
286
  }
266
- }, [fire3PClickEvent, shouldFire3PClickEvent]);
287
+ }, [fire3PClickEvent, getDestinationUrl, shouldFire3PClickEvent, updateAnchorHref]);
267
288
  const {
268
289
  reload
269
290
  } = actions;
@@ -214,6 +214,12 @@ export const HoverCardComponent = ({
214
214
  const trigger = useCallback(({
215
215
  'aria-haspopup': _ariaHasPopup,
216
216
  'aria-expanded': _ariaExpanded,
217
+ // `aria-controls` is also stripped because the trigger wrapper renders
218
+ // with `role="none"`. axe's `aria-valid-attr-value` rule flags any
219
+ // `aria-controls` value sitting on a presentational element, since the
220
+ // element has no semantic role to control. Removing the attribute
221
+ // keeps the trigger semantically inert without losing functionality.
222
+ 'aria-controls': _ariaControls,
217
223
  ...triggerProps
218
224
  }) => /*#__PURE__*/React.createElement("span", {
219
225
  ref: parentSpan
@@ -1,11 +1,15 @@
1
1
 
2
2
  ._2rko12b0{border-radius:var(--ds-radius-small,4px)}._18m915vq{overflow-y:hidden}
3
+ ._18m9ewfl{overflow-y:visible}
3
4
  ._19bv12x7{padding-left:var(--ds-space-075,6px)}
4
5
  ._19bvze3t{padding-left:var(--ds-space-0,0)}
5
6
  ._1bto1l2s{text-overflow:ellipsis}
6
- ._1e0c116y{display:inline-flex}
7
+ ._1btozryt{text-overflow:clip}
8
+ ._1e0c1bgi{display:contents}
7
9
  ._1e0c1nu9{display:inline}
10
+ ._1nmz9jpi{word-break:break-all}
8
11
  ._1reo15vq{overflow-x:hidden}
12
+ ._1reoewfl{overflow-x:visible}
9
13
  ._1wybtjj4{font-size:.8em}
10
14
  ._2hwx1b66{margin-right:var(--ds-space-050,4px)}
11
15
  ._4cvr1h6o{align-items:center}
@@ -16,6 +20,7 @@
16
20
  ._k48pwu06{font-weight:var(--ds-font-weight-bold,653)}
17
21
  ._n3tdv77o{padding-bottom:var(--ds-space-025,2px)}
18
22
  ._n3tdze3t{padding-bottom:var(--ds-space-0,0)}
23
+ ._o5721btx{white-space:break-spaces}
19
24
  ._o5721q9c{white-space:nowrap}
20
25
  ._p12f1osq{max-width:100%}
21
26
  ._s7n4t94y{vertical-align:1px}
@@ -5,6 +5,7 @@ import { ax, ix } from "@compiled/react/runtime";
5
5
  import React from 'react';
6
6
  import { FormattedMessage } from 'react-intl';
7
7
  import { di } from 'react-magnetic-di';
8
+ import { cx } from '@atlaskit/css';
8
9
  import LockLockedIcon from '@atlaskit/icon/core/lock-locked';
9
10
  import { fg } from '@atlaskit/platform-feature-flags';
10
11
  import { Box, Pressable } from '@atlaskit/primitives/compiled';
@@ -31,10 +32,12 @@ const SOCIAL_PROOF_TEAM_PREVIEW_THRESHOLD = 30;
31
32
  const SOCIAL_PROOF_TRAIT_NAME = 'sl_3p_connected_providers_site_pct';
32
33
  const socialProofPillStyles = {
33
34
  strong: "_k48pwu06",
34
- inlineContainer: "_1e0c116y _4cvr1h6o",
35
35
  root: "_2rko12b0 _1e0c1nu9 _4cvr1h6o _vchhusvi _p12f1osq _bfhk1dpa _syazazsu _y3gn18uv _1wybtjj4 _s7n4t94y _ca0qv77o _n3tdv77o _u5f312x7 _19bv12x7 _2hwx1b66 _irr3plhp _1di61gdz",
36
36
  label: "_1reo15vq _18m915vq _1bto1l2s _o5721q9c",
37
- button: "_bfhk1j28 _u5f3ze3t _19bvze3t _ca0qze3t _n3tdze3t"
37
+ wrappingLabel: "_1reoewfl _18m9ewfl _1btozryt _o5721btx _1nmz9jpi",
38
+ button: "_bfhk1j28 _u5f3ze3t _19bvze3t _ca0qze3t _n3tdze3t",
39
+ pressableContents: "_1e0c1bgi",
40
+ inlineGroup: "_1e0c1nu9"
38
41
  };
39
42
 
40
43
  /**
@@ -102,7 +105,7 @@ const UnauthorisedConnectWithSocialProof = ({
102
105
  testId: `${testId}-social-proof-tag`
103
106
  }, /*#__PURE__*/React.createElement(Box, {
104
107
  as: "span",
105
- xcss: socialProofPillStyles.label
108
+ xcss: cx(socialProofPillStyles.label, fg('platform_lp_social_proof_inline_overflow_bug') && socialProofPillStyles.wrappingLabel)
106
109
  }, socialProofPillContent)) : null, /*#__PURE__*/React.createElement(ActionButton, {
107
110
  onClick: onConnectClick,
108
111
  viewType: "unauthorised",
@@ -118,8 +121,11 @@ const UnauthorisedConnectWithSocialProof = ({
118
121
  style: {
119
122
  font: `inherit`
120
123
  },
121
- xcss: socialProofPillStyles.button
122
- }, buttonContent) : buttonContent;
124
+ xcss: cx(socialProofPillStyles.button, fg('platform_lp_social_proof_inline_overflow_bug') && socialProofPillStyles.pressableContents)
125
+ }, fg('platform_lp_social_proof_inline_overflow_bug') ? /*#__PURE__*/React.createElement(Box, {
126
+ as: "span",
127
+ xcss: socialProofPillStyles.inlineGroup
128
+ }, buttonContent) : buttonContent) : buttonContent;
123
129
  };
124
130
  export const InlineCardUnauthorizedView = ({
125
131
  url,
@@ -4,6 +4,7 @@
4
4
  ._19bv12x7{padding-left:var(--ds-space-075,6px)}
5
5
  ._1e0c1bgi{display:contents}
6
6
  ._1e0c1nu9{display:inline}
7
+ ._1nmz4jg8{word-break:normal}
7
8
  ._1nmz9jpi{word-break:break-all}
8
9
  ._1o0zlb4i{border-bottom-right-radius:var(--ds-radius-xsmall,2px)}
9
10
  ._1wybtjj4{font-size:.8em}
@@ -24,6 +25,7 @@
24
25
  ._n3tdt94y{padding-bottom:1px}
25
26
  ._n3tdv77o{padding-bottom:var(--ds-space-025,2px)}
26
27
  ._o5721btx{white-space:break-spaces}
28
+ ._o5721q9c{white-space:nowrap}
27
29
  ._qrwqlb4i{border-top-right-radius:var(--ds-radius-xsmall,2px)}
28
30
  ._s7n4t94y{vertical-align:1px}
29
31
  ._syaz15cr{color:var(--ds-text-inverse,#fff)}
@@ -10,6 +10,7 @@ const styles = {
10
10
  button: "_1e0c1bgi",
11
11
  innerContainer: "_1e0c1nu9 _1y1m1u8q _16d9qvcn _k48p1wq8 _19bv12x7 _ca0qv77o _n3tdv77o _u5f312x7 _y3gn18uv _o5721btx _1nmz9jpi",
12
12
  innerContainerSocialProofConnect: "_2rko12b0 _syaz15cr _80omtlke _bfhkjmqp _2hwxv77o _1e0c1nu9 _4cvr1h6o _1wybtjj4 _1y1m1u8q _16d9qvcn _19bv12x7 _ca0qv77o _n3tdv77o _u5f312x7 _y3gn18uv _s7n4t94y _o5721btx _1nmz9jpi _irr31q28 _1di612kk",
13
+ innerContainerNoWrap: "_o5721q9c _1nmz4jg8",
13
14
  enabled: "_syazi7uo _80omtlke _bfhki8nm _irr3plhp _1di61gdz",
14
15
  disabled: "_syaz1gmx _80om13gf _bfhk187o",
15
16
  unauthorised: "_syaz15cr _80omtlke _bfhkjmqp _qrwqlb4i _1o0zlb4i _13lilb4i _mrkblb4i _ca0qt94y _n3tdt94y _2hwxt94y _k48pi7a9 _irr31q28 _1di612kk"
@@ -40,7 +41,7 @@ export const ActionButton = /*#__PURE__*/forwardRef(({
40
41
  },
41
42
  xcss: styles.button
42
43
  }), /*#__PURE__*/React.createElement("span", {
43
- className: ax([styles.innerContainerSocialProofConnect])
44
+ className: ax([styles.innerContainerSocialProofConnect, fg('platform_lp_social_proof_inline_overflow_bug') && ""])
44
45
  }, children));
45
46
  }
46
47
  return /*#__PURE__*/React.createElement(Pressable, _extends({}, props, {
@@ -9,7 +9,7 @@ import LinkWarningModal from './LinkWarningModal';
9
9
  import { useLinkWarningModal } from './LinkWarningModal/hooks/use-link-warning-modal';
10
10
  const PACKAGE_DATA = {
11
11
  packageName: "@atlaskit/smart-card",
12
- packageVersion: "44.25.0",
12
+ packageVersion: "44.26.0",
13
13
  componentName: 'linkUrl'
14
14
  };
15
15
  const LinkUrl = ({
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7e92f235ef67cfff425c2768c61c1501f8d5daa6e0418075997c0de015ea18b2
3
+ size 35855
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1ee2641306bded4b5e90d1b509fa83e697a55b5eddb2bda5480fc7c50b0ddcf2
3
+ size 36106
@@ -0,0 +1 @@
1
+ export { useDestinationUrl as useSmartLinkDestinationUrl } from '../state/hooks/use-destination-url';
@@ -0,0 +1,34 @@
1
+ import { functionWithFG } from '@atlaskit/platform-feature-flags-react';
2
+ import { getClickUrl } from '../../helpers';
3
+ import { useSmartCardState } from '../../store';
4
+ import { useSmartLinkCrossProductUrlWrapper } from '../use-smart-link-cross-product-url-wrapper';
5
+
6
+ /**
7
+ * Returns the resolved destination URL for a Smart Link, with cross-product analytics
8
+ * parameters appended when the `platform_smartlink_xpc_url_wrapping` feature gate is enabled.
9
+ *
10
+ * This is the same URL that SmartCard would navigate to when clicked. Use this as an `href`
11
+ * wherever you render a link to a Smart Link URL outside of the SmartCard component itself
12
+ * (e.g. toolbar buttons, overlays).
13
+ *
14
+ * Falls back to the raw `url` when:
15
+ * - The link has not yet resolved
16
+ * - The feature gate is disabled
17
+ * - The link is not a first-party Atlassian link
18
+ *
19
+ * @example
20
+ * const href = useSmartLinkDestinationUrl(url);
21
+ *
22
+ * Use as <a href={href} target="_blank">Open link</a>
23
+ */
24
+ var useDestinationUrlImplementation = function useDestinationUrlImplementation(url) {
25
+ var state = useSmartCardState(url);
26
+ var appendCrossProductAnalyticsParams = useSmartLinkCrossProductUrlWrapper({
27
+ details: state.details
28
+ });
29
+ var resolvedUrl = getClickUrl(url, state.details);
30
+ return appendCrossProductAnalyticsParams(resolvedUrl);
31
+ };
32
+ export var useDestinationUrl = functionWithFG('platform_smartlink_xpc_url_wrapping', useDestinationUrlImplementation, function (url) {
33
+ return url;
34
+ });
@@ -17,7 +17,7 @@ var identityUrlWrapper = function identityUrlWrapper(url) {
17
17
  var useSmartLinkCrossProductUrlWrapperFallback = function useSmartLinkCrossProductUrlWrapperFallback(_args) {
18
18
  return identityUrlWrapper;
19
19
  };
20
- var useSmartLinkCrossProductUrlWrapper = function useSmartLinkCrossProductUrlWrapper(_ref) {
20
+ export var useSmartLinkCrossProductUrlWrapper = function useSmartLinkCrossProductUrlWrapper(_ref) {
21
21
  var _effectiveProduct$toL;
22
22
  var details = _ref.details;
23
23
  var _useSmartLinkContext = useSmartLinkContext(),
@@ -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.25.0" || ''
7
+ packageVersion: "44.26.0" || ''
8
8
  };
9
9
  export var TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
10
10
  TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
@@ -103,6 +103,21 @@ function Component(_ref) {
103
103
 
104
104
  // Shared scope guard for all 3P-click handlers.
105
105
  var shouldFire3PClickEvent = thirdPartyARI && thirdPartyARI.startsWith(thirdPartyARIPrefix) && getClickUrl(url, state.details) === url && fire3PClickEvent && fg('platform_smartlink_3pclick_analytics');
106
+ var getDestinationUrl = useCallback(function () {
107
+ var _getClickUrl, _appendCrossProductAn;
108
+ var preferredUrl = (_getClickUrl = getClickUrl(url, state.details)) !== null && _getClickUrl !== void 0 ? _getClickUrl : url;
109
+ return (_appendCrossProductAn = appendCrossProductAnalyticsParams(preferredUrl)) !== null && _appendCrossProductAn !== void 0 ? _appendCrossProductAn : preferredUrl;
110
+ }, [appendCrossProductAnalyticsParams, state.details, url]);
111
+ var updateAnchorHref = useCallback(function (event, destinationUrl) {
112
+ if (!(event.currentTarget instanceof HTMLAnchorElement)) {
113
+ return;
114
+ }
115
+
116
+ // FIXME: destinationUrl should be rendered in the DOM anchor href instead of derived at click time
117
+ // href is only defined when currentTarget is an anchor element.
118
+ // Update the anchor href so the browser context menu uses the decorated URL.
119
+ event.currentTarget.href = destinationUrl;
120
+ }, []);
106
121
 
107
122
  // Setup UI handlers.
108
123
  var handleClickWrapper = useCallback(function (event) {
@@ -122,7 +137,6 @@ function Component(_ref) {
122
137
  exposure: true
123
138
  });
124
139
  if (fg('platform_smartlink_xpc_url_wrapping')) {
125
- var _appendCrossProductAn;
126
140
  // FIXME: InlineCard, BlockCard and EmbedCard call event.preventDefault() internally
127
141
  // before the event bubbles up to this handler. This forces us to snapshot
128
142
  // event.defaultPrevented before calling onClick to detect whether the consumer
@@ -154,16 +168,14 @@ function Component(_ref) {
154
168
  });
155
169
  return;
156
170
  }
171
+ var destinationUrl = getDestinationUrl();
172
+ updateAnchorHref(event, destinationUrl);
157
173
 
158
174
  // For FlexibleCard, read target from the clicked anchor element (e.g. _blank for links
159
175
  // rendered with explicit target). For classic cards, default to _self
160
176
  var _getAnchorAttributesF = getAnchorAttributesFromEvent(event),
161
177
  anchorTarget = _getAnchorAttributesF.target;
162
178
  var target = isSpecialEvent(event) ? '_blank' : isFlexibleUi ? anchorTarget : '_self';
163
-
164
- // FIXME: preferredUrl should be rendered in the DOM anchor href instead of derived at click time
165
- var preferredUrl = getClickUrl(url, state.details);
166
- var destinationUrl = (_appendCrossProductAn = appendCrossProductAnalyticsParams(preferredUrl)) !== null && _appendCrossProductAn !== void 0 ? _appendCrossProductAn : preferredUrl;
167
179
  onClick === null || onClick === void 0 || onClick(event, {
168
180
  url: url,
169
181
  destinationUrl: destinationUrl
@@ -235,7 +247,7 @@ function Component(_ref) {
235
247
  fireLinkClickedEvent(createAnalyticsEvent)(event);
236
248
  }
237
249
  }
238
- }, [fireEvent, id, isFlexibleUi, appearance, definitionId, onClick, url, appendCrossProductAnalyticsParams, state.details, ari, name, fire3PClickEvent, shouldFire3PClickEvent, isPreviewPanelAvailable, openPreviewPanel, createAnalyticsEvent, disablePreviewPanel]);
250
+ }, [fireEvent, id, isFlexibleUi, appearance, definitionId, getDestinationUrl, onClick, url, updateAnchorHref, state.details, ari, name, fire3PClickEvent, shouldFire3PClickEvent, isPreviewPanelAvailable, openPreviewPanel, createAnalyticsEvent, disablePreviewPanel]);
239
251
 
240
252
  // Exposure fires once per eligible mount; click-time reads use no-exposure variant.
241
253
  useEffect(function () {
@@ -247,23 +259,32 @@ function Component(_ref) {
247
259
  // Middle-click handler to trigger fire3PClickEvent on middle-clicks.
248
260
  // Scope is limited to 3P click analytics to keep the experiment focused.
249
261
  var handleFrameAuxClick = useCallback(function (event) {
262
+ if (fg('platform_smartlink_xpc_url_wrapping')) {
263
+ var destinationUrl = getDestinationUrl();
264
+ updateAnchorHref(event, destinationUrl);
265
+ }
266
+
250
267
  // isAuxClick filters Windows right-clicks (button === 2) that also fire onAuxClick.
251
268
  if (isAuxClick(event) && shouldFire3PClickEvent && expValEqualsNoExposure(TRACK_NON_PRIMARY_3P_CLICKS_EXPERIMENT, 'isEnabled', true)) {
252
269
  fire3PClickEvent === null || fire3PClickEvent === void 0 || fire3PClickEvent({
253
270
  isAuxClick: true
254
271
  });
255
272
  }
256
- }, [fire3PClickEvent, shouldFire3PClickEvent]);
273
+ }, [fire3PClickEvent, getDestinationUrl, shouldFire3PClickEvent, updateAnchorHref]);
257
274
 
258
275
  // Right-click handler to trigger fire3PClickEvent on right-clicks.
259
276
  // Scope is limited to 3P click analytics to keep the experiment focused.
260
- var handleFrameContextMenu = useCallback(function (_event) {
277
+ var handleFrameContextMenu = useCallback(function (event) {
278
+ if (fg('platform_smartlink_xpc_url_wrapping')) {
279
+ var destinationUrl = getDestinationUrl();
280
+ updateAnchorHref(event, destinationUrl);
281
+ }
261
282
  if (shouldFire3PClickEvent && expValEqualsNoExposure(TRACK_NON_PRIMARY_3P_CLICKS_EXPERIMENT, 'isEnabled', true)) {
262
283
  fire3PClickEvent === null || fire3PClickEvent === void 0 || fire3PClickEvent({
263
284
  isContextMenu: true
264
285
  });
265
286
  }
266
- }, [fire3PClickEvent, shouldFire3PClickEvent]);
287
+ }, [fire3PClickEvent, getDestinationUrl, shouldFire3PClickEvent, updateAnchorHref]);
267
288
  var reload = actions.reload;
268
289
  var handleAuthorize = useCallback(function () {
269
290
  return actions.authorize(appearance);
@@ -1,7 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
3
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
- var _excluded = ["aria-haspopup", "aria-expanded"];
4
+ var _excluded = ["aria-haspopup", "aria-expanded", "aria-controls"];
5
5
  import React, { useCallback, useEffect, useMemo, useRef } from 'react';
6
6
  import { fg } from '@atlaskit/platform-feature-flags';
7
7
  import Popup from '@atlaskit/popup';
@@ -231,6 +231,7 @@ export var HoverCardComponent = function HoverCardComponent(_ref) {
231
231
  var trigger = useCallback(function (_ref3) {
232
232
  var _ariaHasPopup = _ref3['aria-haspopup'],
233
233
  _ariaExpanded = _ref3['aria-expanded'],
234
+ _ariaControls = _ref3['aria-controls'],
234
235
  triggerProps = _objectWithoutProperties(_ref3, _excluded);
235
236
  return /*#__PURE__*/React.createElement("span", {
236
237
  ref: parentSpan
@@ -1,11 +1,15 @@
1
1
 
2
2
  ._2rko12b0{border-radius:var(--ds-radius-small,4px)}._18m915vq{overflow-y:hidden}
3
+ ._18m9ewfl{overflow-y:visible}
3
4
  ._19bv12x7{padding-left:var(--ds-space-075,6px)}
4
5
  ._19bvze3t{padding-left:var(--ds-space-0,0)}
5
6
  ._1bto1l2s{text-overflow:ellipsis}
6
- ._1e0c116y{display:inline-flex}
7
+ ._1btozryt{text-overflow:clip}
8
+ ._1e0c1bgi{display:contents}
7
9
  ._1e0c1nu9{display:inline}
10
+ ._1nmz9jpi{word-break:break-all}
8
11
  ._1reo15vq{overflow-x:hidden}
12
+ ._1reoewfl{overflow-x:visible}
9
13
  ._1wybtjj4{font-size:.8em}
10
14
  ._2hwx1b66{margin-right:var(--ds-space-050,4px)}
11
15
  ._4cvr1h6o{align-items:center}
@@ -16,6 +20,7 @@
16
20
  ._k48pwu06{font-weight:var(--ds-font-weight-bold,653)}
17
21
  ._n3tdv77o{padding-bottom:var(--ds-space-025,2px)}
18
22
  ._n3tdze3t{padding-bottom:var(--ds-space-0,0)}
23
+ ._o5721btx{white-space:break-spaces}
19
24
  ._o5721q9c{white-space:nowrap}
20
25
  ._p12f1osq{max-width:100%}
21
26
  ._s7n4t94y{vertical-align:1px}
@@ -5,6 +5,7 @@ import { ax, ix } from "@compiled/react/runtime";
5
5
  import React from 'react';
6
6
  import { FormattedMessage } from 'react-intl';
7
7
  import { di } from 'react-magnetic-di';
8
+ import { cx } from '@atlaskit/css';
8
9
  import LockLockedIcon from '@atlaskit/icon/core/lock-locked';
9
10
  import { fg } from '@atlaskit/platform-feature-flags';
10
11
  import { Box, Pressable } from '@atlaskit/primitives/compiled';
@@ -31,10 +32,12 @@ var SOCIAL_PROOF_TEAM_PREVIEW_THRESHOLD = 30;
31
32
  var SOCIAL_PROOF_TRAIT_NAME = 'sl_3p_connected_providers_site_pct';
32
33
  var socialProofPillStyles = {
33
34
  strong: "_k48pwu06",
34
- inlineContainer: "_1e0c116y _4cvr1h6o",
35
35
  root: "_2rko12b0 _1e0c1nu9 _4cvr1h6o _vchhusvi _p12f1osq _bfhk1dpa _syazazsu _y3gn18uv _1wybtjj4 _s7n4t94y _ca0qv77o _n3tdv77o _u5f312x7 _19bv12x7 _2hwx1b66 _irr3plhp _1di61gdz",
36
36
  label: "_1reo15vq _18m915vq _1bto1l2s _o5721q9c",
37
- button: "_bfhk1j28 _u5f3ze3t _19bvze3t _ca0qze3t _n3tdze3t"
37
+ wrappingLabel: "_1reoewfl _18m9ewfl _1btozryt _o5721btx _1nmz9jpi",
38
+ button: "_bfhk1j28 _u5f3ze3t _19bvze3t _ca0qze3t _n3tdze3t",
39
+ pressableContents: "_1e0c1bgi",
40
+ inlineGroup: "_1e0c1nu9"
38
41
  };
39
42
 
40
43
  /**
@@ -103,7 +106,7 @@ var UnauthorisedConnectWithSocialProof = function UnauthorisedConnectWithSocialP
103
106
  testId: "".concat(testId, "-social-proof-tag")
104
107
  }, /*#__PURE__*/React.createElement(Box, {
105
108
  as: "span",
106
- xcss: socialProofPillStyles.label
109
+ xcss: cx(socialProofPillStyles.label, fg('platform_lp_social_proof_inline_overflow_bug') && socialProofPillStyles.wrappingLabel)
107
110
  }, socialProofPillContent)) : null, /*#__PURE__*/React.createElement(ActionButton, {
108
111
  onClick: onConnectClick,
109
112
  viewType: "unauthorised",
@@ -119,8 +122,11 @@ var UnauthorisedConnectWithSocialProof = function UnauthorisedConnectWithSocialP
119
122
  style: {
120
123
  font: "inherit"
121
124
  },
122
- xcss: socialProofPillStyles.button
123
- }, buttonContent) : buttonContent;
125
+ xcss: cx(socialProofPillStyles.button, fg('platform_lp_social_proof_inline_overflow_bug') && socialProofPillStyles.pressableContents)
126
+ }, fg('platform_lp_social_proof_inline_overflow_bug') ? /*#__PURE__*/React.createElement(Box, {
127
+ as: "span",
128
+ xcss: socialProofPillStyles.inlineGroup
129
+ }, buttonContent) : buttonContent) : buttonContent;
124
130
  };
125
131
  export var InlineCardUnauthorizedView = function InlineCardUnauthorizedView(_ref2) {
126
132
  var url = _ref2.url,
@@ -4,6 +4,7 @@
4
4
  ._19bv12x7{padding-left:var(--ds-space-075,6px)}
5
5
  ._1e0c1bgi{display:contents}
6
6
  ._1e0c1nu9{display:inline}
7
+ ._1nmz4jg8{word-break:normal}
7
8
  ._1nmz9jpi{word-break:break-all}
8
9
  ._1o0zlb4i{border-bottom-right-radius:var(--ds-radius-xsmall,2px)}
9
10
  ._1wybtjj4{font-size:.8em}
@@ -24,6 +25,7 @@
24
25
  ._n3tdt94y{padding-bottom:1px}
25
26
  ._n3tdv77o{padding-bottom:var(--ds-space-025,2px)}
26
27
  ._o5721btx{white-space:break-spaces}
28
+ ._o5721q9c{white-space:nowrap}
27
29
  ._qrwqlb4i{border-top-right-radius:var(--ds-radius-xsmall,2px)}
28
30
  ._s7n4t94y{vertical-align:1px}
29
31
  ._syaz15cr{color:var(--ds-text-inverse,#fff)}
@@ -13,6 +13,7 @@ var styles = {
13
13
  button: "_1e0c1bgi",
14
14
  innerContainer: "_1e0c1nu9 _1y1m1u8q _16d9qvcn _k48p1wq8 _19bv12x7 _ca0qv77o _n3tdv77o _u5f312x7 _y3gn18uv _o5721btx _1nmz9jpi",
15
15
  innerContainerSocialProofConnect: "_2rko12b0 _syaz15cr _80omtlke _bfhkjmqp _2hwxv77o _1e0c1nu9 _4cvr1h6o _1wybtjj4 _1y1m1u8q _16d9qvcn _19bv12x7 _ca0qv77o _n3tdv77o _u5f312x7 _y3gn18uv _s7n4t94y _o5721btx _1nmz9jpi _irr31q28 _1di612kk",
16
+ innerContainerNoWrap: "_o5721q9c _1nmz4jg8",
16
17
  enabled: "_syazi7uo _80omtlke _bfhki8nm _irr3plhp _1di61gdz",
17
18
  disabled: "_syaz1gmx _80om13gf _bfhk187o",
18
19
  unauthorised: "_syaz15cr _80omtlke _bfhkjmqp _qrwqlb4i _1o0zlb4i _13lilb4i _mrkblb4i _ca0qt94y _n3tdt94y _2hwxt94y _k48pi7a9 _irr31q28 _1di612kk"
@@ -42,7 +43,7 @@ export var ActionButton = /*#__PURE__*/forwardRef(function (_ref, ref) {
42
43
  },
43
44
  xcss: styles.button
44
45
  }), /*#__PURE__*/React.createElement("span", {
45
- className: ax([styles.innerContainerSocialProofConnect])
46
+ className: ax([styles.innerContainerSocialProofConnect, fg('platform_lp_social_proof_inline_overflow_bug') && ""])
46
47
  }, children));
47
48
  }
48
49
  return /*#__PURE__*/React.createElement(Pressable, _extends({}, props, {
@@ -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.25.0",
15
+ packageVersion: "44.26.0",
16
16
  componentName: 'linkUrl'
17
17
  };
18
18
  var LinkUrl = function LinkUrl(_ref) {
@@ -0,0 +1 @@
1
+ export { useDestinationUrl as useSmartLinkDestinationUrl } from '../state/hooks/use-destination-url';
@@ -0,0 +1 @@
1
+ export declare const useDestinationUrl: (url: string) => string;
@@ -3,6 +3,6 @@ export declare const getIsFirstPartyLink: (details?: SmartLinkResponse) => boole
3
3
  type UseSmartLinkCrossProductUrlWrapperArgs = {
4
4
  details?: SmartLinkResponse;
5
5
  };
6
- declare const useSmartLinkCrossProductUrlWrapper: ({ details, }: UseSmartLinkCrossProductUrlWrapperArgs) => ((url: string) => string);
6
+ export declare const useSmartLinkCrossProductUrlWrapper: ({ details, }: UseSmartLinkCrossProductUrlWrapperArgs) => ((url: string) => string);
7
7
  export declare const useSmartLinkCrossProductUrlWrapperGated: typeof useSmartLinkCrossProductUrlWrapper;
8
8
  export {};
@@ -0,0 +1 @@
1
+ export { useDestinationUrl as useSmartLinkDestinationUrl } from '../state/hooks/use-destination-url';
@@ -0,0 +1 @@
1
+ export declare const useDestinationUrl: (url: string) => string;
@@ -3,6 +3,6 @@ export declare const getIsFirstPartyLink: (details?: SmartLinkResponse) => boole
3
3
  type UseSmartLinkCrossProductUrlWrapperArgs = {
4
4
  details?: SmartLinkResponse;
5
5
  };
6
- declare const useSmartLinkCrossProductUrlWrapper: ({ details, }: UseSmartLinkCrossProductUrlWrapperArgs) => ((url: string) => string);
6
+ export declare const useSmartLinkCrossProductUrlWrapper: ({ details, }: UseSmartLinkCrossProductUrlWrapperArgs) => ((url: string) => string);
7
7
  export declare const useSmartLinkCrossProductUrlWrapperGated: typeof useSmartLinkCrossProductUrlWrapper;
8
8
  export {};
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@atlaskit/smart-card/hook/use-smart-link-destination-url",
3
+ "main": "../../dist/cjs/entry-points/hook-use-smart-link-destination-url.js",
4
+ "module": "../../dist/esm/entry-points/hook-use-smart-link-destination-url.js",
5
+ "module:es2019": "../../dist/es2019/entry-points/hook-use-smart-link-destination-url.js",
6
+ "sideEffects": [
7
+ "**/*.compiled.css"
8
+ ],
9
+ "types": "../../dist/types/entry-points/hook-use-smart-link-destination-url.d.ts",
10
+ "typesVersions": {
11
+ ">=4.5 <5.9": {
12
+ "*": [
13
+ "../../dist/types-ts4.5/entry-points/hook-use-smart-link-destination-url.d.ts"
14
+ ]
15
+ }
16
+ }
17
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "44.25.1",
3
+ "version": "44.26.1",
4
4
  "description": "Smart card component",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -35,7 +35,7 @@
35
35
  "ak-postbuild": "ls -d dist/* | xargs -n 1 copyfiles -u 1 -V src/**/*.{svg,png}"
36
36
  },
37
37
  "dependencies": {
38
- "@atlaskit/adf-utils": "^19.32.0",
38
+ "@atlaskit/adf-utils": "^19.33.0",
39
39
  "@atlaskit/afm-i18n-platform-linking-platform-smart-card": "2.6.0",
40
40
  "@atlaskit/analytics-cross-product": "^1.2.0",
41
41
  "@atlaskit/analytics-gas-types": "^5.1.0",
@@ -87,7 +87,7 @@
87
87
  "@atlaskit/textfield": "^8.3.0",
88
88
  "@atlaskit/theme": "^25.0.0",
89
89
  "@atlaskit/tile": "^1.1.0",
90
- "@atlaskit/tmp-editor-statsig": "^94.0.0",
90
+ "@atlaskit/tmp-editor-statsig": "^95.0.0",
91
91
  "@atlaskit/tokens": "^13.3.0",
92
92
  "@atlaskit/tooltip": "^22.6.0",
93
93
  "@atlaskit/ufo": "^0.5.0",
@@ -244,6 +244,9 @@
244
244
  "platform_sl_3p_preauth_soc_proof_inline_killswitch": {
245
245
  "type": "boolean"
246
246
  },
247
+ "platform_lp_social_proof_inline_overflow_bug": {
248
+ "type": "boolean"
249
+ },
247
250
  "platform_navx_smart_link_icon_label_a11y": {
248
251
  "type": "boolean"
249
252
  },