Skip to content

Input Number

🌏 Translated with the assistance of DeepSeek and ChatGPT

A dedicated input box for entering numbers. Apart from that, it is very similar to Input and has most of Input's features.

Basic Usage

This component is used for numeric input. Pass in modelValue to enter controlled mode. If not passed or set to undefined, it is in uncontrolled mode. In this case, you can use the defaultValue property as the default value.

<template>
	<px-space>
		<px-input-number placeholder="Please input number" v-model="input"></px-input-number>
		<px-input-number placeholder="Please input number" :default-value="0"></px-input-number>
	</px-space>
</template>

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

const input = ref(47)
</script>

<style lang="css" scoped>
.px-input-number {
	width: 320px;
}
</style>

Value Range

Set the value range using the max and min properties. Both ends are inclusive.

<template>
	<px-input-number
		placeholder="Please input number"
		v-model="input"
		:min="-114"
		:max="514"
	></px-input-number>
</template>

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

const input = ref()
</script>

<style lang="css" scoped>
.px-input-number {
	width: 320px;
}
</style>

Step

Set the increment/decrement step using the step property. When the strickStep property is true, the value must be an integer multiple of step.

<template>
	<px-space direction="vertical">
		<px-input-number
			placeholder="Please input number"
			v-model="input1"
			:step="2"
			:min="-13"
			:max="23"
		></px-input-number>
		<px-input-number
			placeholder="Please input number"
			v-model="input2"
			:step="2"
			strick-step
			:min="-13"
			:max="23"
		></px-input-number>
	</px-space>
</template>

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

const input1 = ref(0)
const input2 = ref(0)
</script>

<style lang="css" scoped>
.px-input-number {
	width: 320px;
}
</style>

Precision

Set the precision using the precision property, which specifies the number of decimal places.

<template>
	<px-input-number
		placeholder="Please input number"
		v-model="input"
		:precision="4"
	></px-input-number>
</template>

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

const input = ref(1919.81)
</script>

<style lang="css" scoped>
.px-input-number {
	width: 320px;
}
</style>

Custom Template

Set the number display template by passing the format, allowInput, and parse properties together. For example, you can display units or use thousands separators.

<template>
	<px-space direction="vertical">
		<px-input-number
			direction="vertical"
			placeholder="Please input number"
			v-model="inputUnit"
			:precision="precision"
			:format="formatUnit"
			:allow-input="allowInputUnit"
			:parse="parseUnit"
		></px-input-number>
		<px-input-number
			placeholder="Please input number"
			v-model="inputSeparator"
			:format="formatSeparator"
			:allow-input="allowInputSeparator"
			:parse="parseSeparator"
		></px-input-number>
	</px-space>
</template>

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

const inputUnit = ref(100)
const precision = ref(4)

const formatUnit = (value: number | null | undefined) => {
	if (value === undefined || value === null || isNaN(value)) {
		return ''
	}
	return value.toFixed(precision.value) + '%'
}
const reg4NumberUnit = /^[+-]?\d+(?:\.\d*)?(%)?$/
const allowInputUnit = (value: string) => {
	if (!value.length) {
		return true
	}
	return reg4NumberUnit.test(value)
}
const parseUnit = (value: string) => {
	if (!value.length) {
		return 0
	}
	return parseFloat(value)
}

function thousandSeparator(num: number): string {
	const numStr = Math.abs(num).toString()
	const [int, decimal] = numStr.split('.')

	const formattedInt = int.replace(/\B(?=(\d{3})+(?!\d))/g, ',')

	let result
	if (decimal) {
		const formattedDecimal = decimal.replace(/(\d{3})(?=\d)/g, '$1,')
		result = `${formattedInt}.${formattedDecimal}`
	} else {
		result = formattedInt
	}

	return num < 0 ? '-' + result : result
}
const inputSeparator = ref(12345.6789)

