@meetelise/chat 1.59.0 → 1.59.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/WebComponent/Scheduler/tour-scheduler.d.ts +4 -0
- package/dist/src/WebComponent/actions/call-us-window.d.ts +5 -0
- package/dist/src/WebComponent/actions/email-us-window.d.ts +5 -0
- package/dist/src/WebComponent/me-chat.d.ts +15 -9
- package/dist/src/WebComponent/pubnub-chat.d.ts +14 -0
- package/package.json +1 -1
- package/public/dist/index.js +5594 -5573
- package/src/WebComponent/Scheduler/tour-scheduler.ts +27 -0
- package/src/WebComponent/actions/call-us-window.ts +22 -0
- package/src/WebComponent/actions/email-us-window.ts +22 -0
- package/src/WebComponent/me-chat.ts +89 -136
- package/src/WebComponent/me-select.ts +1 -1
- package/src/WebComponent/pubnub-chat-styles.ts +12 -0
- package/src/WebComponent/pubnub-chat.ts +186 -7
- package/src/chatKeyboard.test.ts +430 -0
- package/src/disclaimers.ts +36 -3
- package/src/meChatAutoOpen.test.ts +143 -0
- package/src/pubnub-chat.test.ts +184 -0
|
@@ -75,11 +75,13 @@ import { readGoogleReserveReferral } from "../../googleReserve";
|
|
|
75
75
|
import fetchBuildingUnitsSummary, {
|
|
76
76
|
UnitSummary,
|
|
77
77
|
} from "../../fetchBuildingUnitsSummary";
|
|
78
|
+
import { focusFirstTabStop, trapTabInside } from "../pubnub-chat";
|
|
78
79
|
|
|
79
80
|
@customElement("tour-scheduler")
|
|
80
81
|
export class TourScheduler extends LitElement {
|
|
81
82
|
connectedCallback(): void {
|
|
82
83
|
super.connectedCallback();
|
|
84
|
+
this.addEventListener("keydown", this.trapOverlayTab);
|
|
83
85
|
if (!this.hasAttribute("role")) {
|
|
84
86
|
this.setAttribute("role", "dialog");
|
|
85
87
|
}
|
|
@@ -149,6 +151,31 @@ export class TourScheduler extends LitElement {
|
|
|
149
151
|
@property({ attribute: true })
|
|
150
152
|
buildingName = "";
|
|
151
153
|
|
|
154
|
+
disconnectedCallback(): void {
|
|
155
|
+
this.removeEventListener("keydown", this.trapOverlayTab);
|
|
156
|
+
super.disconnectedCallback();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
private trapOverlayTab = (event: KeyboardEvent): void => {
|
|
160
|
+
trapTabInside(event, this);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
private movedFocusInside = false;
|
|
164
|
+
|
|
165
|
+
updated(): void {
|
|
166
|
+
if (this.movedFocusInside) return;
|
|
167
|
+
if (focusFirstTabStop(this)) {
|
|
168
|
+
this.movedFocusInside = true;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
// The first paint is the loading state and has no controls. A custom
|
|
172
|
+
// element's tabIndex reads as -1 until the attribute is set, and focus()
|
|
173
|
+
// is ignored until then. Hold focus on the dialog so it does not fall
|
|
174
|
+
// through to the page.
|
|
175
|
+
if (!this.hasAttribute("tabindex")) this.setAttribute("tabindex", "-1");
|
|
176
|
+
if (!this.matches(":focus")) this.focus({ preventScroll: true });
|
|
177
|
+
}
|
|
178
|
+
|
|
152
179
|
onCloseClicked?: (e: MouseEvent) => void;
|
|
153
180
|
|
|
154
181
|
@state()
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
} from "../LeadSourceMultitouchClient";
|
|
18
18
|
|
|
19
19
|
import { getOfficeHourText } from "../OfficeHours";
|
|
20
|
+
import { focusFirstTabStop, trapTabInside } from "../pubnub-chat";
|
|
20
21
|
import {
|
|
21
22
|
formatToUsPhoneInput,
|
|
22
23
|
isModifierKey,
|
|
@@ -32,6 +33,27 @@ import {
|
|
|
32
33
|
|
|
33
34
|
@customElement("call-us-window")
|
|
34
35
|
export class CallUsWindow extends LitElement {
|
|
36
|
+
connectedCallback(): void {
|
|
37
|
+
super.connectedCallback();
|
|
38
|
+
this.addEventListener("keydown", this.trapOverlayTab);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
disconnectedCallback(): void {
|
|
42
|
+
this.removeEventListener("keydown", this.trapOverlayTab);
|
|
43
|
+
super.disconnectedCallback();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private trapOverlayTab = (event: KeyboardEvent): void => {
|
|
47
|
+
trapTabInside(event, this);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
private movedFocusInside = false;
|
|
51
|
+
|
|
52
|
+
updated(): void {
|
|
53
|
+
if (this.movedFocusInside) return;
|
|
54
|
+
if (focusFirstTabStop(this)) this.movedFocusInside = true;
|
|
55
|
+
}
|
|
56
|
+
|
|
35
57
|
static styles = [
|
|
36
58
|
InputStyles,
|
|
37
59
|
css`
|
|
@@ -14,6 +14,7 @@ import axios from "axios";
|
|
|
14
14
|
import { FeatureFlagsShowDropdown } from "../../fetchFeatureFlag";
|
|
15
15
|
import { pushGtmEvent } from "../../gtm";
|
|
16
16
|
import formDisclaimer from "../../disclaimers";
|
|
17
|
+
import { focusFirstTabStop, trapTabInside } from "../pubnub-chat";
|
|
17
18
|
import { isMobile, isValidEmail, snakify } from "../../utils";
|
|
18
19
|
import LeadSourceClient, {
|
|
19
20
|
getDefaultLeadSourceAttribution,
|
|
@@ -32,6 +33,27 @@ import {
|
|
|
32
33
|
|
|
33
34
|
@customElement("email-us-window")
|
|
34
35
|
export class EmailUsWindow extends LitElement {
|
|
36
|
+
connectedCallback(): void {
|
|
37
|
+
super.connectedCallback();
|
|
38
|
+
this.addEventListener("keydown", this.trapOverlayTab);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
disconnectedCallback(): void {
|
|
42
|
+
this.removeEventListener("keydown", this.trapOverlayTab);
|
|
43
|
+
super.disconnectedCallback();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private trapOverlayTab = (event: KeyboardEvent): void => {
|
|
47
|
+
trapTabInside(event, this);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
private movedFocusInside = false;
|
|
51
|
+
|
|
52
|
+
updated(): void {
|
|
53
|
+
if (this.movedFocusInside) return;
|
|
54
|
+
if (focusFirstTabStop(this)) this.movedFocusInside = true;
|
|
55
|
+
}
|
|
56
|
+
|
|
35
57
|
static styles = [
|
|
36
58
|
css`
|
|
37
59
|
.email-us__name-input,
|
|
@@ -10,7 +10,7 @@ import fetchBuildingWebchatView, {
|
|
|
10
10
|
DesignConcepts,
|
|
11
11
|
fetchOrgCentralWebchatView,
|
|
12
12
|
} from "../fetchBuildingWebchatView";
|
|
13
|
-
import Analytics, { logSignal
|
|
13
|
+
import Analytics, { logSignal } from "../analytics";
|
|
14
14
|
import {
|
|
15
15
|
FeatureFlagsShowDropdown,
|
|
16
16
|
fetchFeatureFlagUseApplicationsLinkReplacement,
|
|
@@ -26,15 +26,11 @@ import { defaultPrimaryColor, defaultBackgroundColor } from "../themes";
|
|
|
26
26
|
import getShouldShowWebchat from "../getShouldShowWebchat";
|
|
27
27
|
import { isMobile, onMobileChange } from "../utils";
|
|
28
28
|
import { installLauncher } from "./launcher/Launcher";
|
|
29
|
-
import parseISO from "date-fns/parseISO";
|
|
30
|
-
import isPast from "date-fns/isPast";
|
|
31
29
|
import { getWidgetOverrides } from "../utils/getWidgetOverrides";
|
|
32
30
|
|
|
33
31
|
import "./MEChat.css";
|
|
34
32
|
import { getRawAvailabilities } from "../getAvailabilities";
|
|
35
33
|
import { StyleInfo } from "lit/directives/style-map";
|
|
36
|
-
import addMinutes from "date-fns/addMinutes";
|
|
37
|
-
import formatISO from "date-fns/formatISO";
|
|
38
34
|
import fetchLeadSources from "../fetchLeadSources";
|
|
39
35
|
import fetchBuildingAip from "../fetchBuildingAip";
|
|
40
36
|
import { formatPhoneNumber } from "./actions/formatPhoneNumber";
|
|
@@ -50,6 +46,7 @@ import {
|
|
|
50
46
|
import "./actions/minimize-expand-button";
|
|
51
47
|
import "./launcher/mobile-launcher";
|
|
52
48
|
import "./pubnub-chat";
|
|
49
|
+
import type { PubnubChat } from "./pubnub-chat";
|
|
53
50
|
import { getBuildingPhoneNumber } from "../getBuildingPhoneNumber";
|
|
54
51
|
import {
|
|
55
52
|
clearChatStorageKey,
|
|
@@ -220,6 +217,11 @@ export class MEChat extends LitElement {
|
|
|
220
217
|
@state()
|
|
221
218
|
private displayPubnubChat = false;
|
|
222
219
|
|
|
220
|
+
private launcherButton: HTMLElement | null = null;
|
|
221
|
+
|
|
222
|
+
/** Set only for a user-initiated open, so auto-open does not steal focus. */
|
|
223
|
+
private focusChatOnMount = false;
|
|
224
|
+
|
|
223
225
|
@state()
|
|
224
226
|
private myPubnub: MyPubnub | null = null;
|
|
225
227
|
|
|
@@ -375,7 +377,7 @@ export class MEChat extends LitElement {
|
|
|
375
377
|
this.displayPubnubChat = true;
|
|
376
378
|
this.hideLauncher = true;
|
|
377
379
|
this.hasMounted = true;
|
|
378
|
-
this.
|
|
380
|
+
this.rememberChatAutoOpenDismissed();
|
|
379
381
|
} else if (localStorage.getItem("isChatOpen") === "true") {
|
|
380
382
|
this.hideLauncher = true;
|
|
381
383
|
this.displayPubnubChat = true;
|
|
@@ -850,17 +852,31 @@ export class MEChat extends LitElement {
|
|
|
850
852
|
}
|
|
851
853
|
};
|
|
852
854
|
|
|
855
|
+
private chatAutoOpenDismissedStorageKey = (): string | null => {
|
|
856
|
+
const { orgSlug, buildingSlug } = this;
|
|
857
|
+
if (orgSlug && buildingSlug) {
|
|
858
|
+
return `com.elise.webchat.autoOpenDismissed=${orgSlug}=${buildingSlug}`;
|
|
859
|
+
}
|
|
860
|
+
if (buildingSlug) {
|
|
861
|
+
return `com.elise.webchat.autoOpenDismissed=${buildingSlug}`;
|
|
862
|
+
}
|
|
863
|
+
if (orgSlug) {
|
|
864
|
+
return `com.elise.webchat.autoOpenDismissed=${orgSlug}`;
|
|
865
|
+
}
|
|
866
|
+
return null;
|
|
867
|
+
};
|
|
868
|
+
|
|
853
869
|
private shouldAutoOpenChat = (buildingHasAutoOpen: boolean): boolean => {
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
)
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
870
|
+
if (!buildingHasAutoOpen || isMobile()) return false;
|
|
871
|
+
const key = this.chatAutoOpenDismissedStorageKey();
|
|
872
|
+
if (!key) return true;
|
|
873
|
+
return localStorage.getItem(key) !== "true";
|
|
874
|
+
};
|
|
875
|
+
|
|
876
|
+
private rememberChatAutoOpenDismissed = (): void => {
|
|
877
|
+
const key = this.chatAutoOpenDismissedStorageKey();
|
|
878
|
+
if (!key) return;
|
|
879
|
+
localStorage.setItem(key, "true");
|
|
864
880
|
};
|
|
865
881
|
|
|
866
882
|
private async handleChatInitializeAnalytics(): Promise<void> {
|
|
@@ -888,13 +904,6 @@ export class MEChat extends LitElement {
|
|
|
888
904
|
this.hideLauncher = false;
|
|
889
905
|
}
|
|
890
906
|
|
|
891
|
-
private updateAlreadyAutoOpenedTimestamp = (): void => {
|
|
892
|
-
sessionStorage.setItem(
|
|
893
|
-
"alreadyAutoOpenedTimestamp",
|
|
894
|
-
formatISO(addMinutes(new Date(), 15))
|
|
895
|
-
);
|
|
896
|
-
};
|
|
897
|
-
|
|
898
907
|
/** Show the chat button on the screen if it was previously hidden. */
|
|
899
908
|
show(): void {
|
|
900
909
|
if (!this.launcher) {
|
|
@@ -963,116 +972,11 @@ export class MEChat extends LitElement {
|
|
|
963
972
|
connectedCallback(): void {
|
|
964
973
|
super.connectedCallback();
|
|
965
974
|
window.addEventListener("resize", this.adjustPositionChatAdditionalActions);
|
|
966
|
-
window.addEventListener("keydown", this.handleKeydownTab);
|
|
967
975
|
this._cleanupMobileListener = onMobileChange((m) => {
|
|
968
976
|
this._isMobile = m;
|
|
969
977
|
});
|
|
970
978
|
}
|
|
971
979
|
|
|
972
|
-
private static readonly FOCUSABLE_SELECTOR =
|
|
973
|
-
"a[href]:not([tabindex='-1']), input:not([disabled]), button:not([disabled]), textarea, [tabindex]:not([tabindex='-1'])";
|
|
974
|
-
|
|
975
|
-
/**
|
|
976
|
-
* Recursively collects focusable elements, piercing shadow DOM boundaries.
|
|
977
|
-
*/
|
|
978
|
-
private static isFocusable(el: HTMLElement): boolean {
|
|
979
|
-
if (
|
|
980
|
-
"disabled" in el &&
|
|
981
|
-
(el as HTMLButtonElement | HTMLInputElement).disabled
|
|
982
|
-
) {
|
|
983
|
-
return false;
|
|
984
|
-
}
|
|
985
|
-
return true;
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
private collectFocusableElements(root: Element | ShadowRoot): HTMLElement[] {
|
|
989
|
-
const results: HTMLElement[] = [];
|
|
990
|
-
// If root is an Element with its own shadow root, recurse into it
|
|
991
|
-
if (root instanceof Element && root.shadowRoot) {
|
|
992
|
-
results.push(...this.collectFocusableElements(root.shadowRoot));
|
|
993
|
-
}
|
|
994
|
-
const elements = root.querySelectorAll("*");
|
|
995
|
-
for (const el of Array.from(elements)) {
|
|
996
|
-
if (
|
|
997
|
-
el.matches(MEChat.FOCUSABLE_SELECTOR) &&
|
|
998
|
-
MEChat.isFocusable(el as HTMLElement)
|
|
999
|
-
) {
|
|
1000
|
-
results.push(el as HTMLElement);
|
|
1001
|
-
}
|
|
1002
|
-
if (el.shadowRoot) {
|
|
1003
|
-
results.push(...this.collectFocusableElements(el.shadowRoot));
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
return results;
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
handleKeydownTab = (e: KeyboardEvent): void => {
|
|
1010
|
-
if (e.key !== "Tab") return;
|
|
1011
|
-
|
|
1012
|
-
const launcherShadow =
|
|
1013
|
-
this.shadowRoot?.getElementById("meetelise-launcher")?.shadowRoot;
|
|
1014
|
-
|
|
1015
|
-
let inputsArray: HTMLElement[] = [];
|
|
1016
|
-
if (this.displayPubnubChat) {
|
|
1017
|
-
const chatContainer = this.shadowRoot
|
|
1018
|
-
?.getElementById("pubnub-chat")
|
|
1019
|
-
?.shadowRoot?.getElementById("pubnub-chat-container");
|
|
1020
|
-
const additionalActions = this.shadowRoot?.getElementById(
|
|
1021
|
-
"chatAdditionalActionsPubnub"
|
|
1022
|
-
);
|
|
1023
|
-
if (chatContainer) {
|
|
1024
|
-
inputsArray.push(...this.collectFocusableElements(chatContainer));
|
|
1025
|
-
}
|
|
1026
|
-
if (additionalActions) {
|
|
1027
|
-
inputsArray.push(...this.collectFocusableElements(additionalActions));
|
|
1028
|
-
}
|
|
1029
|
-
} else {
|
|
1030
|
-
const containerElement =
|
|
1031
|
-
launcherShadow?.getElementById("email-us-window") ?? // email us form
|
|
1032
|
-
launcherShadow?.getElementById("tour-scheduler-window") ?? // tour booking form
|
|
1033
|
-
launcherShadow?.getElementById("call-us-window"); // text/call us form
|
|
1034
|
-
if (containerElement) {
|
|
1035
|
-
inputsArray = this.collectFocusableElements(containerElement);
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
if (inputsArray.length === 0) return;
|
|
1040
|
-
e.preventDefault();
|
|
1041
|
-
|
|
1042
|
-
const deepActive = this.getDeepActiveElement();
|
|
1043
|
-
const currentFocusedIndex = inputsArray.findIndex(
|
|
1044
|
-
(el) => el === deepActive
|
|
1045
|
-
);
|
|
1046
|
-
|
|
1047
|
-
const nextIndex = e.shiftKey
|
|
1048
|
-
? (currentFocusedIndex - 1 + inputsArray.length) % inputsArray.length
|
|
1049
|
-
: (currentFocusedIndex + 1) % inputsArray.length;
|
|
1050
|
-
inputsArray[nextIndex].focus();
|
|
1051
|
-
};
|
|
1052
|
-
|
|
1053
|
-
getDeepActiveElement(): Element | null {
|
|
1054
|
-
let activeElement = document.activeElement;
|
|
1055
|
-
let count = 0;
|
|
1056
|
-
while (
|
|
1057
|
-
activeElement?.shadowRoot &&
|
|
1058
|
-
activeElement?.shadowRoot.activeElement
|
|
1059
|
-
) {
|
|
1060
|
-
count += 1;
|
|
1061
|
-
activeElement = activeElement?.shadowRoot.activeElement;
|
|
1062
|
-
if (count > 100) {
|
|
1063
|
-
// just incase we get stuck in an infinite loop
|
|
1064
|
-
sendLoggingEvent({
|
|
1065
|
-
logType: LogType.error,
|
|
1066
|
-
buildingSlug: this.buildingSlug,
|
|
1067
|
-
logTitle: "[ERROR_GETTING_DEEP_ELEMENT]",
|
|
1068
|
-
logData: { message: "error getting deep active element" },
|
|
1069
|
-
});
|
|
1070
|
-
break;
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
|
-
return activeElement;
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
980
|
updated(): void {
|
|
1077
981
|
this.adjustPositionChatAdditionalActions();
|
|
1078
982
|
}
|
|
@@ -1083,7 +987,6 @@ export class MEChat extends LitElement {
|
|
|
1083
987
|
"resize",
|
|
1084
988
|
this.adjustPositionChatAdditionalActions
|
|
1085
989
|
);
|
|
1086
|
-
window.removeEventListener("keydown", this.handleKeydownTab);
|
|
1087
990
|
this._cleanupMobileListener?.();
|
|
1088
991
|
|
|
1089
992
|
super.disconnectedCallback();
|
|
@@ -1103,6 +1006,7 @@ export class MEChat extends LitElement {
|
|
|
1103
1006
|
}
|
|
1104
1007
|
|
|
1105
1008
|
launcher.onChatTapped = async () => {
|
|
1009
|
+
this.focusChatOnMount = true;
|
|
1106
1010
|
this.displayPubnubChat = true;
|
|
1107
1011
|
this.hideLauncher = true;
|
|
1108
1012
|
this.hasMounted = true;
|
|
@@ -1116,8 +1020,58 @@ export class MEChat extends LitElement {
|
|
|
1116
1020
|
this.hideLauncher = false;
|
|
1117
1021
|
this.showTourNextToChat = false;
|
|
1118
1022
|
localStorage.setItem("isChatOpen", "false");
|
|
1023
|
+
this.rememberChatAutoOpenDismissed();
|
|
1119
1024
|
};
|
|
1120
1025
|
|
|
1026
|
+
private focusLauncherButton = (): void => {
|
|
1027
|
+
const stored = this.launcherButton?.isConnected
|
|
1028
|
+
? this.launcherButton
|
|
1029
|
+
: null;
|
|
1030
|
+
(stored ?? this.currentLauncherButton())?.focus();
|
|
1031
|
+
};
|
|
1032
|
+
|
|
1033
|
+
/**
|
|
1034
|
+
* User-initiated open. The caret belongs in the message field.
|
|
1035
|
+
* While consent hides the composer, keep focus on the dialog so the agree
|
|
1036
|
+
* control is reachable. Stored consent is applied after onMount, so try
|
|
1037
|
+
* again once that paint has committed.
|
|
1038
|
+
*/
|
|
1039
|
+
private focusMessageFieldOnOpen = (): void => {
|
|
1040
|
+
const chat = this.shadowRoot?.getElementById(
|
|
1041
|
+
"pubnub-chat"
|
|
1042
|
+
) as PubnubChat | null;
|
|
1043
|
+
const root = chat?.shadowRoot;
|
|
1044
|
+
if (!chat || !root) return;
|
|
1045
|
+
if (!chat.focusMessageField()) {
|
|
1046
|
+
root.getElementById("pubnub-chat-container")?.focus();
|
|
1047
|
+
}
|
|
1048
|
+
setTimeout(() => {
|
|
1049
|
+
chat.focusMessageField();
|
|
1050
|
+
}, 0);
|
|
1051
|
+
};
|
|
1052
|
+
|
|
1053
|
+
private closeChatAndRestoreFocus = (): void => {
|
|
1054
|
+
this.onExitChat();
|
|
1055
|
+
void this.updateComplete.then(() => {
|
|
1056
|
+
this.focusLauncherButton();
|
|
1057
|
+
requestAnimationFrame(() => this.focusLauncherButton());
|
|
1058
|
+
});
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1061
|
+
private currentLauncherButton(): HTMLElement | null {
|
|
1062
|
+
const launcherShadow =
|
|
1063
|
+
this.shadowRoot?.getElementById("meetelise-launcher")?.shadowRoot;
|
|
1064
|
+
const directButton = launcherShadow?.querySelector(
|
|
1065
|
+
"#type-hey__ask-prompt, button[aria-label='Chat with us']"
|
|
1066
|
+
);
|
|
1067
|
+
const mobileButton = launcherShadow
|
|
1068
|
+
?.querySelector("mobile-launcher")
|
|
1069
|
+
?.shadowRoot?.querySelector("button[aria-label='Chat with us']");
|
|
1070
|
+
if (directButton instanceof HTMLElement) return directButton;
|
|
1071
|
+
if (mobileButton instanceof HTMLElement) return mobileButton;
|
|
1072
|
+
return null;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1121
1075
|
render(): TemplateResult {
|
|
1122
1076
|
installLauncher();
|
|
1123
1077
|
const showChatAdditionalActions =
|
|
@@ -1139,9 +1093,13 @@ export class MEChat extends LitElement {
|
|
|
1139
1093
|
.building=${this.buildingWebchatView}
|
|
1140
1094
|
.primaryColor=${this.primaryColor}
|
|
1141
1095
|
.backgroundColor=${this.backgroundColor}
|
|
1142
|
-
.onClickExit=${this.
|
|
1096
|
+
.onClickExit=${this.closeChatAndRestoreFocus}
|
|
1143
1097
|
.onMount=${() => {
|
|
1144
1098
|
this.adjustPositionChatAdditionalActions();
|
|
1099
|
+
this.launcherButton = this.currentLauncherButton();
|
|
1100
|
+
if (!this.focusChatOnMount) return;
|
|
1101
|
+
this.focusChatOnMount = false;
|
|
1102
|
+
this.focusMessageFieldOnOpen();
|
|
1145
1103
|
}}
|
|
1146
1104
|
.requiresConsent=${this.requiresConsent}
|
|
1147
1105
|
.hideMobileFeatures=${this.hideMobileFeatures}
|
|
@@ -1167,12 +1125,7 @@ export class MEChat extends LitElement {
|
|
|
1167
1125
|
.onClickEmailOption=${this.handleContactClicked}
|
|
1168
1126
|
.onClickPhoneOption=${this.handleContactTabClicked}
|
|
1169
1127
|
.onClickSSTOption=${this.handleTourClicked}
|
|
1170
|
-
.onClose=${
|
|
1171
|
-
this.displayPubnubChat = false;
|
|
1172
|
-
this.showTourNextToChat = false;
|
|
1173
|
-
this.hideLauncher = false;
|
|
1174
|
-
localStorage.setItem("isChatOpen", "false");
|
|
1175
|
-
}}
|
|
1128
|
+
.onClose=${this.closeChatAndRestoreFocus}
|
|
1176
1129
|
></chat-additional-actions>
|
|
1177
1130
|
`
|
|
1178
1131
|
: ""
|
|
@@ -357,7 +357,7 @@ export class MESelect extends LitElement {
|
|
|
357
357
|
</svg>
|
|
358
358
|
</div>
|
|
359
359
|
${this.isOpen
|
|
360
|
-
? html`<ul id=${this.listboxId} role="listbox">
|
|
360
|
+
? html`<ul id=${this.listboxId} role="listbox" tabindex="-1">
|
|
361
361
|
${visibleOptions.map(
|
|
362
362
|
(option, index) =>
|
|
363
363
|
html`<li
|
|
@@ -201,4 +201,16 @@ export const pubnubChatStyles = css`
|
|
|
201
201
|
.checkbox:hover {
|
|
202
202
|
opacity: 0.5;
|
|
203
203
|
}
|
|
204
|
+
|
|
205
|
+
.sr-only {
|
|
206
|
+
position: absolute;
|
|
207
|
+
width: 1px;
|
|
208
|
+
height: 1px;
|
|
209
|
+
padding: 0;
|
|
210
|
+
margin: -1px;
|
|
211
|
+
overflow: hidden;
|
|
212
|
+
clip: rect(0, 0, 0, 0);
|
|
213
|
+
white-space: nowrap;
|
|
214
|
+
border: 0;
|
|
215
|
+
}
|
|
204
216
|
`;
|