Programmatic control
Every PhoneInput mutator runs the same pipeline as a keystroke: the controller resolves the
next state, the adapter writes the value and caret to the element, and subscribers receive the
new PhoneInputState. This page covers the methods that drive the input from code and the
lifecycle rules around them.
The examples assume an international input with a fixed plus:
import { ensureEngineReady } from '@telixon/core';import { createPhoneInput } from '@telixon/web-sdk';
await ensureEngineReady();
const phoneInput = createPhoneInput({ mode: 'international', input: inputElement, display: { callingCodeInInput: true, plusPrefix: 'fixed' },});setValue
Section titled “setValue”setValue(value) replaces the current value as a single parse-and-format operation: the string
is read as if it were typed into an empty input in one step, and the result is reformatted under
the active mode and display configuration. Digits and a leading plus carry meaning; formatting
characters in the string do not, so a raw digit string and a preformatted one produce the same
state.
phoneInput.setValue('+380501234567');
phoneInput.getState().value; // '+380 50 123 4567'phoneInput.getState().region; // 'UA'The caret lands at the end of the new value.
In national mode, pass national digits. The whole string is read as national input there, so a
stored E.164 value like '+14155550132' comes out as '1 (415) 555-0132'. Prefill
international inputs from E.164 directly.
Each call pushes one history entry, so a single undo() reverts the whole replacement. A call
that leaves both the value and the region unchanged collapses into the current entry instead of
creating an undo step.
setRegion
Section titled “setRegion”setRegion(region) switches the active region, re-resolves the current digits under its rules,
and pushes one history entry. In national mode it changes the formatting convention:
// mode: 'national', defaultRegion: 'US'phoneInput.setRegion('GB');phoneInput.setValue('2071838750');
phoneInput.getState().value; // '20 7183 8750'phoneInput.getPhoneNumber().formatE164(); // '+442071838750'In international mode with the calling code in the value, the digits decide the region, and
setRegion matters only where they cannot: with '+44 20 7183 8750' in the input,
setRegion('UA') changes nothing, but with only '+1 ' typed, setRegion('CA') resolves the
shared calling code to 'CA' instead of the default 'US'.
Input and picker sync shows setRegion driven by a
region picker in both directions.
Undo and redo
Section titled “Undo and redo”The adapter already routes the platform’s own gestures through the controller history, so every undo step restores a full controller state: value, region, and caret. The browser’s native text undo never runs against the controlled value.
| Gesture | Handling |
|---|---|
Ctrl+Z or Cmd+Z |
undo() |
Ctrl+Shift+Z, Cmd+Shift+Z, Ctrl+Y, or Cmd+Y |
redo() |
Native historyUndo and historyRedo input events, for example the browser’s Edit menu |
undo() and redo() |
undo() and redo() expose the same steps to your own UI, for example toolbar buttons. Methods
and gestures alike are no-ops when no step is available. canUndo() and canRedo() are methods
on the instance, not fields of PhoneInputState, so read them inside your subscriber:
phoneInput.subscribe(() => { undoButton.disabled = !phoneInput.canUndo(); redoButton.disabled = !phoneInput.canRedo();});Every editing operation and every setValue or setRegion call is one entry. The stack keeps
up to maxHistorySize entries (default 150), dropping the oldest first, and editing after an
undo discards the redo branch.
phoneInput.setValue('+14155550132'); // '+1 415-555-0132'phoneInput.setValue('+442071838750'); // '+44 20 7183 8750'
phoneInput.undo();phoneInput.getState().value; // '+1 415-555-0132'phoneInput.canRedo(); // trueclearHistory
Section titled “clearHistory”clearHistory() drops every undo and redo entry, keeping only the current state. Call it after
programmatic prefill so the user’s first undo gesture edits their own input instead of reverting
the form to empty:
phoneInput.setValue('+380501234567');phoneInput.clearHistory();
phoneInput.canUndo(); // falsephoneInput.getState().value; // '+380 50 123 4567'Reading state
Section titled “Reading state”getState() returns the current PhoneInputState without subscribing. getPhoneNumber()
builds a PhoneNumber from the current digits, the same
interface parsePhoneNumber returns:
const phoneNumber = phoneInput.getPhoneNumber();
if (phoneNumber.isValid()) { phoneNumber.formatE164(); // '+380501234567'}Validate on submit covers the submit-time checks built on this object.
destroy and re-attach
Section titled “destroy and re-attach”destroy() detaches the DOM listeners and clears all subscribers. It is idempotent, and it does
not clear the element: the last formatted value stays in the DOM.
One PhoneInput attaches per element; a second createPhoneInput on the same element throws.
destroy() releases the element, so a later createPhoneInput may attach a fresh instance to
it. A destroyed instance never writes to the element or notifies subscribers again; discard it
rather than reusing it.
In component frameworks, create the instance when the element mounts and call destroy() in the
unmount hook; the frameworks guide covers component lifecycles.