Primitive · 4 of 13
The multi-line sibling of InputText, but built differently: the label is in
normal flow rather than absolutely positioned, and the focus halo lives on
the wrapper via :focus-within so it surrounds the whole box.
| Prop | Type | Notes |
|---|---|---|
| id * | string | Wires label to textarea. |
| label * | string | In flow above the field, select-none. |
| placeholder * | string | 12px, nudged down with placeholder:pt-1.5. |
| modelValue | string | Emitted on change, not input — see findings. |
Note what is absent compared to InputText:
no isRequired, no isError, no
errorMessage. The textarea cannot express a validation state
at all.
The real TextField.vue, compiled and mounted. Type into the
second one — it grows. The textarea has
overflow: hidden and its height is set from
scrollHeight on every input, so it never scrolls internally.
The model updates on change, not input.
The template binds @change="$emit('update:modelValue', …)" while
the auto-resize runs on @input. So the parent's
v-model only syncs when the textarea loses focus. A form that
validates or enables its submit button as the user types will look frozen,
and a submit triggered without blurring first can read a stale value.
InputText emits on input, so the two fields behave differently
in the same form.
The auto-resize does not run on programmatic value changes.
Height is only recalculated in the @input handler. Setting
modelValue from the parent — restoring a draft, prefilling — leaves
the box at its minimum height with the content clipped, because
overflow is hidden and nothing re-measures.
No error state exists.
Unlike InputText there is no isError path, so a failed
required-message validation has nowhere to render. The consultation form
works around this by not validating the message field.
The halo is on the wrapper, and that is correct.
Because the label sits inside the same box, putting the shadow on the
textarea alone would draw a glowing rectangle underneath the label. Using
:focus-within on the container keeps the focus ring around the
whole control.