Repository: adobecom/milo
Pull request #3989: MWPW-171550 | Focus for split notification
Author: login: aishwaryamathuria
Labels: name: verified
description: PR has been E2E tested by a reviewer
name: high priority
description: Why is this a high priority? Blocker? Critical? Dependency?
name: Ready for Stage
Created: 2025-04-17T08:36:28Z | Merged: 2025-04-22T11:01:10Z

Adding a **focus** variant to split notification to add focus curtain for the notification block.

Resolves: [MWPW-171550](https://jira.corp.adobe.com/browse/MWPW-171550)

**Test URLs:**
- Before: https://main--milo--adobecom.aem.page/drafts/mathuria/promobar/creativecloud?martech=off
- After: https://mwpw-171550--milo--adobecom.aem.page/drafts/mathuria/promobar/creativecloud?martech=off



















Diff:
diff --git a/libs/blocks/notification/notification.css b/libs/blocks/notification/notification.css
index 8857139f150..47d7874cc12 100644
--- a/libs/blocks/notification/notification.css
+++ b/libs/blocks/notification/notification.css
@@ -404,6 +404,29 @@
   max-width: unset;
 }
 
+.notification.split.focus {
+  width: 100%;
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+  z-index: var(--modal-z-index);
+}
+
+.notification-curtain {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  background: rgb(50 50 50 / 80%);
+  z-index: var(--modal-z-index-curtain);
+}
+
+@media screen and (max-width: 600px) {
+  .mobile-disable-scroll {
+    overflow: hidden;
+  }
+}
+
 @media screen and (min-width: 600px) {
   .notification {
     --max-inline-size-image: 188px;
@@ -551,7 +574,8 @@
   .notification.pill.max-width-12-tablet { max-width: 1200px; }
   .notification.pill.max-width-auto-tablet { max-width: unset; }
 
-  .notification.split {
+  .notification.split,
+  .notification-curtain {
     display: none;
   }
 }
diff --git a/libs/blocks/notification/notification.js b/libs/blocks/notification/notification.js
index 47379de670c..45a2dec5ef3 100644
--- a/libs/blocks/notification/notification.js
+++ b/libs/blocks/notification/notification.js
@@ -15,7 +15,7 @@
 */
 
 import { decorateBlockText, decorateBlockBg, decorateTextOverrides, decorateMultiViewport, loadCDT } from '../../utils/decorate.js';
-import { createTag, getConfig, loadStyle } from '../../utils/utils.js';
+import { createTag, getConfig, loadStyle, createIntersectionObserver } from '../../utils/utils.js';
 
 const { miloLibs, codeRoot } = getConfig();
 const base = miloLibs || codeRoot;
@@ -91,6 +91,10 @@ function addCloseAction(el, btn) {
     if (btn.nodeName === 'A') e.preventDefault();
     el.style.display = 'none';
     el.closest('.section')?.classList.add('close-sticky-section');
+    if (el.classList.contains('focus')) {
+      document.body.classList.remove('mobile-disable-scroll');
+      el.closest('.section').querySelector('.notification-curtain').remove();
+    }
     document.dispatchEvent(new CustomEvent('milo:sticky:closed'));
   });
 }
@@ -136,6 +140,12 @@ async function decorateLockup(lockupArea, el) {
   if (pre && pre[2] === 'icon') el.classList.replace(pre[0], `${pre[1]}-lockup`);
 }
 
+function curtainCallback(el) {
+  const curtain = createTag('div', { class: 'notification-curtain' });
+  document.body.classList.add('mobile-disable-scroll');
+  el.insertAdjacentElement('afterend', curtain);
+}
+
 function decorateSplitList(el, listContent) {
   const closeEvent = '#_evt-close';
   const listContainer = createTag('div', { class: 'split-list-area' });
@@ -160,6 +170,18 @@ function decorateSplitList(el, listContent) {
     pic.querySelector('img').loading = 'eager';
   });
   listContent.replaceWith(listContainer);
