@atlaskit/editor-plugin-card 0.10.10 → 0.11.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 (35) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/common/pulse/index.js +6 -14
  3. package/dist/cjs/messages.js +5 -0
  4. package/dist/cjs/nodeviews/inlineCardWithAwareness.js +20 -2
  5. package/dist/cjs/toolbar.js +5 -9
  6. package/dist/cjs/ui/InlineCardOverlay/index.js +187 -0
  7. package/dist/cjs/ui/InlineCardOverlay/types.js +5 -0
  8. package/dist/cjs/ui/LinkToolbarAppearance.js +19 -3
  9. package/dist/es2019/common/pulse/index.js +8 -14
  10. package/dist/es2019/messages.js +5 -0
  11. package/dist/es2019/nodeviews/inlineCardWithAwareness.js +13 -3
  12. package/dist/es2019/toolbar.js +3 -7
  13. package/dist/es2019/ui/InlineCardOverlay/index.js +175 -0
  14. package/dist/es2019/ui/InlineCardOverlay/types.js +1 -0
  15. package/dist/es2019/ui/LinkToolbarAppearance.js +18 -3
  16. package/dist/esm/common/pulse/index.js +8 -16
  17. package/dist/esm/messages.js +5 -0
  18. package/dist/esm/nodeviews/inlineCardWithAwareness.js +21 -3
  19. package/dist/esm/toolbar.js +4 -8
  20. package/dist/esm/ui/InlineCardOverlay/index.js +179 -0
  21. package/dist/esm/ui/InlineCardOverlay/types.js +1 -0
  22. package/dist/esm/ui/LinkToolbarAppearance.js +19 -3
  23. package/dist/types/common/pulse/index.d.ts +1 -5
  24. package/dist/types/messages.d.ts +5 -0
  25. package/dist/types/toolbar.d.ts +1 -0
  26. package/dist/types/ui/InlineCardOverlay/index.d.ts +5 -0
  27. package/dist/types/ui/InlineCardOverlay/types.d.ts +6 -0
  28. package/dist/types/ui/LinkToolbarAppearance.d.ts +9 -8
  29. package/dist/types-ts4.5/common/pulse/index.d.ts +1 -5
  30. package/dist/types-ts4.5/messages.d.ts +5 -0
  31. package/dist/types-ts4.5/toolbar.d.ts +1 -0
  32. package/dist/types-ts4.5/ui/InlineCardOverlay/index.d.ts +5 -0
  33. package/dist/types-ts4.5/ui/InlineCardOverlay/types.d.ts +6 -0
  34. package/dist/types-ts4.5/ui/LinkToolbarAppearance.d.ts +9 -8
  35. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @atlaskit/editor-plugin-card
2
2
 
3
+ ## 0.11.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#42248](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/42248) [`c3ce5d9263f`](https://bitbucket.org/atlassian/atlassian-frontend/commits/c3ce5d9263f) - Add inline card overlay component
8
+ - [#42848](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/42848) [`f2f8428f703`](https://bitbucket.org/atlassian/atlassian-frontend/commits/f2f8428f703) - Abandons feature flag lp-link-picker-focus-trap as it was not successfully rolled out. Will re-introduce as platform feature flag as/when necessary.
9
+ - Updated dependencies
10
+
11
+ ## 0.11.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [#42755](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/42755) [`97f9fcba5a5`](https://bitbucket.org/atlassian/atlassian-frontend/commits/97f9fcba5a5) - [ux] Add a discovery pulse to smart link view switcher under certain conditions and behind a feature flag
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies
20
+
3
21
  ## 0.10.10
4
22
 
5
23
  ### Patch Changes
@@ -14,24 +14,16 @@ var DiscoveryPulse = exports.DiscoveryPulse = function DiscoveryPulse(_ref) {
14
14
  var children = _ref.children,
15
15
  localStorageKey = _ref.localStorageKey,
16
16
  isDiscovered = _ref.isDiscovered,
17
- timeToDiscoverInMs = _ref.timeToDiscoverInMs,
18
17
  localStorageKeyExpirationInMs = _ref.localStorageKeyExpirationInMs;
18
+ var discovered = isDiscovered || (0, _localStorage.isLocalStorageKeyDiscovered)(localStorageKey);
19
19
  var onDiscovery = (0, _react.useCallback)(function () {
20
- (0, _localStorage.markLocalStorageKeyDiscovered)(localStorageKey, localStorageKeyExpirationInMs);
21
- }, [localStorageKey, localStorageKeyExpirationInMs]);
22
- (0, _react.useEffect)(function () {
23
- if (timeToDiscoverInMs) {
24
- var timeoutUntilDiscovery = setTimeout(function () {
25
- onDiscovery();
26
- }, timeToDiscoverInMs);
27
- return function () {
28
- return clearTimeout(timeoutUntilDiscovery);
29
- };
20
+ if (!discovered) {
21
+ (0, _localStorage.markLocalStorageKeyDiscovered)(localStorageKey, localStorageKeyExpirationInMs);
30
22
  }
31
- onDiscovery();
32
- }, [isDiscovered, localStorageKey, onDiscovery, timeToDiscoverInMs]);
23
+ }, [discovered, localStorageKey, localStorageKeyExpirationInMs]);
33
24
  return /*#__PURE__*/_react.default.createElement(_linkingCommon.Pulse, {
34
- isDiscovered: isDiscovered
25
+ onAnimationIteration: onDiscovery,
26
+ isDiscovered: discovered
35
27
  }, children);
36
28
  };
