shadcn-remix
GitHub

Input Group

Add addons, buttons, and helper content to inputs.

12 results
https://
52% used
import { css } from 'remix/component'

import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
import { css } from 'remix/component'

import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '#app/ui/dropdown-menu.tsx'
import { ArrowUpIcon, CheckIcon, InfoIcon, PlusIcon, SearchIcon } from '#app/ui/icons.tsx'
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
  InputGroupTextarea,
  inputGroupButtonVariants,
} from '#app/ui/input-group.tsx'
import { Separator } from '#app/ui/separator.tsx'
import { Tooltip, TooltipContent, TooltipTrigger } from '#app/ui/tooltip.tsx'

const gridStyles = css({ display: 'grid', width: '100%', maxWidth: '24rem', gap: '1.5rem' })
const srOnly = css({
  position: 'absolute',
  width: '1px',
  height: '1px',
  padding: 0,
  margin: '-1px',
  overflow: 'hidden',
  clip: 'rect(0, 0, 0, 0)',
  whiteSpace: 'nowrap',
  borderWidth: 0,
})
const tightInput = css({ paddingLeft: '0.25rem' })
const roundedFull = css({ borderRadius: '9999px' })
const roundedMenu = css({ '--radius': '0.95rem' })
const pushRight = css({ marginLeft: 'auto' })
const separatorStyles = css({ height: '1rem' })
const badgeStyles = css({
  display: 'flex',
  width: '1rem',
  height: '1rem',
  alignItems: 'center',
  justifyContent: 'center',
  borderRadius: '9999px',
  backgroundColor: 'var(--primary)',
  color: 'var(--primary-foreground)',
})
const badgeIconStyles = css({ width: '0.75rem', height: '0.75rem' })

