Skip to content

Input

Components to deal with accessible labelling, descriptions, errors and grouping of input elements.


vue
<template>
  <PeachyInput.Input class="text">
    <PeachyTextInput.Input
      v-model:value="input"
      placeholder="Placeholder"
      @validate="validateTextInput"
      @clear-validation="textErrors = []">
      <template #before>
        <PeachyInput.Label>
          Text input

          <WarningSvg v-if="textErrors.length" aria-hidden="true" />
        </PeachyInput.Label>

        <PeachyInput.Description>Max 5 characters.</PeachyInput.Description>
      </template>

      <template #after>
        <PeachyInput.Error v-for="(errorMessage, i) in textErrors" :key="i">
          {{ errorMessage }}
        </PeachyInput.Error>
      </template>
    </PeachyTextInput.Input>
  </PeachyInput.Input>
</template>
css
.peachy-input__label {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.peachy-input__label svg {
  height: 1.25rem;
  width: 1.25rem;
}

.peachy-input__label svg path {
  stroke: var(--error-color);
}

.peachy-input__description {
  font-size: 85%;
  width: 15rem;
  margin: 0;
  padding: 0;
  margin-top: -0.25rem;
  opacity: 0.9;
}

.peachy-input__error {
  margin: 0;
  padding: 0;
  margin-top: 0rem;
  font-size: 85%;
  width: 15rem;
}

.peachy-text-input__input[aria-invalid="true"] {
  caret-color: var(--error-color);
  border-color: var(--error-color);
}

.peachy-text-input__input[aria-invalid="true"]:not(:disabled):hover {
  border-color: var(--error-color);
}

.peachy-text-input__input[aria-invalid="true"]:focus,
.peachy-text-input__input[aria-invalid="true"]
  .peachy-text-input__input:focus-visible {
  outline: none !important;
  border-color: var(--error-color);
}

Anatomy

CHECK ANATOMY FOR EACH COMPONENT

Some of the inputs have built in labels.

vue
<template>
  <PeachyInput.Group>
    <PeachyInput.GroupLabel />

    <PeachyInput.Input>
      <PeachyInput.Label />
      <PeachyInput.Description />
      <PeachyInput.Error />
      <!-- <Component>.Input -->
    </PeachyInput.Input>
  </PeachyInput.Group>
</template>

<script lang="ts" setup>
  import { PeachyInput } from "typeach";
</script>

The Input is purely for decoration purposes, so that it can be used as a wrapper around inputs.

Styling

Due to the use of templates #before and #after to put elements inside an input, a tip is to use grid-template-areas on the wrapper element to control placement of slots inside an input.

Accessibility

Resources: A Guide To Accessible Form Validation

Validation happens when a user blurs the input to give quick feedback without interrupting them while they're in the middle of filling out the input.

Clearing validation happens once they start to re-fill the input.