37
29
  var _default = exports.default = _linkingCommon.Pulse;
@@ -25,5 +25,10 @@ var messages = exports.messages = (0, _reactIntlNext.defineMessages)({
25
25
  id: 'fabric.editor.datasource.assetsObjects.description',
26
26
  defaultMessage: 'Insert objects from Assets in Jira Service Management with search and filtering',
27
27
  description: 'Description text displayed when selecting the type of data to include onto the page, in this case: JSM Assets objects'
28
+ },
29
+ inlineOverlay: {
30
+ id: 'fabric.editor.inlineOverlay',
31
+ defaultMessage: 'Change view',
32
+ description: 'An overlay shown when hover over inline smart link to inform user that they can change link view to card and/or embed.'
28
33
  }
29
34
  });
@@ -6,11 +6,13 @@ Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports.InlineCardWithAwareness = void 0;
9
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
10
  var _react = _interopRequireWildcard(require("react"));
10
11
  var _rafSchd = _interopRequireDefault(require("raf-schd"));
11
12
  var _ui = require("@atlaskit/editor-common/ui");
12
13
  var _smartCard = require("@atlaskit/smart-card");
13
14
  var _actions = require("../pm-plugins/actions");
15
+ var _InlineCardOverlay = _interopRequireDefault(require("../ui/InlineCardOverlay"));
14
16
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
15
17
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
18
  var InlineCard = function InlineCard(_ref) {
@@ -26,6 +28,13 @@ var InlineCard = function InlineCard(_ref) {
26
28
  var _node$attrs = node.attrs,
27
29
  url = _node$attrs.url,
28
30
  data = _node$attrs.data;
31
+
32
+ // A complete show/hide logic for the overlay will be implemented
33
+ // in EDM-8239 and EDM-8241
34
+ var _useState = (0, _react.useState)(false),
35
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
36
+ isOverlayVisible = _useState2[0],
37
+ setIsOverlayVisible = _useState2[1];
29
38
  var onClick = function onClick() {};
30
39
  var onResolve = (0, _react.useCallback)(function (data) {
31
40
  if (!getPos || typeof getPos === 'boolean') {
@@ -59,7 +68,16 @@ var InlineCard = function InlineCard(_ref) {
59
68
  });
60
69
  }, [onResolve]);
61
70
  var card = /*#__PURE__*/_react.default.createElement("span", {
62
- className: "card"
71
+ className: "card",
72
+ onMouseEnter: function onMouseEnter() {
73
+ return setIsOverlayVisible(true);
74
+ },
75
+ onMouseLeave: function onMouseLeave() {
76
+ return setIsOverlayVisible(false);
77
+ }
78
+ }, /*#__PURE__*/_react.default.createElement(_InlineCardOverlay.default, {
79
+ isVisible: isOverlayVisible,
80
+ url: url
63
81
  }, /*#__PURE__*/_react.default.createElement(_smartCard.Card, {
64
82
  key: url,
65
83
  url: url,
@@ -71,7 +89,7 @@ var InlineCard = function InlineCard(_ref) {
71
89
  onError: onError,
72
90
  inlinePreloaderStyle: useAlternativePreloader ? 'on-right-without-skeleton' : undefined,
73
91
  showServerActions: showServerActions
74
- }));
92
+ })));
75
93
  // [WS-2307]: we only render card wrapped into a Provider when the value is ready,
