Skip to content

Commit 0963e89

Browse files
vogtnnmetulev
andauthored
people-picker ui refresh and darkmode (#411)
* people-picker ui refresh and darkmode * top and bottom selected people margin and fixing story * css props, refactor scss * final scss updates * style feedback, prop location update, internal prop * displayName fix and intial selection * removing additional requestUpdate * min-width for default fluent guidelines * input background preserve variable * segoe font * height matching to teams-channel-picker * fix overflow issue Co-authored-by: Nikola Metulev <[email protected]>
1 parent ad4e8cc commit 0963e89

File tree

3 files changed

+151
-52
lines changed

3 files changed

+151
-52
lines changed

src/components/mgt-people-picker/mgt-people-picker.scss

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,29 @@ $avatar-size: var(--avatar-size, 48px);
1515
$initials-color: var(--initials-color, white);
1616
$initials-background-color: var(--initials-background-color, #{$ms-color-magenta});
1717
$accent-color: var(--accent-color, #0078d4);
18-
$separator-margin: var(--separator-margin, 0px 0px 0px 0px);
1918

20-
$people-list-background-color: var(--people-list-background-color, white);
19+
$input-border: var(--input-border, 2px solid #b3b0ad);
20+
$input-border-bottom: var(--input-border-bottom, $input-border);
21+
$input-border-right: var(--input-border-right, $input-border);
22+
$input-border-left: var(--input-border-left, $input-border);
23+
$input-border-top: var(--input-border-top, $input-border);
24+
25+
$input-hover-color: var(--input-hover-color, #323130);
26+
$input-focus-color: var(--input-focus-color, #0078d4);
27+
$input-background-color: var(--input-background-color, var(--people-list-background-color, white));
28+
29+
$dropdown-background-color: var(--dropdown-background-color, white);
30+
$dropdown-item-hover-background: var(--dropdown-item-hover-background, #f1f1f1dd);
31+
32+
$placeholder-default-color: var(--placeholder-default-color, #605e5c);
33+
$placeholder-focus-color: var(--placeholder-focus-color, #323130);
34+
$font-color: var(--font-color, #323130);
2135

2236
:host {
2337
border-radius: 2px;
24-
font-family: var(--default-font-family);
25-
font-style: normal;
26-
font-weight: normal;
38+
font-family: var(--default-font-family, 'Segoe UI');
39+
height: 38px;
40+
display: contents;
2741
}
2842
:host .root,
2943
mgt-people-picker .root {
@@ -34,16 +48,27 @@ mgt-people-picker .root {
3448
mgt-people-picker .people-picker {
3549
position: relative;
3650
margin: 7px 0 0 0;
37-
background-color: white;
38-
padding-bottom: 8px;
51+
background-color: $input-background-color;
52+
padding-bottom: 6px;
53+
border: $input-border;
54+
border-bottom: $input-border-bottom;
55+
border-left: $input-border-left;
56+
border-top: $input-border-top;
57+
border-right: $input-border-right;
58+
&:hover {
59+
border-color: $input-hover-color;
60+
}
61+
&.focused {
62+
border-color: $input-focus-color;
63+
}
3964
}
4065

4166
:host .flyout-root,
4267
mgt-people-picker .flyout-root {
4368
padding: 0;
4469
border-radius: 2px;
45-
background-color: $people-list-background-color;
46-
width: 100%;
70+
background-color: $dropdown-background-color;
71+
min-width: 260px;
4772
overflow-y: auto;
4873
text-align: left;
4974
list-style-type: none;
@@ -52,17 +77,10 @@ mgt-people-picker .flyout-root {
5277
cursor: pointer;
5378
}
5479
}
55-
:host .people-list-separator,
56-
mgt-people-picker .people-list-separator {
57-
margin: $separator-margin;
58-
height: 2px;
59-
background: $accent-color;
60-
margin-top: 5px;
61-
text-align: center;
62-
}
6380

6481
:host .people-selected-input,
6582
mgt-people-picker .people-selected-input {
83+
font-family: var(--default-font-family, 'Segoe UI');
6684
position: relative;
6785
border: none;
6886
line-height: normal;
@@ -71,16 +89,24 @@ mgt-people-picker .people-selected-input {
7189
font-weight: normal;
7290
font-size: 14px;
7391
line-height: 19px;
92+
background-color: $input-background-color;
93+
color: $font-color;
94+
&::placeholder {
95+
color: $placeholder-default-color;
96+
}
97+
&:focus::placeholder {
98+
color: $placeholder-focus-color;
99+
}
74100
}
75101

76102
:host .people-selected-list,
77103
mgt-people-picker .people-selected-list {
78104
display: flex;
79105
flex-wrap: wrap;
80106
vertical-align: middle;
81-
margin: 0 0 0 0;
107+
margin: 0 2px 0 0;
82108
list-style-type: none;
83-
padding-left: 10px;
109+
padding-left: 8px;
84110
font-style: normal;
85111
font-weight: normal;
86112
}
@@ -92,6 +118,7 @@ mgt-people-picker .CloseIcon {
92118
padding-left: 4px;
93119
margin-top: 0px;
94120
cursor: pointer;
121+
color: $font-color;
95122
}
96123
:host .SearchIcon,
97124
mgt-people-picker .SearchIcon {
@@ -102,7 +129,7 @@ mgt-people-picker .SearchIcon {
102129
:host .people-person,
103130
mgt-people-picker .people-person {
104131
display: flex;
105-
margin: 4px 5px 0px 0;
132+
margin: 5px 5px 0px 0;
106133
align-items: center;
107134
background-color: rgba(196, 196, 196, 0.24);
108135
border-radius: 15px;
@@ -122,13 +149,13 @@ mgt-people-picker .list-person {
122149
font-size: 14px;
123150

124151
&:hover {
125-
background-color: #f1f1f1dd;
152+
background-color: $dropdown-item-hover-background;
126153
}
127154
}
128155

129156
:host .list-person.focused,
130157
mgt-people-picker .list-person.focused {
131-
background-color: #f1f1f1;
158+
background-color: $dropdown-item-hover-background;
132159
}
133160

134161
:host .people-person-text,
@@ -141,11 +168,11 @@ mgt-people-picker .people-person-text {
141168

142169
:host .input-search,
143170
mgt-people-picker .input-search {
144-
margin: 7px 2px 0px 3px;
171+
margin: 6px 2px 1px 3px;
145172
}
146173
:host .input-search.input-search--start,
147174
mgt-people-picker .input-search.input-search--start {
148-
margin: 7px 0px 0px 0px;
175+
margin: 6px 0px 1px 0px;
149176
line-height: normal;
150177
margin-inline-start: 0px;
151178
margin-inline-end: 0px;
@@ -155,7 +182,7 @@ mgt-people-picker .input-search.input-search--start {
155182
mgt-people-picker .people-picker-input {
156183
display: flex;
157184
order: 2;
158-
background-color: white;
185+
background-color: $input-background-color;
159186
margin: $avatar-margin;
160187
font-size: 14px;
161188
line-height: 19px;
@@ -202,19 +229,22 @@ mgt-person {
202229
.selected-person {
203230
--avatar-size-s: 24px;
204231
margin-left: 0px;
232+
--color: $font-color;
233+
color: $font-color;
234+
margin-bottom: 1px;
205235
}
206236

207237
:host .search-error-text,
208238
:host .loading-text,
209239
mgt-people-picker .search-error-text,
210240
mgt-people-picker .loading-text {
211-
font-family: Segoe UI;
241+
font-family: var(--default-font-family, 'Segoe UI');
212242
font-style: normal;
213243
font-weight: 600;
214244
font-size: 14px;
215245
line-height: 19px;
216246
text-align: center;
217-
color: #232222;
247+
color: $font-color;
218248
margin-left: 50px;
219249
margin-right: 50px;
220250
}
@@ -255,4 +285,5 @@ mgt-people-picker .people-person-text-area {
255285
flex: 1 1 0;
256286
max-height: 40px;
257287
overflow: hidden;
288+
color: $font-color;
258289
}

src/components/mgt-people-picker/mgt-people-picker.ts

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,24 @@ interface IFocusable {
4444
*
4545
* @fires selectionChanged - Fired when selection changes
4646
*
47+
* @cssprop --font-color - {font} Default font color
48+
*
49+
* @cssprop --input-border - {String} Input section entire border
50+
* @cssprop --input-border-top - {String} Input section border top only
51+
* @cssprop --input-border-right - {String} Input section border right only
52+
* @cssprop --input-border-bottom - {String} Input section border bottom only
53+
* @cssprop --input-border-left - {String} Input section border left only
54+
* @cssprop --input-background-color - {Color} Input section background color
55+
* @cssprop --input-hover-color - {Color} Input text hover color
56+
* @cssprop --input-focus-color - {Color} Input text focus color
57+
*
58+
* @cssprop --dropdown-background-color - {Color} Background color of dropdown area
59+
* @cssprop --dropdown-item-hover-background - {Color} Background color of channel or team during hover
60+
* @cssprop --dropdown-item-selected-background - {Color} Background color of selected channel
61+
*
62+
* @cssprop --placeholder-focus-color - {Color} Color of placeholder text during focus state
63+
* @cssprop --placeholder-default-color - {Color} Color of placeholder text
64+
*
4765
* @cssprop --people-list-background-color - {Color} People list background color
4866
* @cssprop --accent-color - {Color} Accent color
4967
*/
@@ -57,6 +75,17 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
5775
return styles;
5876
}
5977

78+
/**
79+
* Gets the flyout element
80+
*
81+
* @protected
82+
* @type {MgtFlyout}
83+
* @memberof MgtLogin
84+
*/
85+
protected get flyout(): MgtFlyout {
86+
return this.renderRoot.querySelector('.flyout');
87+
}
88+
6089
/**
6190
* containing object of IDynamicPerson.
6291
* @type {IDynamicPerson[]}
@@ -185,17 +214,6 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
185214
*/
186215
protected userInput: string;
187216

188-
/**
189-
* Gets the flyout element
190-
*
191-
* @protected
192-
* @type {MgtFlyout}
193-
* @memberof MgtLogin
194-
*/
195-
protected get flyout(): MgtFlyout {
196-
return this.renderRoot.querySelector('.flyout');
197-
}
198-
199217
// if search is still loading don't load "people not found" state
200218
@property({ attribute: false }) private _showLoading: boolean;
201219

@@ -208,6 +226,7 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
208226
// List of people requested if group property is provided
209227
private _groupPeople: IDynamicPerson[];
210228
private _debouncedSearch: { (): void; (): void };
229+
@internalProperty() private _isFocused = false;
211230

212231
@internalProperty() private _foundPeople: IDynamicPerson[];
213232

@@ -238,6 +257,7 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
238257
* @memberof MgtPeoplePicker
239258
*/
240259
public focus(options?: FocusOptions) {
260+
this.gainedFocus();
241261
const peopleInput = this.renderRoot.querySelector('.people-selected-input') as HTMLInputElement;
242262
if (!peopleInput) {
243263
return;
@@ -293,14 +313,18 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
293313
const selectedPeopleTemplate = this.renderSelectedPeople(this.selectedPeople);
294314
const inputTemplate = this.renderInput();
295315
const flyoutTemplate = this.renderFlyout(inputTemplate);
316+
317+
const inputClasses = {
318+
focused: this._isFocused,
319+
'people-picker': true
320+
};
296321
return html`
297-
<div class="people-picker" @click=${() => this.focus()}>
322+
<div class=${classMap(inputClasses)} @click=${() => this.focus()}>
298323
<div class="people-picker-input">
299324
<div class="people-selected-list">
300325
${selectedPeopleTemplate} ${flyoutTemplate}
301326
</div>
302327
</div>
303-
<div class="people-list-separator"></div>
304328
</div>
305329
`;
306330
}
@@ -349,6 +373,7 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
349373
.value="${this.userInput}"
350374
@keydown="${this.onUserKeyDown}"
351375
@keyup="${this.onUserKeyUp}"
376+
@blur=${this.lostFocus}
352377
/>
353378
</div>
354379
`;
@@ -668,6 +693,9 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
668693
if (person) {
669694
this.userInput = '';
670695
const duplicatePeople = this.selectedPeople.filter(p => {
696+
if (!person.id) {
697+
return p.displayName === person.displayName;
698+
}
671699
return p.id === person.id;
672700
});
673701

@@ -680,6 +708,18 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
680708
}
681709
}
682710

711+
private gainedFocus() {
712+
this._isFocused = true;
713+
const input = this.renderRoot.querySelector('.people-selected-input') as HTMLInputElement;
714+
if (input) {
715+
input.focus();
716+
}
717+
}
718+
719+
private lostFocus() {
720+
this._isFocused = false;
721+
}
722+
683723
private renderHighlightText(person: IDynamicPerson): TemplateResult {
684724
let first: string = '';
685725
let last: string = '';
@@ -793,6 +833,9 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
793833
* @param event - event tracked on user input (keydown)
794834
*/
795835
private onUserKeyDown(event: KeyboardEvent): void {
836+
if (!this.flyout.isOpen) {
837+
return;
838+
}
796839
if (event.keyCode === 40 || event.keyCode === 38) {
797840
// keyCodes capture: down arrow (40) and up arrow (38)
798841
this.handleArrowSelection(event);
@@ -858,12 +901,16 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
858901
// find ids from selected people
859902
if (people) {
860903
const idFilter = this.selectedPeople.map(el => {
861-
return el.id;
904+
return el.id ? el.id : el.displayName;
862905
});
863906

864907
// filter id's
865908
const filtered = people.filter((person: IDynamicPerson) => {
866-
return idFilter.indexOf(person.id) === -1;
909+
if (person.id) {
910+
return idFilter.indexOf(person.id) === -1;
911+
} else {
912+
return idFilter.indexOf(person.displayName) === -1;
913+
}
867914
});
868915

869916
return filtered;

0 commit comments

Comments
 (0)