@liberfi.io/ui-tokens
v0.1.103
Published
Token Components for Liberfi React SDK
Readme
@liberfi.io/ui-tokens
Token-related UI components for the Liberfi React SDK. Provides token lists, search, avatars, and pulse (real-time new/migrated token) widgets consumed by downstream applications.
Design Philosophy
- Script / UI / Widget layering —
.script.tsfiles encapsulate data-fetching and business logic as hooks;.ui.tsxfiles are pure presentational components driven by props;.widget.tsxfiles compose scripts and UI together. - No built-in global state — Data flows through props and lightweight React contexts scoped to individual features (e.g.
SearchProvider). Persistent state usesatomWithStorage(jotai) so the storage backend can be swapped. - Callbacks over side effects — Selection, navigation, and feedback (toast, analytics) are surfaced via
onSelectToken,onResult, etc. rather than hard-coded inside the library. - Mobile-first search — The search module targets constrained-width containers (modals, sidebars) and uses a compact mobile layout exclusively.
Installation
pnpm add @liberfi.io/ui-tokensPeer dependencies
The consumer must provide:
react>= 18react-dom>= 18jotai>= 2.15.1
API Reference
Components — Search
| Export | Kind | Description |
| ------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------- |
| SearchTokensButton | Widget | Button that opens the search modal (supports / keyboard shortcut). |
| SearchModal | Widget | AsyncModal wrapper; renders SearchWidget inside a StyledModal. |
| SearchWidget | Widget | Standalone search experience (input + history + result list). Accepts chains?: Chain[] and onSelectToken. |
| SearchInputUI | UI | Search input with 500ms debounce, paste, and clear buttons. |
| SearchContentUI | UI | Conditional renderer — shows history + hint when idle, search results when a keyword is set. |
| SearchHistoryUI | UI | Chips displaying persisted search history with a clear button. |
| SearchResultListWidget | Widget | Virtualized infinite-scroll result list (react-window + react-window-infinite-loader). |
| SearchResultListHeader | UI | Static column headers (Token/Age/MCap/Liq | Price/24h%). |
| SearchResultItemUI | UI | Compact token row — avatar, symbol, age, market cap, TVL, price, and price change. |
| SearchResultListSkeleton | UI | Skeleton placeholder for initial loading state. |
| SearchProvider / useSearchContext | Context | Manages the current search keyword. |
| useSearchHistory | Hook | Read/write persisted search history (backed by atomWithStorage). |
| useSearchResultListScript | Hook | Connects useSearchTokensInfiniteQuery to the search context. |
SearchModal
Wraps AsyncModal with id="search_tokens". Open it from anywhere via:
import { useAsyncModal } from "@liberfi.io/ui-scaffold";
const { onOpen } = useAsyncModal<SearchModalParams, SearchModalResult>(
"search_tokens",
);
await onOpen({ params: { chains: [Chain.SOLANA] } });
// resolves with Token on selection, undefined on dismissSearchWidget (standalone)
import { SearchWidget } from "@liberfi.io/ui-tokens";
<SearchWidget
chains={[Chain.SOLANA]}
onSelectToken={(token) => navigate(`/token/${token.chain}/${token.address}`)}
/>;Components — Token Avatar
| Export | Kind | Description |
| ------------- | ---- | ------------------------------------------------------------------------------------------- |
| TokenAvatar | UI | Token avatar with optional protocol family icon, bonding-curve progress, and image preview. |
Components — Token List
| Export | Kind | Description |
| ------------------------- | ------ | -------------------------------------------- |
| NewTokenListWidget | Widget | New tokens list with real-time subscription. |
| TrendingTokenListWidget | Widget | Trending tokens list. |
| StockTokenListWidget | Widget | Stock tokens list. |
| TokenListFilterModal | UI | Filter modal for token list columns. |
Components — Pulse
| Export | Kind | Description |
| ----------------------------- | ------ | -------------------------------- |
| PulseNewListWidget | Widget | Real-time new token pulse feed. |
| PulseMigratedListWidget | Widget | Migrated tokens pulse feed. |
| PulseFinalStretchListWidget | Widget | Final-stretch tokens pulse feed. |
Hooks
| Export | Description |
| ------------------- | ------------------------------------------------------------------------------------------------- |
| useTokens(params) | Fetches and subscribes to a set of tokens by chain + addresses, with polling and WebSocket merge. |
Usage Examples
Full search modal setup
import { SearchModal, SearchTokensButton } from "@liberfi.io/ui-tokens";
function App() {
return (
<>
{/* Trigger button */}
<SearchTokensButton />
{/* Modal definition — render once at app root */}
<SearchModal />
</>
);
}Standalone search widget inside a sidebar
import { Chain } from "@liberfi.io/types";
import { SearchWidget } from "@liberfi.io/ui-tokens";
function Sidebar() {
return (
<div className="w-80 h-screen">
<SearchWidget
chains={[Chain.SOLANA, Chain.ETHEREUM]}
onSelectToken={(token) => {
console.log("Selected:", token.chain, token.address);
}}
/>
</div>
);
}Future Improvements
- Add tab system (Discover / Favorite / View) for the empty-state content when no keyword is entered.
- Support sort and filter controls in search result headers.
- Add chain selector to scope search to a specific chain.
- Support custom
atomWithStoragestorage adapter for search history (e.g. server-side persistence).
