Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelog App ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip
ARC UI ARC Radiant Components
v4.2 Docs Components Tokens Synthesizer
Getting StartedFrameworksServer Rendering Design TokensThemingTheme SynthesizerTypographyUtilities All ComponentsAccessibilityBrowser SupportChangelogContributingStats App ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip

Input

Versatile form control supporting single-line text, email, password, and multiline textarea modes with built-in label, placeholder, and validation states. Pairs with Form for complete data-entry workflows.

Components Input
input hybrid
<arc-input>

Overview

Input is the foundational text-entry component in ARC UI. It wraps a native `<input>` or `<textarea>` element with consistent styling, an integrated label, placeholder support, and validation feedback — all managed through a single declarative API. Use Input whenever you need to collect freeform text from a user: names, emails, passwords, search queries, or longer messages. The `multiline` prop switches the underlying element to a `<textarea>` for multi-row content without changing the component interface, so forms stay uniform whether a field needs one line or twenty. Input supports `prefix` and `suffix` slots for placing icons, labels, or other inline elements inside the field box. This is useful for search icons, unit labels, clear buttons, or any adornment that should appear visually attached to the input. Input is designed to work seamlessly with the Form component. Wrap a set of Inputs inside a Form to get coordinated validation, submission handling, and error summary. Each Input exposes `name`, `required`, and `type` props that Form reads automatically, so you rarely need extra wiring.

Guidelines

When to use

  • Always provide a `label` so the field is accessible to screen readers
  • Use the most specific `type` available (e.g. `email` for email addresses) to trigger the correct mobile keyboard
  • Set `placeholder` to show an example value, not as a replacement for the label
  • Use `multiline` for any field that may need more than one line of text
  • Use the `prefix` slot for search icons or currency symbols that contextualise the input
  • Use the `suffix` slot for unit labels, clear buttons, or status indicators
  • Group related Inputs inside a Form component for coordinated validation
  • Mark required fields with the `required` prop so validation is handled automatically

When not to use

  • Do not use placeholder text as the only label — it disappears on focus and fails accessibility
  • Do not set `type="password"` on a multiline input — passwords are always single-line
  • Do not disable inputs without explaining to the user why the field is unavailable
  • Avoid overriding the built-in validation styling with custom CSS — use design tokens instead
  • Do not use Input for structured data like dates or selects — use DatePicker or Select instead

Features

  • Integrated label rendered above the field with automatic `for`/`id` association
  • Multiple input types: text, email, tel, url, and password
  • Multiline mode converts to a resizable textarea with a single boolean prop
  • Prefix and suffix slots for icons or inline adornments inside the field box
  • Placeholder text with accessible contrast ratios
  • Required-field indicator with built-in validation message
  • Disabled state that greys out the field and blocks interaction
  • Keyboard-accessible with visible focus ring following design tokens
  • Pairs with Form for coordinated validation and submission

Preview

Usage

Layout and styling work without JavaScript via the HTML/CSS versions. Interactive features like events and state management require the Web Component or a framework wrapper.

<!-- Basic form fields -->
<div style="display:flex; flex-direction:column; width:100%; max-width:400px; gap:16px;">
  <arc-input label="Name" name="name" placeholder="Jane Doe" required></arc-input>
  <arc-input label="Email" name="email" type="email" placeholder="[email protected]" required></arc-input>
  <arc-input label="Message" name="message" multiline placeholder="How can we help?" required></arc-input>
</div>

<!-- With prefix icon (search) -->
<arc-input label="Search" placeholder="Search...">
  <svg slot="prefix" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20"><path fill-rule="evenodd" d="M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z" clip-rule="evenodd"/></svg>
</arc-input>
import { Input } from '@arclux/arc-ui-react';

export default function Example() {
  return (
    <>
      <div style={{ display: 'flex', flexDirection: 'column', width: '100%', maxWidth: 400, gap: 16 }}>
        <Input label="Name" name="name" placeholder="Jane Doe" required />
        <Input label="Email" name="email" type="email" placeholder="[email protected]" required />
        <Input label="Message" name="message" multiline placeholder="How can we help?" required />
      </div>

      {/* With prefix icon */}
      <Input label="Search" placeholder="Search...">
        <svg slot="prefix" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20"><path fillRule="evenodd" d="M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z" clipRule="evenodd"/></svg>
      </Input>
    </>
  );
}
<script setup>
import { Input } from '@arclux/arc-ui-vue';
</script>

<template>
  <div style="display:flex; flex-direction:column; width:100%; max-width:400px; gap:16px;">
    <Input label="Name" name="name" placeholder="Jane Doe" required />
    <Input label="Email" name="email" type="email" placeholder="[email protected]" required />
    <Input label="Message" name="message" multiline placeholder="How can we help?" required />
  </div>
</template>
<script>
  import { Input } from '@arclux/arc-ui-svelte';
</script>

