@open-cloud-initiative/editor-x 0.0.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.
Files changed (190) hide show
  1. package/.devcontainer/Dockerfile +13 -0
  2. package/.devcontainer/devcontainer.json +52 -0
  3. package/.github/dependabot.yml +10 -0
  4. package/.github/workflows/pages.yml +42 -0
  5. package/.github/workflows/publish.yml +41 -0
  6. package/.vscode/settings.json +7 -0
  7. package/LICENSE +9 -0
  8. package/README.md +9 -0
  9. package/app/_component/editor.tsx +383 -0
  10. package/app/layout.tsx +46 -0
  11. package/app/page.tsx +11 -0
  12. package/app/r/registry.json/route.ts +22 -0
  13. package/components/editorx/editor.tsx +1794 -0
  14. package/components/editorx/extensions/floating-menu.tsx +376 -0
  15. package/components/editorx/extensions/floating-toolbar.tsx +97 -0
  16. package/components/editorx/extensions/image-placeholder.tsx +316 -0
  17. package/components/editorx/extensions/image.tsx +462 -0
  18. package/components/editorx/extensions/search-and-replace.tsx +438 -0
  19. package/components/editorx/rich-text-editor.tsx +383 -0
  20. package/components/editorx/tiptap.css +421 -0
  21. package/components/editorx/toolbars/alignment.tsx +126 -0
  22. package/components/editorx/toolbars/blockquote.tsx +47 -0
  23. package/components/editorx/toolbars/bold.tsx +48 -0
  24. package/components/editorx/toolbars/bullet-list.tsx +48 -0
  25. package/components/editorx/toolbars/code-block.tsx +47 -0
  26. package/components/editorx/toolbars/code.tsx +43 -0
  27. package/components/editorx/toolbars/color-and-highlight.tsx +215 -0
  28. package/components/editorx/toolbars/editor-toolbar.tsx +77 -0
  29. package/components/editorx/toolbars/hard-break.tsx +46 -0
  30. package/components/editorx/toolbars/headings.tsx +97 -0
  31. package/components/editorx/toolbars/horizontal-rule.tsx +42 -0
  32. package/components/editorx/toolbars/image-placeholder-toolbar.tsx +47 -0
  33. package/components/editorx/toolbars/italic.tsx +48 -0
  34. package/components/editorx/toolbars/link.tsx +130 -0
  35. package/components/editorx/toolbars/mobile-toolbar-group.tsx +76 -0
  36. package/components/editorx/toolbars/ordered-list.tsx +47 -0
  37. package/components/editorx/toolbars/redo.tsx +44 -0
  38. package/components/editorx/toolbars/strikethrough.tsx +48 -0
  39. package/components/editorx/toolbars/toolbar-provider.tsx +29 -0
  40. package/components/editorx/toolbars/underline.tsx +48 -0
  41. package/components/editorx/toolbars/undo.tsx +43 -0
  42. package/components/layout/theme-switcher.tsx +26 -0
  43. package/components/main-nav.tsx +24 -0
  44. package/components/mobile-nav.tsx +46 -0
  45. package/components/open-in-v0-button.tsx +38 -0
  46. package/components/page-header.tsx +30 -0
  47. package/components/site-footer.tsx +41 -0
  48. package/components/site-header.tsx +32 -0
  49. package/components/theme-provider.tsx +8 -0
  50. package/components/ui/button.tsx +57 -0
  51. package/components/ui/checkbox.tsx +30 -0
  52. package/components/ui/collapsible.tsx +11 -0
  53. package/components/ui/command.tsx +148 -0
  54. package/components/ui/dialog.tsx +122 -0
  55. package/components/ui/drawer.tsx +118 -0
  56. package/components/ui/dropdown-menu.tsx +201 -0
  57. package/components/ui/input.tsx +22 -0
  58. package/components/ui/label.tsx +26 -0
  59. package/components/ui/popover.tsx +33 -0
  60. package/components/ui/resizable.tsx +40 -0
  61. package/components/ui/scroll-area.tsx +42 -0
  62. package/components/ui/separator.tsx +31 -0
  63. package/components/ui/sheet.tsx +140 -0
  64. package/components/ui/sidebar.tsx +763 -0
  65. package/components/ui/skeleton.tsx +15 -0
  66. package/components/ui/spinner.tsx +29 -0
  67. package/components/ui/tabs.tsx +55 -0
  68. package/components/ui/toggle-group.tsx +61 -0
  69. package/components/ui/toggle.tsx +45 -0
  70. package/components/ui/tooltip.tsx +32 -0
  71. package/components.json +21 -0
  72. package/config/site.ts +15 -0
  73. package/eslint.config.mjs +20 -0
  74. package/hooks/use-character-limit.ts +28 -0
  75. package/hooks/use-copy-to-clipboard.ts +16 -0
  76. package/hooks/use-debounce.ts +17 -0
  77. package/hooks/use-image-upload.ts +97 -0
  78. package/hooks/use-media-querry.ts +18 -0
  79. package/hooks/use-mobile.tsx +19 -0
  80. package/images/editor.png +0 -0
  81. package/lib/content.ts +39 -0
  82. package/lib/cookie-client.ts +19 -0
  83. package/lib/localstorage-client.ts +19 -0
  84. package/lib/package.ts +144 -0
  85. package/lib/preferences-config.ts +72 -0
  86. package/lib/preferences-storage.ts +20 -0
  87. package/lib/theme-utils.ts +12 -0
  88. package/lib/theme.ts +50 -0
  89. package/lib/tiptap-utils.ts +45 -0
  90. package/lib/utils.ts +11 -0
  91. package/next-env.d.ts +6 -0
  92. package/next.config.mjs +11 -0
  93. package/package.json +92 -0
  94. package/postcss.config.mjs +8 -0
  95. package/prettier.config.mjs +15 -0
  96. package/public/android-chrome-192x192.png +0 -0
  97. package/public/android-chrome-512x512.png +0 -0
  98. package/public/apple-touch-icon.png +0 -0
  99. package/public/favicon-16x16.png +0 -0
  100. package/public/favicon-32x32.png +0 -0
  101. package/public/favicon.ico +0 -0
  102. package/public/file.svg +1 -0
  103. package/public/globe.svg +1 -0
  104. package/public/next.svg +1 -0
  105. package/public/og.webp +0 -0
  106. package/public/r/editor-x.json +85 -0
  107. package/public/r/registry.json +93 -0
  108. package/public/site.webmanifest +19 -0
  109. package/public/vercel.svg +1 -0
  110. package/public/window.svg +1 -0
  111. package/registry/editor/components/editor.tsx +1794 -0
  112. package/registry/editor/components/extensions/floating-menu.tsx +376 -0
  113. package/registry/editor/components/extensions/floating-toolbar.tsx +97 -0
  114. package/registry/editor/components/extensions/image-placeholder.tsx +316 -0
  115. package/registry/editor/components/extensions/image.tsx +462 -0
  116. package/registry/editor/components/extensions/search-and-replace.tsx +438 -0
  117. package/registry/editor/components/rich-text-editor.tsx +383 -0
  118. package/registry/editor/components/tiptap.css +421 -0
  119. package/registry/editor/components/toolbars/alignment.tsx +126 -0
  120. package/registry/editor/components/toolbars/blockquote.tsx +47 -0
  121. package/registry/editor/components/toolbars/bold.tsx +48 -0
  122. package/registry/editor/components/toolbars/bullet-list.tsx +48 -0
  123. package/registry/editor/components/toolbars/code-block.tsx +47 -0
  124. package/registry/editor/components/toolbars/code.tsx +43 -0
  125. package/registry/editor/components/toolbars/color-and-highlight.tsx +215 -0
  126. package/registry/editor/components/toolbars/editor-toolbar.tsx +77 -0
  127. package/registry/editor/components/toolbars/hard-break.tsx +46 -0
  128. package/registry/editor/components/toolbars/headings.tsx +97 -0
  129. package/registry/editor/components/toolbars/horizontal-rule.tsx +42 -0
  130. package/registry/editor/components/toolbars/image-placeholder-toolbar.tsx +47 -0
  131. package/registry/editor/components/toolbars/italic.tsx +48 -0
  132. package/registry/editor/components/toolbars/link.tsx +130 -0
  133. package/registry/editor/components/toolbars/mobile-toolbar-group.tsx +76 -0
  134. package/registry/editor/components/toolbars/ordered-list.tsx +47 -0
  135. package/registry/editor/components/toolbars/redo.tsx +44 -0
  136. package/registry/editor/components/toolbars/strikethrough.tsx +48 -0
  137. package/registry/editor/components/toolbars/toolbar-provider.tsx +29 -0
  138. package/registry/editor/components/toolbars/underline.tsx +48 -0
  139. package/registry/editor/components/toolbars/undo.tsx +43 -0
  140. package/registry/editor/components/ui/button.tsx +57 -0
  141. package/registry/editor/components/ui/checkbox.tsx +30 -0
  142. package/registry/editor/components/ui/collapsible.tsx +11 -0
  143. package/registry/editor/components/ui/command.tsx +148 -0
  144. package/registry/editor/components/ui/dialog.tsx +122 -0
  145. package/registry/editor/components/ui/drawer.tsx +118 -0
  146. package/registry/editor/components/ui/dropdown-menu.tsx +201 -0
  147. package/registry/editor/components/ui/input.tsx +22 -0
  148. package/registry/editor/components/ui/label.tsx +26 -0
  149. package/registry/editor/components/ui/popover.tsx +33 -0
  150. package/registry/editor/components/ui/resizable.tsx +40 -0
  151. package/registry/editor/components/ui/scroll-area.tsx +42 -0
  152. package/registry/editor/components/ui/separator.tsx +31 -0
  153. package/registry/editor/components/ui/sheet.tsx +140 -0
  154. package/registry/editor/components/ui/sidebar.tsx +763 -0
  155. package/registry/editor/components/ui/skeleton.tsx +15 -0
  156. package/registry/editor/components/ui/spinner.tsx +29 -0
  157. package/registry/editor/components/ui/tabs.tsx +55 -0
  158. package/registry/editor/components/ui/toggle-group.tsx +61 -0
  159. package/registry/editor/components/ui/toggle.tsx +45 -0
  160. package/registry/editor/components/ui/tooltip.tsx +32 -0
  161. package/registry/editor/hooks/use-character-limit.ts +28 -0
  162. package/registry/editor/hooks/use-copy-to-clipboard.ts +16 -0
  163. package/registry/editor/hooks/use-debounce.ts +17 -0
  164. package/registry/editor/hooks/use-image-upload.ts +97 -0
  165. package/registry/editor/hooks/use-media-querry.ts +18 -0
  166. package/registry/editor/hooks/use-mobile.tsx +19 -0
  167. package/registry/editor/lib/content.ts +39 -0
  168. package/registry/editor/lib/cookie-client.ts +19 -0
  169. package/registry/editor/lib/localstorage-client.ts +19 -0
  170. package/registry/editor/lib/package.ts +144 -0
  171. package/registry/editor/lib/preferences-config.ts +72 -0
  172. package/registry/editor/lib/preferences-storage.ts +20 -0
  173. package/registry/editor/lib/theme-utils.ts +12 -0
  174. package/registry/editor/lib/theme.ts +50 -0
  175. package/registry/editor/lib/tiptap-utils.ts +45 -0
  176. package/registry/editor/lib/utils.ts +11 -0
  177. package/registry/editor/page.tsx +9 -0
  178. package/registry.json +93 -0
  179. package/reset.d.ts +1 -0
  180. package/scripts/generate-theme-presets.ts +128 -0
  181. package/scripts/postCreateCommand.sh +0 -0
  182. package/scripts/theme-boot.tsx +105 -0
  183. package/server/server-actions.ts +27 -0
  184. package/stores/preferences/preferences-provider.tsx +55 -0
  185. package/stores/preferences/preferences-store.ts +23 -0
  186. package/styles/globals.css +288 -0
  187. package/styles/presets/brutalist.css +89 -0
  188. package/styles/presets/soft-pop.css +89 -0
  189. package/styles/presets/tangerine.css +89 -0
  190. package/tsconfig.json +50 -0
