Fix scroll not working in new row

This commit is contained in:
Andrew Kingston 2023-04-01 10:50:42 +01:00
parent a50e9ccbc7
commit 5ab0652c87
5 changed files with 76 additions and 101 deletions

View File

@ -70,11 +70,7 @@
<Button size="M" cta icon="Add" on:click={startAdding}>Add row</Button>
</div>
<div
class="container"
class:visible={isAdding}
on:wheel={wheel.actions.handleWheel}
>
<div class="container" class:visible={isAdding}>
<div class="buttons">
<Button size="M" cta on:click={addRow}>Save</Button>
<Button size="M" secondary newStyles on:click={cancel}>Cancel</Button>

View File

@ -72,53 +72,52 @@
<!-- Only show new row functionality if we have any columns -->
{#if firstColumn}
<div
class="container"
class:visible={isAdding}
on:wheel={wheel.actions.handleWheel}
>
<div class="container" class:visible={isAdding}>
<div class="content" class:above-scrollbar={$showHScrollbar}>
<div
class="new-row"
on:mouseenter={() => ($hoveredRowId = "new")}
on:mouseleave={() => ($hoveredRowId = null)}
>
<div
class="sticky-column"
style="flex: 0 0 {width}px"
class:scrolled={scrollLeft > 0}
>
<SheetCell
width={gutterWidth}
{rowHovered}
rowSelected={containsSelectedCell}
<SheetScrollWrapper scrollHorizontally={false} scrollVertically={false}>
<div
class="sticky-column"
style="flex: 0 0 {width}px"
class:scrolled={scrollLeft > 0}
>
<div class="gutter">
<div class="number">1</div>
{#if $config.allowExpandRows}
<Icon
name="Maximize"
size="S"
hoverable
on:click={addViaModal}
/>
{/if}
</div>
</SheetCell>
{#if $stickyColumn}
{@const cellId = `new-${$stickyColumn.name}`}
<DataCell
{cellId}
column={$stickyColumn}
row={newRow}
<SheetCell
width={gutterWidth}
{rowHovered}
selected={$selectedCellId === cellId}
rowSelected={containsSelectedCell}
width={$stickyColumn.width}
{updateRow}
/>
{/if}
</div>
>
<div class="gutter">
<div class="number">1</div>
{#if $config.allowExpandRows}
<Icon
name="Maximize"
size="S"
hoverable
on:click={addViaModal}
/>
{/if}
</div>
</SheetCell>
{#if $stickyColumn}
{@const cellId = `new-${$stickyColumn.name}`}
<DataCell
{cellId}
column={$stickyColumn}
row={newRow}
{rowHovered}
selected={$selectedCellId === cellId}
rowSelected={containsSelectedCell}
width={$stickyColumn.width}
{updateRow}
/>
{/if}
</div>
</SheetScrollWrapper>
<SheetScrollWrapper scrollVertically={false}>
<div class="row">
{#each $renderedColumns as column}

View File

@ -15,7 +15,6 @@
import { createMenuStores } from "../stores/menu"
import { createMaxScrollStores } from "../stores/max-scroll"
import { createPaginationStores } from "../stores/pagination"
import { createWheelStores } from "../stores/wheel"
import DeleteButton from "../controls/DeleteButton.svelte"
import SheetBody from "./SheetBody.svelte"
import ResizeOverlay from "../overlays/ResizeOverlay.svelte"
@ -76,7 +75,6 @@
context = { ...context, ...createUserStores(context) }
context = { ...context, ...createMenuStores(context) }
context = { ...context, ...createPaginationStores(context) }
context = { ...context, ...createWheelStores(context) }
// Reference some stores for local use
const { isResizing, isReordering, ui, loaded, rowHeight } = context

View File

@ -1,5 +1,6 @@
<script>
import { getContext } from "svelte"
import { domDebounce } from "../../../utils/utils"
const {
rowHeight,
@ -7,7 +8,11 @@
visibleColumns,
renderedColumns,
selectedCellId,
wheel,
renderedRows,
maxScrollTop,
maxScrollLeft,
bounds,
hoveredRowId,
} = getContext("sheet")
export let scrollVertically = true
@ -36,11 +41,42 @@
}
return width
}
// Handles a wheel even and updates the scroll offsets
const handleWheel = e => {
e.preventDefault()
const modifier = e.ctrlKey || e.metaKey
let x = modifier ? e.deltaY : e.deltaX
let y = modifier ? e.deltaX : e.deltaY
debouncedHandleWheel(x, y, e.clientY)
}
const debouncedHandleWheel = domDebounce((deltaX, deltaY, clientY) => {
const { top, left } = $scroll
// Calculate new scroll top
let newScrollTop = top + deltaY
newScrollTop = Math.max(0, Math.min(newScrollTop, $maxScrollTop))
// Calculate new scroll left
let newScrollLeft = left + deltaX
newScrollLeft = Math.max(0, Math.min(newScrollLeft, $maxScrollLeft))
// Update state
scroll.set({
left: newScrollLeft,
top: newScrollTop,
})
// Hover row under cursor
const y = clientY - $bounds.top + (newScrollTop % $rowHeight)
const hoveredRow = $renderedRows[Math.floor(y / $rowHeight)]
hoveredRowId.set(hoveredRow?._id)
})
</script>
<div
class="outer"
on:wheel={wheelInteractive ? wheel.actions.handleWheel : null}
on:wheel={wheelInteractive ? handleWheel : null}
on:click|self={() => ($selectedCellId = null)}
>
<div {style}>

View File

@ -1,54 +0,0 @@
import { get } from "svelte/store"
import { domDebounce } from "../../../utils/utils"
export const createWheelStores = context => {
const {
maxScrollLeft,
maxScrollTop,
hoveredRowId,
renderedRows,
bounds,
scroll,
rowHeight,
} = context
// Handles a wheel even and updates the scroll offsets
const handleWheel = e => {
e.preventDefault()
const modifier = e.ctrlKey || e.metaKey
let x = modifier ? e.deltaY : e.deltaX
let y = modifier ? e.deltaX : e.deltaY
debouncedHandleWheel(x, y, e.clientY)
}
const debouncedHandleWheel = domDebounce((deltaX, deltaY, clientY) => {
const { top, left } = get(scroll)
const $rowHeight = get(rowHeight)
// Calculate new scroll top
let newScrollTop = top + deltaY
newScrollTop = Math.max(0, Math.min(newScrollTop, get(maxScrollTop)))
// Calculate new scroll left
let newScrollLeft = left + deltaX
newScrollLeft = Math.max(0, Math.min(newScrollLeft, get(maxScrollLeft)))
// Update state
scroll.set({
left: newScrollLeft,
top: newScrollTop,
})
// Hover row under cursor
const y = clientY - get(bounds).top + (newScrollTop % $rowHeight)
const hoveredRow = get(renderedRows)[Math.floor(y / $rowHeight)]
hoveredRowId.set(hoveredRow?._id)
})
return {
wheel: {
actions: {
handleWheel,
},
},
}
}