<div style="display:flex; flex-direction:column; width:100%; max-width:400px; gap:16px;">
  <Input label="Name" name="name" placeholder="Jane Doe" required />
  <Input label="Email" name="email" type="email" placeholder="[email protected]" required />
  <Input label="Message" name="message" multiline placeholder="How can we help?" required />
</div>
import { Component } from '@angular/core';
import { Input } from '@arclux/arc-ui-angular';

@Component({
  imports: [Input],
  template: `
    <div style="display:flex; flex-direction:column; width:100%; max-width:400px; gap:16px;">
      <arc-input label="Name" name="name" placeholder="Jane Doe" required></arc-input>
      <arc-input label="Email" name="email" type="email" placeholder="[email protected]" required></arc-input>
      <arc-input label="Message" name="message" multiline placeholder="How can we help?" required></arc-input>
    </div>
  `,
})
export class ContactFormComponent {}
import { Input } from '@arclux/arc-ui-solid';

export default function Example() {
  return (
    <div style={{ display: 'flex', 'flex-direction': 'column', width: '100%', 'max-width': '400px', gap: '16px' }}>
      <Input label="Name" name="name" placeholder="Jane Doe" required />
      <Input label="Email" name="email" type="email" placeholder="[email protected]" required />
      <Input label="Message" name="message" multiline placeholder="How can we help?" required />
    </div>
  );
}
import { Input } from '@arclux/arc-ui-preact';

export default function Example() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', width: '100%', maxWidth: 400, gap: 16 }}>
      <Input label="Name" name="name" placeholder="Jane Doe" required />
      <Input label="Email" name="email" type="email" placeholder="[email protected]" required />
      <Input label="Message" name="message" multiline placeholder="How can we help?" required />
    </div>
  );
}
<div style="display:flex; flex-direction:column; width:100%; max-width:400px; gap:16px;">
  <arc-input label="Name" name="name" placeholder="Jane Doe" required></arc-input>
  <arc-input label="Email" name="email" type="email" placeholder="[email protected]" required></arc-input>
  <arc-input label="Message" name="message" multiline placeholder="How can we help?" required></arc-input>
</div>
<!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-input — self-contained, no external CSS needed -->
<div class="arc-input">

</div>

API

autoValidates boolean false
Runs its own constraint logic — owns the whole validity flag set.
name string ''
The name attribute sent with form data on submission. Also used by the Form component to track field state and validation.
label string ''
Visible label rendered above the input. Automatically associated with the field via a generated id, ensuring screen readers announce it correctly.
placeholder string ''
Hint text displayed inside the field when it is empty. Use it to show an example value -- never as a substitute for the label.
value string ''
The current value of the input. Can be set programmatically to pre-fill the field or used for controlled-component patterns. Updated internally on each keystroke.
disabled boolean false
Prevents user interaction and applies a muted visual treatment. The field value is excluded from form submission when disabled.
error string ''
Error message displayed below the input. When set, the input border turns red and the error text appears.
rows number 5
Number of visible text rows when multiline is true. Controls the initial height of the textarea. Ignored for single-line inputs.
type 'text' | 'email' | 'tel' | 'url' | 'password' 'text'
The HTML input type. Controls browser validation behavior and which virtual keyboard appears on mobile devices. Ignored when multiline is true.
multiline boolean false
When true, renders a <textarea> instead of an <input>, allowing multi-row text entry. The textarea is vertically resizable by default.
required boolean false
Marks the field as required. Displays a required indicator next to the label and triggers native constraint validation on form submission.
readonly boolean false
Prevents the user from editing the value while keeping the field focusable, and the value is still submitted with the form.
size 'sm' | 'md' | 'lg' 'md'
Controls the input size. Options: 'sm', 'md', 'lg'.
formAssociated boolean true
properties object { // flag(), unlike `disabled`. The exclusion in props.js is specifically // about form-associated *platform* semantics: a `disabled` content // attribute that is merely present makes the element actually disabled // per the HTML spec, and formDisabledCallback assigns the property back, // so no converter can win. Neither of these is platform-mapped — // `required` is enforced by _computeValidity() below and `readonly` by // each component's own interaction handlers — so the stock converter buys // nothing here and costs the usual bug: `required="false"` read as true, // blocking submission of a form the author meant to leave optional. // Finding #48's shape, across all 26 form controls at once. required: flag(false), readonly: flag(false), }
Lit merges static properties up the prototype chain, so every consumer gets these without declaring them. required participates in constraint validation below; readonly reflects for styling and is enforced by each component's interaction handlers (the mixin can't know which gestures mutate state).
form
validity
validationMessage

Methods

checkValidity() boolean
Whether the control currently satisfies its constraints, per the native constraint-validation API. Fires invalid on the element when it does not, and reports nothing to the user.
reportValidity() boolean
As checkValidity(), but also shows the browser's validation message against the control when it fails.

Events

arc-input detail: { value: string }
Fired on each keystroke with { value } detail
arc-change detail: { value: string }
Fired on blur when value has changed

See Also