Allow reordering columns to be the first column after sticky column

This commit is contained in:
Andrew Kingston 2023-03-01 19:34:26 +00:00
parent c7b8d78c98
commit 36f7d24d42
6 changed files with 43 additions and 30 deletions

View File

@ -14,9 +14,9 @@
{#each $visibleColumns as column} {#each $visibleColumns as column}
<SheetCell <SheetCell
header header
reorderSource={$reorder.columnIdx === column.idx} reorderSource={$reorder.sourceColumn === column.name}
reorderTarget={$reorder.swapColumnIdx === column.idx} reorderTarget={$reorder.targetColumn === column.name}
on:mousedown={e => reorder.actions.startReordering(column.idx, e)} on:mousedown={e => reorder.actions.startReordering(column.name, e)}
width={column.width} width={column.width}
left={column.left} left={column.left}
> >

View File

@ -22,8 +22,8 @@
on:click={() => addRow(column)} on:click={() => addRow(column)}
width={column.width} width={column.width}
left={column.left} left={column.left}
reorderSource={$reorder.columnIdx === column.idx} reorderSource={$reorder.sourceColumn === column.name}
reorderTarget={$reorder.swapColumnIdx === column.idx} reorderTarget={$reorder.targetColumn === column.name}
/> />
{/each} {/each}
</div> </div>

View File

@ -25,8 +25,8 @@
{rowSelected} {rowSelected}
{rowHovered} {rowHovered}
selected={$selectedCellId === cellIdx} selected={$selectedCellId === cellIdx}
reorderSource={$reorder.columnIdx === column.idx} reorderSource={$reorder.sourceColumn === column.name}
reorderTarget={$reorder.swapColumnIdx === column.idx} reorderTarget={$reorder.targetColumn === column.name}
on:click={() => ($selectedCellId = cellIdx)} on:click={() => ($selectedCellId = cellIdx)}
width={column.width} width={column.width}
left={column.left} left={column.left}

View File

@ -89,7 +89,6 @@
<style> <style>
div { div {
overflow: hidden;
min-width: 100%; min-width: 100%;
min-height: 100%; min-height: 100%;
} }

View File

@ -14,6 +14,7 @@
selectedCellId, selectedCellId,
hoveredRowId, hoveredRowId,
scroll, scroll,
reorder,
} = getContext("spreadsheet") } = getContext("spreadsheet")
$: scrollLeft = $scroll.left $: scrollLeft = $scroll.left
@ -66,6 +67,7 @@
sticky sticky
width={$stickyColumn.width} width={$stickyColumn.width}
left={$stickyColumn.left} left={$stickyColumn.left}
reorderTarget={$reorder.targetColumn === $stickyColumn.name}
> >
<Icon <Icon
size="S" size="S"
@ -110,6 +112,7 @@
on:click={() => ($selectedCellId = cellIdx)} on:click={() => ($selectedCellId = cellIdx)}
width={$stickyColumn.width} width={$stickyColumn.width}
left="40" left="40"
reorderTarget={$reorder.targetColumn === $stickyColumn.name}
> >
<svelte:component <svelte:component
this={getCellRenderer($stickyColumn)} this={getCellRenderer($stickyColumn)}
@ -139,6 +142,7 @@
on:click={addRow} on:click={addRow}
width={$stickyColumn.width} width={$stickyColumn.width}
rowHovered={$hoveredRowId === "new"} rowHovered={$hoveredRowId === "new"}
reorderTarget={$reorder.targetColumn === $stickyColumn.name}
/> />
{/if} {/if}
</div> </div>

View File

