Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion src/GleapFeedbackButtonManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export default class GleapFeedbackButtonManager {
}
}

feedbackButtonPressed() {
feedbackButtonPressed(fromKeyboard = false) {
var frameManager = GleapFrameManager.getInstance();
if (frameManager.isOpened()) {
frameManager.hideWidget();
Expand All @@ -93,7 +93,24 @@ export default class GleapFeedbackButtonManager {
frameManager.setAppMode('widget');
frameManager.showWidget();
this.updateRedDot(false);
// Opened from the keyboard: the keyboard moves into the messenger with it.
if (fromKeyboard) {
frameManager.focusFrame();
}
}
}

/**
* The messenger closed while the keyboard was in it (Escape, its close button): the keyboard
* comes back to the launcher instead of the top of the page.
*/
restoreFocus() {
if (!this.feedbackButton || !this.feedbackButton.isConnected) {
return;
}
try {
this.feedbackButton.focus({ preventScroll: true });
} catch (e) {}
}

/**
Expand All @@ -105,10 +122,20 @@ export default class GleapFeedbackButtonManager {
}
this.injectedFeedbackButton = true;

// A div (a <button> would take the host page's button styles), made a real button for the
// keyboard and screen readers: Tab reaches it, Enter and Space open it.
var elem = document.createElement('div');
elem.setAttribute('role', 'button');
elem.setAttribute('tabindex', '0');
elem.addEventListener('click', () => {
this.feedbackButtonPressed();
});
elem.addEventListener('keydown', (event) => {
if (event.key === 'Enter' || event.key === ' ' || event.key === 'Spacebar') {
event.preventDefault();
this.feedbackButtonPressed(true);
}
});
this.attachPressAnimation(elem);
document.body.appendChild(elem);
this.feedbackButton = elem;
Expand Down Expand Up @@ -244,6 +271,12 @@ export default class GleapFeedbackButtonManager {
this.feedbackButton.className = 'bb-feedback-button gleap-font rr-block';
pressAnimationClasses.forEach((className) => this.feedbackButton.classList.add(className));
this.feedbackButton.setAttribute('dir', GleapTranslationManager.getInstance().isRTLLayout ? 'rtl' : 'ltr');
const isWidgetOpen = GleapFrameManager.getInstance().isOpened();
this.feedbackButton.setAttribute('aria-expanded', isWidgetOpen ? 'true' : 'false');
this.feedbackButton.setAttribute(
'aria-label',
(flowConfig.widgetButtonText && `${flowConfig.widgetButtonText}`.trim()) || 'Open support chat'
);

if (
flowConfig.feedbackButtonPosition === GleapFeedbackButtonManager.FEEDBACK_BUTTON_CLASSIC ||
Expand Down
19 changes: 19 additions & 0 deletions src/GleapFrameManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -963,12 +963,28 @@ export default class GleapFrameManager {
}
}

/** Moves the keyboard into the messenger (the launcher opened it from the keyboard). */
focusFrame() {
setTimeout(() => {
try {
const frame = this.gleapFrameContainer && this.gleapFrameContainer.querySelector('.gleap-frame');
if (frame) frame.focus({ preventScroll: true });
} catch (e) {}
}, 0);
}

hideWidget(resetRoutes = false) {
// The standalone survey page (legacy) and inline survey pages can't be closed.
if (this.appMode === 'survey_web' || this.appMode === 'survey_page') {
return;
}

// The keyboard was in the messenger: it goes back to the launcher once it closes.
let hadFocus = false;
try {
hadFocus = !!this.gleapFrameContainer && this.gleapFrameContainer.contains(document.activeElement);
} catch (e) {}

// A survey the messenger closes before it was shown (nothing to ask): it must not open after
// all, and there is nothing to animate and no close event without an open.
const wasOpened = this.widgetOpened;
Expand Down Expand Up @@ -1027,6 +1043,9 @@ export default class GleapFrameManager {
if (typeof window !== 'undefined' && typeof window.focus !== 'undefined') {
window.focus();
}
if (hadFocus) {
GleapFeedbackButtonManager.getInstance().restoreFocus();
}
}

sendMessage(data, queue = false) {
Expand Down
10 changes: 10 additions & 0 deletions src/UI.js
Original file line number Diff line number Diff line change
Expand Up @@ -1659,6 +1659,16 @@ export const injectStyledCSS = (
left: auto;
}

.bb-feedback-button:focus {
outline: none;
}

.bb-feedback-button:focus-visible .bb-feedback-button-icon,
.bb-feedback-button:focus-visible .bb-feedback-button-classic {
outline: 2px solid ${buttonColor};
outline-offset: 3px;
}

.bb-feedback-button--disabled {
display: none !important;
}
Expand Down
Loading