Item
A versatile component used to display any content.
A simple item with title and description.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ItemExample() -> impl IntoView { view! { <div class="flex w-full max-w-md flex-col gap-6"> <Item variant="outline"> <ItemContent> <ItemTitle>"Basic Item"</ItemTitle> <ItemDescription>"A simple item with title and description."</ItemDescription> </ItemContent> <ItemActions> <Button variant="outline" size="sm"> "Action" </Button> </ItemActions> </Item> <a href="#"> <Item variant="outline" size="sm"> <ItemMedia>{icon!(icondata::LuBadgeCheck, class="size-5")}</ItemMedia> <ItemContent class="block"> <ItemTitle>"Your profile has been verified."</ItemTitle> </ItemContent> <ItemActions>{icon!(icondata::LuChevronRight, class="size-4")}</ItemActions> </Item> </a> </div> } }
Variants
Standard styling with subtle background and borders.
Outlined style with clear borders and transparent background.
Subdued appearance with muted colors for secondary content.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ItemVariantsExample() -> impl IntoView { view! { <div class="flex flex-col gap-6"> <Item> <ItemContent> <ItemTitle>"Default Variant"</ItemTitle> <ItemDescription> "Standard styling with subtle background and borders." </ItemDescription> </ItemContent> <ItemActions> <Button variant="outline" size="sm"> "Open" </Button> </ItemActions> </Item> <Item variant="outline"> <ItemContent> <ItemTitle>"Outline Variant"</ItemTitle> <ItemDescription> "Outlined style with clear borders and transparent background." </ItemDescription> </ItemContent> <ItemActions> <Button variant="outline" size="sm"> "Open" </Button> </ItemActions> </Item> <Item variant="muted"> <ItemContent> <ItemTitle>"Muted Variant"</ItemTitle> <ItemDescription> "Subdued appearance with muted colors for secondary content." </ItemDescription> </ItemContent> <ItemActions> <Button variant="outline" size="sm"> "Open" </Button> </ItemActions> </Item> </div> } }
Icon
New login detected from unknown device.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ItemIconExample() -> impl IntoView { view! { <div class="flex w-full max-w-lg flex-col gap-6"> <Item variant="outline"> <ItemMedia variant="icon">{icon!(icondata::LuShieldAlert)}</ItemMedia> <ItemContent> <ItemTitle>"Security Alert"</ItemTitle> <ItemDescription>"New login detected from unknown device."</ItemDescription> </ItemContent> <ItemActions> <Button size="sm" variant="outline"> "Review" </Button> </ItemActions> </Item> </div> } }
Avatar
Last seen 5 months ago
Invite your team to collaborate on this project.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ItemAvatarExample() -> impl IntoView { view! { <div class="flex w-full max-w-lg flex-col gap-6"> <Item variant="outline"> <ItemMedia> <Avatar class="size-10"> <AvatarImage src="https://github.com/evilrabbit.png" /> </Avatar> </ItemMedia> <ItemContent> <ItemTitle>"Evil Rabbit"</ItemTitle> <ItemDescription>"Last seen 5 months ago"</ItemDescription> </ItemContent> <ItemActions> <Button size="icon-sm" variant="outline" class="rounded-full" aria_label="Invite" > {icon!(icondata::LuPlus)} </Button> </ItemActions> </Item> <Item variant="outline"> <ItemMedia> <div class="*:ring-(--background) flex -space-x-2 *:ring-2 *:grayscale"> <Avatar class="flex"> <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" /> </Avatar> <Avatar class="flex"> <AvatarImage src="https://github.com/maxleiter.png" alt="@maxleiter" /> </Avatar> <Avatar> <AvatarImage src="https://github.com/evilrabbit.png" alt="@evilrabbit" /> </Avatar> </div> </ItemMedia> <ItemContent> <ItemTitle>"No Team Members"</ItemTitle> <ItemDescription> "Invite your team to collaborate on this project." </ItemDescription> </ItemContent> <ItemActions> <Button size="sm" variant="outline"> "Invite" </Button> </ItemActions> </Item> </div> } }
Image
use leptos::prelude::*; use singlestage::*; #[derive(Clone)] struct Song { title: String, artist: String, album: String, duration: String, } #[component] pub fn ItemImageExample() -> impl IntoView { let music = RwSignal::new(vec![ Song { title: "Midnight City Lights".to_string(), artist: "Neon Dreams".to_string(), album: "Electric Nights".to_string(), duration: "3:45".to_string(), }, Song { title: "Coffee Shop Conversations".to_string(), artist: "The Morning Brew".to_string(), album: "Urban Stories".to_string(), duration: "4:05".to_string(), }, Song { title: "Digital Rain".to_string(), artist: "Cyber Symphony".to_string(), album: "Binary Beats".to_string(), duration: "3:30".to_string(), }, ]); view! { <div class="flex w-full max-w-md flex-col gap-6"> <ItemGroup class="gap-4"> <For each=move || music.get() key=|song| song.title.clone() let(song)> { let song_title = song.title.clone(); view! { <a href="#" role="listitem"> <Item variant="outline"> <ItemMedia variant="image"> <img src=format!("https://avatar.vercel.sh/{}", song.title) alt=song.title width=32 height=32 class="object-cover grayscale" /> </ItemMedia> <ItemContent> <ItemTitle class="line-clamp-1"> {song_title} " - " <span class="text-(--muted-foreground)">{song.album}</span> </ItemTitle> <ItemDescription>{song.artist}</ItemDescription> </ItemContent> <ItemContent class="flex-none text-center"> <ItemDescription>{song.duration}</ItemDescription> </ItemContent> </Item> </a> } } </For> </ItemGroup> </div> } }
Group
shadcn@vercel.com
maxleiter@vercel.com
evilrabbit@vercel.com
use leptos::prelude::*; use singlestage::*; #[derive(Clone)] struct Person { username: String, avatar: String, email: String, } #[component] pub fn ItemGroupExample() -> impl IntoView { let people = RwSignal::new(vec![ Person { username: "shadcn".to_string(), avatar: "https://github.com/shadcn.png".to_string(), email: "shadcn@vercel.com".to_string(), }, Person { username: "maxleiter".to_string(), avatar: "https://github.com/maxleiter.png".to_string(), email: "maxleiter@vercel.com".to_string(), }, Person { username: "evilrabbit".to_string(), avatar: "https://github.com/evilrabbit.png".to_string(), email: "evilrabbit@vercel.com".to_string(), }, ]); view! { <div class="flex w-full max-w-md flex-col gap-6"> <ItemGroup> <For each=move || people.get() key=|person| person.username.clone() let(person)> { let username = person.username.clone(); view! { <Item> <ItemMedia> <Avatar> <AvatarImage src=person.avatar class="grayscale" /> </Avatar> </ItemMedia> <ItemContent class="gap-1"> <ItemTitle>{person.username}</ItemTitle> <ItemDescription>{person.email}</ItemDescription> </ItemContent> <ItemActions> <Button variant="ghost" size="icon" class="rounded-full"> {icon!(icondata::LuPlus)} </Button> </ItemActions> </Item> {if username.as_str() != "evilrabbit" { view! { <ItemSeparator /> } .into_any() } else { "".into_any() }} } } </For> </ItemGroup> </div> } }
Header
Everyday tasks and UI generation.
Advanced thinking or reasoning.
Open Source model for everyone.
use leptos::prelude::*; use singlestage::*; #[derive(Clone)] struct Model { name: String, description: String, image: String, credit: String, } #[component] pub fn ItemHeaderExample() -> impl IntoView { let models = RwSignal::new(vec![ Model { name: "v0-1.5-sm".to_string(), description: "Everyday tasks and UI generation.".to_string(), image: "https://images.unsplash.com/photo-1650804068570-7fb2e3dbf888?q=80&w=640&auto=format&fit=crop".to_string(), credit: "Valeria Reverdo on Unsplash".to_string(), }, Model { name: "v0-1.5-lg".to_string(), description: "Advanced thinking or reasoning.".to_string(), image: "https://images.unsplash.com/photo-1610280777472-54133d004c8c?q=80&w=640&auto=format&fit=crop".to_string(), credit: "Michael Oeser on Unsplash".to_string(), }, Model { name: "v0-2.0-mini".to_string(), description: "Open Source model for everyone.".to_string(), image: "https://images.unsplash.com/photo-1602146057681-08560aee8cde?q=80&w=640&auto=format&fit=crop".to_string(), credit: "Cherry Laithang on Unsplash".to_string(), }, ]); view! { <div class="flex w-full max-w-xl flex-col gap-6"> <ItemGroup class="grid grid-cols-3 gap-4"> <For each=move || models.get() key=|model| model.name.clone() let(model)> { let model_name = model.name.clone(); view! { <Item variant="outline"> <ItemHeader> <Tooltip value=model.credit> <img src=model.image alt=model.name width=128 height=128 class="aspect-square w-full rounded-sm object-cover" /> </Tooltip> </ItemHeader> <ItemContent> <ItemTitle>{model_name}</ItemTitle> <ItemDescription>{model.description}</ItemDescription> </ItemContent> </Item> } } </For> </ItemGroup> </div> } }
Link
use leptos::prelude::*; use singlestage::*; #[component] pub fn ItemLinkExample() -> impl IntoView { view! { <div class="flex w-full max-w-md flex-col gap-4"> <a href="#"> <Item> <ItemContent> <ItemTitle>"Visit our documentation"</ItemTitle> <ItemDescription> "Learn how to get started with our components." </ItemDescription> </ItemContent> <ItemActions>{icon!(icondata::LuChevronRight, class="size-4")}</ItemActions> </Item> </a> <a href="#" target="_blank" rel="noopener noreferrer"> <Item variant="outline"> <ItemContent> <ItemTitle>"External resource"</ItemTitle> <ItemDescription> "Opens in a new tab with security attributes." </ItemDescription> </ItemContent> <ItemActions>{icon!(icondata::LuExternalLink, class="size-4")}</ItemActions> </Item> </a> </div> } }
Dropdown
use leptos::prelude::*; use singlestage::*; #[derive(Clone)] struct Person { username: String, avatar: String, email: String, } #[component] pub fn ItemDropdownExample() -> impl IntoView { let people = RwSignal::new(vec![ Person { username: "shadcn".to_string(), avatar: "https://github.com/shadcn.png".to_string(), email: "shadcn@vercel.com".to_string(), }, Person { username: "maxleiter".to_string(), avatar: "https://github.com/maxleiter.png".to_string(), email: "maxleiter@vercel.com".to_string(), }, Person { username: "evilrabbit".to_string(), avatar: "https://github.com/evilrabbit.png".to_string(), email: "evilrabbit@vercel.com".to_string(), }, ]); view! { <div class="flex min-h-64 w-full max-w-md flex-col items-center gap-6"> <DropdownMenu> <DropdownMenuTrigger> <Button variant="outline" size="sm" class="w-fit"> "Select" {icon!(icondata::LuChevronDown)} </Button> </DropdownMenuTrigger> <DropdownMenuContent class="w-72 [--radius:0.65rem]"> <For each=move || people.get() key=|person| person.username.clone() let(person)> <DropdownMenuItem class="p-0"> <Item size="sm" class="w-full p-2"> <ItemMedia> <Avatar class="size-8"> <AvatarImage src=person.avatar class="grayscale" /> </Avatar> </ItemMedia> <ItemContent class="gap-0.5"> <ItemTitle>{person.username}</ItemTitle> <ItemDescription>{person.email}</ItemDescription> </ItemContent> </Item> </DropdownMenuItem> </For> </DropdownMenuContent> </DropdownMenu> </div> } }
Anatomy
Import all parts and piece them together.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ItemAnatomy() -> impl IntoView { view! { <ItemGroup> <Item> <ItemMedia /> <ItemHeader /> <ItemContent> <ItemTitle /> <ItemDescription /> </ItemContent> <ItemActions> <Button /> </ItemActions> <ItemFooter /> </Item> <ItemSeparator /> </ItemGroup> } }
API Reference
Item
Contains the contents of an Item.
| Name | Type | Default | Description |
|---|---|---|---|
| size | String | "default" | Set the display size of the Item. |
| variant | String | "default" | Set the display variant of the Item. |
ItemMedia
Contains media content such as an icon or image for an Item.
| Name | Type | Default | Description |
|---|---|---|---|
| variant | String | "default" | Set the display variant of the ItemMedia. |
ItemSeparator
Separates Item content.
| Name | Type | Default | Description |
|---|---|---|---|
| vertical | bool | false | Toggle whether or not the separator should display vertically. |