Introduction
Hi friends, in this post let us dive deep in to the Microsoft Graph Toolkit Person component. We will learn the component properties, css custom properties and also the data templates to customize the component. For those who are not aware of the MSGraph Toolkit or how to use it in SharePoint Framework web part, please go through the below articles
- A Lap Around Microsoft Graph Toolkit
- Microsoft Graph Toolkit: Web Components powered by Microsoft Graph
- SPFx – Using MSGraph Toolkit
Focus on the Code
Once you had setup all the boiler plate code, lets focus on the change that we need to do and also see how to use some of the properies, css and templates.
First we need to add the import statement for TemplateHelper and then add the template to the global declaration. Please change the declarations like the below.
import { TemplateHelper } from '@microsoft/mgt';
declare global {
namespace JSX {
interface IntrinsicElements {
'mgt-person': any;
'template': any;
}
}
}
Usually the dynamic values in the templates is referred using ‘{{‘ & ‘}}‘. We need to change this to ‘[[‘ & ‘]]‘ to avoid unwanted errors while using it in SPFx. Inorder to do that we have to set the binding in the template.
Copy-paste the below code before the render method to set the binding.
TemplateHelper.setBindingSyntax('[[', ']]');
MGT-Person Properties
person-query
This property can be used with ‘me‘, user name or email. The component will automatically fetch the user details and display the info. If the results retrieved are more than one, the first is always displayed.
Below is the code to display the current logged in user with the name, email and presence.
<div>
<div className={styles.sectionTitle}>Current Logged-in user using person-query as 'me'</div>
<mgt-person person-query="me" show-name show-email show-presence></mgt-person>
</div>

Below is the code to display the user info based on the firstname and lastname.
<div>
<div className={styles.sectionTitle}>Using person-query with 'Firstname' and 'Lastname'</div>
<div style={{ display: 'inline-flex' }}>
<mgt-person person-query="prad" show-name show-email></mgt-person>
<mgt-person person-query="vance" show-name show-email></mgt-person>
</div>
</div>

user-id
We can use this property to display the user info based on the unique ID of the user which is a 16-digit guid.
<div>
<div className={styles.sectionTitle}>Using user-id property</div>
<mgt-person user-id="7ba3c6f5-937c-4b72-8a3a-e6ad3baa8d8c" show-name show-email></mgt-person>
</div>

person-details
We can use this property to display the custom user info, using this property won’t trigger the graph call. Copy-paste the below code to declare a personDetail variable with the ‘displayName‘ and ‘email‘ property. The key should be the same but the value can be any.
const personDetail: any = {
displayName: 'Test User',
mail: 'This is random text.'
};
<div>
<div className={styles.sectionTitle}>Using person-details property</div>
<mgt-person person-details={JSON.stringify(personDetail)} show-name show-email></mgt-person>
</div>

As you can see, the above user doesn’t exists, but I am just displaying like the actual user info, the initials are automatically detected from the first and the lastname. You can even assign an image URL, presence status etc.
Below is the code with image and presence details for the person-details property
const personDetail1: any = {
displayName: 'Test User',
mail: 'This is random text.',
personPresence: 'DoNotDisturb',
personImage: 'https://cdn1.iconfinder.com/data/icons/prettyoffice8/256/Users.png'
};
<div>
<div className={styles.sectionTitle}>Using person-details property</div>
<mgt-person person-details={JSON.stringify(personDetail1)} show-name show-email show-presence></mgt-person>
</div>

view
Using this property can restrict what to show on the person component. There are 3 options
- avatar – To show only avatar or initials
- oneline – To show avatar or initials with the first line (displayName)
- twolines – To show avatar or initials with the first and second line (displayName and email)
<div>
<div className={styles.sectionTitle}>Using view property set to 'avatar','oneline' and 'twolines'</div>
<div>
<div style={{ margin: '5px' }}><mgt-person person-details={JSON.stringify(personDetail)} view="avatar"></mgt-person></div>
<div style={{ margin: '5px' }}><mgt-person person-details={JSON.stringify(personDetail)} view="oneline"></mgt-person></div>
<div style={{ margin: '5px' }}><mgt-person person-details={JSON.stringify(personDetail)} view="twolines"></mgt-person></div>
</div>
</div>
<div>
<div>
<div style={{ margin: '5px' }}><mgt-person person-query="me" view="avatar"></mgt-person></div>
<div style={{ margin: '5px' }}><mgt-person person-query="me" view="oneline"></mgt-person></div>
<div style={{ margin: '5px' }}><mgt-person person-query="me" view="twolines"></mgt-person></div>
</div>
</div>

