Skip to content

Commit 2f03ee5

Browse files
authored
fix: properly validate typed in emails and set them on comma or semi-colon key presses (#1978)
* fix: update the email validation regex * fix: use an internal property to set any email this._setAnyMail property is used to check if the comma or semi-colon have been pressed. If they have, then the typed email is checked if it is a valid email and set accordingly. * docs: add documentation for the private properties * fix: back to normal index.html * fix: set any email on Enter keypress * fix: remove tab key instruction on story
1 parent 92206b9 commit 2f03ee5

File tree

4 files changed

+25
-11
lines changed

4 files changed

+25
-11
lines changed

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,4 @@
6262
<mgt-todo></mgt-todo>
6363
<mgt-file-list></mgt-file-list>
6464
</body>
65-
</html>
65+
</html>

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

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77

88
import { User } from '@microsoft/microsoft-graph-types';
9-
import { customElement, html, internalProperty, property, TemplateResult } from 'lit-element';
9+
import { customElement, html, state, property, TemplateResult } from 'lit-element';
1010
import { classMap } from 'lit-html/directives/class-map';
1111
import { repeat } from 'lit-html/directives/repeat';
1212
import {
@@ -491,7 +491,6 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
491491
private _type: PersonType = PersonType.person;
492492
private _groupType: GroupType = GroupType.any;
493493
private _userType: UserType = UserType.any;
494-
private _currentSelectedUser: IDynamicPerson;
495494
private _userFilters: string;
496495
private _groupFilters: string;
497496
private _peopleFilters: string;
@@ -510,9 +509,20 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
510509
// current user index to the left of the highlighted users
511510
private _currentHighlightedUserPos: number = 0;
512511

513-
@internalProperty() private _isFocused = false;
512+
/**
513+
* Checks if the input is focused.
514+
*/
515+
@state() private _isFocused = false;
516+
517+
/**
518+
* Switch to determine if a typed email can be set.
519+
*/
520+
@state() private _setAnyEmail: boolean = false;
514521

515-
@internalProperty() private _foundPeople: IDynamicPerson[];
522+
/**
523+
* List of people found from the graph calls.
524+
*/
525+
@state() private _foundPeople: IDynamicPerson[];
516526

517527
constructor() {
518528
super();
@@ -1363,7 +1373,7 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
13631373
}
13641374

13651375
/**
1366-
* Adds debounce method for set delay on user input
1376+
* Handles input from the key up events on the keyboard.
13671377
*/
13681378
private onUserKeyUp(event: KeyboardEvent): void {
13691379
const isPaste = (event.ctrlKey || event.metaKey) && event.key === 'v';
@@ -1421,6 +1431,7 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
14211431

14221432
if (event.code === 'Comma' || event.code === 'Semicolon') {
14231433
if (this.allowAnyEmail) {
1434+
this._setAnyEmail = true;
14241435
event.preventDefault();
14251436
event.stopPropagation();
14261437
}
@@ -1430,10 +1441,13 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
14301441
this.userInput = input.value;
14311442
const validEmail = isValidEmail(this.userInput);
14321443
if (validEmail && this.allowAnyEmail) {
1433-
this.handleAnyEmail();
1444+
if (this._setAnyEmail) {
1445+
this.handleAnyEmail();
1446+
}
14341447
} else {
14351448
this.handleUserSearch();
14361449
}
1450+
this._setAnyEmail = false;
14371451
}
14381452

14391453
private handleAnyEmail() {
@@ -1544,9 +1558,9 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
15441558
this.addPerson(foundPerson);
15451559
this.hideFlyout();
15461560
this.input.value = '';
1547-
} else if (this.allowAnyEmail) {
1548-
this.handleAnyEmail();
15491561
}
1562+
} else if (this.allowAnyEmail) {
1563+
this.handleAnyEmail();
15501564
}
15511565
}
15521566

packages/mgt-components/src/utils/Utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ export function extractEmailAddress(emailString: string): string {
242242
* @returns {boolean}
243243
*/
244244
export function isValidEmail(emailString: string): boolean {
245-
const emailRx: RegExp = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;
245+
const emailRx: RegExp = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
246246
return emailRx.test(emailString);
247247
}
248248

stories/components/peoplePicker/peoplePicker.properties.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ export const pickerDefaultSelectedUserAndGroupIds = () => html`
234234

235235
export const pickerAllowAnyEmail = () => html`
236236
<mgt-people-picker allow-any-email></mgt-people-picker>
237-
<!-- Type any email address and press comma(,), semicolon(;), tab or enter to add it -->
237+
<!-- Type any email address and press comma(,), semicolon(;), or enter keys to add it -->
238238
<script type="module">
239239
const peoplePicker = document.querySelector('mgt-people-picker');
240240
peoplePicker.selectedPeople = [{mail: "[email protected]", displayName: "[email protected]"}]

0 commit comments

Comments
 (0)