@atlaskit/editor-plugin-type-ahead 12.0.7 → 12.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-type-ahead
|
|
2
2
|
|
|
3
|
+
## 12.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
|
|
9
|
+
## 12.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [`dbf22f118dd9e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/dbf22f118dd9e) -
|
|
14
|
+
Rewrite Rovo Chat @-mention provider on a single Relay-native RovoChatMentionResource that fires
|
|
15
|
+
people + agents in parallel via Promise. People render as soon as URS resolves and agents pop in
|
|
16
|
+
below when ready. New aliased agentStudio_getAgents query consolidates 3 prefetch round trips into
|
|
17
|
+
1, drops over-fetched fields, and uses real abort plumbing. Adds opt-in subscribeToItemsUpdates
|
|
18
|
+
multi-emit contract to the editor mention typeahead so progressive emissions are no longer dropped
|
|
19
|
+
after the first frame.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies
|
|
24
|
+
|
|
3
25
|
## 12.0.7
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
|
@@ -21,14 +21,15 @@ var useLoadItems = exports.useLoadItems = function useLoadItems(triggerHandler,
|
|
|
21
21
|
setItems = _useState2[1];
|
|
22
22
|
var componentIsMounted = (0, _react.useRef)(true);
|
|
23
23
|
var editorViewRef = (0, _react.useRef)(editorView);
|
|
24
|
+
var latestQueryRef = (0, _react.useRef)(query);
|
|
25
|
+
latestQueryRef.current = query;
|
|
24
26
|
(0, _react.useEffect)(function () {
|
|
25
|
-
var
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
27
|
+
var requestQuery = query;
|
|
28
|
+
var isStaleRequest = function isStaleRequest() {
|
|
29
|
+
return latestQueryRef.current !== requestQuery;
|
|
30
|
+
};
|
|
30
31
|
var options = {
|
|
31
|
-
query:
|
|
32
|
+
query: requestQuery || '',
|
|
32
33
|
editorState: editorView.state
|
|
33
34
|
};
|
|
34
35
|
var view = editorViewRef.current;
|
|
@@ -38,10 +39,19 @@ var useLoadItems = exports.useLoadItems = function useLoadItems(triggerHandler,
|
|
|
38
39
|
api === null || api === void 0 || api.core.actions.execute((0, _clearListError.clearListError)());
|
|
39
40
|
});
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Shared render pipeline used by both the single-shot `getItems`
|
|
45
|
+
* Promise path and the opt-in multi-emit `subscribeToItemsUpdates`
|
|
46
|
+
* path. Renders the dropdown with whatever items it is given.
|
|
47
|
+
*
|
|
48
|
+
* Both paths share the empty-state injection, section-building
|
|
49
|
+
* and "View more" placeholder logic — extracting this helper
|
|
50
|
+
* avoids any chance the two paths drift in subtle rendering
|
|
51
|
+
* behaviour.
|
|
52
|
+
*/
|
|
53
|
+
var renderResult = function renderResult(result) {
|
|
42
54
|
var _triggerHandler$getEm;
|
|
43
|
-
// Inject empty list item here so it flows through the normal list rendering and keyboard
|
|
44
|
-
// navigation paths
|
|
45
55
|
var emptyItem = result.length === 0 && (0, _expValEquals.expValEquals)('platform_editor_insert_menu_ai', 'isEnabled', true) ? (_triggerHandler$getEm = triggerHandler.getEmptyItem) === null || _triggerHandler$getEm === void 0 ? void 0 : _triggerHandler$getEm.call(triggerHandler, {
|
|
46
56
|
editorState: editorView.state
|
|
47
57
|
}) : undefined;
|
|
@@ -56,15 +66,18 @@ var useLoadItems = exports.useLoadItems = function useLoadItems(triggerHandler,
|
|
|
56
66
|
if (componentIsMounted.current) {
|
|
57
67
|
setItems(list);
|
|
58
68
|
}
|
|
59
|
-
|
|
60
|
-
// Add a placeholder item for view more button so that it can be traversed with arrow keys
|
|
61
69
|
var viewMoreItem = {
|
|
62
70
|
title: 'View more'
|
|
63
71
|
};
|
|
64
72
|
queueMicrotask(function () {
|
|
65
73
|
(0, _updateListItems.updateListItem)(showViewMore ? list.concat(viewMoreItem) : list, sections)(view.state, view.dispatch);
|
|
66
74
|
});
|
|
67
|
-
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// Matches the pre-refactor implicit-any contract for the original
|
|
78
|
+
// `.catch((e) => updateListError(e)(...))` path.
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
80
|
+
var handleError = function handleError(e) {
|
|
68
81
|
if ((0, _experiments.editorExperiment)('platform_editor_offline_editing_web', true)) {
|
|
69
82
|
if (e) {
|
|
70
83
|
if (componentIsMounted.current) {
|
|
@@ -75,7 +88,42 @@ var useLoadItems = exports.useLoadItems = function useLoadItems(triggerHandler,
|
|
|
75
88
|
});
|
|
76
89
|
}
|
|
77
90
|
}
|
|
78
|
-
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// Multi-emit path: handler opts in by implementing
|
|
94
|
+
// `subscribeToItemsUpdates`. The handler controls when to push
|
|
95
|
+
// updates; we re-render on every push for the lifetime of this
|
|
96
|
+
// effect.
|
|
97
|
+
var subscribeToItemsUpdates = triggerHandler === null || triggerHandler === void 0 ? void 0 : triggerHandler.subscribeToItemsUpdates;
|
|
98
|
+
if (subscribeToItemsUpdates) {
|
|
99
|
+
var stale = false;
|
|
100
|
+
var _subscribeToItemsUpda = subscribeToItemsUpdates(options),
|
|
101
|
+
initial = _subscribeToItemsUpda.initial,
|
|
102
|
+
subscribe = _subscribeToItemsUpda.subscribe;
|
|
103
|
+
initial.then(function (result) {
|
|
104
|
+
if (!stale && !isStaleRequest()) {
|
|
105
|
+
renderResult(result);
|
|
106
|
+
}
|
|
107
|
+
}).catch(handleError);
|
|
108
|
+
var unsubscribe = subscribe(function (items) {
|
|
109
|
+
if (stale || isStaleRequest() || !componentIsMounted.current) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
renderResult(items);
|
|
113
|
+
});
|
|
114
|
+
return function () {
|
|
115
|
+
stale = true;
|
|
116
|
+
unsubscribe();
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Existing single-shot path. Unchanged in behaviour.
|
|
121
|
+
var getItems = triggerHandler === null || triggerHandler === void 0 ? void 0 : triggerHandler.getItems;
|
|
122
|
+
if (!getItems) {
|
|
123
|
+
setItems(EMPTY_LIST_ITEM);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
getItems(options).then(renderResult).catch(handleError);
|
|
79
127
|
|
|
80
128
|
// ignore because EditorView is mutable but we don't want to
|
|
81
129
|
// call loadItems when it changes, only when the query changes
|
|
@@ -10,14 +10,13 @@ export const useLoadItems = (triggerHandler, editorView, query, showViewMore, ap
|
|
|
10
10
|
const [items, setItems] = useState(EMPTY_LIST_ITEM);
|
|
11
11
|
const componentIsMounted = useRef(true);
|
|
12
12
|
const editorViewRef = useRef(editorView);
|
|
13
|
+
const latestQueryRef = useRef(query);
|
|
14
|
+
latestQueryRef.current = query;
|
|
13
15
|
useEffect(() => {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
setItems(EMPTY_LIST_ITEM);
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
16
|
+
const requestQuery = query;
|
|
17
|
+
const isStaleRequest = () => latestQueryRef.current !== requestQuery;
|
|
19
18
|
const options = {
|
|
20
|
-
query:
|
|
19
|
+
query: requestQuery || '',
|
|
21
20
|
editorState: editorView.state
|
|
22
21
|
};
|
|
23
22
|
const {
|
|
@@ -29,10 +28,19 @@ export const useLoadItems = (triggerHandler, editorView, query, showViewMore, ap
|
|
|
29
28
|
api === null || api === void 0 ? void 0 : api.core.actions.execute(clearListError());
|
|
30
29
|
});
|
|
31
30
|
}
|
|
32
|
-
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Shared render pipeline used by both the single-shot `getItems`
|
|
34
|
+
* Promise path and the opt-in multi-emit `subscribeToItemsUpdates`
|
|
35
|
+
* path. Renders the dropdown with whatever items it is given.
|
|
36
|
+
*
|
|
37
|
+
* Both paths share the empty-state injection, section-building
|
|
38
|
+
* and "View more" placeholder logic — extracting this helper
|
|
39
|
+
* avoids any chance the two paths drift in subtle rendering
|
|
40
|
+
* behaviour.
|
|
41
|
+
*/
|
|
42
|
+
const renderResult = result => {
|
|
33
43
|
var _triggerHandler$getEm;
|
|
34
|
-
// Inject empty list item here so it flows through the normal list rendering and keyboard
|
|
35
|
-
// navigation paths
|
|
36
44
|
const emptyItem = result.length === 0 && expValEquals('platform_editor_insert_menu_ai', 'isEnabled', true) ? (_triggerHandler$getEm = triggerHandler.getEmptyItem) === null || _triggerHandler$getEm === void 0 ? void 0 : _triggerHandler$getEm.call(triggerHandler, {
|
|
37
45
|
editorState: editorView.state
|
|
38
46
|
}) : undefined;
|
|
@@ -48,15 +56,18 @@ export const useLoadItems = (triggerHandler, editorView, query, showViewMore, ap
|
|
|
48
56
|
if (componentIsMounted.current) {
|
|
49
57
|
setItems(list);
|
|
50
58
|
}
|
|
51
|
-
|
|
52
|
-
// Add a placeholder item for view more button so that it can be traversed with arrow keys
|
|
53
59
|
const viewMoreItem = {
|
|
54
60
|
title: 'View more'
|
|
55
61
|
};
|
|
56
62
|
queueMicrotask(() => {
|
|
57
63
|
updateListItem(showViewMore ? list.concat(viewMoreItem) : list, sections)(view.state, view.dispatch);
|
|
58
64
|
});
|
|
59
|
-
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Matches the pre-refactor implicit-any contract for the original
|
|
68
|
+
// `.catch((e) => updateListError(e)(...))` path.
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
70
|
+
const handleError = e => {
|
|
60
71
|
if (editorExperiment('platform_editor_offline_editing_web', true)) {
|
|
61
72
|
if (e) {
|
|
62
73
|
if (componentIsMounted.current) {
|
|
@@ -67,7 +78,43 @@ export const useLoadItems = (triggerHandler, editorView, query, showViewMore, ap
|
|
|
67
78
|
});
|
|
68
79
|
}
|
|
69
80
|
}
|
|
70
|
-
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// Multi-emit path: handler opts in by implementing
|
|
84
|
+
// `subscribeToItemsUpdates`. The handler controls when to push
|
|
85
|
+
// updates; we re-render on every push for the lifetime of this
|
|
86
|
+
// effect.
|
|
87
|
+
const subscribeToItemsUpdates = triggerHandler === null || triggerHandler === void 0 ? void 0 : triggerHandler.subscribeToItemsUpdates;
|
|
88
|
+
if (subscribeToItemsUpdates) {
|
|
89
|
+
let stale = false;
|
|
90
|
+
const {
|
|
91
|
+
initial,
|
|
92
|
+
subscribe
|
|
93
|
+
} = subscribeToItemsUpdates(options);
|
|
94
|
+
initial.then(result => {
|
|
95
|
+
if (!stale && !isStaleRequest()) {
|
|
96
|
+
renderResult(result);
|
|
97
|
+
}
|
|
98
|
+
}).catch(handleError);
|
|
99
|
+
const unsubscribe = subscribe(items => {
|
|
100
|
+
if (stale || isStaleRequest() || !componentIsMounted.current) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
renderResult(items);
|
|
104
|
+
});
|
|
105
|
+
return () => {
|
|
106
|
+
stale = true;
|
|
107
|
+
unsubscribe();
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Existing single-shot path. Unchanged in behaviour.
|
|
112
|
+
const getItems = triggerHandler === null || triggerHandler === void 0 ? void 0 : triggerHandler.getItems;
|
|
113
|
+
if (!getItems) {
|
|
114
|
+
setItems(EMPTY_LIST_ITEM);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
getItems(options).then(renderResult).catch(handleError);
|
|
71
118
|
|
|
72
119
|
// ignore because EditorView is mutable but we don't want to
|
|
73
120
|
// call loadItems when it changes, only when the query changes
|
|
@@ -14,14 +14,15 @@ export var useLoadItems = function useLoadItems(triggerHandler, editorView, quer
|
|
|
14
14
|
setItems = _useState2[1];
|
|
15
15
|
var componentIsMounted = useRef(true);
|
|
16
16
|
var editorViewRef = useRef(editorView);
|
|
17
|
+
var latestQueryRef = useRef(query);
|
|
18
|
+
latestQueryRef.current = query;
|
|
17
19
|
useEffect(function () {
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
20
|
+
var requestQuery = query;
|
|
21
|
+
var isStaleRequest = function isStaleRequest() {
|
|
22
|
+
return latestQueryRef.current !== requestQuery;
|
|
23
|
+
};
|
|
23
24
|
var options = {
|
|
24
|
-
query:
|
|
25
|
+
query: requestQuery || '',
|
|
25
26
|
editorState: editorView.state
|
|
26
27
|
};
|
|
27
28
|
var view = editorViewRef.current;
|
|
@@ -31,10 +32,19 @@ export var useLoadItems = function useLoadItems(triggerHandler, editorView, quer
|
|
|
31
32
|
api === null || api === void 0 || api.core.actions.execute(clearListError());
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Shared render pipeline used by both the single-shot `getItems`
|
|
38
|
+
* Promise path and the opt-in multi-emit `subscribeToItemsUpdates`
|
|
39
|
+
* path. Renders the dropdown with whatever items it is given.
|
|
40
|
+
*
|
|
41
|
+
* Both paths share the empty-state injection, section-building
|
|
42
|
+
* and "View more" placeholder logic — extracting this helper
|
|
43
|
+
* avoids any chance the two paths drift in subtle rendering
|
|
44
|
+
* behaviour.
|
|
45
|
+
*/
|
|
46
|
+
var renderResult = function renderResult(result) {
|
|
35
47
|
var _triggerHandler$getEm;
|
|
36
|
-
// Inject empty list item here so it flows through the normal list rendering and keyboard
|
|
37
|
-
// navigation paths
|
|
38
48
|
var emptyItem = result.length === 0 && expValEquals('platform_editor_insert_menu_ai', 'isEnabled', true) ? (_triggerHandler$getEm = triggerHandler.getEmptyItem) === null || _triggerHandler$getEm === void 0 ? void 0 : _triggerHandler$getEm.call(triggerHandler, {
|
|
39
49
|
editorState: editorView.state
|
|
40
50
|
}) : undefined;
|
|
@@ -49,15 +59,18 @@ export var useLoadItems = function useLoadItems(triggerHandler, editorView, quer
|
|
|
49
59
|
if (componentIsMounted.current) {
|
|
50
60
|
setItems(list);
|
|
51
61
|
}
|
|
52
|
-
|
|
53
|
-
// Add a placeholder item for view more button so that it can be traversed with arrow keys
|
|
54
62
|
var viewMoreItem = {
|
|
55
63
|
title: 'View more'
|
|
56
64
|
};
|
|
57
65
|
queueMicrotask(function () {
|
|
58
66
|
updateListItem(showViewMore ? list.concat(viewMoreItem) : list, sections)(view.state, view.dispatch);
|
|
59
67
|
});
|
|
60
|
-
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Matches the pre-refactor implicit-any contract for the original
|
|
71
|
+
// `.catch((e) => updateListError(e)(...))` path.
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
73
|
+
var handleError = function handleError(e) {
|
|
61
74
|
if (editorExperiment('platform_editor_offline_editing_web', true)) {
|
|
62
75
|
if (e) {
|
|
63
76
|
if (componentIsMounted.current) {
|
|
@@ -68,7 +81,42 @@ export var useLoadItems = function useLoadItems(triggerHandler, editorView, quer
|
|
|
68
81
|
});
|
|
69
82
|
}
|
|
70
83
|
}
|
|
71
|
-
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Multi-emit path: handler opts in by implementing
|
|
87
|
+
// `subscribeToItemsUpdates`. The handler controls when to push
|
|
88
|
+
// updates; we re-render on every push for the lifetime of this
|
|
89
|
+
// effect.
|
|
90
|
+
var subscribeToItemsUpdates = triggerHandler === null || triggerHandler === void 0 ? void 0 : triggerHandler.subscribeToItemsUpdates;
|
|
91
|
+
if (subscribeToItemsUpdates) {
|
|
92
|
+
var stale = false;
|
|
93
|
+
var _subscribeToItemsUpda = subscribeToItemsUpdates(options),
|
|
94
|
+
initial = _subscribeToItemsUpda.initial,
|
|
95
|
+
subscribe = _subscribeToItemsUpda.subscribe;
|
|
96
|
+
initial.then(function (result) {
|
|
97
|
+
if (!stale && !isStaleRequest()) {
|
|
98
|
+
renderResult(result);
|
|
99
|
+
}
|
|
100
|
+
}).catch(handleError);
|
|
101
|
+
var unsubscribe = subscribe(function (items) {
|
|
102
|
+
if (stale || isStaleRequest() || !componentIsMounted.current) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
renderResult(items);
|
|
106
|
+
});
|
|
107
|
+
return function () {
|
|
108
|
+
stale = true;
|
|
109
|
+
unsubscribe();
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Existing single-shot path. Unchanged in behaviour.
|
|
114
|
+
var getItems = triggerHandler === null || triggerHandler === void 0 ? void 0 : triggerHandler.getItems;
|
|
115
|
+
if (!getItems) {
|
|
116
|
+
setItems(EMPTY_LIST_ITEM);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
getItems(options).then(renderResult).catch(handleError);
|
|
72
120
|
|
|
73
121
|
// ignore because EditorView is mutable but we don't want to
|
|
74
122
|
// call loadItems when it changes, only when the query changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-type-ahead",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.1.1",
|
|
4
4
|
"description": "Type-ahead plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"@atlaskit/primitives": "^20.0.0",
|
|
37
37
|
"@atlaskit/prosemirror-history": "^1.0.0",
|
|
38
38
|
"@atlaskit/prosemirror-input-rules": "^4.0.0",
|
|
39
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
40
|
-
"@atlaskit/tokens": "^
|
|
39
|
+
"@atlaskit/tmp-editor-statsig": "^111.0.0",
|
|
40
|
+
"@atlaskit/tokens": "^15.0.0",
|
|
41
41
|
"@atlaskit/visually-hidden": "^4.0.0",
|
|
42
42
|
"@babel/runtime": "^7.0.0",
|
|
43
43
|
"@emotion/react": "^11.7.1",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"w3c-keyname": "^2.1.8"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@atlaskit/editor-common": "^116.
|
|
51
|
+
"@atlaskit/editor-common": "^116.11.0",
|
|
52
52
|
"react": "^18.2.0",
|
|
53
53
|
"react-dom": "^18.2.0",
|
|
54
54
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|