Info List
alphav0.2.0Card-framed list of icon-prefixed rows — primary and secondary text, optional actions, per-row links, comfortable and compact variants.
Context
Use for sidebar info cards on detail pages — Event Details, Contact, Address, Account Settings, Product Specs, Restaurant Info, Listing Attributes. Comfortable variant: stacked primary/secondary/action rows with separators (kasder Etkinlik Bilgileri pattern). Compact variant: inline single-line rows, no separators (kasder İletişim pattern). Migration origin: kasder kas-social-front-v0 events/[id]/page.tsx Etkinlik Bilgileri + İletişim sidebar cards.
Installation
pnpm dlx shadcn@latest init"registries": {
"@ilinxa": "https://ui.ilinxa.com/r/{name}.json"
}pnpm dlx shadcn@latest add @ilinxa/info-listAdd -fixtures for dummy data:
pnpm dlx shadcn@latest add @ilinxa/info-list-fixturesPreview
Etkinlik Bilgileri
31 Mayıs 2026 Pazar
09:00 - 18:00
İstanbul Kongre Merkezi
Darülbedai Caddesi No:3, 34367 Harbiye/Şişli/İstanbul
Haritada Gör500 Kişilik Kapasite
423 kişi kayıtlı
Demo source
Usage
When to use
Reach for InfoList for sidebar info cards on detail pages — Event Details, Contact Info, Address, Account Settings, Product Specs, Restaurant Info, Listing Attributes. Two visual flavors: comfortable (stacked primary / secondary / action with separators between rows) and compact(inline single-line rows, no separators).
Minimal example
import { InfoList } from "@/components/info-list";
import { Calendar, MapPin, Users } from "lucide-react";
<InfoList
heading="Event Details"
variant="comfortable"
items={[
{ id: "date", icon: Calendar, primary: "May 31, 2026", secondary: "09:00 - 18:00" },
{ id: "loc", icon: MapPin, primary: "Istanbul Conference Center", secondary: "Şişli/Istanbul" },
{ id: "cap", icon: Users, primary: "500-person capacity", secondary: "423 registered" },
]}
/>;Two variants
comfortable— stacked content (primary bold + secondary muted + optional action). Iconw-5 h-5 text-primary. Separators between rows by default. Use for sidebar info cards with rich per-row content.compact— inline single-line rows. Iconw-4 h-4 text-muted-foreground. No separators by default. Use for contact lists, footer columns, dense info summaries. Compact ignoressecondaryandaction— they imply a richer row than the variant supports.
Linked rows
Pass href per item to wrap primary in the polymorphic linkComponent. Consumer passes full URLs — no auto-prefixing for tel: / mailto:.
<InfoList
variant="compact"
items={[
{ id: "phone", icon: Phone, primary: "+90 (212) 555 0123", href: "tel:+902125550123" },
{ id: "email", icon: Mail, primary: "info@example.com", href: "mailto:info@example.com" },
]}
/>Action slot
Comfortable rows can render an actionReactNode below the secondary line — typically a link button (e.g. "View on map"):
{
id: "location",
icon: MapPin,
primary: event.location,
secondary: event.address,
action: (
<Button variant="link" className="px-0 h-auto">
View on map <ExternalLink className="w-3 h-3" />
</Button>
),
}Polymorphic linkComponent
import NextLink from "next/link";
<InfoList
variant="compact"
linkComponent={NextLink}
items={[
{ id: "profile", icon: User, primary: "View profile", href: "/profile" },
]}
/>Custom renderItem
Bypass the default row layout entirely with renderItem(item) — useful for swapping icon for an avatar, embedding a status badge, or any non-icon row anatomy:
<InfoList
items={items}
renderItem={(item) => (
<div className="flex items-center gap-3">
<Avatar src={people[item.id].image} />
<div>
<p className="font-medium">{item.primary}</p>
<p className="text-sm text-muted-foreground">{item.secondary}</p>
</div>
</div>
)}
/>Frame + separators
framed: true(default) — card chrome (bg-card rounded-2xl p-6 border). Passframed={false}for embedded use inside an existing card.separated— auto-defaults per variant: comfortable=true, compact=false. CSS top-border on each row except the first; override by passing the prop.
Empty state
Empty items array → renders emptyState if provided, else <p role="status"> with labels.emptyText(default "No information.").
Notes
- Renders
<ul role="list">; sectionaria-labelledbyresolves to the heading id (viauseId) when heading is supplied. - Decorative icons are
aria-hidden="true"; link's accessible name is the visibleprimarytext. - Heading defaults to
h3(sidebar info cards typically nest under pageh2). Bump viaheadingAs="h2"when standalone.
Features
- Two variants — comfortable (stacked, separators, w-5 primary icon) and compact (inline, no separators, w-4 muted icon)
- Required icon + primary; optional secondary + action + href per item
- Polymorphic per-row link via linkComponent (default 'a') — works with tel: / mailto: / etc.
- Frame toggle (framed=true card chrome / framed=false bare)
- Separator toggle (auto-defaults per variant; overridable)
- Custom renderItem slot for full row takeover
- Optional section heading with configurable level (h2/h3/h4)
- Soft-failure on optional fields
- Empty state slot + labels.emptyText fallback
- i18n via labels object
- <ul role='list'> semantics + section aria-labelledby
- Compact variant intentionally ignores secondary + action (documented limitation)