From 6e23f341333d43980f3be2094ba60b07e91823be Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Tue, 7 Mar 2023 21:13:16 -0500 Subject: [PATCH] fix: Ensure editor command menus cannot escape rhs of screen --- app/editor/components/CommandMenu.tsx | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/app/editor/components/CommandMenu.tsx b/app/editor/components/CommandMenu.tsx index 85eec5dcf..fcefbd657 100644 --- a/app/editor/components/CommandMenu.tsx +++ b/app/editor/components/CommandMenu.tsx @@ -390,6 +390,7 @@ class CommandMenu extends React.PureComponent< const domAtPos = view.domAtPos.bind(view); const ref = this.menuRef.current; + const offsetWidth = ref ? ref.offsetWidth : 0; const offsetHeight = ref ? ref.offsetHeight : 0; const node = findDomRefAtPos(selection.from, domAtPos); const paragraph: any = { node }; @@ -404,7 +405,7 @@ class CommandMenu extends React.PureComponent< const { left } = this.caretPosition; const { top, bottom, right } = paragraph.node.getBoundingClientRect(); - const margin = 24; + const margin = 12; const offsetParent = ref?.offsetParent ? ref.offsetParent.getBoundingClientRect() @@ -415,9 +416,12 @@ class CommandMenu extends React.PureComponent< left: 0, } as DOMRect); - let leftPos = left - offsetParent.left; - if (props.rtl && ref) { - leftPos = right - ref.scrollWidth; + let leftPos = Math.min( + left - offsetParent.left, + window.innerWidth - offsetParent.left - offsetWidth - margin + ); + if (props.rtl) { + leftPos = right - offsetWidth; } if (startPos.top - offsetHeight > margin) { @@ -468,6 +472,7 @@ class CommandMenu extends React.PureComponent< ); } + const searchInput = search.toLowerCase(); const filtered = items.filter((item) => { if (item.name === "separator") { return true; @@ -492,17 +497,23 @@ class CommandMenu extends React.PureComponent< return !item.defaultHidden; } - const n = search.toLowerCase(); if (!filterable) { return item; } + return ( - (item.title || "").toLowerCase().includes(n) || - (item.keywords || "").toLowerCase().includes(n) + (item.title || "").toLowerCase().includes(searchInput) || + (item.keywords || "").toLowerCase().includes(searchInput) ); }); - return filterExcessSeparators(filtered); + return filterExcessSeparators( + filtered.sort((item) => { + return (item.title || "").toLowerCase().startsWith(searchInput) + ? -1 + : 1; + }) + ); } render() {