diff --git a/modules/conversion-center/assets/js/frontend/handlers/contact-buttons.js b/modules/conversion-center/assets/js/frontend/handlers/contact-buttons.js index a5de4a9755eb..3d135e94abbd 100644 --- a/modules/conversion-center/assets/js/frontend/handlers/contact-buttons.js +++ b/modules/conversion-center/assets/js/frontend/handlers/contact-buttons.js @@ -63,6 +63,7 @@ export default class ContactButtonsHandler extends Base { if ( this.elements.contentWrapper ) { this.elements.contentWrapper.addEventListener( 'click', this.onChatButtonTrackClick.bind( this ) ); + window.addEventListener( 'keyup', this.onDocumentKeyup.bind( this ) ); } window.addEventListener( 'beforeunload', () => { @@ -72,6 +73,46 @@ export default class ContactButtonsHandler extends Base { } ); } + contentWrapperIsHidden( hide ) { + if ( ! this.elements.contentWrapper ) { + return false; + } + + const { hidden } = this.getSettings( 'constants' ); + + // Set current state + if ( true === hide ) { + this.elements.contentWrapper.classList.add( hidden ); + this.elements.contentWrapper.setAttribute( 'aria-hidden', 'true' ); + return; + } + + if ( false === hide ) { + this.elements.contentWrapper.classList.remove( hidden ); + this.elements.contentWrapper.setAttribute( 'aria-hidden', 'false' ); + return; + } + + // Get current state + return this.elements.contentWrapper.classList.contains( hidden ); + } + + onDocumentKeyup( event ) { + // Bail if not ESC key + if ( event.keyCode !== 27 || ! this.elements.main ) { + return; + } + + /* eslint-disable @wordpress/no-global-active-element */ + if ( + ! this.contentWrapperIsHidden() && + this.elements.main.contains( document.activeElement ) + ) { + this.closeChatBox(); + } + /* eslint-enable @wordpress/no-global-active-element */ + } + onChatButtonTrackClick( event ) { const targetElement = event.target || event.srcElement; const selectors = this.getSettings( 'selectors' ); @@ -182,7 +223,7 @@ export default class ContactButtonsHandler extends Base { } openChatBox() { - const { hasAnimations, visible, hidden } = this.getSettings( 'constants' ); + const { hasAnimations, visible } = this.getSettings( 'constants' ); if ( this.elements.main && this.elements.main.classList.contains( hasAnimations ) ) { this.chatBoxEntranceAnimation(); @@ -191,11 +232,13 @@ export default class ContactButtonsHandler extends Base { } if ( this.elements.contentWrapper ) { - this.elements.contentWrapper.classList.remove( hidden ); + this.contentWrapperIsHidden( false ); + this.elements.contentWrapper.setAttribute( 'tabindex', '0' ); + this.elements.contentWrapper.focus( { focusVisible: true } ); } if ( this.elements.chatButton ) { - this.elements.chatButton.setAttribute( 'aria-expanded', 'false' ); + this.elements.chatButton.setAttribute( 'aria-expanded', 'true' ); } if ( this.elements.closeButton ) { @@ -204,7 +247,7 @@ export default class ContactButtonsHandler extends Base { } closeChatBox() { - const { hasAnimations, visible, hidden } = this.getSettings( 'constants' ); + const { hasAnimations, visible } = this.getSettings( 'constants' ); if ( this.elements.main && this.elements.main.classList.contains( hasAnimations ) ) { this.chatBoxExitAnimation(); @@ -213,11 +256,12 @@ export default class ContactButtonsHandler extends Base { } if ( this.elements.contentWrapper ) { - this.elements.contentWrapper.classList.add( hidden ); + this.contentWrapperIsHidden( true ); } if ( this.elements.chatButton ) { - this.elements.chatButton.setAttribute( 'aria-expanded', 'true' ); + this.elements.chatButton.setAttribute( 'aria-expanded', 'false' ); + this.elements.chatButton.focus( { focusVisible: true } ); } if ( this.elements.closeButton ) { @@ -226,9 +270,7 @@ export default class ContactButtonsHandler extends Base { } onChatButtonClick() { - const { hidden } = this.getSettings( 'constants' ); - - if ( this.elements.contentWrapper && this.elements.contentWrapper.classList.contains( hidden ) ) { + if ( this.elements.contentWrapper && this.contentWrapperIsHidden() ) { this.openChatBox(); } else { this.closeChatBox(); @@ -274,6 +316,33 @@ export default class ContactButtonsHandler extends Base { } initDefaultState() { + // Manage accessibility + if ( this.elements.contentWrapper ) { + const randomishId = String( + Date.now().toString( 32 ) + + Math.random().toString( 16 ), + ).replace( /\./g, '' ); + + const wrapperID = this.elements.contentWrapper.id + ? this.elements.contentWrapper.id + : `e-contact-buttons__content-wrapper-${ randomishId }`; + + const isHidden = this.contentWrapperIsHidden(); + + this.elements.contentWrapper.setAttribute( 'id', wrapperID ); + + if ( this.elements.chatButton ) { + this.elements.chatButton.setAttribute( 'aria-expanded', ! isHidden ); + this.elements.chatButton.setAttribute( 'aria-controls', wrapperID ); + } + + if ( this.elements.closeButton ) { + this.elements.closeButton.setAttribute( 'aria-expanded', ! isHidden ); + this.elements.closeButton.setAttribute( 'aria-controls', wrapperID ); + } + } + + // Default to open in Editor if ( elementorFrontend.isEditMode() ) { this.openChatBox(); } @@ -290,8 +359,10 @@ export default class ContactButtonsHandler extends Base { this.initDefaultState(); - if ( this.elements.chatButton.classList.contains( hasEntranceAnimation ) ) { - this.initChatButtonEntranceAnimation(); + if ( this.elements.chatButton ) { + if ( this.elements.chatButton.classList.contains( hasEntranceAnimation ) ) { + this.initChatButtonEntranceAnimation(); + } } } } diff --git a/modules/conversion-center/assets/scss/widgets/contact-buttons-var-3.scss b/modules/conversion-center/assets/scss/widgets/contact-buttons-var-3.scss index fcfa44dc21a4..3ac7a25292e8 100644 --- a/modules/conversion-center/assets/scss/widgets/contact-buttons-var-3.scss +++ b/modules/conversion-center/assets/scss/widgets/contact-buttons-var-3.scss @@ -48,7 +48,7 @@ &__chat-button { - &[aria-expanded="false"] { + &[aria-expanded="true"] { background-color: var(--e-contact-buttons-active-button-bg); svg { @@ -63,27 +63,27 @@ &.has-size-small { height: var(--e-contact-buttons-size-small); width: var(--e-contact-buttons-size-small); - + svg { height: var(--e-contact-buttons-svg-size-small); width: var(--e-contact-buttons-svg-size-small); } } - + &.has-size-medium { height: var(--e-contact-buttons-size-medium); width: var(--e-contact-buttons-size-medium); - + svg { height: var(--e-contact-buttons-svg-size-medium); width: var(--e-contact-buttons-svg-size-medium); } } - + &.has-size-large { height: var(--e-contact-buttons-size-large); width: var(--e-contact-buttons-size-large); - + svg { height: var(--e-contact-buttons-svg-size-large); width: var(--e-contact-buttons-svg-size-large); @@ -113,7 +113,7 @@ position: absolute; inset-inline-end: 0; top: 0; - + &:hover, &:focus { background: none; @@ -168,7 +168,7 @@ } &.has-icon-position-start { - + .e-contact-buttons__contact-icon-container { order: 1; } diff --git a/modules/conversion-center/assets/scss/widgets/contact-buttons-var-4.scss b/modules/conversion-center/assets/scss/widgets/contact-buttons-var-4.scss index dfd13a949f20..034330e8a3aa 100644 --- a/modules/conversion-center/assets/scss/widgets/contact-buttons-var-4.scss +++ b/modules/conversion-center/assets/scss/widgets/contact-buttons-var-4.scss @@ -13,7 +13,7 @@ width: auto; &.has-h-alignment-end { - + .e-contact-buttons__chat-button-container { padding-inline-end: 0; } @@ -91,7 +91,7 @@ & .e-contact-buttons__contact-icon-container { height: var(--e-contact-buttons-size-small); width: var(--e-contact-buttons-size-small); - + svg { height: var(--e-contact-buttons-icon-small); width: var(--e-contact-buttons-icon-small); @@ -105,7 +105,7 @@ & .e-contact-buttons__contact-icon-container { height: var(--e-contact-buttons-size-medium); width: var(--e-contact-buttons-size-medium); - + svg { height: var(--e-contact-buttons-icon-medium); width: var(--e-contact-buttons-icon-medium); @@ -119,7 +119,7 @@ & .e-contact-buttons__contact-icon-container { height: var(--e-contact-buttons-size-large); width: var(--e-contact-buttons-size-large); - + svg { height: var(--e-contact-buttons-icon-large); width: var(--e-contact-buttons-icon-large); @@ -132,7 +132,7 @@ &__chat-buttons-container { display: flex; } - + &__close-button { background-color: var(--e-contact-buttons-active-button-bg); color: var(--e-contact-buttons-active-button-color); @@ -142,28 +142,35 @@ position: relative; top: unset; } - - &__close-button, + + &__chat-button { - + + &[aria-expanded="true"] { + display: none; + } + } + + &__close-button { + &[aria-expanded="false"] { display: none; } } - + &__content { border-radius: 0; box-shadow: none; margin: 0; overflow: visible; } - + &__contact-links { display: flex; flex-direction: column; gap: var(--e-contact-buttons-contact-gap); } - + &__contact-icon-container { align-items: center; background-color: var(--e-contact-buttons-contact-button-bg); @@ -172,31 +179,31 @@ justify-content: center; transition: $transition-hover; } - + &__contact-icon-link { align-items: center; display: flex; flex-direction: row; gap: 14px; - + svg { fill: var(--e-contact-buttons-contact-button-icon); } - + &:hover, &:focus { - + .e-contact-buttons__contact-icon-container { background-color: var(--e-contact-buttons-contact-button-bg-hover); transition: $transition-hover; } - + svg { fill: var(--e-contact-buttons-contact-button-icon-hover); } } } - + &__contact-tooltip { background-color: var(--e-contact-buttons-tooltip-bg); border-radius: 16px; @@ -206,7 +213,7 @@ line-height: 25px; padding: 4px 14px; position: relative; - + &::after { border-style: solid; content: ""; @@ -218,4 +225,4 @@ } } } -} \ No newline at end of file +} diff --git a/modules/conversion-center/assets/scss/widgets/contact-buttons-var-8.scss b/modules/conversion-center/assets/scss/widgets/contact-buttons-var-8.scss index ba8eba9c724d..391126190fda 100644 --- a/modules/conversion-center/assets/scss/widgets/contact-buttons-var-8.scss +++ b/modules/conversion-center/assets/scss/widgets/contact-buttons-var-8.scss @@ -22,23 +22,23 @@ &.has-platform-url { --e-contact-buttons-contact-button-icon: #467FF7; } - + &.has-platform-whatsapp { --e-contact-buttons-contact-button-icon: #25D366; } - + &.has-platform-skype { --e-contact-buttons-contact-button-icon: #00AFF0; } - + &.has-platform-messenger { --e-contact-buttons-contact-button-icon: #168AFF; } - + &.has-platform-viber { --e-contact-buttons-contact-button-icon: #7360F2; } - + &.has-platform-waze { --e-contact-buttons-contact-button-icon: #33CCFF; } @@ -79,7 +79,7 @@ &__chat-buttons-container { display: flex; } - + &__close-button { background-color: var(--e-contact-buttons-active-button-bg); border-radius: 50%; @@ -89,34 +89,40 @@ position: relative; top: unset; } - - &__close-button, + &__chat-button { - + + &[aria-expanded="true"] { + display: none; + } + } + + &__close-button { + &[aria-expanded="false"] { display: none; } } - + &__top-bar-title { font-size: 16px; line-height: 24px; font-weight: 600; } - + &__top-bar-subtitle { font-size: 12px; line-height: 16px; font-weight: 500px; } - + &__contact-links { display: flex; flex-direction: column; gap: 12px; padding: 12px; } - + &__contact-icon-link { background-color: var(--e-contact-buttons-contact-button-bg); border-start-end-radius: 15px; @@ -128,39 +134,39 @@ grid-column-gap: 12px; grid-row-gap: 0; padding: 10px 20px; - + svg { fill: var(--e-contact-buttons-contact-button-icon); } } - + &__contact-icon-link.has-size-small { svg { height: 22px; width: 22px; } } - + &__contact-icon-link.has-size-medium { svg { height: 28px; width: 28px; } } - + &__contact-icon-link.has-size-large { svg { height: 36px; width: 36px; } } - + &__contact-icon-container { align-items: center; display: flex; grid-area: 1 / 1 / 3 / 2; } - + &__contact-title { color: var(--e-contact-buttons-contact-title-text-color); grid-area: 1 / 2 / 2 / 3; @@ -168,7 +174,7 @@ font-weight: 600; line-height: 24px; } - + &__contact-description { color: var(--e-contact-buttons-contact-description-text-color); grid-area: 2 / 2 / 3 / 3; @@ -176,9 +182,9 @@ font-weight: 300; line-height: 16px; } - + &__links-container { background-color: var(--e-contact-buttons-chat-box-bg); } } -} \ No newline at end of file +} diff --git a/modules/conversion-center/classes/render/contact-buttons-core-render.php b/modules/conversion-center/classes/render/contact-buttons-core-render.php index 397ebde88c38..6dab6b2dcbee 100644 --- a/modules/conversion-center/classes/render/contact-buttons-core-render.php +++ b/modules/conversion-center/classes/render/contact-buttons-core-render.php @@ -13,6 +13,7 @@ class Contact_Buttons_Core_Render extends Contact_Buttons_Render_Base { public function render(): void { $this->build_layout_render_attribute(); + $this->add_content_wrapper_render_attribute(); $content_classnames = 'e-contact-buttons__content'; $animation_duration = $this->settings['style_chat_box_animation_duration']; @@ -26,7 +27,7 @@ public function render(): void { ] ); ?>