Skip to content

Filters

createPhoneInput accepts two restriction options. regionFilter narrows resolution to a set of regions; numberTypeFilter narrows it to a set of number types. Both default to null, which means no restriction, and both can change at runtime.

Filters do not block typing. Every keystroke still reaches the controller; a filter changes how the digits resolve and validate, and your rendering decides what to show.

Pass either filter at creation:

import { createPhoneInput } from '@telixon/web-sdk';
const phoneInput = createPhoneInput({
mode: 'international',
input: inputElement,
regionFilter: ['US', 'CA'],
});

Or change them at runtime:

phoneInput.setRegionFilter(['US']);
phoneInput.setNumberTypeFilter(['MOBILE']);
phoneInput.setNumberTypeFilter(null); // removes the restriction

Every emitted state echoes the active values as state.regionFilter and state.numberTypeFilter. Passing an array with the same contents in the same order is a no-op: nothing recomputes, nothing emits. An initialValue resolves under the filters given alongside it.

Resolution walks a deterministic automaton compiled from Google’s libphonenumber metadata. A filter removes the branches outside the allowed set from that walk, so filtering is not a post-hoc check on a parsed number; it changes resolution itself.

Surface Effect of an active filter
state.region Only allowed interpretations resolve. A calling code with no allowed region never completes; digits shared by several regions resolve within the allowed set.
state.validationError Errors are judged against the allowed set. The length fields minLength, maxLength, and possibleLengths come from the allowed regions and types only.
state.placeholder The placeholder follows state.region, so it moves when a filter changes resolution.
getPhoneNumber() The returned PhoneNumber validates under the same restrictions.

numberTypeFilter does not change which number type the placeholder demonstrates; that is placeholderNumberType, which defaults to 'MOBILE'. Set it to a type the filter allows so the example is a number the input accepts.

An input that accepts only United States and Canada numbers:

const phoneInput = createPhoneInput({
mode: 'international',
input: inputElement,
regionFilter: ['US', 'CA'],
});
phoneInput.setValue('12045550123');
phoneInput.getState().value; // '1 204-555-0123'
phoneInput.getState().region; // 'CA'
phoneInput.getState().validationError; // null
phoneInput.setValue('442079460958');
phoneInput.getState().value; // '442079460958'
phoneInput.getState().region; // null
phoneInput.getState().validationError; // { kind: 'INVALID_CALLING_CODE' }

The United Kingdom number cannot complete a calling code inside the allowed set, so its digits pass through unformatted, no region resolves, and the error is INVALID_CALLING_CODE.

Narrowing the filter re-resolves the digits already in the input:

phoneInput.setValue('12045550123');
phoneInput.getState().region; // 'CA'
phoneInput.getState().placeholder; // '1 506-234-5678'
phoneInput.setRegionFilter(['US']);
phoneInput.getState().region; // 'US'
phoneInput.getState().placeholder; // '1 201-555-0123'
phoneInput.getState().validationError; // { kind: 'PATTERN_MISMATCH' }

With Canada excluded, area code 204 (Manitoba) has no allowed Canadian interpretation; the digits are read against the United States, which shares calling code 1, and fail its patterns.

const phoneInput = createPhoneInput({
mode: 'national',
input: inputElement,
defaultRegion: 'GB',
numberTypeFilter: ['MOBILE'],
});
phoneInput.setValue('07400123456');
phoneInput.getState().value; // '07400 123456'
phoneInput.getState().validationError; // null
phoneInput.setValue('02079460958');
phoneInput.getState().value; // '020 7946 0958'
phoneInput.getState().validationError; // { kind: 'PATTERN_MISMATCH' }

The London fixed-line number is valid for the United Kingdom but not as a mobile number, so it reports PATTERN_MISMATCH. It still formats: formatting falls back to the region’s general number structure, which a type filter never removes; only validation narrows to the allowed types.

Length errors narrow with the filter:

phoneInput.setValue('074001');
phoneInput.getState().validationError; // { kind: 'TOO_SHORT', minLength: 10 }

Without the filter, the same digits report { kind: 'POSSIBLE_LOCAL_ONLY' }: they could still be a local-dialing subscriber number. Under ['MOBILE'], only mobile lengths count, and minLength is the ten national digits a United Kingdom mobile number requires.

'FIXED_LINE_OR_MOBILE' in a filter allows both fixed-line and mobile matches. An empty array allows nothing; null, not [], is the value that removes a restriction.

setRegionFilter and setNumberTypeFilter re-resolve the current digits in place and emit one new state. The recompute replaces the current history entry instead of pushing one, so a filter change is never an undo step.

createRegionList accepts the same regionFilter and numberTypeFilter values, so a picker can offer exactly the regions the input accepts. See Region picker and Input and picker sync. For rendering state.validationError, see Validation feedback.