Skip to content

Commit

Permalink
refactor: add loading ux to search results page
Browse files Browse the repository at this point in the history
  • Loading branch information
johnshift committed Dec 13, 2024
1 parent e345944 commit e128aa4
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 14 deletions.
10 changes: 10 additions & 0 deletions src/app/search/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { PillarRoutesContextProvider } from '@/search/state/contexts/pillar-routes-context';

interface Props {
children: React.ReactNode;
}

const Layout = ({ children }: Props) => {
return <PillarRoutesContextProvider>{children}</PillarRoutesContextProvider>;
};
export default Layout;
2 changes: 1 addition & 1 deletion src/search/components/pillar-items-dropdown-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { getPillarItems } from '@/search/data/get-pillar-items';
import { usePillarRoutesContext } from '@/search/state/contexts/pillar-routes-context';

const ITEMS_PER_PAGE = 20;
const DEBOUNCE_DELAY = 300;
const DEBOUNCE_DELAY = 500;

interface Props {
nav: string;
Expand Down
34 changes: 21 additions & 13 deletions src/search/components/plain-search-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import { useEffect, useRef } from 'react';

import { Button } from '@nextui-org/button';
import { Input } from '@nextui-org/input';
import { Spinner } from '@nextui-org/spinner';

import { CloseIcon } from '@/shared/components/icons/close-icon';
import { SearchIcon } from '@/shared/components/icons/sidebar-search-icon';

import { useSearchInput } from '@/search/hooks/use-search-input';

import { usePillarRoutesContext } from '@/search/state/contexts/pillar-routes-context';

export const PlainSearchInput = () => {
const { value, onChange, onClear } = useSearchInput();
const { isPendingPillarRoute } = usePillarRoutesContext();

const inputRef = useRef<HTMLInputElement>(null);

Expand All @@ -30,23 +34,27 @@ export const PlainSearchInput = () => {
<SearchIcon />
</div>
}
endContent={
value ? (
<Button
isIconOnly
size="sm"
onClick={onClear}
variant="light"
className="bg-white/5"
>
<CloseIcon />
</Button>
) : null
}
radius="sm"
classNames={{
input: 'focus:ring-red-500 focus:border-red-500',
}}
endContent={
<>
{isPendingPillarRoute && <Spinner size="sm" color="white" />}
{value && (
<Button
isIconOnly
size="sm"
onClick={onClear}
variant="light"
className="bg-white/5"
>
<CloseIcon />
</Button>
)}
</>
}
isDisabled={isPendingPillarRoute}
value={value}
onChange={onChange}
/>
Expand Down
12 changes: 12 additions & 0 deletions src/search/components/search-result-item.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
'use client';

import Link from 'next/link';
import { useRouter } from 'next/navigation';

import { Button } from '@nextui-org/button';

import { ExternalIcon } from '@/shared/components/icons/external-icon';

import { TSearchResultItem } from '@/search/core/schemas';

import { usePillarRoutesContext } from '@/search/state/contexts/pillar-routes-context';

const escapeRegExp = (str: string): string =>
str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');

Expand Down Expand Up @@ -38,13 +41,22 @@ interface Props extends TSearchResultItem {
}

export const SearchResultItem = ({ label, href, query }: Props) => {
const router = useRouter();
const { isPendingPillarRoute, startTransition } = usePillarRoutesContext();
const onClick = () => {
startTransition(() => {
router.push(href);
});
};
return (
<Button
as={Link}
href={href}
size="sm"
className=""
isDisabled={isPendingPillarRoute}
endContent={<ExternalIcon />}
onClick={onClick}
>
<span className="text-13">{highlightText(label, query)}</span>
</Button>
Expand Down

0 comments on commit e128aa4

Please sign in to comment.