From 136f3d263a083fa3403629484f121fa0f504492d Mon Sep 17 00:00:00 2001
From: Konstantin Gogov <konstantin.gogov@sap.com>
Date: Wed, 4 Sep 2024 18:26:20 +0300
Subject: [PATCH 1/4] feat(ui5-dynamic-page-title): add snapped title for
 mobile devices

- Introduced `snappedTitleOnMobile` property to display a simplified
  title on mobile when the header is snapped.
- Added `snappedTitleOnMobileText` to define the text for the
  mobile-specific snapped title.
- This feature optimizes title display on small screens, improving
  mobile usability.
- Clicking the snapped title on mobile expands the header.
- On non-mobile devices, the standard title is displayed, ignoring the
  mobile-specific title.
---
 packages/fiori/src/DynamicPage.hbs            |  30 +--
 packages/fiori/src/DynamicPage.ts             |  12 +
 packages/fiori/src/DynamicPageTitle.hbs       |  61 +++---
 packages/fiori/src/DynamicPageTitle.ts        |  38 +++-
 packages/fiori/src/themes/DynamicPage.css     |   7 +
 .../fiori/src/themes/DynamicPageTitle.css     |  15 ++
 .../base/DynamicPageTitle-parameters.css      |   2 +
 .../DynamicPageWithSnappedTitleOnMobile.html  | 205 ++++++++++++++++++
 .../test/specs/DynamicPage.mobile.spec.js     | 105 +++++++++
 packages/fiori/test/specs/DynamicPage.spec.js |  18 ++
 10 files changed, 452 insertions(+), 41 deletions(-)
 create mode 100644 packages/fiori/test/pages/DynamicPageWithSnappedTitleOnMobile.html
 create mode 100644 packages/fiori/test/specs/DynamicPage.mobile.spec.js

diff --git a/packages/fiori/src/DynamicPage.hbs b/packages/fiori/src/DynamicPage.hbs
index 8354e83c5a1e..c037ba01571b 100644
--- a/packages/fiori/src/DynamicPage.hbs
+++ b/packages/fiori/src/DynamicPage.hbs
@@ -17,7 +17,7 @@
 				{{> header-actions}}
 			{{/if}}
 		</header>
