mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-18 11:36:36 +00:00
fix(context-menu): render submenu based on viewport constraints #577
This commit is contained in:
parent
29745564a6
commit
6dbbe7a2f0
2 changed files with 27 additions and 3 deletions
|
@ -26,6 +26,7 @@
|
||||||
const position = writable([x, y]);
|
const position = writable([x, y]);
|
||||||
const currentIndex = writable(-1);
|
const currentIndex = writable(-1);
|
||||||
const hasPopup = writable(false);
|
const hasPopup = writable(false);
|
||||||
|
const menuOffsetX = writable(0);
|
||||||
const ctx = getContext("ContextMenu");
|
const ctx = getContext("ContextMenu");
|
||||||
|
|
||||||
let options = [];
|
let options = [];
|
||||||
|
@ -44,6 +45,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
setContext("ContextMenu", {
|
setContext("ContextMenu", {
|
||||||
|
menuOffsetX,
|
||||||
currentIndex,
|
currentIndex,
|
||||||
position,
|
position,
|
||||||
close,
|
close,
|
||||||
|
@ -77,9 +79,19 @@
|
||||||
<svelte:window
|
<svelte:window
|
||||||
on:contextmenu|preventDefault="{(e) => {
|
on:contextmenu|preventDefault="{(e) => {
|
||||||
if (level > 1) return;
|
if (level > 1) return;
|
||||||
if (open || x === 0) x = e.x;
|
|
||||||
|
const { height, width } = ref.getBoundingClientRect();
|
||||||
|
|
||||||
|
if (open || x === 0) {
|
||||||
|
if (window.innerWidth - width < e.x) {
|
||||||
|
x = e.x - width;
|
||||||
|
} else {
|
||||||
|
x = e.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (open || y === 0) {
|
if (open || y === 0) {
|
||||||
const { height } = ref.getBoundingClientRect();
|
menuOffsetX.set(e.x);
|
||||||
|
|
||||||
if (window.innerHeight - height < e.y) {
|
if (window.innerHeight - height < e.y) {
|
||||||
y = e.y - height;
|
y = e.y - height;
|
||||||
|
|
|
@ -70,11 +70,16 @@
|
||||||
let role = "menuitem";
|
let role = "menuitem";
|
||||||
let submenuOpen = false;
|
let submenuOpen = false;
|
||||||
let submenuPosition = [0, 0];
|
let submenuPosition = [0, 0];
|
||||||
|
let menuOffsetX = 0;
|
||||||
|
|
||||||
const unsubPosition = ctx.position.subscribe((position) => {
|
const unsubPosition = ctx.position.subscribe((position) => {
|
||||||
rootMenuPosition = position;
|
rootMenuPosition = position;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const unsubMenuOffsetX = ctx.menuOffsetX.subscribe((_menuOffsetX) => {
|
||||||
|
menuOffsetX = _menuOffsetX;
|
||||||
|
});
|
||||||
|
|
||||||
function handleClick(opts = {}) {
|
function handleClick(opts = {}) {
|
||||||
if (disabled) return ctx.close();
|
if (disabled) return ctx.close();
|
||||||
if (subOptions) return;
|
if (subOptions) return;
|
||||||
|
@ -112,6 +117,7 @@
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubPosition();
|
unsubPosition();
|
||||||
|
unsubMenuOffsetX();
|
||||||
if (unsubCurrentIds) unsubCurrentIds();
|
if (unsubCurrentIds) unsubCurrentIds();
|
||||||
if (unsubCurrentId) unsubCurrentId();
|
if (unsubCurrentId) unsubCurrentId();
|
||||||
if (typeof timeoutHover === "number") clearTimeout(timeoutHover);
|
if (typeof timeoutHover === "number") clearTimeout(timeoutHover);
|
||||||
|
@ -124,7 +130,13 @@
|
||||||
$: ctx.setPopup(submenuOpen);
|
$: ctx.setPopup(submenuOpen);
|
||||||
$: if (submenuOpen) {
|
$: if (submenuOpen) {
|
||||||
const { width, y } = ref.getBoundingClientRect();
|
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) {
|
if (isSelectable) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue