From 7cbfa3626317b6a70979dc2fdac253dacc7f4d9e Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Wed, 23 Oct 2024 15:26:23 +0900 Subject: [PATCH] Fixed menu position being broken when there are too many options. (#434) --- .../action/internal/InlineMenuElement.ts | 28 +++++++++++-------- .../cheetah-grid/src/test/ListGrid_sample.js | 1 + 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/packages/cheetah-grid/src/js/columns/action/internal/InlineMenuElement.ts b/packages/cheetah-grid/src/js/columns/action/internal/InlineMenuElement.ts index 5037d985..c75ed562 100644 --- a/packages/cheetah-grid/src/js/columns/action/internal/InlineMenuElement.ts +++ b/packages/cheetah-grid/src/js/columns/action/internal/InlineMenuElement.ts @@ -127,13 +127,9 @@ function openMenu( // Make the selection item at the middle let offset = 0; - let allHeight = 0; - for (let i = 0; i < children.length; i++) { + for (let i = 0; i < focusIndex; i++) { const { offsetHeight } = children[i]; - if (i < focusIndex) { - offset += offsetHeight; - } - allHeight += offsetHeight; + offset += offsetHeight; } (rect as Rect).offsetTop(-offset); menu.style.transformOrigin = `center ${ @@ -142,15 +138,21 @@ function openMenu( attachElement(element, rect, menu); // Control not to overflow the screen range - const menuClientRect = menu.getBoundingClientRect(); - const scaleDiff = (allHeight - menuClientRect.height) / 2; - const orgMenuTop = menuClientRect.top - scaleDiff; + const bkTransform = menu.style.transform; + let menuClientRect; + try { + // To calculate the original position, set `transform` to `none`. + menu.style.transform = "none"; + menuClientRect = menu.getBoundingClientRect(); + } finally { + menu.style.transform = bkTransform; + } + const orgMenuTop = menuClientRect.top; let menuTop = orgMenuTop; - const menuBottom = menuTop + allHeight; const winBottom = window.innerHeight; const winMargin = 20; - if (menuBottom > winBottom - winMargin) { - const diff = menuBottom - winBottom + winMargin; + if (menuClientRect.bottom > winBottom - winMargin) { + const diff = menuClientRect.bottom - winBottom + winMargin; menuTop -= diff; } if (menuTop < 0 /*winTop*/ + winMargin) { @@ -158,6 +160,8 @@ function openMenu( } if (menuTop !== orgMenuTop) { (rect as Rect).offsetTop(-(orgMenuTop - menuTop)); + // Sets the center of the menu since it is not possible to determine the exact center of the selected element. + menu.style.transformOrigin = "center"; // re update attachElement(element, rect, menu); } diff --git a/packages/cheetah-grid/src/test/ListGrid_sample.js b/packages/cheetah-grid/src/test/ListGrid_sample.js index 28f165ef..238197b2 100644 --- a/packages/cheetah-grid/src/test/ListGrid_sample.js +++ b/packages/cheetah-grid/src/test/ListGrid_sample.js @@ -69,6 +69,7 @@ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deseru {value: '5', label: 'Option 5'}, {value: '6', label: 'Option 6'}, {value: '7', label: 'Option 7'}, + // ...Array(100).fill(0).map((_, i) => ({value: i + 1, label: 'Option ' + (i + 1)})), ]; const grid = new cheetahGrid.ListGrid({ parentElement: document.querySelector('#parent'),