Use the v-model directive to control the value of the InputNumber.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber v-model="value" />
</template>
Use the default-value prop to set the initial value when you do not need to control its state.
<template>
<UInputNumber :default-value="5" />
</template>
This component relies on the @internationalized/number package which provides utilities for formatting and parsing numbers across locales and numbering systems.
Use the min and max props to set the minimum and maximum values of the InputNumber.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber v-model="value" :min="0" :max="10" />
</template>
Use the step prop to set the step value of the InputNumber.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber v-model="value" :step="2" />
</template>
Use the orientation prop to change the orientation of the InputNumber.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber v-model="value" orientation="vertical" />
</template>
Use the placeholder prop to set a placeholder text.
<template>
<UInputNumber placeholder="Enter a number" />
</template>
Use the color prop to change the ring color when the InputNumber is focused.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber v-model="value" color="neutral" highlight />
</template>
Use the variant prop to change the variant of the InputNumber.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber v-model="value" variant="subtle" color="neutral" />
</template>
Use the size prop to change the size of the InputNumber.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber v-model="value" size="xl" />
</template>
Use the disabled prop to disable the InputNumber.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber v-model="value" disabled />
</template>
Use the increment and decrement props to customize the increment and decrement buttons with any Button props. Defaults to { variant: 'link' }.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber
v-model="value"
:increment="{
color: 'neutral',
variant: 'solid',
size: 'xs'
}"
:decrement="{
color: 'neutral',
variant: 'solid',
size: 'xs'
}"
/>
</template>
Use the increment-icon and decrement-icon props to customize the buttons Icon. Defaults to i-lucide-plus / i-lucide-minus.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber
v-model="value"
increment-icon="i-lucide-arrow-right"
decrement-icon="i-lucide-arrow-left"
/>
</template>
Use the format-options prop to customize the format of the value.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber
v-model="value"
:format-options="{
signDisplay: 'exceptZero',
minimumFractionDigits: 1
}"
/>
</template>
Use the format-options prop with style: 'percent' to customize the format of the value.
<script setup lang="ts">
const value = ref(0.05)
</script>
<template>
<UInputNumber
v-model="value"
:step="0.01"
:format-options="{
style: 'percent'
}"
/>
</template>
Use the format-options prop with style: 'currency' to customize the format of the value.
<script setup lang="ts">
const value = ref(1500)
</script>
<template>
<UInputNumber
v-model="value"
:format-options="{
style: 'currency',
currency: 'EUR',
currencyDisplay: 'code',
currencySign: 'accounting'
}"
/>
</template>
You can use the increment and decrement props to control visibility of the buttons.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber
v-model="value"
:increment="false"
:decrement="false"
/>
</template>
You can use the InputNumber within a FormField component to display a label, help text, required indicator, etc.
<script setup lang="ts">
const retries = ref(0)
</script>
<template>
<UFormField label="Retries" help="Specify number of attempts" required>
<UInputNumber v-model="retries" placeholder="Enter retries" />
</UFormField>
</template>
Use the #increment and #decrement slots to customize the buttons.
<script setup lang="ts">
const value = ref(5)
</script>
<template>
<UInputNumber v-model="value">
<template #decrement>
<UButton size="xs" icon="i-lucide-minus" />
</template>
<template #increment>
<UButton size="xs" icon="i-lucide-plus" />
</template>
</UInputNumber>
</template>
| Prop | Default | Type |
|---|---|---|
as |
|
The element or component this component should render as. |
placeholder |
The placeholder text when the input is empty. | |
color |
|
|
variant |
|
|
size |
|
|
highlight |
Highlight the ring color like a focus state. | |
orientation |
|
The orientation of the input menu. |
increment |
| Configure the increment button. The
|
incrementIcon |
|
The icon displayed to increment the value. |
incrementDisabled |
Disable the increment button. | |
decrement |
|
Configure the decrement button. The
|
decrementIcon |
|
The icon displayed to decrement the value. |
decrementDisabled |
Disable the decrement button. | |
autofocus |
| |
autofocusDelay |
| |
modelModifiers |
| |
locale |
|
The locale to use for formatting and parsing numbers. |
disabled |
When | |
name |
The name of the field. Submitted with its owning form as part of a name/value pair. | |
modelValue |
| |
defaultValue |
| |
required |
When | |
id |
Id of the element | |
min |
The smallest value allowed for the input. | |
max |
The largest value allowed for the input. | |
step |
The amount that the input value changes with each increment or decrement "tick". | |
stepSnapping |
When | |
formatOptions |
Formatting options for the value displayed in the number field. This also affects what characters are allowed to be typed by the user. | |
disableWheelChange |
When | |
invertWheelChange |
When | |
readonly |
When | |
ui |
|
| Slot | Type |
|---|---|
increment |
|
decrement |
|
| Event | Type |
|---|---|
change |
|
blur |
|
update:modelValue |
|
When accessing the component via a template ref, you can use the following:
| Name | Type |
|---|---|
inputRef | Ref<InstanceType<typeof NumberFieldInput> | null> |
export default defineAppConfig({
ui: {
inputNumber: {
slots: {
root: 'relative inline-flex items-center',
base: [
'w-full rounded-md border-0 placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75',
'transition-colors'
],
increment: 'absolute flex items-center',
decrement: 'absolute flex items-center'
},
variants: {
fieldGroup: {
horizontal: {
root: 'group has-focus-visible:z-[1]',
base: 'group-not-only:group-first:rounded-e-none group-not-only:group-last:rounded-s-none group-not-last:group-not-first:rounded-none'
},
vertical: {
root: 'group has-focus-visible:z-[1]',
base: 'group-not-only:group-first:rounded-b-none group-not-only:group-last:rounded-t-none group-not-last:group-not-first:rounded-none'
}
},
color: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
},
size: {
xs: 'px-2 py-1 text-xs gap-1',
sm: 'px-2.5 py-1.5 text-xs gap-1.5',
md: 'px-2.5 py-1.5 text-sm gap-1.5',
lg: 'px-3 py-2 text-sm gap-2',
xl: 'px-3 py-2 text-base gap-2'
},
variant: {
outline: 'text-highlighted bg-default ring ring-inset ring-accented',
soft: 'text-highlighted bg-elevated/50 hover:bg-elevated focus:bg-elevated disabled:bg-elevated/50',
subtle: 'text-highlighted bg-elevated ring ring-inset ring-accented',
ghost: 'text-highlighted bg-transparent hover:bg-elevated focus:bg-elevated disabled:bg-transparent dark:disabled:bg-transparent',
none: 'text-highlighted bg-transparent'
},
disabled: {
true: {
increment: 'opacity-75 cursor-not-allowed',
decrement: 'opacity-75 cursor-not-allowed'
}
},
orientation: {
horizontal: {
base: 'text-center',
increment: 'inset-y-0 end-0 pe-1',
decrement: 'inset-y-0 start-0 ps-1'
},
vertical: {
increment: 'top-0 end-0 pe-1 [&>button]:py-0 scale-80',
decrement: 'bottom-0 end-0 pe-1 [&>button]:py-0 scale-80'
}
},
highlight: {
true: ''
},
increment: {
false: ''
},
decrement: {
false: ''
}
},
compoundVariants: [
{
color: 'primary',
variant: [
'outline',
'subtle'
],
class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary'
},
{
color: 'primary',
highlight: true,
class: 'ring ring-inset ring-primary'
},
{
color: 'neutral',
variant: [
'outline',
'subtle'
],
class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-inverted'
},
{
color: 'neutral',
highlight: true,
class: 'ring ring-inset ring-inverted'
},
{
orientation: 'horizontal',
decrement: false,
class: 'text-start'
},
{
decrement: true,
size: 'xs',
class: 'ps-7'
},
{
decrement: true,
size: 'sm',
class: 'ps-8'
},
{
decrement: true,
size: 'md',
class: 'ps-9'
},
{
decrement: true,
size: 'lg',
class: 'ps-10'
},
{
decrement: true,
size: 'xl',
class: 'ps-11'
},
{
increment: true,
size: 'xs',
class: 'pe-7'
},
{
increment: true,
size: 'sm',
class: 'pe-8'
},
{
increment: true,
size: 'md',
class: 'pe-9'
},
{
increment: true,
size: 'lg',
class: 'pe-10'
},
{
increment: true,
size: 'xl',
class: 'pe-11'
}
],
defaultVariants: {
size: 'md',
color: 'primary',
variant: 'outline'
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
inputNumber: {
slots: {
root: 'relative inline-flex items-center',
base: [
'w-full rounded-md border-0 placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75',
'transition-colors'
],
increment: 'absolute flex items-center',
decrement: 'absolute flex items-center'
},
variants: {
fieldGroup: {
horizontal: {
root: 'group has-focus-visible:z-[1]',
base: 'group-not-only:group-first:rounded-e-none group-not-only:group-last:rounded-s-none group-not-last:group-not-first:rounded-none'
},
vertical: {
root: 'group has-focus-visible:z-[1]',
base: 'group-not-only:group-first:rounded-b-none group-not-only:group-last:rounded-t-none group-not-last:group-not-first:rounded-none'
}
},
color: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
},
size: {
xs: 'px-2 py-1 text-xs gap-1',
sm: 'px-2.5 py-1.5 text-xs gap-1.5',
md: 'px-2.5 py-1.5 text-sm gap-1.5',
lg: 'px-3 py-2 text-sm gap-2',
xl: 'px-3 py-2 text-base gap-2'
},
variant: {
outline: 'text-highlighted bg-default ring ring-inset ring-accented',
soft: 'text-highlighted bg-elevated/50 hover:bg-elevated focus:bg-elevated disabled:bg-elevated/50',
subtle: 'text-highlighted bg-elevated ring ring-inset ring-accented',
ghost: 'text-highlighted bg-transparent hover:bg-elevated focus:bg-elevated disabled:bg-transparent dark:disabled:bg-transparent',
none: 'text-highlighted bg-transparent'
},
disabled: {
true: {
increment: 'opacity-75 cursor-not-allowed',
decrement: 'opacity-75 cursor-not-allowed'
}
},
orientation: {
horizontal: {
base: 'text-center',
increment: 'inset-y-0 end-0 pe-1',
decrement: 'inset-y-0 start-0 ps-1'
},
vertical: {
increment: 'top-0 end-0 pe-1 [&>button]:py-0 scale-80',
decrement: 'bottom-0 end-0 pe-1 [&>button]:py-0 scale-80'
}
},
highlight: {
true: ''
},
increment: {
false: ''
},
decrement: {
false: ''
}
},
compoundVariants: [
{
color: 'primary',
variant: [
'outline',
'subtle'
],
class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary'
},
{
color: 'primary',
highlight: true,
class: 'ring ring-inset ring-primary'
},
{
color: 'neutral',
variant: [
'outline',
'subtle'
],
class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-inverted'
},
{
color: 'neutral',
highlight: true,
class: 'ring ring-inset ring-inverted'
},
{
orientation: 'horizontal',
decrement: false,
class: 'text-start'
},
{
decrement: true,
size: 'xs',
class: 'ps-7'
},
{
decrement: true,
size: 'sm',
class: 'ps-8'
},
{
decrement: true,
size: 'md',
class: 'ps-9'
},
{
decrement: true,
size: 'lg',
class: 'ps-10'
},
{
decrement: true,
size: 'xl',
class: 'ps-11'
},
{
increment: true,
size: 'xs',
class: 'pe-7'
},
{
increment: true,
size: 'sm',
class: 'pe-8'
},
{
increment: true,
size: 'md',
class: 'pe-9'
},
{
increment: true,
size: 'lg',
class: 'pe-10'
},
{
increment: true,
size: 'xl',
class: 'pe-11'
}
],
defaultVariants: {
size: 'md',
color: 'primary',
variant: 'outline'
}
}
}
})
]
})
Some colors in compoundVariants are omitted for readability. Check out the source code on GitHub.