Sure
So here is an example of UI
Here is the code for my Search Input:
export const StreamPostsSearch = () => {
const { q } = useStreamPostsLoaderData();
const [, setSearchParams] = useSearchParams();
const debouncedSetSearchParams = useDebouncedCallback(setSearchParams, 200);
const onValueChange = useCallback(
(value?: string) => {
const query = value || '';
if (query.length === 0) {
setSearchParams((prev) => deleteSearchParams(prev, ['q']), {
preventScrollReset: true,
});
debouncedSetSearchParams.cancel();
} else {
debouncedSetSearchParams({ q: query }, { preventScrollReset: true });
}
},
[debouncedSetSearchParams, setSearchParams],
);
return (
<SearchInput
placeholder="Filter posts..."
onQueryChange={onValueChange}
defaultValue={q}
/>
);
};
and react-router loader looks like this:
const SearchStreamPostsQuery = gql(`
query SearchStreamPostsQuery($query: String!, $streamId: ID!, $limit: Int!, $offset: Int!) {
searchStreamPosts(input: {streamId: $streamId, text: $query, limit: $limit, offset: $offset}) {
items {
... on StreamPost {
...StreamPostCardFragment
}
}
}
}
`);
export const clientLoader = ({
request,
params,
}: Route.ClientLoaderArgs) => {
const searchParams = new URL(request.url).searchParams;
const q = (searchParams.get('q') || '').trim();
return {
q,
searchStreamPostsQueryRef: q
? preloadQuery(SearchStreamPostsQuery, {
variables: {
streamId: params.id,
query: q,
limit: 20,
offset: 0,
},
fetchPolicy: 'network-only',
})
: null,
};
};
later in the code I do something like
const {searchStreamPostsQueryRef} = useLoaderData();
return searchStreamPostsQueryRef ? <SearchFeed/> :
return (<Container after={<StreamPostsSearch/>}>
<Suspense fallback={<Skeleton/>}>
{searchStreamPostsQueryRef ? <SearchFeed queryRef={searchStreamPostsQueryRef} /> : <RegularFeed/>}
</Suspense>
</Container>);
So I was thinking about the way of rendering spinner icon inside StreamPostsSearch in addition or instead of skeleton
Will this be enough or better to prepare the sandbox?