@atlaskit/editor-plugin-card 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/messages.js +5 -0
  3. package/dist/cjs/nodeviews/inlineCardWithAwareness.js +20 -2
  4. package/dist/cjs/toolbar.js +1 -8
  5. package/dist/cjs/ui/EditDatasourceButton.js +2 -6
  6. package/dist/cjs/ui/HyperlinkToolbarAppearance.js +10 -2
  7. package/dist/cjs/ui/InlineCardOverlay/index.js +187 -0
  8. package/dist/cjs/ui/InlineCardOverlay/types.js +5 -0
  9. package/dist/cjs/ui/useFetchDatasourceInfo.js +4 -0
  10. package/dist/es2019/messages.js +5 -0
  11. package/dist/es2019/nodeviews/inlineCardWithAwareness.js +13 -3
  12. package/dist/es2019/toolbar.js +0 -7
  13. package/dist/es2019/ui/EditDatasourceButton.js +2 -6
  14. package/dist/es2019/ui/HyperlinkToolbarAppearance.js +10 -2
  15. package/dist/es2019/ui/InlineCardOverlay/index.js +175 -0
  16. package/dist/es2019/ui/InlineCardOverlay/types.js +1 -0
  17. package/dist/es2019/ui/useFetchDatasourceInfo.js +5 -0
  18. package/dist/esm/messages.js +5 -0
  19. package/dist/esm/nodeviews/inlineCardWithAwareness.js +21 -3
  20. package/dist/esm/toolbar.js +1 -8
  21. package/dist/esm/ui/EditDatasourceButton.js +2 -6
  22. package/dist/esm/ui/HyperlinkToolbarAppearance.js +10 -2
  23. package/dist/esm/ui/InlineCardOverlay/index.js +179 -0
  24. package/dist/esm/ui/InlineCardOverlay/types.js +1 -0
  25. package/dist/esm/ui/useFetchDatasourceInfo.js +5 -0
  26. package/dist/types/messages.d.ts +5 -0
  27. package/dist/types/ui/HyperlinkToolbarAppearance.d.ts +6 -7
  28. package/dist/types/ui/InlineCardOverlay/index.d.ts +5 -0
  29. package/dist/types/ui/InlineCardOverlay/types.d.ts +6 -0
  30. package/dist/types-ts4.5/messages.d.ts +5 -0
  31. package/dist/types-ts4.5/ui/HyperlinkToolbarAppearance.d.ts +6 -7
  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/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-plugin-card
2
2
 
3
+ ## 0.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#42821](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/42821) [`9ae7cc56578`](https://bitbucket.org/atlassian/atlassian-frontend/commits/9ae7cc56578) - [ux] Adds datasource edit button to blue links that can resolve into datasources
8
+
9
+ ## 0.11.1
10
+
11
+ ### Patch Changes
12
+
13
+ - [#42248](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/42248) [`c3ce5d9263f`](https://bitbucket.org/atlassian/atlassian-frontend/commits/c3ce5d9263f) - Add inline card overlay component
14
+ - [#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.
15
+ - Updated dependencies
16
+
3
17
  ## 0.11.0
4
18
 
5
19
  ### Minor Changes
@@ -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, {
@@ -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
  };
@@ -8,6 +8,7 @@ var _react = require("@emotion/react");
8
8
  var _messages = require("@atlaskit/editor-common/messages");
9
9
  var _ui = require("@atlaskit/editor-common/ui");
10
10
  var _utils = require("@atlaskit/editor-common/utils");
11
+ var _primitives = require("@atlaskit/primitives");
11
12
  var _actions = require("../pm-plugins/actions");
12
13
  var _CardContextProvider = require("./CardContextProvider");
13
14
  var _useFetchDatasourceInfo = require("./useFetchDatasourceInfo");
@@ -16,9 +17,6 @@ var _useFetchDatasourceInfo = require("./useFetchDatasourceInfo");
16
17
  var buttonStyles = (0, _react.css)({
17
18
  pointerEvents: 'auto'
18
19
  });
19
- var buttonWrapperStyles = (0, _react.css)({
20
- display: 'flex'
21
- });
22
20
 
23
21
  // Edit button in toolbar to open datasource modal. This button is shown for inline, block, and embed cards
24
22
  // if they can resolve into a datasource.
@@ -51,9 +49,7 @@ var EditDatasourceButtonWithCardContext = function EditDatasourceButtonWithCardC
51
49
  editorView.focus();
52
50
  }
53
51
  };