-
+		
 		{{#if headerInContent}}
 			<slot tabindex="{{headerTabIndex}}" ?aria-hidden="{{headerAriaHidden}}" name="headerArea"></slot>
 		{{/if}}
@@ -42,17 +42,19 @@
 </div>
 
 {{#*inline "header-actions"}}
-	{{#if hasHeading}}
-		<ui5-dynamic-page-header-actions
-			?snapped="{{headerSnapped}}"
-			?pinned="{{headerPinned}}"
-			?hide-pin-button="{{hidePinButton}}"
-			.accessibilityAttributes="{{_accAttributesForHeaderActions}}"
-			@ui5-expand-button-click={{onExpandClick}}
-			@ui5-pin-button-click={{onPinClick}}
-			@ui5-expand-button-hover-in={{onExpandHoverIn}}
-			@ui5-expand-button-hover-out={{onExpandHoverOut}}
-			>
-		</ui5-dynamic-page-header-actions>
-	{{/if}}
+	{{#unless hasSnappedTitleOnMobile}}
+		{{#if hasHeading}}
+			<ui5-dynamic-page-header-actions
+				?snapped="{{headerSnapped}}"
+				?pinned="{{headerPinned}}"
+				?hide-pin-button="{{hidePinButton}}"
+				.accessibilityAttributes="{{_accAttributesForHeaderActions}}"
+				@ui5-expand-button-click={{onExpandClick}}
+				@ui5-pin-button-click={{onPinClick}}
+				@ui5-expand-button-hover-in={{onExpandHoverIn}}
+				@ui5-expand-button-hover-out={{onExpandHoverOut}}
+				>
+			</ui5-dynamic-page-header-actions>
+		{{/if}}
+	{{/unless}}
 {{/inline}}
diff --git a/packages/fiori/src/DynamicPage.ts b/packages/fiori/src/DynamicPage.ts
index b9dbb5cfbef5..8b38ddd37dfd 100644
--- a/packages/fiori/src/DynamicPage.ts
+++ b/packages/fiori/src/DynamicPage.ts
@@ -13,6 +13,7 @@ import announce from "@ui5/webcomponents-base/dist/util/InvisibleMessage.js";
 import InvisibleMessageMode from "@ui5/webcomponents-base/dist/types/InvisibleMessageMode.js";
 import { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
 import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
+import { isPhone } from "@ui5/webcomponents-base/dist/Device.js";
 
 import debounce from "@ui5/webcomponents-base/dist/util/debounce.js";
 
@@ -278,6 +279,12 @@ class DynamicPage extends UI5Element {
 		return this._headerSnapped;
 	}
 
+	get hasSnappedTitleOnMobile() {
+		return isPhone()
+			&& this.headerSnapped
+			&& (this.dynamicPageTitle?.snappedTitleOnMobile ?? false);
+	}
+
 	/**
 	 * Defines if the header is snapped.
 	 *
@@ -327,6 +334,11 @@ class DynamicPage extends UI5Element {
 		this.fireEvent("title-toggle");
 		await renderFinished();
 		this.headerActions?.focusExpandButton();
+
+		if (this.hasSnappedTitleOnMobile) {
+			this.dynamicPageTitle?.focus();
+		}
+
 		announce(this._headerLabel, InvisibleMessageMode.Polite);
 	}
 
diff --git a/packages/fiori/src/DynamicPageTitle.hbs b/packages/fiori/src/DynamicPageTitle.hbs
index d7e6de98ebfa..fa6b20f0e623 100644
--- a/packages/fiori/src/DynamicPageTitle.hbs
+++ b/packages/fiori/src/DynamicPageTitle.hbs
@@ -9,39 +9,48 @@
     aria-labelledby="{{_ariaLabelledBy}}"
     aria-describedby="{{_id}}-toggle-description">
   </span>
-  <div class="ui5-dynamic-page-title--top-area">
-    <slot name="breadcrumbs"></slot>
 
-    {{#if mobileNavigationActions}}
-      <slot name="navigationBar"></slot>
-    {{/if}}
-  </div>
+  {{#if hasSnappedTitleOnMobile}}
+    <div id="{{_id}}-heading" class="ui5-dynamic-page--snapped-title-on-mobile">
+      <ui5-title size="H4">{{snappedTitleOnMobileText}}</ui5-title>
+      <ui5-icon name="slim-arrow-down" mode="Decorative"></ui5-icon>
+    </div>
+  {{else}}
+    <div class="ui5-dynamic-page-title--top-area">
+      <slot name="breadcrumbs"></slot>
 
-  <div class="ui5-dynamic-page-title--wrapper"
-    @ui5-_min-content-width-change={{onMinContentWidthChange}}>
-    <div id="{{_id}}-heading" class="ui5-dynamic-page-title--heading">
-      <slot name="{{headingSlotName}}"></slot>
+      {{#if mobileNavigationActions}}
+        <slot name="navigationBar"></slot>
+      {{/if}}
     </div>
 
-    {{#if hasContent}}
-      <div class="ui5-dynamic-page-title--content"
-        style="{{styles.content}}">
-        <slot></slot>
+    <div class="ui5-dynamic-page-title--wrapper"
+      @ui5-_min-content-width-change={{onMinContentWidthChange}}>
+      <div id="{{_id}}-heading" class="ui5-dynamic-page-title--heading">
+        <slot name="{{headingSlotName}}"></slot>
       </div>
-    {{/if}}
 
-    <div class="ui5-dynamic-page-title--actions"
-      style="{{styles.actions}}">
-      <slot name="actionsBar"></slot>
-      {{#unless mobileNavigationActions}}
-        {{#if _needsSeparator}}
-          <div class="ui5-dynamic-page-title--actions-separator"></div>
-        {{/if}}
-        <slot name="navigationBar"></slot>
-      {{/unless}}
+      {{#if hasContent}}
+        <div class="ui5-dynamic-page-title--content"
+          style="{{styles.content}}">
+          <slot></slot>
+        </div>
+      {{/if}}
+
+      <div class="ui5-dynamic-page-title--actions"
+        style="{{styles.actions}}">
+        <slot name="actionsBar"></slot>
+        {{#unless mobileNavigationActions}}
+          {{#if _needsSeparator}}
+            <div class="ui5-dynamic-page-title--actions-separator"></div>
+          {{/if}}
+          <slot name="navigationBar"></slot>
+        {{/unless}}
+      </div>
     </div>
-  </div>
 
-  <slot name="{{subheadingSlotName}}"></slot>
+    <slot name="{{subheadingSlotName}}"></slot>
+  {{/if}}
+  
   <span id="{{_id}}-toggle-description" class="ui5-hidden-text">{{_ariaDescribedbyText}}</span>
 </div>
\ No newline at end of file
diff --git a/packages/fiori/src/DynamicPageTitle.ts b/packages/fiori/src/DynamicPageTitle.ts
index 4c25fa163740..4f98fc4f4b79 100644
--- a/packages/fiori/src/DynamicPageTitle.ts
+++ b/packages/fiori/src/DynamicPageTitle.ts
@@ -12,7 +12,9 @@ import { isEnter, isSpace } from "@ui5/webcomponents-base/dist/Keys.js";
 import type Toolbar from "@ui5/webcomponents/dist/Toolbar.js";
 import type { ToolbarMinWidthChangeEventDetail } from "@ui5/webcomponents/dist/Toolbar.js";
 import ToolbarItemOverflowBehavior from "@ui5/webcomponents/dist/types/ToolbarItemOverflowBehavior.js";
-import { isDesktop } from "@ui5/webcomponents-base/dist/Device.js";
+import { isDesktop, isPhone } from "@ui5/webcomponents-base/dist/Device.js";
+import Icon from "@ui5/webcomponents/dist/Icon.js";
+import Title from "@ui5/webcomponents/dist/Title.js";
 
 // Template
 import DynamicPageTitleTemplate from "./generated/templates/DynamicPageTitleTemplate.lit.js";
@@ -63,6 +65,7 @@ import {
 	renderer: litRender,
 	styles: DynamicPageTitleCss,
 	template: DynamicPageTitleTemplate,
+	dependencies: [Title, Icon],
 })
 
 /**
@@ -81,6 +84,33 @@ class DynamicPageTitle extends UI5Element {
 	@property({ type: Boolean })
 	snapped = false;
 
+	/**
+	 * Defines if snapped title on mobile is enabled.
+	 *
+	 * Using this property enables you to provide a simple, single-line title that takes less space
+	 * on the smaller phone screens when the DynamicPageHeader is in its collapsed (snapped) state.
+	 *
+	 * **Note:** The content set in `snappedTitleOnMobileText` overrides all other content set in the `DynamicPageTitle` slots
+	 * and is only visible on phone screen sizes when the header is in snapped state.
+	 *
+	 * @public
+	 */
+	@property({ type: Boolean })
+	snappedTitleOnMobile = false;
+
+	/**
+	 * Defines the text of the snapped title on mobile.
+	 *
+	 * The only content that is displayed in the DynamicPageTitle when it is viewed on a mobile device
+	 * and the DynamicPageHeader is in collapsed (snapped) state.
+	 *
+	 * **Note:** This property takes effect if the `snappedTitleOnMobile` property is set to `true`.
+	 *
+	 * @public
+	 */
+	@property({ type: String })
+	snappedTitleOnMobileText = "";
+
 	/**
 	 * Defines if the mobileNavigationActions are shown.
 	 *
@@ -244,6 +274,12 @@ class DynamicPageTitle extends UI5Element {
 		return this.interactive ? "0" : undefined;
 	}
 
+	get hasSnappedTitleOnMobile() {
+		return isPhone()
+			&& this.snapped
+			&& (this.snappedTitleOnMobile ?? false);
+	}
+
 	get _headerExpanded() {
 		return !this.snapped;
 	}
diff --git a/packages/fiori/src/themes/DynamicPage.css b/packages/fiori/src/themes/DynamicPage.css
index 93db2137cae4..c4415e41418b 100644
--- a/packages/fiori/src/themes/DynamicPage.css
+++ b/packages/fiori/src/themes/DynamicPage.css
@@ -126,4 +126,11 @@
 
 :host([media-range="XL"]) ::slotted([slot="headerArea"]) {
     padding: var(--_ui5_dynamic_page_header_padding_XL);
+}
+
+/* snappedTitleOnMobile */
+:host([_header-snapped]) ::slotted([slot="headerArea"]) {
+	height: 0;
+	padding: 0;
+	visibility: hidden;
 }
\ No newline at end of file
diff --git a/packages/fiori/src/themes/DynamicPageTitle.css b/packages/fiori/src/themes/DynamicPageTitle.css
index e1159a671714..035f0da0486f 100644
--- a/packages/fiori/src/themes/DynamicPageTitle.css
+++ b/packages/fiori/src/themes/DynamicPageTitle.css
@@ -35,6 +35,10 @@
     box-shadow: var(--sapContent_HeaderShadow);
 }
 
+:host([snapped][snapped-title-on-mobile]) {
+	min-height: var(--_ui5_dynamic_page_snapped_title_on_mobile_min_height);
+}
+
 /* breadcrumbs */
 ::slotted([ui5-breadcrumbs][slot="breadcrumbs"]) {
     padding: var(--_ui5_dynamic_page_title_breadcrumbs_padding_top) 0
@@ -88,6 +92,17 @@
     min-width: 1px;
 }
 
+.ui5-dynamic-page--snapped-title-on-mobile {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	pointer-events: none;
+
+	[ui5-title] {
+		line-height: var(--_ui5_dynamic_page_snapped_title_on_mobile_line_height);
+	}
+}
+
 .ui5-dynamic-page-title--content {
     padding: 0 0 0 1rem;
     flex-shrink: 1.6;
diff --git a/packages/fiori/src/themes/base/DynamicPageTitle-parameters.css b/packages/fiori/src/themes/base/DynamicPageTitle-parameters.css
index eebbce124b13..c6f0fabc51ab 100644
--- a/packages/fiori/src/themes/base/DynamicPageTitle-parameters.css
+++ b/packages/fiori/src/themes/base/DynamicPageTitle-parameters.css
@@ -16,4 +16,6 @@
 
     --_ui5_dynamic_page_title_hover_background: var(--sapObjectHeader_Hover_Background);
 
+	--_ui5_dynamic_page_snapped_title_on_mobile_line_height: 2rem;
+	--_ui5_dynamic_page_snapped_title_on_mobile_min_height: 2rem;
 }
\ No newline at end of file
diff --git a/packages/fiori/test/pages/DynamicPageWithSnappedTitleOnMobile.html b/packages/fiori/test/pages/DynamicPageWithSnappedTitleOnMobile.html
new file mode 100644
index 000000000000..87c3bff7ae17
--- /dev/null
+++ b/packages/fiori/test/pages/DynamicPageWithSnappedTitleOnMobile.html
@@ -0,0 +1,205 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta
+            name="viewport"
+            content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
+        />
+        <meta charset="utf-8" />
+
+        <title>Dynamic page</title>
+
+        <script>
+            // delete Document.prototype.adoptedStyleSheets
+        </script>
+
+        <script src="%VITE_BUNDLE_PATH%" type="module"></script>
+
+        <link rel="stylesheet" type="text/css" href="./styles/DynamicPage.css" />
+
+    </head>
+
+    <body>
+        <ui5-dynamic-page id="page" show-footer>
+            <ui5-dynamic-page-title slot="titleArea" snapped-title-on-mobile snapped-title-on-mobile-text="Snapped Title On Mobile">
+                <ui5-breadcrumbs slot="breadcrumbs">
+                    <ui5-breadcrumbs-item href="#">Man</ui5-breadcrumbs-item>
+                    <ui5-breadcrumbs-item href="#">Shoes</ui5-breadcrumbs-item>
+                    <ui5-breadcrumbs-item href="#">Running Shoes</ui5-breadcrumbs-item>
+                </ui5-breadcrumbs>
+
+                <ui5-title wrapping-type="None" slot="heading">Special Running Shoe</ui5-title>
+
+                <div slot="snappedHeading" class="snapped-title-heading">
+                    <ui5-avatar shape="square" icon="laptop" color-scheme="Accent5" size="S"></ui5-avatar>
+                    <ui5-title wrapping-type="None">Special Running Shoe</ui5-title>
+                </div>
+
+                <p slot="subheading" class="text">PO-48865</p>
+                <p slot="snappedSubheading" class="text">PO-48865</p>
+
+                <ui5-tag color-scheme="7">Special 157.4M EUR</ui5-tag>
+
+                <ui5-toolbar id="actionsToolbar" slot="actionsBar" design="Transparent">
+                    <ui5-toolbar-button text="Create"></ui5-toolbar-button>
+                    <ui5-toolbar-button id="edit-button" design="Transparent" text="Edit"></ui5-toolbar-button>
+                    <ui5-toolbar-button design="Transparent" text="Paste"></ui5-toolbar-button>
+                </ui5-toolbar>
+
+                <ui5-toolbar slot="navigationBar" design="Transparent">
+                    <ui5-toolbar-button design="Transparent" icon="share"></ui5-toolbar-button>
+                    <ui5-toolbar-button design="Transparent" icon="action-settings"></ui5-toolbar-button>
+                </ui5-toolbar>
+            </ui5-dynamic-page-title>
+
+            <ui5-dynamic-page-header slot="headerArea">
+                <div class="product-info">
+                    <ui5-avatar id="avatar" shape="square" icon="laptop" color-scheme="Accent5" size="L"></ui5-avatar>
+                    <div class="product-info-cell">
+                        <ui5-label>Availability</ui5-label>
+                        <p class="text availability">In Stock</p>
+                    </div>
+                    <div class="product-info-cell">
+                        <ui5-label>Price</ui5-label>
+                        <p class="text price">379.99 USD</p>
+                    </div>
+                    <div class="product-info-cell">
+                        <ui5-label>Product Description</ui5-label>
+                        <p class="text product-description">Super-lightweight cushioning propels you forward from landing to toe-off and has a fast, snappy feel.</p>
+                    </div>
+                </div>
+            </ui5-dynamic-page-header>
+
+            <ui5-list header-text="Products (13)" mode="SingleSelect">
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="47.00 EUR">10 inch Portable DVD</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="249.00 EUR">7 inch WidescreenPortable DVD Player w MP3</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="947.00 EUR">Astro Laptop 1516</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="647.00 EUR">Astro Phone 6</ui5-li>
+                <ui5-li description="HT-1252" icon="slim-arrow-right" icon-end additional-text="27.99 EUR">Audio/Video Cable Kit - 4m</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="447.90 EUR">Beam Breaker B-1</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="647.50 EUR">Beam Breaker B-2</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="847.80 EUR">Beam Breaker B-3</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="1,250.00 EUR">Beam Breaker B-4</ui5-li>
+                <ui5-li description="HT-8001" icon="slim-arrow-right" icon-end additional-text="1,288.00 EUR">Camcorder View</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="996.00 EUR">Benda Laptop 1408</ui5-li>
+                <ui5-li description="HT-0003" icon="slim-arrow-right" icon-end additional-text="147.00 EUR">Cepat Tablet 10.5</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="47.00 EUR">10 inch Portable DVD</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="249.00 EUR">7 inch WidescreenPortable DVD Player w MP3</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="947.00 EUR">Astro Laptop 1516</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="647.00 EUR">Astro Phone 6</ui5-li>
+                <ui5-li description="HT-1252" icon="slim-arrow-right" icon-end additional-text="27.99 EUR">Audio/Video Cable Kit - 4m</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="447.90 EUR">Beam Breaker B-1</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="647.50 EUR">Beam Breaker B-2</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="847.80 EUR">Beam Breaker B-3</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="1,250.00 EUR">Beam Breaker B-4</ui5-li>
+                <ui5-li description="HT-8001" icon="slim-arrow-right" icon-end additional-text="1,288.00 EUR">Camcorder View</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="996.00 EUR">Benda Laptop 1408</ui5-li>
+                <ui5-li description="HT-0003" icon="slim-arrow-right" icon-end additional-text="147.00 EUR">Cepat Tablet 10.5</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="47.00 EUR">10 inch Portable DVD</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="249.00 EUR">7 inch WidescreenPortable DVD Player w MP3</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="947.00 EUR">Astro Laptop 1516</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="647.00 EUR">Astro Phone 6</ui5-li>
+                <ui5-li description="HT-1252" icon="slim-arrow-right" icon-end additional-text="27.99 EUR">Audio/Video Cable Kit - 4m</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="447.90 EUR">Beam Breaker B-1</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="647.50 EUR">Beam Breaker B-2</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="847.80 EUR">Beam Breaker B-3</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="1,250.00 EUR">Beam Breaker B-4</ui5-li>
+                <ui5-li description="HT-8001" icon="slim-arrow-right" icon-end additional-text="1,288.00 EUR">Camcorder View</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="996.00 EUR">Benda Laptop 1408</ui5-li>
+                <ui5-li description="HT-0003" icon="slim-arrow-right" icon-end additional-text="147.00 EUR">Cepat Tablet 10.5</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="47.00 EUR">10 inch Portable DVD</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="249.00 EUR">7 inch WidescreenPortable DVD Player w MP3</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="947.00 EUR">Astro Laptop 1516</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="647.00 EUR">Astro Phone 6</ui5-li>
+                <ui5-li description="HT-1252" icon="slim-arrow-right" icon-end additional-text="27.99 EUR">Audio/Video Cable Kit - 4m</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="447.90 EUR">Beam Breaker B-1</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="647.50 EUR">Beam Breaker B-2</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="847.80 EUR">Beam Breaker B-3</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="1,250.00 EUR">Beam Breaker B-4</ui5-li>
+                <ui5-li description="HT-8001" icon="slim-arrow-right" icon-end additional-text="1,288.00 EUR">Camcorder View</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="996.00 EUR">Benda Laptop 1408</ui5-li>
+                <ui5-li description="HT-0003" icon="slim-arrow-right" icon-end additional-text="147.00 EUR">Cepat Tablet 10.5</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="47.00 EUR">10 inch Portable DVD</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="249.00 EUR">7 inch WidescreenPortable DVD Player w MP3</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="947.00 EUR">Astro Laptop 1516</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="647.00 EUR">Astro Phone 6</ui5-li>
+                <ui5-li description="HT-1252" icon="slim-arrow-right" icon-end additional-text="27.99 EUR">Audio/Video Cable Kit - 4m</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="447.90 EUR">Beam Breaker B-1</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="647.50 EUR">Beam Breaker B-2</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="847.80 EUR">Beam Breaker B-3</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="1,250.00 EUR">Beam Breaker B-4</ui5-li>
+                <ui5-li description="HT-8001" icon="slim-arrow-right" icon-end additional-text="1,288.00 EUR">Camcorder View</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="996.00 EUR">Benda Laptop 1408</ui5-li>
+                <ui5-li description="HT-0003" icon="slim-arrow-right" icon-end additional-text="147.00 EUR">Cepat Tablet 10.5</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="47.00 EUR">10 inch Portable DVD</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="249.00 EUR">7 inch WidescreenPortable DVD Player w MP3</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="947.00 EUR">Astro Laptop 1516</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="647.00 EUR">Astro Phone 6</ui5-li>
+                <ui5-li description="HT-1252" icon="slim-arrow-right" icon-end additional-text="27.99 EUR">Audio/Video Cable Kit - 4m</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="447.90 EUR">Beam Breaker B-1</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="647.50 EUR">Beam Breaker B-2</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="847.80 EUR">Beam Breaker B-3</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="1,250.00 EUR">Beam Breaker B-4</ui5-li>
+                <ui5-li description="HT-8001" icon="slim-arrow-right" icon-end additional-text="1,288.00 EUR">Camcorder View</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="996.00 EUR">Benda Laptop 1408</ui5-li>
+                <ui5-li description="HT-0003" icon="slim-arrow-right" icon-end additional-text="147.00 EUR">Cepat Tablet 10.5</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="47.00 EUR">10 inch Portable DVD</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="249.00 EUR">7 inch WidescreenPortable DVD Player w MP3</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="947.00 EUR">Astro Laptop 1516</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="647.00 EUR">Astro Phone 6</ui5-li>
+                <ui5-li description="HT-1252" icon="slim-arrow-right" icon-end additional-text="27.99 EUR">Audio/Video Cable Kit - 4m</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="447.90 EUR">Beam Breaker B-1</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="647.50 EUR">Beam Breaker B-2</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="847.80 EUR">Beam Breaker B-3</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="1,250.00 EUR">Beam Breaker B-4</ui5-li>
+                <ui5-li description="HT-8001" icon="slim-arrow-right" icon-end additional-text="1,288.00 EUR">Camcorder View</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="996.00 EUR">Benda Laptop 1408</ui5-li>
+                <ui5-li description="HT-0003" icon="slim-arrow-right" icon-end additional-text="147.00 EUR">Cepat Tablet 10.5</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="47.00 EUR">10 inch Portable DVD</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="249.00 EUR">7 inch WidescreenPortable DVD Player w MP3</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="947.00 EUR">Astro Laptop 1516</ui5-li>
+                <ui5-li description="HT-1251" icon="slim-arrow-right" icon-end additional-text="647.00 EUR">Astro Phone 6</ui5-li>
+                <ui5-li description="HT-1252" icon="slim-arrow-right" icon-end additional-text="27.99 EUR">Audio/Video Cable Kit - 4m</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="447.90 EUR">Beam Breaker B-1</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="647.50 EUR">Beam Breaker B-2</ui5-li>
+                <ui5-li description="HT-6001" icon="slim-arrow-right" icon-end additional-text="847.80 EUR">Beam Breaker B-3</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="1,250.00 EUR">Beam Breaker B-4</ui5-li>
+                <ui5-li description="HT-8001" icon="slim-arrow-right" icon-end additional-text="1,288.00 EUR">Camcorder View</ui5-li>
+                <ui5-li description="HT-2001" icon="slim-arrow-right" icon-end additional-text="996.00 EUR">Benda Laptop 1408</ui5-li>
+                <ui5-li description="HT-0003" icon="slim-arrow-right" icon-end additional-text="147.00 EUR">Cepat Tablet 10.5</ui5-li>
+                <ui5-li description="HT-1001" icon="slim-arrow-right" icon-end additional-text="87.90 EUR">Gladiator MX</ui5-li>
+            </ui5-list>
+
+            <ui5-bar slot="footerArea" design="FloatingFooter">
+                <ui5-button id="save-edit" slot="endContent">Save</ui5-button>
+                <ui5-button id="cancel-edit" slot="endContent">Close</ui5-button>
+            </ui5-bar>
+        </ui5-dynamic-page>
+
+        <script>
+            const dynamicPage = document.querySelector("ui5-dynamic-page");
+            const editButton = document.querySelector("#edit-button");
+
+            const cancelEdit = document.querySelector("#cancel-edit");
+            const saveEdit = document.querySelector("#save-edit");
+
+            editButton.addEventListener("click", () => {
+                dynamicPage.setAttribute("show-footer", true);
+            });
+
+            [saveEdit, cancelEdit].forEach(button => {
+                button.addEventListener("click", () => {
+                    dynamicPage.removeAttribute("show-footer");
+                });
+            });
+
+            dynamicPage.addEventListener("pin-button-toggle", event => {
+                console.log("Pin button toggled", dynamicPage.headerPinned)
+            });
+
+            dynamicPage.addEventListener("title-toggle", event => {
+                console.log("Title toggled", dynamicPage.headerSnapped)
+            });
+        </script>
+    </body>
+</html>
diff --git a/packages/fiori/test/specs/DynamicPage.mobile.spec.js b/packages/fiori/test/specs/DynamicPage.mobile.spec.js
new file mode 100644
index 000000000000..41dcfe3b6406
--- /dev/null
+++ b/packages/fiori/test/specs/DynamicPage.mobile.spec.js
@@ -0,0 +1,105 @@
+import { assert } from "chai";
+
+describe("DynamicPage Mobile Behaviour", () => {
+	before(async () => {
+		await browser.url(`test/pages/DynamicPage_test.html`);
+		await browser.emulateDevice('iPhone X');
+	});
+
+	it("should display snapped title on mobile when snappedTitleOnMobile is true and header is snapped", async () => {
+		const dynamicPage = await browser.$("#page");
+		const title = await browser.$("#page ui5-dynamic-page-title");
+
+		// Set snappedTitleOnMobile to true and snap the header
+		await title.setProperty("snappedTitleOnMobile", true);
+		await title.setProperty("snappedTitleOnMobileText", "Snapped Title");
+		await dynamicPage.setProperty("headerSnapped", true);
+
+		// Check if the snapped title on mobile is visible
+		const snappedTitleOnMobile = await title.shadow$(".ui5-dynamic-page--snapped-title-on-mobile");
+		assert.ok(
+			await snappedTitleOnMobile.isExisting(),
+			"Snapped title on mobile should be displayed when header is snapped and snappedTitleOnMobile is true."
+		);
+		assert.strictEqual(
+			await snappedTitleOnMobile.getText(),
+			"Snapped Title",
+			"The snapped title on mobile should display the correct text."
+		);
+	});
+
+	it("should not display snapped title on mobile when snappedTitleOnMobile is false", async () => {
+		const dynamicPage = await browser.$("#page");
+		const title = await browser.$("#page ui5-dynamic-page-title");
+
+		// Set snappedTitleOnMobile to false and snap the header
+		await title.setProperty("snappedTitleOnMobile", false);
+		await dynamicPage.setProperty("headerSnapped", true);
+
+		// Check if the snapped title on mobile is not visible
+		const snappedTitleOnMobile = await title.shadow$(".ui5-dynamic-page--snapped-title-on-mobile");
+		assert.strictEqual(
+			await snappedTitleOnMobile.isExisting(),
+			false,
+			"Snapped title on mobile should not be displayed when snappedTitleOnMobile is false."
+		);
+	});
+
+	it("should expand the header when clicked on the snapped title on mobile", async () => {
+		const dynamicPage = await browser.$("#page");
+		const title = await browser.$("#page ui5-dynamic-page-title");
+
+		// Set snappedTitleOnMobile to true and snap the header
+		await title.setProperty("snappedTitleOnMobile", true);
+		await dynamicPage.setProperty("headerSnapped", true);
+
+		// Click on the snapped title on mobile
+		const titleFocusArea = await title.shadow$(".ui5-dynamic-page-title-focus-area");
+		await titleFocusArea.click();
+
+		// Check if the header is expanded
+		assert.strictEqual(
+			await dynamicPage.getProperty("headerSnapped"),
+			false,
+			"Header should expand when snapped title on mobile is clicked."
+		);
+	});
+
+	it("should not display snapped title on mobile when header is not snapped", async () => {
+		const dynamicPage = await browser.$("#page");
+		const title = await browser.$("#page ui5-dynamic-page-title");
+
+		// Set snappedTitleOnMobile to true but keep the header expanded
+		await title.setProperty("snappedTitleOnMobile", true);
+		await dynamicPage.setProperty("headerSnapped", false);
+
+		// Check if the snapped title on mobile is not visible
+		const snappedTitleOnMobile = await title.shadow$(".ui5-dynamic-page--snapped-title-on-mobile");
+		assert.strictEqual(
+			await snappedTitleOnMobile.isExisting(),
+			false,
+			"Snapped title on mobile should not be displayed when the header is not snapped."
+		);
+	});
+
+	it("should focus the title focus area when header action is clicked to snap the header", async () => {
+		const dynamicPage = await browser.$("#page");
+		const title = await browser.$("#page ui5-dynamic-page-title");
+
+		// Set snappedTitleOnMobile to true but keep the header expanded
+		await title.setProperty("snappedTitleOnMobile", true);
+		await dynamicPage.setProperty("headerSnapped", false);
+
+		// Click on the header action to snap the header
+		const snapButton = await dynamicPage.shadow$("ui5-dynamic-page-header-actions")
+			.shadow$(".ui5-dynamic-page-header-action");
+		await snapButton.click();
+
+		// Check if the title focus area is focused
+		const isFocused = await title.isFocused();
+		assert.ok(
+			isFocused,
+			"Focus should be applied to the title focus area after snapping the header via header action."
+		);
+	});
+});
\ No newline at end of file
diff --git a/packages/fiori/test/specs/DynamicPage.spec.js b/packages/fiori/test/specs/DynamicPage.spec.js
index a8a762379f1a..3c55b7649cd8 100644
--- a/packages/fiori/test/specs/DynamicPage.spec.js
+++ b/packages/fiori/test/specs/DynamicPage.spec.js
@@ -285,6 +285,24 @@ describe("Page general interaction", () => {
 
         assert.strictEqual(await page.getProperty("headerSnapped"), true, "Header is snapped");
     });
+
+	it("should not display snapped title on non-mobile devices even if snappedTitleOnMobile is true", async () => {
+		const dynamicPage = await browser.$("#page");
+		const title = await browser.$("#page ui5-dynamic-page-title");
+
+		// Set snappedTitleOnMobile to true and snap the header
+		await title.setProperty("snappedTitleOnMobile", true);
+		await title.setProperty("snappedTitleOnMobileText", "Snapped Title");
+		await dynamicPage.setProperty("headerSnapped", true);
+
+		// Check if the snapped title on mobile is not visible
+		const snappedTitleOnMobile = await title.shadow$(".ui5-dynamic-page--snapped-title-on-mobile");
+		assert.strictEqual(
+			await snappedTitleOnMobile.isExisting(),
+			false,
+			"Snapped title on mobile should not be displayed on desktop devices even when snappedTitleOnMobile is true."
+		);
+	});
 });
 
 describe("Page layout when content has 100% height", () => {

From 16cc39334eb9290c1d50eaa78264931c53d6e20e Mon Sep 17 00:00:00 2001
From: Konstantin Gogov <konstantin.gogov@sap.com>
Date: Wed, 25 Sep 2024 17:58:42 +0300
Subject: [PATCH 2/4] feat(ui5-dynamic-page-title): refactor snapped title
 implementation

- Addressed review comments by changing the implementation of the snapped title on mobile.
- Replaced properties with a slot for better flexibility and maintainability.
---
 packages/fiori/src/DynamicPage.ts             |  4 +-
 packages/fiori/src/DynamicPageTitle.hbs       |  4 +-
 packages/fiori/src/DynamicPageTitle.ts        | 61 +++++++++---------
 .../fiori/src/themes/DynamicPageTitle.css     |  7 +--
 .../DynamicPageWithSnappedTitleOnMobile.html  |  4 +-
 .../test/specs/DynamicPage.mobile.spec.js     | 62 ++++++++++---------
 packages/fiori/test/specs/DynamicPage.spec.js | 18 ------
 7 files changed, 73 insertions(+), 87 deletions(-)

diff --git a/packages/fiori/src/DynamicPage.ts b/packages/fiori/src/DynamicPage.ts
index 8b38ddd37dfd..d7f72c8d0940 100644
--- a/packages/fiori/src/DynamicPage.ts
+++ b/packages/fiori/src/DynamicPage.ts
@@ -280,9 +280,7 @@ class DynamicPage extends UI5Element {
 	}
 
 	get hasSnappedTitleOnMobile() {
-		return isPhone()
-			&& this.headerSnapped
-			&& (this.dynamicPageTitle?.snappedTitleOnMobile ?? false);
+		return isPhone() && this.headerSnapped && this.dynamicPageTitle?.snappedTitleOnMobile.length;
 	}
 
 	/**
diff --git a/packages/fiori/src/DynamicPageTitle.hbs b/packages/fiori/src/DynamicPageTitle.hbs
index fa6b20f0e623..25aa2682b6ce 100644
--- a/packages/fiori/src/DynamicPageTitle.hbs
+++ b/packages/fiori/src/DynamicPageTitle.hbs
@@ -12,8 +12,8 @@
 
   {{#if hasSnappedTitleOnMobile}}
     <div id="{{_id}}-heading" class="ui5-dynamic-page--snapped-title-on-mobile">
-      <ui5-title size="H4">{{snappedTitleOnMobileText}}</ui5-title>
-      <ui5-icon name="slim-arrow-down" mode="Decorative"></ui5-icon>
+        <slot name="snappedTitleOnMobile"></slot>
+        <ui5-icon name="slim-arrow-down" mode="Decorative"></ui5-icon>
     </div>
   {{else}}
     <div class="ui5-dynamic-page-title--top-area">
diff --git a/packages/fiori/src/DynamicPageTitle.ts b/packages/fiori/src/DynamicPageTitle.ts
index 4f98fc4f4b79..29c8587c6cf6 100644
--- a/packages/fiori/src/DynamicPageTitle.ts
+++ b/packages/fiori/src/DynamicPageTitle.ts
@@ -84,33 +84,6 @@ class DynamicPageTitle extends UI5Element {
 	@property({ type: Boolean })
 	snapped = false;
 
-	/**
-	 * Defines if snapped title on mobile is enabled.
-	 *
-	 * Using this property enables you to provide a simple, single-line title that takes less space
-	 * on the smaller phone screens when the DynamicPageHeader is in its collapsed (snapped) state.
-	 *
-	 * **Note:** The content set in `snappedTitleOnMobileText` overrides all other content set in the `DynamicPageTitle` slots
-	 * and is only visible on phone screen sizes when the header is in snapped state.
-	 *
-	 * @public
-	 */
-	@property({ type: Boolean })
-	snappedTitleOnMobile = false;
-
-	/**
-	 * Defines the text of the snapped title on mobile.
-	 *
-	 * The only content that is displayed in the DynamicPageTitle when it is viewed on a mobile device
-	 * and the DynamicPageHeader is in collapsed (snapped) state.
-	 *
-	 * **Note:** This property takes effect if the `snappedTitleOnMobile` property is set to `true`.
-	 *
-	 * @public
-	 */
-	@property({ type: String })
-	snappedTitleOnMobileText = "";
-
 	/**
 	 * Defines if the mobileNavigationActions are shown.
 	 *
@@ -162,6 +135,30 @@ class DynamicPageTitle extends UI5Element {
 	@slot({ type: HTMLElement })
 	snappedHeading!: HTMLElement[];
 
+	/**
+	 * Defines the content of the snapped title on mobile devices.
+	 *
+	 * This slot is displayed only when the `DynamicPageTitle` is in the snapped state on mobile devices.
+	 * It should be used to provide a simplified, single-line title that takes up less space on smaller screens.
+	 *
+	 * **Note:**
+	 * - The content set in this slot overrides all other content set in the `DynamicPageTitle` slots when displayed.
+	 * - The slot is intended for a single `ui5-title` component.
+	 *
+	 * **Usage Example:**
+	 * ```html
+	 * <ui5-dynamic-page-title>
+	 *   <!-- Other slots like heading, subheading, etc. -->
+	 *   <ui5-title slot="snappedTitleOnMobile" size="H4" wrapping-type="None">My Snapped Mobile Title</ui5-title>
+	 * </ui5-dynamic-page-title>
+	 * ```
+	 *
+	 * @public
+	 * @since 2.3.0
+	 */
+	@slot({ type: Title })
+	snappedTitleOnMobile!: Array<Title>;
+
 	/**
 	 * Defines the bar with actions in the Dynamic page title.
 	 *
@@ -242,6 +239,12 @@ class DynamicPageTitle extends UI5Element {
 
 	onBeforeRendering() {
 		this.prepareLayoutActions();
+
+		if (this.hasSnappedTitleOnMobile) {
+			this.setAttribute("_snapped-title-on-mobile", "");
+		} else {
+			this.removeAttribute("_snapped-title-on-mobile");
+		}
 	}
 
 	get styles() {
@@ -275,9 +278,7 @@ class DynamicPageTitle extends UI5Element {
 	}
 
 	get hasSnappedTitleOnMobile() {
-		return isPhone()
-			&& this.snapped
-			&& (this.snappedTitleOnMobile ?? false);
+		return isPhone() && this.snapped && this.snappedTitleOnMobile.length;
 	}
 
 	get _headerExpanded() {
diff --git a/packages/fiori/src/themes/DynamicPageTitle.css b/packages/fiori/src/themes/DynamicPageTitle.css
index 035f0da0486f..87c1c720ae82 100644
--- a/packages/fiori/src/themes/DynamicPageTitle.css
+++ b/packages/fiori/src/themes/DynamicPageTitle.css
@@ -35,8 +35,9 @@
     box-shadow: var(--sapContent_HeaderShadow);
 }
 
-:host([snapped][snapped-title-on-mobile]) {
+:host([snapped][_snapped-title-on-mobile]) {
 	min-height: var(--_ui5_dynamic_page_snapped_title_on_mobile_min_height);
+	line-height: var(--_ui5_dynamic_page_snapped_title_on_mobile_line_height);
 }
 
 /* breadcrumbs */
@@ -97,10 +98,6 @@
 	justify-content: space-between;
 	align-items: center;
 	pointer-events: none;
-
-	[ui5-title] {
-		line-height: var(--_ui5_dynamic_page_snapped_title_on_mobile_line_height);
-	}
 }
 
 .ui5-dynamic-page-title--content {
diff --git a/packages/fiori/test/pages/DynamicPageWithSnappedTitleOnMobile.html b/packages/fiori/test/pages/DynamicPageWithSnappedTitleOnMobile.html
index 87c3bff7ae17..0d30bc33fb3a 100644
--- a/packages/fiori/test/pages/DynamicPageWithSnappedTitleOnMobile.html
+++ b/packages/fiori/test/pages/DynamicPageWithSnappedTitleOnMobile.html
@@ -21,7 +21,7 @@
 
     <body>
         <ui5-dynamic-page id="page" show-footer>
-            <ui5-dynamic-page-title slot="titleArea" snapped-title-on-mobile snapped-title-on-mobile-text="Snapped Title On Mobile">
+            <ui5-dynamic-page-title slot="titleArea">
                 <ui5-breadcrumbs slot="breadcrumbs">
                     <ui5-breadcrumbs-item href="#">Man</ui5-breadcrumbs-item>
                     <ui5-breadcrumbs-item href="#">Shoes</ui5-breadcrumbs-item>
@@ -30,6 +30,8 @@
 
                 <ui5-title wrapping-type="None" slot="heading">Special Running Shoe</ui5-title>
 
+				<ui5-title wrapping-type="None" slot="snappedTitleOnMobile" size="H4">Snapped Title On Mobile</ui5-title>
+
                 <div slot="snappedHeading" class="snapped-title-heading">
                     <ui5-avatar shape="square" icon="laptop" color-scheme="Accent5" size="S"></ui5-avatar>
                     <ui5-title wrapping-type="None">Special Running Shoe</ui5-title>
diff --git a/packages/fiori/test/specs/DynamicPage.mobile.spec.js b/packages/fiori/test/specs/DynamicPage.mobile.spec.js
index 41dcfe3b6406..6407fb7a5dab 100644
--- a/packages/fiori/test/specs/DynamicPage.mobile.spec.js
+++ b/packages/fiori/test/specs/DynamicPage.mobile.spec.js
@@ -1,47 +1,52 @@
 import { assert } from "chai";
 
 describe("DynamicPage Mobile Behaviour", () => {
-	before(async () => {
-		await browser.url(`test/pages/DynamicPage_test.html`);
-		await browser.emulateDevice('iPhone X');
+	beforeEach(async () => {
+		await browser.url("test/pages/DynamicPageWithSnappedTitleOnMobile.html");
+		await browser.emulateDevice("iPhone X");
 	});
 
-	it("should display snapped title on mobile when snappedTitleOnMobile is true and header is snapped", async () => {
+	it("should display snapped title on mobile when snappedTitleOnMobile slot has content and header is snapped", async () => {
 		const dynamicPage = await browser.$("#page");
 		const title = await browser.$("#page ui5-dynamic-page-title");
 
-		// Set snappedTitleOnMobile to true and snap the header
-		await title.setProperty("snappedTitleOnMobile", true);
-		await title.setProperty("snappedTitleOnMobileText", "Snapped Title");
+		// Ensure the header is snapped
 		await dynamicPage.setProperty("headerSnapped", true);
 
 		// Check if the snapped title on mobile is visible
 		const snappedTitleOnMobile = await title.shadow$(".ui5-dynamic-page--snapped-title-on-mobile");
+		const isDisplayed = await snappedTitleOnMobile.isDisplayed();
+
 		assert.ok(
-			await snappedTitleOnMobile.isExisting(),
-			"Snapped title on mobile should be displayed when header is snapped and snappedTitleOnMobile is true."
-		);
-		assert.strictEqual(
-			await snappedTitleOnMobile.getText(),
-			"Snapped Title",
-			"The snapped title on mobile should display the correct text."
+			isDisplayed,
+			"Snapped title on mobile should be displayed when header is snapped and snappedTitleOnMobile slot has content."
 		);
 	});
 
-	it("should not display snapped title on mobile when snappedTitleOnMobile is false", async () => {
+	it("should not display snapped title on mobile when snappedTitleOnMobile slot is empty", async () => {
 		const dynamicPage = await browser.$("#page");
 		const title = await browser.$("#page ui5-dynamic-page-title");
 
-		// Set snappedTitleOnMobile to false and snap the header
-		await title.setProperty("snappedTitleOnMobile", false);
+		// Remove content from the snappedTitleOnMobile slot
+		await browser.execute(() => {
+			const titleElement = document.querySelector("#page ui5-dynamic-page-title");
+			const snappedTitleContent = titleElement.querySelector("[slot='snappedTitleOnMobile']");
+			if (snappedTitleContent) {
+				titleElement.removeChild(snappedTitleContent);
+			}
+		});
+
+		// Snap the header
 		await dynamicPage.setProperty("headerSnapped", true);
 
 		// Check if the snapped title on mobile is not visible
 		const snappedTitleOnMobile = await title.shadow$(".ui5-dynamic-page--snapped-title-on-mobile");
+		const isDisplayed = await snappedTitleOnMobile.isDisplayed();
+
 		assert.strictEqual(
-			await snappedTitleOnMobile.isExisting(),
+			isDisplayed,
 			false,
-			"Snapped title on mobile should not be displayed when snappedTitleOnMobile is false."
+			"Snapped title on mobile should not be displayed when the snappedTitleOnMobile slot is empty."
 		);
 	});
 
@@ -49,17 +54,18 @@ describe("DynamicPage Mobile Behaviour", () => {
 		const dynamicPage = await browser.$("#page");
 		const title = await browser.$("#page ui5-dynamic-page-title");
 
-		// Set snappedTitleOnMobile to true and snap the header
-		await title.setProperty("snappedTitleOnMobile", true);
+		// Ensure the header is snapped
 		await dynamicPage.setProperty("headerSnapped", true);
 
-		// Click on the snapped title on mobile
+		// Click on the title focus area to expand the header
 		const titleFocusArea = await title.shadow$(".ui5-dynamic-page-title-focus-area");
 		await titleFocusArea.click();
 
 		// Check if the header is expanded
+		const headerSnapped = await dynamicPage.getProperty("headerSnapped");
+
 		assert.strictEqual(
-			await dynamicPage.getProperty("headerSnapped"),
+			headerSnapped,
 			false,
 			"Header should expand when snapped title on mobile is clicked."
 		);
@@ -69,14 +75,15 @@ describe("DynamicPage Mobile Behaviour", () => {
 		const dynamicPage = await browser.$("#page");
 		const title = await browser.$("#page ui5-dynamic-page-title");
 
-		// Set snappedTitleOnMobile to true but keep the header expanded
-		await title.setProperty("snappedTitleOnMobile", true);
+		// Ensure the header is not snapped
 		await dynamicPage.setProperty("headerSnapped", false);
 
 		// Check if the snapped title on mobile is not visible
 		const snappedTitleOnMobile = await title.shadow$(".ui5-dynamic-page--snapped-title-on-mobile");
+		const isDisplayed = await snappedTitleOnMobile.isDisplayed();
+
 		assert.strictEqual(
-			await snappedTitleOnMobile.isExisting(),
+			isDisplayed,
 			false,
 			"Snapped title on mobile should not be displayed when the header is not snapped."
 		);
@@ -86,8 +93,7 @@ describe("DynamicPage Mobile Behaviour", () => {
 		const dynamicPage = await browser.$("#page");
 		const title = await browser.$("#page ui5-dynamic-page-title");
 
-		// Set snappedTitleOnMobile to true but keep the header expanded
-		await title.setProperty("snappedTitleOnMobile", true);
+		// Ensure the header is expanded
 		await dynamicPage.setProperty("headerSnapped", false);
 
 		// Click on the header action to snap the header
diff --git a/packages/fiori/test/specs/DynamicPage.spec.js b/packages/fiori/test/specs/DynamicPage.spec.js
index 3c55b7649cd8..a8a762379f1a 100644
--- a/packages/fiori/test/specs/DynamicPage.spec.js
+++ b/packages/fiori/test/specs/DynamicPage.spec.js
@@ -285,24 +285,6 @@ describe("Page general interaction", () => {
 
         assert.strictEqual(await page.getProperty("headerSnapped"), true, "Header is snapped");
     });
-
-	it("should not display snapped title on non-mobile devices even if snappedTitleOnMobile is true", async () => {
-		const dynamicPage = await browser.$("#page");
-		const title = await browser.$("#page ui5-dynamic-page-title");
-
-		// Set snappedTitleOnMobile to true and snap the header
-		await title.setProperty("snappedTitleOnMobile", true);
-		await title.setProperty("snappedTitleOnMobileText", "Snapped Title");
-		await dynamicPage.setProperty("headerSnapped", true);
-
-		// Check if the snapped title on mobile is not visible
-		const snappedTitleOnMobile = await title.shadow$(".ui5-dynamic-page--snapped-title-on-mobile");
-		assert.strictEqual(
-			await snappedTitleOnMobile.isExisting(),
-			false,
-			"Snapped title on mobile should not be displayed on desktop devices even when snappedTitleOnMobile is true."
-		);
-	});
 });
 
 describe("Page layout when content has 100% height", () => {

From 5aaa5f6e1daf5a61a4ea6a69b0e8f068daa6479e Mon Sep 17 00:00:00 2001
From: Konstantin Gogov <konstantin.gogov@sap.com>
Date: Wed, 25 Sep 2024 18:21:33 +0300
Subject: [PATCH 3/4] feat(ui5-dynamic-page-title): refactor snapped title
 documentation

---
 packages/fiori/src/DynamicPageTitle.ts | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/packages/fiori/src/DynamicPageTitle.ts b/packages/fiori/src/DynamicPageTitle.ts
index 29c8587c6cf6..ca1ea7d4c263 100644
--- a/packages/fiori/src/DynamicPageTitle.ts
+++ b/packages/fiori/src/DynamicPageTitle.ts
@@ -142,17 +142,9 @@ class DynamicPageTitle extends UI5Element {
 	 * It should be used to provide a simplified, single-line title that takes up less space on smaller screens.
 	 *
 	 * **Note:**
-	 * - The content set in this slot overrides all other content set in the `DynamicPageTitle` slots when displayed.
+	 * - The content set in this slot **overrides** all other content set in the `DynamicPageTitle` slots when displayed.
 	 * - The slot is intended for a single `ui5-title` component.
 	 *
-	 * **Usage Example:**
-	 * ```html
-	 * <ui5-dynamic-page-title>
-	 *   <!-- Other slots like heading, subheading, etc. -->
-	 *   <ui5-title slot="snappedTitleOnMobile" size="H4" wrapping-type="None">My Snapped Mobile Title</ui5-title>
-	 * </ui5-dynamic-page-title>
-	 * ```
-	 *
 	 * @public
 	 * @since 2.3.0
 	 */

From 982ec0a9481071299aae2984c7a0c04331166658 Mon Sep 17 00:00:00 2001
From: Konstantin Gogov <konstantin.gogov@sap.com>
Date: Thu, 26 Sep 2024 12:23:06 +0300
Subject: [PATCH 4/4] feat(ui5-dynamic-page-title): streamline snapped title
 handling on mobile

Refactored the implementation to pass the "snappedTitleOnMobile" state
from parent to child. This change ensures proper state management,
addressing previous review comments.
---
 packages/fiori/src/DynamicPage.ts             |  1 +
 packages/fiori/src/DynamicPageTitle.ts        | 21 ++++++++-----------
 .../fiori/src/themes/DynamicPageTitle.css     |  2 +-
 3 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/packages/fiori/src/DynamicPage.ts b/packages/fiori/src/DynamicPage.ts
index d7f72c8d0940..c197dad11d68 100644
--- a/packages/fiori/src/DynamicPage.ts
+++ b/packages/fiori/src/DynamicPage.ts
@@ -224,6 +224,7 @@ class DynamicPage extends UI5Element {
 		if (this.dynamicPageTitle) {
 			this.dynamicPageTitle.snapped = this._headerSnapped;
 			this.dynamicPageTitle.interactive = this.hasHeading;
+			this.dynamicPageTitle.hasSnappedTitleOnMobile = !!this.hasSnappedTitleOnMobile;
 		}
 	}
 
diff --git a/packages/fiori/src/DynamicPageTitle.ts b/packages/fiori/src/DynamicPageTitle.ts
index ca1ea7d4c263..acf37be2a2bf 100644
--- a/packages/fiori/src/DynamicPageTitle.ts
+++ b/packages/fiori/src/DynamicPageTitle.ts
@@ -12,7 +12,7 @@ import { isEnter, isSpace } from "@ui5/webcomponents-base/dist/Keys.js";
 import type Toolbar from "@ui5/webcomponents/dist/Toolbar.js";
 import type { ToolbarMinWidthChangeEventDetail } from "@ui5/webcomponents/dist/Toolbar.js";
 import ToolbarItemOverflowBehavior from "@ui5/webcomponents/dist/types/ToolbarItemOverflowBehavior.js";
-import { isDesktop, isPhone } from "@ui5/webcomponents-base/dist/Device.js";
+import { isDesktop } from "@ui5/webcomponents-base/dist/Device.js";
 import Icon from "@ui5/webcomponents/dist/Icon.js";
 import Title from "@ui5/webcomponents/dist/Title.js";
 
@@ -113,6 +113,13 @@ class DynamicPageTitle extends UI5Element {
 	@property({ type: Number })
 	minActionsWidth?: number;
 
+	/**
+	 * Indicates whether the title has snapped on mobile devices.
+	 * @private
+	 */
+	@property({ type: Boolean })
+	hasSnappedTitleOnMobile = false;
+
 	/**
 	 * Defines the content of the Heading of the Dynamic Page.
 	 *
@@ -148,7 +155,7 @@ class DynamicPageTitle extends UI5Element {
 	 * @public
 	 * @since 2.3.0
 	 */
-	@slot({ type: Title })
+	@slot({ type: HTMLElement })
 	snappedTitleOnMobile!: Array<Title>;
 
 	/**
@@ -231,12 +238,6 @@ class DynamicPageTitle extends UI5Element {
 
 	onBeforeRendering() {
 		this.prepareLayoutActions();
-
-		if (this.hasSnappedTitleOnMobile) {
-			this.setAttribute("_snapped-title-on-mobile", "");
-		} else {
-			this.removeAttribute("_snapped-title-on-mobile");
-		}
 	}
 
 	get styles() {
@@ -269,10 +270,6 @@ class DynamicPageTitle extends UI5Element {
 		return this.interactive ? "0" : undefined;
 	}
 
-	get hasSnappedTitleOnMobile() {
-		return isPhone() && this.snapped && this.snappedTitleOnMobile.length;
-	}
-
 	get _headerExpanded() {
 		return !this.snapped;
 	}
diff --git a/packages/fiori/src/themes/DynamicPageTitle.css b/packages/fiori/src/themes/DynamicPageTitle.css
index 87c1c720ae82..3c2f875b9c27 100644
--- a/packages/fiori/src/themes/DynamicPageTitle.css
+++ b/packages/fiori/src/themes/DynamicPageTitle.css
@@ -35,7 +35,7 @@
     box-shadow: var(--sapContent_HeaderShadow);
 }
 
-:host([snapped][_snapped-title-on-mobile]) {
+:host([has-snapped-title-on-mobile]) {
 	min-height: var(--_ui5_dynamic_page_snapped_title_on_mobile_min_height);
 	line-height: var(--_ui5_dynamic_page_snapped_title_on_mobile_line_height);
 }