export function InputGroupDemo() {
  return () => (
    <div mix={gridStyles}>
      <InputGroup>
        <InputGroupInput placeholder="Search..." />
        <InputGroupAddon>
          <SearchIcon />
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">12 results</InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput placeholder="example.com" mix={tightInput} />
        <InputGroupAddon>
          <InputGroupText>https://</InputGroupText>
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <Tooltip>
            <TooltipTrigger
              data-slot="button"
              data-size="icon-xs"
              mix={[inputGroupButtonVariants({ size: 'icon-xs' }), roundedFull]}
            >
              <InfoIcon />
            </TooltipTrigger>
            <TooltipContent>This is content in a tooltip.</TooltipContent>
          </Tooltip>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupTextarea placeholder="Ask, Search or Chat..." />
        <InputGroupAddon align="block-end">
          <InputGroupButton variant="outline" size="icon-xs" mix={roundedFull}>
            <PlusIcon />
          </InputGroupButton>
          <DropdownMenu>
            <DropdownMenuTrigger
              data-slot="button"
              data-size="xs"
              mix={inputGroupButtonVariants({ variant: 'ghost' })}
            >
              Auto
            </DropdownMenuTrigger>
            <DropdownMenuContent side="top" align="start" mix={roundedMenu}>
              <DropdownMenuItem>Auto</DropdownMenuItem>
              <DropdownMenuItem>Agent</DropdownMenuItem>
              <DropdownMenuItem>Manual</DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
          <InputGroupText mix={pushRight}>52% used</InputGroupText>
          <Separator orientation="vertical" mix={separatorStyles} />
          <InputGroupButton variant="default" size="icon-xs" disabled mix={roundedFull}>
            <ArrowUpIcon />
            <span mix={srOnly}>Send</span>
          </InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput placeholder="@shadcn" />
        <InputGroupAddon align="inline-end">
          <div mix={badgeStyles}>
            <CheckIcon mix={badgeIconStyles} />
          </div>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Installation

$ pnpm dlx shadcn@latest add https://www.shadcn-remix.com/r/input-group.json

Usage

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
  InputGroupTextarea,
} from '#app/ui/input-group.tsx'
<InputGroup>
  <InputGroupInput placeholder="Search..." />
  <InputGroupAddon>
    <SearchIcon />
  </InputGroupAddon>
</InputGroup>

Examples

Icon

styleName="radix-nova"

import { css } from 'remix/component'

import {
  CheckIcon,
  CreditCardIcon,
  InfoIcon,
import { css } from 'remix/component'

import {
  CheckIcon,
  CreditCardIcon,
  InfoIcon,
  MailIcon,
  SearchIcon,
  StarIcon,
} from '#app/ui/icons.tsx'
import { InputGroup, InputGroupAddon, InputGroupInput } from '#app/ui/input-group.tsx'

const gridStyles = css({ display: 'grid', width: '100%', maxWidth: '24rem', gap: '1.5rem' })

export function InputGroupIcon() {
  return () => (
    <div mix={gridStyles}>
      <InputGroup>
        <InputGroupInput placeholder="Search..." />
        <InputGroupAddon>
          <SearchIcon />
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput type="email" placeholder="Enter your email" />
        <InputGroupAddon>
          <MailIcon />
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput placeholder="Card number" />
        <InputGroupAddon>
          <CreditCardIcon />
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <CheckIcon />
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput placeholder="Card number" />
        <InputGroupAddon align="inline-end">
          <StarIcon />
          <InfoIcon />
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Text

styleName="radix-nova"

$
USD
https://
.com
@company.com
120 characters left
import { css } from 'remix/component'

import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
import { css } from 'remix/component'

import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
  InputGroupTextarea,
} from '#app/ui/input-group.tsx'

const gridStyles = css({ display: 'grid', width: '100%', maxWidth: '24rem', gap: '1.5rem' })
const tightInput = css({ paddingLeft: '0.125rem' })
const counterStyles = css({
  fontSize: '0.75rem',
  lineHeight: 'calc(1 / 0.75)',
  color: 'var(--muted-foreground)',
})

export function InputGroupTextExample() {
  return () => (
    <div mix={gridStyles}>
      <InputGroup>
        <InputGroupAddon>
          <InputGroupText>$</InputGroupText>
        </InputGroupAddon>
        <InputGroupInput placeholder="0.00" />
        <InputGroupAddon align="inline-end">
          <InputGroupText>USD</InputGroupText>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupAddon>
          <InputGroupText>https://</InputGroupText>
        </InputGroupAddon>
        <InputGroupInput placeholder="example.com" mix={tightInput} />
        <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 mix={counterStyles}>120 characters left</InputGroupText>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Button

styleName="radix-nova"

https://
import { css, on, type Handle } from 'remix/component'

import { CheckIcon, CopyIcon, InfoIcon, StarIcon } from '#app/ui/icons.tsx'
import {
  InputGroup,
  InputGroupAddon,
import { css, on, type Handle } from 'remix/component'

import { CheckIcon, CopyIcon, InfoIcon, StarIcon } from '#app/ui/icons.tsx'
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  inputGroupButtonVariants,
} from '#app/ui/input-group.tsx'
import { Popover, PopoverContent, PopoverTrigger } from '#app/ui/popover.tsx'

const gridStyles = css({ display: 'grid', width: '100%', maxWidth: '24rem', gap: '1.5rem' })
const pillGroup = css({ '--radius': '9999px' })
const prefixStyles = css({ paddingLeft: '0.375rem', color: 'var(--muted-foreground)' })
const popoverStyles = css({
  display: 'flex',
  flexDirection: 'column',
  gap: '0.25rem',
  borderRadius: 'calc(var(--radius) + 4px)',
  fontSize: '0.875rem',
  lineHeight: 'calc(1.25 / 0.875)',
})
const titleStyles = css({ fontWeight: 500 })
const starStyles = css({
  '&[data-favorite="true"]': {
    fill: 'oklch(54.6% 0.245 262.881)',
    stroke: 'oklch(54.6% 0.245 262.881)',
  },
})

export function InputGroupButtonExample(handle: Handle) {
  let isCopied = false
  let isFavorite = false
  let resetCopied: ReturnType<typeof setTimeout> | undefined
  handle.signal.addEventListener('abort', () => clearTimeout(resetCopied))

  return () => (
    <div mix={gridStyles}>
      <InputGroup>
        <InputGroupInput placeholder="https://x.com/shadcn" readOnly />
        <InputGroupAddon align="inline-end">
          <InputGroupButton
            aria-label="Copy"
            title="Copy"
            size="icon-xs"
            mix={on('click', async () => {
              await navigator.clipboard.writeText('https://x.com/shadcn')
              isCopied = true
              handle.update()
              clearTimeout(resetCopied)
              resetCopied = setTimeout(() => {
                isCopied = false
                handle.update()
              }, 2000)
            })}
          >
            {isCopied ? <CheckIcon /> : <CopyIcon />}
          </InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup mix={pillGroup}>
        <InputGroupAddon>
          <Popover>
            <PopoverTrigger
              data-slot="button"
              data-size="icon-xs"
              mix={inputGroupButtonVariants({ variant: 'secondary', size: 'icon-xs' })}
            >
              <InfoIcon />
            </PopoverTrigger>
            <PopoverContent align="start" mix={popoverStyles}>
              <p mix={titleStyles}>Your connection is not secure.</p>
              <p>You should not enter any sensitive information on this site.</p>
            </PopoverContent>
          </Popover>
        </InputGroupAddon>
        <InputGroupAddon mix={prefixStyles}>https://</InputGroupAddon>
        <InputGroupInput id="input-secure-19" />
        <InputGroupAddon align="inline-end">
          <InputGroupButton
            size="icon-xs"
            mix={on('click', () => {
              isFavorite = !isFavorite
              handle.update()
            })}
          >
            <StarIcon data-favorite={String(isFavorite)} mix={starStyles} />
          </InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput placeholder="Type to search..." />
        <InputGroupAddon align="inline-end">
          <InputGroupButton variant="secondary">Search</InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

styleName="radix-nova"

import { css } from 'remix/component'

import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
import { css } from 'remix/component'

import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '#app/ui/dropdown-menu.tsx'
import { ChevronDownIcon, MoreHorizontalIcon } from '#app/ui/icons.tsx'
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  inputGroupButtonVariants,
} from '#app/ui/input-group.tsx'

const gridStyles = css({ display: 'grid', width: '100%', maxWidth: '24rem', gap: '1rem' })
const roundedGroup = css({ '--radius': '1rem' })
const roundedMenu = css({ '--radius': '0.95rem' })
const searchInStyles = css({
  paddingRight: '0.375rem',
  fontSize: '0.75rem',
  lineHeight: 'calc(1 / 0.75)',
})
const chevronStyles = css({ width: '0.75rem', height: '0.75rem' })

export function InputGroupDropdown() {
  return () => (
    <div mix={gridStyles}>
      <InputGroup>
        <InputGroupInput placeholder="Enter file name" />
        <InputGroupAddon align="inline-end">
          <DropdownMenu>
            <DropdownMenuTrigger
              aria-label="More"
              data-slot="button"
              data-size="icon-xs"
              mix={inputGroupButtonVariants({ variant: 'ghost', size: 'icon-xs' })}
            >
              <MoreHorizontalIcon />
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <DropdownMenuItem>Settings</DropdownMenuItem>
              <DropdownMenuItem>Copy path</DropdownMenuItem>
              <DropdownMenuItem>Open location</DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup mix={roundedGroup}>
        <InputGroupInput placeholder="Enter search query" />
        <InputGroupAddon align="inline-end">
          <DropdownMenu>
            <DropdownMenuTrigger
              data-slot="button"
              data-size="xs"
              mix={[inputGroupButtonVariants({ variant: 'ghost' }), searchInStyles]}
            >
              Search In... <ChevronDownIcon mix={chevronStyles} />
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end" mix={roundedMenu}>
              <DropdownMenuItem>Documentation</DropdownMenuItem>
              <DropdownMenuItem>Blog Posts</DropdownMenuItem>
              <DropdownMenuItem>Changelog</DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Spinner

styleName="radix-nova"

Saving...
Please wait...
import { css } from 'remix/component'

import { LoaderIcon } from '#app/ui/icons.tsx'
import {
  InputGroup,
  InputGroupAddon,
import { css } from 'remix/component'

import { LoaderIcon } from '#app/ui/icons.tsx'
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
} from '#app/ui/input-group.tsx'
import { Spinner } from '#app/ui/spinner.tsx'

const gridStyles = css({ display: 'grid', width: '100%', maxWidth: '24rem', gap: '1rem' })
const spinStyles = css({ animation: 'spin 1s linear infinite' })
const mutedStyles = css({ color: 'var(--muted-foreground)' })

export function InputGroupSpinner() {
  return () => (
    <div mix={gridStyles}>
      <InputGroup data-disabled="true">
        <InputGroupInput placeholder="Searching..." disabled />
        <InputGroupAddon align="inline-end">
          <Spinner />
        </InputGroupAddon>
      </InputGroup>
      <InputGroup data-disabled="true">
        <InputGroupInput placeholder="Processing..." disabled />
        <InputGroupAddon>
          <Spinner />
        </InputGroupAddon>
      </InputGroup>
      <InputGroup data-disabled="true">
        <InputGroupInput placeholder="Saving changes..." disabled />
        <InputGroupAddon align="inline-end">
          <InputGroupText>Saving...</InputGroupText>
          <Spinner />
        </InputGroupAddon>
      </InputGroup>
      <InputGroup data-disabled="true">
        <InputGroupInput placeholder="Refreshing data..." disabled />
        <InputGroupAddon>
          <LoaderIcon mix={spinStyles} />
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <InputGroupText mix={mutedStyles}>Please wait...</InputGroupText>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Textarea

styleName="radix-nova"

Line 1, Column 1
script.js
import { css } from 'remix/component'

import { CopyIcon, CornerDownLeftIcon, FileCodeIcon, RefreshCwIcon } from '#app/ui/icons.tsx'
import {
  InputGroup,
  InputGroupAddon,
import { css } from 'remix/component'

import { CopyIcon, CornerDownLeftIcon, FileCodeIcon, RefreshCwIcon } from '#app/ui/icons.tsx'
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupText,
  InputGroupTextarea,
} from '#app/ui/input-group.tsx'

const gridStyles = css({ display: 'grid', width: '100%', maxWidth: '28rem', gap: '1rem' })
const editorStyles = css({ minHeight: '200px' })
// `className="border-t"` / `"border-b"`; the addon's `[.border-t]:pt-3` rule comes along.
const borderTop = css({ borderTopWidth: '1px', paddingTop: '0.75rem' })
const borderBottom = css({ borderBottomWidth: '1px', paddingBottom: '0.75rem' })
const monoStyles = css({
  fontFamily: 'var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace)',
  fontWeight: 500,
})
const pushRight = css({ marginLeft: 'auto' })

export function InputGroupTextareaExample() {
  return () => (
    <div mix={gridStyles}>
      <InputGroup>
        <InputGroupTextarea
          id="textarea-code-32"
          placeholder="console.log('Hello, world!');"
          mix={editorStyles}
        />
        <InputGroupAddon align="block-end" mix={borderTop}>
          <InputGroupText>Line 1, Column 1</InputGroupText>
          <InputGroupButton size="sm" variant="default" mix={pushRight}>
            Run <CornerDownLeftIcon />
          </InputGroupButton>
        </InputGroupAddon>
        <InputGroupAddon align="block-start" mix={borderBottom}>
          <InputGroupText mix={monoStyles}>
            <FileCodeIcon />
            script.js
          </InputGroupText>
          <InputGroupButton size="icon-xs" mix={pushRight}>
            <RefreshCwIcon />
          </InputGroupButton>
          <InputGroupButton variant="ghost" size="icon-xs">
            <CopyIcon />
          </InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Custom Input

Add the data-slot="input-group-control" attribute to your custom input for automatic focus state handling. Here's an example of a custom resizable textarea from a third-party library.

import { css } from 'remix/component'

import { InputGroup, InputGroupAddon, InputGroupButton } from '#app/ui/input-group.tsx'

const gridStyles = css({ display: 'grid', width: '100%', maxWidth: '24rem', gap: '1.5rem' })
// shadcn uses react-textarea-autosize; a native textarea with `field-sizing: content` grows the same way.
import { css } from 'remix/component'

import { InputGroup, InputGroupAddon, InputGroupButton } from '#app/ui/input-group.tsx'

const gridStyles = css({ display: 'grid', width: '100%', maxWidth: '24rem', gap: '1.5rem' })
// shadcn uses react-textarea-autosize; a native textarea with `field-sizing: content` grows the same way.
const autosizeStyles = css({
  display: 'flex',
  fieldSizing: 'content',
  minHeight: '4rem',
  width: '100%',
  resize: 'none',
  borderRadius: 'calc(var(--radius) - 2px)',
  backgroundColor: 'transparent',
  paddingInline: '0.75rem',
  paddingBlock: '0.625rem',
  fontSize: '1rem',
  lineHeight: 1.5,
  transitionProperty: 'color, box-shadow',
  transitionTimingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)',
  transitionDuration: '150ms',
  outlineStyle: 'none',
  '@media (min-width: 48rem)': { fontSize: '0.875rem', lineHeight: 'calc(1.25 / 0.875)' },
})
const pushRight = css({ marginLeft: 'auto' })

export function InputGroupCustom() {
  return () => (
    <div mix={gridStyles}>
      <InputGroup>
        <textarea
          data-slot="input-group-control"
          placeholder="Autoresize textarea..."
          mix={autosizeStyles}
        />
        <InputGroupAddon align="block-end">
          <InputGroupButton size="sm" variant="default" mix={pushRight}>
            Submit
          </InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Label

import { css } from 'remix/component'

import { InfoIcon } from '#app/ui/icons.tsx'
import {
  InputGroup,
  InputGroupAddon,
import { css } from 'remix/component'

import { InfoIcon } from '#app/ui/icons.tsx'
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  inputGroupButtonVariants,
} from '#app/ui/input-group.tsx'
import { Label } from '#app/ui/label.tsx'
import { Tooltip, TooltipContent, TooltipTrigger } from '#app/ui/tooltip.tsx'

const gridStyles = css({ display: 'grid', width: '100%', maxWidth: '24rem', gap: '1rem' })
const foregroundStyles = css({ color: 'var(--foreground)' })
const helpButtonStyles = css({ marginLeft: 'auto', borderRadius: '9999px' })

export function InputGroupLabel() {
  return () => (
    <div mix={gridStyles}>
      <InputGroup>
        <InputGroupInput id="email" placeholder="shadcn" />
        <InputGroupAddon>
          <Label htmlFor="email">@</Label>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput id="email-2" placeholder="shadcn@vercel.com" />
        <InputGroupAddon align="block-start">
          <Label htmlFor="email-2" mix={foregroundStyles}>
            Email
          </Label>
          <Tooltip>
            <TooltipTrigger
              aria-label="Help"
              data-slot="button"
              data-size="icon-xs"
              mix={[inputGroupButtonVariants({ variant: 'ghost', size: 'icon-xs' }), helpButtonStyles]}
            >
              <InfoIcon />
            </TooltipTrigger>
            <TooltipContent>
              <p>We&apos;ll use this to send you notifications</p>
            </TooltipContent>
          </Tooltip>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Tooltip

import { css } from 'remix/component'

import { HelpCircleIcon, InfoIcon } from '#app/ui/icons.tsx'
import {
  InputGroup,
  InputGroupAddon,
import { css } from 'remix/component'

import { HelpCircleIcon, InfoIcon } from '#app/ui/icons.tsx'
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  inputGroupButtonVariants,
} from '#app/ui/input-group.tsx'
import { Tooltip, TooltipContent, TooltipTrigger } from '#app/ui/tooltip.tsx'

const gridStyles = css({ display: 'grid', width: '100%', maxWidth: '24rem', gap: '1rem' })

export function InputGroupTooltip() {
  return () => (
    <div mix={gridStyles}>
      <InputGroup>
        <InputGroupInput placeholder="Enter password" type="password" />
        <InputGroupAddon align="inline-end">
          <Tooltip>
            <TooltipTrigger
              aria-label="Info"
              data-slot="button"
              data-size="icon-xs"
              mix={inputGroupButtonVariants({ variant: 'ghost', size: 'icon-xs' })}
            >
              <InfoIcon />
            </TooltipTrigger>
            <TooltipContent>
              <p>Password must be at least 8 characters</p>
            </TooltipContent>
          </Tooltip>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput placeholder="Your email address" />
        <InputGroupAddon align="inline-end">
          <Tooltip>
            <TooltipTrigger
              aria-label="Help"
              data-slot="button"
              data-size="icon-xs"
              mix={inputGroupButtonVariants({ variant: 'ghost', size: 'icon-xs' })}
            >
              <HelpCircleIcon />
            </TooltipTrigger>
            <TooltipContent>
              <p>We&apos;ll use this to send you notifications</p>
            </TooltipContent>
          </Tooltip>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput placeholder="Enter API key" />
        <InputGroupAddon>
          <Tooltip>
            <TooltipTrigger
              aria-label="Help"
              data-slot="button"
              data-size="icon-xs"
              mix={inputGroupButtonVariants({ variant: 'ghost', size: 'icon-xs' })}
            >
              <HelpCircleIcon />
            </TooltipTrigger>
            <TooltipContent side="left">
              <p>Click for help with API keys</p>
            </TooltipContent>
          </Tooltip>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

API Reference

InputGroup

PropTypeDefault
mixMixValue-

InputGroupAddon

PropTypeDefault
alignInputGroupAddonAlign"inline-start"
mixMixValue-

InputGroupButton

PropTypeDefault
sizeInputGroupButtonSize"xs"
variantButtonVariant"ghost"
mixMixValue-

InputGroupText

PropTypeDefault
mixMixValue-

InputGroupInput

PropTypeDefault
mixMixValue-

InputGroupTextarea

PropTypeDefault
mixMixValue-