From f2cf17455758f43d55dc56da65d4c766e36e95b0 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 13 Mar 2023 19:45:03 +0000 Subject: [PATCH] Ensure the selected cell is always visible --- .../src/components/sheet/Sheet.svelte | 2 +- .../src/components/sheet/SheetRow.svelte | 2 +- .../src/components/sheet/StickyColumn.svelte | 2 +- .../src/components/sheet/stores/max-scroll.js | 78 ++++++++++++++++++- .../src/components/sheet/stores/ui.js | 7 ++ 5 files changed, 86 insertions(+), 5 deletions(-) diff --git a/packages/frontend-core/src/components/sheet/Sheet.svelte b/packages/frontend-core/src/components/sheet/Sheet.svelte index 40d7e578d6..e68771b54a 100644 --- a/packages/frontend-core/src/components/sheet/Sheet.svelte +++ b/packages/frontend-core/src/components/sheet/Sheet.svelte @@ -63,10 +63,10 @@ context = { ...context, ...createScrollStores(context) } context = { ...context, ...createRowsStore(context) } context = { ...context, ...createColumnsStores(context) } - context = { ...context, ...createMaxScrollStores(context) } context = { ...context, ...createUIStores(context) } context = { ...context, ...createResizeStores(context) } context = { ...context, ...createViewportStores(context) } + context = { ...context, ...createMaxScrollStores(context) } context = { ...context, ...createReorderStores(context) } context = { ...context, ...createUserStores(context) } context = { ...context, ...createMenuStores(context) } diff --git a/packages/frontend-core/src/components/sheet/SheetRow.svelte b/packages/frontend-core/src/components/sheet/SheetRow.svelte index 3a71c64d01..aa0b7752d9 100644 --- a/packages/frontend-core/src/components/sheet/SheetRow.svelte +++ b/packages/frontend-core/src/components/sheet/SheetRow.svelte @@ -27,7 +27,7 @@
($hoveredRowId = row._id)} + on:mouseenter={() => ($hoveredRowId = row._id)} on:mouseleave={() => ($hoveredRowId = null)} > {#each $renderedColumns as column (column.name)} diff --git a/packages/frontend-core/src/components/sheet/StickyColumn.svelte b/packages/frontend-core/src/components/sheet/StickyColumn.svelte index 3a6d6ed432..4686a50cba 100644 --- a/packages/frontend-core/src/components/sheet/StickyColumn.svelte +++ b/packages/frontend-core/src/components/sheet/StickyColumn.svelte @@ -85,7 +85,7 @@ {@const containsSelectedRow = $selectedCellRow?._id === row._id}
($hoveredRowId = row._id)} + on:mouseenter={() => ($hoveredRowId = row._id)} on:mouseleave={() => ($hoveredRowId = null)} > { - const { rows, visibleColumns, stickyColumn, bounds, cellHeight, scroll } = - context + const { + rows, + visibleColumns, + stickyColumn, + bounds, + cellHeight, + scroll, + selectedCellRow, + scrolledRowCount, + visualRowCapacity, + selectedCellId, + } = context const padding = 180 // Memoize store primitives @@ -77,6 +87,70 @@ export const createMaxScrollStores = context => { } }) + // Ensure the selected cell is visible + selectedCellRow.subscribe(row => { + if (!row) { + return + } + const $scroll = get(scroll) + const $bounds = get(bounds) + const scrollBarOffset = 16 + + // Ensure row is not below bottom of screen + const rowYPos = row.__idx * cellHeight + const bottomCutoff = + $scroll.top + $bounds.height - cellHeight - scrollBarOffset + let delta = rowYPos - bottomCutoff + if (delta > 0) { + scroll.update(state => ({ + ...state, + top: state.top + delta, + })) + } + + // Ensure row is not above top of screen + else { + delta = $scroll.top - rowYPos + if (delta > 0) { + scroll.update(state => ({ + ...state, + top: Math.max(0, state.top - delta), + })) + } + } + + // Check horizontal position of columns next + const $selectedCellId = get(selectedCellId) + const $visibleColumns = get(visibleColumns) + const columnName = $selectedCellId?.split("-")[1] + const column = $visibleColumns.find(col => col.name === columnName) + if (!column) { + return + } + + // Ensure column is not cutoff on left edge + delta = $scroll.left - column.left + if (delta > 0) { + scroll.update(state => ({ + ...state, + left: state.left - delta, + })) + } + + // Ensure column is not cutoff on right edge + else { + const rightEdge = column.left + column.width + const rightBound = $bounds.width + $scroll.left + delta = rightEdge - rightBound + if (delta > 0) { + scroll.update(state => ({ + ...state, + left: state.left + delta + scrollBarOffset, + })) + } + } + }) + return { contentHeight, contentWidth, diff --git a/packages/frontend-core/src/components/sheet/stores/ui.js b/packages/frontend-core/src/components/sheet/stores/ui.js index cf6f6ee4c3..427a6be694 100644 --- a/packages/frontend-core/src/components/sheet/stores/ui.js +++ b/packages/frontend-core/src/components/sheet/stores/ui.js @@ -79,6 +79,13 @@ export const createUIStores = context => { } }) + // Remove hovered row when a cell is selected + selectedCellId.subscribe(cell => { + if (cell && get(hoveredRowId)) { + hoveredRowId.set(null) + } + }) + return { selectedCellId, selectedRows,