Currency Picker
Headless currency picker component for multi-currency e-commerce applications.
Purpose
This library provides a headless component for managing currency selection. It provides functionality for displaying and changing the active currency while allowing complete UI customization. The component automatically persists currency selection in localStorage and syncs with the active channel's available currencies.
Features
- Currency selection and switching
- Automatic currency persistence in localStorage
- Available currency detection from active channel
- Render prop pattern for flexible UI composition
- Headless component architecture
Installation
- npm
- Yarn
npm install @haus-storefront-react/currency-picker
yarn add @haus-storefront-react/currency-picker
Note: This is not a public package. Contact the Haus Tech Team for access.
API Reference
CurrencyPicker.Root
Main container component that provides currency context and state. Must wrap all other CurrencyPicker components.
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | ChildrenProps<CurrencyPickerContextValue> | No | - | Render prop function that receives context value, or React children |
CurrencyPicker.Trigger
Trigger component for displaying the current currency and opening the selector. Must be used within CurrencyPicker.Root.
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
asChild | boolean | No | false | When true, merges props with child component instead of rendering a button |
className | string | No | - | CSS class name |
style | CSSProperties | No | - | Inline styles |
children | ChildrenProps<{ selectedCurrency: string }> | No | - | Render prop function that receives selectedCurrency, or React children |
disabled | boolean | No | - | Disabled state |
onClick | (event: MouseEvent<HTMLButtonElement>) => void | No | - | Click handler |
CurrencyPicker.Options
Options container for currency options. Must be used within CurrencyPicker.Root. Automatically renders currency options if children are not provided.
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
asChild | boolean | No | false | When true, merges props with child component instead of rendering a div |
className | string | No | - | CSS class name |
style | CSSProperties | No | - | Inline styles |
children | ReactNode | No | - | React children (if not provided, renders available currency options) |
CurrencyPicker.Option
Option component for an individual currency option. Must be used within CurrencyPicker.Options.
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
value | string | Yes | - | Currency code value |
asChild | boolean | No | false | When true, merges props with child component instead of rendering a button |
className | string | No | - | CSS class name |
style | CSSProperties | No | - | Inline styles |
children | ReactNode | No | - | React children (defaults to currency code if not provided) |
disabled | boolean | No | - | Disabled state |
onClick | (event: MouseEvent<HTMLButtonElement>) => void | No | - | Click handler |
CurrencyPicker.Value
Value component for displaying the currently selected currency. Must be used within CurrencyPicker.Root. Returns null if no currency is selected.
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
asChild | boolean | No | false | When true, merges props with child component instead of rendering a span |
className | string | No | - | CSS class name |
style | CSSProperties | No | - | Inline styles |
children | ReactNode | No | - | React children (defaults to selected currency code if not provided) |
useCurrencyPicker
Hook for managing currency selection. Provides currency state and update function.
Parameters
None.
Returns
| Return Value | Type | Description |
|---|---|---|
currencyCode | string | undefined | The currency code from the active channel |
availableCurrencyCodes | string[] | Array of available currency codes from the active channel |
isLoading | boolean | Loading state flag from active channel query |
error | Error | null | Error object if active channel query failed |
selectedCurrency | string | undefined | Currently selected currency code |
setSelectedCurrency | (value: string) => Promise<void> | Function to set the selected currency (persists to storage and invalidates queries) |
Basic Usage
Simple Currency Picker
Design 1: Pill Button Selector
Design 2: Dropdown List
- React
- React Native
import { CurrencyPicker } from '@haus-storefront-react/currency-picker'
function Header() {
return (
<CurrencyPicker.Root>
{({ availableCurrencyCodes, setSelectedCurrency }) => (
<>
<CurrencyPicker.Options>
{availableCurrencyCodes.map((code) => (
<CurrencyPicker.Option
key={code}
value={code}
onClick={() => setSelectedCurrency(code)}
/>
))}
</CurrencyPicker.Options>
</>
)}
</CurrencyPicker.Root>
)
}
import { CurrencyPicker } from '@haus-storefront-react/currency-picker'
function Header() {
return (
<CurrencyPicker.Root>
{({ availableCurrencyCodes, setSelectedCurrency }) => (
<>
<CurrencyPicker.Options>
{availableCurrencyCodes.map((code) => (
<CurrencyPicker.Option
key={code}
value={code}
onClick={() => setSelectedCurrency(code)}
/>
))}
</CurrencyPicker.Options>
</>
)}
</CurrencyPicker.Root>
)
}
Basic Hook Usage
- React
- React Native
import { useCurrencyPicker } from '@haus-storefront-react/currency-picker'
function MyComponent() {
const { selectedCurrency, availableCurrencyCodes, setSelectedCurrency } =
useCurrencyPicker()
return (
<select
value={selectedCurrency || ''}
onChange={(e) => setSelectedCurrency(e.target.value)}
>
{availableCurrencyCodes.map((code) => (
<option key={code} value={code}>
{code}
</option>
))}
</select>
)
}
import { Pressable, Text } from 'react-native'
import { useCurrencyPicker } from '@haus-storefront-react/currency-picker'
function MyComponent() {
const { selectedCurrency, availableCurrencyCodes, setSelectedCurrency } =
useCurrencyPicker()
return (
<>
{availableCurrencyCodes.map((code) => (
<Pressable key={code} onPress={() => setSelectedCurrency(code)}>
<Text>{code}</Text>
</Pressable>
))}
{selectedCurrency && <Text>Selected: {selectedCurrency}</Text>}
</>
)
}
Advanced Usage
Using with Custom UI Components
- React
- React Native
import { CurrencyPicker } from '@haus-storefront-react/currency-picker'
import { Button } from './your-ui-library'
function CustomCurrencyPicker() {
return (
<CurrencyPicker.Root>
{({ setSelectedCurrency }) => (
<>
<CurrencyPicker.Trigger asChild>
<Button variant='outline'>
<CurrencyPicker.Value /> ▼
</Button>
</CurrencyPicker.Trigger>
<CurrencyPicker.Options>
<CurrencyPicker.Option
value='USD'
onClick={() => setSelectedCurrency('USD')}
>
USD
</CurrencyPicker.Option>
<CurrencyPicker.Option
value='EUR'
onClick={() => setSelectedCurrency('EUR')}
>
EUR
</CurrencyPicker.Option>
</CurrencyPicker.Options>
</>
)}
</CurrencyPicker.Root>
)
}
import { View, Text, Pressable } from 'react-native'
import { CurrencyPicker } from '@haus-storefront-react/currency-picker'
function CustomCurrencyPicker() {
return (
<CurrencyPicker.Root>
{({ setSelectedCurrency }) => (
<>
<CurrencyPicker.Trigger asChild>
<Pressable>
<CurrencyPicker.Value /> ▼
</Pressable>
</CurrencyPicker.Trigger>
<CurrencyPicker.Options>
<CurrencyPicker.Option
value='USD'
onClick={() => setSelectedCurrency('USD')}
>
USD
</CurrencyPicker.Option>
<CurrencyPicker.Option
value='EUR'
onClick={() => setSelectedCurrency('EUR')}
>
EUR
</CurrencyPicker.Option>
</CurrencyPicker.Options>
</>
)}
</CurrencyPicker.Root>
)
}
Custom Currency Picker with State Management
- React
- React Native
import { CurrencyPicker } from '@haus-storefront-react/currency-picker'
import { useState } from 'react'
function CurrencyPicker() {
const [isOpen, setIsOpen] = useState(false)
const currencyFlags = {
USD: '🇺🇸',
EUR: '🇪🇺',
GBP: '🇬🇧',
CAD: '🇨🇦',
AUD: '🇦🇺',
JPY: '🇯🇵',
CHF: '🇨🇭',
SEK: '🇸🇪',
}
return (
<CurrencyPicker.Root>
{({
selectedCurrency,
availableCurrencyCodes,
setSelectedCurrency,
isLoading,
}) => (
<div className='currency-picker'>
<button
className='currency-button'
onClick={() => setIsOpen(!isOpen)}
disabled={isLoading}
>
<span className='currency-flag'>
{(selectedCurrency &&
currencyFlags[
selectedCurrency as keyof typeof currencyFlags
]) ||
'💱'}
</span>
<span className='currency-code'>{selectedCurrency}</span>
<span className='dropdown-arrow'>▼</span>
</button>
{isOpen && (
<div className='currency-dropdown'>
{availableCurrencyCodes.map((currency) => (
<button
key={currency}
className={`currency-option ${
currency === selectedCurrency ? 'selected' : ''
}`}
onClick={() => {
setSelectedCurrency(currency)
setIsOpen(false)
}}
>
<span className='currency-flag'>
{currencyFlags[currency as keyof typeof currencyFlags] ||
'💱'}
</span>
<span className='currency-code'>{currency}</span>
</button>
))}
</div>
)}
</div>
)}
</CurrencyPicker.Root>
)
}
import { useState } from 'react'
import { View, Text, Pressable } from 'react-native'
import { CurrencyPicker } from '@haus-storefront-react/currency-picker'
function CurrencyPicker() {
const [isOpen, setIsOpen] = useState(false)
const currencyFlags = {
USD: '🇺🇸',
EUR: '🇪🇺',
GBP: '🇬🇧',
CAD: '🇨🇦',
AUD: '🇦🇺',
JPY: '🇯🇵',
CHF: '🇨🇭',
SEK: '🇸🇪',
}
return (
<CurrencyPicker.Root>
{({
selectedCurrency,
availableCurrencyCodes,
setSelectedCurrency,
isLoading,
}) => (
<View>
<Pressable
onPress={() => setIsOpen(!isOpen)}
disabled={isLoading}
>
<Text>
{(selectedCurrency &&
currencyFlags[
selectedCurrency as keyof typeof currencyFlags
]) ||
'💱'}{' '}
{selectedCurrency} ▼
</Text>
</Pressable>
{isOpen && (
<View>
{availableCurrencyCodes.map((currency) => (
<Pressable
key={currency}
onPress={() => {
setSelectedCurrency(currency)
setIsOpen(false)
}}
>
<Text>
{currencyFlags[currency as keyof typeof currencyFlags] ||
'💱'}{' '}
{currency}
</Text>
</Pressable>
))}
</View>
)}
</View>
)}
</CurrencyPicker.Root>
)
}
Made with ❤️ by Haus Tech Team