@atlaskit/smart-card 44.9.10 → 44.9.11

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 (60) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/__tests__/vr-tests/__snapshots__/inline-card/inline-card-with-all-card-examples-in-text--default--jfp-magma-platform-lozenge-jump-fix-false.png +0 -0
  3. package/dist/cjs/__tests__/vr-tests/__snapshots__/inline-card/inline-card-with-all-card-examples-in-text--default--jfp-magma-platform-lozenge-jump-fix-true.png +0 -0
  4. package/dist/cjs/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-default-state--default.png +0 -0
  5. package/dist/cjs/state/hooks/use-intersection-observer/index.js +2 -1
  6. package/dist/cjs/state/hooks/use-smart-link-seen-event/index.js +66 -0
  7. package/dist/cjs/utils/analytics/SmartLinkAnalyticsContext.js +31 -8
  8. package/dist/cjs/view/CardWithUrl/card-intersection-observer/index.js +25 -20
  9. package/dist/cjs/view/CardWithUrl/component-lazy/LazyIntersectionObserverCard.js +24 -4
  10. package/dist/cjs/view/CardWithUrl/component.js +0 -30
  11. package/dist/cjs/view/InlineCard/Frame/index.js +3 -2
  12. package/dist/cjs/view/LinkUrl/HyperlinkResolver/index.js +0 -41
  13. package/dist/es2019/__tests__/vr-tests/__snapshots__/inline-card/inline-card-with-all-card-examples-in-text--default--jfp-magma-platform-lozenge-jump-fix-false.png +0 -0
  14. package/dist/es2019/__tests__/vr-tests/__snapshots__/inline-card/inline-card-with-all-card-examples-in-text--default--jfp-magma-platform-lozenge-jump-fix-true.png +0 -0
  15. package/dist/es2019/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-default-state--default.png +0 -0
  16. package/dist/es2019/state/hooks/use-intersection-observer/index.js +2 -1
  17. package/dist/es2019/state/hooks/use-smart-link-seen-event/index.js +60 -0
  18. package/dist/es2019/utils/analytics/SmartLinkAnalyticsContext.js +28 -6
  19. package/dist/es2019/view/CardWithUrl/card-intersection-observer/index.js +28 -11
  20. package/dist/es2019/view/CardWithUrl/component-lazy/LazyIntersectionObserverCard.js +25 -4
  21. package/dist/es2019/view/CardWithUrl/component.js +1 -31
  22. package/dist/es2019/view/InlineCard/Frame/index.js +3 -2
  23. package/dist/es2019/view/LinkUrl/HyperlinkResolver/index.js +1 -40
  24. package/dist/esm/__tests__/vr-tests/__snapshots__/inline-card/inline-card-with-all-card-examples-in-text--default--jfp-magma-platform-lozenge-jump-fix-false.png +0 -0
  25. package/dist/esm/__tests__/vr-tests/__snapshots__/inline-card/inline-card-with-all-card-examples-in-text--default--jfp-magma-platform-lozenge-jump-fix-true.png +0 -0
  26. package/dist/esm/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-default-state--default.png +0 -0
  27. package/dist/esm/state/hooks/use-intersection-observer/index.js +2 -1
  28. package/dist/esm/state/hooks/use-smart-link-seen-event/index.js +60 -0
  29. package/dist/esm/utils/analytics/SmartLinkAnalyticsContext.js +31 -8
  30. package/dist/esm/view/CardWithUrl/card-intersection-observer/index.js +26 -21
  31. package/dist/esm/view/CardWithUrl/component-lazy/LazyIntersectionObserverCard.js +24 -4
  32. package/dist/esm/view/CardWithUrl/component.js +1 -31
  33. package/dist/esm/view/InlineCard/Frame/index.js +3 -2
  34. package/dist/esm/view/LinkUrl/HyperlinkResolver/index.js +1 -42
  35. package/dist/types/state/hooks/use-smart-link-seen-event/index.d.ts +14 -0
  36. package/dist/types/utils/analytics/SmartLinkAnalyticsContext.d.ts +10 -0
  37. package/dist/types/view/CardWithUrl/card-intersection-observer/index.d.ts +3 -5
  38. package/dist/types/view/CardWithUrl/types.d.ts +0 -1
  39. package/dist/types-ts4.5/state/hooks/use-smart-link-seen-event/index.d.ts +14 -0
  40. package/dist/types-ts4.5/utils/analytics/SmartLinkAnalyticsContext.d.ts +10 -0
  41. package/dist/types-ts4.5/view/CardWithUrl/card-intersection-observer/index.d.ts +3 -5
  42. package/dist/types-ts4.5/view/CardWithUrl/types.d.ts +0 -1
  43. package/package.json +4 -1
  44. package/dist/cjs/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-default-state-without-connect-button-functionality--default.png +0 -0
  45. package/dist/cjs/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-resolved-state-with-feature-flag-enabled-should-show-no-connect-button---default--platform-editor-resolve-hyperlinks-killswitch-false.png +0 -0
  46. package/dist/cjs/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-resolved-state-with-feature-flag-enabled-should-show-no-connect-button---default--platform-editor-resolve-hyperlinks-killswitch-true.png +0 -0
  47. package/dist/cjs/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-unauthorized-state-with-connect-button-direct-render---always-visible---default.png +0 -0
  48. package/dist/cjs/view/LinkUrl/HyperlinkResolver/unauthorize-view.js +0 -30
  49. package/dist/es2019/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-default-state-without-connect-button-functionality--default.png +0 -0
  50. package/dist/es2019/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-resolved-state-with-feature-flag-enabled-should-show-no-connect-button---default--platform-editor-resolve-hyperlinks-killswitch-false.png +0 -0
  51. package/dist/es2019/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-resolved-state-with-feature-flag-enabled-should-show-no-connect-button---default--platform-editor-resolve-hyperlinks-killswitch-true.png +0 -0
  52. package/dist/es2019/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-unauthorized-state-with-connect-button-direct-render---always-visible---default.png +0 -0
  53. package/dist/es2019/view/LinkUrl/HyperlinkResolver/unauthorize-view.js +0 -22
  54. package/dist/esm/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-default-state-without-connect-button-functionality--default.png +0 -0
  55. package/dist/esm/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-resolved-state-with-feature-flag-enabled-should-show-no-connect-button---default--platform-editor-resolve-hyperlinks-killswitch-false.png +0 -0
  56. package/dist/esm/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-resolved-state-with-feature-flag-enabled-should-show-no-connect-button---default--platform-editor-resolve-hyperlinks-killswitch-true.png +0 -0
  57. package/dist/esm/__tests__/vr-tests/__snapshots__/link-url-connect-button/linkurl-unauthorized-state-with-connect-button-direct-render---always-visible---default.png +0 -0
  58. package/dist/esm/view/LinkUrl/HyperlinkResolver/unauthorize-view.js +0 -23
  59. package/dist/types/view/LinkUrl/HyperlinkResolver/unauthorize-view.d.ts +0 -10
  60. package/dist/types-ts4.5/view/LinkUrl/HyperlinkResolver/unauthorize-view.d.ts +0 -10