+
+  if (el.classList.contains('focus')) {
+    if (el.classList.contains('no-delay')) {
+      curtainCallback(el);
+      return;
+    }
+    createIntersectionObserver({
+      el,
+      option: { once: true },
+      callback: () => curtainCallback(el),
+    });
+  }
 }
 
 async function decorateForegroundText(el, container) {
diff --git a/libs/blocks/section-metadata/section-metadata.css b/libs/blocks/section-metadata/section-metadata.css
index b38f9359990..c52cdf291ba 100644
--- a/libs/blocks/section-metadata/section-metadata.css
+++ b/libs/blocks/section-metadata/section-metadata.css
@@ -217,6 +217,10 @@
   bottom: 5px;
 }
 
+.section.sticky-bottom:has(.notification.split.focus) {
+  bottom: 0;
+}
+
 .section[class*='grid-width-'] {
   padding-left: var(--grid-margins-width);
   padding-right: var(--grid-margins-width);
diff --git a/test/blocks/notification/mocks/body.html b/test/blocks/notification/mocks/body.html
index 4f1f2038059..3058e609c69 100644
--- a/test/blocks/notification/mocks/body.html
+++ b/test/blocks/notification/mocks/body.html
@@ -573,4 +573,70 @@ <h1 id="get-the-full-experience-in-app">Get the full experience in app</h1>
     </div>
   </div>
 </div>
+<div class="section">
+  <div class="notification pill split focus no-delay">
+    <div>
+      <div data-valign="middle">#fff</div>
+    </div>
+    <div>
+      <div data-valign="middle">
+        <h1 id="get-the-full-experience-in-app">Get the full experience in app</h1>
+        <ul>
+          <li>
+            <picture>
+              <source type="image/webp" srcset="" media="(min-width: 600px)">
+              <source type="image/webp" srcset="">
+              <source type="image/png" srcset="" media="(min-width: 600px)">
+              <img loading="lazy" alt="" src="" width="25" height="24">
+            </picture> Adobe Firefly <strong><a href="https://adobe.com/">Get app</a></strong>
+          </li>
+          <li>
+            <picture>
+              <source type="image/webp" srcset="" media="(min-width: 600px)">
+              <source type="image/webp" srcset="">
+              <source type="image/png" srcset="" media="(min-width: 600px)">
+              <img loading="lazy" alt="" src="" width="100" height="96">
+            </picture>
+          </li>
+          <li>
+            Web Browser <em><a href="https://adobe.com/#_evt-close">Continue</a></em>
+          </li>
+        </ul>
+      </div>
+    </div>
+  </div>
+</div>
+<div class="section" style="display:none">
+  <div class="notification pill split focus">
+    <div>
+      <div data-valign="middle">#fff</div>
+    </div>
+    <div>
+      <div data-valign="middle">
+        <h1 id="get-the-full-experience-in-app">Get the full experience in app</h1>
+        <ul>
+          <li>
+            <picture>
+              <source type="image/webp" srcset="" media="(min-width: 600px)">
+              <source type="image/webp" srcset="">
+              <source type="image/png" srcset="" media="(min-width: 600px)">
+              <img loading="lazy" alt="" src="" width="25" height="24">
+            </picture> Adobe Firefly <strong><a href="https://adobe.com/">Get app</a></strong>
+          </li>
+          <li>
+            <picture>
+              <source type="image/webp" srcset="" media="(min-width: 600px)">
+              <source type="image/webp" srcset="">
+              <source type="image/png" srcset="" media="(min-width: 600px)">
+              <img loading="lazy" alt="" src="" width="100" height="96">
+            </picture>
+          </li>
+          <li>
+            Web Browser <em><a href="https://adobe.com/#_evt-close">Continue</a></em>
+          </li>
+        </ul>
+      </div>
+    </div>
+  </div>
+</div>
 <div></div>
diff --git a/test/blocks/notification/notification.test.js b/test/blocks/notification/notification.test.js
index 222e289c0cb..cde06aeacee 100644
--- a/test/blocks/notification/notification.test.js
+++ b/test/blocks/notification/notification.test.js
@@ -102,9 +102,23 @@ describe('notification', async () => {
       const stacks = splits[0].querySelectorAll('.split-list-item').length;
       expect(stacks).to.equal(2);
     });
+    it('has focus closes the notification', () => {
+      expect(splits[1].closest('.section').querySelector('.notification-curtain')).to.exist;
+    });
+    it('closes the notification and focus', () => {
+      setTimeout(() => {
+        splits[3].closest('.section').style.display = 'flex';
+        expect(splits[3].closest('.section').querySelector('.notification-curtain')).to.exist;
+      }, 2000);
+    });
     it('closes the notification', () => {
       splits[0].querySelector('a[href*="#_evt-close"]').dispatchEvent(new MouseEvent('click'));
       expect(splits[0].closest('.section').classList.contains('close-sticky-section')).to.be.true;
     });
+    it('closes the notification and focus', () => {
+      splits[1].querySelector('a[href*="#_evt-close"]').dispatchEvent(new MouseEvent('click'));
+      expect(splits[1].closest('.section').classList.contains('close-sticky-section')).to.be.true;
+      expect(splits[1].closest('.section').querySelector('.notification-curtain')).to.not.exist;
+    });
   });
 });