76
94
  // otherwise if we got data, we can render the card directly since it doesn't need the Provider
77
95
  return cardContext && cardContext.value ? /*#__PURE__*/_react.default.createElement(cardContext.Provider, {
@@ -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.visitCardLink = exports.removeCard = exports.openLinkSettings = exports.floatingToolbar = void 0;
8
+ exports.visitCardLink = exports.shouldRenderToolbarPulse = exports.removeCard = exports.openLinkSettings = exports.floatingToolbar = void 0;
9
9
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
11
  var _react = _interopRequireDefault(require("react"));
@@ -120,14 +120,8 @@ var floatingToolbar = exports.floatingToolbar = function floatingToolbar(cardOpt
120
120
 
121
121
  // Applies padding override for when link picker is currently displayed
122
122
  var className = pluginState !== null && pluginState !== void 0 && pluginState.showLinkingToolbar ? _styles.FLOATING_TOOLBAR_LINKPICKER_CLASSNAME : undefined;
123
-
124
- /**
125
- * Enable focus trap only if feature flag is enabled AND for the new version of the picker
126
- */
127
123
  var lpLinkPicker = featureFlags.lpLinkPicker,
128
- lpLinkPickerFocusTrap = featureFlags.lpLinkPickerFocusTrap,
129
124
  preventPopupOverflow = featureFlags.preventPopupOverflow;
130
- var shouldEnableFocusTrap = lpLinkPicker && lpLinkPickerFocusTrap;
131
125
  var isLinkPickerEnabled = !!lpLinkPicker;
132
126
  return _objectSpread(_objectSpread({
133
127
  title: intl.formatMessage(_messages.cardMessages.card),
@@ -146,8 +140,7 @@ var floatingToolbar = exports.floatingToolbar = function floatingToolbar(cardOpt
146
140
  return element;
147
141
  },
148
142
  items: generateToolbarItems(state, featureFlags, intl, providerFactory, cardOptions, platform, linkPickerOptions, pluginInjectionApi),
149
- scrollable: pluginState !== null && pluginState !== void 0 && pluginState.showLinkingToolbar ? false : true,
150
- focusTrap: shouldEnableFocusTrap && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.showLinkingToolbar)
143
+ scrollable: pluginState !== null && pluginState !== void 0 && pluginState.showLinkingToolbar ? false : true
151
144
  }, (0, _EditLinkToolbar.editLinkToolbarConfig)(Boolean(pluginState === null || pluginState === void 0 ? void 0 : pluginState.showLinkingToolbar), isLinkPickerEnabled));
152
145
  };
153
146
  };
@@ -407,4 +400,7 @@ var getDatasourceButtonGroup = function getDatasourceButtonGroup(metadata, intl,
407
400
  onClick: withToolbarMetadata(removeCard(editorAnalyticsApi))
408
401
  });
409
402
  return toolbarItems;
