ATOM
Components (registry)Surfaces

UserProfile

Avatar plus name and optional meta in one block. Account headers and people cards.

Preview

Editorial

<!-- F12c editorial — non-derivable only. Review: Karen. -->

## Ejemplos

Account header block:

```tsx import { UserProfile } from '@/components/atoms/UserProfile';

<UserProfile name="Ada Lovelace" org="Analytical Engines" avatar={{ type: 'initials', size: 's' }} /> ```

## Accesibilidad

- `name` is required. Initials default from the name; when using image avatars, pass meaningful `alt` via `avatar` props. - Treat as a presentational cluster — interactive menus belong on a surrounding button/menu, not only on the faces.

## Cuándo no usar

- Single avatar without name/org → `Avatar`. - Dense assignee stacks → `AvatarGroup`.

## Criterio de uso

- Usa UserProfile como identidad, no como menu: si necesita acciones, envuelvelo en `DropdownMenu`. - El nombre es lo minimo indispensable; `org` solo aporta cuando el usuario pertenece a varias. - En sidebar colapsado se reduce a avatar: la inicial o imagen debe seguir identificando sin el texto.

## Gotchas

- Sin imagen cae a iniciales: nombres de una sola palabra dan una inicial, y con pocos usuarios eso deja de distinguir. - El avatar no es un boton: si es clickeable, el elemento interactivo lo pone el contenedor.

Uso

import { UserProfile } from '@/components/atoms/UserProfile';

<UserProfile name="Ada Lovelace" org="Analytical Engines" avatar={{ type: 'initials', size: 's' }} />

Props

  • name: string (required)
  • org: string
  • avatar: Omit<AvatarProps, 'className'>

Gotchas

  • react

    name is required. avatar spreads Avatar props; initials default from name words. org is optional subtitle.

  • a11y

    Ensure Avatar gets a meaningful alt/aria via avatar props when using image type.

Anatomía CSS

<div class="user-profile">
  <span class="user-profile__info"></span>
  <span class="user-profile__name"></span>
  <span class="user-profile__org"></span>
</div>
ClasePropósito
user-profileroot
user-profile__infoelement
user-profile__nameelement
user-profile__orgelement

Tokens resueltos

Valores finales tras seguir la cadena de tokens. Derivados del source: si un token cambia, esta tabla cambia sola.

VariantePropValorToken
allhover-bg#f5f5f5muted
allfg#525252muted.foreground

Animaciones

PropiedadDuraciónEasing
background-color0.15scubic-bezier(0.19
1
0.22
1)
opacity0.2sease
width0.2sease

CSS mínimo funcional

Autocontenido: sin imports ni tokens. Para previews y prototipos — en producción se consume el CSS del DS (@atom-uikit/css/components.css</code>, <code>@atom-uikit/tokens/tokens.css).

/* -------------------------------------------------------------------------
   User Profile (Molecule)

   Avatar + name + org/role in a row. Collapses to avatar-only
   when parent constrains width (e.g., sidebar collapsed).

   Composes: Avatar atom.
   Used in: sidebar footer, dropdowns, settings pages.
   ------------------------------------------------------------------------- */

.user-profile {
  display: flex;
  align-items: center;
  gap: 8px;
  overflow: hidden;
  cursor: pointer;
  padding: 4px;
  border-radius: 8px;
  text-decoration: none;
  transition: background-color 0.15s cubic-bezier(0.19, 1, 0.22, 1);
}

.user-profile:hover {
  background-color: #f5f5f5;
}

.user-profile__info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow: hidden;
  min-width: 0;
  transition: opacity 0.2s ease, width 0.2s ease;
}

.user-profile__name {
  font-family: 'inter tight', -apple-system, blinkmacsystemfont, 'segoe ui', roboto, helvetica, arial, sans-serif, ui-sans-serif, system-ui, sans-serif;
  font-size: 12.8px;
  font-weight: 500;
  line-height: 1;
  color: #0a0a0a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.user-profile__org {
  font-family: 'inter tight', -apple-system, blinkmacsystemfont, 'segoe ui', roboto, helvetica, arial, sans-serif, ui-sans-serif, system-ui, sans-serif;
  font-size: 10.24px;
  font-weight: 400;
  line-height: 1;
  color: #525252;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Collapses in sidebar collapsed state */
.sidebar--collapsed .user-profile__info {
  opacity: 0;
  width: 0;
  overflow: hidden;
}

.sidebar--collapsed .user-profile {
  padding: 4px;
  justify-content: center;
  overflow: visible;
}

Codigo fuente

components-react
components/atoms/UserProfile.tsx
import { Avatar, type AvatarProps } from '../atoms/Avatar';

export type UserProfileProps = {
  name: string;
  org?: string;
  avatar?: Omit<AvatarProps, 'className'>;
  className?: string;
};

function cn(...classes: (string | false | undefined | null)[]) {
  return classes.filter(Boolean).join(' ');
}

export function UserProfile({
  name,
  org,
  avatar,
  className,
}: UserProfileProps) {
  return (
    <div className={cn('user-profile', className)}>
      <Avatar
        type="initials"
        shape="square"
        size="s"
        status
        {...avatar}
        initials={avatar?.initials || name.split(' ').map((w) => w[0]).join('').slice(0, 2).toUpperCase()}
      />
      <div className="user-profile__info" data-sidebar-user-info="">
        <span className="user-profile__name">{name}</span>
        {org && <span className="user-profile__org">{org}</span>}
      </div>
    </div>
  );
}

Webflow

Webflowuser-profile

Pega en el Designer como application/json, luego convierte a Component (Atom / UserProfile) y publica. Formato interno no documentado de Webflow — regenerable, no dependencia de runtime.

Setup del sitio (una vez)

Custom Code → Head:

<link rel="stylesheet" href="https://atom-web-ds.vercel.app/v1/tokens.css">
<link rel="stylesheet" href="https://atom-web-ds.vercel.app/v1/components.css">

Unsupported (no silencioso)

  • selector on .sidebar--collapsed .user-profile__infocompound/descendant selector — moved to head Custom Code (Designer styles are single-class)
  • selector on .sidebar--collapsed .user-profilecompound/descendant selector — moved to head Custom Code (Designer styles are single-class)

Tras pegar: Create component → nombre Atom / UserProfile → Publish.

On this page

Detalles

Publicado14 de mayo de 2026
Categoriasurfaces
Lectura...
Visitas...
Ayuda?Slack

Componente

UserProfile

Source

components-react / cssDisponible via MCP: atom_uikit_source("user-profile")
Abrir en Storybook