diff --git a/blocks/chat-cta/chat-cta.css b/blocks/chat-cta/chat-cta.css index f7c055b..712da6e 100644 --- a/blocks/chat-cta/chat-cta.css +++ b/blocks/chat-cta/chat-cta.css @@ -3,11 +3,15 @@ align-items: center; justify-content: center; position: fixed; - width: 100%; - height: 48px; - right: 0; - bottom: 0; - background-color: var(--link-color-dark); + width: fit-content; + height: 56px; + right: 10px; + bottom: 10px; + background-color: var(--color-white); + border-radius: 6px; + border: 1px solid #909090; + box-shadow: 0 0 15px rgba(0 0 0 / 20%); + padding: 0 24px; } [dir=rtl] .cta-chat-sticky { @@ -25,11 +29,10 @@ .chat-cta .fragment .section { margin: 0; - padding: 30px; } .chat-cta .fragment .section .icon-block { - padding: 50px 0; + padding: 40px 0; width: 100%; } @@ -37,13 +40,8 @@ border-bottom: 1px solid rgb(112 112 112); } -.cta-chat-sticky svg { - display: none; -} - .cta-chat-sticky .con-button.outline { border-color: var(--color-white); - color: var(--color-white); } .cta-chat-sticky .con-button.outline:hover { @@ -51,6 +49,11 @@ background-color: var(--color-white); } +.dialog-modal.chat-cta { + bottom: 10px; + top: unset; +} + .dialog-modal.chat-cta .icon-block .foreground .icon-area img { width: 39px; height: auto; @@ -76,7 +79,7 @@ display: block; } -.cta-hidden { +.cta-chat-sticky.cta-hidden { display: none; } @@ -92,19 +95,21 @@ position: fixed; width: fit-content; height: 56px; - right: 0; - bottom: 100px; + right: 10px; + bottom: 56px; background-color: var(--color-white); - border-radius: 6px 0 0 6px; + border-radius: 6px; + border: 1px solid #909090; box-shadow: 0 0 15px rgba(0 0 0 / 20%); + padding: 0 24px; } .cta-chat-sticky a.con-button.outline { padding: 20px 20px 20px 0; - font-size: var(--type-body-xxs-size); + font-size: 16px; font-weight: bold; border: none; - color: var(--link-color-dark); + color: #2c2c2c; } .cta-chat-sticky span { @@ -113,14 +118,13 @@ .cta-chat-sticky svg { display: block; - margin-left: var(--spacing-xs); - height: 16px; + height: 26px; width: auto; top: 0; } .cta-chat-sticky svg path { - fill: var(--link-color-dark); + fill: #2c2c2c; } .chat-cta .fragment .section .icon-block { @@ -134,12 +138,13 @@ .dialog-modal.chat-cta { position: fixed; - right: 0; + right: 10px; bottom: 100px; top: auto; left: auto; box-shadow: 0 0 15px rgba(0 0 0 / 20%); - border-radius: 6px 0 0 6px; + border-radius: 6px; + border: 1px solid #909090; } .dialog-modal.chat-cta .section .icon-block .foreground .text-content p.icon-area { diff --git a/blocks/cta-widget/cta-widget.css b/blocks/cta-widget/cta-widget.css new file mode 100644 index 0000000..1cd23a1 --- /dev/null +++ b/blocks/cta-widget/cta-widget.css @@ -0,0 +1,181 @@ +.cta-widget { + position: fixed; + width: fit-content; + height: 56px; + right: 10px; + bottom: 10px; + background-color: var(--color-white); + border-radius: 6px; + border: 1px solid #909090; + box-shadow: 2px 4px 6px 0 #0003; + z-index: 4; + padding: 0; + font-family: var(--body-font-family); + color: var(--text-color); +} + +.cta-widget div { + display: flex; + justify-content: center; + align-items: center; + font-size: 16px; + font-weight: 700; + padding: 0 24px; +} + +.cta-widget span.icon-chat { + margin-inline-end: 13px; + width: auto; +} + +.cta-widget .icon-chat svg { + width: 26px; + height: auto; +} + +.cta-widget-body { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + margin: auto auto 0; + position: fixed; + right: 0; + bottom: 10px; + left: 0; + box-shadow: 2px 4px 6px 0 #0003; + border-radius: 6px; + border: 1px solid #909090; + z-index: 12; + background-color: var(--background-color); + width: 340px; + max-height: calc(100vh - 20px); + padding: 40px 33px; + box-sizing: border-box; + overflow-y: auto; +} + +.cta-widget-body.hidden, +.cta-widget.hidden, +.cta-curtain.hidden { + display: none; +} + +.cta-widget-body div { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; +} + +.cta-widget-body div:first-of-type { + padding-bottom: 32px; + border-bottom: 1px solid rgb(112 112 112); +} + +.cta-widget-body div:last-of-type { + margin-top: 32px; +} + +.cta-widget-body div img { + max-width: 32px; +} + +.cta-widget-body div :is(h1, h2, h3, h4, h5, h6) { + font-size: var(--type-heading-s-size); + margin: 0; + line-height: var(--type-heading-s-lh); + max-width: 200px; +} + +.cta-widget-body div p { + font-size: var(--type-body-xs-size); + line-height: var(--type-body-xs-lh); + margin-bottom: var(--spacing-xs); + max-width: 200px; + text-align: center; +} + +.cta-widget-body div p:first-of-type { + margin: 0 0 16px; +} + +.cta-widget-body div p:nth-child(3) { + margin: 5px 0 24px; +} + +.cta-widget-body div p:last-of-type { + margin: 0; +} + +.widget-close { + width: 18px; + height: auto; + position: absolute; + top: 16.5px; + right: 14px; + padding: 0; + background-color: transparent; + border: none; + color: var(--text-color); +} + +.cta-curtain { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: rgb(0 0 0 / 50%); + z-index: 11; +} + +@media screen and (min-width: 900px), + screen and (max-height: 499px) { + .cta-widget-body { + flex-direction: row; + max-width: 482px; + width: unset; + height: unset; + top: auto; + right: 10px; + bottom: 10px; + left: auto; + margin: 0; + padding: 32px; + align-items: stretch; + } + + .cta-widget-body div { + max-width: 241px; + align-items: flex-start; + justify-content: flex-start; + } + + .cta-widget-body div p { + max-width: 177px; + text-align: left; + } + + .cta-widget-body div p:nth-child(3) { + flex-grow: 1; + } + + .cta-widget-body div:first-of-type { + padding-right: 32px; + padding-bottom: 0; + border-right: 1px solid rgb(112 112 112); + border-bottom: none; + } + + .cta-widget-body div:last-of-type { + margin: 0; + padding-left: 32px; + } +} + +@media screen and (min-width: 900px) { + .cta-curtain { + display: none; + } +} diff --git a/blocks/cta-widget/cta-widget.js b/blocks/cta-widget/cta-widget.js new file mode 100644 index 0000000..f45a16e --- /dev/null +++ b/blocks/cta-widget/cta-widget.js @@ -0,0 +1,40 @@ +import { LIBS } from '../../scripts/scripts.js'; + +const CLOSE_ICON = ` + + `; + +export default async function init(el) { + const { createTag } = await import(`${LIBS}/utils/utils.js`); + + const [widgetDiv, cta1Div, cta2Div] = el.querySelectorAll(':scope > div'); + const widgetSection = createTag('button', { class: 'cta-widget', tabindex: '0' }, widgetDiv.querySelector('div')); + const ctaSections = [cta1Div.querySelector('div'), cta2Div.querySelector('div')]; + const ctaSection = createTag('section', { class: 'cta-widget-body', tabindex: '0' }, ctaSections); + const close = createTag('button', { + class: 'widget-close', + 'aria-label': 'Close', + }, CLOSE_ICON); + const curtain = createTag('div', { class: 'cta-curtain' }); + + ctaSections.forEach((section) => section.querySelector('a')?.classList.add('con-button', 'outline')); + + ctaSection.classList.add('hidden'); + ctaSection.prepend(close); + curtain.classList.add('hidden'); + + widgetSection.addEventListener('click', () => { + ctaSection.classList.remove('hidden'); + curtain.classList.remove('hidden'); + widgetSection.classList.add('hidden'); + }); + + close.addEventListener('click', () => { + widgetSection.classList.remove('hidden'); + ctaSection.classList.add('hidden'); + curtain.classList.add('hidden'); + }); + + el.after(ctaSection, widgetSection, curtain); + el.remove(); +} diff --git a/scripts/scripts.js b/scripts/scripts.js index 8565274..d82b226 100644 --- a/scripts/scripts.js +++ b/scripts/scripts.js @@ -126,7 +126,10 @@ const CONFIG = { ], useDotHtml: true, dynamicNavKey: 'bacom', - stageDomainsMap: { 'business.stage.adobe.com': { 'business.adobe.com': 'origin' } }, + stageDomainsMap: { + 'business.stage.adobe.com': { 'business.adobe.com': 'origin' }, + '.business-graybox.adobe.com': { 'business.adobe.com': 'origin' }, + }, }; const eagerLoad = (img) => { diff --git a/test/blocks/cta-widget/cta-widget.test.js b/test/blocks/cta-widget/cta-widget.test.js new file mode 100644 index 0000000..2feba7a --- /dev/null +++ b/test/blocks/cta-widget/cta-widget.test.js @@ -0,0 +1,33 @@ +import { readFile } from '@web/test-runner-commands'; +import { expect } from '@esm-bundle/chai'; + +const { default: init } = await import('../../../blocks/cta-widget/cta-widget.js'); + +describe('CTA Widget', () => { + before(async () => { + document.body.innerHTML = await readFile({ path: './mocks/body.html' }); + await init(document.querySelector('.cta-widget')); + }); + + it('Toggles body on click', () => { + const cta = document.querySelector('.cta-widget'); + const body = document.querySelector('.cta-widget-body'); + const curtain = document.querySelector('.cta-curtain'); + cta.click(); + expect(body.classList.contains('hidden')).to.be.false; + expect(curtain.classList.contains('hidden')).to.be.false; + expect(cta.classList.contains('hidden')).to.be.true; + + const close = document.querySelector('.widget-close'); + close.click(); + expect(body.classList.contains('hidden')).to.be.true; + expect(curtain.classList.contains('hidden')).to.be.true; + expect(cta.classList.contains('hidden')).to.be.false; + }); + + it('Decorates the button correctly for mobile', () => { + const anchor = document.querySelector('a'); + expect(anchor.classList.contains('con-button')).to.be.true; + expect(anchor.classList.contains('outline')).to.be.true; + }); +}); diff --git a/test/blocks/cta-widget/mocks/body.html b/test/blocks/cta-widget/mocks/body.html new file mode 100644 index 0000000..61cc5d9 --- /dev/null +++ b/test/blocks/cta-widget/mocks/body.html @@ -0,0 +1,31 @@ +
+
+
+
Contact Us
+
+
+
+

+ + + +

+

Chat with us.

+

Get answers to your questions with the Adobe Assistant.

+

Chat now

+
+
+
+
+

+ + + +

+

Contact Sales.

+

Learn what Adobe Experience Cloud can do for your business.

+

Get started

+
+
+
+