diff --git a/services/web/frontend/js/features/source-editor/components/table-generator/cell.tsx b/services/web/frontend/js/features/source-editor/components/table-generator/cell.tsx
index 23b6d29b80..9e0040ede7 100644
--- a/services/web/frontend/js/features/source-editor/components/table-generator/cell.tsx
+++ b/services/web/frontend/js/features/source-editor/components/table-generator/cell.tsx
@@ -118,7 +118,7 @@ export const Cell: FC<{
if (renderDiv.current && !editing) {
const tree = parser.parse(toDisplay)
const node = tree.topNode
-
+ renderDiv.current.innerText = ''
typesetNodeIntoElement(
node,
renderDiv.current,
diff --git a/services/web/frontend/js/features/source-editor/components/table-generator/contexts/selection-context.tsx b/services/web/frontend/js/features/source-editor/components/table-generator/contexts/selection-context.tsx
index 4f3b0afe92..9fe11d0423 100644
--- a/services/web/frontend/js/features/source-editor/components/table-generator/contexts/selection-context.tsx
+++ b/services/web/frontend/js/features/source-editor/components/table-generator/contexts/selection-context.tsx
@@ -166,6 +166,16 @@ export class TableSelection {
maxY === totalRows - 1
)
}
+
+ width() {
+ const { minX, maxX } = this.normalized()
+ return maxX - minX + 1
+ }
+
+ height() {
+ const { minY, maxY } = this.normalized()
+ return maxY - minY + 1
+ }
}
const SelectionContext = createContext<
diff --git a/services/web/frontend/js/features/source-editor/components/table-generator/contexts/table-context.tsx b/services/web/frontend/js/features/source-editor/components/table-generator/contexts/table-context.tsx
index e074b82827..2560b004ee 100644
--- a/services/web/frontend/js/features/source-editor/components/table-generator/contexts/table-context.tsx
+++ b/services/web/frontend/js/features/source-editor/components/table-generator/contexts/table-context.tsx
@@ -1,5 +1,5 @@
import { FC, createContext, useContext } from 'react'
-import { Positions, TableData } from '../tabular'
+import { Positions, TableData, TableRenderingError } from '../tabular'
import {
CellPosition,
CellSeparator,
@@ -41,7 +41,7 @@ export const TableProvider: FC<{
// TODO: Validate better that the table matches the column definition
for (const row of tableData.table.rows) {
if (row.cells.length !== tableData.table.columns.length) {
- throw new Error("Table doesn't match column definition")
+ return
}
}
diff --git a/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/commands.ts b/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/commands.ts
index 6e4b19ce66..c72704958f 100644
--- a/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/commands.ts
+++ b/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/commands.ts
@@ -173,8 +173,15 @@ export const removeRowOrColumns = (
const numberOfRows = positions.rowPositions.length
if (selection.spansEntireTable(numberOfColumns, numberOfRows)) {
- return emptyTable(view, columnSpecification, positions)
+ emptyTable(view, columnSpecification, positions)
+ return new TableSelection({ cell: 0, row: 0 })
}
+ const removedRows =
+ Number(selection.isRowSelected(startRow, numberOfColumns)) *
+ selection.height()
+ const removedColumns =
+ Number(selection.isColumnSelected(startCell, numberOfRows)) *
+ selection.width()
for (let row = startRow; row <= endRow; row++) {
if (selection.isRowSelected(row, numberOfColumns)) {
@@ -221,6 +228,13 @@ export const removeRowOrColumns = (
insert: newSpecification,
})
view.dispatch({ changes })
+ const updatedNumberOfRows = numberOfRows - removedRows
+ const updatedNumberOfColumns = numberOfColumns - removedColumns
+ // Clamp selection to new table size
+ return new TableSelection({
+ cell: Math.max(0, Math.min(updatedNumberOfColumns - 1, startCell)),
+ row: Math.max(0, Math.min(updatedNumberOfRows - 1, startRow)),
+ })
}
const emptyTable = (
@@ -262,6 +276,13 @@ export const insertRow = (
const numberOfColumns = positions.cells[maxY].length
const insert = `\n${' &'.repeat(numberOfColumns - 1)}\\\\`
view.dispatch({ changes: { from, to: from, insert } })
+ if (!below) {
+ return selection
+ }
+ return new TableSelection(
+ { cell: 0, row: maxY + 1 },
+ { cell: numberOfColumns - 1, row: maxY + 1 }
+ )
}
export const insertColumn = (
@@ -300,6 +321,13 @@ export const insertColumn = (
insert: generateColumnSpecification(columnSpecification),
})
view.dispatch({ changes })
+ if (!after) {
+ return selection
+ }
+ return new TableSelection(
+ { cell: maxX + 1, row: 0 },
+ { cell: maxX + 1, row: positions.rowPositions.length - 1 }
+ )
}
export const removeNodes = (
diff --git a/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/toolbar-button.tsx b/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/toolbar-button.tsx
index b3dbc89f1a..c5d2ee2bfa 100644
--- a/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/toolbar-button.tsx
+++ b/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/toolbar-button.tsx
@@ -36,7 +36,6 @@ export const ToolbarButton = memo<{
if (command) {
event.preventDefault()
command(view)
- view.focus()
}
},
[command, view]
diff --git a/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/toolbar-dropdown.tsx b/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/toolbar-dropdown.tsx
index c31c96518b..7219016cbd 100644
--- a/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/toolbar-dropdown.tsx
+++ b/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/toolbar-dropdown.tsx
@@ -23,10 +23,9 @@ export const ToolbarDropdown: FC<{
disabled,
disabledTooltip,
}) => {
- const { open, onToggle } = useDropdown()
+ const { open, onToggle, ref } = useDropdown()
const toggleButtonRef = useRef(null)
const { ref: tabularRef } = useTabularContext()
-
const button = (
)
- const overlay = open && tabularRef.current && (
+ const overlay = tabularRef.current && (
onToggle(false)}
- animation={false}
- container={tabularRef.current}
- containerPadding={0}
- placement="bottom"
- rootClose
+ show={open}
target={toggleButtonRef.current ?? undefined}
+ placement="bottom"
+ container={tabularRef.current}
+ animation
+ containerPadding={0}
+ onHide={() => onToggle(false)}
>
+ {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions,
+ jsx-a11y/click-events-have-key-events */}
@@ -83,6 +91,7 @@ export const ToolbarDropdown: FC<{
return (
<>
- removeRowOrColumns(view, selection, positions, cellSeparators)
+ setSelection(
+ removeRowOrColumns(view, selection, positions, cellSeparators)
+ )
}
/>
{
- insertColumn(view, selection, positions, false)
+ setSelection(insertColumn(view, selection, positions, false))
}}
>
@@ -186,7 +188,7 @@ export const Toolbar = memo(function Toolbar() {
role="menuitem"
type="button"
onClick={() => {
- insertColumn(view, selection, positions, true)
+ setSelection(insertColumn(view, selection, positions, true))
}}
>
@@ -199,7 +201,7 @@ export const Toolbar = memo(function Toolbar() {
role="menuitem"
type="button"
onClick={() => {
- insertRow(view, selection, positions, false)
+ setSelection(insertRow(view, selection, positions, false))
}}
>
@@ -211,7 +213,7 @@ export const Toolbar = memo(function Toolbar() {
role="menuitem"
type="button"
onClick={() => {
- insertRow(view, selection, positions, true)
+ setSelection(insertRow(view, selection, positions, true))
}}
>
diff --git a/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/tabular.tsx b/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/tabular.tsx
index fa9af58141..dc27430892 100644
--- a/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/tabular.tsx
+++ b/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/tabular.tsx
@@ -38,6 +38,19 @@ export class TabularWidget extends WidgetType {
)
}
+ updateDOM(dom: HTMLElement, view: EditorView): boolean {
+ this.element = dom
+ ReactDOM.render(
+ ,
+ this.element
+ )
+ return true
+ }
+
destroy() {
console.debug('destroying tabular widget')
if (this.element) {