@ -1,29 +1,39 @@
import { get, writable } from "svelte/store" import { get, writable } from "svelte/store"
export const createReorderStores = context => { export const createReorderStores = context => {
const { columns, rand, scroll, bounds } = context const { columns, rand, scroll, bounds, stickyColumn } = context
const reorderInitialState = { const reorderInitialState = {
columnIdx: null, sourceColumn: null,
swapColumnIdx: null, targetColumn: null,
breakpoints: [], breakpoints: [],
initialMouseX: null, initialMouseX: null,
} }
const reorder = writable(reorderInitialState) const reorder = writable(reorderInitialState)
// Callback when dragging on a colum header and starting reordering // Callback when dragging on a colum header and starting reordering
const startReordering = (columnIdx, e) => { const startReordering = (column, e) => {
const $columns = get(columns) const $columns = get(columns)
const $bounds = get(bounds) const $bounds = get(bounds)
const $scroll = get(scroll) const $scroll = get(scroll)
const $stickyColumn = get(stickyColumn)
// Generate new breakpoints for the current columns // Generate new breakpoints for the current columns
let breakpoints = $columns.map(col => col.left + col.width) let breakpoints = $columns.map(col => ({
x: col.left + col.width,
column: col.name,
}))
if ($stickyColumn) {
breakpoints.unshift({
x: 0,
column: $stickyColumn.name,
})
}
// Update state // Update state
reorder.set({ reorder.set({
columnIdx, sourceColumn: column,
targetColumn: null,
breakpoints, breakpoints,
swapColumnIdx: null,
initialMouseX: e.clientX, initialMouseX: e.clientX,
scrollLeft: $scroll.left, scrollLeft: $scroll.left,
sheetLeft: $bounds.left, sheetLeft: $bounds.left,
@ -41,26 +51,23 @@ export const createReorderStores = context => {
// Callback when moving the mouse when reordering columns // Callback when moving the mouse when reordering columns
const onReorderMouseMove = e => { const onReorderMouseMove = e => {
const $reorder = get(reorder) const $reorder = get(reorder)
if ($reorder.columnIdx == null) {
return
}
// Compute the closest breakpoint to the current position // Compute the closest breakpoint to the current position
let swapColumnIdx let targetColumn
let minDistance = Number.MAX_SAFE_INTEGER let minDistance = Number.MAX_SAFE_INTEGER
const mouseX = e.clientX - $reorder.sheetLeft + $reorder.scrollLeft const mouseX = e.clientX - $reorder.sheetLeft + $reorder.scrollLeft
$reorder.breakpoints.forEach((point, idx) => { $reorder.breakpoints.forEach(point => {
const distance = Math.abs(point - mouseX) const distance = Math.abs(point.x - mouseX)
if (distance < minDistance) { if (distance < minDistance) {
minDistance = distance minDistance = distance
swapColumnIdx = idx targetColumn = point.column
} }
}) })
if (swapColumnIdx !== $reorder.swapColumnIdx) { if (targetColumn !== $reorder.targetColumn) {
reorder.update(state => ({ reorder.update(state => ({
...state, ...state,
swapColumnIdx: swapColumnIdx, targetColumn,
})) }))
} }
} }
@ -68,14 +75,17 @@ export const createReorderStores = context => {
// Callback when stopping reordering columns // Callback when stopping reordering columns
const stopReordering = () => { const stopReordering = () => {
// Swap position of columns // Swap position of columns
let { columnIdx, swapColumnIdx } = get(reorder) const $columns = get(columns)
swapColumnIdx++ let { sourceColumn, targetColumn } = get(reorder)
let sourceIdx = $columns.findIndex(x => x.name === sourceColumn)
let targetIdx = $columns.findIndex(x => x.name === targetColumn)
targetIdx++
columns.update(state => { columns.update(state => {
const removed = state.splice(columnIdx, 1) const removed = state.splice(sourceIdx, 1)
if (--swapColumnIdx < columnIdx) { if (--targetIdx < sourceIdx) {
swapColumnIdx++ targetIdx++
} }
state.splice(swapColumnIdx, 0, removed[0]) state.splice(targetIdx, 0, removed[0])
let offset = 0 let offset = 0
return state.map((col, idx) => { return state.map((col, idx) => {
const newCol = { const newCol = {