From 0eecc0c7aae406b9063862cfdf1208800ea02d24 Mon Sep 17 00:00:00 2001 From: Robin Townsend Date: Fri, 25 Feb 2022 12:22:39 -0500 Subject: [PATCH 1/2] Fix edge case in context menu chevron positioning Signed-off-by: Robin Townsend --- src/components/structures/ContextMenu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index bbdcae2eebc..1730ec2396f 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -271,7 +271,7 @@ export default class ContextMenu extends React.PureComponent { windowHeight - contextMenuRect.height - WINDOW_PADDING, ); if (chevronOffset.top !== undefined) { - chevronOffset.top = props.chevronOffset + props.bottom - position.bottom; + chevronOffset.top = props.chevronOffset + position.bottom - props.bottom; } } if (position.left !== undefined) { @@ -288,7 +288,7 @@ export default class ContextMenu extends React.PureComponent { windowWidth - contextMenuRect.width - WINDOW_PADDING, ); if (chevronOffset.left !== undefined) { - chevronOffset.left = props.chevronOffset + props.right - position.right; + chevronOffset.left = props.chevronOffset + position.right - props.right; } } } From 5f6fbb9f5cb639b0c540967cf391983de1e86fea Mon Sep 17 00:00:00 2001 From: Robin Townsend Date: Fri, 25 Feb 2022 12:24:23 -0500 Subject: [PATCH 2/2] Expand context menu positioning regression tests Signed-off-by: Robin Townsend --- .../views/context_menus/ContextMenu-test.tsx | 111 +++++++++++++++--- 1 file changed, 93 insertions(+), 18 deletions(-) diff --git a/test/components/views/context_menus/ContextMenu-test.tsx b/test/components/views/context_menus/ContextMenu-test.tsx index 0b34b7dfd46..29a041f0f0e 100644 --- a/test/components/views/context_menus/ContextMenu-test.tsx +++ b/test/components/views/context_menus/ContextMenu-test.tsx @@ -34,26 +34,101 @@ describe("", () => { height: menuSize, }); - const targetY = windowSize - menuSize + 50; const targetChevronOffset = 25; - const wrapper = mount( - , - ); - const chevron = wrapper.find(".mx_ContextualMenu_chevron_right"); - - const actualY = parseInt(wrapper.getDOMNode().style.getPropertyValue("top")); - const actualChevronOffset = parseInt(chevron.getDOMNode().style.getPropertyValue("top")); - - it("stays within the window", () => { - expect(actualY + menuSize).toBeLessThanOrEqual(windowSize); + describe("near top edge of window", () => { + const targetY = -50; + + const wrapper = mount( + , + ); + const chevron = wrapper.find(".mx_ContextualMenu_chevron_left"); + + const actualY = windowSize - parseInt(wrapper.getDOMNode().style.getPropertyValue("bottom")) - menuSize; + const actualChevronOffset = parseInt(chevron.getDOMNode().style.getPropertyValue("top")); + + it("stays within the window", () => { + expect(actualY).toBeGreaterThanOrEqual(0); + }); + it("positions the chevron correctly", () => { + expect(actualChevronOffset).toEqual(targetChevronOffset + targetY - actualY); + }); }); - it("positions the chevron correctly", () => { - expect(actualChevronOffset).toEqual(targetChevronOffset + targetY - actualY); + + describe("near right edge of window", () => { + const targetX = windowSize - menuSize + 50; + + const wrapper = mount( + , + ); + const chevron = wrapper.find(".mx_ContextualMenu_chevron_top"); + + const actualX = parseInt(wrapper.getDOMNode().style.getPropertyValue("left")); + const actualChevronOffset = parseInt(chevron.getDOMNode().style.getPropertyValue("left")); + + it("stays within the window", () => { + expect(actualX + menuSize).toBeLessThanOrEqual(windowSize); + }); + it("positions the chevron correctly", () => { + expect(actualChevronOffset).toEqual(targetChevronOffset + targetX - actualX); + }); + }); + + describe("near bottom edge of window", () => { + const targetY = windowSize - menuSize + 50; + + const wrapper = mount( + , + ); + const chevron = wrapper.find(".mx_ContextualMenu_chevron_right"); + + const actualY = parseInt(wrapper.getDOMNode().style.getPropertyValue("top")); + const actualChevronOffset = parseInt(chevron.getDOMNode().style.getPropertyValue("top")); + + it("stays within the window", () => { + expect(actualY + menuSize).toBeLessThanOrEqual(windowSize); + }); + it("positions the chevron correctly", () => { + expect(actualChevronOffset).toEqual(targetChevronOffset + targetY - actualY); + }); + }); + + describe("near left edge of window", () => { + const targetX = -50; + + const wrapper = mount( + , + ); + const chevron = wrapper.find(".mx_ContextualMenu_chevron_bottom"); + + const actualX = windowSize - parseInt(wrapper.getDOMNode().style.getPropertyValue("right")) - menuSize; + const actualChevronOffset = parseInt(chevron.getDOMNode().style.getPropertyValue("left")); + + it("stays within the window", () => { + expect(actualX).toBeGreaterThanOrEqual(0); + }); + it("positions the chevron correctly", () => { + expect(actualChevronOffset).toEqual(targetChevronOffset + targetX - actualX); + }); }); });