Grasco
Profile Picture UI

Events

Event reference for ProfilePicture and ProfilePictureGroup components

ProfilePicture Events

EventPayloadDescription
loadImage loaded successfully
errorImage failed to load
cdn-error{ error: string }CDN image failed to load
profile-picture-click{ extCustomerId?, alt?, src? }Avatar clicked (requires interactive.pressable)

The profile-picture-click event only fires when interactive.pressable is set to true.

<ProfilePicture
  extCustomerId="demo-user-1769431807927-pd9dtmn1"
  alt="Kerry Nicholson"
  interactive={{ pressable: true }}
  onLoad={() => console.log('Image loaded')}
  onError={() => console.log('Image failed')}
  onCdnError={(e) => console.log('CDN error:', e.error)}
  onClick={(detail) => console.log('Clicked:', detail)}
/>
DOM EventReact Prop
loadonLoad
erroronError
cdn-erroronCdnError
profile-picture-clickonClick
<profile-picture
  id="avatar"
  ext-customer-id="demo-user-1769431807927-pd9dtmn1"
  alt="Kerry Nicholson"
  interactive='{"pressable": true}'
></profile-picture>

<script>
  const avatar = document.getElementById('avatar');
  avatar.addEventListener('load', () => console.log('Image loaded'));
  avatar.addEventListener('error', () => console.log('Image failed'));
  avatar.addEventListener('cdn-error', (e) => console.log('CDN error:', e.detail.error));
  avatar.addEventListener('profile-picture-click', (e) => console.log('Clicked:', e.detail));
</script>
<template>
  <profile-picture
    ext-customer-id="demo-user-1769431807927-pd9dtmn1"
    alt="Kerry Nicholson"
    :interactive="JSON.stringify({ pressable: true })"
    @load="handleLoad"
    @error="handleError"
    @profile-picture-click="handleClick"
  />
</template>
@Component({
  template: `
    <profile-picture
      ext-customer-id="demo-user-1769431807927-pd9dtmn1"
      alt="Kerry Nicholson"
      [attr.interactive]="interactiveJson"
      (load)="onLoad()"
      (error)="onError()"
      (profile-picture-click)="onClick($event)"
    ></profile-picture>
  `,
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AvatarComponent {
  interactiveJson = JSON.stringify({ pressable: true });
  onLoad() { console.log('loaded'); }
  onError() { console.log('error'); }
  onClick(e: CustomEvent) { console.log('clicked', e.detail); }
}
<profile-picture
  ext-customer-id="demo-user-1769431807927-pd9dtmn1"
  alt="Kerry Nicholson"
  interactive='{"pressable": true}'
  on:load={() => console.log('loaded')}
  on:error={() => console.log('error')}
  on:profile-picture-click={(e) => console.log('clicked', e.detail)}
/>

ProfilePictureGroup Events

EventPayloadDescription
avatar-clickGroupUserDataAvatar clicked
avatar-hoverGroupUserDataAvatar hovered
counter-click{ hiddenUsers: GroupUserData[], open: boolean }Counter clicked
dropdown-item-clickGroupUserDataDropdown item clicked
add-clickAdd button clicked
<ProfilePictureGroup
  max={3}
  size="lg"
  showAddButton
  onAvatarClick={(user) => console.log('Avatar:', user.name)}
  onAvatarHover={(user) => console.log('Hover:', user.name)}
  onCounterClick={(hiddenUsers, open) => console.log('Counter:', { hiddenUsers, open })}
  onDropdownItemClick={(user) => console.log('Dropdown:', user.name)}
  onAddClick={() => console.log('Add clicked')}
>
  {users.map(u => (
    <ProfilePicture key={u.id} extCustomerId={u.id} alt={u.name} data-user-id={u.id} />
  ))}
</ProfilePictureGroup>
DOM EventReact Prop
avatar-clickonAvatarClick
avatar-hoveronAvatarHover
counter-clickonCounterClick
dropdown-item-clickonDropdownItemClick
add-clickonAddClick
<profile-picture-group id="group" max="3" size="lg" show-add-button>
  <profile-picture ext-customer-id="demo-user-1769431807927-pd9dtmn1" alt="Kerry Nicholson" data-user-id="demo-user-1769431807927-pd9dtmn1"></profile-picture>
  <profile-picture ext-customer-id="demo-user-1769429613186-q8x65t0" alt="Sarah Chen" data-user-id="demo-user-1769429613186-q8x65t0"></profile-picture>
  <profile-picture ext-customer-id="demo-user-1769430228786-ompo3g1" alt="Emma Liu" data-user-id="demo-user-1769430228786-ompo3g1"></profile-picture>
  <profile-picture ext-customer-id="demo-user-1769430441537-fs5i098" alt="Marcus Webb" data-user-id="demo-user-1769430441537-fs5i098"></profile-picture>
</profile-picture-group>

<script>
  const group = document.getElementById('group');
  group.addEventListener('avatar-click', (e) => console.log('Avatar:', e.detail));
  group.addEventListener('counter-click', (e) => console.log('Counter:', e.detail));
  group.addEventListener('dropdown-item-click', (e) => console.log('Dropdown:', e.detail));
  group.addEventListener('add-click', () => console.log('Add clicked'));
</script>

GroupUserData Interface

Event payloads for group events use the GroupUserData interface, automatically constructed from ProfilePicture children attributes.

interface GroupUserData {
  /** Value of the data-user-id attribute */
  id: string;
  /** Value of the alt prop */
  name: string;
  /** Value of the src prop */
  src?: string;
  /** Value of the data-status attribute */
  status?: string;
}

Set data-user-id and data-status on each ProfilePicture child to populate event data:

<ProfilePicture
  extCustomerId="demo-user-1769431807927-pd9dtmn1"
  alt="Kerry Nicholson"
  data-user-id="demo-user-1769431807927-pd9dtmn1"
  data-status="online"
/>

On this page