Fix reorder
This commit is contained in:
parent
ada3367b49
commit
42538e114a
|
@ -1,37 +1,33 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import GridScrollWrapper from "../layout/GridScrollWrapper.svelte"
|
||||
import { DefaultRowHeight, GutterWidth } from "../lib/constants"
|
||||
import { DefaultRowHeight } from "../lib/constants"
|
||||
|
||||
const {
|
||||
isReordering,
|
||||
reorder,
|
||||
visibleColumnLookupMap,
|
||||
displayColumn,
|
||||
rowHeight,
|
||||
renderedRows,
|
||||
scrollLeft,
|
||||
bodyLeft,
|
||||
} = getContext("grid")
|
||||
|
||||
$: targetColumn = $visibleColumnLookupMap[$reorder.targetColumn]
|
||||
$: console.log(targetColumn)
|
||||
$: minLeft = GutterWidth + ($displayColumn?.width || 0)
|
||||
$: left = getLeft(targetColumn, $displayColumn, $scrollLeft)
|
||||
$: insertAfter = $reorder.insertAfter
|
||||
$: left = getLeft(targetColumn, insertAfter, $scrollLeft)
|
||||
$: height = $rowHeight * $renderedRows.length + DefaultRowHeight
|
||||
$: style = `left:${left}px; height:${height}px;`
|
||||
$: visible = $isReordering && left >= minLeft
|
||||
$: visible = $isReordering && left >= $bodyLeft
|
||||
|
||||
const getLeft = (targetColumn, displayColumn, scrollLeft) => {
|
||||
const getLeft = (targetColumn, insertAfter, scrollLeft) => {
|
||||
if (!targetColumn) {
|
||||
return 0
|
||||
}
|
||||
let left = GutterWidth + (displayColumn?.width || 0) - scrollLeft
|
||||
|
||||
// If this is not the sticky column, add additional left space
|
||||
if (!targetColumn.primaryDisplay) {
|
||||
left += targetColumn.__left + targetColumn.width
|
||||
let left = targetColumn.__left - scrollLeft
|
||||
if (insertAfter) {
|
||||
left += targetColumn.width
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,41 +1,28 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import { GutterWidth } from "../lib/constants"
|
||||
|
||||
const { resize, visibleColumns, displayColumn, isReordering, scrollLeft } =
|
||||
const { resize, visibleColumns, isReordering, scrollLeft } =
|
||||
getContext("grid")
|
||||
|
||||
$: offset = GutterWidth + ($displayColumn?.width || 0)
|
||||
$: activeColumn = $resize.column
|
||||
|
||||
const getStyle = (column, offset, scrollLeft) => {
|
||||
const left = offset + column.__left + column.width - scrollLeft
|
||||
const getStyle = (column, scrollLeft) => {
|
||||
let left = column.__left + column.width
|
||||
if (!column.primaryDisplay) {
|
||||
left -= scrollLeft
|
||||
}
|
||||
return `left:${left}px;`
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
{#if !$isReordering}
|
||||
{#if $displayColumn}
|
||||
<div
|
||||
class="resize-slider"
|
||||
class:visible={activeColumn === $displayColumn.name}
|
||||
on:mousedown={e => resize.actions.startResizing($displayColumn, e)}
|
||||
on:touchstart={e => resize.actions.startResizing($displayColumn, e)}
|
||||
on:dblclick={() => resize.actions.resetSize($displayColumn)}
|
||||
style="left:{GutterWidth + $displayColumn.width}px;"
|
||||
>
|
||||
<div class="resize-indicator" />
|
||||
</div>
|
||||
{/if}
|
||||
{#each $visibleColumns as column}
|
||||
<div
|
||||
class="resize-slider"
|
||||
class:visible={activeColumn === column.name}
|
||||
class:visible={$resize.column === column.name}
|
||||
on:mousedown={e => resize.actions.startResizing(column, e)}
|
||||
on:touchstart={e => resize.actions.startResizing(column, e)}
|
||||
on:dblclick={() => resize.actions.resetSize(column)}
|
||||
style={getStyle(column, offset, $scrollLeft)}
|
||||
style={getStyle(column, $scrollLeft)}
|
||||
>
|
||||
<div class="resize-indicator" />
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { derived, get, writable } from "svelte/store"
|
||||
import { DefaultColumnWidth } from "../lib/constants"
|
||||
import { DefaultColumnWidth, GutterWidth } from "../lib/constants"
|
||||
|
||||
export const createStores = () => {
|
||||
const columns = writable([])
|
||||
|
@ -39,16 +39,16 @@ export const deriveStores = context => {
|
|||
// Derived list of columns which have not been explicitly hidden, and enrich
|
||||
// with an index so we can easily select nearby columns
|
||||
const visibleColumns = derived(columns, $columns => {
|
||||
let offset = 0
|
||||
let offset = GutterWidth
|
||||
return $columns
|
||||
.filter(col => col.visible)
|
||||
.map((column, idx) => {
|
||||
.map((col, idx) => {
|
||||
const enriched = {
|
||||
...column,
|
||||
...col,
|
||||
__left: offset,
|
||||
__idx: idx,
|
||||
}
|
||||
offset += column.width
|
||||
offset += col.width
|
||||
return enriched
|
||||
})
|
||||
})
|
||||
|
|
|
@ -4,10 +4,10 @@ import { parseEventLocation } from "../lib/utils"
|
|||
const reorderInitialState = {
|
||||
sourceColumn: null,
|
||||
targetColumn: null,
|
||||
insertAfter: false,
|
||||
breakpoints: [],
|
||||
gridLeft: 0,
|
||||
width: 0,
|
||||
latestX: 0,
|
||||
increment: 0,
|
||||
}
|
||||
|
||||
|
@ -35,10 +35,11 @@ export const createActions = context => {
|
|||
bounds,
|
||||
visibleColumns,
|
||||
maxScrollLeft,
|
||||
width,
|
||||
datasource,
|
||||
bodyLeft,
|
||||
width,
|
||||
} = context
|
||||
|
||||
let latestX = 0
|
||||
let autoScrollInterval
|
||||
let isAutoScrolling
|
||||
|
||||
|
@ -46,13 +47,25 @@ export const createActions = context => {
|
|||
const startReordering = (column, e) => {
|
||||
const $scrollableColumns = get(scrollableColumns)
|
||||
const $bounds = get(bounds)
|
||||
const $bodyLeft = get(bodyLeft)
|
||||
|
||||
// Generate new breakpoints for the current columns
|
||||
const breakpoints = $scrollableColumns.map(col => ({
|
||||
x: col.__left + col.width,
|
||||
x: col.__left - $bodyLeft,
|
||||
column: col.name,
|
||||
insertAfter: false,
|
||||
}))
|
||||
|
||||
// Add a very left breakpoint as well
|
||||
const lastCol = $scrollableColumns[$scrollableColumns.length - 1]
|
||||
if (lastCol) {
|
||||
breakpoints.push({
|
||||
x: lastCol.__left + lastCol.width - $bodyLeft,
|
||||
column: lastCol.name,
|
||||
insertAfter: true,
|
||||
})
|
||||
}
|
||||
|
||||
// Update state
|
||||
reorder.set({
|
||||
sourceColumn: column,
|
||||
|
@ -77,10 +90,7 @@ export const createActions = context => {
|
|||
const onReorderMouseMove = e => {
|
||||
// Immediately handle the current position
|
||||
const { x } = parseEventLocation(e)
|
||||
reorder.update(state => ({
|
||||
...state,
|
||||
latestX: x,
|
||||
}))
|
||||
latestX = x
|
||||
considerReorderPosition()
|
||||
|
||||
// Check if we need to start auto-scrolling
|
||||
|
@ -110,20 +120,25 @@ export const createActions = context => {
|
|||
const $scroll = get(scroll)
|
||||
|
||||
// Compute the closest breakpoint to the current position
|
||||
let targetColumn
|
||||
let breakpoint
|
||||
let minDistance = Number.MAX_SAFE_INTEGER
|
||||
const mouseX = $reorder.latestX - $reorder.gridLeft + $scroll.left
|
||||
const mouseX = latestX - $reorder.gridLeft + $scroll.left
|
||||
$reorder.breakpoints.forEach(point => {
|
||||
const distance = Math.abs(point.x - mouseX)
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance
|
||||
targetColumn = point.column
|
||||
breakpoint = point
|
||||
}
|
||||
})
|
||||
if (targetColumn !== $reorder.targetColumn) {
|
||||
if (
|
||||
breakpoint &&
|
||||
(breakpoint.column !== $reorder.targetColumn ||
|
||||
breakpoint.insertAfter !== $reorder.insertAfter)
|
||||
) {
|
||||
reorder.update(state => ({
|
||||
...state,
|
||||
targetColumn,
|
||||
targetColumn: breakpoint.column,
|
||||
insertAfter: breakpoint.insertAfter,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,44 +32,40 @@ export const deriveStores = context => {
|
|||
} = context
|
||||
|
||||
// Memoize store primitives
|
||||
const stickyColumnWidth = derived(displayColumn, $col => $col?.width || 0, 0)
|
||||
const bodyLeft = derived(displayColumn, $displayColumn => {
|
||||
return ($displayColumn?.width || 0) + GutterWidth
|
||||
})
|
||||
|
||||
// Derive vertical limits
|
||||
const contentHeight = derived(
|
||||
[rows, rowHeight],
|
||||
([$rows, $rowHeight]) => ($rows.length + 1) * $rowHeight + Padding,
|
||||
0
|
||||
([$rows, $rowHeight]) => ($rows.length + 1) * $rowHeight + Padding
|
||||
)
|
||||
const maxScrollTop = derived(
|
||||
[height, contentHeight],
|
||||
([$height, $contentHeight]) => Math.max($contentHeight - $height, 0),
|
||||
0
|
||||
([$height, $contentHeight]) => Math.max($contentHeight - $height, 0)
|
||||
)
|
||||
|
||||
// Derive horizontal limits
|
||||
const contentWidth = derived(
|
||||
[visibleColumns, stickyColumnWidth, buttonColumnWidth],
|
||||
([$visibleColumns, $stickyColumnWidth, $buttonColumnWidth]) => {
|
||||
[visibleColumns, buttonColumnWidth],
|
||||
([$visibleColumns, $buttonColumnWidth]) => {
|
||||
const space = Math.max(Padding, $buttonColumnWidth - 1)
|
||||
let width = GutterWidth + space + $stickyColumnWidth
|
||||
let width = GutterWidth + space
|
||||
$visibleColumns.forEach(col => {
|
||||
width += col.width
|
||||
})
|
||||
return width
|
||||
},
|
||||
0
|
||||
)
|
||||
const screenWidth = derived(
|
||||
[width, stickyColumnWidth],
|
||||
([$width, $stickyColumnWidth]) => $width + GutterWidth + $stickyColumnWidth,
|
||||
0
|
||||
}
|
||||
)
|
||||
const screenWidth = derived([width, bodyLeft], ([$width, $bodyLeft]) => {
|
||||
return $width + $bodyLeft
|
||||
})
|
||||
const maxScrollLeft = derived(
|
||||
[contentWidth, screenWidth],
|
||||
([$contentWidth, $screenWidth]) => {
|
||||
return Math.max($contentWidth - $screenWidth, 0)
|
||||
},
|
||||
0
|
||||
}
|
||||
)
|
||||
|
||||
// Derive whether to show scrollbars or not
|
||||
|
@ -87,6 +83,7 @@ export const deriveStores = context => {
|
|||
)
|
||||
|
||||
return {
|
||||
bodyLeft,
|
||||
contentHeight,
|
||||
contentWidth,
|
||||
screenWidth,
|
||||
|
|
Loading…
Reference in New Issue