Close menu

Pattern Library

Input Group (Prefix & Suffix)

Window sizes

Input Group

A wrapper that combines a text input with one or both of a prefix and suffix element. Supports validation states and width modifiers. Follows USWDS input group patterns.

Props

Prop Default Description
error Error message text; applies the error styling to the group
success Set to "true" to apply the success styling to the group
width Width modifier for the group: 2xs, xs, sm, md, lg, xl, 2xl
class Additional CSS classes for the input group wrapper

Slots

Slot Description
(default) A c-input-prefix and/or c-input-suffix wrapping a c-text-input

Example Usage

Currency Input (Dollar)

<c-label id="price-usd" label="Price" hint="Enter price in US dollars." />
<c-input-group>
    <c-input-prefix>$</c-input-prefix>
    <c-text-input id="price-usd" name="price_usd" type="text" inputmode="numeric" />
    <c-input-suffix>USD</c-input-suffix>
</c-input-group>

Currency Input (Euro)

<c-label id="price-eur" label="Price" hint="Enter price in euros." />
<c-input-group>
    <c-input-prefix>€</c-input-prefix>
    <c-text-input id="price-eur" name="price_eur" type="text" inputmode="numeric" />
    <c-input-suffix>EUR</c-input-suffix>
</c-input-group>

Temperature

<c-label id="temperature" label="Temperature" hint="Enter temperature." />
<c-input-group>
    <c-input-prefix>From</c-input-prefix>
    <c-text-input id="temperature" name="temperature" type="text" inputmode="numeric" />
    <c-input-suffix>°F</c-input-suffix>
</c-input-group>

Discount Percentage

<c-label id="discount" label="Discount" hint="Enter discount amount." />
<c-input-group>
    <c-input-prefix>-</c-input-prefix>
    <c-text-input id="discount" name="discount" type="text" inputmode="numeric" />
    <c-input-suffix>%</c-input-suffix>
</c-input-group>

Website URL

<c-label id="website" label="Website" hint="Enter your website URL." />
<c-input-group>
    <c-input-prefix>https://</c-input-prefix>
    <c-text-input id="website" name="website" type="url" />
    <c-input-suffix>.com</c-input-suffix>
</c-input-group>

Social Media Handle

<c-label id="twitter" label="Twitter handle" hint="Enter your Twitter username." />
<c-input-group>
    <c-input-prefix>@</c-input-prefix>
    <c-text-input id="twitter" name="twitter" type="text" />
    <c-input-suffix><c-icon icon="launch" /></c-input-suffix>
</c-input-group>

Search with Icon Prefix

<c-label id="search-products" label="Search products" hint="Enter product name or SKU." />
<c-input-group>
    <c-input-prefix><c-icon icon="search" /></c-input-prefix>
    <c-text-input id="search-products" name="search_query" type="search" />
    <c-input-suffix>in Stock</c-input-suffix>
</c-input-group>

With Error State

<c-label id="amount-error" label="Amount" hint="Enter the amount." error="Please enter a valid amount." />
<c-input-group error="Please enter a valid amount.">
    <c-input-prefix>$</c-input-prefix>
    <c-text-input id="amount-error" name="amount_error" type="text" inputmode="numeric" error="Please enter a valid amount." />
    <c-input-suffix>USD</c-input-suffix>
</c-input-group>

With Success State

<c-label id="amount-success" label="Amount" />
<c-input-group success="true">
    <c-input-prefix>$</c-input-prefix>
    <c-text-input id="amount-success" name="amount_success" type="text" value="1,250.00" success="true" inputmode="numeric" />
    <c-input-suffix>USD</c-input-suffix>
</c-input-group>

Small Width Group

<c-label id="zip-ext" label="ZIP+4" hint="Last 4 digits." />
<c-input-group width="sm">
    <c-input-prefix>-</c-input-prefix>
    <c-text-input id="zip-ext" name="zip_ext" type="text" inputmode="numeric" pattern="\d{4}" />
</c-input-group>

