From f349117a833376ad32970bf118a18448040832de Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Wed, 5 Nov 2025 11:20:46 +0100 Subject: [PATCH 1/2] fix(NcActions): handle expensive height computation by popover library - `autoBoundaryMaxSize` lets floating vue resize the popper inner container to the available size Signed-off-by: Maksim Sukharev --- src/components/NcActions/NcActions.vue | 56 +------------------------- 1 file changed, 1 insertion(+), 55 deletions(-) diff --git a/src/components/NcActions/NcActions.vue b/src/components/NcActions/NcActions.vue index 0a7df3f4e3..797071de5c 100644 --- a/src/components/NcActions/NcActions.vue +++ b/src/components/NcActions/NcActions.vue @@ -1476,7 +1476,6 @@ export default { onOpened() { this.$nextTick(() => { this.focusFirstAction(null) - this.resizePopover() /** * Event emitted when the popover menu is opened. @@ -1487,59 +1486,6 @@ export default { }) }, - /** - * Handle resizing the popover to make sure users can discover there is more to scroll - */ - resizePopover() { - // Get the inner v-popper element that defines the popover height (from floating-vue) - const inner = this.$refs.menu.closest('.v-popper__inner') - const height = this.$refs.menu.clientHeight - const maxMenuHeight = this.getMaxMenuHeight() - - // If the popover height is limited by the max-height (scrollbars shown) limit the height to half of the last element - if (height > maxMenuHeight) { - // sum of action heights - let currentHeight = 0 - // last action height - let actionHeight = 0 - for (const action of this.$refs.menuList.children) { - // If the max height would be overflown by half of the current element, - // then we limit the height to the half of the previous element - if ((currentHeight + action.clientHeight / 2) > maxMenuHeight) { - inner.style.height = `${currentHeight - actionHeight / 2}px` - break - } - // otherwise sum up the height - actionHeight = action.clientHeight - currentHeight += actionHeight - } - } else { - inner.style.height = 'fit-content' - } - }, - - getMaxMenuHeight() { - const { top, bottom } = this.$refs.triggerButton?.$el.getBoundingClientRect() ?? { top: 0, bottom: 0 } - const { top: boundaryTop, bottom: boundaryBottom } = this.boundariesElement?.getBoundingClientRect() ?? { top: 0, bottom: window.innerHeight } - - return Math.max( - // Either expand to the top - Math.min( - // max height is the top position of the trigger minus the header height minus the wedge and the padding - top - 84, - // and also limited to the space in the boundary - top - boundaryTop, - ), - // or expand to the bottom - Math.min( - // the max height is the window height minus current position of the trigger minus the wedge and padding - window.innerHeight - bottom - 34, - // and limit to the available space in the boundary - boundaryBottom - bottom, - ), - ) - }, - // MENU KEYS & FOCUS MANAGEMENT /** * @return {HTMLElement|null} @@ -1927,6 +1873,7 @@ export default { shown: this.opened, placement: this.placement, boundary: this.boundariesElement, + autoBoundaryMaxSize: true, container: this.container, popoverBaseClass: 'action-item__popper', popupRole: this.config.popupRole, @@ -2017,7 +1964,6 @@ export default { // Mostly used when clicking a menu item this.$nextTick(() => { if (this.opened && this.$refs.menu) { - this.resizePopover() const isAnyActive = this.$refs.menu.querySelector('li.active') || [] if (isAnyActive.length === 0) { this.focusFirstAction() From bddaaaab5fb5e2c0c46e6cdf6028e756f7150e13 Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Sat, 15 Nov 2025 13:05:52 +0100 Subject: [PATCH 2/2] fixup! fix(NcActions): handle expensive height computation by popover library Signed-off-by: Maksim Sukharev --- src/components/NcActions/NcActions.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/NcActions/NcActions.vue b/src/components/NcActions/NcActions.vue index 797071de5c..18907ccae6 100644 --- a/src/components/NcActions/NcActions.vue +++ b/src/components/NcActions/NcActions.vue @@ -1869,7 +1869,6 @@ export default { ref: 'popover', props: { delay: 0, - handleResize: true, shown: this.opened, placement: this.placement, boundary: this.boundariesElement, @@ -1885,10 +1884,10 @@ export default { // so we use both 'attrs' and 'props' attrs: { delay: 0, - handleResize: true, shown: this.opened, placement: this.placement, boundary: this.boundariesElement, + autoBoundaryMaxSize: true, container: this.container, ...this.manualOpen && { triggers: [] }, },