Item 컴포넌트는 거의 모든 유형의 콘텐츠를 담을 수 있는 간단한 플렉스 컨테이너입니다. 제목, 설명 및 액션을 표시하는 데 사용하세요. ItemGroup 컴포넌트와 함께 사용하여 아이템 목록을 만들 수 있습니다.
div 요소와 몇 가지 클래스로 동일한 결과를 얻을 수 있지만, 너무 많이 만들어서 컴포넌트로 만들기로 했습니다. 이제 항상 사용합니다.
제목과 설명이 있는 간단한 아이템입니다.
<script lang="ts">
import * as Item from "$lib/components/ui/item/index.js";
import { Button } from "$lib/components/ui/button/index.js";
import BadgeCheckIcon from "@lucide/svelte/icons/badge-check";
import ChevronRightIcon from "@lucide/svelte/icons/chevron-right";
</script>
<div class="flex w-full max-w-md flex-col gap-6">
<Item.Root variant="outline">
<Item.Content>
<Item.Title>기본 아이템</Item.Title>
<Item.Description
>제목과 설명이 있는 간단한 아이템입니다.</Item.Description
>
</Item.Content>
<Item.Actions>
<Button variant="outline" size="sm">작업</Button>
</Item.Actions>
</Item.Root>
<Item.Root variant="outline" size="sm">
{#snippet child({ props })}
<a href="#/" {...props}>
<Item.Media>
<BadgeCheckIcon class="size-5" />
</Item.Media>
<Item.Content>
<Item.Title>프로필이 인증되었습니다.</Item.Title>
</Item.Content>
<Item.Actions>
<ChevronRightIcon class="size-4" />
</Item.Actions>
</a>
{/snippet}
</Item.Root>
</div> 설치
다음 코드를 프로젝트에 복사하여 붙여넣으세요.
사용법
<script lang="ts">
import * as Item from "$lib/components/ui/item/index.js";
</script> <Item.Root>
<Item.Header>Item Header</Item.Header>
<Item.Media />
<Item.Content>
<Item.Title>Item</Item.Title>
<Item.Description>Item</Item.Description>
</Item.Content>
<Item.Actions />
<Item.Footer>Item Footer</Item.Footer>
</Item.Root> Item vs Field
체크박스, 입력, 라디오 또는 셀렉트와 같은 폼 입력을 표시해야 하는 경우 Field를 사용하세요.
제목, 설명 및 액션과 같은 콘텐츠만 표시하면 되는 경우 Item을 사용하세요.
예제
변형
은은한 배경과 테두리가 있는 표준 스타일입니다.
명확한 테두리와 투명한 배경이 있는 아웃라인 스타일입니다.
보조 콘텐츠를 위한 절제된 색상의 차분한 외관입니다.
<script lang="ts">
import * as Item from "$lib/components/ui/item/index.js";
import { Button } from "$lib/components/ui/button/index.js";
</script>
<div class="flex flex-col gap-6">
<Item.Root>
<Item.Content>
<Item.Title>기본 변형</Item.Title>
<Item.Description
>은은한 배경과 테두리가 있는 표준 스타일입니다.</Item.Description
>
</Item.Content>
<Item.Actions>
<Button variant="outline" size="sm">열기</Button>
</Item.Actions>
</Item.Root>
<Item.Root variant="outline">
<Item.Content>
<Item.Title>아웃라인 변형</Item.Title>
<Item.Description>
명확한 테두리와 투명한 배경이 있는 아웃라인 스타일입니다.
</Item.Description>
</Item.Content>
<Item.Actions>
<Button variant="outline" size="sm">열기</Button>
</Item.Actions>
</Item.Root>
<Item.Root variant="muted">
<Item.Content>
<Item.Title>뮤트 변형</Item.Title>
<Item.Description
>보조 콘텐츠를 위한 절제된 색상의 차분한 외관입니다.</Item.Description
>
</Item.Content>
<Item.Actions>
<Button variant="outline" size="sm">열기</Button>
</Item.Actions>
</Item.Root>
</div> 크기
Item 컴포넌트는 다양한 사용 사례에 맞는 여러 크기를 제공합니다. 예를 들어 컴팩트한 아이템에는 sm 크기를 사용하고 표준 아이템에는 기본 크기를 사용할 수 있습니다.
제목과 설명이 있는 간단한 아이템입니다.
<script lang="ts">
import * as Item from "$lib/components/ui/item/index.js";
import { Button } from "$lib/components/ui/button/index.js";
import BadgeCheckIcon from "@lucide/svelte/icons/badge-check";
import ChevronRightIcon from "@lucide/svelte/icons/chevron-right";
</script>
<div class="flex w-full max-w-md flex-col gap-6">
<Item.Root variant="outline">
<Item.Content>
<Item.Title>기본 아이템</Item.Title>
<Item.Description
>제목과 설명이 있는 간단한 아이템입니다.</Item.Description
>
</Item.Content>
<Item.Actions>
<Button variant="outline" size="sm">작업</Button>
</Item.Actions>
</Item.Root>
<Item.Root variant="outline" size="sm">
{#snippet child({ props })}
<a href="#/" {...props}>
<Item.Media>
<BadgeCheckIcon class="size-5" />
</Item.Media>
<Item.Content>
<Item.Title>프로필이 인증되었습니다.</Item.Title>
</Item.Content>
<Item.Actions>
<ChevronRightIcon class="size-4" />
</Item.Actions>
</a>
{/snippet}
</Item.Root>
</div> 아이콘
알 수 없는 기기에서 새로운 로그인이 감지되었습니다.
<script lang="ts">
import * as Item from "$lib/components/ui/item/index.js";
import { Button } from "$lib/components/ui/button/index.js";
import ShieldAlertIcon from "@lucide/svelte/icons/shield-alert";
</script>
<div class="flex w-full max-w-lg flex-col gap-6">
<Item.Root variant="outline">
<Item.Media variant="icon">
<ShieldAlertIcon />
</Item.Media>
<Item.Content>
<Item.Title>보안 알림</Item.Title>
<Item.Description
>알 수 없는 기기에서 새로운 로그인이 감지되었습니다.</Item.Description
>
</Item.Content>
<Item.Actions>
<Button size="sm" variant="outline">확인</Button>
</Item.Actions>
</Item.Root>
</div> 아바타
5개월 전 마지막 접속
이 프로젝트에서 협업할 팀을 초대하세요.
<script lang="ts">
import * as Item from "$lib/components/ui/item/index.js";
import * as Avatar from "$lib/components/ui/avatar/index.js";
import { Button } from "$lib/components/ui/button/index.js";
import Plus from "@lucide/svelte/icons/plus";
</script>
<div class="flex w-full max-w-lg flex-col gap-6">
<Item.Root variant="outline">
<Item.Media>
<Avatar.Root class="size-10">
<Avatar.Image src="https://github.com/evilrabbit.png" />
<Avatar.Fallback>ER</Avatar.Fallback>
</Avatar.Root>
</Item.Media>
<Item.Content>
<Item.Title>Evil Rabbit</Item.Title>
<Item.Description>5개월 전 마지막 접속</Item.Description>
</Item.Content>
<Item.Actions>
<Button
size="icon"
variant="outline"
class="rounded-full"
aria-label="초대"
>
<Plus />
</Button>
</Item.Actions>
</Item.Root>
<Item.Root variant="outline">
<Item.Media>
<div
class="*:data-[slot=avatar]:ring-background flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:grayscale"
>
<Avatar.Root class="hidden sm:flex">
<Avatar.Image src="https://github.com/shadcn.png" alt="@shadcn" />
<Avatar.Fallback>CN</Avatar.Fallback>
</Avatar.Root>
<Avatar.Root class="hidden sm:flex">
<Avatar.Image
src="https://github.com/maxleiter.png"
alt="@maxleiter"
/>
<Avatar.Fallback>LR</Avatar.Fallback>
</Avatar.Root>
<Avatar.Root>
<Avatar.Image
src="https://github.com/evilrabbit.png"
alt="@evilrabbit"
/>
<Avatar.Fallback>ER</Avatar.Fallback>
</Avatar.Root>
</div>
</Item.Media>
<Item.Content>
<Item.Title>팀 멤버 없음</Item.Title>
<Item.Description
>이 프로젝트에서 협업할 팀을 초대하세요.</Item.Description
>
</Item.Content>
<Item.Actions>
<Button size="sm" variant="outline">초대</Button>
</Item.Actions>
</Item.Root>
</div> 이미지
<script lang="ts">
import * as Item from "$lib/components/ui/item/index.js";
const music = [
{
title: "한밤의 도시 불빛",
artist: "네온 드림스",
album: "일렉트릭 나이츠",
duration: "3:45"
},
{
title: "커피숍 대화",
artist: "더 모닝 브루",
album: "도시 이야기",
duration: "4:05"
},
{
title: "디지털 레인",
artist: "사이버 심포니",
album: "바이너리 비트",
duration: "3:30"
}
];
</script>
<div class="flex w-full max-w-md flex-col gap-6">
<div class="flex w-full max-w-md flex-col gap-4">
{#each music as song (song)}
<Item.Root variant="outline">
{#snippet child({ props })}
<a href="#/" {...props}>
<Item.Media variant="image">
<img
src={`https://avatar.vercel.sh/${song.title}`}
alt={song.title}
width="32"
height="32"
class="size-8 rounded object-cover grayscale"
/>
</Item.Media>
<Item.Content>
<Item.Title class="line-clamp-1">
{song.title} -
<span class="text-muted-foreground">{song.album}</span>
</Item.Title>
<Item.Description>{song.artist}</Item.Description>
</Item.Content>
<Item.Content class="flex-none text-center">
<Item.Description>{song.duration}</Item.Description>
</Item.Content>
</a>
{/snippet}
</Item.Root>
{/each}
</div>
</div> 그룹
shadcn@vercel.com
maxleiter@vercel.com
evilrabbit@vercel.com
<script lang="ts">
import * as Item from "$lib/components/ui/item/index.js";
import * as Avatar from "$lib/components/ui/avatar/index.js";
import { Button } from "$lib/components/ui/button/index.js";
import Plus from "@lucide/svelte/icons/plus";
const people = [
{
username: "shadcn",
avatar: "https://github.com/shadcn.png",
email: "shadcn@vercel.com"
},
{
username: "maxleiter",
avatar: "https://github.com/maxleiter.png",
email: "maxleiter@vercel.com"
},
{
username: "evilrabbit",
avatar: "https://github.com/evilrabbit.png",
email: "evilrabbit@vercel.com"
}
];
</script>
<div class="flex w-full max-w-md flex-col gap-6">
<Item.Group>
{#each people as person, index (person.username)}
<Item.Root>
<Item.Media>
<Avatar.Root>
<Avatar.Image src={person.avatar} class="grayscale" />
<Avatar.Fallback>{person.username.charAt(0)}</Avatar.Fallback>
</Avatar.Root>
</Item.Media>
<Item.Content class="gap-1">
<Item.Title>{person.username}</Item.Title>
<Item.Description>{person.email}</Item.Description>
</Item.Content>
<Item.Actions>
<Button variant="ghost" size="icon" class="rounded-full">
<Plus />
</Button>
</Item.Actions>
</Item.Root>
{#if index !== people.length - 1}
<Item.Separator />
{/if}
{/each}
</Item.Group>
</div> 헤더
일상적인 작업 및 UI 생성.
고급 사고 또는 추론.
모두를 위한 오픈 소스 모델.
<script lang="ts">
import * as Item from "$lib/components/ui/item/index.js";
const models = [
{
name: "v0-1.5-sm",
description: "일상적인 작업 및 UI 생성.",
image:
"https://images.unsplash.com/photo-1650804068570-7fb2e3dbf888?q=80&w=640&auto=format&fit=crop",
credit: "Valeria Reverdo on Unsplash"
},
{
name: "v0-1.5-lg",
description: "고급 사고 또는 추론.",
image:
"https://images.unsplash.com/photo-1610280777472-54133d004c8c?q=80&w=640&auto=format&fit=crop",
credit: "Michael Oeser on Unsplash"
},
{
name: "v0-2.0-mini",
description: "모두를 위한 오픈 소스 모델.",
image:
"https://images.unsplash.com/photo-1602146057681-08560aee8cde?q=80&w=640&auto=format&fit=crop",
credit: "Cherry Laithang on Unsplash"
}
];
</script>
<div class="flex w-full max-w-xl flex-col gap-6">
<Item.Group class="grid grid-cols-3 gap-4">
{#each models as model (model.name)}
<Item.Root variant="outline">
<Item.Header>
<img
src={model.image}
alt={model.name}
width="128"
height="128"
class="aspect-square w-full rounded-sm object-cover"
/>
</Item.Header>
<Item.Content>
<Item.Title>{model.name}</Item.Title>
<Item.Description>{model.description}</Item.Description>
</Item.Content>
</Item.Root>
{/each}
</Item.Group>
</div> 링크
아이템을 링크로 렌더링하려면 child 스니펫을 사용하세요. 호버 및 포커스 상태가 앵커 요소에 적용됩니다.
<script lang="ts">
import * as Item from "$lib/components/ui/item/index.js";
import ChevronRightIcon from "@lucide/svelte/icons/chevron-right";
import ExternalLinkIcon from "@lucide/svelte/icons/external-link";
</script>
<div class="flex w-full max-w-md flex-col gap-4">
<Item.Root>
{#snippet child({ props })}
<a href="#/" {...props}>
<Item.Content>
<Item.Title>문서 방문하기</Item.Title>
<Item.Description>컴포넌트 시작 방법을 알아보세요.</Item.Description>
</Item.Content>
<Item.Actions>
<ChevronRightIcon class="size-4" />
</Item.Actions>
</a>
{/snippet}
</Item.Root>
<Item.Root variant="outline">
{#snippet child({ props })}
<a href="#/" target="_blank" rel="noopener noreferrer" {...props}>
<Item.Content>
<Item.Title>외부 리소스</Item.Title>
<Item.Description
>보안 속성과 함께 새 탭에서 열립니다.</Item.Description
>
</Item.Content>
<Item.Actions>
<ExternalLinkIcon class="size-4" />
</Item.Actions>
</a>
{/snippet}
</Item.Root>
</div> 드롭다운
<script lang="ts">
import * as Item from "$lib/components/ui/item/index.js";
import * as Avatar from "$lib/components/ui/avatar/index.js";
import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js";
import { Button } from "$lib/components/ui/button/index.js";
import ChevronDown from "@lucide/svelte/icons/chevron-down";
const people = [
{
username: "shadcn",
avatar: "https://github.com/shadcn.png",
email: "shadcn@vercel.com"
},
{
username: "maxleiter",
avatar: "https://github.com/maxleiter.png",
email: "maxleiter@vercel.com"
},
{
username: "evilrabbit",
avatar: "https://github.com/evilrabbit.png",
email: "evilrabbit@vercel.com"
}
];
</script>
<div class="flex min-h-64 w-full max-w-md flex-col items-center gap-6">
<DropdownMenu.Root>
<DropdownMenu.Trigger>
{#snippet child({ props })}
<Button {...props} variant="outline" size="sm" class="w-fit">
선택 <ChevronDown />
</Button>
{/snippet}
</DropdownMenu.Trigger>
<DropdownMenu.Content class="w-72 [--radius:0.65rem]" align="end">
{#each people as person (person.username)}
<DropdownMenu.Item class="p-0">
<Item.Root size="sm" class="w-full p-2">
<Item.Media>
<Avatar.Root class="size-8">
<Avatar.Image src={person.avatar} class="grayscale" />
<Avatar.Fallback>{person.username.charAt(0)}</Avatar.Fallback>
</Avatar.Root>
</Item.Media>
<Item.Content class="gap-0.5">
<Item.Title>{person.username}</Item.Title>
<Item.Description>{person.email}</Item.Description>
</Item.Content>
</Item.Root>
</DropdownMenu.Item>
{/each}
</DropdownMenu.Content>
</DropdownMenu.Root>
</div>