Improve new row top component and fix style issues with z-index with validation labels
This commit is contained in:
parent
ea78f7fede
commit
77406ac183
|
@ -9,7 +9,7 @@
|
||||||
icon="TableRowAddBottom"
|
icon="TableRowAddBottom"
|
||||||
quiet
|
quiet
|
||||||
size="M"
|
size="M"
|
||||||
on:click={() => dispatch("add-row")}
|
on:click={() => dispatch("add-row-inline")}
|
||||||
disabled={!loaded ||
|
disabled={!loaded ||
|
||||||
!$config.allowAddRows ||
|
!$config.allowAddRows ||
|
||||||
(!$columns.length && !$stickyColumn)}
|
(!$columns.length && !$stickyColumn)}
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
<script>
|
|
||||||
import { Icon } from "@budibase/bbui"
|
|
||||||
import { getContext } from "svelte"
|
|
||||||
|
|
||||||
const { dispatch } = getContext("grid")
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="floating-add-row" on:click={() => dispatch("add-row-inline")}>
|
|
||||||
<Icon name="Add" size="L" color="white" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.floating-add-row {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 32px;
|
|
||||||
left: 32px;
|
|
||||||
height: 50px;
|
|
||||||
width: 50px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: var(--spectrum-global-color-blue-400);
|
|
||||||
display: grid;
|
|
||||||
place-items: center;
|
|
||||||
}
|
|
||||||
.floating-add-row:hover {
|
|
||||||
background: var(--spectrum-global-color-blue-500);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -23,7 +23,6 @@
|
||||||
import AddRowButton from "../controls/AddRowButton.svelte"
|
import AddRowButton from "../controls/AddRowButton.svelte"
|
||||||
import RowHeightButton from "../controls/RowHeightButton.svelte"
|
import RowHeightButton from "../controls/RowHeightButton.svelte"
|
||||||
import NewRowTop from "./NewRowTop.svelte"
|
import NewRowTop from "./NewRowTop.svelte"
|
||||||
import FloatingAddRowButton from "../controls/FloatingAddRowButton.svelte"
|
|
||||||
import {
|
import {
|
||||||
MaxCellRenderHeight,
|
MaxCellRenderHeight,
|
||||||
MaxCellRenderWidthOverflow,
|
MaxCellRenderWidthOverflow,
|
||||||
|
@ -129,14 +128,11 @@
|
||||||
<HeaderRow />
|
<HeaderRow />
|
||||||
<GridBody />
|
<GridBody />
|
||||||
</div>
|
</div>
|
||||||
|
<NewRowTop />
|
||||||
<div class="overlays">
|
<div class="overlays">
|
||||||
<NewRowTop />
|
|
||||||
<ResizeOverlay />
|
<ResizeOverlay />
|
||||||
<ReorderOverlay />
|
<ReorderOverlay />
|
||||||
<BetaButton />
|
<BetaButton />
|
||||||
{#if allowAddRows}
|
|
||||||
<FloatingAddRowButton />
|
|
||||||
{/if}
|
|
||||||
<ScrollOverlay />
|
<ScrollOverlay />
|
||||||
<MenuOverlay />
|
<MenuOverlay />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import { Icon, Button } from "@budibase/bbui"
|
import { Icon, Button } from "@budibase/bbui"
|
||||||
import GridScrollWrapper from "./GridScrollWrapper.svelte"
|
import GridScrollWrapper from "./GridScrollWrapper.svelte"
|
||||||
import DataCell from "../cells/DataCell.svelte"
|
import DataCell from "../cells/DataCell.svelte"
|
||||||
import { fly } from "svelte/transition"
|
import { fade } from "svelte/transition"
|
||||||
import { GutterWidth } from "../lib/constants"
|
import { GutterWidth } from "../lib/constants"
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -14,11 +14,11 @@
|
||||||
scroll,
|
scroll,
|
||||||
config,
|
config,
|
||||||
dispatch,
|
dispatch,
|
||||||
visibleColumns,
|
|
||||||
rows,
|
rows,
|
||||||
showHScrollbar,
|
showHScrollbar,
|
||||||
tableId,
|
tableId,
|
||||||
subscribe,
|
subscribe,
|
||||||
|
renderedColumns,
|
||||||
scrollLeft,
|
scrollLeft,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
let newRow = {}
|
let newRow = {}
|
||||||
let touched = false
|
let touched = false
|
||||||
|
|
||||||
$: firstColumn = $stickyColumn || $visibleColumns[0]
|
$: firstColumn = $stickyColumn || $renderedColumns[0]
|
||||||
$: rowHovered = $hoveredRowId === "new"
|
$: rowHovered = $hoveredRowId === "new"
|
||||||
$: rowFocused = $focusedCellId?.startsWith("new-")
|
$: rowFocused = $focusedCellId?.startsWith("new-")
|
||||||
$: width = GutterWidth + ($stickyColumn?.width || 0)
|
$: width = GutterWidth + ($stickyColumn?.width || 0)
|
||||||
|
@ -52,11 +52,14 @@
|
||||||
|
|
||||||
const cancel = () => {
|
const cancel = () => {
|
||||||
isAdding = false
|
isAdding = false
|
||||||
|
$focusedCellId = null
|
||||||
|
$hoveredRowId = null
|
||||||
}
|
}
|
||||||
|
|
||||||
const startAdding = () => {
|
const startAdding = () => {
|
||||||
newRow = {}
|
newRow = {}
|
||||||
isAdding = true
|
isAdding = true
|
||||||
|
$hoveredRowId = "new"
|
||||||
if (firstColumn) {
|
if (firstColumn) {
|
||||||
$focusedCellId = `new-${firstColumn.name}`
|
$focusedCellId = `new-${firstColumn.name}`
|
||||||
}
|
}
|
||||||
|
@ -72,74 +75,78 @@
|
||||||
dispatch("add-row")
|
dispatch("add-row")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleKeyPress = e => {
|
||||||
|
if (!isAdding) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => subscribe("add-row-inline", startAdding))
|
onMount(() => subscribe("add-row-inline", startAdding))
|
||||||
|
onMount(() => {
|
||||||
|
document.addEventListener("keydown", handleKeyPress)
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("keydown", handleKeyPress)
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Only show new row functionality if we have any columns -->
|
<!-- Only show new row functionality if we have any columns -->
|
||||||
{#if isAdding}
|
{#if isAdding}
|
||||||
<div class="container" transition:fly={{ y: 20, duration: 130 }}>
|
<div class="container">
|
||||||
<div class="content" class:above-scrollbar={$showHScrollbar}>
|
<div
|
||||||
<div
|
class="sticky-column"
|
||||||
class="new-row"
|
transition:fade={{ duration: 130 }}
|
||||||
on:mouseenter={() => ($hoveredRowId = "new")}
|
style="flex: 0 0 {width}px"
|
||||||
on:mouseleave={() => ($hoveredRowId = null)}
|
class:scrolled={$scrollLeft > 0}
|
||||||
>
|
>
|
||||||
<div
|
<GridCell width={GutterWidth} {rowHovered} rowFocused>
|
||||||
class="sticky-column"
|
<div class="gutter">
|
||||||
style="flex: 0 0 {width}px"
|
<div class="number">1</div>
|
||||||
class:scrolled={$scrollLeft > 0}
|
{#if $config.allowExpandRows}
|
||||||
>
|
<Icon name="Maximize" size="S" hoverable on:click={addViaModal} />
|
||||||
<GridCell width={GutterWidth} {rowHovered} rowFocused>
|
|
||||||
<div class="gutter">
|
|
||||||
<div class="number">1</div>
|
|
||||||
{#if $config.allowExpandRows}
|
|
||||||
<Icon
|
|
||||||
name="Maximize"
|
|
||||||
size="S"
|
|
||||||
hoverable
|
|
||||||
on:click={addViaModal}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</GridCell>
|
|
||||||
{#if $stickyColumn}
|
|
||||||
{@const cellId = `new-${$stickyColumn.name}`}
|
|
||||||
<DataCell
|
|
||||||
{cellId}
|
|
||||||
rowFocused
|
|
||||||
column={$stickyColumn}
|
|
||||||
row={newRow}
|
|
||||||
focused={$focusedCellId === cellId}
|
|
||||||
width={$stickyColumn.width}
|
|
||||||
{updateValue}
|
|
||||||
rowIdx={0}
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
</GridCell>
|
||||||
<GridScrollWrapper scrollHorizontally wheelInteractive>
|
{#if $stickyColumn}
|
||||||
<div class="row">
|
{@const cellId = `new-${$stickyColumn.name}`}
|
||||||
{#each $visibleColumns as column}
|
<DataCell
|
||||||
{@const cellId = `new-${column.name}`}
|
{cellId}
|
||||||
{#key cellId}
|
rowFocused
|
||||||
<DataCell
|
column={$stickyColumn}
|
||||||
{cellId}
|
row={newRow}
|
||||||
{column}
|
focused={$focusedCellId === cellId}
|
||||||
row={newRow}
|
width={$stickyColumn.width}
|
||||||
{rowHovered}
|
{updateValue}
|
||||||
focused={$focusedCellId === cellId}
|
rowIdx={0}
|
||||||
{rowFocused}
|
/>
|
||||||
width={column.width}
|
{/if}
|
||||||
{updateValue}
|
|
||||||
rowIdx={0}
|
|
||||||
/>
|
|
||||||
{/key}
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</GridScrollWrapper>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons">
|
<div class="normal-columns" transition:fade={{ duration: 130 }}>
|
||||||
|
<GridScrollWrapper scrollHorizontally wheelInteractive>
|
||||||
|
<div class="row">
|
||||||
|
{#each $renderedColumns as column}
|
||||||
|
{@const cellId = `new-${column.name}`}
|
||||||
|
{#key cellId}
|
||||||
|
<DataCell
|
||||||
|
{cellId}
|
||||||
|
{column}
|
||||||
|
{rowFocused}
|
||||||
|
{rowHovered}
|
||||||
|
{updateValue}
|
||||||
|
row={newRow}
|
||||||
|
focused={$focusedCellId === cellId}
|
||||||
|
width={column.width}
|
||||||
|
rowIdx={0}
|
||||||
|
/>
|
||||||
|
{/key}
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</GridScrollWrapper>
|
||||||
|
</div>
|
||||||
|
<div class="buttons" transition:fade={{ duration: 130 }}>
|
||||||
<Button size="M" cta on:click={addRow}>Save</Button>
|
<Button size="M" cta on:click={addRow}>Save</Button>
|
||||||
<Button size="M" secondary newStyles on:click={cancel}>Cancel</Button>
|
<Button size="M" secondary newStyles on:click={cancel}>Cancel</Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -148,17 +155,22 @@
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.container {
|
.container {
|
||||||
pointer-events: none;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: var(--row-height);
|
top: var(--default-row-height);
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-bottom: 800px;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: row;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
.container:before {
|
.container :global(.cell) {
|
||||||
|
--cell-background: var(--spectrum-global-color-gray-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add overlays independently behind both separate z-indexed column containers */
|
||||||
|
.sticky-column:before,
|
||||||
|
.normal-columns:before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: "";
|
content: "";
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -167,56 +179,17 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: var(--cell-background);
|
background: var(--cell-background);
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
pointer-events: all;
|
|
||||||
background: var(--background);
|
|
||||||
border-bottom: var(--cell-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.new-row {
|
|
||||||
display: flex;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
transition: margin-bottom 130ms ease-out;
|
|
||||||
}
|
|
||||||
.new-row :global(.cell) {
|
|
||||||
--cell-background: var(--background) !important;
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sticky column styles */
|
||||||
.sticky-column {
|
.sticky-column {
|
||||||
display: flex;
|
display: flex;
|
||||||
z-index: 1;
|
z-index: 2;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
/* Don't show borders between cells in the sticky column */
|
|
||||||
.sticky-column :global(.cell:not(:last-child)) {
|
.sticky-column :global(.cell:not(:last-child)) {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
|
||||||
width: 0;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add shadow when scrolled */
|
|
||||||
.sticky-column.scrolled {
|
|
||||||
/*box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.1);*/
|
|
||||||
}
|
|
||||||
.sticky-column.scrolled:after {
|
|
||||||
content: "";
|
|
||||||
width: 10px;
|
|
||||||
height: 100%;
|
|
||||||
background: linear-gradient(to right, rgba(0, 0, 0, 0.05), transparent);
|
|
||||||
left: 100%;
|
|
||||||
top: 0;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Styles for gutter */
|
|
||||||
.gutter {
|
.gutter {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
@ -225,17 +198,6 @@
|
||||||
grid-template-columns: 1fr auto;
|
grid-template-columns: 1fr auto;
|
||||||
gap: var(--cell-spacing);
|
gap: var(--cell-spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Floating buttons */
|
|
||||||
.buttons {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 8px;
|
|
||||||
margin: 24px 0 0 var(--gutter-width);
|
|
||||||
pointer-events: all;
|
|
||||||
align-self: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.number {
|
.number {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -243,4 +205,25 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: var(--spectrum-global-color-gray-500);
|
color: var(--spectrum-global-color-gray-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Normal column styles */
|
||||||
|
.normal-columns {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
width: 0;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Floating buttons */
|
||||||
|
.buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 8px;
|
||||||
|
pointer-events: all;
|
||||||
|
z-index: 2;
|
||||||
|
position: absolute;
|
||||||
|
top: calc(var(--row-height) + 24px);
|
||||||
|
left: var(--gutter-width);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
stickyColumn,
|
stickyColumn,
|
||||||
focusedCellAPI,
|
focusedCellAPI,
|
||||||
clipboard,
|
clipboard,
|
||||||
|
dispatch,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
// Global key listener which intercepts all key events
|
// Global key listener which intercepts all key events
|
||||||
|
@ -19,6 +20,9 @@
|
||||||
if (e.key === "Tab") {
|
if (e.key === "Tab") {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
focusFirstCell()
|
focusFirstCell()
|
||||||
|
} else if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
|
||||||
|
e.preventDefault()
|
||||||
|
dispatch("add-row-inline")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -58,6 +62,8 @@
|
||||||
clipboard.actions.paste()
|
clipboard.actions.paste()
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case "Enter":
|
||||||
|
dispatch("add-row-inline")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
|
|
Loading…
Reference in New Issue