From 53e16242b90ab0ca9e30f91704ee98c835fc8bbb Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Tue, 26 Aug 2025 17:06:55 +0200 Subject: [PATCH] ui/search: add loading state --- .../src/components/Search/Search.stories.tsx | 21 +++++ .../ui/src/components/Search/Search.tsx | 87 +++++++++++-------- 2 files changed, 73 insertions(+), 35 deletions(-) diff --git a/pkgs/clan-app/ui/src/components/Search/Search.stories.tsx b/pkgs/clan-app/ui/src/components/Search/Search.stories.tsx index c466280ea..c0d9e9b2c 100644 --- a/pkgs/clan-app/ui/src/components/Search/Search.stories.tsx +++ b/pkgs/clan-app/ui/src/components/Search/Search.stories.tsx @@ -117,6 +117,27 @@ export const Default: Story = { }, }; +export const Loading: Story = { + args: { + // Test with lots of modules + loading: true, + options: [], + renderItem: () => , + }, + render: (args: SearchProps) => { + return ( +
+ + {...args} + onChange={(module) => { + // Go to the module configuration + }} + /> +
+ ); + }, +}; + type MachineOrTag = | { value: string; diff --git a/pkgs/clan-app/ui/src/components/Search/Search.tsx b/pkgs/clan-app/ui/src/components/Search/Search.tsx index 3b09c6604..4e002d96c 100644 --- a/pkgs/clan-app/ui/src/components/Search/Search.tsx +++ b/pkgs/clan-app/ui/src/components/Search/Search.tsx @@ -2,9 +2,10 @@ import Icon from "../Icon/Icon"; import { Button } from "../Button/Button"; import styles from "./Search.module.css"; import { Combobox } from "@kobalte/core/combobox"; -import { createMemo, createSignal, For, JSX } from "solid-js"; +import { createMemo, createSignal, For, JSX, Match, Switch } from "solid-js"; import { createVirtualizer } from "@tanstack/solid-virtual"; import { CollectionNode } from "@kobalte/core/*"; +import { Loader } from "../Loader/Loader"; export interface Option { value: string; @@ -15,6 +16,8 @@ export interface SearchProps { onChange: (value: T | null) => void; options: T[]; renderItem: (item: T) => JSX.Element; + loading?: boolean; + loadingComponent?: JSX.Element; } export function Search(props: SearchProps) { // Controlled input value, to allow resetting the input itself @@ -136,41 +139,55 @@ export function Search(props: SearchProps) { setComboboxItems(arr); return ( -
- - {(virtualRow) => { - const item: CollectionNode | undefined = - items().getItem(virtualRow.key as string); + + + {props.loadingComponent ?? ( +
+ +
+ )} +
+ +
+ + {(virtualRow) => { + const item: CollectionNode | undefined = + items().getItem(virtualRow.key as string); - if (!item) { - console.warn("Item not found for key:", virtualRow.key); - return null; - } - return ( - - {props.renderItem(item.rawValue)} - - ); - }} - -
+ if (!item) { + console.warn( + "Item not found for key:", + virtualRow.key, + ); + return null; + } + return ( + + {props.renderItem(item.rawValue)} + + ); + }} +
+
+ + ); }}