From ca067490f39ae4c0cfca47c192eff40570ca58a6 Mon Sep 17 00:00:00 2001 From: lubber-de Date: Wed, 20 Dec 2023 22:30:32 +0100 Subject: [PATCH 1/5] fix(modal): use resizeobserver --- src/definitions/modules/modal.js | 104 ++++++++++++++++++++++------- src/definitions/modules/modal.less | 13 +++- 2 files changed, 92 insertions(+), 25 deletions(-) diff --git a/src/definitions/modules/modal.js b/src/definitions/modules/modal.js index bc2ae995e3..6b1d55c05c 100755 --- a/src/definitions/modules/modal.js +++ b/src/definitions/modules/modal.js @@ -94,6 +94,7 @@ id, observer, observeAttributes = false, + resizeObserver, module ; module = { @@ -246,6 +247,9 @@ if (observer) { observer.disconnect(); } + if (resizeObserver) { + resizeObserver.disconnect(); + } module.verbose('Destroying previous modal'); $module .removeData(moduleNamespace) @@ -263,6 +267,13 @@ observeChanges: function () { if ('MutationObserver' in window) { + if ('ResizeObserver' in window && settings.observeChanges) { + resizeObserver = new ResizeObserver(function (entries) { + module.refresh(); + }); + resizeObserver.observe(element); + module.debug('Setting up resize observer', resizeObserver); + } observer = new MutationObserver(function (mutations) { var collectNodes = function (parent) { var nodes = []; @@ -299,7 +310,7 @@ return !shouldRefreshInputs; }); - if (shouldRefresh && settings.observeChanges) { + if (!resizeObserver && shouldRefresh && settings.observeChanges) { module.debug('DOM tree modified, refreshing'); module.refresh(); } @@ -319,12 +330,15 @@ refresh: function () { module.remove.scrolling(); - module.cacheSizes(); - if (!module.can.useFlex()) { - module.set.modalOffset(); + if ($module.css('display') !== 'none') { + module.cacheSizes(); + if (!module.can.useFlex()) { + module.set.modalOffset(); + } + module.set.screenHeight(); + module.set.dimmerHeight(); + module.set.type(); } - module.set.screenHeight(); - module.set.type(); }, refreshModals: function () { @@ -601,7 +615,7 @@ } hadScrollbar = module.has.scrollbar(); module.showDimmer(); - module.cacheSizes(); + module.cacheSizes(true); if (hadScrollbar) { module.set.bodyMargin(); } @@ -729,7 +743,8 @@ if ($dimmable.dimmer('is animating') || !$dimmable.dimmer('is active')) { if (hadScrollbar) { if (!isBody) { - $dimmer.css('top', $dimmable.scrollTop()); + $dimmer.css('top', settings.detachable ? $dimmable.scrollTop() : 0); + module.set.dimmerHeight(); } module.save.bodyMargin(); } @@ -749,6 +764,7 @@ } module.remove.clickaway(); module.remove.screenHeight(); + module.remove.dimmerHeight(); }); } else { module.debug('Dimmer is not visible cannot hide'); @@ -881,6 +897,12 @@ $context.removeAttr('style'); } }, + dimmerStyle: function () { + if ($dimmer.attr('style') === '') { + module.verbose('Removing dimmer style attribute'); + $dimmer.removeAttr('style'); + } + }, screenHeight: function () { module.debug('Removing page height'); $context @@ -888,6 +910,15 @@ ; module.remove.bodyStyle(); }, + dimmerHeight: function () { + module.debug('Removing dimmer height'); + $dimmer.css({ + top: '', + height: '', + maxHeight: '', + }); + module.remove.dimmerStyle(); + }, keyboardShortcuts: function () { module.verbose('Removing keyboard shortcuts'); $document @@ -902,12 +933,14 @@ }, }, - cacheSizes: function () { + cacheSizes: function (getScrollingMargins) { $module.addClass(className.loading); var scrollHeight = $module.prop('scrollHeight'), modalWidth = $module.outerWidth(), - modalHeight = $module.outerHeight() + modalHeight = $module.outerHeight(), + scrollingTop = 0, + bottomMargin = 0 ; if (module.cache.pageHeight === undefined || modalHeight !== 0) { $.extend(module.cache, { @@ -921,6 +954,18 @@ }); module.cache.topOffset = -(module.cache.height / 2); } + if (getScrollingMargins) { + if (module.can.useFlex()) { + $module.addClass(className.scrolling); + scrollingTop = parseInt($module.css('top').replace(/[^\d.]/g, ''), 10) || 0; + bottomMargin = parseInt(window.getComputedStyle($module[0], '::after').height.replace(/[^\d.]/g, ''), 10) || 0; + $module.removeClass(className.scrolling); + } + $.extend(module.cache, { + scrollingTop: scrollingTop, + bottomMargin: bottomMargin, + }); + } $module.removeClass(className.loading); module.debug('Caching modal and container sizes', module.cache); }, @@ -980,7 +1025,8 @@ contextHeight = module.cache.contextHeight, verticalCenter = module.cache.contextHeight / 2, topOffset = module.cache.topOffset, - scrollHeight = module.cache.scrollHeight, + scrollingTop = module.cache.scrollingTop || 0, + scrollHeight = module.cache.scrollHeight - (module.cache.bottomMargin || 0), height = module.cache.height, paddingHeight = settings.padding, startPosition = verticalCenter + topOffset @@ -988,7 +1034,7 @@ return scrollHeight > height ? startPosition + scrollHeight + paddingHeight < contextHeight - : height + (paddingHeight * 2) < contextHeight; + : height + (paddingHeight * 2) - scrollingTop < contextHeight; }, }, has: { @@ -1140,14 +1186,15 @@ }, modalOffset: function () { if (!settings.detachable) { - var canFit = module.can.fit(); + var canFit = module.can.fit(), + scrollTop = (isBody ? $document : $context).scrollTop(); $module .css({ top: !$module.hasClass('aligned') && canFit - ? $document.scrollTop() + (module.cache.contextHeight - module.cache.height) / 2 + ? scrollTop + (module.cache.contextHeight - module.cache.height) / 2 : (!canFit || $module.hasClass('top') - ? $document.scrollTop() + settings.padding - : $document.scrollTop() + (module.cache.contextHeight - module.cache.height - settings.padding)), + ? scrollTop + settings.padding + : scrollTop + (module.cache.contextHeight - module.cache.height - settings.padding)), marginLeft: -(module.cache.width / 2), }) ; @@ -1164,13 +1211,24 @@ module.verbose('Setting modal offset for legacy mode'); }, screenHeight: function () { - if (module.can.fit()) { - $context.css('height', ''); - } else if (!$module.hasClass('bottom')) { - module.debug('Modal is taller than page content, resizing page height'); - $context - .css('height', module.cache.height + (settings.padding * 2) + 'px') - ; + if (!isBody && !settings.detachable) { + if (module.can.fit() || hadScrollbar) { + $context.css('height', ''); + } else if (!$module.hasClass('bottom')) { + module.debug('Modal is taller than page content, resizing page height'); + $context + .css('height', module.cache.height + (settings.padding * 2) + 'px') + ; + } + } + }, + dimmerHeight: function () { + if (!isBody && !settings.detachable) { + var contextHeight = $context.prop('scrollHeight'); + $dimmer.css({ + height: contextHeight, + maxHeight: contextHeight, + }); } }, active: function () { diff --git a/src/definitions/modules/modal.less b/src/definitions/modules/modal.less index 274fc6d36a..fd3f42ca22 100755 --- a/src/definitions/modules/modal.less +++ b/src/definitions/modules/modal.less @@ -227,6 +227,7 @@ opacity: @closeOpacityDimmed; } } + .undetached.dimmable.dimmed > .ui.modal:not(.fullscreen) > .close:not(.inside), .ui.dimmer > .ui.modal:not(.fullscreen) > .close:not(.inside) { text-shadow: @closeShadow; } @@ -447,6 +448,9 @@ overflow: auto; overscroll-behavior: @overscrollBehavior; } + .modals.dimmer { + scrollbar-gutter: stable; + } .modals.dimmer .ui.scrolling.modal.fullscreen { top: 0; } @@ -455,12 +459,17 @@ top: @scrollingTop; } - /* Fix for Firefox, Edge, IE11 */ - .modals.dimmer .ui.scrolling.modal:not([class*="overlay fullscreen"])::after { + .modals.dimmer .ui.modal:not([class*="overlay fullscreen"])::after { content: "\00A0"; position: absolute; + height: 0; + } + .modals.dimmer .ui.scrolling.modal:not([class*="overlay fullscreen"])::after { height: @scrollingMargin; } + .dimmable.dimmed > .modals.dimmer { + overflow: auto; + } /* Undetached Scrolling */ .scrolling.undetached.dimmable.dimmed { From 6c5a7eabf09d536638d979c78e0c62713d851c99 Mon Sep 17 00:00:00 2001 From: lubber-de Date: Wed, 1 May 2024 22:41:47 +0200 Subject: [PATCH 2/5] feat(modal): make scrollbar gutter appearance customizable --- src/definitions/modules/modal.less | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/definitions/modules/modal.less b/src/definitions/modules/modal.less index fd3f42ca22..09d7dd8990 100755 --- a/src/definitions/modules/modal.less +++ b/src/definitions/modules/modal.less @@ -448,8 +448,10 @@ overflow: auto; overscroll-behavior: @overscrollBehavior; } - .modals.dimmer { - scrollbar-gutter: stable; + @supports selector(:has(.f)) { + .modals.dimmer:has(.scrollable) { + scrollbar-gutter: stable; + } } .modals.dimmer .ui.scrolling.modal.fullscreen { top: 0; From 87ea82ee6a61eb93021edacac9b82db8d0db1924 Mon Sep 17 00:00:00 2001 From: lubber-de Date: Fri, 21 Mar 2025 22:39:58 +0100 Subject: [PATCH 3/5] fix(modal): linting fixes --- src/definitions/modules/modal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/definitions/modules/modal.js b/src/definitions/modules/modal.js index c169a273ce..321e20fcda 100755 --- a/src/definitions/modules/modal.js +++ b/src/definitions/modules/modal.js @@ -1117,7 +1117,7 @@ }, dimmerHeight: function () { if (!isBody && !settings.detachable) { - var contextHeight = $context.prop('scrollHeight'); + let contextHeight = $context.prop('scrollHeight'); $dimmer.css({ height: contextHeight, maxHeight: contextHeight, From 7cb640744e7c3ae3113dc007b1de8a595cf293b2 Mon Sep 17 00:00:00 2001 From: lubber-de Date: Tue, 9 Sep 2025 16:00:40 +0200 Subject: [PATCH 4/5] feat(modal): resizeobserver is supported everywhere --- src/definitions/modules/modal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/definitions/modules/modal.js b/src/definitions/modules/modal.js index d92f58754b..7255f2470e 100755 --- a/src/definitions/modules/modal.js +++ b/src/definitions/modules/modal.js @@ -257,7 +257,7 @@ }, observeChanges: function () { - if ('ResizeObserver' in window && settings.observeChanges) { + if (settings.observeChanges) { resizeObserver = new ResizeObserver(function (entries) { module.refresh(); }); From 2553af2bf2d2e4548e86f248901395d5b573e6f9 Mon Sep 17 00:00:00 2001 From: lubber-de Date: Sat, 8 Nov 2025 00:15:32 +0100 Subject: [PATCH 5/5] fix(modal): lint fixes --- src/definitions/modules/modal.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/definitions/modules/modal.js b/src/definitions/modules/modal.js index 57e894a266..3068c3af9d 100755 --- a/src/definitions/modules/modal.js +++ b/src/definitions/modules/modal.js @@ -902,8 +902,8 @@ if (getScrollingMargins) { if (module.can.useFlex()) { $module.addClass(className.scrolling); - scrollingTop = parseInt($module.css('top').replace(/[^\d.]/g, ''), 10) || 0; - bottomMargin = parseInt(window.getComputedStyle($module[0], '::after').height.replace(/[^\d.]/g, ''), 10) || 0; + scrollingTop = Number.parseInt($module.css('top').replace(/[^\d.]/g, ''), 10) || 0; + bottomMargin = Number.parseInt(window.getComputedStyle($module[0], '::after').height.replace(/[^\d.]/g, ''), 10) || 0; $module.removeClass(className.scrolling); } $.extend(module.cache, {