Skip to content

Commit 0749cb3

Browse files
authored
fix(markup): show initial search state in search popup (#570)
1 parent 6da4e70 commit 0749cb3

File tree

2 files changed

+34
-54
lines changed

2 files changed

+34
-54
lines changed

src/markup/codemirror/search-plugin/plugin.ts

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
closeSearchPanel,
44
findNext,
55
findPrevious,
6+
getSearchQuery,
67
search,
78
searchKeymap,
89
searchPanelOpen,
@@ -19,15 +20,7 @@ import {ReactRendererFacet} from '../react-facet';
1920

2021
import {renderSearchPopup} from './view/SearchPopup';
2122

22-
interface SearchQueryParams {
23-
search: string;
24-
caseSensitive?: boolean;
25-
literal?: boolean;
26-
regexp?: boolean;
27-
replace?: string;
28-
valid?: boolean;
29-
wholeWord?: boolean;
30-
}
23+
type SearchQueryConfig = ConstructorParameters<typeof SearchQuery>[0];
3124

3225
const INPUT_DELAY = 200;
3326

@@ -45,14 +38,14 @@ export const SearchPanelPlugin = (params: SearchPanelPluginParams) =>
4538

4639
anchor: HTMLElement | null;
4740
renderer: RendererItem | null;
48-
searchQuery: SearchQueryParams = {
41+
searchConfig: SearchQueryConfig = {
4942
search: '',
5043
caseSensitive: false,
5144
wholeWord: false,
5245
};
5346
receiver: Receiver<EventMap> | undefined;
5447

55-
setViewSearchWithDelay: (config: Partial<SearchQueryParams>) => void;
48+
setViewSearchWithDelay: (config: Partial<SearchQueryConfig>) => void;
5649

5750
constructor(view: EditorView) {
5851
this.view = view;
@@ -79,11 +72,13 @@ export const SearchPanelPlugin = (params: SearchPanelPluginParams) =>
7972
const isPanelOpen = searchPanelOpen(update.state);
8073

8174
if (isPanelOpen && !this.renderer) {
75+
const initial = getSearchQuery(update.state);
8276
this.anchor = document.querySelector(this.params.anchorSelector);
8377
this.renderer = this.view.state
8478
.facet(ReactRendererFacet)
8579
.createItem('cm-search', () =>
8680
renderSearchPopup({
81+
initial,
8782
open: true,
8883
anchor: this.anchor,
8984
onChange: this.handleChange,
@@ -105,13 +100,13 @@ export const SearchPanelPlugin = (params: SearchPanelPluginParams) =>
105100
this.receiver?.off('change-editor-mode', this.handleEditorModeChange);
106101
}
107102

108-
setViewSearch(config: Partial<SearchQueryParams>) {
109-
this.searchQuery = {
110-
...this.searchQuery,
103+
setViewSearch(config: Partial<SearchQueryConfig>) {
104+
this.searchConfig = {
105+
...this.searchConfig,
111106
...config,
112107
};
113108
const searchQuery = new SearchQuery({
114-
...this.searchQuery,
109+
...this.searchConfig,
115110
});
116111

117112
this.view.dispatch({effects: setSearchQuery.of(searchQuery)});
@@ -140,17 +135,8 @@ export const SearchPanelPlugin = (params: SearchPanelPluginParams) =>
140135
findPrevious(this.view);
141136
}
142137

143-
handleSearchConfigChange({
144-
isCaseSensitive,
145-
isWholeWord,
146-
}: {
147-
isCaseSensitive?: boolean;
148-
isWholeWord?: boolean;
149-
}) {
150-
this.setViewSearch({
151-
caseSensitive: isCaseSensitive,
152-
wholeWord: isWholeWord,
153-
});
138+
handleSearchConfigChange(config: Partial<SearchQueryConfig>) {
139+
this.setViewSearch(config);
154140
}
155141
},
156142
{

src/markup/codemirror/search-plugin/view/SearchPopup.tsx

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
import React, {ChangeEvent, useRef, useState} from 'react';
1+
import React, {useRef, useState} from 'react';
22

3+
import type {SearchQuery} from '@codemirror/search';
34
import {ChevronDown, ChevronUp, Xmark} from '@gravity-ui/icons';
45
import {
56
Button,
67
Card,
78
Checkbox,
89
Icon,
9-
PopoverAnchorRef,
10+
type PopoverAnchorRef,
1011
Popup,
1112
TextInput,
12-
TextInputProps,
13+
type TextInputProps,
1314
sp,
1415
} from '@gravity-ui/uikit';
1516

@@ -19,12 +20,11 @@ import {enterKeyHandler} from '../../../../utils/handlers';
1920

2021
import './SearchPopup.scss';
2122

22-
interface SearchConfig {
23-
isCaseSensitive: boolean;
24-
isWholeWord: boolean;
25-
}
23+
type SearchInitial = Pick<SearchQuery, 'search' | 'caseSensitive' | 'wholeWord'>;
24+
type SearchConfig = Pick<SearchInitial, 'caseSensitive' | 'wholeWord'>;
2625

2726
interface SearchCardProps {
27+
initial: SearchInitial;
2828
onSearchKeyDown?: (query: string) => void;
2929
onChange?: (query: string) => void;
3030
onClose?: (query: string) => void;
@@ -36,28 +36,26 @@ interface SearchCardProps {
3636
const b = cn('search-card');
3737

3838
const noop = () => {};
39+
const inverse = (val: boolean) => !val;
3940

4041
export const SearchCard: React.FC<SearchCardProps> = ({
42+
initial,
4143
onChange = noop,
4244
onClose = noop,
4345
onSearchPrev = noop,
4446
onSearchNext = noop,
4547
onConfigChange = noop,
4648
}) => {
47-
const [query, setQuery] = useState<string>('');
48-
const [isCaseSensitive, setIsCaseSensitive] = useState<boolean>(false);
49-
const [isWholeWord, setIsWholeWord] = useState<boolean>(false);
49+
const [query, setQuery] = useState<string>(initial.search);
50+
const [isCaseSensitive, setIsCaseSensitive] = useState<boolean>(initial.caseSensitive);
51+
const [isWholeWord, setIsWholeWord] = useState<boolean>(initial.wholeWord);
5052
const textInputRef = useRef<HTMLInputElement>(null);
5153

5254
const setInputFocus = () => {
5355
textInputRef.current?.focus();
5456
};
5557

56-
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
57-
const {
58-
target: {value},
59-
} = event;
60-
58+
const handleInputChange = (value: string) => {
6159
setQuery(value);
6260
onChange(value);
6361
};
@@ -80,19 +78,19 @@ export const SearchCard: React.FC<SearchCardProps> = ({
8078

8179
const handleIsCaseSensitive = () => {
8280
onConfigChange({
83-
isCaseSensitive: !isCaseSensitive,
84-
isWholeWord,
81+
caseSensitive: !isCaseSensitive,
82+
wholeWord: isWholeWord,
8583
});
86-
setIsCaseSensitive((isCaseSensitive) => !isCaseSensitive);
84+
setIsCaseSensitive(inverse);
8785
setInputFocus();
8886
};
8987

9088
const handleIsWholeWord = () => {
9189
onConfigChange({
92-
isCaseSensitive,
93-
isWholeWord: !isWholeWord,
90+
caseSensitive: isCaseSensitive,
91+
wholeWord: !isWholeWord,
9492
});
95-
setIsWholeWord((isWholeWord) => !isWholeWord);
93+
setIsWholeWord(inverse);
9694
setInputFocus();
9795
};
9896

@@ -112,7 +110,7 @@ export const SearchCard: React.FC<SearchCardProps> = ({
112110
size="s"
113111
autoFocus
114112
onKeyPress={handleSearchKeyPress}
115-
onChange={handleInputChange}
113+
onUpdate={handleInputChange}
116114
value={query}
117115
endContent={
118116
<>
@@ -140,14 +138,10 @@ export const SearchCard: React.FC<SearchCardProps> = ({
140138
);
141139
};
142140

143-
export interface SearchPopupProps {
141+
export interface SearchPopupProps extends SearchCardProps {
142+
open: boolean;
144143
anchor: HTMLElement;
145-
onChange: (query: string) => void;
146144
onClose: () => void;
147-
onSearchNext: () => void;
148-
onSearchPrev: () => void;
149-
onConfigChange: (config: SearchConfig) => void;
150-
open: boolean;
151145
}
152146

153147
export const SearchPopup: React.FC<SearchPopupProps> = ({open, anchor, onClose, ...props}) => {

0 commit comments

Comments
 (0)