diff --git a/services/web/frontend/js/features/source-editor/components/table-generator/tabular.tsx b/services/web/frontend/js/features/source-editor/components/table-generator/tabular.tsx index 2f116a687e..ac3e3c560c 100644 --- a/services/web/frontend/js/features/source-editor/components/table-generator/tabular.tsx +++ b/services/web/frontend/js/features/source-editor/components/table-generator/tabular.tsx @@ -34,6 +34,7 @@ export type ColumnDefinition = { alignment: 'left' | 'center' | 'right' | 'paragraph' borderLeft: number borderRight: number + content: string } export type TableData = { 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 59c4b4ee32..89b7ec85f4 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 @@ -1,7 +1,8 @@ import { EditorView } from '@codemirror/view' -import { Positions } from '../tabular' +import { ColumnDefinition, Positions } from '../tabular' import { ChangeSpec } from '@codemirror/state' -import { RowSeparator } from '../utils' +import { RowSeparator, parseColumnSpecifications } from '../utils' +import { TableSelection } from '../contexts/selection-context' /* eslint-disable no-unused-vars */ export enum BorderTheme { @@ -96,3 +97,46 @@ export const setBorders = ( }) } } + +export const setAlignment = ( + view: EditorView, + selection: TableSelection, + alignment: 'left' | 'right' | 'center', + positions: Positions +) => { + const specification = view.state.sliceDoc( + positions.columnDeclarations.from, + positions.columnDeclarations.to + ) + const columnSpecification = parseColumnSpecifications(specification) + const { minX, maxX } = selection.normalized() + for (let i = minX; i <= maxX; i++) { + if (selection.isColumnSelected(i, positions.rowPositions.length)) { + if (columnSpecification[i].alignment === alignment) { + continue + } + columnSpecification[i].alignment = alignment + // TODO: This won't work for paragraph, which needs width argument + columnSpecification[i].content = alignment[0] + } + } + const newSpecification = generateColumnSpecification(columnSpecification) + view.dispatch({ + changes: [ + { + from: positions.columnDeclarations.from, + to: positions.columnDeclarations.to, + insert: newSpecification, + }, + ], + }) +} + +const generateColumnSpecification = (columns: ColumnDefinition[]) => { + return columns + .map( + ({ borderLeft, borderRight, content }) => + `${'|'.repeat(borderLeft)}${content}${'|'.repeat(borderRight)}` + ) + .join('') +} diff --git a/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/toolbar.tsx b/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/toolbar.tsx index 6ff5f80123..72317a7180 100644 --- a/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/toolbar.tsx +++ b/services/web/frontend/js/features/source-editor/components/table-generator/toolbar/toolbar.tsx @@ -4,7 +4,7 @@ import { ToolbarButton } from './toolbar-button' import { ToolbarButtonMenu } from './toolbar-button-menu' import { ToolbarDropdown } from './toolbar-dropdown' import MaterialIcon from '../../../../../shared/components/material-icon' -import { BorderTheme, setBorders } from './commands' +import { BorderTheme, setAlignment, setBorders } from './commands' import { useCodeMirrorViewContext } from '../../codemirror-editor' import { useTableContext } from '../contexts/table-context' @@ -87,27 +87,36 @@ export const Toolbar = memo(function Toolbar() { label="Alignment" icon="format_align_left" id="table-generator-align-dropdown" - disabled + disabled={ + !selection.isColumnSelected( + selection.from.cell, + positions.rowPositions.length + ) + } > { + setAlignment(view, selection, 'left', positions) + }} /> { + setAlignment(view, selection, 'center', positions) + }} /> - { + setAlignment(view, selection, 'right', positions) + }} />