Merge pull request #10429 from Budibase/more-grid-tweaks
More grid improvements
This commit is contained in:
commit
0769e332a6
|
@ -19,6 +19,7 @@
|
||||||
export let updateValue = rows.actions.updateValue
|
export let updateValue = rows.actions.updateValue
|
||||||
export let invertX = false
|
export let invertX = false
|
||||||
export let invertY = false
|
export let invertY = false
|
||||||
|
export let contentLines = 1
|
||||||
|
|
||||||
const emptyError = writable(null)
|
const emptyError = writable(null)
|
||||||
|
|
||||||
|
@ -84,5 +85,7 @@
|
||||||
{readonly}
|
{readonly}
|
||||||
{invertY}
|
{invertY}
|
||||||
{invertX}
|
{invertX}
|
||||||
|
{contentLines}
|
||||||
/>
|
/>
|
||||||
|
<slot />
|
||||||
</GridCell>
|
</GridCell>
|
||||||
|
|
|
@ -117,6 +117,9 @@
|
||||||
.cell.error {
|
.cell.error {
|
||||||
--cell-color: var(--spectrum-global-color-red-500);
|
--cell-color: var(--spectrum-global-color-red-500);
|
||||||
}
|
}
|
||||||
|
.cell.readonly {
|
||||||
|
--cell-color: var(--spectrum-global-color-gray-600);
|
||||||
|
}
|
||||||
.cell:not(.focused) {
|
.cell:not(.focused) {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
$: sortedBy = column.name === $sort.column
|
$: sortedBy = column.name === $sort.column
|
||||||
$: canMoveLeft = orderable && idx > 0
|
$: canMoveLeft = orderable && idx > 0
|
||||||
$: canMoveRight = orderable && idx < $renderedColumns.length - 1
|
$: canMoveRight = orderable && idx < $renderedColumns.length - 1
|
||||||
|
$: ascendingLabel = column.schema?.type === "number" ? "low-high" : "A-Z"
|
||||||
|
$: descendingLabel = column.schema?.type === "number" ? "high-low" : "Z-A"
|
||||||
|
|
||||||
const editColumn = () => {
|
const editColumn = () => {
|
||||||
dispatch("edit-column", column.schema)
|
dispatch("edit-column", column.schema)
|
||||||
|
@ -179,14 +181,14 @@
|
||||||
on:click={sortAscending}
|
on:click={sortAscending}
|
||||||
disabled={column.name === $sort.column && $sort.order === "ascending"}
|
disabled={column.name === $sort.column && $sort.order === "ascending"}
|
||||||
>
|
>
|
||||||
Sort A-Z
|
Sort {ascendingLabel}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="SortOrderDown"
|
icon="SortOrderDown"
|
||||||
on:click={sortDescending}
|
on:click={sortDescending}
|
||||||
disabled={column.name === $sort.column && $sort.order === "descending"}
|
disabled={column.name === $sort.column && $sort.order === "descending"}
|
||||||
>
|
>
|
||||||
Sort Z-A
|
Sort {descendingLabel}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem disabled={!canMoveLeft} icon="ChevronLeft" on:click={moveLeft}>
|
<MenuItem disabled={!canMoveLeft} icon="ChevronLeft" on:click={moveLeft}>
|
||||||
Move left
|
Move left
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
export let api
|
export let api
|
||||||
export let invertX = false
|
export let invertX = false
|
||||||
export let invertY = false
|
export let invertY = false
|
||||||
|
export let contentLines = 1
|
||||||
|
|
||||||
let isOpen = false
|
let isOpen = false
|
||||||
let focusedOptionIdx = null
|
let focusedOptionIdx = null
|
||||||
|
@ -86,7 +87,11 @@
|
||||||
class:open
|
class:open
|
||||||
on:click|self={editable ? open : null}
|
on:click|self={editable ? open : null}
|
||||||
>
|
>
|
||||||
<div class="values" on:click={editable ? open : null}>
|
<div
|
||||||
|
class="values"
|
||||||
|
class:wrap={contentLines > 1}
|
||||||
|
on:click={editable ? open : null}
|
||||||
|
>
|
||||||
{#each values as val}
|
{#each values as val}
|
||||||
{@const color = getOptionColor(val)}
|
{@const color = getOptionColor(val)}
|
||||||
{#if color}
|
{#if color}
|
||||||
|
@ -160,6 +165,9 @@
|
||||||
grid-row-gap: var(--cell-padding);
|
grid-row-gap: var(--cell-padding);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: var(--cell-padding);
|
padding: var(--cell-padding);
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
.values.wrap {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.text {
|
.text {
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
export let onChange
|
export let onChange
|
||||||
export let invertX = false
|
export let invertX = false
|
||||||
export let invertY = false
|
export let invertY = false
|
||||||
|
export let contentLines = 1
|
||||||
|
|
||||||
const { API, dispatch } = getContext("grid")
|
const { API, dispatch } = getContext("grid")
|
||||||
const color = getColor(0)
|
const color = getColor(0)
|
||||||
|
@ -243,7 +244,11 @@
|
||||||
|
|
||||||
<div class="wrapper" class:editable class:focused style="--color:{color};">
|
<div class="wrapper" class:editable class:focused style="--color:{color};">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="values" on:wheel={e => (focused ? e.stopPropagation() : null)}>
|
<div
|
||||||
|
class="values"
|
||||||
|
class:wrap={editable || contentLines > 1}
|
||||||
|
on:wheel={e => (focused ? e.stopPropagation() : null)}
|
||||||
|
>
|
||||||
{#each value || [] as relationship, idx}
|
{#each value || [] as relationship, idx}
|
||||||
{#if relationship.primaryDisplay}
|
{#if relationship.primaryDisplay}
|
||||||
<div class="badge">
|
<div class="badge">
|
||||||
|
@ -376,6 +381,9 @@
|
||||||
grid-row-gap: var(--cell-padding);
|
grid-row-gap: var(--cell-padding);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: var(--cell-padding);
|
padding: var(--cell-padding);
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
.values.wrap {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.count {
|
.count {
|
||||||
|
|
|
@ -3,16 +3,13 @@
|
||||||
import { ActionButton, Popover, Select } from "@budibase/bbui"
|
import { ActionButton, Popover, Select } from "@budibase/bbui"
|
||||||
|
|
||||||
const { sort, columns, stickyColumn } = getContext("grid")
|
const { sort, columns, stickyColumn } = getContext("grid")
|
||||||
const orderOptions = [
|
|
||||||
{ label: "A-Z", value: "ascending" },
|
|
||||||
{ label: "Z-A", value: "descending" },
|
|
||||||
]
|
|
||||||
|
|
||||||
let open = false
|
let open = false
|
||||||
let anchor
|
let anchor
|
||||||
|
|
||||||
$: columnOptions = getColumnOptions($stickyColumn, $columns)
|
$: columnOptions = getColumnOptions($stickyColumn, $columns)
|
||||||
$: checkValidSortColumn($sort.column, $stickyColumn, $columns)
|
$: checkValidSortColumn($sort.column, $stickyColumn, $columns)
|
||||||
|
$: orderOptions = getOrderOptions($sort.column, columnOptions)
|
||||||
|
|
||||||
const getColumnOptions = (stickyColumn, columns) => {
|
const getColumnOptions = (stickyColumn, columns) => {
|
||||||
let options = []
|
let options = []
|
||||||
|
@ -20,6 +17,7 @@
|
||||||
options.push({
|
options.push({
|
||||||
label: stickyColumn.label || stickyColumn.name,
|
label: stickyColumn.label || stickyColumn.name,
|
||||||
value: stickyColumn.name,
|
value: stickyColumn.name,
|
||||||
|
type: stickyColumn.schema?.type,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
|
@ -27,10 +25,25 @@
|
||||||
...columns.map(col => ({
|
...columns.map(col => ({
|
||||||
label: col.label || col.name,
|
label: col.label || col.name,
|
||||||
value: col.name,
|
value: col.name,
|
||||||
|
type: col.schema?.type,
|
||||||
})),
|
})),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getOrderOptions = (column, columnOptions) => {
|
||||||
|
const type = columnOptions.find(col => col.value === column)?.type
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: type === "number" ? "Low-high" : "A-Z",
|
||||||
|
value: "ascending",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: type === "number" ? "High-low" : "Z-A",
|
||||||
|
value: "descending",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
const updateSortColumn = e => {
|
const updateSortColumn = e => {
|
||||||
sort.update(state => ({
|
sort.update(state => ({
|
||||||
...state,
|
...state,
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
selectedCellMap,
|
selectedCellMap,
|
||||||
focusedRow,
|
focusedRow,
|
||||||
columnHorizontalInversionIndex,
|
columnHorizontalInversionIndex,
|
||||||
|
contentLines,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
$: rowSelected = !!$selectedRows[row._id]
|
$: rowSelected = !!$selectedRows[row._id]
|
||||||
|
@ -44,6 +45,7 @@
|
||||||
focused={$focusedCellId === cellId}
|
focused={$focusedCellId === cellId}
|
||||||
selectedUser={$selectedCellMap[cellId]}
|
selectedUser={$selectedCellMap[cellId]}
|
||||||
width={column.width}
|
width={column.width}
|
||||||
|
contentLines={$contentLines}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
<script>
|
||||||
|
export let keybind
|
||||||
|
export let padded = false
|
||||||
|
export let overlay = false
|
||||||
|
|
||||||
|
$: parsedKeys = parseKeys(keybind)
|
||||||
|
|
||||||
|
const parseKeys = keybind => {
|
||||||
|
return keybind?.split("+").map(key => {
|
||||||
|
if (key.toLowerCase() === "ctrl") {
|
||||||
|
return navigator.platform.startsWith("Mac") ? "⌘" : key
|
||||||
|
} else if (key.toLowerCase() === "enter") {
|
||||||
|
return "↵"
|
||||||
|
}
|
||||||
|
return key
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="keys" class:padded class:overlay>
|
||||||
|
{#each parsedKeys as key}
|
||||||
|
<div class="key">
|
||||||
|
{key}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.keys {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
.keys.padded {
|
||||||
|
padding: var(--cell-padding);
|
||||||
|
}
|
||||||
|
.key {
|
||||||
|
padding: 2px 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
background-color: var(--spectrum-global-color-gray-200);
|
||||||
|
color: var(--spectrum-global-color-gray-700);
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.overlay .key {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -7,6 +7,7 @@
|
||||||
import { GutterWidth } from "../lib/constants"
|
import { GutterWidth } from "../lib/constants"
|
||||||
import { NewRowID } from "../lib/constants"
|
import { NewRowID } from "../lib/constants"
|
||||||
import GutterCell from "../cells/GutterCell.svelte"
|
import GutterCell from "../cells/GutterCell.svelte"
|
||||||
|
import KeyboardShortcut from "./KeyboardShortcut.svelte"
|
||||||
|
|
||||||
const {
|
const {
|
||||||
hoveredRowId,
|
hoveredRowId,
|
||||||
|
@ -27,13 +28,14 @@
|
||||||
columnHorizontalInversionIndex,
|
columnHorizontalInversionIndex,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
|
let visible = false
|
||||||
let isAdding = false
|
let isAdding = false
|
||||||
let newRow = {}
|
let newRow = {}
|
||||||
let offset = 0
|
let offset = 0
|
||||||
|
|
||||||
$: firstColumn = $stickyColumn || $renderedColumns[0]
|
$: firstColumn = $stickyColumn || $renderedColumns[0]
|
||||||
$: width = GutterWidth + ($stickyColumn?.width || 0)
|
$: width = GutterWidth + ($stickyColumn?.width || 0)
|
||||||
$: $tableId, (isAdding = false)
|
$: $tableId, (visible = false)
|
||||||
$: invertY = shouldInvertY(offset, $rowVerticalInversionIndex, $renderedRows)
|
$: invertY = shouldInvertY(offset, $rowVerticalInversionIndex, $renderedRows)
|
||||||
|
|
||||||
const shouldInvertY = (offset, inversionIndex, rows) => {
|
const shouldInvertY = (offset, inversionIndex, rows) => {
|
||||||
|
@ -45,7 +47,8 @@
|
||||||
|
|
||||||
const addRow = async () => {
|
const addRow = async () => {
|
||||||
// Blur the active cell and tick to let final value updates propagate
|
// Blur the active cell and tick to let final value updates propagate
|
||||||
$focusedCellAPI?.blur()
|
isAdding = true
|
||||||
|
$focusedCellId = null
|
||||||
await tick()
|
await tick()
|
||||||
|
|
||||||
// Create row
|
// Create row
|
||||||
|
@ -60,17 +63,19 @@
|
||||||
$focusedCellId = `${savedRow._id}-${firstColumn.name}`
|
$focusedCellId = `${savedRow._id}-${firstColumn.name}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
isAdding = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const clear = () => {
|
const clear = () => {
|
||||||
isAdding = false
|
isAdding = false
|
||||||
|
visible = false
|
||||||
$focusedCellId = null
|
$focusedCellId = null
|
||||||
$hoveredRowId = null
|
$hoveredRowId = null
|
||||||
document.removeEventListener("keydown", handleKeyPress)
|
document.removeEventListener("keydown", handleKeyPress)
|
||||||
}
|
}
|
||||||
|
|
||||||
const startAdding = async () => {
|
const startAdding = async () => {
|
||||||
if (isAdding) {
|
if (visible) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +100,7 @@
|
||||||
|
|
||||||
// Update state and select initial cell
|
// Update state and select initial cell
|
||||||
newRow = {}
|
newRow = {}
|
||||||
isAdding = true
|
visible = true
|
||||||
$hoveredRowId = NewRowID
|
$hoveredRowId = NewRowID
|
||||||
if (firstColumn) {
|
if (firstColumn) {
|
||||||
$focusedCellId = `${NewRowID}-${firstColumn.name}`
|
$focusedCellId = `${NewRowID}-${firstColumn.name}`
|
||||||
|
@ -115,7 +120,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleKeyPress = e => {
|
const handleKeyPress = e => {
|
||||||
if (!isAdding) {
|
if (!visible) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (e.key === "Escape") {
|
if (e.key === "Escape") {
|
||||||
|
@ -137,7 +142,7 @@
|
||||||
</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 visible}
|
||||||
<div
|
<div
|
||||||
class="container"
|
class="container"
|
||||||
class:floating={offset > 0}
|
class:floating={offset > 0}
|
||||||
|
@ -148,6 +153,9 @@
|
||||||
<div class="sticky-column" transition:fade={{ duration: 130 }}>
|
<div class="sticky-column" transition:fade={{ duration: 130 }}>
|
||||||
<GutterCell on:expand={addViaModal} rowHovered>
|
<GutterCell on:expand={addViaModal} rowHovered>
|
||||||
<Icon name="Add" color="var(--spectrum-global-color-gray-500)" />
|
<Icon name="Add" color="var(--spectrum-global-color-gray-500)" />
|
||||||
|
{#if isAdding}
|
||||||
|
<div in:fade={{ duration: 130 }} class="loading-overlay" />
|
||||||
|
{/if}
|
||||||
</GutterCell>
|
</GutterCell>
|
||||||
{#if $stickyColumn}
|
{#if $stickyColumn}
|
||||||
{@const cellId = `${NewRowID}-${$stickyColumn.name}`}
|
{@const cellId = `${NewRowID}-${$stickyColumn.name}`}
|
||||||
|
@ -161,7 +169,14 @@
|
||||||
{updateValue}
|
{updateValue}
|
||||||
rowIdx={0}
|
rowIdx={0}
|
||||||
{invertY}
|
{invertY}
|
||||||
/>
|
>
|
||||||
|
{#if $stickyColumn?.schema?.autocolumn}
|
||||||
|
<div class="readonly-overlay">Can't edit auto column</div>
|
||||||
|
{/if}
|
||||||
|
{#if isAdding}
|
||||||
|
<div in:fade={{ duration: 130 }} class="loading-overlay" />
|
||||||
|
{/if}
|
||||||
|
</DataCell>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="normal-columns" transition:fade={{ duration: 130 }}>
|
<div class="normal-columns" transition:fade={{ duration: 130 }}>
|
||||||
|
@ -181,15 +196,32 @@
|
||||||
rowIdx={0}
|
rowIdx={0}
|
||||||
invertX={columnIdx >= $columnHorizontalInversionIndex}
|
invertX={columnIdx >= $columnHorizontalInversionIndex}
|
||||||
{invertY}
|
{invertY}
|
||||||
/>
|
>
|
||||||
|
{#if column?.schema?.autocolumn}
|
||||||
|
<div class="readonly-overlay">Can't edit auto column</div>
|
||||||
|
{/if}
|
||||||
|
{#if isAdding}
|
||||||
|
<div in:fade={{ duration: 130 }} class="loading-overlay" />
|
||||||
|
{/if}
|
||||||
|
</DataCell>
|
||||||
{/key}
|
{/key}
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</GridScrollWrapper>
|
</GridScrollWrapper>
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons" transition:fade={{ duration: 130 }}>
|
<div class="buttons" transition:fade={{ duration: 130 }}>
|
||||||
<Button size="M" cta on:click={addRow}>Save</Button>
|
<Button size="M" cta on:click={addRow} disabled={isAdding}>
|
||||||
<Button size="M" secondary newStyles on:click={clear}>Cancel</Button>
|
<div class="button-with-keys">
|
||||||
|
Save
|
||||||
|
<KeyboardShortcut overlay keybind="Ctrl+Enter" />
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
<Button size="M" secondary newStyles on:click={clear}>
|
||||||
|
<div class="button-with-keys">
|
||||||
|
Cancel
|
||||||
|
<KeyboardShortcut overlay keybind="Esc" />
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -240,6 +272,14 @@
|
||||||
top: calc(var(--row-height) + var(--offset) + 24px);
|
top: calc(var(--row-height) + var(--offset) + 24px);
|
||||||
left: var(--gutter-width);
|
left: var(--gutter-width);
|
||||||
}
|
}
|
||||||
|
.button-with-keys {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.button-with-keys :global(> div) {
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Sticky column styles */
|
/* Sticky column styles */
|
||||||
.sticky-column {
|
.sticky-column {
|
||||||
|
@ -262,4 +302,33 @@
|
||||||
width: 0;
|
width: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Readonly cell overlay */
|
||||||
|
.readonly-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: var(--row-height);
|
||||||
|
width: 100%;
|
||||||
|
padding: var(--cell-padding);
|
||||||
|
font-style: italic;
|
||||||
|
color: var(--spectrum-global-color-gray-600);
|
||||||
|
z-index: 1;
|
||||||
|
user-select: none;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Overlay while row is being added */
|
||||||
|
.loading-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: var(--row-height);
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
background: var(--spectrum-global-color-gray-400);
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import HeaderCell from "../cells/HeaderCell.svelte"
|
import HeaderCell from "../cells/HeaderCell.svelte"
|
||||||
import { GutterWidth, BlankRowID } from "../lib/constants"
|
import { GutterWidth, BlankRowID } from "../lib/constants"
|
||||||
import GutterCell from "../cells/GutterCell.svelte"
|
import GutterCell from "../cells/GutterCell.svelte"
|
||||||
|
import KeyboardShortcut from "./KeyboardShortcut.svelte"
|
||||||
|
|
||||||
const {
|
const {
|
||||||
rows,
|
rows,
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
focusedRow,
|
focusedRow,
|
||||||
scrollLeft,
|
scrollLeft,
|
||||||
dispatch,
|
dispatch,
|
||||||
|
contentLines,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
$: rowCount = $rows.length
|
$: rowCount = $rows.length
|
||||||
|
@ -85,6 +87,7 @@
|
||||||
selectedUser={$selectedCellMap[cellId]}
|
selectedUser={$selectedCellMap[cellId]}
|
||||||
width={$stickyColumn.width}
|
width={$stickyColumn.width}
|
||||||
column={$stickyColumn}
|
column={$stickyColumn}
|
||||||
|
contentLines={$contentLines}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -103,7 +106,9 @@
|
||||||
<GridCell
|
<GridCell
|
||||||
width={$stickyColumn.width}
|
width={$stickyColumn.width}
|
||||||
highlighted={$hoveredRowId === BlankRowID}
|
highlighted={$hoveredRowId === BlankRowID}
|
||||||
/>
|
>
|
||||||
|
<KeyboardShortcut padded keybind="Ctrl+Enter" />
|
||||||
|
</GridCell>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -15,8 +15,22 @@
|
||||||
selectedRows,
|
selectedRows,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
|
const ignoredOriginSelectors = [
|
||||||
|
".spectrum-Modal",
|
||||||
|
"#builder-side-panel-container",
|
||||||
|
]
|
||||||
|
|
||||||
// Global key listener which intercepts all key events
|
// Global key listener which intercepts all key events
|
||||||
const handleKeyDown = e => {
|
const handleKeyDown = e => {
|
||||||
|
// Avoid processing events sourced from certain origins
|
||||||
|
if (e.target?.closest) {
|
||||||
|
for (let selector of ignoredOriginSelectors) {
|
||||||
|
if (e.target.closest(selector)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If nothing selected avoid processing further key presses
|
// If nothing selected avoid processing further key presses
|
||||||
if (!$focusedCellId) {
|
if (!$focusedCellId) {
|
||||||
if (e.key === "Tab" || e.key?.startsWith("Arrow")) {
|
if (e.key === "Tab" || e.key?.startsWith("Arrow")) {
|
||||||
|
@ -60,11 +74,6 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid processing events sourced from modals
|
|
||||||
if (e.target?.closest?.(".spectrum-Modal")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
// Handle the key ourselves
|
// Handle the key ourselves
|
||||||
|
|
Loading…
Reference in New Issue