Default

Loading interactive example. Full source is available below.

View example source
Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { PersonaProps } from "@coreai-ds/react-components";
import type { JSXElement } from "@coreai-ds/react-components";
import { Persona } from "@coreai-ds/react-components";
import * as React from 'react';

export const Default = (props: Partial<PersonaProps>): JSXElement => {
    return (<Persona name="Kevin Sturgis" secondaryText="Available" presence={{ status: 'available' }} avatar={{
            image: {
                src: 'https://res-1.cdn.office.net/files/fabric-cdn-prod_20230815.002/office-ui-fabric-react-assets/persona-male.png',
            },
        }} {...props}/>);
};

export default Default;

Resources

Best practices

Do

  • Use a persona for brief, at-a-glance information about a person.
  • Use presence-only presentation when layout space is confined.
  • Add explicit states and keyboard behavior when adding interactions.

Don't

  • Overload text slots with detailed information.
  • Assume a persona has interaction states by default.
  • Add periods to persona text slots.

Behavior and states

  • Text slots wrap to the next line when the container becomes too small.
  • Use presenceOnly in confined layouts to remove the avatar and show the presence badge near the person’s name.
  • Personas are static by default and don’t have states built in.
  • Personas usually include an avatar, a presence badge, and up to four lines of text content that provide additional data about that person.
API referenceGenerated CoreAI prop and type summaries

API

Generated CoreAI prop summaries, not replacement type declarations. Most native DOM/event and ARIA props are omitted. ? means optional; JSDoc shows defaults, deprecations, and conditional requirements. Defaults assume the standard CoreAI provider.

Persona API

A Persona is a visual representation of a person or status that showcases an Avatar, PresenceBadge, or an Avatar with a PresenceBadge.

interface PersonaProps {
  as?: "div";

  /**
   * Avatar to display.
   *
   * If a PresenceBadge and an Avatar are provided, the Avatar will display the PresenceBadge as its presence.
   */
  avatar?: WithSlotShorthandValue<Omit<ComponentProps<AvatarSlots>, "color"> & { active?: "active" | "inactive" | "unset"; activeAppearance?: "ring" | "shadow" | "ring-shadow"; color?: "brand" | "neutral" | "colorful" | AvatarNamedColor | undefined; idForColor?: string | undefined; name?: string | undefined; shape?: AvatarShape | undefined; size?: AvatarSize | undefined; } & RefAttributes<HTMLSpanElement>> | null | undefined;

  children?: any;

  className?: string;

  /**
   * The name of the person or entity represented by the Persona.
   *
   * When `primaryText` is not provided, this will be used as the default value for `primaryText`.
   */
  name?: string;

  /**
   * PresenceBadge to display.
   *
   * If `presenceOnly` is true, the PresenceBadge will be displayed instead of the Avatar.
   */
  presence?: WithSlotShorthandValue<Omit<ComponentProps<Pick<BadgeSlots, "root" | "icon">>, "color"> & Pick<BadgeProps, "size"> & { status?: PresenceBadgeStatus; outOfOffice?: boolean; } & RefAttributes<HTMLDivElement>> | null | undefined;

  /**
   * Whether to display only the presence.
   * @default false
   */
  presenceOnly?: boolean;

  /**
   * The first line of text in the Persona, larger than the rest of the lines.
   *
   * `primaryText` defaults to the `name` prop. We recomend to only use `name`, use `primaryText` when the text is
   *  different than the `name` prop.
   */
  primaryText?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;

  /**
   * The fourth line of text in the Persona.
   */
  quaternaryText?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;

  ref?: Ref<HTMLDivElement>;

  /**
   * The second line of text in the Persona.
   */
  secondaryText?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;

  /**
   * The size of a Persona and its text.
   * @default medium
   */
  size?: "small" | "medium" | "large" | "extra-large" | "extra-small" | "huge";

  style?: CSSProperties;

  /**
   * The third line of text in the Persona.
   */
  tertiaryText?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;

  /**
   * The vertical alignment of the text relative to the avatar/presence.
   * @default start
   */
  textAlignment?: "center" | "start";

  /**
   * The position of the text relative to the avatar/presence.
   * @default after
   */
  textPosition?: "below" | "before" | "after";
}

Implementation

CoreAI 0.12.0; Fluent 9.74.9.

Setup and dependencies.

Import components from @coreai-ds/react-components. CoreAI guidance above takes precedence over API demonstration examples.

Avatar Size

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Persona } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    root: {
        display: 'grid',
        gridTemplateColumns: 'repeat(2, max-content)',
        columnGap: '10px',
        rowGap: '10px',
    },
});

