Skip to content
ilinxa/pro-ui

Author Card

alphav0.2.0

Person identity card — avatar, name, role, optional bio, optionally clickable.

Category: MarketingUpdated: 2026-08-11Created: 2026-05-02Author: ilinxa

Context

Surfaces authorship context next to a piece of content: news article sidebars, blog post bylines, doc page authors, team listings, comment headers, contributor cards. Sized for sidebars (works at ~280px and up). Avatar is image-or-icon-fallback; the whole card optionally renders as a link via polymorphic root + href. Same visual rhythm as newsletter-signup / category-cloud / filter-bar — composes cleanly in the same sidebar.

Installation

Initialize shadcn (once per project)Seeds lib/utils.ts and components.json. Skip if you've already used any shadcn component.
pnpm dlx shadcn@latest init
Install the component
pnpm dlx shadcn@latest add @ilinxa/author-card

Add -fixtures for dummy data:

pnpm dlx shadcn@latest add @ilinxa/author-card-fixtures

CLI can't resolve @ilinxa? The namespace is listed in the official shadcn registry directory, so current CLIs need no configuration. If yours can't resolve it (older or pinned versions, self-hosted mirrors), register it manually in components.json:

"registries": {
  "@ilinxa": "https://ui.ilinxa.com/r/{name}.json"
}

Preview

About the author

Anonymous Contributor

Guest Writer

Writes occasionally about local environmental stories.

Demo source

demo.tsxtsx
"use client"; import { Users } from "lucide-react";import { Tabs, TabsContent, TabsTrigger } from "@/components/ui/tabs";import { SwipeTabsList } from "@/components/site/swipe-tabs-list";import { AuthorCard } from "./author-card";import { AUTHOR_CARD_DUMMY } from "./dummy-data"; export default function AuthorCardDemo() {  return (    <Tabs defaultValue="default" className="w-full">      <SwipeTabsList>        <TabsTrigger value="default">Default</TabsTrigger>        <TabsTrigger value="with-image">With image</TabsTrigger>        <TabsTrigger value="clickable">Clickable</TabsTrigger>        <TabsTrigger value="muted">Muted tone</TabsTrigger>        <TabsTrigger value="i18n">Turkish content</TabsTrigger>      </SwipeTabsList>       <TabsContent value="default" className="mt-6 max-w-md">        <AuthorCard {...AUTHOR_CARD_DUMMY.withoutImage} />      </TabsContent>       <TabsContent value="with-image" className="mt-6 max-w-md">        <AuthorCard {...AUTHOR_CARD_DUMMY.withImage} />      </TabsContent>       <TabsContent value="clickable" className="mt-6 max-w-md">        <AuthorCard {...AUTHOR_CARD_DUMMY.clickable} />        <p className="mt-3 text-xs text-muted-foreground">          Hover the card or focus it with the keyboard — the whole surface is a          link to <code>/team/daniel-park</code>.        </p>      </TabsContent>       <TabsContent value="muted" className="mt-6 max-w-md">        <AuthorCard          {...AUTHOR_CARD_DUMMY.collective}          tone="muted"          fallbackIcon={Users}        />      </TabsContent>       <TabsContent value="i18n" className="mt-6 max-w-md">        <AuthorCard {...AUTHOR_CARD_DUMMY.turkish} />      </TabsContent>    </Tabs>  );} 

Usage

When to use

A small "person identity" block — avatar, name, role, optional bio — to surface authorship context next to a piece of content. Reach for it on news article sidebars, blog post bylines, doc page authors, team listings, comment headers, contributor cards.

It's a single card, not a list. Sized for sidebars (works at ~280px and up). Optionally clickable as a whole — pass href+ your router's link component to make the entire surface navigate.

Basic example

import { AuthorCard } from "@/components/author-card"

export function Example() {
  return (
    <AuthorCard
      name="Maya Chen"
      role="Senior Editor"
      bio="Specializes in sustainable urbanism and environmental journalism."
      imageSrc="/authors/maya.jpg"
      imageAlt="Maya Chen"
    />
  )
}

Clickable card

Pass href to make the whole surface navigate. By default the root renders as a native <a>; pass linkComponent for router-aware links.

import Link from "next/link"
import { AuthorCard } from "@/components/author-card"

<AuthorCard
  name="Daniel Park"
  role="Product Designer"
  bio="Currently designing onboarding flows."
  imageSrc="/team/daniel.jpg"
  href="/team/daniel-park"
  linkComponent={Link}
/>

No image — fallback icon

When imageSrc is omitted, a tinted circle with a Lucide User icon renders. Override the icon via fallbackIcon for non-person bylines (e.g. Users for collectives).

import { Users } from "lucide-react"

<AuthorCard
  name="The Editorial Team"
  role="Collective"
  bio="Reporting from across the newsroom."
  fallbackIcon={Users}
  tone="muted"
/>

i18n

All visible chrome strings live in labels; English defaults ship in AUTHOR_CARD_DEFAULT_LABELS. The card text content (name, role, bio) is consumer data — pass localized strings directly.

<AuthorCard
  name="Aylin Demir"
  role="Kıdemli Editör"
  bio="Sürdürülebilir şehircilik ve çevre konularında uzmanlaşmış."
  labels={{ heading: "Yazar Hakkında" }}
/>

Notes

  • The component is exported as React.memo. For memoization to hold, pass stable references for linkComponent / fallbackIcon(don't create them inline on every render).
  • The avatar image uses loading="lazy". Broken srcshows the browser's default broken-image icon — ensure URLs are valid (consumer responsibility).
  • When the card is clickable, the accessible name is the author's name (via aria-labelledby). The heading text reads as a decorative label.
  • Use headingAsto fit the card under your page's landmark structure — most sidebars want h3 (the default).

Features

  • Image-or-icon-fallback avatar
  • 3 tones (primary / accent / muted)
  • Polymorphic root — pass href + linkComponent to make the whole card a link
  • Custom fallback icon via fallbackIcon prop (e.g. Users for collectives)
  • Configurable heading level (h2 / h3 / h4)
  • i18n via labels prop with English defaults
  • Memoized; SSR-safe; lazy-loaded image

Tags

author-cardauthorbylineprofilecardmarketing

Dependencies

npm peer deps: lucide-react@^1.11.0