Skip to content

Commit b10cda1

Browse files
[ENG-1335] Node create modal results limit (#854)
* Add 50-result limit to FuzzySelectInput to prevent UI freezes - Limit displayed results to max 50 items in node create modal - Show truncation hint when results exceed limit - Update keyboard navigation and selection to use displayedItems - Fixes ENG-1335: Performance issues with large result sets Co-authored-by: Trang Doan <trangdoan982@users.noreply.github.com> * Remove truncation hint from FuzzySelectInput Users don't need to see the truncation message Co-authored-by: Trang Doan <trangdoan982@users.noreply.github.com> * lower lim * address PR comments --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Trang Doan <trangdoan982@users.noreply.github.com>
1 parent 82055e1 commit b10cda1

1 file changed

Lines changed: 18 additions & 6 deletions

File tree

apps/roam/src/components/FuzzySelectInput.tsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import {
1717
import fuzzy from "fuzzy";
1818
import { Result } from "~/utils/types";
1919

20+
const RESULTS_LIMIT = 50;
21+
2022
type FuzzySelectInputProps<T extends Result = Result> = {
2123
value?: T;
2224
setValue: (q: T) => void;
@@ -51,6 +53,10 @@ const FuzzySelectInput = <T extends Result = Result>({
5153
.map((result) => result.original);
5254
}, [query, options]);
5355

56+
const displayedItems = useMemo(() => {
57+
return filteredItems.slice(0, RESULTS_LIMIT);
58+
}, [filteredItems]);
59+
5460
const handleSelect = useCallback(
5561
(item: T) => {
5662
setQuery(item.text);
@@ -84,15 +90,15 @@ const FuzzySelectInput = <T extends Result = Result>({
8490
if (e.key === "ArrowDown") {
8591
e.preventDefault();
8692
setActiveIndex((prev) =>
87-
prev < filteredItems.length - 1 ? prev + 1 : prev,
93+
prev < displayedItems.length - 1 ? prev + 1 : prev,
8894
);
8995
} else if (e.key === "ArrowUp") {
9096
e.preventDefault();
9197
setActiveIndex((prev) => (prev > 0 ? prev - 1 : 0));
9298
} else if (e.key === "Enter") {
9399
e.preventDefault();
94100
e.stopPropagation();
95-
if (isOpen && filteredItems[activeIndex]) {
101+
if (isOpen && displayedItems[activeIndex]) {
96102
const keyUpHandler = (keyUpEvent: KeyboardEvent) => {
97103
if (keyUpEvent.key === "Enter" || keyUpEvent.key === " ") {
98104
keyUpEvent.preventDefault();
@@ -104,14 +110,14 @@ const FuzzySelectInput = <T extends Result = Result>({
104110
setTimeout(() => {
105111
document.removeEventListener("keyup", keyUpHandler, true);
106112
}, 150);
107-
handleSelect(filteredItems[activeIndex]);
113+
handleSelect(displayedItems[activeIndex]);
108114
}
109115
} else if (e.key === "Escape") {
110116
e.preventDefault();
111117
setIsOpen(false);
112118
}
113119
},
114-
[filteredItems, activeIndex, isOpen, handleSelect],
120+
[displayedItems, activeIndex, isOpen, handleSelect],
115121
);
116122

117123
useEffect(() => {
@@ -129,7 +135,7 @@ const FuzzySelectInput = <T extends Result = Result>({
129135

130136
useEffect(() => {
131137
setActiveIndex(0);
132-
}, [filteredItems]);
138+
}, [displayedItems]);
133139

134140
useEffect(() => {
135141
if (menuRef.current && isOpen) {
@@ -200,7 +206,7 @@ const FuzzySelectInput = <T extends Result = Result>({
200206
enforceFocus={false}
201207
content={
202208
<Menu className="max-h-64 max-w-md overflow-auto" ulRef={menuRef}>
203-
{filteredItems.map((item, index) => (
209+
{displayedItems.map((item, index) => (
204210
<MenuItem
205211
key={item.uid || index}
206212
text={item.text}
@@ -212,6 +218,12 @@ const FuzzySelectInput = <T extends Result = Result>({
212218
multiline
213219
/>
214220
))}
221+
{filteredItems.length > RESULTS_LIMIT && (
222+
<li className="px-3 py-2 text-center text-xs italic text-gray-500">
223+
Showing first {RESULTS_LIMIT} results — refine your search to see
224+
more.
225+
</li>
226+
)}
215227
</Menu>
216228
}
217229
target={

0 commit comments

Comments
 (0)