@atlaskit/editor-plugin-find-replace 0.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.
Files changed (121) hide show
  1. package/.eslintrc.js +26 -0
  2. package/CHANGELOG.md +11 -0
  3. package/LICENSE.md +13 -0
  4. package/README.md +30 -0
  5. package/dist/cjs/FindReplaceToolbarButtonWithState.js +166 -0
  6. package/dist/cjs/actions.js +19 -0
  7. package/dist/cjs/commands-with-analytics.js +101 -0
  8. package/dist/cjs/commands.js +255 -0
  9. package/dist/cjs/index.js +12 -0
  10. package/dist/cjs/plugin.js +93 -0
  11. package/dist/cjs/pm-plugins/keymap.js +24 -0
  12. package/dist/cjs/pm-plugins/main.js +39 -0
  13. package/dist/cjs/pm-plugins/plugin-factory.js +109 -0
  14. package/dist/cjs/pm-plugins/plugin-key.js +8 -0
  15. package/dist/cjs/reducer.js +61 -0
  16. package/dist/cjs/styles.js +17 -0
  17. package/dist/cjs/types.js +5 -0
  18. package/dist/cjs/ui/Find.js +309 -0
  19. package/dist/cjs/ui/FindReplace.js +104 -0
  20. package/dist/cjs/ui/FindReplaceToolbarButton.js +133 -0
  21. package/dist/cjs/ui/FindReplaceTooltipButton.js +77 -0
  22. package/dist/cjs/ui/Replace.js +176 -0
  23. package/dist/cjs/ui/styles.js +46 -0
  24. package/dist/cjs/utils/array.js +13 -0
  25. package/dist/cjs/utils/batch-decorations.js +310 -0
  26. package/dist/cjs/utils/commands.js +16 -0
  27. package/dist/cjs/utils/index.js +290 -0
  28. package/dist/es2019/FindReplaceToolbarButtonWithState.js +153 -0
  29. package/dist/es2019/actions.js +13 -0
  30. package/dist/es2019/commands-with-analytics.js +72 -0
  31. package/dist/es2019/commands.js +240 -0
  32. package/dist/es2019/index.js +1 -0
  33. package/dist/es2019/plugin.js +88 -0
  34. package/dist/es2019/pm-plugins/keymap.js +16 -0
  35. package/dist/es2019/pm-plugins/main.js +30 -0
  36. package/dist/es2019/pm-plugins/plugin-factory.js +91 -0
  37. package/dist/es2019/pm-plugins/plugin-key.js +2 -0
  38. package/dist/es2019/reducer.js +56 -0
  39. package/dist/es2019/styles.js +18 -0
  40. package/dist/es2019/types.js +1 -0
  41. package/dist/es2019/ui/Find.js +286 -0
  42. package/dist/es2019/ui/FindReplace.js +81 -0
  43. package/dist/es2019/ui/FindReplaceToolbarButton.js +122 -0
  44. package/dist/es2019/ui/FindReplaceTooltipButton.js +51 -0
  45. package/dist/es2019/ui/Replace.js +155 -0
  46. package/dist/es2019/ui/styles.js +50 -0
  47. package/dist/es2019/utils/array.js +3 -0
  48. package/dist/es2019/utils/batch-decorations.js +189 -0
  49. package/dist/es2019/utils/commands.js +6 -0
  50. package/dist/es2019/utils/index.js +249 -0
  51. package/dist/esm/FindReplaceToolbarButtonWithState.js +157 -0
  52. package/dist/esm/actions.js +13 -0
  53. package/dist/esm/commands-with-analytics.js +95 -0
  54. package/dist/esm/commands.js +248 -0
  55. package/dist/esm/index.js +1 -0
  56. package/dist/esm/plugin.js +86 -0
  57. package/dist/esm/pm-plugins/keymap.js +18 -0
  58. package/dist/esm/pm-plugins/main.js +33 -0
  59. package/dist/esm/pm-plugins/plugin-factory.js +104 -0
  60. package/dist/esm/pm-plugins/plugin-key.js +2 -0
  61. package/dist/esm/reducer.js +54 -0
  62. package/dist/esm/styles.js +11 -0
  63. package/dist/esm/types.js +1 -0
  64. package/dist/esm/ui/Find.js +304 -0
  65. package/dist/esm/ui/FindReplace.js +100 -0
  66. package/dist/esm/ui/FindReplaceToolbarButton.js +126 -0
  67. package/dist/esm/ui/FindReplaceTooltipButton.js +70 -0
  68. package/dist/esm/ui/Replace.js +171 -0
  69. package/dist/esm/ui/styles.js +39 -0
  70. package/dist/esm/utils/array.js +7 -0
  71. package/dist/esm/utils/batch-decorations.js +304 -0
  72. package/dist/esm/utils/commands.js +10 -0
  73. package/dist/esm/utils/index.js +280 -0
  74. package/dist/types/FindReplaceToolbarButtonWithState.d.ts +4 -0
  75. package/dist/types/actions.d.ts +64 -0
  76. package/dist/types/commands-with-analytics.d.ts +27 -0
  77. package/dist/types/commands.d.ts +12 -0
  78. package/dist/types/index.d.ts +2 -0
  79. package/dist/types/plugin.d.ts +2 -0
  80. package/dist/types/pm-plugins/keymap.d.ts +4 -0
  81. package/dist/types/pm-plugins/main.d.ts +5 -0
  82. package/dist/types/pm-plugins/plugin-factory.d.ts +2 -0
  83. package/dist/types/pm-plugins/plugin-key.d.ts +3 -0
  84. package/dist/types/reducer.d.ts +4 -0
  85. package/dist/types/styles.d.ts +3 -0
  86. package/dist/types/types.d.ts +76 -0
  87. package/dist/types/ui/Find.d.ts +71 -0
  88. package/dist/types/ui/FindReplace.d.ts +43 -0
  89. package/dist/types/ui/FindReplaceToolbarButton.d.ts +21 -0
  90. package/dist/types/ui/FindReplaceTooltipButton.d.ts +18 -0
  91. package/dist/types/ui/Replace.d.ts +27 -0
  92. package/dist/types/ui/styles.d.ts +6 -0
  93. package/dist/types/utils/array.d.ts +1 -0
  94. package/dist/types/utils/batch-decorations.d.ts +36 -0
  95. package/dist/types/utils/commands.d.ts +2 -0
  96. package/dist/types/utils/index.d.ts +49 -0
  97. package/dist/types-ts4.5/FindReplaceToolbarButtonWithState.d.ts +4 -0
  98. package/dist/types-ts4.5/actions.d.ts +64 -0
  99. package/dist/types-ts4.5/commands-with-analytics.d.ts +27 -0
  100. package/dist/types-ts4.5/commands.d.ts +12 -0
  101. package/dist/types-ts4.5/index.d.ts +2 -0
  102. package/dist/types-ts4.5/plugin.d.ts +2 -0
  103. package/dist/types-ts4.5/pm-plugins/keymap.d.ts +4 -0
  104. package/dist/types-ts4.5/pm-plugins/main.d.ts +5 -0
  105. package/dist/types-ts4.5/pm-plugins/plugin-factory.d.ts +2 -0
  106. package/dist/types-ts4.5/pm-plugins/plugin-key.d.ts +3 -0
  107. package/dist/types-ts4.5/reducer.d.ts +4 -0
  108. package/dist/types-ts4.5/styles.d.ts +3 -0
  109. package/dist/types-ts4.5/types.d.ts +76 -0
  110. package/dist/types-ts4.5/ui/Find.d.ts +71 -0
  111. package/dist/types-ts4.5/ui/FindReplace.d.ts +43 -0
  112. package/dist/types-ts4.5/ui/FindReplaceToolbarButton.d.ts +21 -0
  113. package/dist/types-ts4.5/ui/FindReplaceTooltipButton.d.ts +18 -0
  114. package/dist/types-ts4.5/ui/Replace.d.ts +27 -0
  115. package/dist/types-ts4.5/ui/styles.d.ts +6 -0
  116. package/dist/types-ts4.5/utils/array.d.ts +1 -0
  117. package/dist/types-ts4.5/utils/batch-decorations.d.ts +36 -0
  118. package/dist/types-ts4.5/utils/commands.d.ts +2 -0
  119. package/dist/types-ts4.5/utils/index.d.ts +49 -0
  120. package/package.json +117 -0
  121. package/styles/package.json +17 -0