@@ -1,14 +1,34 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import React, { useCallback, useState } from 'react';
2
+ import React, { useCallback } from 'react';
3
3
  import useIntersectionObserver from '../../../state/hooks/use-intersection-observer';
4
- import { isIntersectionObserverSupported } from '../../../utils';
4
+ import { useSmartLinkSeenEvent } from '../../../state/hooks/use-smart-link-seen-event';
5
5
  import CardLoaderWrapper from '../card-loader-wrapper';
6
6
  const withCardIntersectionObserver = Component => props => {
7
7
  // TODO: NAVX-4682: Add feature parity to LazyIntersectionObserverCard for no lazy loading
8
- const [isIntersected, setIsIntersected] = useState(false);
9
- const onIntersecting = useCallback(() => {
10
- setIsIntersected(true);
11
- }, []);
8
+ const {
9
+ appearance,
10
+ children,
11
+ id,
12
+ onError: onErrorCallback,
13
+ ui,
14
+ url = ''
15
+ } = props;
16
+ const {
17
+ onIntersecting,
18
+ onStatusSettled
19
+ } = useSmartLinkSeenEvent({
20
+ appearance,
21
+ children,
22
+ id,
23
+ ui,
24
+ url
25
+ });
26
+ const onError = useCallback(data => {
27
+ if (data !== null && data !== void 0 && data.status) {
28
+ onStatusSettled(data.status);
29
+ }
30
+ onErrorCallback === null || onErrorCallback === void 0 ? void 0 : onErrorCallback(data);
31
+ }, [onStatusSettled, onErrorCallback]);
12
32
  const ref = useIntersectionObserver({
13
33
  onIntersecting
14
34
  });
@@ -16,10 +36,7 @@ const withCardIntersectionObserver = Component => props => {
16
36
  appearance: props.appearance,
17
37
  ref: ref
18
38
  }, /*#__PURE__*/React.createElement(Component, _extends({}, props, {
19
- isIntersected: isIntersected
39
+ onError: onError
20
40
  })));
21
41
  };
22
- const withCardIntersectionObserverFallback = Component => props => /*#__PURE__*/React.createElement(CardLoaderWrapper, {
23
- appearance: props.appearance
24
- }, /*#__PURE__*/React.createElement(Component, props));
25
- export default (Component => isIntersectionObserverSupported() ? withCardIntersectionObserver(Component) : withCardIntersectionObserverFallback(Component));
42
+ export default withCardIntersectionObserver;
@@ -4,6 +4,7 @@ import { componentWithFG } from '@atlaskit/platform-feature-flags-react';
4
4
  import { usePrefetch } from '../../../state';
5
5
  import { startUfoExperience } from '../../../state/analytics/ufoExperiences';
6
6
  import useIntersectionObserver from '../../../state/hooks/use-intersection-observer';
7
+ import { useSmartLinkSeenEvent } from '../../../state/hooks/use-smart-link-seen-event';
7
8
  import { shouldSample } from '../../../utils/shouldSample';
8
9
  import CardLoaderWrapper from '../card-loader-wrapper';
9
10
  import { CardWithUrlContent } from '../component';
@@ -62,26 +63,46 @@ const LazyIntersectionObserverCardNew = props => {
62
63
  const [shouldSendRenderedUFOEvent] = useState(shouldSample());
63
64
  const {
64
65
  appearance,
65
- url,
66
- id
66
+ children,
67
+ id,
68
+ onError: onErrorCallback,
69
+ ui,
70
+ url
67
71
  } = props;
68
72
  const prefetch = usePrefetch(url);
69
73
  const ComponentObserver = appearance === 'inline' ? 'span' : 'div';
74
+ const {
75
+ onIntersecting: onSeenIntersecting,
76
+ onStatusSettled
77
+ } = useSmartLinkSeenEvent({
78
+ appearance,
79
+ children,
80
+ id,
81
+ ui,
82
+ url
83
+ });
84
+ const onError = useCallback(data => {
85
+ if (data !== null && data !== void 0 && data.status) {
86
+ onStatusSettled(data.status);
87
+ }
88
+ onErrorCallback === null || onErrorCallback === void 0 ? void 0 : onErrorCallback(data);
89
+ }, [onStatusSettled, onErrorCallback]);
70
90
  const onIntersection = useCallback(isIntersecting => {
71
91
  if (isIntersecting) {
72
92
  if (shouldSendRenderedUFOEvent) {
73
93
  startUfoExperience('smart-link-rendered', id);
74
94
  }
95
+ onSeenIntersecting();
75
96
  setIsIntersected(true);
76
97
  } else {
77
98
  prefetch();
78
99
  }
79
- }, [id, prefetch, shouldSendRenderedUFOEvent]);
100
+ }, [id, onSeenIntersecting, prefetch, shouldSendRenderedUFOEvent]);
80
101
  const ref = useIntersectionObserver({
81
102
  onIntersection
82
103
  });
83
104
  const content = isIntersected ? /*#__PURE__*/React.createElement(CardWithUrlContent, _extends({}, props, {
84
- isIntersected: true
105
+ onError: onError
85
106
  })) : /*#__PURE__*/React.createElement(ComponentObserver, {
86
107
  ref: ref
87
108
  }, /*#__PURE__*/React.createElement(LoadingCardLink, props));
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useEffect, useMemo, useRef } from 'react';
1
+ import React, { useCallback, useEffect, useMemo } from 'react';
2
2
  import { useAnalyticsEvents as useAnalyticsEventsNext } from '@atlaskit/analytics-next';
3
3
  import { extractSmartLinkEmbed } from '@atlaskit/link-extractors';
4
4
  import { fg } from '@atlaskit/platform-feature-flags';
