Skip to content

Input

🌏 Translated with the assistance of DeepSeek and ChatGPT

Enter text.

Basic Usage

You can enter text here. Pass in modelValue to enable controlled mode. If not passed or set to undefined, it will be uncontrolled mode, in which case you can use the defaultValue property as the default value.

<template>
	<px-space direction="vertical">
		<px-input placeholder="Please input" v-model="input"></px-input>
		<px-input placeholder="Please input D-mail"></px-input>
		<px-input placeholder="Please input" default-value="El Psy Kongroo"></px-input>
	</px-space>
</template>

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

const input = ref('Steins; Gate')
</script>

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

Password Input

This component can also be a password input box, just set the password property to true.

<template>
	<px-input v-model="input" placeholder="Please input password" password></px-input>
</template>

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

const input = ref('')
</script>

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

Readonly & Disabled

Set readonly for read-only, and disabled for disabled. In both cases, the internal <input> will be set to disabled. The difference is mostly in the styles.

<template>
	<px-space direction="vertical">
		<px-input readonly placeholder="Please input content"></px-input>
		<px-input disabled default-value="Some text..."></px-input>
	</px-space>
</template>

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

Clear Text

When clearable is true, a clear button will be shown when focused.

<template>
	<px-input placeholder="Please input" v-model="input" clearable></px-input>
</template>

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

const input = ref('Test')
</script>

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

Loading State

Set loading for loading state. It works the same as usual, just with an extra loading icon.

<template>
	<px-input placeholder="Please input" v-model="input" loading></px-input>
</template>

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

const input = ref('You can enter text as usual')
</script>

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

Input Size

The input box can have different sizes.

<template>
	<px-space direction="vertical">
		<px-input placeholder="Please input" size="small"></px-input>
		<px-input placeholder="Please input"></px-input>
		<px-input placeholder="Please input" size="large"></px-input>
	</px-space>
</template>

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

Rounded Borders

The input box can also have rounded borders.

Due to limited time and technical resources, custom border-radius still needs optimization, but it does not affect overall usability.

<template>
	<px-space direction="vertical">
		<px-input placeholder="Please input"></px-input>
		<px-input placeholder="Please input" shape="round"></px-input>
		<px-input placeholder="Please input" :border-radius="[20, 0]"></px-input>
	</px-space>
</template>

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

Prefix & Suffix

Add extra content to the prefix or suffix.

$
km
<template>
	<px-space direction="vertical">
		<px-input placeholder="Please input">
			<template #prefix>$</template>
		</px-input>
		<px-input placeholder="Please input">
			<template #suffix>km</template>
		</px-input>
	</px-space>
</template>

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

Composite Input

With the InputGroup component, you can combine various input controls and buttons together.

.ini
<template>
	<px-space direction="vertical">
		<px-input-group>
			<px-input-group-label>
				<IconSearch></IconSearch>
			</px-input-group-label>
			<px-input placeholder="Please input"> </px-input>
			<px-button>Search</px-button>
		</px-input-group>
		<px-input-group>
			<px-input placeholder="Please input file name"> </px-input>
			<px-input-group-label> .ini </px-input-group-label>
		</px-input-group>
		<px-input-group>
			<px-input placeholder="Please input"> </px-input>
			<px-input-number placeholder="Please input" :default-value="0"> </px-input-number>
		</px-input-group>
	</px-space>
</template>
<script setup lang="ts">
import { IconSearch } from '@pixelium/web-vue/icon-hn/es'
</script>
<style lang="css" scoped>
.px-input,
.px-input-number {
	width: 320px;
}
</style>

Character Count & Length Limit

The showCount property enables character count display, and maxLength sets the maximum length.

By default, the Input component uses str.length to calculate length, which may be inaccurate for compound characters. We recommend using grapheme-splitter to solve this issue. The countGraphemes property sets the function for counting characters, and sliceGraphemes is used to slice the string within the length limit. If only countGraphemes is provided without sliceGraphemes, the maxLength limit will not take effect.

8
8 / 20
4 / 20
<template>
	<px-space direction="vertical">
		<px-input placeholder="Please input" default-value="🎺🎸🎹🥁" show-count></px-input>
		<px-input
			placeholder="Please input"
			default-value="🎺🎸🎹🥁"
			show-count
			:max-length="20"
		></px-input>
		<px-input
			placeholder="Please input"
			default-value="🎺🎸🎹🥁"
			show-count
			:max-length="20"
			:countGraphemes="countGraphemes"
			:sliceGraphemes="sliceGraphemes"
		></px-input>
	</px-space>