export const AvatarSize = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.root}>
      <Persona presence={{ status: 'available' }} size="extra-small" name="Kevin Sturgis" avatar={{ color: 'colorful' }} secondaryText="Available"/>
      <Persona presence={{ status: 'available' }} size="small" name="Kevin Sturgis" avatar={{ color: 'colorful' }} secondaryText="Available"/>
      <Persona presence={{ status: 'available' }} size="medium" name="Kevin Sturgis" avatar={{ color: 'colorful' }} secondaryText="Available"/>
      <Persona presence={{ status: 'available' }} size="large" name="Kevin Sturgis" avatar={{ color: 'colorful' }} secondaryText="Available"/>
      <Persona presence={{ status: 'available' }} size="extra-large" name="Kevin Sturgis" avatar={{ color: 'colorful' }} secondaryText="Available"/>
      <Persona presence={{ status: 'available' }} size="huge" name="Kevin Sturgis" avatar={{ color: 'colorful' }} secondaryText="Available"/>
    </div>);
};

export default AvatarSize;

Presence Previous Behavior

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import { presenceAvailableRegular } from "@coreai-ds/react-components";
import { presenceOfflineRegular } from "@coreai-ds/react-components";
import { Persona } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    statusAway: {
        color: tokens.colorPaletteMarigoldBackground3,
    },
    statusOffline: {
        color: tokens.colorNeutralForeground3,
    },
    root: {
        display: 'grid',
        gridAutoFlow: 'column',
        gridTemplateColumns: 'repeat(2, max-content)',
        gridTemplateRows: 'repeat(3, auto)',
        columnGap: '20px',
        rowGap: '10px',
    },
});

export const PresencePreviousBehavior = (): JSXElement => {
    const styles = useStyles();
    const AwayFilledIcon = presenceAvailableRegular.small;
    const OfflineRegularIcon = presenceOfflineRegular.small;
    return (<div className={styles.root}>
      <span>Current Behavior</span>
      <Persona presence={{ status: 'away', outOfOffice: true }} name="Kevin Sturgis" secondaryText="Away - OOF"/>
      <Persona presence={{ status: 'offline', outOfOffice: true }} name="Kevin Sturgis" secondaryText="Offline - OOF"/>

      <span>Previous Behavior</span>
      <Persona presence={{
            status: 'away',
            outOfOffice: true,
            icon: <AwayFilledIcon />,
            className: styles.statusAway,
        }} name="Kevin Sturgis" secondaryText="Away - OOF"/>
      <Persona presence={{
            status: 'offline',
            outOfOffice: true,
            icon: <OfflineRegularIcon />,
            className: styles.statusOffline,
        }} name="Kevin Sturgis" secondaryText="Offline - OOF"/>
    </div>);
};

export default PresencePreviousBehavior;

Presence Size

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Persona } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    root: {
        display: 'grid',
        gridTemplateColumns: 'repeat(2, max-content)',
        columnGap: '10px',
        rowGap: '10px',
    },
});

export const PresenceSize = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.root}>
      <Persona size="extra-small" presenceOnly presence={{ status: 'available' }} name="Kevin Sturgis" secondaryText="Available"/>
      <Persona size="small" presenceOnly presence={{ status: 'available' }} name="Kevin Sturgis" secondaryText="Available"/>
      <Persona size="medium" presenceOnly presence={{ status: 'available' }} name="Kevin Sturgis" secondaryText="Available"/>
      <Persona size="large" presenceOnly presence={{ status: 'available' }} name="Kevin Sturgis" secondaryText="Available"/>
      <Persona size="extra-large" presenceOnly presence={{ status: 'available' }} name="Kevin Sturgis" secondaryText="Available"/>
      <Persona size="huge" presenceOnly presence={{ status: 'available' }} name="Kevin Sturgis" secondaryText="Available"/>
    </div>);
};

export default PresenceSize;

Text Alignment

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Persona } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    root: {
        display: 'grid',
        gridTemplateColumns: 'repeat(3, 1fr)',
        justifyItems: 'center',
    },
});

export const TextAlignment = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.root}>
      <Persona textAlignment="start" name="Kevin Sturgis" presence={{ status: 'available' }} secondaryText="Available" tertiaryText="Software Engineer" quaternaryText="Microsoft"/>
      <Persona textAlignment="center" name="Kevin Sturgis" presence={{ status: 'available' }} secondaryText="Available" tertiaryText="Software Engineer" quaternaryText="Microsoft"/>
    </div>);
};

export default TextAlignment;

Text Position

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Persona } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    root: {
        display: 'grid',
        gridTemplateColumns: 'repeat(3, 1fr)',
        justifyItems: 'center',
    },
});

export const TextPosition = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.root}>
      <Persona textPosition="after" name="Kevin Sturgis" presence={{ status: 'available' }} secondaryText="Available"/>
      <Persona textPosition="below" name="Kevin Sturgis" presence={{ status: 'available' }} secondaryText="Available"/>
      <Persona textPosition="before" name="Kevin Sturgis" presence={{ status: 'available' }} secondaryText="Available"/>
    </div>);
};

export default TextPosition;