packages/react-components/react-persona/library/docs/Spec.md
Convergence epic issue: #24213
A Persona is a visual representation of a person or status that showcases an Avatar, PresenceBadge, or an Avatar with a PresenceBadge. This composite component is not a card, therefore it will not provide a visual board or a popup when the user hovers the Avatar.
Persona is used in PeoplePicker, Team's left rail and menus, chiclets, and Card.
Note: v8's Persona is a combination of v9's Persona and Avatar (v8's Persona has a sub-component PersonaCoin that would count as Avatar, but is not exposed.). In v9 we've taken the approach of having a single component Avatar and another component Persona.
v8's Persona has a sub-component PersonaCoin, the equivalent in v9 is an Avatar. Currently Avatar is able to display a PresenceBadge, but this behavior will be deprecated in favor of Persona having this behavior.
Persona has a slot for an Avatar and PresenceBadge, giving the user the ability to display an Avatar, a PresenceBadge, or Combine them into an Avatar with presence.
Persona with Avatar:
<Persona name="Kevin Sturgis" secondaryText="Software Engineer" />
Persona with PresenceBadge:
<Persona presenceOnly name="Kevin Sturgis" presence={{ status: 'offline', outOfOffice: true }} />
Persona with Avatar + PresenceBadge:
<Persona
name="Kevin Sturgis"
secondaryText="Software Engineer"
tertiaryText="Offline"
presence={{ status: 'offline', outOfOffice: true }}
/>
I will refer to the avatar and presence as content.
There are three position variants:
There are two vertical alignment variants:
There are 3 content variants:
There are 6 sizing variants: extra-small, small, medium, large, extra-large, huge.
Slots
root: The root slot for Persona.avatar: The Avatar to display and Persona's primary slot.presence: The PresenceBadge to display.primaryText: First line of text in Persona. By default its content will be the content of the name prop. It is highly encouraged to only use the name prop and only specify the content of primaryText when it is not a name.secondaryText: Second line of text in Persona.tertiaryText: Third line of text in Persona.quaternaryText: Fourth line of text in Persona.Types
To avoid the issue v8 has, a css grid will be used instead of a flexbox that requires a general wrapper and a text container wrapper.
const coin = presenceOnly
? slots.presence && <slots.presence {...slotProps.presence} />
: slots.avatar && <slots.avatar {...slotProps.avatar} />;
return (
<slots.root {...slotProps.root}>
{(textPosition === 'after' || textPosition === 'below') && coin}
{slots.primaryText && <slots.primaryText {...slotProps.primaryText} />}
{slots.secondaryText && <slots.secondaryText {...slotProps.secondaryText} />}
{slots.tertiaryText && <slots.tertiaryText {...slotProps.tertiaryText} />}
{slots.quaternaryText && <slots.quaternaryText {...slotProps.quaternaryText} />}
{textPosition === 'before' && coin}
</slots.root>
);
<div class="fui-Persona">
<div />
<span class="fui-Persona__primaryText"></span>
<span class="fui-Persona__secondaryText">Secondary Text</span>
<span class="fui-Persona__tertiaryText">Tertiary Text</span>
<span class="fui-Persona__quaternaryText">Quaternary Text</span>
</div>
See MIGRATION.md for details.
Explain how the component will behave in use, including:
aria-* or/androle. Avatar and Badge already accessible and the text labels won't need anything as well.