Team Member

Pro

The person block of a team roster: a photo frame, the name, the role, an optional bio and a row of social links. Stacked, inline or set over the photo, as a plain block or an outline card.

  • Lucía Ferrer

    Lucía Ferrer

    Co-founder & CEO

  • Marcus Obi

    Marcus Obi

    Design Engineer

  • Amara Nwosu

    Amara Nwosu

    Accessibility Lead

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Activate your Pro license (once per machine)npx koalaui-cli@latest login <key># Add this component (its dependencies come along)npx koalaui-cli@latest add team-member

Usage#

Compose the parts you need and leave the rest out: there is no showX prop. A roster without bios omits TeamMemberBio, one without links omits TeamMemberSocials, and a list with no photos omits the media altogether. TeamMemberMedia is a frame for whatever picture you pass it (an <img> or next/image), cropped to cover. A small face can be the Avatar component instead, which every layout treats the same way. Pass asChild to render the member as the <li> of your roster list.

Anatomy#

The root carries the layout, align and variant; the media frame carries the shape. Every part is optional.

import {  TeamMember,  TeamMemberMedia,  TeamMemberContent,  TeamMemberName,  TeamMemberRole,  TeamMemberBio,  TeamMemberSocials,  TeamMemberSocial,} from "@/components/ui/team-member"<TeamMember>  <TeamMemberMedia>…</TeamMemberMedia>  <TeamMemberContent>    <TeamMemberName />    <TeamMemberRole />    <TeamMemberBio />    <TeamMemberSocials>      <TeamMemberSocial label="…">…</TeamMemberSocial>    </TeamMemberSocials>  </TeamMemberContent></TeamMember>

Layouts#

stacked (the default) puts the photo above the copy, the portrait grid and the carousel card. inline puts a small photo beside it, the directory row, and scales the frame and its radius down with it. overlay sets the copy on the foot of the photo over a dark scrim, the wall of faces; the scrim is dark on every theme, so the names stay white and legible whatever the picture.

Lucía Ferrer

Co-founder & CEO

Marcus Obi

Design Engineer

Amara Nwosu

Accessibility Lead

Card#

variant="card" gives the member a box of its own: an inset ring on the page ground, no fill. Around a round face it pads 20px; around a photo that fills its width it insets the photo 8px, so the photo's 16px corner stays concentric with the card's 24px one, and the copy keeps its own 12px step. In a row of cards the links sit on each card's foot. Over a photograph the card becomes a floating panel inset from the foot instead of a scrim.

Lucía Ferrer

Co-founder & CEO

Started Koala after building the same button at three jobs.

Marcus Obi

Design Engineer

Amara Nwosu

Accessibility Lead

Marcus Obi

Design Engineer

AN

Amara Nwosu

Accessibility Lead

Shapes#

The frame's shape: a 4:5 portrait (the default), a 4:3 landscape, a square, or a circle. The first three fill their column; a circle holds the size you give it, since a round face stretched to a wide column would crowd the row.

portrait

landscape

square

circle

Alignment#

align="center" centres the frame, the copy and the links on the column, the shape for round portraits and centred rosters. start (the default) keeps everything on the left edge.

Lucía Ferrer

Co-founder & CEO

Marcus Obi

Design Engineer

API reference#

TeamMember

The root, a <div> that shares its layout and variant with every part through context. Forwards all native <div> props; every part accepts className, merged last.

PropTypeDefaultDescription
layout"stacked" | "inline" | "overlay""stacked"Photo above the copy, a small photo beside it, or the copy set on the photo's foot over a dark scrim.
align"start" | "center""start"center centres the frame, the copy and the links on the column.
variant"plain" | "card""plain"card draws an inset ring with no fill, insetting a filling photo 8px; over a photo it becomes a floating panel.
asChildbooleanfalseRender as the single child element, e.g. the <li> of a roster list.
Data attributeDescription
data-layout"stacked", "inline" or "overlay".

TeamMemberMedia

The photo frame: pass an <img> or next/image as its child, cropped to cover, with a hairline painted over it. Forwards all native <div> props.

PropTypeDefaultDescription
shape"portrait" | "landscape" | "square" | "circle""portrait"4:5, 4:3, 1:1 or round. The first three fill their column; a circle holds the size you give it (className="size-32").
Data attributeDescription
data-shapeThe frame's shape.
data-fillPresent on every shape but circle; a card reads it to inset the photo.

TeamMemberContent

Groups the name, role, bio and links into one block beside or over the photo. Forwards all native <div> props.

TeamMemberName

The person's name, an <h3>. Forwards all native <h3> props.

PropTypeDefaultDescription
asChildbooleanfalseRender your own element (another heading level) instead of the <h3>.

TeamMemberRole

Their role or title, on the muted ink. Forwards all native <p> props.

TeamMemberBio

A line or two about them, on the reading ink. Forwards all native <p> props.

TeamMemberSocials

The wrapping row of social links under the copy. Forwards all native <div> props.

TeamMemberSocial

One icon link, rendered as the icon-only ghost Button (32px box, 40px hit area, 44px on touch). Forwards all native <a> props.

PropTypeDefaultDescription
label*string-The accessible name and the hover tooltip, e.g. "Lucía on LinkedIn".
asChildbooleanfalseRender the child element as the link, e.g. to wrap next/link.

teamMemberVariants

The tv recipe behind every part, for styling a block of your own to match.

FAQ#

An inset ring on an image is drawn under it, so it never shows. The frame paints its hairline with an ::after overlay instead, in pure black or white at 10%: a tinted neutral would pick up the photo's colour and read as dirt on its edge.