52% 사용됨
<script lang="ts">
import IconCheck from "@tabler/icons-svelte/icons/check";
import IconInfoCircle from "@tabler/icons-svelte/icons/info-circle";
import IconPlus from "@tabler/icons-svelte/icons/plus";
import * as InputGroup from "$lib/components/ui/input-group/index.js";
import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js";
import * as Tooltip from "$lib/components/ui/tooltip/index.js";
import { Separator } from "$lib/components/ui/separator/index.js";
import SearchIcon from "@lucide/svelte/icons/search";
import ArrowUpIcon from "@lucide/svelte/icons/arrow-up";
</script>
<div class="grid w-full max-w-sm gap-6">
<InputGroup.Root>
<InputGroup.Input placeholder="검색..." />
<InputGroup.Addon>
<SearchIcon />
</InputGroup.Addon>
<InputGroup.Addon align="inline-end">12개 결과</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Input placeholder="example.com" class="!ps-1" />
<InputGroup.Addon>
<InputGroup.Text>https://</InputGroup.Text>
</InputGroup.Addon>
<InputGroup.Addon align="inline-end">
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<InputGroup.Button {...props} class="rounded-full" size="icon-xs">
<IconInfoCircle />
</InputGroup.Button>
{/snippet}
</Tooltip.Trigger>
<Tooltip.Content>툴팁 내용입니다.</Tooltip.Content>
</Tooltip.Root>
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Textarea placeholder="질문, 검색 또는 채팅..." />
<InputGroup.Addon align="block-end">
<InputGroup.Button variant="outline" class="rounded-full" size="icon-xs">
<IconPlus />
</InputGroup.Button>
<DropdownMenu.Root>
<DropdownMenu.Trigger>
{#snippet child({ props })}
<InputGroup.Button {...props} variant="ghost"
>자동</InputGroup.Button
>
{/snippet}
</DropdownMenu.Trigger>
<DropdownMenu.Content
side="top"
align="start"
class="[--radius:0.95rem]"
>
<DropdownMenu.Item>자동</DropdownMenu.Item>
<DropdownMenu.Item>에이전트</DropdownMenu.Item>
<DropdownMenu.Item>수동</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Root>
<InputGroup.Text class="ms-auto">52% 사용됨</InputGroup.Text>
<Separator orientation="vertical" class="!h-4" />
<InputGroup.Button
variant="default"
class="rounded-full"
size="icon-xs"
disabled
>
<ArrowUpIcon />
<span class="sr-only">전송</span>
</InputGroup.Button>
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Input placeholder="@shadcn" />
<InputGroup.Addon align="inline-end">
<div
class="bg-primary text-primary-foreground flex size-4 items-center justify-center rounded-full"
>
<IconCheck class="size-3" />
</div>
</InputGroup.Addon>
</InputGroup.Root>
</div> 설치
@lucide/svelte 설치:
다음 코드를 프로젝트에 복사하여 붙여넣으세요.
사용법
<script lang="ts">
import * as InputGroup from "$lib/components/ui/input-group/index.js";
import SearchIcon from "@lucide/svelte/icons/search";
</script> <InputGroup.Root>
<InputGroup.Input placeholder="검색..." />
<InputGroup.Addon>
<SearchIcon />
</InputGroup.Addon>
<InputGroup.Addon align="inline-end">
<InputGroup.Button>검색</InputGroup.Button>
</InputGroup.Addon>
</InputGroup.Root> 예제
아이콘
<script lang="ts">
import * as InputGroup from "$lib/components/ui/input-group/index.js";
import CheckIcon from "@lucide/svelte/icons/check";
import CreditCardIcon from "@lucide/svelte/icons/credit-card";
import InfoIcon from "@lucide/svelte/icons/info";
import MailIcon from "@lucide/svelte/icons/mail";
import SearchIcon from "@lucide/svelte/icons/search";
import StarIcon from "@lucide/svelte/icons/star";
</script>
<div class="grid w-full max-w-sm gap-6">
<InputGroup.Root>
<InputGroup.Input placeholder="검색..." />
<InputGroup.Addon>
<SearchIcon />
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Input type="email" placeholder="이메일 입력" />
<InputGroup.Addon>
<MailIcon />
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Input placeholder="카드 번호" />
<InputGroup.Addon>
<CreditCardIcon />
</InputGroup.Addon>
<InputGroup.Addon align="inline-end">
<CheckIcon />
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Input placeholder="카드 번호" />
<InputGroup.Addon align="inline-end">
<StarIcon />
<InfoIcon />
</InputGroup.Addon>
</InputGroup.Root>
</div> 텍스트
입력과 함께 추가 텍스트 정보를 표시합니다.
120자 남음
<script lang="ts">
import * as InputGroup from "$lib/components/ui/input-group/index.js";
</script>
<div class="grid w-full max-w-sm gap-6">
<InputGroup.Root>
<InputGroup.Addon>
<InputGroup.Text>$</InputGroup.Text>
</InputGroup.Addon>
<InputGroup.Input placeholder="0.00" />
<InputGroup.Addon align="inline-end">
<InputGroup.Text>USD</InputGroup.Text>
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Addon>
<InputGroup.Text>https://</InputGroup.Text>
</InputGroup.Addon>
<InputGroup.Input placeholder="example.com" class="!ps-0.5" />
<InputGroup.Addon align="inline-end">
<InputGroup.Text>.com</InputGroup.Text>
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Input placeholder="사용자명 입력" />
<InputGroup.Addon align="inline-end">
<InputGroup.Text>@company.com</InputGroup.Text>
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Textarea placeholder="메시지 입력" />
<InputGroup.Addon align="block-end">
<InputGroup.Text class="text-muted-foreground text-xs"
>120자 남음</InputGroup.Text
>
</InputGroup.Addon>
</InputGroup.Root>
</div> 버튼
입력 그룹 내에서 액션을 수행하기 위한 버튼을 추가합니다.
<script lang="ts">
import IconCheck from "@tabler/icons-svelte/icons/check";
import IconCopy from "@tabler/icons-svelte/icons/copy";
import IconInfoCircle from "@tabler/icons-svelte/icons/info-circle";
import IconStar from "@tabler/icons-svelte/icons/star";
import * as InputGroup from "$lib/components/ui/input-group/index.js";
import * as Popover from "$lib/components/ui/popover/index.js";
import { UseClipboard } from "$lib/hooks/use-clipboard.svelte.js";
let isFavorite = $state(false);
const clipboard = new UseClipboard();
</script>
<div class="grid w-full max-w-sm gap-6">
<InputGroup.Root>
<InputGroup.Input placeholder="https://x.com/shadcn" readonly />
<InputGroup.Addon align="inline-end">
<InputGroup.Button
aria-label="Copy"
title="Copy"
size="icon-xs"
onclick={() => clipboard.copy("https://x.com/shadcn")}
>
{#if clipboard.copied}
<IconCheck />
{:else}
<IconCopy />
{/if}
</InputGroup.Button>
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root class="[--radius:9999px]">
<Popover.Root>
<Popover.Trigger>
{#snippet child({ props })}
<InputGroup.Addon>
<InputGroup.Button {...props} variant="secondary" size="icon-xs">
<IconInfoCircle />
</InputGroup.Button>
</InputGroup.Addon>
{/snippet}
</Popover.Trigger>
<Popover.Content
align="start"
class="flex flex-col gap-1 rounded-xl text-sm"
>
<p class="font-medium">연결이 안전하지 않습니다.</p>
<p>이 사이트에 민감한 정보를 입력하지 마세요.</p>
</Popover.Content>
</Popover.Root>
<InputGroup.Addon class="text-muted-foreground ps-1.5">
<InputGroup.Text>https://</InputGroup.Text>
</InputGroup.Addon>
<InputGroup.Input />
<InputGroup.Addon align="inline-end">
<InputGroup.Button
onclick={() => (isFavorite = !isFavorite)}
size="icon-xs"
>
<IconStar class={isFavorite ? "fill-blue-600 stroke-blue-600" : ""} />
</InputGroup.Button>
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Input placeholder="검색어 입력..." />
<InputGroup.Addon align="inline-end">
<InputGroup.Button variant="secondary">검색</InputGroup.Button>
</InputGroup.Addon>
</InputGroup.Root>
</div> 툴팁
추가 컨텍스트나 도움말을 제공하기 위해 툴팁을 추가합니다.
<script lang="ts">
import * as InputGroup from "$lib/components/ui/input-group/index.js";
import * as Tooltip from "$lib/components/ui/tooltip/index.js";
import HelpCircleIcon from "@lucide/svelte/icons/help-circle";
import InfoIcon from "@lucide/svelte/icons/info";
</script>
<div class="grid w-full max-w-sm gap-4">
<InputGroup.Root>
<InputGroup.Input placeholder="비밀번호 입력" type="password" />
<InputGroup.Addon align="inline-end">
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<InputGroup.Button
{...props}
variant="ghost"
aria-label="Info"
size="icon-xs"
>
<InfoIcon />
</InputGroup.Button>
{/snippet}
</Tooltip.Trigger>
<Tooltip.Content>
<p>비밀번호는 최소 8자 이상이어야 합니다</p>
</Tooltip.Content>
</Tooltip.Root>
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Input placeholder="이메일 주소" />
<InputGroup.Addon align="inline-end">
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<InputGroup.Button
{...props}
variant="ghost"
aria-label="Help"
size="icon-xs"
>
<HelpCircleIcon />
</InputGroup.Button>
{/snippet}
</Tooltip.Trigger>
<Tooltip.Content>
<p>알림을 보내는 데 사용됩니다</p>
</Tooltip.Content>
</Tooltip.Root>
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Input placeholder="API 키 입력" />
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<InputGroup.Addon>
<InputGroup.Button
{...props}
variant="ghost"
aria-label="Help"
size="icon-xs"
>
<HelpCircleIcon />
</InputGroup.Button>
</InputGroup.Addon>
{/snippet}
</Tooltip.Trigger>
<Tooltip.Content side="left">
<p>API 키 관련 도움말 보기</p>
</Tooltip.Content>
</Tooltip.Root>
</InputGroup.Root>
</div> 텍스트영역
입력 그룹은 텍스트영역 컴포넌트와도 작동합니다. 정렬을 위해 block-start 또는 block-end를 사용하세요.
script.js
1행, 1열
<script lang="ts">
import IconBrandJavascript from "@tabler/icons-svelte/icons/brand-javascript";
import IconCopy from "@tabler/icons-svelte/icons/copy";
import IconCornerDownLeft from "@tabler/icons-svelte/icons/corner-down-left";
import IconRefresh from "@tabler/icons-svelte/icons/refresh";
import * as InputGroup from "$lib/components/ui/input-group/index.js";
</script>
<div class="grid w-full max-w-md gap-4">
<InputGroup.Root>
<InputGroup.Addon align="block-start" class="border-b">
<InputGroup.Text class="font-mono font-medium">
<IconBrandJavascript />
script.js
</InputGroup.Text>
<InputGroup.Button class="ms-auto" size="icon-xs">
<IconRefresh />
</InputGroup.Button>
<InputGroup.Button variant="ghost" size="icon-xs">
<IconCopy />
</InputGroup.Button>
</InputGroup.Addon>
<InputGroup.Textarea
placeholder="console.log('Hello, world!');"
class="min-h-[200px]"
/>
<InputGroup.Addon align="block-end" class="border-t">
<InputGroup.Text>1행, 1열</InputGroup.Text>
<InputGroup.Button size="sm" class="ms-auto" variant="default">
실행 <IconCornerDownLeft />
</InputGroup.Button>
</InputGroup.Addon>
</InputGroup.Root>
</div> 스피너
입력을 처리하는 동안 로딩 인디케이터를 표시합니다.
<script lang="ts">
import * as InputGroup from "$lib/components/ui/input-group/index.js";
import { Spinner } from "$lib/components/ui/spinner/index.js";
import LoaderIcon from "@lucide/svelte/icons/loader";
</script>
<div class="grid w-full max-w-sm gap-4">
<InputGroup.Root data-disabled>
<InputGroup.Input placeholder="검색 중..." disabled />
<InputGroup.Addon align="inline-end">
<Spinner />
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root data-disabled>
<InputGroup.Input placeholder="처리 중..." disabled />
<InputGroup.Addon>
<Spinner />
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root data-disabled>
<InputGroup.Input placeholder="변경사항 저장 중..." disabled />
<InputGroup.Addon align="inline-end">
<InputGroup.Text>저장 중...</InputGroup.Text>
<Spinner />
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root data-disabled>
<InputGroup.Input placeholder="데이터 새로고침 중..." disabled />
<InputGroup.Addon>
<LoaderIcon class="animate-spin" />
</InputGroup.Addon>
<InputGroup.Addon align="inline-end">
<InputGroup.Text class="text-muted-foreground"
>잠시만 기다려 주세요...</InputGroup.Text
>
</InputGroup.Addon>
</InputGroup.Root>
</div> 라벨
접근성을 향상시키기 위해 입력 그룹 내에 라벨을 추가합니다.
<script lang="ts">
import * as InputGroup from "$lib/components/ui/input-group/index.js";
import * as Label from "$lib/components/ui/label/index.js";
import * as Tooltip from "$lib/components/ui/tooltip/index.js";
import InfoIcon from "@lucide/svelte/icons/info";
</script>
<div class="grid w-full max-w-sm gap-4">
<InputGroup.Root>
<InputGroup.Input id="email" placeholder="shadcn" />
<InputGroup.Addon>
<Label.Root for="email">@</Label.Root>
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root>
<InputGroup.Input id="email-2" placeholder="shadcn@vercel.com" />
<InputGroup.Addon align="block-start">
<Label.Root for="email-2" class="text-foreground">이메일</Label.Root>
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<InputGroup.Button
{...props}
variant="ghost"
aria-label="Help"
class="ms-auto rounded-full"
size="icon-xs"
>
<InfoIcon />
</InputGroup.Button>
{/snippet}
</Tooltip.Trigger>
<Tooltip.Content>
<p>알림을 보내는 데 사용됩니다</p>
</Tooltip.Content>
</Tooltip.Root>
</InputGroup.Addon>
</InputGroup.Root>
</div> 드롭다운
복잡한 상호작용을 위해 입력 그룹과 드롭다운 메뉴를 함께 사용합니다.
<script lang="ts">
import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js";
import * as InputGroup from "$lib/components/ui/input-group/index.js";
import ChevronDownIcon from "@lucide/svelte/icons/chevron-down";
import MoreHorizontalIcon from "@lucide/svelte/icons/more-horizontal";
</script>
<div class="grid w-full max-w-sm gap-4">
<InputGroup.Root>
<InputGroup.Input placeholder="파일명 입력" />
<InputGroup.Addon align="inline-end">
<DropdownMenu.Root>
<DropdownMenu.Trigger>
{#snippet child({ props })}
<InputGroup.Button
{...props}
variant="ghost"
aria-label="More"
size="icon-xs"
>
<MoreHorizontalIcon />
</InputGroup.Button>
{/snippet}
</DropdownMenu.Trigger>
<DropdownMenu.Content align="end">
<DropdownMenu.Item>설정</DropdownMenu.Item>
<DropdownMenu.Item>경로 복사</DropdownMenu.Item>
<DropdownMenu.Item>위치 열기</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Root>
</InputGroup.Addon>
</InputGroup.Root>
<InputGroup.Root class="[--radius:1rem]">
<InputGroup.Input placeholder="검색어 입력" />
<InputGroup.Addon align="inline-end">
<DropdownMenu.Root>
<DropdownMenu.Trigger>
{#snippet child({ props })}
<InputGroup.Button
{...props}
variant="ghost"
class="!pe-1.5 text-xs"
>
검색 위치... <ChevronDownIcon class="size-3" />
</InputGroup.Button>
{/snippet}
</DropdownMenu.Trigger>
<DropdownMenu.Content align="end" class="[--radius:0.95rem]">
<DropdownMenu.Item>문서</DropdownMenu.Item>
<DropdownMenu.Item>블로그 포스트</DropdownMenu.Item>
<DropdownMenu.Item>변경 로그</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Root>
</InputGroup.Addon>
</InputGroup.Root>
</div> 버튼 그룹
프리픽스와 서픽스를 만들기 위해 입력 그룹을 버튼 그룹으로 감쌉니다.
<script lang="ts">
import * as ButtonGroup from "$lib/components/ui/button-group/index.js";
import * as InputGroup from "$lib/components/ui/input-group/index.js";
import * as Label from "$lib/components/ui/label/index.js";
import Link2Icon from "@lucide/svelte/icons/link-2";
</script>
<div class="grid w-full max-w-sm gap-6">
<ButtonGroup.Root>
<ButtonGroup.Text>
<Label.Root for="url">https://</Label.Root>
</ButtonGroup.Text>
<InputGroup.Root>
<InputGroup.Input id="url" />
<InputGroup.Addon align="inline-end">
<Link2Icon />
</InputGroup.Addon>
</InputGroup.Root>
<ButtonGroup.Text>.com</ButtonGroup.Text>
</ButtonGroup.Root>
</div> 커스텀 입력
자동 동작과 포커스 상태 처리를 위해 커스텀 입력에 data-slot="input-group-control" 속성을 추가하세요.
커스텀 입력에는 스타일이 적용되지 않습니다. class prop을 사용하여 직접 스타일을 적용하세요.
<script lang="ts">
import * as InputGroup from "$lib/components/ui/input-group/index.js";
</script>
<div class="grid w-full max-w-sm gap-6">
<InputGroup.Root>
<textarea
data-slot="input-group-control"
class="flex field-sizing-content min-h-16 w-full resize-none rounded-md bg-transparent px-3 py-2.5 text-base transition-[color,box-shadow] outline-none md:text-sm"
placeholder="자동 크기 조정 텍스트 영역..."
></textarea>
<InputGroup.Addon align="block-end">
<InputGroup.Button class="ms-auto" size="sm" variant="default"
>제출</InputGroup.Button
>
</InputGroup.Addon>
</InputGroup.Root>
</div>