InputNumber

An input for numerical values with a customizable range.

Usage

Use the v-model directive to control the value of the InputNumber.

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <PInputNumber v-model="value" />
</template>

Use the default-value prop to set the initial value when you do not need to control its state.

<template>
  <PInputNumber :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.

Min / Max

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>
  <PInputNumber v-model="value" :min="0" :max="10" />
</template>

Step

Use the step prop to set the step value of the InputNumber.

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <PInputNumber v-model="value" :step="2" />
</template>

Orientation

Use the orientation prop to change the orientation of the InputNumber.

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <PInputNumber v-model="value" orientation="vertical" />
</template>

Placeholder

Use the placeholder prop to set a placeholder text.

<template>
  <PInputNumber placeholder="Enter a number" />
</template>

Color

Use the color prop to change the ring color when the InputNumber is focused.

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <PInputNumber v-model="value" color="neutral" highlight />
</template>

Variant

Use the variant prop to change the variant of the InputNumber.

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <PInputNumber v-model="value" variant="subtle" color="neutral" />
</template>

Size

Use the size prop to change the size of the InputNumber.

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <PInputNumber v-model="value" size="xl" />
</template>

Disabled

Use the disabled prop to disable the InputNumber.

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <PInputNumber v-model="value" disabled />
</template>

Increment / Decrement

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>
  <PInputNumber
    v-model="value"
    :increment="{
      color: 'neutral',
      variant: 'solid',
      size: 'xs'
    }"
    :decrement="{
      color: 'neutral',
      variant: 'solid',
      size: 'xs'
    }"
  />
</template>

Increment / Decrement Icons

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>
  <PInputNumber
    v-model="value"
    increment-icon="i-lucide:arrow-right"
    decrement-icon="i-lucide:arrow-left"
  />
</template>

Examples

With decimal format

Use the format-options prop to customize the format of the value.

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

const value = ref(5);
</script>

<template>
  <PInputNumber
    v-model="value"
    :format-options="{
      signDisplay: 'exceptZero',
      minimumFractionDigits: 1,
    }"
  />
</template>

With percentage format

Use the format-options prop with style: 'percent' to customize the format of the value.

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

const value = ref(0.05);
</script>

<template>
  <PInputNumber
    v-model="value"
    :step="0.01"
    :format-options="{
      style: 'percent',
    }"
  />
</template>

With currency format

Use the format-options prop with style: 'currency' to customize the format of the value.

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

const value = ref(1500);
</script>

<template>
  <PInputNumber
    v-model="value"
    :format-options="{
      style: 'currency',
      currency: 'EUR',
      currencyDisplay: 'code',
      currencySign: 'accounting',
    }"
  />
</template>

Within a FormField

You can use the InputNumber within a FormField component to display a label, help text, required indicator, etc.

Specify number of attempts
<script setup lang="ts">
import { ref } from 'vue';

const retries = ref(0);
</script>

<template>
  <PFormField
    label="Retries"
    help="Specify number of attempts"
    required
  >
    <PInputNumber
      v-model="retries"
      placeholder="Enter retries"
    />
  </PFormField>
</template>

With slots

Use the #increment and #decrement slots to customize the buttons.

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

const value = ref(5);
</script>

<template>
  <PInputNumber v-model="value">
    <template #decrement>
      <PButton
        size="xs"
        icon="i-lucide:minus"
      />
    </template>

    <template #increment>
      <PButton
        size="xs"
        icon="i-lucide:plus"
      />
    </template>
  </PInputNumber>
</template>

API

Props

Prop Default Type
This component also supports all native <input> HTML attributes.

Slots

Slot Type

Emits

Event Type

Expose

When accessing the component via a template ref, you can use the following:

NameType
inputRefRef<HTMLInputElement | null>

Theme

We use unocss-variants to customize the theme. Read more about it in the theming guide.

Below is the theme configuration skeleton for the PInputNumber. Since the component is provided unstyled by default, you will need to fill in these values to apply your own custom look and feel. If you prefer to use our pre-built, opinionated styling, you can instead use our UnoCSS preset, this docs is using it as well.

app.config.ts
export default defineAppConfig({
  pohon: {
    inputNumber: {
      slots: {
        root: '',
        base: '',
        increment: '',
        decrement: ''
      },
      variants: {
        fieldGroup: {
          horizontal: {
            root: '',
            base: ''
          },
          vertical: {
            root: '',
            base: ''
          }
        },
        color: {
          primary: '',
          secondary: '',
          success: '',
          info: '',
          warning: '',
          error: '',
          neutral: ''
        },
        size: {
          xs: '',
          sm: '',
          md: '',
          lg: '',
          xl: ''
        },
        variant: {
          outline: '',
          soft: '',
          subtle: '',
          ghost: '',
          none: ''
        },
        disabled: {
          true: {
            increment: '',
            decrement: ''
          }
        },
        orientation: {
          horizontal: {
            base: '',
            increment: '',
            decrement: ''
          },
          vertical: {
            increment: '',
            decrement: ''
          }
        },
        highlight: {
          true: ''
        },
        increment: {
          false: ''
        },
        decrement: {
          false: ''
        }
      },
      compoundVariants: [],
      defaultVariants: {
        size: 'md',
        color: 'primary',
        variant: 'outline'
      }
    }
  }
};
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import pohon from 'pohon-ui/vite'

export default defineAppConfig({
  pohon: {
    inputNumber: {
      slots: {
        root: '',
        base: '',
        increment: '',
        decrement: ''
      },
      variants: {
        fieldGroup: {
          horizontal: {
            root: '',
            base: ''
          },
          vertical: {
            root: '',
            base: ''
          }
        },
        color: {
          primary: '',
          secondary: '',
          success: '',
          info: '',
          warning: '',
          error: '',
          neutral: ''
        },
        size: {
          xs: '',
          sm: '',
          md: '',
          lg: '',
          xl: ''
        },
        variant: {
          outline: '',
          soft: '',
          subtle: '',
          ghost: '',
          none: ''
        },
        disabled: {
          true: {
            increment: '',
            decrement: ''
          }
        },
        orientation: {
          horizontal: {
            base: '',
            increment: '',
            decrement: ''
          },
          vertical: {
            increment: '',
            decrement: ''
          }
        },
        highlight: {
          true: ''
        },
        increment: {
          false: ''
        },
        decrement: {
          false: ''
        }
      },
      compoundVariants: [],
      defaultVariants: {
        size: 'md',
        color: 'primary',
        variant: 'outline'
      }
    }
  }
};

Akar

With Pohon UI, you can achieve similar component functionality with less code and effort, as it comes with built-in styles mechanism and behaviors that are optimized for common use cases. Since it's using unocss-variants it adds a runtime cost, but it can be worth it if you prioritize development speed and ease of use over fine-grained control.

If this is a deal breaker for you, you can always stick to using Akar and build your own custom components on top of it.

Changelog

No recent changes