403
+ };
404
+ var shouldRenderToolbarPulse = exports.shouldRenderToolbarPulse = function shouldRenderToolbarPulse(embedEnabled, appearance, status, isDiscoverabilityEnabled) {
405
+ return embedEnabled && appearance === 'inline' && status === 'resolved' && isDiscoverabilityEnabled && (0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-card.inline-switcher');
410
406
  };
@@ -0,0 +1,187 @@
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 _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+ var _react = _interopRequireWildcard(require("react"));
12
+ var _react2 = require("@emotion/react");
13
+ var _reactIntlNext = require("react-intl-next");
14
+ var _utils = require("@atlaskit/editor-common/utils");
15
+ var _chevronDown = _interopRequireDefault(require("@atlaskit/icon/glyph/hipchat/chevron-down"));
16
+ var _chevronUp = _interopRequireDefault(require("@atlaskit/icon/glyph/hipchat/chevron-up"));
17
+ var _colors = require("@atlaskit/theme/colors");
18
+ var _messages = require("../../messages");
19
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
20
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
21
+ 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; }
22
+ 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) { (0, _defineProperty2.default)(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; } /** @jsx jsx */
23
+ var PADDING_IN_PX = 2;
24
+ var containerStyles = (0, _react2.css)({
25
+ position: 'relative'
26
+ });
27
+ var linkStyles = (0, _react2.css)({
28
+ color: "var(--ds-text, #172B4D)",
29
+ textDecoration: 'none'
30
+ });
31
+ var overlayStyles = (0, _react2.css)({
32
+ // Positioning
33
+ position: 'relative',
34
+ display: 'inline-flex',
35
+ flexWrap: 'nowrap',
36
+ alignItems: 'center',
37
+ alignSelf: 'stretch',
38
+ height: 'inherit',
39
+ lineHeight: 'initial',
40
+ width: 'max-content',
41
+ top: "var(--ds-space-0, 0)",
42
+ bottom: "var(--ds-space-0, 0)",
43
+ right: 3,
44
+ margin: "-1px ".concat("var(--ds-space-0, 0)"),
45
+ padding: "var(--ds-space-0, 0)",
46
+ // Styling
47
+ fontSize: 'inherit',
48
+ fontWeight: 'normal',
49
+ color: "var(--ds-text, ".concat(_colors.N800, ")"),
50
+ background: "var(--ds-background-accent-gray-subtlest, ".concat(_colors.N20A, ")"),
51
+ borderRadius: 3,
52
+ // inline card border of 4px - 1px
53
+
54
+ // Using `&` twice to increase specificity. (These are not nested styles.)
55
+ /* eslint-disable @atlaskit/design-system/no-nested-styles */
56
+ '&&:link': _objectSpread({}, linkStyles),
57
+ '&&:active': _objectSpread({}, linkStyles),
58
+ '&&:focus': _objectSpread({}, linkStyles),
59
+ '&&:hover': _objectSpread({}, linkStyles),
60
+ '&&:visited': _objectSpread({}, linkStyles),
61
+ /* eslint-enable @atlaskit/design-system/no-nested-styles */
62
+
63
+ // EDM-1717: box-shadow Safari fix bring load wrapper zIndex to 1
64
+ zIndex: 2,
65
+ // Fill lines, match heading and paragraph size
66
+ '::before': {
67
+ content: '" "',
68
+ display: 'inline-block',
69
+ verticalAlign: 'middle',
70
+ width: "var(--ds-space-0, 0)",
71
+ margin: "var(--ds-space-0, 0)",
72
+ padding: "var(--ds-space-0, 0)"
73
+ }
74
+ });
75
+ var safariOverlayStyles = (0, _react2.css)({
76
+ height: '1.1em',
77
+ paddingBottom: "var(--ds-space-025, 2px)",
78
+ right: 3
79
+ });
80
+ var textStyles = (0, _react2.css)({
81
+ paddingLeft: "var(--ds-space-050, 4px)"
82
+ });
83
+ var iconStyles = (0, _react2.css)({
84
+ // Position icon in the middle
85
+ display: 'inline-grid',
86
+ // We want to position the icon in the middle of large text type like heading 1
87
+ // eslint-disable-next-line @atlaskit/design-system/no-nested-styles
88
+ span: {
89
+ display: 'inline-grid'
90
+ }
91
+ });
92
+ var markerStyles = (0, _react2.css)({
93
+ height: "var(--ds-space-0, 0)",
94
+ width: "var(--ds-space-0, 0)",
95
+ margin: "var(--ds-space-0, 0)",
96
+ padding: "var(--ds-space-0, 0)"
97
+ });
98
+ var InlineCardOverlay = function InlineCardOverlay(_ref) {
99
+ var children = _ref.children,
100
+ _ref$isToolbarOpen = _ref.isToolbarOpen,
101
+ isToolbarOpen = _ref$isToolbarOpen === void 0 ? false : _ref$isToolbarOpen,
102
+ _ref$isVisible = _ref.isVisible,
103
+ isVisible = _ref$isVisible === void 0 ? false : _ref$isVisible,
104
+ _ref$testId = _ref.testId,
105
+ testId = _ref$testId === void 0 ? 'inline-card-overlay' : _ref$testId,
106
+ url = _ref.url;
107
+ var _useState = (0, _react.useState)(true),
108
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
109
+ showLabel = _useState2[0],
110
+ setShowLabel = _useState2[1];
111
+ var _useState3 = (0, _react.useState)(0),
112
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
113
+ overlayWidth = _useState4[0],
114
+ setOverlayWidth = _useState4[1];
115
+ var containerRef = (0, _react.useRef)(null);
116
+ var markerRef = (0, _react.useRef)(null);
117
+ var overlayRef = (0, _react.useRef)(null);
118
+ var labelRef = (0, _react.useRef)(null);
119
+ (0, _react.useLayoutEffect)(function () {
120
+ if (!isVisible) {
121
+ // Reset to default state for width calculation when the component become visible.
122
+ setShowLabel(true);
123
+ return;
124
+ }
125
+ try {
126
+ var _containerRef$current, _containerRef$current2, _markerRef$current$ge, _markerRef$current, _overlayRef$current$g, _overlayRef$current, _labelRef$current$get, _labelRef$current;
127
+ // Get the width of the available space to display overlay
128
+ var start = (_containerRef$current = containerRef === null || containerRef === void 0 || (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 || (_containerRef$current2 = _containerRef$current2.getBoundingClientRect()) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.left) !== null && _containerRef$current !== void 0 ? _containerRef$current : 0;
129
+ var end = (_markerRef$current$ge = markerRef === null || markerRef === void 0 || (_markerRef$current = markerRef.current) === null || _markerRef$current === void 0 || (_markerRef$current = _markerRef$current.getBoundingClientRect()) === null || _markerRef$current === void 0 ? void 0 : _markerRef$current.left) !== null && _markerRef$current$ge !== void 0 ? _markerRef$current$ge : 0;
130
+ var availableWidth = end - start - PADDING_IN_PX;
131
+
132
+ // Get overlay width and label width
133
+ var _overlayWidth = (_overlayRef$current$g = overlayRef === null || overlayRef === void 0 || (_overlayRef$current = overlayRef.current) === null || _overlayRef$current === void 0 || (_overlayRef$current = _overlayRef$current.getBoundingClientRect()) === null || _overlayRef$current === void 0 ? void 0 : _overlayRef$current.width) !== null && _overlayRef$current$g !== void 0 ? _overlayRef$current$g : 0;
134
+
135
+ // Show label if there is enough space to display
136
+ var shouldShowLabel = availableWidth > 0 && _overlayWidth > 0 ? availableWidth > _overlayWidth : false;
137
+ setShowLabel(shouldShowLabel);
138
+
139
+ // We use relative positioning and need to set
140
+ // negative margin left (ltr) as the width of the overlay
141
+ // to make the overlay position on top of inline link.
142
+ var labelWidth = (_labelRef$current$get = labelRef === null || labelRef === void 0 || (_labelRef$current = labelRef.current) === null || _labelRef$current === void 0 || (_labelRef$current = _labelRef$current.getBoundingClientRect()) === null || _labelRef$current === void 0 ? void 0 : _labelRef$current.width) !== null && _labelRef$current$get !== void 0 ? _labelRef$current$get : 0;
143
+ var newOverlayWidth = shouldShowLabel ? _overlayWidth : _overlayWidth - labelWidth;
144
+ setOverlayWidth(newOverlayWidth);
145
+ } catch (_unused) {
146
+ // If something goes wrong, play it safe by hiding label so that
147
+ // the component does not look too janky.
148
+ setShowLabel(false);
149
+ }
150
+ }, [isVisible]);
151
+ var intl = (0, _reactIntlNext.useIntl)();
152
+ var label = intl.formatMessage(_messages.messages.inlineOverlay);
153
+ var icon = (0, _react.useMemo)(function () {
154
+ var IconComponent = isToolbarOpen ? _chevronUp.default : _chevronDown.default;
155
+ return (0, _react2.jsx)(IconComponent, {
156
+ label: label,
157
+ size: "small",
158
+ testId: "".concat(testId, "-").concat(isToolbarOpen ? 'open' : 'close')
159
+ });
160
+ }, [isToolbarOpen, label, testId]);
161
+ return (0, _react2.jsx)("span", {
162
+ css: containerStyles,
163
+ ref: containerRef
164
+ }, children, isVisible && (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)("span", {
165
+ "aria-hidden": "true",
166
+ css: markerStyles,
167
+ ref: markerRef
168
+ }), (0, _react2.jsx)("a", {
169
+ css: [overlayStyles, _utils.browser.safari && safariOverlayStyles],
170
+ style: {
171
+ marginLeft: -overlayWidth
172
+ },
173
+ "data-testid": testId,
174
+ href: url,
175
+ onClick: function onClick(e) {
176
+ return e.preventDefault();
177
+ },
178
+ ref: overlayRef
179
+ }, showLabel && (0, _react2.jsx)("span", {
180
+ css: textStyles,
181
+ "data-testid": "".concat(testId, "-label"),
182
+ ref: labelRef
183
+ }, label), (0, _react2.jsx)("span", {
184
+ css: iconStyles
185
+ }, icon))));
186
+ };
187
+ var _default = exports.default = InlineCardOverlay;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -20,6 +20,8 @@ var _card = require("@atlaskit/editor-common/card");
20
20
  var _messages = _interopRequireWildcard(require("@atlaskit/editor-common/messages"));
21
21
  var _utils = require("@atlaskit/editor-common/utils");
22
22
  var _model = require("@atlaskit/editor-prosemirror/model");
23
+ var _pulse = require("../common/pulse");
24
+ var _toolbar = require("../toolbar");
23
25
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
24
26
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
25
27
  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; }