@@ -0,0 +1,438 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ import { type Editor as CoreEditor, Extension, type Range } from "@tiptap/core";
4
+ import type { Node as PMNode } from "@tiptap/pm/model";
5
+ import { Plugin, PluginKey } from "@tiptap/pm/state";
6
+ import { Decoration, DecorationSet, type EditorView } from "@tiptap/pm/view";
7
+
8
+ declare module "@tiptap/core" {
9
+ interface Commands<ReturnType> {
10
+ search: {
11
+ /**
12
+ * @description Set search term in extension.
13
+ */
14
+ setSearchTerm: (searchTerm: string) => ReturnType;
15
+ /**
16
+ * @description Set replace term in extension.
17
+ */
18
+ setReplaceTerm: (replaceTerm: string) => ReturnType;
19
+ /**
20
+ * @description Replace first instance of search result with given replace term.
21
+ */
22
+ replace: () => ReturnType;
23
+ /**
24
+ * @description Replace all instances of search result with given replace term.
25
+ */
26
+ replaceAll: () => ReturnType;
27
+ /**
28
+ * @description Select the next search result.
29
+ */
30
+ selectNextResult: () => ReturnType;
31
+ /**
32
+ * @description Select the previous search result.
33
+ */
34
+ selectPreviousResult: () => ReturnType;
35
+ /**
36
+ * @description Set case sensitivity in extension.
37
+ */
38
+ setCaseSensitive: (caseSensitive: boolean) => ReturnType;
39
+ };
40
+ }
41
+ }
42
+
43
+ interface TextNodeWithPosition {
44
+ text: string;
45
+ pos: number;
46
+ }
47
+
48
+ const getRegex = (
49
+ searchString: string,
50
+ disableRegex: boolean,
51
+ caseSensitive: boolean
52
+ ): RegExp => {
53
+ const escapedString = disableRegex
54
+ ? searchString.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&")
55
+ : searchString;
56
+ return new RegExp(escapedString, caseSensitive ? "gu" : "gui");
57
+ };
58
+
59
+ interface ProcessedSearches {
60
+ decorationsToReturn: DecorationSet;
61
+ results: Range[];
62
+ }
63
+
64
+ function processSearches(
65
+ doc: PMNode,
66
+ searchTerm: RegExp,
67
+ selectedResultIndex: number,
68
+ searchResultClass: string,
69
+ selectedResultClass: string
70
+ ): ProcessedSearches {
71
+ const decorations: Decoration[] = [];
72
+ const results: Range[] = [];
73
+ const textNodesWithPosition: TextNodeWithPosition[] = [];
74
+
75
+ if (!searchTerm) {
76
+ return { decorationsToReturn: DecorationSet.empty, results: [] };
77
+ }
78
+
79
+ doc.descendants((node, pos) => {
80
+ if (node.isText) {
81
+ textNodesWithPosition.push({ text: node.text || "", pos });
82
+ }
83
+ });
84
+
85
+ for (const { text, pos } of textNodesWithPosition) {
86
+ const matches = Array.from(text.matchAll(searchTerm)).filter(
87
+ ([matchText]) => matchText.trim()
88
+ );
89
+
90
+ for (const match of matches) {
91
+ if (match.index !== undefined) {
92
+ results.push({
93
+ from: pos + match.index,
94
+ to: pos + match.index + match[0].length,
95
+ });
96
+ }
97
+ }
98
+ }
99
+
100
+ for (let i = 0; i < results.length; i++) {
101
+ const result = results[i];
102
+ if (!result) continue;
103
+ const { from, to } = result;
104
+ decorations.push(
105
+ Decoration.inline(from, to, {
106
+ class:
107
+ selectedResultIndex === i ? selectedResultClass : searchResultClass,
108
+ })
109
+ );
110
+ }
111
+
112
+ return {
113
+ decorationsToReturn: DecorationSet.create(doc, decorations),
114
+ results,
115
+ };
116
+ }
117
+
118
+ const replace = (
119
+ replaceTerm: string,
120
+ results: Range[],
121
+ { state, dispatch }: any
122
+ ) => {
123
+ const firstResult = results[0];
124
+
125
+ if (!firstResult) {
126
+ return;
127
+ }
128
+
129
+ const { from, to } = firstResult;
130
+
131
+ if (dispatch) {
132
+ dispatch(state.tr.insertText(replaceTerm, from, to));
133
+ }
134
+ };
135
+
136
+ const rebaseNextResult = (
137
+ replaceTerm: string,
138
+ index: number,
139
+ lastOffset: number,
140
+ results: Range[]
141
+ ): [number, Range[]] | null => {
142
+ const nextIndex = index + 1;
143
+
144
+ if (!results[nextIndex]) {
145
+ return null;
146
+ }
147
+
148
+ const currentResult = results[index];
149
+ if (!currentResult) {
150
+ return null;
151
+ }
152
+
153
+ const { from: currentFrom, to: currentTo } = currentResult;
154
+
155
+ const offset = currentTo - currentFrom - replaceTerm.length + lastOffset;
156
+
157
+ const { from, to } = results[nextIndex];
158
+
159
+ results[nextIndex] = {
160
+ to: to - offset,
161
+ from: from - offset,
162
+ };
163
+
164
+ return [offset, results];
165
+ };
166
+
167
+ const replaceAll = (
168
+ replaceTerm: string,
169
+ results: Range[],
170
+ { tr, dispatch }: { tr: any; dispatch: any }
171
+ ) => {
172
+ if (!results.length) {
173
+ return;
174
+ }
175
+
176
+ let offset = 0;
177
+
178
+ for (let i = 0; i < results.length; i++) {
179
+ const result = results[i];
180
+ if (!result) continue;
181
+ const { from, to } = result;
182
+ tr.insertText(replaceTerm, from, to);
183
+ const rebaseResponse = rebaseNextResult(replaceTerm, i, offset, results);
184
+
185
+ if (rebaseResponse) {
186
+ offset = rebaseResponse[0];
187
+ }
188
+ }
189
+
190
+ dispatch(tr);
191
+ };
192
+
193
+ const selectNext = (editor: CoreEditor) => {
194
+ const { results } = editor.storage
195
+ .searchAndReplace as SearchAndReplaceStorage;
196
+
197
+ if (!results.length) {
198
+ return;
199
+ }
200
+
201
+ const { selectedResult } = editor.storage.searchAndReplace;
202
+
203
+ if (selectedResult >= results.length - 1) {
204
+ editor.storage.searchAndReplace.selectedResult = 0;
205
+ } else {
206
+ editor.storage.searchAndReplace.selectedResult += 1;
207
+ }
208
+
209
+ const result = results[editor.storage.searchAndReplace.selectedResult];
210
+ if (!result) return;
211
+
212
+ const { from } = result;
213
+
214
+ const view: EditorView | undefined = editor.view;
215
+
216
+ if (view) {
217
+ view
218
+ .domAtPos(from)
219
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
220
+ // @ts-ignore
221
+ .node.scrollIntoView({ behavior: "smooth", block: "center" });
222
+ }
223
+ };
224
+
225
+ const selectPrevious = (editor: CoreEditor) => {
226
+ const { results } = editor.storage.searchAndReplace;
227
+
228
+ if (!results.length) {
229
+ return;
230
+ }
231
+
232
+ const { selectedResult } = editor.storage.searchAndReplace;
233
+
234
+ if (selectedResult <= 0) {
235
+ editor.storage.searchAndReplace.selectedResult = results.length - 1;
236
+ } else {
237
+ editor.storage.searchAndReplace.selectedResult -= 1;
238
+ }
239
+
240
+ const { from } = results[editor.storage.searchAndReplace.selectedResult];
241
+
242
+ const view: EditorView | undefined = editor.view;
243
+
244
+ if (view) {
245
+ view
246
+ .domAtPos(from)
247
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
248
+ // @ts-ignore
249
+ .node.scrollIntoView({ behavior: "smooth", block: "center" });
250
+ }
251
+ };
252
+
253
+ export const searchAndReplacePluginKey = new PluginKey(
254
+ "searchAndReplacePlugin"
255
+ );
256
+
257
+ export interface SearchAndReplaceOptions {
258
+ searchResultClass: string;
259
+ selectedResultClass: string;
260
+ disableRegex: boolean;
261
+ }
262
+
263
+ export interface SearchAndReplaceStorage {
264
+ searchTerm: string;
265
+ replaceTerm: string;
266
+ results: Range[];
267
+ lastSearchTerm: string;
268
+ selectedResult: number;
269
+ lastSelectedResult: number;
270
+ caseSensitive: boolean;
271
+ lastCaseSensitiveState: boolean;
272
+ }
273
+
274
+ export const SearchAndReplace = Extension.create<
275
+ SearchAndReplaceOptions,
276
+ SearchAndReplaceStorage
277
+ >({
278
+ name: "searchAndReplace",
279
+
280
+ addOptions() {
281
+ return {
282
+ searchResultClass: " bg-yellow-200",
283
+ selectedResultClass: "bg-yellow-500",
284
+ disableRegex: true,
285
+ };
286
+ },
287
+
288
+ addStorage() {
289
+ return {
290
+ searchTerm: "",
291
+ replaceTerm: "",
292
+ results: [],
293
+ lastSearchTerm: "",
294
+ selectedResult: 0,
295
+ lastSelectedResult: 0,
296
+ caseSensitive: false,
297
+ lastCaseSensitiveState: false,
298
+ };
299
+ },
300
+
301
+ addCommands() {
302
+ return {
303
+ setSearchTerm:
304
+ (searchTerm: string) =>
305
+ ({ editor }) => {
306
+ editor.storage.searchAndReplace.searchTerm = searchTerm;
307
+
308
+ return false;
309
+ },
310
+ setReplaceTerm:
311
+ (replaceTerm: string) =>
312
+ ({ editor }) => {
313
+ editor.storage.searchAndReplace.replaceTerm = replaceTerm;
314
+
315
+ return false;
316
+ },
317
+ replace:
318
+ () =>
319
+ ({ editor, state, dispatch }) => {
320
+ const { replaceTerm, results } = editor.storage.searchAndReplace;
321
+
322
+ replace(replaceTerm, results, { state, dispatch });
323
+
324
+ return false;
325
+ },
326
+ replaceAll:
327
+ () =>
328
+ ({ editor, tr, dispatch }) => {
329
+ const { replaceTerm, results } = editor.storage.searchAndReplace;
330
+
331
+ replaceAll(replaceTerm, results, { tr, dispatch });
332
+
333
+ return false;
334
+ },
335
+ selectNextResult:
336
+ () =>
337
+ ({ editor }) => {
338
+ selectNext(editor);
339
+
340
+ return false;
341
+ },
342
+ selectPreviousResult:
343
+ () =>
344
+ ({ editor }) => {
345
+ selectPrevious(editor);
346
+
347
+ return false;
348
+ },
349
+ setCaseSensitive:
350
+ (caseSensitive: boolean) =>
351
+ ({ editor }) => {
352
+ editor.storage.searchAndReplace.caseSensitive = caseSensitive;
353
+
354
+ return false;
355
+ },
356
+ };
357
+ },
358
+
359
+ addProseMirrorPlugins() {
360
+ const editor = this.editor;
361
+ const { searchResultClass, selectedResultClass, disableRegex } =
362
+ this.options;
363
+
364
+ const setLastSearchTerm = (t: string) => {
365
+ editor.storage.searchAndReplace.lastSearchTerm = t;
366
+ };
367
+
368
+ const setLastSelectedResult = (r: number) => {
369
+ editor.storage.searchAndReplace.lastSelectedResult = r;
370
+ };
371
+
372
+ const setLastCaseSensitiveState = (s: boolean) => {
373
+ editor.storage.searchAndReplace.lastCaseSensitiveState = s;
374
+ };
375
+
376
+ return [
377
+ new Plugin({
378
+ key: searchAndReplacePluginKey,
379
+ state: {
380
+ init: () => DecorationSet.empty,
381
+ apply({ doc, docChanged }, oldState) {
382
+ const {
383
+ searchTerm,
384
+ selectedResult,
385
+ lastSearchTerm,
386
+ lastSelectedResult,
387
+ caseSensitive,
388
+ lastCaseSensitiveState,
389
+ } = editor.storage.searchAndReplace as SearchAndReplaceStorage;
390
+
391
+ if (
392
+ !docChanged &&
393
+ lastSearchTerm === searchTerm &&
394
+ selectedResult === lastSelectedResult &&
395
+ lastCaseSensitiveState === caseSensitive
396
+ ) {
397
+ return oldState;
398
+ }
399
+
400
+ setLastSearchTerm(searchTerm);
401
+ setLastSelectedResult(selectedResult);
402
+ setLastCaseSensitiveState(caseSensitive);
403
+
404
+ if (!searchTerm) {
405
+ editor.storage.searchAndReplace.selectedResult = 0;
406
+ editor.storage.searchAndReplace.results = [];
407
+ return DecorationSet.empty;
408
+ }
409
+
410
+ const { decorationsToReturn, results } = processSearches(
411
+ doc,
412
+ getRegex(searchTerm, disableRegex, caseSensitive),
413
+ selectedResult,
414
+ searchResultClass,
415
+ selectedResultClass
416
+ );
417
+
418
+ editor.storage.searchAndReplace.results = results;
419
+
420
+ if (selectedResult > results.length) {
421
+ editor.storage.searchAndReplace.selectedResult = 1;
422
+ editor.commands.selectPreviousResult();
423
+ }
424
+
425
+ return decorationsToReturn;
426
+ },
427
+ },
428
+ props: {
429
+ decorations(state) {
430
+ return this.getState(state);
431
+ },
432
+ },
433
+ }),
434
+ ];
435
+ },
436
+ });
437
+
438
+ export default SearchAndReplace;