Add support for selecting multiple cells
This commit is contained in:
parent
8a8d835a1a
commit
7349910572
|
@ -3,13 +3,13 @@
|
||||||
--ink: #000000;
|
--ink: #000000;
|
||||||
|
|
||||||
/* Brand colours */
|
/* Brand colours */
|
||||||
--bb-coral: #FF4E4E;
|
--bb-coral: #ff4e4e;
|
||||||
--bb-coral-light: #F97777;
|
--bb-coral-light: #f97777;
|
||||||
--bb-indigo: #6E56FF;
|
--bb-indigo: #6e56ff;
|
||||||
--bb-indigo-light: #9F8FFF;
|
--bb-indigo-light: #9f8fff;
|
||||||
--bb-lime: #ECFFB5;
|
--bb-lime: #ecffb5;
|
||||||
--bb-forest-green: #053835;
|
--bb-forest-green: #053835;
|
||||||
--bb-beige: #F6EFEA;
|
--bb-beige: #f6efea;
|
||||||
|
|
||||||
--grey-1: #fafafa;
|
--grey-1: #fafafa;
|
||||||
--grey-2: #f5f5f5;
|
--grey-2: #f5f5f5;
|
||||||
|
@ -49,10 +49,10 @@
|
||||||
--rounded-medium: 8px;
|
--rounded-medium: 8px;
|
||||||
--rounded-large: 16px;
|
--rounded-large: 16px;
|
||||||
|
|
||||||
--font-sans: "Source Sans Pro", -apple-system, BlinkMacSystemFont, Segoe UI, "Inter",
|
--font-sans: "Source Sans Pro", -apple-system, BlinkMacSystemFont, Segoe UI,
|
||||||
"Helvetica Neue", Arial, "Noto Sans", sans-serif;
|
"Inter", "Helvetica Neue", Arial, "Noto Sans", sans-serif;
|
||||||
--font-accent: "Source Sans Pro", -apple-system, BlinkMacSystemFont, Segoe UI, "Inter",
|
--font-accent: "Source Sans Pro", -apple-system, BlinkMacSystemFont, Segoe UI,
|
||||||
"Helvetica Neue", Arial, "Noto Sans", sans-serif;
|
"Inter", "Helvetica Neue", Arial, "Noto Sans", sans-serif;
|
||||||
--font-serif: "Georgia", Cambria, Times New Roman, Times, serif;
|
--font-serif: "Georgia", Cambria, Times New Roman, Times, serif;
|
||||||
--font-mono: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
|
--font-mono: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
|
||||||
monospace;
|
monospace;
|
||||||
|
@ -111,7 +111,7 @@ a {
|
||||||
/* Custom theme additions */
|
/* Custom theme additions */
|
||||||
.spectrum--darkest {
|
.spectrum--darkest {
|
||||||
--drop-shadow: rgba(0, 0, 0, 0.6);
|
--drop-shadow: rgba(0, 0, 0, 0.6);
|
||||||
--spectrum-global-color-blue-100: rgb(28, 33, 43);
|
--spectrum-global-color-blue-100: rgb(30, 36, 50);
|
||||||
}
|
}
|
||||||
.spectrum--dark {
|
.spectrum--dark {
|
||||||
--drop-shadow: rgba(0, 0, 0, 0.3);
|
--drop-shadow: rgba(0, 0, 0, 0.3);
|
||||||
|
|
|
@ -4,12 +4,19 @@
|
||||||
import { getCellRenderer } from "../lib/renderers"
|
import { getCellRenderer } from "../lib/renderers"
|
||||||
import { derived, writable } from "svelte/store"
|
import { derived, writable } from "svelte/store"
|
||||||
|
|
||||||
const { rows, focusedCellId, focusedCellAPI, menu, config, validation } =
|
const {
|
||||||
getContext("grid")
|
rows,
|
||||||
|
focusedCellId,
|
||||||
|
focusedCellAPI,
|
||||||
|
menu,
|
||||||
|
config,
|
||||||
|
validation,
|
||||||
|
cellSelection,
|
||||||
|
} = getContext("grid")
|
||||||
|
|
||||||
export let highlighted
|
export let highlighted
|
||||||
export let selected
|
|
||||||
export let rowFocused
|
export let rowFocused
|
||||||
|
export let rowSelected
|
||||||
export let rowIdx
|
export let rowIdx
|
||||||
export let topRow = false
|
export let topRow = false
|
||||||
export let focused
|
export let focused
|
||||||
|
@ -20,6 +27,8 @@
|
||||||
export let updateValue = rows.actions.updateValue
|
export let updateValue = rows.actions.updateValue
|
||||||
export let contentLines = 1
|
export let contentLines = 1
|
||||||
export let hidden = false
|
export let hidden = false
|
||||||
|
export let isSelectingCells = false
|
||||||
|
export let selectedCells = {}
|
||||||
|
|
||||||
const emptyError = writable(null)
|
const emptyError = writable(null)
|
||||||
|
|
||||||
|
@ -43,6 +52,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Callbacks for cell selection
|
||||||
|
$: cellSelected = selectedCells[cellId]
|
||||||
|
$: updateSelectionCallback = isSelectingCells ? updateSelection : null
|
||||||
|
$: stopSelectionCallback = isSelectingCells ? stopSelection : null
|
||||||
|
|
||||||
const getErrorStore = (selected, cellId) => {
|
const getErrorStore = (selected, cellId) => {
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
return emptyError
|
return emptyError
|
||||||
|
@ -68,20 +82,38 @@
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const startSelection = e => {
|
||||||
|
if (e.button !== 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
focusedCellId.set(cellId)
|
||||||
|
cellSelection.actions.start(cellId)
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateSelection = e => {
|
||||||
|
cellSelection.actions.update(cellId)
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopSelection = e => {
|
||||||
|
cellSelection.actions.stop()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<GridCell
|
<GridCell
|
||||||
{highlighted}
|
{highlighted}
|
||||||
{selected}
|
|
||||||
{rowIdx}
|
{rowIdx}
|
||||||
{topRow}
|
{topRow}
|
||||||
{focused}
|
{focused}
|
||||||
{selectedUser}
|
{selectedUser}
|
||||||
{readonly}
|
{readonly}
|
||||||
{hidden}
|
{hidden}
|
||||||
|
selected={rowSelected || cellSelected}
|
||||||
error={$error}
|
error={$error}
|
||||||
on:click={() => focusedCellId.set(cellId)}
|
|
||||||
on:contextmenu={e => menu.actions.open(cellId, e)}
|
on:contextmenu={e => menu.actions.open(cellId, e)}
|
||||||
|
on:mousedown={startSelection}
|
||||||
|
on:mouseenter={updateSelectionCallback}
|
||||||
|
on:mouseup={stopSelectionCallback}
|
||||||
width={column.width}
|
width={column.width}
|
||||||
>
|
>
|
||||||
<svelte:component
|
<svelte:component
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
on:touchstart
|
on:touchstart
|
||||||
on:touchend
|
on:touchend
|
||||||
on:touchcancel
|
on:touchcancel
|
||||||
|
on:mouseenter
|
||||||
{style}
|
{style}
|
||||||
>
|
>
|
||||||
{#if error}
|
{#if error}
|
||||||
|
@ -155,6 +156,7 @@
|
||||||
.cell.focused.readonly {
|
.cell.focused.readonly {
|
||||||
--cell-background: var(--cell-background-hover);
|
--cell-background: var(--cell-background-hover);
|
||||||
}
|
}
|
||||||
|
.cell.selected.focused,
|
||||||
.cell.selected:not(.focused) {
|
.cell.selected:not(.focused) {
|
||||||
--cell-background: var(--spectrum-global-color-blue-100);
|
--cell-background: var(--spectrum-global-color-blue-100);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,14 @@
|
||||||
dispatch,
|
dispatch,
|
||||||
rows,
|
rows,
|
||||||
columnRenderMap,
|
columnRenderMap,
|
||||||
|
isSelectingCells,
|
||||||
|
selectedCells,
|
||||||
|
selectedCellCount,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
$: rowSelected = !!$selectedRows[row._id]
|
$: rowSelected = !!$selectedRows[row._id]
|
||||||
$: rowHovered = $hoveredRowId === row._id
|
$: rowHovered =
|
||||||
|
$hoveredRowId === row._id && (!$selectedCellCount || !$isSelectingCells)
|
||||||
$: rowFocused = $focusedRow?._id === row._id
|
$: rowFocused = $focusedRow?._id === row._id
|
||||||
$: reorderSource = $reorder.sourceColumn
|
$: reorderSource = $reorder.sourceColumn
|
||||||
</script>
|
</script>
|
||||||
|
@ -43,8 +47,8 @@
|
||||||
{column}
|
{column}
|
||||||
{row}
|
{row}
|
||||||
{rowFocused}
|
{rowFocused}
|
||||||
|
{rowSelected}
|
||||||
highlighted={rowHovered || rowFocused || reorderSource === column.name}
|
highlighted={rowHovered || rowFocused || reorderSource === column.name}
|
||||||
selected={rowSelected}
|
|
||||||
rowIdx={row.__idx}
|
rowIdx={row.__idx}
|
||||||
topRow={top}
|
topRow={top}
|
||||||
focused={$focusedCellId === cellId}
|
focused={$focusedCellId === cellId}
|
||||||
|
@ -52,6 +56,8 @@
|
||||||
width={column.width}
|
width={column.width}
|
||||||
contentLines={$contentLines}
|
contentLines={$contentLines}
|
||||||
hidden={!$columnRenderMap[column.name]}
|
hidden={!$columnRenderMap[column.name]}
|
||||||
|
isSelectingCells={$isSelectingCells}
|
||||||
|
selectedCells={$selectedCells}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
dispatch,
|
dispatch,
|
||||||
contentLines,
|
contentLines,
|
||||||
isDragging,
|
isDragging,
|
||||||
|
isSelectingCells,
|
||||||
|
selectedCells,
|
||||||
|
selectedCellCount,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
$: rowCount = $rows.length
|
$: rowCount = $rows.length
|
||||||
|
@ -70,7 +73,9 @@
|
||||||
<GridScrollWrapper scrollVertically attachHandlers>
|
<GridScrollWrapper scrollVertically attachHandlers>
|
||||||
{#each $renderedRows as row, idx}
|
{#each $renderedRows as row, idx}
|
||||||
{@const rowSelected = !!$selectedRows[row._id]}
|
{@const rowSelected = !!$selectedRows[row._id]}
|
||||||
{@const rowHovered = $hoveredRowId === row._id}
|
{@const rowHovered =
|
||||||
|
$hoveredRowId === row._id &&
|
||||||
|
(!$selectedCellCount || !$isSelectingCells)}
|
||||||
{@const rowFocused = $focusedRow?._id === row._id}
|
{@const rowFocused = $focusedRow?._id === row._id}
|
||||||
{@const cellId = getCellID(row._id, $stickyColumn?.name)}
|
{@const cellId = getCellID(row._id, $stickyColumn?.name)}
|
||||||
<div
|
<div
|
||||||
|
@ -85,7 +90,7 @@
|
||||||
{row}
|
{row}
|
||||||
{cellId}
|
{cellId}
|
||||||
{rowFocused}
|
{rowFocused}
|
||||||
selected={rowSelected}
|
{rowSelected}
|
||||||
highlighted={rowHovered || rowFocused}
|
highlighted={rowHovered || rowFocused}
|
||||||
rowIdx={row.__idx}
|
rowIdx={row.__idx}
|
||||||
topRow={idx === 0}
|
topRow={idx === 0}
|
||||||
|
@ -94,6 +99,8 @@
|
||||||
width={$stickyColumn.width}
|
width={$stickyColumn.width}
|
||||||
column={$stickyColumn}
|
column={$stickyColumn}
|
||||||
contentLines={$contentLines}
|
contentLines={$contentLines}
|
||||||
|
isSelectingCells={$isSelectingCells}
|
||||||
|
selectedCells={$selectedCells}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
notifications,
|
notifications,
|
||||||
hasBudibaseIdentifiers,
|
hasBudibaseIdentifiers,
|
||||||
selectedRowCount,
|
selectedRowCount,
|
||||||
selectedRows,
|
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
let anchor
|
let anchor
|
||||||
|
@ -83,6 +82,25 @@
|
||||||
>
|
>
|
||||||
Delete {$selectedRowCount} rows
|
Delete {$selectedRowCount} rows
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
{:else if $menu.multiCellMode}
|
||||||
|
<MenuItem
|
||||||
|
icon="Copy"
|
||||||
|
on:click={clipboard.actions.copy}
|
||||||
|
on:click={menu.actions.close}
|
||||||
|
>
|
||||||
|
Copy
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
icon="Paste"
|
||||||
|
disabled={$copiedCell == null || $focusedCellAPI?.isReadonly()}
|
||||||
|
on:click={clipboard.actions.paste}
|
||||||
|
on:click={menu.actions.close}
|
||||||
|
>
|
||||||
|
Paste
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem icon="Delete" disabled={isNewRow} on:click={() => {}}>
|
||||||
|
Delete
|
||||||
|
</MenuItem>
|
||||||
{:else}
|
{:else}
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="Copy"
|
icon="Copy"
|
||||||
|
|
|
@ -45,7 +45,7 @@ export const createStores = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deriveStores = context => {
|
export const deriveStores = context => {
|
||||||
const { columns, stickyColumn } = context
|
const { columns, stickyColumn, visibleColumns } = context
|
||||||
|
|
||||||
// Quick access to all columns
|
// Quick access to all columns
|
||||||
const allColumns = derived(
|
const allColumns = derived(
|
||||||
|
@ -67,9 +67,19 @@ export const deriveStores = context => {
|
||||||
return normalCols.length > 0
|
return normalCols.length > 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Derive a lookup map for column indices by name
|
||||||
|
const columnLookupMap = derived(visibleColumns, $visibleColumns => {
|
||||||
|
let map = {}
|
||||||
|
$visibleColumns.forEach((column, idx) => {
|
||||||
|
map[column.name] = idx
|
||||||
|
})
|
||||||
|
return map
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
allColumns,
|
allColumns,
|
||||||
hasNonAutoColumn,
|
hasNonAutoColumn,
|
||||||
|
columnLookupMap,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import * as Table from "./datasources/table"
|
||||||
import * as ViewV2 from "./datasources/viewV2"
|
import * as ViewV2 from "./datasources/viewV2"
|
||||||
import * as NonPlus from "./datasources/nonPlus"
|
import * as NonPlus from "./datasources/nonPlus"
|
||||||
import * as Cache from "./cache"
|
import * as Cache from "./cache"
|
||||||
|
import * as Selection from "./selection"
|
||||||
|
|
||||||
const DependencyOrderedStores = [
|
const DependencyOrderedStores = [
|
||||||
Sort,
|
Sort,
|
||||||
|
@ -44,6 +45,7 @@ const DependencyOrderedStores = [
|
||||||
Config,
|
Config,
|
||||||
Notifications,
|
Notifications,
|
||||||
Cache,
|
Cache,
|
||||||
|
Selection,
|
||||||
]
|
]
|
||||||
|
|
||||||
export const attachStores = context => {
|
export const attachStores = context => {
|
||||||
|
|
|
@ -3,10 +3,11 @@ import { parseCellID } from "../lib/utils"
|
||||||
|
|
||||||
export const createStores = () => {
|
export const createStores = () => {
|
||||||
const menu = writable({
|
const menu = writable({
|
||||||
x: 0,
|
left: 0,
|
||||||
y: 0,
|
top: 0,
|
||||||
visible: false,
|
visible: false,
|
||||||
selectedRow: null,
|
multiRowMode: false,
|
||||||
|
multiCellMode: false,
|
||||||
})
|
})
|
||||||
return {
|
return {
|
||||||
menu,
|
menu,
|
||||||
|
@ -14,8 +15,15 @@ export const createStores = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createActions = context => {
|
export const createActions = context => {
|
||||||
const { menu, focusedCellId, gridID, selectedRows, selectedRowCount } =
|
const {
|
||||||
context
|
menu,
|
||||||
|
focusedCellId,
|
||||||
|
gridID,
|
||||||
|
selectedRows,
|
||||||
|
selectedRowCount,
|
||||||
|
selectedCells,
|
||||||
|
selectedCellCount,
|
||||||
|
} = context
|
||||||
|
|
||||||
const open = (cellId, e) => {
|
const open = (cellId, e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
@ -32,7 +40,7 @@ export const createActions = context => {
|
||||||
const targetBounds = e.target.getBoundingClientRect()
|
const targetBounds = e.target.getBoundingClientRect()
|
||||||
const dataBounds = dataNode.getBoundingClientRect()
|
const dataBounds = dataNode.getBoundingClientRect()
|
||||||
|
|
||||||
// Check if there are multiple rows selected, and this is one of them
|
// Check if there are multiple rows selected, and if this is one of them
|
||||||
let multiRowMode = false
|
let multiRowMode = false
|
||||||
if (get(selectedRowCount) > 1) {
|
if (get(selectedRowCount) > 1) {
|
||||||
const rowId = parseCellID(cellId).id
|
const rowId = parseCellID(cellId).id
|
||||||
|
@ -41,8 +49,16 @@ export const createActions = context => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if there are multiple cells selected, and if this is one of them
|
||||||
|
let multiCellMode = false
|
||||||
|
if (!multiRowMode && get(selectedCellCount) > 1) {
|
||||||
|
if (get(selectedCells)[cellId]) {
|
||||||
|
multiCellMode = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only focus this cell if not in multi row mode
|
// Only focus this cell if not in multi row mode
|
||||||
if (!multiRowMode) {
|
if (!multiRowMode && !multiCellMode) {
|
||||||
focusedCellId.set(cellId)
|
focusedCellId.set(cellId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +67,7 @@ export const createActions = context => {
|
||||||
top: targetBounds.top - dataBounds.top + e.offsetY,
|
top: targetBounds.top - dataBounds.top + e.offsetY,
|
||||||
visible: true,
|
visible: true,
|
||||||
multiRowMode,
|
multiRowMode,
|
||||||
|
multiCellMode,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
import { derived, writable, get } from "svelte/store"
|
||||||
|
import { getCellID, parseCellID } from "../lib/utils"
|
||||||
|
|
||||||
|
export const createStores = () => {
|
||||||
|
const cellSelection = writable({
|
||||||
|
active: false,
|
||||||
|
sourceCellId: null,
|
||||||
|
targetCellId: null,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
cellSelection,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deriveStores = context => {
|
||||||
|
const { cellSelection, rowLookupMap, columnLookupMap, rows, visibleColumns } =
|
||||||
|
context
|
||||||
|
|
||||||
|
const isSelectingCells = derived(cellSelection, $cellSelection => {
|
||||||
|
return $cellSelection.active
|
||||||
|
})
|
||||||
|
|
||||||
|
const selectedCells = derived(
|
||||||
|
[cellSelection, rowLookupMap, columnLookupMap],
|
||||||
|
([$cellSelection, $rowLookupMap, $columnLookupMap]) => {
|
||||||
|
const { sourceCellId, targetCellId } = $cellSelection
|
||||||
|
if (!sourceCellId || !targetCellId || sourceCellId === targetCellId) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
const $rows = get(rows)
|
||||||
|
const $visibleColumns = get(visibleColumns)
|
||||||
|
|
||||||
|
// Get source and target row and column indices
|
||||||
|
const sourceInfo = parseCellID(sourceCellId)
|
||||||
|
const targetInfo = parseCellID(targetCellId)
|
||||||
|
|
||||||
|
// Row indices
|
||||||
|
const sourceRowIndex = $rowLookupMap[sourceInfo.id]
|
||||||
|
const targetRowIndex = $rowLookupMap[targetInfo.id]
|
||||||
|
const lowerRowIndex = Math.min(sourceRowIndex, targetRowIndex)
|
||||||
|
const upperRowIndex = Math.max(sourceRowIndex, targetRowIndex)
|
||||||
|
|
||||||
|
// Column indices
|
||||||
|
const sourceColIndex = $columnLookupMap[sourceInfo.field]
|
||||||
|
const targetColIndex = $columnLookupMap[targetInfo.field]
|
||||||
|
const lowerColIndex = Math.min(sourceColIndex, targetColIndex)
|
||||||
|
const upperColIndex = Math.max(sourceColIndex, targetColIndex)
|
||||||
|
|
||||||
|
// Build map of all cells inside these bounds
|
||||||
|
let map = {}
|
||||||
|
let rowId, colName, cellId
|
||||||
|
for (let rowIdx = lowerRowIndex; rowIdx <= upperRowIndex; rowIdx++) {
|
||||||
|
for (let colIdx = lowerColIndex; colIdx <= upperColIndex; colIdx++) {
|
||||||
|
rowId = $rows[rowIdx]._id
|
||||||
|
colName = $visibleColumns[colIdx].name
|
||||||
|
cellId = getCellID(rowId, colName)
|
||||||
|
map[cellId] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const selectedCellCount = derived(selectedCells, $selectedCells => {
|
||||||
|
return Object.keys($selectedCells).length
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
isSelectingCells,
|
||||||
|
selectedCells,
|
||||||
|
selectedCellCount,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createActions = context => {
|
||||||
|
const { cellSelection } = context
|
||||||
|
|
||||||
|
const startCellSelection = sourceCellId => {
|
||||||
|
cellSelection.set({
|
||||||
|
active: true,
|
||||||
|
sourceCellId,
|
||||||
|
targetCellId: sourceCellId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateCellSelection = targetCellId => {
|
||||||
|
cellSelection.update(state => ({
|
||||||
|
...state,
|
||||||
|
targetCellId,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopCellSelection = () => {
|
||||||
|
cellSelection.update(state => ({
|
||||||
|
...state,
|
||||||
|
active: false,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearCellSelection = () => {
|
||||||
|
cellSelection.set({
|
||||||
|
active: false,
|
||||||
|
sourceCellId: null,
|
||||||
|
targetCellId: null,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
cellSelection: {
|
||||||
|
...cellSelection,
|
||||||
|
actions: {
|
||||||
|
start: startCellSelection,
|
||||||
|
update: updateCellSelection,
|
||||||
|
stop: stopCellSelection,
|
||||||
|
clear: clearCellSelection,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initialise = context => {
|
||||||
|
const { selectedCellCount, selectedRowCount, selectedRows } = context
|
||||||
|
|
||||||
|
selectedCellCount.subscribe($selectedCellCount => {
|
||||||
|
if ($selectedCellCount && get(selectedRowCount)) {
|
||||||
|
selectedRows.set({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
|
@ -188,6 +188,9 @@ export const initialise = context => {
|
||||||
rowHeight,
|
rowHeight,
|
||||||
fixedRowHeight,
|
fixedRowHeight,
|
||||||
selectedRowCount,
|
selectedRowCount,
|
||||||
|
menu,
|
||||||
|
cellSelection,
|
||||||
|
selectedCellCount,
|
||||||
} = context
|
} = context
|
||||||
|
|
||||||
// Ensure we clear invalid rows from state if they disappear
|
// Ensure we clear invalid rows from state if they disappear
|
||||||
|
@ -248,6 +251,14 @@ export const initialise = context => {
|
||||||
if (id && get(selectedRowCount)) {
|
if (id && get(selectedRowCount)) {
|
||||||
selectedRows.set({})
|
selectedRows.set({})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear cell selection when focusing a cell
|
||||||
|
if (id && get(selectedCellCount)) {
|
||||||
|
cellSelection.actions.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the menu if it was open
|
||||||
|
menu.actions.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
// Pull row height from table as long as we don't have a fixed height
|
// Pull row height from table as long as we don't have a fixed height
|
||||||
|
@ -268,8 +279,13 @@ export const initialise = context => {
|
||||||
|
|
||||||
// Clear focused cell when selecting rows
|
// Clear focused cell when selecting rows
|
||||||
selectedRowCount.subscribe(count => {
|
selectedRowCount.subscribe(count => {
|
||||||
if (get(focusedCellId) && count) {
|
if (count) {
|
||||||
|
if (get(focusedCellId)) {
|
||||||
focusedCellId.set(null)
|
focusedCellId.set(null)
|
||||||
}
|
}
|
||||||
|
if (get(selectedCellCount)) {
|
||||||
|
cellSelection.actions.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,5 +16,5 @@
|
||||||
/* Custom additions */
|
/* Custom additions */
|
||||||
--modal-background: var(--spectrum-global-color-gray-50);
|
--modal-background: var(--spectrum-global-color-gray-50);
|
||||||
--drop-shadow: rgba(0, 0, 0, 0.25) !important;
|
--drop-shadow: rgba(0, 0, 0, 0.25) !important;
|
||||||
--spectrum-global-color-blue-100: rgba(35, 40, 50) !important;
|
--spectrum-global-color-blue-100: rgba(36, 44, 64) !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,5 +49,5 @@
|
||||||
/* Custom additions */
|
/* Custom additions */
|
||||||
--modal-background: var(--spectrum-global-color-gray-50);
|
--modal-background: var(--spectrum-global-color-gray-50);
|
||||||
--drop-shadow: rgba(0, 0, 0, 0.15) !important;
|
--drop-shadow: rgba(0, 0, 0, 0.15) !important;
|
||||||
--spectrum-global-color-blue-100: rgb(56, 65, 84) !important;
|
--spectrum-global-color-blue-100: rgb(56, 65, 90) !important;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue