Skip to content

Commit daf0cf9

Browse files
musaleMnickiigavinbarron
authored
fix: add a shimmer for the loading state of person component (#3009)
* WIP * Set the width and height of the fluent-skeleton * Set the shimmers to the selected mgt-person view --------- Co-authored-by: Nickii Miaro <[email protected]> Co-authored-by: Gavin Barron <[email protected]>
1 parent ae5e343 commit daf0cf9

File tree

2 files changed

+87
-11
lines changed

2 files changed

+87
-11
lines changed

packages/mgt-components/src/components/mgt-person/mgt-person.scss

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ $person-line4-text-line-height: var(--person-line4-text-line-height, 16px);
186186

187187
img,
188188
.initials,
189-
.contact-icon {
189+
.contact-icon,
190+
.shimmer {
190191
height: 100%;
191192
width: 100%;
192193
border: $person-avatar-border;
@@ -197,7 +198,8 @@ $person-line4-text-line-height: var(--person-line4-text-line-height, 16px);
197198
}
198199

199200
.initials,
200-
.contact-icon {
201+
.contact-icon,
202+
.shimmer {
201203
display: flex;
202204
justify-content: center;
203205
align-items: center;
@@ -232,6 +234,14 @@ $person-line4-text-line-height: var(--person-line4-text-line-height, 16px);
232234
margin-inline-start: $person-details-left-spacing;
233235
margin-block-end: $person-details-bottom-spacing;
234236

237+
.shimmer {
238+
&.text {
239+
width: 200px;
240+
height: 16px;
241+
margin: 2px 0;
242+
}
243+
}
244+
235245
&.vertical {
236246
display: inline-flex;
237247
flex-direction: column;

packages/mgt-components/src/components/mgt-person/mgt-person.ts

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,38 @@
55
* -------------------------------------------------------------------------------------------
66
*/
77

8+
import { fluentSkeleton } from '@fluentui/web-components';
89
import {
910
MgtTemplatedTaskComponent,
1011
ProviderState,
1112
Providers,
13+
buildComponentName,
1214
customElementHelper,
13-
mgtHtml
15+
mgtHtml,
16+
registerComponent
1417
} from '@microsoft/mgt-element';
1518
import { Presence } from '@microsoft/microsoft-graph-types';
16-
import { html, TemplateResult, nothing } from 'lit';
19+
import { TemplateResult, html, nothing } from 'lit';
1720
import { property, state } from 'lit/decorators.js';
1821
import { classMap } from 'lit/directives/class-map.js';
22+
import { ifDefined } from 'lit/directives/if-defined.js';
23+
import { isContact, isUser } from '../../graph/entityType';
1924
import { findPeople, getEmailFromGraphEntity } from '../../graph/graph.people';
2025
import { getGroupImage, getPersonImage } from '../../graph/graph.photos';
2126
import { getUserPresence } from '../../graph/graph.presence';
2227
import { findUsers, getMe, getUser } from '../../graph/graph.user';
2328
import { getUserWithPhoto } from '../../graph/graph.userWithPhoto';
2429
import { AvatarSize, IDynamicPerson, ViewType, viewTypeConverter } from '../../graph/types';
2530
import '../../styles/style-helper';
31+
import { registerFluentComponents } from '../../utils/FluentComponents';
2632
import { SvgIcon, getSvg } from '../../utils/SvgHelper';
33+
import { IExpandable, IHistoryClearer } from '../mgt-person-card/types';
2734
import '../sub-components/mgt-flyout/mgt-flyout';
2835
import { MgtFlyout, registerMgtFlyoutComponent } from '../sub-components/mgt-flyout/mgt-flyout';
29-
import { type PersonCardInteraction, personCardConverter } from './../PersonCardInteraction';
36+
import { personCardConverter, type PersonCardInteraction } from './../PersonCardInteraction';
3037
import { styles } from './mgt-person-css';
31-
import { MgtPersonConfig, AvatarType, avatarTypeConverter } from './mgt-person-types';
38+
import { AvatarType, MgtPersonConfig, avatarTypeConverter } from './mgt-person-types';
3239
import { strings } from './strings';
33-
import { isUser, isContact } from '../../graph/entityType';
34-
import { ifDefined } from 'lit/directives/if-defined.js';
35-
import { buildComponentName, registerComponent } from '@microsoft/mgt-element';
36-
import { IExpandable, IHistoryClearer } from '../mgt-person-card/types';
3740

3841
/**
3942
* Person properties part of original set provided by graph by default
@@ -55,6 +58,8 @@ export const defaultPersonProperties = [
5558
];
5659

5760
export const registerMgtPersonComponent = () => {
61+
registerFluentComponents(fluentSkeleton);
62+
5863
// register self first to avoid infinte loop due to circular ref between person and person card
5964
registerComponent('person', MgtPerson);
6065

@@ -585,7 +590,68 @@ export class MgtPerson extends MgtTemplatedTaskComponent {
585590
* @memberof MgtPerson
586591
*/
587592
protected renderLoading = (): TemplateResult => {
588-
return this.renderTemplate('loading', null) || html``;
593+
const rootClasses = classMap({
594+
'person-root': true,
595+
small: !this.isThreeLines() && !this.isFourLines() && !this.isLargeAvatar(),
596+
large: this.avatarSize !== 'auto' && this.isLargeAvatar(),
597+
noline: this.isNoLine(),
598+
oneline: this.isOneLine(),
599+
twolines: this.isTwoLines(),
600+
threelines: this.isThreeLines(),
601+
fourlines: this.isFourLines(),
602+
vertical: this.isVertical()
603+
});
604+
605+
const detailsClasses = classMap({
606+
'details-wrapper': true,
607+
vertical: this.isVertical()
608+
});
609+
610+
return (
611+
this.renderTemplate('loading', null) ||
612+
html`
613+
<div class="${rootClasses}">
614+
<div class="avatar-wrapper">
615+
<fluent-skeleton shimmer class="shimmer" shape="circle"></fluent-skeleton>
616+
</div>
617+
<div class=${detailsClasses}>
618+
${this.renderLoadingLines()}
619+
</div>
620+
</div>`
621+
);
622+
};
623+
624+
protected renderLoadingLines = (): TemplateResult[] => {
625+
const lines: TemplateResult[] = [];
626+
if (this.isNoLine()) return lines;
627+
if (this.isOneLine()) {
628+
lines.push(this.renderLoadingLine(1));
629+
}
630+
if (this.isTwoLines()) {
631+
lines.push(this.renderLoadingLine(1));
632+
lines.push(this.renderLoadingLine(2));
633+
}
634+
if (this.isThreeLines()) {
635+
lines.push(this.renderLoadingLine(1));
636+
lines.push(this.renderLoadingLine(2));
637+
lines.push(this.renderLoadingLine(3));
638+
}
639+
if (this.isFourLines()) {
640+
lines.push(this.renderLoadingLine(1));
641+
lines.push(this.renderLoadingLine(2));
642+
lines.push(this.renderLoadingLine(3));
643+
lines.push(this.renderLoadingLine(4));
644+
}
645+
return lines;
646+
};
647+
648+
protected renderLoadingLine = (line: number): TemplateResult => {
649+
const lineNumber = `line${line}`;
650+
return html`
651+
<div class=${lineNumber}>
652+
<fluent-skeleton shimmer class="shimmer text" shape="rect"></fluent-skeleton>
653+
</div>
654+
`;
589655
};
590656

591657
/**

0 commit comments

Comments
 (0)