@@ -0,0 +1,280 @@
1
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
2
+ import { Decoration } from '@atlaskit/editor-prosemirror/view';
3
+ import { searchMatchClass, selectedSearchMatchClass } from '../styles';
4
+ export function getSelectedText(selection) {
5
+ var text = '';
6
+ var selectedContent = selection.content().content;
7
+ for (var i = 0; i < selectedContent.childCount; i++) {
8
+ text += selectedContent.child(i).textContent;
9
+ }
10
+ return text;
11
+ }
12
+ export var createDecorations = function createDecorations(selectedIndex, matches) {
13
+ return matches.map(function (_ref, i) {
14
+ var start = _ref.start,
15
+ end = _ref.end;
16
+ return createDecoration(start, end, i === selectedIndex);
17
+ });
18
+ };
19
+ export var createDecoration = function createDecoration(start, end, isSelected) {
20
+ var className = searchMatchClass;
21
+ if (isSelected) {
22
+ className += " ".concat(selectedSearchMatchClass);
23
+ }
24
+ return Decoration.inline(start, end, {
25
+ class: className
26
+ });
27
+ };
28
+ export function findMatches(content, searchText, shouldMatchCase) {
29
+ var contentIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
30
+ var matches = [];
31
+ var searchTextLength = searchText.length;
32
+ var textGrouping = null;
33
+ var collectMatch = function collectMatch(textGrouping) {
34
+ if (!textGrouping) {
35
+ return;
36
+ }
37
+ var text = textGrouping.text,
38
+ relativePos = textGrouping.pos;
39
+ var pos = contentIndex + relativePos;
40
+ if (!shouldMatchCase) {
41
+ searchText = searchText.toLowerCase();
42
+ text = text.toLowerCase();
43
+ }
44
+ var index = text.indexOf(searchText);
45
+ while (index !== -1) {
46
+ // Find the next substring from the end of the first, so that they don't overlap
47
+ var end = index + searchTextLength;
48
+ // Add the substring index to the position of the node
49
+ matches.push({
50
+ start: pos + index,
51
+ end: pos + end
52
+ });
53
+ index = text.indexOf(searchText, end);
54
+ }
55
+ };
56
+ if (searchTextLength > 0) {
57
+ content.descendants(function (node, pos) {
58
+ if (node.isText) {
59
+ if (textGrouping === null) {
60
+ textGrouping = {
61
+ text: node.text,
62
+ pos: pos
63
+ };
64
+ } else {
65
+ textGrouping.text = textGrouping.text + node.text;
66
+ }
67
+ } else {
68
+ collectMatch(textGrouping);
69
+ textGrouping = null;
70
+ }
71
+ });
72
+ // if there's a dangling text grouping and no non-text node to trigger collectMatch, manually collectMatch
73
+ if (textGrouping) {
74
+ collectMatch(textGrouping);
75
+ }
76
+ }
77
+ return matches;
78
+ }
79
+
80
+ /**
81
+ * Finds index of first item in matches array that comes after user's cursor pos.
82
+ * If `backward` is `true`, finds index of first item that comes before instead.
83
+ */
84
+ export function findSearchIndex(selectionPos, matches) {
85
+ var backward = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
86
+ if (backward) {
87
+ var matchIndex = matches.findIndex(function (match) {
88
+ return match.start >= selectionPos;
89
+ }) - 1;
90
+ if (matchIndex < 0) {
91
+ matchIndex = matches.length - 1; // wrap around from the end
92
+ }
93
+
94
+ return matchIndex;
95
+ }
96
+ return Math.max(matches.findIndex(function (match) {
97
+ return match.start >= selectionPos;
98
+ }), 0);
99
+ }
100
+ export var nextIndex = function nextIndex(currentIndex, total) {
101
+ return (currentIndex + 1) % total;
102
+ };
103
+ export var prevIndex = function prevIndex(currentIndex, total) {
104
+ return (currentIndex - 1 + total) % total;
105
+ };
106
+ export var getSelectionForMatch = function getSelectionForMatch(selection, doc, index, matches) {
107
+ var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
108
+ if (matches[index]) {
109
+ return TextSelection.create(doc, matches[index].start + offset);
110
+ }
111
+ return selection;
112
+ };
113
+ export var findDecorationFromMatch = function findDecorationFromMatch(decorationSet, match) {
114
+ if (!match) {
115
+ return;
116
+ }
117
+ var decorations = decorationSet.find(match.start, match.end);
118
+ return decorations.length ? decorations.find(
119
+ // decorationSet.find() returns any decorations that touch the specifided
120
+ // positions, but we want to be stricter
121
+ function (decoration) {
122
+ return decoration.from === match.start && decoration.to === match.end;
123
+ }) : undefined;
124
+ };
125
+ export var removeDecorationsFromSet = function removeDecorationsFromSet(decorationSet, decorationsToRemove, doc) {
126
+ var prevDecorations = decorationSet.find();
127
+
128
+ // it is essential that we copy the decorations otherwise in some rare cases
129
+ // prosemirror-view will update our decorationsToRemove array to contain nulls
130
+ // instead of Decorations which ruins our check for lost decorations below
131
+ decorationSet = decorationSet.remove(decorationsToRemove.map(function (decoration) {
132
+ return (
133
+ // copy exists but isn't on the type definition
134
+ decoration.copy(decoration.from, decoration.to)
135
+ );
136
+ }));
137
+ var newDecorations = decorationSet.find();
138
+
139
+ // there is a bug in prosemirror-view where it can't cope with deleting inline
140
+ // decorations from a set in some cases (where there are multiple levels of nested
141
+ // children arrays), and it deletes more decorations than it should
142
+ // todo: ticket link
143
+ var lostDecorations = findLostAdjacentDecorations(decorationsToRemove, prevDecorations, newDecorations);
144
+ if (lostDecorations.length > 0) {
145
+ decorationSet = decorationSet.add(doc, lostDecorations);
146
+ }
147
+ return decorationSet;
148
+ };
149
+ export var removeMatchesFromSet = function removeMatchesFromSet(decorationSet, matches, doc) {
150
+ var decorationsToRemove = matches.filter(function (match) {
151
+ return !!match;
152
+ }).map(function (match) {
153
+ return findDecorationFromMatch(decorationSet, match);
154
+ });
155
+ decorationsToRemove.forEach(function (decoration) {
156
+ if (decoration) {
157
+ decorationSet = removeDecorationsFromSet(decorationSet, [decoration], doc);
158
+ }
159
+ });
160
+ return decorationSet;
161
+ };
162
+
163
+ /**
164
+ * Finds decorations in prevDecorations that are not in newDecorations or decorationsToRemove
165
+ * These decorations have been lost by Prosemirror during an over eager decoration removal
166
+ * We need to be smart to cope with thousands of decorations without crashing everything
167
+ */
168
+ export var findLostAdjacentDecorations = function findLostAdjacentDecorations(decorationsToRemove, prevDecorations, newDecorations) {
169
+ var lostDecorations = [];
170
+ if (prevDecorations.length - decorationsToRemove.length > newDecorations.length) {
171
+ var position = decorationsToRemove.length > 0 ? decorationsToRemove[0].from : 0;
172
+ var prevDecorationsStartIdx = findIndexBeforePosition(prevDecorations, position);
173
+ var newDecorationsStartIdx = findIndexBeforePosition(newDecorations, position);
174
+ var startIdx = Math.min(prevDecorationsStartIdx, newDecorationsStartIdx);
175
+ var prevDecorationsToCheck = prevDecorations.slice(startIdx);
176
+ var newDecorationsToCheck = newDecorations.slice(startIdx);
177
+ var uniqueInPrev = [];
178
+ var numToFind = prevDecorationsToCheck.length - newDecorationsToCheck.length;
179
+ var foundAll = false;
180
+ var newDecorationsIdxOffset = 0;
181
+ var _loop = function _loop() {
182
+ var prevDecoration = prevDecorationsToCheck[i];
183
+ // this was a legit removal, skip and continue
184
+ if (decorationsToRemove.find(function (decoration) {
185
+ return decoration.from === prevDecoration.from;
186
+ })) {
187
+ newDecorationsIdxOffset -= 1;
188
+ return 0; // continue
189
+ }
190
+ var j = i + newDecorationsIdxOffset;
191
+
192
+ // this is a lost decoration
193
+ if (j >= newDecorationsToCheck.length) {
194
+ uniqueInPrev.push(prevDecoration);
195
+ if (uniqueInPrev.length === numToFind) {
196
+ foundAll = true;
197
+ }
198
+ }
199
+ for (; j < newDecorationsToCheck.length; j++) {
200
+ var newDecoration = newDecorationsToCheck[j];
201
+
202
+ // decoration found in both arrays, skip and continue
203
+ if (prevDecoration.from === newDecoration.from) {
204
+ break;
205
+ }
206
+
207
+ // this is a lost decoration
208
+ if (newDecoration.from > prevDecoration.from || j === newDecorationsToCheck.length - 1) {
209
+ uniqueInPrev.push(prevDecoration);
210
+ newDecorationsIdxOffset -= 1;
211
+ if (uniqueInPrev.length === numToFind) {
212
+ foundAll = true;
213
+ }
214
+ break;
215
+ }
216
+ }
217
+ if (foundAll) {
218
+ return 1; // break
219
+ }
220
+ },
221
+ _ret;
222
+ for (var i = 0; i < prevDecorationsToCheck.length; i++) {
223
+ _ret = _loop();
224
+ if (_ret === 0) continue;
225
+ if (_ret === 1) break;
226
+ }
227
+
228
+ // make sure we ignore any that we wanted to delete
229
+ lostDecorations = uniqueInPrev.filter(function (decoration) {
230
+ return !decorationsToRemove.find(function (decorationToRemove) {
231
+ return decoration.from === decorationToRemove.from;
232
+ });
233
+ });
234
+ }
235
+ return lostDecorations;
236
+ };
237
+
238
+ /**
239
+ * Searches through array in bumps of 100 to return the index of the first
240
+ * decoration whose 'from' value is before or equal to the position
241
+ */
242
+ export var findIndexBeforePosition = function findIndexBeforePosition(items, position) {
243
+ // jump in batches to cope with arrays with thousands of decorations
244
+ var increment = 100;
245
+ var index = 0;
246
+ for (var i = items.length - 1; i >= 0; i -= increment) {
247
+ if (items[i].from < position) {
248
+ // now we have found the 100 range, we can narrow it down to exact index
249
+ index = i;
250
+ for (var j = i; j <= items.length - 1; j++) {
251
+ if (items[j].from <= position) {
252
+ index = j;
253
+ } else {
254
+ break;
255
+ }
256
+ }
257
+ break;
258
+ }
259
+ if (i < 100 && i > 0) {
260
+ i = 100;
261
+ }
262
+ }
263
+ return index;
264
+ };
265
+
266
+ /**
267
+ * Determines whether a find/replace text Match will be changed as a result
268
+ * of a Step modification to the document. This is evaluated by checking
269
+ * both mapped and unmapped versions of the Step as in different cases the
270
+ * matches will match.
271
+ *
272
+ * **Note:** Match state received here is after step has been applied.
273
+ */
274
+ export var isMatchAffectedByStep = function isMatchAffectedByStep(match, step, tr) {
275
+ var from = step.from,
276
+ to = step.to,
277
+ slice = step.slice;
278
+ var sliceSize = slice.content.size;
279
+ return from + sliceSize >= match.start && to - sliceSize <= match.end || tr.mapping.map(from) + sliceSize >= match.start && tr.mapping.map(to) - sliceSize <= match.end;
280
+ };
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { FindReplaceToolbarButtonWithStateProps } from './types';
3
+ declare const _default: React.MemoExoticComponent<({ popupsBoundariesElement, popupsMountPoint, popupsScrollableElement, isToolbarReducedSpacing, editorView, containerElement, dispatchAnalyticsEvent, featureFlags, takeFullWidth, api, }: FindReplaceToolbarButtonWithStateProps) => JSX.Element | null>;
4
+ export default _default;
@@ -0,0 +1,64 @@
1
+ import type { DecorationSet } from '@atlaskit/editor-prosemirror/view';
2
+ import type { Match } from './types';
3
+ export declare enum FindReplaceActionTypes {
4
+ ACTIVATE = "ACTIVATE",
5
+ FIND = "FIND",
6
+ UPDATE_DECORATIONS = "UPDATE_DECORATIONS",
7
+ FIND_NEXT = "FIND_NEXT",
8
+ FIND_PREVIOUS = "FIND_PREVIOUS",
9
+ REPLACE = "REPLACE",
10
+ REPLACE_ALL = "REPLACE_ALL",
11
+ CANCEL = "CANCEL",
12
+ BLUR = "BLUR",
13
+ TOGGLE_MATCH_CASE = "TOGGLE_MATCH_CASE"
14
+ }
15
+ export interface Activate {
16
+ type: FindReplaceActionTypes.ACTIVATE;
17
+ findText?: string;
18
+ matches?: Match[];
19
+ index?: number;
20
+ }
21
+ export interface Find {
22
+ type: FindReplaceActionTypes.FIND;
23
+ findText: string;
24
+ matches: Match[];
25
+ index: number;
26
+ }
27
+ export interface FindNext {
28
+ type: FindReplaceActionTypes.FIND_NEXT;
29
+ index: number;
30
+ decorationSet: DecorationSet;
31
+ }
32
+ export interface FindPrevious {
33
+ type: FindReplaceActionTypes.FIND_PREVIOUS;
34
+ index: number;
35
+ decorationSet: DecorationSet;
36
+ }
37
+ export interface Replace {
38
+ type: FindReplaceActionTypes.REPLACE;
39
+ replaceText: string;
40
+ decorationSet: DecorationSet;
41
+ matches: Match[];
42
+ index: number;
43
+ }
44
+ export interface ReplaceAll {
45
+ type: FindReplaceActionTypes.REPLACE_ALL;
46
+ replaceText: string;
47
+ decorationSet: DecorationSet;
48
+ matches: Match[];
49
+ index: number;
50
+ }
51
+ export interface Cancel {
52
+ type: FindReplaceActionTypes.CANCEL;
53
+ }
54
+ export interface Blur {
55
+ type: FindReplaceActionTypes.BLUR;
56
+ }
57
+ export interface UpdateDecorations {
58
+ type: FindReplaceActionTypes.UPDATE_DECORATIONS;
59
+ decorationSet: DecorationSet;
60
+ }
61
+ export interface ToggleMatchCase {
62
+ type: FindReplaceActionTypes.TOGGLE_MATCH_CASE;
63
+ }
64
+ export type FindReplaceAction = Activate | Find | FindNext | FindPrevious | Replace | ReplaceAll | Cancel | Blur | UpdateDecorations | ToggleMatchCase;
@@ -0,0 +1,27 @@
1
+ import type { EditorAnalyticsAPI, TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
2
+ import type { Command } from '@atlaskit/editor-common/types';
3
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
4
+ export declare const activateWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => ({ triggerMethod, }: {
5
+ triggerMethod: TRIGGER_METHOD.SHORTCUT | TRIGGER_METHOD.TOOLBAR;
6
+ }) => Command;
7
+ export declare const findWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => ({ editorView, containerElement, keyword, }: {
8
+ editorView: EditorView;
9
+ containerElement: HTMLElement | null;
10
+ keyword?: string | undefined;
11
+ }) => Command;
12
+ export declare const findNextWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => ({ triggerMethod, }: {
13
+ triggerMethod: TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.BUTTON;
14
+ }) => Command;
15
+ export declare const findPrevWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => ({ triggerMethod, }: {
16
+ triggerMethod: TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.BUTTON;
17
+ }) => Command;
18
+ export declare const replaceWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => ({ triggerMethod, replaceText, }: {
19
+ triggerMethod: TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.BUTTON;
20
+ replaceText: string;
21
+ }) => Command;
22
+ export declare const replaceAllWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => ({ replaceText }: {
23
+ replaceText: string;
24
+ }) => Command;
25
+ export declare const cancelSearchWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => ({ triggerMethod, }: {
26
+ triggerMethod: TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.TOOLBAR | TRIGGER_METHOD.BUTTON;
27
+ }) => Command;
@@ -0,0 +1,12 @@
1
+ import type { Decoration, EditorView } from '@atlaskit/editor-prosemirror/view';
2
+ export declare const activate: () => import("@atlaskit/editor-common/types").Command;
3
+ export declare const find: (editorView: EditorView, containerElement: HTMLElement | null, keyword?: string) => import("@atlaskit/editor-common/types").Command;
4
+ export declare const findNext: () => import("@atlaskit/editor-common/types").Command;
5
+ export declare const findPrevious: () => import("@atlaskit/editor-common/types").Command;
6
+ export declare const replace: (replaceText: string) => import("@atlaskit/editor-common/types").Command;
7
+ export declare const replaceAll: (replaceText: string) => import("@atlaskit/editor-common/types").Command;
8
+ export declare const addDecorations: (decorations: Decoration[]) => import("@atlaskit/editor-common/types").Command;
9
+ export declare const removeDecorations: (decorations: Decoration[]) => import("@atlaskit/editor-common/types").Command;
10
+ export declare const cancelSearch: () => import("@atlaskit/editor-common/types").Command;
11
+ export declare const blur: () => import("@atlaskit/editor-common/types").Command;
12
+ export declare const toggleMatchCase: () => import("@atlaskit/editor-common/types").Command;
@@ -0,0 +1,2 @@
1
+ export type { FindReplacePlugin, FindReplaceToolbarButtonActionProps, FindReplaceOptions, } from './types';
2
+ export { findReplacePlugin } from './plugin';
@@ -0,0 +1,2 @@
1
+ import type { FindReplacePlugin } from './types';
2
+ export declare const findReplacePlugin: FindReplacePlugin;
@@ -0,0 +1,4 @@
1
+ import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
2
+ import type { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
+ declare const keymapPlugin: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => SafePlugin<any>;
4
+ export default keymapPlugin;
@@ -0,0 +1,5 @@
1
+ import type { Dispatch } from '@atlaskit/editor-common/event-dispatcher';
2
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
+ import type { FindReplacePluginState } from '../types';
4
+ export declare const initialState: FindReplacePluginState;
5
+ export declare const createPlugin: (dispatch: Dispatch) => SafePlugin<FindReplacePluginState>;
@@ -0,0 +1,2 @@
1
+ import type { FindReplacePluginState } from '../types';
2
+ export declare const createCommand: <A = import("../actions").FindReplaceAction>(action: A | ((state: Readonly<import("prosemirror-state").EditorState>) => false | A), transform?: ((tr: import("prosemirror-state").Transaction, state: import("prosemirror-state").EditorState) => import("prosemirror-state").Transaction) | undefined) => import("@atlaskit/editor-common/types").Command, getPluginState: (state: import("prosemirror-state").EditorState) => FindReplacePluginState, createPluginState: (dispatch: import("@atlaskit/editor-common/event-dispatcher").Dispatch<any>, initialState: FindReplacePluginState | ((state: import("prosemirror-state").EditorState) => FindReplacePluginState)) => import("prosemirror-state").SafeStateField<FindReplacePluginState>;
@@ -0,0 +1,3 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
+ import type { FindReplacePluginState } from '../types';
3
+ export declare const findReplacePluginKey: PluginKey<FindReplacePluginState>;
@@ -0,0 +1,4 @@
1
+ import type { FindReplaceAction } from './actions';
2
+ import type { FindReplacePluginState } from './types';
3
+ declare const reducer: (getInitialState: () => FindReplacePluginState) => (state: FindReplacePluginState, action: FindReplaceAction) => FindReplacePluginState;
4
+ export default reducer;
@@ -0,0 +1,3 @@
1
+ export declare const searchMatchClass = "search-match";
2
+ export declare const selectedSearchMatchClass = "selected-search-match";
3
+ export declare const findReplaceStyles: import("@emotion/react").SerializedStyles;
@@ -0,0 +1,76 @@
1
+ /// <reference types="react" />
2
+ import type { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
3
+ import type { ExtractInjectionAPI, FeatureFlags, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
4
+ import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
5
+ import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
6
+ import type { DecorationSet, EditorView } from '@atlaskit/editor-prosemirror/view';
7
+ export interface FindReplacePluginState {
8
+ /** Whether find/replace is active, i.e. displayed */
9
+ isActive: boolean;
10
+ /**
11
+ * Whether we should set focus into and select all text of find textfield
12
+ * This will be true if user highlights a word and hits cmd+f
13
+ */
14
+ shouldFocus: boolean;
15
+ /** Search keyword */
16
+ findText: string;
17
+ /** Text to replace with */
18
+ replaceText: string;
19
+ /** Index of selected word in array of matches, this gets updated as user finds next/prev */
20
+ index: number;
21
+ /** Positions of find results */
22
+ matches: Match[];
23
+ /** Decorations for the search results */
24
+ decorationSet: DecorationSet;
25
+ /** Whether find/replace should match case when searching for results */
26
+ shouldMatchCase: boolean;
27
+ }
28
+ export type FindReplaceToolbarButtonWithStateProps = {
29
+ popupsBoundariesElement?: HTMLElement;
30
+ popupsMountPoint?: HTMLElement;
31
+ popupsScrollableElement?: HTMLElement;
32
+ isToolbarReducedSpacing?: boolean;
33
+ editorView: EditorView;
34
+ containerElement: HTMLElement | null;
35
+ dispatchAnalyticsEvent?: DispatchAnalyticsEvent;
36
+ takeFullWidth?: boolean;
37
+ featureFlags: FeatureFlags;
38
+ api: ExtractInjectionAPI<FindReplacePlugin> | undefined;
39
+ };
40
+ export type FindReplaceToolbarButtonActionProps = Omit<FindReplaceToolbarButtonWithStateProps, 'featureFlags' | 'api'>;
41
+ type Config = {
42
+ takeFullWidth: boolean;
43
+ twoLineEditorToolbar: boolean;
44
+ };
45
+ export type FindReplacePlugin = NextEditorPlugin<'findReplace', {
46
+ pluginConfiguration: Config;
47
+ sharedState: FindReplacePluginState | undefined;
48
+ dependencies: [
49
+ OptionalPlugin<FeatureFlagsPlugin>,
50
+ OptionalPlugin<AnalyticsPlugin>
51
+ ];
52
+ actions: {
53
+ getToolbarButton: (params: FindReplaceToolbarButtonActionProps) => React.ReactNode;
54
+ };
55
+ }>;
56
+ export type Match = {
57
+ /** Start position */
58
+ start: number;
59
+ /** End position */
60
+ end: number;
61
+ };
62
+ export type TextGrouping = {
63
+ /** The concatenated text across nodes */
64
+ text: string;
65
+ /** Start position */
66
+ pos: number;
67
+ } | null;
68
+ export type FindReplaceOptions = {
69
+ allowMatchCase?: boolean;
70
+ };
71
+ export type MatchCaseProps = {
72
+ allowMatchCase?: boolean;
73
+ shouldMatchCase?: boolean;
74
+ onToggleMatchCase?: () => void;
75
+ };
76
+ export {};
@@ -0,0 +1,71 @@
1
+ /** @jsx jsx */
2
+ import React from 'react';
3
+ import type { WrappedComponentProps } from 'react-intl-next';
4
+ import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
5
+ import type { MatchCaseProps } from '../types';
6
+ export declare const FIND_DEBOUNCE_MS = 100;
7
+ export type FindProps = {
8
+ findText?: string;
9
+ count: {
10
+ index: number;
11
+ total: number;
12
+ };
13
+ shouldFocus: boolean;
14
+ onFindBlur: () => void;
15
+ onFind: (findText?: string) => void;
16
+ onFindNext: ({ triggerMethod, }: {
17
+ triggerMethod: TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.BUTTON;
18
+ }) => void;
19
+ onFindPrev: ({ triggerMethod, }: {
20
+ triggerMethod: TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.BUTTON;
21
+ }) => void;
22
+ onFindTextfieldRefSet: (ref: React.RefObject<HTMLInputElement>) => void;
23
+ onCancel: ({ triggerMethod, }: {
24
+ triggerMethod: TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.TOOLBAR | TRIGGER_METHOD.BUTTON;
25
+ }) => void;
26
+ onArrowDown: () => void;
27
+ } & MatchCaseProps;
28
+ declare const _default: React.FC<import("react-intl-next").WithIntlProps<{
29
+ findText?: string | undefined;
30
+ count: {
31
+ index: number;
32
+ total: number;
33
+ };
34
+ shouldFocus: boolean;
35
+ onFindBlur: () => void;
36
+ onFind: (findText?: string | undefined) => void;
37
+ onFindNext: ({ triggerMethod, }: {
38
+ triggerMethod: TRIGGER_METHOD.BUTTON | TRIGGER_METHOD.KEYBOARD;
39
+ }) => void;
40
+ onFindPrev: ({ triggerMethod, }: {
41
+ triggerMethod: TRIGGER_METHOD.BUTTON | TRIGGER_METHOD.KEYBOARD;
42
+ }) => void;
43
+ onFindTextfieldRefSet: (ref: React.RefObject<HTMLInputElement>) => void;
44
+ onCancel: ({ triggerMethod, }: {
45
+ triggerMethod: TRIGGER_METHOD.BUTTON | TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.TOOLBAR;
46
+ }) => void;
47
+ onArrowDown: () => void;
48
+ } & MatchCaseProps & WrappedComponentProps<"intl">>> & {
49
+ WrappedComponent: React.ComponentType<{
50
+ findText?: string | undefined;
51
+ count: {
52
+ index: number;
53
+ total: number;
54
+ };
55
+ shouldFocus: boolean;
56
+ onFindBlur: () => void;
57
+ onFind: (findText?: string | undefined) => void;
58
+ onFindNext: ({ triggerMethod, }: {
59
+ triggerMethod: TRIGGER_METHOD.BUTTON | TRIGGER_METHOD.KEYBOARD;
60
+ }) => void;
61
+ onFindPrev: ({ triggerMethod, }: {
62
+ triggerMethod: TRIGGER_METHOD.BUTTON | TRIGGER_METHOD.KEYBOARD;
63
+ }) => void;
64
+ onFindTextfieldRefSet: (ref: React.RefObject<HTMLInputElement>) => void;
65
+ onCancel: ({ triggerMethod, }: {
66
+ triggerMethod: TRIGGER_METHOD.BUTTON | TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.TOOLBAR;
67
+ }) => void;
68
+ onArrowDown: () => void;
69
+ } & MatchCaseProps & WrappedComponentProps<"intl">>;
70
+ };
71
+ export default _default;
@@ -0,0 +1,43 @@
1
+ /** @jsx jsx */
2
+ import React from 'react';
3
+ import { jsx } from '@emotion/react';
4
+ import type { DispatchAnalyticsEvent, TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
5
+ import type { MatchCaseProps } from '../types';
6
+ export type FindReplaceProps = {
7
+ findText?: string;
8
+ replaceText?: string;
9
+ count: {
10
+ index: number;
11
+ total: number;
12
+ };
13
+ shouldFocus: boolean;
14
+ onFindBlur: () => void;
15
+ onFind: (findText?: string) => void;
16
+ onFindNext: ({ triggerMethod, }: {
17
+ triggerMethod: TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.BUTTON;
18
+ }) => void;
19
+ onFindPrev: ({ triggerMethod, }: {
20
+ triggerMethod: TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.BUTTON;
21
+ }) => void;
22
+ onReplace: ({ triggerMethod, replaceText, }: {
23
+ triggerMethod: TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.BUTTON;
24
+ replaceText: string;
25
+ }) => void;
26
+ onReplaceAll: ({ replaceText }: {
27
+ replaceText: string;
28
+ }) => void;
29
+ onCancel: ({ triggerMethod, }: {
30
+ triggerMethod: TRIGGER_METHOD.KEYBOARD | TRIGGER_METHOD.TOOLBAR | TRIGGER_METHOD.BUTTON;
31
+ }) => void;
32
+ dispatchAnalyticsEvent?: DispatchAnalyticsEvent;
33
+ } & MatchCaseProps;
34
+ declare class FindReplace extends React.PureComponent<FindReplaceProps> {
35
+ private findTextfield;
36
+ private replaceTextfield?;
37
+ setFindTextfieldRef: (findTextfieldRef: React.RefObject<HTMLInputElement>) => void;
38
+ setReplaceTextfieldRef: (replaceTextfieldRef: React.RefObject<HTMLInputElement>) => void;
39
+ setFocusToFind: () => void;
40
+ setFocusToReplace: () => void;
41
+ render(): jsx.JSX.Element;
42
+ }
43
+ export default FindReplace;
@@ -0,0 +1,21 @@
1
+ /** @jsx jsx */
2
+ import React from 'react';
3
+ import type { WrappedComponentProps } from 'react-intl-next';
4
+ import type { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
5
+ import type { FindReplaceProps } from './FindReplace';
6
+ export interface FindReplaceToolbarButtonProps extends Omit<FindReplaceProps, 'count'> {
7
+ index: number;
8
+ numMatches: number;
9
+ isActive: boolean;
10
+ onActivate: () => void;
11
+ isReducedSpacing?: boolean;
12
+ popupsMountPoint?: HTMLElement;
13
+ popupsBoundariesElement?: HTMLElement;
14
+ popupsScrollableElement?: HTMLElement;
15
+ dispatchAnalyticsEvent?: DispatchAnalyticsEvent;
16
+ takeFullWidth: boolean;
17
+ }
18
+ declare const _default: React.FC<import("react-intl-next").WithIntlProps<FindReplaceToolbarButtonProps & WrappedComponentProps<"intl">>> & {
19
+ WrappedComponent: React.ComponentType<FindReplaceToolbarButtonProps & WrappedComponentProps<"intl">>;
20
+ };
21
+ export default _default;
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ interface Props {
3
+ title: string;
4
+ icon: JSX.Element;
5
+ keymapDescription: string;
6
+ onClick: (ref: React.RefObject<HTMLButtonElement>) => void;
7
+ disabled?: boolean;
8
+ isPressed?: boolean;
9
+ }
10
+ export declare class FindReplaceTooltipButton extends React.PureComponent<Props> {
11
+ private buttonRef;
12
+ static defaultProps: {
13
+ keymapDescription: string;
14
+ };
15
+ handleClick: () => void;
16
+ render(): JSX.Element;
17
+ }
18
+ export {};