diff --git a/packages/frontend-core/src/components/grid/layout/ButtonColumn.svelte b/packages/frontend-core/src/components/grid/layout/ButtonColumn.svelte
index 20cfdb1ec5..ead2c67787 100644
--- a/packages/frontend-core/src/components/grid/layout/ButtonColumn.svelte
+++ b/packages/frontend-core/src/components/grid/layout/ButtonColumn.svelte
@@ -3,6 +3,7 @@
import { Button } from "@budibase/bbui"
import GridCell from "../cells/GridCell.svelte"
import GridScrollWrapper from "./GridScrollWrapper.svelte"
+ import { BlankRowID } from "../lib/constants"
const {
renderedRows,
@@ -17,6 +18,7 @@
isDragging,
buttonColumnWidth,
showVScrollbar,
+ dispatch,
} = getContext("grid")
let container
@@ -89,6 +91,17 @@
{/each}
+
($hoveredRowId = BlankRowID)}
+ on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
+ >
+ dispatch("add-row-inline")}
+ />
+
@@ -129,8 +142,11 @@
align-items: center;
gap: 4px;
}
+ .blank :global(.cell:hover) {
+ cursor: pointer;
+ }
- /* Add left cell border */
+ /* Add left cell border to all cells */
.button-column :global(.cell) {
border-left: var(--cell-border);
}
diff --git a/packages/frontend-core/src/components/grid/layout/Grid.svelte b/packages/frontend-core/src/components/grid/layout/Grid.svelte
index 8a82209162..8ea9e2264d 100644
--- a/packages/frontend-core/src/components/grid/layout/Grid.svelte
+++ b/packages/frontend-core/src/components/grid/layout/Grid.svelte
@@ -26,7 +26,7 @@
MaxCellRenderOverflow,
GutterWidth,
DefaultRowHeight,
- Padding,
+ VPadding,
SmallRowHeight,
ControlsHeight,
ScrollBarSize,
@@ -119,7 +119,7 @@
// Derive min height and make available in context
const minHeight = derived(rowHeight, $height => {
const heightForControls = showControls ? ControlsHeight : 0
- return Padding + SmallRowHeight + $height + heightForControls
+ return VPadding + SmallRowHeight + $height + heightForControls
})
context = { ...context, minHeight }
@@ -354,8 +354,13 @@
transition: none;
}
- /* Overrides */
- .grid.quiet :global(.grid-data-content .row > .cell:not(:last-child)) {
+ /* Overrides for quiet */
+ .grid.quiet :global(.grid-data-content .row > .cell:not(:last-child)),
+ .grid.quiet :global(.sticky-column .row > .cell),
+ .grid.quiet :global(.new-row .row > .cell:not(:last-child)) {
border-right: none;
}
+ .grid.quiet :global(.sticky-column:before) {
+ display: none;
+ }
diff --git a/packages/frontend-core/src/components/grid/layout/GridBody.svelte b/packages/frontend-core/src/components/grid/layout/GridBody.svelte
index 8be56674be..cf93f3004e 100644
--- a/packages/frontend-core/src/components/grid/layout/GridBody.svelte
+++ b/packages/frontend-core/src/components/grid/layout/GridBody.svelte
@@ -2,6 +2,7 @@
import { getContext, onMount } from "svelte"
import GridScrollWrapper from "./GridScrollWrapper.svelte"
import GridRow from "./GridRow.svelte"
+ import GridCell from "../cells/GridCell.svelte"
import { BlankRowID } from "../lib/constants"
import ButtonColumn from "./ButtonColumn.svelte"
@@ -46,7 +47,6 @@
-
{#each $renderedRows as row, idx}
@@ -54,13 +54,16 @@
{/each}
{#if $config.canAddRows}
($hoveredRowId = BlankRowID)}
on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
- on:click={() => dispatch("add-row-inline")}
- />
+ >
+ dispatch("add-row-inline")}
+ />
+
{/if}
{#if $props.buttons?.length}
@@ -76,15 +79,13 @@
overflow: hidden;
flex: 1 1 auto;
}
- .blank {
- height: var(--row-height);
- background: var(--cell-background);
- border-bottom: var(--cell-border);
- border-right: var(--cell-border);
- position: absolute;
+ .row {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: stretch;
}
- .blank.highlighted {
- background: var(--cell-background-hover);
+ .blank :global(.cell:hover) {
cursor: pointer;
}
diff --git a/packages/frontend-core/src/components/grid/layout/NewRow.svelte b/packages/frontend-core/src/components/grid/layout/NewRow.svelte
index 68ace8a5b2..1da8f7a63e 100644
--- a/packages/frontend-core/src/components/grid/layout/NewRow.svelte
+++ b/packages/frontend-core/src/components/grid/layout/NewRow.svelte
@@ -31,6 +31,7 @@
filter,
inlineFilters,
columnRenderMap,
+ scrollTop,
} = getContext("grid")
let visible = false
@@ -43,6 +44,21 @@
$: $datasource, (visible = false)
$: selectedRowCount = Object.values($selectedRows).length
$: hasNoRows = !$rows.length
+ $: renderedRowCount = $renderedRows.length
+ $: offset = getOffset($hasNextPage, renderedRowCount, $rowHeight, $scrollTop)
+
+ const getOffset = (hasNextPage, rowCount, rowHeight, scrollTop) => {
+ // If we have a next page of data then we aren't truly at the bottom, so we
+ // render the add row component at the top
+ if (hasNextPage) {
+ return 0
+ }
+ offset = rowCount * rowHeight - (scrollTop % rowHeight)
+ if (rowCount !== 0) {
+ offset -= 1
+ }
+ return offset
+ }
const addRow = async () => {
// Blur the active cell and tick to let final value updates propagate
@@ -85,12 +101,6 @@
return
}
- // If we have a next page of data then we aren't truly at the bottom, so we
- // render the add row component at the top
- if ($hasNextPage) {
- offset = 0
- }
-
// If we don't have a next page then we're at the bottom and can scroll to
// the max available offset
else {
@@ -98,10 +108,6 @@
...state,
top: $maxScrollTop,
}))
- offset = $renderedRows.length * $rowHeight - ($maxScrollTop % $rowHeight)
- if ($renderedRows.length !== 0) {
- offset -= 1
- }
}
// Update state and select initial cell
@@ -171,39 +177,41 @@
{#if visible}
0}
style="--offset:{offset}px; --sticky-width:{width}px;"
>
-
-
- {#if isAdding}
-
- {/if}
-
- {#if $stickyColumn}
- {@const cellId = getCellID(NewRowID, $stickyColumn.name)}
-
- {#if $stickyColumn?.schema?.autocolumn}
- Can't edit auto column
- {/if}
+
+
+
{#if isAdding}
{/if}
-
- {/if}
+
+ {#if $stickyColumn}
+ {@const cellId = getCellID(NewRowID, $stickyColumn.name)}
+
+ {#if $stickyColumn?.schema?.autocolumn}
+ Can't edit auto column
+ {/if}
+ {#if isAdding}
+
+ {/if}
+
+ {/if}
+
@@ -270,7 +278,7 @@
margin-left: -6px;
}
- .container {
+ .new-row {
position: absolute;
top: var(--default-row-height);
left: 0;
@@ -280,10 +288,10 @@
flex-direction: row;
align-items: stretch;
}
- .container :global(.cell) {
+ .new-row :global(.cell) {
--cell-background: var(--spectrum-global-color-gray-75) !important;
}
- .container.floating :global(.cell) {
+ .new-row.floating :global(.cell) {
height: calc(var(--row-height) + 1px);
border-top: var(--cell-border);
}
@@ -312,8 +320,10 @@
pointer-events: all;
z-index: 3;
position: absolute;
- top: calc(var(--row-height) + var(--offset) + 24px);
- left: 18px;
+ top: calc(
+ var(--row-height) + var(--offset) + var(--default-row-height) / 2
+ );
+ left: calc(var(--default-row-height) / 2);
}
.button-with-keys {
display: flex;
diff --git a/packages/frontend-core/src/components/grid/layout/StickyColumn.svelte b/packages/frontend-core/src/components/grid/layout/StickyColumn.svelte
index b57c89ee4f..85c1eb2897 100644
--- a/packages/frontend-core/src/components/grid/layout/StickyColumn.svelte
+++ b/packages/frontend-core/src/components/grid/layout/StickyColumn.svelte
@@ -66,62 +66,58 @@
-
-
- {#each $renderedRows as row, idx}
- {@const rowSelected = !!$selectedRows[row._id]}
- {@const rowHovered = $hoveredRowId === row._id}
- {@const rowFocused = $focusedRow?._id === row._id}
- {@const cellId = getCellID(row._id, $stickyColumn?.name)}
- ($hoveredRowId = row._id)}
- on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
- on:click={() => dispatch("rowclick", rows.actions.cleanRow(row))}
- >
-
- {#if $stickyColumn}
-
- {/if}
-
- {/each}
- {#if $config.canAddRows}
- ($hoveredRowId = BlankRowID)}
- on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
- on:click={() => dispatch("add-row-inline")}
- >
-
-
-
- {#if $stickyColumn}
-
-
-
- {/if}
-
- {/if}
-
-
+
+ {#each $renderedRows as row, idx}
+ {@const rowSelected = !!$selectedRows[row._id]}
+ {@const rowHovered = $hoveredRowId === row._id}
+ {@const rowFocused = $focusedRow?._id === row._id}
+ {@const cellId = getCellID(row._id, $stickyColumn?.name)}
+ ($hoveredRowId = row._id)}
+ on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
+ on:click={() => dispatch("rowclick", rows.actions.cleanRow(row))}
+ >
+
+ {#if $stickyColumn}
+
+ {/if}
+
+ {/each}
+ {#if $config.canAddRows}
+ ($hoveredRowId = BlankRowID)}
+ on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
+ on:click={() => dispatch("add-row-inline")}
+ >
+
+
+
+ {#if $stickyColumn}
+
+
+
+ {/if}
+
+ {/if}
+
diff --git a/packages/frontend-core/src/components/grid/lib/constants.js b/packages/frontend-core/src/components/grid/lib/constants.js
index 4b5d04894a..6ea7a98178 100644
--- a/packages/frontend-core/src/components/grid/lib/constants.js
+++ b/packages/frontend-core/src/components/grid/lib/constants.js
@@ -1,12 +1,13 @@
-export const Padding = 100
-export const ScrollBarSize = 8
-export const GutterWidth = 72
-export const DefaultColumnWidth = 200
-export const MinColumnWidth = 80
export const SmallRowHeight = 36
export const MediumRowHeight = 64
export const LargeRowHeight = 92
export const DefaultRowHeight = SmallRowHeight
+export const VPadding = SmallRowHeight * 2
+export const HPadding = 40
+export const ScrollBarSize = 8
+export const GutterWidth = 72
+export const DefaultColumnWidth = 200
+export const MinColumnWidth = 80
export const NewRowID = "new"
export const BlankRowID = "blank"
export const RowPageSize = 100
diff --git a/packages/frontend-core/src/components/grid/stores/scroll.js b/packages/frontend-core/src/components/grid/stores/scroll.js
index e7114cd00c..814d4cdc8c 100644
--- a/packages/frontend-core/src/components/grid/stores/scroll.js
+++ b/packages/frontend-core/src/components/grid/stores/scroll.js
@@ -1,6 +1,12 @@
import { writable, derived, get } from "svelte/store"
import { tick } from "svelte"
-import { Padding, GutterWidth, FocusedCellMinOffset } from "../lib/constants"
+import {
+ GutterWidth,
+ FocusedCellMinOffset,
+ ScrollBarSize,
+ HPadding,
+ VPadding,
+} from "../lib/constants"
import { parseCellID } from "../lib/utils"
export const createStores = () => {
@@ -34,28 +40,15 @@ export const deriveStores = context => {
// Memoize store primitives
const stickyColumnWidth = derived(stickyColumn, $col => $col?.width || 0, 0)
- // Derive vertical limits
- const contentHeight = derived(
- [rows, rowHeight],
- ([$rows, $rowHeight]) => ($rows.length + 1) * $rowHeight + Padding,
- 0
- )
- const maxScrollTop = derived(
- [height, contentHeight],
- ([$height, $contentHeight]) => Math.max($contentHeight - $height, 0),
- 0
- )
-
// Derive horizontal limits
const contentWidth = derived(
[visibleColumns, stickyColumnWidth, buttonColumnWidth],
([$visibleColumns, $stickyColumnWidth, $buttonColumnWidth]) => {
- const space = Math.max(Padding, $buttonColumnWidth - 1)
- let width = GutterWidth + space + $stickyColumnWidth
+ let width = GutterWidth + $buttonColumnWidth + $stickyColumnWidth
$visibleColumns.forEach(col => {
width += col.width
})
- return width
+ return width + HPadding
},
0
)
@@ -71,14 +64,6 @@ export const deriveStores = context => {
},
0
)
-
- // Derive whether to show scrollbars or not
- const showVScrollbar = derived(
- [contentHeight, height],
- ([$contentHeight, $height]) => {
- return $contentHeight > $height
- }
- )
const showHScrollbar = derived(
[contentWidth, screenWidth],
([$contentWidth, $screenWidth]) => {
@@ -86,6 +71,30 @@ export const deriveStores = context => {
}
)
+ // Derive vertical limits
+ const contentHeight = derived(
+ [rows, rowHeight, showHScrollbar],
+ ([$rows, $rowHeight, $showHScrollbar]) => {
+ let height = ($rows.length + 1) * $rowHeight + VPadding
+ if ($showHScrollbar) {
+ height += ScrollBarSize * 2
+ }
+ return height
+ },
+ 0
+ )
+ const maxScrollTop = derived(
+ [height, contentHeight],
+ ([$height, $contentHeight]) => Math.max($contentHeight - $height, 0),
+ 0
+ )
+ const showVScrollbar = derived(
+ [contentHeight, height],
+ ([$contentHeight, $height]) => {
+ return $contentHeight > $height
+ }
+ )
+
return {
contentHeight,
contentWidth,