Morphos
Inputs

Input

A primitive text input component with support for controlled and uncontrolled usage.

Interactive example

Open in Storybook

Installation

npm install @morphos/inputs
pnpm add @morphos/inputs
yarn add @morphos/inputs
bun add @morphos/inputs

Import

import { Input } from '@morphos/inputs'

Usage

@Component()
class MyComponent extends StatefulComponent {
  @State() name = ''

  render() {
    return (
      <Input
        type="text"
        placeholder="Enter your name"
        value={this.name}
        onInput={(value) => (this.name = value)}
      />
    )
  }
}

Uncontrolled

@Component()
class MyComponent extends StatefulComponent {
  render() {
    return (
      <Input
        type="text"
        defaultValue="Initial value"
        name="username"
      />
    )
  }
}

With validation state

@Component()
class MyComponent extends StatefulComponent {
  @State() email = ''
  @State() isInvalid = false

  validate() {
    this.isInvalid = !this.email.includes('@')
  }

  render() {
    return (
      <Input
        type="email"
        value={this.email}
        invalid={this.isInvalid}
        aria-describedby="email-error"
        onInput={(value) => (this.email = value)}
        onBlur={() => this.validate()}
      />
    )
  }
}

Props — Input

PropTypeDefaultDescription
type"text" | "email" | "password" | "number" | "search" | "tel" | "url""text"HTML input type
valuestring—Controlled value
defaultValuestring—Uncontrolled initial value
placeholderstring—Placeholder text shown when empty
disabledboolean—Disables the input
readonlyboolean—Makes the input read-only
requiredboolean—Marks the input as required
invalidboolean—Marks the input as invalid
namestring—Form field name for submission
autoCompletestring—HTML autocomplete attribute
maxLengthnumber—Maximum number of characters
minLengthnumber—Minimum number of characters
onInput(value: string, event: Event) => void—Fires on every keystroke
onChange(value: string, event: Event) => void—Fires when the value is committed
onFocus(event: FocusEvent) => void—Fires when the input gains focus
onBlur(event: FocusEvent) => void—Fires when the input loses focus
classstring—Additional CSS classes
idstring—HTML id attribute
aria-labelstring—Accessible label when no visible label is present
aria-labelledbystring—ID of an element that labels the input
aria-describedbystring—ID of an element that describes the input

data-* attributes

AttributeElementWhen present
data-disabledRootdisabled prop is true
data-invalidRootinvalid prop is true
data-focusedRootThe input currently has focus

Accessibility

The Input component renders a native <input> element, inheriting full browser accessibility support. When invalid is true, the component sets aria-invalid="true" on the element, and when required is true it sets aria-required="true", so screen readers announce those states. Pair invalid with aria-describedby pointing to a visible error message for the best experience.

For complete accessible form fields — with a label, description, and error message — pair Input with the Field compound component (FieldLabel, FieldDescription, FieldError), which wires up aria-describedby for you.

Styling example

.morphos-input[data-focused] {
  outline: none;
  border-color: var(--morphos-color-accent);
  box-shadow: var(--morphos-focus-ring);
}

.morphos-input[data-invalid] {
  border-color: var(--morphos-color-danger);
}

.morphos-input[data-disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

On this page