Skip to content

Commit f7ebbde

Browse files
authored
Reduce code duplication, standardise styling in SICP search (#2707)
* Use BP Menu component for search results * Simplify more menus * Use BP MenuItem for IndexSearchResultsMenuEntry * Improve typing * Simplify index search results rendering * Use BP MenuItem for UserSearchResultsMenuEntry * Simplify text search results rendering * Improve layout
1 parent 34e6867 commit f7ebbde

File tree

2 files changed

+66
-157
lines changed

2 files changed

+66
-157
lines changed

src/commons/navigationBar/subcomponents/SicpNavigationBar.tsx

Lines changed: 49 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
import { Alignment, Drawer, InputGroup, Navbar, NavbarGroup, Position } from '@blueprintjs/core';
1+
import {
2+
Alignment,
3+
Drawer,
4+
InputGroup,
5+
Menu,
6+
MenuItem,
7+
Navbar,
8+
NavbarGroup,
9+
Position
10+
} from '@blueprintjs/core';
211
import { IconNames } from '@blueprintjs/icons';
312
import { memoize } from 'lodash';
413
import * as React from 'react';
@@ -192,14 +201,10 @@ const SicpNavigationBar: React.FC = () => {
192201

193202
const rewritedSearchData: SearchData = memoize(fetchSearchData)();
194203
const [isSubmenuVisible, setIsSubmenuVisible] = React.useState('');
195-
const [isSubmenuVisibleIndex, setIsSubmenuVisibleIndex] = React.useState('');
196204
const [results, setResults] = React.useState(['']);
197205
const [resultsIndex, setResultsIndex] = React.useState([
198206
{ text: '', order: '', id: '', hasSubindex: false }
199207
]);
200-
const [focusedSearchResultIndex, setFocusedSearchResultIndex] = React.useState<number>(-1);
201-
const [focusedIndexSearchResultIndex, setFocusedIndexSearchResultIndex] =
202-
React.useState<number>(-1);
203208
const [searchAutocompleteResults, setSearchAutocompleteResults] = React.useState<string[]>([]);
204209
const [indexAutocompleteResults, setIndexAutocompleteResults] = React.useState<string[]>([]);
205210
const [searchQuery, setSearchQuery] = React.useState('');
@@ -242,7 +247,7 @@ const SicpNavigationBar: React.FC = () => {
242247
children: React.ReactNode,
243248
ref: React.RefObject<HTMLDivElement>
244249
) => React.ReactNode
245-
) => {
250+
): React.ReactNode => {
246251
if (isSubMenueHidden(searchInput)) {
247252
return <></>;
248253
}
@@ -296,44 +301,20 @@ const SicpNavigationBar: React.FC = () => {
296301
};
297302

298303
const buildUserSearchResultsMenuEntry = (result: any, index: number) => (
299-
<div
300-
style={{
301-
margin: '0',
302-
width: '100%',
303-
backgroundColor: focusedSearchResultIndex !== index ? 'white' : 'grey',
304-
border: '1px solid black'
305-
}}
304+
<MenuItem
305+
multiline
306+
text={getDisplayedIndex(result) + focusResult(rewritedSearchData.idToContentMap[result])}
306307
key={index}
307308
onClick={() => {
308309
setIndexAutoCompleteCouldShow(false);
309310
setSearchAutoCompleteCouldShow(false);
310311
handleNavigation(result);
311312
}}
312-
onMouseOver={() => setFocusedSearchResultIndex(index)}
313-
>
314-
{getDisplayedIndex(result) + focusResult(rewritedSearchData.idToContentMap[result])}
315-
</div>
313+
/>
316314
);
317315

318316
const buildSearchResultsMenuWith = (children: React.ReactNode) => {
319-
return (
320-
<div
321-
style={{
322-
height: '4000%',
323-
overflowY: 'auto',
324-
position: 'absolute',
325-
top: `0`,
326-
left: '100%',
327-
width: '300%',
328-
backgroundColor: 'white',
329-
overflow: 'auto',
330-
margin: 0,
331-
padding: 0
332-
}}
333-
>
334-
{children}
335-
</div>
336-
);
317+
return children;
337318
};
338319

339320
return menu(
@@ -347,7 +328,7 @@ const SicpNavigationBar: React.FC = () => {
347328

348329
const indexSearchResultSubMenu = (searchInput: string) => {
349330
const isIndexSearchSubMenuHidden = (searchInput: String) => {
350-
return !(isSubmenuVisibleIndex === searchInput);
331+
return false;
351332
};
352333

353334
const getIndexSearchResults = () => {
@@ -366,46 +347,20 @@ const SicpNavigationBar: React.FC = () => {
366347

367348
const buildIndexSearchResultsMenuEntry = (result: any, index: number) => {
368349
return (
369-
<div
370-
style={{
371-
margin: '0',
372-
width: '100%',
373-
backgroundColor: focusedIndexSearchResultIndex !== index ? 'white' : 'grey',
374-
border: '1px solid black'
375-
}}
350+
<MenuItem
351+
text={<Latex>{result.text.replaceAll('LATEX: ', '')}</Latex>}
376352
key={index}
377353
onClick={() => {
378354
setIndexAutoCompleteCouldShow(false);
379355
setSearchAutoCompleteCouldShow(false);
380356
handleNavigation(result.id);
381357
}}
382-
onMouseOver={() => setFocusedIndexSearchResultIndex(index)}
383-
>
384-
<Latex>{result.text.replaceAll('LATEX: ', '')}</Latex>
385-
</div>
358+
/>
386359
);
387360
};
388361

389362
const buildIndexSearchResultsMenuWith = (children: React.ReactNode) => {
390-
return (
391-
<div
392-
style={{
393-
height: '4000%',
394-
overflowY: 'auto',
395-
position: 'absolute',
396-
top: `0`,
397-
left: '100%',
398-
width: '200%',
399-
backgroundColor: 'white',
400-
outline: 'dashed',
401-
overflow: 'auto',
402-
margin: 0,
403-
padding: 0
404-
}}
405-
>
406-
{children}
407-
</div>
408-
);
363+
return children;
409364
};
410365

411366
return menu(
@@ -431,29 +386,16 @@ const SicpNavigationBar: React.FC = () => {
431386
};
432387

433388
const buildUserSearchAutocompleteMenuEntry = (result: any, index: number) => (
434-
<div
435-
style={{
436-
margin: 0,
437-
cursor: 'pointer',
438-
position: 'relative',
439-
display: 'flex',
440-
border: '1px solid black'
389+
<MenuItem
390+
text={result}
391+
onMouseOver={() => {
392+
setResults(sentenceSearch(result));
393+
setIsSubmenuVisible(result);
441394
}}
395+
onClick={() => setSearchQuery(result)}
442396
>
443-
<div
444-
style={{ width: '100%', backgroundColor: isSubmenuVisible !== result ? 'white' : 'grey' }}
445-
onMouseOver={() => {
446-
setFocusedSearchResultIndex(-1);
447-
setResults(sentenceSearch(result));
448-
setIsSubmenuVisible(result);
449-
}}
450-
onClick={() => setSearchQuery(result)}
451-
>
452-
{result}
453-
</div>
454-
455397
{userSearchResultSubMenu(result)}
456-
</div>
398+
</MenuItem>
457399
);
458400

459401
return menu(
@@ -479,34 +421,13 @@ const SicpNavigationBar: React.FC = () => {
479421
};
480422

481423
const buildIndexSearchAutocompleteMenuEntry = (result: any, index: number) => (
482-
<div
483-
style={{
484-
border: '1px solid black',
485-
margin: 0,
486-
cursor: 'pointer',
487-
position: 'relative',
488-
display: 'flex'
489-
}}
424+
<MenuItem
425+
text={result}
426+
onMouseOver={() => setResultsIndex(search(result, rewritedSearchData.indexTrie))}
427+
onClick={() => setIndexSearchQuery(result)}
490428
>
491-
<div
492-
style={{
493-
width: '100%',
494-
backgroundColor: isSubmenuVisibleIndex !== result ? 'white' : 'grey'
495-
}}
496-
onMouseOver={() => {
497-
//setIndexSearchQuery(result);
498-
setFocusedIndexSearchResultIndex(-1);
499-
setResultsIndex(search(result, rewritedSearchData.indexTrie));
500-
setIsSubmenuVisibleIndex(result);
501-
}}
502-
onClick={() => {
503-
setIndexSearchQuery(result);
504-
}}
505-
>
506-
{result}
507-
</div>
508429
{indexSearchResultSubMenu(result)}
509-
</div>
430+
</MenuItem>
510431
);
511432

512433
return menu(
@@ -522,35 +443,21 @@ const SicpNavigationBar: React.FC = () => {
522443
children: React.ReactNode,
523444
ref: React.RefObject<HTMLDivElement>
524445
) => {
525-
return (
526-
<div
527-
style={{
528-
position: 'absolute',
529-
backgroundColor: 'white',
530-
width: '75%'
531-
}}
532-
ref={ref}
533-
>
534-
{children}
535-
</div>
536-
);
446+
return <Menu style={{ position: 'absolute', top: '100%', width: '100%' }}>{children}</Menu>;
537447
};
538448

539449
const handleUserSearchButton = () => {
540-
setFocusedSearchResultIndex(-1);
541450
setResults(sentenceSearch(searchQuery));
542451
setIsSubmenuVisible(searchQuery);
543452
};
544453

545454
const handleIndexSearchButton = () => {
546-
setFocusedIndexSearchResultIndex(-1);
547455
setResultsIndex(search(indexSearchQuery, rewritedSearchData.indexTrie));
548-
setIsSubmenuVisibleIndex(indexSearchQuery);
549456
};
550457

551458
const userSearch = (
552459
<div style={{ position: 'relative' }}>
553-
<div style={{ display: 'inline-flex' }} ref={searchInputRef}>
460+
<div ref={searchInputRef}>
554461
<InputGroup
555462
placeholder="Search"
556463
value={searchQuery}
@@ -560,16 +467,18 @@ const SicpNavigationBar: React.FC = () => {
560467
setSearchAutoCompleteCouldShow(true);
561468
setSearchAutocompleteResults(sentenceAutoComplete(s));
562469
}}
470+
rightElement={
471+
<ControlButton label="Text" icon={IconNames.SEARCH} onClick={handleUserSearchButton} />
472+
}
563473
/>
564-
<ControlButton label="Text" icon={IconNames.SEARCH} onClick={handleUserSearchButton} />
565474
</div>
566475
{userSearchAutocompleteMenu(searchQuery)}
567476
</div>
568477
);
569478

570479
const indexSearch = (
571480
<div style={{ position: 'relative' }}>
572-
<div style={{ display: 'inline-flex' }} ref={indexSearchInputRef}>
481+
<div ref={indexSearchInputRef}>
573482
<InputGroup
574483
placeholder="Search"
575484
value={indexSearchQuery}
@@ -579,16 +488,23 @@ const SicpNavigationBar: React.FC = () => {
579488
setIndexAutoCompleteCouldShow(true);
580489
setIndexAutocompleteResults(indexAutoComplete(s));
581490
}}
491+
rightElement={
492+
<ControlButton
493+
label="Index"
494+
icon={IconNames.SEARCH}
495+
onClick={handleIndexSearchButton}
496+
/>
497+
}
582498
/>
583-
<ControlButton label="Index" icon={IconNames.SEARCH} onClick={handleIndexSearchButton} />
584499
</div>
585500
{indexSearchAutocompleteMenu(indexSearchQuery)}
586501
</div>
587502
);
588503

589504
const searchWrapper = (
590-
<div style={{ display: 'flex', width: '100%', justifyContent: 'center' }} key="searchWrapper">
591-
{[userSearch, indexSearch]}
505+
<div style={{ width: '100%', display: 'flex', gap: 2, justifyContent: 'center' }}>
506+
{userSearch}
507+
{indexSearch}
592508
</div>
593509
);
594510

src/commons/navigationBar/subcomponents/__tests__/__snapshots__/SicpNavigationBar.tsx.snap

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ exports[`Navbar renders correctly 1`] = `
3535
style={
3636
Object {
3737
"display": "flex",
38+
"gap": 2,
3839
"justifyContent": "center",
3940
"width": "100%",
4041
}
@@ -47,23 +48,19 @@ exports[`Navbar renders correctly 1`] = `
4748
}
4849
}
4950
>
50-
<div
51-
style={
52-
Object {
53-
"display": "inline-flex",
54-
}
55-
}
56-
>
51+
<div>
5752
<Blueprint4.InputGroup
5853
onChange={[Function]}
5954
placeholder="Search"
55+
rightElement={
56+
<ControlButton
57+
icon="search"
58+
label="Text"
59+
onClick={[Function]}
60+
/>
61+
}
6062
value=""
6163
/>
62-
<ControlButton
63-
icon="search"
64-
label="Text"
65-
onClick={[Function]}
66-
/>
6764
</div>
6865
<React.Fragment />
6966
</div>
@@ -74,23 +71,19 @@ exports[`Navbar renders correctly 1`] = `
7471
}
7572
}
7673
>
77-
<div
78-
style={
79-
Object {
80-
"display": "inline-flex",
81-
}
82-
}
83-
>
74+
<div>
8475
<Blueprint4.InputGroup
8576
onChange={[Function]}
8677
placeholder="Search"
78+
rightElement={
79+
<ControlButton
80+
icon="search"
81+
label="Index"
82+
onClick={[Function]}
83+
/>
84+
}
8785
value=""
8886
/>
89-
<ControlButton
90-
icon="search"
91-
label="Index"
92-
onClick={[Function]}
93-
/>
9487
</div>
9588
<React.Fragment />
9689
</div>

0 commit comments

Comments
 (0)