Search
Search Examples
Copy-ready examples with live previews.
Basic usage
Controlled open state and controlled input value.
Live preview
Basic search
import { useMemo, useState } from "react";
import Search from "@/packages/ui/src/_components/search/Search";
import Search_results from "@/packages/ui/src/_components/search/Search_results/Search_results";
const ITEMS = ["Alice", "Bob", "Charlie"];
export default function Example() {
const [open, setOpen] = useState(false);
const [value, setValue] = useState("");
const filtered = useMemo(() => {
const q = value.trim().toLowerCase();
if (!q) return ITEMS;
return ITEMS.filter((x) => x.toLowerCase().includes(q));
}, [value]);
return (
<Search
isView={open}
onOpenChange={setOpen}
value={value}
onValueChange={setValue}
placeholder="Search..."
containerContent={
<Search_results
items={filtered}
renderItem={(t) => <div>{t}</div>}
/>
}
/>
);
}Layout + fit
Switch between layout presets and fit behavior.
• When fit="full", the container must have an explicit height.
Live preview
layout + fit
import { useState } from "react";
import Search from "@/packages/ui/src/_components/search/Search";
export default function Example() {
const [open, setOpen] = useState(true);
const [value, setValue] = useState("ren");
return (
<div style={{ height: 520 }}>
<Search
isView={open}
onOpenChange={setOpen}
value={value}
onValueChange={setValue}
layout="docked"
fit="full"
/>
</div>
);
}Search_results
Standalone results list: divider + stackVariants + custom renderItem.
Live preview
Results list
import Search_results from "@/packages/ui/src/_components/search/Search_results/Search_results";
export default function Example() {
return (
<Search_results
items={["Alpha", "Beta", "Gamma"]}
divider
stackVariants="dense"
renderItem={(t) => <div>{t}</div>}
emptyContent={<div style={{ padding: 16 }}>No results</div>}
/>
);
}Disabled
Disable the whole surface (input + interactions).
Live preview
disabled
import Search from "@/packages/ui/src/_components/search/Search";
export default function Example() {
return (
<Search
isView
disabled
value="search"
onValueChange={() => {}}
onOpenChange={() => {}}
/>
);
}Interactive playground
A richer stage to validate combinations inside the live preview container.
Live preview
Playground
import { useMemo, useState } from "react";
import Search from "@/packages/ui/src/_components/search/Search";
import Search_results from "@/packages/ui/src/_components/search/Search_results/Search_results";
const ITEMS = ["Alice", "Bob", "Charlie"];
export default function Example() {
const [open, setOpen] = useState(false);
const [value, setValue] = useState("");
const filtered = useMemo(() => {
const q = value.trim().toLowerCase();
if (!q) return ITEMS;
return ITEMS.filter((x) => x.toLowerCase().includes(q));
}, [value]);
return (
<div style={{ height: 520 }}>
<Search
isView={open}
onOpenChange={setOpen}
value={value}
onValueChange={setValue}
containerContent={
<Search_results items={filtered} renderItem={(t) => <div>{t}</div>} />
}
/>
</div>
);
}On this page
Search Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| isView | boolean | Yes | — | Controlled state: true shows the expanded search view, false shows the collapsed view. |
| onOpenChange | (nextOpen: boolean) => void | Yes | — | Called when the component requests an open-state change (e.g. focus opens, ESC closes, clear/back buttons). |
| value | string | Yes | — | Controlled input value. |
| onValueChange | (nextValue: string) => void | Yes | — | Called on every input change. Use it to keep the controlled value in sync. |
| placeholder | string | No | "Search..." | Input placeholder. |
| disabled | boolean | No | false | Disables user interaction (input + triggers). |
| layout | "default" | "docked" | No | "default" | Layout preset. Use docked when the search is visually attached to another surface (e.g. a top app bar). |
| fit | "auto" | "full" | No | "auto" | Sizing behavior for the expanded content. When fit='full', the parent container must have an explicit height. |
| leadingContent | React.ReactNode | No | undefined | Slot rendered at the start of the input row (e.g. back/menu button). |
| trailingContent | React.ReactNode | No | undefined | Slot rendered at the end of the input row (e.g. clear button, avatar, mic). |
| containerContent | React.ReactNode | No | undefined | Expanded content (usually a <Search_results /> list). |
| onSubmit | (value: string) => void | No | undefined | Called when the user submits the search (e.g. pressing Enter). |
| inputProps | React.InputHTMLAttributes<HTMLInputElement> | No | undefined | Forwarded props for the underlying <input> (id, name, autoComplete, etc.). |
| className | string | No | undefined | Optional className for the root element. |
| customStyles | React.CSSProperties | No | undefined | Optional inline styles for the root element. |
Search_results Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| items | ReadonlyArray<unknown> | No | [] | Items to render. You control the UI of each row via renderItem. |
| renderItem | (item: unknown, index: number) => React.ReactNode | Yes | — | Row renderer. Return the content of a single result row (text + actions, etc.). |
| stackVariants | "dense" | "normal" | "spacious" | No | "dense" | Spacing preset applied to the internal Stack wrapper for each row. |
| divider | boolean | No | true | When true, renders a divider between rows. |
| emptyContent | React.ReactNode | No | undefined | Rendered when items is empty. |
| rowClassName | string | No | undefined | Optional className applied to each row container. |
| className | string | No | undefined | Optional className for the root element. |
| customStyles | React.CSSProperties | No | undefined | Optional inline styles for the root element. |
Components