Shared UI components library for StellarExpert apps.
pnpm add @stellar-expert/ui-frameworkPeer dependencies must be installed separately — see peerDependencies in package.json.
import {
setStellarNetwork,
createToastNotificationsContainer,
initMeta
} from '@stellar-expert/ui-framework'
// Set the active Stellar network
setStellarNetwork('public')
// Initialize page meta tags
initMeta({
serviceTitle: '| StellarExpert',
origin: 'https://stellar.expert',
description: 'Stellar blockchain explorer',
image: 'https://stellar.expert/img/og-image.png'
})
// Initialize toast notifications (call once at app startup)
createToastNotificationsContainer()Global variables:
| Global | Default | Description |
|---|---|---|
window.explorerFrontendOrigin |
https://stellar.expert |
StellarExpert frontend URL |
window.explorerApiOrigin |
https://api.stellar.expert |
StellarExpert API URL |
window.horizonOrigin |
https://horizon.stellar.org |
Stellar Horizon API URL |
Override them before importing components if needed.
Dynamically loadable module with error boundary wrapping and caching.
| Prop | Type | Required | Description |
|---|---|---|---|
load |
() => Promise |
Yes | Dynamic import function |
module |
string |
No | Unique module name for caching |
import {DynamicModule} from '@stellar-expert/ui-framework'
<DynamicModule module="docs" load={() => import('./docs/docs-view')}/>React hook that auto-reinitializes state when dependencies change using deep comparison.
| Param | Type | Description |
|---|---|---|
stateInitializer |
function|any |
Initial state or initializer function receiving (dependencies, prevState) |
dependencies |
any[] |
Dependencies array (deep compared) |
finalizer |
function |
Optional cleanup function |
Returns [state, setState] — setState also uses deep comparison.
import {useDependantState} from '@stellar-expert/ui-framework'
const [transfer] = useDependantState(
() => new TransferSettings(network),
[network, accountLedgerData.address]
)
const [result, setResult] = useDependantState(() => {
loadIssuedAssets(address)
.then(data => setResult({loaded: true, data}))
return {loaded: false, data: []}
}, [address])Returns a function that forces a component re-render.
const forceUpdate = useForceUpdate()Like useEffect but uses deep comparison for dependencies.
import {useDeepEffect} from '@stellar-expert/ui-framework'
useDeepEffect(() => {
// runs when options deeply change
}, [options, modules, type])Hook for determining element visibility using IntersectionObserver.
| Param | Type | Description |
|---|---|---|
root |
RefObject<Element> |
Scroll parent ref |
rootMargin |
string |
Visibility margin (e.g., "100px") |
Returns boolean.
Returns the current Stellar network ('public' or 'testnet').
Sets the active Stellar network and notifies all subscribers.
import {setStellarNetwork} from '@stellar-expert/ui-framework'
setStellarNetwork('testnet')Subscribes to network change events.
import {subscribeToStellarNetworkChange} from '@stellar-expert/ui-framework'
subscribeToStellarNetworkChange(network => {
window.horizonOrigin = appSettings.horizonUrl
})React hook that returns the current network and re-renders on change.
const network = useStellarNetwork()Returns the current screen orientation type (e.g., "portrait-primary").
Boolean indicating Page Visibility API support.
Returns true if the document tab is currently visible.
Registers a visibility change listener. Returns an unsubscribe function.
Returns [theme, setTheme] for managing 'day'/'night' theme.
Initialize default page meta properties. Call once at app startup.
| Param | Type | Required | Description |
|---|---|---|---|
appMetaProps.serviceTitle |
string |
Yes | Service title suffix |
appMetaProps.description |
string |
Yes | Default description |
appMetaProps.origin |
string |
Yes | Site origin URL |
appMetaProps.image |
string |
No | Default OG image |
appMetaProps.imageEndpoint |
string |
No | Thumbnail generation endpoint |
initMeta({
serviceTitle: '| StellarExpert',
origin: metaOrigin,
description: 'StellarExpert - Stellar blockchain explorer',
image: metaOrigin + '/img/og-image.png',
imageEndpoint: metaOrigin + '/thumbnail'
})React hook for setting page title, description, and image.
import {usePageMetadata} from '@stellar-expert/ui-framework'
usePageMetadata({
title: `Account ${address}`,
description: `Explore properties of account ${address}`
})Add or remove the robots noindex meta tag.
Class representing an API response.
| Property | Type | Description |
|---|---|---|
data |
any |
Response data |
error |
string |
Error message if any |
status |
number |
HTTP status code |
loaded |
boolean |
Whether response has been received |
fetchedAt |
number |
Response timestamp |
React hook for fetching data from the StellarExpert API with caching and auto-refresh.
| Option | Type | Default | Description |
|---|---|---|---|
refreshInterval |
number |
— | Auto-refresh interval in seconds |
ttl |
number |
60 |
Cache TTL in seconds |
processResult |
function |
— | Transform the response data |
allowStaleDataTransition |
boolean |
false |
Show stale data during URL transitions |
import {useExplorerApi} from '@stellar-expert/ui-framework'
const {data, loaded, error} = useExplorerApi('account/' + address)
const {data: valueInfo} = useExplorerApi(`account/${address}/value`)
const accountInfo = useExplorerApi('account/' + address, {
processResult(data) { /* transform */ return data }
})Low-level function to fetch from the Explorer API with caching.
React hook for paginated API data with cursor-based navigation.
| Option | Type | Default | Description |
|---|---|---|---|
ttl |
number |
30 |
Cache TTL |
limit |
number |
20 |
Rows per page |
autoReverseRecordsOrder |
boolean |
false |
Reverse order for grid display |
defaultSortOrder |
'asc'|'desc' |
'desc' |
Default sort order |
autoLoadLastPage |
boolean |
true |
Load last page if empty |
includeNetwork |
boolean |
true |
Prefix endpoint with network |
dataProcessingCallback |
function |
— | Post-process records |
autoLoad |
boolean |
true |
Auto-load on mount |
updateLocation |
boolean|function |
true |
Update browser query string |
Returns ExplorerApiListResponse with data, loaded, loading, load(page), reset(), canLoadNextPage, canLoadPrevPage.
import {useExplorerPaginatedApi} from '@stellar-expert/ui-framework'
const assets = useExplorerPaginatedApi(
{path: 'asset/', query: {sort, search: navigation.query.search}},
{autoReverseRecordsOrder: true, defaultSortOrder: order, limit: 20}
)Load a single transaction by hash or ID. Returns a Promise.
Load all transactions for a given ledger sequence.
Batches multiple individual load requests into single API calls.
const loader = new ExplorerBatchInfoLoader(
batch => fetchExplorerApi('directory' + stringifyQuery({address: batch})),
entry => ({key: entry.address, info: entry})
)
const result = await loader.loadEntry(address)Singleton for subscribing to new ledger notifications via long-polling.
| Method | Description |
|---|---|
on(listener) |
Subscribe to new ledgers |
off(listener) |
Unsubscribe |
getLast() |
Fetch most recent ledger |
getLastSequence() |
Fetch most recent ledger sequence |
Create a new Horizon.Server instance using window.horizonOrigin.
Load all records from a Horizon query using cursor-based pagination.
Apply cursor, order, and limit to a Horizon query builder.
Ledger-related Horizon API helpers.
loadTransactions(queryParams?), streamTransactions(cursor, onNewTx, includeFailed?), submitTransaction(tx)
Transaction-related Horizon API helpers.
loadAccount(address), loadIssuedAssets(account, queryParams?), loadAccountOffers(account, queryParams?), loadAccountClaimableBalances(account)
Account-related Horizon API helpers.
Returns 'unlocked', 'locked', or 'partially locked'.
Returns {total, available, asset} for a given balance.
Load orderbook from Horizon.
loadMarketTrades(baseAsset, counterAsset, queryParams?), streamMarketTrades(cursor, baseAsset, counterAsset, onNewTrade), streamTrades(cursor, onNewTrade), loadTradesAggregation(params)
DEX trades Horizon API helpers.
Versatile button rendered as <button> or <a>.
| Prop | Type | Default | Description |
|---|---|---|---|
href |
string |
— | Renders as <a> tag |
onClick |
function |
— | Click handler |
block |
boolean |
false |
Block-level |
outline |
boolean |
false |
Outline style |
clear |
boolean |
false |
Text only |
small |
boolean |
false |
Small size |
disabled |
boolean |
false |
Disabled state |
loading |
boolean |
false |
Loading animation |
className |
string |
— | CSS classes |
children |
ReactNode |
— | Button content |
import {Button} from '@stellar-expert/ui-framework'
<Button block outline href="/signup">Create new account</Button>
<Button block disabled={disabled} loading={inProgress} onClick={proceed}>Submit</Button>Groups buttons with consistent spacing.
| Prop | Type | Description |
|---|---|---|
inline |
boolean |
Render as <span> |
children |
ReactNode |
Nested buttons |
Customizable dropdown select component.
| Prop | Type | Default | Description |
|---|---|---|---|
options |
Array<DropdownOption|string> |
— | Available options |
value |
string|number |
— | Selected value |
onChange |
function |
— | Change handler |
title |
any |
— | Display title |
disabled |
boolean |
false |
Disabled state |
showToggle |
boolean |
true |
Toggle arrow |
solo |
boolean |
false |
Centered dialog mode |
maxHeight |
string |
'35em' |
Max list height |
import {Dropdown} from '@stellar-expert/ui-framework'
<Dropdown options={orderOptions} onChange={setSort} value={sort}/>
<Dropdown options={networks} value={network} onChange={updateNetwork}/>Tabbed interface with optional URL query parameter sync.
| Prop | Type | Description |
|---|---|---|
tabs |
TabDescriptor[] |
Tab definitions ({name, title, render?, isDefault?}) |
selectedTab |
string |
Controlled selected tab |
onChange |
function |
Tab change handler |
queryParam |
string |
Query parameter for URL sync |
right |
boolean |
Right-align tabs |
import {Tabs} from '@stellar-expert/ui-framework'
<Tabs right queryParam="type"
tabs={[
{name: 'all', title: 'All', isDefault: true},
{name: 'trade', title: 'Trades'}
]}
selectedTab={type}
onChange={tabName => setType(tabName)}/>Tooltip with automatic positioning.
| Prop | Type | Default | Description |
|---|---|---|---|
trigger |
ReactElement |
— | Element that triggers the tooltip |
desiredPlace |
'top'|'bottom'|'left'|'right' |
'top' |
Preferred position |
activation |
'hover'|'click' |
'hover' |
Activation mode |
maxWidth |
string |
— | Max tooltip width |
children |
ReactNode |
— | Tooltip content |
Help icon with tooltip and optional "Read more" link.
| Prop | Type | Description |
|---|---|---|
children |
ReactNode |
Tooltip content |
link |
string |
"Read more" URL |
icon |
string |
Icon CSS class |
import {InfoTooltip} from '@stellar-expert/ui-framework'
<InfoTooltip link="https://example.com/docs">
Explanation text shown on hover.
</InfoTooltip>Syntax-highlighted code block.
| Prop | Type | Description |
|---|---|---|
children |
string |
Source code |
lang |
'js'|'json'|'html'|'xml'|'toml'|'rust'|'plain' |
Language |
import {CodeBlock} from '@stellar-expert/ui-framework'
<CodeBlock lang="rust">{contractSourceCode}</CodeBlock>Briefly highlights content with animation when children change.
<UpdateHighlighter>{formatPrice(1 / market.price, 4)}</UpdateHighlighter>Range input slider with optional category labels.
| Prop | Type | Default | Description |
|---|---|---|---|
value |
number |
min |
Current value |
onChange |
function |
— | Change handler (throttled) |
min |
number |
0 |
Minimum |
max |
number |
100 |
Maximum |
step |
number |
1 |
Step |
Link opening in a new tab with rel="noreferrer noopener".
<ExternalLink href="https://example.com">Read more</ExternalLink>Block that auto-selects all its text content on focus.
| Prop | Type | Default | Description |
|---|---|---|---|
as |
string |
'span' |
HTML tag |
wrap |
boolean |
— | Enable/disable text wrapping |
inline |
boolean |
— | Inline display |
import {BlockSelect} from '@stellar-expert/ui-framework'
<BlockSelect>{originalAddress}</BlockSelect>
<BlockSelect inline className="condensed">{transaction.sequence}</BlockSelect>Copy-to-clipboard wrapper with default copy icon.
| Prop | Type | Description |
|---|---|---|
text |
string |
Text to copy |
children |
ReactNode |
Custom trigger (defaults to copy icon) |
title |
string |
Tooltip text |
import {CopyToClipboard} from '@stellar-expert/ui-framework'
<CopyToClipboard text={publicKey}>
<a href="#" className="icon-copy active-icon" title="Copy account address"/>
</CopyToClipboard>Expandable/collapsible content toggle.
| Prop | Type | Default | Description |
|---|---|---|---|
expanded |
boolean |
false |
Initial state |
showMore |
string |
'Show more' |
Expand label |
showLess |
string |
'Show less' |
Collapse label |
onChange |
function |
— | Toggle callback |
micro |
boolean |
— | Icon-only mode |
children |
ReactNode |
— | Hidden content |
import {Spoiler} from '@stellar-expert/ui-framework'
<Spoiler expanded={extended}
onChange={e => setExtended(e.expanded)}
showMore="Show extended info"
showLess="Hide extended info"/>Collapsible panel group (one panel open at a time).
| Prop | Type | Default | Description |
|---|---|---|---|
options |
AccordionOption[] |
— | Panel definitions ({key, title, content}) |
collapsedSymbol |
string |
'+' |
Collapsed prefix |
expandedSymbol |
string |
'-' |
Expanded prefix |
import {Accordion} from '@stellar-expert/ui-framework'
<Accordion options={[
{key: 'overview', title: 'Overview', content: <OverviewPanel/>},
{key: 'details', title: 'Details', content: <DetailsPanel/>}
]}/>Theme toggle button switching between day (light) and night (dark) themes.
<ThemeSelector/>Animated dots progress indicator.
| Prop | Type | Default | Description |
|---|---|---|---|
dots |
number |
5 |
Max dots |
React hook that tracks window width (throttled).
const width = useWindowWidth()QR code renderer with optional embedded logo.
| Prop | Type | Default | Description |
|---|---|---|---|
value |
string |
— | Value to encode |
size |
number |
320 |
QR code size |
caption |
string |
— | Caption below QR |
embeddedImage |
string |
— | Logo URL |
embeddedSize |
number |
10% of size | Logo size |
import {QrCode} from '@stellar-expert/ui-framework'
<QrCode value={accountAddress} size={240}
embeddedImage="/img/logo-square.svg" embeddedSize={36}/>Modal dialog overlay.
| Prop | Type | Description |
|---|---|---|
dialogOpen |
boolean |
Whether dialog is visible |
children |
ReactNode |
Dialog content |
<Dialog dialogOpen={isOpen}><AuthRequestView/></Dialog>Replaces built-in alert() and confirm() with styled dialog versions.
<SystemDialog/>Ref callback that auto-focuses an element after a short delay.
const inputRef = useAutoFocusRef()
return <input ref={inputRef} />Displays a formatted UTC timestamp.
| Prop | Type | Description |
|---|---|---|
date |
string|number|Date |
Timestamp to format |
dateOnly |
boolean |
Show date without time |
import {UtcTimestamp} from '@stellar-expert/ui-framework'
<UtcTimestamp date={created} dateOnly/>
<UtcTimestamp date={offer.created}/>Displays relative time (e.g., "3m ago").
| Prop | Type | Description |
|---|---|---|
ts |
Date|string|number |
Timestamp |
suffix |
string |
Appended text |
import {ElapsedTime} from '@stellar-expert/ui-framework'
<ElapsedTime ts={new Date(tx.createdAt)} suffix=" ago"/>Date/time input selector.
| Prop | Type | Description |
|---|---|---|
value |
string|number|Date |
Current date value |
onChange |
function |
Returns Unix timestamp or null |
min |
string |
Min date |
max |
string |
Max date |
Trims seconds from an ISO date string. Returns a string like "2024-01-15T10:30".
Links to StellarExpert ledger entries.
| Component | ID Prop | Type |
|---|---|---|
TxLink |
tx |
string |
OpLink |
op |
string |
LedgerLink |
sequence |
number |
OfferLink |
offer |
string |
PoolLink |
pool |
string |
All accept optional network and children props.
import {TxLink, OfferLink} from '@stellar-expert/ui-framework'
<TxLink tx={tx.txHash}>
<ElapsedTime ts={new Date(tx.createdAt)} suffix=" ago"/>
</TxLink>
<OfferLink offer={offer.id}/>Generate an explorer URL for a given entry type and ID.
const url = formatExplorerLink('contract', contract.address + '/versions')Parse raw ledger data (including XDR header) into structured LedgerInfo.
Explorer link for Stellar addresses with identicon and directory info.
| Prop | Type | Default | Description |
|---|---|---|---|
account |
string |
— | StrKey-encoded address |
chars |
number|'all' |
8 |
Visible characters |
name |
string|false |
— | Display name override |
link |
string|false |
— | Link override |
icon |
boolean |
true |
Show identicon |
network |
string |
— | Network override |
import {AccountAddress} from '@stellar-expert/ui-framework'
<AccountAddress account={address} chars={12}/>
<AccountAddress account={address} name={false} network={network} chars={12}/>
<AccountAddress account={address} className="plain" link={false} chars="all"/>Renders an account-specific identicon.
| Prop | Type | Description |
|---|---|---|
address |
string |
StrKey-encoded address |
size |
number |
Display size |
Generate an SVG identicon string for a Stellar address.
Account signer key display with weight.
| Prop | Type | Description |
|---|---|---|
signer |
Object |
Signer object (raw XDR or parsed) |
showWeight |
boolean |
Show weight (default true) |
Calculate available balance for an account trustline, accounting for reserves and liabilities.
Explorer link for assets with icon and issuer display.
| Prop | Type | Default | Description |
|---|---|---|---|
asset |
string|AssetDescriptor |
— | Asset descriptor |
link |
string|false |
— | Link override |
issuer |
boolean |
true |
Show issuer |
icon |
boolean |
true |
Show icon |
import {AssetLink} from '@stellar-expert/ui-framework'
<AssetLink asset={descriptor}/>
<AssetLink asset={xrf} issuer={false} icon={false}/>Inline asset issuer display (domain or shortened address).
Asset icon from metadata or identicon fallback.
Asset search and selection dropdown.
| Prop | Type | Description |
|---|---|---|
onChange |
function |
Selection callback |
value |
string |
Selected asset |
predefinedAssets |
string[] |
Assets shown at top |
restricted |
boolean |
Limit to predefined list |
title |
string |
Dropdown title |
import {AssetSelector} from '@stellar-expert/ui-framework'
<AssetSelector value={asset}
onChange={select}
title="Choose an asset"/>Formatted token amount with optional asset link.
| Prop | Type | Description |
|---|---|---|
amount |
string|number |
Token amount |
asset |
string|AssetDescriptor |
Asset descriptor |
decimals |
number|'auto' |
Decimal precision |
adjust |
boolean |
Treat as raw Int64 stroops |
round |
boolean|'floor' |
Round the amount |
issuer |
boolean |
Show issuer |
icon |
boolean |
Show icon |
import {Amount} from '@stellar-expert/ui-framework'
<Amount amount={supply} adjust round/>
<Amount asset={offer.selling} amount={offer.amount} adjust/>
<Amount amount={total} asset={xrf} adjust issuer={false}/>React hook that fetches and caches asset metadata. Returns AssetMeta or null.
React hook for fetching a paginated, searchable asset list. Returns {assets, loadPage, loading}.
Price change percentage indicator with positive/negative styling.
| Prop | Type | Description |
|---|---|---|
change |
number |
Pre-calculated percentage |
current |
number |
Current price |
prev |
number |
Previous price |
standalone |
boolean |
Standalone styling |
allowZero |
boolean |
Show 0% |
Async function to fetch a directory entry.
| Option | Type | Default | Description |
|---|---|---|---|
forceRefresh |
boolean |
false |
Bypass cache |
extended |
boolean |
false |
Extended info |
React hook for directory info. Returns the directory entry or null.
const directoryInfo = useDirectory(address)React hook that fetches all available directory tags.
Renders a list of transaction operations with optional effects.
| Prop | Type | Default | Description |
|---|---|---|---|
parsedTx |
ParsedTxDetails |
— | Parsed transaction |
filter |
function |
— | Filter operations |
showFees |
boolean |
true |
Show fee effects |
compact |
boolean |
false |
Compact view |
showEffects |
boolean |
— | Show effects toggle |
import {TxOperationsList} from '@stellar-expert/ui-framework'
<TxOperationsList parsedTx={parsedTx}/>
<TxOperationsList parsedTx={tx} compact showFees={false}/>Parse transaction details from raw XDR.
| Param | Type | Required | Description |
|---|---|---|---|
network |
string |
Yes | Network passphrase |
txEnvelope |
string |
Yes | Base64 tx envelope XDR |
result |
string |
No | Base64 tx result |
meta |
string |
No | Base64 tx meta |
context |
TxFiltersContext |
No | Filter context |
createdAt |
string |
No | Timestamp |
protocol |
number |
No | Protocol version |
import {parseTxDetails} from '@stellar-expert/ui-framework'
const parsedTx = parseTxDetails({
network: appSettings.networkPassphrase,
txEnvelope: txResponse.body,
result: txResponse.result,
meta: txResponse.meta,
createdAt: txResponse.ts,
context: {},
protocol: txResponse.protocol
})React hook for paginated transaction history.
const historyModel = useTxHistory({
filters: {account: [address]},
order: 'desc',
rows: 50,
updateLocation: false
})React hook for transaction details by ID or hash.
Composable filter panel for managing search filters with URL query parameter sync. Supports multiple filter types including accounts, assets, operation types, timestamps, offers, and liquidity pools.
| Prop | Type | Default | Description |
|---|---|---|---|
presetFilter |
object |
— | Initial base filters always applied |
fields |
object |
{} |
Filter field definitions keyed by field name |
onChange |
function |
— | Callback receiving merged preset + user filters |
Each entry in fields is a FilterFieldDescriptor:
| Property | Type | Default | Description |
|---|---|---|---|
icon |
string |
— | Icon class suffix (prepended with icon-) |
title |
string |
— | Short title in filter condition |
description |
string |
— | Tooltip / "Add filter" dropdown text |
multi |
boolean |
true |
Allow multiple values for this field |
Supported field keys: type, account, source, destination, asset, src_asset, dest_asset, from, to, memo, offer, pool, topic.
import {FilterView, parseFiltersFromQuery} from '@stellar-expert/ui-framework'
<FilterView
presetFilter={{account: [address]}}
fields={{
type: {icon: 'hexagon', title: 'Type', description: 'Operation type'},
asset: {icon: 'asset', title: 'Asset', description: 'Asset involved'},
from: {icon: 'clock', title: 'From', description: 'Start date', multi: false},
to: {icon: 'clock', title: 'To', description: 'End date', multi: false}
}}
onChange={filters => setActiveFilters(filters)}/>Parses and validates filter parameters from the current URL query string against registered field definitions. Returns an object with matched filter key-value pairs.
Renders a human-readable description of a transaction effect.
| Prop | Type | Description |
|---|---|---|
effect |
Object |
Parsed effect with type field |
operation |
Object |
Parent operation context |
React hook for fetching contract information. Returns ExplorerApiResult.
Generate a URL to download contract WASM source.
React hook for fetching contract WASM binary. Returns ArrayBuffer, null, or undefined (loading).
Renders Stellar smart contract values in human-readable format.
| Prop | Type | Default | Description |
|---|---|---|---|
value |
string|xdr.ScVal|Array |
— | ScVal (base64 XDR, parsed, or array) |
indent |
boolean |
false |
Block-level indentation |
import {ScVal} from '@stellar-expert/ui-framework'
<ScVal value={entry.key} indent/>
<ScVal value={entry.value} indent/>Parse a base64-encoded XDR ScVal string into an xdr.ScVal object.
Structural wrapper for ScVal elements (handles indentation and separators).
Set<string> of primitive ScVal type identifiers.
Parse a Stellar generic ID into components. Returns {type, id, ledger, tx, operationOrder}.
const {tx: txid, operationOrder} = parseStellarGenericId(term)Decode a Stellar key into its type and components. Returns {address, type, muxedId?, publicKey?, payload?} or null.
Parse a multiplexed address. Returns {address, muxedId}.
Encode an address and BigInt ID into a multiplexed address.
Convert a signature hint Buffer to a StrKey mask string.
Format a signature hint for display.
Check if a hint matches a key.
Find a key matching a signature hint.
Find a transaction signature for a given signer key.
Find all keys matching a signature's hint.
const possibleSigners = findKeysBySignatureHint(signature, potentialSigners)MIT