Add basic keyboard interactions to dataspaces
This commit is contained in:
parent
045d0c89af
commit
48309349ae
6 changed files with 99 additions and 10 deletions
|
@ -0,0 +1,68 @@
|
|||
<script>
|
||||
import { getContext, onMount } from "svelte"
|
||||
|
||||
const { rows, selectedCellId, columns, selectedCellRow } = getContext("sheet")
|
||||
|
||||
const handleKeyDown = e => {
|
||||
switch (e.key) {
|
||||
case "ArrowLeft":
|
||||
changeSelectedColumn(-1)
|
||||
break
|
||||
case "ArrowRight":
|
||||
changeSelectedColumn(1)
|
||||
break
|
||||
case "ArrowUp":
|
||||
changeSelectedRow(-1)
|
||||
break
|
||||
case "ArrowDown":
|
||||
changeSelectedRow(1)
|
||||
break
|
||||
case "Delete":
|
||||
deleteSelectedCell()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const changeSelectedColumn = delta => {
|
||||
const cellId = $selectedCellId
|
||||
if (!cellId) {
|
||||
return
|
||||
}
|
||||
const cols = $columns
|
||||
const split = cellId.split("-")
|
||||
const columnName = split[1]
|
||||
const column = cols.findIndex(col => col.name === columnName)
|
||||
const newColumn = cols[column + delta]
|
||||
if (newColumn) {
|
||||
$selectedCellId = `${split[0]}-${newColumn.name}`
|
||||
}
|
||||
}
|
||||
|
||||
const changeSelectedRow = delta => {
|
||||
const row = $selectedCellRow
|
||||
const cellId = $selectedCellId
|
||||
if (!row) {
|
||||
return
|
||||
}
|
||||
const newRow = $rows[row.__idx + delta]
|
||||
if (newRow) {
|
||||
const split = cellId.split("-")
|
||||
$selectedCellId = `${newRow._id}-${split[1]}`
|
||||
}
|
||||
}
|
||||
|
||||
const deleteSelectedCell = () => {
|
||||
if (!$selectedCellId) {
|
||||
return
|
||||
}
|
||||
const [rowId, column] = $selectedCellId.split("-")
|
||||
rows.actions.updateRow(rowId, column, null)
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
document.addEventListener("keydown", handleKeyDown)
|
||||
return () => {
|
||||
document.removeEventListener("keydown", handleKeyDown)
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -9,7 +9,7 @@
|
|||
import { createColumnsStores } from "./stores/columns"
|
||||
import { createScrollStores } from "./stores/scroll"
|
||||
import { createBoundsStores } from "./stores/bounds"
|
||||
import { createInterfaceStores } from "./stores/interface"
|
||||
import { createUIStores } from "./stores/ui"
|
||||
export { createUserStores } from "./stores/users"
|
||||
import { createWebsocket } from "./websocket"
|
||||
import { createUserStores } from "./stores/users"
|
||||
|
@ -23,6 +23,8 @@
|
|||
import MenuOverlay from "./MenuOverlay.svelte"
|
||||
import StickyColumn from "./StickyColumn.svelte"
|
||||
import UserAvatars from "./UserAvatars.svelte"
|
||||
import KeyboardManager from "./KeyboardManager.svelte"
|
||||
import { clickOutside } from "@budibase/bbui"
|
||||
|
||||
export let API
|
||||
export let tableId
|
||||
|
@ -60,12 +62,12 @@
|
|||
context = { ...context, ...createScrollStores(context) }
|
||||
context = { ...context, ...createViewportStores(context) }
|
||||
context = { ...context, ...createReorderStores(context) }
|
||||
context = { ...context, ...createInterfaceStores(context) }
|
||||
context = { ...context, ...createUIStores(context) }
|
||||
context = { ...context, ...createUserStores(context) }
|
||||
context = { ...context, ...createMenuStores(context) }
|
||||
|
||||
// Reference some stores for local use
|
||||
const { isResizing, isReordering } = context
|
||||
const { isResizing, isReordering, ui } = context
|
||||
|
||||
// Keep config store up to date
|
||||
$: config.set({
|
||||
|
@ -88,10 +90,11 @@
|
|||
|
||||
<div
|
||||
class="sheet"
|
||||
id="sheet-{rand}"
|
||||
class:is-resizing={$isResizing}
|
||||
class:is-reordering={$isReordering}
|
||||
use:clickOutside={ui.actions.blur}
|
||||
style="--cell-height:{cellHeight}px;"
|
||||
id="sheet-{rand}"
|
||||
>
|
||||
<div class="controls">
|
||||
<div class="controls-left">
|
||||
|
@ -112,6 +115,7 @@
|
|||
<ScrollOverlay />
|
||||
<MenuOverlay />
|
||||
</div>
|
||||
<KeyboardManager />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
value={row[column.name]}
|
||||
schema={column.schema}
|
||||
selected={$selectedCellId === cellId}
|
||||
onChange={val => rows.actions.updateRow(row._id, column, val)}
|
||||
onChange={val => rows.actions.updateRow(row._id, column.name, val)}
|
||||
readonly={column.schema.autocolumn}
|
||||
/>
|
||||
</SheetCell>
|
||||
|
|
|
@ -134,7 +134,7 @@
|
|||
schema={$stickyColumn.schema}
|
||||
selected={$selectedCellId === cellId}
|
||||
onChange={val =>
|
||||
rows.actions.updateRow(row._id, $stickyColumn, val)}
|
||||
rows.actions.updateRow(row._id, $stickyColumn.name, val)}
|
||||
readonly={$stickyColumn.schema.autocolumn}
|
||||
/>
|
||||
</SheetCell>
|
||||
|
|
|
@ -169,12 +169,12 @@ export const createRowsStore = context => {
|
|||
const $rows = get(rows)
|
||||
const index = $rows.findIndex(x => x._id === rowId)
|
||||
const row = $rows[index]
|
||||
if (index === -1 || row?.[column.name] === value) {
|
||||
if (index === -1 || row?.[column] === value) {
|
||||
return
|
||||
}
|
||||
|
||||
// Immediately update state so that the change is reflected
|
||||
let newRow = { ...row, [column.name]: value }
|
||||
let newRow = { ...row, [column]: value }
|
||||
rows.update(state => {
|
||||
state[index] = { ...newRow }
|
||||
return state
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { writable, get, derived } from "svelte/store"
|
||||
|
||||
export const createInterfaceStores = context => {
|
||||
export const createUIStores = context => {
|
||||
const { rows, rowLookupMap } = context
|
||||
const selectedCellId = writable(null)
|
||||
const selectedRows = writable({})
|
||||
|
@ -62,5 +62,22 @@ export const createInterfaceStores = context => {
|
|||
}
|
||||
})
|
||||
|
||||
return { selectedCellId, selectedRows, hoveredRowId, selectedCellRow }
|
||||
// Callback when leaving the sheet, deselecting all focussed or selected items
|
||||
const blur = () => {
|
||||
selectedCellId.set(null)
|
||||
selectedRows.set({})
|
||||
hoveredRowId.set(null)
|
||||
}
|
||||
|
||||
return {
|
||||
selectedCellId,
|
||||
selectedRows,
|
||||
hoveredRowId,
|
||||
selectedCellRow,
|
||||
ui: {
|
||||
actions: {
|
||||
blur,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue