@atlaskit/smart-card 44.3.1 → 44.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/analytics.spec.yaml +9 -0
  3. package/dist/cjs/__tests__/vr-tests/__snapshots__/hover-card/hover-card-with-generic-3p-rovo-chat-action--default.png +0 -0
  4. package/dist/cjs/messages.js +0 -10
  5. package/dist/cjs/ssr.js +28 -1
  6. package/dist/cjs/state/hooks/use-intersection-observer/index.js +49 -0
  7. package/dist/cjs/view/CardWithUrl/card-error-boundary/index.js +28 -0
  8. package/dist/cjs/view/CardWithUrl/card-intersection-observer/index.js +46 -0
  9. package/dist/cjs/view/CardWithUrl/card-loader-wrapper/index.js +23 -0
  10. package/dist/cjs/view/CardWithUrl/component-lazy/LazyIntersectionObserverCard.js +43 -3
  11. package/dist/cjs/view/CardWithUrl/component.js +34 -2
  12. package/dist/cjs/view/FlexibleCard/components/actions/rovo-chat-action/index.js +3 -2
  13. package/dist/es2019/__tests__/vr-tests/__snapshots__/hover-card/hover-card-with-generic-3p-rovo-chat-action--default.png +0 -0
  14. package/dist/es2019/messages.js +0 -10
  15. package/dist/es2019/ssr.js +28 -2
  16. package/dist/es2019/state/hooks/use-intersection-observer/index.js +41 -0
  17. package/dist/es2019/view/CardWithUrl/card-error-boundary/index.js +20 -0
  18. package/dist/es2019/view/CardWithUrl/card-intersection-observer/index.js +25 -0
  19. package/dist/es2019/view/CardWithUrl/card-loader-wrapper/index.js +16 -0
  20. package/dist/es2019/view/CardWithUrl/component-lazy/LazyIntersectionObserverCard.js +39 -2
  21. package/dist/es2019/view/CardWithUrl/component.js +34 -2
  22. package/dist/es2019/view/FlexibleCard/components/actions/rovo-chat-action/index.js +3 -2
  23. package/dist/esm/__tests__/vr-tests/__snapshots__/hover-card/hover-card-with-generic-3p-rovo-chat-action--default.png +0 -0
  24. package/dist/esm/messages.js +0 -10
  25. package/dist/esm/ssr.js +29 -2
  26. package/dist/esm/state/hooks/use-intersection-observer/index.js +44 -0
  27. package/dist/esm/view/CardWithUrl/card-error-boundary/index.js +21 -0
  28. package/dist/esm/view/CardWithUrl/card-intersection-observer/index.js +37 -0
  29. package/dist/esm/view/CardWithUrl/card-loader-wrapper/index.js +15 -0
  30. package/dist/esm/view/CardWithUrl/component-lazy/LazyIntersectionObserverCard.js +42 -2
  31. package/dist/esm/view/CardWithUrl/component.js +34 -2
  32. package/dist/esm/view/FlexibleCard/components/actions/rovo-chat-action/index.js +3 -2
  33. package/dist/types/common/analytics/generated/analytics.types.d.ts +7 -1
  34. package/dist/types/messages.d.ts +1 -1
  35. package/dist/types/state/hooks/use-intersection-observer/index.d.ts +6 -0
  36. package/dist/types/view/CardWithUrl/card-error-boundary/index.d.ts +5 -0
  37. package/dist/types/view/CardWithUrl/card-intersection-observer/index.d.ts +7 -0
  38. package/dist/types/view/CardWithUrl/card-loader-wrapper/index.d.ts +7 -0
  39. package/dist/types/view/CardWithUrl/component-lazy/LazyIntersectionObserverCard.d.ts +1 -1
  40. package/dist/types/view/CardWithUrl/component.d.ts +1 -0
  41. package/dist/types/view/CardWithUrl/types.d.ts +1 -0
  42. package/dist/types-ts4.5/common/analytics/generated/analytics.types.d.ts +7 -1
  43. package/dist/types-ts4.5/messages.d.ts +1 -1
  44. package/dist/types-ts4.5/state/hooks/use-intersection-observer/index.d.ts +6 -0
  45. package/dist/types-ts4.5/view/CardWithUrl/card-error-boundary/index.d.ts +5 -0
  46. package/dist/types-ts4.5/view/CardWithUrl/card-intersection-observer/index.d.ts +7 -0
  47. package/dist/types-ts4.5/view/CardWithUrl/card-loader-wrapper/index.d.ts +7 -0
  48. package/dist/types-ts4.5/view/CardWithUrl/component-lazy/LazyIntersectionObserverCard.d.ts +1 -1
  49. package/dist/types-ts4.5/view/CardWithUrl/component.d.ts +1 -0
  50. package/dist/types-ts4.5/view/CardWithUrl/types.d.ts +1 -0
  51. package/package.json +7 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/smart-card
2
2
 
3
+ ## 44.3.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`d2102caf5dde7`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d2102caf5dde7) -
8
+ [ux] Change post auth SL experiment "Key highlights" prompt to "Highlight what's relevant"
9
+
10
+ ## 44.3.2
11
+
12
+ ### Patch Changes
13
+
14
+ - [`dee5bdcb8345a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/dee5bdcb8345a) -
15
+ Fire analytics event when SL intesects into viewport
16
+ - Updated dependencies
17
+
3
18
  ## 44.3.1
4
19
 
5
20
  ### Patch Changes
@@ -851,6 +851,15 @@ events:
851
851
  required: false
852
852
  type: string
853
853
  description: The unique ID for this Smart Link
854
+ - smartLink seen:
855
+ type: ui
856
+ description: fires an event that represents when a rendered Smart Link is visible in the viewport for the first time
857
+ attributes:
858
+ <<: [*PackageMetaDataContext, *CommonContext, *ResolvedContext]
859
+ display:
860
+ required: true
861
+ type: ['inline', 'block', 'embed', 'flexible']
862
+ description: Whether the card was an Inline, Block, Embed or Flexible UI
854
863
  - smartLink clicked (smartlinkClickAnalyticsWorkflows):
855
864
  type: ui
856
865
  description:
@@ -957,16 +957,6 @@ var messages = exports.messages = (0, _reactIntl.defineMessages)({
957
957
  defaultMessage: '<p>Summarize the main ideas and key points of <a>{url}</a> in 3-5 clear, complete sentences.</p><p>Preserve any important details such as names, dates, and key decisions.</p>',
958
958
  description: 'The prompt message to send to Rovo Chat. {url} refers to Smart Link that the user triggers this action from. (Please make sure all html tags remain the same.)'
959
959
  },
960
- rovo_prompt_button_key_highlights: {
961
- id: 'fabric.linking.rovo_prompt_button_key_highlights.non-final',
962
- defaultMessage: 'Key highlights',
963
- description: 'The name of the action to send a key highlights prompt message to Rovo Chat in relation to current Smart Link'
964
- },
965
- rovo_prompt_message_key_highlights: {
966
- id: 'fabric.linking.rovo_prompt_message_key_highlights.non-final',
967
- defaultMessage: "<p>Based on <a>{url}</a> and the page or ticket I'm currently viewing, highlight the parts of the linked content that are most relevant to this work. Explain briefly why each part is relevant.</p>",
968
- description: 'The prompt message to send to Rovo Chat. {url} refers to Smart Link that the user triggers this action from. (Please make sure all html tags remain the same.)'
969
- },
970
960
  rovo_prompt_button_ask_rovo_anything: {
971
961
  id: 'fabric.linking.rovo_prompt_button_ask_rovo.non-final',
972
962
  defaultMessage: 'Ask Rovo',
package/dist/cjs/ssr.js CHANGED
@@ -12,7 +12,9 @@ var _react = _interopRequireWildcard(require("react"));
12
12
  var _reactErrorBoundary = require("react-error-boundary");
13
13
  var _uuid = _interopRequireDefault(require("uuid"));
14
14
  var _analyticsNext = require("@atlaskit/analytics-next");
15
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
15
16
  var _analytics = require("./utils/analytics/analytics");
17
+ var _cardErrorBoundary = _interopRequireDefault(require("./view/CardWithUrl/card-error-boundary"));
16
18
  var _component = require("./view/CardWithUrl/component");
17
19
  var _LoadingCardLink = require("./view/CardWithUrl/component-lazy/LoadingCardLink");
18
20
  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); }
@@ -21,7 +23,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
21
23
  // SSR friendly version of smart-card
22
24
  // simplifies the logic around rendering and loading placeholders and
23
25
  // only contains whats necessary to render the card on SSR mode
24
- var CardSSR = exports.CardSSR = function CardSSR(props) {
26
+ var CardSSROld = function CardSSROld(props) {
25
27
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
26
28
  var _useState = (0, _react.useState)(function () {
27
29
  var _props$id;
@@ -47,4 +49,29 @@ var CardSSR = exports.CardSSR = function CardSSR(props) {
47
49
  }, /*#__PURE__*/_react.default.createElement(Component, {
48
50
  className: "loader-wrapper"
49
51
  }, /*#__PURE__*/_react.default.createElement(_component.CardWithUrlContent, cardProps))));
52
+ };
53
+
54
+ // SSR friendly version of smart-card
55
+ // simplifies the logic around rendering and loading placeholders and
56
+ // only contains whats necessary to render the card on SSR mode
57
+ var CardSSRNew = function CardSSRNew(props) {
58
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
59
+ var _useState3 = (0, _react.useState)(function () {
60
+ var _props$id2;
61
+ return (_props$id2 = props.id) !== null && _props$id2 !== void 0 ? _props$id2 : (0, _uuid.default)();
62
+ }),
63
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 1),
64
+ id = _useState4[0];
65
+ var propsWithId = _objectSpread(_objectSpread({}, props), {}, {
66
+ id: id
67
+ });
68
+ return /*#__PURE__*/_react.default.createElement(_analyticsNext.AnalyticsContext, {
69
+ data: _analytics.context
70
+ }, /*#__PURE__*/_react.default.createElement(_cardErrorBoundary.default, propsWithId, /*#__PURE__*/_react.default.createElement(_component.CardWithUrl, propsWithId)));
71
+ };
72
+ var CardSSR = exports.CardSSR = function CardSSR(props) {
73
+ if ((0, _platformFeatureFlags.fg)('platform_sl_event_ui_seen')) {
74
+ return /*#__PURE__*/_react.default.createElement(CardSSRNew, props);
75
+ }
76
+ return /*#__PURE__*/_react.default.createElement(CardSSROld, props);
50
77
  };
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = require("react");
8
+ // This property enables the intersection observer to be run once the
9
+ // HTML element being observed is within `X` px of the target container it is
10
+ // being compared to. Since the default container is the `document`, we set this
11
+ // up to check once a Smart Link is within `X` px from the bottom of the viewport.
12
+ var ROOT_MARGIN_VERTICAL = '360px';
13
+ var useIntersectionObserver = function useIntersectionObserver(_ref) {
14
+ var onIntersectingCallback = _ref.onIntersecting,
15
+ onIntersectionCallback = _ref.onIntersection;
16
+ var ref = (0, _react.useRef)(null);
17
+ var onIntersectingCallbackRef = (0, _react.useRef)(onIntersectingCallback);
18
+ var onIntersectionCallbackRef = (0, _react.useRef)(onIntersectionCallback);
19
+ (0, _react.useEffect)(function () {
20
+ onIntersectingCallbackRef.current = onIntersectingCallback;
21
+ onIntersectionCallbackRef.current = onIntersectionCallback;
22
+ }, [onIntersectingCallback, onIntersectionCallback]);
23
+ var onIntersection = (0, _react.useCallback)(function (entries, observer) {
24
+ var _onIntersectionCallba;
25
+ var isIntersecting = entries.some(function (entry) {
26
+ return entry.isIntersecting;
27
+ });
28
+ (_onIntersectionCallba = onIntersectionCallbackRef.current) === null || _onIntersectionCallba === void 0 || _onIntersectionCallba.call(onIntersectionCallbackRef, isIntersecting);
29
+ if (isIntersecting) {
30
+ var _onIntersectingCallba;
31
+ (_onIntersectingCallba = onIntersectingCallbackRef.current) === null || _onIntersectingCallba === void 0 || _onIntersectingCallba.call(onIntersectingCallbackRef);
32
+ observer.disconnect();
33
+ }
34
+ }, []);
35
+ (0, _react.useEffect)(function () {
36
+ if (!ref.current) {
37
+ return;
38
+ }
39
+ var intersectionObserver = new IntersectionObserver(onIntersection, {
40
+ rootMargin: "".concat(ROOT_MARGIN_VERTICAL, " 0px ").concat(ROOT_MARGIN_VERTICAL, " 0px")
41
+ });
42
+ intersectionObserver.observe(ref.current);
43
+ return function () {
44
+ return intersectionObserver.disconnect();
45
+ };
46
+ }, [ref, onIntersection]);
47
+ return ref;
48
+ };
49
+ var _default = exports.default = useIntersectionObserver;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
9
+ var _react = _interopRequireDefault(require("react"));
10
+ var _reactErrorBoundary = require("react-error-boundary");
11
+ var _LoadingCardLink = require("../component-lazy/LoadingCardLink");
12
+ var _excluded = ["children"];
13
+ var CardErrorBoundary = function CardErrorBoundary(_ref) {
14
+ var children = _ref.children,
15
+ props = (0, _objectWithoutProperties2.default)(_ref, _excluded);
16
+ // TODO: NAVX-4682: Add feature parity to CardWithURLRenderer
17
+ var ErrorFallbackComponent = props.fallbackComponent;
18
+ var errorBoundaryFallbackComponent = function errorBoundaryFallbackComponent() {
19
+ if (ErrorFallbackComponent) {
20
+ return /*#__PURE__*/_react.default.createElement(ErrorFallbackComponent, null);
21
+ }
22
+ return /*#__PURE__*/_react.default.createElement(_LoadingCardLink.LoadingCardLink, props);
23
+ };
24
+ return /*#__PURE__*/_react.default.createElement(_reactErrorBoundary.ErrorBoundary, {
25
+ FallbackComponent: errorBoundaryFallbackComponent
26
+ }, children);
27
+ };
28
+ var _default = exports.default = CardErrorBoundary;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
+ var _react = _interopRequireWildcard(require("react"));
12
+ var _useIntersectionObserver = _interopRequireDefault(require("../../../state/hooks/use-intersection-observer"));
13
+ var _utils = require("../../../utils");
14
+ var _cardLoaderWrapper = _interopRequireDefault(require("../card-loader-wrapper"));
15
+ 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); }
16
+ var withCardIntersectionObserver = function withCardIntersectionObserver(Component) {
17
+ return function (props) {
18
+ // TODO: NAVX-4682: Add feature parity to LazyIntersectionObserverCard for no lazy loading
19
+ var _useState = (0, _react.useState)(false),
20
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
21
+ isIntersected = _useState2[0],
22
+ setIsIntersected = _useState2[1];
23
+ var onIntersecting = (0, _react.useCallback)(function () {
24
+ setIsIntersected(true);
25
+ }, []);
26
+ var ref = (0, _useIntersectionObserver.default)({
27
+ onIntersecting: onIntersecting
28
+ });
29
+ return /*#__PURE__*/_react.default.createElement(_cardLoaderWrapper.default, {
30
+ appearance: props.appearance,
31
+ ref: ref
32
+ }, /*#__PURE__*/_react.default.createElement(Component, (0, _extends2.default)({}, props, {
33
+ isIntersected: isIntersected
34
+ })));
35
+ };
36
+ };
37
+ var withCardIntersectionObserverFallback = function withCardIntersectionObserverFallback(Component) {
38
+ return function (props) {
39
+ return /*#__PURE__*/_react.default.createElement(_cardLoaderWrapper.default, {
40
+ appearance: props.appearance
41
+ }, /*#__PURE__*/_react.default.createElement(Component, props));
42
+ };
43
+ };
44
+ var _default = exports.default = function _default(Component) {
45
+ return (0, _utils.isIntersectionObserverSupported)() ? withCardIntersectionObserver(Component) : withCardIntersectionObserverFallback(Component);
46
+ };
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ 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); }
10
+ var CardLoaderWrapper = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
11
+ var appearance = _ref.appearance,
12
+ children = _ref.children;
13
+ var Component = appearance === 'inline' ? 'span' : 'div';
14
+ return (
15
+ /*#__PURE__*/
16
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
17
+ _react.default.createElement(Component, {
18
+ className: "loader-wrapper",
19
+ ref: ref
20
+ }, children)
21
+ );
22
+ });
23
+ var _default = exports.default = CardLoaderWrapper;
@@ -5,12 +5,16 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.LazyIntersectionObserverCard = LazyIntersectionObserverCard;
8
+ exports.LazyIntersectionObserverCard = void 0;
9
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
10
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
11
  var _react = _interopRequireWildcard(require("react"));
12
+ var _platformFeatureFlagsReact = require("@atlaskit/platform-feature-flags-react");
11
13
  var _state = require("../../../state");
12
14
  var _ufoExperiences = require("../../../state/analytics/ufoExperiences");
15
+ var _useIntersectionObserver = _interopRequireDefault(require("../../../state/hooks/use-intersection-observer"));
13
16
  var _shouldSample = require("../../../utils/shouldSample");
17
+ var _cardLoaderWrapper = _interopRequireDefault(require("../card-loader-wrapper"));
14
18
  var _component = require("../component");
15
19
  var _LoadingCardLink = require("./LoadingCardLink");
16
20
  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); }
@@ -19,7 +23,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
19
23
  // being compared to. Since the default container is the `document`, we set this
20
24
  // up to check once a Smart Link is within `X` px from the bottom of the viewport.
21
25
  var ROOT_MARGIN_VERTICAL = '360px';
22
- function LazyIntersectionObserverCard(props) {
26
+ function LazyIntersectionObserverCardOld(props) {
23
27
  var ref = (0, _react.useRef)(null);
24
28
  var _useState = (0, _react.useState)(false),
25
29
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
@@ -68,4 +72,40 @@ function LazyIntersectionObserverCard(props) {
68
72
  return /*#__PURE__*/_react.default.createElement(Component, {
69
73
  className: "loader-wrapper"
70
74
  }, content);
71
- }
75
+ }
76
+ var LazyIntersectionObserverCardNew = function LazyIntersectionObserverCardNew(props) {
77
+ var _useState5 = (0, _react.useState)(false),
78
+ _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
79
+ isIntersected = _useState6[0],
80
+ setIsIntersected = _useState6[1];
81
+ var _useState7 = (0, _react.useState)((0, _shouldSample.shouldSample)()),
82
+ _useState8 = (0, _slicedToArray2.default)(_useState7, 1),
83
+ shouldSendRenderedUFOEvent = _useState8[0];
84
+ var appearance = props.appearance,
85
+ url = props.url,
86
+ id = props.id;
87
+ var prefetch = (0, _state.usePrefetch)(url);
88
+ var ComponentObserver = appearance === 'inline' ? 'span' : 'div';
89
+ var onIntersection = (0, _react.useCallback)(function (isIntersecting) {
90
+ if (isIntersecting) {
91
+ if (shouldSendRenderedUFOEvent) {
92
+ (0, _ufoExperiences.startUfoExperience)('smart-link-rendered', id);
93
+ }
94
+ setIsIntersected(true);
95
+ } else {
96
+ prefetch();
97
+ }
98
+ }, [id, prefetch, shouldSendRenderedUFOEvent]);
99
+ var ref = (0, _useIntersectionObserver.default)({
100
+ onIntersection: onIntersection
101
+ });
102
+ var content = isIntersected ? /*#__PURE__*/_react.default.createElement(_component.CardWithUrlContent, (0, _extends2.default)({}, props, {
103
+ isIntersected: true
104
+ })) : /*#__PURE__*/_react.default.createElement(ComponentObserver, {
105
+ ref: ref
106
+ }, /*#__PURE__*/_react.default.createElement(_LoadingCardLink.LoadingCardLink, props));
107
+ return /*#__PURE__*/_react.default.createElement(_cardLoaderWrapper.default, {
108
+ appearance: appearance
109
+ }, content);
110
+ };
111
+ var LazyIntersectionObserverCard = exports.LazyIntersectionObserverCard = (0, _platformFeatureFlagsReact.componentWithFG)('platform_sl_event_ui_seen', LazyIntersectionObserverCardNew, LazyIntersectionObserverCardOld);
@@ -5,7 +5,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.CardWithUrlContent = void 0;
8
+ exports.CardWithUrlContent = exports.CardWithUrl = void 0;
9
9
  var _react = _interopRequireWildcard(require("react"));
10
10
  var _analyticsNext = require("@atlaskit/analytics-next");
11
11
  var _linkExtractors = require("@atlaskit/link-extractors");
@@ -30,6 +30,7 @@ var _EmbedCard = require("../EmbedCard");
30
30
  var _FlexibleCard = _interopRequireDefault(require("../FlexibleCard"));
31
31
  var _InlineCard = require("../InlineCard");
32
32
  var _useSmartLinkEvents = require("../SmartLinkEvents/useSmartLinkEvents");
33
+ var _cardIntersectionObserver = _interopRequireDefault(require("./card-intersection-observer"));
33
34
  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); }
34
35
  var thirdPartyARIPrefix = 'ari:third-party';
35
36
  var EmbedCardComponent = (0, _platformFeatureFlagsReact.componentWithFG)('rovo_chat_embed_card_dwell_and_hover_metrics', _EmbedCard.EmbedCardUpdated, _EmbedCard.EmbedCard);
@@ -38,6 +39,7 @@ function Component(_ref) {
38
39
  url = _ref.url,
39
40
  isSelected = _ref.isSelected,
40
41
  isHovered = _ref.isHovered,
42
+ isIntersected = _ref.isIntersected,
41
43
  frameStyle = _ref.frameStyle,
42
44
  platform = _ref.platform,
43
45
  onClick = _ref.onClick,
@@ -65,6 +67,7 @@ function Component(_ref) {
65
67
  createAnalyticsEvent = _useAnalyticsEventsNe.createAnalyticsEvent;
66
68
  var _useAnalyticsEvents = (0, _useAnalyticsEvents3.useAnalyticsEvents)(),
67
69
  fireEvent = _useAnalyticsEvents.fireEvent;
70
+ var hasFiredSeenRef = (0, _react.useRef)(false);
68
71
  var isFlexibleUi = (0, _react.useMemo)(function () {
69
72
  return (0, _flexible.isFlexibleUiCard)(children, ui);
70
73
  }, [children, ui]);
@@ -218,6 +221,19 @@ function Component(_ref) {
218
221
  });
219
222
  }
220
223
  }, [appearance, extensionKey, fireEvent, id, isFlexibleUi, state.status]);
224
+
225
+ // Fire smartLink seen event once on a successful render card is in the viewport
226
+ (0, _react.useEffect)(function () {
227
+ if ((0, _platformFeatureFlags.fg)('platform_sl_event_ui_seen')) {
228
+ if (!(0, _helpers.isFinalState)(state.status)) return;
229
+ if (isIntersected && !hasFiredSeenRef.current) {
230
+ fireEvent('ui.smartLink.seen', {
231
+ display: appearance
232
+ });
233
+ hasFiredSeenRef.current = true;
234
+ }
235
+ }
236
+ }, [state.status, isIntersected, fireEvent, appearance]);
221
237
  var onIframeDwell = (0, _react.useCallback)(function (dwellTime, dwellPercentVisible) {
222
238
  fireEvent('ui.smartLinkIframe.dwelled', {
223
239
  id: id,
@@ -340,6 +356,7 @@ function ComponentUpdated(_ref2) {
340
356
  url = _ref2.url,
341
357
  isSelected = _ref2.isSelected,
342
358
  isHovered = _ref2.isHovered,
359
+ isIntersected = _ref2.isIntersected,
343
360
  frameStyle = _ref2.frameStyle,
344
361
  platform = _ref2.platform,
345
362
  onClick = _ref2.onClick,
@@ -367,6 +384,7 @@ function ComponentUpdated(_ref2) {
367
384
  createAnalyticsEvent = _useAnalyticsEventsNe2.createAnalyticsEvent;
368
385
  var _useAnalyticsEvents2 = (0, _useAnalyticsEvents3.useAnalyticsEvents)(),
369
386
  fireEvent = _useAnalyticsEvents2.fireEvent;
387
+ var hasFiredSeenRef = (0, _react.useRef)(false);
370
388
  var isFlexibleUi = (0, _react.useMemo)(function () {
371
389
  return (0, _flexible.isFlexibleUiCard)(children, ui);
372
390
  }, [children, ui]);
@@ -520,6 +538,19 @@ function ComponentUpdated(_ref2) {
520
538
  });
521
539
  }
522
540
  }, [appearance, extensionKey, fireEvent, id, isFlexibleUi, state.status]);
541
+
542
+ // Fire smartLink seen event once on a successful render card is in the viewport
543
+ (0, _react.useEffect)(function () {
544
+ if ((0, _platformFeatureFlags.fg)('platform_sl_event_ui_seen')) {
545
+ if (!(0, _helpers.isFinalState)(state.status)) 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]);
523
554
  var onIframeDwell = (0, _react.useCallback)(function (dwellTime, dwellPercentVisible) {
524
555
  fireEvent('ui.smartLinkIframe.dwelled', {
525
556
  id: id,
@@ -664,4 +695,5 @@ var CardWithUrlContent = exports.CardWithUrlContent = function CardWithUrlConten
664
695
  id: props.id,
665
696
  display: display
666
697
  }, /*#__PURE__*/_react.default.createElement(CardWithUrlContentComponent, props)));
667
- };
698
+ };
699
+ var CardWithUrl = exports.CardWithUrl = (0, _cardIntersectionObserver.default)(CardWithUrlContent);
@@ -152,8 +152,9 @@ var getPromptAction = function getPromptAction(promptKey, intl) {
152
152
  }
153
153
  };
154
154
  case RovoChatPromptKey.KEY_HIGHLIGHTS:
155
- var label_key_highlights = intl.formatMessage(_messages.messages.rovo_prompt_button_key_highlights);
156
- var html_key_highlights = intl.formatMessage(_messages.messages.rovo_prompt_message_key_highlights, {
155
+ var label_key_highlights = intl.formatMessage(_messages.messages.rovo_prompt_button_highlight_relevant_content);
156
+ var html_key_highlights = intl.formatMessage(_messages.messages.rovo_prompt_message_highlight_relevant_content, {
157
+ context: contextLong,
157
158
  url: url
158
159
  }, {
159
160
  ignoreTag: true
@@ -951,16 +951,6 @@ export const messages = defineMessages({
951
951
  defaultMessage: '<p>Summarize the main ideas and key points of <a>{url}</a> in 3-5 clear, complete sentences.</p><p>Preserve any important details such as names, dates, and key decisions.</p>',
952
952
  description: 'The prompt message to send to Rovo Chat. {url} refers to Smart Link that the user triggers this action from. (Please make sure all html tags remain the same.)'
953
953
  },
954
- rovo_prompt_button_key_highlights: {
955
- id: 'fabric.linking.rovo_prompt_button_key_highlights.non-final',
956
- defaultMessage: 'Key highlights',
957
- description: 'The name of the action to send a key highlights prompt message to Rovo Chat in relation to current Smart Link'
958
- },
959
- rovo_prompt_message_key_highlights: {
960
- id: 'fabric.linking.rovo_prompt_message_key_highlights.non-final',
961
- defaultMessage: "<p>Based on <a>{url}</a> and the page or ticket I'm currently viewing, highlight the parts of the linked content that are most relevant to this work. Explain briefly why each part is relevant.</p>",
962
- description: 'The prompt message to send to Rovo Chat. {url} refers to Smart Link that the user triggers this action from. (Please make sure all html tags remain the same.)'
963
- },
964
954
  rovo_prompt_button_ask_rovo_anything: {
965
955
  id: 'fabric.linking.rovo_prompt_button_ask_rovo.non-final',
966
956
  defaultMessage: 'Ask Rovo',
@@ -3,13 +3,15 @@ import { ErrorBoundary } from 'react-error-boundary';
3
3
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
4
4
  import uuid from 'uuid';
5
5
  import { AnalyticsContext } from '@atlaskit/analytics-next';
6
+ import { fg } from '@atlaskit/platform-feature-flags';
6
7
  import { context } from './utils/analytics/analytics';
7
- import { CardWithUrlContent } from './view/CardWithUrl/component';
8
+ import CardErrorBoundary from './view/CardWithUrl/card-error-boundary';
9
+ import { CardWithUrl, CardWithUrlContent } from './view/CardWithUrl/component';
8
10
  import { LoadingCardLink } from './view/CardWithUrl/component-lazy/LoadingCardLink';
9
11
  // SSR friendly version of smart-card
10
12
  // simplifies the logic around rendering and loading placeholders and
11
13
  // only contains whats necessary to render the card on SSR mode
12
- export const CardSSR = props => {
14
+ const CardSSROld = props => {
13
15
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
14
16
  const [id] = useState(() => {
15
17
  var _props$id;
@@ -34,4 +36,28 @@ export const CardSSR = props => {
34
36
  }, /*#__PURE__*/React.createElement(Component, {
35
37
  className: "loader-wrapper"
36
38
  }, /*#__PURE__*/React.createElement(CardWithUrlContent, cardProps))));
39
+ };
40
+
41
+ // SSR friendly version of smart-card
42
+ // simplifies the logic around rendering and loading placeholders and
43
+ // only contains whats necessary to render the card on SSR mode
44
+ const CardSSRNew = props => {
45
+ // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
46
+ const [id] = useState(() => {
47
+ var _props$id2;
48
+ return (_props$id2 = props.id) !== null && _props$id2 !== void 0 ? _props$id2 : uuid();
49
+ });
50
+ const propsWithId = {
51
+ ...props,
52
+ id
53
+ };
54
+ return /*#__PURE__*/React.createElement(AnalyticsContext, {
55
+ data: context
56
+ }, /*#__PURE__*/React.createElement(CardErrorBoundary, propsWithId, /*#__PURE__*/React.createElement(CardWithUrl, propsWithId)));
57
+ };
58
+ export const CardSSR = props => {
59
+ if (fg('platform_sl_event_ui_seen')) {
60
+ return /*#__PURE__*/React.createElement(CardSSRNew, props);
61
+ }
62
+ return /*#__PURE__*/React.createElement(CardSSROld, props);
37
63
  };
@@ -0,0 +1,41 @@
1
+ import { useCallback, useEffect, useRef } from 'react';
2
+
3
+ // This property enables the intersection observer to be run once the
4
+ // HTML element being observed is within `X` px of the target container it is
5
+ // being compared to. Since the default container is the `document`, we set this
6
+ // up to check once a Smart Link is within `X` px from the bottom of the viewport.
7
+ const ROOT_MARGIN_VERTICAL = '360px';
8
+ const useIntersectionObserver = ({
9
+ onIntersecting: onIntersectingCallback,
10
+ onIntersection: onIntersectionCallback
11
+ }) => {
12
+ const ref = useRef(null);
13
+ const onIntersectingCallbackRef = useRef(onIntersectingCallback);
14
+ const onIntersectionCallbackRef = useRef(onIntersectionCallback);
15
+ useEffect(() => {
16
+ onIntersectingCallbackRef.current = onIntersectingCallback;
17
+ onIntersectionCallbackRef.current = onIntersectionCallback;
18
+ }, [onIntersectingCallback, onIntersectionCallback]);
19
+ const onIntersection = useCallback((entries, observer) => {
20
+ var _onIntersectionCallba;
21
+ const isIntersecting = entries.some(entry => entry.isIntersecting);
22
+ (_onIntersectionCallba = onIntersectionCallbackRef.current) === null || _onIntersectionCallba === void 0 ? void 0 : _onIntersectionCallba.call(onIntersectionCallbackRef, isIntersecting);
23
+ if (isIntersecting) {
24
+ var _onIntersectingCallba;
25
+ (_onIntersectingCallba = onIntersectingCallbackRef.current) === null || _onIntersectingCallba === void 0 ? void 0 : _onIntersectingCallba.call(onIntersectingCallbackRef);
26
+ observer.disconnect();
27
+ }
28
+ }, []);
29
+ useEffect(() => {
30
+ if (!ref.current) {
31
+ return;
32
+ }
33
+ const intersectionObserver = new IntersectionObserver(onIntersection, {
34
+ rootMargin: `${ROOT_MARGIN_VERTICAL} 0px ${ROOT_MARGIN_VERTICAL} 0px`
35
+ });
36
+ intersectionObserver.observe(ref.current);
37
+ return () => intersectionObserver.disconnect();
38
+ }, [ref, onIntersection]);
39
+ return ref;
40
+ };
41
+ export default useIntersectionObserver;
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { ErrorBoundary } from 'react-error-boundary';
3
+ import { LoadingCardLink } from '../component-lazy/LoadingCardLink';
4
+ const CardErrorBoundary = ({
5
+ children,
6
+ ...props
7
+ }) => {
8
+ // TODO: NAVX-4682: Add feature parity to CardWithURLRenderer
9
+ const ErrorFallbackComponent = props.fallbackComponent;
10
+ const errorBoundaryFallbackComponent = () => {
11
+ if (ErrorFallbackComponent) {
12
+ return /*#__PURE__*/React.createElement(ErrorFallbackComponent, null);
13
+ }
14
+ return /*#__PURE__*/React.createElement(LoadingCardLink, props);
15
+ };
16
+ return /*#__PURE__*/React.createElement(ErrorBoundary, {
17
+ FallbackComponent: errorBoundaryFallbackComponent
18
+ }, children);
19
+ };
20
+ export default CardErrorBoundary;
@@ -0,0 +1,25 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React, { useCallback, useState } from 'react';
3
+ import useIntersectionObserver from '../../../state/hooks/use-intersection-observer';
4
+ import { isIntersectionObserverSupported } from '../../../utils';
5
+ import CardLoaderWrapper from '../card-loader-wrapper';
6
+ const withCardIntersectionObserver = Component => props => {
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
+ }, []);
12
+ const ref = useIntersectionObserver({
13
+ onIntersecting
14
+ });
15
+ return /*#__PURE__*/React.createElement(CardLoaderWrapper, {
16
+ appearance: props.appearance,
17
+ ref: ref
18
+ }, /*#__PURE__*/React.createElement(Component, _extends({}, props, {
19
+ isIntersected: isIntersected
20
+ })));
21
+ };
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));
@@ -0,0 +1,16 @@
1
+ import React, { forwardRef } from 'react';
2
+ const CardLoaderWrapper = /*#__PURE__*/forwardRef(({
3
+ appearance,
4
+ children
5
+ }, ref) => {
6
+ const Component = appearance === 'inline' ? 'span' : 'div';
7
+ return (
8
+ /*#__PURE__*/
9
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
10
+ React.createElement(Component, {
11
+ className: "loader-wrapper",
12
+ ref: ref
13
+ }, children)
14
+ );
15
+ });
16
+ export default CardLoaderWrapper;