</template>

<script setup lang="ts">
import GraphemeSplitter from 'grapheme-splitter'

const splitter = new GraphemeSplitter()
const countGraphemes = (val: string) => {
	return splitter.countGraphemes(val)
}
const sliceGraphemes = (val: string, limit: number) => {
	const arr = splitter.splitGraphemes(val)
	return arr.slice(0, limit).join('')
}
</script>

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

Manual Operations

The Input component exports some functions to operate on itself.

<template>
	<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 placeholder="Please input" ref="inputRef"></px-input>
	</px-space>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { Input } from '@pixelium/web-vue'

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

const inputRef = ref<InstanceType<typeof Input>>(null)

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

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

Form Validation Status

The input box supports four form validation statuses: 'normal' (default), 'success', 'warning', and 'error'.

<template>
	<px-space direction="vertical">
		<px-input placeholder="Please input"> </px-input>
		<px-input placeholder="Please input" status="success"> </px-input>
		<px-input placeholder="Please input" status="warning"> </px-input>
		<px-input placeholder="Please input" status="error"> </px-input>
	</px-space>
</template>
<style lang="css" scoped>
.px-input {
	width: 320px;
}
</style>

API

InputProps

AttributeTypeOptionalDefaultDescriptionVersion
modelValuestring | nullTrueValue of the input box (controlled mode), supports v-model.0.0.2
defaultValuestring | nullTrueDefault value of the input box (uncontrolled mode).0.0.2
placeholderstringTruePlaceholder text.0.0.2
passwordbooleanTruefalseWhether it is a password input box.0.0.2
disabledbooleanTruefalseWhether it is disabled.0.0.2
readonlybooleanTruefalseWhether it is read-only.0.0.2
clearablebooleanTruefalseWhether to show the clear button.0.0.2
loadingbooleanTruefalseWhether to show the loading state.0.0.2
size'medium' | 'large' | 'small'True'medium'Input box size.0.0.2
shape'default' | 'round'True'default'Input box shape.0.0.2
borderRadiusNumberOrPercentage | NumberOrPercentage[]TrueBorder radius, takes precedence over shape, behaves like CSS border-radius; a single value or array of length 1 → all corners; length 2 → [top left & bottom right, top right & bottom left]; length 3 → [top left, top right & bottom left, bottom right]; length 4 → applies to each corner in clockwise order.0.0.2
maxLengthnumberTrueMaximum input length.0.0.2
showCountbooleanTruefalseWhether to show character count.0.0.2
countGraphemes(value: string) => numberTrueCustom character count function. If only countGraphemes is provided without sliceGraphemes, the maxLength limit will not take effect.0.0.2
sliceGraphemes(value: string, limit: number) => stringTrueCustom function to slice the string to the specified length.0.0.2
status'success' | 'warning' | 'error' | 'normal'True'normal'Form validation status.0.0.2
autofocusbooleanTruefalseNative <input> autofocus attribute.0.0.2
nativeType'text' | 'password' | 'email' | 'tel' | 'url' | 'search'True'text'Native <input> type attribute.0.0.2

InputEvents

EventParameterDescriptionVersion
inputvalue: string, e: EventCallback when input is entered.0.0.2
update:modelValuevalue: stringCallback to update modelValue.0.0.2
changevalue: string, e: Event | undefinedCallback when input content changes.0.0.2
clearvalue: stringCallback when the clear button is clicked and content is cleared.0.0.2
blure: FocusEventCallback when the input box loses focus.0.0.2
focuse: FocusEventCallback when the input box is focused.0.0.2

InputSlots

SlotParameterDescriptionVersion
prefixPrefix content.0.0.2
suffixSuffix content.0.0.2
countinputValue: number, currentLength: number, maxLength: numberSlot for displaying character count.0.0.2

InputExpose

AttributeTypeOptionalDefaultDescriptionVersion
focus() => voidFalseFocus the current input box.0.0.2
blur() => voidFalseRemove focus from the current input box.0.0.2
clear() => voidFalseClear the current input box.0.0.2
select() => voidFalseSelect the content of the current input box.0.0.2

NumberOrPercentage

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