Skip to content

Form input

A form input with :focus, :disabled, :invalid, :placeholder, and :read-only styling embedded inside variant expansions. Use this pattern when state pseudo-classes are part of the component's vocabulary.

Authoring

ts
// recipes/form-input.config.ts
import { defineComponent } from 'varia'

export default defineComponent('form-input', {
  base: 'block w-full rounded-md border bg-white px-3 py-2 text-base shadow-sm placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-offset-1 disabled:bg-gray-50 disabled:text-gray-500 disabled:cursor-not-allowed',
  variants: {
    state: {
      default: 'border-gray-300 focus:border-blue-500 focus:ring-blue-500',
      error: 'border-red-500 text-red-700 placeholder:text-red-300 focus:border-red-500 focus:ring-red-500 invalid:border-red-500',
      success: 'border-emerald-500 focus:border-emerald-500 focus:ring-emerald-500',
    },
    s: {
      sm: 'px-2 py-1 text-sm',
      md: 'px-3 py-2 text-base',
      lg: 'px-4 py-3 text-lg',
    },
    readonly: 'read-only:bg-gray-50 read-only:cursor-default',
  },
})

Every state-driven style lives next to the value it modifies:

  • placeholder:text-gray-400 in base styles the placeholder uniformly.
  • invalid:border-red-500 only inside the error state expansion. The consumer opts in by writing form-input-state-error.
  • read-only: utilities only emit when the consumer adds form-input-readonly to the element.

Live preview

Consumption

html
<input class="form-input form-input-state-default form-input-s-md" />

<input class="form-input form-input-state-error form-input-s-md"
       aria-invalid="true" />

<input class="form-input form-input-state-default form-input-s-lg form-input-readonly"
       readonly value="cannot edit" />

<input class="form-input form-input-state-default form-input-s-md" disabled />

Generated class names

ClassPurpose
form-inputBase input styling, including :focus, :disabled, ::placeholder
form-input-state-default / -error / -successVisual mode
form-input-s-sm / -md / -lgSize
form-input-readonlyToggles :read-only styling

Released under the MIT License.