diff --git a/src/actions/action.ts b/src/actions/action.ts index 3f4c8badf9..a95272a967 100644 --- a/src/actions/action.ts +++ b/src/actions/action.ts @@ -389,7 +389,7 @@ export class Action extends BaseAction implements IAction, ILocalizableOwner { const { innerPopupModel, listModel }: { innerPopupModel: PopupModel, listModel: ListModel } = createPopupModelWithListModel( { items: items, onSelectionChanged: onSelectionChanged }, - { horizontalPosition: "right", showPointer: false } + { horizontalPosition: "right", showPointer: false, canShrink: false } ); innerPopupModel.cssClass = "sv-popup-inner"; listModel.searchEnabled = false; diff --git a/src/popup-dropdown-view-model.ts b/src/popup-dropdown-view-model.ts index d25fa346f7..aaf54d8c2b 100644 --- a/src/popup-dropdown-view-model.ts +++ b/src/popup-dropdown-view-model.ts @@ -98,7 +98,8 @@ export class PopupDropdownViewModel extends PopupBaseViewModel { pos.top, height, DomWindowHelper.getInnerHeight(), - verticalPosition + verticalPosition, + this.model.canShrink ); if (!!newVerticalDimensions) { this.height = newVerticalDimensions.height + "px"; diff --git a/src/popup.ts b/src/popup.ts index 92bd81ab3e..b53e2480c7 100644 --- a/src/popup.ts +++ b/src/popup.ts @@ -15,6 +15,7 @@ export interface IPopupOptionsBase { horizontalPosition?: HorizontalPosition; showPointer?: boolean; isModal?: boolean; + canShrink?: boolean; displayMode?: "popup" | "overlay"; } export interface IDialogOptions extends IPopupOptionsBase { @@ -40,6 +41,7 @@ export class PopupModel extends Base implements IPopupOptionsBase { @property({ defaultValue: "left" }) horizontalPosition: HorizontalPosition; @property({ defaultValue: true }) showPointer: boolean; @property({ defaultValue: false }) isModal: boolean; + @property({ defaultValue: true }) canShrink: boolean; @property({ defaultValue: true }) isFocusedContent: boolean; @property({ defaultValue: true }) isFocusedContainer: boolean; @property({ defaultValue: "" }) cssClass: string; diff --git a/src/utils/popup.ts b/src/utils/popup.ts index dbff8d3942..82d12bb920 100644 --- a/src/utils/popup.ts +++ b/src/utils/popup.ts @@ -57,17 +57,23 @@ export class PopupUtils { top: number, height: number, windowHeight: number, - verticalPosition: VerticalPosition + verticalPosition: VerticalPosition, + canShrink: boolean = true ) { let result; + const maxHeight = windowHeight - PopupUtils.bottomIndent; if(verticalPosition === "top") { result = { height: height, top: top }; } if (top < 0) { - result = { height: height + top, top: 0 }; + result = { height: canShrink ? height + top : height, top: 0 }; } else if (height + top > windowHeight) { - let newHeight = Math.min(height, windowHeight - top - PopupUtils.bottomIndent); - result = { height: newHeight, top: top }; + let newHeight = Math.min(height, maxHeight - top); + result = { height: canShrink ? newHeight : height, top: canShrink ? top : top - (height - newHeight) }; + } + if (result) { + result.height = Math.min(result.height, maxHeight); + result.top = Math.max(result.top, 0); } return result; } diff --git a/tests/components/actionbartests.ts b/tests/components/actionbartests.ts index 331a5d3411..214a766b33 100644 --- a/tests/components/actionbartests.ts +++ b/tests/components/actionbartests.ts @@ -295,3 +295,10 @@ QUnit.test("Action locTitleName doesn't work correctly, bug#8093", (assert) => { survey.locale = "fr"; assert.equal(action1.title, "Effacer la page", "Clear page fr#2"); }); +QUnit.test("Action subitems popup canShrink property", function (assert) { + const action = new Action({ id: "test2", title: "test2" }); + const subitems = [new Action({ id: "test28", title: "test28" }), new Action({ id: "test29", title: "test29" })]; + (action as Action).setItems(subitems, () => { }); + + assert.notOk(action.popupModel.canShrink); +}); \ No newline at end of file diff --git a/tests/components/popuptests.ts b/tests/components/popuptests.ts index 05e3f920de..21e7b09993 100644 --- a/tests/components/popuptests.ts +++ b/tests/components/popuptests.ts @@ -950,6 +950,27 @@ QUnit.test("Check getCorrectedVerticalDimensions if both directions do not fit", assert.equal(newVerticalDimensions.top, 10); }); +QUnit.test("Check getCorrectedVerticalDimensions if both directions do not fit and canShrink = false", (assert) => { + let newVerticalDimensions = PopupUtils.getCorrectedVerticalDimensions(-20, 200, 300, "bottom", false); + assert.equal(newVerticalDimensions.height, 200); + assert.equal(newVerticalDimensions.top, 0); + + newVerticalDimensions = PopupUtils.getCorrectedVerticalDimensions(150, 200, 300, "bottom", false); + assert.equal(newVerticalDimensions.height, 200); + assert.equal(newVerticalDimensions.top, 100 - PopupUtils.bottomIndent); + + newVerticalDimensions = PopupUtils.getCorrectedVerticalDimensions(150, 450, 300, "bottom", false); + assert.equal(newVerticalDimensions.height, 300 - PopupUtils.bottomIndent); + assert.equal(newVerticalDimensions.top, 0); + + newVerticalDimensions = PopupUtils.getCorrectedVerticalDimensions(10, 200, 300, "bottom", false); + assert.notOk(newVerticalDimensions); + + newVerticalDimensions = PopupUtils.getCorrectedVerticalDimensions(10, 200, 300, "top", false); + assert.equal(newVerticalDimensions.height, 200); + assert.equal(newVerticalDimensions.top, 10); +}); + QUnit.test("Check updateHorizontalDimensions", (assert) => { let newHorizontalDimensions = PopupUtils.updateHorizontalDimensions(-20, 200, 300, "center"); assert.equal(newHorizontalDimensions.width, 200, "updateHorizontalDimensions - center - fitting left out - width"); @@ -1314,6 +1335,43 @@ QUnit.test("Fixed PopupModel width calculate and overflow content position calcu targetElement.remove(); }); +QUnit.skip("PopupModel overflow content and canShrink position calculate", (assert) => { + const model: PopupModel = new PopupModel("sv-list", {}, { verticalPosition: "bottom", horizontalPosition: "left", showPointer: false }); + model.setWidthByTarget = true; + const targetElement: HTMLElement = document.createElement("button"); + + targetElement.style.position = "absolute"; + targetElement.style.top = "130px"; + targetElement.style.left = "0px"; + targetElement.style.height = "10px"; + addElementIntoBody(targetElement); + targetElement.parentElement.scrollTop = 0; + targetElement.parentElement.scrollLeft = 0; + + const viewModel: PopupDropdownViewModel = createPopupViewModel(model, targetElement) as PopupDropdownViewModel; + viewModel.initializePopupContainer(); + viewModel.container.innerHTML = popupTemplate; + let popupContainer = getPopupContainer(viewModel.container); + popupContainer.style.width = "200px"; + popupContainer.style.height = "700px"; + + (window).innerWidth = 1000; + (window).innerHeight = 800; + model.toggleVisibility(); + + viewModel.updateOnShowing(); + assert.equal(viewModel.top, "130px", "top"); + assert.equal(viewModel.height, "654px", "height"); + + viewModel.model.canShrink = false; + viewModel.updateOnShowing(); + assert.equal(viewModel.top, "84px", "top"); + assert.equal(viewModel.height, "700px", "height"); + + viewModel.dispose(); + targetElement.remove(); +}); + QUnit.test("PopupViewModel updateOnHiding", (assert) => { const model: PopupModel = new PopupModel("sv-list", {}, { verticalPosition: "bottom", horizontalPosition: "center", showPointer: true }); model.positionMode = "fixed";