MaskPro
FormKit Pro Quick Installation Guide 🚀
Introduction
The mask input automatically transforms user input to match a provided format. Used appropriately, mask inputs can provide an improved user experience by removing any ambiguity for the desired value (for example a phone number or social security number).
Basic example
<FormKit type="mask" name="phone" mask="+1 (###) ###-####" label="Phone number" help="Please enter a phone number"/>Masks
The mask is the desired format of the input. It is passed to the mask prop where it is parsed for tokens. The mask is comprised of:
- Tokens - A string representation of a user-editable region. Shown in white below.
- String literals - Any character that is not a token. Not user-editable. Shown in orange below.

Built-in tokens
The mask input comes with 4 built-in tokens:
h- Accepts a hexadecimal character (0-9a-fA-F).#- Accepts a digit character.a- Accepts an alphabetical character.*- Accepts any character.
<script setup>import { ref } from 'vue'const color = ref(null)</script><template> <FormKit type="mask" name="favorite_color" v-model="color" mask="\#hhhhhh" label="Favorite Color in Hex" help="Enter your favorite color in hexadecimal format. Or try FFA500." /> <div class="box" :style="{ backgroundColor: color }"></div></template><style scoped>.box { width: 30px; height: 30px;}</style>Escaping built-ins
If you need to use one of the built-in tokens as a string literal in your mask, you can escape them with \. Here we are escaping the pound sign # to use in our hex color:
<FormKit mask="\#hhhhhh" type="mask" />
Modes
The mask input supports 3 entry modes:
- Shift (default)
- Replace
- Select
Shift & replace mode
By default, the characters of a mask are automatically shifted forward when typing. This is notable when a mask is already populated and you place the cursor at or near the beginning of the input and begin typing. The characters following your cursor are "shifted" forward as you type. In replace mode, however, subsequent characters are overwritten with a new value:
<FormKit type="mask" mask="###-###-####" value="123-456-7890" label="(Shift mode) Social security number" help="Notice when you type new numbers the characters shift to the right."/><FormKit type="mask" mode="replace" mask="###-###-####" value="123-456-7890" label="(Replace mode) Social security number" help="Notice when you type new numbers the characters are replaced."/>Select mode
In select mode, equivalent char type tokens are grouped into selectable text ranges. FormKit automatically selects these text ranges when clicking or focusing the input. These selection ranges are maintained as the user is typing. When used tastefully, this produces a clear UX as the user is aware of what value they are expected to enter.
Additionally, when an input is in select mode, the user can use the arrow or tab keys to shift their focus from one selection range to another:
<FormKit type="mask" mode="select" mask="###-###-####" label="(Select mode) Social security number" help="In select mode the active range is always highlighted."/>The selectDirection token property controls which direction new
characters flow into the selected range. You can fill "empty" selection characters with a predetermined value (like leading zeros "0") by using the selectFill property. See token properties.
Tokens
Creating new tokens
What if a pattern can accept letters or numbers in the same position? It’s relatively simple to create new tokens. There are 2 types of tokens:
characcepts a single character.enumaccepts any strings from an array of possible values.
The following properties must be defined to create a new token:
{
/**
* The type of token. Can be a `char` or `enum`.
*/
type: 'char',
/**
* The token to parse out of the mask.
*/
token: 'z',
/**
* A placeholder character to display in the input when `show-mask` is
* enabled.
*/
placeholder: '_',
/**
* When using `select` mode, determines which direction do new characters flow
* in.
*/
selectDirection: 'left',
/**
* (Only for `char` type). A regular expression that describes the types of
* characters that can appear in this slot. This pattern will be evaluated
* against individual characters — not in the context of the entire string.
*/
pattern: /[A-Za-z0-9]/,
/**
* (Only for `char` type, optional). An optional character to "fill" the
* selection range with when in select mode. For example, a selectFill set to
* "0" can be helpful with numbers to produce leading zeros like "001".
*/
selectFill: "0",
/**
* (Only for `enum` type). An array of possible values.
*/
values: [
'March',
'April',
'May'
],
}
For example, a new token that accepts letters and numbers, and is represented by the letter z in the mask string would look like this:
{
type: 'char',
token: 'z',
pattern: /[A-Za-z0-9]/,
placeholder: '_',
selectDirection: 'left',
}
Any placeholder you define should not match the Regex pattern provided in the token definition.
Add tokens via prop
To pass a new token to the mask input, you can use the tokens prop which
expects an object with keys that match the token property. For example, our new token in the above example can be applied directly:
<FormKit type="mask" name="promo_code" mask="zzz-#### ####" :tokens="{ z: { type: 'char', token: 'z', pattern: /[A-Za-z0-9]/, placeholder: '_', selectDirection: 'left', }, }" value="a6d-7789 4398" label="Promo code" help="Enter a promo code in the format: fkt-1234 5678"/>Add tokens globally
To register your mask tokens globally, extend the config property of your global FormKit configuration:
<FormKit type="mask" name="tracking" mask="usps-zzz-zzzz-zzzz-zzzz" value="usps-mk6-8d2z-8fggy-921x" label="Tracking number"/>Modify tokens
In addition to creating new tokens, the tokens prop can also modify existing tokens. Any value provided to the tokens prop will be merged into the existing tokens for that input. For example, the digit token’s (#) has no selectFill by default. To add one, extend it:
<FormKit type="mask" mode="select" name="year" mask="####" label="What year were you born?" help="You must be at least 21 to enter this site." :tokens="{ '#': { selectFill: '0', }, }" :validation="`required|max:${new Date().getFullYear() - 21}|min:${ new Date().getFullYear() - 120 }`" validation-label="Birth year" validation-visibility="live" :validation-messages="{ min: 'Alright gramps, you\'re too old for this site.', }"/>Char tokens
char tokens accept a single character. In order for a character to be accepted, it must match the token.pattern regular expression. The four built in tokens (h, #, a, and *) are all char type tokens.
In select mode, char tokens are grouped together into a selection range.
A char token should only ever represent 1 character, and its placeholder should also only be a single character in length.
Enum Tokens
Enum tokens allow for variable length masks within a predefined set of options. As a user begins to type, the enum token’s value will change to the first matching value, and the selection range will reflect the currently unmatched characters. In practice, this operates much like an autocomplete for that specific token. Additionally, users can cycle through available options for a given token by hitting the up/down arrow keys.
A date with auto-completing month names could be well represented with enums:
<script setup>const tokens = { month: { type: 'enum', token: 'month', placeholder: 'month', selectDirection: 'left', values: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', ], }, day: { type: 'enum', token: 'day', placeholder: 'day', selectDirection: 'left', values: new Array(31).fill(0).map((_, i) => `${i}`.padStart(2, '0')), }, year: { type: 'enum', token: 'year', placeholder: 'year', selectDirection: 'left', values: new Array(200).fill(0).map((_, i) => `${1900 + i}`), },}</script><template> <FormKit type="mask" mode="select" mask="month day, year" :tokens="tokens" label="(Enums) Birthday" help="Select a token and then type to autocomplete, or use the up/down arrows to select a value." /></template>Enums are only supported in select mode. When any enum token is found in a mask string, the mode of the input is forcibly set to select.
Groups
Groups are a way to to treat multiple mask characters as a single unit. You create a group by surrounding the desired mask characters in {}:
<FormKit mask="id{-a#a}" type="mask" />
<!-- "-a#a" is the group -->
On their own, groups don't do anything unless you define group options.
Group options
Group options allow you to apply functionality to an entire group using a pipe | followed by the option name and any arguments. The available options are:
- repeat — allows a group to be repeated an infinite number of times.
- placeholder — A character to hold space prior to user input.
A placeholder defined within a group has a higher specificity than a placeholder defined in the token definition and will override it.
Option parameters
Arguments can be passed to a group option by using a colon, such as placeholder:+, where the plus symbol + is passed to the placeholder option.
You can string group options together:
<FormKit type="mask" name="school_id" mask="id{-a#a|repeat|placeholder:+}" label="Id number" help="Id number in the format: id-b4b-b4b-b4b-b4b"/><!-- "-a#a" is the group, "repeat" and "placeholder" are the options -->Groups cannot be used in select mode. An exception will be thrown.
Prefix & suffix
You can ensure certain characters always appear at the beginning or end of an input by using the prefix and suffix props, respectively:
<FormKit type="mask" name="years_old" prefix="I am " suffix=" years old." mask="##" mode="select" validation="required" :tokens="{ '#': { selectFill: '0' } }" label="Age" help="How old are you?"/>Your prefix and suffix content can't match the mask. For instance, if your mask has a digit token #, your prefix/suffix can't contain numbers.
Running the mask in reverse
In specific circumstances, you may want to run your mask in reverse. The mask will test if user input fulfills the mask from right to left. This is common in currency-type inputs and can be applied by adding the reverse prop:
<FormKit type="form" :actions="false" #default="{ value }"> <FormKit type="mask" reverse prefix="€" name="bid" mask="{#,##|repeat}#.##" label="Bid" show-mask="false" allow-incomplete="true" help="Enter your bid for the art piece." /> <pre wrap>{{ value }}</pre> </FormKit>Running a mask in reverse only works in shift mode.
Mask values
Incomplete values
A mask’s value is not considered "complete" until the user has filled the entire pattern. Until that point, FormKit will consider the value of the input "empty". This makes it convenient to use with validation rules like required. However, if you’d like to accept incomplete values, you can via the allow-incomplete prop:
<FormKit type="form" #default="{ value }"> <FormKit type="mask" name="phone" mask="(###) ###-####" label="Phone number" help="Enter a phone number. See the value change as you type." allow-incomplete="true" /> <pre wrap>{{ value }}</pre></FormKit>Unmasked values
By default, the value of a mask input includes the formatting provided via the mask prop. However, if you'd like the raw unmasked value with the string literals removed, you can use the unmask-value prop:
<FormKit type="form" #default="{ value }"> <FormKit type="mask" name="phone" mask="(###) ###-####" label="Phone number" help="Enter a full phone number. See the value has no string literals." unmask-value="true" /> <pre wrap>{{ value }}</pre></FormKit>Hiding the mask
By default, the mask input displays each token’s placeholder character. You can disable this behavior (except in select mode) while still applying formatting automatically via the show-mask prop:
<FormKit type="mask" name="phone" mask="+39 ###.######" label="Número de teléfono" help="Inserisci il tuo numero di cellulare." show-mask="false"/>Overlay (colorizing a mask)
By default, a mask’s value is displayed via the value of its input element. Although this works "out of the box" it does now allow for the text be stylistically differentiated. For example it would be nice if the "literal" portions of the mask looked different than the "placeholder" portions.
To achieve this effect, you can enable an overlay which renders DOM elements that are positioned directly over the input itself. The text inside the input is still there, but it will be transparent. In general the necessary overlay positioning styles are automatically applied for you.
The overlay contains 4 possible sections you can target your styles at:
- Literal (
.formkit-overlay-literaloroverlay-literal-class) - Placeholder (
.formkit-overlay-placeholderoroverlay-placeholder-class) - Enum (
.formkit-overlay-enumoroverlay-enum-class) - Char (
.formkit-overlay-charoroverlay-char-class)
The default genesis theme automatically supports the overlay and applies light gray colors to the placeholder. If you are not using Genesis, please ensure the inner section is positioned (like position: relative).
<template> <FormKit type="mask" mode="select" mask="month day, year" :tokens="tokens" label="Birthday (with overlay)" help="Notice the placeholder text is a lighter gray color." overlay /> <FormKit type="mask" name="phone" mask="+1 (###) ###-####" label="Phone number (with overlay)" help="Let’s add some crazy colors to the overlay." overlay-placeholder-class="yellow" overlay-literal-class="blue" overlay-char-class="red" overlay /></template><style scoped>.red { color: red;}.yellow { color: #d1c813;}.blue { color: blue;}</style>Props & Attributes
| Prop | Type | Default | Description |
|---|---|---|---|
allow-incomplete | boolean | false | By default, the value of a mask input is empty until the pattern is complete. This prop allows the input to use incomplete values. |
mask | string | none | The mask to apply. This is a string composed of tokens (like “#”) and literal string values. |
mode | string | shift | Determines how the mask input operates. Options are shift, replace and select. |
overlay | boolean | false | Renders DOM elements that mimic the text input to allow the differentiation in the stylization of the mask. |
prefix | string | none | Characters that will always appear at the beginning of the input. |
reverse | boolean | false | Runs the mask in reverse — from right to left. |
show-mask | boolean | true | Displays a live representation of the pattern’s placeholder as the internal value of the input. |
suffix | string | none | Characters that will always appear at the end of the input. |
tokens | Object | {} | Add new tokens or modify existing ones. |
unmask-value | boolean | false | By default, the value of the input is the same as what is displayed (with formatting). The string literals will removed from the value if this prop is set to true. |
| Show Universal props | |||
config | Object | {} | Configuration options to provide to the input’s node and any descendent node of this input. |
delay | Number | 20 | Number of milliseconds to debounce an input’s value before the commit hook is dispatched. |
dirtyBehavior | string | touched | Determines how the "dirty" flag of this input is set. Can be set to touched or compare — touched (the default) is more performant, but will not detect when the form is once again matching its initial state. |
errors | Array | [] | Array of strings to show as error messages on this field. |
help | String | '' | Text for help text associated with the input. |
id | String | input_{n} | The unique id of the input. Providing an id also allows the input’s node to be globally accessed. |
ignore | Boolean | false | Prevents an input from being included in any parent (group, list, form etc). Useful when using inputs for UI instead of actual values. |
index | Number | undefined | Allows an input to be inserted at the given index if the parent is a list. If the input’s value is undefined, it inherits the value from that index position. If it has a value it inserts it into the lists’s values at the given index. |
label | String | '' | Text for the label element associated with the input. |
name | String | input_{n} | The name of the input as identified in the data object. This should be unique within a group of fields. |
parent | FormKitNode | contextual | By default the parent is a wrapping group, list or form — but this props allows explicit assignment of the parent node. |
prefix-icon | String | '' | Specifies an icon to put in the prefixIcon section. |
preserve | Boolean | false | Preserves the value of the input on a parent group, list, or form when the input unmounts. |
preserve-errors | Boolean | false | By default errors set on inputs using setErrors are automatically cleared on input, setting this prop to true maintains the error until it is explicitly cleared. |
sections-schema | Object | {} | An object of section keys and schema partial values, where each schema partial is applied to the respective section. |
suffix-icon | String | '' | Specifies an icon to put in the suffixIcon section. |
type | String | text | The type of input to render from the library. |
validation | String, Array | [] | The validation rules to be applied to the input. |
validation-visibility | String | blur | Determines when to show an input's failing validation rules. Valid values are blur, dirty, and live. |
validation-label | String | {label prop} | Determines what label to use in validation error messages, by default it uses the label prop if available, otherwise it uses the name prop. |
validation-rules | Object | {} | Additional custom validation rules to make available to the validation prop. |
value | Any | undefined | Seeds the initial value of an input and/or its children. Not reactive. Can seed entire groups (forms) and lists.. |
Sections
You can target a specific section of an input using that section's "key", allowing you to modify that section's classes, HTML (via :sections-schema, or content (via slots)). Read more about sections here.
Basic structure
The mask input follows the standard text-family structure.
Click on a section to lock focus to the chosen section. Click locked section again to unlock.
Overlay structure
When overlay is enabled, additional sections render styled text over the input.
Click on a section to lock focus to the chosen section. Click locked section again to unlock.
| Section-key | Description |
|---|---|
outer | The outermost wrapping element. |
wrapper | A wrapper around the label and input. |
label | The label of the input. |
prefix | Has no output by default, but allows content directly before an input element. |
prefixIcon | An element for outputting an icon before the prefix section. |
inner | A wrapper around the actual input element. |
suffix | Has no output by default, but allows content directly after an input element. |
suffixIcon | An element for outputting an icon after the suffix section. |
input | The input element itself. |
help | The element containing help text. |
messages | A wrapper around all the messages. |
message | The element (or many elements) containing a message — most often validation and error messages. |
Accessibility
All FormKit inputs are designed with the following accessibility considerations in mind. Help us continually improve accessibility for all by filing accessibility issues here:
- Semantic markup
- ARIA attributes
- Keyboard accessibility
- Focus indicators
- Color contrast with the provided theme
- Accessible labels, help text, and errors
Accessibility attributes
| Section Key | Attribute | Value | Description |
|---|---|---|---|
label | label | for | Associates a label to an input element. Users can click on the label to focus the input or to toggle between states. |
input | input | disabled | Disables an HTML element, preventing user interaction and signaling a non-interactive state. |
aria-describedby | Associates an element with a description, aiding screen readers. | ||
aria-required | Added when input validation is set to required. | ||
icon | icon | for | Links icon to input element when icon in rendered as a label. |
Keyboard Interactions
| Keyboard Event | Description |
|---|---|
| Tab | While in select mode, moves forward through available mask selection ranges. If at the end of available selection ranges the focus will be moved to the next focusable element on the page. |
| Shift+Tab | While in select mode, moves backward through available mask selection ranges. if at the beginning of available selection ranges the focus will be moved to the previous focusable element on the page. |
| ↑↓ | While in select mode, navigates through available options for selection ranges that are enum tokens. |
| Universal Keyboard Events | |
| Tab | Moves the focus to the next focusable element on the page. |
| Shift+Tab | Moves the focus to the previous focusable element on the page. |