Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,27 @@ const baseProps = {
{ label: "dataset", kind: "type" },
] satisfies ComponentSearchSuggestion[],
isLoading: false,
isSearching: false,
isRerankActive: false,
onClearRerank: vi.fn(),
onSuggestedSearch: vi.fn(),
};

describe("ComponentSearchResults", () => {
it("shows a skeleton while search is pending", () => {
render(
<ComponentSearchResults
{...baseProps}
query="csv"
results={[]}
isSearching
/>,
);

expect(screen.getByTestId("search-results-skeleton")).toBeInTheDocument();
expect(screen.getByText("Searching")).toBeInTheDocument();
});

it("shows actionable no-results guidance with clickable suggestions", () => {
const onSuggestedSearch = vi.fn();
render(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import FolderItem from "@/components/shared/ReactFlow/FlowSidebar/components/Fol
import { Button } from "@/components/ui/button";
import { BlockStack, InlineStack } from "@/components/ui/layout";
import { Separator } from "@/components/ui/separator";
import { Skeleton } from "@/components/ui/skeleton";
import { Spinner } from "@/components/ui/spinner";
import { Paragraph, Text } from "@/components/ui/typography";
import type { ComponentSearchSuggestion } from "@/services/componentSearchSuggestions";
Expand All @@ -21,6 +22,7 @@ interface ComponentSearchResultsProps {
browseFolders: UIComponentFolder[];
searchSuggestions: ComponentSearchSuggestion[];
isLoading: boolean;
isSearching: boolean;
isRerankActive: boolean;
onClearRerank: () => void;
onSuggestedSearch: (query: string) => void;
Expand All @@ -32,17 +34,35 @@ export function ComponentSearchResults({
browseFolders,
searchSuggestions,
isLoading,
isSearching,
isRerankActive,
onClearRerank,
onSuggestedSearch,
}: ComponentSearchResultsProps) {
if (isLoading) {
if (isLoading || isSearching) {
return (
<BlockStack gap="2" className="px-2">
<InlineStack align="start" gap="1">
<Text tone="subdued">Search Results </Text>
<BlockStack
gap="2"
className="px-2 min-h-0 flex-1"
data-testid="search-results-skeleton"
>
<InlineStack align="start" gap="1" blockAlign="center">
<Text tone="subdued">
{isSearching ? "Searching" : "Search Results"}
</Text>
<Spinner />
</InlineStack>
<BlockStack gap="2" className="pt-1">
{Array.from({ length: 5 }, (_, index) => (
<InlineStack key={index} gap="2" blockAlign="center">
<Skeleton shape="circle" className="h-4 w-4 shrink-0" />
<BlockStack gap="1" className="min-w-0 flex-1">
<Skeleton size="full" />
<Skeleton size="half" />
</BlockStack>
</InlineStack>
))}
</BlockStack>
</BlockStack>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,17 @@ vi.mock("@/routes/v2/pages/Editor/hooks/useComponentSearchV2State", () => ({
}));

vi.mock("./ComponentSearchResults", () => ({
ComponentSearchResults: ({ query }: { query: string }) => (
<div data-testid="results-query">{query}</div>
ComponentSearchResults: ({
query,
isSearching,
}: {
query: string;
isSearching: boolean;
}) => (
<div>
<div data-testid="results-query">{query}</div>
<div data-testid="results-searching">{String(isSearching)}</div>
</div>
),
}));

Expand Down Expand Up @@ -62,6 +71,7 @@ describe("ComponentSearchV2Content", () => {

expect(input).toHaveValue("csv");
expect(screen.getByTestId("results-query")).toHaveTextContent("");
expect(screen.getByTestId("results-searching")).toHaveTextContent("true");

await act(async () => {
vi.advanceTimersByTime(499);
Expand All @@ -74,6 +84,7 @@ describe("ComponentSearchV2Content", () => {
});

expect(screen.getByTestId("results-query")).toHaveTextContent("csv");
expect(screen.getByTestId("results-searching")).toHaveTextContent("false");
});

it("tracks editor component search completions without query text", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ const EDITOR_SEARCH_RESULT_DEBOUNCE_MS = 500;
function DebouncedComponentSearchInput({
initialValue,
onCommit,
onLocalChange,
}: {
initialValue: string;
onCommit: (value: string) => void;
onLocalChange: (value: string) => void;
}) {
const [localValue, setLocalValue] = useDebouncedSearchValue(
onCommit,
Expand All @@ -36,7 +38,10 @@ function DebouncedComponentSearchInput({
placeholder="Search components..."
className="w-full pl-8 text-sm h-8 focus-visible:ring-gray-400/50"
value={localValue}
onChange={(event) => setLocalValue(event.target.value)}
onChange={(event) => {
setLocalValue(event.target.value);
onLocalChange(event.target.value);
}}
aria-label="Search components"
autoComplete="off"
/>
Expand All @@ -46,6 +51,7 @@ function DebouncedComponentSearchInput({
export function ComponentSearchV2Content() {
const { track } = useAnalytics();
const [query, setQuery] = useState("");
const [localQuery, setLocalQuery] = useState("");
const deferredQuery = useDeferredValue(query);
const [, startSearchTransition] = useTransition();
const {
Expand All @@ -65,10 +71,12 @@ export function ComponentSearchV2Content() {
};

const handleSuggestedSearch = (value: string) => {
setLocalQuery(value);
startSearchTransition(() => setQuery(value));
};

const trimmedDeferredQuery = deferredQuery.trim();
const isSearching = localQuery.trim() !== trimmedDeferredQuery;

useEffect(() => {
if (isLoading || trimmedDeferredQuery.length === 0) return;
Expand Down Expand Up @@ -121,6 +129,7 @@ export function ComponentSearchV2Content() {
<DebouncedComponentSearchInput
initialValue={query}
onCommit={handleQueryCommit}
onLocalChange={setLocalQuery}
/>
</div>
<Button
Expand Down Expand Up @@ -148,6 +157,7 @@ export function ComponentSearchV2Content() {
browseFolders={browseFolders}
searchSuggestions={searchSuggestions}
isLoading={isLoading}
isSearching={isSearching}
isRerankActive={isRerankActive}
onClearRerank={clearRerank}
onSuggestedSearch={handleSuggestedSearch}
Expand Down
Loading