@@ -31,7 +31,6 @@ function Component({
31
31
  url,
32
32
  isSelected,
33
33
  isHovered,
34
- isIntersected,
35
34
  frameStyle,
36
35
  platform,
37
36
  onClick,
@@ -62,7 +61,6 @@ function Component({
62
61
  const {
63
62
  fireEvent
64
63
  } = useAnalyticsEvents();
65
- const hasFiredSeenRef = useRef(false);
66
64
  let isFlexibleUi = useMemo(() => isFlexibleUiCard(children, ui), [children, ui]);
67
65
 
68
66
  // Get state, actions for this card.
@@ -217,19 +215,6 @@ function Component({
217
215
  });
218
216
  }
219
217
  }, [appearance, extensionKey, fireEvent, id, isFlexibleUi, rovoActionsCtaShown, state.status]);
220
-
221
- // Fire smartLink seen event once on a successful render card is in the viewport
222
- useEffect(() => {
223
- if (fg('platform_sl_event_ui_seen')) {
224
- if (state.status !== 'unauthorized') return;
225
- if (isIntersected && !hasFiredSeenRef.current) {
226
- fireEvent('ui.smartLink.seen', {
227
- display: appearance
228
- });
229
- hasFiredSeenRef.current = true;
230
- }
231
- }
232
- }, [state.status, isIntersected, fireEvent, appearance]);
233
218
  const onIframeDwell = useCallback((dwellTime, dwellPercentVisible) => {
234
219
  fireEvent('ui.smartLinkIframe.dwelled', {
235
220
  id,
@@ -352,7 +337,6 @@ function ComponentUpdated({
352
337
  url,
353
338
  isSelected,
354
339
  isHovered,
355
- isIntersected,
356
340
  frameStyle,
357
341
  platform,
358
342
  onClick,
@@ -383,7 +367,6 @@ function ComponentUpdated({
383
367
  const {
384
368
  fireEvent
385
369
  } = useAnalyticsEvents();
386
- const hasFiredSeenRef = useRef(false);
387
370
  let isFlexibleUi = useMemo(() => isFlexibleUiCard(children, ui), [children, ui]);
388
371
 
389
372
  // Get state, actions for this card.
@@ -538,19 +521,6 @@ function ComponentUpdated({
538
521
  });
539
522
  }
540
523
  }, [appearance, extensionKey, fireEvent, id, isFlexibleUi, rovoActionsCtaShown, state.status]);
541
-
542
- // Fire smartLink seen event once on a successful render card is in the viewport
543
- useEffect(() => {
544
- if (fg('platform_sl_event_ui_seen')) {
545
- if (state.status !== 'unauthorized') return;
546
- if (isIntersected && !hasFiredSeenRef.current) {
547
- fireEvent('ui.smartLink.seen', {
548
- display: appearance
549
- });
550
- hasFiredSeenRef.current = true;
551
- }
552
- }
553
- }, [state.status, isIntersected, fireEvent, appearance]);
554
524
  const onIframeDwell = useCallback((dwellTime, dwellPercentVisible) => {
555
525
  fireEvent('ui.smartLinkIframe.dwelled', {
556
526
  id,
@@ -1,4 +1,5 @@
1
1
  import React, { forwardRef, useCallback } from 'react';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import { useMouseDownEvent } from '../../../state/analytics/useLinkClicked';
3
4
  import { WrapperAnchor, WrapperSpan } from './styled';
4
5
  export const Frame = /*#__PURE__*/forwardRef((props, ref) => {
@@ -42,8 +43,8 @@ export const Frame = /*#__PURE__*/forwardRef((props, ref) => {
42
43
  withoutBackground: withoutBackground,
43
44
  isSelected: isSelected,
44
45
  isInteractive: isInteractive,
45
- tabIndex: isInteractive ? 0 : undefined,
46
- role: isInteractive ? 'button' : undefined,
46
+ tabIndex: isInteractive && (fg('navx-3611-inline-card-a11y-role-fix') ? !link : true) ? 0 : undefined,
47
+ role: isInteractive && (fg('navx-3611-inline-card-a11y-role-fix') ? !link : true) ? 'button' : undefined,
47
48
  onClick: handleClick,
48
49
  onMouseDown: handleMouseDown,
49
50
  onKeyPress: handleKeyPress,
@@ -2,17 +2,14 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import React, { useCallback } from 'react';
3
3
  import { withErrorBoundary as withReactErrorBoundary } from 'react-error-boundary';
4
4
  import { injectIntl } from 'react-intl';
5
- import FeatureGates from '@atlaskit/feature-gate-js-client';
6
- import { extractSmartLinkProvider } from '@atlaskit/link-extractors';
7
5
  import { fg } from '@atlaskit/platform-feature-flags';
8
- import { getFirstPartyIdentifier, getServices, getThirdPartyARI } from '../../../state/helpers';
6
+ import { getFirstPartyIdentifier, getThirdPartyARI } from '../../../state/helpers';
9
7
  import useResolveHyperlink from '../../../state/hooks/use-resolve-hyperlink';
10
8
  import useResolveHyperlinkValidator from '../../../state/hooks/use-resolve-hyperlink/useResolveHyperlinkValidator';
11
9
  import { SmartLinkAnalyticsContext } from '../../../utils/analytics/SmartLinkAnalyticsContext';
12
10
  import withIntlProvider from '../../common/intl-provider';
13
11
  import { useFire3PWorkflowsClickEvent } from '../../SmartLinkEvents/useSmartLinkEvents';
14
12
  import Hyperlink from '../Hyperlink';
15
- import HyperlinkUnauthorizedView from './unauthorize-view';
16
13
  const HyperlinkFallbackComponent = () => null;
17
14
  const withValidator = (Component, DefaultComponent) => props => {
18
15
  const shouldResolveHyperlink = useResolveHyperlinkValidator(props === null || props === void 0 ? void 0 : props.href);
@@ -26,12 +23,10 @@ const HyperlinkWithSmartLinkResolverInner = ({
26
23
  ...props
27
24
  }) => {
28
25
  const {
29
- actions,
30
26
  state
31
27
  } = useResolveHyperlink({
32
28
  href: props.href || ''
33
29
  });
34
- const services = getServices(state === null || state === void 0 ? void 0 : state.details);
35
30
  const thirdPartyARI = getThirdPartyARI(state === null || state === void 0 ? void 0 : state.details);
36
31
  const firstPartyIdentifier = getFirstPartyIdentifier();
37
32
  const fire3PClickEvent = fg('platform_smartlink_3pclick_analytics') ?
@@ -46,40 +41,6 @@ const HyperlinkWithSmartLinkResolverInner = ({
46
41
  }
47
42
  onClickCallback === null || onClickCallback === void 0 ? void 0 : onClickCallback(e);
48
43
  }, [onClickCallback, fire3PClickEvent, state === null || state === void 0 ? void 0 : state.status]);
49
- const onAuthorize = useCallback(() => actions.authorize('url'), [actions]);
50
- const shouldRenderConnectBtn = () => {
51
- if (!props.children || !Array.isArray(props.children) || props.children.length === 0) {
52
- return false;
53
- }
54
- const firstChild = props.children[0];
55
- try {
56
- var _firstChild$props;
57
- // Check if first child has a string matching href
58
- if (typeof firstChild === 'string') {
59
- return props.href === firstChild;
60
- }
61
-
62
- // Check if first child has another child object containing matching href. This aligns with the behavior of the TextWrapper component used by editor to render link nodes
63
- if (firstChild !== null && firstChild !== void 0 && (_firstChild$props = firstChild.props) !== null && _firstChild$props !== void 0 && _firstChild$props.children && typeof firstChild.props.children === 'string') {
64
- return props.href === firstChild.props.children;
65
- }
66
- } catch (_) {
67
- return false;
68
- }
69
- };
70
- if ((state === null || state === void 0 ? void 0 : state.status) === 'unauthorized' && shouldRenderConnectBtn() && (
71
- // eslint-disable-next-line @atlaskit/platform/use-recommended-utils -- Statsig migration pending for Bluelink connect experiments
72
- FeatureGates.getExperimentValue('platform_linking_bluelink_connect_confluence', 'isEnabled', false) ||
73
- // eslint-disable-next-line @atlaskit/platform/use-recommended-utils -- Statsig migration pending for Bluelink connect experiments
74
- FeatureGates.getExperimentValue('platform_linking_bluelink_connect_jira', 'isEnabled', false))) {
75
- const provider = extractSmartLinkProvider(state === null || state === void 0 ? void 0 : state.details);
76
- return /*#__PURE__*/React.createElement(HyperlinkUnauthorizedView, _extends({}, props, {
77
- onAuthorize: services !== null && services !== void 0 && services.length ? onAuthorize : undefined,
78
- onClick: onClick,
79
- showConnectBtn: (services === null || services === void 0 ? void 0 : services.length) > 0,
80
- provider: provider
81
- }));
82
- }
83
44
  return /*#__PURE__*/React.createElement(Hyperlink, _extends({}, props, {
84
45
  onClick: onClick
85
46
  }));
@@ -1,4 +1,5 @@
1
1
  import { useCallback, useEffect, useRef } from 'react';
2
+ import { isIntersectionObserverSupported } from '../../../utils';
2
3
 
3
4
  // This property enables the intersection observer to be run once the
4
5
  // HTML element being observed is within `X` px of the target container it is
@@ -28,7 +29,7 @@ var useIntersectionObserver = function useIntersectionObserver(_ref) {
28
29
  }
29
30
  }, []);
30
31
  useEffect(function () {
31
- if (!ref.current) {
32
+ if (!isIntersectionObserverSupported() || !ref.current) {
32
33
  return;
33
34
  }
34
35
  var intersectionObserver = new IntersectionObserver(onIntersection, {
@@ -0,0 +1,60 @@
1
+ import { useCallback, useEffect, useMemo, useRef } from 'react';
2
+ import { useAnalyticsEvents } from '../../../common/analytics/generated/use-analytics-events';
3
+ import { useSmartLinkAnalyticsUtils } from '../../../utils/analytics/SmartLinkAnalyticsContext';
4
+ import { isFlexibleUiCard } from '../../../utils/flexible';
5
+ /**
6
+ * Fires `ui.smartLink.seen` once when a smart link with status `unauthorized`
7
+ * enters the viewport. Uses refs internally so it never causes re-renders,
8
+ * which is important for SSR.
9
+ */
10
+ export function useSmartLinkSeenEvent(_ref) {
11
+ var appearance = _ref.appearance,
12
+ children = _ref.children,
13
+ id = _ref.id,
14
+ ui = _ref.ui,
15
+ _ref$url = _ref.url,
16
+ url = _ref$url === void 0 ? '' : _ref$url;
17
+ var _useAnalyticsEvents = useAnalyticsEvents(),
18
+ fireEvent = _useAnalyticsEvents.fireEvent;
19
+ var _useSmartLinkAnalytic = useSmartLinkAnalyticsUtils(),
20
+ getByUrl = _useSmartLinkAnalytic.getByUrl;
21
+ var getAnalyticsProps = useCallback(function () {
22
+ var isFlexibleUi = isFlexibleUiCard(children, ui);
23
+ var display = isFlexibleUi ? 'flexible' : appearance;
24
+ return {
25
+ display: display,
26
+ id: id
27
+ };
28
+ }, [appearance, children, id, ui]);
29
+ var statusRef = useRef();
30
+ var analyticsPropsRef = useRef(null);
31
+ var hasIntersectedRef = useRef(false);
32
+ var hasFiredSeenRef = useRef(false);
33
+ useEffect(function () {
34
+ analyticsPropsRef.current = getAnalyticsProps();
35
+ }, [getAnalyticsProps]);
36
+ var maybeFireSeenEvent = useCallback(function () {
37
+ if (!hasFiredSeenRef.current && hasIntersectedRef.current && statusRef.current === 'unauthorized') {
38
+ var payload = getByUrl(url, analyticsPropsRef.current);
39
+ fireEvent('ui.smartLink.seen', payload === null || payload === void 0 ? void 0 : payload.attributes);
40
+ hasFiredSeenRef.current = true;
41
+ }
42
+ }, [fireEvent, getByUrl, url]);
43
+ var onIntersecting = useCallback(function () {
44
+ if (hasIntersectedRef.current) {
45
+ return;
46
+ }
47
+ hasIntersectedRef.current = true;
48
+ maybeFireSeenEvent();
49
+ }, [maybeFireSeenEvent]);
50
+ var onStatusSettled = useCallback(function (status) {
51
+ statusRef.current = status;
52
+ maybeFireSeenEvent();
53
+ }, [maybeFireSeenEvent]);
54
+ return useMemo(function () {
55
+ return {
56
+ onIntersecting: onIntersecting,
57
+ onStatusSettled: onStatusSettled
58
+ };
59
+ }, [onIntersecting, onStatusSettled]);
60
+ }
@@ -1,9 +1,8 @@
1
1
  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
- import React, { useMemo } from 'react';
4
+ import React, { useCallback, useMemo } from 'react';
5
5
  import { AnalyticsContext } from '@atlaskit/analytics-next';
6
- import FeatureGates from '@atlaskit/feature-gate-js-client';
7
6
  import { getResolvedAttributes } from '@atlaskit/link-analytics/resolved-attributes';
8
7
  import { useSmartLinkContext } from '@atlaskit/link-provider';
9
8
  import { getUrl } from '@atlaskit/linking-common';
@@ -25,12 +24,9 @@ var getSmartLinkAnalyticsContext = function getSmartLinkAnalyticsContext(_ref) {
25
24
  status = _ref.status,
26
25
  url = _ref.url,
27
26
  error = _ref.error;
28
- var isHyperlinkConnectExperimentEnabled = FeatureGates.getExperimentValue('platform_linking_bluelink_connect_confluence', 'isEnabled', false) || FeatureGates.getExperimentValue('platform_linking_bluelink_connect_jira', 'isEnabled', false);
29
- var resolvedAttributes = isHyperlinkConnectExperimentEnabled ? getExtendedResolvedAttributes({
27
+ var resolvedAttributes = getExtendedResolvedAttributes({
30
28
  url: url,
31
29
  displayCategory: display === 'url' ? 'link' : 'smartLink'
32
- }, response, status, error) : getExtendedResolvedAttributes({
33
- url: url
34
30
  }, response, status, error);
35
31
  return {
36
32
  source: source,
@@ -44,13 +40,40 @@ var getSmartLinkAnalyticsContext = function getSmartLinkAnalyticsContext(_ref) {
44
40
  * Provides an analytics context data to supply attributes to events based on a URL
45
41
  * and the link state in the store
46
42
  */
43
+ export var useSmartLinkAnalyticsUtils = function useSmartLinkAnalyticsUtils() {
44
+ var _useSmartLinkContext = useSmartLinkContext(),
45
+ store = _useSmartLinkContext.store;
46
+ var getByUrl = useCallback(function (url, props) {
47
+ var state = store ? getUrl(store, url) : undefined;
48
+ return getSmartLinkAnalyticsContext({
49
+ display: props === null || props === void 0 ? void 0 : props.display,
50
+ id: props === null || props === void 0 ? void 0 : props.id,
51
+ response: state === null || state === void 0 ? void 0 : state.details,
52
+ source: props === null || props === void 0 ? void 0 : props.source,
53
+ status: state === null || state === void 0 ? void 0 : state.status,
54
+ url: url,
55
+ error: state === null || state === void 0 ? void 0 : state.error
56
+ });
57
+ }, [store]);
58
+ return useMemo(function () {
59
+ return {
60
+ getByUrl: getByUrl
61
+ };
62
+ }, [getByUrl]);
63
+ };
64
+
65
+ /**
66
+ * Provides an analytics context data to supply attributes to events based on a URL
67
+ * and the link state in the store
68
+ * @deprecated Use useSmartLinkAnalyticsUtils instead
69
+ */
47
70
  export var useSmartLinkAnalyticsContext = function useSmartLinkAnalyticsContext(_ref2) {
48
71
  var display = _ref2.display,
49
72
  id = _ref2.id,
50
73
  source = _ref2.source,
51
74
  url = _ref2.url;
52
- var _useSmartLinkContext = useSmartLinkContext(),
53
- store = _useSmartLinkContext.store;
75
+ var _useSmartLinkContext2 = useSmartLinkContext(),
76
+ store = _useSmartLinkContext2.store;
54
77
  var state = store ? getUrl(store, url) : undefined;
55
78
  return useMemo(function () {
56
79
  return getSmartLinkAnalyticsContext({
@@ -1,19 +1,33 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
- import React, { useCallback, useState } from 'react';
2
+ import React, { useCallback } from 'react';
4
3
  import useIntersectionObserver from '../../../state/hooks/use-intersection-observer';
5
- import { isIntersectionObserverSupported } from '../../../utils';
4
+ import { useSmartLinkSeenEvent } from '../../../state/hooks/use-smart-link-seen-event';
6
5
  import CardLoaderWrapper from '../card-loader-wrapper';
7
6
  var withCardIntersectionObserver = function withCardIntersectionObserver(Component) {
8
7
  return function (props) {
9
8
  // TODO: NAVX-4682: Add feature parity to LazyIntersectionObserverCard for no lazy loading
10
- var _useState = useState(false),
11
- _useState2 = _slicedToArray(_useState, 2),
12
- isIntersected = _useState2[0],
13
- setIsIntersected = _useState2[1];
14
- var onIntersecting = useCallback(function () {
15
- setIsIntersected(true);
16
- }, []);
9
+ var appearance = props.appearance,
10
+ children = props.children,
11
+ id = props.id,
12
+ onErrorCallback = props.onError,
13
+ ui = props.ui,
14
+ _props$url = props.url,
15
+ url = _props$url === void 0 ? '' : _props$url;
16
+ var _useSmartLinkSeenEven = useSmartLinkSeenEvent({
17
+ appearance: appearance,
18
+ children: children,
19
+ id: id,
20
+ ui: ui,
21
+ url: url
22
+ }),
23
+ onIntersecting = _useSmartLinkSeenEven.onIntersecting,
24
+ onStatusSettled = _useSmartLinkSeenEven.onStatusSettled;
25
+ var onError = useCallback(function (data) {
26
+ if (data !== null && data !== void 0 && data.status) {
27
+ onStatusSettled(data.status);
28
+ }
29
+ onErrorCallback === null || onErrorCallback === void 0 || onErrorCallback(data);
30
+ }, [onStatusSettled, onErrorCallback]);
17
31
  var ref = useIntersectionObserver({
18
32
  onIntersecting: onIntersecting
19
33
  });
@@ -21,17 +35,8 @@ var withCardIntersectionObserver = function withCardIntersectionObserver(Compone
21
35
  appearance: props.appearance,
22
36
  ref: ref
23
37
  }, /*#__PURE__*/React.createElement(Component, _extends({}, props, {
24
- isIntersected: isIntersected
38
+ onError: onError
25
39
  })));
26
40
  };
27
41
  };
28
- var withCardIntersectionObserverFallback = function withCardIntersectionObserverFallback(Component) {
29
- return function (props) {
30
- return /*#__PURE__*/React.createElement(CardLoaderWrapper, {
31
- appearance: props.appearance
32
- }, /*#__PURE__*/React.createElement(Component, props));
33
- };
34
- };
35
- export default (function (Component) {
36
- return isIntersectionObserverSupported() ? withCardIntersectionObserver(Component) : withCardIntersectionObserverFallback(Component);
37
- });
42
+ export default withCardIntersectionObserver;
@@ -5,6 +5,7 @@ import { componentWithFG } from '@atlaskit/platform-feature-flags-react';
5
5
  import { usePrefetch } from '../../../state';
6
6
  import { startUfoExperience } from '../../../state/analytics/ufoExperiences';
7
7
  import useIntersectionObserver from '../../../state/hooks/use-intersection-observer';
8
+ import { useSmartLinkSeenEvent } from '../../../state/hooks/use-smart-link-seen-event';
8
9
  import { shouldSample } from '../../../utils/shouldSample';
9
10
  import CardLoaderWrapper from '../card-loader-wrapper';
10
11
  import { CardWithUrlContent } from '../component';
@@ -74,25 +75,44 @@ var LazyIntersectionObserverCardNew = function LazyIntersectionObserverCardNew(p
74
75
  _useState8 = _slicedToArray(_useState7, 1),
75
76
  shouldSendRenderedUFOEvent = _useState8[0];
76
77
  var appearance = props.appearance,
77
- url = props.url,
78
- id = props.id;
78
+ children = props.children,
79
+ id = props.id,
80
+ onErrorCallback = props.onError,
81
+ ui = props.ui,
82
+ url = props.url;
79
83
  var prefetch = usePrefetch(url);
80
84
  var ComponentObserver = appearance === 'inline' ? 'span' : 'div';
85
+ var _useSmartLinkSeenEven = useSmartLinkSeenEvent({
86
+ appearance: appearance,
87
+ children: children,
88
+ id: id,
89
+ ui: ui,
90
+ url: url
91
+ }),
92
+ onSeenIntersecting = _useSmartLinkSeenEven.onIntersecting,
93
+ onStatusSettled = _useSmartLinkSeenEven.onStatusSettled;
94
+ var onError = useCallback(function (data) {
95
+ if (data !== null && data !== void 0 && data.status) {
96
+ onStatusSettled(data.status);
97
+ }
98
+ onErrorCallback === null || onErrorCallback === void 0 || onErrorCallback(data);
99
+ }, [onStatusSettled, onErrorCallback]);
81
100
  var onIntersection = useCallback(function (isIntersecting) {
82
101
  if (isIntersecting) {
83
102
  if (shouldSendRenderedUFOEvent) {
84
103
  startUfoExperience('smart-link-rendered', id);
85
104
  }
105
+ onSeenIntersecting();
86
106
  setIsIntersected(true);
87
107
  } else {
88
108
  prefetch();
89
109
  }
90
- }, [id, prefetch, shouldSendRenderedUFOEvent]);
110
+ }, [id, onSeenIntersecting, prefetch, shouldSendRenderedUFOEvent]);
91
111
  var ref = useIntersectionObserver({
92
112
  onIntersection: onIntersection
93
113
  });
94
114
  var content = isIntersected ? /*#__PURE__*/React.createElement(CardWithUrlContent, _extends({}, props, {
95
- isIntersected: true
115
+ onError: onError
96
116
  })) : /*#__PURE__*/React.createElement(ComponentObserver, {
97
117
  ref: ref
98
118
  }, /*#__PURE__*/React.createElement(LoadingCardLink, props));
@@ -1,7 +1,7 @@
1
1
  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
- import React, { useCallback, useEffect, useMemo, useRef } from 'react';
4
+ import React, { useCallback, useEffect, useMemo } from 'react';
5
5
  import { useAnalyticsEvents as useAnalyticsEventsNext } from '@atlaskit/analytics-next';
6
6
  import { extractSmartLinkEmbed } from '@atlaskit/link-extractors';
7
7
  import { fg } from '@atlaskit/platform-feature-flags';
@@ -34,7 +34,6 @@ function Component(_ref) {
34
34
  url = _ref.url,
35
35
  isSelected = _ref.isSelected,
36
36
  isHovered = _ref.isHovered,
37
- isIntersected = _ref.isIntersected,
38
37
  frameStyle = _ref.frameStyle,
39
38
  platform = _ref.platform,
40
39
  onClick = _ref.onClick,
@@ -62,7 +61,6 @@ function Component(_ref) {
62
61
  createAnalyticsEvent = _useAnalyticsEventsNe.createAnalyticsEvent;
63
62
  var _useAnalyticsEvents = useAnalyticsEvents(),
64
63
  fireEvent = _useAnalyticsEvents.fireEvent;
65
- var hasFiredSeenRef = useRef(false);
66
64
  var isFlexibleUi = useMemo(function () {
67
65
  return isFlexibleUiCard(children, ui);
68
66
  }, [children, ui]);
@@ -220,19 +218,6 @@ function Component(_ref) {
220
218
  }));
221
219
  }
222
220
  }, [appearance, extensionKey, fireEvent, id, isFlexibleUi, rovoActionsCtaShown, state.status]);
223
-
224
- // Fire smartLink seen event once on a successful render card is in the viewport
225
- useEffect(function () {
226
- if (fg('platform_sl_event_ui_seen')) {
227
- if (state.status !== 'unauthorized') return;
228
- if (isIntersected && !hasFiredSeenRef.current) {
229
- fireEvent('ui.smartLink.seen', {
230
- display: appearance
231
- });
232
- hasFiredSeenRef.current = true;
233
- }
234
- }
235
- }, [state.status, isIntersected, fireEvent, appearance]);
236
221
  var onIframeDwell = useCallback(function (dwellTime, dwellPercentVisible) {
237
222
  fireEvent('ui.smartLinkIframe.dwelled', {
238
223
  id: id,
@@ -355,7 +340,6 @@ function ComponentUpdated(_ref2) {
355
340
  url = _ref2.url,
356
341
  isSelected = _ref2.isSelected,
357
342
  isHovered = _ref2.isHovered,
358
- isIntersected = _ref2.isIntersected,
359
343
  frameStyle = _ref2.frameStyle,
360
344
  platform = _ref2.platform,
361
345
  onClick = _ref2.onClick,
@@ -383,7 +367,6 @@ function ComponentUpdated(_ref2) {
383
367
  createAnalyticsEvent = _useAnalyticsEventsNe2.createAnalyticsEvent;
384
368
  var _useAnalyticsEvents2 = useAnalyticsEvents(),
385
369
  fireEvent = _useAnalyticsEvents2.fireEvent;
386
- var hasFiredSeenRef = useRef(false);
387
370
  var isFlexibleUi = useMemo(function () {
388
371
  return isFlexibleUiCard(children, ui);
389
372
  }, [children, ui]);
@@ -541,19 +524,6 @@ function ComponentUpdated(_ref2) {
541
524
  }));
542
525
  }
543
526
  }, [appearance, extensionKey, fireEvent, id, isFlexibleUi, rovoActionsCtaShown, state.status]);
544
-
545
- // Fire smartLink seen event once on a successful render card is in the viewport
546
- useEffect(function () {
547
- if (fg('platform_sl_event_ui_seen')) {
548
- if (state.status !== 'unauthorized') return;
549
- if (isIntersected && !hasFiredSeenRef.current) {
550
- fireEvent('ui.smartLink.seen', {
551
- display: appearance
552
- });
553
- hasFiredSeenRef.current = true;
554
- }
555
- }
556
- }, [state.status, isIntersected, fireEvent, appearance]);
557
527
  var onIframeDwell = useCallback(function (dwellTime, dwellPercentVisible) {
558
528
  fireEvent('ui.smartLinkIframe.dwelled', {
559
529
  id: id,
@@ -1,4 +1,5 @@
1
1
  import React, { forwardRef, useCallback } from 'react';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import { useMouseDownEvent } from '../../../state/analytics/useLinkClicked';
3
4
  import { WrapperAnchor, WrapperSpan } from './styled';
4
5
  export var Frame = /*#__PURE__*/forwardRef(function (props, ref) {
@@ -40,8 +41,8 @@ export var Frame = /*#__PURE__*/forwardRef(function (props, ref) {
40
41
  withoutBackground: withoutBackground,
41
42
  isSelected: isSelected,
42
43
  isInteractive: isInteractive,
43
- tabIndex: isInteractive ? 0 : undefined,
44
- role: isInteractive ? 'button' : undefined,
44
+ tabIndex: isInteractive && (fg('navx-3611-inline-card-a11y-role-fix') ? !link : true) ? 0 : undefined,
45
+ role: isInteractive && (fg('navx-3611-inline-card-a11y-role-fix') ? !link : true) ? 'button' : undefined,
45
46
  onClick: handleClick,
46
47
  onMouseDown: handleMouseDown,
47
48
  onKeyPress: handleKeyPress,