@@ -38,7 +40,7 @@ var LinkToolbarAppearance = exports.LinkToolbarAppearance = /*#__PURE__*/functio
38
40
  }
39
41
  _this = _super.call.apply(_super, [this].concat(args));
40
42
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderDropdown", function (view, cardContext) {
41
- var _cardActions$setSelec, _cardActions$setSelec2, _cardActions$changeSe, _cardActions$setSelec3;
43
+ var _cardActions$setSelec, _cardActions$setSelec2, _cardActions$changeSe, _cardActions$setSelec3, _cardContext$store2;
42
44
  var _this$props = _this.props,
43
45
  url = _this$props.url,
44
46
  intl = _this$props.intl,
@@ -49,7 +51,9 @@ var LinkToolbarAppearance = exports.LinkToolbarAppearance = /*#__PURE__*/functio
49
51
  allowBlockCards = _this$props$allowBloc === void 0 ? true : _this$props$allowBloc,
50
52
  platform = _this$props.platform,
51
53
  editorAnalyticsApi = _this$props.editorAnalyticsApi,
52
- cardActions = _this$props.cardActions;
54
+ cardActions = _this$props.cardActions,
55
+ _this$props$showInlin = _this$props.showInlineUpgradeDiscoverability,
56
+ showInlineUpgradeDiscoverability = _this$props$showInlin === void 0 ? false : _this$props$showInlin;
53
57
  var preview = allowEmbeds && cardContext && url && cardContext.extractors.getPreview(url, platform);
