@pure-ds/core 0.7.41 → 0.7.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -218,6 +218,64 @@ function enhanceDropdown(elem) {
218
218
  return false;
219
219
  };
220
220
 
221
+ const collectClippingAncestors = (startNode, stopAt = null) => {
222
+ const targets = [];
223
+ let current = getContainingAncestor(startNode);
224
+
225
+ while (current instanceof Element) {
226
+ const tagName = String(current.tagName || "").toUpperCase();
227
+ if (tagName === "HTML" || tagName === "BODY") {
228
+ break;
229
+ }
230
+
231
+ const style = getComputedStyle(current);
232
+ const clips = [style.overflow, style.overflowX, style.overflowY].some(
233
+ (value) => value && value !== "visible",
234
+ );
235
+
236
+ if (clips) {
237
+ targets.push(current);
238
+ }
239
+
240
+ if (stopAt && current === stopAt) {
241
+ break;
242
+ }
243
+
244
+ current = getContainingAncestor(current);
245
+ }
246
+
247
+ return targets;
248
+ };
249
+
250
+ const setOverlayClippingOverride = (enabled, stopAt = null) => {
251
+ if (enabled) {
252
+ if (overlayOverflowOverrides.size) return;
253
+
254
+ const targets = collectClippingAncestors(menu, stopAt);
255
+ targets.forEach((element) => {
256
+ overlayOverflowOverrides.set(element, {
257
+ overflow: element.style.overflow,
258
+ overflowX: element.style.overflowX,
259
+ overflowY: element.style.overflowY,
260
+ });
261
+
262
+ element.style.overflow = "visible";
263
+ element.style.overflowX = "visible";
264
+ element.style.overflowY = "visible";
265
+ });
266
+
267
+ return;
268
+ }
269
+
270
+ overlayOverflowOverrides.forEach((previous, element) => {
271
+ element.style.overflow = previous.overflow;
272
+ element.style.overflowX = previous.overflowX;
273
+ element.style.overflowY = previous.overflowY;
274
+ });
275
+
276
+ overlayOverflowOverrides.clear();
277
+ };
278
+
221
279
  const reattachFloatingMenu = () => {
222
280
  if (menu.getAttribute("aria-hidden") !== "false") return;
223
281
  clearFloatingMenuPosition();
@@ -230,10 +288,19 @@ function enhanceDropdown(elem) {
230
288
 
231
289
  const positionFloatingMenu = () => {
232
290
  if (menu.getAttribute("aria-hidden") !== "false") return;
233
- if (hasNonViewportFixedContainingBlock()) {
291
+ const hasFixedContainingBlock = hasNonViewportFixedContainingBlock();
292
+
293
+ if (hasFixedContainingBlock) {
294
+ // Fixed overlay is unsafe in this context; keep local positioning,
295
+ // but temporarily unclip ancestor overflow containers.
296
+ setOverlayClippingOverride(true);
234
297
  clearFloatingMenuPosition();
235
298
  return;
236
299
  }
300
+
301
+ // Fixed overlay path does not need clipping overrides.
302
+ setOverlayClippingOverride(false);
303
+
237
304
  const anchorRect = (trigger || elem).getBoundingClientRect();
238
305
  const viewport = window.visualViewport;
239
306
  const viewportWidth =
@@ -309,6 +376,7 @@ function enhanceDropdown(elem) {
309
376
 
310
377
  let configChangedHandler = null;
311
378
  let configRepositionFrame = null;
379
+ const overlayOverflowOverrides = new Map();
312
380
  const bindConfigChanged = () => {
313
381
  if (configChangedHandler || typeof document === "undefined") return;
314
382
  configChangedHandler = () => {
@@ -342,6 +410,7 @@ function enhanceDropdown(elem) {
342
410
  let clickHandler = null;
343
411
 
344
412
  const openMenu = () => {
413
+ setOverlayClippingOverride(false);
345
414
  elem.dataset.dropdownDirection = resolveDirection();
346
415
  elem.dataset.dropdownAlign = resolveAlign();
347
416
  menu.setAttribute("aria-hidden", "false");
@@ -374,6 +443,7 @@ function enhanceDropdown(elem) {
374
443
  unbindReposition();
375
444
  unbindConfigChanged();
376
445
  clearFloatingMenuPosition();
446
+ setOverlayClippingOverride(false);
377
447
 
378
448
  // Remove click-outside handler when closing
379
449
  if (clickHandler) {