Search 10.17.4
Search enables users to specify a word or a phrase to find relevant pieces of content without the use of navigation.
Default
"use client";
import { useMemo, useState } from "react";
import {
MenuItem,
Search,
searchFilterItems,
searchGetItemIndex,
} from "@heathmont/moon-core-tw";
interface Item {
children?: React.ReactNode;
href?: string;
id: string;
}
interface Items {
items: Item[];
heading?: string;
id: string;
}
const Default = () => {
const [open, setOpen] = useState<boolean>(false);
const [search, setSearch] = useState("");
const filteredItems = useMemo(
() =>
searchFilterItems(
[
{
heading: "Results",
id: "results",
items: [
{
id: "home",
children: "Home",
href: "#home",
},
{
id: "settings",
children: "Settings",
href: "#settings",
},
{
id: "projects",
children: "Projects",
closeOnSelect: false,
onClick: () => {
alert("projects");
},
},
],
},
{
heading: "Other",
id: "other",
items: [
{
id: "developer-settings",
children: "Developer settings",
href: "#developer-settings",
},
{
id: "privacy-policy",
children: "Privacy policy",
href: "#privacy-policy",
},
{
id: "log-out",
children: "Log out",
onClick: () => {
alert("Logging out...");
},
},
],
},
],
search,
),
[search],
);
return (
<div className="w-full xl:mx-32">
<Search
onChangeSearch={setSearch}
onChangeOpen={setOpen}
search={search}
isOpen={open}
>
<Search.Input>
<Search.Input.Icon />
<Search.Input.Input />
<Search.Input.ButtonClear>Clear</Search.Input.ButtonClear>
</Search.Input>
<Search.Result>
{filteredItems.length ? (
filteredItems.map((list: Items) => (
<ul className="space-y-1" key={list.id}>
<li>
<Search.ResultHeading>{list.heading}</Search.ResultHeading>
{list.items.map(({ id, children, href, ...rest }: Item) => (
<Search.ResultItem
key={id}
index={searchGetItemIndex(filteredItems, id)}
closeOnSelect={true}
{...rest}
>
{href ? (
<a href={href}>
<MenuItem>
<MenuItem.Title>{children}</MenuItem.Title>
<span className="text-moon-12 text-trunks">
{href}
</span>
</MenuItem>
</a>
) : (
<MenuItem>
<MenuItem.Title>{children}</MenuItem.Title>
<span className="text-moon-12 text-trunks">
Action
</span>
</MenuItem>
)}
</Search.ResultItem>
))}
</li>
</ul>
))
) : (
<Search.NoResults />
)}
</Search.Result>
</Search>
</div>
);
};
export default Default;
With transition
To add an additional transition effect when Search
results appear smoothly, you can wrap a <Search.Result />
sub-component with a <Search.Transition />
.
"use client";
import { useMemo, useState } from "react";
import {
MenuItem,
Search,
searchFilterItems,
searchGetItemIndex,
} from "@heathmont/moon-core-tw";
interface Item {
children?: React.ReactNode;
href?: string;
id: string;
}
interface Items {
items: Item[];
heading?: string;
id: string;
}
const WithTransition = () => {
const [open, setOpen] = useState<boolean>(false);
const [search, setSearch] = useState("");
const filteredItems = useMemo(
() =>
searchFilterItems(
[
{
heading: "Results",
id: "results",
items: [
{
id: "home",
children: "Home",
href: "#home",
},
{
id: "settings",
children: "Settings",
href: "#settings",
},
{
id: "projects",
children: "Projects",
closeOnSelect: false,
onClick: () => {
alert("projects");
},
},
],
},
{
heading: "Other",
id: "other",
items: [
{
id: "developer-settings",
children: "Developer settings",
href: "#developer-settings",
},
{
id: "privacy-policy",
children: "Privacy policy",
href: "#privacy-policy",
},
{
id: "log-out",
children: "Log out",
onClick: () => {
alert("Logging out...");
},
},
],
},
],
search,
),
[search],
);
return (
<div className="w-full xl:mx-32">
<Search
onChangeSearch={setSearch}
onChangeOpen={setOpen}
search={search}
isOpen={open}
>
<Search.Input>
<Search.Input.Icon />
<Search.Input.Input />
<Search.Input.ButtonClear>Clear</Search.Input.ButtonClear>
</Search.Input>
<Search.Transition>
<Search.Result>
{filteredItems.length ? (
filteredItems.map((list: Items) => (
<ul className="space-y-1" key={list.id}>
<li>
<Search.ResultHeading>{list.heading}</Search.ResultHeading>
{list.items.map(({ id, children, href, ...rest }: Item) => (
<Search.ResultItem
key={id}
index={searchGetItemIndex(filteredItems, id)}
closeOnSelect={true}
{...rest}
>
{href ? (
<a href={href}>
<MenuItem>
<MenuItem.Title>{children}</MenuItem.Title>
<span className="text-moon-12 text-trunks">
{href}
</span>
</MenuItem>
</a>
) : (
<MenuItem>
<MenuItem.Title>{children}</MenuItem.Title>
<span className="text-moon-12 text-trunks">
Action
</span>
</MenuItem>
)}
</Search.ResultItem>
))}
</li>
</ul>
))
) : (
<Search.NoResults />
)}
</Search.Result>
</Search.Transition>
</Search>
</div>
);
};
export default WithTransition;
Search
These are props specific to the Search component:
Name | Type | Default |
---|---|---|
className | string | - |
isOpen* | boolean | - |
onChangeOpen* | (isOpen: boolean) => void | - |
onChangeSearch* | (search: string) => void | - |
onChangeSelected | (value: number) => void | - |
search* | string | - |
Properties indicated with * are required.
Search.Input
These are props specific to the Search.Input component:
Name | Type | Default |
---|---|---|
className | string | - |
Search.Input.Icon
These are props specific to the Search.Input.Icon component:
Name | Type | Default |
---|---|---|
className | string | - |
Search.Input.Input
These are props specific to the Search.Input.Input component:
Name | Type | Default |
---|---|---|
autoFocus | boolean | false |
className | string | - |
placeholder | string | Search |
Search.Input.ButtonClear
These are props specific to the Search.Input.ButtonClear component:
Name | Type | Default |
---|---|---|
className | string | - |
Search.Transition
These are props specific to the Search.Transition component:
Name | Type | Default |
---|---|---|
className | string | - |
Search.NoResults
These are props specific to the Search.NoResults component:
Name | Type | Default |
---|---|---|
className | string | - |
Search.Result
These are props specific to the Search.Result component:
Name | Type | Default |
---|---|---|
className | string | - |
Search.ResultItem
These are props specific to the Search.ResultItem component:
Name | Type | Default |
---|---|---|
className | string | - |
Search.ResultHeading
These are props specific to the Search.ResultHeading component:
Name | Type | Default |
---|---|---|
className | string | - |