From 3ab0e95032a85f8ae89cf509b37ab7f42c027aa8 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 24 Feb 2023 09:46:44 +0000 Subject: [PATCH] Test absolute positioning --- .../app/spreadsheet/Spreadsheet.svelte | 120 ++++++++++-------- .../app/spreadsheet/SpreadsheetBody.svelte | 56 ++++---- .../app/spreadsheet/SpreadsheetCell.svelte | 6 +- .../app/spreadsheet/SpreadsheetRow.svelte | 57 +++++---- .../app/spreadsheet/stores/resize.js | 67 +++++++--- 5 files changed, 185 insertions(+), 121 deletions(-) diff --git a/packages/client/src/components/app/spreadsheet/Spreadsheet.svelte b/packages/client/src/components/app/spreadsheet/Spreadsheet.svelte index dde5566dd7..49dbbf00d8 100644 --- a/packages/client/src/components/app/spreadsheet/Spreadsheet.svelte +++ b/packages/client/src/components/app/spreadsheet/Spreadsheet.svelte @@ -92,9 +92,10 @@ if (primaryDisplay) { fields = [primaryDisplay, ...fields.filter(x => x !== primaryDisplay)] } - $columns = fields.map(field => ({ + $columns = fields.map((field, idx) => ({ name: field, width: defaultWidth, + left: 40 + idx * defaultWidth, schema: schema[field], primaryDisplay: field === primaryDisplay, })) @@ -179,47 +180,56 @@ resize, spreadsheetAPI, }) + + let sheetStyles = "" + let left = 40 + for (let i = 0; i < 20; i++) { + sheetStyles += `--col-${i}-width:${160}px; --col-${i}-left:${left}px;` + left += 160 + }
- - - - - {#each $columns as field, fieldIdx} - reorder.actions.startReordering(fieldIdx, e)} - id={`sheet-${rand}-header-${fieldIdx}`} - > - + + + - - {field.name} - - - {/each} - + {#each $columns as field, fieldIdx} + reorder.actions.startReordering(fieldIdx, e)} + id={`sheet-${rand}-header-${fieldIdx}`} + width={field.width} + left={field.left} + column={fieldIdx} + > + + + {field.name} + + + + {/each} +
{#each $rows as row, rowIdx (row._id)} @@ -227,28 +237,30 @@ {/each} - ($hoveredRowId = "new")} - rowHovered={$hoveredRowId === "new"} - > - - - {#each $columns as field, fieldIdx} +
addRow(field)} + label + on:click={addRow} on:mouseenter={() => ($hoveredRowId = "new")} - /> - {/each} - - - - + rowHovered={$hoveredRowId === "new"} + width="40" + left="0" + > + + + {#each $columns as field, fieldIdx} + addRow(field)} + on:mouseenter={() => ($hoveredRowId = "new")} + width={field.width} + left={field.left} + /> + {/each} +
@@ -279,4 +291,10 @@ .wrapper::-webkit-scrollbar-track { background: var(--cell-background); } + + .row { + display: flex; + position: sticky; + width: 100%; + } diff --git a/packages/client/src/components/app/spreadsheet/SpreadsheetBody.svelte b/packages/client/src/components/app/spreadsheet/SpreadsheetBody.svelte index 40084f0066..5853ddceb4 100644 --- a/packages/client/src/components/app/spreadsheet/SpreadsheetBody.svelte +++ b/packages/client/src/components/app/spreadsheet/SpreadsheetBody.svelte @@ -2,18 +2,31 @@ import { getContext, onMount } from "svelte" import { Utils } from "@budibase/frontend-core" - const { columns, selectedCellId, rand, visibleRows, cellHeight } = + const { columns, selectedCellId, rand, visibleRows, cellHeight, rows } = getContext("spreadsheet") let ref - let height = 0 + let height = 600 let horizontallyScrolled = false let scrollTop = 0 $: gridStyles = getGridStyles($columns) $: computeVisibleRows(scrollTop, height) + $: contentHeight = ($rows.length + 2) * cellHeight + 180 + $: contentWidth = computeWidth($columns) + $: console.log("new height") + + const computeWidth = columns => { + console.log("width") + let width = 220 + columns.forEach(col => { + width += col.width + }) + return width + } const getGridStyles = columns => { + console.log("grid") const widths = columns?.map(x => x.width) if (!widths?.length) { return "--grid: 1fr;" @@ -30,11 +43,11 @@ scrollTop = e.target.scrollTop } - const computeVisibleRows = Utils.debounce((scrollTop, height) => { - const rows = Math.ceil(height / cellHeight) + 16 - const firstRow = Math.max(0, Math.floor(scrollTop / cellHeight) - 8) + const computeVisibleRows = (scrollTop, height) => { + const rows = Math.ceil(height / cellHeight) + 8 + const firstRow = Math.max(0, Math.floor(scrollTop / cellHeight) - 4) visibleRows.set([firstRow, firstRow + rows]) - }, 50) + } // Observe and record the height of the body onMount(() => { @@ -53,35 +66,28 @@ class="spreadsheet" class:horizontally-scrolled={horizontallyScrolled} on:scroll={handleScroll} - style={gridStyles} on:click|self={() => ($selectedCellId = null)} id={`sheet-${rand}-body`} > - +
+ +
diff --git a/packages/client/src/components/app/spreadsheet/SpreadsheetCell.svelte b/packages/client/src/components/app/spreadsheet/SpreadsheetCell.svelte index 1ce19744f7..2501d47726 100644 --- a/packages/client/src/components/app/spreadsheet/SpreadsheetCell.svelte +++ b/packages/client/src/components/app/spreadsheet/SpreadsheetCell.svelte @@ -9,6 +9,7 @@ export let reorderSource = false export let reorderTarget = false export let id = null + export let column
@@ -48,7 +50,7 @@ font-size: var(--cell-font-size); gap: var(--cell-spacing); background: var(--cell-background); - position: relative; + position: absolute; transition: border-color 130ms ease-out; } .cell.row-hovered { @@ -71,8 +73,6 @@ /* Header cells */ .cell.header { background: var(--spectrum-global-color-gray-200); - position: sticky; - top: 0; padding: 0 var(--cell-padding); z-index: 3; border-color: var(--spectrum-global-color-gray-400); diff --git a/packages/client/src/components/app/spreadsheet/SpreadsheetRow.svelte b/packages/client/src/components/app/spreadsheet/SpreadsheetRow.svelte index 2311ffab60..c64deaa63f 100644 --- a/packages/client/src/components/app/spreadsheet/SpreadsheetRow.svelte +++ b/packages/client/src/components/app/spreadsheet/SpreadsheetRow.svelte @@ -21,6 +21,7 @@ changeCache, spreadsheetAPI, visibleRows, + cellHeight, } = getContext("spreadsheet") $: rowSelected = !!$selectedRows[row._id] @@ -52,27 +53,27 @@ } -{#if !visible} -
-{:else} - ($hoveredRowId = row._id)} - on:click={() => selectRow(row._id)} - > - {#if rowSelected || rowHovered} - - {:else} - - {rowIdx + 1} - - {/if} - - {#each $columns as field, fieldIdx} - {@const cellIdx = `${row._id}-${field.name}`} - {#key cellIdx} +{#if visible} +
+ ($hoveredRowId = row._id)} + on:click={() => selectRow(row._id)} + width="40" + left="0" + > + {#if rowSelected || rowHovered} + + {:else} + + {rowIdx + 1} + + {/if} + + {#each $columns as field, fieldIdx} + {@const cellIdx = `${row._id}-${field.name}`} ($hoveredRowId = row._id)} on:click={() => ($selectedCellId = cellIdx)} + width={field.width} + left={field.left} + column={fieldIdx} > - {/key} - {/each} - + {/each} +
{/if} diff --git a/packages/client/src/components/app/spreadsheet/stores/resize.js b/packages/client/src/components/app/spreadsheet/stores/resize.js index 58c6151640..aab716df99 100644 --- a/packages/client/src/components/app/spreadsheet/stores/resize.js +++ b/packages/client/src/components/app/spreadsheet/stores/resize.js @@ -1,26 +1,39 @@ import { writable, get } from "svelte/store" +import { domDebounce } from "../../../../utils/domDebounce.js" const MinColumnWidth = 100 export const createResizeStore = context => { - const { columns } = context + const { columns, rand } = context const initialState = { initialMouseX: null, initialWidth: null, columnIdx: null, } + + let initialWidth = 0 + let width = 0 + let left = 0 + let initialMouseX = null + let sheet + let columnIdx = 0 + let columnCount = 0 + let styles + const resize = writable(initialState) - const startResizing = (columnIdx, e) => { + const startResizing = (idx, e) => { // Prevent propagation to stop reordering triggering e.stopPropagation() - // Update state - resize.set({ - columnIdx, - initialWidth: get(columns)[columnIdx].width, - initialMouseX: e.clientX, - }) + sheet = document.getElementById(`sheet-${rand}`) + styles = getComputedStyle(sheet) + width = parseInt(styles.getPropertyValue(`--col-${idx}-width`)) + left = parseInt(styles.getPropertyValue(`--col-${idx}-left`)) + initialWidth = width + initialMouseX = e.clientX + columnIdx = idx + columnCount = get(columns).length // Add mouse event listeners to handle resizing document.addEventListener("mousemove", onResizeMouseMove) @@ -28,21 +41,39 @@ export const createResizeStore = context => { } const onResizeMouseMove = e => { - const $resize = get(resize) - const dx = e.clientX - $resize.initialMouseX - const width = get(columns)[$resize.columnIdx].width - const newWidth = Math.max(MinColumnWidth, $resize.initialWidth + dx) + const dx = e.clientX - initialMouseX + const newWidth = Math.round(Math.max(MinColumnWidth, initialWidth + dx)) - // Skip small updates - if (Math.abs(width - newWidth) < 20) { + if (Math.abs(width - newWidth) < 10) { return } + + let newStyle = `--col-${columnIdx}-width:${newWidth}px;` + + let offset = left + newWidth + for (let i = columnIdx + 1; i < columnCount; i++) { + const colWidth = 160//parseInt(styles.getPropertyValue(`--col-${i}-width`)) + newStyle += `--col-${i}-left:${offset}px;` + offset += colWidth + } + + sheet.style.cssText += newStyle + width = newWidth + // Update width of column - columns.update(state => { - state[$resize.columnIdx].width = newWidth - return state - }) + // columns.update(state => { + // state[$resize.columnIdx].width = Math.round(newWidth) + // + // // Update left offset of other columns + // let offset = 40 + // state.forEach(col => { + // col.left = offset + // offset += col.width + // }) + // + // return state + // }) } const stopResizing = () => {