# Input Group

InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput,
InputGroupText,
InputGroupTextarea,
} from "@/components/starwind/input-group";

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@/components/starwind/input-group";
import Search from "@tabler/icons/outline/search.svg";
---

<InputGroup>
  <InputGroupInput aria-label="Search" placeholder="Search..." />
  <InputGroupAddon>
    <Search />
  </InputGroupAddon>
</InputGroup>
```
  </div>
  <div slot="react">
```tsx
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@/components/starwind/input-group";
import { IconSearch } from "@tabler/icons-react";

export function Example() {
  return (
    <InputGroup>
      <InputGroupInput aria-label="Search" placeholder="Search..." />
      <InputGroupAddon>
        <IconSearch />
      </InputGroupAddon>
    </InputGroup>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import { IconSearch as Search } from "@tabler/icons-vue";
</script>

<template>
  <InputGroup>
    <InputGroupInput aria-label="Search" placeholder="Search..." />
    <InputGroupAddon>
      <Search />
    </InputGroupAddon>
  </InputGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Installation

```bash
npx starwind@latest add input-group --framework astro
```
</DocsTabsContent>
```bash
npx starwind@latest add input-group --framework react
```
</DocsTabsContent>
```bash
npx starwind@latest add input-group --framework vue
```
</DocsTabsContent>
</DocsTabs>

## Usage

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@/components/starwind/input-group";
import Search from "@tabler/icons/outline/search.svg";
---

<InputGroup>
  <InputGroupInput aria-label="Search" placeholder="Search..." />
  <InputGroupAddon>
    <Search />
  </InputGroupAddon>
</InputGroup>
```
  </div>
  <div slot="react">
```tsx
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@/components/starwind/input-group";
import { IconSearch } from "@tabler/icons-react";

export function Example() {
  return (
    <InputGroup>
      <InputGroupInput aria-label="Search" placeholder="Search..." />
      <InputGroupAddon>
        <IconSearch />
      </InputGroupAddon>
    </InputGroup>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import { IconSearch as Search } from "@tabler/icons-vue";
</script>

<template>
  <InputGroup>
    <InputGroupInput aria-label="Search" placeholder="Search..." />
    <InputGroupAddon>
      <Search />
    </InputGroupAddon>
  </InputGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Composition

Combine an input or textarea with the supporting parts you need:

```text
InputGroup
├── InputGroupInput or InputGroupTextarea
└── InputGroupAddon
    ├── InputGroupButton
    └── InputGroupText
```

## Control and Addon Order

`InputGroupText` and `InputGroupButton` are helper components for metadata and actions. Addons are
presentational; associate a field with an external `Label` or an `aria-label` on the control.

Keep `InputGroupAddon` after `InputGroupInput` or `InputGroupTextarea` in the DOM. Use `align` to
control visual placement.

## Alignment

#### inline-start

Use `align="inline-start"` to place content at the start of the field. This is the default alignment.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import Search from "@tabler/icons/outline/search.svg";
---

<InputGroup>
  <InputGroupInput placeholder="Search..." />
  <InputGroupAddon align="inline-start">
    <Search />
  </InputGroupAddon>
</InputGroup>
```
  </div>
  <div slot="react">
```tsx
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import { IconSearch as Search } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <InputGroup>
        <InputGroupInput placeholder="Search..." />
        <InputGroupAddon align="inline-start">
          <Search />
        </InputGroupAddon>
      </InputGroup>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import { IconSearch as Search } from "@tabler/icons-vue";
</script>

<template>
  <InputGroup>
    <InputGroupInput placeholder="Search..." />
    <InputGroupAddon align="inline-start">
      <Search />
    </InputGroupAddon>
  </InputGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

#### inline-end

Use `align="inline-end"` to place content at the end of the field.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import InfoCircle from "@tabler/icons/outline/info-circle.svg";
---

<InputGroup>
  <InputGroupInput type="password" placeholder="Enter password" />
  <InputGroupAddon align="inline-end">
    <InfoCircle />
  </InputGroupAddon>
</InputGroup>
```
  </div>
  <div slot="react">
```tsx
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import { IconInfoCircle as InfoCircle } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <InputGroup>
        <InputGroupInput type="password" placeholder="Enter password" />
        <InputGroupAddon align="inline-end">
          <InfoCircle />
        </InputGroupAddon>
      </InputGroup>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import { IconInfoCircle as InfoCircle } from "@tabler/icons-vue";
</script>

<template>
  <InputGroup>
    <InputGroupInput type="password" placeholder="Enter password" />
    <InputGroupAddon align="inline-end">
      <InfoCircle />
    </InputGroupAddon>
  </InputGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

#### block-start

Use `align="block-start"` to place a header row above the control.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/starwind/input-group";
import Code from "@tabler/icons/outline/code.svg";
import Copy from "@tabler/icons/outline/copy.svg";
---

<div class="grid w-full max-w-sm gap-4">
  <InputGroup>
    <InputGroupInput placeholder="Enter your name" />
    <InputGroupAddon align="block-start">
      <InputGroupText>Full Name</InputGroupText>
    </InputGroupAddon>
  </InputGroup>

  <InputGroup>
    <InputGroupTextarea class="font-mono text-sm" placeholder="console.log('Hello, world!');" />
    <InputGroupAddon align="block-start" class="border-b">
      <Code />
      <InputGroupText class="font-mono">script.js</InputGroupText>
      <InputGroupButton size="icon-sm" class="ml-auto" aria-label="Copy code">
        <Copy />
      </InputGroupButton>
    </InputGroupAddon>
  </InputGroup>
</div>
```
  </div>
  <div slot="react">
```tsx
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/starwind/input-group";
import { IconCode as Code } from "@tabler/icons-react";
import { IconCopy as Copy } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <div className="grid w-full max-w-sm gap-4">
        <InputGroup>
          <InputGroupInput placeholder="Enter your name" />
          <InputGroupAddon align="block-start">
            <InputGroupText>Full Name</InputGroupText>
          </InputGroupAddon>
        </InputGroup>

        <InputGroup>
          <InputGroupTextarea className="font-mono text-sm" placeholder="console.log('Hello, world!');" />
          <InputGroupAddon align="block-start" className="border-b">
            <Code />
            <InputGroupText className="font-mono">script.js</InputGroupText>
            <InputGroupButton size="icon-sm" className="ml-auto" aria-label="Copy code">
              <Copy />
            </InputGroupButton>
          </InputGroupAddon>
        </InputGroup>
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/starwind/input-group";
import { IconCode as Code } from "@tabler/icons-vue";
import { IconCopy as Copy } from "@tabler/icons-vue";
</script>

<template>
  <div class="grid w-full max-w-sm gap-4">
    <InputGroup>
      <InputGroupInput placeholder="Enter your name" />
      <InputGroupAddon align="block-start">
        <InputGroupText>Full Name</InputGroupText>
      </InputGroupAddon>
    </InputGroup>

    <InputGroup>
      <InputGroupTextarea class="font-mono text-sm" placeholder="console.log('Hello, world!');" />
      <InputGroupAddon align="block-start" class="border-b">
        <Code />
        <InputGroupText class="font-mono">script.js</InputGroupText>
        <InputGroupButton size="icon-sm" class="ml-auto" aria-label="Copy code">
          <Copy />
        </InputGroupButton>
      </InputGroupAddon>
    </InputGroup>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

#### block-end

Use `align="block-end"` to place a footer row below the control.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/starwind/input-group";
---

<div class="grid w-full max-w-sm gap-4">
  <InputGroup>
    <InputGroupInput placeholder="Enter amount" />
    <InputGroupAddon align="block-end">
      <InputGroupText>USD</InputGroupText>
    </InputGroupAddon>
  </InputGroup>

  <InputGroup>
    <InputGroupTextarea placeholder="Write a comment..." />
    <InputGroupAddon align="block-end">
      <InputGroupText>0/280</InputGroupText>
      <InputGroupButton variant="default" size="sm" class="ml-auto">Post</InputGroupButton>
    </InputGroupAddon>
  </InputGroup>
</div>
```
  </div>
  <div slot="react">
```tsx
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/starwind/input-group";

export function Example() {
  return (
    <>
      <div className="grid w-full max-w-sm gap-4">
        <InputGroup>
          <InputGroupInput placeholder="Enter amount" />
          <InputGroupAddon align="block-end">
            <InputGroupText>USD</InputGroupText>
          </InputGroupAddon>
        </InputGroup>

        <InputGroup>
          <InputGroupTextarea placeholder="Write a comment..." />
          <InputGroupAddon align="block-end">
            <InputGroupText>0/280</InputGroupText>
            <InputGroupButton variant="default" size="sm" className="ml-auto">Post</InputGroupButton>
          </InputGroupAddon>
        </InputGroup>
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/starwind/input-group";
</script>

<template>
  <div class="grid w-full max-w-sm gap-4">
    <InputGroup>
      <InputGroupInput placeholder="Enter amount" />
      <InputGroupAddon align="block-end">
        <InputGroupText>USD</InputGroupText>
      </InputGroupAddon>
    </InputGroup>

    <InputGroup>
      <InputGroupTextarea placeholder="Write a comment..." />
      <InputGroupAddon align="block-end">
        <InputGroupText>0/280</InputGroupText>
        <InputGroupButton variant="default" size="sm" class="ml-auto">Post</InputGroupButton>
      </InputGroupAddon>
    </InputGroup>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Examples

#### Icon

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import CircleCheck from "@tabler/icons/outline/circle-check.svg";
import CreditCard from "@tabler/icons/outline/credit-card.svg";
import InfoCircle from "@tabler/icons/outline/info-circle.svg";
import Mail from "@tabler/icons/outline/mail.svg";
import Search from "@tabler/icons/outline/search.svg";
import Star from "@tabler/icons/outline/star.svg";
---

<div class="grid w-full max-w-sm gap-6">
  <InputGroup>
    <InputGroupInput placeholder="Search..." />
    <InputGroupAddon>
      <Search />
    </InputGroupAddon>
  </InputGroup>

  <InputGroup>
    <InputGroupInput type="email" placeholder="Enter your email" />
    <InputGroupAddon>
      <Mail />
    </InputGroupAddon>
  </InputGroup>

  <InputGroup>
    <InputGroupInput placeholder="Card number" />
    <InputGroupAddon>
      <CreditCard />
    </InputGroupAddon>
    <InputGroupAddon align="inline-end">
      <CircleCheck />
    </InputGroupAddon>
  </InputGroup>

  <InputGroup>
    <InputGroupInput placeholder="Favorites" />
    <InputGroupAddon align="inline-end">
      <Star />
      <InfoCircle />
    </InputGroupAddon>
  </InputGroup>
</div>
```
  </div>
  <div slot="react">
```tsx
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import { IconCircleCheck as CircleCheck } from "@tabler/icons-react";
import { IconCreditCard as CreditCard } from "@tabler/icons-react";
import { IconInfoCircle as InfoCircle } from "@tabler/icons-react";
import { IconMail as Mail } from "@tabler/icons-react";
import { IconSearch as Search } from "@tabler/icons-react";
import { IconStar as Star } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <div className="grid w-full max-w-sm gap-6">
        <InputGroup>
          <InputGroupInput placeholder="Search..." />
          <InputGroupAddon>
            <Search />
          </InputGroupAddon>
        </InputGroup>

        <InputGroup>
          <InputGroupInput type="email" placeholder="Enter your email" />
          <InputGroupAddon>
            <Mail />
          </InputGroupAddon>
        </InputGroup>

        <InputGroup>
          <InputGroupInput placeholder="Card number" />
          <InputGroupAddon>
            <CreditCard />
          </InputGroupAddon>
          <InputGroupAddon align="inline-end">
            <CircleCheck />
          </InputGroupAddon>
        </InputGroup>

        <InputGroup>
          <InputGroupInput placeholder="Favorites" />
          <InputGroupAddon align="inline-end">
            <Star />
            <InfoCircle />
          </InputGroupAddon>
        </InputGroup>
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import { IconCircleCheck as CircleCheck } from "@tabler/icons-vue";
import { IconCreditCard as CreditCard } from "@tabler/icons-vue";
import { IconInfoCircle as InfoCircle } from "@tabler/icons-vue";
import { IconMail as Mail } from "@tabler/icons-vue";
import { IconSearch as Search } from "@tabler/icons-vue";
import { IconStar as Star } from "@tabler/icons-vue";
</script>

<template>
  <div class="grid w-full max-w-sm gap-6">
    <InputGroup>
      <InputGroupInput placeholder="Search..." />
      <InputGroupAddon>
        <Search />
      </InputGroupAddon>
    </InputGroup>

    <InputGroup>
      <InputGroupInput type="email" placeholder="Enter your email" />
      <InputGroupAddon>
        <Mail />
      </InputGroupAddon>
    </InputGroup>

    <InputGroup>
      <InputGroupInput placeholder="Card number" />
      <InputGroupAddon>
        <CreditCard />
      </InputGroupAddon>
      <InputGroupAddon align="inline-end">
        <CircleCheck />
      </InputGroupAddon>
    </InputGroup>

    <InputGroup>
      <InputGroupInput placeholder="Favorites" />
      <InputGroupAddon align="inline-end">
        <Star />
        <InfoCircle />
      </InputGroupAddon>
    </InputGroup>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

#### Text

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/starwind/input-group";
---

<div class="grid w-full max-w-sm gap-6">
  <InputGroup>
    <InputGroupInput placeholder="0.00" />
    <InputGroupAddon align="inline-start">
      <InputGroupText>$</InputGroupText>
    </InputGroupAddon>
    <InputGroupAddon align="inline-end">
      <InputGroupText>USD</InputGroupText>
    </InputGroupAddon>
  </InputGroup>

  <InputGroup>
    <InputGroupInput placeholder="example" class="!pl-0.5" />
    <InputGroupAddon align="inline-start">
      <InputGroupText>https://</InputGroupText>
    </InputGroupAddon>
    <InputGroupAddon align="inline-end">
      <InputGroupText>.com</InputGroupText>
    </InputGroupAddon>
  </InputGroup>

  <InputGroup>
    <InputGroupInput placeholder="Enter your username" />
    <InputGroupAddon align="inline-end">
      <InputGroupText>@company.com</InputGroupText>
    </InputGroupAddon>
  </InputGroup>

  <InputGroup>
    <InputGroupTextarea placeholder="Enter your message" />
    <InputGroupAddon align="block-end">
      <InputGroupText class="text-xs">120 characters left</InputGroupText>
    </InputGroupAddon>
  </InputGroup>
</div>
```
  </div>
  <div slot="react">
```tsx
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/starwind/input-group";

export function Example() {
  return (
    <>
      <div className="grid w-full max-w-sm gap-6">
        <InputGroup>
          <InputGroupInput placeholder="0.00" />
          <InputGroupAddon align="inline-start">
            <InputGroupText>$</InputGroupText>
          </InputGroupAddon>
          <InputGroupAddon align="inline-end">
            <InputGroupText>USD</InputGroupText>
          </InputGroupAddon>
        </InputGroup>

        <InputGroup>
          <InputGroupInput placeholder="example" className="!pl-0.5" />
          <InputGroupAddon align="inline-start">
            <InputGroupText>https://</InputGroupText>
          </InputGroupAddon>
          <InputGroupAddon align="inline-end">
            <InputGroupText>.com</InputGroupText>
          </InputGroupAddon>
        </InputGroup>

        <InputGroup>
          <InputGroupInput placeholder="Enter your username" />
          <InputGroupAddon align="inline-end">
            <InputGroupText>@company.com</InputGroupText>
          </InputGroupAddon>
        </InputGroup>

        <InputGroup>
          <InputGroupTextarea placeholder="Enter your message" />
          <InputGroupAddon align="block-end">
            <InputGroupText className="text-xs">120 characters left</InputGroupText>
          </InputGroupAddon>
        </InputGroup>
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/starwind/input-group";
</script>

<template>
  <div class="grid w-full max-w-sm gap-6">
    <InputGroup>
      <InputGroupInput placeholder="0.00" />
      <InputGroupAddon align="inline-start">
        <InputGroupText>$</InputGroupText>
      </InputGroupAddon>
      <InputGroupAddon align="inline-end">
        <InputGroupText>USD</InputGroupText>
      </InputGroupAddon>
    </InputGroup>

    <InputGroup>
      <InputGroupInput placeholder="example" class="!pl-0.5" />
      <InputGroupAddon align="inline-start">
        <InputGroupText>https://</InputGroupText>
      </InputGroupAddon>
      <InputGroupAddon align="inline-end">
        <InputGroupText>.com</InputGroupText>
      </InputGroupAddon>
    </InputGroup>

    <InputGroup>
      <InputGroupInput placeholder="Enter your username" />
      <InputGroupAddon align="inline-end">
        <InputGroupText>@company.com</InputGroupText>
      </InputGroupAddon>
    </InputGroup>

    <InputGroup>
      <InputGroupTextarea placeholder="Enter your message" />
      <InputGroupAddon align="block-end">
        <InputGroupText class="text-xs">120 characters left</InputGroupText>
      </InputGroupAddon>
    </InputGroup>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

#### Button

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
} from "@/components/starwind/input-group";
import Copy from "@tabler/icons/outline/copy.svg";
import InfoCircle from "@tabler/icons/outline/info-circle.svg";
import Star from "@tabler/icons/outline/star.svg";
---

<div class="grid w-full max-w-sm gap-6">
  <InputGroup>
    <InputGroupInput placeholder="https://starwind.dev" readonly />
    <InputGroupAddon align="inline-end">
      <InputGroupButton aria-label="Copy" title="Copy" size="icon-sm">
        <Copy />
      </InputGroupButton>
    </InputGroupAddon>
  </InputGroup>

  <InputGroup class="[--radius:9999px]">
    <InputGroupInput placeholder="secure-site" />
    <InputGroupAddon align="inline-start">
      <InputGroupButton variant="secondary" size="icon-sm" aria-label="Info">
        <InfoCircle />
      </InputGroupButton>
    </InputGroupAddon>
    <InputGroupAddon align="inline-start" class="pl-1.5">
      <InputGroupText>https://</InputGroupText>
    </InputGroupAddon>
    <InputGroupAddon align="inline-end">
      <InputGroupButton size="icon-sm" aria-label="Favorite">
        <Star />
      </InputGroupButton>
    </InputGroupAddon>
  </InputGroup>

  <InputGroup>
    <InputGroupInput placeholder="Type to search..." />
    <InputGroupAddon align="inline-end">
      <InputGroupButton variant="secondary">Search</InputGroupButton>
    </InputGroupAddon>
  </InputGroup>
</div>
```
  </div>
  <div slot="react">
```tsx
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
} from "@/components/starwind/input-group";
import { IconCopy as Copy } from "@tabler/icons-react";
import { IconInfoCircle as InfoCircle } from "@tabler/icons-react";
import { IconStar as Star } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <div className="grid w-full max-w-sm gap-6">
        <InputGroup>
          <InputGroupInput placeholder="https://starwind.dev" readOnly />
          <InputGroupAddon align="inline-end">
            <InputGroupButton aria-label="Copy" title="Copy" size="icon-sm">
              <Copy />
            </InputGroupButton>
          </InputGroupAddon>
        </InputGroup>

        <InputGroup className="[--radius:9999px]">
          <InputGroupInput placeholder="secure-site" />
          <InputGroupAddon align="inline-start">
            <InputGroupButton variant="secondary" size="icon-sm" aria-label="Info">
              <InfoCircle />
            </InputGroupButton>
          </InputGroupAddon>
          <InputGroupAddon align="inline-start" className="pl-1.5">
            <InputGroupText>https://</InputGroupText>
          </InputGroupAddon>
          <InputGroupAddon align="inline-end">
            <InputGroupButton size="icon-sm" aria-label="Favorite">
              <Star />
            </InputGroupButton>
          </InputGroupAddon>
        </InputGroup>

        <InputGroup>
          <InputGroupInput placeholder="Type to search..." />
          <InputGroupAddon align="inline-end">
            <InputGroupButton variant="secondary">Search</InputGroupButton>
          </InputGroupAddon>
        </InputGroup>
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
} from "@/components/starwind/input-group";
import { IconCopy as Copy } from "@tabler/icons-vue";
import { IconInfoCircle as InfoCircle } from "@tabler/icons-vue";
import { IconStar as Star } from "@tabler/icons-vue";
</script>

<template>
  <div class="grid w-full max-w-sm gap-6">
    <InputGroup>
      <InputGroupInput placeholder="https://starwind.dev" readonly />
      <InputGroupAddon align="inline-end">
        <InputGroupButton aria-label="Copy" title="Copy" size="icon-sm">
          <Copy />
        </InputGroupButton>
      </InputGroupAddon>
    </InputGroup>

    <InputGroup class="[--radius:9999px]">
      <InputGroupInput placeholder="secure-site" />
      <InputGroupAddon align="inline-start">
        <InputGroupButton variant="secondary" size="icon-sm" aria-label="Info">
          <InfoCircle />
        </InputGroupButton>
      </InputGroupAddon>
      <InputGroupAddon align="inline-start" class="pl-1.5">
        <InputGroupText>https://</InputGroupText>
      </InputGroupAddon>
      <InputGroupAddon align="inline-end">
        <InputGroupButton size="icon-sm" aria-label="Favorite">
          <Star />
        </InputGroupButton>
      </InputGroupAddon>
    </InputGroup>

    <InputGroup>
      <InputGroupInput placeholder="Type to search..." />
      <InputGroupAddon align="inline-end">
        <InputGroupButton variant="secondary">Search</InputGroupButton>
      </InputGroupAddon>
    </InputGroup>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

#### Kbd

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import { Kbd } from "@/components/starwind/kbd";
import Search from "@tabler/icons/outline/search.svg";
---

<InputGroup>
  <InputGroupInput placeholder="Search..." />
  <InputGroupAddon>
    <Search />
  </InputGroupAddon>
  <InputGroupAddon align="inline-end">
    <Kbd>Ctrl+K</Kbd>
  </InputGroupAddon>
</InputGroup>
```
  </div>
  <div slot="react">
```tsx
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import { Kbd } from "@/components/starwind/kbd";
import { IconSearch as Search } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <InputGroup>
        <InputGroupInput placeholder="Search..." />
        <InputGroupAddon>
          <Search />
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <Kbd>Ctrl+K</Kbd>
        </InputGroupAddon>
      </InputGroup>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";
import { Kbd } from "@/components/starwind/kbd";
import { IconSearch as Search } from "@tabler/icons-vue";
</script>

<template>
  <InputGroup>
    <InputGroupInput placeholder="Search..." />
    <InputGroupAddon>
      <Search />
    </InputGroupAddon>
    <InputGroupAddon align="inline-end">
      <Kbd>Ctrl+K</Kbd>
    </InputGroupAddon>
  </InputGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

#### Dropdown

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Dropdown, DropdownContent, DropdownItem, DropdownTrigger } from "@/components/starwind/dropdown";
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "@/components/starwind/input-group";
import ChevronDown from "@tabler/icons/outline/chevron-down.svg";
---

<div class="grid w-full max-w-sm gap-4">
  <InputGroup>
    <InputGroupInput placeholder="Enter file name" />
    <InputGroupAddon align="inline-end">
      <Dropdown>
        <DropdownTrigger asChild>
          <InputGroupButton aria-label="More options" size="icon-sm">
            <ChevronDown />
          </InputGroupButton>
        </DropdownTrigger>
        <DropdownContent align="end">
          <DropdownItem>Settings</DropdownItem>
          <DropdownItem>Copy path</DropdownItem>
          <DropdownItem>Open location</DropdownItem>
        </DropdownContent>
      </Dropdown>
    </InputGroupAddon>
  </InputGroup>

  <InputGroup class="[--radius:1rem]">
    <InputGroupInput placeholder="Enter search query" />
    <InputGroupAddon align="inline-end">
      <Dropdown>
        <DropdownTrigger asChild>
          <InputGroupButton variant="ghost" class="!pr-1.5 text-xs">
            Search in
            <ChevronDown class="size-3" />
          </InputGroupButton>
        </DropdownTrigger>
        <DropdownContent align="end" class="[--radius:0.95rem]">
          <DropdownItem>Documentation</DropdownItem>
          <DropdownItem>Blog Posts</DropdownItem>
          <DropdownItem>Changelog</DropdownItem>
        </DropdownContent>
      </Dropdown>
    </InputGroupAddon>
  </InputGroup>
</div>
```
  </div>
  <div slot="react">
```tsx
import { Dropdown, DropdownContent, DropdownItem, DropdownTrigger } from "@/components/starwind/dropdown";
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "@/components/starwind/input-group";
import { IconChevronDown as ChevronDown } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <div className="grid w-full max-w-sm gap-4">
        <InputGroup>
          <InputGroupInput placeholder="Enter file name" />
          <InputGroupAddon align="inline-end">
            <Dropdown>
              <DropdownTrigger asChild>
                <InputGroupButton aria-label="More options" size="icon-sm">
                  <ChevronDown />
                </InputGroupButton>
              </DropdownTrigger>
              <DropdownContent align="end">
                <DropdownItem>Settings</DropdownItem>
                <DropdownItem>Copy path</DropdownItem>
                <DropdownItem>Open location</DropdownItem>
              </DropdownContent>
            </Dropdown>
          </InputGroupAddon>
        </InputGroup>

        <InputGroup className="[--radius:1rem]">
          <InputGroupInput placeholder="Enter search query" />
          <InputGroupAddon align="inline-end">
            <Dropdown>
              <DropdownTrigger asChild>
                <InputGroupButton variant="ghost" className="!pr-1.5 text-xs">
                  Search in
                  <ChevronDown className="size-3" />
                </InputGroupButton>
              </DropdownTrigger>
              <DropdownContent align="end" className="[--radius:0.95rem]">
                <DropdownItem>Documentation</DropdownItem>
                <DropdownItem>Blog Posts</DropdownItem>
                <DropdownItem>Changelog</DropdownItem>
              </DropdownContent>
            </Dropdown>
          </InputGroupAddon>
        </InputGroup>
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { InputGroupVariants } from "@/components/starwind/input-group";
import { ButtonVariants } from "@/components/starwind/button";
import {
  Dropdown,
  DropdownContent,
  DropdownItem,
  DropdownTrigger,
} from "@/components/starwind/dropdown";
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
} from "@/components/starwind/input-group";
import { IconChevronDown as ChevronDown } from "@tabler/icons-vue";
</script>

<template>
  <div class="grid w-full max-w-sm gap-4">
    <InputGroup>
      <InputGroupInput placeholder="Enter file name" />
      <InputGroupAddon align="inline-end">
        <Dropdown>
          <DropdownTrigger asChild>
            <button
              aria-label="More options"
              type="button"
              :class="ButtonVariants.button({
                variant: 'ghost',
                class: InputGroupVariants.inputGroupButton({ size: 'icon-sm' }),
              })"
            >
              <ChevronDown />
            </button>
          </DropdownTrigger>
          <DropdownContent align="end">
            <DropdownItem>Settings</DropdownItem>
            <DropdownItem>Copy path</DropdownItem>
            <DropdownItem>Open location</DropdownItem>
          </DropdownContent>
        </Dropdown>
      </InputGroupAddon>
    </InputGroup>

    <InputGroup class="[--radius:1rem]">
      <InputGroupInput placeholder="Enter search query" />
      <InputGroupAddon align="inline-end">
        <Dropdown>
          <DropdownTrigger asChild>
            <button
              type="button"
              :class="ButtonVariants.button({
                variant: 'ghost',
                class: InputGroupVariants.inputGroupButton({ class: '!pr-1.5 text-xs' }),
              })"
            >
              Search in
              <ChevronDown class="size-3" />
            </button>
          </DropdownTrigger>
          <DropdownContent align="end" class="[--radius:0.95rem]">
            <DropdownItem>Documentation</DropdownItem>
            <DropdownItem>Blog Posts</DropdownItem>
            <DropdownItem>Changelog</DropdownItem>
          </DropdownContent>
        </Dropdown>
      </InputGroupAddon>
    </InputGroup>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

