Skip to content

Input ​

Input is the box you type in. On its own it is rarely what you want — a TextField wraps it with a label, a description and a validation state, and that is the shape most forms need. Reach for the input directly when you are assembling something the field does not cover.

ts
import { Input, Label, TextField } from "ropav";

Inside a field, variant and size come from the field and do not need repeating. Set them on the input only where it stands alone.

input-affixes.vue
vue
<script setup lang="ts">
import { Input, Label, TextField } from "ropav";

const sizes = ["xs", "sm", "md", "lg"] as const;
</script>

<template>
  <div class="stack">
    <TextField v-for="size in sizes" :key="size" :size="size">
      <Label class="label">{{ size }}</Label>
      <Input class="field" :placeholder="`A ${size} control`" />
    </TextField>
  </div>
</template>

<style scoped>
.stack {
  display: flex;
  flex-direction: column;
  gap: calc(var(--rp-spacing) * 4);
}

.label {
  text-transform: capitalize;
}

.field {
  width: calc(var(--rp-spacing) * 64);
}
</style>

The value belongs to the field ​

Setting value on the input takes the control away from the surrounding field: the caller owns it from then on, and without a listener to go with it the text is pinned and cannot be typed in. That is the same trap a value prop is in React, and the fix is the same — put the value on the TextField and let it flow down.

placeholder is declared here as well as on the field, so it can be set at whichever level reads better. Every other native attribute reaches the element by ordinary attribute fallthrough.

For an input with something attached to it — a currency symbol, a unit, a button — use an InputGroup, which is the same control with room at either end.

Accessibility ​

  • The input is the field as far as assistive technology is concerned: the id lands here, and a Label inside the field points at it.
  • A placeholder is not a label. It disappears when typing starts and it is not reliably announced, so a field whose only name is its placeholder has no name at all.

API ​

PropTypeDefaultDescription
fullWidthboolean—Whether the control stretches to fill its container.
placeholderstring—Placeholder shown while the control is empty. Declared so it can also be set here rather than only on the field; every other native attribute arrives by attribute fallthrough.
size"xs" | "sm" | "md" | "lg""md"How tall the control stands, matching a button of the same size. Taken from the surrounding field when unset.
valuestring—Text in the control. Set here it takes the control over from the surrounding field, so the caller owns the value even inside a TextField — exactly as a value prop does in React. Without a listener to go with it the text is pinned.
variant"primary" | "secondary""primary"Visual variant. Taken from the surrounding field when unset.
EventPayload
changestring
update:valuestring