54
58
  var defaultCommand = function defaultCommand() {
55
59
  return false;
@@ -109,7 +113,7 @@ var LinkToolbarAppearance = exports.LinkToolbarAppearance = /*#__PURE__*/functio
109
113
  if (embedOption) {
110
114
  options.push(embedOption);
111
115
  }
112
- return /*#__PURE__*/_react.default.createElement(_card.LinkToolbarButtonGroup, {
116
+ var LinkToolbarButtons = /*#__PURE__*/_react.default.createElement(_card.LinkToolbarButtonGroup, {
113
117
  key: "link-toolbar-button-group",
114
118
  options: options.map(function (option) {
115
119
  return (0, _card.getButtonGroupOption)(intl, dispatchCommand, _objectSpread(_objectSpread({}, option), {}, {
@@ -119,6 +123,18 @@ var LinkToolbarAppearance = exports.LinkToolbarAppearance = /*#__PURE__*/functio
119
123
  }));
120
124
  })
121
125
  });
126
+ var status = url ? cardContext === null || cardContext === void 0 || (_cardContext$store2 = cardContext.store) === null || _cardContext$store2 === void 0 || (_cardContext$store2 = _cardContext$store2.getState()[url]) === null || _cardContext$store2 === void 0 ? void 0 : _cardContext$store2.status : '';
127
+ var embedEnabled = embedOption ? !embedOption.disabled : false;
128
+ if ((0, _toolbar.shouldRenderToolbarPulse)(embedEnabled, currentAppearance !== null && currentAppearance !== void 0 ? currentAppearance : '', status !== null && status !== void 0 ? status : '', showInlineUpgradeDiscoverability)) {
129
+ return (
130
+ /*#__PURE__*/
131
+ // This div is necessary because the toolbar uses :first-child to add margins and can't add margins to the pulse element
132
+ _react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_pulse.DiscoveryPulse, {
133
+ localStorageKey: "toolbar-upgrade-pulse"
134
+ }, LinkToolbarButtons))
135
+ );
136
+ }
137
+ return LinkToolbarButtons;
122
138
  });
