1
0
Fork 0
mirror of synced 2024-09-08 05:31:47 +12:00

Ensure the selected cell is always visible

This commit is contained in:
Andrew Kingston 2023-03-13 19:45:03 +00:00
parent d4a2bcae4f
commit f2cf174557
5 changed files with 86 additions and 5 deletions

View file

@ -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) }

View file

@ -27,7 +27,7 @@
<div
class="row"
on:focus
on:mouseover={() => ($hoveredRowId = row._id)}
on:mouseenter={() => ($hoveredRowId = row._id)}
on:mouseleave={() => ($hoveredRowId = null)}
>
{#each $renderedColumns as column (column.name)}

View file

@ -85,7 +85,7 @@
{@const containsSelectedRow = $selectedCellRow?._id === row._id}
<div
class="row"
on:mouseover={() => ($hoveredRowId = row._id)}
on:mouseenter={() => ($hoveredRowId = row._id)}
on:mouseleave={() => ($hoveredRowId = null)}
>
<SheetCell

View file

@ -1,8 +1,18 @@
import { derived, get } from "svelte/store"
export const createMaxScrollStores = context => {
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,

View file

@ -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,