person-card
Using this property, we can show a separate card for the person with the email, phone number and other information. The ‘Person-Card’ is a separate component which has many properties and customization options which will be covered in the upcoming posts
<div>
<div className={styles.sectionTitle}>Current Logged-in user using person-query as 'me' and using person-card</div>
<mgt-person person-query="me" show-name show-email show-presence person-card='hover'></mgt-person>
</div>

CSS-Custom Properties
Let us see how we can use our own css styles to customize the component. There are some default css variables that we can use it to customize the component to match our theme or branding.
Copy-paste the below code to your module.scss file
.customPerson {
--avatar-size: 48px;
--avatar-border: 0;
--avatar-border-radius: 10% 35%;
--initials-color: white;
--initials-background-color: magenta;
--font-family: 'Segoe UI';
--font-size: 20px;
--font-weight: 500;
--color: black;
--presence-background-color: #ffffff;
--text-transform: none;
--line2-font-size: 12px;
--line2-font-weight: 400;
--line2-color: black;
--line2-text-transform: none;
--details-spacing: 12px;
}
<div>
<div className={styles.sectionTitle}>Using custom css</div>
<mgt-person class={styles.customPerson} person-query="vance" show-name show-email></mgt-person>
</div>

Templates
The templates provide us with more customizable options and we can also use templates to show different information at different stage of the component. Following are the templates available for this is component.
- loading – Template to render when the component is at the loading state, which means while fetching the info from Graph API.
- no-data – Template to render when there is no results returned for the query.
- default – Template to display the information when there is a result returned from the Graph API. The results are returned as person and personImage, you can see the details returned below.
- person-card – Template to customize the information that is shown on the person-card.
Below is the results returned for the query that can be used in the default template. The below properties can be accessed using the person key. E.g., use [[person.displayName]] inside the template to access the ‘DisplayName’ of the user.
{
"id": "9c8438c1-62f9-4cf4-b89d-76ca4449f043",
"displayName": "Adele Vance",
"givenName": "Adele",
"surname": "Vance",
"birthday": null,
"personNotes": null,
"isFavorite": false,
"jobTitle": "Retail Manager",
"companyName": null,
"yomiCompany": null,
"department": "Retail",
"officeLocation": "18/2111",
"profession": null,
"userPrincipalName": "AdeleV@o365practice.onmicrosoft.com",
"imAddress": "sip:adelev@o365practice.onmicrosoft.com",
"scoredEmailAddresses": [
{
"address": "AdeleV@o365practice.onmicrosoft.com",
"relevanceScore": 1,
"selectionLikelihood": "notSpecified"
}
],
"phones": [
{
"type": "business",
"number": "+1 425 555 0109"
},
{
"type": "mobile",
"number": "+1 4255550109"
}
],
"personType": {
"class": "Person",
"subclass": "OrganizationUser"
},
"personImage": "data:image/pjpeg;base64,/9j/4AAQSkZJ"
}
<div>
<div className={styles.sectionTitle}>Using templates</div>
<mgt-person person-query="vance">
<template data-type="loading">
<p>Loading...</p>
</template>
<template>
{/* <div style={{ overflow: 'auto' }}>[[person]]</div> */}
<div className={styles.customPersonContainer}>
<div className={styles.personImage}><img src="[[personImage]]" /></div>
<div><b>Title:</b> [[person.displayName]]</div>
<div><b>Job Title:</b> [[person.jobTitle]]</div>
<div><b>UPN:</b> [[person.userPrincipalName]]</div>
<div><b>Business Phone:</b> [[person.phones[0].number]]</div>
</div>
</template>
</mgt-person>
</div>
.sectionTitle {
font-weight: 700;
margin-top: 5px;
margin-bottom: 5px;
color: black;
font-style: italic;
text-align: center;
}
.customPersonContainer {
max-width: 300px;
border: 1px solid #CCC;
padding: 10px;
div.personImage {
text-align: center;
img {
border-radius: 35% 10%;
}
}
}

Source Code
The source code along with other samples can be found in the below github link.
Happy Coding…
Pingback: SPFx – MGT Person Card Component | Knowledge Share