123
139
  return _this;
124
140
  }
@@ -1,27 +1,21 @@
1
- import React, { useCallback, useEffect } from 'react';
1
+ import React, { useCallback } from 'react';
2
2
  import { Pulse } from '@atlaskit/linking-common';
3
- import { markLocalStorageKeyDiscovered } from '../local-storage';
3
+ import { isLocalStorageKeyDiscovered, markLocalStorageKeyDiscovered } from '../local-storage';
4
4
  export const DiscoveryPulse = ({
5
5
  children,
6
6
  localStorageKey,
7
7
  isDiscovered,
8
- timeToDiscoverInMs,
9
8
  localStorageKeyExpirationInMs
10
9
  }) => {
10
+ const discovered = isDiscovered || isLocalStorageKeyDiscovered(localStorageKey);
11
11
  const onDiscovery = useCallback(() => {
12
- markLocalStorageKeyDiscovered(localStorageKey, localStorageKeyExpirationInMs);
13
- }, [localStorageKey, localStorageKeyExpirationInMs]);
14
- useEffect(() => {
15
- if (timeToDiscoverInMs) {
16
- const timeoutUntilDiscovery = setTimeout(() => {
17
- onDiscovery();
18
- }, timeToDiscoverInMs);
19
- return () => clearTimeout(timeoutUntilDiscovery);
12
+ if (!discovered) {
13
+ markLocalStorageKeyDiscovered(localStorageKey, localStorageKeyExpirationInMs);
20
14
  }
21
- onDiscovery();
22
- }, [isDiscovered, localStorageKey, onDiscovery, timeToDiscoverInMs]);
15
+ }, [discovered, localStorageKey, localStorageKeyExpirationInMs]);
23
16
  return /*#__PURE__*/React.createElement(Pulse, {
24
- isDiscovered: isDiscovered
17
+ onAnimationIteration: onDiscovery,
18
+ isDiscovered: discovered
25
19
  }, children);
26
20
  };
27
21
  export default Pulse;
@@ -19,5 +19,10 @@ export const messages = defineMessages({
19
19
  id: 'fabric.editor.datasource.assetsObjects.description',
20
20
  defaultMessage: 'Insert objects from Assets in Jira Service Management with search and filtering',
21
21
  description: 'Description text displayed when selecting the type of data to include onto the page, in this case: JSM Assets objects'
22
+ },
23
+ inlineOverlay: {
24
+ id: 'fabric.editor.inlineOverlay',
25
+ defaultMessage: 'Change view',
26
+ description: 'An overlay shown when hover over inline smart link to inform user that they can change link view to card and/or embed.'
22
27
  }
23
28
  });
@@ -1,8 +1,9 @@
1
- import React, { memo, useCallback, useMemo } from 'react';
1
+ import React, { memo, useCallback, useMemo, useState } from 'react';
2
2
  import rafSchedule from 'raf-schd';
3
3
  import { findOverflowScrollParent } from '@atlaskit/editor-common/ui';
4
4
  import { Card as SmartCard } from '@atlaskit/smart-card';
5
5
  import { registerCard } from '../pm-plugins/actions';
