Improve and simplify scrolling
This commit is contained in:
parent
42538e114a
commit
e05c46435f
|
@ -6,14 +6,14 @@
|
||||||
const {
|
const {
|
||||||
isReordering,
|
isReordering,
|
||||||
reorder,
|
reorder,
|
||||||
visibleColumnLookupMap,
|
columnLookupMap,
|
||||||
rowHeight,
|
rowHeight,
|
||||||
renderedRows,
|
renderedRows,
|
||||||
scrollLeft,
|
scrollLeft,
|
||||||
bodyLeft,
|
bodyLeft,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
$: targetColumn = $visibleColumnLookupMap[$reorder.targetColumn]
|
$: targetColumn = $columnLookupMap[$reorder.targetColumn]
|
||||||
$: insertAfter = $reorder.insertAfter
|
$: insertAfter = $reorder.insertAfter
|
||||||
$: left = getLeft(targetColumn, insertAfter, $scrollLeft)
|
$: left = getLeft(targetColumn, insertAfter, $scrollLeft)
|
||||||
$: height = $rowHeight * $renderedRows.length + DefaultRowHeight
|
$: height = $rowHeight * $renderedRows.length + DefaultRowHeight
|
||||||
|
@ -21,6 +21,7 @@
|
||||||
$: visible = $isReordering && left >= $bodyLeft
|
$: visible = $isReordering && left >= $bodyLeft
|
||||||
|
|
||||||
const getLeft = (targetColumn, insertAfter, scrollLeft) => {
|
const getLeft = (targetColumn, insertAfter, scrollLeft) => {
|
||||||
|
console.log(targetColumn)
|
||||||
if (!targetColumn) {
|
if (!targetColumn) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ export const createActions = context => {
|
||||||
rowChangeCache,
|
rowChangeCache,
|
||||||
rows,
|
rows,
|
||||||
focusedCellId,
|
focusedCellId,
|
||||||
visibleColumnLookupMap,
|
columnLookupMap,
|
||||||
allVisibleColumns,
|
allVisibleColumns,
|
||||||
} = context
|
} = context
|
||||||
|
|
||||||
|
@ -156,9 +156,9 @@ export const createActions = context => {
|
||||||
const $focusedCellId = get(focusedCellId)
|
const $focusedCellId = get(focusedCellId)
|
||||||
const { rowId, field } = parseCellID($focusedCellId)
|
const { rowId, field } = parseCellID($focusedCellId)
|
||||||
const $rowLookupMap = get(rowLookupMap)
|
const $rowLookupMap = get(rowLookupMap)
|
||||||
const $visibleColumnLookupMap = get(visibleColumnLookupMap)
|
const $columnLookupMap = get(columnLookupMap)
|
||||||
const rowIdx = $rowLookupMap[rowId].__idx
|
const rowIdx = $rowLookupMap[rowId].__idx
|
||||||
const colIdx = $visibleColumnLookupMap[field].__idx
|
const colIdx = $columnLookupMap[field].__idx
|
||||||
|
|
||||||
// Get limits of how many rows and columns we're able to paste into
|
// Get limits of how many rows and columns we're able to paste into
|
||||||
const $rows = get(rows)
|
const $rows = get(rows)
|
||||||
|
|
|
@ -5,10 +5,21 @@ export const createStores = () => {
|
||||||
const columns = writable([])
|
const columns = writable([])
|
||||||
|
|
||||||
const enrichedColumns = derived(columns, $columns => {
|
const enrichedColumns = derived(columns, $columns => {
|
||||||
return $columns.map((col, idx) => ({
|
let offset = GutterWidth
|
||||||
|
let visibleIdx = 0
|
||||||
|
return $columns.map((col, idx) => {
|
||||||
|
const enriched = {
|
||||||
...col,
|
...col,
|
||||||
__idx: idx,
|
__idx: idx, // Overall column index
|
||||||
}))
|
__visibleIdx: visibleIdx, // Index within the visible columns
|
||||||
|
__left: offset, // Left offset relative to all visible columns
|
||||||
|
}
|
||||||
|
if (col.visible) {
|
||||||
|
visibleIdx++
|
||||||
|
offset += col.width
|
||||||
|
}
|
||||||
|
return enriched
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -22,11 +33,6 @@ export const createStores = () => {
|
||||||
export const deriveStores = context => {
|
export const deriveStores = context => {
|
||||||
const { columns } = context
|
const { columns } = context
|
||||||
|
|
||||||
// Derive the primary display column
|
|
||||||
const displayColumn = derived(columns, $columns => {
|
|
||||||
return $columns.find(col => col.primaryDisplay)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Derive a lookup map for all columns by name
|
// Derive a lookup map for all columns by name
|
||||||
const columnLookupMap = derived(columns, $columns => {
|
const columnLookupMap = derived(columns, $columns => {
|
||||||
let map = {}
|
let map = {}
|
||||||
|
@ -36,33 +42,15 @@ export const deriveStores = context => {
|
||||||
return map
|
return map
|
||||||
})
|
})
|
||||||
|
|
||||||
// Derived list of columns which have not been explicitly hidden, and enrich
|
// Derived list of columns which have not been explicitly hidden
|
||||||
// with an index so we can easily select nearby columns
|
|
||||||
const visibleColumns = derived(columns, $columns => {
|
const visibleColumns = derived(columns, $columns => {
|
||||||
let offset = GutterWidth
|
return $columns.filter(col => col.visible)
|
||||||
return $columns
|
|
||||||
.filter(col => col.visible)
|
|
||||||
.map((col, idx) => {
|
|
||||||
const enriched = {
|
|
||||||
...col,
|
|
||||||
__left: offset,
|
|
||||||
__idx: idx,
|
|
||||||
}
|
|
||||||
offset += col.width
|
|
||||||
return enriched
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Derive a lookup map for visible columns by name
|
// Split visible columns into their discrete types
|
||||||
const visibleColumnLookupMap = derived(visibleColumns, $visibleColumns => {
|
const displayColumn = derived(visibleColumns, $visibleColumns => {
|
||||||
let map = {}
|
return $visibleColumns.find(col => col.primaryDisplay)
|
||||||
$visibleColumns.forEach(column => {
|
|
||||||
map[column.name] = column
|
|
||||||
})
|
})
|
||||||
return map
|
|
||||||
})
|
|
||||||
|
|
||||||
// Derive scrollable columns
|
|
||||||
const scrollableColumns = derived(visibleColumns, $visibleColumns => {
|
const scrollableColumns = derived(visibleColumns, $visibleColumns => {
|
||||||
return $visibleColumns.filter(col => !col.primaryDisplay)
|
return $visibleColumns.filter(col => !col.primaryDisplay)
|
||||||
})
|
})
|
||||||
|
@ -79,7 +67,6 @@ export const deriveStores = context => {
|
||||||
displayColumn,
|
displayColumn,
|
||||||
columnLookupMap,
|
columnLookupMap,
|
||||||
visibleColumns,
|
visibleColumns,
|
||||||
visibleColumnLookupMap,
|
|
||||||
scrollableColumns,
|
scrollableColumns,
|
||||||
hasNonAutoColumn,
|
hasNonAutoColumn,
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,14 +30,14 @@ export const createActions = context => {
|
||||||
columns,
|
columns,
|
||||||
columnLookupMap,
|
columnLookupMap,
|
||||||
scrollableColumns,
|
scrollableColumns,
|
||||||
visibleColumnLookupMap,
|
|
||||||
scroll,
|
scroll,
|
||||||
bounds,
|
bounds,
|
||||||
visibleColumns,
|
visibleColumns,
|
||||||
maxScrollLeft,
|
|
||||||
datasource,
|
datasource,
|
||||||
bodyLeft,
|
bodyLeft,
|
||||||
width,
|
width,
|
||||||
|
scrollLeft,
|
||||||
|
maxScrollLeft,
|
||||||
} = context
|
} = context
|
||||||
let latestX = 0
|
let latestX = 0
|
||||||
let autoScrollInterval
|
let autoScrollInterval
|
||||||
|
@ -94,17 +94,19 @@ export const createActions = context => {
|
||||||
considerReorderPosition()
|
considerReorderPosition()
|
||||||
|
|
||||||
// Check if we need to start auto-scrolling
|
// Check if we need to start auto-scrolling
|
||||||
|
const $scrollLeft = get(scrollLeft)
|
||||||
|
const $maxScrollLeft = get(maxScrollLeft)
|
||||||
const $reorder = get(reorder)
|
const $reorder = get(reorder)
|
||||||
const proximityCutoff = Math.min(140, get(width) / 6)
|
const proximityCutoff = Math.min(140, get(width) / 6)
|
||||||
const speedFactor = 16
|
const speedFactor = 16
|
||||||
const rightProximity = Math.max(0, $reorder.gridLeft + $reorder.width - x)
|
const rightProximity = Math.max(0, $reorder.gridLeft + $reorder.width - x)
|
||||||
const leftProximity = Math.max(0, x - $reorder.gridLeft)
|
const leftProximity = Math.max(0, x - $reorder.gridLeft)
|
||||||
if (rightProximity < proximityCutoff) {
|
if (rightProximity < proximityCutoff && $scrollLeft < $maxScrollLeft) {
|
||||||
const weight = proximityCutoff - rightProximity
|
const weight = proximityCutoff - rightProximity
|
||||||
const increment = (weight / proximityCutoff) * speedFactor
|
const increment = (weight / proximityCutoff) * speedFactor
|
||||||
reorder.update(state => ({ ...state, increment }))
|
reorder.update(state => ({ ...state, increment }))
|
||||||
startAutoScroll()
|
startAutoScroll()
|
||||||
} else if (leftProximity < proximityCutoff) {
|
} else if (leftProximity < proximityCutoff && $scrollLeft > 0) {
|
||||||
const weight = -1 * (proximityCutoff - leftProximity)
|
const weight = -1 * (proximityCutoff - leftProximity)
|
||||||
const increment = (weight / proximityCutoff) * speedFactor
|
const increment = (weight / proximityCutoff) * speedFactor
|
||||||
reorder.update(state => ({ ...state, increment }))
|
reorder.update(state => ({ ...state, increment }))
|
||||||
|
@ -180,20 +182,26 @@ export const createActions = context => {
|
||||||
document.removeEventListener("touchcancel", stopReordering)
|
document.removeEventListener("touchcancel", stopReordering)
|
||||||
|
|
||||||
// Ensure there's actually a change before saving
|
// Ensure there's actually a change before saving
|
||||||
const { sourceColumn, targetColumn } = get(reorder)
|
const { sourceColumn, targetColumn, insertAfter } = get(reorder)
|
||||||
reorder.set(reorderInitialState)
|
reorder.set(reorderInitialState)
|
||||||
if (sourceColumn !== targetColumn) {
|
if (sourceColumn !== targetColumn) {
|
||||||
await moveColumn(sourceColumn, targetColumn)
|
await moveColumn({ sourceColumn, targetColumn, insertAfter })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves a column after another columns.
|
// Moves a column after another columns.
|
||||||
// An undefined target column will move the source to index 0.
|
// An undefined target column will move the source to index 0.
|
||||||
const moveColumn = async (sourceColumn, targetColumn) => {
|
const moveColumn = async ({
|
||||||
|
sourceColumn,
|
||||||
|
targetColumn,
|
||||||
|
insertAfter = false,
|
||||||
|
}) => {
|
||||||
const $columnLookupMap = get(columnLookupMap)
|
const $columnLookupMap = get(columnLookupMap)
|
||||||
let sourceIdx = $columnLookupMap[sourceColumn]
|
let sourceIdx = $columnLookupMap[sourceColumn].__idx
|
||||||
let targetIdx = $columnLookupMap[targetColumn]
|
let targetIdx = $columnLookupMap[targetColumn].__idx
|
||||||
|
if (insertAfter) {
|
||||||
targetIdx++
|
targetIdx++
|
||||||
|
}
|
||||||
columns.update(state => {
|
columns.update(state => {
|
||||||
const removed = state.splice(sourceIdx, 1)
|
const removed = state.splice(sourceIdx, 1)
|
||||||
if (--targetIdx < sourceIdx) {
|
if (--targetIdx < sourceIdx) {
|
||||||
|
@ -214,20 +222,26 @@ export const createActions = context => {
|
||||||
// Moves a column one place left (as appears visually)
|
// Moves a column one place left (as appears visually)
|
||||||
const moveColumnLeft = async column => {
|
const moveColumnLeft = async column => {
|
||||||
const $visibleColumns = get(visibleColumns)
|
const $visibleColumns = get(visibleColumns)
|
||||||
const $visibleColumnLookupMap = get(visibleColumnLookupMap)
|
const $columnLookupMap = get(columnLookupMap)
|
||||||
const sourceIdx = $visibleColumnLookupMap[column]
|
const sourceIdx = $columnLookupMap[column]
|
||||||
await moveColumn(column, $visibleColumns[sourceIdx - 2]?.name)
|
await moveColumn({
|
||||||
|
sourceColumn: column,
|
||||||
|
targetColumn: $visibleColumns[sourceIdx - 2]?.name,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves a column one place right (as appears visually)
|
// Moves a column one place right (as appears visually)
|
||||||
const moveColumnRight = async column => {
|
const moveColumnRight = async column => {
|
||||||
const $visibleColumns = get(visibleColumns)
|
const $visibleColumns = get(visibleColumns)
|
||||||
const $visibleColumnLookupMap = get(visibleColumnLookupMap)
|
const $columnLookupMap = get(columnLookupMap)
|
||||||
const sourceIdx = $visibleColumnLookupMap[column]
|
const sourceIdx = $columnLookupMap[column]
|
||||||
if (sourceIdx === $visibleColumns.length - 1) {
|
if (sourceIdx === $visibleColumns.length - 1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await moveColumn(column, $visibleColumns[sourceIdx + 1]?.name)
|
await moveColumn({
|
||||||
|
sourceColumn: column,
|
||||||
|
targetColumn: $visibleColumns[sourceIdx + 1]?.name,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Reference in New Issue