Components

Text input

Use the text input component when you need to let users enter text that’s no longer than a single line, such as their name or phone number.

See the GOV.UK Design System documentation on text inputs for more information on when to use this component.

<script setup lang="ts">
import { ref } from 'vue'
const eventName = ref('')
</script>

<template>
  <gv-input label="What is the name of the event?" v-model="eventName" />
  <gv-inset-text v-if="eventName" aria-live="polite">
    '{{ eventName }}' will be printed on the poster for your event.
  </gv-inset-text>
</template>

Binding with v-model and using events

Use v-model to bind data to the input, as you would with a native <input>.

You can also attach event listeners and they'll be bound to the underlying <input>.

<script setup lang="ts">
import { ref } from 'vue'
const bindingExampleData = ref('')

function handleKeyDown() {
  alert('You pressed the down key')
}
</script>

<template>
  <gv-input label="Type or press the down arrow key in this input" v-model="bindingExampleData" @keydown.down="handleKeyDown"/>
  <gv-inset-text v-if="bindingExampleData" aria-live="polite">
    You typed {{bindingExampleData}}.
  </gv-inset-text>
</template>

Setting the label as the page heading

If you’re asking just one question per page, you can set the contents of the <label> as the page heading. Set the label-is-page-heading prop to true and pass a class in label-class to change the size, for example govuk-label--l.

This will be printed on the poster
<script setup lang="ts">
import { ref } from 'vue'
const eventName = ref('')
</script>

<template>
  <gv-input v-model="eventName" :label-is-page-heading="true" label-class="govuk-label--l">
    <template #label>
      What is the name of the event?
    </template>
    <template #hint>
      This will be printed on the poster
    </template>
  </gv-input>
  <gv-inset-text v-if="eventName" aria-live="polite">
    '{{ eventName }}' will be printed on the poster for your event.
  </gv-inset-text>
</template>

Changing the input size

You can pass any of the GOV.UK input size modifier classes via class.

<gv-input label="5 character width" class="govuk-input--width-5" />
<gv-input label="One-half width" class="govuk-!-width-one-half" />

Numeric input

If you’re asking the user to enter a whole number, set the inputmode prop to numeric to use the numeric keypad on devices with on-screen keyboards.

Must be between 6 and 8 digits long
<gv-input :label-is-page-heading="true" label-class="govuk-label--l" inputmode="numeric" :spellcheck="false" class="govuk-input--width-10">
  <template #label>
    What is your account number?
  </template>
  <template #hint>
    Must be between 6 and 8 digits long
  </template>
</gv-input>

If you've bound data with v-model, remember that the user may type a string rather than a number. You'll need to check whether the model value is actually a number if that's important in your code, for example if you're doing calculations or you're passing the model value as a prop value to a prop that's expecting a number.

The GOV.UK Design System recommends avoding type="number", so GOV.UK Vue doesn't support it.

It also recommends avoiding inputmode="decimal". Use a normal <gv-input> without an inputmode for decimals.

Prefixes and suffixes

You can add prefixes and suffixes with the prefixText and suffixText props, or the prefix and suffix slots:

<script setup lang="ts">
import { ref, computed } from 'vue'

const itemPrice = ref(null)
const vatRate = 0.2

const priceWithVat = computed(() => {
  const parsedItemPrice = parseFloat(itemPrice.value);
  
  if(!isNaN(parsedItemPrice)) {
    const formatter = new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'GBP' })
    return formatter.format(parsedItemPrice * (1 + vatRate))
  }
})
</script>
<template>
  <gv-input v-model="itemPrice" prefix="£" suffix="per item" :spellcheck="false" class="govuk-input--width-4">
    <template #label>
      What is the cost per item excluding VAT, in pounds?
    </template>
  </gv-input>
  <gv-inset-text v-if="priceWithVat" aria-live="polite">
    The total cost per item, including VAT, is {{ priceWithVat }}
  </gv-inset-text>
</template>

Props

NameTypeDescription
modelValue string
The value of the input. In most cases you should use v-model instead of setting this prop directly.
id string
The ID of the input. If you don't provide an ID, one will be generated automatically.
name string
The name of the input, which is submitted with the form data.
type string
Type of input control to render, for example, a password input control. Defaults to text.

Defaults to 'text'.
inputmode string
Optional value for inputmode.

Allowed values: text, none, tel, url, email, numeric, decimal, search.
describedBy string
One or more element IDs to add to the aria-describedby attribute, used to provide additional descriptive information for screenreader users.
autocomplete string
Attribute to identify input purpose, for example postal-code or username. See autofill for full list of values that can be used.
pattern string
Attribute to provide a regular expression pattern, used to match allowed character combinations for the input value.
spellcheck boolean
Whether to enable or disable the spellcheck attribute on the input

Defaults to null.
disabled boolean
If true, input will be disabled.
formGroupClass string|array|object
Classes to add to the form group. You can bind a string, an array or an object, as with normal Vue class bindings.
label string
Text to use within the label. If content is provided in the default slot, this prop will be ignored.
labelIsPageHeading boolean
Whether the label also acts as the heading for the page.

Defaults to false.
labelClass string|array|object
Classes to add to the label tag. You can bind a string, an array or an object, as with normal Vue class bindings.
hint string
Text to use within the hint. If content is provided in the hint slot, this prop will be ignored.
hintClass string|array|object
Classes to add to the hint span tag. You can bind a string, an array or an object, as with normal Vue class bindings.
prefix string
Text to use within the prefix. If content is provided in the prefix slot, this prop will be ignored.
prefixClass string|array|object
Classes to add to the prefix. You can bind a string, an array or an object, as with normal Vue class bindings.
suffix string
Text to use within the suffix. If content is provided in the suffix slot, this prop will be ignored.
suffixClass string|array|object
Classes to add to the suffix. You can bind a string, an array or an object, as with normal Vue class bindings.
errorMessage string
Text to use within the error message. If content is provided in the error-message slot, this prop will be ignored.
errorMessageClass string|array|object
Classes to add to the error message <p> tag. You can bind a string, an array or an object, as with normal Vue class bindings.
errorMessageVisuallyHiddenText string
A visually hidden prefix used before the error message. Defaults to 'Error'.
beforeInput string
Text to add before the input. If content is provided in the before-input slot, this prop will be ignored.
afterInput string
Text to add after the input. If content is provided in the after-input slot, this prop will be ignored.

Slots

NameDescription
label
The content of the label. If content is provided in this slot, the label prop will be ignored.
hint
The content of the hint. If content is provided in this slot, the hint prop will be ignored.
error-message
The content of the error message. If content is provided in this slot, the errorMessage prop will be ignored.
before-input
Content to add before the input. If content is provided in this slot, the beforeInput prop will be ignored.
prefix
The content of the prefix. If content is provided in this slot, the prefix prop will be ignored.
suffix
The content of the suffix. If content is provided in this slot, the suffix prop will be ignored.
after-input
Content to add after the input. If content is provided in this slot, the afterInput prop will be ignored.