6
+ import InlineCardOverlay from '../ui/InlineCardOverlay';
6
7
  const InlineCard = ({
7
8
  node,
8
9
  cardContext,
@@ -16,6 +17,10 @@ const InlineCard = ({
16
17
  url,
17
18
  data
18
19
  } = node.attrs;
20
+
21
+ // A complete show/hide logic for the overlay will be implemented
22
+ // in EDM-8239 and EDM-8241
23
+ const [isOverlayVisible, setIsOverlayVisible] = useState(false);
19
24
  const onClick = () => {};
20
25
  const onResolve = useCallback(data => {
21
26
  if (!getPos || typeof getPos === 'boolean') {
@@ -53,7 +58,12 @@ const InlineCard = ({
53
58
  });
54
59
  }, [onResolve]);
55
60
  const card = /*#__PURE__*/React.createElement("span", {
56
- className: "card"
61
+ className: "card",
62
+ onMouseEnter: () => setIsOverlayVisible(true),
63
+ onMouseLeave: () => setIsOverlayVisible(false)
64
+ }, /*#__PURE__*/React.createElement(InlineCardOverlay, {
65
+ isVisible: isOverlayVisible,
66
+ url: url
57
67
  }, /*#__PURE__*/React.createElement(SmartCard, {
58
68
  key: url,
59
69
  url: url,
@@ -65,7 +75,7 @@ const InlineCard = ({
65
75
  onError: onError,
66
76
  inlinePreloaderStyle: useAlternativePreloader ? 'on-right-without-skeleton' : undefined,
67
77
  showServerActions: showServerActions
68
- }));
78
+ })));
69
79
  // [WS-2307]: we only render card wrapped into a Provider when the value is ready,
70
80
  // otherwise if we got data, we can render the card directly since it doesn't need the Provider
71
81
  return cardContext && cardContext.value ? /*#__PURE__*/React.createElement(cardContext.Provider, {
@@ -114,16 +114,10 @@ export const floatingToolbar = (cardOptions, featureFlags, platform, linkPickerO
114
114
 
115
115
  // Applies padding override for when link picker is currently displayed
116
116
  const className = pluginState !== null && pluginState !== void 0 && pluginState.showLinkingToolbar ? FLOATING_TOOLBAR_LINKPICKER_CLASSNAME : undefined;
117
-
118
- /**
119
- * Enable focus trap only if feature flag is enabled AND for the new version of the picker
120
- */
121
117
  const {
122
118
  lpLinkPicker,
123
- lpLinkPickerFocusTrap,
124
119
  preventPopupOverflow
125
120
  } = featureFlags;
126
- const shouldEnableFocusTrap = lpLinkPicker && lpLinkPickerFocusTrap;
127
121
  const isLinkPickerEnabled = !!lpLinkPicker;
128
122
  return {
129
123
  title: intl.formatMessage(messages.card),
@@ -143,7 +137,6 @@ export const floatingToolbar = (cardOptions, featureFlags, platform, linkPickerO
143
137
  },
144
138
  items: generateToolbarItems(state, featureFlags, intl, providerFactory, cardOptions, platform, linkPickerOptions, pluginInjectionApi),
145
139
  scrollable: pluginState !== null && pluginState !== void 0 && pluginState.showLinkingToolbar ? false : true,
146
- focusTrap: shouldEnableFocusTrap && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.showLinkingToolbar),
147
140
  ...editLinkToolbarConfig(Boolean(pluginState === null || pluginState === void 0 ? void 0 : pluginState.showLinkingToolbar), isLinkPickerEnabled)
148
141
  };
149
142
  };
@@ -402,4 +395,7 @@ const getDatasourceButtonGroup = (metadata, intl, editorAnalyticsApi, node, hove
402
395
  onClick: withToolbarMetadata(removeCard(editorAnalyticsApi))
403
396
  });
404
397
  return toolbarItems;
398
+ };
399
+ export const shouldRenderToolbarPulse = (embedEnabled, appearance, status, isDiscoverabilityEnabled) => {
400
+ return embedEnabled && appearance === 'inline' && status === 'resolved' && isDiscoverabilityEnabled && getBooleanFF('platform.linking-platform.smart-card.inline-switcher');
405
401
  };