diff --git a/packages/interwovenkit-react/src/components/form/AssetOptions.tsx b/packages/interwovenkit-react/src/components/form/AssetOptions.tsx index c019f2f1..56939169 100644 --- a/packages/interwovenkit-react/src/components/form/AssetOptions.tsx +++ b/packages/interwovenkit-react/src/components/form/AssetOptions.tsx @@ -1,5 +1,5 @@ import clsx from "clsx" -import { useState } from "react" +import { memo, useDeferredValue, useMemo, useState } from "react" import { formatAmount } from "@initia/utils" import { formatValue } from "@/lib/format" import Image from "../Image" @@ -12,6 +12,58 @@ import styles from "./AssetOptions.module.css" import type { ReactNode } from "react" +const DEFAULT_SEARCH_KEYS: Array = ["symbol"] +const DEFAULT_RENDER_ASSET = (asset: BaseAsset, children: (asset: BaseAsset) => ReactNode) => + children(asset) + +interface AssetListProps { + assets: BaseAsset[] + onSelect: (denom: string) => void + renderAsset: (asset: BaseAsset, children: (asset: BaseAsset) => ReactNode) => ReactNode + listClassName?: string +} + +const AssetList = memo(function AssetList(props: AssetListProps) { + const { assets, onSelect, renderAsset, listClassName } = props + + return ( +
+ {assets.map((asset) => ( + + ))} +
+ ) +}) + interface Props { assets: BaseAsset[] onSelect: (denom: string) => void @@ -30,14 +82,18 @@ const AssetOptions = (props: Props) => { const { assets, onSelect, - renderAsset = (asset, children) => children(asset), - searchKeys = ["symbol"], + renderAsset = DEFAULT_RENDER_ASSET, + searchKeys = DEFAULT_SEARCH_KEYS, placeholder = "Search by symbol", emptyMessage = "No assets", listClassName, } = props const [search, setSearch] = useState("") - const filteredAssets = filterBySearch(searchKeys, search, assets) + const deferredSearch = useDeferredValue(search) + const filteredAssets = useMemo( + () => filterBySearch(searchKeys, deferredSearch, assets), + [searchKeys, deferredSearch, assets], + ) return (
@@ -54,40 +110,12 @@ const AssetOptions = (props: Props) => { {filteredAssets.length === 0 ? ( {emptyMessage} ) : ( -
- {filteredAssets.map((asset) => ( - - ))} -
+ )}
) diff --git a/packages/interwovenkit-react/src/components/form/search.ts b/packages/interwovenkit-react/src/components/form/search.ts index 6adee164..ab327067 100644 --- a/packages/interwovenkit-react/src/components/form/search.ts +++ b/packages/interwovenkit-react/src/components/form/search.ts @@ -1,8 +1,10 @@ -import { any, includes } from "ramda" - export function filterBySearch(fields: Array, search: string, data: T[]): T[] { - return data.filter((item) => { - const values = fields.map((field) => item[field]).map((val) => String(val ?? "").toLowerCase()) - return any(includes(search.toLowerCase()), values) - }) + const query = search.toLowerCase() + return data.filter((item) => + fields.some((field) => + String(item[field] ?? "") + .toLowerCase() + .includes(query), + ), + ) }