@atlaskit/editor-plugin-card 0.10.10 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/cjs/common/pulse/index.js +6 -14
- package/dist/cjs/messages.js +5 -0
- package/dist/cjs/nodeviews/inlineCardWithAwareness.js +20 -2
- package/dist/cjs/toolbar.js +5 -9
- package/dist/cjs/ui/InlineCardOverlay/index.js +187 -0
- package/dist/cjs/ui/InlineCardOverlay/types.js +5 -0
- package/dist/cjs/ui/LinkToolbarAppearance.js +19 -3
- package/dist/es2019/common/pulse/index.js +8 -14
- package/dist/es2019/messages.js +5 -0
- package/dist/es2019/nodeviews/inlineCardWithAwareness.js +13 -3
- package/dist/es2019/toolbar.js +3 -7
- package/dist/es2019/ui/InlineCardOverlay/index.js +175 -0
- package/dist/es2019/ui/InlineCardOverlay/types.js +1 -0
- package/dist/es2019/ui/LinkToolbarAppearance.js +18 -3
- package/dist/esm/common/pulse/index.js +8 -16
- package/dist/esm/messages.js +5 -0
- package/dist/esm/nodeviews/inlineCardWithAwareness.js +21 -3
- package/dist/esm/toolbar.js +4 -8
- package/dist/esm/ui/InlineCardOverlay/index.js +179 -0
- package/dist/esm/ui/InlineCardOverlay/types.js +1 -0
- package/dist/esm/ui/LinkToolbarAppearance.js +19 -3
- package/dist/types/common/pulse/index.d.ts +1 -5
- package/dist/types/messages.d.ts +5 -0
- package/dist/types/toolbar.d.ts +1 -0
- package/dist/types/ui/InlineCardOverlay/index.d.ts +5 -0
- package/dist/types/ui/InlineCardOverlay/types.d.ts +6 -0
- package/dist/types/ui/LinkToolbarAppearance.d.ts +9 -8
- package/dist/types-ts4.5/common/pulse/index.d.ts +1 -5
- package/dist/types-ts4.5/messages.d.ts +5 -0
- package/dist/types-ts4.5/toolbar.d.ts +1 -0
- package/dist/types-ts4.5/ui/InlineCardOverlay/index.d.ts +5 -0
- package/dist/types-ts4.5/ui/InlineCardOverlay/types.d.ts +6 -0
- package/dist/types-ts4.5/ui/LinkToolbarAppearance.d.ts +9 -8
- package/package.json +4 -4
|
@@ -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 {};
|
|
@@ -6,12 +6,14 @@ import { commandWithMetadata, getButtonGroupOption, LinkToolbarButtonGroup } fro
|
|
|
6
6
|
import nodeNames, { cardMessages as messages } from '@atlaskit/editor-common/messages';
|
|
7
7
|
import { isSupportedInParent } from '@atlaskit/editor-common/utils';
|
|
8
8
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
9
|
+
import { DiscoveryPulse } from '../common/pulse';
|
|
10
|
+
import { shouldRenderToolbarPulse } from '../toolbar';
|
|
9
11
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
10
12
|
export class LinkToolbarAppearance extends React.Component {
|
|
11
13
|
constructor(...args) {
|
|
12
14
|
super(...args);
|
|
13
15
|
_defineProperty(this, "renderDropdown", (view, cardContext) => {
|
|
14
|
-
var _cardActions$setSelec, _cardActions$setSelec2, _cardActions$changeSe, _cardActions$setSelec3;
|
|
16
|
+
var _cardActions$setSelec, _cardActions$setSelec2, _cardActions$changeSe, _cardActions$setSelec3, _cardContext$store2, _cardContext$store2$g;
|
|
15
17
|
const {
|
|
16
18
|
url,
|
|
17
19
|
intl,
|
|
@@ -21,7 +23,8 @@ export class LinkToolbarAppearance extends React.Component {
|
|
|
21
23
|
allowBlockCards = true,
|
|
22
24
|
platform,
|
|
23
25
|
editorAnalyticsApi,
|
|
24
|
-
cardActions
|
|
26
|
+
cardActions,
|
|
27
|
+
showInlineUpgradeDiscoverability = false
|
|
25
28
|
} = this.props;
|
|
26
29
|
const preview = allowEmbeds && cardContext && url && cardContext.extractors.getPreview(url, platform);
|
|
27
30
|
const defaultCommand = () => false;
|
|
@@ -80,7 +83,7 @@ export class LinkToolbarAppearance extends React.Component {
|
|
|
80
83
|
if (embedOption) {
|
|
81
84
|
options.push(embedOption);
|
|
82
85
|
}
|
|
83
|
-
|
|
86
|
+
const LinkToolbarButtons = /*#__PURE__*/React.createElement(LinkToolbarButtonGroup, {
|
|
84
87
|
key: "link-toolbar-button-group",
|
|
85
88
|
options: options.map(option => getButtonGroupOption(intl, dispatchCommand, {
|
|
86
89
|
...option,
|
|
@@ -89,6 +92,18 @@ export class LinkToolbarAppearance extends React.Component {
|
|
|
89
92
|
})
|
|
90
93
|
}))
|
|
91
94
|
});
|
|
95
|
+
const status = url ? cardContext === null || cardContext === void 0 ? void 0 : (_cardContext$store2 = cardContext.store) === null || _cardContext$store2 === void 0 ? void 0 : (_cardContext$store2$g = _cardContext$store2.getState()[url]) === null || _cardContext$store2$g === void 0 ? void 0 : _cardContext$store2$g.status : '';
|
|
96
|
+
const embedEnabled = embedOption ? !embedOption.disabled : false;
|
|
97
|
+
if (shouldRenderToolbarPulse(embedEnabled, currentAppearance !== null && currentAppearance !== void 0 ? currentAppearance : '', status !== null && status !== void 0 ? status : '', showInlineUpgradeDiscoverability)) {
|
|
98
|
+
return (
|
|
99
|
+
/*#__PURE__*/
|
|
100
|
+
// This div is necessary because the toolbar uses :first-child to add margins and can't add margins to the pulse element
|
|
101
|
+
React.createElement("div", null, /*#__PURE__*/React.createElement(DiscoveryPulse, {
|
|
102
|
+
localStorageKey: "toolbar-upgrade-pulse"
|
|
103
|
+
}, LinkToolbarButtons))
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
return LinkToolbarButtons;
|
|
92
107
|
});
|
|
93
108
|
}
|
|
94
109
|
render() {
|
|
@@ -1,28 +1,20 @@
|
|
|
1
|
-
import React, { useCallback
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
2
|
import { Pulse } from '@atlaskit/linking-common';
|
|
3
|
-
import { markLocalStorageKeyDiscovered } from '../local-storage';
|
|
3
|
+
import { isLocalStorageKeyDiscovered, markLocalStorageKeyDiscovered } from '../local-storage';
|
|
4
4
|
export var DiscoveryPulse = function DiscoveryPulse(_ref) {
|
|
5
5
|
var children = _ref.children,
|
|
6
6
|
localStorageKey = _ref.localStorageKey,
|
|
7
7
|
isDiscovered = _ref.isDiscovered,
|
|
8
|
-
timeToDiscoverInMs = _ref.timeToDiscoverInMs,
|
|
9
8
|
localStorageKeyExpirationInMs = _ref.localStorageKeyExpirationInMs;
|
|
9
|
+
var discovered = isDiscovered || isLocalStorageKeyDiscovered(localStorageKey);
|
|
10
10
|
var onDiscovery = useCallback(function () {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
useEffect(function () {
|
|
14
|
-
if (timeToDiscoverInMs) {
|
|
15
|
-
var timeoutUntilDiscovery = setTimeout(function () {
|
|
16
|
-
onDiscovery();
|
|
17
|
-
}, timeToDiscoverInMs);
|
|
18
|
-
return function () {
|
|
19
|
-
return clearTimeout(timeoutUntilDiscovery);
|
|
20
|
-
};
|
|
11
|
+
if (!discovered) {
|
|
12
|
+
markLocalStorageKeyDiscovered(localStorageKey, localStorageKeyExpirationInMs);
|
|
21
13
|
}
|
|
22
|
-
|
|
23
|
-
}, [isDiscovered, localStorageKey, onDiscovery, timeToDiscoverInMs]);
|
|
14
|
+
}, [discovered, localStorageKey, localStorageKeyExpirationInMs]);
|
|
24
15
|
return /*#__PURE__*/React.createElement(Pulse, {
|
|
25
|
-
|
|
16
|
+
onAnimationIteration: onDiscovery,
|
|
17
|
+
isDiscovered: discovered
|
|
26
18
|
}, children);
|
|
27
19
|
};
|
|
28
20
|
export default Pulse;
|
package/dist/esm/messages.js
CHANGED
|
@@ -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
|
|
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, {
|
package/dist/esm/toolbar.js
CHANGED
|
@@ -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
|
};
|
|
@@ -397,4 +390,7 @@ var getDatasourceButtonGroup = function getDatasourceButtonGroup(metadata, intl,
|
|
|
397
390
|
onClick: withToolbarMetadata(removeCard(editorAnalyticsApi))
|
|
398
391
|
});
|
|
399
392
|
return toolbarItems;
|
|
393
|
+
};
|
|
394
|
+
export var shouldRenderToolbarPulse = function shouldRenderToolbarPulse(embedEnabled, appearance, status, isDiscoverabilityEnabled) {
|
|
395
|
+
return embedEnabled && appearance === 'inline' && status === 'resolved' && isDiscoverabilityEnabled && getBooleanFF('platform.linking-platform.smart-card.inline-switcher');
|
|
400
396
|
};
|
|
@@ -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 {};
|
|
@@ -16,6 +16,8 @@ import { commandWithMetadata, getButtonGroupOption, LinkToolbarButtonGroup } fro
|
|
|
16
16
|
import nodeNames, { cardMessages as messages } from '@atlaskit/editor-common/messages';
|
|
17
17
|
import { isSupportedInParent } from '@atlaskit/editor-common/utils';
|
|
18
18
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
19
|
+
import { DiscoveryPulse } from '../common/pulse';
|
|
20
|
+
import { shouldRenderToolbarPulse } from '../toolbar';
|
|
19
21
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
20
22
|
export var LinkToolbarAppearance = /*#__PURE__*/function (_React$Component) {
|
|
21
23
|
_inherits(LinkToolbarAppearance, _React$Component);
|
|
@@ -28,7 +30,7 @@ export var LinkToolbarAppearance = /*#__PURE__*/function (_React$Component) {
|
|
|
28
30
|
}
|
|
29
31
|
_this = _super.call.apply(_super, [this].concat(args));
|
|
30
32
|
_defineProperty(_assertThisInitialized(_this), "renderDropdown", function (view, cardContext) {
|
|
31
|
-
var _cardActions$setSelec, _cardActions$setSelec2, _cardActions$changeSe, _cardActions$setSelec3;
|
|
33
|
+
var _cardActions$setSelec, _cardActions$setSelec2, _cardActions$changeSe, _cardActions$setSelec3, _cardContext$store2;
|
|
32
34
|
var _this$props = _this.props,
|
|
33
35
|
url = _this$props.url,
|
|
34
36
|
intl = _this$props.intl,
|
|
@@ -39,7 +41,9 @@ export var LinkToolbarAppearance = /*#__PURE__*/function (_React$Component) {
|
|
|
39
41
|
allowBlockCards = _this$props$allowBloc === void 0 ? true : _this$props$allowBloc,
|
|
40
42
|
platform = _this$props.platform,
|
|
41
43
|
editorAnalyticsApi = _this$props.editorAnalyticsApi,
|
|
42
|
-
cardActions = _this$props.cardActions
|
|
44
|
+
cardActions = _this$props.cardActions,
|
|
45
|
+
_this$props$showInlin = _this$props.showInlineUpgradeDiscoverability,
|
|
46
|
+
showInlineUpgradeDiscoverability = _this$props$showInlin === void 0 ? false : _this$props$showInlin;
|
|
43
47
|
var preview = allowEmbeds && cardContext && url && cardContext.extractors.getPreview(url, platform);
|
|
44
48
|
var defaultCommand = function defaultCommand() {
|
|
45
49
|
return false;
|
|
@@ -99,7 +103,7 @@ export var LinkToolbarAppearance = /*#__PURE__*/function (_React$Component) {
|
|
|
99
103
|
if (embedOption) {
|
|
100
104
|
options.push(embedOption);
|
|
101
105
|
}
|
|
102
|
-
|
|
106
|
+
var LinkToolbarButtons = /*#__PURE__*/React.createElement(LinkToolbarButtonGroup, {
|
|
103
107
|
key: "link-toolbar-button-group",
|
|
104
108
|
options: options.map(function (option) {
|
|
105
109
|
return getButtonGroupOption(intl, dispatchCommand, _objectSpread(_objectSpread({}, option), {}, {
|
|
@@ -109,6 +113,18 @@ export var LinkToolbarAppearance = /*#__PURE__*/function (_React$Component) {
|
|
|
109
113
|
}));
|
|
110
114
|
})
|
|
111
115
|
});
|
|
116
|
+
var status = url ? cardContext === null || cardContext === void 0 || (_cardContext$store2 = cardContext.store) === null || _cardContext$store2 === void 0 || (_cardContext$store2 = _cardContext$store2.getState()[url]) === null || _cardContext$store2 === void 0 ? void 0 : _cardContext$store2.status : '';
|
|
117
|
+
var embedEnabled = embedOption ? !embedOption.disabled : false;
|
|
118
|
+
if (shouldRenderToolbarPulse(embedEnabled, currentAppearance !== null && currentAppearance !== void 0 ? currentAppearance : '', status !== null && status !== void 0 ? status : '', showInlineUpgradeDiscoverability)) {
|
|
119
|
+
return (
|
|
120
|
+
/*#__PURE__*/
|
|
121
|
+
// This div is necessary because the toolbar uses :first-child to add margins and can't add margins to the pulse element
|
|
122
|
+
React.createElement("div", null, /*#__PURE__*/React.createElement(DiscoveryPulse, {
|
|
123
|
+
localStorageKey: "toolbar-upgrade-pulse"
|
|
124
|
+
}, LinkToolbarButtons))
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
return LinkToolbarButtons;
|
|
112
128
|
});
|
|
113
129
|
return _this;
|
|
114
130
|
}
|
|
@@ -13,14 +13,10 @@ export interface PulseProps {
|
|
|
13
13
|
* The time in ms after which the key in local storage will be considered expired and the Pulse will be shown again
|
|
14
14
|
*/
|
|
15
15
|
localStorageKeyExpirationInMs?: number;
|
|
16
|
-
/**
|
|
17
|
-
* The time in ms since the Pulse has started after which the key will be stored in local storage.
|
|
18
|
-
*/
|
|
19
|
-
timeToDiscoverInMs?: number;
|
|
20
16
|
/**
|
|
21
17
|
* And indicator that the feature was discovered externally and the pulsation needs to stop.
|
|
22
18
|
*/
|
|
23
19
|
isDiscovered?: boolean;
|
|
24
20
|
}
|
|
25
|
-
export declare const DiscoveryPulse: ({ children, localStorageKey, isDiscovered,
|
|
21
|
+
export declare const DiscoveryPulse: ({ children, localStorageKey, isDiscovered, localStorageKeyExpirationInMs, }: PulseProps) => JSX.Element;
|
|
26
22
|
export default Pulse;
|
package/dist/types/messages.d.ts
CHANGED
package/dist/types/toolbar.d.ts
CHANGED
|
@@ -7,3 +7,4 @@ export declare const removeCard: (editorAnalyticsApi: EditorAnalyticsAPI | undef
|
|
|
7
7
|
export declare const visitCardLink: (editorAnalyticsApi: EditorAnalyticsAPI | undefined) => Command;
|
|
8
8
|
export declare const openLinkSettings: (editorAnalyticsApi: EditorAnalyticsAPI | undefined) => Command;
|
|
9
9
|
export declare const floatingToolbar: (cardOptions: CardOptions, featureFlags: FeatureFlags, platform?: CardPlatform, linkPickerOptions?: LinkPickerOptions, pluginInjectionApi?: ExtractInjectionAPI<typeof cardPlugin>) => FloatingToolbarHandler;
|
|
10
|
+
export declare const shouldRenderToolbarPulse: (embedEnabled: boolean, appearance: string, status: string, isDiscoverabilityEnabled: boolean) => boolean;
|