Credit for a person built on Item, Avatar and Media: row, stack or profile layouts with an avatar or portrait, name, role and bio. Byline density credits one person; dense suits member lists.
The source comes with full access.
One payment of $149 ($49 for now) opens the source right here and lets the CLI install every paid component, with lifetime updates.
pnpm dlx shadcn add @01orbital/personnpx shadcn add @01orbital/personyarn shadcn add @01orbital/personbunx --bun shadcn add @01orbital/personPart of the 01orbital library. With a license, put ORBITAL_TOKEN in .env.local and the same command installs it (licensed install, pricing).
It lands at components/editorial/person.tsx, as source you own and edit.
import {
Person,
PersonAvatar,
PersonBio,
PersonContent,
PersonName,
PersonPortrait,
PersonRole,
} from "@/components/editorial/person"
import { AvatarImage } from "@/components/ui/avatar"
const PEOPLE = [
{
name: "Mara Castellanos",
role: "Co-founder, CEO",
image: "https://01orbital.dev/art/kit/celestograph-61495-roan-6b.png",
},
{
name: "Priya Raman",
role: "Head of design",
image: "https://01orbital.dev/art/kit/celestograph-9963-bloom-1b.png",
},
{
name: "Teodor Lindqvist",
role: "Co-founder, CTO",
bio: "Builds the tools our team uses every day, from the first prototype to the components we ship.",
image: "https://01orbital.dev/art/kit/celestograph-61495-gesso-6b.png",
},
] as const
export default function PersonDemo() {
return (
<div className="grid w-full max-w-3xl items-start gap-10 sm:grid-cols-2">
<Person>
<PersonAvatar>
<AvatarImage src={PEOPLE[0].image} alt="" />
</PersonAvatar>
<PersonContent>
<PersonName>{PEOPLE[0].name}</PersonName>
<PersonRole>{PEOPLE[0].role}</PersonRole>
</PersonContent>
</Person>
<Person variant="stack">
<PersonPortrait shape="circle" className="size-40">
<img src={PEOPLE[1].image} alt="" loading="lazy" />
</PersonPortrait>
<PersonContent>
<PersonName>{PEOPLE[1].name}</PersonName>
<PersonRole>{PEOPLE[1].role}</PersonRole>
</PersonContent>
</Person>
<Person variant="profile" className="sm:col-span-2">
<PersonPortrait className="w-52">
<img src={PEOPLE[2].image} alt="" loading="lazy" />
</PersonPortrait>
<PersonContent>
<PersonName>{PEOPLE[2].name}</PersonName>
<PersonRole>{PEOPLE[2].role}</PersonRole>
<PersonBio>{PEOPLE[2].bio}</PersonBio>
</PersonContent>
</Person>
</div>
)
}Person is built from 7 parts. In the example they nest like this:
Person
├─ PersonAvatar
├─ PersonContent
│ ├─ PersonName
│ ├─ PersonRole
│ └─ PersonBio
└─ PersonPortraitPerson: A person's picture, name and role, for a byline under a quote, a team card or a staff list. Put a PersonAvatar or PersonPortrait and a PersonContent inside. It renders a <div>; pass render={<li />} when it sits in a list.PersonAvatar: The round picture frame in Person: 56px, or 40px in a dense person. Put an AvatarImage or artwork inside and let it fill the frame, which clips it to the circle. The frame sets the size, so change it with className.PersonContent: The person's text: put a PersonName, a PersonRole and an optional PersonBio inside. In a profile person it wraps below the portrait when less than 16rem is left beside it.PersonName: The person's name, in semibold text. A long name wraps, not cut off.PersonRole: The person's role or job title, in muted text below PersonName.PersonBio: A short paragraph about the person, in muted text, set a little apart below PersonRole. It shows in full, never cut off.PersonPortrait: A larger picture of the person, for team cards and profiles. It is as wide as its container, in a 3:4 frame with a hairline outline. An <img> placed directly inside fills and crops to the frame.A person's picture, name and role, for a byline under a quote, a team card or a staff list. Put a PersonAvatar or PersonPortrait and a PersonContent inside. It renders a <div>; pass render={<li />} when it sits in a list.
row sets the picture beside the text and stack centers the text below it. profile sets the text beside a PersonPortrait when both fit and below it when they don't. The portrait is full width unless you give it a width, so by default the text sits below it. byline density (the default) gives a 56px avatar and 28px lines; dense gives a 40px avatar and 20px lines for compact lists. Person adds no space around itself; set the gap on the list that holds it.
Prop
Type
It also accepts the props of the Base UI part it wraps, and the HTML attributes of the element it renders.
The round picture frame in Person: 56px, or 40px in a dense person. Put an AvatarImage or artwork inside and let it fill the frame, which clips it to the circle. The frame sets the size, so change it with className.
It accepts the props of the Base UI part it wraps, and the HTML attributes of the element it renders.
The person's text: put a PersonName, a PersonRole and an optional PersonBio inside. In a profile person it wraps below the portrait when less than 16rem is left beside it.
It accepts the HTML attributes of the element it renders.
The person's name, in semibold text. A long name wraps, not cut off.
It accepts the HTML attributes of the element it renders.
The person's role or job title, in muted text below PersonName.
It accepts the HTML attributes of the element it renders.
A short paragraph about the person, in muted text, set a little apart below PersonRole. It shows in full, never cut off.
It accepts the HTML attributes of the element it renders.
A larger picture of the person, for team cards and profiles. It is as wide as its container, in a 3:4 frame with a hairline outline. An <img> placed directly inside fills and crops to the frame.
Prop
Type
It also accepts the props of the Base UI part it wraps, and the HTML attributes of the element it renders.
npm: class-variance-authority, cn. The CLI installs them for you.
Registry pieces it installs with it:
avataritemMilestones
Roadmap or company history as an ordered list on Grid, in grid or rows layout. Rules can be off, a top border per item, or one fading horizon line with dots; the current milestone's dot is filled.
Post
Blog post listing parts: a Grid list or divided column of posts, each made fully clickable by its title link, with cover media, dotted meta for date, category and author, title and clamped excerpt.