@atlaskit/editor-plugin-media-insert 1.2.2 → 2.0.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 +25 -0
- package/dist/cjs/actions.js +28 -0
- package/dist/cjs/index.js +1 -8
- package/dist/cjs/plugin.js +57 -10
- package/dist/cjs/pm-plugins/main.js +40 -0
- package/dist/cjs/pm-plugins/plugin-key.js +8 -0
- package/dist/cjs/types.js +5 -0
- package/dist/cjs/ui/FromURL.js +30 -22
- package/dist/cjs/ui/MediaCard.js +1 -9
- package/dist/cjs/ui/MediaInsertContent.js +30 -0
- package/dist/cjs/ui/MediaInsertPicker.js +96 -0
- package/dist/cjs/ui/MediaInsertWrapper.js +21 -0
- package/dist/es2019/actions.js +21 -0
- package/dist/es2019/index.js +1 -2
- package/dist/es2019/plugin.js +62 -12
- package/dist/es2019/pm-plugins/main.js +34 -0
- package/dist/es2019/pm-plugins/plugin-key.js +2 -0
- package/dist/es2019/types.js +1 -0
- package/dist/es2019/ui/FromURL.js +18 -5
- package/dist/es2019/ui/MediaCard.js +1 -5
- package/dist/es2019/ui/MediaInsertContent.js +21 -0
- package/dist/es2019/ui/MediaInsertPicker.js +86 -0
- package/dist/es2019/ui/MediaInsertWrapper.js +15 -0
- package/dist/esm/actions.js +22 -0
- package/dist/esm/index.js +1 -2
- package/dist/esm/plugin.js +57 -10
- package/dist/esm/pm-plugins/main.js +34 -0
- package/dist/esm/pm-plugins/plugin-key.js +2 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/ui/FromURL.js +30 -22
- package/dist/esm/ui/MediaCard.js +1 -9
- package/dist/esm/ui/MediaInsertContent.js +20 -0
- package/dist/esm/ui/MediaInsertPicker.js +89 -0
- package/dist/esm/ui/MediaInsertWrapper.js +14 -0
- package/dist/types/actions.d.ts +6 -0
- package/dist/types/index.d.ts +1 -2
- package/dist/types/plugin.d.ts +1 -2
- package/dist/types/pm-plugins/main.d.ts +3 -0
- package/dist/types/pm-plugins/plugin-key.d.ts +3 -0
- package/dist/types/types.d.ts +17 -0
- package/dist/types/ui/FromURL.d.ts +3 -2
- package/dist/types/ui/MediaCard.d.ts +2 -2
- package/dist/types/ui/MediaInsertContent.d.ts +8 -0
- package/dist/types/ui/MediaInsertPicker.d.ts +3 -0
- package/dist/types/ui/MediaInsertWrapper.d.ts +4 -0
- package/dist/types-ts4.5/actions.d.ts +6 -0
- package/dist/types-ts4.5/index.d.ts +1 -2
- package/dist/types-ts4.5/plugin.d.ts +1 -2
- package/dist/types-ts4.5/pm-plugins/main.d.ts +3 -0
- package/dist/types-ts4.5/pm-plugins/plugin-key.d.ts +3 -0
- package/dist/types-ts4.5/types.d.ts +20 -0
- package/dist/types-ts4.5/ui/FromURL.d.ts +3 -2
- package/dist/types-ts4.5/ui/MediaCard.d.ts +2 -2
- package/dist/types-ts4.5/ui/MediaInsertContent.d.ts +8 -0
- package/dist/types-ts4.5/ui/MediaInsertPicker.d.ts +3 -0
- package/dist/types-ts4.5/ui/MediaInsertWrapper.d.ts +4 -0
- package/package.json +9 -4
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
|
+
import { ACTION_CLOSE_POPUP, ACTION_OPEN_POPUP } from '../actions';
|
|
3
|
+
import { pluginKey } from './plugin-key';
|
|
4
|
+
export const createPlugin = () => {
|
|
5
|
+
return new SafePlugin({
|
|
6
|
+
state: {
|
|
7
|
+
init() {
|
|
8
|
+
return {
|
|
9
|
+
isOpen: false
|
|
10
|
+
};
|
|
11
|
+
},
|
|
12
|
+
apply(tr, mediaInsertPluginState) {
|
|
13
|
+
const meta = tr.getMeta(pluginKey);
|
|
14
|
+
if (meta) {
|
|
15
|
+
switch (meta.type) {
|
|
16
|
+
case ACTION_OPEN_POPUP:
|
|
17
|
+
return {
|
|
18
|
+
isOpen: true
|
|
19
|
+
};
|
|
20
|
+
case ACTION_CLOSE_POPUP:
|
|
21
|
+
return {
|
|
22
|
+
isOpen: false
|
|
23
|
+
};
|
|
24
|
+
default:
|
|
25
|
+
return mediaInsertPluginState;
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
return mediaInsertPluginState;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
key: pluginKey
|
|
33
|
+
});
|
|
34
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -23,6 +23,9 @@ const PreviewImageStyles = xcss({
|
|
|
23
23
|
const ButtonGroupStyles = xcss({
|
|
24
24
|
alignSelf: 'end'
|
|
25
25
|
});
|
|
26
|
+
const FormStyles = xcss({
|
|
27
|
+
flexGrow: 1
|
|
28
|
+
});
|
|
26
29
|
const INITIAL_PREVIEW_STATE = Object.freeze({
|
|
27
30
|
isLoading: false,
|
|
28
31
|
error: null,
|
|
@@ -68,7 +71,8 @@ export function MediaFromURL({
|
|
|
68
71
|
mediaProvider,
|
|
69
72
|
onInsert,
|
|
70
73
|
onExternalInsert,
|
|
71
|
-
dispatchAnalyticsEvent
|
|
74
|
+
dispatchAnalyticsEvent,
|
|
75
|
+
onEscKeyPressed
|
|
72
76
|
}) {
|
|
73
77
|
const intl = useIntl();
|
|
74
78
|
const strings = {
|
|
@@ -94,7 +98,7 @@ export function MediaFromURL({
|
|
|
94
98
|
const {
|
|
95
99
|
uploadMediaClientConfig,
|
|
96
100
|
uploadParams
|
|
97
|
-
} =
|
|
101
|
+
} = mediaProvider;
|
|
98
102
|
if (!uploadMediaClientConfig) {
|
|
99
103
|
return;
|
|
100
104
|
}
|
|
@@ -174,18 +178,27 @@ export function MediaFromURL({
|
|
|
174
178
|
return onExternalInsert(inputUrl);
|
|
175
179
|
}
|
|
176
180
|
}, [onExternalInsert, onInsert, previewState.previewInfo, previewState.warning, inputUrl]);
|
|
177
|
-
|
|
181
|
+
const onInputKeyPress = React.useCallback(event => {
|
|
182
|
+
if (event && event.key === 'Esc') {
|
|
183
|
+
onEscKeyPressed();
|
|
184
|
+
}
|
|
185
|
+
}, [onEscKeyPressed]);
|
|
186
|
+
return /*#__PURE__*/React.createElement(Box, {
|
|
187
|
+
as: "form",
|
|
178
188
|
onSubmit: e => {
|
|
179
189
|
e.preventDefault();
|
|
180
190
|
uploadExternalMedia(inputUrl);
|
|
181
|
-
}
|
|
191
|
+
},
|
|
192
|
+
xcss: FormStyles
|
|
182
193
|
}, /*#__PURE__*/React.createElement(Stack, {
|
|
183
|
-
space: "space.150"
|
|
194
|
+
space: "space.150",
|
|
195
|
+
grow: "fill"
|
|
184
196
|
}, /*#__PURE__*/React.createElement(TextField, {
|
|
185
197
|
autoFocus: true,
|
|
186
198
|
value: inputUrl,
|
|
187
199
|
placeholder: strings.pasteLinkToUpload,
|
|
188
200
|
onChange: onURLChange,
|
|
201
|
+
onKeyPress: onInputKeyPress,
|
|
189
202
|
onPaste: onPaste
|
|
190
203
|
}), previewState.previewInfo && /*#__PURE__*/React.createElement(Inline, {
|
|
191
204
|
alignInline: "center",
|
|
@@ -8,14 +8,10 @@ const maxDimensions = {
|
|
|
8
8
|
};
|
|
9
9
|
export const MediaCard = ({
|
|
10
10
|
attrs,
|
|
11
|
-
mediaProvider
|
|
11
|
+
mediaProvider
|
|
12
12
|
}) => {
|
|
13
13
|
const intl = useIntl();
|
|
14
14
|
const mediaAlt = intl.formatMessage(mediaInsertMessages.mediaAlt);
|
|
15
|
-
const [mediaProvider, setMediaProvider] = React.useState();
|
|
16
|
-
React.useEffect(() => {
|
|
17
|
-
mediaProviderPromise.then(setMediaProvider);
|
|
18
|
-
}, [mediaProviderPromise]);
|
|
19
15
|
const dimensions = React.useMemo(() => {
|
|
20
16
|
return {
|
|
21
17
|
width: attrs.width,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Box } from '@atlaskit/primitives';
|
|
3
|
+
import Tabs, { Tab, TabList, TabPanel } from '@atlaskit/tabs';
|
|
4
|
+
import { MediaFromURL } from './FromURL';
|
|
5
|
+
export const MediaInsertContent = ({
|
|
6
|
+
mediaProvider,
|
|
7
|
+
dispatchAnalyticsEvent,
|
|
8
|
+
onEscKeyPressed
|
|
9
|
+
}) => {
|
|
10
|
+
return /*#__PURE__*/React.createElement(Tabs, {
|
|
11
|
+
id: "media-insert-tab-navigation"
|
|
12
|
+
}, /*#__PURE__*/React.createElement(Box, {
|
|
13
|
+
paddingBlockEnd: "space.150"
|
|
14
|
+
}, /*#__PURE__*/React.createElement(TabList, null, /*#__PURE__*/React.createElement(Tab, null, "Link"))), /*#__PURE__*/React.createElement(TabPanel, null, /*#__PURE__*/React.createElement(MediaFromURL, {
|
|
15
|
+
mediaProvider: mediaProvider,
|
|
16
|
+
onExternalInsert: () => {},
|
|
17
|
+
onInsert: () => {},
|
|
18
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
19
|
+
onEscKeyPressed: onEscKeyPressed
|
|
20
|
+
})));
|
|
21
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
4
|
+
import { Popup, withOuterListeners } from '@atlaskit/editor-common/ui';
|
|
5
|
+
import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
|
|
6
|
+
import { akEditorFloatingDialogZIndex } from '@atlaskit/editor-shared-styles';
|
|
7
|
+
import { MediaInsertContent } from './MediaInsertContent';
|
|
8
|
+
import { MediaInsertWrapper } from './MediaInsertWrapper';
|
|
9
|
+
const PopupWithListeners = withOuterListeners(Popup);
|
|
10
|
+
const getDomRefFromSelection = (view, dispatchAnalyticsEvent) => {
|
|
11
|
+
try {
|
|
12
|
+
const domRef = findDomRefAtPos(view.state.selection.from, view.domAtPos.bind(view));
|
|
13
|
+
if (domRef instanceof HTMLElement) {
|
|
14
|
+
return domRef;
|
|
15
|
+
} else {
|
|
16
|
+
throw new Error('Invalid DOM reference');
|
|
17
|
+
}
|
|
18
|
+
} catch (error) {
|
|
19
|
+
if (dispatchAnalyticsEvent) {
|
|
20
|
+
const payload = {
|
|
21
|
+
action: ACTION.ERRORED,
|
|
22
|
+
actionSubject: ACTION_SUBJECT.PICKER,
|
|
23
|
+
actionSubjectId: ACTION_SUBJECT_ID.PICKER_MEDIA,
|
|
24
|
+
eventType: EVENT_TYPE.OPERATIONAL,
|
|
25
|
+
attributes: {
|
|
26
|
+
error: 'Error getting DOM reference from selection'
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
dispatchAnalyticsEvent(payload);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
export const MediaInsertPicker = ({
|
|
34
|
+
api,
|
|
35
|
+
editorView,
|
|
36
|
+
dispatchAnalyticsEvent,
|
|
37
|
+
popupsMountPoint,
|
|
38
|
+
popupsBoundariesElement,
|
|
39
|
+
popupsScrollableElement,
|
|
40
|
+
closeMediaInsertPicker
|
|
41
|
+
}) => {
|
|
42
|
+
var _useSharedPluginState, _useSharedPluginState2, _useSharedPluginState3, _useSharedPluginState4;
|
|
43
|
+
const targetRef = getDomRefFromSelection(editorView, dispatchAnalyticsEvent);
|
|
44
|
+
const isOpen = (_useSharedPluginState = useSharedPluginState(api, ['mediaInsert'])) === null || _useSharedPluginState === void 0 ? void 0 : (_useSharedPluginState2 = _useSharedPluginState.mediaInsertState) === null || _useSharedPluginState2 === void 0 ? void 0 : _useSharedPluginState2.isOpen;
|
|
45
|
+
const mediaProvider = (_useSharedPluginState3 = useSharedPluginState(api, ['media'])) === null || _useSharedPluginState3 === void 0 ? void 0 : (_useSharedPluginState4 = _useSharedPluginState3.mediaState) === null || _useSharedPluginState4 === void 0 ? void 0 : _useSharedPluginState4.mediaProvider;
|
|
46
|
+
if (!isOpen || !mediaProvider) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const handleClose = exitMethod => event => {
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
if (dispatchAnalyticsEvent) {
|
|
52
|
+
const payload = {
|
|
53
|
+
action: ACTION.CLOSED,
|
|
54
|
+
actionSubject: ACTION_SUBJECT.PICKER,
|
|
55
|
+
actionSubjectId: ACTION_SUBJECT_ID.PICKER_MEDIA,
|
|
56
|
+
eventType: EVENT_TYPE.UI,
|
|
57
|
+
attributes: {
|
|
58
|
+
exitMethod
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
dispatchAnalyticsEvent(payload);
|
|
62
|
+
}
|
|
63
|
+
closeMediaInsertPicker();
|
|
64
|
+
};
|
|
65
|
+
return /*#__PURE__*/React.createElement(PopupWithListeners
|
|
66
|
+
// TODO: i18n
|
|
67
|
+
, {
|
|
68
|
+
ariaLabel: 'Media Insert',
|
|
69
|
+
offset: [0, 12],
|
|
70
|
+
target: targetRef,
|
|
71
|
+
zIndex: akEditorFloatingDialogZIndex,
|
|
72
|
+
fitHeight: 390,
|
|
73
|
+
fitWidth: 340,
|
|
74
|
+
mountTo: popupsMountPoint,
|
|
75
|
+
boundariesElement: popupsBoundariesElement,
|
|
76
|
+
handleClickOutside: handleClose(INPUT_METHOD.MOUSE),
|
|
77
|
+
handleEscapeKeydown: handleClose(INPUT_METHOD.KEYBOARD),
|
|
78
|
+
scrollableElement: popupsScrollableElement,
|
|
79
|
+
preventOverflow: true,
|
|
80
|
+
focusTrap: true
|
|
81
|
+
}, /*#__PURE__*/React.createElement(MediaInsertWrapper, null, /*#__PURE__*/React.createElement(MediaInsertContent, {
|
|
82
|
+
mediaProvider: mediaProvider,
|
|
83
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
84
|
+
onEscKeyPressed: () => handleClose(INPUT_METHOD.KEYBOARD)
|
|
85
|
+
})));
|
|
86
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Box, xcss } from '@atlaskit/primitives';
|
|
3
|
+
const styles = xcss({
|
|
4
|
+
boxShadow: 'elevation.shadow.overflow',
|
|
5
|
+
width: '340px',
|
|
6
|
+
padding: 'space.200',
|
|
7
|
+
borderRadius: 'border.radius'
|
|
8
|
+
});
|
|
9
|
+
export const MediaInsertWrapper = ({
|
|
10
|
+
children
|
|
11
|
+
}) => {
|
|
12
|
+
return /*#__PURE__*/React.createElement(Box, {
|
|
13
|
+
xcss: styles
|
|
14
|
+
}, children);
|
|
15
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { pluginKey } from './pm-plugins/plugin-key';
|
|
2
|
+
export var ACTION_OPEN_POPUP = 'OPEN_POPUP';
|
|
3
|
+
export var ACTION_CLOSE_POPUP = 'CLOSE_POPUP';
|
|
4
|
+
var setPopupMeta = function setPopupMeta(_ref) {
|
|
5
|
+
var type = _ref.type,
|
|
6
|
+
tr = _ref.tr;
|
|
7
|
+
return tr.setMeta(pluginKey, {
|
|
8
|
+
type: type
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
export var showMediaInsertPopup = function showMediaInsertPopup(tr) {
|
|
12
|
+
return setPopupMeta({
|
|
13
|
+
type: ACTION_OPEN_POPUP,
|
|
14
|
+
tr: tr
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
export var closeMediaInsertPicker = function closeMediaInsertPicker(tr) {
|
|
18
|
+
return setPopupMeta({
|
|
19
|
+
type: ACTION_CLOSE_POPUP,
|
|
20
|
+
tr: tr
|
|
21
|
+
});
|
|
22
|
+
};
|
package/dist/esm/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export { mediaInsertPlugin } from './plugin';
|
|
2
|
-
export { MediaFromURL } from './ui/FromURL';
|
|
1
|
+
export { mediaInsertPlugin } from './plugin';
|
package/dist/esm/plugin.js
CHANGED
|
@@ -1,22 +1,58 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
3
|
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
3
4
|
import { IconImages } from '@atlaskit/editor-common/quick-insert';
|
|
4
|
-
|
|
5
|
+
import { closeMediaInsertPicker as _closeMediaInsertPicker, showMediaInsertPopup } from './actions';
|
|
6
|
+
import { createPlugin } from './pm-plugins/main';
|
|
7
|
+
import { pluginKey } from './pm-plugins/plugin-key';
|
|
8
|
+
import { MediaInsertPicker } from './ui/MediaInsertPicker';
|
|
9
|
+
export var mediaInsertPlugin = function mediaInsertPlugin(_ref) {
|
|
10
|
+
var api = _ref.api;
|
|
5
11
|
return {
|
|
6
12
|
name: 'mediaInsert',
|
|
7
13
|
pmPlugins: function pmPlugins() {
|
|
8
14
|
return [{
|
|
9
15
|
name: 'mediaInsert',
|
|
10
16
|
plugin: function plugin() {
|
|
11
|
-
|
|
12
|
-
console.log('mediaInsert plugin');
|
|
13
|
-
return undefined;
|
|
17
|
+
return createPlugin();
|
|
14
18
|
}
|
|
15
19
|
}];
|
|
16
20
|
},
|
|
21
|
+
getSharedState: function getSharedState(editorState) {
|
|
22
|
+
if (!editorState) {
|
|
23
|
+
return {
|
|
24
|
+
isOpen: false
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
var _ref2 = pluginKey.getState(editorState) || {},
|
|
28
|
+
isOpen = _ref2.isOpen;
|
|
29
|
+
return {
|
|
30
|
+
isOpen: isOpen
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
contentComponent: function contentComponent(_ref3) {
|
|
34
|
+
var editorView = _ref3.editorView,
|
|
35
|
+
dispatchAnalyticsEvent = _ref3.dispatchAnalyticsEvent,
|
|
36
|
+
popupsMountPoint = _ref3.popupsMountPoint,
|
|
37
|
+
popupsBoundariesElement = _ref3.popupsBoundariesElement,
|
|
38
|
+
popupsScrollableElement = _ref3.popupsScrollableElement;
|
|
39
|
+
var dispatch = editorView.dispatch,
|
|
40
|
+
state = editorView.state;
|
|
41
|
+
return /*#__PURE__*/React.createElement(MediaInsertPicker, {
|
|
42
|
+
api: api,
|
|
43
|
+
editorView: editorView,
|
|
44
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
45
|
+
popupsMountPoint: popupsMountPoint,
|
|
46
|
+
popupsBoundariesElement: popupsBoundariesElement,
|
|
47
|
+
popupsScrollableElement: popupsScrollableElement,
|
|
48
|
+
closeMediaInsertPicker: function closeMediaInsertPicker() {
|
|
49
|
+
return dispatch(_closeMediaInsertPicker(state.tr));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
},
|
|
17
53
|
pluginsOptions: {
|
|
18
|
-
quickInsert: function quickInsert(
|
|
19
|
-
var formatMessage =
|
|
54
|
+
quickInsert: function quickInsert(_ref4) {
|
|
55
|
+
var formatMessage = _ref4.formatMessage;
|
|
20
56
|
return [{
|
|
21
57
|
id: 'media-insert',
|
|
22
58
|
title: formatMessage(messages.insertMediaFromUrl),
|
|
@@ -27,10 +63,21 @@ export var mediaInsertPlugin = function mediaInsertPlugin() {
|
|
|
27
63
|
return /*#__PURE__*/React.createElement(IconImages, null);
|
|
28
64
|
},
|
|
29
65
|
action: function action(insert) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
66
|
+
var _api$analytics;
|
|
67
|
+
// Insert empty string to remove the typeahead raw text
|
|
68
|
+
// close the quick insert immediately
|
|
69
|
+
var tr = insert('');
|
|
70
|
+
showMediaInsertPopup(tr);
|
|
71
|
+
api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 || _api$analytics.attachAnalyticsEvent({
|
|
72
|
+
action: ACTION.OPENED,
|
|
73
|
+
actionSubject: ACTION_SUBJECT.PICKER,
|
|
74
|
+
actionSubjectId: ACTION_SUBJECT_ID.PICKER_MEDIA,
|
|
75
|
+
attributes: {
|
|
76
|
+
inputMethod: INPUT_METHOD.QUICK_INSERT
|
|
77
|
+
},
|
|
78
|
+
eventType: EVENT_TYPE.UI
|
|
79
|
+
})(tr);
|
|
80
|
+
return tr;
|
|
34
81
|
}
|
|
35
82
|
}];
|
|
36
83
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
|
+
import { ACTION_CLOSE_POPUP, ACTION_OPEN_POPUP } from '../actions';
|
|
3
|
+
import { pluginKey } from './plugin-key';
|
|
4
|
+
export var createPlugin = function createPlugin() {
|
|
5
|
+
return new SafePlugin({
|
|
6
|
+
state: {
|
|
7
|
+
init: function init() {
|
|
8
|
+
return {
|
|
9
|
+
isOpen: false
|
|
10
|
+
};
|
|
11
|
+
},
|
|
12
|
+
apply: function apply(tr, mediaInsertPluginState) {
|
|
13
|
+
var meta = tr.getMeta(pluginKey);
|
|
14
|
+
if (meta) {
|
|
15
|
+
switch (meta.type) {
|
|
16
|
+
case ACTION_OPEN_POPUP:
|
|
17
|
+
return {
|
|
18
|
+
isOpen: true
|
|
19
|
+
};
|
|
20
|
+
case ACTION_CLOSE_POPUP:
|
|
21
|
+
return {
|
|
22
|
+
isOpen: false
|
|
23
|
+
};
|
|
24
|
+
default:
|
|
25
|
+
return mediaInsertPluginState;
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
return mediaInsertPluginState;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
key: pluginKey
|
|
33
|
+
});
|
|
34
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/esm/ui/FromURL.js
CHANGED
|
@@ -29,6 +29,9 @@ var PreviewImageStyles = xcss({
|
|
|
29
29
|
var ButtonGroupStyles = xcss({
|
|
30
30
|
alignSelf: 'end'
|
|
31
31
|
});
|
|
32
|
+
var FormStyles = xcss({
|
|
33
|
+
flexGrow: 1
|
|
34
|
+
});
|
|
32
35
|
var INITIAL_PREVIEW_STATE = Object.freeze({
|
|
33
36
|
isLoading: false,
|
|
34
37
|
error: null,
|
|
@@ -70,7 +73,8 @@ export function MediaFromURL(_ref) {
|
|
|
70
73
|
var mediaProvider = _ref.mediaProvider,
|
|
71
74
|
onInsert = _ref.onInsert,
|
|
72
75
|
onExternalInsert = _ref.onExternalInsert,
|
|
73
|
-
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent
|
|
76
|
+
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent,
|
|
77
|
+
onEscKeyPressed = _ref.onEscKeyPressed;
|
|
74
78
|
var intl = useIntl();
|
|
75
79
|
var strings = {
|
|
76
80
|
loadPreview: intl.formatMessage(mediaInsertMessages.loadPreview),
|
|
@@ -95,32 +99,27 @@ export function MediaFromURL(_ref) {
|
|
|
95
99
|
onUploadFailureAnalytics = _useAnalyticsEvents.onUploadFailureAnalytics;
|
|
96
100
|
var uploadExternalMedia = React.useCallback( /*#__PURE__*/function () {
|
|
97
101
|
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(url) {
|
|
98
|
-
var
|
|
102
|
+
var uploadMediaClientConfig, uploadParams, mediaClient, collection, _yield$mediaClient$fi, uploadableFileUpfrontIds, dimensions, message;
|
|
99
103
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
100
104
|
while (1) switch (_context.prev = _context.next) {
|
|
101
105
|
case 0:
|
|
102
106
|
dispatch({
|
|
103
107
|
type: 'loading'
|
|
104
108
|
});
|
|
105
|
-
|
|
106
|
-
return mediaProvider;
|
|
107
|
-
case 3:
|
|
108
|
-
_yield$mediaProvider = _context.sent;
|
|
109
|
-
uploadMediaClientConfig = _yield$mediaProvider.uploadMediaClientConfig;
|
|
110
|
-
uploadParams = _yield$mediaProvider.uploadParams;
|
|
109
|
+
uploadMediaClientConfig = mediaProvider.uploadMediaClientConfig, uploadParams = mediaProvider.uploadParams;
|
|
111
110
|
if (uploadMediaClientConfig) {
|
|
112
|
-
_context.next =
|
|
111
|
+
_context.next = 4;
|
|
113
112
|
break;
|
|
114
113
|
}
|
|
115
114
|
return _context.abrupt("return");
|
|
116
|
-
case
|
|
115
|
+
case 4:
|
|
117
116
|
mediaClient = getMediaClient(uploadMediaClientConfig);
|
|
118
117
|
collection = uploadParams === null || uploadParams === void 0 ? void 0 : uploadParams.collection;
|
|
119
118
|
onUploadAnalytics();
|
|
120
|
-
_context.prev =
|
|
121
|
-
_context.next =
|
|
119
|
+
_context.prev = 7;
|
|
120
|
+
_context.next = 10;
|
|
122
121
|
return mediaClient.file.uploadExternal(url, collection);
|
|
123
|
-
case
|
|
122
|
+
case 10:
|
|
124
123
|
_yield$mediaClient$fi = _context.sent;
|
|
125
124
|
uploadableFileUpfrontIds = _yield$mediaClient$fi.uploadableFileUpfrontIds;
|
|
126
125
|
dimensions = _yield$mediaClient$fi.dimensions;
|
|
@@ -135,11 +134,11 @@ export function MediaFromURL(_ref) {
|
|
|
135
134
|
occurrenceKey: uploadableFileUpfrontIds.occurrenceKey
|
|
136
135
|
}
|
|
137
136
|
});
|
|
138
|
-
_context.next =
|
|
137
|
+
_context.next = 20;
|
|
139
138
|
break;
|
|
140
|
-
case
|
|
141
|
-
_context.prev =
|
|
142
|
-
_context.t0 = _context["catch"](
|
|
139
|
+
case 17:
|
|
140
|
+
_context.prev = 17;
|
|
141
|
+
_context.t0 = _context["catch"](7);
|
|
143
142
|
if (typeof _context.t0 === 'string' && _context.t0 === 'Could not download remote file') {
|
|
144
143
|
// TODO: Make sure this gets good unit test coverage with the actual
|
|
145
144
|
// media plugin. This hard coded error message could be changed at any
|
|
@@ -164,11 +163,11 @@ export function MediaFromURL(_ref) {
|
|
|
164
163
|
error: 'Unknown error'
|
|
165
164
|
});
|
|
166
165
|
}
|
|
167
|
-
case
|
|
166
|
+
case 20:
|
|
168
167
|
case "end":
|
|
169
168
|
return _context.stop();
|
|
170
169
|
}
|
|
171
|
-
}, _callee, null, [[
|
|
170
|
+
}, _callee, null, [[7, 17]]);
|
|
172
171
|
}));
|
|
173
172
|
return function (_x) {
|
|
174
173
|
return _ref2.apply(this, arguments);
|
|
@@ -204,18 +203,27 @@ export function MediaFromURL(_ref) {
|
|
|
204
203
|
return onExternalInsert(inputUrl);
|
|
205
204
|
}
|
|
206
205
|
}, [onExternalInsert, onInsert, previewState.previewInfo, previewState.warning, inputUrl]);
|
|
207
|
-
|
|
206
|
+
var onInputKeyPress = React.useCallback(function (event) {
|
|
207
|
+
if (event && event.key === 'Esc') {
|
|
208
|
+
onEscKeyPressed();
|
|
209
|
+
}
|
|
210
|
+
}, [onEscKeyPressed]);
|
|
211
|
+
return /*#__PURE__*/React.createElement(Box, {
|
|
212
|
+
as: "form",
|
|
208
213
|
onSubmit: function onSubmit(e) {
|
|
209
214
|
e.preventDefault();
|
|
210
215
|
uploadExternalMedia(inputUrl);
|
|
211
|
-
}
|
|
216
|
+
},
|
|
217
|
+
xcss: FormStyles
|
|
212
218
|
}, /*#__PURE__*/React.createElement(Stack, {
|
|
213
|
-
space: "space.150"
|
|
219
|
+
space: "space.150",
|
|
220
|
+
grow: "fill"
|
|
214
221
|
}, /*#__PURE__*/React.createElement(TextField, {
|
|
215
222
|
autoFocus: true,
|
|
216
223
|
value: inputUrl,
|
|
217
224
|
placeholder: strings.pasteLinkToUpload,
|
|
218
225
|
onChange: onURLChange,
|
|
226
|
+
onKeyPress: onInputKeyPress,
|
|
219
227
|
onPaste: onPaste
|
|
220
228
|
}), previewState.previewInfo && /*#__PURE__*/React.createElement(Inline, {
|
|
221
229
|
alignInline: "center",
|
package/dist/esm/ui/MediaCard.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
1
|
import React from 'react';
|
|
3
2
|
import { useIntl } from 'react-intl-next';
|
|
4
3
|
import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
|
|
@@ -9,16 +8,9 @@ var maxDimensions = {
|
|
|
9
8
|
};
|
|
10
9
|
export var MediaCard = function MediaCard(_ref) {
|
|
11
10
|
var attrs = _ref.attrs,
|
|
12
|
-
|
|
11
|
+
mediaProvider = _ref.mediaProvider;
|
|
13
12
|
var intl = useIntl();
|
|
14
13
|
var mediaAlt = intl.formatMessage(mediaInsertMessages.mediaAlt);
|
|
15
|
-
var _React$useState = React.useState(),
|
|
16
|
-
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
17
|
-
mediaProvider = _React$useState2[0],
|
|
18
|
-
setMediaProvider = _React$useState2[1];
|
|
19
|
-
React.useEffect(function () {
|
|
20
|
-
mediaProviderPromise.then(setMediaProvider);
|
|
21
|
-
}, [mediaProviderPromise]);
|
|
22
14
|
var dimensions = React.useMemo(function () {
|
|
23
15
|
return {
|
|
24
16
|
width: attrs.width,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Box } from '@atlaskit/primitives';
|
|
3
|
+
import Tabs, { Tab, TabList, TabPanel } from '@atlaskit/tabs';
|
|
4
|
+
import { MediaFromURL } from './FromURL';
|
|
5
|
+
export var MediaInsertContent = function MediaInsertContent(_ref) {
|
|
6
|
+
var mediaProvider = _ref.mediaProvider,
|
|
7
|
+
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent,
|
|
8
|
+
onEscKeyPressed = _ref.onEscKeyPressed;
|
|
9
|
+
return /*#__PURE__*/React.createElement(Tabs, {
|
|
10
|
+
id: "media-insert-tab-navigation"
|
|
11
|
+
}, /*#__PURE__*/React.createElement(Box, {
|
|
12
|
+
paddingBlockEnd: "space.150"
|
|
13
|
+
}, /*#__PURE__*/React.createElement(TabList, null, /*#__PURE__*/React.createElement(Tab, null, "Link"))), /*#__PURE__*/React.createElement(TabPanel, null, /*#__PURE__*/React.createElement(MediaFromURL, {
|
|
14
|
+
mediaProvider: mediaProvider,
|
|
15
|
+
onExternalInsert: function onExternalInsert() {},
|
|
16
|
+
onInsert: function onInsert() {},
|
|
17
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
18
|
+
onEscKeyPressed: onEscKeyPressed
|
|
19
|
+
})));
|
|
20
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
4
|
+
import { Popup, withOuterListeners } from '@atlaskit/editor-common/ui';
|
|
5
|
+
import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
|
|
6
|
+
import { akEditorFloatingDialogZIndex } from '@atlaskit/editor-shared-styles';
|
|
7
|
+
import { MediaInsertContent } from './MediaInsertContent';
|
|
8
|
+
import { MediaInsertWrapper } from './MediaInsertWrapper';
|
|
9
|
+
var PopupWithListeners = withOuterListeners(Popup);
|
|
10
|
+
var getDomRefFromSelection = function getDomRefFromSelection(view, dispatchAnalyticsEvent) {
|
|
11
|
+
try {
|
|
12
|
+
var domRef = findDomRefAtPos(view.state.selection.from, view.domAtPos.bind(view));
|
|
13
|
+
if (domRef instanceof HTMLElement) {
|
|
14
|
+
return domRef;
|
|
15
|
+
} else {
|
|
16
|
+
throw new Error('Invalid DOM reference');
|
|
17
|
+
}
|
|
18
|
+
} catch (error) {
|
|
19
|
+
if (dispatchAnalyticsEvent) {
|
|
20
|
+
var payload = {
|
|
21
|
+
action: ACTION.ERRORED,
|
|
22
|
+
actionSubject: ACTION_SUBJECT.PICKER,
|
|
23
|
+
actionSubjectId: ACTION_SUBJECT_ID.PICKER_MEDIA,
|
|
24
|
+
eventType: EVENT_TYPE.OPERATIONAL,
|
|
25
|
+
attributes: {
|
|
26
|
+
error: 'Error getting DOM reference from selection'
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
dispatchAnalyticsEvent(payload);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
export var MediaInsertPicker = function MediaInsertPicker(_ref) {
|
|
34
|
+
var _useSharedPluginState, _useSharedPluginState2;
|
|
35
|
+
var api = _ref.api,
|
|
36
|
+
editorView = _ref.editorView,
|
|
37
|
+
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent,
|
|
38
|
+
popupsMountPoint = _ref.popupsMountPoint,
|
|
39
|
+
popupsBoundariesElement = _ref.popupsBoundariesElement,
|
|
40
|
+
popupsScrollableElement = _ref.popupsScrollableElement,
|
|
41
|
+
closeMediaInsertPicker = _ref.closeMediaInsertPicker;
|
|
42
|
+
var targetRef = getDomRefFromSelection(editorView, dispatchAnalyticsEvent);
|
|
43
|
+
var isOpen = (_useSharedPluginState = useSharedPluginState(api, ['mediaInsert'])) === null || _useSharedPluginState === void 0 || (_useSharedPluginState = _useSharedPluginState.mediaInsertState) === null || _useSharedPluginState === void 0 ? void 0 : _useSharedPluginState.isOpen;
|
|
44
|
+
var mediaProvider = (_useSharedPluginState2 = useSharedPluginState(api, ['media'])) === null || _useSharedPluginState2 === void 0 || (_useSharedPluginState2 = _useSharedPluginState2.mediaState) === null || _useSharedPluginState2 === void 0 ? void 0 : _useSharedPluginState2.mediaProvider;
|
|
45
|
+
if (!isOpen || !mediaProvider) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
var handleClose = function handleClose(exitMethod) {
|
|
49
|
+
return function (event) {
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
if (dispatchAnalyticsEvent) {
|
|
52
|
+
var payload = {
|
|
53
|
+
action: ACTION.CLOSED,
|
|
54
|
+
actionSubject: ACTION_SUBJECT.PICKER,
|
|
55
|
+
actionSubjectId: ACTION_SUBJECT_ID.PICKER_MEDIA,
|
|
56
|
+
eventType: EVENT_TYPE.UI,
|
|
57
|
+
attributes: {
|
|
58
|
+
exitMethod: exitMethod
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
dispatchAnalyticsEvent(payload);
|
|
62
|
+
}
|
|
63
|
+
closeMediaInsertPicker();
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
return /*#__PURE__*/React.createElement(PopupWithListeners
|
|
67
|
+
// TODO: i18n
|
|
68
|
+
, {
|
|
69
|
+
ariaLabel: 'Media Insert',
|
|
70
|
+
offset: [0, 12],
|
|
71
|
+
target: targetRef,
|
|
72
|
+
zIndex: akEditorFloatingDialogZIndex,
|
|
73
|
+
fitHeight: 390,
|
|
74
|
+
fitWidth: 340,
|
|
75
|
+
mountTo: popupsMountPoint,
|
|
76
|
+
boundariesElement: popupsBoundariesElement,
|
|
77
|
+
handleClickOutside: handleClose(INPUT_METHOD.MOUSE),
|
|
78
|
+
handleEscapeKeydown: handleClose(INPUT_METHOD.KEYBOARD),
|
|
79
|
+
scrollableElement: popupsScrollableElement,
|
|
80
|
+
preventOverflow: true,
|
|
81
|
+
focusTrap: true
|
|
82
|
+
}, /*#__PURE__*/React.createElement(MediaInsertWrapper, null, /*#__PURE__*/React.createElement(MediaInsertContent, {
|
|
83
|
+
mediaProvider: mediaProvider,
|
|
84
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
85
|
+
onEscKeyPressed: function onEscKeyPressed() {
|
|
86
|
+
return handleClose(INPUT_METHOD.KEYBOARD);
|
|
87
|
+
}
|
|
88
|
+
})));
|
|
89
|
+
};
|