Skip to content

fix: prevent workspace search bar text from getting garbled #9703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Sep 15, 2023
Prev Previous commit
Next Next commit
fix: Add onBlur behavior for state syncs
  • Loading branch information
Parkreiner committed Sep 15, 2023
commit 11c06e1f3f01880c4770713024e40707e9c3f35a
27 changes: 19 additions & 8 deletions site/src/components/Filter/filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,23 @@ export const Filter = ({
learnMoreLink2,
presets,
}: FilterProps) => {
const [searchQuery, setSearchQuery] = useState(filter.query);
// Storing local copy of the filter query so that it can be updated more
// aggressively without re-renders rippling out to the rest of the app every
// single time. Exists for performance reasons - not really a good way to
// remove this; render keys would cause the component to remount too often
const [queryCopy, setQueryCopy] = useState(filter.query);
const textboxInputRef = useRef<HTMLInputElement>(null);

// Conditionally re-syncs the parent and local filter queries
useEffect(() => {
// We don't want to update this while the user is typing something or has
// the focus in the input
const hasInnerFocus =
const hasSelfOrInnerFocus =
textboxInputRef.current?.contains(document.activeElement) ?? false;

if (!hasInnerFocus) {
setSearchQuery(filter.query);
// This doesn't address all state sync issues - namely, what happens if the
// user removes focus just after this synchronizing effect fires. Also need
// to rely on onBlur behavior as an extra safety measure
if (!hasSelfOrInnerFocus) {
setQueryCopy(filter.query);
}
}, [filter.query]);

Expand Down Expand Up @@ -205,12 +211,17 @@ export const Filter = ({
"aria-label": "Filter",
name: "query",
placeholder: "Search...",
value: searchQuery,
value: queryCopy,
ref: textboxInputRef,
onChange: (e) => {
setSearchQuery(e.target.value);
setQueryCopy(e.target.value);
filter.debounceUpdate(e.target.value);
},
onBlur: () => {
if (queryCopy !== filter.query) {
setQueryCopy(filter.query);
}
},
sx: {
borderRadius: "6px",
borderTopLeftRadius: 0,
Expand Down