#### Spinner

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
} from "@/components/starwind/input-group";
import { Spinner } from "@/components/starwind/spinner";
---

<div class="grid w-full max-w-sm gap-4">
  <InputGroup>
    <InputGroupInput placeholder="Searching..." />
    <InputGroupAddon align="inline-end">
      <Spinner />
    </InputGroupAddon>
  </InputGroup>

  <InputGroup>
    <InputGroupInput placeholder="Processing..." />
    <InputGroupAddon>
      <Spinner />
    </InputGroupAddon>
  </InputGroup>

  <InputGroup>
    <InputGroupInput placeholder="Saving changes..." />
    <InputGroupAddon align="inline-end">
      <InputGroupText>Saving...</InputGroupText>
      <Spinner />
    </InputGroupAddon>
  </InputGroup>
</div>
```
  </div>
  <div slot="react">
```tsx
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
} from "@/components/starwind/input-group";
import { Spinner } from "@/components/starwind/spinner";

export function Example() {
  return (
    <>
      <div className="grid w-full max-w-sm gap-4">
        <InputGroup>
          <InputGroupInput placeholder="Searching..." />
          <InputGroupAddon align="inline-end">
            <Spinner />
          </InputGroupAddon>
        </InputGroup>

        <InputGroup>
          <InputGroupInput placeholder="Processing..." />
          <InputGroupAddon>
            <Spinner />
          </InputGroupAddon>
        </InputGroup>

        <InputGroup>
          <InputGroupInput placeholder="Saving changes..." />
          <InputGroupAddon align="inline-end">
            <InputGroupText>Saving...</InputGroupText>
            <Spinner />
          </InputGroupAddon>
        </InputGroup>
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
} from "@/components/starwind/input-group";
import { Spinner } from "@/components/starwind/spinner";
</script>

<template>
  <div class="grid w-full max-w-sm gap-4">
    <InputGroup>
      <InputGroupInput placeholder="Searching..." />
      <InputGroupAddon align="inline-end">
        <Spinner />
      </InputGroupAddon>
    </InputGroup>

    <InputGroup>
      <InputGroupInput placeholder="Processing..." />
      <InputGroupAddon>
        <Spinner />
      </InputGroupAddon>
    </InputGroup>

    <InputGroup>
      <InputGroupInput placeholder="Saving changes..." />
      <InputGroupAddon align="inline-end">
        <InputGroupText>Saving...</InputGroupText>
        <Spinner />
      </InputGroupAddon>
    </InputGroup>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

#### Textarea

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/starwind/input-group";
import ArrowRight from "@tabler/icons/outline/arrow-right.svg";
import Code from "@tabler/icons/outline/code.svg";
import Copy from "@tabler/icons/outline/copy.svg";
---

<InputGroup>
  <InputGroupTextarea
    id="textarea-code"
    placeholder="console.log('Hello, world!');"
    class="min-h-[180px] font-mono text-sm"
  />
  <InputGroupAddon align="block-end" class="border-t">
    <InputGroupText>Line 1, Column 1</InputGroupText>
    <InputGroupButton size="sm" class="ml-auto" variant="default">
      Run
      <ArrowRight />
    </InputGroupButton>
  </InputGroupAddon>
  <InputGroupAddon align="block-start" class="border-b">
    <InputGroupText class="font-mono font-medium">
      <Code />
      script.js
    </InputGroupText>
    <InputGroupButton class="ml-auto" size="icon-sm" aria-label="Copy code">
      <Copy />
    </InputGroupButton>
  </InputGroupAddon>
</InputGroup>
```
  </div>
  <div slot="react">
```tsx
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/starwind/input-group";
import { IconArrowRight as ArrowRight } from "@tabler/icons-react";
import { IconCode as Code } from "@tabler/icons-react";
import { IconCopy as Copy } from "@tabler/icons-react";

export function Example() {
  return (
    <>
      <InputGroup>
        <InputGroupTextarea
          id="textarea-code"
          placeholder="console.log('Hello, world!');"
          className="min-h-[180px] font-mono text-sm"
        />
        <InputGroupAddon align="block-end" className="border-t">
          <InputGroupText>Line 1, Column 1</InputGroupText>
          <InputGroupButton size="sm" className="ml-auto" variant="default">
            Run
            <ArrowRight />
          </InputGroupButton>
        </InputGroupAddon>
        <InputGroupAddon align="block-start" className="border-b">
          <InputGroupText className="font-mono font-medium">
            <Code />
            script.js
          </InputGroupText>
          <InputGroupButton className="ml-auto" size="icon-sm" aria-label="Copy code">
            <Copy />
          </InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/starwind/input-group";
import { IconArrowRight as ArrowRight } from "@tabler/icons-vue";
import { IconCode as Code } from "@tabler/icons-vue";
import { IconCopy as Copy } from "@tabler/icons-vue";
</script>

<template>
  <InputGroup>
    <InputGroupTextarea
      id="textarea-code"
      placeholder="console.log('Hello, world!');"
      class="min-h-[180px] font-mono text-sm"
    />
    <InputGroupAddon align="block-end" class="border-t">
      <InputGroupText>Line 1, Column 1</InputGroupText>
      <InputGroupButton size="sm" class="ml-auto" variant="default">
        Run
        <ArrowRight />
      </InputGroupButton>
    </InputGroupAddon>
    <InputGroupAddon align="block-start" class="border-b">
      <InputGroupText class="font-mono font-medium">
        <Code />
        script.js
      </InputGroupText>
      <InputGroupButton class="ml-auto" size="icon-sm" aria-label="Copy code">
        <Copy />
      </InputGroupButton>
    </InputGroupAddon>
  </InputGroup>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## API Reference
### InputGroup
- Inherits div attributes.

### InputGroupAddon
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `align` | `"inline-start" \| "inline-end" \| "block-start" \| "block-end"` | No | `"inline-start"` | Styled variant | Aligns the component within its available axis. |
- Inherits div attributes.

### InputGroupButton
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `size` | `"sm" \| "icon-sm"` | No | `"sm"` | Styled variant | Selects the component's visual size. |
- Inherits Button props. Omits `size`.

### InputGroupInput
- Inherits Input props.

### InputGroupText
- Inherits span attributes.

### InputGroupTextarea
- Inherits Textarea props.

## Changelog

### v1.1.2

- Named the generated aggregate default export so React and Astro tooling can identify the installed component cleanly.

### v1.1.1

- Aligned Astro and React attribute forwarding with the current generated adapter output.

### v1.1.0

- Added contract-generated Astro and React implementations while preserving the component's existing public API and styling.
- `InputGroupAddon` is now presentational and no longer installs a click-to-focus script. Give the
control its own accessible name, and use `InputGroupButton` when the addon itself performs an
action.

### v1.0.1

- Refactor tailwind variants functions into separate `variants.ts` file

### v1.0.0

- Initial release with starwind v1.16.0