@telixon/web-sdk
@telixon/web-sdk binds @telixon/core to the web platform: a phone input adapter, a region list
controller, and a flag emoji helper. It ships no CSS and no image assets; rendering stays yours.
createPhoneInput and createRegionList require a ready engine and throw
EngineNotReadyError otherwise; initialize with
ensureEngineReady() from @telixon/core first.
createPhoneInput()
Section titled “createPhoneInput()”function createPhoneInput(options: PhoneInputOptions): PhoneInput;Attaches a headless phone input controller to a DOM <input> element. It wires the element’s
native editing events (beforeinput, compositionend, undo/redo keyboard shortcuts) to a core
input controller and keeps the value, caret, and resolved
phone metadata in sync through every reformat.
Throws when the element is not type="text" or type="tel", when another PhoneInput is already
attached to the same element, or when the engine is not ready.
import { ensureEngineReady } from '@telixon/core';import { createPhoneInput } from '@telixon/web-sdk';
await ensureEngineReady();
const inputElement = document.querySelector('input');if (!(inputElement instanceof HTMLInputElement)) throw new Error('input element not found');
const phoneInput = createPhoneInput({ mode: 'national', input: inputElement, defaultRegion: 'US',});
phoneInput.subscribe((state) => { // state: PhoneInputState});PhoneInputOptions
Section titled “PhoneInputOptions”A discriminated union on mode: NationalPhoneInputOptions (mode: 'national') or
InternationalPhoneInputOptions (mode: 'international'). Both share the base options:
| Option | Type | Default | Description |
|---|---|---|---|
input |
PhoneInputElement |
required | The <input> to attach; must be type="text" or type="tel". |
initialValue |
string |
'' |
Seeds the first state, applied to the DOM at construction. |
regionFilter |
readonly RegionCode[] | null |
null |
Restricts resolution to the given regions. |
numberTypeFilter |
readonly NumberType[] | null |
null |
Restricts resolution to the given number types. |
placeholderNumberType |
NumberType |
'MOBILE' |
The number type whose example becomes state.placeholder. |
Each mode adds its core controller configuration:
| Mode | Additional options |
|---|---|
'national' |
defaultRegion (required), strict, maxHistorySize; see NationalInputControllerConfig. |
'international' |
defaultRegion, strict, maxHistorySize, display; display.callingCodeInInput: false requires defaultRegion. See InternationalInputControllerConfig. |
PhoneInputElement is HTMLInputElement.
PhoneInput
Section titled “PhoneInput”The initial state is applied to the DOM at construction but not emitted to subscribers; call
getState() after subscribe to read the bootstrap value.
| Method | Returns | Description |
|---|---|---|
subscribe(listener) |
() => void |
Subscribes to state changes; returns an unsubscribe function. |
getState() |
PhoneInputState |
Reads the current state without subscribing. |
setValue(value) |
void |
Replaces the current value as one parse-and-format operation. Pushes a history entry. |
setRegion(region) |
void |
Switches the active region and re-resolves the digits. Pushes a history entry. |
undo(), redo() |
void |
History navigation; no-op when the matching availability check returns false. |
canUndo(), canRedo() |
boolean |
History availability. |
clearHistory() |
void |
Drops undo/redo history, keeping the current entry. |
getPhoneNumber() |
PhoneNumber |
Builds a PhoneNumber from the current digits. |
setRegionFilter(regions) |
void |
Restricts resolution to regions; null removes the restriction. |
setNumberTypeFilter(numberTypes) |
void |
Restricts resolution to numberTypes; null removes the restriction. |
destroy() |
void |
Detaches all DOM listeners and clears subscribers. Idempotent. |
PhoneInputListener is (state: PhoneInputState) => void.
PhoneInputState
Section titled “PhoneInputState”The snapshot emitted after every state change.
| Field | Type | Description |
|---|---|---|
value |
string |
The formatted value currently in the input. |
region |
RegionCode | null |
The region resolved from the digits, or null when unresolved. |
selectionStart, selectionEnd |
number |
The caret range within value after the last operation. |
regionFilter |
readonly RegionCode[] | null |
The active region restriction; null means none. |
numberTypeFilter |
readonly NumberType[] | null |
The active number type restriction; null means none. |
placeholder |
string | null |
The example number for the resolved region and display config, or null when unresolved. Exposed in state only, never written to the element. |
validationError |
ValidationError | null |
The structured outcome of getPhoneNumber().getValidationError(), or null when none apply. |
createRegionList()
Section titled “createRegionList()”function createRegionList<T = undefined>(options?: RegionListOptions<T>): RegionList<T>;Creates a headless region list controller for pickers, dropdowns, and selector UIs: a reactive list of region options that is filtered, searched, sorted, prioritized, and localized as pure state. No DOM is involved.
On every change the pipeline runs in a fixed order: base set (cached per locale), then
regionFilter, numberTypeFilter, search, sort, and prioritize. The generic T flows from the
dataFactory return type; without a factory, data is present and undefined.
import { createRegionList } from '@telixon/web-sdk';
const regionList = createRegionList();
regionList.search('ukr');regionList.getState().options;// [{ region: 'UA', callingCode: '380', displayName: 'Ukraine', data: undefined }]RegionListOptions
Section titled “RegionListOptions”All fields are optional.
| Option | Type | Default | Description |
|---|---|---|---|
dataFactory |
RegionDataFactory<T> |
none | Produces the data slot for each option. Invoked once per region at construction and on localize/refresh; expected to be pure. |
regionFilter |
readonly RegionCode[] | null |
null |
Restricts the list to the given regions. [] matches nothing. |
numberTypeFilter |
readonly NumberType[] | null |
null |
Restricts the list to regions supporting at least one of the given number types. [] matches nothing. |
searchQuery |
string |
'' |
Initial search query. |
searchFn |
RegionSearchFn<T> |
built-in search | Custom search predicate; see Search. |
locale |
string |
'en' |
Locale for display names and collation. |
sort |
RegionListSort<T> |
'alphabetical' |
Sort order; see Sort. |
prioritize |
readonly RegionCode[] |
[] |
Regions pinned to the top of the sorted list, in the given order. |
RegionDataFactory<T> is (input: RegionDataFactoryInput) => T; RegionDataFactoryInput carries
the precomputed region, callingCode, displayName, and the active locale.
RegionList
Section titled “RegionList”No emit fires on construction; call getState() after subscribe to read the bootstrap value.
Action verbs (search, localize) name user-driven interactions; set* names declarative
configuration changes.
| Method | Returns | Description |
|---|---|---|
subscribe(listener) |
() => void |
Subscribes to state changes; returns an unsubscribe function. |
getState() |
RegionListState<T> |
Reads the current state without subscribing. |
search(query) |
void |
Updates the query and re-runs the pipeline. No-op when unchanged. |
localize(locale) |
void |
Switches the locale, recomputes display names and data, and re-runs the pipeline. No-op when unchanged. |
refresh() |
void |
Recomputes the base set (display names and dataFactory) and re-emits. For when external state read by dataFactory changes. Always emits. |
setRegionFilter(value) |
void |
Replaces the region restriction; null removes it, [] matches nothing. No-op when unchanged. |
setNumberTypeFilter(value) |
void |
Replaces the number type restriction; null removes it, [] matches nothing. No-op when unchanged. |
destroy() |
void |
Clears all subscribers. Idempotent. |
RegionListListener<T> is (state: RegionListState<T>) => void.
RegionOption
Section titled “RegionOption”One entry in the rendered list.
| Field | Type | Description |
|---|---|---|
region |
RegionCode |
Two-letter region code, for example 'US'. |
callingCode |
string |
Calling code digits, for example '1'. |
displayName |
string |
Region name from Intl.DisplayNames for the active locale; falls back to the region code when the runtime cannot produce a localized name. The exact string depends on the runtime’s ICU data. |
data |
T |
The dataFactory result; undefined without a factory. |
import { createRegionList, regionToFlagEmoji } from '@telixon/web-sdk';
const regionList = createRegionList({ dataFactory: ({ region }) => ({ flag: regionToFlagEmoji(region) }),});
regionList.getState().options.find((option) => option.region === 'UA');// { region: 'UA', callingCode: '380', displayName: 'Ukraine', data: { flag: '🇺🇦' } }Search
Section titled “Search”The built-in search matches case-insensitively and diacritic-insensitively against the display
name, the region code, and the calling code. The calling code match is a substring match, and a
leading + in the query is accepted. Empty and whitespace-only queries short-circuit to the full
list without invoking the search function.
const regionList = createRegionList();
regionList.search('+38');regionList.getState().options.map((option) => option.region);// ['BA', 'CV', 'HR', 'XK', 'ME', 'MK', 'RS', 'SI', 'UA']RegionSearchFn<T> is (query: string, option: RegionOption<T>) => boolean: return true to
include option. It receives the raw query and performs its own normalization.
RegionListSort<T> selects the comparator:
| Value | Order |
|---|---|
'alphabetical' |
By displayName collated in the list’s locale, then region code. Default. |
'callingCode' |
By numeric calling code, then displayName, then region code. |
| comparator | (a: RegionOption<T>, b: RegionOption<T>) => number; you own its ordering. |
The built-in comparators break ties by region code, so they are total orders: a given runtime always produces the same order. Display names and collation come from the runtime’s ICU, so the order can differ between environments.
const regionList = createRegionList({ sort: 'callingCode', prioritize: ['US', 'GB'],});
regionList .getState() .options.slice(0, 5) .map((option) => `${option.region} +${option.callingCode}`);// ['US +1', 'GB +44', 'AS +1', 'AI +1', 'AG +1']RegionListState
Section titled “RegionListState”The snapshot emitted on every state change.
| Field | Type | Description |
|---|---|---|
options |
readonly RegionOption<T>[] |
The post-filter, post-sort, post-prioritize list as currently rendered. |
regionFilter |
readonly RegionCode[] | null |
The active region restriction; null means none. |
numberTypeFilter |
readonly NumberType[] | null |
The active number type restriction; null means none. |
searchQuery |
string |
The active query. |
locale |
string |
The active locale. |
regionToFlagEmoji()
Section titled “regionToFlagEmoji()”function regionToFlagEmoji(region: RegionCode): string;Converts a region code to its flag emoji: the two Unicode regional indicator symbols for its letters, derived arithmetically. No image assets are involved. Rendering is the platform’s choice: systems with flag emoji support show a flag; systems without it (notably Windows) show the two letters. For a flag on every platform, render an SVG set keyed by the region code instead.
import { regionToFlagEmoji } from '@telixon/web-sdk';
regionToFlagEmoji('UA'); // '🇺🇦'regionToFlagEmoji('CH'); // '🇨🇭'Exported types
Section titled “Exported types”Every type-only export and where this page documents it:
| Type | Documented in |
|---|---|
PhoneInputOptions, NationalPhoneInputOptions, InternationalPhoneInputOptions, PhoneInputElement |
PhoneInputOptions |
PhoneInput, PhoneInputListener |
PhoneInput |
PhoneInputState |
PhoneInputState |
RegionListOptions, RegionDataFactory, RegionDataFactoryInput |
RegionListOptions |
RegionList, RegionListListener |
RegionList |
RegionOption |
RegionOption |
RegionSearchFn |
Search |
RegionListSort |
Sort |
RegionListState |
RegionListState |