Skip to content

Commit 78f21f0

Browse files
committed
Add find selected index rendering
1 parent 67ecba2 commit 78f21f0

File tree

2 files changed

+103
-14
lines changed

2 files changed

+103
-14
lines changed

packages/code-editor/src/SearchForm/SearchForm.styles.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { color } from '@leafygreen-ui/tokens';
1313
const CONTAINER_MAX_WIDTH = 500;
1414
const SECTION_HEIGHT = 52;
1515
const INPUT_WIDTH = 240;
16+
const INPUT_MIN_WIDTH = 120;
1617

1718
const getBaseContainerStyles = (theme: Theme) => css`
1819
background-color: ${color[theme].background[Variant.Secondary][
@@ -114,9 +115,13 @@ export const getToggleIconStyles = (isOpen: boolean) =>
114115
export const findInputContainerStyles = css`
115116
position: relative;
116117
flex: 1 1 ${INPUT_WIDTH}px;
117-
min-width: 100px;
118+
min-width: ${INPUT_MIN_WIDTH}px;
118119
max-width: ${INPUT_WIDTH}px;
119120
margin-right: ${spacing[100]}px;
121+
122+
& input {
123+
padding-right: ${spacing[1200]}px;
124+
}
120125
`;
121126

122127
export const allButtonStyles = css`
@@ -127,12 +132,26 @@ export const closeButtonStyles = css`
127132
margin-left: auto;
128133
`;
129134

130-
export const findInputIconButtonStyles = css`
135+
export const findOptionsContainerStyles = css`
131136
position: absolute;
132137
right: ${spacing[100]}px;
133138
top: ${spacing[100]}px;
139+
display: flex;
140+
align-items: center;
134141
`;
135142

143+
// export const findInputIconButtonStyles = css`
144+
// position: absolute;
145+
// right: ${spacing[100]}px;
146+
// top: ${spacing[100]}px;
147+
// `;
148+
149+
// export const findCountStyles = css`
150+
// position: absolute;
151+
// right: ${spacing[200]}px;
152+
// top: ${spacing[100]}px;
153+
// `;
154+
136155
export const replaceInputContainerStyles = css`
137156
position: relative;
138157
flex: 1 1 ${INPUT_WIDTH}px;

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

Lines changed: 82 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@ import Button from '@leafygreen-ui/button';
1919
import IconButton from '@leafygreen-ui/icon-button';
2020
import { useDarkMode } from '@leafygreen-ui/leafygreen-provider';
2121
import TextInput from '@leafygreen-ui/text-input';
22+
import { Body } from '@leafygreen-ui/typography';
2223

2324
import { Icon } from '../../../icon/src/Icon';
2425

2526
import {
2627
allButtonStyles,
2728
closeButtonStyles,
2829
findInputContainerStyles,
29-
findInputIconButtonStyles,
3030
findInputStyles,
31+
findOptionsContainerStyles,
3132
findSectionStyles,
3233
getContainerStyles,
3334
getReplaceInnerSectionStyles,
@@ -44,6 +45,7 @@ export function SearchForm({ view }: SearchFormProps) {
4445
const [searchString, setSearchString] = useState('');
4546
const [findCount, setFindCount] = useState(0);
4647
const { theme } = useDarkMode();
48+
const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
4749

4850
const handleToggleButtonClick = useCallback(
4951
(_e: MouseEvent<HTMLButtonElement>) => {
@@ -66,6 +68,35 @@ export function SearchForm({ view }: SearchFormProps) {
6668
[],
6769
);
6870

71+
const computeSelectedIndex = useCallback(() => {
72+
const query = new SearchQuery({
73+
search: searchString,
74+
caseSensitive: true,
75+
regexp: false,
76+
wholeWord: false,
77+
replace: '',
78+
});
79+
80+
const cursor = query.getCursor(view.state.doc);
81+
const selection = view.state.selection.main;
82+
83+
let index = 1;
84+
let result = cursor.next();
85+
86+
while (!result.done) {
87+
if (
88+
result.value.from === selection.from &&
89+
result.value.to === selection.to
90+
) {
91+
return index;
92+
}
93+
index++;
94+
result = cursor.next();
95+
}
96+
97+
return null;
98+
}, [searchString, view]);
99+
69100
useEffect(() => {
70101
const query = new SearchQuery({
71102
search: searchString,
@@ -87,16 +118,48 @@ export function SearchForm({ view }: SearchFormProps) {
87118
}
88119

89120
setFindCount(count);
90-
}, [searchString, view]);
121+
122+
// Update selected index if current selection matches one of the results
123+
const selection = view.state.selection.main;
124+
const cursor2 = query.getCursor(view.state.doc);
125+
let idx = 1;
126+
let res2 = cursor2.next();
127+
let currentIndex: number | null = null;
128+
129+
while (!res2.done) {
130+
if (
131+
res2.value.from === selection.from &&
132+
res2.value.to === selection.to
133+
) {
134+
currentIndex = idx;
135+
break;
136+
}
137+
idx++;
138+
res2 = cursor2.next();
139+
}
140+
141+
setSelectedIndex(currentIndex);
142+
}, [searchString, view, computeSelectedIndex]);
91143

92144
const handleFindFormSubmit = useCallback(
93145
(e: FormEvent<HTMLFormElement>) => {
94146
e.preventDefault();
95147
findNext(view);
148+
setSelectedIndex(computeSelectedIndex());
96149
},
97-
[view],
150+
[view, computeSelectedIndex],
98151
);
99152

153+
const handleNextClick = useCallback(() => {
154+
findNext(view);
155+
setSelectedIndex(computeSelectedIndex());
156+
}, [view, computeSelectedIndex]);
157+
158+
const handlePreviousClick = useCallback(() => {
159+
findPrevious(view);
160+
setSelectedIndex(computeSelectedIndex());
161+
}, [view, computeSelectedIndex]);
162+
100163
return (
101164
<div
102165
className={getContainerStyles({ theme, isOpen })}
@@ -123,31 +186,38 @@ export function SearchForm({ view }: SearchFormProps) {
123186
value={searchString}
124187
/>
125188
</form>
126-
<IconButton
127-
className={findInputIconButtonStyles}
128-
aria-label="filter button"
129-
>
130-
<Icon glyph="Filter" />
131-
</IconButton>
189+
<div className={findOptionsContainerStyles}>
190+
{searchString && (
191+
<Body>
192+
{selectedIndex ?? '?'}/{findCount}
193+
</Body>
194+
)}
195+
<IconButton aria-label="filter button">
196+
<Icon glyph="Filter" />
197+
</IconButton>
198+
</div>
132199
</div>
133200
<IconButton
134201
aria-label="previous item button"
135202
disabled={!searchString || findCount === 0}
136-
onClick={() => findPrevious(view)}
203+
onClick={handlePreviousClick}
137204
>
138205
<Icon glyph="ArrowUp" />
139206
</IconButton>
140207
<IconButton
141208
aria-label="next item button"
142209
disabled={!searchString || findCount === 0}
143-
onClick={() => findNext(view)}
210+
onClick={handleNextClick}
144211
>
145212
<Icon glyph="ArrowDown" />
146213
</IconButton>
147214
<Button
148215
className={allButtonStyles}
149216
disabled={!searchString || findCount === 0}
150-
onClick={() => selectMatches(view)}
217+
onClick={() => {
218+
selectMatches(view);
219+
setSelectedIndex(null);
220+
}}
151221
>
152222
All
153223
</Button>

0 commit comments

Comments
 (0)