diff options
author | Kristóf Marussy <kristof@marussy.com> | 2022-08-17 21:43:29 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2022-08-17 21:43:29 +0200 |
commit | bb900e1bd40a6b7efd7a538114d985ea7f7e3e88 (patch) | |
tree | bb15a937ade92313dc654a640bc1de925442eff2 /subprojects/frontend/src/editor/SearchPanelStore.ts | |
parent | refactor(frondend): improve editor store and theme (diff) | |
download | refinery-bb900e1bd40a6b7efd7a538114d985ea7f7e3e88.tar.gz refinery-bb900e1bd40a6b7efd7a538114d985ea7f7e3e88.tar.zst refinery-bb900e1bd40a6b7efd7a538114d985ea7f7e3e88.zip |
feat(frontend): custom search panel
Also improves editor styling (to enable panel styling).
Diffstat (limited to 'subprojects/frontend/src/editor/SearchPanelStore.ts')
-rw-r--r-- | subprojects/frontend/src/editor/SearchPanelStore.ts | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/subprojects/frontend/src/editor/SearchPanelStore.ts b/subprojects/frontend/src/editor/SearchPanelStore.ts new file mode 100644 index 00000000..43a571e5 --- /dev/null +++ b/subprojects/frontend/src/editor/SearchPanelStore.ts | |||
@@ -0,0 +1,108 @@ | |||
1 | import { | ||
2 | closeSearchPanel, | ||
3 | findNext, | ||
4 | findPrevious, | ||
5 | getSearchQuery, | ||
6 | openSearchPanel, | ||
7 | replaceAll, | ||
8 | replaceNext, | ||
9 | SearchQuery, | ||
10 | selectMatches, | ||
11 | setSearchQuery, | ||
12 | } from '@codemirror/search'; | ||
13 | import { action, computed, makeObservable, observable, override } from 'mobx'; | ||
14 | |||
15 | import type EditorStore from './EditorStore'; | ||
16 | import PanelStore from './PanelStore'; | ||
17 | |||
18 | export default class SearchPanelStore extends PanelStore { | ||
19 | searchField: HTMLInputElement | undefined; | ||
20 | |||
21 | constructor(store: EditorStore) { | ||
22 | // Use a custom class name to avoid specificity issues with | ||
23 | // CodeMirror `.cm-search.cm-panel` CSS styles. | ||
24 | super('refinery-cm-search', openSearchPanel, closeSearchPanel, store); | ||
25 | makeObservable(this, { | ||
26 | searchField: observable.ref, | ||
27 | query: computed, | ||
28 | invalidRegexp: computed, | ||
29 | open: override, | ||
30 | setSearchField: action, | ||
31 | updateQuery: action, | ||
32 | findNext: action, | ||
33 | findPrevious: action, | ||
34 | selectMatches: action, | ||
35 | }); | ||
36 | } | ||
37 | |||
38 | setSearchField(newSearchField: HTMLInputElement | undefined): void { | ||
39 | this.searchField = newSearchField; | ||
40 | if (this.state) { | ||
41 | this.selectSearchField(); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | get query(): SearchQuery { | ||
46 | return getSearchQuery(this.store.state); | ||
47 | } | ||
48 | |||
49 | get invalidRegexp(): boolean { | ||
50 | const { search, valid } = this.query; | ||
51 | return !valid && search !== ''; | ||
52 | } | ||
53 | |||
54 | updateQuery(newQueryOptions: { | ||
55 | search?: string; | ||
56 | caseSensitive?: boolean; | ||
57 | literal?: boolean; | ||
58 | regexp?: boolean; | ||
59 | replace?: string; | ||
60 | }): void { | ||
61 | const { search, caseSensitive, literal, regexp, replace } = this.query; | ||
62 | const newQuery = new SearchQuery({ | ||
63 | search, | ||
64 | caseSensitive, | ||
65 | literal, | ||
66 | regexp, | ||
67 | replace, | ||
68 | ...newQueryOptions, | ||
69 | ...(newQueryOptions.regexp === true && { literal: false }), | ||
70 | ...(newQueryOptions.literal === true && { regexp: false }), | ||
71 | }); | ||
72 | this.store.dispatch({ | ||
73 | effects: [setSearchQuery.of(newQuery)], | ||
74 | }); | ||
75 | } | ||
76 | |||
77 | findNext(): void { | ||
78 | this.store.doCommand(findNext); | ||
79 | } | ||
80 | |||
81 | findPrevious(): void { | ||
82 | this.store.doCommand(findPrevious); | ||
83 | } | ||
84 | |||
85 | selectMatches(): void { | ||
86 | this.store.doCommand(selectMatches); | ||
87 | } | ||
88 | |||
89 | replaceNext(): void { | ||
90 | this.store.doCommand(replaceNext); | ||
91 | } | ||
92 | |||
93 | replaceAll(): void { | ||
94 | this.store.doCommand(replaceAll); | ||
95 | } | ||
96 | |||
97 | override open(): boolean { | ||
98 | return super.open() || this.selectSearchField(); | ||
99 | } | ||
100 | |||
101 | private selectSearchField(): boolean { | ||
102 | if (this.searchField === undefined) { | ||
103 | return false; | ||
104 | } | ||
105 | this.searchField.select(); | ||
106 | return true; | ||
107 | } | ||
108 | } | ||