Skip to content

Commit f904171

Browse files
committed
Add find functionality
1 parent 3f9b74a commit f904171

File tree

1 file changed

+80
-26
lines changed

1 file changed

+80
-26
lines changed

packages/code-editor/src/SearchForm/SearchForm.tsx

Lines changed: 80 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
1-
import React, { ChangeEvent, MouseEvent, useCallback, useState } from 'react';
2-
import { closeSearchPanel } from '@codemirror/search';
1+
import React, {
2+
ChangeEvent,
3+
FormEvent,
4+
MouseEvent,
5+
useCallback,
6+
useEffect,
7+
useState,
8+
} from 'react';
9+
import {
10+
closeSearchPanel,
11+
findNext,
12+
findPrevious,
13+
SearchQuery,
14+
selectMatches,
15+
setSearchQuery,
16+
} from '@codemirror/search';
317

418
import Button from '@leafygreen-ui/button';
519
import IconButton from '@leafygreen-ui/icon-button';
@@ -27,6 +41,8 @@ import { SearchFormProps } from './SearchForm.types';
2741

2842
export function SearchForm({ view }: SearchFormProps) {
2943
const [isOpen, setIsOpen] = useState(false);
44+
const [searchString, setSearchString] = useState('');
45+
const [findCount, setFindCount] = useState(0);
3046
const { theme } = useDarkMode();
3147

3248
const handleToggleButtonClick = useCallback(
@@ -43,24 +59,45 @@ export function SearchForm({ view }: SearchFormProps) {
4359
[view],
4460
);
4561

46-
const handleFindInputChange = useCallback(
62+
const handleSearchQueryChange = useCallback(
4763
(_e: ChangeEvent<HTMLInputElement>) => {
48-
// const newQuery = new SearchQuery({
49-
// search: 'test',
50-
// caseSensitive: true,
51-
// regexp: false,
52-
// wholeWord: false,
53-
// replace: '',
54-
// });
55-
// view.dispatch({ effects: setSearchQuery.of(newQuery) });
56-
// if (!query || !query.eq(newQuery)) {
57-
// setQuery(newQuery);
58-
// view.dispatch({ effects: setSearchQuery.of(newQuery) });
59-
// }
64+
setSearchString(_e.target.value);
6065
},
6166
[],
6267
);
6368

69+
useEffect(() => {
70+
const query = new SearchQuery({
71+
search: searchString,
72+
caseSensitive: true,
73+
regexp: false,
74+
wholeWord: false,
75+
replace: '',
76+
});
77+
78+
view.dispatch({ effects: setSearchQuery.of(query) });
79+
80+
const cursor = query.getCursor(view.state.doc);
81+
let count = 0;
82+
83+
let result = cursor.next();
84+
85+
while (!result.done) {
86+
count++;
87+
result = cursor.next();
88+
}
89+
90+
setFindCount(count);
91+
}, [searchString, view]);
92+
93+
const handleFindFormSubmit = useCallback(
94+
(e: FormEvent<HTMLFormElement>) => {
95+
e.preventDefault();
96+
findNext(view);
97+
},
98+
[view],
99+
);
100+
64101
return (
65102
<div
66103
className={getContainerStyles({ theme, isOpen })}
@@ -76,28 +113,45 @@ export function SearchForm({ view }: SearchFormProps) {
76113
<Icon glyph="ChevronDown" className={getToggleIconStyles(isOpen)} />
77114
</IconButton>
78115
<div className={findInputContainerStyles}>
79-
<TextInput
80-
placeholder="Find"
81-
aria-labelledby="find"
82-
onChange={handleFindInputChange}
83-
className={findInputStyles}
84-
// eslint-disable-next-line jsx-a11y/no-autofocus
85-
autoFocus
86-
/>
116+
<form onSubmit={handleFindFormSubmit}>
117+
<TextInput
118+
placeholder="Find"
119+
aria-labelledby="find"
120+
onChange={handleSearchQueryChange}
121+
className={findInputStyles}
122+
// eslint-disable-next-line jsx-a11y/no-autofocus
123+
autoFocus
124+
value={searchString}
125+
/>
126+
</form>
87127
<IconButton
88128
className={findInputIconButtonStyles}
89129
aria-label="filter button"
90130
>
91131
<Icon glyph="Filter" />
92132
</IconButton>
93133
</div>
94-
<IconButton aria-label="next item button">
134+
<IconButton
135+
aria-label="previous item button"
136+
disabled={!searchString || findCount === 0}
137+
onClick={() => findPrevious(view)}
138+
>
95139
<Icon glyph="ArrowUp" />
96140
</IconButton>
97-
<IconButton aria-label="previous item button">
141+
<IconButton
142+
aria-label="next item button"
143+
disabled={!searchString || findCount === 0}
144+
onClick={() => findNext(view)}
145+
>
98146
<Icon glyph="ArrowDown" />
99147
</IconButton>
100-
<Button className={allButtonStyles}>All</Button>
148+
<Button
149+
className={allButtonStyles}
150+
disabled={!searchString || findCount === 0}
151+
onClick={() => selectMatches(view)}
152+
>
153+
All
154+
</Button>
101155
<IconButton
102156
aria-label="close find menu button"
103157
onClick={handleCloseButtonClick}

0 commit comments

Comments
 (0)