const formatSeparator = (value: number | null | undefined) => {
	if (value === undefined || value === null || isNaN(value)) {
		return ''
	}
	return thousandSeparator(value)
}
const reg4Number = /^[+-]?\d+(?:\.\d*)?$/
const allowInputSeparator = (value: string) => {
	if (!value.length) {
		return true
	}
	return reg4Number.test(value.split(',').join(''))
}
const parseSeparator = (value: string) => {
	if (!value.length) {
		return 0
	}
	return parseFloat(value.split(',').join(''))
}
</script>

<style lang="css" scoped>
.px-input-number {
	width: 320px;
}
</style>

Button Placement

The position of the increment/decrement buttons can also be configured using the buttonPlacement property.

<template>
	<px-space>
		<px-input-number
			placeholder="Please input number"
			button-placement="start"
		></px-input-number>
		<px-input-number
			placeholder="Please input number"
			button-placement="start-reverse"
		></px-input-number>
		<px-input-number placeholder="Please input number"></px-input-number>
		<px-input-number
			placeholder="Please input number"
			button-placement="end-reverse"
		></px-input-number>
		<px-input-number
			placeholder="Please input number"
			button-placement="both"
		></px-input-number>
		<px-input-number
			placeholder="Please input number"
			button-placement="both-reverse"
		></px-input-number>
	</px-space>
</template>

<style lang="css" scoped>
.px-input-number {
	width: 320px;
}
</style>

More Options

This InputNumber has most of Input component's features.

Disabled, Readonly, Loading & Clearable

Shape

Size

Slot

+
s

Composite

Status

Expose

<template>
	<px-space direction="vertical">
		<h4>Disabled, Readonly, Loading & Clearable</h4>
		<px-space>
			<px-input-number
				placeholder="Please input number"
				disabled
				:default-value="0"
			></px-input-number>
			<px-input-number
				placeholder="Please input number"
				readonly
				:default-value="0"
			></px-input-number>
			<px-input-number
				placeholder="Please input number"
				loading
				:default-value="0"
			></px-input-number>
			<px-input-number
				placeholder="Please input number"
				clearable
				:default-value="0"
			></px-input-number>
		</px-space>
		<h4>Shape</h4>
		<px-space>
			<px-input-number
				placeholder="Please input number"
				shape="round"
				:default-value="0"
			></px-input-number>
			<px-input-number placeholder="Please input number" :default-value="0"></px-input-number>
		</px-space>
		<h4>Size</h4>
		<px-space>
			<px-input-number
				placeholder="Please input number"
				size="small"
				:default-value="0"
			></px-input-number>
			<px-input-number placeholder="Please input number" :default-value="0"></px-input-number>
			<px-input-number
				placeholder="Please input number"
				size="large"
				:default-value="0"
			></px-input-number>
		</px-space>
		<h4>Slot</h4>
		<px-space>
			<px-input-number placeholder="Please input number" :default-value="1">
				<template #prefix>+</template>
				<template #suffix>s</template>
			</px-input-number>
			<px-input-number placeholder="Please input number" :default-value="0">
				<template #prepend>
					<IconBolt></IconBolt>
				</template>
			</px-input-number>
			<px-input-number placeholder="Please input number">
				<template #append>
					<IconBolt></IconBolt>
				</template>
			</px-input-number>
		</px-space>
		<h4>Composite</h4>
		<px-space>
			<px-input-group>
				<px-input-group-label>
					<IconBolt></IconBolt>
				</px-input-group-label>
				<px-input-number placeholder="Please input number" :default-value="0">
				</px-input-number>
				<px-button>Confirm</px-button>
			</px-input-group>
		</px-space>
		<h4>Status</h4>
		<px-space>
			<px-input-number placeholder="Please input number"> </px-input-number>
			<px-input-number placeholder="Please input number" status="success"> </px-input-number>
			<px-input-number placeholder="Please input number" status="warning"> </px-input-number>
			<px-input-number placeholder="Please input number" status="error"> </px-input-number>
		</px-space>
		<h4>Expose</h4>
		<px-space direction="vertical">
			<px-space>
				<px-button theme="info" @click="focusHandler">Focus</px-button>
				<px-button theme="info" @click="blurHandler">Blur</px-button>
				<px-button theme="info" @click="selectHandler">Select</px-button>
				<px-button theme="warning" @click="clearHandler">Clear</px-button>
			</px-space>
			<px-input-number placeholder="Please input" ref="inputNumberRef"></px-input-number>
		</px-space>
	</px-space>
