From 6dbbe7a2f0466f4ccbae67f42428425d8b9f671c Mon Sep 17 00:00:00 2001 From: Eric Y Liu Date: Fri, 2 Apr 2021 13:23:01 -0700 Subject: [PATCH] fix(context-menu): render submenu based on viewport constraints #577 --- src/ContextMenu/ContextMenu.svelte | 16 ++++++++++++++-- src/ContextMenu/ContextMenuOption.svelte | 14 +++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/ContextMenu/ContextMenu.svelte b/src/ContextMenu/ContextMenu.svelte index 190caa44..1a75c18d 100644 --- a/src/ContextMenu/ContextMenu.svelte +++ b/src/ContextMenu/ContextMenu.svelte @@ -26,6 +26,7 @@ const position = writable([x, y]); const currentIndex = writable(-1); const hasPopup = writable(false); + const menuOffsetX = writable(0); const ctx = getContext("ContextMenu"); let options = []; @@ -44,6 +45,7 @@ } setContext("ContextMenu", { + menuOffsetX, currentIndex, position, close, @@ -77,9 +79,19 @@ { rootMenuPosition = position; }); + const unsubMenuOffsetX = ctx.menuOffsetX.subscribe((_menuOffsetX) => { + menuOffsetX = _menuOffsetX; + }); + function handleClick(opts = {}) { if (disabled) return ctx.close(); if (subOptions) return; @@ -112,6 +117,7 @@ return () => { unsubPosition(); + unsubMenuOffsetX(); if (unsubCurrentIds) unsubCurrentIds(); if (unsubCurrentId) unsubCurrentId(); if (typeof timeoutHover === "number") clearTimeout(timeoutHover); @@ -124,7 +130,13 @@ $: ctx.setPopup(submenuOpen); $: if (submenuOpen) { const { width, y } = ref.getBoundingClientRect(); - submenuPosition = [rootMenuPosition[0] + width, y]; + let x = rootMenuPosition[0] + width; + + if (window.innerWidth - menuOffsetX < width) { + x = rootMenuPosition[0] - width; + } + + submenuPosition = [x, y]; } $: { if (isSelectable) {