Hooks and utilities for formatting, localization, and international text processing with support for multiple languages and regions.
Hook for accessing current locale information and text direction.
/**
* Hook for accessing current locale information
* @returns Current locale and text direction information
*/
function useLocale(): LocaleInfo;
interface LocaleInfo {
/** Current locale string (BCP 47 language tag) */
locale: string;
/** Text direction for current locale */
direction: "ltr" | "rtl";
}Hook for locale-aware date and time formatting with full Intl.DateTimeFormat support.
/**
* Hook for locale-aware date and time formatting
* @param options - Date formatting configuration options
* @returns DateFormatter instance with formatting methods
*/
function useDateFormatter(options?: DateFormatterOptions): DateFormatter;
interface DateFormatterOptions extends Intl.DateTimeFormatOptions {
/** Calendar system to use */
calendar?: string;
/** Override locale */
locale?: string;
}
interface DateFormatter {
/** Format single date */
format: (date: Date) => string;
/** Format date to parts for custom styling */
formatToParts: (date: Date) => Intl.DateTimeFormatPart[];
/** Format date range */
formatRange: (start: Date, end: Date) => string;
/** Format date range to parts */
formatRangeToParts: (start: Date, end: Date) => Intl.DateTimeFormatPart[];
/** Get resolved formatting options */
resolvedOptions: () => Intl.DateTimeFormatOptions;
}Hook for locale-aware number formatting including currency, percentages, and units.
/**
* Hook for locale-aware number formatting
* @param options - Number formatting configuration options
* @returns Intl.NumberFormat instance for formatting
*/
function useNumberFormatter(options?: Intl.NumberFormatOptions): Intl.NumberFormat;Hook for locale-aware string comparison and sorting.
/**
* Hook for locale-aware string comparison and sorting
* @param options - Collation configuration options
* @returns Intl.Collator instance for string comparison
*/
function useCollator(options?: Intl.CollatorOptions): Intl.Collator;Hook for locale-aware text filtering and searching.
/**
* Hook for locale-aware text filtering and searching
* @param options - Filter configuration options
* @returns Filter function for text matching
*/
function useFilter(options?: FilterOptions): Filter;
interface FilterOptions {
/** Text matching sensitivity */
sensitivity?: "base" | "accent" | "case" | "variant";
/** Whether to ignore case */
ignorePunctuation?: boolean;
/** Custom collator options */
collatorOptions?: Intl.CollatorOptions;
}
interface Filter {
/** Check if text starts with query */
startsWith: (text: string, query: string) => boolean;
/** Check if text ends with query */
endsWith: (text: string, query: string) => boolean;
/** Check if text contains query */
contains: (text: string, query: string) => boolean;
}Hook for accessing localized string resources with interpolation support.
/**
* Hook for accessing localized string resources
* @param strings - Localized string dictionary
* @param deps - Dependencies for re-evaluation
* @returns String formatter function
*/
function useLocalizedStringFormatter(
strings: LocalizedStrings,
deps?: any[]
): LocalizedStringFormatter;
interface LocalizedStrings {
[key: string]: string | ((values: any) => string);
}
interface LocalizedStringFormatter {
/** Format localized string with interpolation */
format: (key: string, values?: any) => string;
}Hook for advanced message formatting with ICU MessageFormat support.
/**
* Hook for advanced message formatting with ICU MessageFormat
* @param locale - Target locale for formatting
* @returns Message formatter function
*/
function useMessageFormatter(locale?: string): FormatMessage;
interface FormatMessage {
/** Format message with ICU MessageFormat syntax */
(message: string, values?: Record<string, any>): string;
}function MultiLanguageApp() {
const { locale, direction } = useLocale();
const formatDate = useDateFormatter({
dateStyle: 'medium',
timeStyle: 'short'
});
const formatNumber = useNumberFormatter({
style: 'currency',
currency: locale.startsWith('en-US') ? 'USD' : 'EUR'
});
return (
<div dir={direction}>
<Text>Current locale: {locale}</Text>
<Text>Today: {formatDate.format(new Date())}</Text>
<Text>Price: {formatNumber.format(29.99)}</Text>
</div>
);
}function LocalizedDataTable({ data }) {
const { locale } = useLocale();
const formatDate = useDateFormatter({
dateStyle: 'short'
});
const formatCurrency = useNumberFormatter({
style: 'currency',
currency: 'USD'
});
const collator = useCollator({
numeric: true,
sensitivity: 'base'
});
const sortedData = [...data].sort((a, b) =>
collator.compare(a.name, b.name)
);
return (
<TableView items={sortedData}>
<TableHeader>
<Column key="name">Name</Column>
<Column key="date">Date</Column>
<Column key="amount">Amount</Column>
</TableHeader>
<TableBody>
{(item) => (
<Row key={item.id}>
<Cell>{item.name}</Cell>
<Cell>{formatDate.format(new Date(item.date))}</Cell>
<Cell>{formatCurrency.format(item.amount)}</Cell>
</Row>
)}
</TableBody>
</TableView>
);
}function LocalizedSearch({ items, onResults }) {
const [query, setQuery] = useState('');
const filter = useFilter({
sensitivity: 'base',
ignorePunctuation: true
});
const filteredItems = useMemo(() => {
if (!query.trim()) return items;
return items.filter(item =>
filter.contains(item.name, query) ||
filter.contains(item.description, query)
);
}, [items, query, filter]);
useEffect(() => {
onResults(filteredItems);
}, [filteredItems, onResults]);
return (
<SearchField
label="Search"
value={query}
onChange={setQuery}
placeholder="Type to search..."
/>
);
}const messages = {
'en-US': {
welcome: 'Welcome, {name}!',
itemCount: '{count, plural, =0 {no items} =1 {one item} other {# items}}',
lastUpdate: 'Last updated {date, date, medium} at {date, time, short}'
},
'es-ES': {
welcome: '¡Bienvenido, {name}!',
itemCount: '{count, plural, =0 {sin elementos} =1 {un elemento} other {# elementos}}',
lastUpdate: 'Última actualización {date, date, medium} a las {date, time, short}'
}
};
function LocalizedMessages({ userName, itemCount, lastUpdate }) {
const { locale } = useLocale();
const strings = useLocalizedStringFormatter(messages[locale] || messages['en-US']);
const formatMessage = useMessageFormatter(locale);
return (
<View>
<Heading>
{strings.format('welcome', { name: userName })}
</Heading>
<Text>
{formatMessage(strings.format('itemCount'), { count: itemCount })}
</Text>
<Text>
{formatMessage(strings.format('lastUpdate'), { date: lastUpdate })}
</Text>
</View>
);
}function LocalizedDateRangePicker() {
const [dateRange, setDateRange] = useState({
start: today(getLocalTimeZone()),
end: today(getLocalTimeZone()).add({ days: 7 })
});
const { locale } = useLocale();
const formatDate = useDateFormatter({
dateStyle: 'full'
});
return (
<View>
<DateRangePicker
label="Select Date Range"
value={dateRange}
onChange={setDateRange}
/>
<Text>
Selected: {formatDate.format(dateRange.start.toDate(getLocalTimeZone()))}
{' - '}
{formatDate.format(dateRange.end.toDate(getLocalTimeZone()))}
</Text>
<Text>
Locale: {locale}
</Text>
</View>
);
}function CurrencyConverter() {
const [amount, setAmount] = useState(100);
const [fromCurrency, setFromCurrency] = useState('USD');
const [toCurrency, setToCurrency] = useState('EUR');
const formatFrom = useNumberFormatter({
style: 'currency',
currency: fromCurrency
});
const formatTo = useNumberFormatter({
style: 'currency',
currency: toCurrency
});
// Mock conversion rate - in real app, fetch from API
const convertedAmount = amount * 0.85;
return (
<Form>
<NumberField
label="Amount"
value={amount}
onChange={setAmount}
formatOptions={{
style: 'currency',
currency: fromCurrency
}}
/>
<Picker
label="From Currency"
selectedKey={fromCurrency}
onSelectionChange={setFromCurrency}
>
<Item key="USD">US Dollar</Item>
<Item key="EUR">Euro</Item>
<Item key="GBP">British Pound</Item>
<Item key="JPY">Japanese Yen</Item>
</Picker>
<Picker
label="To Currency"
selectedKey={toCurrency}
onSelectionChange={setToCurrency}
>
<Item key="USD">US Dollar</Item>
<Item key="EUR">Euro</Item>
<Item key="GBP">British Pound</Item>
<Item key="JPY">Japanese Yen</Item>
</Picker>
<View backgroundColor="gray-100" padding="size-200">
<Text>
{formatFrom.format(amount)} = {formatTo.format(convertedAmount)}
</Text>
</View>
</Form>
);
}/** BCP 47 language tag */
type Locale = string;
/** Text direction */
type Direction = "ltr" | "rtl";
/** Locale information */
interface LocaleInfo {
/** Current locale */
locale: Locale;
/** Text direction */
direction: Direction;
}/** Date formatter options extending Intl options */
interface DateFormatterOptions extends Intl.DateTimeFormatOptions {
/** Calendar system */
calendar?: string;
/** Override locale */
locale?: string;
}
/** Date formatter with additional methods */
interface DateFormatter extends Intl.DateTimeFormat {
/** Format date range */
formatRange: (start: Date, end: Date) => string;
/** Format date range to parts */
formatRangeToParts: (start: Date, end: Date) => Intl.DateTimeFormatPart[];
}/** Text filter configuration */
interface FilterOptions {
/** Case and accent sensitivity */
sensitivity?: "base" | "accent" | "case" | "variant";
/** Whether to ignore punctuation */
ignorePunctuation?: boolean;
/** Collator options */
collatorOptions?: Intl.CollatorOptions;
}
/** Text filter function interface */
interface Filter {
/** Check if text starts with query */
startsWith: (text: string, query: string) => boolean;
/** Check if text ends with query */
endsWith: (text: string, query: string) => boolean;
/** Check if text contains query */
contains: (text: string, query: string) => boolean;
}/** Localized string dictionary */
interface LocalizedStrings {
[key: string]: string | ((values: any) => string);
}
/** String formatter function */
interface LocalizedStringFormatter {
/** Format string with interpolation */
format: (key: string, values?: any) => string;
}
/** Message formatter for ICU MessageFormat */
interface FormatMessage {
/** Format message with values */
(message: string, values?: Record<string, any>): string;
}