</template>

<script setup lang="ts">
import { IconBolt } from '@pixelium/web-vue/icon-hn/es'
import { ref } from 'vue'
import { InputNumber } from '@pixelium/web-vue'

// If on-demand import
// import { InputNumber } from '@pixelium/web-vue/es'

const inputNumberRef = ref<InstanceType<typeof InputNumber>>(null)

const focusHandler = () => {
	inputNumberRef.value?.focus()
}
const blurHandler = () => {
	inputNumberRef.value?.blur()
}
const clearHandler = () => {
	inputNumberRef.value?.clear()
}
const selectHandler = () => {
	inputNumberRef.value?.select()
}
</script>

<style lang="css" scoped>
.px-input-number {
	width: 320px;
}
</style>

API

InputNumberProps

AttributeTypeOptionalDefaultDescriptionVersion
modelValuestring | nullTrueValue of the number input (controlled mode), supports v-model.0.0.2
defaultValuestring | nullTrueDefault value of the number input (uncontrolled mode).0.0.2
placeholderstringTruePlaceholder text.0.0.2
disabledbooleanTruefalseWhether the input is disabled.0.0.2
readonlybooleanTruefalseWhether the input is read-only.0.0.2
maxnumberTrueNumber.MAX_SAFE_INTEGERMaximum value (inclusive).0.0.2
minnumberTrueNumber.MIN_SAFE_INTEGERMinimum value (inclusive).0.0.2
stepnumberTrue1Increment/decrement step for the spin buttons.0.0.2
precisionnumberTrueNumber of decimal places, must be an integer between 0 and 100.0.0.2
strickStepbooleanTruefalse0.0.2
format(value: number | Nullish) => stringTrueFunction to convert the numeric value to a display string.0.0.2
allowInput(value: string) => booleanTrueFunction to validate whether the typed text is allowed.0.0.2
parse(value: string) => numberTrueFunction to convert the input text to a numeric value.0.0.2
clearablebooleanTruefalseWhether to show a clear button.0.0.2
loadingbooleanTruefalseWhether to show a loading state.0.0.2
size'medium' | 'large' | 'small'True'medium'Size of the number input.0.0.2
shape'default' | 'round'True'default'Shape of the number input.0.0.2
borderRadiusNumberOrPercentage | NumberOrPercentage[]True0.0.2
buttonPlacementbooleanTrue'end'Position of the increment/decrement buttons.0.0.2
status'success' | 'warning' | 'error' | 'normal'True'normal'Form validation status.0.0.2
autofocusbooleanTruefalseNative <input> autofocus attribute.0.0.2

InputNumberEvents

EventParameterDescriptionVersion
inputvalue: number, e: EventCallback fired on input.0.0.2
update:modelValuevalue: numberCallback fired when modelValue is updated.0.0.2
changevalue: number, e: Event | undefinedCallback fired when the value changes.0.0.2
clearvalue: numberCallback fired when the clear button is clicked.0.0.2
blure: FocusEventCallback fired when the input loses focus.0.0.2
focuse: FocusEventCallback fired when the input receives focus.0.0.2

InputNumberSlots

SlotParameterDescriptionVersion
prefixPrefix content.0.0.2
suffixSuffix content.0.0.2

InputNumberExpose

AttributeTypeOptionalDefaultDescriptionVersion
focus() => voidFalseFocus the number input.0.0.2
blur() => voidFalseBlur the number input.0.0.2
clear() => voidFalseClear the number input.0.0.2
select() => voidFalseSelect all text in the number input.0.0.2

NumberOrPercentage

ts
export type NumberOrPercentage = number | `${number}%`