@atlaskit/editor-plugin-quick-insert 15.1.4 → 16.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 +20 -0
- package/dist/cjs/entry-points/registry-element-browser.js +12 -0
- package/dist/cjs/quickInsertPlugin.js +10 -3
- package/dist/cjs/ui/RegistryElementBrowser/RegistryElementBrowser.compiled.css +2 -0
- package/dist/cjs/ui/RegistryElementBrowser/RegistryElementBrowser.js +176 -0
- package/dist/cjs/ui/RegistryElementBrowser/RegistryElementBrowserCategories.compiled.css +2 -0
- package/dist/cjs/ui/RegistryElementBrowser/RegistryElementBrowserCategories.js +52 -0
- package/dist/cjs/ui/RegistryElementBrowser/RegistryElementBrowserFooter.js +40 -0
- package/dist/cjs/ui/RegistryElementBrowser/RegistryElementBrowserSearchResults.compiled.css +2 -0
- package/dist/cjs/ui/RegistryElementBrowser/RegistryElementBrowserSearchResults.js +123 -0
- package/dist/cjs/ui/RegistryElementBrowser/index.js +144 -0
- package/dist/cjs/ui/RegistryElementBrowser/model.js +129 -0
- package/dist/es2019/entry-points/registry-element-browser.js +2 -0
- package/dist/es2019/quickInsertPlugin.js +8 -3
- package/dist/es2019/ui/RegistryElementBrowser/RegistryElementBrowser.compiled.css +2 -0
- package/dist/es2019/ui/RegistryElementBrowser/RegistryElementBrowser.js +147 -0
- package/dist/es2019/ui/RegistryElementBrowser/RegistryElementBrowserCategories.compiled.css +2 -0
- package/dist/es2019/ui/RegistryElementBrowser/RegistryElementBrowserCategories.js +55 -0
- package/dist/es2019/ui/RegistryElementBrowser/RegistryElementBrowserFooter.js +35 -0
- package/dist/es2019/ui/RegistryElementBrowser/RegistryElementBrowserSearchResults.compiled.css +2 -0
- package/dist/es2019/ui/RegistryElementBrowser/RegistryElementBrowserSearchResults.js +112 -0
- package/dist/es2019/ui/RegistryElementBrowser/index.js +123 -0
- package/dist/es2019/ui/RegistryElementBrowser/model.js +97 -0
- package/dist/esm/entry-points/registry-element-browser.js +2 -0
- package/dist/esm/quickInsertPlugin.js +10 -3
- package/dist/esm/ui/RegistryElementBrowser/RegistryElementBrowser.compiled.css +2 -0
- package/dist/esm/ui/RegistryElementBrowser/RegistryElementBrowser.js +167 -0
- package/dist/esm/ui/RegistryElementBrowser/RegistryElementBrowserCategories.compiled.css +2 -0
- package/dist/esm/ui/RegistryElementBrowser/RegistryElementBrowserCategories.js +45 -0
- package/dist/esm/ui/RegistryElementBrowser/RegistryElementBrowserFooter.js +33 -0
- package/dist/esm/ui/RegistryElementBrowser/RegistryElementBrowserSearchResults.compiled.css +2 -0
- package/dist/esm/ui/RegistryElementBrowser/RegistryElementBrowserSearchResults.js +114 -0
- package/dist/esm/ui/RegistryElementBrowser/index.js +135 -0
- package/dist/esm/ui/RegistryElementBrowser/model.js +122 -0
- package/dist/types/entry-points/registry-element-browser.d.ts +1 -0
- package/dist/types/ui/RegistryElementBrowser/RegistryElementBrowser.d.ts +25 -0
- package/dist/types/ui/RegistryElementBrowser/RegistryElementBrowserCategories.d.ts +14 -0
- package/dist/types/ui/RegistryElementBrowser/RegistryElementBrowserFooter.d.ts +9 -0
- package/dist/types/ui/RegistryElementBrowser/RegistryElementBrowserSearchResults.d.ts +31 -0
- package/dist/types/ui/RegistryElementBrowser/index.d.ts +9 -0
- package/dist/types/ui/RegistryElementBrowser/model.d.ts +31 -0
- package/package.json +12 -7
- package/registry-element-browser/package.json +10 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const compareRanks = (left, right) => {
|
|
2
|
+
for (let index = 0; index < Math.max(left.length, right.length); index++) {
|
|
3
|
+
var _left$index, _right$index;
|
|
4
|
+
const difference = ((_left$index = left[index]) !== null && _left$index !== void 0 ? _left$index : 0) - ((_right$index = right[index]) !== null && _right$index !== void 0 ? _right$index : 0);
|
|
5
|
+
if (difference !== 0) {
|
|
6
|
+
return difference;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return 0;
|
|
10
|
+
};
|
|
11
|
+
const isVisible = registration => {
|
|
12
|
+
var _registration$isHidde;
|
|
13
|
+
return ((_registration$isHidde = registration.isHidden) === null || _registration$isHidde === void 0 ? void 0 : _registration$isHidde.call(registration)) !== true;
|
|
14
|
+
};
|
|
15
|
+
const getChildren = (components, parentKey) => components.filter(component => {
|
|
16
|
+
var _component$parents;
|
|
17
|
+
return isVisible(component) && ((_component$parents = component.parents) === null || _component$parents === void 0 ? void 0 : _component$parents.some(parent => parent.key === parentKey));
|
|
18
|
+
});
|
|
19
|
+
const getParentRank = (registration, parentKey) => {
|
|
20
|
+
var _registration$parents, _registration$parents2, _registration$parents3;
|
|
21
|
+
return (_registration$parents = (_registration$parents2 = registration.parents) === null || _registration$parents2 === void 0 ? void 0 : (_registration$parents3 = _registration$parents2.find(parent => parent.key === parentKey)) === null || _registration$parents3 === void 0 ? void 0 : _registration$parents3.rank) !== null && _registration$parents !== void 0 ? _registration$parents : Number.MAX_SAFE_INTEGER;
|
|
22
|
+
};
|
|
23
|
+
const getDescendantItems = (components, parentKey, ancestorRanks, sectionKey) => getChildren(components, parentKey).flatMap(component => {
|
|
24
|
+
const ranks = [...ancestorRanks, getParentRank(component, parentKey)];
|
|
25
|
+
if (component.type === 'menu-item') {
|
|
26
|
+
return component.component ? [{
|
|
27
|
+
ranks,
|
|
28
|
+
registration: component,
|
|
29
|
+
sectionKeys: [sectionKey]
|
|
30
|
+
}] : [];
|
|
31
|
+
}
|
|
32
|
+
return getDescendantItems(components, component.key, ranks, sectionKey);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Builds the Element Browser's immutable open-time view of the Quick Insert registry.
|
|
37
|
+
* The caller provides only components rooted at the Quick Insert menu surface.
|
|
38
|
+
*/
|
|
39
|
+
export const createRegistryElementBrowserModel = (components, {
|
|
40
|
+
footerKey,
|
|
41
|
+
overflowKeys,
|
|
42
|
+
recommendedSectionKey,
|
|
43
|
+
rootKey
|
|
44
|
+
}) => {
|
|
45
|
+
const excludedKeys = new Set([footerKey, recommendedSectionKey, ...overflowKeys]);
|
|
46
|
+
const visibleComponents = components.filter(component => isVisible(component) && !excludedKeys.has(component.key));
|
|
47
|
+
const sections = getChildren(visibleComponents, rootKey).filter(component => component.type === 'menu-section').map(section => ({
|
|
48
|
+
key: section.key,
|
|
49
|
+
rank: getParentRank(section, rootKey)
|
|
50
|
+
})).sort((left, right) => left.rank - right.rank);
|
|
51
|
+
const itemByKey = new Map();
|
|
52
|
+
sections.forEach(section => {
|
|
53
|
+
getDescendantItems(visibleComponents, section.key, [section.rank], section.key).forEach(item => {
|
|
54
|
+
const existing = itemByKey.get(item.registration.key);
|
|
55
|
+
if (!existing) {
|
|
56
|
+
itemByKey.set(item.registration.key, item);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const sectionKeys = [...new Set([...existing.sectionKeys, ...item.sectionKeys])];
|
|
60
|
+
itemByKey.set(item.registration.key, compareRanks(item.ranks, existing.ranks) < 0 ? {
|
|
61
|
+
...item,
|
|
62
|
+
sectionKeys
|
|
63
|
+
} : {
|
|
64
|
+
...existing,
|
|
65
|
+
sectionKeys
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
items: [...itemByKey.values()].sort((left, right) => compareRanks(left.ranks, right.ranks)),
|
|
71
|
+
sections
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
export const getInitialRegistryElementBrowserSection = (model, requestedSection) => model.sections.some(section => section.key === requestedSection) ? requestedSection : undefined;
|
|
75
|
+
export const getRegistryElementBrowserItems = ({
|
|
76
|
+
formatMessage,
|
|
77
|
+
model,
|
|
78
|
+
query,
|
|
79
|
+
section
|
|
80
|
+
}) => {
|
|
81
|
+
const normalizedQuery = query.trim();
|
|
82
|
+
const items = section ? model.items.filter(item => item.sectionKeys.includes(section)) : model.items;
|
|
83
|
+
if (!normalizedQuery) {
|
|
84
|
+
return items;
|
|
85
|
+
}
|
|
86
|
+
return items.flatMap(item => {
|
|
87
|
+
var _item$registration$ma, _item$registration;
|
|
88
|
+
const result = (_item$registration$ma = (_item$registration = item.registration).match) === null || _item$registration$ma === void 0 ? void 0 : _item$registration$ma.call(_item$registration, {
|
|
89
|
+
formatMessage,
|
|
90
|
+
query: normalizedQuery
|
|
91
|
+
});
|
|
92
|
+
return result ? [{
|
|
93
|
+
...item,
|
|
94
|
+
score: Math.min(1, Math.max(0, result.score))
|
|
95
|
+
}] : [];
|
|
96
|
+
}).sort((left, right) => left.score - right.score || compareRanks(left.ranks, right.ranks) || left.registration.key.localeCompare(right.registration.key));
|
|
97
|
+
};
|
|
@@ -22,6 +22,7 @@ import { pluginKey } from './pm-plugins/plugin-key';
|
|
|
22
22
|
import { getLegacyCompatibleComponents } from './ui/getLegacyCompatibleComponents';
|
|
23
23
|
import { getQuickInsertComponents } from './ui/getQuickInsertComponents';
|
|
24
24
|
import ModalElementBrowser from './ui/ModalElementBrowser';
|
|
25
|
+
import { RegistryElementBrowserContainer } from './ui/RegistryElementBrowser';
|
|
25
26
|
import { getQuickInsertSuggestions, withLayoutQuickInsertPrioritySorting } from './ui/search';
|
|
26
27
|
export var quickInsertPlugin = function quickInsertPlugin(_ref) {
|
|
27
28
|
var options = _ref.config,
|
|
@@ -81,7 +82,9 @@ export var quickInsertPlugin = function quickInsertPlugin(_ref) {
|
|
|
81
82
|
return {
|
|
82
83
|
title: formatMessage(messages.viewMore),
|
|
83
84
|
ariaLabel: formatMessage(messages.viewMoreAriaLabel),
|
|
84
|
-
onClick:
|
|
85
|
+
onClick: function onClick(props) {
|
|
86
|
+
return openElementBrowser()(props);
|
|
87
|
+
},
|
|
85
88
|
iconBefore: /*#__PURE__*/React.createElement(ShowMoreHorizontalIcon, {
|
|
86
89
|
label: ""
|
|
87
90
|
})
|
|
@@ -108,7 +111,7 @@ export var quickInsertPlugin = function quickInsertPlugin(_ref) {
|
|
|
108
111
|
tr: tr
|
|
109
112
|
});
|
|
110
113
|
}
|
|
111
|
-
return openElementBrowserCommand(options)({
|
|
114
|
+
return (isExperimentEnabled('platform_editor_slash_command') ? openElementBrowserCommand(options) : _openElementBrowserModal)({
|
|
112
115
|
tr: tr
|
|
113
116
|
});
|
|
114
117
|
};
|
|
@@ -153,7 +156,11 @@ export var quickInsertPlugin = function quickInsertPlugin(_ref) {
|
|
|
153
156
|
return null;
|
|
154
157
|
}
|
|
155
158
|
if (options !== null && options !== void 0 && options.enableElementBrowser) {
|
|
156
|
-
return /*#__PURE__*/React.createElement(
|
|
159
|
+
return isExperimentEnabled('platform_editor_slash_command') && api !== null && api !== void 0 && api.uiControlRegistry ? /*#__PURE__*/React.createElement(RegistryElementBrowserContainer, {
|
|
160
|
+
editorView: editorView,
|
|
161
|
+
helpUrl: options === null || options === void 0 ? void 0 : options.elementBrowserHelpUrl,
|
|
162
|
+
pluginInjectionAPI: api
|
|
163
|
+
}) : /*#__PURE__*/React.createElement(ModalElementBrowser, {
|
|
157
164
|
editorView: editorView,
|
|
158
165
|
helpUrl: options === null || options === void 0 ? void 0 : options.elementBrowserHelpUrl,
|
|
159
166
|
pluginInjectionAPI: api
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/* RegistryElementBrowser.tsx generated by @compiled/babel-plugin v2.0.0 */
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
|
+
import "./RegistryElementBrowser.compiled.css";
|
|
4
|
+
import { ax, ix } from "@compiled/react/runtime";
|
|
5
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
6
|
+
import { useIntl } from 'react-intl';
|
|
7
|
+
import Heading from '@atlaskit/heading/heading';
|
|
8
|
+
import { MENU, RECOMMENDED_SECTION } from '@atlaskit/editor-common/quick-insert/keys';
|
|
9
|
+
import { getMenuFooterSectionKey } from '@atlaskit/editor-common/type-ahead-get-menu-footer-section-key';
|
|
10
|
+
import { getSectionOverflowItemKey } from '@atlaskit/editor-common/type-ahead-get-section-overflow-item-key';
|
|
11
|
+
import Modal, { ModalBody, ModalFooter, ModalHeader, ModalTransition } from '@atlaskit/modal-dialog';
|
|
12
|
+
import { createRegistryElementBrowserModel, getInitialRegistryElementBrowserSection, getRegistryElementBrowserItems } from './model';
|
|
13
|
+
import { RegistryElementBrowserCategories } from './RegistryElementBrowserCategories';
|
|
14
|
+
import { RegistryElementBrowserFooter } from './RegistryElementBrowserFooter';
|
|
15
|
+
import { RegistryElementBrowserSearchResults } from './RegistryElementBrowserSearchResults';
|
|
16
|
+
var browserLayoutStyles = null;
|
|
17
|
+
var resultsId = 'registry-element-browser-results';
|
|
18
|
+
export var RegistryElementBrowser = function RegistryElementBrowser(_ref) {
|
|
19
|
+
var components = _ref.components,
|
|
20
|
+
emptyStateHandler = _ref.emptyStateHandler,
|
|
21
|
+
defaultSection = _ref.defaultSection,
|
|
22
|
+
helpUrl = _ref.helpUrl,
|
|
23
|
+
editorView = _ref.editorView,
|
|
24
|
+
isOffline = _ref.isOffline,
|
|
25
|
+
isOpen = _ref.isOpen,
|
|
26
|
+
onClearSelection = _ref.onClearSelection,
|
|
27
|
+
onClose = _ref.onClose,
|
|
28
|
+
onCloseComplete = _ref.onCloseComplete,
|
|
29
|
+
onConfirmInsert = _ref.onConfirmInsert,
|
|
30
|
+
onSelect = _ref.onSelect;
|
|
31
|
+
var _useIntl = useIntl(),
|
|
32
|
+
formatMessage = _useIntl.formatMessage;
|
|
33
|
+
var model = useMemo(function () {
|
|
34
|
+
return createRegistryElementBrowserModel(components, {
|
|
35
|
+
footerKey: getMenuFooterSectionKey(MENU.key),
|
|
36
|
+
overflowKeys: new Set(components.filter(function (component) {
|
|
37
|
+
return component.type === 'menu-section';
|
|
38
|
+
}).map(function (component) {
|
|
39
|
+
return getSectionOverflowItemKey(component.key);
|
|
40
|
+
})),
|
|
41
|
+
recommendedSectionKey: RECOMMENDED_SECTION.key,
|
|
42
|
+
rootKey: MENU.key
|
|
43
|
+
});
|
|
44
|
+
}, [components]);
|
|
45
|
+
var _useState = useState(''),
|
|
46
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
47
|
+
query = _useState2[0],
|
|
48
|
+
setQuery = _useState2[1];
|
|
49
|
+
var _useState3 = useState(function () {
|
|
50
|
+
return getInitialRegistryElementBrowserSection(model, defaultSection);
|
|
51
|
+
}),
|
|
52
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
53
|
+
section = _useState4[0],
|
|
54
|
+
setSection = _useState4[1];
|
|
55
|
+
var _useState5 = useState(),
|
|
56
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
57
|
+
selectedKey = _useState6[0],
|
|
58
|
+
setSelectedKey = _useState6[1];
|
|
59
|
+
var wasOpen = useRef(false);
|
|
60
|
+
var previousIsOffline = useRef(isOffline);
|
|
61
|
+
useEffect(function () {
|
|
62
|
+
if (isOpen && !wasOpen.current) {
|
|
63
|
+
setQuery('');
|
|
64
|
+
setSection(getInitialRegistryElementBrowserSection(model, defaultSection));
|
|
65
|
+
// This clears local visual state and the parent-held insertion handler together.
|
|
66
|
+
// eslint-disable-next-line @atlassian/perf-linting/no-chain-state-updates
|
|
67
|
+
setSelectedKey(undefined);
|
|
68
|
+
onClearSelection();
|
|
69
|
+
}
|
|
70
|
+
wasOpen.current = isOpen;
|
|
71
|
+
}, [defaultSection, isOpen, model, onClearSelection]);
|
|
72
|
+
var items = useMemo(function () {
|
|
73
|
+
return getRegistryElementBrowserItems({
|
|
74
|
+
formatMessage: formatMessage,
|
|
75
|
+
model: model,
|
|
76
|
+
query: query,
|
|
77
|
+
section: query ? undefined : section
|
|
78
|
+
});
|
|
79
|
+
}, [formatMessage, model, query, section]);
|
|
80
|
+
useEffect(function () {
|
|
81
|
+
if (previousIsOffline.current !== isOffline) {
|
|
82
|
+
setSelectedKey(undefined);
|
|
83
|
+
onClearSelection();
|
|
84
|
+
}
|
|
85
|
+
previousIsOffline.current = isOffline;
|
|
86
|
+
}, [isOffline, onClearSelection]);
|
|
87
|
+
var onSearchChange = useCallback(function (event) {
|
|
88
|
+
setQuery(event.currentTarget.value);
|
|
89
|
+
setSection(undefined);
|
|
90
|
+
setSelectedKey(undefined);
|
|
91
|
+
onClearSelection();
|
|
92
|
+
}, [onClearSelection]);
|
|
93
|
+
var onSectionClick = useCallback(function (event) {
|
|
94
|
+
setQuery('');
|
|
95
|
+
setSection(event.currentTarget.dataset.section || undefined);
|
|
96
|
+
setSelectedKey(undefined);
|
|
97
|
+
onClearSelection();
|
|
98
|
+
}, [onClearSelection]);
|
|
99
|
+
var onRegistrySelect = useCallback(function (key, handler) {
|
|
100
|
+
setSelectedKey(key);
|
|
101
|
+
onSelect(handler);
|
|
102
|
+
}, [onSelect]);
|
|
103
|
+
var onKeyDown = useCallback(function (event) {
|
|
104
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
105
|
+
var _resultCollection$que;
|
|
106
|
+
var resultCollection = event.currentTarget.ownerDocument.getElementById(resultsId);
|
|
107
|
+
var options = Array.from((_resultCollection$que = resultCollection === null || resultCollection === void 0 ? void 0 : resultCollection.querySelectorAll('[role="option"]:not([aria-disabled="true"]):not([disabled])')) !== null && _resultCollection$que !== void 0 ? _resultCollection$que : []);
|
|
108
|
+
var currentIndex = options.findIndex(function (option) {
|
|
109
|
+
return option === event.currentTarget.ownerDocument.activeElement;
|
|
110
|
+
});
|
|
111
|
+
var nextIndex = event.key === 'ArrowDown' ? currentIndex + 1 : currentIndex - 1;
|
|
112
|
+
var nextOption = options.at(nextIndex);
|
|
113
|
+
if (nextOption) {
|
|
114
|
+
event.preventDefault();
|
|
115
|
+
nextOption.focus();
|
|
116
|
+
}
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (event.key === 'Escape') {
|
|
120
|
+
event.preventDefault();
|
|
121
|
+
onClose();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (event.key === 'Enter' && selectedKey) {
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
onConfirmInsert();
|
|
127
|
+
}
|
|
128
|
+
}, [onClose, onConfirmInsert, selectedKey]);
|
|
129
|
+
return /*#__PURE__*/React.createElement(ModalTransition, null, isOpen && /*#__PURE__*/React.createElement(Modal, {
|
|
130
|
+
label: formatMessage({
|
|
131
|
+
defaultMessage: 'Insert elements',
|
|
132
|
+
id: 'editor.quick-insert.title'
|
|
133
|
+
}),
|
|
134
|
+
onClose: onClose,
|
|
135
|
+
onCloseComplete: onCloseComplete,
|
|
136
|
+
width: "x-large"
|
|
137
|
+
}, /*#__PURE__*/React.createElement(ModalHeader, null, /*#__PURE__*/React.createElement(Heading, {
|
|
138
|
+
size: "medium"
|
|
139
|
+
}, formatMessage({
|
|
140
|
+
defaultMessage: 'Insert elements',
|
|
141
|
+
id: 'editor.quick-insert.title'
|
|
142
|
+
}))), /*#__PURE__*/React.createElement(ModalBody, null, /*#__PURE__*/React.createElement("div", {
|
|
143
|
+
className: ax(["_zulp1ejb _1e0c11p5 _yv0eo9bh"])
|
|
144
|
+
}, /*#__PURE__*/React.createElement(RegistryElementBrowserCategories, {
|
|
145
|
+
query: query,
|
|
146
|
+
section: section,
|
|
147
|
+
sections: model.sections,
|
|
148
|
+
onSectionClick: onSectionClick
|
|
149
|
+
}), /*#__PURE__*/React.createElement(RegistryElementBrowserSearchResults, {
|
|
150
|
+
editorView: editorView,
|
|
151
|
+
emptyStateHandler: emptyStateHandler,
|
|
152
|
+
isOffline: isOffline,
|
|
153
|
+
items: items,
|
|
154
|
+
query: query,
|
|
155
|
+
resultsId: resultsId,
|
|
156
|
+
section: section,
|
|
157
|
+
selectedKey: selectedKey,
|
|
158
|
+
onKeyDown: onKeyDown,
|
|
159
|
+
onSearchChange: onSearchChange,
|
|
160
|
+
onSelect: onRegistrySelect
|
|
161
|
+
}))), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(RegistryElementBrowserFooter, {
|
|
162
|
+
helpUrl: helpUrl,
|
|
163
|
+
isInsertEnabled: Boolean(selectedKey),
|
|
164
|
+
onClose: onClose,
|
|
165
|
+
onConfirmInsert: onConfirmInsert
|
|
166
|
+
}))));
|
|
167
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/* RegistryElementBrowserCategories.tsx generated by @compiled/babel-plugin v2.0.0 */
|
|
2
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
|
+
import "./RegistryElementBrowserCategories.compiled.css";
|
|
4
|
+
import { ax, ix } from "@compiled/react/runtime";
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { useIntl } from 'react-intl';
|
|
7
|
+
import Button from '@atlaskit/button/default/button';
|
|
8
|
+
import { BLOCK_TEMPLATES_SECTION, DATA_AND_CHARTS_SECTION, EMBED_SECTION, MEDIA_SECTION, OTHER_SECTION, ROVO_SECTION, STRUCTURE_SECTION, TEXT_FORMATTING_SECTION } from '@atlaskit/editor-common/quick-insert/keys';
|
|
9
|
+
import { messages } from '@atlaskit/editor-common/quick-insert/messages';
|
|
10
|
+
var sectionMessages = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, BLOCK_TEMPLATES_SECTION.key, messages.categoryBlockTemplates), DATA_AND_CHARTS_SECTION.key, messages.categoryDataAndCharts), EMBED_SECTION.key, messages.categoryEmbed), MEDIA_SECTION.key, messages.categoryMedia), OTHER_SECTION.key, messages.categoryOther), ROVO_SECTION.key, messages.categoryRovo), STRUCTURE_SECTION.key, messages.categoryStructure), TEXT_FORMATTING_SECTION.key, messages.categoryTextFormatting);
|
|
11
|
+
var categoryGridStyles = null;
|
|
12
|
+
export var RegistryElementBrowserCategories = function RegistryElementBrowserCategories(_ref) {
|
|
13
|
+
var query = _ref.query,
|
|
14
|
+
section = _ref.section,
|
|
15
|
+
sections = _ref.sections,
|
|
16
|
+
onSectionClick = _ref.onSectionClick;
|
|
17
|
+
var _useIntl = useIntl(),
|
|
18
|
+
formatMessage = _useIntl.formatMessage;
|
|
19
|
+
var isAllSelected = section === undefined && !query;
|
|
20
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
21
|
+
"aria-label": formatMessage({
|
|
22
|
+
defaultMessage: 'Element categories',
|
|
23
|
+
id: 'editor.quick-insert.categories-label'
|
|
24
|
+
}),
|
|
25
|
+
"data-testid": "registry-element-browser-categories",
|
|
26
|
+
className: ax(["_zulpu2gc _1e0c11p5 _yv0e9sye"])
|
|
27
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
28
|
+
appearance: isAllSelected ? 'primary' : 'subtle',
|
|
29
|
+
"aria-pressed": isAllSelected,
|
|
30
|
+
"data-section": "",
|
|
31
|
+
onClick: onSectionClick
|
|
32
|
+
}, formatMessage({
|
|
33
|
+
defaultMessage: 'All',
|
|
34
|
+
id: 'editor.quick-insert.all'
|
|
35
|
+
})), sections.map(function (entry) {
|
|
36
|
+
var _sectionMessages2;
|
|
37
|
+
return /*#__PURE__*/React.createElement(Button, {
|
|
38
|
+
appearance: section === entry.key && !query ? 'primary' : 'subtle',
|
|
39
|
+
"aria-pressed": section === entry.key && !query,
|
|
40
|
+
"data-section": entry.key,
|
|
41
|
+
key: entry.key,
|
|
42
|
+
onClick: onSectionClick
|
|
43
|
+
}, formatMessage((_sectionMessages2 = sectionMessages[entry.key]) !== null && _sectionMessages2 !== void 0 ? _sectionMessages2 : messages.categoryOther));
|
|
44
|
+
}));
|
|
45
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useIntl } from 'react-intl';
|
|
3
|
+
import Button from '@atlaskit/button/default/button';
|
|
4
|
+
import LinkButton from '@atlaskit/button/link';
|
|
5
|
+
export var RegistryElementBrowserFooter = function RegistryElementBrowserFooter(_ref) {
|
|
6
|
+
var helpUrl = _ref.helpUrl,
|
|
7
|
+
isInsertEnabled = _ref.isInsertEnabled,
|
|
8
|
+
onClose = _ref.onClose,
|
|
9
|
+
onConfirmInsert = _ref.onConfirmInsert;
|
|
10
|
+
var _useIntl = useIntl(),
|
|
11
|
+
formatMessage = _useIntl.formatMessage;
|
|
12
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, helpUrl && /*#__PURE__*/React.createElement(LinkButton, {
|
|
13
|
+
appearance: "subtle",
|
|
14
|
+
href: helpUrl,
|
|
15
|
+
target: "_blank"
|
|
16
|
+
}, formatMessage({
|
|
17
|
+
defaultMessage: 'Help',
|
|
18
|
+
id: 'editor.quick-insert.help'
|
|
19
|
+
})), /*#__PURE__*/React.createElement(Button, {
|
|
20
|
+
appearance: "subtle",
|
|
21
|
+
onClick: onClose
|
|
22
|
+
}, formatMessage({
|
|
23
|
+
defaultMessage: 'Close',
|
|
24
|
+
id: 'editor.quick-insert.close'
|
|
25
|
+
})), /*#__PURE__*/React.createElement(Button, {
|
|
26
|
+
appearance: "primary",
|
|
27
|
+
isDisabled: !isInsertEnabled,
|
|
28
|
+
onClick: onConfirmInsert
|
|
29
|
+
}, formatMessage({
|
|
30
|
+
defaultMessage: 'Insert',
|
|
31
|
+
id: 'editor.quick-insert.insert'
|
|
32
|
+
})));
|
|
33
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/* RegistryElementBrowserSearchResults.tsx generated by @compiled/babel-plugin v2.0.0 */
|
|
2
|
+
import "./RegistryElementBrowserSearchResults.compiled.css";
|
|
3
|
+
import { ax, ix } from "@compiled/react/runtime";
|
|
4
|
+
import React, { useMemo } from 'react';
|
|
5
|
+
import { useIntl } from 'react-intl';
|
|
6
|
+
import LinkButton from '@atlaskit/button/link';
|
|
7
|
+
import { QuickInsertProvider } from '@atlaskit/editor-common/quick-insert/provider';
|
|
8
|
+
import { Stack, Text } from '@atlaskit/primitives/compiled';
|
|
9
|
+
import Textfield from '@atlaskit/textfield';
|
|
10
|
+
var resultsGridStyles = null;
|
|
11
|
+
var RegistryElementBrowserItem = function RegistryElementBrowserItem(_ref) {
|
|
12
|
+
var editorView = _ref.editorView,
|
|
13
|
+
isOffline = _ref.isOffline,
|
|
14
|
+
isSelected = _ref.isSelected,
|
|
15
|
+
item = _ref.item,
|
|
16
|
+
onSelect = _ref.onSelect;
|
|
17
|
+
var _item$registration = item.registration,
|
|
18
|
+
Component = _item$registration.component,
|
|
19
|
+
key = _item$registration.key;
|
|
20
|
+
var contextValue = useMemo(function () {
|
|
21
|
+
return {
|
|
22
|
+
editorView: editorView,
|
|
23
|
+
isOffline: isOffline,
|
|
24
|
+
item: {
|
|
25
|
+
id: key,
|
|
26
|
+
isSelected: isSelected
|
|
27
|
+
},
|
|
28
|
+
select: function select(handler) {
|
|
29
|
+
return onSelect(key, handler);
|
|
30
|
+
},
|
|
31
|
+
surface: 'element-browser'
|
|
32
|
+
};
|
|
33
|
+
}, [editorView, isOffline, isSelected, key, onSelect]);
|
|
34
|
+
if (!Component) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return /*#__PURE__*/React.createElement(QuickInsertProvider, {
|
|
38
|
+
value: contextValue
|
|
39
|
+
}, /*#__PURE__*/React.createElement(Component, undefined, null));
|
|
40
|
+
};
|
|
41
|
+
export var RegistryElementBrowserSearchResults = function RegistryElementBrowserSearchResults(_ref2) {
|
|
42
|
+
var _emptyStateHandler;
|
|
43
|
+
var editorView = _ref2.editorView,
|
|
44
|
+
emptyStateHandler = _ref2.emptyStateHandler,
|
|
45
|
+
isOffline = _ref2.isOffline,
|
|
46
|
+
items = _ref2.items,
|
|
47
|
+
query = _ref2.query,
|
|
48
|
+
resultsId = _ref2.resultsId,
|
|
49
|
+
section = _ref2.section,
|
|
50
|
+
selectedKey = _ref2.selectedKey,
|
|
51
|
+
onKeyDown = _ref2.onKeyDown,
|
|
52
|
+
onSearchChange = _ref2.onSearchChange,
|
|
53
|
+
onSelect = _ref2.onSelect;
|
|
54
|
+
var _useIntl = useIntl(),
|
|
55
|
+
formatMessage = _useIntl.formatMessage;
|
|
56
|
+
return /*#__PURE__*/React.createElement(Stack, {
|
|
57
|
+
space: "space.200"
|
|
58
|
+
}, /*#__PURE__*/React.createElement(Textfield, {
|
|
59
|
+
autoFocus: true,
|
|
60
|
+
"aria-controls": resultsId,
|
|
61
|
+
"aria-label": formatMessage({
|
|
62
|
+
defaultMessage: 'Search elements',
|
|
63
|
+
id: 'editor.quick-insert.search'
|
|
64
|
+
}),
|
|
65
|
+
name: "registry-element-browser-search",
|
|
66
|
+
onChange: onSearchChange,
|
|
67
|
+
onKeyDown: onKeyDown,
|
|
68
|
+
value: query
|
|
69
|
+
}), /*#__PURE__*/React.createElement(Text, {
|
|
70
|
+
"aria-live": "polite"
|
|
71
|
+
}, formatMessage({
|
|
72
|
+
defaultMessage: '{count} results',
|
|
73
|
+
id: 'editor.quick-insert.results'
|
|
74
|
+
}, {
|
|
75
|
+
count: items.length
|
|
76
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
77
|
+
"aria-label": formatMessage({
|
|
78
|
+
defaultMessage: 'Element results',
|
|
79
|
+
id: 'editor.quick-insert.results-label'
|
|
80
|
+
}),
|
|
81
|
+
"data-testid": "registry-element-browser-results",
|
|
82
|
+
id: resultsId,
|
|
83
|
+
onKeyDown: onKeyDown,
|
|
84
|
+
tabIndex: -1,
|
|
85
|
+
role: items.length ? 'listbox' : undefined,
|
|
86
|
+
className: ax(["_zulpu2gc _1e0c11p5 _yv0e13mt"])
|
|
87
|
+
}, items.length ? items.map(function (item) {
|
|
88
|
+
return /*#__PURE__*/React.createElement(RegistryElementBrowserItem, {
|
|
89
|
+
editorView: editorView,
|
|
90
|
+
isOffline: isOffline,
|
|
91
|
+
isSelected: selectedKey === item.registration.key,
|
|
92
|
+
item: item,
|
|
93
|
+
key: item.registration.key,
|
|
94
|
+
onSelect: onSelect
|
|
95
|
+
});
|
|
96
|
+
}) : (_emptyStateHandler = emptyStateHandler === null || emptyStateHandler === void 0 ? void 0 : emptyStateHandler({
|
|
97
|
+
mode: 'full',
|
|
98
|
+
searchTerm: query,
|
|
99
|
+
selectedCategory: section
|
|
100
|
+
})) !== null && _emptyStateHandler !== void 0 ? _emptyStateHandler : /*#__PURE__*/React.createElement(Stack, {
|
|
101
|
+
alignInline: "center",
|
|
102
|
+
space: "space.100"
|
|
103
|
+
}, /*#__PURE__*/React.createElement(Text, null, formatMessage({
|
|
104
|
+
defaultMessage: 'Nothing matches your search',
|
|
105
|
+
id: 'editor.quick-insert.empty'
|
|
106
|
+
})), /*#__PURE__*/React.createElement(LinkButton, {
|
|
107
|
+
appearance: "primary",
|
|
108
|
+
href: "https://marketplace.atlassian.com/search?category=Macros&hosting=cloud&product=confluence",
|
|
109
|
+
target: "_blank"
|
|
110
|
+
}, formatMessage({
|
|
111
|
+
defaultMessage: 'Explore Atlassian Marketplace',
|
|
112
|
+
id: 'editor.quick-insert.explore-marketplace'
|
|
113
|
+
})))));
|
|
114
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
|
+
import { isOfflineMode } from '@atlaskit/editor-common/connectivity/isOfflineMode';
|
|
5
|
+
import { insertSelectedItem } from '@atlaskit/editor-common/insert';
|
|
6
|
+
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
7
|
+
import { MENU } from '@atlaskit/editor-common/quick-insert/keys';
|
|
8
|
+
import { closeElementBrowser } from '../../pm-plugins/commands';
|
|
9
|
+
import { pluginKey } from '../../pm-plugins/plugin-key';
|
|
10
|
+
import { RegistryElementBrowser } from './RegistryElementBrowser';
|
|
11
|
+
export var RegistryElementBrowserContainer = function RegistryElementBrowserContainer(_ref) {
|
|
12
|
+
var _pluginKey$getState;
|
|
13
|
+
var editorView = _ref.editorView,
|
|
14
|
+
pluginInjectionAPI = _ref.pluginInjectionAPI,
|
|
15
|
+
helpUrl = _ref.helpUrl;
|
|
16
|
+
var _useSharedPluginState = useSharedPluginStateWithSelector(pluginInjectionAPI, ['quickInsert', 'connectivity'], function (state) {
|
|
17
|
+
var _state$quickInsertSta, _state$quickInsertSta2, _state$quickInsertSta3, _state$connectivitySt;
|
|
18
|
+
return {
|
|
19
|
+
isElementBrowserOpen: (_state$quickInsertSta = (_state$quickInsertSta2 = state.quickInsertState) === null || _state$quickInsertSta2 === void 0 ? void 0 : _state$quickInsertSta2.isElementBrowserOpen) !== null && _state$quickInsertSta !== void 0 ? _state$quickInsertSta : false,
|
|
20
|
+
emptyStateHandler: (_state$quickInsertSta3 = state.quickInsertState) === null || _state$quickInsertSta3 === void 0 ? void 0 : _state$quickInsertSta3.emptyStateHandler,
|
|
21
|
+
mode: (_state$connectivitySt = state.connectivityState) === null || _state$connectivitySt === void 0 ? void 0 : _state$connectivitySt.mode
|
|
22
|
+
};
|
|
23
|
+
}),
|
|
24
|
+
currentEmptyStateHandler = _useSharedPluginState.emptyStateHandler,
|
|
25
|
+
isElementBrowserOpen = _useSharedPluginState.isElementBrowserOpen,
|
|
26
|
+
mode = _useSharedPluginState.mode;
|
|
27
|
+
var _useState = useState([]),
|
|
28
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
29
|
+
snapshot = _useState2[0],
|
|
30
|
+
setSnapshot = _useState2[1];
|
|
31
|
+
var _useState3 = useState(),
|
|
32
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
33
|
+
emptyStateHandler = _useState4[0],
|
|
34
|
+
setEmptyStateHandler = _useState4[1];
|
|
35
|
+
var wasOpen = useRef(false);
|
|
36
|
+
var selectionHandler = useRef(undefined);
|
|
37
|
+
var isInsertConfirmed = useRef(false);
|
|
38
|
+
var lifecycleOpen = useRef(false);
|
|
39
|
+
var fireLifecycleEvent = useCallback(function (action) {
|
|
40
|
+
var _pluginInjectionAPI$a;
|
|
41
|
+
pluginInjectionAPI === null || pluginInjectionAPI === void 0 || (_pluginInjectionAPI$a = pluginInjectionAPI.analytics) === null || _pluginInjectionAPI$a === void 0 || _pluginInjectionAPI$a.actions.fireAnalyticsEvent({
|
|
42
|
+
action: action,
|
|
43
|
+
actionSubject: ACTION_SUBJECT.ELEMENT_BROWSER,
|
|
44
|
+
attributes: {
|
|
45
|
+
mode: 'full'
|
|
46
|
+
},
|
|
47
|
+
eventType: EVENT_TYPE.UI
|
|
48
|
+
});
|
|
49
|
+
}, [pluginInjectionAPI]);
|
|
50
|
+
useEffect(function () {
|
|
51
|
+
if (isElementBrowserOpen && !wasOpen.current) {
|
|
52
|
+
var _pluginInjectionAPI$u, _pluginInjectionAPI$u2;
|
|
53
|
+
setSnapshot((_pluginInjectionAPI$u = pluginInjectionAPI === null || pluginInjectionAPI === void 0 || (_pluginInjectionAPI$u2 = pluginInjectionAPI.uiControlRegistry) === null || _pluginInjectionAPI$u2 === void 0 ? void 0 : _pluginInjectionAPI$u2.actions.getComponents(MENU.key)) !== null && _pluginInjectionAPI$u !== void 0 ? _pluginInjectionAPI$u : []);
|
|
54
|
+
selectionHandler.current = undefined;
|
|
55
|
+
setEmptyStateHandler(function () {
|
|
56
|
+
return currentEmptyStateHandler;
|
|
57
|
+
});
|
|
58
|
+
isInsertConfirmed.current = false;
|
|
59
|
+
lifecycleOpen.current = true;
|
|
60
|
+
fireLifecycleEvent(ACTION.OPENED);
|
|
61
|
+
} else if (!isElementBrowserOpen && wasOpen.current && lifecycleOpen.current) {
|
|
62
|
+
lifecycleOpen.current = false;
|
|
63
|
+
fireLifecycleEvent(ACTION.CLOSED);
|
|
64
|
+
}
|
|
65
|
+
wasOpen.current = isElementBrowserOpen;
|
|
66
|
+
}, [currentEmptyStateHandler, fireLifecycleEvent, isElementBrowserOpen, pluginInjectionAPI]);
|
|
67
|
+
useEffect(function () {
|
|
68
|
+
return function () {
|
|
69
|
+
if (lifecycleOpen.current) {
|
|
70
|
+
lifecycleOpen.current = false;
|
|
71
|
+
fireLifecycleEvent(ACTION.CLOSED);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}, [fireLifecycleEvent]);
|
|
75
|
+
var focusInEditor = useCallback(function () {
|
|
76
|
+
if (!editorView.hasFocus()) {
|
|
77
|
+
editorView.focus();
|
|
78
|
+
}
|
|
79
|
+
}, [editorView]);
|
|
80
|
+
var onClose = useCallback(function () {
|
|
81
|
+
if (!isInsertConfirmed.current) {
|
|
82
|
+
selectionHandler.current = undefined;
|
|
83
|
+
}
|
|
84
|
+
closeElementBrowser()(editorView.state, editorView.dispatch);
|
|
85
|
+
focusInEditor();
|
|
86
|
+
}, [editorView, focusInEditor]);
|
|
87
|
+
var onCloseComplete = useCallback(function () {
|
|
88
|
+
var handler = isInsertConfirmed.current ? selectionHandler.current : undefined;
|
|
89
|
+
selectionHandler.current = undefined;
|
|
90
|
+
isInsertConfirmed.current = false;
|
|
91
|
+
focusInEditor();
|
|
92
|
+
if (!handler) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
var insert = function insert(maybeNode) {
|
|
96
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
97
|
+
return insertSelectedItem(maybeNode, options)(editorView.state, editorView.state.tr, editorView.state.selection.head);
|
|
98
|
+
};
|
|
99
|
+
var transaction = handler({
|
|
100
|
+
insert: insert,
|
|
101
|
+
source: INPUT_METHOD.ELEMENT_BROWSER
|
|
102
|
+
});
|
|
103
|
+
if (transaction) {
|
|
104
|
+
editorView.dispatch(transaction);
|
|
105
|
+
}
|
|
106
|
+
}, [editorView, focusInEditor]);
|
|
107
|
+
var onSelect = useCallback(function (handler) {
|
|
108
|
+
selectionHandler.current = handler;
|
|
109
|
+
}, []);
|
|
110
|
+
var onClearSelection = useCallback(function () {
|
|
111
|
+
selectionHandler.current = undefined;
|
|
112
|
+
isInsertConfirmed.current = false;
|
|
113
|
+
}, []);
|
|
114
|
+
var onConfirmInsert = useCallback(function () {
|
|
115
|
+
if (!selectionHandler.current) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
isInsertConfirmed.current = true;
|
|
119
|
+
onClose();
|
|
120
|
+
}, [onClose]);
|
|
121
|
+
return /*#__PURE__*/React.createElement(RegistryElementBrowser, {
|
|
122
|
+
components: snapshot,
|
|
123
|
+
emptyStateHandler: emptyStateHandler,
|
|
124
|
+
helpUrl: helpUrl,
|
|
125
|
+
defaultSection: (_pluginKey$getState = pluginKey.getState(editorView.state)) === null || _pluginKey$getState === void 0 ? void 0 : _pluginKey$getState.elementBrowserInitialCategory,
|
|
126
|
+
editorView: editorView,
|
|
127
|
+
isOffline: isOfflineMode(mode),
|
|
128
|
+
isOpen: isElementBrowserOpen,
|
|
129
|
+
onClearSelection: onClearSelection,
|
|
130
|
+
onClose: onClose,
|
|
131
|
+
onCloseComplete: onCloseComplete,
|
|
132
|
+
onConfirmInsert: onConfirmInsert,
|
|
133
|
+
onSelect: onSelect
|
|
134
|
+
});
|
|
135
|
+
};
|