diff --git a/application/source/dom/util.mjs b/application/source/dom/util.mjs
index ce375d943b8d80d2e48633ed32717a8333087f95..38c5e14175e3ef9eb74f7e0cff6521b4fd557339 100644
--- a/application/source/dom/util.mjs
+++ b/application/source/dom/util.mjs
@@ -8,7 +8,7 @@
 import { getGlobal } from "../types/global.mjs";
 import { validateString } from "../types/validate.mjs";
 
-export { getDocument, getWindow, getDocumentFragmentFromString };
+export { getDocument, getWindow, getDocumentFragmentFromString, findElementWithIdUpwards };
 
 /**
  * This method fetches the document object
@@ -151,3 +151,52 @@ function getDocumentFragmentFromString(html) {
 
     return template.content;
 }
+
+
+/**
+ * Recursively searches upwards from a given element to find an ancestor element
+ * with a specified ID, considering both normal DOM and shadow DOM.
+ *
+ * @param {HTMLElement|ShadowRoot} element - The starting element or shadow root to search from.
+ * @param {string} targetId - The ID of the target element to find.
+ * @returns {HTMLElement|null} - The ancestor element with the specified ID, or null if not found.
+ * @memberOf Monster.DOM
+ * @since 3.29.0
+ * @license AGPLv3
+ * @copyright schukai GmbH
+ */
+function findElementWithIdUpwards(element, targetId) {
+    if (!element) {
+        return null;
+    }
+
+    // Check if the current element has the target ID
+    if (element.id === targetId) {
+        return element;
+    }
+
+    // Search within the current element's shadow root, if it exists
+    if (element.shadowRoot) {
+        const target = element.shadowRoot.getElementById(targetId);
+        if (target) {
+            return target;
+        }
+    }
+
+    // If the current element is the document.documentElement, search within the main document
+    if (element === document.documentElement) {
+        const target = document.getElementById(targetId);
+        if (target) {
+            return target;
+        }
+    }
+
+    // If the current element is inside a shadow root, search its host's ancestors
+    const rootNode = element.getRootNode();
+    if (rootNode && rootNode instanceof ShadowRoot) {
+        return findElementWithIdUpwards(rootNode.host, targetId);
+    }
+
+    // Otherwise, search the current element's parent
+    return findElementWithIdUpwards(element.parentElement, targetId);
+}
\ No newline at end of file
diff --git a/development/test/cases/dom/find.mjs b/development/test/cases/dom/find.mjs
new file mode 100644
index 0000000000000000000000000000000000000000..24bc0a2feaa80fb66aa04acbcd0ee4cd8c686b0c
--- /dev/null
+++ b/development/test/cases/dom/find.mjs
@@ -0,0 +1,85 @@
+import {
+    findElementWithIdUpwards
+} from "../../../../application/source/dom/util.mjs";
+
+import { expect } from 'chai';
+import { JSDOM } from 'jsdom';
+
+let originalEnvironment;
+
+function setupTestEnvironment() {
+    const { window } = new JSDOM('<!DOCTYPE html>', { pretendToBeVisual: true });
+
+    const { document, customElements, HTMLElement } = window;
+    originalEnvironment = {
+        document: globalThis.document,
+        customElements: globalThis.customElements,
+        HTMLElement: globalThis.HTMLElement,
+        ShadowRoot: globalThis.ShadowRoot,
+    };
+    globalThis.document = document;
+    globalThis.customElements = customElements;
+    globalThis.HTMLElement = HTMLElement;
+    globalThis.ShadowRoot = window.ShadowRoot || class ShadowRoot {}; // Fallback for JSDOM
+
+    class TestComponent extends HTMLElement {
+        constructor() {
+            super();
+            this.attachShadow({ mode: 'open' });
+        }
+    }
+
+    if (!customElements.get('test-component')) {
+        customElements.define('test-component', TestComponent);
+    }
+}
+
+function cleanupTestEnvironment() {
+    Object.assign(globalThis, originalEnvironment);
+}
+
+describe('findElementWithIdUpwards', () => {
+    before(() => {
+        setupTestEnvironment();
+    });
+
+    after(() => {
+        cleanupTestEnvironment();
+    });
+
+    beforeEach(() => {
+        // Set up the DOM
+        document.body.innerHTML = `
+      <div id="container">
+        <div id="parent">
+          <div id="child"></div>
+        </div>
+      </div>
+    `;
+
+        const shadowHost = document.createElement('div');
+        document.body.appendChild(shadowHost);
+        const shadowRoot = shadowHost.attachShadow({ mode: 'open' });
+        const innerElement = document.createElement('div');
+        innerElement.id = 'inner';
+        shadowRoot.appendChild(innerElement);
+    });
+
+    it('should find the element with the target ID in the normal DOM', () => {
+        const child = document.getElementById('child');
+        const result = findElementWithIdUpwards(child, 'parent');
+        expect(result).to.equal(document.getElementById('parent'));
+    });
+
+    it('should find the element with the target ID in the shadow DOM', () => {
+        const innerElement = document.querySelector('div[shadowroot] > div');
+        const result = findElementWithIdUpwards(innerElement, 'inner');
+        expect(result).to.equal(innerElement);
+    });
+
+    it('should return null if the element with the target ID is not found', () => {
+        const child = document.getElementById('child');
+        const result = findElementWithIdUpwards(child, 'nonexistent');
+        expect(result).to.be.null;
+    });
+});
diff --git a/development/test/cases/dom/util.mjs b/development/test/cases/dom/util.mjs
index 0ee3586470834805a2815e5737b32bfa7adb03e2..456c3452811c791879837696b4acefab44640b6c 100644
--- a/development/test/cases/dom/util.mjs
+++ b/development/test/cases/dom/util.mjs
@@ -1,5 +1,3 @@
-'use strict';
-
 import {
     getDocument, getWindow, getDocumentFragmentFromString
 } from "../../../../application/source/dom/util.mjs";