Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ jobs:
REF="master"
ENVIRONMENT="graphite-dev (Production)"
else
REF="${{ inputs.checkout_ref || github.head_ref || github.ref_name }}"
REF="$(git rev-parse HEAD)"
ENVIRONMENT="graphite-dev (Preview)"
fi
DEPLOY_ID=$(gh api \
Expand Down
38 changes: 37 additions & 1 deletion frontend/src/components/floating-menus/MenuList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
let virtualScrollingEntriesStart = 0;
let keydownListenerAdded = false;
let destroyed = false;
let maxMenuWidth = 0;
let resizeObserver: ResizeObserver | undefined = undefined;
// eslint-disable-next-line svelte/prefer-svelte-reactivity -- `loadedFonts` reactivity is driven by `loadedFontsGeneration`, not the Set itself
let loadedFonts = new Set<string>();
let loadedFontsGeneration = 0;
Expand Down Expand Up @@ -77,6 +79,7 @@
});
onDestroy(() => {
removeEventListener("keydown", keydown);
resizeObserver?.disconnect();
// Set the destroyed status in the closure kept by the awaited `tick()` in `onMount` in case that delayed run occurs after the component is destroyed
destroyed = true;
});
Expand Down Expand Up @@ -144,6 +147,15 @@
keydownListenerAdded = false;
}

// For virtual scrolling menus, observe width changes so the menu only grows and never shrinks while open
if (open && virtualScrolling) {
startMenuWidthObserver();
} else if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver = undefined;
maxMenuWidth = 0;
}

highlighted = activeEntry;
dispatch("open", open);

Expand All @@ -156,14 +168,38 @@
});
}

function watchEntriesHash(_entriesHash: bigint) {
function watchEntriesHash(_: bigint) {
reactiveEntries = entries;
}

function watchRemeasureWidth(_: MenuListEntry[][], __: boolean) {
// Skip re-measurement for virtual scrolling menus since ResizeObserver handles their width
if (virtualScrolling) return;

self?.measureAndEmitNaturalWidth();
}

async function startMenuWidthObserver() {
await tick();
// Guard against the menu having closed during the tick
if (!open) return;

const floatingMenuContentDiv = self?.div()?.querySelector("[data-floating-menu-content]");
if (!(floatingMenuContentDiv instanceof HTMLElement)) return;

maxMenuWidth = 0;

resizeObserver?.disconnect();
resizeObserver = new ResizeObserver(() => {
const width = floatingMenuContentDiv.scrollWidth;
if (width > maxMenuWidth) {
maxMenuWidth = width;
floatingMenuContentDiv.style.minWidth = `${maxMenuWidth}px`;
}
});
resizeObserver.observe(floatingMenuContentDiv);
}

function onScroll(e: Event) {
if (!virtualScrollingEntryHeight) return;
virtualScrollingEntriesStart = e.target instanceof HTMLElement ? e.target.scrollTop : 0;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/layout/FloatingMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@
<div class="tail" bind:this={tail}></div>
{/if}
{#if displayContainer}
<div class="floating-menu-container" bind:this={floatingMenuContainer}>
<div class="floating-menu-container" bind:this={floatingMenuContainer} on:wheel|stopPropagation>
<LayoutCol class="floating-menu-content" styles={{ "min-width": minWidthStyleValue }} {scrollableY} bind:this={floatingMenuContent} data-floating-menu-content>
<slot />
</LayoutCol>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/utility-functions/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ export function onWheelScroll(e: WheelEvent, editor: EditorWrapper) {

// Redirect vertical scroll wheel movement into a horizontal scroll on a horizontally scrollable element
// There seems to be no possible way to properly employ the browser's smooth scrolling interpolation
const horizontalScrollableElement = e.target instanceof Element && e.target.closest("[data-scrollable-x]");
const horizontalScrollableElement = e.target instanceof Element && !e.target.closest("[data-scrollable-y]") && e.target.closest("[data-scrollable-x]");
if (horizontalScrollableElement && e.deltaY !== 0) {
horizontalScrollableElement.scrollTo(horizontalScrollableElement.scrollLeft + e.deltaY, 0);
return;
Expand Down
Loading