54
- return (0, _react.jsx)("div", {
55
- css: buttonWrapperStyles
56
- }, (0, _react.jsx)(_ui.FloatingToolbarButton, {
52
+ return (0, _react.jsx)(_primitives.Flex, null, (0, _react.jsx)(_ui.FloatingToolbarButton, {
57
53
  css: buttonStyles,
58
54
  title: intl.formatMessage(_messages.cardMessages.datasourceTitle),
59
55
  icon: (0, _react.jsx)(_ui.SmallerEditIcon, null),
@@ -16,6 +16,8 @@ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime
16
16
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
17
17
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
18
18
  var _react = _interopRequireWildcard(require("react"));
19
+ var _primitives = require("@atlaskit/primitives");
20
+ var _EditDatasourceButton = require("./EditDatasourceButton");
19
21
  var _LinkToolbarAppearance = require("./LinkToolbarAppearance");
20
22
  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); }
21
23
  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; }
@@ -155,7 +157,13 @@ var HyperlinkToolbarAppearance = exports.HyperlinkToolbarAppearance = /*#__PURE_
155
157
  if (!supportedUrlsMap.get(url)) {
156
158
  return null;
157
159
  }
158
- return /*#__PURE__*/_react.default.createElement(_LinkToolbarAppearance.LinkToolbarAppearance, {
160
+ return /*#__PURE__*/_react.default.createElement(_primitives.Flex, null, /*#__PURE__*/_react.default.createElement(_EditDatasourceButton.EditDatasourceButton, {
161
+ url: url,
162
+ intl: intl,
163
+ editorState: editorState,
164
+ editorView: editorView,
165
+ editorAnalyticsApi: editorAnalyticsApi
166
+ }), /*#__PURE__*/_react.default.createElement(_LinkToolbarAppearance.LinkToolbarAppearance, {
159
167
  key: "link-appearance",
160
168
  url: url,
161
169
  intl: intl,
@@ -166,7 +174,7 @@ var HyperlinkToolbarAppearance = exports.HyperlinkToolbarAppearance = /*#__PURE_
166
174
  platform: platform,
167
175
  editorAnalyticsApi: editorAnalyticsApi,
168
176
  cardActions: cardActions
169
- });
177
+ }));
170
178
  }
171
179
  }]);
172
180
  return HyperlinkToolbarAppearance;
@@ -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
+ });
@@ -11,6 +11,10 @@ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/sli
11
11
  var _react = require("react");
12
12
  /** @jsx jsx */
13
13
 
14
+ // eslint-disable-next-line import/no-extraneous-dependencies
15
+
16
+ // eslint-disable-next-line import/no-extraneous-dependencies
17
+
14
18
  var useFetchDatasourceInfo = exports.useFetchDatasourceInfo = function useFetchDatasourceInfo(_ref) {
15
19
  var isRegularCardNode = _ref.isRegularCardNode,
16
20
  url = _ref.url,
@@ -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
  };
@@ -3,15 +3,13 @@ import { css, jsx } from '@emotion/react';
3
3
  import { cardMessages as messages } from '@atlaskit/editor-common/messages';
4
4
  import { FloatingToolbarButton as Button, FloatingToolbarSeparator as Separator, SmallerEditIcon } from '@atlaskit/editor-common/ui';
5
5
  import { canRenderDatasource, getDatasourceType } from '@atlaskit/editor-common/utils';
6
+ import { Flex } from '@atlaskit/primitives';
6
7
  import { showDatasourceModal } from '../pm-plugins/actions';
7
8
  import { CardContextProvider } from './CardContextProvider';
8
9
  import { useFetchDatasourceInfo } from './useFetchDatasourceInfo';
9
10
  const buttonStyles = css({
10
11
  pointerEvents: 'auto'
11
12
  });
12
- const buttonWrapperStyles = css({
13
- display: 'flex'
14
- });
15
13
 
16
14
  // Edit button in toolbar to open datasource modal. This button is shown for inline, block, and embed cards
17
15
  // if they can resolve into a datasource.
@@ -46,9 +44,7 @@ const EditDatasourceButtonWithCardContext = ({
46
44
  editorView.focus();
47
45
  }
48
46
  };
49
- return jsx("div", {
50
- css: buttonWrapperStyles
51
- }, jsx(Button, {
47
+ return jsx(Flex, null, jsx(Button, {
52
48
  css: buttonStyles,
53
49
  title: intl.formatMessage(messages.datasourceTitle),
54
50
  icon: jsx(SmallerEditIcon, null),
@@ -1,5 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import React, { Component } from 'react';
3
+ import { Flex } from '@atlaskit/primitives';
4
+ import { EditDatasourceButton } from './EditDatasourceButton';
3
5
  import { LinkToolbarAppearance } from './LinkToolbarAppearance';
4
6
  // eslint-disable-next-line @repo/internal/react/no-class-components
5
7
  export class HyperlinkToolbarAppearance extends Component {
@@ -70,7 +72,13 @@ export class HyperlinkToolbarAppearance extends Component {
70
72
  if (!supportedUrlsMap.get(url)) {
71
73
  return null;
72
74
  }
73
- return /*#__PURE__*/React.createElement(LinkToolbarAppearance, {
75
+ return /*#__PURE__*/React.createElement(Flex, null, /*#__PURE__*/React.createElement(EditDatasourceButton, {
76
+ url: url,
77
+ intl: intl,
78
+ editorState: editorState,
79
+ editorView: editorView,
80
+ editorAnalyticsApi: editorAnalyticsApi
81
+ }), /*#__PURE__*/React.createElement(LinkToolbarAppearance, {
74
82
  key: "link-appearance",
75
83
  url: url,
76
84
  intl: intl,
@@ -81,6 +89,6 @@ export class HyperlinkToolbarAppearance extends Component {
81
89
  platform: platform,
82
90
  editorAnalyticsApi: editorAnalyticsApi,
83
91
  cardActions: cardActions
84
- });
92
+ }));
85
93
  }
86
94
  }
@@ -0,0 +1,175 @@
1
+ /** @jsx jsx */
2
+
3
+ import React, { useLayoutEffect, useMemo, useRef, useState } from 'react';
4
+ import { css, jsx } from '@emotion/react';
5
+ import { useIntl } from 'react-intl-next';
6
+ import { browser } from '@atlaskit/editor-common/utils';
7
+ import HipchatChevronDownIcon from '@atlaskit/icon/glyph/hipchat/chevron-down';
8
+ import HipchatChevronUpIcon from '@atlaskit/icon/glyph/hipchat/chevron-up';
9
+ import { N20A, N800 } from '@atlaskit/theme/colors';
10
+ import { messages } from '../../messages';
11
+ const PADDING_IN_PX = 2;
12
+ const containerStyles = css({
13
+ position: 'relative'
14
+ });
15
+ const linkStyles = css({
16
+ color: "var(--ds-text, #172B4D)",
17
+ textDecoration: 'none'
18
+ });
19
+ const overlayStyles = css({
20
+ // Positioning
21
+ position: 'relative',
22
+ display: 'inline-flex',
23
+ flexWrap: 'nowrap',
24
+ alignItems: 'center',
25
+ alignSelf: 'stretch',
26
+ height: 'inherit',
27
+ lineHeight: 'initial',
28
+ width: 'max-content',
29
+ top: "var(--ds-space-0, 0)",
30
+ bottom: "var(--ds-space-0, 0)",
31
+ right: 3,
32
+ margin: `-1px ${"var(--ds-space-0, 0)"}`,
33
+ padding: "var(--ds-space-0, 0)",
34
+ // Styling
35
+ fontSize: 'inherit',
36
+ fontWeight: 'normal',
37
+ color: `var(--ds-text, ${N800})`,
38
+ background: `var(--ds-background-accent-gray-subtlest, ${N20A})`,
39
+ borderRadius: 3,
40
+ // inline card border of 4px - 1px
41
+
42
+ // Using `&` twice to increase specificity. (These are not nested styles.)
43
+ /* eslint-disable @atlaskit/design-system/no-nested-styles */
44
+ '&&:link': {
45
+ ...linkStyles
46
+ },
47
+ '&&:active': {
48
+ ...linkStyles
49
+ },
50
+ '&&:focus': {
51
+ ...linkStyles
52
+ },
53
+ '&&:hover': {
54
+ ...linkStyles
55
+ },
56
+ '&&:visited': {
57
+ ...linkStyles
58
+ },
59
+ /* eslint-enable @atlaskit/design-system/no-nested-styles */
60
+
61
+ // EDM-1717: box-shadow Safari fix bring load wrapper zIndex to 1
62
+ zIndex: 2,
63
+ // Fill lines, match heading and paragraph size
64
+ '::before': {
65
+ content: '" "',
66
+ display: 'inline-block',
67
+ verticalAlign: 'middle',
68
+ width: "var(--ds-space-0, 0)",
69
+ margin: "var(--ds-space-0, 0)",
70
+ padding: "var(--ds-space-0, 0)"
71
+ }
72
+ });
73
+ const safariOverlayStyles = css({
74
+ height: '1.1em',
75
+ paddingBottom: "var(--ds-space-025, 2px)",
76
+ right: 3
77
+ });
78
+ const textStyles = css({
79
+ paddingLeft: "var(--ds-space-050, 4px)"
80
+ });
81
+ const iconStyles = css({
82
+ // Position icon in the middle
83
+ display: 'inline-grid',
84
+ // We want to position the icon in the middle of large text type like heading 1
85
+ // eslint-disable-next-line @atlaskit/design-system/no-nested-styles
86
+ span: {
87
+ display: 'inline-grid'
88
+ }
89
+ });
90
+ const markerStyles = css({
91
+ height: "var(--ds-space-0, 0)",
92
+ width: "var(--ds-space-0, 0)",
93
+ margin: "var(--ds-space-0, 0)",
94
+ padding: "var(--ds-space-0, 0)"
95
+ });
96
+ const InlineCardOverlay = ({
97
+ children,
98
+ isToolbarOpen = false,
99
+ isVisible = false,
100
+ testId = 'inline-card-overlay',
101
+ url
102
+ }) => {
103
+ const [showLabel, setShowLabel] = useState(true);
104
+ const [overlayWidth, setOverlayWidth] = useState(0);
105
+ const containerRef = useRef(null);
106
+ const markerRef = useRef(null);
107
+ const overlayRef = useRef(null);
108
+ const labelRef = useRef(null);
109
+ useLayoutEffect(() => {
110
+ if (!isVisible) {
111
+ // Reset to default state for width calculation when the component become visible.
112
+ setShowLabel(true);
113
+ return;
114
+ }
115
+ try {
116
+ var _containerRef$current, _containerRef$current2, _containerRef$current3, _markerRef$current$ge, _markerRef$current, _markerRef$current$ge2, _overlayRef$current$g, _overlayRef$current, _overlayRef$current$g2, _labelRef$current$get, _labelRef$current, _labelRef$current$get2;
117
+ // Get the width of the available space to display overlay
118
+ const start = (_containerRef$current = containerRef === null || containerRef === void 0 ? void 0 : (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : (_containerRef$current3 = _containerRef$current2.getBoundingClientRect()) === null || _containerRef$current3 === void 0 ? void 0 : _containerRef$current3.left) !== null && _containerRef$current !== void 0 ? _containerRef$current : 0;
119
+ const end = (_markerRef$current$ge = markerRef === null || markerRef === void 0 ? void 0 : (_markerRef$current = markerRef.current) === null || _markerRef$current === void 0 ? void 0 : (_markerRef$current$ge2 = _markerRef$current.getBoundingClientRect()) === null || _markerRef$current$ge2 === void 0 ? void 0 : _markerRef$current$ge2.left) !== null && _markerRef$current$ge !== void 0 ? _markerRef$current$ge : 0;
120
+ const availableWidth = end - start - PADDING_IN_PX;
121
+
122
+ // Get overlay width and label width
123
+ const overlayWidth = (_overlayRef$current$g = overlayRef === null || overlayRef === void 0 ? void 0 : (_overlayRef$current = overlayRef.current) === null || _overlayRef$current === void 0 ? void 0 : (_overlayRef$current$g2 = _overlayRef$current.getBoundingClientRect()) === null || _overlayRef$current$g2 === void 0 ? void 0 : _overlayRef$current$g2.width) !== null && _overlayRef$current$g !== void 0 ? _overlayRef$current$g : 0;
124
+
125
+ // Show label if there is enough space to display
126
+ const shouldShowLabel = availableWidth > 0 && overlayWidth > 0 ? availableWidth > overlayWidth : false;
127
+ setShowLabel(shouldShowLabel);
128
+
129
+ // We use relative positioning and need to set
130
+ // negative margin left (ltr) as the width of the overlay
131
+ // to make the overlay position on top of inline link.
132
+ const labelWidth = (_labelRef$current$get = labelRef === null || labelRef === void 0 ? void 0 : (_labelRef$current = labelRef.current) === null || _labelRef$current === void 0 ? void 0 : (_labelRef$current$get2 = _labelRef$current.getBoundingClientRect()) === null || _labelRef$current$get2 === void 0 ? void 0 : _labelRef$current$get2.width) !== null && _labelRef$current$get !== void 0 ? _labelRef$current$get : 0;
133
+ const newOverlayWidth = shouldShowLabel ? overlayWidth : overlayWidth - labelWidth;
134
+ setOverlayWidth(newOverlayWidth);
135
+ } catch {
136
+ // If something goes wrong, play it safe by hiding label so that
137
+ // the component does not look too janky.
138
+ setShowLabel(false);
139
+ }
140
+ }, [isVisible]);
141
+ const intl = useIntl();
142
+ const label = intl.formatMessage(messages.inlineOverlay);
143
+ const icon = useMemo(() => {
144
+ const IconComponent = isToolbarOpen ? HipchatChevronUpIcon : HipchatChevronDownIcon;
145
+ return jsx(IconComponent, {
146
+ label: label,
147
+ size: "small",
148
+ testId: `${testId}-${isToolbarOpen ? 'open' : 'close'}`
149
+ });
150
+ }, [isToolbarOpen, label, testId]);
151
+ return jsx("span", {
152
+ css: containerStyles,
153
+ ref: containerRef
154
+ }, children, isVisible && jsx(React.Fragment, null, jsx("span", {
155
+ "aria-hidden": "true",
156
+ css: markerStyles,
157
+ ref: markerRef
158
+ }), jsx("a", {
159
+ css: [overlayStyles, browser.safari && safariOverlayStyles],
160
+ style: {
161
+ marginLeft: -overlayWidth
162
+ },
163
+ "data-testid": testId,
164
+ href: url,
165
+ onClick: e => e.preventDefault(),
166
+ ref: overlayRef
167
+ }, showLabel && jsx("span", {
168
+ css: textStyles,
169
+ "data-testid": `${testId}-label`,
170
+ ref: labelRef
171
+ }, label), jsx("span", {
172
+ css: iconStyles
173
+ }, icon))));
174
+ };
175
+ export default InlineCardOverlay;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,10 @@
1
1
  /** @jsx jsx */
2
2
  import { useEffect, useState } from 'react';
3
+
4
+ // eslint-disable-next-line import/no-extraneous-dependencies
5
+
6
+ // eslint-disable-next-line import/no-extraneous-dependencies
7
+
3
8
  export const useFetchDatasourceInfo = ({
4
9
  isRegularCardNode,
5
10
  url,
@@ -19,5 +19,10 @@ export var 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,10 @@
1
- import React, { memo, useCallback, useMemo } from 'react';
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import React, { memo, useCallback, useMemo, useState } from 'react';
2
3
  import rafSchedule from 'raf-schd';
3
4
  import { findOverflowScrollParent } from '@atlaskit/editor-common/ui';
4
5
  import { Card as SmartCard } from '@atlaskit/smart-card';
5
6
  import { registerCard } from '../pm-plugins/actions';
7
+ import InlineCardOverlay from '../ui/InlineCardOverlay';
6
8
  var InlineCard = function InlineCard(_ref) {
7
9
  var node = _ref.node,
8
10
  cardContext = _ref.cardContext,
@@ -16,6 +18,13 @@ var InlineCard = function InlineCard(_ref) {
16
18
  var _node$attrs = node.attrs,
17
19
  url = _node$attrs.url,
18
20
  data = _node$attrs.data;
21
+
22
+ // A complete show/hide logic for the overlay will be implemented
23
+ // in EDM-8239 and EDM-8241
24
+ var _useState = useState(false),
25
+ _useState2 = _slicedToArray(_useState, 2),
26
+ isOverlayVisible = _useState2[0],
27
+ setIsOverlayVisible = _useState2[1];
19
28
  var onClick = function onClick() {};
20
29
  var onResolve = useCallback(function (data) {
21
30
  if (!getPos || typeof getPos === 'boolean') {
@@ -49,7 +58,16 @@ var InlineCard = function InlineCard(_ref) {
49
58
  });
50
59
  }, [onResolve]);
51
60
  var card = /*#__PURE__*/React.createElement("span", {
52
- className: "card"
61
+ className: "card",
62
+ onMouseEnter: function onMouseEnter() {
63
+ return setIsOverlayVisible(true);
64
+ },
65
+ onMouseLeave: function onMouseLeave() {
66
+ return setIsOverlayVisible(false);
67
+ }
68
+ }, /*#__PURE__*/React.createElement(InlineCardOverlay, {
69
+ isVisible: isOverlayVisible,
70
+ url: url
53
71
  }, /*#__PURE__*/React.createElement(SmartCard, {
54
72
  key: url,
55
73
  url: url,
@@ -61,7 +79,7 @@ var InlineCard = function InlineCard(_ref) {
61
79
  onError: onError,
62
80
  inlinePreloaderStyle: useAlternativePreloader ? 'on-right-without-skeleton' : undefined,
63
81
  showServerActions: showServerActions
64
- }));
82
+ })));
65
83
  // [WS-2307]: we only render card wrapped into a Provider when the value is ready,
66
84
  // otherwise if we got data, we can render the card directly since it doesn't need the Provider
67
85
  return cardContext && cardContext.value ? /*#__PURE__*/React.createElement(cardContext.Provider, {
@@ -110,14 +110,8 @@ export var floatingToolbar = function floatingToolbar(cardOptions, featureFlags,
110
110
 
111
111
  // Applies padding override for when link picker is currently displayed
112
112
  var className = pluginState !== null && pluginState !== void 0 && pluginState.showLinkingToolbar ? FLOATING_TOOLBAR_LINKPICKER_CLASSNAME : undefined;
113
-
114
- /**
115
- * Enable focus trap only if feature flag is enabled AND for the new version of the picker
116
- */
117
113
  var lpLinkPicker = featureFlags.lpLinkPicker,
118
- lpLinkPickerFocusTrap = featureFlags.lpLinkPickerFocusTrap,
119
114
  preventPopupOverflow = featureFlags.preventPopupOverflow;
120
- var shouldEnableFocusTrap = lpLinkPicker && lpLinkPickerFocusTrap;
121
115
  var isLinkPickerEnabled = !!lpLinkPicker;
122
116
  return _objectSpread(_objectSpread({
123
117
  title: intl.formatMessage(messages.card),
@@ -136,8 +130,7 @@ export var floatingToolbar = function floatingToolbar(cardOptions, featureFlags,
136
130
  return element;
137
131
  },
138
132
  items: generateToolbarItems(state, featureFlags, intl, providerFactory, cardOptions, platform, linkPickerOptions, pluginInjectionApi),
139
- scrollable: pluginState !== null && pluginState !== void 0 && pluginState.showLinkingToolbar ? false : true,
140
- focusTrap: shouldEnableFocusTrap && (pluginState === null || pluginState === void 0 ? void 0 : pluginState.showLinkingToolbar)
133
+ scrollable: pluginState !== null && pluginState !== void 0 && pluginState.showLinkingToolbar ? false : true
141
134
  }, editLinkToolbarConfig(Boolean(pluginState === null || pluginState === void 0 ? void 0 : pluginState.showLinkingToolbar), isLinkPickerEnabled));
142
135
  };
143
136
  };
@@ -3,15 +3,13 @@ import { css, jsx } from '@emotion/react';
3
3
  import { cardMessages as messages } from '@atlaskit/editor-common/messages';
4
4
  import { FloatingToolbarButton as Button, FloatingToolbarSeparator as Separator, SmallerEditIcon } from '@atlaskit/editor-common/ui';
5
5
  import { canRenderDatasource, getDatasourceType } from '@atlaskit/editor-common/utils';
6
+ import { Flex } from '@atlaskit/primitives';
6
7
  import { showDatasourceModal } from '../pm-plugins/actions';
7
8
  import { CardContextProvider } from './CardContextProvider';
8
9
  import { useFetchDatasourceInfo } from './useFetchDatasourceInfo';
9
10
  var buttonStyles = css({
10
11
  pointerEvents: 'auto'
11
12
  });
12
- var buttonWrapperStyles = css({
13
- display: 'flex'
14
- });
15
13
 
16
14
  // Edit button in toolbar to open datasource modal. This button is shown for inline, block, and embed cards
17
15
  // if they can resolve into a datasource.
@@ -44,9 +42,7 @@ var EditDatasourceButtonWithCardContext = function EditDatasourceButtonWithCardC
44
42
  editorView.focus();
45
43
  }
46
44
  };
47
- return jsx("div", {
48
- css: buttonWrapperStyles
49
- }, jsx(Button, {
45
+ return jsx(Flex, null, jsx(Button, {
50
46
  css: buttonStyles,
51
47
  title: intl.formatMessage(messages.datasourceTitle),
52
48
  icon: jsx(SmallerEditIcon, null),
@@ -10,6 +10,8 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
10
10
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
11
11
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
12
12
  import React, { Component } from 'react';
13
+ import { Flex } from '@atlaskit/primitives';
14
+ import { EditDatasourceButton } from './EditDatasourceButton';
13
15
  import { LinkToolbarAppearance } from './LinkToolbarAppearance';
14
16
  // eslint-disable-next-line @repo/internal/react/no-class-components
15
17
  export var HyperlinkToolbarAppearance = /*#__PURE__*/function (_Component) {
@@ -145,7 +147,13 @@ export var HyperlinkToolbarAppearance = /*#__PURE__*/function (_Component) {
145
147
  if (!supportedUrlsMap.get(url)) {
146
148
  return null;
147
149
  }
148
- return /*#__PURE__*/React.createElement(LinkToolbarAppearance, {
150
+ return /*#__PURE__*/React.createElement(Flex, null, /*#__PURE__*/React.createElement(EditDatasourceButton, {
151
+ url: url,
152
+ intl: intl,
153
+ editorState: editorState,
154
+ editorView: editorView,
155
+ editorAnalyticsApi: editorAnalyticsApi
156
+ }), /*#__PURE__*/React.createElement(LinkToolbarAppearance, {
149
157
  key: "link-appearance",
150
158
  url: url,
151
159
  intl: intl,
@@ -156,7 +164,7 @@ export var HyperlinkToolbarAppearance = /*#__PURE__*/function (_Component) {
156
164
  platform: platform,
157
165
  editorAnalyticsApi: editorAnalyticsApi,
158
166
  cardActions: cardActions
159
- });
167
+ }));
160
168
  }
161
169
  }]);
162
170
  return HyperlinkToolbarAppearance;
@@ -0,0 +1,179 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
+ /** @jsx jsx */
6
+
7
+ import React, { useLayoutEffect, useMemo, useRef, useState } from 'react';
8
+ import { css, jsx } from '@emotion/react';
9
+ import { useIntl } from 'react-intl-next';
10
+ import { browser } from '@atlaskit/editor-common/utils';
11
+ import HipchatChevronDownIcon from '@atlaskit/icon/glyph/hipchat/chevron-down';
12
+ import HipchatChevronUpIcon from '@atlaskit/icon/glyph/hipchat/chevron-up';
13
+ import { N20A, N800 } from '@atlaskit/theme/colors';
14
+ import { messages } from '../../messages';
15
+ var PADDING_IN_PX = 2;
16
+ var containerStyles = css({
17
+ position: 'relative'
18
+ });
19
+ var linkStyles = css({
20
+ color: "var(--ds-text, #172B4D)",
21
+ textDecoration: 'none'
22
+ });
23
+ var overlayStyles = css({
24
+ // Positioning
25
+ position: 'relative',
26
+ display: 'inline-flex',
27
+ flexWrap: 'nowrap',
28
+ alignItems: 'center',
29
+ alignSelf: 'stretch',
30
+ height: 'inherit',
31
+ lineHeight: 'initial',
32
+ width: 'max-content',
33
+ top: "var(--ds-space-0, 0)",
34
+ bottom: "var(--ds-space-0, 0)",
35
+ right: 3,
36
+ margin: "-1px ".concat("var(--ds-space-0, 0)"),
37
+ padding: "var(--ds-space-0, 0)",
38
+ // Styling
39
+ fontSize: 'inherit',
40
+ fontWeight: 'normal',
41
+ color: "var(--ds-text, ".concat(N800, ")"),
42
+ background: "var(--ds-background-accent-gray-subtlest, ".concat(N20A, ")"),
43
+ borderRadius: 3,
44
+ // inline card border of 4px - 1px
45
+
46
+ // Using `&` twice to increase specificity. (These are not nested styles.)
47
+ /* eslint-disable @atlaskit/design-system/no-nested-styles */
48
+ '&&:link': _objectSpread({}, linkStyles),
49
+ '&&:active': _objectSpread({}, linkStyles),
50
+ '&&:focus': _objectSpread({}, linkStyles),
51
+ '&&:hover': _objectSpread({}, linkStyles),
52
+ '&&:visited': _objectSpread({}, linkStyles),
53
+ /* eslint-enable @atlaskit/design-system/no-nested-styles */
54
+
55
+ // EDM-1717: box-shadow Safari fix bring load wrapper zIndex to 1
56
+ zIndex: 2,
57
+ // Fill lines, match heading and paragraph size
58
+ '::before': {
59
+ content: '" "',
60
+ display: 'inline-block',
61
+ verticalAlign: 'middle',
62
+ width: "var(--ds-space-0, 0)",
63
+ margin: "var(--ds-space-0, 0)",
64
+ padding: "var(--ds-space-0, 0)"
65
+ }
66
+ });
67
+ var safariOverlayStyles = css({
68
+ height: '1.1em',
69
+ paddingBottom: "var(--ds-space-025, 2px)",
70
+ right: 3
71
+ });
72
+ var textStyles = css({
73
+ paddingLeft: "var(--ds-space-050, 4px)"
74
+ });
75
+ var iconStyles = css({
76
+ // Position icon in the middle
77
+ display: 'inline-grid',
78
+ // We want to position the icon in the middle of large text type like heading 1
79
+ // eslint-disable-next-line @atlaskit/design-system/no-nested-styles
80
+ span: {
81
+ display: 'inline-grid'
82
+ }
83
+ });
84
+ var markerStyles = css({
85
+ height: "var(--ds-space-0, 0)",
86
+ width: "var(--ds-space-0, 0)",
87
+ margin: "var(--ds-space-0, 0)",
88
+ padding: "var(--ds-space-0, 0)"
89
+ });
90
+ var InlineCardOverlay = function InlineCardOverlay(_ref) {
91
+ var children = _ref.children,
92
+ _ref$isToolbarOpen = _ref.isToolbarOpen,
93
+ isToolbarOpen = _ref$isToolbarOpen === void 0 ? false : _ref$isToolbarOpen,
94
+ _ref$isVisible = _ref.isVisible,
95
+ isVisible = _ref$isVisible === void 0 ? false : _ref$isVisible,
96
+ _ref$testId = _ref.testId,
97
+ testId = _ref$testId === void 0 ? 'inline-card-overlay' : _ref$testId,
98
+ url = _ref.url;
99
+ var _useState = useState(true),
100
+ _useState2 = _slicedToArray(_useState, 2),
101
+ showLabel = _useState2[0],
102
+ setShowLabel = _useState2[1];
103
+ var _useState3 = useState(0),
104
+ _useState4 = _slicedToArray(_useState3, 2),
105
+ overlayWidth = _useState4[0],
106
+ setOverlayWidth = _useState4[1];
107
+ var containerRef = useRef(null);
108
+ var markerRef = useRef(null);
109
+ var overlayRef = useRef(null);
110
+ var labelRef = useRef(null);
111
+ useLayoutEffect(function () {
112
+ if (!isVisible) {
113
+ // Reset to default state for width calculation when the component become visible.
114
+ setShowLabel(true);
115
+ return;
116
+ }
117
+ try {
118
+ var _containerRef$current, _containerRef$current2, _markerRef$current$ge, _markerRef$current, _overlayRef$current$g, _overlayRef$current, _labelRef$current$get, _labelRef$current;
119
+ // Get the width of the available space to display overlay
120
+ 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;
121
+ 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;
122
+ var availableWidth = end - start - PADDING_IN_PX;
123
+
124
+ // Get overlay width and label width
125
+ 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;
126
+
127
+ // Show label if there is enough space to display
128
+ var shouldShowLabel = availableWidth > 0 && _overlayWidth > 0 ? availableWidth > _overlayWidth : false;
129
+ setShowLabel(shouldShowLabel);
130
+
131
+ // We use relative positioning and need to set
132
+ // negative margin left (ltr) as the width of the overlay
133
+ // to make the overlay position on top of inline link.
134
+ 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;
135
+ var newOverlayWidth = shouldShowLabel ? _overlayWidth : _overlayWidth - labelWidth;
136
+ setOverlayWidth(newOverlayWidth);
137
+ } catch (_unused) {
138
+ // If something goes wrong, play it safe by hiding label so that
139
+ // the component does not look too janky.
140
+ setShowLabel(false);
141
+ }
142
+ }, [isVisible]);
143
+ var intl = useIntl();
144
+ var label = intl.formatMessage(messages.inlineOverlay);
145
+ var icon = useMemo(function () {
146
+ var IconComponent = isToolbarOpen ? HipchatChevronUpIcon : HipchatChevronDownIcon;
147
+ return jsx(IconComponent, {
148
+ label: label,
149
+ size: "small",
150
+ testId: "".concat(testId, "-").concat(isToolbarOpen ? 'open' : 'close')
151
+ });
152
+ }, [isToolbarOpen, label, testId]);
153
+ return jsx("span", {
154
+ css: containerStyles,
155
+ ref: containerRef
156
+ }, children, isVisible && jsx(React.Fragment, null, jsx("span", {
157
+ "aria-hidden": "true",
158
+ css: markerStyles,
159
+ ref: markerRef
160
+ }), jsx("a", {
161
+ css: [overlayStyles, browser.safari && safariOverlayStyles],
162
+ style: {
163
+ marginLeft: -overlayWidth
164
+ },
165
+ "data-testid": testId,
166
+ href: url,
167
+ onClick: function onClick(e) {
168
+ return e.preventDefault();
169
+ },
170
+ ref: overlayRef
171
+ }, showLabel && jsx("span", {
172
+ css: textStyles,
173
+ "data-testid": "".concat(testId, "-label"),
174
+ ref: labelRef
175
+ }, label), jsx("span", {
176
+ css: iconStyles
177
+ }, icon))));
178
+ };
179
+ export default InlineCardOverlay;
@@ -0,0 +1 @@
1
+ export {};
@@ -3,6 +3,11 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import _regeneratorRuntime from "@babel/runtime/regenerator";
4
4
  /** @jsx jsx */
5
5
  import { useEffect, useState } from 'react';
6
+
7
+ // eslint-disable-next-line import/no-extraneous-dependencies
8
+
9
+ // eslint-disable-next-line import/no-extraneous-dependencies
10
+
6
11
  export var useFetchDatasourceInfo = function useFetchDatasourceInfo(_ref) {
7
12
  var isRegularCardNode = _ref.isRegularCardNode,
8
13
  url = _ref.url,
@@ -19,4 +19,9 @@ export declare const messages: {
19
19
  defaultMessage: string;
20
20
  description: string;
21
21
  };
22
+ inlineOverlay: {
23
+ id: string;
24
+ defaultMessage: string;
25
+ description: string;
26
+ };
22
27
  };
@@ -1,12 +1,11 @@
1
1
  import { Component } from 'react';
2
- import { IntlShape } from 'react-intl-next';
2
+ import type { IntlShape } from 'react-intl-next';
3
3
  import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
4
- import { CardOptions } from '@atlaskit/editor-common/card';
5
- import type { CardPluginActions } from '@atlaskit/editor-common/card';
6
- import { CardProvider, ProviderFactory } from '@atlaskit/editor-common/provider-factory';
7
- import { EditorState } from '@atlaskit/editor-prosemirror/state';
8
- import { EditorView } from '@atlaskit/editor-prosemirror/view';
9
- import { CardPlatform } from '@atlaskit/smart-card';
4
+ import type { CardOptions, CardPluginActions } from '@atlaskit/editor-common/card';
5
+ import type { CardProvider, ProviderFactory } from '@atlaskit/editor-common/provider-factory';
6
+ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
7
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
8
+ import type { CardPlatform } from '@atlaskit/smart-card';
10
9
  export interface HyperlinkToolbarAppearanceProps {
11
10
  intl: IntlShape;
12
11
  editorState: EditorState;
@@ -0,0 +1,5 @@
1
+ /** @jsx jsx */
2
+ import type { FC } from 'react';
3
+ import type { InlineCardOverlayProps } from './types';
4
+ declare const InlineCardOverlay: FC<InlineCardOverlayProps>;
5
+ export default InlineCardOverlay;
@@ -0,0 +1,6 @@
1
+ export type InlineCardOverlayProps = {
2
+ isToolbarOpen?: boolean;
3
+ isVisible?: boolean;
4
+ testId?: string;
5
+ url: string;
6
+ };
@@ -19,4 +19,9 @@ export declare const messages: {
19
19
  defaultMessage: string;
20
20
  description: string;
21
21
  };
22
+ inlineOverlay: {
23
+ id: string;
24
+ defaultMessage: string;
25
+ description: string;
26
+ };
22
27
  };
@@ -1,12 +1,11 @@
1
1
  import { Component } from 'react';
2
- import { IntlShape } from 'react-intl-next';
2
+ import type { IntlShape } from 'react-intl-next';
3
3
  import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
4
- import { CardOptions } from '@atlaskit/editor-common/card';
5
- import type { CardPluginActions } from '@atlaskit/editor-common/card';
6
- import { CardProvider, ProviderFactory } from '@atlaskit/editor-common/provider-factory';
7
- import { EditorState } from '@atlaskit/editor-prosemirror/state';
8
- import { EditorView } from '@atlaskit/editor-prosemirror/view';
9
- import { CardPlatform } from '@atlaskit/smart-card';
4
+ import type { CardOptions, CardPluginActions } from '@atlaskit/editor-common/card';
5
+ import type { CardProvider, ProviderFactory } from '@atlaskit/editor-common/provider-factory';
6
+ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
7
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
8
+ import type { CardPlatform } from '@atlaskit/smart-card';
10
9
  export interface HyperlinkToolbarAppearanceProps {
11
10
  intl: IntlShape;
12
11
  editorState: EditorState;
@@ -0,0 +1,5 @@
1
+ /** @jsx jsx */
2
+ import type { FC } from 'react';
3
+ import type { InlineCardOverlayProps } from './types';
4
+ declare const InlineCardOverlay: FC<InlineCardOverlayProps>;
5
+ export default InlineCardOverlay;
@@ -0,0 +1,6 @@
1
+ export type InlineCardOverlayProps = {
2
+ isToolbarOpen?: boolean;
3
+ isVisible?: boolean;
4
+ testId?: string;
5
+ url: string;
6
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-card",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Card plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -47,9 +47,10 @@
47
47
  "@atlaskit/frontend-utilities": "^2.7.0",
48
48
  "@atlaskit/icon": "^21.12.0",
49
49
  "@atlaskit/link-analytics": "^8.3.0",
50
- "@atlaskit/link-datasource": "^1.14.0",
50
+ "@atlaskit/link-datasource": "^1.15.0",
51
51
  "@atlaskit/linking-common": "^4.17.0",
52
52
  "@atlaskit/platform-feature-flags": "^0.2.0",
53
+ "@atlaskit/primitives": "^1.9.0",
53
54
  "@atlaskit/smart-card": "^26.42.0",
54
55
  "@atlaskit/theme": "^12.6.0",
55
56
  "@atlaskit/tokens": "^1.28.0",