Input

The Input component covers the standard HTML input types, plus textarea. It takes its size, variant and shape from the Form or Fieldset around it.

About

There is no separate textarea component: pass type="textarea" and the Input renders one. The label, the helper text and the aria-describedby link between them are wired up for you, and the styling comes from the Form or Fieldset around the field.

Example

Here's a basic example of the Input component in action:

Svelte
<script>
  import { Input } from "theui-svelte";
</script>

<Input placeholder="Type your full name">Name</Input>

Input Type

The Input component supports various input types, making it a flexible solution for different use cases. Whether you need a standard text field, a password input, or a date picker, this component adapts to your needs. To specify the type of input, use the type prop. Here's an example:

Svelte
<Input type="text" name="username" placeholder="Enter your username">Username</Input>
<Input type="email" name="email" placeholder="Enter your email">Email</Input>
<Input type="password" name="password" placeholder="Enter your password">Password</Input>
<Input type="date" name="dob">Date of birth</Input>
<Input type="url" name="url" placeholder="Enter your profile URL">URL</Input>
<Input type="number" name="days" placeholder="Enter numbers">Number of days</Input>

Other available input types are: datetime-local, month, tel, time, week, search, textarea.

Textarea

When the type prop is set to "textarea", the Input component renders a <textarea> instead of a standard input field. By default, the textarea has 3 rows, but you can customize it using the rows attribute.

Svelte
<Input ... type="textarea">Your message</Input>

Default Value

The value prop allows you to set a default value for the input field or textarea. This is useful when you want the input to start with a predefined value, such as prefilled user data, placeholders for editing forms, or default selections.

The value prop work for all the input types including textarea. It is bindable, so use bind:value to read what the user types.

Svelte
<Input ... type="text" value="john_doe">Username</Input>
<Input ... type="textarea" value="A passionate developer who loves coding.">About you</Input>

<!-- Two-way binding -->
<script>
  let username = $state("john_doe");
</script>
<Input ... bind:value={username}>Username</Input>

Input Variant

The variant prop allows you to control the visual style of the input field. There are two available variants:

  • bordered(default): Displays the input with a visible border, making it distinct and clearly separated from the background.
  • flat: drops the border and keeps only the bottom rule.

This prop helps you match the input style with your overall UI theme.

Svelte
<Input ... variant="bordered">Username</Input>
<Input ... variant="flat">Email</Input>

Using flat is great for modern, clean designs, while bordered ensures clear separation and visibility.

Label

Labels help users understand the purpose of an input field. The Input component allows you to define labels in two ways: by passing plain text or using a mix of elements inside the component.

Adding a Label

To add a label, simply place text or elements inside the Input component. This can be a simple text label or a combination of icons, tooltips, or other elements. By default, the label appears above the input field.

Svelte
<!-- Simple text label -->
<Input name="username">Username</Input>

<!-- Label with multiple items -->
<Input name="password" type="password">
  🔒 Password
  <HelperText>Password must be 10 characters long</HelperText>
</Input>

Helper Text

Use the helperText prop to show extra information below the input, like a hint or a format requirement. It accepts a string or a snippet. The helper text is linked to the input with aria-describedby, so screen readers read it along with the label. A string renders as plain text, so use the snippet for markup.

Password must be 10 characters long
Svelte
<!-- String -->
<Input name="password" type="password" helperText="Password must be 10 characters long">Password</Input>

<!-- Snippet -->
<Input name="password" type="password">
  Password
  {#snippet helperText()}
    Must be <b>10 characters</b> long
  {/snippet}
</Input>

Floating Labels

With floatingLabel the label starts inside the field and moves up to the top edge once the field has focus or content.

The floating label works with both the "bordered" and "flat" input variants. However, it is enabled by default when the variant is set to "flat", unless explicitly disabled (this also applies to a flat Input inside a bordered Form or Fieldset). For the "bordered" variant, you must enable it manually by adding the floatingLabel prop.

Svelte
<Input ... variant="bordered" floatingLabel>Name</Input>
<Input ... variant="flat" floatingLabel>Name</Input>

Sizing

The size prop controls the input field's size and supports "sm", "md", "lg", and "xl". The default is "md". Adjusting this prop allows you to customize the input's appearance to fit different design needs.

Svelte
<Input ... size="sm">Small</Input>
<Input ... size="md">Medium (Default)</Input>
<Input ... size="lg">Large</Input>
<Input ... size="xl">Extra Large</Input>

Rounded Input

The rounded prop controls the roundness of the input's corners, allowing for different visual styles. Available values are "none", "sm", "md", "lg", "xl", "2xl", and "full", with "md" as the default. The "flat" variant has no rounded corners. Use this prop to adjust the input's appearance, from sharp edges to fully rounded corners, depending on your design needs.

Svelte
<Input ... rounded="none">Rounded none</Input>
<Input ... rounded="sm">Rounded small</Input>
<Input ... rounded="md">Rounded medium</Input>
<Input ... rounded="lg">Rounded large</Input>
<Input ... rounded="xl">Rounded extra large</Input>
<Input ... rounded="full">Rounded full</Input>

Animation Speed

The animationSpeed prop controls the speed of input animations, allowing for smooth transitions and interactions. Available values are "none", "slower", "slow", "normal", "fast", and "faster", with "normal" as the default.

Svelte
<Input ... animationSpeed="slower">Animation slower</Input>
<Input ... animationSpeed="slow">Animation slow</Input>
<Input ... animationSpeed="normal">Animation normal</Input>
<Input ... animationSpeed="fast">Animation fast</Input>
<Input ... animationSpeed="faster">Animation faster</Input>
<Input ... animationSpeed="none">Animation none</Input>

Customization

These props cover the different parts of the field:

  • wrapperClasses: Applied to the outermost wrapper <div>, allowing full control over the container's styling.
  • labelClasses: Applied directly to the label, making it easy to adjust typography, spacing, or colors.
  • class attribute: This is the standard HTML class attribute applied to the input element itself, giving you direct control over its styling.

By combining these options, you can fully customize the input's layout and appearance while keeping its functionality intact.

Svelte
<Input
  name="myInput"
  placeholder="Enter username"
  wrapperClasses="flex-row items-center gap-16"
  labelClasses="text-xl text-blue-500"
  class="text-blue-500 focus:ring-blue-500 focus:border-blue-500"
>USERNAME</Input>

Reset Styles

Set the reset prop to true to remove the default styles of the input and its label, so only your own classes apply. This is useful when the input must follow a completely different design. The default is false.

Svelte
<Input name="myInput" reset={true} class="w-full border-2 border-dashed border-gray-400 p-2" wrapperClasses="flex flex-col gap-1">
  Custom input
</Input>

Inherited Settings

When an Input is placed inside a Form or Fieldset, it takes variant, floatingLabel, size, rounded, animationSpeed, labelClasses and reset from the closest one (the Fieldset first, then the Form). Any of these props set on the Input itself override the inherited value.

Accessibility

The <label> is tied to the field with for and id, so a screen reader reads the label together with the field. When there is helper text, aria-describedby links it as well, so it is read out too. The same wiring applies whether the field is a text input or a textarea.

Configuration