@atlaskit/editor-plugin-media-insert 22.0.0 → 23.1.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 +31 -0
- package/dist/cjs/mediaInsertPlugin.js +33 -0
- package/dist/cjs/ui/LocalMedia.js +2 -2
- package/dist/cjs/ui/MediaCard.js +2 -2
- package/dist/cjs/ui/MediaFromURL.js +2 -2
- package/dist/cjs/ui/MediaInsertPicker.js +34 -4
- package/dist/es2019/mediaInsertPlugin.js +26 -0
- package/dist/es2019/ui/LocalMedia.js +1 -1
- package/dist/es2019/ui/MediaCard.js +1 -1
- package/dist/es2019/ui/MediaFromURL.js +1 -1
- package/dist/es2019/ui/MediaInsertPicker.js +30 -3
- package/dist/esm/mediaInsertPlugin.js +34 -0
- package/dist/esm/ui/LocalMedia.js +1 -1
- package/dist/esm/ui/MediaCard.js +1 -1
- package/dist/esm/ui/MediaFromURL.js +1 -1
- package/dist/esm/ui/MediaInsertPicker.js +33 -3
- package/dist/types/index.d.ts +1 -1
- package/dist/types/mediaInsertPluginType.d.ts +66 -1
- package/dist/types-ts4.5/index.d.ts +1 -1
- package/dist/types-ts4.5/mediaInsertPluginType.d.ts +66 -1
- package/package.json +16 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-media-insert
|
|
2
2
|
|
|
3
|
+
## 23.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`1b208e1f7d8f7`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/1b208e1f7d8f7) -
|
|
8
|
+
[ux] Adds the entry point for ai image generation to the media insert picker plugin as a new tab.
|
|
9
|
+
This feature is fully behind an experiment gate.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
|
|
15
|
+
## 23.0.0
|
|
16
|
+
|
|
17
|
+
### Major Changes
|
|
18
|
+
|
|
19
|
+
- [`901c87a57486e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/901c87a57486e) -
|
|
20
|
+
Removed `react-intl-next` alias and replaced all usages with `react-intl` directly.
|
|
21
|
+
|
|
22
|
+
What changed: The `react-intl-next` npm alias (which resolved to `react-intl@^5`) has been
|
|
23
|
+
removed. All imports now reference `react-intl` directly, and `peerDependencies` have been updated
|
|
24
|
+
to `"^5.25.1 || ^6.0.0 || ^7.0.0"`.
|
|
25
|
+
|
|
26
|
+
How consumer should update their code: Ensure `react-intl` is installed at a version satisfying
|
|
27
|
+
`^5.25.1 || ^6.0.0 || ^7.0.0`. If your application was using `react-intl-next` as an npm alias, it
|
|
28
|
+
can be safely removed. Replace any remaining `react-intl-next` imports with `react-intl`.
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- Updated dependencies
|
|
33
|
+
|
|
3
34
|
## 22.0.0
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
|
@@ -13,9 +13,34 @@ var _actions = require("./pm-plugins/actions");
|
|
|
13
13
|
var _main = require("./pm-plugins/main");
|
|
14
14
|
var _pluginKey = require("./pm-plugins/plugin-key");
|
|
15
15
|
var _MediaInsertPicker = require("./ui/MediaInsertPicker");
|
|
16
|
+
/**
|
|
17
|
+
* Per-editor-instance registry of insert tabs registered via
|
|
18
|
+
* `actions.registerInsertTab(...)`. Idempotent on `key` so that re-registering
|
|
19
|
+
* the same tab (e.g. on plugin re-init in dev / StrictMode) replaces rather
|
|
20
|
+
* than duplicates.
|
|
21
|
+
*/
|
|
22
|
+
var createInsertTabRegistry = function createInsertTabRegistry() {
|
|
23
|
+
var tabs = [];
|
|
24
|
+
return {
|
|
25
|
+
register: function register(tab) {
|
|
26
|
+
var existingIndex = tabs.findIndex(function (t) {
|
|
27
|
+
return t.key === tab.key;
|
|
28
|
+
});
|
|
29
|
+
if (existingIndex >= 0) {
|
|
30
|
+
tabs[existingIndex] = tab;
|
|
31
|
+
} else {
|
|
32
|
+
tabs.push(tab);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
getAll: function getAll() {
|
|
36
|
+
return tabs;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
};
|
|
16
40
|
var mediaInsertPlugin = exports.mediaInsertPlugin = function mediaInsertPlugin(_ref) {
|
|
17
41
|
var api = _ref.api,
|
|
18
42
|
config = _ref.config;
|
|
43
|
+
var insertTabRegistry = createInsertTabRegistry();
|
|
19
44
|
return {
|
|
20
45
|
name: 'mediaInsert',
|
|
21
46
|
pmPlugins: function pmPlugins() {
|
|
@@ -48,6 +73,14 @@ var mediaInsertPlugin = exports.mediaInsertPlugin = function mediaInsertPlugin(_
|
|
|
48
73
|
};
|
|
49
74
|
}
|
|
50
75
|
},
|
|
76
|
+
actions: {
|
|
77
|
+
registerInsertTab: function registerInsertTab(tab) {
|
|
78
|
+
return insertTabRegistry.register(tab);
|
|
79
|
+
},
|
|
80
|
+
getInsertTabs: function getInsertTabs() {
|
|
81
|
+
return insertTabRegistry.getAll();
|
|
82
|
+
}
|
|
83
|
+
},
|
|
51
84
|
contentComponent: function contentComponent(_ref4) {
|
|
52
85
|
var editorView = _ref4.editorView,
|
|
53
86
|
dispatchAnalyticsEvent = _ref4.dispatchAnalyticsEvent,
|
|
@@ -10,7 +10,7 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
|
|
|
10
10
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
11
11
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
12
12
|
var _react = _interopRequireWildcard(require("react"));
|
|
13
|
-
var
|
|
13
|
+
var _reactIntl = require("react-intl");
|
|
14
14
|
var _new = _interopRequireDefault(require("@atlaskit/button/new"));
|
|
15
15
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
16
16
|
var _messages = require("@atlaskit/editor-common/messages");
|
|
@@ -55,7 +55,7 @@ var LocalMedia = exports.LocalMedia = /*#__PURE__*/_react.default.forwardRef(fun
|
|
|
55
55
|
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent,
|
|
56
56
|
closeMediaInsertPicker = _ref.closeMediaInsertPicker,
|
|
57
57
|
insertFile = _ref.insertFile;
|
|
58
|
-
var intl = (0,
|
|
58
|
+
var intl = (0, _reactIntl.useIntl)();
|
|
59
59
|
var strings = {
|
|
60
60
|
upload: intl.formatMessage(_messages.mediaInsertMessages.upload),
|
|
61
61
|
networkError: intl.formatMessage(_messages.mediaInsertMessages.localFileNetworkErrorMessage),
|
package/dist/cjs/ui/MediaCard.js
CHANGED
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.MediaCard = void 0;
|
|
8
8
|
var _react = _interopRequireDefault(require("react"));
|
|
9
|
-
var
|
|
9
|
+
var _reactIntl = require("react-intl");
|
|
10
10
|
var _messages = require("@atlaskit/editor-common/messages");
|
|
11
11
|
var _mediaCard = require("@atlaskit/media-card");
|
|
12
12
|
var maxDimensions = {
|
|
@@ -16,7 +16,7 @@ var maxDimensions = {
|
|
|
16
16
|
var MediaCard = exports.MediaCard = function MediaCard(_ref) {
|
|
17
17
|
var attrs = _ref.attrs,
|
|
18
18
|
mediaProvider = _ref.mediaProvider;
|
|
19
|
-
var intl = (0,
|
|
19
|
+
var intl = (0, _reactIntl.useIntl)();
|
|
20
20
|
var mediaAlt = intl.formatMessage(_messages.mediaInsertMessages.mediaAlt);
|
|
21
21
|
var dimensions = _react.default.useMemo(function () {
|
|
22
22
|
return {
|
|
@@ -14,7 +14,7 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
|
|
|
14
14
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
15
15
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
16
16
|
var _react = _interopRequireWildcard(require("react"));
|
|
17
|
-
var
|
|
17
|
+
var _reactIntl = require("react-intl");
|
|
18
18
|
var _adfSchema = require("@atlaskit/adf-schema");
|
|
19
19
|
var _buttonGroup = _interopRequireDefault(require("@atlaskit/button/button-group"));
|
|
20
20
|
var _new = _interopRequireDefault(require("@atlaskit/button/new"));
|
|
@@ -106,7 +106,7 @@ function MediaFromURL(_ref) {
|
|
|
106
106
|
isOnlyExternalLinks = _ref.isOnlyExternalLinks,
|
|
107
107
|
customizedUrlValidation = _ref.customizedUrlValidation,
|
|
108
108
|
customizedHelperMessage = _ref.customizedHelperMessage;
|
|
109
|
-
var intl = (0,
|
|
109
|
+
var intl = (0, _reactIntl.useIntl)();
|
|
110
110
|
var strings = {
|
|
111
111
|
loadPreview: intl.formatMessage(_messages.mediaInsertMessages.loadPreview),
|
|
112
112
|
insert: intl.formatMessage(_messages.mediaInsertMessages.insert),
|
|
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
8
8
|
exports.MediaInsertPicker = void 0;
|
|
9
9
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
10
10
|
var _react = _interopRequireDefault(require("react"));
|
|
11
|
-
var
|
|
11
|
+
var _reactIntl = require("react-intl");
|
|
12
12
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
13
13
|
var _getDomRefFromSelection = require("@atlaskit/editor-common/get-dom-ref-from-selection");
|
|
14
14
|
var _hooks = require("@atlaskit/editor-common/hooks");
|
|
@@ -43,6 +43,7 @@ var CustomTabPanel = function CustomTabPanel(_ref) {
|
|
|
43
43
|
);
|
|
44
44
|
};
|
|
45
45
|
var MediaInsertPicker = exports.MediaInsertPicker = function MediaInsertPicker(_ref2) {
|
|
46
|
+
var _api$mediaInsert$acti, _api$mediaInsert, _api$mediaInsert$getI;
|
|
46
47
|
var api = _ref2.api,
|
|
47
48
|
editorView = _ref2.editorView,
|
|
48
49
|
dispatchAnalyticsEvent = _ref2.dispatchAnalyticsEvent,
|
|
@@ -57,6 +58,10 @@ var MediaInsertPicker = exports.MediaInsertPicker = function MediaInsertPicker(_
|
|
|
57
58
|
isOnlyExternalLinks = _ref2$isOnlyExternalL === void 0 ? false : _ref2$isOnlyExternalL,
|
|
58
59
|
customizedUrlValidation = _ref2.customizedUrlValidation,
|
|
59
60
|
customizedHelperMessage = _ref2.customizedHelperMessage;
|
|
61
|
+
// Tabs registered by other plugins via `api.mediaInsert.actions.registerInsertTab(...)`.
|
|
62
|
+
// Read once per render; the registry is mutated only at plugin setup time so this is stable
|
|
63
|
+
// for the lifetime of an editor instance.
|
|
64
|
+
var registeredTabs = (_api$mediaInsert$acti = api === null || api === void 0 || (_api$mediaInsert = api.mediaInsert) === null || _api$mediaInsert === void 0 || (_api$mediaInsert = _api$mediaInsert.actions) === null || _api$mediaInsert === void 0 || (_api$mediaInsert$getI = _api$mediaInsert.getInsertTabs) === null || _api$mediaInsert$getI === void 0 ? void 0 : _api$mediaInsert$getI.call(_api$mediaInsert)) !== null && _api$mediaInsert$acti !== void 0 ? _api$mediaInsert$acti : [];
|
|
60
65
|
var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['media', 'mediaInsert'], function (states) {
|
|
61
66
|
var _states$mediaState, _states$mediaInsertSt, _states$mediaInsertSt2;
|
|
62
67
|
return {
|
|
@@ -79,7 +84,7 @@ var MediaInsertPicker = exports.MediaInsertPicker = function MediaInsertPicker(_
|
|
|
79
84
|
targetRef = (0, _getDomRefFromSelection.getDomRefFromSelection)(editorView, _analytics.ACTION_SUBJECT_ID.PICKER_MEDIA, api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions);
|
|
80
85
|
mountPoint = popupsMountPoint;
|
|
81
86
|
}
|
|
82
|
-
var intl = (0,
|
|
87
|
+
var intl = (0, _reactIntl.useIntl)();
|
|
83
88
|
var focusEditor = (0, _useFocusEditor.useFocusEditor)({
|
|
84
89
|
editorView: editorView
|
|
85
90
|
});
|
|
@@ -91,6 +96,11 @@ var MediaInsertPicker = exports.MediaInsertPicker = function MediaInsertPicker(_
|
|
|
91
96
|
}
|
|
92
97
|
var handleClose = function handleClose(exitMethod) {
|
|
93
98
|
return function (event) {
|
|
99
|
+
// Same as AIImageGenerationPopup: react-select can detach the option
|
|
100
|
+
// before `click` fires, so withOuterListeners treats it as outside.
|
|
101
|
+
if (exitMethod === _analytics.INPUT_METHOD.MOUSE && event.target instanceof Node && !event.target.isConnected) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
94
104
|
event.preventDefault();
|
|
95
105
|
if (dispatchAnalyticsEvent) {
|
|
96
106
|
var payload = {
|
|
@@ -132,7 +142,11 @@ var MediaInsertPicker = exports.MediaInsertPicker = function MediaInsertPicker(_
|
|
|
132
142
|
id: "media-insert-tab-navigation"
|
|
133
143
|
}, /*#__PURE__*/_react.default.createElement(_compiled.Box, {
|
|
134
144
|
paddingBlockEnd: "space.150"
|
|
135
|
-
}, /*#__PURE__*/_react.default.createElement(_tabs.TabList, null, !isOnlyExternalLinks && /*#__PURE__*/_react.default.createElement(_tabs.Tab, null, intl.formatMessage(_messages.mediaInsertMessages.fileTabTitle)), /*#__PURE__*/_react.default.createElement(_tabs.Tab, null, intl.formatMessage(_messages.mediaInsertMessages.linkTabTitle))
|
|
145
|
+
}, /*#__PURE__*/_react.default.createElement(_tabs.TabList, null, !isOnlyExternalLinks && /*#__PURE__*/_react.default.createElement(_tabs.Tab, null, intl.formatMessage(_messages.mediaInsertMessages.fileTabTitle)), /*#__PURE__*/_react.default.createElement(_tabs.Tab, null, intl.formatMessage(_messages.mediaInsertMessages.linkTabTitle)), registeredTabs.map(function (tab) {
|
|
146
|
+
return /*#__PURE__*/_react.default.createElement(_tabs.Tab, {
|
|
147
|
+
key: tab.key
|
|
148
|
+
}, tab.label);
|
|
149
|
+
}))), !isOnlyExternalLinks && /*#__PURE__*/_react.default.createElement(CustomTabPanel, null, /*#__PURE__*/_react.default.createElement(_LocalMedia.LocalMedia, {
|
|
136
150
|
ref: autofocusRef,
|
|
137
151
|
mediaProvider: mediaProvider
|
|
138
152
|
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
|
|
@@ -157,6 +171,22 @@ var MediaInsertPicker = exports.MediaInsertPicker = function MediaInsertPicker(_
|
|
|
157
171
|
isOnlyExternalLinks: isOnlyExternalLinks,
|
|
158
172
|
customizedUrlValidation: customizedUrlValidation,
|
|
159
173
|
customizedHelperMessage: customizedHelperMessage
|
|
160
|
-
})))
|
|
174
|
+
})), registeredTabs.map(function (_ref3) {
|
|
175
|
+
var key = _ref3.key,
|
|
176
|
+
TabComponent = _ref3.component;
|
|
177
|
+
return /*#__PURE__*/_react.default.createElement(CustomTabPanel, {
|
|
178
|
+
key: key
|
|
179
|
+
}, /*#__PURE__*/_react.default.createElement(TabComponent
|
|
180
|
+
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
|
|
181
|
+
, {
|
|
182
|
+
closeMediaInsertPicker: function closeMediaInsertPicker() {
|
|
183
|
+
_closeMediaInsertPicker();
|
|
184
|
+
focusEditor();
|
|
185
|
+
},
|
|
186
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
187
|
+
insertMediaSingle: insertMediaSingle,
|
|
188
|
+
mediaProvider: mediaProvider
|
|
189
|
+
}));
|
|
190
|
+
})));
|
|
161
191
|
}));
|
|
162
192
|
};
|
|
@@ -6,10 +6,32 @@ import { closeMediaInsertPicker, showMediaInsertPopup } from './pm-plugins/actio
|
|
|
6
6
|
import { createPlugin } from './pm-plugins/main';
|
|
7
7
|
import { pluginKey } from './pm-plugins/plugin-key';
|
|
8
8
|
import { MediaInsertPicker } from './ui/MediaInsertPicker';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Per-editor-instance registry of insert tabs registered via
|
|
12
|
+
* `actions.registerInsertTab(...)`. Idempotent on `key` so that re-registering
|
|
13
|
+
* the same tab (e.g. on plugin re-init in dev / StrictMode) replaces rather
|
|
14
|
+
* than duplicates.
|
|
15
|
+
*/
|
|
16
|
+
const createInsertTabRegistry = () => {
|
|
17
|
+
const tabs = [];
|
|
18
|
+
return {
|
|
19
|
+
register: tab => {
|
|
20
|
+
const existingIndex = tabs.findIndex(t => t.key === tab.key);
|
|
21
|
+
if (existingIndex >= 0) {
|
|
22
|
+
tabs[existingIndex] = tab;
|
|
23
|
+
} else {
|
|
24
|
+
tabs.push(tab);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
getAll: () => tabs
|
|
28
|
+
};
|
|
29
|
+
};
|
|
9
30
|
export const mediaInsertPlugin = ({
|
|
10
31
|
api,
|
|
11
32
|
config
|
|
12
33
|
}) => {
|
|
34
|
+
const insertTabRegistry = createInsertTabRegistry();
|
|
13
35
|
return {
|
|
14
36
|
name: 'mediaInsert',
|
|
15
37
|
pmPlugins() {
|
|
@@ -38,6 +60,10 @@ export const mediaInsertPlugin = ({
|
|
|
38
60
|
tr
|
|
39
61
|
}) => showMediaInsertPopup(tr, mountInfo)
|
|
40
62
|
},
|
|
63
|
+
actions: {
|
|
64
|
+
registerInsertTab: tab => insertTabRegistry.register(tab),
|
|
65
|
+
getInsertTabs: () => insertTabRegistry.getAll()
|
|
66
|
+
},
|
|
41
67
|
contentComponent: ({
|
|
42
68
|
editorView,
|
|
43
69
|
dispatchAnalyticsEvent,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
|
-
import { useIntl } from 'react-intl
|
|
2
|
+
import { useIntl } from 'react-intl';
|
|
3
3
|
import Button from '@atlaskit/button/new';
|
|
4
4
|
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
5
5
|
import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { useIntl } from 'react-intl
|
|
2
|
+
import { useIntl } from 'react-intl';
|
|
3
3
|
import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
|
|
4
4
|
import { Card, CardLoading } from '@atlaskit/media-card';
|
|
5
5
|
const maxDimensions = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
2
|
import React, { Fragment } from 'react';
|
|
3
|
-
import { useIntl } from 'react-intl
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
4
|
import { isSafeUrl } from '@atlaskit/adf-schema';
|
|
5
5
|
import ButtonGroup from '@atlaskit/button/button-group';
|
|
6
6
|
import Button from '@atlaskit/button/new';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { useIntl } from 'react-intl
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
4
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
5
5
|
import { getDomRefFromSelection } from '@atlaskit/editor-common/get-dom-ref-from-selection';
|
|
6
6
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
@@ -49,6 +49,11 @@ export const MediaInsertPicker = ({
|
|
|
49
49
|
customizedUrlValidation,
|
|
50
50
|
customizedHelperMessage
|
|
51
51
|
}) => {
|
|
52
|
+
var _api$mediaInsert$acti, _api$mediaInsert, _api$mediaInsert$acti2, _api$mediaInsert$acti3;
|
|
53
|
+
// Tabs registered by other plugins via `api.mediaInsert.actions.registerInsertTab(...)`.
|
|
54
|
+
// Read once per render; the registry is mutated only at plugin setup time so this is stable
|
|
55
|
+
// for the lifetime of an editor instance.
|
|
56
|
+
const registeredTabs = (_api$mediaInsert$acti = api === null || api === void 0 ? void 0 : (_api$mediaInsert = api.mediaInsert) === null || _api$mediaInsert === void 0 ? void 0 : (_api$mediaInsert$acti2 = _api$mediaInsert.actions) === null || _api$mediaInsert$acti2 === void 0 ? void 0 : (_api$mediaInsert$acti3 = _api$mediaInsert$acti2.getInsertTabs) === null || _api$mediaInsert$acti3 === void 0 ? void 0 : _api$mediaInsert$acti3.call(_api$mediaInsert$acti2)) !== null && _api$mediaInsert$acti !== void 0 ? _api$mediaInsert$acti : [];
|
|
52
57
|
const {
|
|
53
58
|
mediaProvider,
|
|
54
59
|
isOpen,
|
|
@@ -84,6 +89,11 @@ export const MediaInsertPicker = ({
|
|
|
84
89
|
return null;
|
|
85
90
|
}
|
|
86
91
|
const handleClose = exitMethod => event => {
|
|
92
|
+
// Same as AIImageGenerationPopup: react-select can detach the option
|
|
93
|
+
// before `click` fires, so withOuterListeners treats it as outside.
|
|
94
|
+
if (exitMethod === INPUT_METHOD.MOUSE && event.target instanceof Node && !event.target.isConnected) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
87
97
|
event.preventDefault();
|
|
88
98
|
if (dispatchAnalyticsEvent) {
|
|
89
99
|
const payload = {
|
|
@@ -123,7 +133,9 @@ export const MediaInsertPicker = ({
|
|
|
123
133
|
id: "media-insert-tab-navigation"
|
|
124
134
|
}, /*#__PURE__*/React.createElement(Box, {
|
|
125
135
|
paddingBlockEnd: "space.150"
|
|
126
|
-
}, /*#__PURE__*/React.createElement(TabList, null, !isOnlyExternalLinks && /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.fileTabTitle)), /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.linkTabTitle))
|
|
136
|
+
}, /*#__PURE__*/React.createElement(TabList, null, !isOnlyExternalLinks && /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.fileTabTitle)), /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.linkTabTitle)), registeredTabs.map(tab => /*#__PURE__*/React.createElement(Tab, {
|
|
137
|
+
key: tab.key
|
|
138
|
+
}, tab.label)))), !isOnlyExternalLinks && /*#__PURE__*/React.createElement(CustomTabPanel, null, /*#__PURE__*/React.createElement(LocalMedia, {
|
|
127
139
|
ref: autofocusRef,
|
|
128
140
|
mediaProvider: mediaProvider
|
|
129
141
|
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
|
|
@@ -148,5 +160,20 @@ export const MediaInsertPicker = ({
|
|
|
148
160
|
isOnlyExternalLinks: isOnlyExternalLinks,
|
|
149
161
|
customizedUrlValidation: customizedUrlValidation,
|
|
150
162
|
customizedHelperMessage: customizedHelperMessage
|
|
151
|
-
}))
|
|
163
|
+
})), registeredTabs.map(({
|
|
164
|
+
key,
|
|
165
|
+
component: TabComponent
|
|
166
|
+
}) => /*#__PURE__*/React.createElement(CustomTabPanel, {
|
|
167
|
+
key: key
|
|
168
|
+
}, /*#__PURE__*/React.createElement(TabComponent
|
|
169
|
+
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
|
|
170
|
+
, {
|
|
171
|
+
closeMediaInsertPicker: () => {
|
|
172
|
+
closeMediaInsertPicker();
|
|
173
|
+
focusEditor();
|
|
174
|
+
},
|
|
175
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
176
|
+
insertMediaSingle: insertMediaSingle,
|
|
177
|
+
mediaProvider: mediaProvider
|
|
178
|
+
})))))));
|
|
152
179
|
};
|
|
@@ -6,9 +6,35 @@ import { closeMediaInsertPicker as _closeMediaInsertPicker, showMediaInsertPopup
|
|
|
6
6
|
import { createPlugin } from './pm-plugins/main';
|
|
7
7
|
import { pluginKey } from './pm-plugins/plugin-key';
|
|
8
8
|
import { MediaInsertPicker } from './ui/MediaInsertPicker';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Per-editor-instance registry of insert tabs registered via
|
|
12
|
+
* `actions.registerInsertTab(...)`. Idempotent on `key` so that re-registering
|
|
13
|
+
* the same tab (e.g. on plugin re-init in dev / StrictMode) replaces rather
|
|
14
|
+
* than duplicates.
|
|
15
|
+
*/
|
|
16
|
+
var createInsertTabRegistry = function createInsertTabRegistry() {
|
|
17
|
+
var tabs = [];
|
|
18
|
+
return {
|
|
19
|
+
register: function register(tab) {
|
|
20
|
+
var existingIndex = tabs.findIndex(function (t) {
|
|
21
|
+
return t.key === tab.key;
|
|
22
|
+
});
|
|
23
|
+
if (existingIndex >= 0) {
|
|
24
|
+
tabs[existingIndex] = tab;
|
|
25
|
+
} else {
|
|
26
|
+
tabs.push(tab);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
getAll: function getAll() {
|
|
30
|
+
return tabs;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
};
|
|
9
34
|
export var mediaInsertPlugin = function mediaInsertPlugin(_ref) {
|
|
10
35
|
var api = _ref.api,
|
|
11
36
|
config = _ref.config;
|
|
37
|
+
var insertTabRegistry = createInsertTabRegistry();
|
|
12
38
|
return {
|
|
13
39
|
name: 'mediaInsert',
|
|
14
40
|
pmPlugins: function pmPlugins() {
|
|
@@ -41,6 +67,14 @@ export var mediaInsertPlugin = function mediaInsertPlugin(_ref) {
|
|
|
41
67
|
};
|
|
42
68
|
}
|
|
43
69
|
},
|
|
70
|
+
actions: {
|
|
71
|
+
registerInsertTab: function registerInsertTab(tab) {
|
|
72
|
+
return insertTabRegistry.register(tab);
|
|
73
|
+
},
|
|
74
|
+
getInsertTabs: function getInsertTabs() {
|
|
75
|
+
return insertTabRegistry.getAll();
|
|
76
|
+
}
|
|
77
|
+
},
|
|
44
78
|
contentComponent: function contentComponent(_ref4) {
|
|
45
79
|
var editorView = _ref4.editorView,
|
|
46
80
|
dispatchAnalyticsEvent = _ref4.dispatchAnalyticsEvent,
|
|
@@ -4,7 +4,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
4
4
|
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; }
|
|
5
5
|
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; }
|
|
6
6
|
import React, { useCallback } from 'react';
|
|
7
|
-
import { useIntl } from 'react-intl
|
|
7
|
+
import { useIntl } from 'react-intl';
|
|
8
8
|
import Button from '@atlaskit/button/new';
|
|
9
9
|
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
10
10
|
import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
|
package/dist/esm/ui/MediaCard.js
CHANGED
|
@@ -8,7 +8,7 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
|
8
8
|
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; }
|
|
9
9
|
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; }
|
|
10
10
|
import React, { Fragment } from 'react';
|
|
11
|
-
import { useIntl } from 'react-intl
|
|
11
|
+
import { useIntl } from 'react-intl';
|
|
12
12
|
import { isSafeUrl } from '@atlaskit/adf-schema';
|
|
13
13
|
import ButtonGroup from '@atlaskit/button/button-group';
|
|
14
14
|
import Button from '@atlaskit/button/new';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { useIntl } from 'react-intl
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
4
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
5
5
|
import { getDomRefFromSelection } from '@atlaskit/editor-common/get-dom-ref-from-selection';
|
|
6
6
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
@@ -34,6 +34,7 @@ var CustomTabPanel = function CustomTabPanel(_ref) {
|
|
|
34
34
|
);
|
|
35
35
|
};
|
|
36
36
|
export var MediaInsertPicker = function MediaInsertPicker(_ref2) {
|
|
37
|
+
var _api$mediaInsert$acti, _api$mediaInsert, _api$mediaInsert$getI;
|
|
37
38
|
var api = _ref2.api,
|
|
38
39
|
editorView = _ref2.editorView,
|
|
39
40
|
dispatchAnalyticsEvent = _ref2.dispatchAnalyticsEvent,
|
|
@@ -48,6 +49,10 @@ export var MediaInsertPicker = function MediaInsertPicker(_ref2) {
|
|
|
48
49
|
isOnlyExternalLinks = _ref2$isOnlyExternalL === void 0 ? false : _ref2$isOnlyExternalL,
|
|
49
50
|
customizedUrlValidation = _ref2.customizedUrlValidation,
|
|
50
51
|
customizedHelperMessage = _ref2.customizedHelperMessage;
|
|
52
|
+
// Tabs registered by other plugins via `api.mediaInsert.actions.registerInsertTab(...)`.
|
|
53
|
+
// Read once per render; the registry is mutated only at plugin setup time so this is stable
|
|
54
|
+
// for the lifetime of an editor instance.
|
|
55
|
+
var registeredTabs = (_api$mediaInsert$acti = api === null || api === void 0 || (_api$mediaInsert = api.mediaInsert) === null || _api$mediaInsert === void 0 || (_api$mediaInsert = _api$mediaInsert.actions) === null || _api$mediaInsert === void 0 || (_api$mediaInsert$getI = _api$mediaInsert.getInsertTabs) === null || _api$mediaInsert$getI === void 0 ? void 0 : _api$mediaInsert$getI.call(_api$mediaInsert)) !== null && _api$mediaInsert$acti !== void 0 ? _api$mediaInsert$acti : [];
|
|
51
56
|
var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['media', 'mediaInsert'], function (states) {
|
|
52
57
|
var _states$mediaState, _states$mediaInsertSt, _states$mediaInsertSt2;
|
|
53
58
|
return {
|
|
@@ -82,6 +87,11 @@ export var MediaInsertPicker = function MediaInsertPicker(_ref2) {
|
|
|
82
87
|
}
|
|
83
88
|
var handleClose = function handleClose(exitMethod) {
|
|
84
89
|
return function (event) {
|
|
90
|
+
// Same as AIImageGenerationPopup: react-select can detach the option
|
|
91
|
+
// before `click` fires, so withOuterListeners treats it as outside.
|
|
92
|
+
if (exitMethod === INPUT_METHOD.MOUSE && event.target instanceof Node && !event.target.isConnected) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
85
95
|
event.preventDefault();
|
|
86
96
|
if (dispatchAnalyticsEvent) {
|
|
87
97
|
var payload = {
|
|
@@ -123,7 +133,11 @@ export var MediaInsertPicker = function MediaInsertPicker(_ref2) {
|
|
|
123
133
|
id: "media-insert-tab-navigation"
|
|
124
134
|
}, /*#__PURE__*/React.createElement(Box, {
|
|
125
135
|
paddingBlockEnd: "space.150"
|
|
126
|
-
}, /*#__PURE__*/React.createElement(TabList, null, !isOnlyExternalLinks && /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.fileTabTitle)), /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.linkTabTitle))
|
|
136
|
+
}, /*#__PURE__*/React.createElement(TabList, null, !isOnlyExternalLinks && /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.fileTabTitle)), /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.linkTabTitle)), registeredTabs.map(function (tab) {
|
|
137
|
+
return /*#__PURE__*/React.createElement(Tab, {
|
|
138
|
+
key: tab.key
|
|
139
|
+
}, tab.label);
|
|
140
|
+
}))), !isOnlyExternalLinks && /*#__PURE__*/React.createElement(CustomTabPanel, null, /*#__PURE__*/React.createElement(LocalMedia, {
|
|
127
141
|
ref: autofocusRef,
|
|
128
142
|
mediaProvider: mediaProvider
|
|
129
143
|
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
|
|
@@ -148,6 +162,22 @@ export var MediaInsertPicker = function MediaInsertPicker(_ref2) {
|
|
|
148
162
|
isOnlyExternalLinks: isOnlyExternalLinks,
|
|
149
163
|
customizedUrlValidation: customizedUrlValidation,
|
|
150
164
|
customizedHelperMessage: customizedHelperMessage
|
|
151
|
-
})))
|
|
165
|
+
})), registeredTabs.map(function (_ref3) {
|
|
166
|
+
var key = _ref3.key,
|
|
167
|
+
TabComponent = _ref3.component;
|
|
168
|
+
return /*#__PURE__*/React.createElement(CustomTabPanel, {
|
|
169
|
+
key: key
|
|
170
|
+
}, /*#__PURE__*/React.createElement(TabComponent
|
|
171
|
+
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
|
|
172
|
+
, {
|
|
173
|
+
closeMediaInsertPicker: function closeMediaInsertPicker() {
|
|
174
|
+
_closeMediaInsertPicker();
|
|
175
|
+
focusEditor();
|
|
176
|
+
},
|
|
177
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
178
|
+
insertMediaSingle: insertMediaSingle,
|
|
179
|
+
mediaProvider: mediaProvider
|
|
180
|
+
}));
|
|
181
|
+
})));
|
|
152
182
|
}));
|
|
153
183
|
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { mediaInsertPlugin } from './mediaInsertPlugin';
|
|
2
|
-
export type { MediaInsertPlugin, MediaInsertPluginState, MediaInsertPluginDependencies, MediaInsertPluginCommands, MediaInsertPluginConfig, } from './mediaInsertPluginType';
|
|
2
|
+
export type { MediaInsertPlugin, MediaInsertPluginState, MediaInsertPluginDependencies, MediaInsertPluginCommands, MediaInsertPluginConfig, MediaInsertPluginActions, MediaInsertTabProps, RegisterInsertTab, } from './mediaInsertPluginType';
|
|
@@ -1,8 +1,49 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from 'react';
|
|
2
|
+
import type { AnalyticsEventPayload } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import type { MediaProvider } from '@atlaskit/editor-common/provider-factory';
|
|
1
4
|
import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
|
|
2
5
|
import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
|
|
3
6
|
import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
|
|
4
7
|
import type { MediaPlugin } from '@atlaskit/editor-plugin-media';
|
|
5
|
-
import type { CustomizedHelperMessage } from './types';
|
|
8
|
+
import type { CustomizedHelperMessage, InsertMediaSingle } from './types';
|
|
9
|
+
/**
|
|
10
|
+
* Props provided to a registered insert tab inside the media insert picker.
|
|
11
|
+
*
|
|
12
|
+
* The picker owns the popup chrome and provides the editor-side context
|
|
13
|
+
* needed to insert media; the registering plugin provides the actual UI.
|
|
14
|
+
*/
|
|
15
|
+
export type MediaInsertTabProps = {
|
|
16
|
+
closeMediaInsertPicker: () => void;
|
|
17
|
+
dispatchAnalyticsEvent?: (payload: AnalyticsEventPayload) => void;
|
|
18
|
+
insertMediaSingle: InsertMediaSingle;
|
|
19
|
+
mediaProvider: MediaProvider;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Descriptor for an insert tab registered onto the media insert picker via
|
|
23
|
+
* `api.mediaInsert.actions.registerInsertTab(...)`.
|
|
24
|
+
*
|
|
25
|
+
* Other plugins (typically private `@atlassian/*` plugins like
|
|
26
|
+
* `editor-plugin-ai-image-generation`) call `registerInsertTab` from inside
|
|
27
|
+
* their own setup so the public `editor-plugin-media-insert` package never
|
|
28
|
+
* needs to import them directly.
|
|
29
|
+
*/
|
|
30
|
+
export type RegisterInsertTab = {
|
|
31
|
+
/**
|
|
32
|
+
* Stable identifier for this tab. Used to de-duplicate registrations so
|
|
33
|
+
* calling `registerInsertTab` with the same key twice replaces the prior
|
|
34
|
+
* registration rather than appending a duplicate tab.
|
|
35
|
+
*/
|
|
36
|
+
key: string;
|
|
37
|
+
/**
|
|
38
|
+
* Label rendered inside the tab. Typically a `<FormattedMessage />` so the
|
|
39
|
+
* registering plugin owns its own i18n.
|
|
40
|
+
*/
|
|
41
|
+
label: ReactNode;
|
|
42
|
+
/**
|
|
43
|
+
* Component rendered inside the picker when this tab is active.
|
|
44
|
+
*/
|
|
45
|
+
component: ComponentType<MediaInsertTabProps>;
|
|
46
|
+
};
|
|
6
47
|
export type MediaInsertPluginState = {
|
|
7
48
|
isOpen?: boolean;
|
|
8
49
|
mountInfo?: {
|
|
@@ -21,6 +62,29 @@ export type MediaInsertPluginCommands = {
|
|
|
21
62
|
ref: HTMLElement;
|
|
22
63
|
}) => EditorCommand;
|
|
23
64
|
};
|
|
65
|
+
export type MediaInsertPluginActions = {
|
|
66
|
+
/**
|
|
67
|
+
* Returns the list of insert tabs that have been registered with the
|
|
68
|
+
* picker. Order matches registration order.
|
|
69
|
+
*/
|
|
70
|
+
getInsertTabs: () => RegisterInsertTab[];
|
|
71
|
+
/**
|
|
72
|
+
* Register an additional tab inside the media insert picker. Idempotent
|
|
73
|
+
* by `key`: re-registering with the same key replaces the prior entry.
|
|
74
|
+
*
|
|
75
|
+
* Intended to be called from another plugin's setup, e.g.:
|
|
76
|
+
*
|
|
77
|
+
* ```tsx
|
|
78
|
+
* // inside aiImageGenerationPlugin
|
|
79
|
+
* api?.mediaInsert?.actions.registerInsertTab({
|
|
80
|
+
* key: 'ai-image-generation',
|
|
81
|
+
* label: <FormattedMessage {...messages.generateTabTitle} />,
|
|
82
|
+
* component: MediaInsertImageGenerationTab,
|
|
83
|
+
* });
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
registerInsertTab: (tab: RegisterInsertTab) => void;
|
|
87
|
+
};
|
|
24
88
|
export type MediaInsertPluginConfig = {
|
|
25
89
|
customizedHelperMessage?: CustomizedHelperMessage;
|
|
26
90
|
customizedUrlValidation?: (input: string) => boolean;
|
|
@@ -55,6 +119,7 @@ export type MediaInsertPluginConfig = {
|
|
|
55
119
|
isOnlyExternalLinks?: boolean;
|
|
56
120
|
};
|
|
57
121
|
export type MediaInsertPlugin = NextEditorPlugin<'mediaInsert', {
|
|
122
|
+
actions: MediaInsertPluginActions;
|
|
58
123
|
commands: MediaInsertPluginCommands;
|
|
59
124
|
dependencies: MediaInsertPluginDependencies;
|
|
60
125
|
pluginConfiguration: MediaInsertPluginConfig | undefined;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { mediaInsertPlugin } from './mediaInsertPlugin';
|
|
2
|
-
export type { MediaInsertPlugin, MediaInsertPluginState, MediaInsertPluginDependencies, MediaInsertPluginCommands, MediaInsertPluginConfig, } from './mediaInsertPluginType';
|
|
2
|
+
export type { MediaInsertPlugin, MediaInsertPluginState, MediaInsertPluginDependencies, MediaInsertPluginCommands, MediaInsertPluginConfig, MediaInsertPluginActions, MediaInsertTabProps, RegisterInsertTab, } from './mediaInsertPluginType';
|
|
@@ -1,8 +1,49 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from 'react';
|
|
2
|
+
import type { AnalyticsEventPayload } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import type { MediaProvider } from '@atlaskit/editor-common/provider-factory';
|
|
1
4
|
import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
|
|
2
5
|
import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
|
|
3
6
|
import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
|
|
4
7
|
import type { MediaPlugin } from '@atlaskit/editor-plugin-media';
|
|
5
|
-
import type { CustomizedHelperMessage } from './types';
|
|
8
|
+
import type { CustomizedHelperMessage, InsertMediaSingle } from './types';
|
|
9
|
+
/**
|
|
10
|
+
* Props provided to a registered insert tab inside the media insert picker.
|
|
11
|
+
*
|
|
12
|
+
* The picker owns the popup chrome and provides the editor-side context
|
|
13
|
+
* needed to insert media; the registering plugin provides the actual UI.
|
|
14
|
+
*/
|
|
15
|
+
export type MediaInsertTabProps = {
|
|
16
|
+
closeMediaInsertPicker: () => void;
|
|
17
|
+
dispatchAnalyticsEvent?: (payload: AnalyticsEventPayload) => void;
|
|
18
|
+
insertMediaSingle: InsertMediaSingle;
|
|
19
|
+
mediaProvider: MediaProvider;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Descriptor for an insert tab registered onto the media insert picker via
|
|
23
|
+
* `api.mediaInsert.actions.registerInsertTab(...)`.
|
|
24
|
+
*
|
|
25
|
+
* Other plugins (typically private `@atlassian/*` plugins like
|
|
26
|
+
* `editor-plugin-ai-image-generation`) call `registerInsertTab` from inside
|
|
27
|
+
* their own setup so the public `editor-plugin-media-insert` package never
|
|
28
|
+
* needs to import them directly.
|
|
29
|
+
*/
|
|
30
|
+
export type RegisterInsertTab = {
|
|
31
|
+
/**
|
|
32
|
+
* Stable identifier for this tab. Used to de-duplicate registrations so
|
|
33
|
+
* calling `registerInsertTab` with the same key twice replaces the prior
|
|
34
|
+
* registration rather than appending a duplicate tab.
|
|
35
|
+
*/
|
|
36
|
+
key: string;
|
|
37
|
+
/**
|
|
38
|
+
* Label rendered inside the tab. Typically a `<FormattedMessage />` so the
|
|
39
|
+
* registering plugin owns its own i18n.
|
|
40
|
+
*/
|
|
41
|
+
label: ReactNode;
|
|
42
|
+
/**
|
|
43
|
+
* Component rendered inside the picker when this tab is active.
|
|
44
|
+
*/
|
|
45
|
+
component: ComponentType<MediaInsertTabProps>;
|
|
46
|
+
};
|
|
6
47
|
export type MediaInsertPluginState = {
|
|
7
48
|
isOpen?: boolean;
|
|
8
49
|
mountInfo?: {
|
|
@@ -21,6 +62,29 @@ export type MediaInsertPluginCommands = {
|
|
|
21
62
|
ref: HTMLElement;
|
|
22
63
|
}) => EditorCommand;
|
|
23
64
|
};
|
|
65
|
+
export type MediaInsertPluginActions = {
|
|
66
|
+
/**
|
|
67
|
+
* Returns the list of insert tabs that have been registered with the
|
|
68
|
+
* picker. Order matches registration order.
|
|
69
|
+
*/
|
|
70
|
+
getInsertTabs: () => RegisterInsertTab[];
|
|
71
|
+
/**
|
|
72
|
+
* Register an additional tab inside the media insert picker. Idempotent
|
|
73
|
+
* by `key`: re-registering with the same key replaces the prior entry.
|
|
74
|
+
*
|
|
75
|
+
* Intended to be called from another plugin's setup, e.g.:
|
|
76
|
+
*
|
|
77
|
+
* ```tsx
|
|
78
|
+
* // inside aiImageGenerationPlugin
|
|
79
|
+
* api?.mediaInsert?.actions.registerInsertTab({
|
|
80
|
+
* key: 'ai-image-generation',
|
|
81
|
+
* label: <FormattedMessage {...messages.generateTabTitle} />,
|
|
82
|
+
* component: MediaInsertImageGenerationTab,
|
|
83
|
+
* });
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
registerInsertTab: (tab: RegisterInsertTab) => void;
|
|
87
|
+
};
|
|
24
88
|
export type MediaInsertPluginConfig = {
|
|
25
89
|
customizedHelperMessage?: CustomizedHelperMessage;
|
|
26
90
|
customizedUrlValidation?: (input: string) => boolean;
|
|
@@ -55,6 +119,7 @@ export type MediaInsertPluginConfig = {
|
|
|
55
119
|
isOnlyExternalLinks?: boolean;
|
|
56
120
|
};
|
|
57
121
|
export type MediaInsertPlugin = NextEditorPlugin<'mediaInsert', {
|
|
122
|
+
actions: MediaInsertPluginActions;
|
|
58
123
|
commands: MediaInsertPluginCommands;
|
|
59
124
|
dependencies: MediaInsertPluginDependencies;
|
|
60
125
|
pluginConfiguration: MediaInsertPluginConfig | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-media-insert",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "23.1.0",
|
|
4
4
|
"description": "Media Insert plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -21,31 +21,31 @@
|
|
|
21
21
|
],
|
|
22
22
|
"atlaskit:src": "src/index.ts",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@atlaskit/adf-schema": "^52.
|
|
24
|
+
"@atlaskit/adf-schema": "^52.7.0",
|
|
25
25
|
"@atlaskit/button": "^23.11.0",
|
|
26
|
-
"@atlaskit/editor-plugin-analytics": "^
|
|
27
|
-
"@atlaskit/editor-plugin-media": "^
|
|
26
|
+
"@atlaskit/editor-plugin-analytics": "^10.0.0",
|
|
27
|
+
"@atlaskit/editor-plugin-media": "^12.2.0",
|
|
28
28
|
"@atlaskit/editor-prosemirror": "^7.3.0",
|
|
29
29
|
"@atlaskit/editor-shared-styles": "^3.10.0",
|
|
30
30
|
"@atlaskit/form": "^15.5.0",
|
|
31
|
-
"@atlaskit/icon": "^34.
|
|
32
|
-
"@atlaskit/media-card": "^80.
|
|
33
|
-
"@atlaskit/media-client": "^36.
|
|
34
|
-
"@atlaskit/media-client-react": "^5.
|
|
35
|
-
"@atlaskit/media-picker": "^71.
|
|
31
|
+
"@atlaskit/icon": "^34.3.0",
|
|
32
|
+
"@atlaskit/media-card": "^80.4.0",
|
|
33
|
+
"@atlaskit/media-client": "^36.1.0",
|
|
34
|
+
"@atlaskit/media-client-react": "^5.1.0",
|
|
35
|
+
"@atlaskit/media-picker": "^71.2.0",
|
|
36
36
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
37
37
|
"@atlaskit/primitives": "^19.0.0",
|
|
38
38
|
"@atlaskit/section-message": "^8.12.0",
|
|
39
39
|
"@atlaskit/tabs": "^19.1.0",
|
|
40
40
|
"@atlaskit/textfield": "^8.3.0",
|
|
41
|
-
"@babel/runtime": "^7.0.0"
|
|
42
|
-
"react-intl-next": "npm:react-intl@^5.18.1"
|
|
41
|
+
"@babel/runtime": "^7.0.0"
|
|
43
42
|
},
|
|
44
43
|
"peerDependencies": {
|
|
45
|
-
"@atlaskit/editor-common": "^
|
|
44
|
+
"@atlaskit/editor-common": "^114.14.0",
|
|
46
45
|
"@atlaskit/tokens": "^13.0.0",
|
|
47
46
|
"react": "^18.2.0",
|
|
48
|
-
"react-dom": "^18.2.0"
|
|
47
|
+
"react-dom": "^18.2.0",
|
|
48
|
+
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|
|
49
49
|
},
|
|
50
50
|
"techstack": {
|
|
51
51
|
"@atlassian/frontend": {
|
|
@@ -92,5 +92,8 @@
|
|
|
92
92
|
"platform_editor_nov_a11y_fixes": {
|
|
93
93
|
"type": "boolean"
|
|
94
94
|
}
|
|
95
|
+
},
|
|
96
|
+
"devDependencies": {
|
|
97
|
+
"react-intl": "^6.6.2"
|
|
95
98
|
}
|
|
96
99
|
}
|