Reviews:
user: login: sharath-kannan
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T10:09:43Z
user: login: drashti1712
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T10:10:45Z

Review comments:

PR comments:
user: login: aem-code-sync[bot]
created_at: 2025-04-17T08:36:31Z
body: <!-- aem-bot-dash -->
Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch and validate page speed.
In case there are problems, just click a checkbox below to rerun the respective action.

- [ ] <!-- action-psi --> Re-run PSI checks
- [ ] <!-- action-sync --> Re-sync branch

<details>
<summary>Commits</summary>
<!-- commit-history -->

* [7ea5b18](https://github.com/adobecom/milo/commit/7ea5b18ba6bbc25ee97e171dadce12ac7fb56890) :white_check_mark: (latest)
* [a3bc51b](https://github.com/adobecom/milo/commit/a3bc51b378da5b8ec5b26590abb6fc270425d6ea) :white_check_mark:
* [c946978](https://github.com/adobecom/milo/commit/c94697862a7131abb054ce7db1ae1171aaa941d3) :white_check_mark:
* [c2e34b5](https://github.com/adobecom/milo/commit/c2e34b5d43bc73ce64b9e59b085c612875d1b6e6) :white_check_mark:
* [c80b09d](https://github.com/adobecom/milo/commit/c80b09d7905f58474026d0af3f3ebfea83ac7606) :white_check_mark:
* [3e1f59f](https://github.com/adobecom/milo/commit/3e1f59fe36bdf98e28ec7a519909d5b7eba71756) :white_check_mark:
* [28a2c7a](https://github.com/adobecom/milo/commit/28a2c7aa07d1cfb0488d693e068c3baaf9d5c619) :white_check_mark:
* [01a20b5](https://github.com/adobecom/milo/commit/01a20b5dd626aa240ae879f893ef677757335ad0) :white_check_mark:

<!-- commit-history-end -->
</details>
author_association: CONTRIBUTOR
user: login: aem-code-sync[bot]
created_at: 2025-04-17T08:37:19Z
body: <!-- aem-bot-psi -->
| | Page | Scores | Audits | Google |
|-|------|--------|--------|--------|
| :iphone: | [/drafts/mathuria/promobar/creativecloud?martech=off](https://mwpw-171550--milo--adobecom.aem.page/drafts/mathuria/promobar/creativecloud?martech=off) | [![PERFORMANCE](https://img.shields.io/badge/PERFORMANCE-95-green?style=for-the-badge "Performance")](https://googlechrome.github.io/lighthouse/scorecalc/#device=mobile&version=12.4.0&SI=5381.873089497406&FCP=933&LCP=1685.514305&TBT=0&CLS=0 "See Calculator") ![A11Y](https://img.shields.io/badge/A11Y-96-green?style=for-the-badge "Accessibility") ![SEO](https://img.shields.io/badge/SEO-69-orange?style=for-the-badge "SEO") ![BEST PRACTICES](https://img.shields.io/badge/BEST%20PRACTICES-96-green?style=for-the-badge "Best Practices") | ![SI](https://img.shields.io/badge/SI-5.4s-orange?style=for-the-badge "Speed Index") ![FCP](https://img.shields.io/badge/FCP-0.9s-green?style=for-the-badge "First Contentful Paint") ![LCP](https://img.shields.io/badge/LCP-1.7s-green?style=for-the-badge "Largest Contentful Paint") ![TBT](https://img.shields.io/badge/TBT-0ms-green?style=for-the-badge "Total Blocking Time") ![CLS](https://img.shields.io/badge/CLS-0-green?style=for-the-badge "Cumulative Layout Shift") | [![PSI](https://www.gstatic.com/images/icons/material/product/2x/pagespeed_16dp.png)](https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fmwpw-171550--milo--adobecom.aem.page%2Fdrafts%2Fmathuria%2Fpromobar%2Fcreativecloud%3Fmartech%3Doff "Run again in Google PSI") |
| :desktop_computer: | [/drafts/mathuria/promobar/creativecloud?martech=off](https://mwpw-171550--milo--adobecom.aem.page/drafts/mathuria/promobar/creativecloud?martech=off) | [![PERFORMANCE](https://img.shields.io/badge/PERFORMANCE-96-green?style=for-the-badge "Performance")](https://googlechrome.github.io/lighthouse/scorecalc/#device=mobile&version=12.4.0&SI=2043.9637564090829&FCP=265.836&LCP=468.897435&TBT=0&CLS=0.00495137711854922 "See Calculator") ![A11Y](https://img.shields.io/badge/A11Y-96-green?style=for-the-badge "Accessibility") ![SEO](https://img.shields.io/badge/SEO-69-orange?style=for-the-badge "SEO") ![BEST PRACTICES](https://img.shields.io/badge/BEST%20PRACTICES-96-green?style=for-the-badge "Best Practices") | ![SI](https://img.shields.io/badge/SI-2.0s-orange?style=for-the-badge "Speed Index") ![FCP](https://img.shields.io/badge/FCP-0.3s-green?style=for-the-badge "First Contentful Paint") ![LCP](https://img.shields.io/badge/LCP-0.5s-green?style=for-the-badge "Largest Contentful Paint") ![TBT](https://img.shields.io/badge/TBT-0ms-green?style=for-the-badge "Total Blocking Time") ![CLS](https://img.shields.io/badge/CLS-0.005-green?style=for-the-badge "Cumulative Layout Shift") | [![PSI](https://www.gstatic.com/images/icons/material/product/2x/pagespeed_16dp.png)](https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fmwpw-171550--milo--adobecom.aem.page%2Fdrafts%2Fmathuria%2Fpromobar%2Fcreativecloud%3Fmartech%3Doff "Run again in Google PSI") |

author_association: CONTRIBUTOR
user: login: aem-code-sync[bot]
created_at: 2025-04-17T08:37:19Z
body: <!-- aem-bot-psi -->
| | Page | Scores | Audits | Google |
|-|------|--------|--------|--------|
| :iphone: | [/drafts/mathuria/promobar/creativecloud?martech=off](https://mwpw-171550--milo--adobecom.aem.page/drafts/mathuria/promobar/creativecloud?martech=off) | [![PERFORMANCE](https://img.shields.io/badge/PERFORMANCE-97-green?style=for-the-badge "Performance")](https://googlechrome.github.io/lighthouse/scorecalc/#device=mobile&version=12.4.0&SI=4037.3028878000396&FCP=947.2151800000001&LCP=1730.1060875&TBT=70.32120499999996&CLS=0.0010728892888481278 "See Calculator") ![A11Y](https://img.shields.io/badge/A11Y-96-green?style=for-the-badge "Accessibility") ![SEO](https://img.shields.io/badge/SEO-69-orange?style=for-the-badge "SEO") ![BEST PRACTICES](https://img.shields.io/badge/BEST%20PRACTICES-96-green?style=for-the-badge "Best Practices") | ![SI](https://img.shields.io/badge/SI-4.0s-orange?style=for-the-badge "Speed Index") ![FCP](https://img.shields.io/badge/FCP-0.9s-green?style=for-the-badge "First Contentful Paint") ![LCP](https://img.shields.io/badge/LCP-1.7s-green?style=for-the-badge "Largest Contentful Paint") ![TBT](https://img.shields.io/badge/TBT-70ms-green?style=for-the-badge "Total Blocking Time") ![CLS](https://img.shields.io/badge/CLS-0.001-green?style=for-the-badge "Cumulative Layout Shift") | [![PSI](https://www.gstatic.com/images/icons/material/product/2x/pagespeed_16dp.png)](https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fmwpw-171550--milo--adobecom.aem.page%2Fdrafts%2Fmathuria%2Fpromobar%2Fcreativecloud%3Fmartech%3Doff "Run again in Google PSI") |
| :desktop_computer: | [/drafts/mathuria/promobar/creativecloud?martech=off](https://mwpw-171550--milo--adobecom.aem.page/drafts/mathuria/promobar/creativecloud?martech=off) | [![PERFORMANCE](https://img.shields.io/badge/PERFORMANCE-100-green?style=for-the-badge "Performance")](https://googlechrome.github.io/lighthouse/scorecalc/#device=mobile&version=12.4.0&SI=710.7021407414728&FCP=261.5&LCP=468.555935&TBT=0&CLS=0.00495137711854922 "See Calculator") ![A11Y](https://img.shields.io/badge/A11Y-96-green?style=for-the-badge "Accessibility") ![SEO](https://img.shields.io/badge/SEO-69-orange?style=for-the-badge "SEO") ![BEST PRACTICES](https://img.shields.io/badge/BEST%20PRACTICES-96-green?style=for-the-badge "Best Practices") | ![SI](https://img.shields.io/badge/SI-0.7s-green?style=for-the-badge "Speed Index") ![FCP](https://img.shields.io/badge/FCP-0.3s-green?style=for-the-badge "First Contentful Paint") ![LCP](https://img.shields.io/badge/LCP-0.5s-green?style=for-the-badge "Largest Contentful Paint") ![TBT](https://img.shields.io/badge/TBT-0ms-green?style=for-the-badge "Total Blocking Time") ![CLS](https://img.shields.io/badge/CLS-0.005-green?style=for-the-badge "Cumulative Layout Shift") | [![PSI](https://www.gstatic.com/images/icons/material/product/2x/pagespeed_16dp.png)](https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fmwpw-171550--milo--adobecom.aem.page%2Fdrafts%2Fmathuria%2Fpromobar%2Fcreativecloud%3Fmartech%3Doff "Run again in Google PSI") |

author_association: CONTRIBUTOR
user: login: spadmasa
created_at: 2025-04-21T10:24:33Z
body: Validation done on the pr
https://mwpw-171550--milo--adobecom.aem.page/drafts/mathuria/promobar/creativecloud?martech=off
![image](https://github.com/user-attachments/assets/b9623bae-596a-4f2d-88cb-47f8e086d946)
![image](https://github.com/user-attachments/assets/cf41bf77-3fb3-4da7-bc9e-8b1c85a50241)

https://main--cc--adobecom.aem.live/drafts/souj/mweb/creativecloud11?milolibs=mwpw-171550
![image](https://github.com/user-attachments/assets/8df87017-d52a-499c-92bb-60848c418d84)
![image](https://github.com/user-attachments/assets/9edbffcc-291c-4b05-8868-b84d60fd2b25)

regression on product pages
https://main--cc--adobecom.aem.live/creativecloud?milolibs=mwpw-171550
![image](https://github.com/user-attachments/assets/177d5742-afdc-4d6f-8303-fefbf9af6c2f)


author_association: NONE