@atlaskit/editor-plugin-card 1.13.0 → 1.14.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.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/ui/AwarenessWrapper/index.js +29 -11
- package/dist/cjs/ui/NewInlineCardOverlay/index.js +234 -0
- package/dist/es2019/ui/AwarenessWrapper/index.js +23 -7
- package/dist/es2019/ui/NewInlineCardOverlay/index.js +213 -0
- package/dist/esm/ui/AwarenessWrapper/index.js +29 -11
- package/dist/esm/ui/NewInlineCardOverlay/index.js +224 -0
- package/dist/types/ui/NewInlineCardOverlay/index.d.ts +6 -0
- package/dist/types-ts4.5/ui/NewInlineCardOverlay/index.d.ts +6 -0
- package/package.json +8 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-card
|
|
2
2
|
|
|
3
|
+
## 1.14.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#100627](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/100627)
|
|
8
|
+
[`619f85adfe8b`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/619f85adfe8b) -
|
|
9
|
+
EDM-9852 Add initial inline link overlay for live pages support
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#101524](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/101524)
|
|
14
|
+
[`4821570088e6`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/4821570088e6) -
|
|
15
|
+
ED-23362 Bump ADF schema to version 36.8.1 and add support for adf validation and transformation
|
|
16
|
+
|
|
3
17
|
## 1.13.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
|
@@ -9,10 +9,12 @@ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/sli
|
|
|
9
9
|
var _react = require("react");
|
|
10
10
|
var _react2 = require("@emotion/react");
|
|
11
11
|
var _analyticsNext = require("@atlaskit/analytics-next");
|
|
12
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
12
13
|
var _useLinkUpgradeDiscoverability = _interopRequireDefault(require("../../common/hooks/useLinkUpgradeDiscoverability"));
|
|
13
14
|
var _localStorage = require("../../common/local-storage");
|
|
14
15
|
var _utils = require("../../utils");
|
|
15
16
|
var _InlineCardOverlay = _interopRequireDefault(require("../InlineCardOverlay"));
|
|
17
|
+
var _NewInlineCardOverlay = _interopRequireDefault(require("../NewInlineCardOverlay"));
|
|
16
18
|
var _Pulse = require("../Pulse");
|
|
17
19
|
/** @jsx jsx */
|
|
18
20
|
|
|
@@ -77,17 +79,33 @@ var AwarenessWrapper = exports.AwarenessWrapper = function AwarenessWrapper(_ref
|
|
|
77
79
|
setOverlayHoveredStyles(isHovered);
|
|
78
80
|
}, [setOverlayHoveredStyles]);
|
|
79
81
|
var cardWithOverlay = (0, _react.useMemo)(function () {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
82
|
+
if (shouldShowLinkOverlay) {
|
|
83
|
+
if ((0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-links-in-live-pages')) {
|
|
84
|
+
return (0, _react2.jsx)(_NewInlineCardOverlay.default, {
|
|
85
|
+
isSelected: isSelected,
|
|
86
|
+
isVisible: isResolvedViewRendered && (isInserted || isHovered || isSelected),
|
|
87
|
+
onMouseEnter: function onMouseEnter() {
|
|
88
|
+
return handleOverlayChange(true);
|
|
89
|
+
},
|
|
90
|
+
onMouseLeave: function onMouseLeave() {
|
|
91
|
+
return handleOverlayChange(false);
|
|
92
|
+
},
|
|
93
|
+
url: url
|
|
94
|
+
}, children);
|
|
95
|
+
}
|
|
96
|
+
return (0, _react2.jsx)(_InlineCardOverlay.default, {
|
|
97
|
+
isSelected: isSelected,
|
|
98
|
+
isVisible: isResolvedViewRendered && (isInserted || isHovered || isSelected),
|
|
99
|
+
onMouseEnter: function onMouseEnter() {
|
|
100
|
+
return handleOverlayChange(true);
|
|
101
|
+
},
|
|
102
|
+
onMouseLeave: function onMouseLeave() {
|
|
103
|
+
return handleOverlayChange(false);
|
|
104
|
+
},
|
|
105
|
+
url: url
|
|
106
|
+
}, children);
|
|
107
|
+
}
|
|
108
|
+
return children;
|
|
91
109
|
}, [shouldShowLinkOverlay, isSelected, isResolvedViewRendered, isInserted, isHovered, url, children, handleOverlayChange]);
|
|
92
110
|
return (0, _react.useMemo)(function () {
|
|
93
111
|
var _cardContext$value;
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = void 0;
|
|
9
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
10
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
11
|
+
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
12
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
13
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
14
|
+
var _react2 = require("@emotion/react");
|
|
15
|
+
var _debounce = _interopRequireDefault(require("lodash/debounce"));
|
|
16
|
+
var _reactIntlNext = require("react-intl-next");
|
|
17
|
+
var _messages = require("@atlaskit/editor-common/messages");
|
|
18
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
19
|
+
var _preferences = _interopRequireDefault(require("@atlaskit/icon/glyph/preferences"));
|
|
20
|
+
var _colors = require("@atlaskit/theme/colors");
|
|
21
|
+
var _utils2 = require("../InlineCardOverlay/utils");
|
|
22
|
+
var _excluded = ["children", "isSelected", "isVisible", "testId", "url"];
|
|
23
|
+
/* eslint-disable @atlaskit/design-system/no-nested-styles */
|
|
24
|
+
/* eslint-disable @atlaskit/design-system/prefer-primitives */
|
|
25
|
+
/** @jsx jsx */
|
|
26
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
|
|
27
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
28
|
+
var DEBOUNCE_IN_MS = 5;
|
|
29
|
+
var ESTIMATED_MIN_WIDTH_IN_PX = 16;
|
|
30
|
+
var PADDING_IN_PX = 4;
|
|
31
|
+
var ICON_WIDTH_IN_PX = 14;
|
|
32
|
+
var ICON_AND_LABEL_CLASSNAME = 'ak-editor-card-overlay-icon-and-label';
|
|
33
|
+
var OVERLAY_LABEL_CLASSNAME = 'ak-editor-card-overlay-label';
|
|
34
|
+
var OVERLAY_MARKER_CLASSNAME = 'ak-editor-card-overlay-marker';
|
|
35
|
+
var TEXT_NODE_SELECTOR = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].join(',');
|
|
36
|
+
var SMART_LINK_BACKGROUND_COLOR = "var(--ds-surface-raised, ".concat(_colors.N0, ")");
|
|
37
|
+
// TODO: This should be lighter to match the rest of the button
|
|
38
|
+
var SMART_LINK_ACTIVE_COLOR = "var(--ds-background-selected, ".concat(_colors.B100, ")");
|
|
39
|
+
var containerStyles = (0, _react2.css)({
|
|
40
|
+
position: 'relative',
|
|
41
|
+
lineHeight: 'normal',
|
|
42
|
+
':active': (0, _defineProperty2.default)({}, ".".concat(ICON_AND_LABEL_CLASSNAME), {
|
|
43
|
+
background: SMART_LINK_ACTIVE_COLOR
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
var overlayStyles = (0, _react2.css)({
|
|
47
|
+
// Set default styling to be invisible but available in dom for width calculation.
|
|
48
|
+
visibility: 'hidden',
|
|
49
|
+
marginTop: "var(--ds-space-050, 4px)",
|
|
50
|
+
position: 'absolute',
|
|
51
|
+
verticalAlign: 'text-top',
|
|
52
|
+
height: '1lh',
|
|
53
|
+
'@supports not (height: 1lh)': {
|
|
54
|
+
height: '1.2em'
|
|
55
|
+
},
|
|
56
|
+
overflow: 'hidden',
|
|
57
|
+
// EDM-1717: box-shadow Safari fix bring load wrapper zIndex to 1
|
|
58
|
+
zIndex: 2,
|
|
59
|
+
pointerEvents: 'none'
|
|
60
|
+
});
|
|
61
|
+
var showOverlayStyles = (0, _react2.css)({
|
|
62
|
+
visibility: 'visible'
|
|
63
|
+
});
|
|
64
|
+
var iconStyles = (0, _react2.css)({
|
|
65
|
+
// Position icon in the middle
|
|
66
|
+
span: {
|
|
67
|
+
display: 'flex'
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
var labelStyles = (0, _react2.css)({
|
|
71
|
+
fontSize: '0.875em',
|
|
72
|
+
fontWeight: '600',
|
|
73
|
+
width: 'max-content'
|
|
74
|
+
});
|
|
75
|
+
var iconAndLabelStyles = (0, _react2.css)({
|
|
76
|
+
display: 'flex',
|
|
77
|
+
alignItems: 'center',
|
|
78
|
+
height: '100%',
|
|
79
|
+
marginLeft: "var(--ds-space-050, 4px)",
|
|
80
|
+
marginRight: "var(--ds-space-025, 2px)",
|
|
81
|
+
background: SMART_LINK_BACKGROUND_COLOR,
|
|
82
|
+
color: "var(--ds-text-subtlest, ".concat(_colors.N700, ")")
|
|
83
|
+
});
|
|
84
|
+
var overflowingContainerStyles = (0, _react2.css)({
|
|
85
|
+
display: 'flex',
|
|
86
|
+
flexDirection: 'row-reverse',
|
|
87
|
+
alignItems: 'center',
|
|
88
|
+
width: 'max-content',
|
|
89
|
+
height: '100%'
|
|
90
|
+
});
|
|
91
|
+
var NarrowInlineCardOverlay = function NarrowInlineCardOverlay(_ref) {
|
|
92
|
+
var children = _ref.children,
|
|
93
|
+
_ref$isSelected = _ref.isSelected,
|
|
94
|
+
isSelected = _ref$isSelected === void 0 ? false : _ref$isSelected,
|
|
95
|
+
_ref$isVisible = _ref.isVisible,
|
|
96
|
+
isVisible = _ref$isVisible === void 0 ? false : _ref$isVisible,
|
|
97
|
+
_ref$testId = _ref.testId,
|
|
98
|
+
testId = _ref$testId === void 0 ? 'inline-card-overlay' : _ref$testId,
|
|
99
|
+
url = _ref.url,
|
|
100
|
+
props = (0, _objectWithoutProperties2.default)(_ref, _excluded);
|
|
101
|
+
var _useState = (0, _react.useState)(false),
|
|
102
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
103
|
+
showOverlay = _useState2[0],
|
|
104
|
+
setShowOverlay = _useState2[1];
|
|
105
|
+
var _useState3 = (0, _react.useState)(undefined),
|
|
106
|
+
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
|
|
107
|
+
availableWidth = _useState4[0],
|
|
108
|
+
setAvailableWidth = _useState4[1];
|
|
109
|
+
var maxOverlayWidth = (0, _react.useRef)(0);
|
|
110
|
+
var minOverlayWidth = (0, _react.useRef)(ESTIMATED_MIN_WIDTH_IN_PX);
|
|
111
|
+
var parentWidth = (0, _react.useRef)(0);
|
|
112
|
+
var iconSize = (0, _react.useRef)('small');
|
|
113
|
+
var containerRef = (0, _react.useRef)(null);
|
|
114
|
+
|
|
115
|
+
// TODO EDM-9843: Use availableWidth for small link edge case
|
|
116
|
+
availableWidth;
|
|
117
|
+
var setVisibility = (0, _react.useCallback)(function () {
|
|
118
|
+
if (!containerRef.current || !maxOverlayWidth.current) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
var marker = (0, _utils2.getChildElement)(containerRef, ".".concat(OVERLAY_MARKER_CLASSNAME));
|
|
122
|
+
if (!marker) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
var oneLine = (0, _utils2.isOneLine)(containerRef.current, marker);
|
|
127
|
+
|
|
128
|
+
// Get the width of the available space to display overlay.
|
|
129
|
+
// This is the width of the inline link itself. If the inline
|
|
130
|
+
// is wrapped to the next line, this is width of the last line.
|
|
131
|
+
var _availableWidth = (0, _utils2.getInlineCardAvailableWidth)(containerRef.current, marker) - PADDING_IN_PX - (
|
|
132
|
+
// Always leave at least the icon visible
|
|
133
|
+
oneLine ? ICON_WIDTH_IN_PX + PADDING_IN_PX : 0);
|
|
134
|
+
setAvailableWidth(_availableWidth);
|
|
135
|
+
var canShowOverlay = !isSelected;
|
|
136
|
+
setShowOverlay(canShowOverlay);
|
|
137
|
+
} catch (_unused) {
|
|
138
|
+
// If something goes wrong, hide the overlay all together.
|
|
139
|
+
setShowOverlay(false);
|
|
140
|
+
}
|
|
141
|
+
}, [isSelected]);
|
|
142
|
+
(0, _react.useLayoutEffect)(function () {
|
|
143
|
+
// Using useLayoutEffect here.
|
|
144
|
+
// 1) We want all to be able to determine whether to display label before
|
|
145
|
+
// the overlay becomes visible.
|
|
146
|
+
// 2) We need to wait for the refs to be assigned to be able to do determine
|
|
147
|
+
// the width of the overlay.
|
|
148
|
+
if (!containerRef.current) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// This should run only once
|
|
153
|
+
if (!maxOverlayWidth.current) {
|
|
154
|
+
var iconAndLabel = (0, _utils2.getChildElement)(containerRef, ".".concat(ICON_AND_LABEL_CLASSNAME));
|
|
155
|
+
var _label = (0, _utils2.getChildElement)(containerRef, ".".concat(OVERLAY_LABEL_CLASSNAME));
|
|
156
|
+
if (iconAndLabel && _label) {
|
|
157
|
+
// Set overlay max (label + icon) and min (icon only) width.
|
|
158
|
+
var _getOverlayWidths = (0, _utils2.getOverlayWidths)(iconAndLabel, _label),
|
|
159
|
+
max = _getOverlayWidths.max,
|
|
160
|
+
min = _getOverlayWidths.min;
|
|
161
|
+
maxOverlayWidth.current = max;
|
|
162
|
+
minOverlayWidth.current = min;
|
|
163
|
+
iconSize.current = (0, _utils2.getIconSize)(_label);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (isVisible) {
|
|
167
|
+
setVisibility();
|
|
168
|
+
}
|
|
169
|
+
}, [setVisibility, isVisible]);
|
|
170
|
+
(0, _react.useEffect)(function () {
|
|
171
|
+
var _containerRef$current;
|
|
172
|
+
// Find the closest block parent to observe size change
|
|
173
|
+
var parent = containerRef === null || containerRef === void 0 || (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.closest(TEXT_NODE_SELECTOR);
|
|
174
|
+
if (!parent) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
var updateOverlay = (0, _debounce.default)(function (entries) {
|
|
178
|
+
var _entries$;
|
|
179
|
+
if (!isVisible) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
var size = entries === null || entries === void 0 || (_entries$ = entries[0]) === null || _entries$ === void 0 || (_entries$ = _entries$.contentBoxSize) === null || _entries$ === void 0 || (_entries$ = _entries$[0]) === null || _entries$ === void 0 ? void 0 : _entries$.inlineSize;
|
|
183
|
+
if (!size) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (!parentWidth.current) {
|
|
187
|
+
parentWidth.current = size;
|
|
188
|
+
}
|
|
189
|
+
if (parentWidth.current === size) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
parentWidth.current = size;
|
|
193
|
+
setVisibility();
|
|
194
|
+
}, DEBOUNCE_IN_MS);
|
|
195
|
+
var observer = new ResizeObserver(updateOverlay);
|
|
196
|
+
observer.observe(parent);
|
|
197
|
+
return function () {
|
|
198
|
+
observer.disconnect();
|
|
199
|
+
};
|
|
200
|
+
}, [isVisible, setVisibility]);
|
|
201
|
+
var intl = (0, _reactIntlNext.useIntl)();
|
|
202
|
+
var label = intl.formatMessage(_messages.cardMessages.inlineOverlay);
|
|
203
|
+
return (0, _react2.jsx)("span", (0, _extends2.default)({}, props, {
|
|
204
|
+
css: containerStyles,
|
|
205
|
+
ref: containerRef
|
|
206
|
+
}), isVisible && (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)("span", {
|
|
207
|
+
"aria-hidden": "true",
|
|
208
|
+
className: OVERLAY_MARKER_CLASSNAME
|
|
209
|
+
}, _utils.ZERO_WIDTH_JOINER), (0, _react2.jsx)("a", {
|
|
210
|
+
css: [overlayStyles, showOverlay && showOverlayStyles],
|
|
211
|
+
"data-testid": testId,
|
|
212
|
+
href: url,
|
|
213
|
+
onClick: function onClick(e) {
|
|
214
|
+
return e.preventDefault();
|
|
215
|
+
},
|
|
216
|
+
tabIndex: -1
|
|
217
|
+
}, (0, _react2.jsx)("span", {
|
|
218
|
+
css: overflowingContainerStyles
|
|
219
|
+
}, (0, _react2.jsx)("span", {
|
|
220
|
+
css: iconAndLabelStyles,
|
|
221
|
+
className: ICON_AND_LABEL_CLASSNAME
|
|
222
|
+
}, (0, _react2.jsx)("span", {
|
|
223
|
+
css: iconStyles
|
|
224
|
+
}, (0, _react2.jsx)(_preferences.default, {
|
|
225
|
+
label: label,
|
|
226
|
+
size: iconSize.current,
|
|
227
|
+
testId: "".concat(testId, "-icon")
|
|
228
|
+
})), (0, _react2.jsx)("span", {
|
|
229
|
+
css: labelStyles,
|
|
230
|
+
className: OVERLAY_LABEL_CLASSNAME,
|
|
231
|
+
"data-testid": "".concat(testId, "-label")
|
|
232
|
+
}))))), children);
|
|
233
|
+
};
|
|
234
|
+
var _default = exports.default = NarrowInlineCardOverlay;
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import { css, jsx } from '@emotion/react';
|
|
4
4
|
import { AnalyticsContext } from '@atlaskit/analytics-next';
|
|
5
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
5
6
|
import useLinkUpgradeDiscoverability from '../../common/hooks/useLinkUpgradeDiscoverability';
|
|
6
7
|
import { isLocalStorageKeyDiscovered, LOCAL_STORAGE_DISCOVERY_KEY_SMART_LINK, LOCAL_STORAGE_DISCOVERY_KEY_TOOLBAR, markLocalStorageKeyDiscovered, ONE_DAY_IN_MILLISECONDS } from '../../common/local-storage';
|
|
7
8
|
import { getResolvedAttributesFromStore } from '../../utils';
|
|
8
9
|
import InlineCardOverlay from '../InlineCardOverlay';
|
|
10
|
+
import NewInlineCardOverlay from '../NewInlineCardOverlay';
|
|
9
11
|
import { DiscoveryPulse } from '../Pulse';
|
|
10
12
|
// editor adds a standard line-height that is bigger than an inline smart link
|
|
11
13
|
// due to that the link has a bit of white space around it, which doesn't look right when there is pulse around it
|
|
@@ -66,13 +68,27 @@ export const AwarenessWrapper = ({
|
|
|
66
68
|
setIsHovered(isHovered);
|
|
67
69
|
setOverlayHoveredStyles(isHovered);
|
|
68
70
|
}, [setOverlayHoveredStyles]);
|
|
69
|
-
const cardWithOverlay = useMemo(() =>
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
const cardWithOverlay = useMemo(() => {
|
|
72
|
+
if (shouldShowLinkOverlay) {
|
|
73
|
+
if (getBooleanFF('platform.linking-platform.smart-links-in-live-pages')) {
|
|
74
|
+
return jsx(NewInlineCardOverlay, {
|
|
75
|
+
isSelected: isSelected,
|
|
76
|
+
isVisible: isResolvedViewRendered && (isInserted || isHovered || isSelected),
|
|
77
|
+
onMouseEnter: () => handleOverlayChange(true),
|
|
78
|
+
onMouseLeave: () => handleOverlayChange(false),
|
|
79
|
+
url: url
|
|
80
|
+
}, children);
|
|
81
|
+
}
|
|
82
|
+
return jsx(InlineCardOverlay, {
|
|
83
|
+
isSelected: isSelected,
|
|
84
|
+
isVisible: isResolvedViewRendered && (isInserted || isHovered || isSelected),
|
|
85
|
+
onMouseEnter: () => handleOverlayChange(true),
|
|
86
|
+
onMouseLeave: () => handleOverlayChange(false),
|
|
87
|
+
url: url
|
|
88
|
+
}, children);
|
|
89
|
+
}
|
|
90
|
+
return children;
|
|
91
|
+
}, [shouldShowLinkOverlay, isSelected, isResolvedViewRendered, isInserted, isHovered, url, children, handleOverlayChange]);
|
|
76
92
|
return useMemo(() => {
|
|
77
93
|
var _cardContext$value;
|
|
78
94
|
return jsx("span", {
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
/* eslint-disable @atlaskit/design-system/no-nested-styles */
|
|
3
|
+
/* eslint-disable @atlaskit/design-system/prefer-primitives */
|
|
4
|
+
/** @jsx jsx */
|
|
5
|
+
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
6
|
+
import { css, jsx } from '@emotion/react';
|
|
7
|
+
import debounce from 'lodash/debounce';
|
|
8
|
+
import { useIntl } from 'react-intl-next';
|
|
9
|
+
import { cardMessages as messages } from '@atlaskit/editor-common/messages';
|
|
10
|
+
import { ZERO_WIDTH_JOINER } from '@atlaskit/editor-common/utils';
|
|
11
|
+
import PreferencesIcon from '@atlaskit/icon/glyph/preferences';
|
|
12
|
+
import { B100, N0, N700 } from '@atlaskit/theme/colors';
|
|
13
|
+
import { getChildElement, getIconSize, getInlineCardAvailableWidth, getOverlayWidths, isOneLine } from '../InlineCardOverlay/utils';
|
|
14
|
+
const DEBOUNCE_IN_MS = 5;
|
|
15
|
+
const ESTIMATED_MIN_WIDTH_IN_PX = 16;
|
|
16
|
+
const PADDING_IN_PX = 4;
|
|
17
|
+
const ICON_WIDTH_IN_PX = 14;
|
|
18
|
+
const ICON_AND_LABEL_CLASSNAME = 'ak-editor-card-overlay-icon-and-label';
|
|
19
|
+
const OVERLAY_LABEL_CLASSNAME = 'ak-editor-card-overlay-label';
|
|
20
|
+
const OVERLAY_MARKER_CLASSNAME = 'ak-editor-card-overlay-marker';
|
|
21
|
+
const TEXT_NODE_SELECTOR = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].join(',');
|
|
22
|
+
const SMART_LINK_BACKGROUND_COLOR = `var(--ds-surface-raised, ${N0})`;
|
|
23
|
+
// TODO: This should be lighter to match the rest of the button
|
|
24
|
+
const SMART_LINK_ACTIVE_COLOR = `var(--ds-background-selected, ${B100})`;
|
|
25
|
+
const containerStyles = css({
|
|
26
|
+
position: 'relative',
|
|
27
|
+
lineHeight: 'normal',
|
|
28
|
+
':active': {
|
|
29
|
+
[`.${ICON_AND_LABEL_CLASSNAME}`]: {
|
|
30
|
+
background: SMART_LINK_ACTIVE_COLOR
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
const overlayStyles = css({
|
|
35
|
+
// Set default styling to be invisible but available in dom for width calculation.
|
|
36
|
+
visibility: 'hidden',
|
|
37
|
+
marginTop: "var(--ds-space-050, 4px)",
|
|
38
|
+
position: 'absolute',
|
|
39
|
+
verticalAlign: 'text-top',
|
|
40
|
+
height: '1lh',
|
|
41
|
+
'@supports not (height: 1lh)': {
|
|
42
|
+
height: '1.2em'
|
|
43
|
+
},
|
|
44
|
+
overflow: 'hidden',
|
|
45
|
+
// EDM-1717: box-shadow Safari fix bring load wrapper zIndex to 1
|
|
46
|
+
zIndex: 2,
|
|
47
|
+
pointerEvents: 'none'
|
|
48
|
+
});
|
|
49
|
+
const showOverlayStyles = css({
|
|
50
|
+
visibility: 'visible'
|
|
51
|
+
});
|
|
52
|
+
const iconStyles = css({
|
|
53
|
+
// Position icon in the middle
|
|
54
|
+
span: {
|
|
55
|
+
display: 'flex'
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
const labelStyles = css({
|
|
59
|
+
fontSize: '0.875em',
|
|
60
|
+
fontWeight: '600',
|
|
61
|
+
width: 'max-content'
|
|
62
|
+
});
|
|
63
|
+
const iconAndLabelStyles = css({
|
|
64
|
+
display: 'flex',
|
|
65
|
+
alignItems: 'center',
|
|
66
|
+
height: '100%',
|
|
67
|
+
marginLeft: "var(--ds-space-050, 4px)",
|
|
68
|
+
marginRight: "var(--ds-space-025, 2px)",
|
|
69
|
+
background: SMART_LINK_BACKGROUND_COLOR,
|
|
70
|
+
color: `var(--ds-text-subtlest, ${N700})`
|
|
71
|
+
});
|
|
72
|
+
const overflowingContainerStyles = css({
|
|
73
|
+
display: 'flex',
|
|
74
|
+
flexDirection: 'row-reverse',
|
|
75
|
+
alignItems: 'center',
|
|
76
|
+
width: 'max-content',
|
|
77
|
+
height: '100%'
|
|
78
|
+
});
|
|
79
|
+
const NarrowInlineCardOverlay = ({
|
|
80
|
+
children,
|
|
81
|
+
isSelected = false,
|
|
82
|
+
isVisible = false,
|
|
83
|
+
testId = 'inline-card-overlay',
|
|
84
|
+
url,
|
|
85
|
+
...props
|
|
86
|
+
}) => {
|
|
87
|
+
const [showOverlay, setShowOverlay] = useState(false);
|
|
88
|
+
const [availableWidth, setAvailableWidth] = useState(undefined);
|
|
89
|
+
const maxOverlayWidth = useRef(0);
|
|
90
|
+
const minOverlayWidth = useRef(ESTIMATED_MIN_WIDTH_IN_PX);
|
|
91
|
+
const parentWidth = useRef(0);
|
|
92
|
+
const iconSize = useRef('small');
|
|
93
|
+
const containerRef = useRef(null);
|
|
94
|
+
|
|
95
|
+
// TODO EDM-9843: Use availableWidth for small link edge case
|
|
96
|
+
availableWidth;
|
|
97
|
+
const setVisibility = useCallback(() => {
|
|
98
|
+
if (!containerRef.current || !maxOverlayWidth.current) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const marker = getChildElement(containerRef, `.${OVERLAY_MARKER_CLASSNAME}`);
|
|
102
|
+
if (!marker) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const oneLine = isOneLine(containerRef.current, marker);
|
|
107
|
+
|
|
108
|
+
// Get the width of the available space to display overlay.
|
|
109
|
+
// This is the width of the inline link itself. If the inline
|
|
110
|
+
// is wrapped to the next line, this is width of the last line.
|
|
111
|
+
const availableWidth = getInlineCardAvailableWidth(containerRef.current, marker) - PADDING_IN_PX - (
|
|
112
|
+
// Always leave at least the icon visible
|
|
113
|
+
oneLine ? ICON_WIDTH_IN_PX + PADDING_IN_PX : 0);
|
|
114
|
+
setAvailableWidth(availableWidth);
|
|
115
|
+
const canShowOverlay = !isSelected;
|
|
116
|
+
setShowOverlay(canShowOverlay);
|
|
117
|
+
} catch {
|
|
118
|
+
// If something goes wrong, hide the overlay all together.
|
|
119
|
+
setShowOverlay(false);
|
|
120
|
+
}
|
|
121
|
+
}, [isSelected]);
|
|
122
|
+
useLayoutEffect(() => {
|
|
123
|
+
// Using useLayoutEffect here.
|
|
124
|
+
// 1) We want all to be able to determine whether to display label before
|
|
125
|
+
// the overlay becomes visible.
|
|
126
|
+
// 2) We need to wait for the refs to be assigned to be able to do determine
|
|
127
|
+
// the width of the overlay.
|
|
128
|
+
if (!containerRef.current) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// This should run only once
|
|
133
|
+
if (!maxOverlayWidth.current) {
|
|
134
|
+
const iconAndLabel = getChildElement(containerRef, `.${ICON_AND_LABEL_CLASSNAME}`);
|
|
135
|
+
const label = getChildElement(containerRef, `.${OVERLAY_LABEL_CLASSNAME}`);
|
|
136
|
+
if (iconAndLabel && label) {
|
|
137
|
+
// Set overlay max (label + icon) and min (icon only) width.
|
|
138
|
+
const {
|
|
139
|
+
max,
|
|
140
|
+
min
|
|
141
|
+
} = getOverlayWidths(iconAndLabel, label);
|
|
142
|
+
maxOverlayWidth.current = max;
|
|
143
|
+
minOverlayWidth.current = min;
|
|
144
|
+
iconSize.current = getIconSize(label);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (isVisible) {
|
|
148
|
+
setVisibility();
|
|
149
|
+
}
|
|
150
|
+
}, [setVisibility, isVisible]);
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
var _containerRef$current;
|
|
153
|
+
// Find the closest block parent to observe size change
|
|
154
|
+
const parent = containerRef === null || containerRef === void 0 ? void 0 : (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.closest(TEXT_NODE_SELECTOR);
|
|
155
|
+
if (!parent) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const updateOverlay = debounce(entries => {
|
|
159
|
+
var _entries$, _entries$$contentBoxS, _entries$$contentBoxS2;
|
|
160
|
+
if (!isVisible) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const size = entries === null || entries === void 0 ? void 0 : (_entries$ = entries[0]) === null || _entries$ === void 0 ? void 0 : (_entries$$contentBoxS = _entries$.contentBoxSize) === null || _entries$$contentBoxS === void 0 ? void 0 : (_entries$$contentBoxS2 = _entries$$contentBoxS[0]) === null || _entries$$contentBoxS2 === void 0 ? void 0 : _entries$$contentBoxS2.inlineSize;
|
|
164
|
+
if (!size) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (!parentWidth.current) {
|
|
168
|
+
parentWidth.current = size;
|
|
169
|
+
}
|
|
170
|
+
if (parentWidth.current === size) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
parentWidth.current = size;
|
|
174
|
+
setVisibility();
|
|
175
|
+
}, DEBOUNCE_IN_MS);
|
|
176
|
+
const observer = new ResizeObserver(updateOverlay);
|
|
177
|
+
observer.observe(parent);
|
|
178
|
+
return () => {
|
|
179
|
+
observer.disconnect();
|
|
180
|
+
};
|
|
181
|
+
}, [isVisible, setVisibility]);
|
|
182
|
+
const intl = useIntl();
|
|
183
|
+
const label = intl.formatMessage(messages.inlineOverlay);
|
|
184
|
+
return jsx("span", _extends({}, props, {
|
|
185
|
+
css: containerStyles,
|
|
186
|
+
ref: containerRef
|
|
187
|
+
}), isVisible && jsx(React.Fragment, null, jsx("span", {
|
|
188
|
+
"aria-hidden": "true",
|
|
189
|
+
className: OVERLAY_MARKER_CLASSNAME
|
|
190
|
+
}, ZERO_WIDTH_JOINER), jsx("a", {
|
|
191
|
+
css: [overlayStyles, showOverlay && showOverlayStyles],
|
|
192
|
+
"data-testid": testId,
|
|
193
|
+
href: url,
|
|
194
|
+
onClick: e => e.preventDefault(),
|
|
195
|
+
tabIndex: -1
|
|
196
|
+
}, jsx("span", {
|
|
197
|
+
css: overflowingContainerStyles
|
|
198
|
+
}, jsx("span", {
|
|
199
|
+
css: iconAndLabelStyles,
|
|
200
|
+
className: ICON_AND_LABEL_CLASSNAME
|
|
201
|
+
}, jsx("span", {
|
|
202
|
+
css: iconStyles
|
|
203
|
+
}, jsx(PreferencesIcon, {
|
|
204
|
+
label: label,
|
|
205
|
+
size: iconSize.current,
|
|
206
|
+
testId: `${testId}-icon`
|
|
207
|
+
})), jsx("span", {
|
|
208
|
+
css: labelStyles,
|
|
209
|
+
className: OVERLAY_LABEL_CLASSNAME,
|
|
210
|
+
"data-testid": `${testId}-label`
|
|
211
|
+
}))))), children);
|
|
212
|
+
};
|
|
213
|
+
export default NarrowInlineCardOverlay;
|
|
@@ -3,10 +3,12 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
|
3
3
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
4
4
|
import { css, jsx } from '@emotion/react';
|
|
5
5
|
import { AnalyticsContext } from '@atlaskit/analytics-next';
|
|
6
|
+
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
6
7
|
import useLinkUpgradeDiscoverability from '../../common/hooks/useLinkUpgradeDiscoverability';
|
|
7
8
|
import { isLocalStorageKeyDiscovered, LOCAL_STORAGE_DISCOVERY_KEY_SMART_LINK, LOCAL_STORAGE_DISCOVERY_KEY_TOOLBAR, markLocalStorageKeyDiscovered, ONE_DAY_IN_MILLISECONDS } from '../../common/local-storage';
|
|
8
9
|
import { getResolvedAttributesFromStore } from '../../utils';
|
|
9
10
|
import InlineCardOverlay from '../InlineCardOverlay';
|
|
11
|
+
import NewInlineCardOverlay from '../NewInlineCardOverlay';
|
|
10
12
|
import { DiscoveryPulse } from '../Pulse';
|
|
11
13
|
// editor adds a standard line-height that is bigger than an inline smart link
|
|
12
14
|
// due to that the link has a bit of white space around it, which doesn't look right when there is pulse around it
|
|
@@ -69,17 +71,33 @@ export var AwarenessWrapper = function AwarenessWrapper(_ref) {
|
|
|
69
71
|
setOverlayHoveredStyles(isHovered);
|
|
70
72
|
}, [setOverlayHoveredStyles]);
|
|
71
73
|
var cardWithOverlay = useMemo(function () {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
74
|
+
if (shouldShowLinkOverlay) {
|
|
75
|
+
if (getBooleanFF('platform.linking-platform.smart-links-in-live-pages')) {
|
|
76
|
+
return jsx(NewInlineCardOverlay, {
|
|
77
|
+
isSelected: isSelected,
|
|
78
|
+
isVisible: isResolvedViewRendered && (isInserted || isHovered || isSelected),
|
|
79
|
+
onMouseEnter: function onMouseEnter() {
|
|
80
|
+
return handleOverlayChange(true);
|
|
81
|
+
},
|
|
82
|
+
onMouseLeave: function onMouseLeave() {
|
|
83
|
+
return handleOverlayChange(false);
|
|
84
|
+
},
|
|
85
|
+
url: url
|
|
86
|
+
}, children);
|
|
87
|
+
}
|
|
88
|
+
return jsx(InlineCardOverlay, {
|
|
89
|
+
isSelected: isSelected,
|
|
90
|
+
isVisible: isResolvedViewRendered && (isInserted || isHovered || isSelected),
|
|
91
|
+
onMouseEnter: function onMouseEnter() {
|
|
92
|
+
return handleOverlayChange(true);
|
|
93
|
+
},
|
|
94
|
+
onMouseLeave: function onMouseLeave() {
|
|
95
|
+
return handleOverlayChange(false);
|
|
96
|
+
},
|
|
97
|
+
url: url
|
|
98
|
+
}, children);
|
|
99
|
+
}
|
|
100
|
+
return children;
|
|
83
101
|
}, [shouldShowLinkOverlay, isSelected, isResolvedViewRendered, isInserted, isHovered, url, children, handleOverlayChange]);
|
|
84
102
|
return useMemo(function () {
|
|
85
103
|
var _cardContext$value;
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
|
|
4
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
5
|
+
var _excluded = ["children", "isSelected", "isVisible", "testId", "url"];
|
|
6
|
+
/* eslint-disable @atlaskit/design-system/no-nested-styles */
|
|
7
|
+
/* eslint-disable @atlaskit/design-system/prefer-primitives */
|
|
8
|
+
/** @jsx jsx */
|
|
9
|
+
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
10
|
+
import { css, jsx } from '@emotion/react';
|
|
11
|
+
import debounce from 'lodash/debounce';
|
|
12
|
+
import { useIntl } from 'react-intl-next';
|
|
13
|
+
import { cardMessages as messages } from '@atlaskit/editor-common/messages';
|
|
14
|
+
import { ZERO_WIDTH_JOINER } from '@atlaskit/editor-common/utils';
|
|
15
|
+
import PreferencesIcon from '@atlaskit/icon/glyph/preferences';
|
|
16
|
+
import { B100, N0, N700 } from '@atlaskit/theme/colors';
|
|
17
|
+
import { getChildElement, getIconSize, getInlineCardAvailableWidth, getOverlayWidths, isOneLine } from '../InlineCardOverlay/utils';
|
|
18
|
+
var DEBOUNCE_IN_MS = 5;
|
|
19
|
+
var ESTIMATED_MIN_WIDTH_IN_PX = 16;
|
|
20
|
+
var PADDING_IN_PX = 4;
|
|
21
|
+
var ICON_WIDTH_IN_PX = 14;
|
|
22
|
+
var ICON_AND_LABEL_CLASSNAME = 'ak-editor-card-overlay-icon-and-label';
|
|
23
|
+
var OVERLAY_LABEL_CLASSNAME = 'ak-editor-card-overlay-label';
|
|
24
|
+
var OVERLAY_MARKER_CLASSNAME = 'ak-editor-card-overlay-marker';
|
|
25
|
+
var TEXT_NODE_SELECTOR = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].join(',');
|
|
26
|
+
var SMART_LINK_BACKGROUND_COLOR = "var(--ds-surface-raised, ".concat(N0, ")");
|
|
27
|
+
// TODO: This should be lighter to match the rest of the button
|
|
28
|
+
var SMART_LINK_ACTIVE_COLOR = "var(--ds-background-selected, ".concat(B100, ")");
|
|
29
|
+
var containerStyles = css({
|
|
30
|
+
position: 'relative',
|
|
31
|
+
lineHeight: 'normal',
|
|
32
|
+
':active': _defineProperty({}, ".".concat(ICON_AND_LABEL_CLASSNAME), {
|
|
33
|
+
background: SMART_LINK_ACTIVE_COLOR
|
|
34
|
+
})
|
|
35
|
+
});
|
|
36
|
+
var overlayStyles = css({
|
|
37
|
+
// Set default styling to be invisible but available in dom for width calculation.
|
|
38
|
+
visibility: 'hidden',
|
|
39
|
+
marginTop: "var(--ds-space-050, 4px)",
|
|
40
|
+
position: 'absolute',
|
|
41
|
+
verticalAlign: 'text-top',
|
|
42
|
+
height: '1lh',
|
|
43
|
+
'@supports not (height: 1lh)': {
|
|
44
|
+
height: '1.2em'
|
|
45
|
+
},
|
|
46
|
+
overflow: 'hidden',
|
|
47
|
+
// EDM-1717: box-shadow Safari fix bring load wrapper zIndex to 1
|
|
48
|
+
zIndex: 2,
|
|
49
|
+
pointerEvents: 'none'
|
|
50
|
+
});
|
|
51
|
+
var showOverlayStyles = css({
|
|
52
|
+
visibility: 'visible'
|
|
53
|
+
});
|
|
54
|
+
var iconStyles = css({
|
|
55
|
+
// Position icon in the middle
|
|
56
|
+
span: {
|
|
57
|
+
display: 'flex'
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
var labelStyles = css({
|
|
61
|
+
fontSize: '0.875em',
|
|
62
|
+
fontWeight: '600',
|
|
63
|
+
width: 'max-content'
|
|
64
|
+
});
|
|
65
|
+
var iconAndLabelStyles = css({
|
|
66
|
+
display: 'flex',
|
|
67
|
+
alignItems: 'center',
|
|
68
|
+
height: '100%',
|
|
69
|
+
marginLeft: "var(--ds-space-050, 4px)",
|
|
70
|
+
marginRight: "var(--ds-space-025, 2px)",
|
|
71
|
+
background: SMART_LINK_BACKGROUND_COLOR,
|
|
72
|
+
color: "var(--ds-text-subtlest, ".concat(N700, ")")
|
|
73
|
+
});
|
|
74
|
+
var overflowingContainerStyles = css({
|
|
75
|
+
display: 'flex',
|
|
76
|
+
flexDirection: 'row-reverse',
|
|
77
|
+
alignItems: 'center',
|
|
78
|
+
width: 'max-content',
|
|
79
|
+
height: '100%'
|
|
80
|
+
});
|
|
81
|
+
var NarrowInlineCardOverlay = function NarrowInlineCardOverlay(_ref) {
|
|
82
|
+
var children = _ref.children,
|
|
83
|
+
_ref$isSelected = _ref.isSelected,
|
|
84
|
+
isSelected = _ref$isSelected === void 0 ? false : _ref$isSelected,
|
|
85
|
+
_ref$isVisible = _ref.isVisible,
|
|
86
|
+
isVisible = _ref$isVisible === void 0 ? false : _ref$isVisible,
|
|
87
|
+
_ref$testId = _ref.testId,
|
|
88
|
+
testId = _ref$testId === void 0 ? 'inline-card-overlay' : _ref$testId,
|
|
89
|
+
url = _ref.url,
|
|
90
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
91
|
+
var _useState = useState(false),
|
|
92
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
93
|
+
showOverlay = _useState2[0],
|
|
94
|
+
setShowOverlay = _useState2[1];
|
|
95
|
+
var _useState3 = useState(undefined),
|
|
96
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
97
|
+
availableWidth = _useState4[0],
|
|
98
|
+
setAvailableWidth = _useState4[1];
|
|
99
|
+
var maxOverlayWidth = useRef(0);
|
|
100
|
+
var minOverlayWidth = useRef(ESTIMATED_MIN_WIDTH_IN_PX);
|
|
101
|
+
var parentWidth = useRef(0);
|
|
102
|
+
var iconSize = useRef('small');
|
|
103
|
+
var containerRef = useRef(null);
|
|
104
|
+
|
|
105
|
+
// TODO EDM-9843: Use availableWidth for small link edge case
|
|
106
|
+
availableWidth;
|
|
107
|
+
var setVisibility = useCallback(function () {
|
|
108
|
+
if (!containerRef.current || !maxOverlayWidth.current) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
var marker = getChildElement(containerRef, ".".concat(OVERLAY_MARKER_CLASSNAME));
|
|
112
|
+
if (!marker) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
var oneLine = isOneLine(containerRef.current, marker);
|
|
117
|
+
|
|
118
|
+
// Get the width of the available space to display overlay.
|
|
119
|
+
// This is the width of the inline link itself. If the inline
|
|
120
|
+
// is wrapped to the next line, this is width of the last line.
|
|
121
|
+
var _availableWidth = getInlineCardAvailableWidth(containerRef.current, marker) - PADDING_IN_PX - (
|
|
122
|
+
// Always leave at least the icon visible
|
|
123
|
+
oneLine ? ICON_WIDTH_IN_PX + PADDING_IN_PX : 0);
|
|
124
|
+
setAvailableWidth(_availableWidth);
|
|
125
|
+
var canShowOverlay = !isSelected;
|
|
126
|
+
setShowOverlay(canShowOverlay);
|
|
127
|
+
} catch (_unused) {
|
|
128
|
+
// If something goes wrong, hide the overlay all together.
|
|
129
|
+
setShowOverlay(false);
|
|
130
|
+
}
|
|
131
|
+
}, [isSelected]);
|
|
132
|
+
useLayoutEffect(function () {
|
|
133
|
+
// Using useLayoutEffect here.
|
|
134
|
+
// 1) We want all to be able to determine whether to display label before
|
|
135
|
+
// the overlay becomes visible.
|
|
136
|
+
// 2) We need to wait for the refs to be assigned to be able to do determine
|
|
137
|
+
// the width of the overlay.
|
|
138
|
+
if (!containerRef.current) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// This should run only once
|
|
143
|
+
if (!maxOverlayWidth.current) {
|
|
144
|
+
var iconAndLabel = getChildElement(containerRef, ".".concat(ICON_AND_LABEL_CLASSNAME));
|
|
145
|
+
var _label = getChildElement(containerRef, ".".concat(OVERLAY_LABEL_CLASSNAME));
|
|
146
|
+
if (iconAndLabel && _label) {
|
|
147
|
+
// Set overlay max (label + icon) and min (icon only) width.
|
|
148
|
+
var _getOverlayWidths = getOverlayWidths(iconAndLabel, _label),
|
|
149
|
+
max = _getOverlayWidths.max,
|
|
150
|
+
min = _getOverlayWidths.min;
|
|
151
|
+
maxOverlayWidth.current = max;
|
|
152
|
+
minOverlayWidth.current = min;
|
|
153
|
+
iconSize.current = getIconSize(_label);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (isVisible) {
|
|
157
|
+
setVisibility();
|
|
158
|
+
}
|
|
159
|
+
}, [setVisibility, isVisible]);
|
|
160
|
+
useEffect(function () {
|
|
161
|
+
var _containerRef$current;
|
|
162
|
+
// Find the closest block parent to observe size change
|
|
163
|
+
var parent = containerRef === null || containerRef === void 0 || (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.closest(TEXT_NODE_SELECTOR);
|
|
164
|
+
if (!parent) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
var updateOverlay = debounce(function (entries) {
|
|
168
|
+
var _entries$;
|
|
169
|
+
if (!isVisible) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
var size = entries === null || entries === void 0 || (_entries$ = entries[0]) === null || _entries$ === void 0 || (_entries$ = _entries$.contentBoxSize) === null || _entries$ === void 0 || (_entries$ = _entries$[0]) === null || _entries$ === void 0 ? void 0 : _entries$.inlineSize;
|
|
173
|
+
if (!size) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (!parentWidth.current) {
|
|
177
|
+
parentWidth.current = size;
|
|
178
|
+
}
|
|
179
|
+
if (parentWidth.current === size) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
parentWidth.current = size;
|
|
183
|
+
setVisibility();
|
|
184
|
+
}, DEBOUNCE_IN_MS);
|
|
185
|
+
var observer = new ResizeObserver(updateOverlay);
|
|
186
|
+
observer.observe(parent);
|
|
187
|
+
return function () {
|
|
188
|
+
observer.disconnect();
|
|
189
|
+
};
|
|
190
|
+
}, [isVisible, setVisibility]);
|
|
191
|
+
var intl = useIntl();
|
|
192
|
+
var label = intl.formatMessage(messages.inlineOverlay);
|
|
193
|
+
return jsx("span", _extends({}, props, {
|
|
194
|
+
css: containerStyles,
|
|
195
|
+
ref: containerRef
|
|
196
|
+
}), isVisible && jsx(React.Fragment, null, jsx("span", {
|
|
197
|
+
"aria-hidden": "true",
|
|
198
|
+
className: OVERLAY_MARKER_CLASSNAME
|
|
199
|
+
}, ZERO_WIDTH_JOINER), jsx("a", {
|
|
200
|
+
css: [overlayStyles, showOverlay && showOverlayStyles],
|
|
201
|
+
"data-testid": testId,
|
|
202
|
+
href: url,
|
|
203
|
+
onClick: function onClick(e) {
|
|
204
|
+
return e.preventDefault();
|
|
205
|
+
},
|
|
206
|
+
tabIndex: -1
|
|
207
|
+
}, jsx("span", {
|
|
208
|
+
css: overflowingContainerStyles
|
|
209
|
+
}, jsx("span", {
|
|
210
|
+
css: iconAndLabelStyles,
|
|
211
|
+
className: ICON_AND_LABEL_CLASSNAME
|
|
212
|
+
}, jsx("span", {
|
|
213
|
+
css: iconStyles
|
|
214
|
+
}, jsx(PreferencesIcon, {
|
|
215
|
+
label: label,
|
|
216
|
+
size: iconSize.current,
|
|
217
|
+
testId: "".concat(testId, "-icon")
|
|
218
|
+
})), jsx("span", {
|
|
219
|
+
css: labelStyles,
|
|
220
|
+
className: OVERLAY_LABEL_CLASSNAME,
|
|
221
|
+
"data-testid": "".concat(testId, "-label")
|
|
222
|
+
}))))), children);
|
|
223
|
+
};
|
|
224
|
+
export default NarrowInlineCardOverlay;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { jsx } from '@emotion/react';
|
|
4
|
+
import type { InlineCardOverlayProps } from '../InlineCardOverlay/types';
|
|
5
|
+
declare const NarrowInlineCardOverlay: ({ children, isSelected, isVisible, testId, url, ...props }: React.PropsWithChildren<InlineCardOverlayProps>) => jsx.JSX.Element;
|
|
6
|
+
export default NarrowInlineCardOverlay;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { jsx } from '@emotion/react';
|
|
4
|
+
import type { InlineCardOverlayProps } from '../InlineCardOverlay/types';
|
|
5
|
+
declare const NarrowInlineCardOverlay: ({ children, isSelected, isVisible, testId, url, ...props }: React.PropsWithChildren<InlineCardOverlayProps>) => jsx.JSX.Element;
|
|
6
|
+
export default NarrowInlineCardOverlay;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-card",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "Card plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
".": "./src/index.ts"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@atlaskit/adf-schema": "^36.
|
|
35
|
+
"@atlaskit/adf-schema": "^36.8.0",
|
|
36
36
|
"@atlaskit/analytics-next": "^9.3.0",
|
|
37
37
|
"@atlaskit/custom-steps": "^0.2.0",
|
|
38
|
-
"@atlaskit/editor-common": "^80.
|
|
38
|
+
"@atlaskit/editor-common": "^80.4.0",
|
|
39
39
|
"@atlaskit/editor-plugin-analytics": "^1.2.0",
|
|
40
40
|
"@atlaskit/editor-plugin-decorations": "^1.1.0",
|
|
41
41
|
"@atlaskit/editor-plugin-editor-viewmode": "^1.1.0",
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"@atlaskit/icon": "^22.2.0",
|
|
51
51
|
"@atlaskit/link-analytics": "^8.3.0",
|
|
52
52
|
"@atlaskit/link-client-extension": "^1.8.0",
|
|
53
|
-
"@atlaskit/link-datasource": "^2.
|
|
53
|
+
"@atlaskit/link-datasource": "^2.3.0",
|
|
54
54
|
"@atlaskit/linking-common": "^5.6.0",
|
|
55
55
|
"@atlaskit/linking-types": "^8.8.0",
|
|
56
56
|
"@atlaskit/platform-feature-flags": "^0.2.0",
|
|
57
57
|
"@atlaskit/primitives": "^6.2.0",
|
|
58
|
-
"@atlaskit/smart-card": "^26.
|
|
58
|
+
"@atlaskit/smart-card": "^26.69.0",
|
|
59
59
|
"@atlaskit/theme": "^12.8.0",
|
|
60
60
|
"@atlaskit/tokens": "^1.48.0",
|
|
61
61
|
"@babel/runtime": "^7.0.0",
|
|
@@ -105,6 +105,9 @@
|
|
|
105
105
|
},
|
|
106
106
|
"prettier": "@atlassian/atlassian-frontend-prettier-config-1.0.0",
|
|
107
107
|
"platform-feature-flags": {
|
|
108
|
+
"platform.linking-platform.smart-links-in-live-pages": {
|
|
109
|
+
"type": "boolean"
|
|
110
|
+
},
|
|
108
111
|
"platform.linking-platform.datasource-word_wrap": {
|
|
109
112
|
"type": "boolean"
|
|
110
113
|
},
|