Simplify logic for reordering and add new overlay. Simplify sheet cells

This commit is contained in:
Andrew Kingston 2023-04-12 09:51:49 +01:00
parent 38f326dce4
commit 7fa976ba5e
14 changed files with 101 additions and 77 deletions

View File

@ -7,14 +7,12 @@
const { rows, focusedCellId, focusedCellAPI, menu, config, validation } = const { rows, focusedCellId, focusedCellAPI, menu, config, validation } =
getContext("sheet") getContext("sheet")
export let rowSelected export let highlighted
export let rowHovered export let selected
export let rowFocused export let rowFocused
export let rowIdx export let rowIdx
export let focused export let focused
export let selectedUser export let selectedUser
export let reorderSource
export let reorderTarget
export let column export let column
export let row export let row
export let cellId export let cellId
@ -58,14 +56,11 @@
</script> </script>
<SheetCell <SheetCell
{rowSelected} {highlighted}
{rowHovered} {selected}
{rowFocused}
{rowIdx} {rowIdx}
{focused} {focused}
{selectedUser} {selectedUser}
{reorderSource}
{reorderTarget}
error={$error} error={$error}
on:click={() => focusedCellId.set(cellId)} on:click={() => focusedCellId.set(cellId)}
on:contextmenu={e => menu.actions.open(cellId, e)} on:contextmenu={e => menu.actions.open(cellId, e)}

View File

@ -105,8 +105,6 @@
class:sorted={sortedBy} class:sorted={sortedBy}
> >
<SheetCell <SheetCell
reorderSource={$reorder.sourceColumn === column.name}
reorderTarget={$reorder.targetColumn === column.name}
on:mousedown={onMouseDown} on:mousedown={onMouseDown}
on:mouseup={onMouseUp} on:mouseup={onMouseUp}
on:contextmenu={onContextMenu} on:contextmenu={onContextMenu}
@ -178,6 +176,9 @@
.header-cell { .header-cell {
display: flex; display: flex;
} }
.header-cell.disabled {
pointer-events: none;
}
.header-cell :global(.cell) { .header-cell :global(.cell) {
padding: 0 var(--cell-padding); padding: 0 var(--cell-padding);
gap: calc(2 * var(--cell-spacing)); gap: calc(2 * var(--cell-spacing));

View File

@ -28,7 +28,7 @@
const parsed = JSON.parse(trimmed) const parsed = JSON.parse(trimmed)
onChange(parsed) onChange(parsed)
} catch (error) { } catch (error) {
console.log("error parsing") // Swallow
} }
} }
</script> </script>

View File

@ -1,15 +1,11 @@
<script> <script>
export let rowSelected = false
export let rowHovered = false
export let rowFocused = false
export let focused = false export let focused = false
export let reorderSource = false export let selected = false
export let reorderTarget = false export let highlighted = false
export let width = "" export let width = ""
export let center = false
export let selectedUser = null export let selectedUser = null
export let rowIdx
export let error = null export let error = null
export let rowIdx
$: style = getStyle(width, selectedUser) $: style = getStyle(width, selectedUser)
@ -24,15 +20,11 @@
<div <div
class="cell" class="cell"
class:row-selected={rowSelected} class:selected
class:row-hovered={rowHovered} class:highlighted
class:row-focused={rowFocused}
class:focused class:focused
class:selected-other={selectedUser != null}
class:reorder-source={reorderSource}
class:reorder-target={reorderTarget}
class:center
class:error class:error
class:selected-other={selectedUser != null}
on:focus on:focus
on:mousedown on:mousedown
on:mouseup on:mouseup
@ -119,29 +111,13 @@
.cell:hover { .cell:hover {
cursor: default; cursor: default;
} }
.cell.row-hovered, .cell.highlighted,
.cell.row-focused { .cell.focused {
--cell-background: var(--cell-background-hover); --cell-background: var(--cell-background-hover);
} }
.cell.row-selected { .cell.selected {
--cell-background: var(--spectrum-global-color-blue-100); --cell-background: var(--spectrum-global-color-blue-100);
} }
.cell.center {
justify-content: center;
}
/* Reorder styles */
.cell.reorder-source {
--cell-background: var(--spectrum-global-color-gray-100);
}
.cell.reorder-target:after {
content: " ";
position: absolute;
right: 0;
background: var(--spectrum-global-color-blue-400);
width: 2px;
height: calc(var(--row-height) + 2px);
}
/* Label for additional text */ /* Label for additional text */
.label { .label {

View File

@ -7,7 +7,7 @@
</script> </script>
<div class="header"> <div class="header">
<SheetScrollWrapper scrollVertically={false} wheelInteractive={false}> <SheetScrollWrapper scrollHorizontally>
<div class="row"> <div class="row">
{#each $renderedColumns as column, idx} {#each $renderedColumns as column, idx}
<HeaderCell {column} {idx} /> <HeaderCell {column} {idx} />

View File

@ -118,7 +118,7 @@
{/if} {/if}
</div> </div>
<SheetScrollWrapper scrollVertically={false} foo> <SheetScrollWrapper scrollHorizontally wheelInteractive foo>
<div class="row"> <div class="row">
{#each $visibleColumns as column} {#each $visibleColumns as column}
{@const cellId = `new-${column.name}`} {@const cellId = `new-${column.name}`}

View File

@ -3,10 +3,11 @@
import { writable } from "svelte/store" import { writable } from "svelte/store"
import { createEventManagers } from "../lib/events" import { createEventManagers } from "../lib/events"
import { createAPIClient } from "../../../api" import { createAPIClient } from "../../../api"
import { createStores } from "../stores" import { attachStores } from "../stores"
import DeleteButton from "../controls/DeleteButton.svelte" import DeleteButton from "../controls/DeleteButton.svelte"
import SheetBody from "./SheetBody.svelte" import SheetBody from "./SheetBody.svelte"
import ResizeOverlay from "../overlays/ResizeOverlay.svelte" import ResizeOverlay from "../overlays/ResizeOverlay.svelte"
import ReorderOverlay from "../overlays/ReorderOverlay.svelte"
import HeaderRow from "./HeaderRow.svelte" import HeaderRow from "./HeaderRow.svelte"
import ScrollOverlay from "../overlays/ScrollOverlay.svelte" import ScrollOverlay from "../overlays/ScrollOverlay.svelte"
import MenuOverlay from "../overlays/MenuOverlay.svelte" import MenuOverlay from "../overlays/MenuOverlay.svelte"
@ -54,7 +55,7 @@
tableId: tableIdStore, tableId: tableIdStore,
} }
context = { ...context, ...createEventManagers() } context = { ...context, ...createEventManagers() }
context = { ...context, ...createStores(context) } context = attachStores(context)
// Reference some stores for local use // Reference some stores for local use
const { isResizing, isReordering, ui, loaded, rowHeight } = context const { isResizing, isReordering, ui, loaded, rowHeight } = context
@ -111,6 +112,7 @@
</div> </div>
<div class="overlays"> <div class="overlays">
<ResizeOverlay /> <ResizeOverlay />
<ReorderOverlay />
<ScrollOverlay /> <ScrollOverlay />
<MenuOverlay /> <MenuOverlay />
</div> </div>
@ -135,9 +137,9 @@
--cell-background-hover: var(--spectrum-global-color-gray-100); --cell-background-hover: var(--spectrum-global-color-gray-100);
--cell-padding: 10px; --cell-padding: 10px;
--cell-spacing: 4px; --cell-spacing: 4px;
--cell-border: 1px solid var(--spectrum-global-color-gray-200);
--cell-font-size: 14px; --cell-font-size: 14px;
--controls-height: 50px; --controls-height: 50px;
--cell-border: 1px solid var(--spectrum-global-color-gray-200);
} }
.sheet, .sheet,
.sheet :global(*) { .sheet :global(*) {
@ -161,7 +163,6 @@
.sheet-data-outer { .sheet-data-outer {
height: 0; height: 0;
flex-direction: column; flex-direction: column;
/*background: var(--spectrum-global-color-gray-75);*/
background: var(--cell-background); background: var(--cell-background);
} }
.sheet-data-inner { .sheet-data-inner {

View File

@ -25,7 +25,7 @@
</script> </script>
<div bind:this={body} class="sheet-body"> <div bind:this={body} class="sheet-body">
<SheetScrollWrapper> <SheetScrollWrapper scrollHorizontally scrollVertically wheelInteractive>
{#each $renderedRows as row, idx} {#each $renderedRows as row, idx}
<SheetRow {row} {idx} invert={idx >= inversionIdx} /> <SheetRow {row} {idx} invert={idx >= inversionIdx} />
{/each} {/each}

View File

@ -21,6 +21,7 @@
$: rowSelected = !!$selectedRows[row._id] $: rowSelected = !!$selectedRows[row._id]
$: rowHovered = $hoveredRowId === row._id $: rowHovered = $hoveredRowId === row._id
$: rowFocused = $focusedRow?._id === row._id $: rowFocused = $focusedRow?._id === row._id
$: reorderSource = $reorder.sourceColumn
$: cols = rowFocused ? $visibleColumns : $renderedColumns $: cols = rowFocused ? $visibleColumns : $renderedColumns
$: foo = `margin-left: ${-1 * $hiddenColumnsWidth}px;` $: foo = `margin-left: ${-1 * $hiddenColumnsWidth}px;`
</script> </script>
@ -35,18 +36,16 @@
{#each cols as column (column.name)} {#each cols as column (column.name)}
{@const cellId = `${row._id}-${column.name}`} {@const cellId = `${row._id}-${column.name}`}
<DataCell <DataCell
{rowSelected}
{rowHovered}
{rowFocused}
{cellId} {cellId}
{column} {column}
{row} {row}
{invert} {invert}
{rowFocused}
highlighted={rowHovered || rowFocused || reorderSource === column.name}
selected={rowSelected}
rowIdx={idx} rowIdx={idx}
focused={$focusedCellId === cellId} focused={$focusedCellId === cellId}
selectedUser={$selectedCellMap[cellId]} selectedUser={$selectedCellMap[cellId]}
reorderSource={$reorder.sourceColumn === column.name}
reorderTarget={$reorder.targetColumn === column.name}
width={column.width} width={column.width}
/> />
{/each} {/each}

View File

@ -14,9 +14,9 @@
hiddenColumnsWidth, hiddenColumnsWidth,
} = getContext("sheet") } = getContext("sheet")
export let scrollVertically = true export let scrollVertically = false
export let scrollHorizontally = true export let scrollHorizontally = false
export let wheelInteractive = true export let wheelInteractive = false
export let foo = false export let foo = false
$: style = generateStyle($scroll, $rowHeight, $hiddenColumnsWidth, foo) $: style = generateStyle($scroll, $rowHeight, $hiddenColumnsWidth, foo)

View File

@ -13,8 +13,6 @@
renderedRows, renderedRows,
focusedCellId, focusedCellId,
hoveredRowId, hoveredRowId,
scroll,
reorder,
config, config,
selectedCellMap, selectedCellMap,
focusedRow, focusedRow,
@ -86,7 +84,7 @@
</div> </div>
<div class="content" on:mouseleave={() => ($hoveredRowId = null)}> <div class="content" on:mouseleave={() => ($hoveredRowId = null)}>
<SheetScrollWrapper scrollHorizontally={false}> <SheetScrollWrapper scrollVertically wheelInteractive>
{#each $renderedRows as row, idx} {#each $renderedRows as row, idx}
{@const rowSelected = !!$selectedRows[row._id]} {@const rowSelected = !!$selectedRows[row._id]}
{@const rowHovered = $hoveredRowId === row._id} {@const rowHovered = $hoveredRowId === row._id}
@ -99,9 +97,8 @@
> >
<SheetCell <SheetCell
width={gutterWidth} width={gutterWidth}
{rowSelected} highlighted={rowFocused || rowHovered}
{rowFocused} selected={rowSelected}
{rowHovered}
> >
<div class="gutter"> <div class="gutter">
<div <div
@ -135,14 +132,12 @@
</SheetCell> </SheetCell>
{#if $stickyColumn} {#if $stickyColumn}
<DataCell <DataCell
{rowSelected} selected={rowSelected}
{rowHovered} highlighted={rowHovered || rowFocused}
{rowFocused}
rowIdx={idx} rowIdx={idx}
focused={$focusedCellId === cellId} focused={$focusedCellId === cellId}
selectedUser={$selectedCellMap[cellId]} selectedUser={$selectedCellMap[cellId]}
width={$stickyColumn.width} width={$stickyColumn.width}
reorderTarget={$reorder.targetColumn === $stickyColumn.name}
column={$stickyColumn} column={$stickyColumn}
{row} {row}
{cellId} {cellId}

View File

@ -0,0 +1,60 @@
<script>
import { getContext } from "svelte"
import SheetScrollWrapper from "../layout/SheetScrollWrapper.svelte"
const {
isReordering,
reorder,
visibleColumns,
gutterWidth,
stickyColumn,
rowHeight,
renderedRows,
} = getContext("sheet")
$: targetColumn = $reorder.targetColumn
$: left = getLeft(targetColumn, $stickyColumn, $visibleColumns)
$: height = $rowHeight * ($renderedRows.length + 1)
$: style = `left:${left}px; height:${height}px;`
const getLeft = (targetColumn, stickyColumn, visibleColumns) => {
let left = gutterWidth + (stickyColumn?.width || 0)
// If this is not the sticky column, add additional left space
if (targetColumn !== stickyColumn?.name) {
const column = visibleColumns.find(x => x.name === targetColumn)
if (!column) {
return left
}
left += column.left + column.width
}
return left
}
</script>
{#if $isReordering}
<div class="reorder-wrapper">
<SheetScrollWrapper scrollVertically>
<div class="reorder-overlay" {style} />
</SheetScrollWrapper>
</div>
{/if}
<style>
.reorder-wrapper {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
pointer-events: none;
}
.reorder-overlay {
position: absolute;
top: 0;
width: 2px;
background: var(--spectrum-global-color-blue-400);
margin-left: -2px;
}
</style>

View File

@ -26,18 +26,16 @@ const DependencyOrderedStores = [
Pagination, Pagination,
] ]
export const createStores = context => { export const attachStores = context => {
let stores = {}
// Atomic store creation // Atomic store creation
for (let store of DependencyOrderedStores) { for (let store of DependencyOrderedStores) {
stores = { ...stores, ...store.createStores?.({ ...context, ...stores }) } context = { ...context, ...store.createStores?.(context) }
} }
// Derived store creation // Derived store creation
for (let store of DependencyOrderedStores) { for (let store of DependencyOrderedStores) {
stores = { ...stores, ...store.deriveStores?.({ ...context, ...stores }) } context = { ...context, ...store.deriveStores?.(context) }
} }
return stores return context
} }

View File

@ -421,7 +421,6 @@ export default class DataFetch {
if (state.loading || !this.options.paginate || !state.hasNextPage) { if (state.loading || !this.options.paginate || !state.hasNextPage) {
return return
} }
console.log("NEXT PAGE")
// Fetch next page // Fetch next page
const nextCursor = state.cursors[state.pageNumber + 1] const nextCursor = state.cursors[state.pageNumber + 1]