- Remove ScrubInput aliases, app wrappers, test hooks, and translated legacy references - Share a Tailwind NumberField demo between Storybook and VitePress - Generate component API tables from Vue metadata and type-check examples with Twoslash - Upgrade the docs stack to VitePress 2
2.5 KiB
| title | description |
|---|---|
| NumberField | Headless numeric field primitives with scrubbing, expressions, and keyboard stepping. |
NumberField
The NumberField family provides a headless numeric control with pointer scrubbing, mixed values, keyboard stepping, safe arithmetic expressions, units, trailing actions, and binding-aware state.
Anatomy
NumberFieldRoot— renderless state and interaction ownerNumberFieldLeading— leading label or iconNumberFieldValue— non-editing valueNumberFieldInput— editing input with spinbutton semanticsNumberFieldUnit— unit textNumberFieldTrailing— trailing action areaNumberFieldMenu— field menu area
Root slot
The default slot receives modelValue, displayValue, draftValue, placeholder, all state
booleans, state, actions, and attrs. Bind attrs to the focusable outer element. It contains
the canonical spinbutton ARIA contract, keyboard/focus handlers, and data-editing,
data-scrubbing, data-mixed, data-disabled, and data-bound attributes.
Expressions and keyboard
Committed input accepts absolute arithmetic such as 12*8+4, relative operations such as
+10, -4, *2, and /3, and percentages such as 50% when max is finite. The parser only
accepts numbers, parentheses, and + - * /; it never evaluates JavaScript.
Arrow keys step by step. Shift multiplies the step by 10 and Alt multiplies it by 0.1. Enter
commits and Escape restores the interaction-start value.
Example
<script setup lang="ts">
import { ref } from 'vue'
import {
NumberFieldInput,
NumberFieldLeading,
NumberFieldRoot,
NumberFieldUnit,
NumberFieldValue
} from '@open-pencil/vue'
const width = ref(120)
// ^?
</script>
<template>
<NumberFieldRoot
v-slot="{ attrs, editing, actions }"
v-model="width"
:min="0"
:max="1000"
aria-label="Width"
>
<div v-bind="attrs" @pointerdown="!editing && actions.startScrub($event)">
<NumberFieldLeading>W</NumberFieldLeading>
<NumberFieldInput />
<NumberFieldValue />
<NumberFieldUnit>px</NumberFieldUnit>
</div>
</NumberFieldRoot>
</template>
Generated API reference
The following tables are extracted from the Vue source and its JSDoc during the documentation build.