Usage Notes

  • c-input-group is the required wrapper for any c-input-prefix or c-input-suffix usage
  • Apply validation states (error, success) to both c-input-group and the inner c-text-input so that both the border styling and the input styling update together
  • For a pre-built currency input with $ prefix, use the dedicated c-currency-input component
  • Prefix and suffix elements are aria-hidden="true" and are decorative only
{% load cotton %}

<div class="component-variants">
    <h1>Input Group Component</h1>
    <p class="usa-intro">Use input groups to combine prefixes and suffixes, helping users understand the context and format of the input. This component wraps an input with optional prefix and/or suffix elements.</p>

    {% for variant in variants %}
    <div class="component-variant">
        <h2 class="variant-title">{{ variant.title }}</h2>

        {% cotton text-input id="{{ variant.id }}" name="{{ variant.name }}" type="{{ variant.type }}" value="{{ variant.value }}" label="{{ variant.label }}" hint="{{ variant.hint }}" error="{{ variant.error }}" success="{{ variant.success }}" disabled="{{ variant.disabled }}" readonly="{{ variant.readonly }}" required="{{ variant.required }}" width="{{ variant.width }}" pattern="{{ variant.pattern }}" inputmode="{{ variant.inputmode }}" prefix="{{ variant.prefix }}" prefix_icon="{{ variant.prefix_icon }}" suffix="{{ variant.suffix }}" suffix_icon="{{ variant.suffix_icon }}" %}{% endcotton %}
    </div>
    {% endfor %}
    
</div>
name: Input Group (Prefix & Suffix)
context:
  variants:
    - title: "Currency Input (Dollar)"
      id: "group-currency-usd"
      name: "price_usd"
      label: "Price"
      type: "text"
      hint: "Enter price in US dollars"
      prefix: "$"
      suffix: "USD"
      inputmode: "numeric"


    - title: "Currency Input (Euro)"
      id: "group-currency-eur"
      name: "price_eur"
      label: "Price"
      type: "text"
      hint: "Enter price in euros"
      prefix: "€"
      suffix: "EUR"
      inputmode: "numeric"


    - title: "Temperature Range"
      id: "group-temp-range"
      name: "temperature"
      label: "Temperature"
      type: "text"
      hint: "Enter temperature"
      prefix: "From"
      suffix: "°F"
      inputmode: "numeric"


    - title: "Discount Percentage"
      id: "group-discount"
      name: "discount"
      label: "Discount"
      type: "text"
      hint: "Enter discount amount"
      prefix: "-"
      suffix: "%"
      inputmode: "numeric"


    - title: "Website URL"
      id: "group-url"
      name: "website"
      label: "Website"
      type: "url"
      hint: "Enter your website URL"
      prefix: "https://"
      suffix: ".com"


    - title: "Social Media Handle"
      id: "group-social"
      name: "twitter"
      label: "Twitter handle"
      type: "text"
      hint: "Enter your Twitter username"
      prefix: "@"
      suffix_icon: "launch"


    - title: "Search with Context"
      id: "group-search"
      name: "search_query"
      label: "Search products"
      type: "search"
      hint: "Enter product name or SKU"
      prefix_icon: "search"
      suffix: "in Stock"


    - title: "With Error State"
      id: "group-error"
      name: "amount_error"
      label: "Amount"
      type: "text"
      hint: "Enter the amount"
      prefix: "$"
      suffix: "USD"
      error: "Please enter a valid amount"
      inputmode: "numeric"


    - title: "With Success State"
      id: "group-success"
      name: "amount_success"
      label: "Amount"
      type: "text"
      value: "1,250.00"
      prefix: "$"
      suffix: "USD"
      success: "true"
      inputmode: "numeric"


    - title: "Small Width Group"
      id: "group-small"
      name: "zip_ext"
      label: "ZIP+4"
      type: "text"
      hint: "Last 4 digits"
      prefix: "-"
      suffix: ""
      width: "sm"
      inputmode: "numeric"
      pattern: "\\d{4}"